wallet: allow anti-fee-sniping in sendall RPC while not relying on RBF default
What changed, and why it matters
This is a small fix in Bitcoin Core's 'sendall' wallet RPC command. The bug meant that when a user explicitly set a transaction as non-replaceable, the wallet skipped its normal anti-fee-sniping protection. Anti-fee-sniping is a privacy/defense mechanism that uses the current block height as a transaction 'locktime' to make transactions look more similar and slightly harder to target. The fix changes the input sequence number used in that case so the protection still runs even when RBF is disabled.
Reviewers should confirm that MAX_SEQUENCE_NONFINAL is the intended sequence for non-RBF transactions with locktime in this codebase, and that no other RPC paths have the same pattern. Users running nodes with the sendall RPC should upgrade to include this fix if they rely on anti-fee-sniping behavior.
Security signals we found
Privacy/deanonymization signal: anti-fee-sniping is a fingerprinting countermeasure; bypassing it can make transactions more distinguishable
Logic bug: RPC parameter 'replaceable=false' inadvertently disabled a separate wallet defense mechanism
No consensus or signature validation change
No remote/network attack surface introduced
Evidence from the diff
In src/wallet/rpc/spend.cpp, the sendall RPC builds transaction inputs. Previously, when rbf was false it used CTxIn::SEQUENCE_FINAL (0xffffffff), which signals the input is final and also suppresses locktime. Because anti-fee-sniping sets a non-default locktime, a final sequence would make the locktime ineffective. The patch uses CTxIn::MAX_SEQUENCE_NONFINAL instead, which still disables RBF but does not disable locktime, so the anti-fee-sniping locktime remains meaningful. This is a one-line logic correction, not a consensus change.
Changed components
src/wallet/rpc/spend.cppsendall RPCwallet anti-fee-sniping locktime logicInspect captured patch +1 / −1
diff --git a/src/wallet/rpc/spend.cpp b/src/wallet/rpc/spend.cpp
index b6cdc860..8bb14c47 100644
--- a/src/wallet/rpc/spend.cpp
+++ b/src/wallet/rpc/spend.cpp
@@ -1498,7 +1498,7 @@ RPCMethod sendall()
if (output.depth == 0 && coin_control.m_version == TRUC_VERSION) {
coin_control.m_max_tx_weight = TRUC_CHILD_MAX_WEIGHT;
}
- CTxIn input(output.outpoint.hash, output.outpoint.n, CScript(), rbf ? MAX_BIP125_RBF_SEQUENCE : CTxIn::SEQUENCE_FINAL);
+ CTxIn input(output.outpoint.hash, output.outpoint.n, CScript(), rbf ? MAX_BIP125_RBF_SEQUENCE : CTxIn::MAX_SEQUENCE_NONFINAL);
rawTx.vin.push_back(input);
total_input_value += output.txout.nValue;
}
Why this scored 31/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.