Skip to content

Commit 8facd0e

Browse files
achow101thepastaclaw
authored andcommitted
Merge bitcoin#28597: wallet: No BDB creation, unless -deprecatedrpc=create_bdb
fa071ae wallet: No BDB creation, unless -deprecatedrpc=create_bdb (MarcoFalke) Pull request description: With BDB being removed soon, it seems confusing and harmful to allow users to create fresh BDB wallets going forward, as it would load them with an additional burden of having to migrate them soon after. Also, it would be good to allow for one release for test (and external) scripts to adapt. Fix all issues by introducing the `-deprecatedrpc=create_bdb` setting. ACKs for top commit: Sjors: tACK fa071ae achow101: ACK fa071ae furszy: utACK fa071ae Tree-SHA512: 37a4c3e4ba659e0ebe2382e71d9c80e42a895d9ad743f5dda7c110fbbb7d2a36f46769982552a9ac0c3a57203379ef164be97aa8033eb7674d6b4da030ba8f9b
1 parent 3cafabb commit 8facd0e

File tree

5 files changed

+39
-21
lines changed

5 files changed

+39
-21
lines changed

src/rpc/util.cpp

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,7 @@ TMPL_INST(nullptr, std::optional<bool>, maybe_arg ? std::optional{maybe_arg->get
573573
TMPL_INST(nullptr, const std::string*, maybe_arg ? &maybe_arg->get_str() : nullptr;);
574574

575575
// Required arg or optional arg with default value.
576+
TMPL_INST(CheckRequiredOrDefault, bool, CHECK_NONFATAL(maybe_arg)->get_bool(););
576577
TMPL_INST(CheckRequiredOrDefault, int, CHECK_NONFATAL(maybe_arg)->getInt<int>(););
577578
TMPL_INST(CheckRequiredOrDefault, uint64_t, CHECK_NONFATAL(maybe_arg)->getInt<uint64_t>(););
578579
TMPL_INST(CheckRequiredOrDefault, const std::string&, CHECK_NONFATAL(maybe_arg)->get_str(););
@@ -678,42 +679,50 @@ UniValue RPCHelpMan::GetArgMap() const
678679
return arr;
679680
}
680681

681-
void RPCArg::MatchesType(const UniValue& request) const
682+
static std::optional<UniValue::VType> ExpectedType(RPCArg::Type type)
682683
{
683-
if (m_opts.skip_type_check) return;
684-
if (IsOptional() && request.isNull()) return;
685-
switch (m_type) {
684+
using Type = RPCArg::Type;
685+
switch (type) {
686686
case Type::STR_HEX:
687687
case Type::STR: {
688-
RPCTypeCheckArgument(request, UniValue::VSTR);
689-
return;
688+
return UniValue::VSTR;
690689
}
691690
case Type::NUM: {
692-
RPCTypeCheckArgument(request, UniValue::VNUM);
693-
return;
691+
return UniValue::VNUM;
694692
}
695693
case Type::AMOUNT: {
696694
// VNUM or VSTR, checked inside AmountFromValue()
697-
return;
695+
return std::nullopt;
698696
}
699697
case Type::RANGE: {
700698
// VNUM or VARR, checked inside ParseRange()
701-
return;
699+
return std::nullopt;
702700
}
703701
case Type::BOOL: {
704-
RPCTypeCheckArgument(request, UniValue::VBOOL);
705-
return;
702+
return UniValue::VBOOL;
706703
}
707704
case Type::OBJ:
708705
case Type::OBJ_USER_KEYS: {
709-
RPCTypeCheckArgument(request, UniValue::VOBJ);
710-
return;
706+
return UniValue::VOBJ;
711707
}
712708
case Type::ARR: {
713-
RPCTypeCheckArgument(request, UniValue::VARR);
714-
return;
709+
return UniValue::VARR;
715710
}
716711
} // no default case, so the compiler can warn about missing cases
712+
NONFATAL_UNREACHABLE();
713+
}
714+
715+
UniValue RPCArg::MatchesType(const UniValue& request) const
716+
{
717+
if (m_opts.skip_type_check) return true;
718+
if (IsOptional() && request.isNull()) return true;
719+
const auto exp_type{ExpectedType(m_type)};
720+
if (!exp_type) return true; // nothing to check
721+
722+
if (*exp_type != request.getType()) {
723+
return strprintf("JSON value of type %s is not of expected type %s", uvTypeName(request.getType()), uvTypeName(*exp_type));
724+
}
725+
return true;
717726
}
718727

719728
std::string RPCArg::GetFirstName() const

src/rpc/util.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -231,8 +231,11 @@ struct RPCArg {
231231

232232
bool IsOptional() const;
233233

234-
/** Check whether the request JSON type matches. */
235-
void MatchesType(const UniValue& request) const;
234+
/**
235+
* Check whether the request JSON type matches.
236+
* Returns true if type matches, or object describing error(s) if not.
237+
*/
238+
UniValue MatchesType(const UniValue& request) const;
236239

237240
/** Return the first of all aliases */
238241
std::string GetFirstName() const;

src/wallet/rpc/wallet.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -635,7 +635,7 @@ static RPCHelpMan createwallet()
635635
{"passphrase", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, "Encrypt the wallet with this passphrase."},
636636
{"avoid_reuse", RPCArg::Type::BOOL, RPCArg::Default{false}, "Keep track of coin reuse, and treat dirty and clean coins differently with privacy considerations in mind."},
637637
{"descriptors", RPCArg::Type::BOOL, RPCArg::Default{true}, "Create a native descriptor wallet. The wallet will use descriptors internally to handle address creation."
638-
" Setting to \"false\" will create a legacy wallet; however, the legacy wallet type is being deprecated and"
638+
" Setting to \"false\" will create a legacy wallet; This is only possible with the -deprecatedrpc=create_bdb setting because, the legacy wallet type is being deprecated and"
639639
" support for creating and opening legacy wallets will be removed in the future."},
640640
{"load_on_startup", RPCArg::Type::BOOL, RPCArg::Optional::OMITTED_NAMED_ARG, "Save wallet name to persistent settings and load on startup. True to add wallet to startup list, false to remove, null to leave unchanged."},
641641
{"external_signer", RPCArg::Type::BOOL, RPCArg::Default{false}, "Use an external signer such as a hardware wallet. Requires -signer to be configured. Wallet creation will fail if keys cannot be fetched. Requires disable_private_keys and descriptors set to true."},
@@ -681,11 +681,16 @@ static RPCHelpMan createwallet()
681681
if (!request.params[5].isNull() && request.params[6].isNull()) {
682682
throw JSONRPCError(RPC_INVALID_PARAMETER, "The createwallet RPC requires specifying the 'load_on_startup' flag when param 'descriptors' is specified. Dash Core v21 introduced this requirement due to breaking changes in the createwallet RPC.");
683683
}
684-
if (request.params[5].isNull() || request.params[5].get_bool()) {
684+
if (self.Arg<bool>("descriptors")) {
685685
#ifndef USE_SQLITE
686686
throw JSONRPCError(RPC_WALLET_ERROR, "Compiled without sqlite support (required for descriptor wallets)");
687687
#endif
688688
flags |= WALLET_FLAG_DESCRIPTORS;
689+
} else {
690+
if (!context.chain->rpcEnableDeprecated("create_bdb")) {
691+
throw JSONRPCError(RPC_WALLET_ERROR, "BDB wallet creation is deprecated and will be removed in a future release."
692+
" In this release it can be re-enabled temporarily with the -deprecatedrpc=create_bdb setting.");
693+
}
689694
}
690695
if (!request.params[7].isNull() && request.params[7].get_bool()) {
691696
#ifdef ENABLE_EXTERNAL_SIGNER

test/functional/test_framework/util.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,7 @@ def write_config(config_path, *, n, chain, extra_config="", disable_autoconnect=
421421
f.write("shrinkdebugfile=0\n")
422422
# To reduce IO and consumed disk storage use tiny size for allocated blk and rev files
423423
f.write("tinyblk=1\n")
424+
f.write("deprecatedrpc=create_bdb\n") # Required to run the tests
424425
# To improve SQLite wallet performance so that the tests don't timeout, use -unsafesqlitesync
425426
f.write("unsafesqlitesync=1\n")
426427
if disable_autoconnect:

test/functional/wallet_createwallet.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ def run_test(self):
175175

176176
if self.is_bdb_compiled():
177177
self.log.info("Test legacy wallet deprecation")
178-
res = self.nodes[0].createwallet(wallet_name="legacy_w0", descriptors=False, load_on_startup=True)
178+
res = self.nodes[0].createwallet(wallet_name="legacy_w0", passphrase=None, descriptors=False, load_on_startup=True)
179179
assert_equal(res["warning"], "Wallet created successfully. The legacy wallet type is being deprecated and support for creating and opening legacy wallets will be removed in the future.")
180180

181181
if __name__ == '__main__':

0 commit comments

Comments
 (0)