mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-11-12 15:09:59 +01:00
Merge #16383: rpcwallet: default include_watchonly to true for watchonly wallets
72eaab073btests: functional watch-only wallet tests (William Casarin)72ffbdc579doc: add release note for include_watchonly default changes (William Casarin)003a3c73c0rpcwallet: document include_watchonly default for watchonly wallets (William Casarin)a50d9e6c0brpcwallet: default include_watchonly to true for watchonly wallets (William Casarin) Pull request description: Right now it's a bit annoying to deal with watchonly wallets, many rpc commands have an `include_watchonly` argument that needs to be explicitly set. Wallets created with `createwallet` can have a `disable_private_keys` parameter, for those wallets we already know that they are watchonly, so there's no reason to have to explicitly ask for it for every command. Instead we check this wallet flag when the `include_watchonly` parameter isn't set. ACKs for top commit: achow101: Code review ACK72eaab073bSjors: ACK72eaab073bpromag: ACK72eaab073b, code review only, didn't look closely to the test. kallewoof: ACK72eaab073bfanquake: ACK72eaab073b- I've looked over the changes, they make sense to me. Compiled and ran the tests etc. Tree-SHA512: d3646b55e97f386594d7efc994f0712f3888475c6a5dc7f131ac9f8c49bf5d4677182b88f42b34152abe1ad101ecadd152b4c20e9d3c1267190db36f77ab8bd7
This commit is contained in:
@@ -52,6 +52,23 @@ static inline bool GetAvoidReuseFlag(CWallet * const pwallet, const UniValue& pa
|
||||
return avoid_reuse;
|
||||
}
|
||||
|
||||
|
||||
/** Used by RPC commands that have an include_watchonly parameter.
|
||||
* We default to true for watchonly wallets if include_watchonly isn't
|
||||
* explicitly set.
|
||||
*/
|
||||
static bool ParseIncludeWatchonly(const UniValue& include_watchonly, const CWallet& pwallet)
|
||||
{
|
||||
if (include_watchonly.isNull()) {
|
||||
// if include_watchonly isn't explicitly set, then check if we have a watchonly wallet
|
||||
return pwallet.IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS);
|
||||
}
|
||||
|
||||
// otherwise return whatever include_watchonly was set to
|
||||
return include_watchonly.get_bool();
|
||||
}
|
||||
|
||||
|
||||
/** Checks if a CKey is in the given CWallet compressed or otherwise*/
|
||||
bool HaveKey(const CWallet& wallet, const CKey& key)
|
||||
{
|
||||
@@ -710,7 +727,7 @@ static UniValue getbalance(const JSONRPCRequest& request)
|
||||
{
|
||||
{"dummy", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, "Remains for backward compatibility. Must be excluded or set to \"*\"."},
|
||||
{"minconf", RPCArg::Type::NUM, /* default */ "0", "Only include transactions confirmed at least this many times."},
|
||||
{"include_watchonly", RPCArg::Type::BOOL, /* default */ "false", "Also include balance in watch-only addresses (see 'importaddress')"},
|
||||
{"include_watchonly", RPCArg::Type::BOOL, /* default */ "true for watch-only wallets, otherwise false", "Also include balance in watch-only addresses (see 'importaddress')"},
|
||||
{"avoid_reuse", RPCArg::Type::BOOL, /* default */ "true", "(only available if avoid_reuse wallet flag is set) Do not include balance in dirty outputs; addresses are considered dirty if they have previously been used in a transaction."},
|
||||
},
|
||||
RPCResult{
|
||||
@@ -743,10 +760,7 @@ static UniValue getbalance(const JSONRPCRequest& request)
|
||||
min_depth = request.params[1].get_int();
|
||||
}
|
||||
|
||||
bool include_watchonly = false;
|
||||
if (!request.params[2].isNull() && request.params[2].get_bool()) {
|
||||
include_watchonly = true;
|
||||
}
|
||||
bool include_watchonly = ParseIncludeWatchonly(request.params[2], *pwallet);
|
||||
|
||||
bool avoid_reuse = GetAvoidReuseFlag(pwallet, request.params[3]);
|
||||
|
||||
@@ -1023,9 +1037,10 @@ static UniValue ListReceived(interfaces::Chain::Lock& locked_chain, CWallet * co
|
||||
fIncludeEmpty = params[1].get_bool();
|
||||
|
||||
isminefilter filter = ISMINE_SPENDABLE;
|
||||
if(!params[2].isNull())
|
||||
if(params[2].get_bool())
|
||||
filter = filter | ISMINE_WATCH_ONLY;
|
||||
|
||||
if (ParseIncludeWatchonly(params[2], *pwallet)) {
|
||||
filter |= ISMINE_WATCH_ONLY;
|
||||
}
|
||||
|
||||
bool has_filtered_address = false;
|
||||
CTxDestination filtered_address = CNoDestination();
|
||||
@@ -1169,7 +1184,7 @@ static UniValue listreceivedbyaddress(const JSONRPCRequest& request)
|
||||
{
|
||||
{"minconf", RPCArg::Type::NUM, /* default */ "1", "The minimum number of confirmations before payments are included."},
|
||||
{"include_empty", RPCArg::Type::BOOL, /* default */ "false", "Whether to include addresses that haven't received any payments."},
|
||||
{"include_watchonly", RPCArg::Type::BOOL, /* default */ "false", "Whether to include watch-only addresses (see 'importaddress')."},
|
||||
{"include_watchonly", RPCArg::Type::BOOL, /* default */ "true for watch-only wallets, otherwise false", "Whether to include watch-only addresses (see 'importaddress')"},
|
||||
{"address_filter", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, "If present, only return information on this address."},
|
||||
},
|
||||
RPCResult{
|
||||
@@ -1220,7 +1235,7 @@ static UniValue listreceivedbylabel(const JSONRPCRequest& request)
|
||||
{
|
||||
{"minconf", RPCArg::Type::NUM, /* default */ "1", "The minimum number of confirmations before payments are included."},
|
||||
{"include_empty", RPCArg::Type::BOOL, /* default */ "false", "Whether to include labels that haven't received any payments."},
|
||||
{"include_watchonly", RPCArg::Type::BOOL, /* default */ "false", "Whether to include watch-only addresses (see 'importaddress')."},
|
||||
{"include_watchonly", RPCArg::Type::BOOL, /* default */ "true for watch-only wallets, otherwise false", "Whether to include watch-only addresses (see 'importaddress')"},
|
||||
},
|
||||
RPCResult{
|
||||
"[\n"
|
||||
@@ -1361,7 +1376,7 @@ UniValue listtransactions(const JSONRPCRequest& request)
|
||||
" with the specified label, or \"*\" to disable filtering and return all transactions."},
|
||||
{"count", RPCArg::Type::NUM, /* default */ "10", "The number of transactions to return"},
|
||||
{"skip", RPCArg::Type::NUM, /* default */ "0", "The number of transactions to skip"},
|
||||
{"include_watchonly", RPCArg::Type::BOOL, /* default */ "false", "Include transactions to watch-only addresses (see 'importaddress')"},
|
||||
{"include_watchonly", RPCArg::Type::BOOL, /* default */ "true for watch-only wallets, otherwise false", "Include transactions to watch-only addresses (see 'importaddress')"},
|
||||
},
|
||||
RPCResult{
|
||||
"[\n"
|
||||
@@ -1424,9 +1439,10 @@ UniValue listtransactions(const JSONRPCRequest& request)
|
||||
if (!request.params[2].isNull())
|
||||
nFrom = request.params[2].get_int();
|
||||
isminefilter filter = ISMINE_SPENDABLE;
|
||||
if(!request.params[3].isNull())
|
||||
if(request.params[3].get_bool())
|
||||
filter = filter | ISMINE_WATCH_ONLY;
|
||||
|
||||
if (ParseIncludeWatchonly(request.params[3], *pwallet)) {
|
||||
filter |= ISMINE_WATCH_ONLY;
|
||||
}
|
||||
|
||||
if (nCount < 0)
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative count");
|
||||
@@ -1492,7 +1508,7 @@ static UniValue listsinceblock(const JSONRPCRequest& request)
|
||||
{
|
||||
{"blockhash", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, "If set, the block hash to list transactions since, otherwise list all transactions."},
|
||||
{"target_confirmations", RPCArg::Type::NUM, /* default */ "1", "Return the nth block hash from the main chain. e.g. 1 would mean the best block hash. Note: this is not used as a filter, but only affects [lastblock] in the return value"},
|
||||
{"include_watchonly", RPCArg::Type::BOOL, /* default */ "false", "Include transactions to watch-only addresses (see 'importaddress')"},
|
||||
{"include_watchonly", RPCArg::Type::BOOL, /* default */ "true for watch-only wallets, otherwise false", "Include transactions to watch-only addresses (see 'importaddress')"},
|
||||
{"include_removed", RPCArg::Type::BOOL, /* default */ "true", "Show transactions that were removed due to a reorg in the \"removed\" array\n"
|
||||
" (not guaranteed to work on pruned nodes)"},
|
||||
},
|
||||
@@ -1569,8 +1585,8 @@ static UniValue listsinceblock(const JSONRPCRequest& request)
|
||||
}
|
||||
}
|
||||
|
||||
if (!request.params[2].isNull() && request.params[2].get_bool()) {
|
||||
filter = filter | ISMINE_WATCH_ONLY;
|
||||
if (ParseIncludeWatchonly(request.params[2], *pwallet)) {
|
||||
filter |= ISMINE_WATCH_ONLY;
|
||||
}
|
||||
|
||||
bool include_removed = (request.params[3].isNull() || request.params[3].get_bool());
|
||||
@@ -1632,7 +1648,7 @@ static UniValue gettransaction(const JSONRPCRequest& request)
|
||||
"\nGet detailed information about in-wallet transaction <txid>\n",
|
||||
{
|
||||
{"txid", RPCArg::Type::STR, RPCArg::Optional::NO, "The transaction id"},
|
||||
{"include_watchonly", RPCArg::Type::BOOL, /* default */ "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[]"},
|
||||
},
|
||||
RPCResult{
|
||||
"{\n"
|
||||
@@ -1687,9 +1703,10 @@ static UniValue gettransaction(const JSONRPCRequest& request)
|
||||
uint256 hash(ParseHashV(request.params[0], "txid"));
|
||||
|
||||
isminefilter filter = ISMINE_SPENDABLE;
|
||||
if(!request.params[1].isNull())
|
||||
if(request.params[1].get_bool())
|
||||
filter = filter | ISMINE_WATCH_ONLY;
|
||||
|
||||
if (ParseIncludeWatchonly(request.params[1], *pwallet)) {
|
||||
filter |= ISMINE_WATCH_ONLY;
|
||||
}
|
||||
|
||||
UniValue entry(UniValue::VOBJ);
|
||||
auto it = pwallet->mapWallet.find(hash);
|
||||
@@ -3015,8 +3032,7 @@ void FundTransaction(CWallet* const pwallet, CMutableTransaction& tx, CAmount& f
|
||||
}
|
||||
}
|
||||
|
||||
if (options.exists("includeWatching"))
|
||||
coinControl.fAllowWatchOnly = options["includeWatching"].get_bool();
|
||||
coinControl.fAllowWatchOnly = ParseIncludeWatchonly(options["includeWatching"], *pwallet);
|
||||
|
||||
if (options.exists("lockUnspents"))
|
||||
lockUnspents = options["lockUnspents"].get_bool();
|
||||
@@ -3048,6 +3064,9 @@ void FundTransaction(CWallet* const pwallet, CMutableTransaction& tx, CAmount& f
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// if options is null and not a bool
|
||||
coinControl.fAllowWatchOnly = ParseIncludeWatchonly(NullUniValue, *pwallet);
|
||||
}
|
||||
|
||||
if (tx.vout.size() == 0)
|
||||
@@ -3102,7 +3121,7 @@ static UniValue fundrawtransaction(const JSONRPCRequest& request)
|
||||
{"changeAddress", RPCArg::Type::STR, /* default */ "pool address", "The bitcoin address to receive the change"},
|
||||
{"changePosition", RPCArg::Type::NUM, /* default */ "random", "The index of the change output"},
|
||||
{"change_type", RPCArg::Type::STR, /* default */ "set by -changetype", "The output type to use. Only valid if changeAddress is not specified. Options are \"legacy\", \"p2sh-segwit\", and \"bech32\"."},
|
||||
{"includeWatching", RPCArg::Type::BOOL, /* default */ "false", "Also select inputs which are watch only"},
|
||||
{"includeWatching", RPCArg::Type::BOOL, /* default */ "true for watch-only wallets, otherwise false", "Also select inputs which are watch only"},
|
||||
{"lockUnspents", RPCArg::Type::BOOL, /* default */ "false", "Lock selected unspent outputs"},
|
||||
{"feeRate", RPCArg::Type::AMOUNT, /* default */ "not set: makes wallet determine the fee", "Set a specific fee rate in " + CURRENCY_UNIT + "/kB"},
|
||||
{"subtractFeeFromOutputs", RPCArg::Type::ARR, /* default */ "empty array", "A json array of integers.\n"
|
||||
@@ -4047,7 +4066,7 @@ UniValue walletcreatefundedpsbt(const JSONRPCRequest& request)
|
||||
{"changeAddress", RPCArg::Type::STR_HEX, /* default */ "pool address", "The bitcoin address to receive the change"},
|
||||
{"changePosition", RPCArg::Type::NUM, /* default */ "random", "The index of the change output"},
|
||||
{"change_type", RPCArg::Type::STR, /* default */ "set by -changetype", "The output type to use. Only valid if changeAddress is not specified. Options are \"legacy\", \"p2sh-segwit\", and \"bech32\"."},
|
||||
{"includeWatching", RPCArg::Type::BOOL, /* default */ "false", "Also select inputs which are watch only"},
|
||||
{"includeWatching", RPCArg::Type::BOOL, /* default */ "true for watch-only wallets, otherwise false", "Also select inputs which are watch only"},
|
||||
{"lockUnspents", RPCArg::Type::BOOL, /* default */ "false", "Lock selected unspent outputs"},
|
||||
{"feeRate", RPCArg::Type::AMOUNT, /* default */ "not set: makes wallet determine the fee", "Set a specific fee rate in " + CURRENCY_UNIT + "/kB"},
|
||||
{"subtractFeeFromOutputs", RPCArg::Type::ARR, /* default */ "empty array", "A json array of integers.\n"
|
||||
|
||||
Reference in New Issue
Block a user