20#include <xrpld/app/ledger/InboundLedgers.h> 
   21#include <xrpld/app/ledger/Ledger.h> 
   22#include <xrpld/app/ledger/LedgerToJson.h> 
   23#include <xrpld/app/ledger/PendingSaves.h> 
   24#include <xrpld/app/main/Application.h> 
   25#include <xrpld/app/misc/HashRouter.h> 
   26#include <xrpld/app/rdb/backend/SQLiteDatabase.h> 
   27#include <xrpld/consensus/LedgerTiming.h> 
   28#include <xrpld/core/Config.h> 
   29#include <xrpld/core/JobQueue.h> 
   30#include <xrpld/core/SociDB.h> 
   32#include <xrpl/basics/Log.h> 
   33#include <xrpl/basics/contract.h> 
   34#include <xrpl/beast/utility/instrumentation.h> 
   35#include <xrpl/json/to_string.h> 
   36#include <xrpl/nodestore/Database.h> 
   37#include <xrpl/nodestore/detail/DatabaseNodeImp.h> 
   38#include <xrpl/protocol/Feature.h> 
   39#include <xrpl/protocol/HashPrefix.h> 
   40#include <xrpl/protocol/Indexes.h> 
   41#include <xrpl/protocol/PublicKey.h> 
   42#include <xrpl/protocol/SecretKey.h> 
   43#include <xrpl/protocol/digest.h> 
   44#include <xrpl/protocol/jss.h> 
   95    equal(base_type 
const& impl)
 const override 
   98            return iter_ == p->iter_;
 
 
  108    sles_type::value_type
 
 
  143    equal(base_type 
const& impl)
 const override 
  145        if (
auto const p = 
dynamic_cast<txs_iter_impl const*
>(&impl))
 
  146            return iter_ == p->iter_;
 
 
  159        auto const& item = *
iter_;
 
 
 
  176    , rules_{config.features}
 
  177    , j_(
beast::Journal(
beast::Journal::getNullSink()))
 
  188        sle->setFieldU32(sfSequence, 1);
 
  189        sle->setAccountID(sfAccount, 
id);
 
  194    if (!amendments.empty())
 
  197        sle->setFieldV256(sfAmendments, 
STVector256{amendments});
 
  204        if (
std::find(amendments.begin(), amendments.end(), featureXRPFees) !=
 
  215                sle->at(sfBaseFee) = *f;
 
  218                sle->at(sfReserveBase) = *f;
 
  221                sle->at(sfReserveIncrement) = *f;
 
 
  241    , rules_(config.features)
 
  251        JLOG(j.
warn()) << 
"Don't have transaction root for ledger" << 
info_.
seq;
 
  258        JLOG(j.
warn()) << 
"Don't have state data root for ledger" << 
info_.
seq;
 
 
  280    , stateMap_(prevLedger.stateMap_, true)
 
  281    , fees_(prevLedger.fees_)
 
  282    , rules_(prevLedger.rules_)
 
  283    , j_(
beast::Journal(
beast::Journal::getNullSink()))
 
 
  311    , rules_{config.features}
 
  313    , j_(
beast::Journal(
beast::Journal::getNullSink()))
 
 
  326    , rules_{config.features}
 
  327    , j_(
beast::Journal(
beast::Journal::getNullSink()))
 
 
  360    bool correctCloseTime)
 
  363    XRPL_ASSERT(!
open(), 
"ripple::Ledger::setAccepted : valid ledger state");
 
 
  426    if (last && item->key() >= last)
 
 
  434    if (k.
key == beast::zero)
 
  437        UNREACHABLE(
"ripple::Ledger::read : zero key");
 
 
  492    auto const& item = txMap_.peekItem(key);
 
  498        return {std::move(result.first), std::move(result.second)};
 
 
  509    if (!stateMap_.peekItem(key, 
digest))
 
 
  520        LogicError(
"Ledger::rawErase: key not found");
 
 
  527        LogicError(
"Ledger::rawErase: key not found");
 
 
  538        LogicError(
"Ledger::rawInsert: key already exists");
 
 
  549        LogicError(
"Ledger::rawReplace: key not found");
 
 
  559        metaData, 
"ripple::Ledger::rawTxInsert : non-null metadata input");
 
  562    Serializer s(txn->getDataLength() + metaData->getDataLength() + 16);
 
  563    s.
addVL(txn->peekData());
 
  564    s.
