script: use SCRIPT_ERR_SCRIPTNUM for CScriptNum errors

This commit is contained in:
Bruno Garcia 2026-01-22 10:05:27 -03:00
parent 0ca4dcd786
commit bd31a92d67
4 changed files with 74 additions and 68 deletions

View File

@ -1223,6 +1223,10 @@ bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript&
return set_error(serror, SCRIPT_ERR_STACK_SIZE);
}
}
catch (const scriptnum_error&)
{
return set_error(serror, SCRIPT_ERR_SCRIPTNUM);
}
catch (...)
{
return set_error(serror, SCRIPT_ERR_UNKNOWN_ERROR);

View File

@ -859,10 +859,10 @@
["1 1 ADD", "0 EQUAL", "P2SH,STRICTENC", "EVAL_FALSE"],
["11 1 ADD 12 SUB", "11 EQUAL", "P2SH,STRICTENC", "EVAL_FALSE"],
["2147483648 0 ADD", "NOP", "P2SH,STRICTENC", "UNKNOWN_ERROR", "arithmetic operands must be in range [-2^31...2^31] "],
["-2147483648 0 ADD", "NOP", "P2SH,STRICTENC", "UNKNOWN_ERROR", "arithmetic operands must be in range [-2^31...2^31] "],
["2147483647 DUP ADD", "4294967294 NUMEQUAL", "P2SH,STRICTENC", "UNKNOWN_ERROR", "NUMEQUAL must be in numeric range"],
["'abcdef' NOT", "0 EQUAL", "P2SH,STRICTENC", "UNKNOWN_ERROR", "NOT is an arithmetic operand"],
["2147483648 0 ADD", "NOP", "P2SH,STRICTENC", "SCRIPTNUM", "arithmetic operands must be in range [-2^31...2^31] "],
["-2147483648 0 ADD", "NOP", "P2SH,STRICTENC", "SCRIPTNUM", "arithmetic operands must be in range [-2^31...2^31] "],
["2147483647 DUP ADD", "4294967294 NUMEQUAL", "P2SH,STRICTENC", "SCRIPTNUM", "NUMEQUAL must be in numeric range"],
["'abcdef' NOT", "0 EQUAL", "P2SH,STRICTENC", "SCRIPTNUM", "NOT is an arithmetic operand"],
["2 DUP MUL", "4 EQUAL", "P2SH,STRICTENC", "DISABLED_OPCODE", "disabled"],
["2 DUP DIV", "1 EQUAL", "P2SH,STRICTENC", "DISABLED_OPCODE", "disabled"],
@ -1016,14 +1016,14 @@
["1","RESERVED2", "P2SH,STRICTENC", "BAD_OPCODE", "OP_RESERVED2 is reserved"],
["1","0xba", "P2SH,STRICTENC", "BAD_OPCODE", "0xba == MAX_OPCODE + 1"],
["2147483648", "1ADD 1", "P2SH,STRICTENC", "UNKNOWN_ERROR", "We cannot do math on 5-byte integers"],
["2147483648", "NEGATE 1", "P2SH,STRICTENC", "UNKNOWN_ERROR", "We cannot do math on 5-byte integers"],
["-2147483648", "1ADD 1", "P2SH,STRICTENC", "UNKNOWN_ERROR", "Because we use a sign bit, -2147483648 is also 5 bytes"],
["2147483647", "1ADD 1SUB 1", "P2SH,STRICTENC", "UNKNOWN_ERROR", "We cannot do math on 5-byte integers, even if the result is 4-bytes"],
["2147483648", "1SUB 1", "P2SH,STRICTENC", "UNKNOWN_ERROR", "We cannot do math on 5-byte integers, even if the result is 4-bytes"],
["2147483648", "1ADD 1", "P2SH,STRICTENC", "SCRIPTNUM", "We cannot do math on 5-byte integers"],
["2147483648", "NEGATE 1", "P2SH,STRICTENC", "SCRIPTNUM", "We cannot do math on 5-byte integers"],
["-2147483648", "1ADD 1", "P2SH,STRICTENC", "SCRIPTNUM", "Because we use a sign bit, -2147483648 is also 5 bytes"],
["2147483647", "1ADD 1SUB 1", "P2SH,STRICTENC", "SCRIPTNUM", "We cannot do math on 5-byte integers, even if the result is 4-bytes"],
["2147483648", "1SUB 1", "P2SH,STRICTENC", "SCRIPTNUM", "We cannot do math on 5-byte integers, even if the result is 4-bytes"],
["2147483648 1", "BOOLOR 1", "P2SH,STRICTENC", "UNKNOWN_ERROR", "We cannot do BOOLOR on 5-byte integers (but we can still do IF etc)"],
["2147483648 1", "BOOLAND 1", "P2SH,STRICTENC", "UNKNOWN_ERROR", "We cannot do BOOLAND on 5-byte integers"],
["2147483648 1", "BOOLOR 1", "P2SH,STRICTENC", "SCRIPTNUM", "We cannot do BOOLOR on 5-byte integers (but we can still do IF etc)"],
["2147483648 1", "BOOLAND 1", "P2SH,STRICTENC", "SCRIPTNUM", "We cannot do BOOLAND on 5-byte integers"],
["1", "1 ENDIF", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL", "ENDIF without IF"],
["1", "IF 1", "P2SH,STRICTENC", "UNBALANCED_CONDITIONAL", "IF without ENDIF"],
@ -1169,66 +1169,66 @@
["MINIMALDATA enforcement for numeric arguments"],
["0x01 0x00", "NOT DROP 1", "MINIMALDATA", "UNKNOWN_ERROR", "numequals 0"],
["0x02 0x0000", "NOT DROP 1", "MINIMALDATA", "UNKNOWN_ERROR", "numequals 0"],
["0x01 0x80", "NOT DROP 1", "MINIMALDATA", "UNKNOWN_ERROR", "0x80 (negative zero) numequals 0"],
["0x02 0x0080", "NOT DROP 1", "MINIMALDATA", "UNKNOWN_ERROR", "numequals 0"],
["0x02 0x0500", "NOT DROP 1", "MINIMALDATA", "UNKNOWN_ERROR", "numequals 5"],
["0x03 0x050000", "NOT DROP 1", "MINIMALDATA", "UNKNOWN_ERROR", "numequals 5"],
["0x02 0x0580", "NOT DROP 1", "MINIMALDATA", "UNKNOWN_ERROR", "numequals -5"],
["0x03 0x050080", "NOT DROP 1", "MINIMALDATA", "UNKNOWN_ERROR", "numequals -5"],
["0x03 0xff7f80", "NOT DROP 1", "MINIMALDATA", "UNKNOWN_ERROR", "Minimal encoding is 0xffff"],
["0x03 0xff7f00", "NOT DROP 1", "MINIMALDATA", "UNKNOWN_ERROR", "Minimal encoding is 0xff7f"],
["0x04 0xffff7f80", "NOT DROP 1", "MINIMALDATA", "UNKNOWN_ERROR", "Minimal encoding is 0xffffff"],
["0x04 0xffff7f00", "NOT DROP 1", "MINIMALDATA", "UNKNOWN_ERROR", "Minimal encoding is 0xffff7f"],
["0x01 0x00", "NOT DROP 1", "MINIMALDATA", "SCRIPTNUM", "numequals 0"],
["0x02 0x0000", "NOT DROP 1", "MINIMALDATA", "SCRIPTNUM", "numequals 0"],
["0x01 0x80", "NOT DROP 1", "MINIMALDATA", "SCRIPTNUM", "0x80 (negative zero) numequals 0"],
["0x02 0x0080", "NOT DROP 1", "MINIMALDATA", "SCRIPTNUM", "numequals 0"],
["0x02 0x0500", "NOT DROP 1", "MINIMALDATA", "SCRIPTNUM", "numequals 5"],
["0x03 0x050000", "NOT DROP 1", "MINIMALDATA", "SCRIPTNUM", "numequals 5"],
["0x02 0x0580", "NOT DROP 1", "MINIMALDATA", "SCRIPTNUM", "numequals -5"],
["0x03 0x050080", "NOT DROP 1", "MINIMALDATA", "SCRIPTNUM", "numequals -5"],
["0x03 0xff7f80", "NOT DROP 1", "MINIMALDATA", "SCRIPTNUM", "Minimal encoding is 0xffff"],
["0x03 0xff7f00", "NOT DROP 1", "MINIMALDATA", "SCRIPTNUM", "Minimal encoding is 0xff7f"],
["0x04 0xffff7f80", "NOT DROP 1", "MINIMALDATA", "SCRIPTNUM", "Minimal encoding is 0xffffff"],
["0x04 0xffff7f00", "NOT DROP 1", "MINIMALDATA", "SCRIPTNUM", "Minimal encoding is 0xffff7f"],
["Test every numeric-accepting opcode for correct handling of the numeric minimal encoding rule"],
["1 0x02 0x0000", "PICK DROP", "MINIMALDATA", "UNKNOWN_ERROR"],
["1 0x02 0x0000", "ROLL DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"],
["0x02 0x0000", "1ADD DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"],
["0x02 0x0000", "1SUB DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"],
["0x02 0x0000", "NEGATE DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"],
["0x02 0x0000", "ABS DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"],
["0x02 0x0000", "NOT DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"],
["0x02 0x0000", "0NOTEQUAL DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"],
["1 0x02 0x0000", "PICK DROP", "MINIMALDATA", "SCRIPTNUM"],
["1 0x02 0x0000", "ROLL DROP 1", "MINIMALDATA", "SCRIPTNUM"],
["0x02 0x0000", "1ADD DROP 1", "MINIMALDATA", "SCRIPTNUM"],
["0x02 0x0000", "1SUB DROP 1", "MINIMALDATA", "SCRIPTNUM"],
["0x02 0x0000", "NEGATE DROP 1", "MINIMALDATA", "SCRIPTNUM"],
["0x02 0x0000", "ABS DROP 1", "MINIMALDATA", "SCRIPTNUM"],
["0x02 0x0000", "NOT DROP 1", "MINIMALDATA", "SCRIPTNUM"],
["0x02 0x0000", "0NOTEQUAL DROP 1", "MINIMALDATA", "SCRIPTNUM"],
["0 0x02 0x0000", "ADD DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"],
["0x02 0x0000 0", "ADD DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"],
["0 0x02 0x0000", "SUB DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"],
["0x02 0x0000 0", "SUB DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"],
["0 0x02 0x0000", "BOOLAND DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"],
["0x02 0x0000 0", "BOOLAND DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"],
["0 0x02 0x0000", "BOOLOR DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"],
["0x02 0x0000 0", "BOOLOR DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"],
["0 0x02 0x0000", "NUMEQUAL DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"],
["0x02 0x0000 1", "NUMEQUAL DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"],
["0 0x02 0x0000", "NUMEQUALVERIFY 1", "MINIMALDATA", "UNKNOWN_ERROR"],
["0x02 0x0000 0", "NUMEQUALVERIFY 1", "MINIMALDATA", "UNKNOWN_ERROR"],
["0 0x02 0x0000", "NUMNOTEQUAL DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"],
["0x02 0x0000 0", "NUMNOTEQUAL DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"],
["0 0x02 0x0000", "LESSTHAN DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"],
["0x02 0x0000 0", "LESSTHAN DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"],
["0 0x02 0x0000", "GREATERTHAN DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"],
["0x02 0x0000 0", "GREATERTHAN DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"],
["0 0x02 0x0000", "LESSTHANOREQUAL DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"],
["0x02 0x0000 0", "LESSTHANOREQUAL DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"],
["0 0x02 0x0000", "GREATERTHANOREQUAL DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"],
["0x02 0x0000 0", "GREATERTHANOREQUAL DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"],
["0 0x02 0x0000", "MIN DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"],
["0x02 0x0000 0", "MIN DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"],
["0 0x02 0x0000", "MAX DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"],
["0x02 0x0000 0", "MAX DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"],
["0 0x02 0x0000", "ADD DROP 1", "MINIMALDATA", "SCRIPTNUM"],
["0x02 0x0000 0", "ADD DROP 1", "MINIMALDATA", "SCRIPTNUM"],
["0 0x02 0x0000", "SUB DROP 1", "MINIMALDATA", "SCRIPTNUM"],
["0x02 0x0000 0", "SUB DROP 1", "MINIMALDATA", "SCRIPTNUM"],
["0 0x02 0x0000", "BOOLAND DROP 1", "MINIMALDATA", "SCRIPTNUM"],
["0x02 0x0000 0", "BOOLAND DROP 1", "MINIMALDATA", "SCRIPTNUM"],
["0 0x02 0x0000", "BOOLOR DROP 1", "MINIMALDATA", "SCRIPTNUM"],
["0x02 0x0000 0", "BOOLOR DROP 1", "MINIMALDATA", "SCRIPTNUM"],
["0 0x02 0x0000", "NUMEQUAL DROP 1", "MINIMALDATA", "SCRIPTNUM"],
["0x02 0x0000 1", "NUMEQUAL DROP 1", "MINIMALDATA", "SCRIPTNUM"],
["0 0x02 0x0000", "NUMEQUALVERIFY 1", "MINIMALDATA", "SCRIPTNUM"],
["0x02 0x0000 0", "NUMEQUALVERIFY 1", "MINIMALDATA", "SCRIPTNUM"],
["0 0x02 0x0000", "NUMNOTEQUAL DROP 1", "MINIMALDATA", "SCRIPTNUM"],
["0x02 0x0000 0", "NUMNOTEQUAL DROP 1", "MINIMALDATA", "SCRIPTNUM"],
["0 0x02 0x0000", "LESSTHAN DROP 1", "MINIMALDATA", "SCRIPTNUM"],
["0x02 0x0000 0", "LESSTHAN DROP 1", "MINIMALDATA", "SCRIPTNUM"],
["0 0x02 0x0000", "GREATERTHAN DROP 1", "MINIMALDATA", "SCRIPTNUM"],
["0x02 0x0000 0", "GREATERTHAN DROP 1", "MINIMALDATA", "SCRIPTNUM"],
["0 0x02 0x0000", "LESSTHANOREQUAL DROP 1", "MINIMALDATA", "SCRIPTNUM"],
["0x02 0x0000 0", "LESSTHANOREQUAL DROP 1", "MINIMALDATA", "SCRIPTNUM"],
["0 0x02 0x0000", "GREATERTHANOREQUAL DROP 1", "MINIMALDATA", "SCRIPTNUM"],
["0x02 0x0000 0", "GREATERTHANOREQUAL DROP 1", "MINIMALDATA", "SCRIPTNUM"],
["0 0x02 0x0000", "MIN DROP 1", "MINIMALDATA", "SCRIPTNUM"],
["0x02 0x0000 0", "MIN DROP 1", "MINIMALDATA", "SCRIPTNUM"],
["0 0x02 0x0000", "MAX DROP 1", "MINIMALDATA", "SCRIPTNUM"],
["0x02 0x0000 0", "MAX DROP 1", "MINIMALDATA", "SCRIPTNUM"],
["0x02 0x0000 0 0", "WITHIN DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"],
["0 0x02 0x0000 0", "WITHIN DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"],
["0 0 0x02 0x0000", "WITHIN DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"],
["0x02 0x0000 0 0", "WITHIN DROP 1", "MINIMALDATA", "SCRIPTNUM"],
["0 0x02 0x0000 0", "WITHIN DROP 1", "MINIMALDATA", "SCRIPTNUM"],
["0 0 0x02 0x0000", "WITHIN DROP 1", "MINIMALDATA", "SCRIPTNUM"],
["0 0 0x02 0x0000", "CHECKMULTISIG DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"],
["0 0x02 0x0000 0", "CHECKMULTISIG DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"],
["0 0x02 0x0000 0 1", "CHECKMULTISIG DROP 1", "MINIMALDATA", "UNKNOWN_ERROR"],
["0 0 0x02 0x0000", "CHECKMULTISIGVERIFY 1", "MINIMALDATA", "UNKNOWN_ERROR"],
["0 0x02 0x0000 0", "CHECKMULTISIGVERIFY 1", "MINIMALDATA", "UNKNOWN_ERROR"],
["0 0 0x02 0x0000", "CHECKMULTISIG DROP 1", "MINIMALDATA", "SCRIPTNUM"],
["0 0x02 0x0000 0", "CHECKMULTISIG DROP 1", "MINIMALDATA", "SCRIPTNUM"],
["0 0x02 0x0000 0 1", "CHECKMULTISIG DROP 1", "MINIMALDATA", "SCRIPTNUM"],
["0 0 0x02 0x0000", "CHECKMULTISIGVERIFY 1", "MINIMALDATA", "SCRIPTNUM"],
["0 0x02 0x0000 0", "CHECKMULTISIGVERIFY 1", "MINIMALDATA", "SCRIPTNUM"],
["Order of CHECKMULTISIG evaluation tests, inverted by swapping the order of"],
@ -2551,7 +2551,7 @@
["CHECKSEQUENCEVERIFY tests"],
["", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY", "INVALID_STACK_OPERATION", "CSV automatically fails on an empty stack"],
["-1", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY", "NEGATIVE_LOCKTIME", "CSV automatically fails if stack top is negative"],
["0x0100", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY,MINIMALDATA", "UNKNOWN_ERROR", "CSV fails if stack top is not minimally encoded"],
["0x0100", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY,MINIMALDATA", "SCRIPTNUM", "CSV fails if stack top is not minimally encoded"],
["0", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY", "UNSATISFIED_LOCKTIME", "CSV fails if stack top bit 1 << 31 is set and the tx version < 2"],
["0x050000000001", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY", "UNSATISFIED_LOCKTIME",
"CSV fails if stack top bit 1 << 31 is not set, and tx version < 2"],

View File

@ -95,6 +95,7 @@ static ScriptErrorDesc script_errors[]={
{SCRIPT_ERR_TAPSCRIPT_EMPTY_PUBKEY, "TAPSCRIPT_EMPTY_PUBKEY"},
{SCRIPT_ERR_OP_CODESEPARATOR, "OP_CODESEPARATOR"},
{SCRIPT_ERR_SIG_FINDANDDELETE, "SIG_FINDANDDELETE"},
{SCRIPT_ERR_SCRIPTNUM, "SCRIPTNUM"}
};
static std::string FormatScriptFlags(script_verify_flags flags)

View File

@ -640,6 +640,7 @@ ERR_BAD_OPCODE = {"err_msg": "Opcode missing or not understood"}
ERR_EVAL_FALSE = {"err_msg": "Script evaluated without error but finished with a false/empty top stack element"}
ERR_WITNESS_PROGRAM_WITNESS_EMPTY = {"err_msg": "Witness program was passed an empty witness"}
ERR_CHECKSIGVERIFY = {"err_msg": "Script failed an OP_CHECKSIGVERIFY operation"}
ERR_SCRIPT_NUM = {"err_msg": "Script number overflowed or is non-minimally encoded"}
VALID_SIGHASHES_ECDSA = [
SIGHASH_ALL,
@ -1060,8 +1061,8 @@ def spenders_taproot_active():
add_spender(spenders, "tapscript/emptypk/checksigadd", leaf="t9", **SINGLE_SIG, **common, failure={"leaf": "t10"}, **ERR_TAPSCRIPT_EMPTY_PUBKEY)
add_spender(spenders, "tapscript/emptypk/checksigadd", leaf="t35", standard=False, **SINGLE_SIG, **common, failure={"leaf": "t10"}, **ERR_TAPSCRIPT_EMPTY_PUBKEY)
# Test that OP_CHECKSIGADD results are as expected
add_spender(spenders, "tapscript/checksigaddresults", leaf="t28", **SINGLE_SIG, **common, failure={"leaf": "t27"}, err_msg="unknown error")
add_spender(spenders, "tapscript/checksigaddoversize", leaf="t29", **SINGLE_SIG, **common, failure={"leaf": "t27"}, err_msg="unknown error")
add_spender(spenders, "tapscript/checksigaddresults", leaf="t28", **SINGLE_SIG, **common, failure={"leaf": "t27"}, **ERR_SCRIPT_NUM)
add_spender(spenders, "tapscript/checksigaddoversize", leaf="t29", **SINGLE_SIG, **common, failure={"leaf": "t27"}, **ERR_SCRIPT_NUM)
# Test that OP_CHECKSIGADD requires 3 stack elements.
add_spender(spenders, "tapscript/checksigadd3args", leaf="t9", **SINGLE_SIG, **common, failure={"leaf": "t11"}, **ERR_INVALID_STACK_OPERATION)
# Test that empty signatures do not cause script failure in OP_CHECKSIG and OP_CHECKSIGADD (but do fail with empty pubkey, and do fail OP_CHECKSIGVERIFY)