Skip to content

Commit d9aa7b2

Browse files
committed
Merge bitcoin/bitcoin#26596: wallet: Migrate legacy wallets to descriptor wallets without requiring BDB
8ce3739 test: verify wallet is still active post-migration failure (furszy) 771bc60 wallet: Use LegacyDataSPKM when loading (Ava Chow) 61d872f wallet: Move MigrateToDescriptor and DeleteRecords to LegacyDataSPKM (Ava Chow) b231f4d wallet: Move LegacyScriptPubKeyMan::IsMine to LegacyDataSPKM (Ava Chow) 7461d0c wallet: Move LegacySPKM data storage and handling to LegacyDataSPKM (Ava Chow) 517e204 Change MigrateLegacyToDescriptor to reopen wallet as BERKELEY_RO (Ava Chow) Pull request description: #26606 introduced `BerkeleyRODatabase` which is an independent parser for BDB files. This PR uses this in legacy wallet migration so that migration will continue to work once the legacy wallet and BDB are removed. `LegacyDataSPKM` is introduced to have the minimum data and functions necessary for a legacy wallet to be loaded for migration. ACKs for top commit: cbergqvist: ACK 8ce3739 theStack: Code-review ACK 8ce3739 furszy: Code review ACK 8ce3739 Tree-SHA512: dccea12d6c597de15e3e42f97ab483cfd069e103611200279a177e021e8e9c4e74387c4f45d2e58b3a1e7e2bdb32a1d2d2060b1f8086c03eeaa0c68579d9d54e
2 parents 9b480f7 + 8ce3739 commit d9aa7b2

File tree

6 files changed

+221
-125
lines changed

6 files changed

+221
-125
lines changed

src/wallet/scriptpubkeyman.cpp

Lines changed: 48 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ bool PermitsUncompressed(IsMineSigVersion sigversion)
8484
return sigversion == IsMineSigVersion::TOP || sigversion == IsMineSigVersion::P2SH;
8585
}
8686

