primitives/
state_root.rs

1// Copyright 2019 Conflux Foundation. All rights reserved.
2// Conflux is free software and distributed under GNU General Public License.
3// See http://www.gnu.org/licenses/
4
5use crate::hash::{keccak, KECCAK_EMPTY};
6use cfx_types::H256;
7use rlp::{Decodable, DecoderError, Encodable, Rlp, RlpStream};
8use serde_derive::{Deserialize, Serialize};
9
10pub type MerkleHash = H256;
11
12/// The Merkle Hash for an empty MPT (either as a subtree or as a whole tree).
13pub const MERKLE_NULL_NODE: MerkleHash = KECCAK_EMPTY;
14
15/// The deferred state root consists of 3 parts: snapshot, delta_0, delta.
16/// when delta grows over threshold, snapshot and delta_0 is merged into new
17/// snapshot, and the delta becomes new delta_0.
18#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
19#[serde(rename_all = "camelCase")]
20pub struct StateRoot {
21    pub snapshot_root: MerkleHash,
22    pub intermediate_delta_root: MerkleHash,
23    pub delta_root: MerkleHash,
24}
25
26impl Default for StateRoot {
27    fn default() -> Self {
28        Self {
29            snapshot_root: MERKLE_NULL_NODE,
30            intermediate_delta_root: MERKLE_NULL_NODE,
31            delta_root: MERKLE_NULL_NODE,
32        }
33    }
34}
35
36impl StateRoot {
37    pub fn compute_state_root_hash(&self) -> H256 {
38        let mut buffer: [u8; 96] = [0; 96];
39        buffer[0..32].copy_from_slice(self.snapshot_root.as_bytes());
40        buffer[32..64].copy_from_slice(self.intermediate_delta_root.as_bytes());
41        buffer[64..96].copy_from_slice(self.delta_root.as_bytes());
42        keccak(&buffer[..])
43    }
44
45    pub fn genesis(genesis_root: &MerkleHash) -> StateRoot {
46        Self {
47            snapshot_root: MERKLE_NULL_NODE,
48            intermediate_delta_root: MERKLE_NULL_NODE,
49            delta_root: genesis_root.clone(),
50        }
51    }
52}
53
54impl Encodable for StateRoot {
55    fn rlp_append(&self, s: &mut RlpStream) {
56        s.begin_list(3)
57            .append(&self.snapshot_root)
58            .append(&self.intermediate_delta_root)
59            .append(&self.delta_root);
60    }
61}
62
63impl Decodable for StateRoot {
64    fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
65        Ok(Self {
66            snapshot_root: rlp.val_at(0)?,
67            intermediate_delta_root: rlp.val_at(1)?,
68            delta_root: rlp.val_at(2)?,
69        })
70    }
71}