xrpld
Loading...
Searching...
No Matches
DirectoryInvariant.cpp
1#include <xrpl/tx/invariants/DirectoryInvariant.h>
2
3#include <xrpl/basics/Log.h>
4#include <xrpl/beast/utility/Journal.h>
5#include <xrpl/ledger/ReadView.h>
6#include <xrpl/protocol/Feature.h>
7#include <xrpl/protocol/Indexes.h>
8#include <xrpl/protocol/Keylet.h>
9#include <xrpl/protocol/LedgerFormats.h>
10#include <xrpl/protocol/SField.h>
11#include <xrpl/protocol/STLedgerEntry.h>
12#include <xrpl/protocol/STTx.h>
13#include <xrpl/protocol/TER.h>
14#include <xrpl/protocol/XRPAmount.h>
15
16#include <algorithm>
17#include <memory>
18
19namespace xrpl {
20
21namespace {
22
23[[nodiscard]] bool
24isRootBookDirectory(SLE const& dir)
25{
26 // Child page keys do not encode book quality.
27 return dir.isFieldPresent(sfExchangeRate) || dir.isFieldPresent(sfTakerPaysCurrency) ||
28 dir.isFieldPresent(sfTakerPaysIssuer) || dir.isFieldPresent(sfTakerPaysMPT) ||
29 dir.isFieldPresent(sfTakerGetsCurrency) || dir.isFieldPresent(sfTakerGetsIssuer) ||
30 dir.isFieldPresent(sfTakerGetsMPT) || dir.isFieldPresent(sfDomainID);
31}
32
33[[nodiscard]] bool
34badExchangeRate(SLE const& dir)
35{
36 return isRootBookDirectory(dir) &&
37 (!dir.isFieldPresent(sfExchangeRate) ||
38 dir.getFieldU64(sfExchangeRate) != getQuality(dir.key()));
39}
40
41} // namespace
42
43void
45 bool isDelete,
46 std::shared_ptr<SLE const> const& before,
48{
49 // New root directories must have matching exchange-rate metadata. New
50 // child directories, and modified directories that change sfRootIndex, must
51 // point to an existing root.
52
53 // Only validate newly-created directories and sfRootIndex changes;
54 // LedgerStateFix handles legacy bad exchange-rate metadata. Skip deletions
55 // because `after` is not guaranteed to be null.
56 if (badBookDirectory_ || isDelete || !after || after->getType() != ltDIR_NODE)
57 return;
58
59 auto const rootIndex = after->getFieldH256(sfRootIndex);
60 // Ignore ordinary modifications that do not change which root this
61 // directory belongs to. That tolerates legacy bad exchange-rate metadata
62 // during normal operation while still checking sfRootIndex changes.
63 if (before && before->getFieldH256(sfRootIndex) == rootIndex)
64 return;
65
66 if (after->key() == rootIndex && !badBookDirectory_)
67 {
68 badBookDirectory_ = badBookDirectory_ || badExchangeRate(*after);
69 return;
70 }
71
72 rootIndexes_.insert(rootIndex);
73}
74
75bool
77 STTx const&,
78 TER const,
79 XRPAmount const,
80 ReadView const& view,
81 beast::Journal const& j)
82{
83 if (!view.rules().enabled(fixCleanup3_2_0))
84 return true;
85
87 {
88 JLOG(j.fatal()) << "Invariant failed: book directory exchange rate "
89 "does not match directory quality";
90 return false;
91 }
92
93 return std::ranges::all_of(rootIndexes_, [&](auto const& rootIndex) {
94 auto const root = view.read(Keylet(ltDIR_NODE, rootIndex));
95 if (!root)
96 {
97 JLOG(j.fatal()) << "Invariant failed: book directory root missing";
98 return false;
99 }
100 return true;
101 });
102}
103
104} // namespace xrpl
T all_of(T... args)
A generic endpoint for log messages.
Definition Journal.h:44
Stream fatal() const
Definition Journal.h:368
A view into a ledger.
Definition ReadView.h:41
virtual Rules const & rules() const =0
Returns the tx processing rules.
virtual SLE::const_pointer read(Keylet const &k) const =0
Return the state item associated with a key.
bool enabled(uint256 const &feature) const
Returns true if a feature is enabled.
Definition Rules.cpp:180
bool finalize(STTx const &, TER const, XRPAmount const, ReadView const &, beast::Journal const &)
void visitEntry(bool, std::shared_ptr< SLE const > const &, std::shared_ptr< SLE const > const &)
hash_set< uint256 > rootIndexes_
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
std::uint64_t getQuality(uint256 const &uBase)
Definition Indexes.cpp:172
Number root(Number f, unsigned d)
STLedgerEntry SLE
bool after(NetClock::time_point now, std::uint32_t mark)
Has the specified time passed?
Definition View.cpp:572
TERSubset< CanCvtToTER > TER
Definition TER.h:647
A pair of SHAMap key and LedgerEntryType.
Definition Keylet.h:20