Changeset View
Changeset View
Standalone View
Standalone View
src/test/txvalidationcache_tests.cpp
Show All 22 Lines | |||||
BOOST_AUTO_TEST_SUITE(txvalidationcache_tests) | BOOST_AUTO_TEST_SUITE(txvalidationcache_tests) | ||||
static bool ToMemPool(CMutableTransaction &tx) { | static bool ToMemPool(CMutableTransaction &tx) { | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
CValidationState state; | CValidationState state; | ||||
return AcceptToMemoryPool(GetConfig(), mempool, state, | return AcceptToMemoryPool(GetConfig(), mempool, state, | ||||
MakeTransactionRef(tx), false, nullptr, nullptr, | MakeTransactionRef(tx), false, nullptr, nullptr, | ||||
true, 0); | true, Amount(0)); | ||||
} | } | ||||
BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup) { | BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup) { | ||||
// Make sure skipping validation of transctions that were validated going | // Make sure skipping validation of transctions that were validated going | ||||
// into the memory pool does not allow double-spends in blocks to pass | // into the memory pool does not allow double-spends in blocks to pass | ||||
// validation when they should not. | // validation when they should not. | ||||
CScript scriptPubKey = CScript() << ToByteVector(coinbaseKey.GetPubKey()) | CScript scriptPubKey = CScript() << ToByteVector(coinbaseKey.GetPubKey()) | ||||
<< OP_CHECKSIG; | << OP_CHECKSIG; | ||||
// Create a double-spend of mature coinbase txn: | // Create a double-spend of mature coinbase txn: | ||||
std::vector<CMutableTransaction> spends; | std::vector<CMutableTransaction> spends; | ||||
spends.resize(2); | spends.resize(2); | ||||
for (int i = 0; i < 2; i++) { | for (int i = 0; i < 2; i++) { | ||||
spends[i].nVersion = 1; | spends[i].nVersion = 1; | ||||
spends[i].vin.resize(1); | spends[i].vin.resize(1); | ||||
spends[i].vin[0].prevout.hash = coinbaseTxns[0].GetId(); | spends[i].vin[0].prevout.hash = coinbaseTxns[0].GetId(); | ||||
spends[i].vin[0].prevout.n = 0; | spends[i].vin[0].prevout.n = 0; | ||||
spends[i].vout.resize(1); | spends[i].vout.resize(1); | ||||
spends[i].vout[0].nValue = 11 * CENT.GetSatoshis(); | spends[i].vout[0].nValue = 11 * CENT; | ||||
spends[i].vout[0].scriptPubKey = scriptPubKey; | spends[i].vout[0].scriptPubKey = scriptPubKey; | ||||
// Sign: | // Sign: | ||||
std::vector<uint8_t> vchSig; | std::vector<uint8_t> vchSig; | ||||
uint256 hash = SignatureHash(scriptPubKey, spends[i], 0, | uint256 hash = SignatureHash(scriptPubKey, spends[i], 0, | ||||
SIGHASH_ALL | SIGHASH_FORKID, | SIGHASH_ALL | SIGHASH_FORKID, | ||||
coinbaseTxns[0].vout[0].nValue); | coinbaseTxns[0].vout[0].nValue); | ||||
BOOST_CHECK(coinbaseKey.Sign(hash, vchSig)); | BOOST_CHECK(coinbaseKey.Sign(hash, vchSig)); | ||||
▲ Show 20 Lines • Show All 110 Lines • ▼ Show 20 Lines | BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup) { | ||||
// coinbase tx. | // coinbase tx. | ||||
CMutableTransaction spend_tx; | CMutableTransaction spend_tx; | ||||
spend_tx.nVersion = 1; | spend_tx.nVersion = 1; | ||||
spend_tx.vin.resize(1); | spend_tx.vin.resize(1); | ||||
spend_tx.vin[0].prevout.hash = coinbaseTxns[0].GetId(); | spend_tx.vin[0].prevout.hash = coinbaseTxns[0].GetId(); | ||||
spend_tx.vin[0].prevout.n = 0; | spend_tx.vin[0].prevout.n = 0; | ||||
spend_tx.vout.resize(4); | spend_tx.vout.resize(4); | ||||
spend_tx.vout[0].nValue = 11 * CENT.GetSatoshis(); | spend_tx.vout[0].nValue = 11 * CENT; | ||||
spend_tx.vout[0].scriptPubKey = p2sh_scriptPubKey; | spend_tx.vout[0].scriptPubKey = p2sh_scriptPubKey; | ||||
spend_tx.vout[1].nValue = 11 * CENT.GetSatoshis(); | spend_tx.vout[1].nValue = 11 * CENT; | ||||
spend_tx.vout[1].scriptPubKey = | spend_tx.vout[1].scriptPubKey = | ||||
CScript() << OP_CHECKLOCKTIMEVERIFY << OP_DROP | CScript() << OP_CHECKLOCKTIMEVERIFY << OP_DROP | ||||
<< ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG; | << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG; | ||||
spend_tx.vout[2].nValue = 11 * CENT.GetSatoshis(); | spend_tx.vout[2].nValue = 11 * CENT; | ||||
spend_tx.vout[2].scriptPubKey = | spend_tx.vout[2].scriptPubKey = | ||||
CScript() << OP_CHECKSEQUENCEVERIFY << OP_DROP | CScript() << OP_CHECKSEQUENCEVERIFY << OP_DROP | ||||
<< ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG; | << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG; | ||||
spend_tx.vout[3].nValue = 11 * CENT.GetSatoshis(); | spend_tx.vout[3].nValue = 11 * CENT; | ||||
spend_tx.vout[3].scriptPubKey = p2sh_scriptPubKey; | spend_tx.vout[3].scriptPubKey = p2sh_scriptPubKey; | ||||
// Sign, and push an extra element on the stack. | // Sign, and push an extra element on the stack. | ||||
{ | { | ||||
std::vector<uint8_t> vchSig; | std::vector<uint8_t> vchSig; | ||||
uint256 hash = SignatureHash(p2pk_scriptPubKey, spend_tx, 0, | uint256 hash = SignatureHash(p2pk_scriptPubKey, spend_tx, 0, | ||||
SIGHASH_ALL | SIGHASH_FORKID, | SIGHASH_ALL | SIGHASH_FORKID, | ||||
coinbaseTxns[0].vout[0].nValue); | coinbaseTxns[0].vout[0].nValue); | ||||
▲ Show 20 Lines • Show All 46 Lines • ▼ Show 20 Lines | BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup) { | ||||
// 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.hash = spend_tx.GetId(); | invalid_under_p2sh_tx.vin[0].prevout.hash = spend_tx.GetId(); | ||||
invalid_under_p2sh_tx.vin[0].prevout.n = 0; | invalid_under_p2sh_tx.vin[0].prevout.n = 0; | ||||
invalid_under_p2sh_tx.vout.resize(1); | invalid_under_p2sh_tx.vout.resize(1); | ||||
invalid_under_p2sh_tx.vout[0].nValue = 11 * CENT.GetSatoshis(); | invalid_under_p2sh_tx.vout[0].nValue = 11 * CENT; | ||||
invalid_under_p2sh_tx.vout[0].scriptPubKey = p2pk_scriptPubKey; | invalid_under_p2sh_tx.vout[0].scriptPubKey = p2pk_scriptPubKey; | ||||
std::vector<uint8_t> vchSig2(p2pk_scriptPubKey.begin(), | std::vector<uint8_t> vchSig2(p2pk_scriptPubKey.begin(), | ||||
p2pk_scriptPubKey.end()); | p2pk_scriptPubKey.end()); | ||||
invalid_under_p2sh_tx.vin[0].scriptSig << vchSig2; | invalid_under_p2sh_tx.vin[0].scriptSig << vchSig2; | ||||
ValidateCheckInputsForAllFlags(invalid_under_p2sh_tx, | ValidateCheckInputsForAllFlags(invalid_under_p2sh_tx, | ||||
SCRIPT_VERIFY_P2SH, true, false); | SCRIPT_VERIFY_P2SH, true, false); | ||||
} | } | ||||
// Test CHECKLOCKTIMEVERIFY | // Test CHECKLOCKTIMEVERIFY | ||||
{ | { | ||||
CMutableTransaction invalid_with_cltv_tx; | CMutableTransaction invalid_with_cltv_tx; | ||||
invalid_with_cltv_tx.nVersion = 1; | invalid_with_cltv_tx.nVersion = 1; | ||||
invalid_with_cltv_tx.nLockTime = 100; | invalid_with_cltv_tx.nLockTime = 100; | ||||
invalid_with_cltv_tx.vin.resize(1); | invalid_with_cltv_tx.vin.resize(1); | ||||
invalid_with_cltv_tx.vin[0].prevout.hash = spend_tx.GetId(); | invalid_with_cltv_tx.vin[0].prevout.hash = spend_tx.GetId(); | ||||
invalid_with_cltv_tx.vin[0].prevout.n = 1; | invalid_with_cltv_tx.vin[0].prevout.n = 1; | ||||
invalid_with_cltv_tx.vin[0].nSequence = 0; | invalid_with_cltv_tx.vin[0].nSequence = 0; | ||||
invalid_with_cltv_tx.vout.resize(1); | invalid_with_cltv_tx.vout.resize(1); | ||||
invalid_with_cltv_tx.vout[0].nValue = 11 * CENT.GetSatoshis(); | invalid_with_cltv_tx.vout[0].nValue = 11 * CENT; | ||||
invalid_with_cltv_tx.vout[0].scriptPubKey = p2pk_scriptPubKey; | invalid_with_cltv_tx.vout[0].scriptPubKey = p2pk_scriptPubKey; | ||||
// Sign | // Sign | ||||
std::vector<uint8_t> vchSig; | std::vector<uint8_t> vchSig; | ||||
uint256 hash = SignatureHash( | uint256 hash = SignatureHash( | ||||
spend_tx.vout[1].scriptPubKey, invalid_with_cltv_tx, 0, | spend_tx.vout[1].scriptPubKey, invalid_with_cltv_tx, 0, | ||||
SIGHASH_ALL | SIGHASH_FORKID, spend_tx.vout[1].nValue); | SIGHASH_ALL | SIGHASH_FORKID, spend_tx.vout[1].nValue); | ||||
BOOST_CHECK(coinbaseKey.Sign(hash, vchSig)); | BOOST_CHECK(coinbaseKey.Sign(hash, vchSig)); | ||||
Show All 18 Lines | BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup) { | ||||
{ | { | ||||
CMutableTransaction invalid_with_csv_tx; | CMutableTransaction invalid_with_csv_tx; | ||||
invalid_with_csv_tx.nVersion = 2; | invalid_with_csv_tx.nVersion = 2; | ||||
invalid_with_csv_tx.vin.resize(1); | invalid_with_csv_tx.vin.resize(1); | ||||
invalid_with_csv_tx.vin[0].prevout.hash = spend_tx.GetId(); | invalid_with_csv_tx.vin[0].prevout.hash = spend_tx.GetId(); | ||||
invalid_with_csv_tx.vin[0].prevout.n = 2; | invalid_with_csv_tx.vin[0].prevout.n = 2; | ||||
invalid_with_csv_tx.vin[0].nSequence = 100; | invalid_with_csv_tx.vin[0].nSequence = 100; | ||||
invalid_with_csv_tx.vout.resize(1); | invalid_with_csv_tx.vout.resize(1); | ||||
invalid_with_csv_tx.vout[0].nValue = 11 * CENT.GetSatoshis(); | invalid_with_csv_tx.vout[0].nValue = 11 * CENT; | ||||
invalid_with_csv_tx.vout[0].scriptPubKey = p2pk_scriptPubKey; | invalid_with_csv_tx.vout[0].scriptPubKey = p2pk_scriptPubKey; | ||||
// Sign | // Sign | ||||
std::vector<uint8_t> vchSig; | std::vector<uint8_t> vchSig; | ||||
uint256 hash = SignatureHash( | uint256 hash = SignatureHash( | ||||
spend_tx.vout[2].scriptPubKey, invalid_with_csv_tx, 0, | spend_tx.vout[2].scriptPubKey, invalid_with_csv_tx, 0, | ||||
SIGHASH_ALL | SIGHASH_FORKID, spend_tx.vout[2].nValue); | SIGHASH_ALL | SIGHASH_FORKID, spend_tx.vout[2].nValue); | ||||
BOOST_CHECK(coinbaseKey.Sign(hash, vchSig)); | BOOST_CHECK(coinbaseKey.Sign(hash, vchSig)); | ||||
Show All 21 Lines | // TODO: add tests for remaining script flags | ||||
tx.nVersion = 1; | tx.nVersion = 1; | ||||
tx.vin.resize(2); | tx.vin.resize(2); | ||||
tx.vin[0].prevout.hash = spend_tx.GetId(); | tx.vin[0].prevout.hash = spend_tx.GetId(); | ||||
tx.vin[0].prevout.n = 0; | tx.vin[0].prevout.n = 0; | ||||
tx.vin[1].prevout.hash = spend_tx.GetId(); | tx.vin[1].prevout.hash = spend_tx.GetId(); | ||||
tx.vin[1].prevout.n = 3; | tx.vin[1].prevout.n = 3; | ||||
tx.vout.resize(1); | tx.vout.resize(1); | ||||
tx.vout[0].nValue = 22 * CENT.GetSatoshis(); | tx.vout[0].nValue = 22 * CENT; | ||||
tx.vout[0].scriptPubKey = p2pk_scriptPubKey; | tx.vout[0].scriptPubKey = p2pk_scriptPubKey; | ||||
// Sign | // Sign | ||||
SignatureData sigdata; | SignatureData sigdata; | ||||
ProduceSignature(MutableTransactionSignatureCreator( | ProduceSignature( | ||||
&keystore, &tx, 0, 11 * CENT.GetSatoshis(), | MutableTransactionSignatureCreator(&keystore, &tx, 0, 11 * CENT, | ||||
SIGHASH_ALL | SIGHASH_FORKID), | SIGHASH_ALL | SIGHASH_FORKID), | ||||
spend_tx.vout[0].scriptPubKey, sigdata); | spend_tx.vout[0].scriptPubKey, sigdata); | ||||
UpdateTransaction(tx, 0, sigdata); | UpdateTransaction(tx, 0, sigdata); | ||||
ProduceSignature(MutableTransactionSignatureCreator( | ProduceSignature( | ||||
&keystore, &tx, 1, 11 * CENT.GetSatoshis(), | MutableTransactionSignatureCreator(&keystore, &tx, 1, 11 * CENT, | ||||
SIGHASH_ALL | SIGHASH_FORKID), | SIGHASH_ALL | SIGHASH_FORKID), | ||||
spend_tx.vout[3].scriptPubKey, sigdata); | spend_tx.vout[3].scriptPubKey, sigdata); | ||||
UpdateTransaction(tx, 1, sigdata); | UpdateTransaction(tx, 1, sigdata); | ||||
// This should be valid under all script flags | // This should be valid under all script flags | ||||
ValidateCheckInputsForAllFlags(tx, 0, true, false); | ValidateCheckInputsForAllFlags(tx, 0, true, false); | ||||
// Check that if the second input is invalid, but the first input is | // Check that if the second input is invalid, but the first input is | ||||
// valid, the transaction is not cached. | // valid, the transaction is not cached. | ||||
// Invalidate vin[1] | // Invalidate vin[1] | ||||
Show All 24 Lines |