mirror of
https://github.com/XRPLF/clio.git
synced 2026-06-02 08:16:58 +00:00
@@ -5,6 +5,7 @@ target_sources(
|
||||
BackendCounters.cpp
|
||||
BackendInterface.cpp
|
||||
LedgerCache.cpp
|
||||
LedgerHeaderCache.cpp
|
||||
cassandra/impl/Future.cpp
|
||||
cassandra/impl/Cluster.cpp
|
||||
cassandra/impl/Batch.cpp
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "data/BackendInterface.hpp"
|
||||
#include "data/DBHelpers.hpp"
|
||||
#include "data/LedgerCacheInterface.hpp"
|
||||
#include "data/LedgerHeaderCache.hpp"
|
||||
#include "data/Types.hpp"
|
||||
#include "data/cassandra/Concepts.hpp"
|
||||
#include "data/cassandra/Handle.hpp"
|
||||
@@ -62,6 +63,8 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
class CacheBackendCassandraTest;
|
||||
|
||||
namespace data::cassandra {
|
||||
|
||||
/**
|
||||
@@ -71,21 +74,27 @@ namespace data::cassandra {
|
||||
*
|
||||
* @tparam SettingsProviderType The settings provider type to use
|
||||
* @tparam ExecutionStrategyType The execution strategy type to use
|
||||
* @tparam FetchLedgerCacheType The ledger header cache type to use
|
||||
*/
|
||||
template <SomeSettingsProvider SettingsProviderType, SomeExecutionStrategy ExecutionStrategyType>
|
||||
template <
|
||||
SomeSettingsProvider SettingsProviderType,
|
||||
SomeExecutionStrategy ExecutionStrategyType,
|
||||
typename FetchLedgerCacheType = FetchLedgerCache>
|
||||
class BasicCassandraBackend : public BackendInterface {
|
||||
util::Logger log_{"Backend"};
|
||||
|
||||
SettingsProviderType settingsProvider_;
|
||||
Schema<SettingsProviderType> schema_;
|
||||
|
||||
std::atomic_uint32_t ledgerSequence_ = 0u;
|
||||
friend class ::CacheBackendCassandraTest;
|
||||
|
||||
protected:
|
||||
Handle handle_;
|
||||
|
||||
// have to be mutable because BackendInterface constness :(
|
||||
mutable ExecutionStrategyType executor_;
|
||||
// TODO: move to interface level
|
||||
mutable FetchLedgerCacheType ledgerCache_{};
|
||||
|
||||
public:
|
||||
/**
|
||||
@@ -129,7 +138,6 @@ public:
|
||||
LOG(log_.error()) << error;
|
||||
throw std::runtime_error(error);
|
||||
}
|
||||
|
||||
LOG(log_.info()) << "Created (revamped) CassandraBackend";
|
||||
}
|
||||
|
||||
@@ -263,11 +271,16 @@ public:
|
||||
std::optional<ripple::LedgerHeader>
|
||||
fetchLedgerBySequence(std::uint32_t const sequence, boost::asio::yield_context yield) const override
|
||||
{
|
||||
if (auto const lock = ledgerCache_.get(); lock.has_value() && lock->seq == sequence)
|
||||
return lock->ledger;
|
||||
|
||||
auto const res = executor_.read(yield, schema_->selectLedgerBySeq, sequence);
|
||||
if (res) {
|
||||
if (auto const& result = res.value(); result) {
|
||||
if (auto const maybeValue = result.template get<std::vector<unsigned char>>(); maybeValue) {
|
||||
return util::deserializeHeader(ripple::makeSlice(*maybeValue));
|
||||
auto const header = util::deserializeHeader(ripple::makeSlice(*maybeValue));
|
||||
ledgerCache_.put(FetchLedgerCache::CacheEntry{header, sequence});
|
||||
return header;
|
||||
}
|
||||
|
||||
LOG(log_.error()) << "Could not fetch ledger by sequence - no rows";
|
||||
|
||||
46
src/data/LedgerHeaderCache.cpp
Normal file
46
src/data/LedgerHeaderCache.cpp
Normal file
@@ -0,0 +1,46 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of clio: https://github.com/XRPLF/clio
|
||||
Copyright (c) 2025, the clio developers.
|
||||
|
||||
Permission to use, copy, modify, and distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include "data/LedgerHeaderCache.hpp"
|
||||
|
||||
#include "util/Mutex.hpp"
|
||||
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
#include <shared_mutex>
|
||||
|
||||
namespace data {
|
||||
|
||||
FetchLedgerCache::FetchLedgerCache() = default;
|
||||
|
||||
void
|
||||
FetchLedgerCache::put(CacheEntry const& cacheEntry)
|
||||
{
|
||||
auto lock = mutex_.lock<std::unique_lock>();
|
||||
*lock = cacheEntry;
|
||||
}
|
||||
|
||||
std::optional<FetchLedgerCache::CacheEntry>
|
||||
FetchLedgerCache::get() const
|
||||
{
|
||||
auto const lock = mutex_.lock<std::shared_lock>();
|
||||
return lock.get();
|
||||
}
|
||||
|
||||
} // namespace data
|
||||
85
src/data/LedgerHeaderCache.hpp
Normal file
85
src/data/LedgerHeaderCache.hpp
Normal file
@@ -0,0 +1,85 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of clio: https://github.com/XRPLF/clio
|
||||
Copyright (c) 2025, the clio developers.
|
||||
|
||||
Permission to use, copy, modify, and distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "util/Mutex.hpp"
|
||||
|
||||
#include <xrpl/protocol/LedgerHeader.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
#include <shared_mutex>
|
||||
|
||||
namespace data {
|
||||
|
||||
/**
|
||||
* @brief A simple cache holding one `ripple::LedgerHeader` to reduce DB lookups.
|
||||
*
|
||||
* Used internally by backend implementations. When a ledger header is
|
||||
* fetched via `FetchLedgerBySeq` (often triggered by RPC commands),
|
||||
* the result can be stored here. Subsequent requests for the same ledger
|
||||
* sequence can proceed to retrieve the header from this cache, avoiding unnecessary
|
||||
* database reads and improving performance.
|
||||
*/
|
||||
class FetchLedgerCache {
|
||||
public:
|
||||
FetchLedgerCache();
|
||||
|
||||
/**
|
||||
* @brief Struct to store ledger header cache entry and the sequence it belongs to
|
||||
*/
|
||||
struct CacheEntry {
|
||||
ripple::LedgerHeader ledger;
|
||||
uint32_t seq{};
|
||||
|
||||
/**
|
||||
* @brief Comparing CacheEntry. Used in testing for EXPECT_CALL
|
||||
*
|
||||
* @param other The other cacheEntry to compare
|
||||
* @return true if two CacheEntry is the same, false otherwise
|
||||
*/
|
||||
bool
|
||||
operator==(CacheEntry const& other) const
|
||||
{
|
||||
return ledger.hash == other.ledger.hash && seq == other.seq;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Put CacheEntry into thread-safe container
|
||||
*
|
||||
* @param cacheEntry The Cache to store into thread-safe container.
|
||||
*/
|
||||
void
|
||||
put(CacheEntry const& cacheEntry);
|
||||
|
||||
/**
|
||||
* @brief Read CacheEntry from thread-safe container.
|
||||
*
|
||||
* @return Optional CacheEntry, depending on if it exists in thread-safe container or not.
|
||||
*/
|
||||
std::optional<CacheEntry>
|
||||
get() const;
|
||||
|
||||
private:
|
||||
mutable util::Mutex<std::optional<CacheEntry>, std::shared_mutex> mutex_;
|
||||
};
|
||||
|
||||
} // namespace data
|
||||
35
tests/common/util/MockLedgerHeaderCache.hpp
Normal file
35
tests/common/util/MockLedgerHeaderCache.hpp
Normal file
@@ -0,0 +1,35 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of clio: https://github.com/XRPLF/clio
|
||||
Copyright (c) 2025, the clio developers.
|
||||
|
||||
Permission to use, copy, modify, and distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "data/LedgerHeaderCache.hpp"
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
#include <xrpl/protocol/LedgerHeader.h>
|
||||
|
||||
#include <optional>
|
||||
|
||||
struct MockLedgerHeaderCache {
|
||||
MockLedgerHeaderCache() = default;
|
||||
using CacheEntry = data::FetchLedgerCache::CacheEntry;
|
||||
|
||||
MOCK_METHOD(void, put, (CacheEntry), ());
|
||||
MOCK_METHOD(std::optional<CacheEntry>, get, (), (const));
|
||||
};
|
||||
@@ -21,13 +21,16 @@
|
||||
#include "data/CassandraBackend.hpp"
|
||||
#include "data/DBHelpers.hpp"
|
||||
#include "data/LedgerCache.hpp"
|
||||
#include "data/LedgerHeaderCache.hpp"
|
||||
#include "data/Types.hpp"
|
||||
#include "data/cassandra/Handle.hpp"
|
||||
#include "data/cassandra/SettingsProvider.hpp"
|
||||
#include "data/cassandra/Types.hpp"
|
||||
#include "etl/NFTHelpers.hpp"
|
||||
#include "rpc/RPCHelpers.hpp"
|
||||
#include "util/AsioContextTestFixture.hpp"
|
||||
#include "util/LedgerUtils.hpp"
|
||||
#include "util/MockLedgerHeaderCache.hpp"
|
||||
#include "util/MockPrometheus.hpp"
|
||||
#include "util/Random.hpp"
|
||||
#include "util/StringUtils.hpp"
|
||||
@@ -42,6 +45,7 @@
|
||||
#include <boost/uuid/random_generator.hpp>
|
||||
#include <boost/uuid/uuid.hpp>
|
||||
#include <boost/uuid/uuid_hash.hpp>
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <xrpl/basics/Slice.h>
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
@@ -78,7 +82,7 @@ using namespace prometheus;
|
||||
|
||||
using namespace data::cassandra;
|
||||
|
||||
class BackendCassandraTest : public SyncAsioContextTest, public WithPrometheus {
|
||||
class BackendCassandraTestBase : public SyncAsioContextTest, public WithPrometheus {
|
||||
protected:
|
||||
ClioConfigDefinition cfg_{
|
||||
{"database.type", ConfigValue{ConfigType::String}.defaultValue("cassandra")},
|
||||
@@ -106,17 +110,23 @@ protected:
|
||||
{"read_only", ConfigValue{ConfigType::Boolean}.defaultValue(false)}
|
||||
};
|
||||
|
||||
static constexpr auto kRAWHEADER =
|
||||
"03C3141A01633CD656F91B4EBB5EB89B791BD34DBC8A04BB6F407C5335BC54351E"
|
||||
"DD733898497E809E04074D14D271E4832D7888754F9230800761563A292FA2315A"
|
||||
"6DB6FE30CC5909B285080FCD6773CC883F9FE0EE4D439340AC592AADB973ED3CF5"
|
||||
"3E2232B33EF57CECAC2816E3122816E31A0A00F8377CD95DFA484CFAE282656A58"
|
||||
"CE5AA29652EFFD80AC59CD91416E4E13DBBE";
|
||||
|
||||
ObjectView obj_ = cfg_.getObject("database.cassandra");
|
||||
SettingsProvider settingsProvider_{obj_};
|
||||
|
||||
// recreated for each test
|
||||
data::LedgerCache cache_;
|
||||
std::unique_ptr<BackendInterface> backend_{std::make_unique<CassandraBackend>(settingsProvider_, cache_, false)};
|
||||
|
||||
std::default_random_engine randomEngine_{0};
|
||||
|
||||
public:
|
||||
~BackendCassandraTest() override
|
||||
~BackendCassandraTestBase() override
|
||||
{
|
||||
// drop the keyspace for next test
|
||||
Handle const handle{TestGlobals::instance().backendHost};
|
||||
@@ -125,6 +135,11 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class BackendCassandraTest : public BackendCassandraTestBase {
|
||||
protected:
|
||||
std::unique_ptr<BackendInterface> backend_{std::make_unique<CassandraBackend>(settingsProvider_, cache_, false)};
|
||||
};
|
||||
|
||||
TEST_F(BackendCassandraTest, Basic)
|
||||
{
|
||||
std::atomic_bool done = false;
|
||||
@@ -898,12 +913,6 @@ TEST_F(BackendCassandraTest, CacheIntegration)
|
||||
boost::asio::spawn(ctx_, [this, &done, &work](boost::asio::yield_context yield) {
|
||||
backend_->cache().setFull();
|
||||
|
||||
std::string const rawHeader =
|
||||
"03C3141A01633CD656F91B4EBB5EB89B791BD34DBC8A04BB6F407C5335BC54351E"
|
||||
"DD733898497E809E04074D14D271E4832D7888754F9230800761563A292FA2315A"
|
||||
"6DB6FE30CC5909B285080FCD6773CC883F9FE0EE4D439340AC592AADB973ED3CF5"
|
||||
"3E2232B33EF57CECAC2816E3122816E31A0A00F8377CD95DFA484CFAE282656A58"
|
||||
"CE5AA29652EFFD80AC59CD91416E4E13DBBE";
|
||||
// this account is not related to the above transaction and
|
||||
// metadata
|
||||
std::string const accountHex =
|
||||
@@ -912,7 +921,7 @@ TEST_F(BackendCassandraTest, CacheIntegration)
|
||||
"142252F328CF91263417762570D67220CCB33B1370";
|
||||
std::string const accountIndexHex = "E0311EB450B6177F969B94DBDDA83E99B7A0576ACD9079573876F16C0C004F06";
|
||||
|
||||
std::string rawHeaderBlob = hexStringToBinaryString(rawHeader);
|
||||
std::string rawHeaderBlob = hexStringToBinaryString(kRAWHEADER);
|
||||
std::string accountBlob = hexStringToBinaryString(accountHex);
|
||||
std::string const accountIndexBlob = hexStringToBinaryString(accountIndexHex);
|
||||
ripple::LedgerHeader const lgrInfo = util::deserializeHeader(ripple::makeSlice(rawHeaderBlob));
|
||||
@@ -1294,8 +1303,63 @@ TEST_F(BackendCassandraTest, CacheIntegration)
|
||||
ASSERT_EQ(done, true);
|
||||
}
|
||||
|
||||
class CacheBackendCassandraTest : public BackendCassandraTestBase {
|
||||
protected:
|
||||
using TestBackendType = data::cassandra::BasicCassandraBackend<
|
||||
SettingsProvider,
|
||||
data::cassandra::impl::DefaultExecutionStrategy<>,
|
||||
MockLedgerHeaderCache>;
|
||||
|
||||
std::unique_ptr<BackendInterface> backend_{std::make_unique<TestBackendType>(settingsProvider_, cache_, false)};
|
||||
|
||||
public:
|
||||
MockLedgerHeaderCache&
|
||||
getMockCache()
|
||||
{
|
||||
return dynamic_cast<TestBackendType&>(*backend_).ledgerCache_;
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(CacheBackendCassandraTest, CacheFetchLedgerBySeq)
|
||||
{
|
||||
runSpawn([&](boost::asio::yield_context yield) {
|
||||
auto rawHeaderBlob = hexStringToBinaryString(kRAWHEADER);
|
||||
ripple::LedgerHeader lgrInfo = util::deserializeHeader(ripple::makeSlice(rawHeaderBlob));
|
||||
|
||||
backend_->writeLedger(lgrInfo, std::move(rawHeaderBlob));
|
||||
auto const testLedgerSeq = lgrInfo.seq;
|
||||
ASSERT_TRUE(backend_->finishWrites(lgrInfo.seq));
|
||||
|
||||
EXPECT_CALL(getMockCache(), put(data::FetchLedgerCache::CacheEntry{lgrInfo, testLedgerSeq}));
|
||||
|
||||
{
|
||||
testing::InSequence s;
|
||||
// first time, getSeq doesn't match ledger sequence
|
||||
EXPECT_CALL(getMockCache(), get()).WillOnce(testing::Return(std::nullopt));
|
||||
|
||||
// second time, it would be cached
|
||||
EXPECT_CALL(getMockCache(), get())
|
||||
.WillOnce(testing::Return(data::FetchLedgerCache::CacheEntry{.ledger = lgrInfo, .seq = testLedgerSeq}));
|
||||
}
|
||||
|
||||
{
|
||||
// backend should cache the result of fetchLedgerBySequence
|
||||
auto const ledger = backend_->fetchLedgerBySequence(testLedgerSeq, yield);
|
||||
ASSERT_TRUE(ledger.has_value());
|
||||
EXPECT_EQ(ledger->seq, lgrInfo.seq);
|
||||
}
|
||||
|
||||
{
|
||||
// Second call: should return from cache
|
||||
auto const ledger = backend_->fetchLedgerBySequence(testLedgerSeq, yield);
|
||||
ASSERT_TRUE(ledger.has_value());
|
||||
EXPECT_EQ(ledger->seq, lgrInfo.seq);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
struct BackendCassandraNodeMessageTest : BackendCassandraTest {
|
||||
boost::uuids::random_generator generateUuid{};
|
||||
boost::uuids::random_generator generateUuid;
|
||||
};
|
||||
|
||||
TEST_F(BackendCassandraNodeMessageTest, UpdateFetch)
|
||||
|
||||
@@ -14,6 +14,7 @@ target_sources(
|
||||
data/LedgerCacheTests.cpp
|
||||
data/cassandra/AsyncExecutorTests.cpp
|
||||
data/cassandra/ExecutionStrategyTests.cpp
|
||||
data/cassandra/LedgerHeaderCacheTests.cpp
|
||||
data/cassandra/RetryPolicyTests.cpp
|
||||
data/cassandra/SettingsProviderTests.cpp
|
||||
# Cluster
|
||||
|
||||
70
tests/unit/data/cassandra/LedgerHeaderCacheTests.cpp
Normal file
70
tests/unit/data/cassandra/LedgerHeaderCacheTests.cpp
Normal file
@@ -0,0 +1,70 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of clio: https://github.com/XRPLF/clio
|
||||
Copyright (c) 2025, the clio developers.
|
||||
|
||||
Permission to use, copy, modify, and distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include "data/LedgerHeaderCache.hpp"
|
||||
#include "util/TestObject.hpp"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/protocol/LedgerHeader.h>
|
||||
|
||||
using namespace data;
|
||||
using Test = ::testing::Test;
|
||||
|
||||
constexpr auto kLEDGER_HASH = "4BC50C9B0D8515D3EAAE1E74B29A95804346C491EE1A95BF25E4AAB854A6A652";
|
||||
constinit auto const kLEDGER_HASH2 = "1B8590C01B0006EDFA9ED60296DD052DC5E90F99659B25014D08E1BC983515BC";
|
||||
|
||||
class FetchLedgerCacheTest : public Test {
|
||||
protected:
|
||||
FetchLedgerCache cache_;
|
||||
};
|
||||
|
||||
TEST_F(FetchLedgerCacheTest, DefaultCacheIsEmpty)
|
||||
{
|
||||
auto const result = cache_.get();
|
||||
EXPECT_FALSE(result.has_value());
|
||||
}
|
||||
|
||||
TEST_F(FetchLedgerCacheTest, CanStoreAndRetrieveEntry)
|
||||
{
|
||||
auto const ledger = createLedgerHeader(kLEDGER_HASH, 42);
|
||||
FetchLedgerCache::CacheEntry entry{.ledger = ledger, .seq = 42};
|
||||
|
||||
cache_.put(entry);
|
||||
auto const result = cache_.get();
|
||||
|
||||
ASSERT_TRUE(result.has_value());
|
||||
EXPECT_EQ(result.value(), entry);
|
||||
}
|
||||
|
||||
TEST_F(FetchLedgerCacheTest, PutOverwritesPreviousEntry)
|
||||
{
|
||||
auto const ledger1 = createLedgerHeader(kLEDGER_HASH, 1);
|
||||
auto const ledger2 = createLedgerHeader(kLEDGER_HASH2, 2);
|
||||
|
||||
FetchLedgerCache::CacheEntry entry1{.ledger = ledger1, .seq = 1};
|
||||
FetchLedgerCache::CacheEntry entry2{.ledger = ledger2, .seq = 2};
|
||||
|
||||
cache_.put(entry1);
|
||||
cache_.put(entry2);
|
||||
|
||||
auto const result = cache_.get();
|
||||
ASSERT_TRUE(result.has_value());
|
||||
EXPECT_EQ(result.value(), entry2);
|
||||
}
|
||||
Reference in New Issue
Block a user