diff --git a/src/script/interpreter.h b/src/script/interpreter.h --- a/src/script/interpreter.h +++ b/src/script/interpreter.h @@ -107,6 +107,11 @@ // Do we accept signature using SIGHASH_FORKID // SCRIPT_ENABLE_SIGHASH_FORKID = (1U << 16), + + + // Enable new opcodes activated from 15 May 2018 HF + // + SCRIPT_ENABLE_OPCODES0 = (1U << 17), }; 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 @@ -312,6 +312,7 @@ } int nOpCount = 0; bool fRequireMinimal = (flags & SCRIPT_VERIFY_MINIMALDATA) != 0; + bool fEnabledOpCodes0 = (flags & SCRIPT_ENABLE_OPCODES0) != 0; try { while (pc < pend) { @@ -332,14 +333,28 @@ return set_error(serror, SCRIPT_ERR_OP_COUNT); } - if (opcode == OP_CAT || opcode == OP_SUBSTR || opcode == OP_LEFT || - opcode == OP_RIGHT || opcode == OP_INVERT || opcode == OP_AND || - opcode == OP_OR || opcode == OP_XOR || opcode == OP_2MUL || - opcode == OP_2DIV || opcode == OP_MUL || opcode == OP_DIV || - opcode == OP_MOD || opcode == OP_LSHIFT || - opcode == OP_RSHIFT) { - // Disabled opcodes. - return set_error(serror, SCRIPT_ERR_DISABLED_OPCODE); + // May 15 2018 HF activates AND, OR, XOR, DIV, MOD, CAT, and SPLIT + if (fEnabledOpCodes0) { + if (opcode == OP_CAT || opcode == OP_SUBSTR || opcode == OP_LEFT || + opcode == OP_RIGHT || opcode == OP_INVERT || opcode == OP_AND || + opcode == OP_OR || opcode == OP_XOR || opcode == OP_2MUL || + opcode == OP_2DIV || opcode == OP_MUL || opcode == OP_DIV || + opcode == OP_MOD || opcode == OP_LSHIFT || opcode == OP_RSHIFT || + opcode == OP_SPLIT || opcode == OP_BIN2NUM || opcode == OP_NUM2BIN) { + // Disabled opcodes. + return set_error(serror, SCRIPT_ERR_DISABLED_OPCODE); + } + } + else { + if (opcode == OP_CAT || opcode == OP_SUBSTR || opcode == OP_LEFT || + opcode == OP_RIGHT || opcode == OP_INVERT || opcode == OP_AND || + opcode == OP_OR || opcode == OP_XOR || opcode == OP_2MUL || + opcode == OP_2DIV || opcode == OP_MUL || opcode == OP_DIV || + opcode == OP_MOD || opcode == OP_LSHIFT || opcode == OP_RSHIFT || + opcode == OP_SPLIT || opcode == OP_BIN2NUM || opcode == OP_NUM2BIN) { + // Disabled opcodes. + return set_error(serror, SCRIPT_ERR_DISABLED_OPCODE); + } } if (fExec && 0 <= opcode && opcode <= OP_PUSHDATA4) { diff --git a/src/script/script.h b/src/script/script.h --- a/src/script/script.h +++ b/src/script/script.h @@ -106,6 +106,7 @@ OP_LEFT = 0x80, OP_RIGHT = 0x81, OP_SIZE = 0x82, + OP_SPLIT = 0xba, // bit logic OP_INVERT = 0x83, @@ -134,6 +135,8 @@ OP_MOD = 0x97, OP_LSHIFT = 0x98, OP_RSHIFT = 0x99, + OP_BIN2NUM = 0xbb, + OP_NUM2BIN = 0xbc, OP_BOOLAND = 0x9a, OP_BOOLOR = 0x9b, diff --git a/src/script/script.cpp b/src/script/script.cpp --- a/src/script/script.cpp +++ b/src/script/script.cpp @@ -129,6 +129,8 @@ return "OP_RIGHT"; case OP_SIZE: return "OP_SIZE"; + case OP_SPLIT: + return "OP_SPLIT"; // bit logic case OP_INVERT: @@ -179,6 +181,10 @@ return "OP_LSHIFT"; case OP_RSHIFT: return "OP_RSHIFT"; + case OP_BIN2NUM: + return "OP_BIN2NUM"; + case OP_NUM2BIN: + return "OP_NUM2BIN"; case OP_BOOLAND: return "OP_BOOLAND"; case OP_BOOLOR: 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 @@ -240,10 +240,7 @@ ["0", "IF NOP10 ENDIF 1", "P2SH,STRICTENC,DISCOURAGE_UPGRADABLE_NOPS", "OK", "Discouraged NOPs are allowed if not executed"], -["0", "IF 0xba ELSE 1 ENDIF", "P2SH,STRICTENC", "OK", "opcodes above NOP10 invalid if executed"], -["0", "IF 0xbb ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], -["0", "IF 0xbc ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], -["0", "IF 0xbd ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], +["0", "IF 0xbd ELSE 1 ENDIF", "P2SH,STRICTENC", "OK", "opcodes above NOP13 invalid if executed"], ["0", "IF 0xbe ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], ["0", "IF 0xbf ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], ["0", "IF 0xc0 ELSE 1 ENDIF", "P2SH,STRICTENC", "OK"], @@ -878,10 +875,7 @@ "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS", "Discouraged NOP10 in redeemScript"], ["0x50","1", "P2SH,STRICTENC", "BAD_OPCODE", "opcode 0x50 is reserved"], -["1", "IF 0xba ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE", "opcodes above NOP10 invalid if executed"], -["1", "IF 0xbb ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xbc ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], -["1", "IF 0xbd ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], +["1", "IF 0xbd ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE", "opcodes above NOP13 invalid if executed"], ["1", "IF 0xbe ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], ["1", "IF 0xbf ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], ["1", "IF 0xc0 ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"], @@ -1001,7 +995,6 @@ ["1","RESERVED", "P2SH,STRICTENC", "BAD_OPCODE", "OP_RESERVED is reserved"], ["1","RESERVED1", "P2SH,STRICTENC", "BAD_OPCODE", "OP_RESERVED1 is reserved"], ["1","RESERVED2", "P2SH,STRICTENC", "BAD_OPCODE", "OP_RESERVED2 is reserved"], -["1","0xba", "P2SH,STRICTENC", "BAD_OPCODE", "0xba == OP_NOP10 + 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"], diff --git a/src/validation.cpp b/src/validation.cpp --- a/src/validation.cpp +++ b/src/validation.cpp @@ -1892,6 +1892,11 @@ flags |= SCRIPT_VERIFY_NULLFAIL; } + if (IsMonolithEnabled(config, pindex->pprev)) { + // When the May 15, 2018 HF is enabled, activate new opcodes. + flags |= SCRIPT_ENABLE_OPCODES0; + } + return flags; }