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