Fixing bug in OP_PICK, not interpreting script numbers any more, just using the script number passed to us

This commit is contained in:
Chris Stewart 2016-05-11 09:18:05 -05:00
parent 721620c72c
commit 7e80094ee1
4 changed files with 25 additions and 21 deletions

View file

@ -20,7 +20,6 @@ trait StackInterpreter extends BitcoinSLogger {
/** /**
* Duplicates the element on top of the stack * Duplicates the element on top of the stack
* expects the first element in script to be the OP_DUP operation * expects the first element in script to be the OP_DUP operation
*
* @param program * @param program
* @return * @return
*/ */
@ -36,7 +35,6 @@ trait StackInterpreter extends BitcoinSLogger {
/** /**
* If the top stack value is not 0, duplicate it. * If the top stack value is not 0, duplicate it.
*
* @param program * @param program
* @return * @return
*/ */
@ -161,7 +159,8 @@ trait StackInterpreter extends BitcoinSLogger {
def opPick(program : ScriptProgram) : ScriptProgram = { def opPick(program : ScriptProgram) : ScriptProgram = {
require(program.script.headOption.isDefined && program.script.head == OP_PICK, "Top of script stack must be OP_PICK") require(program.script.headOption.isDefined && program.script.head == OP_PICK, "Top of script stack must be OP_PICK")
require(program.stack.size > 0,"Stack must have at least two items on it for OP_PICK") require(program.stack.size > 0,"Stack must have at least two items on it for OP_PICK")
executeOpWithStackTopAsNumberArg(program, (number : ScriptNumber) => executeOpWithStackTopAsNumberArg(program, { number : ScriptNumber =>
logger.info("Script number for OP_PICK: " + number)
//check if n is within the bound of the script //check if n is within the bound of the script
(number.num >= 0 && number.num < program.stack.tail.size) match { (number.num >= 0 && number.num < program.stack.tail.size) match {
case true => case true =>
@ -171,7 +170,7 @@ trait StackInterpreter extends BitcoinSLogger {
logger.error("The index for OP_PICK would have caused an index out of bounds exception") logger.error("The index for OP_PICK would have caused an index out of bounds exception")
ScriptProgram(program, ScriptErrorInvalidStackOperation) ScriptProgram(program, ScriptErrorInvalidStackOperation)
} }
) })
} }
/** /**
@ -376,6 +375,10 @@ trait StackInterpreter extends BitcoinSLogger {
* @return the program with the result of the op pushed onto to the top of the stack * @return the program with the result of the op pushed onto to the top of the stack
*/ */
private def executeOpWithStackTopAsNumberArg(program : ScriptProgram, op : ScriptNumber => ScriptProgram) : ScriptProgram = { private def executeOpWithStackTopAsNumberArg(program : ScriptProgram, op : ScriptNumber => ScriptProgram) : ScriptProgram = {
program.stack.head match {
case scriptNum : ScriptNumber => op(scriptNum)
case _ : ScriptToken =>
//interpret the stack top as a number
val number : Try[ScriptNumber] = ScriptNumber(program.stack.head.bytes, ScriptFlagUtil.requireMinimalData(program.flags)) val number : Try[ScriptNumber] = ScriptNumber(program.stack.head.bytes, ScriptFlagUtil.requireMinimalData(program.flags))
number match { number match {
case Success(n) => op(n) case Success(n) => op(n)
@ -384,5 +387,6 @@ trait StackInterpreter extends BitcoinSLogger {
ScriptProgram(program,ScriptErrorUnknownError) ScriptProgram(program,ScriptErrorUnknownError)
} }
} }
}
} }

View file

@ -52,9 +52,9 @@ class TransactionTest extends FlatSpec with MustMatchers with BitcoinSLogger {
val lines = val lines =
""" """
|[ |[
| ["ddc454a1c0c35c188c98976b17670f69e586d9c0f3593ea879928332f0a069e7, which spends an input that pushes using a PUSHDATA1 that is negative when read as signed"], |[[["cbebc4da731e8995fe97f6fadcd731b36ad40e5ecb31e38e904f6e5982fa09f7", 0, "0x2102085c6600657566acc2d6382a47bc3f324008d2aa10940dd7705a48aa2a5a5e33ac7c2103f5d0fb955f95dd6be6115ce85661db412ec6a08abcbfce7da0ba8297c6cc0ec4ac7c5379a820d68df9e32a147cffa36193c6f7c43a1c8c69cda530e1c6db354bfabdcfefaf3c875379a820f531f3041d3136701ea09067c53e7159c8f9b2746a56c3d82966c54bbc553226879a5479827701200122a59a5379827701200122a59a6353798277537982778779679a68"]],
| [[["c5510a5dd97a25f43175af1fe649b707b1df8e1a41489bac33a23087027a2f48", 0, "0x4c 0xae 0x606563686f2022553246736447566b58312b5a536e587574356542793066794778625456415675534a6c376a6a334878416945325364667657734f53474f36633338584d7439435c6e543249584967306a486956304f376e775236644546673d3d22203e20743b206f70656e73736c20656e63202d7061737320706173733a5b314a564d7751432d707269766b65792d6865785d202d64202d6165732d3235362d636263202d61202d696e207460 DROP DUP HASH160 0x14 0xbfd7436b6265aa9de506f8a994f881ff08cc2872 EQUALVERIFY CHECKSIG"]], |"0100000001f709fa82596e4f908ee331cb5e0ed46ab331d7dcfaf697fe95891e73dac4ebcb000000008c20ca42095840735e89283fec298e62ac2ddea9b5f34a8cbb7097ad965b87568100201b1b01dc829177da4a14551d2fc96a9db00c6501edfa12f22cd9cefd335c227f483045022100a9df60536df5733dd0de6bc921fab0b3eee6426501b43a228afa2c90072eb5ca02201c78b74266fac7d1db5deff080d8a403743203f109fbcabf6d5a760bf87386d20100ffffffff01c075790000000000232103611f9a45c18f28f06f19076ad571c344c82ce8fcfe34464cf8085217a2d294a6ac00000000", "P2SH"]
| "0100000001482f7a028730a233ac9b48411a8edfb107b749e61faf7531f4257ad95d0a51c5000000008b483045022100bf0bbae9bde51ad2b222e87fbf67530fbafc25c903519a1e5dcc52a32ff5844e022028c4d9ad49b006dd59974372a54291d5764be541574bb0c4dc208ec51f80b7190141049dd4aad62741dc27d5f267f7b70682eee22e7e9c1923b9c0957bdae0b96374569b460eb8d5b40d972e8c7c0ad441de3d94c4a29864b212d56050acb980b72b2bffffffff0180969800000000001976a914e336d0017a9d28de99d16472f6ca6d5a3a8ebc9988ac00000000", "P2SH"] |
|] |]
""".stripMargin """.stripMargin
//val lines = try source.getLines.filterNot(_.isEmpty).map(_.trim) mkString "\n" finally source.close() //val lines = try source.getLines.filterNot(_.isEmpty).map(_.trim) mkString "\n" finally source.close()

View file

@ -214,7 +214,7 @@ class StackInterpreterTest extends FlatSpec with MustMatchers with StackInterpre
val newProgram = opRoll(program) val newProgram = opRoll(program)
newProgram.isInstanceOf[ExecutedScriptProgram] must be (true) newProgram.isInstanceOf[ExecutedScriptProgram] must be (true)
newProgram.asInstanceOf[ExecutedScriptProgram].error must be (Some(ScriptErrorUnknownError)) newProgram.asInstanceOf[ExecutedScriptProgram].error must be (Some(ScriptErrorInvalidStackOperation))
} }
it must "evaluate an OP_ROT correctly" in { it must "evaluate an OP_ROT correctly" in {