21#include <xrpld/app/ledger/LedgerMaster.h>
22#include <xrpld/rpc/detail/RPCHelpers.h>
23#include <xrpl/beast/unit_test.h>
24#include <xrpl/protocol/ErrorCodes.h>
25#include <xrpl/protocol/jss.h>
35 static constexpr char const*
hash1 =
36 "3020EB9E7BE24EF7D7A060CB051583EC117384636D1781AFB5B87F3E348DA489";
38 "BD8A3D72CA73DDE887AD63666EC2BAD07875CBA997A102579B5B95ECDFFEAED8";
41 "0000000000000000000000000000000000000000000000000000000000000000";
47 using namespace test::jtx;
53 BEAST_EXPECT(env.current()->info().seq == 5);
57 auto const result = env.rpc(
"ledger_request",
"arbitrary_text");
60 result[jss::result][jss::error_message] ==
61 "Ledger index too small");
65 auto const result = env.rpc(
"ledger_request",
"-1");
68 result[jss::result][jss::error_message] ==
69 "Ledger index too small");
73 auto const result = env.rpc(
"ledger_request",
"0");
76 result[jss::result][jss::error_message] ==
77 "Ledger index too small");
81 auto const result = env.rpc(
"ledger_request",
"1");
84 result[jss::result][jss::ledger_index] == 1 &&
85 result[jss::result].isMember(jss::ledger));
87 result[jss::result][jss::ledger].isMember(jss::ledger_hash) &&
88 result[jss::result][jss::ledger][jss::ledger_hash].isString());
92 auto const result = env.rpc(
"ledger_request",
"2");
95 result[jss::result][jss::ledger_index] == 2 &&
96 result[jss::result].isMember(jss::ledger));
98 result[jss::result][jss::ledger].isMember(jss::ledger_hash) &&
99 result[jss::result][jss::ledger][jss::ledger_hash].isString());
103 auto const result = env.rpc(
"ledger_request",
"3");
106 result[jss::result][jss::ledger_index] == 3 &&
107 result[jss::result].isMember(jss::ledger));
109 result[jss::result][jss::ledger].isMember(jss::ledger_hash) &&
110 result[jss::result][jss::ledger][jss::ledger_hash].isString());
112 auto const ledgerHash =
113 result[jss::result][jss::ledger][jss::ledger_hash].asString();
116 auto const r = env.rpc(
"ledger_request", ledgerHash);
119 r[jss::result][jss::ledger_index] == 3 &&
120 r[jss::result].isMember(jss::ledger));
122 r[jss::result][jss::ledger].isMember(jss::ledger_hash) &&
123 r[jss::result][jss::ledger][jss::ledger_hash] ==
131 auto const result = env.rpc(
"ledger_request", ledgerHash);
135 result[jss::result][jss::error_message] ==
136 "Invalid field 'ledger_hash'.");
142 auto const result = env.rpc(
"ledger_request", ledgerHash);
146 result[jss::result][jss::have_header] ==
false);
150 auto const result = env.rpc(
"ledger_request",
"4");
153 result[jss::result][jss::error_message] ==
154 "Ledger index too large");
158 auto const result = env.rpc(
"ledger_request",
"5");
161 result[jss::result][jss::error_message] ==
162 "Ledger index too large");
169 using namespace test::jtx;
172 Account
const gw{
"gateway"};
173 auto const USD = gw[
"USD"];
174 env.fund(XRP(100000), gw);
178 env.fund(XRP(1000),
"bob");
181 env.memoize(
"alice");
182 env.fund(XRP(1000),
"alice");
185 env.memoize(
"carol");
186 env.fund(XRP(1000),
"carol");
189 auto result = env.rpc(
"ledger_request",
"1")[jss::result];
190 BEAST_EXPECT(result[jss::ledger][jss::ledger_index] ==
"1");
192 result[jss::ledger][jss::total_coins] ==
"100000000000000000");
193 BEAST_EXPECT(result[jss::ledger][jss::closed] ==
true);
194 BEAST_EXPECT(result[jss::ledger][jss::ledger_hash] ==
hash1);
195 BEAST_EXPECT(result[jss::ledger][jss::parent_hash] ==
zerohash);
196 BEAST_EXPECT(result[jss::ledger][jss::account_hash] ==
accounthash1);
197 BEAST_EXPECT(result[jss::ledger][jss::transaction_hash] ==
zerohash);
199 result = env.rpc(
"ledger_request",
"2")[jss::result];
200 constexpr char const* hash2 =
201 "CCC3B3E88CCAC17F1BE6B4A648A55999411F19E3FE55EB721960EB0DF28EDDA5";
202 BEAST_EXPECT(result[jss::ledger][jss::ledger_index] ==
"2");
204 result[jss::ledger][jss::total_coins] ==
"100000000000000000");
205 BEAST_EXPECT(result[jss::ledger][jss::closed] ==
true);
206 BEAST_EXPECT(result[jss::ledger][jss::ledger_hash] == hash2);
207 BEAST_EXPECT(result[jss::ledger][jss::parent_hash] ==
hash1);
209 result[jss::ledger][jss::account_hash] ==
210 "3C834285F7F464FBE99AFEB84D354A968EB2CAA24523FF26797A973D906A3D29");
211 BEAST_EXPECT(result[jss::ledger][jss::transaction_hash] ==
zerohash);
213 result = env.rpc(
"ledger_request",
"3")[jss::result];
214 constexpr char const* hash3 =
215 "8D631B20BC989AF568FBA97375290544B0703A5ADC1CF9E9053580461690C9EE";
216 BEAST_EXPECT(result[jss::ledger][jss::ledger_index] ==
"3");
218 result[jss::ledger][jss::total_coins] ==
"99999999999999980");
219 BEAST_EXPECT(result[jss::ledger][jss::closed] ==
true);
220 BEAST_EXPECT(result[jss::ledger][jss::ledger_hash] == hash3);
221 BEAST_EXPECT(result[jss::ledger][jss::parent_hash] == hash2);
223 result[jss::ledger][jss::account_hash] ==
224 "BC9EF2A16BFF80BCFABA6FA84688D858D33BD0FA0435CAA9DF6DA4105A39A29E");
226 result[jss::ledger][jss::transaction_hash] ==
227 "0213EC486C058B3942FBE3DAC6839949A5C5B02B8B4244C8998EFDF04DBD8222");
229 result = env.rpc(
"ledger_request",
"4")[jss::result];
230 constexpr char const* hash4 =
231 "1A8E7098B23597E73094DADA58C9D62F3AB93A12C6F7666D56CA85A6CFDE530F";
232 BEAST_EXPECT(result[jss::ledger][jss::ledger_index] ==
"4");
234 result[jss::ledger][jss::total_coins] ==
"99999999999999960");
235 BEAST_EXPECT(result[jss::ledger][jss::closed] ==
true);
236 BEAST_EXPECT(result[jss::ledger][jss::ledger_hash] == hash4);
237 BEAST_EXPECT(result[jss::ledger][jss::parent_hash] == hash3);
239 result[jss::ledger][jss::account_hash] ==
240 "C690188F123C91355ADA8BDF4AC5B5C927076D3590C215096868A5255264C6DD");
242 result[jss::ledger][jss::transaction_hash] ==
243 "3CBDB8F42E04333E1642166BFB93AC9A7E1C6C067092CD5D881D6F3AB3D67E76");
245 result = env.rpc(
"ledger_request",
"5")[jss::result];
246 constexpr char const* hash5 =
247 "C6A222D71AE65D7B4F240009EAD5DEB20D7EEDE5A4064F28BBDBFEEB6FBE48E5";
248 BEAST_EXPECT(result[jss::ledger][jss::ledger_index] ==
"5");
250 result[jss::ledger][jss::total_coins] ==
"99999999999999940");
251 BEAST_EXPECT(result[jss::ledger][jss::closed] ==
true);
252 BEAST_EXPECT(result[jss::ledger][jss::ledger_hash] == hash5);
253 BEAST_EXPECT(result[jss::ledger][jss::parent_hash] == hash4);
255 result[jss::ledger][jss::account_hash] ==
256 "EA81CD9D36740736F00CB747E0D0E32D3C10B695823D961F0FB9A1CE7133DD4D");
258 result[jss::ledger][jss::transaction_hash] ==
259 "C3D086CD6BDB9E97AD1D513B2C049EF2840BD21D0B3E22D84EBBB89B6D2EF59D");
261 result = env.rpc(
"ledger_request",
"6")[jss::result];
262 BEAST_EXPECT(result[jss::error] ==
"invalidParams");
263 BEAST_EXPECT(result[jss::status] ==
"error");
264 BEAST_EXPECT(result[jss::error_message] ==
"Ledger index too large");
270 using namespace test::jtx;
272 Account
const gw{
"gateway"};
273 auto const USD = gw[
"USD"];
274 env.fund(XRP(100000), gw);
278 jvParams[jss::ledger_hash] =
279 "AB868A6CFEEC779C2FF845C0AF00A642259986AF40C01976A7F842B6918936C7";
280 jvParams[jss::ledger_index] =
"1";
281 auto result = env.rpc(
282 "json",
"ledger_request", jvParams.
toStyledString())[jss::result];
283 BEAST_EXPECT(result[jss::error] ==
"invalidParams");
284 BEAST_EXPECT(result[jss::status] ==
"error");
286 result[jss::error_message] ==
287 "Exactly one of ledger_hash and ledger_index can be set.");
291 env.timeKeeper().adjustCloseTime(
weeks{3});
292 result = env.rpc(
apiVersion,
"ledger_request",
"1")[jss::result];
293 BEAST_EXPECT(result[jss::status] ==
"error");
296 BEAST_EXPECT(result[jss::error] ==
"noCurrent");
298 result[jss::error_message] ==
"Current ledger is unavailable.");
302 BEAST_EXPECT(result[jss::error] ==
"notSynced");
304 result[jss::error_message] ==
"Not synced to the network.");
311 using namespace test::jtx;
312 using namespace std::chrono_literals;
317 Account
const gw{
"gateway"};
318 auto const USD = gw[
"USD"];
319 env.fund(XRP(100000), gw);
321 int const max_limit = 256;
323 for (
auto i = 0; i < max_limit + 10; i++)
326 env.fund(XRP(1000), bob);
330 auto result = env.rpc(
"ledger_request",
"1")[jss::result];
331 BEAST_EXPECT(result[jss::ledger][jss::ledger_index] ==
"1");
333 result[jss::ledger][jss::total_coins] ==
"100000000000000000");
334 BEAST_EXPECT(result[jss::ledger][jss::closed] ==
true);
335 BEAST_EXPECT(result[jss::ledger][jss::ledger_hash] ==
hash1);
336 BEAST_EXPECT(result[jss::ledger][jss::parent_hash] ==
zerohash);
337 BEAST_EXPECT(result[jss::ledger][jss::account_hash] ==
accounthash1);
338 BEAST_EXPECT(result[jss::ledger][jss::transaction_hash] ==
zerohash);
344 using namespace test::jtx;
345 Env env{*
this, envconfig(no_admin)};
346 Account
const gw{
"gateway"};
347 auto const USD = gw[
"USD"];
348 env.fund(XRP(100000), gw);
351 auto const result = env.rpc(
"ledger_request",
"1")[jss::result];
370BEAST_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)