Fixing merge conflicts

This commit is contained in:
Chris Stewart 2016-02-23 14:15:05 -06:00
commit 2b88e270db
9 changed files with 93 additions and 58 deletions

View file

@ -2,7 +2,7 @@ package org.scalacoin.marshallers.transaction
import org.scalacoin.marshallers.RawBitcoinSerializer
import org.scalacoin.marshallers.script.RawScriptSignatureParser
import org.scalacoin.protocol.{VarIntImpl, VarInt}
import org.scalacoin.protocol.{CompactSizeUInt}
import org.scalacoin.protocol.script.ScriptSignature
import org.scalacoin.protocol.transaction.{TransactionInputImpl, TransactionOutPoint, TransactionInput}
import org.scalacoin.util.ScalacoinUtil
@ -24,28 +24,31 @@ trait RawTransactionInputParser extends RawBitcoinSerializer[Seq[TransactionInpu
@tailrec
def loop(bytes : List[Byte], accum : List[TransactionInput], inputsLeftToParse : Int) : Seq[TransactionInput] = {
if (inputsLeftToParse > 0) {
//TODO: This needs to be refactored into a loop function that returns a single TransactionInput
//then call it multiple times and create a Seq[TransactionInput
logger.debug("Bytes to parse for input: " + ScalacoinUtil.encodeHex(bytes))
val outPointBytesSize = 36
val outPointBytes = bytes.take(outPointBytesSize)
val outPoint : TransactionOutPoint = RawTransactionOutPointParser.read(outPointBytes)
val scriptVarIntSize : Int = ScalacoinUtil.parseVarIntSize(bytes(outPointBytesSize)).toInt
logger.debug("VarInt hex: " + ScalacoinUtil.encodeHex(bytes.slice(outPointBytesSize,outPointBytesSize + scriptVarIntSize)))
val scriptSigVarInt : VarInt = ScalacoinUtil.parseVarInt(bytes.slice(outPointBytesSize,outPointBytesSize + scriptVarIntSize))
val scriptCompactSizeUIntSize : Int = ScalacoinUtil.parseCompactSizeUIntSize(bytes(outPointBytesSize)).toInt
logger.debug("VarInt hex: " + ScalacoinUtil.encodeHex(bytes.slice(outPointBytesSize,outPointBytesSize + scriptCompactSizeUIntSize)))
val scriptSigCompactSizeUInt : CompactSizeUInt = ScalacoinUtil.parseCompactSizeUInt(bytes.slice(outPointBytesSize,outPointBytesSize + scriptCompactSizeUIntSize))
val scriptSigBytes = bytes.slice(outPointBytesSize + scriptVarIntSize,
outPointBytesSize + scriptVarIntSize + scriptSigVarInt.num.toInt)
val scriptSigBytes = bytes.slice(outPointBytesSize+ scriptCompactSizeUIntSize,
outPointBytesSize + scriptCompactSizeUIntSize + scriptSigCompactSizeUInt.num.toInt)
val scriptSig : ScriptSignature = RawScriptSignatureParser.read(scriptSigBytes)
val sequenceBytesSize = 4
val endOfScriptSigBytes = outPointBytesSize + scriptSigVarInt.num.toInt + scriptVarIntSize
val endOfScriptSigBytes = outPointBytesSize + scriptSigCompactSizeUInt.num.toInt + scriptCompactSizeUIntSize
val lastInputByte = endOfScriptSigBytes + sequenceBytesSize
val sequenceBytes = bytes.slice(endOfScriptSigBytes,lastInputByte)
logger.debug("Sequence bytes: " + ScalacoinUtil.encodeHex(sequenceBytes))
val sequenceNumberHex : String = ScalacoinUtil.encodeHex(sequenceBytes)
val sequenceNumber : Long = java.lang.Long.parseLong(sequenceNumberHex,16)
val txInput = TransactionInputImpl(outPoint,scriptSigVarInt, scriptSig,sequenceNumber)
val txInput = TransactionInputImpl(outPoint,/*scriptSigCompactSizeUInt,*/ scriptSig,sequenceNumber)
val newAccum = txInput :: accum
val bytesToBeParsed = bytes.slice(lastInputByte, bytes.size)
@ -77,7 +80,7 @@ trait RawTransactionInputParser extends RawBitcoinSerializer[Seq[TransactionInpu
*/
def write(input : TransactionInput) : String = {
val outPoint = RawTransactionOutPointParser.write(input.previousOutput)
val varInt = input.scriptSigVarInt.hex
val varInt = input.scriptSigCompactSizeUInt.hex
val scriptSig = RawScriptSignatureParser.write(input.scriptSignature)
val sequenceWithoutPadding = input.sequence.toHexString
val paddingNeeded = 8 - sequenceWithoutPadding.size

View file

@ -21,6 +21,8 @@ trait RawTransactionOutputParser extends RawBitcoinSerializer[Seq[TransactionOut
@tailrec
def loop(bytes : List[Byte], accum : List[TransactionOutput], outputsLeftToParse : Int) : List[TransactionOutput] = {
if (outputsLeftToParse > 0) {
//TODO: this needs to be refactored to, need to create a function that returns a single TransactionOutput
//then call that function multiple times to get a Seq[TransactionOutput]
val satoshisHex = ScalacoinUtil.encodeHex(bytes.take(8).reverse)
logger.debug("Satoshi hex: " + satoshisHex)
val satoshis = Satoshis(java.lang.Long.parseLong(satoshisHex, 16))

View file

@ -7,7 +7,7 @@ import org.scalacoin.util.ScalacoinUtil
*/
trait VarInt {
trait CompactSizeUInt {
/**
* The number parsed from VarInt
@ -31,7 +31,7 @@ trait VarInt {
}
case class VarIntImpl(num : Long, size : Long) extends VarInt
case class CompactSizeUIntImpl(num : Long, size : Long) extends CompactSizeUInt

View file

@ -1,8 +1,9 @@
package org.scalacoin.protocol.transaction
import org.scalacoin.marshallers.transaction.{RawTransactionInputParser, TransactionElement}
import org.scalacoin.protocol.VarInt
import org.scalacoin.protocol.script.{ScriptSignatureFactory, ScriptSignature}
import org.scalacoin.protocol.{CompactSizeUInt}
import org.scalacoin.protocol.script.ScriptSignature
import org.scalacoin.util.ScalacoinUtil
/**
@ -14,9 +15,11 @@ trait TransactionInput extends TransactionElement with TransactionInputFactory {
def scriptSignature : ScriptSignature
def sequence : Long
def scriptSigVarInt : VarInt //= ScalacoinUtil.parseVarInt(scriptSignature)
def scriptSigCompactSizeUInt : CompactSizeUInt = ScalacoinUtil.parseCompactSizeUInt(scriptSignature)
//https://bitcoin.org/en/developer-reference#txin
override def size = previousOutput.size + scriptSignature.size + scriptSigVarInt.size.toInt + 4
override def size = previousOutput.size + scriptSignature.size +
scriptSigCompactSizeUInt.size.toInt + 4
def hex = RawTransactionInputParser.write(Seq(this))
}
@ -25,7 +28,8 @@ object TransactionInput extends TransactionInput {
override def previousOutput = empty.previousOutput
override def scriptSignature = empty.scriptSignature
override def sequence = empty.sequence
override def scriptSigVarInt = empty.scriptSigVarInt
override def scriptSigCompactSizeUInt = empty.scriptSigCompactSizeUInt
}
case class TransactionInputImpl(previousOutput : TransactionOutPoint, scriptSigVarInt : VarInt,
case class TransactionInputImpl(previousOutput : TransactionOutPoint,
scriptSignature : ScriptSignature, sequence : Long) extends TransactionInput

View file

@ -2,9 +2,11 @@ package org.scalacoin.protocol.transaction
import org.scalacoin.currency.{CurrencyUnits, CurrencyUnit, Satoshis}
import org.scalacoin.marshallers.transaction.{RawTransactionOutputParser, TransactionElement}
import org.scalacoin.protocol.VarInt
import org.scalacoin.protocol.script.{ScriptPubKeyFactory, ScriptPubKey}
/**
* Created by chris on 12/26/15.
*/

View file

@ -51,15 +51,18 @@ trait BinaryTree[+T] {
* @return
*/
def findFirstDFS[T](t : T)(f : T => Boolean = (x : T) => x == t)(implicit tree : BinaryTree[T] = this) : Option[BinaryTree[T]] = {
//TODO: Optimize this to be tail recursive
if (tree.value.isDefined && f(tree.value.get)) Some(tree)
else {
val leftTreeResult : Option[BinaryTree[T]] = if (tree.left.isDefined) findFirstDFS(t)(f)(tree.left.get) else None
if (leftTreeResult.isDefined) leftTreeResult
else if (tree.right.isDefined) findFirstDFS(t)(f)(tree.right.get)
else None
@tailrec
def loop(subTree : BinaryTree[T], remainder : List[BinaryTree[T]]) : Option[BinaryTree[T]] = {
subTree match {
case Empty => if (remainder.isEmpty) None else loop(remainder.head, remainder.tail)
case Leaf(x) => if (f(x)) Some(Leaf(x)) else if (remainder.isEmpty) None else loop(remainder.head, remainder.tail)
case Node(v, l, r) =>
if (f(v)) Some(Node(v,l,r))
else loop(l, r :: remainder)
}
}
loop(tree,List())
}
/**
@ -107,6 +110,7 @@ trait BinaryTree[+T] {
}
/**
* Removes the subTree from the parentTree
* @param subTree - the tree to be removed
@ -147,14 +151,14 @@ trait BinaryTree[+T] {
def toSeq : Seq[T] = {
//TODO: Optimize this into a tailrec function
//@tailrec
def loop(tree : BinaryTree[T],accum : List[T]) : List[T] = tree match {
case Leaf(x) => accum ++ List(x)
case Empty => accum
case Node(v,l,r) => loop(r,loop(l,accum ++ List(v)))
@tailrec
def loop(tree : BinaryTree[T], accum : List[T], remainder : List[BinaryTree[T]]) : List[T] = tree match {
case Leaf(x) => if (remainder.isEmpty) accum ++ List(x) else loop(remainder.head,accum ++ List(x),remainder.tail)
case Empty => if (remainder.isEmpty) accum else loop(remainder.head, accum, remainder.tail)
case Node(v,l,r) =>
loop(l,accum ++ List(v), r :: remainder)
}
loop(this,List())
loop(this,List(),List())
}
def toList : List[T] = toSeq.toList

View file

@ -1,7 +1,7 @@
package org.scalacoin.util
import org.scalacoin.protocol.script.ScriptSignature
import org.scalacoin.protocol.{VarIntImpl, VarInt}
import org.scalacoin.protocol.{CompactSizeUInt, CompactSizeUIntImpl}
import org.slf4j.LoggerFactory
/**
@ -12,8 +12,21 @@ trait NumberUtil {
private def logger = LoggerFactory.getLogger(this.getClass())
/**
* Takes a hex number and converts it into a signed number
* used in the bitcoin numbering system
* @param hex
* @return
*/
def toLong(hex : String) : Long = toLong(ScalacoinUtil.decodeHex(hex))
/**
* Takes a list of bytes and converts it in to signed number inside of bitcoins
* numbering system
* @param bytes
* @return
*/
def toLong(bytes : List[Byte]) : Long = {
logger.debug("bytes: " + bytes)
val reversedBytes = bytes.reverse
@ -33,6 +46,11 @@ trait NumberUtil {
}
/**
* Converts a long number to a signed number hex representation
* @param long
* @return
*/
def longToHex(long : Long) : String = {
if (long > -1) {
val bytes = toByteList(long)
@ -97,30 +115,31 @@ trait NumberUtil {
def toByteList(long : Long) = BigInt(long).toByteArray.toList
/**
* Parses a VarInt from a string of hex characters
* https://en.bitcoin.it/wiki/Protocol_documentation#Variable_length_integer
* https://bitcoin.org/en/developer-reference#compactsize-unsigned-integers
* @param hex
* @return
*/
def parseVarInt(hex : String) : VarInt = parseVarInt(ScalacoinUtil.decodeHex(hex))
def parseCompactSizeUInt(hex : String) : CompactSizeUInt = parseCompactSizeUInt(ScalacoinUtil.decodeHex(hex))
/**
* Parses a VarInt from a sequence of bytes
* https://en.bitcoin.it/wiki/Protocol_documentation#Variable_length_integer
* Parses a CompactSizeUInt from a sequence of bytes
* https://bitcoin.org/en/developer-reference#compactsize-unsigned-integers
* @param bytes
* @return
*/
def parseVarInt(bytes : Seq[Byte]) : VarInt = {
def parseCompactSizeUInt(bytes : Seq[Byte]) : CompactSizeUInt = {
require(bytes.size > 0, "Cannot parse a VarInt if the byte array is size 0")
//8 bit number
if (parseLong(bytes.head) < 253) VarIntImpl(parseLong(bytes.head),1)
if (parseLong(bytes.head) < 253) CompactSizeUIntImpl(parseLong(bytes.head),1)
//16 bit number
else if (parseLong(bytes.head) == 253) VarIntImpl(parseLong(bytes.slice(1,3).reverse),3)
else if (parseLong(bytes.head) == 253) CompactSizeUIntImpl(parseLong(bytes.slice(1,3).reverse),3)
//32 bit number
else if (parseLong(bytes.head) == 254) VarIntImpl(parseLong(bytes.slice(1,5).reverse),5)
else if (parseLong(bytes.head) == 254) CompactSizeUIntImpl(parseLong(bytes.slice(1,5).reverse),5)
//64 bit number
else VarIntImpl(parseLong(bytes.slice(1,9).reverse),9)
else CompactSizeUIntImpl(parseLong(bytes.slice(1,9).reverse),9)
}
/**
@ -129,7 +148,7 @@ trait NumberUtil {
* @param byte
* @return
*/
def parseVarIntSize(byte : Byte) : Long = {
def parseCompactSizeUIntSize(byte : Byte) : Long = {
//8 bit number
if (parseLong(byte) < 253) 1
//16 bit number
@ -142,20 +161,21 @@ trait NumberUtil {
/**
* Parses a VarInt from a sequence of bytes
* https://en.bitcoin.it/wiki/Protocol_documentation#Variable_length_integer
* @param bytes
* Parses the compact size uint from a script signature
* https://bitcoin.org/en/developer-reference#compactsize-unsigned-integers
* @param script
* @return
*/
def parseVarInt(scriptSig : ScriptSignature) : VarInt = {
//largest 8 uint
val size = scriptSig.size
if (size < 255) VarIntImpl(size,1)
else if (size < 65536) VarIntImpl(size,3)
else if (size < 4294967296L) VarIntImpl(size,5)
else VarIntImpl(size,9)
def parseCompactSizeUInt(script : ScriptSignature) : CompactSizeUInt = {
if (script.bytes.size <=252 ) {
CompactSizeUIntImpl(script.bytes.size,1)
} else if (script.bytes.size <= 0xffff) {
CompactSizeUIntImpl(script.bytes.size,3)
} else if (script.bytes.size <= 0xffffffff) {
CompactSizeUIntImpl(script.bytes.size,5)
}
else CompactSizeUIntImpl(script.bytes.size,9)
}
private def parseLong(hex : String) : Long = java.lang.Long.parseLong(hex,16)

View file

@ -100,7 +100,7 @@ class RawTransactionInputParserTest extends FlatSpec with MustMatchers with RawT
txInput.head.previousOutput.txId must be ("e99eb3e6551844d0db252ef242c043796b3b0ccfb126c0ae09f9dd0230e2f10d")
txInput.head.previousOutput.vout must be (0)
txInput.head.scriptSignature.hex must be ("004730440220028c02f14654a0cc12c7e3229adb09d5d35bebb6ba1057e39adb1b2706607b0d0220564fab12c6da3d5acef332406027a7ff1cbba980175ffd880e1ba1bf40598f6b014830450221009362f8d67b60773745e983d07ba10efbe566127e244b724385b2ca2e47292dda022033def393954c320653843555ddbe7679b35cc1cacfe1dad923977de8cd6cc6d7014c695221025e9adcc3d65c11346c8a6069d6ebf5b51b348d1d6dc4b95e67480c34dc0bc75c21030585b3c80f4964bf0820086feda57c8e49fa1eab925db7c04c985467973df96521037753a5e3e9c4717d3f81706b38a6fb82b5fb89d29e580d7b98a37fea8cdefcad53ae")
txInput.head.scriptSigVarInt.num must be (txInput.head.scriptSignature.size)
txInput.head.scriptSigCompactSizeUInt.num must be (txInput.head.scriptSignature.size)
txInput.head.sequence must be (4294967295L)
RawTransactionInputParser.write(txInput) must be (rawTxInput)

View file

@ -1,7 +1,7 @@
package org.scalacoin.util
import org.scalacoin.currency.CurrencyUnits
import org.scalacoin.protocol.VarIntImpl
import org.scalacoin.protocol.{CompactSizeUIntImpl}
import org.scalacoin.protocol.script.{ScriptSignatureImpl, ScriptPubKey, ScriptPubKeyImpl, ScriptSignature}
import org.scalacoin.protocol.transaction._
import org.scalacoin.script.constant.{OP_0, ScriptToken}
@ -20,7 +20,7 @@ trait TransactionTestUtil {
def buildSpendingTransaction(scriptSignature : ScriptSignature, tx : Transaction) : Transaction = {
val outpoint = TransactionOutPointImpl(tx.txId,0)
val input = TransactionInputImpl(outpoint,VarIntImpl(0,0),scriptSignature,0xFFFFFFFF)
val input = TransactionInputImpl(outpoint,scriptSignature,0xFFFFFFFF)
//empty script pubkey
val scriptPubKey = ScriptPubKeyImpl(Seq(),"",Seq())
val output = TransactionOutputImpl(CurrencyUnits.oneSatoshi,0,scriptPubKey)
@ -38,7 +38,7 @@ trait TransactionTestUtil {
val outpoint = TransactionOutPointImpl("",0)
val scriptSignature = ScriptSignatureImpl(Seq(OP_0,OP_0),"0000")
val input = TransactionInputImpl(outpoint,VarIntImpl(0,0),scriptSignature,0xFFFFFFFF)
val input = TransactionInputImpl(outpoint,scriptSignature,0xFFFFFFFF)
val output = TransactionOutputImpl(CurrencyUnits.oneSatoshi,0,scriptPubKey)
TransactionImpl(TransactionConstants.version,Seq(input),Seq(output),TransactionConstants.lockTime)