Skip to content

Commit 3f8dbcd

Browse files
author
MarcoFalke
committed
Merge #16658: validation: Rename CheckInputs to CheckInputScripts
3bd8db8 [validation] fix comments in CheckInputScripts() (John Newbery) 6f6465c scripted-diff: [validation] Rename CheckInputs to CheckInputScripts (John Newbery) Pull request description: CheckInputs() used to check no double spends, scripts & sigs and amounts. Since 832e074, the double spend and amount checks have been moved to CheckTxInputs(), and CheckInputs() now just validates input scripts. Rename the function to CheckInputScripts(). Also fix incorrect comments. ACKs for top commit: MarcoFalke: re-ACK 3bd8db8, did the rebase myself, checked the scripted diff 👡 promag: ACK 3bd8db8 :trollface: Tree-SHA512: 7b3f8597d210492798fb784ee8ea47ea6377519111190161c7cc34a967509013f4337304f52e9bedc97b7710de7b0ff8880e08cd7f867754567f82e7b02c794c
2 parents 0655c7a + 3bd8db8 commit 3f8dbcd

File tree

5 files changed

+41
-39
lines changed

5 files changed

+41
-39
lines changed

src/script/standard.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ extern unsigned nMaxDatacarrierBytes;
4747
* but in the future other flags may be added, such as a soft-fork to enforce
4848
* strict DER encoding.
4949
*
50-
* Failing one of these tests may trigger a DoS ban - see CheckInputs() for
50+
* Failing one of these tests may trigger a DoS ban - see CheckInputScripts() for
5151
* details.
5252
*/
5353
static const unsigned int MANDATORY_SCRIPT_VERIFY_FLAGS = SCRIPT_VERIFY_P2SH;

src/test/txvalidationcache_tests.cpp

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
#include <boost/test/unit_test.hpp>
1515

16-
bool CheckInputs(const CTransaction& tx, TxValidationState &state, const CCoinsViewCache &inputs, unsigned int flags, bool cacheSigStore, bool cacheFullScriptStore, PrecomputedTransactionData& txdata, std::vector<CScriptCheck> *pvChecks);
16+
bool CheckInputScripts(const CTransaction& tx, TxValidationState &state, const CCoinsViewCache &inputs, unsigned int flags, bool cacheSigStore, bool cacheFullScriptStore, PrecomputedTransactionData& txdata, std::vector<CScriptCheck> *pvChecks);
1717

1818
BOOST_AUTO_TEST_SUITE(tx_validationcache_tests)
1919

@@ -95,8 +95,8 @@ BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup)
9595
BOOST_CHECK_EQUAL(m_node.mempool->size(), 0U);
9696
}
9797

98-
// Run CheckInputs (using CoinsTip()) on the given transaction, for all script
99-
// flags. Test that CheckInputs passes for all flags that don't overlap with
98+
// Run CheckInputScripts (using CoinsTip()) on the given transaction, for all script
99+
// flags. Test that CheckInputScripts passes for all flags that don't overlap with
100100
// the failing_flags argument, but otherwise fails.
101101
// CHECKLOCKTIMEVERIFY and CHECKSEQUENCEVERIFY (and future NOP codes that may
102102
// get reassigned) have an interaction with DISCOURAGE_UPGRADABLE_NOPS: if
@@ -123,8 +123,8 @@ static void ValidateCheckInputsForAllFlags(const CTransaction &tx, uint32_t fail
123123
// WITNESS requires P2SH
124124
test_flags |= SCRIPT_VERIFY_P2SH;
125125
}
126-
bool ret = CheckInputs(tx, state, &::ChainstateActive().CoinsTip(), test_flags, true, add_to_cache, txdata, nullptr);
127-
// CheckInputs should succeed iff test_flags doesn't intersect with
126+
bool ret = CheckInputScripts(tx, state, &::ChainstateActive().CoinsTip(), test_flags, true, add_to_cache, txdata, nullptr);
127+
// CheckInputScripts should succeed iff test_flags doesn't intersect with
128128
// failing_flags
129129
bool expected_return_value = !(test_flags & failing_flags);
130130
BOOST_CHECK_EQUAL(ret, expected_return_value);
@@ -133,21 +133,21 @@ static void ValidateCheckInputsForAllFlags(const CTransaction &tx, uint32_t fail
133133
if (ret && add_to_cache) {
134134
// Check that we get a cache hit if the tx was valid
135135
std::vector<CScriptCheck> scriptchecks;
136-
BOOST_CHECK(CheckInputs(tx, state, &::ChainstateActive().CoinsTip(), test_flags, true, add_to_cache, txdata, &scriptchecks));
136+
BOOST_CHECK(CheckInputScripts(tx, state, &::ChainstateActive().CoinsTip(), test_flags, true, add_to_cache, txdata, &scriptchecks));
137137
BOOST_CHECK(scriptchecks.empty());
138138
} else {
139139
// Check that we get script executions to check, if the transaction
140140
// was invalid, or we didn't add to cache.
141141
std::vector<CScriptCheck> scriptchecks;
142-
BOOST_CHECK(CheckInputs(tx, state, &::ChainstateActive().CoinsTip(), test_flags, true, add_to_cache, txdata, &scriptchecks));
142+
BOOST_CHECK(CheckInputScripts(tx, state, &::ChainstateActive().CoinsTip(), test_flags, true, add_to_cache, txdata, &scriptchecks));
143143
BOOST_CHECK_EQUAL(scriptchecks.size(), tx.vin.size());
144144
}
145145
}
146146
}
147147

