Added these comments:
RPCTypeCheck(request.params, {
- UniValueType(), // ARR or OBJ, checked later
- UniValue::VNUM,
- UniValue::VSTR,
- UniValue::VNUM,
- UniValue::VOBJ,
+ UniValueType(), // outputs (ARR or OBJ, checked later)
+ UniValue::VNUM, // conf_target
+ UniValue::VSTR, // estimate_mode
+ UniValue::VNUM, // fee_rate
+ UniValue::VOBJ, // options
}, true
);
I was trying to figure out what exactly is checked here that prevents e.g. both conf_target and fee_rate to be set here, if params[1]…[3] all need to be null here.
You're right. Updated.
UniValue options{request.params[4].isNull() ? UniValue::VOBJ : request.params[4]};
- if (options.exists("conf_target") || options.exists("estimate_mode") || options.exists("fee_rate")) {
- if (!request.params[1].isNull() || !request.params[2].isNull() || !request.params[3].isNull()) {
- throw JSONRPCError(RPC_INVALID_PARAMETER, "Use either conf_target and estimate_mode for fee estimation, or fee_rate to specify an explicit fee rate.");
+ if (options.exists("conf_target") || options.exists("estimate_mode")) {
+ if (!request.params[1].isNull() || !request.params[2].isNull()) {
+ throw JSONRPCError(RPC_INVALID_PARAMETER, "Pass conf_target and estimate_mode either as arguments or in the options object, but not both");
}
} else {
options.pushKV("conf_target", request.params[1]);
options.pushKV("estimate_mode", request.params[2]);
+ }
+ if (options.exists("fee_rate")) {
+ if (!request.params[3].isNull()) {
+ throw JSONRPCError(RPC_INVALID_PARAMETER, "Pass fee_rate either as an argument or in the options object, but not both");
+ }
+ } else {
options.pushKV("fee_rate", request.params[3]);
}
This hopefully maintains the original goal of the code that either the argument or the option should be passed, but not both. The check if conf_target or estimate_mode are passed at the same time as fee_rate happens in SetFeeEstimateMode().