20 #include <ripple/app/ledger/AcceptedLedger.h>
21 #include <ripple/app/ledger/InboundLedgers.h>
22 #include <ripple/app/ledger/Ledger.h>
23 #include <ripple/app/ledger/LedgerMaster.h>
24 #include <ripple/app/ledger/LedgerToJson.h>
25 #include <ripple/app/ledger/OrderBookDB.h>
26 #include <ripple/app/ledger/PendingSaves.h>
27 #include <ripple/app/ledger/TransactionMaster.h>
28 #include <ripple/app/main/Application.h>
29 #include <ripple/app/misc/HashRouter.h>
30 #include <ripple/app/misc/LoadFeeTrack.h>
31 #include <ripple/app/misc/NetworkOPs.h>
32 #include <ripple/app/rdb/backend/PostgresDatabase.h>
33 #include <ripple/app/rdb/backend/SQLiteDatabase.h>
34 #include <ripple/basics/Log.h>
35 #include <ripple/basics/StringUtilities.h>
36 #include <ripple/basics/contract.h>
37 #include <ripple/beast/core/LexicalCast.h>
38 #include <ripple/consensus/LedgerTiming.h>
39 #include <ripple/core/Config.h>
40 #include <ripple/core/JobQueue.h>
41 #include <ripple/core/Pg.h>
42 #include <ripple/core/SociDB.h>
43 #include <ripple/json/to_string.h>
44 #include <ripple/nodestore/Database.h>
45 #include <ripple/protocol/Feature.h>
46 #include <ripple/protocol/HashPrefix.h>
47 #include <ripple/protocol/Indexes.h>
48 #include <ripple/protocol/PublicKey.h>
49 #include <ripple/protocol/SecretKey.h>
50 #include <ripple/protocol/UintTypes.h>
51 #include <ripple/protocol/digest.h>
52 #include <ripple/protocol/jss.h>
53 #include <boost/optional.hpp>
58 #include <ripple/nodestore/impl/DatabaseNodeImp.h>
102 return std::make_unique<sles_iter_impl>(*
this);
106 equal(base_type
const& impl)
const override
109 return iter_ == p->iter_;
123 return std::make_shared<SLE const>(sit,
iter_->key());
150 return std::make_unique<txs_iter_impl>(*
this);
154 equal(base_type
const& impl)
const override
156 if (
auto const p =
dynamic_cast<txs_iter_impl const*
>(&impl))
157 return iter_ == p->iter_;
170 auto const& item = *
iter_;
201 sle->setFieldAmount(
sfBalance, info_.drops);
205 if (!amendments.empty())
208 sle->setFieldV256(
sfAmendments, STVector256{amendments});
252 , rules_(config.features)
264 Throw<std::runtime_error>(
"Missing tx map root for ledger");
267 JLOG(j.
warn()) <<
"Don't have transaction root for ledger" <<
info_.
seq;
276 Throw<std::runtime_error>(
"Missing state map root for ledger");
279 JLOG(j.
warn()) <<
"Don't have state data root for ledger" <<
info_.
seq;
301 , stateMap_(prevLedger.stateMap_, true)
302 , fees_(prevLedger.fees_)
303 , rules_(prevLedger.rules_)
304 , j_(
beast::Journal(
beast::Journal::getNullSink()))
350 info_.seq = ledgerSeq;
351 info_.closeTime = closeTime;
381 bool correctCloseTime)
406 return std::make_shared<STTx const>(sit);
417 result.
first = std::make_shared<STTx const>(s);
447 if (last && item->key() >= last)
455 if (k.
key == beast::zero)
463 auto sle = std::make_shared<SLE>(
SerialIter{item->slice()}, item->key());
480 return std::make_unique<sles_iter_impl>(
stateMap_.
end());
487 return std::make_unique<sles_iter_impl>(stateMap_.upper_bound(key));
499 return std::make_unique<txs_iter_impl>(!
open(),
txMap_.
end());
511 auto const& item = txMap_.peekItem(key);
517 return {std::move(result.first), std::move(result.second)};
528 if (!stateMap_.peekItem(key,
digest))
530 return digest.as_uint256();
539 LogicError(
"Ledger::rawErase: key not found");
546 LogicError(
"Ledger::rawErase: key not found");
557 LogicError(
"Ledger::rawInsert: key already exists");
568 LogicError(
"Ledger::rawReplace: key not found");
580 Serializer s(txn->getDataLength() + metaData->getDataLength() + 16);
581 s.
addVL(txn->peekData());
582 s.
addVL(metaData->peekData());
597 Serializer s(txn->getDataLength() + metaData->getDataLength() + 16);
598 s.
addVL(txn->peekData());
599 s.
addVL(metaData->peekData());
623 JLOG(
j_.
error()) <<
"Exception in " << __func__ <<
": " << ex.
what();
631 bool oldFees =
false;
632 bool newFees =
false;
634 auto const baseFee = sle->at(~
sfBaseFee);
641 if (reserveIncrement)
643 oldFees = baseFee || reserveBase || reserveIncrement;
648 auto const reserveIncrementXRP =
650 auto assign = [&ret](
664 newFees = baseFeeXRP || reserveBaseXRP || reserveIncrementXRP;
666 if (oldFees && newFees)
680 JLOG(
j_.
error()) <<
"Exception in " << __func__ <<
": " << ex.
what();
705 auto sle = std::make_shared<SLE>(
SerialIter{value->slice()}, value->key());
719 for (
auto const& n : nUnlData)
777 if (!hasToDisable && !hasToReEnable)
784 for (
auto v : oldNUnl)
786 if (hasToReEnable && v.isFieldPresent(
sfPublicKey) &&
802 if (!newNUnl.
empty())
838 if (!missingNodes1.
empty())
840 if (
auto stream = j.
info())
842 stream << missingNodes1.
size() <<
" missing account node(s)";
843 stream <<
"First: " << missingNodes1[0].what();
858 if (!missingNodes2.
empty())
860 if (
auto stream = j.
info())
862 stream << missingNodes2.
size() <<
" missing transaction node(s)";
863 stream <<
"First: " << missingNodes2[0].what();
866 return missingNodes1.
empty() && missingNodes2.
empty();
884 JLOG(ledgerJ.
fatal()) <<
"ledger is not sensible" << j;
902 if ((prevIndex & 0xff) == 0)
911 sle = std::make_shared<SLE>(k);
916 hashes =
static_cast<decltype(hashes)
>(sle->getFieldV256(
sfHashes));
920 assert(hashes.
size() <= 256);
937 sle = std::make_shared<SLE>(k);
942 hashes =
static_cast<decltype(hashes)
>(sle->getFieldV256(
sfHashes));
945 assert(hashes.
size() <= 256);
946 if (hashes.
size() == 256)
980 auto j = app.
journal(
"Ledger");
985 JLOG(j.debug()) <<
"Save aborted";
991 Throw<std::runtime_error>(
"Failed to get relational database");
993 auto const res = db->saveValidatedLedger(ledger,
current);
1015 JLOG(stream) <<
"Double pend save for " << ledger->
info().
seq;
1030 JLOG(stream) <<
"Pend save with seq in pending saves "
1037 if (!isSynchronous &&
1042 saveValidatedLedger(app, ledger, isCurrent);
1079 auto ledger = std::make_shared<Ledger>(
1143 assert(!ledger || ledger->
info().
hash == ledgerHash);
1156 Throw<std::runtime_error>(
1157 "flatFetchTransactions: not running in reporting mode");
1169 Throw<std::runtime_error>(
1170 "Called flatFetchTransactions but database is not DatabaseNodeImp");
1172 auto objs = nodeDb->fetchBatch(nodestoreHashes);
1176 <<
" Flat fetch time : " << ((end - start).count() / 1000000000.0)
1177 <<
" number of transactions " << nodestoreHashes.
size();
1178 assert(objs.size() == nodestoreHashes.
size());
1179 for (
size_t i = 0; i < objs.size(); ++i)
1181 uint256& nodestoreHash = nodestoreHashes[i];
1182 auto& obj = objs[i];
1190 Throw<std::runtime_error>(
1191 "flatFetchTransactions : Error making SHAMap node");
1193 auto item = (
static_cast<SHAMapLeafNode*
>(node.get()))->peekItem();
1197 Throw<std::runtime_error>(
1198 "flatFetchTransactions : Error reading SHAMap node");
1201 if (!txnPlusMeta.first || !txnPlusMeta.second)
1204 Throw<std::runtime_error>(
1205 "flatFetchTransactions : Error deserializing SHAMap node");
1207 txns.push_back(std::move(txnPlusMeta));
1212 Throw<std::runtime_error>(
1213 "flatFetchTransactions : Containing SHAMap node not found");
1231 Throw<std::runtime_error>(
"Failed to get relational database");
1233 auto nodestoreHashes = db->getTxHashes(ledger.
info().
seq);
virtual LedgerInfo const & info() const =0
Returns information about the ledger.
std::unique_ptr< sles_type::iter_base > slesUpperBound(uint256 const &key) const override
XRPAmount reference_fee
The cost of a reference transaction in drops.
sles_iter_impl(SHAMap::const_iterator iter)
std::unique_ptr< sles_type::iter_base > slesBegin() const override
virtual Family & getNodeFamily()=0
bool addSLE(SLE const &sle)
uint256 const & key() const
Returns the 'key' (or 'index') of this item.
bool isFlagLedger(LedgerIndex seq)
Returns true if the given ledgerIndex is a flag ledgerIndex.
void rawReplace(std::shared_ptr< SLE > const &sle) override
Unconditionally replace a state item.
@ ledgerMaster
ledger master data for signing
const SF_AMOUNT sfBaseFeeDrops
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)
const SF_UINT32 sfReserveBase
A pair of SHAMap key and LedgerEntryType.
const uint256 featureXRPFees
bool isVotingLedger() const
Returns true if the ledger directly precedes a flag ledger.
std::optional< uint256 > succ(uint256 const &key, std::optional< uint256 > const &last=std::nullopt) const override
Return the key of the next state item.
tx_type txRead(key_type const &key) const override
Read a transaction from the tx map.
bool enabled(uint256 const &feature) const
Returns true if a feature is enabled.
Keylet const & amendments() noexcept
The index of the amendment table.
SHAMapHash getHash() const
std::shared_ptr< Ledger > loadByIndex(std::uint32_t ledgerIndex, Application &app, bool acquire)
@ txNode
transaction plus metadata
bool updateGiveItem(SHAMapNodeType type, boost::intrusive_ptr< SHAMapItem const > item)
Stream trace() const
Severity stream access functions.
boost::intrusive_ptr< SHAMapItem const > const & peekItem(uint256 const &id) const
std::unique_ptr< sles_type::iter_base > slesEnd() const override
const SF_UINT32 sfFirstLedgerSequence
bool pending(LedgerIndex seq)
Return true if a ledger is in the progress of being saved.
constexpr value_type drops() const
Returns the number of drops.
boost::intrusive_ptr< SHAMapItem > make_shamapitem(uint256 const &tag, Slice data)
const SF_UINT32 sfSequence
bool walkLedger(beast::Journal j, bool parallel=false) const
void defaultFees(Config const &config)
sles_type::value_type dereference() const override
Keylet const & skip() noexcept
The index of the "short" skip list.
std::tuple< std::shared_ptr< Ledger >, std::uint32_t, uint256 > getLatestLedger(Application &app)
constexpr std::uint32_t FLAG_LEDGER_INTERVAL
Serializer getSerializer() const
bool exists(Keylet const &k) const override
Determine if a state item exists.
bool equal(base_type const &impl) const override
void push_back(STObject const &object)
std::shared_ptr< SLE > peek(Keylet const &k) const
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.
txs_iter_impl & operator=(txs_iter_impl const &)=delete
const_iterator begin() const
bool addJob(JobType type, std::string const &name, JobHandler &&jobHandler)
Adds a job to the JobQueue.
void rawTxInsert(uint256 const &key, std::shared_ptr< Serializer const > const &txn, std::shared_ptr< Serializer const > const &metaData) override
Add a transaction to the tx map.
void setFieldVL(SField const &field, Blob const &)
bool startWork(LedgerIndex seq)
Start working on a ledger.
txs_iter_impl(bool metadata, SHAMap::const_iterator iter)
virtual std::optional< LedgerInfo > getNewestLedgerInfo()=0
getNewestLedgerInfo Returns the info of the newest saved ledger.
void rawErase(std::shared_ptr< SLE > const &sle) override
Delete an existing state item.
virtual std::optional< LedgerInfo > getLedgerInfoByIndex(LedgerIndex ledgerSeq)=0
getLedgerInfoByIndex Returns a ledger by its sequence.
static Sink & getNullSink()
Returns a Sink which does nothing.
void updateNegativeUNL()
update the Negative UNL ledger component.
bool addItem(SHAMapNodeType type, boost::intrusive_ptr< SHAMapItem const > item)
static void finishLoadByIndexOrHash(std::shared_ptr< Ledger > const &ledger, Config const &config, beast::Journal j)
static constexpr std::uint32_t XRP_LEDGER_EARLIEST_FEES
The XRP Ledger mainnet's earliest ledger with a FeeSettings object.
std::shared_ptr< STTx const > deserializeTx(SHAMapItem const &item)
Deserialize a SHAMapItem containing a single STTx.
std::pair< PublicKey, SecretKey > generateKeyPair(KeyType type, Seed const &seed)
Generate a key pair deterministically.
constexpr XRPAmount INITIAL_XRP
Configure the native currency.
std::shared_ptr< SLE const > value_type
std::optional< PublicKey > validatorToDisable() const
get the to be disabled validator's master public key if any
std::unique_ptr< txs_type::iter_base > txsEnd() const override
static Hasher::result_type digest(void const *data, std::size_t size) noexcept
NetClock::time_point closeTime
std::optional< KeyType > publicKeyType(Slice const &slice)
Returns the type of public key.
LedgerInfo const & info() const override
Returns information about the ledger.
T time_since_epoch(T... args)
bool hasItem(uint256 const &id) const
Does the tree have an item with the given ID?
bool txExists(uint256 const &key) const override
Returns true if a tx exists in the tx map.
static bool saveValidatedLedger(Application &app, std::shared_ptr< Ledger const > const &ledger, bool current)
std::shared_ptr< Ledger > loadByHash(uint256 const &ledgerHash, Application &app, bool acquire)
bool addGiveItem(SHAMapNodeType type, boost::intrusive_ptr< SHAMapItem const > item)
Keylet account(AccountID const &id) noexcept
AccountID root.
virtual PendingSaves & pendingSaves()=0
std::pair< std::shared_ptr< STTx const >, std::shared_ptr< STObject const > > deserializeTxPlusMeta(SHAMapItem const &item)
Deserialize a SHAMapItem containing STTx + STObject metadata.
uint256 calculateLedgerHash(LedgerInfo const &info)
std::unique_ptr< base_type > copy() const override
void Rethrow()
Rethrow the exception currently being handled.
const SF_UINT32 sfReserveIncrement
virtual Config & config()=0
bool isCurrent(ValidationParms const &p, NetClock::time_point now, NetClock::time_point signTime, NetClock::time_point seenTime)
Whether a validation is still current.
SHAMap::const_iterator iter_
void setAccepted(NetClock::time_point closeTime, NetClock::duration closeResolution, bool correctCloseTime)
AccountID calcAccountID(PublicKey const &pk)
virtual RelationalDatabase & getRelationalDatabase()=0
SHAMap::const_iterator iter_
bool isFlagLedger() const
Returns true if the ledger is a flag ledger.
bool equal(base_type const &impl) const override
sles_iter_impl & operator=(sles_iter_impl const &)=delete
virtual JobQueue & getJobQueue()=0
const SF_VL sfValidatorToDisable
virtual std::optional< LedgerInfo > getLedgerInfoByHash(uint256 const &ledgerHash)=0
getLedgerInfoByHash Returns the info of the ledger with given hash.
Slice slice() const noexcept
void rawInsert(std::shared_ptr< SLE > const &sle) override
Unconditionally insert a state item.
bool assertSensible(beast::Journal ledgerJ) const
@ current
This was a new validation and was added.
void finishWork(LedgerIndex seq)
Finish working on a ledger.
A generic endpoint for log messages.
XRPAmount account_reserve
The account reserve requirement in drops.
const SF_AMOUNT sfReserveIncrementDrops
std::optional< PublicKey > validatorToReEnable() const
get the to be re-enabled validator's master public key if any
bool shouldWork(LedgerIndex seq, bool isSynchronous)
Check if a ledger should be dispatched.
const SF_AMOUNT sfReserveBaseDrops
static constexpr std::uint32_t FEE_UNITS_DEPRECATED
bool fetchRoot(SHAMapHash const &hash, SHAMapSyncFilter *filter)
void walkMap(std::vector< SHAMapMissingNode > &missingNodes, int maxMissing) const
void setImmutable(bool rehash=true)
Json::Value getJson(LedgerFill const &fill)
Return a new Json::Value representing the ledger with given options.
std::shared_ptr< SLE const > read(Keylet const &k) const override
Return the state item associated with a key.
static std::shared_ptr< SHAMapTreeNode > makeFromPrefix(Slice rawNode, SHAMapHash const &hash)
const SF_UINT64 sfBaseFee
const_iterator upper_bound(uint256 const &id) const
Find the first item after the given item.
bool getCloseAgree(LedgerInfo const &info)
const SF_VECTOR256 sfHashes
Seed generateSeed(std::string const &passPhrase)
Generate a seed deterministically.
std::unique_ptr< txs_type::iter_base > txsBegin() const override
T emplace_back(T... args)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
bool walkMapParallel(std::vector< SHAMapMissingNode > &missingNodes, int maxMissing) const
std::unordered_set< uint256, beast::uhash<> > features
virtual NodeStore::Database & getNodeStore()=0
virtual beast::Journal journal(std::string const &name)=0
void emplace_back(Args &&... args)
LedgerIndex seq() const
Returns the sequence number of the base ledger.
const_iterator end() const
void LogicError(std::string const &how) noexcept
Called when faulty logic causes a broken invariant.
NetClock::duration closeTimeResolution
sha512_half_hasher::result_type sha512Half(Args const &... args)
Returns the SHA512-Half of a series of objects.
const create_genesis_t create_genesis
const SField sfDisabledValidator
int unshare()
Convert any modified nodes to shared.
XRPAmount owner_reserve
The per-owned item reserve requirement in drops.
bool open() const override
Returns true if this reflects an open ledger.
const SF_AMOUNT sfBalance
const SF_UINT32 sfReferenceFeeUnits
Rules makeRulesGivenLedger(DigestAwareReadView const &ledger, Rules const ¤t)
int addVL(Blob const &vector)
hash_set< PublicKey > negativeUNL() const
get Negative UNL validators' master public keys
std::string to_string(Manifest const &m)
Format the specified manifest to a string for debugging purposes.
Keylet const & fees() noexcept
The (fixed) index of the object containing the ledger fees.
constexpr auto ledgerGenesisTimeResolution
Close time resolution in genesis ledger.
bool check(STLedgerEntry const &) const
Returns true if the SLE matches the type.
const SF_ACCOUNT sfAccount
Information about the notional ledger backing the view.
uint256 const & as_uint256() const
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.
virtual void missingNodeAcquireByHash(uint256 const &refHash, std::uint32_t refNum)=0
Acquire ledger that has a missing node by ledger hash.
uint256 rawTxInsertWithHash(uint256 const &key, std::shared_ptr< Serializer const > const &txn, std::shared_ptr< Serializer const > const &metaData)
const SF_UINT32 sfLastLedgerSequence
constexpr auto ledgerDefaultTimeResolution
Initial resolution of ledger close time.
Keylet const & negativeUNL() noexcept
The (fixed) index of the object containing the ledger negativeUNL.
txs_type::value_type dereference() const override
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.
Ledger(Ledger const &)=delete
std::optional< digest_type > digest(key_type const &key) const override
Return the digest associated with the key.
std::shared_ptr< Ledger > loadLedgerHelper(LedgerInfo const &info, Application &app, bool acquire)
bool delItem(uint256 const &id)
void increment() override
void setFieldU32(SField const &field, std::uint32_t)
std::unique_ptr< base_type > copy() const override
const SField sfDisabledValidators
virtual HashRouter & getHashRouter()=0
void increment() override
bool setFlags(uint256 const &key, int flags)
Set the flags on a hash.
Slice getSlice(std::size_t bytes)
const SF_VECTOR256 sfAmendments
static const std::uint32_t sLCF_NoConsensusTime
void open(soci::session &s, BasicConfig const &config, std::string const &dbName)
Open a soci session.
const SF_VL sfValidatorToReEnable
NetClock::time_point parentCloseTime
std::vector< std::pair< std::shared_ptr< STTx const >, std::shared_ptr< STObject const > > > flatFetchTransactions(Application &app, std::vector< uint256 > &nodestoreHashes)