addVL(metaData->peekData());
 
 
  578        "ripple::Ledger::rawTxInsertWithHash : non-null metadata input");
 
  581    Serializer s(txn->getDataLength() + metaData->getDataLength() + 16);
 
  582    s.
addVL(txn->peekData());
 
  583    s.
addVL(metaData->peekData());
 
 
  607        JLOG(
j_.
error()) << 
"Exception in " << __func__ << 
": " << ex.
what();
 
  615            bool oldFees = 
false;
 
  616            bool newFees = 
false;
 
  618                auto const baseFee = sle->at(~sfBaseFee);
 
  619                auto const reserveBase = sle->at(~sfReserveBase);
 
  620                auto const reserveIncrement = sle->at(~sfReserveIncrement);
 
  625                if (reserveIncrement)
 
  627                oldFees = baseFee || reserveBase || reserveIncrement;
 
  630                auto const baseFeeXRP = sle->at(~sfBaseFeeDrops);
 
  631                auto const reserveBaseXRP = sle->at(~sfReserveBaseDrops);
 
  632                auto const reserveIncrementXRP =
 
  633                    sle->at(~sfReserveIncrementDrops);
 
  634                auto assign = [&ret](
 
  648                newFees = baseFeeXRP || reserveBaseXRP || reserveIncrementXRP;
 
  650            if (oldFees && newFees)
 
  664        JLOG(
j_.
error()) << 
"Exception in " << __func__ << 
": " << ex.
what();
 
 
  676        "ripple::Ledger::defaultFees : zero fees");
 
 
  702        sle && sle->isFieldPresent(sfDisabledValidators))
 
  704        auto const& nUnlData = sle->getFieldArray(sfDisabledValidators);
 
  705        for (
auto const& n : nUnlData)
 
  707            if (n.isFieldPresent(sfPublicKey))
 
  709                auto d = n.getFieldVL(sfPublicKey);
 
 
  727        sle && sle->isFieldPresent(sfValidatorToDisable))
 
  729        auto d = sle->getFieldVL(sfValidatorToDisable);
 
 
  742        sle && sle->isFieldPresent(sfValidatorToReEnable))
 
  744        auto d = sle->getFieldVL(sfValidatorToReEnable);
 
 
  760    bool const hasToDisable = sle->isFieldPresent(sfValidatorToDisable);
 
  761    bool const hasToReEnable = sle->isFieldPresent(sfValidatorToReEnable);
 
  763    if (!hasToDisable && !hasToReEnable)
 
  767    if (sle->isFieldPresent(sfDisabledValidators))
 
  769        auto const& oldNUnl = sle->getFieldArray(sfDisabledValidators);
 
  770        for (
auto v : oldNUnl)
 
  772            if (hasToReEnable && v.isFieldPresent(sfPublicKey) &&
 
  773                v.getFieldVL(sfPublicKey) ==
 
  774                    sle->getFieldVL(sfValidatorToReEnable))
 
  784            sfPublicKey, sle->getFieldVL(sfValidatorToDisable));
 
  788    if (!newNUnl.
empty())
 
  790        sle->setFieldArray(sfDisabledValidators, newNUnl);
 
  792            sle->makeFieldAbsent(sfValidatorToReEnable);
 
  794            sle->makeFieldAbsent(sfValidatorToDisable);
 
 
  824    if (!missingNodes1.
empty())
 
  826        if (
auto stream = j.
info())
 
  828            stream << missingNodes1.
size() << 
" missing account node(s)";
 
  829            stream << 
"First: " << missingNodes1[0].what();
 
  844    if (!missingNodes2.
empty())
 
  846        if (
auto stream = j.
info())
 
  848            stream << missingNodes2.
size() << 
" missing transaction node(s)";
 
  849            stream << 
"First: " << missingNodes2[0].what();
 
  852    return missingNodes1.
empty() && missingNodes2.
empty();
 
 
  871    JLOG(ledgerJ.
fatal()) << 
"ledger is not sensible" << j;
 
  873    UNREACHABLE(
"ripple::Ledger::assertSensible : ledger is not sensible");
 
 
  890    if ((prevIndex & 0xff) == 0)
 
  904            hashes = 
static_cast<decltype(hashes)
>(sle->getFieldV256(sfHashes));
 
  909            hashes.
size() <= 256,
 
  910            "ripple::Ledger::updateSkipList : first maximum hashes size");
 
  913        sle->setFieldU32(sfLastLedgerSequence, prevIndex);
 
  932        hashes = 
