rippled
Ledger.cpp
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2012, 2013 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/ledger/AcceptedLedger.h>
21 #include <ripple/app/ledger/InboundLedgers.h>
22 #include <ripple/app/ledger/Ledger.h>
23 #include <ripple/app/ledger/LedgerMaster.h>
24 #include <ripple/app/ledger/LedgerToJson.h>
25 #include <ripple/app/ledger/OrderBookDB.h>
26 #include <ripple/app/ledger/PendingSaves.h>
27 #include <ripple/app/ledger/TransactionMaster.h>
28 #include <ripple/app/main/Application.h>
29 #include <ripple/app/misc/HashRouter.h>
30 #include <ripple/app/misc/LoadFeeTrack.h>
31 #include <ripple/app/misc/NetworkOPs.h>
32 #include <ripple/basics/Log.h>
33 #include <ripple/basics/StringUtilities.h>
34 #include <ripple/basics/contract.h>
35 #include <ripple/beast/core/LexicalCast.h>
36 #include <ripple/consensus/LedgerTiming.h>
37 #include <ripple/core/Config.h>
38 #include <ripple/core/DatabaseCon.h>
39 #include <ripple/core/JobQueue.h>
40 #include <ripple/core/SociDB.h>
41 #include <ripple/json/to_string.h>
42 #include <ripple/nodestore/Database.h>
43 #include <ripple/protocol/HashPrefix.h>
44 #include <ripple/protocol/Indexes.h>
45 #include <ripple/protocol/PublicKey.h>
46 #include <ripple/protocol/SecretKey.h>
47 #include <ripple/protocol/UintTypes.h>
48 #include <ripple/protocol/digest.h>
49 #include <ripple/protocol/jss.h>
50 #include <boost/optional.hpp>
51 #include <cassert>
52 #include <utility>
53 
54 namespace ripple {
55 
57 
58 static uint256
60 {
61  // VFALCO This has to match addRaw in View.h.
62  return sha512Half(
64  std::uint32_t(info.seq),
65  std::uint64_t(info.drops.drops()),
66  info.parentHash,
67  info.txHash,
68  info.accountHash,
72  std::uint8_t(info.closeFlags));
73 }
74 
75 //------------------------------------------------------------------------------
76 
77 class Ledger::sles_iter_impl : public sles_type::iter_base
78 {
79 private:
81 
82 public:
83  sles_iter_impl() = delete;
85  operator=(sles_iter_impl const&) = delete;
86 
87  sles_iter_impl(sles_iter_impl const&) = default;
88 
90  {
91  }
92 
94  copy() const override
95  {
96  return std::make_unique<sles_iter_impl>(*this);
97  }
98 
99  bool
100  equal(base_type const& impl) const override
101  {
102  auto const& other = dynamic_cast<sles_iter_impl const&>(impl);
103  return iter_ == other.iter_;
104  }
105 
106  void
107  increment() override
108  {
109  ++iter_;
110  }
111 
113  dereference() const override
114  {
115  auto const item = *iter_;
116  SerialIter sit(item.slice());
117  return std::make_shared<SLE const>(sit, item.key());
118  }
119 };
120 
121 //------------------------------------------------------------------------------
122 
123 class Ledger::txs_iter_impl : public txs_type::iter_base
124 {
125 private:
126  bool metadata_;
128 
129 public:
130  txs_iter_impl() = delete;
132  operator=(txs_iter_impl const&) = delete;
133 
134  txs_iter_impl(txs_iter_impl const&) = default;
135 
137  : metadata_(metadata), iter_(iter)
138  {
139  }
140 
142  copy() const override
143  {
144  return std::make_unique<txs_iter_impl>(*this);
145  }
146 
147  bool
148  equal(base_type const& impl) const override
149  {
150  auto const& other = dynamic_cast<txs_iter_impl const&>(impl);
151  return iter_ == other.iter_;
152  }
153 
154  void
155  increment() override
156  {
157  ++iter_;
158  }
159 
161  dereference() const override
162  {
163  auto const item = *iter_;
164  if (metadata_)
165  return deserializeTxPlusMeta(item);
166  return {deserializeTx(item), nullptr};
167  }
168 };
169 
170 //------------------------------------------------------------------------------
171 
174  Config const& config,
175  std::vector<uint256> const& amendments,
176  Family& family)
177  : mImmutable(false)
178  , txMap_(std::make_shared<SHAMap>(SHAMapType::TRANSACTION, family))
179  , stateMap_(std::make_shared<SHAMap>(SHAMapType::STATE, family))
180  , rules_{config.features}
181 {
182  info_.seq = 1;
183  info_.drops = INITIAL_XRP;
184  info_.closeTimeResolution = ledgerDefaultTimeResolution;
185 
186  static auto const id = calcAccountID(
187  generateKeyPair(KeyType::secp256k1, generateSeed("masterpassphrase"))
188  .first);
189  {
190  auto const sle = std::make_shared<SLE>(keylet::account(id));
191  sle->setFieldU32(sfSequence, 1);
192  sle->setAccountID(sfAccount, id);
193  sle->setFieldAmount(sfBalance, info_.drops);
194  rawInsert(sle);
195  }
196 
197  if (!amendments.empty())
198  {
199  auto const sle = std::make_shared<SLE>(keylet::amendments());
200  sle->setFieldV256(sfAmendments, STVector256{amendments});
201  rawInsert(sle);
202  }
203 
204  stateMap_->flushDirty(hotACCOUNT_NODE, info_.seq);
205  setImmutable(config);
206 }
207 
209  LedgerInfo const& info,
210  bool& loaded,
211  bool acquire,
212  Config const& config,
213  Family& family,
214  beast::Journal j)
215  : mImmutable(true)
216  , txMap_(std::make_shared<SHAMap>(
218  info.txHash,
219  family))
220  , stateMap_(
221  std::make_shared<SHAMap>(SHAMapType::STATE, info.accountHash, family))
222  , rules_(config.features)
223  , info_(info)
224 {
225  loaded = true;
226 
227  if (info_.txHash.isNonZero() &&
228  !txMap_->fetchRoot(SHAMapHash{info_.txHash}, nullptr))
229  {
230  loaded = false;
231  JLOG(j.warn()) << "Don't have TX root for ledger";
232  }
233 
234  if (info_.accountHash.isNonZero() &&
235  !stateMap_->fetchRoot(SHAMapHash{info_.accountHash}, nullptr))
236  {
237  loaded = false;
238  JLOG(j.warn()) << "Don't have AS root for ledger";
239  }
240 
241  txMap_->setImmutable();
242  stateMap_->setImmutable();
243 
244  if (!setup(config))
245  loaded = false;
246 
247  if (!loaded)
248  {
250  if (acquire)
251  family.missing_node(info_.hash, info_.seq);
252  }
253 }
254 
255 // Create a new ledger that follows this one
256 Ledger::Ledger(Ledger const& prevLedger, NetClock::time_point closeTime)
257  : mImmutable(false)
258  , txMap_(std::make_shared<SHAMap>(
260  prevLedger.stateMap_->family()))
261  , stateMap_(prevLedger.stateMap_->snapShot(true))
262  , fees_(prevLedger.fees_)
263  , rules_(prevLedger.rules_)
264 {
265  info_.seq = prevLedger.info_.seq + 1;
266  info_.parentCloseTime = prevLedger.info_.closeTime;
267  info_.hash = prevLedger.info().hash + uint256(1);
268  info_.drops = prevLedger.info().drops;
270  info_.parentHash = prevLedger.info().hash;
272  prevLedger.info_.closeTimeResolution,
273  getCloseAgree(prevLedger.info()),
274  info_.seq);
275 
276  if (prevLedger.info_.closeTime == NetClock::time_point{})
277  {
279  }
280  else
281  {
282  info_.closeTime =
284  }
285 }
286 
287 Ledger::Ledger(LedgerInfo const& info, Config const& config, Family& family)
288  : mImmutable(true)
289  , txMap_(std::make_shared<SHAMap>(
291  info.txHash,
292  family))
293  , stateMap_(
294  std::make_shared<SHAMap>(SHAMapType::STATE, info.accountHash, family))
295  , rules_{config.features}
296  , info_(info)
297 {
298  info_.hash = calculateLedgerHash(info_);
299 }
300 
302  std::uint32_t ledgerSeq,
303  NetClock::time_point closeTime,
304  Config const& config,
305  Family& family)
306  : mImmutable(false)
307  , txMap_(std::make_shared<SHAMap>(SHAMapType::TRANSACTION, family))
308  , stateMap_(std::make_shared<SHAMap>(SHAMapType::STATE, family))
309  , rules_{config.features}
310 {
311  info_.seq = ledgerSeq;
312  info_.closeTime = closeTime;
313  info_.closeTimeResolution = ledgerDefaultTimeResolution;
314  setup(config);
315 }
316 
317 void
319 {
320  // Force update, since this is the only
321  // place the hash transitions to valid
322  if (!mImmutable)
323  {
324  info_.txHash = txMap_->getHash().as_uint256();
325  info_.accountHash = stateMap_->getHash().as_uint256();
326  }
327 
329 
330  mImmutable = true;
331  txMap_->setImmutable();
332  stateMap_->setImmutable();
333  setup(config);
334 }
335 
336 void
338  NetClock::time_point closeTime,
339  NetClock::duration closeResolution,
340  bool correctCloseTime,
341  Config const& config)
342 {
343  // Used when we witnessed the consensus.
344  assert(!open());
345 
346  info_.closeTime = closeTime;
347  info_.closeTimeResolution = closeResolution;
348  info_.closeFlags = correctCloseTime ? 0 : sLCF_NoConsensusTime;
349  setImmutable(config);
350 }
351 
352 bool
353 Ledger::addSLE(SLE const& sle)
354 {
355  SHAMapItem item(sle.key(), sle.getSerializer());
356  return stateMap_->addItem(std::move(item), false, false);
357 }
358 
359 //------------------------------------------------------------------------------
360 
363 {
364  SerialIter sit(item.slice());
365  return std::make_shared<STTx const>(sit);
366 }
367 
370 {
372  result;
373  SerialIter sit(item.slice());
374  {
375  SerialIter s(sit.getSlice(sit.getVLDataLength()));
376  result.first = std::make_shared<STTx const>(s);
377  }
378  {
379  SerialIter s(sit.getSlice(sit.getVLDataLength()));
380  result.second = std::make_shared<STObject const>(s, sfMetadata);
381  }
382  return result;
383 }
384 
385 //------------------------------------------------------------------------------
386 
387 bool
388 Ledger::exists(Keylet const& k) const
389 {
390  // VFALCO NOTE Perhaps check the type for debug builds?
391  return stateMap_->hasItem(k.key);
392 }
393 
394 boost::optional<uint256>
395 Ledger::succ(uint256 const& key, boost::optional<uint256> const& last) const
396 {
397  auto item = stateMap_->upper_bound(key);
398  if (item == stateMap_->end())
399  return boost::none;
400  if (last && item->key() >= last)
401  return boost::none;
402  return item->key();
403 }
404 
406 Ledger::read(Keylet const& k) const
407 {
408  if (k.key == beast::zero)
409  {
410  assert(false);
411  return nullptr;
412  }
413  auto const& item = stateMap_->peekItem(k.key);
414  if (!item)
415  return nullptr;
416  auto sle = std::make_shared<SLE>(
417  SerialIter{item->data(), item->size()}, item->key());
418  if (!k.check(*sle))
419  return nullptr;
420  return sle;
421 }
422 
423 //------------------------------------------------------------------------------
424 
425 auto
426 Ledger::slesBegin() const -> std::unique_ptr<sles_type::iter_base>
427 {
428  return std::make_unique<sles_iter_impl>(stateMap_->begin());
429 }
430 
431 auto
432 Ledger::slesEnd() const -> std::unique_ptr<sles_type::iter_base>
433 {
434  return std::make_unique<sles_iter_impl>(stateMap_->end());
435 }
436 
437 auto
440 {
441  return std::make_unique<sles_iter_impl>(stateMap_->upper_bound(key));
442 }
443 
444 auto
445 Ledger::txsBegin() const -> std::unique_ptr<txs_type::iter_base>
446 {
447  return std::make_unique<txs_iter_impl>(!open(), txMap_->begin());
448 }
449 
450 auto
451 Ledger::txsEnd() const -> std::unique_ptr<txs_type::iter_base>
452 {
453  return std::make_unique<txs_iter_impl>(!open(), txMap_->end());
454 }
455 
456 bool
457 Ledger::txExists(uint256 const& key) const
458 {
459  return txMap_->hasItem(key);
460 }
461 
462 auto
463 Ledger::txRead(key_type const& key) const -> tx_type
464 {
465  auto const& item = txMap_->peekItem(key);
466  if (!item)
467  return {};
468  if (!open())
469  {
470  auto result = deserializeTxPlusMeta(*item);
471  return {std::move(result.first), std::move(result.second)};
472  }
473  return {deserializeTx(*item), nullptr};
474 }
475 
476 auto
477 Ledger::digest(key_type const& key) const -> boost::optional<digest_type>
478 {
480  // VFALCO Unfortunately this loads the item
481  // from the NodeStore needlessly.
482  if (!stateMap_->peekItem(key, digest))
483  return boost::none;
484  return digest.as_uint256();
485 }
486 
487 //------------------------------------------------------------------------------
488 
489 void
491 {
492  if (!stateMap_->delItem(sle->key()))
493  LogicError("Ledger::rawErase: key not found");
494 }
495 
496 void
498 {
499  Serializer ss;
500  sle->add(ss);
501  auto item = std::make_shared<SHAMapItem const>(sle->key(), std::move(ss));
502  // VFALCO NOTE addGiveItem should take ownership
503  if (!stateMap_->addGiveItem(std::move(item), false, false))
504  LogicError("Ledger::rawInsert: key already exists");
505 }
506 
507 void
509 {
510  Serializer ss;
511  sle->add(ss);
512  auto item = std::make_shared<SHAMapItem const>(sle->key(), std::move(ss));
513  // VFALCO NOTE updateGiveItem should take ownership
514  if (!stateMap_->updateGiveItem(std::move(item), false, false))
515  LogicError("Ledger::rawReplace: key not found");
516 }
517 
518 void
520  uint256 const& key,
522  std::shared_ptr<Serializer const> const& metaData)
523 {
524  assert(metaData);
525 
526  // low-level - just add to table
527  Serializer s(txn->getDataLength() + metaData->getDataLength() + 16);
528  s.addVL(txn->peekData());
529  s.addVL(metaData->peekData());
530  auto item = std::make_shared<SHAMapItem const>(key, std::move(s));
531  if (!txMap().addGiveItem(std::move(item), true, true))
532  LogicError("duplicate_tx: " + to_string(key));
533 }
534 
535 bool
536 Ledger::setup(Config const& config)
537 {
538  bool ret = true;
539 
540  fees_.base = config.FEE_DEFAULT;
544 
545  try
546  {
547  if (auto const sle = read(keylet::fees()))
548  {
549  // VFALCO NOTE Why getFieldIndex and not isFieldPresent?
550 
551  if (sle->getFieldIndex(sfBaseFee) != -1)
552  fees_.base = sle->getFieldU64(sfBaseFee);
553 
554  if (sle->getFieldIndex(sfReferenceFeeUnits) != -1)
555  fees_.units = sle->getFieldU32(sfReferenceFeeUnits);
556 
557  if (sle->getFieldIndex(sfReserveBase) != -1)
558  fees_.reserve = sle->getFieldU32(sfReserveBase);
559 
560  if (sle->getFieldIndex(sfReserveIncrement) != -1)
561  fees_.increment = sle->getFieldU32(sfReserveIncrement);
562  }
563  }
564  catch (SHAMapMissingNode const&)
565  {
566  ret = false;
567  }
568  catch (std::exception const&)
569  {
570  Rethrow();
571  }
572 
573  try
574  {
575  rules_ = Rules(*this, config.features);
576  }
577  catch (SHAMapMissingNode const&)
578  {
579  ret = false;
580  }
581  catch (std::exception const&)
582  {
583  Rethrow();
584  }
585 
586  return ret;
587 }
588 
590 Ledger::peek(Keylet const& k) const
591 {
592  auto const& value = stateMap_->peekItem(k.key);
593  if (!value)
594  return nullptr;
595  auto sle = std::make_shared<SLE>(
596  SerialIter{value->data(), value->size()}, value->key());
597  if (!k.check(*sle))
598  return nullptr;
599  return sle;
600 }
601 
602 //------------------------------------------------------------------------------
603 bool
605 {
606  std::vector<SHAMapMissingNode> missingNodes1;
607  std::vector<SHAMapMissingNode> missingNodes2;
608 
609  if (stateMap_->getHash().isZero() && !info_.accountHash.isZero() &&
610  !stateMap_->fetchRoot(SHAMapHash{info_.accountHash}, nullptr))
611  {
612  missingNodes1.emplace_back(
614  }
615  else
616  {
617  stateMap_->walkMap(missingNodes1, 32);
618  }
619 
620  if (!missingNodes1.empty())
621  {
622  if (auto stream = j.info())
623  {
624  stream << missingNodes1.size() << " missing account node(s)";
625  stream << "First: " << missingNodes1[0].what();
626  }
627  }
628 
629  if (txMap_->getHash().isZero() && info_.txHash.isNonZero() &&
630  !txMap_->fetchRoot(SHAMapHash{info_.txHash}, nullptr))
631  {
632  missingNodes2.emplace_back(
634  }
635  else
636  {
637  txMap_->walkMap(missingNodes2, 32);
638  }
639 
640  if (!missingNodes2.empty())
641  {
642  if (auto stream = j.info())
643  {
644  stream << missingNodes2.size() << " missing transaction node(s)";
645  stream << "First: " << missingNodes2[0].what();
646  }
647  }
648  return missingNodes1.empty() && missingNodes2.empty();
649 }
650 
651 bool
653 {
655  txMap_ && (info_.accountHash == stateMap_->getHash().as_uint256()) &&
656  (info_.txHash == txMap_->getHash().as_uint256()))
657  {
658  return true;
659  }
660 
661  Json::Value j = getJson(*this);
662 
663  j[jss::accountTreeHash] = to_string(info_.accountHash);
664  j[jss::transTreeHash] = to_string(info_.txHash);
665 
666  JLOG(ledgerJ.fatal()) << "ledger is not sane" << j;
667 
668  assert(false);
669 
670  return false;
671 }
672 
673 // update the skip list with the information from our previous ledger
674 // VFALCO TODO Document this skip list concept
675 void
677 {
678  if (info_.seq == 0) // genesis ledger has no previous ledger
679  return;
680 
681  std::uint32_t prevIndex = info_.seq - 1;
682 
683  // update record of every 256th ledger
684  if ((prevIndex & 0xff) == 0)
685  {
686  auto const k = keylet::skip(prevIndex);
687  auto sle = peek(k);
688  std::vector<uint256> hashes;
689 
690  bool created;
691  if (!sle)
692  {
693  sle = std::make_shared<SLE>(k);
694  created = true;
695  }
696  else
697  {
698  hashes = static_cast<decltype(hashes)>(sle->getFieldV256(sfHashes));
699  created = false;
700  }
701 
702  assert(hashes.size() <= 256);
703  hashes.push_back(info_.parentHash);
704  sle->setFieldV256(sfHashes, STVector256(hashes));
705  sle->setFieldU32(sfLastLedgerSequence, prevIndex);
706  if (created)
707  rawInsert(sle);
708  else
709  rawReplace(sle);
710  }
711 
712  // update record of past 256 ledger
713  auto const k = keylet::skip();
714  auto sle = peek(k);
715  std::vector<uint256> hashes;
716  bool created;
717  if (!sle)
718  {
719  sle = std::make_shared<SLE>(k);
720  created = true;
721  }
722  else
723  {
724  hashes = static_cast<decltype(hashes)>(sle->getFieldV256(sfHashes));
725  created = false;
726  }
727  assert(hashes.size() <= 256);
728  if (hashes.size() == 256)
729  hashes.erase(hashes.begin());
730  hashes.push_back(info_.parentHash);
731  sle->setFieldV256(sfHashes, STVector256(hashes));
732  sle->setFieldU32(sfLastLedgerSequence, prevIndex);
733  if (created)
734  rawInsert(sle);
735  else
736  rawReplace(sle);
737 }
738 
739 static bool
741  Application& app,
742  std::shared_ptr<Ledger const> const& ledger,
743  bool current)
744 {
745  auto j = app.journal("Ledger");
746  auto seq = ledger->info().seq;
747  if (!app.pendingSaves().startWork(seq))
748  {
749  // The save was completed synchronously
750  JLOG(j.debug()) << "Save aborted";
751  return true;
752  }
753 
754  // TODO(tom): Fix this hard-coded SQL!
755  JLOG(j.trace()) << "saveValidatedLedger " << (current ? "" : "fromAcquire ")
756  << seq;
757  static boost::format deleteLedger(
758  "DELETE FROM Ledgers WHERE LedgerSeq = %u;");
759  static boost::format deleteTrans1(
760  "DELETE FROM Transactions WHERE LedgerSeq = %u;");
761  static boost::format deleteTrans2(
762  "DELETE FROM AccountTransactions WHERE LedgerSeq = %u;");
763  static boost::format deleteAcctTrans(
764  "DELETE FROM AccountTransactions WHERE TransID = '%s';");
765 
766  if (!ledger->info().accountHash.isNonZero())
767  {
768  JLOG(j.fatal()) << "AH is zero: " << getJson(*ledger);
769  assert(false);
770  }
771 
772  if (ledger->info().accountHash != ledger->stateMap().getHash().as_uint256())
773  {
774  JLOG(j.fatal()) << "sAL: " << ledger->info().accountHash
775  << " != " << ledger->stateMap().getHash();
776  JLOG(j.fatal()) << "saveAcceptedLedger: seq=" << seq
777  << ", current=" << current;
778  assert(false);
779  }
780 
781  assert(ledger->info().txHash == ledger->txMap().getHash().as_uint256());
782 
783  // Save the ledger header in the hashed object store
784  {
785  Serializer s(128);
787  addRaw(ledger->info(), s);
788  app.getNodeStore().store(
789  hotLEDGER, std::move(s.modData()), ledger->info().hash, seq);
790  }
791 
792  AcceptedLedger::pointer aLedger;
793  try
794  {
795  aLedger = app.getAcceptedLedgerCache().fetch(ledger->info().hash);
796  if (!aLedger)
797  {
798  aLedger = std::make_shared<AcceptedLedger>(
799  ledger, app.accountIDCache(), app.logs());
800  app.getAcceptedLedgerCache().canonicalize_replace_client(
801  ledger->info().hash, aLedger);
802  }
803  }
804  catch (std::exception const&)
805  {
806  JLOG(j.warn()) << "An accepted ledger was missing nodes";
807  app.getLedgerMaster().failedSave(seq, ledger->info().hash);
808  // Clients can now trust the database for information about this
809  // ledger sequence.
810  app.pendingSaves().finishWork(seq);
811  return false;
812  }
813 
814  {
815  auto db = app.getLedgerDB().checkoutDb();
816  *db << boost::str(deleteLedger % seq);
817  }
818 
819  {
820  auto db = app.getTxnDB().checkoutDb();
821 
822  soci::transaction tr(*db);
823 
824  *db << boost::str(deleteTrans1 % seq);
825  *db << boost::str(deleteTrans2 % seq);
826 
827  std::string const ledgerSeq(std::to_string(seq));
828 
829  for (auto const& [_, acceptedLedgerTx] : aLedger->getMap())
830  {
831  (void)_;
832  uint256 transactionID = acceptedLedgerTx->getTransactionID();
833 
835 
836  std::string const txnId(to_string(transactionID));
837  std::string const txnSeq(
838  std::to_string(acceptedLedgerTx->getTxnSeq()));
839 
840  *db << boost::str(deleteAcctTrans % transactionID);
841 
842  auto const& accts = acceptedLedgerTx->getAffected();
843 
844  if (!accts.empty())
845  {
846  std::string sql(
847  "INSERT INTO AccountTransactions "
848  "(TransID, Account, LedgerSeq, TxnSeq) VALUES ");
849 
850  // Try to make an educated guess on how much space we'll need
851  // for our arguments. In argument order we have:
852  // 64 + 34 + 10 + 10 = 118 + 10 extra = 128 bytes
853  sql.reserve(sql.length() + (accts.size() * 128));
854 
855  bool first = true;
856  for (auto const& account : accts)
857  {
858  if (!first)
859  sql += ", ('";
860  else
861  {
862  sql += "('";
863  first = false;
864  }
865 
866  sql += txnId;
867  sql += "','";
868  sql += app.accountIDCache().toBase58(account);
869  sql += "',";
870  sql += ledgerSeq;
871  sql += ",";
872  sql += txnSeq;
873  sql += ")";
874  }
875  sql += ";";
876  JLOG(j.trace()) << "ActTx: " << sql;
877  *db << sql;
878  }
879  else
880  {
881  JLOG(j.warn()) << "Transaction in ledger " << seq
882  << " affects no accounts";
883  JLOG(j.warn())
884  << acceptedLedgerTx->getTxn()->getJson(JsonOptions::none);
885  }
886 
887  *db
889  acceptedLedgerTx->getTxn()->getMetaSQL(
890  seq, acceptedLedgerTx->getEscMeta()) +
891  ";");
892  }
893 
894  tr.commit();
895  }
896 
897  {
898  static std::string addLedger(
899  R"sql(INSERT OR REPLACE INTO Ledgers
900  (LedgerHash,LedgerSeq,PrevHash,TotalCoins,ClosingTime,PrevClosingTime,
901  CloseTimeRes,CloseFlags,AccountSetHash,TransSetHash)
902  VALUES
903  (:ledgerHash,:ledgerSeq,:prevHash,:totalCoins,:closingTime,:prevClosingTime,
904  :closeTimeRes,:closeFlags,:accountSetHash,:transSetHash);)sql");
905 
906  auto db(app.getLedgerDB().checkoutDb());
907 
908  soci::transaction tr(*db);
909 
910  auto const hash = to_string(ledger->info().hash);
911  auto const parentHash = to_string(ledger->info().parentHash);
912  auto const drops = to_string(ledger->info().drops);
913  auto const closeTime =
914  ledger->info().closeTime.time_since_epoch().count();
915  auto const parentCloseTime =
916  ledger->info().parentCloseTime.time_since_epoch().count();
917  auto const closeTimeResolution =
918  ledger->info().closeTimeResolution.count();
919  auto const closeFlags = ledger->info().closeFlags;
920  auto const accountHash = to_string(ledger->info().accountHash);
921  auto const txHash = to_string(ledger->info().txHash);
922 
923  *db << addLedger, soci::use(hash), soci::use(seq),
924  soci::use(parentHash), soci::use(drops), soci::use(closeTime),
925  soci::use(parentCloseTime), soci::use(closeTimeResolution),
926  soci::use(closeFlags), soci::use(accountHash), soci::use(txHash);
927 
928  tr.commit();
929  }
930 
931  // Clients can now trust the database for
932  // information about this ledger sequence.
933  app.pendingSaves().finishWork(seq);
934  return true;
935 }
936 
940 bool
942  Application& app,
943  std::shared_ptr<Ledger const> const& ledger,
944  bool isSynchronous,
945  bool isCurrent)
946 {
947  if (!app.getHashRouter().setFlags(ledger->info().hash, SF_SAVED))
948  {
949  // We have tried to save this ledger recently
950  auto stream = app.journal("Ledger").debug();
951  JLOG(stream) << "Double pend save for " << ledger->info().seq;
952 
953  if (!isSynchronous || !app.pendingSaves().pending(ledger->info().seq))
954  {
955  // Either we don't need it to be finished
956  // or it is finished
957  return true;
958  }
959  }
960 
961  assert(ledger->isImmutable());
962 
963  if (!app.pendingSaves().shouldWork(ledger->info().seq, isSynchronous))
964  {
965  auto stream = app.journal("Ledger").debug();
966  JLOG(stream) << "Pend save with seq in pending saves "
967  << ledger->info().seq;
968 
969  return true;
970  }
971 
972  JobType const jobType{isCurrent ? jtPUBLEDGER : jtPUBOLDLEDGER};
973  char const* const jobName{
974  isCurrent ? "Ledger::pendSave" : "Ledger::pendOldSave"};
975 
976  // See if we can use the JobQueue.
977  if (!isSynchronous &&
978  app.getJobQueue().addJob(
979  jobType, jobName, [&app, ledger, isCurrent](Job&) {
980  saveValidatedLedger(app, ledger, isCurrent);
981  }))
982  {
983  return true;
984  }
985 
986  // The JobQueue won't do the Job. Do the save synchronously.
987  return saveValidatedLedger(app, ledger, isCurrent);
988 }
989 
990 void
991 Ledger::unshare() const
992 {
993  stateMap_->unshare();
994  txMap_->unshare();
995 }
996 
997 void
998 Ledger::invariants() const
999 {
1000  stateMap_->invariants();
1001  txMap_->invariants();
1002 }
1003 
1004 //------------------------------------------------------------------------------
1005 
1006 /*
1007  * Load a ledger from the database.
1008  *
1009  * @param sqlSuffix: Additional string to append to the sql query.
1010  * (typically a where clause).
1011  * @param acquire: Acquire the ledger if not found locally.
1012  * @return The ledger, ledger sequence, and ledger hash.
1013  */
1015 loadLedgerHelper(std::string const& sqlSuffix, Application& app, bool acquire)
1016 {
1017  uint256 ledgerHash{};
1018  std::uint32_t ledgerSeq{0};
1019 
1020  auto db = app.getLedgerDB().checkoutDb();
1021 
1022  boost::optional<std::string> sLedgerHash, sPrevHash, sAccountHash,
1023  sTransHash;
1024  boost::optional<std::uint64_t> totDrops, closingTime, prevClosingTime,
1025  closeResolution, closeFlags, ledgerSeq64;
1026 
1027  std::string const sql =
1028  "SELECT "
1029  "LedgerHash, PrevHash, AccountSetHash, TransSetHash, "
1030  "TotalCoins,"
1031  "ClosingTime, PrevClosingTime, CloseTimeRes, CloseFlags,"
1032  "LedgerSeq from Ledgers " +
1033  sqlSuffix + ";";
1034 
1035  *db << sql, soci::into(sLedgerHash), soci::into(sPrevHash),
1036  soci::into(sAccountHash), soci::into(sTransHash), soci::into(totDrops),
1037  soci::into(closingTime), soci::into(prevClosingTime),
1038  soci::into(closeResolution), soci::into(closeFlags),
1039  soci::into(ledgerSeq64);
1040 
1041  if (!db->got_data())
1042  {
1043  auto stream = app.journal("Ledger").debug();
1044  JLOG(stream) << "Ledger not found: " << sqlSuffix;
1045  return std::make_tuple(
1046  std::shared_ptr<Ledger>(), ledgerSeq, ledgerHash);
1047  }
1048 
1049  ledgerSeq = rangeCheckedCast<std::uint32_t>(ledgerSeq64.value_or(0));
1050 
1051  uint256 prevHash{}, accountHash{}, transHash{};
1052  if (sLedgerHash)
1053  ledgerHash.SetHexExact(*sLedgerHash);
1054  if (sPrevHash)
1055  prevHash.SetHexExact(*sPrevHash);
1056  if (sAccountHash)
1057  accountHash.SetHexExact(*sAccountHash);
1058  if (sTransHash)
1059  transHash.SetHexExact(*sTransHash);
1060 
1061  using time_point = NetClock::time_point;
1062  using duration = NetClock::duration;
1063 
1064  LedgerInfo info;
1065  info.parentHash = prevHash;
1066  info.txHash = transHash;
1067  info.accountHash = accountHash;
1068  info.drops = totDrops.value_or(0);
1069  info.closeTime = time_point{duration{closingTime.value_or(0)}};
1070  info.parentCloseTime = time_point{duration{prevClosingTime.value_or(0)}};
1071  info.closeFlags = closeFlags.value_or(0);
1072  info.closeTimeResolution = duration{closeResolution.value_or(0)};
1073  info.seq = ledgerSeq;
1074 
1075  bool loaded;
1076  auto ledger = std::make_shared<Ledger>(
1077  info,
1078  loaded,
1079  acquire,
1080  app.config(),
1081  app.family(),
1082  app.journal("Ledger"));
1083 
1084  if (!loaded)
1085  ledger.reset();
1087  return std::make_tuple(ledger, ledgerSeq, ledgerHash);
1088 }
1089 
1090 static void
1092  std::shared_ptr<Ledger> const& ledger,
1093  Config const& config,
1094  beast::Journal j)
1095 {
1096  if (!ledger)
1097  return;
1098 
1099  ledger->setImmutable(config);
1100 
1101  JLOG(j.trace()) << "Loaded ledger: " << to_string(ledger->info().hash);
1103  ledger->setFull();
1104 }
1105 
1107 loadByIndex(std::uint32_t ledgerIndex, Application& app, bool acquire)
1108 {
1109  std::shared_ptr<Ledger> ledger;
1110  {
1112  s << "WHERE LedgerSeq = " << ledgerIndex;
1113  std::tie(ledger, std::ignore, std::ignore) =
1114  loadLedgerHelper(s.str(), app, acquire);
1115  }
1116 
1117  finishLoadByIndexOrHash(ledger, app.config(), app.journal("Ledger"));
1118  return ledger;
1119 }
1120 
1122 loadByHash(uint256 const& ledgerHash, Application& app, bool acquire)
1123 {
1124  std::shared_ptr<Ledger> ledger;
1125  {
1127  s << "WHERE LedgerHash = '" << ledgerHash << "'";
1128  std::tie(ledger, std::ignore, std::ignore) =
1129  loadLedgerHelper(s.str(), app, acquire);
1130  }
1131 
1132  finishLoadByIndexOrHash(ledger, app.config(), app.journal("Ledger"));
1133 
1134  assert(!ledger || ledger->info().hash == ledgerHash);
1136  return ledger;
1137 }
1138 
1139 uint256
1140 getHashByIndex(std::uint32_t ledgerIndex, Application& app)
1141 {
1142  uint256 ret;
1143 
1144  std::string sql =
1145  "SELECT LedgerHash FROM Ledgers INDEXED BY SeqLedger WHERE LedgerSeq='";
1146  sql.append(beast::lexicalCastThrow<std::string>(ledgerIndex));
1147  sql.append("';");
1148 
1149  std::string hash;
1150  {
1151  auto db = app.getLedgerDB().checkoutDb();
1152 
1153  boost::optional<std::string> lh;
1154  *db << sql, soci::into(lh);
1155 
1156  if (!db->got_data() || !lh)
1157  return ret;
1158 
1159  hash = *lh;
1160  if (hash.empty())
1161  return ret;
1162  }
1163 
1164  ret.SetHexExact(hash);
1165  return ret;
1166 }
1167 
1168 bool
1170  std::uint32_t ledgerIndex,
1171  uint256& ledgerHash,
1172  uint256& parentHash,
1173  Application& app)
1174 {
1175  auto db = app.getLedgerDB().checkoutDb();
1176 
1177  boost::optional<std::string> lhO, phO;
1178 
1179  *db << "SELECT LedgerHash,PrevHash FROM Ledgers "
1180  "INDEXED BY SeqLedger Where LedgerSeq = :ls;",
1181  soci::into(lhO), soci::into(phO), soci::use(ledgerIndex);
1182 
1183  if (!lhO || !phO)
1184  {
1185  auto stream = app.journal("Ledger").trace();
1186  JLOG(stream) << "Don't have ledger " << ledgerIndex;
1187  return false;
1188  }
1189 
1190  ledgerHash.SetHexExact(*lhO);
1191  parentHash.SetHexExact(*phO);
1193  return true;
1194 }
1195 
1197 getHashesByIndex(std::uint32_t minSeq, std::uint32_t maxSeq, Application& app)
1198 {
1200 
1201  std::string sql =
1202  "SELECT LedgerSeq,LedgerHash,PrevHash FROM Ledgers WHERE LedgerSeq >= ";
1203  sql.append(beast::lexicalCastThrow<std::string>(minSeq));
1204  sql.append(" AND LedgerSeq <= ");
1205  sql.append(beast::lexicalCastThrow<std::string>(maxSeq));
1206  sql.append(";");
1207 
1208  auto db = app.getLedgerDB().checkoutDb();
1209 
1210  std::uint64_t ls;
1211  std::string lh;
1212  boost::optional<std::string> ph;
1213  soci::statement st =
1214  (db->prepare << sql, soci::into(ls), soci::into(lh), soci::into(ph));
1215 
1216  st.execute();
1217  while (st.fetch())
1218  {
1219  std::pair<uint256, uint256>& hashes =
1220  ret[rangeCheckedCast<std::uint32_t>(ls)];
1221  hashes.first.SetHexExact(lh);
1222  if (ph)
1223  hashes.second.SetHexExact(*ph);
1224  else
1225  hashes.second.zero();
1226  if (!ph)
1227  {
1228  auto stream = app.journal("Ledger").warn();
1229  JLOG(stream) << "Null prev hash for ledger seq: " << ls;
1230  }
1231  }
1232 
1233  return ret;
1234 }
1235 
1236 } // namespace ripple
beast::Journal::fatal
Stream fatal() const
Definition: Journal.h:339
ripple::Ledger::slesUpperBound
std::unique_ptr< sles_type::iter_base > slesUpperBound(uint256 const &key) const override
Definition: Ledger.cpp:438
ripple::loadLedgerHelper
std::tuple< std::shared_ptr< Ledger >, std::uint32_t, uint256 > loadLedgerHelper(std::string const &sqlSuffix, Application &app, bool acquire)
Definition: Ledger.cpp:1010
ripple::Application
Definition: Application.h:94
ripple::Ledger::sles_iter_impl::sles_iter_impl
sles_iter_impl(SHAMap::const_iterator iter)
Definition: Ledger.cpp:89
ripple::Ledger::slesBegin
std::unique_ptr< sles_type::iter_base > slesBegin() const override
Definition: Ledger.cpp:426
ripple::Family::missing_node
virtual void missing_node(std::uint32_t refNum)=0
ripple::Ledger::addSLE
bool addSLE(SLE const &sle)
Definition: Ledger.cpp:353
ripple::Ledger::rawReplace
void rawReplace(std::shared_ptr< SLE > const &sle) override
Unconditionally replace a state item.
Definition: Ledger.cpp:508
ripple::HashPrefix::ledgerMaster
@ ledgerMaster
ledger master data for signing
std::make_tuple
T make_tuple(T... args)
ripple::Ledger::txMap_
std::shared_ptr< SHAMap > txMap_
Definition: Ledger.h:344
ripple::Keylet
A pair of SHAMap key and LedgerEntryType.
Definition: Keylet.h:38
ripple::Application::getAcceptedLedgerCache
virtual TaggedCache< uint256, AcceptedLedger > & getAcceptedLedgerCache()=0
ripple::Ledger::mImmutable
bool mImmutable
Definition: Ledger.h:342
ripple::Ledger::sles_iter_impl
Definition: Ledger.cpp:77
ripple::STLedgerEntry
Definition: STLedgerEntry.h:30
ripple::Ledger::txRead
tx_type txRead(key_type const &key) const override
Read a transaction from the tx map.
Definition: Ledger.cpp:463
std::string
STL class.
std::shared_ptr
STL class.
ripple::LedgerInfo::parentHash
uint256 parentHash
Definition: ReadView.h:99
ripple::keylet::amendments
Keylet const & amendments() noexcept
The index of the amendment table.
Definition: Indexes.cpp:150
ripple::SHAMap::getHash
SHAMapHash getHash() const
Definition: SHAMap.cpp:789
ripple::loadByIndex
std::shared_ptr< Ledger > loadByIndex(std::uint32_t ledgerIndex, Application &app, bool acquire)
Definition: Ledger.cpp:1102
utility
ripple::Ledger::fees_
Fees fees_
Definition: Ledger.h:350
std::exception
STL class.
ripple::base_uint::isNonZero
bool isNonZero() const
Definition: base_uint.h:480
beast::Journal::trace
Stream trace() const
Severity stream access functions.
Definition: Journal.h:309
ripple::Ledger::unshare
void unshare() const
Definition: Ledger.cpp:986
ripple::Ledger::slesEnd
std::unique_ptr< sles_type::iter_base > slesEnd() const override
Definition: Ledger.cpp:432
ripple::Serializer::modData
Blob & modData()
Definition: Serializer.h:176
ripple::ReadView::txs_type
Definition: ReadView.h:209
ripple::PendingSaves::pending
bool pending(LedgerIndex seq)
Return true if a ledger is in the progress of being saved.
Definition: PendingSaves.h:84
std::pair
ripple::SHAMapType::TRANSACTION
@ TRANSACTION
std::string::reserve
T reserve(T... args)
ripple::LedgerInfo::hash
uint256 hash
Definition: ReadView.h:96
ripple::XRPAmount::drops
constexpr value_type drops() const
Returns the number of drops.
Definition: XRPAmount.h:172
ripple::sfMetadata
const SField sfMetadata(access, STI_METADATA, 257, "Metadata")
Definition: SField.h:336
ripple::hotACCOUNT_NODE
@ hotACCOUNT_NODE
Definition: NodeObject.h:35
std::vector
STL class.
std::vector::size
T size(T... args)
ripple::sfSequence
const SF_U32 sfSequence(access, STI_UINT32, 4, "Sequence")
Definition: SField.h:355
ripple::Ledger::sles_iter_impl::dereference
sles_type::value_type dereference() const override
Definition: Ledger.cpp:113
ripple::sfAccount
const SF_Account sfAccount(access, STI_ACCOUNT, 1, "Account")
Definition: SField.h:476
std::chrono::duration
ripple::keylet::skip
Keylet const & skip() noexcept
The index of the "short" skip list.
Definition: Indexes.cpp:132
ripple::STObject::getSerializer
Serializer getSerializer() const
Definition: STObject.h:366
ripple::Ledger::exists
bool exists(Keylet const &k) const override
Determine if a state item exists.
Definition: Ledger.cpp:388
beast::Journal::warn
Stream warn() const
Definition: Journal.h:327
ripple::Ledger::txs_iter_impl::equal
bool equal(base_type const &impl) const override
Definition: Ledger.cpp:148
ripple::Ledger::peek
std::shared_ptr< SLE > peek(Keylet const &k) const
Definition: Ledger.cpp:590
ripple::Ledger::invariants
void invariants() const
Definition: Ledger.cpp:993
ripple::roundCloseTime
std::chrono::time_point< Clock, Duration > roundCloseTime(std::chrono::time_point< Clock, Duration > closeTime, std::chrono::duration< Rep, Period > closeResolution)
Calculates the close time for a ledger, given a close time resolution.
Definition: LedgerTiming.h:126
std::tuple
ripple::addRaw
void addRaw(LedgerInfo const &info, Serializer &s)
Definition: View.cpp:43
ripple::Ledger::txs_iter_impl::operator=
txs_iter_impl & operator=(txs_iter_impl const &)=delete
ripple::Ledger::walkLedger
bool walkLedger(beast::Journal j) const
Definition: Ledger.cpp:604
ripple::STTx::getMetaSQLInsertReplaceHeader
static std::string const & getMetaSQLInsertReplaceHeader()
Definition: STTx.cpp:216
ripple::JobQueue::addJob
bool addJob(JobType type, std::string const &name, JobHandler &&jobHandler)
Adds a job to the JobQueue.
Definition: JobQueue.h:166
ripple::LedgerInfo::seq
LedgerIndex seq
Definition: ReadView.h:88
ripple::to_string
std::string to_string(ListDisposition disposition)
Definition: ValidatorList.cpp:41
ripple::Ledger::rawTxInsert
void rawTxInsert(uint256 const &key, std::shared_ptr< Serializer const > const &txn, std::shared_ptr< Serializer const > const &metaData) override
Add a transaction to the tx map.
Definition: Ledger.cpp:519
ripple::PendingSaves::startWork
bool startWork(LedgerIndex seq)
Start working on a ledger.
Definition: PendingSaves.h:51
ripple::Ledger::txs_iter_impl::txs_iter_impl
txs_iter_impl(bool metadata, SHAMap::const_iterator iter)
Definition: Ledger.cpp:136
ripple::Fees::reserve
XRPAmount reserve
Definition: ReadView.h:51
ripple::Ledger::rawErase
void rawErase(std::shared_ptr< SLE > const &sle) override
Delete an existing state item.
Definition: Ledger.cpp:490
ripple::SHAMapType::STATE
@ STATE
ripple::sfReserveBase
const SF_U32 sfReserveBase(access, STI_UINT32, 31, "ReserveBase")
Definition: SField.h:383
ripple::LedgerInfo::txHash
uint256 txHash
Definition: ReadView.h:97
ripple::Ledger::info_
LedgerInfo info_
Definition: Ledger.h:352
ripple::finishLoadByIndexOrHash
static void finishLoadByIndexOrHash(std::shared_ptr< Ledger > const &ledger, Config const &config, beast::Journal j)
Definition: Ledger.cpp:1086
ripple::deserializeTx
std::shared_ptr< STTx const > deserializeTx(SHAMapItem const &item)
Deserialize a SHAMapItem containing a single STTx.
Definition: Ledger.cpp:362
ripple::SHAMapHash
Definition: SHAMapTreeNode.h:43
ripple::generateKeyPair
std::pair< PublicKey, SecretKey > generateKeyPair(KeyType type, Seed const &seed)
Generate a key pair deterministically.
Definition: SecretKey.cpp:243
ripple::Application::accountIDCache
virtual AccountIDCache const & accountIDCache() const =0
ripple::Ledger::setImmutable
void setImmutable(Config const &config)
Definition: Ledger.cpp:318
ripple::INITIAL_XRP
constexpr XRPAmount INITIAL_XRP
Configure the native currency.
Definition: SystemParameters.h:42
ripple::getHashByIndex
uint256 getHashByIndex(std::uint32_t ledgerIndex, Application &app)
Definition: Ledger.cpp:1135
ripple::SHAMapMissingNode
Definition: SHAMapMissingNode.h:55
ripple::uint256
base_uint< 256 > uint256
Definition: base_uint.h:493
ripple::detail::ReadViewFwdRange< std::shared_ptr< SLE const > >::value_type
std::shared_ptr< SLE const > value_type
Definition: ReadViewFwdRange.h:137
ripple::Ledger::txsEnd
std::unique_ptr< txs_type::iter_base > txsEnd() const override
Definition: Ledger.cpp:451
ripple::Fees::increment
XRPAmount increment
Definition: ReadView.h:52
std::tie
T tie(T... args)
std::vector::push_back
T push_back(T... args)
ripple::digest
static Hasher::result_type digest(void const *data, std::size_t size) noexcept
Definition: tokens.cpp:43
ripple::LedgerInfo::closeTime
NetClock::time_point closeTime
Definition: ReadView.h:119
ripple::STLedgerEntry::key
uint256 const & key() const
Returns the 'key' (or 'index') of this item.
Definition: STLedgerEntry.h:92
ripple::Keylet::key
uint256 key
Definition: Keylet.h:41
ripple::base_uint< 256 >
ripple::sfLastLedgerSequence
const SF_U32 sfLastLedgerSequence(access, STI_UINT32, 27, "LastLedgerSequence")
Definition: SField.h:379
ripple::jtPUBOLDLEDGER
@ jtPUBOLDLEDGER
Definition: Job.h:42
ripple::Ledger::info
LedgerInfo const & info() const override
Returns information about the ledger.
Definition: Ledger.h:155
std::chrono::time_point::time_since_epoch
T time_since_epoch(T... args)
ripple::NodeStore::Database::store
virtual void store(NodeObjectType type, Blob &&data, uint256 const &hash, std::uint32_t seq)=0
Store the object.
ripple::Ledger::txExists
bool txExists(uint256 const &key) const override
Returns true if a tx exists in the tx map.
Definition: Ledger.cpp:457
ripple::Ledger::assertSane
bool assertSane(beast::Journal ledgerJ) const
Definition: Ledger.cpp:652
ripple::saveValidatedLedger
static bool saveValidatedLedger(Application &app, std::shared_ptr< Ledger const > const &ledger, bool current)
Definition: Ledger.cpp:740
ripple::loadByHash
std::shared_ptr< Ledger > loadByHash(uint256 const &ledgerHash, Application &app, bool acquire)
Definition: Ledger.cpp:1117
ripple::DatabaseCon::checkoutDb
LockedSociSession checkoutDb()
Definition: DatabaseCon.h:129
ripple::base_uint::isZero
bool isZero() const
Definition: base_uint.h:475
ripple::Application::family
virtual Family & family()=0
ripple::Ledger::setAccepted
void setAccepted(NetClock::time_point closeTime, NetClock::duration closeResolution, bool correctCloseTime, Config const &config)
Definition: Ledger.cpp:337
ripple::Ledger
Holds a ledger.
Definition: Ledger.h:77
ripple::LedgerMaster::failedSave
void failedSave(std::uint32_t seq, uint256 const &hash)
Definition: LedgerMaster.cpp:929
ripple::Application::getLedgerMaster
virtual LedgerMaster & getLedgerMaster()=0
ripple::Ledger::setFull
void setFull() const
Definition: Ledger.h:274
ripple::keylet::account
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition: Indexes.cpp:120
ripple::SHAMapItem
Definition: SHAMapItem.h:34
ripple::Config
Definition: Config.h:66
ripple::Application::pendingSaves
virtual PendingSaves & pendingSaves()=0
ripple::deserializeTxPlusMeta
std::pair< std::shared_ptr< STTx const >, std::shared_ptr< STObject const > > deserializeTxPlusMeta(SHAMapItem const &item)
Deserialize a SHAMapItem containing STTx + STObject metadata.
Definition: Ledger.cpp:369
ripple::Config::TRANSACTION_FEE_BASE
static constexpr FeeUnit32 TRANSACTION_FEE_BASE
Definition: Config.h:132
ripple::Ledger::txs_iter_impl::copy
std::unique_ptr< base_type > copy() const override
Definition: Ledger.cpp:142
ripple::Rethrow
void Rethrow()
Rethrow the exception currently being handled.
Definition: contract.h:48
ripple::JsonOptions::none
@ none
ripple::Application::config
virtual Config & config()=0
ripple::isCurrent
bool isCurrent(ValidationParms const &p, NetClock::time_point now, NetClock::time_point signTime, NetClock::time_point seenTime)
Whether a validation is still current.
Definition: Validations.h:145
ripple::Ledger::txs_iter_impl::iter_
SHAMap::const_iterator iter_
Definition: Ledger.cpp:127
ripple::Ledger::stateMap
SHAMap const & stateMap() const
Definition: Ledger.h:289
ripple::Config::FEE_OWNER_RESERVE
XRPAmount FEE_OWNER_RESERVE
Definition: Config.h:158
ripple::SHAMap::const_iterator
Definition: SHAMap.h:536
ripple::calcAccountID
AccountID calcAccountID(PublicKey const &pk)
Definition: AccountID.cpp:131
ripple::SHAMap
A SHAMap is both a radix tree with a fan-out of 16 and a Merkle tree.
Definition: SHAMap.h:81
ripple::Ledger::sles_iter_impl::iter_
SHAMap::const_iterator iter_
Definition: Ledger.cpp:80
ripple::create_genesis_t
Definition: Ledger.h:45
ripple::Ledger::sles_iter_impl::equal
bool equal(base_type const &impl) const override
Definition: Ledger.cpp:100
ripple::LedgerInfo::closeFlags
int closeFlags
Definition: ReadView.h:110
std::to_string
T to_string(T... args)
ripple::Ledger::sles_iter_impl::operator=
sles_iter_impl & operator=(sles_iter_impl const &)=delete
ripple::Application::getJobQueue
virtual JobQueue & getJobQueue()=0
ripple::Config::FEE_ACCOUNT_RESERVE
XRPAmount FEE_ACCOUNT_RESERVE
Definition: Config.h:157
ripple::Ledger::rawInsert
void rawInsert(std::shared_ptr< SLE > const &sle) override
Unconditionally insert a state item.
Definition: Ledger.cpp:497
beast::Journal::info
Stream info() const
Definition: Journal.h:321
std::chrono::time_point
ripple::sfReferenceFeeUnits
const SF_U32 sfReferenceFeeUnits(access, STI_UINT32, 30, "ReferenceFeeUnits")
Definition: SField.h:382
std::vector::erase
T erase(T... args)
ripple::Application::logs
virtual Logs & logs()=0
ripple::Family
Definition: Family.h:32
ripple::ValStatus::current
@ current
This was a new validation and was added.
ripple::Job
Definition: Job.h:82
ripple::SerialIter
Definition: Serializer.h:308
ripple::PendingSaves::finishWork
void finishWork(LedgerIndex seq)
Finish working on a ledger.
Definition: PendingSaves.h:74
ripple::HashPrefix::transactionID
@ transactionID
transaction plus signature to give transaction ID
beast::Journal
A generic endpoint for log messages.
Definition: Journal.h:58
ripple::Application::getLedgerDB
virtual DatabaseCon & getLedgerDB()=0
std::uint32_t
ripple::Ledger::sles_iter_impl::sles_iter_impl
sles_iter_impl()=delete
ripple::Ledger::txs_iter_impl::txs_iter_impl
txs_iter_impl()=delete
ripple::Ledger::isImmutable
bool isImmutable() const
Definition: Ledger.h:258
std::map
STL class.
ripple::SHAMapItem::slice
Slice slice() const
Definition: SHAMapItem.h:63
ripple::jtPUBLEDGER
@ jtPUBLEDGER
Definition: Job.h:54
ripple::PendingSaves::shouldWork
bool shouldWork(LedgerIndex seq, bool isSynchronous)
Check if a ledger should be dispatched.
Definition: PendingSaves.h:99
ripple::base_uint::SetHexExact
bool SetHexExact(const char *psz)
Parse a hex string into a base_uint The string must contain exactly bytes * 2 hex characters and must...
Definition: base_uint.h:370
std::string::append
T append(T... args)
ripple::LedgerInfo::drops
XRPAmount drops
Definition: ReadView.h:101
ripple::KeyType::secp256k1
@ secp256k1
ripple::Serializer
Definition: Serializer.h:39
ripple::getJson
Json::Value getJson(LedgerFill const &fill)
Return a new Json::Value representing the ledger with given options.
Definition: LedgerToJson.cpp:283
std::ostringstream
STL class.
ripple::Ledger::read
std::shared_ptr< SLE const > read(Keylet const &k) const override
Return the state item associated with a key.
Definition: Ledger.cpp:406
ripple::Ledger::txMap
SHAMap const & txMap() const
Definition: Ledger.h:301
ripple::getCloseAgree
bool getCloseAgree(LedgerInfo const &info)
Definition: ReadView.h:414
ripple::Config::FEE_DEFAULT
XRPAmount FEE_DEFAULT
Definition: Config.h:156
ripple::generateSeed
Seed generateSeed(std::string const &passPhrase)
Generate a seed deterministically.
Definition: Seed.cpp:69
ripple::sfHashes
const SF_Vec256 sfHashes(access, STI_VECTOR256, 2, "Hashes")
Definition: SField.h:490
ripple::Ledger::txsBegin
std::unique_ptr< txs_type::iter_base > txsBegin() const override
Definition: Ledger.cpp:445
ripple::TransactionMaster::inLedger
bool inLedger(uint256 const &hash, std::uint32_t ledger)
Definition: TransactionMaster.cpp:40
std::vector::emplace_back
T emplace_back(T... args)
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::ReadView::sles_type
Definition: ReadView.h:198
ripple::Config::features
std::unordered_set< uint256, beast::uhash<> > features
Definition: Config.h:179
ripple::Application::getNodeStore
virtual NodeStore::Database & getNodeStore()=0
ripple::Application::journal
virtual beast::Journal journal(std::string const &name)=0
ripple::sfBalance
const SF_Amount sfBalance(access, STI_AMOUNT, 2, "Balance")
Definition: SField.h:440
ripple::calculateLedgerHash
static uint256 calculateLedgerHash(LedgerInfo const &info)
Definition: Ledger.cpp:59
ripple::Ledger::setup
bool setup(Config const &config)
Definition: Ledger.cpp:536
std::vector::begin
T begin(T... args)
ripple::sfReserveIncrement
const SF_U32 sfReserveIncrement(access, STI_UINT32, 32, "ReserveIncrement")
Definition: SField.h:384
std
STL namespace.
ripple::LogicError
void LogicError(std::string const &how) noexcept
Called when faulty logic causes a broken invariant.
Definition: contract.cpp:48
ripple::Fees::units
FeeUnit32 units
Definition: ReadView.h:50
ripple::LedgerInfo::closeTimeResolution
NetClock::duration closeTimeResolution
Definition: ReadView.h:113
ripple::sha512Half
sha512_half_hasher::result_type sha512Half(Args const &... args)
Returns the SHA512-Half of a series of objects.
Definition: digest.h:227
ripple::create_genesis
const create_genesis_t create_genesis
Definition: Ledger.cpp:56
cassert
ripple::Ledger::stateMap_
std::shared_ptr< SHAMap > stateMap_
Definition: Ledger.h:345
ripple::Ledger::updateSkipList
void updateSkipList()
Definition: Ledger.cpp:676
ripple::SerialIter::getVLDataLength
int getVLDataLength()
Definition: Serializer.cpp:462
ripple::Ledger::open
bool open() const override
Returns true if this reflects an open ledger.
Definition: Ledger.h:149
ripple::Ledger::succ
boost::optional< uint256 > succ(uint256 const &key, boost::optional< uint256 > const &last=boost::none) const override
Return the key of the next state item.
Definition: Ledger.cpp:395
std::chrono::duration::count
T count(T... args)
ripple::Ledger::txs_iter_impl::metadata_
bool metadata_
Definition: Ledger.cpp:126
ripple::STVector256
Definition: STVector256.h:29
ripple::Serializer::addVL
int addVL(Blob const &vector)
Definition: Serializer.cpp:192
std::vector::empty
T empty(T... args)
ripple::Rules
Rules controlling protocol behavior.
Definition: ReadView.h:127
ripple::SHAMapType
SHAMapType
Definition: SHAMapMissingNode.h:32
ripple::Ledger::txs_iter_impl
Definition: Ledger.cpp:123
std::ostringstream::str
T str(T... args)
beast::Journal::debug
Stream debug() const
Definition: Journal.h:315
ripple::JobType
JobType
Definition: Job.h:33
ripple::keylet::fees
Keylet const & fees() noexcept
The (fixed) index of the object containing the ledger fees.
Definition: Indexes.cpp:158
ripple::getHashesByIndex
bool getHashesByIndex(std::uint32_t ledgerIndex, uint256 &ledgerHash, uint256 &parentHash, Application &app)
Definition: Ledger.cpp:1164
ripple::hotLEDGER
@ hotLEDGER
Definition: NodeObject.h:34
ripple::Keylet::check
bool check(STLedgerEntry const &) const
Returns true if the SLE matches the type.
Definition: Keylet.cpp:26
ripple::Serializer::add32
int add32(std::uint32_t i)
Definition: Serializer.cpp:38
ripple::LedgerInfo
Information about the notional ledger backing the view.
Definition: ReadView.h:80
ripple::NetClock::duration
std::chrono::duration< rep, period > duration
Definition: chrono.h:53
ripple::SHAMapHash::as_uint256
uint256 const & as_uint256() const
Definition: SHAMapTreeNode.h:54
ripple::sfAmendments
const SF_Vec256 sfAmendments(access, STI_VECTOR256, 3, "Amendments")
Definition: SField.h:491
ripple::getNextLedgerTimeResolution
std::chrono::duration< Rep, Period > getNextLedgerTimeResolution(std::chrono::duration< Rep, Period > previousResolution, bool previousAgree, Seq ledgerSeq)
Calculates the close time resolution for the specified ledger.
Definition: LedgerTiming.h:77
ripple::sfBaseFee
const SF_U64 sfBaseFee(access, STI_UINT64, 5, "BaseFee")
Definition: SField.h:398
ripple::ledgerDefaultTimeResolution
constexpr auto ledgerDefaultTimeResolution
Initial resolution of ledger close time.
Definition: LedgerTiming.h:44
ripple::Ledger::txs_iter_impl::dereference
txs_type::value_type dereference() const override
Definition: Ledger.cpp:161
ripple::pendSaveValidated
bool pendSaveValidated(Application &app, std::shared_ptr< Ledger const > const &ledger, bool isSynchronous, bool isCurrent)
Save, or arrange to save, a fully-validated ledger Returns false on error.
Definition: Ledger.cpp:936
ripple::Ledger::Ledger
Ledger(Ledger const &)=delete
std::unique_ptr
STL class.
ripple::Ledger::digest
boost::optional< digest_type > digest(key_type const &key) const override
Return the digest associated with the key.
Definition: Ledger.cpp:477
ripple::Ledger::txs_iter_impl::increment
void increment() override
Definition: Ledger.cpp:155
ripple::NetClock::time_point
std::chrono::time_point< NetClock > time_point
Definition: chrono.h:54
ripple::Ledger::sles_iter_impl::copy
std::unique_ptr< base_type > copy() const override
Definition: Ledger.cpp:94
ripple::Application::getHashRouter
virtual HashRouter & getHashRouter()=0
ripple::Ledger::sles_iter_impl::increment
void increment() override
Definition: Ledger.cpp:107
ripple::HashRouter::setFlags
bool setFlags(uint256 const &key, int flags)
Set the flags on a hash.
Definition: HashRouter.cpp:96
ripple::LedgerInfo::accountHash
uint256 accountHash
Definition: ReadView.h:98
ripple::Ledger::rules_
Rules rules_
Definition: Ledger.h:351
ripple::Fees::base
XRPAmount base
Definition: ReadView.h:49
ripple::SerialIter::getSlice
Slice getSlice(std::size_t bytes)
Definition: Serializer.cpp:487
Json::Value
Represents a JSON value.
Definition: json_value.h:145
ripple::sLCF_NoConsensusTime
static const std::uint32_t sLCF_NoConsensusTime
Definition: ReadView.h:411
ripple::Application::getTxnDB
virtual DatabaseCon & getTxnDB()=0
ripple::open
void open(soci::session &s, BasicConfig const &config, std::string const &dbName)
Open a soci session.
Definition: SociDB.cpp:99
ripple::AccountIDCache::toBase58
std::string toBase58(AccountID const &) const
Return ripple::toBase58 for the AccountID.
Definition: AccountID.cpp:190
ripple::LedgerInfo::parentCloseTime
NetClock::time_point parentCloseTime
Definition: ReadView.h:89
ripple::Application::getMasterTransaction
virtual TransactionMaster & getMasterTransaction()=0