22#include <xrpld/app/ledger/LedgerMaster.h>
23#include <xrpld/rpc/detail/RPCHelpers.h>
25#include <xrpl/beast/unit_test.h>
26#include <xrpl/protocol/ErrorCodes.h>
27#include <xrpl/protocol/jss.h>
37 static constexpr char const*
hash1 =
38 "3020EB9E7BE24EF7D7A060CB051583EC117384636D1781AFB5B87F3E348DA489";
40 "BD8A3D72CA73DDE887AD63666EC2BAD07875CBA997A102579B5B95ECDFFEAED8";
43 "0000000000000000000000000000000000000000000000000000000000000000";
49 using namespace test::jtx;
55 BEAST_EXPECT(env.current()->info().seq == 5);
59 auto const result = env.rpc(
"ledger_request",
"arbitrary_text");
62 result[jss::result][jss::error_message] ==
63 "Ledger index too small");
67 auto const result = env.rpc(
"ledger_request",
"-1");
70 result[jss::result][jss::error_message] ==
71 "Ledger index too small");
75 auto const result = env.rpc(
"ledger_request",
"0");
78 result[jss::result][jss::error_message] ==
79 "Ledger index too small");
83 auto const result = env.rpc(
"ledger_request",
"1");
86 result[jss::result][jss::ledger_index] == 1 &&
87 result[jss::result].isMember(jss::ledger));
89 result[jss::result][jss::ledger].isMember(jss::ledger_hash) &&
90 result[jss::result][jss::ledger][jss::ledger_hash].isString());
94 auto const result = env.rpc(
"ledger_request",
"2");
97 result[jss::result][jss::ledger_index] == 2 &&
98 result[jss::result].isMember(jss::ledger));
100 result[jss::result][jss::ledger].isMember(jss::ledger_hash) &&
101 result[jss::result][jss::ledger][jss::ledger_hash].isString());
105 auto const result = env.rpc(
"ledger_request",
"3");
108 result[jss::result][jss::ledger_index] == 3 &&
109 result[jss::result].isMember(jss::ledger));
111 result[jss::result][jss::ledger].isMember(jss::ledger_hash) &&
112 result[jss::result][jss::ledger][jss::ledger_hash].isString());
114 auto const ledgerHash =
115 result[jss::result][jss::ledger][jss::ledger_hash].asString();
118 auto const r = env.rpc(
"ledger_request", ledgerHash);
121 r[jss::result][jss::ledger_index] == 3 &&
122 r[jss::result].isMember(jss::ledger));
124 r[jss::result][jss::ledger].isMember(jss::ledger_hash) &&
125 r[jss::result][jss::ledger][jss::ledger_hash] ==
133 auto const result = env.rpc(
"ledger_request", ledgerHash);
137 result[jss::result][jss::error_message] ==
138 "Invalid field 'ledger_hash'.");
144 auto const result = env.rpc(
"ledger_request", ledgerHash);
148 result[jss::result][jss::have_header] ==
false);
152 auto const result = env.rpc(
"ledger_request",
"4");
155 result[jss::result][jss::error_message] ==
156 "Ledger index too large");
160 auto const result = env.rpc(
"ledger_request",
"5");
163 result[jss::result][jss::error_message] ==
164 "Ledger index too large");
171 using namespace test::jtx;
174 Account
const gw{
"gateway"};
175 auto const USD = gw[
"USD"];
176 env.fund(XRP(100000), gw);
180 env.fund(XRP(1000),
"bob");
183 env.memoize(
"alice");
184 env.fund(XRP(1000),
"alice");
187 env.memoize(
"carol");
188 env.fund(XRP(1000),
"carol");
191 auto result = env.rpc(
"ledger_request",
"1")[jss::result];
192 BEAST_EXPECT(result[jss::ledger][jss::ledger_index] ==
"1");
194 result[jss::ledger][jss::total_coins] ==
"100000000000000000");
195 BEAST_EXPECT(result[jss::ledger][jss::closed] ==
true);
196 BEAST_EXPECT(result[jss::ledger][jss::ledger_hash] ==
hash1);
197 BEAST_EXPECT(result[jss::ledger][jss::parent_hash] ==
zerohash);
198 BEAST_EXPECT(result[jss::ledger][jss::account_hash] ==
accounthash1);
199 BEAST_EXPECT(result[jss::ledger][jss::transaction_hash] ==
zerohash);
201 result = env.rpc(
"ledger_request",
"2")[jss::result];
202 constexpr char const* hash2 =
203 "CCC3B3E88CCAC17F1BE6B4A648A55999411F19E3FE55EB721960EB0DF28EDDA5";
204 BEAST_EXPECT(result[jss::ledger][jss::ledger_index] ==
"2");
206 result[jss::ledger][jss::total_coins] ==
"100000000000000000");
207 BEAST_EXPECT(result[jss::ledger][jss::closed] ==
true);
208 BEAST_EXPECT(result[jss::ledger][jss::ledger_hash] == hash2);
209 BEAST_EXPECT(result[jss::ledger][jss::parent_hash] ==
hash1);
211 result[jss::ledger][jss::account_hash] ==
212 "3C834285F7F464FBE99AFEB84D354A968EB2CAA24523FF26797A973D906A3D29");
213 BEAST_EXPECT(result[jss::ledger][jss::transaction_hash] ==
zerohash);
215 result = env.rpc(
"ledger_request",
"3")[jss::result];
216 constexpr char const* hash3 =
217 "8D631B20BC989AF568FBA97375290544B0703A5ADC1CF9E9053580461690C9EE";
218 BEAST_EXPECT(result[jss::ledger][jss::ledger_index] ==
"3");
220 result[jss::ledger][jss::total_coins] ==
"99999999999999980");
221 BEAST_EXPECT(result[jss::ledger][jss::closed] ==
true);
222 BEAST_EXPECT(result[jss::ledger][jss::ledger_hash] == hash3);
223 BEAST_EXPECT(result[jss::ledger][jss::parent_hash] == hash2);
225 result[jss::ledger][jss::account_hash] ==
226 "BC9EF2A16BFF80BCFABA6FA84688D858D33BD0FA0435CAA9DF6DA4105A39A29E");
228 result[jss::ledger][jss::transaction_hash] ==
229 "0213EC486C058B3942FBE3DAC6839949A5C5B02B8B4244C8998EFDF04DBD8222");
231 result = env.rpc(
"ledger_request",
"4")[jss::result];
232 constexpr char const* hash4 =
233 "1A8E7098B23597E73094DADA58C9D62F3AB93A12C6F7666D56CA85A6CFDE530F";
234 BEAST_EXPECT(result[jss::ledger][jss::ledger_index] ==
"4");
236 result[jss::ledger][jss::total_coins] ==
"99999999999999960");
237 BEAST_EXPECT(result[jss::ledger][jss::closed] ==
true);
238 BEAST_EXPECT(result[jss::ledger][jss::ledger_hash] == hash4);
239 BEAST_EXPECT(result[jss::ledger][jss::parent_hash] == hash3);
241 result[jss::ledger][jss::account_hash] ==
242 "C690188F123C91355ADA8BDF4AC5B5C927076D3590C215096868A5255264C6DD");
244 result[jss::ledger][jss::transaction_hash] ==
245 "3CBDB8F42E04333E1642166BFB93AC9A7E1C6C067092CD5D881D6F3AB3D67E76");
247 result = env.rpc(
"ledger_request",
"5")[jss::result];
248 constexpr char const* hash5 =
249 "C6A222D71AE65D7B4F240009EAD5DEB20D7EEDE5A4064F28BBDBFEEB6FBE48E5";
250 BEAST_EXPECT(result[jss::ledger][jss::ledger_index] ==
"5");
252 result[jss::ledger][jss::total_coins] ==
"99999999999999940");
253 BEAST_EXPECT(result[jss::ledger][jss::closed] ==
true);
254 BEAST_EXPECT(result[jss::ledger][jss::ledger_hash] == hash5);
255 BEAST_EXPECT(result[jss::ledger][jss::parent_hash] == hash4);
257 result[jss::ledger][jss::account_hash] ==
258 "EA81CD9D36740736F00CB747E0D0E32D3C10B695823D961F0FB9A1CE7133DD4D");
260 result[jss::ledger][jss::transaction_hash] ==
261 "C3D086CD6BDB9E97AD1D513B2C049EF2840BD21D0B3E22D84EBBB89B6D2EF59D");
263 result = env.rpc(
"ledger_request",
"6")[jss::result];
264 BEAST_EXPECT(result[jss::error] ==
"invalidParams");
265 BEAST_EXPECT(result[jss::status] ==
"error");
266 BEAST_EXPECT(result[jss::error_message] ==
"Ledger index too large");
272 using namespace test::jtx;
274 Account
const gw{
"gateway"};
275 auto const USD = gw[
"USD"];
276 env.fund(XRP(100000), gw);
280 jvParams[jss::ledger_hash] =
281 "AB868A6CFEEC779C2FF845C0AF00A642259986AF40C01976A7F842B6918936C7";
282 jvParams[jss::ledger_index] =
"1";
283 auto result = env.rpc(
284 "json",
"ledger_request", jvParams.
toStyledString())[jss::result];
285 BEAST_EXPECT(result[jss::error] ==
"invalidParams");
286 BEAST_EXPECT(result[jss::status] ==
"error");
288 result[jss::error_message] ==
289 "Exactly one of ledger_hash and ledger_index can be set.");
293 env.timeKeeper().adjustCloseTime(
weeks{3});
294 result = env.rpc(
apiVersion,
"ledger_request",
"1")[jss::result];
295 BEAST_EXPECT(result[jss::status] ==
"error");
298 BEAST_EXPECT(result[jss::error] ==
"noCurrent");
300 result[jss::error_message] ==
"Current ledger is unavailable.");
304 BEAST_EXPECT(result[jss::error] ==
"notSynced");
306 result[jss::error_message] ==
"Not synced to the network.");
313 using namespace test::jtx;
314 using namespace std::chrono_literals;
319 Account
const gw{
"gateway"};
320 auto const USD = gw[
"USD"];
321 env.fund(XRP(100000), gw);
323 int const max_limit = 256;
325 for (
auto i = 0; i < max_limit + 10; i++)
328 env.fund(XRP(1000), bob);
332 auto result = env.rpc(
"ledger_request",
"1")[jss::result];
333 BEAST_EXPECT(result[jss::ledger][jss::ledger_index] ==
"1");
335 result[jss::ledger][jss::total_coins] ==
"100000000000000000");
336 BEAST_EXPECT(result[jss::ledger][jss::closed] ==
true);
337 BEAST_EXPECT(result[jss::ledger][jss::ledger_hash] ==
hash1);
338 BEAST_EXPECT(result[jss::ledger][jss::parent_hash] ==
zerohash);
339 BEAST_EXPECT(result[jss::ledger][jss::account_hash] ==
accounthash1);
340 BEAST_EXPECT(result[jss::ledger][jss::transaction_hash] ==
zerohash);
346 using namespace test::jtx;
347 Env env{*
this, envconfig(no_admin)};
348 Account
const gw{
"gateway"};
349 auto const USD = gw[
"USD"];
350 env.fund(XRP(100000), gw);
353 auto const result = env.rpc(
"ledger_request",
"1")[jss::result];
372BEAST_DEFINE_TESTSUITE(LedgerRequestRPC, app,
ripple);
std::string toStyledString() const
void run() override
Runs the suite.
static constexpr char const * hash1
void testMoreThan256Closed()
static constexpr char const * accounthash1
static constexpr char const * zerohash
void testBadInput(unsigned apiVersion)
bool contains_error(Json::Value const &json)
Returns true if the json contains an rpc error specification.
static constexpr std::integral_constant< unsigned, Version > apiVersion
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
void forAllApiVersions(Fn const &fn, Args &&... args)