Merge bitcoin/bitcoin#30295: #28984 package rbf followups

3f00aae140 package rbf: cpfp structure requires package > parent feerate (Greg Sanders)
ad7f1f697f test package rbf boundary conditions more closely (Greg Sanders)
ff4558d441 doc: reword package RBF documentation (Greg Sanders)
de669a883b doc: replace mention of V3 with TRUC (Greg Sanders)

Pull request description:

  Some suggested nits/changes from #28984

ACKs for top commit:
  glozow:
    ACK 3f00aae140
  murchandamus:
    ACK 3f00aae140

Tree-SHA512: 79434cc8aba25a43e99793298cdc99cad807db2c3a2e780a31953f244b95eecd97b90559abd67fbf30996c00966675fa257253a7812ec4727420226162c629ae
This commit is contained in:
merge-script 2024-07-12 17:15:27 +01:00
commit c4d45b695e
No known key found for this signature in database
GPG key ID: 2EEB9F5CC09526C1
3 changed files with 23 additions and 11 deletions

View file

@ -38,11 +38,11 @@ The following rules are enforced for all packages:
* Only limited package replacements are currently considered. (#28984)
- All direct conflicts must signal replacement (or have `-mempoolfullrbf=1` set).
- All direct conflicts must signal replacement (or the node must have `-mempoolfullrbf=1` set).
- Packages are 1-parent-1-child, with no in-mempool ancestors of the package.
- All conflicting clusters(connected components of mempool transactions) must be clusters of up to size 2.
- All conflicting clusters (connected components of mempool transactions) must be clusters of up to size 2.
- No more than MAX_REPLACEMENT_CANDIDATES transactions can be replaced, analogous to
regular [replacement rule](./mempool-replacements.md) 5).
@ -56,7 +56,7 @@ The following rules are enforced for all packages:
- *Rationale*: Basic support for package RBF can be used by wallets
by making chains of no longer than two, then directly conflicting
those chains when needed. Combined with V3 transactions this can
those chains when needed. Combined with TRUC transactions this can
result in more robust fee bumping. More general package RBF may be
enabled in the future.

View file

@ -1208,7 +1208,7 @@ bool MemPoolAccept::PackageMempoolChecks(const std::vector<CTransactionRef>& txn
const CFeeRate package_feerate(m_subpackage.m_total_modified_fees, m_subpackage.m_total_vsize);
if (package_feerate <= parent_feerate) {
return package_state.Invalid(PackageValidationResult::PCKG_POLICY,
"package RBF failed: package feerate is less than parent feerate",
"package RBF failed: package feerate is less than or equal to parent feerate",
strprintf("package feerate %s <= parent feerate is %s", package_feerate.ToString(), parent_feerate.ToString()));
}

View file

@ -168,11 +168,20 @@ class PackageRBFTest(BitcoinTestFramework):
self.assert_mempool_contents(expected=package_txns1)
self.log.info("Check replacement pays for incremental bandwidth")
package_hex3, package_txns3 = self.create_simple_package(coin, parent_fee=DEFAULT_FEE, child_fee=DEFAULT_CHILD_FEE)
pkg_results3 = node.submitpackage(package_hex3)
assert_equal(f"package RBF failed: insufficient anti-DoS fees, rejecting replacement {package_txns3[1].rehash()}, not enough additional fees to relay; 0.00 < 0.00000{sum([tx.get_vsize() for tx in package_txns3])}", pkg_results3["package_msg"])
_, placeholder_txns3 = self.create_simple_package(coin)
package_3_size = sum([tx.get_vsize() for tx in placeholder_txns3])
incremental_sats_required = Decimal(package_3_size) / COIN
incremental_sats_short = incremental_sats_required - Decimal("0.00000001")
# Recreate the package with slightly higher fee once we know the size of the new package, but still short of required fee
failure_package_hex3, failure_package_txns3 = self.create_simple_package(coin, parent_fee=DEFAULT_FEE, child_fee=DEFAULT_CHILD_FEE + incremental_sats_short)
assert_equal(package_3_size, sum([tx.get_vsize() for tx in failure_package_txns3]))
pkg_results3 = node.submitpackage(failure_package_hex3)
assert_equal(f"package RBF failed: insufficient anti-DoS fees, rejecting replacement {failure_package_txns3[1].rehash()}, not enough additional fees to relay; {incremental_sats_short} < {incremental_sats_required}", pkg_results3["package_msg"])
self.assert_mempool_contents(expected=package_txns1)
success_package_hex3, success_package_txns3 = self.create_simple_package(coin, parent_fee=DEFAULT_FEE, child_fee=DEFAULT_CHILD_FEE + incremental_sats_required)
node.submitpackage(success_package_hex3)
self.assert_mempool_contents(expected=success_package_txns3)
self.generate(node, 1)
self.log.info("Check Package RBF must have strict cpfp structure")
@ -180,11 +189,14 @@ class PackageRBFTest(BitcoinTestFramework):
package_hex4, package_txns4 = self.create_simple_package(coin, parent_fee=DEFAULT_FEE, child_fee=DEFAULT_CHILD_FEE)
node.submitpackage(package_hex4)
self.assert_mempool_contents(expected=package_txns4)
package_hex5, package_txns5 = self.create_simple_package(coin, parent_fee=DEFAULT_CHILD_FEE, child_fee=DEFAULT_CHILD_FEE - Decimal("0.00000001"))
package_hex5, package_txns5 = self.create_simple_package(coin, parent_fee=DEFAULT_CHILD_FEE, child_fee=DEFAULT_CHILD_FEE)
pkg_results5 = node.submitpackage(package_hex5)
assert 'package RBF failed: package feerate is less than parent feerate' in pkg_results5["package_msg"]
assert 'package RBF failed: package feerate is less than or equal to parent feerate' in pkg_results5["package_msg"]
self.assert_mempool_contents(expected=package_txns4)
package_hex5_1, package_txns5_1 = self.create_simple_package(coin, parent_fee=DEFAULT_CHILD_FEE, child_fee=DEFAULT_CHILD_FEE + Decimal("0.00000001"))
node.submitpackage(package_hex5_1)
self.assert_mempool_contents(expected=package_txns5_1)
self.generate(node, 1)
def test_package_rbf_max_conflicts(self):