mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2025-02-23 06:45:21 +01:00
Fixing merge conflicts
This commit is contained in:
commit
2b88e270db
9 changed files with 93 additions and 58 deletions
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -51,14 +51,17 @@ 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
|
||||
|
|
|
@ -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,21 +161,22 @@ 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)
|
||||
|
||||
private def parseLong(bytes : List[Byte]) : Long = parseLong(ScalacoinUtil.encodeHex(bytes))
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Reference in a new issue