ab_core_primitives/
trees.rs1mod alias;
8mod hashers;
9#[cfg(test)]
10mod tests;
11
12use crate::address::Address;
13use ab_blake3::{BLOCK_LEN, OUT_LEN};
14use ab_io_type::trivial_type::TrivialType;
15use ab_merkle_tree::MerkleHasher;
16use ab_merkle_tree::balanced::BalancedMerkleTree;
17use ab_merkle_tree::blake3::Blake3MerkleHasher;
18use ab_merkle_tree::mmr::MerkleMountainRange;
19use ab_merkle_tree::sparse::SparseMerkleTree;
20use alias::UnbalancedMerkleTreeAlias;
21use array_reshape::FlattenEach;
22use hashers::{Blake3SizedMerkleHasher, Blake3StaticMerkleHasher};
23
24type SegmentRootsMerkleHasher =
25 Blake3SizedMerkleHasher<{ ab_blake3::const_hash(b"segment-roots-merkle-tree") }>;
26type OwnSegmentsMerkleHasher =
27 Blake3StaticMerkleHasher<{ ab_blake3::const_hash(b"own-segments-merkle-tree") }>;
28type ShardOwnSegmentsMerkleHasher =
29 Blake3StaticMerkleHasher<{ ab_blake3::const_hash(b"shard-own-segments-merkle-tree") }>;
30type LeafShardBodyMerkleHasher =
31 Blake3StaticMerkleHasher<{ ab_blake3::const_hash(b"leaf-shard-body-merkle-tree") }>;
32type TransactionsMerkleHasher =
33 Blake3SizedMerkleHasher<{ ab_blake3::const_hash(b"transactions-merkle-tree") }>;
34type IntermediateShardBodyMerkleHasher =
35 Blake3StaticMerkleHasher<{ ab_blake3::const_hash(b"intermediate-shard-body-merkle-tree") }>;
36type LeafShardsSegmentsMerkleHasher =
37 Blake3SizedMerkleHasher<{ ab_blake3::const_hash(b"leaf-shards-segments-merkle-tree") }>;
38type ChildLeafShardBlocksMerkleHasher =
39 Blake3SizedMerkleHasher<{ ab_blake3::const_hash(b"child-leaf-shard-blocks-merkle-tree") }>;
40type ChildIntermediateShardBlocksMerkleHasher = Blake3SizedMerkleHasher<
41 { ab_blake3::const_hash(b"child-intermediate-shard-blocks-merkle-tree") },
42>;
43type BeaconChainBodyMerkleHasher =
44 Blake3StaticMerkleHasher<{ ab_blake3::const_hash(b"beacon-chain-body-merkle-tree") }>;
45type IntermediateShardsSegmentsMerkleHasher =
46 Blake3SizedMerkleHasher<{ ab_blake3::const_hash(b"intermediate-shards-segments-merkle-tree") }>;
47type BeaconChainHeaderMerkleHasher =
48 Blake3StaticMerkleHasher<{ ab_blake3::const_hash(b"beacon-chain-header-merkle-tree") }>;
49type IntermediateShardHeaderMerkleHasher =
50 Blake3StaticMerkleHasher<{ ab_blake3::const_hash(b"intermediate-shard-header-merkle-tree") }>;
51type LeafShardHeaderMerkleHasher =
52 Blake3StaticMerkleHasher<{ ab_blake3::const_hash(b"leaf-shard-header-merkle-tree") }>;
53type SuperSegmentMerkleHasher =
54 Blake3SizedMerkleHasher<{ ab_blake3::const_hash(b"super-segment-merkle-tree") }>;
55type StateOwnersSparseMerkleHasher =
56 Blake3StaticMerkleHasher<{ ab_blake3::const_hash(b"state-owners-sparse-merkle-tree") }>;
57type StateOwnerContractsSparseMerkleHasher = Blake3StaticMerkleHasher<
58 { ab_blake3::const_hash(b"state-owner-contracts-sparse-merkle-tree") },
59>;
60type BlockMerkleMountainRangeHasher =
61 Blake3StaticMerkleHasher<{ ab_blake3::const_hash(b"block-merkle-mountain-range") }>;
62
63const {
64 let keys = [
65 Blake3MerkleHasher::KEY,
66 SegmentRootsMerkleHasher::BASE_KEY,
67 OwnSegmentsMerkleHasher::KEY,
68 ShardOwnSegmentsMerkleHasher::KEY,
69 LeafShardBodyMerkleHasher::KEY,
70 TransactionsMerkleHasher::BASE_KEY,
71 IntermediateShardBodyMerkleHasher::KEY,
72 LeafShardsSegmentsMerkleHasher::BASE_KEY,
73 ChildLeafShardBlocksMerkleHasher::BASE_KEY,
74 ChildIntermediateShardBlocksMerkleHasher::BASE_KEY,
75 BeaconChainBodyMerkleHasher::KEY,
76 IntermediateShardsSegmentsMerkleHasher::BASE_KEY,
77 BeaconChainHeaderMerkleHasher::KEY,
78 IntermediateShardHeaderMerkleHasher::KEY,
79 LeafShardHeaderMerkleHasher::KEY,
80 SuperSegmentMerkleHasher::BASE_KEY,
81 StateOwnersSparseMerkleHasher::KEY,
82 StateOwnerContractsSparseMerkleHasher::KEY,
83 BlockMerkleMountainRangeHasher::KEY,
84 ];
85
86 let mut i = 0;
87 while i < keys.len() {
88 let mut j = i + 1;
89 while j < keys.len() {
90 assert!(keys[i] != keys[j], "Keys of Merkle Trees must be unique");
91 j += 1;
92 }
93 i += 1;
94 }
95}
96
97const ADDRESS_BITS: u8 = Address::SIZE as u8 * u8::BITS as u8;
99
100pub type SegmentRootsMerkleTree = <SegmentRootsMerkleHasher as UnbalancedMerkleTreeAlias>::Tree;
102pub type OwnSegmentsMerkleTree<'a> = BalancedMerkleTree<'a, 2, OwnSegmentsMerkleHasher>;
104pub type ShardOwnSegmentsMerkleTree<'a> = BalancedMerkleTree<'a, 2, ShardOwnSegmentsMerkleHasher>;
106pub type LeafShardBodyMerkleTree<'a> = BalancedMerkleTree<'a, 2, LeafShardBodyMerkleHasher>;
108pub type TransactionsMerkleTree = <TransactionsMerkleHasher as UnbalancedMerkleTreeAlias>::Tree;
110pub type IntermediateShardBodyMerkleTree =
112 <IntermediateShardBodyMerkleHasher as UnbalancedMerkleTreeAlias>::Tree;
113pub type LeafShardsSegmentsMerkleTree =
115 <LeafShardsSegmentsMerkleHasher as UnbalancedMerkleTreeAlias>::Tree;
116pub type ChildLeafShardBlocksMerkleTree =
118 <ChildLeafShardBlocksMerkleHasher as UnbalancedMerkleTreeAlias>::Tree;
119pub type ChildIntermediateShardBlocksMerkleTree =
121 <ChildIntermediateShardBlocksMerkleHasher as UnbalancedMerkleTreeAlias>::Tree;
122pub type BeaconChainBodyMerkleTree<'a> = BalancedMerkleTree<'a, 4, BeaconChainBodyMerkleHasher>;
124pub type IntermediateShardsSegmentsMerkleTree =
126 <IntermediateShardsSegmentsMerkleHasher as UnbalancedMerkleTreeAlias>::Tree;
127pub type BeaconChainHeaderMerkleTree =
129 <BeaconChainHeaderMerkleHasher as UnbalancedMerkleTreeAlias>::Tree;
130pub type IntermediateShardHeaderMerkleTree =
132 <IntermediateShardHeaderMerkleHasher as UnbalancedMerkleTreeAlias>::Tree;
133pub type LeafShardHeaderMerkleTree =
135 <LeafShardHeaderMerkleHasher as UnbalancedMerkleTreeAlias>::Tree;
136pub type SuperSegmentMerkleTree = <SuperSegmentMerkleHasher as UnbalancedMerkleTreeAlias>::Tree;
138pub type StateOwnersSparseMerkleTree =
140 SparseMerkleTree<ADDRESS_BITS, StateOwnersSparseMerkleHasher>;
141pub type StateOwnerContractsSparseMerkleTree =
143 SparseMerkleTree<ADDRESS_BITS, StateOwnerContractsSparseMerkleHasher>;
144pub type BlockMerkleMountainRange =
149 MerkleMountainRange<{ u64::from(u32::MAX) }, BlockMerkleMountainRangeHasher>;
150
151macro_rules! impl_merkle_hasher {
204 ($($hasher:ty),+ $(,)?) => {
205 $(
206 impl MerkleHasher for $hasher {
207 const OUT_LEN: usize = OUT_LEN;
208
209 #[inline(always)]
210 fn hash_pair(&self, pair: &[[u8; OUT_LEN]; 2]) -> [u8; OUT_LEN] {
211 ab_blake3::single_block_keyed_hash(self.node_key(), pair.as_flattened())
212 .expect("Exactly one block worth of data; qed")
213 }
214
215 #[inline(always)]
216 fn hash_pairs<const NUM_PAIRS: usize>(
217 &self,
218 pairs: &[[[u8; OUT_LEN]; 2]; NUM_PAIRS],
219 ) -> [[u8; OUT_LEN]; NUM_PAIRS] {
220 let pairs = pairs
221 .as_slice()
222 .flatten_each_ref::<BLOCK_LEN>()
223 .as_array::<NUM_PAIRS>()
224 .expect("Same number of pairs as in the input; qed");
225 let mut hashes = [[0; OUT_LEN]; NUM_PAIRS];
226 ab_blake3::single_block_keyed_hash_many_exact(
227 self.node_key(),
228 pairs,
229 &mut hashes,
230 );
231 hashes
232 }
233
234 #[inline(always)]
235 fn hash_single_leaf(&self, leaf: &[u8; OUT_LEN]) -> [u8; OUT_LEN] {
236 self.single_leaf_root(leaf)
237 }
238 }
239 )+
240 };
241}
242
243impl_merkle_hasher!(
244 SegmentRootsMerkleHasher,
245 OwnSegmentsMerkleHasher,
246 ShardOwnSegmentsMerkleHasher,
247 LeafShardBodyMerkleHasher,
248 TransactionsMerkleHasher,
249 IntermediateShardBodyMerkleHasher,
250 LeafShardsSegmentsMerkleHasher,
251 ChildLeafShardBlocksMerkleHasher,
252 ChildIntermediateShardBlocksMerkleHasher,
253 BeaconChainBodyMerkleHasher,
254 IntermediateShardsSegmentsMerkleHasher,
255 BeaconChainHeaderMerkleHasher,
256 IntermediateShardHeaderMerkleHasher,
257 LeafShardHeaderMerkleHasher,
258 SuperSegmentMerkleHasher,
259 StateOwnersSparseMerkleHasher,
260 StateOwnerContractsSparseMerkleHasher,
261 BlockMerkleMountainRangeHasher,
262);