xrpld
Toggle main menu visibility
Loading...
Searching...
No Matches
libxrpl
tx
invariants
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
19
namespace
xrpl
{
20
21
namespace
{
22
23
[[nodiscard]]
bool
24
isRootBookDirectory(
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
34
badExchangeRate(
SLE
const
& dir)
35
{
36
return
isRootBookDirectory(dir) &&
37
(!dir.isFieldPresent(sfExchangeRate) ||
38
dir.getFieldU64(sfExchangeRate) !=
getQuality
(dir.key()));
39
}
40
41
}
// namespace
42
43
void
44
ValidBookDirectory::visitEntry
(
45
bool
isDelete,
46
std::shared_ptr<SLE const>
const
& before,
47
std::shared_ptr<SLE const>
const
&
after
)
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
75
bool
76
ValidBookDirectory::finalize
(
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
86
if
(
badBookDirectory_
)
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
algorithm
std::ranges::all_of
T all_of(T... args)
beast::Journal
A generic endpoint for log messages.
Definition
Journal.h:44
beast::Journal::fatal
Stream fatal() const
Definition
Journal.h:368
xrpl::ReadView
A view into a ledger.
Definition
ReadView.h:41
xrpl::ReadView::rules
virtual Rules const & rules() const =0
Returns the tx processing rules.
xrpl::ReadView::read
virtual SLE::const_pointer read(Keylet const &k) const =0
Return the state item associated with a key.
xrpl::Rules::enabled
bool enabled(UInt256 const &feature) const
Returns true if a feature is enabled.
Definition
Rules.cpp:182
xrpl::STTx
Definition
STTx.h:43
xrpl::ValidBookDirectory::finalize
bool finalize(STTx const &, TER const, XRPAmount const, ReadView const &, beast::Journal const &)
Definition
DirectoryInvariant.cpp:76
xrpl::ValidBookDirectory::rootIndexes_
HashSet< UInt256 > rootIndexes_
Definition
DirectoryInvariant.h:19
xrpl::ValidBookDirectory::badBookDirectory_
bool badBookDirectory_
Definition
DirectoryInvariant.h:18
xrpl::ValidBookDirectory::visitEntry
void visitEntry(bool, std::shared_ptr< SLE const > const &, std::shared_ptr< SLE const > const &)
Definition
DirectoryInvariant.cpp:44
xrpl::XRPAmount
Definition
XRPAmount.h:28
memory
xrpl
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition
algorithm.h:5
xrpl::getQuality
std::uint64_t getQuality(UInt256 const &uBase)
Definition
Indexes.cpp:194
xrpl::root
Number root(Number f, unsigned d)
Definition
libxrpl/basics/Number.cpp:1537
xrpl::SLE
STLedgerEntry SLE
Definition
ServiceRegistry.h:42
xrpl::after
bool after(NetClock::time_point now, std::uint32_t mark)
Has the specified time passed?
Definition
View.cpp:644
xrpl::TER
TERSubset< CanCvtToTER > TER
Definition
TER.h:654
std::shared_ptr
xrpl::Keylet
A pair of SHAMap key and LedgerEntryType.
Definition
Keylet.h:20
Generated by
1.17.0