script: precompute the DefaultCheckTemplateVerifyHash

Co-authored-by: James O'Beirne <github@au92.org>
This commit is contained in:
Jeremy Rubin 2019-10-16 14:56:24 -07:00 committed by James O'Beirne
parent a11706203d
commit a0bd24e9cd
No known key found for this signature in database
GPG key ID: 7A935DADB2C44F05
2 changed files with 40 additions and 13 deletions

View file

@ -1531,12 +1531,19 @@ void PrecomputedTransactionData::Init(const T& txTo, std::vector<CTxOut>&& 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 evaluation.
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);
@ -1890,9 +1897,16 @@ bool GenericTransactionSignatureChecker<T>::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<CTransaction>;

View file

@ -161,6 +161,9 @@ bool CheckSignatureEncoding(const std::vector<unsigned char> &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<CTxOut> 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<CTxOut> m_spent_outputs;
//! Whether m_spent_outputs is initialized.
bool m_spent_outputs_ready = false;