@@ -554,22 +554,26 @@ class MerklePatriciaTrieSuite extends AnyFunSuite with ScalaCheckPropertyChecks
554
554
assert(proof.isEmpty)
555
555
}
556
556
557
- test(" getProof returns empty result for non-existing key" ) {
558
- forAll(keyValueListGen()) { keyValueList : Seq [(Int , Int )] =>
559
- val input : Seq [(Array [Byte ], Array [Byte ])] = keyValueList
560
- .map { case (k, v) => k.toString.getBytes() -> v.toString.getBytes() }
561
-
562
- val trie = input
563
- .foldLeft(emptyMpt) { case (recTrie, (key, value)) =>
564
- recTrie.put(key, value)
565
- }
566
-
567
- input.toList.foreach(x => {
568
- val keyToFind = x._1 ++ Array (Byte .MaxValue )
569
- val proof = trie.getProof(keyToFind)
570
- assert(proof.isEmpty)
571
- })
572
- }
557
+ test(" getProof returns proof result for non-existing address" ) {
558
+ // given
559
+ val EmptyTrie = MerklePatriciaTrie [Array [Byte ], Array [Byte ]](emptyEphemNodeStorage)
560
+ val key1 : Array [Byte ] = Hex .decode(" 10000001" )
561
+ val key2 : Array [Byte ] = Hex .decode(" 10000002" )
562
+ val key3 : Array [Byte ] = Hex .decode(" 30000003" )
563
+ val key4 : Array [Byte ] = Hex .decode(" 10000004" ) // a key that doesn't have a corresponding value in the trie
564
+
565
+ val val1 : Array [Byte ] = Hex .decode(" 0101" )
566
+ val val2 : Array [Byte ] = Hex .decode(" 0102" )
567
+ val val3 : Array [Byte ] = Hex .decode(" 0103" )
568
+ val trie = EmptyTrie
569
+ .put(key1, val1)
570
+ .put(key2, val2)
571
+ .put(key3, val3)
572
+ // when
573
+ val proof : Option [Vector [MptNode ]] = trie.getProof(key4)
574
+ // then
575
+ assert(proof.isDefined)
576
+ proof.foreach(_.foreach(MptUtils .showMptNode(_, true , " " )))
573
577
}
574
578
575
579
test(" getProof returns valid proof for existing key" ) {
@@ -620,3 +624,43 @@ class MerklePatriciaTrieSuite extends AnyFunSuite with ScalaCheckPropertyChecks
620
624
assert(obtained.isEmpty)
621
625
}
622
626
}
627
+
628
+ object MptUtils {
629
+ import io .iohk .ethereum .mpt ._
630
+ import org .bouncycastle .util .encoders .Hex
631
+ def show (val1 : Array [Byte ]): String =
632
+ Hex .encode(val1).map(_.toChar).mkString
633
+ def showKV (key1 : Array [Byte ], trie : MerklePatriciaTrie [Array [Byte ], Array [Byte ]]): String =
634
+ show(key1) + " -> " + trie.get(key1).map(show)
635
+ def showMptNode (n : MptNode , showNull : Boolean = false , indent : String ): Unit = {
636
+ n match {
637
+ case LeafNode (key, value, cachedHash, cachedRlpEncoded, parsedRlp) =>
638
+ if (showNull) println(" \n " )
639
+ println(s " $indent LeafNode( ${show(key.toArray)} -> ${show(value.toArray)}) " )
640
+ case ExtensionNode (sharedKey, next, cachedHash, cachedRlpEncoded, parsedRlp) =>
641
+ if (showNull) println(" \n " )
642
+ println(s " $indent ExtensionNode(sharedKey = ${show(sharedKey.toArray)}" )
643
+ println(s " $indent next = " )
644
+ showMptNode(next, false , indent + " " )
645
+ println(s " $indent ) " )
646
+ case BranchNode (children, terminator, cachedHash, cachedRlpEncoded, parsedRlp) =>
647
+ if (showNull) println(" \n " )
648
+ println(
649
+ s " $indent BranchNode(children = ${children.filterNot(n => n.isInstanceOf [NullNode .type ]).size}, terminator = ${terminator
650
+ .map(e => show(e.toArray))}"
651
+ )
652
+ println(s " $indent children: " )
653
+ children.map(showMptNode(_, false , indent + " " ))
654
+ println(s " $indent ) " )
655
+ case NullNode =>
656
+ if (showNull) println(s " $indent NullNode " )
657
+ case other =>
658
+ if (showNull) println(" \n " )
659
+ println(s " $indent $other" )
660
+ }
661
+ }
662
+ def showMptTrie [K , V ](mpt : MerklePatriciaTrie [K , V ]): Unit = {
663
+ println(s " MPT ROOT HASH ${mpt.getRootHash} rootNode: " )
664
+ mpt.rootNode.map(n => showMptNode(n, false , " " ))
665
+ }
666
+ }
0 commit comments