diff --git a/doc/release-notes-16185.md b/doc/release-notes-16185.md index 14e4004f72..2567ebea40 100644 --- a/doc/release-notes-16185.md +++ b/doc/release-notes-16185.md @@ -1,3 +1,6 @@ RPC changes ----------- -The `gettransaction` RPC now accepts a third (boolean) argument `verbose`. If set to `true`, a new `details` field will be added to the response containing additional transaction details. +The `gettransaction` RPC now accepts a third (boolean) argument `verbose`. If +set to `true`, a new `decoded` field will be added to the response containing +the decoded transaction. This field is equivalent to RPC `decoderawtransaction`, +or RPC `getrawtransaction` when `verbose` is passed. diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 15531540c3..4bd5a4cc74 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1655,7 +1655,7 @@ static UniValue gettransaction(const JSONRPCRequest& request) { {"txid", RPCArg::Type::STR, RPCArg::Optional::NO, "The transaction id"}, {"include_watchonly", RPCArg::Type::BOOL, /* default */ "true for watch-only wallets, otherwise false", "Whether to include watch-only addresses in balance calculation and details[]"}, - {"verbose", RPCArg::Type::BOOL, /* default */ "false", "Whether to add a field with additional transaction details"}, + {"verbose", RPCArg::Type::BOOL, /* default */ "false", "Whether to include a `decoded` field containing the decoded transaction (equivalent to RPC decoderawtransaction)"}, }, RPCResult{ RPCResult::Type::OBJ, "", "", Cat(Cat>( @@ -1689,9 +1689,9 @@ static UniValue gettransaction(const JSONRPCRequest& request) }}, }}, {RPCResult::Type::STR_HEX, "hex", "Raw data for transaction"}, - {RPCResult::Type::OBJ, "details", /*optional=*/true, "Additional transaction details", + {RPCResult::Type::OBJ, "decoded", /*optional=*/true, "the decoded transaction (only present when `verbose` is passed), equivalent to the", { - {RPCResult::Type::ELISION, "", "Equivalent to the RPC decoderawtransaction method, or the RPC getrawtransaction method when `verbose` is passed."}, + {RPCResult::Type::ELISION, "", "RPC decoderawtransaction method, or the RPC getrawtransaction method when `verbose` is passed."}, }}, }), }, @@ -1748,9 +1748,9 @@ static UniValue gettransaction(const JSONRPCRequest& request) entry.pushKV("hex", strHex); if (verbose) { - UniValue details(UniValue::VOBJ); - TxToUniv(*wtx.tx, uint256(), details, false); - entry.pushKV("details", details); + UniValue decoded(UniValue::VOBJ); + TxToUniv(*wtx.tx, uint256(), decoded, false); + entry.pushKV("decoded", decoded); } return entry; diff --git a/test/functional/wallet_basic.py b/test/functional/wallet_basic.py index 36ee0309b6..3ee5eabbda 100755 --- a/test/functional/wallet_basic.py +++ b/test/functional/wallet_basic.py @@ -496,10 +496,37 @@ class WalletTest(BitcoinTestFramework): self.nodes[0].setlabel(change, 'foobar') assert_equal(self.nodes[0].getaddressinfo(change)['ischange'], False) - # Test "verbose" field value in gettransaction response - self.log.info("Testing verbose gettransaction...") + # Test gettransaction response with different arguments. + self.log.info("Testing gettransaction response with different arguments...") + self.nodes[0].setlabel(change, 'baz') + baz = self.nodes[0].listtransactions(label="baz", count=1)[0] + expected_receive_vout = {"label": "baz", + "address": baz["address"], + "amount": baz["amount"], + "category": baz["category"], + "vout": baz["vout"]} + expected_fields = frozenset({'amount', 'chainlock', 'confirmations', 'details', 'fee', + 'instantlock', 'instantlock_internal', + 'hex', 'timereceived', 'time', 'trusted', 'txid', 'walletconflicts'}) + + verbose_field = "decoded" + expected_verbose_fields = expected_fields | {verbose_field} + + self.log.debug("Testing gettransaction response without verbose") + tx = self.nodes[0].gettransaction(txid=txid) + assert_equal(set([*tx]), expected_fields) + assert_array_result(tx["details"], {"category": "receive"}, expected_receive_vout) + + self.log.debug("Testing gettransaction response with verbose set to False") + tx = self.nodes[0].gettransaction(txid=txid, verbose=False) + assert_equal(set([*tx]), expected_fields) + assert_array_result(tx["details"], {"category": "receive"}, expected_receive_vout) + + self.log.debug("Testing gettransaction response with verbose set to True") tx = self.nodes[0].gettransaction(txid=txid, verbose=True) - assert_equal(tx["details"], self.nodes[0].decoderawtransaction(tx["hex"])) + assert_equal(set([*tx]), expected_verbose_fields) + assert_array_result(tx["details"], {"category": "receive"}, expected_receive_vout) + assert_equal(tx[verbose_field], self.nodes[0].decoderawtransaction(tx["hex"])) if __name__ == '__main__':