diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -3183,10 +3183,10 @@ std::string error; std::string warning; - WalletCreationStatus status; - std::shared_ptr wallet = + std::shared_ptr wallet; + WalletCreationStatus status = CreateWallet(config.GetChainParams(), *g_rpc_chain, passphrase, flags, - request.params[0].get_str(), error, warning, status); + request.params[0].get_str(), error, warning, wallet); if (status == WalletCreationStatus::CREATION_FAILED) { throw JSONRPCError(RPC_WALLET_ERROR, error); } else if (status == WalletCreationStatus::ENCRYPTION_FAILED) { diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -57,11 +57,11 @@ enum class WalletCreationStatus { SUCCESS, CREATION_FAILED, ENCRYPTION_FAILED }; -std::shared_ptr +WalletCreationStatus CreateWallet(const CChainParams ¶ms, interfaces::Chain &chain, const SecureString &passphrase, uint64_t wallet_creation_flags, const std::string &name, std::string &error, std::string &warning, - WalletCreationStatus &status); + std::shared_ptr &result); //! Default for -keypool static const unsigned int DEFAULT_KEYPOOL_SIZE = 1000; diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -166,11 +166,11 @@ return LoadWallet(chainParams, chain, WalletLocation(name), error, warning); } -std::shared_ptr +WalletCreationStatus CreateWallet(const CChainParams ¶ms, interfaces::Chain &chain, const SecureString &passphrase, uint64_t wallet_creation_flags, const std::string &name, std::string &error, std::string &warning, - WalletCreationStatus &status) { + std::shared_ptr &result) { // Indicate that the wallet is actually supposed to be blank and not just // blank to make it encrypted bool create_blank = (wallet_creation_flags & WALLET_FLAG_BLANK_WALLET); @@ -184,8 +184,7 @@ WalletLocation location(name); if (location.Exists()) { error = "Wallet " + location.GetName() + " already exists."; - status = WalletCreationStatus::CREATION_FAILED; - return nullptr; + return WalletCreationStatus::CREATION_FAILED; } // Wallet::Verify will check if we're trying to create a wallet with a @@ -194,8 +193,16 @@ if (!CWallet::Verify(params, chain, location, false, wallet_error, warning)) { error = "Wallet file verification failed: " + wallet_error; - status = WalletCreationStatus::CREATION_FAILED; - return nullptr; + return WalletCreationStatus::CREATION_FAILED; + } + + // Do not allow a passphrase when private keys are disabled + if (!passphrase.empty() && + (wallet_creation_flags & WALLET_FLAG_DISABLE_PRIVATE_KEYS)) { + error = "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."; + return WalletCreationStatus::CREATION_FAILED; } // Make the wallet @@ -203,8 +210,7 @@ params, chain, location, wallet_creation_flags); if (!wallet) { error = "Wallet creation failed"; - status = WalletCreationStatus::CREATION_FAILED; - return nullptr; + return WalletCreationStatus::CREATION_FAILED; } // Encrypt the wallet @@ -212,15 +218,13 @@ !(wallet_creation_flags & WALLET_FLAG_DISABLE_PRIVATE_KEYS)) { if (!wallet->EncryptWallet(passphrase)) { error = "Error: Wallet created but failed to encrypt."; - status = WalletCreationStatus::ENCRYPTION_FAILED; - return nullptr; + return WalletCreationStatus::ENCRYPTION_FAILED; } if (!create_blank) { // Unlock the wallet if (!wallet->Unlock(passphrase)) { error = "Error: Wallet was encrypted but could not be unlocked"; - status = WalletCreationStatus::ENCRYPTION_FAILED; - return nullptr; + return WalletCreationStatus::ENCRYPTION_FAILED; } // Set a seed for the wallet @@ -234,8 +238,8 @@ } AddWallet(wallet); wallet->postInitProcess(); - status = WalletCreationStatus::SUCCESS; - return wallet; + result = wallet; + return WalletCreationStatus::SUCCESS; } const uint32_t BIP32_HARDENED_KEY_LIMIT = 0x80000000; 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 @@ -174,6 +174,16 @@ False, '') + self.log.info( + 'Using a passphrase with private keys disabled returns error') + assert_raises_rpc_error( + -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', + disable_private_keys=True, + passphrase='thisisapassphrase') + if __name__ == '__main__': CreateWalletTest().main()