From 90fd5acbe57edb219a5dcbdc1095e11ae5398da5 Mon Sep 17 00:00:00 2001 From: pablomartin4btc Date: Tue, 8 Jul 2025 01:14:50 -0300 Subject: [PATCH] rpc, test: Fix error message in getdescriptoractivity Mark blockhashes and scanobjects arguments as required, so the user receives a clear help message when either is missing. Added a new functional test for this use case. Co-authored-by: stickies-v --- src/rpc/blockchain.cpp | 24 ++++++++++++++------ test/functional/rpc_getdescriptoractivity.py | 6 +++++ 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index ca872cf6ac8..9fcc685ae03 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -2193,16 +2193,20 @@ static const auto scan_action_arg_desc = RPCArg{ "\"status\" for progress report (in %) of the current scan" }; +static const auto output_descriptor_obj = RPCArg{ + "", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "An object with output descriptor and metadata", + { + {"desc", RPCArg::Type::STR, RPCArg::Optional::NO, "An output descriptor"}, + {"range", RPCArg::Type::RANGE, RPCArg::Default{1000}, "The range of HD chain indexes to explore (either end or [begin,end])"}, + } +}; + static const auto scan_objects_arg_desc = RPCArg{ "scanobjects", RPCArg::Type::ARR, RPCArg::Optional::OMITTED, "Array of scan objects. Required for \"start\" action\n" "Every scan object is either a string descriptor or an object:", { {"descriptor", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "An output descriptor"}, - {"", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "An object with output descriptor and metadata", - { - {"desc", RPCArg::Type::STR, RPCArg::Optional::NO, "An output descriptor"}, - {"range", RPCArg::Type::RANGE, RPCArg::Default{1000}, "The range of HD chain indexes to explore (either end or [begin,end])"}, - }}, + output_descriptor_obj, }, RPCArgOptions{.oneline_description="[scanobjects,...]"}, }; @@ -2632,10 +2636,16 @@ static RPCHelpMan getdescriptoractivity() "This command pairs well with the `relevant_blocks` output of `scanblocks()`.\n" "This call may take several minutes. If you encounter timeouts, try specifying no RPC timeout (bitcoin-cli -rpcclienttimeout=0)", { - RPCArg{"blockhashes", RPCArg::Type::ARR, RPCArg::Optional::OMITTED, "The list of blockhashes to examine for activity. Order doesn't matter. Must be along main chain or an error is thrown.\n", { + RPCArg{"blockhashes", RPCArg::Type::ARR, RPCArg::Optional::NO, "The list of blockhashes to examine for activity. Order doesn't matter. Must be along main chain or an error is thrown.\n", { {"blockhash", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "A valid blockhash"}, }}, - scan_objects_arg_desc, + RPCArg{"scanobjects", RPCArg::Type::ARR, RPCArg::Optional::NO, "The list of descriptors (scan objects) to examine for activity. Every scan object is either a string descriptor or an object:", + { + {"descriptor", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "An output descriptor"}, + output_descriptor_obj, + }, + RPCArgOptions{.oneline_description="[scanobjects,...]"}, + }, {"include_mempool", RPCArg::Type::BOOL, RPCArg::Default{true}, "Whether to include unconfirmed activity"}, }, RPCResult{ diff --git a/test/functional/rpc_getdescriptoractivity.py b/test/functional/rpc_getdescriptoractivity.py index 94c871c58cd..510d7692ed7 100755 --- a/test/functional/rpc_getdescriptoractivity.py +++ b/test/functional/rpc_getdescriptoractivity.py @@ -31,6 +31,7 @@ class GetBlocksActivityTest(BitcoinTestFramework): self.test_confirmed_and_unconfirmed(node, wallet) self.test_receive_then_spend(node, wallet) self.test_no_address(node, wallet) + self.test_required_args(node) def test_no_activity(self, node): self.log.info("Test that no activity is found for an unused address") @@ -231,6 +232,11 @@ class GetBlocksActivityTest(BitcoinTestFramework): assert_equal(list(a2['output_spk'].keys()), ['asm', 'desc', 'hex', 'type']) assert a2['amount'] == Decimal(no_addr_tx["tx"].vout[0].nValue) / COIN + def test_required_args(self, node): + self.log.info("Test that required arguments must be passed") + assert_raises_rpc_error(-1, "getdescriptoractivity", node.getdescriptoractivity) + assert_raises_rpc_error(-1, "getdescriptoractivity", node.getdescriptoractivity, []) + if __name__ == '__main__': GetBlocksActivityTest(__file__).main()