Merge #16185: gettransaction: add an argument to decode the transaction

9965940e35 doc: Add release note for the new gettransaction argument (darosior)
b8b3f0435a tests: Add a new functional test for gettransaction (darosior)
7f3bb247a8 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 9965940e35

Tree-SHA512: bcb6b4bd252b3488d6afc77659c499c2ad99fd58661eb24b6a2e17014c74f22e47fde70e00fedb4f4754915786622ad02483b2cf2c4dea0ab0eb4ac8276dbeee
This commit is contained in:
MeshCollider 2019-09-02 23:29:42 +12:00
commit 33f9750b1b
No known key found for this signature in database
GPG Key ID: D300116E1C875A3D
4 changed files with 21 additions and 1 deletions

View File

@ -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.

View File

@ -85,6 +85,7 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "getblockheader", 1, "verbose" }, { "getblockheader", 1, "verbose" },
{ "getchaintxstats", 0, "nblocks" }, { "getchaintxstats", 0, "nblocks" },
{ "gettransaction", 1, "include_watchonly" }, { "gettransaction", 1, "include_watchonly" },
{ "gettransaction", 2, "decode" },
{ "getrawtransaction", 1, "verbose" }, { "getrawtransaction", 1, "verbose" },
{ "createrawtransaction", 0, "inputs" }, { "createrawtransaction", 0, "inputs" },
{ "createrawtransaction", 1, "outputs" }, { "createrawtransaction", 1, "outputs" },

View File

@ -1649,6 +1649,7 @@ static UniValue gettransaction(const JSONRPCRequest& request)
{ {
{"txid", RPCArg::Type::STR, RPCArg::Optional::NO, "The transaction id"}, {"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[]"}, {"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{
"{\n" "{\n"
@ -1684,11 +1685,13 @@ static UniValue gettransaction(const JSONRPCRequest& request)
" ,...\n" " ,...\n"
" ],\n" " ],\n"
" \"hex\" : \"data\" (string) Raw data for transaction\n" " \"hex\" : \"data\" (string) Raw data for transaction\n"
" \"decoded\" : transaction (json object) Optional, the decoded transaction\n"
"}\n" "}\n"
}, },
RPCExamples{ RPCExamples{
HelpExampleCli("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"") HelpExampleCli("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"")
+ HelpExampleCli("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\" true") + HelpExampleCli("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\" true")
+ HelpExampleCli("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\" false true")
+ HelpExampleRpc("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"") + HelpExampleRpc("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"")
}, },
}.Check(request); }.Check(request);
@ -1708,6 +1711,8 @@ static UniValue gettransaction(const JSONRPCRequest& request)
filter |= ISMINE_WATCH_ONLY; filter |= ISMINE_WATCH_ONLY;
} }
bool decode_tx = request.params[2].isNull() ? false : request.params[2].get_bool();
UniValue entry(UniValue::VOBJ); UniValue entry(UniValue::VOBJ);
auto it = pwallet->mapWallet.find(hash); auto it = pwallet->mapWallet.find(hash);
if (it == pwallet->mapWallet.end()) { if (it == pwallet->mapWallet.end()) {
@ -1733,6 +1738,12 @@ static UniValue gettransaction(const JSONRPCRequest& request)
std::string strHex = EncodeHexTx(*wtx.tx, pwallet->chain().rpcSerializationFlags()); std::string strHex = EncodeHexTx(*wtx.tx, pwallet->chain().rpcSerializationFlags());
entry.pushKV("hex", strHex); entry.pushKV("hex", strHex);
if (decode_tx) {
UniValue decoded(UniValue::VOBJ);
TxToUniv(*wtx.tx, uint256(), decoded, false);
entry.pushKV("decoded", decoded);
}
return entry; return entry;
} }
@ -4175,7 +4186,7 @@ static const CRPCCommand commands[] =
{ "wallet", "getrawchangeaddress", &getrawchangeaddress, {"address_type"} }, { "wallet", "getrawchangeaddress", &getrawchangeaddress, {"address_type"} },
{ "wallet", "getreceivedbyaddress", &getreceivedbyaddress, {"address","minconf"} }, { "wallet", "getreceivedbyaddress", &getreceivedbyaddress, {"address","minconf"} },
{ "wallet", "getreceivedbylabel", &getreceivedbylabel, {"label","minconf"} }, { "wallet", "getreceivedbylabel", &getreceivedbylabel, {"label","minconf"} },
{ "wallet", "gettransaction", &gettransaction, {"txid","include_watchonly"} }, { "wallet", "gettransaction", &gettransaction, {"txid","include_watchonly","decode"} },
{ "wallet", "getunconfirmedbalance", &getunconfirmedbalance, {} }, { "wallet", "getunconfirmedbalance", &getunconfirmedbalance, {} },
{ "wallet", "getbalances", &getbalances, {} }, { "wallet", "getbalances", &getbalances, {} },
{ "wallet", "getwalletinfo", &getwalletinfo, {} }, { "wallet", "getwalletinfo", &getwalletinfo, {} },

View File

@ -499,6 +499,11 @@ class WalletTest(BitcoinTestFramework):
self.nodes[0].setlabel(change, 'foobar') self.nodes[0].setlabel(change, 'foobar')
assert_equal(self.nodes[0].getaddressinfo(change)['ischange'], False) 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__': if __name__ == '__main__':
WalletTest().main() WalletTest().main()