ab_client_consensus_common/
state.rs1use ab_aligned_buffer::SharedAlignedBuffer;
2use ab_client_api::ContractSlotState;
3use ab_core_primitives::address::Address;
4use ab_core_primitives::hashes::Blake3Hash;
5use ab_merkle_tree::sparse::{Leaf, SparseMerkleTree};
6use blake3::hash;
7use std::collections::BTreeMap;
8use std::num::NonZeroU128;
9use std::sync::Arc as StdArc;
10
11type Smt128 = SparseMerkleTree<{ size_of::<Address>() as u8 * u8::BITS as u8 }>;
12
13#[derive(Debug, Clone)]
15pub struct GlobalState {
16 state: BTreeMap<Address, BTreeMap<Address, SharedAlignedBuffer>>,
18 total_len: usize,
19}
20
21impl GlobalState {
22 pub fn new(system_contract_states: &[ContractSlotState]) -> Self {
23 let mut state = BTreeMap::<Address, BTreeMap<_, _>>::new();
24 for system_contract_state in system_contract_states.iter() {
25 state
26 .entry(system_contract_state.owner)
27 .or_default()
28 .insert(
29 system_contract_state.contract,
30 system_contract_state.contents.clone(),
31 );
32 }
33
34 Self {
35 state,
36 total_len: system_contract_states.len(),
37 }
38 }
39
40 pub fn to_system_contract_states(&self) -> StdArc<[ContractSlotState]> {
41 let mut system_contract_states =
42 StdArc::<[ContractSlotState]>::new_uninit_slice(self.total_len);
43
44 self.state
45 .iter()
46 .flat_map(|(owner, state)| {
47 state.iter().map(|(contract, contents)| ContractSlotState {
48 owner: *owner,
49 contract: *contract,
50 contents: contents.clone(),
51 })
52 })
53 .zip(unsafe { StdArc::get_mut_unchecked(&mut system_contract_states) })
55 .for_each(|(input, output)| {
56 output.write(input);
57 });
58
59 unsafe { system_contract_states.assume_init() }
62 }
63
64 pub fn root(&self) -> Blake3Hash {
65 let mut previous_owner = None;
66
67 let maybe_state_root =
68 Smt128::compute_root_only(self.state.iter().flat_map(|(&owner, state)| {
69 let owner = u128::from(owner);
70 let skip_leaf = if let Some(previous_owner) = previous_owner
71 && previous_owner + 1 != owner
72 {
73 let skip_count = NonZeroU128::new(owner - previous_owner).expect(
74 "Owner is a larger number due to BTreeMap, hence the difference is more \
75 than zero; qed",
76 );
77 Some(Leaf::Empty { skip_count })
78 } else {
79 None
80 };
81 previous_owner.replace(owner);
82
83 let mut previous_contract = None;
84
85 let maybe_owner_root =
86 Smt128::compute_root_only(state.iter().flat_map(|(&contract, contents)| {
87 let contract = u128::from(contract);
88 let skip_leaf = if let Some(previous_contract) = previous_contract
89 && previous_contract + 1 != contract
90 {
91 let skip_count = NonZeroU128::new(contract - previous_contract).expect(
92 "Contract is a larger number due to BTreeMap, hence the difference \
93 is more than zero; qed",
94 );
95 Some(Leaf::Empty { skip_count })
96 } else {
97 None
98 };
99 previous_contract.replace(contract);
100
101 skip_leaf.into_iter().chain([Leaf::OccupiedOwned {
102 leaf: *hash(contents.as_slice()).as_bytes(),
104 }])
105 }));
106 let owner_root = maybe_owner_root.expect(
107 "The number of leaves is limited by address space, which is 128-bit; qed",
108 );
109
110 skip_leaf
111 .into_iter()
112 .chain([Leaf::OccupiedOwned { leaf: owner_root }])
113 }));
114 let state_root = maybe_state_root
115 .expect("The number of leaves is limited by address space, which is 128-bit; qed");
116
117 Blake3Hash::new(state_root)
118 }
119}