diem_types/proof/
mod.rs

1// Copyright (c) The Diem Core Contributors
2// SPDX-License-Identifier: Apache-2.0
3
4// Copyright 2021 Conflux Foundation. All rights reserved.
5// Conflux is free software and distributed under GNU General Public License.
6// See http://www.gnu.org/licenses/
7
8pub 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
47/// Verifies that a given `transaction_info` exists in the ledger using provided
48/// proof.
49fn 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}