Skip to content

Commit d633db5

Browse files
committed
rpc: add "ischange: true" in wallet gettransaction decoded tx output
1 parent c779ee3 commit d633db5

File tree

5 files changed

+25
-6
lines changed

5 files changed

+25
-6
lines changed

src/core_io.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ class SigningProvider;
2121
class uint256;
2222
class UniValue;
2323
class CTxUndo;
24+
class CTxOut;
2425

2526
/**
2627
* Verbose level for block's transaction
@@ -46,6 +47,6 @@ std::string FormatScript(const CScript& script);
4647
std::string EncodeHexTx(const CTransaction& tx);
4748
std::string SighashToStr(unsigned char sighash_type);
4849
void ScriptToUniv(const CScript& script, UniValue& out, bool include_hex = true, bool include_address = false, const SigningProvider* provider = nullptr);
49-
void TxToUniv(const CTransaction& tx, const uint256& block_hash, UniValue& entry, bool include_hex = true, const CTxUndo* txundo = nullptr, TxVerbosity verbosity = TxVerbosity::SHOW_DETAILS);
50+
void TxToUniv(const CTransaction& tx, const uint256& block_hash, UniValue& entry, bool include_hex = true, const CTxUndo* txundo = nullptr, TxVerbosity verbosity = TxVerbosity::SHOW_DETAILS, std::function<bool(const CTxOut&)> is_change_func = {});
5051

5152
#endif // BITCOIN_CORE_IO_H

src/core_write.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ void ScriptToUniv(const CScript& script, UniValue& out, bool include_hex, bool i
168168
out.pushKV("type", GetTxnOutputType(type));
169169
}
170170

171-
void TxToUniv(const CTransaction& tx, const uint256& block_hash, UniValue& entry, bool include_hex, const CTxUndo* txundo, TxVerbosity verbosity)
171+
void TxToUniv(const CTransaction& tx, const uint256& block_hash, UniValue& entry, bool include_hex, const CTxUndo* txundo, TxVerbosity verbosity, std::function<bool(const CTxOut&)> is_change_func)
172172
{
173173
CHECK_NONFATAL(verbosity >= TxVerbosity::SHOW_DETAILS);
174174

@@ -243,6 +243,11 @@ void TxToUniv(const CTransaction& tx, const uint256& block_hash, UniValue& entry
243243
UniValue o(UniValue::VOBJ);
244244
ScriptToUniv(txout.scriptPubKey, /*out=*/o, /*include_hex=*/true, /*include_address=*/true);
245245
out.pushKV("scriptPubKey", std::move(o));
246+
247+
if (is_change_func && is_change_func(txout)) {
248+
out.pushKV("ischange", true);
249+
}
250+
246251
vout.push_back(std::move(out));
247252

248253
if (have_undo) {

src/rpc/rawtransaction.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ static std::vector<RPCResult> DecodeTxDoc(const std::string& txid_field_doc)
118118
{RPCResult::Type::STR_AMOUNT, "value", "The value in " + CURRENCY_UNIT},
119119
{RPCResult::Type::NUM, "n", "index"},
120120
{RPCResult::Type::OBJ, "scriptPubKey", "", ScriptPubKeyDoc()},
121+
{RPCResult::Type::BOOL, "ischange", /*optional=*/true, "Output script is change (only if wallet transaction and true for selected rpcwallet)"},
121122
}},
122123
}},
123124
};

src/wallet/rpc/transactions.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -796,7 +796,16 @@ RPCHelpMan gettransaction()
796796

797797
if (verbose) {
798798
UniValue decoded(UniValue::VOBJ);
799-
TxToUniv(*wtx.tx, /*block_hash=*/uint256(), /*entry=*/decoded, /*include_hex=*/false);
799+
TxToUniv(*wtx.tx,
800+
/*block_hash=*/uint256(),
801+
/*entry=*/decoded,
802+
/*include_hex=*/false,
803+
/*txundo=*/nullptr,
804+
/*verbosity=*/TxVerbosity::SHOW_DETAILS,
805+
/*is_change_func=*/[&pwallet](const CTxOut& txout) EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet) {
806+
AssertLockHeld(pwallet->cs_wallet);
807+
return OutputIsChange(*pwallet, txout);
808+
});
800809
entry.pushKV("decoded", std::move(decoded));
801810
}
802811

test/functional/wallet_basic.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -542,13 +542,16 @@ def run_test(self):
542542
destination = self.nodes[1].getnewaddress()
543543
txid = self.nodes[0].sendtoaddress(destination, 0.123)
544544
tx = self.nodes[0].gettransaction(txid=txid, verbose=True)['decoded']
545-
output_addresses = [vout['scriptPubKey']['address'] for vout in tx["vout"]]
546-
assert len(output_addresses) > 1
547-
for address in output_addresses:
545+
assert len(tx["vout"]) > 1
546+
for vout in tx["vout"]:
547+
address = vout['scriptPubKey']['address']
548548
ischange = self.nodes[0].getaddressinfo(address)['ischange']
549549
assert_equal(ischange, address != destination)
550550
if ischange:
551551
change = address
552+
assert vout["ischange"]
553+
else:
554+
assert "ischange" not in vout
552555
self.nodes[0].setlabel(change, 'foobar')
553556
assert_equal(self.nodes[0].getaddressinfo(change)['ischange'], False)
554557

0 commit comments

Comments
 (0)