148148
BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup)
149149
{
150-
// Test that passing CheckInputs with one set of script flags doesn't imply
150+
// Test that passing CheckInputScripts with one set of script flags doesn't imply
151151
// that we would pass again with a different set of flags.
152152
{
153153
LOCK(cs_main);
@@ -202,16 +202,16 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup)
202202
TxValidationState state;
203203
PrecomputedTransactionData ptd_spend_tx(spend_tx);
204204

205-
BOOST_CHECK(!CheckInputs(CTransaction(spend_tx), state, &::ChainstateActive().CoinsTip(), SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_DERSIG, true, true, ptd_spend_tx, nullptr));
205+
BOOST_CHECK(!CheckInputScripts(CTransaction(spend_tx), state, &::ChainstateActive().CoinsTip(), SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_DERSIG, true, true, ptd_spend_tx, nullptr));
206206

207207
// If we call again asking for scriptchecks (as happens in
208208
// ConnectBlock), we should add a script check object for this -- we're
209209
// not caching invalidity (if that changes, delete this test case).
210210
std::vector<CScriptCheck> scriptchecks;
211-
BOOST_CHECK(CheckInputs(CTransaction(spend_tx), state, &::ChainstateActive().CoinsTip(), SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_DERSIG, true, true, ptd_spend_tx, &scriptchecks));
211+
BOOST_CHECK(CheckInputScripts(CTransaction(spend_tx), state, &::ChainstateActive().CoinsTip(), SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_DERSIG, true, true, ptd_spend_tx, &scriptchecks));
212212
BOOST_CHECK_EQUAL(scriptchecks.size(), 1U);
213213

214-
// Test that CheckInputs returns true iff DERSIG-enforcing flags are
214+
// Test that CheckInputScripts returns true iff DERSIG-enforcing flags are
215215
// not present. Don't add these checks to the cache, so that we can
216216
// test later that block validation works fine in the absence of cached
217217
// successes.
@@ -270,7 +270,7 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup)
270270
invalid_with_cltv_tx.vin[0].scriptSig = CScript() << vchSig << 100;
271271
TxValidationState state;
272272
PrecomputedTransactionData txdata(invalid_with_cltv_tx);
273-
BOOST_CHECK(CheckInputs(CTransaction(invalid_with_cltv_tx), state, ::ChainstateActive().CoinsTip(), SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY, true, true, txdata, nullptr));
273+
BOOST_CHECK(CheckInputScripts(CTransaction(invalid_with_cltv_tx), state, ::ChainstateActive().CoinsTip(), SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY, true, true, txdata, nullptr));
274274
}
275275

