Add unit tests for correctScriptNumberRepresentation scriptUtil function, add random cltv/csv scriptSigs to randomScriptSig generator

This commit is contained in:
Tom McCabe 2016-09-19 14:26:10 -05:00
parent 0dbb724749
commit 98c5007894
5 changed files with 24 additions and 17 deletions

View file

@ -494,7 +494,7 @@ object NonStandardScriptPubKey extends Factory[NonStandardScriptPubKey] {
}
/**
* Represents the empty script pub key
* Represents the empty ScriptPubKey
*/
case object EmptyScriptPubKey extends ScriptPubKey {
def hex = ""

View file

@ -420,8 +420,8 @@ object CLTVScriptSignature extends Factory[CLTVScriptSignature] {
case cltvScriptPubKey : CLTVScriptPubKey => apply(cltvScriptPubKey.scriptPubKeyAfterCLTV, sigs, pubKeys)
case csvScriptPubKey : CSVScriptPubKey => apply(csvScriptPubKey.scriptPubKeyAfterCSV, sigs, pubKeys)
case EmptyScriptPubKey => CLTVScriptSignature(EmptyScriptSignature)
case _ : NonStandardScriptPubKey | _ : P2SHScriptPubKey => throw new IllegalArgumentException("A NonStandardScriptSignature or P2SHScriptSignature cannot be" +
"the underlying scriptSig in a CLTVScriptSignature. Got: " + this)
case x @ (_ : NonStandardScriptPubKey | _ : P2SHScriptPubKey) => throw new IllegalArgumentException("A NonStandardScriptSignature or P2SHScriptSignature cannot be" +
"the underlying scriptSig in a CLTVScriptSignature. Got: " + x)
}
}
@ -461,8 +461,8 @@ object CSVScriptSignature extends Factory[CSVScriptSignature] {
case cltvScriptPubKey : CLTVScriptPubKey => apply(cltvScriptPubKey.scriptPubKeyAfterCLTV, sigs, pubKeys)
case csvScriptPubKey : CSVScriptPubKey => apply(csvScriptPubKey.scriptPubKeyAfterCSV, sigs, pubKeys)
case EmptyScriptPubKey => CSVScriptSignature(EmptyScriptSignature)
case _ : NonStandardScriptPubKey | _ : P2SHScriptPubKey => throw new IllegalArgumentException("A NonStandardScriptSignature or P2SHScriptSignature cannot be" +
"the underlying scriptSig in a CSVScriptSignature. Got: " + this)
case x @ (_ : NonStandardScriptPubKey | _ : P2SHScriptPubKey) => throw new IllegalArgumentException("A NonStandardScriptSignature or P2SHScriptSignature cannot be" +
"the underlying scriptSig in a CSVScriptSignature. Got: " + x)
}
}

View file

