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>
31#include <xrpld/nodestore/Database.h>
32#include <xrpld/nodestore/detail/DatabaseNodeImp.h>
34#include <xrpl/basics/Log.h>
35#include <xrpl/basics/contract.h>
36#include <xrpl/beast/utility/instrumentation.h>
37#include <xrpl/json/to_string.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)
436 UNREACHABLE(
"ripple::Ledger::read : zero key");
490 auto const& item = txMap_.peekItem(key);
496 return {std::move(result.first), std::move(result.second)};
507 if (!stateMap_.peekItem(key,
digest))
518 LogicError(
"Ledger::rawErase: key not found");
525 LogicError(
"Ledger::rawErase: key not found");
536 LogicError(
"Ledger::rawInsert: key already exists");
547 LogicError(
"Ledger::rawReplace: key not found");
557 metaData,
"ripple::Ledger::rawTxInsert : non-null metadata input");
560 Serializer s(txn->getDataLength() + metaData->getDataLength() + 16);
561 s.
addVL(txn->peekData());
562 s.
addVL(metaData->peekData());
576 "ripple::Ledger::rawTxInsertWithHash : non-null metadata input");
579 Serializer s(txn->getDataLength() + metaData->getDataLength() + 16);
580 s.
addVL(txn->peekData());
581 s.
addVL(metaData->peekData());
605 JLOG(
j_.
error()) <<
"Exception in " << __func__ <<
": " << ex.
what();
613 bool oldFees =
false;
614 bool newFees =
false;
616 auto const baseFee = sle->at(~sfBaseFee);
617 auto const reserveBase = sle->at(~sfReserveBase);
618 auto const reserveIncrement = sle->at(~sfReserveIncrement);
623 if (reserveIncrement)
625 oldFees = baseFee || reserveBase || reserveIncrement;
628 auto const baseFeeXRP = sle->at(~sfBaseFeeDrops);
629 auto const reserveBaseXRP = sle->at(~sfReserveBaseDrops);
630 auto const reserveIncrementXRP =
631 sle->at(~sfReserveIncrementDrops);
632 auto assign = [&ret](
646 newFees = baseFeeXRP || reserveBaseXRP || reserveIncrementXRP;
648 if (oldFees && newFees)
662 JLOG(
j_.
error()) <<
"Exception in " << __func__ <<
": " << ex.
what();
674 "ripple::Ledger::defaultFees : zero fees");
700 sle && sle->isFieldPresent(sfDisabledValidators))
702 auto const& nUnlData = sle->getFieldArray(sfDisabledValidators);
703 for (
auto const& n : nUnlData)
705 if (n.isFieldPresent(sfPublicKey))
707 auto d = n.getFieldVL(sfPublicKey);
725 sle && sle->isFieldPresent(sfValidatorToDisable))
727 auto d = sle->getFieldVL(sfValidatorToDisable);
740 sle && sle->isFieldPresent(sfValidatorToReEnable))
742 auto d = sle->getFieldVL(sfValidatorToReEnable);
758 bool const hasToDisable = sle->isFieldPresent(sfValidatorToDisable);
759 bool const hasToReEnable = sle->isFieldPresent(sfValidatorToReEnable);
761 if (!hasToDisable && !hasToReEnable)
765 if (sle->isFieldPresent(sfDisabledValidators))
767 auto const& oldNUnl = sle->getFieldArray(sfDisabledValidators);
768 for (
auto v : oldNUnl)
770 if (hasToReEnable && v.isFieldPresent(sfPublicKey) &&
771 v.getFieldVL(sfPublicKey) ==
772 sle->getFieldVL(sfValidatorToReEnable))
782 sfPublicKey, sle->getFieldVL(sfValidatorToDisable));
786 if (!newNUnl.
empty())
788 sle->setFieldArray(sfDisabledValidators, newNUnl);
790 sle->makeFieldAbsent(sfValidatorToReEnable);
792 sle->makeFieldAbsent(sfValidatorToDisable);
822 if (!missingNodes1.
empty())
824 if (
auto stream = j.
info())
826 stream << missingNodes1.
size() <<
" missing account node(s)";
827 stream <<
"First: " << missingNodes1[0].what();
842 if (!missingNodes2.
empty())
844 if (
auto stream = j.
info())
846 stream << missingNodes2.
size() <<
" missing transaction node(s)";
847 stream <<
"First: " << missingNodes2[0].what();
850 return missingNodes1.
empty() && missingNodes2.
empty();
868 JLOG(ledgerJ.
fatal()) <<
"ledger is not sensible" << j;
870 UNREACHABLE(
"ripple::Ledger::assertSensible : ledger is not sensible");
886 if ((prevIndex & 0xff) == 0)
900 hashes =
static_cast<decltype(hashes)
>(sle->getFieldV256(sfHashes));
905 hashes.
size() <= 256,
906 "ripple::Ledger::updateSkipList : first maximum hashes size");
909 sle->setFieldU32(sfLastLedgerSequence, prevIndex);
928 hashes =
static_cast<decltype(hashes)
>(sle->getFieldV256(sfHashes));
932 hashes.
size() <= 256,
933 "ripple::Ledger::updateSkipList : second maximum hashes size");
934 if (hashes.
size() == 256)
938 sle->setFieldU32(sfLastLedgerSequence, prevIndex);
968 auto j = app.
journal(
"Ledger");
969 auto seq = ledger->info().seq;
973 JLOG(j.debug()) <<
"Save aborted";
979 Throw<std::runtime_error>(
"Failed to get relational database");
981 auto const res = db->saveValidatedLedger(ledger,
current);
1004 JLOG(stream) <<
"Double pend save for " << ledger->info().seq;
1015 ledger->isImmutable(),
"ripple::pendSaveValidated : immutable ledger");
1020 JLOG(stream) <<
"Pend save with seq in pending saves "
1021 << ledger->info().seq;
1027 if (!isSynchronous &&
1095 "ripple::finishLoadByIndexOrHash : valid ledger fees");
1096 ledger->setImmutable();
1098 JLOG(j.
trace()) <<
"Loaded ledger: " <<
to_string(ledger->info().hash);
1135 !ledger || ledger->info().hash == ledgerHash,
1136 "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)