Skip to content

Commit

Permalink
Merge 38b7e20 into 5ed0f6d
Browse files Browse the repository at this point in the history
  • Loading branch information
nkohen committed Jun 17, 2019
2 parents 5ed0f6d + 38b7e20 commit 2168cf8
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 12 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package org.bitcoins.core.gcs

import org.bitcoins.core.crypto.DoubleSha256Digest
import org.bitcoins.core.crypto.DoubleSha256DigestBE
import org.bitcoins.core.protocol.blockchain.Block
import org.bitcoins.core.protocol.script.ScriptPubKey
import org.bitcoins.testkit.util.BitcoinSUnitTest
Expand All @@ -14,20 +14,28 @@ class BlockFilterTest extends BitcoinSUnitTest {
// https://github.com/bitcoin/bips/blob/master/bip-0158.mediawiki#appendix-c-test-vectors
case class Bip158TestCase(
blockHeight: Int,
blockHash: DoubleSha256Digest,
blockHash: DoubleSha256DigestBE,
block: Block,
prevOutputScripts: Vector[ScriptPubKey],
// TODO prevHeader: BlockFilterHeader,
prevHeader: DoubleSha256DigestBE,
filter: GolombFilter,
// TODO header: BlockFilterHeader,
header: DoubleSha256DigestBE,
notes: String
) {

val clue: String = s"Test Notes: $notes"

def runTest(): org.scalatest.Assertion = {
val constructedFilter = BlockFilter(block, prevOutputScripts)

assert(constructedFilter.decodedHashes == filter.decodedHashes,
s"Test Notes: $notes")
assert(constructedFilter.decodedHashes == filter.decodedHashes, clue)

assert(constructedFilter.encodedData.bytes == filter.encodedData.bytes,
clue)

val constructedHeader = constructedFilter.getHeader(prevHeader.flip)

assert(constructedHeader.hash == header.flip, clue)
}
}

Expand All @@ -37,23 +45,33 @@ class BlockFilterTest extends BitcoinSUnitTest {
def fromJsArray(array: JsArray): Bip158TestCase = {
val parseResult = for {
height <- array(0).validate[Int]
blockHash <- array(1).validate[String].map(DoubleSha256Digest.fromHex)
blockHash <- array(1).validate[String].map(DoubleSha256DigestBE.fromHex)

block <- array(2).validate[String].map(Block.fromHex)

scriptArray <- array(3).validate[JsArray]
scripts = parseScripts(scriptArray)

//prevHeader <- array(4).validate[String].map(BlockFilterHeader.fromHex)
prevHeader <- array(4)
.validate[String]
.map(DoubleSha256DigestBE.fromHex)

filter <- array(5)
.validate[String]
.map(BlockFilter.fromHex(_, blockHash))
.map(BlockFilter.fromHex(_, blockHash.flip))

//header <- array(6).validate[String].map(BlockFilterHeader.fromHex)
header <- array(6).validate[String].map(DoubleSha256DigestBE.fromHex)

notes <- array(7).validate[String]
} yield Bip158TestCase(height, blockHash, block, scripts, filter, notes)
} yield
Bip158TestCase(height,
blockHash,
block,
scripts,
prevHeader,
filter,
header,
notes)

parseResult.get
}
Expand Down
21 changes: 21 additions & 0 deletions core/src/main/scala/org/bitcoins/core/gcs/FilterHeader.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package org.bitcoins.core.gcs

import org.bitcoins.core.crypto.DoubleSha256Digest
import org.bitcoins.core.util.CryptoUtil

case class FilterHeader(
filterHash: DoubleSha256Digest,
prevHeaderHash: DoubleSha256Digest) {

val hash: DoubleSha256Digest = {
CryptoUtil.doubleSHA256(filterHash.bytes ++ prevHeaderHash.bytes)
}

def nextHeader(nextFilter: GolombFilter): FilterHeader = {
FilterHeader(filterHash = nextFilter.hash, prevHeaderHash = this.hash)
}

def nextHeader(nextFilterHash: DoubleSha256Digest): FilterHeader = {
FilterHeader(filterHash = nextFilterHash, prevHeaderHash = this.hash)
}
}
20 changes: 19 additions & 1 deletion core/src/main/scala/org/bitcoins/core/gcs/GolombFilter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import org.bitcoins.core.protocol.transaction.{
TransactionOutput
}
import org.bitcoins.core.script.control.OP_RETURN
import org.bitcoins.core.util.BitcoinSUtil
import org.bitcoins.core.util.{BitcoinSUtil, CryptoUtil}
import scodec.bits.{BitVector, ByteVector}

import scala.annotation.tailrec
Expand All @@ -31,6 +31,24 @@ case class GolombFilter(
encodedData: BitVector) {
lazy val decodedHashes: Vector[UInt64] = GCS.golombDecodeSet(encodedData, p)

lazy val hash: DoubleSha256Digest = {
CryptoUtil.doubleSHA256(this.bytes)
}

def getHeader(prevHeader: FilterHeader): FilterHeader = {
FilterHeader(filterHash = this.hash, prevHeaderHash = prevHeader.hash)
}

def getHeader(prevHeaderHash: DoubleSha256Digest): FilterHeader = {
FilterHeader(filterHash = this.hash, prevHeaderHash = prevHeaderHash)
}

def bytes: ByteVector = {
n.bytes ++ encodedData.bytes
}

def hex: String = bytes.toHex

// TODO: Offer alternative that stops decoding when it finds out if data is there
def matchesHash(hash: UInt64): Boolean = {
@tailrec
Expand Down

0 comments on commit 2168cf8

Please sign in to comment.