rpc, mempool: rpcdeprecate `bip125-replaceable` key in mempool RPCs reponses
What changed, and why it matters
This commit removes a long-deprecated 'bip125-replaceable' field from several Bitcoin mempool-related RPC responses by default. Users can still get the old field back by starting their node with -deprecatedrpc=bip125. It is a routine API cleanup, not a security fix.
No security action needed. Developers relying on the 'bip125-replaceable' field in getrawmempool, getmempoolancestors, getmempooldescendants, or getmempoolentry should migrate to the replacement field or enable -deprecatedrpc=bip125 during transition.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The change moves the ‘bip125-replaceable’ key out of the default MempoolEntryDescription() and entryToJSON() output. It is now only emitted when the ‘bip125’ deprecated RPC flag is enabled. The functional test is updated to pass that flag so existing RBF tests continue to see the field. No logic bug, crash, or vulnerability is present in the diff.
Changed components
src/rpc/mempool.cpptest/functional/feature_rbf.pyInspect captured patch +16 / −12
diff --git a/src/rpc/mempool.cpp b/src/rpc/mempool.cpp
index 1b76f7d8..e762c6ab 100644
--- a/src/rpc/mempool.cpp
+++ b/src/rpc/mempool.cpp
@@ -430,7 +430,7 @@ static std::vector<RPCResult> ClusterDescription()
static std::vector<RPCResult> MempoolEntryDescription()
{
- return {
+ std::vector<RPCResult> list = {
RPCResult{RPCResult::Type::NUM, "vsize", "virtual transaction size as defined in BIP 141. This is different from actual serialized size for witness transactions as witness data is discounted."},
RPCResult{RPCResult::Type::NUM, "weight", "transaction weight as defined in BIP 141."},
RPCResult{RPCResult::Type::NUM_TIME, "time", "local time transaction entered pool in seconds since 1 Jan 1970 GMT"},
@@ -453,9 +453,12 @@ static std::vector<RPCResult> MempoolEntryDescription()
{RPCResult{RPCResult::Type::STR_HEX, "transactionid", "parent transaction id"}}},
RPCResult{RPCResult::Type::ARR, "spentby", "unconfirmed transactions spending outputs from this transaction",
{RPCResult{RPCResult::Type::STR_HEX, "transactionid", "child transaction id"}}},
- RPCResult{RPCResult::Type::BOOL, "bip125-replaceable", "Whether this transaction signals BIP125 replaceability or has an unconfirmed ancestor signaling BIP125 replaceability. (DEPRECATED)\n"},
RPCResult{RPCResult::Type::BOOL, "unbroadcast", "Whether this transaction is currently unbroadcast (initial broadcast not yet acknowledged by any peers)"},
};
+ if (IsDeprecatedRPCEnabled("bip125")) {
+ list.emplace_back(RPCResult::Type::BOOL, "bip125-replaceable", "Whether this transaction signals BIP125 replaceability or has an unconfirmed ancestor signaling BIP125 replaceability. (DEPRECATED)\n");
+ }
+ return list;
}
void AppendChunkInfo(UniValue& all_chunks, FeePerWeight chunk_feerate, std::vector<const CTxMemPoolEntry *> chunk_txs)
@@ -554,18 +557,19 @@ static void entryToJSON(const CTxMemPool& pool, UniValue& info, const CTxMemPool
}
info.pushKV("spentby", std::move(spent));
+ info.pushKV("unbroadcast", pool.IsUnbroadcastTx(tx.GetHash()));
// Add opt-in RBF status
- bool rbfStatus = false;
- RBFTransactionState rbfState = IsRBFOptIn(tx, pool);
- if (rbfState == RBFTransactionState::UNKNOWN) {
- throw JSONRPCError(RPC_MISC_ERROR, "Transaction is not in mempool");
- } else if (rbfState == RBFTransactionState::REPLACEABLE_BIP125) {
- rbfStatus = true;
+ if (IsDeprecatedRPCEnabled("bip125")) {
+ bool rbfStatus = false;
+ RBFTransactionState rbfState = IsRBFOptIn(tx, pool);
+ if (rbfState == RBFTransactionState::UNKNOWN) {
+ throw JSONRPCError(RPC_MISC_ERROR, "Transaction is not in mempool");
+ } else if (rbfState == RBFTransactionState::REPLACEABLE_BIP125) {
+ rbfStatus = true;
+ }
+ info.pushKV("bip125-replaceable", rbfStatus);
}
-
- info.pushKV("bip125-replaceable", rbfStatus);
- info.pushKV("unbroadcast", pool.IsUnbroadcastTx(tx.GetHash()));
}
UniValue MempoolToJSON(const CTxMemPool& pool, bool verbose, bool include_mempool_sequence)
diff --git a/test/functional/feature_rbf.py b/test/functional/feature_rbf.py
index 5527f7a9..b26d59ab 100755
--- a/test/functional/feature_rbf.py
+++ b/test/functional/feature_rbf.py
@@ -28,7 +28,7 @@ class ReplaceByFeeTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 2
self.uses_wallet = None
- self.extra_args = [["-deprecatedrpc=fullrbf"], []]
+ self.extra_args = [["-deprecatedrpc=fullrbf", "-deprecatedrpc=bip125"], []]
def run_test(self):
self.wallet = MiniWallet(self.nodes[0])
Why this scored 20/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.