mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2024-11-19 01:40:55 +01:00
2018 11 24 scala 2.12 warnings (#251)
* fixing compiler warnings for core module * fix rpc project compiler warnings for scalac 2.12 * revert default scala version to 2.11.12
This commit is contained in:
parent
953142c013
commit
fd810b8ab6
@ -156,7 +156,7 @@ sealed abstract class BloomFilter extends NetworkElement {
|
||||
//constants that matched inside of our current filter
|
||||
val constants = scriptPubKey.asm.filter(c => c.isInstanceOf[ScriptConstant] && contains(c.bytes))
|
||||
//we need to create a new outpoint in the filter if a constant in the scriptPubKey matched
|
||||
constants.map(c => TransactionOutPoint(transaction.txId, UInt32(index)))
|
||||
constants.map(_ => TransactionOutPoint(transaction.txId, UInt32(index)))
|
||||
}
|
||||
|
||||
logger.debug("Inserting outPoints: " + outPoints)
|
||||
@ -189,18 +189,18 @@ sealed abstract class BloomFilter extends NetworkElement {
|
||||
logger.debug("Found constant in bloom filter: " + h._1.hex)
|
||||
val filter = accumFilter.insert(TransactionOutPoint(txId, UInt32(h._2)))
|
||||
loop(t, filter)
|
||||
case h +: t => loop(t, accumFilter)
|
||||
case _ +: t => loop(t, accumFilter)
|
||||
case Nil => accumFilter
|
||||
}
|
||||
val p2pkOrMultiSigScriptPubKeys: Seq[(ScriptPubKey, Int)] = scriptPubKeysWithIndex.filter {
|
||||
case (s, index) => s.isInstanceOf[P2PKScriptPubKey] ||
|
||||
case (s, _) => s.isInstanceOf[P2PKScriptPubKey] ||
|
||||
s.isInstanceOf[MultiSignatureScriptPubKey]
|
||||
}
|
||||
//gets rid of all asm operations in the scriptPubKey except for the constants
|
||||
val scriptConstantsWithOutputIndex: Seq[(ScriptToken, Int)] = p2pkOrMultiSigScriptPubKeys.flatMap {
|
||||
case (scriptPubKey, index) =>
|
||||
(scriptPubKey.asm.map(token => (token, index))).filter {
|
||||
case (token, index) => token.isInstanceOf[ScriptConstant]
|
||||
case (token, _) => token.isInstanceOf[ScriptConstant]
|
||||
}
|
||||
}
|
||||
loop(scriptConstantsWithOutputIndex, this)
|
||||
|
@ -31,7 +31,7 @@ trait Merkle extends BitcoinSLogger {
|
||||
def computeMerkleRoot(transactions: Seq[Transaction]): DoubleSha256Digest = transactions match {
|
||||
case Nil => throw new IllegalArgumentException("We cannot have zero transactions in the block. There always should be ATLEAST one - the coinbase tx")
|
||||
case h +: Nil => h.txId
|
||||
case h +: t =>
|
||||
case _ +: _ =>
|
||||
val leafs = transactions.map(tx => Leaf(tx.txId))
|
||||
val merkleTree = build(leafs, Nil)
|
||||
merkleTree.value.get
|
||||
|
@ -71,7 +71,7 @@ sealed abstract class DERSignatureUtil {
|
||||
//https://stackoverflow.com/questions/2409618/how-do-i-decode-a-der-encoded-string-in-java
|
||||
val seq: DLSequence = Try(asn1InputStream.readObject.asInstanceOf[DLSequence]) match {
|
||||
case Success(seq) => seq
|
||||
case Failure(err) => new DLSequence()
|
||||
case Failure(_) => new DLSequence()
|
||||
}
|
||||
val default = new ASN1Integer(0)
|
||||
val r: ASN1Integer = Try(seq.getObjectAt(0).asInstanceOf[ASN1Integer]) match {
|
||||
|
@ -262,7 +262,7 @@ sealed abstract class ECPublicKey extends BaseECKey {
|
||||
signer.init(false, publicKeyParams)
|
||||
signature match {
|
||||
case EmptyDigitalSignature => signer.verifySignature(data.toArray, java.math.BigInteger.valueOf(0), java.math.BigInteger.valueOf(0))
|
||||
case sig: ECDigitalSignature =>
|
||||
case _: ECDigitalSignature =>
|
||||
logger.debug("Public key bytes: " + BitcoinSUtil.encodeHex(bytes))
|
||||
val rBigInteger: BigInteger = new BigInteger(signature.r.toString())
|
||||
val sBigInteger: BigInteger = new BigInteger(signature.s.toString())
|
||||
|
@ -113,7 +113,7 @@ sealed abstract class TransactionSignatureSerializer {
|
||||
}
|
||||
|
||||
case _: SIGHASH_ALL =>
|
||||
val sigHashAllTx: Transaction = sigHashAll(txWithInputSigsRemoved, inputIndex)
|
||||
val sigHashAllTx: Transaction = sigHashAll(txWithInputSigsRemoved)
|
||||
sigHashAllTx.bytes ++ sigHashBytes
|
||||
|
||||
case _: SIGHASH_ANYONECANPAY =>
|
||||
@ -121,7 +121,7 @@ sealed abstract class TransactionSignatureSerializer {
|
||||
txWithInputsRemoved.bytes ++ sigHashBytes
|
||||
|
||||
case _: SIGHASH_ALL_ANYONECANPAY =>
|
||||
val sigHashAllTx = sigHashAll(txWithInputSigsRemoved, inputIndex)
|
||||
val sigHashAllTx = sigHashAll(txWithInputSigsRemoved)
|
||||
val sigHashAllAnyoneCanPayTx = sigHashAnyoneCanPay(sigHashAllTx, inputWithConnectedScript)
|
||||
sigHashAllAnyoneCanPayTx.bytes ++ sigHashBytes
|
||||
|
||||
@ -245,7 +245,7 @@ sealed abstract class TransactionSignatureSerializer {
|
||||
}
|
||||
|
||||
/** Executes the [[SIGHASH_ALL]] procedure on a spending transaction at inputIndex. */
|
||||
private def sigHashAll(spendingTransaction: Transaction, inputIndex: UInt32): Transaction = {
|
||||
private def sigHashAll(spendingTransaction: Transaction): Transaction = {
|
||||
spendingTransaction
|
||||
}
|
||||
|
||||
|
@ -461,7 +461,7 @@ object Address extends AddressFactory[Address] {
|
||||
BitcoinAddress.fromString(str)
|
||||
}
|
||||
override def fromScriptPubKey(spk: ScriptPubKey, network: NetworkParameters): Try[Address] = network match {
|
||||
case bitcoinNetwork: BitcoinNetwork => BitcoinAddress.fromScriptPubKey(spk, network)
|
||||
case _: BitcoinNetwork => BitcoinAddress.fromScriptPubKey(spk, network)
|
||||
}
|
||||
def apply(spk: ScriptPubKey, networkParameters: NetworkParameters): Try[Address] = {
|
||||
fromScriptPubKey(spk, networkParameters)
|
||||
|
@ -1,6 +1,6 @@
|
||||
package org.bitcoins.core.protocol
|
||||
|
||||
import org.bitcoins.core.util.{ BitcoinSLogger, BitcoinSUtil }
|
||||
import org.bitcoins.core.util.BitcoinSLogger
|
||||
import scodec.bits.ByteVector
|
||||
|
||||
/**
|
||||
|
@ -74,7 +74,7 @@ object P2PKHScriptPubKey extends ScriptFactory[P2PKHScriptPubKey] {
|
||||
|
||||
/** Checks if the given asm matches the pattern for [[P2PKHScriptPubKey]] */
|
||||
def isP2PKHScriptPubKey(asm: Seq[ScriptToken]): Boolean = asm match {
|
||||
case List(OP_DUP, OP_HASH160, x: BytesToPushOntoStack, y: ScriptConstant, OP_EQUALVERIFY, OP_CHECKSIG) => true
|
||||
case Seq(OP_DUP, OP_HASH160, _: BytesToPushOntoStack, _: ScriptConstant, OP_EQUALVERIFY, OP_CHECKSIG) => true
|
||||
case _ => false
|
||||
}
|
||||
}
|
||||
@ -244,7 +244,7 @@ object P2SHScriptPubKey extends ScriptFactory[P2SHScriptPubKey] {
|
||||
|
||||
/** Checks if the given asm matches the pattern for [[P2SHScriptPubKey]] */
|
||||
def isP2SHScriptPubKey(asm: Seq[ScriptToken]): Boolean = asm match {
|
||||
case List(OP_HASH160, x: BytesToPushOntoStack, y: ScriptConstant, OP_EQUAL) => true
|
||||
case Seq(OP_HASH160, _: BytesToPushOntoStack, _: ScriptConstant, OP_EQUAL) => true
|
||||
case _ => false
|
||||
}
|
||||
|
||||
@ -284,7 +284,7 @@ object P2PKScriptPubKey extends ScriptFactory[P2PKScriptPubKey] {
|
||||
|
||||
/** Sees if the given asm matches the [[P2PKHScriptPubKey]] pattern */
|
||||
def isP2PKScriptPubKey(asm: Seq[ScriptToken]): Boolean = asm match {
|
||||
case List(b: BytesToPushOntoStack, x: ScriptConstant, OP_CHECKSIG) => true
|
||||
case Seq(_: BytesToPushOntoStack, _: ScriptConstant, OP_CHECKSIG) => true
|
||||
case _ => false
|
||||
}
|
||||
|
||||
@ -305,7 +305,7 @@ sealed trait LockTimeScriptPubKey extends ScriptPubKey {
|
||||
asm.head match {
|
||||
case scriptNumOp: ScriptNumberOperation => ScriptNumber(scriptNumOp.toLong)
|
||||
case _: BytesToPushOntoStack => ScriptNumber(asm(1).hex)
|
||||
case x @ (_: ScriptConstant | _: ScriptOperation) => throw new IllegalArgumentException("In a LockTimeScriptPubKey, " +
|
||||
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.")
|
||||
}
|
||||
}
|
||||
@ -365,7 +365,7 @@ object CLTVScriptPubKey extends ScriptFactory[CLTVScriptPubKey] {
|
||||
val tailTokens = asm.slice(4, asm.length)
|
||||
if (P2SHScriptPubKey.isP2SHScriptPubKey(tailTokens) || tailTokens.contains(OP_CHECKLOCKTIMEVERIFY)) return false
|
||||
asm.slice(0, 4) match {
|
||||
case List(lockTimeBytesToPush: BytesToPushOntoStack, lockTime: ScriptConstant, OP_CHECKLOCKTIMEVERIFY, OP_DROP) =>
|
||||
case Seq(_: BytesToPushOntoStack, _: ScriptConstant, OP_CHECKLOCKTIMEVERIFY, OP_DROP) =>
|
||||
validScriptAfterLockTime(tailTokens)
|
||||
case _ => false
|
||||
}
|
||||
@ -373,7 +373,7 @@ object CLTVScriptPubKey extends ScriptFactory[CLTVScriptPubKey] {
|
||||
val tailTokens = asm.slice(3, asm.length)
|
||||
if (P2SHScriptPubKey.isP2SHScriptPubKey(tailTokens) || tailTokens.contains(OP_CHECKLOCKTIMEVERIFY)) return false
|
||||
asm.slice(0, 3) match {
|
||||
case List(scriptNumOp: ScriptNumberOperation, OP_CHECKLOCKTIMEVERIFY, OP_DROP) =>
|
||||
case Seq(_: ScriptNumberOperation, OP_CHECKLOCKTIMEVERIFY, OP_DROP) =>
|
||||
validScriptAfterLockTime(tailTokens)
|
||||
case _ => false
|
||||
}
|
||||
@ -435,7 +435,7 @@ object CSVScriptPubKey extends ScriptFactory[CSVScriptPubKey] {
|
||||
val tailTokens = asm.slice(4, asm.length)
|
||||
if (P2SHScriptPubKey.isP2SHScriptPubKey(tailTokens) || tailTokens.contains(OP_CHECKSEQUENCEVERIFY)) return false
|
||||
asm.slice(0, 4) match {
|
||||
case List(lockTimeBytesToPush: BytesToPushOntoStack, lockTime: ScriptConstant, OP_CHECKSEQUENCEVERIFY, OP_DROP) =>
|
||||
case Seq(_: BytesToPushOntoStack, _: ScriptConstant, OP_CHECKSEQUENCEVERIFY, OP_DROP) =>
|
||||
CLTVScriptPubKey.validScriptAfterLockTime(tailTokens)
|
||||
case _ => false
|
||||
}
|
||||
@ -443,7 +443,7 @@ object CSVScriptPubKey extends ScriptFactory[CSVScriptPubKey] {
|
||||
val tailTokens = asm.slice(3, asm.length)
|
||||
if (P2SHScriptPubKey.isP2SHScriptPubKey(tailTokens) || tailTokens.contains(OP_CHECKSEQUENCEVERIFY)) return false
|
||||
asm.slice(0, 3) match {
|
||||
case List(numberOp: ScriptNumberOperation, OP_CHECKSEQUENCEVERIFY, OP_DROP) =>
|
||||
case Seq(_: ScriptNumberOperation, OP_CHECKSEQUENCEVERIFY, OP_DROP) =>
|
||||
CLTVScriptPubKey.validScriptAfterLockTime(tailTokens)
|
||||
case _ => false
|
||||
}
|
||||
|
@ -99,7 +99,7 @@ object P2PKHScriptSignature extends ScriptFactory[P2PKHScriptSignature] {
|
||||
|
||||
/** Determines if the given asm matches a [[P2PKHScriptSignature]] */
|
||||
def isP2PKHScriptSig(asm: Seq[ScriptToken]): Boolean = asm match {
|
||||
case List(w: BytesToPushOntoStack, x: ScriptConstant, y: BytesToPushOntoStack,
|
||||
case Seq(_: BytesToPushOntoStack, _: ScriptConstant, _: BytesToPushOntoStack,
|
||||
z: ScriptConstant) =>
|
||||
if (ECPublicKey.isFullyValid(z.bytes)) true
|
||||
else !P2SHScriptSignature.isRedeemScript(z)
|
||||
@ -138,7 +138,7 @@ sealed trait P2SHScriptSignature extends ScriptSignature {
|
||||
} else {
|
||||
val asmWithoutRedeemScriptAndPushOp: Try[Seq[ScriptToken]] = Try {
|
||||
asm(asm.size - 2) match {
|
||||
case b: BytesToPushOntoStack => asm.dropRight(2)
|
||||
case _: BytesToPushOntoStack => asm.dropRight(2)
|
||||
case _ => asm.dropRight(3)
|
||||
}
|
||||
}
|
||||
@ -170,7 +170,7 @@ sealed trait P2SHScriptSignature extends ScriptSignature {
|
||||
* the first part is the digital signatures
|
||||
* the second part is the redeem script
|
||||
*/
|
||||
def splitAtRedeemScript(asm: Seq[ScriptToken]): (Seq[ScriptToken], Seq[ScriptToken]) = {
|
||||
def splitAtRedeemScript: (Seq[ScriptToken], Seq[ScriptToken]) = {
|
||||
(scriptSignatureNoRedeemScript.asm, redeemScript.asm)
|
||||
}
|
||||
|
||||
@ -325,7 +325,7 @@ object P2PKScriptSignature extends ScriptFactory[P2PKScriptSignature] {
|
||||
|
||||
/** P2PK scriptSigs always have the pattern [pushop, digitalSignature] */
|
||||
def isP2PKScriptSignature(asm: Seq[ScriptToken]): Boolean = asm match {
|
||||
case List(w: BytesToPushOntoStack, x: ScriptConstant) => true
|
||||
case Seq(_: BytesToPushOntoStack, _: ScriptConstant) => true
|
||||
case _ => false
|
||||
}
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ sealed abstract class Transaction extends NetworkElement {
|
||||
/** Determines if this transaction is a coinbase transaction. */
|
||||
def isCoinbase: Boolean = inputs.size match {
|
||||
case 1 => inputs.head match {
|
||||
case coinbase: CoinbaseInput => true
|
||||
case _: CoinbaseInput => true
|
||||
case _: TransactionInput => false
|
||||
}
|
||||
case _: Int => false
|
||||
@ -156,7 +156,7 @@ object Transaction extends Factory[Transaction] {
|
||||
wtxTry match {
|
||||
case Success(wtx) =>
|
||||
wtx
|
||||
case Failure(f) =>
|
||||
case Failure(_) =>
|
||||
val btx = RawBaseTransactionParser.read(bytes)
|
||||
btx
|
||||
}
|
||||
|
@ -96,7 +96,7 @@ object ScriptProgram extends BitcoinSLogger {
|
||||
case program: ExecutionInProgressScriptProgram =>
|
||||
ExecutionInProgressScriptProgram(program.txSignatureComponent, program.stack, program.script, program.originalScript,
|
||||
program.altStack, flags, program.lastCodeSeparator)
|
||||
case program: ExecutedScriptProgram =>
|
||||
case _: ExecutedScriptProgram =>
|
||||
throw new RuntimeException("Cannot update the script flags on a program that has been executed")
|
||||
}
|
||||
|
||||
@ -110,7 +110,7 @@ object ScriptProgram extends BitcoinSLogger {
|
||||
case program: ExecutionInProgressScriptProgram =>
|
||||
ExecutionInProgressScriptProgram(program.txSignatureComponent, tokens.toList, program.script, program.originalScript,
|
||||
program.altStack, program.flags, program.lastCodeSeparator)
|
||||
case program: ExecutedScriptProgram =>
|
||||
case _: ExecutedScriptProgram =>
|
||||
throw new RuntimeException("Cannot update stack for program that has been fully executed")
|
||||
}
|
||||
case Script =>
|
||||
@ -121,7 +121,7 @@ object ScriptProgram extends BitcoinSLogger {
|
||||
case program: ExecutionInProgressScriptProgram =>
|
||||
ExecutionInProgressScriptProgram(program.txSignatureComponent, program.stack, tokens.toList, program.originalScript,
|
||||
program.altStack, program.flags, program.lastCodeSeparator)
|
||||
case program: ExecutedScriptProgram =>
|
||||
case _: ExecutedScriptProgram =>
|
||||
throw new RuntimeException("Cannot update the script for a program that has been fully executed")
|
||||
}
|
||||
case AltStack => oldProgram match {
|
||||
@ -131,7 +131,7 @@ object ScriptProgram extends BitcoinSLogger {
|
||||
case program: ExecutionInProgressScriptProgram =>
|
||||
ExecutionInProgressScriptProgram(program.txSignatureComponent, program.stack, program.script, program.originalScript,
|
||||
tokens.toList, program.flags, program.lastCodeSeparator)
|
||||
case program: ExecutedScriptProgram =>
|
||||
case _: ExecutedScriptProgram =>
|
||||
throw new RuntimeException("Cannot update the alt stack for a program that has been fully executed")
|
||||
}
|
||||
|
||||
@ -142,7 +142,7 @@ object ScriptProgram extends BitcoinSLogger {
|
||||
case program: ExecutionInProgressScriptProgram =>
|
||||
ExecutionInProgressScriptProgram(program.txSignatureComponent, program.stack, program.script, tokens.toList,
|
||||
program.altStack, program.flags, program.lastCodeSeparator)
|
||||
case program: ExecutedScriptProgram =>
|
||||
case _: ExecutedScriptProgram =>
|
||||
throw new RuntimeException("Cannot update the original script for a program that has been fully executed")
|
||||
}
|
||||
|
||||
@ -178,8 +178,11 @@ object ScriptProgram extends BitcoinSLogger {
|
||||
}
|
||||
|
||||
/** Updates the [[Stack]], [[Script]], [[AltStack]] of the given [[ScriptProgram]]. */
|
||||
def apply(oldProgram: ScriptProgram, stack: Seq[ScriptToken], script: Seq[ScriptToken], altStack: Seq[ScriptToken],
|
||||
updateIndicator: UpdateIndicator): ScriptProgram = {
|
||||
def apply(
|
||||
oldProgram: ScriptProgram,
|
||||
stack: Seq[ScriptToken],
|
||||
script: Seq[ScriptToken],
|
||||
altStack: Seq[ScriptToken]): ScriptProgram = {
|
||||
val updatedProgramStack = ScriptProgram(oldProgram, stack, Stack)
|
||||
val updatedProgramScript = ScriptProgram(updatedProgramStack, script, Script)
|
||||
val updatedProgramAltStack = ScriptProgram(updatedProgramScript, altStack, AltStack)
|
||||
|
@ -56,7 +56,7 @@ sealed abstract class ArithmeticInterpreter {
|
||||
/** If the input is 0 or 1, it is flipped. Otherwise the output will be 0. */
|
||||
def opNot(program: ScriptProgram): ScriptProgram = {
|
||||
require(program.script.headOption.contains(OP_NOT), "Script top must be OP_NOT")
|
||||
performUnaryArithmeticOperation(program, x => if (program.stackTopIsFalse) OP_TRUE else OP_FALSE)
|
||||
performUnaryArithmeticOperation(program, _ => if (program.stackTopIsFalse) OP_TRUE else OP_FALSE)
|
||||
}
|
||||
|
||||
/** Returns 0 if the input is 0. 1 otherwise. */
|
||||
@ -250,7 +250,7 @@ sealed abstract class ArithmeticInterpreter {
|
||||
val newProgram = ScriptProgram(program, interpretedNumber :: program.stack.tail, ScriptProgram.Stack)
|
||||
performUnaryArithmeticOperation(newProgram, op)
|
||||
}
|
||||
case Some(s: ScriptToken) =>
|
||||
case Some(_: ScriptToken) =>
|
||||
//pretty sure that an error is thrown inside of CScriptNum which in turn is caught by interpreter.cpp here
|
||||
//https://github.com/bitcoin/bitcoin/blob/master/src/script/interpreter.cpp#L999-L1002
|
||||
logger.error("Stack top must be a script number/script constant to perform an arithmetic operation")
|
||||
@ -284,7 +284,7 @@ sealed abstract class ArithmeticInterpreter {
|
||||
val newStackTop = op(x, y)
|
||||
ScriptProgram(program, newStackTop :: program.stack.tail.tail, program.script.tail)
|
||||
}
|
||||
case (x: ScriptConstant, y: ScriptNumber) =>
|
||||
case (x: ScriptConstant, _: ScriptNumber) =>
|
||||
//interpret x as a number
|
||||
val interpretedNumber = ScriptNumber(x.hex)
|
||||
val newProgram = ScriptProgram(program, interpretedNumber :: program.stack.tail, ScriptProgram.Stack)
|
||||
@ -299,7 +299,7 @@ sealed abstract class ArithmeticInterpreter {
|
||||
val interpretedNumberY = ScriptNumber(y.hex)
|
||||
val newProgram = ScriptProgram(program, interpretedNumberX :: interpretedNumberY :: program.stack.tail.tail, ScriptProgram.Stack)
|
||||
performBinaryArithmeticOperation(newProgram, op)
|
||||
case (x: ScriptToken, y: ScriptToken) =>
|
||||
case (_: ScriptToken, _: ScriptToken) =>
|
||||
//pretty sure that an error is thrown inside of CScriptNum which in turn is caught by interpreter.cpp here
|
||||
//https://github.com/bitcoin/bitcoin/blob/master/src/script/interpreter.cpp#L999-L1002
|
||||
logger.error("The top two stack items must be script numbers to perform an arithmetic operation")
|
||||
@ -369,7 +369,7 @@ sealed abstract class ArithmeticInterpreter {
|
||||
val interpretedNumberX = ScriptNumber(x.hex)
|
||||
val interpretedNumberY = ScriptNumber(y.hex)
|
||||
(interpretedNumberX, interpretedNumberY)
|
||||
case (x: ScriptToken, y: ScriptToken) =>
|
||||
case (_: ScriptToken, _: ScriptToken) =>
|
||||
//pretty sure that an error is thrown inside of CScriptNum which in turn is caught by interpreter.cpp here
|
||||
//https://github.com/bitcoin/bitcoin/blob/master/src/script/interpreter.cpp#L999-L1002
|
||||
logger.error("The top two stack items must be script numbers to perform an arithmetic operation")
|
||||
|
@ -256,18 +256,18 @@ sealed abstract class ControlOperationsInterpreter {
|
||||
/** Removes the first [[OP_ELSE]] in a [[BinaryTree]]. */
|
||||
def removeFirstOpElse(tree: BinaryTree[ScriptToken]): BinaryTree[ScriptToken] = {
|
||||
//@tailrec
|
||||
def loop(child: BinaryTree[ScriptToken], parent: Node[ScriptToken]): BinaryTree[ScriptToken] = child match {
|
||||
def loop(child: BinaryTree[ScriptToken]): BinaryTree[ScriptToken] = child match {
|
||||
case Empty => Empty
|
||||
case l: Leaf[ScriptToken] => l
|
||||
case Node(OP_ELSE, _, r) => r
|
||||
case n: Node[ScriptToken] =>
|
||||
Node(n.v, n.l, loop(n.r, n))
|
||||
Node(n.v, n.l, loop(n.r))
|
||||
}
|
||||
tree match {
|
||||
case Empty => Empty
|
||||
case l: Leaf[ScriptToken] => l
|
||||
case n: Node[ScriptToken] =>
|
||||
val result = Node(n.v, n.l, loop(n.r, n))
|
||||
val result = Node(n.v, n.l, loop(n.r))
|
||||
result
|
||||
}
|
||||
}
|
||||
|
@ -73,8 +73,8 @@ sealed abstract class ScriptInterpreter {
|
||||
case witness: WitnessScriptPubKey =>
|
||||
if (segwitEnabled) executeSegWitScript(scriptPubKeyExecutedProgram, witness).get
|
||||
else scriptPubKeyExecutedProgram
|
||||
case p2sh: P2SHScriptPubKey =>
|
||||
if (p2shEnabled) executeP2shScript(scriptSigExecutedProgram, program, p2sh)
|
||||
case _: P2SHScriptPubKey =>
|
||||
if (p2shEnabled) executeP2shScript(scriptSigExecutedProgram)
|
||||
else scriptPubKeyExecutedProgram
|
||||
case _: P2PKHScriptPubKey | _: P2PKScriptPubKey | _: MultiSignatureScriptPubKey | _: CSVScriptPubKey
|
||||
| _: CLTVScriptPubKey | _: NonStandardScriptPubKey | _: WitnessCommitment
|
||||
@ -126,17 +126,15 @@ sealed abstract class ScriptInterpreter {
|
||||
* a p2sh script returns true if both of those intermediate steps evaluate to true
|
||||
*
|
||||
* @param scriptPubKeyExecutedProgram the program with the script signature pushed onto the stack
|
||||
* @param originalProgram the original program, used for setting errors & checking that the original script signature contains push only tokens
|
||||
* @param p2shScriptPubKey the p2sh scriptPubKey that contains the value the redeemScript must hash to
|
||||
* @return the executed program
|
||||
*/
|
||||
private def executeP2shScript(scriptPubKeyExecutedProgram: ExecutedScriptProgram, originalProgram: ScriptProgram, p2shScriptPubKey: P2SHScriptPubKey): ExecutedScriptProgram = {
|
||||
private def executeP2shScript(scriptPubKeyExecutedProgram: ExecutedScriptProgram): ExecutedScriptProgram = {
|
||||
val flags = scriptPubKeyExecutedProgram.flags
|
||||
|
||||
val segwitEnabled = ScriptFlagUtil.segWitEnabled(flags)
|
||||
|
||||
/** Helper function to actually run a p2sh script */
|
||||
def run(p: ExecutedScriptProgram, stack: Seq[ScriptToken], s: ScriptPubKey): ExecutedScriptProgram = {
|
||||
def run(p: ExecutedScriptProgram, s: ScriptPubKey): ExecutedScriptProgram = {
|
||||
|
||||
val p2shRedeemScriptProgram = ExecutionInProgressScriptProgram(
|
||||
txSignatureComponent = p.txSignatureComponent,
|
||||
@ -199,7 +197,7 @@ sealed abstract class ScriptInterpreter {
|
||||
error = ScriptErrorWitnessMalleatedP2SH)
|
||||
} else {
|
||||
//segwit not enabled, treat as old spk
|
||||
run(scriptPubKeyExecutedProgram, stack, p2wpkh)
|
||||
run(scriptPubKeyExecutedProgram, p2wpkh)
|
||||
}
|
||||
|
||||
case p2wsh: P2WSHWitnessSPKV0 =>
|
||||
@ -224,12 +222,12 @@ sealed abstract class ScriptInterpreter {
|
||||
} else {
|
||||
logger.warn("redeem script was witness script pubkey, segwit was NOT enabled")
|
||||
//treat the segwit scriptpubkey as any other redeem script
|
||||
run(scriptPubKeyExecutedProgram, stack, p2wsh)
|
||||
run(scriptPubKeyExecutedProgram, p2wsh)
|
||||
}
|
||||
case s @ (_: P2SHScriptPubKey | _: P2PKHScriptPubKey | _: P2PKScriptPubKey | _: MultiSignatureScriptPubKey
|
||||
| _: CLTVScriptPubKey | _: CSVScriptPubKey | _: NonStandardScriptPubKey | _: WitnessCommitment
|
||||
| _: EscrowTimeoutScriptPubKey | _: UnassignedWitnessScriptPubKey | EmptyScriptPubKey) =>
|
||||
run(scriptPubKeyExecutedProgram, stack, s)
|
||||
run(scriptPubKeyExecutedProgram, s)
|
||||
}
|
||||
case false =>
|
||||
logger.warn("P2SH scriptPubKey hash did not match the hash for the serialized redeemScript")
|
||||
@ -388,85 +386,85 @@ sealed abstract class ScriptInterpreter {
|
||||
loop(ScriptProgram(p, ScriptErrorStackSize), opCount)
|
||||
|
||||
//stack operations
|
||||
case OP_DUP :: t => loop(StackInterpreter.opDup(p), calcOpCount(opCount, OP_DUP))
|
||||
case OP_DEPTH :: t => loop(StackInterpreter.opDepth(p), calcOpCount(opCount, OP_DEPTH))
|
||||
case OP_TOALTSTACK :: t => loop(StackInterpreter.opToAltStack(p), calcOpCount(opCount, OP_TOALTSTACK))
|
||||
case OP_FROMALTSTACK :: t => loop(StackInterpreter.opFromAltStack(p), calcOpCount(opCount, OP_FROMALTSTACK))
|
||||
case OP_DROP :: t => loop(StackInterpreter.opDrop(p), calcOpCount(opCount, OP_DROP))
|
||||
case OP_IFDUP :: t => loop(StackInterpreter.opIfDup(p), calcOpCount(opCount, OP_IFDUP))
|
||||
case OP_NIP :: t => loop(StackInterpreter.opNip(p), calcOpCount(opCount, OP_NIP))
|
||||
case OP_OVER :: t => loop(StackInterpreter.opOver(p), calcOpCount(opCount, OP_OVER))
|
||||
case OP_PICK :: t => loop(StackInterpreter.opPick(p), calcOpCount(opCount, OP_PICK))
|
||||
case OP_ROLL :: t => loop(StackInterpreter.opRoll(p), calcOpCount(opCount, OP_ROLL))
|
||||
case OP_ROT :: t => loop(StackInterpreter.opRot(p), calcOpCount(opCount, OP_ROT))
|
||||
case OP_2ROT :: t => loop(StackInterpreter.op2Rot(p), calcOpCount(opCount, OP_2ROT))
|
||||
case OP_2DROP :: t => loop(StackInterpreter.op2Drop(p), calcOpCount(opCount, OP_2DROP))
|
||||
case OP_SWAP :: t => loop(StackInterpreter.opSwap(p), calcOpCount(opCount, OP_SWAP))
|
||||
case OP_TUCK :: t => loop(StackInterpreter.opTuck(p), calcOpCount(opCount, OP_TUCK))
|
||||
case OP_2DUP :: t => loop(StackInterpreter.op2Dup(p), calcOpCount(opCount, OP_2DUP))
|
||||
case OP_3DUP :: t => loop(StackInterpreter.op3Dup(p), calcOpCount(opCount, OP_3DUP))
|
||||
case OP_2OVER :: t => loop(StackInterpreter.op2Over(p), calcOpCount(opCount, OP_2OVER))
|
||||
case OP_2SWAP :: t => loop(StackInterpreter.op2Swap(p), calcOpCount(opCount, OP_2SWAP))
|
||||
case OP_DUP :: _ => loop(StackInterpreter.opDup(p), calcOpCount(opCount, OP_DUP))
|
||||
case OP_DEPTH :: _ => loop(StackInterpreter.opDepth(p), calcOpCount(opCount, OP_DEPTH))
|
||||
case OP_TOALTSTACK :: _ => loop(StackInterpreter.opToAltStack(p), calcOpCount(opCount, OP_TOALTSTACK))
|
||||
case OP_FROMALTSTACK :: _ => loop(StackInterpreter.opFromAltStack(p), calcOpCount(opCount, OP_FROMALTSTACK))
|
||||
case OP_DROP :: _ => loop(StackInterpreter.opDrop(p), calcOpCount(opCount, OP_DROP))
|
||||
case OP_IFDUP :: _ => loop(StackInterpreter.opIfDup(p), calcOpCount(opCount, OP_IFDUP))
|
||||
case OP_NIP :: _ => loop(StackInterpreter.opNip(p), calcOpCount(opCount, OP_NIP))
|
||||
case OP_OVER :: _ => loop(StackInterpreter.opOver(p), calcOpCount(opCount, OP_OVER))
|
||||
case OP_PICK :: _ => loop(StackInterpreter.opPick(p), calcOpCount(opCount, OP_PICK))
|
||||
case OP_ROLL :: _ => loop(StackInterpreter.opRoll(p), calcOpCount(opCount, OP_ROLL))
|
||||
case OP_ROT :: _ => loop(StackInterpreter.opRot(p), calcOpCount(opCount, OP_ROT))
|
||||
case OP_2ROT :: _ => loop(StackInterpreter.op2Rot(p), calcOpCount(opCount, OP_2ROT))
|
||||
case OP_2DROP :: _ => loop(StackInterpreter.op2Drop(p), calcOpCount(opCount, OP_2DROP))
|
||||
case OP_SWAP :: _ => loop(StackInterpreter.opSwap(p), calcOpCount(opCount, OP_SWAP))
|
||||
case OP_TUCK :: _ => loop(StackInterpreter.opTuck(p), calcOpCount(opCount, OP_TUCK))
|
||||
case OP_2DUP :: _ => loop(StackInterpreter.op2Dup(p), calcOpCount(opCount, OP_2DUP))
|
||||
case OP_3DUP :: _ => loop(StackInterpreter.op3Dup(p), calcOpCount(opCount, OP_3DUP))
|
||||
case OP_2OVER :: _ => loop(StackInterpreter.op2Over(p), calcOpCount(opCount, OP_2OVER))
|
||||
case OP_2SWAP :: _ => loop(StackInterpreter.op2Swap(p), calcOpCount(opCount, OP_2SWAP))
|
||||
|
||||
//arithmetic operations
|
||||
case OP_ADD :: t => loop(ArithmeticInterpreter.opAdd(p), calcOpCount(opCount, OP_ADD))
|
||||
case OP_1ADD :: t => loop(ArithmeticInterpreter.op1Add(p), calcOpCount(opCount, OP_1ADD))
|
||||
case OP_1SUB :: t => loop(ArithmeticInterpreter.op1Sub(p), calcOpCount(opCount, OP_1SUB))
|
||||
case OP_SUB :: t => loop(ArithmeticInterpreter.opSub(p), calcOpCount(opCount, OP_SUB))
|
||||
case OP_ABS :: t => loop(ArithmeticInterpreter.opAbs(p), calcOpCount(opCount, OP_ABS))
|
||||
case OP_NEGATE :: t => loop(ArithmeticInterpreter.opNegate(p), calcOpCount(opCount, OP_NEGATE))
|
||||
case OP_NOT :: t => loop(ArithmeticInterpreter.opNot(p), calcOpCount(opCount, OP_NOT))
|
||||
case OP_0NOTEQUAL :: t => loop(ArithmeticInterpreter.op0NotEqual(p), calcOpCount(opCount, OP_0NOTEQUAL))
|
||||
case OP_BOOLAND :: t => loop(ArithmeticInterpreter.opBoolAnd(p), calcOpCount(opCount, OP_BOOLAND))
|
||||
case OP_BOOLOR :: t => loop(ArithmeticInterpreter.opBoolOr(p), calcOpCount(opCount, OP_BOOLOR))
|
||||
case OP_NUMEQUAL :: t => loop(ArithmeticInterpreter.opNumEqual(p), calcOpCount(opCount, OP_NUMEQUAL))
|
||||
case OP_NUMEQUALVERIFY :: t => loop(ArithmeticInterpreter.opNumEqualVerify(p), calcOpCount(opCount, OP_NUMEQUALVERIFY))
|
||||
case OP_NUMNOTEQUAL :: t => loop(ArithmeticInterpreter.opNumNotEqual(p), calcOpCount(opCount, OP_NUMNOTEQUAL))
|
||||
case OP_LESSTHAN :: t => loop(ArithmeticInterpreter.opLessThan(p), calcOpCount(opCount, OP_LESSTHAN))
|
||||
case OP_GREATERTHAN :: t => loop(ArithmeticInterpreter.opGreaterThan(p), calcOpCount(opCount, OP_GREATERTHAN))
|
||||
case OP_LESSTHANOREQUAL :: t => loop(ArithmeticInterpreter.opLessThanOrEqual(p), calcOpCount(opCount, OP_LESSTHANOREQUAL))
|
||||
case OP_GREATERTHANOREQUAL :: t => loop(ArithmeticInterpreter.opGreaterThanOrEqual(p), calcOpCount(opCount, OP_GREATERTHANOREQUAL))
|
||||
case OP_MIN :: t => loop(ArithmeticInterpreter.opMin(p), calcOpCount(opCount, OP_MIN))
|
||||
case OP_MAX :: t => loop(ArithmeticInterpreter.opMax(p), calcOpCount(opCount, OP_MAX))
|
||||
case OP_WITHIN :: t => loop(ArithmeticInterpreter.opWithin(p), calcOpCount(opCount, OP_WITHIN))
|
||||
case OP_ADD :: _ => loop(ArithmeticInterpreter.opAdd(p), calcOpCount(opCount, OP_ADD))
|
||||
case OP_1ADD :: _ => loop(ArithmeticInterpreter.op1Add(p), calcOpCount(opCount, OP_1ADD))
|
||||
case OP_1SUB :: _ => loop(ArithmeticInterpreter.op1Sub(p), calcOpCount(opCount, OP_1SUB))
|
||||
case OP_SUB :: _ => loop(ArithmeticInterpreter.opSub(p), calcOpCount(opCount, OP_SUB))
|
||||
case OP_ABS :: _ => loop(ArithmeticInterpreter.opAbs(p), calcOpCount(opCount, OP_ABS))
|
||||
case OP_NEGATE :: _ => loop(ArithmeticInterpreter.opNegate(p), calcOpCount(opCount, OP_NEGATE))
|
||||
case OP_NOT :: _ => loop(ArithmeticInterpreter.opNot(p), calcOpCount(opCount, OP_NOT))
|
||||
case OP_0NOTEQUAL :: _ => loop(ArithmeticInterpreter.op0NotEqual(p), calcOpCount(opCount, OP_0NOTEQUAL))
|
||||
case OP_BOOLAND :: _ => loop(ArithmeticInterpreter.opBoolAnd(p), calcOpCount(opCount, OP_BOOLAND))
|
||||
case OP_BOOLOR :: _ => loop(ArithmeticInterpreter.opBoolOr(p), calcOpCount(opCount, OP_BOOLOR))
|
||||
case OP_NUMEQUAL :: _ => loop(ArithmeticInterpreter.opNumEqual(p), calcOpCount(opCount, OP_NUMEQUAL))
|
||||
case OP_NUMEQUALVERIFY :: _ => loop(ArithmeticInterpreter.opNumEqualVerify(p), calcOpCount(opCount, OP_NUMEQUALVERIFY))
|
||||
case OP_NUMNOTEQUAL :: _ => loop(ArithmeticInterpreter.opNumNotEqual(p), calcOpCount(opCount, OP_NUMNOTEQUAL))
|
||||
case OP_LESSTHAN :: _ => loop(ArithmeticInterpreter.opLessThan(p), calcOpCount(opCount, OP_LESSTHAN))
|
||||
case OP_GREATERTHAN :: _ => loop(ArithmeticInterpreter.opGreaterThan(p), calcOpCount(opCount, OP_GREATERTHAN))
|
||||
case OP_LESSTHANOREQUAL :: _ => loop(ArithmeticInterpreter.opLessThanOrEqual(p), calcOpCount(opCount, OP_LESSTHANOREQUAL))
|
||||
case OP_GREATERTHANOREQUAL :: _ => loop(ArithmeticInterpreter.opGreaterThanOrEqual(p), calcOpCount(opCount, OP_GREATERTHANOREQUAL))
|
||||
case OP_MIN :: _ => loop(ArithmeticInterpreter.opMin(p), calcOpCount(opCount, OP_MIN))
|
||||
case OP_MAX :: _ => loop(ArithmeticInterpreter.opMax(p), calcOpCount(opCount, OP_MAX))
|
||||
case OP_WITHIN :: _ => loop(ArithmeticInterpreter.opWithin(p), calcOpCount(opCount, OP_WITHIN))
|
||||
|
||||
//bitwise operations
|
||||
case OP_EQUAL :: t => loop(BitwiseInterpreter.opEqual(p), calcOpCount(opCount, OP_EQUAL))
|
||||
case OP_EQUAL :: _ => loop(BitwiseInterpreter.opEqual(p), calcOpCount(opCount, OP_EQUAL))
|
||||
|
||||
case OP_EQUALVERIFY :: t => loop(BitwiseInterpreter.opEqualVerify(p), calcOpCount(opCount, OP_EQUALVERIFY))
|
||||
case OP_EQUALVERIFY :: _ => loop(BitwiseInterpreter.opEqualVerify(p), calcOpCount(opCount, OP_EQUALVERIFY))
|
||||
|
||||
case OP_0 :: t => loop(ScriptProgram(p, ScriptNumber.zero :: p.stack, t), calcOpCount(opCount, OP_0))
|
||||
case (scriptNumberOp: ScriptNumberOperation) :: t =>
|
||||
loop(ScriptProgram(p, ScriptNumber(scriptNumberOp.toLong) :: p.stack, t), calcOpCount(opCount, scriptNumberOp))
|
||||
case (bytesToPushOntoStack: BytesToPushOntoStack) :: t =>
|
||||
case (bytesToPushOntoStack: BytesToPushOntoStack) :: _ =>
|
||||
loop(ConstantInterpreter.pushScriptNumberBytesToStack(p), calcOpCount(opCount, bytesToPushOntoStack))
|
||||
case (scriptNumber: ScriptNumber) :: t =>
|
||||
loop(ScriptProgram(p, scriptNumber :: p.stack, t), calcOpCount(opCount, scriptNumber))
|
||||
case OP_PUSHDATA1 :: t => loop(ConstantInterpreter.opPushData1(p), calcOpCount(opCount, OP_PUSHDATA1))
|
||||
case OP_PUSHDATA2 :: t => loop(ConstantInterpreter.opPushData2(p), calcOpCount(opCount, OP_PUSHDATA2))
|
||||
case OP_PUSHDATA4 :: t => loop(ConstantInterpreter.opPushData4(p), calcOpCount(opCount, OP_PUSHDATA4))
|
||||
case OP_PUSHDATA1 :: _ => loop(ConstantInterpreter.opPushData1(p), calcOpCount(opCount, OP_PUSHDATA1))
|
||||
case OP_PUSHDATA2 :: _ => loop(ConstantInterpreter.opPushData2(p), calcOpCount(opCount, OP_PUSHDATA2))
|
||||
case OP_PUSHDATA4 :: _ => loop(ConstantInterpreter.opPushData4(p), calcOpCount(opCount, OP_PUSHDATA4))
|
||||
|
||||
case (x: ScriptConstant) :: t => loop(ScriptProgram(p, x :: p.stack, t), calcOpCount(opCount, x))
|
||||
|
||||
//control operations
|
||||
case OP_IF :: t => loop(ControlOperationsInterpreter.opIf(p), calcOpCount(opCount, OP_IF))
|
||||
case OP_NOTIF :: t => loop(ControlOperationsInterpreter.opNotIf(p), calcOpCount(opCount, OP_NOTIF))
|
||||
case OP_ELSE :: t => loop(ControlOperationsInterpreter.opElse(p), calcOpCount(opCount, OP_ELSE))
|
||||
case OP_ENDIF :: t => loop(ControlOperationsInterpreter.opEndIf(p), calcOpCount(opCount, OP_ENDIF))
|
||||
case OP_RETURN :: t => loop(ControlOperationsInterpreter.opReturn(p), calcOpCount(opCount, OP_RETURN))
|
||||
case OP_IF :: _ => loop(ControlOperationsInterpreter.opIf(p), calcOpCount(opCount, OP_IF))
|
||||
case OP_NOTIF :: _ => loop(ControlOperationsInterpreter.opNotIf(p), calcOpCount(opCount, OP_NOTIF))
|
||||
case OP_ELSE :: _ => loop(ControlOperationsInterpreter.opElse(p), calcOpCount(opCount, OP_ELSE))
|
||||
case OP_ENDIF :: _ => loop(ControlOperationsInterpreter.opEndIf(p), calcOpCount(opCount, OP_ENDIF))
|
||||
case OP_RETURN :: _ => loop(ControlOperationsInterpreter.opReturn(p), calcOpCount(opCount, OP_RETURN))
|
||||
|
||||
case OP_VERIFY :: t => loop(ControlOperationsInterpreter.opVerify(p), calcOpCount(opCount, OP_VERIFY))
|
||||
case OP_VERIFY :: _ => loop(ControlOperationsInterpreter.opVerify(p), calcOpCount(opCount, OP_VERIFY))
|
||||
|
||||
//crypto operations
|
||||
case OP_HASH160 :: t => loop(CryptoInterpreter.opHash160(p), calcOpCount(opCount, OP_HASH160))
|
||||
case OP_CHECKSIG :: t => loop(CryptoInterpreter.opCheckSig(p), calcOpCount(opCount, OP_CHECKSIG))
|
||||
case OP_CHECKSIGVERIFY :: t => loop(CryptoInterpreter.opCheckSigVerify(p), calcOpCount(opCount, OP_CHECKSIGVERIFY))
|
||||
case OP_SHA1 :: t => loop(CryptoInterpreter.opSha1(p), calcOpCount(opCount, OP_SHA1))
|
||||
case OP_RIPEMD160 :: t => loop(CryptoInterpreter.opRipeMd160(p), calcOpCount(opCount, OP_RIPEMD160))
|
||||
case OP_SHA256 :: t => loop(CryptoInterpreter.opSha256(p), calcOpCount(opCount, OP_SHA256))
|
||||
case OP_HASH256 :: t => loop(CryptoInterpreter.opHash256(p), calcOpCount(opCount, OP_HASH256))
|
||||
case OP_CODESEPARATOR :: t => loop(CryptoInterpreter.opCodeSeparator(p), calcOpCount(opCount, OP_CODESEPARATOR))
|
||||
case OP_CHECKMULTISIG :: t =>
|
||||
case OP_HASH160 :: _ => loop(CryptoInterpreter.opHash160(p), calcOpCount(opCount, OP_HASH160))
|
||||
case OP_CHECKSIG :: _ => loop(CryptoInterpreter.opCheckSig(p), calcOpCount(opCount, OP_CHECKSIG))
|
||||
case OP_CHECKSIGVERIFY :: _ => loop(CryptoInterpreter.opCheckSigVerify(p), calcOpCount(opCount, OP_CHECKSIGVERIFY))
|
||||
case OP_SHA1 :: _ => loop(CryptoInterpreter.opSha1(p), calcOpCount(opCount, OP_SHA1))
|
||||
case OP_RIPEMD160 :: _ => loop(CryptoInterpreter.opRipeMd160(p), calcOpCount(opCount, OP_RIPEMD160))
|
||||
case OP_SHA256 :: _ => loop(CryptoInterpreter.opSha256(p), calcOpCount(opCount, OP_SHA256))
|
||||
case OP_HASH256 :: _ => loop(CryptoInterpreter.opHash256(p), calcOpCount(opCount, OP_HASH256))
|
||||
case OP_CODESEPARATOR :: _ => loop(CryptoInterpreter.opCodeSeparator(p), calcOpCount(opCount, OP_CODESEPARATOR))
|
||||
case OP_CHECKMULTISIG :: _ =>
|
||||
CryptoInterpreter.opCheckMultiSig(p) match {
|
||||
case newProgram: ExecutedScriptProgram =>
|
||||
//script was marked invalid for other reasons, don't need to update the opcount
|
||||
@ -475,7 +473,7 @@ sealed abstract class ScriptInterpreter {
|
||||
val newOpCount = calcOpCount(opCount, OP_CHECKMULTISIG) + BitcoinScriptUtil.numPossibleSignaturesOnStack(program).toInt
|
||||
loop(newProgram, newOpCount)
|
||||
}
|
||||
case OP_CHECKMULTISIGVERIFY :: t =>
|
||||
case OP_CHECKMULTISIGVERIFY :: _ =>
|
||||
CryptoInterpreter.opCheckMultiSigVerify(p) match {
|
||||
case newProgram: ExecutedScriptProgram =>
|
||||
//script was marked invalid for other reasons, don't need to update the opcount
|
||||
@ -490,31 +488,31 @@ sealed abstract class ScriptInterpreter {
|
||||
loop(ScriptProgram(p, p.stack, t), calcOpCount(opCount, OP_NOP))
|
||||
|
||||
//if we see an OP_NOP and the DISCOURAGE_UPGRADABLE_OP_NOPS flag is set we must fail our program
|
||||
case (nop: NOP) :: t if ScriptFlagUtil.discourageUpgradableNOPs(p.flags) =>
|
||||
case (nop: NOP) :: _ if ScriptFlagUtil.discourageUpgradableNOPs(p.flags) =>
|
||||
logger.error("We cannot execute a NOP when the ScriptVerifyDiscourageUpgradableNOPs is set")
|
||||
loop(ScriptProgram(p, ScriptErrorDiscourageUpgradableNOPs), calcOpCount(opCount, nop))
|
||||
case (nop: NOP) :: t => loop(ScriptProgram(p, p.stack, t), calcOpCount(opCount, nop))
|
||||
case OP_RESERVED :: t =>
|
||||
case OP_RESERVED :: _ =>
|
||||
logger.error("OP_RESERVED automatically marks transaction invalid")
|
||||
loop(ScriptProgram(p, ScriptErrorBadOpCode), calcOpCount(opCount, OP_RESERVED))
|
||||
case OP_VER :: t =>
|
||||
case OP_VER :: _ =>
|
||||
logger.error("Transaction is invalid when executing OP_VER")
|
||||
loop(ScriptProgram(p, ScriptErrorBadOpCode), calcOpCount(opCount, OP_VER))
|
||||
case OP_RESERVED1 :: t =>
|
||||
case OP_RESERVED1 :: _ =>
|
||||
logger.error("Transaction is invalid when executing OP_RESERVED1")
|
||||
loop(ScriptProgram(p, ScriptErrorBadOpCode), calcOpCount(opCount, OP_RESERVED1))
|
||||
case OP_RESERVED2 :: t =>
|
||||
case OP_RESERVED2 :: _ =>
|
||||
logger.error("Transaction is invalid when executing OP_RESERVED2")
|
||||
loop(ScriptProgram(p, ScriptErrorBadOpCode), calcOpCount(opCount, OP_RESERVED2))
|
||||
|
||||
case (reservedOperation: ReservedOperation) :: t =>
|
||||
case (reservedOperation: ReservedOperation) :: _ =>
|
||||
logger.error("Undefined operation found which automatically fails the script: " + reservedOperation)
|
||||
loop(ScriptProgram(p, ScriptErrorBadOpCode), calcOpCount(opCount, reservedOperation))
|
||||
//splice operations
|
||||
case OP_SIZE :: t => loop(SpliceInterpreter.opSize(p), calcOpCount(opCount, OP_SIZE))
|
||||
case OP_SIZE :: _ => loop(SpliceInterpreter.opSize(p), calcOpCount(opCount, OP_SIZE))
|
||||
|
||||
//locktime operations
|
||||
case OP_CHECKLOCKTIMEVERIFY :: t =>
|
||||
case OP_CHECKLOCKTIMEVERIFY :: _ =>
|
||||
//check if CLTV is enforced yet
|
||||
if (ScriptFlagUtil.checkLockTimeVerifyEnabled(p.flags)) {
|
||||
loop(LockTimeInterpreter.opCheckLockTimeVerify(p), calcOpCount(opCount, OP_CHECKLOCKTIMEVERIFY))
|
||||
@ -524,7 +522,7 @@ sealed abstract class ScriptInterpreter {
|
||||
loop(ScriptProgram(p, ScriptErrorDiscourageUpgradableNOPs), calcOpCount(opCount, OP_CHECKLOCKTIMEVERIFY))
|
||||
} //in this case, just reat OP_CLTV just like a NOP and remove it from the stack
|
||||
else loop(ScriptProgram(p, p.script.tail, ScriptProgram.Script), calcOpCount(opCount, OP_CHECKLOCKTIMEVERIFY))
|
||||
case OP_CHECKSEQUENCEVERIFY :: t =>
|
||||
case OP_CHECKSEQUENCEVERIFY :: _ =>
|
||||
//check if CLTV is enforced yet
|
||||
if (ScriptFlagUtil.checkSequenceVerifyEnabled(p.flags)) {
|
||||
loop(LockTimeInterpreter.opCheckSequenceVerify(p), calcOpCount(opCount, OP_CHECKSEQUENCEVERIFY))
|
||||
@ -536,7 +534,7 @@ sealed abstract class ScriptInterpreter {
|
||||
else loop(ScriptProgram(p, p.script.tail, ScriptProgram.Script), calcOpCount(opCount, OP_CHECKSEQUENCEVERIFY))
|
||||
//no more script operations to run, return whether the program is valid and the final state of the program
|
||||
case Nil => loop(ScriptProgram.toExecutedProgram(p), opCount)
|
||||
case h :: t => throw new RuntimeException(h + " was unmatched")
|
||||
case h :: _ => throw new RuntimeException(h + " was unmatched")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ sealed abstract class StackInterpreter {
|
||||
def opDup(program: ScriptProgram): ScriptProgram = {
|
||||
require(program.script.headOption.contains(OP_DUP), "Top of the script stack must be OP_DUP")
|
||||
program.stack match {
|
||||
case h :: t => ScriptProgram(program, h :: program.stack, program.script.tail)
|
||||
case h :: _ => ScriptProgram(program, h :: program.stack, program.script.tail)
|
||||
case Nil =>
|
||||
logger.error("Cannot duplicate the top element on an empty stack")
|
||||
ScriptProgram(program, ScriptErrorInvalidStackOperation)
|
||||
@ -55,7 +55,7 @@ sealed abstract class StackInterpreter {
|
||||
require(program.script.headOption.contains(OP_TOALTSTACK), "Top of script stack must be OP_TOALTSTACK")
|
||||
if (program.stack.nonEmpty) {
|
||||
ScriptProgram(program, program.stack.tail,
|
||||
program.script.tail, program.stack.head :: program.altStack, ScriptProgram.AltStack)
|
||||
program.script.tail, program.stack.head :: program.altStack)
|
||||
} else {
|
||||
logger.error("OP_TOALTSTACK requires an element to be on the stack")
|
||||
ScriptProgram(program, ScriptErrorInvalidStackOperation)
|
||||
@ -67,7 +67,7 @@ sealed abstract class StackInterpreter {
|
||||
require(program.script.headOption.contains(OP_FROMALTSTACK), "Top of script stack must be OP_FROMALTSTACK")
|
||||
if (program.altStack.nonEmpty) {
|
||||
ScriptProgram(program, program.altStack.head :: program.stack,
|
||||
program.script.tail, program.altStack.tail, ScriptProgram.AltStack)
|
||||
program.script.tail, program.altStack.tail)
|
||||
} else {
|
||||
logger.error("Alt Stack must have at least one item on it for OP_FROMALTSTACK")
|
||||
ScriptProgram(program, ScriptErrorInvalidAltStackOperation)
|
||||
@ -90,7 +90,7 @@ sealed abstract class StackInterpreter {
|
||||
require(program.script.headOption.contains(OP_NIP), "Top of script stack must be OP_NIP")
|
||||
program.stack match {
|
||||
case h :: _ :: t => ScriptProgram(program, h :: t, program.script.tail)
|
||||
case h :: t =>
|
||||
case _ :: _ =>
|
||||
logger.error("Stack must have at least two items on it for OP_NIP")
|
||||
ScriptProgram(program, ScriptErrorInvalidStackOperation)
|
||||
case Nil =>
|
||||
@ -104,7 +104,7 @@ sealed abstract class StackInterpreter {
|
||||
require(program.script.headOption.contains(OP_OVER), "Top of script stack must be OP_OVER")
|
||||
program.stack match {
|
||||
case _ :: h1 :: _ => ScriptProgram(program, h1 :: program.stack, program.script.tail)
|
||||
case h :: t =>
|
||||
case _ :: _ =>
|
||||
logger.error("Stack must have at least two items on it for OP_OVER")
|
||||
ScriptProgram(program, ScriptErrorInvalidStackOperation)
|
||||
case Nil =>
|
||||
|
@ -5,8 +5,6 @@ import org.bitcoins.core.protocol.{ CompactSizeUInt, NetworkElement }
|
||||
import scodec.bits.ByteVector
|
||||
|
||||
import scala.annotation.tailrec
|
||||
import scala.collection.immutable.VectorBuilder
|
||||
import scala.collection.mutable
|
||||
|
||||
/**
|
||||
* Created by chris on 2/18/16.
|
||||
|
@ -50,8 +50,8 @@ sealed abstract class ScriptParser extends Factory[List[ScriptToken]] {
|
||||
operations match {
|
||||
//for parsing strings like 'Az', need to remove single quotes
|
||||
//example: [[https://github.com/bitcoin/bitcoin/blob/master/src/test/data/script_valid.json#L24]]
|
||||
case h +: t if (h.size > 0 && h.head == ''' && h.last == ''') =>
|
||||
val strippedQuotes = h.replace("'", "")
|
||||
case h +: t if (h.size > 0 && h.head == '\'' && h.last == '\'') =>
|
||||
val strippedQuotes = h.replace("\'", "")
|
||||
if (strippedQuotes.size == 0) {
|
||||
loop(t, OP_0.bytes ++ accum)
|
||||
} else {
|
||||
|
@ -37,7 +37,7 @@ sealed abstract class Base58 {
|
||||
val ones: String = bytes.toSeq.takeWhile(_ == 0).map(_ => '1').mkString
|
||||
@tailrec
|
||||
def loop(current: BigInt, str: String): String = current match {
|
||||
case a if current == BigInt(0) =>
|
||||
case _ if current == BigInt(0) =>
|
||||
ones + str.reverse
|
||||
case _: BigInt =>
|
||||
val quotient: BigInt = current / BigInt(58L)
|
||||
@ -77,7 +77,7 @@ sealed abstract class Base58 {
|
||||
/** Determines if a string is a valid [[Base58Type]] string. */
|
||||
def isValid(base58: String): Boolean = validityChecks(base58) match {
|
||||
case Success(bool) => bool
|
||||
case Failure(exception) => false
|
||||
case Failure(_) => false
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -13,13 +13,13 @@ trait BinaryTree[+T] {
|
||||
|
||||
def left: Option[BinaryTree[T]] = this match {
|
||||
case n: Node[T] => Some(n.l)
|
||||
case l: Leaf[T] => None
|
||||
case _: Leaf[T] => None
|
||||
case Empty => None
|
||||
}
|
||||
|
||||
def right: Option[BinaryTree[T]] = this match {
|
||||
case n: Node[T] => Some(n.r)
|
||||
case l: Leaf[T] => None
|
||||
case _: Leaf[T] => None
|
||||
case Empty => None
|
||||
}
|
||||
|
||||
@ -55,7 +55,7 @@ trait BinaryTree[+T] {
|
||||
/** Checks if the [[BinaryTree]] contains a certain element. */
|
||||
def contains[T](t: T)(f: T => Boolean = (x: T) => x == t)(implicit tree: BinaryTree[T] = this): Boolean = findFirstDFS(t)(f)(tree).isDefined
|
||||
|
||||
def count[T](t: T)(implicit tree: BinaryTree[T] = this): Int = toSeq.count(_ == t)
|
||||
def count[T](t: T): Int = toSeq.count(_ == t)
|
||||
|
||||
/**
|
||||
* Inserts an element into one of the two branches in a [[BinaryTree]].
|
||||
|
@ -75,7 +75,7 @@ trait BitcoinSUtil {
|
||||
*/
|
||||
private def addPadding(charactersNeeded: Int, hex: String): String = {
|
||||
val paddingNeeded = charactersNeeded - hex.length
|
||||
val padding = for { i <- 0 until paddingNeeded } yield "0"
|
||||
val padding = Vector.fill(paddingNeeded)("0")
|
||||
val paddedHex = padding.mkString + hex
|
||||
paddedHex
|
||||
}
|
||||
|
@ -155,7 +155,7 @@ trait BitcoinScriptUtil extends BitcoinSLogger {
|
||||
case size if (size <= 75) => token.bytes.size == pushOp.toLong
|
||||
case size if (size <= 255) => pushOp == OP_PUSHDATA1
|
||||
case size if (size <= 65535) => pushOp == OP_PUSHDATA2
|
||||
case size =>
|
||||
case _: Long =>
|
||||
//default case is true because we have to use the largest push op as possible which is OP_PUSHDATA4
|
||||
true
|
||||
}
|
||||
@ -313,12 +313,12 @@ trait BitcoinScriptUtil extends BitcoinSLogger {
|
||||
|
||||
P2PKHScriptPubKey(p2wpkh.pubKeyHash).asm
|
||||
|
||||
case p2wsh: P2WSHWitnessSPKV0 =>
|
||||
case _: P2WSHWitnessSPKV0 =>
|
||||
val wtxSig = txSignatureComponent.asInstanceOf[WitnessTxSigComponentP2SH]
|
||||
|
||||
val p2wshRedeem = ScriptPubKey.fromAsmBytes(wtxSig.witness.stack.head)
|
||||
p2wshRedeem.asm
|
||||
case redeem: ScriptPubKey =>
|
||||
case _: ScriptPubKey =>
|
||||
|
||||
val sigsRemoved = removeSignaturesFromScript(p2shScriptSig.signatures, p2shScriptSig.redeemScript.asm)
|
||||
sigsRemoved
|
||||
|
@ -54,7 +54,7 @@ sealed abstract class P2PKSigner extends BitcoinSigner {
|
||||
val flags = Policy.standardFlags
|
||||
|
||||
val signed: Future[TxSigComponent] = spk match {
|
||||
case p2wshSPK: P2WSHWitnessSPKV0 =>
|
||||
case _: P2WSHWitnessSPKV0 =>
|
||||
val wtx = unsignedTx match {
|
||||
case btx: BaseTransaction => WitnessTransaction(btx.version, btx.inputs,
|
||||
btx.outputs, btx.lockTime, EmptyWitness)
|
||||
@ -142,7 +142,7 @@ sealed abstract class P2PKHSigner extends BitcoinSigner {
|
||||
val flags = Policy.standardFlags
|
||||
|
||||
val signed: Future[TxSigComponent] = spk match {
|
||||
case p2wshSPK: P2WSHWitnessSPKV0 =>
|
||||
case _: P2WSHWitnessSPKV0 =>
|
||||
val wtx = unsignedTx match {
|
||||
case btx: BaseTransaction => WitnessTransaction(btx.version, btx.inputs,
|
||||
btx.outputs, btx.lockTime, EmptyWitness)
|
||||
@ -259,7 +259,7 @@ sealed abstract class MultiSigSigner extends BitcoinSigner {
|
||||
val flags = Policy.standardFlags
|
||||
|
||||
val signed: Future[TxSigComponent] = spk match {
|
||||
case p2wshSPK: P2WSHWitnessSPKV0 =>
|
||||
case _: P2WSHWitnessSPKV0 =>
|
||||
val wtx = unsignedTx match {
|
||||
case btx: BaseTransaction => WitnessTransaction(btx.version, btx.inputs,
|
||||
btx.outputs, btx.lockTime, EmptyWitness)
|
||||
|
Loading…
Reference in New Issue
Block a user