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