1#include <xrpl/ledger/Ledger.h>
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>
76 equal(base_type
const& impl)
const override
78 if (
auto const p =
dynamic_cast<SlesIterImpl const*
>(&impl))
79 return iter_ == p->iter_;
89 [[nodiscard]] SlesType::value_type
123 equal(base_type
const& impl)
const override
125 if (
auto const p =
dynamic_cast<TxsIterImpl const*
>(&impl))
126 return iter_ == p->iter_;
136 [[nodiscard]] TxsType::value_type
139 auto const& item = *
iter_;
165 static auto const kID =
169 sle->setFieldU32(sfSequence, 1);
170 sle->setAccountID(sfAccount, kID);
171 sle->setFieldAmount(sfBalance,
header_.drops);
175 if (!amendments.empty())
178 sle->setFieldV256(sfAmendments,
STVector256{amendments});
187 sle->at(sfBaseFeeDrops) =
fees.base;
188 sle->at(sfReserveBaseDrops) =
fees.reserve;
189 sle->at(sfReserveIncrementDrops) =
fees.increment;
194 sle->at(sfBaseFee) = *f;
196 sle->at(sfReserveBase) = *f;
198 sle->at(sfReserveIncrement) = *f;
229 JLOG(j.warn()) <<
"Don't have transaction root for ledger" << header_.seq;
232 if (
header_.accountHash.isNonZero() &&
236 JLOG(j.warn()) <<
"Don't have state data root for ledger" << header_.seq;
335 bool correctCloseTime)
338 XRPL_ASSERT(!
open(),
"xrpl::Ledger::setAccepted : valid ledger state");
341 header_.closeTimeResolution = closeResolution;
399 if (last && item->key() >= last)
407 if (k.
key == beast::kZero)
410 UNREACHABLE(
"xrpl::Ledger::read : zero key");
458 return txMap_.hasItem(key);
464 auto const& item =
txMap_.peekItem(key);
470 return {std::move(result.first), std::move(result.second)};
483 return digest.asUInt256();
492 logicError(
"Ledger::rawErase: key not found");
499 logicError(
"Ledger::rawErase: key not found");
510 logicError(
"Ledger::rawInsert: key already exists");
522 logicError(
"Ledger::rawReplace: key not found");
532 XRPL_ASSERT(metaData,
"xrpl::Ledger::rawTxInsert : non-null metadata input");
535 Serializer s(txn->getDataLength() + metaData->getDataLength() + 16);
536 s.
addVL(txn->peekData());
537 s.
addVL(metaData->peekData());
557 JLOG(
j_.error()) <<
"Exception in " << __func__ <<
": " << ex.
what();
565 bool oldFees =
false;
566 bool newFees =
false;
568 auto const baseFee = sle->at(~sfBaseFee);
569 auto const reserveBase = sle->at(~sfReserveBase);
570 auto const reserveIncrement = sle->at(~sfReserveIncrement);
572 fees_.base = *baseFee;
574 fees_.reserve = *reserveBase;
575 if (reserveIncrement)
576 fees_.increment = *reserveIncrement;
577 oldFees = baseFee || reserveBase || reserveIncrement;
580 auto const baseFeeXRP = sle->at(~sfBaseFeeDrops);
581 auto const reserveBaseXRP = sle->at(~sfReserveBaseDrops);
582 auto const reserveIncrementXRP = sle->at(~sfReserveIncrementDrops);
596 assign(
fees_.base, baseFeeXRP);
597 assign(
fees_.reserve, reserveBaseXRP);
598 assign(
fees_.increment, reserveIncrementXRP);
599 newFees = baseFeeXRP || reserveBaseXRP || reserveIncrementXRP;
601 if (oldFees && newFees)
606 if (!
rules_.enabled(featureXRPFees) && newFees)
619 JLOG(
j_.error()) <<
"Exception in " << __func__ <<
": " << ex.
what();
644 auto const& nUnlData = sle->getFieldArray(sfDisabledValidators);
645 for (
auto const& n : nUnlData)
647 if (n.isFieldPresent(sfPublicKey))
649 auto d = n.getFieldVL(sfPublicKey);
668 auto d = sle->getFieldVL(sfValidatorToDisable);
682 auto d = sle->getFieldVL(sfValidatorToReEnable);
698 bool const hasToDisable = sle->isFieldPresent(sfValidatorToDisable);
699 bool const hasToReEnable = sle->isFieldPresent(sfValidatorToReEnable);
701 if (!hasToDisable && !hasToReEnable)
705 if (sle->isFieldPresent(sfDisabledValidators))
707 auto const& oldNUnl = sle->getFieldArray(sfDisabledValidators);
708 for (
auto const& v : oldNUnl)
710 if (hasToReEnable && v.isFieldPresent(sfPublicKey) &&
711 v.getFieldVL(sfPublicKey) == sle->getFieldVL(sfValidatorToReEnable))
720 newNUnl.
back().
setFieldVL(sfPublicKey, sle->getFieldVL(sfValidatorToDisable));
724 if (!newNUnl.
empty())
726 sle->setFieldArray(sfDisabledValidators, newNUnl);
728 sle->makeFieldAbsent(sfValidatorToReEnable);
730 sle->makeFieldAbsent(sfValidatorToDisable);
755 return stateMap_.walkMapParallel(missingNodes1, 32);
761 if (!missingNodes1.
empty())
763 if (
auto stream = j.
info())
765 stream << missingNodes1.
size() <<
" missing account node(s)";
766 stream <<
"First: " << missingNodes1[0].what();
770 if (
txMap_.getHash().isZero() &&
header_.txHash.isNonZero() &&
777 txMap_.walkMap(missingNodes2, 32);
780 if (!missingNodes2.
empty())
782 if (
auto stream = j.
info())
784 stream << missingNodes2.
size() <<
" missing transaction node(s)";
785 stream <<
"First: " << missingNodes2[0].what();
788 return missingNodes1.
empty() && missingNodes2.
empty();
796 if (
header_.accountHash.isZero())
816 if ((prevIndex & 0xff) == 0)
822 bool created =
false;
830 hashes =
static_cast<decltype(hashes)
>(sle->getFieldV256(sfHashes));
835 hashes.
size() <= 256,
"xrpl::Ledger::updateSkipList : first maximum hashes size");
838 sle->setFieldU32(sfLastLedgerSequence, prevIndex);
853 bool created =
false;
861 hashes =
static_cast<decltype(hashes)
>(sle->getFieldV256(sfHashes));
864 XRPL_ASSERT(hashes.
size() <= 256,
"xrpl::Ledger::updateSkipList : second maximum hashes size");
865 if (hashes.
size() == 256)
869 sle->setFieldU32(sfLastLedgerSequence, prevIndex);
883 return ::xrpl::isFlagLedger(
header_.seq);
888 return ::xrpl::isVotingLedger(
header_.seq + 1);
A generic endpoint for log messages.
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
SHAMap::ConstIterator iter_
SlesIterImpl & operator=(SlesIterImpl const &)=delete
void increment() override
SlesIterImpl(SHAMap::ConstIterator iter)
bool equal(base_type const &impl) const override
std::unique_ptr< base_type > copy() const override
TxsIterImpl(TxsIterImpl const &)=default
void increment() override
std::unique_ptr< base_type > copy() const override
SHAMap::ConstIterator iter_
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
std::chrono::duration< rep, period > duration
std::pair< std::shared_ptr< STTx const >, std::shared_ptr< STObject const > > tx_type
LedgerIndex seq() const
Returns the sequence number of the base ledger.
Rules controlling protocol behavior.
void pushBack(STObject const &object)
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 &)
void setFieldU32(SField const &field, std::uint32_t)
Serializer getSerializer() const
static STObject makeInnerObject(SField const &name)
Slice getSlice(std::size_t bytes)
int addVL(Blob const &vector)
Slice slice() const noexcept
T emplace_back(T... args)
Keylet const & skip() noexcept
The index of the "short" skip list.
Keylet const & negativeUNL() noexcept
The (fixed) index of the object containing the ledger negativeUNL.
Keylet const & feeSettings() noexcept
The (fixed) index of the object containing the ledger fees.
Keylet const & amendments() noexcept
The index of the amendment table.
Keylet account(AccountID const &id) noexcept
AccountID root.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
CreateGenesisT const kCreateGenesis
Rules makeRulesGivenLedger(DigestAwareReadView const &ledger, Rules const ¤t)
std::unordered_set< Value, Hash, Pred, Allocator > hash_set
Seed generateSeed(std::string const &passPhrase)
Generate a seed deterministically.
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)
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.
XRPL_NO_SANITIZE_ADDRESS void rethrow()
Rethrow the exception currently being handled.
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.
boost::intrusive_ptr< SHAMapItem > makeShamapitem(uint256 const &tag, Slice data)
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.
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)
Reflects the fee settings for a particular ledger.
A pair of SHAMap key and LedgerEntryType.
bool check(STLedgerEntry const &) const
Returns true if the SLE matches the type.