static_cast<decltype(hashes)
>(sle->getFieldV256(sfHashes));
 
  936        hashes.
size() <= 256,
 
  937        "ripple::Ledger::updateSkipList : second maximum hashes size");
 
  938    if (hashes.
size() == 256)
 
  942    sle->setFieldU32(sfLastLedgerSequence, prevIndex);
 
 
  972    auto j = app.
journal(
"Ledger");
 
  973    auto seq = ledger->info().seq;
 
  977        JLOG(j.debug()) << 
"Save aborted";
 
  983        Throw<std::runtime_error>(
"Failed to get relational database");
 
  985    auto const res = db->saveValidatedLedger(ledger, 
current);
 
 
 1008        JLOG(stream) << 
"Double pend save for " << ledger->info().seq;
 
 1019        ledger->isImmutable(), 
"ripple::pendSaveValidated : immutable ledger");
 
 1024        JLOG(stream) << 
"Pend save with seq in pending saves " 
 1025                     << ledger->info().seq;
 
 1031    if (!isSynchronous &&
 
 
 1099        "ripple::finishLoadByIndexOrHash : valid ledger fees");
 
 1100    ledger->setImmutable();
 
 1102    JLOG(j.
trace()) << 
"Loaded ledger: " << 
to_string(ledger->info().hash);
 
 
 1139            !ledger || ledger->info().hash == ledgerHash,
 
 1140            "ripple::loadByHash : ledger hash match if loaded");
 
 
A generic endpoint for log messages.
 
Stream trace() const
Severity stream access functions.
 
virtual Config & config()=0
 
virtual beast::Journal journal(std::string const &name)=0
 
virtual JobQueue & getJobQueue()=0
 
virtual Family & getNodeFamily()=0
 
virtual RelationalDatabase & getRelationalDatabase()=0
 
virtual HashRouter & getHashRouter()=0
 
virtual PendingSaves & pendingSaves()=0
 
static constexpr std::uint32_t FEE_UNITS_DEPRECATED
 
virtual void missingNodeAcquireByHash(uint256 const &refHash, std::uint32_t refNum)=0
Acquire ledger that has a missing node by ledger hash.
 
bool setFlags(uint256 const &key, HashRouterFlags flags)
Set the flags on a hash.
 
bool addJob(JobType type, std::string const &name, JobHandler &&jobHandler)
Adds a job to the JobQueue.
 
sles_iter_impl(sles_iter_impl const &)=default
 
std::unique_ptr< base_type > copy() const override
 
sles_type::value_type dereference() const override
 
sles_iter_impl(SHAMap::const_iterator iter)
 
void increment() override
 
bool equal(base_type const &impl) const override
 
SHAMap::const_iterator iter_
 
sles_iter_impl & operator=(sles_iter_impl const &)=delete
 
txs_iter_impl & operator=(txs_iter_impl const &)=delete
 
txs_iter_impl(txs_iter_impl const &)=default
 
SHAMap::const_iterator iter_
 
txs_type::value_type dereference() const override
 
bool equal(base_type const &impl) const override
 
std::unique_ptr< base_type > copy() const override
 
void increment() override
 
txs_iter_impl(bool metadata, SHAMap::const_iterator iter)
 
LedgerInfo const & info() const override
Returns information about the ledger.
 
void setAccepted(NetClock::time_point closeTime, NetClock::duration closeResolution, bool correctCloseTime)
 
void defaultFees(Config const &config)
 
void rawTxInsert(uint256 const &key, std::shared_ptr< Serializer const > const &txn, std::shared_ptr< Serializer const > const &metaData) override
 
std::unique_ptr< sles_type::iter_base > slesUpperBound(uint256 const &key) const override
 
bool open() const override
Returns true if this reflects an open ledger.
 
bool assertSensible(beast::Journal ledgerJ) const
 
bool exists(Keylet const &k) const override
Determine if a state item exists.
 
void rawReplace(std::shared_ptr< SLE > const &sle) override
Unconditionally replace a state item.
 
std::unique_ptr< sles_type::iter_base > slesEnd() const override
 
void rawErase(std::shared_ptr< SLE > const &sle) override
Delete an existing state item.
 
std::optional< PublicKey > validatorToReEnable() const
get the to be re-enabled validator's master public key if any
 
bool isFlagLedger() const
Returns true if the ledger is a flag ledger.
 
