rippled
Loading...
Searching...
No Matches
CredentialAccept.cpp
1#include <xrpl/basics/Log.h>
2#include <xrpl/ledger/ApplyView.h>
3#include <xrpl/ledger/helpers/AccountRootHelpers.h>
4#include <xrpl/ledger/helpers/CredentialHelpers.h>
5#include <xrpl/protocol/Feature.h>
6#include <xrpl/protocol/Indexes.h>
7#include <xrpl/protocol/TxFlags.h>
8#include <xrpl/tx/transactors/credentials/CredentialAccept.h>
9
10#include <chrono>
11
12namespace xrpl {
13
14using namespace credentials;
15
18{
19 // 0 means "Allow any flags"
20 return ctx.rules.enabled(fixInvalidTxFlags) ? tfUniversalMask : 0;
21}
22
25{
26 if (!ctx.tx[sfIssuer])
27 {
28 JLOG(ctx.j.trace()) << "Malformed transaction: Issuer field zeroed.";
30 }
31
32 auto const credType = ctx.tx[sfCredentialType];
33 if (credType.empty() || (credType.size() > maxCredentialTypeLength))
34 {
35 JLOG(ctx.j.trace()) << "Malformed transaction: invalid size of CredentialType.";
36 return temMALFORMED;
37 }
38
39 return tesSUCCESS;
40}
41
42TER
44{
45 AccountID const subject = ctx.tx[sfAccount];
46 AccountID const issuer = ctx.tx[sfIssuer];
47 auto const credType(ctx.tx[sfCredentialType]);
48
49 if (!ctx.view.exists(keylet::account(issuer)))
50 {
51 JLOG(ctx.j.warn()) << "No issuer: " << to_string(issuer);
52 return tecNO_ISSUER;
53 }
54
55 auto const sleCred = ctx.view.read(keylet::credential(subject, issuer, credType));
56 if (!sleCred)
57 {
58 JLOG(ctx.j.warn()) << "No credential: " << to_string(subject) << ", " << to_string(issuer)
59 << ", " << credType;
60 return tecNO_ENTRY;
61 }
62
63 if ((sleCred->getFieldU32(sfFlags) & lsfAccepted) != 0u)
64 {
65 JLOG(ctx.j.warn()) << "Credential already accepted: " << to_string(subject) << ", "
66 << to_string(issuer) << ", " << credType;
67 return tecDUPLICATE;
68 }
69
70 return tesSUCCESS;
71}
72
73TER
75{
76 AccountID const issuer{ctx_.tx[sfIssuer]};
77
78 // Both exist as credential object exist itself (checked in preclaim)
79 auto const sleSubject = view().peek(keylet::account(account_));
80 auto const sleIssuer = view().peek(keylet::account(issuer));
81
82 if (!sleSubject || !sleIssuer)
83 return tefINTERNAL; // LCOV_EXCL_LINE
84
85 {
86 STAmount const reserve{
87 view().fees().accountReserve(sleSubject->getFieldU32(sfOwnerCount) + 1)};
88 if (preFeeBalance_ < reserve)
90 }
91
92 auto const credType(ctx_.tx[sfCredentialType]);
93 Keylet const credentialKey = keylet::credential(account_, issuer, credType);
94 auto const sleCred = view().peek(credentialKey); // Checked in preclaim()
95
96 if (checkExpired(sleCred, view().header().parentCloseTime))
97 {
98 JLOG(j_.trace()) << "Credential is expired: " << sleCred->getText();
99 // delete expired credentials even if the transaction failed
100 auto const err = credentials::deleteSLE(view(), sleCred, j_);
101 return isTesSuccess(err) ? tecEXPIRED : err;
102 }
103
104 sleCred->setFieldU32(sfFlags, lsfAccepted);
105 view().update(sleCred);
106
107 adjustOwnerCount(view(), sleIssuer, -1, j_);
108 adjustOwnerCount(view(), sleSubject, 1, j_);
109
110 return tesSUCCESS;
111}
112
113} // namespace xrpl
Stream trace() const
Severity stream access functions.
Definition Journal.h:295
Stream warn() const
Definition Journal.h:313
STTx const & tx
virtual void update(std::shared_ptr< SLE > const &sle)=0
Indicate changes to a peeked SLE.
virtual std::shared_ptr< SLE > peek(Keylet const &k)=0
Prepare to modify the SLE associated with key.
static TER preclaim(PreclaimContext const &ctx)
static std::uint32_t getFlagsMask(PreflightContext const &ctx)
static NotTEC preflight(PreflightContext const &ctx)
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 std::shared_ptr< SLE const > 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:120
AccountID const account_
Definition Transactor.h:116
beast::Journal const j_
Definition Transactor.h:114
ApplyView & view()
Definition Transactor.h:132
XRPAmount preFeeBalance_
Definition Transactor.h:117
ApplyContext & ctx_
Definition Transactor.h:112
bool checkExpired(std::shared_ptr< SLE const > const &sleCredential, NetClock::time_point const &closed)
TER deleteSLE(ApplyView &view, std::shared_ptr< SLE > const &sleCredential, beast::Journal j)
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition Indexes.cpp:165
Keylet credential(AccountID const &subject, AccountID const &issuer, Slice const &credType) noexcept
Definition Indexes.cpp:498
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
std::string to_string(base_uint< Bits, Tag > const &a)
Definition base_uint.h:602
@ tefINTERNAL
Definition TER.h:153
void adjustOwnerCount(ApplyView &view, std::shared_ptr< SLE > const &sle, std::int32_t amount, beast::Journal j)
Adjust the owner count up or down.
@ temMALFORMED
Definition TER.h:67
@ temINVALID_ACCOUNT_ID
Definition TER.h:99
bool isTesSuccess(TER x) noexcept
Definition TER.h:651
@ tecNO_ENTRY
Definition TER.h:287
@ tecEXPIRED
Definition TER.h:295
@ tecINSUFFICIENT_RESERVE
Definition TER.h:288
@ tecNO_ISSUER
Definition TER.h:280
@ tecDUPLICATE
Definition TER.h:296
constexpr FlagValue tfUniversalMask
Definition TxFlags.h:43
@ tesSUCCESS
Definition TER.h:225
std::size_t constexpr maxCredentialTypeLength
The maximum length of a CredentialType inside a Credential.
Definition Protocol.h:221
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:57
ReadView const & view
Definition Transactor.h:60
beast::Journal const j
Definition Transactor.h:65
State information when preflighting a tx.
Definition Transactor.h:14
beast::Journal const j
Definition Transactor.h:21