Merge ElementsProject/elements#1032: script: cache transaction weight per-transaction

4aad8c1a14 script: cache transaction weight per-transaction (Andrew Poelstra)

Pull request description:

  This is an O(N) operation so we want to make sure that we're not recomputing
  it every time we hit the INSPECTTXWEIGHT opcode.

ACKs for top commit:
  sanket1729:
    Cr ACK 4aad8c1a14

Tree-SHA512: c6bf6db748ede3f29c1294363a9415b54252bec784cfe270d8db1e7d845dc680fc9af37ad3ceaa33f9439c1dcdfde683a15fa3086fe79f50fdc487bfbf602921
This commit is contained in:
Andrew Poelstra 2021-09-05 18:01:59 +00:00
commit 904054ffcb
No known key found for this signature in database
GPG key ID: C588D63CE41B97C1
2 changed files with 10 additions and 14 deletions

View file

@ -2020,7 +2020,12 @@ bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript&
}
case OP_TXWEIGHT:
{
push8_le(stack, checker.GetTxWeight());
const PrecomputedTransactionData *cache = checker.GetPrecomputedTransactionData();
// Return error if the evaluation context is unavailable
// TODO: Handle accoding to MissingDataBehavior
if (!cache || !cache->m_bip341_taproot_ready)
return set_error(serror, SCRIPT_ERR_INTROSPECT_CONTEXT_UNAVAILABLE);
push8_le(stack, cache->m_tx_weight);
break;
}
default: assert(!"invalid opcode"); break;
@ -2581,6 +2586,9 @@ void PrecomputedTransactionData::Init(const T& txTo, std::vector<CTxOut>&& spent
m_bip143_segwit_ready = true;
}
if (uses_bip341_taproot) {
// line copied from GetTransactionWeight() in src/consensus/validation.h
// (we cannot directly use that function for type reasons)
m_tx_weight = ::GetSerializeSize(txTo, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR - 1) + ::GetSerializeSize(txTo, PROTOCOL_VERSION);
m_outpoints_flag_single_hash = GetOutpointFlagsSHA256(txTo);
m_spent_asset_amounts_single_hash = GetSpentAssetsAmountsSHA256(m_spent_outputs);
m_issuance_rangeproofs_single_hash = GetIssuanceRangeproofsSHA256(txTo);
@ -2993,13 +3001,6 @@ const std::vector<CTxOut>* GenericTransactionSignatureChecker<T>::GetTxvOut() co
return &(txTo->vout);
}
template <class T>
uint64_t GenericTransactionSignatureChecker<T>::GetTxWeight() const
{
// line copied from GetTransactionWeight() in src/consensus/validation.h
return ::GetSerializeSize(*txTo, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR - 1) + ::GetSerializeSize(*txTo, PROTOCOL_VERSION);
}
template <class T>
const PrecomputedTransactionData* GenericTransactionSignatureChecker<T>::GetPrecomputedTransactionData() const
{

View file

@ -168,6 +168,7 @@ struct PrecomputedTransactionData
uint256 m_spent_amounts_single_hash;
uint256 m_spent_scripts_single_hash;
// Elements
uint64_t m_tx_weight;
uint256 m_outpoints_flag_single_hash;
uint256 m_spent_asset_amounts_single_hash;
uint256 m_issuances_single_hash;
@ -293,11 +294,6 @@ public:
return 0;
}
virtual uint64_t GetTxWeight() const
{
return 0;
}
virtual const PrecomputedTransactionData* GetPrecomputedTransactionData() const
{
return nullptr;
@ -335,7 +331,6 @@ public:
const std::vector<CTxOut>* GetTxvOut() const override;
uint32_t GetLockTime() const override;
int32_t GetTxVersion() const override;
uint64_t GetTxWeight() const override;
const PrecomputedTransactionData* GetPrecomputedTransactionData() const override;
uint32_t GetnIn() const override;