diff --git a/src/wallet/rpc/spend.cpp b/src/wallet/rpc/spend.cpp index 69db2221da..6e4e875669 100644 --- a/src/wallet/rpc/spend.cpp +++ b/src/wallet/rpc/spend.cpp @@ -72,9 +72,13 @@ static void InterpretFeeEstimationInstructions(const UniValue& conf_target, cons } else { options.pushKV("fee_rate", fee_rate); } - if (!options["conf_target"].isNull() && (options["estimate_mode"].isNull() || (ToLower(options["estimate_mode"].get_str()) == "unset"))) { + auto estimate_mode_set = !options["estimate_mode"].isNull() && (ToLower(options["estimate_mode"].get_str()) != "unset"); + if (!options["conf_target"].isNull() && !estimate_mode_set) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Specify estimate_mode"); } + if (options["conf_target"].isNull() && estimate_mode_set) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "estimate_mode should be passed with conf_target"); + } } static UniValue FinishTransaction(const std::shared_ptr pwallet, const UniValue& options, const CMutableTransaction& rawTx) diff --git a/test/functional/wallet_send.py b/test/functional/wallet_send.py index 0b4f10a67d..11db3ec0f1 100755 --- a/test/functional/wallet_send.py +++ b/test/functional/wallet_send.py @@ -304,12 +304,12 @@ class WalletSendTest(BitcoinTestFramework): self.log.info("Testing case insensitive fee estimation mode parse") for mode in ["ecoNOMICAL", "economical", "ECONOMICAL"]: res = self.test_send(from_wallet=w0, to_wallet=w1, amount=1, - estimate_mode=mode, add_to_wallet=False + estimate_mode=mode, conf_target=1, add_to_wallet=False ) assert_equal(res["complete"], True) res = self.test_send(from_wallet=w0, to_wallet=w1, amount=1, - arg_estimate_mode=mode, add_to_wallet=False + arg_estimate_mode=mode, arg_conf_target=1, add_to_wallet=False ) assert_equal(res["complete"], True) @@ -324,6 +324,16 @@ class WalletSendTest(BitcoinTestFramework): estimate_mode=mode, conf_target=1, add_to_wallet=False, expect_error = (-8, 'Specify estimate_mode') ) + # Verify that 'estimate_mode' requires a confirmation target + for mode in ["ecoNOMICAL", "economical", "ECONOMICAL"]: + self.test_send(from_wallet=w0, to_wallet=w1, amount=1, + estimate_mode=mode, conf_target=None, add_to_wallet=False, expect_error = (-8, 'estimate_mode should be passed with conf_target') + ) + + self.test_send(from_wallet=w0, to_wallet=w1, amount=1, + arg_estimate_mode=mode, arg_conf_target=None, add_to_wallet=False, expect_error = (-8, 'estimate_mode should be passed with conf_target') + ) + if not self.options.descriptors: # Descriptor wallets do not allow mixed watch-only and non-watch-only things in the same wallet. # This is specifically testing that w4 ignores its own private keys and creates a psbt with send