Compare commits

...

1 Commits

Author SHA1 Message Date
Denis Angell
73b15f5c39 fix: Keep FullBelowCache entries until the first validated ledger 2026-10-08 01:26:24 -04:00
4 changed files with 86 additions and 5 deletions

View File

@@ -71,6 +71,7 @@ test.app > xrpld.app
test.app > xrpld.core
test.app > xrpld.overlay
test.app > xrpld.rpc
test.app > xrpld.shamap
test.app > xrpl.json
test.app > xrpl.ledger
test.app > xrpl.nodestore

View File

@@ -0,0 +1,54 @@
#include <test/jtx/Env.h>
#include <xrpld/app/ledger/LedgerMaster.h>
#include <xrpld/app/main/Application.h>
#include <xrpld/app/main/Tuning.h>
#include <xrpld/shamap/NodeFamily.h>
#include <xrpl/basics/base_uint.h>
#include <xrpl/basics/chrono.h>
#include <xrpl/beast/unit_test/suite.h>
#include <chrono>
namespace xrpl::test {
class NodeFamily_test : public beast::unit_test::Suite
{
void
testFullBelowKeptUntilValidated()
{
testcase("FullBelowCache kept until the first validated ledger");
using namespace std::chrono_literals;
jtx::Env env{*this};
TestStopwatch clock;
NodeFamily family(env.app(), env.app().getCollectorManager(), clock);
auto const fullBelow = family.getFullBelowCache();
fullBelow->insert(UInt256{1});
clock.advance(kFullBelowExpiration + 1s);
family.sweep(false);
BEAST_EXPECT(fullBelow->size() == 1);
family.sweep(true);
BEAST_EXPECT(fullBelow->size() == 0);
// A standalone Env has a validated ledger, so sweep() expires the entry.
BEAST_EXPECT(env.app().getLedgerMaster().haveValidated());
fullBelow->insert(UInt256{2});
clock.advance(kFullBelowExpiration + 1s);
family.sweep();
BEAST_EXPECT(fullBelow->size() == 0);
}
public:
void
run() override
{
testFullBelowKeptUntilValidated();
}
};
BEAST_DEFINE_TESTSUITE(NodeFamily, app, xrpl);
} // namespace xrpl::test

View File

@@ -21,14 +21,14 @@
namespace xrpl {
NodeFamily::NodeFamily(Application& app, CollectorManager& cm)
NodeFamily::NodeFamily(Application& app, CollectorManager& cm, Stopwatch& clock)
: app_(app)
, db_(app.getNodeStore())
, j_(app.getJournal("NodeFamily"))
, fbCache_(
std::make_shared<FullBelowCache>(
"Node family full below cache",
stopwatch(),
clock,
app.getJournal("NodeFamilyFulLBelowCache"),
cm.collector(),
kFullBelowTargetSize,
@@ -38,7 +38,7 @@ NodeFamily::NodeFamily(Application& app, CollectorManager& cm)
"Node family tree node cache",
app.config().getValueFor(SizedItem::TreeCacheSize),
std::chrono::seconds(app.config().getValueFor(SizedItem::TreeCacheAge)),
stopwatch(),
clock,
j_))
{
}
@@ -46,7 +46,17 @@ NodeFamily::NodeFamily(Application& app, CollectorManager& cm)
void
NodeFamily::sweep()
{
fbCache_->sweep();
sweep(app_.getLedgerMaster().haveValidated());
}
void
NodeFamily::sweep(bool haveValidated)
{
// Keep FullBelowCache entries until a ledger is validated: a first sync grows the cache past
// kFullBelowTargetSize, and TaggedCache::sweep then expires entries far younger than
// kFullBelowExpiration.
if (haveValidated)
fbCache_->sweep();
tnCache_->sweep();
}

View File

@@ -3,6 +3,7 @@
#include <xrpld/app/main/CollectorManager.h>
#include <xrpl/basics/base_uint.h>
#include <xrpl/basics/chrono.h>
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/nodestore/Database.h>
#include <xrpl/protocol/Protocol.h>
@@ -31,7 +32,12 @@ public:
NodeFamily&
operator=(NodeFamily&&) = delete;
NodeFamily(Application& app, CollectorManager& cm);
/**
* @param app The application whose node store and ledger master the family uses.
* @param cm The collector for cache statistics.
* @param clock The clock the FullBelowCache and TreeNodeCache age their entries by.
*/
NodeFamily(Application& app, CollectorManager& cm, Stopwatch& clock = stopwatch());
node_store::Database&
db() override
@@ -66,6 +72,16 @@ public:
void
sweep() override;
/**
* Sweep the TreeNodeCache, and the FullBelowCache only when haveValidated is true, so a
* first sync keeps the FullBelowCache entries it has built.
*
* @param haveValidated Whether the node has a validated ledger
* (LedgerMaster::haveValidated()).
*/
void
sweep(bool haveValidated);
void
reset() override;