rippled
NFTokenCancelOffer.cpp
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2021 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 <ripple/app/tx/impl/NFTokenCancelOffer.h>
21 #include <ripple/app/tx/impl/details/NFTokenUtils.h>
22 #include <ripple/ledger/View.h>
23 #include <ripple/protocol/Feature.h>
24 #include <ripple/protocol/TxFlags.h>
25 #include <ripple/protocol/st.h>
26 #include <boost/endian/conversion.hpp>
27 
28 namespace ripple {
29 
30 NotTEC
32 {
34  return temDISABLED;
35 
36  if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
37  return ret;
38 
40  return temINVALID_FLAG;
41 
42  if (auto const& ids = ctx.tx[sfNFTokenOffers];
43  ids.empty() || (ids.size() > maxTokenOfferCancelCount))
44  return temMALFORMED;
45 
46  // In order to prevent unnecessarily overlarge transactions, we
47  // disallow duplicates in the list of offers to cancel.
49  std::sort(ids.begin(), ids.end());
50  if (std::adjacent_find(ids.begin(), ids.end()) != ids.end())
51  return temMALFORMED;
52 
53  return preflight2(ctx);
54 }
55 
56 TER
58 {
59  auto const account = ctx.tx[sfAccount];
60 
61  auto const& ids = ctx.tx[sfNFTokenOffers];
62 
63  auto ret = std::find_if(
64  ids.begin(), ids.end(), [&ctx, &account](uint256 const& id) {
65  auto const offer = ctx.view.read(keylet::child(id));
66 
67  // If id is not in the ledger we assume the offer was consumed
68  // before we got here.
69  if (!offer)
70  return false;
71 
72  // If id is in the ledger but is not an NFTokenOffer, then
73  // they have no permission.
74  if (offer->getType() != ltNFTOKEN_OFFER)
75  return true;
76 
77  // Anyone can cancel, if expired
78  if (hasExpired(ctx.view, (*offer)[~sfExpiration]))
79  return false;
80 
81  // The owner can always cancel
82  if ((*offer)[sfOwner] == account)
83  return false;
84 
85  // The recipient can always cancel
86  if (auto const dest = (*offer)[~sfDestination]; dest == account)
87  return false;
88 
89  return true;
90  });
91 
92  if (ret != ids.end())
93  return tecNO_PERMISSION;
94 
95  return tesSUCCESS;
96 }
97 
98 TER
100 {
101  for (auto const& id : ctx_.tx[sfNFTokenOffers])
102  {
103  if (auto offer = view().peek(keylet::nftoffer(id));
104  offer && !nft::deleteTokenOffer(view(), offer))
105  {
106  JLOG(j_.fatal()) << "Unable to delete token offer " << id
107  << " (ledger " << view().seq() << ")";
108  return tefBAD_LEDGER;
109  }
110  }
111 
112  return tesSUCCESS;
113 }
114 
115 } // namespace ripple
beast::Journal::fatal
Stream fatal() const
Definition: Journal.h:339
ripple::NFTokenCancelOffer::doApply
TER doApply() override
Definition: NFTokenCancelOffer.cpp:99
ripple::preflight2
NotTEC preflight2(PreflightContext const &ctx)
Checks whether the signature appears valid.
Definition: Transactor.cpp:130
ripple::Rules::enabled
bool enabled(uint256 const &feature) const
Returns true if a feature is enabled.
Definition: Rules.cpp:94
ripple::sfNFTokenOffers
const SF_VECTOR256 sfNFTokenOffers
ripple::Transactor::j_
const beast::Journal j_
Definition: Transactor.h:89
ripple::isTesSuccess
bool isTesSuccess(TER x)
Definition: TER.h:597
ripple::STObject::getFieldV256
const STVector256 & getFieldV256(SField const &field) const
Definition: STObject.cpp:617
std::find_if
T find_if(T... args)
ripple::STVector256::end
std::vector< uint256 >::iterator end()
Definition: STVector256.h:234
ripple::keylet::nftoffer
Keylet nftoffer(AccountID const &owner, std::uint32_t seq)
An offer from an account to buy or sell an NFT.
Definition: Indexes.cpp:355
ripple::STObject::empty
bool empty() const
Definition: STObject.h:871
ripple::NFTokenCancelOffer::preflight
static NotTEC preflight(PreflightContext const &ctx)
Definition: NFTokenCancelOffer.cpp:31
std::sort
T sort(T... args)
ripple::preflight1
NotTEC preflight1(PreflightContext const &ctx)
Performs early sanity checks on the account and fee fields.
Definition: Transactor.cpp:78
ripple::STVector256::begin
std::vector< uint256 >::iterator begin()
Definition: STVector256.h:222
ripple::base_uint< 256 >
ripple::temINVALID_FLAG
@ temINVALID_FLAG
Definition: TER.h:109
ripple::tefBAD_LEDGER
@ tefBAD_LEDGER
Definition: TER.h:152
ripple::NFTokenCancelOffer::preclaim
static TER preclaim(PreclaimContext const &ctx)
Definition: NFTokenCancelOffer.cpp:57
ripple::TERSubset< CanCvtToTER >
ripple::STObject::getFlags
std::uint32_t getFlags() const
Definition: STObject.cpp:481
ripple::maxTokenOfferCancelCount
constexpr std::size_t maxTokenOfferCancelCount
The maximum number of token offers that can be canceled at once.
Definition: Protocol.h:67
ripple::PreclaimContext::tx
STTx const & tx
Definition: Transactor.h:58
ripple::PreclaimContext
State information when determining if a tx is likely to claim a fee.
Definition: Transactor.h:52
ripple::tfNFTokenCancelOfferMask
constexpr const std::uint32_t tfNFTokenCancelOfferMask
Definition: TxFlags.h:157
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::featureNonFungibleTokensV1
const uint256 featureNonFungibleTokensV1
ripple::Transactor::view
ApplyView & view()
Definition: Transactor.h:107
ripple::temDISABLED
@ temDISABLED
Definition: TER.h:112
ripple::ReadView::seq
LedgerIndex seq() const
Returns the sequence number of the base ledger.
Definition: ReadView.h:193
ripple::tecNO_PERMISSION
@ tecNO_PERMISSION
Definition: TER.h:272
std::adjacent_find
T adjacent_find(T... args)
ripple::STVector256
Definition: STVector256.h:29
ripple::Transactor::ctx_
ApplyContext & ctx_
Definition: Transactor.h:88
ripple::sfAccount
const SF_ACCOUNT sfAccount
ripple::temMALFORMED
@ temMALFORMED
Definition: TER.h:85
ripple::PreflightContext::tx
STTx const & tx
Definition: Transactor.h:35
ripple::PreflightContext
State information when preflighting a tx.
Definition: Transactor.h:31
ripple::PreflightContext::rules
const Rules rules
Definition: Transactor.h:36
ripple::tesSUCCESS
@ tesSUCCESS
Definition: TER.h:222
ripple::ApplyContext::tx
STTx const & tx
Definition: ApplyContext.h:48
ripple::nft::deleteTokenOffer
bool deleteTokenOffer(ApplyView &view, std::shared_ptr< SLE > const &offer)
Deletes the given token offer.
Definition: NFTokenUtils.cpp:605
ripple::NotTEC
TERSubset< CanCvtToNotTEC > NotTEC
Definition: TER.h:528