xrpld
Loading...
Searching...
No Matches
LedgerPersistence.cpp
1#include <xrpld/app/ledger/LedgerPersistence.h>
2
3#include <xrpl/basics/Log.h>
4#include <xrpl/basics/base_uint.h>
5#include <xrpl/beast/utility/instrumentation.h>
6#include <xrpl/core/HashRouter.h>
7#include <xrpl/core/Job.h>
8#include <xrpl/core/JobQueue.h>
9#include <xrpl/core/ServiceRegistry.h>
10#include <xrpl/ledger/PendingSaves.h>
11#include <xrpl/ledger/entries/FeeSettingsEntry.h>
12#include <xrpl/protocol/Indexes.h> // IWYU pragma: keep
13#include <xrpl/protocol/Rules.h>
14#include <xrpl/protocol/SystemParameters.h> // IWYU pragma: keep
15#include <xrpl/rdb/RelationalDatabase.h>
16
17#include <cstdint>
18#include <memory>
19#include <optional>
20#include <string>
21#include <tuple>
22
23namespace xrpl {
24
25static bool
27 ServiceRegistry& registry,
29 bool current)
30{
31 auto j = registry.getJournal("Ledger");
32 auto seq = ledger->header().seq;
33 if (!registry.getPendingSaves().startWork(seq))
34 {
35 // The save was completed synchronously
36 JLOG(j.debug()) << "Save aborted";
37 return true;
38 }
39
40 auto& db = registry.getRelationalDatabase();
41
42 auto const res = db.saveValidatedLedger(ledger, current);
43
44 // Clients can now trust the database for
45 // information about this ledger sequence.
46 registry.getPendingSaves().finishWork(seq);
47 return res;
48}
49
50bool
52 ServiceRegistry& registry,
54 bool isSynchronous,
55 bool isCurrent)
56{
57 if (!registry.getHashRouter().setFlags(ledger->header().hash, HashRouterFlags::SAVED))
58 {
59 // We have tried to save this ledger recently
60 auto stream = registry.getJournal("Ledger").debug();
61 JLOG(stream) << "Double pend save for " << ledger->header().seq;
62
63 if (!isSynchronous || !registry.getPendingSaves().pending(ledger->header().seq))
64 {
65 // Either we don't need it to be finished
66 // or it is finished
67 return true;
68 }
69 }
70
71 XRPL_ASSERT(ledger->isImmutable(), "xrpl::pendSaveValidated : immutable ledger");
72
73 if (!registry.getPendingSaves().shouldWork(ledger->header().seq, isSynchronous))
74 {
75 auto stream = registry.getJournal("Ledger").debug();
76 JLOG(stream) << "Pend save with seq in pending saves " << ledger->header().seq;
77
78 return true;
79 }
80
81 // See if we can use the JobQueue.
82 if (!isSynchronous &&
83 registry.getJobQueue().addJob(
85 "Pub" + std::to_string(ledger->seq()),
86 [&registry, ledger, isCurrent]() { saveValidatedLedger(registry, ledger, isCurrent); }))
87 {
88 return true;
89 }
90
91 // The JobQueue won't do the Job. Do the save synchronously.
92 return saveValidatedLedger(registry, ledger, isCurrent);
93}
94
97 LedgerHeader const& info,
98 Rules const& rules,
99 Fees const& fees,
100 ServiceRegistry& registry,
101 bool acquire)
102{
103 bool loaded = false;
104 auto ledger = std::make_shared<Ledger>(
105 info,
106 loaded,
107 acquire,
108 rules,
109 fees,
110 registry.getNodeFamily(),
111 registry.getJournal("Ledger"));
112
113 if (!loaded)
114 ledger.reset();
115
116 return ledger;
117}
118
119static void
121{
122 if (!ledger)
123 return;
124
125 XRPL_ASSERT(
126 ledger->header().seq < kXrpLedgerEarliestFees || FeeSettingsEntryR(*ledger),
127 "xrpl::finishLoadByIndexOrHash : valid ledger fees");
128 ledger->setImmutable();
129
130 JLOG(j.trace()) << "Loaded ledger: " << to_string(ledger->header().hash);
131
132 ledger->setFull();
133}
134
136getLatestLedger(Rules const& rules, Fees const& fees, ServiceRegistry& registry)
137{
139 if (!info)
140 return {std::shared_ptr<Ledger>(), {}, {}};
141 return {loadLedgerHelper(*info, rules, fees, registry, true), info->seq, info->hash};
142}
143
146 std::uint32_t ledgerIndex,
147 Rules const& rules,
148 Fees const& fees,
149 ServiceRegistry& registry,
150 bool acquire)
151{
153 registry.getRelationalDatabase().getLedgerInfoByIndex(ledgerIndex))
154 {
155 std::shared_ptr<Ledger> ledger = loadLedgerHelper(*info, rules, fees, registry, acquire);
156 finishLoadByIndexOrHash(ledger, registry.getJournal("Ledger"));
157 return ledger;
158 }
159 return {};
160}
161
164 UInt256 const& ledgerHash,
165 Rules const& rules,
166 Fees const& fees,
167 ServiceRegistry& registry,
168 bool acquire)
169{
171 registry.getRelationalDatabase().getLedgerInfoByHash(ledgerHash))
172 {
173 std::shared_ptr<Ledger> ledger = loadLedgerHelper(*info, rules, fees, registry, acquire);
174 finishLoadByIndexOrHash(ledger, registry.getJournal("Ledger"));
175 XRPL_ASSERT(
176 !ledger || ledger->header().hash == ledgerHash,
177 "xrpl::loadByHash : ledger hash match if loaded");
178 return ledger;
179 }
180 return {};
181}
182
183} // namespace xrpl
A generic endpoint for log messages.
Definition Journal.h:44
Stream debug() const
Definition Journal.h:344
Stream trace() const
Severity stream access functions.
Definition Journal.h:338
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:176
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:40
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 make_shared(T... args)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
bool isCurrent(ValidationParms const &p, NetClock::time_point now, NetClock::time_point signTime, NetClock::time_point seenTime)
Whether a validation is still current.
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 pendSaveValidated(ServiceRegistry &registry, std::shared_ptr< Ledger const > const &ledger, bool isSynchronous, bool isCurrent)
Save, or arrange to save, a fully-validated ledger.
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.
std::string to_string(BaseUInt< Bits, Tag > const &a)
Definition base_uint.h:657
static constexpr std::uint32_t kXrpLedgerEarliestFees
The XRP Ledger mainnet's earliest ledger with a FeeSettings object.
BaseUInt< 256 > UInt256
Definition base_uint.h:580
static bool saveValidatedLedger(ServiceRegistry &registry, std::shared_ptr< Ledger const > const &ledger, bool current)
std::shared_ptr< Ledger > loadByHash(UInt256 const &ledgerHash, Rules const &rules, Fees const &fees, ServiceRegistry &registry, bool acquire)
Load a ledger by its hash.
@ JtPuboldledger
Definition Job.h:30
@ JtPubledger
Definition Job.h:54
FeeSettingsEntry< ReadView > FeeSettingsEntryR
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)