xrpld
Loading...
Searching...
No Matches
CredentialAccept.cpp
1#include <xrpl/tx/transactors/credentials/CredentialAccept.h>
2
3#include <xrpl/basics/Log.h>
4#include <xrpl/ledger/ApplyView.h>
5#include <xrpl/ledger/helpers/AccountRootHelpers.h>
6#include <xrpl/ledger/helpers/CredentialHelpers.h>
7#include <xrpl/protocol/AccountID.h>
8#include <xrpl/protocol/Feature.h>
9#include <xrpl/protocol/Indexes.h>
10#include <xrpl/protocol/Keylet.h>
11#include <xrpl/protocol/LedgerFormats.h>
12#include <xrpl/protocol/Protocol.h>
13#include <xrpl/protocol/SField.h>
14#include <xrpl/protocol/STAmount.h>
15#include <xrpl/protocol/STLedgerEntry.h>
16#include <xrpl/protocol/STTx.h>
17#include <xrpl/protocol/TER.h>
18#include <xrpl/protocol/TxFlags.h>
19#include <xrpl/protocol/XRPAmount.h>
20#include <xrpl/tx/Transactor.h>
21
22#include <cstdint>
23namespace xrpl {
24
25using namespace credentials;
26
27std::uint32_t
29{
30 // 0 means "Allow any flags"
31 return ctx.rules.enabled(fixInvalidTxFlags) ? tfUniversalMask : 0;
32}
33
36{
37 if (!ctx.tx[sfIssuer])
38 {
39 JLOG(ctx.j.trace()) << "Malformed transaction: Issuer field zeroed.";
41 }
42
43 auto const credType = ctx.tx[sfCredentialType];
44 if (credType.empty() || (credType.size() > kMaxCredentialTypeLength))
45 {
46 JLOG(ctx.j.trace()) << "Malformed transaction: invalid size of CredentialType.";
47 return temMALFORMED;
48 }
49
50 return tesSUCCESS;
51}
52
53TER
55{
56 AccountID const subject = ctx.tx[sfAccount];
57 AccountID const issuer = ctx.tx[sfIssuer];
58 auto const credType(ctx.tx[sfCredentialType]);
59
60 if (!ctx.view.exists(keylet::account(issuer)))
61 {
62 JLOG(ctx.j.warn()) << "No issuer: " << to_string(issuer);
63 return tecNO_ISSUER;
64 }
65
66 auto const sleCred = ctx.view.read(keylet::credential(subject, issuer, credType));
67 if (!sleCred)
68 {
69 JLOG(ctx.j.warn()) << "No credential: " << to_string(subject) << ", " << to_string(issuer)
70 << ", " << credType;
71 return tecNO_ENTRY;
72 }
73
74 if (sleCred->isFlag(lsfAccepted))
75 {
76 JLOG(ctx.j.warn()) << "Credential already accepted: " << to_string(subject) << ", "
77 << to_string(issuer) << ", " << credType;
78 return tecDUPLICATE;
79 }
80
81 return tesSUCCESS;
82}
83
84TER
86{
87 AccountID const issuer{ctx_.tx[sfIssuer]};
88
89 // Both exist as credential object exist itself (checked in preclaim)
90 auto const sleSubject = view().peek(keylet::account(accountID_));
91 auto const sleIssuer = view().peek(keylet::account(issuer));
92
93 if (!sleSubject || !sleIssuer)
94 return tefINTERNAL; // LCOV_EXCL_LINE
95
96 {
97 STAmount const reserve{
98 view().fees().accountReserve(sleSubject->getFieldU32(sfOwnerCount) + 1)};
99 if (preFeeBalance_ < reserve)
101 }
102
103 auto const credType(ctx_.tx[sfCredentialType]);
104 Keylet const credentialKey = keylet::credential(accountID_, issuer, credType);
105 auto const sleCred = view().peek(credentialKey); // Checked in preclaim()
106 if (!sleCred)
107 return tefINTERNAL; // LCOV_EXCL_LINE
108
109 if (checkExpired(*sleCred, view().header().parentCloseTime))
110 {
111 JLOG(j_.trace()) << "Credential is expired: " << sleCred->getText();
112 // delete expired credentials even if the transaction failed
113 auto const err = credentials::deleteSLE(view(), sleCred, j_);
114 return isTesSuccess(err) ? tecEXPIRED : err;
115 }
116
117 sleCred->setFieldU32(sfFlags, lsfAccepted);
118 view().update(sleCred);
119
120 adjustOwnerCount(view(), sleIssuer, -1, j_);
121 adjustOwnerCount(view(), sleSubject, 1, j_);
122
123 return tesSUCCESS;
124}
125
126void
128{
129 // No transaction-specific invariants yet (future work).
130}
131
132bool
134 STTx const&,
135 TER,
136 XRPAmount,
137 ReadView const&,
138 beast::Journal const&)
139{
140 // No transaction-specific invariants yet (future work).
141 return true;
142}
143} // namespace xrpl
A generic endpoint for log messages.
Definition Journal.h:38
Stream trace() const
Severity stream access functions.
Definition Journal.h:291
Stream warn() const
Definition Journal.h:309
virtual SLE::pointer peek(Keylet const &k)=0
Prepare to modify the SLE associated with key.
virtual void update(SLE::ref sle)=0
Indicate changes to a peeked SLE.
void visitInvariantEntry(bool isDelete, SLE::const_ref before, SLE::const_ref after) override
Inspect a single ledger entry modified by this transaction.
bool finalizeInvariants(STTx const &tx, TER result, XRPAmount fee, ReadView const &view, beast::Journal const &j) override
Check transaction-specific post-conditions after all entries have been visited.
static TER preclaim(PreclaimContext const &ctx)
static std::uint32_t getFlagsMask(PreflightContext const &ctx)
static NotTEC preflight(PreflightContext const &ctx)
A view into a ledger.
Definition ReadView.h:31
virtual Fees const & fees() const =0
Returns the fees for the base ledger.
virtual bool exists(Keylet const &k) const =0
Determine if a state item exists.
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:171
std::shared_ptr< STLedgerEntry const > const & const_ref
beast::Journal const j_
Definition Transactor.h:118
ApplyView & view()
Definition Transactor.h:136
AccountID const accountID_
Definition Transactor.h:120
XRPAmount preFeeBalance_
Definition Transactor.h:121
ApplyContext & ctx_
Definition Transactor.h:116
TER deleteSLE(ApplyView &view, SLE::ref sleCredential, beast::Journal j)
bool checkExpired(SLE const &sleCredential, NetClock::time_point const &closed)
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition Indexes.cpp:186
Keylet credential(AccountID const &subject, AccountID const &issuer, Slice const &credType) noexcept
Definition Indexes.cpp:545
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
constexpr std::size_t kMaxCredentialTypeLength
The maximum length of a CredentialType inside a Credential.
Definition Protocol.h:225
@ tefINTERNAL
Definition TER.h:163
std::string to_string(BaseUInt< Bits, Tag > const &a)
Definition base_uint.h:633
TERSubset< CanCvtToNotTEC > NotTEC
Definition TER.h:594
void adjustOwnerCount(ApplyView &view, SLE::ref sle, std::int32_t amount, beast::Journal j)
Adjust the owner count up or down.
BaseUInt< 160, detail::AccountIDTag > AccountID
A 160-bit unsigned that uniquely identifies an account.
Definition AccountID.h:28
@ temMALFORMED
Definition TER.h:73
@ temINVALID_ACCOUNT_ID
Definition TER.h:105
bool isTesSuccess(TER x) noexcept
Definition TER.h:663
TERSubset< CanCvtToTER > TER
Definition TER.h:634
@ tecNO_ENTRY
Definition TER.h:304
@ tecEXPIRED
Definition TER.h:312
@ tecINSUFFICIENT_RESERVE
Definition TER.h:305
@ tecNO_ISSUER
Definition TER.h:297
@ tecDUPLICATE
Definition TER.h:313
constexpr FlagValue tfUniversalMask
Definition TxFlags.h:45
@ tesSUCCESS
Definition TER.h:240
XRPAmount accountReserve(std::size_t ownerCount) const
Returns the account reserve given the owner count, in drops.
A pair of SHAMap key and LedgerEntryType.
Definition Keylet.h:19
State information when determining if a tx is likely to claim a fee.
Definition Transactor.h:61
ReadView const & view
Definition Transactor.h:64
beast::Journal const j
Definition Transactor.h:69
State information when preflighting a tx.
Definition Transactor.h:18
beast::Journal const j
Definition Transactor.h:25