Changeset View
Changeset View
Standalone View
Standalone View
src/test/script_tests.cpp
Show First 20 Lines • Show All 2,074 Lines • ▼ Show 20 Lines | tests.push_back( | ||||
TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG, | TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG, | ||||
"Schnorr P2PK with cheater forkID bit", | "Schnorr P2PK with cheater forkID bit", | ||||
SCRIPT_ENABLE_SCHNORR | SCRIPT_VERIFY_STRICTENC | | SCRIPT_ENABLE_SCHNORR | SCRIPT_VERIFY_STRICTENC | | ||||
SCRIPT_ENABLE_SIGHASH_FORKID) | SCRIPT_ENABLE_SIGHASH_FORKID) | ||||
.PushSigSchnorr(keys.key1) | .PushSigSchnorr(keys.key1) | ||||
.EditPush(64, "01", "41") | .EditPush(64, "01", "41") | ||||
.ScriptError(SCRIPT_ERR_EVAL_FALSE)); | .ScriptError(SCRIPT_ERR_EVAL_FALSE)); | ||||
// Tests SCRIPT_ALLOW_SEGWIT_RECOVERY | // Tests Segwit Recovery transactions and SCRIPT_DISALLOW_SEGWIT_RECOVERY | ||||
const uint32_t allowSegwitRecoveryFlags = SCRIPT_VERIFY_CLEANSTACK | | const uint32_t allowSegwitRecoveryFlags = | ||||
SCRIPT_VERIFY_P2SH | | SCRIPT_VERIFY_CLEANSTACK | SCRIPT_VERIFY_P2SH; | ||||
SCRIPT_ALLOW_SEGWIT_RECOVERY; | |||||
tests.push_back( | tests.push_back( | ||||
TestBuilder(CScript() << OP_0 << ToByteVector(keys.pubkey0.GetID()), | TestBuilder(CScript() << OP_0 << ToByteVector(keys.pubkey0.GetID()), | ||||
"v0 P2SH-P2WPKH but no SCRIPT_ALLOW_SEGWIT_RECOVERY", | "v0 P2SH-P2WPKH with SCRIPT_DISALLOW_SEGWIT_RECOVERY", | ||||
SCRIPT_VERIFY_CLEANSTACK | SCRIPT_VERIFY_P2SH, true) | SCRIPT_VERIFY_CLEANSTACK | SCRIPT_VERIFY_P2SH | | ||||
SCRIPT_DISALLOW_SEGWIT_RECOVERY, | |||||
true) | |||||
.PushRedeem() | .PushRedeem() | ||||
.ScriptError(SCRIPT_ERR_CLEANSTACK)); | .ScriptError(SCRIPT_ERR_CLEANSTACK)); | ||||
tests.push_back( | tests.push_back( | ||||
TestBuilder(CScript() << OP_0 << ToByteVector(keys.pubkey0.GetID()), | TestBuilder(CScript() << OP_0 << ToByteVector(keys.pubkey0.GetID()), | ||||
"v0 P2SH-P2WPKH with SCRIPT_ALLOW_SEGWIT_RECOVERY", | "Valid Segwit Recovery with v0 P2SH-P2WPKH", | ||||
allowSegwitRecoveryFlags, true) | allowSegwitRecoveryFlags, true) | ||||
.PushRedeem()); | .PushRedeem()); | ||||
tests.push_back( | tests.push_back( | ||||
TestBuilder(CScript() << OP_0 << ToByteVector(keys.pubkey0.GetID()), | TestBuilder(CScript() << OP_0 << ToByteVector(keys.pubkey0.GetID()), | ||||
"v0 P2SH-P2WPKH with extra stack item and " | "v0 P2SH-P2WPKH Segwit Recovery with extra stack item", | ||||
"SCRIPT_ALLOW_SEGWIT_RECOVERY", | |||||
allowSegwitRecoveryFlags, true) | allowSegwitRecoveryFlags, true) | ||||
.Num(0) | .Num(0) | ||||
.PushRedeem() | .PushRedeem() | ||||
.ScriptError(SCRIPT_ERR_CLEANSTACK)); | .ScriptError(SCRIPT_ERR_CLEANSTACK)); | ||||
uint256 dummy256(std::vector<uint8_t>( | uint256 dummy256(std::vector<uint8_t>( | ||||
{90, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, | {90, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, | ||||
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31})); | 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31})); | ||||
tests.push_back( | tests.push_back( | ||||
TestBuilder(CScript() << OP_0 << ToByteVector(dummy256), | TestBuilder(CScript() << OP_0 << ToByteVector(dummy256), | ||||
"v0 P2SH-P2WSH but no SCRIPT_ALLOW_SEGWIT_RECOVERY", | "v0 P2SH-P2WSH with SCRIPT_DISALLOW_SEGWIT_RECOVERY", | ||||
SCRIPT_VERIFY_CLEANSTACK | SCRIPT_VERIFY_P2SH, true) | SCRIPT_VERIFY_CLEANSTACK | SCRIPT_VERIFY_P2SH | | ||||
SCRIPT_DISALLOW_SEGWIT_RECOVERY, | |||||
true) | |||||
.PushRedeem() | .PushRedeem() | ||||
.ScriptError(SCRIPT_ERR_CLEANSTACK)); | .ScriptError(SCRIPT_ERR_CLEANSTACK)); | ||||
tests.push_back( | tests.push_back(TestBuilder(CScript() << OP_0 << ToByteVector(dummy256), | ||||
TestBuilder(CScript() << OP_0 << ToByteVector(dummy256), | "Valid Segwit Recovery with v0 P2SH-P2WSH", | ||||
"v0 P2SH-P2WSH with SCRIPT_ALLOW_SEGWIT_RECOVERY", | |||||
allowSegwitRecoveryFlags, true) | allowSegwitRecoveryFlags, true) | ||||
.PushRedeem()); | .PushRedeem()); | ||||
tests.push_back(TestBuilder(CScript() << OP_0 << ToByteVector(dummy256), | tests.push_back( | ||||
"v0 P2SH-P2WSH with extra stack item and " | TestBuilder(CScript() << OP_0 << ToByteVector(dummy256), | ||||
"SCRIPT_ALLOW_SEGWIT_RECOVERY", | "v0 P2SH-P2WSH Segwit Recovery with extra stack item", | ||||
allowSegwitRecoveryFlags, true) | allowSegwitRecoveryFlags, true) | ||||
.Num(0) | .Num(0) | ||||
.PushRedeem() | .PushRedeem() | ||||
.ScriptError(SCRIPT_ERR_CLEANSTACK)); | .ScriptError(SCRIPT_ERR_CLEANSTACK)); | ||||
// Tests the limits of IsWitnessProgram along with | // Tests the limits of IsWitnessProgram without | ||||
// SCRIPT_ALLOW_SEGWIT_RECOVERY | // SCRIPT_DISALLOW_SEGWIT_RECOVERY. | ||||
std::vector<uint8_t> shortprogram({90, 1}); | std::vector<uint8_t> shortprogram({90, 1}); | ||||
tests.push_back( | tests.push_back( | ||||
TestBuilder(CScript() << OP_0 | TestBuilder(CScript() << OP_0 | ||||
<< std::vector<uint8_t>(shortprogram.begin(), | << std::vector<uint8_t>(shortprogram.begin(), | ||||
shortprogram.end() - 1), | shortprogram.end() - 1), | ||||
"Invalid witness program (too short) with " | "Segwit Recovery with invalid witness program (too short)", | ||||
"SCRIPT_ALLOW_SEGWIT_RECOVERY", | |||||
allowSegwitRecoveryFlags, true) | allowSegwitRecoveryFlags, true) | ||||
.PushRedeem() | .PushRedeem() | ||||
.ScriptError(SCRIPT_ERR_CLEANSTACK)); | .ScriptError(SCRIPT_ERR_CLEANSTACK)); | ||||
tests.push_back( | tests.push_back( | ||||
TestBuilder(CScript() << OP_0 << shortprogram, | TestBuilder( | ||||
"Valid witness program (min allowed length) with " | CScript() << OP_0 << shortprogram, | ||||
"SCRIPT_ALLOW_SEGWIT_RECOVERY", | "Segwit Recovery with valid witness program (min allowed length)", | ||||
allowSegwitRecoveryFlags, true) | allowSegwitRecoveryFlags, true) | ||||
.PushRedeem()); | .PushRedeem()); | ||||
std::vector<uint8_t> longprogram( | std::vector<uint8_t> longprogram( | ||||
{90, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, | {90, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, | ||||
14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, | 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, | ||||
28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40}); | 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40}); | ||||
tests.push_back( | tests.push_back( | ||||
TestBuilder(CScript() << OP_0 | TestBuilder( | ||||
CScript() << OP_0 | |||||
<< std::vector<uint8_t>(longprogram.begin(), | << std::vector<uint8_t>(longprogram.begin(), | ||||
longprogram.end() - 1), | longprogram.end() - 1), | ||||
"Valid witness program (max allowed length) with " | "Segwit Recovery with valid witness program (max allowed length)", | ||||
"SCRIPT_ALLOW_SEGWIT_RECOVERY", | |||||
allowSegwitRecoveryFlags, true) | allowSegwitRecoveryFlags, true) | ||||
.PushRedeem()); | .PushRedeem()); | ||||
tests.push_back(TestBuilder(CScript() << OP_0 << longprogram, | tests.push_back( | ||||
"Invalid witness program (too long) with " | TestBuilder(CScript() << OP_0 << longprogram, | ||||
"SCRIPT_ALLOW_SEGWIT_RECOVERY", | "Segwit Recovery with invalid witness program (too long)", | ||||
allowSegwitRecoveryFlags, true) | allowSegwitRecoveryFlags, true) | ||||
.PushRedeem() | .PushRedeem() | ||||
.ScriptError(SCRIPT_ERR_CLEANSTACK)); | .ScriptError(SCRIPT_ERR_CLEANSTACK)); | ||||
tests.push_back( | tests.push_back( | ||||
TestBuilder(CScript() << OP_16 << ToByteVector(dummy256), | TestBuilder( | ||||
"Valid witness program (max allowed version) with " | CScript() << OP_16 << ToByteVector(dummy256), | ||||
"SCRIPT_ALLOW_SEGWIT_RECOVERY", | "Segwit Recovery with valid witness program (max allowed version)", | ||||
allowSegwitRecoveryFlags, true) | allowSegwitRecoveryFlags, true) | ||||
.PushRedeem()); | .PushRedeem()); | ||||
tests.push_back( | tests.push_back( | ||||
TestBuilder(CScript() << OP_1NEGATE << ToByteVector(dummy256), | TestBuilder( | ||||
"Invalid witness program (invalid version -1) with " | CScript() << OP_1NEGATE << ToByteVector(dummy256), | ||||
"SCRIPT_ALLOW_SEGWIT_RECOVERY", | "Segwit Recovery with invalid witness program (invalid version -1)", | ||||
allowSegwitRecoveryFlags, true) | allowSegwitRecoveryFlags, true) | ||||
.PushRedeem() | .PushRedeem() | ||||
.ScriptError(SCRIPT_ERR_CLEANSTACK)); | .ScriptError(SCRIPT_ERR_CLEANSTACK)); | ||||
tests.push_back( | tests.push_back( | ||||
TestBuilder(CScript() << 17 << ToByteVector(dummy256), | TestBuilder( | ||||
"Invalid witness program (invalid version 17) with " | CScript() << 17 << ToByteVector(dummy256), | ||||
"SCRIPT_ALLOW_SEGWIT_RECOVERY", | "Segwit Recovery with invalid witness program (invalid version 17)", | ||||
allowSegwitRecoveryFlags, true) | allowSegwitRecoveryFlags, true) | ||||
.PushRedeem() | .PushRedeem() | ||||
.ScriptError(SCRIPT_ERR_CLEANSTACK)); | .ScriptError(SCRIPT_ERR_CLEANSTACK)); | ||||
tests.push_back( | tests.push_back( | ||||
TestBuilder(CScript() << OP_0 << ToByteVector(dummy256) << OP_1, | TestBuilder(CScript() << OP_0 << ToByteVector(dummy256) << OP_1, | ||||
"Invalid witness program (more than 2 stack " | "Segwit Recovery with invalid witness program (more than 2 " | ||||
"items) with SCRIPT_ALLOW_SEGWIT_RECOVERY", | "stack items)", | ||||
allowSegwitRecoveryFlags, true) | allowSegwitRecoveryFlags, true) | ||||
.PushRedeem() | .PushRedeem() | ||||
.ScriptError(SCRIPT_ERR_CLEANSTACK)); | .ScriptError(SCRIPT_ERR_CLEANSTACK)); | ||||
tests.push_back( | tests.push_back( | ||||
TestBuilder(CScript() << OP_0 << std::vector<uint8_t>({0, 0}), | TestBuilder(CScript() << OP_0 << std::vector<uint8_t>({0, 0}), | ||||
"Valid segwit recovery, in spite of false value being left " | "Valid segwit recovery, in spite of false value being left " | ||||
"on stack (0)", | "on stack (0)", | ||||
allowSegwitRecoveryFlags, true) | allowSegwitRecoveryFlags, true) | ||||
.PushRedeem()); | .PushRedeem()); | ||||
tests.push_back( | tests.push_back( | ||||
TestBuilder(CScript() << OP_0 << std::vector<uint8_t>({0, 0x80}), | TestBuilder(CScript() << OP_0 << std::vector<uint8_t>({0, 0x80}), | ||||
"Valid segwit recovery, in spite of false value being left " | "Valid segwit recovery, in spite of false value being left " | ||||
"on stack (minus 0)", | "on stack (minus 0)", | ||||
allowSegwitRecoveryFlags, true) | allowSegwitRecoveryFlags, true) | ||||
.PushRedeem()); | .PushRedeem()); | ||||
tests.push_back( | tests.push_back( | ||||
TestBuilder(CScript() << OP_0 << std::vector<uint8_t>({0, 0}), | |||||
"Otherwise valid segwit recovery, in spite of false value " | |||||
"being left " | |||||
"on stack (0), but with SCRIPT_DISALLOW_SEGWIT_RECOVERY", | |||||
allowSegwitRecoveryFlags | SCRIPT_DISALLOW_SEGWIT_RECOVERY, | |||||
true) | |||||
.PushRedeem() | |||||
.ScriptError(SCRIPT_ERR_EVAL_FALSE)); | |||||
tests.push_back( | |||||
TestBuilder( | TestBuilder( | ||||
CScript() << OP_RESERVED << ToByteVector(dummy256), | CScript() << OP_0 << std::vector<uint8_t>({0, 0x80}), | ||||
"Invalid witness program (OP_RESERVED in version field) with " | "Otherwise valid segwit recovery, in spite of false value being " | ||||
"SCRIPT_ALLOW_SEGWIT_RECOVERY", | "left " | ||||
"on stack (minus 0), but with SCRIPT_DISALLOW_SEGWIT_RECOVERY", | |||||
allowSegwitRecoveryFlags | SCRIPT_DISALLOW_SEGWIT_RECOVERY, true) | |||||
.PushRedeem() | |||||
.ScriptError(SCRIPT_ERR_EVAL_FALSE)); | |||||
tests.push_back( | |||||
TestBuilder(CScript() << OP_RESERVED << ToByteVector(dummy256), | |||||
"Segwit Recovery with invalid witness program (OP_RESERVED " | |||||
"in version field)", | |||||
allowSegwitRecoveryFlags, true) | allowSegwitRecoveryFlags, true) | ||||
.PushRedeem() | .PushRedeem() | ||||
.ScriptError(SCRIPT_ERR_BAD_OPCODE)); | .ScriptError(SCRIPT_ERR_BAD_OPCODE)); | ||||
const uint8_t nonmin_push_00[] = {1, 0}; | const uint8_t nonmin_push_00[] = {1, 0}; | ||||
tests.push_back( | tests.push_back( | ||||
TestBuilder( | TestBuilder( | ||||
CScript(&nonmin_push_00[0], &nonmin_push_00[sizeof(nonmin_push_00)]) | CScript(&nonmin_push_00[0], &nonmin_push_00[sizeof(nonmin_push_00)]) | ||||
<< ToByteVector(keys.pubkey0.GetID()), | << ToByteVector(keys.pubkey0.GetID()), | ||||
"Invalid witness program (non-minimal push in version field) with " | "Segwit Recovery with invalid witness program (non-minimal push in " | ||||
"SCRIPT_ALLOW_SEGWIT_RECOVERY", | "version field)", | ||||
allowSegwitRecoveryFlags, true) | allowSegwitRecoveryFlags, true) | ||||
.PushRedeem() | .PushRedeem() | ||||
.ScriptError(SCRIPT_ERR_CLEANSTACK)); | .ScriptError(SCRIPT_ERR_CLEANSTACK)); | ||||
const uint8_t nonmin_push_45aa[] = {OP_PUSHDATA1, 2, 0x45, 0xaa}; | const uint8_t nonmin_push_45aa[] = {OP_PUSHDATA1, 2, 0x45, 0xaa}; | ||||
tests.push_back( | tests.push_back( | ||||
TestBuilder((CScript() << OP_0) + | TestBuilder((CScript() << OP_0) + | ||||
CScript(&nonmin_push_45aa[0], | CScript(&nonmin_push_45aa[0], | ||||
&nonmin_push_45aa[sizeof(nonmin_push_45aa)]), | &nonmin_push_45aa[sizeof(nonmin_push_45aa)]), | ||||
"Invalid witness program (non-minimal push in program " | "Segwit Recovery with invalid witness program (non-minimal " | ||||
"field) with SCRIPT_ALLOW_SEGWIT_RECOVERY", | "push in program field)", | ||||
allowSegwitRecoveryFlags, true) | allowSegwitRecoveryFlags, true) | ||||
.PushRedeem() | .PushRedeem() | ||||
.ScriptError(SCRIPT_ERR_CLEANSTACK)); | .ScriptError(SCRIPT_ERR_CLEANSTACK)); | ||||
tests.push_back( | tests.push_back( | ||||
TestBuilder(CScript() << OP_0 << ToByteVector(dummy256), | TestBuilder(CScript() << OP_0 << ToByteVector(dummy256), | ||||
"v0 P2SH-P2WPKH whose redeem script hash does not match " | "v0 P2SH-P2WPKH Segwit Recovery whose redeem script hash " | ||||
"P2SH output and SCRIPT_ALLOW_SEGWIT_RECOVERY", | "does not match " | ||||
"P2SH output", | |||||
allowSegwitRecoveryFlags, true) | allowSegwitRecoveryFlags, true) | ||||
.Push(CScript() << OP_0 << ToByteVector(keys.pubkey0.GetID())) | .Push(CScript() << OP_0 << ToByteVector(keys.pubkey0.GetID())) | ||||
.ScriptError(SCRIPT_ERR_EVAL_FALSE)); | .ScriptError(SCRIPT_ERR_EVAL_FALSE)); | ||||
tests.push_back( | tests.push_back( | ||||
TestBuilder(CScript() << OP_1, | TestBuilder(CScript() << OP_1, | ||||
"v0 P2SH-P2WPKH spending a non-P2SH output and " | "v0 P2SH-P2WPKH Segwit Recovery spending a non-P2SH output", | ||||
"SCRIPT_ALLOW_SEGWIT_RECOVERY", | |||||
allowSegwitRecoveryFlags) | allowSegwitRecoveryFlags) | ||||
.Push(CScript() << OP_0 << ToByteVector(keys.pubkey0.GetID())) | .Push(CScript() << OP_0 << ToByteVector(keys.pubkey0.GetID())) | ||||
.ScriptError(SCRIPT_ERR_CLEANSTACK)); | .ScriptError(SCRIPT_ERR_CLEANSTACK)); | ||||
std::set<std::string> tests_set; | std::set<std::string> tests_set; | ||||
{ | { | ||||
UniValue json_tests = read_json(std::string( | UniValue json_tests = read_json(std::string( | ||||
▲ Show 20 Lines • Show All 797 Lines • Show Last 20 Lines |