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