Skip to content

Commit

Permalink
merge bitcoin#20286: deprecate addresses and reqSigs from rpc outputs
Browse files Browse the repository at this point in the history
  • Loading branch information
kwvg committed Jun 27, 2024
1 parent 7cddf70 commit 169dce7
Show file tree
Hide file tree
Showing 41 changed files with 193 additions and 136 deletions.
5 changes: 1 addition & 4 deletions doc/REST-interface.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,8 @@ $ curl localhost:19998/rest/getutxos/checkmempool/b2cdfd7b89def827ff8af7cd9bff76
"scriptPubKey" : {
"asm" : "OP_DUP OP_HASH160 1c7cebb529b86a04c683dfa87be49de35bcf589e OP_EQUALVERIFY OP_CHECKSIG",
"hex" : "76a9141c7cebb529b86a04c683dfa87be49de35bcf589e88ac",
"reqSigs" : 1,
"type" : "pubkeyhash",
"addresses" : [
"mi7as51dvLJsizWnTMurtRmrP8hG2m1XvD"
]
"address" : "mi7as51dvLJsizWnTMurtRmrP8hG2m1XvD"
}
}
]
Expand Down
16 changes: 16 additions & 0 deletions doc/release-notes-20286.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
Updated RPCs
------------

- The following RPCs: `gettxout`, `getrawtransaction`, `decoderawtransaction`,
`decodescript`, `gettransaction`, and REST endpoints: `/rest/tx`,
`/rest/getutxos`, `/rest/block` deprecated the following fields (which are no
longer returned in the responses by default): `addresses`, `reqSigs`.
The `-deprecatedrpc=addresses` flag must be passed for these fields to be
included in the RPC response. Note that these fields are attributes of
the `scriptPubKey` object returned in the RPC response. However, in the response
of `decodescript` these fields are top-level attributes, and included again as attributes
of the `scriptPubKey` object.

- When creating a hex-encoded Dash transaction using the `dash-tx` utility
with the `-json` option set, the following fields: `addresses`, `reqSigs` are no longer
returned in the tx output of the response.
2 changes: 1 addition & 1 deletion src/bitcoin-tx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -676,7 +676,7 @@ static void MutateTx(CMutableTransaction& tx, const std::string& command,
static void OutputTxJSON(const CTransaction& tx)
{
UniValue entry(UniValue::VOBJ);
TxToUniv(tx, uint256(), entry);
TxToUniv(tx, uint256(), /* include_addresses */ false, entry);

std::string jsonOutput = entry.write(4);
tfm::format(std::cout, "%s\n", jsonOutput);
Expand Down
4 changes: 2 additions & 2 deletions src/core_io.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ UniValue ValueFromAmount(const CAmount amount);
std::string FormatScript(const CScript& script);
std::string EncodeHexTx(const CTransaction& tx);
std::string SighashToStr(unsigned char sighash_type);
void ScriptPubKeyToUniv(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex);
void ScriptPubKeyToUniv(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex, bool include_addresses);
void ScriptToUniv(const CScript& script, UniValue& out, bool include_address);
void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry, bool include_hex = true, const CTxUndo* txundo = nullptr, const CSpentIndexTxInfo* ptxSpentInfo = nullptr);
void TxToUniv(const CTransaction& tx, const uint256& hashBlock, bool include_addresses, UniValue& entry, bool include_hex = true, const CTxUndo* txundo = nullptr, const CSpentIndexTxInfo* ptxSpentInfo = nullptr);

#endif // BITCOIN_CORE_IO_H
24 changes: 16 additions & 8 deletions src/core_write.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,10 +166,13 @@ void ScriptToUniv(const CScript& script, UniValue& out, bool include_address)
}
}

