Coverage Summary for Class: BlockChainFlusher (co.rsk.core.bc)
Class |
Method, %
|
Line, %
|
BlockChainFlusher |
0%
(0/8)
|
0%
(0/48)
|
BlockChainFlusher$OnBestBlockListener |
0%
(0/2)
|
0%
(0/2)
|
Total |
0%
(0/10)
|
0%
(0/50)
|
1 /*
2 * This file is part of RskJ
3 * Copyright (C) 2019 RSK Labs Ltd.
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18 package co.rsk.core.bc;
19
20 import co.rsk.config.InternalService;
21 import co.rsk.logfilter.BlocksBloomStore;
22 import co.rsk.metrics.profilers.Metric;
23 import co.rsk.metrics.profilers.Profiler;
24 import co.rsk.metrics.profilers.ProfilerFactory;
25 import co.rsk.trie.TrieStore;
26 import co.rsk.util.FormatUtils;
27 import org.ethereum.core.Block;
28 import org.ethereum.core.TransactionReceipt;
29 import org.ethereum.db.BlockStore;
30 import org.ethereum.db.ReceiptStore;
31 import org.ethereum.listener.CompositeEthereumListener;
32 import org.ethereum.listener.EthereumListenerAdapter;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
35
36 import java.util.List;
37
38 /**
39 * Flushes the repository and block store after every flushNumberOfBlocks invocations
40 */
41 public class BlockChainFlusher implements InternalService {
42 private static final Logger logger = LoggerFactory.getLogger(BlockChainFlusher.class);
43
44 private static final Profiler profiler = ProfilerFactory.getInstance();
45
46 private final int flushNumberOfBlocks;
47 private final CompositeEthereumListener emitter;
48 private final TrieStore trieStore;
49 private final BlockStore blockStore;
50 private final ReceiptStore receiptStore;
51 private final BlocksBloomStore blocksBloomStore;
52
53 private final OnBestBlockListener listener = new OnBestBlockListener();
54
55 private int nFlush = 1;
56
57 public BlockChainFlusher(
58 int flushNumberOfBlocks,
59 CompositeEthereumListener emitter,
60 TrieStore trieStore,
61 BlockStore blockStore,
62 ReceiptStore receiptStore,
63 BlocksBloomStore blocksBloomStore) {
64 this.flushNumberOfBlocks = flushNumberOfBlocks;
65 this.emitter = emitter;
66 this.trieStore = trieStore;
67 this.blockStore = blockStore;
68 this.receiptStore = receiptStore;
69 this.blocksBloomStore = blocksBloomStore;
70 }
71
72 @Override
73 public void start() {
74 emitter.addListener(listener);
75 }
76
77 @Override
78 public void stop() {
79 emitter.removeListener(listener);
80 flushAll();
81 closeAll();
82 }
83
84 private void closeAll() {
85 logger.trace("closing blockStore.");
86 blockStore.close();
87 logger.trace("blockStore closed.");
88 logger.trace("closing blocksBloomStore.");
89 blocksBloomStore.close();
90 logger.trace("blocksBloomStore closed.");
91 }
92
93 private void flush() {
94 if (nFlush == 0) {
95 flushAll();
96 }
97
98 nFlush++;
99 nFlush = nFlush % flushNumberOfBlocks;
100 }
101
102 private void flushAll() {
103 Metric metric = profiler.start(Profiler.PROFILING_TYPE.BLOCKCHAIN_FLUSH);
104
105 long saveTime = System.nanoTime();
106 trieStore.flush();
107 long totalTime = System.nanoTime() - saveTime;
108
109 if (logger.isTraceEnabled()) {
110 logger.trace("repository flush: [{}]seconds", FormatUtils.formatNanosecondsToSeconds(totalTime));
111 }
112
113 saveTime = System.nanoTime();
114 blockStore.flush();
115 totalTime = System.nanoTime() - saveTime;
116
117 if (logger.isTraceEnabled()) {
118 logger.trace("blockstore flush: [{}]seconds", FormatUtils.formatNanosecondsToSeconds(totalTime));
119 }
120
121 saveTime = System.nanoTime();
122 receiptStore.flush();
123 totalTime = System.nanoTime() - saveTime;
124
125 if (logger.isTraceEnabled()) {
126 logger.trace("receiptstore flush: [{}]seconds", FormatUtils.formatNanosecondsToSeconds(totalTime));
127 }
128
129 saveTime = System.nanoTime();
130 blocksBloomStore.flush();
131 totalTime = System.nanoTime() - saveTime;
132
133 if (logger.isTraceEnabled()) {
134 logger.trace("bloomBlocksStore flush: [{}]seconds", FormatUtils.formatNanosecondsToSeconds(totalTime));
135 }
136
137 profiler.stop(metric);
138 }
139
140 private class OnBestBlockListener extends EthereumListenerAdapter {
141 @Override
142 public void onBestBlock(Block block, List<TransactionReceipt> receipts) {
143 flush();
144 }
145 }
146 }