@@ -478,6 +478,9 @@ class MemPoolAccept
478
478
*/
479
479
const std::optional<CFeeRate> m_client_maxfeerate;
480
480
481
+ /* * Whether CPFP carveout and RBF carveout are granted. */
482
+ const bool m_allow_carveouts;
483
+
481
484
/* * Parameters for single transaction mempool validation. */
482
485
static ATMPArgs SingleAccept (const CChainParams& chainparams, int64_t accept_time,
483
486
bool bypass_limits, std::vector<COutPoint>& coins_to_uncache,
@@ -492,6 +495,7 @@ class MemPoolAccept
492
495
/* m_package_submission */ false ,
493
496
/* m_package_feerates */ false ,
494
497
/* m_client_maxfeerate */ {}, // checked by caller
498
+ /* m_allow_carveouts */ true ,
495
499
};
496
500
}
497
501
@@ -508,6 +512,7 @@ class MemPoolAccept
508
512
/* m_package_submission */ false , // not submitting to mempool
509
513
/* m_package_feerates */ false ,
510
514
/* m_client_maxfeerate */ {}, // checked by caller
515
+ /* m_allow_carveouts */ false ,
511
516
};
512
517
}
513
518
@@ -524,6 +529,7 @@ class MemPoolAccept
524
529
/* m_package_submission */ true ,
525
530
/* m_package_feerates */ true ,
526
531
/* m_client_maxfeerate */ client_maxfeerate,
532
+ /* m_allow_carveouts */ false ,
527
533
};
528
534
}
529
535
@@ -539,6 +545,7 @@ class MemPoolAccept
539
545
/* m_package_submission */ true , // do not LimitMempoolSize in Finalize()
540
546
/* m_package_feerates */ false , // only 1 transaction
541
547
/* m_client_maxfeerate */ package_args.m_client_maxfeerate ,
548
+ /* m_allow_carveouts */ false ,
542
549
};
543
550
}
544
551
@@ -554,7 +561,8 @@ class MemPoolAccept
554
561
bool allow_sibling_eviction,
555
562
bool package_submission,
556
563
bool package_feerates,
557
- std::optional<CFeeRate> client_maxfeerate)
564
+ std::optional<CFeeRate> client_maxfeerate,
565
+ bool allow_carveouts)
558
566
: m_chainparams{chainparams},
559
567
m_accept_time{accept_time},
560
568
m_bypass_limits{bypass_limits},
@@ -564,7 +572,8 @@ class MemPoolAccept
564
572
m_allow_sibling_eviction{allow_sibling_eviction},
565
573
m_package_submission{package_submission},
566
574
m_package_feerates{package_feerates},
567
- m_client_maxfeerate{client_maxfeerate}
575
+ m_client_maxfeerate{client_maxfeerate},
576
+ m_allow_carveouts{allow_carveouts}
568
577
{
569
578
}
570
579
};
@@ -917,7 +926,7 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
917
926
CTxMemPool::Limits maybe_rbf_limits = m_pool.m_opts .limits ;
918
927
919
928
// Calculate in-mempool ancestors, up to a limit.
920
- if (ws.m_conflicts .size () == 1 ) {
929
+ if (ws.m_conflicts .size () == 1 && args. m_allow_carveouts ) {
921
930
// In general, when we receive an RBF transaction with mempool conflicts, we want to know whether we
922
931
// would meet the chain limits after the conflicts have been removed. However, there isn't a practical
923
932
// way to do this short of calculating the ancestor and descendant sets with an overlay cache of
@@ -956,6 +965,13 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
956
965
ws.m_ancestors = std::move (*ancestors);
957
966
} else {
958
967
// If CalculateMemPoolAncestors fails second time, we want the original error string.
968
+ const auto error_message{util::ErrorString (ancestors).original };
969
+
970
+ // Carve-out is not allowed in this context; fail
971
+ if (!args.m_allow_carveouts ) {
972
+ return state.Invalid (TxValidationResult::TX_MEMPOOL_POLICY, " too-long-mempool-chain" , error_message);
973
+ }
974
+
959
975
// Contracting/payment channels CPFP carve-out:
960
976
// If the new transaction is relatively small (up to 40k weight)
961
977
// and has at most one ancestor (ie ancestor limit of 2, including
@@ -974,7 +990,6 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
974
990
.descendant_count = maybe_rbf_limits.descendant_count + 1 ,
975
991
.descendant_size_vbytes = maybe_rbf_limits.descendant_size_vbytes + EXTRA_DESCENDANT_TX_SIZE_LIMIT,
976
992
};
977
- const auto error_message{util::ErrorString (ancestors).original };
978
993
if (ws.m_vsize > EXTRA_DESCENDANT_TX_SIZE_LIMIT || ws.m_ptx ->nVersion == 3 ) {
979
994
return state.Invalid (TxValidationResult::TX_MEMPOOL_POLICY, " too-long-mempool-chain" , error_message);
980
995
}
@@ -1431,9 +1446,7 @@ PackageMempoolAcceptResult MemPoolAccept::AcceptMultipleTransactions(const std::
1431
1446
}
1432
1447
1433
1448
// Apply package mempool ancestor/descendant limits. Skip if there is only one transaction,
1434
- // because it's unnecessary. Also, CPFP carve out can increase the limit for individual
1435
- // transactions, but this exemption is not extended to packages in CheckPackageLimits().
1436
- std::string err_string;
1449
+ // because it's unnecessary.
1437
1450
if (txns.size () > 1 && !PackageMempoolChecks (txns, m_total_vsize, package_state)) {
1438
1451
return PackageMempoolAcceptResult (package_state, std::move (results));
1439
1452
}
0 commit comments