Added these comments:
0 RPCTypeCheck(request.params, {
1- UniValueType(), // ARR or OBJ, checked later
2- UniValue::VNUM,
3- UniValue::VSTR,
4- UniValue::VNUM,
5- UniValue::VOBJ,
6+ UniValueType(), // outputs (ARR or OBJ, checked later)
7+ UniValue::VNUM, // conf_target
8+ UniValue::VSTR, // estimate_mode
9+ UniValue::VNUM, // fee_rate
10+ UniValue::VOBJ, // options
11 }, true
12 );
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.
0 UniValue options{request.params[4].isNull() ? UniValue::VOBJ : request.params[4]};
1- if (options.exists("conf_target") || options.exists("estimate_mode") || options.exists("fee_rate")) {
2- if (!request.params[1].isNull() || !request.params[2].isNull() || !request.params[3].isNull()) {
3- throw JSONRPCError(RPC_INVALID_PARAMETER, "Use either conf_target and estimate_mode for fee estimation, or fee_rate to specify an explicit fee rate.");
4+ if (options.exists("conf_target") || options.exists("estimate_mode")) {
5+ if (!request.params[1].isNull() || !request.params[2].isNull()) {
6+ throw JSONRPCError(RPC_INVALID_PARAMETER, "Pass conf_target and estimate_mode either as arguments or in the options object, but not both");
7 }
8 } else {
9 options.pushKV("conf_target", request.params[1]);
10 options.pushKV("estimate_mode", request.params[2]);
11+ }
12+ if (options.exists("fee_rate")) {
13+ if (!request.params[3].isNull()) {
14+ throw JSONRPCError(RPC_INVALID_PARAMETER, "Pass fee_rate either as an argument or in the options object, but not both");
15+ }
16+ } else {
17 options.pushKV("fee_rate", request.params[3]);
18 }
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()
.