xrpld
Loading...
Searching...
No Matches
SponsorshipInvariant.cpp
1#include <xrpl/tx/invariants/SponsorshipInvariant.h>
2//
3#include <xrpl/basics/Log.h>
4#include <xrpl/beast/utility/Journal.h>
5#include <xrpl/core/ServiceRegistry.h>
6#include <xrpl/ledger/ReadView.h>
7#include <xrpl/ledger/helpers/SponsorHelpers.h>
8#include <xrpl/protocol/LedgerFormats.h>
9#include <xrpl/protocol/SField.h>
10#include <xrpl/protocol/STTx.h>
11#include <xrpl/protocol/TER.h>
12#include <xrpl/protocol/XRPAmount.h>
13
14#include <cstdint>
15
16namespace xrpl {
17
18// Add new sponsorship-related invariants implementations
19void
21{
22 auto getSponsored = [](SLE::const_ref sle) -> std::uint32_t {
23 if (sle && sle->getType() == ltACCOUNT_ROOT)
24 return sle->getFieldU32(sfSponsoredOwnerCount);
25 return 0;
26 };
27 auto getSponsoring = [](SLE::const_ref sle) -> std::uint32_t {
28 if (sle && sle->getType() == ltACCOUNT_ROOT)
29 return sle->getFieldU32(sfSponsoringOwnerCount);
30 return 0;
31 };
32
33 auto getOwnerCount = [](SLE::const_ref sle) -> std::uint32_t {
34 if (sle && sle->getType() == ltACCOUNT_ROOT)
35 return sle->getFieldU32(sfOwnerCount);
36 return 0;
37 };
38
39 auto getSponsoredObjectOwnerCount = [&](SLE::const_ref sle) -> std::uint32_t {
40 if (!sle)
41 return 0;
42 switch (sle->getType())
43 {
44 case ltACCOUNT_ROOT:
45 return 0;
46 case ltRIPPLE_STATE: {
47 // A trust line can be reserve-sponsored independently on each
48 // side, so it may contribute up to two sponsored owner counts.
49 uint32_t ownerCount = 0;
50 if (sle->isFieldPresent(sfHighSponsor))
51 ownerCount++;
52 if (sle->isFieldPresent(sfLowSponsor))
53 ownerCount++;
54 return ownerCount;
55 }
56 default:
57 // Every other supported type carries a single sfSponsor field
58 // and contributes its full owner-count magnitude only when it is
59 // sponsored.
60 if (!sle->isFieldPresent(sfSponsor))
61 return 0;
62 return getLedgerEntryOwnerCount(*sle);
63 }
64 };
65
66 // The values are implicitly casted to std::int64_t to calculate deltas.
67 std::int64_t const beforeSponsored = getSponsored(before);
68 std::int64_t const afterSponsored = getSponsored(after);
69 std::int64_t const beforeSponsoring = getSponsoring(before);
70 std::int64_t const afterSponsoring = getSponsoring(after);
71
72 std::int64_t const beforeSponsoredObjectOwnerCount = getSponsoredObjectOwnerCount(before);
73 std::int64_t const afterSponsoredObjectOwnerCount =
74 isDelete ? 0 : getSponsoredObjectOwnerCount(after);
75
76 deltaSponsoredOwnerCount_ += (afterSponsored - beforeSponsored);
77 deltaSponsoringOwnerCount_ += (afterSponsoring - beforeSponsoring);
78
80 (afterSponsoredObjectOwnerCount - beforeSponsoredObjectOwnerCount);
81
82 if (getOwnerCount(after) < getSponsored(after))
84}
85
86bool
88 STTx const&,
89 TER const,
90 XRPAmount const,
91 ReadView const&,
92 beast::Journal const& j) const
93{
95 {
96 JLOG(j.fatal()) << "Invariant failed: SponsoredOwnerCount does not "
97 "equal SponsoringOwnerCount delta.";
98 return false;
99 }
100
102 {
103 JLOG(j.fatal())
104 << "Invariant failed: OwnerCount must be greater than or equal to SponsoredOwnerCount.";
105 return false;
106 }
107
109 {
110 JLOG(j.fatal()) << "Invariant failed: SponsoredObjectOwnerCount does not "
111 "equal SponsoredOwnerCount delta.";
112 return false;
113 }
114
115 return true;
116}
117
118void
120{
121 auto getSponsoringAccountCount = [](SLE::const_ref sle) -> std::uint32_t {
122 if (sle && sle->getType() == ltACCOUNT_ROOT)
123 return sle->getFieldU32(sfSponsoringAccountCount);
124 return 0;
125 };
126
127 auto hasSponsorField = [](SLE::const_ref sle) -> bool {
128 return sle && sle->getType() == ltACCOUNT_ROOT && sle->isFieldPresent(sfSponsor);
129 };
130
131 std::int64_t const beforeCount = getSponsoringAccountCount(before);
132 std::int64_t const afterCount = getSponsoringAccountCount(after);
133 deltaSponsoringAccountCount_ += (afterCount - beforeCount);
134
135 int const beforePresent = hasSponsorField(before) ? 1 : 0;
136 int const afterPresent = hasSponsorField(after) ? 1 : 0;
137 deltaSponsorFieldPresence_ += (afterPresent - beforePresent);
138}
139
140bool
142 STTx const&,
143 TER const,
144 XRPAmount const,
145 ReadView const&,
146 beast::Journal const& j) const
147{
149 {
150 JLOG(j.fatal()) << "Invariant failed: Net delta of SponsoringAccountCount does not "
151 "match net delta of sfSponsor presence.";
152 return false;
153 }
154
155 return true;
156}
157
158} // namespace xrpl
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
std::shared_ptr< STLedgerEntry const > const & const_ref
void visitEntry(bool, SLE::const_ref, SLE::const_ref)
bool finalize(STTx const &, TER const, XRPAmount const, ReadView const &, beast::Journal const &) const
bool finalize(STTx const &, TER const, XRPAmount const, ReadView const &, beast::Journal const &) const
void visitEntry(bool, SLE::const_ref, SLE::const_ref)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
bool after(NetClock::time_point now, std::uint32_t mark)
Has the specified time passed?
Definition View.cpp:572
std::uint32_t getLedgerEntryOwnerCount(SLE const &sle)
Return the number of owner-count units the ledger entry consumes.
TERSubset< CanCvtToTER > TER
Definition TER.h:647
std::uint32_t ownerCount(SLE::const_ref sle, beast::Journal j, std::int32_t ownerCountAdj=0)
Return number of the objects which reserve is covered by the account(sle) (so called "ownercount").