diff --git a/doc/release-notes.md b/doc/release-notes.md
--- a/doc/release-notes.md
+++ b/doc/release-notes.md
@@ -3,3 +3,8 @@
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.
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')