Skip to content

Commit 93d20a7

Browse files
author
MarcoFalke
committed
Merge #11309: Minor cleanups for AcceptToMemoryPool
bf64c3c Ignore transactions added to mempool during a reorg for fee estimation purposes. (Alex Morcos) 04f78ab Do not reject based on mempool min fee when bypass_limits is set. (Alex Morcos) fd849e1 Change AcceptToMemoryPool function signature (Alex Morcos) Pull request description: First commit just removes default arguments from `AcceptToMemoryPool` and consolidates two arguments, it does not change behavior. Second commit finally fixes the fact that we're not meant to reject based on mempool min fee when adding a transaction from a disconnected block during a reorg as mentioned [here](bitcoin/bitcoin#9602 (comment)) Third commit makes fee estimation ignore transactions added from a disconnected block during a reorg. I think this was another source of fee estimates returning estimates below 1000 sat/kB as in #11303. Tree-SHA512: 30925ca8b341915bb214f1d2590b36b7931f2e125b7660150e38ae70338f00db5aa7f1608546dddb181446924177eb7cf62ea8bd2583068acc074d6c3f86bc0c
2 parents bbc901d + bf64c3c commit 93d20a7

File tree

6 files changed

+34
-27
lines changed

6 files changed

+34
-27
lines changed

src/net_processing.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1788,7 +1788,8 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
17881788

17891789
std::list<CTransactionRef> lRemovedTxn;
17901790