276276
// TEST CHECKSEQUENCEVERIFY
@@ -298,12 +298,12 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup)
298298
invalid_with_csv_tx.vin[0].scriptSig = CScript() << vchSig << 100;
299299
TxValidationState state;
300300
PrecomputedTransactionData txdata(invalid_with_csv_tx);
301-
BOOST_CHECK(CheckInputs(CTransaction(invalid_with_csv_tx), state, &::ChainstateActive().CoinsTip(), SCRIPT_VERIFY_CHECKSEQUENCEVERIFY, true, true, txdata, nullptr));
301+
BOOST_CHECK(CheckInputScripts(CTransaction(invalid_with_csv_tx), state, &::ChainstateActive().CoinsTip(), SCRIPT_VERIFY_CHECKSEQUENCEVERIFY, true, true, txdata, nullptr));
302302
}
303303

304304
// TODO: add tests for remaining script flags
305305

306-
// Test that passing CheckInputs with a valid witness doesn't imply success
306+
// Test that passing CheckInputScripts with a valid witness doesn't imply success
307307
// for the same tx with a different witness.
308308
{
309309
CMutableTransaction valid_with_witness_tx;
@@ -360,12 +360,12 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup)
360360
TxValidationState state;
361361
PrecomputedTransactionData txdata(tx);
362362
// This transaction is now invalid under segwit, because of the second input.
363-
BOOST_CHECK(!CheckInputs(CTransaction(tx), state, &::ChainstateActive().CoinsTip(), SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, true, true, txdata, nullptr));
363+
BOOST_CHECK(!CheckInputScripts(CTransaction(tx), state, &::ChainstateActive().CoinsTip(), SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, true, true, txdata, nullptr));
364364

365365
std::vector<CScriptCheck> scriptchecks;
366366
// Make sure this transaction was not cached (ie because the first
367367
// input was valid)
368-
BOOST_CHECK(CheckInputs(CTransaction(tx), state, &::ChainstateActive().CoinsTip(), SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, true, true, txdata, &scriptchecks));
368+
BOOST_CHECK(CheckInputScripts(CTransaction(tx), state, &::ChainstateActive().CoinsTip(), SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, true, true, txdata, &scriptchecks));
369369
// Should get 2 script checks back -- caching is on a whole-transaction basis.
370370
BOOST_CHECK_EQUAL(scriptchecks.size(), 2U);
371371
}

