diff --git a/src/script/interpreter.h b/src/script/interpreter.h --- a/src/script/interpreter.h +++ b/src/script/interpreter.h @@ -106,6 +106,10 @@ // Do we accept activate replay protection using a different fork id. // SCRIPT_ENABLE_REPLAY_PROTECTION = (1U << 17), + + // Is OP_CHECKDATASIG and variant are enabled. + // + SCRIPT_ENABLE_CHECKDATASIG = (1U << 18), }; bool CheckSignatureEncoding(const std::vector &vchSig, uint32_t flags, diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -140,7 +140,7 @@ // Verify that the length of the signature matches the sum of the length // of the elements. - if ((size_t)(lenR + lenS + 7) != sig.size()) return false; + if (size_t(lenR + lenS + 7) != sig.size()) return false; // Check whether the R element is an integer. if (sig[2] != 0x02) return false; diff --git a/src/test/checkdatasig_tests.cpp b/src/test/checkdatasig_tests.cpp --- a/src/test/checkdatasig_tests.cpp +++ b/src/test/checkdatasig_tests.cpp @@ -28,10 +28,19 @@ BaseSignatureChecker sigchecker; for (uint32_t flags : flagset) { - // Make sure that opcodes are disabled. + // The opcode are not implemented yet, so we get a bad opcode error when + // passing the activation flag. ScriptError err = SCRIPT_ERR_OK; stacktype stack{original_stack}; - bool r = EvalScript(stack, script, flags, sigchecker, &err); + bool r = EvalScript(stack, script, flags | SCRIPT_ENABLE_CHECKDATASIG, + sigchecker, &err); + BOOST_CHECK(!r); + BOOST_CHECK_EQUAL(err, SCRIPT_ERR_BAD_OPCODE); + + // Make sure that we get a bad opcode when the activation flag is not + // passed. + stack = original_stack; + r = EvalScript(stack, script, flags, sigchecker, &err); BOOST_CHECK(!r); BOOST_CHECK_EQUAL(err, SCRIPT_ERR_BAD_OPCODE); } 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 @@ -241,7 +241,9 @@ "Discouraged NOPs are allowed if not executed"], ["0", "IF CHECKDATASIG ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF CHECKDATASIG ELSE 1 ENDIF", "P2SH,STRICTENC,CHECKDATASIG", "OK"], ["0", "IF CHECKDATASIGVERIFY ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF CHECKDATASIGVERIFY ELSE 1 ENDIF", "P2SH,STRICTENC,CHECKDATASIG", "OK"], ["0", "IF 0xbc ELSE 1 ENDIF", "P2SH,STRICTENC", "OK", "opcodes >= FIRST_UNDEFINED_OP_VALUE invalid if executed"], ["0", "IF 0xbd ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], ["0", "IF 0xbe ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], @@ -1067,7 +1069,9 @@ ["0x50","1", "P2SH,STRICTENC", "BAD_OPCODE", "opcode 0x50 is reserved"], ["1", "IF CHECKDATASIG ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF CHECKDATASIG ELSE 1 ENDIF", "P2SH,STRICTENC,CHECKDATASIG", "BAD_OPCODE"], ["1", "IF CHECKDATASIGVERIFY ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF CHECKDATASIGVERIFY ELSE 1 ENDIF", "P2SH,STRICTENC,CHECKDATASIG", "BAD_OPCODE"], ["1", "IF 0xbc ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE", "opcodes >= FIRST_UNDEFINED_OP_VALUE invalid if executed"], ["1", "IF 0xbd ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], ["1", "IF 0xbe ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], diff --git a/src/test/scriptflags.cpp b/src/test/scriptflags.cpp --- a/src/test/scriptflags.cpp +++ b/src/test/scriptflags.cpp @@ -31,6 +31,7 @@ {"COMPRESSED_PUBKEYTYPE", SCRIPT_VERIFY_COMPRESSED_PUBKEYTYPE}, {"SIGHASH_FORKID", SCRIPT_ENABLE_SIGHASH_FORKID}, {"REPLAY_PROTECTION", SCRIPT_ENABLE_REPLAY_PROTECTION}, + {"CHECKDATASIG", SCRIPT_ENABLE_CHECKDATASIG}, }; uint32_t ParseScriptFlags(std::string strFlags) {