@@ -688,7 +688,7 @@ class MemPoolAccept
688688 bool ConsensusScriptChecks (const ATMPArgs& args, Workspace& ws) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_pool.cs);
689689
690690 // Try to add the transaction to the mempool, removing any conflicts first.
691- void FinalizeSubpackage (const ATMPArgs& args, std::vector<Workspace>& ws ) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_pool.cs);
691+ void FinalizeSubpackage (const ATMPArgs& args) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_pool.cs);
692692
693693 // Submit all transactions to the mempool and call ConsensusScriptChecks to add to the script
694694 // cache - should only be called after successful validation of all transactions in the package.
@@ -1283,34 +1283,48 @@ bool MemPoolAccept::ConsensusScriptChecks(const ATMPArgs& args, Workspace& ws)
12831283 return true ;
12841284}
12851285
1286- void MemPoolAccept::FinalizeSubpackage (const ATMPArgs& args, std::vector<Workspace>& workspaces )
1286+ void MemPoolAccept::FinalizeSubpackage (const ATMPArgs& args)
12871287{
12881288 AssertLockHeld (cs_main);
12891289 AssertLockHeld (m_pool.cs );
1290- const CTransaction& tx = *workspaces.front ().m_ptx ;
1291- const uint256& hash = workspaces.front ().m_hash ;
12921290
12931291 if (!m_subpackage.m_all_conflicts .empty ()) Assume (args.m_allow_replacement );
12941292 // Remove conflicting transactions from the mempool
12951293 for (CTxMemPool::txiter it : m_subpackage.m_all_conflicts )
12961294 {
1297- LogDebug (BCLog::MEMPOOL, " replacing mempool tx %s (wtxid=%s, fees=%s, vsize=%s). New tx %s (wtxid=%s, fees=%s, vsize=%s)\n " ,
1298- it->GetTx ().GetHash ().ToString (),
1299- it->GetTx ().GetWitnessHash ().ToString (),
1300- it->GetFee (),
1301- it->GetTxSize (),
1302- hash.ToString (),
1303- tx.GetWitnessHash ().ToString (),
1304- workspaces[0 ].m_tx_handle ->GetFee (),
1305- workspaces[0 ].m_tx_handle ->GetTxSize ());
1295+ std::string log_string = strprintf (" replacing mempool tx %s (wtxid=%s, fees=%s, vsize=%s). " ,
1296+ it->GetTx ().GetHash ().ToString (),
1297+ it->GetTx ().GetWitnessHash ().ToString (),
1298+ it->GetFee (),
1299+ it->GetTxSize ());
1300+ FeeFrac feerate{m_subpackage.m_total_modified_fees , int32_t (m_subpackage.m_total_vsize )};
1301+ uint256 tx_or_package_hash{};
1302+ if (m_subpackage.m_changeset ->GetTxCount () == 1 ) {
1303+ const CTransaction& tx = m_subpackage.m_changeset ->GetAddedTxn (0 );
1304+ tx_or_package_hash = tx.GetHash ();
1305+ log_string += strprintf (" New tx %s (wtxid=%s, fees=%s, vsize=%s)" ,
1306+ tx.GetHash ().ToString (),
1307+ tx.GetWitnessHash ().ToString (),
1308+ feerate.fee ,
1309+ feerate.size );
1310+ } else {
1311+ tx_or_package_hash = GetPackageHash (m_subpackage.m_changeset ->GetAddedTxns ());
1312+ log_string += strprintf (" New package %s with %lu txs, fees=%s, vsize=%s" ,
1313+ tx_or_package_hash.ToString (),
1314+ m_subpackage.m_changeset ->GetTxCount (),
1315+ feerate.fee ,
1316+ feerate.size );
1317+
1318+ }
1319+ LogDebug (BCLog::MEMPOOL, " %s\n " , log_string);
13061320 TRACEPOINT (mempool, replaced,
13071321 it->GetTx ().GetHash ().data (),
13081322 it->GetTxSize (),
13091323 it->GetFee (),
13101324 std::chrono::duration_cast<std::chrono::duration<std::uint64_t >>(it->GetTime ()).count (),
1311- hash .data (),
1312- workspaces[ 0 ]. m_tx_handle -> GetTxSize () ,
1313- workspaces[ 0 ]. m_tx_handle -> GetFee ()
1325+ tx_or_package_hash .data (),
1326+ feerate. size ,
1327+ feerate. fee
13141328 );
13151329 m_subpackage.m_replaced_transactions .push_back (it->GetSharedTx ());
13161330 }
@@ -1333,7 +1347,7 @@ bool MemPoolAccept::SubmitPackage(const ATMPArgs& args, std::vector<Workspace>&
13331347 return !m_pool.exists (GenTxid::Txid (ws.m_ptx ->GetHash ())); }));
13341348
13351349 bool all_submitted = true ;
1336- FinalizeSubpackage (args, workspaces );
1350+ FinalizeSubpackage (args);
13371351 // ConsensusScriptChecks adds to the script cache and is therefore consensus-critical;
13381352 // CheckInputsFromMempoolAndCache asserts that transactions only spend coins available from the
13391353 // mempool or UTXO set. Submit each transaction to the mempool immediately after calling
@@ -1402,8 +1416,7 @@ MempoolAcceptResult MemPoolAccept::AcceptSingleTransaction(const CTransactionRef
14021416 AssertLockHeld (cs_main);
14031417 LOCK (m_pool.cs ); // mempool "read lock" (held through m_pool.m_opts.signals->TransactionAddedToMempool())
14041418
1405- std::vector<Workspace> workspaces{Workspace (ptx)};
1406- Workspace &ws = workspaces.front ();
1419+ Workspace ws (ptx);
14071420 const std::vector<Wtxid> single_wtxid{ws.m_ptx ->GetWitnessHash ()};
14081421
14091422 if (!PreChecks (args, ws)) {
@@ -1414,6 +1427,9 @@ MempoolAcceptResult MemPoolAccept::AcceptSingleTransaction(const CTransactionRef
14141427 return MempoolAcceptResult::Failure (ws.m_state );
14151428 }
14161429
1430+ m_subpackage.m_total_vsize = ws.m_vsize ;
1431+ m_subpackage.m_total_modified_fees = ws.m_modified_fees ;
1432+
14171433 // Individual modified feerate exceeded caller-defined max; abort
14181434 if (args.m_client_maxfeerate && CFeeRate (ws.m_modified_fees , ws.m_vsize ) > args.m_client_maxfeerate .value ()) {
14191435 ws.m_state .Invalid (TxValidationResult::TX_MEMPOOL_POLICY, " max feerate exceeded" , " " );
@@ -1451,12 +1467,9 @@ MempoolAcceptResult MemPoolAccept::AcceptSingleTransaction(const CTransactionRef
14511467 ws.m_base_fees , effective_feerate, single_wtxid);
14521468 }
14531469
1454- FinalizeSubpackage (args, workspaces );
1470+ FinalizeSubpackage (args);
14551471
1456- // trim mempool and check if tx was trimmed
1457- // If we are validating a package, don't trim here because we could evict a previous transaction
1458- // in the package. LimitMempoolSize() should be called at the very end to make sure the mempool
1459- // is still within limits and package submission happens atomically.
1472+ // Limit the mempool, if appropriate.
14601473 if (!args.m_package_submission && !args.m_bypass_limits ) {
14611474 LimitMempoolSize (m_pool, m_active_chainstate.CoinsTip ());
14621475 if (!m_pool.exists (GenTxid::Txid (ws.m_hash ))) {
0 commit comments