rippled
Loading...
Searching...
No Matches
directory.cpp
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2025 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 <test/jtx/directory.h>
21
22#include <xrpl/ledger/Sandbox.h>
23
24namespace ripple::test::jtx {
25
27namespace directory {
28
29auto
31 Env& env,
32 std::uint64_t newLastPage,
33 Keylet directory,
36{
38 env.app().openLedger().modify(
39 [&](OpenView& view, beast::Journal j) -> bool {
40 Sandbox sb(&view, tapNONE);
41
42 // Find the root page
43 auto sleRoot = sb.peek(directory);
44 if (!sleRoot)
45 {
47 return false;
48 }
49
50 // Find last page
51 auto const lastIndex = sleRoot->getFieldU64(sfIndexPrevious);
52 if (lastIndex == 0)
53 {
55 return false;
56 }
57
58 if (sb.exists(keylet::page(directory, newLastPage)))
59 {
61 return false;
62 }
63
64 if (lastIndex >= newLastPage)
65 {
67 return false;
68 }
69
70 auto slePage = sb.peek(keylet::page(directory, lastIndex));
71 if (!slePage)
72 {
74 return false;
75 }
76
77 // Copy its data and delete the page
78 auto indexes = slePage->getFieldV256(sfIndexes);
79 auto prevIndex = slePage->at(~sfIndexPrevious);
80 auto owner = slePage->at(~sfOwner);
81 sb.erase(slePage);
82
83 // Create new page to replace slePage
84 auto sleNew =
85 std::make_shared<SLE>(keylet::page(directory, newLastPage));
86 sleNew->setFieldH256(sfRootIndex, directory.key);
87 sleNew->setFieldV256(sfIndexes, indexes);
88 if (owner)
89 sleNew->setAccountID(sfOwner, *owner);
90 if (prevIndex)
91 sleNew->setFieldU64(sfIndexPrevious, *prevIndex);
92 sb.insert(sleNew);
93
94 // Adjust root previous and previous node's next
95 sleRoot->setFieldU64(sfIndexPrevious, newLastPage);
96 if (prevIndex.value_or(0) == 0)
97 sleRoot->setFieldU64(sfIndexNext, newLastPage);
98 else
99 {
100 auto slePrev = sb.peek(keylet::page(directory, *prevIndex));
101 if (!slePrev)
102 {
104 return false;
105 }
106 slePrev->setFieldU64(sfIndexNext, newLastPage);
107 sb.update(slePrev);
108 }
109 sb.update(sleRoot);
110
111 // Fixup page numbers in the objects referred by indexes
112 if (adjust)
113 for (auto const key : indexes)
114 {
115 if (!adjust(sb, key, newLastPage))
116 {
118 return false;
119 }
120 }
121
122 sb.apply(view);
123 return true;
124 });
125
126 return res;
127}
128
129bool
131{
132 auto sle = view.peek({ltANY, key});
133 if (sle && sle->isFieldPresent(sfOwnerNode))
134 {
135 sle->setFieldU64(sfOwnerNode, page);
136 view.update(sle);
137 return true;
138 }
139
140 return false;
141}
142
143} // namespace directory
144
145} // namespace ripple::test::jtx
A generic endpoint for log messages.
Definition Journal.h:60
virtual OpenLedger & openLedger()=0
Writeable view to a ledger, for applying a transaction.
Definition ApplyView.h:143
virtual void update(std::shared_ptr< SLE > const &sle)=0
Indicate changes to a peeked SLE.
virtual std::shared_ptr< SLE > peek(Keylet const &k)=0
Prepare to modify the SLE associated with key.
bool modify(modify_type const &f)
Modify the open ledger.
Writable ledger view that accumulates state and tx changes.
Definition OpenView.h:65
Discardable, editable view to a ledger.
Definition Sandbox.h:35
void apply(RawView &to)
Definition Sandbox.h:55
void erase(std::shared_ptr< SLE > const &sle) override
Remove a peeked SLE.
void update(std::shared_ptr< SLE > const &sle) override
Indicate changes to a peeked SLE.
void insert(std::shared_ptr< SLE > const &sle) override
Insert a new state SLE.
bool exists(Keylet const &k) const override
Determine if a state item exists.
std::shared_ptr< SLE > peek(Keylet const &k) override
Prepare to modify the SLE associated with key.
A transaction testing environment.
Definition Env.h:121
Application & app()
Definition Env.h:261
T is_same_v
Keylet page(uint256 const &root, std::uint64_t index=0) noexcept
A page in a directory.
Definition Indexes.cpp:380
auto bumpLastPage(Env &env, std::uint64_t newLastPage, Keylet directory, std::function< bool(ApplyView &, uint256, std::uint64_t)> adjust) -> Expected< void, Error >
Move the position of the last page in the user's directory on open ledger to newLastPage.
Definition directory.cpp:30
bool adjustOwnerNode(ApplyView &view, uint256 key, std::uint64_t page)
Implementation of adjust for the most common ledger entry, i.e.
@ ltANY
A special type, matching any ledger entry type.
@ tapNONE
Definition ApplyView.h:31
A pair of SHAMap key and LedgerEntryType.
Definition Keylet.h:39
uint256 key
Definition Keylet.h:40