Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package scorex.crypto.authds.merkle

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

// hash the corresponding value inside E with the first hash inside M, taking note of the side
if (m_new.head._2 == MerkleProof.LeftSide) {
e_new = e_new :+ hf.prefixedHash(MerkleTree.InternalNodePrefix, m_new.head._1 ++ e.apply(i)._2)
if (m_new.head._2 == LeftSide) {
e_new = e_new :+ hf.prefixedHash(InternalNodePrefix, m_new.head._1 ++ e.apply(i)._2)
} else {
e_new = e_new :+ hf.prefixedHash(MerkleTree.InternalNodePrefix, e.apply(i)._2 ++ m_new.head._1)
e_new = e_new :+ hf.prefixedHash(InternalNodePrefix, e.apply(i)._2 ++ m_new.head._1)
}

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

// Repeat until the root of the tree is reached (M has no more elements)
if (m_new.nonEmpty || e_new.size > 1) {
if ((m_new.nonEmpty || e_new.size > 1) && a_new.nonEmpty) {
e_new = loop(a_new, a_new zip e_new, m_new)
}
e_new
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import org.scalatest.matchers.should.Matchers
import org.scalatestplus.scalacheck.ScalaCheckDrivenPropertyChecks
import scorex.crypto.TestingCommons
import scorex.crypto.authds.LeafData
import scorex.crypto.hash.Blake2b256
import scorex.crypto.hash.{Blake2b256, Digest32}

import scala.util.Random

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

property("Proof for empty node caused stack overflow") {
val batch = BatchMerkleProof(Seq(), Seq((Digest32 @@ Array.fill[Byte](32)(0),MerkleProof.LeftSide)))
batch.valid(Digest32 @@ Array.fill[Byte](32)(0))
}

property("Tree creation from 0 elements") {
val tree = MerkleTree(Seq.empty)(hf)
tree.rootHash shouldEqual Array.fill(hf.DigestSize)(0: Byte)
Expand Down