aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAva Chow <github@achow101.com>2024-01-02 16:35:22 -0500
committerAva Chow <github@achow101.com>2024-05-13 23:01:37 -0400
commit0c8e72847603540bb29b8b8aeb80fa3f2e3a2c9a (patch)
tree3ad7d3dafb7257f8031fc8c5f9f2171d22e8eb2d
parent756ff9b478484b17c4a6e65c171c2e4fecb21ad4 (diff)
downloadbitcoin-0c8e72847603540bb29b8b8aeb80fa3f2e3a2c9a.tar.xz
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.
-rw-r--r--src/wallet/db.cpp3
-rw-r--r--src/wallet/db.h6
-rw-r--r--src/wallet/migrate.cpp31
-rw-r--r--src/wallet/migrate.h17
-rw-r--r--src/wallet/test/util.cpp5
5 files changed, 52 insertions, 10 deletions
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 <vector>
namespace wallet {
+bool operator<(BytePrefix a, Span<const std::byte> b) { return a.prefix < b.subspan(0, std::min(a.prefix.size(), b.size())); }
+bool operator<(Span<const std::byte> a, BytePrefix b) { return a.subspan(0, std::min(a.size(), b.prefix.size())) < b.prefix; }
+
std::vector<fs::path> ListDatabases(const fs::path& wallet_dir)
{
std::vector<fs::path> 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<const std::byte> prefix;
+};
+bool operator<(BytePrefix a, Span<const std::byte> b);
+bool operator<(Span<const std::byte> 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<const std::byte> 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<DatabaseCursor> BerkeleyROBatch::GetNewPrefixCursor(Span<const std::byte> prefix)
+{
+ return std::make_unique<BerkeleyROCursor>(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 <optional>
namespace wallet {
+
+using BerkeleyROData = std::map<SerializeData, SerializeData, std::less<>>;
+
/**
* 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<const std::byte> prefix = {});
+ ~BerkeleyROCursor() {}
+
Status Next(DataStream& key, DataStream& value) override;
};
@@ -97,8 +110,8 @@ public:
void Flush() override {}
void Close() override {}
- std::unique_ptr<DatabaseCursor> GetNewCursor() override { return std::make_unique<BerkeleyROCursor>(); }
- std::unique_ptr<DatabaseCursor> GetNewPrefixCursor(Span<const std::byte> prefix) override { return std::make_unique<BerkeleyROCursor>(); }
+ std::unique_ptr<DatabaseCursor> GetNewCursor() override { return std::make_unique<BerkeleyROCursor>(m_database); }
+ std::unique_ptr<DatabaseCursor> GetNewPrefixCursor(Span<const std::byte> 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<const std::byte> prefix; };
-bool operator<(BytePrefix a, Span<const std::byte> b) { return a.prefix < b.subspan(0, std::min(a.prefix.size(), b.size())); }
-bool operator<(Span<const std::byte> a, BytePrefix b) { return a.subspan(0, std::min(a.size(), b.prefix.size())) < b.prefix; }
-
MockableCursor::MockableCursor(const MockableData& records, bool pass, Span<const std::byte> prefix)
{
m_pass = pass;