xrpld
Loading...
Searching...
No Matches
PermissionedDomainSet.cpp
1#include <xrpl/tx/transactors/permissioned_domain/PermissionedDomainSet.h>
2
3#include <xrpl/beast/utility/Zero.h>
4#include <xrpl/core/ServiceRegistry.h>
5#include <xrpl/ledger/helpers/AccountRootHelpers.h>
6#include <xrpl/ledger/helpers/CredentialHelpers.h>
7#include <xrpl/ledger/helpers/DirectoryHelpers.h>
8#include <xrpl/protocol/Feature.h>
9#include <xrpl/protocol/Indexes.h>
10#include <xrpl/protocol/Keylet.h>
11#include <xrpl/protocol/Protocol.h>
12#include <xrpl/protocol/SField.h>
13#include <xrpl/protocol/STLedgerEntry.h>
14#include <xrpl/protocol/STObject.h>
15#include <xrpl/protocol/STTx.h>
16#include <xrpl/protocol/SeqProxy.h>
17#include <xrpl/protocol/TER.h>
18#include <xrpl/protocol/XRPAmount.h>
19#include <xrpl/tx/Transactor.h>
20
21#include <memory>
22#include <utility>
23
24namespace xrpl {
25
26bool
28{
29 return ctx.rules.enabled(featureCredentials);
30}
31
34{
35 if (auto err = credentials::checkArray(
36 ctx.tx.getFieldArray(sfAcceptedCredentials),
38 ctx.j);
39 !isTesSuccess(err))
40 return err;
41
42 auto const domain = ctx.tx.at(~sfDomainID);
43 if (domain && *domain == beast::kZero)
44 return temMALFORMED;
45
46 return tesSUCCESS;
47}
48
49TER
51{
52 auto const account = ctx.tx.getAccountID(sfAccount);
53
54 if (!ctx.view.exists(keylet::account(account)))
55 return tefINTERNAL; // LCOV_EXCL_LINE
56
57 auto const& credentials = ctx.tx.getFieldArray(sfAcceptedCredentials);
58 for (auto const& credential : credentials)
59 {
60 if (!ctx.view.exists(keylet::account(credential.getAccountID(sfIssuer))))
61 return tecNO_ISSUER;
62 }
63
64 if (ctx.tx.isFieldPresent(sfDomainID))
65 {
66 auto const sleDomain =
68 if (!sleDomain)
69 return tecNO_ENTRY;
70 if (sleDomain->getAccountID(sfOwner) != account)
71 return tecNO_PERMISSION;
72 }
73
74 return tesSUCCESS;
75}
76
80TER
82{
83 auto const ownerSle = view().peek(keylet::account(accountID_));
84 if (!ownerSle)
85 return tefINTERNAL; // LCOV_EXCL_LINE
86
87 auto const sortedTxCredentials =
88 credentials::makeSorted(ctx_.tx.getFieldArray(sfAcceptedCredentials));
89 STArray sortedLE(sfAcceptedCredentials, sortedTxCredentials.size());
90 for (auto const& p : sortedTxCredentials)
91 {
92 auto cred = STObject::makeInnerObject(sfCredential);
93 cred.setAccountID(sfIssuer, p.first);
94 cred.setFieldVL(sfCredentialType, p.second);
95 sortedLE.pushBack(std::move(cred));
96 }
97
98 if (ctx_.tx.isFieldPresent(sfDomainID))
99 {
100 // Modify existing permissioned domain.
101 auto slePd = view().peek(keylet::permissionedDomain(ctx_.tx.getFieldH256(sfDomainID)));
102 if (!slePd)
103 return tefINTERNAL; // LCOV_EXCL_LINE
104 slePd->peekFieldArray(sfAcceptedCredentials) = std::move(sortedLE);
105 view().update(slePd);
106 }
107 else
108 {
109 // Create new permissioned domain.
110 // Check reserve availability for new object creation
111 auto const balance = STAmount((*ownerSle)[sfBalance]).xrp();
112 auto const reserve =
113 accountReserve(ctx_.view(), ownerSle, ctx_.journal, {.ownerCountDelta = 1});
114 if (balance < reserve)
116
117 bool const fixEnabled = view().rules().enabled(fixCleanup3_1_3);
118 auto const seq = fixEnabled ? ctx_.tx.getSeqProxy()
119 : SeqProxy::rawSequence(ctx_.tx.getFieldU32(sfSequence));
120 Keylet const pdKeylet = keylet::permissionedDomain(accountID_, seq);
121 auto slePd = std::make_shared<SLE>(pdKeylet);
122
123 slePd->setAccountID(sfOwner, accountID_);
124 slePd->setFieldU32(sfSequence, seq.value());
125 slePd->peekFieldArray(sfAcceptedCredentials) = std::move(sortedLE);
126 auto const page =
128 if (!page)
129 return tecDIR_FULL; // LCOV_EXCL_LINE
130
131 slePd->setFieldU64(sfOwnerNode, *page);
132 // If we succeeded, the new entry counts against the creator's reserve.
133 increaseOwnerCount(view(), ownerSle, {}, 1, ctx_.journal);
134 view().insert(slePd);
135 }
136
137 return tesSUCCESS;
138}
139
140void
142{
143 // No transaction-specific invariants yet (future work).
144}
145
146bool
148 STTx const&,
149 TER,
150 XRPAmount,
151 ReadView const&,
152 beast::Journal const&)
153{
154 // No transaction-specific invariants yet (future work).
155 return true;
156}
157
158} // namespace xrpl
A generic endpoint for log messages.
Definition Journal.h:44
virtual SLE::pointer peek(Keylet const &k)=0
Prepare to modify the SLE associated with key.
virtual void insert(SLE::ref sle)=0
Insert a new state SLE.
std::optional< std::uint64_t > dirInsert(Keylet const &directory, uint256 const &key, std::function< void(SLE::ref)> const &describe)
Insert an entry to a directory.
Definition ApplyView.h:366
virtual void update(SLE::ref sle)=0
Indicate changes to a peeked SLE.
TER doApply() override
Attempt to create the Permissioned Domain.
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 bool checkExtraFeatures(PreflightContext const &ctx)
void visitInvariantEntry(bool isDelete, SLE::const_ref before, SLE::const_ref after) override
Inspect a single ledger entry modified by this transaction.
static TER preclaim(PreclaimContext const &ctx)
static NotTEC preflight(PreflightContext const &ctx)
A view into a ledger.
Definition ReadView.h:41
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.
bool enabled(uint256 const &feature) const
Returns true if a feature is enabled.
Definition Rules.cpp:180
XRPAmount xrp() const
Definition STAmount.cpp:271
void pushBack(STObject const &object)
Definition STArray.h:212
std::shared_ptr< STLedgerEntry const > const & const_ref
T::value_type at(TypedField< T > const &f) const
Get the value of a field.
Definition STObject.h:1078
STArray const & getFieldArray(SField const &field) const
Definition STObject.cpp:688
bool isFieldPresent(SField const &field) const
Definition STObject.cpp:464
uint256 getFieldH256(SField const &field) const
Definition STObject.cpp:631
static STObject makeInnerObject(SField const &name)
Definition STObject.cpp:79
AccountID getAccountID(SField const &field) const
Definition STObject.cpp:643
static constexpr SeqProxy rawSequence(std::uint32_t v)
Factory function to return a sequence-based SeqProxy.
Definition SeqProxy.h:62
ApplyView & view()
Definition Transactor.h:175
AccountID const accountID_
Definition Transactor.h:157
ApplyContext & ctx_
Definition Transactor.h:153
T make_shared(T... args)
constexpr Zero kZero
Definition Zero.h:30
std::set< std::pair< AccountID, Slice > > makeSorted(STArray const &credentials)
NotTEC checkArray(STArray const &credentials, unsigned maxSize, beast::Journal j)
Keylet ownerDir(AccountID const &id) noexcept
The root page of an account's directory.
Definition Indexes.cpp:373
Keylet permissionedDomain(AccountID const &account, SeqProxy const &seq) noexcept
Definition Indexes.cpp:579
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition Indexes.cpp:198
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
void increaseOwnerCount(ApplyView &view, SLE::ref accountSle, SLE::ref sponsorSle, std::uint32_t count, beast::Journal j)
Increase owner-count fields when the caller supplies the sponsor.
@ tefINTERNAL
Definition TER.h:165
TERSubset< CanCvtToNotTEC > NotTEC
Definition TER.h:607
std::function< void(SLE::ref)> describeOwnerDir(AccountID const &account)
Returns a function that sets the owner on a directory SLE.
@ temMALFORMED
Definition TER.h:75
bool isTesSuccess(TER x) noexcept
Definition TER.h:676
TERSubset< CanCvtToTER > TER
Definition TER.h:647
constexpr std::size_t kMaxPermissionedDomainCredentialsArraySize
The maximum number of credentials can be passed in array for permissioned domain.
Definition Protocol.h:286
@ tecDIR_FULL
Definition TER.h:290
@ tecNO_ENTRY
Definition TER.h:309
@ tecINSUFFICIENT_RESERVE
Definition TER.h:310
@ tecNO_PERMISSION
Definition TER.h:308
@ tecNO_ISSUER
Definition TER.h:302
XRPAmount accountReserve(ReadView const &view, SLE::const_ref sle, beast::Journal j, Adjustment adj={})
Returns the account reserve, in drops.
@ tesSUCCESS
Definition TER.h:245
A pair of SHAMap key and LedgerEntryType.
Definition Keylet.h:20
State information when determining if a tx is likely to claim a fee.
Definition Transactor.h:83
ReadView const & view
Definition Transactor.h:86
State information when preflighting a tx.
Definition Transactor.h:38
beast::Journal const j
Definition Transactor.h:45