From 22401f17e026ead4bc3fe96967eec56a719a4f75 Mon Sep 17 00:00:00 2001 From: Andrew Chow Date: Thu, 25 Aug 2022 14:35:28 -0400 Subject: [PATCH] Implement LegacyScriptPubKeyMan::DeleteRecords --- src/wallet/scriptpubkeyman.cpp | 7 ++++++ src/wallet/scriptpubkeyman.h | 2 ++ src/wallet/walletdb.cpp | 40 ++++++++++++++++++++++++++++++++++ src/wallet/walletdb.h | 6 +++++ 4 files changed, 55 insertions(+) diff --git a/src/wallet/scriptpubkeyman.cpp b/src/wallet/scriptpubkeyman.cpp index 3e6830a08da..41654579c6a 100644 --- a/src/wallet/scriptpubkeyman.cpp +++ b/src/wallet/scriptpubkeyman.cpp @@ -1964,6 +1964,13 @@ std::optional LegacyScriptPubKeyMan::MigrateToDescriptor() return out; } +bool LegacyScriptPubKeyMan::DeleteRecords() +{ + LOCK(cs_KeyStore); + WalletBatch batch(m_storage.GetDatabase()); + return batch.EraseRecords(DBKeys::LEGACY_TYPES); +} + util::Result DescriptorScriptPubKeyMan::GetNewDestination(const OutputType type) { // Returns true if this descriptor supports getting new addresses. Conditions where we may be unable to fetch them (e.g. locked) are caught later diff --git a/src/wallet/scriptpubkeyman.h b/src/wallet/scriptpubkeyman.h index 19ec277c562..3ab489c3744 100644 --- a/src/wallet/scriptpubkeyman.h +++ b/src/wallet/scriptpubkeyman.h @@ -517,6 +517,8 @@ public: /** Get the DescriptorScriptPubKeyMans (with private keys) that have the same scriptPubKeys as this LegacyScriptPubKeyMan. * Does not modify this ScriptPubKeyMan. */ std::optional MigrateToDescriptor(); + /** Delete all the records ofthis LegacyScriptPubKeyMan from disk*/ + bool DeleteRecords(); }; /** Wraps a LegacyScriptPubKeyMan so that it can be returned in a new unique_ptr. Does not provide privkeys */ diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index 0d85652c0c0..30406a22f92 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -59,6 +59,7 @@ const std::string WALLETDESCRIPTORCKEY{"walletdescriptorckey"}; const std::string WALLETDESCRIPTORKEY{"walletdescriptorkey"}; const std::string WATCHMETA{"watchmeta"}; const std::string WATCHS{"watchs"}; +const std::unordered_set LEGACY_TYPES{CRYPTED_KEY, CSCRIPT, DEFAULTKEY, HDCHAIN, KEYMETA, KEY, OLD_KEY, POOL, WATCHMETA, WATCHS}; } // namespace DBKeys // @@ -1083,6 +1084,45 @@ bool WalletBatch::WriteWalletFlags(const uint64_t flags) return WriteIC(DBKeys::FLAGS, flags); } +bool WalletBatch::EraseRecords(const std::unordered_set& types) +{ + // Get cursor + if (!m_batch->StartCursor()) + { + return false; + } + + // Iterate the DB and look for any records that have the type prefixes + while (true) + { + // Read next record + CDataStream key(SER_DISK, CLIENT_VERSION); + CDataStream value(SER_DISK, CLIENT_VERSION); + bool complete; + bool ret = m_batch->ReadAtCursor(key, value, complete); + if (complete) { + break; + } + else if (!ret) + { + m_batch->CloseCursor(); + return false; + } + + // Make a copy of key to avoid data being deleted by the following read of the type + Span key_data = MakeUCharSpan(key); + + std::string type; + key >> type; + + if (types.count(type) > 0) { + m_batch->Erase(key_data); + } + } + m_batch->CloseCursor(); + return true; +} + bool WalletBatch::TxnBegin() { return m_batch->TxnBegin(); diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h index a04ea598b65..6aa25fae038 100644 --- a/src/wallet/walletdb.h +++ b/src/wallet/walletdb.h @@ -84,6 +84,9 @@ extern const std::string WALLETDESCRIPTORCKEY; extern const std::string WALLETDESCRIPTORKEY; extern const std::string WATCHMETA; extern const std::string WATCHS; + +// Keys in this set pertain only to the legacy wallet (LegacyScriptPubKeyMan) and are removed during migration from legacy to descriptors. +extern const std::unordered_set LEGACY_TYPES; } // namespace DBKeys /* simple HD chain data model */ @@ -276,6 +279,9 @@ public: //! write the hdchain model (external chain child index counter) bool WriteHDChain(const CHDChain& chain); + //! Delete records of the given types + bool EraseRecords(const std::unordered_set& types); + bool WriteWalletFlags(const uint64_t flags); //! Begin a new transaction bool TxnBegin();