rippled
Loading...
Searching...
No Matches
NFTokenCancelOffer.cpp
1#include <xrpl/ledger/View.h>
2#include <xrpl/protocol/Feature.h>
3#include <xrpl/protocol/TxFlags.h>
4#include <xrpl/tx/transactors/nft/NFTokenCancelOffer.h>
5#include <xrpl/tx/transactors/nft/NFTokenUtils.h>
6
7#include <boost/endian/conversion.hpp>
8
9namespace xrpl {
10
13{
14 if (auto const& ids = ctx.tx[sfNFTokenOffers];
15 ids.empty() || (ids.size() > maxTokenOfferCancelCount))
16 return temMALFORMED;
17
18 // In order to prevent unnecessarily overlarge transactions, we
19 // disallow duplicates in the list of offers to cancel.
20 STVector256 ids = ctx.tx.getFieldV256(sfNFTokenOffers);
21 std::sort(ids.begin(), ids.end());
22 if (std::adjacent_find(ids.begin(), ids.end()) != ids.end())
23 return temMALFORMED;
24
25 return tesSUCCESS;
26}
27
28TER
30{
31 auto const account = ctx.tx[sfAccount];
32
33 auto const& ids = ctx.tx[sfNFTokenOffers];
34
35 auto ret = std::find_if(ids.begin(), ids.end(), [&ctx, &account](uint256 const& id) {
36 auto const offer = ctx.view.read(keylet::child(id));
37
38 // If id is not in the ledger we assume the offer was consumed
39 // before we got here.
40 if (!offer)
41 return false;
42
43 // If id is in the ledger but is not an NFTokenOffer, then
44 // they have no permission.
45 if (offer->getType() != ltNFTOKEN_OFFER)
46 return true;
47
48 // Anyone can cancel, if expired
49 if (hasExpired(ctx.view, (*offer)[~sfExpiration]))
50 return false;
51
52 // The owner can always cancel
53 if ((*offer)[sfOwner] == account)
54 return false;
55
56 // The recipient can always cancel
57 if (auto const dest = (*offer)[~sfDestination]; dest == account)
58 return false;
59
60 return true;
61 });
62
63 if (ret != ids.end())
64 return tecNO_PERMISSION;
65
66 return tesSUCCESS;
67}
68
69TER
71{
72 for (auto const& id : ctx_.tx[sfNFTokenOffers])
73 {
74 if (auto offer = view().peek(keylet::nftoffer(id));
75 offer && !nft::deleteTokenOffer(view(), offer))
76 {
77 // LCOV_EXCL_START
78 JLOG(j_.fatal()) << "Unable to delete token offer " << id << " (ledger " << view().seq()
79 << ")";
80 return tefBAD_LEDGER;
81 // LCOV_EXCL_STOP
82 }
83 }
84
85 return tesSUCCESS;
86}
87
88} // namespace xrpl
T adjacent_find(T... args)
Stream fatal() const
Definition Journal.h:325
STTx const & tx
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)
LedgerIndex seq() const
Returns the sequence number of the base ledger.
Definition ReadView.h:97
STVector256 const & getFieldV256(SField const &field) const
Definition STObject.cpp:663
std::vector< uint256 >::iterator begin()
std::vector< uint256 >::iterator end()
beast::Journal const j_
Definition Transactor.h:114
ApplyView & view()
Definition Transactor.h:132
ApplyContext & ctx_
Definition Transactor.h:112
T find_if(T... args)
Keylet nftoffer(AccountID const &owner, std::uint32_t seq)
An offer from an account to buy or sell an NFT.
Definition Indexes.cpp:386
bool deleteTokenOffer(ApplyView &view, std::shared_ptr< SLE > const &offer)
Deletes the given token offer.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
@ tefBAD_LEDGER
Definition TER.h:150
@ temMALFORMED
Definition TER.h:67
@ tecNO_PERMISSION
Definition TER.h:286
TERSubset< CanCvtToNotTEC > NotTEC
Definition TER.h:582
@ tesSUCCESS
Definition TER.h:225
std::size_t constexpr maxTokenOfferCancelCount
The maximum number of token offers that can be canceled at once.
Definition Protocol.h:52
T sort(T... args)
State information when determining if a tx is likely to claim a fee.
Definition Transactor.h:57
State information when preflighting a tx.
Definition Transactor.h:14