xrpld
Loading...
Searching...
No Matches
directory.cpp
1#include <test/jtx/directory.h>
2
3#include <test/jtx/Env.h>
4
5#include <xrpl/basics/base_uint.h>
6#include <xrpl/beast/utility/Journal.h>
7#include <xrpl/core/ServiceRegistry.h>
8#include <xrpl/ledger/ApplyView.h>
9#include <xrpl/ledger/OpenView.h>
10#include <xrpl/ledger/Sandbox.h>
11#include <xrpl/protocol/Indexes.h>
12#include <xrpl/protocol/Keylet.h>
13#include <xrpl/protocol/LedgerFormats.h>
14#include <xrpl/protocol/SField.h>
15
16#include <cstdint>
17#include <expected>
18#include <functional>
19#include <memory>
20
25
26auto
28 Env& env,
29 std::uint64_t newLastPage,
31 std::function<bool(ApplyView&, uint256, std::uint64_t)> adjust) -> std::expected<void, Error>
32{
33 std::expected<void, Error> res{};
34 env.app().getOpenLedger().modify([&](OpenView& view, beast::Journal j) -> bool {
35 Sandbox sb(&view, TapNone);
36
37 // Find the root page
38 auto sleRoot = sb.peek(directory);
39 if (!sleRoot)
40 {
42 return false;
43 }
44
45 // Find last page
46 auto const lastIndex = sleRoot->getFieldU64(sfIndexPrevious);
47 if (lastIndex == 0)
48 {
50 return false;
51 }
52
53 if (sb.exists(keylet::page(directory, newLastPage)))
54 {
56 return false;
57 }
58
59 if (lastIndex >= newLastPage)
60 {
62 return false;
63 }
64
65 auto slePage = sb.peek(keylet::page(directory, lastIndex));
66 if (!slePage)
67 {
69 return false;
70 }
71
72 // Copy its data and delete the page
73 auto indexes = slePage->getFieldV256(sfIndexes);
74 auto prevIndex = slePage->at(~sfIndexPrevious);
75 auto owner = slePage->at(~sfOwner);
76 sb.erase(slePage);
77
78 // Create new page to replace slePage
79 auto sleNew = std::make_shared<SLE>(keylet::page(directory, newLastPage));
80 sleNew->setFieldH256(sfRootIndex, directory.key);
81 sleNew->setFieldV256(sfIndexes, indexes);
82 if (owner)
83 sleNew->setAccountID(sfOwner, *owner);
84 if (prevIndex)
85 sleNew->setFieldU64(sfIndexPrevious, *prevIndex);
86 sb.insert(sleNew);
87
88 // Adjust root previous and previous node's next
89 sleRoot->setFieldU64(sfIndexPrevious, newLastPage);
90 if (prevIndex.valueOr(0) == 0)
91 {
92 sleRoot->setFieldU64(sfIndexNext, newLastPage);
93 }
94 else
95 {
96 auto slePrev = sb.peek(keylet::page(directory, *prevIndex));
97 if (!slePrev)
98 {
100 return false;
101 }
102 slePrev->setFieldU64(sfIndexNext, newLastPage);
103 sb.update(slePrev);
104 }
105 sb.update(sleRoot);
106
107 // Fixup page numbers in the objects referred by indexes
108 if (adjust)
109 {
110 for (auto const key : indexes)
111 {
112 if (!adjust(sb, key, newLastPage))
113 {
115 return false;
116 }
117 }
118 }
119
120 sb.apply(view);
121 return true;
122 });
123
124 return res;
125}
126
127bool
129{
130 auto sle = view.peek({ltANY, key});
131 if (sle && sle->isFieldPresent(sfOwnerNode))
132 {
133 sle->setFieldU64(sfOwnerNode, page);
134 view.update(sle);
135 return true;
136 }
137
138 return false;
139}
140
141} // namespace xrpl::test::jtx::directory
A generic endpoint for log messages.
Definition Journal.h:44
Writeable view to a ledger, for applying a transaction.
Definition ApplyView.h:134
virtual SLE::pointer peek(Keylet const &k)=0
Prepare to modify the SLE associated with key.
virtual void update(SLE::ref sle)=0
Indicate changes to a peeked SLE.
bool modify(modify_type const &f)
Modify the open ledger.
Writable ledger view that accumulates state and tx changes.
Definition OpenView.h:59
Discardable, editable view to a ledger.
Definition Sandbox.h:18
void apply(RawView &to)
Definition Sandbox.h:38
virtual OpenLedger & getOpenLedger()=0
void insert(SLE::ref sle) override
Insert a new state SLE.
SLE::pointer peek(Keylet const &k) override
Prepare to modify the SLE associated with key.
void update(SLE::ref sle) override
Indicate changes to a peeked SLE.
void erase(SLE::ref sle) override
Remove a peeked SLE.
bool exists(Keylet const &k) const override
Determine if a state item exists.
A transaction testing environment.
Definition Env.h:161
Application & app()
Definition Env.h:300
T make_shared(T... args)
Keylet page(uint256 const &root, std::uint64_t const index=0) noexcept
A page in a directory.
Definition Indexes.cpp:379
Directory operations.
Definition directory.h:19
auto bumpLastPage(Env &env, std::uint64_t newLastPage, Keylet directory, std::function< bool(ApplyView &, uint256, std::uint64_t)> adjust) -> std::expected< void, Error >
Move the position of the last page in the user's directory on open ledger to newLastPage.
Definition directory.cpp:27
bool adjustOwnerNode(ApplyView &view, uint256 key, std::uint64_t page)
Implementation of adjust for the most common ledger entry, i.e.
@ TapNone
Definition ApplyView.h:28
@ ltANY
A special type, matching any ledger entry type.
BaseUInt< 256 > uint256
Definition base_uint.h:580
A pair of SHAMap key and LedgerEntryType.
Definition Keylet.h:20
T unexpected(T... args)