@ -60,10 +60,6 @@ trait ScriptInterpreter extends CryptoInterpreter with StackInterpreter with Con
scriptPubKey match {
case p2shScriptPubKey : P2SHScriptPubKey if (ScriptFlagUtil.p2shEnabled(program.flags)) =>
executeP2shScript(scriptSigExecutedProgram, programBeingExecuted, p2shScriptPubKey)
/* case csv : CSVScriptPubKey if csv.scriptPubKeyAfterCSV.isInstanceOf[P2SHScriptPubKey] && ScriptFlagUtil.p2shEnabled(program.flags) =>
executeP2shScript(scriptSigExecutedProgram, programBeingExecuted, P2SHScriptPubKey(csv.scriptPubKeyAfterCSV.hex))
case cltv : CLTVScriptPubKey if cltv.scriptPubKeyAfterCLTV.isInstanceOf[P2SHScriptPubKey] && ScriptFlagUtil.p2shEnabled(program.flags) =>
executeP2shScript(scriptSigExecutedProgram, programBeingExecuted, P2SHScriptPubKey(cltv.scriptPubKeyAfterCLTV.hex))*/
case _ : MultiSignatureScriptPubKey | _ : P2SHScriptPubKey | _ : P2PKHScriptPubKey |
_ : P2PKScriptPubKey | _ : CLTVScriptPubKey | _ : CSVScriptPubKey | _ : NonStandardScriptPubKey | EmptyScriptPubKey =>
logger.info("Stack state after scriptSig execution: " + scriptSigExecutedProgram.stack)

View file

@ -56,25 +56,23 @@ class TransactionSignatureCreatorSpec extends Properties("TransactionSignatureCr
Prop.forAllNoShrink(TransactionGenerators.spendableCLTVTransaction :| "cltv_spendable") {
case (txSignatureComponent: TransactionSignatureComponent, _, scriptNumber) =>
//run it through the interpreter
require(txSignatureComponent.transaction.lockTime.underlying >= scriptNumber.underlying, "TxLocktime must be satisifed so it should be greater than or equal to " +
require(txSignatureComponent.transaction.lockTime.underlying >= scriptNumber.underlying, "TxLocktime must be satisfied so it should be greater than or equal to " +
"the cltv value. Got TxLockTime : " + txSignatureComponent.transaction.lockTime.underlying + " , and cltv Value: " +
scriptNumber.underlying)
val program = ScriptProgram(txSignatureComponent)
val result = ScriptInterpreter.run(program)
val cltv = CLTVScriptPubKey(txSignatureComponent.scriptPubKey.hex)
Seq(ScriptOk).contains(result)
result == ScriptOk
}
property("generate a valid signature for a validly constructed, but NOT spendable cltv transaction") =
property("fail to verify a transaction with a locktime that has not yet been met") =
Prop.forAllNoShrink(TransactionGenerators.unspendableCLTVTransaction :| "cltv_unspendable") {
case (txSignatureComponent: TransactionSignatureComponent, _, scriptNumber) =>
//run it through the interpreter
require(txSignatureComponent.transaction.lockTime.underlying < scriptNumber.underlying, "TxLocktime must not be satisifed so it should be less than " +
require(txSignatureComponent.transaction.lockTime.underlying < scriptNumber.underlying, "TxLocktime must not be satisfied so it should be less than " +
"the cltv value. Got TxLockTime : " + txSignatureComponent.transaction.lockTime.underlying + " , and cltv Value: " +
scriptNumber.underlying)
val program = ScriptProgram(txSignatureComponent)
val result = ScriptInterpreter.run(program)
val cltv = CLTVScriptPubKey(txSignatureComponent.scriptPubKey.hex)
Seq(ScriptErrorUnsatisfiedLocktime, ScriptErrorPushSize).contains(result)
}
@ -87,7 +85,7 @@ class TransactionSignatureCreatorSpec extends Properties("TransactionSignatureCr
Seq(ScriptOk, ScriptErrorPushSize).contains(result)
}
property("generate a valid signature for a validly constructed but unspendable csv transaction") =
property("fail to verify a transaction with a relative locktime that has not been satisfied yet") =
Prop.forAllNoShrink(TransactionGenerators.unspendableCSVTransaction :| "unspendable csv") {
case (txSignatureComponent: TransactionSignatureComponent, keys, scriptNumber, sequence) =>
//run it through the interpreter

View file

@ -1,7 +1,7 @@
package org.bitcoins.core.util
import org.bitcoins.core.crypto.ECPublicKey
import org.bitcoins.core.script.bitwise.OP_EQUALVERIFY
import org.bitcoins.core.script.bitwise.{OP_OR, OP_EQUALVERIFY}
import org.bitcoins.core.script.constant._
import org.bitcoins.core.script.crypto._
import org.bitcoins.core.script.locktime.OP_CHECKLOCKTIMEVERIFY
@ -183,4 +183,17 @@ class BitcoinScriptUtilTest extends FlatSpec with MustMatchers {
val program = TestUtil.testProgram
BitcoinScriptUtil.checkPubKeyEncoding(key,program) must be (false)
}
it must "determine if script number is correctly minimally-encoded" in {
val scriptNum100 = ScriptNumber(100)
val scriptNum10 = ScriptNumber(10)
val scriptNumZero = ScriptNumber(0)
val scriptNum16 = ScriptNumber(16)
val scriptNum17 = ScriptNumber(17)
BitcoinScriptUtil.correctScriptNumberRepresentation(scriptNum100) must be (None)
BitcoinScriptUtil.correctScriptNumberRepresentation(scriptNum10) must be (Some(OP_10))
BitcoinScriptUtil.correctScriptNumberRepresentation(scriptNumZero) must be (Some(OP_0))
BitcoinScriptUtil.correctScriptNumberRepresentation(scriptNum16) must be (Some(OP_16))
BitcoinScriptUtil.correctScriptNumberRepresentation(scriptNum17) must be (None)
}
}