Changeset View
Changeset View
Standalone View
Standalone View
src/test/txpackage_tests.cpp
Show First 20 Lines • Show All 89 Lines • ▼ Show 20 Lines | BOOST_FIXTURE_TEST_CASE(package_validation_tests, TestChain100Setup) { | ||||
CScript child_locking_script = | CScript child_locking_script = | ||||
GetScriptForDestination(PKHash(child_key.GetPubKey())); | GetScriptForDestination(PKHash(child_key.GetPubKey())); | ||||
auto mtx_child = CreateValidMempoolTransaction( | auto mtx_child = CreateValidMempoolTransaction( | ||||
/* input_transaction */ tx_parent, /* vout */ 0, | /* input_transaction */ tx_parent, /* vout */ 0, | ||||
/* input_height */ 101, /* input_signing_key */ parent_key, | /* input_height */ 101, /* input_signing_key */ parent_key, | ||||
/* output_destination */ child_locking_script, | /* output_destination */ child_locking_script, | ||||
/* output_amount */ Amount(48 * COIN), /* submit */ false); | /* output_amount */ Amount(48 * COIN), /* submit */ false); | ||||
CTransactionRef tx_child = MakeTransactionRef(mtx_child); | CTransactionRef tx_child = MakeTransactionRef(mtx_child); | ||||
const auto result_parent_child = ProcessNewPackage( | const auto result_parent_child = | ||||
GetConfig(), m_node.chainman->ActiveChainstate(), *m_node.mempool, | ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool, | ||||
{tx_parent, tx_child}, /* test_accept */ true); | {tx_parent, tx_child}, /* test_accept */ true); | ||||
BOOST_CHECK_MESSAGE(result_parent_child.m_state.IsValid(), | BOOST_CHECK_MESSAGE(result_parent_child.m_state.IsValid(), | ||||
"Package validation unexpectedly failed: " | "Package validation unexpectedly failed: " | ||||
<< result_parent_child.m_state.GetRejectReason()); | << result_parent_child.m_state.GetRejectReason()); | ||||
auto it_parent = result_parent_child.m_tx_results.find(tx_parent->GetId()); | auto it_parent = result_parent_child.m_tx_results.find(tx_parent->GetId()); | ||||
auto it_child = result_parent_child.m_tx_results.find(tx_child->GetId()); | auto it_child = result_parent_child.m_tx_results.find(tx_child->GetId()); | ||||
BOOST_CHECK(it_parent != result_parent_child.m_tx_results.end()); | BOOST_CHECK(it_parent != result_parent_child.m_tx_results.end()); | ||||
BOOST_CHECK_MESSAGE(it_parent->second.m_state.IsValid(), | BOOST_CHECK_MESSAGE(it_parent->second.m_state.IsValid(), | ||||
"Package validation unexpectedly failed: " | "Package validation unexpectedly failed: " | ||||
<< it_parent->second.m_state.GetRejectReason()); | << it_parent->second.m_state.GetRejectReason()); | ||||
BOOST_CHECK(it_child != result_parent_child.m_tx_results.end()); | BOOST_CHECK(it_child != result_parent_child.m_tx_results.end()); | ||||
BOOST_CHECK_MESSAGE(it_child->second.m_state.IsValid(), | BOOST_CHECK_MESSAGE(it_child->second.m_state.IsValid(), | ||||
"Package validation unexpectedly failed: " | "Package validation unexpectedly failed: " | ||||
<< it_child->second.m_state.GetRejectReason()); | << it_child->second.m_state.GetRejectReason()); | ||||
// A single, giant transaction submitted through ProcessNewPackage fails on | // A single, giant transaction submitted through ProcessNewPackage fails on | ||||
// single tx policy. | // single tx policy. | ||||
CTransactionRef giant_ptx = create_placeholder_tx(999, 999); | CTransactionRef giant_ptx = create_placeholder_tx(999, 999); | ||||
BOOST_CHECK(GetVirtualTransactionSize(*giant_ptx) > | BOOST_CHECK(GetVirtualTransactionSize(*giant_ptx) > | ||||
MAX_PACKAGE_SIZE * 1000); | MAX_PACKAGE_SIZE * 1000); | ||||
auto result_single_large = | auto result_single_large = | ||||
ProcessNewPackage(GetConfig(), m_node.chainman->ActiveChainstate(), | ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool, | ||||
*m_node.mempool, {giant_ptx}, /* test_accept */ true); | {giant_ptx}, /* test_accept */ true); | ||||
BOOST_CHECK(result_single_large.m_state.IsInvalid()); | BOOST_CHECK(result_single_large.m_state.IsInvalid()); | ||||
BOOST_CHECK_EQUAL(result_single_large.m_state.GetResult(), | BOOST_CHECK_EQUAL(result_single_large.m_state.GetResult(), | ||||
PackageValidationResult::PCKG_TX); | PackageValidationResult::PCKG_TX); | ||||
BOOST_CHECK_EQUAL(result_single_large.m_state.GetRejectReason(), | BOOST_CHECK_EQUAL(result_single_large.m_state.GetRejectReason(), | ||||
"transaction failed"); | "transaction failed"); | ||||
auto it_giant_tx = | auto it_giant_tx = | ||||
result_single_large.m_tx_results.find(giant_ptx->GetId()); | result_single_large.m_tx_results.find(giant_ptx->GetId()); | ||||
BOOST_CHECK(it_giant_tx != result_single_large.m_tx_results.end()); | BOOST_CHECK(it_giant_tx != result_single_large.m_tx_results.end()); | ||||
▲ Show 20 Lines • Show All 104 Lines • ▼ Show 20 Lines | // 2 Parents and 1 Child where one parent depends on the other. | ||||
!CheckPackage({tx_parent_also_child, tx_parent, tx_child}, state)); | !CheckPackage({tx_parent_also_child, tx_parent, tx_child}, state)); | ||||
BOOST_CHECK_EQUAL(state.GetResult(), | BOOST_CHECK_EQUAL(state.GetResult(), | ||||
PackageValidationResult::PCKG_POLICY); | PackageValidationResult::PCKG_POLICY); | ||||
BOOST_CHECK_EQUAL(state.GetRejectReason(), "package-not-sorted"); | BOOST_CHECK_EQUAL(state.GetRejectReason(), "package-not-sorted"); | ||||
} | } | ||||
} | } | ||||
BOOST_FIXTURE_TEST_CASE(package_submission_tests, TestChain100Setup) { | BOOST_FIXTURE_TEST_CASE(package_submission_tests, TestChain100Setup) { | ||||
const Config &config{GetConfig()}; | |||||
unsigned int expected_pool_size = m_node.mempool->size(); | unsigned int expected_pool_size = m_node.mempool->size(); | ||||
CKey parent_key; | CKey parent_key; | ||||
parent_key.MakeNewKey(true); | parent_key.MakeNewKey(true); | ||||
CScript parent_locking_script = | CScript parent_locking_script = | ||||
GetScriptForDestination(PKHash(parent_key.GetPubKey())); | GetScriptForDestination(PKHash(parent_key.GetPubKey())); | ||||
// Unrelated transactions are not allowed in package submission. | // Unrelated transactions are not allowed in package submission. | ||||
Package package_unrelated; | Package package_unrelated; | ||||
for (size_t i{0}; i < 10; ++i) { | for (size_t i{0}; i < 10; ++i) { | ||||
auto mtx = CreateValidMempoolTransaction( | auto mtx = CreateValidMempoolTransaction( | ||||
/*input_transaction=*/m_coinbase_txns[i + 25], /*input_vout=*/0, | /*input_transaction=*/m_coinbase_txns[i + 25], /*input_vout=*/0, | ||||
/*input_height=*/0, /*input_signing_key=*/coinbaseKey, | /*input_height=*/0, /*input_signing_key=*/coinbaseKey, | ||||
/*output_destination=*/parent_locking_script, | /*output_destination=*/parent_locking_script, | ||||
/*output_amount=*/Amount(49 * COIN), /*submit=*/false); | /*output_amount=*/Amount(49 * COIN), /*submit=*/false); | ||||
package_unrelated.emplace_back(MakeTransactionRef(mtx)); | package_unrelated.emplace_back(MakeTransactionRef(mtx)); | ||||
} | } | ||||
{ | { | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
auto result_unrelated_submit = ProcessNewPackage( | auto result_unrelated_submit = ProcessNewPackage( | ||||
config, m_node.chainman->ActiveChainstate(), *m_node.mempool, | m_node.chainman->ActiveChainstate(), *m_node.mempool, | ||||
package_unrelated, /*test_accept=*/false); | package_unrelated, /*test_accept=*/false); | ||||
BOOST_CHECK(result_unrelated_submit.m_state.IsInvalid()); | BOOST_CHECK(result_unrelated_submit.m_state.IsInvalid()); | ||||
BOOST_CHECK_EQUAL(result_unrelated_submit.m_state.GetResult(), | BOOST_CHECK_EQUAL(result_unrelated_submit.m_state.GetResult(), | ||||
PackageValidationResult::PCKG_POLICY); | PackageValidationResult::PCKG_POLICY); | ||||
BOOST_CHECK_EQUAL(result_unrelated_submit.m_state.GetRejectReason(), | BOOST_CHECK_EQUAL(result_unrelated_submit.m_state.GetRejectReason(), | ||||
"package-not-child-with-parents"); | "package-not-child-with-parents"); | ||||
BOOST_CHECK_EQUAL(m_node.mempool->size(), expected_pool_size); | BOOST_CHECK_EQUAL(m_node.mempool->size(), expected_pool_size); | ||||
} | } | ||||
Show All 34 Lines | auto mtx_grandchild = CreateValidMempoolTransaction( | ||||
/*output_amount=*/Amount(47 * COIN), /*submit=*/false); | /*output_amount=*/Amount(47 * COIN), /*submit=*/false); | ||||
CTransactionRef tx_grandchild = MakeTransactionRef(mtx_grandchild); | CTransactionRef tx_grandchild = MakeTransactionRef(mtx_grandchild); | ||||
package_3gen.push_back(tx_grandchild); | package_3gen.push_back(tx_grandchild); | ||||
// 3 Generations is not allowed. | // 3 Generations is not allowed. | ||||
{ | { | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
auto result_3gen_submit = ProcessNewPackage( | auto result_3gen_submit = ProcessNewPackage( | ||||
config, m_node.chainman->ActiveChainstate(), *m_node.mempool, | m_node.chainman->ActiveChainstate(), *m_node.mempool, package_3gen, | ||||
package_3gen, /*test_accept=*/false); | /*test_accept=*/false); | ||||
BOOST_CHECK(result_3gen_submit.m_state.IsInvalid()); | BOOST_CHECK(result_3gen_submit.m_state.IsInvalid()); | ||||
BOOST_CHECK_EQUAL(result_3gen_submit.m_state.GetResult(), | BOOST_CHECK_EQUAL(result_3gen_submit.m_state.GetResult(), | ||||
PackageValidationResult::PCKG_POLICY); | PackageValidationResult::PCKG_POLICY); | ||||
BOOST_CHECK_EQUAL(result_3gen_submit.m_state.GetRejectReason(), | BOOST_CHECK_EQUAL(result_3gen_submit.m_state.GetRejectReason(), | ||||
"package-not-child-with-parents"); | "package-not-child-with-parents"); | ||||
BOOST_CHECK_EQUAL(m_node.mempool->size(), expected_pool_size); | BOOST_CHECK_EQUAL(m_node.mempool->size(), expected_pool_size); | ||||
} | } | ||||
// Child with missing parent. | // Child with missing parent. | ||||
mtx_child.vin.push_back(CTxIn(COutPoint(package_unrelated[0]->GetId(), 0))); | mtx_child.vin.push_back(CTxIn(COutPoint(package_unrelated[0]->GetId(), 0))); | ||||
Package package_missing_parent; | Package package_missing_parent; | ||||
package_missing_parent.push_back(tx_parent); | package_missing_parent.push_back(tx_parent); | ||||
package_missing_parent.push_back(MakeTransactionRef(mtx_child)); | package_missing_parent.push_back(MakeTransactionRef(mtx_child)); | ||||
{ | { | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
const auto result_missing_parent = ProcessNewPackage( | const auto result_missing_parent = ProcessNewPackage( | ||||
config, m_node.chainman->ActiveChainstate(), *m_node.mempool, | m_node.chainman->ActiveChainstate(), *m_node.mempool, | ||||
package_missing_parent, /*test_accept=*/false); | package_missing_parent, /*test_accept=*/false); | ||||
BOOST_CHECK(result_missing_parent.m_state.IsInvalid()); | BOOST_CHECK(result_missing_parent.m_state.IsInvalid()); | ||||
BOOST_CHECK_EQUAL(result_missing_parent.m_state.GetResult(), | BOOST_CHECK_EQUAL(result_missing_parent.m_state.GetResult(), | ||||
PackageValidationResult::PCKG_POLICY); | PackageValidationResult::PCKG_POLICY); | ||||
BOOST_CHECK_EQUAL(result_missing_parent.m_state.GetRejectReason(), | BOOST_CHECK_EQUAL(result_missing_parent.m_state.GetRejectReason(), | ||||
"package-not-child-with-unconfirmed-parents"); | "package-not-child-with-unconfirmed-parents"); | ||||
BOOST_CHECK_EQUAL(m_node.mempool->size(), expected_pool_size); | BOOST_CHECK_EQUAL(m_node.mempool->size(), expected_pool_size); | ||||
} | } | ||||
// Submit package with parent + child. | // Submit package with parent + child. | ||||
{ | { | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
const auto submit_parent_child = ProcessNewPackage( | const auto submit_parent_child = ProcessNewPackage( | ||||
config, m_node.chainman->ActiveChainstate(), *m_node.mempool, | m_node.chainman->ActiveChainstate(), *m_node.mempool, | ||||
package_parent_child, /*test_accept=*/false); | package_parent_child, /*test_accept=*/false); | ||||
expected_pool_size += 2; | expected_pool_size += 2; | ||||
BOOST_CHECK_MESSAGE( | BOOST_CHECK_MESSAGE( | ||||
submit_parent_child.m_state.IsValid(), | submit_parent_child.m_state.IsValid(), | ||||
"Package validation unexpectedly failed: " | "Package validation unexpectedly failed: " | ||||
<< submit_parent_child.m_state.GetRejectReason()); | << submit_parent_child.m_state.GetRejectReason()); | ||||
auto it_parent = | auto it_parent = | ||||
submit_parent_child.m_tx_results.find(tx_parent->GetId()); | submit_parent_child.m_tx_results.find(tx_parent->GetId()); | ||||
auto it_child = | auto it_child = | ||||
submit_parent_child.m_tx_results.find(tx_child->GetId()); | submit_parent_child.m_tx_results.find(tx_child->GetId()); | ||||
BOOST_CHECK(it_parent != submit_parent_child.m_tx_results.end()); | BOOST_CHECK(it_parent != submit_parent_child.m_tx_results.end()); | ||||
BOOST_CHECK(it_parent->second.m_state.IsValid()); | BOOST_CHECK(it_parent->second.m_state.IsValid()); | ||||
BOOST_CHECK(it_child != submit_parent_child.m_tx_results.end()); | BOOST_CHECK(it_child != submit_parent_child.m_tx_results.end()); | ||||
BOOST_CHECK(it_child->second.m_state.IsValid()); | BOOST_CHECK(it_child->second.m_state.IsValid()); | ||||
BOOST_CHECK_EQUAL(m_node.mempool->size(), expected_pool_size); | BOOST_CHECK_EQUAL(m_node.mempool->size(), expected_pool_size); | ||||
BOOST_CHECK(m_node.mempool->exists(tx_parent->GetId())); | BOOST_CHECK(m_node.mempool->exists(tx_parent->GetId())); | ||||
BOOST_CHECK(m_node.mempool->exists(tx_child->GetId())); | BOOST_CHECK(m_node.mempool->exists(tx_child->GetId())); | ||||
} | } | ||||
// Already-in-mempool transactions should be detected and de-duplicated. | // Already-in-mempool transactions should be detected and de-duplicated. | ||||
{ | { | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
const auto submit_deduped = ProcessNewPackage( | const auto submit_deduped = ProcessNewPackage( | ||||
config, m_node.chainman->ActiveChainstate(), *m_node.mempool, | m_node.chainman->ActiveChainstate(), *m_node.mempool, | ||||
package_parent_child, /*test_accept=*/false); | package_parent_child, /*test_accept=*/false); | ||||
BOOST_CHECK_MESSAGE(submit_deduped.m_state.IsValid(), | BOOST_CHECK_MESSAGE(submit_deduped.m_state.IsValid(), | ||||
"Package validation unexpectedly failed: " | "Package validation unexpectedly failed: " | ||||
<< submit_deduped.m_state.GetRejectReason()); | << submit_deduped.m_state.GetRejectReason()); | ||||
auto it_parent_deduped = | auto it_parent_deduped = | ||||
submit_deduped.m_tx_results.find(tx_parent->GetId()); | submit_deduped.m_tx_results.find(tx_parent->GetId()); | ||||
auto it_child_deduped = | auto it_child_deduped = | ||||
submit_deduped.m_tx_results.find(tx_child->GetId()); | submit_deduped.m_tx_results.find(tx_child->GetId()); | ||||
Show All 18 Lines | BOOST_FIXTURE_TEST_CASE(package_submission_tests, TestChain100Setup) { | ||||
expected_pool_size -= 1; | expected_pool_size -= 1; | ||||
Package package_with_confirmed; | Package package_with_confirmed; | ||||
package_with_confirmed.push_back(tx_parent); | package_with_confirmed.push_back(tx_parent); | ||||
package_with_confirmed.push_back(tx_child); | package_with_confirmed.push_back(tx_child); | ||||
{ | { | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
const auto result_confirmed_parent = ProcessNewPackage( | const auto result_confirmed_parent = ProcessNewPackage( | ||||
config, m_node.chainman->ActiveChainstate(), *m_node.mempool, | m_node.chainman->ActiveChainstate(), *m_node.mempool, | ||||
package_with_confirmed, /*test_accept=*/false); | package_with_confirmed, /*test_accept=*/false); | ||||
BOOST_CHECK(result_confirmed_parent.m_state.IsInvalid()); | BOOST_CHECK(result_confirmed_parent.m_state.IsInvalid()); | ||||
BOOST_CHECK_EQUAL(result_confirmed_parent.m_state.GetResult(), | BOOST_CHECK_EQUAL(result_confirmed_parent.m_state.GetResult(), | ||||
PackageValidationResult::PCKG_TX); | PackageValidationResult::PCKG_TX); | ||||
BOOST_CHECK_EQUAL(result_confirmed_parent.m_state.GetRejectReason(), | BOOST_CHECK_EQUAL(result_confirmed_parent.m_state.GetRejectReason(), | ||||
"transaction failed"); | "transaction failed"); | ||||
BOOST_CHECK_EQUAL(m_node.mempool->size(), expected_pool_size); | BOOST_CHECK_EQUAL(m_node.mempool->size(), expected_pool_size); | ||||
Show All 9 Lines |