cfx_internal_common/
state_root_with_aux_info.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
5/// Auxiliary information for deferred state root, which is necessary for state
6/// trees look-up. The StateRootAuxInfo should be provided by consensus layer
7/// for state storage access.
8#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
9#[serde(rename_all = "camelCase")]
10pub struct StateRootAuxInfo {
11    // We need the snapshot epoch_id to associate the intermediate mpt and
12    // delta mpt, because snapshot merkle root are not guaranteed to be
13    // unique.
14    pub snapshot_epoch_id: EpochId,
15    // When we need to shift the snapshot, this is the only "known" information
16    // from consensus to retrieve the new snapshot.
17    pub intermediate_epoch_id: EpochId,
18    // We need key_padding in order to retrieve key-values from (Intermediate-)
19    // Delta MPT.
20    pub maybe_intermediate_mpt_key_padding: Option<DeltaMptKeyPadding>,
21
22    // FIXME: how is it possible to fill this field for recovered state from
23    // FIXME: blame? what's the expectation of saving as many
24    // FIXME: EpochExecutionCommitments from blame?
25    pub delta_mpt_key_padding: DeltaMptKeyPadding,
26
27    // The merged hash of the original three fields
28    pub state_root_hash: MerkleHash,
29}
30
31impl StateRootAuxInfo {
32    pub fn genesis_state_root_aux_info(
33        genesis_state_root: &MerkleHash,
34    ) -> Self {
35        Self {
36            snapshot_epoch_id: NULL_EPOCH,
37            intermediate_epoch_id: NULL_EPOCH,
38            maybe_intermediate_mpt_key_padding: None,
39            delta_mpt_key_padding: GENESIS_DELTA_MPT_KEY_PADDING.clone(),
40            state_root_hash: genesis_state_root.clone(),
41        }
42    }
43}
44
45/// This struct is stored as state execution result and is used to compute state
46/// of children blocks.
47#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
48#[serde(rename_all = "camelCase")]
49pub struct StateRootWithAuxInfo {
50    pub state_root: StateRoot,
51    pub aux_info: StateRootAuxInfo,
52}
53
54impl StateRootWithAuxInfo {
55    pub fn genesis(genesis_root: &MerkleHash) -> Self {
56        let state_root = StateRoot::genesis(genesis_root);
57        let genesis_state_root = state_root.compute_state_root_hash();
58        Self {
59            state_root,
60            aux_info: StateRootAuxInfo::genesis_state_root_aux_info(
61                &genesis_state_root,
62            ),
63        }
64    }
65}
66
67impl From<(&StateRoot, &StateRootAuxInfo)> for StateRootWithAuxInfo {
68    fn from(x: (&StateRoot, &StateRootAuxInfo)) -> Self {
69        Self {
70            state_root: x.0.clone(),
71            aux_info: x.1.clone(),
72        }
73    }
74}
75
76impl Encodable for StateRootAuxInfo {
77    fn rlp_append(&self, s: &mut RlpStream) {
78        s.begin_list(5)
79            .append(&self.snapshot_epoch_id)
80            .append(&self.intermediate_epoch_id)
81            .append(&self.maybe_intermediate_mpt_key_padding)
82            .append(&&self.delta_mpt_key_padding[..])
83            .append(&self.state_root_hash);
84    }
85}
86
87impl Decodable for StateRootAuxInfo {
88    fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
89        Ok(Self {
90            snapshot_epoch_id: rlp.val_at(0)?,
91            intermediate_epoch_id: rlp.val_at(1)?,
92            maybe_intermediate_mpt_key_padding: rlp.val_at(2)?,
93            delta_mpt_key_padding: rlp.val_at(3)?,
94            state_root_hash: rlp.val_at(4)?,
95        })
96    }
97}
98
99impl Encodable for StateRootWithAuxInfo {
100    fn rlp_append(&self, s: &mut RlpStream) {
101        s.begin_list(2)
102            .append(&self.state_root)
103            .append(&self.aux_info);
104    }
105}
106
107impl Decodable for StateRootWithAuxInfo {
108    fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
109        Ok(Self {
110            state_root: rlp.val_at(0)?,
111            aux_info: rlp.val_at(1)?,
112        })
113    }
114}
115
116use primitives::{
117    DeltaMptKeyPadding, EpochId, MerkleHash, StateRoot,
118    GENESIS_DELTA_MPT_KEY_PADDING, NULL_EPOCH,
119};
120use rlp::{Decodable, DecoderError, Encodable, Rlp, RlpStream};
121use serde_derive::{Deserialize, Serialize};