hash_set< PublicKey > negativeUNL() const
get Negative UNL validators' master public keys
 
bool txExists(uint256 const &key) const override
 
std::optional< PublicKey > validatorToDisable() const
get the to be disabled validator's master public key if any
 
bool isVotingLedger() const
Returns true if the ledger directly precedes a flag ledger.
 
void updateNegativeUNL()
update the Negative UNL ledger component.
 
std::shared_ptr< SLE > peek(Keylet const &k) const
 
std::optional< digest_type > digest(key_type const &key) const override
Return the digest associated with the key.
 
tx_type txRead(key_type const &key) const override
Read a transaction from the tx map.
 
void rawInsert(std::shared_ptr< SLE > const &sle) override
Unconditionally insert a state item.
 
bool walkLedger(beast::Journal j, bool parallel=false) const
 
std::shared_ptr< SLE const > read(Keylet const &k) const override
Return the state item associated with a key.
 
uint256 rawTxInsertWithHash(uint256 const &key, std::shared_ptr< Serializer const > const &txn, std::shared_ptr< Serializer const > const &metaData)
 
std::unique_ptr< sles_type::iter_base > slesBegin() const override
 
std::unique_ptr< txs_type::iter_base > txsEnd() const override
 
std::unique_ptr< txs_type::iter_base > txsBegin() const override
 
std::optional< uint256 > succ(uint256 const &key, std::optional< uint256 > const &last=std::nullopt) const override
 
bool addSLE(SLE const &sle)
 
Ledger(Ledger const &)=delete
 
void setImmutable(bool rehash=true)
 
void finishWork(LedgerIndex seq)
Finish working on a ledger.
 
bool startWork(LedgerIndex seq)
Start working on a ledger.
 
bool shouldWork(LedgerIndex seq, bool isSynchronous)
Check if a ledger should be dispatched.
 
bool pending(LedgerIndex seq)
Return true if a ledger is in the progress of being saved.
 
LedgerIndex seq() const
Returns the sequence number of the base ledger.
 
virtual std::optional< LedgerInfo > getNewestLedgerInfo()=0
getNewestLedgerInfo Returns the info of the newest saved ledger.
 
virtual std::optional< LedgerInfo > getLedgerInfoByIndex(LedgerIndex ledgerSeq)=0
getLedgerInfoByIndex Returns a ledger by its sequence.
 
virtual std::optional< LedgerInfo > getLedgerInfoByHash(uint256 const &ledgerHash)=0
getLedgerInfoByHash Returns the info of the ledger with given hash.
 
bool enabled(uint256 const &feature) const
Returns true if a feature is enabled.
 
uint256 const & as_uint256() const
 
bool hasItem(uint256 const &id) const
Does the tree have an item with the given ID?
 
boost::intrusive_ptr< SHAMapItem const > const & peekItem(uint256 const &id) const
 
bool addGiveItem(SHAMapNodeType type, boost::intrusive_ptr< SHAMapItem const > item)
 
const_iterator end() const
 
bool addItem(SHAMapNodeType type, boost::intrusive_ptr< SHAMapItem const > item)
 
const_iterator upper_bound(uint256 const &id) const
Find the first item after the given item.
 
SHAMapHash getHash() const
 
void walkMap(std::vector< SHAMapMissingNode > &missingNodes, int maxMissing) const
 
bool walkMapParallel(std::vector< SHAMapMissingNode > &missingNodes, int maxMissing) const
 
bool updateGiveItem(SHAMapNodeType type, boost::intrusive_ptr< SHAMapItem const > item)
 
const_iterator begin() const
 
bool delItem(uint256 const &id)
 
bool fetchRoot(SHAMapHash const &hash, SHAMapSyncFilter *filter)
 
int flushDirty(NodeObjectType t)
Flush modified nodes to the nodestore and convert them to shared.
 
int unshare()
Convert any modified nodes to shared.
 
void push_back(STObject const &object)
 
uint256 const & key() const
Returns the 'key' (or 'index') of this item.
 
Serializer getSerializer() const
 
static STObject makeInnerObject(SField const &name)
 
void setFieldU32(SField const &field, std::uint32_t)
 
void setFieldVL(SField const &field, Blob const &)
 
Slice getSlice(std::size_t bytes)
 
Slice slice() const noexcept
 
int addVL(Blob const &vector)
 
std::optional< Dest > dropsAs() const
 
constexpr value_type drops() const
Returns the number of drops.
 
