diff options
author | MarcoFalke <falke.marco@gmail.com> | 2021-03-29 15:14:25 +0200 |
---|---|---|
committer | MarcoFalke <falke.marco@gmail.com> | 2021-03-29 15:14:31 +0200 |
commit | 1c7be9ab90af14d24f4668b02d9f07cec6f88a78 (patch) | |
tree | ef84a8e4388ce4610bf070af1792d00bc68d0d90 /src | |
parent | 4399dc81420f5a106bc34384b837bbd9aba7ddef (diff) | |
parent | 90ae3d8ca68334ec712d67b21a8d4721c6d79788 (diff) | |
download | bitcoin-1c7be9ab90af14d24f4668b02d9f07cec6f88a78.tar.xz |
Merge #20286: rpc: deprecate `addresses` and `reqSigs` from rpc outputs
90ae3d8ca68334ec712d67b21a8d4721c6d79788 doc: Add release notes for -deprecatedrpc=addresses and bitcoin-tx (Michael Dietz)
085b3a729952896ccd0e40c17df569f4421f5493 rpc: deprecate `addresses` and `reqSigs` from rpc outputs (Michael Dietz)
Pull request description:
Considering the limited applicability of `reqSigs` and the confusing output of `1` in all cases except bare multisig, the `addresses` and `reqSigs` outputs are removed for all rpc commands.
1) add a new sane "address" field (for outputs that have an identifiable address, which doesn't include bare multisig)
2) with -deprecatedrpc: leave "reqSigs" and "addresses" intact (with all weird/wrong behavior they have now)
3) without -deprecatedrpc: drop "reqSigs" and "addresses" entirely always.
Note: Some light refactoring done to allow us to very easily delete a few chunks of code (marked with TODOs) when we remove this deprecated behavior.
Using `IsDeprecatedRPCEnabled` in core_write.cpp caused some circular dependencies involving core_io
Circular dependencies were caused by rpc/util unnecessarily importing node/coinstats and node/transaction. Really what rpc/util needs are some fundamental type/helper-function definitions. So this was cleaned up to make more sense.
This fixes #20102.
ACKs for top commit:
MarcoFalke:
re-ACK 90ae3d8ca68334ec712d67b21a8d4721c6d79788 📢
Tree-SHA512: 8ffb617053b5f4a8b055da17c06711fd19632e0037d71c4c8135e50c8cd7a19163989484e4e0f17a6cc48bd597f04ecbfd609aef54b7d1d1e76a784214fcf72a
Diffstat (limited to 'src')
-rw-r--r-- | src/bitcoin-tx.cpp | 2 | ||||
-rw-r--r-- | src/core_io.h | 4 | ||||
-rw-r--r-- | src/core_write.cpp | 24 | ||||
-rw-r--r-- | src/rpc/blockchain.cpp | 20 | ||||
-rw-r--r-- | src/rpc/blockchain.h | 4 | ||||
-rw-r--r-- | src/rpc/rawtransaction.cpp | 21 | ||||
-rw-r--r-- | src/script/standard.cpp | 2 | ||||
-rw-r--r-- | src/script/standard.h | 2 | ||||
-rw-r--r-- | src/test/fuzz/script.cpp | 6 | ||||
-rw-r--r-- | src/test/fuzz/transaction.cpp | 6 | ||||
-rw-r--r-- | src/wallet/rpcwallet.cpp | 2 |
11 files changed, 63 insertions, 30 deletions
diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index 321d62fe4d..93ac4b8f7e 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -725,7 +725,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); diff --git a/src/core_io.h b/src/core_io.h index 01340ae2ee..3b9b66574c 100644 --- a/src/core_io.h +++ b/src/core_io.h @@ -44,8 +44,8 @@ UniValue ValueFromAmount(const CAmount amount); std::string FormatScript(const CScript& script); std::string EncodeHexTx(const CTransaction& tx, const int serializeFlags = 0); 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, int serialize_flags = 0, const CTxUndo* txundo = nullptr); +void TxToUniv(const CTransaction& tx, const uint256& hashBlock, bool include_addresses, UniValue& entry, bool include_hex = true, int serialize_flags = 0, const CTxUndo* txundo = nullptr); #endif // BITCOIN_CORE_IO_H diff --git a/src/core_write.cpp b/src/core_write.cpp index d3034ae25d..b35f835f42 100644 --- a/src/core_write.cpp +++ b/src/core_write.cpp @@ -156,10 +156,13 @@ void ScriptToUniv(const CScript& script, UniValue& out, bool include_address) } } +// TODO: from v23 ("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; @@ -172,17 +175,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, int serialize_flags, const CTxUndo* txundo) +void TxToUniv(const CTransaction& tx, const uint256& hashBlock, bool include_addresses, UniValue& entry, bool include_hex, int serialize_flags, const CTxUndo* txundo) { entry.pushKV("txid", tx.GetHash().GetHex()); entry.pushKV("hash", tx.GetWitnessHash().GetHex()); @@ -241,7 +249,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); vout.push_back(out); diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 3ba2fa46ae..f0ad141fa9 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1113,11 +1113,13 @@ static RPCHelpMan gettxout() {RPCResult::Type::NUM, "confirmations", "The number of confirmations"}, {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::STR_HEX, "type", "The type, eg pubkeyhash"}, - {RPCResult::Type::ARR, "addresses", "array of bitcoin addresses", {{RPCResult::Type::STR, "address", "bitcoin address"}}}, + {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::STR, "address", /* optional */ true, "bitcoin 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 bitcoin addresses", + {{RPCResult::Type::STR, "address", "bitcoin address"}}}, }}, {RPCResult::Type::BOOL, "coinbase", "Coinbase or not"}, }}, @@ -1775,6 +1777,16 @@ void CalculatePercentilesByWeight(CAmount result[NUM_GETBLOCKSTATS_PERCENTILES], } } +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, int serialize_flags, const CTxUndo* txundo) +{ + TxToUniv(tx, hashBlock, IsDeprecatedRPCEnabled("addresses"), entry, include_hex, serialize_flags, txundo); +} + template<typename T> static inline bool SetHasKeys(const std::set<T>& set) {return false;} template<typename T, typename Tk, typename... Args> diff --git a/src/rpc/blockchain.h b/src/rpc/blockchain.h index d8cae4dd24..e719dfc702 100644 --- a/src/rpc/blockchain.h +++ b/src/rpc/blockchain.h @@ -6,6 +6,7 @@ #define BITCOIN_RPC_BLOCKCHAIN_H #include <amount.h> +#include <core_io.h> #include <streams.h> #include <sync.h> @@ -54,6 +55,9 @@ UniValue blockheaderToJSON(const CBlockIndex* tip, const CBlockIndex* blockindex /** Used by getblockstats to get feerates at different percentiles by weight */ void CalculatePercentilesByWeight(CAmount result[NUM_GETBLOCKSTATS_PERCENTILES], std::vector<std::pair<CAmount, int64_t>>& scores, int64_t total_weight); +void ScriptPubKeyToUniv(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex); +void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry, bool include_hex = true, int serialize_flags = 0, const CTxUndo* txundo = nullptr); + NodeContext& EnsureNodeContext(const util::Ref& context); CTxMemPool& EnsureMemPool(const util::Ref& context); ChainstateManager& EnsureChainman(const util::Ref& context); diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 2f92a321f8..7932bd2915 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -35,7 +35,6 @@ #include <validation.h> #include <validationinterface.h> - #include <numeric> #include <stdint.h> @@ -132,9 +131,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, "bitcoin 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 bitcoin addresses", { {RPCResult::Type::STR, "address", "bitcoin address"}, }}, @@ -490,9 +490,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, "bitcoin 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 bitcoin addresses", { {RPCResult::Type::STR, "address", "bitcoin address"}, }}, @@ -548,8 +549,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, "bitcoin 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 bitcoin addresses", { {RPCResult::Type::STR, "address", "bitcoin address"}, }}, @@ -559,8 +561,9 @@ static RPCHelpMan decodescript() {RPCResult::Type::STR, "asm", "String representation of the script public key"}, {RPCResult::Type::STR_HEX, "hex", "Hex string of the script public key"}, {RPCResult::Type::STR, "type", "The type of the script public key (e.g. witness_v0_keyhash or witness_v0_scripthash)"}, - {RPCResult::Type::NUM, "reqSigs", "The required signatures (always 1)"}, - {RPCResult::Type::ARR, "addresses", "(always length 1)", + {RPCResult::Type::STR, "address", /* optional */ true, "bitcoin 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 bitcoin addresses", { {RPCResult::Type::STR, "address", "segwit address"}, }}, diff --git a/src/script/standard.cpp b/src/script/standard.cpp index 4d882cd1f1..700155c8d4 100644 --- a/src/script/standard.cpp +++ b/src/script/standard.cpp @@ -220,7 +220,6 @@ 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; @@ -228,6 +227,7 @@ bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet) assert(false); } +// TODO: from v23 ("addresses" and "reqSigs" deprecated) "ExtractDestinations" should be removed bool ExtractDestinations(const CScript& scriptPubKey, TxoutType& typeRet, std::vector<CTxDestination>& addressRet, int& nRequiredRet) { addressRet.clear(); diff --git a/src/script/standard.h b/src/script/standard.h index d5d87392ad..f2bf4a8af3 100644 --- a/src/script/standard.h +++ b/src/script/standard.h @@ -247,6 +247,8 @@ bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet) * Note: this function confuses destinations (a subset of CScripts that are * encodable as an address) with key identifiers (of keys involved in a * CScript), and its use should be phased out. + * + * TODO: from v23 ("addresses" and "reqSigs" deprecated) "ExtractDestinations" should be removed */ bool ExtractDestinations(const CScript& scriptPubKey, TxoutType& typeRet, std::vector<CTxDestination>& addressRet, int& nRequiredRet); diff --git a/src/test/fuzz/script.cpp b/src/test/fuzz/script.cpp index 8219a04e49..e87ae5b04b 100644 --- a/src/test/fuzz/script.cpp +++ b/src/test/fuzz/script.cpp @@ -103,9 +103,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); diff --git a/src/test/fuzz/transaction.cpp b/src/test/fuzz/transaction.cpp index 41e1687405..17e4405a13 100644 --- a/src/test/fuzz/transaction.cpp +++ b/src/test/fuzz/transaction.cpp @@ -100,7 +100,9 @@ FUZZ_TARGET_INIT(transaction, initialize_transaction) (void)IsWitnessStandard(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); } diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 6dc8d1de42..e70bbafde0 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1741,7 +1741,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); } |