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/misc/CredentialHelpers.h>
21#include <xrpld/app/tx/detail/PermissionedDomainSet.h>
22#include <xrpld/ledger/View.h>
23
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()
Definition: ApplyContext.h:55
beast::Journal const journal
Definition: ApplyContext.h:52
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:315
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:651
STArray const & getFieldArray(SField const &field) const
Definition: STObject.cpp:686
T::value_type at(TypedField< T > const &f) const
Get the value of a field.
Definition: STObject.h:1038
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:93
ApplyView & view()
Definition: Transactor.h:109
ApplyContext & ctx_
Definition: Transactor.h:90
A balance matches.
Definition: balance.h:39
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:563
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition: Indexes.cpp:177
Keylet ownerDir(AccountID const &id) noexcept
The root page of an account's directory.
Definition: Indexes.cpp:367
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: algorithm.h:26
std::size_t constexpr maxPermissionedDomainCredentialsArraySize
The maximum number of credentials can be passed in array for permissioned domain.
Definition: Protocol.h:111
bool isTesSuccess(TER x)
Definition: TER.h:672
std::function< void(SLE::ref)> describeOwnerDir(AccountID const &account)
Definition: View.cpp:1037
NotTEC preflight1(PreflightContext const &ctx)
Performs early sanity checks on the account and fee fields.
Definition: Transactor.cpp:83
@ tefINTERNAL
Definition: TER.h:173
static bool adjustOwnerCount(ApplyContext &ctx, int count)
Definition: SetOracle.cpp:186
NotTEC preflight2(PreflightContext const &ctx)
Checks whether the signature appears valid.
Definition: Transactor.cpp:144
@ 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
constexpr std::uint32_t tfUniversalMask
Definition: TxFlags.h:62
@ credential
Credentials signature.
TERSubset< CanCvtToNotTEC > NotTEC
Definition: TER.h:603
@ 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.
Definition: protocol/Fees.h:49
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:55
ReadView const & view
Definition: Transactor.h:58
State information when preflighting a tx.
Definition: Transactor.h:34
beast::Journal const j
Definition: Transactor.h:40