Skip to content

Commit

Permalink
Merge pull request input-output-hk#93 from ApexTheory/84-batch-merkle…
Browse files Browse the repository at this point in the history
…-proof

Batch Merkle Proof - override equals for matcher array equality
  • Loading branch information
kushti authored Jan 5, 2022
2 parents 2237785 + 5649aaa commit 789bc95
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import scorex.crypto.authds.merkle.MerkleTree.InternalNodePrefix
import scorex.crypto.hash.{CryptographicHash, Digest}
import scorex.util.ScorexEncoding

import java.util
import scala.language.postfixOps

/**
Expand Down Expand Up @@ -90,6 +91,31 @@ case class BatchMerkleProof[D <: Digest](indices: Seq[(Int, Digest)], proofs: Se
}

val e = indices sortBy(_._1)
loop(indices.map(_._1), e, proofs).head.sameElements(expectedRootHash)
loop(indices.map(_._1), e, proofs) match {
case root: Seq[Digest] if root.size == 1 => root.head.sameElements(expectedRootHash)
case _ => false
}
}

override def equals(obj: Any): Boolean = obj match {
case that: BatchMerkleProof[D] =>
if (this.indices.size != that.indices.size ||
this.proofs.size != that.proofs.size) {
return false
}
for (i <- this.indices.indices) {
if (this.indices.apply(i)._1 != that.indices.apply(i)._1 ||
!util.Arrays.equals(this.indices.apply(i)._2, that.indices.apply(i)._2)) {
return false
}
}
for (i <- this.proofs.indices) {
if (this.proofs.apply(i)._2 != that.proofs.apply(i)._2 ||
!util.Arrays.equals(this.proofs.apply(i)._1, that.proofs.apply(i)._1)) {
return false
}
}
true
case _ => false
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ case class MerkleTree[D <: Digest](topNode: Node[D],
m
}

if (indices.forall(index => index >= 0 && index < length)) {
if (indices.nonEmpty && indices.forall(index => index >= 0 && index < length)) {
val hashes: Seq[Digest] = elementsHashIndex.toSeq.sortBy(_._2).map(_._1.toArray.asInstanceOf[Digest])
val normalized_indices = indices.distinct.sorted
val multiproof = loop(normalized_indices, hashes)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,12 @@ class MerkleTreeSpecification extends AnyPropSpec with ScalaCheckDrivenPropertyC
tree.proofByIndices(Seq(2,10)) shouldBe None
}

property("Empty Batch proof generation should be None") {
val d = (0 until 10).map(_ => LeafData @@ scorex.utils.Random.randomBytes(LeafSize))
val tree = MerkleTree(d)
tree.proofByIndices(Seq.empty[Int]) shouldBe None
}

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

0 comments on commit 789bc95

Please sign in to comment.