diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -2417,9 +2417,9 @@ { {"desc", RPCArg::Type::STR, RPCArg::Optional::NO, "An output descriptor"}, - {"range", RPCArg::Type::NUM, /* default */ "1000", - "Up to what child index HD chains should be " - "explored"}, + {"range", RPCArg::Type::RANGE, /* default */ "1000", + "The range of HD chain indexes to explore (either " + "end or [begin,end])"}, }, }, }, @@ -2486,7 +2486,7 @@ for (const UniValue &scanobject : request.params[1].get_array().getValues()) { std::string desc_str; - int range = 1000; + std::pair range = {0, 1000}; if (scanobject.isStr()) { desc_str = scanobject.get_str(); } else if (scanobject.isObject()) { @@ -2499,8 +2499,9 @@ desc_str = desc_uni.get_str(); UniValue range_uni = find_value(scanobject, "range"); if (!range_uni.isNull()) { - range = range_uni.get_int(); - if (range < 0 || range > 1000000) { + range = ParseRange(range_uni); + if (range.first < 0 || (range.second >> 31) != 0 || + range.second >= range.first + 1000000) { throw JSONRPCError(RPC_INVALID_PARAMETER, "range out of range"); } @@ -2519,9 +2520,10 @@ strprintf("Invalid descriptor '%s'", desc_str)); } if (!desc->IsRange()) { - range = 0; + range.first = 0; + range.second = 0; } - for (int i = 0; i <= range; ++i) { + for (int i = range.first; i <= range.second; ++i) { std::vector scripts; if (!desc->Expand(i, provider, scripts, provider)) { throw JSONRPCError( diff --git a/test/functional/rpc_scantxoutset.py b/test/functional/rpc_scantxoutset.py --- a/test/functional/rpc_scantxoutset.py +++ b/test/functional/rpc_scantxoutset.py @@ -143,6 +143,16 @@ {"desc": "combo(tpubD6NzVbkrYhZ4WaWSyoBvQwbpLkojyoTZPRsgXELWz3Popb3qkjcJyJUGLnL4qHHoQvao8ESaAstxYSnhyswJ76uZPStJRJCTKvosUCJZL5B/1/1/*)", "range": 1499}])['total_amount'], Decimal("12.288")) assert_equal(self.nodes[0].scantxoutset("start", [ {"desc": "combo(tpubD6NzVbkrYhZ4WaWSyoBvQwbpLkojyoTZPRsgXELWz3Popb3qkjcJyJUGLnL4qHHoQvao8ESaAstxYSnhyswJ76uZPStJRJCTKvosUCJZL5B/1/1/*)", "range": 1500}])['total_amount'], Decimal("28.672")) + assert_equal( + self.nodes[0].scantxoutset( + "start", + [ + { + "desc": "combo(tpubD6NzVbkrYhZ4WaWSyoBvQwbpLkojyoTZPRsgXELWz3Popb3qkjcJyJUGLnL4qHHoQvao8ESaAstxYSnhyswJ76uZPStJRJCTKvosUCJZL5B/1/1/*)", + "range": [ + 1500, + 1500]}])['total_amount'], + Decimal("16.384")) # Test the reported descriptors for a few matches assert_equal(descriptors(self.nodes[0].scantxoutset("start",