20 #include <ripple/app/tx/impl/details/NFTokenUtils.h>
21 #include <ripple/basics/algorithm.h>
22 #include <ripple/ledger/Directory.h>
23 #include <ripple/ledger/View.h>
24 #include <ripple/protocol/Feature.h>
25 #include <ripple/protocol/STAccount.h>
26 #include <ripple/protocol/STArray.h>
27 #include <ripple/protocol/TxFlags.h>
28 #include <ripple/protocol/nftPageMask.h>
47 view.
succ(first.key, last.key.next()).value_or(last.key)));
61 view.
succ(first.key, last.key.next()).value_or(last.key)));
80 view.
succ(first.key, last.key.next()).value_or(last.key)));
86 cp = std::make_shared<SLE>(last);
89 createCallback(view, owner);
122 return (obj.getFieldH256(sfNFTokenID) & nft::pageMask) == cmp;
128 if (splitIter == narr.
end())
131 return (obj.getFieldH256(sfNFTokenID) & nft::pageMask) ==
137 if (splitIter == narr.
end())
142 if (splitIter == narr.
begin())
163 splitIter = narr.
end();
193 auto np = std::make_shared<SLE>(
keylet::nftpage(base, tokenIDForNewPage));
214 createCallback(view, owner);
221 return (first.key <= np->key()) ? np : cp;
223 return (first.key < np->key()) ? np : cp;
236 return lowBitsCmp < 0;
267 arr.push_back(std::move(nft));
288 if (p1->key() >= p2->key())
289 Throw<std::runtime_error>(
"mergePages: pages passed in out of order!");
292 Throw<std::runtime_error>(
"mergePages: next link broken!");
295 Throw<std::runtime_error>(
"mergePages: previous link broken!");
297 auto const p1arr = p1->getFieldArray(
sfNFTokens);
298 auto const p2arr = p2->getFieldArray(
sfNFTokens);
307 STArray x(p1arr.size() + p2arr.size());
316 return compareTokens(
317 a.getFieldH256(sfNFTokenID), b.getFieldH256(sfNFTokenID));
333 Throw<std::runtime_error>(
"mergePages: p0 can't be located!");
357 return removeToken(view, owner, nftokenID, std::move(page));
373 arr.begin(), arr.end(), [&nftokenID](
STObject const& obj) {
374 return (obj[sfNFTokenID] == nftokenID);
384 auto const loadPage = [&view](
389 if (
auto const id = (*page1)[~field])
394 Throw<std::runtime_error>(
395 "page " +
to_string(page1->key()) +
" has a broken " +
396 field.getName() +
" field pointing to " +
to_string(*
id));
495 for (
auto const& t : page->getFieldArray(
sfNFTokens))
517 for (
auto const& t : page->getFieldArray(
sfNFTokens))
533 if (maxDeletableOffers == 0)
549 auto offerIndexes = page->getFieldV256(
sfIndexes);
557 for (
int i = offerIndexes.size() - 1; i >= 0; --i)
562 ++deletedOffersCount;
564 Throw<std::runtime_error>(
566 " cannot be deleted!");
569 if (maxDeletableOffers == deletedOffersCount)
572 }
while (pageIndex.value_or(0) && maxDeletableOffers != deletedOffersCount);
574 return deletedOffersCount;
586 totalOffers += iter.page_size();
596 totalOffers += iter.page_size();
610 auto const owner = (*offer)[
sfOwner];
const SF_UINT64 sfIndexNext
Keylet ownerDir(AccountID const &id) noexcept
The root page of an account's directory.
A pair of SHAMap key and LedgerEntryType.
const_iterator begin() const
bool enabled(uint256 const &feature) const
Returns true if a feature is enabled.
const SF_UINT64 sfOwnerNode
A field with a type known at compile time.
constexpr std::size_t maxDeletableTokenOfferEntries
The maximum number of offers in an offer directory for NFT to be burnable.
virtual std::shared_ptr< SLE > peek(Keylet const &k)=0
Prepare to modify the SLE associated with key.
const SF_UINT256 sfNFTokenID
std::optional< TokenAndPage > findTokenAndPage(ApplyView &view, AccountID const &owner, uint256 const &nftokenID)
std::size_t removeTokenOffersWithLimit(ApplyView &view, Keylet const &directory, std::size_t maxDeletableOffers)
Delete up to a specified number of offers from the specified token offer directory.
virtual void erase(std::shared_ptr< SLE > const &sle)=0
Remove a peeked SLE.
static bool mergePages(ApplyView &view, std::shared_ptr< SLE > const &p1, std::shared_ptr< SLE > const &p2)
TER notTooManyOffers(ReadView const &view, uint256 const &nftokenID)
Returns tesSUCCESS if NFToken has few enough offers that it can be burned.
T back_inserter(T... args)
Keylet nftoffer(AccountID const &owner, std::uint32_t seq)
An offer from an account to buy or sell an NFT.
constexpr std::size_t dirMaxTokensPerPage
The maximum number of items in an NFT page.
virtual void update(std::shared_ptr< SLE > const &sle)=0
Indicate changes to a peeked SLE.
std::optional< STObject > findToken(ReadView const &view, AccountID const &owner, uint256 const &nftokenID)
Finds the specified token in the owner's token directory.
TER removeToken(ApplyView &view, AccountID const &owner, uint256 const &nftokenID)
Remove the token from the owner's token directory.
const SF_UINT64 sfNFTokenOfferNode
bool compareTokens(uint256 const &a, uint256 const &b)
Writeable view to a ledger, for applying a transaction.
constexpr uint256 pageMask(std::string_view("0000000000000000000000000000000000000000ffffffffffffffffffffffff"))
const SF_VECTOR256 sfIndexes
bool dirRemove(Keylet const &directory, std::uint64_t page, uint256 const &key, bool keepRoot)
Remove an entry from a directory.
Integers of any length that is a multiple of 32-bits.
Keylet nftpage_min(AccountID const &owner)
NFT page keylets.
void adjustOwnerCount(ApplyView &view, std::shared_ptr< SLE > const &sle, std::int32_t amount, beast::Journal j)
Adjust the owner count up or down.
Keylet nftpage(Keylet const &k, uint256 const &token)
Keylet account(AccountID const &id) noexcept
AccountID root.
@ ltNFTOKEN_OFFER
A ledger object which identifies an offer to buy or sell an NFT.
Keylet page(uint256 const &key, std::uint64_t index) noexcept
A page in a directory.
Keylet nft_sells(uint256 const &id) noexcept
The directory of sell offers for the specified NFT.
Keylet nftpage_max(AccountID const &owner)
A keylet for the owner's last possible NFT page.
constexpr const std::uint32_t tfSellNFToken
A generic endpoint for log messages.
Keylet nft_buys(uint256 const &id) noexcept
The directory of buy offers for the specified NFT.
virtual std::optional< key_type > succ(key_type const &key, std::optional< key_type > const &last=std::nullopt) const =0
Return the key of the next state item.
const uint256 fixNFTokenDirV1
virtual std::shared_ptr< SLE const > read(Keylet const &k) const =0
Return the state item associated with a key.
@ ltNFTOKEN_PAGE
A ledger object which contains a list of NFTs.
virtual void insert(std::shared_ptr< SLE > const &sle)=0
Insert a new state SLE.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
virtual Rules const & rules() const =0
Returns the tx processing rules.
@ tecNO_SUITABLE_NFTOKEN_PAGE
const SF_UINT256 sfNextPageMin
const SF_UINT256 sfPreviousPageMin
std::string to_string(Manifest const &m)
Format the specified manifest to a string for debugging purposes.
iterator erase(iterator pos)
const_iterator & next_page()
const_iterator end() const
T make_move_iterator(T... args)
static std::shared_ptr< SLE const > locatePage(ReadView const &view, AccountID owner, uint256 const &id)
static std::shared_ptr< SLE > getPageForToken(ApplyView &view, AccountID const &owner, uint256 const &id, std::function< void(ApplyView &, AccountID const &)> const &createCallback)
TER insertToken(ApplyView &view, AccountID owner, STObject &&nft)
Insert the token in the owner's token directory.
bool deleteTokenOffer(ApplyView &view, std::shared_ptr< SLE > const &offer)
Deletes the given token offer.
uint256 getFieldH256(SField const &field) const