20#include <xrpld/app/ledger/InboundLedgers.h>
21#include <xrpld/app/ledger/LedgerMaster.h>
22#include <xrpld/app/main/Application.h>
23#include <xrpld/app/misc/NetworkOPs.h>
24#include <xrpld/core/JobQueue.h>
25#include <xrpld/perflog/PerfLog.h>
26#include <xrpl/basics/CanProcess.h>
27#include <xrpl/basics/DecayingSample.h>
28#include <xrpl/basics/Log.h>
29#include <xrpl/beast/container/aged_map.h>
30#include <xrpl/beast/core/LexicalCast.h>
31#include <xrpl/protocol/jss.h>
60 ,
j_(app.journal(
"InboundLedger"))
63 ,
mCounter(collector->make_counter(
"ledger_fetches"))
78 "ripple::InboundLedgersImp::acquire::doAcquire : nonzero hash");
82 if (!needNetworkLedger)
92 ss <<
"InboundLedger::acquire: "
93 <<
"Request: " <<
to_string(hash) <<
", " << seq
94 <<
" NeedNetworkLedger: " << (needNetworkLedger ?
"yes" :
"no")
96 <<
" Should acquire: " << (
shouldAcquire ?
"true." :
"false.");
104 bool const shouldBroadcast = [&]() {
121 bool const nearFuture =
122 (seq > validSeq) && (seq < validSeq + lagLeeway);
127 bool const consensus =
129 ss <<
" Evaluating whether to broadcast requests to peers"
130 <<
". full: " << (isFull ?
"true" :
"false")
131 <<
". ledger sequence " << seq
132 <<
". Valid sequence: " << validSeq
133 <<
". Lag leeway: " << lagLeeway
134 <<
". request for near future ledger: "
135 << (nearFuture ?
"true" :
"false")
136 <<
". Consensus: " << (consensus ?
"true" :
"false");
151 ss <<
". Would broadcast to peers? "
152 << (shouldBroadcast ?
"true." :
"false.");
156 JLOG(
j_.
debug()) <<
"Abort(rule): " << ss.
str();
166 JLOG(
j_.
debug()) <<
"Abort(stopping): " << ss.
str();
174 inbound = it->second;
178 inbound = std::make_shared<InboundLedger>(
190 ss <<
" IsNew: " << (isNew ?
"true" :
"false");
192 if (inbound->isFailed())
194 JLOG(
j_.
debug()) <<
"Abort(failed): " << ss.
str();
199 inbound->update(seq);
201 if (!inbound->isComplete())
203 JLOG(
j_.
debug()) <<
"InProgress: " << ss.
str();
208 return inbound->getLedger();
210 using namespace std::chrono_literals;
212 doAcquire,
"InboundLedgersImp::acquire", 500ms,
j_);
230 <<
"Exception thrown for acquiring new inbound ledger "
231 << hash <<
": " << e.
what();
235 JLOG(
j_.
warn()) <<
"Unknown exception thrown for acquiring new "
247 "ripple::InboundLedgersImp::find : nonzero input");
284 if (
auto ledger =
find(hash))
286 JLOG(
j_.
trace()) <<
"Got data (" << packet->nodes().size()
287 <<
") for acquiring ledger: " << hash;
300 JLOG(
j_.
trace()) <<
"Got data for ledger " << hash
301 <<
" which we're no longer acquiring";
305 if (packet->type() == protocol::liAS_NODE)
345 for (
int i = 0; i < packet_ptr->nodes().size(); ++i)
347 auto const& node = packet_ptr->nodes(i);
349 if (!node.has_nodeid() || !node.has_nodedata())
359 newNode->serializeWithPrefix(s);
362 newNode->getHash().as_uint256(),
363 std::make_shared<Blob>(s.
begin(), s.
end()));
411 "ripple::InboundLedgersImp::getInfo : non-null ledger");
419 ret[
to_string(it.first)][jss::failed] =
true;
423 for (
auto const& it : acqs)
430 ret[
to_string(it.first)] = it.second->getJson(0);
448 "ripple::InboundLedgersImp::gotFetchPack : non-null "
454 for (
auto const&
acquire : acquires)
478 auto const la = it->second->getLastAction();
502 <<
"Swept " << stuffToSweep.
size() <<
" out of " << total
503 <<
" inbound ledgers. Duration: "
504 << std::chrono::duration_cast<std::chrono::milliseconds>(
554 return std::make_unique<InboundLedgersImp>(
RAII class to check if an Item is already being processed on another thread, as indicated by it's pre...
A generic endpoint for log messages.
Stream trace() const
Severity stream access functions.
virtual time_point now() const =0
Returns the current time.
Associative container where each element is also indexed by time.
A metric for measuring an integral value.
virtual JobQueue & getJobQueue()=0
virtual NetworkOPs & getOPs()=0
virtual LedgerMaster & getLedgerMaster()=0
Sampling function using exponential decay to provide a continuous value.
double value(time_point now)
void add(double value, time_point now)
void clearFailures() override
DecayWindow< 30, clock_type > fetchRate_
std::size_t cacheSize() override
std::recursive_mutex mLock
void gotFetchPack() override
Json::Value getInfo() override
void logFailure(uint256 const &h, std::uint32_t seq) override
void gotStaleData(std::shared_ptr< protocol::TMLedgerData > packet_ptr) override
We got some data for a ledger we are no longer acquiring Since we paid the price to receive it,...
beast::aged_map< uint256, std::uint32_t > mRecentFailures
std::set< uint256 > pendingAcquires_
beast::insight::Counter mCounter
std::unique_ptr< PeerSetBuilder > mPeerSetBuilder
std::shared_ptr< Ledger const > acquire(uint256 const &hash, std::uint32_t seq, InboundLedger::Reason reason) override
std::mutex fetchRateMutex_
void acquireAsync(uint256 const &hash, std::uint32_t seq, InboundLedger::Reason reason) override
InboundLedgersImp(Application &app, clock_type &clock, beast::insight::Collector::ptr const &collector, std::unique_ptr< PeerSetBuilder > peerSetBuilder)
static constexpr std::chrono::minutes const kReacquireInterval
std::size_t fetchRate() override
Returns the rate of historical ledger fetches per minute.
std::shared_ptr< InboundLedger > find(uint256 const &hash) override
bool gotLedgerData(LedgerHash const &hash, std::shared_ptr< Peer > peer, std::shared_ptr< protocol::TMLedgerData > packet) override
We received a TMLedgerData from a peer.
void onLedgerFetched() override
Called when a complete ledger is obtained.
std::mutex acquiresMutex_
bool isFailure(uint256 const &h) override
Manages the lifetime of inbound ledgers.
bool addJob(JobType type, std::string const &name, JobHandler &&jobHandler)
Adds a job to the JobQueue.
void addFetchPack(uint256 const &hash, std::shared_ptr< Blob > data)
LedgerIndex getValidLedgerIndex()
virtual bool isNeedNetworkLedger()=0
static std::shared_ptr< SHAMapTreeNode > makeFromWire(Slice rawNode)
@ objectValue
object value (collection of name/value pairs).
std::enable_if< is_aged_container< AgedContainer >::value, std::size_t >::type expire(AgedContainer &c, std::chrono::duration< Rep, Period > const &age)
Expire aged container items past the specified age.
auto measureDurationAndLog(Func &&func, const std::string &actionDescription, std::chrono::duration< Rep, Period > maxDelay, const beast::Journal &journal)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
static bool shouldAcquire(std::uint32_t const currentLedger, std::uint32_t const ledgerHistory, std::optional< LedgerIndex > const minimumOnline, std::uint32_t const candidateLedger, beast::Journal j)
std::unique_ptr< PeerSetBuilder > make_PeerSetBuilder(Application &app)
std::unique_ptr< InboundLedgers > make_InboundLedgers(Application &app, InboundLedgers::clock_type &clock, beast::insight::Collector::ptr const &collector)
std::enable_if_t< std::is_same< T, char >::value||std::is_same< T, unsigned char >::value, Slice > makeSlice(std::array< T, N > const &a)
std::string to_string(base_uint< Bits, Tag > const &a)