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