Changeset View
Changeset View
Standalone View
Standalone View
src/test/txvalidationcache_tests.cpp
Show First 20 Lines • Show All 106 Lines • ▼ Show 20 Lines | void ValidateCheckInputsForAllFlags(const CMutableTransaction &mutableTx, | ||||
PrecomputedTransactionData txdata(tx); | PrecomputedTransactionData txdata(tx); | ||||
// If we add many more flags, this loop can get too expensive, but we can | // If we add many more flags, this loop can get too expensive, but we can | ||||
// rewrite in the future to randomly pick a set of flags to evaluate. | // rewrite in the future to randomly pick a set of flags to evaluate. | ||||
for (uint32_t test_flags = 0; test_flags < (1U << 17); test_flags += 1) { | for (uint32_t test_flags = 0; test_flags < (1U << 17); test_flags += 1) { | ||||
CValidationState state; | CValidationState state; | ||||
// Make sure the mandatory flags are enabled. | // Make sure the mandatory flags are enabled. | ||||
test_flags |= MANDATORY_SCRIPT_VERIFY_FLAGS; | test_flags |= MANDATORY_SCRIPT_VERIFY_FLAGS; | ||||
bool ret = CheckInputs(tx, state, pcoinsTip, true, test_flags, true, | bool ret = CheckInputs(tx, state, pcoinsTip.get(), true, test_flags, | ||||
add_to_cache, txdata, nullptr); | true, add_to_cache, txdata, nullptr); | ||||
// CheckInputs should succeed iff test_flags doesn't intersect with | // CheckInputs should succeed iff test_flags doesn't intersect with | ||||
// failing_flags | // failing_flags | ||||
bool expected_return_value = !(test_flags & failing_flags); | bool expected_return_value = !(test_flags & failing_flags); | ||||
if (expected_return_value && upgraded_nop) { | if (expected_return_value && upgraded_nop) { | ||||
// If the script flag being tested corresponds to an upgraded NOP, | // If the script flag being tested corresponds to an upgraded NOP, | ||||
// then script execution should fail if DISCOURAGE_UPGRADABLE_NOPS | // then script execution should fail if DISCOURAGE_UPGRADABLE_NOPS | ||||
// is set. | // is set. | ||||
expected_return_value = | expected_return_value = | ||||
!(test_flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS); | !(test_flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS); | ||||
} | } | ||||
BOOST_CHECK_EQUAL(ret, expected_return_value); | BOOST_CHECK_EQUAL(ret, expected_return_value); | ||||
// Test the caching | // Test the caching | ||||
if (ret && add_to_cache) { | if (ret && add_to_cache) { | ||||
// Check that we get a cache hit if the tx was valid | // Check that we get a cache hit if the tx was valid | ||||
std::vector<CScriptCheck> scriptchecks; | std::vector<CScriptCheck> scriptchecks; | ||||
BOOST_CHECK(CheckInputs(tx, state, pcoinsTip, true, test_flags, | BOOST_CHECK(CheckInputs(tx, state, pcoinsTip.get(), true, | ||||
true, add_to_cache, txdata, &scriptchecks)); | test_flags, true, add_to_cache, txdata, | ||||
&scriptchecks)); | |||||
BOOST_CHECK(scriptchecks.empty()); | BOOST_CHECK(scriptchecks.empty()); | ||||
} else { | } else { | ||||
// Check that we get script executions to check, if the transaction | // Check that we get script executions to check, if the transaction | ||||
// was invalid, or we didn't add to cache. | // was invalid, or we didn't add to cache. | ||||
std::vector<CScriptCheck> scriptchecks; | std::vector<CScriptCheck> scriptchecks; | ||||
BOOST_CHECK(CheckInputs(tx, state, pcoinsTip, true, test_flags, | BOOST_CHECK(CheckInputs(tx, state, pcoinsTip.get(), true, | ||||
true, add_to_cache, txdata, &scriptchecks)); | test_flags, true, add_to_cache, txdata, | ||||
&scriptchecks)); | |||||
BOOST_CHECK_EQUAL(scriptchecks.size(), tx.vin.size()); | BOOST_CHECK_EQUAL(scriptchecks.size(), tx.vin.size()); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup) { | BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup) { | ||||
// Test that passing CheckInputs with one set of script flags doesn't imply | // Test that passing CheckInputs with one set of script flags doesn't imply | ||||
// that we would pass again with a different set of flags. | // that we would pass again with a different set of flags. | ||||
▲ Show 20 Lines • Show All 52 Lines • ▼ Show 20 Lines | BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup) { | ||||
// Test that invalidity under a set of flags doesn't preclude validity under | // Test that invalidity under a set of flags doesn't preclude validity under | ||||
// other (eg consensus) flags. | // other (eg consensus) flags. | ||||
// spend_tx is invalid according to DERSIG | // spend_tx is invalid according to DERSIG | ||||
{ | { | ||||
CValidationState state; | CValidationState state; | ||||
PrecomputedTransactionData ptd_spend_tx(spend_tx); | PrecomputedTransactionData ptd_spend_tx(spend_tx); | ||||
BOOST_CHECK(!CheckInputs(spend_tx, state, pcoinsTip, true, | BOOST_CHECK(!CheckInputs(spend_tx, state, pcoinsTip.get(), true, | ||||
MANDATORY_SCRIPT_VERIFY_FLAGS | | MANDATORY_SCRIPT_VERIFY_FLAGS | | ||||
SCRIPT_VERIFY_CLEANSTACK, | SCRIPT_VERIFY_CLEANSTACK, | ||||
true, true, ptd_spend_tx, nullptr)); | true, true, ptd_spend_tx, nullptr)); | ||||
// If we call again asking for scriptchecks (as happens in | // If we call again asking for scriptchecks (as happens in | ||||
// ConnectBlock), we should add a script check object for this -- we're | // ConnectBlock), we should add a script check object for this -- we're | ||||
// not caching invalidity (if that changes, delete this test case). | // not caching invalidity (if that changes, delete this test case). | ||||
std::vector<CScriptCheck> scriptchecks; | std::vector<CScriptCheck> scriptchecks; | ||||
BOOST_CHECK(CheckInputs(spend_tx, state, pcoinsTip, true, | BOOST_CHECK(CheckInputs(spend_tx, state, pcoinsTip.get(), true, | ||||
MANDATORY_SCRIPT_VERIFY_FLAGS | | MANDATORY_SCRIPT_VERIFY_FLAGS | | ||||
SCRIPT_VERIFY_CLEANSTACK, | SCRIPT_VERIFY_CLEANSTACK, | ||||
true, true, ptd_spend_tx, &scriptchecks)); | true, true, ptd_spend_tx, &scriptchecks)); | ||||
BOOST_CHECK_EQUAL(scriptchecks.size(), 1); | BOOST_CHECK_EQUAL(scriptchecks.size(), 1); | ||||
// Test that CheckInputs returns true iff cleanstack-enforcing flags are | // Test that CheckInputs returns true iff cleanstack-enforcing flags are | ||||
// not present. Don't add these checks to the cache, so that we can test | // not present. Don't add these checks to the cache, so that we can test | ||||
// later that block validation works fine in the absence of cached | // later that block validation works fine in the absence of cached | ||||
▲ Show 20 Lines • Show All 55 Lines • ▼ Show 20 Lines | // Test CHECKLOCKTIMEVERIFY | ||||
// Make it valid, and check again | // Make it valid, and check again | ||||
invalid_with_cltv_tx.vin[0].scriptSig = CScript() << vchSig << 100; | invalid_with_cltv_tx.vin[0].scriptSig = CScript() << vchSig << 100; | ||||
CValidationState state; | CValidationState state; | ||||
CTransaction transaction(invalid_with_cltv_tx); | CTransaction transaction(invalid_with_cltv_tx); | ||||
PrecomputedTransactionData txdata(transaction); | PrecomputedTransactionData txdata(transaction); | ||||
BOOST_CHECK(CheckInputs(transaction, state, pcoinsTip, true, | BOOST_CHECK(CheckInputs(transaction, state, pcoinsTip.get(), true, | ||||
MANDATORY_SCRIPT_VERIFY_FLAGS | | MANDATORY_SCRIPT_VERIFY_FLAGS | | ||||
SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY, | SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY, | ||||
true, true, txdata, nullptr)); | true, true, txdata, nullptr)); | ||||
} | } | ||||
// TEST CHECKSEQUENCEVERIFY | // TEST CHECKSEQUENCEVERIFY | ||||
{ | { | ||||
CMutableTransaction invalid_with_csv_tx; | CMutableTransaction invalid_with_csv_tx; | ||||
Show All 19 Lines | // TEST CHECKSEQUENCEVERIFY | ||||
// Make it valid, and check again | // Make it valid, and check again | ||||
invalid_with_csv_tx.vin[0].scriptSig = CScript() << vchSig << 100; | invalid_with_csv_tx.vin[0].scriptSig = CScript() << vchSig << 100; | ||||
CValidationState state; | CValidationState state; | ||||
CTransaction transaction(invalid_with_csv_tx); | CTransaction transaction(invalid_with_csv_tx); | ||||
PrecomputedTransactionData txdata(transaction); | PrecomputedTransactionData txdata(transaction); | ||||
BOOST_CHECK(CheckInputs(transaction, state, pcoinsTip, true, | BOOST_CHECK(CheckInputs(transaction, state, pcoinsTip.get(), true, | ||||
MANDATORY_SCRIPT_VERIFY_FLAGS | | MANDATORY_SCRIPT_VERIFY_FLAGS | | ||||
SCRIPT_VERIFY_CHECKSEQUENCEVERIFY, | SCRIPT_VERIFY_CHECKSEQUENCEVERIFY, | ||||
true, true, txdata, nullptr)); | true, true, txdata, nullptr)); | ||||
} | } | ||||
// TODO: add tests for remaining script flags | // TODO: add tests for remaining script flags | ||||
{ | { | ||||
Show All 30 Lines | // TODO: add tests for remaining script flags | ||||
tx.vin[1].scriptSig = CScript(); | tx.vin[1].scriptSig = CScript(); | ||||
CValidationState state; | CValidationState state; | ||||
CTransaction transaction(tx); | CTransaction transaction(tx); | ||||
PrecomputedTransactionData txdata(transaction); | PrecomputedTransactionData txdata(transaction); | ||||
// This transaction is now invalid because the second signature is | // This transaction is now invalid because the second signature is | ||||
// missing. | // missing. | ||||
BOOST_CHECK(!CheckInputs(transaction, state, pcoinsTip, true, | BOOST_CHECK(!CheckInputs(transaction, state, pcoinsTip.get(), true, | ||||
MANDATORY_SCRIPT_VERIFY_FLAGS, true, true, | MANDATORY_SCRIPT_VERIFY_FLAGS, true, true, | ||||
txdata, nullptr)); | txdata, nullptr)); | ||||
// Make sure this transaction was not cached (ie becausethe first input | // Make sure this transaction was not cached (ie becausethe first input | ||||
// was valid) | // was valid) | ||||
std::vector<CScriptCheck> scriptchecks; | std::vector<CScriptCheck> scriptchecks; | ||||
BOOST_CHECK(CheckInputs(transaction, state, pcoinsTip, true, | BOOST_CHECK(CheckInputs(transaction, state, pcoinsTip.get(), true, | ||||
MANDATORY_SCRIPT_VERIFY_FLAGS, true, true, | MANDATORY_SCRIPT_VERIFY_FLAGS, true, true, | ||||
txdata, &scriptchecks)); | txdata, &scriptchecks)); | ||||
// Should get 2 script checks back -- caching is on a whole-transaction | // Should get 2 script checks back -- caching is on a whole-transaction | ||||
// basis. | // basis. | ||||
BOOST_CHECK_EQUAL(scriptchecks.size(), 2); | BOOST_CHECK_EQUAL(scriptchecks.size(), 2); | ||||
} | } | ||||
} | } | ||||
BOOST_AUTO_TEST_SUITE_END() | BOOST_AUTO_TEST_SUITE_END() |