rippled
Loading...
Searching...
No Matches
PermissionedDomainSet.cpp
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2024 Ripple Labs Inc.
5
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#include <xrpld/app/tx/detail/PermissionedDomainSet.h>
21
22#include <xrpl/ledger/CredentialHelpers.h>
23#include <xrpl/ledger/View.h>
24#include <xrpl/protocol/STObject.h>
25#include <xrpl/protocol/TxFlags.h>
26
27#include <optional>
28
29namespace ripple {
30
33{
34 if (!ctx.rules.enabled(featurePermissionedDomains) ||
35 !ctx.rules.enabled(featureCredentials))
36 return temDISABLED;
37
38 if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
39 return ret;
40
41 if (ctx.tx.getFlags() & tfUniversalMask)
42 {
43 JLOG(ctx.j.debug()) << "PermissionedDomainSet: invalid flags.";
44 return temINVALID_FLAG;
45 }
46
47 if (auto err = credentials::checkArray(
48 ctx.tx.getFieldArray(sfAcceptedCredentials),
50 ctx.j);
51 !isTesSuccess(err))
52 return err;
53
54 auto const domain = ctx.tx.at(~sfDomainID);
55 if (domain && *domain == beast::zero)
56 return temMALFORMED;
57
58 return preflight2(ctx);
59}
60
61TER
63{
64 auto const account = ctx.tx.getAccountID(sfAccount);
65
66 if (!ctx.view.exists(keylet::account(account)))
67 return tefINTERNAL; // LCOV_EXCL_LINE
68
69 auto const& credentials = ctx.tx.getFieldArray(sfAcceptedCredentials);
70 for (auto const& credential : credentials)
71 {
72 if (!ctx.view.exists(
73 keylet::account(credential.getAccountID(sfIssuer))))
74 return tecNO_ISSUER;
75 }
76
77 if (ctx.tx.isFieldPresent(sfDomainID))
78 {
79 auto const sleDomain = ctx.view.read(
81 if (!sleDomain)
82 return tecNO_ENTRY;
83 if (sleDomain->getAccountID(sfOwner) != account)
84 return tecNO_PERMISSION;
85 }
86
87 return tesSUCCESS;
88}
89
91TER
93{
94 auto const ownerSle = view().peek(keylet::account(account_));
95 if (!ownerSle)
96 return tefINTERNAL; // LCOV_EXCL_LINE
97
98 auto const sortedTxCredentials =
99 credentials::makeSorted(ctx_.tx.getFieldArray(sfAcceptedCredentials));
100 STArray sortedLE(sfAcceptedCredentials, sortedTxCredentials.size());
101 for (auto const& p : sortedTxCredentials)
102 {
103 auto cred = STObject::makeInnerObject(sfCredential);
104 cred.setAccountID(sfIssuer, p.first);
105 cred.setFieldVL(sfCredentialType, p.second);
106 sortedLE.push_back(std::move(cred));
107 }
108
109 if (ctx_.tx.isFieldPresent(sfDomainID))
110 {
111 // Modify existing permissioned domain.
112 auto slePd = view().peek(
114 if (!slePd)
115 return tefINTERNAL; // LCOV_EXCL_LINE
116 slePd->peekFieldArray(sfAcceptedCredentials) = std::move(sortedLE);
117 view().update(slePd);
118 }
119 else
120 {
121 // Create new permissioned domain.
122 // Check reserve availability for new object creation
123 auto const balance = STAmount((*ownerSle)[sfBalance]).xrp();
124 auto const reserve =
125 ctx_.view().fees().accountReserve((*ownerSle)[sfOwnerCount] + 1);
126 if (balance < reserve)
128
129 Keylet const pdKeylet = keylet::permissionedDomain(
130 account_, ctx_.tx.getFieldU32(sfSequence));
131 auto slePd = std::make_shared<SLE>(pdKeylet);
132 if (!slePd)
133 return tefINTERNAL; // LCOV_EXCL_LINE
134
135 slePd->setAccountID(sfOwner, account_);
136 slePd->setFieldU32(sfSequence, ctx_.tx.getFieldU32(sfSequence));
137 slePd->peekFieldArray(sfAcceptedCredentials) = std::move(sortedLE);
138 auto const page = view().dirInsert(
140 if (!page)
141 return tecDIR_FULL; // LCOV_EXCL_LINE
142
143 slePd->setFieldU64(sfOwnerNode, *page);
144 // If we succeeded, the new entry counts against the creator's reserve.
145 adjustOwnerCount(view(), ownerSle, 1, ctx_.journal);
146 view().insert(slePd);
147 }
148
149 return tesSUCCESS;
150}
151
152} // namespace ripple
Stream debug() const
Definition Journal.h:328
ApplyView & view()
beast::Journal const journal
virtual void update(std::shared_ptr< SLE > const &sle)=0
Indicate changes to a peeked SLE.
virtual void insert(std::shared_ptr< SLE > const &sle)=0
Insert a new state SLE.
std::optional< std::uint64_t > dirInsert(Keylet const &directory, uint256 const &key, std::function< void(std::shared_ptr< SLE > const &)> const &describe)
Insert an entry to a directory.
Definition ApplyView.h:317
virtual std::shared_ptr< SLE > peek(Keylet const &k)=0
Prepare to modify the SLE associated with key.
static NotTEC preflight(PreflightContext const &ctx)
static TER preclaim(PreclaimContext const &ctx)
TER doApply() override
Attempt to create the Permissioned Domain.
virtual std::shared_ptr< SLE const > read(Keylet const &k) const =0
Return the state item associated with a key.
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.
bool enabled(uint256 const &feature) const
Returns true if a feature is enabled.
Definition Rules.cpp:130
XRPAmount xrp() const
Definition STAmount.cpp:306
void push_back(STObject const &object)
Definition STArray.h:212
AccountID getAccountID(SField const &field) const
Definition STObject.cpp:657
STArray const & getFieldArray(SField const &field) const
Definition STObject.cpp:692
T::value_type at(TypedField< T > const &f) const
Get the value of a field.
Definition STObject.h:1042
std::uint32_t getFieldU32(SField const &field) const
Definition STObject.cpp:615
bool isFieldPresent(SField const &field) const
Definition STObject.cpp:484
static STObject makeInnerObject(SField const &name)
Definition STObject.cpp:95
std::uint32_t getFlags() const
Definition STObject.cpp:537
uint256 getFieldH256(SField const &field) const
Definition STObject.cpp:645
AccountID const account_
Definition Transactor.h:145
ApplyView & view()
Definition Transactor.h:161
ApplyContext & ctx_
Definition Transactor.h:141
T is_same_v
NotTEC checkArray(STArray const &credentials, unsigned maxSize, beast::Journal j)
std::set< std::pair< AccountID, Slice > > makeSorted(STArray const &credentials)
Keylet permissionedDomain(AccountID const &account, std::uint32_t seq) noexcept
Definition Indexes.cpp:570
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition Indexes.cpp:184
Keylet ownerDir(AccountID const &id) noexcept
The root page of an account's directory.
Definition Indexes.cpp:374
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:25
std::size_t constexpr maxPermissionedDomainCredentialsArraySize
The maximum number of credentials can be passed in array for permissioned domain.
Definition Protocol.h:110
void adjustOwnerCount(ApplyView &view, std::shared_ptr< SLE > const &sle, std::int32_t amount, beast::Journal j)
Adjust the owner count up or down.
Definition View.cpp:1029
std::function< void(SLE::ref)> describeOwnerDir(AccountID const &account)
Definition View.cpp:1047
NotTEC preflight1(PreflightContext const &ctx)
Performs early sanity checks on the account and fee fields.
@ tefINTERNAL
Definition TER.h:173
NotTEC preflight2(PreflightContext const &ctx)
Checks whether the signature appears valid.
@ tecNO_ENTRY
Definition TER.h:306
@ tecNO_ISSUER
Definition TER.h:299
@ tecDIR_FULL
Definition TER.h:287
@ tecNO_PERMISSION
Definition TER.h:305
@ tecINSUFFICIENT_RESERVE
Definition TER.h:307
@ tesSUCCESS
Definition TER.h:244
bool isTesSuccess(TER x) noexcept
Definition TER.h:674
constexpr std::uint32_t tfUniversalMask
Definition TxFlags.h:63
@ credential
Credentials signature.
TERSubset< CanCvtToNotTEC > NotTEC
Definition TER.h:605
@ temMALFORMED
Definition TER.h:87
@ temINVALID_FLAG
Definition TER.h:111
@ temDISABLED
Definition TER.h:114
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:39
State information when determining if a tx is likely to claim a fee.
Definition Transactor.h:80
ReadView const & view
Definition Transactor.h:83
State information when preflighting a tx.
Definition Transactor.h:35
beast::Journal const j
Definition Transactor.h:42