rippled
Loading...
Searching...
No Matches
Indexes.cpp
1#include <xrpl/basics/Slice.h>
2#include <xrpl/basics/base_uint.h>
3#include <xrpl/basics/safe_cast.h>
4#include <xrpl/beast/utility/instrumentation.h>
5#include <xrpl/protocol/AccountID.h>
6#include <xrpl/protocol/Asset.h>
7#include <xrpl/protocol/Book.h>
8#include <xrpl/protocol/Indexes.h>
9#include <xrpl/protocol/LedgerFormats.h>
10#include <xrpl/protocol/Protocol.h>
11#include <xrpl/protocol/SField.h>
12#include <xrpl/protocol/STXChainBridge.h>
13#include <xrpl/protocol/SeqProxy.h>
14#include <xrpl/protocol/UintTypes.h>
15#include <xrpl/protocol/digest.h>
16#include <xrpl/protocol/nftPageMask.h>
17
18#include <boost/endian/conversion.hpp>
19
20#include <algorithm>
21#include <array>
22#include <cstdint>
23#include <cstring>
24#include <set>
25#include <utility>
26#include <vector>
27
28namespace xrpl {
29
48 ACCOUNT = 'a',
49 DIR_NODE = 'd',
50 TRUST_LINE = 'r',
51 OFFER = 'o',
52 OWNER_DIR = 'O',
53 BOOK_DIR = 'B',
54 SKIP_LIST = 's',
55 ESCROW = 'u',
56 AMENDMENTS = 'f',
57 FEE_SETTINGS = 'e',
58 TICKET = 'T',
59 SIGNER_LIST = 'S',
61 CHECK = 'C',
62 DEPOSIT_PREAUTH = 'p',
64 NEGATIVE_UNL = 'N',
65 NFTOKEN_OFFER = 'q',
68 AMM = 'A',
69 BRIDGE = 'H',
70 XCHAIN_CLAIM_ID = 'Q',
72 DID = 'I',
73 ORACLE = 'R',
74 MPTOKEN_ISSUANCE = '~',
75 MPTOKEN = 't',
76 CREDENTIAL = 'D',
78 DELEGATE = 'E',
79 VAULT = 'V',
80 LOAN_BROKER = 'l', // lower-case L
81 LOAN = 'L',
82
83 // No longer used or supported. Left here to reserve the space
84 // to avoid accidental reuse.
85 CONTRACT [[deprecated]] = 'c',
86 GENERATOR [[deprecated]] = 'g',
87 NICKNAME [[deprecated]] = 'n',
88};
89
90template <class... Args>
91static uint256
92indexHash(LedgerNameSpace space, Args const&... args)
93{
94 return sha512Half(safe_cast<std::uint16_t>(space), args...);
95}
96
98getBookBase(Book const& book)
99{
100 XRPL_ASSERT(isConsistent(book), "xrpl::getBookBase : input is consistent");
101
102 auto const index = book.domain
103 ? indexHash(
105 book.in.currency,
106 book.out.currency,
107 book.in.account,
108 book.out.account,
109 *(book.domain))
111
112 // Return with quality 0.
113 auto k = keylet::quality({ltDIR_NODE, index}, 0);
114
115 return k.key;
116}
117
120{
121 static constexpr uint256 nextQuality("0000000000000000000000000000000000000000000000010000000000000000");
122 return uBase + nextQuality;
123}
124
126getQuality(uint256 const& uBase)
127{
128 // VFALCO [base_uint] This assumes a certain storage format
129 return boost::endian::big_to_native(((std::uint64_t*)uBase.end())[-1]);
130}
131
133getTicketIndex(AccountID const& account, std::uint32_t ticketSeq)
134{
135 return indexHash(LedgerNameSpace::TICKET, account, std::uint32_t(ticketSeq));
136}
137
139getTicketIndex(AccountID const& account, SeqProxy ticketSeq)
140{
141 XRPL_ASSERT(ticketSeq.isTicket(), "xrpl::getTicketIndex : valid input");
142 return getTicketIndex(account, ticketSeq.value());
143}
144
145MPTID
146makeMptID(std::uint32_t sequence, AccountID const& account)
147{
148 MPTID u;
149 sequence = boost::endian::native_to_big(sequence);
150 memcpy(u.data(), &sequence, sizeof(sequence));
151 memcpy(u.data() + sizeof(sequence), account.data(), sizeof(account));
152 return u;
153}
154
155//------------------------------------------------------------------------------
156
157namespace keylet {
158
159Keylet
160account(AccountID const& id) noexcept
161{
162 return Keylet{ltACCOUNT_ROOT, indexHash(LedgerNameSpace::ACCOUNT, id)};
163}
164
165Keylet
166child(uint256 const& key) noexcept
167{
168 return {ltCHILD, key};
169}
170
171Keylet const&
172skip() noexcept
173{
174 static Keylet const ret{ltLEDGER_HASHES, indexHash(LedgerNameSpace::SKIP_LIST)};
175 return ret;
176}
177
178Keylet
179skip(LedgerIndex ledger) noexcept
180{
181 return {
182 ltLEDGER_HASHES,
184}
185
186Keylet const&
187amendments() noexcept
188{
189 static Keylet const ret{ltAMENDMENTS, indexHash(LedgerNameSpace::AMENDMENTS)};
190 return ret;
191}
192
193Keylet const&
194fees() noexcept
195{
196 static Keylet const ret{ltFEE_SETTINGS, indexHash(LedgerNameSpace::FEE_SETTINGS)};
197 return ret;
198}
199
200Keylet const&
201negativeUNL() noexcept
202{
203 static Keylet const ret{ltNEGATIVE_UNL, indexHash(LedgerNameSpace::NEGATIVE_UNL)};
204 return ret;
205}
206
207Keylet
209{
210 return {ltDIR_NODE, getBookBase(b)};
211}
212
213Keylet
214line(AccountID const& id0, AccountID const& id1, Currency const& currency) noexcept
215{
216 // There is code in SetTrust that calls us with id0 == id1, to allow users
217 // to locate and delete such "weird" trustlines. If we remove that code, we
218 // could enable this assert:
219 // XRPL_ASSERT(id0 != id1, "xrpl::keylet::line : accounts must be
220 // different");
221
222 // A trust line is shared between two accounts; while we typically think
223 // of this as an "issuer" and a "holder" the relationship is actually fully
224 // bidirectional.
225 //
226 // So that we can generate a unique ID for a trust line, regardess of which
227 // side of the line we're looking at, we define a "canonical" order for the
228 // two accounts (smallest then largest) and hash them in that order:
229 auto const accounts = std::minmax(id0, id1);
230
231 return {ltRIPPLE_STATE, indexHash(LedgerNameSpace::TRUST_LINE, accounts.first, accounts.second, currency)};
232}
233
234Keylet
235offer(AccountID const& id, std::uint32_t seq) noexcept
236{
237 return {ltOFFER, indexHash(LedgerNameSpace::OFFER, id, seq)};
238}
239
240Keylet
241quality(Keylet const& k, std::uint64_t q) noexcept
242{
243 XRPL_ASSERT(k.type == ltDIR_NODE, "xrpl::keylet::quality : valid input type");
244
245 // Indexes are stored in big endian format: they print as hex as stored.
246 // Most significant bytes are first and the least significant bytes
247 // represent adjacent entries. We place the quality, in big endian format,
248 // in the 8 right most bytes; this way, incrementing goes to the next entry
249 // for indexes.
250 uint256 x = k.key;
251
252 // FIXME This is ugly and we can and should do better...
253 ((std::uint64_t*)x.end())[-1] = boost::endian::native_to_big(q);
254
255 return {ltDIR_NODE, x};
256}
257
258Keylet
260{
261 XRPL_ASSERT(k.type == ltDIR_NODE, "xrpl::keylet::next_t::operator() : valid input type");
262 return {ltDIR_NODE, getQualityNext(k.key)};
263}
264
265Keylet
267{
268 return {ltTICKET, getTicketIndex(id, ticketSeq)};
269}
270
271Keylet
272ticket_t::operator()(AccountID const& id, SeqProxy ticketSeq) const
273{
274 return {ltTICKET, getTicketIndex(id, ticketSeq)};
275}
276
277// This function is presently static, since it's never accessed from anywhere
278// else. If we ever support multiple pages of signer lists, this would be the
279// keylet used to locate them.
280static Keylet
282{
283 return {ltSIGNER_LIST, indexHash(LedgerNameSpace::SIGNER_LIST, account, page)};
284}
285
286Keylet
287signers(AccountID const& account) noexcept
288{
289 return signers(account, 0);
290}
291
292Keylet
293check(AccountID const& id, std::uint32_t seq) noexcept
294{
295 return {ltCHECK, indexHash(LedgerNameSpace::CHECK, id, seq)};
296}
297
298Keylet
299depositPreauth(AccountID const& owner, AccountID const& preauthorized) noexcept
300{
301 return {ltDEPOSIT_PREAUTH, indexHash(LedgerNameSpace::DEPOSIT_PREAUTH, owner, preauthorized)};
302}
303
304// Credentials should be sorted here, use credentials::makeSorted
305Keylet
306depositPreauth(AccountID const& owner, std::set<std::pair<AccountID, Slice>> const& authCreds) noexcept
307{
309 hashes.reserve(authCreds.size());
310 for (auto const& o : authCreds)
311 hashes.emplace_back(sha512Half(o.first, o.second));
312
313 return {ltDEPOSIT_PREAUTH, indexHash(LedgerNameSpace::DEPOSIT_PREAUTH_CREDENTIALS, owner, hashes)};
314}
315
316//------------------------------------------------------------------------------
317
318Keylet
319unchecked(uint256 const& key) noexcept
320{
321 return {ltANY, key};
322}
323
324Keylet
325ownerDir(AccountID const& id) noexcept
326{
327 return {ltDIR_NODE, indexHash(LedgerNameSpace::OWNER_DIR, id)};
328}
329
330Keylet
331page(uint256 const& key, std::uint64_t index) noexcept
332{
333 if (index == 0)
334 return {ltDIR_NODE, key};
335
336 return {ltDIR_NODE, indexHash(LedgerNameSpace::DIR_NODE, key, index)};
337}
338
339Keylet
340escrow(AccountID const& src, std::uint32_t seq) noexcept
341{
342 return {ltESCROW, indexHash(LedgerNameSpace::ESCROW, src, seq)};
343}
344
345Keylet
346payChan(AccountID const& src, AccountID const& dst, std::uint32_t seq) noexcept
347{
348 return {ltPAYCHAN, indexHash(LedgerNameSpace::XRP_PAYMENT_CHANNEL, src, dst, seq)};
349}
350
351Keylet
353{
355 std::memcpy(buf.data(), owner.data(), owner.size());
356 return {ltNFTOKEN_PAGE, uint256{buf}};
357}
358
359Keylet
361{
363 std::memcpy(id.data(), owner.data(), owner.size());
364 return {ltNFTOKEN_PAGE, id};
365}
366
367Keylet
368nftpage(Keylet const& k, uint256 const& token)
369{
370 XRPL_ASSERT(k.type == ltNFTOKEN_PAGE, "xrpl::keylet::nftpage : valid input type");
371 return {ltNFTOKEN_PAGE, (k.key & ~nft::pageMask) + (token & nft::pageMask)};
372}
373
374Keylet
376{
377 return {ltNFTOKEN_OFFER, indexHash(LedgerNameSpace::NFTOKEN_OFFER, owner, seq)};
378}
379
380Keylet
381nft_buys(uint256 const& id) noexcept
382{
383 return {ltDIR_NODE, indexHash(LedgerNameSpace::NFTOKEN_BUY_OFFERS, id)};
384}
385
386Keylet
387nft_sells(uint256 const& id) noexcept
388{
389 return {ltDIR_NODE, indexHash(LedgerNameSpace::NFTOKEN_SELL_OFFERS, id)};
390}
391
392Keylet
393amm(Asset const& issue1, Asset const& issue2) noexcept
394{
395 auto const& [minI, maxI] = std::minmax(issue1.get<Issue>(), issue2.get<Issue>());
396 return amm(indexHash(LedgerNameSpace::AMM, minI.account, minI.currency, maxI.account, maxI.currency));
397}
398
399Keylet
400amm(uint256 const& id) noexcept
401{
402 return {ltAMM, id};
403}
404
405Keylet
406delegate(AccountID const& account, AccountID const& authorizedAccount) noexcept
407{
408 return {ltDELEGATE, indexHash(LedgerNameSpace::DELEGATE, account, authorizedAccount)};
409}
410
411Keylet
413{
414 // A door account can support multiple bridges. On the locking chain
415 // there can only be one bridge per lockingChainCurrency. On the issuing
416 // chain there can only be one bridge per issuingChainCurrency.
417 auto const& issue = bridge.issue(chainType);
418 return {ltBRIDGE, indexHash(LedgerNameSpace::BRIDGE, bridge.door(chainType), issue.currency)};
419}
420
421Keylet
423{
424 return {
425 ltXCHAIN_OWNED_CLAIM_ID,
426 indexHash(
428 bridge.lockingChainDoor(),
429 bridge.lockingChainIssue(),
430 bridge.issuingChainDoor(),
431 bridge.issuingChainIssue(),
432 seq)};
433}
434
435Keylet
437{
438 return {
439 ltXCHAIN_OWNED_CREATE_ACCOUNT_CLAIM_ID,
440 indexHash(
442 bridge.lockingChainDoor(),
443 bridge.lockingChainIssue(),
444 bridge.issuingChainDoor(),
445 bridge.issuingChainIssue(),
446 seq)};
447}
448
449Keylet
450did(AccountID const& account) noexcept
451{
452 return {ltDID, indexHash(LedgerNameSpace::DID, account)};
453}
454
455Keylet
456oracle(AccountID const& account, std::uint32_t const& documentID) noexcept
457{
458 return {ltORACLE, indexHash(LedgerNameSpace::ORACLE, account, documentID)};
459}
460
461Keylet
462mptIssuance(std::uint32_t seq, AccountID const& issuer) noexcept
463{
464 return mptIssuance(makeMptID(seq, issuer));
465}
466
467Keylet
468mptIssuance(MPTID const& issuanceID) noexcept
469{
470 return {ltMPTOKEN_ISSUANCE, indexHash(LedgerNameSpace::MPTOKEN_ISSUANCE, issuanceID)};
471}
472
473Keylet
474mptoken(MPTID const& issuanceID, AccountID const& holder) noexcept
475{
476 return mptoken(mptIssuance(issuanceID).key, holder);
477}
478
479Keylet
480mptoken(uint256 const& issuanceKey, AccountID const& holder) noexcept
481{
482 return {ltMPTOKEN, indexHash(LedgerNameSpace::MPTOKEN, issuanceKey, holder)};
483}
484
485Keylet
486credential(AccountID const& subject, AccountID const& issuer, Slice const& credType) noexcept
487{
488 return {ltCREDENTIAL, indexHash(LedgerNameSpace::CREDENTIAL, subject, issuer, credType)};
489}
490
491Keylet
492vault(AccountID const& owner, std::uint32_t seq) noexcept
493{
494 return vault(indexHash(LedgerNameSpace::VAULT, owner, seq));
495}
496
497Keylet
498loanbroker(AccountID const& owner, std::uint32_t seq) noexcept
499{
501}
502
503Keylet
504loan(uint256 const& loanBrokerID, std::uint32_t loanSeq) noexcept
505{
506 return loan(indexHash(LedgerNameSpace::LOAN, loanBrokerID, loanSeq));
507}
508
509Keylet
511{
512 return {ltPERMISSIONED_DOMAIN, indexHash(LedgerNameSpace::PERMISSIONED_DOMAIN, account, seq)};
513}
514
515Keylet
516permissionedDomain(uint256 const& domainID) noexcept
517{
518 return {ltPERMISSIONED_DOMAIN, domainID};
519}
520
521} // namespace keylet
522
523} // namespace xrpl
Specifies an order book.
Definition Book.h:17
Issue in
Definition Book.h:19
std::optional< uint256 > domain
Definition Book.h:21
Issue out
Definition Book.h:20
A currency issued by an account.
Definition Issue.h:14
Currency currency
Definition Issue.h:16
AccountID account
Definition Issue.h:17
A type that represents either a sequence value or a ticket value.
Definition SeqProxy.h:37
constexpr bool isTicket() const
Definition SeqProxy.h:75
constexpr std::uint32_t value() const
Definition SeqProxy.h:63
An immutable linear range of bytes.
Definition Slice.h:27
iterator end()
Definition base_uint.h:118
pointer data()
Definition base_uint.h:102
static constexpr std::size_t size()
Definition base_uint.h:495
T emplace_back(T... args)
T memcpy(T... args)
T minmax(T... args)
Keylet const & skip() noexcept
The index of the "short" skip list.
Definition Indexes.cpp:172
Keylet quality(Keylet const &k, std::uint64_t q) noexcept
The initial directory page for a specific quality.
Definition Indexes.cpp:241
Keylet signers(AccountID const &account) noexcept
A SignerList.
Definition Indexes.cpp:287
Keylet oracle(AccountID const &account, std::uint32_t const &documentID) noexcept
Definition Indexes.cpp:456
Keylet const & negativeUNL() noexcept
The (fixed) index of the object containing the ledger negativeUNL.
Definition Indexes.cpp:201
Keylet did(AccountID const &account) noexcept
Definition Indexes.cpp:450
Keylet nftpage_max(AccountID const &owner)
A keylet for the owner's last possible NFT page.
Definition Indexes.cpp:360
Keylet nftoffer(AccountID const &owner, std::uint32_t seq)
An offer from an account to buy or sell an NFT.
Definition Indexes.cpp:375
Keylet unchecked(uint256 const &key) noexcept
Any ledger entry.
Definition Indexes.cpp:319
Keylet depositPreauth(AccountID const &owner, AccountID const &preauthorized) noexcept
A DepositPreauth.
Definition Indexes.cpp:299
Keylet nftpage(Keylet const &k, uint256 const &token)
Definition Indexes.cpp:368
Keylet loanbroker(AccountID const &owner, std::uint32_t seq) noexcept
Definition Indexes.cpp:498
Keylet escrow(AccountID const &src, std::uint32_t seq) noexcept
An escrow entry.
Definition Indexes.cpp:340
Keylet bridge(STXChainBridge const &bridge, STXChainBridge::ChainType chainType)
Definition Indexes.cpp:412
Keylet const & amendments() noexcept
The index of the amendment table.
Definition Indexes.cpp:187
Keylet ownerDir(AccountID const &id) noexcept
The root page of an account's directory.
Definition Indexes.cpp:325
Keylet nft_buys(uint256 const &id) noexcept
The directory of buy offers for the specified NFT.
Definition Indexes.cpp:381
Keylet payChan(AccountID const &src, AccountID const &dst, std::uint32_t seq) noexcept
A PaymentChannel.
Definition Indexes.cpp:346
Keylet mptIssuance(std::uint32_t seq, AccountID const &issuer) noexcept
Definition Indexes.cpp:462
Keylet check(AccountID const &id, std::uint32_t seq) noexcept
A Check.
Definition Indexes.cpp:293
Keylet amm(Asset const &issue1, Asset const &issue2) noexcept
AMM entry.
Definition Indexes.cpp:393
Keylet loan(uint256 const &loanBrokerID, std::uint32_t loanSeq) noexcept
Definition Indexes.cpp:504
Keylet offer(AccountID const &id, std::uint32_t seq) noexcept
An offer from an account.
Definition Indexes.cpp:235
Keylet child(uint256 const &key) noexcept
Any item that can be in an owner dir.
Definition Indexes.cpp:166
Keylet vault(AccountID const &owner, std::uint32_t seq) noexcept
Definition Indexes.cpp:492
Keylet line(AccountID const &id0, AccountID const &id1, Currency const &currency) noexcept
The index of a trust line for a given currency.
Definition Indexes.cpp:214
Keylet nftpage_min(AccountID const &owner)
NFT page keylets.
Definition Indexes.cpp:352
Keylet xChainCreateAccountClaimID(STXChainBridge const &bridge, std::uint64_t seq)
Definition Indexes.cpp:436
Keylet mptoken(MPTID const &issuanceID, AccountID const &holder) noexcept
Definition Indexes.cpp:474
Keylet nft_sells(uint256 const &id) noexcept
The directory of sell offers for the specified NFT.
Definition Indexes.cpp:387
Keylet delegate(AccountID const &account, AccountID const &authorizedAccount) noexcept
A keylet for Delegate object.
Definition Indexes.cpp:406
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition Indexes.cpp:160
Keylet const & fees() noexcept
The (fixed) index of the object containing the ledger fees.
Definition Indexes.cpp:194
Keylet permissionedDomain(AccountID const &account, std::uint32_t seq) noexcept
Definition Indexes.cpp:510
Keylet page(uint256 const &root, std::uint64_t index=0) noexcept
A page in a directory.
Definition Indexes.cpp:331
Keylet credential(AccountID const &subject, AccountID const &issuer, Slice const &credType) noexcept
Definition Indexes.cpp:486
Keylet xChainClaimID(STXChainBridge const &bridge, std::uint64_t seq)
Definition Indexes.cpp:422
uint256 constexpr pageMask(std::string_view("0000000000000000000000000000000000000000ffffffffffffffffffffffff"))
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6
bool isConsistent(Book const &book)
Definition Book.cpp:10
sha512_half_hasher::result_type sha512Half(Args const &... args)
Returns the SHA512-Half of a series of objects.
Definition digest.h:205
uint256 getTicketIndex(AccountID const &account, std::uint32_t uSequence)
Definition Indexes.cpp:133
std::uint64_t getQuality(uint256 const &uBase)
Definition Indexes.cpp:126
base_uint< 256 > uint256
Definition base_uint.h:527
static uint256 indexHash(LedgerNameSpace space, Args const &... args)
Definition Indexes.cpp:92
base_uint< 192 > MPTID
MPTID is a 192-bit value representing MPT Issuance ID, which is a concatenation of a 32-bit sequence ...
Definition UintTypes.h:45
uint256 getQualityNext(uint256 const &uBase)
Definition Indexes.cpp:119
LedgerNameSpace
Type-specific prefix for calculating ledger indices.
Definition Indexes.cpp:47
uint256 getBookBase(Book const &book)
Definition Indexes.cpp:98
@ ltANY
A special type, matching any ledger entry type.
@ ltCHILD
A special type, matching any ledger type except directory nodes.
MPTID makeMptID(std::uint32_t sequence, AccountID const &account)
Definition Indexes.cpp:146
T reserve(T... args)
A pair of SHAMap key and LedgerEntryType.
Definition Keylet.h:20
uint256 key
Definition Keylet.h:21
LedgerEntryType type
Definition Keylet.h:22
Keylet operator()(Book const &b) const
Definition Indexes.cpp:208
Keylet operator()(Keylet const &k) const
Definition Indexes.cpp:259
Keylet operator()(AccountID const &id, std::uint32_t ticketSeq) const
Definition Indexes.cpp:266