Skip to content

Commit 8f29cba

Browse files
committed
refactor: enhance readability of MKMap tests
And explain further the way MKMapNode work.
1 parent b1e0305 commit 8f29cba

File tree

2 files changed

+100
-36
lines changed

2 files changed

+100
-36
lines changed

mithril-common/src/crypto_helper/merkle_map.rs

Lines changed: 99 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ impl<K: MKMapKey, V: MKMapValue<K>> MKMap<K, V> {
6363
"MKMap values should be replaced by entry with same root"
6464
));
6565
}
66+
self.inner_map_values.insert(key.clone(), value.clone());
67+
return Ok(());
6668
} else {
6769
let key_max = self.inner_map_values.keys().max();
6870
if key_max > Some(&key) {
@@ -253,16 +255,18 @@ impl<K: MKMapKey> From<MKProof> for MKMapProof<K> {
253255
}
254256
}
255257

256-
/// A MKMap node
258+
/// A merkelized map node that is used to represent multi layered merkelized map
259+
/// The MKMapNode can be either a MKMap (Merkle map), a MKTree (full Merkle tree) or a MKTreeNode (Merkle tree node, e.g the root of a Merkle tree)
260+
/// Both MKMap and MKTree can generate proofs of membership for elements that they contain, which allows for recursive proof generation for the multiple layers
257261
#[derive(Clone)]
258262
pub enum MKMapNode<K: MKMapKey> {
259-
/// A MKMap node
263+
/// A Merkle map
260264
Map(Rc<MKMap<K, Self>>),
261265

262-
/// A MKTree node
266+
/// A full Merkle tree
263267
Tree(Rc<MKTree>),
264268

265-
/// A MKTreeNode node
269+
/// A Merkle tree node
266270
TreeNode(MKTreeNode),
267271
}
268272

@@ -357,23 +361,25 @@ mod tests {
357361
) -> Vec<(BlockRange, MKTree)> {
358362
(0..total_leaves / block_range_length)
359363
.map(|block_range_index| {
360-
let block_range = BlockRange::new(
361-
block_range_index * block_range_length,
362-
(block_range_index + 1) * block_range_length,
363-
);
364-
let leaves = <Range<u64> as Clone>::clone(&block_range)
365-
.map(|leaf_index| leaf_index.to_string())
366-
.collect::<Vec<_>>();
367-
let merkle_tree_block_range = MKTree::new(&leaves).unwrap();
368-
364+
let block_range =
365+
BlockRange::from_block_number_and_length(block_range_index, block_range_length)
366+
.unwrap();
367+
let merkle_tree_block_range = generate_merkle_tree(&block_range);
369368
(block_range, merkle_tree_block_range)
370369
})
371370
.collect::<Vec<_>>()
372371
}
373372

373+
fn generate_merkle_tree(block_range: &BlockRange) -> MKTree {
374+
let leaves = <Range<u64> as Clone>::clone(block_range)
375+
.map(|leaf_index| leaf_index.to_string())
376+
.collect::<Vec<_>>();
377+
MKTree::new(&leaves).unwrap()
378+
}
379+
374380
#[test]
375-
fn test_mk_map_should_compute_consistent_root() {
376-
let entries = generate_merkle_trees(100000, 100);
381+
fn test_mk_map_should_compute_same_root_when_replacing_entry_with_equivalent() {
382+
let entries = generate_merkle_trees(10, 3);
377383
let merkle_tree_node_entries = &entries
378384
.iter()
379385
.map(|(range, mktree)| {
@@ -387,7 +393,6 @@ mod tests {
387393
.into_iter()
388394
.map(|(range, mktree)| (range.to_owned(), mktree.into()))
389395
.collect::<Vec<(_, MKMapNode<_>)>>();
390-
391396
let mk_map_nodes = MKMap::new(merkle_tree_node_entries.as_slice()).unwrap();
392397
let mk_map_full = MKMap::new(merkle_tree_full_entries.as_slice()).unwrap();
393398

@@ -399,44 +404,70 @@ mod tests {
399404

400405
#[test]
401406
fn test_mk_map_should_accept_replacement_with_same_root_value() {
402-
let entries = generate_merkle_trees(1000, 10);
407+
let entries = [
408+
BlockRange::new(0, 3),
409+
BlockRange::new(4, 6),
410+
BlockRange::new(7, 9),
411+
]
412+
.iter()
413+
.map(|block_range| (block_range.to_owned(), generate_merkle_tree(block_range)))
414+
.collect::<Vec<_>>();
403415
let merkle_tree_entries = &entries
404416
.into_iter()
405417
.map(|(range, mktree)| (range.to_owned(), mktree.into()))
406418
.collect::<Vec<(_, MKMapNode<_>)>>();
407419
let mut mk_map = MKMap::new(merkle_tree_entries.as_slice()).unwrap();
408-
let block_range_replacement = BlockRange::new(0, 10);
420+
let mk_map_root_expected = mk_map.compute_root().unwrap();
421+
let block_range_replacement = BlockRange::new(0, 3);
409422
let same_root_value = MKMapNode::TreeNode(
410423
mk_map
411424
.get(&block_range_replacement)
412425
.unwrap()
413426
.compute_root()
414427
.unwrap(),
415428
);
429+
416430
mk_map
417431
.insert(block_range_replacement, same_root_value)
418432
.unwrap();
433+
434+
assert_eq!(mk_map_root_expected, mk_map.compute_root().unwrap())
419435
}
420436

421437
#[test]
422438
fn test_mk_map_should_reject_replacement_with_different_root_value() {
423-
let entries = generate_merkle_trees(1000, 10);
439+
let entries = [
440+
BlockRange::new(0, 3),
441+
BlockRange::new(4, 6),
442+
BlockRange::new(7, 9),
443+
]
444+
.iter()
445+
.map(|block_range| (block_range.to_owned(), generate_merkle_tree(block_range)))
446+
.collect::<Vec<_>>();
424447
let merkle_tree_entries = &entries
425448
.into_iter()
426449
.map(|(range, mktree)| (range.to_owned(), mktree.into()))
427450
.collect::<Vec<_>>();
428451
let mut mk_map = MKMap::new(merkle_tree_entries.as_slice()).unwrap();
429-
let block_range_replacement = BlockRange::new(0, 10);
452+
let block_range_replacement = BlockRange::new(0, 3);
430453
let value_replacement: MKTreeNode = "test-123".to_string().into();
431454
let different_root_value = MKMapNode::TreeNode(value_replacement);
455+
432456
mk_map
433457
.insert(block_range_replacement, different_root_value)
434458
.expect_err("the MKMap should reject replacement with different root value");
435459
}
436460

437461
#[test]
438462
fn test_mk_map_should_reject_out_of_order_insertion() {
439-
let entries = generate_merkle_trees(1000, 10);
463+
let entries = [
464+
BlockRange::new(0, 3),
465+
BlockRange::new(4, 6),
466+
BlockRange::new(7, 9),
467+
]
468+
.iter()
469+
.map(|block_range| (block_range.to_owned(), generate_merkle_tree(block_range)))
470+
.collect::<Vec<_>>();
440471
let merkle_tree_entries = &entries
441472
.iter()
442473
.map(|(range, mktree)| {
@@ -451,14 +482,22 @@ mod tests {
451482
BlockRange::new(0, 25),
452483
MKMapNode::TreeNode("test-123".into()),
453484
);
485+
454486
mk_map
455487
.insert(out_of_order_entry.0, out_of_order_entry.1)
456488
.expect_err("the MKMap should reject out of order insertion");
457489
}
458490

459491
#[test]
460492
fn test_mk_map_should_list_keys_correctly() {
461-
let entries = generate_merkle_trees(100000, 100);
493+
let entries = [
494+
BlockRange::new(0, 3),
495+
BlockRange::new(4, 6),
496+
BlockRange::new(7, 9),
497+
]
498+
.iter()
499+
.map(|block_range| (block_range.to_owned(), generate_merkle_tree(block_range)))
500+
.collect::<Vec<_>>();
462501
let merkle_tree_entries = &entries
463502
.iter()
464503
.map(|(range, mktree)| {
@@ -469,6 +508,7 @@ mod tests {
469508
})
470509
.collect::<Vec<_>>();
471510
let mk_map = MKMap::new(merkle_tree_entries.as_slice()).unwrap();
511+
472512
let keys = mk_map
473513
.iter()
474514
.map(|(k, _v)| k.to_owned())
@@ -484,7 +524,14 @@ mod tests {
484524

485525
#[test]
486526
fn test_mk_map_should_list_values_correctly() {
487-
let entries = generate_merkle_trees(100000, 100);
527+
let entries = [
528+
BlockRange::new(0, 3),
529+
BlockRange::new(4, 6),
530+
BlockRange::new(7, 9),
531+
]
532+
.iter()
533+
.map(|block_range| (block_range.to_owned(), generate_merkle_tree(block_range)))
534+
.collect::<Vec<_>>();
488535
let merkle_tree_entries = &entries
489536
.iter()
490537
.map(|(range, mktree)| {
@@ -495,6 +542,7 @@ mod tests {
495542
})
496543
.collect::<Vec<_>>();
497544
let mk_map = MKMap::new(merkle_tree_entries.as_slice()).unwrap();
545+
498546
let values = mk_map
499547
.iter()
500548
.map(|(_k, v)| v.to_owned())
@@ -513,8 +561,15 @@ mod tests {
513561

514562
#[test]
515563
fn test_mk_map_should_find_value_correctly() {
516-
let entries = generate_merkle_trees(100000, 100);
517-
let mktree_node_to_certify = entries[2].1.leaves()[10].clone();
564+
let entries = [
565+
BlockRange::new(0, 3),
566+
BlockRange::new(4, 6),
567+
BlockRange::new(7, 9),
568+
]
569+
.iter()
570+
.map(|block_range| (block_range.to_owned(), generate_merkle_tree(block_range)))
571+
.collect::<Vec<_>>();
572+
let mktree_node_to_certify = entries[2].1.leaves()[1].clone();
518573
let merkle_tree_entries = &entries
519574
.into_iter()
520575
.map(|(range, mktree)| (range.to_owned(), mktree.into()))
@@ -525,13 +580,21 @@ mod tests {
525580
}
526581

527582
#[test]
528-
fn test_mk_map_should_clone_correctly() {
529-
let entries = generate_merkle_trees(100000, 100);
583+
fn test_mk_map_should_clone_and_compute_same_root() {
584+
let entries = [
585+
BlockRange::new(0, 3),
586+
BlockRange::new(4, 6),
587+
BlockRange::new(7, 9),
588+
]
589+
.iter()
590+
.map(|block_range| (block_range.to_owned(), generate_merkle_tree(block_range)))
591+
.collect::<Vec<_>>();
530592
let merkle_tree_node_entries = &entries
531593
.into_iter()
532594
.map(|(range, mktree)| (range.to_owned(), mktree.into()))
533595
.collect::<Vec<(_, MKMapNode<_>)>>();
534596
let mk_map = MKMap::new(merkle_tree_node_entries.as_slice()).unwrap();
597+
535598
let mk_map_clone = mk_map.clone();
536599

537600
assert_eq!(
@@ -542,26 +605,27 @@ mod tests {
542605

543606
#[test]
544607
fn test_mk_map_should_not_compute_proof_for_no_leaves() {
545-
let entries = generate_merkle_trees(100000, 100);
608+
let entries = generate_merkle_trees(10, 3);
546609
let mktree_nodes_to_certify: &[MKTreeNode] = &[];
547610
let merkle_tree_node_entries = &entries
548611
.into_iter()
549612
.map(|(range, mktree)| (range.to_owned(), mktree.into()))
550613
.collect::<Vec<(_, MKMapNode<_>)>>();
551614
let mk_map_full = MKMap::new(merkle_tree_node_entries.as_slice()).unwrap();
615+
552616
mk_map_full
553617
.compute_proof(mktree_nodes_to_certify)
554618
.expect_err("MKMap should not compute proof for no leaves");
555619
}
556620

557621
#[test]
558622
fn test_mk_map_should_compute_and_verify_valid_proof() {
559-
let entries = generate_merkle_trees(100000, 100);
623+
let entries = generate_merkle_trees(10, 3);
560624
let mktree_nodes_to_certify = [
561625
entries[0].1.leaves()[0].clone(),
562-
entries[2].1.leaves()[0].clone(),
563-
entries[2].1.leaves()[5].clone(),
564-
entries[3].1.leaves()[10].clone(),
626+
entries[1].1.leaves()[0].clone(),
627+
entries[1].1.leaves()[1].clone(),
628+
entries[2].1.leaves()[1].clone(),
565629
];
566630
let merkle_tree_node_entries = &entries
567631
.into_iter()
@@ -579,11 +643,11 @@ mod tests {
579643

580644
#[test]
581645
fn test_mk_map_should_compute_and_verify_valid_proof_recursively() {
582-
let entries = generate_merkle_trees(100000, 100);
646+
let entries = generate_merkle_trees(100, 3);
583647
let mktree_nodes_to_certify = [
584648
entries[0].1.leaves()[0].clone(),
585-
entries[2].1.leaves()[5].clone(),
586-
entries[3].1.leaves()[10].clone(),
649+
entries[2].1.leaves()[1].clone(),
650+
entries[3].1.leaves()[2].clone(),
587651
entries[20].1.leaves()[0].clone(),
588652
entries[30].1.leaves()[0].clone(),
589653
];

mithril-common/src/entities/block_range.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ impl BlockRange {
6262
}
6363

6464
/// Create a BlockRange from a block number and a range length
65-
fn from_block_number_and_length(
65+
pub(crate) fn from_block_number_and_length(
6666
number: BlockNumber,
6767
length: BlockRangeLength,
6868
) -> StdResult<Self> {

0 commit comments

Comments
 (0)