// TODO: from v21 ("addresses" and "reqSigs" deprecated) this method should be refactored to remove the `include_addresses` option
// this method can also be combined with `ScriptToUniv` as they will overlap
void ScriptPubKeyToUniv(const CScript& scriptPubKey,
UniValue& out, bool fIncludeHex)
UniValue& out, bool fIncludeHex, bool include_addresses)
{
TxoutType type;
CTxDestination address;
std::vector<CTxDestination> addresses;
int nRequired;

Expand All @@ -182,17 +185,22 @@ void ScriptPubKeyToUniv(const CScript& scriptPubKey,
return;
}

out.pushKV("reqSigs", nRequired);
if (ExtractDestination(scriptPubKey, address)) {
out.pushKV("address", EncodeDestination(address));
}
out.pushKV("type", GetTxnOutputType(type));

UniValue a(UniValue::VARR);
for (const CTxDestination& addr : addresses) {
a.push_back(EncodeDestination(addr));
if (include_addresses) {
UniValue a(UniValue::VARR);
for (const CTxDestination& addr : addresses) {
a.push_back(EncodeDestination(addr));
}
out.pushKV("addresses", a);
out.pushKV("reqSigs", nRequired);
}
out.pushKV("addresses", a);
}

void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry, bool include_hex, const CTxUndo* txundo, const CSpentIndexTxInfo* ptxSpentInfo)
void TxToUniv(const CTransaction& tx, const uint256& hashBlock, bool include_addresses, UniValue& entry, bool include_hex, const CTxUndo* txundo, const CSpentIndexTxInfo* ptxSpentInfo)
{
uint256 txid = tx.GetHash();
entry.pushKV("txid", txid.GetHex());
Expand Down Expand Up @@ -260,7 +268,7 @@ void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry,
out.pushKV("n", (int64_t)i);

UniValue o(UniValue::VOBJ);
ScriptPubKeyToUniv(txout.scriptPubKey, o, true);
ScriptPubKeyToUniv(txout.scriptPubKey, o, true, include_addresses);
out.pushKV("scriptPubKey", o);

// Add spent information if spentindex is enabled
Expand Down
17 changes: 14 additions & 3 deletions src/rpc/blockchain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1513,11 +1513,12 @@ static RPCHelpMan gettxout()
{RPCResult::Type::STR_AMOUNT, "value", "The transaction value in " + CURRENCY_UNIT},
{RPCResult::Type::OBJ, "scriptPubKey", "",
{
{RPCResult::Type::STR_HEX, "asm", ""},
{RPCResult::Type::STR, "asm", ""},
{RPCResult::Type::STR_HEX, "hex", ""},
{RPCResult::Type::NUM, "reqSigs", "Number of required signatures"},
{RPCResult::Type::NUM, "reqSigs", /* optional */ true, "(DEPRECATED, returned only if config option -deprecatedrpc=addresses is passed) Number of required signatures"},
{RPCResult::Type::STR_HEX, "type", "The type, eg pubkeyhash"},
{RPCResult::Type::ARR, "addresses", "Array of Dash addresses",
{RPCResult::Type::STR, "address", /* optional */ true, "Dash address (only if a well-defined address exists)"},
{RPCResult::Type::ARR, "addresses", /* optional */ true, "(DEPRECATED, returned only if config option -deprecatedrpc=addresses is passed) Array of Dash addresses",
{{RPCResult::Type::STR, "address", "Dash address"}}},
}},
{RPCResult::Type::BOOL, "coinbase", "Coinbase or not"},
Expand Down Expand Up @@ -2264,6 +2265,16 @@ void CalculatePercentilesBySize(CAmount result[NUM_GETBLOCKSTATS_PERCENTILES], s
}
}

void ScriptPubKeyToUniv(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex)
{
ScriptPubKeyToUniv(scriptPubKey, out, fIncludeHex, IsDeprecatedRPCEnabled("addresses"));
}

void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry, bool include_hex, const CTxUndo* txundo, const CSpentIndexTxInfo* ptxSpentInfo)
{
TxToUniv(tx, hashBlock, IsDeprecatedRPCEnabled("addresses"), entry, include_hex, txundo, ptxSpentInfo);
}

template<typename T>
static inline bool SetHasKeys(const std::set<T>& set) {return false;}
template<typename T, typename Tk, typename... Args>
Expand Down
4 changes: 4 additions & 0 deletions src/rpc/blockchain.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include <amount.h>
#include <context.h>
#include <core_io.h>
#include <streams.h>
#include <sync.h>

Expand Down Expand Up @@ -57,6 +58,9 @@ UniValue blockheaderToJSON(const CBlockIndex* tip, const CBlockIndex* blockindex
/** Used by getblockstats to get feerates at different percentiles by weight */
void CalculatePercentilesBySize(CAmount result[NUM_GETBLOCKSTATS_PERCENTILES], std::vector<std::pair<CAmount, int64_t>>& scores, int64_t total_size);

void ScriptPubKeyToUniv(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex);
void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry, bool include_hex = true, const CTxUndo* txundo = nullptr, const CSpentIndexTxInfo* ptxSpentInfo = nullptr);

