Skip to content

Commit 1d2db26

Browse files
authored
Merge pull request #109 from ccellado/fix_overflow
Stack overflow fix for BatchMerkeProof
2 parents d925f93 + 9eb6b85 commit 1d2db26

File tree

2 files changed

+11
-5
lines changed

2 files changed

+11
-5
lines changed

shared/src/main/scala/scorex/crypto/authds/merkle/BatchMerkleProof.scala

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package scorex.crypto.authds.merkle
22

33
import scorex.crypto.authds.Side
4+
import scorex.crypto.authds.merkle.MerkleProof.LeftSide
45
import scorex.crypto.authds.merkle.MerkleTree.InternalNodePrefix
56
import scorex.crypto.hash.{CryptographicHash, Digest}
67
import scorex.util.ScorexEncoding
@@ -68,10 +69,10 @@ case class BatchMerkleProof[D <: Digest](indices: Seq[(Int, Digest)], proofs: Se
6869
} else {
6970

7071
// hash the corresponding value inside E with the first hash inside M, taking note of the side
71-
if (m_new.head._2 == MerkleProof.LeftSide) {
72-
e_new = e_new :+ hf.prefixedHash(MerkleTree.InternalNodePrefix, m_new.head._1 ++ e.apply(i)._2)
72+
if (m_new.head._2 == LeftSide) {
73+
e_new = e_new :+ hf.prefixedHash(InternalNodePrefix, m_new.head._1 ++ e.apply(i)._2)
7374
} else {
74-
e_new = e_new :+ hf.prefixedHash(MerkleTree.InternalNodePrefix, e.apply(i)._2 ++ m_new.head._1)
75+
e_new = e_new :+ hf.prefixedHash(InternalNodePrefix, e.apply(i)._2 ++ m_new.head._1)
7576
}
7677

7778
// remove the used value from m
@@ -84,7 +85,7 @@ case class BatchMerkleProof[D <: Digest](indices: Seq[(Int, Digest)], proofs: Se
8485
a_new = b.distinct.map(_._1 / 2)
8586

8687
// Repeat until the root of the tree is reached (M has no more elements)
87-
if (m_new.nonEmpty || e_new.size > 1) {
88+
if ((m_new.nonEmpty || e_new.size > 1) && a_new.nonEmpty) {
8889
e_new = loop(a_new, a_new zip e_new, m_new)
8990
}
9091
e_new

shared/src/test/scala/scorex/crypto/authds/merkle/MerkleTreeSpecification.scala

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import org.scalatest.matchers.should.Matchers
55
import org.scalatestplus.scalacheck.ScalaCheckDrivenPropertyChecks
66
import scorex.crypto.TestingCommons
77
import scorex.crypto.authds.LeafData
8-
import scorex.crypto.hash.Blake2b256
8+
import scorex.crypto.hash.{Blake2b256, Digest32}
99

1010
import scala.util.Random
1111

@@ -87,6 +87,11 @@ class MerkleTreeSpecification extends AnyPropSpec with ScalaCheckDrivenPropertyC
8787
tree.proofByIndices(Seq.empty[Int]) shouldBe None
8888
}
8989

90+
property("Proof for empty node caused stack overflow") {
91+
val batch = BatchMerkleProof(Seq(), Seq((Digest32 @@ Array.fill[Byte](32)(0),MerkleProof.LeftSide)))
92+
batch.valid(Digest32 @@ Array.fill[Byte](32)(0))
93+
}
94+
9095
property("Tree creation from 0 elements") {
9196
val tree = MerkleTree(Seq.empty)(hf)
9297
tree.rootHash shouldEqual Array.fill(hf.DigestSize)(0: Byte)

0 commit comments

Comments
 (0)