Skip to main content

diem_types/proof/
mod.rs

1// Copyright (c) The Diem Core Contributors
2// SPDX-License-Identifier: Apache-2.0
3
4pub 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
41/// Verifies that a given `transaction_info` exists in the ledger using provided proof.
42fn 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}