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
23
24auto
26 Env& env,
27 std::uint64_t newLastPage,
29 std::function<bool(ApplyView&, uint256, std::uint64_t)> adjust) -> std::expected<void, Error>
30{
31 std::expected<void, Error> res{};
32 env.app().getOpenLedger().modify([&](OpenView& view, beast::Journal j) -> bool {
33 Sandbox sb(&view, TapNone);
34
35 // Find the root page
36 auto sleRoot = sb.peek(directory);
37 if (!sleRoot)
38 {
40 return false;
41 }
42
43 // Find last page
44 auto const lastIndex = sleRoot->getFieldU64(sfIndexPrevious);
45 if (lastIndex == 0)
46 {
48 return false;
49 }
50
51 if (sb.exists(keylet::page(directory, newLastPage)))
52 {
54 return false;
55 }
56
57 if (lastIndex >= newLastPage)
58 {
60 return false;
61 }
62
63 auto slePage = sb.peek(keylet::page(directory, lastIndex));
64 if (!slePage)
65 {
67 return false;
68 }
69
70 // Copy its data and delete the page
71 auto indexes = slePage->getFieldV256(sfIndexes);
72 auto prevIndex = slePage->at(~sfIndexPrevious);
73 auto owner = slePage->at(~sfOwner);
74 sb.erase(slePage);
75
76 // Create new page to replace slePage
77 auto sleNew = std::make_shared<SLE>(keylet::page(directory, newLastPage));
78 sleNew->setFieldH256(sfRootIndex, directory.key);
79 sleNew->setFieldV256(sfIndexes, indexes);
80 if (owner)
81 sleNew->setAccountID(sfOwner, *owner);
82 if (prevIndex)
83 sleNew->setFieldU64(sfIndexPrevious, *prevIndex);
84 sb.insert(sleNew);
85
86 // Adjust root previous and previous node's next
87 sleRoot->setFieldU64(sfIndexPrevious, newLastPage);
88 if (prevIndex.valueOr(0) == 0)
89 {
90 sleRoot->setFieldU64(sfIndexNext, newLastPage);
91 }
92 else
93 {
94 auto slePrev = sb.peek(keylet::page(directory, *prevIndex));
95 if (!slePrev)
96 {
98 return false;
99 }
100 slePrev->setFieldU64(sfIndexNext, newLastPage);
101 sb.update(slePrev);
102 }
103 sb.update(sleRoot);
104
105 // Fixup page numbers in the objects referred by indexes
106 if (adjust)
107 {
108 for (auto const key : indexes)
109 {
110 if (!adjust(sb, key, newLastPage))
111 {
113 return false;
114 }
115 }
116 }
117
118 sb.apply(view);
119 return true;
120 });
121
122 return res;
123}
124
125bool
127{
128 auto sle = view.peek({ltANY, key});
129 if (sle && sle->isFieldPresent(sfOwnerNode))
130 {
131 sle->setFieldU64(sfOwnerNode, page);
132 view.update(sle);
133 return true;
134 }
135
136 return false;
137}
138
139} // namespace xrpl::test::jtx::directory
A generic endpoint for log messages.
Definition Journal.h:38
Writeable view to a ledger, for applying a transaction.
Definition ApplyView.h:118
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:45
Discardable, editable view to a ledger.
Definition Sandbox.h:15
void apply(RawView &to)
Definition Sandbox.h:35
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:143
Application & app()
Definition Env.h:280
T make_shared(T... args)
Keylet page(uint256 const &root, std::uint64_t index=0) noexcept
A page in a directory.
Definition Indexes.cpp:363
Directory operations.
Definition directory.h:13
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:25
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:13
@ ltANY
A special type, matching any ledger entry type.
BaseUInt< 256 > uint256
Definition base_uint.h:562
A pair of SHAMap key and LedgerEntryType.
Definition Keylet.h:19
T unexpected(T... args)