@@ -606,7 +606,39 @@ bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript&
606606 break ;
607607 }
608608
609- case OP_NOP1: case OP_NOP4: case OP_NOP5:
609+ case OP_CHECKTEMPLATEVERIFY:
610+ {
611+ // if flags not enabled; treat as a NOP4
612+ if (!(flags & SCRIPT_VERIFY_DEFAULT_CHECK_TEMPLATE_VERIFY_HASH)) {
613+ if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS)
614+ return set_error (serror, SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS);
615+ break ;
616+ }
617+
618+ if (stack.size () < 1 )
619+ return set_error (serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
620+
621+ // If the argument was not 32 bytes, treat as OP_NOP4:
622+ switch (stack.back ().size ()) {
623+ case 32 :
624+ {
625+ const Span<const unsigned char > hash{stack.back ()};
626+ if (!checker.CheckDefaultCheckTemplateVerifyHash (hash)) {
627+ return set_error (serror, SCRIPT_ERR_TEMPLATE_MISMATCH);
628+ }
629+ break ;
630+ }
631+ default :
632+ // future upgrade can add semantics for this opcode with different length args
633+ // so discourage use when applicable
634+ if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) {
635+ return set_error (serror, SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS);
636+ }
637+ }
638+ }
639+ break ;
640+
641+ case OP_NOP1: case OP_NOP5:
610642 case OP_NOP6: case OP_NOP7: case OP_NOP8: case OP_NOP9: case OP_NOP10:
611643 {
612644 if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS)
@@ -1406,12 +1438,79 @@ uint256 GetSpentScriptsSHA256(const std::vector<CTxOut>& outputs_spent)
14061438 return ss.GetSHA256 ();
14071439}
14081440
1441+ /* * Compute the (single) SHA256 of the concatenation of all scriptSigs in a tx. */
1442+ template <class T >
1443+ uint256 GetScriptSigsSHA256 (const T& txTo)
1444+ {
1445+ CHashWriter ss (SER_GETHASH, 0 );
1446+ for (const auto & in : txTo.vin ) {
1447+ ss << in.scriptSig ;
1448+ }
1449+ return ss.GetSHA256 ();
1450+ }
1451+
1452+ /* Not Exported, just convenience */
1453+ template <typename TxType>
1454+ uint256 GetDefaultCheckTemplateVerifyHashWithScript (const TxType& tx, const uint256& outputs_hash, const uint256& sequences_hash,
1455+ const uint256& scriptSig_hash, const uint32_t input_index) {
1456+ auto h = CHashWriter (SER_GETHASH, 0 )
1457+ << tx.nVersion
1458+ << tx.nLockTime
1459+ << scriptSig_hash
1460+ << uint32_t (tx.vin .size ())
1461+ << sequences_hash
1462+ << uint32_t (tx.vout .size ())
1463+ << outputs_hash
1464+ << input_index;
1465+ return h.GetSHA256 ();
1466+ }
1467+
1468+ template <typename TxType>
1469+ uint256 GetDefaultCheckTemplateVerifyHashEmptyScript (const TxType& tx, const uint256& outputs_hash, const uint256& sequences_hash,
1470+ const uint32_t input_index) {
1471+ auto h = CHashWriter (SER_GETHASH, 0 )
1472+ << tx.nVersion
1473+ << tx.nLockTime
1474+ << uint32_t (tx.vin .size ())
1475+ << sequences_hash
1476+ << uint32_t (tx.vout .size ())
1477+ << outputs_hash
1478+ << input_index;
1479+ return h.GetSHA256 ();
1480+ }
14091481
14101482} // namespace
14111483
1484+ template <typename TxType>
1485+ uint256 GetDefaultCheckTemplateVerifyHash (const TxType& tx, uint32_t input_index) {
1486+ return GetDefaultCheckTemplateVerifyHash (tx, GetOutputsSHA256 (tx), GetSequencesSHA256 (tx), input_index);
1487+ }
1488+
1489+ template <typename TxType>
1490+ static bool NoScriptSigs (const TxType& tx)
1491+ {
1492+ return std::all_of (tx.vin .begin (), tx.vin .end (), [](const CTxIn& c) { return c.scriptSig .empty (); });
1493+ }
1494+
1495+ template <typename TxType>
1496+ uint256 GetDefaultCheckTemplateVerifyHash (const TxType& tx, const uint256& outputs_hash, const uint256& sequences_hash,
1497+ const uint32_t input_index) {
1498+ return NoScriptSigs (tx) ? GetDefaultCheckTemplateVerifyHashEmptyScript (tx, outputs_hash, sequences_hash, input_index) :
1499+ GetDefaultCheckTemplateVerifyHashWithScript (tx, outputs_hash, sequences_hash, GetScriptSigsSHA256 (tx), input_index);
1500+ }
1501+
1502+ template
1503+ uint256 GetDefaultCheckTemplateVerifyHash (const CTransaction& tx, const uint256& outputs_hash, const uint256& sequences_hash,
1504+ const uint32_t input_index);
1505+ template
1506+ uint256 GetDefaultCheckTemplateVerifyHash (const CMutableTransaction& tx, const uint256& outputs_hash, const uint256& sequences_hash,
1507+ const uint32_t input_index);
1508+
14121509template <class T >
1413- void PrecomputedTransactionData::Init (const T& txTo, std::vector<CTxOut>&& spent_outputs, bool force)
1510+ void PrecomputedTransactionData::Init (const T& txTo, std::vector<CTxOut>&& spent_outputs, bool force, PrecomputedTransactionData:: bip_119_cache_synchronizer_t f )
14141511{
1512+ // Do not allow overriding a sync function if one is already set
1513+ if (m_bip119_cache_synchronizer) assert (f == nullptr );
14151514 assert (!m_spent_outputs_ready);
14161515
14171516 m_spent_outputs = std::move (spent_outputs);
@@ -1459,19 +1558,60 @@ void PrecomputedTransactionData::Init(const T& txTo, std::vector<CTxOut>&& spent
14591558 m_spent_scripts_single_hash = GetSpentScriptsSHA256 (m_spent_outputs);
14601559 m_bip341_taproot_ready = true ;
14611560 }
1561+
1562+ if (force) {
1563+ // Eagerly compute BIP119 state
1564+ BIP119EagerInit (txTo);
1565+ // Disable Lazy Sync Wrapper
1566+ m_bip119_cache_synchronizer = nullptr ;
1567+ } else if (!m_bip119_cache_synchronizer) {
1568+ // If no function was provided, assume that we are single-threaded but
1569+ // still cache-on-first-use
1570+ auto single_threaded = [&](std::function<void ()> f)
1571+ {
1572+ f ();
1573+ // disables future calls from recomputing
1574+ m_bip119_cache_synchronizer = nullptr ;
1575+ };
1576+ m_bip119_cache_synchronizer = single_threaded;
1577+ }
1578+ }
1579+
1580+ template <class T >
1581+ void PrecomputedTransactionData::BIP119EagerInit (const T& txTo)
1582+ {
1583+ if (!(m_bip143_segwit_ready || m_bip341_taproot_ready)) {
1584+ m_prevouts_single_hash = GetPrevoutsSHA256 (txTo);
1585+ m_sequences_single_hash = GetSequencesSHA256 (txTo);
1586+ m_outputs_single_hash = GetOutputsSHA256 (txTo);
1587+ }
1588+ // 0 hash used to signal if we should skip scriptSigs
1589+ // when re-computing for different indexes.
1590+ m_scriptSigs_single_hash = NoScriptSigs (txTo) ? uint256{} : GetScriptSigsSHA256 (txTo);
1591+ }
1592+ template <class T >
1593+ void PrecomputedTransactionData::BIP119LazyInit (const T& txTo)
1594+ {
1595+ if (m_bip119_cache_synchronizer) {
1596+ m_bip119_cache_synchronizer ([&]() {
1597+ BIP119EagerInit (txTo);
1598+ });
1599+ }
14621600}
14631601
14641602template <class T >
1465- PrecomputedTransactionData::PrecomputedTransactionData (const T& txTo)
1603+ PrecomputedTransactionData::PrecomputedTransactionData (const T& txTo, PrecomputedTransactionData:: bip_119_cache_synchronizer_t f) : m_bip119_cache_synchronizer(f )
14661604{
14671605 Init (txTo, {});
14681606}
14691607
14701608// explicit instantiation
1471- template void PrecomputedTransactionData::Init (const CTransaction& txTo, std::vector<CTxOut>&& spent_outputs, bool force);
1472- template void PrecomputedTransactionData::Init (const CMutableTransaction& txTo, std::vector<CTxOut>&& spent_outputs, bool force);
1473- template PrecomputedTransactionData::PrecomputedTransactionData(const CTransaction& txTo);
1474- template PrecomputedTransactionData::PrecomputedTransactionData(const CMutableTransaction& txTo);
1609+ template void PrecomputedTransactionData::Init (const CTransaction& txTo, std::vector<CTxOut>&& spent_outputs, bool force, PrecomputedTransactionData::bip_119_cache_synchronizer_t f);
1610+ template void PrecomputedTransactionData::Init (const CMutableTransaction& txTo, std::vector<CTxOut>&& spent_outputs, bool force, PrecomputedTransactionData::bip_119_cache_synchronizer_t f);
1611+ template void PrecomputedTransactionData::BIP119LazyInit (const CTransaction& txTo);
1612+ template void PrecomputedTransactionData::BIP119LazyInit (const CMutableTransaction& txTo);
1613+ template PrecomputedTransactionData::PrecomputedTransactionData(const CTransaction& txTo, PrecomputedTransactionData::bip_119_cache_synchronizer_t f);
1614+ template PrecomputedTransactionData::PrecomputedTransactionData(const CMutableTransaction& txTo, PrecomputedTransactionData::bip_119_cache_synchronizer_t f);
14751615
14761616const HashWriter HASHER_TAPSIGHASH{TaggedHash (" TapSighash" )};
14771617const HashWriter HASHER_TAPLEAF{TaggedHash (" TapLeaf" )};
@@ -1815,6 +1955,23 @@ bool GenericTransactionSignatureChecker<T>::CheckSequence(const CScriptNum& nSeq
18151955 return true ;
18161956}
18171957
1958+ template <class T >
1959+ bool GenericTransactionSignatureChecker<T>::CheckDefaultCheckTemplateVerifyHash(const Span<const unsigned char >& hash) const
1960+ {
1961+ // Should already be checked before calling...
1962+ assert (hash.size () == 32 );
1963+ if (txdata && txTo) {
1964+ txdata->BIP119LazyInit (*txTo);
1965+ uint256 hash_tmpl = txdata->m_scriptSigs_single_hash .IsNull () ?
1966+ GetDefaultCheckTemplateVerifyHashEmptyScript (*txTo, txdata->m_outputs_single_hash , txdata->m_sequences_single_hash , nIn) :
1967+ GetDefaultCheckTemplateVerifyHashWithScript (*txTo, txdata->m_outputs_single_hash , txdata->m_sequences_single_hash ,
1968+ txdata->m_scriptSigs_single_hash , nIn);
1969+ return std::equal (hash_tmpl.begin (), hash_tmpl.end (), hash.data ());
1970+ } else {
1971+ return HandleMissingData (m_mdb);
1972+ }
1973+ }
1974+
18181975// explicit instantiation
18191976template class GenericTransactionSignatureChecker <CTransaction>;
18201977template class GenericTransactionSignatureChecker <CMutableTransaction>;
0 commit comments