Skip to content

Commit 4aad8c1

Browse files
committed
script: cache transaction weight per-transaction
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.
1 parent 338ccc4 commit 4aad8c1

File tree

2 files changed

+10
-14
lines changed

2 files changed

+10
-14
lines changed

src/script/interpreter.cpp

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2020,7 +2020,12 @@ bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript&
20202020
}
20212021
case OP_TXWEIGHT:
20222022
{
2023-
push8_le(stack, checker.GetTxWeight());
2023+
const PrecomputedTransactionData *cache = checker.GetPrecomputedTransactionData();
2024+
// Return error if the evaluation context is unavailable
2025+
// TODO: Handle accoding to MissingDataBehavior
2026+
if (!cache || !cache->m_bip341_taproot_ready)
2027+
return set_error(serror, SCRIPT_ERR_INTROSPECT_CONTEXT_UNAVAILABLE);
2028+
push8_le(stack, cache->m_tx_weight);
20242029
break;
20252030
}
20262031
default: assert(!"invalid opcode"); break;
@@ -2581,6 +2586,9 @@ void PrecomputedTransactionData::Init(const T& txTo, std::vector<CTxOut>&& spent
25812586
m_bip143_segwit_ready = true;
25822587
}
25832588
if (uses_bip341_taproot) {
2589+
// line copied from GetTransactionWeight() in src/consensus/validation.h
2590+
// (we cannot directly use that function for type reasons)
2591+
m_tx_weight = ::GetSerializeSize(txTo, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR - 1) + ::GetSerializeSize(txTo, PROTOCOL_VERSION);
25842592
m_outpoints_flag_single_hash = GetOutpointFlagsSHA256(txTo);
25852593
m_spent_asset_amounts_single_hash = GetSpentAssetsAmountsSHA256(m_spent_outputs);
25862594
m_issuance_rangeproofs_single_hash = GetIssuanceRangeproofsSHA256(txTo);
@@ -2993,13 +3001,6 @@ const std::vector<CTxOut>* GenericTransactionSignatureChecker<T>::GetTxvOut() co
29933001
return &(txTo->vout);
29943002
}
29953003

2996-
template <class T>
2997-
uint64_t GenericTransactionSignatureChecker<T>::GetTxWeight() const
2998-
{
2999-
// line copied from GetTransactionWeight() in src/consensus/validation.h
3000-
return ::GetSerializeSize(*txTo, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR - 1) + ::GetSerializeSize(*txTo, PROTOCOL_VERSION);
3001-
}
3002-
30033004
template <class T>
30043005
const PrecomputedTransactionData* GenericTransactionSignatureChecker<T>::GetPrecomputedTransactionData() const
30053006
{

src/script/interpreter.h

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ struct PrecomputedTransactionData
168168
uint256 m_spent_amounts_single_hash;
169169
uint256 m_spent_scripts_single_hash;
170170
// Elements
171+
uint64_t m_tx_weight;
171172
uint256 m_outpoints_flag_single_hash;
172173
uint256 m_spent_asset_amounts_single_hash;
173174
uint256 m_issuances_single_hash;
@@ -293,11 +294,6 @@ class BaseSignatureChecker
293294
return 0;
294295
}
295296

296-
virtual uint64_t GetTxWeight() const
297-
{
298-
return 0;
299-
}
300-
301297
virtual const PrecomputedTransactionData* GetPrecomputedTransactionData() const
302298
{
303299
return nullptr;
@@ -335,7 +331,6 @@ class GenericTransactionSignatureChecker : public BaseSignatureChecker
335331
const std::vector<CTxOut>* GetTxvOut() const override;
336332
uint32_t GetLockTime() const override;
337333
int32_t GetTxVersion() const override;
338-
uint64_t GetTxWeight() const override;
339334

340335
const PrecomputedTransactionData* GetPrecomputedTransactionData() const override;
341336
uint32_t GetnIn() const override;

0 commit comments

Comments
 (0)