src/validation.cpp

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ std::unique_ptr<CBlockTreeDB> pblocktree;
180180
// See definition for documentation
181181
static void FindFilesToPruneManual(std::set<int>& setFilesToPrune, int nManualPruneHeight);
182182
static void FindFilesToPrune(std::set<int>& setFilesToPrune, uint64_t nPruneAfterHeight);
183-
bool CheckInputs(const CTransaction& tx, TxValidationState &state, const CCoinsViewCache &inputs, unsigned int flags, bool cacheSigStore, bool cacheFullScriptStore, PrecomputedTransactionData& txdata, std::vector<CScriptCheck> *pvChecks = nullptr);
183+
bool CheckInputScripts(const CTransaction& tx, TxValidationState &state, const CCoinsViewCache &inputs, unsigned int flags, bool cacheSigStore, bool cacheFullScriptStore, PrecomputedTransactionData& txdata, std::vector<CScriptCheck> *pvChecks = nullptr);
184184
static FILE* OpenUndoFile(const FlatFilePos &pos, bool fReadOnly = false);
185185
static FlatFileSeq BlockFileSeq();
186186
static FlatFileSeq UndoFileSeq();
@@ -396,19 +396,19 @@ static bool CheckInputsFromMempoolAndCache(const CTransaction& tx, TxValidationS
396396

397397
// pool.cs should be locked already, but go ahead and re-take the lock here
398398
// to enforce that mempool doesn't change between when we check the view
399-
// and when we actually call through to CheckInputs
399+
// and when we actually call through to CheckInputScripts
400400
LOCK(pool.cs);
401401

402402
assert(!tx.IsCoinBase());
403403
for (const CTxIn& txin : tx.vin) {
404404
const Coin& coin = view.AccessCoin(txin.prevout);
405405

406-
// At this point we haven't actually checked if the coins are all
407-
// available (or shouldn't assume we have, since CheckInputs does).
408-
// So we just return failure if the inputs are not available here,
409-
// and then only have to check equivalence for available inputs.
406+
// AcceptToMemoryPoolWorker has already checked that the coins are
407+
// available, so this shouldn't fail. If the inputs are not available
408+
// here then return false.
410409
if (coin.IsSpent()) return false;
411410

411+
// Check equivalence for available inputs.
412412
const CTransactionRef& txFrom = pool.get(txin.prevout.hash);
413413
if (txFrom) {
414414
assert(txFrom->GetHash() == txin.prevout.hash);
@@ -421,8 +421,8 @@ static bool CheckInputsFromMempoolAndCache(const CTransaction& tx, TxValidationS
421421
}
422422
}
423423

424-
// Call CheckInputs() to cache signature and script validity against current tip consensus rules.
425-
return CheckInputs(tx, state, view, flags, /* cacheSigStore = */ true, /* cacheFullSciptStore = */ true, txdata);
424+
// Call CheckInputScripts() to cache signature and script validity against current tip consensus rules.
425+
return CheckInputScripts(tx, state, view, flags, /* cacheSigStore = */ true, /* cacheFullSciptStore = */ true, txdata);
426426
}
427427

428428
namespace {
@@ -906,20 +906,20 @@ bool MemPoolAccept::PolicyScriptChecks(ATMPArgs& args, Workspace& ws, Precompute
906906

907907
constexpr unsigned int scriptVerifyFlags = STANDARD_SCRIPT_VERIFY_FLAGS;
908908

909-
// Check against previous transactions
909+
// Check input scripts and signatures.
910910
// This is done last to help prevent CPU exhaustion denial-of-service attacks.
911-
if (!CheckInputs(tx, state, m_view, scriptVerifyFlags, true, false, txdata)) {
911+
if (!CheckInputScripts(tx, state, m_view, scriptVerifyFlags, true, false, txdata)) {
912912
// SCRIPT_VERIFY_CLEANSTACK requires SCRIPT_VERIFY_WITNESS, so we
913913
// need to turn both off, and compare against just turning off CLEANSTACK
914914
// to see if the failure is specifically due to witness validation.
915-
TxValidationState state_dummy; // Want reported failures to be from first CheckInputs
916-
if (!tx.HasWitness() && CheckInputs(tx, state_dummy, m_view, scriptVerifyFlags & ~(SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_CLEANSTACK), true, false, txdata) &&
917-
!CheckInputs(tx, state_dummy, m_view, scriptVerifyFlags & ~SCRIPT_VERIFY_CLEANSTACK, true, false, txdata)) {
915+
TxValidationState state_dummy; // Want reported failures to be from first CheckInputScripts
916+
if (!tx.HasWitness() && CheckInputScripts(tx, state_dummy, m_view, scriptVerifyFlags & ~(SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_CLEANSTACK), true, false, txdata) &&
917+
!CheckInputScripts(tx, state_dummy, m_view, scriptVerifyFlags & ~SCRIPT_VERIFY_CLEANSTACK, true, false, txdata)) {
918918
// Only the witness is missing, so the transaction itself may be fine.
919919
state.Invalid(TxValidationResult::TX_WITNESS_MUTATED,
920920
state.GetRejectReason(), state.GetDebugMessage());
921921
}
922-
return false; // state filled in by CheckInputs
922+
return false; // state filled in by CheckInputScripts
923923
}
924924

925925
return true;
@@ -950,7 +950,7 @@ bool MemPoolAccept::ConsensusScriptChecks(ATMPArgs& args, Workspace& ws, Precomp
950950
// transactions into the mempool can be exploited as a DoS attack.
951951
unsigned int currentBlockScriptVerifyFlags = GetBlockScriptFlags(::ChainActive().Tip(), chainparams.GetConsensus());
952952
if (!CheckInputsFromMempoolAndCache(tx, state, m_view, m_pool, currentBlockScriptVerifyFlags, txdata)) {
953-
return error("%s: BUG! PLEASE REPORT THIS! CheckInputs failed against latest-block but not STANDARD flags %s, %s",
953+
return error("%s: BUG! PLEASE REPORT THIS! CheckInputScripts failed against latest-block but not STANDARD flags %s, %s",
954954
__func__, hash.ToString(), FormatStateMessage(state));
955955
}
956956

@@ -1466,8 +1466,10 @@ void InitScriptExecutionCache() {
14661466
}
14671467

14681468
/**
1469-
* Check whether all inputs of this transaction are valid (no double spends, scripts & sigs, amounts)
1470-
* This does not modify the UTXO set.
1469+
* Check whether all of this transaction's input scripts succeed.
1470+
*
1471+
* This involves ECDSA signature checks so can be computationally intensive. This function should
1472+
* only be called after the cheap sanity checks in CheckTxInputs passed.
14711473
*
14721474
* If pvChecks is not nullptr, script checks are pushed onto it instead of being performed inline. Any
14731475
* script checks which are not necessary (eg due to script execution cache hits) are, obviously,
@@ -1482,7 +1484,7 @@ void InitScriptExecutionCache() {
14821484
*
14831485
* Non-static (and re-declared) in src/test/txvalidationcache_tests.cpp
14841486
*/
1485-
bool CheckInputs(const CTransaction& tx, TxValidationState &state, const CCoinsViewCache &inputs, unsigned int flags, bool cacheSigStore, bool cacheFullScriptStore, PrecomputedTransactionData& txdata, std::vector<CScriptCheck> *pvChecks) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
1487+
bool CheckInputScripts(const CTransaction& tx, TxValidationState &state, const CCoinsViewCache &inputs, unsigned int flags, bool cacheSigStore, bool cacheFullScriptStore, PrecomputedTransactionData& txdata, std::vector<CScriptCheck> *pvChecks) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
14861488
{
14871489
if (tx.IsCoinBase()) return true;
14881490

@@ -2129,11 +2131,11 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,
21292131
std::vector<CScriptCheck> vChecks;
21302132
bool fCacheResults = fJustCheck; /* Don't cache results if we're actually connecting blocks (still consult the cache, though) */
21312133
TxValidationState tx_state;
2132-
if (fScriptChecks && !CheckInputs(tx, tx_state, view, flags, fCacheResults, fCacheResults, txdata[i], g_parallel_script_checks ? &vChecks : nullptr)) {
2134+
if (fScriptChecks && !CheckInputScripts(tx, tx_state, view, flags, fCacheResults, fCacheResults, txdata[i], g_parallel_script_checks ? &vChecks : nullptr)) {
21332135
// Any transaction validation failure in ConnectBlock is a block consensus failure
21342136
state.Invalid(BlockValidationResult::BLOCK_CONSENSUS,
21352137
tx_state.GetRejectReason(), tx_state.GetDebugMessage());
2136-
return error("ConnectBlock(): CheckInputs on %s failed with %s",
2138+
return error("ConnectBlock(): CheckInputScripts on %s failed with %s",
21372139
tx.GetHash().ToString(), FormatStateMessage(state));
21382140
}
21392141
control.Add(vChecks);

test/functional/feature_cltv.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ def run_test(self):
135135
block.hashMerkleRoot = block.calc_merkle_root()
136136
block.solve()
137137

138-
with self.nodes[0].assert_debug_log(expected_msgs=['CheckInputs on {} failed with non-mandatory-script-verify-flag (Negative locktime)'.format(block.vtx[-1].hash)]):
138+
with self.nodes[0].assert_debug_log(expected_msgs=['CheckInputScripts on {} failed with non-mandatory-script-verify-flag (Negative locktime)'.format(block.vtx[-1].hash)]):
139139
self.nodes[0].p2p.send_and_ping(msg_block(block))
140140
assert_equal(int(self.nodes[0].getbestblockhash(), 16), tip)
141141
self.nodes[0].p2p.sync_with_ping()

test/functional/feature_dersig.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ def run_test(self):
120120
block.rehash()
121121
block.solve()
122122

123-
with self.nodes[0].assert_debug_log(expected_msgs=['CheckInputs on {} failed with non-mandatory-script-verify-flag (Non-canonical DER signature)'.format(block.vtx[-1].hash)]):
123+
with self.nodes[0].assert_debug_log(expected_msgs=['CheckInputScripts on {} failed with non-mandatory-script-verify-flag (Non-canonical DER signature)'.format(block.vtx[-1].hash)]):
124124
self.nodes[0].p2p.send_and_ping(msg_block(block))
125125
assert_equal(int(self.nodes[0].getbestblockhash(), 16), tip)
126126
self.nodes[0].p2p.sync_with_ping()

0 commit comments

Comments
 (0)