Correct num expected inputs calc for multisig.

This commit corrects the number of expected inputs for a multi-sig script
to include the additional item that is popped from the stack due to the
OP_CHECKMULTISIG consensus bug (which is required and properly performed).

Note this issue did NOT affect the consensus critical code and hence would
not cause a chain fork.  It did however, cause standard p2sh multisig txns
to be rejected from the mempool as nonstandard.

The tx rejected as non-standard which prompted this was spotted by
@mbelshe on IRC.

ok @owainga
This commit is contained in:
Dave Collins 2014-03-16 23:07:20 -05:00
parent 9375c8dc48
commit c8332cc9a7
2 changed files with 11 additions and 8 deletions

View file

@ -1128,11 +1128,13 @@ func expectedInputs(pops []parsedOpcode, class ScriptClass) int {
return 1 return 1
case MultiSigTy: case MultiSigTy:
// Standard multisig has a push a small number for the number // Standard multisig has a push a small number for the number
// of sigs and number of keys. // of sigs and number of keys. Check the first push instruction
// Check the first push instruction to see how many arguments // to see how many arguments are expected. typeOfScript already
// are expected. typeOfScript already checked this so we know // checked this so we know it'll be a small int. Also, due to
// it'll be a small int. // the original bitcoind bug where OP_CHECKMULTISIG pops an
return asSmallInt(pops[0].opcode) // additional item from the stack, add an extra expected input
// for the extra push that is required to compensate.
return asSmallInt(pops[0].opcode) + 1
case NullDataTy: case NullDataTy:
fallthrough fallthrough
default: default:

View file

@ -1200,7 +1200,7 @@ var txTests = []txTest{
scriptInfo: btcscript.ScriptInfo{ scriptInfo: btcscript.ScriptInfo{
PkScriptClass: btcscript.ScriptHashTy, PkScriptClass: btcscript.ScriptHashTy,
NumInputs: 2, NumInputs: 2,
ExpectedInputs: 1, ExpectedInputs: 2,
SigOps: 1, SigOps: 1,
}, },
}, },
@ -1780,6 +1780,7 @@ func TestScriptInfo(t *testing.T) {
name: "multisig script", name: "multisig script",
sigScript: []byte{btcscript.OP_TRUE, sigScript: []byte{btcscript.OP_TRUE,
btcscript.OP_TRUE, btcscript.OP_TRUE, btcscript.OP_TRUE, btcscript.OP_TRUE,
btcscript.OP_0, // Extra arg for OP_CHECKMULTISIG bug
}, },
pkScript: []byte{ pkScript: []byte{
btcscript.OP_3, btcscript.OP_DATA_33, btcscript.OP_3, btcscript.OP_DATA_33,
@ -1802,8 +1803,8 @@ func TestScriptInfo(t *testing.T) {
bip16: true, bip16: true,
scriptInfo: btcscript.ScriptInfo{ scriptInfo: btcscript.ScriptInfo{
PkScriptClass: btcscript.MultiSigTy, PkScriptClass: btcscript.MultiSigTy,
NumInputs: 3, NumInputs: 4,
ExpectedInputs: 3, ExpectedInputs: 4,
SigOps: 3, SigOps: 3,
}, },
}, },