forked from bitcoin/bitcoin
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
merge bitcoin#23381: refactoring for package submission
changes involving RBF have been excluded as RBF isn't implemented in Dash Core excluded: - 8fa2936 - 3d3e459
- Loading branch information
Showing
6 changed files
with
219 additions
and
144 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
// Copyright (c) 2021 The Bitcoin Core developers | ||
// Distributed under the MIT software license, see the accompanying | ||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||
|
||
#include <consensus/validation.h> | ||
#include <key_io.h> | ||
#include <policy/packages.h> | ||
#include <policy/policy.h> | ||
#include <primitives/transaction.h> | ||
#include <script/script.h> | ||
#include <script/standard.h> | ||
#include <test/util/setup_common.h> | ||
#include <validation.h> | ||
|
||
#include <boost/test/unit_test.hpp> | ||
|
||
struct TestChain100NoDIP0001Setup : public TestChain100Setup { | ||
TestChain100NoDIP0001Setup() | ||
: TestChain100Setup{{"-testactivationheight=dip0001@2000"}} {} | ||
}; | ||
|
||
BOOST_AUTO_TEST_SUITE(txpackage_tests) | ||
|
||
// Create placeholder transactions that have no meaning. | ||
inline CTransactionRef create_placeholder_tx(size_t num_inputs, size_t num_outputs) | ||
{ | ||
CMutableTransaction mtx = CMutableTransaction(); | ||
mtx.vin.resize(num_inputs); | ||
mtx.vout.resize(num_outputs); | ||
auto random_script = CScript() << ToByteVector(InsecureRand256()) << ToByteVector(InsecureRand256()); | ||
for (size_t i{0}; i < num_inputs; ++i) { | ||
mtx.vin[i].prevout.hash = InsecureRand256(); | ||
mtx.vin[i].prevout.n = 0; | ||
mtx.vin[i].scriptSig = random_script; | ||
} | ||
for (size_t o{0}; o < num_outputs; ++o) { | ||
mtx.vout[o].nValue = 1 * CENT; | ||
mtx.vout[o].scriptPubKey = random_script; | ||
} | ||
return MakeTransactionRef(mtx); | ||
} | ||
|
||
BOOST_FIXTURE_TEST_CASE(package_sanitization_tests, TestChain100NoDIP0001Setup) | ||
{ | ||
// Packages can't have more than 25 transactions. | ||
Package package_too_many; | ||
package_too_many.reserve(MAX_PACKAGE_COUNT + 1); | ||
for (size_t i{0}; i < MAX_PACKAGE_COUNT + 1; ++i) { | ||
package_too_many.emplace_back(create_placeholder_tx(1, 1)); | ||
} | ||
PackageValidationState state_too_many; | ||
BOOST_CHECK(!CheckPackage(package_too_many, state_too_many)); | ||
BOOST_CHECK_EQUAL(state_too_many.GetResult(), PackageValidationResult::PCKG_POLICY); | ||
BOOST_CHECK_EQUAL(state_too_many.GetRejectReason(), "package-too-many-transactions"); | ||
|
||
// Packages can't have a total size of more than 101KvB. | ||
CTransactionRef large_ptx = create_placeholder_tx(150, 150); | ||
Package package_too_large; | ||
auto size_large = GetVirtualTransactionSize(*large_ptx); | ||
size_t total_size{0}; | ||
while (total_size <= MAX_PACKAGE_SIZE * 1000) { | ||
package_too_large.push_back(large_ptx); | ||
total_size += size_large; | ||
} | ||
BOOST_CHECK(package_too_large.size() <= MAX_PACKAGE_COUNT); | ||
PackageValidationState state_too_large; | ||
BOOST_CHECK(!CheckPackage(package_too_large, state_too_large)); | ||
BOOST_CHECK_EQUAL(state_too_large.GetResult(), PackageValidationResult::PCKG_POLICY); | ||
BOOST_CHECK_EQUAL(state_too_large.GetRejectReason(), "package-too-large"); | ||
} | ||
|
||
BOOST_FIXTURE_TEST_CASE(package_validation_tests, TestChain100NoDIP0001Setup) | ||
{ | ||
LOCK(cs_main); | ||
unsigned int initialPoolSize = m_node.mempool->size(); | ||
|
||
// Parent and Child Package | ||
CKey parent_key; | ||
parent_key.MakeNewKey(true); | ||
CScript parent_locking_script = GetScriptForDestination(PKHash(parent_key.GetPubKey())); | ||
auto mtx_parent = CreateValidMempoolTransaction(/* input_transaction */ m_coinbase_txns[0], /* vout */ 0, | ||
/* input_height */ 0, /* input_signing_key */ coinbaseKey, | ||
/* output_destination */ parent_locking_script, | ||
/* output_amount */ CAmount(49 * COIN), /* submit */ false); | ||
CTransactionRef tx_parent = MakeTransactionRef(mtx_parent); | ||
|
||
CKey child_key; | ||
child_key.MakeNewKey(true); | ||
CScript child_locking_script = GetScriptForDestination(PKHash(child_key.GetPubKey())); | ||
auto mtx_child = CreateValidMempoolTransaction(/* input_transaction */ tx_parent, /* vout */ 0, | ||
/* input_height */ 101, /* input_signing_key */ parent_key, | ||
/* output_destination */ child_locking_script, | ||
/* output_amount */ CAmount(48 * COIN), /* submit */ false); | ||
CTransactionRef tx_child = MakeTransactionRef(mtx_child); | ||
const auto result_parent_child = ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool, {tx_parent, tx_child}, /* test_accept */ true); | ||
BOOST_CHECK_MESSAGE(result_parent_child.m_state.IsValid(), | ||
"Package validation unexpectedly failed: " << result_parent_child.m_state.GetRejectReason()); | ||
auto it_parent = result_parent_child.m_tx_results.find(tx_parent->GetHash()); | ||
auto it_child = result_parent_child.m_tx_results.find(tx_child->GetHash()); | ||
BOOST_CHECK(it_parent != result_parent_child.m_tx_results.end()); | ||
BOOST_CHECK_MESSAGE(it_parent->second.m_state.IsValid(), | ||
"Package validation unexpectedly failed: " << it_parent->second.m_state.GetRejectReason()); | ||
BOOST_CHECK(it_child != result_parent_child.m_tx_results.end()); | ||
BOOST_CHECK_MESSAGE(it_child->second.m_state.IsValid(), | ||
"Package validation unexpectedly failed: " << it_child->second.m_state.GetRejectReason()); | ||
|
||
// A single, giant transaction submitted through ProcessNewPackage fails on single tx policy. | ||
CTransactionRef giant_ptx = create_placeholder_tx(999, 999); | ||
BOOST_CHECK(GetVirtualTransactionSize(*giant_ptx) > MAX_PACKAGE_SIZE * 1000); | ||
auto result_single_large = ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool, {giant_ptx}, /* test_accept */ true); | ||
BOOST_CHECK(result_single_large.m_state.IsInvalid()); | ||
BOOST_CHECK_EQUAL(result_single_large.m_state.GetResult(), PackageValidationResult::PCKG_TX); | ||
BOOST_CHECK_EQUAL(result_single_large.m_state.GetRejectReason(), "transaction failed"); | ||
auto it_giant_tx = result_single_large.m_tx_results.find(giant_ptx->GetHash()); | ||
BOOST_CHECK(it_giant_tx != result_single_large.m_tx_results.end()); | ||
BOOST_CHECK_EQUAL(it_giant_tx->second.m_state.GetRejectReason(), "tx-size"); | ||
|
||
// Check that mempool size hasn't changed. | ||
BOOST_CHECK_EQUAL(m_node.mempool->size(), initialPoolSize); | ||
} | ||
BOOST_AUTO_TEST_SUITE_END() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.