66 uint64_t nConflictingCount = 0;
67 for (
const auto& mi : iters_conflicting) {
68 nConflictingCount += mi->GetCountWithDescendants();
74 return strprintf(
"rejecting replacement %s; too many potential replacements (%d > %d)\n",
92 std::set<uint256> parents_of_conflicts;
93 for (
const auto& mi : iters_conflicting) {
94 for (
const CTxIn& txin : mi->GetTx().vin) {
95 parents_of_conflicts.insert(txin.prevout.hash);
99 for (
unsigned int j = 0; j < tx.
vin.size(); j++) {
107 if (!parents_of_conflicts.count(tx.
vin[j].prevout.hash)) {
111 return strprintf(
"replacement %s adds unconfirmed input, idx %d",
120 const std::set<Txid>& direct_conflicts,
124 const Txid& hashAncestor = ancestorIt->GetTx().GetHash();
125 if (direct_conflicts.count(hashAncestor)) {
126 return strprintf(
"%s spends conflicting transaction %s",
138 for (
const auto& mi : iters_conflicting) {
149 CFeeRate original_feerate(mi->GetModifiedFee(), mi->GetTxSize());
150 if (replacement_feerate <= original_feerate) {
151 return strprintf(
"rejecting replacement %s; new feerate %s <= old feerate %s",
162 size_t replacement_vsize,
169 if (replacement_fees < original_fees) {
170 return strprintf(
"rejecting replacement %s, less fees than conflicting txs; %s < %s",
177 CAmount additional_fees = replacement_fees - original_fees;
178 if (additional_fees < relay_fee.
GetFee(replacement_vsize)) {
179 return strprintf(
"rejecting replacement %s, not enough additional fees to relay; %s < %s",
192 if (!chunk_results.has_value()) {
196 if (!std::is_gt(
CompareChunks(chunk_results.value().second, chunk_results.value().first))) {
int64_t CAmount
Amount in satoshis (Can be negative)
#define Assert(val)
Identity function.
Fee rate in satoshis per kilovirtualbyte: CAmount / kvB.
std::string ToString(const FeeEstimateMode &fee_estimate_mode=FeeEstimateMode::BTC_KVB) const
CAmount GetFee(uint32_t num_bytes) const
Return the fee in satoshis for the given vsize in vbytes.
The basic transaction that is broadcasted on the network and contained in blocks.
const Txid & GetHash() const LIFETIMEBOUND
const std::vector< CTxIn > vin
An input of a transaction.
util::Result< std::pair< std::vector< FeeFrac >, std::vector< FeeFrac > > > CalculateChunksForRBF()
Calculate the sorted chunks for the old and new mempool relating to the clusters that would be affect...
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
setEntries AssumeCalculateMemPoolAncestors(std::string_view calling_fn_name, const CTxMemPoolEntry &entry, const Limits &limits, bool fSearchForParents=true) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Same as CalculateMemPoolAncestors, but always returns a (non-optional) setEntries.
RecursiveMutex cs
This mutex needs to be locked when accessing mapTx or other members that are guarded by it.
std::set< txiter, CompareIteratorByHash > setEntries
indexed_transaction_set::nth_index< 0 >::type::const_iterator txiter
bool exists(const GenTxid >xid) const
void CalculateDescendants(txiter it, setEntries &setDescendants) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Populate setDescendants with all in-mempool descendants of hash.
const CTxMemPoolEntry * GetEntry(const Txid &txid) const LIFETIMEBOUND EXCLUSIVE_LOCKS_REQUIRED(cs)
static GenTxid Txid(const uint256 &hash)
std::string ToString() const
std::string ToString() const
std::string FormatMoney(const CAmount n)
Money parsing/formatting utilities.
bilingual_str ErrorString(const Result< T > &result)
std::optional< std::string > HasNoNewUnconfirmed(const CTransaction &tx, const CTxMemPool &pool, const CTxMemPool::setEntries &iters_conflicting)
The replacement transaction may only include an unconfirmed input if that input was included in one o...
std::optional< std::pair< DiagramCheckError, std::string > > ImprovesFeerateDiagram(CTxMemPool::ChangeSet &changeset)
The replacement transaction must improve the feerate diagram of the mempool.
std::optional< std::string > PaysForRBF(CAmount original_fees, CAmount replacement_fees, size_t replacement_vsize, CFeeRate relay_fee, const uint256 &txid)
The replacement transaction must pay more fees than the original transactions.
RBFTransactionState IsRBFOptInEmptyMempool(const CTransaction &tx)
std::optional< std::string > EntriesAndTxidsDisjoint(const CTxMemPool::setEntries &ancestors, const std::set< Txid > &direct_conflicts, const uint256 &txid)
Check the intersection between two sets of transactions (a set of mempool entries and a set of txids)...
std::optional< std::string > PaysMoreThanConflicts(const CTxMemPool::setEntries &iters_conflicting, CFeeRate replacement_feerate, const uint256 &txid)
Check that the feerate of the replacement transaction(s) is higher than the feerate of each of the tr...
RBFTransactionState IsRBFOptIn(const CTransaction &tx, const CTxMemPool &pool)
Determine whether an unconfirmed transaction is signaling opt-in to RBF according to BIP 125 This inv...
std::optional< std::string > GetEntriesForConflicts(const CTransaction &tx, CTxMemPool &pool, const CTxMemPool::setEntries &iters_conflicting, CTxMemPool::setEntries &all_conflicts)
Get all descendants of iters_conflicting.
RBFTransactionState
The rbf state of unconfirmed transactions.
@ UNKNOWN
Unconfirmed tx that does not signal rbf and is not in the mempool.
@ FINAL
Neither this tx nor a mempool ancestor signals rbf.
@ REPLACEABLE_BIP125
Either this tx or a mempool ancestor signals rbf.
static constexpr uint32_t MAX_REPLACEMENT_CANDIDATES
Maximum number of transactions that can be replaced by RBF (Rule #5).
@ FAILURE
New diagram wasn't strictly superior
@ UNCALCULABLE
Unable to calculate due to topology or other reason.
static constexpr MemPoolLimits NoLimits()
std::partial_ordering CompareChunks(Span< const FeeFrac > chunks0, Span< const FeeFrac > chunks1)
Compare the feerate diagrams implied by the provided sorted chunks data.
bool SignalsOptInRBF(const CTransaction &tx)
Check whether the sequence numbers on this transaction are signaling opt-in to replace-by-fee,...