diff --git a/doc/release-notes.md b/doc/release-notes.md --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -4,6 +4,11 @@ This release includes the following features and fixes: +RPC changes +----------- +`createwallet` now returns a warning if an empty string is used as an encryption password, and does not encrypt the wallet, instead of raising an error. +This makes it easier to disable encryption but also specify other options when using the `bitcoin-cli` tool. + Low-level changes ================= @@ -11,3 +16,4 @@ --- - `-fallbackfee` was 0 (disabled) by default for the main chain, but 20000 by default for the test chains. Now it is 0 by default for all chains. Testnet and regtest users will have to add fallbackfee=20000 to their configuration if they weren't setting it and they want it to keep working like before. (#16524) + diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -3168,12 +3168,13 @@ SecureString passphrase; passphrase.reserve(100); + std::string warning; if (!request.params[3].isNull()) { passphrase = request.params[3].get_str().c_str(); if (passphrase.empty()) { - // Empty string is invalid - throw JSONRPCError(RPC_WALLET_ENCRYPTION_FAILED, - "Cannot encrypt a wallet with a blank password"); + // Empty string means unencrypted + warning = "Empty string given as passphrase, wallet will not be " + "encrypted."; } } @@ -3182,11 +3183,11 @@ } std::string error; - std::string warning; + std::string create_warning; std::shared_ptr wallet; - WalletCreationStatus status = - CreateWallet(config.GetChainParams(), *g_rpc_chain, passphrase, flags, - request.params[0].get_str(), error, warning, wallet); + WalletCreationStatus status = CreateWallet( + config.GetChainParams(), *g_rpc_chain, passphrase, flags, + request.params[0].get_str(), error, create_warning, wallet); switch (status) { case WalletCreationStatus::CREATION_FAILED: throw JSONRPCError(RPC_WALLET_ERROR, error); @@ -3197,6 +3198,12 @@ // no default case, so the compiler can warn about missing cases } + if (warning.empty()) { + warning = create_warning; + } else if (!warning.empty() && !create_warning.empty()) { + warning += "; " + create_warning; + } + UniValue obj(UniValue::VOBJ); obj.pushKV("name", wallet->GetName()); obj.pushKV("warning", warning); diff --git a/test/functional/wallet_createwallet.py b/test/functional/wallet_createwallet.py --- a/test/functional/wallet_createwallet.py +++ b/test/functional/wallet_createwallet.py @@ -165,14 +165,35 @@ walletinfo = w6.getwalletinfo() assert_equal(walletinfo['keypoolsize'], 1) assert_equal(walletinfo['keypoolsize_hd_internal'], 1) - # Empty passphrase, error - assert_raises_rpc_error(-16, - 'Cannot encrypt a wallet with a blank password', - self.nodes[0].createwallet, - 'w7', - False, - False, - '') + # Allow empty passphrase, but there should be a warning + resp = self.nodes[0].createwallet( + wallet_name='w7', + disable_private_keys=False, + blank=False, + passphrase='') + assert_equal( + resp['warning'], + 'Empty string given as passphrase, wallet will not be encrypted.') + w7 = node.get_wallet_rpc('w7') + assert_raises_rpc_error( + -15, + 'Error: running with an unencrypted wallet, but walletpassphrase was called.', + w7.walletpassphrase, + '', + 10) + + self.log.info('Test making a wallet with avoid reuse flag') + # Use positional arguments to check for bug where avoid_reuse could not + # be set for wallets without needing them to be encrypted + self.nodes[0].createwallet('w8', False, False, '', True) + w8 = node.get_wallet_rpc('w8') + assert_raises_rpc_error( + -15, + 'Error: running with an unencrypted wallet, but walletpassphrase was called.', + w7.walletpassphrase, + '', + 10) + assert_equal(w8.getwalletinfo()["avoid_reuse"], True) self.log.info( 'Using a passphrase with private keys disabled returns error') @@ -180,7 +201,7 @@ -4, 'Passphrase provided but private keys are disabled. A passphrase is only used to encrypt private keys, so cannot be used for wallets with private keys disabled.', self.nodes[0].createwallet, - wallet_name='w8', + wallet_name='w9', disable_private_keys=True, passphrase='thisisapassphrase')