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