From 4c72e6966dc650e646949faeb98d0a52c8862f7c Mon Sep 17 00:00:00 2001 From: MeshCollider Date: Mon, 2 Sep 2019 23:29:42 +1200 Subject: [PATCH] Merge #16185: gettransaction: add an argument to decode the transaction MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 9965940e35c445ccded55510348af228ff22f0e9 doc: Add release note for the new gettransaction argument (darosior) b8b3f0435a2837d3897e9e232ef6ca839ce74eb8 tests: Add a new functional test for gettransaction (darosior) 7f3bb247a811582d1aa4805d8e601c19808dc7ba gettransaction: add an argument to decode the transaction (darosior) Pull request description: This PR adds a new parameter to the `gettransaction` call : `decode`. If set to `true`, it will add a new `decoded` field to the response. This mimics the behavior of `getrawtransaction`'s `verbose` argument to avoid using 2 calls if we want to decode a wallet transaction (`gettransaction` then `decoderawtransaction`). Fix #16181 . ACKs for top commit: meshcollider: re-utACK 9965940e35c445ccded55510348af228ff22f0e9 Tree-SHA512: bcb6b4bd252b3488d6afc77659c499c2ad99fd58661eb24b6a2e17014c74f22e47fde70e00fedb4f4754915786622ad02483b2cf2c4dea0ab0eb4ac8276dbeee --- doc/release-notes-16185.md | 3 +++ src/rpc/client.cpp | 1 + src/wallet/rpcwallet.cpp | 15 ++++++++++++++- test/functional/wallet_basic.py | 5 +++++ 4 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 doc/release-notes-16185.md diff --git a/doc/release-notes-16185.md b/doc/release-notes-16185.md new file mode 100644 index 0000000000..eeeb951e5b --- /dev/null +++ b/doc/release-notes-16185.md @@ -0,0 +1,3 @@ +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. diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp index 4fb93be805..424d75f462 100644 --- a/src/rpc/client.cpp +++ b/src/rpc/client.cpp @@ -105,6 +105,7 @@ static const CRPCConvertParam vRPCConvertParams[] = { "getchaintxstats", 0, "nblocks" }, { "getmerkleblocks", 2, "count" }, { "gettransaction", 1, "include_watchonly" }, + { "gettransaction", 2, "decode" }, { "getrawtransaction", 1, "verbose" }, { "createrawtransaction", 0, "inputs" }, { "createrawtransaction", 1, "outputs" }, diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index b9171d10f0..ca3e76a25c 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1655,6 +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[]"}, + {"decode", RPCArg::Type::BOOL, /* default */ "false", "Whether to add a field with the decoded transaction"}, }, RPCResult{ RPCResult::Type::OBJ, "", "", Cat(Cat>( @@ -1688,6 +1689,10 @@ static UniValue gettransaction(const JSONRPCRequest& request) }}, }}, {RPCResult::Type::STR_HEX, "hex", "Raw data for transaction"}, + {RPCResult::Type::OBJ, "decoded", /*optional=*/true, "The decoded transaction", + { + {RPCResult::Type::ELISION, "", "Equivalent to the RPC decoderawtransaction method, or the RPC getrawtransaction method when `verbose` is passed."}, + }}, }), }, RPCExamples{ @@ -1715,6 +1720,8 @@ static UniValue gettransaction(const JSONRPCRequest& request) filter |= ISMINE_WATCH_ONLY; } + bool decode_tx = request.params[2].isNull() ? false : request.params[2].get_bool(); + UniValue entry(UniValue::VOBJ); auto it = pwallet->mapWallet.find(hash); if (it == pwallet->mapWallet.end()) { @@ -1740,6 +1747,12 @@ static UniValue gettransaction(const JSONRPCRequest& request) std::string strHex = EncodeHexTx(*wtx.tx); entry.pushKV("hex", strHex); + if (decode_tx) { + UniValue decoded(UniValue::VOBJ); + TxToUniv(*wtx.tx, uint256(), decoded, false); + entry.pushKV("decoded", decoded); + } + return entry; } @@ -4093,7 +4106,7 @@ static const CRPCCommand commands[] = { "wallet", "getrawchangeaddress", &getrawchangeaddress, {} }, { "wallet", "getreceivedbyaddress", &getreceivedbyaddress, {"address","minconf","addlocked"} }, { "wallet", "getreceivedbylabel", &getreceivedbylabel, {"label","minconf","addlocked"} }, - { "wallet", "gettransaction", &gettransaction, {"txid","include_watchonly"} }, + { "wallet", "gettransaction", &gettransaction, {"txid","include_watchonly","decode"} }, { "wallet", "getunconfirmedbalance", &getunconfirmedbalance, {} }, { "wallet", "getbalances", &getbalances, {} }, { "wallet", "getwalletinfo", &getwalletinfo, {} }, diff --git a/test/functional/wallet_basic.py b/test/functional/wallet_basic.py index d419bfb946..7e9f0ab531 100755 --- a/test/functional/wallet_basic.py +++ b/test/functional/wallet_basic.py @@ -496,6 +496,11 @@ class WalletTest(BitcoinTestFramework): 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) + assert_equal(tx["decoded"], self.nodes[0].decoderawtransaction(tx["hex"])) + if __name__ == '__main__': WalletTest().main()