1pub mod accumulator;
5pub mod definition;
6pub mod position;
7#[cfg(any(test, feature = "fuzzing"))]
8pub mod proptest_proof;
9
10#[cfg(test)]
11mod unit_tests;
12
13use crate::{
14 ledger_info::LedgerInfo,
15 transaction::{TransactionInfoTrait, Version},
16};
17use anyhow::{ensure, Result};
18use diem_crypto::{
19 hash::{
20 CryptoHash, CryptoHasher, EventAccumulatorHasher, SparseMerkleInternalHasher,
21 TestOnlyHasher, TransactionAccumulatorHasher,
22 },
23 HashValue,
24};
25use diem_crypto_derive::CryptoHasher;
26#[cfg(any(test, feature = "fuzzing"))]
27use proptest_derive::Arbitrary;
28use serde::{Deserialize, Serialize};
29use std::marker::PhantomData;
30
31pub use self::definition::{
32 AccountStateProof, AccumulatorConsistencyProof, AccumulatorExtensionProof, AccumulatorProof,
33 AccumulatorRangeProof, EventAccumulatorProof, EventProof, SparseMerkleProof,
34 SparseMerkleRangeProof, TransactionAccumulatorProof, TransactionAccumulatorRangeProof,
35 TransactionAccumulatorSummary, TransactionInfoListWithProof, TransactionInfoWithProof,
36};
37
38#[cfg(any(test, feature = "fuzzing"))]
39pub use self::definition::{TestAccumulatorProof, TestAccumulatorRangeProof};
40
41fn verify_transaction_info<T: TransactionInfoTrait>(
43 ledger_info: &LedgerInfo,
44 transaction_version: Version,
45 transaction_info: &T,
46 ledger_info_to_transaction_info_proof: &TransactionAccumulatorProof,
47) -> Result<()> {
48 ensure!(
49 transaction_version <= ledger_info.version(),
50 "Transaction version {} is newer than LedgerInfo version {}.",
51 transaction_version,
52 ledger_info.version(),
53 );
54
55 let transaction_info_hash = transaction_info.hash();
56 ledger_info_to_transaction_info_proof.verify(
57 ledger_info.transaction_accumulator_hash(),
58 transaction_info_hash,
59 transaction_version,
60 )?;
61
62 Ok(())
63}
64
65pub struct MerkleTreeInternalNode<H> {
66 left_child: HashValue,
67 right_child: HashValue,
68 hasher: PhantomData<H>,
69}
70
71impl<H: CryptoHasher> MerkleTreeInternalNode<H> {
72 pub fn new(left_child: HashValue, right_child: HashValue) -> Self {
73 Self {
74 left_child,
75 right_child,
76 hasher: PhantomData,
77 }
78 }
79}
80
81impl<H: CryptoHasher> CryptoHash for MerkleTreeInternalNode<H> {
82 type Hasher = H;
83
84 fn hash(&self) -> HashValue {
85 let mut state = Self::Hasher::default();
86 state.update(self.left_child.as_ref());
87 state.update(self.right_child.as_ref());
88 state.finish()
89 }
90}
91
92pub type SparseMerkleInternalNode = MerkleTreeInternalNode<SparseMerkleInternalHasher>;
93pub type TransactionAccumulatorInternalNode = MerkleTreeInternalNode<TransactionAccumulatorHasher>;
94pub type EventAccumulatorInternalNode = MerkleTreeInternalNode<EventAccumulatorHasher>;
95pub type TestAccumulatorInternalNode = MerkleTreeInternalNode<TestOnlyHasher>;
96
97#[derive(Clone, Copy, CryptoHasher, Debug, Eq, PartialEq, Serialize, Deserialize)]
98#[cfg_attr(any(test, feature = "fuzzing"), derive(Arbitrary))]
99pub struct SparseMerkleLeafNode {
100 key: HashValue,
101 value_hash: HashValue,
102}
103
104impl SparseMerkleLeafNode {
105 pub fn new(key: HashValue, value_hash: HashValue) -> Self {
106 SparseMerkleLeafNode { key, value_hash }
107 }
108
109 pub fn key(&self) -> HashValue {
110 self.key
111 }
112
113 pub fn value_hash(&self) -> HashValue {
114 self.value_hash
115 }
116}
117
118impl CryptoHash for SparseMerkleLeafNode {
119 type Hasher = SparseMerkleLeafNodeHasher;
120
121 fn hash(&self) -> HashValue {
122 let mut state = Self::Hasher::default();
123 state.update(self.key.as_ref());
124 state.update(self.value_hash.as_ref());
125 state.finish()
126 }
127}
128
129pub mod default_protocol {
130 pub use super::definition::default_protocol::{
131 AccountStateProof, AccumulatorConsistencyProof, AccumulatorExtensionProof,
132 AccumulatorProof, AccumulatorRangeProof, EventAccumulatorProof, EventProof,
133 SparseMerkleProof, SparseMerkleRangeProof, TransactionAccumulatorProof,
134 TransactionAccumulatorRangeProof, TransactionAccumulatorSummary,
135 TransactionInfoListWithProof, TransactionInfoWithProof,
136 };
137}