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  if (!stateMap_->addGiveItem(std::move(item), false, false))
503  LogicError("Ledger::rawInsert: key already exists");
504 }
505 
506 void
508 {
509  Serializer ss;
510  sle->add(ss);
511  auto item = std::make_shared<SHAMapItem const>(sle->key(), std::move(ss));
512 
513  if (!stateMap_->updateGiveItem(std::move(item), false, false))
514  LogicError("Ledger::rawReplace: key not found");
515 }
516 
517 void
519  uint256 const& key,
521  std::shared_ptr<Serializer const> const& metaData)
522 {
523  assert(metaData);
524 
525  // low-level - just add to table
526  Serializer s(txn->getDataLength() + metaData->getDataLength() + 16);
527  s.addVL(txn->peekData());
528  s.addVL(metaData->peekData());
529  auto item = std::make_shared<SHAMapItem const>(key, std::move(s));
530  if (!txMap().addGiveItem(std::move(item), true, true))
531  LogicError("duplicate_tx: " + to_string(key));
532 }
533 
534 bool
535 Ledger::setup(Config const& config)
536 {
537  bool ret = true;
538 
539  fees_.base = config.FEE_DEFAULT;
543 
544  try
545  {
546  if (auto const sle = read(keylet::fees()))
547  {
548  // VFALCO NOTE Why getFieldIndex and not isFieldPresent?
549 
550  if (sle->getFieldIndex(sfBaseFee) != -1)
551  fees_.base = sle->getFieldU64(sfBaseFee);
552 
553  if (sle->getFieldIndex(sfReferenceFeeUnits) != -1)
554  fees_.units = sle->getFieldU32(sfReferenceFeeUnits);
555 
556  if (sle->getFieldIndex(sfReserveBase) != -1)
557  fees_.reserve = sle->getFieldU32(sfReserveBase);
558 
559  if (sle->getFieldIndex(sfReserveIncrement) != -1)
560  fees_.increment = sle->getFieldU32(sfReserveIncrement);
561  }
562  }
563  catch (SHAMapMissingNode const&)
564  {
565  ret = false;
566  }
567  catch (std::exception const&)
568  {
569  Rethrow();
570  }
571 
572  try
573  {
574  rules_ = Rules(*this, config.features);
575  }
576  catch (SHAMapMissingNode const&)
577  {
578  ret = false;
579  }
580  catch (std::exception const&)
581  {
582  Rethrow();
583  }
584 
585  return ret;
586 }
587 
589 Ledger::peek(Keylet const& k) const
590 {
591  auto const& value = stateMap_->peekItem(k.key);
592  if (!value)
593  return nullptr;
594  auto sle = std::make_shared<SLE>(
595  SerialIter{value->data(), value->size()}, value->key());
596  if (!k.check(*sle))
597  return nullptr;
598  return sle;
599 }
600 
601 //------------------------------------------------------------------------------
602 bool
604 {
605  std::vector<SHAMapMissingNode> missingNodes1;
606  std::vector<SHAMapMissingNode> missingNodes2;
607 
608  if (stateMap_->getHash().isZero() && !info_.accountHash.isZero() &&
609  !stateMap_->fetchRoot(SHAMapHash{info_.accountHash}, nullptr))
610  {
611  missingNodes1.emplace_back(
613  }
614  else
615  {
616  stateMap_->walkMap(missingNodes1, 32);
617  }
618 
619  if (!missingNodes1.empty())
620  {
621  if (auto stream = j.info())
622  {
623  stream << missingNodes1.size() << " missing account node(s)";
624  stream << "First: " << missingNodes1[0].what();
625  }
626  }
627 
628  if (txMap_->getHash().isZero() && info_.txHash.isNonZero() &&
629  !txMap_->fetchRoot(SHAMapHash{info_.txHash}, nullptr))
630  {
631  missingNodes2.emplace_back(
633  }
634  else
635  {
636  txMap_->walkMap(missingNodes2, 32);
637  }
638 
639  if (!missingNodes2.empty())
640  {
641  if (auto stream = j.info())
642  {
643  stream << missingNodes2.size() << " missing transaction node(s)";
644  stream << "First: " << missingNodes2[0].what();
645  }
646  }
647  return missingNodes1.empty() && missingNodes2.empty();
648 }
649 
650 bool
652 {
654  txMap_ && (info_.accountHash == stateMap_->getHash().as_uint256()) &&
655  (info_.txHash == txMap_->getHash().as_uint256()))
656  {
657  return true;
658  }
659 
660  Json::Value j = getJson(*this);
661 
662  j[jss::accountTreeHash] = to_string(info_.accountHash);
663  j[jss::transTreeHash] = to_string(info_.txHash);
664 
665  JLOG(ledgerJ.fatal()) << "ledger is not sane" << j;
666 
667  assert(false);
668 
669  return false;
670 }
671 
672 // update the skip list with the information from our previous ledger
673 // VFALCO TODO Document this skip list concept
674 void
676 {
677  if (info_.seq == 0) // genesis ledger has no previous ledger
678  return;
679 
680  std::uint32_t prevIndex = info_.seq - 1;
681 
682  // update record of every 256th ledger
683  if ((prevIndex & 0xff) == 0)
684  {
685  auto const k = keylet::skip(prevIndex);
686  auto sle = peek(k);
687  std::vector<uint256> hashes;
688 
689  bool created;
690  if (!sle)
691  {
692  sle = std::make_shared<SLE>(k);
693  created = true;
694  }
695  else
696  {
697  hashes = static_cast<decltype(hashes)>(sle->getFieldV256(sfHashes));
698  created = false;
699  }
700 
701  assert(hashes.size() <= 256);
702  hashes.push_back(info_.parentHash);
703  sle->setFieldV256(sfHashes, STVector256(hashes));
704  sle->setFieldU32(sfLastLedgerSequence, prevIndex);
705  if (created)
706  rawInsert(sle);
707  else
708  rawReplace(sle);
709  }
710 
711  // update record of past 256 ledger
712  auto const k = keylet::skip();
713  auto sle = peek(k);
714  std::vector<uint256> hashes;
715  bool created;
716  if (!sle)
717  {
718  sle = std::make_shared<SLE>(k);
719  created = true;
720  }
721  else
722  {
723  hashes = static_cast<decltype(hashes)>(sle->getFieldV256(sfHashes));
724  created = false;
725  }
726  assert(hashes.size() <= 256);
727  if (hashes.size() == 256)
728  hashes.erase(hashes.begin());
729  hashes.push_back(info_.parentHash);
730  sle->setFieldV256(sfHashes, STVector256(hashes));
731  sle->setFieldU32(sfLastLedgerSequence, prevIndex);
732  if (created)
733  rawInsert(sle);
734  else
735  rawReplace(sle);
736 }
737 
738 static bool
740  Application& app,
741  std::shared_ptr<Ledger const> const& ledger,
742  bool current)
743 {
744  auto j = app.journal("Ledger");
745  auto seq = ledger->info().seq;
746  if (!app.pendingSaves().startWork(seq))
747  {
748  // The save was completed synchronously
749  JLOG(j.debug()) << "Save aborted";
750  return true;
751  }
752 
753  // TODO(tom): Fix this hard-coded SQL!
754  JLOG(j.trace()) << "saveValidatedLedger " << (current ? "" : "fromAcquire ")
755  << seq;
756  static boost::format deleteLedger(
757  "DELETE FROM Ledgers WHERE LedgerSeq = %u;");
758  static boost::format deleteTrans1(
759  "DELETE FROM Transactions WHERE LedgerSeq = %u;");
760  static boost::format deleteTrans2(
761  "DELETE FROM AccountTransactions WHERE LedgerSeq = %u;");
762  static boost::format deleteAcctTrans(
763  "DELETE FROM AccountTransactions WHERE TransID = '%s';");
764 
765  if (!ledger->info().accountHash.isNonZero())
766  {
767  JLOG(j.fatal()) << "AH is zero: " << getJson(*ledger);
768  assert(false);
769  }
770 
771  if (ledger->info().accountHash != ledger->stateMap().getHash().as_uint256())
772  {
773  JLOG(j.fatal()) << "sAL: " << ledger->info().accountHash
774  << " != " << ledger->stateMap().getHash();
775  JLOG(j.fatal()) << "saveAcceptedLedger: seq=" << seq
776  << ", current=" << current;
777  assert(false);
778  }
779 
780  assert(ledger->info().txHash == ledger->txMap().getHash().as_uint256());
781 
782  // Save the ledger header in the hashed object store
783  {
784  Serializer s(128);
786  addRaw(ledger->info(), s);
787  app.getNodeStore().store(
788  hotLEDGER, std::move(s.modData()), ledger->info().hash, seq);
789  }
790 
791  AcceptedLedger::pointer aLedger;
792  try
793  {
794  aLedger = app.getAcceptedLedgerCache().fetch(ledger->info().hash);
795  if (!aLedger)
796  {
797  aLedger = std::make_shared<AcceptedLedger>(
798  ledger, app.accountIDCache(), app.logs());
799  app.getAcceptedLedgerCache().canonicalize_replace_client(
800  ledger->info().hash, aLedger);
801  }
802  }
803  catch (std::exception const&)
804  {
805  JLOG(j.warn()) << "An accepted ledger was missing nodes";
806  app.getLedgerMaster().failedSave(seq, ledger->info().hash);
807  // Clients can now trust the database for information about this
808  // ledger sequence.
809  app.pendingSaves().finishWork(seq);
810  return false;
811  }
812 
813  {
814  auto db = app.getLedgerDB().checkoutDb();
815  *db << boost::str(deleteLedger % seq);
816  }
817 
818  {
819  auto db = app.getTxnDB().checkoutDb();
820 
821  soci::transaction tr(*db);
822 
823  *db << boost::str(deleteTrans1 % seq);
824  *db << boost::str(deleteTrans2 % seq);
825 
826  std::string const ledgerSeq(std::to_string(seq));
827 
828  for (auto const& [_, acceptedLedgerTx] : aLedger->getMap())
829  {
830  (void)_;
831  uint256 transactionID = acceptedLedgerTx->getTransactionID();
832 
834 
835  std::string const txnId(to_string(transactionID));
836  std::string const txnSeq(
837  std::to_string(acceptedLedgerTx->getTxnSeq()));
838 
839  *db << boost::str(deleteAcctTrans % transactionID);
840 
841  auto const& accts = acceptedLedgerTx->getAffected();
842 
843  if (!accts.empty())
844  {
845  std::string sql(
846  "INSERT INTO AccountTransactions "
847  "(TransID, Account, LedgerSeq, TxnSeq) VALUES ");
848 
849  // Try to make an educated guess on how much space we'll need
850  // for our arguments. In argument order we have:
851  // 64 + 34 + 10 + 10 = 118 + 10 extra = 128 bytes
852  sql.reserve(sql.length() + (accts.size() * 128));
853 
854  bool first = true;
855  for (auto const& account : accts)
856  {
857  if (!first)
858  sql += ", ('";
859  else
860  {
861  sql += "('";
862  first = false;
863  }
864 
865  sql += txnId;
866  sql += "','";
867  sql += app.accountIDCache().toBase58(account);
868  sql += "',";
869  sql += ledgerSeq;
870  sql += ",";
871  sql += txnSeq;
872  sql += ")";
873  }
874  sql += ";";
875  JLOG(j.trace()) << "ActTx: " << sql;
876  *db << sql;
877  }
878  else
879  {
880  JLOG(j.warn()) << "Transaction in ledger " << seq
881  << " affects no accounts";
882  JLOG(j.warn())
883  << acceptedLedgerTx->getTxn()->getJson(JsonOptions::none);
884  }
885 
886  *db
888  acceptedLedgerTx->getTxn()->getMetaSQL(
889  seq, acceptedLedgerTx->getEscMeta()) +
890  ";");
891  }
892 
893  tr.commit();
894  }
895 
896  {
897  static std::string addLedger(
898  R"sql(INSERT OR REPLACE INTO Ledgers
899  (LedgerHash,LedgerSeq,PrevHash,TotalCoins,ClosingTime,PrevClosingTime,
900  CloseTimeRes,CloseFlags,AccountSetHash,TransSetHash)
901  VALUES
902  (:ledgerHash,:ledgerSeq,:prevHash,:totalCoins,:closingTime,:prevClosingTime,
903  :closeTimeRes,:closeFlags,:accountSetHash,:transSetHash);)sql");
904 
905  auto db(app.getLedgerDB().checkoutDb());
906 
907  soci::transaction tr(*db);
908 
909  auto const hash = to_string(ledger->info().hash);
910  auto const parentHash = to_string(ledger->info().parentHash);
911  auto const drops = to_string(ledger->info().drops);
912  auto const closeTime =
913  ledger->info().closeTime.time_since_epoch().count();
914  auto const parentCloseTime =
915  ledger->info().parentCloseTime.time_since_epoch().count();
916  auto const closeTimeResolution =
917  ledger->info().closeTimeResolution.count();
918  auto const closeFlags = ledger->info().closeFlags;
919  auto const accountHash = to_string(ledger->info().accountHash);
920  auto const txHash = to_string(ledger->info().txHash);
921 
922  *db << addLedger, soci::use(hash), soci::use(seq),
923  soci::use(parentHash), soci::use(drops), soci::use(closeTime),
924  soci::use(parentCloseTime), soci::use(closeTimeResolution),
925  soci::use(closeFlags), soci::use(accountHash), soci::use(txHash);
926 
927  tr.commit();
928  }
929 
930  // Clients can now trust the database for
931  // information about this ledger sequence.
932  app.pendingSaves().finishWork(seq);
933  return true;
934 }
935 
939 bool
941  Application& app,
942  std::shared_ptr<Ledger const> const& ledger,
943  bool isSynchronous,
944  bool isCurrent)
945 {
946  if (!app.getHashRouter().setFlags(ledger->info().hash, SF_SAVED))
947  {
948  // We have tried to save this ledger recently
949  auto stream = app.journal("Ledger").debug();
950  JLOG(stream) << "Double pend save for " << ledger->info().seq;
951 
952  if (!isSynchronous || !app.pendingSaves().pending(ledger->info().seq))
953  {
954  // Either we don't need it to be finished
955  // or it is finished
956  return true;
957  }
958  }
959 
960  assert(ledger->isImmutable());
961 
962  if (!app.pendingSaves().shouldWork(ledger->info().seq, isSynchronous))
963  {
964  auto stream = app.journal("Ledger").debug();
965  JLOG(stream) << "Pend save with seq in pending saves "
966  << ledger->info().seq;
967 
968  return true;
969  }
970 
971  JobType const jobType{isCurrent ? jtPUBLEDGER : jtPUBOLDLEDGER};
972  char const* const jobName{
973  isCurrent ? "Ledger::pendSave" : "Ledger::pendOldSave"};
974 
975  // See if we can use the JobQueue.
976  if (!isSynchronous &&
977  app.getJobQueue().addJob(
978  jobType, jobName, [&app, ledger, isCurrent](Job&) {
979  saveValidatedLedger(app, ledger, isCurrent);
980  }))
981  {
982  return true;
983  }
984 
985  // The JobQueue won't do the Job. Do the save synchronously.
986  return saveValidatedLedger(app, ledger, isCurrent);
987 }
988 
989 void
990 Ledger::unshare() const
991 {
992  stateMap_->unshare();
993  txMap_->unshare();
994 }
995 
996 void
997 Ledger::invariants() const
998 {
999  stateMap_->invariants();
1000  txMap_->invariants();
1001 }
1002 
1003 //------------------------------------------------------------------------------
1004 
1005 /*
1006  * Load a ledger from the database.
1007  *
1008  * @param sqlSuffix: Additional string to append to the sql query.
1009  * (typically a where clause).
1010  * @param acquire: Acquire the ledger if not found locally.
1011  * @return The ledger, ledger sequence, and ledger hash.
1012  */
1014 loadLedgerHelper(std::string const& sqlSuffix, Application& app, bool acquire)
1015 {
1016  uint256 ledgerHash{};
1017  std::uint32_t ledgerSeq{0};
1018 
1019  auto db = app.getLedgerDB().checkoutDb();
1020 
1021  boost::optional<std::string> sLedgerHash, sPrevHash, sAccountHash,
1022  sTransHash;
1023  boost::optional<std::uint64_t> totDrops, closingTime, prevClosingTime,
1024  closeResolution, closeFlags, ledgerSeq64;
1025 
1026  std::string const sql =
1027  "SELECT "
1028  "LedgerHash, PrevHash, AccountSetHash, TransSetHash, "
1029  "TotalCoins,"
1030  "ClosingTime, PrevClosingTime, CloseTimeRes, CloseFlags,"
1031  "LedgerSeq from Ledgers " +
1032  sqlSuffix + ";";
1033 
1034  *db << sql, soci::into(sLedgerHash), soci::into(sPrevHash),
1035  soci::into(sAccountHash), soci::into(sTransHash), soci::into(totDrops),
1036  soci::into(closingTime), soci::into(prevClosingTime),
1037  soci::into(closeResolution), soci::into(closeFlags),
1038  soci::into(ledgerSeq64);
1039 
1040  if (!db->got_data())
1041  {
1042  auto stream = app.journal("Ledger").debug();
1043  JLOG(stream) << "Ledger not found: " << sqlSuffix;
1044  return std::make_tuple(
1045  std::shared_ptr<Ledger>(), ledgerSeq, ledgerHash);
1046  }
1047 
1048  ledgerSeq = rangeCheckedCast<std::uint32_t>(ledgerSeq64.value_or(0));
1049 
1050  uint256 prevHash{}, accountHash{}, transHash{};
1051  if (sLedgerHash)
1052  ledgerHash.SetHexExact(*sLedgerHash);
1053  if (sPrevHash)
1054  prevHash.SetHexExact(*sPrevHash);
1055  if (sAccountHash)
1056  accountHash.SetHexExact(*sAccountHash);
1057  if (sTransHash)
1058  transHash.SetHexExact(*sTransHash);
1059 
1060  using time_point = NetClock::time_point;
1061  using duration = NetClock::duration;
1062 
1063  LedgerInfo info;
1064  info.parentHash = prevHash;
1065  info.txHash = transHash;
1066  info.accountHash = accountHash;
1067  info.drops = totDrops.value_or(0);
1068  info.closeTime = time_point{duration{closingTime.value_or(0)}};
1069  info.parentCloseTime = time_point{duration{prevClosingTime.value_or(0)}};
1070  info.closeFlags = closeFlags.value_or(0);
1071  info.closeTimeResolution = duration{closeResolution.value_or(0)};
1072  info.seq = ledgerSeq;
1073 
1074  bool loaded;
1075  auto ledger = std::make_shared<Ledger>(
1076  info,
1077  loaded,
1078  acquire,
1079  app.config(),
1080  app.family(),
1081  app.journal("Ledger"));
1082 
1083  if (!loaded)
1084  ledger.reset();
1086  return std::make_tuple(ledger, ledgerSeq, ledgerHash);
1087 }
1088 
1089 static void
1091  std::shared_ptr<Ledger> const& ledger,
1092  Config const& config,
1093  beast::Journal j)
1094 {
1095  if (!ledger)
1096  return;
1097 
1098  ledger->setImmutable(config);
1099 
1100  JLOG(j.trace()) << "Loaded ledger: " << to_string(ledger->info().hash);
1102  ledger->setFull();
1103 }
1104 
1106 loadByIndex(std::uint32_t ledgerIndex, Application& app, bool acquire)
1107 {
1108  std::shared_ptr<Ledger> ledger;
1109  {
1111  s << "WHERE LedgerSeq = " << ledgerIndex;
1112  std::tie(ledger, std::ignore, std::ignore) =
1113  loadLedgerHelper(s.str(), app, acquire);
1114  }
1115 
1116  finishLoadByIndexOrHash(ledger, app.config(), app.journal("Ledger"));
1117  return ledger;
1118 }
1119 
1121 loadByHash(uint256 const& ledgerHash, Application& app, bool acquire)
1122 {
1123  std::shared_ptr<Ledger> ledger;
1124  {
1126  s << "WHERE LedgerHash = '" << ledgerHash << "'";
1127  std::tie(ledger, std::ignore, std::ignore) =
1128  loadLedgerHelper(s.str(), app, acquire);
1129  }
1130 
1131  finishLoadByIndexOrHash(ledger, app.config(), app.journal("Ledger"));
1132 
1133  assert(!ledger || ledger->info().hash == ledgerHash);
1135  return ledger;
1136 }
1137 
1138 uint256
1139 getHashByIndex(std::uint32_t ledgerIndex, Application& app)
1140 {
1141  uint256 ret;
1142 
1143  std::string sql =
1144  "SELECT LedgerHash FROM Ledgers INDEXED BY SeqLedger WHERE LedgerSeq='";
1145  sql.append(beast::lexicalCastThrow<std::string>(ledgerIndex));
1146  sql.append("';");
1147 
1148  std::string hash;
1149  {
1150  auto db = app.getLedgerDB().checkoutDb();
1151 
1152  boost::optional<std::string> lh;
1153  *db << sql, soci::into(lh);
1154 
1155  if (!db->got_data() || !lh)
1156  return ret;
1157 
1158  hash = *lh;
1159  if (hash.empty())
1160  return ret;
1161  }
1162 
1163  ret.SetHexExact(hash);
1164  return ret;
1165 }
1166 
1167 bool
1169  std::uint32_t ledgerIndex,
1170  uint256& ledgerHash,
1171  uint256& parentHash,
1172  Application& app)
1173 {
1174  auto db = app.getLedgerDB().checkoutDb();
1175 
1176  boost::optional<std::string> lhO, phO;
1177 
1178  *db << "SELECT LedgerHash,PrevHash FROM Ledgers "
1179  "INDEXED BY SeqLedger Where LedgerSeq = :ls;",
1180  soci::into(lhO), soci::into(phO), soci::use(ledgerIndex);
1181 
1182  if (!lhO || !phO)
1183  {
1184  auto stream = app.journal("Ledger").trace();
1185  JLOG(stream) << "Don't have ledger " << ledgerIndex;
1186  return false;
1187  }
1188 
1189  ledgerHash.SetHexExact(*lhO);
1190  parentHash.SetHexExact(*phO);
1192  return true;
1193 }
1194 
1196 getHashesByIndex(std::uint32_t minSeq, std::uint32_t maxSeq, Application& app)
1197 {
1199 
1200  std::string sql =
1201  "SELECT LedgerSeq,LedgerHash,PrevHash FROM Ledgers WHERE LedgerSeq >= ";
1202  sql.append(beast::lexicalCastThrow<std::string>(minSeq));
1203  sql.append(" AND LedgerSeq <= ");
1204  sql.append(beast::lexicalCastThrow<std::string>(maxSeq));
1205  sql.append(";");
1206 
1207  auto db = app.getLedgerDB().checkoutDb();
1208 
1209  std::uint64_t ls;
1210  std::string lh;
1211  boost::optional<std::string> ph;
1212  soci::statement st =
1213  (db->prepare << sql, soci::into(ls), soci::into(lh), soci::into(ph));
1214 
1215  st.execute();
1216  while (st.fetch())
1217  {
1218  std::pair<uint256, uint256>& hashes =
1219  ret[rangeCheckedCast<std::uint32_t>(ls)];
1220  hashes.first.SetHexExact(lh);
1221  if (ph)
1222  hashes.second.SetHexExact(*ph);
1223  else
1224  hashes.second.zero();
1225  if (!ph)
1226  {
1227  auto stream = app.journal("Ledger").warn();
1228  JLOG(stream) << "Null prev hash for ledger seq: " << ls;
1229  }
1230  }
1231 
1232  return ret;
1233 }
1234 
1235 } // 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:1009
ripple::Application
Definition: Application.h:97
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:507
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:791
ripple::loadByIndex
std::shared_ptr< Ledger > loadByIndex(std::uint32_t ledgerIndex, Application &app, bool acquire)
Definition: Ledger.cpp:1101
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:985
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:589
ripple::Ledger::invariants
void invariants() const
Definition: Ledger.cpp:992
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:603
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:518
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:1085
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:1134
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:651
ripple::saveValidatedLedger
static bool saveValidatedLedger(Application &app, std::shared_ptr< Ledger const > const &ledger, bool current)
Definition: Ledger.cpp:739
ripple::loadByHash
std::shared_ptr< Ledger > loadByHash(uint256 const &ledgerHash, Application &app, bool acquire)
Definition: Ledger.cpp:1116
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:911
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:160
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:159
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:158
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:181
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:535
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:675
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:1163
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:935
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