rippled
NFTokenUtils.h
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 #ifndef RIPPLE_TX_IMPL_DETAILS_NFTOKENUTILS_H_INCLUDED
21 #define RIPPLE_TX_IMPL_DETAILS_NFTOKENUTILS_H_INCLUDED
22 
23 #include <ripple/basics/base_uint.h>
24 #include <ripple/basics/tagged_integer.h>
25 #include <ripple/ledger/ApplyView.h>
26 #include <ripple/protocol/AccountID.h>
27 #include <ripple/protocol/TER.h>
28 
29 namespace ripple {
30 
31 namespace nft {
32 
33 // Separate taxons from regular integers.
34 struct TaxonTag
35 {
36 };
38 
39 inline Taxon
41 {
42  return static_cast<Taxon>(i);
43 }
44 
45 inline std::uint32_t
47 {
48  return static_cast<std::uint32_t>(t);
49 }
50 
51 constexpr std::uint16_t const flagBurnable = 0x0001;
52 constexpr std::uint16_t const flagOnlyXRP = 0x0002;
53 constexpr std::uint16_t const flagCreateTrustLines = 0x0004;
54 constexpr std::uint16_t const flagTransferable = 0x0008;
55 
60  ApplyView& view,
61  Keylet const& directory,
62  std::size_t maxDeletableOffers);
63 
65 TER
66 notTooManyOffers(ReadView const& view, uint256 const& nftokenID);
67 
70 findToken(
71  ReadView const& view,
72  AccountID const& owner,
73  uint256 const& nftokenID);
74 
77 {
80 
82  : token(token_), page(std::move(page_))
83  {
84  }
85 };
88  ApplyView& view,
89  AccountID const& owner,
90  uint256 const& nftokenID);
91 
93 TER
94 insertToken(ApplyView& view, AccountID owner, STObject&& nft);
95 
97 TER
98 removeToken(ApplyView& view, AccountID const& owner, uint256 const& nftokenID);
99 
100 TER
102  ApplyView& view,
103  AccountID const& owner,
104  uint256 const& nftokenID,
105  std::shared_ptr<SLE>&& page);
106 
116 bool
117 deleteTokenOffer(ApplyView& view, std::shared_ptr<SLE> const& offer);
118 
119 inline std::uint16_t
120 getFlags(uint256 const& id)
121 {
122  std::uint16_t flags;
123  memcpy(&flags, id.begin(), 2);
124  return boost::endian::big_to_native(flags);
125 }
126 
127 inline std::uint16_t
129 {
130  std::uint16_t fee;
131  memcpy(&fee, id.begin() + 2, 2);
132  return boost::endian::big_to_native(fee);
133 }
134 
135 inline std::uint32_t
136 getSerial(uint256 const& id)
137 {
138  std::uint32_t seq;
139  memcpy(&seq, id.begin() + 28, 4);
140  return boost::endian::big_to_native(seq);
141 }
142 
143 inline Taxon
145 {
146  // An issuer may issue several NFTs with the same taxon; to ensure that NFTs
147  // are spread across multiple pages we lightly mix the taxon up by using the
148  // sequence (which is not under the issuer's direct control) as the seed for
149  // a simple linear congruential generator.
150  //
151  // From the Hull-Dobell theorem we know that f(x)=(m*x+c) mod n will yield a
152  // permutation of [0, n) when n is a power of 2 if m is congruent to 1 mod 4
153  // and c is odd.
154  //
155  // Here we use m = 384160001 and c = 2459. The modulo is implicit because we
156  // use 2^32 for n and the arithmetic gives it to us for "free".
157  //
158  // Note that the scramble value we calculate is not cryptographically secure
159  // but that's fine since all we're looking for is some dispersion.
160  //
161  // **IMPORTANT** Changing these numbers would be a breaking change requiring
162  // an amendment along with a way to distinguish token IDs that
163  // were generated with the old code.
164  return taxon ^ toTaxon(((384160001 * tokenSeq) + 2459));
165 }
166 
167 inline Taxon
168 getTaxon(uint256 const& id)
169 {
170  std::uint32_t taxon;
171  memcpy(&taxon, id.begin() + 24, 4);
172  taxon = boost::endian::big_to_native(taxon);
173 
174  // The taxon cipher is just an XOR, so it is reversible by applying the
175  // XOR a second time.
176  return cipheredTaxon(getSerial(id), toTaxon(taxon));
177 }
178 
179 inline AccountID
180 getIssuer(uint256 const& id)
181 {
182  return AccountID::fromVoid(id.data() + 4);
183 }
184 
185 bool
186 compareTokens(uint256 const& a, uint256 const& b);
187 
188 } // namespace nft
189 
190 } // namespace ripple
191 
192 #endif // RIPPLE_TX_IMPL_DETAILS_NFTOKENUTILS_H_INCLUDED
ripple::Keylet
A pair of SHAMap key and LedgerEntryType.
Definition: Keylet.h:38
ripple::nft::getFlags
std::uint16_t getFlags(uint256 const &id)
Definition: NFTokenUtils.h:120
std::shared_ptr
STL class.
ripple::nft::TokenAndPage::page
std::shared_ptr< SLE > page
Definition: NFTokenUtils.h:79
ripple::nft::findTokenAndPage
std::optional< TokenAndPage > findTokenAndPage(ApplyView &view, AccountID const &owner, uint256 const &nftokenID)
Definition: NFTokenUtils.cpp:505
ripple::nft::TokenAndPage
Finds the token in the owner's token directory.
Definition: NFTokenUtils.h:76
ripple::nft::removeTokenOffersWithLimit
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.
Definition: NFTokenUtils.cpp:528
ripple::nft::flagTransferable
constexpr const std::uint16_t flagTransferable
Definition: NFTokenUtils.h:54
ripple::nft::notTooManyOffers
TER notTooManyOffers(ReadView const &view, uint256 const &nftokenID)
Returns tesSUCCESS if NFToken has few enough offers that it can be burned.
Definition: NFTokenUtils.cpp:578
ripple::nft::TokenAndPage::token
STObject token
Definition: NFTokenUtils.h:78
ripple::nft::flagOnlyXRP
constexpr const std::uint16_t flagOnlyXRP
Definition: NFTokenUtils.h:52
ripple::nft::findToken
std::optional< STObject > findToken(ReadView const &view, AccountID const &owner, uint256 const &nftokenID)
Finds the specified token in the owner's token directory.
Definition: NFTokenUtils.cpp:483
ripple::nft::toTaxon
Taxon toTaxon(std::uint32_t i)
Definition: NFTokenUtils.h:40
ripple::nft::removeToken
TER removeToken(ApplyView &view, AccountID const &owner, uint256 const &nftokenID)
Remove the token from the owner's token directory.
Definition: NFTokenUtils.cpp:349
ripple::nft::compareTokens
bool compareTokens(uint256 const &a, uint256 const &b)
Definition: NFTokenUtils.cpp:227
ripple::ApplyView
Writeable view to a ledger, for applying a transaction.
Definition: ApplyView.h:134
ripple::nft::getIssuer
AccountID getIssuer(uint256 const &id)
Definition: NFTokenUtils.h:180
ripple::base_uint< 256 >
ripple::nft::TokenAndPage::TokenAndPage
TokenAndPage(STObject const &token_, std::shared_ptr< SLE > page_)
Definition: NFTokenUtils.h:81
ripple::nft::toUInt32
std::uint32_t toUInt32(Taxon t)
Definition: NFTokenUtils.h:46
ripple::TERSubset< CanCvtToTER >
ripple::nft::getSerial
std::uint32_t getSerial(uint256 const &id)
Definition: NFTokenUtils.h:136
std::uint32_t
ripple::nft::flagBurnable
constexpr const std::uint16_t flagBurnable
Definition: NFTokenUtils.h:51
ripple::STObject
Definition: STObject.h:51
ripple::ReadView
A view into a ledger.
Definition: ReadView.h:125
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::nft::Taxon
tagged_integer< std::uint32_t, TaxonTag > Taxon
Definition: NFTokenUtils.h:37
std
STL namespace.
ripple::base_uint< 160, detail::AccountIDTag >::fromVoid
static base_uint fromVoid(void const *data)
Definition: base_uint.h:312
ripple::nft::TaxonTag
Definition: NFTokenUtils.h:34
ripple::nft::flagCreateTrustLines
constexpr const std::uint16_t flagCreateTrustLines
Definition: NFTokenUtils.h:53
std::optional
std::size_t
ripple::tagged_integer
A type-safe wrap around standard integral types.
Definition: tagged_integer.h:44
ripple::nft::getTransferFee
std::uint16_t getTransferFee(uint256 const &id)
Definition: NFTokenUtils.h:128
ripple::nft::cipheredTaxon
Taxon cipheredTaxon(std::uint32_t tokenSeq, Taxon taxon)
Definition: NFTokenUtils.h:144
ripple::nft::getTaxon
Taxon getTaxon(uint256 const &id)
Definition: NFTokenUtils.h:168
ripple::nft::insertToken
TER insertToken(ApplyView &view, AccountID owner, STObject &&nft)
Insert the token in the owner's token directory.
Definition: NFTokenUtils.cpp:243
ripple::nft::deleteTokenOffer
bool deleteTokenOffer(ApplyView &view, std::shared_ptr< SLE > const &offer)
Deletes the given token offer.
Definition: NFTokenUtils.cpp:605