rippled
Loading...
Searching...
No Matches
DelegateSet.cpp
1#include <xrpl/basics/Log.h>
2#include <xrpl/ledger/View.h>
3#include <xrpl/ledger/helpers/AccountRootHelpers.h>
4#include <xrpl/ledger/helpers/DirectoryHelpers.h>
5#include <xrpl/protocol/Feature.h>
6#include <xrpl/protocol/Indexes.h>
7#include <xrpl/protocol/st.h>
8#include <xrpl/tx/transactors/delegate/DelegateSet.h>
9
10namespace xrpl {
11
14{
15 auto const& permissions = ctx.tx.getFieldArray(sfPermissions);
16 if (permissions.size() > permissionMaxSize)
17 return temARRAY_TOO_LARGE;
18
19 // can not authorize self
20 if (ctx.tx[sfAccount] == ctx.tx[sfAuthorize])
21 return temMALFORMED;
22
24
25 for (auto const& permission : permissions)
26 {
27 if (!permissionSet.insert(permission[sfPermissionValue]).second)
28 return temMALFORMED;
29
30 if (!Permission::getInstance().isDelegable(permission[sfPermissionValue], ctx.rules))
31 return temMALFORMED;
32 }
33
34 return tesSUCCESS;
35}
36
37TER
39{
40 if (!ctx.view.exists(keylet::account(ctx.tx[sfAccount])))
41 return terNO_ACCOUNT; // LCOV_EXCL_LINE
42
43 if (!ctx.view.exists(keylet::account(ctx.tx[sfAuthorize])))
44 return tecNO_TARGET;
45
46 // Deleting the delegate object is invalid if it doesn’t exist.
47 if (ctx.tx.getFieldArray(sfPermissions).empty() &&
48 !ctx.view.exists(keylet::delegate(ctx.tx[sfAccount], ctx.tx[sfAuthorize])))
49 {
50 return tecNO_ENTRY;
51 }
52
53 return tesSUCCESS;
54}
55
56TER
58{
59 auto const sleOwner = ctx_.view().peek(keylet::account(account_));
60 if (!sleOwner)
61 return tefINTERNAL; // LCOV_EXCL_LINE
62
63 auto const& authAccount = ctx_.tx[sfAuthorize];
64 auto const delegateKey = keylet::delegate(account_, authAccount);
65
66 auto sle = ctx_.view().peek(delegateKey);
67 if (sle)
68 {
69 auto const& permissions = ctx_.tx.getFieldArray(sfPermissions);
70 if (permissions.empty())
71 {
72 // if permissions array is empty, delete the ledger object.
73 return deleteDelegate(view(), sle, account_, j_);
74 }
75
76 sle->setFieldArray(sfPermissions, permissions);
77 ctx_.view().update(sle);
78 return tesSUCCESS;
79 }
80
81 auto const& permissions = ctx_.tx.getFieldArray(sfPermissions);
82 if (permissions.empty())
83 return tecINTERNAL; // LCOV_EXCL_LINE
84
85 STAmount const reserve{
86 ctx_.view().fees().accountReserve(sleOwner->getFieldU32(sfOwnerCount) + 1)};
87
88 if (preFeeBalance_ < reserve)
90
91 sle = std::make_shared<SLE>(delegateKey);
92 sle->setAccountID(sfAccount, account_);
93 sle->setAccountID(sfAuthorize, authAccount);
94
95 sle->setFieldArray(sfPermissions, permissions);
96 auto const page =
98
99 if (!page)
100 return tecDIR_FULL; // LCOV_EXCL_LINE
101
102 (*sle)[sfOwnerNode] = *page;
103 ctx_.view().insert(sle);
104 adjustOwnerCount(ctx_.view(), sleOwner, 1, ctx_.journal);
105
106 return tesSUCCESS;
107}
108
109TER
111 ApplyView& view,
112 std::shared_ptr<SLE> const& sle,
113 AccountID const& account,
115{
116 if (!sle)
117 return tecINTERNAL; // LCOV_EXCL_LINE
118
119 if (!view.dirRemove(keylet::ownerDir(account), (*sle)[sfOwnerNode], sle->key(), false))
120 {
121 // LCOV_EXCL_START
122 JLOG(j.fatal()) << "Unable to delete Delegate from owner.";
123 return tefBAD_LEDGER;
124 // LCOV_EXCL_STOP
125 }
126
127 auto const sleOwner = view.peek(keylet::account(account));
128 if (!sleOwner)
129 return tecINTERNAL; // LCOV_EXCL_LINE
130
131 adjustOwnerCount(view, sleOwner, -1, j);
132
133 view.erase(sle);
134
135 return tesSUCCESS;
136}
137
138} // namespace xrpl
A generic endpoint for log messages.
Definition Journal.h:40
Stream fatal() const
Definition Journal.h:325
STTx const & tx
beast::Journal const journal
ApplyView & view()
Writeable view to a ledger, for applying a transaction.
Definition ApplyView.h:116
virtual void update(std::shared_ptr< SLE > const &sle)=0
Indicate changes to a peeked SLE.
bool dirRemove(Keylet const &directory, std::uint64_t page, uint256 const &key, bool keepRoot)
Remove an entry from a directory.
virtual void erase(std::shared_ptr< SLE > const &sle)=0
Remove 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:289
virtual std::shared_ptr< SLE > peek(Keylet const &k)=0
Prepare to modify the SLE associated with key.
static TER deleteDelegate(ApplyView &view, std::shared_ptr< SLE > const &sle, AccountID const &account, beast::Journal j)
static NotTEC preflight(PreflightContext const &ctx)
TER doApply() override
static TER preclaim(PreclaimContext const &ctx)
bool isDelegable(std::uint32_t const &permissionValue, Rules const &rules) const
static Permission const & getInstance()
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 empty() const
Definition STArray.h:231
STArray const & getFieldArray(SField const &field) const
Definition STObject.cpp:680
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
T insert(T... args)
T is_same_v
Keylet ownerDir(AccountID const &id) noexcept
The root page of an account's directory.
Definition Indexes.cpp:336
Keylet delegate(AccountID const &account, AccountID const &authorizedAccount) noexcept
A keylet for Delegate object.
Definition Indexes.cpp:418
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition Indexes.cpp:165
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
@ terNO_ACCOUNT
Definition TER.h:197
@ tefBAD_LEDGER
Definition TER.h:150
@ 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.
std::function< void(SLE::ref)> describeOwnerDir(AccountID const &account)
Returns a function that sets the owner on a directory SLE.
@ temARRAY_TOO_LARGE
Definition TER.h:121
@ temMALFORMED
Definition TER.h:67
@ tecDIR_FULL
Definition TER.h:268
@ tecNO_ENTRY
Definition TER.h:287
@ tecNO_TARGET
Definition TER.h:285
@ tecINTERNAL
Definition TER.h:291
@ tecINSUFFICIENT_RESERVE
Definition TER.h:288
TERSubset< CanCvtToNotTEC > NotTEC
Definition TER.h:582
@ tesSUCCESS
Definition TER.h:225
std::size_t constexpr permissionMaxSize
The maximum number of delegate permissions an account can grant.
Definition Protocol.h:305
XRPAmount accountReserve(std::size_t ownerCount) const
Returns the account reserve given the owner count, in drops.
State information when determining if a tx is likely to claim a fee.
Definition Transactor.h:57
ReadView const & view
Definition Transactor.h:60
State information when preflighting a tx.
Definition Transactor.h:14