aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/dummywallet.cpp1
-rw-r--r--src/wallet/scriptpubkeyman.cpp13
-rw-r--r--src/wallet/scriptpubkeyman.h6
-rw-r--r--src/wallet/wallet.cpp44
-rw-r--r--src/wallet/wallet.h16
-rw-r--r--src/wallet/walletutil.cpp18
-rw-r--r--src/wallet/walletutil.h3
7 files changed, 49 insertions, 52 deletions
diff --git a/src/dummywallet.cpp b/src/dummywallet.cpp
index 8d2dcd0279..4543f098a1 100644
--- a/src/dummywallet.cpp
+++ b/src/dummywallet.cpp
@@ -40,7 +40,6 @@ void DummyWalletInit::AddWalletOptions(ArgsManager& argsman) const
"-salvagewallet",
"-spendzeroconfchange",
"-txconfirmtarget=<n>",
- "-upgradewallet",
"-wallet=<path>",
"-walletbroadcast",
"-walletdir=<dir>",
diff --git a/src/wallet/scriptpubkeyman.cpp b/src/wallet/scriptpubkeyman.cpp
index 188289b010..d2e1be6402 100644
--- a/src/wallet/scriptpubkeyman.cpp
+++ b/src/wallet/scriptpubkeyman.cpp
@@ -438,12 +438,12 @@ bool LegacyScriptPubKeyMan::CanGetAddresses(bool internal) const
return keypool_has_keys;
}
-bool LegacyScriptPubKeyMan::Upgrade(int prev_version, bilingual_str& error)
+bool LegacyScriptPubKeyMan::Upgrade(int prev_version, int new_version, bilingual_str& error)
{
LOCK(cs_KeyStore);
bool hd_upgrade = false;
bool split_upgrade = false;
- if (m_storage.CanSupportFeature(FEATURE_HD) && !IsHDEnabled()) {
+ if (IsFeatureSupported(new_version, FEATURE_HD) && !IsHDEnabled()) {
WalletLogPrintf("Upgrading wallet to HD\n");
m_storage.SetMinVersion(FEATURE_HD);
@@ -453,10 +453,17 @@ bool LegacyScriptPubKeyMan::Upgrade(int prev_version, bilingual_str& error)
hd_upgrade = true;
}
// Upgrade to HD chain split if necessary
- if (m_storage.CanSupportFeature(FEATURE_HD_SPLIT)) {
+ if (IsFeatureSupported(new_version, FEATURE_HD_SPLIT)) {
WalletLogPrintf("Upgrading wallet to use HD chain split\n");
m_storage.SetMinVersion(FEATURE_PRE_SPLIT_KEYPOOL);
split_upgrade = FEATURE_HD_SPLIT > prev_version;
+ // Upgrade the HDChain
+ if (m_hd_chain.nVersion < CHDChain::VERSION_HD_CHAIN_SPLIT) {
+ m_hd_chain.nVersion = CHDChain::VERSION_HD_CHAIN_SPLIT;
+ if (!WalletBatch(m_storage.GetDatabase()).WriteHDChain(m_hd_chain)) {
+ throw std::runtime_error(std::string(__func__) + ": writing chain failed");
+ }
+ }
}
// Mark all keys currently in the keypool as pre-split
if (split_upgrade) {
diff --git a/src/wallet/scriptpubkeyman.h b/src/wallet/scriptpubkeyman.h
index 63c10b7a0d..3bf8f78120 100644
--- a/src/wallet/scriptpubkeyman.h
+++ b/src/wallet/scriptpubkeyman.h
@@ -37,7 +37,7 @@ public:
virtual bool IsWalletFlagSet(uint64_t) const = 0;
virtual void UnsetBlankWalletFlag(WalletBatch&) = 0;
virtual bool CanSupportFeature(enum WalletFeature) const = 0;
- virtual void SetMinVersion(enum WalletFeature, WalletBatch* = nullptr, bool = false) = 0;
+ virtual void SetMinVersion(enum WalletFeature, WalletBatch* = nullptr) = 0;
virtual const CKeyingMaterial& GetEncryptionKey() const = 0;
virtual bool HasEncryptionKeys() const = 0;
virtual bool IsLocked() const = 0;
@@ -206,7 +206,7 @@ public:
virtual bool CanGetAddresses(bool internal = false) const { return false; }
/** Upgrades the wallet to the specified version */
- virtual bool Upgrade(int prev_version, bilingual_str& error) { return false; }
+ virtual bool Upgrade(int prev_version, int new_version, bilingual_str& error) { return false; }
virtual bool HavePrivateKeys() const { return false; }
@@ -371,7 +371,7 @@ public:
bool SetupGeneration(bool force = false) override;
- bool Upgrade(int prev_version, bilingual_str& error) override;
+ bool Upgrade(int prev_version, int new_version, bilingual_str& error) override;
bool HavePrivateKeys() const override;
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index e1f34fbcf9..d414555511 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -436,21 +436,13 @@ void CWallet::chainStateFlushed(const CBlockLocator& loc)
batch.WriteBestBlock(loc);
}
-void CWallet::SetMinVersion(enum WalletFeature nVersion, WalletBatch* batch_in, bool fExplicit)
+void CWallet::SetMinVersion(enum WalletFeature nVersion, WalletBatch* batch_in)
{
LOCK(cs_wallet);
if (nWalletVersion >= nVersion)
return;
-
- // when doing an explicit upgrade, if we pass the max version permitted, upgrade all the way
- if (fExplicit && nVersion > nWalletMaxVersion)
- nVersion = FEATURE_LATEST;
-
nWalletVersion = nVersion;
- if (nVersion > nWalletMaxVersion)
- nWalletMaxVersion = nVersion;
-
{
WalletBatch* batch = batch_in ? batch_in : new WalletBatch(*database);
if (nWalletVersion > 40000)
@@ -460,18 +452,6 @@ void CWallet::SetMinVersion(enum WalletFeature nVersion, WalletBatch* batch_in,
}
}
-bool CWallet::SetMaxVersion(int nVersion)
-{
- LOCK(cs_wallet);
- // cannot downgrade below current version
- if (nWalletVersion > nVersion)
- return false;
-
- nWalletMaxVersion = nVersion;
-
- return true;
-}
-
std::set<uint256> CWallet::GetConflicts(const uint256& txid) const
{
std::set<uint256> result;
@@ -656,7 +636,7 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
}
// Encryption was introduced in version 0.4.0
- SetMinVersion(FEATURE_WALLETCRYPT, encrypted_batch, true);
+ SetMinVersion(FEATURE_WALLETCRYPT, encrypted_batch);
if (!encrypted_batch->TxnCommit()) {
delete encrypted_batch;
@@ -4125,33 +4105,31 @@ const CAddressBookData* CWallet::FindAddressBookEntry(const CTxDestination& dest
bool CWallet::UpgradeWallet(int version, bilingual_str& error, std::vector<bilingual_str>& warnings)
{
int prev_version = GetVersion();
- int nMaxVersion = version;
- if (nMaxVersion == 0) // the -upgradewallet without argument case
- {
+ if (version == 0) {
WalletLogPrintf("Performing wallet upgrade to %i\n", FEATURE_LATEST);
- nMaxVersion = FEATURE_LATEST;
- SetMinVersion(FEATURE_LATEST); // permanently upgrade the wallet immediately
+ version = FEATURE_LATEST;
} else {
- WalletLogPrintf("Allowing wallet upgrade up to %i\n", nMaxVersion);
+ WalletLogPrintf("Allowing wallet upgrade up to %i\n", version);
}
- if (nMaxVersion < GetVersion())
+ if (version < prev_version)
{
error = _("Cannot downgrade wallet");
return false;
}
- SetMaxVersion(nMaxVersion);
LOCK(cs_wallet);
// Do not upgrade versions to any version between HD_SPLIT and FEATURE_PRE_SPLIT_KEYPOOL unless already supporting HD_SPLIT
- int max_version = GetVersion();
- if (!CanSupportFeature(FEATURE_HD_SPLIT) && max_version >= FEATURE_HD_SPLIT && max_version < FEATURE_PRE_SPLIT_KEYPOOL) {
+ if (!CanSupportFeature(FEATURE_HD_SPLIT) && version >= FEATURE_HD_SPLIT && version < FEATURE_PRE_SPLIT_KEYPOOL) {
error = _("Cannot upgrade a non HD split wallet without upgrading to support pre split keypool. Please use version 169900 or no version specified.");
return false;
}
+ // Permanently upgrade to the version
+ SetMinVersion(GetClosestWalletFeature(version));
+
for (auto spk_man : GetActiveScriptPubKeyMans()) {
- if (!spk_man->Upgrade(prev_version, error)) {
+ if (!spk_man->Upgrade(prev_version, version, error)) {
return false;
}
}
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
index 00e0e3c84d..0934213fc7 100644
--- a/src/wallet/wallet.h
+++ b/src/wallet/wallet.h
@@ -636,9 +636,6 @@ private:
//! the current wallet version: clients below this version are not able to load the wallet
int nWalletVersion GUARDED_BY(cs_wallet){FEATURE_BASE};
- //! the maximum wallet format version: memory-only variable that specifies to what version this wallet may be upgraded
- int nWalletMaxVersion GUARDED_BY(cs_wallet) = FEATURE_BASE;
-
int64_t nNextResend = 0;
bool fBroadcastTransactions = false;
// Local time that the tip block was received. Used to schedule wallet rebroadcasts.
@@ -800,8 +797,8 @@ public:
const CWalletTx* GetWalletTx(const uint256& hash) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
bool IsTrusted(const CWalletTx& wtx, std::set<uint256>& trusted_parents) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
- //! check whether we are allowed to upgrade (or already support) to the named feature
- bool CanSupportFeature(enum WalletFeature wf) const override EXCLUSIVE_LOCKS_REQUIRED(cs_wallet) { AssertLockHeld(cs_wallet); return nWalletMaxVersion >= wf; }
+ //! check whether we support the named feature
+ bool CanSupportFeature(enum WalletFeature wf) const override EXCLUSIVE_LOCKS_REQUIRED(cs_wallet) { AssertLockHeld(cs_wallet); return IsFeatureSupported(nWalletVersion, wf); }
/**
* populate vCoins with vector of available COutputs.
@@ -853,7 +850,7 @@ public:
//! Upgrade stored CKeyMetadata objects to store key origin info as KeyOriginInfo
void UpgradeKeyMetadata() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
- bool LoadMinVersion(int nVersion) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet) { AssertLockHeld(cs_wallet); nWalletVersion = nVersion; nWalletMaxVersion = std::max(nWalletMaxVersion, nVersion); return true; }
+ bool LoadMinVersion(int nVersion) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet) { AssertLockHeld(cs_wallet); nWalletVersion = nVersion; return true; }
/**
* Adds a destination data tuple to the store, and saves it to disk
@@ -1076,11 +1073,8 @@ public:
unsigned int GetKeyPoolSize() const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
- //! signify that a particular wallet feature is now used. this may change nWalletVersion and nWalletMaxVersion if those are lower
- void SetMinVersion(enum WalletFeature, WalletBatch* batch_in = nullptr, bool fExplicit = false) override;
-
- //! change which version we're allowed to upgrade to (note that this does not immediately imply upgrading to that format)
- bool SetMaxVersion(int nVersion);
+ //! signify that a particular wallet feature is now used.
+ void SetMinVersion(enum WalletFeature, WalletBatch* batch_in = nullptr) override;
//! get the current wallet format (the oldest client version guaranteed to understand this wallet)
int GetVersion() const { LOCK(cs_wallet); return nWalletVersion; }
diff --git a/src/wallet/walletutil.cpp b/src/wallet/walletutil.cpp
index 6563c45134..702293e6c7 100644
--- a/src/wallet/walletutil.cpp
+++ b/src/wallet/walletutil.cpp
@@ -79,3 +79,21 @@ std::vector<fs::path> ListWalletDir()
return paths;
}
+
+bool IsFeatureSupported(int wallet_version, int feature_version)
+{
+ return wallet_version >= feature_version;
+}
+
+WalletFeature GetClosestWalletFeature(int version)
+{
+ if (version >= FEATURE_LATEST) return FEATURE_LATEST;
+ if (version >= FEATURE_PRE_SPLIT_KEYPOOL) return FEATURE_PRE_SPLIT_KEYPOOL;
+ if (version >= FEATURE_NO_DEFAULT_KEY) return FEATURE_NO_DEFAULT_KEY;
+ if (version >= FEATURE_HD_SPLIT) return FEATURE_HD_SPLIT;
+ if (version >= FEATURE_HD) return FEATURE_HD;
+ if (version >= FEATURE_COMPRPUBKEY) return FEATURE_COMPRPUBKEY;
+ if (version >= FEATURE_WALLETCRYPT) return FEATURE_WALLETCRYPT;
+ if (version >= FEATURE_BASE) return FEATURE_BASE;
+ return static_cast<WalletFeature>(0);
+}
diff --git a/src/wallet/walletutil.h b/src/wallet/walletutil.h
index afdcb2e18a..27521abd81 100644
--- a/src/wallet/walletutil.h
+++ b/src/wallet/walletutil.h
@@ -29,7 +29,8 @@ enum WalletFeature
FEATURE_LATEST = FEATURE_PRE_SPLIT_KEYPOOL
};
-
+bool IsFeatureSupported(int wallet_version, int feature_version);
+WalletFeature GetClosestWalletFeature(int version);
enum WalletFlags : uint64_t {
// wallet flags in the upper section (> 1 << 31) will lead to not opening the wallet if flag is unknown