From 0c8e72847603540bb29b8b8aeb80fa3f2e3a2c9a Mon Sep 17 00:00:00 2001 From: Ava Chow Date: Tue, 2 Jan 2024 16:35:22 -0500 Subject: wallet: implement BerkeleyROBatch Implement ReadKey and HasKey of BerkeleyROBatch, and Next of BerkeleyROCursor. Also adds the containers for records to BerkeleyRODatabase so that BerkeleyROBatch will be able to access the records. --- src/wallet/db.cpp | 3 +++ src/wallet/db.h | 6 ++++++ src/wallet/migrate.cpp | 31 ++++++++++++++++++++++++++++--- src/wallet/migrate.h | 17 +++++++++++++++-- src/wallet/test/util.cpp | 5 ----- 5 files changed, 52 insertions(+), 10 deletions(-) (limited to 'src/wallet') diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp index ea06767e9b..a5a5f8ec6f 100644 --- a/src/wallet/db.cpp +++ b/src/wallet/db.cpp @@ -16,6 +16,9 @@ #include namespace wallet { +bool operator<(BytePrefix a, Span b) { return a.prefix < b.subspan(0, std::min(a.prefix.size(), b.size())); } +bool operator<(Span a, BytePrefix b) { return a.subspan(0, std::min(a.size(), b.prefix.size())) < b.prefix; } + std::vector ListDatabases(const fs::path& wallet_dir) { std::vector paths; diff --git a/src/wallet/db.h b/src/wallet/db.h index 084fcadc24..648adff5fe 100644 --- a/src/wallet/db.h +++ b/src/wallet/db.h @@ -20,6 +20,12 @@ class ArgsManager; struct bilingual_str; namespace wallet { +// BytePrefix compares equality with other byte spans that begin with the same prefix. +struct BytePrefix { + Span prefix; +}; +bool operator<(BytePrefix a, Span b); +bool operator<(Span a, BytePrefix b); class DatabaseCursor { diff --git a/src/wallet/migrate.cpp b/src/wallet/migrate.cpp index e567cb0f51..f922d99a17 100644 --- a/src/wallet/migrate.cpp +++ b/src/wallet/migrate.cpp @@ -21,17 +21,42 @@ bool BerkeleyRODatabase::Backup(const std::string& dest) const bool BerkeleyROBatch::ReadKey(DataStream&& key, DataStream& value) { - return false; + SerializeData key_data{key.begin(), key.end()}; + const auto it{m_database.m_records.find(key_data)}; + if (it == m_database.m_records.end()) { + return false; + } + auto val = it->second; + value.clear(); + value.write(Span(val)); + return true; } bool BerkeleyROBatch::HasKey(DataStream&& key) { - return false; + SerializeData key_data{key.begin(), key.end()}; + return m_database.m_records.count(key_data) > 0; +} + +BerkeleyROCursor::BerkeleyROCursor(const BerkeleyRODatabase& database, Span prefix) + : m_database(database) +{ + std::tie(m_cursor, m_cursor_end) = m_database.m_records.equal_range(BytePrefix{prefix}); } DatabaseCursor::Status BerkeleyROCursor::Next(DataStream& ssKey, DataStream& ssValue) { - return DatabaseCursor::Status::FAIL; + if (m_cursor == m_cursor_end) { + return DatabaseCursor::Status::DONE; + } + ssKey.write(Span(m_cursor->first)); + ssValue.write(Span(m_cursor->second)); + m_cursor++; + return DatabaseCursor::Status::MORE; } +std::unique_ptr BerkeleyROBatch::GetNewPrefixCursor(Span prefix) +{ + return std::make_unique(m_database, prefix); +} } // namespace wallet diff --git a/src/wallet/migrate.h b/src/wallet/migrate.h index de7082e8a0..a3b0d78d02 100644 --- a/src/wallet/migrate.h +++ b/src/wallet/migrate.h @@ -10,6 +10,9 @@ #include namespace wallet { + +using BerkeleyROData = std::map>; + /** * A class representing a BerkeleyDB file from which we can only read records. * This is used only for migration of legacy to descriptor wallets @@ -27,6 +30,8 @@ public: } ~BerkeleyRODatabase(){}; + BerkeleyROData m_records; + /** Open the database if it is not already opened. */ void Open() override; @@ -69,7 +74,15 @@ public: class BerkeleyROCursor : public DatabaseCursor { +private: + const BerkeleyRODatabase& m_database; + BerkeleyROData::const_iterator m_cursor; + BerkeleyROData::const_iterator m_cursor_end; + public: + explicit BerkeleyROCursor(const BerkeleyRODatabase& database, Span prefix = {}); + ~BerkeleyROCursor() {} + Status Next(DataStream& key, DataStream& value) override; }; @@ -97,8 +110,8 @@ public: void Flush() override {} void Close() override {} - std::unique_ptr GetNewCursor() override { return std::make_unique(); } - std::unique_ptr GetNewPrefixCursor(Span prefix) override { return std::make_unique(); } + std::unique_ptr GetNewCursor() override { return std::make_unique(m_database); } + std::unique_ptr GetNewPrefixCursor(Span prefix) override; bool TxnBegin() override { return false; } bool TxnCommit() override { return false; } bool TxnAbort() override { return false; } diff --git a/src/wallet/test/util.cpp b/src/wallet/test/util.cpp index 49d206f409..b21a9a601d 100644 --- a/src/wallet/test/util.cpp +++ b/src/wallet/test/util.cpp @@ -93,11 +93,6 @@ CTxDestination getNewDestination(CWallet& w, OutputType output_type) return *Assert(w.GetNewDestination(output_type, "")); } -// BytePrefix compares equality with other byte spans that begin with the same prefix. -struct BytePrefix { Span prefix; }; -bool operator<(BytePrefix a, Span b) { return a.prefix < b.subspan(0, std::min(a.prefix.size(), b.size())); } -bool operator<(Span a, BytePrefix b) { return a.subspan(0, std::min(a.size(), b.prefix.size())) < b.prefix; } - MockableCursor::MockableCursor(const MockableData& records, bool pass, Span prefix) { m_pass = pass; -- cgit v1.2.3