Forgot to implement aritmetic operation OP_WITHIN

This commit is contained in:
Chris Stewart 2016-02-07 11:44:05 -06:00
parent a3594967ea
commit a9926e6cba
3 changed files with 48 additions and 0 deletions

View File

@ -394,6 +394,34 @@ trait ArithmeticInterpreter extends ControlOperationsInterpreter {
}
/**
* Returns 1 if x is within the specified range (left-inclusive), 0 otherwise.
* @param program
* @return
*/
def opWithin(program : ScriptProgram) : ScriptProgram = {
require(program.script.headOption.isDefined && program.script.head == OP_WITHIN,
"Script top must be OP_WITHIN")
require(program.stack.size > 2, "Stack size must be 3 or more perform an OP_WITHIN")
val c = program.stack.head
val b = program.stack.tail.head
val a = program.stack.tail.tail.head
val isWithinRange = (a,b,c) match {
case (x : ScriptNumberOperation, y : ScriptNumber, z : ScriptNumber) => z >= x && z < y
case (x : ScriptNumber, y : ScriptNumberOperation, z : ScriptNumber) => z >= x && z < y.scriptNumber
case (x : ScriptNumber, y : ScriptNumber, z : ScriptNumberOperation) => z.scriptNumber >= x && z.scriptNumber < y
case (x : ScriptNumber, y : ScriptNumber, z : ScriptNumber) => z >= x && z < y
case (x,y,z) => z.toLong >= x.toLong && z.toLong < y.toLong
}
val newStackTop = if (isWithinRange) OP_1 else OP_0
ScriptProgramImpl(newStackTop :: program.stack.tail.tail.tail,
program.script.tail, program.transaction, program.altStack)
}
/**
* Wraps a scala number into a script token for the script language

View File

@ -82,6 +82,7 @@ trait ScriptInterpreter extends CryptoInterpreter with StackInterpreter with Con
case OP_GREATERTHANOREQUAL :: t => loop(opGreaterThanOrEqual(program))
case OP_MIN :: t => loop(opMin(program))
case OP_MAX :: t => loop(opMax(program))
case OP_WITHIN :: t => loop(opWithin(program))
//bitwise operations
case OP_EQUAL :: t => {
val newProgram = opEqual(program)

View File

@ -338,4 +338,23 @@ class ArithmeticInterpreterTest extends FlatSpec with MustMatchers with Arithmet
newProgram.stack must be (List(ScriptNumberImpl(1)))
}
it must "evaluate an OP_WITHIN correctly" in {
val stack = List(OP_0,ScriptNumberImpl(2), ScriptNumberImpl(1))
val script = List(OP_WITHIN)
val program = ScriptProgramImpl(stack,script,TestUtil.transaction,List())
val newProgram = opWithin(program)
newProgram.stack must be (List(OP_0))
newProgram.script.isEmpty must be (true)
val stack1 = List(OP_0, ScriptNumberImpl(1),ScriptNumberImpl(0))
val script1 = List(OP_WITHIN)
val program1 = ScriptProgramImpl(stack1,script1,TestUtil.transaction,List())
val newProgram1 = opWithin(program1)
newProgram1.stack must be (List(OP_1))
newProgram1.script.isEmpty must be (true)
}
}