Skip to content

Commit c5ba1d9

Browse files
author
MacroFake
committed
Merge bitcoin/bitcoin#25610: wallet, rpc: Opt in to RBF by default
ab3c06d doc: Release notes for default RBF (Andrew Chow) 61d9149 rpc: Default rbf enabled (Andrew Chow) e3c3363 wallet: Enable -walletrbf by default (Andrew Chow) Pull request description: The GUI currently opts in to RBF by default, but RPCs do not, and `-walletrbf` is default disabled. This PR makes the default in those two places to also opt in. The last time this was proposed (#9527), the primary objections were the novelty at the time, the inability to bump transactions, and the gui not having the option to disable rbf. In the 5 years since, RBF usage has steadily grown, with ~27% of txs opting in. The GUI has the option to enable/disable RBF, and is also defaulted to having it enabled. And we have the ability to bump RBF'd transactions in both the RPC and the GUI. So I think it makes sense to finally change the default to always opt in to RBF. ACKs for top commit: darosior: reACK ab3c06d aureleoules: ACK ab3c06d. glozow: utACK ab3c06d Tree-SHA512: 81b012c5033e270f86a87a6a196ccc549eb54b158eebf88e917cc6621d40d7bdcd1566b602688907dd5d364b95a557b29f97dce869cea512e339588262c027b6
2 parents b3c7c02 + ab3c06d commit c5ba1d9

File tree

8 files changed

+28
-13
lines changed

8 files changed

+28
-13
lines changed

doc/release-notes-25610.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
Wallet
2+
------
3+
4+
- The `-walletrbf` startup option will now default to `true`. The
5+
wallet will now default to opt-in RBF on transactions that it creates.
6+
7+
Updated RPCs
8+
------------
9+
10+
- The `replaceable` option for the `createrawtransaction` and
11+
`createpsbt` RPCs will now default to `true`. Transactions created
12+
with these RPCs will default to having opt-in RBF enabled.

src/rpc/rawtransaction.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ static std::vector<RPCArg> CreateTxDoc()
157157
},
158158
},
159159
{"locktime", RPCArg::Type::NUM, RPCArg::Default{0}, "Raw locktime. Non-0 value also locktime-activates inputs"},
160-
{"replaceable", RPCArg::Type::BOOL, RPCArg::Default{false}, "Marks this transaction as BIP125-replaceable.\n"
160+
{"replaceable", RPCArg::Type::BOOL, RPCArg::Default{true}, "Marks this transaction as BIP125-replaceable.\n"
161161
"Allows this transaction to be replaced by a transaction with higher fees. If provided, it is an error if explicit sequence numbers are incompatible."},
162162
};
163163
}
@@ -302,7 +302,7 @@ static RPCHelpMan createrawtransaction()
302302
}, true
303303
);
304304

305-
bool rbf = false;
305+
std::optional<bool> rbf;
306306
if (!request.params[3].isNull()) {
307307
rbf = request.params[3].isTrue();
308308
}
@@ -1451,7 +1451,7 @@ static RPCHelpMan createpsbt()
14511451
}, true
14521452
);
14531453

1454-
bool rbf = false;
1454+
std::optional<bool> rbf;
14551455
if (!request.params[3].isNull()) {
14561456
rbf = request.params[3].isTrue();
14571457
}

src/rpc/rawtransaction_util.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
#include <util/strencodings.h>
2222
#include <util/translation.h>
2323

