jmt/types/proof/definition.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775
// Copyright (c) The Diem Core Contributors
// SPDX-License-Identifier: Apache-2.0
//! This module has definition of various proofs.
use core::marker::PhantomData;
use super::{SparseMerkleInternalNode, SparseMerkleLeafNode, SparseMerkleNode};
use crate::{
storage::Node,
types::nibble::nibble_path::{skip_common_prefix, NibblePath},
Bytes32Ext, KeyHash, RootHash, SimpleHasher, ValueHash, SPARSE_MERKLE_PLACEHOLDER_HASH,
};
use alloc::vec::Vec;
use anyhow::{bail, ensure, format_err, Result};
use serde::{Deserialize, Serialize};
/// A proof that can be used to authenticate an element in a Sparse Merkle Tree given trusted root
/// hash. For example, `TransactionInfoToAccountProof` can be constructed on top of this structure.
#[derive(Serialize, Deserialize, borsh::BorshSerialize, borsh::BorshDeserialize)]
pub struct SparseMerkleProof<H: SimpleHasher> {
/// This proof can be used to authenticate whether a given leaf exists in the tree or not.
/// - If this is `Some(leaf_node)`
/// - If `leaf_node.key` equals requested key, this is an inclusion proof and
/// `leaf_node.value_hash` equals the hash of the corresponding account blob.
/// - Otherwise this is a non-inclusion proof. `leaf_node.key` is the only key
/// that exists in the subtree and `leaf_node.value_hash` equals the hash of the
/// corresponding account blob.
/// - If this is `None`, this is also a non-inclusion proof which indicates the subtree is
/// empty.
// Prevent serde from adding a spurious Serialize/Deserialize bound on H
#[serde(bound(serialize = "", deserialize = ""))]
leaf: Option<SparseMerkleLeafNode>,
/// All siblings in this proof, including the default ones. Siblings are ordered from the bottom
/// level to the root level. The siblings contain the node type information to be able to efficiently
/// coalesce on deletes.
siblings: Vec<SparseMerkleNode>,
/// A marker type showing which hash function is used in this proof.
phantom_hasher: PhantomData<H>,
}
// Deriving Debug fails since H is not Debug though phantom_hasher implements it
// generically. Implement Debug manually as a workaround to enable Proptest
impl<H: SimpleHasher> core::fmt::Debug for SparseMerkleProof<H> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("SparseMerkleProof")
.field("leaf", &self.leaf)
.field("siblings", &self.siblings)
.field("phantom_hasher", &self.phantom_hasher)
.finish()
}
}
// Manually implement PartialEq to circumvent [incorrect auto-bounds](https://github.com/rust-lang/rust/issues/26925)
// TODO: Switch back to #[derive] once the perfect_derive feature lands
impl<H: SimpleHasher> PartialEq for SparseMerkleProof<H> {
fn eq(&self, other: &Self) -> bool {
self.leaf == other.leaf && self.siblings == other.siblings
}
}
// Manually implement Clone to circumvent [incorrect auto-bounds](https://github.com/rust-lang/rust/issues/26925)
// TODO: Switch back to #[derive] once the perfect_derive feature lands
impl<H: SimpleHasher> Clone for SparseMerkleProof<H> {
fn clone(&self) -> Self {
Self {
leaf: self.leaf.clone(),
siblings: self.siblings.clone(),
phantom_hasher: Default::default(),
}
}
}
impl<H: SimpleHasher> SparseMerkleProof<H> {
/// Constructs a new `SparseMerkleProof` using leaf and a list of siblings.
pub(crate) fn new(leaf: Option<SparseMerkleLeafNode>, siblings: Vec<SparseMerkleNode>) -> Self {
SparseMerkleProof {
leaf,
siblings,
phantom_hasher: Default::default(),
}
}
/// Returns the leaf node in this proof.
pub fn leaf(&self) -> Option<SparseMerkleLeafNode> {
self.leaf.clone()
}
/// Returns the list of siblings in this proof.
pub(crate) fn siblings(&self) -> &[SparseMerkleNode] {
&self.siblings
}
pub(crate) fn take_siblings(self) -> Vec<SparseMerkleNode> {
self.siblings
}
/// Verifies an element whose key is `element_key` and value is
/// `element_value` exists in the Sparse Merkle Tree using the provided proof.
pub fn verify_existence<V: AsRef<[u8]>>(
&self,
expected_root_hash: RootHash,
element_key: KeyHash,
element_value: V,
) -> Result<()> {
self.verify(expected_root_hash, element_key, Some(element_value))
}
/// Verifies the proof is a valid non-inclusion proof that shows this key doesn't exist in the
/// tree.
pub fn verify_nonexistence(
&self,
expected_root_hash: RootHash,
element_key: KeyHash,
) -> Result<()> {
self.verify(expected_root_hash, element_key, None::<&[u8]>)
}
/// If `element_value` is present, verifies an element whose key is `element_key` and value is
/// `element_value` exists in the Sparse Merkle Tree using the provided proof. Otherwise
/// verifies the proof is a valid non-inclusion proof that shows this key doesn't exist in the
/// tree.
pub fn verify<V: AsRef<[u8]>>(
&self,
expected_root_hash: RootHash,
element_key: KeyHash,
element_value: Option<V>,
) -> Result<()> {
ensure!(
self.siblings.len() <= 256,
"Sparse Merkle Tree proof has more than {} ({}) siblings.",
256,
self.siblings.len(),
);
match (element_value, self.leaf.clone()) {
(Some(value), Some(leaf)) => {
// This is an inclusion proof, so the key and value hash provided in the proof
// should match element_key and element_value_hash. `siblings` should prove the
// route from the leaf node to the root.
ensure!(
element_key == leaf.key_hash,
"Keys do not match. Key in proof: {:?}. Expected key: {:?}.",
leaf.key_hash,
element_key
);
let hash: ValueHash = ValueHash::with::<H>(value);
ensure!(
hash == leaf.value_hash,
"Value hashes do not match. Value hash in proof: {:?}. \
Expected value hash: {:?}",
leaf.value_hash,
hash,
);
}
(Some(_value), None) => bail!("Expected inclusion proof. Found non-inclusion proof."),
(None, Some(leaf)) => {
// This is a non-inclusion proof. The proof intends to show that if a leaf node
// representing `element_key` is inserted, it will break a currently existing leaf
// node represented by `proof_key` into a branch. `siblings` should prove the
// route from that leaf node to the root.
ensure!(
element_key != leaf.key_hash,
"Expected non-inclusion proof, but key exists in proof.",
);
ensure!(
element_key.0.common_prefix_bits_len(&leaf.key_hash.0) >= self.siblings.len(),
"Key would not have ended up in the subtree where the provided key in proof \
is the only existing key, if it existed. So this is not a valid \
non-inclusion proof.",
);
}
(None, None) => {
// This is a non-inclusion proof. The proof intends to show that if a leaf node
// representing `element_key` is inserted, it will show up at a currently empty
// position. `sibling` should prove the route from this empty position to the root.
}
}
let current_hash = self
.leaf
.clone()
.map_or(SPARSE_MERKLE_PLACEHOLDER_HASH, |leaf| leaf.hash::<H>());
let actual_root_hash = self
.siblings
.iter()
.zip(
element_key
.0
.iter_bits()
.rev()
.skip(256 - self.siblings.len()),
)
.fold(current_hash, |hash, (sibling_node, bit)| {
if bit {
SparseMerkleInternalNode::new(sibling_node.hash::<H>(), hash).hash::<H>()
} else {
SparseMerkleInternalNode::new(hash, sibling_node.hash::<H>()).hash::<H>()
}
});
ensure!(
actual_root_hash == expected_root_hash.0,
"Root hashes do not match. Actual root hash: {:?}. Expected root hash: {:?}.",
actual_root_hash,
expected_root_hash.0,
);
Ok(())
}
/// This function computes a new merkle path on split insertion (ie when inserting a new value creates
/// a key split).
///
/// Add the correct siblings of the new merkle path by finding the splitting nibble and
/// adding the default leaves to the path
///
/// To compute the number of default leaves we need to add, we need to:
/// - Compute the number of default leaves to separate the old leaf from the new leaf in the last nibble
/// - Compute the number of default leaves to traverse the common prefix
/// - Compute the number of default leaves remaining to select the former old leaf in the former last nibble
/// (this leaf becomes an internal node, hence the path needs to be fully specified)
fn compute_new_merkle_path_on_split<V: AsRef<[u8]>>(
mut self,
leaf_node: SparseMerkleLeafNode,
new_element_key: KeyHash,
new_element_value: V,
) -> SparseMerkleProof<H> {
let new_key_path = NibblePath::new(new_element_key.0.to_vec());
let old_key_path = NibblePath::new(leaf_node.key_hash.0.to_vec());
// The verify_nonexistence check from before ensure that the common prefix nibbles_len is greater than the
// siblings len
let mut new_key_nibbles = new_key_path.nibbles();
let mut old_key_nibbles = old_key_path.nibbles();
let common_prefix_len = skip_common_prefix(&mut new_key_nibbles, &mut old_key_nibbles);
let num_siblings = self.siblings().len();
// The number of default leaves we need to add to the path.
let default_leaves_to_add_to_the_path =
((4 * (common_prefix_len + 1) - num_siblings) / 4) * 4;
// This variable contains the number of default siblings that are inserted within the last nibble subtree to distinguish
// between the former and the new key. Since we are splitting the former key, we are creating a new level of the jmt
// that only contains the new and the former key. When converted into a binary tree, we need to add default leaves to
// reach the binary tree level that can distinguish the two keys. This amounts adding as many default leaves as there
// are bits in common in the last nibble of both keys.
let mut default_siblings_leaf_nibble = 0;
// We can safely unwrap these values as the check have been already performed in verify_nonexistence
let mut new_key_bits = new_key_nibbles.bits();
let mut old_key_bits = old_key_nibbles.bits();
// Hence, we have to add the number of bits in common in both keys.
while new_key_bits.next() == old_key_bits.next() {
default_siblings_leaf_nibble += 1;
}
// The number of default leaves we need to add to the previous root. When splitting a leaf node, we create a new internal node
// in place of the former leaf that has two leaf children. Hence we need to add some default siblings because the leaf node may
// not be at the last level of the subtree of the last nibble.
// To get this number, we need to take the number of siblings modulo 4 (this yields the hight of the splitted leaf in the last binary subtree,
// or the number of bits in the last nibble of the splitted leaf), substract it to 4 (to get the number of bits needed to complete the last nibble)
// and then take the result modulo 4 (in case num_siblings % 4 is zero, which happens when the leaf is at the lowest height of the last binary subtree).
let default_siblings_prev_root = (4 - (num_siblings % 4)) % 4;
let num_default_siblings = default_siblings_prev_root
+ default_leaves_to_add_to_the_path
+ default_siblings_leaf_nibble
- 4;
let mut new_siblings: Vec<SparseMerkleNode> = Vec::with_capacity(
num_default_siblings + 1 + self.siblings.len(), /* The default siblings, the current leaf that becomes a sibling and the former siblings */
);
// Add the previous leaf node
new_siblings.push(SparseMerkleNode::Leaf(SparseMerkleLeafNode {
key_hash: leaf_node.key_hash,
value_hash: leaf_node.value_hash,
}));
// Fill the siblings with the former default siblings
new_siblings.resize(num_default_siblings + 1, SparseMerkleNode::Null);
// Finally add the other siblings
new_siblings.append(&mut self.siblings);
// Step 2: we compute the new Merkle path (we build a new [`SparseMerkleProof`] object)
// In this case the siblings are left unchanged, only the leaf value is updated
SparseMerkleProof::new(
Some(SparseMerkleLeafNode::new(
new_element_key,
ValueHash::with::<H>(new_element_value),
)),
new_siblings,
)
}
/// Checks the old value against the root hash and computes the new root hash based on
/// the new key value pair
fn check_compute_new_root<V: AsRef<[u8]>>(
self,
old_root_hash: RootHash,
new_element_key: KeyHash,
new_element_value: Option<V>,
) -> Result<RootHash> {
if let Some(new_element_value) = new_element_value {
// A value have been supplied, we need to prove that we inserted a given value at the new key
match self.leaf {
// In the case there is a leaf in the Merkle path, we check that this leaf exists in the tree
// The inserted key is going to update an existing leaf
Some(leaf_node) => {
// First verify that the old merkle path is valid
ensure!(self.root_hash() == old_root_hash);
if new_element_key == leaf_node.key_hash {
// Step 2: we compute the new Merkle path (we build a new [`SparseMerkleProof`] object)
// In this case the siblings are left unchanged, only the leaf value is updated
let new_merkle_path: SparseMerkleProof<H> = SparseMerkleProof::new(
Some(SparseMerkleLeafNode::new(
new_element_key,
ValueHash::with::<H>(new_element_value),
)),
self.siblings,
);
// Step 3: we compute the new Merkle root
Ok(new_merkle_path.root_hash())
} else {
let new_merkle_path = self.compute_new_merkle_path_on_split(
leaf_node,
new_element_key,
new_element_value,
);
// Step 3: we compute the new Merkle root
Ok(new_merkle_path.root_hash())
}
}
// There is no leaf in the Merkle path, which means the key we are going to insert does not update an existing leaf
None => {
ensure!(self
.verify_nonexistence(old_root_hash, new_element_key)
.is_ok());
// Step 2: we compute the new Merkle path (we build a new [`SparseMerkleProof`] object)
// In that case, the leaf is none so we don't need to change the siblings
let new_merkle_path: SparseMerkleProof<H> = SparseMerkleProof::new(
Some(SparseMerkleLeafNode::new(
new_element_key,
ValueHash::with::<H>(new_element_value),
)),
self.siblings,
);
// Step 3: we compute the new Merkle root
Ok(new_merkle_path.root_hash())
}
}
} else {
// No value supplied, we need to prove that the previous value was deleted
if let Some(leaf_node) = self.leaf {
ensure!(self.root_hash() == old_root_hash);
ensure!(
new_element_key == leaf_node.key_hash,
"Key {:?} to remove doesn't match the leaf key {:?} supplied with the proof",
new_element_key,
leaf_node.key_hash
);
// Step 2: we compute the new Merkle tree path.
// In case of deletion, we need to rewind the nibble until we reach the first non-default hash
// to simulate node coalescing.
// Then, when we reach the first non-default hash, we have to compute the new merkle path
// We have two different cases:
// - the first non-default sibling is an internal node: we don't apply coalescing.
// - the first non-default sibling is a leaf node: we apply coalescing
let mut siblings_it = self.siblings.into_iter().peekable();
let mut next_non_default_sib = SparseMerkleNode::Null;
while let Some(next_sibling) = siblings_it.peek() {
if *next_sibling != SparseMerkleNode::Null {
next_non_default_sib = *next_sibling;
break;
}
siblings_it.next();
}
let new_merkle_hash = match next_non_default_sib {
SparseMerkleNode::Internal(_) => {
// We need to keep the internal node in the iterator and simply compute the merkle path using the
// default leave as the root
let remaining_siblings_len = siblings_it.len();
// If the sibling is an internal node, it doesn't get coalesced after deletion.
RootHash(
siblings_it
.zip(
new_element_key
.0
.iter_bits()
.rev()
.skip(256 - remaining_siblings_len),
)
.fold(Node::new_null().hash::<H>(), |hash, (sibling_node, bit)| {
if bit {
SparseMerkleInternalNode::new(
sibling_node.hash::<H>(),
hash,
)
.hash::<H>()
} else {
SparseMerkleInternalNode::new(
hash,
sibling_node.hash::<H>(),
)
.hash::<H>()
}
}),
)
}
SparseMerkleNode::Leaf(_) => {
// We need to remove the leaf from the iterator
siblings_it.next();
// We have to remove the default leaves left in the siblings before the next root: coalescing
while let Some(next_sibling) = siblings_it.peek() {
if *next_sibling != SparseMerkleNode::Null {
break;
}
siblings_it.next();
}
let remaining_siblings_len = siblings_it.len();
// If the sibling is a leaf, we need to start computing the merkle hash from the leaf value
// because the node gets coalesced
RootHash(
siblings_it
.zip(
new_element_key
.0
.iter_bits()
.rev()
.skip(256 - remaining_siblings_len),
)
.fold(
next_non_default_sib.hash::<H>(),
|hash, (sibling_node, bit)| {
if bit {
SparseMerkleInternalNode::new(
sibling_node.hash::<H>(),
hash,
)
.hash::<H>()
} else {
SparseMerkleInternalNode::new(
hash,
sibling_node.hash::<H>(),
)
.hash::<H>()
}
},
),
)
// Step 3: we compute the new Merkle root
}
SparseMerkleNode::Null => RootHash(SPARSE_MERKLE_PLACEHOLDER_HASH),
};
Ok(new_merkle_hash)
} else {
// We just return the old root hash if we try to remove the empty node
// because there isn't any changes to the merkle tree
Ok(old_root_hash)
}
}
}
pub fn root_hash(&self) -> RootHash {
let current_hash = self
.leaf
.clone()
.map_or(SPARSE_MERKLE_PLACEHOLDER_HASH, |leaf| leaf.hash::<H>());
let actual_root_hash = self
.siblings
.iter()
.zip(
self.leaf()
.expect("need leaf hash for root_hash")
.key_hash
.0
.iter_bits()
.rev()
.skip(256 - self.siblings.len()),
)
.fold(current_hash, |hash, (sibling_node, bit)| {
if bit {
SparseMerkleInternalNode::new(sibling_node.hash::<H>(), hash).hash::<H>()
} else {
SparseMerkleInternalNode::new(hash, sibling_node.hash::<H>()).hash::<H>()
}
});
RootHash(actual_root_hash)
}
}
#[derive(Debug, Serialize, Deserialize, borsh::BorshSerialize, borsh::BorshDeserialize)]
pub struct UpdateMerkleProof<H: SimpleHasher>(Vec<SparseMerkleProof<H>>);
impl<H: SimpleHasher> UpdateMerkleProof<H> {
pub fn new(merkle_proofs: Vec<SparseMerkleProof<H>>) -> Self {
UpdateMerkleProof(merkle_proofs)
}
/// Verifies an update of the [`JellyfishMerkleTree`], proving the transition from an `old_root_hash` to a `new_root_hash` ([`RootHash`])
/// Multiple cases to handle:
/// - Insert a tuple `new_element_key`, `new_element_value`
/// - Update a tuple `new_element_key`, `new_element_value`
/// - Delete the `new_element_key`
/// This function does the following high level operations:
/// 1. Verify the Merkle path provided against the `old_root_hash`
/// 2. Use the provided Merkle path and the tuple (`new_element_key`, `new_element_value`) to compute the new Merkle path.
/// 3. Compare the new Merkle path against the new_root_hash
/// If these steps are verified then the [`JellyfishMerkleTree`] has been soundly updated
///
/// This function consumes the Merkle proof to avoid uneccessary copying.
pub fn verify_update<V: AsRef<[u8]>>(
self,
old_root_hash: RootHash,
new_root_hash: RootHash,
updates: impl AsRef<[(KeyHash, Option<V>)]>,
) -> Result<()> {
let updates = updates.as_ref();
ensure!(
updates.len() == self.0.len(),
"Mismatched number of updates and proofs. Received {} proofs for {} updates",
self.0.len(),
updates.len()
);
let mut curr_root_hash = old_root_hash;
for (merkle_proof, (new_element_key, new_element_value)) in
self.0.into_iter().zip(updates.iter())
{
// Checks the old root hash and computes the new root
curr_root_hash = merkle_proof.check_compute_new_root(
curr_root_hash,
*new_element_key,
new_element_value.as_ref(),
)?;
}
ensure!(
curr_root_hash == new_root_hash,
"Root hashes do not match. Actual root hash: {:?}. Expected root hash: {:?}.",
curr_root_hash,
new_root_hash,
);
Ok(())
}
}
/// Note: this is not a range proof in the sense that a range of nodes is verified!
/// Instead, it verifies the entire left part of the tree up to a known rightmost node.
/// See the description below.
///
/// A proof that can be used to authenticate a range of consecutive leaves, from the leftmost leaf to
/// the rightmost known one, in a sparse Merkle tree. For example, given the following sparse Merkle tree:
///
/// ```text
/// root
/// / \
/// / \
/// / \
/// o o
/// / \ / \
/// a o o h
/// / \ / \
/// o d e X
/// / \ / \
/// b c f g
/// ```
///
/// if the proof wants show that `[a, b, c, d, e]` exists in the tree, it would need the siblings
/// `X` and `h` on the right.
#[derive(Eq, Serialize, Deserialize, borsh::BorshSerialize, borsh::BorshDeserialize)]
pub struct SparseMerkleRangeProof<H: SimpleHasher> {
/// The vector of siblings on the right of the path from root to last leaf. The ones near the
/// bottom are at the beginning of the vector. In the above example, it's `[X, h]`.
right_siblings: Vec<SparseMerkleNode>,
_phantom: PhantomData<H>,
}
// Manually implement PartialEq to circumvent [incorrect auto-bounds](https://github.com/rust-lang/rust/issues/26925)
// TODO: Switch back to #[derive] once the perfect_derive feature lands
impl<H: SimpleHasher> PartialEq for SparseMerkleRangeProof<H> {
fn eq(&self, other: &Self) -> bool {
self.right_siblings == other.right_siblings
}
}
// Manually implement Clone to circumvent [incorrect auto-bounds](https://github.com/rust-lang/rust/issues/26925)
// TODO: Switch back to #[derive] once the perfect_derive feature lands
impl<H: SimpleHasher> Clone for SparseMerkleRangeProof<H> {
fn clone(&self) -> Self {
Self {
right_siblings: self.right_siblings.clone(),
_phantom: self._phantom.clone(),
}
}
}
// Manually implement Debug to circumvent [incorrect auto-bounds](https://github.com/rust-lang/rust/issues/26925)
// TODO: Switch back to #[derive] once the perfect_derive feature lands
impl<H: SimpleHasher> core::fmt::Debug for SparseMerkleRangeProof<H> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("SparseMerkleRangeProof")
.field("right_siblings", &self.right_siblings)
.field("_phantom", &self._phantom)
.finish()
}
}
impl<H: SimpleHasher> SparseMerkleRangeProof<H> {
/// Constructs a new `SparseMerkleRangeProof`.
pub(crate) fn new(right_siblings: Vec<SparseMerkleNode>) -> Self {
Self {
right_siblings,
_phantom: Default::default(),
}
}
/// Returns the right siblings.
pub(crate) fn right_siblings(&self) -> &[SparseMerkleNode] {
&self.right_siblings
}
/// Verifies that the rightmost known leaf exists in the tree and that the resulting
/// root hash matches the expected root hash.
pub fn verify(
&self,
expected_root_hash: RootHash,
rightmost_known_leaf: SparseMerkleLeafNode,
left_siblings: Vec<[u8; 32]>,
) -> Result<()> {
let num_siblings = left_siblings.len() + self.right_siblings.len();
let mut left_sibling_iter = left_siblings.iter();
let mut right_sibling_iter = self.right_siblings().iter();
let mut current_hash = rightmost_known_leaf.hash::<H>();
for bit in rightmost_known_leaf
.key_hash()
.0
.iter_bits()
.rev()
.skip(256 - num_siblings)
{
let (left_hash, right_hash) = if bit {
(
*left_sibling_iter
.next()
.ok_or_else(|| format_err!("Missing left sibling."))?,
current_hash,
)
} else {
(
current_hash,
right_sibling_iter
.next()
.ok_or_else(|| format_err!("Missing right sibling."))?
.hash::<H>(),
)
};
current_hash = SparseMerkleInternalNode::new(left_hash, right_hash).hash::<H>();
}
ensure!(
current_hash == expected_root_hash.0,
"Root hashes do not match. Actual root hash: {:?}. Expected root hash: {:?}.",
current_hash,
expected_root_hash,
);
Ok(())
}
}
#[cfg(test)]
mod serialization_tests {
//! These tests ensure that the various proofs supported by the JMT can actually be serialized and deserialized
//! when instantiated with a specific hasher. This is done as a sanity check to ensure the trait bounds inferred by Rustc
//! are not too restrictive.
use sha2::Sha256;
use crate::{
proof::{SparseMerkleInternalNode, SparseMerkleLeafNode, SparseMerkleNode},
KeyHash, ValueHash,
};
use super::{SparseMerkleProof, SparseMerkleRangeProof};
fn get_test_proof() -> SparseMerkleProof<Sha256> {
SparseMerkleProof {
leaf: Some(SparseMerkleLeafNode::new(
KeyHash([1u8; 32]),
ValueHash([2u8; 32]),
)),
siblings: alloc::vec![SparseMerkleNode::Internal(SparseMerkleInternalNode::new(
[3u8; 32], [4u8; 32]
))],
phantom_hasher: Default::default(),
}
}
fn get_test_range_proof() -> SparseMerkleRangeProof<Sha256> {
SparseMerkleRangeProof {
right_siblings: alloc::vec![SparseMerkleNode::Internal(SparseMerkleInternalNode::new(
[3u8; 32], [4u8; 32]
))],
_phantom: Default::default(),
}
}
#[test]
fn test_sparse_merkle_proof_roundtrip_serde() {
let proof = get_test_proof();
let serialized_proof = serde_json::to_string(&proof).expect("serialization is infallible");
let deserialized =
serde_json::from_str(&serialized_proof).expect("serialized proof is valid");
assert_eq!(proof, deserialized);
}
#[test]
fn test_sparse_merkle_proof_roundtrip_borsh() {
use borsh::BorshDeserialize;
let proof = get_test_proof();
let serialized_proof = borsh::to_vec(&proof).expect("serialization is infallible");
let deserialized =
SparseMerkleProof::<Sha256>::deserialize(&mut serialized_proof.as_slice())
.expect("serialized proof is valid");
assert_eq!(proof, deserialized);
}
#[test]
fn test_sparse_merkle_range_proof_roundtrip_serde() {
let proof = get_test_range_proof();
let serialized_proof = serde_json::to_string(&proof).expect("serialization is infallible");
let deserialized =
serde_json::from_str(&serialized_proof).expect("serialized proof is valid");
assert_eq!(proof, deserialized);
}
#[test]
fn test_sparse_merkle_range_proof_roundtrip_borsh() {
use borsh::BorshDeserialize;
let proof = get_test_range_proof();
let serialized_proof = borsh::to_vec(&proof).expect("serialization is infallible");
let deserialized =
SparseMerkleRangeProof::<Sha256>::deserialize(&mut serialized_proof.as_slice())
.expect("serialized proof is valid");
assert_eq!(proof, deserialized);
}
}