From abcd7c5d6dc99f5fc837e7ab2172386717c3abfb Mon Sep 17 00:00:00 2001 From: Torkel Rogstad Date: Mon, 7 Jan 2019 16:23:29 +0100 Subject: [PATCH] Fixes some Scaladocs (#286) * Fixes some Scaladocs * ran scalafmt * ran test:scalafmt --- .../bitcoins/core/crypto/TxSigComponent.scala | 54 +- .../org/bitcoins/core/protocol/Address.scala | 22 +- .../protocol/blockchain/ChainParams.scala | 9 +- .../blockchain/PartialMerkleTree.scala | 33 +- .../core/protocol/script/Script.scala | 6 +- .../core/protocol/script/ScriptFactory.scala | 13 +- .../core/protocol/script/ScriptPubKey.scala | 495 ++++++++++++------ .../protocol/script/ScriptSignature.scala | 226 +++++--- .../core/protocol/script/ScriptWitness.scala | 7 +- .../interpreter/ScriptInterpreter.scala | 3 +- .../script/RawScriptPubKeyParser.scala | 9 +- .../script/RawScriptSignatureParser.scala | 9 +- .../core/util/BitcoinScriptUtil.scala | 35 +- .../core/wallet/builder/TxBuilderError.scala | 70 ++- .../core/wallet/signer/FundingInfo.scala | 7 +- .../bitcoins/core/wallet/signer/Signer.scala | 17 +- .../bitcoins/core/gen/ScriptGenerators.scala | 132 ++--- .../bitcoins/core/gen/WitnessGenerators.scala | 120 ++--- .../org/bitcoins/core/gen/ln/LnRouteGen.scala | 5 +- 19 files changed, 790 insertions(+), 482 deletions(-) diff --git a/core/src/main/scala/org/bitcoins/core/crypto/TxSigComponent.scala b/core/src/main/scala/org/bitcoins/core/crypto/TxSigComponent.scala index b4de413b61..e48739b518 100644 --- a/core/src/main/scala/org/bitcoins/core/crypto/TxSigComponent.scala +++ b/core/src/main/scala/org/bitcoins/core/crypto/TxSigComponent.scala @@ -10,7 +10,8 @@ import scala.util.{Failure, Success, Try} /** * Created by chris on 4/6/16. - * Represents a transaction whose input is being checked against the spending conditions of a [[ScriptPubKey]] + * Represents a transaction whose input is being checked against the spending conditions of a + * [[org.bitcoins.core.protocol.script.ScriptPubKey ScriptPubKey]] */ sealed abstract class TxSigComponent { @@ -31,7 +32,7 @@ sealed abstract class TxSigComponent { /** The scriptPubKey for which the input is being checked against */ def scriptPubKey: ScriptPubKey = output.scriptPubKey - /** The amount of [[CurrencyUnit]] we are spending in this TxSigComponent */ + /** The amount of [[org.bitcoins.core.currency.CurrencyUnit CurrencyUnit]] we are spending in this TxSigComponent */ def amount: CurrencyUnit = output.value /** The flags that are needed to verify if the signature is correct */ @@ -42,19 +43,24 @@ sealed abstract class TxSigComponent { } /** - * The [[TxSigComponent]] used to evaluate the the original Satoshi transaction digest algorithm. - * Basically this is every spk that is not a [[WitnessScriptPubKey]] EXCEPT in the case of a - * P2SH(witness script) [[ScriptPubKey]] + * The [[org.bitcoins.core.crypto.TxSigComponent TxSigComponent]] + * used to evaluate the the original Satoshi transaction digest algorithm. + * Basically this is every spk that is not a + * [[org.bitcoins.core.protocol.script.WitnessScriptPubKey WitnessScriptPubKey]] EXCEPT in the case of a + * P2SH(witness script) [[org.bitcoins.core.protocol.script.ScriptPubKey ScriptPubKey]] */ sealed abstract class BaseTxSigComponent extends TxSigComponent { override def sigVersion = SigVersionBase } /** - * The [[TxSigComponent]] used to represent all the components necessarily for BIP143 - * [[https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki]] - * Examples of these [[ScriptPubKey]]'s are [[P2WPKHWitnessSPKV0]], - * [[P2WSHWitnessSPKV0]], and P2SH(witness script) + * The [[org.bitcoins.core.crypto.TxSigComponent TxSigComponent]] + * used to represent all the components necessarily for + * [[https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki BIP143]]. + * Examples of these [[org.bitcoins.core.protocol.script.ScriptPubKey ScriptPubKey]]'s + * are [[org.bitcoins.core.protocol.script.P2WPKHWitnessV0 P2WPKHWitnessSPKV0]], + * [[org.bitcoins.core.protocol.script.P2WSHWitnessSPKV0 P2WSHWitnessSPKV0]], + * and P2SH(witness script) */ sealed abstract class WitnessTxSigComponent extends TxSigComponent { @@ -67,7 +73,9 @@ sealed abstract class WitnessTxSigComponent extends TxSigComponent { override def sigVersion = SigVersionWitnessV0 } -/** This represents checking the [[WitnessTransaction]] against a [[P2WPKHWitnessSPKV0]] or a [[P2WSHWitnessSPKV0]] */ +/** This represents checking the [[org.bitcoins.core.protocol.transaction.WitnessTransaction WitnessTransaction]] + * against a [[org.bitcoins.core.protocol.script.P2WPKHWitnessSPKV0 P2WPKHWitnessSPKV0]] or a + * [[org.bitcoins.core.protocol.script.P2WSHWitnessSPKV0 P2WSHWitnessSPKV0]] */ sealed abstract class WitnessTxSigComponentRaw extends WitnessTxSigComponent { override def scriptPubKey: WitnessScriptPubKey = output.scriptPubKey.asInstanceOf[WitnessScriptPubKey] @@ -77,7 +85,8 @@ sealed abstract class WitnessTxSigComponentRaw extends WitnessTxSigComponent { } } -/** This represents checking the [[WitnessTransaction]] against a P2SH(P2WSH) or P2SH(P2WPKH) scriptPubKey */ +/** This represents checking the [[org.bitcoins.core.protocol.transaction.WitnessTransaction WitnessTransaction]] + * against a P2SH(P2WSH) or P2SH(P2WPKH) scriptPubKey */ sealed abstract class WitnessTxSigComponentP2SH extends WitnessTxSigComponent { override def scriptPubKey: P2SHScriptPubKey = output.scriptPubKey.asInstanceOf[P2SHScriptPubKey] @@ -97,8 +106,8 @@ sealed abstract class WitnessTxSigComponentP2SH extends WitnessTxSigComponent { case x @ (_: P2PKScriptPubKey | _: P2PKHScriptPubKey | _: MultiSignatureScriptPubKey | _: P2SHScriptPubKey | _: CSVScriptPubKey | _: CLTVScriptPubKey | - _: NonStandardScriptPubKey | - _: WitnessCommitment | EmptyScriptPubKey) => + _: NonStandardScriptPubKey | _: WitnessCommitment | + EmptyScriptPubKey) => Failure(new IllegalArgumentException( "Must have a witness scriptPubKey as redeemScript for P2SHScriptPubKey in WitnessTxSigComponentP2SH, got: " + x)) @@ -114,10 +123,14 @@ sealed abstract class WitnessTxSigComponentP2SH extends WitnessTxSigComponent { } /** - * This represents a 'rebuilt' [[ScriptPubKey]] that was constructed from [[WitnessScriptPubKey]] - * After the [[ScriptPubKey]] is rebuilt, we need to use that rebuilt scriptpubkey to evaluate the [[ScriptSignature]] - * See BIP141 for more info on rebuilding P2WSH and P2WPKH scriptpubkeys - * [[https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#witness-program]] + * This represents a 'rebuilt' [[org.bitcoins.core.protocol.script.ScriptPubKey ScriptPubKey]] + * that was constructed from [[org.bitcoins.core.protocol.script.WitnessScriptPubKey WitnessScriptPubKey]] + * After the + * [[org.bitcoins.core.protocol.script.ScriptPubKey ScriptPubKey]] is rebuilt, we need to use that rebuilt + * scriptpubkey to evaluate the [[org.bitcoins.core.protocol.script.ScriptSignature ScriptSignature]] + * See + * [[https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#witness-program BIP141]] + * for more info on rebuilding P2WSH and P2WPKH scriptpubkeys */ sealed abstract class WitnessTxSigComponentRebuilt extends TxSigComponent { override def transaction: WitnessTransaction @@ -194,8 +207,7 @@ object WitnessTxSigComponentRaw { case x @ (_: P2PKScriptPubKey | _: P2PKHScriptPubKey | _: MultiSignatureScriptPubKey | _: P2SHScriptPubKey | _: LockTimeScriptPubKey | _: NonStandardScriptPubKey | - _: WitnessCommitment | - EmptyScriptPubKey) => + _: WitnessCommitment | EmptyScriptPubKey) => throw new IllegalArgumentException( s"Cannot create a WitnessTxSigComponentRaw with a spk of $x") } @@ -222,8 +234,8 @@ object WitnessTxSigComponentP2SH { WitnessTxSigComponentP2SHImpl(transaction, inputIndex, output, flags) case x @ (_: P2PKScriptPubKey | _: P2PKHScriptPubKey | _: MultiSignatureScriptPubKey | _: LockTimeScriptPubKey | - _: NonStandardScriptPubKey | - _: WitnessCommitment | _: WitnessScriptPubKey | EmptyScriptPubKey) => + _: NonStandardScriptPubKey | _: WitnessCommitment | + _: WitnessScriptPubKey | EmptyScriptPubKey) => throw new IllegalArgumentException( s"Cannot create a WitnessTxSigComponentP2SH with a spk of $x") } diff --git a/core/src/main/scala/org/bitcoins/core/protocol/Address.scala b/core/src/main/scala/org/bitcoins/core/protocol/Address.scala index 7d32d622ac..b4fca3cfaa 100644 --- a/core/src/main/scala/org/bitcoins/core/protocol/Address.scala +++ b/core/src/main/scala/org/bitcoins/core/protocol/Address.scala @@ -223,9 +223,8 @@ object Bech32Address extends AddressFactory[Bech32Address] { case x @ (_: P2PKScriptPubKey | _: P2PKHScriptPubKey | _: MultiSignatureScriptPubKey | _: P2SHScriptPubKey | _: LockTimeScriptPubKey | _: WitnessScriptPubKey | - _: NonStandardScriptPubKey | - _: WitnessCommitment | _: UnassignedWitnessScriptPubKey | - EmptyScriptPubKey) => + _: NonStandardScriptPubKey | _: WitnessCommitment | + _: UnassignedWitnessScriptPubKey | EmptyScriptPubKey) => Failure( new IllegalArgumentException( "Cannot create a address for the scriptPubKey: " + x)) @@ -328,9 +327,8 @@ object P2PKHAddress extends AddressFactory[P2PKHAddress] { case p2pkh: P2PKHScriptPubKey => Success(P2PKHAddress(p2pkh, np)) case x @ (_: P2PKScriptPubKey | _: MultiSignatureScriptPubKey | _: P2SHScriptPubKey | _: LockTimeScriptPubKey | _: WitnessScriptPubKey | - _: NonStandardScriptPubKey | - _: WitnessCommitment | _: UnassignedWitnessScriptPubKey | - EmptyScriptPubKey) => + _: NonStandardScriptPubKey | _: WitnessCommitment | + _: UnassignedWitnessScriptPubKey | EmptyScriptPubKey) => Failure( new IllegalArgumentException( "Cannot create a address for the scriptPubKey: " + x)) @@ -398,9 +396,9 @@ object P2SHAddress extends AddressFactory[P2SHAddress] { case p2sh: P2SHScriptPubKey => Success(P2SHAddress(p2sh, np)) case x @ (_: P2PKScriptPubKey | _: P2PKHScriptPubKey | _: MultiSignatureScriptPubKey | _: LockTimeScriptPubKey | - _: WitnessScriptPubKey | - _: NonStandardScriptPubKey | _: WitnessCommitment | - _: UnassignedWitnessScriptPubKey | EmptyScriptPubKey) => + _: WitnessScriptPubKey | _: NonStandardScriptPubKey | + _: WitnessCommitment | _: UnassignedWitnessScriptPubKey | + EmptyScriptPubKey) => Failure( new IllegalArgumentException( "Cannot create a address for the scriptPubKey: " + x)) @@ -439,9 +437,9 @@ object BitcoinAddress extends AddressFactory[BitcoinAddress] { case p2sh: P2SHScriptPubKey => Success(P2SHAddress(p2sh, np)) case witSPK: WitnessScriptPubKey => Success(Bech32Address(witSPK, np)) case x @ (_: P2PKScriptPubKey | _: MultiSignatureScriptPubKey | - _: LockTimeScriptPubKey | - _: NonStandardScriptPubKey | _: WitnessCommitment | - _: UnassignedWitnessScriptPubKey | EmptyScriptPubKey) => + _: LockTimeScriptPubKey | _: NonStandardScriptPubKey | + _: WitnessCommitment | _: UnassignedWitnessScriptPubKey | + EmptyScriptPubKey) => Failure( new IllegalArgumentException( "Cannot create a address for the scriptPubKey: " + x)) diff --git a/core/src/main/scala/org/bitcoins/core/protocol/blockchain/ChainParams.scala b/core/src/main/scala/org/bitcoins/core/protocol/blockchain/ChainParams.scala index 1acd0319b5..45744f00f3 100644 --- a/core/src/main/scala/org/bitcoins/core/protocol/blockchain/ChainParams.scala +++ b/core/src/main/scala/org/bitcoins/core/protocol/blockchain/ChainParams.scala @@ -106,11 +106,10 @@ sealed abstract class ChainParams { val const = ScriptConstant(timestampBytes) val asm = { - List( - BytesToPushOntoStack(4), - ScriptConstant("ffff001d"), - BytesToPushOntoStack(1), - ScriptConstant("04")) ++ + List(BytesToPushOntoStack(4), + ScriptConstant("ffff001d"), + BytesToPushOntoStack(1), + ScriptConstant("04")) ++ BitcoinScriptUtil.calculatePushOp(const) ++ List(const) } diff --git a/core/src/main/scala/org/bitcoins/core/protocol/blockchain/PartialMerkleTree.scala b/core/src/main/scala/org/bitcoins/core/protocol/blockchain/PartialMerkleTree.scala index d22075ab64..92900258f8 100644 --- a/core/src/main/scala/org/bitcoins/core/protocol/blockchain/PartialMerkleTree.scala +++ b/core/src/main/scala/org/bitcoins/core/protocol/blockchain/PartialMerkleTree.scala @@ -10,15 +10,16 @@ import scala.math._ /** * Created by chris on 8/7/16. - * Represents a subset of known txids inside of a [[Block]] + * Represents a subset of known txids inside of a [[org.bitcoins.core.protocol.blockchain.Block Block]] * in a way that allows recovery of the txids & merkle root * without having to store them all explicitly. - * See BIP37 for more details - * [[https://github.com/bitcoin/bips/blob/master/bip-0037.mediawiki#partial-merkle-branch-format]] + * See + * [[https://github.com/bitcoin/bips/blob/master/bip-0037.mediawiki#partial-merkle-branch-format BIP37]] + * for more details * * Encoding procedure: - * [[https://bitcoin.org/en/developer-reference#creating-a-merkleblock-message]] - * [[https://github.com/bitcoin/bitcoin/blob/b7b48c8bbdf7a90861610b035d8b0a247ef78c45/src/merkleblock.cpp#L78]] + * [[https://bitcoin.org/en/developer-reference#creating-a-merkleblock-message "Bitcoin.org: creating a merkleblock message"]] + * [[https://github.com/bitcoin/bitcoin/blob/b7b48c8bbdf7a90861610b035d8b0a247ef78c45/src/merkleblock.cpp#L78 "Bitcoin Core: merkleblock.cpp"]] * Traverse the tree in depth first order, storing a bit for each traversal. * This bit signifies if the node is a parent of at least one * matched leaf txid (or a matched leaf txid) itself. @@ -27,8 +28,8 @@ import scala.math._ * Otherwise no hash is stored, but we recurse all of this node's child branches. * * Decoding procedure: - * [[https://bitcoin.org/en/developer-reference#parsing-a-merkleblock-message]] - * [[https://github.com/bitcoin/bitcoin/blob/b7b48c8bbdf7a90861610b035d8b0a247ef78c45/src/merkleblock.cpp#L96]] + * [[https://bitcoin.org/en/developer-reference#parsing-a-merkleblock-message "Bitcoin.org: parsing a merkleblock message"]] + * [[https://github.com/bitcoin/bitcoin/blob/b7b48c8bbdf7a90861610b035d8b0a247ef78c45/src/merkleblock.cpp#L96 "Bitcoin Core: merkleblock.cpp"]] * The same depth first decoding procedure is performed, but we consume the * bits and hashes that we used during encoding */ @@ -37,10 +38,10 @@ sealed trait PartialMerkleTree extends BitcoinSLogger { /** The total number of transactions in this block */ def transactionCount: UInt32 - /** The actual scala integer representation for [[transactionCount]] */ + /** The actual scala integer representation for `transactionCount` */ private def numTransactions: Int = transactionCount.toInt - /** Maximum height of the [[tree]] */ + /** Maximum height of the `tree` */ private def maxHeight = PartialMerkleTree.calcMaxHeight(numTransactions) /** The actual tree used to represent this partial merkle tree*/ @@ -154,8 +155,10 @@ object PartialMerkleTree { /** * @param txMatches indicates whether the given txid matches the bloom filter, the full merkle branch needs - * to be included inside of the [[PartialMerkleTree]] - * @return the binary tree that represents the partial merkle tree, the bits needed to reconstruct this partial merkle tree, and the hashes needed to be inserted + * to be included inside of the + * [[org.bitcoins.core.protocol.blockchain.PartialMerkleTree PartialMerkleTree]] + * @return the binary tree that represents the partial merkle tree, the bits needed to reconstruct this partial + * merkle tree, and the hashes needed to be inserted * according to the flags inside of bits */ private def build(txMatches: Seq[(Boolean, DoubleSha256Digest)]): ( @@ -164,7 +167,7 @@ object PartialMerkleTree { val maxHeight = calcMaxHeight(txMatches.size) /** - * This loops through our merkle tree building [[bits]] so we can instruct another node how to create the partial merkle tree + * This loops through our merkle tree building `bits` so we can instruct another node how to create the partial merkle tree * [[https://github.com/bitcoin/bitcoin/blob/b7b48c8bbdf7a90861610b035d8b0a247ef78c45/src/merkleblock.cpp#L78]] * @param bits the accumulator for bits indicating how to reconsctruct the partial merkle tree * @param hashes the relevant hashes used with bits to reconstruct the merkle tree @@ -261,13 +264,13 @@ object PartialMerkleTree { } /** - * This constructor creates a partial from this given [[BinaryTree]] - * You probably don't want to use this constructor, unless you manually constructed [[bits]] and the [[tree]] + * This constructor creates a partial from this given [[org.bitcoins.core.util.BinaryTree BinaryTree]] + * You probably don't want to use this constructor, unless you manually constructed `bits` and the `tree` * by hand * @param tree the partial merkle tree -- note this is NOT the full merkle tree * @param transactionCount the number of transactions there initially was in the full merkle tree * @param bits the path to the matches in the partial merkle tree - * @param hashes the hashes used to reconstruct the binary tree according to [[bits]] + * @param hashes the hashes used to reconstruct the binary tree according to `bits` */ def apply( tree: BinaryTree[DoubleSha256Digest], diff --git a/core/src/main/scala/org/bitcoins/core/protocol/script/Script.scala b/core/src/main/scala/org/bitcoins/core/protocol/script/Script.scala index a4a0616968..2cc2d71a7c 100644 --- a/core/src/main/scala/org/bitcoins/core/protocol/script/Script.scala +++ b/core/src/main/scala/org/bitcoins/core/protocol/script/Script.scala @@ -1,11 +1,9 @@ - package org.bitcoins.core.protocol.script -import org.bitcoins.core.protocol.{ CompactSizeUInt, NetworkElement } +import org.bitcoins.core.protocol.{CompactSizeUInt, NetworkElement} import org.bitcoins.core.script.constant.ScriptToken import scodec.bits.ByteVector - /** This is meant to be a super type for * scripts in the bitcoin protocol. This gives us * access to the asm representation, and how to serialize the script @@ -34,4 +32,4 @@ abstract class Script extends NetworkElement { /** The full byte serialization for a script on the network */ override val bytes: ByteVector = compactSizeUInt.bytes ++ asmBytes -} \ No newline at end of file +} diff --git a/core/src/main/scala/org/bitcoins/core/protocol/script/ScriptFactory.scala b/core/src/main/scala/org/bitcoins/core/protocol/script/ScriptFactory.scala index dcf4decb3b..b20d6286b1 100644 --- a/core/src/main/scala/org/bitcoins/core/protocol/script/ScriptFactory.scala +++ b/core/src/main/scala/org/bitcoins/core/protocol/script/ScriptFactory.scala @@ -11,8 +11,11 @@ import scodec.bits.ByteVector trait ScriptFactory[T <: Script] extends Factory[T] { /** Builds a script from the given asm with the given constructor if the invariant holds true, else throws an error */ - def buildScript(asm: Vector[ScriptToken], constructor: Vector[ScriptToken] => T, - invariant: Seq[ScriptToken] => Boolean, errorMsg: String): T = { + def buildScript( + asm: Vector[ScriptToken], + constructor: Vector[ScriptToken] => T, + invariant: Seq[ScriptToken] => Boolean, + errorMsg: String): T = { if (invariant(asm)) { constructor(asm) } else throw new IllegalArgumentException(errorMsg) @@ -22,9 +25,7 @@ trait ScriptFactory[T <: Script] extends Factory[T] { def fromAsm(asm: Seq[ScriptToken]): T def fromBytes(bytes: ByteVector): T = { - BitcoinScriptUtil.parseScript( - bytes = bytes, - f = fromAsm) + BitcoinScriptUtil.parseScript(bytes = bytes, f = fromAsm) } /** @@ -50,4 +51,4 @@ trait ScriptFactory[T <: Script] extends Factory[T] { def fromAsmHex(hex: String): T = { fromAsmBytes(BitcoinSUtil.decodeHex(hex)) } -} \ No newline at end of file +} diff --git a/core/src/main/scala/org/bitcoins/core/protocol/script/ScriptPubKey.scala b/core/src/main/scala/org/bitcoins/core/protocol/script/ScriptPubKey.scala index 8fc2609aba..a40fb3c54d 100644 --- a/core/src/main/scala/org/bitcoins/core/protocol/script/ScriptPubKey.scala +++ b/core/src/main/scala/org/bitcoins/core/protocol/script/ScriptPubKey.scala @@ -5,8 +5,16 @@ import org.bitcoins.core.crypto._ import org.bitcoins.core.script.bitwise.{OP_EQUAL, OP_EQUALVERIFY} import org.bitcoins.core.script.constant.{BytesToPushOntoStack, _} import org.bitcoins.core.script.control.OP_RETURN -import org.bitcoins.core.script.crypto.{OP_CHECKMULTISIG, OP_CHECKMULTISIGVERIFY, OP_CHECKSIG, OP_HASH160} -import org.bitcoins.core.script.locktime.{OP_CHECKLOCKTIMEVERIFY, OP_CHECKSEQUENCEVERIFY} +import org.bitcoins.core.script.crypto.{ + OP_CHECKMULTISIG, + OP_CHECKMULTISIGVERIFY, + OP_CHECKSIG, + OP_HASH160 +} +import org.bitcoins.core.script.locktime.{ + OP_CHECKLOCKTIMEVERIFY, + OP_CHECKSEQUENCEVERIFY +} import org.bitcoins.core.script.reserved.UndefinedOP_NOP import org.bitcoins.core.script.stack.{OP_DROP, OP_DUP} import org.bitcoins.core.util._ @@ -19,16 +27,21 @@ import scala.util.{Failure, Success, Try} sealed abstract class ScriptPubKey extends Script /** - * Represents a pay-to-pubkey hash script pubkey - * https://bitcoin.org/en/developer-guide#pay-to-public-key-hash-p2pkh - * Format: OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG + * Represents a + * [[https://bitcoin.org/en/developer-guide#pay-to-public-key-hash-p2pkh pay-to-pubkey hash script pubkey]] + * + * Format: `OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG` */ sealed trait P2PKHScriptPubKey extends ScriptPubKey { - def pubKeyHash: Sha256Hash160Digest = Sha256Hash160Digest(asm(asm.length - 3).bytes) + + def pubKeyHash: Sha256Hash160Digest = + Sha256Hash160Digest(asm(asm.length - 3).bytes) } object P2PKHScriptPubKey extends ScriptFactory[P2PKHScriptPubKey] { - private case class P2PKHScriptPubKeyImpl(override val asm: Vector[ScriptToken]) extends P2PKHScriptPubKey { + private case class P2PKHScriptPubKeyImpl( + override val asm: Vector[ScriptToken]) + extends P2PKHScriptPubKey { override def toString = "P2PKHScriptPubKeyImpl(" + hex + ")" } @@ -39,20 +52,33 @@ object P2PKHScriptPubKey extends ScriptFactory[P2PKHScriptPubKey] { def apply(hash: Sha256Hash160Digest): P2PKHScriptPubKey = { val pushOps = BitcoinScriptUtil.calculatePushOp(hash.bytes) - val asm = Seq(OP_DUP, OP_HASH160) ++ pushOps ++ Seq(ScriptConstant(hash.bytes), OP_EQUALVERIFY, OP_CHECKSIG) + val asm = Seq(OP_DUP, OP_HASH160) ++ pushOps ++ Seq( + ScriptConstant(hash.bytes), + OP_EQUALVERIFY, + OP_CHECKSIG) P2PKHScriptPubKey(asm) } def fromAsm(asm: Seq[ScriptToken]): P2PKHScriptPubKey = { - buildScript(asm.toVector, P2PKHScriptPubKeyImpl(_), isP2PKHScriptPubKey(_), "Given asm was not a p2pkh scriptPubKey, got: " + asm) + buildScript(asm.toVector, + P2PKHScriptPubKeyImpl(_), + isP2PKHScriptPubKey(_), + "Given asm was not a p2pkh scriptPubKey, got: " + asm) } def apply(asm: Seq[ScriptToken]): P2PKHScriptPubKey = fromAsm(asm) - /** Checks if the given asm matches the pattern for [[P2PKHScriptPubKey]] */ + /** Checks if the given asm matches the pattern for + * [[org.bitcoins.core.protocol.script.P2PKHScriptPubKey P2PKHScriptPubKey]] */ def isP2PKHScriptPubKey(asm: Seq[ScriptToken]): Boolean = { asm match { - case Seq(OP_DUP, OP_HASH160, _: BytesToPushOntoStack, _: ScriptConstant, OP_EQUALVERIFY, OP_CHECKSIG) => true + case Seq(OP_DUP, + OP_HASH160, + _: BytesToPushOntoStack, + _: ScriptConstant, + OP_EQUALVERIFY, + OP_CHECKSIG) => + true case _ => false } } @@ -68,16 +94,23 @@ sealed trait MultiSignatureScriptPubKey extends ScriptPubKey { /** Returns the amount of required signatures for this multisignature script pubkey output */ def requiredSigs: Int = { val asmWithoutPushOps = asm.filterNot(_.isInstanceOf[BytesToPushOntoStack]) - val opCheckMultiSigIndex = if (asm.indexOf(OP_CHECKMULTISIG) != -1) asmWithoutPushOps.indexOf(OP_CHECKMULTISIG) else asmWithoutPushOps.indexOf(OP_CHECKMULTISIGVERIFY) + val opCheckMultiSigIndex = + if (asm.indexOf(OP_CHECKMULTISIG) != -1) + asmWithoutPushOps.indexOf(OP_CHECKMULTISIG) + else asmWithoutPushOps.indexOf(OP_CHECKMULTISIGVERIFY) //magic number 2 represents the maxSig operation and the OP_CHECKMULTISIG operation at the end of the asm - val numSigsRequired = asmWithoutPushOps(opCheckMultiSigIndex - maxSigs.toInt - 2) + val numSigsRequired = asmWithoutPushOps( + opCheckMultiSigIndex - maxSigs.toInt - 2) numSigsRequired match { case x: ScriptNumber => x.toInt - case c: ScriptConstant if ScriptNumber(c.hex).toLong <= Consensus.maxPublicKeysPerMultiSig => + case c: ScriptConstant + if ScriptNumber(c.hex).toLong <= Consensus.maxPublicKeysPerMultiSig => ScriptNumber(c.hex).toInt - case _ => throw new RuntimeException("The first element of the multisignature pubkey must be a script number operation\n" + - "operation: " + numSigsRequired + - "\nscriptPubKey: " + this) + case _ => + throw new RuntimeException( + "The first element of the multisignature pubkey must be a script number operation\n" + + "operation: " + numSigsRequired + + "\nscriptPubKey: " + this) } } @@ -89,35 +122,51 @@ sealed trait MultiSignatureScriptPubKey extends ScriptPubKey { } else { asm(checkMultiSigIndex - 1) match { case x: ScriptNumber => x.toInt - case c: ScriptConstant if ScriptNumber(c.hex).toLong <= Consensus.maxPublicKeysPerMultiSig => + case c: ScriptConstant + if ScriptNumber(c.hex).toLong <= Consensus.maxPublicKeysPerMultiSig => ScriptNumber(c.hex).toInt - case x => throw new RuntimeException("The element preceding a OP_CHECKMULTISIG operation in a multisignature pubkey must be a script number operation, got: " + x) + case x => + throw new RuntimeException( + "The element preceding a OP_CHECKMULTISIG operation in a multisignature pubkey must be a script number operation, got: " + x) } } } - /** Gives the OP_CHECKMULTISIG or OP_CHECKMULTISIGVERIFY index inside of asm */ + /** Gives the `OP_CHECKMULTISIG` or `OP_CHECKMULTISIGVERIFY` index inside of asm */ private def checkMultiSigIndex: Int = { - if (asm.indexOf(OP_CHECKMULTISIG) != -1) asm.indexOf(OP_CHECKMULTISIG) else asm.indexOf(OP_CHECKMULTISIGVERIFY) + if (asm.indexOf(OP_CHECKMULTISIG) != -1) asm.indexOf(OP_CHECKMULTISIG) + else asm.indexOf(OP_CHECKMULTISIGVERIFY) } - /** Returns the public keys encoded into the scriptPubKey */ + /** Returns the public keys encoded into the `scriptPubKey` */ def publicKeys: Seq[ECPublicKey] = { - asm.filter(_.isInstanceOf[ScriptConstant]).slice(1, maxSigs + 1).map(key => ECPublicKey(key.hex)) + asm + .filter(_.isInstanceOf[ScriptConstant]) + .slice(1, maxSigs + 1) + .map(key => ECPublicKey(key.hex)) } } -object MultiSignatureScriptPubKey extends ScriptFactory[MultiSignatureScriptPubKey] { +object MultiSignatureScriptPubKey + extends ScriptFactory[MultiSignatureScriptPubKey] { - private case class MultiSignatureScriptPubKeyImpl(override val asm: Vector[ScriptToken]) extends MultiSignatureScriptPubKey { + private case class MultiSignatureScriptPubKeyImpl( + override val asm: Vector[ScriptToken]) + extends MultiSignatureScriptPubKey { override def toString = "MultiSignatureScriptPubKeyImpl(" + hex + ")" } - def apply(requiredSigs: Int, pubKeys: Seq[ECPublicKey]): MultiSignatureScriptPubKey = { - require(requiredSigs <= Consensus.maxPublicKeysPerMultiSig, "We cannot have more required signatures than: " + - Consensus.maxPublicKeysPerMultiSig + " got: " + requiredSigs) - require(pubKeys.length <= Consensus.maxPublicKeysPerMultiSig, "We cannot have more public keys than " + - Consensus.maxPublicKeysPerMultiSig + " got: " + pubKeys.length) + def apply( + requiredSigs: Int, + pubKeys: Seq[ECPublicKey]): MultiSignatureScriptPubKey = { + require( + requiredSigs <= Consensus.maxPublicKeysPerMultiSig, + "We cannot have more required signatures than: " + + Consensus.maxPublicKeysPerMultiSig + " got: " + requiredSigs + ) + require(pubKeys.length <= Consensus.maxPublicKeysPerMultiSig, + "We cannot have more public keys than " + + Consensus.maxPublicKeysPerMultiSig + " got: " + pubKeys.length) val required = ScriptNumberOperation.fromNumber(requiredSigs) match { case Some(scriptNumOp) => Seq(scriptNumOp) @@ -138,28 +187,34 @@ object MultiSignatureScriptPubKey extends ScriptFactory[MultiSignatureScriptPubK pushOps = BitcoinScriptUtil.calculatePushOp(pubKey.bytes) constant = ScriptConstant(pubKey.bytes) } yield pushOps ++ Seq(constant) - val asm: Seq[ScriptToken] = required ++ pubKeysWithPushOps.flatten ++ possible ++ Seq(OP_CHECKMULTISIG) + val asm: Seq[ScriptToken] = required ++ pubKeysWithPushOps.flatten ++ possible ++ Seq( + OP_CHECKMULTISIG) MultiSignatureScriptPubKey(asm) } def fromAsm(asm: Seq[ScriptToken]): MultiSignatureScriptPubKey = { - buildScript(asm.toVector, MultiSignatureScriptPubKeyImpl(_), isMultiSignatureScriptPubKey(_), "Given asm was not a MultSignatureScriptPubKey, got: " + asm) + buildScript(asm.toVector, + MultiSignatureScriptPubKeyImpl(_), + isMultiSignatureScriptPubKey(_), + "Given asm was not a MultSignatureScriptPubKey, got: " + asm) } def apply(asm: Seq[ScriptToken]): MultiSignatureScriptPubKey = fromAsm(asm) - /** Determines if the given script tokens are a multisignature scriptPubKey */ + /** Determines if the given script tokens are a multisignature `scriptPubKey` */ def isMultiSignatureScriptPubKey(asm: Seq[ScriptToken]): Boolean = { val isNotEmpty = asm.size > 0 - val containsMultiSigOp = asm.contains(OP_CHECKMULTISIG) || asm.contains(OP_CHECKMULTISIGVERIFY) + val containsMultiSigOp = asm.contains(OP_CHECKMULTISIG) || asm.contains( + OP_CHECKMULTISIGVERIFY) //we need either the first or second asm operation to indicate how many signatures are required val hasRequiredSignaturesTry = Try { asm.headOption match { - case None => false + case None => false case Some(token) => //this is for the case that we have more than 16 public keys, the //first operation will be a push op, the second operation being the actual number of keys - if (token.isInstanceOf[BytesToPushOntoStack]) isValidPubKeyNumber(asm.tail.head) + if (token.isInstanceOf[BytesToPushOntoStack]) + isValidPubKeyNumber(asm.tail.head) else isValidPubKeyNumber(token) } } @@ -170,8 +225,11 @@ object MultiSignatureScriptPubKey extends ScriptFactory[MultiSignatureScriptPubK } } - val standardOps = asm.filter(op => op.isInstanceOf[ScriptNumber] || op == OP_CHECKMULTISIG || - op == OP_CHECKMULTISIGVERIFY || op.isInstanceOf[ScriptConstant] || op.isInstanceOf[BytesToPushOntoStack]) + val standardOps = asm.filter( + op => + op.isInstanceOf[ScriptNumber] || op == OP_CHECKMULTISIG || + op == OP_CHECKMULTISIGVERIFY || op.isInstanceOf[ScriptConstant] || op + .isInstanceOf[BytesToPushOntoStack]) (hasRequiredSignaturesTry, hasMaximumSignaturesTry) match { case (Success(hasRequiredSignatures), Success(hasMaximumSignatures)) => val result = isNotEmpty && containsMultiSigOp && hasRequiredSignatures && @@ -185,28 +243,32 @@ object MultiSignatureScriptPubKey extends ScriptFactory[MultiSignatureScriptPubK /** * Checks that the given script token is with the range of the maximum amount of - * public keys we can have in a [[MultiSignatureScriptPubKey]] + * public keys we can have in a + * [[org.bitcoins.core.protocol.script.MultiSignatureScriptPubKey MultiSignatureScriptPubKey]] */ private def isValidPubKeyNumber(token: ScriptToken): Boolean = token match { case constant: ScriptConstant => constant.isInstanceOf[ScriptNumber] || - ScriptNumber(constant.bytes) <= ScriptNumber(Consensus.maxPublicKeysPerMultiSig) + ScriptNumber(constant.bytes) <= ScriptNumber( + Consensus.maxPublicKeysPerMultiSig) case _: ScriptToken => false } } /** - * Represents a pay-to-scripthash public key - * https://bitcoin.org/en/developer-guide#pay-to-script-hash-p2sh - * Format: OP_HASH160 OP_EQUAL + * Represents a [[https://bitcoin.org/en/developer-guide#pay-to-script-hash-p2sh pay-to-scripthash public key]] + * Format: `OP_HASH160 OP_EQUAL` */ sealed trait P2SHScriptPubKey extends ScriptPubKey { + /** The hash of the script for which this scriptPubKey is being created from */ - def scriptHash: Sha256Hash160Digest = Sha256Hash160Digest(asm(asm.length - 2).bytes) + def scriptHash: Sha256Hash160Digest = + Sha256Hash160Digest(asm(asm.length - 2).bytes) } object P2SHScriptPubKey extends ScriptFactory[P2SHScriptPubKey] { - private case class P2SHScriptPubKeyImpl(override val asm: Vector[ScriptToken]) extends P2SHScriptPubKey { + private case class P2SHScriptPubKeyImpl(override val asm: Vector[ScriptToken]) + extends P2SHScriptPubKey { override def toString = "P2SHScriptPubKeyImpl(" + hex + ")" } @@ -217,35 +279,46 @@ object P2SHScriptPubKey extends ScriptFactory[P2SHScriptPubKey] { def apply(hash: Sha256Hash160Digest): P2SHScriptPubKey = { val pushOps = BitcoinScriptUtil.calculatePushOp(hash.bytes) - val asm = Seq(OP_HASH160) ++ pushOps ++ Seq(ScriptConstant(hash.bytes), OP_EQUAL) + val asm = Seq(OP_HASH160) ++ pushOps ++ Seq(ScriptConstant(hash.bytes), + OP_EQUAL) P2SHScriptPubKey(asm) } - /** Checks if the given asm matches the pattern for [[P2SHScriptPubKey]] */ + /** Checks if the given asm matches the pattern for + * [[org.bitcoins.core.protocol.script.P2SHScriptPubKey P2SHScriptPubKey]] */ def isP2SHScriptPubKey(asm: Seq[ScriptToken]): Boolean = asm match { - case Seq(OP_HASH160, _: BytesToPushOntoStack, _: ScriptConstant, OP_EQUAL) => true + case Seq(OP_HASH160, + _: BytesToPushOntoStack, + _: ScriptConstant, + OP_EQUAL) => + true case _ => false } def fromAsm(asm: Seq[ScriptToken]): P2SHScriptPubKey = { - buildScript(asm.toVector, P2SHScriptPubKeyImpl(_), isP2SHScriptPubKey(_), "Given asm was not a p2sh scriptPubkey, got: " + asm) + buildScript(asm.toVector, + P2SHScriptPubKeyImpl(_), + isP2SHScriptPubKey(_), + "Given asm was not a p2sh scriptPubkey, got: " + asm) } def apply(asm: Seq[ScriptToken]): P2SHScriptPubKey = fromAsm(asm) } /** - * Represents a pay to public key script public key - * https://bitcoin.org/en/developer-guide#pubkey - * Format: OP_CHECKSIG + * Represents a [[https://bitcoin.org/en/developer-guide#pubkey pay to public key script public key]] + * Format: ` OP_CHECKSIG` */ sealed trait P2PKScriptPubKey extends ScriptPubKey { - def publicKey: ECPublicKey = ECPublicKey(BitcoinScriptUtil.filterPushOps(asm).head.bytes) + + def publicKey: ECPublicKey = + ECPublicKey(BitcoinScriptUtil.filterPushOps(asm).head.bytes) } object P2PKScriptPubKey extends ScriptFactory[P2PKScriptPubKey] { - private case class P2PKScriptPubKeyImpl(override val asm: Vector[ScriptToken]) extends P2PKScriptPubKey { + private case class P2PKScriptPubKeyImpl(override val asm: Vector[ScriptToken]) + extends P2PKScriptPubKey { override def toString = "P2PKScriptPubKeyImpl(" + hex + ")" } @@ -256,25 +329,30 @@ object P2PKScriptPubKey extends ScriptFactory[P2PKScriptPubKey] { } def fromAsm(asm: Seq[ScriptToken]): P2PKScriptPubKey = { - buildScript(asm.toVector, P2PKScriptPubKeyImpl(_), isP2PKScriptPubKey(_), "Given asm was not a p2pk scriptPubKey, got: " + asm) + buildScript(asm.toVector, + P2PKScriptPubKeyImpl(_), + isP2PKScriptPubKey(_), + "Given asm was not a p2pk scriptPubKey, got: " + asm) } def apply(asm: Seq[ScriptToken]): P2PKScriptPubKey = fromAsm(asm) - /** Sees if the given asm matches the [[P2PKHScriptPubKey]] pattern */ + /** Sees if the given asm matches the + * [[org.bitcoins.core.protocol.script.P2PKHScriptPubKey P2PKHScriptPubKey]] pattern */ def isP2PKScriptPubKey(asm: Seq[ScriptToken]): Boolean = asm match { case Seq(_: BytesToPushOntoStack, _: ScriptConstant, OP_CHECKSIG) => true - case _ => false + case _ => false } } sealed trait LockTimeScriptPubKey extends ScriptPubKey { - /** Determines the nested ScriptPubKey inside the LockTimeScriptPubKey */ + + /** Determines the nested `ScriptPubKey` inside the `LockTimeScriptPubKey` */ def nestedScriptPubKey: ScriptPubKey = { val bool: Boolean = asm.head.isInstanceOf[ScriptNumberOperation] bool match { - case true => ScriptPubKey(asm.slice(3, asm.length)) + case true => ScriptPubKey(asm.slice(3, asm.length)) case false => ScriptPubKey(asm.slice(4, asm.length)) } } @@ -282,12 +360,14 @@ sealed trait LockTimeScriptPubKey extends ScriptPubKey { /** The relative locktime value (i.e. the amount of time the output should remain unspendable) */ def locktime: ScriptNumber = { asm.head match { - case scriptNumOp: ScriptNumberOperation => ScriptNumber(scriptNumOp.toLong) + case scriptNumOp: ScriptNumberOperation => + ScriptNumber(scriptNumOp.toLong) case _: BytesToPushOntoStack => ScriptNumber(asm(1).hex) case _: ScriptConstant | _: ScriptOperation => - throw new IllegalArgumentException("In a LockTimeScriptPubKey, " + - "the first asm must be either a ScriptNumberOperation (i.e. OP_5), or the BytesToPushOntoStack " + - "for the proceeding ScriptConstant.") + throw new IllegalArgumentException( + "In a LockTimeScriptPubKey, " + + "the first asm must be either a ScriptNumberOperation (i.e. OP_5), or the BytesToPushOntoStack " + + "for the proceeding ScriptConstant.") } } } @@ -298,42 +378,52 @@ object LockTimeScriptPubKey extends ScriptFactory[LockTimeScriptPubKey] { require(isValidLockTimeScriptPubKey(asm)) if (asm.contains(OP_CHECKLOCKTIMEVERIFY)) CLTVScriptPubKey(asm) else if (asm.contains(OP_CHECKSEQUENCEVERIFY)) CSVScriptPubKey(asm) - else throw new IllegalArgumentException("Given asm was not a LockTimeScriptPubKey, got: " + asm) + else + throw new IllegalArgumentException( + "Given asm was not a LockTimeScriptPubKey, got: " + asm) } def isValidLockTimeScriptPubKey(asm: Seq[ScriptToken]): Boolean = { - CLTVScriptPubKey.isCLTVScriptPubKey(asm) || CSVScriptPubKey.isCSVScriptPubKey(asm) + CLTVScriptPubKey.isCLTVScriptPubKey(asm) || CSVScriptPubKey + .isCSVScriptPubKey(asm) } } /** - * Represents a scriptPubKey that contains OP_CHECKLOCKTIMEVERIFY. + * Represents a scriptPubKey that contains `OP_CHECKLOCKTIMEVERIFY.` * Adds an absolute/defined locktime condition to any scriptPubKey. - * [[https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki]] - * Format: OP_CLTV OP_DROP + * [[https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki BIP65]] + * Format: ` OP_CLTV OP_DROP ` */ sealed trait CLTVScriptPubKey extends LockTimeScriptPubKey object CLTVScriptPubKey extends ScriptFactory[CLTVScriptPubKey] { - private case class CLTVScriptPubKeyImpl(override val asm: Vector[ScriptToken]) extends CLTVScriptPubKey { + private case class CLTVScriptPubKeyImpl(override val asm: Vector[ScriptToken]) + extends CLTVScriptPubKey { override def toString = "CLTVScriptPubKeyImpl(" + hex + ")" } def fromAsm(asm: Seq[ScriptToken]): CLTVScriptPubKey = { - buildScript(asm.toVector, CLTVScriptPubKeyImpl(_), isCLTVScriptPubKey(_), "Given asm was not a CLTVScriptPubKey, got: " + asm) + buildScript(asm.toVector, + CLTVScriptPubKeyImpl(_), + isCLTVScriptPubKey(_), + "Given asm was not a CLTVScriptPubKey, got: " + asm) } def apply(asm: Seq[ScriptToken]): CLTVScriptPubKey = fromAsm(asm) - def apply(locktime: ScriptNumber, scriptPubKey: ScriptPubKey): CLTVScriptPubKey = { + def apply( + locktime: ScriptNumber, + scriptPubKey: ScriptPubKey): CLTVScriptPubKey = { val scriptOp = BitcoinScriptUtil.minimalScriptNumberRepresentation(locktime) - val scriptNum: Seq[ScriptToken] = if (scriptOp.isInstanceOf[ScriptNumberOperation]) { - Seq(scriptOp) - } else { - val pushOpsLockTime = BitcoinScriptUtil.calculatePushOp(locktime.bytes) - pushOpsLockTime ++ Seq(ScriptConstant(locktime.bytes)) - } + val scriptNum: Seq[ScriptToken] = + if (scriptOp.isInstanceOf[ScriptNumberOperation]) { + Seq(scriptOp) + } else { + val pushOpsLockTime = BitcoinScriptUtil.calculatePushOp(locktime.bytes) + pushOpsLockTime ++ Seq(ScriptConstant(locktime.bytes)) + } val cltvAsm = Seq(OP_CHECKLOCKTIMEVERIFY, OP_DROP) val scriptPubKeyAsm = scriptPubKey.asm @@ -344,15 +434,20 @@ object CLTVScriptPubKey extends ScriptFactory[CLTVScriptPubKey] { def isCLTVScriptPubKey(asm: Seq[ScriptToken]): Boolean = { if (asm.head.isInstanceOf[BytesToPushOntoStack]) { val tailTokens = asm.slice(4, asm.length) - if (P2SHScriptPubKey.isP2SHScriptPubKey(tailTokens) || tailTokens.contains(OP_CHECKLOCKTIMEVERIFY)) return false + if (P2SHScriptPubKey.isP2SHScriptPubKey(tailTokens) || tailTokens + .contains(OP_CHECKLOCKTIMEVERIFY)) return false asm.slice(0, 4) match { - case Seq(_: BytesToPushOntoStack, _: ScriptConstant, OP_CHECKLOCKTIMEVERIFY, OP_DROP) => + case Seq(_: BytesToPushOntoStack, + _: ScriptConstant, + OP_CHECKLOCKTIMEVERIFY, + OP_DROP) => validScriptAfterLockTime(tailTokens) case _ => false } } else { val tailTokens = asm.slice(3, asm.length) - if (P2SHScriptPubKey.isP2SHScriptPubKey(tailTokens) || tailTokens.contains(OP_CHECKLOCKTIMEVERIFY)) return false + if (P2SHScriptPubKey.isP2SHScriptPubKey(tailTokens) || tailTokens + .contains(OP_CHECKLOCKTIMEVERIFY)) return false asm.slice(0, 3) match { case Seq(_: ScriptNumberOperation, OP_CHECKLOCKTIMEVERIFY, OP_DROP) => validScriptAfterLockTime(tailTokens) @@ -364,12 +459,14 @@ object CLTVScriptPubKey extends ScriptFactory[CLTVScriptPubKey] { /** * We need this check because sometimes we can get very lucky in having a non valid * lock time script that has the first 4 bytes as a valid locktime script - * and then the bytes after the first 4 bytes gets lucky and is parsed by our [[org.bitcoins.core.serializers.script.ScriptParser]] + * and then the bytes after the first 4 bytes gets lucky and is parsed by our + * [[org.bitcoins.core.serializers.script.ScriptParser ScriptParser]] * A good way to see if this is _actually_ a valid script is by checking if we have any - * [[UndefinedOP_NOP]] in the script, which means we definitely don't have a valid locktime script - * See this example of what happened before we added this check: + * [[org.bitcoins.core.script.reserved.UndefinedOP_NOP UndefinedOP_NOP]] in the script, + * which means we definitely don't have a valid locktime script * - * [[https://travis-ci.org/bitcoin-s/bitcoin-s-core/builds/201652191#L2526]] + * See this example of what happened before we added this check: + * [[https://travis-ci.org/bitcoin-s/bitcoin-s-core/builds/201652191#L2526 Travis CI]] */ def validScriptAfterLockTime(asm: Seq[ScriptToken]): Boolean = { !asm.exists(_.isInstanceOf[UndefinedOP_NOP]) @@ -377,33 +474,43 @@ object CLTVScriptPubKey extends ScriptFactory[CLTVScriptPubKey] { } /** - * Represents a scriptPubKey that contains OP_CHECKSEQUENCEVERIFY. - * Adds a relative lockTime condition to any scriptPubKey. - * https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki - * Format: OP_CSV OP_DROP + * Represents a scriptPubKey that contains + * [[org.bitcoins.core.script.locktime.OP_CHECKSEQUENCEVERIFY OP_CHECKSEQUENCEVERIFY]] + * Adds a relative lockTime condition to any `scriptPubKey`. + * [[https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki BIP112]] + * Format: ` OP_CSV OP_DROP ` */ sealed trait CSVScriptPubKey extends LockTimeScriptPubKey object CSVScriptPubKey extends ScriptFactory[CSVScriptPubKey] { - private case class CSVScriptPubKeyImpl(override val asm: Vector[ScriptToken]) extends CSVScriptPubKey { + private case class CSVScriptPubKeyImpl(override val asm: Vector[ScriptToken]) + extends CSVScriptPubKey { override def toString = "CSVScriptPubKeyImpl(" + hex + ")" } def fromAsm(asm: Seq[ScriptToken]): CSVScriptPubKey = { - buildScript(asm.toVector, CSVScriptPubKeyImpl(_), isCSVScriptPubKey(_), "Given asm was not a CSVScriptPubKey, got: " + asm) + buildScript(asm.toVector, + CSVScriptPubKeyImpl(_), + isCSVScriptPubKey(_), + "Given asm was not a CSVScriptPubKey, got: " + asm) } def apply(asm: Seq[ScriptToken]): CSVScriptPubKey = fromAsm(asm) - def apply(relativeLockTime: ScriptNumber, scriptPubKey: ScriptPubKey): CSVScriptPubKey = { - val scriptOp = BitcoinScriptUtil.minimalScriptNumberRepresentation(relativeLockTime) + def apply( + relativeLockTime: ScriptNumber, + scriptPubKey: ScriptPubKey): CSVScriptPubKey = { + val scriptOp = + BitcoinScriptUtil.minimalScriptNumberRepresentation(relativeLockTime) - val scriptNum: Seq[ScriptToken] = if (scriptOp.isInstanceOf[ScriptNumberOperation]) { - Seq(scriptOp) - } else { - val pushOpsLockTime = BitcoinScriptUtil.calculatePushOp(relativeLockTime.bytes) - pushOpsLockTime ++ Seq(ScriptConstant(relativeLockTime.bytes)) - } + val scriptNum: Seq[ScriptToken] = + if (scriptOp.isInstanceOf[ScriptNumberOperation]) { + Seq(scriptOp) + } else { + val pushOpsLockTime = + BitcoinScriptUtil.calculatePushOp(relativeLockTime.bytes) + pushOpsLockTime ++ Seq(ScriptConstant(relativeLockTime.bytes)) + } val csvAsm = Seq(OP_CHECKSEQUENCEVERIFY, OP_DROP) val scriptPubKeyAsm = scriptPubKey.asm @@ -414,15 +521,20 @@ object CSVScriptPubKey extends ScriptFactory[CSVScriptPubKey] { def isCSVScriptPubKey(asm: Seq[ScriptToken]): Boolean = { if (asm.head.isInstanceOf[BytesToPushOntoStack]) { val tailTokens = asm.slice(4, asm.length) - if (P2SHScriptPubKey.isP2SHScriptPubKey(tailTokens) || tailTokens.contains(OP_CHECKSEQUENCEVERIFY)) return false + if (P2SHScriptPubKey.isP2SHScriptPubKey(tailTokens) || tailTokens + .contains(OP_CHECKSEQUENCEVERIFY)) return false asm.slice(0, 4) match { - case Seq(_: BytesToPushOntoStack, _: ScriptConstant, OP_CHECKSEQUENCEVERIFY, OP_DROP) => + case Seq(_: BytesToPushOntoStack, + _: ScriptConstant, + OP_CHECKSEQUENCEVERIFY, + OP_DROP) => CLTVScriptPubKey.validScriptAfterLockTime(tailTokens) case _ => false } } else { val tailTokens = asm.slice(3, asm.length) - if (P2SHScriptPubKey.isP2SHScriptPubKey(tailTokens) || tailTokens.contains(OP_CHECKSEQUENCEVERIFY)) return false + if (P2SHScriptPubKey.isP2SHScriptPubKey(tailTokens) || tailTokens + .contains(OP_CHECKSEQUENCEVERIFY)) return false asm.slice(0, 3) match { case Seq(_: ScriptNumberOperation, OP_CHECKSEQUENCEVERIFY, OP_DROP) => CLTVScriptPubKey.validScriptAfterLockTime(tailTokens) @@ -436,13 +548,17 @@ object CSVScriptPubKey extends ScriptFactory[CSVScriptPubKey] { sealed trait NonStandardScriptPubKey extends ScriptPubKey object NonStandardScriptPubKey extends ScriptFactory[NonStandardScriptPubKey] { - private case class NonStandardScriptPubKeyImpl(override val asm: Vector[ScriptToken]) extends NonStandardScriptPubKey { + private case class NonStandardScriptPubKeyImpl( + override val asm: Vector[ScriptToken]) + extends NonStandardScriptPubKey { override def toString = "NonStandardScriptPubKeyImpl(" + hex + ")" } def fromAsm(asm: Seq[ScriptToken]): NonStandardScriptPubKey = { //everything can be a NonStandardScriptPubkey, thus the trivially true function - buildScript(asm.toVector, NonStandardScriptPubKeyImpl(_), { _ => true }, "") + buildScript(asm.toVector, NonStandardScriptPubKeyImpl(_), { _ => + true + }, "") } def apply(asm: Seq[ScriptToken]): NonStandardScriptPubKey = fromAsm(asm) @@ -453,53 +569,82 @@ case object EmptyScriptPubKey extends ScriptPubKey { override def asm: Seq[ScriptToken] = Vector.empty } -/** Factory companion object used to create ScriptPubKey objects */ +/** Factory companion object used to create + * [[org.bitcoins.core.protocol.script.ScriptPubKey ScriptPubKey]] objects */ object ScriptPubKey extends ScriptFactory[ScriptPubKey] { def empty: ScriptPubKey = fromAsm(Nil) - /** Creates a scriptPubKey from its asm representation */ + /** Creates a `scriptPubKey` from its asm representation */ def fromAsm(asm: Seq[ScriptToken]): ScriptPubKey = asm match { case Nil => EmptyScriptPubKey - case _ if P2PKHScriptPubKey.isP2PKHScriptPubKey(asm) => P2PKHScriptPubKey(asm) + case _ if P2PKHScriptPubKey.isP2PKHScriptPubKey(asm) => + P2PKHScriptPubKey(asm) case _ if P2SHScriptPubKey.isP2SHScriptPubKey(asm) => P2SHScriptPubKey(asm) case _ if P2PKScriptPubKey.isP2PKScriptPubKey(asm) => P2PKScriptPubKey(asm) - case _ if MultiSignatureScriptPubKey.isMultiSignatureScriptPubKey(asm) => MultiSignatureScriptPubKey(asm) + case _ if MultiSignatureScriptPubKey.isMultiSignatureScriptPubKey(asm) => + MultiSignatureScriptPubKey(asm) case _ if CLTVScriptPubKey.isCLTVScriptPubKey(asm) => CLTVScriptPubKey(asm) - case _ if CSVScriptPubKey.isCSVScriptPubKey(asm) => CSVScriptPubKey(asm) - case _ if WitnessScriptPubKey.isWitnessScriptPubKey(asm) => WitnessScriptPubKey(asm).get - case _ if WitnessCommitment.isWitnessCommitment(asm) => WitnessCommitment(asm) + case _ if CSVScriptPubKey.isCSVScriptPubKey(asm) => CSVScriptPubKey(asm) + case _ if WitnessScriptPubKey.isWitnessScriptPubKey(asm) => + WitnessScriptPubKey(asm).get + case _ if WitnessCommitment.isWitnessCommitment(asm) => + WitnessCommitment(asm) case _ => NonStandardScriptPubKey(asm) } def apply(asm: Seq[ScriptToken]): ScriptPubKey = fromAsm(asm) } -/** This type represents a [[ScriptPubKey]] to evaluate a [[ScriptWitness]] */ +/** This type represents a + * [[org.bitcoins.core.protocol.script.ScriptPubKey ScriptPubKey]] to evaluate a + * [[org.bitcoins.core.protocol.script.ScriptWitness ScriptWitness]] */ sealed trait WitnessScriptPubKey extends ScriptPubKey { def witnessProgram: Seq[ScriptToken] def witnessVersion = WitnessVersion(asm.head) } object WitnessScriptPubKey { - /** Witness scripts must begin with one of these operations, see BIP141 */ - val validWitVersions: Seq[ScriptNumberOperation] = Seq(OP_0, OP_1, OP_2, OP_3, OP_4, OP_5, OP_6, OP_7, OP_8, - OP_9, OP_10, OP_11, OP_12, OP_13, OP_14, OP_15, OP_16) + + /** Witness scripts must begin with one of these operations, see + * [[https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki BIP141]] */ + val validWitVersions: Seq[ScriptNumberOperation] = Seq(OP_0, + OP_1, + OP_2, + OP_3, + OP_4, + OP_5, + OP_6, + OP_7, + OP_8, + OP_9, + OP_10, + OP_11, + OP_12, + OP_13, + OP_14, + OP_15, + OP_16) val unassignedWitVersions = validWitVersions.tail def apply(asm: Seq[ScriptToken]): Option[WitnessScriptPubKey] = fromAsm(asm) def fromAsm(asm: Seq[ScriptToken]): Option[WitnessScriptPubKey] = asm match { - case _ if P2WPKHWitnessSPKV0.isValid(asm) => Some(P2WPKHWitnessSPKV0.fromAsm(asm)) - case _ if P2WSHWitnessSPKV0.isValid(asm) => Some(P2WSHWitnessSPKV0.fromAsm(asm)) - case _ if WitnessScriptPubKey.isWitnessScriptPubKey(asm) => Some(UnassignedWitnessScriptPubKey(asm)) + case _ if P2WPKHWitnessSPKV0.isValid(asm) => + Some(P2WPKHWitnessSPKV0.fromAsm(asm)) + case _ if P2WSHWitnessSPKV0.isValid(asm) => + Some(P2WSHWitnessSPKV0.fromAsm(asm)) + case _ if WitnessScriptPubKey.isWitnessScriptPubKey(asm) => + Some(UnassignedWitnessScriptPubKey(asm)) case _ => None } /** - * Checks if the given asm is a valid [[org.bitcoins.core.protocol.script.WitnessScriptPubKey]] - * Mimics this function inside of Bitcoin Core - * [[https://github.com/bitcoin/bitcoin/blob/14d01309bed59afb08651f2b701ff90371b15b20/src/script/script.cpp#L223-L237]] + * Checks if the given asm is a valid + * [[org.bitcoins.core.protocol.script.WitnessScriptPubKey WitnessScriptPubKey]] + * Mimics + * [[https://github.com/bitcoin/bitcoin/blob/14d01309bed59afb08651f2b701ff90371b15b20/src/script/script.cpp#L223-L237 this function]] + * inside of Bitcoin Core */ def isWitnessScriptPubKey(asm: Seq[ScriptToken]): Boolean = { @@ -512,7 +657,8 @@ object WitnessScriptPubKey { //we can also have a LockTimeScriptPubKey with a nested 0 public key multisig script, need to check that as well val bytes = BitcoinSUtil.toByteVector(asm) - val isMultiSig = MultiSignatureScriptPubKey.isMultiSignatureScriptPubKey(asm) + val isMultiSig = + MultiSignatureScriptPubKey.isMultiSignatureScriptPubKey(asm) val isLockTimeSPK = { LockTimeScriptPubKey.isValidLockTimeScriptPubKey(asm) } @@ -526,7 +672,8 @@ object WitnessScriptPubKey { } } -/** Represents a [[https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#witness-program]] */ +/** Represents a + * [[https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#witness-program BIP141 Witness program]] */ sealed abstract class WitnessScriptPubKeyV0 extends WitnessScriptPubKey { override def witnessProgram: Seq[ScriptToken] = asm.tail.tail } @@ -534,20 +681,23 @@ sealed abstract class WitnessScriptPubKeyV0 extends WitnessScriptPubKey { object WitnessScriptPubKeyV0 { /** - * Mimics the function to determine if a [[ScriptPubKey]] contains a witness - * A witness program is any valid [[ScriptPubKey]] that consists of a 1 byte push op and then a data push + * Mimics the function to determine if a + * [[org.bitcoins.core.protocol.script.ScriptPubKey ScriptPubKey]] contains a witness + * A witness program is any valid + * [[org.bitcoins.core.protocol.script.ScriptPubKey ScriptPubKey]] that consists of a 1 byte push op and then a data push * between 2 and 40 bytes * Verison 0 witness program need to have an OP_0 as the first operation * [[https://github.com/bitcoin/bitcoin/blob/449f9b8debcceb61a92043bc7031528a53627c47/src/script/script.cpp#L215-L229]] */ def isValid(asm: Seq[ScriptToken]): Boolean = { - WitnessScriptPubKey.isWitnessScriptPubKey(asm) && asm.headOption == Some(OP_0) + WitnessScriptPubKey.isWitnessScriptPubKey(asm) && asm.headOption == Some( + OP_0) } } /** - * Represents the pay-to-witness-pubkeyhash script pubkey type as defined in BIP141 - * [[https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#P2WPKH]] + * Represents the pay-to-witness-pubkeyhash script pubkey type as defined in + * [[https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#P2WPKH BIP141]] */ sealed abstract class P2WPKHWitnessSPKV0 extends WitnessScriptPubKeyV0 { def pubKeyHash: Sha256Hash160Digest = Sha256Hash160Digest(asm(2).bytes) @@ -555,16 +705,21 @@ sealed abstract class P2WPKHWitnessSPKV0 extends WitnessScriptPubKeyV0 { } object P2WPKHWitnessSPKV0 extends ScriptFactory[P2WPKHWitnessSPKV0] { - private case class P2WPKHWitnessSPKV0Impl(override val asm: Vector[ScriptToken]) extends P2WPKHWitnessSPKV0 + private case class P2WPKHWitnessSPKV0Impl( + override val asm: Vector[ScriptToken]) + extends P2WPKHWitnessSPKV0 override def fromAsm(asm: Seq[ScriptToken]): P2WPKHWitnessSPKV0 = { - buildScript(asm.toVector, P2WPKHWitnessSPKV0Impl(_), isValid(_), s"Given asm was not a P2WPKHWitnessSPKV0, got $asm") + buildScript(asm.toVector, + P2WPKHWitnessSPKV0Impl(_), + isValid(_), + s"Given asm was not a P2WPKHWitnessSPKV0, got $asm") } def isValid(asm: Seq[ScriptToken]): Boolean = { val asmBytes = BitcoinSUtil.toByteVector(asm) WitnessScriptPubKeyV0.isValid(asm) && - asmBytes.size == 22 + asmBytes.size == 22 } def fromHash(hash: Sha256Hash160Digest): P2WPKHWitnessSPKV0 = { @@ -575,7 +730,9 @@ object P2WPKHWitnessSPKV0 extends ScriptFactory[P2WPKHWitnessSPKV0] { /** Creates a P2WPKH witness script pubkey */ def apply(pubKey: ECPublicKey): P2WPKHWitnessSPKV0 = { //https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki#restrictions-on-public-key-type - require(pubKey.isCompressed, s"Public key must be compressed to be used in a segwit script, see BIP143") + require( + pubKey.isCompressed, + s"Public key must be compressed to be used in a segwit script, see BIP143") val hash = CryptoUtil.sha256Hash160(pubKey.bytes) val pushop = BitcoinScriptUtil.calculatePushOp(hash.bytes) fromAsm(Seq(OP_0) ++ pushop ++ Seq(ScriptConstant(hash.bytes))) @@ -583,8 +740,8 @@ object P2WPKHWitnessSPKV0 extends ScriptFactory[P2WPKHWitnessSPKV0] { } /** - * Reprents the pay-to-witness-scripthash script pubkey type as defined in BIP141 - * [[https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#p2wsh]] + * Reprents the pay-to-witness-scripthash script pubkey type as defined in + * [[https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#p2wsh BIP141]] */ sealed abstract class P2WSHWitnessSPKV0 extends WitnessScriptPubKeyV0 { def scriptHash: Sha256Digest = Sha256Digest(asm(3).bytes) @@ -592,16 +749,21 @@ sealed abstract class P2WSHWitnessSPKV0 extends WitnessScriptPubKeyV0 { } object P2WSHWitnessSPKV0 extends ScriptFactory[P2WSHWitnessSPKV0] { - private case class P2WSHWitnessSPKV0Impl(override val asm: Vector[ScriptToken]) extends P2WSHWitnessSPKV0 + private case class P2WSHWitnessSPKV0Impl( + override val asm: Vector[ScriptToken]) + extends P2WSHWitnessSPKV0 override def fromAsm(asm: Seq[ScriptToken]): P2WSHWitnessSPKV0 = { - buildScript(asm.toVector, P2WSHWitnessSPKV0Impl(_), isValid(_), s"Given asm was not a P2WSHWitnessSPKV0, got $asm") + buildScript(asm.toVector, + P2WSHWitnessSPKV0Impl(_), + isValid(_), + s"Given asm was not a P2WSHWitnessSPKV0, got $asm") } def isValid(asm: Seq[ScriptToken]): Boolean = { val asmBytes = BitcoinSUtil.toByteVector(asm) WitnessScriptPubKeyV0.isValid(asm) && - asmBytes.size == 34 + asmBytes.size == 34 } def fromHash(hash: Sha256Digest): P2WSHWitnessSPKV0 = { @@ -610,26 +772,37 @@ object P2WSHWitnessSPKV0 extends ScriptFactory[P2WSHWitnessSPKV0] { } def apply(spk: ScriptPubKey): P2WSHWitnessSPKV0 = { - require(BitcoinScriptUtil.isOnlyCompressedPubKey(spk), s"Public key must be compressed to be used in a segwit script, see BIP143") + require( + BitcoinScriptUtil.isOnlyCompressedPubKey(spk), + s"Public key must be compressed to be used in a segwit script, see BIP143") val hash = CryptoUtil.sha256(spk.asmBytes) val pushop = BitcoinScriptUtil.calculatePushOp(hash.bytes) fromAsm(Seq(OP_0) ++ pushop ++ Seq(ScriptConstant(hash.bytes))) } } -/** Type to represent all [[org.bitcoins.core.protocol.script.WitnessScriptPubKey]]s we have not used yet in the bitcoin protocol */ +/** Type to represent all + * [[org.bitcoins.core.protocol.script.WitnessScriptPubKey WitnessScriptPubKey]]s + * we have not used yet in the bitcoin protocol */ sealed trait UnassignedWitnessScriptPubKey extends WitnessScriptPubKey { override def witnessProgram: Seq[ScriptToken] = asm.tail.tail } -object UnassignedWitnessScriptPubKey extends ScriptFactory[UnassignedWitnessScriptPubKey] { - private case class UnassignedWitnessScriptPubKeyImpl(override val asm: Vector[ScriptToken]) extends UnassignedWitnessScriptPubKey { +object UnassignedWitnessScriptPubKey + extends ScriptFactory[UnassignedWitnessScriptPubKey] { + private case class UnassignedWitnessScriptPubKeyImpl( + override val asm: Vector[ScriptToken]) + extends UnassignedWitnessScriptPubKey { override def toString = "UnassignedWitnessScriptPubKeyImpl(" + hex + ")" } override def fromAsm(asm: Seq[ScriptToken]): UnassignedWitnessScriptPubKey = { - buildScript(asm.toVector, UnassignedWitnessScriptPubKeyImpl(_), WitnessScriptPubKey.isWitnessScriptPubKey(_), - "Given asm was not a valid witness script pubkey: " + asm) + buildScript( + asm.toVector, + UnassignedWitnessScriptPubKeyImpl(_), + WitnessScriptPubKey.isWitnessScriptPubKey(_), + "Given asm was not a valid witness script pubkey: " + asm + ) } def apply(asm: Seq[ScriptToken]): UnassignedWitnessScriptPubKey = fromAsm(asm) } @@ -637,35 +810,51 @@ object UnassignedWitnessScriptPubKey extends ScriptFactory[UnassignedWitnessScri /** * This trait represents the witness commitment found in the coinbase transaction * This is needed to commit to the wtxids of all of the witness transactions, since the merkle tree - * does not commit to the witnesses for all [[org.bitcoins.core.protocol.transaction.WitnessTransaction]] + * does not commit to the witnesses for all + * [[org.bitcoins.core.protocol.transaction.WitnessTransaction WitnessTransaction]] * See BIP141 for more info * [[https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#commitment-structure]] */ sealed trait WitnessCommitment extends ScriptPubKey { - /** The commitment to the [[WitnessTransaction]]s in the [[Block]] */ - def witnessRootHash: DoubleSha256Digest = DoubleSha256Digest(asm(2).bytes.splitAt(4)._2) + + /** The commitment to the + * [[org.bitcoins.core.protocol.transaction.WitnessTransaction WitnessTransaction]]s in the + * [[org.bitcoins.core.protocol.blockchain.Block Block]] */ + def witnessRootHash: DoubleSha256Digest = + DoubleSha256Digest(asm(2).bytes.splitAt(4)._2) } object WitnessCommitment extends ScriptFactory[WitnessCommitment] { - private case class WitnessCommitmentImpl(override val asm: Vector[ScriptToken]) extends WitnessCommitment { + private case class WitnessCommitmentImpl( + override val asm: Vector[ScriptToken]) + extends WitnessCommitment { override def toString = "WitnessCommitmentImpl(" + hex + ")" } - /** Every witness commitment must start with this header, see BIP141 for details */ + /** Every witness commitment must start with this header, see + * [[https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki BIP141]] + * for details */ private val commitmentHeader = "aa21a9ed" def apply(asm: Seq[ScriptToken]): WitnessCommitment = fromAsm(asm) override def fromAsm(asm: Seq[ScriptToken]): WitnessCommitment = { - buildScript(asm.toVector, WitnessCommitmentImpl(_), isWitnessCommitment(_), "Given asm was not a valid witness commitment, got: " + asm) + buildScript(asm.toVector, + WitnessCommitmentImpl(_), + isWitnessCommitment(_), + "Given asm was not a valid witness commitment, got: " + asm) } def apply(hash: DoubleSha256Digest): WitnessCommitment = { - WitnessCommitment(Seq(OP_RETURN, BytesToPushOntoStack(36), ScriptConstant(commitmentHeader + hash.hex))) + WitnessCommitment( + Seq(OP_RETURN, + BytesToPushOntoStack(36), + ScriptConstant(commitmentHeader + hash.hex))) } + /** - * This determines if the given asm has the correct witness structure according to BIP141 - * [[https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#commitment-structure]] + * This determines if the given asm has the correct witness structure according to + * [[https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#commitment-structure BIP141]] */ def isWitnessCommitment(asm: Seq[ScriptToken]): Boolean = { if (asm.size < 3) false @@ -674,7 +863,7 @@ object WitnessCommitment extends ScriptFactory[WitnessCommitment] { val asmBytes = BitcoinSUtil.toByteVector(asm) val Seq(opReturn, pushOp, constant) = asm.take(3) opReturn == OP_RETURN && pushOp == BytesToPushOntoStack(36) && - constant.hex.take(8) == commitmentHeader && asmBytes.size >= minCommitmentSize + constant.hex.take(8) == commitmentHeader && asmBytes.size >= minCommitmentSize } } -} \ No newline at end of file +} diff --git a/core/src/main/scala/org/bitcoins/core/protocol/script/ScriptSignature.scala b/core/src/main/scala/org/bitcoins/core/protocol/script/ScriptSignature.scala index 43c1e639c1..ec3fb0d768 100644 --- a/core/src/main/scala/org/bitcoins/core/protocol/script/ScriptSignature.scala +++ b/core/src/main/scala/org/bitcoins/core/protocol/script/ScriptSignature.scala @@ -29,15 +29,19 @@ sealed trait NonStandardScriptSignature extends ScriptSignature { override def toString = "NonStandardScriptSignature(" + hex + ")" } -object NonStandardScriptSignature extends ScriptFactory[NonStandardScriptSignature] { - private case class NonStandardScriptSignatureImpl(override val asm: Vector[ScriptToken]) extends NonStandardScriptSignature +object NonStandardScriptSignature + extends ScriptFactory[NonStandardScriptSignature] { + private case class NonStandardScriptSignatureImpl( + override val asm: Vector[ScriptToken]) + extends NonStandardScriptSignature def fromAsm(asm: Seq[ScriptToken]): NonStandardScriptSignature = { - buildScript( - asm = asm.toVector, - constructor = NonStandardScriptSignatureImpl(_), - invariant = { _ => true }, - errorMsg = "") + buildScript(asm = asm.toVector, + constructor = NonStandardScriptSignatureImpl(_), + invariant = { _ => + true + }, + errorMsg = "") } } @@ -64,32 +68,42 @@ sealed trait P2PKHScriptSignature extends ScriptSignature { } object P2PKHScriptSignature extends ScriptFactory[P2PKHScriptSignature] { - private case class P2PKHScriptSignatureImpl(override val asm: Vector[ScriptToken]) extends P2PKHScriptSignature + private case class P2PKHScriptSignatureImpl( + override val asm: Vector[ScriptToken]) + extends P2PKHScriptSignature def fromAsm(asm: Seq[ScriptToken]): P2PKHScriptSignature = { buildScript( asm = asm.toVector, constructor = P2PKHScriptSignatureImpl(_), invariant = isP2PKHScriptSig(_), - errorMsg = s"Given asm was not a P2PKHScriptSignature, got: $asm") + errorMsg = s"Given asm was not a P2PKHScriptSignature, got: $asm" + ) } /** * Builds a script signature from a digital signature and a public key * this is a pay to public key hash script sig */ - def apply(signature: ECDigitalSignature, pubKey: ECPublicKey): P2PKHScriptSignature = { - val signatureBytesToPushOntoStack = BitcoinScriptUtil.calculatePushOp(signature.bytes) - val pubKeyBytesToPushOntoStack = BitcoinScriptUtil.calculatePushOp(pubKey.bytes) - val asm: Seq[ScriptToken] = signatureBytesToPushOntoStack ++ Seq(ScriptConstant(signature.hex)) ++ + def apply( + signature: ECDigitalSignature, + pubKey: ECPublicKey): P2PKHScriptSignature = { + val signatureBytesToPushOntoStack = + BitcoinScriptUtil.calculatePushOp(signature.bytes) + val pubKeyBytesToPushOntoStack = + BitcoinScriptUtil.calculatePushOp(pubKey.bytes) + val asm: Seq[ScriptToken] = signatureBytesToPushOntoStack ++ Seq( + ScriptConstant(signature.hex)) ++ pubKeyBytesToPushOntoStack ++ Seq(ScriptConstant(pubKey.hex)) fromAsm(asm) } /** Determines if the given asm matches a [[P2PKHScriptSignature]] */ def isP2PKHScriptSig(asm: Seq[ScriptToken]): Boolean = asm match { - case Seq(_: BytesToPushOntoStack, _: ScriptConstant, _: BytesToPushOntoStack, - z: ScriptConstant) => + case Seq(_: BytesToPushOntoStack, + _: ScriptConstant, + _: BytesToPushOntoStack, + z: ScriptConstant) => if (ECPublicKey.isFullyValid(z.bytes)) true else !P2SHScriptSignature.isRedeemScript(z) case _ => false @@ -108,7 +122,7 @@ sealed trait P2SHScriptSignature extends ScriptSignature { def redeemScript: ScriptPubKey = { val scriptSig = scriptSignatureNoRedeemScript if (scriptSig == EmptyScriptSignature && - WitnessScriptPubKey.isWitnessScriptPubKey(asm.tail)) { + WitnessScriptPubKey.isWitnessScriptPubKey(asm.tail)) { //if we have an EmptyScriptSignature, we need to check if the rest of the asm //is a Witness script. It is not necessarily a witness script, since this code //path might be used for signing a normal p2sh spk in TransactionSignatureSerializer @@ -128,17 +142,19 @@ sealed trait P2SHScriptSignature extends ScriptSignature { val asmWithoutRedeemScriptAndPushOp: Try[Seq[ScriptToken]] = Try { asm(asm.size - 2) match { case _: BytesToPushOntoStack => asm.dropRight(2) - case _ => asm.dropRight(3) + case _ => asm.dropRight(3) } } - val script = asmWithoutRedeemScriptAndPushOp.getOrElse(EmptyScriptSignature.asm) + val script = + asmWithoutRedeemScriptAndPushOp.getOrElse(EmptyScriptSignature.asm) ScriptSignature.fromAsm(script) } } /** Returns the public keys for the p2sh scriptSignature */ def publicKeys: Seq[ECPublicKey] = { - val pubKeys: Seq[ScriptToken] = redeemScript.asm.filter(_.isInstanceOf[ScriptConstant]) + val pubKeys: Seq[ScriptToken] = redeemScript.asm + .filter(_.isInstanceOf[ScriptConstant]) .filterNot(_.isInstanceOf[ScriptNumberOperation]) pubKeys.map(k => ECPublicKey(k.hex)) } @@ -146,8 +162,8 @@ sealed trait P2SHScriptSignature extends ScriptSignature { /** The digital signatures inside of the scriptSig */ def signatures: Seq[ECDigitalSignature] = { val sigs = { - scriptSignatureNoRedeemScript - .asm.filter(_.isInstanceOf[ScriptConstant]) + scriptSignatureNoRedeemScript.asm + .filter(_.isInstanceOf[ScriptConstant]) .filterNot(_.isInstanceOf[ScriptNumberOperation]) .filterNot(_.hex.length < 100) } @@ -167,13 +183,18 @@ sealed trait P2SHScriptSignature extends ScriptSignature { } object P2SHScriptSignature extends ScriptFactory[P2SHScriptSignature] { - private case class P2SHScriptSignatureImpl(override val asm: Vector[ScriptToken]) extends P2SHScriptSignature + private case class P2SHScriptSignatureImpl( + override val asm: Vector[ScriptToken]) + extends P2SHScriptSignature - def apply(scriptSig: ScriptSignature, redeemScript: ScriptPubKey): P2SHScriptSignature = { + def apply( + scriptSig: ScriptSignature, + redeemScript: ScriptPubKey): P2SHScriptSignature = { //we need to calculate the size of the redeemScript and add the corresponding push op val serializedRedeemScript = ScriptConstant(redeemScript.asmBytes) val pushOps = BitcoinScriptUtil.calculatePushOp(serializedRedeemScript) - val asm: Seq[ScriptToken] = scriptSig.asm ++ pushOps ++ Seq(serializedRedeemScript) + val asm: Seq[ScriptToken] = scriptSig.asm ++ pushOps ++ Seq( + serializedRedeemScript) fromAsm(asm) } @@ -187,18 +208,20 @@ object P2SHScriptSignature extends ScriptFactory[P2SHScriptSignature] { //we have a P2SHScriptPubKey //previously P2SHScriptSignature's redeem script had to be standard scriptPubKey's, this //was removed in 0.11 or 0.12 of Bitcoin Core - buildScript( - asm = asm.toVector, - constructor = P2SHScriptSignatureImpl(_), - invariant = { _ => true }, - errorMsg = s"Given asm tokens are not a p2sh scriptSig, got: $asm") + buildScript(asm = asm.toVector, + constructor = P2SHScriptSignatureImpl(_), + invariant = { _ => + true + }, + errorMsg = + s"Given asm tokens are not a p2sh scriptSig, got: $asm") } /** Tests if the given asm tokens are a [[P2SHScriptSignature]] */ def isP2SHScriptSig(asm: Seq[ScriptToken]): Boolean = asm match { - case _ if asm.size > 1 && isRedeemScript(asm.last) => true + case _ if asm.size > 1 && isRedeemScript(asm.last) => true case _ if WitnessScriptPubKey.isWitnessScriptPubKey(asm) => true - case _ => false + case _ => false } /** Detects if the given script token is a redeem script */ @@ -207,12 +230,13 @@ object P2SHScriptSignature extends ScriptFactory[P2SHScriptSignature] { redeemScriptTry match { case Success(redeemScript) => redeemScript match { - case _: P2PKHScriptPubKey | _: MultiSignatureScriptPubKey - | _: P2SHScriptPubKey | _: P2PKScriptPubKey - | _: CLTVScriptPubKey | _: CSVScriptPubKey - | _: WitnessScriptPubKeyV0 | _: UnassignedWitnessScriptPubKey => true + case _: P2PKHScriptPubKey | _: MultiSignatureScriptPubKey | + _: P2SHScriptPubKey | _: P2PKScriptPubKey | _: CLTVScriptPubKey | + _: CSVScriptPubKey | _: WitnessScriptPubKeyV0 | + _: UnassignedWitnessScriptPubKey => + true case _: NonStandardScriptPubKey | _: WitnessCommitment => false - case EmptyScriptPubKey => false + case EmptyScriptPubKey => false } case Failure(_) => false } @@ -236,18 +260,23 @@ sealed trait MultiSignatureScriptSignature extends ScriptSignature { /** The digital signatures inside of the scriptSig */ def signatures: Seq[ECDigitalSignature] = { - asm.tail.filter(_.isInstanceOf[ScriptConstant]) + asm.tail + .filter(_.isInstanceOf[ScriptConstant]) .map(sig => ECDigitalSignature(sig.hex)) } override def toString = "MultiSignatureScriptSignature(" + hex + ")" } -object MultiSignatureScriptSignature extends ScriptFactory[MultiSignatureScriptSignature] { +object MultiSignatureScriptSignature + extends ScriptFactory[MultiSignatureScriptSignature] { - private case class MultiSignatureScriptSignatureImpl(override val asm: Vector[ScriptToken]) extends MultiSignatureScriptSignature + private case class MultiSignatureScriptSignatureImpl( + override val asm: Vector[ScriptToken]) + extends MultiSignatureScriptSignature - def apply(signatures: Seq[ECDigitalSignature]): MultiSignatureScriptSignature = { + def apply( + signatures: Seq[ECDigitalSignature]): MultiSignatureScriptSignature = { val sigsPushOpsPairs: Seq[Seq[ScriptToken]] = for { sig <- signatures constant = ScriptConstant(sig.bytes) @@ -264,7 +293,9 @@ object MultiSignatureScriptSignature extends ScriptFactory[MultiSignatureScriptS asm = asm.toVector, constructor = MultiSignatureScriptSignatureImpl(_), invariant = isMultiSignatureScriptSignature(_), - errorMsg = s"The given asm tokens were not a multisignature script sig: $asm") + errorMsg = + s"The given asm tokens were not a multisignature script sig: $asm" + ) } /** @@ -274,15 +305,21 @@ object MultiSignatureScriptSignature extends ScriptFactory[MultiSignatureScriptS * @param asm the asm to check if it falls in the multisignature script sig format * @return boolean indicating if the scriptsignature is a multisignature script signature */ - def isMultiSignatureScriptSignature(asm: Seq[ScriptToken]): Boolean = asm.isEmpty match { - case true => false - //case false if (asm.size == 1) => false - case false => - val firstTokenIsScriptNumberOperation = asm.head.isInstanceOf[ScriptNumberOperation] - val restOfScriptIsPushOpsOrScriptConstants = asm.tail.map( - token => token.isInstanceOf[ScriptConstant] || StackPushOperationFactory.isPushOperation(token)).exists(_ == false) - firstTokenIsScriptNumberOperation && !restOfScriptIsPushOpsOrScriptConstants - } + def isMultiSignatureScriptSignature(asm: Seq[ScriptToken]): Boolean = + asm.isEmpty match { + case true => false + //case false if (asm.size == 1) => false + case false => + val firstTokenIsScriptNumberOperation = + asm.head.isInstanceOf[ScriptNumberOperation] + val restOfScriptIsPushOpsOrScriptConstants = asm.tail + .map( + token => + token.isInstanceOf[ScriptConstant] || StackPushOperationFactory + .isPushOperation(token)) + .exists(_ == false) + firstTokenIsScriptNumberOperation && !restOfScriptIsPushOpsOrScriptConstants + } } /** @@ -304,7 +341,9 @@ sealed trait P2PKScriptSignature extends ScriptSignature { } object P2PKScriptSignature extends ScriptFactory[P2PKScriptSignature] { - private case class P2PKScriptSignatureImpl(override val asm: Vector[ScriptToken]) extends P2PKScriptSignature + private case class P2PKScriptSignatureImpl( + override val asm: Vector[ScriptToken]) + extends P2PKScriptSignature def apply(signature: ECDigitalSignature): P2PKScriptSignature = { val pushOps = BitcoinScriptUtil.calculatePushOp(signature.bytes) @@ -314,14 +353,16 @@ object P2PKScriptSignature extends ScriptFactory[P2PKScriptSignature] { } def fromAsm(asm: Seq[ScriptToken]): P2PKScriptSignature = { - buildScript(asm.toVector, P2PKScriptSignatureImpl(_), isP2PKScriptSignature(_), - "The given asm tokens were not a p2pk script sig: " + asm) + buildScript(asm.toVector, + P2PKScriptSignatureImpl(_), + isP2PKScriptSignature(_), + "The given asm tokens were not a p2pk script sig: " + asm) } /** P2PK scriptSigs always have the pattern [pushop, digitalSignature] */ def isP2PKScriptSignature(asm: Seq[ScriptToken]): Boolean = asm match { case Seq(_: BytesToPushOntoStack, _: ScriptConstant) => true - case _ => false + case _ => false } } @@ -342,14 +383,17 @@ sealed trait CLTVScriptSignature extends LockTimeScriptSignature { * [[CLTVScriptPubKey]] does not manipulate the stack */ object CLTVScriptSignature extends ScriptFactory[CLTVScriptSignature] { - private case class CLTVScriptSignatureImpl(override val asm: Vector[ScriptToken]) extends CLTVScriptSignature + private case class CLTVScriptSignatureImpl( + override val asm: Vector[ScriptToken]) + extends CLTVScriptSignature override def fromAsm(asm: Seq[ScriptToken]): CLTVScriptSignature = { - buildScript( - asm = asm.toVector, - constructor = CLTVScriptSignatureImpl(_), - invariant = { _ => true }, - errorMsg = s"Given asm was not a CLTVScriptSignature $asm") + buildScript(asm = asm.toVector, + constructor = CLTVScriptSignatureImpl(_), + invariant = { _ => + true + }, + errorMsg = s"Given asm was not a CLTVScriptSignature $asm") } override def fromHex(hex: String): CLTVScriptSignature = { @@ -366,14 +410,17 @@ sealed trait CSVScriptSignature extends LockTimeScriptSignature { } object CSVScriptSignature extends ScriptFactory[CSVScriptSignature] { - private case class CSVScriptSignatureImpl(override val asm: Vector[ScriptToken]) extends CSVScriptSignature + private case class CSVScriptSignatureImpl( + override val asm: Vector[ScriptToken]) + extends CSVScriptSignature override def fromAsm(asm: Seq[ScriptToken]): CSVScriptSignature = { - buildScript( - asm = asm.toVector, - constructor = CSVScriptSignatureImpl(_), - invariant = { _ => true }, - errorMsg = s"Given asm was not a CLTVScriptSignature $asm") + buildScript(asm = asm.toVector, + constructor = CSVScriptSignatureImpl(_), + invariant = { _ => + true + }, + errorMsg = s"Given asm was not a CLTVScriptSignature $asm") } override def fromHex(hex: String): CSVScriptSignature = { @@ -399,12 +446,18 @@ object ScriptSignature extends ScriptFactory[ScriptSignature] { /** Creates a scriptSignature from the list of script tokens */ def fromAsm(tokens: Seq[ScriptToken]): ScriptSignature = tokens match { case Nil => EmptyScriptSignature - case _ if (tokens.size > 1 && P2SHScriptSignature.isRedeemScript(tokens.last)) => + case _ + if (tokens.size > 1 && P2SHScriptSignature.isRedeemScript( + tokens.last)) => P2SHScriptSignature.fromAsm(tokens) - case _ if (MultiSignatureScriptSignature.isMultiSignatureScriptSignature(tokens)) => + case _ + if (MultiSignatureScriptSignature.isMultiSignatureScriptSignature( + tokens)) => MultiSignatureScriptSignature.fromAsm(tokens) - case _ if P2PKHScriptSignature.isP2PKHScriptSig(tokens) => P2PKHScriptSignature.fromAsm(tokens) - case _ if P2PKScriptSignature.isP2PKScriptSignature(tokens) => P2PKScriptSignature.fromAsm(tokens) + case _ if P2PKHScriptSignature.isP2PKHScriptSig(tokens) => + P2PKHScriptSignature.fromAsm(tokens) + case _ if P2PKScriptSignature.isP2PKScriptSignature(tokens) => + P2PKScriptSignature.fromAsm(tokens) case _ => NonStandardScriptSignature.fromAsm(tokens) } @@ -414,21 +467,32 @@ object ScriptSignature extends ScriptFactory[ScriptSignature] { * @param scriptPubKey the scriptPubKey which the script signature is trying to spend * @return */ - def fromScriptPubKey(tokens: Seq[ScriptToken], scriptPubKey: ScriptPubKey): Try[ScriptSignature] = scriptPubKey match { - case _: P2SHScriptPubKey => Try(P2SHScriptSignature.fromAsm(tokens)) + def fromScriptPubKey( + tokens: Seq[ScriptToken], + scriptPubKey: ScriptPubKey): Try[ScriptSignature] = scriptPubKey match { + case _: P2SHScriptPubKey => Try(P2SHScriptSignature.fromAsm(tokens)) case _: P2PKHScriptPubKey => Try(P2PKHScriptSignature.fromAsm(tokens)) - case _: P2PKScriptPubKey => Try(P2PKScriptSignature.fromAsm(tokens)) - case _: MultiSignatureScriptPubKey => Try(MultiSignatureScriptSignature.fromAsm(tokens)) - case _: NonStandardScriptPubKey => Try(NonStandardScriptSignature.fromAsm(tokens)) + case _: P2PKScriptPubKey => Try(P2PKScriptSignature.fromAsm(tokens)) + case _: MultiSignatureScriptPubKey => + Try(MultiSignatureScriptSignature.fromAsm(tokens)) + case _: NonStandardScriptPubKey => + Try(NonStandardScriptSignature.fromAsm(tokens)) case s: CLTVScriptPubKey => fromScriptPubKey(tokens, s.nestedScriptPubKey) - case s: CSVScriptPubKey => fromScriptPubKey(tokens, s.nestedScriptPubKey) - case _: WitnessScriptPubKeyV0 | _: UnassignedWitnessScriptPubKey => Success(EmptyScriptSignature) + case s: CSVScriptPubKey => fromScriptPubKey(tokens, s.nestedScriptPubKey) + case _: WitnessScriptPubKeyV0 | _: UnassignedWitnessScriptPubKey => + Success(EmptyScriptSignature) case EmptyScriptPubKey => - if (tokens.isEmpty) Success(EmptyScriptSignature) else Try(NonStandardScriptSignature.fromAsm(tokens)) - case _: WitnessCommitment => Failure(new IllegalArgumentException("Cannot spend witness commitment scriptPubKey")) + if (tokens.isEmpty) Success(EmptyScriptSignature) + else Try(NonStandardScriptSignature.fromAsm(tokens)) + case _: WitnessCommitment => + Failure( + new IllegalArgumentException( + "Cannot spend witness commitment scriptPubKey")) } - def apply(tokens: Seq[ScriptToken], scriptPubKey: ScriptPubKey): Try[ScriptSignature] = { + def apply( + tokens: Seq[ScriptToken], + scriptPubKey: ScriptPubKey): Try[ScriptSignature] = { fromScriptPubKey(tokens, scriptPubKey) } -} \ No newline at end of file +} diff --git a/core/src/main/scala/org/bitcoins/core/protocol/script/ScriptWitness.scala b/core/src/main/scala/org/bitcoins/core/protocol/script/ScriptWitness.scala index fa297c4e24..ff2c33bda4 100644 --- a/core/src/main/scala/org/bitcoins/core/protocol/script/ScriptWitness.scala +++ b/core/src/main/scala/org/bitcoins/core/protocol/script/ScriptWitness.scala @@ -71,10 +71,9 @@ object P2WPKHWitnessV0 { scriptSig match { case p2pkh: P2PKHScriptSignature => P2WPKHWitnessV0(p2pkh.publicKey, p2pkh.signature) - case x @ (_: LockTimeScriptSignature | - _: MultiSignatureScriptSignature | _: NonStandardScriptSignature | - _: P2PKScriptSignature | _: P2SHScriptSignature | - EmptyScriptSignature) => + case x @ (_: LockTimeScriptSignature | _: MultiSignatureScriptSignature | + _: NonStandardScriptSignature | _: P2PKScriptSignature | + _: P2SHScriptSignature | EmptyScriptSignature) => throw new IllegalArgumentException( s"Expected P2PKHScriptSignature, got $x") } diff --git a/core/src/main/scala/org/bitcoins/core/script/interpreter/ScriptInterpreter.scala b/core/src/main/scala/org/bitcoins/core/script/interpreter/ScriptInterpreter.scala index 4112acef84..6bf4a16fb2 100644 --- a/core/src/main/scala/org/bitcoins/core/script/interpreter/ScriptInterpreter.scala +++ b/core/src/main/scala/org/bitcoins/core/script/interpreter/ScriptInterpreter.scala @@ -96,8 +96,7 @@ sealed abstract class ScriptInterpreter { case _: P2PKHScriptPubKey | _: P2PKScriptPubKey | _: MultiSignatureScriptPubKey | _: CSVScriptPubKey | _: CLTVScriptPubKey | _: NonStandardScriptPubKey | - _: WitnessCommitment | - EmptyScriptPubKey => + _: WitnessCommitment | EmptyScriptPubKey => scriptPubKeyExecutedProgram } } diff --git a/core/src/main/scala/org/bitcoins/core/serializers/script/RawScriptPubKeyParser.scala b/core/src/main/scala/org/bitcoins/core/serializers/script/RawScriptPubKeyParser.scala index 70f251f08f..d9f508198e 100644 --- a/core/src/main/scala/org/bitcoins/core/serializers/script/RawScriptPubKeyParser.scala +++ b/core/src/main/scala/org/bitcoins/core/serializers/script/RawScriptPubKeyParser.scala @@ -13,13 +13,12 @@ trait RawScriptPubKeyParser extends RawBitcoinSerializer[ScriptPubKey] { override def read(bytes: ByteVector): ScriptPubKey = { if (bytes.isEmpty) EmptyScriptPubKey else { - BitcoinScriptUtil.parseScript( - bytes = bytes, - f = ScriptPubKey.fromAsm) + BitcoinScriptUtil.parseScript(bytes = bytes, f = ScriptPubKey.fromAsm) } } - override def write(scriptPubKey: ScriptPubKey): ByteVector = scriptPubKey.bytes + override def write(scriptPubKey: ScriptPubKey): ByteVector = + scriptPubKey.bytes } -object RawScriptPubKeyParser extends RawScriptPubKeyParser \ No newline at end of file +object RawScriptPubKeyParser extends RawScriptPubKeyParser diff --git a/core/src/main/scala/org/bitcoins/core/serializers/script/RawScriptSignatureParser.scala b/core/src/main/scala/org/bitcoins/core/serializers/script/RawScriptSignatureParser.scala index c625d8ce24..9bc16ce4cd 100644 --- a/core/src/main/scala/org/bitcoins/core/serializers/script/RawScriptSignatureParser.scala +++ b/core/src/main/scala/org/bitcoins/core/serializers/script/RawScriptSignatureParser.scala @@ -8,18 +8,17 @@ import scodec.bits.ByteVector /** * Created by chris on 1/12/16. */ -sealed abstract class RawScriptSignatureParser extends RawBitcoinSerializer[ScriptSignature] { +sealed abstract class RawScriptSignatureParser + extends RawBitcoinSerializer[ScriptSignature] { def read(bytes: ByteVector): ScriptSignature = { if (bytes.isEmpty) EmptyScriptSignature else { - BitcoinScriptUtil.parseScript( - bytes = bytes, - f = ScriptSignature.fromAsm) + BitcoinScriptUtil.parseScript(bytes = bytes, f = ScriptSignature.fromAsm) } } def write(scriptSig: ScriptSignature): ByteVector = scriptSig.bytes } -object RawScriptSignatureParser extends RawScriptSignatureParser \ No newline at end of file +object RawScriptSignatureParser extends RawScriptSignatureParser diff --git a/core/src/main/scala/org/bitcoins/core/util/BitcoinScriptUtil.scala b/core/src/main/scala/org/bitcoins/core/util/BitcoinScriptUtil.scala index f861c39947..e3f358fd70 100644 --- a/core/src/main/scala/org/bitcoins/core/util/BitcoinScriptUtil.scala +++ b/core/src/main/scala/org/bitcoins/core/util/BitcoinScriptUtil.scala @@ -4,12 +4,29 @@ import org.bitcoins.core.consensus.Consensus import org.bitcoins.core.crypto._ import org.bitcoins.core.number.UInt32 import org.bitcoins.core.protocol.CompactSizeUInt -import org.bitcoins.core.protocol.script.{CLTVScriptPubKey, CSVScriptPubKey, EmptyScriptPubKey, _} +import org.bitcoins.core.protocol.script.{ + CLTVScriptPubKey, + CSVScriptPubKey, + EmptyScriptPubKey, + _ +} import org.bitcoins.core.script.constant._ -import org.bitcoins.core.script.crypto.{OP_CHECKMULTISIG, OP_CHECKMULTISIGVERIFY, OP_CHECKSIG, OP_CHECKSIGVERIFY} +import org.bitcoins.core.script.crypto.{ + OP_CHECKMULTISIG, + OP_CHECKMULTISIGVERIFY, + OP_CHECKSIG, + OP_CHECKSIGVERIFY +} import org.bitcoins.core.script.flag.{ScriptFlag, ScriptFlagUtil} -import org.bitcoins.core.script.result.{ScriptError, ScriptErrorPubKeyType, ScriptErrorWitnessPubKeyType} -import org.bitcoins.core.script.{ExecutionInProgressScriptProgram, ScriptProgram} +import org.bitcoins.core.script.result.{ + ScriptError, + ScriptErrorPubKeyType, + ScriptErrorWitnessPubKeyType +} +import org.bitcoins.core.script.{ + ExecutionInProgressScriptProgram, + ScriptProgram +} import org.bitcoins.core.serializers.script.ScriptParser import scodec.bits.ByteVector @@ -390,7 +407,8 @@ trait BitcoinScriptUtil extends BitcoinSLogger { } case _: P2PKHScriptPubKey | _: P2PKScriptPubKey | _: MultiSignatureScriptPubKey | _: NonStandardScriptPubKey | - _: CLTVScriptPubKey | _: CSVScriptPubKey | _: WitnessCommitment | EmptyScriptPubKey => + _: CLTVScriptPubKey | _: CSVScriptPubKey | _: WitnessCommitment | + EmptyScriptPubKey => script } @@ -507,12 +525,15 @@ trait BitcoinScriptUtil extends BitcoinSLogger { } } - def parseScript[T <: Script](bytes: ByteVector, f: Vector[ScriptToken] => T): T = { + def parseScript[T <: Script]( + bytes: ByteVector, + f: Vector[ScriptToken] => T): T = { val compactSizeUInt = CompactSizeUInt.parseCompactSizeUInt(bytes) //TODO: Figure out a better way to do this, we can theoretically have numbers larger than Int.MaxValue, //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) + val scriptPubKeyBytes = + bytes.slice(compactSizeUInt.size.toInt, len + compactSizeUInt.size.toInt) val script: List[ScriptToken] = ScriptParser.fromBytes(scriptPubKeyBytes) f(script.toVector) } diff --git a/core/src/main/scala/org/bitcoins/core/wallet/builder/TxBuilderError.scala b/core/src/main/scala/org/bitcoins/core/wallet/builder/TxBuilderError.scala index c166b76f9c..01157799cd 100644 --- a/core/src/main/scala/org/bitcoins/core/wallet/builder/TxBuilderError.scala +++ b/core/src/main/scala/org/bitcoins/core/wallet/builder/TxBuilderError.scala @@ -3,7 +3,7 @@ package org.bitcoins.core.wallet.builder import scala.util.Failure /** - * Represents an error that can be returned by the [[org.bitcoins.core.wallet.builder.TxBuilder]] + * Represents an error that can be returned by the [[org.bitcoins.core.wallet.builder.TxBuilder TxBuilder]] * if it failed to sign a set of utxos */ sealed abstract class TxBuilderError @@ -20,7 +20,7 @@ object TxBuilderError { "This tx fails the invariants function you passed in")) /** - * Means that we gave too many [[org.bitcoins.core.wallet.signer.Signer.Sign]] for the TxBuilder + * Means that we gave too many [[org.bitcoins.core.crypto.Sign Sign]] for the TxBuilder * to use during the signing process for a utxo. * An example of this occurring is if we gave 2 private keys to sign a p2pkh spk. * A p2pkh only requires one private key to sign the utxo. @@ -30,29 +30,30 @@ object TxBuilderError { "You passed in too many signers for this scriptPubKey type")) /** - * Means that you are using the wrong [[org.bitcoins.core.wallet.signer.Signer]] to - * sign the given [[org.bitcoins.core.protocol.script.ScriptPubKey]] + * Means that you are using the wrong [[org.bitcoins.core.wallet.signer.Signer Signer]] to + * sign the given [[org.bitcoins.core.protocol.script.ScriptPubKey ScriptPubKey]] */ val WrongSigner = Failure(new IllegalArgumentException( "You did not pass in the write Signer to sign the given transaction, you probably gave the wrong identifier")) /** - * Means that the [[org.bitcoins.core.protocol.script.ScriptWitnessV0]] you passed as an argument does - * not hash to the commitment inside of [[org.bitcoins.core.protocol.script.P2WSHWitnessSPKV0]] + * Means that the [[org.bitcoins.core.protocol.script.ScriptWitnessV0 ScriptWitnessV0]] you passed as an argument does + * not hash to the commitment inside of [[org.bitcoins.core.protocol.script.P2WSHWitnessSPKV0 P2WSHWitnessSPKV0]] */ val WrongWitness = Failure(new IllegalArgumentException( "You passed in the wrong ScriptWitness type to sign the given WitnessScriptPubKey")) /** * Means that the redeem script you passed as an argument does not hash to the commitment - * inside of the [[org.bitcoins.core.protocol.script.P2SHScriptPubKey]] + * inside of the [[org.bitcoins.core.protocol.script.P2SHScriptPubKey P2SHScriptPubKey]] */ val WrongRedeemScript = Failure(new IllegalArgumentException( "Means that the redeem script you passed as an argument does not hash to the commitment")) /** - * Means that you passed the wrong public key for a [[org.bitcoins.core.protocol.script.P2PKHScriptPubKey]] or a - * [[org.bitcoins.core.protocol.script.P2WPKHWitnessSPKV0]] that you are trying to spend + * Means that you passed the wrong public key for a + * [[org.bitcoins.core.protocol.script.P2PKHScriptPubKey P2PKHScriptPubKey]] or a + * [[org.bitcoins.core.protocol.script.P2WPKHWitnessSPKV0 P2WPKHWitnessSPKV0]] that you are trying to spend */ //case object WrongPublicKey extends TxBuilderError val WrongPublicKey = Failure( @@ -60,7 +61,8 @@ object TxBuilderError { "You passed in the wrong public key to sign a P2PKHScriptPubKey")) /** - * Can occurr when we are trying to sign a [[org.bitcoins.core.protocol.script.P2SHScriptPubKey]] but + * Can occurr when we are trying to sign a + * [[org.bitcoins.core.protocol.script.P2SHScriptPubKey P2SHScriptPubKey]] but * we do not have a redeem script for that p2sh spk. */ //case object NoRedeemScript extends TxBuilderError @@ -69,30 +71,38 @@ object TxBuilderError { "We are missing a redeem script to sign a transaction")) /** - * Can occurr when we are trying to sign a [[org.bitcoins.core.protocol.script.WitnessScriptPubKey]] - * but we do not have a [[org.bitcoins.core.protocol.script.ScriptWitness]] for that witness spk + * Can occurr when we are trying to sign a + * [[org.bitcoins.core.protocol.script.WitnessScriptPubKey WitnessScriptPubKey]] + * but we do not have a [[org.bitcoins.core.protocol.script.ScriptWitness ScriptWitness]] for that witness spk */ //case object NoWitness extends TxBuilderError val NoWitness = Failure( new IllegalArgumentException("We are missing a witness redeem script")) - /** We expected a [[org.bitcoins.core.protocol.script.WitnessScriptPubKeyV0]], but got a non witness spk type */ + /** We expected a + * [[org.bitcoins.core.protocol.script.WitnessScriptPubKeyV0 WitnessScriptPubKeyV0]], + * but got a non witness spk type */ val NonWitnessSPK = Failure( new IllegalArgumentException( "We expected a witness spk, but got a non witness spk")) - /** We cannot have a [[org.bitcoins.core.protocol.script.WitnessScriptPubKey]] nested inside of another [[org.bitcoins.core.protocol.script.ScriptPubKey]] */ + /** We cannot have a + * [[org.bitcoins.core.protocol.script.WitnessScriptPubKey WitnessScriptPubKey]] nested inside of another + * [[org.bitcoins.core.protocol.script.ScriptPubKey ScriptPubKey]] */ //case object NestedWitnessSPK extends TxBuilderError val NestedWitnessSPK = Failure( new IllegalArgumentException("We cannot nested witness SPKs")) - /** We cannot have a [[org.bitcoins.core.protocol.script.P2SHScriptPubKey]] nested inside of another spk */ + /** We cannot have a [[org.bitcoins.core.protocol.script.P2SHScriptPubKey P2SHScriptPubKey]] + * nested inside of another spk */ val NestedP2SHSPK = Failure( new IllegalArgumentException("We cannot sign nested P2SHScriptPubKeys")) /** - * Means that there is no signer defined for the given [[org.bitcoins.core.protocol.script.ScriptPubKey]] type. - * An example of a spk with no signer that is defined is [[org.bitcoins.core.protocol.script.WitnessCommitment]] + * Means that there is no signer defined for the given + * [[org.bitcoins.core.protocol.script.ScriptPubKey ScriptPubKey]] type. + * An example of a spk with no signer that is defined is + * [[org.bitcoins.core.protocol.script.WitnessCommitment WitnessCommitment]] */ val NoSigner = Failure( new IllegalArgumentException( @@ -106,7 +116,9 @@ object TxBuilderError { val FeeToLarge = Failure(new IllegalArgumentException("Fee too large")) /** - * Means that the [[TxBuilder.destinations]] outputs you specified when creating the [[TxBuilder]] are NOT + * Means that the + * [[org.bitcoins.core.wallet.builder.TxBuilder.destinations TxBuilder.destinations]] + * outputs you specified when creating the [[org.bitcoins.core.wallet.builder.TxBuilder TxBuilder]] are NOT * all included in the final signed tx */ val MissingDestinationOutput = Failure( @@ -115,7 +127,7 @@ object TxBuilderError { /** * Means that the script we are signing for requires a public key, but we did not pass one in - * as a parameter inside of [[org.bitcoins.core.crypto.Sign]] + * as a parameter inside of [[org.bitcoins.core.crypto.Sign Sign]] */ val MissingPublicKey = Failure( new IllegalArgumentException( @@ -127,7 +139,9 @@ object TxBuilderError { /** * Means that the signed version of this transaction has MORE outputs than what was specified - * when building the [[TxBuilder]]. [[TxBuilder.destinations]] && [[TxBuilder.changeOutput]] should + * when building the [[org.bitcoins.core.wallet.builder.TxBuilder TxBuilder]]. + * [[org.bitcoins.core.wallet.builder.TxBuilder.destinations TxBuilder.destinations]] && + * [[org.bitcoins.core.wallet.builder.TxBuilder.changeSPK TxBuilder.changeSPK]] should * be the only outputs in the signedTx */ val ExtraOutputsAdded = Failure(new IllegalArgumentException( @@ -135,7 +149,9 @@ object TxBuilderError { /** * Means that the transaction spends outpoints that were not given when creating - * the [[TxBuilder]], aka, we should only spend outpoints in [[TxBuilder.outPoints]] + * the [[org.bitcoins.core.wallet.builder.TxBuilder TxBuilder]], aka, we should + * only spend outpoints in + * [[org.bitcoins.core.wallet.builder.TxBuilder.outPoints TxBuilder.outPoints]] */ val ExtraOutPoints = Failure(new IllegalArgumentException( "Means that the transaction spends outpoints that were not given when creating the TxBuilder")) @@ -144,17 +160,20 @@ object TxBuilderError { val MintsMoney = Failure(new IllegalArgumentException( "This transaction creates spends more money than it was funded by the given utxos")) - /** Means that the fee was too low for [[TxBuilder.feeRate]] */ + /** Means that the fee was too low for + * [[org.bitcoins.core.wallet.builder.TxBuilder.feeRate TxBuilder.feeRate]] */ val LowFee = Failure( new IllegalArgumentException("Means that the fee was too low")) - /** Means tha this transaction pays too high of a fee for [[TxBuilder.feeRate]] */ + /** Means tha this transaction pays too high of a fee for + * [[org.bitcoins.core.wallet.builder.TxBuilder.feeRate TxBuilder.feeRate]] */ val HighFee = Failure( new IllegalArgumentException("Means that the fee was too high")) /** - * Indicates we are spending multiple [[org.bitcoins.core.protocol.script.CLTVScriptPubKey]], + * Indicates we are spending multiple + * [[org.bitcoins.core.protocol.script.CLTVScriptPubKey CLTVScriptPubKey]], * and that one of those spk's outputs are locked by block height, while the other is locked by * a time stamp. Since there is only one locktime field on a transaction, we cannot satisfy both of these * locktimes simultaneously. @@ -162,7 +181,8 @@ object TxBuilderError { val IncompatibleLockTimes = Failure(new IllegalArgumentException( "Means you tried to spend an output that requires a lock by blockheight, and another output that requires a lock by timestamp")) - /** Means we have a output on this transaction below [[org.bitcoins.core.policy.Policy.dustThreshold]] */ + /** Means we have a output on this transaction below + * [[org.bitcoins.core.policy.Policy.dustThreshold Policy.dustThreshold]] */ val OutputBelowDustThreshold = Failure(new IllegalArgumentException( "The p2p network discourages outputs below the dustThreshold, this tx won't be relayed")) diff --git a/core/src/main/scala/org/bitcoins/core/wallet/signer/FundingInfo.scala b/core/src/main/scala/org/bitcoins/core/wallet/signer/FundingInfo.scala index 7f703bd51a..2b61dd4188 100644 --- a/core/src/main/scala/org/bitcoins/core/wallet/signer/FundingInfo.scala +++ b/core/src/main/scala/org/bitcoins/core/wallet/signer/FundingInfo.scala @@ -9,10 +9,11 @@ import org.bitcoins.core.wallet.utxo.{BitcoinUTXOSpendingInfo, UTXOSpendingInfo} /** * This meant to represent the class used to 'fund' an - * unsigned [[Transaction]]. - * This is useful for when we have multiple [[org.bitcoins.core.config.NetworkParameters]] + * unsigned [[org.bitcoins.core.protocol.transaction.Transaction Transaction]]. + * This is useful for when we have multiple [[org.bitcoins.core.config.NetworkParameters NetworkParameters]] * that each have their own transaction type. I.e. we should only be able to have - * BitcoinTransactions paired with [[BitcoinUTXOSpendingInfo]], the same would apply for litecoin etc. + * BitcoinTransactions paired with [[org.bitcoins.core.wallet.utxo.BitcoinUTXOSpendingInfo BitcoinUTXOSpendingInfo]], + * the same would apply for litecoin etc. */ sealed abstract class FundingInfo { diff --git a/core/src/main/scala/org/bitcoins/core/wallet/signer/Signer.scala b/core/src/main/scala/org/bitcoins/core/wallet/signer/Signer.scala index 2e39bb8caa..2ece97cf3b 100644 --- a/core/src/main/scala/org/bitcoins/core/wallet/signer/Signer.scala +++ b/core/src/main/scala/org/bitcoins/core/wallet/signer/Signer.scala @@ -399,8 +399,9 @@ sealed abstract class MultiSigSigner extends BitcoinSigner { Future.successful((m, lock)) case _: P2PKScriptPubKey | _: P2PKHScriptPubKey | _: P2SHScriptPubKey | _: P2WPKHWitnessSPKV0 | - _: P2WSHWitnessSPKV0 | _: WitnessCommitment| _: CSVScriptPubKey | - _: CLTVScriptPubKey | _: NonStandardScriptPubKey | + _: P2WSHWitnessSPKV0 | _: WitnessCommitment | + _: CSVScriptPubKey | _: CLTVScriptPubKey | + _: NonStandardScriptPubKey | _: UnassignedWitnessScriptPubKey | _: P2WPKHWitnessSPKV0 | EmptyScriptPubKey => Future.fromTry(TxBuilderError.WrongSigner) @@ -408,9 +409,9 @@ sealed abstract class MultiSigSigner extends BitcoinSigner { case m: MultiSignatureScriptPubKey => Future.successful((m, m)) case _: P2PKScriptPubKey | _: P2PKHScriptPubKey | _: P2SHScriptPubKey | _: P2WPKHWitnessSPKV0 | - _: P2WSHWitnessSPKV0 | _: WitnessCommitment| _: NonStandardScriptPubKey | - _: P2WPKHWitnessSPKV0 | _: UnassignedWitnessScriptPubKey | - EmptyScriptPubKey => + _: P2WSHWitnessSPKV0 | _: WitnessCommitment | + _: NonStandardScriptPubKey | _: P2WPKHWitnessSPKV0 | + _: UnassignedWitnessScriptPubKey | EmptyScriptPubKey => Future.fromTry(TxBuilderError.WrongSigner) } } @@ -485,8 +486,7 @@ sealed abstract class MultiSigSigner extends BitcoinSigner { _: P2WPKHWitnessSPKV0 | _: P2WSHWitnessSPKV0 | _: CLTVScriptPubKey | _: CSVScriptPubKey | _: UnassignedWitnessScriptPubKey | _: NonStandardScriptPubKey | - _: WitnessCommitment | - EmptyScriptPubKey => + _: WitnessCommitment | EmptyScriptPubKey => Future.fromTry(TxBuilderError.WrongSigner) } multiSigSPK.flatMap { mSPK => @@ -528,7 +528,8 @@ sealed abstract class MultiSigSigner extends BitcoinSigner { } case _: P2PKScriptPubKey | _: P2PKHScriptPubKey | _: P2SHScriptPubKey | _: P2WPKHWitnessSPKV0 | _: NonStandardScriptPubKey | - _: WitnessCommitment | _: UnassignedWitnessScriptPubKey | EmptyScriptPubKey => + _: WitnessCommitment | _: UnassignedWitnessScriptPubKey | + EmptyScriptPubKey => Future.fromTry(TxBuilderError.WrongSigner) } signed diff --git a/testkit/src/main/scala/org/bitcoins/core/gen/ScriptGenerators.scala b/testkit/src/main/scala/org/bitcoins/core/gen/ScriptGenerators.scala index fe91937b56..001c82caed 100644 --- a/testkit/src/main/scala/org/bitcoins/core/gen/ScriptGenerators.scala +++ b/testkit/src/main/scala/org/bitcoins/core/gen/ScriptGenerators.scala @@ -123,7 +123,7 @@ sealed abstract class ScriptGenerators extends BitcoinSLogger { (privateKeys, requiredSigs) <- CryptoGenerators.privateKeySeqWithRequiredSigs pubKeys = privateKeys.map(_.publicKey) multiSignatureScriptPubKey = MultiSignatureScriptPubKey(requiredSigs, - pubKeys) + pubKeys) } yield (multiSignatureScriptPubKey, privateKeys) def smallMultiSigScriptPubKey: Gen[ @@ -132,7 +132,7 @@ sealed abstract class ScriptGenerators extends BitcoinSLogger { (privateKeys, requiredSigs) <- CryptoGenerators.smallPrivateKeySeqWithRequiredSigs pubKeys = privateKeys.map(_.publicKey) multiSignatureScriptPubKey = MultiSignatureScriptPubKey(requiredSigs, - pubKeys) + pubKeys) } yield (multiSignatureScriptPubKey, privateKeys) def p2shScriptPubKey: Gen[(P2SHScriptPubKey, Seq[ECPrivateKey])] = @@ -172,11 +172,13 @@ sealed abstract class ScriptGenerators extends BitcoinSLogger { /** Generates an arbitrary [[org.bitcoins.core.protocol.script.WitnessScriptPubKey]] */ def witnessScriptPubKey: Gen[(WitnessScriptPubKey, Seq[ECPrivateKey])] = - Gen.oneOf(assignedWitnessScriptPubKey,unassignedWitnessScriptPubKey) + Gen.oneOf(assignedWitnessScriptPubKey, unassignedWitnessScriptPubKey) - def assignedWitnessScriptPubKey: Gen[(WitnessScriptPubKey, Seq[ECPrivateKey])] = { + def assignedWitnessScriptPubKey: Gen[ + (WitnessScriptPubKey, Seq[ECPrivateKey])] = { Gen.oneOf(p2wpkhSPKV0, p2wshSPKV0) } + def witnessCommitment: Gen[(WitnessCommitment, Seq[ECPrivateKey])] = for { hash <- CryptoGenerators.doubleSha256Digest @@ -203,16 +205,16 @@ sealed abstract class ScriptGenerators extends BitcoinSLogger { def randomNonLockTimeNonP2SHScriptPubKey: Gen[ (ScriptPubKey, Seq[ECPrivateKey])] = { Gen.oneOf(p2pkScriptPubKey.map(privKeyToSeq(_)), - p2pkhScriptPubKey.map(privKeyToSeq(_)), - multiSigScriptPubKey) + p2pkhScriptPubKey.map(privKeyToSeq(_)), + multiSigScriptPubKey) } def randomNonLockTimeScriptSig: Gen[ScriptSignature] = { Gen.oneOf(p2pkScriptSignature, - p2pkhScriptSignature, - multiSignatureScriptSignature, - emptyScriptSignature, - p2shScriptSignature) + p2pkhScriptSignature, + multiSignatureScriptSignature, + emptyScriptSignature, + p2shScriptSignature) } def lockTimeScriptPubKey: Gen[(LockTimeScriptPubKey, Seq[ECPrivateKey])] = @@ -257,7 +259,7 @@ sealed abstract class ScriptGenerators extends BitcoinSLogger { * Note: Does NOT generate a correct/valid signature */ private def pickCorrespondingScriptSignature( - scriptPubKey: ScriptPubKey): Gen[ScriptSignature] = scriptPubKey match { + scriptPubKey: ScriptPubKey): Gen[ScriptSignature] = scriptPubKey match { case _: P2PKScriptPubKey => p2pkScriptSignature case _: P2PKHScriptPubKey => p2pkhScriptSignature case _: MultiSignatureScriptPubKey => multiSignatureScriptSignature @@ -267,7 +269,7 @@ sealed abstract class ScriptGenerators extends BitcoinSLogger { case _: WitnessScriptPubKeyV0 | _: UnassignedWitnessScriptPubKey => emptyScriptSignature case x @ (_: P2SHScriptPubKey | _: NonStandardScriptPubKey | - _: WitnessCommitment) => + _: WitnessCommitment) => throw new IllegalArgumentException( "Cannot pick for p2sh script pubkey, " + "non standard script pubkey or witness commitment got: " + x) @@ -344,7 +346,7 @@ sealed abstract class ScriptGenerators extends BitcoinSLogger { * sequence of [[ECPrivateKey]] used to sign the scriptSig */ def signedMultiSignatureScriptSignature: Gen[( - MultiSignatureScriptSignature, + MultiSignatureScriptSignature, MultiSignatureScriptPubKey, Seq[ECPrivateKey])] = for { @@ -352,7 +354,7 @@ sealed abstract class ScriptGenerators extends BitcoinSLogger { hashType <- CryptoGenerators.hashType publicKeys = privateKeys.map(_.publicKey) multiSigScriptPubKey = MultiSignatureScriptPubKey(requiredSigs, - publicKeys) + publicKeys) emptyDigitalSignatures = privateKeys.map(_ => EmptyDigitalSignature) scriptSig = MultiSignatureScriptSignature(emptyDigitalSignatures) (creditingTx, outputIndex) = TransactionGenerators @@ -394,9 +396,9 @@ sealed abstract class ScriptGenerators extends BitcoinSLogger { * used to sign the scriptSig */ def signedCLTVScriptSignature( - cltvLockTime: ScriptNumber, - lockTime: UInt32, - sequence: UInt32): Gen[ + cltvLockTime: ScriptNumber, + lockTime: UInt32, + sequence: UInt32): Gen[ (CLTVScriptSignature, CLTVScriptPubKey, Seq[ECPrivateKey])] = for { (scriptPubKey, privKeys) <- randomNonLockTimeNonP2SHScriptPubKey @@ -407,26 +409,26 @@ sealed abstract class ScriptGenerators extends BitcoinSLogger { case m: MultiSignatureScriptPubKey => val requiredSigs = m.requiredSigs val cltvScriptSig = lockTimeHelper(Some(lockTime), - sequence, - cltv, - privKeys, - Some(requiredSigs), - hashType) + sequence, + cltv, + privKeys, + Some(requiredSigs), + hashType) (cltvScriptSig.asInstanceOf[CLTVScriptSignature], cltv, privKeys) case _: P2PKHScriptPubKey | _: P2PKScriptPubKey => val cltvScriptSig = lockTimeHelper(Some(lockTime), - sequence, - cltv, - privKeys, - None, - hashType) + sequence, + cltv, + privKeys, + None, + hashType) (cltvScriptSig.asInstanceOf[CLTVScriptSignature], cltv, privKeys) case _: UnassignedWitnessScriptPubKey | _: WitnessScriptPubKeyV0 => throw new IllegalArgumentException( "Cannot created a witness scriptPubKey for a CSVScriptSig since we do not have a witness") case _: P2SHScriptPubKey | _: CLTVScriptPubKey | _: CSVScriptPubKey | - _: NonStandardScriptPubKey | _: WitnessCommitment | - EmptyScriptPubKey => + _: NonStandardScriptPubKey | _: WitnessCommitment | + EmptyScriptPubKey => throw new IllegalArgumentException( "We only " + "want to generate P2PK, P2PKH, and MultiSig ScriptSignatures when creating a CSVScriptSignature") @@ -439,8 +441,8 @@ sealed abstract class ScriptGenerators extends BitcoinSLogger { * used to sign the scriptSig */ def signedCSVScriptSignature( - csvScriptNum: ScriptNumber, - sequence: UInt32): Gen[ + csvScriptNum: ScriptNumber, + sequence: UInt32): Gen[ (CSVScriptSignature, CSVScriptPubKey, Seq[ECPrivateKey])] = for { (scriptPubKey, privKeys) <- randomNonLockTimeNonP2SHScriptPubKey @@ -451,11 +453,11 @@ sealed abstract class ScriptGenerators extends BitcoinSLogger { case m: MultiSignatureScriptPubKey => val requiredSigs = m.requiredSigs val csvScriptSig = lockTimeHelper(None, - sequence, - csv, - privKeys, - Some(requiredSigs), - hashType) + sequence, + csv, + privKeys, + Some(requiredSigs), + hashType) (csvScriptSig.asInstanceOf[CSVScriptSignature], csv, privKeys) case _: P2PKHScriptPubKey | _: P2PKScriptPubKey => val csvScriptSig = @@ -465,8 +467,8 @@ sealed abstract class ScriptGenerators extends BitcoinSLogger { throw new IllegalArgumentException( "Cannot created a witness scriptPubKey for a CSVScriptSig since we do not have a witness") case _: P2SHScriptPubKey | _: CLTVScriptPubKey | _: CSVScriptPubKey | - _: NonStandardScriptPubKey | _: WitnessCommitment | - EmptyScriptPubKey => + _: NonStandardScriptPubKey | _: WitnessCommitment | + EmptyScriptPubKey => throw new IllegalArgumentException( "We only " + "want to generate P2PK, P2PKH, and MultiSig ScriptSignatures when creating a CLTVScriptSignature.") @@ -487,8 +489,8 @@ sealed abstract class ScriptGenerators extends BitcoinSLogger { txLockTime <- NumberGenerator.uInt32s sequence <- NumberGenerator.uInt32s scriptSig <- signedCLTVScriptSignature(cltv.locktime, - txLockTime, - sequence) + txLockTime, + sequence) } yield scriptSig /** Generates a [[LockTimeScriptSignature]] and [[LockTimeScriptPubKey]] pair that are valid when run through the interpreter */ @@ -499,12 +501,12 @@ sealed abstract class ScriptGenerators extends BitcoinSLogger { /** Helper function to generate [[LockTimeScriptSignature]]s */ private def lockTimeHelper( - lockTime: Option[UInt32], - sequence: UInt32, - lock: LockTimeScriptPubKey, - privateKeys: Seq[ECPrivateKey], - requiredSigs: Option[Int], - hashType: HashType): LockTimeScriptSignature = { + lockTime: Option[UInt32], + sequence: UInt32, + lock: LockTimeScriptPubKey, + privateKeys: Seq[ECPrivateKey], + requiredSigs: Option[Int], + hashType: HashType): LockTimeScriptSignature = { val tc = TransactionConstants val pubKeys = privateKeys.map(_.publicKey) val (creditingTx, outputIndex) = @@ -528,8 +530,8 @@ sealed abstract class ScriptGenerators extends BitcoinSLogger { i <- 0 until requiredSigs.getOrElse(1) } yield TransactionSignatureCreator.createSig(txSignatureComponent, - privateKeys(i), - hashType) + privateKeys(i), + hashType) lock match { case csv: CSVScriptPubKey => @@ -545,7 +547,7 @@ sealed abstract class ScriptGenerators extends BitcoinSLogger { def signedP2SHP2WPKHScriptSignature: Gen[ ( - P2SHScriptSignature, + P2SHScriptSignature, P2SHScriptPubKey, Seq[ECPrivateKey], TransactionWitness, @@ -557,14 +559,14 @@ sealed abstract class ScriptGenerators extends BitcoinSLogger { wtxSigComponent.scriptPubKey.asInstanceOf[WitnessScriptPubKey]) } yield (p2shScriptSig, - p2shScriptPubKey, - privKeys, - witness, - wtxSigComponent.amount) + p2shScriptPubKey, + privKeys, + witness, + wtxSigComponent.amount) def signedP2SHP2WSHScriptSignature: Gen[ ( - P2SHScriptSignature, + P2SHScriptSignature, P2SHScriptPubKey, Seq[ECPrivateKey], TransactionWitness, @@ -575,10 +577,10 @@ sealed abstract class ScriptGenerators extends BitcoinSLogger { p2shScriptSig = P2SHScriptSignature(wtxSigComponent.scriptPubKey) } yield (p2shScriptSig, - p2shScriptPubKey, - privKeys, - witness, - wtxSigComponent.amount) + p2shScriptPubKey, + privKeys, + witness, + wtxSigComponent.amount) /** * This function chooses a random signed [[ScriptSignature]] that is NOT a [[P2SHScriptSignature]], [[CSVScriptSignature]], @@ -616,7 +618,7 @@ sealed abstract class ScriptGenerators extends BitcoinSLogger { /** Simply converts one private key in the generator to a sequence of private keys */ private def packageToSequenceOfPrivateKeys( - gen: Gen[(ScriptSignature, ScriptPubKey, ECPrivateKey)]): Gen[ + gen: Gen[(ScriptSignature, ScriptPubKey, ECPrivateKey)]): Gen[ (ScriptSignature, ScriptPubKey, Seq[ECPrivateKey])] = for { (scriptSig, scriptPubKey, privateKey) <- gen @@ -624,16 +626,16 @@ sealed abstract class ScriptGenerators extends BitcoinSLogger { /** Simply converts one private key in the generator to a sequence of private keys */ private def privKeyToSeq(tuple: (ScriptPubKey, ECPrivateKey)): ( - ScriptPubKey, + ScriptPubKey, Seq[ECPrivateKey]) = { val (s, key) = tuple (s, Seq(key)) } private def lockTimeHelperScriptSig( - lock: LockTimeScriptPubKey, - sigs: Seq[ECDigitalSignature], - keys: Seq[ECPublicKey]): LockTimeScriptSignature = { + lock: LockTimeScriptPubKey, + sigs: Seq[ECDigitalSignature], + keys: Seq[ECPublicKey]): LockTimeScriptSignature = { val nestedScriptSig = lock.nestedScriptPubKey match { case _: P2PKScriptPubKey => P2PKScriptSignature(sigs.head) @@ -647,7 +649,7 @@ sealed abstract class ScriptGenerators extends BitcoinSLogger { throw new IllegalArgumentException( "Cannot have a nested locktimeScriptPubKey inside a lockTimeScriptPubKey") case x @ (_: NonStandardScriptPubKey | _: P2SHScriptPubKey | - _: WitnessCommitment) => + _: WitnessCommitment) => throw new IllegalArgumentException( "A NonStandardScriptPubKey/P2SHScriptPubKey/WitnessCommitment cannot be" + "the underlying scriptSig in a CSVScriptSignature. Got: " + x) @@ -660,4 +662,4 @@ sealed abstract class ScriptGenerators extends BitcoinSLogger { } } -object ScriptGenerators extends ScriptGenerators \ No newline at end of file +object ScriptGenerators extends ScriptGenerators diff --git a/testkit/src/main/scala/org/bitcoins/core/gen/WitnessGenerators.scala b/testkit/src/main/scala/org/bitcoins/core/gen/WitnessGenerators.scala index 9bd7e8eb59..70bfdc5240 100644 --- a/testkit/src/main/scala/org/bitcoins/core/gen/WitnessGenerators.scala +++ b/testkit/src/main/scala/org/bitcoins/core/gen/WitnessGenerators.scala @@ -85,25 +85,25 @@ sealed abstract class WitnessGenerators extends BitcoinSLogger { witScriptPubKey = P2WSHWitnessSPKV0(scriptPubKey) unsignedScriptWitness = P2WSHWitnessV0(scriptPubKey) u = createUnsignedRawWTxSigComponent(witScriptPubKey, - amount, - unsignedScriptWitness, - None) + amount, + unsignedScriptWitness, + None) createdSig = TransactionSignatureCreator.createSig(u, privKeys, hashType) signedScriptWitness = P2WSHWitnessV0(scriptPubKey, - P2PKScriptSignature(createdSig)) + P2PKScriptSignature(createdSig)) oldTx = u.transaction txWitness = TransactionWitness( oldTx.witness.witnesses .updated(u.inputIndex.toInt, signedScriptWitness)) wtx = WitnessTransaction(oldTx.version, - oldTx.inputs, - oldTx.outputs, - oldTx.lockTime, - txWitness) + oldTx.inputs, + oldTx.outputs, + oldTx.lockTime, + txWitness) signedWtxSigComponent = WitnessTxSigComponentRaw(wtx, - u.inputIndex, - u.output, - u.flags) + u.inputIndex, + u.output, + u.flags) } yield (txWitness, signedWtxSigComponent, Seq(privKeys)) def signedP2WSHP2PKHTransactionWitness: Gen[ @@ -115,9 +115,9 @@ sealed abstract class WitnessGenerators extends BitcoinSLogger { witScriptPubKey = P2WSHWitnessSPKV0(scriptPubKey) unsignedScriptWitness = P2WSHWitnessV0(scriptPubKey) u = createUnsignedRawWTxSigComponent(witScriptPubKey, - amount, - unsignedScriptWitness, - None) + amount, + unsignedScriptWitness, + None) createdSig = TransactionSignatureCreator.createSig(u, privKey, hashType) signedScriptWitness = P2WSHWitnessV0( scriptPubKey, @@ -127,14 +127,14 @@ sealed abstract class WitnessGenerators extends BitcoinSLogger { oldTx.witness.witnesses .updated(u.inputIndex.toInt, signedScriptWitness)) wtx = WitnessTransaction(oldTx.version, - oldTx.inputs, - oldTx.outputs, - oldTx.lockTime, - txWitness) + oldTx.inputs, + oldTx.outputs, + oldTx.lockTime, + txWitness) signedWtxSigComponent = WitnessTxSigComponentRaw(wtx, - u.inputIndex, - u.output, - u.flags) + u.inputIndex, + u.output, + u.flags) } yield (txWitness, signedWtxSigComponent, Seq(privKey)) def signedP2WSHMultiSigTransactionWitness: Gen[ @@ -146,27 +146,27 @@ sealed abstract class WitnessGenerators extends BitcoinSLogger { witScriptPubKey = P2WSHWitnessSPKV0(scriptPubKey) unsignedScriptWitness = P2WSHWitnessV0(scriptPubKey) u = createUnsignedRawWTxSigComponent(witScriptPubKey, - amount, - unsignedScriptWitness, - None) + amount, + unsignedScriptWitness, + None) signedScriptSig = multiSigScriptSigGenHelper(privKeys, - scriptPubKey, - u, - hashType) + scriptPubKey, + u, + hashType) signedScriptWitness = P2WSHWitnessV0(scriptPubKey, signedScriptSig) oldTx = u.transaction txWitness = TransactionWitness( oldTx.witness.witnesses .updated(u.inputIndex.toInt, signedScriptWitness)) wtx = WitnessTransaction(oldTx.version, - oldTx.inputs, - oldTx.outputs, - oldTx.lockTime, - txWitness) + oldTx.inputs, + oldTx.outputs, + oldTx.lockTime, + txWitness) signedWtxSigComponent = WitnessTxSigComponentRaw(wtx, - u.inputIndex, - u.output, - u.flags) + u.inputIndex, + u.output, + u.flags) } yield (txWitness, signedWtxSigComponent, privKeys) /** @@ -176,23 +176,23 @@ sealed abstract class WitnessGenerators extends BitcoinSLogger { def signedP2WSHTransactionWitness: Gen[ (TransactionWitness, WitnessTxSigComponentRaw, Seq[ECPrivateKey])] = { Gen.oneOf(signedP2WSHP2PKTransactionWitness, - signedP2WSHP2PKHTransactionWitness, - signedP2WSHMultiSigTransactionWitness) + signedP2WSHP2PKHTransactionWitness, + signedP2WSHMultiSigTransactionWitness) } /** Helps generate a signed [[MultiSignatureScriptSignature]] */ private def multiSigScriptSigGenHelper( - privateKeys: Seq[ECPrivateKey], - scriptPubKey: MultiSignatureScriptPubKey, - unsignedWtxSigComponent: WitnessTxSigComponent, - hashType: HashType): MultiSignatureScriptSignature = { + privateKeys: Seq[ECPrivateKey], + scriptPubKey: MultiSignatureScriptPubKey, + unsignedWtxSigComponent: WitnessTxSigComponent, + hashType: HashType): MultiSignatureScriptSignature = { val requiredSigs = scriptPubKey.requiredSigs val txSignatures = for { i <- 0 until requiredSigs } yield TransactionSignatureCreator.createSig(unsignedWtxSigComponent, - privateKeys(i), - hashType) + privateKeys(i), + hashType) //add the signature to the scriptSig instead of having an empty scriptSig val signedScriptSig = MultiSignatureScriptSignature(txSignatures) @@ -215,28 +215,28 @@ sealed abstract class WitnessGenerators extends BitcoinSLogger { /** Takes a signed [[ScriptWitness]] and an unsignedTx and adds the witness to the unsigned [[WitnessTransaction]] */ def createSignedWTxComponent( - witness: ScriptWitness, - unsignedWTxComponent: WitnessTxSigComponent): ( - TransactionWitness, + witness: ScriptWitness, + unsignedWTxComponent: WitnessTxSigComponent): ( + TransactionWitness, WitnessTxSigComponent) = { val signedTxWitness = TransactionWitness.fromWitOpt(Vector(Some(witness))) val unsignedSpendingTx = unsignedWTxComponent.transaction val signedSpendingTx = WitnessTransaction(unsignedSpendingTx.version, - unsignedSpendingTx.inputs, - unsignedSpendingTx.outputs, - unsignedSpendingTx.lockTime, - signedTxWitness) + unsignedSpendingTx.inputs, + unsignedSpendingTx.outputs, + unsignedSpendingTx.lockTime, + signedTxWitness) val signedWtxSigComponent = unsignedWTxComponent match { case wtxP2SH: WitnessTxSigComponentP2SH => WitnessTxSigComponent(signedSpendingTx, - unsignedWTxComponent.inputIndex, - wtxP2SH.output, - unsignedWTxComponent.flags) + unsignedWTxComponent.inputIndex, + wtxP2SH.output, + unsignedWTxComponent.flags) case wtxRaw: WitnessTxSigComponentRaw => WitnessTxSigComponent(signedSpendingTx, - unsignedWTxComponent.inputIndex, - wtxRaw.output, - unsignedWTxComponent.flags) + unsignedWTxComponent.inputIndex, + wtxRaw.output, + unsignedWTxComponent.flags) } (signedTxWitness, signedWtxSigComponent) @@ -244,10 +244,10 @@ sealed abstract class WitnessGenerators extends BitcoinSLogger { /** Creates a unsigned [[WitnessTxSigComponent]] from the given parameters */ def createUnsignedRawWTxSigComponent( - witScriptPubKey: WitnessScriptPubKey, - amount: CurrencyUnit, - unsignedScriptWitness: ScriptWitness, - sequence: Option[UInt32]): WitnessTxSigComponentRaw = { + witScriptPubKey: WitnessScriptPubKey, + amount: CurrencyUnit, + unsignedScriptWitness: ScriptWitness, + sequence: Option[UInt32]): WitnessTxSigComponentRaw = { val tc = TransactionConstants val flags = Policy.standardScriptVerifyFlags val witness = @@ -270,4 +270,4 @@ sealed abstract class WitnessGenerators extends BitcoinSLogger { } } -object WitnessGenerators extends WitnessGenerators \ No newline at end of file +object WitnessGenerators extends WitnessGenerators diff --git a/testkit/src/main/scala/org/bitcoins/core/gen/ln/LnRouteGen.scala b/testkit/src/main/scala/org/bitcoins/core/gen/ln/LnRouteGen.scala index 3452acd595..eec8a1813a 100644 --- a/testkit/src/main/scala/org/bitcoins/core/gen/ln/LnRouteGen.scala +++ b/testkit/src/main/scala/org/bitcoins/core/gen/ln/LnRouteGen.scala @@ -3,7 +3,10 @@ package org.bitcoins.core.gen.ln import org.bitcoins.core.gen.{CryptoGenerators, NumberGenerator} import org.bitcoins.core.protocol.ln.ShortChannelId import org.bitcoins.core.protocol.ln.currency.MilliSatoshis -import org.bitcoins.core.protocol.ln.fee.{FeeBaseMSat, FeeProportionalMillionths} +import org.bitcoins.core.protocol.ln.fee.{ + FeeBaseMSat, + FeeProportionalMillionths +} import org.bitcoins.core.protocol.ln.routing.LnRoute import org.scalacheck.Gen