@ -4,6 +4,8 @@
# include <consensus/validation.h>
# include <consensus/validation.h>
# include <key_io.h>
# include <key_io.h>
# include <policy/packages.h>
# include <policy/policy.h>
# include <primitives/transaction.h>
# include <primitives/transaction.h>
# include <script/script.h>
# include <script/script.h>
# include <script/standard.h>
# include <script/standard.h>
@ -49,6 +51,25 @@ BOOST_FIXTURE_TEST_CASE(tx_mempool_reject_coinbase, TestChain100Setup)
BOOST_CHECK ( result . m_state . GetResult ( ) = = TxValidationResult : : TX_CONSENSUS ) ;
BOOST_CHECK ( result . m_state . GetResult ( ) = = TxValidationResult : : TX_CONSENSUS ) ;
}
}
// 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_tests , TestChain100Setup )
BOOST_FIXTURE_TEST_CASE ( package_tests , TestChain100Setup )
{
{
LOCK ( cs_main ) ;
LOCK ( cs_main ) ;
@ -84,6 +105,43 @@ BOOST_FIXTURE_TEST_CASE(package_tests, TestChain100Setup)
BOOST_CHECK_MESSAGE ( it_child - > second . m_state . IsValid ( ) ,
BOOST_CHECK_MESSAGE ( it_child - > second . m_state . IsValid ( ) ,
" Package validation unexpectedly failed: " < < it_child - > second . m_state . GetRejectReason ( ) ) ;
" Package validation unexpectedly failed: " < < it_child - > second . m_state . GetRejectReason ( ) ) ;
// 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 ) ) ;
}
auto result_too_many = ProcessNewPackage ( m_node . chainman - > ActiveChainstate ( ) , * m_node . mempool , package_too_many , /* test_accept */ true ) ;
BOOST_CHECK ( result_too_many . m_state . IsInvalid ( ) ) ;
BOOST_CHECK_EQUAL ( result_too_many . m_state . GetResult ( ) , PackageValidationResult : : PCKG_POLICY ) ;
BOOST_CHECK_EQUAL ( result_too_many . m_state . 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 ) ;
auto result_too_large = ProcessNewPackage ( m_node . chainman - > ActiveChainstate ( ) , * m_node . mempool , package_too_large , /* test_accept */ true ) ;
BOOST_CHECK ( result_too_large . m_state . IsInvalid ( ) ) ;
BOOST_CHECK_EQUAL ( result_too_large . m_state . GetResult ( ) , PackageValidationResult : : PCKG_POLICY ) ;
BOOST_CHECK_EQUAL ( result_too_large . m_state . GetRejectReason ( ) , " package-too-large " ) ;
// 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 - > GetWitnessHash ( ) ) ;
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.
// Check that mempool size hasn't changed.
BOOST_CHECK_EQUAL ( m_node . mempool - > size ( ) , initialPoolSize ) ;
BOOST_CHECK_EQUAL ( m_node . mempool - > size ( ) , initialPoolSize ) ;
}
}