MCPcopy Create free account
hub / github.com/bitcoin/bitcoin / PackageRBFChecks

Method PackageRBFChecks

src/validation.cpp:1041–1137  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1039}
1040
1041bool MemPoolAccept::PackageRBFChecks(const std::vector<CTransactionRef>& txns,
1042 std::vector<Workspace>& workspaces,
1043 const int64_t total_vsize,
1044 PackageValidationState& package_state)
1045{
1046 AssertLockHeld(cs_main);
1047 AssertLockHeld(m_pool.cs);
1048
1049 assert(std::all_of(txns.cbegin(), txns.cend(), [this](const auto& tx)
1050 { return !m_pool.exists(tx->GetHash());}));
1051
1052 assert(txns.size() == workspaces.size());
1053
1054 // We're in package RBF context; replacement proposal must be size 2
1055 if (workspaces.size() != 2 || !Assume(IsChildWithParents(txns))) {
1056 return package_state.Invalid(PackageValidationResult::PCKG_POLICY, "package RBF failed: package must be 1-parent-1-child");
1057 }
1058
1059 // If the package has in-mempool parents, we won't consider a package RBF
1060 // since it would result in a cluster larger than 2.
1061 // N.B. To relax this constraint we will need to revisit how CCoinsViewMemPool::PackageAddTransaction
1062 // is being used inside AcceptMultipleTransactions to track available inputs while processing a package.
1063 // Specifically we would need to check that the ancestors of the new
1064 // transactions don't intersect with the set of transactions to be removed
1065 // due to RBF, which is not checked at all in the package acceptance
1066 // context.
1067 for (const auto& ws : workspaces) {
1068 if (!ws.m_parents.empty()) {
1069 return package_state.Invalid(PackageValidationResult::PCKG_POLICY, "package RBF failed: new transaction cannot have mempool ancestors");
1070 }
1071 }
1072
1073 // Aggregate all conflicts into one set.
1074 CTxMemPool::setEntries direct_conflict_iters;
1075 for (Workspace& ws : workspaces) {
1076 // Aggregate all conflicts into one set.
1077 direct_conflict_iters.merge(ws.m_iters_conflicting);
1078 }
1079
1080 const auto& parent_ws = workspaces[0];
1081 const auto& child_ws = workspaces[1];
1082
1083 // Don't consider replacements that would cause us to remove a large number of mempool entries.
1084 // This limit is not increased in a package RBF. Use the aggregate number of transactions.
1085 CTxMemPool::setEntries all_conflicts;
1086 if (const auto err_string{GetEntriesForConflicts(*child_ws.m_ptx, m_pool, direct_conflict_iters,
1087 all_conflicts)}) {
1088 return package_state.Invalid(PackageValidationResult::PCKG_POLICY,
1089 "package RBF failed: too many potential replacements", *err_string);
1090 }
1091
1092 for (CTxMemPool::txiter it : all_conflicts) {
1093 m_subpackage.m_changeset->StageRemoval(it);
1094 m_subpackage.m_conflicting_fees += it->GetModifiedFee();
1095 m_subpackage.m_conflicting_size += it->GetTxSize();
1096 }
1097
1098 // Use the child as the transaction for attributing errors to.

Callers

nothing calls this directly

Calls 15

IsChildWithParentsFunction · 0.85
GetEntriesForConflictsFunction · 0.85
PaysForRBFFunction · 0.85
ImprovesFeerateDiagramFunction · 0.85
GetPackageHashFunction · 0.85
InvalidMethod · 0.80
mergeMethod · 0.80
StageRemovalMethod · 0.80
cbeginMethod · 0.45
cendMethod · 0.45
existsMethod · 0.45

Tested by

no test coverage detected