diff --git a/doc/shared-libraries.md b/doc/shared-libraries.md --- a/doc/shared-libraries.md +++ b/doc/shared-libraries.md @@ -30,7 +30,6 @@ - `bitcoinconsensus_SCRIPT_FLAGS_VERIFY_NONE` - `bitcoinconsensus_SCRIPT_FLAGS_VERIFY_P2SH` - Evaluate P2SH ([BIP16](https://github.com/bitcoin/bips/blob/master/bip-0016.mediawiki)) subscripts - `bitcoinconsensus_SCRIPT_FLAGS_VERIFY_DERSIG` - Enforce strict DER ([BIP66](https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki)) compliance -- `bitcoinconsensus_SCRIPT_FLAGS_VERIFY_NULLDUMMY` - Enforce NULLDUMMY ([BIP147](https://github.com/bitcoin/bips/blob/master/bip-0147.mediawiki)) - `bitcoinconsensus_SCRIPT_FLAGS_VERIFY_CHECKLOCKTIMEVERIFY` - Enable CHECKLOCKTIMEVERIFY ([BIP65](https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki)) - `bitcoinconsensus_SCRIPT_FLAGS_VERIFY_CHECKSEQUENCEVERIFY` - Enable CHECKSEQUENCEVERIFY ([BIP112](https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki)) - `bitcoinconsensus_SCRIPT_FLAGS_VERIFY_WITNESS` - Enable WITNESS ([BIP141](https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki)) diff --git a/src/policy/policy.h b/src/policy/policy.h --- a/src/policy/policy.h +++ b/src/policy/policy.h @@ -84,11 +84,10 @@ */ static constexpr uint32_t STANDARD_SCRIPT_VERIFY_FLAGS = MANDATORY_SCRIPT_VERIFY_FLAGS | SCRIPT_VERIFY_DERSIG | - SCRIPT_VERIFY_NULLDUMMY | SCRIPT_VERIFY_SIGPUSHONLY | - SCRIPT_VERIFY_MINIMALDATA | SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS | - SCRIPT_VERIFY_CLEANSTACK | SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY | - SCRIPT_VERIFY_CHECKSEQUENCEVERIFY | SCRIPT_VERIFY_CHECKDATASIG_SIGOPS | - SCRIPT_DISALLOW_SEGWIT_RECOVERY; + SCRIPT_VERIFY_SIGPUSHONLY | SCRIPT_VERIFY_MINIMALDATA | + SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS | SCRIPT_VERIFY_CLEANSTACK | + SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY | SCRIPT_VERIFY_CHECKSEQUENCEVERIFY | + SCRIPT_VERIFY_CHECKDATASIG_SIGOPS | SCRIPT_DISALLOW_SEGWIT_RECOVERY; /** * For convenience, standard but not mandatory verify flags. diff --git a/src/script/bitcoinconsensus.h b/src/script/bitcoinconsensus.h --- a/src/script/bitcoinconsensus.h +++ b/src/script/bitcoinconsensus.h @@ -51,8 +51,6 @@ bitcoinconsensus_SCRIPT_FLAGS_VERIFY_P2SH = (1U << 0), // enforce strict DER (BIP66) compliance bitcoinconsensus_SCRIPT_FLAGS_VERIFY_DERSIG = (1U << 2), - // enforce NULLDUMMY (BIP147) - bitcoinconsensus_SCRIPT_FLAGS_VERIFY_NULLDUMMY = (1U << 4), // enable CHECKLOCKTIMEVERIFY (BIP65) bitcoinconsensus_SCRIPT_FLAGS_VERIFY_CHECKLOCKTIMEVERIFY = (1U << 9), // enable CHECKSEQUENCEVERIFY (BIP112) @@ -64,7 +62,6 @@ bitcoinconsensus_SCRIPT_FLAGS_VERIFY_ALL = bitcoinconsensus_SCRIPT_FLAGS_VERIFY_P2SH | bitcoinconsensus_SCRIPT_FLAGS_VERIFY_DERSIG | - bitcoinconsensus_SCRIPT_FLAGS_VERIFY_NULLDUMMY | bitcoinconsensus_SCRIPT_FLAGS_VERIFY_CHECKLOCKTIMEVERIFY | bitcoinconsensus_SCRIPT_FLAGS_VERIFY_CHECKSEQUENCEVERIFY, }; diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -1107,18 +1107,6 @@ } } else { // LEGACY MULTISIG (ECDSA / NULL) - // A bug causes CHECKMULTISIG to consume one extra - // argument whose contents were not checked in any - // way. - // - // Unfortunately this is a potential source of - // mutability, so optionally verify it is exactly - // equal to zero. - if ((flags & SCRIPT_VERIFY_NULLDUMMY) && - stacktop(-idxDummy).size()) { - return set_error(serror, - ScriptError::SIG_NULLDUMMY); - } // Remove signature for pre-fork scripts for (int k = 0; k < nSigsCount; k++) { diff --git a/src/script/script_error.h b/src/script/script_error.h --- a/src/script/script_error.h +++ b/src/script/script_error.h @@ -60,7 +60,6 @@ MINIMALDATA, SIG_PUSHONLY, SIG_HIGH_S, - SIG_NULLDUMMY, PUBKEYTYPE, CLEANSTACK, MINIMALIF, diff --git a/src/script/script_error.cpp b/src/script/script_error.cpp --- a/src/script/script_error.cpp +++ b/src/script/script_error.cpp @@ -81,8 +81,6 @@ return "Only push operators allowed in signature scripts"; case ScriptError::SIG_HIGH_S: return "Non-canonical signature: S value is unnecessarily high"; - case ScriptError::SIG_NULLDUMMY: - return "Dummy CHECKMULTISIG argument must be zero"; case ScriptError::MINIMALIF: return "OP_IF/NOTIF argument must be minimal"; case ScriptError::SIG_NULLFAIL: diff --git a/src/script/script_flags.h b/src/script/script_flags.h --- a/src/script/script_flags.h +++ b/src/script/script_flags.h @@ -30,10 +30,6 @@ // (softfork safe, BIP62 rule 5). SCRIPT_VERIFY_LOW_S = (1U << 3), - // verify dummy stack item consumed by CHECKMULTISIG is of zero-length - // (softfork safe, BIP62 rule 7). - SCRIPT_VERIFY_NULLDUMMY = (1U << 4), - // Using a non-push operator in the scriptSig causes script failure // (softfork safe, BIP62 rule 2). SCRIPT_VERIFY_SIGPUSHONLY = (1U << 5), diff --git a/src/test/data/script_tests.json b/src/test/data/script_tests.json --- a/src/test/data/script_tests.json +++ b/src/test/data/script_tests.json @@ -2361,13 +2361,6 @@ "3 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG", "", "OK", - "3-of-3 with nonzero dummy but no NULLDUMMY" -], -[ - "1 0x47 0x304402204d69d5caa4dbab259f79fce89d3b459bbd91697c1c052a1554ff3b08b2241cbd0220330a8e17a90d51996e363cb8902fce6278c6350fa59ae12832db2f6a44d64dce01 0x47 0x3044022031a1e5289b0d9c33ec182a7f67210b9997187c710f7d3f0f28bdfb618c4e025c02205d95fe63ee83a20ec44159a06f7c0b43b61d5f0c346ca4a2cc7b91878ad1a85001 0x47 0x304402200a9faba8228f7a86bf6c3b2a0da0e2f9136ea390e5a5f66dbf232e499459f34a0220437bcac47d837870eeb41aabc379cbf2b1dcef954bd887f3968849922694ebd701", - "3 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG", - "NULLDUMMY", - "SIG_NULLDUMMY", "3-of-3 with nonzero dummy" ], [ @@ -2375,14 +2368,7 @@ "3 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG NOT", "", "OK", - "3-of-3 NOT with invalid sig and nonzero dummy but no NULLDUMMY" -], -[ - "1 0x47 0x304402203f78692a12d075d5057dea07265f0ba8ede774f083b85896fe07231efbe155da0220388fc48ffd8fb1c189fbf8bd767ee1c38b3f5d864b18faa1d81d0c3670cda85b01 0x47 0x3044022070a2850b5363fc49db8f617f08f5947bb85a1d439da07a6dc0d2fc178d9a5f3f022019e15a476e9dab8e3cb18a2bcae279366b1701c1b11c020851517cf03132bbff01 0x47 0x304402206457d83204e94902c789a16fa9e2f1f1d25684c7748c93373e9077b01a49b80a02204b0509cba423c7bbad8f80653c54a1ce10c901d33292464a4d5162f2016ddc2901", - "3 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG NOT", - "NULLDUMMY", - "SIG_NULLDUMMY", - "3-of-3 NOT with invalid sig with nonzero dummy" + "3-of-3 NOT with invalid sig and nonzero dummy" ], [ "0 0x47 0x3044022044b11d5a64bebbd4280c616146bc961eed3081300eef527fbe8da91f6775892a022045b044719bf5c7100617cd518fff22c102f93e6768ed986543668be43bc44d1601 DUP", @@ -3337,13 +3323,6 @@ "OK", "CHECKMULTISIG 0-of-1 with SCHNORR_MULTISIG, dummy need not be null" ], -[ - "1 0x41 0x105e4fed395e64ca013ac1ce020ef69b9990a577fe4b74648faafb69e499f76dd53d5c64aa866924361dd3aadde9b7184bbcb4f79520396c9ed17c4d8489a59701", - "1 0x41 0x0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 1 CHECKMULTISIG", - "MINIMALDATA,NULLDUMMY,NULLFAIL,SCHNORR_MULTISIG,STRICTENC", - "OK", - "SCHNORR_MULTISIG implies that NULLDUMMY flag has no effect" -], [ "1 0x41 0x17fa4dd3e62694cc7816d32b73d5646ea768072aea4926a09e159e5f57be8fd6523800b259fe2a12e27aa29a3719f19e9e4b99d7f8e465a6f19454f914ccb3ec01", "1 0x41 0x0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 1 CHECKMULTISIGVERIFY 1", @@ -3416,8 +3395,7 @@ ["NULLFAIL should cover all signatures and signatures only"], ["0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", "0x01 0x14 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0x01 0x14 CHECKMULTISIG NOT", "DERSIG", "OK", "BIP66 and NULLFAIL-compliant"], ["0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", "0x01 0x14 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0x01 0x14 CHECKMULTISIG NOT", "DERSIG,NULLFAIL", "OK", "BIP66 and NULLFAIL-compliant"], -["1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", "0x01 0x14 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0x01 0x14 CHECKMULTISIG NOT", "DERSIG,NULLFAIL", "OK", "BIP66 and NULLFAIL-compliant, not NULLDUMMY-compliant"], -["1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", "0x01 0x14 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0x01 0x14 CHECKMULTISIG NOT", "DERSIG,NULLFAIL,NULLDUMMY", "SIG_NULLDUMMY", "BIP66 and NULLFAIL-compliant, not NULLDUMMY-compliant"], +["1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", "0x01 0x14 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0x01 0x14 CHECKMULTISIG NOT", "DERSIG,NULLFAIL", "OK", "BIP66 and NULLFAIL-compliant"], ["0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0x09 0x300602010102010101", "0x01 0x14 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0x01 0x14 CHECKMULTISIG NOT", "DERSIG", "OK", "BIP66-compliant but not NULLFAIL-compliant"], ["0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0x09 0x300602010102010101", "0x01 0x14 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0x01 0x14 CHECKMULTISIG NOT", "DERSIG,NULLFAIL", "NULLFAIL", "BIP66-compliant but not NULLFAIL-compliant"], ["0 0x09 0x300602010102010101 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", "0x01 0x14 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0x01 0x14 CHECKMULTISIG NOT", "DERSIG", "OK", "BIP66-compliant but not NULLFAIL-compliant"], diff --git a/src/test/data/tx_invalid.json b/src/test/data/tx_invalid.json --- a/src/test/data/tx_invalid.json +++ b/src/test/data/tx_invalid.json @@ -85,26 +85,6 @@ "0100000001b14bdcbc3e01bdaad36cc08e81e69c82e1060bc14e518db2b49aa43ad90ba260000000004847304402203f16c6f40162ab686621ef3000b04e75418a0c0cb2d8aebeac894ae360ac1e780220ddc15ecdfc3507ac48e1681a33eb60996631bf6bf5bc0a0682c4db743ce7ca2b01ffffffff0140420f00000000001976a914660d4ef3a743e3e696ad990364e555c271ad504b88ac00000000", "P2SH"], -["CHECKMULTISIG SCRIPT_VERIFY_NULLDUMMY tests:"], - -["The following is a tweaked form of 23b397edccd3740a74adb603c9756370fafcde9bcc4483eb271ecad09a94dd63"], -["It is an OP_CHECKMULTISIG with the dummy value set to something other than an empty string"], -[[["60a20bd93aa49ab4b28d514ec10b06e1829ce6818ec06cd3aabd013ebcdc4bb1", 0, "1 0x41 0x04cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaff7d8a473e7e2e6d317b87bafe8bde97e3cf8f065dec022b51d11fcdd0d348ac4 0x41 0x0461cbdcc5409fb4b4d42b51d33381354d80e550078cb532a34bfa2fcfdeb7d76519aecc62770f5b0e4ef8551946d8a540911abe3e7854a26f39f58b25c15342af 2 OP_CHECKMULTISIG"]], -"0100000001b14bdcbc3e01bdaad36cc08e81e69c82e1060bc14e518db2b49aa43ad90ba260000000004a010047304402203f16c6f40162ab686621ef3000b04e75418a0c0cb2d8aebeac894ae360ac1e780220ddc15ecdfc3507ac48e1681a33eb60996631bf6bf5bc0a0682c4db743ce7ca2b01ffffffff0140420f00000000001976a914660d4ef3a743e3e696ad990364e555c271ad504b88ac00000000", "P2SH,NULLDUMMY"], - -["As above, but using an OP_1"], -[[["60a20bd93aa49ab4b28d514ec10b06e1829ce6818ec06cd3aabd013ebcdc4bb1", 0, "1 0x41 0x04cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaff7d8a473e7e2e6d317b87bafe8bde97e3cf8f065dec022b51d11fcdd0d348ac4 0x41 0x0461cbdcc5409fb4b4d42b51d33381354d80e550078cb532a34bfa2fcfdeb7d76519aecc62770f5b0e4ef8551946d8a540911abe3e7854a26f39f58b25c15342af 2 OP_CHECKMULTISIG"]], -"0100000001b14bdcbc3e01bdaad36cc08e81e69c82e1060bc14e518db2b49aa43ad90ba26000000000495147304402203f16c6f40162ab686621ef3000b04e75418a0c0cb2d8aebeac894ae360ac1e780220ddc15ecdfc3507ac48e1681a33eb60996631bf6bf5bc0a0682c4db743ce7ca2b01ffffffff0140420f00000000001976a914660d4ef3a743e3e696ad990364e555c271ad504b88ac00000000", "P2SH,NULLDUMMY"], - -["As above, but using an OP_1NEGATE"], -[[["60a20bd93aa49ab4b28d514ec10b06e1829ce6818ec06cd3aabd013ebcdc4bb1", 0, "1 0x41 0x04cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaff7d8a473e7e2e6d317b87bafe8bde97e3cf8f065dec022b51d11fcdd0d348ac4 0x41 0x0461cbdcc5409fb4b4d42b51d33381354d80e550078cb532a34bfa2fcfdeb7d76519aecc62770f5b0e4ef8551946d8a540911abe3e7854a26f39f58b25c15342af 2 OP_CHECKMULTISIG"]], -"0100000001b14bdcbc3e01bdaad36cc08e81e69c82e1060bc14e518db2b49aa43ad90ba26000000000494f47304402203f16c6f40162ab686621ef3000b04e75418a0c0cb2d8aebeac894ae360ac1e780220ddc15ecdfc3507ac48e1681a33eb60996631bf6bf5bc0a0682c4db743ce7ca2b01ffffffff0140420f00000000001976a914660d4ef3a743e3e696ad990364e555c271ad504b88ac00000000", "P2SH,NULLDUMMY"], - -["As above, but with the dummy byte missing"], -[[["60a20bd93aa49ab4b28d514ec10b06e1829ce6818ec06cd3aabd013ebcdc4bb1", 0, "1 0x41 0x04cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaff7d8a473e7e2e6d317b87bafe8bde97e3cf8f065dec022b51d11fcdd0d348ac4 0x41 0x0461cbdcc5409fb4b4d42b51d33381354d80e550078cb532a34bfa2fcfdeb7d76519aecc62770f5b0e4ef8551946d8a540911abe3e7854a26f39f58b25c15342af 2 OP_CHECKMULTISIG"]], -"0100000001b14bdcbc3e01bdaad36cc08e81e69c82e1060bc14e518db2b49aa43ad90ba260000000004847304402203f16c6f40162ab686621ef3000b04e75418a0c0cb2d8aebeac894ae360ac1e780220ddc15ecdfc3507ac48e1681a33eb60996631bf6bf5bc0a0682c4db743ce7ca2b01ffffffff0140420f00000000001976a914660d4ef3a743e3e696ad990364e555c271ad504b88ac00000000", "P2SH,NULLDUMMY"], - - ["Empty stack when we try to run CHECKSIG"], [[["ad503f72c18df5801ee64d76090afe4c607fb2b822e9b7b63c5826c50e22fc3b", 0, "0x21 0x027c3a97665bf283a102a587a62a30a0c102d4d3b141015e2cae6f64e2543113e5 CHECKSIG NOT"]], "01000000013bfc220ec526583cb6b7e922b8b27f604cfe0a09764de61e80f58dc1723f50ad0000000000ffffffff0101000000000000002321027c3a97665bf283a102a587a62a30a0c102d4d3b141015e2cae6f64e2543113e5ac00000000", "P2SH"], diff --git a/src/test/data/tx_valid.json b/src/test/data/tx_valid.json --- a/src/test/data/tx_valid.json +++ b/src/test/data/tx_valid.json @@ -14,9 +14,8 @@ ["The following is a tweaked form of 23b397edccd3740a74adb603c9756370fafcde9bcc4483eb271ecad09a94dd63"], ["It is an OP_CHECKMULTISIG with an arbitrary extra byte stuffed into the signature at pos length - 2"], -["The dummy byte is fine however, so the NULLDUMMY flag should be happy"], [[["60a20bd93aa49ab4b28d514ec10b06e1829ce6818ec06cd3aabd013ebcdc4bb1", 0, "1 0x41 0x04cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaff7d8a473e7e2e6d317b87bafe8bde97e3cf8f065dec022b51d11fcdd0d348ac4 0x41 0x0461cbdcc5409fb4b4d42b51d33381354d80e550078cb532a34bfa2fcfdeb7d76519aecc62770f5b0e4ef8551946d8a540911abe3e7854a26f39f58b25c15342af 2 OP_CHECKMULTISIG"]], -"0100000001b14bdcbc3e01bdaad36cc08e81e69c82e1060bc14e518db2b49aa43ad90ba260000000004a0048304402203f16c6f40162ab686621ef3000b04e75418a0c0cb2d8aebeac894ae360ac1e780220ddc15ecdfc3507ac48e1681a33eb60996631bf6bf5bc0a0682c4db743ce7ca2bab01ffffffff0140420f00000000001976a914660d4ef3a743e3e696ad990364e555c271ad504b88ac00000000", "P2SH,NULLDUMMY"], +"0100000001b14bdcbc3e01bdaad36cc08e81e69c82e1060bc14e518db2b49aa43ad90ba260000000004a0048304402203f16c6f40162ab686621ef3000b04e75418a0c0cb2d8aebeac894ae360ac1e780220ddc15ecdfc3507ac48e1681a33eb60996631bf6bf5bc0a0682c4db743ce7ca2bab01ffffffff0140420f00000000001976a914660d4ef3a743e3e696ad990364e555c271ad504b88ac00000000", "P2SH"], ["The following is a tweaked form of 23b397edccd3740a74adb603c9756370fafcde9bcc4483eb271ecad09a94dd63"], ["It is an OP_CHECKMULTISIG with the dummy value set to something other than an empty string"], diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -79,7 +79,6 @@ {ScriptError::MINIMALDATA, "MINIMALDATA"}, {ScriptError::SIG_PUSHONLY, "SIG_PUSHONLY"}, {ScriptError::SIG_HIGH_S, "SIG_HIGH_S"}, - {ScriptError::SIG_NULLDUMMY, "SIG_NULLDUMMY"}, {ScriptError::PUBKEYTYPE, "PUBKEYTYPE"}, {ScriptError::CLEANSTACK, "CLEANSTACK"}, {ScriptError::MINIMALIF, "MINIMALIF"}, @@ -1067,7 +1066,7 @@ << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG, - "3-of-3 with nonzero dummy but no NULLDUMMY", 0) + "3-of-3 with nonzero dummy", 0) .Num(1) .PushSigECDSA(keys.key0) .PushSigECDSA(keys.key1) @@ -1075,39 +1074,14 @@ tests.push_back(TestBuilder(CScript() << OP_3 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 - << OP_CHECKMULTISIG, - "3-of-3 with nonzero dummy", - SCRIPT_VERIFY_NULLDUMMY) + << OP_CHECKMULTISIG << OP_NOT, + "3-of-3 NOT with invalid sig and nonzero dummy", + 0) .Num(1) .PushSigECDSA(keys.key0) .PushSigECDSA(keys.key1) .PushSigECDSA(keys.key2) - .SetScriptError(ScriptError::SIG_NULLDUMMY)); - tests.push_back( - TestBuilder( - CScript() << OP_3 << ToByteVector(keys.pubkey0C) - << ToByteVector(keys.pubkey1C) - << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG - << OP_NOT, - "3-of-3 NOT with invalid sig and nonzero dummy but no NULLDUMMY", 0) - .Num(1) - .PushSigECDSA(keys.key0) - .PushSigECDSA(keys.key1) - .PushSigECDSA(keys.key2) - .DamagePush(10)); - tests.push_back( - TestBuilder(CScript() << OP_3 << ToByteVector(keys.pubkey0C) - << ToByteVector(keys.pubkey1C) - << ToByteVector(keys.pubkey2C) << OP_3 - << OP_CHECKMULTISIG << OP_NOT, - "3-of-3 NOT with invalid sig with nonzero dummy", - SCRIPT_VERIFY_NULLDUMMY) - .Num(1) - .PushSigECDSA(keys.key0) - .PushSigECDSA(keys.key1) - .PushSigECDSA(keys.key2) - .DamagePush(10) - .SetScriptError(ScriptError::SIG_NULLDUMMY)); + .DamagePush(10)); tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey1C) << OP_2 @@ -2214,14 +2188,6 @@ "dummy need not be null", newmultisigflags) .Push("00")); - tests.push_back( - TestBuilder( - CScript() << OP_1 << ToByteVector(keys.pubkey0) << OP_1 - << OP_CHECKMULTISIG, - "SCHNORR_MULTISIG implies that NULLDUMMY flag has no effect", - newmultisigflags | SCRIPT_VERIFY_NULLDUMMY) - .Num(0b1) - .PushSigSchnorr(keys.key0)); tests.push_back( TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey0) << OP_1 << OP_CHECKMULTISIGVERIFY << OP_1, diff --git a/src/test/scriptflags.cpp b/src/test/scriptflags.cpp --- a/src/test/scriptflags.cpp +++ b/src/test/scriptflags.cpp @@ -21,7 +21,6 @@ {"LOW_S", SCRIPT_VERIFY_LOW_S}, {"SIGPUSHONLY", SCRIPT_VERIFY_SIGPUSHONLY}, {"MINIMALDATA", SCRIPT_VERIFY_MINIMALDATA}, - {"NULLDUMMY", SCRIPT_VERIFY_NULLDUMMY}, {"DISCOURAGE_UPGRADABLE_NOPS", SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS}, {"CLEANSTACK", SCRIPT_VERIFY_CLEANSTACK}, {"MINIMALIF", SCRIPT_VERIFY_MINIMALIF}, diff --git a/test/functional/abc-schnorrmultisig-activation.py b/test/functional/abc-schnorrmultisig-activation.py --- a/test/functional/abc-schnorrmultisig-activation.py +++ b/test/functional/abc-schnorrmultisig-activation.py @@ -55,15 +55,11 @@ REPLAY_PROTECTION_START_TIME = GRAVITON_START_TIME * 2 -# Before the upgrade, Schnorr checkmultisig is rejected but forgiven if it -# would have been valid after the upgrade. +# Before the upgrade, Schnorr checkmultisig is rejected. PREUPGRADE_SCHNORR_MULTISIG_ERROR = 'mandatory-script-verify-flag-failed (Signature cannot be 65 bytes in CHECKMULTISIG)' -# Before the upgrade, ECDSA checkmultisig with non-null dummy are rejected with -# a non-mandatory error. -PREUPGRADE_ECDSA_NULLDUMMY_ERROR = 'non-mandatory-script-verify-flag (Dummy CHECKMULTISIG argument must be zero)' # After the upgrade, ECDSA checkmultisig with non-null dummy are invalid since -# the new mode refuses ECDSA, but still do not result in ban. +# the new mode refuses ECDSA. POSTUPGRADE_ECDSA_NULLDUMMY_ERROR = 'mandatory-script-verify-flag-failed (Only Schnorr signatures allowed in this operation)' # A mandatory (bannable) error occurs when people pass Schnorr signatures into @@ -219,7 +215,7 @@ ecdsa0tx = create_fund_and_spend_tx(OP_0, 'ecdsa') ecdsa0tx_2 = create_fund_and_spend_tx(OP_0, 'ecdsa') - # two of these, which are nonstandard before upgrade and invalid after. + # two of these, which are valid before upgrade and invalid after. ecdsa1tx = create_fund_and_spend_tx(OP_1, 'ecdsa') ecdsa1tx_2 = create_fund_and_spend_tx(OP_1, 'ecdsa') @@ -235,17 +231,13 @@ self.log.info("Start preupgrade tests") self.log.info("Sending rejected transactions via RPC") - assert_raises_rpc_error(-26, PREUPGRADE_ECDSA_NULLDUMMY_ERROR, - node.sendrawtransaction, ToHex(ecdsa1tx)) assert_raises_rpc_error(-26, SCHNORR_LEGACY_MULTISIG_ERROR, node.sendrawtransaction, ToHex(schnorr0tx)) assert_raises_rpc_error(-26, PREUPGRADE_SCHNORR_MULTISIG_ERROR, node.sendrawtransaction, ToHex(schnorr1tx)) self.log.info( - "Sending rejected transactions via net (banning depending on situation)") - self.check_for_no_ban_on_rejected_tx( - ecdsa1tx, PREUPGRADE_ECDSA_NULLDUMMY_ERROR) + "Sending rejected transactions via net (bannable)") self.check_for_ban_on_rejected_tx( schnorr0tx, SCHNORR_LEGACY_MULTISIG_ERROR) self.check_for_ban_on_rejected_tx( @@ -293,7 +285,8 @@ preupgrade_block = tip self.log.info( - "Mine the activation block itself, including a legacy nulldummy violation at the last possible moment") + "Mine the activation block itself, including a non-null-dummy ECDSA at the last possible moment") + node.p2p.send_txs_and_test([ecdsa1tx], node) tip = self.build_block(tip, [ecdsa1tx]) node.p2p.send_blocks_and_test([tip], node) @@ -306,11 +299,11 @@ upgrade_block = tip self.log.info( - "Trying to mine a legacy nulldummy violation, but we are just barely too late") + "Trying to mine a non-null-dummy ECDSA, but we are just barely too late") self.check_for_ban_on_rejected_block( self.build_block(tip, [ecdsa1tx_2]), BADINPUTS_ERROR) self.log.info( - "If we try to submit it by mempool or RPC, the error code has changed and we are banned") + "If we try to submit it by mempool or RPC, it is rejected and we are banned") assert_raises_rpc_error(-26, POSTUPGRADE_ECDSA_NULLDUMMY_ERROR, node.sendrawtransaction, ToHex(ecdsa1tx_2)) self.check_for_ban_on_rejected_tx( @@ -351,7 +344,8 @@ self.log.info( "Invalidating the upgrade block evicts the transactions valid only after upgrade") node.invalidateblock(upgrade_block.hash) - assert_equal(set(node.getrawmempool()), {ecdsa0tx_2.hash}) + assert_equal(set(node.getrawmempool()), { + ecdsa0tx_2.hash, ecdsa1tx.hash}) self.log.info("Return to our tip") node.reconsiderblock(upgrade_block.hash) diff --git a/test/functional/feature_nulldummy.py b/test/functional/feature_nulldummy.py deleted file mode 100755 --- a/test/functional/feature_nulldummy.py +++ /dev/null @@ -1,124 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (c) 2016-2019 The Bitcoin Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. -"""Test NULLDUMMY softfork. - -Connect to a single node. -Generate 2 blocks (save the coinbases for later). -Generate 427 more blocks. -[Policy/Consensus] Check that NULLDUMMY compliant transactions are accepted in the 430th block. -[Policy] Check that non-NULLDUMMY transactions are rejected before activation. -[Consensus] Check that the new NULLDUMMY rules are not enforced on the 431st block. -[Policy/Consensus] Check that the new NULLDUMMY rules are enforced on the 432nd block. -""" - -import time - -from test_framework.blocktools import create_block, create_coinbase -from test_framework.messages import CTransaction, FromHex, ToHex -from test_framework.script import CScript -from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import assert_equal, assert_raises_rpc_error - -# This test checks for a reject reason that changes after the graviton -# upgrade. Since the nulldummy effect and this test are destined to be removed -# after the upgrade anyway, we run this test pre-upgrade only. -# More detailed dummy tests can be found in abc-schnorrmultisig-activation.py. -GRAVITON_START_TIME = 2000000000 - -NULLDUMMY_ERROR = "non-mandatory-script-verify-flag (Dummy CHECKMULTISIG argument must be zero) (code 64)" - - -def trueDummy(tx): - scriptSig = CScript(tx.vin[0].scriptSig) - newscript = [] - for i in scriptSig: - if (len(newscript) == 0): - assert len(i) == 0 - newscript.append(b'\x51') - else: - newscript.append(i) - tx.vin[0].scriptSig = CScript(newscript) - tx.rehash() - - -class NULLDUMMYTest(BitcoinTestFramework): - - def set_test_params(self): - self.num_nodes = 1 - self.setup_clean_chain = True - self.extra_args = [['-whitelist=127.0.0.1', - "-gravitonactivationtime={}".format(GRAVITON_START_TIME)]] - - def run_test(self): - self.address = self.nodes[0].getnewaddress() - self.ms_address = self.nodes[0].addmultisigaddress(1, [self.address])[ - 'address'] - - # Block 2 - self.coinbase_blocks = self.nodes[0].generate(2) - coinbase_txid = [] - for i in self.coinbase_blocks: - coinbase_txid.append(self.nodes[0].getblock(i)['tx'][0]) - # Block 429 - self.nodes[0].generate(427) - self.lastblockhash = self.nodes[0].getbestblockhash() - self.tip = int("0x" + self.lastblockhash, 0) - self.lastblockheight = 429 - self.lastblocktime = int(time.time()) + 429 - - self.log.info( - "Test 1: NULLDUMMY compliant base transactions should be accepted to mempool and mined before activation [430]") - test1txs = [self.create_transaction( - self.nodes[0], coinbase_txid[0], self.ms_address, 49)] - txid1 = self.nodes[0].sendrawtransaction(ToHex(test1txs[0]), True) - test1txs.append(self.create_transaction( - self.nodes[0], txid1, self.ms_address, 48)) - txid2 = self.nodes[0].sendrawtransaction(ToHex(test1txs[1]), True) - self.block_submit(self.nodes[0], test1txs, True) - - self.log.info( - "Test 2: Non-NULLDUMMY base multisig transaction should not be accepted to mempool before activation") - test2tx = self.create_transaction( - self.nodes[0], txid2, self.ms_address, 48) - trueDummy(test2tx) - assert_raises_rpc_error(-26, NULLDUMMY_ERROR, - self.nodes[0].sendrawtransaction, ToHex(test2tx), True) - - self.log.info( - "Test 3: Non-NULLDUMMY base transactions should be accepted in a block before activation [431]") - self.block_submit(self.nodes[0], [test2tx], True) - - def create_transaction(self, node, txid, to_address, amount): - inputs = [{"txid": txid, "vout": 0}] - outputs = {to_address: amount} - rawtx = node.createrawtransaction(inputs, outputs) - signresult = node.signrawtransactionwithwallet(rawtx) - return FromHex(CTransaction(), signresult['hex']) - - def block_submit(self, node, txs, accept=False): - block = create_block(self.tip, create_coinbase( - self.lastblockheight + 1), self.lastblocktime + 1) - block.nVersion = 4 - for tx in txs: - tx.rehash() - block.vtx.append(tx) - block.vtx = [block.vtx[0]] + \ - sorted(block.vtx[1:], key=lambda tx: tx.get_id()) - block.hashMerkleRoot = block.calc_merkle_root() - block.rehash() - block.solve() - node.submitblock(ToHex(block)) - if (accept): - assert_equal(node.getbestblockhash(), block.hash) - self.tip = block.sha256 - self.lastblockhash = block.hash - self.lastblocktime += 1 - self.lastblockheight += 1 - else: - assert_equal(node.getbestblockhash(), self.lastblockhash) - - -if __name__ == '__main__': - NULLDUMMYTest().main() diff --git a/test/functional/timing.json b/test/functional/timing.json --- a/test/functional/timing.json +++ b/test/functional/timing.json @@ -143,10 +143,6 @@ "name": "feature_notifications.py", "time": 1 }, - { - "name": "feature_nulldummy.py", - "time": 1 - }, { "name": "feature_proxy.py", "time": 1 @@ -475,4 +471,4 @@ "name": "wallet_zapwallettxes.py", "time": 5 } -] \ No newline at end of file +]