xrpld
Loading...
Searching...
No Matches
AccountTxPaging_test.cpp
1
2#include <test/jtx/Account.h>
3#include <test/jtx/Env.h>
4#include <test/jtx/amount.h>
5#include <test/jtx/offer.h>
6#include <test/jtx/pay.h>
7
8#include <xrpl/beast/unit_test/suite.h>
9#include <xrpl/json/json_value.h>
10#include <xrpl/json/to_string.h>
11#include <xrpl/protocol/jss.h>
12
13namespace xrpl {
14
16{
17 static bool
18 checkTransaction(json::Value const& tx, int sequence, int ledger)
19 {
20 return (
21 tx[jss::tx][jss::Sequence].asInt() == sequence &&
22 tx[jss::tx][jss::ledger_index].asInt() == ledger);
23 }
24
25 static auto
27 test::jtx::Env& env,
28 test::jtx::Account const& account,
29 int ledgerMin,
30 int ledgerMax,
31 int limit,
32 bool forward,
33 json::Value const& marker = json::ValueType::Null)
34 {
35 json::Value jvc;
36 jvc[jss::account] = account.human();
37 jvc[jss::ledger_index_min] = ledgerMin;
38 jvc[jss::ledger_index_max] = ledgerMax;
39 jvc[jss::forward] = forward;
40 jvc[jss::limit] = limit;
41 if (marker)
42 jvc[jss::marker] = marker;
43
44 return env.rpc("json", "account_tx", to_string(jvc))[jss::result];
45 }
46
47 void
49 {
50 testcase("Paging for Single Account");
51 using namespace test::jtx;
52
53 Env env(*this);
54 Account const a1{"A1"};
55 Account const a2{"A2"};
56 Account const a3{"A3"};
57
58 env.fund(XRP(10000), a1, a2, a3);
59 env.close();
60
61 env.trust(a3["USD"](1000), a1);
62 env.trust(a2["USD"](1000), a1);
63 env.trust(a3["USD"](1000), a2);
64 env.close();
65
66 for (auto i = 0; i < 5; ++i)
67 {
68 env(pay(a2, a1, a2["USD"](2)));
69 env(pay(a3, a1, a3["USD"](2)));
70 env(offer(a1, XRP(11), a1["USD"](1)));
71 env(offer(a2, XRP(10), a2["USD"](1)));
72 env(offer(a3, XRP(9), a3["USD"](1)));
73 env.close();
74 }
75
76 /* The sequence/ledger for A3 are as follows:
77 * seq ledger_index
78 * 3 ----> 3
79 * 1 ----> 3
80 * 2 ----> 4
81 * 2 ----> 4
82 * 2 ----> 5
83 * 3 ----> 5
84 * 4 ----> 6
85 * 5 ----> 6
86 * 6 ----> 7
87 * 7 ----> 7
88 * 8 ----> 8
89 * 9 ----> 8
90 * 10 ----> 9
91 * 11 ----> 9
92 */
93
94 // page through the results in several ways.
95 {
96 // limit = 2, 3 batches giving the first 6 txs
97 auto jrr = next(env, a3, 2, 5, 2, true);
98 auto txs = jrr[jss::transactions];
99 if (!BEAST_EXPECT(txs.isArray() && txs.size() == 2))
100 return;
101 BEAST_EXPECT(checkTransaction(txs[0u], 3, 3));
102 BEAST_EXPECT(checkTransaction(txs[1u], 3, 3));
103 if (!BEAST_EXPECT(jrr[jss::marker]))
104 return;
105
106 jrr = next(env, a3, 2, 5, 2, true, jrr[jss::marker]);
107 txs = jrr[jss::transactions];
108 if (!BEAST_EXPECT(txs.isArray() && txs.size() == 2))
109 return;
110 BEAST_EXPECT(checkTransaction(txs[0u], 4, 4));
111 BEAST_EXPECT(checkTransaction(txs[1u], 4, 4));
112 if (!BEAST_EXPECT(jrr[jss::marker]))
113 return;
114
115 jrr = next(env, a3, 2, 5, 2, true, jrr[jss::marker]);
116 txs = jrr[jss::transactions];
117 if (!BEAST_EXPECT(txs.isArray() && txs.size() == 2))
118 return;
119 BEAST_EXPECT(checkTransaction(txs[0u], 4, 5));
120 BEAST_EXPECT(checkTransaction(txs[1u], 5, 5));
121 BEAST_EXPECT(!jrr[jss::marker]);
122 }
123
124 {
125 // limit 1, 3 requests giving the first 3 txs
126 auto jrr = next(env, a3, 3, 9, 1, true);
127 auto txs = jrr[jss::transactions];
128 if (!BEAST_EXPECT(txs.isArray() && txs.size() == 1))
129 return;
130 BEAST_EXPECT(checkTransaction(txs[0u], 3, 3));
131 if (!BEAST_EXPECT(jrr[jss::marker]))
132 return;
133
134 jrr = next(env, a3, 3, 9, 1, true, jrr[jss::marker]);
135 txs = jrr[jss::transactions];
136 if (!BEAST_EXPECT(txs.isArray() && txs.size() == 1))
137 return;
138 BEAST_EXPECT(checkTransaction(txs[0u], 3, 3));
139 if (!BEAST_EXPECT(jrr[jss::marker]))
140 return;
141
142 jrr = next(env, a3, 3, 9, 1, true, jrr[jss::marker]);
143 txs = jrr[jss::transactions];
144 if (!BEAST_EXPECT(txs.isArray() && txs.size() == 1))
145 return;
146 BEAST_EXPECT(checkTransaction(txs[0u], 4, 4));
147 if (!BEAST_EXPECT(jrr[jss::marker]))
148 return;
149
150 // continue with limit 3, to end of all txs
151 jrr = next(env, a3, 3, 9, 3, true, jrr[jss::marker]);
152 txs = jrr[jss::transactions];
153 if (!BEAST_EXPECT(txs.isArray() && txs.size() == 3))
154 return;
155 BEAST_EXPECT(checkTransaction(txs[0u], 4, 4));
156 BEAST_EXPECT(checkTransaction(txs[1u], 4, 5));
157 BEAST_EXPECT(checkTransaction(txs[2u], 5, 5));
158 if (!BEAST_EXPECT(jrr[jss::marker]))
159 return;
160
161 jrr = next(env, a3, 3, 9, 3, true, jrr[jss::marker]);
162 txs = jrr[jss::transactions];
163 if (!BEAST_EXPECT(txs.isArray() && txs.size() == 3))
164 return;
165 BEAST_EXPECT(checkTransaction(txs[0u], 6, 6));
166 BEAST_EXPECT(checkTransaction(txs[1u], 7, 6));
167 BEAST_EXPECT(checkTransaction(txs[2u], 8, 7));
168 if (!BEAST_EXPECT(jrr[jss::marker]))
169 return;
170
171 jrr = next(env, a3, 3, 9, 3, true, jrr[jss::marker]);
172 txs = jrr[jss::transactions];
173 if (!BEAST_EXPECT(txs.isArray() && txs.size() == 3))
174 return;
175 BEAST_EXPECT(checkTransaction(txs[0u], 9, 7));
176 BEAST_EXPECT(checkTransaction(txs[1u], 10, 8));
177 BEAST_EXPECT(checkTransaction(txs[2u], 11, 8));
178 if (!BEAST_EXPECT(jrr[jss::marker]))
179 return;
180
181 jrr = next(env, a3, 3, 9, 3, true, jrr[jss::marker]);
182 txs = jrr[jss::transactions];
183 if (!BEAST_EXPECT(txs.isArray() && txs.size() == 2))
184 return;
185 BEAST_EXPECT(checkTransaction(txs[0u], 12, 9));
186 BEAST_EXPECT(checkTransaction(txs[1u], 13, 9));
187 BEAST_EXPECT(!jrr[jss::marker]);
188 }
189
190 {
191 // limit 2, descending, 2 batches giving last 4 txs
192 auto jrr = next(env, a3, 3, 9, 2, false);
193 auto txs = jrr[jss::transactions];
194 if (!BEAST_EXPECT(txs.isArray() && txs.size() == 2))
195 return;
196 BEAST_EXPECT(checkTransaction(txs[0u], 13, 9));
197 BEAST_EXPECT(checkTransaction(txs[1u], 12, 9));
198 if (!BEAST_EXPECT(jrr[jss::marker]))
199 return;
200
201 jrr = next(env, a3, 3, 9, 2, false, jrr[jss::marker]);
202 txs = jrr[jss::transactions];
203 if (!BEAST_EXPECT(txs.isArray() && txs.size() == 2))
204 return;
205 BEAST_EXPECT(checkTransaction(txs[0u], 11, 8));
206 BEAST_EXPECT(checkTransaction(txs[1u], 10, 8));
207 if (!BEAST_EXPECT(jrr[jss::marker]))
208 return;
209
210 // continue with limit 3 until all txs have been seen
211 jrr = next(env, a3, 3, 9, 3, false, jrr[jss::marker]);
212 txs = jrr[jss::transactions];
213 if (!BEAST_EXPECT(txs.isArray() && txs.size() == 3))
214 return;
215 BEAST_EXPECT(checkTransaction(txs[0u], 9, 7));
216 BEAST_EXPECT(checkTransaction(txs[1u], 8, 7));
217 BEAST_EXPECT(checkTransaction(txs[2u], 7, 6));
218 if (!BEAST_EXPECT(jrr[jss::marker]))
219 return;
220
221 jrr = next(env, a3, 3, 9, 3, false, jrr[jss::marker]);
222 txs = jrr[jss::transactions];
223 if (!BEAST_EXPECT(txs.isArray() && txs.size() == 3))
224 return;
225 BEAST_EXPECT(checkTransaction(txs[0u], 6, 6));
226 BEAST_EXPECT(checkTransaction(txs[1u], 5, 5));
227 BEAST_EXPECT(checkTransaction(txs[2u], 4, 5));
228 if (!BEAST_EXPECT(jrr[jss::marker]))
229 return;
230
231 jrr = next(env, a3, 3, 9, 3, false, jrr[jss::marker]);
232 txs = jrr[jss::transactions];
233 if (!BEAST_EXPECT(txs.isArray() && txs.size() == 3))
234 return;
235 BEAST_EXPECT(checkTransaction(txs[0u], 4, 4));
236 BEAST_EXPECT(checkTransaction(txs[1u], 4, 4));
237 BEAST_EXPECT(checkTransaction(txs[2u], 3, 3));
238 if (!BEAST_EXPECT(jrr[jss::marker]))
239 return;
240
241 jrr = next(env, a3, 3, 9, 3, false, jrr[jss::marker]);
242 txs = jrr[jss::transactions];
243 if (!BEAST_EXPECT(txs.isArray() && txs.size() == 1))
244 return;
245 BEAST_EXPECT(checkTransaction(txs[0u], 3, 3));
246 BEAST_EXPECT(!jrr[jss::marker]);
247 }
248 }
249
250public:
251 void
252 run() override
253 {
255 }
256};
257
258BEAST_DEFINE_TESTSUITE(AccountTxPaging, app, xrpl);
259
260} // namespace xrpl
A testsuite class.
Definition suite.h:50
TestcaseT testcase
Memberspace for declaring test cases.
Definition suite.h:149
Represents a JSON value.
Definition json_value.h:130
static auto next(test::jtx::Env &env, test::jtx::Account const &account, int ledgerMin, int ledgerMax, int limit, bool forward, json::Value const &marker=json::ValueType::Null)
void run() override
Runs the suite.
static bool checkTransaction(json::Value const &tx, int sequence, int ledger)
Immutable cryptographic account descriptor.
Definition jtx/Account.h:17
A transaction testing environment.
Definition Env.h:143
json::Value rpc(unsigned apiVersion, std::unordered_map< std::string, std::string > const &headers, std::string const &cmd, Args &&... args)
Execute an RPC command.
Definition Env.h:864
@ Null
'null' value
Definition json_value.h:19
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
std::string to_string(BaseUInt< Bits, Tag > const &a)
Definition base_uint.h:633
BEAST_DEFINE_TESTSUITE(AccountTxPaging, app, xrpl)