0diff --git a/src/wallet/test/util.cpp b/src/wallet/test/util.cpp
1index f14f451b52b8..0256d3fafbf6 100644
2--- a/src/wallet/test/util.cpp
3+++ b/src/wallet/test/util.cpp
4@@ -61,25 +61,15 @@ CTxDestination getNewDestination(CWallet& w, OutputType output_type)
5 return *Assert(w.GetNewDestination(output_type, ""));
6 }
7
8-MockableCursor::MockableCursor(const std::map<SerializeData, SerializeData>& records, bool pass, Span<std::byte> prefix)
9+// BytePrefix object compares equal with other byte spans beginning with the same prefix.
10+struct BytePrefix { Span<const std::byte> prefix; };
11+bool operator<(BytePrefix a, Span<const std::byte> b) { return a.prefix < b.subspan(0, std::min(a.prefix.size(), b.size())); }
12+bool operator<(Span<const std::byte> a, BytePrefix b) { return a.subspan(0, std::min(a.size(), b.prefix.size())) < b.prefix; }
13+
14+MockableCursor::MockableCursor(const MockableData& records, bool pass, Span<std::byte> prefix)
15 {
16 m_pass = pass;
17-
18- // Start the cursor at the first value that is greater than or equal to the prefix
19- m_cursor = records.lower_bound(SerializeData(prefix.begin(), prefix.end()));
20-
21- // The end cursor is the first item that is greater than or equal to the prefix + 1 (when interpreted as an integer)
22- SerializeData end_range(prefix.begin(), prefix.end());
23- auto it = end_range.rbegin();
24- for (; it != end_range.rend(); ++it) {
25- if (*it == std::byte(std::numeric_limits<unsigned char>::max())) {
26- *it = std::byte(0);
27- continue;
28- }
29- *it = std::byte(std::to_integer<unsigned char>(*it) + 1);
30- break;
31- }
32- m_cursor_end = records.lower_bound(end_range);
33+ std::tie(m_cursor, m_cursor_end) = records.equal_range(BytePrefix{prefix});
34 }
35
36 DatabaseCursor::Status MockableCursor::Next(DataStream& key, DataStream& value)
37@@ -165,7 +155,7 @@ bool MockableBatch::ErasePrefix(Span<const std::byte> prefix)
38 return true;
39 }
40
41-std::unique_ptr<WalletDatabase> CreateMockableWalletDatabase(std::map<SerializeData, SerializeData> records)
42+std::unique_ptr<WalletDatabase> CreateMockableWalletDatabase(MockableData records)
43 {
44 return std::make_unique<MockableDatabase>(records);
45 }
46diff --git a/src/wallet/test/util.h b/src/wallet/test/util.h
47index 75f9b46c2a1d..3fdf40d13ccb 100644
48--- a/src/wallet/test/util.h
49+++ b/src/wallet/test/util.h
50@@ -32,15 +32,17 @@ std::string getnewaddress(CWallet& w);
51 /** Returns a new destination, of an specific type, from the wallet */
52 CTxDestination getNewDestination(CWallet& w, OutputType output_type);
53
54+using MockableData = std::map<SerializeData, SerializeData, std::less<>>;
55+
56 class MockableCursor: public DatabaseCursor
57 {
58 public:
59- std::map<SerializeData, SerializeData>::const_iterator m_cursor;
60- std::map<SerializeData, SerializeData>::const_iterator m_cursor_end;
61+ MockableData::const_iterator m_cursor;
62+ MockableData::const_iterator m_cursor_end;
63 bool m_pass;
64
65- explicit MockableCursor(const std::map<SerializeData, SerializeData>& records, bool pass) : m_cursor(records.begin()), m_cursor_end(records.end()), m_pass(pass) {}
66- MockableCursor(const std::map<SerializeData, SerializeData>& records, bool pass, Span<std::byte> prefix);
67+ explicit MockableCursor(const MockableData& records, bool pass) : m_cursor(records.begin()), m_cursor_end(records.end()), m_pass(pass) {}
68+ MockableCursor(const MockableData& records, bool pass, Span<std::byte> prefix);
69 ~MockableCursor() {}
70
71 Status Next(DataStream& key, DataStream& value) override;
72@@ -49,7 +51,7 @@ public:
73 class MockableBatch : public DatabaseBatch
74 {
75 private:
76- std::map<SerializeData, SerializeData>& m_records;
77+ MockableData& m_records;
78 bool m_pass;
79
80 bool ReadKey(DataStream&& key, DataStream& value) override;
81@@ -59,7 +61,7 @@ private:
82 bool ErasePrefix(Span<const std::byte> prefix) override;
83
84 public:
85- explicit MockableBatch(std::map<SerializeData, SerializeData>& records, bool pass) : m_records(records), m_pass(pass) {}
86+ explicit MockableBatch(MockableData& records, bool pass) : m_records(records), m_pass(pass) {}
87 ~MockableBatch() {}
88
89 void Flush() override {}
90@@ -82,10 +84,10 @@ public:
91 class MockableDatabase : public WalletDatabase
92 {
93 public:
94- std::map<SerializeData, SerializeData> m_records;
95+ MockableData m_records;
96 bool m_pass{true};
97
98- MockableDatabase(std::map<SerializeData, SerializeData> records = {}) : WalletDatabase(), m_records(records) {}
99+ MockableDatabase(MockableData records = {}) : WalletDatabase(), m_records(records) {}
100 ~MockableDatabase() {};
101
102 void Open() override {}
103@@ -105,7 +107,7 @@ public:
104 std::unique_ptr<DatabaseBatch> MakeBatch(bool flush_on_close = true) override { return std::make_unique<MockableBatch>(m_records, m_pass); }
105 };
106
107-std::unique_ptr<WalletDatabase> CreateMockableWalletDatabase(std::map<SerializeData, SerializeData> records = {});
108+std::unique_ptr<WalletDatabase> CreateMockableWalletDatabase(MockableData records = {});
109
110 MockableDatabase& GetMockableDatabase(CWallet& wallet);
111 } // namespace wallet
112diff --git a/src/wallet/test/walletload_tests.cpp b/src/wallet/test/walletload_tests.cpp
113index 6823eafdfa7f..c1ff7baae117 100644
114--- a/src/wallet/test/walletload_tests.cpp
115+++ b/src/wallet/test/walletload_tests.cpp
116@@ -83,7 +83,7 @@ BOOST_FIXTURE_TEST_CASE(wallet_load_ckey, TestingSetup)
117 {
118 SerializeData ckey_record_key;
119 SerializeData ckey_record_value;
120- std::map<SerializeData, SerializeData> records;
121+ MockableData records;
122
123 {
124 // Context setup.