From eb948328a5aefb0fb4b350bd652914a65f469c74 Mon Sep 17 00:00:00 2001 From: Tom McCabe Date: Thu, 15 Dec 2016 17:56:34 -0600 Subject: [PATCH] missed some opCode require statements w/ multiple clauses --- .../arithmetic/ArithmeticInterpreter.scala | 40 +++++++++--------- .../core/script/stack/StackInterpreter.scala | 42 +++++++++---------- 2 files changed, 40 insertions(+), 42 deletions(-) diff --git a/src/main/scala/org/bitcoins/core/script/arithmetic/ArithmeticInterpreter.scala b/src/main/scala/org/bitcoins/core/script/arithmetic/ArithmeticInterpreter.scala index 80140603eb..7af06e2b6e 100644 --- a/src/main/scala/org/bitcoins/core/script/arithmetic/ArithmeticInterpreter.scala +++ b/src/main/scala/org/bitcoins/core/script/arithmetic/ArithmeticInterpreter.scala @@ -16,31 +16,31 @@ trait ArithmeticInterpreter extends ControlOperationsInterpreter { /** a is added to b. */ def opAdd(program : ScriptProgram) : ScriptProgram = { - require(program.script.nonEmpty && program.script.head == OP_ADD, "Script top must be OP_ADD") + require(program.script.headOption.contains(OP_ADD), "Script top must be OP_ADD") performBinaryArithmeticOperation(program, (x,y) => x + y) } /** Increments the stack top by 1. */ def op1Add(program : ScriptProgram) : ScriptProgram = { - require(program.script.nonEmpty && program.script.head == OP_1ADD, "Script top must be OP_1ADD") + require(program.script.headOption.contains(OP_1ADD), "Script top must be OP_1ADD") performUnaryArithmeticOperation(program, x => x + ScriptNumber.one) } /** Decrements the stack top by 1. */ def op1Sub(program : ScriptProgram) : ScriptProgram = { - require(program.script.nonEmpty && program.script.head == OP_1SUB, "Script top must be OP_1SUB") + require(program.script.headOption.contains(OP_1SUB), "Script top must be OP_1SUB") performUnaryArithmeticOperation(program, x => x - ScriptNumber.one ) } /** b is subtracted from a. */ def opSub(program : ScriptProgram) : ScriptProgram = { - require(program.script.nonEmpty && program.script.head == OP_SUB, "Script top must be OP_SUB") + require(program.script.headOption.contains(OP_SUB), "Script top must be OP_SUB") performBinaryArithmeticOperation(program, (x,y) => y - x) } /** Takes the absolute value of the stack top. */ def opAbs(program : ScriptProgram) : ScriptProgram = { - require(program.script.nonEmpty && program.script.head == OP_ABS, "Script top must be OP_ABS") + require(program.script.headOption.contains(OP_ABS), "Script top must be OP_ABS") performUnaryArithmeticOperation(program, x => x match { case ScriptNumber.zero => ScriptNumber.zero case _ : ScriptNumber => ScriptNumber(x.underlying.abs) @@ -49,25 +49,25 @@ trait ArithmeticInterpreter extends ControlOperationsInterpreter { /** Negates the stack top. */ def opNegate(program : ScriptProgram) : ScriptProgram = { - require(program.script.nonEmpty && program.script.head == OP_NEGATE, "Script top must be OP_NEGATE") + require(program.script.headOption.contains(OP_NEGATE), "Script top must be OP_NEGATE") performUnaryArithmeticOperation(program, x => x -) } /** If the input is 0 or 1, it is flipped. Otherwise the output will be 0. */ def opNot(program : ScriptProgram) : ScriptProgram = { - require(program.script.nonEmpty && program.script.head == OP_NOT, "Script top must be OP_NOT") + require(program.script.headOption.contains(OP_NOT), "Script top must be OP_NOT") performUnaryArithmeticOperation(program, x => if (program.stackTopIsFalse) OP_TRUE else OP_FALSE) } /** Returns 0 if the input is 0. 1 otherwise. */ def op0NotEqual(program : ScriptProgram) : ScriptProgram = { - require(program.script.nonEmpty && program.script.head == OP_0NOTEQUAL, "Script top must be OP_0NOTEQUAL") + require(program.script.headOption.contains(OP_0NOTEQUAL), "Script top must be OP_0NOTEQUAL") performUnaryArithmeticOperation(program, x => if(x.underlying == 0) OP_FALSE else OP_TRUE) } /** If both a and b are not 0, the output is 1. Otherwise 0. */ def opBoolAnd(program : ScriptProgram) : ScriptProgram = { - require(program.script.nonEmpty && program.script.head == OP_BOOLAND, "Script top must be OP_BOOLAND") + require(program.script.headOption.contains(OP_BOOLAND), "Script top must be OP_BOOLAND") performBinaryBooleanOperation(program,(x,y) => { val xIsFalse = (x == ScriptNumber.zero || x == OP_0) val yIsFalse = (y == ScriptNumber.zero || y == OP_0) @@ -77,7 +77,7 @@ trait ArithmeticInterpreter extends ControlOperationsInterpreter { /** If a or b is not 0, the output is 1. Otherwise 0. */ def opBoolOr(program : ScriptProgram) : ScriptProgram = { - require(program.script.nonEmpty && program.script.head == OP_BOOLOR, "Script top must be OP_BOOLOR") + require(program.script.headOption.contains(OP_BOOLOR), "Script top must be OP_BOOLOR") performBinaryBooleanOperation(program, (x,y) => { if (x == y && (x == ScriptNumber.zero || x == OP_0)) false else true }) @@ -85,13 +85,13 @@ trait ArithmeticInterpreter extends ControlOperationsInterpreter { /** Returns 1 if the numbers are equal, 0 otherwise. */ def opNumEqual(program : ScriptProgram) : ScriptProgram = { - require(program.script.nonEmpty && program.script.head == OP_NUMEQUAL, "Script top must be OP_NUMEQUAL") + require(program.script.headOption.contains(OP_NUMEQUAL), "Script top must be OP_NUMEQUAL") performBinaryBooleanOperation(program,(x,y) => x.numEqual(y)) } /** Same as [[OP_NUMEQUAL]], but runs [[OP_VERIFY]] afterward. */ def opNumEqualVerify(program : ScriptProgram) : ScriptProgram = { - require(program.script.nonEmpty && program.script.head == OP_NUMEQUALVERIFY, + require(program.script.headOption.contains(OP_NUMEQUALVERIFY), "Script top must be OP_NUMEQUALVERIFY") if (program.stack.size < 2) { logger.error("OP_NUMEQUALVERIFY requires two stack elements") @@ -112,7 +112,7 @@ trait ArithmeticInterpreter extends ControlOperationsInterpreter { /** Returns 1 if the numbers are not equal, 0 otherwise. */ def opNumNotEqual(program : ScriptProgram) : ScriptProgram = { - require(program.script.nonEmpty && program.script.head == OP_NUMNOTEQUAL, + require(program.script.headOption.contains(OP_NUMNOTEQUAL), "Script top must be OP_NUMNOTEQUAL") performBinaryBooleanOperation(program, (x,y) => { x.underlying != y.underlying @@ -121,35 +121,35 @@ trait ArithmeticInterpreter extends ControlOperationsInterpreter { /** Returns 1 if a is less than b, 0 otherwise. */ def opLessThan(program : ScriptProgram) : ScriptProgram = { - require(program.script.nonEmpty && program.script.head == OP_LESSTHAN, + require(program.script.headOption.contains(OP_LESSTHAN), "Script top must be OP_LESSTHAN") performBinaryBooleanOperation(program, (x,y) => y < x) } /** Returns 1 if a is greater than b, 0 otherwise. */ def opGreaterThan(program : ScriptProgram) : ScriptProgram = { - require(program.script.nonEmpty && program.script.head == OP_GREATERTHAN, + require(program.script.headOption.contains(OP_GREATERTHAN), "Script top must be OP_GREATERTHAN") performBinaryBooleanOperation(program, (x,y) => y > x) } /** Returns 1 if a is less than or equal to b, 0 otherwise. */ def opLessThanOrEqual(program : ScriptProgram) : ScriptProgram = { - require(program.script.nonEmpty && program.script.head == OP_LESSTHANOREQUAL, + require(program.script.headOption.contains(OP_LESSTHANOREQUAL), "Script top must be OP_LESSTHANOREQUAL") performBinaryBooleanOperation(program, (x,y) => y <= x) } /** Returns 1 if a is greater than or equal to b, 0 otherwise. */ def opGreaterThanOrEqual(program : ScriptProgram) : ScriptProgram = { - require(program.script.nonEmpty && program.script.head == OP_GREATERTHANOREQUAL, + require(program.script.headOption.contains(OP_GREATERTHANOREQUAL), "Script top must be OP_GREATERTHANOREQUAL") performBinaryBooleanOperation(program, (x,y) => y >= x) } /** Returns the smaller of a and b. */ def opMin(program : ScriptProgram) : ScriptProgram = { - require(program.script.nonEmpty && program.script.head == OP_MIN, + require(program.script.headOption.contains(OP_MIN), "Script top must be OP_MIN") if (program.stack.size < 2) { logger.error("OP_MAX requires at least two stack elements") @@ -161,7 +161,7 @@ trait ArithmeticInterpreter extends ControlOperationsInterpreter { /** Returns the larger of a and b. */ def opMax(program : ScriptProgram) : ScriptProgram = { - require(program.script.nonEmpty && program.script.head == OP_MAX, + require(program.script.headOption.contains(OP_MAX), "Script top must be OP_MAX") if (program.stack.size < 2) { logger.error("OP_MAX requires at least two stack elements") @@ -173,7 +173,7 @@ trait ArithmeticInterpreter extends ControlOperationsInterpreter { /** Returns 1 if x is within the specified range (left-inclusive), 0 otherwise. */ def opWithin(program : ScriptProgram) : ScriptProgram = { - require(program.script.nonEmpty && program.script.head == OP_WITHIN, + require(program.script.headOption.contains(OP_WITHIN), "Script top must be OP_WITHIN") if (program.stack.size < 3) { logger.error("OP_WITHIN requires at least 3 elements on the stack") diff --git a/src/main/scala/org/bitcoins/core/script/stack/StackInterpreter.scala b/src/main/scala/org/bitcoins/core/script/stack/StackInterpreter.scala index 39e8d63651..5360f6d077 100644 --- a/src/main/scala/org/bitcoins/core/script/stack/StackInterpreter.scala +++ b/src/main/scala/org/bitcoins/core/script/stack/StackInterpreter.scala @@ -19,7 +19,7 @@ trait StackInterpreter extends BitcoinSLogger { /** Duplicates the element on top of the stack * expects the first element in script to be the OP_DUP operation. */ def opDup(program : ScriptProgram) : ScriptProgram = { - require(program.script.nonEmpty && program.script.head == OP_DUP, "Top of the script stack must be OP_DUP") + require(program.script.headOption.contains(OP_DUP), "Top of the script stack must be OP_DUP") program.stack match { case h :: t => ScriptProgram(program, h :: program.stack, program.script.tail) case Nil => @@ -30,7 +30,7 @@ trait StackInterpreter extends BitcoinSLogger { /** If the top stack value is not 0, duplicate it. */ def opIfDup(program : ScriptProgram) : ScriptProgram = { - require(program.script.nonEmpty && program.script.head == OP_IFDUP, "Top of the script stack must be OP_DUP") + require(program.script.headOption.contains(OP_IFDUP), "Top of the script stack must be OP_DUP") if (program.stack.nonEmpty) { if (program.stack.head == ScriptNumber.zero) return ScriptProgram(program, program.stack, program.script.tail) ScriptProgram(program, program.stack.head :: program.stack, program.script.tail) @@ -42,7 +42,7 @@ trait StackInterpreter extends BitcoinSLogger { /** Puts the number of stack items onto the stack. */ def opDepth(program : ScriptProgram) : ScriptProgram = { - require(program.script.nonEmpty && program.script.head == OP_DEPTH, "Top of script stack must be OP_DEPTH") + require(program.script.headOption.contains(OP_DEPTH), "Top of script stack must be OP_DEPTH") require(program.script.nonEmpty, "OP_DEPTH requires at least two elements on the script stack") val stackSize = program.stack.size val numberToPush : ScriptNumber = ScriptNumber(stackSize) @@ -51,7 +51,7 @@ trait StackInterpreter extends BitcoinSLogger { /** Puts the input onto the top of the alt stack. Removes it from the main stack. */ def opToAltStack(program : ScriptProgram) : ScriptProgram = { - require(program.script.nonEmpty && program.script.head == OP_TOALTSTACK, "Top of script stack must be OP_TOALTSTACK") + require(program.script.headOption.contains(OP_TOALTSTACK), "Top of script stack must be OP_TOALTSTACK") if (program.stack.nonEmpty) { ScriptProgram(program, program.stack.tail, program.script.tail, program.stack.head :: program.altStack, ScriptProgram.AltStack) @@ -63,7 +63,7 @@ trait StackInterpreter extends BitcoinSLogger { /** Puts the input onto the top of the main stack. Removes it from the alt stack. */ def opFromAltStack(program : ScriptProgram) : ScriptProgram = { - require(program.script.nonEmpty && program.script.head == OP_FROMALTSTACK, "Top of script stack must be OP_FROMALTSTACK") + require(program.script.headOption.contains(OP_FROMALTSTACK), "Top of script stack must be OP_FROMALTSTACK") if (program.altStack.nonEmpty) { ScriptProgram(program, program.altStack.head :: program.stack, program.script.tail, program.altStack.tail, ScriptProgram.AltStack) @@ -75,7 +75,7 @@ trait StackInterpreter extends BitcoinSLogger { /** Removes the top stack item. */ def opDrop(program : ScriptProgram) : ScriptProgram = { - require(program.script.nonEmpty && program.script.head == OP_DROP, "Top of script stack must be OP_DROP") + require(program.script.headOption.contains(OP_DROP), "Top of script stack must be OP_DROP") if (program.stack.nonEmpty) { ScriptProgram(program, program.stack.tail, program.script.tail) } else { @@ -87,7 +87,7 @@ trait StackInterpreter extends BitcoinSLogger { /** Removes the second-to-top stack item. */ def opNip(program : ScriptProgram) : ScriptProgram = { - require(program.script.nonEmpty && program.script.head == OP_NIP, "Top of script stack must be OP_NIP") + require(program.script.headOption.contains(OP_NIP), "Top of script stack must be OP_NIP") program.stack match { case h :: _ :: t => ScriptProgram(program, h :: t, program.script.tail) case h :: t => @@ -102,7 +102,7 @@ trait StackInterpreter extends BitcoinSLogger { /** Copies the second-to-top stack item to the top. */ def opOver(program : ScriptProgram) : ScriptProgram = { - require(program.script.nonEmpty && program.script.head == OP_OVER, "Top of script stack must be OP_OVER") + require(program.script.headOption.contains(OP_OVER), "Top of script stack must be OP_OVER") program.stack match { case _ :: h1 :: _ => ScriptProgram(program, h1 :: program.stack, program.script.tail) case h :: t => logger.error("Stack must have at least two items on it for OP_OVER") @@ -115,8 +115,7 @@ trait StackInterpreter extends BitcoinSLogger { /** The item n back in the stack is copied to the top. */ def opPick(program : ScriptProgram) : ScriptProgram = { - require(program.script.nonEmpty && program.script.head == OP_PICK, "Top of script stack must be OP_PICK") - require(program.stack.nonEmpty,"Stack must have at least two items on it for OP_PICK") + require(program.script.headOption.contains(OP_PICK), "Top of script stack must be OP_PICK") executeOpWithStackTopAsNumberArg(program, { number : ScriptNumber => logger.info("Script number for OP_PICK: " + number) //check if n is within the bound of the script @@ -132,10 +131,9 @@ trait StackInterpreter extends BitcoinSLogger { /** The item n back in the stack is moved to the top. */ def opRoll(program : ScriptProgram) : ScriptProgram = { - require(program.script.nonEmpty && program.script.head == OP_ROLL, "Top of script stack must be OP_ROLL") - require(program.stack.nonEmpty,"Stack must have at least one items on it for OP_ROLL") + require(program.script.headOption.contains(OP_ROLL), "Top of script stack must be OP_ROLL") executeOpWithStackTopAsNumberArg(program, (number : ScriptNumber) => - if (number.underlying >= 0 && number.underlying < program.stack.tail.size) { + if (number.underlying >= 0 && number.underlying < program.stack.tail.size) { val newStackTop = program.stack.tail(number.toInt) //removes the old instance of the stack top, appends the new index to the head val newStack = newStackTop :: program.stack.tail.diff(List(newStackTop)) @@ -150,7 +148,7 @@ trait StackInterpreter extends BitcoinSLogger { /** The top three items on the stack are rotated to the left. * Ex: x1 x2 x3 -> x2 x3 x1 */ def opRot(program : ScriptProgram) : ScriptProgram = { - require(program.script.nonEmpty && program.script.head == OP_ROT, "Top of script stack must be OP_ROT") + require(program.script.headOption.contains(OP_ROT), "Top of script stack must be OP_ROT") program.stack match { case h :: h1 :: h2 :: t => val newStack = h2 :: h :: h1 :: t @@ -164,7 +162,7 @@ trait StackInterpreter extends BitcoinSLogger { /** The fifth and sixth items back are moved to the top of the stack. * Ex. x1 x2 x3 x4 x5 x6 -> x3 x4 x5 x6 x1 x2 */ def op2Rot(program : ScriptProgram) : ScriptProgram = { - require(program.script.nonEmpty && program.script.head == OP_2ROT, "Top of script stack must be OP_2ROT") + require(program.script.headOption.contains(OP_2ROT), "Top of script stack must be OP_2ROT") program.stack match { case h :: h1 :: h2 :: h3 :: h4 :: h5 :: t => val newStack = h4 :: h5 :: h :: h1 :: h2 :: h3 :: t @@ -177,7 +175,7 @@ trait StackInterpreter extends BitcoinSLogger { /** Removes the top two stack items. */ def op2Drop(program : ScriptProgram) : ScriptProgram = { - require(program.script.nonEmpty && program.script.head == OP_2DROP, "Top of script stack must be OP_2DROP") + require(program.script.headOption.contains(OP_2DROP), "Top of script stack must be OP_2DROP") if (program.stack.size > 1) { ScriptProgram(program, program.stack.tail.tail, program.script.tail) } else { @@ -189,7 +187,7 @@ trait StackInterpreter extends BitcoinSLogger { /** The top two items on the stack are swapped. */ def opSwap(program : ScriptProgram) : ScriptProgram = { - require(program.script.nonEmpty && program.script.head == OP_SWAP, "Top of script stack must be OP_SWAP") + require(program.script.headOption.contains(OP_SWAP), "Top of script stack must be OP_SWAP") if (program.stack.size > 1) { val newStack = program.stack.tail.head :: program.stack.head :: program.stack.tail.tail ScriptProgram(program, newStack, program.script.tail) @@ -202,7 +200,7 @@ trait StackInterpreter extends BitcoinSLogger { /** The item at the top of the stack is copied and inserted before the second-to-top item. */ def opTuck(program : ScriptProgram) : ScriptProgram = { - require(program.script.nonEmpty && program.script.head == OP_TUCK, "Top of script stack must be OP_TUCK") + require(program.script.headOption.contains(OP_TUCK), "Top of script stack must be OP_TUCK") program.stack match { case h :: h1 :: t => val newStack = h :: h1 :: h:: t @@ -216,7 +214,7 @@ trait StackInterpreter extends BitcoinSLogger { /** Duplicates the top two stack items. */ def op2Dup(program : ScriptProgram) : ScriptProgram = { - require(program.script.nonEmpty && program.script.head == OP_2DUP, "Top of script stack must be OP_2DUP") + require(program.script.headOption.contains(OP_2DUP), "Top of script stack must be OP_2DUP") program.stack match { case h :: h1 :: t => val newStack = h :: h1 :: h :: h1 :: t @@ -229,7 +227,7 @@ trait StackInterpreter extends BitcoinSLogger { /** Duplicates the top three stack items. */ def op3Dup(program : ScriptProgram) : ScriptProgram = { - require(program.script.nonEmpty && program.script.head == OP_3DUP, "Top of script stack must be OP_3DUP") + require(program.script.headOption.contains(OP_3DUP), "Top of script stack must be OP_3DUP") program.stack match { case h :: h1 :: h2 :: t => val newStack = h :: h1 :: h2 :: h :: h1 :: h2 :: t @@ -242,7 +240,7 @@ trait StackInterpreter extends BitcoinSLogger { /** Copies the pair of items two spaces back in the stack to the front. */ def op2Over(program : ScriptProgram) : ScriptProgram = { - require(program.script.nonEmpty && program.script.head == OP_2OVER, "Top of script stack must be OP_2OVER") + require(program.script.headOption.contains(OP_2OVER), "Top of script stack must be OP_2OVER") program.stack match { case h :: h1 :: h2 :: h3 :: t => val newStack = h2 :: h3 :: h :: h1 :: h2 :: h3 :: t @@ -255,7 +253,7 @@ trait StackInterpreter extends BitcoinSLogger { /** Swaps the top two pairs of items. */ def op2Swap(program : ScriptProgram) : ScriptProgram = { - require(program.script.nonEmpty && program.script.head == OP_2SWAP, "Top of script stack must be OP_2SWAP") + require(program.script.headOption.contains(OP_2SWAP), "Top of script stack must be OP_2SWAP") program.stack match { case h :: h1 :: h2 :: h3 :: t => val newStack = h2 :: h3 :: h :: h1 :: t