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 AccumulatorConsistencyProof, AccumulatorExtensionProof, AccumulatorProof,
38 AccumulatorRangeProof, EventAccumulatorProof, SparseMerkleProof,
39 TransactionAccumulatorProof, TransactionAccumulatorRangeProof,
40 TransactionInfoWithProof, TransactionListProof,
41};
42
43#[cfg(any(test, feature = "fuzzing"))]
44pub use self::definition::{TestAccumulatorProof, TestAccumulatorRangeProof};
45
46fn verify_transaction_info(
49 ledger_info: &LedgerInfo, transaction_version: Version,
50 transaction_info: &TransactionInfo,
51 ledger_info_to_transaction_info_proof: &TransactionAccumulatorProof,
52) -> Result<()> {
53 ensure!(
54 transaction_version <= ledger_info.version(),
55 "Transaction version {} is newer than LedgerInfo version {}.",
56 transaction_version,
57 ledger_info.version(),
58 );
59
60 let transaction_info_hash = transaction_info.hash();
61 ledger_info_to_transaction_info_proof.verify(
62 ledger_info.transaction_accumulator_hash(),
63 transaction_info_hash,
64 transaction_version,
65 )?;
66
67 Ok(())
68}
69
70pub struct MerkleTreeInternalNode<H> {
71 left_child: HashValue,
72 right_child: HashValue,
73 hasher: PhantomData<H>,
74}
75
76impl<H: CryptoHasher> MerkleTreeInternalNode<H> {
77 pub fn new(left_child: HashValue, right_child: HashValue) -> Self {
78 Self {
79 left_child,
80 right_child,
81 hasher: PhantomData,
82 }
83 }
84}
85
86impl<H: CryptoHasher> CryptoHash for MerkleTreeInternalNode<H> {
87 type Hasher = H;
88
89 fn hash(&self) -> HashValue {
90 let mut state = Self::Hasher::default();
91 state.update(self.left_child.as_ref());
92 state.update(self.right_child.as_ref());
93 state.finish()
94 }
95}
96
97pub type SparseMerkleInternalNode =
98 MerkleTreeInternalNode<SparseMerkleInternalHasher>;
99pub type TransactionAccumulatorInternalNode =
100 MerkleTreeInternalNode<TransactionAccumulatorHasher>;
101pub type EventAccumulatorInternalNode =
102 MerkleTreeInternalNode<EventAccumulatorHasher>;
103pub type TestAccumulatorInternalNode = MerkleTreeInternalNode<TestOnlyHasher>;
104
105#[derive(
106 Clone, Copy, CryptoHasher, Debug, Eq, PartialEq, Serialize, Deserialize,
107)]
108#[cfg_attr(any(test, feature = "fuzzing"), derive(Arbitrary))]
109pub struct SparseMerkleLeafNode {
110 key: HashValue,
111 value_hash: HashValue,
112}
113
114impl SparseMerkleLeafNode {
115 pub fn new(key: HashValue, value_hash: HashValue) -> Self {
116 SparseMerkleLeafNode { key, value_hash }
117 }
118
119 pub fn key(&self) -> HashValue { self.key }
120
121 pub fn value_hash(&self) -> HashValue { self.value_hash }
122}
123
124impl CryptoHash for SparseMerkleLeafNode {
125 type Hasher = SparseMerkleLeafNodeHasher;
126
127 fn hash(&self) -> HashValue {
128 let mut state = Self::Hasher::default();
129 state.update(self.key.as_ref());
130 state.update(self.value_hash.as_ref());
131 state.finish()
132 }
133}