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 ? indexHash(
104 book.in.currency,
105 book.out.currency,
106 book.in.account,
107 book.out.account,
108 *(book.domain))
109 : indexHash(
111 book.in.currency,
112 book.out.currency,
113 book.in.account,
114 book.out.account);
115
116 // Return with quality 0.
117 auto k = keylet::quality({ltDIR_NODE, index}, 0);
118
119 return k.key;
120}
121
124{
125 static constexpr uint256 nextQuality(
126 "0000000000000000000000000000000000000000000000010000000000000000");
127 return uBase + nextQuality;
128}
129
131getQuality(uint256 const& uBase)
132{
133 // VFALCO [base_uint] This assumes a certain storage format
134 return boost::endian::big_to_native(((std::uint64_t*)uBase.end())[-1]);
135}
136
138getTicketIndex(AccountID const& account, std::uint32_t ticketSeq)
139{
140 return indexHash(
141 LedgerNameSpace::TICKET, account, std::uint32_t(ticketSeq));
142}
143
145getTicketIndex(AccountID const& account, SeqProxy ticketSeq)
146{
147 XRPL_ASSERT(ticketSeq.isTicket(), "xrpl::getTicketIndex : valid input");
148 return getTicketIndex(account, ticketSeq.value());
149}
150
151MPTID
152makeMptID(std::uint32_t sequence, AccountID const& account)
153{
154 MPTID u;
155 sequence = boost::endian::native_to_big(sequence);
156 memcpy(u.data(), &sequence, sizeof(sequence));
157 memcpy(u.data() + sizeof(sequence), account.data(), sizeof(account));
158 return u;
159}
160
161//------------------------------------------------------------------------------
162
163namespace keylet {
164
165Keylet
166account(AccountID const& id) noexcept
167{
168 return Keylet{ltACCOUNT_ROOT, indexHash(LedgerNameSpace::ACCOUNT, id)};
169}
170
171Keylet
172child(uint256 const& key) noexcept
173{
174 return {ltCHILD, key};
175}
176
177Keylet const&
178skip() noexcept
179{
180 static Keylet const ret{
181 ltLEDGER_HASHES, indexHash(LedgerNameSpace::SKIP_LIST)};
182 return ret;
183}
184
185Keylet
186skip(LedgerIndex ledger) noexcept
187{
188 return {
189 ltLEDGER_HASHES,
190 indexHash(
192 std::uint32_t(static_cast<std::uint32_t>(ledger) >> 16))};
193}
194
195Keylet const&
196amendments() noexcept
197{
198 static Keylet const ret{
200 return ret;
201}
202
203Keylet const&
204fees() noexcept
205{
206 static Keylet const ret{
208 return ret;
209}
210
211Keylet const&
212negativeUNL() noexcept
213{
214 static Keylet const ret{
216 return ret;
217}
218
219Keylet
221{
222 return {ltDIR_NODE, getBookBase(b)};
223}
224
225Keylet
227 AccountID const& id0,
228 AccountID const& id1,
229 Currency const& currency) noexcept
230{
231 // There is code in SetTrust that calls us with id0 == id1, to allow users
232 // to locate and delete such "weird" trustlines. If we remove that code, we
233 // could enable this assert:
234 // XRPL_ASSERT(id0 != id1, "xrpl::keylet::line : accounts must be
235 // different");
236
237 // A trust line is shared between two accounts; while we typically think
238 // of this as an "issuer" and a "holder" the relationship is actually fully
239 // bidirectional.
240 //
241 // So that we can generate a unique ID for a trust line, regardess of which
242 // side of the line we're looking at, we define a "canonical" order for the
243 // two accounts (smallest then largest) and hash them in that order:
244 auto const accounts = std::minmax(id0, id1);
245
246 return {
247 ltRIPPLE_STATE,
248 indexHash(
250 accounts.first,
251 accounts.second,
252 currency)};
253}
254
255Keylet
256offer(AccountID const& id, std::uint32_t seq) noexcept
257{
258 return {ltOFFER, indexHash(LedgerNameSpace::OFFER, id, seq)};
259}
260
261Keylet
262quality(Keylet const& k, std::uint64_t q) noexcept
263{
264 XRPL_ASSERT(
265 k.type == ltDIR_NODE, "xrpl::keylet::quality : valid input type");
266
267 // Indexes are stored in big endian format: they print as hex as stored.
268 // Most significant bytes are first and the least significant bytes
269 // represent adjacent entries. We place the quality, in big endian format,
270 // in the 8 right most bytes; this way, incrementing goes to the next entry
271 // for indexes.
272 uint256 x = k.key;
273
274 // FIXME This is ugly and we can and should do better...
275 ((std::uint64_t*)x.end())[-1] = boost::endian::native_to_big(q);
276
277 return {ltDIR_NODE, x};
278}
279
280Keylet
282{
283 XRPL_ASSERT(
284 k.type == ltDIR_NODE,
285 "xrpl::keylet::next_t::operator() : valid input type");
286 return {ltDIR_NODE, getQualityNext(k.key)};
287}
288
289Keylet
291{
292 return {ltTICKET, getTicketIndex(id, ticketSeq)};
293}
294
295Keylet
296ticket_t::operator()(AccountID const& id, SeqProxy ticketSeq) const
297{
298 return {ltTICKET, getTicketIndex(id, ticketSeq)};
299}
300
301// This function is presently static, since it's never accessed from anywhere
302// else. If we ever support multiple pages of signer lists, this would be the
303// keylet used to locate them.
304static Keylet
306{
307 return {
309}
310
311Keylet
312signers(AccountID const& account) noexcept
313{
314 return signers(account, 0);
315}
316
317Keylet
318check(AccountID const& id, std::uint32_t seq) noexcept
319{
320 return {ltCHECK, indexHash(LedgerNameSpace::CHECK, id, seq)};
321}
322
323Keylet
324depositPreauth(AccountID const& owner, AccountID const& preauthorized) noexcept
325{
326 return {
327 ltDEPOSIT_PREAUTH,
328 indexHash(LedgerNameSpace::DEPOSIT_PREAUTH, owner, preauthorized)};
329}
330
331// Credentials should be sorted here, use credentials::makeSorted
332Keylet
334 AccountID const& owner,
335 std::set<std::pair<AccountID, Slice>> const& authCreds) noexcept
336{
338 hashes.reserve(authCreds.size());
339 for (auto const& o : authCreds)
340 hashes.emplace_back(sha512Half(o.first, o.second));
341
342 return {
343 ltDEPOSIT_PREAUTH,
345}
346
347//------------------------------------------------------------------------------
348
349Keylet
350unchecked(uint256 const& key) noexcept
351{
352 return {ltANY, key};
353}
354
355Keylet
356ownerDir(AccountID const& id) noexcept
357{
358 return {ltDIR_NODE, indexHash(LedgerNameSpace::OWNER_DIR, id)};
359}
360
361Keylet
362page(uint256 const& key, std::uint64_t index) noexcept
363{
364 if (index == 0)
365 return {ltDIR_NODE, key};
366
367 return {ltDIR_NODE, indexHash(LedgerNameSpace::DIR_NODE, key, index)};
368}
369
370Keylet
371escrow(AccountID const& src, std::uint32_t seq) noexcept
372{
373 return {ltESCROW, indexHash(LedgerNameSpace::ESCROW, src, seq)};
374}
375
376Keylet
377payChan(AccountID const& src, AccountID const& dst, std::uint32_t seq) noexcept
378{
379 return {
380 ltPAYCHAN,
382}
383
384Keylet
386{
388 std::memcpy(buf.data(), owner.data(), owner.size());
389 return {ltNFTOKEN_PAGE, uint256{buf}};
390}
391
392Keylet
394{
396 std::memcpy(id.data(), owner.data(), owner.size());
397 return {ltNFTOKEN_PAGE, id};
398}
399
400Keylet
401nftpage(Keylet const& k, uint256 const& token)
402{
403 XRPL_ASSERT(
404 k.type == ltNFTOKEN_PAGE, "xrpl::keylet::nftpage : valid input type");
405 return {ltNFTOKEN_PAGE, (k.key & ~nft::pageMask) + (token & nft::pageMask)};
406}
407
408Keylet
410{
411 return {
412 ltNFTOKEN_OFFER, indexHash(LedgerNameSpace::NFTOKEN_OFFER, owner, seq)};
413}
414
415Keylet
416nft_buys(uint256 const& id) noexcept
417{
418 return {ltDIR_NODE, indexHash(LedgerNameSpace::NFTOKEN_BUY_OFFERS, id)};
419}
420
421Keylet
422nft_sells(uint256 const& id) noexcept
423{
424 return {ltDIR_NODE, indexHash(LedgerNameSpace::NFTOKEN_SELL_OFFERS, id)};
425}
426
427Keylet
428amm(Asset const& issue1, Asset const& issue2) noexcept
429{
430 auto const& [minI, maxI] =
431 std::minmax(issue1.get<Issue>(), issue2.get<Issue>());
432 return amm(indexHash(
434 minI.account,
435 minI.currency,
436 maxI.account,
437 maxI.currency));
438}
439
440Keylet
441amm(uint256 const& id) noexcept
442{
443 return {ltAMM, id};
444}
445
446Keylet
447delegate(AccountID const& account, AccountID const& authorizedAccount) noexcept
448{
449 return {
450 ltDELEGATE,
451 indexHash(LedgerNameSpace::DELEGATE, account, authorizedAccount)};
452}
453
454Keylet
456{
457 // A door account can support multiple bridges. On the locking chain
458 // there can only be one bridge per lockingChainCurrency. On the issuing
459 // chain there can only be one bridge per issuingChainCurrency.
460 auto const& issue = bridge.issue(chainType);
461 return {
462 ltBRIDGE,
463 indexHash(
464 LedgerNameSpace::BRIDGE, bridge.door(chainType), issue.currency)};
465}
466
467Keylet
469{
470 return {
471 ltXCHAIN_OWNED_CLAIM_ID,
472 indexHash(
474 bridge.lockingChainDoor(),
475 bridge.lockingChainIssue(),
476 bridge.issuingChainDoor(),
477 bridge.issuingChainIssue(),
478 seq)};
479}
480
481Keylet
483{
484 return {
485 ltXCHAIN_OWNED_CREATE_ACCOUNT_CLAIM_ID,
486 indexHash(
488 bridge.lockingChainDoor(),
489 bridge.lockingChainIssue(),
490 bridge.issuingChainDoor(),
491 bridge.issuingChainIssue(),
492 seq)};
493}
494
495Keylet
496did(AccountID const& account) noexcept
497{
498 return {ltDID, indexHash(LedgerNameSpace::DID, account)};
499}
500
501Keylet
502oracle(AccountID const& account, std::uint32_t const& documentID) noexcept
503{
504 return {ltORACLE, indexHash(LedgerNameSpace::ORACLE, account, documentID)};
505}
506
507Keylet
508mptIssuance(std::uint32_t seq, AccountID const& issuer) noexcept
509{
510 return mptIssuance(makeMptID(seq, issuer));
511}
512
513Keylet
514mptIssuance(MPTID const& issuanceID) noexcept
515{
516 return {
517 ltMPTOKEN_ISSUANCE,
519}
520
521Keylet
522mptoken(MPTID const& issuanceID, AccountID const& holder) noexcept
523{
524 return mptoken(mptIssuance(issuanceID).key, holder);
525}
526
527Keylet
528mptoken(uint256 const& issuanceKey, AccountID const& holder) noexcept
529{
530 return {
531 ltMPTOKEN, indexHash(LedgerNameSpace::MPTOKEN, issuanceKey, holder)};
532}
533
534Keylet
536 AccountID const& subject,
537 AccountID const& issuer,
538 Slice const& credType) noexcept
539{
540 return {
541 ltCREDENTIAL,
542 indexHash(LedgerNameSpace::CREDENTIAL, subject, issuer, credType)};
543}
544
545Keylet
546vault(AccountID const& owner, std::uint32_t seq) noexcept
547{
548 return vault(indexHash(LedgerNameSpace::VAULT, owner, seq));
549}
550
551Keylet
552loanbroker(AccountID const& owner, std::uint32_t seq) noexcept
553{
555}
556
557Keylet
558loan(uint256 const& loanBrokerID, std::uint32_t loanSeq) noexcept
559{
560 return loan(indexHash(LedgerNameSpace::LOAN, loanBrokerID, loanSeq));
561}
562
563Keylet
565{
566 return {
567 ltPERMISSIONED_DOMAIN,
569}
570
571Keylet
572permissionedDomain(uint256 const& domainID) noexcept
573{
574 return {ltPERMISSIONED_DOMAIN, domainID};
575}
576
577} // namespace keylet
578
579} // 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:122
pointer data()
Definition base_uint.h:106
static constexpr std::size_t size()
Definition base_uint.h:507
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:178
Keylet quality(Keylet const &k, std::uint64_t q) noexcept
The initial directory page for a specific quality.
Definition Indexes.cpp:262
Keylet signers(AccountID const &account) noexcept
A SignerList.
Definition Indexes.cpp:312
Keylet oracle(AccountID const &account, std::uint32_t const &documentID) noexcept
Definition Indexes.cpp:502
Keylet const & negativeUNL() noexcept
The (fixed) index of the object containing the ledger negativeUNL.
Definition Indexes.cpp:212
Keylet did(AccountID const &account) noexcept
Definition Indexes.cpp:496
Keylet nftpage_max(AccountID const &owner)
A keylet for the owner's last possible NFT page.
Definition Indexes.cpp:393
Keylet nftoffer(AccountID const &owner, std::uint32_t seq)
An offer from an account to buy or sell an NFT.
Definition Indexes.cpp:409
Keylet unchecked(uint256 const &key) noexcept
Any ledger entry.
Definition Indexes.cpp:350
Keylet depositPreauth(AccountID const &owner, AccountID const &preauthorized) noexcept
A DepositPreauth.
Definition Indexes.cpp:324
Keylet nftpage(Keylet const &k, uint256 const &token)
Definition Indexes.cpp:401
Keylet loanbroker(AccountID const &owner, std::uint32_t seq) noexcept
Definition Indexes.cpp:552
Keylet escrow(AccountID const &src, std::uint32_t seq) noexcept
An escrow entry.
Definition Indexes.cpp:371
Keylet bridge(STXChainBridge const &bridge, STXChainBridge::ChainType chainType)
Definition Indexes.cpp:455
Keylet const & amendments() noexcept
The index of the amendment table.
Definition Indexes.cpp:196
Keylet ownerDir(AccountID const &id) noexcept
The root page of an account's directory.
Definition Indexes.cpp:356
Keylet nft_buys(uint256 const &id) noexcept
The directory of buy offers for the specified NFT.
Definition Indexes.cpp:416
Keylet payChan(AccountID const &src, AccountID const &dst, std::uint32_t seq) noexcept
A PaymentChannel.
Definition Indexes.cpp:377
Keylet mptIssuance(std::uint32_t seq, AccountID const &issuer) noexcept
Definition Indexes.cpp:508
Keylet check(AccountID const &id, std::uint32_t seq) noexcept
A Check.
Definition Indexes.cpp:318
Keylet amm(Asset const &issue1, Asset const &issue2) noexcept
AMM entry.
Definition Indexes.cpp:428
Keylet loan(uint256 const &loanBrokerID, std::uint32_t loanSeq) noexcept
Definition Indexes.cpp:558
Keylet offer(AccountID const &id, std::uint32_t seq) noexcept
An offer from an account.
Definition Indexes.cpp:256
Keylet child(uint256 const &key) noexcept
Any item that can be in an owner dir.
Definition Indexes.cpp:172
Keylet vault(AccountID const &owner, std::uint32_t seq) noexcept
Definition Indexes.cpp:546
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:226
Keylet nftpage_min(AccountID const &owner)
NFT page keylets.
Definition Indexes.cpp:385
Keylet xChainCreateAccountClaimID(STXChainBridge const &bridge, std::uint64_t seq)
Definition Indexes.cpp:482
Keylet mptoken(MPTID const &issuanceID, AccountID const &holder) noexcept
Definition Indexes.cpp:522
Keylet nft_sells(uint256 const &id) noexcept
The directory of sell offers for the specified NFT.
Definition Indexes.cpp:422
Keylet delegate(AccountID const &account, AccountID const &authorizedAccount) noexcept
A keylet for Delegate object.
Definition Indexes.cpp:447
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition Indexes.cpp:166
Keylet const & fees() noexcept
The (fixed) index of the object containing the ledger fees.
Definition Indexes.cpp:204
Keylet permissionedDomain(AccountID const &account, std::uint32_t seq) noexcept
Definition Indexes.cpp:564
Keylet page(uint256 const &root, std::uint64_t index=0) noexcept
A page in a directory.
Definition Indexes.cpp:362
Keylet credential(AccountID const &subject, AccountID const &issuer, Slice const &credType) noexcept
Definition Indexes.cpp:535
Keylet xChainClaimID(STXChainBridge const &bridge, std::uint64_t seq)
Definition Indexes.cpp:468
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:138
std::uint64_t getQuality(uint256 const &uBase)
Definition Indexes.cpp:131
base_uint< 256 > uint256
Definition base_uint.h:539
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:123
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:152
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:220
Keylet operator()(Keylet const &k) const
Definition Indexes.cpp:281
Keylet operator()(AccountID const &id, std::uint32_t ticketSeq) const
Definition Indexes.cpp:290