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