1use super::{
11 accumulator::InMemoryAccumulator, position::Position,
12 verify_transaction_info, MerkleTreeInternalNode, SparseMerkleInternalNode,
13 SparseMerkleLeafNode,
14};
15use crate::{
16 ledger_info::LedgerInfo,
17 transaction::{TransactionInfo, Version},
18};
19use anyhow::{bail, ensure, format_err, Result};
20#[cfg(any(test, feature = "fuzzing"))]
21use diem_crypto::hash::TestOnlyHasher;
22use diem_crypto::{
23 hash::{
24 CryptoHash, CryptoHasher, EventAccumulatorHasher,
25 TransactionAccumulatorHasher, SPARSE_MERKLE_PLACEHOLDER_HASH,
26 },
27 HashValue,
28};
29#[cfg(any(test, feature = "fuzzing"))]
30use proptest_derive::Arbitrary;
31use serde::{Deserialize, Serialize};
32use std::marker::PhantomData;
33
34#[derive(Clone, Serialize, Deserialize)]
38pub struct AccumulatorProof<H> {
39 siblings: Vec<HashValue>,
42
43 phantom: PhantomData<H>,
44}
45
46pub type LeafCount = u64;
50pub const MAX_ACCUMULATOR_PROOF_DEPTH: usize = 63;
51pub const MAX_ACCUMULATOR_LEAVES: LeafCount = 1 << MAX_ACCUMULATOR_PROOF_DEPTH;
52
53impl<H> AccumulatorProof<H>
54where H: CryptoHasher
55{
56 pub fn new(siblings: Vec<HashValue>) -> Self {
58 AccumulatorProof {
59 siblings,
60 phantom: PhantomData,
61 }
62 }
63
64 pub fn siblings(&self) -> &[HashValue] { &self.siblings }
66
67 pub fn verify(
71 &self, expected_root_hash: HashValue, element_hash: HashValue,
72 element_index: u64,
73 ) -> Result<()> {
74 ensure!(
75 self.siblings.len() <= MAX_ACCUMULATOR_PROOF_DEPTH,
76 "Accumulator proof has more than {} ({}) siblings.",
77 MAX_ACCUMULATOR_PROOF_DEPTH,
78 self.siblings.len()
79 );
80
81 let actual_root_hash = self
82 .siblings
83 .iter()
84 .fold(
85 (element_hash, element_index),
86 |(hash, index), sibling_hash| {
89 (
90 if index % 2 == 0 {
91 MerkleTreeInternalNode::<H>::new(
93 hash,
94 *sibling_hash,
95 )
96 .hash()
97 } else {
98 MerkleTreeInternalNode::<H>::new(
100 *sibling_hash,
101 hash,
102 )
103 .hash()
104 },
105 index / 2,
107 )
108 },
109 )
110 .0;
111 ensure!(
112 actual_root_hash == expected_root_hash,
113 "Root hashes do not match. Actual root hash: {:x}. Expected root hash: {:x}.",
114 actual_root_hash,
115 expected_root_hash
116 );
117
118 Ok(())
119 }
120}
121
122impl<H> std::fmt::Debug for AccumulatorProof<H> {
123 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
124 write!(f, "AccumulatorProof {{ siblings: {:?} }}", self.siblings)
125 }
126}
127
128impl<H> PartialEq for AccumulatorProof<H> {
129 fn eq(&self, other: &Self) -> bool { self.siblings == other.siblings }
130}
131
132impl<H> Eq for AccumulatorProof<H> {}
133
134pub type TransactionAccumulatorProof =
135 AccumulatorProof<TransactionAccumulatorHasher>;
136pub type EventAccumulatorProof = AccumulatorProof<EventAccumulatorHasher>;
137#[cfg(any(test, feature = "fuzzing"))]
138pub type TestAccumulatorProof = AccumulatorProof<TestOnlyHasher>;
139
140#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
144pub struct SparseMerkleProof<V> {
145 leaf: Option<SparseMerkleLeafNode>,
158
159 siblings: Vec<HashValue>,
162
163 phantom: PhantomData<V>,
164}
165
166impl<V> SparseMerkleProof<V>
167where V: CryptoHash
168{
169 pub fn new(
171 leaf: Option<SparseMerkleLeafNode>, siblings: Vec<HashValue>,
172 ) -> Self {
173 SparseMerkleProof {
174 leaf,
175 siblings,
176 phantom: PhantomData,
177 }
178 }
179
180 pub fn leaf(&self) -> Option<SparseMerkleLeafNode> { self.leaf }
182
183 pub fn siblings(&self) -> &[HashValue] { &self.siblings }
185
186 pub fn verify(
192 &self, expected_root_hash: HashValue, element_key: HashValue,
193 element_value: Option<&V>,
194 ) -> Result<()> {
195 ensure!(
196 self.siblings.len() <= HashValue::LENGTH_IN_BITS,
197 "Sparse Merkle Tree proof has more than {} ({}) siblings.",
198 HashValue::LENGTH_IN_BITS,
199 self.siblings.len(),
200 );
201
202 match (element_value, self.leaf) {
203 (Some(value), Some(leaf)) => {
204 ensure!(
209 element_key == leaf.key,
210 "Keys do not match. Key in proof: {:x}. Expected key: {:x}.",
211 leaf.key,
212 element_key
213 );
214 let hash = value.hash();
215 ensure!(
216 hash == leaf.value_hash,
217 "Value hashes do not match. Value hash in proof: {:x}. \
218 Expected value hash: {:x}",
219 leaf.value_hash,
220 hash,
221 );
222 }
223 (Some(_value), None) => {
224 bail!("Expected inclusion proof. Found non-inclusion proof.")
225 }
226 (None, Some(leaf)) => {
227 ensure!(
234 element_key != leaf.key,
235 "Expected non-inclusion proof, but key exists in proof.",
236 );
237 ensure!(
238 element_key.common_prefix_bits_len(leaf.key) >= self.siblings.len(),
239 "Key would not have ended up in the subtree where the provided key in proof \
240 is the only existing key, if it existed. So this is not a valid \
241 non-inclusion proof.",
242 );
243 }
244 (None, None) => {
245 }
251 }
252
253 let current_hash = self
254 .leaf
255 .map_or(*SPARSE_MERKLE_PLACEHOLDER_HASH, |leaf| leaf.hash());
256 let actual_root_hash = self
257 .siblings
258 .iter()
259 .zip(
260 element_key
261 .iter_bits()
262 .rev()
263 .skip(HashValue::LENGTH_IN_BITS - self.siblings.len()),
264 )
265 .fold(current_hash, |hash, (sibling_hash, bit)| {
266 if bit {
267 SparseMerkleInternalNode::new(*sibling_hash, hash).hash()
268 } else {
269 SparseMerkleInternalNode::new(hash, *sibling_hash).hash()
270 }
271 });
272 ensure!(
273 actual_root_hash == expected_root_hash,
274 "Root hashes do not match. Actual root hash: {:x}. Expected root hash: {:x}.",
275 actual_root_hash,
276 expected_root_hash,
277 );
278
279 Ok(())
280 }
281}
282
283#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
293pub struct AccumulatorConsistencyProof {
294 subtrees: Vec<HashValue>,
296}
297
298impl AccumulatorConsistencyProof {
299 pub fn new(subtrees: Vec<HashValue>) -> Self { Self { subtrees } }
301
302 pub fn subtrees(&self) -> &[HashValue] { &self.subtrees }
304}
305
306#[derive(Clone, Deserialize, Serialize)]
326pub struct AccumulatorRangeProof<H> {
327 left_siblings: Vec<HashValue>,
330
331 right_siblings: Vec<HashValue>,
334
335 phantom: PhantomData<H>,
336}
337
338impl<H> AccumulatorRangeProof<H>
339where H: CryptoHasher
340{
341 pub fn new(
344 left_siblings: Vec<HashValue>, right_siblings: Vec<HashValue>,
345 ) -> Self {
346 Self {
347 left_siblings,
348 right_siblings,
349 phantom: PhantomData,
350 }
351 }
352
353 pub fn new_empty() -> Self { Self::new(vec![], vec![]) }
355
356 pub fn left_siblings(&self) -> &Vec<HashValue> { &self.left_siblings }
358
359 pub fn right_siblings(&self) -> &Vec<HashValue> { &self.right_siblings }
361
362 pub fn verify(
366 &self, expected_root_hash: HashValue, first_leaf_index: Option<u64>,
367 leaf_hashes: &[HashValue],
368 ) -> Result<()> {
369 if first_leaf_index.is_none() {
370 ensure!(
371 leaf_hashes.is_empty(),
372 "first_leaf_index indicated empty list while leaf_hashes is not empty.",
373 );
374 ensure!(
375 self.left_siblings.is_empty() && self.right_siblings.is_empty(),
376 "No siblings are needed.",
377 );
378 return Ok(());
379 }
380
381 ensure!(
382 self.left_siblings.len() <= MAX_ACCUMULATOR_PROOF_DEPTH,
383 "Proof has more than {} ({}) left siblings.",
384 MAX_ACCUMULATOR_PROOF_DEPTH,
385 self.left_siblings.len(),
386 );
387 ensure!(
388 self.right_siblings.len() <= MAX_ACCUMULATOR_PROOF_DEPTH,
389 "Proof has more than {} ({}) right siblings.",
390 MAX_ACCUMULATOR_PROOF_DEPTH,
391 self.right_siblings.len(),
392 );
393 ensure!(
394 !leaf_hashes.is_empty(),
395 "leaf_hashes is empty while first_leaf_index indicated non-empty list.",
396 );
397
398 let mut left_sibling_iter = self.left_siblings.iter().peekable();
399 let mut right_sibling_iter = self.right_siblings.iter().peekable();
400
401 let mut first_pos = Position::from_leaf_index(
402 first_leaf_index.expect("first_leaf_index should not be None."),
403 );
404 let mut current_hashes = leaf_hashes.to_vec();
405 let mut parent_hashes = vec![];
406
407 while current_hashes.len() > 1
410 || left_sibling_iter.peek().is_some()
411 || right_sibling_iter.peek().is_some()
412 {
413 let mut children_iter = current_hashes.iter();
414
415 if first_pos.is_right_child() {
418 let left_hash = *left_sibling_iter.next().ok_or_else(|| {
419 format_err!("First child is a right child, but missing sibling on the left.")
420 })?;
421 let right_hash =
422 *children_iter.next().expect("The first leaf must exist.");
423 parent_hashes.push(
424 MerkleTreeInternalNode::<H>::new(left_hash, right_hash)
425 .hash(),
426 );
427 }
428
429 let mut children_iter = children_iter.as_slice().chunks_exact(2);
431 while let Some(chunk) = children_iter.next() {
432 let left_hash = chunk[0];
433 let right_hash = chunk[1];
434 parent_hashes.push(
435 MerkleTreeInternalNode::<H>::new(left_hash, right_hash)
436 .hash(),
437 );
438 }
439
440 let remainder = children_iter.remainder();
443 assert!(remainder.len() <= 1);
444 if !remainder.is_empty() {
445 let left_hash = remainder[0];
446 let right_hash = *right_sibling_iter.next().ok_or_else(|| {
447 format_err!("Last child is a left child, but missing sibling on the right.")
448 })?;
449 parent_hashes.push(
450 MerkleTreeInternalNode::<H>::new(left_hash, right_hash)
451 .hash(),
452 );
453 }
454
455 first_pos = first_pos.parent();
456 current_hashes.clear();
457 std::mem::swap(&mut current_hashes, &mut parent_hashes);
458 }
459
460 ensure!(
461 current_hashes[0] == expected_root_hash,
462 "Root hashes do not match. Actual root hash: {:x}. Expected root hash: {:x}.",
463 current_hashes[0],
464 expected_root_hash,
465 );
466
467 Ok(())
468 }
469}
470
471impl<H> std::fmt::Debug for AccumulatorRangeProof<H> {
472 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
473 write!(
474 f,
475 "AccumulatorRangeProof {{ left_siblings: {:?}, right_siblings: {:?} }}",
476 self.left_siblings, self.right_siblings,
477 )
478 }
479}
480
481impl<H> PartialEq for AccumulatorRangeProof<H> {
482 fn eq(&self, other: &Self) -> bool {
483 self.left_siblings == other.left_siblings
484 && self.right_siblings == other.right_siblings
485 }
486}
487
488impl<H> Eq for AccumulatorRangeProof<H> {}
489
490pub type TransactionAccumulatorRangeProof =
491 AccumulatorRangeProof<TransactionAccumulatorHasher>;
492#[cfg(any(test, feature = "fuzzing"))]
493pub type TestAccumulatorRangeProof = AccumulatorRangeProof<TestOnlyHasher>;
494
495#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
498#[cfg_attr(any(test, feature = "fuzzing"), derive(Arbitrary))]
499pub struct TransactionInfoWithProof {
500 ledger_info_to_transaction_info_proof: TransactionAccumulatorProof,
503
504 transaction_info: TransactionInfo,
506}
507
508impl TransactionInfoWithProof {
509 pub fn new(
512 ledger_info_to_transaction_info_proof: TransactionAccumulatorProof,
513 transaction_info: TransactionInfo,
514 ) -> Self {
515 Self {
516 ledger_info_to_transaction_info_proof,
517 transaction_info,
518 }
519 }
520
521 pub fn ledger_info_to_transaction_info_proof(
524 &self,
525 ) -> &TransactionAccumulatorProof {
526 &self.ledger_info_to_transaction_info_proof
527 }
528
529 pub fn transaction_info(&self) -> &TransactionInfo {
531 &self.transaction_info
532 }
533
534 pub fn verify(
537 &self, ledger_info: &LedgerInfo, transaction_version: Version,
538 ) -> Result<()> {
539 verify_transaction_info(
540 ledger_info,
541 transaction_version,
542 &self.transaction_info,
543 &self.ledger_info_to_transaction_info_proof,
544 )?;
545 Ok(())
546 }
547}
548
549#[derive(Clone, Debug, Eq, PartialEq, Deserialize, Serialize)]
551#[cfg_attr(any(test, feature = "fuzzing"), derive(Arbitrary))]
552pub struct TransactionListProof {
553 ledger_info_to_transaction_infos_proof: TransactionAccumulatorRangeProof,
556
557 transaction_infos: Vec<TransactionInfo>,
559}
560
561impl TransactionListProof {
562 pub fn new(
565 ledger_info_to_transaction_infos_proof: TransactionAccumulatorRangeProof,
566 transaction_infos: Vec<TransactionInfo>,
567 ) -> Self {
568 Self {
569 ledger_info_to_transaction_infos_proof,
570 transaction_infos,
571 }
572 }
573
574 pub fn new_empty() -> Self {
576 Self::new(AccumulatorRangeProof::new_empty(), vec![])
577 }
578
579 pub fn transaction_infos(&self) -> &[TransactionInfo] {
581 &self.transaction_infos
582 }
583
584 pub fn left_siblings(&self) -> &Vec<HashValue> {
585 self.ledger_info_to_transaction_infos_proof.left_siblings()
586 }
587
588 pub fn unpack(
589 self,
590 ) -> (TransactionAccumulatorRangeProof, Vec<TransactionInfo>) {
591 (
592 self.ledger_info_to_transaction_infos_proof,
593 self.transaction_infos,
594 )
595 }
596
597 pub fn verify(
601 &self, ledger_info: &LedgerInfo,
602 first_transaction_version: Option<Version>,
603 transaction_hashes: &[HashValue],
604 ) -> Result<()> {
605 ensure!(
606 self.transaction_infos.len() == transaction_hashes.len(),
607 "The number of TransactionInfo objects ({}) does not match the number of \
608 transactions ({}).",
609 self.transaction_infos.len(),
610 transaction_hashes.len(),
611 );
612
613 itertools::zip_eq(transaction_hashes, &self.transaction_infos)
614 .map(|(txn_hash, txn_info)| {
615 ensure!(
616 *txn_hash == txn_info.transaction_hash(),
617 "The hash of transaction does not match the transaction info in proof. \
618 Transaction hash: {:x}. Transaction hash in txn_info: {:x}.",
619 txn_hash,
620 txn_info.transaction_hash(),
621 );
622 Ok(())
623 })
624 .collect::<Result<Vec<_>>>()?;
625
626 let txn_info_hashes: Vec<_> = self
627 .transaction_infos
628 .iter()
629 .map(CryptoHash::hash)
630 .collect();
631 self.ledger_info_to_transaction_infos_proof.verify(
632 ledger_info.transaction_accumulator_hash(),
633 first_transaction_version,
634 &txn_info_hashes,
635 )?;
636 Ok(())
637 }
638}
639
640#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
643pub struct AccumulatorExtensionProof<H> {
644 frozen_subtree_roots: Vec<HashValue>,
647 num_leaves: LeafCount,
649 leaves: Vec<HashValue>,
651
652 hasher: PhantomData<H>,
653}
654
655impl<H: CryptoHasher> AccumulatorExtensionProof<H> {
656 pub fn new(
657 frozen_subtree_roots: Vec<HashValue>, num_leaves: LeafCount,
658 leaves: Vec<HashValue>,
659 ) -> Self {
660 Self {
661 frozen_subtree_roots,
662 num_leaves,
663 leaves,
664 hasher: PhantomData,
665 }
666 }
667
668 pub fn verify(
669 &self, _original_root: HashValue,
670 ) -> anyhow::Result<InMemoryAccumulator<H>> {
671 let original_tree = InMemoryAccumulator::<H>::new(
672 self.frozen_subtree_roots.clone(),
673 self.num_leaves,
674 )?;
675 Ok(original_tree.append(self.leaves.as_slice()))
683 }
684}