mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-01-19 14:53:43 +01:00
Merge bitcoin/bitcoin#26596: wallet: Migrate legacy wallets to descriptor wallets without requiring BDB
8ce3739edbtest: verify wallet is still active post-migration failure (furszy)771bc60f13wallet: Use LegacyDataSPKM when loading (Ava Chow)61d872f1b3wallet: Move MigrateToDescriptor and DeleteRecords to LegacyDataSPKM (Ava Chow)b231f4d556wallet: Move LegacyScriptPubKeyMan::IsMine to LegacyDataSPKM (Ava Chow)7461d0c006wallet: Move LegacySPKM data storage and handling to LegacyDataSPKM (Ava Chow)517e204bacChange 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: ACK8ce3739edbtheStack: Code-review ACK8ce3739edbfurszy: Code review ACK8ce3739edbTree-SHA512: dccea12d6c597de15e3e42f97ab483cfd069e103611200279a177e021e8e9c4e74387c4f45d2e58b3a1e7e2bdb32a1d2d2060b1f8086c03eeaa0c68579d9d54e
This commit is contained in:
@@ -84,7 +84,7 @@ bool PermitsUncompressed(IsMineSigVersion sigversion)
|
||||
return sigversion == IsMineSigVersion::TOP || sigversion == IsMineSigVersion::P2SH;
|
||||
}
|
||||
|
||||
bool HaveKeys(const std::vector<valtype>& pubkeys, const LegacyScriptPubKeyMan& keystore)
|
||||
bool HaveKeys(const std::vector<valtype>& pubkeys, const LegacyDataSPKM& keystore)
|
||||
{
|
||||
for (const valtype& pubkey : pubkeys) {
|
||||
CKeyID keyID = CPubKey(pubkey).GetID();
|
||||
@@ -102,7 +102,7 @@ bool HaveKeys(const std::vector<valtype>& pubkeys, const LegacyScriptPubKeyMan&
|
||||
//! scripts or simply treat any script that has been
|
||||
//! stored in the keystore as spendable
|
||||
// NOLINTNEXTLINE(misc-no-recursion)
|
||||
IsMineResult IsMineInner(const LegacyScriptPubKeyMan& keystore, const CScript& scriptPubKey, IsMineSigVersion sigversion, bool recurse_scripthash=true)
|
||||
IsMineResult IsMineInner(const LegacyDataSPKM& keystore, const CScript& scriptPubKey, IsMineSigVersion sigversion, bool recurse_scripthash=true)
|
||||
{
|
||||
IsMineResult ret = IsMineResult::NO;
|
||||
|
||||
@@ -217,7 +217,7 @@ IsMineResult IsMineInner(const LegacyScriptPubKeyMan& keystore, const CScript& s
|
||||
|
||||
} // namespace
|
||||
|
||||
isminetype LegacyScriptPubKeyMan::IsMine(const CScript& script) const
|
||||
isminetype LegacyDataSPKM::IsMine(const CScript& script) const
|
||||
{
|
||||
switch (IsMineInner(*this, script, IsMineSigVersion::TOP)) {
|
||||
case IsMineResult::INVALID:
|
||||
@@ -231,7 +231,7 @@ isminetype LegacyScriptPubKeyMan::IsMine(const CScript& script) const
|
||||
assert(false);
|
||||
}
|
||||
|
||||
bool LegacyScriptPubKeyMan::CheckDecryptionKey(const CKeyingMaterial& master_key)
|
||||
bool LegacyDataSPKM::CheckDecryptionKey(const CKeyingMaterial& master_key)
|
||||
{
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
@@ -585,7 +585,7 @@ int64_t LegacyScriptPubKeyMan::GetTimeFirstKey() const
|
||||
return nTimeFirstKey;
|
||||
}
|
||||
|
||||
std::unique_ptr<SigningProvider> LegacyScriptPubKeyMan::GetSolvingProvider(const CScript& script) const
|
||||
std::unique_ptr<SigningProvider> LegacyDataSPKM::GetSolvingProvider(const CScript& script) const
|
||||
{
|
||||
return std::make_unique<LegacySigningProvider>(*this);
|
||||
}
|
||||
@@ -721,7 +721,7 @@ void LegacyScriptPubKeyMan::UpdateTimeFirstKey(int64_t nCreateTime)
|
||||
NotifyFirstKeyTimeChanged(this, nTimeFirstKey);
|
||||
}
|
||||
|
||||
bool LegacyScriptPubKeyMan::LoadKey(const CKey& key, const CPubKey &pubkey)
|
||||
bool LegacyDataSPKM::LoadKey(const CKey& key, const CPubKey &pubkey)
|
||||
{
|
||||
return AddKeyPubKeyInner(key, pubkey);
|
||||
}
|
||||
@@ -773,7 +773,7 @@ bool LegacyScriptPubKeyMan::AddKeyPubKeyWithDB(WalletBatch& batch, const CKey& s
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LegacyScriptPubKeyMan::LoadCScript(const CScript& redeemScript)
|
||||
bool LegacyDataSPKM::LoadCScript(const CScript& redeemScript)
|
||||
{
|
||||
/* A sanity check was added in pull #3843 to avoid adding redeemScripts
|
||||
* that never can be redeemed. However, old wallets may still contain
|
||||
@@ -788,18 +788,36 @@ bool LegacyScriptPubKeyMan::LoadCScript(const CScript& redeemScript)
|
||||
return FillableSigningProvider::AddCScript(redeemScript);
|
||||
}
|
||||
|
||||
void LegacyDataSPKM::LoadKeyMetadata(const CKeyID& keyID, const CKeyMetadata& meta)
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
mapKeyMetadata[keyID] = meta;
|
||||
}
|
||||
|
||||
void LegacyScriptPubKeyMan::LoadKeyMetadata(const CKeyID& keyID, const CKeyMetadata& meta)
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
LegacyDataSPKM::LoadKeyMetadata(keyID, meta);
|
||||
UpdateTimeFirstKey(meta.nCreateTime);
|
||||
mapKeyMetadata[keyID] = meta;
|
||||
}
|
||||
|
||||
void LegacyDataSPKM::LoadScriptMetadata(const CScriptID& script_id, const CKeyMetadata& meta)
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
m_script_metadata[script_id] = meta;
|
||||
}
|
||||
|
||||
void LegacyScriptPubKeyMan::LoadScriptMetadata(const CScriptID& script_id, const CKeyMetadata& meta)
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
LegacyDataSPKM::LoadScriptMetadata(script_id, meta);
|
||||
UpdateTimeFirstKey(meta.nCreateTime);
|
||||
m_script_metadata[script_id] = meta;
|
||||
}
|
||||
|
||||
bool LegacyDataSPKM::AddKeyPubKeyInner(const CKey& key, const CPubKey& pubkey)
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
return FillableSigningProvider::AddKeyPubKey(key, pubkey);
|
||||
}
|
||||
|
||||
bool LegacyScriptPubKeyMan::AddKeyPubKeyInner(const CKey& key, const CPubKey &pubkey)
|
||||
@@ -827,7 +845,7 @@ bool LegacyScriptPubKeyMan::AddKeyPubKeyInner(const CKey& key, const CPubKey &pu
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LegacyScriptPubKeyMan::LoadCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret, bool checksum_valid)
|
||||
bool LegacyDataSPKM::LoadCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret, bool checksum_valid)
|
||||
{
|
||||
// Set fDecryptionThoroughlyChecked to false when the checksum is invalid
|
||||
if (!checksum_valid) {
|
||||
@@ -837,7 +855,7 @@ bool LegacyScriptPubKeyMan::LoadCryptedKey(const CPubKey &vchPubKey, const std::
|
||||
return AddCryptedKeyInner(vchPubKey, vchCryptedSecret);
|
||||
}
|
||||
|
||||
bool LegacyScriptPubKeyMan::AddCryptedKeyInner(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret)
|
||||
bool LegacyDataSPKM::AddCryptedKeyInner(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret)
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
assert(mapKeys.empty());
|
||||
@@ -865,13 +883,13 @@ bool LegacyScriptPubKeyMan::AddCryptedKey(const CPubKey &vchPubKey,
|
||||
}
|
||||
}
|
||||
|
||||
bool LegacyScriptPubKeyMan::HaveWatchOnly(const CScript &dest) const
|
||||
bool LegacyDataSPKM::HaveWatchOnly(const CScript &dest) const
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
return setWatchOnly.count(dest) > 0;
|
||||
}
|
||||
|
||||
bool LegacyScriptPubKeyMan::HaveWatchOnly() const
|
||||
bool LegacyDataSPKM::HaveWatchOnly() const
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
return (!setWatchOnly.empty());
|
||||
@@ -905,12 +923,12 @@ bool LegacyScriptPubKeyMan::RemoveWatchOnly(const CScript &dest)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LegacyScriptPubKeyMan::LoadWatchOnly(const CScript &dest)
|
||||
bool LegacyDataSPKM::LoadWatchOnly(const CScript &dest)
|
||||
{
|
||||
return AddWatchOnlyInMem(dest);
|
||||
}
|
||||
|
||||
bool LegacyScriptPubKeyMan::AddWatchOnlyInMem(const CScript &dest)
|
||||
bool LegacyDataSPKM::AddWatchOnlyInMem(const CScript &dest)
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
setWatchOnly.insert(dest);
|
||||
@@ -954,7 +972,7 @@ bool LegacyScriptPubKeyMan::AddWatchOnly(const CScript& dest, int64_t nCreateTim
|
||||
return AddWatchOnly(dest);
|
||||
}
|
||||
|
||||
void LegacyScriptPubKeyMan::LoadHDChain(const CHDChain& chain)
|
||||
void LegacyDataSPKM::LoadHDChain(const CHDChain& chain)
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
m_hd_chain = chain;
|
||||
@@ -975,14 +993,14 @@ void LegacyScriptPubKeyMan::AddHDChain(const CHDChain& chain)
|
||||
m_hd_chain = chain;
|
||||
}
|
||||
|
||||
void LegacyScriptPubKeyMan::AddInactiveHDChain(const CHDChain& chain)
|
||||
void LegacyDataSPKM::AddInactiveHDChain(const CHDChain& chain)
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
assert(!chain.seed_id.IsNull());
|
||||
m_inactive_hd_chains[chain.seed_id] = chain;
|
||||
}
|
||||
|
||||
bool LegacyScriptPubKeyMan::HaveKey(const CKeyID &address) const
|
||||
bool LegacyDataSPKM::HaveKey(const CKeyID &address) const
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
if (!m_storage.HasEncryptionKeys()) {
|
||||
@@ -991,7 +1009,7 @@ bool LegacyScriptPubKeyMan::HaveKey(const CKeyID &address) const
|
||||
return mapCryptedKeys.count(address) > 0;
|
||||
}
|
||||
|
||||
bool LegacyScriptPubKeyMan::GetKey(const CKeyID &address, CKey& keyOut) const
|
||||
bool LegacyDataSPKM::GetKey(const CKeyID &address, CKey& keyOut) const
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
if (!m_storage.HasEncryptionKeys()) {
|
||||
@@ -1010,7 +1028,7 @@ bool LegacyScriptPubKeyMan::GetKey(const CKeyID &address, CKey& keyOut) const
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LegacyScriptPubKeyMan::GetKeyOrigin(const CKeyID& keyID, KeyOriginInfo& info) const
|
||||
bool LegacyDataSPKM::GetKeyOrigin(const CKeyID& keyID, KeyOriginInfo& info) const
|
||||
{
|
||||
CKeyMetadata meta;
|
||||
{
|
||||
@@ -1030,7 +1048,7 @@ bool LegacyScriptPubKeyMan::GetKeyOrigin(const CKeyID& keyID, KeyOriginInfo& inf
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LegacyScriptPubKeyMan::GetWatchPubKey(const CKeyID &address, CPubKey &pubkey_out) const
|
||||
bool LegacyDataSPKM::GetWatchPubKey(const CKeyID &address, CPubKey &pubkey_out) const
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
WatchKeyMap::const_iterator it = mapWatchKeys.find(address);
|
||||
@@ -1041,7 +1059,7 @@ bool LegacyScriptPubKeyMan::GetWatchPubKey(const CKeyID &address, CPubKey &pubke
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LegacyScriptPubKeyMan::GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const
|
||||
bool LegacyDataSPKM::GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
if (!m_storage.HasEncryptionKeys()) {
|
||||
@@ -1160,7 +1178,7 @@ void LegacyScriptPubKeyMan::DeriveNewChildKey(WalletBatch &batch, CKeyMetadata&
|
||||
throw std::runtime_error(std::string(__func__) + ": writing HD chain model failed");
|
||||
}
|
||||
|
||||
void LegacyScriptPubKeyMan::LoadKeyPool(int64_t nIndex, const CKeyPool &keypool)
|
||||
void LegacyDataSPKM::LoadKeyPool(int64_t nIndex, const CKeyPool &keypool)
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
if (keypool.m_pre_split) {
|
||||
@@ -1681,7 +1699,7 @@ std::set<CKeyID> LegacyScriptPubKeyMan::GetKeys() const
|
||||
return set_address;
|
||||
}
|
||||
|
||||
std::unordered_set<CScript, SaltedSipHasher> LegacyScriptPubKeyMan::GetScriptPubKeys() const
|
||||
std::unordered_set<CScript, SaltedSipHasher> LegacyDataSPKM::GetScriptPubKeys() const
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
std::unordered_set<CScript, SaltedSipHasher> spks;
|
||||
@@ -1739,7 +1757,7 @@ std::unordered_set<CScript, SaltedSipHasher> LegacyScriptPubKeyMan::GetScriptPub
|
||||
return spks;
|
||||
}
|
||||
|
||||
std::unordered_set<CScript, SaltedSipHasher> LegacyScriptPubKeyMan::GetNotMineScriptPubKeys() const
|
||||
std::unordered_set<CScript, SaltedSipHasher> LegacyDataSPKM::GetNotMineScriptPubKeys() const
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
std::unordered_set<CScript, SaltedSipHasher> spks;
|
||||
@@ -1749,7 +1767,7 @@ std::unordered_set<CScript, SaltedSipHasher> LegacyScriptPubKeyMan::GetNotMineSc
|
||||
return spks;
|
||||
}
|
||||
|
||||
std::optional<MigrationData> LegacyScriptPubKeyMan::MigrateToDescriptor()
|
||||
std::optional<MigrationData> LegacyDataSPKM::MigrateToDescriptor()
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
if (m_storage.IsLocked()) {
|
||||
@@ -1816,7 +1834,7 @@ std::optional<MigrationData> LegacyScriptPubKeyMan::MigrateToDescriptor()
|
||||
WalletDescriptor w_desc(std::move(desc), creation_time, 0, 0, 0);
|
||||
|
||||
// Make the DescriptorScriptPubKeyMan and get the scriptPubKeys
|
||||
auto desc_spk_man = std::unique_ptr<DescriptorScriptPubKeyMan>(new DescriptorScriptPubKeyMan(m_storage, w_desc, m_keypool_size));
|
||||
auto desc_spk_man = std::make_unique<DescriptorScriptPubKeyMan>(m_storage, w_desc, /*keypool_size=*/0);
|
||||
desc_spk_man->AddDescriptorKey(key, key.GetPubKey());
|
||||
desc_spk_man->TopUp();
|
||||
auto desc_spks = desc_spk_man->GetScriptPubKeys();
|
||||
@@ -1861,7 +1879,7 @@ std::optional<MigrationData> LegacyScriptPubKeyMan::MigrateToDescriptor()
|
||||
WalletDescriptor w_desc(std::move(desc), 0, 0, chain_counter, 0);
|
||||
|
||||
// Make the DescriptorScriptPubKeyMan and get the scriptPubKeys
|
||||
auto desc_spk_man = std::unique_ptr<DescriptorScriptPubKeyMan>(new DescriptorScriptPubKeyMan(m_storage, w_desc, m_keypool_size));
|
||||
auto desc_spk_man = std::make_unique<DescriptorScriptPubKeyMan>(m_storage, w_desc, /*keypool_size=*/0);
|
||||
desc_spk_man->AddDescriptorKey(master_key.key, master_key.key.GetPubKey());
|
||||
desc_spk_man->TopUp();
|
||||
auto desc_spks = desc_spk_man->GetScriptPubKeys();
|
||||
@@ -1923,7 +1941,7 @@ std::optional<MigrationData> LegacyScriptPubKeyMan::MigrateToDescriptor()
|
||||
} else {
|
||||
// Make the DescriptorScriptPubKeyMan and get the scriptPubKeys
|
||||
WalletDescriptor w_desc(std::move(desc), creation_time, 0, 0, 0);
|
||||
auto desc_spk_man = std::unique_ptr<DescriptorScriptPubKeyMan>(new DescriptorScriptPubKeyMan(m_storage, w_desc, m_keypool_size));
|
||||
auto desc_spk_man = std::make_unique<DescriptorScriptPubKeyMan>(m_storage, w_desc, /*keypool_size=*/0);
|
||||
for (const auto& keyid : privkeyids) {
|
||||
CKey key;
|
||||
if (!GetKey(keyid, key)) {
|
||||
@@ -2001,7 +2019,7 @@ std::optional<MigrationData> LegacyScriptPubKeyMan::MigrateToDescriptor()
|
||||
return out;
|
||||
}
|
||||
|
||||
bool LegacyScriptPubKeyMan::DeleteRecords()
|
||||
bool LegacyDataSPKM::DeleteRecords()
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
WalletBatch batch(m_storage.GetDatabase());
|
||||
|
||||
Reference in New Issue
Block a user