xrpld
Loading...
Searching...
No Matches
NFTokenCancelOffer.cpp
1#include <xrpl/tx/transactors/nft/NFTokenCancelOffer.h>
2
3#include <xrpl/basics/Log.h>
4#include <xrpl/basics/base_uint.h>
5#include <xrpl/ledger/View.h>
6#include <xrpl/ledger/helpers/NFTokenHelpers.h>
7#include <xrpl/protocol/Feature.h>
8#include <xrpl/protocol/Indexes.h>
9#include <xrpl/protocol/LedgerFormats.h>
10#include <xrpl/protocol/Protocol.h>
11#include <xrpl/protocol/SField.h>
12#include <xrpl/protocol/STLedgerEntry.h>
13#include <xrpl/protocol/STTx.h>
14#include <xrpl/protocol/STVector256.h>
15#include <xrpl/protocol/TER.h>
16#include <xrpl/protocol/XRPAmount.h>
17#include <xrpl/tx/Transactor.h>
18
19#include <algorithm>
20namespace xrpl {
21
24{
25 auto const& offerIds = ctx.tx[sfNFTokenOffers];
26
27 if (offerIds.empty() || (offerIds.size() > kMaxTokenOfferCancelCount))
28 return temMALFORMED;
29
30 // Zero offer IDs cannot be passed as ledger entry keys.
31 if (ctx.rules.enabled(fixCleanup3_2_0) &&
32 std::ranges::any_of(offerIds, [](uint256 const& id) { return id.isZero(); }))
33 return temMALFORMED;
34
35 // In order to prevent unnecessarily overlarge transactions, we
36 // disallow duplicates in the list of offers to cancel.
37 STVector256 ids = ctx.tx.getFieldV256(sfNFTokenOffers);
39 if (std::ranges::adjacent_find(ids) != ids.end())
40 return temMALFORMED;
41
42 return tesSUCCESS;
43}
44
45TER
47{
48 auto const account = ctx.tx[sfAccount];
49
50 auto const& ids = ctx.tx[sfNFTokenOffers];
51
52 auto ret = std::ranges::find_if(ids, [&ctx, &account](uint256 const& id) {
53 auto const offer = ctx.view.read(keylet::child(id));
54
55 // If id is not in the ledger we assume the offer was consumed
56 // before we got here.
57 if (!offer)
58 return false;
59
60 // If id is in the ledger but is not an NFTokenOffer, then
61 // they have no permission.
62 if (offer->getType() != ltNFTOKEN_OFFER)
63 return true;
64
65 // Anyone can cancel, if expired
66 if (hasExpired(ctx.view, (*offer)[~sfExpiration]))
67 return false;
68
69 // The owner can always cancel
70 if ((*offer)[sfOwner] == account)
71 return false;
72
73 // The recipient can always cancel
74 if (auto const dest = (*offer)[~sfDestination]; dest == account)
75 return false;
76
77 return true;
78 });
79
80 if (ret != ids.end())
81 return tecNO_PERMISSION;
82
83 return tesSUCCESS;
84}
85
86TER
88{
89 for (auto const& id : ctx_.tx[sfNFTokenOffers])
90 {
91 if (auto offer = view().peek(keylet::nftokenOffer(id));
92 offer && !nft::deleteTokenOffer(view(), offer))
93 {
94 // LCOV_EXCL_START
95 JLOG(j_.fatal()) << "Unable to delete token offer " << id << " (ledger " << view().seq()
96 << ")";
97 return tefBAD_LEDGER;
98 // LCOV_EXCL_STOP
99 }
100 }
101
102 return tesSUCCESS;
103}
104
105void
107{
108 // No transaction-specific invariants yet (future work).
109}
110
111bool
113 STTx const&,
114 TER,
115 XRPAmount,
116 ReadView const&,
117 beast::Journal const&)
118{
119 // No transaction-specific invariants yet (future work).
120 return true;
121}
122
123} // namespace xrpl
T adjacent_find(T... args)
T any_of(T... args)
A generic endpoint for log messages.
Definition Journal.h:38
static NotTEC preflight(PreflightContext const &ctx)
static TER preclaim(PreclaimContext const &ctx)
void visitInvariantEntry(bool isDelete, SLE::const_ref before, SLE::const_ref after) override
Inspect a single ledger entry modified by this transaction.
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.
A view into a ledger.
Definition ReadView.h:31
virtual SLE::const_pointer read(Keylet const &k) const =0
Return the state item associated with a key.
LedgerIndex seq() const
Returns the sequence number of the base ledger.
Definition ReadView.h:97
bool enabled(uint256 const &feature) const
Returns true if a feature is enabled.
Definition Rules.cpp:171
std::shared_ptr< STLedgerEntry const > const & const_ref
STVector256 const & getFieldV256(SField const &field) const
Definition STObject.cpp:661
std::vector< uint256 >::iterator end()
beast::Journal const j_
Definition Transactor.h:118
ApplyView & view()
Definition Transactor.h:136
ApplyContext & ctx_
Definition Transactor.h:116
T find_if(T... args)
Keylet child(uint256 const &key) noexcept
Any item that can be in an owner dir.
Definition Indexes.cpp:192
Keylet nftokenOffer(AccountID const &owner, std::uint32_t seq)
An offer from an account to buy or sell an NFT.
Definition Indexes.cpp:407
bool deleteTokenOffer(ApplyView &view, SLE::ref offer)
Deletes the given token offer.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
bool hasExpired(ReadView const &view, std::optional< std::uint32_t > const &exp)
Determines whether the given expiration time has passed.
Definition View.cpp:47
@ tefBAD_LEDGER
Definition TER.h:160
TERSubset< CanCvtToNotTEC > NotTEC
Definition TER.h:594
constexpr std::size_t kMaxTokenOfferCancelCount
The maximum number of token offers that can be canceled at once.
Definition Protocol.h:56
@ temMALFORMED
Definition TER.h:73
TERSubset< CanCvtToTER > TER
Definition TER.h:634
@ tecNO_PERMISSION
Definition TER.h:303
BaseUInt< 256 > uint256
Definition base_uint.h:562
@ tesSUCCESS
Definition TER.h:240
T sort(T... args)
State information when determining if a tx is likely to claim a fee.
Definition Transactor.h:61
ReadView const & view
Definition Transactor.h:64
State information when preflighting a tx.
Definition Transactor.h:18