Adding test case for tx_invalid.json, fixing bug with parsign -1 satoshis in our RawTransactionOutputParser

This commit is contained in:
Chris Stewart 2016-05-13 08:50:08 -05:00
parent 574f593dcb
commit 811d15af81
2 changed files with 56 additions and 3 deletions

View file

@ -25,7 +25,7 @@ trait RawTransactionOutputParser extends RawBitcoinSerializer[Seq[TransactionOut
//then call that function multiple times to get a Seq[TransactionOutput]
val satoshisHex = BitcoinSUtil.encodeHex(bytes.take(8).reverse)
logger.debug("Satoshi hex: " + satoshisHex)
val satoshis = Satoshis(java.lang.Long.parseLong(satoshisHex, 16))
val satoshis = parseSatoshis(satoshisHex)
//it doesn't include itself towards the size, thats why it is incremented by one
val firstScriptPubKeyByte = 8
val scriptCompactSizeUIntSize : Int = BitcoinSUtil.parseCompactSizeUIntSize(bytes(firstScriptPubKeyByte)).toInt
@ -72,6 +72,18 @@ trait RawTransactionOutputParser extends RawBitcoinSerializer[Seq[TransactionOut
if (compactSizeUIntHex == "00") satoshisHex + compactSizeUIntHex
else satoshisHex + compactSizeUIntHex + output.scriptPubKey.hex
}
/**
* Parses the amount of satoshis a hex string represetns
* @param hex the hex string that is being parsed to satoshis
* @return the value of the hex string in satoshis
*/
private def parseSatoshis(hex : String) : Satoshis = {
if (hex == "ffffffffffffffff") {
//this represents a negative satoshis
CurrencyUnits.negativeSatoshi
} else Satoshis(java.lang.Long.parseLong(hex, 16))
}
}

View file

@ -7,7 +7,7 @@ import org.bitcoins.script.ScriptProgram
import org.bitcoins.script.flag.ScriptFlagFactory
import org.bitcoins.protocol.transaction.testprotocol.CoreTransactionTestCaseProtocol._
import org.bitcoins.script.interpreter.ScriptInterpreter
import org.bitcoins.script.result.ScriptOk
import org.bitcoins.script.result.{ScriptError, ScriptOk}
import org.bitcoins.util.{BitcoinSLogger, TestUtil, TransactionTestUtil}
import org.scalatest.{FlatSpec, MustMatchers}
@ -56,7 +56,7 @@ class TransactionTest extends FlatSpec with MustMatchers with BitcoinSLogger {
|"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffff00000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"]
|]
""".stripMargin*/
val lines = try source.getLines.filterNot(_.isEmpty).map(_.trim) mkString "\n" finally source.close()
/* 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
@ -79,6 +79,47 @@ class TransactionTest extends FlatSpec with MustMatchers with BitcoinSLogger {
withClue(testCase.raw) {
ScriptInterpreter.run(program) must equal (ScriptOk)
}
}*/
}
it must "read all of the tx_invalid.json's contents and return a ScriptError" in {
val source = Source.fromURL(getClass.getResource("/tx_invalid.json"))
//use this to represent a single test case from script_valid.json
/* val lines =
"""
|[
|[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "DUP HASH160 0x14 0x5b6462475454710f3c22f5fdf0b40704c92f25c3 EQUALVERIFY CHECKSIGVERIFY 1 0x4c 0x47 0x3044022067288ea50aa799543a536ff9306f8e1cba05b9c6b10951175b924f96732555ed022026d7b5265f38d21541519e4a1e55044d5b9e17e15cdbaf29ae3792e99e883e7a01"]],
|"01000000010001000000000000000000000000000000000000000000000000000000000000000000006a473044022067288ea50aa799543a536ff9306f8e1cba05b9c6b10951175b924f96732555ed022026d7b5265f38d21541519e4a1e55044d5b9e17e15cdbaf29ae3792e99e883e7a012103ba8c8b86dea131c22ab967e6dd99bdae8eff7a1f75a2c35f1f944109e3fe5e22ffffffff010000000000000000015100000000", "P2SH"]
|
|]
""".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
for {
testCase <- testCases
(outPoint,scriptPubKey) <- testCase.creditingTxsInfo
tx = testCase.spendingTx
(input,inputIndex) = findInput(tx,outPoint)
} yield {
logger.info("Raw test case: " + testCase.raw)
logger.info("Parsed ScriptSig: " + tx.inputs(inputIndex).scriptSignature)
logger.info("Sequence number: " + tx.inputs(inputIndex).sequence)
logger.info("ScriptPubKey: " + scriptPubKey)
logger.info("OutPoint: " + outPoint)
logger.info("Flags after parsing: " + testCase.flags)
require(outPoint.txId == input.previousOutput.txId,
"OutPoint txId not the same as input prevout txid\noutPoint.txId: " + outPoint.txId + "\n" +
"input prevout txid: " + input.previousOutput.txId)
val program = ScriptProgram(tx,scriptPubKey,inputIndex,testCase.flags)
withClue(testCase.raw) {
ScriptInterpreter.run(program).isInstanceOf[ScriptError] must equal (true)
}
}
}