Coverage Summary for Class: GarbageCollector (co.rsk.core.bc)
Class |
Method, %
|
Line, %
|
GarbageCollector |
0%
(0/5)
|
0%
(0/11)
|
GarbageCollector$GarbageCollectorInvoker |
0%
(0/2)
|
0%
(0/7)
|
Total |
0%
(0/7)
|
0%
(0/18)
|
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
19 package co.rsk.core.bc;
20
21 import co.rsk.config.InternalService;
22 import co.rsk.db.RepositoryLocator;
23 import co.rsk.trie.MultiTrieStore;
24 import org.ethereum.core.Block;
25 import org.ethereum.core.BlockHeader;
26 import org.ethereum.core.TransactionReceipt;
27 import org.ethereum.db.BlockStore;
28 import org.ethereum.listener.CompositeEthereumListener;
29 import org.ethereum.listener.EthereumListener;
30 import org.ethereum.listener.EthereumListenerAdapter;
31
32 import java.util.List;
33
34 public class GarbageCollector implements InternalService {
35 private final CompositeEthereumListener emitter;
36 private final MultiTrieStore multiTrieStore;
37 private final BlockStore blockStore;
38 private final RepositoryLocator repositoryLocator;
39 private final EthereumListener garbageCollectorInvoker;
40
41 public GarbageCollector(CompositeEthereumListener emitter,
42 int blocksPerEpoch,
43 int numberOfEpochs,
44 MultiTrieStore multiTrieStore,
45 BlockStore blockStore,
46 RepositoryLocator repositoryLocator) {
47 this.emitter = emitter;
48 this.multiTrieStore = multiTrieStore;
49 this.blockStore = blockStore;
50 this.repositoryLocator = repositoryLocator;
51 this.garbageCollectorInvoker = new GarbageCollectorInvoker(blocksPerEpoch, numberOfEpochs);
52 }
53
54 @Override
55 public void start() {
56 emitter.addListener(garbageCollectorInvoker);
57 }
58
59 @Override
60 public void stop() {
61 emitter.removeListener(garbageCollectorInvoker);
62 }
63
64 private void collect(long untilBlock) {
65 BlockHeader untilHeader = blockStore.getChainBlockByNumber(untilBlock).getHeader();
66 multiTrieStore.collect(repositoryLocator.snapshotAt(untilHeader).getRoot());
67 }
68
69 private class GarbageCollectorInvoker extends EthereumListenerAdapter {
70 private final int blocksPerEpoch;
71 private final int numberOfEpochs;
72
73 public GarbageCollectorInvoker(int blocksPerEpoch, int numberOfEpochs) {
74 this.blocksPerEpoch = blocksPerEpoch;
75 this.numberOfEpochs = numberOfEpochs;
76 }
77
78 /**
79 * It'll collect all states older than <code>blocksPerEpoch * numberOfEpochs - 1</code> from
80 * the store (if there are enough blocks)
81 */
82 @Override
83 public void onBestBlock(Block block, List<TransactionReceipt> receipts) {
84 int statesToKeep = blocksPerEpoch * numberOfEpochs - 1;
85 long currentBlockNumber = block.getNumber();
86 if(currentBlockNumber % blocksPerEpoch == 0 && currentBlockNumber >= statesToKeep) {
87 collect(currentBlockNumber - statesToKeep);
88 }
89 }
90 }
91 }