Skip to content

Commit 2723625

Browse files
committed
wallet, rpc: Output wallet flags in getwalletinfo
1 parent c1c8d8f commit 2723625

File tree

4 files changed

+43
-11
lines changed

4 files changed

+43
-11
lines changed

src/wallet/rpc/wallet.cpp

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@ static RPCHelpMan getwalletinfo()
6161
{RPCResult::Type::BOOL, "external_signer", "whether this wallet is configured to use an external signer such as a hardware wallet"},
6262
{RPCResult::Type::BOOL, "blank", "Whether this wallet intentionally does not contain any keys, scripts, or descriptors"},
6363
{RPCResult::Type::NUM_TIME, "birthtime", /*optional=*/true, "The start time for blocks scanning. It could be modified by (re)importing any descriptor with an earlier timestamp."},
64+
{RPCResult::Type::ARR, "flags", "The flags currently set on the wallet",
65+
{
66+
{RPCResult::Type::STR, "flag", "The name of the flag"},
67+
}},
6468
RESULT_LAST_PROCESSED_BLOCK,
6569
}},
6670
},
@@ -116,6 +120,21 @@ static RPCHelpMan getwalletinfo()
116120
obj.pushKV("birthtime", birthtime);
117121
}
118122

123+
// Push known flags
124+
UniValue flags(UniValue::VARR);
125+
uint64_t wallet_flags = pwallet->GetWalletFlags();
126+
for (uint64_t i = 0; i < 64; ++i) {
127+
uint64_t flag = uint64_t{1} << i;
128+
if (flag & wallet_flags) {
129+
if (flag & KNOWN_WALLET_FLAGS) {
130+
flags.push_back(WALLET_FLAG_TO_STRING.at(WalletFlags{flag}));
131+
} else {
132+
flags.push_back(strprintf("unknown_flag_%u", i));
133+
}
134+
}
135+
}
136+
obj.pushKV("flags", flags);
137+
119138
AppendLastProcessedBlock(obj, *pwallet);
120139
return obj;
121140
},
@@ -267,7 +286,7 @@ static RPCHelpMan loadwallet()
267286
static RPCHelpMan setwalletflag()
268287
{
269288
std::string flags;
270-
for (auto& it : WALLET_FLAG_MAP)
289+
for (auto& it : STRING_TO_WALLET_FLAG)
271290
if (it.second & MUTABLE_WALLET_FLAGS)
272291
flags += (flags == "" ? "" : ", ") + it.first;
273292

@@ -298,11 +317,11 @@ static RPCHelpMan setwalletflag()
298317
std::string flag_str = request.params[0].get_str();
299318
bool value = request.params[1].isNull() || request.params[1].get_bool();
300319

301-
if (!WALLET_FLAG_MAP.count(flag_str)) {
320+
if (!STRING_TO_WALLET_FLAG.count(flag_str)) {
302321
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Unknown wallet flag: %s", flag_str));
303322
}
304323

305-
auto flag = WALLET_FLAG_MAP.at(flag_str);
324+
auto flag = STRING_TO_WALLET_FLAG.at(flag_str);
306325

307326
if (!(flag & MUTABLE_WALLET_FLAGS)) {
308327
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Wallet flag is immutable: %s", flag_str));

src/wallet/wallet.h

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -160,14 +160,24 @@ static constexpr uint64_t KNOWN_WALLET_FLAGS =
160160
static constexpr uint64_t MUTABLE_WALLET_FLAGS =
161161
WALLET_FLAG_AVOID_REUSE;
162162

163-
static const std::map<std::string,WalletFlags> WALLET_FLAG_MAP{
164-
{"avoid_reuse", WALLET_FLAG_AVOID_REUSE},
165-
{"blank", WALLET_FLAG_BLANK_WALLET},
166-
{"key_origin_metadata", WALLET_FLAG_KEY_ORIGIN_METADATA},
167-
{"last_hardened_xpub_cached", WALLET_FLAG_LAST_HARDENED_XPUB_CACHED},
168-
{"disable_private_keys", WALLET_FLAG_DISABLE_PRIVATE_KEYS},
169-
{"descriptor_wallet", WALLET_FLAG_DESCRIPTORS},
170-
{"external_signer", WALLET_FLAG_EXTERNAL_SIGNER}
163+
static const std::map<WalletFlags, std::string> WALLET_FLAG_TO_STRING{
164+
{WALLET_FLAG_AVOID_REUSE, "avoid_reuse"},
165+
{WALLET_FLAG_BLANK_WALLET, "blank"},
166+
{WALLET_FLAG_KEY_ORIGIN_METADATA, "key_origin_metadata"},
167+
{WALLET_FLAG_LAST_HARDENED_XPUB_CACHED, "last_hardened_xpub_cached"},
168+
{WALLET_FLAG_DISABLE_PRIVATE_KEYS, "disable_private_keys"},
169+
{WALLET_FLAG_DESCRIPTORS, "descriptor_wallet"},
170+
{WALLET_FLAG_EXTERNAL_SIGNER, "external_signer"}
171+
};
172+
173+
static const std::map<std::string, WalletFlags> STRING_TO_WALLET_FLAG{
174+
{WALLET_FLAG_TO_STRING.at(WALLET_FLAG_AVOID_REUSE), WALLET_FLAG_AVOID_REUSE},
175+
{WALLET_FLAG_TO_STRING.at(WALLET_FLAG_BLANK_WALLET), WALLET_FLAG_BLANK_WALLET},
176+
{WALLET_FLAG_TO_STRING.at(WALLET_FLAG_KEY_ORIGIN_METADATA), WALLET_FLAG_KEY_ORIGIN_METADATA},
177+
{WALLET_FLAG_TO_STRING.at(WALLET_FLAG_LAST_HARDENED_XPUB_CACHED), WALLET_FLAG_LAST_HARDENED_XPUB_CACHED},
178+
{WALLET_FLAG_TO_STRING.at(WALLET_FLAG_DISABLE_PRIVATE_KEYS), WALLET_FLAG_DISABLE_PRIVATE_KEYS},
179+
{WALLET_FLAG_TO_STRING.at(WALLET_FLAG_DESCRIPTORS), WALLET_FLAG_DESCRIPTORS},
180+
{WALLET_FLAG_TO_STRING.at(WALLET_FLAG_EXTERNAL_SIGNER), WALLET_FLAG_EXTERNAL_SIGNER}
171181
};
172182

173183
/** A wrapper to reserve an address from a wallet

test/functional/wallet_avoidreuse.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,9 @@ def test_persistence(self):
104104

105105
# Flags should be node1.avoid_reuse=false, node2.avoid_reuse=true
106106
assert_equal(self.nodes[0].getwalletinfo()["avoid_reuse"], False)
107+
assert_equal(sorted(self.nodes[0].getwalletinfo()["flags"]), sorted(["descriptor_wallet", "last_hardened_xpub_cached"]))
107108
assert_equal(self.nodes[1].getwalletinfo()["avoid_reuse"], True)
109+
assert_equal(sorted(self.nodes[1].getwalletinfo()["flags"]), sorted(["descriptor_wallet", "last_hardened_xpub_cached", "avoid_reuse"]))
108110

109111
self.restart_node(1)
110112
self.connect_nodes(0, 1)

test/functional/wallet_createwallet.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ def run_test(self):
4444
assert_raises_rpc_error(-4, "Error: This wallet has no available keys", w1.getrawchangeaddress)
4545
import_res = w1.importdescriptors([{"desc": w0.getaddressinfo(address1)['desc'], "timestamp": "now"}])
4646
assert_equal(import_res[0]["success"], True)
47+
assert_equal(sorted(w1.getwalletinfo()["flags"]), sorted(["last_hardened_xpub_cached", "descriptor_wallet", "disable_private_keys"]))
4748

4849
self.log.info('Test that private keys cannot be imported')
4950
privkey, pubkey = generate_keypair(wif=True)

0 commit comments

Comments
 (0)