Implementing OP_2ROT for script operations

This commit is contained in:
Chris Stewart 2016-02-03 21:44:13 -06:00
parent d41da910b7
commit 7c17ae7568
3 changed files with 30 additions and 0 deletions

View file

@ -52,6 +52,7 @@ trait ScriptInterpreter extends CryptoInterpreter with StackInterpreter with Con
case OP_PICK :: t => loop(opPick(program))
case OP_ROLL :: t => loop(opRoll(program))
case OP_ROT :: t => loop(opRot(program))
case OP_2ROT :: t => loop(op2Rot(program))
//arithmetic operations
case OP_ADD :: t => loop(opAdd(program))

View file

@ -153,6 +153,7 @@ trait StackInterpreter {
/**
* The top three items on the stack are rotated to the left.
* x1 x2 x3 -> x2 x3 x1
* @param program
* @return
*/
@ -167,4 +168,21 @@ trait StackInterpreter {
ScriptProgramImpl(newStack,program.script.tail,program.transaction,program.altStack)
}
/**
* The fifth and sixth items back are moved to the top of the stack.
* x1 x2 x3 x4 x5 x6 -> x3 x4 x5 x6 x1 x2
* @param program
* @return
*/
def op2Rot(program : ScriptProgram) : ScriptProgram = {
require(program.script.headOption.isDefined && program.script.head == OP_2ROT, "Top of script stack must be OP_2ROT")
require(program.stack.size > 5,"Stack must have at least 5 items on it for OP_2ROT")
val newStack = program.stack match {
case h :: h1 :: h2 :: h3 :: h4 :: h5 :: t => h4 :: h5 :: h :: h1 :: h2 :: h3 :: t
case _ => throw new RuntimeException("Stack must have at least 5 items on it for OP_2ROT")
}
ScriptProgramImpl(newStack,program.script.tail,program.transaction,program.altStack)
}
}

View file

@ -149,6 +149,17 @@ class StackInterpreterTest extends FlatSpec with MustMatchers with StackInterpre
newProgram.stack must be (List(ScriptConstantImpl("16"),ScriptConstantImpl("14"),ScriptConstantImpl("15")))
newProgram.script.isEmpty must be (true)
}
it must "evaluate an OP_2ROT correctly" in {
val stack = List(ScriptConstantImpl("14"), ScriptConstantImpl("15"), ScriptConstantImpl("16"),
ScriptConstantImpl("17"), ScriptConstantImpl("18"), ScriptConstantImpl("19"))
val script = List(OP_2ROT)
val program = ScriptProgramImpl(stack,script,TestUtil.transaction,List())
val newProgram = op2Rot(program)
newProgram.stack must be (List(ScriptConstantImpl("18"),ScriptConstantImpl("19"),ScriptConstantImpl("14"),
ScriptConstantImpl("15"),ScriptConstantImpl("16"), ScriptConstantImpl("17")))
newProgram.script.isEmpty must be (true)
}
}