rippled
SHAMapStore_test.cpp
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2012-2015 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 <ripple/app/main/Application.h>
21 #include <ripple/app/misc/SHAMapStore.h>
22 #include <ripple/app/rdb/backend/SQLiteDatabase.h>
23 #include <ripple/core/ConfigSections.h>
24 #include <ripple/protocol/jss.h>
25 #include <test/jtx.h>
26 #include <test/jtx/envconfig.h>
27 
28 namespace ripple {
29 namespace test {
30 
31 class SHAMapStore_test : public beast::unit_test::suite
32 {
33  static auto const deleteInterval = 8;
34 
35  static auto
37  {
38  cfg->LEDGER_HISTORY = deleteInterval;
39  auto& section = cfg->section(ConfigSection::nodeDatabase());
40  section.set("online_delete", std::to_string(deleteInterval));
41  return cfg;
42  }
43 
44  static auto
46  {
47  cfg = onlineDelete(std::move(cfg));
48  cfg->section(ConfigSection::nodeDatabase()).set("advisory_delete", "1");
49  return cfg;
50  }
51 
52  bool
54  jtx::Env& env,
55  Json::Value const& json,
56  std::string ledgerID,
57  bool checkDB = false)
58  {
59  auto good = json.isMember(jss::result) &&
60  !RPC::contains_error(json[jss::result]) &&
61  json[jss::result][jss::ledger][jss::ledger_index] == ledgerID;
62  if (!good || !checkDB)
63  return good;
64 
65  auto const seq = json[jss::result][jss::ledger_index].asUInt();
66 
69  if (!oinfo)
70  return false;
71  const LedgerInfo& info = oinfo.value();
72 
73  const std::string outHash = to_string(info.hash);
74  const LedgerIndex outSeq = info.seq;
75  const std::string outParentHash = to_string(info.parentHash);
76  const std::string outDrops = to_string(info.drops);
77  const std::uint64_t outCloseTime =
78  info.closeTime.time_since_epoch().count();
79  const std::uint64_t outParentCloseTime =
80  info.parentCloseTime.time_since_epoch().count();
81  const std::uint64_t outCloseTimeResolution =
83  const std::uint64_t outCloseFlags = info.closeFlags;
84  const std::string outAccountHash = to_string(info.accountHash);
85  const std::string outTxHash = to_string(info.txHash);
86 
87  auto const& ledger = json[jss::result][jss::ledger];
88  return outHash == ledger[jss::hash].asString() && outSeq == seq &&
89  outParentHash == ledger[jss::parent_hash].asString() &&
90  outDrops == ledger[jss::total_coins].asString() &&
91  outCloseTime == ledger[jss::close_time].asUInt() &&
92  outParentCloseTime == ledger[jss::parent_close_time].asUInt() &&
93  outCloseTimeResolution ==
94  ledger[jss::close_time_resolution].asUInt() &&
95  outCloseFlags == ledger[jss::close_flags].asUInt() &&
96  outAccountHash == ledger[jss::account_hash].asString() &&
97  outTxHash == ledger[jss::transaction_hash].asString();
98  }
99 
100  bool
102  {
103  return json.isMember(jss::result) &&
104  RPC::contains_error(json[jss::result]) &&
105  json[jss::result][jss::error_code] == error;
106  }
107 
110  {
111  BEAST_EXPECT(
112  json.isMember(jss::result) &&
113  json[jss::result].isMember(jss::ledger) &&
114  json[jss::result][jss::ledger].isMember(jss::hash) &&
115  json[jss::result][jss::ledger][jss::hash].isString());
116  return json[jss::result][jss::ledger][jss::hash].asString();
117  }
118 
119  void
120  ledgerCheck(jtx::Env& env, int const rows, int const first)
121  {
122  const auto [actualRows, actualFirst, actualLast] =
123  dynamic_cast<SQLiteDatabase*>(&env.app().getRelationalDatabase())
124  ->getLedgerCountMinMax();
125 
126  BEAST_EXPECT(actualRows == rows);
127  BEAST_EXPECT(actualFirst == first);
128  BEAST_EXPECT(actualLast == first + rows - 1);
129  }
130 
131  void
132  transactionCheck(jtx::Env& env, int const rows)
133  {
134  BEAST_EXPECT(
135  dynamic_cast<SQLiteDatabase*>(&env.app().getRelationalDatabase())
136  ->getTransactionCount() == rows);
137  }
138 
139  void
140  accountTransactionCheck(jtx::Env& env, int const rows)
141  {
142  BEAST_EXPECT(
143  dynamic_cast<SQLiteDatabase*>(&env.app().getRelationalDatabase())
144  ->getAccountTransactionCount() == rows);
145  }
146 
147  int
149  {
150  using namespace std::chrono_literals;
151 
152  auto& store = env.app().getSHAMapStore();
153 
154  int ledgerSeq = 3;
155  store.rendezvous();
156  BEAST_EXPECT(!store.getLastRotated());
157 
158  env.close();
159  store.rendezvous();
160 
161  auto ledger = env.rpc("ledger", "validated");
162  BEAST_EXPECT(goodLedger(env, ledger, std::to_string(ledgerSeq++)));
163 
164  BEAST_EXPECT(store.getLastRotated() == ledgerSeq - 1);
165  return ledgerSeq;
166  }
167 
168 public:
169  void
171  {
172  using namespace std::chrono_literals;
173 
174  testcase("clearPrior");
175  using namespace jtx;
176 
177  Env env(*this, envconfig(onlineDelete));
178 
179  auto& store = env.app().getSHAMapStore();
180  env.fund(XRP(10000), noripple("alice"));
181 
182  ledgerCheck(env, 1, 2);
183  transactionCheck(env, 0);
184  accountTransactionCheck(env, 0);
185 
187 
188  auto ledgerTmp = env.rpc("ledger", "0");
189  BEAST_EXPECT(bad(ledgerTmp));
190 
191  ledgers.emplace(std::make_pair(1, env.rpc("ledger", "1")));
192  BEAST_EXPECT(goodLedger(env, ledgers[1], "1"));
193 
194  ledgers.emplace(std::make_pair(2, env.rpc("ledger", "2")));
195  BEAST_EXPECT(goodLedger(env, ledgers[2], "2"));
196 
197  ledgerTmp = env.rpc("ledger", "current");
198  BEAST_EXPECT(goodLedger(env, ledgerTmp, "3"));
199 
200  ledgerTmp = env.rpc("ledger", "4");
201  BEAST_EXPECT(bad(ledgerTmp));
202 
203  ledgerTmp = env.rpc("ledger", "100");
204  BEAST_EXPECT(bad(ledgerTmp));
205 
206  auto const firstSeq = waitForReady(env);
207  auto lastRotated = firstSeq - 1;
208 
209  for (auto i = firstSeq + 1; i < deleteInterval + firstSeq; ++i)
210  {
211  env.fund(XRP(10000), noripple("test" + std::to_string(i)));
212  env.close();
213 
214  ledgerTmp = env.rpc("ledger", "current");
215  BEAST_EXPECT(goodLedger(env, ledgerTmp, std::to_string(i)));
216  }
217  BEAST_EXPECT(store.getLastRotated() == lastRotated);
218 
219  for (auto i = 3; i < deleteInterval + lastRotated; ++i)
220  {
221  ledgers.emplace(
222  std::make_pair(i, env.rpc("ledger", std::to_string(i))));
223  BEAST_EXPECT(
224  goodLedger(env, ledgers[i], std::to_string(i), true) &&
225  getHash(ledgers[i]).length());
226  }
227 
228  ledgerCheck(env, deleteInterval + 1, 2);
231 
232  {
233  // Closing one more ledger triggers a rotate
234  env.close();
235 
236  auto ledger = env.rpc("ledger", "current");
237  BEAST_EXPECT(
238  goodLedger(env, ledger, std::to_string(deleteInterval + 4)));
239  }
240 
241  store.rendezvous();
242 
243  BEAST_EXPECT(store.getLastRotated() == deleteInterval + 3);
244  lastRotated = store.getLastRotated();
245  BEAST_EXPECT(lastRotated == 11);
246 
247  // That took care of the fake hashes
248  ledgerCheck(env, deleteInterval + 1, 3);
251 
252  // The last iteration of this loop should trigger a rotate
253  for (auto i = lastRotated - 1; i < lastRotated + deleteInterval - 1;
254  ++i)
255  {
256  env.close();
257 
258  ledgerTmp = env.rpc("ledger", "current");
259  BEAST_EXPECT(goodLedger(env, ledgerTmp, std::to_string(i + 3)));
260 
261  ledgers.emplace(
262  std::make_pair(i, env.rpc("ledger", std::to_string(i))));
263  BEAST_EXPECT(
264  store.getLastRotated() == lastRotated ||
265  i == lastRotated + deleteInterval - 2);
266  BEAST_EXPECT(
267  goodLedger(env, ledgers[i], std::to_string(i), true) &&
268  getHash(ledgers[i]).length());
269  }
270 
271  store.rendezvous();
272 
273  BEAST_EXPECT(store.getLastRotated() == deleteInterval + lastRotated);
274 
275  ledgerCheck(env, deleteInterval + 1, lastRotated);
276  transactionCheck(env, 0);
277  accountTransactionCheck(env, 0);
278  }
279 
280  void
282  {
283  testcase("automatic online_delete");
284  using namespace jtx;
285  using namespace std::chrono_literals;
286 
287  Env env(*this, envconfig(onlineDelete));
288  auto& store = env.app().getSHAMapStore();
289 
290  auto ledgerSeq = waitForReady(env);
291  auto lastRotated = ledgerSeq - 1;
292  BEAST_EXPECT(store.getLastRotated() == lastRotated);
293  BEAST_EXPECT(lastRotated != 2);
294 
295  // Because advisory_delete is unset,
296  // "can_delete" is disabled.
297  auto const canDelete = env.rpc("can_delete");
298  BEAST_EXPECT(bad(canDelete, rpcNOT_ENABLED));
299 
300  // Close ledgers without triggering a rotate
301  for (; ledgerSeq < lastRotated + deleteInterval; ++ledgerSeq)
302  {
303  env.close();
304 
305  auto ledger = env.rpc("ledger", "validated");
306  BEAST_EXPECT(
307  goodLedger(env, ledger, std::to_string(ledgerSeq), true));
308  }
309 
310  store.rendezvous();
311 
312  // The database will always have back to ledger 2,
313  // regardless of lastRotated.
314  ledgerCheck(env, ledgerSeq - 2, 2);
315  BEAST_EXPECT(lastRotated == store.getLastRotated());
316 
317  {
318  // Closing one more ledger triggers a rotate
319  env.close();
320 
321  auto ledger = env.rpc("ledger", "validated");
322  BEAST_EXPECT(
323  goodLedger(env, ledger, std::to_string(ledgerSeq++), true));
324  }
325 
326  store.rendezvous();
327 
328  ledgerCheck(env, ledgerSeq - lastRotated, lastRotated);
329  BEAST_EXPECT(lastRotated != store.getLastRotated());
330 
331  lastRotated = store.getLastRotated();
332 
333  // Close enough ledgers to trigger another rotate
334  for (; ledgerSeq < lastRotated + deleteInterval + 1; ++ledgerSeq)
335  {
336  env.close();
337 
338  auto ledger = env.rpc("ledger", "validated");
339  BEAST_EXPECT(
340  goodLedger(env, ledger, std::to_string(ledgerSeq), true));
341  }
342 
343  store.rendezvous();
344 
345  ledgerCheck(env, deleteInterval + 1, lastRotated);
346  BEAST_EXPECT(lastRotated != store.getLastRotated());
347  }
348 
349  void
351  {
352  testcase("online_delete with advisory_delete");
353  using namespace jtx;
354  using namespace std::chrono_literals;
355 
356  // Same config with advisory_delete enabled
357  Env env(*this, envconfig(advisoryDelete));
358  auto& store = env.app().getSHAMapStore();
359 
360  auto ledgerSeq = waitForReady(env);
361  auto lastRotated = ledgerSeq - 1;
362  BEAST_EXPECT(store.getLastRotated() == lastRotated);
363  BEAST_EXPECT(lastRotated != 2);
364 
365  auto canDelete = env.rpc("can_delete");
366  BEAST_EXPECT(!RPC::contains_error(canDelete[jss::result]));
367  BEAST_EXPECT(canDelete[jss::result][jss::can_delete] == 0);
368 
369  canDelete = env.rpc("can_delete", "never");
370  BEAST_EXPECT(!RPC::contains_error(canDelete[jss::result]));
371  BEAST_EXPECT(canDelete[jss::result][jss::can_delete] == 0);
372 
373  auto const firstBatch = deleteInterval + ledgerSeq;
374  for (; ledgerSeq < firstBatch; ++ledgerSeq)
375  {
376  env.close();
377 
378  auto ledger = env.rpc("ledger", "validated");
379  BEAST_EXPECT(
380  goodLedger(env, ledger, std::to_string(ledgerSeq), true));
381  }
382 
383  store.rendezvous();
384 
385  ledgerCheck(env, ledgerSeq - 2, 2);
386  BEAST_EXPECT(lastRotated == store.getLastRotated());
387 
388  // This does not kick off a cleanup
389  canDelete = env.rpc(
390  "can_delete", std::to_string(ledgerSeq + deleteInterval / 2));
391  BEAST_EXPECT(!RPC::contains_error(canDelete[jss::result]));
392  BEAST_EXPECT(
393  canDelete[jss::result][jss::can_delete] ==
394  ledgerSeq + deleteInterval / 2);
395 
396  store.rendezvous();
397 
398  ledgerCheck(env, ledgerSeq - 2, 2);
399  BEAST_EXPECT(store.getLastRotated() == lastRotated);
400 
401  {
402  // This kicks off a cleanup, but it stays small.
403  env.close();
404 
405  auto ledger = env.rpc("ledger", "validated");
406  BEAST_EXPECT(
407  goodLedger(env, ledger, std::to_string(ledgerSeq++), true));
408  }
409 
410  store.rendezvous();
411 
412  ledgerCheck(env, ledgerSeq - lastRotated, lastRotated);
413 
414  BEAST_EXPECT(store.getLastRotated() == ledgerSeq - 1);
415  lastRotated = ledgerSeq - 1;
416 
417  for (; ledgerSeq < lastRotated + deleteInterval; ++ledgerSeq)
418  {
419  // No cleanups in this loop.
420  env.close();
421 
422  auto ledger = env.rpc("ledger", "validated");
423  BEAST_EXPECT(
424  goodLedger(env, ledger, std::to_string(ledgerSeq), true));
425  }
426 
427  store.rendezvous();
428 
429  BEAST_EXPECT(store.getLastRotated() == lastRotated);
430 
431  {
432  // This kicks off another cleanup.
433  env.close();
434 
435  auto ledger = env.rpc("ledger", "validated");
436  BEAST_EXPECT(
437  goodLedger(env, ledger, std::to_string(ledgerSeq++), true));
438  }
439 
440  store.rendezvous();
441 
442  ledgerCheck(env, ledgerSeq - firstBatch, firstBatch);
443 
444  BEAST_EXPECT(store.getLastRotated() == ledgerSeq - 1);
445  lastRotated = ledgerSeq - 1;
446 
447  // This does not kick off a cleanup
448  canDelete = env.rpc("can_delete", "always");
449  BEAST_EXPECT(!RPC::contains_error(canDelete[jss::result]));
450  BEAST_EXPECT(
451  canDelete[jss::result][jss::can_delete] ==
453 
454  for (; ledgerSeq < lastRotated + deleteInterval; ++ledgerSeq)
455  {
456  // No cleanups in this loop.
457  env.close();
458 
459  auto ledger = env.rpc("ledger", "validated");
460  BEAST_EXPECT(
461  goodLedger(env, ledger, std::to_string(ledgerSeq), true));
462  }
463 
464  store.rendezvous();
465 
466  BEAST_EXPECT(store.getLastRotated() == lastRotated);
467 
468  {
469  // This kicks off another cleanup.
470  env.close();
471 
472  auto ledger = env.rpc("ledger", "validated");
473  BEAST_EXPECT(
474  goodLedger(env, ledger, std::to_string(ledgerSeq++), true));
475  }
476 
477  store.rendezvous();
478 
479  ledgerCheck(env, ledgerSeq - lastRotated, lastRotated);
480 
481  BEAST_EXPECT(store.getLastRotated() == ledgerSeq - 1);
482  lastRotated = ledgerSeq - 1;
483 
484  // This does not kick off a cleanup
485  canDelete = env.rpc("can_delete", "now");
486  BEAST_EXPECT(!RPC::contains_error(canDelete[jss::result]));
487  BEAST_EXPECT(canDelete[jss::result][jss::can_delete] == ledgerSeq - 1);
488 
489  for (; ledgerSeq < lastRotated + deleteInterval; ++ledgerSeq)
490  {
491  // No cleanups in this loop.
492  env.close();
493 
494  auto ledger = env.rpc("ledger", "validated");
495  BEAST_EXPECT(
496  goodLedger(env, ledger, std::to_string(ledgerSeq), true));
497  }
498 
499  store.rendezvous();
500 
501  BEAST_EXPECT(store.getLastRotated() == lastRotated);
502 
503  {
504  // This kicks off another cleanup.
505  env.close();
506 
507  auto ledger = env.rpc("ledger", "validated");
508  BEAST_EXPECT(
509  goodLedger(env, ledger, std::to_string(ledgerSeq++), true));
510  }
511 
512  store.rendezvous();
513 
514  ledgerCheck(env, ledgerSeq - lastRotated, lastRotated);
515 
516  BEAST_EXPECT(store.getLastRotated() == ledgerSeq - 1);
517  lastRotated = ledgerSeq - 1;
518  }
519 
520  void
521  run() override
522  {
523  testClear();
524  testAutomatic();
525  testCanDelete();
526  }
527 };
528 
529 // VFALCO This test fails because of thread asynchronous issues
531 
532 } // namespace test
533 } // namespace ripple
ripple::SQLiteDatabase
Definition: SQLiteDatabase.h:27
ripple::test::jtx::json
Inject raw JSON.
Definition: jtx_json.h:31
ripple::test::SHAMapStore_test::run
void run() override
Definition: SHAMapStore_test.cpp:521
ripple::test::jtx::XRP
const XRP_t XRP
Converts to XRP Issue or STAmount.
Definition: amount.cpp:105
std::string
STL class.
ripple::LedgerInfo::parentHash
uint256 parentHash
Definition: ReadView.h:94
ripple::LedgerInfo::hash
uint256 hash
Definition: ReadView.h:91
ripple::test::SHAMapStore_test::testAutomatic
void testAutomatic()
Definition: SHAMapStore_test.cpp:281
ripple::SHAMapStore
class to create database, launch online delete thread, and related SQLite database
Definition: SHAMapStore.h:36
ripple::test::SHAMapStore_test::deleteInterval
static const auto deleteInterval
Definition: SHAMapStore_test.cpp:33
std::map::emplace
T emplace(T... args)
ripple::test::jtx::Env::app
Application & app()
Definition: Env.h:241
ripple::LedgerInfo::seq
LedgerIndex seq
Definition: ReadView.h:83
ripple::test::jtx::envconfig
std::unique_ptr< Config > envconfig()
creates and initializes a default configuration for jtx::Env
Definition: envconfig.h:49
ripple::rpcLGR_NOT_FOUND
@ rpcLGR_NOT_FOUND
Definition: ErrorCodes.h:72
ripple::RelationalDatabase::getLedgerInfoByIndex
virtual std::optional< LedgerInfo > getLedgerInfoByIndex(LedgerIndex ledgerSeq)=0
getLedgerInfoByIndex Returns a ledger by its sequence.
ripple::LedgerInfo::txHash
uint256 txHash
Definition: ReadView.h:92
ripple::SHAMapStore::rendezvous
virtual void rendezvous() const =0
ripple::error_code_i
error_code_i
Definition: ErrorCodes.h:40
ripple::test::SHAMapStore_test::advisoryDelete
static auto advisoryDelete(std::unique_ptr< Config > cfg)
Definition: SHAMapStore_test.cpp:45
ripple::LedgerInfo::closeTime
NetClock::time_point closeTime
Definition: ReadView.h:114
std::chrono::time_point::time_since_epoch
T time_since_epoch(T... args)
ripple::RPC::contains_error
bool contains_error(Json::Value const &json)
Returns true if the json contains an rpc error specification.
Definition: ErrorCodes.cpp:194
ripple::SQLiteDatabase::getTransactionCount
virtual std::size_t getTransactionCount()=0
getTransactionCount Returns the number of transactions.
ripple::Application::getRelationalDatabase
virtual RelationalDatabase & getRelationalDatabase()=0
ripple::SQLiteDatabase::getAccountTransactionCount
virtual std::size_t getAccountTransactionCount()=0
getAccountTransactionCount Returns the number of account transactions.
ripple::LedgerInfo::closeFlags
int closeFlags
Definition: ReadView.h:105
std::to_string
T to_string(T... args)
ripple::test::jtx::Env::close
bool close(NetClock::time_point closeTime, std::optional< std::chrono::milliseconds > consensusDelay=std::nullopt)
Close and advance the ledger.
Definition: Env.cpp:121
ripple::rpcNOT_ENABLED
@ rpcNOT_ENABLED
Definition: ErrorCodes.h:59
std::uint32_t
std::map
STL class.
ripple::test::SHAMapStore_test::transactionCheck
void transactionCheck(jtx::Env &env, int const rows)
Definition: SHAMapStore_test.cpp:132
ripple::LedgerInfo::drops
XRPAmount drops
Definition: ReadView.h:96
std::optional::value
T value(T... args)
ripple::test::jtx::seq
Set the sequence number on a JTx.
Definition: seq.h:33
ripple::test::SHAMapStore_test::testCanDelete
void testCanDelete()
Definition: SHAMapStore_test.cpp:350
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::test::jtx::noripple
std::array< Account, 1+sizeof...(Args)> noripple(Account const &account, Args const &... args)
Designate accounts as no-ripple in Env::fund.
Definition: Env.h:64
ripple::test::SHAMapStore_test::testClear
void testClear()
Definition: SHAMapStore_test.cpp:170
ripple::test::SHAMapStore_test::ledgerCheck
void ledgerCheck(jtx::Env &env, int const rows, int const first)
Definition: SHAMapStore_test.cpp:120
ripple::LedgerInfo::closeTimeResolution
NetClock::duration closeTimeResolution
Definition: ReadView.h:108
ripple::test::jtx::Env::fund
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
Definition: Env.cpp:228
ripple::test::SHAMapStore_test::accountTransactionCheck
void accountTransactionCheck(jtx::Env &env, int const rows)
Definition: SHAMapStore_test.cpp:140
ripple::test::SHAMapStore_test::waitForReady
int waitForReady(jtx::Env &env)
Definition: SHAMapStore_test.cpp:148
std::chrono::duration::count
T count(T... args)
ripple::test::SHAMapStore_test::goodLedger
bool goodLedger(jtx::Env &env, Json::Value const &json, std::string ledgerID, bool checkDB=false)
Definition: SHAMapStore_test.cpp:53
std::optional
ripple::to_string
std::string to_string(Manifest const &m)
Format the specified manifest to a string for debugging purposes.
Definition: app/misc/impl/Manifest.cpp:41
std::make_pair
T make_pair(T... args)
ripple::LedgerInfo
Information about the notional ledger backing the view.
Definition: ReadView.h:75
ripple::Application::getSHAMapStore
virtual SHAMapStore & getSHAMapStore()=0
ripple::test::SHAMapStore_test
Definition: SHAMapStore_test.cpp:31
ripple::test::SHAMapStore_test::onlineDelete
static auto onlineDelete(std::unique_ptr< Config > cfg)
Definition: SHAMapStore_test.cpp:36
std::unique_ptr
STL class.
std::numeric_limits
ripple::test::SHAMapStore_test::bad
bool bad(Json::Value const &json, error_code_i error=rpcLGR_NOT_FOUND)
Definition: SHAMapStore_test.cpp:101
ripple::LedgerInfo::accountHash
uint256 accountHash
Definition: ReadView.h:93
ripple::test::jtx::Env
A transaction testing environment.
Definition: Env.h:116
ripple::ConfigSection::nodeDatabase
static std::string nodeDatabase()
Definition: ConfigSections.h:33
ripple::test::jtx::Env::rpc
Json::Value rpc(std::unordered_map< std::string, std::string > const &headers, std::string const &cmd, Args &&... args)
Execute an RPC command.
Definition: Env.h:687
Json::Value
Represents a JSON value.
Definition: json_value.h:145
ripple::test::SHAMapStore_test::getHash
std::string getHash(Json::Value const &json)
Definition: SHAMapStore_test.cpp:109
ripple::LedgerInfo::parentCloseTime
NetClock::time_point parentCloseTime
Definition: ReadView.h:84
ripple::test::BEAST_DEFINE_TESTSUITE
BEAST_DEFINE_TESTSUITE(DeliverMin, app, ripple)