mirror of
https://github.com/Xahau/xahaud.git
synced 2025-11-19 10:05:48 +00:00
523 lines
13 KiB
C++
523 lines
13 KiB
C++
//------------------------------------------------------------------------------
|
|
/*
|
|
This file is part of rippled: https://github.com/ripple/rippled
|
|
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
|
|
|
Permission to use, copy, modify, and/or distribute this software for any
|
|
purpose with or without fee is hereby granted, provided that the above
|
|
copyright notice and this permission notice appear in all copies.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
*/
|
|
//==============================================================================
|
|
|
|
#ifndef RIPPLE_APP_LEDGER_LEDGER_H_INCLUDED
|
|
#define RIPPLE_APP_LEDGER_LEDGER_H_INCLUDED
|
|
|
|
#include <ripple/basics/CountedObject.h>
|
|
#include <ripple/beast/utility/Journal.h>
|
|
#include <ripple/core/TimeKeeper.h>
|
|
#include <ripple/ledger/CachedView.h>
|
|
#include <ripple/ledger/View.h>
|
|
#include <ripple/protocol/Book.h>
|
|
#include <ripple/protocol/Indexes.h>
|
|
#include <ripple/protocol/STLedgerEntry.h>
|
|
#include <ripple/protocol/Serializer.h>
|
|
#include <ripple/protocol/TxMeta.h>
|
|
#include <ripple/shamap/SHAMap.h>
|
|
#include <mutex>
|
|
|
|
namespace ripple {
|
|
|
|
class Application;
|
|
class Job;
|
|
class TransactionMaster;
|
|
|
|
class SqliteStatement;
|
|
|
|
struct create_genesis_t
|
|
{
|
|
explicit create_genesis_t() = default;
|
|
};
|
|
extern create_genesis_t const create_genesis;
|
|
|
|
/** Holds a ledger.
|
|
|
|
The ledger is composed of two SHAMaps. The state map holds all of the
|
|
ledger entries such as account roots and order books. The tx map holds
|
|
all of the transactions and associated metadata that made it into that
|
|
particular ledger. Most of the operations on a ledger are concerned
|
|
with the state map.
|
|
|
|
This can hold just the header, a partial set of data, or the entire set
|
|
of data. It all depends on what is in the corresponding SHAMap entry.
|
|
Various functions are provided to populate or depopulate the caches that
|
|
the object holds references to.
|
|
|
|
Ledgers are constructed as either mutable or immutable.
|
|
|
|
1) If you are the sole owner of a mutable ledger, you can do whatever you
|
|
want with no need for locks.
|
|
|
|
2) If you have an immutable ledger, you cannot ever change it, so no need
|
|
for locks.
|
|
|
|
3) Mutable ledgers cannot be shared.
|
|
|
|
@note Presented to clients as ReadView
|
|
@note Calls virtuals in the constructor, so marked as final
|
|
*/
|
|
class Ledger final : public std::enable_shared_from_this<Ledger>,
|
|
public DigestAwareReadView,
|
|
public TxsRawView,
|
|
public CountedObject<Ledger>
|
|
{
|
|
public:
|
|
Ledger(Ledger const&) = delete;
|
|
Ledger&
|
|
operator=(Ledger const&) = delete;
|
|
|
|
Ledger(Ledger&&) = delete;
|
|
Ledger&
|
|
operator=(Ledger&&) = delete;
|
|
|
|
/** Create the Genesis ledger.
|
|
|
|
The Genesis ledger contains a single account whose
|
|
AccountID is generated with a Generator using the seed
|
|
computed from the string "masterpassphrase" and ordinal
|
|
zero.
|
|
|
|
The account has an XRP balance equal to the total amount
|
|
of XRP in the system. No more XRP than the amount which
|
|
starts in this account can ever exist, with amounts
|
|
used to pay fees being destroyed.
|
|
|
|
Amendments specified are enabled in the genesis ledger
|
|
*/
|
|
Ledger(
|
|
create_genesis_t,
|
|
Config const& config,
|
|
std::vector<uint256> const& amendments,
|
|
Family& family);
|
|
|
|
Ledger(LedgerInfo const& info, Config const& config, Family& family);
|
|
|
|
/** Used for ledgers loaded from JSON files
|
|
|
|
@param acquire If true, acquires the ledger if not found locally
|
|
*/
|
|
Ledger(
|
|
LedgerInfo const& info,
|
|
bool& loaded,
|
|
bool acquire,
|
|
Config const& config,
|
|
Family& family,
|
|
beast::Journal j);
|
|
|
|
// used when loading ledgers from catalogue files
|
|
Ledger(
|
|
LedgerInfo& info,
|
|
Config const& config,
|
|
Family& family,
|
|
SHAMap const& baseState);
|
|
|
|
/** Create a new ledger following a previous ledger
|
|
|
|
The ledger will have the sequence number that
|
|
follows previous, and have
|
|
parentCloseTime == previous.closeTime.
|
|
*/
|
|
Ledger(Ledger const& previous, NetClock::time_point closeTime);
|
|
|
|
// used for database ledgers
|
|
Ledger(
|
|
std::uint32_t ledgerSeq,
|
|
NetClock::time_point closeTime,
|
|
Config const& config,
|
|
Family& family);
|
|
|
|
~Ledger() = default;
|
|
|
|
//
|
|
// ReadView
|
|
//
|
|
|
|
bool
|
|
open() const override
|
|
{
|
|
return false;
|
|
}
|
|
|
|
LedgerInfo const&
|
|
info() const override
|
|
{
|
|
return info_;
|
|
}
|
|
|
|
void
|
|
setLedgerInfo(LedgerInfo const& info)
|
|
{
|
|
info_ = info;
|
|
}
|
|
|
|
Fees const&
|
|
fees() const override
|
|
{
|
|
return fees_;
|
|
}
|
|
|
|
Rules const&
|
|
rules() const override
|
|
{
|
|
return rules_;
|
|
}
|
|
|
|
bool
|
|
exists(Keylet const& k) const override;
|
|
|
|
bool
|
|
exists(uint256 const& key) const;
|
|
|
|
std::optional<uint256>
|
|
succ(uint256 const& key, std::optional<uint256> const& last = std::nullopt)
|
|
const override;
|
|
|
|
std::shared_ptr<SLE const>
|
|
read(Keylet const& k) const override;
|
|
|
|
std::unique_ptr<sles_type::iter_base>
|
|
slesBegin() const override;
|
|
|
|
std::unique_ptr<sles_type::iter_base>
|
|
slesEnd() const override;
|
|
|
|
std::unique_ptr<sles_type::iter_base>
|
|
slesUpperBound(uint256 const& key) const override;
|
|
|
|
std::unique_ptr<txs_type::iter_base>
|
|
txsBegin() const override;
|
|
|
|
std::unique_ptr<txs_type::iter_base>
|
|
txsEnd() const override;
|
|
|
|
bool
|
|
txExists(uint256 const& key) const override;
|
|
|
|
tx_type
|
|
txRead(key_type const& key) const override;
|
|
|
|
//
|
|
// DigestAwareReadView
|
|
//
|
|
|
|
std::optional<digest_type>
|
|
digest(key_type const& key) const override;
|
|
|
|
//
|
|
// RawView
|
|
//
|
|
|
|
void
|
|
rawErase(std::shared_ptr<SLE> const& sle) override;
|
|
|
|
void
|
|
rawInsert(std::shared_ptr<SLE> const& sle) override;
|
|
|
|
void
|
|
rawErase(uint256 const& key);
|
|
|
|
void
|
|
rawReplace(std::shared_ptr<SLE> const& sle) override;
|
|
|
|
void
|
|
rawDestroyXRP(XRPAmount const& fee) override
|
|
{
|
|
info_.drops -= fee;
|
|
}
|
|
|
|
//
|
|
// TxsRawView
|
|
//
|
|
|
|
void
|
|
rawTxInsert(
|
|
uint256 const& key,
|
|
std::shared_ptr<Serializer const> const& txn,
|
|
std::shared_ptr<Serializer const> const& metaData) override;
|
|
|
|
// Insert the transaction, and return the hash of the SHAMap leaf node
|
|
// holding the transaction. The hash can be used to fetch the transaction
|
|
// directly, instead of traversing the SHAMap
|
|
// @param key transaction ID
|
|
// @param txn transaction
|
|
// @param metaData transaction metadata
|
|
// @return hash of SHAMap leaf node that holds the transaction
|
|
uint256
|
|
rawTxInsertWithHash(
|
|
uint256 const& key,
|
|
std::shared_ptr<Serializer const> const& txn,
|
|
std::shared_ptr<Serializer const> const& metaData);
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
void
|
|
setValidated() const
|
|
{
|
|
info_.validated = true;
|
|
}
|
|
|
|
void
|
|
setAccepted(
|
|
NetClock::time_point closeTime,
|
|
NetClock::duration closeResolution,
|
|
bool correctCloseTime);
|
|
|
|
void
|
|
setImmutable(bool rehash = true);
|
|
|
|
void
|
|
setCloseFlags(int closeFlags);
|
|
|
|
void
|
|
setDrops(uint64_t drops);
|
|
|
|
bool
|
|
isImmutable() const
|
|
{
|
|
return mImmutable;
|
|
}
|
|
|
|
/* Mark this ledger as "should be full".
|
|
|
|
"Full" is metadata property of the ledger, it indicates
|
|
that the local server wants all the corresponding nodes
|
|
in durable storage.
|
|
|
|
This is marked `const` because it reflects metadata
|
|
and not data that is in common with other nodes on the
|
|
network.
|
|
*/
|
|
void
|
|
setFull() const
|
|
{
|
|
txMap_.setFull();
|
|
txMap_.setLedgerSeq(info_.seq);
|
|
stateMap_.setFull();
|
|
stateMap_.setLedgerSeq(info_.seq);
|
|
}
|
|
|
|
void
|
|
setTotalDrops(std::uint64_t totDrops)
|
|
{
|
|
info_.drops = totDrops;
|
|
}
|
|
|
|
SHAMap const&
|
|
stateMap() const
|
|
{
|
|
return stateMap_;
|
|
}
|
|
|
|
SHAMap&
|
|
stateMap()
|
|
{
|
|
return stateMap_;
|
|
}
|
|
|
|
SHAMap const&
|
|
txMap() const
|
|
{
|
|
return txMap_;
|
|
}
|
|
|
|
SHAMap&
|
|
txMap()
|
|
{
|
|
return txMap_;
|
|
}
|
|
|
|
// returns false on error
|
|
bool
|
|
addSLE(SLE const& sle);
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
void
|
|
updateSkipList();
|
|
|
|
bool
|
|
walkLedger(beast::Journal j, bool parallel = false) const;
|
|
|
|
bool
|
|
assertSensible(beast::Journal ledgerJ) const;
|
|
|
|
void
|
|
invariants() const;
|
|
void
|
|
unshare() const;
|
|
|
|
/**
|
|
* get Negative UNL validators' master public keys
|
|
*
|
|
* @return the public keys
|
|
*/
|
|
hash_set<PublicKey>
|
|
negativeUNL() const;
|
|
|
|
/**
|
|
* get the to be disabled validator's master public key if any
|
|
*
|
|
* @return the public key if any
|
|
*/
|
|
std::optional<PublicKey>
|
|
validatorToDisable() const;
|
|
|
|
/**
|
|
* get the to be re-enabled validator's master public key if any
|
|
*
|
|
* @return the public key if any
|
|
*/
|
|
std::optional<PublicKey>
|
|
validatorToReEnable() const;
|
|
|
|
/**
|
|
* update the Negative UNL ledger component.
|
|
* @note must be called at and only at flag ledgers
|
|
* must be called before applying UNLModify Tx
|
|
*/
|
|
void
|
|
updateNegativeUNL();
|
|
|
|
/** Returns true if the ledger is a flag ledger */
|
|
bool
|
|
isFlagLedger() const;
|
|
|
|
/** Returns true if the ledger directly precedes a flag ledger */
|
|
bool
|
|
isVotingLedger() const;
|
|
|
|
std::shared_ptr<SLE>
|
|
peek(Keylet const& k) const;
|
|
|
|
private:
|
|
class sles_iter_impl;
|
|
class txs_iter_impl;
|
|
|
|
bool
|
|
setup();
|
|
|
|
void
|
|
defaultFees(Config const& config);
|
|
|
|
bool mImmutable;
|
|
|
|
// A SHAMap containing the transactions associated with this ledger.
|
|
SHAMap mutable txMap_;
|
|
|
|
// A SHAMap containing the state objects for this ledger.
|
|
SHAMap mutable stateMap_;
|
|
|
|
// Protects fee variables
|
|
std::mutex mutable mutex_;
|
|
|
|
Fees fees_;
|
|
Rules rules_;
|
|
LedgerInfo info_;
|
|
beast::Journal j_;
|
|
};
|
|
|
|
/** A ledger wrapped in a CachedView. */
|
|
using CachedLedger = CachedView<Ledger>;
|
|
|
|
std::uint32_t constexpr FLAG_LEDGER_INTERVAL = 256;
|
|
/** Returns true if the given ledgerIndex is a flag ledgerIndex */
|
|
bool
|
|
isFlagLedger(LedgerIndex seq);
|
|
|
|
//------------------------------------------------------------------------------
|
|
//
|
|
// API
|
|
//
|
|
//------------------------------------------------------------------------------
|
|
|
|
extern bool
|
|
pendSaveValidated(
|
|
Application& app,
|
|
std::shared_ptr<Ledger const> const& ledger,
|
|
bool isSynchronous,
|
|
bool isCurrent);
|
|
|
|
std::shared_ptr<Ledger>
|
|
loadLedgerHelper(LedgerInfo const& sinfo, Application& app, bool acquire);
|
|
|
|
std::shared_ptr<Ledger>
|
|
loadByIndex(std::uint32_t ledgerIndex, Application& app, bool acquire = true);
|
|
|
|
std::shared_ptr<Ledger>
|
|
loadByHash(uint256 const& ledgerHash, Application& app, bool acquire = true);
|
|
|
|
// Fetch the ledger with the highest sequence contained in the database
|
|
extern std::tuple<std::shared_ptr<Ledger>, std::uint32_t, uint256>
|
|
getLatestLedger(Application& app);
|
|
|
|
// *** Reporting Mode Only ***
|
|
// Fetch all of the transactions contained in ledger from the nodestore.
|
|
// The transactions are fetched directly as a batch, instead of traversing the
|
|
// transaction SHAMap. Fetching directly is significantly faster than
|
|
// traversing, as there are less database reads, and all of the reads can
|
|
// executed concurrently. This function only works in reporting mode.
|
|
// @param ledger the ledger for which to fetch the contained transactions
|
|
// @param app reference to the Application
|
|
// @return vector of (transaction, metadata) pairs
|
|
extern std::vector<
|
|
std::pair<std::shared_ptr<STTx const>, std::shared_ptr<STObject const>>>
|
|
flatFetchTransactions(ReadView const& ledger, Application& app);
|
|
|
|
// *** Reporting Mode Only ***
|
|
// For each nodestore hash, fetch the transaction.
|
|
// The transactions are fetched directly as a batch, instead of traversing the
|
|
// transaction SHAMap. Fetching directly is significantly faster than
|
|
// traversing, as there are less database reads, and all of the reads can
|
|
// executed concurrently. This function only works in reporting mode.
|
|
// @param nodestoreHashes hashes of the transactions to fetch
|
|
// @param app reference to the Application
|
|
// @return vector of (transaction, metadata) pairs
|
|
extern std::vector<
|
|
std::pair<std::shared_ptr<STTx const>, std::shared_ptr<STObject const>>>
|
|
flatFetchTransactions(Application& app, std::vector<uint256>& nodestoreHashes);
|
|
|
|
/** Deserialize a SHAMapItem containing a single STTx
|
|
|
|
Throw:
|
|
|
|
May throw on deserializaton error
|
|
*/
|
|
std::shared_ptr<STTx const>
|
|
deserializeTx(SHAMapItem const& item);
|
|
|
|
/** Deserialize a SHAMapItem containing STTx + STObject metadata
|
|
|
|
The SHAMap must contain two variable length
|
|
serialization objects.
|
|
|
|
Throw:
|
|
|
|
May throw on deserializaton error
|
|
*/
|
|
std::pair<std::shared_ptr<STTx const>, std::shared_ptr<STObject const>>
|
|
deserializeTxPlusMeta(SHAMapItem const& item);
|
|
|
|
uint256
|
|
calculateLedgerHash(LedgerInfo const& info);
|
|
|
|
} // namespace ripple
|
|
|
|
#endif
|