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:
Nadav Kohen 2020-02-24 13:39:20 -07:00 committed by GitHub
parent 03cfbc0803
commit 052b64b7e2
40 changed files with 142 additions and 107 deletions

View File

@ -60,7 +60,7 @@ class RawTransactionRpcTest extends BitcoindRpcTest {
} yield {
assert(rpcTransaction.txid == transaction.txIdBE)
assert(rpcTransaction.locktime == transaction.lockTime)
assert(rpcTransaction.size == transaction.size)
assert(rpcTransaction.size == transaction.byteSize)
assert(rpcTransaction.version == transaction.version.toInt)
assert(rpcTransaction.vsize == transaction.vsize)
}

View File

@ -12,6 +12,7 @@ import org.bitcoins.core.protocol.BitcoinAddress
import org.bitcoins.core.protocol.blockchain.BlockHeader
import org.bitcoins.core.protocol.script.ScriptPubKey
import org.bitcoins.core.protocol.transaction.Transaction
import org.bitcoins.core.util.SeqWrapper
import org.bitcoins.core.wallet.fee.BitcoinFeeUnit
import play.api.libs.json.JsObject
@ -161,6 +162,9 @@ case class TestMempoolAcceptResult(
final case class DeriveAddressesResult(addresses: Vector[BitcoinAddress])
extends OtherResult
with SeqWrapper[BitcoinAddress] {
override protected val wrapped: Vector[BitcoinAddress] = addresses
}
final case class GetDescriptorInfoResult(
descriptor: String,

View File

@ -2,12 +2,11 @@ package org.bitcoins.chain.blockchain
import org.bitcoins.chain.models.BlockHeaderDb
import scala.collection.{mutable, IndexedSeqLike}
import scala.collection.mutable
/** @inheritdoc */
case class Blockchain(headers: Vector[BlockHeaderDb])
extends IndexedSeqLike[BlockHeaderDb, Vector[BlockHeaderDb]]
with BaseBlockChain {
extends BaseBlockChain {
protected[blockchain] def compObjectfromHeaders(
headers: scala.collection.immutable.Seq[BlockHeaderDb]): Blockchain =

View File

@ -2,20 +2,13 @@ package org.bitcoins.chain.blockchain
import org.bitcoins.chain.models.BlockHeaderDb
import scala.collection.immutable.IndexedSeq
/** @inheritdoc */
case class Blockchain(headers: Vector[BlockHeaderDb])
extends IndexedSeq[BlockHeaderDb]
with BaseBlockChain {
case class Blockchain(headers: Vector[BlockHeaderDb]) extends BaseBlockChain {
protected[blockchain] def compObjectfromHeaders(
headers: scala.collection.immutable.Seq[BlockHeaderDb]) =
Blockchain.fromHeaders(headers)
/** @inheritdoc */
override def seq = this
}
object Blockchain extends BaseBlockChainCompObject {

View File

@ -7,6 +7,7 @@ import org.bitcoins.chain.ChainVerificationLogger
import org.bitcoins.chain.validation.TipUpdateResult
import org.bitcoins.chain.validation.TipValidation
import org.bitcoins.core.crypto.DoubleSha256DigestBE
import org.bitcoins.core.util.SeqWrapper
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(
headers: scala.collection.immutable.Seq[BlockHeaderDb]): Blockchain
@ -43,12 +44,10 @@ private[blockchain] trait BaseBlockChain {
/** The height of the chain */
val height: Int = tip.height
val length: Int = headers.length
def apply(idx: Int): BlockHeaderDb = headers(idx)
def headers: Vector[BlockHeaderDb]
override protected lazy val wrapped: Vector[BlockHeaderDb] = headers
def find(predicate: BlockHeaderDb => Boolean): Option[BlockHeaderDb]
/** Finds a block header at a given height */

View File

@ -74,8 +74,8 @@ class TransactionTest extends BitcoinSUnitTest {
val rawTx = TestUtil.rawTransaction
val tx = Transaction(rawTx)
//size is in bytes so divide by 2
assert(tx.size == tx.totalSize)
tx.size must be(rawTx.size / 2)
assert(tx.byteSize == tx.totalSize)
tx.byteSize must be(rawTx.size / 2)
}
it must "serialize and deserialize a tx" in {
@ -132,7 +132,7 @@ class TransactionTest extends BitcoinSUnitTest {
"0200000000010140d43a99926d43eb0e619bf0b3d83b4a31f60c176beecfb9d35bf45e54d0f7420100000017160014a4b4ca48de0b3fffc15404a1acdc8dbaae226955ffffffff0100e1f5050000000017a9144a1154d50b03292b3024370901711946cb7cccc387024830450221008604ef8f6d8afa892dee0f31259b6ce02dd70c545cfcfed8148179971876c54a022076d771d6e91bed212783c9b06e0de600fab2d518fad6f15a2b191d7fbd262a3e0121039d25ab79f41f75ceaf882411fd41fa670a4c672c23ffaf0e361a969cde0692e800000000"
val tx2 = WitnessTransaction(hex2)
tx2.hex must be(hex2)
tx2.size must be(216)
tx2.byteSize must be(216)
tx2.weight must be(534)
tx2.vsize must be(134)
tx2.baseSize must be(106)

View File

@ -32,7 +32,7 @@ class RawTransactionInputParserTest extends FlatSpec with MustMatchers {
it must "find the correct size for an input" in {
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 {

View File

@ -62,7 +62,7 @@ class RawTransactionOutPointParserTest extends BitcoinSUnitTest {
val rawOutPoint =
"85d6b0da2edf96b282030d3f4f79d14cc8c882cfef1b3064170c850660317de100000000"
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 {

View File

@ -50,7 +50,7 @@ object BIP39Seed extends Factory[BIP39Seed] {
password: String = EMPTY_PASSWORD): BIP39Seed = {
val salt = s"mnemonic$password"
val words = mnemonic.words.mkString(" ")
val words = mnemonic.mkString(" ")
val encodedBytes = PBKDF2
.withSha512(words, salt, ITERATION_COUNT, DERIVED_KEY_LENGTH)

View File

@ -92,7 +92,7 @@ sealed abstract class ExtKey extends NetworkElement {
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
*/
def deriveChildPrivKey(path: BIP32Path): ExtPrivateKey = {
path.path.foldLeft(this)((accum: ExtPrivateKey, curr: BIP32Node) =>
path.foldLeft(this)((accum: ExtPrivateKey, curr: BIP32Node) =>
accum.deriveChildPrivKey(curr.toUInt32))
}
@ -326,8 +326,8 @@ object ExtPrivateKey extends Factory[ExtPrivateKey] {
chaincode,
masterPrivKey)
path.path.foldLeft(root)((accum, curr) =>
accum.deriveChildPrivKey(curr.toUInt32))
path.foldLeft(root)(
(accum, curr) => accum.deriveChildPrivKey(curr.toUInt32))
}
/** Generates a extended private key from the provided seed and version */

View File

@ -2,7 +2,7 @@ package org.bitcoins.core.crypto
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 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]]
* HD wallet.
*/
sealed abstract class MnemonicCode extends MaskedToString {
sealed abstract class MnemonicCode
extends SeqWrapper[String]
with MaskedToString {
require(
MnemonicCode.VALID_LENGTHS.contains(words.length), {
val validLengths = MnemonicCode.VALID_LENGTHS.mkString(", ")
@ -51,6 +53,8 @@ sealed abstract class MnemonicCode extends MaskedToString {
*/
def words: Vector[String]
override protected lazy val wrapped: Vector[String] = words
/**
* Returns the entropy initially provided to construct
* this mnemonic code

View File

@ -86,7 +86,7 @@ sealed trait WitnessTxSigComponent extends TxSigComponent {
override def transaction: WitnessTransaction
def witness: ScriptWitness = transaction.witness.witnesses(inputIndex.toInt)
def witness: ScriptWitness = transaction.witness(inputIndex.toInt)
def witnessVersion: WitnessVersion

View File

@ -2,11 +2,12 @@ package org.bitcoins.core.hd
import org.bitcoins.core.crypto.ExtKey
import org.bitcoins.core.number.UInt32
import org.bitcoins.core.util.Factory
import org.bitcoins.core.util.{Factory, SeqWrapper}
import scodec.bits.ByteVector
abstract class BIP32Path {
abstract class BIP32Path extends SeqWrapper[BIP32Node] {
def path: Vector[BIP32Node]
override protected lazy val wrapped: Vector[BIP32Node] = path
/**
* 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
* }}}
*/
def diff(that: BIP32Path): Option[BIP32Path] = {
import that.{path => otherPath}
def diff(otherPath: BIP32Path): Option[BIP32Path] = {
if (path.length > otherPath.length) {
None
} else if (path == otherPath) {
} else if (this.toVector == otherPath.toVector) {
Some(BIP32Path.empty)
} else {
val lengthDiff = otherPath.length - path.length
@ -64,7 +64,7 @@ abstract class BIP32Path {
// append the next divergent element to
// the acummed value
case (Some(accum), ((None, their), _)) =>
Some(BIP32Path(accum.path :+ their))
Some(BIP32Path((accum :+ their).toVector))
// we've not yet reached the start of diverging
// paths

View File

@ -53,6 +53,6 @@ object HDAccount {
}
def isSameAccount(bip32Path: BIP32Path, account: HDAccount): Boolean = {
isSameAccount(bip32Path.path, account)
isSameAccount(bip32Path.toVector, account)
}
}

View File

@ -15,7 +15,7 @@ sealed abstract class CompactSizeUInt extends NetworkElement {
/** The number parsed from VarInt. */
def num: UInt64
override def hex = size match {
override def hex = byteSize match {
case 1 => BitcoinSUtil.flipEndianness(num.hex.slice(14, 16))
case 3 => "fd" + BitcoinSUtil.flipEndianness(num.hex.slice(12, 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] {
private case class CompactSizeUIntImpl(num: UInt64, override val size: Long)
private case class CompactSizeUIntImpl(
num: UInt64,
override val byteSize: Long)
extends CompactSizeUInt
val zero: CompactSizeUInt = CompactSizeUInt(UInt64.zero)

View File

@ -11,7 +11,7 @@ import scodec.bits.ByteVector
trait NetworkElement extends Any {
/** The size of the NetworkElement in bytes. */
def size: Long = bytes.size
def byteSize: Long = bytes.size
/** The hexadecimal representation of the NetworkElement */
def hex: String = bytes.toHex

View File

@ -3,7 +3,7 @@ package org.bitcoins.core.protocol.ln
import org.bitcoins.core.number.{UInt5, UInt8}
import org.bitcoins.core.protocol.NetworkElement
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 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]]
*/
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(
@ -26,6 +28,8 @@ sealed abstract class LnTaggedFields extends NetworkElement {
def tags: Vector[LnTag]
override protected lazy val wrapped: Vector[LnTag] = tags
def tag[T <: LnTag: ClassTag]: Option[T] =
tags.collectFirst {
case t: T => t

View File

@ -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.util.LnUtil
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 scala.annotation.tailrec
@ -19,7 +19,7 @@ import scala.annotation.tailrec
* One of the tagged fields on a Lightning Network invoice
* [[https://github.com/lightningnetwork/lightning-rfc/blob/master/11-payment-encoding.md#tagged-fields]]
*/
sealed abstract class LnTag {
sealed trait LnTag {
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
@ -247,7 +250,7 @@ object LnTag {
accum
} else {
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))
}
}

View File

@ -71,7 +71,7 @@ sealed abstract class Transaction extends NetworkElement {
* [[https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#Transaction_size_calculations]]
*/
def baseSize: Long = this match {
case btx: BaseTransaction => btx.size
case btx: BaseTransaction => btx.byteSize
case wtx: WitnessTransaction =>
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 {
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 {
require(
inputs.length == witness.witnesses.length,
s"Must have same amount of inputs and witnesses in witness tx, inputs=${inputs.length} witnesses=${witness.witnesses.length}"
inputs.length == witness.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 */
@ -153,7 +153,7 @@ sealed abstract class WitnessTransaction extends Transaction {
*/
override def weight: Long = {
val base = BaseTransaction(version, inputs, outputs, lockTime)
base.size * 3 + size
base.byteSize * 3 + byteSize
}
override def bytes = RawWitnessTransactionParser.write(this)

View File

@ -11,7 +11,7 @@ case class TransactionOutput(value: CurrencyUnit, scriptPubKey: ScriptPubKey)
extends NetworkElement {
//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)
}

View File

@ -3,7 +3,7 @@ package org.bitcoins.core.protocol.transaction
import org.bitcoins.core.protocol.NetworkElement
import org.bitcoins.core.protocol.script.{EmptyScriptWitness, ScriptWitness}
import org.bitcoins.core.serializers.transaction.RawTransactionWitnessParser
import org.bitcoins.core.util.BitcoinSUtil
import org.bitcoins.core.util.{BitcoinSUtil, SeqWrapper}
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
* [[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]
override protected val wrapped: Vector[ScriptWitness] = witnesses
override def bytes: ByteVector = {
RawTransactionWitnessParser.write(this)

View File

@ -387,7 +387,7 @@ case class PSBT(
if (!previousElements.exists(_.key == expectedBytes)) {
val fp =
if (extKey.fingerprint == ExtKey.masterFingerprint) {
extKey.deriveChildPubKey(path.path.head).get.fingerprint
extKey.deriveChildPubKey(path.head).get.fingerprint
} else {
extKey.fingerprint
}
@ -579,7 +579,7 @@ case class PSBT(
case Some(
InputPSBTRecord.FinalizedScriptWitness(scriptWitness)) =>
TransactionWitness(
witness.witnesses.updated(index, scriptWitness))
witness.updated(index, scriptWitness).toVector)
}
}
WitnessTransaction(transaction.version,

View File

@ -13,7 +13,7 @@ import org.bitcoins.core.protocol.transaction.{
WitnessTransaction
}
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.utxo._
import scodec.bits.ByteVector
@ -87,11 +87,13 @@ sealed trait PSBTMapFactory[
}
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.PSBTGlobalKeyId._
require(getRecords(UnsignedTransactionKeyId).nonEmpty,
"A GlobalPSBTMap must have a Unsigned Transaction")
override val wrapped: Vector[GlobalPSBTRecord] = elements
def unsignedTransaction: UnsignedTransaction = {
getRecords(UnsignedTransactionKeyId).head
@ -150,11 +152,14 @@ object GlobalPSBTMap extends PSBTMapFactory[GlobalPSBTRecord, GlobalPSBTMap] {
}
case class InputPSBTMap(elements: Vector[InputPSBTRecord])
extends PSBTMap[InputPSBTRecord] {
extends SeqWrapper[InputPSBTRecord]
with PSBTMap[InputPSBTRecord] {
require(
this.witnessUTXOOpt.isEmpty || this.nonWitnessOrUnknownUTXOOpt.isEmpty,
"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.PSBTInputKeyId._
@ -642,7 +647,7 @@ object InputPSBTMap extends PSBTMapFactory[InputPSBTRecord, InputPSBTMap] {
sigComponent.transaction match {
case _: BaseTransaction => InputPSBTMap(utxos ++ Vector(scriptSig))
case wtx: WitnessTransaction =>
val witness = wtx.witness.witnesses(sigComponent.inputIndex.toInt)
val witness = wtx.witness(sigComponent.inputIndex.toInt)
val scriptWitness = FinalizedScriptWitness(witness)
val finalizedSigs =
if (witness != EmptyScriptWitness) {
@ -721,10 +726,13 @@ object InputPSBTMap extends PSBTMapFactory[InputPSBTRecord, InputPSBTMap] {
override def recordFactory: Factory[InputPSBTRecord] = InputPSBTRecord
}
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.PSBTOutputKeyId._
override val wrapped: Vector[OutputPSBTRecord] = elements
def redeemScriptOpt: Option[RedeemScript] = {
getRecords(RedeemScriptKeyId).headOption
}

View File

@ -39,11 +39,11 @@ object PSBTRecord {
if (keyCmpctUInt.toLong == 0) {
(ByteVector.empty, ByteVector.empty)
} else {
val key = bytes.drop(keyCmpctUInt.size).take(keyCmpctUInt.toLong)
val valueBytes = bytes.drop(keyCmpctUInt.size + keyCmpctUInt.toLong)
val key = bytes.drop(keyCmpctUInt.byteSize).take(keyCmpctUInt.toLong)
val valueBytes = bytes.drop(keyCmpctUInt.byteSize + keyCmpctUInt.toLong)
val valueCmpctUInt = CompactSizeUInt.parse(valueBytes)
val value = valueBytes
.drop(valueCmpctUInt.size)
.drop(valueCmpctUInt.byteSize)
.take(valueCmpctUInt.toLong)
(key, value)
@ -74,8 +74,8 @@ object GlobalPSBTRecord extends Factory[GlobalPSBTRecord] {
derivationPath: BIP32Path)
extends GlobalPSBTRecord {
require(
derivationPath.path.length == xpub.depth.toInt,
s"Derivation path length does not match xpubkey depth, difference: ${derivationPath.path.length - xpub.depth.toInt}"
derivationPath.length == xpub.depth.toInt,
s"Derivation path length does not match xpubkey depth, difference: ${derivationPath.length - xpub.depth.toInt}"
)
require(
masterFingerprint.length == 4,
@ -83,7 +83,7 @@ object GlobalPSBTRecord extends Factory[GlobalPSBTRecord] {
override type KeyId = XPubKeyKeyId.type
override val key: ByteVector = ByteVector(XPubKeyKeyId.byte) ++ xpub.bytes
override val value: ByteVector = derivationPath.path
override val value: ByteVector = derivationPath
.foldLeft(masterFingerprint)(_ ++ _.toUInt32.bytesLE)
}
@ -155,7 +155,8 @@ object InputPSBTRecord extends Factory[InputPSBTRecord] {
pubKey: ECPublicKey,
signature: ECDigitalSignature)
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 val key: ByteVector = ByteVector(PartialSignatureKeyId.byte) ++ pubKey.bytes
@ -186,12 +187,13 @@ object InputPSBTRecord extends Factory[InputPSBTRecord] {
masterFingerprint: ByteVector,
path: BIP32Path)
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 val key: ByteVector = ByteVector(BIP32DerivationPathKeyId.byte) ++ pubKey.bytes
override val value: ByteVector =
path.path.foldLeft(masterFingerprint)(_ ++ _.toUInt32.bytesLE)
path.foldLeft(masterFingerprint)(_ ++ _.toUInt32.bytesLE)
}
case class FinalizedScriptSig(scriptSig: ScriptSignature)
@ -307,12 +309,13 @@ object OutputPSBTRecord extends Factory[OutputPSBTRecord] {
masterFingerprint: ByteVector,
path: BIP32Path)
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 val key: ByteVector = ByteVector(BIP32DerivationPathKeyId.byte) ++ pubKey.bytes
override val value: ByteVector =
path.path.foldLeft(masterFingerprint)(_ ++ _.toUInt32.bytesLE)
path.foldLeft(masterFingerprint)(_ ++ _.toUInt32.bytesLE)
}
case class Unknown(key: ByteVector, value: ByteVector)

View File

@ -1130,17 +1130,11 @@ sealed abstract class ScriptInterpreter extends BitcoinSLogger {
case b: BaseTxSigComponent =>
b.transaction match {
case wtx: WitnessTransaction =>
wtx.witness
.witnesses(txSigComponent.inputIndex.toInt)
.stack
.nonEmpty
wtx.witness(txSigComponent.inputIndex.toInt).stack.nonEmpty
case _: BaseTransaction => false
}
case r: WitnessTxSigComponentRebuilt =>
r.transaction.witness
.witnesses(txSigComponent.inputIndex.toInt)
.stack
.nonEmpty
r.transaction.witness(txSigComponent.inputIndex.toInt).stack.nonEmpty
}
if (unexpectedWitness)

View File

@ -19,7 +19,7 @@ sealed abstract class RawSerializerHelper {
bytes: ByteVector,
constructor: ByteVector => T): (Seq[T], ByteVector) = {
val count = CompactSizeUInt.parse(bytes)
val payload = bytes.splitAt(count.size.toInt)._2
val payload = bytes.splitAt(count.byteSize.toInt)._2
var counter = 0
val b = Vector.newBuilder[T]
@tailrec
@ -28,7 +28,7 @@ sealed abstract class RawSerializerHelper {
remaining
} else {
val parsed = constructor(remaining)
val (_, newRemaining) = remaining.splitAt(parsed.size)
val (_, newRemaining) = remaining.splitAt(parsed.byteSize)
counter = counter + 1
b.+=(parsed)

View File

@ -15,9 +15,9 @@ sealed abstract class RawBloomFilterSerializer
override def read(bytes: ByteVector): BloomFilter = {
val filterSize = CompactSizeUInt.parseCompactSizeUInt(bytes)
val filter = bytes.slice(filterSize.size.toInt,
filterSize.size.toInt + filterSize.num.toInt)
val hashFuncsIndex = (filterSize.size + filterSize.num.toInt).toInt
val filter = bytes.slice(filterSize.byteSize.toInt,
filterSize.byteSize.toInt + filterSize.num.toInt)
val hashFuncsIndex = (filterSize.byteSize + filterSize.num.toInt).toInt
val hashFuncs = UInt32(
bytes.slice(hashFuncsIndex, hashFuncsIndex + 4).reverse)
val tweakIndex = hashFuncsIndex + 4

View File

@ -16,7 +16,7 @@ trait RawAddrMessageSerializer extends RawBitcoinSerializer[AddrMessage] {
override def read(bytes: ByteVector): AddrMessage = {
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, _) =
parseNetworkIpAddresses(ipCount, ipAddressBytes)
AddrMessage(ipCount, networkIpAddresses)
@ -48,7 +48,7 @@ trait RawAddrMessageSerializer extends RawBitcoinSerializer[AddrMessage] {
val networkIpAddress =
RawNetworkIpAddressSerializer.read(remainingBytes)
val newRemainingBytes =
remainingBytes.slice(networkIpAddress.size, remainingBytes.size)
remainingBytes.slice(networkIpAddress.byteSize, remainingBytes.size)
loop(remainingAddresses - 1,
newRemainingBytes,
networkIpAddress :: accum)

View File

@ -14,7 +14,7 @@ trait RawFilterAddMessageSerializer
override def read(bytes: ByteVector): FilterAddMessage = {
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)
}

View File

@ -20,7 +20,7 @@ trait RawGetBlocksMessageSerializer
val version = ProtocolVersion(bytes.take(4))
val hashCount =
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 (blockHashHeaders, remainingBytes) =
parseBlockHeaders(blockHeaderBytesStopHash, hashCount)

View File

@ -15,7 +15,7 @@ trait RawGetHeadersMessageSerializer
val version = ProtocolVersion(bytes.take(4))
val hashCount =
CompactSizeUInt.parseCompactSizeUInt(bytes.slice(4, bytes.length))
val hashesStartIndex = (hashCount.size + 4).toInt
val hashesStartIndex = (hashCount.byteSize + 4).toInt
val (hashes, remainingBytes) =
parseHashes(bytes.slice(hashesStartIndex, bytes.length), hashCount)
val hashStop = DoubleSha256Digest(remainingBytes.take(32))

View File

@ -12,7 +12,7 @@ trait RawHeadersMessageSerializer extends RawBitcoinSerializer[HeadersMessage] {
def read(bytes: ByteVector): HeadersMessage = {
val compactSizeUInt = CompactSizeUInt.parseCompactSizeUInt(bytes)
val headerStartIndex = compactSizeUInt.size.toInt
val headerStartIndex = compactSizeUInt.byteSize.toInt
val headerBytes = bytes.slice(headerStartIndex, bytes.length)
val headers = parseBlockHeaders(headerBytes, compactSizeUInt)
HeadersMessage(compactSizeUInt, headers)

View File

@ -19,7 +19,7 @@ trait RawInventoryMessageSerializer
*/
override def read(bytes: ByteVector): InventoryMessage = {
val inventoryCount = CompactSizeUInt.parseCompactSizeUInt(bytes)
val inventoryStart = inventoryCount.size.toInt
val inventoryStart = inventoryCount.byteSize.toInt
val remainingBytes = bytes.slice(inventoryStart, bytes.size)
val (inventories, _) = parseInventories(remainingBytes, inventoryCount)
InventoryMessage(inventoryCount, inventories)

View File

@ -11,24 +11,24 @@ trait RawRejectMessageSerializer extends RawBitcoinSerializer[RejectMessage] {
def read(bytes: ByteVector): RejectMessage = {
val messageSize = CompactSizeUInt.parseCompactSizeUInt(bytes)
val message: String = bytes
.slice(messageSize.size.toInt,
messageSize.size.toInt +
.slice(messageSize.byteSize.toInt,
messageSize.byteSize.toInt +
messageSize.num.toInt)
.toArray
.map(_.toChar)
.mkString
val code: Char = bytes(messageSize.size.toInt + messageSize.num.toInt).toChar
val reasonSizeStartIndex = messageSize.size.toInt + messageSize.num.toInt + 1
val code: Char = bytes(messageSize.byteSize.toInt + messageSize.num.toInt).toChar
val reasonSizeStartIndex = messageSize.byteSize.toInt + messageSize.num.toInt + 1
val reasonSize = CompactSizeUInt.parseCompactSizeUInt(
bytes.slice(reasonSizeStartIndex.toInt, bytes.size))
val reason = bytes
.slice(
(reasonSizeStartIndex + reasonSize.size).toInt,
(reasonSizeStartIndex + reasonSize.size.toInt + reasonSize.num.toInt))
(reasonSizeStartIndex + reasonSize.byteSize).toInt,
(reasonSizeStartIndex + reasonSize.byteSize.toInt + reasonSize.num.toInt))
.toArray
.map(_.toChar)
.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)
RejectMessage(messageSize, message, code, reasonSize, reason, extra)
}

View File

@ -43,7 +43,7 @@ trait RawVersionMessageSerializer
val userAgentSize =
CompactSizeUInt.parseCompactSizeUInt(bytes.slice(80, bytes.size))
val userAgentBytesStartIndex = 80 + userAgentSize.size.toInt
val userAgentBytesStartIndex = 80 + userAgentSize.byteSize.toInt
val userAgentBytes = bytes.slice(
userAgentBytesStartIndex,

View File

@ -17,7 +17,7 @@ sealed abstract class RawScriptWitnessParser
def read(bytes: ByteVector): ScriptWitness = {
//first byte is the number of stack items
val stackSize = CompactSizeUInt.parseCompactSizeUInt(bytes)
val (_, stackBytes) = bytes.splitAt(stackSize.size.toInt)
val (_, stackBytes) = bytes.splitAt(stackSize.byteSize.toInt)
@tailrec
def loop(
remainingBytes: ByteVector,
@ -27,7 +27,7 @@ sealed abstract class RawScriptWitnessParser
else {
val elementSize = CompactSizeUInt.parseCompactSizeUInt(remainingBytes)
val (_, stackElementBytes) =
remainingBytes.splitAt(elementSize.size.toInt)
remainingBytes.splitAt(elementSize.byteSize.toInt)
val stackElement = stackElementBytes.take(elementSize.num.toInt)
val (_, newRemainingBytes) =
stackElementBytes.splitAt(stackElement.size)

View File

@ -38,7 +38,7 @@ sealed abstract class RawTransactionWitnessParser {
}
def write(witness: TransactionWitness): ByteVector = {
witness.witnesses.foldLeft(ByteVector.empty)(_ ++ _.bytes)
witness.foldLeft(ByteVector.empty)(_ ++ _.bytes)
}
}

View File

@ -588,7 +588,8 @@ trait BitcoinScriptUtil extends BitcoinSLogger {
//but scala collections don't allow you to use 'slice' with longs
val len = Try(compactSizeUInt.num.toInt).getOrElse(Int.MaxValue)
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)
f(script.toVector)
}

View 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)
}

View File

@ -293,7 +293,7 @@ object BitcoinSignerSingle {
btx.lockTime,
transactionWitness)
case wtx: WitnessTransaction =>
wtx.witness.witnesses(inputIndex) match {
wtx.witness(inputIndex) match {
case EmptyScriptWitness =>
val transactionWitnessOpt =
psbt
@ -740,8 +740,9 @@ sealed abstract class P2WPKHSigner
val pubKey = signer.publicKey
val unsignedTxWitness = TransactionWitness(
wtx.witness.witnesses
.updated(inputIndex.toInt, spendingInfoToSatisfy.scriptWitness))
wtx.witness
.updated(inputIndex.toInt, spendingInfoToSatisfy.scriptWitness)
.toVector)
val unsignedWtx = WitnessTransaction(wtx.version,
wtx.inputs,