@@ -806,42 +806,62 @@ UniValue estimatesmartfee(const JSONRPCRequest& request)
806806{
807807 if (request.fHelp || request.params .size () < 1 || request.params .size () > 2 )
808808 throw std::runtime_error (
809- " estimatesmartfee nblocks (conservative )\n "
809+ " estimatesmartfee nblocks (\" estimate_mode \" )\n "
810810 " \n Estimates the approximate fee per kilobyte needed for a transaction to begin\n "
811811 " confirmation within nblocks blocks if possible and return the number of blocks\n "
812812 " for which the estimate is valid. Uses virtual transaction size as defined\n "
813813 " in BIP 141 (witness data is discounted).\n "
814814 " \n Arguments:\n "
815- " 1. nblocks (numeric)\n "
816- " 2. conservative (bool, optional, default=true) Whether to return a more conservative estimate which\n "
817- " also satisfies a longer history. A conservative estimate potentially returns a higher\n "
818- " feerate and is more likely to be sufficient for the desired target, but is not as\n "
819- " responsive to short term drops in the prevailing fee market\n "
815+ " 1. nblocks (numeric) Confirmation target in blocks (1 - 1008)\n "
816+ " 2. \" estimate_mode\" (string, optional, default=CONSERVATIVE) The fee estimate mode.\n "
817+ " Whether to return a more conservative estimate which also satisfies\n "
818+ " a longer history. A conservative estimate potentially returns a\n "
819+ " higher feerate and is more likely to be sufficient for the desired\n "
820+ " target, but is not as responsive to short term drops in the\n "
821+ " prevailing fee market. Must be one of:\n "
822+ " \" UNSET\" (defaults to CONSERVATIVE)\n "
823+ " \" ECONOMICAL\"\n "
824+ " \" CONSERVATIVE\"\n "
820825 " \n Result:\n "
821826 " {\n "
822- " \" feerate\" : x.x, (numeric) estimate fee-per-kilobyte (in BTC)\n "
827+ " \" feerate\" : x.x, (numeric, optional) estimate fee-per-kilobyte (in BTC)\n "
828+ " \" errors\" : [ str... ] (json array of strings, optional) Errors encountered during processing\n "
823829 " \" blocks\" : n (numeric) block number where estimate was found\n "
824830 " }\n "
825831 " \n "
826- " A negative value is returned if not enough transactions and blocks\n "
832+ " The request target will be clamped between 2 and the highest target\n "
833+ " fee estimation is able to return based on how long it has been running.\n "
834+ " An error is returned if not enough transactions and blocks\n "
827835 " have been observed to make an estimate for any number of blocks.\n "
828836 " \n Example:\n "
829837 + HelpExampleCli (" estimatesmartfee" , " 6" )
830838 );
831839
832- RPCTypeCheck (request.params , {UniValue::VNUM});
833-
840+ RPCTypeCheck (request.params , {UniValue::VNUM, UniValue::VSTR });
841+ RPCTypeCheckArgument (request. params [ 0 ], UniValue::VNUM);
834842 int nBlocks = request.params [0 ].get_int ();
843+ if (nBlocks < 1 || (unsigned int )nBlocks > ::feeEstimator.HighestTargetTracked (FeeEstimateHorizon::LONG_HALFLIFE)) {
844+ throw JSONRPCError (RPC_INVALID_PARAMETER, " Invalid nblocks" );
845+ }
835846 bool conservative = true ;
836847 if (request.params .size () > 1 && !request.params [1 ].isNull ()) {
837- RPCTypeCheckArgument (request.params [1 ], UniValue::VBOOL);
838- conservative = request.params [1 ].get_bool ();
848+ FeeEstimateMode fee_mode;
849+ if (!FeeModeFromString (request.params [1 ].get_str (), fee_mode)) {
850+ throw JSONRPCError (RPC_INVALID_PARAMETER, " Invalid estimate_mode parameter" );
851+ }
852+ if (fee_mode == FeeEstimateMode::ECONOMICAL) conservative = false ;
839853 }
840854
841855 UniValue result (UniValue::VOBJ);
856+ UniValue errors (UniValue::VARR);
842857 FeeCalculation feeCalc;
843858 CFeeRate feeRate = ::feeEstimator.estimateSmartFee (nBlocks, &feeCalc, conservative);
844- result.push_back (Pair (" feerate" , feeRate == CFeeRate (0 ) ? -1.0 : ValueFromAmount (feeRate.GetFeePerK ())));
859+ if (feeRate != CFeeRate (0 )) {
860+ result.push_back (Pair (" feerate" , ValueFromAmount (feeRate.GetFeePerK ())));
861+ } else {
862+ errors.push_back (" Insufficient data or no feerate found" );
863+ result.push_back (Pair (" errors" , errors));
864+ }
845865 result.push_back (Pair (" blocks" , feeCalc.returnedTarget ));
846866 return result;
847867}
@@ -889,7 +909,7 @@ UniValue estimaterawfee(const JSONRPCRequest& request)
889909 + HelpExampleCli (" estimaterawfee" , " 6 0.9" )
890910 );
891911
892- RPCTypeCheck (request.params , {UniValue::VNUM, UniValue::VNUM, UniValue::VNUM }, true );
912+ RPCTypeCheck (request.params , {UniValue::VNUM, UniValue::VNUM}, true );
893913 RPCTypeCheckArgument (request.params [0 ], UniValue::VNUM);
894914 int nBlocks = request.params [0 ].get_int ();
895915 if (nBlocks < 1 || (unsigned int )nBlocks > ::feeEstimator.HighestTargetTracked (FeeEstimateHorizon::LONG_HALFLIFE)) {
@@ -963,7 +983,7 @@ static const CRPCCommand commands[] =
963983 { " generating" , " generatetoaddress" , &generatetoaddress, true , {" nblocks" ," address" ," maxtries" } },
964984
965985 { " util" , " estimatefee" , &estimatefee, true , {" nblocks" } },
966- { " util" , " estimatesmartfee" , &estimatesmartfee, true , {" nblocks" , " conservative " } },
986+ { " util" , " estimatesmartfee" , &estimatesmartfee, true , {" nblocks" , " estimate_mode " } },
967987
968988 { " hidden" , " estimaterawfee" , &estimaterawfee, true , {" nblocks" , " threshold" } },
969989};
0 commit comments