Changeset View
Changeset View
Standalone View
Standalone View
src/test/txvalidationcache_tests.cpp
Show First 20 Lines • Show All 58 Lines • ▼ Show 20 Lines | for (int i = 0; i < 2; i++) { | ||||
vchSig.push_back(uint8_t(SIGHASH_ALL | SIGHASH_FORKID)); | vchSig.push_back(uint8_t(SIGHASH_ALL | SIGHASH_FORKID)); | ||||
spends[i].vin[0].scriptSig << vchSig; | spends[i].vin[0].scriptSig << vchSig; | ||||
} | } | ||||
CBlock block; | CBlock block; | ||||
// Test 1: block with both of those transactions should be rejected. | // Test 1: block with both of those transactions should be rejected. | ||||
block = CreateAndProcessBlock(spends, scriptPubKey); | block = CreateAndProcessBlock(spends, scriptPubKey); | ||||
LOCK(cs_main); | |||||
BOOST_CHECK(chainActive.Tip()->GetBlockHash() != block.GetHash()); | BOOST_CHECK(chainActive.Tip()->GetBlockHash() != block.GetHash()); | ||||
// Test 2: ... and should be rejected if spend1 is in the memory pool | // Test 2: ... and should be rejected if spend1 is in the memory pool | ||||
BOOST_CHECK(ToMemPool(spends[0])); | BOOST_CHECK(ToMemPool(spends[0])); | ||||
block = CreateAndProcessBlock(spends, scriptPubKey); | block = CreateAndProcessBlock(spends, scriptPubKey); | ||||
BOOST_CHECK(chainActive.Tip()->GetBlockHash() != block.GetHash()); | BOOST_CHECK(chainActive.Tip()->GetBlockHash() != block.GetHash()); | ||||
g_mempool.clear(); | g_mempool.clear(); | ||||
▲ Show 20 Lines • Show All 164 Lines • ▼ Show 20 Lines | // Sign the main transaction that we spend from. | ||||
// The last item on the stack will be dropped by CHECKMULTISIG This is | // The last item on the stack will be dropped by CHECKMULTISIG This is | ||||
// to check nulldummy enforcement. It is OP_1 instead of OP_0. | // to check nulldummy enforcement. It is OP_1 instead of OP_0. | ||||
mutableSpend_tx.vin[0].scriptSig << OP_1 << vchSig; | mutableSpend_tx.vin[0].scriptSig << OP_1 << vchSig; | ||||
} | } | ||||
const CTransaction spend_tx(mutableSpend_tx); | const CTransaction spend_tx(mutableSpend_tx); | ||||
LOCK(cs_main); | |||||
// 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 NULLDUMMY | // spend_tx is invalid according to NULLDUMMY | ||||
{ | { | ||||
LOCK(cs_main); | |||||
CValidationState state; | CValidationState state; | ||||
PrecomputedTransactionData ptd_spend_tx(spend_tx); | PrecomputedTransactionData ptd_spend_tx(spend_tx); | ||||
BOOST_CHECK(!CheckInputs(spend_tx, state, pcoinsTip.get(), true, | BOOST_CHECK(!CheckInputs(spend_tx, state, pcoinsTip.get(), true, | ||||
MANDATORY_SCRIPT_VERIFY_FLAGS | | MANDATORY_SCRIPT_VERIFY_FLAGS | | ||||
SCRIPT_VERIFY_NULLDUMMY, | SCRIPT_VERIFY_NULLDUMMY, | ||||
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( | BOOST_CHECK( | ||||
CheckInputs(spend_tx, state, pcoinsTip.get(), true, | CheckInputs(spend_tx, state, pcoinsTip.get(), true, | ||||
MANDATORY_SCRIPT_VERIFY_FLAGS | SCRIPT_VERIFY_NULLDUMMY, | MANDATORY_SCRIPT_VERIFY_FLAGS | SCRIPT_VERIFY_NULLDUMMY, | ||||
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 | ||||
// successes. | // successes. | ||||
ValidateCheckInputsForAllFlags(spend_tx, SCRIPT_VERIFY_NULLDUMMY, false, | ValidateCheckInputsForAllFlags(spend_tx, SCRIPT_VERIFY_NULLDUMMY, false, | ||||
false); | false); | ||||
} | |||||
// And if we produce a block with this tx, it should be valid (LOW_S not | // And if we produce a block with this tx, it should be valid (LOW_S not | ||||
// enabled yet), even though there's no cache entry. | // enabled yet), even though there's no cache entry. | ||||
CBlock block; | CBlock block; | ||||
block = CreateAndProcessBlock({spend_tx}, p2pk_scriptPubKey); | block = CreateAndProcessBlock({spend_tx}, p2pk_scriptPubKey); | ||||
BOOST_CHECK(chainActive.Tip()->GetBlockHash() == block.GetHash()); | BOOST_CHECK(chainActive.Tip()->GetBlockHash() == block.GetHash()); | ||||
BOOST_CHECK(pcoinsTip->GetBestBlock() == block.GetHash()); | BOOST_CHECK(pcoinsTip->GetBestBlock() == block.GetHash()); | ||||
} | |||||
LOCK(cs_main); | |||||
// Test P2SH: construct a transaction that is valid without P2SH, and then | // Test P2SH: construct a transaction that is valid without P2SH, and then | ||||
// test validity with P2SH. | // test validity with P2SH. | ||||
{ | { | ||||
CMutableTransaction invalid_under_p2sh_tx; | CMutableTransaction invalid_under_p2sh_tx; | ||||
invalid_under_p2sh_tx.nVersion = 1; | invalid_under_p2sh_tx.nVersion = 1; | ||||
invalid_under_p2sh_tx.vin.resize(1); | invalid_under_p2sh_tx.vin.resize(1); | ||||
invalid_under_p2sh_tx.vin[0].prevout = COutPoint(spend_tx.GetId(), 0); | invalid_under_p2sh_tx.vin[0].prevout = COutPoint(spend_tx.GetId(), 0); | ||||
▲ Show 20 Lines • Show All 143 Lines • Show Last 20 Lines |