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/RelationalDBInterfaceSqlite.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<RelationalDBInterfaceSqlite*>(
124  &env.app().getRelationalDBInterface())
125  ->getLedgerCountMinMax();
126 
127  BEAST_EXPECT(actualRows == rows);
128  BEAST_EXPECT(actualFirst == first);
129  BEAST_EXPECT(actualLast == first + rows - 1);
130  }
131 
132  void
133  transactionCheck(jtx::Env& env, int const rows)
134  {
135  BEAST_EXPECT(
136  dynamic_cast<RelationalDBInterfaceSqlite*>(
137  &env.app().getRelationalDBInterface())
138  ->getTransactionCount() == rows);
139  }
140 
141  void
142  accountTransactionCheck(jtx::Env& env, int const rows)
143  {
144  BEAST_EXPECT(
145  dynamic_cast<RelationalDBInterfaceSqlite*>(
146  &env.app().getRelationalDBInterface())
147  ->getAccountTransactionCount() == rows);
148  }
149 
150  int
152  {
153  using namespace std::chrono_literals;
154 
155  auto& store = env.app().getSHAMapStore();
156 
157  int ledgerSeq = 3;
158  store.rendezvous();
159  BEAST_EXPECT(!store.getLastRotated());
160 
161  env.close();
162  store.rendezvous();
163 
164  auto ledger = env.rpc("ledger", "validated");
165  BEAST_EXPECT(goodLedger(env, ledger, std::to_string(ledgerSeq++)));
166 
167  BEAST_EXPECT(store.getLastRotated() == ledgerSeq - 1);
168  return ledgerSeq;
169  }
170 
171 public:
172  void
174  {
175  using namespace std::chrono_literals;
176 
177  testcase("clearPrior");
178  using namespace jtx;
179 
180  Env env(*this, envconfig(onlineDelete));
181 
182  auto& store = env.app().getSHAMapStore();
183  env.fund(XRP(10000), noripple("alice"));
184 
185  ledgerCheck(env, 1, 2);
186  transactionCheck(env, 0);
187  accountTransactionCheck(env, 0);
188 
190 
191  auto ledgerTmp = env.rpc("ledger", "0");
192  BEAST_EXPECT(bad(ledgerTmp));
193 
194  ledgers.emplace(std::make_pair(1, env.rpc("ledger", "1")));
195  BEAST_EXPECT(goodLedger(env, ledgers[1], "1"));
196 
197  ledgers.emplace(std::make_pair(2, env.rpc("ledger", "2")));
198  BEAST_EXPECT(goodLedger(env, ledgers[2], "2"));
199 
200  ledgerTmp = env.rpc("ledger", "current");
201  BEAST_EXPECT(goodLedger(env, ledgerTmp, "3"));
202 
203  ledgerTmp = env.rpc("ledger", "4");
204  BEAST_EXPECT(bad(ledgerTmp));
205 
206  ledgerTmp = env.rpc("ledger", "100");
207  BEAST_EXPECT(bad(ledgerTmp));
208 
209  auto const firstSeq = waitForReady(env);
210  auto lastRotated = firstSeq - 1;
211 
212  for (auto i = firstSeq + 1; i < deleteInterval + firstSeq; ++i)
213  {
214  env.fund(XRP(10000), noripple("test" + std::to_string(i)));
215  env.close();
216 
217  ledgerTmp = env.rpc("ledger", "current");
218  BEAST_EXPECT(goodLedger(env, ledgerTmp, std::to_string(i)));
219  }
220  BEAST_EXPECT(store.getLastRotated() == lastRotated);
221 
222  for (auto i = 3; i < deleteInterval + lastRotated; ++i)
223  {
224  ledgers.emplace(
225  std::make_pair(i, env.rpc("ledger", std::to_string(i))));
226  BEAST_EXPECT(
227  goodLedger(env, ledgers[i], std::to_string(i), true) &&
228  getHash(ledgers[i]).length());
229  }
230 
231  ledgerCheck(env, deleteInterval + 1, 2);
234 
235  {
236  // Closing one more ledger triggers a rotate
237  env.close();
238 
239  auto ledger = env.rpc("ledger", "current");
240  BEAST_EXPECT(
241  goodLedger(env, ledger, std::to_string(deleteInterval + 4)));
242  }
243 
244  store.rendezvous();
245 
246  BEAST_EXPECT(store.getLastRotated() == deleteInterval + 3);
247  lastRotated = store.getLastRotated();
248  BEAST_EXPECT(lastRotated == 11);
249 
250  // That took care of the fake hashes
251  ledgerCheck(env, deleteInterval + 1, 3);
254 
255  // The last iteration of this loop should trigger a rotate
256  for (auto i = lastRotated - 1; i < lastRotated + deleteInterval - 1;
257  ++i)
258  {
259  env.close();
260 
261  ledgerTmp = env.rpc("ledger", "current");
262  BEAST_EXPECT(goodLedger(env, ledgerTmp, std::to_string(i + 3)));
263 
264  ledgers.emplace(
265  std::make_pair(i, env.rpc("ledger", std::to_string(i))));
266  BEAST_EXPECT(
267  store.getLastRotated() == lastRotated ||
268  i == lastRotated + deleteInterval - 2);
269  BEAST_EXPECT(
270  goodLedger(env, ledgers[i], std::to_string(i), true) &&
271  getHash(ledgers[i]).length());
272  }
273 
274  store.rendezvous();
275 
276  BEAST_EXPECT(store.getLastRotated() == deleteInterval + lastRotated);
277 
278  ledgerCheck(env, deleteInterval + 1, lastRotated);
279  transactionCheck(env, 0);
280  accountTransactionCheck(env, 0);
281  }
282 
283  void
285  {
286  testcase("automatic online_delete");
287  using namespace jtx;
288  using namespace std::chrono_literals;
289 
290  Env env(*this, envconfig(onlineDelete));
291  auto& store = env.app().getSHAMapStore();
292 
293  auto ledgerSeq = waitForReady(env);
294  auto lastRotated = ledgerSeq - 1;
295  BEAST_EXPECT(store.getLastRotated() == lastRotated);
296  BEAST_EXPECT(lastRotated != 2);
297 
298  // Because advisory_delete is unset,
299  // "can_delete" is disabled.
300  auto const canDelete = env.rpc("can_delete");
301  BEAST_EXPECT(bad(canDelete, rpcNOT_ENABLED));
302 
303  // Close ledgers without triggering a rotate
304  for (; ledgerSeq < lastRotated + deleteInterval; ++ledgerSeq)
305  {
306  env.close();
307 
308  auto ledger = env.rpc("ledger", "validated");
309  BEAST_EXPECT(
310  goodLedger(env, ledger, std::to_string(ledgerSeq), true));
311  }
312 
313  store.rendezvous();
314 
315  // The database will always have back to ledger 2,
316  // regardless of lastRotated.
317  ledgerCheck(env, ledgerSeq - 2, 2);
318  BEAST_EXPECT(lastRotated == store.getLastRotated());
319 
320  {
321  // Closing one more ledger triggers a rotate
322  env.close();
323 
324  auto ledger = env.rpc("ledger", "validated");
325  BEAST_EXPECT(
326  goodLedger(env, ledger, std::to_string(ledgerSeq++), true));
327  }
328 
329  store.rendezvous();
330 
331  ledgerCheck(env, ledgerSeq - lastRotated, lastRotated);
332  BEAST_EXPECT(lastRotated != store.getLastRotated());
333 
334  lastRotated = store.getLastRotated();
335 
336  // Close enough ledgers to trigger another rotate
337  for (; ledgerSeq < lastRotated + deleteInterval + 1; ++ledgerSeq)
338  {
339  env.close();
340 
341  auto ledger = env.rpc("ledger", "validated");
342  BEAST_EXPECT(
343  goodLedger(env, ledger, std::to_string(ledgerSeq), true));
344  }
345 
346  store.rendezvous();
347 
348  ledgerCheck(env, deleteInterval + 1, lastRotated);
349  BEAST_EXPECT(lastRotated != store.getLastRotated());
350  }
351 
352  void
354  {
355  testcase("online_delete with advisory_delete");
356  using namespace jtx;
357  using namespace std::chrono_literals;
358 
359  // Same config with advisory_delete enabled
360  Env env(*this, envconfig(advisoryDelete));
361  auto& store = env.app().getSHAMapStore();
362 
363  auto ledgerSeq = waitForReady(env);
364  auto lastRotated = ledgerSeq - 1;
365  BEAST_EXPECT(store.getLastRotated() == lastRotated);
366  BEAST_EXPECT(lastRotated != 2);
367 
368  auto canDelete = env.rpc("can_delete");
369  BEAST_EXPECT(!RPC::contains_error(canDelete[jss::result]));
370  BEAST_EXPECT(canDelete[jss::result][jss::can_delete] == 0);
371 
372  canDelete = env.rpc("can_delete", "never");
373  BEAST_EXPECT(!RPC::contains_error(canDelete[jss::result]));
374  BEAST_EXPECT(canDelete[jss::result][jss::can_delete] == 0);
375 
376  auto const firstBatch = deleteInterval + ledgerSeq;
377  for (; ledgerSeq < firstBatch; ++ledgerSeq)
378  {
379  env.close();
380 
381  auto ledger = env.rpc("ledger", "validated");
382  BEAST_EXPECT(
383  goodLedger(env, ledger, std::to_string(ledgerSeq), true));
384  }
385 
386  store.rendezvous();
387 
388  ledgerCheck(env, ledgerSeq - 2, 2);
389  BEAST_EXPECT(lastRotated == store.getLastRotated());
390 
391  // This does not kick off a cleanup
392  canDelete = env.rpc(
393  "can_delete", std::to_string(ledgerSeq + deleteInterval / 2));
394  BEAST_EXPECT(!RPC::contains_error(canDelete[jss::result]));
395  BEAST_EXPECT(
396  canDelete[jss::result][jss::can_delete] ==
397  ledgerSeq + deleteInterval / 2);
398 
399  store.rendezvous();
400 
401  ledgerCheck(env, ledgerSeq - 2, 2);
402  BEAST_EXPECT(store.getLastRotated() == lastRotated);
403 
404  {
405  // This kicks off a cleanup, but it stays small.
406  env.close();
407 
408  auto ledger = env.rpc("ledger", "validated");
409  BEAST_EXPECT(
410  goodLedger(env, ledger, std::to_string(ledgerSeq++), true));
411  }
412 
413  store.rendezvous();
414 
415  ledgerCheck(env, ledgerSeq - lastRotated, lastRotated);
416 
417  BEAST_EXPECT(store.getLastRotated() == ledgerSeq - 1);
418  lastRotated = ledgerSeq - 1;
419 
420  for (; ledgerSeq < lastRotated + deleteInterval; ++ledgerSeq)
421  {
422  // No cleanups in this loop.
423  env.close();
424 
425  auto ledger = env.rpc("ledger", "validated");
426  BEAST_EXPECT(
427  goodLedger(env, ledger, std::to_string(ledgerSeq), true));
428  }
429 
430  store.rendezvous();
431 
432  BEAST_EXPECT(store.getLastRotated() == lastRotated);
433 
434  {
435  // This kicks off another cleanup.
436  env.close();
437 
438  auto ledger = env.rpc("ledger", "validated");
439  BEAST_EXPECT(
440  goodLedger(env, ledger, std::to_string(ledgerSeq++), true));
441  }
442 
443  store.rendezvous();
444 
445  ledgerCheck(env, ledgerSeq - firstBatch, firstBatch);
446 
447  BEAST_EXPECT(store.getLastRotated() == ledgerSeq - 1);
448  lastRotated = ledgerSeq - 1;
449 
450  // This does not kick off a cleanup
451  canDelete = env.rpc("can_delete", "always");
452  BEAST_EXPECT(!RPC::contains_error(canDelete[jss::result]));
453  BEAST_EXPECT(
454  canDelete[jss::result][jss::can_delete] ==
456 
457  for (; ledgerSeq < lastRotated + deleteInterval; ++ledgerSeq)
458  {
459  // No cleanups in this loop.
460  env.close();
461 
462  auto ledger = env.rpc("ledger", "validated");
463  BEAST_EXPECT(
464  goodLedger(env, ledger, std::to_string(ledgerSeq), true));
465  }
466 
467  store.rendezvous();
468 
469  BEAST_EXPECT(store.getLastRotated() == lastRotated);
470 
471  {
472  // This kicks off another cleanup.
473  env.close();
474 
475  auto ledger = env.rpc("ledger", "validated");
476  BEAST_EXPECT(
477  goodLedger(env, ledger, std::to_string(ledgerSeq++), true));
478  }
479 
480  store.rendezvous();
481 
482  ledgerCheck(env, ledgerSeq - lastRotated, lastRotated);
483 
484  BEAST_EXPECT(store.getLastRotated() == ledgerSeq - 1);
485  lastRotated = ledgerSeq - 1;
486 
487  // This does not kick off a cleanup
488  canDelete = env.rpc("can_delete", "now");
489  BEAST_EXPECT(!RPC::contains_error(canDelete[jss::result]));
490  BEAST_EXPECT(canDelete[jss::result][jss::can_delete] == ledgerSeq - 1);
491 
492  for (; ledgerSeq < lastRotated + deleteInterval; ++ledgerSeq)
493  {
494  // No cleanups in this loop.
495  env.close();
496 
497  auto ledger = env.rpc("ledger", "validated");
498  BEAST_EXPECT(
499  goodLedger(env, ledger, std::to_string(ledgerSeq), true));
500  }
501 
502  store.rendezvous();
503 
504  BEAST_EXPECT(store.getLastRotated() == lastRotated);
505 
506  {
507  // This kicks off another cleanup.
508  env.close();
509 
510  auto ledger = env.rpc("ledger", "validated");
511  BEAST_EXPECT(
512  goodLedger(env, ledger, std::to_string(ledgerSeq++), true));
513  }
514 
515  store.rendezvous();
516 
517  ledgerCheck(env, ledgerSeq - lastRotated, lastRotated);
518 
519  BEAST_EXPECT(store.getLastRotated() == ledgerSeq - 1);
520  lastRotated = ledgerSeq - 1;
521  }
522 
523  void
524  run() override
525  {
526  testClear();
527  testAutomatic();
528  testCanDelete();
529  }
530 };
531 
532 // VFALCO This test fails because of thread asynchronous issues
534 
535 } // namespace test
536 } // namespace ripple
ripple::test::jtx::json
Inject raw JSON.
Definition: jtx_json.h:31
ripple::test::SHAMapStore_test::run
void run() override
Definition: SHAMapStore_test.cpp:524
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:103
ripple::LedgerInfo::hash
uint256 hash
Definition: ReadView.h:100
ripple::Application::getRelationalDBInterface
virtual RelationalDBInterface & getRelationalDBInterface()=0
ripple::test::SHAMapStore_test::testAutomatic
void testAutomatic()
Definition: SHAMapStore_test.cpp:284
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::RelationalDBInterfaceSqlite::getAccountTransactionCount
virtual std::size_t getAccountTransactionCount()=0
getAccountTransactionCount Returns number of account transactions.
ripple::test::jtx::Env::app
Application & app()
Definition: Env.h:240
ripple::LedgerInfo::seq
LedgerIndex seq
Definition: ReadView.h:92
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::LedgerInfo::txHash
uint256 txHash
Definition: ReadView.h:101
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:123
std::chrono::time_point::time_since_epoch
T time_since_epoch(T... args)
ripple::RelationalDBInterface::getLedgerInfoByIndex
virtual std::optional< LedgerInfo > getLedgerInfoByIndex(LedgerIndex ledgerSeq)=0
getLedgerInfoByIndex Returns ledger by its sequence.
ripple::RPC::contains_error
bool contains_error(Json::Value const &json)
Returns true if the json contains an rpc error specification.
Definition: ErrorCodes.cpp:225
ripple::RelationalDBInterfaceSqlite
Definition: RelationalDBInterfaceSqlite.h:27
ripple::LedgerInfo::closeFlags
int closeFlags
Definition: ReadView.h:114
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:133
ripple::LedgerInfo::drops
XRPAmount drops
Definition: ReadView.h:105
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:353
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:173
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:117
ripple::test::jtx::Env::fund
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
Definition: Env.cpp:225
ripple::test::SHAMapStore_test::accountTransactionCheck
void accountTransactionCheck(jtx::Env &env, int const rows)
Definition: SHAMapStore_test.cpp:142
ripple::test::SHAMapStore_test::waitForReady
int waitForReady(jtx::Env &env)
Definition: SHAMapStore_test.cpp:151
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:39
std::make_pair
T make_pair(T... args)
ripple::LedgerInfo
Information about the notional ledger backing the view.
Definition: ReadView.h:84
ripple::Application::getSHAMapStore
virtual SHAMapStore & getSHAMapStore()=0
ripple::test::SHAMapStore_test
Definition: SHAMapStore_test.cpp:31
ripple::RelationalDBInterfaceSqlite::getTransactionCount
virtual std::size_t getTransactionCount()=0
getTransactionCount Returns number of transactions.
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:102
ripple::test::jtx::Env
A transaction testing environment.
Definition: Env.h:115
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:683
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:93
ripple::test::BEAST_DEFINE_TESTSUITE
BEAST_DEFINE_TESTSUITE(DeliverMin, app, ripple)