rpc: add "ischange: true" in wallet gettransaction decoded tx output
This commit is contained in:
5 files changed
+25
-6
No files matched your search
+2
-1
@@ -21,6 +21,7 @@ class SigningProvider;
|
|||||||
class uint256;
|
class uint256;
|
||||||
class UniValue;
|
class UniValue;
|
||||||
class CTxUndo;
|
class CTxUndo;
|
||||||
|
class CTxOut;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verbose level for block's transaction
|
* Verbose level for block's transaction
|
||||||
@@ -46,6 +47,6 @@ std::string FormatScript(const CScript& script);
|
|||||||
std::string EncodeHexTx(const CTransaction& tx);
|
std::string EncodeHexTx(const CTransaction& tx);
|
||||||
std::string SighashToStr(unsigned char sighash_type);
|
std::string SighashToStr(unsigned char sighash_type);
|
||||||
void ScriptToUniv(const CScript& script, UniValue& out, bool include_hex = true, bool include_address = false, const SigningProvider* provider = nullptr);
|
void ScriptToUniv(const CScript& script, UniValue& out, bool include_hex = true, bool include_address = false, const SigningProvider* provider = nullptr);
|
||||||
void TxToUniv(const CTransaction& tx, const uint256& block_hash, UniValue& entry, bool include_hex = true, const CTxUndo* txundo = nullptr, TxVerbosity verbosity = TxVerbosity::SHOW_DETAILS);
|
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 = {});
|
||||||
|
|
||||||
#endif // BITCOIN_CORE_IO_H
|
#endif // BITCOIN_CORE_IO_H
|
||||||
+6
-1
@@ -168,7 +168,7 @@ void ScriptToUniv(const CScript& script, UniValue& out, bool include_hex, bool i
|
|||||||
out.pushKV("type", GetTxnOutputType(type));
|
out.pushKV("type", GetTxnOutputType(type));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TxToUniv(const CTransaction& tx, const uint256& block_hash, UniValue& entry, bool include_hex, const CTxUndo* txundo, TxVerbosity verbosity)
|
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)
|
||||||
{
|
{
|
||||||
CHECK_NONFATAL(verbosity >= TxVerbosity::SHOW_DETAILS);
|
CHECK_NONFATAL(verbosity >= TxVerbosity::SHOW_DETAILS);
|
||||||
|
|
||||||
@@ -243,6 +243,11 @@ void TxToUniv(const CTransaction& tx, const uint256& block_hash, UniValue& entry
|
|||||||
UniValue o(UniValue::VOBJ);
|
UniValue o(UniValue::VOBJ);
|
||||||
ScriptToUniv(txout.scriptPubKey, /*out=*/o, /*include_hex=*/true, /*include_address=*/true);
|
ScriptToUniv(txout.scriptPubKey, /*out=*/o, /*include_hex=*/true, /*include_address=*/true);
|
||||||
out.pushKV("scriptPubKey", std::move(o));
|
out.pushKV("scriptPubKey", std::move(o));
|
||||||
|
|
||||||
|
if (is_change_func && is_change_func(txout)) {
|
||||||
|
out.pushKV("ischange", true);
|
||||||
|
}
|
||||||
|
|
||||||
vout.push_back(std::move(out));
|
vout.push_back(std::move(out));
|
||||||
|
|
||||||
if (have_undo) {
|
if (have_undo) {
|
||||||
|
|||||||
@@ -118,6 +118,7 @@ static std::vector<RPCResult> DecodeTxDoc(const std::string& txid_field_doc)
|
|||||||
{RPCResult::Type::STR_AMOUNT, "value", "The value in " + CURRENCY_UNIT},
|
{RPCResult::Type::STR_AMOUNT, "value", "The value in " + CURRENCY_UNIT},
|
||||||
{RPCResult::Type::NUM, "n", "index"},
|
{RPCResult::Type::NUM, "n", "index"},
|
||||||
{RPCResult::Type::OBJ, "scriptPubKey", "", ScriptPubKeyDoc()},
|
{RPCResult::Type::OBJ, "scriptPubKey", "", ScriptPubKeyDoc()},
|
||||||
|
{RPCResult::Type::BOOL, "ischange", /*optional=*/true, "Output script is change (only if wallet transaction and true for selected rpcwallet)"},
|
||||||
}},
|
}},
|
||||||
}},
|
}},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -796,7 +796,16 @@ RPCHelpMan gettransaction()
|
|||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
UniValue decoded(UniValue::VOBJ);
|
UniValue decoded(UniValue::VOBJ);
|
||||||
TxToUniv(*wtx.tx, /*block_hash=*/uint256(), /*entry=*/decoded, /*include_hex=*/false);
|
TxToUniv(*wtx.tx,
|
||||||
|
/*block_hash=*/uint256(),
|
||||||
|
/*entry=*/decoded,
|
||||||
|
/*include_hex=*/false,
|
||||||
|
/*txundo=*/nullptr,
|
||||||
|
/*verbosity=*/TxVerbosity::SHOW_DETAILS,
|
||||||
|
/*is_change_func=*/[&pwallet](const CTxOut& txout) EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet) {
|
||||||
|
AssertLockHeld(pwallet->cs_wallet);
|
||||||
|
return OutputIsChange(*pwallet, txout);
|
||||||
|
});
|
||||||
entry.pushKV("decoded", std::move(decoded));
|
entry.pushKV("decoded", std::move(decoded));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -542,13 +542,16 @@ class WalletTest(BitcoinTestFramework):
|
|||||||
destination = self.nodes[1].getnewaddress()
|
destination = self.nodes[1].getnewaddress()
|
||||||
txid = self.nodes[0].sendtoaddress(destination, 0.123)
|
txid = self.nodes[0].sendtoaddress(destination, 0.123)
|
||||||
tx = self.nodes[0].gettransaction(txid=txid, verbose=True)['decoded']
|
tx = self.nodes[0].gettransaction(txid=txid, verbose=True)['decoded']
|
||||||
output_addresses = [vout['scriptPubKey']['address'] for vout in tx["vout"]]
|
assert len(tx["vout"]) > 1
|
||||||
assert len(output_addresses) > 1
|
for vout in tx["vout"]:
|
||||||
for address in output_addresses:
|
address = vout['scriptPubKey']['address']
|
||||||
ischange = self.nodes[0].getaddressinfo(address)['ischange']
|
ischange = self.nodes[0].getaddressinfo(address)['ischange']
|
||||||
assert_equal(ischange, address != destination)
|
assert_equal(ischange, address != destination)
|
||||||
if ischange:
|
if ischange:
|
||||||
change = address
|
change = address
|
||||||
|
assert vout["ischange"]
|
||||||
|
else:
|
||||||
|
assert "ischange" not in vout
|
||||||
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)
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user