From d5eff75956b60a166a02246c8cb25b2341f6df47 Mon Sep 17 00:00:00 2001 From: Chris Stewart Date: Tue, 19 Jan 2016 20:20:24 -0600 Subject: [PATCH] Successfully running the first grouping of tests from bicoin core - the ones to do with whitespaces --- .../scalacoin/script/constant/Constants.scala | 32 +++++++++---------- .../interpreter/ScriptInterpreter.scala | 32 +++++++++++-------- .../interpreter/ScriptInterpreterTest.scala | 7 ++-- .../testprotocol/CoreTestCase.scala | 3 +- 4 files changed, 40 insertions(+), 34 deletions(-) diff --git a/src/main/scala/org/scalacoin/script/constant/Constants.scala b/src/main/scala/org/scalacoin/script/constant/Constants.scala index c7ac5c14a1..08001c63ef 100644 --- a/src/main/scala/org/scalacoin/script/constant/Constants.scala +++ b/src/main/scala/org/scalacoin/script/constant/Constants.scala @@ -86,112 +86,112 @@ case object OP_TRUE extends ScriptOperation { /** * The number 1 is pushed onto the stack. */ -case object OP_1 extends ScriptOperation { +case object OP_1 extends ScriptOperation with ScriptNumber { override def opCode = OP_TRUE.opCode } /** * The number 2 is pushed onto the stack. */ -case object OP_2 extends ScriptOperation { +case object OP_2 extends ScriptOperation with ScriptNumber { override def opCode = 82 } /** * The number 3 is pushed onto the stack. */ -case object OP_3 extends ScriptOperation { +case object OP_3 extends ScriptOperation with ScriptNumber { override def opCode = 83 } /** * The number 4 is pushed onto the stack. */ -case object OP_4 extends ScriptOperation { +case object OP_4 extends ScriptOperation with ScriptNumber { override def opCode = 84 } /** * The number 5 is pushed onto the stack. */ -case object OP_5 extends ScriptOperation { +case object OP_5 extends ScriptOperation with ScriptNumber { override def opCode = 85 } /** * The number 6 is pushed onto the stack. */ -case object OP_6 extends ScriptOperation { +case object OP_6 extends ScriptOperation with ScriptNumber { override def opCode = 86 } /** * The number 7 is pushed onto the stack. */ -case object OP_7 extends ScriptOperation { +case object OP_7 extends ScriptOperation with ScriptNumber { override def opCode = 87 } /** * The number 8 is pushed onto the stack. */ -case object OP_8 extends ScriptOperation { +case object OP_8 extends ScriptOperation with ScriptNumber { override def opCode = 88 } /** * The number 9 is pushed onto the stack. */ -case object OP_9 extends ScriptOperation { +case object OP_9 extends ScriptOperation with ScriptNumber { override def opCode = 89 } /** * The number 10 is pushed onto the stack. */ -case object OP_10 extends ScriptOperation { +case object OP_10 extends ScriptOperation with ScriptNumber { override def opCode = 90 } /** * The number 11 is pushed onto the stack. */ -case object OP_11 extends ScriptOperation { +case object OP_11 extends ScriptOperation with ScriptNumber { override def opCode = 91 } /** * The number 12 is pushed onto the stack. */ -case object OP_12 extends ScriptOperation { +case object OP_12 extends ScriptOperation with ScriptNumber { override def opCode = 92 } /** * The number 13 is pushed onto the stack. */ -case object OP_13 extends ScriptOperation { +case object OP_13 extends ScriptOperation with ScriptNumber { override def opCode = 93 } /** * The number 14 is pushed onto the stack. */ -case object OP_14 extends ScriptOperation { +case object OP_14 extends ScriptOperation with ScriptNumber { override def opCode = 94 } /** * The number 15 is pushed onto the stack. */ -case object OP_15 extends ScriptOperation { +case object OP_15 extends ScriptOperation with ScriptNumber { override def opCode = 95 } /** * The number 16 is pushed onto the stack. */ -case object OP_16 extends ScriptOperation { +case object OP_16 extends ScriptOperation with ScriptNumber { override def opCode = 96 } diff --git a/src/main/scala/org/scalacoin/script/interpreter/ScriptInterpreter.scala b/src/main/scala/org/scalacoin/script/interpreter/ScriptInterpreter.scala index 4b66501dac..be37edc405 100644 --- a/src/main/scala/org/scalacoin/script/interpreter/ScriptInterpreter.scala +++ b/src/main/scala/org/scalacoin/script/interpreter/ScriptInterpreter.scala @@ -31,34 +31,38 @@ trait ScriptInterpreter extends CryptoInterpreter with StackInterpreter with Con @tailrec def loop(scripts : (List[ScriptToken], List[ScriptToken])) : Boolean = { - val (stack,outputScript) = (scripts._1, scripts._2) - outputScript match { + val (stack,script) = (scripts._1, scripts._2) + script match { //stack operations - case OP_DUP :: t => loop(opDup(stack,outputScript)) - case OP_DEPTH :: t => loop(opDepth(stack,outputScript)) + case OP_DUP :: t => loop(opDup(stack,script)) + case OP_DEPTH :: t => loop(opDepth(stack,script)) //bitwise operations case OP_EQUAL :: t => { - val (newInputScript,newOutputScript) = equal(stack, outputScript) - logger.debug("New input script: " + newInputScript) - logger.debug("new output script: " + newOutputScript) - if (newInputScript.head == ScriptTrue && newOutputScript.size == 0) true - else if (newInputScript.head == ScriptFalse && newOutputScript.size == 0) false - else loop(newInputScript,newOutputScript) + val (newStack,newScript) = equal(stack, script) + logger.debug("New stack: " + newStack) + logger.debug("New script: " + newScript) + if (newStack.head == ScriptTrue && newScript.size == 0) true + else if (newStack.head == ScriptFalse && newScript.size == 0) false + else loop(newStack,newScript) } - case OP_EQUALVERIFY :: t => equalVerify(stack,outputScript) + case OP_EQUALVERIFY :: t => equalVerify(stack,script) //script constants //TODO: Implement these case ScriptConstantImpl(x) :: t if x == "1" => throw new RuntimeException("Not implemented yet") case ScriptConstantImpl(x) :: t if x == "0" => throw new RuntimeException("Not implemented yet") - case OP_0 :: t => loop(OP_0 :: stack, t) + case (scriptNumber : ScriptNumber)::t => loop(scriptNumber :: stack, t) + //TODO: is this right? I need to just push a constant on the input stack??? case ScriptConstantImpl(x) :: t => loop((ScriptConstantImpl(x) :: stack, t)) //crypto operations - case OP_HASH160 :: t => loop(hash160(stack,outputScript)) - case OP_CHECKSIG :: t => checkSig(stack,outputScript,fullScript) + case OP_HASH160 :: t => loop(hash160(stack,script)) + case OP_CHECKSIG :: t => checkSig(stack,script,fullScript) + //no more script operations to run, if stack top is true or '1' then it is a valid script + case Nil => stack.head == OP_1 || stack.head == ScriptTrue + case h :: t => throw new RuntimeException(h + " was unmatched") } } diff --git a/src/test/scala/org/scalacoin/script/interpreter/ScriptInterpreterTest.scala b/src/test/scala/org/scalacoin/script/interpreter/ScriptInterpreterTest.scala index 605c40cebf..9d48c48d35 100644 --- a/src/test/scala/org/scalacoin/script/interpreter/ScriptInterpreterTest.scala +++ b/src/test/scala/org/scalacoin/script/interpreter/ScriptInterpreterTest.scala @@ -37,15 +37,16 @@ class ScriptInterpreterTest extends FlatSpec with MustMatchers with ScriptInterp val lines = try source.getLines.filterNot(_.isEmpty).map(_.trim) mkString "\n" finally source.close() val json = lines.parseJson val testCasesOpt : Seq[Option[CoreTestCase]] = json.convertTo[Seq[Option[CoreTestCase]]] - val testCases = Seq(testCasesOpt.flatten.head) + val testCases : Seq[CoreTestCase] = testCasesOpt.flatten for { testCase <- testCases } yield { logger.info("Running test case: ") - logger.info("ScriptSig: " + testCase.scriptSig) - logger.info("ScriptPubKey: " + testCase.scriptPubKey) + logger.info("Raw test case: " + testCase.raw) + logger.info("Parsed ScriptSig: " + testCase.scriptSig) + logger.info("Parsed ScriptPubKey: " + testCase.scriptPubKey) logger.info("Flags: " + testCase.flags) logger.info("Comments: " + testCase.comments) withClue(testCase.comments) { diff --git a/src/test/scala/org/scalacoin/script/interpreter/testprotocol/CoreTestCase.scala b/src/test/scala/org/scalacoin/script/interpreter/testprotocol/CoreTestCase.scala index 5705ec000a..99c37fb1cd 100644 --- a/src/test/scala/org/scalacoin/script/interpreter/testprotocol/CoreTestCase.scala +++ b/src/test/scala/org/scalacoin/script/interpreter/testprotocol/CoreTestCase.scala @@ -13,7 +13,8 @@ trait CoreTestCase { def scriptPubKey : ScriptPubKey def flags : String def comments : String + def raw : String } case class CoreTestCaseImpl(scriptSig : ScriptSignature, - scriptPubKey: ScriptPubKey, flags : String, comments : String) extends CoreTestCase + scriptPubKey: ScriptPubKey, flags : String, comments : String, raw : String) extends CoreTestCase