Coverage Summary for Class: StateRootHandler (co.rsk.db)
Class |
Class, %
|
Method, %
|
Line, %
|
StateRootHandler |
100%
(1/1)
|
100%
(4/4)
|
50%
(15/30)
|
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.db;
20
21 import co.rsk.crypto.Keccak256;
22 import co.rsk.trie.Trie;
23 import co.rsk.trie.TrieConverter;
24 import org.ethereum.config.blockchain.upgrades.ActivationConfig;
25 import org.ethereum.config.blockchain.upgrades.ConsensusRule;
26 import org.ethereum.core.BlockHeader;
27 import org.ethereum.datasource.KeyValueDataSource;
28
29 import java.util.Map;
30 import java.util.Objects;
31
32 public class StateRootHandler {
33 private final ActivationConfig activationConfig;
34 private final TrieConverter trieConverter;
35 private final StateRootTranslator stateRootTranslator;
36
37 public StateRootHandler(
38 ActivationConfig activationConfig,
39 TrieConverter trieConverter,
40 KeyValueDataSource stateRootDB,
41 Map<Keccak256, Keccak256> stateRootCache) {
42 this.activationConfig = activationConfig;
43 this.trieConverter = trieConverter;
44 this.stateRootTranslator = new StateRootTranslator(stateRootDB, stateRootCache);
45 }
46
47 public Keccak256 translate(BlockHeader block) {
48 boolean isRskip126Enabled = activationConfig.isActive(ConsensusRule.RSKIP126, block.getNumber());
49 Keccak256 blockStateRoot = new Keccak256(block.getStateRoot());
50 if (isRskip126Enabled) {
51 return blockStateRoot;
52 }
53
54 return Objects.requireNonNull(
55 stateRootTranslator.get(blockStateRoot),
56 "Reset database or continue syncing with previous version"
57 );
58 }
59
60 public Keccak256 convert(BlockHeader minedBlock, Trie executionResult) {
61 boolean isRskip126Enabled = activationConfig.isActive(ConsensusRule.RSKIP126, minedBlock.getNumber());
62 if (isRskip126Enabled) {
63 return executionResult.getHash();
64 }
65
66 //we shouldn't be converting blocks before orchid in stable networks
67 return new Keccak256(trieConverter.getOrchidAccountTrieRoot(executionResult));
68 }
69
70 public void register(BlockHeader executedBlock, Trie executionResult) {
71 boolean isRskip126Enabled = activationConfig.isActive(ConsensusRule.RSKIP126, executedBlock.getNumber());
72 if (isRskip126Enabled) {
73 return;
74 }
75
76 if (executedBlock.isGenesis()) {
77 Keccak256 genesisStateRoot = convert(executedBlock, executionResult);
78 stateRootTranslator.put(genesisStateRoot, executionResult.getHash());
79 } else {
80 boolean isRskip85Enabled = activationConfig.isActive(ConsensusRule.RSKIP85, executedBlock.getNumber());
81 if (isRskip85Enabled) {
82 Keccak256 orchidStateRoot = convert(executedBlock, executionResult);
83 stateRootTranslator.put(orchidStateRoot, executionResult.getHash());
84 } else {
85 Keccak256 blockStateRoot = new Keccak256(executedBlock.getStateRoot());
86 stateRootTranslator.put(blockStateRoot, executionResult.getHash());
87 }
88 }
89 }
90 }