diff --git a/AMMUtils_8cpp_source.html b/AMMUtils_8cpp_source.html index fb17529055..8115bc2133 100644 --- a/AMMUtils_8cpp_source.html +++ b/AMMUtils_8cpp_source.html @@ -604,8 +604,8 @@ $(document).ready(function() { init_codefold(0); });
beast::Journal::debug
Stream debug() const
Definition Journal.h:328
beast::Journal::trace
Stream trace() const
Severity stream access functions.
Definition Journal.h:322
ripple::ApplyView
Writeable view to a ledger, for applying a transaction.
Definition ApplyView.h:143
-
ripple::ApplyView::dirRemove
bool dirRemove(Keylet const &directory, std::uint64_t page, uint256 const &key, bool keepRoot)
Remove an entry from a directory.
Definition ApplyView.cpp:191
-
ripple::ApplyView::emptyDirDelete
bool emptyDirDelete(Keylet const &directory)
Remove the specified directory, if it is empty.
Definition ApplyView.cpp:125
+
ripple::ApplyView::dirRemove
bool dirRemove(Keylet const &directory, std::uint64_t page, uint256 const &key, bool keepRoot)
Remove an entry from a directory.
Definition ApplyView.cpp:207
+
ripple::ApplyView::emptyDirDelete
bool emptyDirDelete(Keylet const &directory)
Remove the specified directory, if it is empty.
Definition ApplyView.cpp:141
ripple::Issue
A currency issued by an account.
Definition Issue.h:33
ripple::Issue::account
AccountID account
Definition Issue.h:36
ripple::Issue::currency
Currency currency
Definition Issue.h:35
@@ -684,7 +684,7 @@ $(document).ready(function() { init_codefold(0); });
ripple::ammAccountHolds
STAmount ammAccountHolds(ReadView const &view, AccountID const &ammAccountID, Issue const &issue)
Returns total amount held by AMM for the given token.
Definition AMMUtils.cpp:211
ripple::root
Number root(Number f, unsigned d)
Definition Number.cpp:636
ripple::deleteAMMTrustLine
TER deleteAMMTrustLine(ApplyView &view, std::shared_ptr< SLE > sleState, std::optional< AccountID > const &ammAccountID, beast::Journal j)
Delete trustline to AMM.
Definition View.cpp:2806
-
ripple::maxDeletableAMMTrustLines
std::uint16_t constexpr maxDeletableAMMTrustLines
The maximum number of trustlines to delete as part of AMM account deletion cleanup.
Definition Protocol.h:147
+
ripple::maxDeletableAMMTrustLines
std::uint16_t constexpr maxDeletableAMMTrustLines
The maximum number of trustlines to delete as part of AMM account deletion cleanup.
Definition Protocol.h:150
ripple::TER
TERSubset< CanCvtToTER > TER
Definition TER.h:645
ripple::withinRelativeDistance
bool withinRelativeDistance(Quality const &calcQuality, Quality const &reqQuality, Number const &dist)
Check if the relative distance between the qualities is within the requested distance.
Definition AMMHelpers.h:129
ripple::AUCTION_SLOT_DISCOUNTED_FEE_FRACTION
std::uint32_t constexpr AUCTION_SLOT_DISCOUNTED_FEE_FRACTION
Definition AMMCore.h:38
diff --git a/AMM__test_8cpp_source.html b/AMM__test_8cpp_source.html index 0a865681c8..0800c433f9 100644 --- a/AMM__test_8cpp_source.html +++ b/AMM__test_8cpp_source.html @@ -8304,7 +8304,7 @@ $(document).ready(function() { init_codefold(0); });
ripple::tfTwoAssetIfEmpty
constexpr std::uint32_t tfTwoAssetIfEmpty
Definition TxFlags.h:251
ripple::amountFromString
STAmount amountFromString(Asset const &asset, std::string const &amount)
Definition STAmount.cpp:996
ripple::asfAllowTrustLineClawback
constexpr std::uint32_t asfAllowTrustLineClawback
Definition TxFlags.h:94
-
ripple::maxDeletableAMMTrustLines
std::uint16_t constexpr maxDeletableAMMTrustLines
The maximum number of trustlines to delete as part of AMM account deletion cleanup.
Definition Protocol.h:147
+
ripple::maxDeletableAMMTrustLines
std::uint16_t constexpr maxDeletableAMMTrustLines
The maximum number of trustlines to delete as part of AMM account deletion cleanup.
Definition Protocol.h:150
ripple::asfRequireAuth
constexpr std::uint32_t asfRequireAuth
Definition TxFlags.h:78
ripple::terADDRESS_COLLISION
@ terADDRESS_COLLISION
Definition TER.h:228
ripple::terNO_ACCOUNT
@ terNO_ACCOUNT
Definition TER.h:217
diff --git a/ApplyView_8cpp_source.html b/ApplyView_8cpp_source.html index 1945c41712..e32ac5005b 100644 --- a/ApplyView_8cpp_source.html +++ b/ApplyView_8cpp_source.html @@ -105,362 +105,380 @@ $(document).ready(function() { init_codefold(0); });
22#include <xrpl/ledger/ApplyView.h>
23#include <xrpl/protocol/Protocol.h>
24
-
25namespace ripple {
-
26
-
27std::optional<std::uint64_t>
-
-
28ApplyView::dirAdd(
-
29 bool preserveOrder,
-
30 Keylet const& directory,
-
31 uint256 const& key,
-
32 std::function<void(std::shared_ptr<SLE> const&)> const& describe)
-
33{
-
34 auto root = peek(directory);
-
35
-
36 if (!root)
-
37 {
-
38 // No root, make it.
-
39 root = std::make_shared<SLE>(directory);
-
40 root->setFieldH256(sfRootIndex, directory.key);
-
41 describe(root);
-
42
-
43 STVector256 v;
-
44 v.push_back(key);
-
45 root->setFieldV256(sfIndexes, v);
-
46
-
47 insert(root);
-
48 return std::uint64_t{0};
-
49 }
-
50
-
51 std::uint64_t page = root->getFieldU64(sfIndexPrevious);
-
52
-
53 auto node = root;
-
54
-
55 if (page)
-
56 {
-
57 node = peek(keylet::page(directory, page));
-
58 if (!node)
-
59 LogicError("Directory chain: root back-pointer broken.");
-
60 }
-
61
-
62 auto indexes = node->getFieldV256(sfIndexes);
-
63
-
64 // If there's space, we use it:
-
65 if (indexes.size() < dirNodeMaxEntries)
-
66 {
-
67 if (preserveOrder)
-
68 {
-
69 if (std::find(indexes.begin(), indexes.end(), key) != indexes.end())
-
70 LogicError("dirInsert: double insertion");
-
71
-
72 indexes.push_back(key);
-
73 }
-
74 else
-
75 {
-
76 // We can't be sure if this page is already sorted because
-
77 // it may be a legacy page we haven't yet touched. Take
-
78 // the time to sort it.
-
79 std::sort(indexes.begin(), indexes.end());
-
80
-
81 auto pos = std::lower_bound(indexes.begin(), indexes.end(), key);
-
82
-
83 if (pos != indexes.end() && key == *pos)
-
84 LogicError("dirInsert: double insertion");
+
25#include <limits>
+
26#include <type_traits>
+
27
+
28namespace ripple {
+
29
+
30std::optional<std::uint64_t>
+
+ +
32 bool preserveOrder,
+
33 Keylet const& directory,
+
34 uint256 const& key,
+
35 std::function<void(std::shared_ptr<SLE> const&)> const& describe)
+
36{
+
37 auto root = peek(directory);
+
38
+
39 if (!root)
+
40 {
+
41 // No root, make it.
+
42 root = std::make_shared<SLE>(directory);
+
43 root->setFieldH256(sfRootIndex, directory.key);
+
44 describe(root);
+
45
+ +
47 v.push_back(key);
+
48 root->setFieldV256(sfIndexes, v);
+
49
+
50 insert(root);
+
51 return std::uint64_t{0};
+
52 }
+
53
+
54 std::uint64_t page = root->getFieldU64(sfIndexPrevious);
+
55
+
56 auto node = root;
+
57
+
58 if (page)
+
59 {
+
60 node = peek(keylet::page(directory, page));
+
61 if (!node)
+
62 LogicError("Directory chain: root back-pointer broken.");
+
63 }
+
64
+
65 auto indexes = node->getFieldV256(sfIndexes);
+
66
+
67 // If there's space, we use it:
+
68 if (indexes.size() < dirNodeMaxEntries)
+
69 {
+
70 if (preserveOrder)
+
71 {
+
72 if (std::find(indexes.begin(), indexes.end(), key) != indexes.end())
+
73 LogicError("dirInsert: double insertion");
+
74
+
75 indexes.push_back(key);
+
76 }
+
77 else
+
78 {
+
79 // We can't be sure if this page is already sorted because
+
80 // it may be a legacy page we haven't yet touched. Take
+
81 // the time to sort it.
+
82 std::sort(indexes.begin(), indexes.end());
+
83
+
84 auto pos = std::lower_bound(indexes.begin(), indexes.end(), key);
85
-
86 indexes.insert(pos, key);
-
87 }
+
86 if (pos != indexes.end() && key == *pos)
+
87 LogicError("dirInsert: double insertion");
88
-
89 node->setFieldV256(sfIndexes, indexes);
-
90 update(node);
-
91 return page;
-
92 }
-
93
-
94 // Check whether we're out of pages.
-
95 if (++page >= dirNodeMaxPages)
-
96 return std::nullopt;
-
97
-
98 // We are about to create a new node; we'll link it to
-
99 // the chain first:
-
100 node->setFieldU64(sfIndexNext, page);
-
101 update(node);
-
102
-
103 root->setFieldU64(sfIndexPrevious, page);
-
104 update(root);
-
105
-
106 // Insert the new key:
-
107 indexes.clear();
-
108 indexes.push_back(key);
-
109
-
110 node = std::make_shared<SLE>(keylet::page(directory, page));
-
111 node->setFieldH256(sfRootIndex, directory.key);
-
112 node->setFieldV256(sfIndexes, indexes);
+
89 indexes.insert(pos, key);
+
90 }
+
91
+
92 node->setFieldV256(sfIndexes, indexes);
+
93 update(node);
+
94 return page;
+
95 }
+
96
+
97 // We rely on modulo arithmetic of unsigned integers (guaranteed in
+
98 // [basic.fundamental] paragraph 2) to detect page representation overflow.
+
99 // For signed integers this would be UB, hence static_assert here.
+
100 static_assert(std::is_unsigned_v<decltype(page)>);
+
101 // Defensive check against breaking changes in compiler.
+
102 static_assert([]<typename T>(std::type_identity<T>) constexpr -> T {
+ +
104 return ++tmp;
+
105 }(std::type_identity<decltype(page)>{}) == 0);
+
106 ++page;
+
107 // Check whether we're out of pages.
+
108 if (page == 0)
+
109 return std::nullopt;
+
110 if (!rules().enabled(fixDirectoryLimit) &&
+
111 page >= dirNodeMaxPages) // Old pages limit
+
112 return std::nullopt;
113
-
114 // Save some space by not specifying the value 0 since
-
115 // it's the default.
-
116 if (page != 1)
-
117 node->setFieldU64(sfIndexPrevious, page - 1);
-
118 describe(node);
-
119 insert(node);
-
120
-
121 return page;
-
122}
+
114 // We are about to create a new node; we'll link it to
+
115 // the chain first:
+
116 node->setFieldU64(sfIndexNext, page);
+
117 update(node);
+
118
+
119 root->setFieldU64(sfIndexPrevious, page);
+
120 update(root);
+
121
+
122 // Insert the new key:
+
123 indexes.clear();
+
124 indexes.push_back(key);
+
125
+
126 node = std::make_shared<SLE>(keylet::page(directory, page));
+
127 node->setFieldH256(sfRootIndex, directory.key);
+
128 node->setFieldV256(sfIndexes, indexes);
+
129
+
130 // Save some space by not specifying the value 0 since
+
131 // it's the default.
+
132 if (page != 1)
+
133 node->setFieldU64(sfIndexPrevious, page - 1);
+
134 describe(node);
+
135 insert(node);
+
136
+
137 return page;
+
138}
-
123
-
124bool
-
- -
126{
-
127 auto node = peek(directory);
-
128
-
129 if (!node)
-
130 return false;
-
131
-
132 // Verify that the passed directory node is the directory root.
-
133 if (directory.type != ltDIR_NODE ||
-
134 node->getFieldH256(sfRootIndex) != directory.key)
-
135 {
-
136 // LCOV_EXCL_START
-
137 UNREACHABLE("ripple::ApplyView::emptyDirDelete : invalid node type");
-
138 return false;
-
139 // LCOV_EXCL_STOP
-
140 }
-
141
-
142 // The directory still contains entries and so it cannot be removed
-
143 if (!node->getFieldV256(sfIndexes).empty())
-
144 return false;
-
145
-
146 std::uint64_t constexpr rootPage = 0;
-
147 auto prevPage = node->getFieldU64(sfIndexPrevious);
-
148 auto nextPage = node->getFieldU64(sfIndexNext);
-
149
-
150 if (nextPage == rootPage && prevPage != rootPage)
-
151 LogicError("Directory chain: fwd link broken");
-
152
-
153 if (prevPage == rootPage && nextPage != rootPage)
-
154 LogicError("Directory chain: rev link broken");
-
155
-
156 // Older versions of the code would, in some cases, allow the last
-
157 // page to be empty. Remove such pages:
-
158 if (nextPage == prevPage && nextPage != rootPage)
-
159 {
-
160 auto last = peek(keylet::page(directory, nextPage));
+
139
+
140bool
+
+ +
142{
+
143 auto node = peek(directory);
+
144
+
145 if (!node)
+
146 return false;
+
147
+
148 // Verify that the passed directory node is the directory root.
+
149 if (directory.type != ltDIR_NODE ||
+
150 node->getFieldH256(sfRootIndex) != directory.key)
+
151 {
+
152 // LCOV_EXCL_START
+
153 UNREACHABLE("ripple::ApplyView::emptyDirDelete : invalid node type");
+
154 return false;
+
155 // LCOV_EXCL_STOP
+
156 }
+
157
+
158 // The directory still contains entries and so it cannot be removed
+
159 if (!node->getFieldV256(sfIndexes).empty())
+
160 return false;
161
-
162 if (!last)
-
163 LogicError("Directory chain: fwd link broken.");
-
164
-
165 if (!last->getFieldV256(sfIndexes).empty())
-
166 return false;
-
167
-
168 // Update the first page's linked list and
-
169 // mark it as updated.
-
170 node->setFieldU64(sfIndexNext, rootPage);
-
171 node->setFieldU64(sfIndexPrevious, rootPage);
-
172 update(node);
-
173
-
174 // And erase the empty last page:
-
175 erase(last);
-
176
-
177 // Make sure our local values reflect the
-
178 // updated information:
-
179 nextPage = rootPage;
-
180 prevPage = rootPage;
-
181 }
-
182
-
183 // If there are no other pages, erase the root:
-
184 if (nextPage == rootPage && prevPage == rootPage)
-
185 erase(node);
-
186
-
187 return true;
-
188}
-
+
162 std::uint64_t constexpr rootPage = 0;
+
163 auto prevPage = node->getFieldU64(sfIndexPrevious);
+
164 auto nextPage = node->getFieldU64(sfIndexNext);
+
165
+
166 if (nextPage == rootPage && prevPage != rootPage)
+
167 LogicError("Directory chain: fwd link broken");
+
168
+
169 if (prevPage == rootPage && nextPage != rootPage)
+
170 LogicError("Directory chain: rev link broken");
+
171
+
172 // Older versions of the code would, in some cases, allow the last
+
173 // page to be empty. Remove such pages:
+
174 if (nextPage == prevPage && nextPage != rootPage)
+
175 {
+
176 auto last = peek(keylet::page(directory, nextPage));
+
177
+
178 if (!last)
+
179 LogicError("Directory chain: fwd link broken.");
+
180
+
181 if (!last->getFieldV256(sfIndexes).empty())
+
182 return false;
+
183
+
184 // Update the first page's linked list and
+
185 // mark it as updated.
+
186 node->setFieldU64(sfIndexNext, rootPage);
+
187 node->setFieldU64(sfIndexPrevious, rootPage);
+
188 update(node);
189
-
190bool
-
- -
192 Keylet const& directory,
-
193 std::uint64_t page,
-
194 uint256 const& key,
-
195 bool keepRoot)
-
196{
-
197 auto node = peek(keylet::page(directory, page));
+
190 // And erase the empty last page:
+
191 erase(last);
+
192
+
193 // Make sure our local values reflect the
+
194 // updated information:
+
195 nextPage = rootPage;
+
196 prevPage = rootPage;
+
197 }
198
-
199 if (!node)
-
200 return false;
-
201
-
202 std::uint64_t constexpr rootPage = 0;
-
203
-
204 {
-
205 auto entries = node->getFieldV256(sfIndexes);
-
206
-
207 auto it = std::find(entries.begin(), entries.end(), key);
-
208
-
209 if (entries.end() == it)
-
210 return false;
-
211
-
212 // We always preserve the relative order when we remove.
-
213 entries.erase(it);
+
199 // If there are no other pages, erase the root:
+
200 if (nextPage == rootPage && prevPage == rootPage)
+
201 erase(node);
+
202
+
203 return true;
+
204}
+
+
205
+
206bool
+
+ +
208 Keylet const& directory,
+
209 std::uint64_t page,
+
210 uint256 const& key,
+
211 bool keepRoot)
+
212{
+
213 auto node = peek(keylet::page(directory, page));
214
-
215 node->setFieldV256(sfIndexes, entries);
-
216 update(node);
+
215 if (!node)
+
216 return false;
217
-
218 if (!entries.empty())
-
219 return true;
-
220 }
-
221
-
222 // The current page is now empty; check if it can be
-
223 // deleted, and, if so, whether the entire directory
-
224 // can now be removed.
-
225 auto prevPage = node->getFieldU64(sfIndexPrevious);
-
226 auto nextPage = node->getFieldU64(sfIndexNext);
+
218 std::uint64_t constexpr rootPage = 0;
+
219
+
220 {
+
221 auto entries = node->getFieldV256(sfIndexes);
+
222
+
223 auto it = std::find(entries.begin(), entries.end(), key);
+
224
+
225 if (entries.end() == it)
+
226 return false;
227
-
228 // The first page is the directory's root node and is
-
229 // treated specially: it can never be deleted even if
-
230 // it is empty, unless we plan on removing the entire
-
231 // directory.
-
232 if (page == rootPage)
-
233 {
-
234 if (nextPage == page && prevPage != page)
-
235 LogicError("Directory chain: fwd link broken");
-
236
-
237 if (prevPage == page && nextPage != page)
-
238 LogicError("Directory chain: rev link broken");
-
239
-
240 // Older versions of the code would, in some cases,
-
241 // allow the last page to be empty. Remove such
-
242 // pages if we stumble on them:
-
243 if (nextPage == prevPage && nextPage != page)
-
244 {
-
245 auto last = peek(keylet::page(directory, nextPage));
-
246 if (!last)
-
247 LogicError("Directory chain: fwd link broken.");
-
248
-
249 if (last->getFieldV256(sfIndexes).empty())
-
250 {
-
251 // Update the first page's linked list and
-
252 // mark it as updated.
-
253 node->setFieldU64(sfIndexNext, page);
-
254 node->setFieldU64(sfIndexPrevious, page);
-
255 update(node);
-
256
-
257 // And erase the empty last page:
-
258 erase(last);
-
259
-
260 // Make sure our local values reflect the
-
261 // updated information:
-
262 nextPage = page;
-
263 prevPage = page;
-
264 }
-
265 }
-
266
-
267 if (keepRoot)
-
268 return true;
-
269
-
270 // If there's no other pages, erase the root:
-
271 if (nextPage == page && prevPage == page)
-
272 erase(node);
-
273
-
274 return true;
-
275 }
-
276
-
277 // This can never happen for nodes other than the root:
-
278 if (nextPage == page)
-
279 LogicError("Directory chain: fwd link broken");
-
280
-
281 if (prevPage == page)
-
282 LogicError("Directory chain: rev link broken");
-
283
-
284 // This node isn't the root, so it can either be in the
-
285 // middle of the list, or at the end. Unlink it first
-
286 // and then check if that leaves the list with only a
-
287 // root:
-
288 auto prev = peek(keylet::page(directory, prevPage));
-
289 if (!prev)
-
290 LogicError("Directory chain: fwd link broken.");
-
291 // Fix previous to point to its new next.
-
292 prev->setFieldU64(sfIndexNext, nextPage);
-
293 update(prev);
-
294
-
295 auto next = peek(keylet::page(directory, nextPage));
-
296 if (!next)
-
297 LogicError("Directory chain: rev link broken.");
-
298 // Fix next to point to its new previous.
-
299 next->setFieldU64(sfIndexPrevious, prevPage);
-
300 update(next);
-
301
-
302 // The page is no longer linked. Delete it.
-
303 erase(node);
-
304
-
305 // Check whether the next page is the last page and, if
-
306 // so, whether it's empty. If it is, delete it.
-
307 if (nextPage != rootPage && next->getFieldU64(sfIndexNext) == rootPage &&
-
308 next->getFieldV256(sfIndexes).empty())
-
309 {
-
310 // Since next doesn't point to the root, it
-
311 // can't be pointing to prev.
-
312 erase(next);
-
313
-
314 // The previous page is now the last page:
-
315 prev->setFieldU64(sfIndexNext, rootPage);
-
316 update(prev);
+
228 // We always preserve the relative order when we remove.
+
229 entries.erase(it);
+
230
+
231 node->setFieldV256(sfIndexes, entries);
+
232 update(node);
+
233
+
234 if (!entries.empty())
+
235 return true;
+
236 }
+
237
+
238 // The current page is now empty; check if it can be
+
239 // deleted, and, if so, whether the entire directory
+
240 // can now be removed.
+
241 auto prevPage = node->getFieldU64(sfIndexPrevious);
+
242 auto nextPage = node->getFieldU64(sfIndexNext);
+
243
+
244 // The first page is the directory's root node and is
+
245 // treated specially: it can never be deleted even if
+
246 // it is empty, unless we plan on removing the entire
+
247 // directory.
+
248 if (page == rootPage)
+
249 {
+
250 if (nextPage == page && prevPage != page)
+
251 LogicError("Directory chain: fwd link broken");
+
252
+
253 if (prevPage == page && nextPage != page)
+
254 LogicError("Directory chain: rev link broken");
+
255
+
256 // Older versions of the code would, in some cases,
+
257 // allow the last page to be empty. Remove such
+
258 // pages if we stumble on them:
+
259 if (nextPage == prevPage && nextPage != page)
+
260 {
+
261 auto last = peek(keylet::page(directory, nextPage));
+
262 if (!last)
+
263 LogicError("Directory chain: fwd link broken.");
+
264
+
265 if (last->getFieldV256(sfIndexes).empty())
+
266 {
+
267 // Update the first page's linked list and
+
268 // mark it as updated.
+
269 node->setFieldU64(sfIndexNext, page);
+
270 node->setFieldU64(sfIndexPrevious, page);
+
271 update(node);
+
272
+
273 // And erase the empty last page:
+
274 erase(last);
+
275
+
276 // Make sure our local values reflect the
+
277 // updated information:
+
278 nextPage = page;
+
279 prevPage = page;
+
280 }
+
281 }
+
282
+
283 if (keepRoot)
+
284 return true;
+
285
+
286 // If there's no other pages, erase the root:
+
287 if (nextPage == page && prevPage == page)
+
288 erase(node);
+
289
+
290 return true;
+
291 }
+
292
+
293 // This can never happen for nodes other than the root:
+
294 if (nextPage == page)
+
295 LogicError("Directory chain: fwd link broken");
+
296
+
297 if (prevPage == page)
+
298 LogicError("Directory chain: rev link broken");
+
299
+
300 // This node isn't the root, so it can either be in the
+
301 // middle of the list, or at the end. Unlink it first
+
302 // and then check if that leaves the list with only a
+
303 // root:
+
304 auto prev = peek(keylet::page(directory, prevPage));
+
305 if (!prev)
+
306 LogicError("Directory chain: fwd link broken.");
+
307 // Fix previous to point to its new next.
+
308 prev->setFieldU64(sfIndexNext, nextPage);
+
309 update(prev);
+
310
+
311 auto next = peek(keylet::page(directory, nextPage));
+
312 if (!next)
+
313 LogicError("Directory chain: rev link broken.");
+
314 // Fix next to point to its new previous.
+
315 next->setFieldU64(sfIndexPrevious, prevPage);
+
316 update(next);
317
-
318 // And the root points to the last page:
-
319 auto root = peek(keylet::page(directory, rootPage));
-
320 if (!root)
-
321 LogicError("Directory chain: root link broken.");
-
322 root->setFieldU64(sfIndexPrevious, prevPage);
-
323 update(root);
-
324
-
325 nextPage = rootPage;
-
326 }
-
327
-
328 // If we're not keeping the root, then check to see if
-
329 // it's left empty. If so, delete it as well.
-
330 if (!keepRoot && nextPage == rootPage && prevPage == rootPage)
-
331 {
-
332 if (prev->getFieldV256(sfIndexes).empty())
-
333 erase(prev);
-
334 }
-
335
-
336 return true;
-
337}
-
-
338
-
339bool
-
- -
341 Keylet const& directory,
-
342 std::function<void(uint256 const&)> const& callback)
-
343{
- -
345
-
346 do
+
318 // The page is no longer linked. Delete it.
+
319 erase(node);
+
320
+
321 // Check whether the next page is the last page and, if
+
322 // so, whether it's empty. If it is, delete it.
+
323 if (nextPage != rootPage && next->getFieldU64(sfIndexNext) == rootPage &&
+
324 next->getFieldV256(sfIndexes).empty())
+
325 {
+
326 // Since next doesn't point to the root, it
+
327 // can't be pointing to prev.
+
328 erase(next);
+
329
+
330 // The previous page is now the last page:
+
331 prev->setFieldU64(sfIndexNext, rootPage);
+
332 update(prev);
+
333
+
334 // And the root points to the last page:
+
335 auto root = peek(keylet::page(directory, rootPage));
+
336 if (!root)
+
337 LogicError("Directory chain: root link broken.");
+
338 root->setFieldU64(sfIndexPrevious, prevPage);
+
339 update(root);
+
340
+
341 nextPage = rootPage;
+
342 }
+
343
+
344 // If we're not keeping the root, then check to see if
+
345 // it's left empty. If so, delete it as well.
+
346 if (!keepRoot && nextPage == rootPage && prevPage == rootPage)
347 {
-
348 auto const page = peek(keylet::page(directory, pi.value_or(0)));
-
349
-
350 if (!page)
-
351 return false;
-
352
-
353 for (auto const& item : page->getFieldV256(sfIndexes))
-
354 callback(item);
-
355
-
356 pi = (*page)[~sfIndexNext];
-
357
-
358 erase(page);
-
359 } while (pi);
-
360
-
361 return true;
-
362}
+
348 if (prev->getFieldV256(sfIndexes).empty())
+
349 erase(prev);
+
350 }
+
351
+
352 return true;
+
353}
-
363
-
364} // namespace ripple
-
bool dirDelete(Keylet const &directory, std::function< void(uint256 const &)> const &)
Remove the specified directory, invoking the callback for every node.
+
354
+
355bool
+
+ +
357 Keylet const& directory,
+
358 std::function<void(uint256 const&)> const& callback)
+
359{
+ +
361
+
362 do
+
363 {
+
364 auto const page = peek(keylet::page(directory, pi.value_or(0)));
+
365
+
366 if (!page)
+
367 return false;
+
368
+
369 for (auto const& item : page->getFieldV256(sfIndexes))
+
370 callback(item);
+
371
+
372 pi = (*page)[~sfIndexNext];
+
373
+
374 erase(page);
+
375 } while (pi);
+
376
+
377 return true;
+
378}
+
+
379
+
380} // namespace ripple
+
bool dirDelete(Keylet const &directory, std::function< void(uint256 const &)> const &)
Remove the specified directory, invoking the callback for every node.
virtual void update(std::shared_ptr< SLE > const &sle)=0
Indicate changes to a peeked SLE.
-
bool dirRemove(Keylet const &directory, std::uint64_t page, uint256 const &key, bool keepRoot)
Remove an entry from a directory.
-
bool emptyDirDelete(Keylet const &directory)
Remove the specified directory, if it is empty.
-
std::optional< std::uint64_t > dirAdd(bool preserveOrder, Keylet const &directory, uint256 const &key, std::function< void(std::shared_ptr< SLE > const &)> const &describe)
Add an entry to a directory using the specified insert strategy.
Definition ApplyView.cpp:28
+
bool dirRemove(Keylet const &directory, std::uint64_t page, uint256 const &key, bool keepRoot)
Remove an entry from a directory.
+
bool emptyDirDelete(Keylet const &directory)
Remove the specified directory, if it is empty.
+
std::optional< std::uint64_t > dirAdd(bool preserveOrder, Keylet const &directory, uint256 const &key, std::function< void(std::shared_ptr< SLE > const &)> const &describe)
Add an entry to a directory using the specified insert strategy.
Definition ApplyView.cpp:31
virtual void insert(std::shared_ptr< SLE > const &sle)=0
Insert a new state SLE.
virtual std::shared_ptr< SLE > peek(Keylet const &k)=0
Prepare to modify the SLE associated with key.
virtual void erase(std::shared_ptr< SLE > const &sle)=0
Remove a peeked SLE.
+
virtual Rules const & rules() const =0
Returns the tx processing rules.
+
bool enabled(uint256 const &feature) const
Returns true if a feature is enabled.
Definition Rules.cpp:130
void push_back(uint256 const &v)
@@ -468,10 +486,13 @@ $(document).ready(function() { init_codefold(0); });
T is_same_v
+
T is_unsigned_v
+
T lower_bound(T... args)
+
T max(T... args)
Keylet page(uint256 const &root, std::uint64_t index=0) noexcept
A page in a directory.
Definition Indexes.cpp:380
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:25
-
std::uint64_t constexpr dirNodeMaxPages
The maximum number of pages allowed in a directory.
Definition Protocol.h:59
+
std::uint64_t constexpr dirNodeMaxPages
The maximum number of pages allowed in a directory.
Definition Protocol.h:62
std::size_t constexpr dirNodeMaxEntries
The maximum number of entries per directory page.
Definition Protocol.h:56
Number root(Number f, unsigned d)
Definition Number.cpp:636
void LogicError(std::string const &how) noexcept
Called when faulty logic causes a broken invariant.
@@ -481,6 +502,8 @@ $(document).ready(function() { init_codefold(0); });
A pair of SHAMap key and LedgerEntryType.
Definition Keylet.h:39
LedgerEntryType type
Definition Keylet.h:41
uint256 key
Definition Keylet.h:40
+ +
T value_or(T... args)
diff --git a/ApplyView_8h_source.html b/ApplyView_8h_source.html index 7912f53129..ae189e04de 100644 --- a/ApplyView_8h_source.html +++ b/ApplyView_8h_source.html @@ -330,13 +330,13 @@ $(document).ready(function() { init_codefold(0); });
ripple::ApplyView::dirInsert
std::optional< std::uint64_t > dirInsert(Keylet const &directory, Keylet const &key, std::function< void(std::shared_ptr< SLE > const &)> const &describe)
Definition ApplyView.h:328
ripple::ApplyView::creditHook
virtual void creditHook(AccountID const &from, AccountID const &to, STAmount const &amount, STAmount const &preCreditBalance)
Definition ApplyView.h:243
ripple::ApplyView::ApplyView
ApplyView()=default
-
ripple::ApplyView::dirDelete
bool dirDelete(Keylet const &directory, std::function< void(uint256 const &)> const &)
Remove the specified directory, invoking the callback for every node.
Definition ApplyView.cpp:340
+
ripple::ApplyView::dirDelete
bool dirDelete(Keylet const &directory, std::function< void(uint256 const &)> const &)
Remove the specified directory, invoking the callback for every node.
Definition ApplyView.cpp:356
ripple::ApplyView::update
virtual void update(std::shared_ptr< SLE > const &sle)=0
Indicate changes to a peeked SLE.
-
ripple::ApplyView::dirRemove
bool dirRemove(Keylet const &directory, std::uint64_t page, uint256 const &key, bool keepRoot)
Remove an entry from a directory.
Definition ApplyView.cpp:191
-
ripple::ApplyView::emptyDirDelete
bool emptyDirDelete(Keylet const &directory)
Remove the specified directory, if it is empty.
Definition ApplyView.cpp:125
+
ripple::ApplyView::dirRemove
bool dirRemove(Keylet const &directory, std::uint64_t page, uint256 const &key, bool keepRoot)
Remove an entry from a directory.
Definition ApplyView.cpp:207
+
ripple::ApplyView::emptyDirDelete
bool emptyDirDelete(Keylet const &directory)
Remove the specified directory, if it is empty.
Definition ApplyView.cpp:141
ripple::ApplyView::dirAppend
std::optional< std::uint64_t > dirAppend(Keylet const &directory, Keylet const &key, std::function< void(std::shared_ptr< SLE > const &)> const &describe)
Append an entry to a directory.
Definition ApplyView.h:280
ripple::ApplyView::adjustOwnerCountHook
virtual void adjustOwnerCountHook(AccountID const &account, std::uint32_t cur, std::uint32_t next)
Definition ApplyView.h:254
-
ripple::ApplyView::dirAdd
std::optional< std::uint64_t > dirAdd(bool preserveOrder, Keylet const &directory, uint256 const &key, std::function< void(std::shared_ptr< SLE > const &)> const &describe)
Add an entry to a directory using the specified insert strategy.
Definition ApplyView.cpp:28
+
ripple::ApplyView::dirAdd
std::optional< std::uint64_t > dirAdd(bool preserveOrder, Keylet const &directory, uint256 const &key, std::function< void(std::shared_ptr< SLE > const &)> const &describe)
Add an entry to a directory using the specified insert strategy.
Definition ApplyView.cpp:31
ripple::ApplyView::insert
virtual void insert(std::shared_ptr< SLE > const &sle)=0
Insert a new state SLE.
ripple::ApplyView::flags
virtual ApplyFlags flags() const =0
Returns the tx apply flags.
ripple::ApplyView::dirRemove
bool dirRemove(Keylet const &directory, std::uint64_t page, Keylet const &key, bool keepRoot)
Definition ApplyView.h:361
diff --git a/Batch_8cpp_source.html b/Batch_8cpp_source.html index 9673ea4257..488d52aa55 100644 --- a/Batch_8cpp_source.html +++ b/Batch_8cpp_source.html @@ -602,7 +602,7 @@ $(document).ready(function() { init_codefold(0); });
ripple::tesSUCCESS
@ tesSUCCESS
Definition TER.h:244
ripple::isTesSuccess
bool isTesSuccess(TER x) noexcept
Definition TER.h:674
ripple::tapBATCH
@ tapBATCH
Definition ApplyView.h:45
-
ripple::maxBatchTxCount
std::size_t constexpr maxBatchTxCount
The maximum number of transactions that can be in a batch.
Definition Protocol.h:179
+
ripple::maxBatchTxCount
std::size_t constexpr maxBatchTxCount
The maximum number of transactions that can be in a batch.
Definition Protocol.h:182
ripple::tfInnerBatchTxn
constexpr std::uint32_t tfInnerBatchTxn
Definition TxFlags.h:61
ripple::temREDUNDANT
@ temREDUNDANT
Definition TER.h:112
ripple::temBAD_FEE
@ temBAD_FEE
Definition TER.h:92
diff --git a/CashCheck_8cpp_source.html b/CashCheck_8cpp_source.html index ceb33557e6..f18309c6bd 100644 --- a/CashCheck_8cpp_source.html +++ b/CashCheck_8cpp_source.html @@ -614,7 +614,7 @@ $(document).ready(function() { init_codefold(0); });
ripple::ApplyContext::journal
beast::Journal const journal
Definition ApplyContext.h:75
ripple::ApplyContext::tx
STTx const & tx
Definition ApplyContext.h:72
ripple::ApplyContext::deliver
void deliver(STAmount const &amount)
Sets the DeliveredAmount field in the metadata.
Definition ApplyContext.h:104
-
ripple::ApplyView::dirRemove
bool dirRemove(Keylet const &directory, std::uint64_t page, uint256 const &key, bool keepRoot)
Remove an entry from a directory.
Definition ApplyView.cpp:191
+
ripple::ApplyView::dirRemove
bool dirRemove(Keylet const &directory, std::uint64_t page, uint256 const &key, bool keepRoot)
Remove an entry from a directory.
Definition ApplyView.cpp:207
ripple::CashCheck::preclaim
static TER preclaim(PreclaimContext const &ctx)
Definition CashCheck.cpp:69
ripple::CashCheck::doApply
TER doApply() override
Definition CashCheck.cpp:241
ripple::CashCheck::preflight
static NotTEC preflight(PreflightContext const &ctx)
Definition CashCheck.cpp:36
diff --git a/Change_8cpp_source.html b/Change_8cpp_source.html index 53cad28133..0c0c5b3423 100644 --- a/Change_8cpp_source.html +++ b/Change_8cpp_source.html @@ -625,7 +625,7 @@ $(document).ready(function() { init_codefold(0); });
ripple::ApplyContext::app
Application & app
Definition ApplyContext.h:71
ripple::ApplyContext::tx
STTx const & tx
Definition ApplyContext.h:72
ripple::ApplyView::update
virtual void update(std::shared_ptr< SLE > const &sle)=0
Indicate changes to a peeked SLE.
-
ripple::ApplyView::dirRemove
bool dirRemove(Keylet const &directory, std::uint64_t page, uint256 const &key, bool keepRoot)
Remove an entry from a directory.
Definition ApplyView.cpp:191
+
ripple::ApplyView::dirRemove
bool dirRemove(Keylet const &directory, std::uint64_t page, uint256 const &key, bool keepRoot)
Remove an entry from a directory.
Definition ApplyView.cpp:207
ripple::ApplyView::insert
virtual void insert(std::shared_ptr< SLE > const &sle)=0
Insert a new state SLE.
ripple::ApplyView::peek
virtual std::shared_ptr< SLE > peek(Keylet const &k)=0
Prepare to modify the SLE associated with key.
ripple::Change::activateTrustLinesToSelfFix
void activateTrustLinesToSelfFix()
Definition Change.cpp:170
diff --git a/CredentialHelpers_8cpp_source.html b/CredentialHelpers_8cpp_source.html index cfa71e606c..7eb3afed0a 100644 --- a/CredentialHelpers_8cpp_source.html +++ b/CredentialHelpers_8cpp_source.html @@ -503,7 +503,7 @@ $(document).ready(function() { init_codefold(0); });
beast::Journal::fatal
Stream fatal() const
Definition Journal.h:352
beast::Journal::trace
Stream trace() const
Severity stream access functions.
Definition Journal.h:322
ripple::ApplyView
Writeable view to a ledger, for applying a transaction.
Definition ApplyView.h:143
-
ripple::ApplyView::dirRemove
bool dirRemove(Keylet const &directory, std::uint64_t page, uint256 const &key, bool keepRoot)
Remove an entry from a directory.
Definition ApplyView.cpp:191
+
ripple::ApplyView::dirRemove
bool dirRemove(Keylet const &directory, std::uint64_t page, uint256 const &key, bool keepRoot)
Remove an entry from a directory.
Definition ApplyView.cpp:207
ripple::ApplyView::peek
virtual std::shared_ptr< SLE > peek(Keylet const &k)=0
Prepare to modify the SLE associated with key.
ripple::ApplyView::erase
virtual void erase(std::shared_ptr< SLE > const &sle)=0
Remove a peeked SLE.
ripple::ReadView
A view into a ledger.
Definition ReadView.h:51
@@ -547,9 +547,9 @@ $(document).ready(function() { init_codefold(0); });
ripple::tefBAD_LEDGER
@ tefBAD_LEDGER
Definition TER.h:170
ripple::tefINTERNAL
@ tefINTERNAL
Definition TER.h:173
ripple::QualityDirection::out
@ out
-
ripple::maxCredentialsArraySize
std::size_t constexpr maxCredentialsArraySize
The maximum number of credentials can be passed in array.
Definition Protocol.h:106
+
ripple::maxCredentialsArraySize
std::size_t constexpr maxCredentialsArraySize
The maximum number of credentials can be passed in array.
Definition Protocol.h:109
ripple::ManifestDisposition::accepted
@ accepted
Manifest is valid.
-
ripple::maxCredentialTypeLength
std::size_t constexpr maxCredentialTypeLength
The maximum length of a CredentialType inside a Credential.
Definition Protocol.h:103
+
ripple::maxCredentialTypeLength
std::size_t constexpr maxCredentialTypeLength
The maximum length of a CredentialType inside a Credential.
Definition Protocol.h:106
ripple::makeSlice
std::enable_if_t< std::is_same< T, char >::value||std::is_same< T, unsigned char >::value, Slice > makeSlice(std::array< T, N > const &a)
Definition Slice.h:244
ripple::tecNO_ENTRY
@ tecNO_ENTRY
Definition TER.h:306
ripple::tecOBJECT_NOT_FOUND
@ tecOBJECT_NOT_FOUND
Definition TER.h:326
diff --git a/Credentials_8cpp_source.html b/Credentials_8cpp_source.html index 940e089aed..3b7ee48c17 100644 --- a/Credentials_8cpp_source.html +++ b/Credentials_8cpp_source.html @@ -252,7 +252,7 @@ $(document).ready(function() { init_codefold(0); });
162 << to_string(credentialKey.key) << ": "
163 << (page ? "success" : "failure");
164 if (!page)
-
165 return tecDIR_FULL; // LCOV_EXCL_LINE
+
165 return tecDIR_FULL;
166 sleCred->setFieldU64(sfIssuerNode, *page);
167
168 adjustOwnerCount(view(), sleIssuer, 1, j_);
@@ -272,7 +272,7 @@ $(document).ready(function() { init_codefold(0); });
182 << to_string(credentialKey.key) << ": "
183 << (page ? "success" : "failure");
184 if (!page)
-
185 return tecDIR_FULL; // LCOV_EXCL_LINE
+
185 return tecDIR_FULL;
186 sleCred->setFieldU64(sfSubjectNode, *page);
187 view().update(view().peek(keylet::account(subject)));
188 }
@@ -525,12 +525,12 @@ $(document).ready(function() { init_codefold(0); });
ripple::keylet::account
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition Indexes.cpp:184
ripple::keylet::ownerDir
Keylet ownerDir(AccountID const &id) noexcept
The root page of an account's directory.
Definition Indexes.cpp:374
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:25
-
ripple::maxCredentialURILength
std::size_t constexpr maxCredentialURILength
The maximum length of a URI inside a Credential.
Definition Protocol.h:100
+
ripple::maxCredentialURILength
std::size_t constexpr maxCredentialURILength
The maximum length of a URI inside a Credential.
Definition Protocol.h:103
ripple::lsfAccepted
@ lsfAccepted
Definition LedgerFormats.h:204
ripple::adjustOwnerCount
void adjustOwnerCount(ApplyView &view, std::shared_ptr< SLE > const &sle, std::int32_t amount, beast::Journal j)
Adjust the owner count up or down.
Definition View.cpp:1032
ripple::describeOwnerDir
std::function< void(SLE::ref)> describeOwnerDir(AccountID const &account)
Definition View.cpp:1050
ripple::tefINTERNAL
@ tefINTERNAL
Definition TER.h:173
-
ripple::maxCredentialTypeLength
std::size_t constexpr maxCredentialTypeLength
The maximum length of a CredentialType inside a Credential.
Definition Protocol.h:103
+
ripple::maxCredentialTypeLength
std::size_t constexpr maxCredentialTypeLength
The maximum length of a CredentialType inside a Credential.
Definition Protocol.h:106
ripple::tecNO_ENTRY
@ tecNO_ENTRY
Definition TER.h:306
ripple::tecNO_ISSUER
@ tecNO_ISSUER
Definition TER.h:299
ripple::tecNO_TARGET
@ tecNO_TARGET
Definition TER.h:304
diff --git a/Credentials__test_8cpp_source.html b/Credentials__test_8cpp_source.html index 1961ee1304..b58420e045 100644 --- a/Credentials__test_8cpp_source.html +++ b/Credentials__test_8cpp_source.html @@ -647,559 +647,593 @@ $(document).ready(function() { init_codefold(0); });
558 jle[jss::result][jss::node]["CredentialType"] ==
559 strHex(std::string_view(credType)));
560 }
-
561 }
-
562
-
563 {
-
564 using namespace jtx;
-
565 Env env{*this, features};
-
566
-
567 env.fund(XRP(5000), issuer);
-
568 env.close();
-
569
-
570 {
-
571 testcase("Credentials fail, subject doesn't exist.");
-
572 auto const jv = credentials::create(subject, issuer, credType);
-
573 env(jv, ter(tecNO_TARGET));
-
574 }
-
575 }
-
576
-
577 {
-
578 using namespace jtx;
-
579 Env env{*this, features};
+
561
+
562 {
+
563 testcase("Credentials fail, directory full");
+
564 std::uint32_t const issuerSeq{env.seq(issuer) + 1};
+
565 env(ticket::create(issuer, 63));
+
566 env.close();
+
567
+
568 // Everything below can only be tested on open ledger.
+
569 auto const res1 = directory::bumpLastPage(
+
570 env,
+
571 directory::maximumPageIndex(env),
+
572 keylet::ownerDir(issuer.id()),
+
573 directory::adjustOwnerNode);
+
574 BEAST_EXPECT(res1);
+
575
+
576 auto const jv = credentials::create(issuer, subject, credType);
+
577 env(jv, ter(tecDIR_FULL));
+
578 // Free one directory entry by using a ticket
+
579 env(noop(issuer), ticket::use(issuerSeq + 40));
580
-
581 auto const reserve = drops(env.current()->fees().reserve);
-
582 env.fund(reserve, subject, issuer);
-
583 env.close();
-
584
-
585 testcase("Credentials fail, not enough reserve.");
-
586 {
-
587 auto const jv = credentials::create(subject, issuer, credType);
-
588 env(jv, ter(tecINSUFFICIENT_RESERVE));
-
589 env.close();
-
590 }
-
591 }
-
592 }
+
581 // Fill subject directory
+
582 env(ticket::create(subject, 63));
+
583 auto const res2 = directory::bumpLastPage(
+
584 env,
+
585 directory::maximumPageIndex(env),
+
586 keylet::ownerDir(subject.id()),
+
587 directory::adjustOwnerNode);
+
588 BEAST_EXPECT(res2);
+
589 env(jv, ter(tecDIR_FULL));
+
590
+
591 // End test
+
592 env.close();
+
593 }
+
594 }
+
595
+
596 {
+
597 using namespace jtx;
+
598 Env env{*this, features};
+
599
+
600 env.fund(XRP(5000), issuer);
+
601 env.close();
+
602
+
603 {
+
604 testcase("Credentials fail, subject doesn't exist.");
+
605 auto const jv = credentials::create(subject, issuer, credType);
+
606 env(jv, ter(tecNO_TARGET));
+
607 }
+
608 }
+
609
+
610 {
+
611 using namespace jtx;
+
612 Env env{*this, features};
+
613
+
614 auto const reserve = drops(env.current()->fees().reserve);
+
615 env.fund(reserve, subject, issuer);
+
616 env.close();
+
617
+
618 testcase("Credentials fail, not enough reserve.");
+
619 {
+
620 auto const jv = credentials::create(subject, issuer, credType);
+
621 env(jv, ter(tecINSUFFICIENT_RESERVE));
+
622 env.close();
+
623 }
+
624 }
+
625 }
-
593
-
594 void
-
-
595 testAcceptFailed(FeatureBitset features)
-
596 {
-
597 using namespace jtx;
-
598
-
599 char const credType[] = "abcde";
-
600 Account const issuer{"issuer"};
-
601 Account const subject{"subject"};
-
602 Account const other{"other"};
-
603
-
604 {
-
605 Env env{*this, features};
-
606
-
607 env.fund(XRP(5000), subject, issuer);
-
608
-
609 {
-
610 testcase("CredentialsAccept fail, Credential doesn't exist.");
-
611 env(credentials::accept(subject, issuer, credType),
-
612 ter(tecNO_ENTRY));
-
613 env.close();
-
614 }
-
615
-
616 {
-
617 testcase("CredentialsAccept fail, invalid Issuer account.");
-
618 auto jv = credentials::accept(subject, issuer, credType);
-
619 jv[jss::Issuer] = to_string(xrpAccount());
-
620 env(jv, ter(temINVALID_ACCOUNT_ID));
-
621 env.close();
-
622 }
-
623
-
624 {
-
625 testcase(
-
626 "CredentialsAccept fail, invalid credentialType param.");
-
627 auto jv = credentials::accept(subject, issuer, "");
-
628 env(jv, ter(temMALFORMED));
-
629 }
-
630 }
+
626
+
627 void
+
+ +
629 {
+
630 using namespace jtx;
631
-
632 {
-
633 Env env{*this, features};
-
634
-
635 env.fund(drops(env.current()->fees().accountReserve(1)), issuer);
-
636 env.fund(drops(env.current()->fees().accountReserve(0)), subject);
-
637 env.close();
-
638
-
639 {
-
640 testcase("CredentialsAccept fail, not enough reserve.");
-
641 env(credentials::create(subject, issuer, credType));
-
642 env.close();
-
643
+
632 char const credType[] = "abcde";
+
633 Account const issuer{"issuer"};
+
634 Account const subject{"subject"};
+
635 Account const other{"other"};
+
636
+
637 {
+
638 Env env{*this, features};
+
639
+
640 env.fund(XRP(5000), subject, issuer);
+
641
+
642 {
+
643 testcase("CredentialsAccept fail, Credential doesn't exist.");
644 env(credentials::accept(subject, issuer, credType),
- +
646 env.close();
-
647
-
648 // check credential still present
-
649 auto const jle =
-
650 credentials::ledgerEntry(env, subject, issuer, credType);
-
651 BEAST_EXPECT(
-
652 jle.isObject() && jle.isMember(jss::result) &&
-
653 !jle[jss::result].isMember(jss::error) &&
-
654 jle[jss::result].isMember(jss::node) &&
-
655 jle[jss::result][jss::node].isMember("LedgerEntryType") &&
-
656 jle[jss::result][jss::node]["LedgerEntryType"] ==
-
657 jss::Credential &&
-
658 jle[jss::result][jss::node][jss::Issuer] ==
-
659 issuer.human() &&
-
660 jle[jss::result][jss::node][jss::Subject] ==
-
661 subject.human() &&
-
662 jle[jss::result][jss::node]["CredentialType"] ==
-
663 strHex(std::string_view(credType)));
-
664 }
-
665 }
-
666
-
667 {
-
668 using namespace jtx;
-
669 Env env{*this, features};
-
670
-
671 env.fund(XRP(5000), subject, issuer);
-
672 env.close();
-
673
-
674 {
-
675 env(credentials::create(subject, issuer, credType));
-
676 env.close();
-
677
-
678 testcase("CredentialsAccept fail, invalid fee.");
-
679 auto jv = credentials::accept(subject, issuer, credType);
-
680 jv[jss::Fee] = -1;
-
681 env(jv, ter(temBAD_FEE));
-
682
-
683 testcase("CredentialsAccept fail, lsfAccepted already set.");
-
684 env(credentials::accept(subject, issuer, credType));
-
685 env.close();
-
686 env(credentials::accept(subject, issuer, credType),
- -
688 env.close();
-
689
-
690 // check credential still present
-
691 auto const jle =
-
692 credentials::ledgerEntry(env, subject, issuer, credType);
-
693 BEAST_EXPECT(
-
694 jle.isObject() && jle.isMember(jss::result) &&
-
695 !jle[jss::result].isMember(jss::error) &&
-
696 jle[jss::result].isMember(jss::node) &&
-
697 jle[jss::result][jss::node].isMember("LedgerEntryType") &&
-
698 jle[jss::result][jss::node]["LedgerEntryType"] ==
-
699 jss::Credential &&
-
700 jle[jss::result][jss::node][jss::Issuer] ==
-
701 issuer.human() &&
-
702 jle[jss::result][jss::node][jss::Subject] ==
-
703 subject.human() &&
-
704 jle[jss::result][jss::node]["CredentialType"] ==
-
705 strHex(std::string_view(credType)));
-
706 }
-
707
-
708 {
-
709 char const credType2[] = "efghi";
+
647 }
+
648
+
649 {
+
650 testcase("CredentialsAccept fail, invalid Issuer account.");
+
651 auto jv = credentials::accept(subject, issuer, credType);
+
652 jv[jss::Issuer] = to_string(xrpAccount());
+
653 env(jv, ter(temINVALID_ACCOUNT_ID));
+
654 env.close();
+
655 }
+
656
+
657 {
+
658 testcase(
+
659 "CredentialsAccept fail, invalid credentialType param.");
+
660 auto jv = credentials::accept(subject, issuer, "");
+
661 env(jv, ter(temMALFORMED));
+
662 }
+
663 }
+
664
+
665 {
+
666 Env env{*this, features};
+
667
+
668 env.fund(drops(env.current()->fees().accountReserve(1)), issuer);
+
669 env.fund(drops(env.current()->fees().accountReserve(0)), subject);
+
670 env.close();
+
671
+
672 {
+
673 testcase("CredentialsAccept fail, not enough reserve.");
+
674 env(credentials::create(subject, issuer, credType));
+
675 env.close();
+
676
+
677 env(credentials::accept(subject, issuer, credType),
+ +
679 env.close();
+
680
+
681 // check credential still present
+
682 auto const jle =
+
683 credentials::ledgerEntry(env, subject, issuer, credType);
+
684 BEAST_EXPECT(
+
685 jle.isObject() && jle.isMember(jss::result) &&
+
686 !jle[jss::result].isMember(jss::error) &&
+
687 jle[jss::result].isMember(jss::node) &&
+
688 jle[jss::result][jss::node].isMember("LedgerEntryType") &&
+
689 jle[jss::result][jss::node]["LedgerEntryType"] ==
+
690 jss::Credential &&
+
691 jle[jss::result][jss::node][jss::Issuer] ==
+
692 issuer.human() &&
+
693 jle[jss::result][jss::node][jss::Subject] ==
+
694 subject.human() &&
+
695 jle[jss::result][jss::node]["CredentialType"] ==
+
696 strHex(std::string_view(credType)));
+
697 }
+
698 }
+
699
+
700 {
+
701 using namespace jtx;
+
702 Env env{*this, features};
+
703
+
704 env.fund(XRP(5000), subject, issuer);
+
705 env.close();
+
706
+
707 {
+
708 env(credentials::create(subject, issuer, credType));
+
709 env.close();
710
-
711 testcase("CredentialsAccept fail, expired credentials.");
-
712 auto jv = credentials::create(subject, issuer, credType2);
-
713 uint32_t const t = env.current()
-
714 ->info()
-
715 .parentCloseTime.time_since_epoch()
-
716 .count();
-
717 jv[sfExpiration.jsonName] = t;
-
718 env(jv);
-
719 env.close();
-
720
-
721 // credentials are expired now
-
722 env(credentials::accept(subject, issuer, credType2),
-
723 ter(tecEXPIRED));
-
724 env.close();
-
725
-
726 // check that expired credentials were deleted
-
727 auto const jDelCred =
-
728 credentials::ledgerEntry(env, subject, issuer, credType2);
-
729 BEAST_EXPECT(
-
730 jDelCred.isObject() && jDelCred.isMember(jss::result) &&
-
731 jDelCred[jss::result].isMember(jss::error) &&
-
732 jDelCred[jss::result][jss::error] == "entryNotFound");
-
733
-
734 BEAST_EXPECT(ownerCount(env, issuer) == 0);
-
735 BEAST_EXPECT(ownerCount(env, subject) == 1);
-
736 }
-
737 }
-
738
-
739 {
-
740 using namespace jtx;
-
741 Env env{*this, features};
-
742
-
743 env.fund(XRP(5000), issuer, subject, other);
-
744 env.close();
-
745
-
746 {
-
747 testcase("CredentialsAccept fail, issuer doesn't exist.");
-
748 auto jv = credentials::create(subject, issuer, credType);
-
749 env(jv);
-
750 env.close();
-
751
-
752 // delete issuer
-
753 int const delta = env.seq(issuer) + 255;
-
754 for (int i = 0; i < delta; ++i)
-
755 env.close();
-
756 auto const acctDelFee{drops(env.current()->fees().increment)};
-
757 env(acctdelete(issuer, other), fee(acctDelFee));
+
711 testcase("CredentialsAccept fail, invalid fee.");
+
712 auto jv = credentials::accept(subject, issuer, credType);
+
713 jv[jss::Fee] = -1;
+
714 env(jv, ter(temBAD_FEE));
+
715
+
716 testcase("CredentialsAccept fail, lsfAccepted already set.");
+
717 env(credentials::accept(subject, issuer, credType));
+
718 env.close();
+
719 env(credentials::accept(subject, issuer, credType),
+ +
721 env.close();
+
722
+
723 // check credential still present
+
724 auto const jle =
+
725 credentials::ledgerEntry(env, subject, issuer, credType);
+
726 BEAST_EXPECT(
+
727 jle.isObject() && jle.isMember(jss::result) &&
+
728 !jle[jss::result].isMember(jss::error) &&
+
729 jle[jss::result].isMember(jss::node) &&
+
730 jle[jss::result][jss::node].isMember("LedgerEntryType") &&
+
731 jle[jss::result][jss::node]["LedgerEntryType"] ==
+
732 jss::Credential &&
+
733 jle[jss::result][jss::node][jss::Issuer] ==
+
734 issuer.human() &&
+
735 jle[jss::result][jss::node][jss::Subject] ==
+
736 subject.human() &&
+
737 jle[jss::result][jss::node]["CredentialType"] ==
+
738 strHex(std::string_view(credType)));
+
739 }
+
740
+
741 {
+
742 char const credType2[] = "efghi";
+
743
+
744 testcase("CredentialsAccept fail, expired credentials.");
+
745 auto jv = credentials::create(subject, issuer, credType2);
+
746 uint32_t const t = env.current()
+
747 ->info()
+
748 .parentCloseTime.time_since_epoch()
+
749 .count();
+
750 jv[sfExpiration.jsonName] = t;
+
751 env(jv);
+
752 env.close();
+
753
+
754 // credentials are expired now
+
755 env(credentials::accept(subject, issuer, credType2),
+
756 ter(tecEXPIRED));
+
757 env.close();
758
-
759 // can't accept - no issuer account
-
760 jv = credentials::accept(subject, issuer, credType);
-
761 env(jv, ter(tecNO_ISSUER));
-
762 env.close();
-
763
-
764 // check that expired credentials were deleted
-
765 auto const jDelCred =
-
766 credentials::ledgerEntry(env, subject, issuer, credType);
-
767 BEAST_EXPECT(
-
768 jDelCred.isObject() && jDelCred.isMember(jss::result) &&
-
769 jDelCred[jss::result].isMember(jss::error) &&
-
770 jDelCred[jss::result][jss::error] == "entryNotFound");
-
771 }
-
772 }
-
773 }
-
-
774
-
775 void
-
- -
777 {
-
778 using namespace test::jtx;
-
779
-
780 char const credType[] = "abcde";
-
781 Account const issuer{"issuer"};
-
782 Account const subject{"subject"};
-
783 Account const other{"other"};
+
759 // check that expired credentials were deleted
+
760 auto const jDelCred =
+
761 credentials::ledgerEntry(env, subject, issuer, credType2);
+
762 BEAST_EXPECT(
+
763 jDelCred.isObject() && jDelCred.isMember(jss::result) &&
+
764 jDelCred[jss::result].isMember(jss::error) &&
+
765 jDelCred[jss::result][jss::error] == "entryNotFound");
+
766
+
767 BEAST_EXPECT(ownerCount(env, issuer) == 0);
+
768 BEAST_EXPECT(ownerCount(env, subject) == 1);
+
769 }
+
770 }
+
771
+
772 {
+
773 using namespace jtx;
+
774 Env env{*this, features};
+
775
+
776 env.fund(XRP(5000), issuer, subject, other);
+
777 env.close();
+
778
+
779 {
+
780 testcase("CredentialsAccept fail, issuer doesn't exist.");
+
781 auto jv = credentials::create(subject, issuer, credType);
+
782 env(jv);
+
783 env.close();
784
-
785 {
-
786 using namespace jtx;
-
787 Env env{*this, features};
-
788
-
789 env.fund(XRP(5000), subject, issuer, other);
-
790 env.close();
+
785 // delete issuer
+
786 int const delta = env.seq(issuer) + 255;
+
787 for (int i = 0; i < delta; ++i)
+
788 env.close();
+
789 auto const acctDelFee{drops(env.current()->fees().increment)};
+
790 env(acctdelete(issuer, other), fee(acctDelFee));
791
-
792 {
-
793 testcase("CredentialsDelete fail, no Credentials.");
-
794 env(credentials::deleteCred(subject, subject, issuer, credType),
- -
796 env.close();
-
797 }
-
798
-
799 {
-
800 testcase("CredentialsDelete fail, invalid Subject account.");
-
801 auto jv =
-
802 credentials::deleteCred(subject, subject, issuer, credType);
-
803 jv[jss::Subject] = to_string(xrpAccount());
-
804 env(jv, ter(temINVALID_ACCOUNT_ID));
-
805 env.close();
-
806 }
+
792 // can't accept - no issuer account
+
793 jv = credentials::accept(subject, issuer, credType);
+
794 env(jv, ter(tecNO_ISSUER));
+
795 env.close();
+
796
+
797 // check that expired credentials were deleted
+
798 auto const jDelCred =
+
799 credentials::ledgerEntry(env, subject, issuer, credType);
+
800 BEAST_EXPECT(
+
801 jDelCred.isObject() && jDelCred.isMember(jss::result) &&
+
802 jDelCred[jss::result].isMember(jss::error) &&
+
803 jDelCred[jss::result][jss::error] == "entryNotFound");
+
804 }
+
805 }
+
806 }
+
807
-
808 {
-
809 testcase("CredentialsDelete fail, invalid Issuer account.");
-
810 auto jv =
-
811 credentials::deleteCred(subject, subject, issuer, credType);
-
812 jv[jss::Issuer] = to_string(xrpAccount());
-
813 env(jv, ter(temINVALID_ACCOUNT_ID));
-
814 env.close();
-
815 }
-
816
-
817 {
-
818 testcase(
-
819 "CredentialsDelete fail, invalid credentialType param.");
-
820 auto jv = credentials::deleteCred(subject, subject, issuer, "");
-
821 env(jv, ter(temMALFORMED));
-
822 }
-
823
-
824 {
-
825 char const credType2[] = "fghij";
-
826
-
827 env(credentials::create(subject, issuer, credType2));
-
828 env.close();
-
829
-
830 // Other account can't delete credentials without expiration
-
831 env(credentials::deleteCred(other, subject, issuer, credType2),
-
832 ter(tecNO_PERMISSION));
-
833 env.close();
-
834
-
835 // check credential still present
-
836 auto const jle =
-
837 credentials::ledgerEntry(env, subject, issuer, credType2);
-
838 BEAST_EXPECT(
-
839 jle.isObject() && jle.isMember(jss::result) &&
-
840 !jle[jss::result].isMember(jss::error) &&
-
841 jle[jss::result].isMember(jss::node) &&
-
842 jle[jss::result][jss::node].isMember("LedgerEntryType") &&
-
843 jle[jss::result][jss::node]["LedgerEntryType"] ==
-
844 jss::Credential &&
-
845 jle[jss::result][jss::node][jss::Issuer] ==
-
846 issuer.human() &&
-
847 jle[jss::result][jss::node][jss::Subject] ==
-
848 subject.human() &&
-
849 jle[jss::result][jss::node]["CredentialType"] ==
-
850 strHex(std::string_view(credType2)));
-
851 }
-
852
-
853 {
-
854 testcase("CredentialsDelete fail, time not expired yet.");
-
855
-
856 auto jv = credentials::create(subject, issuer, credType);
-
857 // current time in ripple epoch + 1000s
-
858 uint32_t const t = env.current()
-
859 ->info()
-
860 .parentCloseTime.time_since_epoch()
-
861 .count() +
-
862 1000;
-
863 jv[sfExpiration.jsonName] = t;
-
864 env(jv);
-
865 env.close();
-
866
-
867 // Other account can't delete credentials that not expired
-
868 env(credentials::deleteCred(other, subject, issuer, credType),
-
869 ter(tecNO_PERMISSION));
-
870 env.close();
-
871
-
872 // check credential still present
-
873 auto const jle =
-
874 credentials::ledgerEntry(env, subject, issuer, credType);
-
875 BEAST_EXPECT(
-
876 jle.isObject() && jle.isMember(jss::result) &&
-
877 !jle[jss::result].isMember(jss::error) &&
-
878 jle[jss::result].isMember(jss::node) &&
-
879 jle[jss::result][jss::node].isMember("LedgerEntryType") &&
-
880 jle[jss::result][jss::node]["LedgerEntryType"] ==
-
881 jss::Credential &&
-
882 jle[jss::result][jss::node][jss::Issuer] ==
-
883 issuer.human() &&
-
884 jle[jss::result][jss::node][jss::Subject] ==
-
885 subject.human() &&
-
886 jle[jss::result][jss::node]["CredentialType"] ==
-
887 strHex(std::string_view(credType)));
-
888 }
-
889
-
890 {
-
891 testcase("CredentialsDelete fail, no Issuer and Subject.");
-
892
-
893 auto jv =
-
894 credentials::deleteCred(subject, subject, issuer, credType);
-
895 jv.removeMember(jss::Subject);
-
896 jv.removeMember(jss::Issuer);
-
897 env(jv, ter(temMALFORMED));
+
808 void
+
+ +
810 {
+
811 using namespace test::jtx;
+
812
+
813 char const credType[] = "abcde";
+
814 Account const issuer{"issuer"};
+
815 Account const subject{"subject"};
+
816 Account const other{"other"};
+
817
+
818 {
+
819 using namespace jtx;
+
820 Env env{*this, features};
+
821
+
822 env.fund(XRP(5000), subject, issuer, other);
+
823 env.close();
+
824
+
825 {
+
826 testcase("CredentialsDelete fail, no Credentials.");
+
827 env(credentials::deleteCred(subject, subject, issuer, credType),
+ +
829 env.close();
+
830 }
+
831
+
832 {
+
833 testcase("CredentialsDelete fail, invalid Subject account.");
+
834 auto jv =
+
835 credentials::deleteCred(subject, subject, issuer, credType);
+
836 jv[jss::Subject] = to_string(xrpAccount());
+
837 env(jv, ter(temINVALID_ACCOUNT_ID));
+
838 env.close();
+
839 }
+
840
+
841 {
+
842 testcase("CredentialsDelete fail, invalid Issuer account.");
+
843 auto jv =
+
844 credentials::deleteCred(subject, subject, issuer, credType);
+
845 jv[jss::Issuer] = to_string(xrpAccount());
+
846 env(jv, ter(temINVALID_ACCOUNT_ID));
+
847 env.close();
+
848 }
+
849
+
850 {
+
851 testcase(
+
852 "CredentialsDelete fail, invalid credentialType param.");
+
853 auto jv = credentials::deleteCred(subject, subject, issuer, "");
+
854 env(jv, ter(temMALFORMED));
+
855 }
+
856
+
857 {
+
858 char const credType2[] = "fghij";
+
859
+
860 env(credentials::create(subject, issuer, credType2));
+
861 env.close();
+
862
+
863 // Other account can't delete credentials without expiration
+
864 env(credentials::deleteCred(other, subject, issuer, credType2),
+ +
866 env.close();
+
867
+
868 // check credential still present
+
869 auto const jle =
+
870 credentials::ledgerEntry(env, subject, issuer, credType2);
+
871 BEAST_EXPECT(
+
872 jle.isObject() && jle.isMember(jss::result) &&
+
873 !jle[jss::result].isMember(jss::error) &&
+
874 jle[jss::result].isMember(jss::node) &&
+
875 jle[jss::result][jss::node].isMember("LedgerEntryType") &&
+
876 jle[jss::result][jss::node]["LedgerEntryType"] ==
+
877 jss::Credential &&
+
878 jle[jss::result][jss::node][jss::Issuer] ==
+
879 issuer.human() &&
+
880 jle[jss::result][jss::node][jss::Subject] ==
+
881 subject.human() &&
+
882 jle[jss::result][jss::node]["CredentialType"] ==
+
883 strHex(std::string_view(credType2)));
+
884 }
+
885
+
886 {
+
887 testcase("CredentialsDelete fail, time not expired yet.");
+
888
+
889 auto jv = credentials::create(subject, issuer, credType);
+
890 // current time in ripple epoch + 1000s
+
891 uint32_t const t = env.current()
+
892 ->info()
+
893 .parentCloseTime.time_since_epoch()
+
894 .count() +
+
895 1000;
+
896 jv[sfExpiration.jsonName] = t;
+
897 env(jv);
898 env.close();
-
899 }
-
900
-
901 {
-
902 testcase("CredentialsDelete fail, invalid fee.");
-
903
-
904 auto jv =
-
905 credentials::deleteCred(subject, subject, issuer, credType);
-
906 jv[jss::Fee] = -1;
-
907 env(jv, ter(temBAD_FEE));
-
908 env.close();
-
909 }
-
910
-
911 {
-
912 testcase("deleteSLE fail, bad SLE.");
- -
914 env.current().get(), ApplyFlags::tapNONE);
-
915 auto ter =
-
916 ripple::credentials::deleteSLE(*view, {}, env.journal);
-
917 BEAST_EXPECT(ter == tecNO_ENTRY);
-
918 }
-
919 }
-
920 }
+
899
+
900 // Other account can't delete credentials that not expired
+
901 env(credentials::deleteCred(other, subject, issuer, credType),
+ +
903 env.close();
+
904
+
905 // check credential still present
+
906 auto const jle =
+
907 credentials::ledgerEntry(env, subject, issuer, credType);
+
908 BEAST_EXPECT(
+
909 jle.isObject() && jle.isMember(jss::result) &&
+
910 !jle[jss::result].isMember(jss::error) &&
+
911 jle[jss::result].isMember(jss::node) &&
+
912 jle[jss::result][jss::node].isMember("LedgerEntryType") &&
+
913 jle[jss::result][jss::node]["LedgerEntryType"] ==
+
914 jss::Credential &&
+
915 jle[jss::result][jss::node][jss::Issuer] ==
+
916 issuer.human() &&
+
917 jle[jss::result][jss::node][jss::Subject] ==
+
918 subject.human() &&
+
919 jle[jss::result][jss::node]["CredentialType"] ==
+
920 strHex(std::string_view(credType)));
+
921 }
+
922
+
923 {
+
924 testcase("CredentialsDelete fail, no Issuer and Subject.");
+
925
+
926 auto jv =
+
927 credentials::deleteCred(subject, subject, issuer, credType);
+
928 jv.removeMember(jss::Subject);
+
929 jv.removeMember(jss::Issuer);
+
930 env(jv, ter(temMALFORMED));
+
931 env.close();
+
932 }
+
933
+
934 {
+
935 testcase("CredentialsDelete fail, invalid fee.");
+
936
+
937 auto jv =
+
938 credentials::deleteCred(subject, subject, issuer, credType);
+
939 jv[jss::Fee] = -1;
+
940 env(jv, ter(temBAD_FEE));
+
941 env.close();
+
942 }
+
943
+
944 {
+
945 testcase("deleteSLE fail, bad SLE.");
+ +
947 env.current().get(), ApplyFlags::tapNONE);
+
948 auto ter =
+
949 ripple::credentials::deleteSLE(*view, {}, env.journal);
+
950 BEAST_EXPECT(ter == tecNO_ENTRY);
+
951 }
+
952 }
+
953 }
-
921
-
922 void
-
- -
924 {
-
925 using namespace test::jtx;
-
926
-
927 char const credType[] = "abcde";
-
928 Account const issuer{"issuer"};
-
929 Account const subject{"subject"};
-
930
-
931 {
-
932 using namespace jtx;
-
933 Env env{*this, features};
-
934
-
935 env.fund(XRP(5000), subject, issuer);
-
936 env.close();
-
937
-
938 {
-
939 testcase("Credentials fail, Feature is not enabled.");
-
940 env(credentials::create(subject, issuer, credType),
- -
942 env(credentials::accept(subject, issuer, credType),
- -
944 env(credentials::deleteCred(subject, subject, issuer, credType),
- -
946 }
-
947 }
-
948 }
-
-
949
-
950 void
-
- -
952 {
-
953 using namespace test::jtx;
954
-
955 char const credType[] = "abcde";
-
956 Account const issuer{"issuer"};
-
957 Account const subject{"subject"};
-
958
-
959 {
-
960 using namespace jtx;
-
961 Env env{*this};
-
962
-
963 env.fund(XRP(5000), subject, issuer);
-
964 env.close();
-
965
-
966 env(credentials::create(subject, issuer, credType));
-
967 env.close();
-
968
-
969 env(credentials::accept(subject, issuer, credType));
-
970 env.close();
-
971
-
972 testcase("account_tx");
-
973
-
974 std::string txHash0, txHash1;
-
975 {
-
976 Json::Value params;
-
977 params[jss::account] = subject.human();
-
978 auto const jv = env.rpc(
-
979 "json", "account_tx", to_string(params))[jss::result];
-
980
-
981 BEAST_EXPECT(jv[jss::transactions].size() == 4);
-
982 auto const& tx0(jv[jss::transactions][0u][jss::tx]);
-
983 BEAST_EXPECT(
-
984 tx0[jss::TransactionType] == jss::CredentialAccept);
-
985 auto const& tx1(jv[jss::transactions][1u][jss::tx]);
-
986 BEAST_EXPECT(
-
987 tx1[jss::TransactionType] == jss::CredentialCreate);
-
988 txHash0 = tx0[jss::hash].asString();
-
989 txHash1 = tx1[jss::hash].asString();
-
990 }
+
955 void
+
+ +
957 {
+
958 using namespace test::jtx;
+
959
+
960 char const credType[] = "abcde";
+
961 Account const issuer{"issuer"};
+
962 Account const subject{"subject"};
+
963
+
964 {
+
965 using namespace jtx;
+
966 Env env{*this, features};
+
967
+
968 env.fund(XRP(5000), subject, issuer);
+
969 env.close();
+
970
+
971 {
+
972 testcase("Credentials fail, Feature is not enabled.");
+
973 env(credentials::create(subject, issuer, credType),
+ +
975 env(credentials::accept(subject, issuer, credType),
+ +
977 env(credentials::deleteCred(subject, subject, issuer, credType),
+ +
979 }
+
980 }
+
981 }
+
+
982
+
983 void
+
+ +
985 {
+
986 using namespace test::jtx;
+
987
+
988 char const credType[] = "abcde";
+
989 Account const issuer{"issuer"};
+
990 Account const subject{"subject"};
991
-
992 {
-
993 Json::Value params;
-
994 params[jss::account] = issuer.human();
-
995 auto const jv = env.rpc(
-
996 "json", "account_tx", to_string(params))[jss::result];
-
997
-
998 BEAST_EXPECT(jv[jss::transactions].size() == 4);
-
999 auto const& tx0(jv[jss::transactions][0u][jss::tx]);
-
1000 BEAST_EXPECT(
-
1001 tx0[jss::TransactionType] == jss::CredentialAccept);
-
1002 auto const& tx1(jv[jss::transactions][1u][jss::tx]);
-
1003 BEAST_EXPECT(
-
1004 tx1[jss::TransactionType] == jss::CredentialCreate);
-
1005
-
1006 BEAST_EXPECT(txHash0 == tx0[jss::hash].asString());
-
1007 BEAST_EXPECT(txHash1 == tx1[jss::hash].asString());
-
1008 }
-
1009
-
1010 testcase("account_objects");
-
1011 std::string objectIdx;
-
1012 {
-
1013 Json::Value params;
-
1014 params[jss::account] = subject.human();
-
1015 auto jv = env.rpc(
-
1016 "json", "account_objects", to_string(params))[jss::result];
-
1017
-
1018 BEAST_EXPECT(jv[jss::account_objects].size() == 1);
-
1019 auto const& object(jv[jss::account_objects][0u]);
-
1020
-
1021 BEAST_EXPECT(
-
1022 object["LedgerEntryType"].asString() == jss::Credential);
-
1023 objectIdx = object[jss::index].asString();
-
1024 }
-
1025
-
1026 {
-
1027 Json::Value params;
-
1028 params[jss::account] = issuer.human();
-
1029 auto jv = env.rpc(
-
1030 "json", "account_objects", to_string(params))[jss::result];
-
1031
-
1032 BEAST_EXPECT(jv[jss::account_objects].size() == 1);
-
1033 auto const& object(jv[jss::account_objects][0u]);
-
1034
-
1035 BEAST_EXPECT(
-
1036 object["LedgerEntryType"].asString() == jss::Credential);
-
1037 BEAST_EXPECT(objectIdx == object[jss::index].asString());
-
1038 }
-
1039 }
-
1040 }
-
-
1041
-
1042 void
-
- -
1044 {
-
1045 using namespace test::jtx;
-
1046
-
1047 bool const enabled = features[fixInvalidTxFlags];
-
1048 testcase(
-
1049 std::string("Test flag, fix ") +
-
1050 (enabled ? "enabled" : "disabled"));
-
1051
-
1052 char const credType[] = "abcde";
-
1053 Account const issuer{"issuer"};
-
1054 Account const subject{"subject"};
-
1055
-
1056 {
-
1057 using namespace jtx;
-
1058 Env env{*this, features};
-
1059
-
1060 env.fund(XRP(5000), subject, issuer);
-
1061 env.close();
-
1062
-
1063 {
-
1064 ter const expected(
-
1065 enabled ? TER(temINVALID_FLAG) : TER(tesSUCCESS));
-
1066 env(credentials::create(subject, issuer, credType),
- -
1068 expected);
-
1069 env(credentials::accept(subject, issuer, credType),
- -
1071 expected);
-
1072 env(credentials::deleteCred(subject, subject, issuer, credType),
- -
1074 expected);
-
1075 }
-
1076 }
-
1077 }
-
-
1078
-
1079 void
-
-
1080 run() override
-
1081 {
-
1082 using namespace test::jtx;
- - - - - - -
1089 testFeatureFailed(all - featureCredentials);
-
1090 testFlags(all - fixInvalidTxFlags);
-
1091 testFlags(all);
-
1092 testRPC();
-
1093 }
-
-
1094};
+
992 {
+
993 using namespace jtx;
+
994 Env env{*this};
+
995
+
996 env.fund(XRP(5000), subject, issuer);
+
997 env.close();
+
998
+
999 env(credentials::create(subject, issuer, credType));
+
1000 env.close();
+
1001
+
1002 env(credentials::accept(subject, issuer, credType));
+
1003 env.close();
+
1004
+
1005 testcase("account_tx");
+
1006
+
1007 std::string txHash0, txHash1;
+
1008 {
+
1009 Json::Value params;
+
1010 params[jss::account] = subject.human();
+
1011 auto const jv = env.rpc(
+
1012 "json", "account_tx", to_string(params))[jss::result];
+
1013
+
1014 BEAST_EXPECT(jv[jss::transactions].size() == 4);
+
1015 auto const& tx0(jv[jss::transactions][0u][jss::tx]);
+
1016 BEAST_EXPECT(
+
1017 tx0[jss::TransactionType] == jss::CredentialAccept);
+
1018 auto const& tx1(jv[jss::transactions][1u][jss::tx]);
+
1019 BEAST_EXPECT(
+
1020 tx1[jss::TransactionType] == jss::CredentialCreate);
+
1021 txHash0 = tx0[jss::hash].asString();
+
1022 txHash1 = tx1[jss::hash].asString();
+
1023 }
+
1024
+
1025 {
+
1026 Json::Value params;
+
1027 params[jss::account] = issuer.human();
+
1028 auto const jv = env.rpc(
+
1029 "json", "account_tx", to_string(params))[jss::result];
+
1030
+
1031 BEAST_EXPECT(jv[jss::transactions].size() == 4);
+
1032 auto const& tx0(jv[jss::transactions][0u][jss::tx]);
+
1033 BEAST_EXPECT(
+
1034 tx0[jss::TransactionType] == jss::CredentialAccept);
+
1035 auto const& tx1(jv[jss::transactions][1u][jss::tx]);
+
1036 BEAST_EXPECT(
+
1037 tx1[jss::TransactionType] == jss::CredentialCreate);
+
1038
+
1039 BEAST_EXPECT(txHash0 == tx0[jss::hash].asString());
+
1040 BEAST_EXPECT(txHash1 == tx1[jss::hash].asString());
+
1041 }
+
1042
+
1043 testcase("account_objects");
+
1044 std::string objectIdx;
+
1045 {
+
1046 Json::Value params;
+
1047 params[jss::account] = subject.human();
+
1048 auto jv = env.rpc(
+
1049 "json", "account_objects", to_string(params))[jss::result];
+
1050
+
1051 BEAST_EXPECT(jv[jss::account_objects].size() == 1);
+
1052 auto const& object(jv[jss::account_objects][0u]);
+
1053
+
1054 BEAST_EXPECT(
+
1055 object["LedgerEntryType"].asString() == jss::Credential);
+
1056 objectIdx = object[jss::index].asString();
+
1057 }
+
1058
+
1059 {
+
1060 Json::Value params;
+
1061 params[jss::account] = issuer.human();
+
1062 auto jv = env.rpc(
+
1063 "json", "account_objects", to_string(params))[jss::result];
+
1064
+
1065 BEAST_EXPECT(jv[jss::account_objects].size() == 1);
+
1066 auto const& object(jv[jss::account_objects][0u]);
+
1067
+
1068 BEAST_EXPECT(
+
1069 object["LedgerEntryType"].asString() == jss::Credential);
+
1070 BEAST_EXPECT(objectIdx == object[jss::index].asString());
+
1071 }
+
1072 }
+
1073 }
+
1074
+
1075 void
+
+ +
1077 {
+
1078 using namespace test::jtx;
+
1079
+
1080 bool const enabled = features[fixInvalidTxFlags];
+
1081 testcase(
+
1082 std::string("Test flag, fix ") +
+
1083 (enabled ? "enabled" : "disabled"));
+
1084
+
1085 char const credType[] = "abcde";
+
1086 Account const issuer{"issuer"};
+
1087 Account const subject{"subject"};
+
1088
+
1089 {
+
1090 using namespace jtx;
+
1091 Env env{*this, features};
+
1092
+
1093 env.fund(XRP(5000), subject, issuer);
+
1094 env.close();
1095
-
1096BEAST_DEFINE_TESTSUITE(Credentials, app, ripple);
-
1097
-
1098} // namespace test
-
1099} // namespace ripple
+
1096 {
+
1097 ter const expected(
+
1098 enabled ? TER(temINVALID_FLAG) : TER(tesSUCCESS));
+
1099 env(credentials::create(subject, issuer, credType),
+ +
1101 expected);
+
1102 env(credentials::accept(subject, issuer, credType),
+ +
1104 expected);
+
1105 env(credentials::deleteCred(subject, subject, issuer, credType),
+ +
1107 expected);
+
1108 }
+
1109 }
+
1110 }
+
+
1111
+
1112 void
+
+
1113 run() override
+
1114 {
+
1115 using namespace test::jtx;
+ + + + +
1120 testCreateFailed(all - fixDirectoryLimit);
+ + +
1123 testFeatureFailed(all - featureCredentials);
+
1124 testFlags(all - fixInvalidTxFlags);
+
1125 testFlags(all);
+
1126 testRPC();
+
1127 }
+
+
1128};
+
+
1129
+
1130BEAST_DEFINE_TESTSUITE(Credentials, app, ripple);
+
1131
+
1132} // namespace test
+
1133} // namespace ripple
std::string
std::string_view
Json::Value
Represents a JSON value.
Definition json_value.h:149
@@ -1212,14 +1246,21 @@ $(document).ready(function() { init_codefold(0); });
ripple::test::jtx::credentials::uri
Definition credentials.h:45
ripple::test::jtx::fee
Set the fee on a JTx.
Definition fee.h:37
ripple::test::jtx::ter
Set the expected result code for a JTx The test will fail if the code doesn't match.
Definition ter.h:35
+
ripple::test::jtx::ticket::use
Set a ticket sequence on a JTx.
Definition ticket.h:48
ripple::test::jtx::txflags
Set the flags on a JTx.
Definition txflags.h:31
+
std::uint32_t
std::is_same_v
T is_same_v
ripple::credentials::deleteSLE
TER deleteSLE(ApplyView &view, std::shared_ptr< SLE > const &sleCredential, beast::Journal j)
Definition CredentialHelpers.cpp:67
+
ripple::keylet::ownerDir
Keylet ownerDir(AccountID const &id) noexcept
The root page of an account's directory.
Definition Indexes.cpp:374
ripple::test::jtx::credentials::create
Json::Value create(jtx::Account const &subject, jtx::Account const &issuer, std::string_view credType)
Definition creds.cpp:32
ripple::test::jtx::credentials::accept
Json::Value accept(jtx::Account const &subject, jtx::Account const &issuer, std::string_view credType)
Definition creds.cpp:48
ripple::test::jtx::credentials::keylet
Keylet keylet(test::jtx::Account const &subject, test::jtx::Account const &issuer, std::string_view credType)
Definition credentials.h:34
ripple::test::jtx::credentials::deleteCred
Json::Value deleteCred(jtx::Account const &acc, jtx::Account const &subject, jtx::Account const &issuer, std::string_view credType)
Definition creds.cpp:62
ripple::test::jtx::credentials::ledgerEntry
Json::Value ledgerEntry(jtx::Env &env, jtx::Account const &subject, jtx::Account const &issuer, std::string_view credType)
Definition creds.cpp:78
+
ripple::test::jtx::directory::bumpLastPage
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
+
ripple::test::jtx::directory::maximumPageIndex
auto maximumPageIndex(Env const &env) -> std::uint64_t
Definition directory.h:70
+
ripple::test::jtx::directory::adjustOwnerNode
bool adjustOwnerNode(ApplyView &view, uint256 key, std::uint64_t page)
Implementation of adjust for the most common ledger entry, i.e.
Definition directory.cpp:130
+
ripple::test::jtx::ticket::create
Json::Value create(Account const &account, std::uint32_t count)
Create one of more tickets.
Definition ticket.cpp:31
ripple::test::jtx::ownerCount
std::uint32_t ownerCount(Env const &env, Account const &account)
Definition TestHelpers.cpp:54
ripple::test::jtx::drops
PrettyAmount drops(Integer i)
Returns an XRP PrettyAmount, which is trivially convertible to STAmount.
Definition src/test/jtx/amount.h:326
ripple::test::jtx::checkVL
bool checkVL(Slice const &result, std::string const &expected)
Definition TestHelpers.h:364
@@ -1229,22 +1270,24 @@ $(document).ready(function() { init_codefold(0); });
ripple::test::reserve
static XRPAmount reserve(jtx::Env &env, std::uint32_t count)
Definition DepositAuth_test.cpp:32
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:25
ripple::xrpAccount
AccountID const & xrpAccount()
Compute AccountID from public key.
Definition AccountID.cpp:178
-
ripple::maxCredentialURILength
std::size_t constexpr maxCredentialURILength
The maximum length of a URI inside a Credential.
Definition Protocol.h:100
+
ripple::maxCredentialURILength
std::size_t constexpr maxCredentialURILength
The maximum length of a URI inside a Credential.
Definition Protocol.h:103
ripple::tfSellNFToken
constexpr std::uint32_t const tfSellNFToken
Definition TxFlags.h:230
ripple::lsfAccepted
@ lsfAccepted
Definition LedgerFormats.h:204
ripple::tfPassive
constexpr std::uint32_t tfPassive
Definition TxFlags.h:98
ripple::TxSearched::all
@ all
ripple::strHex
std::string strHex(FwdIt begin, FwdIt end)
Definition strHex.h:30
-
ripple::maxCredentialTypeLength
std::size_t constexpr maxCredentialTypeLength
The maximum length of a CredentialType inside a Credential.
Definition Protocol.h:103
+
ripple::maxCredentialTypeLength
std::size_t constexpr maxCredentialTypeLength
The maximum length of a CredentialType inside a Credential.
Definition Protocol.h:106
ripple::tecNO_ENTRY
@ tecNO_ENTRY
Definition TER.h:306
ripple::tecNO_ISSUER
@ tecNO_ISSUER
Definition TER.h:299
ripple::tecNO_TARGET
@ tecNO_TARGET
Definition TER.h:304
+
ripple::tecDIR_FULL
@ tecDIR_FULL
Definition TER.h:287
ripple::tecDUPLICATE
@ tecDUPLICATE
Definition TER.h:315
ripple::tecNO_PERMISSION
@ tecNO_PERMISSION
Definition TER.h:305
ripple::tecINSUFFICIENT_RESERVE
@ tecINSUFFICIENT_RESERVE
Definition TER.h:307
ripple::tecEXPIRED
@ tecEXPIRED
Definition TER.h:314
ripple::tesSUCCESS
@ tesSUCCESS
Definition TER.h:244
ripple::to_string
std::string to_string(base_uint< Bits, Tag > const &a)
Definition base_uint.h:630
+
ripple::ReleaseStrongRefAction::noop
@ noop
ripple::tapNONE
@ tapNONE
Definition ApplyView.h:31
ripple::TER
TERSubset< CanCvtToTER > TER
Definition TER.h:645
ripple::tfTransferable
constexpr std::uint32_t const tfTransferable
Definition TxFlags.h:142
@@ -1256,14 +1299,14 @@ $(document).ready(function() { init_codefold(0); });
std::string_view::size
T size(T... args)
string_view
ripple::test::Credentials_test
Definition Credentials_test.cpp:37
-
ripple::test::Credentials_test::testAcceptFailed
void testAcceptFailed(FeatureBitset features)
Definition Credentials_test.cpp:595
+
ripple::test::Credentials_test::testAcceptFailed
void testAcceptFailed(FeatureBitset features)
Definition Credentials_test.cpp:628
ripple::test::Credentials_test::testSuccessful
void testSuccessful(FeatureBitset features)
Definition Credentials_test.cpp:39
-
ripple::test::Credentials_test::testDeleteFailed
void testDeleteFailed(FeatureBitset features)
Definition Credentials_test.cpp:776
-
ripple::test::Credentials_test::testFeatureFailed
void testFeatureFailed(FeatureBitset features)
Definition Credentials_test.cpp:923
-
ripple::test::Credentials_test::testRPC
void testRPC()
Definition Credentials_test.cpp:951
-
ripple::test::Credentials_test::testFlags
void testFlags(FeatureBitset features)
Definition Credentials_test.cpp:1043
+
ripple::test::Credentials_test::testDeleteFailed
void testDeleteFailed(FeatureBitset features)
Definition Credentials_test.cpp:809
+
ripple::test::Credentials_test::testFeatureFailed
void testFeatureFailed(FeatureBitset features)
Definition Credentials_test.cpp:956
+
ripple::test::Credentials_test::testRPC
void testRPC()
Definition Credentials_test.cpp:984
+
ripple::test::Credentials_test::testFlags
void testFlags(FeatureBitset features)
Definition Credentials_test.cpp:1076
ripple::test::Credentials_test::testCredentialsDelete
void testCredentialsDelete(FeatureBitset features)
Definition Credentials_test.cpp:188
-
ripple::test::Credentials_test::run
void run() override
Runs the suite.
Definition Credentials_test.cpp:1080
+
ripple::test::Credentials_test::run
void run() override
Runs the suite.
Definition Credentials_test.cpp:1113
ripple::test::Credentials_test::testCreateFailed
void testCreateFailed(FeatureBitset features)
Definition Credentials_test.cpp:437
diff --git a/DID_8cpp_source.html b/DID_8cpp_source.html index a76ef0837b..c70415363d 100644 --- a/DID_8cpp_source.html +++ b/DID_8cpp_source.html @@ -319,7 +319,7 @@ $(document).ready(function() { init_codefold(0); });
ripple::ApplyContext::tx
STTx const & tx
Definition ApplyContext.h:72
ripple::ApplyView
Writeable view to a ledger, for applying a transaction.
Definition ApplyView.h:143
ripple::ApplyView::update
virtual void update(std::shared_ptr< SLE > const &sle)=0
Indicate changes to a peeked SLE.
-
ripple::ApplyView::dirRemove
bool dirRemove(Keylet const &directory, std::uint64_t page, uint256 const &key, bool keepRoot)
Remove an entry from a directory.
Definition ApplyView.cpp:191
+
ripple::ApplyView::dirRemove
bool dirRemove(Keylet const &directory, std::uint64_t page, uint256 const &key, bool keepRoot)
Remove an entry from a directory.
Definition ApplyView.cpp:207
ripple::ApplyView::insert
virtual void insert(std::shared_ptr< SLE > const &sle)=0
Insert a new state SLE.
ripple::ApplyView::dirInsert
std::optional< std::uint64_t > dirInsert(Keylet const &directory, uint256 const &key, std::function< void(std::shared_ptr< SLE > const &)> const &describe)
Insert an entry to a directory.
Definition ApplyView.h:319
ripple::ApplyView::peek
virtual std::shared_ptr< SLE > peek(Keylet const &k)=0
Prepare to modify the SLE associated with key.
@@ -346,12 +346,12 @@ $(document).ready(function() { init_codefold(0); });
ripple::keylet::account
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition Indexes.cpp:184
ripple::keylet::ownerDir
Keylet ownerDir(AccountID const &id) noexcept
The root page of an account's directory.
Definition Indexes.cpp:374
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:25
-
ripple::maxDIDURILength
std::size_t constexpr maxDIDURILength
The maximum length of a URI inside a DID.
Definition Protocol.h:91
-
ripple::maxDIDAttestationLength
std::size_t constexpr maxDIDAttestationLength
The maximum length of an Attestation inside a DID.
Definition Protocol.h:94
+
ripple::maxDIDURILength
std::size_t constexpr maxDIDURILength
The maximum length of a URI inside a DID.
Definition Protocol.h:94
+
ripple::maxDIDAttestationLength
std::size_t constexpr maxDIDAttestationLength
The maximum length of an Attestation inside a DID.
Definition Protocol.h:97
ripple::adjustOwnerCount
void adjustOwnerCount(ApplyView &view, std::shared_ptr< SLE > const &sle, std::int32_t amount, beast::Journal j)
Adjust the owner count up or down.
Definition View.cpp:1032
ripple::addSLE
TER addSLE(ApplyContext &ctx, std::shared_ptr< SLE > const &sle, AccountID const &owner)
Definition DID.cpp:72
ripple::set
bool set(T &target, std::string const &name, Section const &section)
Set a value from a configuration Section If the named value is not found or doesn't parse as a T,...
Definition BasicConfig.h:315
-
ripple::maxDIDDocumentLength
std::size_t constexpr maxDIDDocumentLength
The maximum length of a Data element inside a DID.
Definition Protocol.h:88
+
ripple::maxDIDDocumentLength
std::size_t constexpr maxDIDDocumentLength
The maximum length of a Data element inside a DID.
Definition Protocol.h:91
ripple::describeOwnerDir
std::function< void(SLE::ref)> describeOwnerDir(AccountID const &account)
Definition View.cpp:1050
ripple::tefBAD_LEDGER
@ tefBAD_LEDGER
Definition TER.h:170
ripple::tefINTERNAL
@ tefINTERNAL
Definition TER.h:173
diff --git a/DelegateSet_8cpp_source.html b/DelegateSet_8cpp_source.html index b958c26381..be6ddb1df2 100644 --- a/DelegateSet_8cpp_source.html +++ b/DelegateSet_8cpp_source.html @@ -268,7 +268,7 @@ $(document).ready(function() { init_codefold(0); });
ripple::ApplyContext::tx
STTx const & tx
Definition ApplyContext.h:72
ripple::ApplyView
Writeable view to a ledger, for applying a transaction.
Definition ApplyView.h:143
ripple::ApplyView::update
virtual void update(std::shared_ptr< SLE > const &sle)=0
Indicate changes to a peeked SLE.
-
ripple::ApplyView::dirRemove
bool dirRemove(Keylet const &directory, std::uint64_t page, uint256 const &key, bool keepRoot)
Remove an entry from a directory.
Definition ApplyView.cpp:191
+
ripple::ApplyView::dirRemove
bool dirRemove(Keylet const &directory, std::uint64_t page, uint256 const &key, bool keepRoot)
Remove an entry from a directory.
Definition ApplyView.cpp:207
ripple::ApplyView::insert
virtual void insert(std::shared_ptr< SLE > const &sle)=0
Insert a new state SLE.
ripple::ApplyView::dirInsert
std::optional< std::uint64_t > dirInsert(Keylet const &directory, uint256 const &key, std::function< void(std::shared_ptr< SLE > const &)> const &describe)
Insert an entry to a directory.
Definition ApplyView.h:319
ripple::ApplyView::peek
virtual std::shared_ptr< SLE > peek(Keylet const &k)=0
Prepare to modify the SLE associated with key.
@@ -298,7 +298,7 @@ $(document).ready(function() { init_codefold(0); });
ripple::keylet::account
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition Indexes.cpp:184
ripple::keylet::ownerDir
Keylet ownerDir(AccountID const &id) noexcept
The root page of an account's directory.
Definition Indexes.cpp:374
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:25
-
ripple::permissionMaxSize
std::size_t constexpr permissionMaxSize
The maximum number of delegate permissions an account can grant.
Definition Protocol.h:176
+
ripple::permissionMaxSize
std::size_t constexpr permissionMaxSize
The maximum number of delegate permissions an account can grant.
Definition Protocol.h:179
ripple::adjustOwnerCount
void adjustOwnerCount(ApplyView &view, std::shared_ptr< SLE > const &sle, std::int32_t amount, beast::Journal j)
Adjust the owner count up or down.
Definition View.cpp:1032
ripple::describeOwnerDir
std::function< void(SLE::ref)> describeOwnerDir(AccountID const &account)
Definition View.cpp:1050
ripple::tefBAD_LEDGER
@ tefBAD_LEDGER
Definition TER.h:170
diff --git a/DeleteAccount_8cpp_source.html b/DeleteAccount_8cpp_source.html index e1f72a0bda..ef4390f7be 100644 --- a/DeleteAccount_8cpp_source.html +++ b/DeleteAccount_8cpp_source.html @@ -593,7 +593,7 @@ $(document).ready(function() { init_codefold(0); });
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:25
ripple::AccountID
base_uint< 160, detail::AccountIDTag > AccountID
A 160-bit unsigned that uniquely identifies an account.
Definition AccountID.h:48
ripple::toBase58
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
Definition AccountID.cpp:114
-
ripple::maxDeletableDirEntries
std::size_t constexpr maxDeletableDirEntries
The maximum number of owner directory entries for account to be deletable.
Definition Protocol.h:65
+
ripple::maxDeletableDirEntries
std::size_t constexpr maxDeletableDirEntries
The maximum number of owner directory entries for account to be deletable.
Definition Protocol.h:68
ripple::uint256
base_uint< 256 > uint256
Definition base_uint.h:558
ripple::removeSignersFromLedger
static TER removeSignersFromLedger(Application &app, ApplyView &view, Keylet const &accountKeylet, Keylet const &ownerDirKeylet, Keylet const &signerListKeylet, beast::Journal j)
Definition SetSignerList.cpp:196
ripple::lsfRequireDestTag
@ lsfRequireDestTag
Definition LedgerFormats.h:126
diff --git a/DeleteOracle_8cpp_source.html b/DeleteOracle_8cpp_source.html index 6b49f30246..154079a1ca 100644 --- a/DeleteOracle_8cpp_source.html +++ b/DeleteOracle_8cpp_source.html @@ -197,7 +197,7 @@ $(document).ready(function() { init_codefold(0); });
ripple::ApplyContext::view
ApplyView & view()
Definition ApplyContext.h:78
ripple::ApplyContext::tx
STTx const & tx
Definition ApplyContext.h:72
ripple::ApplyView
Writeable view to a ledger, for applying a transaction.
Definition ApplyView.h:143
-
ripple::ApplyView::dirRemove
bool dirRemove(Keylet const &directory, std::uint64_t page, uint256 const &key, bool keepRoot)
Remove an entry from a directory.
Definition ApplyView.cpp:191
+
ripple::ApplyView::dirRemove
bool dirRemove(Keylet const &directory, std::uint64_t page, uint256 const &key, bool keepRoot)
Remove an entry from a directory.
Definition ApplyView.cpp:207
ripple::ApplyView::peek
virtual std::shared_ptr< SLE > peek(Keylet const &k)=0
Prepare to modify the SLE associated with key.
ripple::ApplyView::erase
virtual void erase(std::shared_ptr< SLE > const &sle)=0
Remove a peeked SLE.
ripple::DeleteOracle::deleteOracle
static TER deleteOracle(ApplyView &view, std::shared_ptr< SLE > const &sle, AccountID const &account, beast::Journal j)
Definition DeleteOracle.cpp:60
diff --git a/DeliveredAmount_8h_source.html b/DeliveredAmount_8h_source.html index 7fdb0e21dd..abdb619cb2 100644 --- a/DeliveredAmount_8h_source.html +++ b/DeliveredAmount_8h_source.html @@ -163,7 +163,7 @@ $(document).ready(function() { init_codefold(0); });
ripple::RPC::getDeliveredAmount
std::optional< STAmount > getDeliveredAmount(RPC::Context const &context, std::shared_ptr< STTx const > const &serializedTx, TxMeta const &transactionMeta, LedgerIndex const &ledgerIndex)
Definition DeliveredAmount.cpp:155
ripple::RPC::insertDeliveredAmount
void insertDeliveredAmount(Json::Value &meta, ReadView const &, std::shared_ptr< STTx const > const &serializedTx, TxMeta const &)
Add a delivered_amount field to the meta input/output parameter.
Definition DeliveredAmount.cpp:103
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:25
-
ripple::LedgerIndex
std::uint32_t LedgerIndex
A ledger index.
Definition Protocol.h:136
+
ripple::LedgerIndex
std::uint32_t LedgerIndex
A ledger index.
Definition Protocol.h:139
std::optional
std::shared_ptr
diff --git a/DepositAuthorized_8cpp_source.html b/DepositAuthorized_8cpp_source.html index 3324d6a873..a950e29594 100644 --- a/DepositAuthorized_8cpp_source.html +++ b/DepositAuthorized_8cpp_source.html @@ -312,7 +312,7 @@ $(document).ready(function() { init_codefold(0); });
ripple::lsfAccepted
@ lsfAccepted
Definition LedgerFormats.h:204
ripple::rpcError
Json::Value rpcError(int iError)
Definition RPCErr.cpp:31
ripple::doDepositAuthorized
Json::Value doDepositAuthorized(RPC::JsonContext &context)
Definition DepositAuthorized.cpp:41
-
ripple::maxCredentialsArraySize
std::size_t constexpr maxCredentialsArraySize
The maximum number of credentials can be passed in array.
Definition Protocol.h:106
+
ripple::maxCredentialsArraySize
std::size_t constexpr maxCredentialsArraySize
The maximum number of credentials can be passed in array.
Definition Protocol.h:109
std::vector::push_back
T push_back(T... args)
std::vector::reserve
T reserve(T... args)
std::set
diff --git a/DepositAuthorized__test_8cpp_source.html b/DepositAuthorized__test_8cpp_source.html index c82cac7d0e..7ee45a152d 100644 --- a/DepositAuthorized__test_8cpp_source.html +++ b/DepositAuthorized__test_8cpp_source.html @@ -777,7 +777,7 @@ $(document).ready(function() { init_codefold(0); });
ripple::test::jtx::XRP
XRP_t const XRP
Converts to XRP Issue or STAmount.
Definition amount.cpp:111
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:25
ripple::asfDepositAuth
constexpr std::uint32_t asfDepositAuth
Definition TxFlags.h:85
-
ripple::maxCredentialsArraySize
std::size_t constexpr maxCredentialsArraySize
The maximum number of credentials can be passed in array.
Definition Protocol.h:106
+
ripple::maxCredentialsArraySize
std::size_t constexpr maxCredentialsArraySize
The maximum number of credentials can be passed in array.
Definition Protocol.h:109
ripple::authorized
static bool authorized(Port const &port, std::map< std::string, std::string > const &h)
Definition ServerHandler.cpp:85
std::vector::size
T size(T... args)
std::vector
diff --git a/DepositPreauth_8cpp_source.html b/DepositPreauth_8cpp_source.html index 298e602353..96b42df2e8 100644 --- a/DepositPreauth_8cpp_source.html +++ b/DepositPreauth_8cpp_source.html @@ -418,7 +418,7 @@ $(document).ready(function() { init_codefold(0); });
beast::Journal::warn
Stream warn() const
Definition Journal.h:340
ripple::ApplyContext::tx
STTx const & tx
Definition ApplyContext.h:72
ripple::ApplyView
Writeable view to a ledger, for applying a transaction.
Definition ApplyView.h:143
-
ripple::ApplyView::dirRemove
bool dirRemove(Keylet const &directory, std::uint64_t page, uint256 const &key, bool keepRoot)
Remove an entry from a directory.
Definition ApplyView.cpp:191
+
ripple::ApplyView::dirRemove
bool dirRemove(Keylet const &directory, std::uint64_t page, uint256 const &key, bool keepRoot)
Remove an entry from a directory.
Definition ApplyView.cpp:207
ripple::ApplyView::insert
virtual void insert(std::shared_ptr< SLE > const &sle)=0
Insert a new state SLE.
ripple::ApplyView::dirInsert
std::optional< std::uint64_t > dirInsert(Keylet const &directory, uint256 const &key, std::function< void(std::shared_ptr< SLE > const &)> const &describe)
Insert an entry to a directory.
Definition ApplyView.h:319
ripple::ApplyView::peek
virtual std::shared_ptr< SLE > peek(Keylet const &k)=0
Prepare to modify the SLE associated with key.
@@ -457,7 +457,7 @@ $(document).ready(function() { init_codefold(0); });
ripple::describeOwnerDir
std::function< void(SLE::ref)> describeOwnerDir(AccountID const &account)
Definition View.cpp:1050
ripple::tefBAD_LEDGER
@ tefBAD_LEDGER
Definition TER.h:170
ripple::tefINTERNAL
@ tefINTERNAL
Definition TER.h:173
-
ripple::maxCredentialsArraySize
std::size_t constexpr maxCredentialsArraySize
The maximum number of credentials can be passed in array.
Definition Protocol.h:106
+
ripple::maxCredentialsArraySize
std::size_t constexpr maxCredentialsArraySize
The maximum number of credentials can be passed in array.
Definition Protocol.h:109
ripple::tecNO_ENTRY
@ tecNO_ENTRY
Definition TER.h:306
ripple::tecNO_ISSUER
@ tecNO_ISSUER
Definition TER.h:299
ripple::tecNO_TARGET
@ tecNO_TARGET
Definition TER.h:304
diff --git a/Directory__test_8cpp_source.html b/Directory__test_8cpp_source.html index bb854294f7..c13c52869e 100644 --- a/Directory__test_8cpp_source.html +++ b/Directory__test_8cpp_source.html @@ -105,515 +105,608 @@ $(document).ready(function() { init_codefold(0); });
22#include <xrpl/ledger/Sandbox.h>
23#include <xrpl/protocol/Feature.h>
24#include <xrpl/protocol/Protocol.h>
-
25#include <xrpl/protocol/jss.h>
-
26
-
27#include <algorithm>
-
28
-
29namespace ripple {
-
30namespace test {
-
31
-
-
32struct Directory_test : public beast::unit_test::suite
-
33{
-
34 // Map [0-15576] into a unique 3 letter currency code
-
35 std::string
-
- -
37 {
-
38 // There are only 17576 possible combinations
-
39 BEAST_EXPECT(i < 17577);
-
40
-
41 std::string code;
+
25#include <xrpl/protocol/TER.h>
+
26#include <xrpl/protocol/jss.h>
+
27
+
28#include <algorithm>
+
29#include <limits>
+
30
+
31namespace ripple {
+
32namespace test {
+
33
+
+ +
35{
+
36 // Map [0-15576] into a unique 3 letter currency code
+ +
+ +
39 {
+
40 // There are only 17576 possible combinations
+
41 BEAST_EXPECT(i < 17577);
42
-
43 for (int j = 0; j != 3; ++j)
-
44 {
-
45 code.push_back('A' + (i % 26));
-
46 i /= 26;
-
47 }
-
48
-
49 return code;
-
50 }
+
43 std::string code;
+
44
+
45 for (int j = 0; j != 3; ++j)
+
46 {
+
47 code.push_back('A' + (i % 26));
+
48 i /= 26;
+
49 }
+
50
+
51 return code;
+
52 }
-
51
-
52 // Insert n empty pages, numbered [0, ... n - 1], in the
-
53 // specified directory:
-
54 void
-
- -
56 {
-
57 for (std::uint64_t i = 0; i < n; ++i)
-
58 {
-
59 auto p = std::make_shared<SLE>(keylet::page(base, i));
-
60
-
61 p->setFieldV256(sfIndexes, STVector256{});
+
53
+
54 // Insert n empty pages, numbered [0, ... n - 1], in the
+
55 // specified directory:
+
56 void
+
+ +
58 {
+
59 for (std::uint64_t i = 0; i < n; ++i)
+
60 {
+
61 auto p = std::make_shared<SLE>(keylet::page(base, i));
62
-
63 if (i + 1 == n)
-
64 p->setFieldU64(sfIndexNext, 0);
-
65 else
-
66 p->setFieldU64(sfIndexNext, i + 1);
-
67
-
68 if (i == 0)
-
69 p->setFieldU64(sfIndexPrevious, n - 1);
-
70 else
-
71 p->setFieldU64(sfIndexPrevious, i - 1);
-
72
-
73 sb.insert(p);
-
74 }
-
75 }
+
63 p->setFieldV256(sfIndexes, STVector256{});
+
64
+
65 if (i + 1 == n)
+
66 p->setFieldU64(sfIndexNext, 0);
+
67 else
+
68 p->setFieldU64(sfIndexNext, i + 1);
+
69
+
70 if (i == 0)
+
71 p->setFieldU64(sfIndexPrevious, n - 1);
+
72 else
+
73 p->setFieldU64(sfIndexPrevious, i - 1);
+
74
+
75 sb.insert(p);
+
76 }
+
77 }
-
76
-
77 void
-
- -
79 {
-
80 using namespace jtx;
-
81
-
82 auto gw = Account("gw");
-
83 auto USD = gw["USD"];
-
84 auto alice = Account("alice");
-
85 auto bob = Account("bob");
-
86
-
87 testcase("Directory Ordering (with 'SortedDirectories' amendment)");
+
78
+
79 void
+
+ +
81 {
+
82 using namespace jtx;
+
83
+
84 auto gw = Account("gw");
+
85 auto USD = gw["USD"];
+
86 auto alice = Account("alice");
+
87 auto bob = Account("bob");
88
-
89 Env env(*this);
-
90 env.fund(XRP(10000000), alice, gw);
-
91
-
92 std::uint32_t const firstOfferSeq{env.seq(alice)};
-
93 for (std::size_t i = 1; i <= 400; ++i)
-
94 env(offer(alice, USD(i), XRP(i)));
-
95 env.close();
-
96
-
97 // Check Alice's directory: it should contain one
-
98 // entry for each offer she added, and, within each
-
99 // page the entries should be in sorted order.
-
100 {
-
101 auto const view = env.closed();
-
102
-
103 std::uint64_t page = 0;
+
89 testcase("Directory Ordering (with 'SortedDirectories' amendment)");
+
90
+
91 Env env(*this);
+
92 env.fund(XRP(10000000), alice, gw);
+
93
+
94 std::uint32_t const firstOfferSeq{env.seq(alice)};
+
95 for (std::size_t i = 1; i <= 400; ++i)
+
96 env(offer(alice, USD(i), XRP(i)));
+
97 env.close();
+
98
+
99 // Check Alice's directory: it should contain one
+
100 // entry for each offer she added, and, within each
+
101 // page the entries should be in sorted order.
+
102 {
+
103 auto const view = env.closed();
104
-
105 do
-
106 {
-
107 auto p =
-
108 view->read(keylet::page(keylet::ownerDir(alice), page));
-
109
-
110 // Ensure that the entries in the page are sorted
-
111 auto const& v = p->getFieldV256(sfIndexes);
-
112 BEAST_EXPECT(std::is_sorted(v.begin(), v.end()));
-
113
-
114 // Ensure that the page contains the correct orders by
-
115 // calculating which sequence numbers belong here.
-
116 std::uint32_t const minSeq =
-
117 firstOfferSeq + (page * dirNodeMaxEntries);
-
118 std::uint32_t const maxSeq = minSeq + dirNodeMaxEntries;
-
119
-
120 for (auto const& e : v)
-
121 {
-
122 auto c = view->read(keylet::child(e));
-
123 BEAST_EXPECT(c);
-
124 BEAST_EXPECT(c->getFieldU32(sfSequence) >= minSeq);
-
125 BEAST_EXPECT(c->getFieldU32(sfSequence) < maxSeq);
-
126 }
-
127
-
128 page = p->getFieldU64(sfIndexNext);
-
129 } while (page != 0);
-
130 }
-
131
-
132 // Now check the orderbook: it should be in the order we placed
-
133 // the offers.
-
134 auto book = BookDirs(
-
135 *env.current(), Book({xrpIssue(), USD.issue(), std::nullopt}));
-
136 int count = 1;
-
137
-
138 for (auto const& offer : book)
-
139 {
-
140 count++;
-
141 BEAST_EXPECT(offer->getFieldAmount(sfTakerPays) == USD(count));
-
142 BEAST_EXPECT(offer->getFieldAmount(sfTakerGets) == XRP(count));
-
143 }
-
144 }
+
105 std::uint64_t page = 0;
+
106
+
107 do
+
108 {
+
109 auto p =
+
110 view->read(keylet::page(keylet::ownerDir(alice), page));
+
111
+
112 // Ensure that the entries in the page are sorted
+
113 auto const& v = p->getFieldV256(sfIndexes);
+
114 BEAST_EXPECT(std::is_sorted(v.begin(), v.end()));
+
115
+
116 // Ensure that the page contains the correct orders by
+
117 // calculating which sequence numbers belong here.
+
118 std::uint32_t const minSeq =
+
119 firstOfferSeq + (page * dirNodeMaxEntries);
+
120 std::uint32_t const maxSeq = minSeq + dirNodeMaxEntries;
+
121
+
122 for (auto const& e : v)
+
123 {
+
124 auto c = view->read(keylet::child(e));
+
125 BEAST_EXPECT(c);
+
126 BEAST_EXPECT(c->getFieldU32(sfSequence) >= minSeq);
+
127 BEAST_EXPECT(c->getFieldU32(sfSequence) < maxSeq);
+
128 }
+
129
+
130 page = p->getFieldU64(sfIndexNext);
+
131 } while (page != 0);
+
132 }
+
133
+
134 // Now check the orderbook: it should be in the order we placed
+
135 // the offers.
+
136 auto book = BookDirs(
+
137 *env.current(), Book({xrpIssue(), USD.issue(), std::nullopt}));
+
138 int count = 1;
+
139
+
140 for (auto const& offer : book)
+
141 {
+
142 count++;
+
143 BEAST_EXPECT(offer->getFieldAmount(sfTakerPays) == USD(count));
+
144 BEAST_EXPECT(offer->getFieldAmount(sfTakerGets) == XRP(count));
+
145 }
+
146 }
-
145
-
146 void
-
- -
148 {
-
149 testcase("dirIsEmpty");
-
150
-
151 using namespace jtx;
-
152 auto const alice = Account("alice");
-
153 auto const bob = Account("bob");
-
154 auto const charlie = Account("charlie");
-
155 auto const gw = Account("gw");
-
156
-
157 Env env(*this);
+
147
+
148 void
+
+ +
150 {
+
151 testcase("dirIsEmpty");
+
152
+
153 using namespace jtx;
+
154 auto const alice = Account("alice");
+
155 auto const bob = Account("bob");
+
156 auto const charlie = Account("charlie");
+
157 auto const gw = Account("gw");
158
-
159 env.fund(XRP(1000000), alice, charlie, gw);
-
160 env.close();
-
161
-
162 // alice should have an empty directory.
-
163 BEAST_EXPECT(dirIsEmpty(*env.closed(), keylet::ownerDir(alice)));
-
164
-
165 // Give alice a signer list, then there will be stuff in the directory.
-
166 env(signers(alice, 1, {{bob, 1}}));
-
167 env.close();
-
168 BEAST_EXPECT(!dirIsEmpty(*env.closed(), keylet::ownerDir(alice)));
-
169
-
170 env(signers(alice, jtx::none));
-
171 env.close();
-
172 BEAST_EXPECT(dirIsEmpty(*env.closed(), keylet::ownerDir(alice)));
-
173
-
174 std::vector<IOU> const currencies = [this, &gw]() {
- -
176
-
177 c.reserve((2 * dirNodeMaxEntries) + 3);
+
159 Env env(*this);
+
160
+
161 env.fund(XRP(1000000), alice, charlie, gw);
+
162 env.close();
+
163
+
164 // alice should have an empty directory.
+
165 BEAST_EXPECT(dirIsEmpty(*env.closed(), keylet::ownerDir(alice)));
+
166
+
167 // Give alice a signer list, then there will be stuff in the directory.
+
168 env(signers(alice, 1, {{bob, 1}}));
+
169 env.close();
+
170 BEAST_EXPECT(!dirIsEmpty(*env.closed(), keylet::ownerDir(alice)));
+
171
+
172 env(signers(alice, jtx::none));
+
173 env.close();
+
174 BEAST_EXPECT(dirIsEmpty(*env.closed(), keylet::ownerDir(alice)));
+
175
+
176 std::vector<IOU> const currencies = [this, &gw]() {
+
178
-
179 while (c.size() != c.capacity())
-
180 c.push_back(gw[currcode(c.size())]);
-
181
-
182 return c;
-
183 }();
-
184
-
185 // First, Alices creates a lot of trustlines, and then
-
186 // deletes them in a different order:
-
187 {
-
188 auto cl = currencies;
-
189
-
190 for (auto const& c : cl)
-
191 {
-
192 env(trust(alice, c(50)));
-
193 env.close();
-
194 }
-
195
-
196 BEAST_EXPECT(!dirIsEmpty(*env.closed(), keylet::ownerDir(alice)));
+
179 c.reserve((2 * dirNodeMaxEntries) + 3);
+
180
+
181 while (c.size() != c.capacity())
+
182 c.push_back(gw[currcode(c.size())]);
+
183
+
184 return c;
+
185 }();
+
186
+
187 // First, Alices creates a lot of trustlines, and then
+
188 // deletes them in a different order:
+
189 {
+
190 auto cl = currencies;
+
191
+
192 for (auto const& c : cl)
+
193 {
+
194 env(trust(alice, c(50)));
+
195 env.close();
+
196 }
197
-
198 std::shuffle(cl.begin(), cl.end(), default_prng());
+
198 BEAST_EXPECT(!dirIsEmpty(*env.closed(), keylet::ownerDir(alice)));
199
-
200 for (auto const& c : cl)
-
201 {
-
202 env(trust(alice, c(0)));
-
203 env.close();
-
204 }
-
205
-
206 BEAST_EXPECT(dirIsEmpty(*env.closed(), keylet::ownerDir(alice)));
-
207 }
-
208
-
209 // Now, Alice creates offers to buy currency, creating
-
210 // implicit trust lines.
-
211 {
-
212 auto cl = currencies;
-
213
-
214 BEAST_EXPECT(dirIsEmpty(*env.closed(), keylet::ownerDir(alice)));
+
200 std::shuffle(cl.begin(), cl.end(), default_prng());
+
201
+
202 for (auto const& c : cl)
+
203 {
+
204 env(trust(alice, c(0)));
+
205 env.close();
+
206 }
+
207
+
208 BEAST_EXPECT(dirIsEmpty(*env.closed(), keylet::ownerDir(alice)));
+
209 }
+
210
+
211 // Now, Alice creates offers to buy currency, creating
+
212 // implicit trust lines.
+
213 {
+
214 auto cl = currencies;
215
-
216 for (auto c : currencies)
-
217 {
-
218 env(trust(charlie, c(50)));
-
219 env.close();
-
220 env(pay(gw, charlie, c(50)));
+
216 BEAST_EXPECT(dirIsEmpty(*env.closed(), keylet::ownerDir(alice)));
+
217
+
218 for (auto c : currencies)
+
219 {
+
220 env(trust(charlie, c(50)));
221 env.close();
-
222 env(offer(alice, c(50), XRP(50)));
+
222 env(pay(gw, charlie, c(50)));
223 env.close();
-
224 }
-
225
-
226 BEAST_EXPECT(!dirIsEmpty(*env.closed(), keylet::ownerDir(alice)));
+
224 env(offer(alice, c(50), XRP(50)));
+
225 env.close();
+
226 }
227
-
228 // Now fill the offers in a random order. Offer
-
229 // entries will drop, and be replaced by trust
-
230 // lines that are implicitly created.
-
231 std::shuffle(cl.begin(), cl.end(), default_prng());
-
232
-
233 for (auto const& c : cl)
-
234 {
-
235 env(offer(charlie, XRP(50), c(50)));
-
236 env.close();
-
237 }
-
238 BEAST_EXPECT(!dirIsEmpty(*env.closed(), keylet::ownerDir(alice)));
-
239 // Finally, Alice now sends the funds back to
-
240 // Charlie. The implicitly created trust lines
-
241 // should drop away:
-
242 std::shuffle(cl.begin(), cl.end(), default_prng());
-
243
-
244 for (auto const& c : cl)
-
245 {
-
246 env(pay(alice, charlie, c(50)));
-
247 env.close();
-
248 }
-
249
-
250 BEAST_EXPECT(dirIsEmpty(*env.closed(), keylet::ownerDir(alice)));
-
251 }
-
252 }
+
228 BEAST_EXPECT(!dirIsEmpty(*env.closed(), keylet::ownerDir(alice)));
+
229
+
230 // Now fill the offers in a random order. Offer
+
231 // entries will drop, and be replaced by trust
+
232 // lines that are implicitly created.
+
233 std::shuffle(cl.begin(), cl.end(), default_prng());
+
234
+
235 for (auto const& c : cl)
+
236 {
+
237 env(offer(charlie, XRP(50), c(50)));
+
238 env.close();
+
239 }
+
240 BEAST_EXPECT(!dirIsEmpty(*env.closed(), keylet::ownerDir(alice)));
+
241 // Finally, Alice now sends the funds back to
+
242 // Charlie. The implicitly created trust lines
+
243 // should drop away:
+
244 std::shuffle(cl.begin(), cl.end(), default_prng());
+
245
+
246 for (auto const& c : cl)
+
247 {
+
248 env(pay(alice, charlie, c(50)));
+
249 env.close();
+
250 }
+
251
+
252 BEAST_EXPECT(dirIsEmpty(*env.closed(), keylet::ownerDir(alice)));
+
253 }
+
254 }
-
253
-
254 void
-
- -
256 {
-
257 testcase("RIPD-1353 Empty Offer Directories");
-
258
-
259 using namespace jtx;
-
260 Env env(*this);
-
261
-
262 auto const gw = Account{"gateway"};
-
263 auto const alice = Account{"alice"};
-
264 auto const USD = gw["USD"];
-
265
-
266 env.fund(XRP(10000), alice, gw);
-
267 env.close();
-
268 env.trust(USD(1000), alice);
-
269 env(pay(gw, alice, USD(1000)));
-
270
-
271 auto const firstOfferSeq = env.seq(alice);
+
255
+
256 void
+
+ +
258 {
+
259 testcase("RIPD-1353 Empty Offer Directories");
+
260
+
261 using namespace jtx;
+
262 Env env(*this);
+
263
+
264 auto const gw = Account{"gateway"};
+
265 auto const alice = Account{"alice"};
+
266 auto const USD = gw["USD"];
+
267
+
268 env.fund(XRP(10000), alice, gw);
+
269 env.close();
+
270 env.trust(USD(1000), alice);
+
271 env(pay(gw, alice, USD(1000)));
272
-
273 // Fill up three pages of offers
-
274 for (int i = 0; i < 3; ++i)
-
275 for (int j = 0; j < dirNodeMaxEntries; ++j)
-
276 env(offer(alice, XRP(1), USD(1)));
-
277 env.close();
-
278
-
279 // remove all the offers. Remove the middle page last
-
280 for (auto page : {0, 2, 1})
-
281 {
-
282 for (int i = 0; i < dirNodeMaxEntries; ++i)
-
283 {
-
284 env(offer_cancel(
-
285 alice, firstOfferSeq + page * dirNodeMaxEntries + i));
-
286 env.close();
-
287 }
-
288 }
-
289
-
290 // All the offers have been cancelled, so the book
-
291 // should have no entries and be empty:
-
292 {
-
293 Sandbox sb(env.closed().get(), tapNONE);
-
294 uint256 const bookBase =
-
295 getBookBase({xrpIssue(), USD.issue(), std::nullopt});
-
296
-
297 BEAST_EXPECT(dirIsEmpty(sb, keylet::page(bookBase)));
-
298 BEAST_EXPECT(!sb.succ(bookBase, getQualityNext(bookBase)));
-
299 }
-
300
-
301 // Alice returns the USD she has to the gateway
-
302 // and removes her trust line. Her owner directory
-
303 // should now be empty:
-
304 {
-
305 env.trust(USD(0), alice);
-
306 env(pay(alice, gw, alice["USD"](1000)));
-
307 env.close();
-
308 BEAST_EXPECT(dirIsEmpty(*env.closed(), keylet::ownerDir(alice)));
-
309 }
-
310 }
+
273 auto const firstOfferSeq = env.seq(alice);
+
274
+
275 // Fill up three pages of offers
+
276 for (int i = 0; i < 3; ++i)
+
277 for (int j = 0; j < dirNodeMaxEntries; ++j)
+
278 env(offer(alice, XRP(1), USD(1)));
+
279 env.close();
+
280
+
281 // remove all the offers. Remove the middle page last
+
282 for (auto page : {0, 2, 1})
+
283 {
+
284 for (int i = 0; i < dirNodeMaxEntries; ++i)
+
285 {
+
286 env(offer_cancel(
+
287 alice, firstOfferSeq + page * dirNodeMaxEntries + i));
+
288 env.close();
+
289 }
+
290 }
+
291
+
292 // All the offers have been cancelled, so the book
+
293 // should have no entries and be empty:
+
294 {
+
295 Sandbox sb(env.closed().get(), tapNONE);
+
296 uint256 const bookBase =
+
297 getBookBase({xrpIssue(), USD.issue(), std::nullopt});
+
298
+
299 BEAST_EXPECT(dirIsEmpty(sb, keylet::page(bookBase)));
+
300 BEAST_EXPECT(!sb.succ(bookBase, getQualityNext(bookBase)));
+
301 }
+
302
+
303 // Alice returns the USD she has to the gateway
+
304 // and removes her trust line. Her owner directory
+
305 // should now be empty:
+
306 {
+
307 env.trust(USD(0), alice);
+
308 env(pay(alice, gw, alice["USD"](1000)));
+
309 env.close();
+
310 BEAST_EXPECT(dirIsEmpty(*env.closed(), keylet::ownerDir(alice)));
+
311 }
+
312 }
-
311
-
312 void
-
- -
314 {
-
315 testcase("Empty Chain on Delete");
-
316
-
317 using namespace jtx;
-
318 Env env(*this);
-
319
-
320 auto const gw = Account{"gateway"};
-
321 auto const alice = Account{"alice"};
-
322 auto const USD = gw["USD"];
-
323
-
324 env.fund(XRP(10000), alice);
-
325 env.close();
-
326
-
327 constexpr uint256 base(
-
328 "fb71c9aa3310141da4b01d6c744a98286af2d72ab5448d5adc0910ca0c910880");
-
329
-
330 constexpr uint256 item(
-
331 "bad0f021aa3b2f6754a8fe82a5779730aa0bbbab82f17201ef24900efc2c7312");
-
332
-
333 {
-
334 // Create a chain of three pages:
-
335 Sandbox sb(env.closed().get(), tapNONE);
-
336 makePages(sb, base, 3);
-
337
-
338 // Insert an item in the middle page:
-
339 {
-
340 auto p = sb.peek(keylet::page(base, 1));
-
341 BEAST_EXPECT(p);
-
342
-
343 STVector256 v;
-
344 v.push_back(item);
-
345 p->setFieldV256(sfIndexes, v);
-
346 sb.update(p);
-
347 }
-
348
-
349 // Now, try to delete the item from the middle
-
350 // page. This should cause all pages to be deleted:
-
351 BEAST_EXPECT(sb.dirRemove(
-
352 keylet::page(base, 0), 1, keylet::unchecked(item), false));
-
353 BEAST_EXPECT(!sb.peek(keylet::page(base, 2)));
-
354 BEAST_EXPECT(!sb.peek(keylet::page(base, 1)));
-
355 BEAST_EXPECT(!sb.peek(keylet::page(base, 0)));
-
356 }
-
357
-
358 {
-
359 // Create a chain of four pages:
-
360 Sandbox sb(env.closed().get(), tapNONE);
-
361 makePages(sb, base, 4);
-
362
-
363 // Now add items on pages 1 and 2:
-
364 {
-
365 auto p1 = sb.peek(keylet::page(base, 1));
-
366 BEAST_EXPECT(p1);
-
367
-
368 STVector256 v1;
-
369 v1.push_back(~item);
-
370 p1->setFieldV256(sfIndexes, v1);
-
371 sb.update(p1);
-
372
-
373 auto p2 = sb.peek(keylet::page(base, 2));
-
374 BEAST_EXPECT(p2);
-
375
-
376 STVector256 v2;
-
377 v2.push_back(item);
-
378 p2->setFieldV256(sfIndexes, v2);
-
379 sb.update(p2);
-
380 }
-
381
-
382 // Now, try to delete the item from page 2.
-
383 // This should cause pages 2 and 3 to be
-
384 // deleted:
-
385 BEAST_EXPECT(sb.dirRemove(
-
386 keylet::page(base, 0), 2, keylet::unchecked(item), false));
-
387 BEAST_EXPECT(!sb.peek(keylet::page(base, 3)));
-
388 BEAST_EXPECT(!sb.peek(keylet::page(base, 2)));
-
389
-
390 auto p1 = sb.peek(keylet::page(base, 1));
-
391 BEAST_EXPECT(p1);
-
392 BEAST_EXPECT(p1->getFieldU64(sfIndexNext) == 0);
-
393 BEAST_EXPECT(p1->getFieldU64(sfIndexPrevious) == 0);
-
394
-
395 auto p0 = sb.peek(keylet::page(base, 0));
-
396 BEAST_EXPECT(p0);
-
397 BEAST_EXPECT(p0->getFieldU64(sfIndexNext) == 1);
-
398 BEAST_EXPECT(p0->getFieldU64(sfIndexPrevious) == 1);
-
399 }
-
400 }
+
313
+
314 void
+
+ +
316 {
+
317 testcase("Empty Chain on Delete");
+
318
+
319 using namespace jtx;
+
320 Env env(*this);
+
321
+
322 auto const gw = Account{"gateway"};
+
323 auto const alice = Account{"alice"};
+
324 auto const USD = gw["USD"];
+
325
+
326 env.fund(XRP(10000), alice);
+
327 env.close();
+
328
+
329 constexpr uint256 base(
+
330 "fb71c9aa3310141da4b01d6c744a98286af2d72ab5448d5adc0910ca0c910880");
+
331
+
332 constexpr uint256 item(
+
333 "bad0f021aa3b2f6754a8fe82a5779730aa0bbbab82f17201ef24900efc2c7312");
+
334
+
335 {
+
336 // Create a chain of three pages:
+
337 Sandbox sb(env.closed().get(), tapNONE);
+
338 makePages(sb, base, 3);
+
339
+
340 // Insert an item in the middle page:
+
341 {
+
342 auto p = sb.peek(keylet::page(base, 1));
+
343 BEAST_EXPECT(p);
+
344
+
345 STVector256 v;
+
346 v.push_back(item);
+
347 p->setFieldV256(sfIndexes, v);
+
348 sb.update(p);
+
349 }
+
350
+
351 // Now, try to delete the item from the middle
+
352 // page. This should cause all pages to be deleted:
+
353 BEAST_EXPECT(sb.dirRemove(
+
354 keylet::page(base, 0), 1, keylet::unchecked(item), false));
+
355 BEAST_EXPECT(!sb.peek(keylet::page(base, 2)));
+
356 BEAST_EXPECT(!sb.peek(keylet::page(base, 1)));
+
357 BEAST_EXPECT(!sb.peek(keylet::page(base, 0)));
+
358 }
+
359
+
360 {
+
361 // Create a chain of four pages:
+
362 Sandbox sb(env.closed().get(), tapNONE);
+
363 makePages(sb, base, 4);
+
364
+
365 // Now add items on pages 1 and 2:
+
366 {
+
367 auto p1 = sb.peek(keylet::page(base, 1));
+
368 BEAST_EXPECT(p1);
+
369
+
370 STVector256 v1;
+
371 v1.push_back(~item);
+
372 p1->setFieldV256(sfIndexes, v1);
+
373 sb.update(p1);
+
374
+
375 auto p2 = sb.peek(keylet::page(base, 2));
+
376 BEAST_EXPECT(p2);
+
377
+
378 STVector256 v2;
+
379 v2.push_back(item);
+
380 p2->setFieldV256(sfIndexes, v2);
+
381 sb.update(p2);
+
382 }
+
383
+
384 // Now, try to delete the item from page 2.
+
385 // This should cause pages 2 and 3 to be
+
386 // deleted:
+
387 BEAST_EXPECT(sb.dirRemove(
+
388 keylet::page(base, 0), 2, keylet::unchecked(item), false));
+
389 BEAST_EXPECT(!sb.peek(keylet::page(base, 3)));
+
390 BEAST_EXPECT(!sb.peek(keylet::page(base, 2)));
+
391
+
392 auto p1 = sb.peek(keylet::page(base, 1));
+
393 BEAST_EXPECT(p1);
+
394 BEAST_EXPECT(p1->getFieldU64(sfIndexNext) == 0);
+
395 BEAST_EXPECT(p1->getFieldU64(sfIndexPrevious) == 0);
+
396
+
397 auto p0 = sb.peek(keylet::page(base, 0));
+
398 BEAST_EXPECT(p0);
+
399 BEAST_EXPECT(p0->getFieldU64(sfIndexNext) == 1);
+
400 BEAST_EXPECT(p0->getFieldU64(sfIndexPrevious) == 1);
+
401 }
+
402 }
-
401
-
402 void
-
- -
404 {
-
405 testcase("fixPreviousTxnID");
-
406 using namespace jtx;
-
407
-
408 auto const gw = Account{"gateway"};
-
409 auto const alice = Account{"alice"};
-
410 auto const USD = gw["USD"];
-
411
-
412 auto ledger_data = [this](Env& env) {
-
413 Json::Value params;
-
414 params[jss::type] = jss::directory;
-
415 params[jss::ledger_index] = "validated";
-
416 auto const result =
-
417 env.rpc("json", "ledger_data", to_string(params))[jss::result];
-
418 BEAST_EXPECT(!result.isMember(jss::marker));
-
419 return result;
-
420 };
-
421
-
422 // fixPreviousTxnID is disabled.
-
423 Env env(*this, testable_amendments() - fixPreviousTxnID);
-
424 env.fund(XRP(10000), alice, gw);
-
425 env.close();
-
426 env.trust(USD(1000), alice);
-
427 env(pay(gw, alice, USD(1000)));
-
428 env.close();
-
429
-
430 {
-
431 auto const jrr = ledger_data(env);
-
432 auto const& jstate = jrr[jss::state];
-
433 BEAST_EXPECTS(checkArraySize(jstate, 2), jrr.toStyledString());
-
434 for (auto const& directory : jstate)
-
435 {
-
436 BEAST_EXPECT(
-
437 directory["LedgerEntryType"] ==
-
438 jss::DirectoryNode); // sanity check
-
439 // The PreviousTxnID and PreviousTxnLgrSeq fields should not be
-
440 // on the DirectoryNode object when the amendment is disabled
-
441 BEAST_EXPECT(!directory.isMember("PreviousTxnID"));
-
442 BEAST_EXPECT(!directory.isMember("PreviousTxnLgrSeq"));
-
443 }
-
444 }
-
445
-
446 // Now enable the amendment so the directory node is updated.
-
447 env.enableFeature(fixPreviousTxnID);
-
448 env.close();
-
449
-
450 // Make sure the `PreviousTxnID` and `PreviousTxnLgrSeq` fields now
-
451 // exist
-
452 env(offer(alice, XRP(1), USD(1)));
-
453 auto const txID = to_string(env.tx()->getTransactionID());
-
454 auto const ledgerSeq = env.current()->info().seq;
-
455 env.close();
-
456 // Make sure the fields only exist if the object is touched
-
457 env(noop(gw));
-
458 env.close();
-
459
-
460 {
-
461 auto const jrr = ledger_data(env);
-
462 auto const& jstate = jrr[jss::state];
-
463 BEAST_EXPECTS(checkArraySize(jstate, 3), jrr.toStyledString());
-
464 for (auto const& directory : jstate)
-
465 {
-
466 BEAST_EXPECT(
-
467 directory["LedgerEntryType"] ==
-
468 jss::DirectoryNode); // sanity check
-
469 if (directory[jss::Owner] == gw.human())
-
470 {
-
471 // gw's directory did not get touched, so it
-
472 // should not have those fields populated
-
473 BEAST_EXPECT(!directory.isMember("PreviousTxnID"));
-
474 BEAST_EXPECT(!directory.isMember("PreviousTxnLgrSeq"));
-
475 }
-
476 else
-
477 {
-
478 // All of the other directories, including the order
-
479 // book, did get touched, so they should have those
-
480 // fields
-
481 BEAST_EXPECT(
-
482 directory.isMember("PreviousTxnID") &&
-
483 directory["PreviousTxnID"].asString() == txID);
-
484 BEAST_EXPECT(
-
485 directory.isMember("PreviousTxnLgrSeq") &&
-
486 directory["PreviousTxnLgrSeq"].asUInt() == ledgerSeq);
-
487 }
-
488 }
-
489 }
-
490 }
-
-
491
-
492 void
-
-
493 run() override
-
494 {
- - -
497 testRipd1353();
- - -
500 }
-
-
501};
+
403
+
404 void
+
+ +
406 {
+
407 testcase("fixPreviousTxnID");
+
408 using namespace jtx;
+
409
+
410 auto const gw = Account{"gateway"};
+
411 auto const alice = Account{"alice"};
+
412 auto const USD = gw["USD"];
+
413
+
414 auto ledger_data = [this](Env& env) {
+
415 Json::Value params;
+
416 params[jss::type] = jss::directory;
+
417 params[jss::ledger_index] = "validated";
+
418 auto const result =
+
419 env.rpc("json", "ledger_data", to_string(params))[jss::result];
+
420 BEAST_EXPECT(!result.isMember(jss::marker));
+
421 return result;
+
422 };
+
423
+
424 // fixPreviousTxnID is disabled.
+
425 Env env(*this, testable_amendments() - fixPreviousTxnID);
+
426 env.fund(XRP(10000), alice, gw);
+
427 env.close();
+
428 env.trust(USD(1000), alice);
+
429 env(pay(gw, alice, USD(1000)));
+
430 env.close();
+
431
+
432 {
+
433 auto const jrr = ledger_data(env);
+
434 auto const& jstate = jrr[jss::state];
+
435 BEAST_EXPECTS(checkArraySize(jstate, 2), jrr.toStyledString());
+
436 for (auto const& directory : jstate)
+
437 {
+
438 BEAST_EXPECT(
+
439 directory["LedgerEntryType"] ==
+
440 jss::DirectoryNode); // sanity check
+
441 // The PreviousTxnID and PreviousTxnLgrSeq fields should not be
+
442 // on the DirectoryNode object when the amendment is disabled
+
443 BEAST_EXPECT(!directory.isMember("PreviousTxnID"));
+
444 BEAST_EXPECT(!directory.isMember("PreviousTxnLgrSeq"));
+
445 }
+
446 }
+
447
+
448 // Now enable the amendment so the directory node is updated.
+
449 env.enableFeature(fixPreviousTxnID);
+
450 env.close();
+
451
+
452 // Make sure the `PreviousTxnID` and `PreviousTxnLgrSeq` fields now
+
453 // exist
+
454 env(offer(alice, XRP(1), USD(1)));
+
455 auto const txID = to_string(env.tx()->getTransactionID());
+
456 auto const ledgerSeq = env.current()->info().seq;
+
457 env.close();
+
458 // Make sure the fields only exist if the object is touched
+
459 env(noop(gw));
+
460 env.close();
+
461
+
462 {
+
463 auto const jrr = ledger_data(env);
+
464 auto const& jstate = jrr[jss::state];
+
465 BEAST_EXPECTS(checkArraySize(jstate, 3), jrr.toStyledString());
+
466 for (auto const& directory : jstate)
+
467 {
+
468 BEAST_EXPECT(
+
469 directory["LedgerEntryType"] ==
+
470 jss::DirectoryNode); // sanity check
+
471 if (directory[jss::Owner] == gw.human())
+
472 {
+
473 // gw's directory did not get touched, so it
+
474 // should not have those fields populated
+
475 BEAST_EXPECT(!directory.isMember("PreviousTxnID"));
+
476 BEAST_EXPECT(!directory.isMember("PreviousTxnLgrSeq"));
+
477 }
+
478 else
+
479 {
+
480 // All of the other directories, including the order
+
481 // book, did get touched, so they should have those
+
482 // fields
+
483 BEAST_EXPECT(
+
484 directory.isMember("PreviousTxnID") &&
+
485 directory["PreviousTxnID"].asString() == txID);
+
486 BEAST_EXPECT(
+
487 directory.isMember("PreviousTxnLgrSeq") &&
+
488 directory["PreviousTxnLgrSeq"].asUInt() == ledgerSeq);
+
489 }
+
490 }
+
491 }
+
492 }
+
493
+
494 void
+
+ +
496 {
+
497 using namespace test::jtx;
+
498 Account alice("alice");
+
499
+
500 auto const testCase = [&, this](FeatureBitset features, auto setup) {
+
501 using namespace test::jtx;
502
-
503BEAST_DEFINE_TESTSUITE_PRIO(Directory, ledger, ripple, 1);
-
504
-
505} // namespace test
-
506} // namespace ripple
+
503 Env env(*this, features);
+
504 env.fund(XRP(20000), alice);
+
505 env.close();
+
506
+
507 auto const [lastPage, full] = setup(env);
+
508
+
509 // Populate root page and last page
+
510 for (int i = 0; i < 63; ++i)
+
511 env(credentials::create(alice, alice, std::to_string(i)));
+
512 env.close();
+
513
+
514 // NOTE, everything below can only be tested on open ledger because
+
515 // there is no transaction type to express what bumpLastPage does.
+
516
+
517 // Bump position of last page from 1 to highest possible
+
518 auto const res = directory::bumpLastPage(
+
519 env,
+
520 lastPage,
+
521 keylet::ownerDir(alice.id()),
+
522 [lastPage, this](
+
523 ApplyView& view, uint256 key, std::uint64_t page) {
+
524 auto sle = view.peek({ltCREDENTIAL, key});
+
525 if (!BEAST_EXPECT(sle))
+
526 return false;
+
527
+
528 BEAST_EXPECT(page == lastPage);
+
529 sle->setFieldU64(sfIssuerNode, page);
+
530 // sfSubjectNode is not set in self-issued credentials
+
531 view.update(sle);
+
532 return true;
+
533 });
+
534 BEAST_EXPECT(res);
+
535
+
536 // Create one more credential
+
537 env(credentials::create(alice, alice, std::to_string(63)));
+
538
+
539 // Not enough space for another object if full
+
540 auto const expected = full ? ter{tecDIR_FULL} : ter{tesSUCCESS};
+
541 env(credentials::create(alice, alice, "foo"), expected);
+
542
+
543 // Destroy all objects in directory
+
544 for (int i = 0; i < 64; ++i)
+ +
546 alice, alice, alice, std::to_string(i)));
+
547
+
548 if (!full)
+
549 env(credentials::deleteCred(alice, alice, alice, "foo"));
+
550
+
551 // Verify directory is empty.
+
552 auto const sle = env.le(keylet::ownerDir(alice.id()));
+
553 BEAST_EXPECT(sle == nullptr);
+
554
+
555 // Test completed
+
556 env.close();
+
557 };
+
558
+
559 testCase(
+
560 testable_amendments() - fixDirectoryLimit,
+ +
562 testcase("directory full without fixDirectoryLimit");
+
563 return {dirNodeMaxPages - 1, true};
+
564 });
+
565 testCase(
+ +
567 [this](Env&) -> std::tuple<std::uint64_t, bool> {
+
568 testcase("directory not full with fixDirectoryLimit");
+
569 return {dirNodeMaxPages - 1, false};
+
570 });
+
571 testCase(
+ +
573 [this](Env&) -> std::tuple<std::uint64_t, bool> {
+
574 testcase("directory full with fixDirectoryLimit");
+ +
576 });
+
577 }
+
+
578
+
579 void
+
+
580 run() override
+
581 {
+
582 testDirectoryOrdering();
+
583 testDirIsEmpty();
+
584 testRipd1353();
+
585 testEmptyChain();
+
586 testPreviousTxnID();
+
587 testDirectoryFull();
+
588 }
+
+
589};
+
+
590
+
591BEAST_DEFINE_TESTSUITE_PRIO(Directory, ledger, ripple, 1);
+
592
+
593} // namespace test
+
594} // namespace ripple
T capacity(T... args)
Represents a JSON value.
Definition json_value.h:149
A testsuite class.
Definition suite.h:55
testcase_t testcase
Memberspace for declaring test cases.
Definition suite.h:155
-
bool dirRemove(Keylet const &directory, std::uint64_t page, uint256 const &key, bool keepRoot)
Remove an entry from a directory.
+
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.
+
bool dirRemove(Keylet const &directory, std::uint64_t page, uint256 const &key, bool keepRoot)
Remove an entry from a directory.
Specifies an order book.
Definition Book.h:36
+
void push_back(uint256 const &v)
Discardable, editable view to a ledger.
Definition Sandbox.h:35
@@ -623,6 +716,7 @@ $(document).ready(function() { init_codefold(0); });
std::optional< key_type > succ(key_type const &key, std::optional< key_type > const &last=std::nullopt) const override
Return the key of the next state item.
std::shared_ptr< SLE > peek(Keylet const &k) override
Prepare to modify the SLE associated with key.
Immutable cryptographic account descriptor.
Definition Account.h:39
+
AccountID id() const
Returns the Account ID.
Definition Account.h:111
A transaction testing environment.
Definition Env.h:121
std::shared_ptr< ReadView const > closed()
Returns the last closed ledger.
Definition Env.cpp:116
std::uint32_t seq(Account const &account) const
Returns the next sequence number on account.
Definition Env.cpp:269
@@ -632,13 +726,19 @@ $(document).ready(function() { init_codefold(0); });
void trust(STAmount const &amount, Account const &account)
Establish trust lines.
Definition Env.cpp:321
void enableFeature(uint256 const feature)
Definition Env.cpp:675
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
Definition Env.cpp:290
+
Set the expected result code for a JTx The test will fail if the code doesn't match.
Definition ter.h:35
T is_same_v
T is_sorted(T... args)
+ +
T max(T... args)
Keylet child(uint256 const &key) noexcept
Any item that can be in an owner dir.
Definition Indexes.cpp:190
Keylet page(uint256 const &root, std::uint64_t index=0) noexcept
A page in a directory.
Definition Indexes.cpp:380
Keylet unchecked(uint256 const &key) noexcept
Any ledger entry.
Definition Indexes.cpp:368
Keylet ownerDir(AccountID const &id) noexcept
The root page of an account's directory.
Definition Indexes.cpp:374
+
Json::Value create(jtx::Account const &subject, jtx::Account const &issuer, std::string_view credType)
Definition creds.cpp:32
+
Json::Value deleteCred(jtx::Account const &acc, jtx::Account const &subject, jtx::Account const &issuer, std::string_view credType)
Definition creds.cpp:62
+
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 checkArraySize(Json::Value const &val, unsigned int size)
Json::Value signers(Account const &account, std::uint32_t quorum, std::vector< signer > const &v)
Definition multisign.cpp:34
static none_t const none
Definition tags.h:34
@@ -650,8 +750,11 @@ $(document).ready(function() { init_codefold(0); });
Json::Value offer_cancel(Account const &account, std::uint32_t offerSeq)
Cancel an offer.
Definition offer.cpp:46
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:25
Issue const & xrpIssue()
Returns an asset specifier that represents XRP.
Definition Issue.h:115
+
std::uint64_t constexpr dirNodeMaxPages
The maximum number of pages allowed in a directory.
Definition Protocol.h:62
bool dirIsEmpty(ReadView const &view, Keylet const &k)
Returns true if the directory is empty.
Definition View.cpp:907
+
@ tecDIR_FULL
Definition TER.h:287
std::size_t constexpr dirNodeMaxEntries
The maximum number of entries per directory page.
Definition Protocol.h:56
+
@ tesSUCCESS
Definition TER.h:244
uint256 getQualityNext(uint256 const &uBase)
Definition Indexes.cpp:141
std::string to_string(base_uint< Bits, Tag > const &a)
Definition base_uint.h:630
@@ -663,15 +766,18 @@ $(document).ready(function() { init_codefold(0); });
T reserve(T... args)
T size(T... args)
- -
std::string currcode(std::size_t i)
- - -
void makePages(Sandbox &sb, uint256 const &base, std::uint64_t n)
- -
void run() override
Runs the suite.
- - + +
std::string currcode(std::size_t i)
+ + +
void makePages(Sandbox &sb, uint256 const &base, std::uint64_t n)
+ +
void run() override
Runs the suite.
+ + + +
T to_string(T... args)
+
diff --git a/EscrowToken__test_8cpp_source.html b/EscrowToken__test_8cpp_source.html index 0a9b6f4591..47d89418bf 100644 --- a/EscrowToken__test_8cpp_source.html +++ b/EscrowToken__test_8cpp_source.html @@ -4187,7 +4187,7 @@ $(document).ready(function() { init_codefold(0); });
constexpr std::uint32_t tfSetDeepFreeze
Definition TxFlags.h:120
constexpr std::uint32_t asfAllowTrustLineLocking
Definition TxFlags.h:95
constexpr std::uint32_t const tfMPTCanTransfer
Definition TxFlags.h:152
-
std::uint64_t constexpr maxMPTokenAmount
The maximum amount of MPTokenIssuance.
Definition Protocol.h:116
+
std::uint64_t constexpr maxMPTokenAmount
The maximum amount of MPTokenIssuance.
Definition Protocol.h:119
constexpr std::uint32_t const tfMPTUnauthorize
Definition TxFlags.h:172
diff --git a/Escrow_8cpp_source.html b/Escrow_8cpp_source.html index ba35b14817..6940d5bdc7 100644 --- a/Escrow_8cpp_source.html +++ b/Escrow_8cpp_source.html @@ -1502,7 +1502,7 @@ $(document).ready(function() { init_codefold(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.
-
bool dirRemove(Keylet const &directory, std::uint64_t page, uint256 const &key, bool keepRoot)
Remove an entry from a directory.
+
bool dirRemove(Keylet const &directory, std::uint64_t page, uint256 const &key, bool keepRoot)
Remove an entry from a directory.
virtual void insert(std::shared_ptr< SLE > const &sle)=0
Insert a new state SLE.
std::optional< std::uint64_t > dirInsert(Keylet const &directory, uint256 const &key, std::function< void(std::shared_ptr< SLE > const &)> const &describe)
Insert an entry to a directory.
Definition ApplyView.h:319
virtual std::shared_ptr< SLE > peek(Keylet const &k)=0
Prepare to modify the SLE associated with key.
diff --git a/GetAggregatePrice_8cpp_source.html b/GetAggregatePrice_8cpp_source.html index e39543881e..1bc92dbbf8 100644 --- a/GetAggregatePrice_8cpp_source.html +++ b/GetAggregatePrice_8cpp_source.html @@ -498,7 +498,7 @@ $(document).ready(function() { init_codefold(0); });
@ rpcOBJECT_NOT_FOUND
Definition ErrorCodes.h:143
@ rpcINVALID_PARAMS
Definition ErrorCodes.h:84
@ rpcINTERNAL
Definition ErrorCodes.h:130
-
std::size_t constexpr maxTrim
The maximum percentage of outliers to trim.
Definition Protocol.h:172
+
std::size_t constexpr maxTrim
The maximum percentage of outliers to trim.
Definition Protocol.h:175
Issue const & noIssue()
Returns an asset specifier that represents no account and currency.
Definition Issue.h:123
bimap< multiset_of< std::uint32_t, std::greater< std::uint32_t > >, multiset_of< STAmount > > Prices
static void iteratePriceData(RPC::JsonContext &context, std::shared_ptr< SLE const > const &sle, std::function< bool(STObject const &)> &&f)
Calls callback "f" on the ledger-object sle and up to three previous metadata objects.
diff --git a/InvariantCheck_8cpp_source.html b/InvariantCheck_8cpp_source.html index 6a3d5e60db..db1363ebb7 100644 --- a/InvariantCheck_8cpp_source.html +++ b/InvariantCheck_8cpp_source.html @@ -3507,10 +3507,10 @@ $(document).ready(function() { init_codefold(0); });
constexpr base_uint< Bits, Tag > operator|(base_uint< Bits, Tag > const &a, base_uint< Bits, Tag > const &b)
Definition base_uint.h:615
static bool validBalances(STAmount const &amount, STAmount const &amount2, STAmount const &lptAMMBalance, ValidAMM::ZeroAllowed zeroAllowed)
base_uint< 256 > uint256
Definition base_uint.h:558
-
std::size_t constexpr maxPermissionedDomainCredentialsArraySize
The maximum number of credentials can be passed in array for permissioned domain.
Definition Protocol.h:110
+
std::size_t constexpr maxPermissionedDomainCredentialsArraySize
The maximum number of credentials can be passed in array for permissioned domain.
Definition Protocol.h:113
bool hasPrivilege(STTx const &tx, Privilege priv)
constexpr std::enable_if_t< std::is_integral_v< Dest > &&std::is_integral_v< Src >, Dest > safe_cast(Src s) noexcept
Definition safe_cast.h:41
-
std::uint64_t constexpr maxMPTokenAmount
The maximum amount of MPTokenIssuance.
Definition Protocol.h:116
+
std::uint64_t constexpr maxMPTokenAmount
The maximum amount of MPTokenIssuance.
Definition Protocol.h:119
@ lsfHighDeepFreeze
@ lsfDefaultRipple
@@ -3536,7 +3536,7 @@ $(document).ready(function() { init_codefold(0); }); -
std::size_t constexpr dirMaxTokensPerPage
The maximum number of items in an NFT page.
Definition Protocol.h:62
+
std::size_t constexpr dirMaxTokensPerPage
The maximum number of items in an NFT page.
Definition Protocol.h:65
Buffer sign(PublicKey const &pk, SecretKey const &sk, Slice const &message)
Generate a signature for a message.
std::array< keyletDesc< AccountID const & >, 6 > const directAccountKeylets
Definition Indexes.h:384
std::pair< STAmount, STAmount > ammPoolHolds(ReadView const &view, AccountID const &ammAccountID, Issue const &issue1, Issue const &issue2, FreezeHandling freezeHandling, beast::Journal const j)
Get AMM pool balances.
Definition AMMUtils.cpp:31
diff --git a/Invariants__test_8cpp_source.html b/Invariants__test_8cpp_source.html index a9331b27e3..1b93fcd4ca 100644 --- a/Invariants__test_8cpp_source.html +++ b/Invariants__test_8cpp_source.html @@ -3727,8 +3727,8 @@ $(document).ready(function() { init_codefold(0); });
constexpr std::uint32_t tfSetDeepFreeze
Definition TxFlags.h:120
constexpr std::uint32_t const tfMPTCanTransfer
Definition TxFlags.h:152
base_uint< 256 > uint256
Definition base_uint.h:558
-
std::size_t constexpr maxPermissionedDomainCredentialsArraySize
The maximum number of credentials can be passed in array for permissioned domain.
Definition Protocol.h:110
-
std::uint64_t constexpr maxMPTokenAmount
The maximum amount of MPTokenIssuance.
Definition Protocol.h:116
+
std::size_t constexpr maxPermissionedDomainCredentialsArraySize
The maximum number of credentials can be passed in array for permissioned domain.
Definition Protocol.h:113
+
std::uint64_t constexpr maxMPTokenAmount
The maximum amount of MPTokenIssuance.
Definition Protocol.h:119
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:64
@ lsfHighDeepFreeze
@ lsfRequireDestTag
@@ -3751,7 +3751,7 @@ $(document).ready(function() { init_codefold(0); });
AccountID pseudoAccountAddress(ReadView const &view, uint256 const &pseudoOwnerKey)
Definition View.cpp:1069
std::string to_string(base_uint< Bits, Tag > const &a)
Definition base_uint.h:630
LedgerEntryType
Identifiers for on-ledger objects.
-
std::uint8_t constexpr vaultStrategyFirstComeFirstServe
Vault withdrawal policies.
Definition Protocol.h:122
+
std::uint8_t constexpr vaultStrategyFirstComeFirstServe
Vault withdrawal policies.
Definition Protocol.h:125
@ tapNONE
Definition ApplyView.h:31
base_uint< 160 > uint160
Definition base_uint.h:557
MPTID makeMptID(std::uint32_t sequence, AccountID const &account)
Definition Indexes.cpp:170
diff --git a/KeyCache__test_8cpp_source.html b/KeyCache__test_8cpp_source.html index a10c77ca24..9b76b8c35e 100644 --- a/KeyCache__test_8cpp_source.html +++ b/KeyCache__test_8cpp_source.html @@ -191,7 +191,7 @@ $(document).ready(function() { init_codefold(0); });
Map/cache combination.
Definition TaggedCache.h:62
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:25
-
std::uint32_t LedgerIndex
A ledger index.
Definition Protocol.h:136
+
std::uint32_t LedgerIndex
A ledger index.
Definition Protocol.h:139
diff --git a/RCLCxLedger_8h_source.html b/RCLCxLedger_8h_source.html index 7793d165c3..cd7ff48c3a 100644 --- a/RCLCxLedger_8h_source.html +++ b/RCLCxLedger_8h_source.html @@ -215,7 +215,7 @@ $(document).ready(function() { init_codefold(0); });
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:25
bool getCloseAgree(LedgerHeader const &info)
-
std::uint32_t LedgerIndex
A ledger index.
Definition Protocol.h:136
+
std::uint32_t LedgerIndex
A ledger index.
Definition Protocol.h:139
Json::Value getJson(LedgerFill const &fill)
Return a new Json::Value representing the ledger with given options.
uint256 LedgerHash
diff --git a/RCLValidations_8h_source.html b/RCLValidations_8h_source.html index 0b444df91c..627a809f69 100644 --- a/RCLValidations_8h_source.html +++ b/RCLValidations_8h_source.html @@ -368,7 +368,7 @@ $(document).ready(function() { init_codefold(0); });
T is_same_v
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:25
-
std::uint32_t LedgerIndex
A ledger index.
Definition Protocol.h:136
+
std::uint32_t LedgerIndex
A ledger index.
Definition Protocol.h:139
base_uint< 160, detail::NodeIDTag > NodeID
NodeID is a 160-bit hash representing one node.
Definition UintTypes.h:59
void handleNewValidation(Application &app, std::shared_ptr< STValidation > const &val, std::string const &source, BypassAccept const bypassAccept, std::optional< beast::Journal > j)
Handle a new validation.
@ no
Definition Steps.h:45
diff --git a/STAmount_8cpp_source.html b/STAmount_8cpp_source.html index 07f5bbb833..c02cbd2a1c 100644 --- a/STAmount_8cpp_source.html +++ b/STAmount_8cpp_source.html @@ -2029,7 +2029,7 @@ $(document).ready(function() { init_codefold(0); });
bool canAdd(STAmount const &amt1, STAmount const &amt2)
Safely checks if two STAmount values can be added without overflow, underflow, or precision loss.
Definition STAmount.cpp:505
SerializedTypeID
Definition SField.h:110
static std::uint64_t const tenTo17
Definition STAmount.cpp:73
-
std::uint64_t constexpr maxMPTokenAmount
The maximum amount of MPTokenIssuance.
Definition Protocol.h:116
+
std::uint64_t constexpr maxMPTokenAmount
The maximum amount of MPTokenIssuance.
Definition Protocol.h:119
STAmount amountFromQuality(std::uint64_t rate)
Definition STAmount.cpp:984
static std::string const & systemCurrencyCode()
bool set(T &target, std::string const &name, Section const &section)
Set a value from a configuration Section If the named value is not found or doesn't parse as a T,...
diff --git a/STTx_8cpp_source.html b/STTx_8cpp_source.html index 64c349f002..1c9a9562dc 100644 --- a/STTx_8cpp_source.html +++ b/STTx_8cpp_source.html @@ -1158,7 +1158,7 @@ $(document).ready(function() { init_codefold(0); });
Expected< void, std::string > multiSignHelper(STObject const &sigObject, std::optional< AccountID > txnAccountID, bool const fullyCanonical, std::function< Serializer(AccountID const &)> makeMsg, Rules const &rules)
Definition STTx.cpp:477
@ txSign
inner transaction to sign
@ transactionID
transaction plus signature to give transaction ID
-
std::size_t constexpr maxBatchTxCount
The maximum number of transactions that can be in a batch.
Definition Protocol.h:179
+
std::size_t constexpr maxBatchTxCount
The maximum number of transactions that can be in a batch.
Definition Protocol.h:182
static Expected< void, std::string > singleSignHelper(STObject const &sigObject, Slice const &data, bool const fullyCanonical)
Definition STTx.cpp:417
void LogicError(std::string const &how) noexcept
Called when faulty logic causes a broken invariant.
STL namespace.
diff --git a/SetAccount_8cpp_source.html b/SetAccount_8cpp_source.html index 397ac42b84..702bddb6f6 100644 --- a/SetAccount_8cpp_source.html +++ b/SetAccount_8cpp_source.html @@ -834,7 +834,7 @@ $(document).ready(function() { init_codefold(0); });
constexpr std::uint32_t tfRequireDestTag
Definition TxFlags.h:66
constexpr std::uint32_t asfNoFreeze
Definition TxFlags.h:82
AccountID calcAccountID(PublicKey const &pk)
-
std::size_t constexpr maxDomainLength
The maximum length of a domain.
Definition Protocol.h:97
+
std::size_t constexpr maxDomainLength
The maximum length of a domain.
Definition Protocol.h:100
constexpr std::uint32_t asfDisableMaster
Definition TxFlags.h:80
bool dirIsEmpty(ReadView const &view, Keylet const &k)
Returns true if the directory is empty.
Definition View.cpp:907
constexpr std::uint32_t asfDisallowIncomingTrustline
Definition TxFlags.h:93
diff --git a/SetOracle_8cpp_source.html b/SetOracle_8cpp_source.html index 3d4065b503..ba783cbad2 100644 --- a/SetOracle_8cpp_source.html +++ b/SetOracle_8cpp_source.html @@ -477,10 +477,10 @@ $(document).ready(function() { init_codefold(0); });
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:25
static void setPriceDataInnerObjTemplate(STObject &obj)
bool isConsistent(Book const &book)
Definition Book.cpp:29
-
std::size_t constexpr maxPriceScale
The maximum price scaling factor.
Definition Protocol.h:168
-
std::size_t constexpr maxOracleURI
The maximum length of a URI inside an Oracle.
Definition Protocol.h:150
+
std::size_t constexpr maxPriceScale
The maximum price scaling factor.
Definition Protocol.h:171
+
std::size_t constexpr maxOracleURI
The maximum length of a URI inside an Oracle.
Definition Protocol.h:153
void adjustOwnerCount(ApplyView &view, std::shared_ptr< SLE > const &sle, std::int32_t amount, beast::Journal j)
Adjust the owner count up or down.
Definition View.cpp:1032
-
std::size_t constexpr maxOracleProvider
The maximum length of a Provider inside an Oracle.
Definition Protocol.h:153
+
std::size_t constexpr maxOracleProvider
The maximum length of a Provider inside an Oracle.
Definition Protocol.h:156
std::function< void(SLE::ref)> describeOwnerDir(AccountID const &account)
Definition View.cpp:1050
static std::pair< Currency, Currency > tokenPairKey(STObject const &pair)
Definition SetOracle.cpp:32
@ tefINTERNAL
Definition TER.h:173
@@ -492,12 +492,12 @@ $(document).ready(function() { init_codefold(0); });
@ tecARRAY_EMPTY
Definition TER.h:356
@ tecTOKEN_PAIR_NOT_FOUND
Definition TER.h:355
static constexpr std::chrono::seconds epoch_offset
Clock for measuring the network time.
Definition chrono.h:55
-
std::size_t constexpr maxOracleSymbolClass
The maximum length of a SymbolClass inside an Oracle.
Definition Protocol.h:159
+
std::size_t constexpr maxOracleSymbolClass
The maximum length of a SymbolClass inside an Oracle.
Definition Protocol.h:162
@ tesSUCCESS
Definition TER.h:244
-
std::size_t constexpr maxOracleDataSeries
The maximum size of a data series array inside an Oracle.
Definition Protocol.h:156
+
std::size_t constexpr maxOracleDataSeries
The maximum size of a data series array inside an Oracle.
Definition Protocol.h:159
@ terNO_ACCOUNT
Definition TER.h:217
TERSubset< CanCvtToTER > TER
Definition TER.h:645
-
std::size_t constexpr maxLastUpdateTimeDelta
The maximum allowed time difference between lastUpdateTime and the time of the last closed ledger.
Definition Protocol.h:164
+
std::size_t constexpr maxLastUpdateTimeDelta
The maximum allowed time difference between lastUpdateTime and the time of the last closed ledger.
Definition Protocol.h:167
TERSubset< CanCvtToNotTEC > NotTEC
Definition TER.h:605
@ temMALFORMED
Definition TER.h:87
@ temARRAY_EMPTY
Definition TER.h:140
diff --git a/SetSignerList_8cpp_source.html b/SetSignerList_8cpp_source.html index c1463dcb8c..86f75d564b 100644 --- a/SetSignerList_8cpp_source.html +++ b/SetSignerList_8cpp_source.html @@ -576,7 +576,7 @@ $(document).ready(function() { init_codefold(0); });
Application & app
Writeable view to a ledger, for applying a transaction.
Definition ApplyView.h:143
-
bool dirRemove(Keylet const &directory, std::uint64_t page, uint256 const &key, bool keepRoot)
Remove an entry from a directory.
+
bool dirRemove(Keylet const &directory, std::uint64_t page, uint256 const &key, bool keepRoot)
Remove an entry from a directory.
virtual void insert(std::shared_ptr< SLE > const &sle)=0
Insert a new state SLE.
std::optional< std::uint64_t > dirInsert(Keylet const &directory, uint256 const &key, std::function< void(std::shared_ptr< SLE > const &)> const &describe)
Insert an entry to a directory.
Definition ApplyView.h:319
virtual std::shared_ptr< SLE > peek(Keylet const &k)=0
Prepare to modify the SLE associated with key.
diff --git a/State_8cpp_source.html b/State_8cpp_source.html index af5e3f3d70..852b14b621 100644 --- a/State_8cpp_source.html +++ b/State_8cpp_source.html @@ -228,7 +228,7 @@ $(document).ready(function() { init_codefold(0); });
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:25
LedgerIndex getCanDelete(soci::session &session)
getCanDelete Returns the ledger sequence which can be deleted.
Definition State.cpp:81
-
std::uint32_t LedgerIndex
A ledger index.
Definition Protocol.h:136
+
std::uint32_t LedgerIndex
A ledger index.
Definition Protocol.h:139
SavedState getSavedState(soci::session &session)
getSavedState Returns the saved state.
Definition State.cpp:99
void setSavedState(soci::session &session, SavedState const &state)
setSavedState Saves the given state.
Definition State.cpp:111
void initStateDB(soci::session &session, BasicConfig const &config, std::string const &dbName)
initStateDB Opens a session with the State database.
Definition State.cpp:25
diff --git a/TaggedCache__test_8cpp_source.html b/TaggedCache__test_8cpp_source.html index 332cf5e4fb..dddd6be5c6 100644 --- a/TaggedCache__test_8cpp_source.html +++ b/TaggedCache__test_8cpp_source.html @@ -251,7 +251,7 @@ $(document).ready(function() { init_codefold(0); });
T is_same_v
A namespace for easy access to logging severity values.
Definition Journal.h:30
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:25
-
std::uint32_t LedgerIndex
A ledger index.
Definition Protocol.h:136
+
std::uint32_t LedgerIndex
A ledger index.
Definition Protocol.h:139