T emplace_back(T... args)
 
Keylet const & negativeUNL() noexcept
The (fixed) index of the object containing the ledger negativeUNL.
 
Keylet const & amendments() noexcept
The index of the amendment table.
 
Keylet account(AccountID const &id) noexcept
AccountID root.
 
Keylet const & fees() noexcept
The (fixed) index of the object containing the ledger fees.
 
Keylet const & skip() noexcept
The index of the "short" skip list.
 
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
 
bool getCloseAgree(LedgerHeader const &info)
 
std::tuple< std::shared_ptr< Ledger >, std::uint32_t, uint256 > getLatestLedger(Application &app)
 
std::pair< std::shared_ptr< STTx const >, std::shared_ptr< STObject const > > deserializeTxPlusMeta(SHAMapItem const &item)
Deserialize a SHAMapItem containing STTx + STObject metadata.
 
static void finishLoadByIndexOrHash(std::shared_ptr< Ledger > const &ledger, Config const &config, beast::Journal j)
 
std::shared_ptr< Ledger > loadByIndex(std::uint32_t ledgerIndex, Application &app, bool acquire)
 
std::pair< PublicKey, SecretKey > generateKeyPair(KeyType type, Seed const &seed)
Generate a key pair deterministically.
 
std::shared_ptr< STTx const > deserializeTx(SHAMapItem const &item)
Deserialize a SHAMapItem containing a single STTx.
 
bool isCurrent(ValidationParms const &p, NetClock::time_point now, NetClock::time_point signTime, NetClock::time_point seenTime)
Whether a validation is still current.
 
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.
 
static bool saveValidatedLedger(Application &app, std::shared_ptr< Ledger const > const &ledger, bool current)
 
constexpr XRPAmount INITIAL_XRP
Configure the native currency.
 
std::shared_ptr< Ledger > loadLedgerHelper(LedgerInfo const &info, Application &app, bool acquire)
 
AccountID calcAccountID(PublicKey const &pk)
 
@ current
This was a new validation and was added.
 
static constexpr std::uint32_t XRP_LEDGER_EARLIEST_FEES
The XRP Ledger mainnet's earliest ledger with a FeeSettings object.
 
auto constexpr ledgerDefaultTimeResolution
Initial resolution of ledger close time.
 
uint256 calculateLedgerHash(LedgerInfo const &info)
 
std::shared_ptr< Ledger > loadByHash(uint256 const &ledgerHash, Application &app, bool acquire)
 
@ open
We haven't closed our ledger yet, but others might have.
 
std::optional< KeyType > publicKeyType(Slice const &slice)
Returns the type of public key.
 
bool isFlagLedger(LedgerIndex seq)
Returns true if the given ledgerIndex is a flag ledgerIndex.
 
auto constexpr ledgerGenesisTimeResolution
Close time resolution in genesis ledger.
 
static std::uint32_t const sLCF_NoConsensusTime
 
static Hasher::result_type digest(void const *data, std::size_t size) noexcept
 
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)
 
boost::intrusive_ptr< SHAMapItem > make_shamapitem(uint256 const &tag, Slice data)
 
Rules makeRulesGivenLedger(DigestAwareReadView const &ledger, Rules const ¤t)
 
std::string to_string(base_uint< Bits, Tag > const &a)
 
create_genesis_t const create_genesis
 
Json::Value getJson(LedgerFill const &fill)
Return a new Json::Value representing the ledger with given options.
 
@ txNode
transaction plus metadata
 
@ ledgerMaster
ledger master data for signing
 
void Rethrow()
Rethrow the exception currently being handled.
 
Seed generateSeed(std::string const &passPhrase)
Generate a seed deterministically.
 
sha512_half_hasher::result_type sha512Half(Args const &... args)
Returns the SHA512-Half of a series of objects.
 
std::uint32_t constexpr FLAG_LEDGER_INTERVAL
 
void LogicError(std::string const &how) noexcept
Called when faulty logic causes a broken invariant.
 
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.
 
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.
 
XRPAmount reference_fee
The cost of a reference transaction in drops.
 
XRPAmount owner_reserve
The per-owned item reserve requirement in drops.
 
XRPAmount account_reserve
The account reserve requirement in drops.
 
A pair of SHAMap key and LedgerEntryType.
 
bool check(STLedgerEntry const &) const
Returns true if the SLE matches the type.
 
T time_since_epoch(T... args)