rippled
Loading...
Searching...
No Matches
NFTokenCancelOffer.cpp
1#include <xrpld/app/tx/detail/NFTokenCancelOffer.h>
2#include <xrpld/app/tx/detail/NFTokenUtils.h>
3
4#include <xrpl/ledger/View.h>
5#include <xrpl/protocol/Feature.h>
6#include <xrpl/protocol/TxFlags.h>
7
8#include <boost/endian/conversion.hpp>
9
10namespace ripple {
11
17
20{
21 if (auto const& ids = ctx.tx[sfNFTokenOffers];
22 ids.empty() || (ids.size() > maxTokenOfferCancelCount))
23 return temMALFORMED;
24
25 // In order to prevent unnecessarily overlarge transactions, we
26 // disallow duplicates in the list of offers to cancel.
27 STVector256 ids = ctx.tx.getFieldV256(sfNFTokenOffers);
28 std::sort(ids.begin(), ids.end());
29 if (std::adjacent_find(ids.begin(), ids.end()) != ids.end())
30 return temMALFORMED;
31
32 return tesSUCCESS;
33}
34
35TER
37{
38 auto const account = ctx.tx[sfAccount];
39
40 auto const& ids = ctx.tx[sfNFTokenOffers];
41
42 auto ret = std::find_if(
43 ids.begin(), ids.end(), [&ctx, &account](uint256 const& id) {
44 auto const offer = ctx.view.read(keylet::child(id));
45
46 // If id is not in the ledger we assume the offer was consumed
47 // before we got here.
48 if (!offer)
49 return false;
50
51 // If id is in the ledger but is not an NFTokenOffer, then
52 // they have no permission.
53 if (offer->getType() != ltNFTOKEN_OFFER)
54 return true;
55
56 // Anyone can cancel, if expired
57 if (hasExpired(ctx.view, (*offer)[~sfExpiration]))
58 return false;
59
60 // The owner can always cancel
61 if ((*offer)[sfOwner] == account)
62 return false;
63
64 // The recipient can always cancel
65 if (auto const dest = (*offer)[~sfDestination]; dest == account)
66 return false;
67
68 return true;
69 });
70
71 if (ret != ids.end())
72 return tecNO_PERMISSION;
73
74 return tesSUCCESS;
75}
76
77TER
79{
80 for (auto const& id : ctx_.tx[sfNFTokenOffers])
81 {
82 if (auto offer = view().peek(keylet::nftoffer(id));
83 offer && !nft::deleteTokenOffer(view(), offer))
84 {
85 // LCOV_EXCL_START
86 JLOG(j_.fatal()) << "Unable to delete token offer " << id
87 << " (ledger " << view().seq() << ")";
88 return tefBAD_LEDGER;
89 // LCOV_EXCL_STOP
90 }
91 }
92
93 return tesSUCCESS;
94}
95
96} // namespace ripple
T adjacent_find(T... args)
Stream fatal() const
Definition Journal.h:333
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 std::uint32_t getFlagsMask(PreflightContext const &ctx)
static TER preclaim(PreclaimContext const &ctx)
LedgerIndex seq() const
Returns the sequence number of the base ledger.
Definition ReadView.h:99
STVector256 const & getFieldV256(SField const &field) const
Definition STObject.cpp:666
std::vector< uint256 >::iterator begin()
std::vector< uint256 >::iterator end()
ApplyView & view()
Definition Transactor.h:144
beast::Journal const j_
Definition Transactor.h:126
ApplyContext & ctx_
Definition Transactor.h:124
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:408
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:6
std::size_t constexpr maxTokenOfferCancelCount
The maximum number of token offers that can be canceled at once.
Definition Protocol.h:52
@ tefBAD_LEDGER
Definition TER.h:151
@ tecNO_PERMISSION
Definition TER.h:287
@ tesSUCCESS
Definition TER.h:226
constexpr std::uint32_t const tfNFTokenCancelOfferMask
Definition TxFlags.h:216
@ temMALFORMED
Definition TER.h:68
T sort(T... args)
State information when determining if a tx is likely to claim a fee.
Definition Transactor.h:61
State information when preflighting a tx.
Definition Transactor.h:16