mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2025-02-25 15:20:17 +01:00
Fixing bug in OP_PICK, not interpreting script numbers any more, just using the script number passed to us
This commit is contained in:
parent
721620c72c
commit
7e80094ee1
4 changed files with 25 additions and 21 deletions
|
@ -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,17 +159,18 @@ 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 =>
|
||||||
val newStackTop = program.stack.tail(number.num.toInt)
|
val newStackTop = program.stack.tail(number.num.toInt)
|
||||||
ScriptProgram (program, newStackTop :: program.stack.tail, program.script.tail)
|
ScriptProgram(program, newStackTop :: program.stack.tail, program.script.tail)
|
||||||
case false =>
|
case false =>
|
||||||
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Add table
Reference in a new issue