xrpld
Loading...
Searching...
No Matches
libxrpl/ledger/Ledger.cpp
1#include <xrpl/ledger/Ledger.h>
2
3#include <xrpl/basics/Log.h>
4#include <xrpl/basics/Slice.h>
5#include <xrpl/basics/UnorderedContainers.h>
6#include <xrpl/basics/base_uint.h>
7#include <xrpl/basics/chrono.h>
8#include <xrpl/basics/contract.h>
9#include <xrpl/beast/utility/Journal.h>
10#include <xrpl/beast/utility/Zero.h>
11#include <xrpl/beast/utility/instrumentation.h>
12#include <xrpl/ledger/LedgerTiming.h>
13#include <xrpl/ledger/ReadView.h>
14#include <xrpl/ledger/entries/FeeSettingsEntry.h>
15#include <xrpl/ledger/entries/NegativeUNLEntry.h>
16#include <xrpl/nodestore/NodeObject.h>
17#include <xrpl/protocol/Feature.h>
18#include <xrpl/protocol/Fees.h>
19#include <xrpl/protocol/Indexes.h>
20#include <xrpl/protocol/KeyType.h>
21#include <xrpl/protocol/Keylet.h>
22#include <xrpl/protocol/LedgerHeader.h>
23#include <xrpl/protocol/Protocol.h>
24#include <xrpl/protocol/PublicKey.h>
25#include <xrpl/protocol/Rules.h>
26#include <xrpl/protocol/SField.h>
27#include <xrpl/protocol/STArray.h>
28#include <xrpl/protocol/STLedgerEntry.h>
29#include <xrpl/protocol/STObject.h>
30#include <xrpl/protocol/STTx.h>
31#include <xrpl/protocol/SecretKey.h>
32#include <xrpl/protocol/Seed.h>
33#include <xrpl/protocol/Serializer.h>
34#include <xrpl/protocol/SystemParameters.h>
35#include <xrpl/shamap/Family.h>
36#include <xrpl/shamap/SHAMap.h>
37#include <xrpl/shamap/SHAMapItem.h>
38#include <xrpl/shamap/SHAMapMissingNode.h>
39#include <xrpl/shamap/SHAMapTreeNode.h>
40
41#include <algorithm>
42#include <cstdint>
43#include <exception>
44#include <memory>
45#include <optional>
46#include <utility>
47#include <vector>
48
49namespace xrpl {
50
52
53//------------------------------------------------------------------------------
54
55class Ledger::SlesIterImpl : public SlesType::IterBase
56{
57private:
59
60public:
61 SlesIterImpl() = delete;
63 operator=(SlesIterImpl const&) = delete;
64
65 SlesIterImpl(SlesIterImpl const&) = default;
66
68 {
69 }
70
71 [[nodiscard]] std::unique_ptr<BaseType>
72 copy() const override
73 {
75 }
76
77 [[nodiscard]] bool
78 equal(BaseType const& impl) const override
79 {
80 if (auto const p = dynamic_cast<SlesIterImpl const*>(&impl))
81 return iter_ == p->iter_;
82 return false;
83 }
84
85 void
86 increment() override
87 {
88 ++iter_;
89 }
90
91 [[nodiscard]] SlesType::value_type
92 dereference() const override
93 {
94 SerialIter sit(iter_->slice());
95 return std::make_shared<SLE const>(sit, iter_->key());
96 }
97};
98
99//------------------------------------------------------------------------------
100
101class Ledger::TxsIterImpl : public TxsType::IterBase
102{
103private:
106
107public:
108 TxsIterImpl() = delete;
110 operator=(TxsIterImpl const&) = delete;
111
112 TxsIterImpl(TxsIterImpl const&) = default;
113
114 TxsIterImpl(bool metadata, SHAMap::ConstIterator iter) : metadata_(metadata), iter_(iter)
115 {
116 }
117
118 [[nodiscard]] std::unique_ptr<BaseType>
119 copy() const override
120 {
121 return std::make_unique<TxsIterImpl>(*this);
122 }
123
124 [[nodiscard]] bool
125 equal(BaseType const& impl) const override
126 {
127 if (auto const p = dynamic_cast<TxsIterImpl const*>(&impl))
128 return iter_ == p->iter_;
129 return false;
130 }
131
132 void
133 increment() override
134 {
135 ++iter_;
136 }
137
138 [[nodiscard]] TxsType::value_type
139 dereference() const override
140 {
141 auto const& item = *iter_;
142 if (metadata_)
144 return {Ledger::deserializeTx(item), nullptr};
145 }
146};
147
148//------------------------------------------------------------------------------
149
152 Rules rules,
153 Fees const& fees,
154 std::vector<UInt256> const& amendments,
155 Family& family)
156 : immutable_(false)
157 , txMap_(SHAMapType::TRANSACTION, family)
158 , stateMap_(SHAMapType::STATE, family)
159 , fees_(fees)
160 , rules_(std::move(rules))
161 , j_(beast::Journal(beast::Journal::getNullSink()))
162{
163 header_.seq = 1;
164 header_.drops = kInitialXrp;
165 header_.closeTimeResolution = kLedgerGenesisTimeResolution;
166
167 static auto const kID =
169 {
170 auto const sle = std::make_shared<SLE>(keylet::account(kID));
171 sle->setFieldU32(sfSequence, 1);
172 sle->setAccountID(sfAccount, kID);
173 sle->setFieldAmount(sfBalance, header_.drops);
174 rawInsert(sle);
175 }
176
177 if (!amendments.empty())
178 {
179 auto const sle = std::make_shared<SLE>(keylet::amendments());
180 sle->setFieldV256(sfAmendments, STVector256{amendments});
181 rawInsert(sle);
182 }
183
184 {
186 // Whether featureXRPFees is supported will depend on startup options.
187 if (std::ranges::find(amendments, featureXRPFees) != amendments.end())
188 {
189 sle->at(sfBaseFeeDrops) = fees.base;
190 sle->at(sfReserveBaseDrops) = fees.reserve;
191 sle->at(sfReserveIncrementDrops) = fees.increment;
192 }
193 else
194 {
195 if (auto const f = fees.base.dropsAs<std::uint64_t>())
196 sle->at(sfBaseFee) = *f;
197 if (auto const f = fees.reserve.dropsAs<std::uint32_t>())
198 sle->at(sfReserveBase) = *f;
199 if (auto const f = fees.increment.dropsAs<std::uint32_t>())
200 sle->at(sfReserveIncrement) = *f;
201 sle->at(sfReferenceFeeUnits) = kFeeUnitsDeprecated;
202 }
203 rawInsert(sle);
204 }
205
207 setImmutable();
208}
209
211 LedgerHeader const& info,
212 bool& loaded,
213 bool acquire,
214 Rules rules,
215 Fees const& fees,
216 Family& family,
218 : immutable_(true)
219 , txMap_(SHAMapType::TRANSACTION, info.txHash, family)
220 , stateMap_(SHAMapType::STATE, info.accountHash, family)
221 , fees_(fees)
222 , rules_(std::move(rules))
223 , header_(info)
224 , j_(j)
225{
226 loaded = true;
227
228 if (header_.txHash.isNonZero() && !txMap_.fetchRoot(SHAMapHash{header_.txHash}, nullptr))
229 {
230 loaded = false;
231 JLOG(j.warn()) << "Don't have transaction root for ledger" << header_.seq;
232 }
233
234 if (header_.accountHash.isNonZero() &&
235 !stateMap_.fetchRoot(SHAMapHash{header_.accountHash}, nullptr))
236 {
237 loaded = false;
238 JLOG(j.warn()) << "Don't have state data root for ledger" << header_.seq;
239 }
240
241 txMap_.setImmutable();
242 stateMap_.setImmutable();
243
244 if (!setup())
245 loaded = false;
246
247 if (!loaded)
248 {
250 if (acquire)
251 family.missingNodeAcquireByHash(header_.hash, header_.seq);
252 }
253}
254
255// Create a new ledger that follows this one
256Ledger::Ledger(Ledger const& prevLedger, NetClock::time_point closeTime)
257 : immutable_(false)
258 , txMap_(SHAMapType::TRANSACTION, prevLedger.txMap_.family())
259 , stateMap_(prevLedger.stateMap_, true)
260 , fees_(prevLedger.fees_)
261 , rules_(prevLedger.rules_)
262 , j_(beast::Journal(beast::Journal::getNullSink()))
263{
264 header_.seq = prevLedger.header_.seq + 1;
265 header_.parentCloseTime = prevLedger.header_.closeTime;
266 header_.hash = prevLedger.header().hash + UInt256(1);
267 header_.drops = prevLedger.header().drops;
268 header_.closeTimeResolution = prevLedger.header_.closeTimeResolution;
269 header_.parentHash = prevLedger.header().hash;
270 header_.closeTimeResolution = getNextLedgerTimeResolution(
271 prevLedger.header_.closeTimeResolution, getCloseAgree(prevLedger.header()), header_.seq);
272
273 if (prevLedger.header_.closeTime == NetClock::time_point{})
274 {
275 header_.closeTime = roundCloseTime(closeTime, header_.closeTimeResolution);
276 }
277 else
278 {
279 header_.closeTime = prevLedger.header_.closeTime + header_.closeTimeResolution;
280 }
281}
282
284 : immutable_(true)
285 , txMap_(SHAMapType::TRANSACTION, info.txHash, family)
286 , stateMap_(SHAMapType::STATE, info.accountHash, family)
287 , rules_(std::move(rules))
288 , header_(info)
289 , j_(beast::Journal(beast::Journal::getNullSink()))
290{
292}
293
295 std::uint32_t ledgerSeq,
296 NetClock::time_point closeTime,
297 Rules rules,
298 Fees const& fees,
299 Family& family)
300 : immutable_(false)
301 , txMap_(SHAMapType::TRANSACTION, family)
302 , stateMap_(SHAMapType::STATE, family)
303 , fees_(fees)
304 , rules_(std::move(rules))
305 , j_(beast::Journal(beast::Journal::getNullSink()))
306{
307 header_.seq = ledgerSeq;
308 header_.closeTime = closeTime;
309 header_.closeTimeResolution = kLedgerDefaultTimeResolution;
310 setup();
311}
312
313void
315{
316 // Force update, since this is the only
317 // place the hash transitions to valid
318 if (!immutable_ && rehash)
319 {
320 header_.txHash = txMap_.getHash().asUInt256();
321 header_.accountHash = stateMap_.getHash().asUInt256();
322 }
323
324 if (rehash)
326
327 immutable_ = true;
328 txMap_.setImmutable();
329 stateMap_.setImmutable();
330 setup();
331}
332
333void
335 NetClock::time_point closeTime,
336 NetClock::duration closeResolution,
337 bool correctCloseTime)
338{
339 // Used when we witnessed the consensus.
340 XRPL_ASSERT(!open(), "xrpl::Ledger::setAccepted : valid ledger state");
341
342 header_.closeTime = closeTime;
343 header_.closeTimeResolution = closeResolution;
344 header_.closeFlags = correctCloseTime ? 0 : kSLcfNoConsensusTime;
345 setImmutable();
346}
347
348bool
350{
351 auto const s = sle.getSerializer();
352 return stateMap_.addItem(SHAMapNodeType::TnAccountState, makeShamapitem(sle.key(), s.slice()));
353}
354
355//------------------------------------------------------------------------------
356
359{
360 SerialIter sit(item.slice());
362}
363
366{
368 SerialIter sit(item.slice());
369 {
370 SerialIter s(sit.getSlice(sit.getVLDataLength()));
372 }
373 {
374 SerialIter s(sit.getSlice(sit.getVLDataLength()));
375 result.second = std::make_shared<STObject const>(s, sfMetadata);
376 }
377 return result;
378}
379
380//------------------------------------------------------------------------------
381
382bool
383Ledger::exists(Keylet const& k) const
384{
385 // VFALCO NOTE Perhaps check the type for debug builds?
386 return stateMap_.hasItem(k.key);
387}
388
389bool
390Ledger::exists(UInt256 const& key) const
391{
392 return stateMap_.hasItem(key);
393}
394
396Ledger::succ(UInt256 const& key, std::optional<UInt256> const& last) const
397{
398 auto item = stateMap_.upperBound(key);
399 if (item == stateMap_.end())
400 return std::nullopt;
401 if (last && item->key() >= last)
402 return std::nullopt;
403 return item->key();
404}
405
407Ledger::read(Keylet const& k) const
408{
409 if (k.key == beast::kZero)
410 {
411 // LCOV_EXCL_START
412 UNREACHABLE("xrpl::Ledger::read : zero key");
413 return nullptr;
414 // LCOV_EXCL_STOP
415 }
416 auto const& item = stateMap_.peekItem(k.key);
417 if (!item)
418 return nullptr;
419 auto sle = std::make_shared<SLE>(SerialIter{item->slice()}, item->key());
420 if (!k.check(*sle))
421 return nullptr;
422 return sle;
423}
424
425//------------------------------------------------------------------------------
426
427auto
428Ledger::slesBegin() const -> std::unique_ptr<SlesType::IterBase>
429{
431}
432
433auto
434Ledger::slesEnd() const -> std::unique_ptr<SlesType::IterBase>
435{
437}
438
439auto
444
445auto
446Ledger::txsBegin() const -> std::unique_ptr<TxsType::IterBase>
447{
448 return std::make_unique<TxsIterImpl>(!open(), txMap_.begin());
449}
450
451auto
452Ledger::txsEnd() const -> std::unique_ptr<TxsType::IterBase>
453{
454 return std::make_unique<TxsIterImpl>(!open(), txMap_.end());
455}
456
457bool
458Ledger::txExists(UInt256 const& key) const
459{
460 return txMap_.hasItem(key);
461}
462
463auto
464Ledger::txRead(key_type const& key) const -> TxType
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
477auto
479{
481 // VFALCO Unfortunately this loads the item
482 // from the NodeStore needlessly.
483 if (!stateMap_.peekItem(key, digest))
484 return std::nullopt;
485 return digest.asUInt256();
486}
487
488//------------------------------------------------------------------------------
489
490void
492{
493 if (!stateMap_.delItem(sle->key()))
494 logicError("Ledger::rawErase: key not found");
495}
496
497void
499{
500 if (!stateMap_.delItem(key))
501 logicError("Ledger::rawErase: key not found");
502}
503
504void
506{
507 Serializer ss;
508 sle->add(ss);
509 if (!stateMap_.addGiveItem(
511 {
512 logicError("Ledger::rawInsert: key already exists");
513 }
514}
515
516void
518{
519 Serializer ss;
520 sle->add(ss);
521 if (!stateMap_.updateGiveItem(
523 {
524 logicError("Ledger::rawReplace: key not found");
525 }
526}
527
528void
530 UInt256 const& key,
532 std::shared_ptr<Serializer const> const& metaData)
533{
534 XRPL_ASSERT(metaData, "xrpl::Ledger::rawTxInsert : non-null metadata input");
535
536 // low-level - just add to table
537 Serializer s(txn->getDataLength() + metaData->getDataLength() + 16);
538 s.addVL(txn->peekData());
539 s.addVL(metaData->peekData());
540 if (!txMap_.addGiveItem(SHAMapNodeType::TnTransactionMd, makeShamapitem(key, s.slice())))
541 logicError("duplicate_tx: " + to_string(key));
542}
543
544bool
546{
547 bool ret = true;
548
549 try
550 {
552 }
553 catch (SHAMapMissingNode const&)
554 {
555 ret = false;
556 }
557 catch (std::exception const& ex)
558 {
559 JLOG(j_.error()) << "Exception in " << __func__ << ": " << ex.what();
560 rethrow();
561 }
562
563 try
564 {
565 if (auto const sle = FeeSettingsEntryR(*this))
566 {
567 bool oldFees = false;
568 bool newFees = false;
569 {
570 auto const baseFee = sle->at(~sfBaseFee);
571 auto const reserveBase = sle->at(~sfReserveBase);
572 auto const reserveIncrement = sle->at(~sfReserveIncrement);
573 if (baseFee)
574 fees_.base = *baseFee;
575 if (reserveBase)
576 fees_.reserve = *reserveBase;
577 if (reserveIncrement)
578 fees_.increment = *reserveIncrement;
579 oldFees = baseFee || reserveBase || reserveIncrement;
580 }
581 {
582 auto const baseFeeXRP = sle->at(~sfBaseFeeDrops);
583 auto const reserveBaseXRP = sle->at(~sfReserveBaseDrops);
584 auto const reserveIncrementXRP = sle->at(~sfReserveIncrementDrops);
585 auto assign = [&ret](XRPAmount& dest, std::optional<STAmount> const& src) {
586 if (src)
587 {
588 if (src->native())
589 {
590 dest = src->xrp();
591 }
592 else
593 {
594 ret = false;
595 }
596 }
597 };
598 assign(fees_.base, baseFeeXRP);
599 assign(fees_.reserve, reserveBaseXRP);
600 assign(fees_.increment, reserveIncrementXRP);
601 newFees = baseFeeXRP || reserveBaseXRP || reserveIncrementXRP;
602 }
603 if (oldFees && newFees)
604 {
605 // Should be all of one or the other, but not both
606 ret = false;
607 }
608 if (!rules_.enabled(featureXRPFees) && newFees)
609 {
610 // Can't populate the new fees before the amendment is enabled
611 ret = false;
612 }
613 }
614 }
615 catch (SHAMapMissingNode const&)
616 {
617 ret = false;
618 }
619 catch (std::exception const& ex)
620 {
621 JLOG(j_.error()) << "Exception in " << __func__ << ": " << ex.what();
622 rethrow();
623 }
624
625 return ret;
626}
627
629Ledger::peek(Keylet const& k) const
630{
631 auto const& value = stateMap_.peekItem(k.key);
632 if (!value)
633 return nullptr;
634 auto sle = std::make_shared<SLE>(SerialIter{value->slice()}, value->key());
635 if (!k.check(*sle))
636 return nullptr;
637 return sle;
638}
639
642{
643 HashSet<PublicKey> negUnl;
644 if (auto const sle = NegativeUNLEntryR(*this); sle && sle->isFieldPresent(sfDisabledValidators))
645 {
646 auto const& nUnlData = sle->getFieldArray(sfDisabledValidators);
647 for (auto const& n : nUnlData)
648 {
649 if (n.isFieldPresent(sfPublicKey))
650 {
651 auto d = n.getFieldVL(sfPublicKey);
652 auto s = makeSlice(d);
653 if (!publicKeyType(s))
654 {
655 continue;
656 }
657 negUnl.emplace(s);
658 }
659 }
660 }
661
662 return negUnl;
663}
664
667{
668 if (auto const sle = NegativeUNLEntryR(*this); sle && sle->isFieldPresent(sfValidatorToDisable))
669 {
670 auto d = sle->getFieldVL(sfValidatorToDisable);
671 auto s = makeSlice(d);
672 if (publicKeyType(s))
673 return PublicKey(s);
674 }
675
676 return std::nullopt;
677}
678
681{
682 if (auto const sle = NegativeUNLEntryR(*this);
683 sle && sle->isFieldPresent(sfValidatorToReEnable))
684 {
685 auto d = sle->getFieldVL(sfValidatorToReEnable);
686 auto s = makeSlice(d);
687 if (publicKeyType(s))
688 return PublicKey(s);
689 }
690
691 return std::nullopt;
692}
693
694void
696{
697 auto sle = peek(keylet::negativeUNL());
698 if (!sle)
699 return;
700
701 bool const hasToDisable = sle->isFieldPresent(sfValidatorToDisable);
702 bool const hasToReEnable = sle->isFieldPresent(sfValidatorToReEnable);
703
704 if (!hasToDisable && !hasToReEnable)
705 return;
706
707 STArray newNUnl;
708 if (sle->isFieldPresent(sfDisabledValidators))
709 {
710 auto const& oldNUnl = sle->getFieldArray(sfDisabledValidators);
711 for (auto const& v : oldNUnl)
712 {
713 if (hasToReEnable && v.isFieldPresent(sfPublicKey) &&
714 v.getFieldVL(sfPublicKey) == sle->getFieldVL(sfValidatorToReEnable))
715 continue;
716 newNUnl.pushBack(v);
717 }
718 }
719
720 if (hasToDisable)
721 {
722 newNUnl.pushBack(STObject::makeInnerObject(sfDisabledValidator));
723 newNUnl.back().setFieldVL(sfPublicKey, sle->getFieldVL(sfValidatorToDisable));
724 newNUnl.back().setFieldU32(sfFirstLedgerSequence, seq());
725 }
726
727 if (!newNUnl.empty())
728 {
729 sle->setFieldArray(sfDisabledValidators, newNUnl);
730 if (hasToReEnable)
731 sle->makeFieldAbsent(sfValidatorToReEnable);
732 if (hasToDisable)
733 sle->makeFieldAbsent(sfValidatorToDisable);
734 rawReplace(sle);
735 }
736 else
737 {
738 rawErase(sle);
739 }
740}
741
742//------------------------------------------------------------------------------
743bool
744Ledger::walkLedger(beast::Journal j, bool parallel) const
745{
746 std::vector<SHAMapMissingNode> missingNodes1;
747 std::vector<SHAMapMissingNode> missingNodes2;
748
749 if (stateMap_.getHash().isZero() && !header_.accountHash.isZero() &&
750 !stateMap_.fetchRoot(SHAMapHash{header_.accountHash}, nullptr))
751 {
752 missingNodes1.emplace_back(SHAMapType::STATE, SHAMapHash{header_.accountHash});
753 }
754 else
755 {
756 if (parallel)
757 {
758 return stateMap_.walkMapParallel(missingNodes1, 32);
759 }
760
761 stateMap_.walkMap(missingNodes1, 32);
762 }
763
764 if (!missingNodes1.empty())
765 {
766 if (auto stream = j.info())
767 {
768 stream << missingNodes1.size() << " missing account node(s)";
769 stream << "First: " << missingNodes1[0].what();
770 }
771 }
772
773 if (txMap_.getHash().isZero() && header_.txHash.isNonZero() &&
774 !txMap_.fetchRoot(SHAMapHash{header_.txHash}, nullptr))
775 {
777 }
778 else
779 {
780 txMap_.walkMap(missingNodes2, 32);
781 }
782
783 if (!missingNodes2.empty())
784 {
785 if (auto stream = j.info())
786 {
787 stream << missingNodes2.size() << " missing transaction node(s)";
788 stream << "First: " << missingNodes2[0].what();
789 }
790 }
791 return missingNodes1.empty() && missingNodes2.empty();
792}
793
794bool
796{
797 if (header_.hash.isZero())
798 return false;
799 if (header_.accountHash.isZero())
800 return false;
801 if (header_.accountHash != stateMap_.getHash().asUInt256())
802 return false;
803 if (header_.txHash != txMap_.getHash().asUInt256())
804 return false;
805 return true;
806}
807
808// update the skip list with the information from our previous ledger
809// VFALCO TODO Document this skip list concept
810void
812{
813 if (header_.seq == 0) // genesis ledger has no previous ledger
814 return;
815
816 std::uint32_t const prevIndex = header_.seq - 1;
817
818 // update record of every 256th ledger
819 if ((prevIndex & 0xff) == 0)
820 {
821 auto const k = keylet::skip(prevIndex);
822 auto sle = peek(k);
824
825 bool created = false;
826 if (!sle)
827 {
828 sle = std::make_shared<SLE>(k);
829 created = true;
830 }
831 else
832 {
833 hashes = static_cast<decltype(hashes)>(sle->getFieldV256(sfHashes));
834 created = false;
835 }
836
837 XRPL_ASSERT(
838 hashes.size() <= 256, "xrpl::Ledger::updateSkipList : first maximum hashes size");
839 hashes.push_back(header_.parentHash);
840 sle->setFieldV256(sfHashes, STVector256(hashes));
841 sle->setFieldU32(sfLastLedgerSequence, prevIndex);
842 if (created)
843 {
844 rawInsert(sle);
845 }
846 else
847 {
848 rawReplace(sle);
849 }
850 }
851
852 // update record of past 256 ledger
853 auto const k = keylet::skip();
854 auto sle = peek(k);
856 bool created = false;
857 if (!sle)
858 {
859 sle = std::make_shared<SLE>(k);
860 created = true;
861 }
862 else
863 {
864 hashes = static_cast<decltype(hashes)>(sle->getFieldV256(sfHashes));
865 created = false;
866 }
867 XRPL_ASSERT(hashes.size() <= 256, "xrpl::Ledger::updateSkipList : second maximum hashes size");
868 if (hashes.size() == 256)
869 hashes.erase(hashes.begin());
870 hashes.push_back(header_.parentHash);
871 sle->setFieldV256(sfHashes, STVector256(hashes));
872 sle->setFieldU32(sfLastLedgerSequence, prevIndex);
873 if (created)
874 {
875 rawInsert(sle);
876 }
877 else
878 {
879 rawReplace(sle);
880 }
881}
882
883bool
885{
886 return ::xrpl::isFlagLedger(header_.seq);
887}
888bool
890{
891 return ::xrpl::isVotingLedger(header_.seq + 1);
892}
893
894void
896{
897 stateMap_.unshare();
898 txMap_.unshare();
899}
900
901void
903{
904 stateMap_.invariants();
905 txMap_.invariants();
906}
907
908} // namespace xrpl
T begin(T... args)
A generic endpoint for log messages.
Definition Journal.h:44
Stream info() const
Definition Journal.h:350
virtual void missingNodeAcquireByHash(UInt256 const &refHash, std::uint32_t refNum)=0
Acquire ledger that has a missing node by ledger hash.
SlesIterImpl(SlesIterImpl const &)=default
SlesType::value_type dereference() const override
bool equal(BaseType const &impl) const override
std::unique_ptr< BaseType > copy() const override
SlesIterImpl & operator=(SlesIterImpl const &)=delete
SlesIterImpl(SHAMap::ConstIterator iter)
TxsIterImpl(TxsIterImpl const &)=default
std::unique_ptr< BaseType > copy() const override
bool equal(BaseType const &impl) const override
TxsIterImpl & operator=(TxsIterImpl const &)=delete
TxsType::value_type dereference() const override
TxsIterImpl(bool metadata, SHAMap::ConstIterator iter)
std::unique_ptr< TxsType::IterBase > txsEnd() const override
HashSet< PublicKey > negativeUNL() const
get Negative UNL validators' master public keys
bool txExists(UInt256 const &key) const override
bool isFlagLedger() const
Returns true if the ledger is a flag ledger.
std::optional< DigestType > digest(key_type const &key) const override
Return the digest associated with the key.
std::optional< PublicKey > validatorToDisable() const
get the to be disabled validator's master public key if any
void rawInsert(SLE::Ref sle) override
Unconditionally insert a state item.
void updateNegativeUNL()
update the Negative UNL ledger component.
bool isVotingLedger() const
Returns true if the ledger directly precedes a flag ledger.
std::unique_ptr< SlesType::IterBase > slesBegin() const override
void rawReplace(SLE::Ref sle) override
Unconditionally replace a state item.
void setImmutable(bool rehash=true)
std::unique_ptr< SlesType::IterBase > slesUpperBound(UInt256 const &key) const override
bool open() const override
Returns true if this reflects an open ledger.
static std::pair< std::shared_ptr< STTx const >, std::shared_ptr< STObject const > > deserializeTxPlusMeta(SHAMapItem const &item)
Deserialize a SHAMapItem containing STTx + STObject metadata.
LedgerHeader const & header() const override
Returns information about the ledger.
void setAccepted(NetClock::time_point closeTime, NetClock::duration closeResolution, bool correctCloseTime)
Ledger(Ledger const &)=delete
static std::shared_ptr< STTx const > deserializeTx(SHAMapItem const &item)
Deserialize a SHAMapItem containing a single STTx.
bool addSLE(SLE const &sle)
std::unique_ptr< TxsType::IterBase > txsBegin() const override
std::optional< UInt256 > succ(UInt256 const &key, std::optional< UInt256 > const &last=std::nullopt) const override
std::unique_ptr< SlesType::IterBase > slesEnd() const override
void rawTxInsert(UInt256 const &key, std::shared_ptr< Serializer const > const &txn, std::shared_ptr< Serializer const > const &metaData) override
Rules const & rules() const override
Returns the tx processing rules.
Fees const & fees() const override
Returns the fees for the base ledger.
bool walkLedger(beast::Journal j, bool parallel=false) const
std::optional< PublicKey > validatorToReEnable() const
get the to be re-enabled validator's master public key if any
TxType txRead(key_type const &key) const override
Read a transaction from the tx map.
SLE::const_pointer read(Keylet const &k) const override
Return the state item associated with a key.
SLE::pointer peek(Keylet const &k) const
bool exists(Keylet const &k) const override
Determine if a state item exists.
void rawErase(SLE::Ref sle) override
Delete an existing state item.
std::chrono::time_point< NetClock > time_point
Definition chrono.h:48
std::chrono::duration< rep, period > duration
Definition chrono.h:47
A public key.
Definition PublicKey.h:53
UInt256 key_type
Definition ReadView.h:45
LedgerIndex seq() const
Returns the sequence number of the base ledger.
Definition ReadView.h:115
Rules controlling protocol behavior.
Definition Rules.h:40
Slice slice() const
Definition SHAMapItem.h:92
bool empty() const
Definition STArray.h:254
void pushBack(STObject const &object)
Definition STArray.h:212
STObject & back()
Definition STArray.h:193
UInt256 const & key() const
Returns the 'key' (or 'index') of this item.
std::shared_ptr< STLedgerEntry > pointer
std::shared_ptr< STLedgerEntry > const & Ref
std::shared_ptr< STLedgerEntry const > const_pointer
void setFieldVL(SField const &field, Blob const &)
Definition STObject.cpp:791
void setFieldU32(SField const &field, std::uint32_t)
Definition STObject.cpp:743
Serializer getSerializer() const
Definition STObject.h:1003
bool isFieldPresent(SField const &field) const
Definition STObject.cpp:464
static STObject makeInnerObject(SField const &name)
Definition STObject.cpp:79
int getVLDataLength()
Reads the length header at the read position and steps past it.
Slice getSlice(std::size_t bytes)
int addVL(Blob const &vector)
Slice slice() const noexcept
Definition Serializer.h:141
T emplace_back(T... args)
T emplace(T... args)
T empty(T... args)
T erase(T... args)
T find(T... args)
T make_shared(T... args)
T make_unique(T... args)
constexpr Zero kZero
Definition Zero.h:30
STL namespace.
Keylet const & skip() noexcept
The index of the "short" skip list.
Definition Indexes.cpp:232
Keylet const & negativeUNL() noexcept
The (fixed) index of the object containing the ledger negativeUNL.
Definition Indexes.cpp:262
Keylet const & feeSettings() noexcept
The (fixed) index of the object containing the ledger fees.
Definition Indexes.cpp:255
Keylet const & amendments() noexcept
The index of the amendment table.
Definition Indexes.cpp:248
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition Indexes.cpp:220
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
TxType
Transaction type identifiers.
Definition TxFormats.h:45
CreateGenesisT const kCreateGenesis
Rules makeRulesGivenLedger(DigestAwareReadView const &ledger, Rules const &current)
Definition ReadView.cpp:62
Seed generateSeed(std::string const &passPhrase)
Generate a seed deterministically.
Definition Seed.cpp:58
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.
std::pair< PublicKey, SecretKey > generateKeyPair(KeyType type, Seed const &seed)
Generate a key pair deterministically.
constexpr std::uint32_t kFeeUnitsDeprecated
bool getCloseAgree(LedgerHeader const &info)
std::string to_string(BaseUInt< Bits, Tag > const &a)
Definition base_uint.h:657
void logicError(std::string const &how) noexcept
Called when faulty logic causes a broken invariant.
std::optional< KeyType > publicKeyType(Slice const &slice)
Returns the type of public key.
STLedgerEntry SLE
Slice makeSlice(std::array< T, N > const &a)
Definition Slice.h:228
XRPL_NO_SANITIZE_ADDRESS void rethrow()
Rethrow the exception currently being handled.
Definition contract.h:36
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.
void open(soci::session &s, BasicConfig const &config, std::string const &dbName)
Open a soci session.
Definition SociDB.cpp:91
BaseUInt< 256 > UInt256
Definition base_uint.h:580
boost::intrusive_ptr< SHAMapItem > makeShamapitem(UInt256 const &tag, Slice data)
Definition SHAMapItem.h:148
std::unordered_set< Value, Hash, Pred, Allocator > HashSet
AccountID calcAccountID(PublicKey const &pk)
constexpr auto kLedgerGenesisTimeResolution
Close time resolution in genesis ledger.
constexpr auto kLedgerDefaultTimeResolution
Initial resolution of ledger close time.
UInt256 calculateLedgerHash(LedgerHeader const &info)
Calculate the hash of a ledger header.
static std::uint32_t const kSLcfNoConsensusTime
FeeSettingsEntry< ReadView > FeeSettingsEntryR
constexpr XRPAmount kInitialXrp
Configure the native currency.
NegativeUNLEntry< ReadView > NegativeUNLEntryR
T push_back(T... args)
T size(T... args)
Reflects the fee settings for a particular ledger.
A pair of SHAMap key and LedgerEntryType.
Definition Keylet.h:20
UInt256 key
Definition Keylet.h:21
bool check(STLedgerEntry const &) const
Returns true if the SLE matches the type.
Definition Keylet.cpp:10
Information about the notional ledger backing the view.
NetClock::duration closeTimeResolution
NetClock::time_point closeTime
T what(T... args)