rippled
Loading...
Searching...
No Matches
LedgerPersistence.cpp
1#include <xrpld/app/ledger/LedgerPersistence.h>
2
3#include <xrpl/beast/utility/instrumentation.h>
4#include <xrpl/core/HashRouter.h>
5#include <xrpl/core/JobQueue.h>
6#include <xrpl/core/ServiceRegistry.h>
7#include <xrpl/json/to_string.h>
8#include <xrpl/ledger/PendingSaves.h>
9#include <xrpl/protocol/Indexes.h>
10#include <xrpl/rdb/RelationalDatabase.h>
11
12namespace xrpl {
13
14static bool
16 ServiceRegistry& registry,
18 bool current)
19{
20 auto j = registry.getJournal("Ledger");
21 auto seq = ledger->header().seq;
22 if (!registry.getPendingSaves().startWork(seq))
23 {
24 // The save was completed synchronously
25 JLOG(j.debug()) << "Save aborted";
26 return true;
27 }
28
29 auto& db = registry.getRelationalDatabase();
30
31 auto const res = db.saveValidatedLedger(ledger, current);
32
33 // Clients can now trust the database for
34 // information about this ledger sequence.
35 registry.getPendingSaves().finishWork(seq);
36 return res;
37}
38
39bool
41 ServiceRegistry& registry,
43 bool isSynchronous,
44 bool isCurrent)
45{
46 if (!registry.getHashRouter().setFlags(ledger->header().hash, HashRouterFlags::SAVED))
47 {
48 // We have tried to save this ledger recently
49 auto stream = registry.getJournal("Ledger").debug();
50 JLOG(stream) << "Double pend save for " << ledger->header().seq;
51
52 if (!isSynchronous || !registry.getPendingSaves().pending(ledger->header().seq))
53 {
54 // Either we don't need it to be finished
55 // or it is finished
56 return true;
57 }
58 }
59
60 XRPL_ASSERT(ledger->isImmutable(), "xrpl::pendSaveValidated : immutable ledger");
61
62 if (!registry.getPendingSaves().shouldWork(ledger->header().seq, isSynchronous))
63 {
64 auto stream = registry.getJournal("Ledger").debug();
65 JLOG(stream) << "Pend save with seq in pending saves " << ledger->header().seq;
66
67 return true;
68 }
69
70 // See if we can use the JobQueue.
71 if (!isSynchronous &&
72 registry.getJobQueue().addJob(
74 "Pub" + std::to_string(ledger->seq()),
75 [&registry, ledger, isCurrent]() { saveValidatedLedger(registry, ledger, isCurrent); }))
76 {
77 return true;
78 }
79
80 // The JobQueue won't do the Job. Do the save synchronously.
81 return saveValidatedLedger(registry, ledger, isCurrent);
82}
83
86 LedgerHeader const& info,
87 Rules const& rules,
88 Fees const& fees,
89 ServiceRegistry& registry,
90 bool acquire)
91{
92 bool loaded = false;
93 auto ledger = std::make_shared<Ledger>(
94 info,
95 loaded,
96 acquire,
97 rules,
98 fees,
99 registry.getNodeFamily(),
100 registry.getJournal("Ledger"));
101
102 if (!loaded)
103 ledger.reset();
104
105 return ledger;
106}
107
108static void
110{
111 if (!ledger)
112 return;
113
114 XRPL_ASSERT(
115 ledger->header().seq < XRP_LEDGER_EARLIEST_FEES || ledger->read(keylet::fees()),
116 "xrpl::finishLoadByIndexOrHash : valid ledger fees");
117 ledger->setImmutable();
118
119 JLOG(j.trace()) << "Loaded ledger: " << to_string(ledger->header().hash);
120
121 ledger->setFull();
122}
123
125getLatestLedger(Rules const& rules, Fees const& fees, ServiceRegistry& registry)
126{
128 if (!info)
129 return {std::shared_ptr<Ledger>(), {}, {}};
130 return {loadLedgerHelper(*info, rules, fees, registry, true), info->seq, info->hash};
131}
132
135 std::uint32_t ledgerIndex,
136 Rules const& rules,
137 Fees const& fees,
138 ServiceRegistry& registry,
139 bool acquire)
140{
142 registry.getRelationalDatabase().getLedgerInfoByIndex(ledgerIndex))
143 {
144 std::shared_ptr<Ledger> ledger = loadLedgerHelper(*info, rules, fees, registry, acquire);
145 finishLoadByIndexOrHash(ledger, registry.getJournal("Ledger"));
146 return ledger;
147 }
148 return {};
149}
150
153 uint256 const& ledgerHash,
154 Rules const& rules,
155 Fees const& fees,
156 ServiceRegistry& registry,
157 bool acquire)
158{
160 registry.getRelationalDatabase().getLedgerInfoByHash(ledgerHash))
161 {
162 std::shared_ptr<Ledger> ledger = loadLedgerHelper(*info, rules, fees, registry, acquire);
163 finishLoadByIndexOrHash(ledger, registry.getJournal("Ledger"));
164 XRPL_ASSERT(
165 !ledger || ledger->header().hash == ledgerHash,
166 "xrpl::loadByHash : ledger hash match if loaded");
167 return ledger;
168 }
169 return {};
170}
171
172} // namespace xrpl
A generic endpoint for log messages.
Definition Journal.h:40
Stream debug() const
Definition Journal.h:301
Stream trace() const
Severity stream access functions.
Definition Journal.h:295
bool setFlags(uint256 const &key, HashRouterFlags flags)
Set the flags on a hash.
bool addJob(JobType type, std::string const &name, JobHandler &&jobHandler)
Adds a job to the JobQueue.
Definition JobQueue.h:147
void finishWork(LedgerIndex seq)
Finish working on a ledger.
bool shouldWork(LedgerIndex seq, bool isSynchronous)
Check if a ledger should be dispatched.
bool startWork(LedgerIndex seq)
Start working on a ledger.
bool pending(LedgerIndex seq)
Return true if a ledger is in the progress of being saved.
virtual bool saveValidatedLedger(std::shared_ptr< Ledger const > const &ledger, bool current)=0
saveValidatedLedger Saves a ledger into the database.
virtual std::optional< LedgerHeader > getNewestLedgerInfo()=0
getNewestLedgerInfo Returns the info of the newest saved ledger.
virtual std::optional< LedgerHeader > getLedgerInfoByHash(uint256 const &ledgerHash)=0
getLedgerInfoByHash Returns the info of the ledger with given hash.
virtual std::optional< LedgerHeader > getLedgerInfoByIndex(LedgerIndex ledgerSeq)=0
getLedgerInfoByIndex Returns a ledger by its sequence.
Rules controlling protocol behavior.
Definition Rules.h:18
Service registry for dependency injection.
virtual PendingSaves & getPendingSaves()=0
virtual JobQueue & getJobQueue()=0
virtual RelationalDatabase & getRelationalDatabase()=0
virtual beast::Journal getJournal(std::string const &name)=0
virtual HashRouter & getHashRouter()=0
virtual Family & getNodeFamily()=0
T is_same_v
Keylet const & fees() noexcept
The (fixed) index of the object containing the ledger fees.
Definition Indexes.cpp:200
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
static constexpr std::uint32_t XRP_LEDGER_EARLIEST_FEES
The XRP Ledger mainnet's earliest ledger with a FeeSettings object.
std::tuple< std::shared_ptr< Ledger >, std::uint32_t, uint256 > getLatestLedger(Rules const &rules, Fees const &fees, ServiceRegistry &registry)
Fetch the ledger with the highest sequence contained in the database.
bool isCurrent(ValidationParms const &p, NetClock::time_point now, NetClock::time_point signTime, NetClock::time_point seenTime)
Whether a validation is still current.
bool pendSaveValidated(ServiceRegistry &registry, std::shared_ptr< Ledger const > const &ledger, bool isSynchronous, bool isCurrent)
Save, or arrange to save, a fully-validated ledger.
std::string to_string(base_uint< Bits, Tag > const &a)
Definition base_uint.h:602
std::shared_ptr< Ledger > loadLedgerHelper(LedgerHeader const &info, Rules const &rules, Fees const &fees, ServiceRegistry &registry, bool acquire)
Make ledger using info loaded from database.
std::shared_ptr< Ledger > loadByIndex(std::uint32_t ledgerIndex, Rules const &rules, Fees const &fees, ServiceRegistry &registry, bool acquire)
Load a ledger by its sequence number.
@ current
This was a new validation and was added.
base_uint< 256 > uint256
Definition base_uint.h:531
static bool saveValidatedLedger(ServiceRegistry &registry, std::shared_ptr< Ledger const > const &ledger, bool current)
@ jtPUBLEDGER
Definition Job.h:47
@ jtPUBOLDLEDGER
Definition Job.h:23
std::shared_ptr< Ledger > loadByHash(uint256 const &ledgerHash, Rules const &rules, Fees const &fees, ServiceRegistry &registry, bool acquire)
Load a ledger by its hash.
static void finishLoadByIndexOrHash(std::shared_ptr< Ledger > const &ledger, beast::Journal j)
Reflects the fee settings for a particular ledger.
Information about the notional ledger backing the view.
T to_string(T... args)