Skip to content

Commit

Permalink
fix one more segwit test
Browse files Browse the repository at this point in the history
  • Loading branch information
h0ngcha0 committed Jan 7, 2018
1 parent ccf405b commit 218d1fb
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 26 deletions.
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ scalacOptions := Seq(
libraryDependencies ++= Seq(
"com.madgag.spongycastle" % "core" % "1.52.0.0",
"org.scodec" %% "scodec-core" % "1.10.3",
"io.github.yzernik" %% "bitcoin-scodec" % "0.2.9-hc-3-3",
"io.github.yzernik" %% "bitcoin-scodec" % "0.2.9-hc-3-6",
"com.iheart" %% "ficus" % "1.4.1",
"org.typelevel" %% "cats-core" % "1.0.0-MF",
"com.github.mpilquist" %% "simulacrum" % "0.10.0",
Expand Down
3 changes: 3 additions & 0 deletions src/main/scala/me/hongchao/bitcoin4s/script/CryptoOp.scala
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,10 @@ object CryptoOp {
case DecodeResult.Ok(decodedPublicKey) =>
val checkResult = checkSignature(decodedPublicKey, signature, sigHashFlagBytes, state)
handleResult(checkResult)

case DecodeResult.OkButNotStrictEncoded(decodedPublicKey) =>
abort(PublicKeyWrongEncoding(opCode, state))

case DecodeResult.Failure =>
handleResult(false)
}
Expand Down Expand Up @@ -294,6 +296,7 @@ object CryptoOp {
inputIndex = state.inputIndex,
sigHashType = sigHashType
)

case segwitTx: TxWitness =>
segwitTx.signingHash(
currentScript,
Expand Down
8 changes: 5 additions & 3 deletions src/main/scala/me/hongchao/bitcoin4s/script/Interpreter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -484,11 +484,13 @@ object Interpreter {
Some((scriptPubKey, witnessStack))
} else if (witnessHash.bytes.length == 32) {
// P2WPSH
val head = witnessStack.head

for {
last <- witnessStack.lastOption
scriptPubKey <- (Hash.Sha256(last.bytes.toArray).toSeq == witnessHash.bytes).option(Parser.parse(last.bytes))
head <- witnessStack.headOption
scriptPubKey <- (Hash.Sha256(head.bytes.toArray).toSeq == witnessHash.bytes).option(Parser.parse(head.bytes))
} yield {
(scriptPubKey, removePushOps(witnessStack.dropRight(1)))
(scriptPubKey, removePushOps(witnessStack.tail))
}
} else {
None
Expand Down
12 changes: 12 additions & 0 deletions src/main/scala/me/hongchao/bitcoin4s/script/TransactionOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -182,5 +182,17 @@ object TransactionOps {
Hash.Hash256(preImage.toArray)
}
}

implicit class RichTx(tx: Tx) {
def serialized(): ByteVector = {
tx match {
case regularTx: RegularTx =>
regularTx.transactionId()
case txWitness: TxWitness =>
txWitness.transactionId()
}
}
}

}

Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ class ScriptSpec extends Spec with ScriptTestRunner {
checkedExpectedResults.contains(test.expectedResult)
// && test.raw.contains("Invalid witness script")
// checkedExpectedResults.contains(test.expectedResult)
}.take(989)
}.take(990)

filteredScriptTests.zipWithIndex.foreach(Function.tupled(run))
}
Expand Down
47 changes: 26 additions & 21 deletions src/test/scala/me/hongchao/bitcoin4s/script/ScriptTestRunner.scala
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,9 @@ trait ScriptTestRunner { self: Spec =>


def run(test: TestCase, testNumber: Int) = {
println(s"\n\nTest $testNumber: $test\n\n")
//println(s"\n\nTest $testNumber: $test\n\n")

val amount: Long = test.witness.map(_._2).getOrElse(0)
val amount = test.witness.map(_._2)
val creditingTx = creditingTransaction(test.scriptPubKey.flatMap(_.bytes), amount)
val spendingTx = spendingTransaction(creditingTx, test.scriptSig.flatMap(_.bytes), test.witness.map(_._1))

Expand All @@ -101,7 +101,7 @@ trait ScriptTestRunner { self: Spec =>
flags = test.scriptFlags,
transaction = spendingTx,
inputIndex = 0,
amount = amount
amount = amount.getOrElse(0)
)

withClue(test.comments) {
Expand Down Expand Up @@ -211,37 +211,42 @@ trait ScriptTestRunner { self: Spec =>
}
}

def creditingTransaction(scriptPubKey: Seq[Byte], amount: Long) = {
def creditingTransaction(scriptPubKey: Seq[Byte], maybeAmount: Option[Long]) = {
val emptyTxId = Array.fill[Byte](32)(0)
val emptyOutpoint = OutPoint(Hash.NULL, -1)
val maxSequence = 0xffffffff
val txIn = TxIn(
previous_output = emptyOutpoint,
sig_script = ByteVector(Seq(OP_0, OP_0).flatMap(_.bytes)),
//witness_script = List.empty,
sequence = maxSequence
)
val txOut = RegularTxOut(value = amount, pk_script = ByteVector(scriptPubKey))

RegularTx(
version = 1,
//marker = None,
//flags = None,
tx_in = txIn :: Nil,
tx_out = txOut :: Nil,
//witness_scripts = List.empty,
lock_time = 0
)

maybeAmount match {
case Some(amount) =>
val txOut = TxOutWitness(value = amount, pk_script = ByteVector(scriptPubKey))
TxWitness(
version = 1,
tx_in = txIn :: Nil,
tx_out = txOut :: Nil,
lock_time = 0
)
case None =>
val txOut = RegularTxOut(value = 0, pk_script = ByteVector(scriptPubKey))
RegularTx(
version = 1,
tx_in = txIn :: Nil,
tx_out = txOut :: Nil,
lock_time = 0
)
}
}

def spendingTransaction(creditingTransaction: RegularTx, scriptSig: Seq[Byte], maybeWitnessScript: Option[Seq[ScriptConstant]]) = {
def spendingTransaction(creditingTransaction: Tx, scriptSig: Seq[Byte], maybeWitnessScript: Option[Seq[ScriptConstant]]) = {
val maxSequence = 0xffffffff
/* val witnessScript = maybeWitnessScript.map(_.map { scriptConstant =>
ByteVector(scriptConstant.bytes)
}).getOrElse(Seq.empty).toList*/

import scodec.bits._
val prevId = Hash(ByteVector(Hash256(creditingTransaction.transactionId().toArray)).reverse)

val prevId = Hash(ByteVector(Hash256(creditingTransaction.serialized().toArray)).reverse)
val txIn = TxIn(
previous_output = OutPoint(prevId, 0),
sig_script = ByteVector(scriptSig),
Expand Down

0 comments on commit 218d1fb

Please sign in to comment.