20#include <xrpld/app/ledger/LedgerReplayer.h>
21#include <xrpld/app/ledger/detail/LedgerDeltaAcquire.h>
22#include <xrpld/app/ledger/detail/SkipListAcquire.h>
23#include <xrpld/core/JobQueue.h>
32 , inboundLedgers_(inboundLedgers)
33 , peerSetBuilder_(
std::move(peerSetBuilder))
34 , j_(app.journal(
"LedgerReplayer"))
47 uint256 const& finishLedgerHash,
51 finishLedgerHash.
isNonZero() && totalNumLedgers > 0 &&
53 "ripple::LedgerReplayer::replay : valid inputs");
56 r, finishLedgerHash, totalNumLedgers);
60 bool newSkipList =
false;
67 JLOG(
j_.
info()) <<
"Too many replay tasks, dropping new task "
72 for (
auto const& t :
tasks_)
78 <<
" ledgers merged into an existing task.";
82 JLOG(
j_.
info()) <<
"Replay " << totalNumLedgers
83 <<
" ledgers. Finish ledger hash "
88 skipList = i->second.lock();
92 skipList = std::make_shared<SkipListAcquire>(
101 task = std::make_shared<LedgerReplayTask>(
122 auto const& parameter = task->getTaskParameter();
123 JLOG(
j_.
trace()) <<
"Creating " << parameter.totalLedgers_ - 1 <<
" deltas";
124 if (parameter.totalLedgers_ > 1)
127 parameter.skipList_.begin(),
128 parameter.skipList_.end(),
129 parameter.startHash_);
130 if (skipListItem == parameter.skipList_.end() ||
131 ++skipListItem == parameter.skipList_.end())
133 JLOG(
j_.
error()) <<
"Task parameter error when creating deltas "
134 << parameter.finishHash_;
139 seq <= parameter.finishSeq_ &&
140 skipListItem != parameter.skipList_.end();
141 ++seq, ++skipListItem)
144 bool newDelta =
false;
149 auto i =
deltas_.find(*skipListItem);
151 delta = i->second.lock();
155 delta = std::make_shared<LedgerDeltaAcquire>(
161 deltas_[*skipListItem] = delta;
166 task->addDelta(delta);
176 boost::intrusive_ptr<SHAMapItem const>
const& item)
184 skipList = i->second.lock();
193 skipList->processData(info.
seq, item);
207 delta = i->second.lock();
216 delta->processData(info, std::move(txns));
225 JLOG(
j_.
debug()) <<
"Sweeping, LedgerReplayer has " <<
tasks_.size()
227 <<
" skipLists, and " <<
deltas_.size() <<
" deltas.";
233 [
this](
auto const& t) ->
bool {
236 JLOG(j_.debug()) <<
"Sweep task "
237 << t->getTaskParameter().finishHash_;
244 auto removeCannotLocked = [](
auto& subTasks) {
245 for (
auto it = subTasks.begin(); it != subTasks.end();)
247 if (
auto item = it->second.lock(); !item)
249 it = subTasks.erase(it);
258 JLOG(j_.
debug()) <<
" LedgerReplayer sweep lock duration "
259 << std::chrono::duration_cast<std::chrono::milliseconds>(
266LedgerReplayer::stop()
268 JLOG(j_.
info()) <<
"Stopping...";
272 tasks_.begin(), tasks_.end(), [](
auto& i) { i->cancel(); });
274 auto lockAndCancel = [](
auto& i) {
275 if (
auto sptr = i.second.lock(); sptr)
280 std::for_each(skipLists_.begin(), skipLists_.end(), lockAndCancel);
282 std::for_each(deltas_.begin(), deltas_.end(), lockAndCancel);
286 JLOG(j_.
info()) <<
"Stopped";
Stream trace() const
Severity stream access functions.
virtual bool isStopping() const =0
Manages the lifetime of inbound ledgers.
bool canMergeInto(TaskParameter const &existingTask) const
check if this task can be merged into an existing task
void gotReplayDelta(LedgerInfo const &info, std::map< std::uint32_t, std::shared_ptr< STTx const > > &&txns)
Process a ledger delta (extracted from a TMReplayDeltaResponse message)
void createDeltas(std::shared_ptr< LedgerReplayTask > task)
Create LedgerDeltaAcquire subtasks for the LedgerReplayTask task.
void sweep()
Remove completed tasks.
std::vector< std::shared_ptr< LedgerReplayTask > > tasks_
std::unique_ptr< PeerSetBuilder > peerSetBuilder_
LedgerReplayer(Application &app, InboundLedgers &inboundLedgers, std::unique_ptr< PeerSetBuilder > peerSetBuilder)
void gotSkipList(LedgerInfo const &info, boost::intrusive_ptr< SHAMapItem const > const &data)
Process a skip list (extracted from a TMProofPathResponse message)
hash_map< uint256, std::weak_ptr< SkipListAcquire > > skipLists_
void replay(InboundLedger::Reason r, uint256 const &finishLedgerHash, std::uint32_t totalNumLedgers)
Replay a range of ledgers.
InboundLedgers & inboundLedgers_
hash_map< uint256, std::weak_ptr< LedgerDeltaAcquire > > deltas_
std::uint32_t constexpr MAX_TASK_SIZE
std::uint32_t constexpr MAX_TASKS
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.