diff options
-rw-r--r-- | src/wallet/feebumper.cpp | 7 | ||||
-rw-r--r-- | src/wallet/rpcwallet.cpp | 19 |
2 files changed, 21 insertions, 5 deletions
diff --git a/src/wallet/feebumper.cpp b/src/wallet/feebumper.cpp index 1e25d4ee28..ce76f4e512 100644 --- a/src/wallet/feebumper.cpp +++ b/src/wallet/feebumper.cpp @@ -258,7 +258,12 @@ Result CreateRateBumpTransaction(CWallet* wallet, const uint256& txid, const CCo } } - new_coin_control.m_feerate = EstimateFeeRate(wallet, wtx, new_coin_control, old_fee); + if (coin_control.m_feerate) { + // The user provided a feeRate argument. + } else { + // The user did not provide a feeRate argument + new_coin_control.m_feerate = EstimateFeeRate(wallet, wtx, new_coin_control, old_fee); + } // Fill in required inputs we are double-spending(all of them) // N.B.: bip125 doesn't require all the inputs in the replaced transaction to be diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 30e767e489..098778d878 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -3290,7 +3290,7 @@ static UniValue bumpfee(const JSONRPCRequest& request) "The command will fail if the wallet or mempool contains a transaction that spends one of T's outputs.\n" "By default, the new fee will be calculated automatically using estimatesmartfee.\n" "The user can specify a confirmation target for estimatesmartfee.\n" - "Alternatively, the user can specify totalFee (DEPRECATED), or use RPC settxfee to set a higher fee rate.\n" + "Alternatively, the user can specify totalFee (DEPRECATED), or fee_rate (" + CURRENCY_UNIT + " per kB) for the new transaction .\n" "At a minimum, the new fee rate must be high enough to pay an additional new relay fee (incrementalfee\n" "returned by getnetworkinfo) to enter the node's mempool.\n", { @@ -3302,6 +3302,9 @@ static UniValue bumpfee(const JSONRPCRequest& request) " In rare cases, the actual fee paid might be slightly higher than the specified\n" " totalFee if the tx change output has to be removed because it is too close to\n" " the dust threshold."}, + {"fee_rate", RPCArg::Type::NUM, /* default */ "fallback to 'confTarget'", "FeeRate (NOT total fee) to pay, in " + CURRENCY_UNIT + " per kB\n" + " Specify a fee rate instead of relying on the built-in fee estimator.\n" + " Must be at least 0.0001 BTC per kB higher than the current transaction fee rate.\n"}, {"replaceable", RPCArg::Type::BOOL, /* default */ "true", "Whether the new transaction should still be\n" " marked bip-125 replaceable. If true, the sequence numbers in the transaction will\n" " be left unchanged from the original. If false, any input sequence numbers in the\n" @@ -3343,13 +3346,15 @@ static UniValue bumpfee(const JSONRPCRequest& request) { {"confTarget", UniValueType(UniValue::VNUM)}, {"totalFee", UniValueType(UniValue::VNUM)}, + {"fee_rate", UniValueType(UniValue::VNUM)}, {"replaceable", UniValueType(UniValue::VBOOL)}, {"estimate_mode", UniValueType(UniValue::VSTR)}, }, true, true); - - if (options.exists("confTarget") && options.exists("totalFee")) { - throw JSONRPCError(RPC_INVALID_PARAMETER, "confTarget and totalFee options should not both be set. Please provide either a confirmation target for fee estimation or an explicit total fee for the transaction."); + if (options.exists("confTarget") && (options.exists("totalFee") || options.exists("fee_rate"))) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "confTarget can't be set with totalFee or fee_rate. Please provide either a confirmation target in blocks for automatic fee estimation, or an explicit fee rate."); + } else if (options.exists("fee_rate") && options.exists("totalFee")) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "fee_rate can't be set along with totalFee."); } else if (options.exists("confTarget")) { // TODO: alias this to conf_target coin_control.m_confirm_target = ParseConfirmTarget(options["confTarget"], pwallet->chain().estimateMaxBlocks()); } else if (options.exists("totalFee")) { @@ -3360,6 +3365,12 @@ static UniValue bumpfee(const JSONRPCRequest& request) if (totalFee <= 0) { throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid totalFee %s (must be greater than 0)", FormatMoney(totalFee))); } + } else if (options.exists("fee_rate")) { + CFeeRate fee_rate(AmountFromValue(options["fee_rate"])); + if (fee_rate <= 0) { + throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid fee_rate %s (must be greater than 0)", fee_rate.ToString())); + } + coin_control.m_feerate = fee_rate; } if (options.exists("replaceable")) { |