mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2025-02-24 06:57:51 +01:00
Implementing ScriptErrorWitnessUnexpected for the case of having a witness without a WitnessScriptPubKey
This commit is contained in:
parent
5d29512fe2
commit
2b3010b808
2 changed files with 36 additions and 6 deletions
|
@ -81,6 +81,11 @@ trait ScriptInterpreter extends CryptoInterpreter with StackInterpreter with Con
|
|||
}
|
||||
logger.debug("Executed Script Program: " + executedProgram)
|
||||
if (executedProgram.error.isDefined) executedProgram.error.get
|
||||
else if (checkUnexpectedWitness(program)) {
|
||||
//note: the 'program' value we pass above is intetional, we need to check the original program
|
||||
//as the 'executedProgram' may have had the scriptPubKey value changed to the rebuilt ScriptPubKey of the witness program
|
||||
ScriptErrorWitnessUnexpected
|
||||
}
|
||||
else if (executedProgram.stackTopIsTrue && flags.contains(ScriptVerifyCleanStack)) {
|
||||
//require that the stack after execution has exactly one element on it
|
||||
executedProgram.stack.size == 1 match {
|
||||
|
@ -474,5 +479,31 @@ trait ScriptInterpreter extends CryptoInterpreter with StackInterpreter with Con
|
|||
case true => oldOpCount + 1
|
||||
case false => oldOpCount
|
||||
}
|
||||
|
||||
/** Checks if the transaction contained a witness that we did not use
|
||||
* [[https://github.com/bitcoin/bitcoin/blob/528472111b4965b1a99c4bcf08ac5ec93d87f10f/src/script/interpreter.cpp#L1515-L1523]]
|
||||
* Return true if witness was NOT used, return false if witness was used
|
||||
* */
|
||||
private def checkUnexpectedWitness(program: ScriptProgram): Boolean = {
|
||||
val txSigComponent = program.txSignatureComponent
|
||||
txSigComponent match {
|
||||
case b : BaseTransactionSignatureComponent =>
|
||||
//base transactions never have witnesses
|
||||
false
|
||||
case w : WitnessV0TransactionSignatureComponent =>
|
||||
val witnessedUsed = w.scriptPubKey match {
|
||||
case _ : WitnessScriptPubKey => true
|
||||
case _ : P2SHScriptPubKey => txSigComponent.scriptSignature match {
|
||||
case p2shScriptSig: P2SHScriptSignature =>
|
||||
p2shScriptSig.redeemScript.isInstanceOf[WitnessScriptPubKey]
|
||||
case _ @ (_ : CLTVScriptSignature | _ : CSVScriptSignature| _ : MultiSignatureScriptSignature| _ : NonStandardScriptSignature |
|
||||
_ : P2PKScriptSignature| _ : P2PKHScriptSignature | EmptyScriptSignature) => false
|
||||
}
|
||||
case _ @ (_ : CLTVScriptPubKey | _ : CSVScriptPubKey | _ : MultiSignatureScriptPubKey | _ : NonStandardScriptPubKey |
|
||||
_ : P2PKScriptPubKey | _ : P2PKHScriptPubKey | EmptyScriptPubKey) => false
|
||||
}
|
||||
!witnessedUsed
|
||||
}
|
||||
}
|
||||
}
|
||||
object ScriptInterpreter extends ScriptInterpreter
|
|
@ -33,15 +33,14 @@ class ScriptInterpreterTest extends FlatSpec with MustMatchers with ScriptInterp
|
|||
"""
|
||||
| [[
|
||||
| [
|
||||
| "304402204209e49457c2358f80d0256bc24535b8754c14d08840fc4be762d6f5a0aed80b02202eaf7d8fc8d62f60c67adcd99295528d0e491ae93c195cec5a67e7a09532a88001",
|
||||
| "048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf",
|
||||
| "",
|
||||
| 0.00000000
|
||||
| ],
|
||||
| "11 0x16 0x00147cf9c846cd4882efec4bf07e44ebdad495c94f4b",
|
||||
| "HASH160 0x14 0x4e0c2aed91315303fc6a1dc4c7bc21c88f75402e EQUAL",
|
||||
| "0x47 0x304402200a5c6163f07b8d3b013c4d1d6dba25e780b39658d79ba37af7057a3b7f15ffa102201fd9b4eaa9943f734928b99a83592c2e7bf342ea2680f6a2bb705167966b742001",
|
||||
| "0x41 0x0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG",
|
||||
| "P2SH,WITNESS",
|
||||
| "WITNESS_MALLEATED_P2SH",
|
||||
| "P2SH(P2WPKH) with superfluous push in scriptSig"
|
||||
| "WITNESS_UNEXPECTED",
|
||||
| "P2PK with witness"
|
||||
| ]]
|
||||
""".stripMargin*/
|
||||
val lines = try source.getLines.filterNot(_.isEmpty).map(_.trim) mkString "\n" finally source.close()
|
||||
|
|
Loading…
Add table
Reference in a new issue