1#include <xrpl/ledger/helpers/CredentialHelpers.h>
3#include <xrpl/basics/Log.h>
4#include <xrpl/basics/Slice.h>
5#include <xrpl/basics/base_uint.h>
6#include <xrpl/basics/chrono.h>
7#include <xrpl/beast/utility/Journal.h>
8#include <xrpl/ledger/ApplyView.h>
9#include <xrpl/ledger/ReadView.h>
10#include <xrpl/ledger/helpers/AccountRootHelpers.h>
11#include <xrpl/protocol/AccountID.h>
12#include <xrpl/protocol/Feature.h>
13#include <xrpl/protocol/Indexes.h>
14#include <xrpl/protocol/LedgerFormats.h>
15#include <xrpl/protocol/Protocol.h>
16#include <xrpl/protocol/SField.h>
17#include <xrpl/protocol/STArray.h>
18#include <xrpl/protocol/STLedgerEntry.h>
19#include <xrpl/protocol/STObject.h>
20#include <xrpl/protocol/STTx.h>
21#include <xrpl/protocol/STVector256.h>
22#include <xrpl/protocol/TER.h>
23#include <xrpl/protocol/digest.h>
46static std::expected<bool, TER>
50 bool foundExpired =
false;
52 for (
auto const& h : arr)
56 auto const sleCred = view.
peek(k);
60 JLOG(j.
trace()) <<
"Credentials are expired. Cred: " << sleCred->getText();
62 auto const err =
deleteSLE(view, sleCred, j);
78 auto delSLE = [&view, &sleCredential, j](
84 JLOG(j.
fatal()) <<
"Internal error: can't retrieve Owner account.";
94 JLOG(j.
fatal()) <<
"Unable to delete Credential from owner.";
105 auto const issuer = sleCredential->getAccountID(sfIssuer);
106 auto const subject = sleCredential->getAccountID(sfSubject);
107 bool const accepted = sleCredential->isFlag(lsfAccepted);
109 auto err = delSLE(issuer, sfIssuerNode, !accepted || (subject == issuer));
113 if (subject != issuer)
115 err = delSLE(subject, sfSubjectNode, accepted);
121 view.
erase(sleCredential);
135 JLOG(j.
trace()) <<
"Malformed transaction: Credentials array size is invalid: "
143 auto [it, ins] = duplicates.
insert(cred);
146 JLOG(j.
trace()) <<
"Malformed transaction: duplicates in credentials.";
161 for (
auto const& h : credIDs)
166 JLOG(j.
trace()) <<
"Credential doesn't exist. Cred: " << h;
170 if (sleCred->getAccountID(sfSubject) != src)
172 JLOG(j.
trace()) <<
"Credential doesn't belong to the source account. Cred: " << h;
176 if (!sleCred->isFlag(lsfAccepted))
178 JLOG(j.
trace()) <<
"Credential isn't accepted. Cred: " << h;
197 bool foundExpired =
false;
198 for (
auto const& h : slePD->getFieldArray(sfAcceptedCredentials))
200 auto const issuer = h.getAccountID(sfIssuer);
201 auto const type = h.getFieldVL(sfCredentialType);
203 auto const sleCredential = view.
read(keyletCredential);
217 if (sleCredential->isFlag(lsfAccepted))
235 for (
auto const& h : credIDs)
241 auto [it, ins] = sorted.
emplace((*sleCred)[sfIssuer], (*sleCred)[sfCredentialType]);
244 lifeExtender.
push_back(std::move(sleCred));
259 auto [it, ins] = out.
emplace(cred[sfIssuer], cred[sfCredentialType]);
271 JLOG(j.
trace()) <<
"Malformed transaction: "
272 "Invalid credentials size: "
280 auto const& issuer = credential[sfIssuer];
283 JLOG(j.
trace()) <<
"Malformed transaction: "
284 "Issuer account is invalid: "
289 auto const ct = credential[sfCredentialType];
292 JLOG(j.
trace()) <<
"Malformed transaction: "
293 "Invalid credentialType size: "
301 JLOG(j.
trace()) <<
"Malformed transaction: "
302 "duplicates in credentials.";
322 for (
auto const& h : slePD->getFieldArray(sfAcceptedCredentials))
324 auto const issuer = h.getAccountID(sfIssuer);
325 auto const type = h.getFieldVL(sfCredentialType);
327 if (view.
exists(keyletCredential))
332 if (!foundExpired.has_value())
333 return foundExpired.error();
341 if (sleCredential->isFlag(lsfAccepted))
363 if (sleDst && ((sleDst->getFlags() & lsfDepositAuth) != 0u))
385 auto const foundExpired =
387 if (!foundExpired.has_value())
388 return foundExpired.error();
A generic endpoint for log messages.
Stream trace() const
Severity stream access functions.
Writeable view to a ledger, for applying a transaction.
virtual SLE::pointer peek(Keylet const &k)=0
Prepare to modify the SLE associated with key.
bool dirRemove(Keylet const &directory, std::uint64_t page, uint256 const &key, bool keepRoot)
Remove an entry from a directory.
virtual void erase(SLE::ref sle)=0
Remove a peeked SLE.
std::chrono::time_point< NetClock > time_point
virtual Rules const & rules() const =0
Returns the tx processing rules.
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.
virtual LedgerHeader const & header() const =0
Returns information about the ledger.
bool enabled(uint256 const &feature) const
Returns true if a feature is enabled.
std::shared_ptr< STLedgerEntry > const & ref
std::shared_ptr< STLedgerEntry const > const & const_ref
bool isFieldPresent(SField const &field) const
STVector256 const & getFieldV256(SField const &field) const
TER validDomain(ReadView const &view, uint256 domainID, AccountID const &subject)
TER deleteSLE(ApplyView &view, SLE::ref sleCredential, beast::Journal j)
std::set< std::pair< AccountID, Slice > > makeSorted(STArray const &credentials)
static std::expected< bool, TER > removeExpired(ApplyView &view, STVector256 const &arr, beast::Journal const j)
NotTEC checkFields(STTx const &tx, beast::Journal j)
TER valid(STTx const &tx, ReadView const &view, AccountID const &src, beast::Journal j)
NotTEC checkArray(STArray const &credentials, unsigned maxSize, beast::Journal j)
TER authorizedDepositPreauth(ReadView const &view, STVector256 const &ctx, AccountID const &dst)
bool checkExpired(SLE const &sleCredential, NetClock::time_point const &closed)
Keylet depositPreauth(AccountID const &owner, AccountID const &preauthorized) noexcept
A DepositPreauth.
Keylet ownerDir(AccountID const &id) noexcept
The root page of an account's directory.
Keylet account(AccountID const &id) noexcept
AccountID root.
Keylet permissionedDomain(AccountID const &account, std::uint32_t seq) noexcept
Keylet credential(AccountID const &subject, AccountID const &issuer, Slice const &credType) noexcept
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
sha512_half_hasher::result_type sha512Half(Args const &... args)
Returns the SHA512-Half of a series of objects.
constexpr std::size_t kMaxCredentialTypeLength
The maximum length of a CredentialType inside a Credential.
TER verifyValidDomain(ApplyView &view, AccountID const &account, uint256 domainID, beast::Journal j)
std::string to_string(BaseUInt< Bits, Tag > const &a)
TERSubset< CanCvtToNotTEC > NotTEC
constexpr std::size_t kMaxCredentialsArraySize
The maximum number of credentials can be passed in array.
void adjustOwnerCount(ApplyView &view, SLE::ref sle, std::int32_t amount, beast::Journal j)
Adjust the owner count up or down.
TER cleanupExpiredCredentials(STTx const &tx, ApplyView &view, beast::Journal j)
Remove expired credentials referenced by the transaction.
BaseUInt< 160, detail::AccountIDTag > AccountID
A 160-bit unsigned that uniquely identifies an account.
bool isTesSuccess(TER x) noexcept
TERSubset< CanCvtToTER > TER
std::enable_if_t< std::is_same_v< T, char >||std::is_same_v< T, unsigned char >, Slice > makeSlice(std::array< T, N > const &a)
TER checkDepositPreauth(STTx const &tx, ReadView const &view, AccountID const &src, AccountID const &dst, std::shared_ptr< SLE const > const &sleDst, beast::Journal j)
Check whether src is authorized to deposit to dst.
TER verifyDepositPreauth(STTx const &tx, ApplyView &view, AccountID const &src, AccountID const &dst, SLE::const_ref sleDst, beast::Journal j)
T time_since_epoch(T... args)