aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Chow <achow101-github@achow101.com>2019-05-24 17:13:13 -0400
committerAndrew Chow <achow101-github@achow101.com>2019-07-09 19:50:16 -0400
commit1aecdf2063cbe28d4715ae5ae1a7e51b860c9f4d (patch)
tree80c6305c3d76181614f9501cf2409b08336e3c23 /src
parent357488f660a570dc97d969ae92e026854d167142 (diff)
downloadbitcoin-1aecdf2063cbe28d4715ae5ae1a7e51b860c9f4d.tar.xz
Move wallet creation out of the createwallet rpc into its own function
Diffstat (limited to 'src')
-rw-r--r--src/wallet/rpcwallet.cpp56
-rw-r--r--src/wallet/wallet.cpp64
-rw-r--r--src/wallet/wallet.h8
3 files changed, 82 insertions, 46 deletions
diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp
index 3be814bf77..723614e3bc 100644
--- a/src/wallet/rpcwallet.cpp
+++ b/src/wallet/rpcwallet.cpp
@@ -2677,17 +2677,12 @@ static UniValue createwallet(const JSONRPCRequest& request)
},
}.Check(request);
- std::string error;
- std::string warning;
-
uint64_t flags = 0;
if (!request.params[1].isNull() && request.params[1].get_bool()) {
flags |= WALLET_FLAG_DISABLE_PRIVATE_KEYS;
}
- bool create_blank = false; // Indicate that the wallet is actually supposed to be blank and not just blank to make it encrypted
if (!request.params[2].isNull() && request.params[2].get_bool()) {
- create_blank = true;
flags |= WALLET_FLAG_BLANK_WALLET;
}
SecureString passphrase;
@@ -2698,55 +2693,24 @@ static UniValue createwallet(const JSONRPCRequest& request)
// Empty string is invalid
throw JSONRPCError(RPC_WALLET_ENCRYPTION_FAILED, "Cannot encrypt a wallet with a blank password");
}
- // Born encrypted wallets need to be blank first so that wallet creation doesn't make any unencrypted keys
- flags |= WALLET_FLAG_BLANK_WALLET;
}
if (!request.params[4].isNull() && request.params[4].get_bool()) {
flags |= WALLET_FLAG_AVOID_REUSE;
}
- WalletLocation location(request.params[0].get_str());
- if (location.Exists()) {
- throw JSONRPCError(RPC_WALLET_ERROR, "Wallet " + location.GetName() + " already exists.");
- }
-
- // Wallet::Verify will check if we're trying to create a wallet with a duplication name.
- if (!CWallet::Verify(*g_rpc_interfaces->chain, location, false, error, warning)) {
- throw JSONRPCError(RPC_WALLET_ERROR, "Wallet file verification failed: " + error);
- }
-
- std::shared_ptr<CWallet> const wallet = CWallet::CreateWalletFromFile(*g_rpc_interfaces->chain, location, flags);
- if (!wallet) {
- throw JSONRPCError(RPC_WALLET_ERROR, "Wallet creation failed.");
- }
-
- // Encrypt the wallet if there's a passphrase
- if (!passphrase.empty() && !(flags & WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {
- if (!wallet->EncryptWallet(passphrase)) {
- throw JSONRPCError(RPC_WALLET_ENCRYPTION_FAILED, "Error: Wallet created but failed to encrypt.");
- }
-
- if (!create_blank) {
- // Unlock the wallet
- if (!wallet->Unlock(passphrase)) {
- throw JSONRPCError(RPC_WALLET_ENCRYPTION_FAILED, "Error: Wallet was encrypted but could not be unlocked");
- }
-
- // Set a seed for the wallet
- CPubKey master_pub_key = wallet->GenerateNewSeed();
- wallet->SetHDSeed(master_pub_key);
- wallet->NewKeyPool();
-
- // Relock the wallet
- wallet->Lock();
- }
+ std::string error;
+ std::string warning;
+ WalletCreationStatus status;
+ std::shared_ptr<CWallet> wallet = CreateWallet(*g_rpc_interfaces->chain, request.params[0].get_str(), error, warning, status, passphrase, flags);
+ if (status == WalletCreationStatus::CREATION_FAILED) {
+ throw JSONRPCError(RPC_WALLET_ERROR, error);
+ } else if (status == WalletCreationStatus::ENCRYPTION_FAILED) {
+ throw JSONRPCError(RPC_WALLET_ENCRYPTION_FAILED, error);
+ } else if (status != WalletCreationStatus::SUCCESS) {
+ throw JSONRPCError(RPC_WALLET_ERROR, "Wallet creation failed");
}
- AddWallet(wallet);
-
- wallet->postInitProcess();
-
UniValue obj(UniValue::VOBJ);
obj.pushKV("name", wallet->GetName());
obj.pushKV("warning", warning);
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index 7f14a4a7c3..e444e4fbb1 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -160,6 +160,70 @@ std::shared_ptr<CWallet> LoadWallet(interfaces::Chain& chain, const std::string&
return LoadWallet(chain, WalletLocation(name), error, warning);
}
+std::shared_ptr<CWallet> CreateWallet(interfaces::Chain& chain, const std::string& name, std::string& error, std::string& warning, WalletCreationStatus& status, const SecureString& passphrase, uint64_t wallet_creation_flags)
+{
+ // 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);
+
+ // Born encrypted wallets need to be created blank first.
+ if (!passphrase.empty()) {
+ wallet_creation_flags |= WALLET_FLAG_BLANK_WALLET;
+ }
+
+ // Check the wallet file location
+ WalletLocation location(name);
+ if (location.Exists()) {
+ error = "Wallet " + location.GetName() + " already exists.";
+ status = WalletCreationStatus::CREATION_FAILED;
+ return nullptr;
+ }
+
+ // Wallet::Verify will check if we're trying to create a wallet with a duplicate name.
+ std::string wallet_error;
+ if (!CWallet::Verify(chain, location, false, wallet_error, warning)) {
+ error = "Wallet file verification failed: " + wallet_error;
+ status = WalletCreationStatus::CREATION_FAILED;
+ return nullptr;
+ }
+
+ // Make the wallet
+ std::shared_ptr<CWallet> wallet = CWallet::CreateWalletFromFile(chain, location, wallet_creation_flags);
+ if (!wallet) {
+ error = "Wallet creation failed";
+ status = WalletCreationStatus::CREATION_FAILED;
+ return nullptr;
+ }
+
+ // Encrypt the wallet
+ if (!passphrase.empty() && !(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;
+ }
+ 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;
+ }
+
+ // Set a seed for the wallet
+ CPubKey master_pub_key = wallet->GenerateNewSeed();
+ wallet->SetHDSeed(master_pub_key);
+ wallet->NewKeyPool();
+
+ // Relock the wallet
+ wallet->Lock();
+ }
+ }
+ AddWallet(wallet);
+ wallet->postInitProcess();
+ status = WalletCreationStatus::SUCCESS;
+ return wallet;
+}
+
const uint32_t BIP32_HARDENED_KEY_LIMIT = 0x80000000;
const uint256 CMerkleTx::ABANDON_HASH(uint256S("0000000000000000000000000000000000000000000000000000000000000001"));
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
index 7b5465c219..b4357fb2ef 100644
--- a/src/wallet/wallet.h
+++ b/src/wallet/wallet.h
@@ -49,6 +49,14 @@ std::vector<std::shared_ptr<CWallet>> GetWallets();
std::shared_ptr<CWallet> GetWallet(const std::string& name);
std::shared_ptr<CWallet> LoadWallet(interfaces::Chain& chain, const WalletLocation& location, std::string& error, std::string& warning);
+enum WalletCreationStatus {
+ SUCCESS,
+ CREATION_FAILED,
+ ENCRYPTION_FAILED
+};
+
+std::shared_ptr<CWallet> CreateWallet(interfaces::Chain& chain, const std::string& name, std::string& error, std::string& warning, WalletCreationStatus& status, const SecureString& passphrase, uint64_t wallet_creation_flags);
+
//! Default for -keypool
static const unsigned int DEFAULT_KEYPOOL_SIZE = 1000;
//! -paytxfee default