diff options
author | Pieter Wuille <pieter@wuille.net> | 2020-09-11 14:33:00 -0700 |
---|---|---|
committer | Pieter Wuille <pieter@wuille.net> | 2020-10-12 02:06:32 -0700 |
commit | 5d62e3a68b6ea9bb03556ee1fbf5678f20be01a2 (patch) | |
tree | de9e5600c4d2a5718861b4331df2344fd8c47838 /src/validation.cpp | |
parent | 8bd2b4e78452ff69c08c37acf164a6b80e503f13 (diff) | |
download | bitcoin-5d62e3a68b6ea9bb03556ee1fbf5678f20be01a2.tar.xz |
refactor: keep spent outputs in PrecomputedTransactionData
A BIP-341 signature message may commit to the scriptPubKeys and amounts
of all spent outputs (including other ones than the input being signed
for spends), so keep them available to signature hashing code.
Diffstat (limited to 'src/validation.cpp')
-rw-r--r-- | src/validation.cpp | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/src/validation.cpp b/src/validation.cpp index e9c0607ced..2090d9477f 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -1539,13 +1539,20 @@ bool CheckInputScripts(const CTransaction& tx, TxValidationState &state, const C } if (!txdata.m_ready) { - txdata.Init(tx); + std::vector<CTxOut> spent_outputs; + spent_outputs.reserve(tx.vin.size()); + + for (const auto& txin : tx.vin) { + const COutPoint& prevout = txin.prevout; + const Coin& coin = inputs.AccessCoin(prevout); + assert(!coin.IsSpent()); + spent_outputs.emplace_back(coin.out); + } + txdata.Init(tx, std::move(spent_outputs)); } + assert(txdata.m_spent_outputs.size() == tx.vin.size()); for (unsigned int i = 0; i < tx.vin.size(); i++) { - const COutPoint &prevout = tx.vin[i].prevout; - const Coin& coin = inputs.AccessCoin(prevout); - assert(!coin.IsSpent()); // We very carefully only pass in things to CScriptCheck which // are clearly committed to by tx' witness hash. This provides @@ -1554,7 +1561,7 @@ bool CheckInputScripts(const CTransaction& tx, TxValidationState &state, const C // spent being checked as a part of CScriptCheck. // Verify signature - CScriptCheck check(coin.out, tx, i, flags, cacheSigStore, &txdata); + CScriptCheck check(txdata.m_spent_outputs[i], tx, i, flags, cacheSigStore, &txdata); if (pvChecks) { pvChecks->push_back(CScriptCheck()); check.swap(pvChecks->back()); @@ -1568,7 +1575,7 @@ bool CheckInputScripts(const CTransaction& tx, TxValidationState &state, const C // splitting the network between upgraded and // non-upgraded nodes by banning CONSENSUS-failing // data providers. - CScriptCheck check2(coin.out, tx, i, + CScriptCheck check2(txdata.m_spent_outputs[i], tx, i, flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS, cacheSigStore, &txdata); if (check2()) return state.Invalid(TxValidationResult::TX_NOT_STANDARD, strprintf("non-mandatory-script-verify-flag (%s)", ScriptErrorString(check.GetScriptError()))); |