Skip to content

Commit 5020d40

Browse files
committed
[ETCM-533] refactor pathTraverse in order to get the proof and value in both cases(existing/non existing key)
1 parent 2492b3d commit 5020d40

File tree

3 files changed

+13
-94
lines changed

3 files changed

+13
-94
lines changed

src/it/scala/io/iohk/ethereum/txExecTest/util/DumpChainApp.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ class BlockchainMock(genesisHash: ByteString) extends Blockchain {
150150
rootHash: NodeHash,
151151
position: BigInt,
152152
ethCompatibleStorage: Boolean
153-
): (BigInt, Seq[MptNode]) = (1, Seq.empty)
153+
): (BigInt, Seq[MptNode]) = (BigInt(0), Seq.empty)
154154

155155
override protected def getHashByBlockNumber(number: BigInt): Option[ByteString] = Some(genesisHash)
156156

src/main/scala/io/iohk/ethereum/mpt/MerklePatriciaTrie.scala

Lines changed: 12 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,10 @@ class MerklePatriciaTrie[K, V] private (private[mpt] val rootNode: Option[MptNod
8484
def get(key: K): Option[V] = {
8585
pathTraverse[Option[V]](None, mkKeyNibbles(key)) { case (_, node) =>
8686
node match {
87-
case LeafNode(_, value, _, _, _) =>
87+
case Some(LeafNode(_, value, _, _, _)) =>
8888
Some(vSerializer.fromBytes(value.toArray[Byte]))
8989

90-
case BranchNode(_, terminator, _, _, _) =>
90+
case Some(BranchNode(_, terminator, _, _, _)) =>
9191
terminator.map(term => vSerializer.fromBytes(term.toArray[Byte]))
9292

9393
case _ => None
@@ -103,9 +103,9 @@ class MerklePatriciaTrie[K, V] private (private[mpt] val rootNode: Option[MptNod
103103
* @throws io.iohk.ethereum.mpt.MerklePatriciaTrie.MPTException if there is any inconsistency in how the trie is build.
104104
*/
105105
def getProof(key: K): Option[Vector[MptNode]] = {
106-
pathTraverseWithProof[Vector[MptNode]](Vector.empty, mkKeyNibbles(key)) { case (acc, node) =>
106+
pathTraverse[Vector[MptNode]](Vector.empty, mkKeyNibbles(key)) { case (acc, node) =>
107107
node match {
108-
case nextNodeOnExt @ (_: BranchNode | _: ExtensionNode | _: LeafNode) => acc :+ nextNodeOnExt
108+
case Some(nextNodeOnExt @ (_: BranchNode | _: ExtensionNode | _: LeafNode)) => acc :+ nextNodeOnExt
109109
case _ => acc
110110
}
111111
}
@@ -121,25 +121,25 @@ class MerklePatriciaTrie[K, V] private (private[mpt] val rootNode: Option[MptNod
121121
* @tparam T accumulator type
122122
* @return accumulated data or None if key doesn't exist
123123
*/
124-
private def pathTraverse[T](acc: T, searchKey: Array[Byte])(op: (T, MptNode) => T): Option[T] = {
124+
private def pathTraverse[T](acc: T, searchKey: Array[Byte])(op: (T, Option[MptNode]) => T): Option[T] = {
125125

126126
@tailrec
127-
def pathTraverse(acc: T, node: MptNode, searchKey: Array[Byte], op: (T, MptNode) => T): Option[T] = {
127+
def pathTraverse(acc: T, node: MptNode, searchKey: Array[Byte], op: (T, Option[MptNode]) => T): Option[T] = {
128128
node match {
129129
case LeafNode(key, _, _, _, _) =>
130-
if (key.toArray[Byte] sameElements searchKey) Some(op(acc, node)) else None
130+
if (key.toArray[Byte] sameElements searchKey) Some(op(acc, Some(node))) else Some(op(acc, None))
131131

132132
case extNode @ ExtensionNode(sharedKey, _, _, _, _) =>
133133
val (commonKey, remainingKey) = searchKey.splitAt(sharedKey.length)
134134
if (searchKey.length >= sharedKey.length && (sharedKey.toArray[Byte] sameElements commonKey)) {
135-
pathTraverse(op(acc, node), extNode.next, remainingKey, op)
136-
} else None
135+
pathTraverse(op(acc, Some(node)), extNode.next, remainingKey, op)
136+
} else Some(op(acc, None))
137137

138138
case branch: BranchNode =>
139-
if (searchKey.isEmpty) Some(op(acc, node))
139+
if (searchKey.isEmpty) Some(op(acc, Some(node)))
140140
else
141141
pathTraverse(
142-
op(acc, node),
142+
op(acc, Some(node)),
143143
branch.children(searchKey(0)),
144144
searchKey.slice(1, searchKey.length),
145145
op
@@ -149,7 +149,7 @@ class MerklePatriciaTrie[K, V] private (private[mpt] val rootNode: Option[MptNod
149149
pathTraverse(acc, getFromHash(bytes, nodeStorage), searchKey, op)
150150

151151
case NullNode =>
152-
None
152+
Some(op(acc, None))
153153
}
154154
}
155155

@@ -161,46 +161,6 @@ class MerklePatriciaTrie[K, V] private (private[mpt] val rootNode: Option[MptNod
161161
}
162162
}
163163

164-
private def pathTraverseWithProof[T](acc: T, searchKey: Array[Byte])(op: (T, MptNode) => T): Option[T] = {
165-
166-
@tailrec
167-
def pathTraverseWithProof(acc: T, node: MptNode, searchKey: Array[Byte], op: (T, MptNode) => T): Option[T] = {
168-
node match {
169-
case LeafNode(key, _, _, _, _) =>
170-
if (key.toArray[Byte] sameElements searchKey) Some(op(acc, node)) else Some(acc)
171-
172-
case extNode @ ExtensionNode(sharedKey, _, _, _, _) =>
173-
val (commonKey, remainingKey) = searchKey.splitAt(sharedKey.length)
174-
if (searchKey.length >= sharedKey.length && (sharedKey.toArray[Byte] sameElements commonKey)) {
175-
pathTraverseWithProof(op(acc, node), extNode.next, remainingKey, op)
176-
} else Some(acc)
177-
178-
case branch: BranchNode =>
179-
if (searchKey.isEmpty) Some(op(acc, node))
180-
else
181-
pathTraverseWithProof(
182-
op(acc, node),
183-
branch.children(searchKey(0)),
184-
searchKey.slice(1, searchKey.length),
185-
op
186-
)
187-
188-
case HashNode(bytes) =>
189-
pathTraverseWithProof(acc, getFromHash(bytes, nodeStorage), searchKey, op)
190-
191-
case NullNode =>
192-
Some(acc)
193-
}
194-
}
195-
196-
rootNode match {
197-
case Some(root) =>
198-
pathTraverseWithProof(acc, root, searchKey, op)
199-
case None =>
200-
None
201-
}
202-
}
203-
204164
private def getFromHash(nodeId: Array[Byte], source: MptStorage): MptNode = {
205165
val nodeEncoded = source.get(nodeId).encode
206166
MptTraversals

src/test/scala/io/iohk/ethereum/mpt/MerklePatriciaTrieSuite.scala

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -573,7 +573,6 @@ class MerklePatriciaTrieSuite extends AnyFunSuite with ScalaCheckPropertyChecks
573573
val proof: Option[Vector[MptNode]] = trie.getProof(key4)
574574
// then
575575
assert(proof.isDefined)
576-
proof.foreach(_.foreach(MptUtils.showMptNode(_, true, " ")))
577576
}
578577

579578
test("getProof returns valid proof for existing key") {
@@ -624,43 +623,3 @@ class MerklePatriciaTrieSuite extends AnyFunSuite with ScalaCheckPropertyChecks
624623
assert(obtained.isEmpty)
625624
}
626625
}
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

Comments
 (0)