87-
bool HaveKeys(const std::vector<valtype>& pubkeys, const LegacyScriptPubKeyMan& keystore)
87+
bool HaveKeys(const std::vector<valtype>& pubkeys, const LegacyDataSPKM& keystore)
8888
{
8989
for (const valtype& pubkey : pubkeys) {
9090
CKeyID keyID = CPubKey(pubkey).GetID();
@@ -102,7 +102,7 @@ bool HaveKeys(const std::vector<valtype>& pubkeys, const LegacyScriptPubKeyMan&
102102
//! scripts or simply treat any script that has been
103103
//! stored in the keystore as spendable
104104
// NOLINTNEXTLINE(misc-no-recursion)
105-
IsMineResult IsMineInner(const LegacyScriptPubKeyMan& keystore, const CScript& scriptPubKey, IsMineSigVersion sigversion, bool recurse_scripthash=true)
105+
IsMineResult IsMineInner(const LegacyDataSPKM& keystore, const CScript& scriptPubKey, IsMineSigVersion sigversion, bool recurse_scripthash=true)
106106
{
107107
IsMineResult ret = IsMineResult::NO;
108108

@@ -217,7 +217,7 @@ IsMineResult IsMineInner(const LegacyScriptPubKeyMan& keystore, const CScript& s
217217

218218
} // namespace
219219

220-
isminetype LegacyScriptPubKeyMan::IsMine(const CScript& script) const
220+
isminetype LegacyDataSPKM::IsMine(const CScript& script) const
221221
{
222222
switch (IsMineInner(*this, script, IsMineSigVersion::TOP)) {
223223
case IsMineResult::INVALID:
@@ -231,7 +231,7 @@ isminetype LegacyScriptPubKeyMan::IsMine(const CScript& script) const
231231
assert(false);
232232
}
233233

234-
bool LegacyScriptPubKeyMan::CheckDecryptionKey(const CKeyingMaterial& master_key)
234+
bool LegacyDataSPKM::CheckDecryptionKey(const CKeyingMaterial& master_key)
235235
{
236236
{
237237
LOCK(cs_KeyStore);
@@ -585,7 +585,7 @@ int64_t LegacyScriptPubKeyMan::GetTimeFirstKey() const
585585
return nTimeFirstKey;
586586
}
587587

588-
std::unique_ptr<SigningProvider> LegacyScriptPubKeyMan::GetSolvingProvider(const CScript& script) const
588+
std::unique_ptr<SigningProvider> LegacyDataSPKM::GetSolvingProvider(const CScript& script) const
589589
{
590590
return std::make_unique<LegacySigningProvider>(*this);
591591
}
@@ -721,7 +721,7 @@ void LegacyScriptPubKeyMan::UpdateTimeFirstKey(int64_t nCreateTime)
721721
NotifyFirstKeyTimeChanged(this, nTimeFirstKey);
722722
}
723723

724-
bool LegacyScriptPubKeyMan::LoadKey(const CKey& key, const CPubKey &pubkey)
724+
bool LegacyDataSPKM::LoadKey(const CKey& key, const CPubKey &pubkey)
725725
{
726726
return AddKeyPubKeyInner(key, pubkey);
727727
}
@@ -773,7 +773,7 @@ bool LegacyScriptPubKeyMan::AddKeyPubKeyWithDB(WalletBatch& batch, const CKey& s
773773
return true;
774774
}
775775

776-
bool LegacyScriptPubKeyMan::LoadCScript(const CScript& redeemScript)
776+
bool LegacyDataSPKM::LoadCScript(const CScript& redeemScript)
777777
{
778778
/* A sanity check was added in pull #3843 to avoid adding redeemScripts
779779
* that never can be redeemed. However, old wallets may still contain
@@ -788,18 +788,36 @@ bool LegacyScriptPubKeyMan::LoadCScript(const CScript& redeemScript)
788788
return FillableSigningProvider::AddCScript(redeemScript);
789789
}
790790

791+
void LegacyDataSPKM::LoadKeyMetadata(const CKeyID& keyID, const CKeyMetadata& meta)
792+
{
793+
LOCK(cs_KeyStore);
794+
mapKeyMetadata[keyID] = meta;
795+
}
796+
791797
void LegacyScriptPubKeyMan::LoadKeyMetadata(const CKeyID& keyID, const CKeyMetadata& meta)
792798
{
793799
LOCK(cs_KeyStore);
800+
LegacyDataSPKM::LoadKeyMetadata(keyID, meta);
794801
UpdateTimeFirstKey(meta.nCreateTime);
795-
mapKeyMetadata[keyID] = meta;
802+
}
803+
804+
void LegacyDataSPKM::LoadScriptMetadata(const CScriptID& script_id, const CKeyMetadata& meta)
805+
{
806+
LOCK(cs_KeyStore);
807+
m_script_metadata[script_id] = meta;
796808
}
797809

798810
void LegacyScriptPubKeyMan::LoadScriptMetadata(const CScriptID& script_id, const CKeyMetadata& meta)
799811
{
800812
LOCK(cs_KeyStore);
813+
LegacyDataSPKM::LoadScriptMetadata(script_id, meta);
801814
UpdateTimeFirstKey(meta.nCreateTime);
802-
m_script_metadata[script_id] = meta;
815+
}
816+
817+
bool LegacyDataSPKM::AddKeyPubKeyInner(const CKey& key, const CPubKey& pubkey)
818+
{
819+
LOCK(cs_KeyStore);
820+
return FillableSigningProvider::AddKeyPubKey(key, pubkey);
803821
}
804822

805823
bool LegacyScriptPubKeyMan::AddKeyPubKeyInner(const CKey& key, const CPubKey &pubkey)
@@ -827,7 +845,7 @@ bool LegacyScriptPubKeyMan::AddKeyPubKeyInner(const CKey& key, const CPubKey &pu
827845
return true;
828846
}
829847

830-
bool LegacyScriptPubKeyMan::LoadCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret, bool checksum_valid)
848+
bool LegacyDataSPKM::LoadCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret, bool checksum_valid)
831849
{
832850
// Set fDecryptionThoroughlyChecked to false when the checksum is invalid
833851
if (!checksum_valid) {
@@ -837,7 +855,7 @@ bool LegacyScriptPubKeyMan::LoadCryptedKey(const CPubKey &vchPubKey, const std::
837855
return AddCryptedKeyInner(vchPubKey, vchCryptedSecret);
838856
}
839857

840-
bool LegacyScriptPubKeyMan::AddCryptedKeyInner(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret)
858+
bool LegacyDataSPKM::AddCryptedKeyInner(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret)
841859
{
842860
LOCK(cs_KeyStore);
843861
assert(mapKeys.empty());
@@ -865,13 +883,13 @@ bool LegacyScriptPubKeyMan::AddCryptedKey(const CPubKey &vchPubKey,
865883
}
866884
}
867885

868-
bool LegacyScriptPubKeyMan::HaveWatchOnly(const CScript &dest) const
886+
bool LegacyDataSPKM::HaveWatchOnly(const CScript &dest) const
869887
{
870888
LOCK(cs_KeyStore);
871889
return setWatchOnly.count(dest) > 0;
872890
}
873891

874-
bool LegacyScriptPubKeyMan::HaveWatchOnly() const
892+
bool LegacyDataSPKM::HaveWatchOnly() const
875893
{
876894
LOCK(cs_KeyStore);
877895
return (!setWatchOnly.empty());
@@ -905,12 +923,12 @@ bool LegacyScriptPubKeyMan::RemoveWatchOnly(const CScript &dest)
905923
return true;
906924
}
907925

908-
bool LegacyScriptPubKeyMan::LoadWatchOnly(const CScript &dest)
926+
bool LegacyDataSPKM::LoadWatchOnly(const CScript &dest)
909927
{
910928
return AddWatchOnlyInMem(dest);
911929
}
912930

913-
bool LegacyScriptPubKeyMan::AddWatchOnlyInMem(const CScript &dest)
931+
bool LegacyDataSPKM::AddWatchOnlyInMem(const CScript &dest)
914932
{
915933
LOCK(cs_KeyStore);
916934
setWatchOnly.insert(dest);
@@ -954,7 +972,7 @@ bool LegacyScriptPubKeyMan::AddWatchOnly(const CScript& dest, int64_t nCreateTim
954972
return AddWatchOnly(dest);
955973
}
956974

957-
void LegacyScriptPubKeyMan::LoadHDChain(const CHDChain& chain)
975+
void LegacyDataSPKM::LoadHDChain(const CHDChain& chain)
958976
{
959977
LOCK(cs_KeyStore);
960978
m_hd_chain = chain;
@@ -975,14 +993,14 @@ void LegacyScriptPubKeyMan::AddHDChain(const CHDChain& chain)
975993
m_hd_chain = chain;
976994
}
977995

978-
void LegacyScriptPubKeyMan::AddInactiveHDChain(const CHDChain& chain)
996+
void LegacyDataSPKM::AddInactiveHDChain(const CHDChain& chain)
979997
{
980998
LOCK(cs_KeyStore);
981999
assert(!chain.seed_id.IsNull());
9821000
m_inactive_hd_chains[chain.seed_id] = chain;
9831001
}
9841002

985-
bool LegacyScriptPubKeyMan::HaveKey(const CKeyID &address) const
1003+
bool LegacyDataSPKM::HaveKey(const CKeyID &address) const
9861004
{
9871005
LOCK(cs_KeyStore);
9881006
if (!m_storage.HasEncryptionKeys()) {
@@ -991,7 +1009,7 @@ bool LegacyScriptPubKeyMan::HaveKey(const CKeyID &address) const
9911009
return mapCryptedKeys.count(address) > 0;
9921010
}
9931011

994-
bool LegacyScriptPubKeyMan::GetKey(const CKeyID &address, CKey& keyOut) const
1012+
bool LegacyDataSPKM::GetKey(const CKeyID &address, CKey& keyOut) const
9951013
{
9961014
LOCK(cs_KeyStore);
9971015
if (!m_storage.HasEncryptionKeys()) {
@@ -1010,7 +1028,7 @@ bool LegacyScriptPubKeyMan::GetKey(const CKeyID &address, CKey& keyOut) const
10101028
return false;
10111029
}
10121030

1013-
bool LegacyScriptPubKeyMan::GetKeyOrigin(const CKeyID& keyID, KeyOriginInfo& info) const
1031+
bool LegacyDataSPKM::GetKeyOrigin(const CKeyID& keyID, KeyOriginInfo& info) const
10141032
{
10151033
CKeyMetadata meta;
10161034
{
@@ -1030,7 +1048,7 @@ bool LegacyScriptPubKeyMan::GetKeyOrigin(const CKeyID& keyID, KeyOriginInfo& inf
10301048
return true;
10311049
}
10321050

1033-
bool LegacyScriptPubKeyMan::GetWatchPubKey(const CKeyID &address, CPubKey &pubkey_out) const
1051+
bool LegacyDataSPKM::GetWatchPubKey(const CKeyID &address, CPubKey &pubkey_out) const
10341052
{
10351053
LOCK(cs_KeyStore);
10361054
WatchKeyMap::const_iterator it = mapWatchKeys.find(address);
@@ -1041,7 +1059,7 @@ bool LegacyScriptPubKeyMan::GetWatchPubKey(const CKeyID &address, CPubKey &pubke
10411059
return false;
10421060
}
10431061

1044-
bool LegacyScriptPubKeyMan::GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const
1062+
bool LegacyDataSPKM::GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const
10451063
{
10461064
LOCK(cs_KeyStore);
10471065
if (!m_storage.HasEncryptionKeys()) {
@@ -1160,7 +1178,7 @@ void LegacyScriptPubKeyMan::DeriveNewChildKey(WalletBatch &batch, CKeyMetadata&
11601178
throw std::runtime_error(std::string(__func__) + ": writing HD chain model failed");
11611179
}
11621180

1163-
void LegacyScriptPubKeyMan::LoadKeyPool(int64_t nIndex, const CKeyPool &keypool)
1181+
void LegacyDataSPKM::LoadKeyPool(int64_t nIndex, const CKeyPool &keypool)
11641182
{
11651183
LOCK(cs_KeyStore);
11661184
if (keypool.m_pre_split) {
@@ -1681,7 +1699,7 @@ std::set<CKeyID> LegacyScriptPubKeyMan::GetKeys() const
16811699
return set_address;
16821700
}
16831701

1684-
std::unordered_set<CScript, SaltedSipHasher> LegacyScriptPubKeyMan::GetScriptPubKeys() const
1702+
std::unordered_set<CScript, SaltedSipHasher> LegacyDataSPKM::GetScriptPubKeys() const
16851703
{
16861704
LOCK(cs_KeyStore);
16871705
std::unordered_set<CScript, SaltedSipHasher> spks;
@@ -1739,7 +1757,7 @@ std::unordered_set<CScript, SaltedSipHasher> LegacyScriptPubKeyMan::GetScriptPub
17391757
return spks;
17401758
}
17411759

1742-
std::unordered_set<CScript, SaltedSipHasher> LegacyScriptPubKeyMan::GetNotMineScriptPubKeys() const
1760+
std::unordered_set<CScript, SaltedSipHasher> LegacyDataSPKM::GetNotMineScriptPubKeys() const
17431761
{
17441762
LOCK(cs_KeyStore);
17451763
std::unordered_set<CScript, SaltedSipHasher> spks;
@@ -1749,7 +1767,7 @@ std::unordered_set<CScript, SaltedSipHasher> LegacyScriptPubKeyMan::GetNotMineSc
17491767
return spks;
17501768
}
17511769

1752-
std::optional<MigrationData> LegacyScriptPubKeyMan::MigrateToDescriptor()
1770+
std::optional<MigrationData> LegacyDataSPKM::MigrateToDescriptor()
17531771
{
17541772
LOCK(cs_KeyStore);
17551773
if (m_storage.IsLocked()) {
@@ -1816,7 +1834,7 @@ std::optional<MigrationData> LegacyScriptPubKeyMan::MigrateToDescriptor()
18161834
WalletDescriptor w_desc(std::move(desc), creation_time, 0, 0, 0);
18171835

18181836
// Make the DescriptorScriptPubKeyMan and get the scriptPubKeys
1819-
auto desc_spk_man = std::unique_ptr<DescriptorScriptPubKeyMan>(new DescriptorScriptPubKeyMan(m_storage, w_desc, m_keypool_size));
1837+
auto desc_spk_man = std::make_unique<DescriptorScriptPubKeyMan>(m_storage, w_desc, /*keypool_size=*/0);
18201838
desc_spk_man->AddDescriptorKey(key, key.GetPubKey());
18211839
desc_spk_man->TopUp();
18221840
auto desc_spks = desc_spk_man->GetScriptPubKeys();
@@ -1861,7 +1879,7 @@ std::optional<MigrationData> LegacyScriptPubKeyMan::MigrateToDescriptor()
18611879
WalletDescriptor w_desc(std::move(desc), 0, 0, chain_counter, 0);
18621880

18631881
// Make the DescriptorScriptPubKeyMan and get the scriptPubKeys
1864-
auto desc_spk_man = std::unique_ptr<DescriptorScriptPubKeyMan>(new DescriptorScriptPubKeyMan(m_storage, w_desc, m_keypool_size));
1882+
auto desc_spk_man = std::make_unique<DescriptorScriptPubKeyMan>(m_storage, w_desc, /*keypool_size=*/0);
18651883
desc_spk_man->AddDescriptorKey(master_key.key, master_key.key.GetPubKey());
18661884
desc_spk_man->TopUp();
18671885
auto desc_spks = desc_spk_man->GetScriptPubKeys();
@@ -1923,7 +1941,7 @@ std::optional<MigrationData> LegacyScriptPubKeyMan::MigrateToDescriptor()
19231941
} else {
19241942
// Make the DescriptorScriptPubKeyMan and get the scriptPubKeys
19251943
WalletDescriptor w_desc(std::move(desc), creation_time, 0, 0, 0);
1926-
auto desc_spk_man = std::unique_ptr<DescriptorScriptPubKeyMan>(new DescriptorScriptPubKeyMan(m_storage, w_desc, m_keypool_size));
1944+
auto desc_spk_man = std::make_unique<DescriptorScriptPubKeyMan>(m_storage, w_desc, /*keypool_size=*/0);
19271945
for (const auto& keyid : privkeyids) {
19281946
CKey key;
19291947
if (!GetKey(keyid, key)) {
@@ -2001,7 +2019,7 @@ std::optional<MigrationData> LegacyScriptPubKeyMan::MigrateToDescriptor()
20012019
return out;
20022020
}
20032021

2004-
bool LegacyScriptPubKeyMan::DeleteRecords()
2022+
bool LegacyDataSPKM::DeleteRecords()
20052023
{
20062024
LOCK(cs_KeyStore);
20072025
WalletBatch batch(m_storage.GetDatabase());

0 commit comments

Comments
 (0)