mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2024-11-19 09:52:09 +01:00
Seq and Map Wrappers (#1131)
* Renamed size to byteSize in NetworkElement to avoid ambiguity * Introduced SeqWrapper and MapWrapper to allow for wrapper case classes to have direct access to underlying methods * Responded to review
This commit is contained in:
parent
03cfbc0803
commit
052b64b7e2
@ -60,7 +60,7 @@ class RawTransactionRpcTest extends BitcoindRpcTest {
|
|||||||
} yield {
|
} yield {
|
||||||
assert(rpcTransaction.txid == transaction.txIdBE)
|
assert(rpcTransaction.txid == transaction.txIdBE)
|
||||||
assert(rpcTransaction.locktime == transaction.lockTime)
|
assert(rpcTransaction.locktime == transaction.lockTime)
|
||||||
assert(rpcTransaction.size == transaction.size)
|
assert(rpcTransaction.size == transaction.byteSize)
|
||||||
assert(rpcTransaction.version == transaction.version.toInt)
|
assert(rpcTransaction.version == transaction.version.toInt)
|
||||||
assert(rpcTransaction.vsize == transaction.vsize)
|
assert(rpcTransaction.vsize == transaction.vsize)
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ import org.bitcoins.core.protocol.BitcoinAddress
|
|||||||
import org.bitcoins.core.protocol.blockchain.BlockHeader
|
import org.bitcoins.core.protocol.blockchain.BlockHeader
|
||||||
import org.bitcoins.core.protocol.script.ScriptPubKey
|
import org.bitcoins.core.protocol.script.ScriptPubKey
|
||||||
import org.bitcoins.core.protocol.transaction.Transaction
|
import org.bitcoins.core.protocol.transaction.Transaction
|
||||||
|
import org.bitcoins.core.util.SeqWrapper
|
||||||
import org.bitcoins.core.wallet.fee.BitcoinFeeUnit
|
import org.bitcoins.core.wallet.fee.BitcoinFeeUnit
|
||||||
import play.api.libs.json.JsObject
|
import play.api.libs.json.JsObject
|
||||||
|
|
||||||
@ -161,6 +162,9 @@ case class TestMempoolAcceptResult(
|
|||||||
|
|
||||||
final case class DeriveAddressesResult(addresses: Vector[BitcoinAddress])
|
final case class DeriveAddressesResult(addresses: Vector[BitcoinAddress])
|
||||||
extends OtherResult
|
extends OtherResult
|
||||||
|
with SeqWrapper[BitcoinAddress] {
|
||||||
|
override protected val wrapped: Vector[BitcoinAddress] = addresses
|
||||||
|
}
|
||||||
|
|
||||||
final case class GetDescriptorInfoResult(
|
final case class GetDescriptorInfoResult(
|
||||||
descriptor: String,
|
descriptor: String,
|
||||||
|
@ -2,12 +2,11 @@ package org.bitcoins.chain.blockchain
|
|||||||
|
|
||||||
import org.bitcoins.chain.models.BlockHeaderDb
|
import org.bitcoins.chain.models.BlockHeaderDb
|
||||||
|
|
||||||
import scala.collection.{mutable, IndexedSeqLike}
|
import scala.collection.mutable
|
||||||
|
|
||||||
/** @inheritdoc */
|
/** @inheritdoc */
|
||||||
case class Blockchain(headers: Vector[BlockHeaderDb])
|
case class Blockchain(headers: Vector[BlockHeaderDb])
|
||||||
extends IndexedSeqLike[BlockHeaderDb, Vector[BlockHeaderDb]]
|
extends BaseBlockChain {
|
||||||
with BaseBlockChain {
|
|
||||||
|
|
||||||
protected[blockchain] def compObjectfromHeaders(
|
protected[blockchain] def compObjectfromHeaders(
|
||||||
headers: scala.collection.immutable.Seq[BlockHeaderDb]): Blockchain =
|
headers: scala.collection.immutable.Seq[BlockHeaderDb]): Blockchain =
|
||||||
|
@ -2,20 +2,13 @@ package org.bitcoins.chain.blockchain
|
|||||||
|
|
||||||
import org.bitcoins.chain.models.BlockHeaderDb
|
import org.bitcoins.chain.models.BlockHeaderDb
|
||||||
|
|
||||||
import scala.collection.immutable.IndexedSeq
|
|
||||||
|
|
||||||
/** @inheritdoc */
|
/** @inheritdoc */
|
||||||
case class Blockchain(headers: Vector[BlockHeaderDb])
|
case class Blockchain(headers: Vector[BlockHeaderDb]) extends BaseBlockChain {
|
||||||
extends IndexedSeq[BlockHeaderDb]
|
|
||||||
with BaseBlockChain {
|
|
||||||
|
|
||||||
protected[blockchain] def compObjectfromHeaders(
|
protected[blockchain] def compObjectfromHeaders(
|
||||||
headers: scala.collection.immutable.Seq[BlockHeaderDb]) =
|
headers: scala.collection.immutable.Seq[BlockHeaderDb]) =
|
||||||
Blockchain.fromHeaders(headers)
|
Blockchain.fromHeaders(headers)
|
||||||
|
|
||||||
/** @inheritdoc */
|
|
||||||
override def seq = this
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
object Blockchain extends BaseBlockChainCompObject {
|
object Blockchain extends BaseBlockChainCompObject {
|
||||||
|
@ -7,6 +7,7 @@ import org.bitcoins.chain.ChainVerificationLogger
|
|||||||
import org.bitcoins.chain.validation.TipUpdateResult
|
import org.bitcoins.chain.validation.TipUpdateResult
|
||||||
import org.bitcoins.chain.validation.TipValidation
|
import org.bitcoins.chain.validation.TipValidation
|
||||||
import org.bitcoins.core.crypto.DoubleSha256DigestBE
|
import org.bitcoins.core.crypto.DoubleSha256DigestBE
|
||||||
|
import org.bitcoins.core.util.SeqWrapper
|
||||||
|
|
||||||
import scala.annotation.tailrec
|
import scala.annotation.tailrec
|
||||||
|
|
||||||
@ -33,7 +34,7 @@ import scala.annotation.tailrec
|
|||||||
* }}}
|
* }}}
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private[blockchain] trait BaseBlockChain {
|
private[blockchain] trait BaseBlockChain extends SeqWrapper[BlockHeaderDb] {
|
||||||
|
|
||||||
protected[blockchain] def compObjectfromHeaders(
|
protected[blockchain] def compObjectfromHeaders(
|
||||||
headers: scala.collection.immutable.Seq[BlockHeaderDb]): Blockchain
|
headers: scala.collection.immutable.Seq[BlockHeaderDb]): Blockchain
|
||||||
@ -43,12 +44,10 @@ private[blockchain] trait BaseBlockChain {
|
|||||||
/** The height of the chain */
|
/** The height of the chain */
|
||||||
val height: Int = tip.height
|
val height: Int = tip.height
|
||||||
|
|
||||||
val length: Int = headers.length
|
|
||||||
|
|
||||||
def apply(idx: Int): BlockHeaderDb = headers(idx)
|
|
||||||
|
|
||||||
def headers: Vector[BlockHeaderDb]
|
def headers: Vector[BlockHeaderDb]
|
||||||
|
|
||||||
|
override protected lazy val wrapped: Vector[BlockHeaderDb] = headers
|
||||||
|
|
||||||
def find(predicate: BlockHeaderDb => Boolean): Option[BlockHeaderDb]
|
def find(predicate: BlockHeaderDb => Boolean): Option[BlockHeaderDb]
|
||||||
|
|
||||||
/** Finds a block header at a given height */
|
/** Finds a block header at a given height */
|
||||||
|
@ -74,8 +74,8 @@ class TransactionTest extends BitcoinSUnitTest {
|
|||||||
val rawTx = TestUtil.rawTransaction
|
val rawTx = TestUtil.rawTransaction
|
||||||
val tx = Transaction(rawTx)
|
val tx = Transaction(rawTx)
|
||||||
//size is in bytes so divide by 2
|
//size is in bytes so divide by 2
|
||||||
assert(tx.size == tx.totalSize)
|
assert(tx.byteSize == tx.totalSize)
|
||||||
tx.size must be(rawTx.size / 2)
|
tx.byteSize must be(rawTx.size / 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
it must "serialize and deserialize a tx" in {
|
it must "serialize and deserialize a tx" in {
|
||||||
@ -132,7 +132,7 @@ class TransactionTest extends BitcoinSUnitTest {
|
|||||||
"0200000000010140d43a99926d43eb0e619bf0b3d83b4a31f60c176beecfb9d35bf45e54d0f7420100000017160014a4b4ca48de0b3fffc15404a1acdc8dbaae226955ffffffff0100e1f5050000000017a9144a1154d50b03292b3024370901711946cb7cccc387024830450221008604ef8f6d8afa892dee0f31259b6ce02dd70c545cfcfed8148179971876c54a022076d771d6e91bed212783c9b06e0de600fab2d518fad6f15a2b191d7fbd262a3e0121039d25ab79f41f75ceaf882411fd41fa670a4c672c23ffaf0e361a969cde0692e800000000"
|
"0200000000010140d43a99926d43eb0e619bf0b3d83b4a31f60c176beecfb9d35bf45e54d0f7420100000017160014a4b4ca48de0b3fffc15404a1acdc8dbaae226955ffffffff0100e1f5050000000017a9144a1154d50b03292b3024370901711946cb7cccc387024830450221008604ef8f6d8afa892dee0f31259b6ce02dd70c545cfcfed8148179971876c54a022076d771d6e91bed212783c9b06e0de600fab2d518fad6f15a2b191d7fbd262a3e0121039d25ab79f41f75ceaf882411fd41fa670a4c672c23ffaf0e361a969cde0692e800000000"
|
||||||
val tx2 = WitnessTransaction(hex2)
|
val tx2 = WitnessTransaction(hex2)
|
||||||
tx2.hex must be(hex2)
|
tx2.hex must be(hex2)
|
||||||
tx2.size must be(216)
|
tx2.byteSize must be(216)
|
||||||
tx2.weight must be(534)
|
tx2.weight must be(534)
|
||||||
tx2.vsize must be(134)
|
tx2.vsize must be(134)
|
||||||
tx2.baseSize must be(106)
|
tx2.baseSize must be(106)
|
||||||
|
@ -32,7 +32,7 @@ class RawTransactionInputParserTest extends FlatSpec with MustMatchers {
|
|||||||
|
|
||||||
it must "find the correct size for an input" in {
|
it must "find the correct size for an input" in {
|
||||||
val txInput: TransactionInput = RawTransactionInputParser.read(rawTxInput)
|
val txInput: TransactionInput = RawTransactionInputParser.read(rawTxInput)
|
||||||
txInput.size must be(BitcoinSUtil.decodeHex(rawTxInput).size)
|
txInput.byteSize must be(BitcoinSUtil.decodeHex(rawTxInput).size)
|
||||||
}
|
}
|
||||||
|
|
||||||
it must "write a single input" in {
|
it must "write a single input" in {
|
||||||
|
@ -62,7 +62,7 @@ class RawTransactionOutPointParserTest extends BitcoinSUnitTest {
|
|||||||
val rawOutPoint =
|
val rawOutPoint =
|
||||||
"85d6b0da2edf96b282030d3f4f79d14cc8c882cfef1b3064170c850660317de100000000"
|
"85d6b0da2edf96b282030d3f4f79d14cc8c882cfef1b3064170c850660317de100000000"
|
||||||
val outPoint = RawTransactionOutPointParser.read(rawOutPoint)
|
val outPoint = RawTransactionOutPointParser.read(rawOutPoint)
|
||||||
outPoint.size must be(36)
|
outPoint.byteSize must be(36)
|
||||||
}
|
}
|
||||||
|
|
||||||
it must "parse a outpoint with extremely large vout" in {
|
it must "parse a outpoint with extremely large vout" in {
|
||||||
|
@ -50,7 +50,7 @@ object BIP39Seed extends Factory[BIP39Seed] {
|
|||||||
password: String = EMPTY_PASSWORD): BIP39Seed = {
|
password: String = EMPTY_PASSWORD): BIP39Seed = {
|
||||||
val salt = s"mnemonic$password"
|
val salt = s"mnemonic$password"
|
||||||
|
|
||||||
val words = mnemonic.words.mkString(" ")
|
val words = mnemonic.mkString(" ")
|
||||||
|
|
||||||
val encodedBytes = PBKDF2
|
val encodedBytes = PBKDF2
|
||||||
.withSha512(words, salt, ITERATION_COUNT, DERIVED_KEY_LENGTH)
|
.withSha512(words, salt, ITERATION_COUNT, DERIVED_KEY_LENGTH)
|
||||||
|
@ -92,7 +92,7 @@ sealed abstract class ExtKey extends NetworkElement {
|
|||||||
case Nil => Success(accum)
|
case Nil => Success(accum)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
loop(path.path.toList, pub)
|
loop(path.toList, pub)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -184,7 +184,7 @@ sealed abstract class ExtPrivateKey
|
|||||||
* specialized version of a BIP32 path
|
* specialized version of a BIP32 path
|
||||||
*/
|
*/
|
||||||
def deriveChildPrivKey(path: BIP32Path): ExtPrivateKey = {
|
def deriveChildPrivKey(path: BIP32Path): ExtPrivateKey = {
|
||||||
path.path.foldLeft(this)((accum: ExtPrivateKey, curr: BIP32Node) =>
|
path.foldLeft(this)((accum: ExtPrivateKey, curr: BIP32Node) =>
|
||||||
accum.deriveChildPrivKey(curr.toUInt32))
|
accum.deriveChildPrivKey(curr.toUInt32))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -326,8 +326,8 @@ object ExtPrivateKey extends Factory[ExtPrivateKey] {
|
|||||||
chaincode,
|
chaincode,
|
||||||
masterPrivKey)
|
masterPrivKey)
|
||||||
|
|
||||||
path.path.foldLeft(root)((accum, curr) =>
|
path.foldLeft(root)(
|
||||||
accum.deriveChildPrivKey(curr.toUInt32))
|
(accum, curr) => accum.deriveChildPrivKey(curr.toUInt32))
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Generates a extended private key from the provided seed and version */
|
/** Generates a extended private key from the provided seed and version */
|
||||||
|
@ -2,7 +2,7 @@ package org.bitcoins.core.crypto
|
|||||||
|
|
||||||
import java.security.SecureRandom
|
import java.security.SecureRandom
|
||||||
|
|
||||||
import org.bitcoins.core.util.{CryptoUtil, MaskedToString}
|
import org.bitcoins.core.util.{CryptoUtil, MaskedToString, SeqWrapper}
|
||||||
import scodec.bits.{BitVector, ByteVector}
|
import scodec.bits.{BitVector, ByteVector}
|
||||||
|
|
||||||
import scala.annotation.tailrec
|
import scala.annotation.tailrec
|
||||||
@ -16,7 +16,9 @@ import scala.io.Source
|
|||||||
* can be the root of a [[https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki BIP32]]
|
* can be the root of a [[https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki BIP32]]
|
||||||
* HD wallet.
|
* HD wallet.
|
||||||
*/
|
*/
|
||||||
sealed abstract class MnemonicCode extends MaskedToString {
|
sealed abstract class MnemonicCode
|
||||||
|
extends SeqWrapper[String]
|
||||||
|
with MaskedToString {
|
||||||
require(
|
require(
|
||||||
MnemonicCode.VALID_LENGTHS.contains(words.length), {
|
MnemonicCode.VALID_LENGTHS.contains(words.length), {
|
||||||
val validLengths = MnemonicCode.VALID_LENGTHS.mkString(", ")
|
val validLengths = MnemonicCode.VALID_LENGTHS.mkString(", ")
|
||||||
@ -51,6 +53,8 @@ sealed abstract class MnemonicCode extends MaskedToString {
|
|||||||
*/
|
*/
|
||||||
def words: Vector[String]
|
def words: Vector[String]
|
||||||
|
|
||||||
|
override protected lazy val wrapped: Vector[String] = words
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the entropy initially provided to construct
|
* Returns the entropy initially provided to construct
|
||||||
* this mnemonic code
|
* this mnemonic code
|
||||||
|
@ -86,7 +86,7 @@ sealed trait WitnessTxSigComponent extends TxSigComponent {
|
|||||||
|
|
||||||
override def transaction: WitnessTransaction
|
override def transaction: WitnessTransaction
|
||||||
|
|
||||||
def witness: ScriptWitness = transaction.witness.witnesses(inputIndex.toInt)
|
def witness: ScriptWitness = transaction.witness(inputIndex.toInt)
|
||||||
|
|
||||||
def witnessVersion: WitnessVersion
|
def witnessVersion: WitnessVersion
|
||||||
|
|
||||||
|
@ -2,11 +2,12 @@ package org.bitcoins.core.hd
|
|||||||
|
|
||||||
import org.bitcoins.core.crypto.ExtKey
|
import org.bitcoins.core.crypto.ExtKey
|
||||||
import org.bitcoins.core.number.UInt32
|
import org.bitcoins.core.number.UInt32
|
||||||
import org.bitcoins.core.util.Factory
|
import org.bitcoins.core.util.{Factory, SeqWrapper}
|
||||||
import scodec.bits.ByteVector
|
import scodec.bits.ByteVector
|
||||||
|
|
||||||
abstract class BIP32Path {
|
abstract class BIP32Path extends SeqWrapper[BIP32Node] {
|
||||||
def path: Vector[BIP32Node]
|
def path: Vector[BIP32Node]
|
||||||
|
override protected lazy val wrapped: Vector[BIP32Node] = path
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BIP32 paths can be subsets/superset of each other.
|
* BIP32 paths can be subsets/superset of each other.
|
||||||
@ -31,12 +32,11 @@ abstract class BIP32Path {
|
|||||||
* m/44'/1'/0 diff m/44'/2'/1 == None
|
* m/44'/1'/0 diff m/44'/2'/1 == None
|
||||||
* }}}
|
* }}}
|
||||||
*/
|
*/
|
||||||
def diff(that: BIP32Path): Option[BIP32Path] = {
|
def diff(otherPath: BIP32Path): Option[BIP32Path] = {
|
||||||
import that.{path => otherPath}
|
|
||||||
|
|
||||||
if (path.length > otherPath.length) {
|
if (path.length > otherPath.length) {
|
||||||
None
|
None
|
||||||
} else if (path == otherPath) {
|
} else if (this.toVector == otherPath.toVector) {
|
||||||
Some(BIP32Path.empty)
|
Some(BIP32Path.empty)
|
||||||
} else {
|
} else {
|
||||||
val lengthDiff = otherPath.length - path.length
|
val lengthDiff = otherPath.length - path.length
|
||||||
@ -64,7 +64,7 @@ abstract class BIP32Path {
|
|||||||
// append the next divergent element to
|
// append the next divergent element to
|
||||||
// the acummed value
|
// the acummed value
|
||||||
case (Some(accum), ((None, their), _)) =>
|
case (Some(accum), ((None, their), _)) =>
|
||||||
Some(BIP32Path(accum.path :+ their))
|
Some(BIP32Path((accum :+ their).toVector))
|
||||||
|
|
||||||
// we've not yet reached the start of diverging
|
// we've not yet reached the start of diverging
|
||||||
// paths
|
// paths
|
||||||
|
@ -53,6 +53,6 @@ object HDAccount {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def isSameAccount(bip32Path: BIP32Path, account: HDAccount): Boolean = {
|
def isSameAccount(bip32Path: BIP32Path, account: HDAccount): Boolean = {
|
||||||
isSameAccount(bip32Path.path, account)
|
isSameAccount(bip32Path.toVector, account)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ sealed abstract class CompactSizeUInt extends NetworkElement {
|
|||||||
/** The number parsed from VarInt. */
|
/** The number parsed from VarInt. */
|
||||||
def num: UInt64
|
def num: UInt64
|
||||||
|
|
||||||
override def hex = size match {
|
override def hex = byteSize match {
|
||||||
case 1 => BitcoinSUtil.flipEndianness(num.hex.slice(14, 16))
|
case 1 => BitcoinSUtil.flipEndianness(num.hex.slice(14, 16))
|
||||||
case 3 => "fd" + BitcoinSUtil.flipEndianness(num.hex.slice(12, 16))
|
case 3 => "fd" + BitcoinSUtil.flipEndianness(num.hex.slice(12, 16))
|
||||||
case 5 => "fe" + BitcoinSUtil.flipEndianness(num.hex.slice(8, 16))
|
case 5 => "fe" + BitcoinSUtil.flipEndianness(num.hex.slice(8, 16))
|
||||||
@ -37,7 +37,9 @@ sealed abstract class CompactSizeUInt extends NetworkElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
object CompactSizeUInt extends Factory[CompactSizeUInt] {
|
object CompactSizeUInt extends Factory[CompactSizeUInt] {
|
||||||
private case class CompactSizeUIntImpl(num: UInt64, override val size: Long)
|
private case class CompactSizeUIntImpl(
|
||||||
|
num: UInt64,
|
||||||
|
override val byteSize: Long)
|
||||||
extends CompactSizeUInt
|
extends CompactSizeUInt
|
||||||
|
|
||||||
val zero: CompactSizeUInt = CompactSizeUInt(UInt64.zero)
|
val zero: CompactSizeUInt = CompactSizeUInt(UInt64.zero)
|
||||||
|
@ -11,7 +11,7 @@ import scodec.bits.ByteVector
|
|||||||
trait NetworkElement extends Any {
|
trait NetworkElement extends Any {
|
||||||
|
|
||||||
/** The size of the NetworkElement in bytes. */
|
/** The size of the NetworkElement in bytes. */
|
||||||
def size: Long = bytes.size
|
def byteSize: Long = bytes.size
|
||||||
|
|
||||||
/** The hexadecimal representation of the NetworkElement */
|
/** The hexadecimal representation of the NetworkElement */
|
||||||
def hex: String = bytes.toHex
|
def hex: String = bytes.toHex
|
||||||
|
@ -3,7 +3,7 @@ package org.bitcoins.core.protocol.ln
|
|||||||
import org.bitcoins.core.number.{UInt5, UInt8}
|
import org.bitcoins.core.number.{UInt5, UInt8}
|
||||||
import org.bitcoins.core.protocol.NetworkElement
|
import org.bitcoins.core.protocol.NetworkElement
|
||||||
import org.bitcoins.core.protocol.ln.util.LnUtil
|
import org.bitcoins.core.protocol.ln.util.LnUtil
|
||||||
import org.bitcoins.core.util.Bech32
|
import org.bitcoins.core.util.{Bech32, SeqWrapper}
|
||||||
import scodec.bits.ByteVector
|
import scodec.bits.ByteVector
|
||||||
|
|
||||||
import scala.annotation.tailrec
|
import scala.annotation.tailrec
|
||||||
@ -13,7 +13,9 @@ import scala.reflect.ClassTag
|
|||||||
/**
|
/**
|
||||||
* An aggregation of all the individual tagged fields in a [[org.bitcoins.core.protocol.ln.LnInvoice]]
|
* An aggregation of all the individual tagged fields in a [[org.bitcoins.core.protocol.ln.LnInvoice]]
|
||||||
*/
|
*/
|
||||||
sealed abstract class LnTaggedFields extends NetworkElement {
|
sealed abstract class LnTaggedFields
|
||||||
|
extends SeqWrapper[LnTag]
|
||||||
|
with NetworkElement {
|
||||||
|
|
||||||
require(tag[LnTag.PaymentHashTag].nonEmpty, "You must supply a payment hash")
|
require(tag[LnTag.PaymentHashTag].nonEmpty, "You must supply a payment hash")
|
||||||
require(
|
require(
|
||||||
@ -26,6 +28,8 @@ sealed abstract class LnTaggedFields extends NetworkElement {
|
|||||||
|
|
||||||
def tags: Vector[LnTag]
|
def tags: Vector[LnTag]
|
||||||
|
|
||||||
|
override protected lazy val wrapped: Vector[LnTag] = tags
|
||||||
|
|
||||||
def tag[T <: LnTag: ClassTag]: Option[T] =
|
def tag[T <: LnTag: ClassTag]: Option[T] =
|
||||||
tags.collectFirst {
|
tags.collectFirst {
|
||||||
case t: T => t
|
case t: T => t
|
||||||
|
@ -10,7 +10,7 @@ import org.bitcoins.core.protocol.ln.node.NodeId
|
|||||||
import org.bitcoins.core.protocol.ln.routing.LnRoute
|
import org.bitcoins.core.protocol.ln.routing.LnRoute
|
||||||
import org.bitcoins.core.protocol.ln.util.LnUtil
|
import org.bitcoins.core.protocol.ln.util.LnUtil
|
||||||
import org.bitcoins.core.protocol.script.{P2WPKHWitnessSPKV0, P2WSHWitnessSPKV0}
|
import org.bitcoins.core.protocol.script.{P2WPKHWitnessSPKV0, P2WSHWitnessSPKV0}
|
||||||
import org.bitcoins.core.util.{Bech32, CryptoUtil}
|
import org.bitcoins.core.util.{Bech32, CryptoUtil, SeqWrapper}
|
||||||
import scodec.bits.ByteVector
|
import scodec.bits.ByteVector
|
||||||
|
|
||||||
import scala.annotation.tailrec
|
import scala.annotation.tailrec
|
||||||
@ -19,7 +19,7 @@ import scala.annotation.tailrec
|
|||||||
* One of the tagged fields on a Lightning Network invoice
|
* One of the tagged fields on a Lightning Network invoice
|
||||||
* [[https://github.com/lightningnetwork/lightning-rfc/blob/master/11-payment-encoding.md#tagged-fields]]
|
* [[https://github.com/lightningnetwork/lightning-rfc/blob/master/11-payment-encoding.md#tagged-fields]]
|
||||||
*/
|
*/
|
||||||
sealed abstract class LnTag {
|
sealed trait LnTag {
|
||||||
|
|
||||||
def prefix: LnTagPrefix
|
def prefix: LnTagPrefix
|
||||||
|
|
||||||
@ -217,7 +217,10 @@ object LnTag {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
case class RoutingInfo(routes: Vector[LnRoute]) extends LnTag {
|
case class RoutingInfo(routes: Vector[LnRoute])
|
||||||
|
extends SeqWrapper[LnRoute]
|
||||||
|
with LnTag {
|
||||||
|
override protected val wrapped: Vector[LnRoute] = routes
|
||||||
|
|
||||||
override val prefix: LnTagPrefix = LnTagPrefix.RoutingInfo
|
override val prefix: LnTagPrefix = LnTagPrefix.RoutingInfo
|
||||||
|
|
||||||
@ -247,7 +250,7 @@ object LnTag {
|
|||||||
accum
|
accum
|
||||||
} else {
|
} else {
|
||||||
val route = LnRoute.fromBytes(remaining)
|
val route = LnRoute.fromBytes(remaining)
|
||||||
val newRemaining = remaining.slice(route.size, remaining.size)
|
val newRemaining = remaining.slice(route.byteSize, remaining.size)
|
||||||
loop(newRemaining, accum.:+(route))
|
loop(newRemaining, accum.:+(route))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,7 @@ sealed abstract class Transaction extends NetworkElement {
|
|||||||
* [[https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#Transaction_size_calculations]]
|
* [[https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#Transaction_size_calculations]]
|
||||||
*/
|
*/
|
||||||
def baseSize: Long = this match {
|
def baseSize: Long = this match {
|
||||||
case btx: BaseTransaction => btx.size
|
case btx: BaseTransaction => btx.byteSize
|
||||||
case wtx: WitnessTransaction =>
|
case wtx: WitnessTransaction =>
|
||||||
BaseTransaction(wtx.version, wtx.inputs, wtx.outputs, wtx.lockTime).baseSize
|
BaseTransaction(wtx.version, wtx.inputs, wtx.outputs, wtx.lockTime).baseSize
|
||||||
}
|
}
|
||||||
@ -106,7 +106,7 @@ sealed abstract class Transaction extends NetworkElement {
|
|||||||
|
|
||||||
sealed abstract class BaseTransaction extends Transaction {
|
sealed abstract class BaseTransaction extends Transaction {
|
||||||
override def bytes = RawBaseTransactionParser.write(this)
|
override def bytes = RawBaseTransactionParser.write(this)
|
||||||
override def weight = size * 4
|
override def weight = byteSize * 4
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,8 +120,8 @@ case object EmptyTransaction extends BaseTransaction {
|
|||||||
|
|
||||||
sealed abstract class WitnessTransaction extends Transaction {
|
sealed abstract class WitnessTransaction extends Transaction {
|
||||||
require(
|
require(
|
||||||
inputs.length == witness.witnesses.length,
|
inputs.length == witness.length,
|
||||||
s"Must have same amount of inputs and witnesses in witness tx, inputs=${inputs.length} witnesses=${witness.witnesses.length}"
|
s"Must have same amount of inputs and witnesses in witness tx, inputs=${inputs.length} witnesses=${witness.length}"
|
||||||
)
|
)
|
||||||
|
|
||||||
/** The txId for the witness transaction from satoshi's original serialization */
|
/** The txId for the witness transaction from satoshi's original serialization */
|
||||||
@ -153,7 +153,7 @@ sealed abstract class WitnessTransaction extends Transaction {
|
|||||||
*/
|
*/
|
||||||
override def weight: Long = {
|
override def weight: Long = {
|
||||||
val base = BaseTransaction(version, inputs, outputs, lockTime)
|
val base = BaseTransaction(version, inputs, outputs, lockTime)
|
||||||
base.size * 3 + size
|
base.byteSize * 3 + byteSize
|
||||||
}
|
}
|
||||||
override def bytes = RawWitnessTransactionParser.write(this)
|
override def bytes = RawWitnessTransactionParser.write(this)
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ case class TransactionOutput(value: CurrencyUnit, scriptPubKey: ScriptPubKey)
|
|||||||
extends NetworkElement {
|
extends NetworkElement {
|
||||||
|
|
||||||
//https://bitcoin.org/en/developer-reference#txout
|
//https://bitcoin.org/en/developer-reference#txout
|
||||||
override def size = scriptPubKey.size + 8
|
override def byteSize = scriptPubKey.byteSize + 8
|
||||||
|
|
||||||
override def bytes = RawTransactionOutputParser.write(this)
|
override def bytes = RawTransactionOutputParser.write(this)
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ package org.bitcoins.core.protocol.transaction
|
|||||||
import org.bitcoins.core.protocol.NetworkElement
|
import org.bitcoins.core.protocol.NetworkElement
|
||||||
import org.bitcoins.core.protocol.script.{EmptyScriptWitness, ScriptWitness}
|
import org.bitcoins.core.protocol.script.{EmptyScriptWitness, ScriptWitness}
|
||||||
import org.bitcoins.core.serializers.transaction.RawTransactionWitnessParser
|
import org.bitcoins.core.serializers.transaction.RawTransactionWitnessParser
|
||||||
import org.bitcoins.core.util.BitcoinSUtil
|
import org.bitcoins.core.util.{BitcoinSUtil, SeqWrapper}
|
||||||
import scodec.bits.ByteVector
|
import scodec.bits.ByteVector
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -11,8 +11,11 @@ import scodec.bits.ByteVector
|
|||||||
* The witness data for [[org.bitcoins.core.protocol.script.ScriptSignature ScriptSignature]] in this transaction
|
* The witness data for [[org.bitcoins.core.protocol.script.ScriptSignature ScriptSignature]] in this transaction
|
||||||
* [[https://github.com/bitcoin/bitcoin/blob/b4e4ba475a5679e09f279aaf2a83dcf93c632bdb/src/primitives/transaction.h#L232-L268]]
|
* [[https://github.com/bitcoin/bitcoin/blob/b4e4ba475a5679e09f279aaf2a83dcf93c632bdb/src/primitives/transaction.h#L232-L268]]
|
||||||
*/
|
*/
|
||||||
sealed abstract class TransactionWitness extends NetworkElement {
|
sealed abstract class TransactionWitness
|
||||||
|
extends SeqWrapper[ScriptWitness]
|
||||||
|
with NetworkElement {
|
||||||
val witnesses: Vector[ScriptWitness]
|
val witnesses: Vector[ScriptWitness]
|
||||||
|
override protected val wrapped: Vector[ScriptWitness] = witnesses
|
||||||
|
|
||||||
override def bytes: ByteVector = {
|
override def bytes: ByteVector = {
|
||||||
RawTransactionWitnessParser.write(this)
|
RawTransactionWitnessParser.write(this)
|
||||||
|
@ -387,7 +387,7 @@ case class PSBT(
|
|||||||
if (!previousElements.exists(_.key == expectedBytes)) {
|
if (!previousElements.exists(_.key == expectedBytes)) {
|
||||||
val fp =
|
val fp =
|
||||||
if (extKey.fingerprint == ExtKey.masterFingerprint) {
|
if (extKey.fingerprint == ExtKey.masterFingerprint) {
|
||||||
extKey.deriveChildPubKey(path.path.head).get.fingerprint
|
extKey.deriveChildPubKey(path.head).get.fingerprint
|
||||||
} else {
|
} else {
|
||||||
extKey.fingerprint
|
extKey.fingerprint
|
||||||
}
|
}
|
||||||
@ -579,7 +579,7 @@ case class PSBT(
|
|||||||
case Some(
|
case Some(
|
||||||
InputPSBTRecord.FinalizedScriptWitness(scriptWitness)) =>
|
InputPSBTRecord.FinalizedScriptWitness(scriptWitness)) =>
|
||||||
TransactionWitness(
|
TransactionWitness(
|
||||||
witness.witnesses.updated(index, scriptWitness))
|
witness.updated(index, scriptWitness).toVector)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
WitnessTransaction(transaction.version,
|
WitnessTransaction(transaction.version,
|
||||||
|
@ -13,7 +13,7 @@ import org.bitcoins.core.protocol.transaction.{
|
|||||||
WitnessTransaction
|
WitnessTransaction
|
||||||
}
|
}
|
||||||
import org.bitcoins.core.script.crypto.HashType
|
import org.bitcoins.core.script.crypto.HashType
|
||||||
import org.bitcoins.core.util.{CryptoUtil, Factory}
|
import org.bitcoins.core.util.{CryptoUtil, Factory, SeqWrapper}
|
||||||
import org.bitcoins.core.wallet.signer.{BitcoinSigner, BitcoinSignerSingle}
|
import org.bitcoins.core.wallet.signer.{BitcoinSigner, BitcoinSignerSingle}
|
||||||
import org.bitcoins.core.wallet.utxo._
|
import org.bitcoins.core.wallet.utxo._
|
||||||
import scodec.bits.ByteVector
|
import scodec.bits.ByteVector
|
||||||
@ -87,11 +87,13 @@ sealed trait PSBTMapFactory[
|
|||||||
}
|
}
|
||||||
|
|
||||||
case class GlobalPSBTMap(elements: Vector[GlobalPSBTRecord])
|
case class GlobalPSBTMap(elements: Vector[GlobalPSBTRecord])
|
||||||
extends PSBTMap[GlobalPSBTRecord] {
|
extends SeqWrapper[GlobalPSBTRecord]
|
||||||
|
with PSBTMap[GlobalPSBTRecord] {
|
||||||
import org.bitcoins.core.psbt.GlobalPSBTRecord._
|
import org.bitcoins.core.psbt.GlobalPSBTRecord._
|
||||||
import org.bitcoins.core.psbt.PSBTGlobalKeyId._
|
import org.bitcoins.core.psbt.PSBTGlobalKeyId._
|
||||||
require(getRecords(UnsignedTransactionKeyId).nonEmpty,
|
require(getRecords(UnsignedTransactionKeyId).nonEmpty,
|
||||||
"A GlobalPSBTMap must have a Unsigned Transaction")
|
"A GlobalPSBTMap must have a Unsigned Transaction")
|
||||||
|
override val wrapped: Vector[GlobalPSBTRecord] = elements
|
||||||
|
|
||||||
def unsignedTransaction: UnsignedTransaction = {
|
def unsignedTransaction: UnsignedTransaction = {
|
||||||
getRecords(UnsignedTransactionKeyId).head
|
getRecords(UnsignedTransactionKeyId).head
|
||||||
@ -150,11 +152,14 @@ object GlobalPSBTMap extends PSBTMapFactory[GlobalPSBTRecord, GlobalPSBTMap] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case class InputPSBTMap(elements: Vector[InputPSBTRecord])
|
case class InputPSBTMap(elements: Vector[InputPSBTRecord])
|
||||||
extends PSBTMap[InputPSBTRecord] {
|
extends SeqWrapper[InputPSBTRecord]
|
||||||
|
with PSBTMap[InputPSBTRecord] {
|
||||||
require(
|
require(
|
||||||
this.witnessUTXOOpt.isEmpty || this.nonWitnessOrUnknownUTXOOpt.isEmpty,
|
this.witnessUTXOOpt.isEmpty || this.nonWitnessOrUnknownUTXOOpt.isEmpty,
|
||||||
"InputPSBTMap cannot have both a NonWitnessOrUnknownUTXO and a WitnessUTXO"
|
"InputPSBTMap cannot have both a NonWitnessOrUnknownUTXO and a WitnessUTXO"
|
||||||
)
|
)
|
||||||
|
override protected val wrapped: Vector[InputPSBTRecord] = elements
|
||||||
|
|
||||||
import org.bitcoins.core.psbt.InputPSBTRecord._
|
import org.bitcoins.core.psbt.InputPSBTRecord._
|
||||||
import org.bitcoins.core.psbt.PSBTInputKeyId._
|
import org.bitcoins.core.psbt.PSBTInputKeyId._
|
||||||
|
|
||||||
@ -642,7 +647,7 @@ object InputPSBTMap extends PSBTMapFactory[InputPSBTRecord, InputPSBTMap] {
|
|||||||
sigComponent.transaction match {
|
sigComponent.transaction match {
|
||||||
case _: BaseTransaction => InputPSBTMap(utxos ++ Vector(scriptSig))
|
case _: BaseTransaction => InputPSBTMap(utxos ++ Vector(scriptSig))
|
||||||
case wtx: WitnessTransaction =>
|
case wtx: WitnessTransaction =>
|
||||||
val witness = wtx.witness.witnesses(sigComponent.inputIndex.toInt)
|
val witness = wtx.witness(sigComponent.inputIndex.toInt)
|
||||||
val scriptWitness = FinalizedScriptWitness(witness)
|
val scriptWitness = FinalizedScriptWitness(witness)
|
||||||
val finalizedSigs =
|
val finalizedSigs =
|
||||||
if (witness != EmptyScriptWitness) {
|
if (witness != EmptyScriptWitness) {
|
||||||
@ -721,10 +726,13 @@ object InputPSBTMap extends PSBTMapFactory[InputPSBTRecord, InputPSBTMap] {
|
|||||||
override def recordFactory: Factory[InputPSBTRecord] = InputPSBTRecord
|
override def recordFactory: Factory[InputPSBTRecord] = InputPSBTRecord
|
||||||
}
|
}
|
||||||
case class OutputPSBTMap(elements: Vector[OutputPSBTRecord])
|
case class OutputPSBTMap(elements: Vector[OutputPSBTRecord])
|
||||||
extends PSBTMap[OutputPSBTRecord] {
|
extends SeqWrapper[OutputPSBTRecord]
|
||||||
|
with PSBTMap[OutputPSBTRecord] {
|
||||||
import org.bitcoins.core.psbt.OutputPSBTRecord._
|
import org.bitcoins.core.psbt.OutputPSBTRecord._
|
||||||
import org.bitcoins.core.psbt.PSBTOutputKeyId._
|
import org.bitcoins.core.psbt.PSBTOutputKeyId._
|
||||||
|
|
||||||
|
override val wrapped: Vector[OutputPSBTRecord] = elements
|
||||||
|
|
||||||
def redeemScriptOpt: Option[RedeemScript] = {
|
def redeemScriptOpt: Option[RedeemScript] = {
|
||||||
getRecords(RedeemScriptKeyId).headOption
|
getRecords(RedeemScriptKeyId).headOption
|
||||||
}
|
}
|
||||||
|
@ -39,11 +39,11 @@ object PSBTRecord {
|
|||||||
if (keyCmpctUInt.toLong == 0) {
|
if (keyCmpctUInt.toLong == 0) {
|
||||||
(ByteVector.empty, ByteVector.empty)
|
(ByteVector.empty, ByteVector.empty)
|
||||||
} else {
|
} else {
|
||||||
val key = bytes.drop(keyCmpctUInt.size).take(keyCmpctUInt.toLong)
|
val key = bytes.drop(keyCmpctUInt.byteSize).take(keyCmpctUInt.toLong)
|
||||||
val valueBytes = bytes.drop(keyCmpctUInt.size + keyCmpctUInt.toLong)
|
val valueBytes = bytes.drop(keyCmpctUInt.byteSize + keyCmpctUInt.toLong)
|
||||||
val valueCmpctUInt = CompactSizeUInt.parse(valueBytes)
|
val valueCmpctUInt = CompactSizeUInt.parse(valueBytes)
|
||||||
val value = valueBytes
|
val value = valueBytes
|
||||||
.drop(valueCmpctUInt.size)
|
.drop(valueCmpctUInt.byteSize)
|
||||||
.take(valueCmpctUInt.toLong)
|
.take(valueCmpctUInt.toLong)
|
||||||
|
|
||||||
(key, value)
|
(key, value)
|
||||||
@ -74,8 +74,8 @@ object GlobalPSBTRecord extends Factory[GlobalPSBTRecord] {
|
|||||||
derivationPath: BIP32Path)
|
derivationPath: BIP32Path)
|
||||||
extends GlobalPSBTRecord {
|
extends GlobalPSBTRecord {
|
||||||
require(
|
require(
|
||||||
derivationPath.path.length == xpub.depth.toInt,
|
derivationPath.length == xpub.depth.toInt,
|
||||||
s"Derivation path length does not match xpubkey depth, difference: ${derivationPath.path.length - xpub.depth.toInt}"
|
s"Derivation path length does not match xpubkey depth, difference: ${derivationPath.length - xpub.depth.toInt}"
|
||||||
)
|
)
|
||||||
require(
|
require(
|
||||||
masterFingerprint.length == 4,
|
masterFingerprint.length == 4,
|
||||||
@ -83,7 +83,7 @@ object GlobalPSBTRecord extends Factory[GlobalPSBTRecord] {
|
|||||||
|
|
||||||
override type KeyId = XPubKeyKeyId.type
|
override type KeyId = XPubKeyKeyId.type
|
||||||
override val key: ByteVector = ByteVector(XPubKeyKeyId.byte) ++ xpub.bytes
|
override val key: ByteVector = ByteVector(XPubKeyKeyId.byte) ++ xpub.bytes
|
||||||
override val value: ByteVector = derivationPath.path
|
override val value: ByteVector = derivationPath
|
||||||
.foldLeft(masterFingerprint)(_ ++ _.toUInt32.bytesLE)
|
.foldLeft(masterFingerprint)(_ ++ _.toUInt32.bytesLE)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,7 +155,8 @@ object InputPSBTRecord extends Factory[InputPSBTRecord] {
|
|||||||
pubKey: ECPublicKey,
|
pubKey: ECPublicKey,
|
||||||
signature: ECDigitalSignature)
|
signature: ECDigitalSignature)
|
||||||
extends InputPSBTRecord {
|
extends InputPSBTRecord {
|
||||||
require(pubKey.size == 33, s"pubKey must be 33 bytes, got: ${pubKey.size}")
|
require(pubKey.byteSize == 33,
|
||||||
|
s"pubKey must be 33 bytes, got: ${pubKey.byteSize}")
|
||||||
|
|
||||||
override type KeyId = PartialSignatureKeyId.type
|
override type KeyId = PartialSignatureKeyId.type
|
||||||
override val key: ByteVector = ByteVector(PartialSignatureKeyId.byte) ++ pubKey.bytes
|
override val key: ByteVector = ByteVector(PartialSignatureKeyId.byte) ++ pubKey.bytes
|
||||||
@ -186,12 +187,13 @@ object InputPSBTRecord extends Factory[InputPSBTRecord] {
|
|||||||
masterFingerprint: ByteVector,
|
masterFingerprint: ByteVector,
|
||||||
path: BIP32Path)
|
path: BIP32Path)
|
||||||
extends InputPSBTRecord {
|
extends InputPSBTRecord {
|
||||||
require(pubKey.size == 33, s"pubKey must be 33 bytes, got: ${pubKey.size}")
|
require(pubKey.byteSize == 33,
|
||||||
|
s"pubKey must be 33 bytes, got: ${pubKey.byteSize}")
|
||||||
|
|
||||||
override type KeyId = BIP32DerivationPathKeyId.type
|
override type KeyId = BIP32DerivationPathKeyId.type
|
||||||
override val key: ByteVector = ByteVector(BIP32DerivationPathKeyId.byte) ++ pubKey.bytes
|
override val key: ByteVector = ByteVector(BIP32DerivationPathKeyId.byte) ++ pubKey.bytes
|
||||||
override val value: ByteVector =
|
override val value: ByteVector =
|
||||||
path.path.foldLeft(masterFingerprint)(_ ++ _.toUInt32.bytesLE)
|
path.foldLeft(masterFingerprint)(_ ++ _.toUInt32.bytesLE)
|
||||||
}
|
}
|
||||||
|
|
||||||
case class FinalizedScriptSig(scriptSig: ScriptSignature)
|
case class FinalizedScriptSig(scriptSig: ScriptSignature)
|
||||||
@ -307,12 +309,13 @@ object OutputPSBTRecord extends Factory[OutputPSBTRecord] {
|
|||||||
masterFingerprint: ByteVector,
|
masterFingerprint: ByteVector,
|
||||||
path: BIP32Path)
|
path: BIP32Path)
|
||||||
extends OutputPSBTRecord {
|
extends OutputPSBTRecord {
|
||||||
require(pubKey.size == 33, s"pubKey must be 33 bytes, got: ${pubKey.size}")
|
require(pubKey.byteSize == 33,
|
||||||
|
s"pubKey must be 33 bytes, got: ${pubKey.byteSize}")
|
||||||
|
|
||||||
override type KeyId = BIP32DerivationPathKeyId.type
|
override type KeyId = BIP32DerivationPathKeyId.type
|
||||||
override val key: ByteVector = ByteVector(BIP32DerivationPathKeyId.byte) ++ pubKey.bytes
|
override val key: ByteVector = ByteVector(BIP32DerivationPathKeyId.byte) ++ pubKey.bytes
|
||||||
override val value: ByteVector =
|
override val value: ByteVector =
|
||||||
path.path.foldLeft(masterFingerprint)(_ ++ _.toUInt32.bytesLE)
|
path.foldLeft(masterFingerprint)(_ ++ _.toUInt32.bytesLE)
|
||||||
}
|
}
|
||||||
|
|
||||||
case class Unknown(key: ByteVector, value: ByteVector)
|
case class Unknown(key: ByteVector, value: ByteVector)
|
||||||
|
@ -1130,17 +1130,11 @@ sealed abstract class ScriptInterpreter extends BitcoinSLogger {
|
|||||||
case b: BaseTxSigComponent =>
|
case b: BaseTxSigComponent =>
|
||||||
b.transaction match {
|
b.transaction match {
|
||||||
case wtx: WitnessTransaction =>
|
case wtx: WitnessTransaction =>
|
||||||
wtx.witness
|
wtx.witness(txSigComponent.inputIndex.toInt).stack.nonEmpty
|
||||||
.witnesses(txSigComponent.inputIndex.toInt)
|
|
||||||
.stack
|
|
||||||
.nonEmpty
|
|
||||||
case _: BaseTransaction => false
|
case _: BaseTransaction => false
|
||||||
}
|
}
|
||||||
case r: WitnessTxSigComponentRebuilt =>
|
case r: WitnessTxSigComponentRebuilt =>
|
||||||
r.transaction.witness
|
r.transaction.witness(txSigComponent.inputIndex.toInt).stack.nonEmpty
|
||||||
.witnesses(txSigComponent.inputIndex.toInt)
|
|
||||||
.stack
|
|
||||||
.nonEmpty
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unexpectedWitness)
|
if (unexpectedWitness)
|
||||||
|
@ -19,7 +19,7 @@ sealed abstract class RawSerializerHelper {
|
|||||||
bytes: ByteVector,
|
bytes: ByteVector,
|
||||||
constructor: ByteVector => T): (Seq[T], ByteVector) = {
|
constructor: ByteVector => T): (Seq[T], ByteVector) = {
|
||||||
val count = CompactSizeUInt.parse(bytes)
|
val count = CompactSizeUInt.parse(bytes)
|
||||||
val payload = bytes.splitAt(count.size.toInt)._2
|
val payload = bytes.splitAt(count.byteSize.toInt)._2
|
||||||
var counter = 0
|
var counter = 0
|
||||||
val b = Vector.newBuilder[T]
|
val b = Vector.newBuilder[T]
|
||||||
@tailrec
|
@tailrec
|
||||||
@ -28,7 +28,7 @@ sealed abstract class RawSerializerHelper {
|
|||||||
remaining
|
remaining
|
||||||
} else {
|
} else {
|
||||||
val parsed = constructor(remaining)
|
val parsed = constructor(remaining)
|
||||||
val (_, newRemaining) = remaining.splitAt(parsed.size)
|
val (_, newRemaining) = remaining.splitAt(parsed.byteSize)
|
||||||
|
|
||||||
counter = counter + 1
|
counter = counter + 1
|
||||||
b.+=(parsed)
|
b.+=(parsed)
|
||||||
|
@ -15,9 +15,9 @@ sealed abstract class RawBloomFilterSerializer
|
|||||||
|
|
||||||
override def read(bytes: ByteVector): BloomFilter = {
|
override def read(bytes: ByteVector): BloomFilter = {
|
||||||
val filterSize = CompactSizeUInt.parseCompactSizeUInt(bytes)
|
val filterSize = CompactSizeUInt.parseCompactSizeUInt(bytes)
|
||||||
val filter = bytes.slice(filterSize.size.toInt,
|
val filter = bytes.slice(filterSize.byteSize.toInt,
|
||||||
filterSize.size.toInt + filterSize.num.toInt)
|
filterSize.byteSize.toInt + filterSize.num.toInt)
|
||||||
val hashFuncsIndex = (filterSize.size + filterSize.num.toInt).toInt
|
val hashFuncsIndex = (filterSize.byteSize + filterSize.num.toInt).toInt
|
||||||
val hashFuncs = UInt32(
|
val hashFuncs = UInt32(
|
||||||
bytes.slice(hashFuncsIndex, hashFuncsIndex + 4).reverse)
|
bytes.slice(hashFuncsIndex, hashFuncsIndex + 4).reverse)
|
||||||
val tweakIndex = hashFuncsIndex + 4
|
val tweakIndex = hashFuncsIndex + 4
|
||||||
|
@ -16,7 +16,7 @@ trait RawAddrMessageSerializer extends RawBitcoinSerializer[AddrMessage] {
|
|||||||
|
|
||||||
override def read(bytes: ByteVector): AddrMessage = {
|
override def read(bytes: ByteVector): AddrMessage = {
|
||||||
val ipCount = CompactSizeUInt.parseCompactSizeUInt(bytes)
|
val ipCount = CompactSizeUInt.parseCompactSizeUInt(bytes)
|
||||||
val ipAddressBytes = bytes.slice(ipCount.size.toInt, bytes.size)
|
val ipAddressBytes = bytes.slice(ipCount.byteSize.toInt, bytes.size)
|
||||||
val (networkIpAddresses, _) =
|
val (networkIpAddresses, _) =
|
||||||
parseNetworkIpAddresses(ipCount, ipAddressBytes)
|
parseNetworkIpAddresses(ipCount, ipAddressBytes)
|
||||||
AddrMessage(ipCount, networkIpAddresses)
|
AddrMessage(ipCount, networkIpAddresses)
|
||||||
@ -48,7 +48,7 @@ trait RawAddrMessageSerializer extends RawBitcoinSerializer[AddrMessage] {
|
|||||||
val networkIpAddress =
|
val networkIpAddress =
|
||||||
RawNetworkIpAddressSerializer.read(remainingBytes)
|
RawNetworkIpAddressSerializer.read(remainingBytes)
|
||||||
val newRemainingBytes =
|
val newRemainingBytes =
|
||||||
remainingBytes.slice(networkIpAddress.size, remainingBytes.size)
|
remainingBytes.slice(networkIpAddress.byteSize, remainingBytes.size)
|
||||||
loop(remainingAddresses - 1,
|
loop(remainingAddresses - 1,
|
||||||
newRemainingBytes,
|
newRemainingBytes,
|
||||||
networkIpAddress :: accum)
|
networkIpAddress :: accum)
|
||||||
|
@ -14,7 +14,7 @@ trait RawFilterAddMessageSerializer
|
|||||||
|
|
||||||
override def read(bytes: ByteVector): FilterAddMessage = {
|
override def read(bytes: ByteVector): FilterAddMessage = {
|
||||||
val elementSize = CompactSizeUInt.parseCompactSizeUInt(bytes)
|
val elementSize = CompactSizeUInt.parseCompactSizeUInt(bytes)
|
||||||
val element = bytes.slice(elementSize.size.toInt, bytes.size)
|
val element = bytes.slice(elementSize.byteSize.toInt, bytes.size)
|
||||||
FilterAddMessage(elementSize, element)
|
FilterAddMessage(elementSize, element)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ trait RawGetBlocksMessageSerializer
|
|||||||
val version = ProtocolVersion(bytes.take(4))
|
val version = ProtocolVersion(bytes.take(4))
|
||||||
val hashCount =
|
val hashCount =
|
||||||
CompactSizeUInt.parseCompactSizeUInt(bytes.slice(4, bytes.size))
|
CompactSizeUInt.parseCompactSizeUInt(bytes.slice(4, bytes.size))
|
||||||
val blockHeaderStartByte = (hashCount.size + 4).toInt
|
val blockHeaderStartByte = (hashCount.byteSize + 4).toInt
|
||||||
val blockHeaderBytesStopHash = bytes.slice(blockHeaderStartByte, bytes.size)
|
val blockHeaderBytesStopHash = bytes.slice(blockHeaderStartByte, bytes.size)
|
||||||
val (blockHashHeaders, remainingBytes) =
|
val (blockHashHeaders, remainingBytes) =
|
||||||
parseBlockHeaders(blockHeaderBytesStopHash, hashCount)
|
parseBlockHeaders(blockHeaderBytesStopHash, hashCount)
|
||||||
|
@ -15,7 +15,7 @@ trait RawGetHeadersMessageSerializer
|
|||||||
val version = ProtocolVersion(bytes.take(4))
|
val version = ProtocolVersion(bytes.take(4))
|
||||||
val hashCount =
|
val hashCount =
|
||||||
CompactSizeUInt.parseCompactSizeUInt(bytes.slice(4, bytes.length))
|
CompactSizeUInt.parseCompactSizeUInt(bytes.slice(4, bytes.length))
|
||||||
val hashesStartIndex = (hashCount.size + 4).toInt
|
val hashesStartIndex = (hashCount.byteSize + 4).toInt
|
||||||
val (hashes, remainingBytes) =
|
val (hashes, remainingBytes) =
|
||||||
parseHashes(bytes.slice(hashesStartIndex, bytes.length), hashCount)
|
parseHashes(bytes.slice(hashesStartIndex, bytes.length), hashCount)
|
||||||
val hashStop = DoubleSha256Digest(remainingBytes.take(32))
|
val hashStop = DoubleSha256Digest(remainingBytes.take(32))
|
||||||
|
@ -12,7 +12,7 @@ trait RawHeadersMessageSerializer extends RawBitcoinSerializer[HeadersMessage] {
|
|||||||
|
|
||||||
def read(bytes: ByteVector): HeadersMessage = {
|
def read(bytes: ByteVector): HeadersMessage = {
|
||||||
val compactSizeUInt = CompactSizeUInt.parseCompactSizeUInt(bytes)
|
val compactSizeUInt = CompactSizeUInt.parseCompactSizeUInt(bytes)
|
||||||
val headerStartIndex = compactSizeUInt.size.toInt
|
val headerStartIndex = compactSizeUInt.byteSize.toInt
|
||||||
val headerBytes = bytes.slice(headerStartIndex, bytes.length)
|
val headerBytes = bytes.slice(headerStartIndex, bytes.length)
|
||||||
val headers = parseBlockHeaders(headerBytes, compactSizeUInt)
|
val headers = parseBlockHeaders(headerBytes, compactSizeUInt)
|
||||||
HeadersMessage(compactSizeUInt, headers)
|
HeadersMessage(compactSizeUInt, headers)
|
||||||
|
@ -19,7 +19,7 @@ trait RawInventoryMessageSerializer
|
|||||||
*/
|
*/
|
||||||
override def read(bytes: ByteVector): InventoryMessage = {
|
override def read(bytes: ByteVector): InventoryMessage = {
|
||||||
val inventoryCount = CompactSizeUInt.parseCompactSizeUInt(bytes)
|
val inventoryCount = CompactSizeUInt.parseCompactSizeUInt(bytes)
|
||||||
val inventoryStart = inventoryCount.size.toInt
|
val inventoryStart = inventoryCount.byteSize.toInt
|
||||||
val remainingBytes = bytes.slice(inventoryStart, bytes.size)
|
val remainingBytes = bytes.slice(inventoryStart, bytes.size)
|
||||||
val (inventories, _) = parseInventories(remainingBytes, inventoryCount)
|
val (inventories, _) = parseInventories(remainingBytes, inventoryCount)
|
||||||
InventoryMessage(inventoryCount, inventories)
|
InventoryMessage(inventoryCount, inventories)
|
||||||
|
@ -11,24 +11,24 @@ trait RawRejectMessageSerializer extends RawBitcoinSerializer[RejectMessage] {
|
|||||||
def read(bytes: ByteVector): RejectMessage = {
|
def read(bytes: ByteVector): RejectMessage = {
|
||||||
val messageSize = CompactSizeUInt.parseCompactSizeUInt(bytes)
|
val messageSize = CompactSizeUInt.parseCompactSizeUInt(bytes)
|
||||||
val message: String = bytes
|
val message: String = bytes
|
||||||
.slice(messageSize.size.toInt,
|
.slice(messageSize.byteSize.toInt,
|
||||||
messageSize.size.toInt +
|
messageSize.byteSize.toInt +
|
||||||
messageSize.num.toInt)
|
messageSize.num.toInt)
|
||||||
.toArray
|
.toArray
|
||||||
.map(_.toChar)
|
.map(_.toChar)
|
||||||
.mkString
|
.mkString
|
||||||
val code: Char = bytes(messageSize.size.toInt + messageSize.num.toInt).toChar
|
val code: Char = bytes(messageSize.byteSize.toInt + messageSize.num.toInt).toChar
|
||||||
val reasonSizeStartIndex = messageSize.size.toInt + messageSize.num.toInt + 1
|
val reasonSizeStartIndex = messageSize.byteSize.toInt + messageSize.num.toInt + 1
|
||||||
val reasonSize = CompactSizeUInt.parseCompactSizeUInt(
|
val reasonSize = CompactSizeUInt.parseCompactSizeUInt(
|
||||||
bytes.slice(reasonSizeStartIndex.toInt, bytes.size))
|
bytes.slice(reasonSizeStartIndex.toInt, bytes.size))
|
||||||
val reason = bytes
|
val reason = bytes
|
||||||
.slice(
|
.slice(
|
||||||
(reasonSizeStartIndex + reasonSize.size).toInt,
|
(reasonSizeStartIndex + reasonSize.byteSize).toInt,
|
||||||
(reasonSizeStartIndex + reasonSize.size.toInt + reasonSize.num.toInt))
|
(reasonSizeStartIndex + reasonSize.byteSize.toInt + reasonSize.num.toInt))
|
||||||
.toArray
|
.toArray
|
||||||
.map(_.toChar)
|
.map(_.toChar)
|
||||||
.mkString
|
.mkString
|
||||||
val extraStartIndex = (reasonSizeStartIndex + reasonSize.size.toInt + reasonSize.num.toInt)
|
val extraStartIndex = (reasonSizeStartIndex + reasonSize.byteSize.toInt + reasonSize.num.toInt)
|
||||||
val extra = bytes.slice(extraStartIndex, bytes.size)
|
val extra = bytes.slice(extraStartIndex, bytes.size)
|
||||||
RejectMessage(messageSize, message, code, reasonSize, reason, extra)
|
RejectMessage(messageSize, message, code, reasonSize, reason, extra)
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ trait RawVersionMessageSerializer
|
|||||||
val userAgentSize =
|
val userAgentSize =
|
||||||
CompactSizeUInt.parseCompactSizeUInt(bytes.slice(80, bytes.size))
|
CompactSizeUInt.parseCompactSizeUInt(bytes.slice(80, bytes.size))
|
||||||
|
|
||||||
val userAgentBytesStartIndex = 80 + userAgentSize.size.toInt
|
val userAgentBytesStartIndex = 80 + userAgentSize.byteSize.toInt
|
||||||
|
|
||||||
val userAgentBytes = bytes.slice(
|
val userAgentBytes = bytes.slice(
|
||||||
userAgentBytesStartIndex,
|
userAgentBytesStartIndex,
|
||||||
|
@ -17,7 +17,7 @@ sealed abstract class RawScriptWitnessParser
|
|||||||
def read(bytes: ByteVector): ScriptWitness = {
|
def read(bytes: ByteVector): ScriptWitness = {
|
||||||
//first byte is the number of stack items
|
//first byte is the number of stack items
|
||||||
val stackSize = CompactSizeUInt.parseCompactSizeUInt(bytes)
|
val stackSize = CompactSizeUInt.parseCompactSizeUInt(bytes)
|
||||||
val (_, stackBytes) = bytes.splitAt(stackSize.size.toInt)
|
val (_, stackBytes) = bytes.splitAt(stackSize.byteSize.toInt)
|
||||||
@tailrec
|
@tailrec
|
||||||
def loop(
|
def loop(
|
||||||
remainingBytes: ByteVector,
|
remainingBytes: ByteVector,
|
||||||
@ -27,7 +27,7 @@ sealed abstract class RawScriptWitnessParser
|
|||||||
else {
|
else {
|
||||||
val elementSize = CompactSizeUInt.parseCompactSizeUInt(remainingBytes)
|
val elementSize = CompactSizeUInt.parseCompactSizeUInt(remainingBytes)
|
||||||
val (_, stackElementBytes) =
|
val (_, stackElementBytes) =
|
||||||
remainingBytes.splitAt(elementSize.size.toInt)
|
remainingBytes.splitAt(elementSize.byteSize.toInt)
|
||||||
val stackElement = stackElementBytes.take(elementSize.num.toInt)
|
val stackElement = stackElementBytes.take(elementSize.num.toInt)
|
||||||
val (_, newRemainingBytes) =
|
val (_, newRemainingBytes) =
|
||||||
stackElementBytes.splitAt(stackElement.size)
|
stackElementBytes.splitAt(stackElement.size)
|
||||||
|
@ -38,7 +38,7 @@ sealed abstract class RawTransactionWitnessParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def write(witness: TransactionWitness): ByteVector = {
|
def write(witness: TransactionWitness): ByteVector = {
|
||||||
witness.witnesses.foldLeft(ByteVector.empty)(_ ++ _.bytes)
|
witness.foldLeft(ByteVector.empty)(_ ++ _.bytes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -588,7 +588,8 @@ trait BitcoinScriptUtil extends BitcoinSLogger {
|
|||||||
//but scala collections don't allow you to use 'slice' with longs
|
//but scala collections don't allow you to use 'slice' with longs
|
||||||
val len = Try(compactSizeUInt.num.toInt).getOrElse(Int.MaxValue)
|
val len = Try(compactSizeUInt.num.toInt).getOrElse(Int.MaxValue)
|
||||||
val scriptPubKeyBytes =
|
val scriptPubKeyBytes =
|
||||||
bytes.slice(compactSizeUInt.size.toInt, len + compactSizeUInt.size.toInt)
|
bytes.slice(compactSizeUInt.byteSize.toInt,
|
||||||
|
len + compactSizeUInt.byteSize.toInt)
|
||||||
val script: List[ScriptToken] = ScriptParser.fromBytes(scriptPubKeyBytes)
|
val script: List[ScriptToken] = ScriptParser.fromBytes(scriptPubKeyBytes)
|
||||||
f(script.toVector)
|
f(script.toVector)
|
||||||
}
|
}
|
||||||
|
17
core/src/main/scala/org/bitcoins/core/util/Wrappers.scala
Normal file
17
core/src/main/scala/org/bitcoins/core/util/Wrappers.scala
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
package org.bitcoins.core.util
|
||||||
|
|
||||||
|
trait SeqWrapper[+T] extends IndexedSeq[T] {
|
||||||
|
protected def wrapped: IndexedSeq[T]
|
||||||
|
override def iterator: Iterator[T] = wrapped.iterator
|
||||||
|
override def length: Int = wrapped.length
|
||||||
|
override def apply(idx: Int): T = wrapped(idx)
|
||||||
|
}
|
||||||
|
|
||||||
|
trait MapWrapper[K, +T] extends Map[K, T] {
|
||||||
|
protected def wrapped: Map[K, T]
|
||||||
|
override def +[B1 >: T](kv: (K, B1)): Map[K, B1] = wrapped.+(kv)
|
||||||
|
override def get(key: K): Option[T] = wrapped.get(key)
|
||||||
|
override def iterator: Iterator[(K, T)] = wrapped.iterator
|
||||||
|
override def updated[V1 >: T](key: K, value: V1): Map[K, V1] =
|
||||||
|
wrapped.updated(key, value)
|
||||||
|
}
|
@ -293,7 +293,7 @@ object BitcoinSignerSingle {
|
|||||||
btx.lockTime,
|
btx.lockTime,
|
||||||
transactionWitness)
|
transactionWitness)
|
||||||
case wtx: WitnessTransaction =>
|
case wtx: WitnessTransaction =>
|
||||||
wtx.witness.witnesses(inputIndex) match {
|
wtx.witness(inputIndex) match {
|
||||||
case EmptyScriptWitness =>
|
case EmptyScriptWitness =>
|
||||||
val transactionWitnessOpt =
|
val transactionWitnessOpt =
|
||||||
psbt
|
psbt
|
||||||
@ -740,8 +740,9 @@ sealed abstract class P2WPKHSigner
|
|||||||
val pubKey = signer.publicKey
|
val pubKey = signer.publicKey
|
||||||
|
|
||||||
val unsignedTxWitness = TransactionWitness(
|
val unsignedTxWitness = TransactionWitness(
|
||||||
wtx.witness.witnesses
|
wtx.witness
|
||||||
.updated(inputIndex.toInt, spendingInfoToSatisfy.scriptWitness))
|
.updated(inputIndex.toInt, spendingInfoToSatisfy.scriptWitness)
|
||||||
|
.toVector)
|
||||||
|
|
||||||
val unsignedWtx = WitnessTransaction(wtx.version,
|
val unsignedWtx = WitnessTransaction(wtx.version,
|
||||||
wtx.inputs,
|
wtx.inputs,
|
||||||
|
Loading…
Reference in New Issue
Block a user