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