1791-
if (!AlreadyHave(inv) && AcceptToMemoryPool(mempool, state, ptx, true, &fMissingInputs, &lRemovedTxn)) {
1791+
if (!AlreadyHave(inv) &&
1792+
AcceptToMemoryPool(mempool, state, ptx, &fMissingInputs, &lRemovedTxn, false /* bypass_limits */, 0 /* nAbsurdFee */)) {
17921793
mempool.check(pcoinsTip);
17931794
RelayTransaction(tx, connman);
17941795
for (unsigned int i = 0; i < tx.vout.size(); i++) {
@@ -1826,7 +1827,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
18261827

18271828
if (setMisbehaving.count(fromPeer))
18281829
continue;
1829-
if (AcceptToMemoryPool(mempool, stateDummy, porphanTx, true, &fMissingInputs2, &lRemovedTxn)) {
1830+
if (AcceptToMemoryPool(mempool, stateDummy, porphanTx, &fMissingInputs2, &lRemovedTxn, false /* bypass_limits */, 0 /* nAbsurdFee */)) {
18301831
LogPrint(BCLog::MEMPOOL, " accepted orphan tx %s\n", orphanHash.ToString());
18311832
RelayTransaction(orphanTx, connman);
18321833
for (unsigned int i = 0; i < orphanTx.vout.size(); i++) {

src/rpc/rawtransaction.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -942,8 +942,8 @@ UniValue sendrawtransaction(const JSONRPCRequest& request)
942942
// push to local node and sync with wallets
943943
CValidationState state;
944944
bool fMissingInputs;
945-
bool fLimitFree = true;
946-
if (!AcceptToMemoryPool(mempool, state, std::move(tx), fLimitFree, &fMissingInputs, nullptr, false, nMaxRawTxFee)) {
945+
if (!AcceptToMemoryPool(mempool, state, std::move(tx), &fMissingInputs,
946+
nullptr /* plTxnReplaced */, false /* bypass_limits */, nMaxRawTxFee)) {
947947
if (state.IsInvalid()) {
948948
throw JSONRPCError(RPC_TRANSACTION_REJECTED, strprintf("%i: %s", state.GetRejectCode(), state.GetRejectReason()));
949949
} else {

src/test/txvalidationcache_tests.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ ToMemPool(CMutableTransaction& tx)
2929
LOCK(cs_main);
3030

3131
CValidationState state;
32-
return AcceptToMemoryPool(mempool, state, MakeTransactionRef(tx), false, nullptr, nullptr, true, 0);
32+
return AcceptToMemoryPool(mempool, state, MakeTransactionRef(tx), nullptr /* pfMissingInputs */,
33+
nullptr /* plTxnReplaced */, true /* bypass_limits */, 0 /* nAbsurdFee */);
3334
}
3435

3536
BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup)

src/validation.cpp

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,9 @@ void UpdateMempoolForReorg(DisconnectedBlockTransactions &disconnectpool, bool f
384384
while (it != disconnectpool.queuedTx.get<insertion_order>().rend()) {
385385
// ignore validation errors in resurrected transactions
386386
CValidationState stateDummy;
387-
if (!fAddToMempool || (*it)->IsCoinBase() || !AcceptToMemoryPool(mempool, stateDummy, *it, false, nullptr, nullptr, true)) {
387+
if (!fAddToMempool || (*it)->IsCoinBase() ||
388+
!AcceptToMemoryPool(mempool, stateDummy, *it, nullptr /* pfMissingInputs */,
389+
nullptr /* plTxnReplaced */, true /* bypass_limits */, 0 /* nAbsurdFee */)) {
388390
// If the transaction doesn't make it in to the mempool, remove any
389391
// transactions that depend on it (which would now be orphans).
390392
mempool.removeRecursive(**it, MemPoolRemovalReason::REORG);
@@ -443,9 +445,9 @@ static bool CheckInputsFromMempoolAndCache(const CTransaction& tx, CValidationSt
443445
return CheckInputs(tx, state, view, true, flags, cacheSigStore, true, txdata);
444446
}
445447

446-
static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool& pool, CValidationState& state, const CTransactionRef& ptx, bool fLimitFree,
448+
static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool& pool, CValidationState& state, const CTransactionRef& ptx,
447449
bool* pfMissingInputs, int64_t nAcceptTime, std::list<CTransactionRef>* plTxnReplaced,
448-
bool fOverrideMempoolLimit, const CAmount& nAbsurdFee, std::vector<COutPoint>& coins_to_uncache)
450+
bool bypass_limits, const CAmount& nAbsurdFee, std::vector<COutPoint>& coins_to_uncache)
449451
{
450452
const CTransaction& tx = *ptx;
451453
const uint256 hash = tx.GetHash();
@@ -618,12 +620,12 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool
618620
strprintf("%d", nSigOpsCost));
619621

620622
CAmount mempoolRejectFee = pool.GetMinFee(gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000).GetFee(nSize);
621-
if (mempoolRejectFee > 0 && nModifiedFees < mempoolRejectFee) {
623+
if (!bypass_limits && mempoolRejectFee > 0 && nModifiedFees < mempoolRejectFee) {
622624
return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "mempool min fee not met", false, strprintf("%d < %d", nFees, mempoolRejectFee));
623625
}
624626

625627
// No transactions are allowed below minRelayTxFee except from disconnected blocks
626-
if (fLimitFree && nModifiedFees < ::minRelayTxFee.GetFee(nSize)) {
628+
if (!bypass_limits && nModifiedFees < ::minRelayTxFee.GetFee(nSize)) {
627629
return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "min relay fee not met");
628630
}
629631

@@ -855,17 +857,18 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool
855857
}
856858
pool.RemoveStaged(allConflicting, false, MemPoolRemovalReason::REPLACED);
857859

858-
// This transaction should only count for fee estimation if it isn't a
859-
// BIP 125 replacement transaction (may not be widely supported), the
860-
// node is not behind, and the transaction is not dependent on any other
861-
// transactions in the mempool.
862-
bool validForFeeEstimation = !fReplacementTransaction && IsCurrentForFeeEstimation() && pool.HasNoInputsOf(tx);
860+
// This transaction should only count for fee estimation if:
861+
// - it isn't a BIP 125 replacement transaction (may not be widely supported)
862+
// - it's not being readded during a reorg which bypasses typical mempool fee limits
863+
// - the node is not behind
864+
// - the transaction is not dependent on any other transactions in the mempool
865+
bool validForFeeEstimation = !fReplacementTransaction && !bypass_limits && IsCurrentForFeeEstimation() && pool.HasNoInputsOf(tx);
863866

864867
// Store transaction in memory
865868
pool.addUnchecked(hash, entry, setAncestors, validForFeeEstimation);
866869

867870
// trim mempool and check if tx was trimmed
868-
if (!fOverrideMempoolLimit) {
871+
if (!bypass_limits) {
869872
LimitMempoolSize(pool, gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000, gArgs.GetArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY) * 60 * 60);
870873
if (!pool.exists(hash))
871874
return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "mempool full");
@@ -878,12 +881,12 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool
878881
}
879882

880883
/** (try to) add transaction to memory pool with a specified acceptance time **/
881-
static bool AcceptToMemoryPoolWithTime(const CChainParams& chainparams, CTxMemPool& pool, CValidationState &state, const CTransactionRef &tx, bool fLimitFree,
884+
static bool AcceptToMemoryPoolWithTime(const CChainParams& chainparams, CTxMemPool& pool, CValidationState &state, const CTransactionRef &tx,
882885
bool* pfMissingInputs, int64_t nAcceptTime, std::list<CTransactionRef>* plTxnReplaced,
883-
bool fOverrideMempoolLimit, const CAmount nAbsurdFee)
886+
bool bypass_limits, const CAmount nAbsurdFee)
884887
{
885888
std::vector<COutPoint> coins_to_uncache;
886-
bool res = AcceptToMemoryPoolWorker(chainparams, pool, state, tx, fLimitFree, pfMissingInputs, nAcceptTime, plTxnReplaced, fOverrideMempoolLimit, nAbsurdFee, coins_to_uncache);
889+
bool res = AcceptToMemoryPoolWorker(chainparams, pool, state, tx, pfMissingInputs, nAcceptTime, plTxnReplaced, bypass_limits, nAbsurdFee, coins_to_uncache);
887890
if (!res) {
888891
for (const COutPoint& hashTx : coins_to_uncache)
889892
pcoinsTip->Uncache(hashTx);
@@ -894,12 +897,12 @@ static bool AcceptToMemoryPoolWithTime(const CChainParams& chainparams, CTxMemPo
894897
return res;
895898
}
896899

897-
bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransactionRef &tx, bool fLimitFree,
900+
bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransactionRef &tx,
898901
bool* pfMissingInputs, std::list<CTransactionRef>* plTxnReplaced,
899-
bool fOverrideMempoolLimit, const CAmount nAbsurdFee)
902+
bool bypass_limits, const CAmount nAbsurdFee)
900903
{
901904
const CChainParams& chainparams = Params();
902-
return AcceptToMemoryPoolWithTime(chainparams, pool, state, tx, fLimitFree, pfMissingInputs, GetTime(), plTxnReplaced, fOverrideMempoolLimit, nAbsurdFee);
905+
return AcceptToMemoryPoolWithTime(chainparams, pool, state, tx, pfMissingInputs, GetTime(), plTxnReplaced, bypass_limits, nAbsurdFee);
903906
}
904907

905908
/** Return transaction in txOut, and if it was found inside a block, its hash is placed in hashBlock */
@@ -4306,7 +4309,8 @@ bool LoadMempool(void)
43064309
CValidationState state;
43074310
if (nTime + nExpiryTimeout > nNow) {
43084311
LOCK(cs_main);
4309-
AcceptToMemoryPoolWithTime(chainparams, mempool, state, tx, true, nullptr, nTime, nullptr, false, 0);
4312+
AcceptToMemoryPoolWithTime(chainparams, mempool, state, tx, nullptr /* pfMissingInputs */, nTime,
4313+
nullptr /* plTxnReplaced */, false /* bypass_limits */, 0 /* nAbsurdFee */);
43104314
if (state.IsValid()) {
43114315
++count;
43124316
} else {

src/validation.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -301,9 +301,9 @@ void PruneBlockFilesManual(int nManualPruneHeight);
301301

302302
/** (try to) add transaction to memory pool
303303
* plTxnReplaced will be appended to with all transactions replaced from mempool **/
304-
bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransactionRef &tx, bool fLimitFree,
305-
bool* pfMissingInputs, std::list<CTransactionRef>* plTxnReplaced = nullptr,
306-
bool fOverrideMempoolLimit=false, const CAmount nAbsurdFee=0);
304+
bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransactionRef &tx,
305+
bool* pfMissingInputs, std::list<CTransactionRef>* plTxnReplaced,
306+
bool bypass_limits, const CAmount nAbsurdFee);
307307

308308
/** Convert CValidationState to a human-readable message for logging */
309309
std::string FormatStateMessage(const CValidationState &state);

src/wallet/wallet.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4047,5 +4047,6 @@ int CMerkleTx::GetBlocksToMaturity() const
40474047

40484048
bool CMerkleTx::AcceptToMemoryPool(const CAmount& nAbsurdFee, CValidationState& state)
40494049
{
4050-
return ::AcceptToMemoryPool(mempool, state, tx, true, nullptr, nullptr, false, nAbsurdFee);
4050+
return ::AcceptToMemoryPool(mempool, state, tx, nullptr /* pfMissingInputs */,
4051+
nullptr /* plTxnReplaced */, false /* bypass_limits */, nAbsurdFee);
40514052
}

0 commit comments

Comments
 (0)