NodeContext& EnsureAnyNodeContext(const CoreContext& context);
CTxMemPool& EnsureMemPool(const NodeContext& node);
CTxMemPool& EnsureAnyMemPool(const CoreContext& context);
Expand Down
15 changes: 9 additions & 6 deletions src/rpc/rawtransaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,9 +168,10 @@ static RPCHelpMan getrawtransaction()
{
{RPCResult::Type::STR, "asm", "the asm"},
{RPCResult::Type::STR, "hex", "the hex"},
{RPCResult::Type::NUM, "reqSigs", "The required sigs"},
{RPCResult::Type::NUM, "reqSigs", /* optional */ true, "(DEPRECATED, returned only if config option -deprecatedrpc=addresses is passed) Number of required signatures"},
{RPCResult::Type::STR, "type", "The type, eg 'pubkeyhash'"},
{RPCResult::Type::ARR, "addresses", "",
{RPCResult::Type::STR, "address", /* optional */ true, "Dash address (only if a well-defined address exists)"},
{RPCResult::Type::ARR, "addresses", /* optional */ true, "(DEPRECATED, returned only if config option -deprecatedrpc=addresses is passed) Array of Dash addresses",
{
{RPCResult::Type::STR, "address", "Dash address"},
}},
Expand Down Expand Up @@ -827,9 +828,10 @@ static RPCHelpMan decoderawtransaction()
{
{RPCResult::Type::STR, "asm", "the asm"},
{RPCResult::Type::STR_HEX, "hex", "the hex"},
{RPCResult::Type::NUM, "reqSigs", "The required sigs"},
{RPCResult::Type::NUM, "reqSigs", /* optional */ true, "(DEPRECATED, returned only if config option -deprecatedrpc=addresses is passed) Number of required signatures"},
{RPCResult::Type::STR, "type", "The type, eg 'pubkeyhash'"},
{RPCResult::Type::ARR, "addresses", "",
{RPCResult::Type::STR, "address", /* optional */ true, "Dash address (only if a well-defined address exists)"},
{RPCResult::Type::ARR, "addresses", /* optional */ true, "(DEPRECATED, returned only if config option -deprecatedrpc=addresses is passed) Array of Dash addresses",
{
{RPCResult::Type::STR, "address", "Dash address"},
}},
Expand Down Expand Up @@ -883,8 +885,9 @@ static RPCHelpMan decodescript()
{
{RPCResult::Type::STR, "asm", "Script public key"},
{RPCResult::Type::STR, "type", "The output type (e.g. "+GetAllOutputTypes()+")"},
{RPCResult::Type::NUM, "reqSigs", "The required signatures"},
{RPCResult::Type::ARR, "addresses", "",
{RPCResult::Type::STR, "address", /* optional */ true, "Dash address (only if a well-defined address exists)"},
{RPCResult::Type::NUM, "reqSigs", /* optional */ true, "(DEPRECATED, returned only if config option -deprecatedrpc=addresses is passed) Number of required signatures"},
{RPCResult::Type::ARR, "addresses", /* optional */ true, "(DEPRECATED, returned only if config option -deprecatedrpc=addresses is passed) Array of Dash addresses",
{
{RPCResult::Type::STR, "address", "Dash address"},
}},
Expand Down
2 changes: 1 addition & 1 deletion src/script/standard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,14 +189,14 @@ bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet)
return true;
}
case TxoutType::MULTISIG:
// Multisig txns have more than one address...
case TxoutType::NULL_DATA:
case TxoutType::NONSTANDARD:
return false;
} // no default case, so the compiler can warn about missing cases
assert(false);
}

// TODO: from v21 ("addresses" and "reqSigs" deprecated) "ExtractDestinations" should be removed
bool ExtractDestinations(const CScript& scriptPubKey, TxoutType& typeRet, std::vector<CTxDestination>& addressRet, int& nRequiredRet)
{
addressRet.clear();
Expand Down
2 changes: 2 additions & 0 deletions src/script/standard.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet)
* and nRequiredRet with the n required to spend. For other destinations,
* addressRet is populated with a single value and nRequiredRet is set to 1.
* Returns true if successful.
*
* TODO: from v21 ("addresses" and "reqSigs" deprecated) "ExtractDestinations" should be removed
*/
bool ExtractDestinations(const CScript& scriptPubKey, TxoutType& typeRet, std::vector<CTxDestination>& addressRet, int& nRequiredRet);

Expand Down
6 changes: 4 additions & 2 deletions src/test/fuzz/script.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,11 @@ FUZZ_TARGET_INIT(script, initialize_script)
(void)ScriptToAsmStr(script, true);

UniValue o1(UniValue::VOBJ);
ScriptPubKeyToUniv(script, o1, true);
ScriptPubKeyToUniv(script, o1, true, true);
ScriptPubKeyToUniv(script, o1, true, false);
UniValue o2(UniValue::VOBJ);
ScriptPubKeyToUniv(script, o2, false);
ScriptPubKeyToUniv(script, o2, false, true);
ScriptPubKeyToUniv(script, o2, false, false);
UniValue o3(UniValue::VOBJ);
ScriptToUniv(script, o3, true);
UniValue o4(UniValue::VOBJ);
Expand Down
6 changes: 4 additions & 2 deletions src/test/fuzz/transaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,9 @@ FUZZ_TARGET_INIT(transaction, initialize_transaction)
(void)AreInputsStandard(tx, coins_view_cache);

UniValue u(UniValue::VOBJ);
TxToUniv(tx, /* hashBlock */ {}, u);
TxToUniv(tx, /* hashBlock */ {}, /* include_addresses */ true, u);
TxToUniv(tx, /* hashBlock */ {}, /* include_addresses */ false, u);
static const uint256 u256_max(uint256S("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"));
TxToUniv(tx, u256_max, u);
TxToUniv(tx, u256_max, /* include_addresses */ true, u);
TxToUniv(tx, u256_max, /* include_addresses */ false, u);
}
2 changes: 1 addition & 1 deletion src/wallet/rpcwallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1811,7 +1811,7 @@ static RPCHelpMan gettransaction()

if (verbose) {
UniValue decoded(UniValue::VOBJ);
TxToUniv(*wtx.tx, uint256(), decoded, false);
TxToUniv(*wtx.tx, uint256(), pwallet->chain().rpcEnableDeprecated("addresses"), decoded, false);
entry.pushKV("decoded", decoded);
}

Expand Down
3 changes: 2 additions & 1 deletion test/functional/feature_dip3_deterministicmns.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ def set_test_params(self):
self.setup_clean_chain = True
self.supports_cli = False

self.extra_args = ["-budgetparams=10:10:10"]
self.extra_args = ["-deprecatedrpc=addresses"]
self.extra_args += ["-budgetparams=10:10:10"]
self.extra_args += ["-sporkkey=cP4EKFyJsHT39LDqgdcB43Y3YXjNyjb5Fuas1GQSeAtjnZWmZEQK"]
self.extra_args += ["-dip3params=135:150"]

Expand Down
6 changes: 3 additions & 3 deletions test/functional/feature_governance.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,14 @@ def check_superblock(self):
coinbase_outputs = self.nodes[0].getblock(self.nodes[0].getbestblockhash(), 2)["tx"][0]["vout"]
payments_found = 0
for txout in coinbase_outputs:
if txout["value"] == self.p0_amount and txout["scriptPubKey"]["addresses"][0] == self.p0_payout_address:
if txout["value"] == self.p0_amount and txout["scriptPubKey"]["address"] == self.p0_payout_address:
payments_found += 1
if txout["value"] == self.p1_amount and txout["scriptPubKey"]["addresses"][0] == self.p1_payout_address:
if txout["value"] == self.p1_amount and txout["scriptPubKey"]["address"] == self.p1_payout_address:
if self.p1_hash > self.p2_hash:
payments_found += 1
else:
assert False
if txout["value"] == self.p2_amount and txout["scriptPubKey"]["addresses"][0] == self.p2_payout_address:
if txout["value"] == self.p2_amount and txout["scriptPubKey"]["address"] == self.p2_payout_address:
if self.p2_hash > self.p1_hash:
payments_found += 1
else:
Expand Down
6 changes: 3 additions & 3 deletions test/functional/p2p_filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ def test_msg_mempool(self):
filter_peer = P2PBloomFilter()

self.log.debug("Create a tx relevant to the peer before connecting")
filter_address = self.nodes[0].decodescript(filter_peer.watch_script_pubkey)['addresses'][0]
filter_address = self.nodes[0].decodescript(filter_peer.watch_script_pubkey)['address']
txid = self.nodes[0].sendtoaddress(filter_address, 90)

self.log.debug("Send a mempool msg after connecting and check that the tx is received")
Expand All @@ -136,7 +136,7 @@ def test_msg_mempool(self):
def test_frelay_false(self, filter_peer):
self.log.info("Check that a node with fRelay set to false does not receive invs until the filter is set")
filter_peer.tx_received = False
filter_address = self.nodes[0].decodescript(filter_peer.watch_script_pubkey)['addresses'][0]
filter_address = self.nodes[0].decodescript(filter_peer.watch_script_pubkey)['address']
self.nodes[0].sendtoaddress(filter_address, 90)
# Sync to make sure the reason filter_peer doesn't receive the tx is not p2p delays
filter_peer.sync_with_ping()
Expand All @@ -150,7 +150,7 @@ def test_filter(self, filter_peer):
filter_peer.send_and_ping(filter_peer.watch_filter_init)
# If fRelay is not already True, sending filterload sets it to True
assert self.nodes[0].getpeerinfo()[0]['relaytxes']
filter_address = self.nodes[0].decodescript(filter_peer.watch_script_pubkey)['addresses'][0]
filter_address = self.nodes[0].decodescript(filter_peer.watch_script_pubkey)['address']

self.log.info('Check that we receive merkleblock and tx if the filter matches a tx in a block')
block_hash = self.nodes[0].generatetoaddress(1, filter_address)[0]
Expand Down
Loading

0 comments on commit 169dce7

Please sign in to comment.