24-
CMutableTransaction ConstructTransaction(const UniValue& inputs_in, const UniValue& outputs_in, const UniValue& locktime, bool rbf)
24+
CMutableTransaction ConstructTransaction(const UniValue& inputs_in, const UniValue& outputs_in, const UniValue& locktime, std::optional<bool> rbf)
2525
{
2626
if (outputs_in.isNull()) {
2727
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, output argument must be non-null");
@@ -60,7 +60,8 @@ CMutableTransaction ConstructTransaction(const UniValue& inputs_in, const UniVal
6060
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout cannot be negative");
6161

6262
uint32_t nSequence;
63-
if (rbf) {
63+
64+
if (rbf.value_or(true)) {
6465
nSequence = MAX_BIP125_RBF_SEQUENCE; /* CTxIn::SEQUENCE_FINAL - 2 */
6566
} else if (rawTx.nLockTime) {
6667
nSequence = CTxIn::MAX_SEQUENCE_NONFINAL; /* CTxIn::SEQUENCE_FINAL - 1 */
@@ -132,7 +133,7 @@ CMutableTransaction ConstructTransaction(const UniValue& inputs_in, const UniVal
132133
}
133134
}
134135

135-
if (rbf && rawTx.vin.size() > 0 && !SignalsOptInRBF(CTransaction(rawTx))) {
136+
if (rbf.has_value() && rbf.value() && rawTx.vin.size() > 0 && !SignalsOptInRBF(CTransaction(rawTx))) {
136137
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter combination: Sequence number(s) contradict replaceable option");
137138
}
138139

src/rpc/rawtransaction_util.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#include <map>
99
#include <string>
10+
#include <optional>
1011

1112
struct bilingual_str;
1213
class FillableSigningProvider;
@@ -38,6 +39,6 @@ void SignTransactionResultToJSON(CMutableTransaction& mtx, bool complete, const
3839
void ParsePrevouts(const UniValue& prevTxsUnival, FillableSigningProvider* keystore, std::map<COutPoint, Coin>& coins);
3940

4041
/** Create a transaction from univalue parameters */
41-
CMutableTransaction ConstructTransaction(const UniValue& inputs_in, const UniValue& outputs_in, const UniValue& locktime, bool rbf);
42+
CMutableTransaction ConstructTransaction(const UniValue& inputs_in, const UniValue& outputs_in, const UniValue& locktime, std::optional<bool> rbf);
4243

4344
#endif // BITCOIN_RPC_RAWTRANSACTION_UTIL_H

src/wallet/wallet.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ static const bool DEFAULT_WALLET_REJECT_LONG_CHAINS{true};
9999
//! -txconfirmtarget default
100100
static const unsigned int DEFAULT_TX_CONFIRM_TARGET = 6;
101101
//! -walletrbf default
102-
static const bool DEFAULT_WALLET_RBF = false;
102+
static const bool DEFAULT_WALLET_RBF = true;
103103
static const bool DEFAULT_WALLETBROADCAST = true;
104104
static const bool DEFAULT_DISABLE_WALLET = false;
105105
static const bool DEFAULT_WALLETCROSSCHAIN = false;

test/functional/p2p_permissions.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,8 @@ def check_tx_relay(self):
111111
'vout': 0,
112112
}], outputs=[{
113113
ADDRESS_BCRT1_P2WSH_OP_TRUE: 5,
114-
}]),
114+
}],
115+
replaceable=False),
115116
)
116117
tx.wit.vtxinwit = [CTxInWitness()]
117118
tx.wit.vtxinwit[0].scriptWitness.stack = [CScript([OP_TRUE])]

test/functional/rpc_psbt.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,7 @@ def run_test(self):
467467

468468
# Creator Tests
469469
for creator in creators:
470-
created_tx = self.nodes[0].createpsbt(creator['inputs'], creator['outputs'])
470+
created_tx = self.nodes[0].createpsbt(inputs=creator['inputs'], outputs=creator['outputs'], replaceable=False)
471471
assert_equal(created_tx, creator['result'])
472472

473473
# Signer tests

test/functional/wallet_listtransactions.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ def set_test_params(self):
2525
self.num_nodes = 3
2626
# This test isn't testing txn relay/timing, so set whitelist on the
2727
# peers for instant txn relay. This speeds up the test run time 2-3x.
28-
self.extra_args = [["[email protected]"]] * self.num_nodes
28+
self.extra_args = [["[email protected]", "-walletrbf=0"]] * self.num_nodes
2929

3030
def skip_test_if_missing_module(self):
3131
self.skip_if_no_wallet()
@@ -146,7 +146,7 @@ def get_unconfirmed_utxo_entry(node, txid_to_match):
146146
# Create tx2 using createrawtransaction
147147
inputs = [{"txid": utxo_to_use["txid"], "vout": utxo_to_use["vout"]}]
148148
outputs = {self.nodes[0].getnewaddress(): 0.999}
149-
tx2 = self.nodes[1].createrawtransaction(inputs, outputs)
149+
tx2 = self.nodes[1].createrawtransaction(inputs=inputs, outputs=outputs, replaceable=False)
150150
tx2_signed = self.nodes[1].signrawtransactionwithwallet(tx2)["hex"]
151151
txid_2 = self.nodes[1].sendrawtransaction(tx2_signed)
152152

@@ -178,7 +178,7 @@ def get_unconfirmed_utxo_entry(node, txid_to_match):
178178
utxo_to_use = get_unconfirmed_utxo_entry(self.nodes[1], txid_3)
179179
inputs = [{"txid": txid_3, "vout": utxo_to_use["vout"]}]
180180
outputs = {self.nodes[0].getnewaddress(): 0.997}
181-
tx4 = self.nodes[1].createrawtransaction(inputs, outputs)
181+
tx4 = self.nodes[1].createrawtransaction(inputs=inputs, outputs=outputs, replaceable=False)
182182
tx4_signed = self.nodes[1].signrawtransactionwithwallet(tx4)["hex"]
183183
txid_4 = self.nodes[1].sendrawtransaction(tx4_signed)
184184

0 commit comments

Comments
 (0)