| 986 | } |
| 987 | |
| 988 | bool MemPoolAccept::ReplacementChecks(Workspace& ws) |
| 989 | { |
| 990 | AssertLockHeld(cs_main); |
| 991 | AssertLockHeld(m_pool.cs); |
| 992 | |
| 993 | const CTransaction& tx = *ws.m_ptx; |
| 994 | const Txid& hash = ws.m_hash; |
| 995 | TxValidationState& state = ws.m_state; |
| 996 | |
| 997 | CFeeRate newFeeRate(ws.m_modified_fees, ws.m_vsize); |
| 998 | |
| 999 | CTxMemPool::setEntries all_conflicts; |
| 1000 | |
| 1001 | // Calculate all conflicting entries and enforce Rule #5. |
| 1002 | if (const auto err_string{GetEntriesForConflicts(tx, m_pool, ws.m_iters_conflicting, all_conflicts)}) { |
| 1003 | return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, |
| 1004 | strprintf("too many potential replacements%s", ws.m_sibling_eviction ? " (including sibling eviction)" : ""), *err_string); |
| 1005 | } |
| 1006 | |
| 1007 | // Check if it's economically rational to mine this transaction rather than the ones it |
| 1008 | // replaces and pays for its own relay fees. Enforce Rules #3 and #4. |
| 1009 | for (CTxMemPool::txiter it : all_conflicts) { |
| 1010 | m_subpackage.m_conflicting_fees += it->GetModifiedFee(); |
| 1011 | m_subpackage.m_conflicting_size += it->GetTxSize(); |
| 1012 | } |
| 1013 | |
| 1014 | if (const auto err_string{PaysForRBF(m_subpackage.m_conflicting_fees, ws.m_modified_fees, ws.m_vsize, |
| 1015 | m_pool.m_opts.incremental_relay_feerate, hash)}) { |
| 1016 | // Result may change in a package context |
| 1017 | return state.Invalid(TxValidationResult::TX_RECONSIDERABLE, |
| 1018 | strprintf("insufficient fee%s", ws.m_sibling_eviction ? " (including sibling eviction)" : ""), *err_string); |
| 1019 | } |
| 1020 | |
| 1021 | // Add all the to-be-removed transactions to the changeset. |
| 1022 | for (auto it : all_conflicts) { |
| 1023 | m_subpackage.m_changeset->StageRemoval(it); |
| 1024 | } |
| 1025 | |
| 1026 | // Run cluster size limit checks and fail if we exceed them. |
| 1027 | if (!m_subpackage.m_changeset->CheckMemPoolPolicyLimits()) { |
| 1028 | return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, "too-large-cluster", ""); |
| 1029 | } |
| 1030 | |
| 1031 | if (const auto err_string{ImprovesFeerateDiagram(*m_subpackage.m_changeset)}) { |
| 1032 | // We checked above for the cluster size limits being respected, so a |
| 1033 | // failure here can only be due to an insufficient fee. |
| 1034 | Assume(err_string->first == DiagramCheckError::FAILURE); |
| 1035 | return state.Invalid(TxValidationResult::TX_RECONSIDERABLE, "replacement-failed", err_string->second); |
| 1036 | } |
| 1037 | |
| 1038 | return true; |
| 1039 | } |
| 1040 | |
| 1041 | bool MemPoolAccept::PackageRBFChecks(const std::vector<CTransactionRef>& txns, |
| 1042 | std::vector<Workspace>& workspaces, |
nothing calls this directly
no test coverage detected