From ce776c77f76570dbe62bb71baa27dee855d6e1dc Mon Sep 17 00:00:00 2001 From: Jeremy Rubin Date: Wed, 16 Oct 2019 14:36:34 -0700 Subject: [PATCH 01/10] Add StandardTemplateHash definition --- src/script/interpreter.cpp | 55 ++++++++++++++++++++++++++++++++++++++ src/script/interpreter.h | 7 +++++ 2 files changed, 62 insertions(+) diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index a35306b6935..40397a67aba 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -1377,6 +1377,18 @@ uint256 GetSpentAmountsSHA256(const std::vector& outputs_spent) HashWriter ss{}; for (const auto& txout : outputs_spent) { ss << txout.nValue; + + } + return ss.GetSHA256(); +} + +/** Compute the (single) SHA256 of the concatenation of all scriptSigs in a tx. */ +template +uint256 GetScriptSigsSHA256(const T& txTo) +{ + HashWriter ss{}; + for (const auto& in : txTo.vin) { + ss << in.scriptSig; } return ss.GetSHA256(); } @@ -1391,9 +1403,52 @@ uint256 GetSpentScriptsSHA256(const std::vector& outputs_spent) return ss.GetSHA256(); } +/* Not Exported, just convenience */ +template +uint256 GetDefaultCheckTemplateVerifyHashWithScript(const TxType& tx, const uint256& outputs_hash, const uint256& sequences_hash, + const uint256& scriptSig_hash, const uint32_t input_index) { + auto h = HashWriter{} + << tx.nVersion + << tx.nLockTime + << scriptSig_hash + << uint32_t(tx.vin.size()) + << sequences_hash + << uint32_t(tx.vout.size()) + << outputs_hash + << input_index; + return h.GetSHA256(); +} + +template +uint256 GetDefaultCheckTemplateVerifyHashEmptyScript(const TxType& tx, const uint256& outputs_hash, const uint256& sequences_hash, + const uint32_t input_index) { + auto h = HashWriter{} + << tx.nVersion + << tx.nLockTime + << uint32_t(tx.vin.size()) + << sequences_hash + << uint32_t(tx.vout.size()) + << outputs_hash + << input_index; + return h.GetSHA256(); +} } // namespace +template +uint256 GetDefaultCheckTemplateVerifyHash(const TxType& tx, uint32_t input_index) { + return GetDefaultCheckTemplateVerifyHash(tx, GetOutputsSHA256(tx), GetSequencesSHA256(tx), input_index); +} + +template +uint256 GetDefaultCheckTemplateVerifyHash(const TxType& tx, const uint256& outputs_hash, const uint256& sequences_hash, + const uint32_t input_index) { + bool skip_scriptSigs = std::find_if(tx.vin.begin(), tx.vin.end(), + [](const CTxIn& c) { return c.scriptSig != CScript(); }) == tx.vin.end(); + return skip_scriptSigs ? GetDefaultCheckTemplateVerifyHashEmptyScript(tx, outputs_hash, sequences_hash, input_index) : + GetDefaultCheckTemplateVerifyHashWithScript(tx, outputs_hash, sequences_hash, GetScriptSigsSHA256(tx), input_index); +} + template void PrecomputedTransactionData::Init(const T& txTo, std::vector&& spent_outputs, bool force) { diff --git a/src/script/interpreter.h b/src/script/interpreter.h index e2fb1998f0b..ffad73a7e42 100644 --- a/src/script/interpreter.h +++ b/src/script/interpreter.h @@ -187,6 +187,13 @@ struct PrecomputedTransactionData explicit PrecomputedTransactionData(const T& tx); }; +/* Standard Template Hash Declarations */ +template +uint256 GetDefaultCheckTemplateVerifyHash(const TxType& tx, uint32_t input_index); +template +uint256 GetDefaultCheckTemplateVerifyHash(const TxType& tx, const uint256& outputs_hash, const uint256& sequences_hash, + const uint32_t input_index); + enum class SigVersion { BASE = 0, //!< Bare scripts and BIP16 P2SH-wrapped redeemscripts From ef989f36ea403b695a0898d7f636413ea104ecd2 Mon Sep 17 00:00:00 2001 From: Jeremy Rubin Date: Wed, 16 Oct 2019 14:37:18 -0700 Subject: [PATCH 02/10] Add SignatureChecker method for checking DefaultCheckTemplateVerifyHash. --- src/script/interpreter.cpp | 26 ++++++++++++++++++-------- src/script/interpreter.h | 6 ++++++ 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index 40397a67aba..dd7e25b3c11 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -1405,10 +1405,11 @@ uint256 GetSpentScriptsSHA256(const std::vector& outputs_spent) /* Not Exported, just convenience */ template -uint256 GetDefaultCheckTemplateVerifyHashWithScript(const TxType& tx, const uint256& outputs_hash, const uint256& sequences_hash, - const uint256& scriptSig_hash, const uint32_t input_index) { +uint256 GetDefaultCheckTemplateVerifyHashWithScript( + const TxType& tx, const uint256& outputs_hash, const uint256& sequences_hash, + const uint256& scriptSig_hash, const uint32_t input_index) { auto h = HashWriter{} - << tx.nVersion + << tx.version << tx.nLockTime << scriptSig_hash << uint32_t(tx.vin.size()) @@ -1420,10 +1421,10 @@ uint256 GetDefaultCheckTemplateVerifyHashWithScript(const TxType& tx, const uint } template -uint256 GetDefaultCheckTemplateVerifyHashEmptyScript(const TxType& tx, const uint256& outputs_hash, const uint256& sequences_hash, - const uint32_t input_index) { +uint256 GetDefaultCheckTemplateVerifyHashEmptyScript( + const TxType& tx, const uint256& outputs_hash, const uint256& sequences_hash, const uint32_t input_index) { auto h = HashWriter{} - << tx.nVersion + << tx.version << tx.nLockTime << uint32_t(tx.vin.size()) << sequences_hash @@ -1441,8 +1442,8 @@ uint256 GetDefaultCheckTemplateVerifyHash(const TxType& tx, uint32_t input_index } template -uint256 GetDefaultCheckTemplateVerifyHash(const TxType& tx, const uint256& outputs_hash, const uint256& sequences_hash, - const uint32_t input_index) { +uint256 GetDefaultCheckTemplateVerifyHash( + const TxType& tx, const uint256& outputs_hash, const uint256& sequences_hash, const uint32_t input_index) { bool skip_scriptSigs = std::find_if(tx.vin.begin(), tx.vin.end(), [](const CTxIn& c) { return c.scriptSig != CScript(); }) == tx.vin.end(); return skip_scriptSigs ? GetDefaultCheckTemplateVerifyHashEmptyScript(tx, outputs_hash, sequences_hash, input_index) : @@ -1836,6 +1837,15 @@ bool GenericTransactionSignatureChecker::CheckSequence(const CScriptNum& nSeq return true; } +template +bool GenericTransactionSignatureChecker::CheckDefaultCheckTemplateVerifyHash(const std::vector& hash) const +{ + // Should already be checked before calling... + assert(hash.size() == 32); + assert(txTo != nullptr); + uint256 hash_tmpl = GetDefaultCheckTemplateVerifyHash(*txTo, nIn); + return std::equal(hash_tmpl.begin(), hash_tmpl.end(), hash.data()); +} // explicit instantiation template class GenericTransactionSignatureChecker; template class GenericTransactionSignatureChecker; diff --git a/src/script/interpreter.h b/src/script/interpreter.h index ffad73a7e42..a0a2eaecf3f 100644 --- a/src/script/interpreter.h +++ b/src/script/interpreter.h @@ -272,6 +272,11 @@ public: return false; } + virtual bool CheckDefaultCheckTemplateVerifyHash(const std::vector& hash) const + { + return false; + } + virtual ~BaseSignatureChecker() = default; }; @@ -308,6 +313,7 @@ public: bool CheckSchnorrSignature(Span sig, Span pubkey, SigVersion sigversion, ScriptExecutionData& execdata, ScriptError* serror = nullptr) const override; bool CheckLockTime(const CScriptNum& nLockTime) const override; bool CheckSequence(const CScriptNum& nSequence) const override; + bool CheckDefaultCheckTemplateVerifyHash(const std::vector& hash) const override; }; using TransactionSignatureChecker = GenericTransactionSignatureChecker; From 20cf7fe381493463d141f0b97c6cccee542e20d1 Mon Sep 17 00:00:00 2001 From: Jeremy Rubin Date: Wed, 16 Oct 2019 14:48:23 -0700 Subject: [PATCH 03/10] Add OP_CHECKTEMPLATEVERIFY Opcode as OP_NOP4 [TESTS] modify script_tests.json to enable OP_NOP4 as OP_CHECKTEMPLATEVERIFY --- src/policy/policy.h | 1 + src/script/interpreter.cpp | 49 +++++++++++++++++++++++++++++---- src/script/interpreter.h | 13 +++++++-- src/script/script.h | 3 +- src/script/script_error.cpp | 2 ++ src/script/script_error.h | 1 + src/test/data/script_tests.json | 1 - 7 files changed, 61 insertions(+), 9 deletions(-) diff --git a/src/policy/policy.h b/src/policy/policy.h index 2151ec13dd0..7f6bf29f74d 100644 --- a/src/policy/policy.h +++ b/src/policy/policy.h @@ -126,6 +126,7 @@ static constexpr unsigned int STANDARD_SCRIPT_VERIFY_FLAGS{MANDATORY_SCRIPT_VERI SCRIPT_VERIFY_DISCOURAGE_OP_SUCCESS | SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_PUBKEYTYPE}; + /** For convenience, standard but not mandatory verify flags. */ static constexpr unsigned int STANDARD_NOT_MANDATORY_VERIFY_FLAGS{STANDARD_SCRIPT_VERIFY_FLAGS & ~MANDATORY_SCRIPT_VERIFY_FLAGS}; diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index dd7e25b3c11..3cf744b274d 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -591,7 +591,42 @@ bool EvalScript(std::vector >& stack, const CScript& break; } - case OP_NOP1: case OP_NOP4: case OP_NOP5: + case OP_CHECKTEMPLATEVERIFY: + { + if (flags & SCRIPT_VERIFY_DISCOURAGE_CHECKTEMPLATEVERIFY) { + return set_error(serror, SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS); + } + + // if flags not enabled; treat as a NOP4 + if (!(flags & SCRIPT_VERIFY_CHECKTEMPLATEVERIFY)) { + break; + } + + if (stack.size() < 1) { + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + } + + // If the argument was not 32 bytes, treat as OP_NOP4: + switch (stack.back().size()) { + case 32: + { + const Span hash{stack.back()}; + if (!checker.CheckDefaultCheckTemplateVerifyHash(hash)) { + return set_error(serror, SCRIPT_ERR_TEMPLATE_MISMATCH); + } + break; + } + default: + // future upgrade can add semantics for this opcode with different length args + // so discourage use when applicable + if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_CHECKTEMPLATEVERIFY) { + return set_error(serror, SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS); + } + } + } + break; + + case OP_NOP1: case OP_NOP5: case OP_NOP6: case OP_NOP7: case OP_NOP8: case OP_NOP9: case OP_NOP10: { if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) @@ -1441,12 +1476,16 @@ uint256 GetDefaultCheckTemplateVerifyHash(const TxType& tx, uint32_t input_index return GetDefaultCheckTemplateVerifyHash(tx, GetOutputsSHA256(tx), GetSequencesSHA256(tx), input_index); } +template +static bool NoScriptSigs(const TxType& tx) +{ + return std::all_of(tx.vin.begin(), tx.vin.end(), [](const CTxIn& c) { return c.scriptSig.empty(); }); +} + template uint256 GetDefaultCheckTemplateVerifyHash( const TxType& tx, const uint256& outputs_hash, const uint256& sequences_hash, const uint32_t input_index) { - bool skip_scriptSigs = std::find_if(tx.vin.begin(), tx.vin.end(), - [](const CTxIn& c) { return c.scriptSig != CScript(); }) == tx.vin.end(); - return skip_scriptSigs ? GetDefaultCheckTemplateVerifyHashEmptyScript(tx, outputs_hash, sequences_hash, input_index) : + return NoScriptSigs(tx) ? GetDefaultCheckTemplateVerifyHashEmptyScript(tx, outputs_hash, sequences_hash, input_index) : GetDefaultCheckTemplateVerifyHashWithScript(tx, outputs_hash, sequences_hash, GetScriptSigsSHA256(tx), input_index); } @@ -1838,7 +1877,7 @@ bool GenericTransactionSignatureChecker::CheckSequence(const CScriptNum& nSeq } template -bool GenericTransactionSignatureChecker::CheckDefaultCheckTemplateVerifyHash(const std::vector& hash) const +bool GenericTransactionSignatureChecker::CheckDefaultCheckTemplateVerifyHash(const Span& hash) const { // Should already be checked before calling... assert(hash.size() == 32); diff --git a/src/script/interpreter.h b/src/script/interpreter.h index a0a2eaecf3f..7e24634db3b 100644 --- a/src/script/interpreter.h +++ b/src/script/interpreter.h @@ -143,6 +143,15 @@ enum : uint32_t { // Making unknown public key versions (in BIP 342 scripts) non-standard SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_PUBKEYTYPE = (1U << 20), + // CHECKTEMPLATEVERIFY validation (BIP-119) + SCRIPT_VERIFY_CHECKTEMPLATEVERIFY = (1U << 21), + + // discourage upgradable OP_CHECKTEMPLATEVERIFY hashes + SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_CHECKTEMPLATEVERIFY = (1U << 22), + + // discourage OP_CHECKTEMPLATEVERIFY + SCRIPT_VERIFY_DISCOURAGE_CHECKTEMPLATEVERIFY = (1U << 23), + // Constants to point to the highest flag in use. Add new flags above this line. // SCRIPT_VERIFY_END_MARKER @@ -272,7 +281,7 @@ public: return false; } - virtual bool CheckDefaultCheckTemplateVerifyHash(const std::vector& hash) const + virtual bool CheckDefaultCheckTemplateVerifyHash(const Span& hash) const { return false; } @@ -313,7 +322,7 @@ public: bool CheckSchnorrSignature(Span sig, Span pubkey, SigVersion sigversion, ScriptExecutionData& execdata, ScriptError* serror = nullptr) const override; bool CheckLockTime(const CScriptNum& nLockTime) const override; bool CheckSequence(const CScriptNum& nSequence) const override; - bool CheckDefaultCheckTemplateVerifyHash(const std::vector& hash) const override; + bool CheckDefaultCheckTemplateVerifyHash(const Span& hash) const override; }; using TransactionSignatureChecker = GenericTransactionSignatureChecker; diff --git a/src/script/script.h b/src/script/script.h index f4579849803..5ac07f55296 100644 --- a/src/script/script.h +++ b/src/script/script.h @@ -198,7 +198,8 @@ enum opcodetype OP_NOP2 = OP_CHECKLOCKTIMEVERIFY, OP_CHECKSEQUENCEVERIFY = 0xb2, OP_NOP3 = OP_CHECKSEQUENCEVERIFY, - OP_NOP4 = 0xb3, + OP_CHECKTEMPLATEVERIFY = 0xb3, + OP_NOP4 = OP_CHECKTEMPLATEVERIFY, OP_NOP5 = 0xb4, OP_NOP6 = 0xb5, OP_NOP7 = 0xb6, diff --git a/src/script/script_error.cpp b/src/script/script_error.cpp index fadc04262c3..f33994d0b3b 100644 --- a/src/script/script_error.cpp +++ b/src/script/script_error.cpp @@ -25,6 +25,8 @@ std::string ScriptErrorString(const ScriptError serror) return "Script failed an OP_CHECKSIGVERIFY operation"; case SCRIPT_ERR_NUMEQUALVERIFY: return "Script failed an OP_NUMEQUALVERIFY operation"; + case SCRIPT_ERR_TEMPLATE_MISMATCH: + return "Script failed an OP_CHECKTEMPLATEVERIFY operation"; case SCRIPT_ERR_SCRIPT_SIZE: return "Script is too big"; case SCRIPT_ERR_PUSH_SIZE: diff --git a/src/script/script_error.h b/src/script/script_error.h index 44e68fe0fae..74d7041533d 100644 --- a/src/script/script_error.h +++ b/src/script/script_error.h @@ -29,6 +29,7 @@ typedef enum ScriptError_t SCRIPT_ERR_CHECKMULTISIGVERIFY, SCRIPT_ERR_CHECKSIGVERIFY, SCRIPT_ERR_NUMEQUALVERIFY, + SCRIPT_ERR_TEMPLATE_MISMATCH, /* Logical/Format/Canonical errors */ SCRIPT_ERR_BAD_OPCODE, diff --git a/src/test/data/script_tests.json b/src/test/data/script_tests.json index ad05240369b..63941b2b6a6 100644 --- a/src/test/data/script_tests.json +++ b/src/test/data/script_tests.json @@ -875,7 +875,6 @@ ["Ensure 100% coverage of discouraged NOPS"], ["1", "NOP1", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], -["1", "NOP4", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], ["1", "NOP5", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], ["1", "NOP6", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], ["1", "NOP7", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], From fc2374644af0d93ca9d9e5d6b499a461dc181c7a Mon Sep 17 00:00:00 2001 From: Jeremy Rubin Date: Thu, 2 Sep 2021 16:35:28 -0700 Subject: [PATCH 04/10] Change printing of NOP4 to CheckTemplateVerify (separate commit for ease of bisecting should downstream software expect to parse NOP4 this now fails) --- src/script/script.cpp | 2 +- src/test/data/script_tests.json | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/script/script.cpp b/src/script/script.cpp index d650db9a0d6..4c8fbeeef44 100644 --- a/src/script/script.cpp +++ b/src/script/script.cpp @@ -138,7 +138,7 @@ std::string GetOpName(opcodetype opcode) case OP_NOP1 : return "OP_NOP1"; case OP_CHECKLOCKTIMEVERIFY : return "OP_CHECKLOCKTIMEVERIFY"; case OP_CHECKSEQUENCEVERIFY : return "OP_CHECKSEQUENCEVERIFY"; - case OP_NOP4 : return "OP_NOP4"; + case OP_CHECKTEMPLATEVERIFY : return "OP_CHECKTEMPLATEVERIFY"; case OP_NOP5 : return "OP_NOP5"; case OP_NOP6 : return "OP_NOP6"; case OP_NOP7 : return "OP_NOP7"; diff --git a/src/test/data/script_tests.json b/src/test/data/script_tests.json index 63941b2b6a6..b4b3724d713 100644 --- a/src/test/data/script_tests.json +++ b/src/test/data/script_tests.json @@ -244,8 +244,8 @@ ["'abcdefghijklmnopqrstuvwxyz'", "HASH256 0x4c 0x20 0xca139bc10c2f660da42666f72e89a225936fc60f193c161124a672050c434671 EQUAL", "P2SH,STRICTENC", "OK"], -["1","NOP1 CHECKLOCKTIMEVERIFY CHECKSEQUENCEVERIFY NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 1 EQUAL", "P2SH,STRICTENC", "OK"], -["'NOP_1_to_10' NOP1 CHECKLOCKTIMEVERIFY CHECKSEQUENCEVERIFY NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_10' EQUAL", "P2SH,STRICTENC", "OK"], +["1","NOP1 CHECKLOCKTIMEVERIFY CHECKSEQUENCEVERIFY CHECKTEMPLATEVERIFY NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 1 EQUAL", "P2SH,STRICTENC", "OK"], +["'NOP_1_to_10' NOP1 CHECKLOCKTIMEVERIFY CHECKSEQUENCEVERIFY CHECKTEMPLATEVERIFY NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_10' EQUAL", "P2SH,STRICTENC", "OK"], ["1", "NOP", "P2SH,STRICTENC,DISCOURAGE_UPGRADABLE_NOPS", "OK", "Discourage NOPx flag allows OP_NOP"], @@ -456,7 +456,7 @@ ["NOP", "NOP1 1", "P2SH,STRICTENC", "OK"], ["NOP", "CHECKLOCKTIMEVERIFY 1", "P2SH,STRICTENC", "OK"], ["NOP", "CHECKSEQUENCEVERIFY 1", "P2SH,STRICTENC", "OK"], -["NOP", "NOP4 1", "P2SH,STRICTENC", "OK"], +["NOP", "CHECKTEMPLATEVERIFY 1", "P2SH,STRICTENC", "OK"], ["NOP", "NOP5 1", "P2SH,STRICTENC", "OK"], ["NOP", "NOP6 1", "P2SH,STRICTENC", "OK"], ["NOP", "NOP7 1", "P2SH,STRICTENC", "OK"], @@ -870,8 +870,8 @@ ["2 2 LSHIFT", "8 EQUAL", "P2SH,STRICTENC", "DISABLED_OPCODE", "disabled"], ["2 1 RSHIFT", "1 EQUAL", "P2SH,STRICTENC", "DISABLED_OPCODE", "disabled"], -["1", "NOP1 CHECKLOCKTIMEVERIFY CHECKSEQUENCEVERIFY NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 2 EQUAL", "P2SH,STRICTENC", "EVAL_FALSE"], -["'NOP_1_to_10' NOP1 CHECKLOCKTIMEVERIFY CHECKSEQUENCEVERIFY NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_11' EQUAL", "P2SH,STRICTENC", "EVAL_FALSE"], +["1", "NOP1 CHECKLOCKTIMEVERIFY CHECKSEQUENCEVERIFY CHECKTEMPLATEVERIFY NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 2 EQUAL", "P2SH,STRICTENC", "EVAL_FALSE"], +["'NOP_1_to_10' NOP1 CHECKLOCKTIMEVERIFY CHECKSEQUENCEVERIFY CHECKTEMPLATEVERIFY NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_11' EQUAL", "P2SH,STRICTENC", "EVAL_FALSE"], ["Ensure 100% coverage of discouraged NOPS"], ["1", "NOP1", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], From 43be0ce1c106d0a6e178c43146b9d8db8a4d8d74 Mon Sep 17 00:00:00 2001 From: Jeremy Rubin Date: Wed, 16 Oct 2019 14:56:24 -0700 Subject: [PATCH 05/10] script: precompute the DefaultCheckTemplateVerifyHash Co-authored-by: James O'Beirne --- src/script/interpreter.cpp | 32 +++++++++++++++++++++++--------- src/script/interpreter.h | 23 +++++++++++++++++------ 2 files changed, 40 insertions(+), 15 deletions(-) diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index 3cf744b274d..59a0dcaec04 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -1522,12 +1522,19 @@ void PrecomputedTransactionData::Init(const T& txTo, std::vector&& spent if (uses_bip341_taproot && uses_bip143_segwit) break; // No need to scan further if we already need all. } - if (uses_bip143_segwit || uses_bip341_taproot) { - // Computations shared between both sighash schemes. - m_prevouts_single_hash = GetPrevoutsSHA256(txTo); - m_sequences_single_hash = GetSequencesSHA256(txTo); - m_outputs_single_hash = GetOutputsSHA256(txTo); - } + // Each of these computations is always required for CHECKTEMPLATEVERIFY, and sometimes + // required for any segwit/taproot. + m_prevouts_single_hash = GetPrevoutsSHA256(txTo); + m_sequences_single_hash = GetSequencesSHA256(txTo); + m_outputs_single_hash = GetOutputsSHA256(txTo); + + // Only required for CHECKTEMPLATEVERIFY. + // + // The empty hash is used to signal whether or not we should skip scriptSigs + // when re-computing for different indexes. + m_scriptSigs_single_hash = NoScriptSigs(txTo) ? uint256{} : GetScriptSigsSHA256(txTo); + m_bip119_ctv_ready = true; + if (uses_bip143_segwit) { hashPrevouts = SHA256Uint256(m_prevouts_single_hash); hashSequence = SHA256Uint256(m_sequences_single_hash); @@ -1881,9 +1888,16 @@ bool GenericTransactionSignatureChecker::CheckDefaultCheckTemplateVerifyHash( { // Should already be checked before calling... assert(hash.size() == 32); - assert(txTo != nullptr); - uint256 hash_tmpl = GetDefaultCheckTemplateVerifyHash(*txTo, nIn); - return std::equal(hash_tmpl.begin(), hash_tmpl.end(), hash.data()); + if (txdata && txdata->m_bip119_ctv_ready) { + assert(txTo != nullptr); + uint256 hash_tmpl = txdata->m_scriptSigs_single_hash.IsNull() ? + GetDefaultCheckTemplateVerifyHashEmptyScript(*txTo, txdata->m_outputs_single_hash, txdata->m_sequences_single_hash, nIn) : + GetDefaultCheckTemplateVerifyHashWithScript(*txTo, txdata->m_outputs_single_hash, txdata->m_sequences_single_hash, + txdata->m_scriptSigs_single_hash, nIn); + return std::equal(hash_tmpl.begin(), hash_tmpl.end(), hash.data()); + } else { + return HandleMissingData(m_mdb); + } } // explicit instantiation template class GenericTransactionSignatureChecker; diff --git a/src/script/interpreter.h b/src/script/interpreter.h index 7e24634db3b..51e672275e0 100644 --- a/src/script/interpreter.h +++ b/src/script/interpreter.h @@ -161,6 +161,9 @@ bool CheckSignatureEncoding(const std::vector &vchSig, unsigned i struct PrecomputedTransactionData { + // Order of fields is packed below (uint256 is 32 bytes, vector is 24 bytes + // (3 ptrs), ready flags (1 byte each). + // BIP341 precomputed data. // These are single-SHA256, see https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#cite_note-16. uint256 m_prevouts_single_hash; @@ -168,15 +171,25 @@ struct PrecomputedTransactionData uint256 m_outputs_single_hash; uint256 m_spent_amounts_single_hash; uint256 m_spent_scripts_single_hash; - //! Whether the 5 fields above are initialized. - bool m_bip341_taproot_ready = false; + + // BIP119 precomputed data (single SHA256). + uint256 m_scriptSigs_single_hash; // BIP143 precomputed data (double-SHA256). uint256 hashPrevouts, hashSequence, hashOutputs; - //! Whether the 3 fields above are initialized. + + // BIP341 cached outputs. + std::vector m_spent_outputs; + + //! Whether the bip341 fields above are initialized. + bool m_bip341_taproot_ready = false; + + //! Whether the bip119 fields above are initialized. + bool m_bip119_ctv_ready = false; + + //! Whether the bip143 fields above are initialized. bool m_bip143_segwit_ready = false; - std::vector m_spent_outputs; //! Whether m_spent_outputs is initialized. bool m_spent_outputs_ready = false; @@ -198,8 +211,6 @@ struct PrecomputedTransactionData /* Standard Template Hash Declarations */ template -uint256 GetDefaultCheckTemplateVerifyHash(const TxType& tx, uint32_t input_index); -template uint256 GetDefaultCheckTemplateVerifyHash(const TxType& tx, const uint256& outputs_hash, const uint256& sequences_hash, const uint32_t input_index); From 90ab82e8ffce6a9334e9c591b30114d1a95793a8 Mon Sep 17 00:00:00 2001 From: Jeremy Rubin Date: Wed, 16 Oct 2019 15:04:09 -0700 Subject: [PATCH 06/10] policy: make bare OP_CHECKTEMPLATEVERIFY standard Co-authored-by: James O'Beirne --- src/addresstype.cpp | 1 + src/policy/policy.cpp | 5 +++++ src/policy/policy.h | 5 ++++- src/rpc/rawtransaction.cpp | 4 ++++ src/script/script.cpp | 8 ++++++++ src/script/script.h | 2 ++ src/script/sign.cpp | 1 + src/script/solver.cpp | 5 +++++ src/script/solver.h | 1 + src/test/fuzz/script.cpp | 1 + src/test/transaction_tests.cpp | 3 +++ src/wallet/rpc/backup.cpp | 2 ++ src/wallet/scriptpubkeyman.cpp | 5 +++++ 13 files changed, 42 insertions(+), 1 deletion(-) diff --git a/src/addresstype.cpp b/src/addresstype.cpp index 67e643943d4..66d6c47ff9a 100644 --- a/src/addresstype.cpp +++ b/src/addresstype.cpp @@ -98,6 +98,7 @@ bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet) case TxoutType::MULTISIG: case TxoutType::NULL_DATA: case TxoutType::NONSTANDARD: + case TxoutType::TX_BARE_DEFAULT_CHECKTEMPLATEVERIFY: addressRet = CNoDestination(scriptPubKey); return false; } // no default case, so the compiler can warn about missing cases diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp index ed336928235..1f4a325d6cb 100644 --- a/src/policy/policy.cpp +++ b/src/policy/policy.cpp @@ -214,6 +214,11 @@ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs) if (subscript.GetSigOpCount(true) > MAX_P2SH_SIGOPS) { return false; } + } else if (whichType == TxoutType::TX_BARE_DEFAULT_CHECKTEMPLATEVERIFY) { + // after activation, only allow bare with no scriptsig. + // pre-activation disallowing enforced via discouraged logic in the + // interpreter. + if (tx.vin[i].scriptSig.size() != 0) return false; } } diff --git a/src/policy/policy.h b/src/policy/policy.h index 7f6bf29f74d..800e74c4e7e 100644 --- a/src/policy/policy.h +++ b/src/policy/policy.h @@ -124,7 +124,10 @@ static constexpr unsigned int STANDARD_SCRIPT_VERIFY_FLAGS{MANDATORY_SCRIPT_VERI SCRIPT_VERIFY_CONST_SCRIPTCODE | SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_TAPROOT_VERSION | SCRIPT_VERIFY_DISCOURAGE_OP_SUCCESS | - SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_PUBKEYTYPE}; + SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_PUBKEYTYPE | + SCRIPT_VERIFY_DISCOURAGE_CHECKTEMPLATEVERIFY | + SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_CHECKTEMPLATEVERIFY | + SCRIPT_VERIFY_CHECKTEMPLATEVERIFY}; /** For convenience, standard but not mandatory verify flags. */ diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 421656152cb..309ce717fa7 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -544,6 +544,8 @@ static RPCHelpMan decodescript() case TxoutType::WITNESS_UNKNOWN: case TxoutType::WITNESS_V1_TAPROOT: case TxoutType::ANCHOR: + // don't wrap CTV because P2SH CTV is a hash cycle + case TxoutType::TX_BARE_DEFAULT_CHECKTEMPLATEVERIFY: // Should not be wrapped return false; } // no default case, so the compiler can warn about missing cases @@ -587,6 +589,8 @@ static RPCHelpMan decodescript() case TxoutType::WITNESS_V0_SCRIPTHASH: case TxoutType::WITNESS_V1_TAPROOT: case TxoutType::ANCHOR: + // don't wrap CTV because P2SH CTV is a hash cycle + case TxoutType::TX_BARE_DEFAULT_CHECKTEMPLATEVERIFY: // Should not be wrapped return false; } // no default case, so the compiler can warn about missing cases diff --git a/src/script/script.cpp b/src/script/script.cpp index 4c8fbeeef44..fc77d70a9e9 100644 --- a/src/script/script.cpp +++ b/src/script/script.cpp @@ -221,6 +221,14 @@ bool CScript::IsPayToAnchor(int version, const std::vector& progr program[1] == 0x73; } +bool CScript::IsPayToBareDefaultCheckTemplateVerifyHash() const +{ + // Extra-fast test for pay-to-bare-default-check-template-verify-hash CScripts: + return (this->size() == 34 && + (*this)[0] == 0x20 && + (*this)[33] == OP_CHECKTEMPLATEVERIFY); +} + bool CScript::IsPayToScriptHash() const { // Extra-fast test for pay-to-script-hash CScripts: diff --git a/src/script/script.h b/src/script/script.h index 5ac07f55296..f42c31caa04 100644 --- a/src/script/script.h +++ b/src/script/script.h @@ -553,6 +553,8 @@ public: */ static bool IsPayToAnchor(int version, const std::vector& program); + bool IsPayToBareDefaultCheckTemplateVerifyHash() const; + bool IsPayToScriptHash() const; bool IsPayToWitnessScriptHash() const; bool IsWitnessProgram(int& version, std::vector& program) const; diff --git a/src/script/sign.cpp b/src/script/sign.cpp index 42db2513597..74d9663bc41 100644 --- a/src/script/sign.cpp +++ b/src/script/sign.cpp @@ -412,6 +412,7 @@ static bool SignStep(const SigningProvider& provider, const BaseSignatureCreator case TxoutType::NONSTANDARD: case TxoutType::NULL_DATA: case TxoutType::WITNESS_UNKNOWN: + case TxoutType::TX_BARE_DEFAULT_CHECKTEMPLATEVERIFY: return false; case TxoutType::PUBKEY: if (!CreateSig(creator, sigdata, provider, sig, CPubKey(vSolutions[0]), scriptPubKey, sigversion)) return false; diff --git a/src/script/solver.cpp b/src/script/solver.cpp index bd3c5cdf724..04622069ddf 100644 --- a/src/script/solver.cpp +++ b/src/script/solver.cpp @@ -29,6 +29,7 @@ std::string GetTxnOutputType(TxoutType t) case TxoutType::WITNESS_V0_SCRIPTHASH: return "witness_v0_scripthash"; case TxoutType::WITNESS_V1_TAPROOT: return "witness_v1_taproot"; case TxoutType::WITNESS_UNKNOWN: return "witness_unknown"; + case TxoutType::TX_BARE_DEFAULT_CHECKTEMPLATEVERIFY: return "bare_default_ctv_hash"; } // no default case, so the compiler can warn about missing cases assert(false); } @@ -151,6 +152,10 @@ TxoutType Solver(const CScript& scriptPubKey, std::vector witnessprogram; if (scriptPubKey.IsWitnessProgram(witnessversion, witnessprogram)) { diff --git a/src/script/solver.h b/src/script/solver.h index 5b945477c90..0b64551bf72 100644 --- a/src/script/solver.h +++ b/src/script/solver.h @@ -31,6 +31,7 @@ enum class TxoutType { WITNESS_V0_SCRIPTHASH, WITNESS_V0_KEYHASH, WITNESS_V1_TAPROOT, + TX_BARE_DEFAULT_CHECKTEMPLATEVERIFY, WITNESS_UNKNOWN, //!< Only for Witness versions not already defined above }; diff --git a/src/test/fuzz/script.cpp b/src/test/fuzz/script.cpp index 07a49e039fb..4b74abd1278 100644 --- a/src/test/fuzz/script.cpp +++ b/src/test/fuzz/script.cpp @@ -76,6 +76,7 @@ FUZZ_TARGET(script, .init = initialize_script) assert(which_type == TxoutType::PUBKEY || which_type == TxoutType::NONSTANDARD || which_type == TxoutType::NULL_DATA || + which_type == TxoutType::TX_BARE_DEFAULT_CHECKTEMPLATEVERIFY || which_type == TxoutType::MULTISIG); } if (which_type == TxoutType::NONSTANDARD || diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index 8beeec49915..90c6622b437 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -70,6 +70,9 @@ static std::map mapFlagNames = { {std::string("DISCOURAGE_UPGRADABLE_PUBKEYTYPE"), (unsigned int)SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_PUBKEYTYPE}, {std::string("DISCOURAGE_OP_SUCCESS"), (unsigned int)SCRIPT_VERIFY_DISCOURAGE_OP_SUCCESS}, {std::string("DISCOURAGE_UPGRADABLE_TAPROOT_VERSION"), (unsigned int)SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_TAPROOT_VERSION}, + {std::string("DISCOURAGE_UPGRADABLE_CHECKTEMPLATEVERIFY"), (unsigned int)SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_CHECKTEMPLATEVERIFY}, + {std::string("DISCOURAGE_CHECKTEMPLATEVERIFY"), (unsigned int)SCRIPT_VERIFY_DISCOURAGE_CHECKTEMPLATEVERIFY}, + {std::string("CHECKTEMPLATEVERIFY"), (unsigned int)SCRIPT_VERIFY_CHECKTEMPLATEVERIFY}, }; unsigned int ParseScriptFlags(std::string strFlags) diff --git a/src/wallet/rpc/backup.cpp b/src/wallet/rpc/backup.cpp index ac23b092d40..49e5e40209e 100644 --- a/src/wallet/rpc/backup.cpp +++ b/src/wallet/rpc/backup.cpp @@ -912,6 +912,8 @@ static std::string RecurseImportData(const CScript& script, ImportData& import_d case TxoutType::WITNESS_V1_TAPROOT: case TxoutType::ANCHOR: return "unrecognized script"; + case TxoutType::TX_BARE_DEFAULT_CHECKTEMPLATEVERIFY: + return "bare default CheckTemplateVerify hash"; } // no default case, so the compiler can warn about missing cases NONFATAL_UNREACHABLE(); } diff --git a/src/wallet/scriptpubkeyman.cpp b/src/wallet/scriptpubkeyman.cpp index 04287581f5a..f0865d6b0e2 100644 --- a/src/wallet/scriptpubkeyman.cpp +++ b/src/wallet/scriptpubkeyman.cpp @@ -208,6 +208,11 @@ IsMineResult IsMineInner(const LegacyDataSPKM& keystore, const CScript& scriptPu } break; } + case TxoutType::TX_BARE_DEFAULT_CHECKTEMPLATEVERIFY: + { + ret = IsMineResult::NO; + break; + } } // no default case, so the compiler can warn about missing cases if (ret == IsMineResult::NO && keystore.HaveWatchOnly(scriptPubKey)) { From 6a14878be3728ff1435f8e3d751ffe94bda32a76 Mon Sep 17 00:00:00 2001 From: Jeremy Rubin Date: Thu, 2 Sep 2021 16:31:26 -0700 Subject: [PATCH 07/10] test: add tx_valid.json tests for BIP-119 CheckTemplateVerify --- src/test/data/tx_valid.json | 152 ++++++++++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) diff --git a/src/test/data/tx_valid.json b/src/test/data/tx_valid.json index 70df0d0f697..e153820a9db 100644 --- a/src/test/data/tx_valid.json +++ b/src/test/data/tx_valid.json @@ -520,5 +520,157 @@ [[["1111111111111111111111111111111111111111111111111111111111111111", 0, "0x00 0x14 0x751e76e8199196d454941c45d1b3a323f1433bd6", 5000000]], "0100000000010111111111111111111111111111111111111111111111111111111111111111110000000000ffffffff0130244c0000000000fd02014cdc1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111175210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ac02483045022100c1a4a6581996a7fdfea77d58d537955a5655c1d619b6f3ab6874f28bb2e19708022056402db6fede03caae045a3be616a1a2d0919a475ed4be828dc9ff21f24063aa01210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179800000000", "NONE"], +["Check that CTV is Processed with a Taproot Spend"], +[[["f90521604b56c392ffa17a01bcae5914b8cf7728cc6cec00d90838818cc5465f", 0, "1 0x20 0x24f5fe807bcee7774dc515f0b7ee8d6ae39eefd1b590264c52ff867e22c49419", 155000]], +"020000000001015f46c58c813808d900ec6ccc2877cfb81459aebc017aa1ff92c3564b602105f90000000000000000000ae80300000000000017a914ce0036ae7d49f06967dd92cc1ffff4a878c457f987d00700000000000017a91406e00c3b362e65e03507a2858d7b6499b668669887b80b00000000000017a9142ee42c65592c59b69bfefbd03781140c67e5232487a00f00000000000017a9146b3df16a1e6651d582ca6598900cb4f2d6c9dfb887881300000000000017a914877d55932d4f38b476d4db27e4efbe159ff0a07187701700000000000017a91441e9dc892e861d252d513d594ba833cd6bc8917087581b00000000000017a914b93075800c693dcc78b0553bf9d1cf879d76a02487401f00000000000017a914e9f0ea3a2cae0ad01114e2ec3502ef08bbc50af487282300000000000017a9149a645b5293bdf8be72cb9d1460bce7d64445cfad87102700000000000017a91451e5d6b2ee24ae128234c92245df3624620ea7d3870222209eb65498bfcd4eb90e61c2c5e323a9c16c8bfd8d53ba649915bcdb572099c12fb321c0b7e0105780185688d998a8f8438aa07637a5799755688ec80175cb26c0406e0200000000", +"DISCOURAGE_CHECKTEMPLATEVERIFY"], +["Check that CTV upgradability works (taproot)"], +[[["f90521604b56c392ffa17a01bcae5914b8cf7728cc6cec00d90838818cc5465f", 0, "1 0x20 0x24f5fe807bcee7774dc515f0b7ee8d6ae39eefd1b590264c52ff867e22c49419", 155000]], +"020000000001015f46c58c813808d900ec6ccc2877cfb81459aebc017aa1ff92c3564b602105f90000000000000000000ae80300000000000017a914ce0036ae7d49f06967dd92cc1ffff4a878c457f987d00700000000000017a91406e00c3b362e65e03507a2858d7b6499b668669887b80b00000000000017a9142ee42c65592c59b69bfefbd03781140c67e5232487a00f00000000000017a9146b3df16a1e6651d582ca6598900cb4f2d6c9dfb887881300000000000017a914877d55932d4f38b476d4db27e4efbe159ff0a07187701700000000000017a91441e9dc892e861d252d513d594ba833cd6bc8917087581b00000000000017a914b93075800c693dcc78b0553bf9d1cf879d76a02487401f00000000000017a914e9f0ea3a2cae0ad01114e2ec3502ef08bbc50af487282300000000000017a9149a645b5293bdf8be72cb9d1460bce7d64445cfad87102700000000000017a91451e5d6b2ee24ae128234c92245df3624620ea7d3870222209eb65498bfcd4eb90e61c2c5e323a9c16c8bfd8d53ba649915bcdb572099c12fb321c0b7e0105780185688d998a8f8438aa07637a5799755688ec80175cb26c0406e0200000000", +"DISCOURAGE_CHECKTEMPLATEVERIFY"], + +["Segwit v0 CTV Spend"], +[[["c16621d89637274011a8fb02ac487d283367f33d36de8c1ec8e323e55cb149cb", + 0, + "0x00 0x20 0xf47ad51491d952cb1fad0d3f208dde482561d2170ebbbbc08e2e0292eeb4ec3d", + 155000]], + "02000000000101cb49b15ce523e3c81e8cde363df36733287d48ac02fba81140273796d82166c10000000000000000000ae80300000000000017a91496e75de842d245fe846f1866f535d3d549af1eee87d00700000000000017a91443078220afb62f1dd0f13b58103c2cdea3ec31eb87b80b00000000000017a914c2aabf119c1825b1de66bc34e0792e37c198b5a987a00f00000000000017a9146e9e99a0b342e90e9360e26aa1a2b12ac7d1701e87881300000000000017a9149fc2952de5c6268759a4addd6f1336585de5a6b687701700000000000017a914f0bb53b2734e0f4027b25084630f4c7cb793f0d087581b00000000000017a914151a578ea0bbe3a24bf8335c4ee162643be28b4787401f00000000000017a9148f7ffde60fa425fa919ab9de3c7731fa4268151787282300000000000017a91454c45d77bccc359d07a2b17b4abfc78e8c3237b787102700000000000017a914e43197dbd28424b86c7c8823180e2b15192a96d1870122207427029cbb0a48361ba1b83e4fff21918618477be3d217d83b2ff846815305f6b300000000", + "DISCOURAGE_CHECKTEMPLATEVERIFY"], +["Check that CTV upgradability works (Segwit v0)"], +[[["c16621d89637274011a8fb02ac487d283367f33d36de8c1ec8e323e55cb149cb", + 0, + "0x00 0x20 0xf47ad51491d952cb1fad0d3f208dde482561d2170ebbbbc08e2e0292eeb4ec3d", + 155000]], + "02000000000101cb49b15ce523e3c81e8cde363df36733287d48ac02fba81140273796d82166c10000000000000000000ae80300000000000017a91496e75de842d245fe846f1866f535d3d549af1eee87d00700000000000017a91443078220afb62f1dd0f13b58103c2cdea3ec31eb87b80b00000000000017a914c2aabf119c1825b1de66bc34e0792e37c198b5a987a00f00000000000017a9146e9e99a0b342e90e9360e26aa1a2b12ac7d1701e87881300000000000017a9149fc2952de5c6268759a4addd6f1336585de5a6b687701700000000000017a914f0bb53b2734e0f4027b25084630f4c7cb793f0d087581b00000000000017a914151a578ea0bbe3a24bf8335c4ee162643be28b4787401f00000000000017a9148f7ffde60fa425fa919ab9de3c7731fa4268151787282300000000000017a91454c45d77bccc359d07a2b17b4abfc78e8c3237b787102700000000000017a914e43197dbd28424b86c7c8823180e2b15192a96d1870122207427029cbb0a48361ba1b83e4fff21918618477be3d217d83b2ff846815305f6b300000000", +"DISCOURAGE_CHECKTEMPLATEVERIFY"], + + ["CTV reserves different sized args for future upgrades"], +[[["e8e9805801b7fb44814531de0dd498b955651b9c25a85a043d73f18970622647", + 0, + "0x00 0x20 0x65f15821061635e6807f06701bf0a12d8e89dcff88df5968bd0822c9dbb52f1c", + 155000]], + "020000000001014726627089f1733d045aa8259c1b6555b998d40dde31458144fbb7015880e9e80000000000000000000ae90300000000000017a91496e75de842d245fe846f1866f535d3d549af1eee87d00700000000000017a91443078220afb62f1dd0f13b58103c2cdea3ec31eb87b80b00000000000017a914c2aabf119c1825b1de66bc34e0792e37c198b5a987a00f00000000000017a9146e9e99a0b342e90e9360e26aa1a2b12ac7d1701e87881300000000000017a9149fc2952de5c6268759a4addd6f1336585de5a6b687701700000000000017a914f0bb53b2734e0f4027b25084630f4c7cb793f0d087581b00000000000017a914151a578ea0bbe3a24bf8335c4ee162643be28b4787401f00000000000017a9148f7ffde60fa425fa919ab9de3c7731fa4268151787282300000000000017a91454c45d77bccc359d07a2b17b4abfc78e8c3237b787102700000000000017a914e43197dbd28424b86c7c8823180e2b15192a96d18702015101b300000000", + "DISCOURAGE_UPGRADABLE_CHECKTEMPLATEVERIFY,DISCOURAGE_CHECKTEMPLATEVERIFY"], + + ["CheckTemplateVerify Argument from Witness Stack"], +[[["e8e9805801b7fb44814531de0dd498b955651b9c25a85a043d73f18970622647", + 0, + "0x00 0x20 0x65f15821061635e6807f06701bf0a12d8e89dcff88df5968bd0822c9dbb52f1c", + 155000]], + "020000000001014726627089f1733d045aa8259c1b6555b998d40dde31458144fbb7015880e9e80000000000000000000ae90300000000000017a91496e75de842d245fe846f1866f535d3d549af1eee87d00700000000000017a91443078220afb62f1dd0f13b58103c2cdea3ec31eb87b80b00000000000017a914c2aabf119c1825b1de66bc34e0792e37c198b5a987a00f00000000000017a9146e9e99a0b342e90e9360e26aa1a2b12ac7d1701e87881300000000000017a9149fc2952de5c6268759a4addd6f1336585de5a6b687701700000000000017a914f0bb53b2734e0f4027b25084630f4c7cb793f0d087581b00000000000017a914151a578ea0bbe3a24bf8335c4ee162643be28b4787401f00000000000017a9148f7ffde60fa425fa919ab9de3c7731fa4268151787282300000000000017a91454c45d77bccc359d07a2b17b4abfc78e8c3237b787102700000000000017a914e43197dbd28424b86c7c8823180e2b15192a96d18702204d5783a61241bdef19c3480e094cc933c91d2bde995c8c50407099184b501f4301b300000000", + "DISCOURAGE_CHECKTEMPLATEVERIFY"], + ["CheckTemplateVerify Argument from Witness Stack"], +[[["e8e9805801b7fb44814531de0dd498b955651b9c25a85a043d73f18970622647", + 0, + "0x00 0x20 0x65f15821061635e6807f06701bf0a12d8e89dcff88df5968bd0822c9dbb52f1c", + 155000]], + "020000000001014726627089f1733d045aa8259c1b6555b998d40dde31458144fbb7015880e9e80000000000000000000ae90300000000000017a91496e75de842d245fe846f1866f535d3d549af1eee87d00700000000000017a91443078220afb62f1dd0f13b58103c2cdea3ec31eb87b80b00000000000017a914c2aabf119c1825b1de66bc34e0792e37c198b5a987a00f00000000000017a9146e9e99a0b342e90e9360e26aa1a2b12ac7d1701e87881300000000000017a9149fc2952de5c6268759a4addd6f1336585de5a6b687701700000000000017a914f0bb53b2734e0f4027b25084630f4c7cb793f0d087581b00000000000017a914151a578ea0bbe3a24bf8335c4ee162643be28b4787401f00000000000017a9148f7ffde60fa425fa919ab9de3c7731fa4268151787282300000000000017a91454c45d77bccc359d07a2b17b4abfc78e8c3237b787102700000000000017a914e43197dbd28424b86c7c8823180e2b15192a96d18702204d5783a61241bdef19c3480e094cc933c91d2bde995c8c50407099184b501f4301b300000000", + "DISCOURAGE_CHECKTEMPLATEVERIFY"], + + ["BEGIN CTV congestion control tree level with 4 levels:"], + ["CTV congestion control tree level 0"], +[[["d0246d069143263bca9a2b176fcf64bd8e4975c7670ed33659b4b8f88d3e7446", + 0, + "0x20 0x10618b50aa1120e9e940bbea8b6d081019e38fbb9b956b0ab4f61631d05727ca OP_CHECKTEMPLATEVERIFY", + 16600]], + "020000000146743e8df8b8b45936d30e67c775498ebd64cf6f172b9aca3b264391066d24d000000000000000000002781e0000000000002220bceb923d731eddf09705690d6ee697d1b3d57279ad96910cfb66a8d43a638800b3781e00000000000022201210e50077518896fd1661bffc2c1e88ad6e204ec4e8755407b42a97347c1e1bb300000000", + "DISCOURAGE_CHECKTEMPLATEVERIFY"], +["CTV congestion control tree level 1"], +[[["b69f866d47ebb75eeecfbc3b9b641f926f11035b64ff27a5a5e88b9c065bddf5", + 0, + "0x20 0xbceb923d731eddf09705690d6ee697d1b3d57279ad96910cfb66a8d43a638800 OP_CHECKTEMPLATEVERIFY", + 7800]], + "0200000001f5dd5b069c8be8a5a527ff645b03116f921f649b3bbccfee5eb7eb476d869fb600000000000000000002480d00000000000022204c683607ca7950380df10647b223f656cd73d1f7ad67b30caf60d78337f913b2b3480d0000000000002220805bddd8b95a3cf3729b62703de37a1533b11634de76aa4a18605b640f1f3208b300000000", + "DISCOURAGE_CHECKTEMPLATEVERIFY"], +["CTV congestion control tree level 2"], +[[["7d331a33880504fa94478c9687f3f41322ec76f81edad8e72491cbb81eea4754", + 0, + "0x20 0x4c683607ca7950380df10647b223f656cd73d1f7ad67b30caf60d78337f913b2 OP_CHECKTEMPLATEVERIFY", + 3400]], + "02000000015447ea1eb8cb9124e7d8da1ef876ec2213f4f387968c4794fa040588331a337d00000000000000000002b004000000000000222084ac6e0fdbe91b09d1bf68158643ad68e0b3e64373738fb35711de0835011079b3b0040000000000002220241af26179a8e861cca473244723978127c16531f71fbcc33563c4f099651f8fb300000000", + "DISCOURAGE_CHECKTEMPLATEVERIFY"], +["CTV congestion control tree level 3"], +[[["e630b2357e02d1611a0615ce3964c408823ce3269974bd94e57ddea96900da70", + 0, + "0x20 0x84ac6e0fdbe91b09d1bf68158643ad68e0b3e64373738fb35711de0835011079 OP_CHECKTEMPLATEVERIFY", + 1200]], + "020000000170da0069a9de7de594bd749926e33c8208c46439ce15061a61d1027e35b230e60000000000000000000264000000000000001600141ca3bdf6bd2b1fc27420316a0d13f81fcdb85cb0640000000000000016001489d611c79700d6b4ae73d853ed49b86621d5802100000000", + "DISCOURAGE_CHECKTEMPLATEVERIFY"], + ["END"], + + ["BEGIN CTV congestion control tree level with 4 levels:"], + ["CTV congestion control tree level 0"], +[[["d0246d069143263bca9a2b176fcf64bd8e4975c7670ed33659b4b8f88d3e7446", + 0, + "0x20 0x10618b50aa1120e9e940bbea8b6d081019e38fbb9b956b0ab4f61631d05727ca OP_CHECKTEMPLATEVERIFY", + 16600]], + "020000000146743e8df8b8b45936d30e67c775498ebd64cf6f172b9aca3b264391066d24d000000000000000000002781e0000000000002220bceb923d731eddf09705690d6ee697d1b3d57279ad96910cfb66a8d43a638800b3781e00000000000022201210e50077518896fd1661bffc2c1e88ad6e204ec4e8755407b42a97347c1e1bb300000000", + "DISCOURAGE_CHECKTEMPLATEVERIFY"], +["CTV congestion control tree level 1"], +[[["b69f866d47ebb75eeecfbc3b9b641f926f11035b64ff27a5a5e88b9c065bddf5", + 0, + "0x20 0xbceb923d731eddf09705690d6ee697d1b3d57279ad96910cfb66a8d43a638800 OP_CHECKTEMPLATEVERIFY", + 7800]], + "0200000001f5dd5b069c8be8a5a527ff645b03116f921f649b3bbccfee5eb7eb476d869fb600000000000000000002480d00000000000022204c683607ca7950380df10647b223f656cd73d1f7ad67b30caf60d78337f913b2b3480d0000000000002220805bddd8b95a3cf3729b62703de37a1533b11634de76aa4a18605b640f1f3208b300000000", + "DISCOURAGE_CHECKTEMPLATEVERIFY"], +["CTV congestion control tree level 2"], +[[["7d331a33880504fa94478c9687f3f41322ec76f81edad8e72491cbb81eea4754", + 0, + "0x20 0x4c683607ca7950380df10647b223f656cd73d1f7ad67b30caf60d78337f913b2 OP_CHECKTEMPLATEVERIFY", + 3400]], + "02000000015447ea1eb8cb9124e7d8da1ef876ec2213f4f387968c4794fa040588331a337d00000000000000000002b004000000000000222084ac6e0fdbe91b09d1bf68158643ad68e0b3e64373738fb35711de0835011079b3b0040000000000002220241af26179a8e861cca473244723978127c16531f71fbcc33563c4f099651f8fb300000000", + "DISCOURAGE_CHECKTEMPLATEVERIFY"], +["CTV congestion control tree level 3"], +[[["e630b2357e02d1611a0615ce3964c408823ce3269974bd94e57ddea96900da70", + 0, + "0x20 0x84ac6e0fdbe91b09d1bf68158643ad68e0b3e64373738fb35711de0835011079 OP_CHECKTEMPLATEVERIFY", + 1200]], + "020000000170da0069a9de7de594bd749926e33c8208c46439ce15061a61d1027e35b230e60000000000000000000264000000000000001600141ca3bdf6bd2b1fc27420316a0d13f81fcdb85cb0640000000000000016001489d611c79700d6b4ae73d853ed49b86621d5802100000000", + "DISCOURAGE_CHECKTEMPLATEVERIFY"], + ["END"], + + ["Test CTV with a specific scriptsig"], +[[["32858fe9a6348d4ee5fcfce78f6dbca0b54dff169ff4cc41439adca4e5d30746", + 0, + "1", + 155000], + ["357722dce671e5aa52abd617002baa8d5d970cef43feca3bf2d4c8b1e5d53d11", + 0, + "0x20 0x08a5903863a0562c0b5608521a8a77ca02e669eb01f3981eede6bf6f2f38c2c2 OP_CHECKTEMPLATEVERIFY", + 155000]], + "0200000002113dd5e5b1c8d4f23bcafe43ef0c975d8daa2b0017d6ab52aae571e6dc227735000000000151000000004607d3e5a4dc9a4341ccf49f16ff4db5a0bc6d8fe7fcfce54e8d34a6e98f8532000000000100000000000ae80300000000000017a9146422bb825e07ab99ab915223ac67f195a4fb761987d00700000000000017a914cc9fa001f8c9ff9dfdecf0ec1356d37c808aec2d87b80b00000000000017a914092f42f35fd05eaf816a090ad8f1adec8394132d87a00f00000000000017a9147cfd2a76093289ebabf860d3071b92756dbde1b787881300000000000017a914c3d81e1a59c256bff75c535878e1701943a9e48987701700000000000017a914029ddf1319c05ff38cd974ba99fdcf1cb4b88b9687581b00000000000017a9148c95279a9fd452ad7b1cb7a35fd08e7ff55946af87401f00000000000017a9149216fef0f965b2f1890a420aa725cb86ba47a9c087282300000000000017a9141424c24d8cd907a36310db639ec7d194c62d620087102700000000000017a9145b278b155e6dd103b4bf5ba78e4a95c16926c9bd8700000000", + "CLEANSTACK,DISCOURAGE_CHECKTEMPLATEVERIFY"], +[[["32858fe9a6348d4ee5fcfce78f6dbca0b54dff169ff4cc41439adca4e5d30746", + 0, + "1", + 155000], + ["357722dce671e5aa52abd617002baa8d5d970cef43feca3bf2d4c8b1e5d53d11", + 0, + "0x20 0x08a5903863a0562c0b5608521a8a77ca02e669eb01f3981eede6bf6f2f38c2c2 OP_CHECKTEMPLATEVERIFY", + 155000]], + "0200000002113dd5e5b1c8d4f23bcafe43ef0c975d8daa2b0017d6ab52aae571e6dc227735000000000151000000004607d3e5a4dc9a4341ccf49f16ff4db5a0bc6d8fe7fcfce54e8d34a6e98f8532000000000100000000000ae80300000000000017a9146422bb825e07ab99ab915223ac67f195a4fb761987d00700000000000017a914cc9fa001f8c9ff9dfdecf0ec1356d37c808aec2d87b80b00000000000017a914092f42f35fd05eaf816a090ad8f1adec8394132d87a00f00000000000017a9147cfd2a76093289ebabf860d3071b92756dbde1b787881300000000000017a914c3d81e1a59c256bff75c535878e1701943a9e48987701700000000000017a914029ddf1319c05ff38cd974ba99fdcf1cb4b88b9687581b00000000000017a9148c95279a9fd452ad7b1cb7a35fd08e7ff55946af87401f00000000000017a9149216fef0f965b2f1890a420aa725cb86ba47a9c087282300000000000017a9141424c24d8cd907a36310db639ec7d194c62d620087102700000000000017a9145b278b155e6dd103b4bf5ba78e4a95c16926c9bd8700000000", + "CLEANSTACK,DISCOURAGE_CHECKTEMPLATEVERIFY"], + ["Test CTV with a specific scriptsig at different index"], + [[["e2f2baee9c59389b34e39742ce05debf64aaa7a00fbdab88614f4d3c133186d5", + 0, + "1", + 155000], + ["c88e4b769a9211d2bca7516dbeacf250585dc825e41e34a65607a444b97fb782", + 0, + "0x20 0xcc06acb181a8e9893c53c92fcfcb56fc004a360964af02cfd15b9f3321385f86 OP_CHECKTEMPLATEVERIFY", + 155000]], +"0200000002d58631133c4d4f6188abbd0fa0a7aa64bfde05ce4297e3349b38599ceebaf2e20000000001510000000082b77fb944a40756a6341ee425c85d5850f2acbe6d51a7bcd211929a764b8ec8000000000100000000000ae80300000000000017a914d63e77972529f4db5b32efaa4e06f66ae0b5dc0987d00700000000000017a91488b6705f8c9568c52b55ed712c257f84f64a49f587b80b00000000000017a9142be57e9a179f8d9ff8f33a788d4b54512ea9e36087a00f00000000000017a91429261b4f65796f618908de9f51669014e2e2e04f87881300000000000017a914e3a1e1d24cbba3ca9369248082988bad3ceafcfb87701700000000000017a91403801b0a9591f3b5a00a5ea60fb34dc12b4a691187581b00000000000017a91465248bc2c732db2d88db0b0d677c1514b101025b87401f00000000000017a91420021e3dc4e80c7192c1a3cd04026d22d0f8d38287282300000000000017a914df27596dbff2028791bd7692846e65d16d8fed0d87102700000000000017a9142ed128e911cab04d3277d3635f79d5e3d7e6f4c48700000000", +"CLEANSTACK,DISCOURAGE_CHECKTEMPLATEVERIFY"], + [[["e2f2baee9c59389b34e39742ce05debf64aaa7a00fbdab88614f4d3c133186d5", + 0, + "1", + 155000], + ["c88e4b769a9211d2bca7516dbeacf250585dc825e41e34a65607a444b97fb782", + 0, + "0x20 0xcc06acb181a8e9893c53c92fcfcb56fc004a360964af02cfd15b9f3321385f86 OP_CHECKTEMPLATEVERIFY", + 155000]], +"0200000002d58631133c4d4f6188abbd0fa0a7aa64bfde05ce4297e3349b38599ceebaf2e20000000001510000000082b77fb944a40756a6341ee425c85d5850f2acbe6d51a7bcd211929a764b8ec8000000000100000000000ae80300000000000017a914d63e77972529f4db5b32efaa4e06f66ae0b5dc0987d00700000000000017a91488b6705f8c9568c52b55ed712c257f84f64a49f587b80b00000000000017a9142be57e9a179f8d9ff8f33a788d4b54512ea9e36087a00f00000000000017a91429261b4f65796f618908de9f51669014e2e2e04f87881300000000000017a914e3a1e1d24cbba3ca9369248082988bad3ceafcfb87701700000000000017a91403801b0a9591f3b5a00a5ea60fb34dc12b4a691187581b00000000000017a91465248bc2c732db2d88db0b0d677c1514b101025b87401f00000000000017a91420021e3dc4e80c7192c1a3cd04026d22d0f8d38287282300000000000017a914df27596dbff2028791bd7692846e65d16d8fed0d87102700000000000017a9142ed128e911cab04d3277d3635f79d5e3d7e6f4c48700000000", + "CLEANSTACK,DISCOURAGE_CHECKTEMPLATEVERIFY"], + ["Make diffs cleaner by leaving a comment here without comma at the end"] ] From b7e7ca146b43d59140b6616513176dba020f3a39 Mon Sep 17 00:00:00 2001 From: Jeremy Rubin Date: Sat, 11 Sep 2021 19:26:24 -0700 Subject: [PATCH 08/10] test: add tx_invalid.json examples for CTV --- src/test/data/tx_invalid.json | 95 +++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) diff --git a/src/test/data/tx_invalid.json b/src/test/data/tx_invalid.json index 486469ddefb..d1660fd3a97 100644 --- a/src/test/data/tx_invalid.json +++ b/src/test/data/tx_invalid.json @@ -393,5 +393,100 @@ ["ceafe58e0f6e7d67c0409fbbf673c84c166e3c5d3c24af58f7175b18df3bb3db", 1, "2 0x48 0x3045022015bd0139bcccf990a6af6ec5c1c52ed8222e03a0d51c334df139968525d2fcd20221009f9efe325476eb64c3958e4713e9eefe49bf1d820ed58d2112721b134e2a1a5303 0x21 0x0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71 0x21 0x0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71 3 CHECKMULTISIG"]], "0100000002dbb33bdf185b17f758af243c5d3c6e164cc873f6bb9f40c0677d6e0f8ee5afce000000006b4830450221009627444320dc5ef8d7f68f35010b4c050a6ed0d96b67a84db99fda9c9de58b1e02203e4b4aaa019e012e65d69b487fdf8719df72f488fa91506a80c49a33929f1fd50121022b78b756e2258af13779c1a1f37ea6800259716ca4b7f0b87610e0bf3ab52a01ffffffffdbb33bdf185b17f758af243c5d3c6e164cc873f6bb9f40c0677d6e0f8ee5afce010000009300483045022015bd0139bcccf990a6af6ec5c1c52ed8222e03a0d51c334df139968525d2fcd20221009f9efe325476eb64c3958e4713e9eefe49bf1d820ed58d2112721b134e2a1a5303483045022015bd0139bcccf990a6af6ec5c1c52ed8222e03a0d51c334df139968525d2fcd20221009f9efe325476eb64c3958e4713e9eefe49bf1d820ed58d2112721b134e2a1a5303ffffffff01a0860100000000001976a9149bc0bbdd3024da4d0c38ed1aecf5c68dd1d3fa1288ac00000000", "CONST_SCRIPTCODE"], +["CheckTemplateVerify (CTV) Tests"], +["Modified Segwit OP_CTV Spend Failed if Amount Mutated"], +[[["10bf165531fbdfac386f018d92d72dce3ad73af1f183f6fac2c7a2a1050aa51b", + 0, + "0x00 0x20 0x9e650578b4f13cde08d16211f3635239e22ba3e108ba7f5fa4bd6c12f8c8219a", + 155000]], +"020000000001011ba50a05a1a2c7c2faf683f1f13ad73ace2dd7928d016f38acdffb315516bf100000000000000000000ae90300000000000017a9142b697af70a75926b158a2ea0aab8054eb18490ac87d00700000000000017a9143177919dae74db1c4cd3e6e69861091c6aee9eb287b80b00000000000017a91417d751e7c17c8264e90e4831fed9c47804b2bbc887a00f00000000000017a914a46167b1fbca936b56dda9710a0c16a53fd32fe687881300000000000017a914b4a5ddbdda32760d1c61dd131007fd7e67d650e187701700000000000017a91480909aab0729614b1162d86563cbfb0c71d5bc9e87581b00000000000017a914997c99e26f67463a1f9770003f90603360408bed87401f00000000000017a9149fef27cd2e724889aa522ac6b5eb35de7582727487282300000000000017a914c7c616d8323c7046de863e2301ec0c7884626e9687102700000000000017a914b590ca292351b64cbf725bad01c3ba6da808ab0b870122200a2891d90df11c7714549c76b80b29c86d544110d958a6dabcfcd5cda1612427b300000000", +"CHECKTEMPLATEVERIFY,WITNESS,P2SH"], + +["Modified Segwit OP_CTV Spend Failed if # inputs Mutated"], +[[["7438c73c9a554540dce173b485e888683e9ae5beae3ae94142e77ae2cc024e3c", + 0, + "0x00 0x20 0xc19287614d027e87b85ace418cb0fc2d89241392370f0f7cf2ebb06b861c85f0", + 155000], + ["24040d2cd61f2ecb67e9fe5634c1d90e59b6b16028ff03003cf20f398ce27e44", + 0, + "1", + 155000]], + "020000000001023c4e02cce27ae74241e93aaebee59a3e6888e885b473e1dc4045559a3cc73874000000000000000000447ee28c390ff23c0003ff2860b1b6590ed9c13456fee967cb2e1fd62c0d04240000000000000000000ae90300000000000017a91406651b0a47731127630ccc27d07fb9afc041846987d00700000000000017a914c758d7ce652d5ed562253ed00e9afc34ea1f76bf87b80b00000000000017a914fe8740b477b23838679c7eaa6e452e66c58a72bc87a00f00000000000017a914cc07d98fc32e2ff65f62076f2824d63bd5a1628787881300000000000017a914acfb84e8356788c7a8312194d1833e5d5677d58e87701700000000000017a91409aad9fbb6609e4486fa5b04afbbde40659388f787581b00000000000017a914ffd3dc8f12ebb700dd45a6a58914347533b6728587401f00000000000017a914781456255e72a09dfab2211dc151165c62ab7af987282300000000000017a914ee01dfa11feb2bc68b22d6909052647c8c001ec787102700000000000017a9145dd4e76cb2cef90e09f181c55fdc42717f3d948787012220cf100c0bb5dc85c104d87c31e7b57a4a7791cc2091dc87ddaac40c91edda7f6bb30000000000", + "CHECKTEMPLATEVERIFY,WITNESS,P2SH"], +["Wrong Size CTV Argument is Discouraged"], +[[["13e313be0d1eab290bcf2b58f4ad76c3f4fd46b2ac4273c607cdc7f5a4170794", + 0, + "0x00 0x20 0xaeba7cb39e708a34dd186698a80cc34e70bb92921a01f853ac691bb572b52d62", + 155000]], + "02000000000101940717a4f5c7cd07c67342acb246fdf4c376adf4582bcf0b29ab1e0dbe13e3130000000000000000000ae90300000000000017a914f0ccedba146f6390e5961b2a0a39cfba046c312987d00700000000000017a91458d4792223eebb552801d6690b5985513fbddaca87b80b00000000000017a914774b6fe872b65890c610ec6edda928703fe8503e87a00f00000000000017a9148ad37662e56b5f2e472e4bdc205f0dcde8708fd787881300000000000017a9149e8680d850f172186f4e16cee442f0d0121fd46e87701700000000000017a9141394792d48889f70878ce2ee3b151de33d4b774987581b00000000000017a9142444dbb85cf5dfa3e94d2a970a4d4bb795495df687401f00000000000017a914b0437ba6b526e697e695d4f8a53482d26547b64f87282300000000000017a91408ceb5466bc28db2122f954ca59d4a4a08fc133b87102700000000000017a91486f51c990634abc769d6d9d01608ff99f93b050387010251b300000000", +"CHECKTEMPLATEVERIFY,WITNESS,P2SH,DISCOURAGE_UPGRADABLE_CHECKTEMPLATEVERIFY"], + +["Empty Stack is Rejected for CTV"], +[[["e658e5b94eba5931faf2379a61a75a05b153648690527d35f7143bed462a6ebc", + 0, + "0x00 0x20 0x6c9cc4747e7d287ac1abf8c65152a78d369213583e306b7d3163e12c561abaa2", + 155000]], + "02000000000101bc6e2a46ed3b14f7357d5290866453b1055aa7619a37f2fa3159ba4eb9e558e60000000000000000000ae90300000000000017a914b038d0ca030a6d6bc4a06bda13ae1413ce96f37e87d00700000000000017a914fa5716162fb8f5f3cafdce1c1f5533e182c83f4d87b80b00000000000017a91417d10dea89621354333f4dfcbdafe18ec6a794da87a00f00000000000017a9142abb09f63aaecdfbe0e92fedc0afedf19194360187881300000000000017a914aab8b0219014272348de62cbc195e20151b7735787701700000000000017a914a507b83449359c82a195fc9bab99fa1b7c8289eb87581b00000000000017a91401ea6e7336fb9d5e5f36994eecade840ba938d0687401f00000000000017a914e5a474adbd25d66bb70c9b0b6a27f3eebf70b3f587282300000000000017a914d4ae33b227632cf0434f054782558baf9aa6e42d87102700000000000017a9147e4cca8f6c63cb7a56dd3c6edd2acbd031813de9870106b3746375685100000000", + "CHECKTEMPLATEVERIFY,WITNESS,P2SH"], + +["Wrong Size Stack Argument is Discouraged for CTV"], +[[["e658e5b94eba5931faf2379a61a75a05b153648690527d35f7143bed462a6ebc", + 0, + "0x00 0x20 0x6c9cc4747e7d287ac1abf8c65152a78d369213583e306b7d3163e12c561abaa2", + 155000]], +"02000000000101bc6e2a46ed3b14f7357d5290866453b1055aa7619a37f2fa3159ba4eb9e558e60000000000000000000ae90300000000000017a914b038d0ca030a6d6bc4a06bda13ae1413ce96f37e87d00700000000000017a914fa5716162fb8f5f3cafdce1c1f5533e182c83f4d87b80b00000000000017a91417d10dea89621354333f4dfcbdafe18ec6a794da87a00f00000000000017a9142abb09f63aaecdfbe0e92fedc0afedf19194360187881300000000000017a914aab8b0219014272348de62cbc195e20151b7735787701700000000000017a914a507b83449359c82a195fc9bab99fa1b7c8289eb87581b00000000000017a91401ea6e7336fb9d5e5f36994eecade840ba938d0687401f00000000000017a914e5a474adbd25d66bb70c9b0b6a27f3eebf70b3f587282300000000000017a914d4ae33b227632cf0434f054782558baf9aa6e42d87102700000000000017a9147e4cca8f6c63cb7a56dd3c6edd2acbd031813de98702015106b3746375685100000000", +"CHECKTEMPLATEVERIFY,WITNESS,P2SH,DISCOURAGE_UPGRADABLE_CHECKTEMPLATEVERIFY"], + +["Wrong TX Hash passed via the stack fails CTV"], +[[["1303ae3fc607b6eb3a4da63d3d7f4722b595db87890943618e11c3905662cae4", + 0, + "0x00 0x20 0x6c9cc4747e7d287ac1abf8c65152a78d369213583e306b7d3163e12c561abaa2", + 155000]], + "02000000000101e4ca625690c3118e6143098987db95b522477f3d3da64d3aebb607c63fae03130000000000000000000ae90300000000000017a9145850541d205b7b1feb1bc10112f9d739fa9a7dc287d00700000000000017a914d76b85e77e20777d5ec9d7d9998ae0c062d4669087b80b00000000000017a914c79f4a39b0580e4ec90e1b4989fc6124e4135cc187a00f00000000000017a91469635f1f4c06d66591282a02303b1435ee888d9487881300000000000017a91410d3b9b2aaffae25b6098169e2dc69928849215387701700000000000017a91456e4a3e5a3a49b9a66240288e79a8a5e8e31d05587581b00000000000017a9143936403d1a70b32c1e0e6920f9cd99cbc8a8345787401f00000000000017a9146ec4fa5a4e329f9d92ea29b65fa48c6ec1470ffa87282300000000000017a914f66743d56210c98bce8a44742b2ecfa9b7f48fdb87102700000000000017a914555c65f1c355993b46003311931eb08cf457209b870220a2638b51a692e6a8b39e87c431edde4fc1ada3dedaf9665875ac8353af44c50706b3746375685100000000", + "CHECKTEMPLATEVERIFY,WITNESS,P2SH"], + +["Embedded CTV Impossible with Bare P2SH due to hash cycle"], +[[["6a869fd9a0395f35e412ad3eb7fffa61a59263b1ad16aeb5fcc30e032bc3a8bf", + 0, + "OP_HASH160 0x14 0x40aec8967698985eb369afd3ad3dc571110e6a10 OP_EQUAL", + 155000]], + "0200000001bfa8c32b030ec3fcb5ae16adb16392a561faffb73ead12e4355f39a0d99f866a000000002322203b8d241649e612058fd2f1b4decbe9141284f0e4dd297d95b0da01a5d8791e4bb3000000000ae90300000000000017a914b04d55bbfedf606a08795fb0c2655bb3212f2bde87d00700000000000017a914d079c2cfad655234e68159422727eefa78811b4787b80b00000000000017a9145ea3edd87eb790af8051da692f4d59e5be6ffd4b87a00f00000000000017a914e17e2c4f4fcae1ef0d5ef96c740565426009ca2187881300000000000017a9144769d9f3b6fdf14f1223d9e7f11be7873bcbcde387701700000000000017a914064529bab7b89253159c9043ef128f37f78add7a87581b00000000000017a9147bae64476db031d744b442ddee9af3e60ef1e4ea87401f00000000000017a914dd2d96d0ba673c0b9d5950223c334f19f2b6f4a487282300000000000017a9148abaaa7b977855f96afacea4c79e3caf5e7482c487102700000000000017a9140dab14b1ee04aea522639ee27d29a5f6a57758c18700000000", + "CHECKTEMPLATEVERIFY,P2SH"], + +["CTV at pos 2 with >1 Input Fails if too few inputs"], +[[["eeda9ea077b04abec103ffbba6bcf41cd67cdfdabe5ccc6ed766b9cd4ed4808a", + 0, + "0x20 0x3e123dbe62352fa40471c195aebd3cdec43cca8728520c8a2d5737009fa05b0b OP_CHECKTEMPLATEVERIFY", + 155000]], +"02000000018a80d44ecdb966d76ecc5cbedadf7cd61cf4bca6bbff03c1be4ab077a09edaee0000000000000000000ae80300000000000017a9144dd991d2f69eed133bb9d16e298703c830e1fb2387d00700000000000017a9147a50ac55b0af704dfffc797c507db803488ad44787b80b00000000000017a914caab97b53be0b75526e011bc49b0101365f611b887a00f00000000000017a91448c947e1b16103782a7dcba1dd5896936fbc7d2587881300000000000017a914ff075d852727e7e32ff5e11b13d254cb553fb73287701700000000000017a914761069764474d5ef5d0e068e88e4ebe2edd2336087581b00000000000017a914cd76c979ed6421f5d39380b5eb3d0dc7f56e864b87401f00000000000017a91417e7563571166469e14275be7ef00d91927eee0387282300000000000017a9140f9ddd36a76392fec584f05b34d33282fbd4921287102700000000000017a91417603536acce13cf7496387f8169a7f832f08f4c8700000000", +"CHECKTEMPLATEVERIFY"], + +["CTV at pos 2 with >1 Input Fails if inputs in wrong order"], +[[["eeda9ea077b04abec103ffbba6bcf41cd67cdfdabe5ccc6ed766b9cd4ed4808a", + 0, + "0x20 0x3e123dbe62352fa40471c195aebd3cdec43cca8728520c8a2d5737009fa05b0b OP_CHECKTEMPLATEVERIFY", + 155000], + ["b6d623f1e5eaaaa83a21739f60ac173818ce6b9e13ca18ddda74e9dbe6124c0b", 0, "1", 155000]], +"02000000028a80d44ecdb966d76ecc5cbedadf7cd61cf4bca6bbff03c1be4ab077a09edaee0000000000000000000b4c12e6dbe974dadd18ca139e6bce183817ac609f73213aa8aaeae5f123d6b60000000000000000000ae80300000000000017a9144dd991d2f69eed133bb9d16e298703c830e1fb2387d00700000000000017a9147a50ac55b0af704dfffc797c507db803488ad44787b80b00000000000017a914caab97b53be0b75526e011bc49b0101365f611b887a00f00000000000017a91448c947e1b16103782a7dcba1dd5896936fbc7d2587881300000000000017a914ff075d852727e7e32ff5e11b13d254cb553fb73287701700000000000017a914761069764474d5ef5d0e068e88e4ebe2edd2336087581b00000000000017a914cd76c979ed6421f5d39380b5eb3d0dc7f56e864b87401f00000000000017a91417e7563571166469e14275be7ef00d91927eee0387282300000000000017a9140f9ddd36a76392fec584f05b34d33282fbd4921287102700000000000017a91417603536acce13cf7496387f8169a7f832f08f4c8700000000", +"CHECKTEMPLATEVERIFY"], + +["CTV at pos 2 with >1 Input Fails if scriptSig of other input modified"], +[[["eeda9ea077b04abec103ffbba6bcf41cd67cdfdabe5ccc6ed766b9cd4ed4808a", + 0, + "0x20 0x3e123dbe62352fa40471c195aebd3cdec43cca8728520c8a2d5737009fa05b0b OP_CHECKTEMPLATEVERIFY", + 155000], + ["b6d623f1e5eaaaa83a21739f60ac173818ce6b9e13ca18ddda74e9dbe6124c0b", 0, "1", 155000]], +"02000000020b4c12e6dbe974dadd18ca139e6bce183817ac609f73213aa8aaeae5f123d6b6000000000151000000008a80d44ecdb966d76ecc5cbedadf7cd61cf4bca6bbff03c1be4ab077a09edaee0000000000000000000ae80300000000000017a9144dd991d2f69eed133bb9d16e298703c830e1fb2387d00700000000000017a9147a50ac55b0af704dfffc797c507db803488ad44787b80b00000000000017a914caab97b53be0b75526e011bc49b0101365f611b887a00f00000000000017a91448c947e1b16103782a7dcba1dd5896936fbc7d2587881300000000000017a914ff075d852727e7e32ff5e11b13d254cb553fb73287701700000000000017a914761069764474d5ef5d0e068e88e4ebe2edd2336087581b00000000000017a914cd76c979ed6421f5d39380b5eb3d0dc7f56e864b87401f00000000000017a91417e7563571166469e14275be7ef00d91927eee0387282300000000000017a9140f9ddd36a76392fec584f05b34d33282fbd4921287102700000000000017a91417603536acce13cf7496387f8169a7f832f08f4c8700000000", +"CHECKTEMPLATEVERIFY"], + +["CTV at pos 1 with specific scriptsigs fails with incorrect scriptSig"], +[[["a2522fa96033c5736f3142ff616426cd03a3d0f077f609e22c5a33a96e04e597", + 0, + "0x20 0x4870387ef3dc7b392294140a323ec7b38dc138710f0931ce27f386a57128ea63 OP_CHECKTEMPLATEVERIFY", + 155000], + ["b6d623f1e5eaaaa83a21739f60ac173818ce6b9e13ca18ddda74e9dbe6124c0b", 0, "1", 155000]], +"020000000297e5046ea9335a2ce209f677f0d0a303cd266461ff42316f73c53360a92f52a2000000000151000000000b4c12e6dbe974dadd18ca139e6bce183817ac609f73213aa8aaeae5f123d6b6000000000151000000000ae80300000000000017a9143f163a8747557345ce2e6fe00c1894f2f281795e87d00700000000000017a9144cf13dfda93a7413b7e646611735656e5457657087b80b00000000000017a914868998b49df649c37a88d48c9d4a5b37290e507287a00f00000000000017a914034f9914a77571a6396482e9881745c92c3037c687881300000000000017a914a8238003e1732e2baf4334a8546d72be99af9bae87701700000000000017a91491dbac5d67d5941115a03fc7eaec09f31a5b4dfc87581b00000000000017a914e0c0f19fec3b2993b9c116c798b5429d4515596687401f00000000000017a914d6b40d98d94530f1a1eb57614680813c81a95ccd87282300000000000017a914fb0bfb072bb79611a4323981828108a3cf54b0a687102700000000000017a9149e2d11f06ba667e981b802af10be8dabd08eafff8700000000", +"CHECKTEMPLATEVERIFY"], + ["Make diffs cleaner by leaving a comment here without comma at the end"] ] From 201ebd868930cb4be22db04c023734f6af34e28c Mon Sep 17 00:00:00 2001 From: Jeremy Rubin Date: Sat, 11 Sep 2021 23:03:11 -0700 Subject: [PATCH 09/10] test: add CTV hash computation unit test & mutation tester Co-authored-by: James O'Beirne --- src/script/interpreter.cpp | 7 + src/test/CMakeLists.txt | 2 + src/test/ctvhash_tests.cpp | 198 ++++ src/test/data/ctvhash.json | 2204 ++++++++++++++++++++++++++++++++++++ 4 files changed, 2411 insertions(+) create mode 100644 src/test/ctvhash_tests.cpp create mode 100644 src/test/data/ctvhash.json diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index 59a0dcaec04..b032f4451f6 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -1489,6 +1489,13 @@ uint256 GetDefaultCheckTemplateVerifyHash( GetDefaultCheckTemplateVerifyHashWithScript(tx, outputs_hash, sequences_hash, GetScriptSigsSHA256(tx), input_index); } +template +uint256 GetDefaultCheckTemplateVerifyHash(const CTransaction& tx, const uint256& outputs_hash, const uint256& sequences_hash, + const uint32_t input_index); +template +uint256 GetDefaultCheckTemplateVerifyHash(const CMutableTransaction& tx, const uint256& outputs_hash, const uint256& sequences_hash, + const uint32_t input_index); + template void PrecomputedTransactionData::Init(const T& txTo, std::vector&& spent_outputs, bool force) { diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index 6d75344194f..ac608e6075e 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -34,6 +34,7 @@ add_executable(test_bitcoin compilerbug_tests.cpp compress_tests.cpp crypto_tests.cpp + ctvhash_tests.cpp cuckoocache_tests.cpp dbwrapper_tests.cpp denialofservice_tests.cpp @@ -129,6 +130,7 @@ target_json_data_sources(test_bitcoin data/base58_encode_decode.json data/bip341_wallet_vectors.json data/blockfilters.json + data/ctvhash.json data/key_io_invalid.json data/key_io_valid.json data/script_tests.json diff --git a/src/test/ctvhash_tests.cpp b/src/test/ctvhash_tests.cpp new file mode 100644 index 00000000000..f3f3d49a1f5 --- /dev/null +++ b/src/test/ctvhash_tests.cpp @@ -0,0 +1,198 @@ +// Copyright (c) 2013-2021 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include +#include +#include +#include +#include