1#include <xrpld/app/ledger/LedgerCleaner.h>
3#include <xrpld/app/ledger/InboundLedger.h>
4#include <xrpld/app/ledger/InboundLedgers.h>
5#include <xrpld/app/ledger/LedgerMaster.h>
6#include <xrpld/app/ledger/LedgerPersistence.h>
7#include <xrpld/app/main/Application.h>
9#include <xrpl/basics/Log.h>
10#include <xrpl/basics/contract.h>
11#include <xrpl/beast/core/CurrentThreadName.h>
12#include <xrpl/beast/utility/Journal.h>
13#include <xrpl/beast/utility/PropertyStream.h>
14#include <xrpl/beast/utility/Zero.h>
15#include <xrpl/beast/utility/instrumentation.h>
16#include <xrpl/json/json_value.h>
17#include <xrpl/ledger/ReadView.h>
18#include <xrpl/ledger/View.h>
19#include <xrpl/protocol/Protocol.h>
20#include <xrpl/protocol/RippleLedgerHash.h>
21#include <xrpl/protocol/Rules.h>
22#include <xrpl/protocol/jss.h>
23#include <xrpl/server/LoadFeeTrack.h>
24#include <xrpl/shamap/SHAMapMissingNode.h>
87 logicError(
"LedgerCleanerImp::stop not called.");
99 JLOG(
j_.info()) <<
"Stopping";
121 map[
"status"] =
"idle";
125 map[
"status"] =
"running";
128 map[
"check_nodes"] =
checkNodes_ ?
"true" :
"false";
129 map[
"fix_txns"] =
fixTxns_ ?
"true" :
"false";
146 app_.getLedgerMaster().getFullValidatedRange(minRange, maxRange);
196 if (params.
isMember(jss::max_ledger))
199 if (params.
isMember(jss::min_ledger))
208 if (params.
isMember(jss::check_nodes))
229 JLOG(
j_.debug()) <<
"Started";
256 JLOG(
j_.warn()) <<
"Ledger #" << ledger->header().seq <<
": " << mn.
what();
257 app_.getInboundLedgers().acquire(
260 return hash ? *hash : beast::kZero;
277 auto nodeLedger =
app_.getInboundLedgers().acquire(
281 JLOG(
j_.debug()) <<
"Ledger " << ledgerIndex <<
" not available";
282 app_.getLedgerMaster().clearLedger(ledgerIndex);
283 app_.getInboundLedgers().acquire(
288 Rules const rules{
app_.config().features};
289 Fees const fees =
app_.config().fees.toFees();
291 if (!dbLedger || (dbLedger->header().hash != ledgerHash) ||
292 (dbLedger->header().parentHash != nodeLedger->header().parentHash))
295 JLOG(
j_.debug()) <<
"Ledger " << ledgerIndex <<
" mismatches SQL DB";
299 if (!
app_.getLedgerMaster().fixIndex(ledgerIndex, ledgerHash))
301 JLOG(
j_.debug()) <<
"ledger " << ledgerIndex <<
" had wrong entry in history";
305 if (doNodes && !nodeLedger->walkLedger(
app_.getJournal(
"Ledger")))
307 JLOG(
j_.debug()) <<
"Ledger " << ledgerIndex <<
" is missing nodes";
308 app_.getLedgerMaster().clearLedger(ledgerIndex);
309 app_.getInboundLedgers().acquire(
316 JLOG(
j_.debug()) <<
"Failed to save ledger " << ledgerIndex;
333 if (!referenceLedger || (referenceLedger->header().seq < ledgerIndex))
335 referenceLedger =
app_.getLedgerMaster().getValidatedLedger();
336 if (!referenceLedger)
338 JLOG(
j_.warn()) <<
"No validated ledger";
343 if (referenceLedger->header().seq >= ledgerIndex)
356 XRPL_ASSERT(nonzero,
"xrpl::LedgerCleanerImp::getHash : nonzero hash");
361 referenceLedger =
app_.getInboundLedgers().acquire(
370 JLOG(
j_.warn()) <<
"Validated ledger is prior to target ledger";
380 auto shouldExit = [
this] {
387 while (!shouldExit())
391 bool doNodes =
false;
394 if (
app_.getFeeTrack().isLoadedLocal())
396 JLOG(
j_.debug()) <<
"Waiting for load to subside";
413 ledgerHash =
getHash(ledgerIndex, goodLedger);
418 JLOG(
j_.info()) <<
"Unable to get hash for ledger " << ledgerIndex;
421 else if (!
doLedger(ledgerIndex, ledgerHash, doNodes, doTxns))
423 JLOG(
j_.info()) <<
"Failed to process ledger " << ledgerIndex;
A generic endpoint for log messages.
bool isMember(char const *key) const
Return true if the object has a member named key.
std::condition_variable wakeup_
LedgerHash getHash(LedgerIndex const &ledgerIndex, std::shared_ptr< ReadView const > &referenceLedger)
Returns the hash of the specified ledger.
~LedgerCleanerImp() override
void clean(json::Value const ¶ms) override
Start a long running task to clean the ledger.
void doLedgerCleaner()
Run the ledger cleaner.
void onWrite(beast::PropertyStream::Map &map) override
Subclass override.
bool doLedger(LedgerIndex const &ledgerIndex, LedgerHash const &ledgerHash, bool doNodes, bool doTxns)
Process a single ledger.
LedgerCleanerImp(Application &app, beast::Journal journal)
LedgerHash getLedgerHash(std::shared_ptr< ReadView const > &ledger, LedgerIndex index)
Rules controlling protocol behavior.
void setCurrentThreadName(std::string_view newThreadName)
Changes the name of the caller thread.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
bool pendSaveValidated(ServiceRegistry ®istry, std::shared_ptr< Ledger const > const &ledger, bool isSynchronous, bool isCurrent)
Save, or arrange to save, a fully-validated ledger.
std::uint32_t LedgerIndex
A ledger index.
std::shared_ptr< Ledger > loadByIndex(std::uint32_t ledgerIndex, Rules const &rules, Fees const &fees, ServiceRegistry ®istry, bool acquire)
Load a ledger by its sequence number.
void logicError(std::string const &how) noexcept
Called when faulty logic causes a broken invariant.
LedgerIndex getCandidateLedger(LedgerIndex requested)
Find a ledger index from which we could easily get the requested ledger.
std::optional< uint256 > hashOfSeq(ReadView const &ledger, LedgerIndex seq, beast::Journal journal)
Return the hash of a ledger by sequence.
std::unique_ptr< LedgerCleaner > makeLedgerCleaner(Application &app, beast::Journal journal)
Reflects the fee settings for a particular ledger.