mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2025-02-25 15:20:17 +01:00
Implementing parser for core's tx_valid/invalid.json test cases, refactoring TransactionImpl inside the factory object
This commit is contained in:
parent
a82ed54d24
commit
6bab4115be
5 changed files with 88 additions and 10 deletions
|
@ -25,13 +25,14 @@ case object EmptyTransaction extends Transaction {
|
||||||
override def outputs = Seq()
|
override def outputs = Seq()
|
||||||
override def lockTime = TransactionConstants.lockTime
|
override def lockTime = TransactionConstants.lockTime
|
||||||
}
|
}
|
||||||
sealed case class TransactionImpl(version : Long, inputs : Seq[TransactionInput],
|
|
||||||
outputs : Seq[TransactionOutput], lockTime : Long) extends Transaction
|
|
||||||
|
|
||||||
object Transaction extends Factory[Transaction] {
|
object Transaction extends Factory[Transaction] {
|
||||||
|
|
||||||
|
private sealed case class TransactionImpl(version : Long, inputs : Seq[TransactionInput],
|
||||||
|
outputs : Seq[TransactionOutput], lockTime : Long) extends Transaction
|
||||||
/**
|
/**
|
||||||
* Updates a transaction outputs
|
* Updates a transaction outputs
|
||||||
*
|
|
||||||
* @param updatedOutputs
|
* @param updatedOutputs
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
@ -41,7 +42,6 @@ object Transaction extends Factory[Transaction] {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates a transaction's inputs
|
* Updates a transaction's inputs
|
||||||
*
|
|
||||||
* @param updatedInputs
|
* @param updatedInputs
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
@ -51,7 +51,6 @@ object Transaction extends Factory[Transaction] {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Factory function that modifies a transactions locktime
|
* Factory function that modifies a transactions locktime
|
||||||
*
|
|
||||||
* @param oldTx
|
* @param oldTx
|
||||||
* @param lockTime
|
* @param lockTime
|
||||||
* @return
|
* @return
|
||||||
|
@ -63,14 +62,12 @@ object Transaction extends Factory[Transaction] {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes the inputs of the transactions
|
* Removes the inputs of the transactions
|
||||||
*
|
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
def emptyInputs(oldTx : Transaction) : Transaction = TransactionImpl(oldTx.version,Seq(),oldTx.outputs,oldTx.lockTime)
|
def emptyInputs(oldTx : Transaction) : Transaction = TransactionImpl(oldTx.version,Seq(),oldTx.outputs,oldTx.lockTime)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes the outputs of the transactions
|
* Removes the outputs of the transactions
|
||||||
*
|
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
def emptyOutputs(oldTx : Transaction) : Transaction = TransactionImpl(oldTx.version,oldTx.inputs,Seq(),oldTx.lockTime)
|
def emptyOutputs(oldTx : Transaction) : Transaction = TransactionImpl(oldTx.version,oldTx.inputs,Seq(),oldTx.lockTime)
|
||||||
|
@ -86,4 +83,8 @@ object Transaction extends Factory[Transaction] {
|
||||||
def apply(oldTx : Transaction, updatedInputs : UpdateTransactionInputs) : Transaction = factory(oldTx, updatedInputs)
|
def apply(oldTx : Transaction, updatedInputs : UpdateTransactionInputs) : Transaction = factory(oldTx, updatedInputs)
|
||||||
def apply(oldTx : Transaction, updatedOutputs : UpdateTransactionOutputs) : Transaction = factory(oldTx, updatedOutputs)
|
def apply(oldTx : Transaction, updatedOutputs : UpdateTransactionOutputs) : Transaction = factory(oldTx, updatedOutputs)
|
||||||
|
|
||||||
|
def apply(version : Int, inputs : Seq[TransactionInput],
|
||||||
|
outputs : Seq[TransactionOutput], lockTime : Long) : Transaction = {
|
||||||
|
TransactionImpl(version,inputs,outputs,lockTime)
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,9 +1,18 @@
|
||||||
package org.bitcoins.protocol.transaction
|
package org.bitcoins.protocol.transaction
|
||||||
|
|
||||||
import org.bitcoins.marshallers.transaction.RawTransactionParser
|
import org.bitcoins.marshallers.transaction.RawTransactionParser
|
||||||
import org.bitcoins.util.TestUtil
|
import org.bitcoins.protocol.script.ScriptPubKey
|
||||||
|
import org.bitcoins.protocol.transaction.testprotocol.CoreTransactionTestCase
|
||||||
|
import org.bitcoins.script.ScriptProgram
|
||||||
|
import org.bitcoins.script.flag.ScriptFlagFactory
|
||||||
|
|
||||||
|
import org.bitcoins.protocol.transaction.testprotocol.CoreTransactionTestCaseProtocol._
|
||||||
|
import org.bitcoins.util.{TestUtil, TransactionTestUtil}
|
||||||
import org.scalatest.{FlatSpec, MustMatchers}
|
import org.scalatest.{FlatSpec, MustMatchers}
|
||||||
|
|
||||||
|
import scala.io.Source
|
||||||
|
import spray.json._
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by chris on 7/14/15.
|
* Created by chris on 7/14/15.
|
||||||
*/
|
*/
|
||||||
|
@ -31,4 +40,44 @@ class TransactionTest extends FlatSpec with MustMatchers {
|
||||||
//size is in bytes so divide by 2
|
//size is in bytes so divide by 2
|
||||||
tx.size must be (rawTx.size / 2)
|
tx.size must be (rawTx.size / 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
it must "read all of the tx_valid.json's contents and return ScriptOk" in {
|
||||||
|
|
||||||
|
|
||||||
|
val source = Source.fromURL(getClass.getResource("/tx_valid.json"))
|
||||||
|
|
||||||
|
|
||||||
|
/* //use this to represent a single test case from script_valid.json
|
||||||
|
val lines =
|
||||||
|
"""
|
||||||
|
|
|
||||||
|
|[["4294967296", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY", "UNSATISFIED_LOCKTIME",
|
||||||
|
"CSV fails if stack top bit 1 << 31 is not set, and tx version < 2"]]
|
||||||
|
""".stripMargin*/
|
||||||
|
val lines = try source.getLines.filterNot(_.isEmpty).map(_.trim) mkString "\n" finally source.close()
|
||||||
|
val json = lines.parseJson
|
||||||
|
val testCasesOpt : Seq[Option[CoreTransactionTestCase]] = json.convertTo[Seq[Option[CoreTransactionTestCase]]]
|
||||||
|
val testCases : Seq[CoreTransactionTestCase] = testCasesOpt.flatten
|
||||||
|
|
||||||
|
println(testCases)
|
||||||
|
/* for {
|
||||||
|
testCase <- testCases
|
||||||
|
(creditingTx,outputIndex) = TransactionTestUtil.buildCreditingTransaction(testCase.scriptPubKey.scriptPubKey)
|
||||||
|
(tx,inputIndex) = TransactionTestUtil.buildSpendingTransaction(creditingTx,testCase.scriptSig.scriptSignature,outputIndex)
|
||||||
|
} yield {
|
||||||
|
require(testCase.scriptPubKey.asm == testCase.scriptPubKey.scriptPubKey.asm)
|
||||||
|
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)
|
||||||
|
val scriptPubKey = ScriptPubKey.fromAsm(testCase.scriptPubKey.asm)
|
||||||
|
val flags = ScriptFlagFactory.fromList(testCase.flags)
|
||||||
|
logger.info("Flags after parsing: " + flags)
|
||||||
|
val program = ScriptProgram(tx,scriptPubKey,inputIndex,flags)
|
||||||
|
withClue(testCase.raw) {
|
||||||
|
ScriptInterpreter.run(program) must equal (testCase.expectedResult)
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
package org.bitcoins.protocol.transaction.testprotocol
|
||||||
|
|
||||||
|
import org.bitcoins.protocol.script.ScriptPubKey
|
||||||
|
import org.bitcoins.protocol.transaction.{Transaction, TransactionOutPoint}
|
||||||
|
import org.bitcoins.script.flag.ScriptFlag
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by chris on 5/4/16.
|
||||||
|
* Used to represent the test cases found inside of tx_valid.json & tx_invalid.json
|
||||||
|
* from bitcoin core
|
||||||
|
*/
|
||||||
|
trait CoreTransactionTestCase {
|
||||||
|
|
||||||
|
|
||||||
|
def outPoints : Seq[TransactionOutPoint] = creditingTxsInfo.map(_._1)
|
||||||
|
|
||||||
|
def scriptPubKeys : Seq[ScriptPubKey] = creditingTxsInfo.map(_._2)
|
||||||
|
|
||||||
|
def creditingTxsInfo : Seq[(TransactionOutPoint, ScriptPubKey)]
|
||||||
|
def spendingTx : Transaction
|
||||||
|
|
||||||
|
def flags : Seq[ScriptFlag]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
case class CoreTransactionTestCaseImpl(creditingTxsInfo : Seq[(TransactionOutPoint,ScriptPubKey)],
|
||||||
|
spendingTx : Transaction, flags : Seq[ScriptFlag]) extends CoreTransactionTestCase
|
|
@ -17,6 +17,7 @@ import org.bitcoins.util.{BitcoinSLogger, TestUtil, TransactionTestUtil}
|
||||||
import org.scalatest.{FlatSpec, MustMatchers}
|
import org.scalatest.{FlatSpec, MustMatchers}
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import CoreTestCaseProtocol._
|
import CoreTestCaseProtocol._
|
||||||
|
import org.bitcoins.protocol.transaction.testprotocol.CoreTransactionTestCase
|
||||||
import spray.json._
|
import spray.json._
|
||||||
|
|
||||||
import scala.io.Source
|
import scala.io.Source
|
||||||
|
|
|
@ -55,7 +55,7 @@ trait TransactionTestUtil extends BitcoinSLogger {
|
||||||
val input = TransactionInput(outpoint,scriptSignature,TransactionConstants.sequence)
|
val input = TransactionInput(outpoint,scriptSignature,TransactionConstants.sequence)
|
||||||
val output = TransactionOutput(CurrencyUnits.zeroSatoshis,scriptPubKey)
|
val output = TransactionOutput(CurrencyUnits.zeroSatoshis,scriptPubKey)
|
||||||
|
|
||||||
val tx = TransactionImpl(TransactionConstants.version,Seq(input),Seq(output),TransactionConstants.lockTime)
|
val tx = Transaction(TransactionConstants.version,Seq(input),Seq(output),TransactionConstants.lockTime)
|
||||||
(tx,0)
|
(tx,0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ trait TransactionTestUtil extends BitcoinSLogger {
|
||||||
val outpoint = TransactionOutPoint(creditingTx.txId,outputIndex)
|
val outpoint = TransactionOutPoint(creditingTx.txId,outputIndex)
|
||||||
val input = TransactionInput(outpoint,scriptSignature,TransactionConstants.sequence)
|
val input = TransactionInput(outpoint,scriptSignature,TransactionConstants.sequence)
|
||||||
val output = TransactionOutput(CurrencyUnits.zeroSatoshis,EmptyScriptPubKey)
|
val output = TransactionOutput(CurrencyUnits.zeroSatoshis,EmptyScriptPubKey)
|
||||||
val tx = TransactionImpl(TransactionConstants.version,Seq(input),Seq(output),TransactionConstants.lockTime)
|
val tx = Transaction(TransactionConstants.version,Seq(input),Seq(output),TransactionConstants.lockTime)
|
||||||
/* val expectedHex = "01000000019ce5586f04dd407719ab7e2ed3583583b9022f29652702cfac5ed082013461fe000000004847304402200a5c6163f07b8d3b013c4d1d6dba25e780b39658d79ba37af7057a3b7f15ffa102201fd9b4eaa9943f734928b99a83592c2e7bf342ea2680f6a2bb705167966b742001ffffffff0100000000000000000000000000"
|
/* val expectedHex = "01000000019ce5586f04dd407719ab7e2ed3583583b9022f29652702cfac5ed082013461fe000000004847304402200a5c6163f07b8d3b013c4d1d6dba25e780b39658d79ba37af7057a3b7f15ffa102201fd9b4eaa9943f734928b99a83592c2e7bf342ea2680f6a2bb705167966b742001ffffffff0100000000000000000000000000"
|
||||||
require(tx.hex == expectedHex,"\nExpected hex: " + expectedHex + "\nActual hex: " + tx.hex)*/
|
require(tx.hex == expectedHex,"\nExpected hex: " + expectedHex + "\nActual hex: " + tx.hex)*/
|
||||||
(tx,0)
|
(tx,0)
|
||||||
|
|
Loading…
Add table
Reference in a new issue