diff --git a/doc/release-notes.md b/doc/release-notes.md --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -8,4 +8,7 @@ RPC changes ----------- -The `gettransaction` RPC now accepts a third (boolean) argument `decode`. If set to `true`, a new `decoded` field will be added to the response containing the decoded transaction. +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/rpc/client.cpp b/src/rpc/client.cpp --- a/src/rpc/client.cpp +++ b/src/rpc/client.cpp @@ -79,7 +79,7 @@ {"getblockheader", 1, "verbose"}, {"getchaintxstats", 0, "nblocks"}, {"gettransaction", 1, "include_watchonly"}, - {"gettransaction", 2, "decode"}, + {"gettransaction", 2, "verbose"}, {"getrawtransaction", 1, "verbose"}, {"createrawtransaction", 0, "inputs"}, {"createrawtransaction", 1, "outputs"}, diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1929,8 +1929,9 @@ /* default */ "true for watch-only wallets, otherwise false", "Whether to include watch-only addresses in balance calculation " "and details[]"}, - {"decode", RPCArg::Type::BOOL, /* default */ "false", - "Whether to add a field with the decoded transaction"}, + {"verbose", RPCArg::Type::BOOL, /* default */ "false", + "Whether to include a `decoded` field containing the decoded " + "transaction (equivalent to RPC decoderawtransaction)"}, }, RPCResult{ "{\n" @@ -1993,7 +1994,11 @@ " ],\n" " \"hex\" : \"data\" (string) Raw data for transaction\n" " \"decoded\" : transaction (json object) Optional, the " - "decoded transaction\n" + "decoded transaction (only present when `verbose` is passed), " + "equivalent to the\n" + " RPC " + "decoderawtransaction method, or the RPC getrawtransaction method " + "when `verbose` is passed.\n" "}\n"}, RPCExamples{HelpExampleCli("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c" @@ -2024,7 +2029,7 @@ filter |= ISMINE_WATCH_ONLY; } - bool decode_tx = + bool verbose = request.params[2].isNull() ? false : request.params[2].get_bool(); UniValue entry(UniValue::VOBJ); @@ -2057,7 +2062,7 @@ EncodeHexTx(*wtx.tx, pwallet->chain().rpcSerializationFlags()); entry.pushKV("hex", strHex); - if (decode_tx) { + if (verbose) { UniValue decoded(UniValue::VOBJ); TxToUniv(*wtx.tx, uint256(), decoded, false); entry.pushKV("decoded", decoded); @@ -4751,7 +4756,7 @@ { "wallet", "getrawchangeaddress", getrawchangeaddress, {"address_type"} }, { "wallet", "getreceivedbyaddress", getreceivedbyaddress, {"address","minconf"} }, { "wallet", "getreceivedbylabel", getreceivedbylabel, {"label","minconf"} }, - { "wallet", "gettransaction", gettransaction, {"txid","include_watchonly","decode"} }, + { "wallet", "gettransaction", gettransaction, {"txid","include_watchonly","verbose"} }, { "wallet", "getunconfirmedbalance", getunconfirmedbalance, {} }, { "wallet", "getbalances", getbalances, {} }, { "wallet", "getwalletinfo", getwalletinfo, {} }, diff --git a/test/functional/wallet_basic.py b/test/functional/wallet_basic.py --- a/test/functional/wallet_basic.py +++ b/test/functional/wallet_basic.py @@ -539,11 +539,53 @@ self.nodes[0].setlabel(change, 'foobar') assert_equal(self.nodes[0].getaddressinfo(change)['ischange'], False) - # Test "decoded" field value in gettransaction response - self.log.info("Testing gettransaction decoding...") - tx = self.nodes[0].gettransaction(txid=txid, decode=True) + # 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', + 'confirmations', + 'details', + 'fee', + 'hex', + 'time', + 'timereceived', + '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(set([*tx]), expected_verbose_fields) + assert_array_result( + tx["details"], { + "category": "receive"}, expected_receive_vout) assert_equal( - tx["decoded"], + tx[verbose_field], self.nodes[0].decoderawtransaction( tx["hex"]))