rippled
Loading...
Searching...
No Matches
View_test.cpp
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2012, 2013 Ripple Labs Inc.
5
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#include <test/jtx.h>
21#include <xrpld/app/ledger/Ledger.h>
22#include <xrpld/core/ConfigSections.h>
23#include <xrpld/ledger/ApplyViewImpl.h>
24#include <xrpld/ledger/OpenView.h>
25#include <xrpld/ledger/PaymentSandbox.h>
26#include <xrpld/ledger/Sandbox.h>
27#include <xrpl/protocol/Feature.h>
28#include <xrpl/protocol/Protocol.h>
29#include <type_traits>
30
31namespace ripple {
32namespace test {
33
35{
36 // Convert a small integer to a key
37 static Keylet
39 {
40 return Keylet{ltACCOUNT_ROOT, uint256(id)};
41 }
42
43 // Create SLE with key and payload
46 {
47 auto const le = std::make_shared<SLE>(k(id));
48 le->setFieldU32(sfSequence, seq);
49 return le;
50 }
51
52 // Return payload for SLE
53 template <class T>
54 static std::uint32_t
56 {
57 return le->getFieldU32(sfSequence);
58 }
59
60 // Set payload on SLE
61 static void
63 {
64 le->setFieldU32(sfSequence, seq);
65 }
66
67 // Erase all state items
68 static void
69 wipe(OpenLedger& openLedger)
70 {
71 openLedger.modify([](OpenView& view, beast::Journal) {
72 // HACK!
74 next.emplace(0);
75 for (;;)
76 {
77 next = view.succ(*next);
78 if (!next)
79 break;
80 view.rawErase(std::make_shared<SLE>(
81 *view.read(keylet::unchecked(*next))));
82 }
83 return true;
84 });
85 }
86
87 static void
88 wipe(Ledger& ledger)
89 {
90 // HACK!
92 next.emplace(0);
93 for (;;)
94 {
95 next = ledger.succ(*next);
96 if (!next)
97 break;
98 ledger.rawErase(
99 std::make_shared<SLE>(*ledger.read(keylet::unchecked(*next))));
100 }
101 }
102
103 // Test succ correctness
104 void
106 ReadView const& v,
107 std::uint32_t id,
109 {
110 auto const next = v.succ(k(id).key);
111 if (answer)
112 {
113 if (BEAST_EXPECT(next))
114 BEAST_EXPECT(*next == k(*answer).key);
115 }
116 else
117 {
118 BEAST_EXPECT(!next);
119 }
120 }
121
122 template <class T>
125 {
126 return std::make_shared<std::remove_const_t<T>>(*sp);
127 }
128
129 // Exercise Ledger implementation of ApplyView
130 void
132 {
133 testcase("Ledger");
134
135 using namespace jtx;
136 Env env(*this);
137 Config config;
138 std::shared_ptr<Ledger const> const genesis = std::make_shared<Ledger>(
140 config,
142 env.app().getNodeFamily());
143 auto const ledger = std::make_shared<Ledger>(
144 *genesis, env.app().timeKeeper().closeTime());
145 wipe(*ledger);
146 ReadView& v = *ledger;
147 succ(v, 0, std::nullopt);
148 ledger->rawInsert(sle(1, 1));
149 BEAST_EXPECT(v.exists(k(1)));
150 BEAST_EXPECT(seq(v.read(k(1))) == 1);
151 succ(v, 0, 1);
152 succ(v, 1, std::nullopt);
153 ledger->rawInsert(sle(2, 2));
154 BEAST_EXPECT(seq(v.read(k(2))) == 2);
155 ledger->rawInsert(sle(3, 3));
156 BEAST_EXPECT(seq(v.read(k(3))) == 3);
157 auto s = copy(v.read(k(2)));
158 seq(s, 4);
159 ledger->rawReplace(s);
160 BEAST_EXPECT(seq(v.read(k(2))) == 4);
161 ledger->rawErase(sle(2));
162 BEAST_EXPECT(!v.exists(k(2)));
163 BEAST_EXPECT(v.exists(k(1)));
164 BEAST_EXPECT(v.exists(k(3)));
165 }
166
167 void
169 {
170 testcase("Meta");
171
172 using namespace jtx;
173 Env env(*this);
174 wipe(env.app().openLedger());
175 auto const open = env.current();
177 succ(v, 0, std::nullopt);
178 v.insert(sle(1));
179 BEAST_EXPECT(v.exists(k(1)));
180 BEAST_EXPECT(seq(v.read(k(1))) == 1);
181 BEAST_EXPECT(seq(v.peek(k(1))) == 1);
182 succ(v, 0, 1);
183 succ(v, 1, std::nullopt);
184 v.insert(sle(2, 2));
185 BEAST_EXPECT(seq(v.read(k(2))) == 2);
186 v.insert(sle(3, 3));
187 auto s = v.peek(k(3));
188 BEAST_EXPECT(seq(s) == 3);
189 s = v.peek(k(2));
190 seq(s, 4);
191 v.update(s);
192 BEAST_EXPECT(seq(v.read(k(2))) == 4);
193 v.erase(s);
194 BEAST_EXPECT(!v.exists(k(2)));
195 BEAST_EXPECT(v.exists(k(1)));
196 BEAST_EXPECT(v.exists(k(3)));
197 }
198
199 // Exercise all succ paths
200 void
202 {
203 testcase("Meta succ");
204
205 using namespace jtx;
206 Env env(*this);
207 wipe(env.app().openLedger());
208 auto const open = env.current();
210 v0.insert(sle(1));
211 v0.insert(sle(2));
212 v0.insert(sle(4));
213 v0.insert(sle(7));
214 {
215 Sandbox v1(&v0);
216 v1.insert(sle(3));
217 v1.insert(sle(5));
218 v1.insert(sle(6));
219
220 // v0: 12-4--7
221 // v1: --3-56-
222
223 succ(v0, 0, 1);
224 succ(v0, 1, 2);
225 succ(v0, 2, 4);
226 succ(v0, 3, 4);
227 succ(v0, 4, 7);
228 succ(v0, 5, 7);
229 succ(v0, 6, 7);
230 succ(v0, 7, std::nullopt);
231
232 succ(v1, 0, 1);
233 succ(v1, 1, 2);
234 succ(v1, 2, 3);
235 succ(v1, 3, 4);
236 succ(v1, 4, 5);
237 succ(v1, 5, 6);
238 succ(v1, 6, 7);
239 succ(v1, 7, std::nullopt);
240
241 v1.erase(v1.peek(k(4)));
242 succ(v1, 3, 5);
243
244 v1.erase(v1.peek(k(6)));
245 succ(v1, 5, 7);
246 succ(v1, 6, 7);
247
248 // v0: 12----7
249 // v1: --3-5--
250
251 v1.apply(v0);
252 }
253
254 // v0: 123-5-7
255
256 succ(v0, 0, 1);
257 succ(v0, 1, 2);
258 succ(v0, 2, 3);
259 succ(v0, 3, 5);
260 succ(v0, 4, 5);
261 succ(v0, 5, 7);
262 succ(v0, 6, 7);
263 succ(v0, 7, std::nullopt);
264 }
265
266 void
268 {
269 testcase("Stacked");
270
271 using namespace jtx;
272 Env env(*this);
273 wipe(env.app().openLedger());
274 auto const open = env.current();
276 v0.rawInsert(sle(1, 1));
277 v0.rawInsert(sle(2, 2));
278 v0.rawInsert(sle(4, 4));
279
280 {
281 Sandbox v1(&v0);
282 v1.erase(v1.peek(k(2)));
283 v1.insert(sle(3, 3));
284 auto s = v1.peek(k(4));
285 seq(s, 5);
286 v1.update(s);
287 BEAST_EXPECT(seq(v1.read(k(1))) == 1);
288 BEAST_EXPECT(!v1.exists(k(2)));
289 BEAST_EXPECT(seq(v1.read(k(3))) == 3);
290 BEAST_EXPECT(seq(v1.read(k(4))) == 5);
291 {
292 Sandbox v2(&v1);
293 auto s2 = v2.peek(k(3));
294 seq(s2, 6);
295 v2.update(s2);
296 v2.erase(v2.peek(k(4)));
297 BEAST_EXPECT(seq(v2.read(k(1))) == 1);
298 BEAST_EXPECT(!v2.exists(k(2)));
299 BEAST_EXPECT(seq(v2.read(k(3))) == 6);
300 BEAST_EXPECT(!v2.exists(k(4)));
301 // discard v2
302 }
303 BEAST_EXPECT(seq(v1.read(k(1))) == 1);
304 BEAST_EXPECT(!v1.exists(k(2)));
305 BEAST_EXPECT(seq(v1.read(k(3))) == 3);
306 BEAST_EXPECT(seq(v1.read(k(4))) == 5);
307
308 {
309 Sandbox v2(&v1);
310 auto s2 = v2.peek(k(3));
311 seq(s2, 6);
312 v2.update(s2);
313 v2.erase(v2.peek(k(4)));
314 BEAST_EXPECT(seq(v2.read(k(1))) == 1);
315 BEAST_EXPECT(!v2.exists(k(2)));
316 BEAST_EXPECT(seq(v2.read(k(3))) == 6);
317 BEAST_EXPECT(!v2.exists(k(4)));
318 v2.apply(v1);
319 }
320 BEAST_EXPECT(seq(v1.read(k(1))) == 1);
321 BEAST_EXPECT(!v1.exists(k(2)));
322 BEAST_EXPECT(seq(v1.read(k(3))) == 6);
323 BEAST_EXPECT(!v1.exists(k(4)));
324 v1.apply(v0);
325 }
326 BEAST_EXPECT(seq(v0.read(k(1))) == 1);
327 BEAST_EXPECT(!v0.exists(k(2)));
328 BEAST_EXPECT(seq(v0.read(k(3))) == 6);
329 BEAST_EXPECT(!v0.exists(k(4)));
330 }
331
332 // Verify contextual information
333 void
335 {
336 testcase("Context");
337
338 using namespace jtx;
339 using namespace std::chrono;
340 {
341 Env env(*this);
342 wipe(env.app().openLedger());
343 auto const open = env.current();
344 OpenView v0(open.get());
345 BEAST_EXPECT(v0.seq() != 98);
346 BEAST_EXPECT(v0.seq() == open->seq());
347 BEAST_EXPECT(v0.parentCloseTime() != NetClock::time_point{99s});
348 BEAST_EXPECT(v0.parentCloseTime() == open->parentCloseTime());
349 {
350 // shallow copy
351 OpenView v1(v0);
352 BEAST_EXPECT(v1.seq() == v0.seq());
353 BEAST_EXPECT(v1.parentCloseTime() == v1.parentCloseTime());
354
355 ApplyViewImpl v2(&v1, tapRETRY);
356 BEAST_EXPECT(v2.parentCloseTime() == v1.parentCloseTime());
357 BEAST_EXPECT(v2.seq() == v1.seq());
358 BEAST_EXPECT(v2.flags() == tapRETRY);
359
360 Sandbox v3(&v2);
361 BEAST_EXPECT(v3.seq() == v2.seq());
362 BEAST_EXPECT(v3.parentCloseTime() == v2.parentCloseTime());
363 BEAST_EXPECT(v3.flags() == tapRETRY);
364 }
365 {
366 ApplyViewImpl v1(&v0, tapRETRY);
367 PaymentSandbox v2(&v1);
368 BEAST_EXPECT(v2.seq() == v0.seq());
369 BEAST_EXPECT(v2.parentCloseTime() == v0.parentCloseTime());
370 BEAST_EXPECT(v2.flags() == tapRETRY);
371 PaymentSandbox v3(&v2);
372 BEAST_EXPECT(v3.seq() == v2.seq());
373 BEAST_EXPECT(v3.parentCloseTime() == v2.parentCloseTime());
374 BEAST_EXPECT(v3.flags() == v2.flags());
375 }
376 }
377 }
378
379 // Return a list of keys found via sles
381 sles(ReadView const& ledger)
382 {
384 v.reserve(32);
385 for (auto const& sle : ledger.sles)
386 v.push_back(sle->key());
387 return v;
388 }
389
390 template <class... Args>
392 list(Args... args)
393 {
394 return std::vector<uint256>({uint256(args)...});
395 }
396
397 void
399 {
400 testcase("Upper and lower bound");
401
402 using namespace jtx;
403 Env env(*this);
404 Config config;
405 std::shared_ptr<Ledger const> const genesis = std::make_shared<Ledger>(
407 config,
409 env.app().getNodeFamily());
410 auto const ledger = std::make_shared<Ledger>(
411 *genesis, env.app().timeKeeper().closeTime());
412
413 auto setup = [&ledger](std::vector<int> const& vec) {
414 wipe(*ledger);
415 for (auto x : vec)
416 {
417 ledger->rawInsert(sle(x));
418 }
419 };
420 {
421 setup({1, 2, 3});
422 BEAST_EXPECT(sles(*ledger) == list(1, 2, 3));
423 auto e = ledger->stateMap().end();
424 auto b1 = ledger->stateMap().begin();
425 BEAST_EXPECT(ledger->stateMap().lower_bound(uint256(1)) == e);
426 BEAST_EXPECT(ledger->stateMap().lower_bound(uint256(2)) == b1);
427 ++b1;
428 BEAST_EXPECT(ledger->stateMap().lower_bound(uint256(3)) == b1);
429 ++b1;
430 BEAST_EXPECT(ledger->stateMap().lower_bound(uint256(4)) == b1);
431 BEAST_EXPECT(ledger->stateMap().lower_bound(uint256(5)) == b1);
432 b1 = ledger->stateMap().begin();
433 BEAST_EXPECT(ledger->stateMap().upper_bound(uint256(0)) == b1);
434 ++b1;
435 BEAST_EXPECT(ledger->stateMap().upper_bound(uint256(1)) == b1);
436 ++b1;
437 BEAST_EXPECT(ledger->stateMap().upper_bound(uint256(2)) == b1);
438 BEAST_EXPECT(ledger->stateMap().upper_bound(uint256(3)) == e);
439 }
440
441 {
442 setup({2, 4, 6});
443 BEAST_EXPECT(sles(*ledger) == list(2, 4, 6));
444 auto e = ledger->stateMap().end();
445 auto b1 = ledger->stateMap().begin();
446 BEAST_EXPECT(ledger->stateMap().lower_bound(uint256(1)) == e);
447 BEAST_EXPECT(ledger->stateMap().lower_bound(uint256(2)) == e);
448 BEAST_EXPECT(ledger->stateMap().lower_bound(uint256(3)) == b1);
449 BEAST_EXPECT(ledger->stateMap().lower_bound(uint256(4)) == b1);
450 ++b1;
451 BEAST_EXPECT(ledger->stateMap().lower_bound(uint256(5)) == b1);
452 BEAST_EXPECT(ledger->stateMap().lower_bound(uint256(6)) == b1);
453 ++b1;
454 BEAST_EXPECT(ledger->stateMap().lower_bound(uint256(7)) == b1);
455 b1 = ledger->stateMap().begin();
456 BEAST_EXPECT(ledger->stateMap().upper_bound(uint256(1)) == b1);
457 ++b1;
458 BEAST_EXPECT(ledger->stateMap().upper_bound(uint256(2)) == b1);
459 BEAST_EXPECT(ledger->stateMap().upper_bound(uint256(3)) == b1);
460 ++b1;
461
462 BEAST_EXPECT(ledger->stateMap().upper_bound(uint256(4)) == b1);
463 BEAST_EXPECT(ledger->stateMap().upper_bound(uint256(5)) == b1);
464 BEAST_EXPECT(ledger->stateMap().upper_bound(uint256(6)) == e);
465 BEAST_EXPECT(ledger->stateMap().upper_bound(uint256(7)) == e);
466 }
467 {
468 setup({2, 3, 5, 6, 10, 15});
469 BEAST_EXPECT(sles(*ledger) == list(2, 3, 5, 6, 10, 15));
470 auto e = ledger->stateMap().end();
471 auto b = ledger->stateMap().begin();
472 BEAST_EXPECT(ledger->stateMap().lower_bound(uint256(1)) == e);
473 BEAST_EXPECT(ledger->stateMap().lower_bound(uint256(2)) == e);
474 BEAST_EXPECT(ledger->stateMap().lower_bound(uint256(3)) == b);
475 ++b;
476 BEAST_EXPECT(ledger->stateMap().lower_bound(uint256(4)) == b);
477 BEAST_EXPECT(ledger->stateMap().lower_bound(uint256(5)) == b);
478 ++b;
479 BEAST_EXPECT(ledger->stateMap().lower_bound(uint256(6)) == b);
480 ++b;
481 BEAST_EXPECT(ledger->stateMap().lower_bound(uint256(7)) == b);
482 BEAST_EXPECT(ledger->stateMap().lower_bound(uint256(8)) == b);
483 BEAST_EXPECT(ledger->stateMap().lower_bound(uint256(9)) == b);
484 BEAST_EXPECT(ledger->stateMap().lower_bound(uint256(10)) == b);
485 ++b;
486 BEAST_EXPECT(ledger->stateMap().lower_bound(uint256(11)) == b);
487 BEAST_EXPECT(ledger->stateMap().lower_bound(uint256(12)) == b);
488 BEAST_EXPECT(ledger->stateMap().lower_bound(uint256(13)) == b);
489 BEAST_EXPECT(ledger->stateMap().lower_bound(uint256(14)) == b);
490 BEAST_EXPECT(ledger->stateMap().lower_bound(uint256(15)) == b);
491 ++b;
492 BEAST_EXPECT(ledger->stateMap().lower_bound(uint256(16)) == b);
493 b = ledger->stateMap().begin();
494 BEAST_EXPECT(ledger->stateMap().upper_bound(uint256(0)) == b);
495 BEAST_EXPECT(ledger->stateMap().upper_bound(uint256(1)) == b);
496 ++b;
497 BEAST_EXPECT(ledger->stateMap().upper_bound(uint256(2)) == b);
498 ++b;
499 BEAST_EXPECT(ledger->stateMap().upper_bound(uint256(3)) == b);
500 BEAST_EXPECT(ledger->stateMap().upper_bound(uint256(4)) == b);
501 ++b;
502 BEAST_EXPECT(ledger->stateMap().upper_bound(uint256(5)) == b);
503 ++b;
504 BEAST_EXPECT(ledger->stateMap().upper_bound(uint256(6)) == b);
505 BEAST_EXPECT(ledger->stateMap().upper_bound(uint256(7)) == b);
506 BEAST_EXPECT(ledger->stateMap().upper_bound(uint256(8)) == b);
507 BEAST_EXPECT(ledger->stateMap().upper_bound(uint256(9)) == b);
508 ++b;
509 BEAST_EXPECT(ledger->stateMap().upper_bound(uint256(10)) == b);
510 BEAST_EXPECT(ledger->stateMap().upper_bound(uint256(11)) == b);
511 BEAST_EXPECT(ledger->stateMap().upper_bound(uint256(12)) == b);
512 BEAST_EXPECT(ledger->stateMap().upper_bound(uint256(13)) == b);
513 BEAST_EXPECT(ledger->stateMap().upper_bound(uint256(14)) == b);
514 ++b;
515 BEAST_EXPECT(ledger->stateMap().upper_bound(uint256(15)) == e);
516 BEAST_EXPECT(ledger->stateMap().upper_bound(uint256(16)) == e);
517 }
518 {
519 // some full trees, some empty trees, etc
520 setup({0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
521 13, 14, 15, 16, 20, 25, 30, 32, 33, 34, 35, 36, 37,
522 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 66, 100});
523 BEAST_EXPECT(
524 sles(*ledger) ==
525 list(
526 0,
527 1,
528 2,
529 3,
530 4,
531 5,
532 6,
533 7,
534 8,
535 9,
536 10,
537 11,
538 12,
539 13,
540 14,
541 15,
542 16,
543 20,
544 25,
545 30,
546 32,
547 33,
548 34,
549 35,
550 36,
551 37,
552 38,
553 39,
554 40,
555 41,
556 42,
557 43,
558 44,
559 45,
560 46,
561 47,
562 48,
563 66,
564 100));
565 auto b = ledger->stateMap().begin();
566 auto e = ledger->stateMap().end();
567 BEAST_EXPECT(ledger->stateMap().lower_bound(uint256(0)) == e);
568 BEAST_EXPECT(ledger->stateMap().lower_bound(uint256(1)) == b);
569 BEAST_EXPECT(
570 ledger->stateMap().lower_bound(uint256(5))->key() ==
571 uint256(4));
572 BEAST_EXPECT(
573 ledger->stateMap().lower_bound(uint256(15))->key() ==
574 uint256(14));
575 BEAST_EXPECT(
576 ledger->stateMap().lower_bound(uint256(16))->key() ==
577 uint256(15));
578 BEAST_EXPECT(
579 ledger->stateMap().lower_bound(uint256(19))->key() ==
580 uint256(16));
581 BEAST_EXPECT(
582 ledger->stateMap().lower_bound(uint256(20))->key() ==
583 uint256(16));
584 BEAST_EXPECT(
585 ledger->stateMap().lower_bound(uint256(24))->key() ==
586 uint256(20));
587 BEAST_EXPECT(
588 ledger->stateMap().lower_bound(uint256(31))->key() ==
589 uint256(30));
590 BEAST_EXPECT(
591 ledger->stateMap().lower_bound(uint256(32))->key() ==
592 uint256(30));
593 BEAST_EXPECT(
594 ledger->stateMap().lower_bound(uint256(40))->key() ==
595 uint256(39));
596 BEAST_EXPECT(
597 ledger->stateMap().lower_bound(uint256(47))->key() ==
598 uint256(46));
599 BEAST_EXPECT(
600 ledger->stateMap().lower_bound(uint256(48))->key() ==
601 uint256(47));
602 BEAST_EXPECT(
603 ledger->stateMap().lower_bound(uint256(64))->key() ==
604 uint256(48));
605
606 BEAST_EXPECT(
607 ledger->stateMap().lower_bound(uint256(90))->key() ==
608 uint256(66));
609 BEAST_EXPECT(
610 ledger->stateMap().lower_bound(uint256(96))->key() ==
611 uint256(66));
612 BEAST_EXPECT(
613 ledger->stateMap().lower_bound(uint256(100))->key() ==
614 uint256(66));
615
616 BEAST_EXPECT(
617 ledger->stateMap().upper_bound(uint256(0))->key() ==
618 uint256(1));
619 BEAST_EXPECT(
620 ledger->stateMap().upper_bound(uint256(5))->key() ==
621 uint256(6));
622 BEAST_EXPECT(
623 ledger->stateMap().upper_bound(uint256(15))->key() ==
624 uint256(16));
625 BEAST_EXPECT(
626 ledger->stateMap().upper_bound(uint256(16))->key() ==
627 uint256(20));
628 BEAST_EXPECT(
629 ledger->stateMap().upper_bound(uint256(18))->key() ==
630 uint256(20));
631 BEAST_EXPECT(
632 ledger->stateMap().upper_bound(uint256(20))->key() ==
633 uint256(25));
634 BEAST_EXPECT(
635 ledger->stateMap().upper_bound(uint256(31))->key() ==
636 uint256(32));
637 BEAST_EXPECT(
638 ledger->stateMap().upper_bound(uint256(32))->key() ==
639 uint256(33));
640 BEAST_EXPECT(
641 ledger->stateMap().upper_bound(uint256(47))->key() ==
642 uint256(48));
643 BEAST_EXPECT(
644 ledger->stateMap().upper_bound(uint256(48))->key() ==
645 uint256(66));
646 BEAST_EXPECT(
647 ledger->stateMap().upper_bound(uint256(53))->key() ==
648 uint256(66));
649 BEAST_EXPECT(
650 ledger->stateMap().upper_bound(uint256(66))->key() ==
651 uint256(100));
652 BEAST_EXPECT(
653 ledger->stateMap().upper_bound(uint256(70))->key() ==
654 uint256(100));
655 BEAST_EXPECT(
656 ledger->stateMap().upper_bound(uint256(85))->key() ==
657 uint256(100));
658 BEAST_EXPECT(
659 ledger->stateMap().upper_bound(uint256(98))->key() ==
660 uint256(100));
661 BEAST_EXPECT(ledger->stateMap().upper_bound(uint256(100)) == e);
662 BEAST_EXPECT(ledger->stateMap().upper_bound(uint256(155)) == e);
663 }
664 }
665
666 void
668 {
669 testcase("Sles");
670
671 using namespace jtx;
672 Env env(*this);
673 Config config;
674 std::shared_ptr<Ledger const> const genesis = std::make_shared<Ledger>(
676 config,
678 env.app().getNodeFamily());
679 auto const ledger = std::make_shared<Ledger>(
680 *genesis, env.app().timeKeeper().closeTime());
681 auto setup123 = [&ledger, this]() {
682 // erase middle element
683 wipe(*ledger);
684 ledger->rawInsert(sle(1));
685 ledger->rawInsert(sle(2));
686 ledger->rawInsert(sle(3));
687 BEAST_EXPECT(sles(*ledger) == list(1, 2, 3));
688 };
689 {
690 setup123();
691 OpenView view(ledger.get());
692 view.rawErase(sle(1));
693 view.rawInsert(sle(4));
694 view.rawInsert(sle(5));
695 BEAST_EXPECT(sles(view) == list(2, 3, 4, 5));
696 auto b = view.sles.begin();
697 BEAST_EXPECT(view.sles.upper_bound(uint256(1)) == b);
698 ++b;
699 BEAST_EXPECT(view.sles.upper_bound(uint256(2)) == b);
700 ++b;
701 BEAST_EXPECT(view.sles.upper_bound(uint256(3)) == b);
702 ++b;
703 BEAST_EXPECT(view.sles.upper_bound(uint256(4)) == b);
704 ++b;
705 BEAST_EXPECT(view.sles.upper_bound(uint256(5)) == b);
706 }
707 {
708 setup123();
709 OpenView view(ledger.get());
710 view.rawErase(sle(1));
711 view.rawErase(sle(2));
712 view.rawInsert(sle(4));
713 view.rawInsert(sle(5));
714 BEAST_EXPECT(sles(view) == list(3, 4, 5));
715 auto b = view.sles.begin();
716 BEAST_EXPECT(view.sles.upper_bound(uint256(1)) == b);
717 BEAST_EXPECT(view.sles.upper_bound(uint256(2)) == b);
718 ++b;
719 BEAST_EXPECT(view.sles.upper_bound(uint256(3)) == b);
720 ++b;
721 BEAST_EXPECT(view.sles.upper_bound(uint256(4)) == b);
722 ++b;
723 BEAST_EXPECT(view.sles.upper_bound(uint256(5)) == b);
724 }
725 {
726 setup123();
727 OpenView view(ledger.get());
728 view.rawErase(sle(1));
729 view.rawErase(sle(2));
730 view.rawErase(sle(3));
731 view.rawInsert(sle(4));
732 view.rawInsert(sle(5));
733 BEAST_EXPECT(sles(view) == list(4, 5));
734 auto b = view.sles.begin();
735 BEAST_EXPECT(view.sles.upper_bound(uint256(1)) == b);
736 BEAST_EXPECT(view.sles.upper_bound(uint256(2)) == b);
737 BEAST_EXPECT(view.sles.upper_bound(uint256(3)) == b);
738 ++b;
739 BEAST_EXPECT(view.sles.upper_bound(uint256(4)) == b);
740 ++b;
741 BEAST_EXPECT(view.sles.upper_bound(uint256(5)) == b);
742 }
743 {
744 setup123();
745 OpenView view(ledger.get());
746 view.rawErase(sle(3));
747 view.rawInsert(sle(4));
748 view.rawInsert(sle(5));
749 BEAST_EXPECT(sles(view) == list(1, 2, 4, 5));
750 auto b = view.sles.begin();
751 ++b;
752 BEAST_EXPECT(view.sles.upper_bound(uint256(1)) == b);
753 ++b;
754 BEAST_EXPECT(view.sles.upper_bound(uint256(2)) == b);
755 BEAST_EXPECT(view.sles.upper_bound(uint256(3)) == b);
756 ++b;
757 BEAST_EXPECT(view.sles.upper_bound(uint256(4)) == b);
758 ++b;
759 BEAST_EXPECT(view.sles.upper_bound(uint256(5)) == b);
760 }
761 {
762 setup123();
763 OpenView view(ledger.get());
764 view.rawReplace(sle(1, 10));
765 view.rawReplace(sle(3, 30));
766 BEAST_EXPECT(sles(view) == list(1, 2, 3));
767 BEAST_EXPECT(seq(view.read(k(1))) == 10);
768 BEAST_EXPECT(seq(view.read(k(2))) == 1);
769 BEAST_EXPECT(seq(view.read(k(3))) == 30);
770
771 view.rawErase(sle(3));
772 BEAST_EXPECT(sles(view) == list(1, 2));
773 auto b = view.sles.begin();
774 ++b;
775 BEAST_EXPECT(view.sles.upper_bound(uint256(1)) == b);
776 ++b;
777 BEAST_EXPECT(view.sles.upper_bound(uint256(2)) == b);
778 BEAST_EXPECT(view.sles.upper_bound(uint256(3)) == b);
779 BEAST_EXPECT(view.sles.upper_bound(uint256(4)) == b);
780 BEAST_EXPECT(view.sles.upper_bound(uint256(5)) == b);
781
782 view.rawInsert(sle(5));
783 view.rawInsert(sle(4));
784 view.rawInsert(sle(3));
785 BEAST_EXPECT(sles(view) == list(1, 2, 3, 4, 5));
786 b = view.sles.begin();
787 ++b;
788 BEAST_EXPECT(view.sles.upper_bound(uint256(1)) == b);
789 ++b;
790 BEAST_EXPECT(view.sles.upper_bound(uint256(2)) == b);
791 ++b;
792 BEAST_EXPECT(view.sles.upper_bound(uint256(3)) == b);
793 ++b;
794 BEAST_EXPECT(view.sles.upper_bound(uint256(4)) == b);
795 ++b;
796 BEAST_EXPECT(view.sles.upper_bound(uint256(5)) == b);
797 }
798 }
799
800 void
802 {
803 testcase("Flags");
804
805 using namespace jtx;
806 Env env(*this);
807
808 auto const alice = Account("alice");
809 auto const bob = Account("bob");
810 auto const carol = Account("carol");
811 auto const gw = Account("gateway");
812 auto const USD = gw["USD"];
813 auto const EUR = gw["EUR"];
814
815 env.fund(XRP(10000), alice, bob, carol, gw);
816 env.trust(USD(100), alice, bob, carol);
817 {
818 // Global freezing.
819 env(pay(gw, alice, USD(50)));
820 env(offer(alice, XRP(5), USD(5)));
821
822 // Now freeze gw.
823 env(fset(gw, asfGlobalFreeze));
824 env.close();
825 env(offer(alice, XRP(4), USD(5)), ter(tecFROZEN));
826 env.close();
827
828 // Alice's USD balance should be zero if frozen.
829 BEAST_EXPECT(
830 USD(0) ==
832 *env.closed(),
833 alice,
834 USD.currency,
835 gw,
837 env.journal));
838
839 // Thaw gw and try again.
840 env(fclear(gw, asfGlobalFreeze));
841 env.close();
842 env(offer("alice", XRP(4), USD(5)));
843 }
844 {
845 // Local freezing.
846 env(pay(gw, bob, USD(50)));
847 env.close();
848
849 // Now gw freezes bob's USD trust line.
850 env(trust(gw, USD(100), bob, tfSetFreeze));
851 env.close();
852
853 // Bob's balance should be zero if frozen.
854 BEAST_EXPECT(
855 USD(0) ==
857 *env.closed(),
858 bob,
859 USD.currency,
860 gw,
862 env.journal));
863
864 // gw thaws bob's trust line. bob gets his money back.
865 env(trust(gw, USD(100), bob, tfClearFreeze));
866 env.close();
867 BEAST_EXPECT(
868 USD(50) ==
870 *env.closed(),
871 bob,
872 USD.currency,
873 gw,
875 env.journal));
876 }
877 {
878 // accountHolds().
879 env(pay(gw, carol, USD(50)));
880 env.close();
881
882 // carol has no EUR.
883 BEAST_EXPECT(
884 EUR(0) ==
886 *env.closed(),
887 carol,
888 EUR.currency,
889 gw,
891 env.journal));
892
893 // But carol does have USD.
894 BEAST_EXPECT(
895 USD(50) ==
897 *env.closed(),
898 carol,
899 USD.currency,
900 gw,
902 env.journal));
903
904 // carol's XRP balance should be her holdings minus her reserve.
905 auto const carolsXRP = accountHolds(
906 *env.closed(),
907 carol,
908 xrpCurrency(),
909 xrpAccount(),
911 env.journal);
912 // carol's XRP balance: 10000
913 // base reserve: -200
914 // 1 trust line times its reserve: 1 * -50
915 // -------
916 // carol's available balance: 9750
917 BEAST_EXPECT(carolsXRP == XRP(9750));
918
919 // carol should be able to spend *more* than her XRP balance on
920 // a fee by eating into her reserve.
921 env(noop(carol), fee(carolsXRP + XRP(10)));
922 env.close();
923
924 // carol's XRP balance should now show as zero.
925 BEAST_EXPECT(
926 XRP(0) ==
928 *env.closed(),
929 carol,
930 xrpCurrency(),
931 gw,
933 env.journal));
934 }
935 {
936 // accountFunds().
937 // Gateways have whatever funds they claim to have.
938 auto const gwUSD = accountFunds(
939 *env.closed(), gw, USD(314159), fhZERO_IF_FROZEN, env.journal);
940 BEAST_EXPECT(gwUSD == USD(314159));
941
942 // carol has funds from the gateway.
943 auto carolsUSD = accountFunds(
944 *env.closed(), carol, USD(0), fhZERO_IF_FROZEN, env.journal);
945 BEAST_EXPECT(carolsUSD == USD(50));
946
947 // If carol's funds are frozen she has no funds...
948 env(fset(gw, asfGlobalFreeze));
949 env.close();
950 carolsUSD = accountFunds(
951 *env.closed(), carol, USD(0), fhZERO_IF_FROZEN, env.journal);
952 BEAST_EXPECT(carolsUSD == USD(0));
953
954 // ... unless the query ignores the FROZEN state.
955 carolsUSD = accountFunds(
956 *env.closed(), carol, USD(0), fhIGNORE_FREEZE, env.journal);
957 BEAST_EXPECT(carolsUSD == USD(50));
958
959 // Just to be tidy, thaw gw.
960 env(fclear(gw, asfGlobalFreeze));
961 env.close();
962 }
963 }
964
965 void
967 {
968 testcase("Transfer rate");
969
970 using namespace jtx;
971 Env env(*this);
972
973 auto const gw1 = Account("gw1");
974
975 env.fund(XRP(10000), gw1);
976 env.close();
977
978 auto rdView = env.closed();
979 // Test with no rate set on gw1.
980 BEAST_EXPECT(transferRate(*rdView, gw1) == parityRate);
981
982 env(rate(gw1, 1.02));
983 env.close();
984
985 rdView = env.closed();
986 BEAST_EXPECT(transferRate(*rdView, gw1) == Rate{1020000000});
987 }
988
989 void
991 {
992 // This test requires incompatible ledgers. The good news we can
993 // construct and manage two different Env instances at the same
994 // time. So we can use two Env instances to produce mutually
995 // incompatible ledgers.
996 testcase("Are compatible");
997
998 using namespace jtx;
999 auto const alice = Account("alice");
1000 auto const bob = Account("bob");
1001
1002 // The first Env.
1003 Env eA(*this, envconfig(), nullptr, beast::severities::kDisabled);
1004
1005 eA.fund(XRP(10000), alice);
1006 eA.close();
1007 auto const rdViewA3 = eA.closed();
1008
1009 eA.fund(XRP(10000), bob);
1010 eA.close();
1011 auto const rdViewA4 = eA.closed();
1012
1013 // The two Env's can't share the same ports, so modify the config
1014 // of the second Env to use higher port numbers
1015 Env eB{*this, envconfig(), nullptr, beast::severities::kDisabled};
1016
1017 // Make ledgers that are incompatible with the first ledgers. Note
1018 // that bob is funded before alice.
1019 eB.fund(XRP(10000), bob);
1020 eB.close();
1021 auto const rdViewB3 = eB.closed();
1022
1023 eB.fund(XRP(10000), alice);
1024 eB.close();
1025 auto const rdViewB4 = eB.closed();
1026
1027 // Check for compatibility.
1028 auto jStream = eA.journal.error();
1029 BEAST_EXPECT(areCompatible(*rdViewA3, *rdViewA4, jStream, ""));
1030 BEAST_EXPECT(areCompatible(*rdViewA4, *rdViewA3, jStream, ""));
1031 BEAST_EXPECT(areCompatible(*rdViewA4, *rdViewA4, jStream, ""));
1032 BEAST_EXPECT(!areCompatible(*rdViewA3, *rdViewB4, jStream, ""));
1033 BEAST_EXPECT(!areCompatible(*rdViewA4, *rdViewB3, jStream, ""));
1034 BEAST_EXPECT(!areCompatible(*rdViewA4, *rdViewB4, jStream, ""));
1035
1036 // Try the other interface.
1037 // Note that the different interface has different outcomes.
1038 auto const& iA3 = rdViewA3->info();
1039 auto const& iA4 = rdViewA4->info();
1040
1041 BEAST_EXPECT(areCompatible(iA3.hash, iA3.seq, *rdViewA4, jStream, ""));
1042 BEAST_EXPECT(areCompatible(iA4.hash, iA4.seq, *rdViewA3, jStream, ""));
1043 BEAST_EXPECT(areCompatible(iA4.hash, iA4.seq, *rdViewA4, jStream, ""));
1044 BEAST_EXPECT(!areCompatible(iA3.hash, iA3.seq, *rdViewB4, jStream, ""));
1045 BEAST_EXPECT(areCompatible(iA4.hash, iA4.seq, *rdViewB3, jStream, ""));
1046 BEAST_EXPECT(!areCompatible(iA4.hash, iA4.seq, *rdViewB4, jStream, ""));
1047 }
1048
1049 void
1051 {
1052 testcase("Regressions");
1053
1054 using namespace jtx;
1055
1056 // Create a ledger with 1 item, put a
1057 // ApplyView on that, then another ApplyView,
1058 // erase the item, apply.
1059 {
1060 Env env(*this);
1061 Config config;
1062 std::shared_ptr<Ledger const> const genesis =
1063 std::make_shared<Ledger>(
1065 config,
1067 env.app().getNodeFamily());
1068 auto const ledger = std::make_shared<Ledger>(
1069 *genesis, env.app().timeKeeper().closeTime());
1070 wipe(*ledger);
1071 ledger->rawInsert(sle(1));
1072 ReadView& v0 = *ledger;
1073 ApplyViewImpl v1(&v0, tapNONE);
1074 {
1075 Sandbox v2(&v1);
1076 v2.erase(v2.peek(k(1)));
1077 v2.apply(v1);
1078 }
1079 BEAST_EXPECT(!v1.exists(k(1)));
1080 }
1081
1082 // Make sure OpenLedger::empty works
1083 {
1084 Env env(*this);
1085 BEAST_EXPECT(env.app().openLedger().empty());
1086 env.fund(XRP(10000), Account("test"));
1087 BEAST_EXPECT(!env.app().openLedger().empty());
1088 }
1089 }
1090
1091 void
1092 run() override
1093 {
1094 // This had better work, or else
1095 BEAST_EXPECT(k(0).key < k(1).key);
1096
1097 testLedger();
1098 testMeta();
1099 testMetaSucc();
1100 testStacked();
1101 testContext();
1102 testSles();
1104 testFlags();
1108 }
1109};
1110
1112{
1113 void
1115 {
1116 using namespace jtx;
1117 Env env{*this, envconfig(validator, "")};
1118
1119 // Start out with no amendments.
1120 auto majorities = getMajorityAmendments(*env.closed());
1121 BEAST_EXPECT(majorities.empty());
1122
1123 // Now close ledgers until the amendments show up.
1124 int i = 0;
1125 for (i = 0; i <= 256; ++i)
1126 {
1127 env.close();
1128 majorities = getMajorityAmendments(*env.closed());
1129 if (!majorities.empty())
1130 break;
1131 }
1132
1133 // There should be at least 5 amendments. Don't do exact comparison
1134 // to avoid maintenance as more amendments are added in the future.
1135 BEAST_EXPECT(i == 254);
1136 BEAST_EXPECT(majorities.size() >= 5);
1137
1138 // None of the amendments should be enabled yet.
1139 auto enableds = getEnabledAmendments(*env.closed());
1140 BEAST_EXPECT(enableds.empty());
1141
1142 // Now wait 2 weeks modulo 256 ledgers for the amendments to be
1143 // enabled. Speed the process by closing ledgers every 80 minutes,
1144 // which should get us to just past 2 weeks after 256 ledgers.
1145 for (i = 0; i <= 256; ++i)
1146 {
1147 using namespace std::chrono_literals;
1148 env.close(80min);
1149 enableds = getEnabledAmendments(*env.closed());
1150 if (!enableds.empty())
1151 break;
1152 }
1153 BEAST_EXPECT(i == 255);
1154 BEAST_EXPECT(enableds.size() >= 5);
1155 }
1156
1157 void
1158 run() override
1159 {
1161 }
1162};
1163
1164BEAST_DEFINE_TESTSUITE(View, ledger, ripple);
1165BEAST_DEFINE_TESTSUITE(GetAmendments, ledger, ripple);
1166
1167} // namespace test
1168} // namespace ripple
A generic endpoint for log messages.
Definition: Journal.h:59
Stream error() const
Definition: Journal.h:335
A testsuite class.
Definition: suite.h:53
testcase_t testcase
Memberspace for declaring test cases.
Definition: suite.h:153
virtual OpenLedger & openLedger()=0
virtual TimeKeeper & timeKeeper()=0
Editable, discardable view that can build metadata for one tx.
Definition: ApplyViewImpl.h:37
Holds a ledger.
Definition: Ledger.h:80
void rawErase(std::shared_ptr< SLE > const &sle) override
Delete an existing state item.
Definition: Ledger.cpp:524
std::shared_ptr< SLE const > read(Keylet const &k) const override
Return the state item associated with a key.
Definition: Ledger.cpp:441
std::optional< uint256 > succ(uint256 const &key, std::optional< uint256 > const &last=std::nullopt) const override
Definition: Ledger.cpp:430
Represents the open ledger.
Definition: OpenLedger.h:50
bool modify(modify_type const &f)
Modify the open ledger.
Definition: OpenLedger.cpp:57
bool empty() const
Returns true if there are no transactions.
Definition: OpenLedger.cpp:43
Writable ledger view that accumulates state and tx changes.
Definition: OpenView.h:56
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.
Definition: OpenView.cpp:164
std::shared_ptr< SLE const > read(Keylet const &k) const override
Return the state item associated with a key.
Definition: OpenView.cpp:171
void rawErase(std::shared_ptr< SLE > const &sle) override
Delete an existing state item.
Definition: OpenView.cpp:233
void rawReplace(std::shared_ptr< SLE > const &sle) override
Unconditionally replace a state item.
Definition: OpenView.cpp:245
void rawInsert(std::shared_ptr< SLE > const &sle) override
Unconditionally insert a state item.
Definition: OpenView.cpp:239
A wrapper which makes credits unavailable to balances.
A view into a ledger.
Definition: ReadView.h:55
virtual std::shared_ptr< SLE const > read(Keylet const &k) const =0
Return the state item associated with a key.
NetClock::time_point parentCloseTime() const
Returns the close time of the previous ledger.
Definition: ReadView.h:115
virtual std::optional< key_type > succ(key_type const &key, std::optional< key_type > const &last=std::nullopt) const =0
Return the key of the next state item.
virtual bool exists(Keylet const &k) const =0
Determine if a state item exists.
LedgerIndex seq() const
Returns the sequence number of the base ledger.
Definition: ReadView.h:122
sles_type sles
Iterable range of ledger state items.
Definition: ReadView.h:249
Discardable, editable view to a ledger.
Definition: Sandbox.h:35
void apply(RawView &to)
Definition: Sandbox.h:55
time_point closeTime() const
Returns the predicted close time, in network time.
Definition: TimeKeeper.h:76
void erase(std::shared_ptr< SLE > const &sle) override
Remove a peeked SLE.
void update(std::shared_ptr< SLE > const &sle) override
Indicate changes to a peeked SLE.
void insert(std::shared_ptr< SLE > const &sle) override
Insert a new state SLE.
void rawInsert(std::shared_ptr< SLE > const &sle) override
Unconditionally insert a state item.
bool exists(Keylet const &k) const override
Determine if a state item exists.
ApplyFlags flags() const override
Returns the tx apply flags.
std::shared_ptr< SLE const > read(Keylet const &k) const override
Return the state item associated with a key.
std::shared_ptr< SLE > peek(Keylet const &k) override
Prepare to modify the SLE associated with key.
void run() override
Runs the suite.
Definition: View_test.cpp:1158
static std::shared_ptr< SLE > sle(std::uint64_t id, std::uint32_t seq=1)
Definition: View_test.cpp:45
static void wipe(Ledger &ledger)
Definition: View_test.cpp:88
static void seq(std::shared_ptr< SLE > const &le, std::uint32_t seq)
Definition: View_test.cpp:62
void succ(ReadView const &v, std::uint32_t id, std::optional< std::uint32_t > answer)
Definition: View_test.cpp:105
static Keylet k(std::uint64_t id)
Definition: View_test.cpp:38
static void wipe(OpenLedger &openLedger)
Definition: View_test.cpp:69
static std::shared_ptr< std::remove_const_t< T > > copy(std::shared_ptr< T > const &sp)
Definition: View_test.cpp:124
static std::vector< uint256 > sles(ReadView const &ledger)
Definition: View_test.cpp:381
void run() override
Runs the suite.
Definition: View_test.cpp:1092
static std::uint32_t seq(std::shared_ptr< T > const &le)
Definition: View_test.cpp:55
static std::vector< uint256 > list(Args... args)
Definition: View_test.cpp:392
Immutable cryptographic account descriptor.
Definition: Account.h:38
A transaction testing environment.
Definition: Env.h:117
std::shared_ptr< ReadView const > closed()
Returns the last closed ledger.
Definition: Env.cpp:115
std::shared_ptr< OpenView const > current() const
Returns the current ledger.
Definition: Env.h:325
bool close(NetClock::time_point closeTime, std::optional< std::chrono::milliseconds > consensusDelay=std::nullopt)
Close and advance the ledger.
Definition: Env.cpp:121
void trust(STAmount const &amount, Account const &account)
Establish trust lines.
Definition: Env.cpp:268
Application & app()
Definition: Env.h:255
beast::Journal const journal
Definition: Env.h:158
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
Definition: Env.cpp:237
Set the fee on a JTx.
Definition: fee.h:36
Set the expected result code for a JTx The test will fail if the code doesn't match.
Definition: ter.h:34
Keylet unchecked(uint256 const &key) noexcept
Any ledger entry.
Definition: Indexes.cpp:344
std::unique_ptr< Config > validator(std::unique_ptr< Config >, std::string const &)
adjust configuration with params needed to be a validator
Definition: envconfig.cpp:113
Json::Value fclear(Account const &account, std::uint32_t off)
Remove account flag.
Definition: flags.h:40
Json::Value trust(Account const &account, STAmount const &amount, std::uint32_t flags)
Modify a trust line.
Definition: trust.cpp:30
Json::Value fset(Account const &account, std::uint32_t on, std::uint32_t off=0)
Add and/or remove flag.
Definition: flags.cpp:28
Json::Value pay(AccountID const &account, AccountID const &to, AnyAmount amount)
Create a payment.
Definition: pay.cpp:29
std::unique_ptr< Config > envconfig()
creates and initializes a default configuration for jtx::Env
Definition: envconfig.h:54
Json::Value rate(Account const &account, double multiplier)
Set a transfer rate.
Definition: rate.cpp:30
Json::Value noop(Account const &account)
The null transaction.
Definition: noop.h:31
Json::Value offer(Account const &account, STAmount const &takerPays, STAmount const &takerGets, std::uint32_t flags)
Create an offer.
Definition: offer.cpp:28
XRP_t const XRP
Converts to XRP Issue or STAmount.
Definition: amount.cpp:104
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: algorithm.h:26
constexpr std::uint32_t asfGlobalFreeze
Definition: TxFlags.h:82
STAmount accountFunds(ReadView const &view, AccountID const &id, STAmount const &saDefault, FreezeHandling freezeHandling, beast::Journal j)
Definition: View.cpp:442
@ fhZERO_IF_FROZEN
Definition: View.h:80
@ fhIGNORE_FREEZE
Definition: View.h:80
AccountID const & xrpAccount()
Compute AccountID from public key.
Definition: AccountID.cpp:170
base_uint< 256 > uint256
Definition: base_uint.h:557
Rate transferRate(ReadView const &view, AccountID const &issuer)
Returns IOU issuer transfer fee as Rate.
Definition: View.cpp:650
std::set< uint256 > getEnabledAmendments(ReadView const &view)
Definition: View.cpp:796
@ open
We haven't closed our ledger yet, but others might have.
Currency const & xrpCurrency()
XRP currency.
Definition: UintTypes.cpp:115
constexpr std::uint32_t tfClearFreeze
Definition: TxFlags.h:116
@ tecFROZEN
Definition: TER.h:290
STAmount accountHolds(ReadView const &view, AccountID const &account, Currency const &currency, AccountID const &issuer, FreezeHandling zeroIfFrozen, beast::Journal j)
Definition: View.cpp:308
majorityAmendments_t getMajorityAmendments(ReadView const &view)
Definition: View.cpp:813
create_genesis_t const create_genesis
Definition: Ledger.cpp:60
@ tapRETRY
Definition: ApplyView.h:39
@ tapNONE
Definition: ApplyView.h:31
constexpr std::uint32_t tfSetFreeze
Definition: TxFlags.h:115
bool areCompatible(ReadView const &validLedger, ReadView const &testLedger, beast::Journal::Stream &s, const char *reason)
Return false if the test ledger is provably incompatible with the valid ledger, that is,...
Definition: View.cpp:674
Rate const parityRate
A transfer rate signifying a 1:1 exchange.
T push_back(T... args)
T reserve(T... args)
A pair of SHAMap key and LedgerEntryType.
Definition: Keylet.h:39
uint256 key
Definition: Keylet.h:40
Represents a transfer rate.
Definition: Rate.h:38
iterator upper_bound(key_type const &key) const
Definition: ReadView.cpp:41
iterator begin() const
Definition: ReadView.cpp:29
Set the sequence number on a JTx.
Definition: seq.h:34