mirror of
https://github.com/XRPLF/rippled.git
synced 2026-07-24 15:40:26 +00:00
Refactor treatment of Ledger:
All handling of Ledger in shared_ptr is modified to use a const managed object when the context requires immutable semantics.
This commit is contained in:
@@ -41,7 +41,7 @@ AcceptedLedgerTx::AcceptedLedgerTx (
|
||||
, accountCache_ (accountCache)
|
||||
, logs_ (logs)
|
||||
{
|
||||
assert (! ledger->info().open);
|
||||
assert (! ledger->open());
|
||||
|
||||
mResult = mMeta->getResultTER ();
|
||||
|
||||
@@ -65,7 +65,7 @@ AcceptedLedgerTx::AcceptedLedgerTx (
|
||||
, accountCache_ (accountCache)
|
||||
, logs_ (logs)
|
||||
{
|
||||
assert (ledger->info().open);
|
||||
assert (ledger->open());
|
||||
buildJson ();
|
||||
}
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ public:
|
||||
startRound (
|
||||
LedgerConsensus& consensus,
|
||||
LedgerHash const &prevLCLHash,
|
||||
Ledger::ref previousLedger,
|
||||
std::shared_ptr<Ledger const> const& previousLedger,
|
||||
NetClock::time_point closeTime) = 0;
|
||||
|
||||
/** Specified the network time when the last ledger closed */
|
||||
|
||||
@@ -66,7 +66,8 @@ public:
|
||||
{
|
||||
return mHaveHeader;
|
||||
}
|
||||
Ledger::ref getLedger () const
|
||||
std::shared_ptr<Ledger> const&
|
||||
getLedger() const
|
||||
{
|
||||
return mLedger;
|
||||
}
|
||||
@@ -131,7 +132,7 @@ private:
|
||||
bool takeAsRootNode (Blob const& data, SHAMapAddNode&);
|
||||
|
||||
private:
|
||||
Ledger::pointer mLedger;
|
||||
std::shared_ptr<Ledger> mLedger;
|
||||
bool mHaveHeader;
|
||||
bool mHaveState;
|
||||
bool mHaveTransactions;
|
||||
|
||||
@@ -40,7 +40,9 @@ public:
|
||||
|
||||
// VFALCO TODO Should this be called findOrAdd ?
|
||||
//
|
||||
virtual Ledger::pointer acquire (uint256 const& hash,
|
||||
virtual
|
||||
std::shared_ptr<Ledger>
|
||||
acquire (uint256 const& hash,
|
||||
std::uint32_t seq, InboundLedger::fcReason) = 0;
|
||||
|
||||
virtual std::shared_ptr<InboundLedger> find (LedgerHash const& hash) = 0;
|
||||
|
||||
@@ -179,6 +179,7 @@ Ledger::Ledger (create_genesis_t, Config const& config, Family& family)
|
||||
info_.seq = 1;
|
||||
info_.drops = SYSTEM_CURRENCY_START;
|
||||
info_.closeTimeResolution = ledgerDefaultTimeResolution;
|
||||
|
||||
static auto const id = calcAccountID(
|
||||
generateKeyPair(KeyType::secp256k1,
|
||||
generateSeed("masterpassphrase")).first);
|
||||
@@ -189,7 +190,6 @@ Ledger::Ledger (create_genesis_t, Config const& config, Family& family)
|
||||
rawInsert(sle);
|
||||
stateMap_->flushDirty (hotACCOUNT_NODE, info_.seq);
|
||||
updateHash();
|
||||
setClosed();
|
||||
setImmutable(config);
|
||||
setup(config);
|
||||
}
|
||||
@@ -210,8 +210,8 @@ Ledger::Ledger (uint256 const& parentHash,
|
||||
: mImmutable (true)
|
||||
, txMap_ (std::make_shared <SHAMap> (
|
||||
SHAMapType::TRANSACTION, transHash, family))
|
||||
, stateMap_ (std::make_shared <SHAMap> (SHAMapType::STATE, accountHash,
|
||||
family))
|
||||
, stateMap_ (std::make_shared <SHAMap> (
|
||||
SHAMapType::STATE, accountHash, family))
|
||||
{
|
||||
info_.seq = ledgerSeq;
|
||||
info_.parentCloseTime = parentCloseTime;
|
||||
@@ -222,6 +222,7 @@ Ledger::Ledger (uint256 const& parentHash,
|
||||
info_.parentHash = parentHash;
|
||||
info_.closeTimeResolution = closeResolution;
|
||||
info_.closeFlags = closeFlags;
|
||||
|
||||
loaded = true;
|
||||
|
||||
if (info_.txHash.isNonZero () &&
|
||||
@@ -251,20 +252,8 @@ Ledger::Ledger (uint256 const& parentHash,
|
||||
}
|
||||
}
|
||||
|
||||
// Create a new ledger that's a snapshot of this one
|
||||
Ledger::Ledger (Ledger const& ledger,
|
||||
bool isMutable)
|
||||
: mImmutable (!isMutable)
|
||||
, txMap_ (ledger.txMap_->snapShot (isMutable))
|
||||
, stateMap_ (ledger.stateMap_->snapShot (isMutable))
|
||||
, fees_ (ledger.fees_)
|
||||
, info_ (ledger.info_)
|
||||
{
|
||||
updateHash ();
|
||||
}
|
||||
|
||||
// Create a new open ledger that follows this one
|
||||
Ledger::Ledger (open_ledger_t, Ledger const& prevLedger,
|
||||
// Create a new ledger that follows this one
|
||||
Ledger::Ledger (Ledger const& prevLedger,
|
||||
NetClock::time_point closeTime)
|
||||
: mImmutable (false)
|
||||
, txMap_ (std::make_shared <SHAMap> (SHAMapType::TRANSACTION,
|
||||
@@ -273,14 +262,13 @@ Ledger::Ledger (open_ledger_t, Ledger const& prevLedger,
|
||||
, fees_(prevLedger.fees_)
|
||||
, rules_(prevLedger.rules_)
|
||||
{
|
||||
info_.open = true;
|
||||
info_.seq = prevLedger.info_.seq + 1;
|
||||
info_.parentCloseTime =
|
||||
prevLedger.info_.closeTime;
|
||||
info_.hash = prevLedger.info().hash + uint256(1);
|
||||
info_.drops = prevLedger.info().drops;
|
||||
info_.closeTimeResolution = prevLedger.info_.closeTimeResolution;
|
||||
info_.parentHash = prevLedger.getHash ();
|
||||
info_.parentHash = prevLedger.info().hash;
|
||||
info_.closeTimeResolution = getNextLedgerTimeResolution(
|
||||
prevLedger.info_.closeTimeResolution,
|
||||
getCloseAgree(prevLedger.info()), info_.seq);
|
||||
@@ -374,39 +362,13 @@ void Ledger::updateHash()
|
||||
mValidHash = true;
|
||||
}
|
||||
|
||||
void Ledger::setRaw (SerialIter& sit, bool hasPrefix, Family& family)
|
||||
{
|
||||
if (hasPrefix)
|
||||
sit.get32 ();
|
||||
|
||||
info_.seq = sit.get32 ();
|
||||
info_.drops = sit.get64 ();
|
||||
info_.parentHash = sit.get256 ();
|
||||
info_.txHash = sit.get256 ();
|
||||
info_.accountHash = sit.get256 ();
|
||||
info_.parentCloseTime = NetClock::time_point{NetClock::duration{sit.get32()}};
|
||||
info_.closeTime = NetClock::time_point{NetClock::duration{sit.get32()}};
|
||||
info_.closeTimeResolution = NetClock::duration{sit.get8()};
|
||||
info_.closeFlags = sit.get8 ();
|
||||
updateHash ();
|
||||
txMap_ = std::make_shared<SHAMap> (SHAMapType::TRANSACTION, info_.txHash,
|
||||
family);
|
||||
stateMap_ = std::make_shared<SHAMap> (SHAMapType::STATE, info_.accountHash,
|
||||
family);
|
||||
}
|
||||
|
||||
void Ledger::addRaw (Serializer& s) const
|
||||
{
|
||||
ripple::addRaw(info_, s);
|
||||
}
|
||||
|
||||
void
|
||||
Ledger::setAccepted(NetClock::time_point closeTime,
|
||||
NetClock::duration closeResolution,
|
||||
bool correctCloseTime, Config const& config)
|
||||
{
|
||||
// Used when we witnessed the consensus.
|
||||
assert (closed());
|
||||
assert (!open());
|
||||
|
||||
info_.closeTime = closeTime;
|
||||
info_.closeTimeResolution = closeResolution;
|
||||
@@ -453,7 +415,7 @@ deserializeTxPlusMeta (SHAMapItem const& item)
|
||||
return result;
|
||||
}
|
||||
|
||||
void Ledger::setAcquiring (void)
|
||||
void Ledger::setAcquiring ()
|
||||
{
|
||||
if (!txMap_ || !stateMap_)
|
||||
Throw<std::runtime_error> ("invalid map");
|
||||
@@ -462,21 +424,6 @@ void Ledger::setAcquiring (void)
|
||||
stateMap_->setSynching ();
|
||||
}
|
||||
|
||||
bool Ledger::isAcquiring (void) const
|
||||
{
|
||||
return isAcquiringTx () || isAcquiringAS ();
|
||||
}
|
||||
|
||||
bool Ledger::isAcquiringTx (void) const
|
||||
{
|
||||
return txMap_->isSynching ();
|
||||
}
|
||||
|
||||
bool Ledger::isAcquiringAS (void) const
|
||||
{
|
||||
return stateMap_->isSynching ();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
bool
|
||||
@@ -555,18 +502,16 @@ auto
|
||||
Ledger::txsBegin() const ->
|
||||
std::unique_ptr<txs_type::iter_base>
|
||||
{
|
||||
return std::make_unique<
|
||||
txs_iter_impl>(closed(),
|
||||
txMap_->begin(), *this);
|
||||
return std::make_unique<txs_iter_impl>(
|
||||
!open(), txMap_->begin(), *this);
|
||||
}
|
||||
|
||||
auto
|
||||
Ledger::txsEnd() const ->
|
||||
std::unique_ptr<txs_type::iter_base>
|
||||
{
|
||||
return std::make_unique<
|
||||
txs_iter_impl>(closed(),
|
||||
txMap_->end(), *this);
|
||||
return std::make_unique<txs_iter_impl>(
|
||||
!open(), txMap_->end(), *this);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -584,7 +529,7 @@ Ledger::txRead(
|
||||
txMap_->peekItem(key);
|
||||
if (! item)
|
||||
return {};
|
||||
if (closed())
|
||||
if (!open())
|
||||
{
|
||||
auto result =
|
||||
deserializeTxPlusMeta(*item);
|
||||
@@ -649,30 +594,18 @@ Ledger::rawTxInsert (uint256 const& key,
|
||||
> const& txn, std::shared_ptr<
|
||||
Serializer const> const& metaData)
|
||||
{
|
||||
assert (static_cast<bool>(metaData) != info_.open);
|
||||
assert (metaData);
|
||||
|
||||
if (metaData)
|
||||
{
|
||||
// low-level - just add to table
|
||||
Serializer s(txn->getDataLength () +
|
||||
metaData->getDataLength () + 16);
|
||||
s.addVL (txn->peekData ());
|
||||
s.addVL (metaData->peekData ());
|
||||
auto item = std::make_shared<
|
||||
SHAMapItem const> (key, std::move(s));
|
||||
if (! txMap().addGiveItem
|
||||
(std::move(item), true, true))
|
||||
LogicError("duplicate_tx: " + to_string(key));
|
||||
}
|
||||
else
|
||||
{
|
||||
// low-level - just add to table
|
||||
auto item = std::make_shared<
|
||||
SHAMapItem const>(key, txn->peekData());
|
||||
if (! txMap().addGiveItem(
|
||||
std::move(item), true, false))
|
||||
LogicError("duplicate_tx: " + to_string(key));
|
||||
}
|
||||
// low-level - just add to table
|
||||
Serializer s(txn->getDataLength () +
|
||||
metaData->getDataLength () + 16);
|
||||
s.addVL (txn->peekData ());
|
||||
s.addVL (metaData->peekData ());
|
||||
auto item = std::make_shared<
|
||||
SHAMapItem const> (key, std::move(s));
|
||||
if (! txMap().addGiveItem
|
||||
(std::move(item), true, true))
|
||||
LogicError("duplicate_tx: " + to_string(key));
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -910,8 +843,31 @@ void Ledger::updateSkipList ()
|
||||
rawReplace(sle);
|
||||
}
|
||||
|
||||
void Ledger::setRaw (SerialIter& sit, bool hasPrefix, Family& family)
|
||||
{
|
||||
if (hasPrefix)
|
||||
sit.get32 ();
|
||||
|
||||
info_.seq = sit.get32 ();
|
||||
info_.drops = sit.get64 ();
|
||||
info_.parentHash = sit.get256 ();
|
||||
info_.txHash = sit.get256 ();
|
||||
info_.accountHash = sit.get256 ();
|
||||
info_.parentCloseTime = NetClock::time_point{NetClock::duration{sit.get32()}};
|
||||
info_.closeTime = NetClock::time_point{NetClock::duration{sit.get32()}};
|
||||
info_.closeTimeResolution = NetClock::duration{sit.get8()};
|
||||
info_.closeFlags = sit.get8 ();
|
||||
updateHash ();
|
||||
txMap_ = std::make_shared<SHAMap> (SHAMapType::TRANSACTION, info_.txHash,
|
||||
family);
|
||||
stateMap_ = std::make_shared<SHAMap> (SHAMapType::STATE, info_.accountHash,
|
||||
family);
|
||||
}
|
||||
|
||||
static bool saveValidatedLedger (
|
||||
Application& app, std::shared_ptr<Ledger> const& ledger, bool current)
|
||||
Application& app,
|
||||
std::shared_ptr<Ledger const> const& ledger,
|
||||
bool current)
|
||||
{
|
||||
auto j = app.journal ("Ledger");
|
||||
|
||||
@@ -969,7 +925,7 @@ static bool saveValidatedLedger (
|
||||
{
|
||||
Serializer s (128);
|
||||
s.add32 (HashPrefix::ledgerMaster);
|
||||
ledger->addRaw (s);
|
||||
addRaw(ledger->info(), s);
|
||||
app.getNodeStore ().store (
|
||||
hotLEDGER, std::move (s.modData ()), ledger->info().hash);
|
||||
}
|
||||
@@ -1099,8 +1055,11 @@ static bool saveValidatedLedger (
|
||||
/** Save, or arrange to save, a fully-validated ledger
|
||||
Returns false on error
|
||||
*/
|
||||
bool pendSaveValidated (Application& app,
|
||||
std::shared_ptr<Ledger> const& ledger, bool isSynchronous, bool isCurrent)
|
||||
bool pendSaveValidated (
|
||||
Application& app,
|
||||
std::shared_ptr<Ledger const> const& ledger,
|
||||
bool isSynchronous,
|
||||
bool isCurrent)
|
||||
{
|
||||
if (! app.getHashRouter ().setFlags (ledger->info().hash, SF_SAVED))
|
||||
{
|
||||
@@ -1221,10 +1180,9 @@ Ledger::getNeededAccountStateHashes (
|
||||
* (typically a where clause).
|
||||
* @return The ledger, ledger sequence, and ledger hash.
|
||||
*/
|
||||
std::tuple<Ledger::pointer, std::uint32_t, uint256>
|
||||
std::tuple<std::shared_ptr<Ledger>, std::uint32_t, uint256>
|
||||
loadLedgerHelper(std::string const& sqlSuffix, Application& app)
|
||||
{
|
||||
Ledger::pointer ledger;
|
||||
uint256 ledgerHash{};
|
||||
std::uint32_t ledgerSeq{0};
|
||||
|
||||
@@ -1258,7 +1216,10 @@ loadLedgerHelper(std::string const& sqlSuffix, Application& app)
|
||||
if (!db->got_data ())
|
||||
{
|
||||
JLOG (app.journal("Ledger").debug) << "Ledger not found: " << sqlSuffix;
|
||||
return std::make_tuple (Ledger::pointer (), ledgerSeq, ledgerHash);
|
||||
return std::make_tuple (
|
||||
std::shared_ptr<Ledger>(),
|
||||
ledgerSeq,
|
||||
ledgerHash);
|
||||
}
|
||||
|
||||
ledgerSeq =
|
||||
@@ -1277,45 +1238,49 @@ loadLedgerHelper(std::string const& sqlSuffix, Application& app)
|
||||
using time_point = NetClock::time_point;
|
||||
using duration = NetClock::duration;
|
||||
bool loaded = false;
|
||||
ledger = std::make_shared<Ledger>(prevHash,
|
||||
transHash,
|
||||
accountHash,
|
||||
totDrops.value_or(0),
|
||||
time_point{duration{closingTime.value_or(0)}},
|
||||
time_point{duration{prevClosingTime.value_or(0)}},
|
||||
closeFlags.value_or(0),
|
||||
duration{closeResolution.value_or(0)},
|
||||
ledgerSeq,
|
||||
loaded,
|
||||
app.config(),
|
||||
app.family(),
|
||||
app.journal("Ledger"));
|
||||
|
||||
auto ledger = std::make_shared<Ledger>(
|
||||
prevHash,
|
||||
transHash,
|
||||
accountHash,
|
||||
totDrops.value_or(0),
|
||||
time_point{duration{closingTime.value_or(0)}},
|
||||
time_point{duration{prevClosingTime.value_or(0)}},
|
||||
closeFlags.value_or(0),
|
||||
duration{closeResolution.value_or(0)},
|
||||
ledgerSeq,
|
||||
loaded,
|
||||
app.config(),
|
||||
app.family(),
|
||||
app.journal("Ledger"));
|
||||
|
||||
if (!loaded)
|
||||
return std::make_tuple (Ledger::pointer (), ledgerSeq, ledgerHash);
|
||||
ledger.reset();
|
||||
|
||||
return std::make_tuple (ledger, ledgerSeq, ledgerHash);
|
||||
}
|
||||
|
||||
static
|
||||
void finishLoadByIndexOrHash(Ledger::pointer& ledger, Config const& config, beast::Journal j)
|
||||
void finishLoadByIndexOrHash(
|
||||
std::shared_ptr<Ledger> const& ledger,
|
||||
Config const& config,
|
||||
beast::Journal j)
|
||||
{
|
||||
if (!ledger)
|
||||
return;
|
||||
|
||||
ledger->setClosed ();
|
||||
ledger->setImmutable (config);
|
||||
|
||||
JLOG (j.trace)
|
||||
<< "Loaded ledger: " << to_string (ledger->getHash ());
|
||||
<< "Loaded ledger: " << to_string (ledger->info().hash);
|
||||
|
||||
ledger->setFull ();
|
||||
}
|
||||
|
||||
Ledger::pointer
|
||||
std::shared_ptr<Ledger>
|
||||
loadByIndex (std::uint32_t ledgerIndex, Application& app)
|
||||
{
|
||||
Ledger::pointer ledger;
|
||||
std::shared_ptr<Ledger> ledger;
|
||||
{
|
||||
std::ostringstream s;
|
||||
s << "WHERE LedgerSeq = " << ledgerIndex;
|
||||
@@ -1323,14 +1288,15 @@ loadByIndex (std::uint32_t ledgerIndex, Application& app)
|
||||
loadLedgerHelper (s.str (), app);
|
||||
}
|
||||
|
||||
finishLoadByIndexOrHash (ledger, app.config(), app.journal ("Ledger"));
|
||||
finishLoadByIndexOrHash (ledger, app.config(),
|
||||
app.journal ("Ledger"));
|
||||
return ledger;
|
||||
}
|
||||
|
||||
Ledger::pointer
|
||||
std::shared_ptr<Ledger>
|
||||
loadByHash (uint256 const& ledgerHash, Application& app)
|
||||
{
|
||||
Ledger::pointer ledger;
|
||||
std::shared_ptr<Ledger> ledger;
|
||||
{
|
||||
std::ostringstream s;
|
||||
s << "WHERE LedgerHash = '" << ledgerHash << "'";
|
||||
@@ -1338,9 +1304,10 @@ loadByHash (uint256 const& ledgerHash, Application& app)
|
||||
loadLedgerHelper (s.str (), app);
|
||||
}
|
||||
|
||||
finishLoadByIndexOrHash (ledger, app.config(), app.journal ("Ledger"));
|
||||
finishLoadByIndexOrHash (ledger, app.config(),
|
||||
app.journal ("Ledger"));
|
||||
|
||||
assert (!ledger || ledger->getHash () == ledgerHash);
|
||||
assert (!ledger || ledger->info().hash == ledgerHash);
|
||||
|
||||
return ledger;
|
||||
}
|
||||
|
||||
@@ -80,9 +80,6 @@ class Ledger final
|
||||
public:
|
||||
static char const* getCountedObjectName () { return "Ledger"; }
|
||||
|
||||
using pointer = std::shared_ptr<Ledger>;
|
||||
using ref = const std::shared_ptr<Ledger>&;
|
||||
|
||||
Ledger (Ledger const&) = delete;
|
||||
Ledger& operator= (Ledger const&) = delete;
|
||||
|
||||
@@ -110,16 +107,13 @@ public:
|
||||
Family& family,
|
||||
beast::Journal j);
|
||||
|
||||
// Create a new ledger that's a snapshot of this one
|
||||
Ledger (Ledger const& target, bool isMutable);
|
||||
|
||||
/** Create a new open ledger
|
||||
/** Create a new ledger following a previous ledger
|
||||
|
||||
The ledger will have the sequence number that
|
||||
follows previous, and have
|
||||
parentCloseTime == previous.closeTime.
|
||||
*/
|
||||
Ledger (open_ledger_t, Ledger const& previous,
|
||||
Ledger (Ledger const& previous,
|
||||
NetClock::time_point closeTime);
|
||||
|
||||
Ledger (void const* data,
|
||||
@@ -137,6 +131,12 @@ public:
|
||||
// ReadView
|
||||
//
|
||||
|
||||
bool
|
||||
open() const override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
LedgerInfo const&
|
||||
info() const override
|
||||
{
|
||||
@@ -227,12 +227,7 @@ public:
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void setClosed()
|
||||
{
|
||||
info_.open = false;
|
||||
}
|
||||
|
||||
void setValidated()
|
||||
void setValidated() const
|
||||
{
|
||||
info_.validated = true;
|
||||
}
|
||||
@@ -248,27 +243,23 @@ public:
|
||||
return mImmutable;
|
||||
}
|
||||
|
||||
// Indicates that all ledger entries
|
||||
// are available locally. For example,
|
||||
// all in the NodeStore and memory.
|
||||
void setFull ()
|
||||
/* 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_->setLedgerSeq (info_.seq);
|
||||
stateMap_->setLedgerSeq (info_.seq);
|
||||
}
|
||||
|
||||
// ledger signature operations
|
||||
void addRaw (Serializer& s) const;
|
||||
void setRaw (SerialIter& sit, bool hasPrefix, Family& family);
|
||||
|
||||
// DEPRECATED
|
||||
// Remove contract.h include
|
||||
uint256 const&
|
||||
getHash() const
|
||||
{
|
||||
return info_.hash;
|
||||
}
|
||||
|
||||
void setTotalDrops (std::uint64_t totDrops)
|
||||
{
|
||||
info_.drops = totDrops;
|
||||
@@ -302,10 +293,7 @@ public:
|
||||
bool addSLE (SLE const& sle);
|
||||
|
||||
// ledger sync functions
|
||||
void setAcquiring (void);
|
||||
bool isAcquiring (void) const;
|
||||
bool isAcquiringTx (void) const;
|
||||
bool isAcquiringAS (void) const;
|
||||
void setAcquiring ();
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
@@ -328,7 +316,7 @@ private:
|
||||
class sles_iter_impl;
|
||||
class txs_iter_impl;
|
||||
|
||||
bool saveValidatedLedger (bool current);
|
||||
void setRaw (SerialIter& sit, bool hasPrefix, Family& family);
|
||||
|
||||
bool
|
||||
setup (Config const& config);
|
||||
@@ -339,8 +327,6 @@ private:
|
||||
void
|
||||
updateHash();
|
||||
|
||||
// The basic Ledger structure, can be opened, closed, or synching
|
||||
|
||||
bool mValidHash = false;
|
||||
bool mImmutable;
|
||||
|
||||
@@ -368,22 +354,22 @@ extern
|
||||
bool
|
||||
pendSaveValidated(
|
||||
Application& app,
|
||||
std::shared_ptr<Ledger> const& ledger,
|
||||
std::shared_ptr<Ledger const> const& ledger,
|
||||
bool isSynchronous,
|
||||
bool isCurrent);
|
||||
|
||||
extern
|
||||
Ledger::pointer
|
||||
std::shared_ptr<Ledger>
|
||||
loadByIndex (std::uint32_t ledgerIndex,
|
||||
Application& app);
|
||||
|
||||
extern
|
||||
std::tuple<Ledger::pointer, std::uint32_t, uint256>
|
||||
std::tuple<std::shared_ptr<Ledger>, std::uint32_t, uint256>
|
||||
loadLedgerHelper(std::string const& sqlSuffix,
|
||||
Application& app);
|
||||
|
||||
extern
|
||||
Ledger::pointer
|
||||
std::shared_ptr<Ledger>
|
||||
loadByHash (uint256 const& ledgerHash, Application& app);
|
||||
|
||||
extern
|
||||
|
||||
@@ -56,7 +56,7 @@ public:
|
||||
|
||||
virtual void startRound (
|
||||
LedgerHash const& prevLCLHash,
|
||||
Ledger::ref prevLedger,
|
||||
std::shared_ptr<Ledger const> const& prevLedger,
|
||||
NetClock::time_point closeTime,
|
||||
int previousProposers,
|
||||
std::chrono::milliseconds previousConvergeTime) = 0;
|
||||
@@ -90,7 +90,7 @@ void applyTransactions (
|
||||
Application& app,
|
||||
SHAMap const* set,
|
||||
OpenView& view,
|
||||
Ledger::ref checkLedger,
|
||||
ReadView const& checkLedger,
|
||||
CanonicalTXSet& retriableTransactions,
|
||||
ApplyFlags flags);
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <ripple/app/ledger/LedgerToJson.h>
|
||||
#include <ripple/basics/Log.h>
|
||||
#include <ripple/basics/chrono.h>
|
||||
#include <ripple/basics/contract.h>
|
||||
#include <ripple/json/to_string.h>
|
||||
|
||||
namespace ripple {
|
||||
@@ -52,17 +53,22 @@ LedgerHistory::LedgerHistory (
|
||||
{
|
||||
}
|
||||
|
||||
bool LedgerHistory::addLedger (Ledger::pointer ledger, bool validated)
|
||||
bool
|
||||
LedgerHistory::insert(
|
||||
std::shared_ptr<Ledger const> ledger,
|
||||
bool validated)
|
||||
{
|
||||
assert (ledger && ledger->isImmutable ());
|
||||
if(! ledger->isImmutable())
|
||||
LogicError("mutable Ledger in insert");
|
||||
|
||||
assert (ledger->stateMap().getHash ().isNonZero ());
|
||||
|
||||
LedgersByHash::ScopedLockType sl (m_ledgers_by_hash.peekMutex ());
|
||||
|
||||
const bool alreadyHad = m_ledgers_by_hash.canonicalize (
|
||||
ledger->getHash(), ledger, true);
|
||||
ledger->info().hash, ledger, true);
|
||||
if (validated)
|
||||
mLedgersByIndex[ledger->info().seq] = ledger->getHash();
|
||||
mLedgersByIndex[ledger->info().seq] = ledger->info().hash;
|
||||
|
||||
return alreadyHad;
|
||||
}
|
||||
@@ -78,7 +84,8 @@ LedgerHash LedgerHistory::getLedgerHash (LedgerIndex index)
|
||||
return uint256 ();
|
||||
}
|
||||
|
||||
Ledger::pointer LedgerHistory::getLedgerBySeq (LedgerIndex index)
|
||||
std::shared_ptr<Ledger const>
|
||||
LedgerHistory::getLedgerBySeq (LedgerIndex index)
|
||||
{
|
||||
{
|
||||
LedgersByHash::ScopedLockType sl (m_ledgers_by_hash.peekMutex ());
|
||||
@@ -92,7 +99,7 @@ Ledger::pointer LedgerHistory::getLedgerBySeq (LedgerIndex index)
|
||||
}
|
||||
}
|
||||
|
||||
Ledger::pointer ret = loadByIndex (index, app_);
|
||||
std::shared_ptr<Ledger const> ret = loadByIndex (index, app_);
|
||||
|
||||
if (!ret)
|
||||
return ret;
|
||||
@@ -104,20 +111,21 @@ Ledger::pointer LedgerHistory::getLedgerBySeq (LedgerIndex index)
|
||||
LedgersByHash::ScopedLockType sl (m_ledgers_by_hash.peekMutex ());
|
||||
|
||||
assert (ret->isImmutable ());
|
||||
m_ledgers_by_hash.canonicalize (ret->getHash (), ret);
|
||||
mLedgersByIndex[ret->info().seq] = ret->getHash ();
|
||||
return (ret->info().seq == index) ? ret : Ledger::pointer ();
|
||||
m_ledgers_by_hash.canonicalize (ret->info().hash, ret);
|
||||
mLedgersByIndex[ret->info().seq] = ret->info().hash;
|
||||
return (ret->info().seq == index) ? ret : nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
Ledger::pointer LedgerHistory::getLedgerByHash (LedgerHash const& hash)
|
||||
std::shared_ptr<Ledger const>
|
||||
LedgerHistory::getLedgerByHash (LedgerHash const& hash)
|
||||
{
|
||||
Ledger::pointer ret = m_ledgers_by_hash.fetch (hash);
|
||||
auto ret = m_ledgers_by_hash.fetch (hash);
|
||||
|
||||
if (ret)
|
||||
{
|
||||
assert (ret->isImmutable ());
|
||||
assert (ret->getHash () == hash);
|
||||
assert (ret->info().hash == hash);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -127,19 +135,22 @@ Ledger::pointer LedgerHistory::getLedgerByHash (LedgerHash const& hash)
|
||||
return ret;
|
||||
|
||||
assert (ret->isImmutable ());
|
||||
assert (ret->getHash () == hash);
|
||||
m_ledgers_by_hash.canonicalize (ret->getHash (), ret);
|
||||
assert (ret->getHash () == hash);
|
||||
assert (ret->info().hash == hash);
|
||||
m_ledgers_by_hash.canonicalize (ret->info().hash, ret);
|
||||
assert (ret->info().hash == hash);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
log_one(Ledger::pointer ledger, uint256 const& tx, char const* msg,
|
||||
log_one(
|
||||
ReadView const& ledger,
|
||||
uint256 const& tx,
|
||||
char const* msg,
|
||||
beast::Journal& j)
|
||||
{
|
||||
auto metaData = ledger->txRead(tx).second;
|
||||
auto metaData = ledger.txRead(tx).second;
|
||||
|
||||
if (metaData != nullptr)
|
||||
{
|
||||
@@ -157,10 +168,12 @@ log_one(Ledger::pointer ledger, uint256 const& tx, char const* msg,
|
||||
static
|
||||
void
|
||||
log_metadata_difference(
|
||||
Ledger::pointer builtLedger, Ledger::pointer validLedger, uint256 const& tx,
|
||||
ReadView const& builtLedger,
|
||||
ReadView const& validLedger,
|
||||
uint256 const& tx,
|
||||
beast::Journal j)
|
||||
{
|
||||
auto getMeta = [j](Ledger const& ledger,
|
||||
auto getMeta = [j](ReadView const& ledger,
|
||||
uint256 const& txID) -> std::shared_ptr<TxMeta>
|
||||
{
|
||||
auto meta = ledger.txRead(txID).second;
|
||||
@@ -169,8 +182,8 @@ log_metadata_difference(
|
||||
return std::make_shared<TxMeta> (txID, ledger.seq(), *meta, j);
|
||||
};
|
||||
|
||||
auto validMetaData = getMeta (*validLedger, tx);
|
||||
auto builtMetaData = getMeta (*builtLedger, tx);
|
||||
auto validMetaData = getMeta (validLedger, tx);
|
||||
auto builtMetaData = getMeta (builtLedger, tx);
|
||||
assert(validMetaData != nullptr || builtMetaData != nullptr);
|
||||
|
||||
if (validMetaData != nullptr && builtMetaData != nullptr)
|
||||
@@ -299,15 +312,16 @@ leaves (SHAMap const& sm)
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
void LedgerHistory::handleMismatch (
|
||||
LedgerHash const& built, LedgerHash const& valid, Json::Value const& consensus)
|
||||
LedgerHash const& built,
|
||||
LedgerHash const& valid,
|
||||
Json::Value const& consensus)
|
||||
{
|
||||
assert (built != valid);
|
||||
++mismatch_counter_;
|
||||
|
||||
Ledger::pointer builtLedger = getLedgerByHash (built);
|
||||
Ledger::pointer validLedger = getLedgerByHash (valid);
|
||||
auto builtLedger = getLedgerByHash (built);
|
||||
auto validLedger = getLedgerByHash (valid);
|
||||
|
||||
if (!builtLedger || !validLedger)
|
||||
{
|
||||
@@ -326,19 +340,19 @@ void LedgerHistory::handleMismatch (
|
||||
j_.debug << "Consensus: " << consensus;
|
||||
}
|
||||
|
||||
// Determine the mismatch reason
|
||||
// Distinguish Byzantine failure from transaction processing difference
|
||||
// Determine the mismatch reason, distinguishing Byzantine
|
||||
// failure from transaction processing difference
|
||||
|
||||
// Disagreement over prior ledger indicates sync issue
|
||||
if (builtLedger->info().parentHash != validLedger->info().parentHash)
|
||||
{
|
||||
// Disagreement over prior ledger indicates sync issue
|
||||
JLOG (j_.error) << "MISMATCH on prior ledger";
|
||||
return;
|
||||
}
|
||||
|
||||
// Disagreement over close time indicates Byzantine failure
|
||||
if (builtLedger->info().closeTime != validLedger->info().closeTime)
|
||||
{
|
||||
// Disagreement over close time indicates Byzantine failure
|
||||
JLOG (j_.error) << "MISMATCH on close time";
|
||||
return;
|
||||
}
|
||||
@@ -346,18 +360,18 @@ void LedgerHistory::handleMismatch (
|
||||
// Find differences between built and valid ledgers
|
||||
auto const builtTx = leaves(builtLedger->txMap());
|
||||
auto const validTx = leaves(validLedger->txMap());
|
||||
|
||||
if (builtTx == validTx)
|
||||
JLOG (j_.error) <<
|
||||
"MISMATCH with same " << builtTx.size() << " transactions";
|
||||
"MISMATCH with same " << builtTx.size() <<
|
||||
" transactions";
|
||||
else
|
||||
JLOG (j_.error) << "MISMATCH with " <<
|
||||
builtTx.size() << " built and " <<
|
||||
validTx.size() << " valid transactions.";
|
||||
|
||||
JLOG (j_.error) << "built\n" <<
|
||||
getJson(*builtLedger);
|
||||
JLOG (j_.error) << "valid\n" <<
|
||||
getJson(*validLedger);
|
||||
JLOG (j_.error) << "built\n" << getJson(*builtLedger);
|
||||
JLOG (j_.error) << "valid\n" << getJson(*validLedger);
|
||||
|
||||
// Log all differences between built and valid ledgers
|
||||
auto b = builtTx.begin();
|
||||
@@ -366,12 +380,12 @@ void LedgerHistory::handleMismatch (
|
||||
{
|
||||
if ((*b)->key() < (*v)->key())
|
||||
{
|
||||
log_one (builtLedger, (*b)->key(), "valid", j_);
|
||||
log_one (*builtLedger, (*b)->key(), "valid", j_);
|
||||
++b;
|
||||
}
|
||||
else if ((*b)->key() > (*v)->key())
|
||||
{
|
||||
log_one(validLedger, (*v)->key(), "built", j_);
|
||||
log_one(*validLedger, (*v)->key(), "built", j_);
|
||||
++v;
|
||||
}
|
||||
else
|
||||
@@ -379,23 +393,28 @@ void LedgerHistory::handleMismatch (
|
||||
if ((*b)->peekData() != (*v)->peekData())
|
||||
{
|
||||
// Same transaction with different metadata
|
||||
log_metadata_difference(builtLedger, validLedger, (*b)->key(), j_);
|
||||
log_metadata_difference(
|
||||
*builtLedger,
|
||||
*validLedger, (*b)->key(), j_);
|
||||
}
|
||||
++b;
|
||||
++v;
|
||||
}
|
||||
}
|
||||
for (; b != builtTx.end(); ++b)
|
||||
log_one (builtLedger, (*b)->key(), "valid", j_);
|
||||
log_one (*builtLedger, (*b)->key(), "valid", j_);
|
||||
for (; v != validTx.end(); ++v)
|
||||
log_one (validLedger, (*v)->key(), "built", j_);
|
||||
log_one (*validLedger, (*v)->key(), "built", j_);
|
||||
}
|
||||
|
||||
void LedgerHistory::builtLedger (Ledger::ref ledger, Json::Value consensus)
|
||||
void LedgerHistory::builtLedger (
|
||||
std::shared_ptr<Ledger const> const& ledger,
|
||||
Json::Value consensus)
|
||||
{
|
||||
LedgerIndex index = ledger->info().seq;
|
||||
LedgerHash hash = ledger->getHash();
|
||||
LedgerHash hash = ledger->info().hash;
|
||||
assert (!hash.isZero());
|
||||
|
||||
ConsensusValidated::ScopedLockType sl (
|
||||
m_consensus_validated.peekMutex());
|
||||
|
||||
@@ -422,11 +441,13 @@ void LedgerHistory::builtLedger (Ledger::ref ledger, Json::Value consensus)
|
||||
entry->consensus.emplace (std::move (consensus));
|
||||
}
|
||||
|
||||
void LedgerHistory::validatedLedger (Ledger::ref ledger)
|
||||
void LedgerHistory::validatedLedger (
|
||||
std::shared_ptr<Ledger const> const& ledger)
|
||||
{
|
||||
LedgerIndex index = ledger->info().seq;
|
||||
LedgerHash hash = ledger->getHash();
|
||||
LedgerHash hash = ledger->info().hash;
|
||||
assert (!hash.isZero());
|
||||
|
||||
ConsensusValidated::ScopedLockType sl (
|
||||
m_consensus_validated.peekMutex());
|
||||
|
||||
|
||||
@@ -40,7 +40,8 @@ public:
|
||||
/** Track a ledger
|
||||
@return `true` if the ledger was already tracked
|
||||
*/
|
||||
bool addLedger (Ledger::pointer ledger, bool validated);
|
||||
bool insert (std::shared_ptr<Ledger const> ledger,
|
||||
bool validated);
|
||||
|
||||
/** Get the ledgers_by_hash cache hit rate
|
||||
@return the hit rate
|
||||
@@ -50,10 +51,13 @@ public:
|
||||
return m_ledgers_by_hash.getHitRate ();
|
||||
}
|
||||
|
||||
/** Get a ledger given its squence number
|
||||
@param ledgerIndex The sequence number of the desired ledger
|
||||
*/
|
||||
Ledger::pointer getLedgerBySeq (LedgerIndex ledgerIndex);
|
||||
/** Get a ledger given its squence number */
|
||||
std::shared_ptr<Ledger const>
|
||||
getLedgerBySeq (LedgerIndex ledgerIndex);
|
||||
|
||||
/** Retrieve a ledger given its hash */
|
||||
std::shared_ptr<Ledger const>
|
||||
getLedgerByHash (LedgerHash const& ledgerHash);
|
||||
|
||||
/** Get a ledger's hash given its sequence number
|
||||
@param ledgerIndex The sequence number of the desired ledger
|
||||
@@ -61,12 +65,6 @@ public:
|
||||
*/
|
||||
LedgerHash getLedgerHash (LedgerIndex ledgerIndex);
|
||||
|
||||
/** Retrieve a ledger given its hash
|
||||
@param ledgerHash The hash of the requested ledger
|
||||
@return The ledger requested
|
||||
*/
|
||||
Ledger::pointer getLedgerByHash (LedgerHash const& ledgerHash);
|
||||
|
||||
/** Set the history cache's paramters
|
||||
@param size The target size of the cache
|
||||
@param age The target age of the cache, in seconds
|
||||
@@ -81,13 +79,14 @@ public:
|
||||
m_consensus_validated.sweep ();
|
||||
}
|
||||
|
||||
/** Report that we have locally built a particular ledger
|
||||
*/
|
||||
void builtLedger (Ledger::ref, Json::Value);
|
||||
/** Report that we have locally built a particular ledger */
|
||||
void builtLedger (
|
||||
std::shared_ptr<Ledger const> const&,
|
||||
Json::Value);
|
||||
|
||||
/** Report that we have validated a particular ledger
|
||||
*/
|
||||
void validatedLedger (Ledger::ref);
|
||||
/** Report that we have validated a particular ledger */
|
||||
void validatedLedger (
|
||||
std::shared_ptr<Ledger const> const&);
|
||||
|
||||
/** Repair a hash to index mapping
|
||||
@param ledgerIndex The index whose mapping is to be repaired
|
||||
@@ -113,7 +112,7 @@ private:
|
||||
beast::insight::Collector::ptr collector_;
|
||||
beast::insight::Counter mismatch_counter_;
|
||||
|
||||
using LedgersByHash = TaggedCache <LedgerHash, Ledger>;
|
||||
using LedgersByHash = TaggedCache <LedgerHash, Ledger const>;
|
||||
|
||||
LedgersByHash m_ledgers_by_hash;
|
||||
|
||||
|
||||
@@ -20,44 +20,42 @@
|
||||
#ifndef RIPPLE_APP_LEDGER_LEDGERHOLDER_H_INCLUDED
|
||||
#define RIPPLE_APP_LEDGER_LEDGERHOLDER_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/contract.h>
|
||||
#include <mutex>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
// Can std::atomic<std::shared_ptr>> make this lock free?
|
||||
|
||||
// VFALCO NOTE This class can be replaced with atomic<shared_ptr<...>>
|
||||
|
||||
/** Hold a ledger in a thread-safe way.
|
||||
|
||||
VFALCO TODO The constructor should require a valid ledger, this
|
||||
way the object always holds a value. We can use the
|
||||
genesis ledger in all cases.
|
||||
*/
|
||||
class LedgerHolder
|
||||
{
|
||||
public:
|
||||
// Update the held ledger
|
||||
void set (Ledger::pointer ledger)
|
||||
void set (std::shared_ptr<Ledger const> ledger)
|
||||
{
|
||||
// The held ledger must always be immutable
|
||||
if (ledger && !ledger->isImmutable ())
|
||||
ledger = std::make_shared <Ledger> (*ledger, false);
|
||||
|
||||
{
|
||||
std::lock_guard <std::mutex> sl (m_lock);
|
||||
m_heldLedger = ledger;
|
||||
}
|
||||
if(! ledger)
|
||||
LogicError("LedgerHolder::set with nullptr");
|
||||
if(! ledger->isImmutable())
|
||||
LogicError("LedgerHolder::set with mutable Ledger");
|
||||
std::lock_guard <std::mutex> sl (m_lock);
|
||||
m_heldLedger = std::move(ledger);
|
||||
}
|
||||
|
||||
// Return the (immutable) held ledger
|
||||
Ledger::pointer get ()
|
||||
std::shared_ptr<Ledger const> get ()
|
||||
{
|
||||
std::lock_guard <std::mutex> sl (m_lock);
|
||||
return m_heldLedger;
|
||||
}
|
||||
|
||||
// Return a mutable snapshot of the held ledger
|
||||
Ledger::pointer getMutable ()
|
||||
{
|
||||
Ledger::pointer ret = get ();
|
||||
return ret ? std::make_shared <Ledger> (*ret, true) : ret;
|
||||
}
|
||||
|
||||
bool empty ()
|
||||
{
|
||||
std::lock_guard <std::mutex> sl (m_lock);
|
||||
@@ -66,7 +64,7 @@ public:
|
||||
|
||||
private:
|
||||
std::mutex m_lock;
|
||||
Ledger::pointer m_heldLedger;
|
||||
std::shared_ptr<Ledger const> m_heldLedger;
|
||||
};
|
||||
|
||||
} // ripple
|
||||
|
||||
@@ -49,7 +49,7 @@ struct LedgerReplay
|
||||
std::map< int, std::shared_ptr<STTx const> > txns_;
|
||||
NetClock::time_point closeTime_;
|
||||
int closeFlags_;
|
||||
Ledger::pointer prevLedger_;
|
||||
std::shared_ptr<Ledger const> prevLedger_;
|
||||
};
|
||||
|
||||
// Tracks the current ledger and any ledgers in the process of closing
|
||||
@@ -69,37 +69,43 @@ public:
|
||||
beast::insight::Collector::ptr const& collector,
|
||||
beast::Journal journal);
|
||||
|
||||
public:
|
||||
using callback = std::function <void (Ledger::ref)>;
|
||||
|
||||
public:
|
||||
virtual ~LedgerMaster () = default;
|
||||
|
||||
LedgerIndex getCurrentLedgerIndex ();
|
||||
LedgerIndex getValidLedgerIndex ();
|
||||
|
||||
bool isCompatible (Ledger::pointer,
|
||||
beast::Journal::Stream, const char* reason);
|
||||
bool isCompatible (
|
||||
ReadView const&,
|
||||
beast::Journal::Stream,
|
||||
char const* reason);
|
||||
|
||||
std::recursive_mutex& peekMutex ();
|
||||
|
||||
// The current ledger is the ledger we believe new transactions should go in
|
||||
std::shared_ptr<ReadView const> getCurrentLedger ();
|
||||
std::shared_ptr<ReadView const>
|
||||
getCurrentLedger();
|
||||
|
||||
// The finalized ledger is the last closed/accepted ledger
|
||||
Ledger::pointer getClosedLedger ();
|
||||
std::shared_ptr<Ledger const>
|
||||
getClosedLedger()
|
||||
{
|
||||
return mClosedLedger.get();
|
||||
}
|
||||
|
||||
// The validated ledger is the last fully validated ledger
|
||||
Ledger::pointer getValidatedLedger ();
|
||||
std::shared_ptr<Ledger const>
|
||||
getValidatedLedger ()
|
||||
{
|
||||
return mValidLedger.get();
|
||||
}
|
||||
|
||||
// The Rules are in the last fully validated ledger if there is one.
|
||||
Rules getValidatedRules();
|
||||
|
||||
// This is the last ledger we published to clients and can lag the validated
|
||||
// ledger
|
||||
Ledger::pointer getPublishedLedger ();
|
||||
|
||||
bool isValidLedger(LedgerInfo const&);
|
||||
std::shared_ptr<ReadView const>
|
||||
getPublishedLedger();
|
||||
|
||||
std::chrono::seconds getPublishedLedgerAge ();
|
||||
std::chrono::seconds getValidatedLedgerAge ();
|
||||
@@ -111,13 +117,13 @@ public:
|
||||
|
||||
std::uint32_t getEarliestFetch ();
|
||||
|
||||
bool storeLedger (Ledger::pointer);
|
||||
void forceValid (Ledger::pointer);
|
||||
bool storeLedger (std::shared_ptr<Ledger const> ledger);
|
||||
|
||||
void setFullLedger (
|
||||
Ledger::pointer ledger, bool isSynchronous, bool isCurrent);
|
||||
std::shared_ptr<Ledger const> const& ledger,
|
||||
bool isSynchronous, bool isCurrent);
|
||||
|
||||
void switchLCL (Ledger::pointer lastClosed);
|
||||
void switchLCL (std::shared_ptr<Ledger const> const& lastClosed);
|
||||
|
||||
void failedSave(std::uint32_t seq, uint256 const& hash);
|
||||
|
||||
@@ -144,9 +150,9 @@ public:
|
||||
*/
|
||||
uint256 getHashBySeq (std::uint32_t index);
|
||||
|
||||
/** Walk to a ledger's hash using the skip list
|
||||
*/
|
||||
/** Walk to a ledger's hash using the skip list */
|
||||
boost::optional<LedgerHash> walkHashBySeq (std::uint32_t index);
|
||||
|
||||
/** Walk the chain of ledger hashes to determine the hash of the
|
||||
ledger with the specified index. The referenceLedger is used as
|
||||
the base of the chain and should be fully validated and must not
|
||||
@@ -155,17 +161,21 @@ public:
|
||||
in the node store.
|
||||
*/
|
||||
boost::optional<LedgerHash> walkHashBySeq (
|
||||
std::uint32_t index, Ledger::ref referenceLedger);
|
||||
std::uint32_t index,
|
||||
std::shared_ptr<ReadView const> const& referenceLedger);
|
||||
|
||||
Ledger::pointer getLedgerBySeq (std::uint32_t index);
|
||||
std::shared_ptr<Ledger const>
|
||||
getLedgerBySeq (std::uint32_t index);
|
||||
|
||||
Ledger::pointer getLedgerByHash (uint256 const& hash);
|
||||
std::shared_ptr<Ledger const>
|
||||
getLedgerByHash (uint256 const& hash);
|
||||
|
||||
void setLedgerRangePresent (
|
||||
std::uint32_t minV, std::uint32_t maxV);
|
||||
|
||||
boost::optional<LedgerHash> getLedgerHash(
|
||||
std::uint32_t desiredSeq, Ledger::ref knownGoodLedger);
|
||||
std::uint32_t desiredSeq,
|
||||
std::shared_ptr<ReadView const> const& knownGoodLedger);
|
||||
|
||||
boost::optional <NetClock::time_point> getCloseTimeBySeq (
|
||||
LedgerIndex ledgerIndex);
|
||||
@@ -174,7 +184,7 @@ public:
|
||||
LedgerHash const& ledgerHash);
|
||||
|
||||
void addHeldTransaction (std::shared_ptr<Transaction> const& trans);
|
||||
void fixMismatch (Ledger::ref ledger);
|
||||
void fixMismatch (ReadView const& ledger);
|
||||
|
||||
bool haveLedger (std::uint32_t seq);
|
||||
void clearLedger (std::uint32_t seq);
|
||||
@@ -187,9 +197,9 @@ public:
|
||||
void sweep ();
|
||||
float getCacheHitRate ();
|
||||
|
||||
void checkAccept (Ledger::ref ledger);
|
||||
void checkAccept (std::shared_ptr<Ledger const> const& ledger);
|
||||
void checkAccept (uint256 const& hash, std::uint32_t seq);
|
||||
void consensusBuilt (Ledger::ref ledger, Json::Value consensus);
|
||||
void consensusBuilt (std::shared_ptr<Ledger const> const& ledger, Json::Value consensus);
|
||||
|
||||
LedgerIndex getBuildingLedger ();
|
||||
void setBuildingLedger (LedgerIndex index);
|
||||
@@ -235,9 +245,15 @@ public:
|
||||
std::size_t getFetchPackCacheSize () const;
|
||||
|
||||
private:
|
||||
void setValidLedger(Ledger::ref l);
|
||||
void setPubLedger(Ledger::ref l);
|
||||
void tryFill(Job& job, Ledger::pointer ledger);
|
||||
void setValidLedger(
|
||||
std::shared_ptr<Ledger const> const& l);
|
||||
void setPubLedger(
|
||||
std::shared_ptr<Ledger const> const& l);
|
||||
|
||||
void tryFill(
|
||||
Job& job,
|
||||
std::shared_ptr<Ledger const> ledger);
|
||||
|
||||
void getFetchPack(LedgerHash missingHash, LedgerIndex missingIndex);
|
||||
boost::optional<LedgerHash> getLedgerHashForHistory(LedgerIndex index);
|
||||
int getNeededValidations();
|
||||
@@ -250,7 +266,10 @@ private:
|
||||
std::uint32_t const ledgerHistory,
|
||||
std::uint32_t const ledgerHistoryIndex,
|
||||
std::uint32_t const candidateLedger) const;
|
||||
std::vector<Ledger::pointer> findNewLedgersToPublish();
|
||||
|
||||
std::vector<std::shared_ptr<Ledger const>>
|
||||
findNewLedgersToPublish();
|
||||
|
||||
void updatePaths(Job& job);
|
||||
void newPFWork(const char *name);
|
||||
|
||||
@@ -270,13 +289,13 @@ private:
|
||||
LedgerHolder mValidLedger;
|
||||
|
||||
// The last ledger we have published.
|
||||
Ledger::pointer mPubLedger;
|
||||
std::shared_ptr<Ledger const> mPubLedger;
|
||||
|
||||
// The last ledger we did pathfinding against.
|
||||
Ledger::pointer mPathLedger;
|
||||
std::shared_ptr<Ledger const> mPathLedger;
|
||||
|
||||
// The last ledger we handled fetching history
|
||||
Ledger::pointer mHistLedger;
|
||||
std::shared_ptr<Ledger const> mHistLedger;
|
||||
|
||||
// Fully validated ledger, whether or not we have the ledger resident.
|
||||
std::pair <uint256, LedgerIndex> mLastValidLedger;
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
#ifndef RIPPLE_APP_LEDGER_LOCALTXS_H_INCLUDED
|
||||
#define RIPPLE_APP_LEDGER_LOCALTXS_H_INCLUDED
|
||||
|
||||
#include <ripple/app/ledger/Ledger.h>
|
||||
#include <ripple/app/misc/CanonicalTXSet.h>
|
||||
#include <ripple/ledger/ReadView.h>
|
||||
#include <memory>
|
||||
|
||||
namespace ripple {
|
||||
@@ -42,7 +42,7 @@ public:
|
||||
virtual CanonicalTXSet getTxSet () = 0;
|
||||
|
||||
// Remove obsolete transactions based on a new fully-valid ledger
|
||||
virtual void sweep (Ledger::ref validLedger) = 0;
|
||||
virtual void sweep (ReadView const& view) = 0;
|
||||
|
||||
virtual std::size_t size () = 0;
|
||||
};
|
||||
|
||||
@@ -78,7 +78,7 @@ void
|
||||
ConsensusImp::startRound (
|
||||
LedgerConsensus& consensus,
|
||||
LedgerHash const &prevLCLHash,
|
||||
Ledger::ref previousLedger,
|
||||
std::shared_ptr<Ledger const> const& previousLedger,
|
||||
NetClock::time_point closeTime)
|
||||
{
|
||||
consensus.startRound (
|
||||
|
||||
@@ -63,7 +63,7 @@ public:
|
||||
startRound (
|
||||
LedgerConsensus& ledgerConsensus,
|
||||
LedgerHash const& prevLCLHash,
|
||||
Ledger::ref previousLedger,
|
||||
std::shared_ptr<Ledger const> const& previousLedger,
|
||||
NetClock::time_point closeTime) override;
|
||||
|
||||
void
|
||||
|
||||
@@ -142,7 +142,6 @@ void InboundLedger::init (ScopedLockType& collectionLock)
|
||||
{
|
||||
JLOG (m_journal.debug) <<
|
||||
"Acquiring ledger we already have locally: " << getHash ();
|
||||
mLedger->setClosed ();
|
||||
mLedger->setImmutable (app_.config());
|
||||
|
||||
if (mReason != fcHISTORY)
|
||||
@@ -192,7 +191,7 @@ bool InboundLedger::tryLocal ()
|
||||
true, app_.config(), app_.family());
|
||||
}
|
||||
|
||||
if (mLedger->getHash () != mHash)
|
||||
if (mLedger->info().hash != mHash)
|
||||
{
|
||||
// We know for a fact the ledger can never be acquired
|
||||
JLOG (m_journal.warning) <<
|
||||
@@ -264,7 +263,6 @@ bool InboundLedger::tryLocal ()
|
||||
JLOG (m_journal.debug) <<
|
||||
"Had everything locally";
|
||||
mComplete = true;
|
||||
mLedger->setClosed ();
|
||||
mLedger->setImmutable (app_.config());
|
||||
}
|
||||
|
||||
@@ -357,7 +355,6 @@ void InboundLedger::done ()
|
||||
|
||||
if (isComplete () && !isFailed () && mLedger)
|
||||
{
|
||||
mLedger->setClosed ();
|
||||
mLedger->setImmutable (app_.config());
|
||||
if (mReason != fcHISTORY)
|
||||
app_.getLedgerMaster ().storeLedger (mLedger);
|
||||
@@ -735,10 +732,10 @@ bool InboundLedger::takeHeader (std::string const& data)
|
||||
data.data(), data.size(), false,
|
||||
app_.config(), app_.family());
|
||||
|
||||
if (mLedger->getHash () != mHash)
|
||||
if (mLedger->info().hash != mHash)
|
||||
{
|
||||
JLOG (m_journal.warning) <<
|
||||
"Acquire hash mismatch: " << mLedger->getHash () <<
|
||||
"Acquire hash mismatch: " << mLedger->info().hash <<
|
||||
"!=" << mHash;
|
||||
mLedger.reset ();
|
||||
return false;
|
||||
|
||||
@@ -64,8 +64,11 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
Ledger::pointer acquire (
|
||||
uint256 const& hash, std::uint32_t seq, InboundLedger::fcReason reason)
|
||||
std::shared_ptr<Ledger>
|
||||
acquire (
|
||||
uint256 const& hash,
|
||||
std::uint32_t seq,
|
||||
InboundLedger::fcReason reason)
|
||||
{
|
||||
assert (hash.isNonZero ());
|
||||
bool isNew = true;
|
||||
|
||||
@@ -269,7 +269,9 @@ private:
|
||||
}
|
||||
|
||||
// VFALCO TODO This should return boost::optional<uint256>
|
||||
LedgerHash getLedgerHash(Ledger::pointer ledger, LedgerIndex index)
|
||||
LedgerHash getLedgerHash(
|
||||
std::shared_ptr<ReadView const>& ledger,
|
||||
LedgerIndex index)
|
||||
{
|
||||
boost::optional<LedgerHash> hash;
|
||||
try
|
||||
@@ -281,7 +283,7 @@ private:
|
||||
JLOG (j_.warning) <<
|
||||
"Node missing from ledger " << ledger->info().seq;
|
||||
app_.getInboundLedgers().acquire (
|
||||
ledger->getHash(), ledger->info().seq,
|
||||
ledger->info().hash, ledger->info().seq,
|
||||
InboundLedger::fcGENERIC);
|
||||
}
|
||||
return hash ? *hash : zero; // kludge
|
||||
@@ -300,9 +302,8 @@ private:
|
||||
bool doNodes,
|
||||
bool doTxns)
|
||||
{
|
||||
Ledger::pointer nodeLedger =
|
||||
app_.getInboundLedgers().acquire (
|
||||
ledgerHash, ledgerIndex, InboundLedger::fcGENERIC);
|
||||
auto nodeLedger = app_.getInboundLedgers().acquire (
|
||||
ledgerHash, ledgerIndex, InboundLedger::fcGENERIC);
|
||||
if (!nodeLedger)
|
||||
{
|
||||
JLOG (j_.debug) << "Ledger " << ledgerIndex << " not available";
|
||||
@@ -312,9 +313,9 @@ private:
|
||||
return false;
|
||||
}
|
||||
|
||||
Ledger::pointer dbLedger = loadByIndex(ledgerIndex, app_);
|
||||
auto dbLedger = loadByIndex(ledgerIndex, app_);
|
||||
if (! dbLedger ||
|
||||
(dbLedger->getHash() != ledgerHash) ||
|
||||
(dbLedger->info().hash != ledgerHash) ||
|
||||
(dbLedger->info().parentHash != nodeLedger->info().parentHash))
|
||||
{
|
||||
// Ideally we'd also check for more than one ledger with that index
|
||||
@@ -355,7 +356,7 @@ private:
|
||||
*/
|
||||
LedgerHash getHash(
|
||||
LedgerIndex const& ledgerIndex,
|
||||
Ledger::pointer& referenceLedger)
|
||||
std::shared_ptr<ReadView const>& referenceLedger)
|
||||
{
|
||||
LedgerHash ledgerHash;
|
||||
|
||||
@@ -411,7 +412,7 @@ private:
|
||||
return shouldExit_;
|
||||
};
|
||||
|
||||
Ledger::pointer goodLedger;
|
||||
std::shared_ptr<ReadView const> goodLedger;
|
||||
|
||||
while (! shouldExit())
|
||||
{
|
||||
|
||||
@@ -569,14 +569,14 @@ void LedgerConsensusImp::checkLCL ()
|
||||
|
||||
handleLCL (netLgr);
|
||||
}
|
||||
else if (mPreviousLedger->getHash () != mPrevLedgerHash)
|
||||
else if (mPreviousLedger->info().hash != mPrevLedgerHash)
|
||||
handleLCL (netLgr);
|
||||
}
|
||||
|
||||
void LedgerConsensusImp::handleLCL (uint256 const& lclHash)
|
||||
{
|
||||
assert (lclHash != mPrevLedgerHash ||
|
||||
mPreviousLedger->getHash () != lclHash);
|
||||
mPreviousLedger->info().hash != lclHash);
|
||||
|
||||
if (mPrevLedgerHash != lclHash)
|
||||
{
|
||||
@@ -601,12 +601,12 @@ void LedgerConsensusImp::handleLCL (uint256 const& lclHash)
|
||||
playbackProposals ();
|
||||
}
|
||||
|
||||
if (mPreviousLedger->getHash () == mPrevLedgerHash)
|
||||
if (mPreviousLedger->info().hash == mPrevLedgerHash)
|
||||
return;
|
||||
|
||||
// we need to switch the ledger we're working from
|
||||
auto newLCL = ledgerMaster_.getLedgerByHash (mPrevLedgerHash);
|
||||
if (!newLCL)
|
||||
auto buildLCL = ledgerMaster_.getLedgerByHash (mPrevLedgerHash);
|
||||
if (! buildLCL)
|
||||
{
|
||||
if (mAcquiringLedger != lclHash)
|
||||
{
|
||||
@@ -631,13 +631,13 @@ void LedgerConsensusImp::handleLCL (uint256 const& lclHash)
|
||||
return;
|
||||
}
|
||||
|
||||
assert (!newLCL->info().open && newLCL->isImmutable ());
|
||||
assert (newLCL->getHash () == lclHash);
|
||||
assert (!buildLCL->open() && buildLCL->isImmutable ());
|
||||
assert (buildLCL->info().hash == lclHash);
|
||||
JLOG (j_.info) <<
|
||||
"Have the consensus ledger " << mPrevLedgerHash;
|
||||
startRound (
|
||||
lclHash,
|
||||
newLCL,
|
||||
buildLCL,
|
||||
mCloseTime,
|
||||
mPreviousProposers,
|
||||
mPreviousMSeconds);
|
||||
@@ -975,80 +975,83 @@ void LedgerConsensusImp::accept (std::shared_ptr<SHAMap> set)
|
||||
// Put transactions into a deterministic, but unpredictable, order
|
||||
CanonicalTXSet retriableTxs (set->getHash ().as_uint256());
|
||||
|
||||
// Build the new last closed ledger
|
||||
auto newLCL = std::make_shared<Ledger>(
|
||||
open_ledger, *mPreviousLedger,
|
||||
app_.timeKeeper().closeTime());
|
||||
newLCL->setClosed (); // so applyTransactions sees a closed ledger
|
||||
|
||||
// Set up to write SHAMap changes to our database,
|
||||
// perform updates, extract changes
|
||||
JLOG (j_.debug)
|
||||
<< "Applying consensus set transactions to the"
|
||||
<< " last closed ledger";
|
||||
|
||||
std::shared_ptr<Ledger const> sharedLCL;
|
||||
{
|
||||
OpenView accum(&*newLCL);
|
||||
assert(accum.closed());
|
||||
if (replay)
|
||||
// Build the new last closed ledger
|
||||
auto buildLCL = std::make_shared<Ledger>(
|
||||
*mPreviousLedger,
|
||||
app_.timeKeeper().closeTime());
|
||||
|
||||
// Set up to write SHAMap changes to our database,
|
||||
// perform updates, extract changes
|
||||
JLOG (j_.debug)
|
||||
<< "Applying consensus set transactions to the"
|
||||
<< " last closed ledger";
|
||||
|
||||
{
|
||||
// Special case, we are replaying a ledger close
|
||||
for (auto& tx : replay->txns_)
|
||||
applyTransaction (app_, accum, tx.second, false, tapNO_CHECK_SIGN, j_);
|
||||
OpenView accum(&*buildLCL);
|
||||
assert(!accum.open());
|
||||
if (replay)
|
||||
{
|
||||
// Special case, we are replaying a ledger close
|
||||
for (auto& tx : replay->txns_)
|
||||
applyTransaction (app_, accum, tx.second, false, tapNO_CHECK_SIGN, j_);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Normal case, we are not replaying a ledger close
|
||||
applyTransactions (app_, set.get(), accum,
|
||||
*buildLCL, retriableTxs, tapNONE);
|
||||
}
|
||||
// Update fee computations.
|
||||
app_.getTxQ().processValidatedLedger(app_, accum,
|
||||
mCurrentMSeconds > 5s);
|
||||
|
||||
accum.apply(*buildLCL);
|
||||
}
|
||||
|
||||
// retriableTxs will include any transactions that
|
||||
// made it into the consensus set but failed during application
|
||||
// to the ledger.
|
||||
|
||||
buildLCL->updateSkipList ();
|
||||
|
||||
{
|
||||
int asf = buildLCL->stateMap().flushDirty (
|
||||
hotACCOUNT_NODE, buildLCL->info().seq);
|
||||
int tmf = buildLCL->txMap().flushDirty (
|
||||
hotTRANSACTION_NODE, buildLCL->info().seq);
|
||||
JLOG (j_.debug) << "Flushed " <<
|
||||
asf << " accounts and " <<
|
||||
tmf << " transaction nodes";
|
||||
}
|
||||
|
||||
// Accept ledger
|
||||
buildLCL->setAccepted(closeTime, mCloseResolution,
|
||||
closeTimeCorrect, app_.config());
|
||||
|
||||
// And stash the ledger in the ledger master
|
||||
if (ledgerMaster_.storeLedger (buildLCL))
|
||||
JLOG (j_.debug)
|
||||
<< "Consensus built ledger we already had";
|
||||
else if (app_.getInboundLedgers().find (buildLCL->info().hash))
|
||||
JLOG (j_.debug)
|
||||
<< "Consensus built ledger we were acquiring";
|
||||
else
|
||||
{
|
||||
// Normal case, we are not replaying a ledger close
|
||||
applyTransactions (app_, set.get(), accum,
|
||||
newLCL, retriableTxs, tapNONE);
|
||||
}
|
||||
// Update fee computations.
|
||||
app_.getTxQ().processValidatedLedger(app_, accum,
|
||||
mCurrentMSeconds > 5s);
|
||||
|
||||
accum.apply(*newLCL);
|
||||
JLOG (j_.debug)
|
||||
<< "Consensus built new ledger";
|
||||
sharedLCL = std::move(buildLCL);
|
||||
}
|
||||
|
||||
// retriableTxs will include any transactions that
|
||||
// made it into the consensus set but failed during application
|
||||
// to the ledger.
|
||||
|
||||
newLCL->updateSkipList ();
|
||||
|
||||
{
|
||||
int asf = newLCL->stateMap().flushDirty (
|
||||
hotACCOUNT_NODE, newLCL->info().seq);
|
||||
int tmf = newLCL->txMap().flushDirty (
|
||||
hotTRANSACTION_NODE, newLCL->info().seq);
|
||||
JLOG (j_.debug) << "Flushed " <<
|
||||
asf << " accounts and " <<
|
||||
tmf << " transaction nodes";
|
||||
}
|
||||
|
||||
// Accept ledger
|
||||
newLCL->setAccepted(closeTime, mCloseResolution,
|
||||
closeTimeCorrect, app_.config());
|
||||
|
||||
// And stash the ledger in the ledger master
|
||||
if (ledgerMaster_.storeLedger (newLCL))
|
||||
JLOG (j_.debug)
|
||||
<< "Consensus built ledger we already had";
|
||||
else if (app_.getInboundLedgers().find (newLCL->getHash()))
|
||||
JLOG (j_.debug)
|
||||
<< "Consensus built ledger we were acquiring";
|
||||
else
|
||||
JLOG (j_.debug)
|
||||
<< "Consensus built new ledger";
|
||||
|
||||
uint256 const newLCLHash = newLCL->getHash ();
|
||||
uint256 const newLCLHash = sharedLCL->info().hash;
|
||||
JLOG (j_.debug)
|
||||
<< "Report: NewL = " << newLCL->getHash ()
|
||||
<< ":" << newLCL->info().seq;
|
||||
<< "Report: NewL = " << newLCLHash
|
||||
<< ":" << sharedLCL->info().seq;
|
||||
// Tell directly connected peers that we have a new LCL
|
||||
statusChange (protocol::neACCEPTED_LEDGER, *newLCL);
|
||||
statusChange (protocol::neACCEPTED_LEDGER, *sharedLCL);
|
||||
|
||||
if (mValidating &&
|
||||
! ledgerMaster_.isCompatible (newLCL,
|
||||
! ledgerMaster_.isCompatible (*sharedLCL,
|
||||
app_.journal("LedgerConsensus").warning,
|
||||
"Not validating"))
|
||||
{
|
||||
@@ -1061,15 +1064,15 @@ void LedgerConsensusImp::accept (std::shared_ptr<SHAMap> set)
|
||||
auto v = std::make_shared<STValidation> (newLCLHash,
|
||||
consensus_.validationTimestamp(app_.timeKeeper().now()),
|
||||
mValPublic, mProposing);
|
||||
v->setFieldU32 (sfLedgerSequence, newLCL->info().seq);
|
||||
v->setFieldU32 (sfLedgerSequence, sharedLCL->info().seq);
|
||||
addLoad(v); // Our network load
|
||||
|
||||
if (((newLCL->info().seq + 1) % 256) == 0)
|
||||
if (((sharedLCL->info().seq + 1) % 256) == 0)
|
||||
// next ledger is flag ledger
|
||||
{
|
||||
// Suggest fee changes and new features
|
||||
m_feeVote.doValidation (newLCL, *v);
|
||||
app_.getAmendmentTable ().doValidation (newLCL, *v);
|
||||
m_feeVote.doValidation (sharedLCL, *v);
|
||||
app_.getAmendmentTable ().doValidation (sharedLCL, *v);
|
||||
}
|
||||
|
||||
auto const signingHash = v->sign (mValSecret);
|
||||
@@ -1088,10 +1091,10 @@ void LedgerConsensusImp::accept (std::shared_ptr<SHAMap> set)
|
||||
}
|
||||
else
|
||||
JLOG (j_.info)
|
||||
<< "CNF newLCL " << newLCLHash;
|
||||
<< "CNF buildLCL " << newLCLHash;
|
||||
|
||||
// See if we can accept a ledger as fully-validated
|
||||
ledgerMaster_.consensusBuilt (newLCL, getJson (true));
|
||||
ledgerMaster_.consensusBuilt (sharedLCL, getJson (true));
|
||||
|
||||
{
|
||||
// Apply disputed transactions that didn't get in
|
||||
@@ -1150,7 +1153,7 @@ void LedgerConsensusImp::accept (std::shared_ptr<SHAMap> set)
|
||||
else
|
||||
rules.emplace();
|
||||
app_.openLedger().accept(app_, *rules,
|
||||
newLCL, localTx, anyDisputes, retriableTxs, tapNONE,
|
||||
sharedLCL, localTx, anyDisputes, retriableTxs, tapNONE,
|
||||
"consensus",
|
||||
[&](OpenView& view, beast::Journal j)
|
||||
{
|
||||
@@ -1159,10 +1162,10 @@ void LedgerConsensusImp::accept (std::shared_ptr<SHAMap> set)
|
||||
});
|
||||
}
|
||||
|
||||
ledgerMaster_.switchLCL (newLCL);
|
||||
ledgerMaster_.switchLCL (sharedLCL);
|
||||
|
||||
assert (ledgerMaster_.getClosedLedger()->getHash() == newLCL->getHash());
|
||||
assert (app_.openLedger().current()->info().parentHash == newLCL->getHash());
|
||||
assert (ledgerMaster_.getClosedLedger()->info().hash == sharedLCL->info().hash);
|
||||
assert (app_.openLedger().current()->info().parentHash == sharedLCL->info().hash);
|
||||
|
||||
if (mValidating)
|
||||
{
|
||||
@@ -1363,7 +1366,7 @@ void LedgerConsensusImp::sendHaveTxSet (uint256 const& hash, bool direct)
|
||||
}
|
||||
|
||||
void LedgerConsensusImp::statusChange (
|
||||
protocol::NodeEvent event, Ledger& ledger)
|
||||
protocol::NodeEvent event, ReadView const& ledger)
|
||||
{
|
||||
protocol::TMStatusChange s;
|
||||
|
||||
@@ -1376,8 +1379,8 @@ void LedgerConsensusImp::statusChange (
|
||||
s.set_networktime (app_.timeKeeper().now().time_since_epoch().count());
|
||||
s.set_ledgerhashprevious(ledger.info().parentHash.begin (),
|
||||
std::decay_t<decltype(ledger.info().parentHash)>::bytes);
|
||||
s.set_ledgerhash (ledger.getHash ().begin (),
|
||||
std::decay_t<decltype(ledger.getHash ())>::bytes);
|
||||
s.set_ledgerhash (ledger.info().hash.begin (),
|
||||
std::decay_t<decltype(ledger.info().hash)>::bytes);
|
||||
|
||||
std::uint32_t uMin, uMax;
|
||||
if (!ledgerMaster_.getFullValidatedRange (uMin, uMax))
|
||||
@@ -1757,7 +1760,7 @@ void LedgerConsensusImp::checkOurValidation ()
|
||||
return;
|
||||
}
|
||||
|
||||
auto v = std::make_shared<STValidation> (mPreviousLedger->getHash (),
|
||||
auto v = std::make_shared<STValidation> (mPreviousLedger->info().hash,
|
||||
consensus_.validationTimestamp(app_.timeKeeper().now()),
|
||||
mValPublic, false);
|
||||
addLoad(v);
|
||||
@@ -1803,7 +1806,7 @@ void LedgerConsensusImp::endConsensus (bool correctLCL)
|
||||
|
||||
void LedgerConsensusImp::startRound (
|
||||
LedgerHash const& prevLCLHash,
|
||||
Ledger::ref prevLedger,
|
||||
std::shared_ptr<Ledger const> const& prevLedger,
|
||||
NetClock::time_point closeTime,
|
||||
int previousProposers,
|
||||
std::chrono::milliseconds previousConvergeTime)
|
||||
@@ -1861,7 +1864,7 @@ void LedgerConsensusImp::startRound (
|
||||
mProposing = mValidating = false;
|
||||
}
|
||||
|
||||
mHaveCorrectLCL = (mPreviousLedger->getHash () == mPrevLedgerHash);
|
||||
mHaveCorrectLCL = (mPreviousLedger->info().hash == mPrevLedgerHash);
|
||||
|
||||
if (!mHaveCorrectLCL)
|
||||
{
|
||||
@@ -1874,7 +1877,7 @@ void LedgerConsensusImp::startRound (
|
||||
{
|
||||
JLOG (j_.info)
|
||||
<< "Entering consensus with: "
|
||||
<< mPreviousLedger->getHash ();
|
||||
<< mPreviousLedger->info().hash;
|
||||
JLOG (j_.info)
|
||||
<< "Correct LCL is: " << prevLCLHash;
|
||||
}
|
||||
@@ -1981,7 +1984,7 @@ void applyTransactions (
|
||||
Application& app,
|
||||
SHAMap const* set,
|
||||
OpenView& view,
|
||||
Ledger::ref checkLedger,
|
||||
ReadView const& checkLedger,
|
||||
CanonicalTXSet& retriableTxs,
|
||||
ApplyFlags flags)
|
||||
{
|
||||
@@ -1991,7 +1994,7 @@ void applyTransactions (
|
||||
{
|
||||
for (auto const& item : *set)
|
||||
{
|
||||
if (checkLedger->txExists (item.key()))
|
||||
if (checkLedger.txExists (item.key()))
|
||||
continue;
|
||||
|
||||
// The transaction isn't in the check ledger, try to apply it
|
||||
|
||||
@@ -105,7 +105,7 @@ public:
|
||||
*/
|
||||
void startRound (
|
||||
LedgerHash const& prevLCLHash,
|
||||
Ledger::ref prevLedger,
|
||||
std::shared_ptr<Ledger const> const& prevLedger,
|
||||
NetClock::time_point closeTime,
|
||||
int previousProposers,
|
||||
std::chrono::milliseconds previousConvergeTime) override;
|
||||
@@ -256,7 +256,7 @@ private:
|
||||
typically neACCEPTED_LEDGER or neCLOSING_LEDGER.
|
||||
@param ledger The ledger associated with the event.
|
||||
*/
|
||||
void statusChange (protocol::NodeEvent event, Ledger& ledger);
|
||||
void statusChange (protocol::NodeEvent event, ReadView const& ledger);
|
||||
|
||||
/** Take an initial position on what we think the consensus should be
|
||||
based on the transactions that made it into our open ledger
|
||||
@@ -316,7 +316,7 @@ private:
|
||||
uint256 mPrevLedgerHash;
|
||||
uint256 mAcquiringLedger;
|
||||
|
||||
Ledger::pointer mPreviousLedger;
|
||||
std::shared_ptr<Ledger const> mPreviousLedger;
|
||||
LedgerProposal::pointer mOurPosition;
|
||||
PublicKey mValPublic;
|
||||
SecretKey mValSecret;
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <ripple/app/misc/TxQ.h>
|
||||
#include <ripple/app/misc/Validations.h>
|
||||
#include <ripple/app/paths/PathRequests.h>
|
||||
#include <ripple/basics/contract.h>
|
||||
#include <ripple/basics/Log.h>
|
||||
#include <ripple/basics/TaggedCache.h>
|
||||
#include <ripple/basics/UptimeTimer.h>
|
||||
@@ -109,8 +110,10 @@ LedgerMaster::getValidLedgerIndex ()
|
||||
}
|
||||
|
||||
bool
|
||||
LedgerMaster::isCompatible (Ledger::pointer ledger,
|
||||
beast::Journal::Stream s, const char* reason)
|
||||
LedgerMaster::isCompatible (
|
||||
ReadView const& view,
|
||||
beast::Journal::Stream s,
|
||||
char const* reason)
|
||||
{
|
||||
if (mStrictValCount)
|
||||
{
|
||||
@@ -122,7 +125,7 @@ LedgerMaster::isCompatible (Ledger::pointer ledger,
|
||||
auto validLedger = getValidatedLedger();
|
||||
|
||||
if (validLedger &&
|
||||
! areCompatible (*validLedger, *ledger, s, reason))
|
||||
! areCompatible (*validLedger, view, s, reason))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -132,7 +135,7 @@ LedgerMaster::isCompatible (Ledger::pointer ledger,
|
||||
|
||||
if ((mLastValidLedger.second != 0) &&
|
||||
! areCompatible (mLastValidLedger.first,
|
||||
mLastValidLedger.second, *ledger, s, reason))
|
||||
mLastValidLedger.second, view, s, reason))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -201,13 +204,19 @@ LedgerMaster::isCaughtUp(std::string& reason)
|
||||
}
|
||||
|
||||
void
|
||||
LedgerMaster::setValidLedger(Ledger::ref l)
|
||||
LedgerMaster::setValidLedger(
|
||||
std::shared_ptr<Ledger const> const& l)
|
||||
{
|
||||
std::vector <NetClock::time_point> times;
|
||||
NetClock::time_point signTime;
|
||||
|
||||
if (! app_.config().RUN_STANDALONE)
|
||||
{
|
||||
times = app_.getValidations().getValidationTimes(
|
||||
l->getHash());
|
||||
l->info().hash);
|
||||
}
|
||||
|
||||
NetClock::time_point signTime;
|
||||
|
||||
if (! times.empty () && times.size() >= mMinValidations)
|
||||
{
|
||||
// Calculate the sample median
|
||||
@@ -224,14 +233,16 @@ LedgerMaster::setValidLedger(Ledger::ref l)
|
||||
mValidLedger.set (l);
|
||||
mValidLedgerSign = signTime.time_since_epoch().count();
|
||||
mValidLedgerSeq = l->info().seq;
|
||||
app_.getOPs().updateLocalTx (l);
|
||||
|
||||
app_.getOPs().updateLocalTx (*l);
|
||||
app_.getSHAMapStore().onLedgerClosed (getValidatedLedger());
|
||||
mLedgerHistory.validatedLedger (l);
|
||||
app_.getAmendmentTable().doValidatedLedger (l);
|
||||
}
|
||||
|
||||
void
|
||||
LedgerMaster::setPubLedger(Ledger::ref l)
|
||||
LedgerMaster::setPubLedger(
|
||||
std::shared_ptr<Ledger const> const& l)
|
||||
{
|
||||
mPubLedger = l;
|
||||
mPubLedgerClose = l->info().closeTime.time_since_epoch().count();
|
||||
@@ -242,21 +253,22 @@ void
|
||||
LedgerMaster::addHeldTransaction (
|
||||
std::shared_ptr<Transaction> const& transaction)
|
||||
{
|
||||
// returns true if transaction was added
|
||||
ScopedLockType ml (m_mutex);
|
||||
mHeldTransactions.insert (transaction->getSTransaction ());
|
||||
}
|
||||
|
||||
void
|
||||
LedgerMaster::switchLCL (Ledger::pointer lastClosed)
|
||||
LedgerMaster::switchLCL(std::shared_ptr<Ledger const> const& lastClosed)
|
||||
{
|
||||
assert (lastClosed);
|
||||
if(! lastClosed->isImmutable())
|
||||
LogicError("mutable ledger in switchLCL");
|
||||
|
||||
lastClosed->setClosed ();
|
||||
if (lastClosed->open())
|
||||
LogicError ("The new last closed ledger is open!");
|
||||
|
||||
{
|
||||
ScopedLockType ml (m_mutex);
|
||||
|
||||
mClosedLedger.set (lastClosed);
|
||||
}
|
||||
|
||||
@@ -278,17 +290,10 @@ LedgerMaster::fixIndex (LedgerIndex ledgerIndex, LedgerHash const& ledgerHash)
|
||||
}
|
||||
|
||||
bool
|
||||
LedgerMaster::storeLedger (Ledger::pointer ledger)
|
||||
LedgerMaster::storeLedger (std::shared_ptr<Ledger const> ledger)
|
||||
{
|
||||
// Returns true if we already had the ledger
|
||||
return mLedgerHistory.addLedger (ledger, false);
|
||||
}
|
||||
|
||||
void
|
||||
LedgerMaster::forceValid (Ledger::pointer ledger)
|
||||
{
|
||||
ledger->setValidated();
|
||||
setFullLedger(ledger, true, false);
|
||||
return mLedgerHistory.insert(std::move(ledger), false);
|
||||
}
|
||||
|
||||
/** Apply held transactions to the open ledger
|
||||
@@ -442,7 +447,7 @@ LedgerMaster::getValidatedRange (std::uint32_t& minVal, std::uint32_t& maxVal)
|
||||
|
||||
// Get the earliest ledger we will let peers fetch
|
||||
std::uint32_t
|
||||
LedgerMaster::getEarliestFetch ()
|
||||
LedgerMaster::getEarliestFetch()
|
||||
{
|
||||
// The earliest ledger we will let people fetch is ledger zero,
|
||||
// unless that creates a larger range than allowed
|
||||
@@ -456,7 +461,9 @@ LedgerMaster::getEarliestFetch ()
|
||||
}
|
||||
|
||||
void
|
||||
LedgerMaster::tryFill (Job& job, Ledger::pointer ledger)
|
||||
LedgerMaster::tryFill (
|
||||
Job& job,
|
||||
std::shared_ptr<Ledger const> ledger)
|
||||
{
|
||||
std::uint32_t seq = ledger->info().seq;
|
||||
uint256 prevHash = ledger->info().parentHash;
|
||||
@@ -567,18 +574,18 @@ LedgerMaster::getFetchPack (LedgerHash missingHash, LedgerIndex missingIndex)
|
||||
}
|
||||
|
||||
void
|
||||
LedgerMaster::fixMismatch (Ledger::ref ledger)
|
||||
LedgerMaster::fixMismatch (ReadView const& ledger)
|
||||
{
|
||||
int invalidate = 0;
|
||||
boost::optional<uint256> hash;
|
||||
|
||||
for (std::uint32_t lSeq = ledger->info().seq - 1; lSeq > 0; --lSeq)
|
||||
for (std::uint32_t lSeq = ledger.info().seq - 1; lSeq > 0; --lSeq)
|
||||
{
|
||||
if (haveLedger (lSeq))
|
||||
{
|
||||
try
|
||||
{
|
||||
hash = hashOfSeq(*ledger, lSeq, m_journal);
|
||||
hash = hashOfSeq(ledger, lSeq, m_journal);
|
||||
}
|
||||
catch (std::exception const&)
|
||||
{
|
||||
@@ -591,9 +598,9 @@ LedgerMaster::fixMismatch (Ledger::ref ledger)
|
||||
if (hash)
|
||||
{
|
||||
// try to close the seam
|
||||
Ledger::pointer otherLedger = getLedgerBySeq (lSeq);
|
||||
auto otherLedger = getLedgerBySeq (lSeq);
|
||||
|
||||
if (otherLedger && (otherLedger->getHash () == *hash))
|
||||
if (otherLedger && (otherLedger->info().hash == *hash))
|
||||
{
|
||||
// we closed the seam
|
||||
if (invalidate != 0)
|
||||
@@ -623,18 +630,20 @@ LedgerMaster::fixMismatch (Ledger::ref ledger)
|
||||
|
||||
void
|
||||
LedgerMaster::setFullLedger (
|
||||
Ledger::pointer ledger, bool isSynchronous, bool isCurrent)
|
||||
std::shared_ptr<Ledger const> const& ledger,
|
||||
bool isSynchronous, bool isCurrent)
|
||||
{
|
||||
// A new ledger has been accepted as part of the trusted chain
|
||||
JLOG (m_journal.debug) << "Ledger " << ledger->info().seq
|
||||
<< " accepted :" << ledger->getHash ();
|
||||
JLOG (m_journal.debug) <<
|
||||
"Ledger " << ledger->info().seq <<
|
||||
" accepted :" << ledger->info().hash;
|
||||
assert (ledger->stateMap().getHash ().isNonZero ());
|
||||
|
||||
ledger->setValidated();
|
||||
ledger->setFull();
|
||||
|
||||
if (isCurrent)
|
||||
mLedgerHistory.addLedger(ledger, true);
|
||||
mLedgerHistory.insert(ledger, true);
|
||||
|
||||
{
|
||||
// Check the SQL database's entry for the sequence before this
|
||||
@@ -648,12 +657,11 @@ LedgerMaster::setFullLedger (
|
||||
pendSaveValidated (app_, ledger, isSynchronous, isCurrent);
|
||||
|
||||
{
|
||||
ScopedLockType ml (mCompleteLock);
|
||||
mCompleteLedgers.setValue (ledger->info().seq);
|
||||
}
|
||||
|
||||
{
|
||||
ScopedLockType ml (mCompleteLock);
|
||||
mCompleteLedgers.setValue (ledger->info().seq);
|
||||
}
|
||||
|
||||
{
|
||||
ScopedLockType ml (m_mutex);
|
||||
|
||||
if (ledger->info().seq > mValidLedgerSeq)
|
||||
@@ -670,12 +678,12 @@ LedgerMaster::setFullLedger (
|
||||
auto prevLedger = getLedgerBySeq (ledger->info().seq - 1);
|
||||
|
||||
if (!prevLedger ||
|
||||
(prevLedger->getHash () != ledger->info().parentHash))
|
||||
(prevLedger->info().hash != ledger->info().parentHash))
|
||||
{
|
||||
JLOG (m_journal.warning)
|
||||
<< "Acquired ledger invalidates previous ledger: "
|
||||
<< (prevLedger ? "hashMismatch" : "missingLedger");
|
||||
fixMismatch (ledger);
|
||||
<< "Acquired ledger invalidates previous ledger: "
|
||||
<< (prevLedger ? "hashMismatch" : "missingLedger");
|
||||
fixMismatch (*ledger);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -694,8 +702,7 @@ LedgerMaster::failedSave(std::uint32_t seq, uint256 const& hash)
|
||||
void
|
||||
LedgerMaster::checkAccept (uint256 const& hash, std::uint32_t seq)
|
||||
{
|
||||
|
||||
int valCount;
|
||||
int valCount = 0;
|
||||
|
||||
if (seq != 0)
|
||||
{
|
||||
@@ -728,7 +735,7 @@ LedgerMaster::checkAccept (uint256 const& hash, std::uint32_t seq)
|
||||
return;
|
||||
}
|
||||
|
||||
Ledger::pointer ledger = mLedgerHistory.getLedgerByHash (hash);
|
||||
auto ledger = mLedgerHistory.getLedgerByHash (hash);
|
||||
|
||||
if (!ledger)
|
||||
{
|
||||
@@ -777,7 +784,8 @@ LedgerMaster::getNeededValidations ()
|
||||
}
|
||||
|
||||
void
|
||||
LedgerMaster::checkAccept (Ledger::ref ledger)
|
||||
LedgerMaster::checkAccept (
|
||||
std::shared_ptr<Ledger const> const& ledger)
|
||||
{
|
||||
if (ledger->info().seq <= mValidLedgerSeq)
|
||||
return;
|
||||
@@ -789,13 +797,14 @@ LedgerMaster::checkAccept (Ledger::ref ledger)
|
||||
if (ledger->info().seq <= mValidLedgerSeq)
|
||||
return;
|
||||
|
||||
int minVal = getNeededValidations();
|
||||
int tvc = app_.getValidations().getTrustedValidationCount(
|
||||
ledger->getHash());
|
||||
auto const minVal = getNeededValidations();
|
||||
auto const tvc = app_.getValidations().getTrustedValidationCount(
|
||||
ledger->info().hash);
|
||||
if (tvc < minVal) // nothing we can do
|
||||
{
|
||||
JLOG (m_journal.trace)
|
||||
<< "Only " << tvc << " validations for " << ledger->getHash();
|
||||
JLOG (m_journal.trace) <<
|
||||
"Only " << tvc <<
|
||||
" validations for " << ledger->info().hash;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -803,7 +812,7 @@ LedgerMaster::checkAccept (Ledger::ref ledger)
|
||||
<< "Advancing accepted ledger to " << ledger->info().seq
|
||||
<< " with >= " << minVal << " validations";
|
||||
|
||||
mLastValidateHash = ledger->getHash();
|
||||
mLastValidateHash = ledger->info().hash;
|
||||
mLastValidateSeq = ledger->info().seq;
|
||||
|
||||
ledger->setValidated();
|
||||
@@ -817,7 +826,7 @@ LedgerMaster::checkAccept (Ledger::ref ledger)
|
||||
}
|
||||
|
||||
std::uint64_t const base = app_.getFeeTrack().getLoadBase();
|
||||
auto fees = app_.getValidations().fees (ledger->getHash(), base);
|
||||
auto fees = app_.getValidations().fees (ledger->info().hash, base);
|
||||
{
|
||||
auto fees2 = app_.getValidations().fees (
|
||||
ledger->info(). parentHash, base);
|
||||
@@ -842,7 +851,8 @@ LedgerMaster::checkAccept (Ledger::ref ledger)
|
||||
|
||||
/** Report that the consensus process built a particular ledger */
|
||||
void
|
||||
LedgerMaster::consensusBuilt (Ledger::ref ledger, Json::Value consensus)
|
||||
LedgerMaster::consensusBuilt(
|
||||
std::shared_ptr<Ledger const> const& ledger, Json::Value consensus)
|
||||
{
|
||||
|
||||
// Because we just built a ledger, we are no longer building one
|
||||
@@ -906,7 +916,7 @@ LedgerMaster::consensusBuilt (Ledger::ref ledger, Json::Value consensus)
|
||||
|
||||
auto neededValidations = getNeededValidations ();
|
||||
auto maxSeq = mValidLedgerSeq.load();
|
||||
auto maxLedger = ledger->getHash();
|
||||
auto maxLedger = ledger->info().hash;
|
||||
|
||||
// Of the ledgers with sufficient validations,
|
||||
// find the one with the highest sequence
|
||||
@@ -916,8 +926,7 @@ LedgerMaster::consensusBuilt (Ledger::ref ledger, Json::Value consensus)
|
||||
// If we still don't know the sequence, get it
|
||||
if (v.second.ledgerSeq_ == 0)
|
||||
{
|
||||
Ledger::pointer ledger = getLedgerByHash (v.first);
|
||||
if (ledger)
|
||||
if (auto ledger = getLedgerByHash (v.first))
|
||||
v.second.ledgerSeq_ = ledger->info().seq;
|
||||
}
|
||||
|
||||
@@ -984,96 +993,110 @@ LedgerMaster::shouldFetchPack (std::uint32_t seq) const
|
||||
return (fetch_seq_ != seq);
|
||||
}
|
||||
|
||||
std::vector<Ledger::pointer>
|
||||
std::vector<std::shared_ptr<Ledger const>>
|
||||
LedgerMaster::findNewLedgersToPublish ()
|
||||
{
|
||||
std::vector<Ledger::pointer> ret;
|
||||
std::vector<std::shared_ptr<Ledger const>> ret;
|
||||
|
||||
JLOG (m_journal.trace) << "findNewLedgersToPublish<";
|
||||
|
||||
// No valid ledger, nothing to do
|
||||
if (mValidLedger.empty ())
|
||||
{
|
||||
// No valid ledger, nothing to do
|
||||
JLOG(m_journal.trace) <<
|
||||
"No valid journal, nothing to publish.";
|
||||
return {};
|
||||
}
|
||||
else if (! mPubLedger)
|
||||
|
||||
if (! mPubLedger)
|
||||
{
|
||||
JLOG (m_journal.info) << "First published ledger will be "
|
||||
<< mValidLedgerSeq;
|
||||
ret.push_back (mValidLedger.get ());
|
||||
JLOG(m_journal.info) <<
|
||||
"First published ledger will be " << mValidLedgerSeq;
|
||||
return { mValidLedger.get () };
|
||||
}
|
||||
else if (mValidLedgerSeq > (mPubLedgerSeq + MAX_LEDGER_GAP))
|
||||
|
||||
if (mValidLedgerSeq > (mPubLedgerSeq + MAX_LEDGER_GAP))
|
||||
{
|
||||
JLOG (m_journal.warning)
|
||||
<< "Gap in validated ledger stream " << mPubLedgerSeq
|
||||
<< " - " << mValidLedgerSeq - 1;
|
||||
Ledger::pointer valLedger = mValidLedger.get ();
|
||||
JLOG(m_journal.warning) <<
|
||||
"Gap in validated ledger stream " << mPubLedgerSeq <<
|
||||
" - " << mValidLedgerSeq - 1;
|
||||
|
||||
auto valLedger = mValidLedger.get ();
|
||||
ret.push_back (valLedger);
|
||||
setPubLedger (valLedger);
|
||||
app_.getOrderBookDB().setup(valLedger);
|
||||
|
||||
return { valLedger };
|
||||
}
|
||||
else if (mValidLedgerSeq > mPubLedgerSeq)
|
||||
|
||||
if (mValidLedgerSeq <= mPubLedgerSeq)
|
||||
{
|
||||
int acqCount = 0;
|
||||
(m_journal.trace) <<
|
||||
"No valid journal, nothing to publish.";
|
||||
return {};
|
||||
}
|
||||
|
||||
auto pubSeq = mPubLedgerSeq + 1; // Next sequence to publish
|
||||
Ledger::pointer valLedger = mValidLedger.get ();
|
||||
std::uint32_t valSeq = valLedger->info().seq;
|
||||
int acqCount = 0;
|
||||
|
||||
ScopedUnlockType sul(m_mutex);
|
||||
try
|
||||
auto pubSeq = mPubLedgerSeq + 1; // Next sequence to publish
|
||||
auto valLedger = mValidLedger.get ();
|
||||
std::uint32_t valSeq = valLedger->info().seq;
|
||||
|
||||
ScopedUnlockType sul(m_mutex);
|
||||
try
|
||||
{
|
||||
for (std::uint32_t seq = pubSeq; seq <= valSeq; ++seq)
|
||||
{
|
||||
for (std::uint32_t seq = pubSeq; seq <= valSeq; ++seq)
|
||||
JLOG(m_journal.trace)
|
||||
<< "Trying to fetch/publish valid ledger " << seq;
|
||||
|
||||
std::shared_ptr<Ledger const> ledger;
|
||||
// This can throw
|
||||
auto hash = hashOfSeq(*valLedger, seq, m_journal);
|
||||
// VFALCO TODO Restructure this code so that zero is not
|
||||
// used.
|
||||
if (! hash)
|
||||
hash = zero; // kludge
|
||||
if (seq == valSeq)
|
||||
{
|
||||
JLOG (m_journal.trace)
|
||||
<< "Trying to fetch/publish valid ledger " << seq;
|
||||
// We need to publish the ledger we just fully validated
|
||||
ledger = valLedger;
|
||||
}
|
||||
else if (hash->isZero())
|
||||
{
|
||||
JLOG (m_journal.fatal)
|
||||
<< "Ledger: " << valSeq
|
||||
<< " does not have hash for " << seq;
|
||||
assert (false);
|
||||
}
|
||||
else
|
||||
{
|
||||
ledger = mLedgerHistory.getLedgerByHash (*hash);
|
||||
}
|
||||
|
||||
Ledger::pointer ledger;
|
||||
// This can throw
|
||||
auto hash = hashOfSeq(*valLedger, seq, m_journal);
|
||||
// VFALCO TODO Restructure this code so that zero is not
|
||||
// used.
|
||||
if (! hash)
|
||||
hash = zero; // kludge
|
||||
if (seq == valSeq)
|
||||
{
|
||||
// We need to publish the ledger we just fully validated
|
||||
ledger = valLedger;
|
||||
}
|
||||
else if (hash->isZero())
|
||||
{
|
||||
JLOG (m_journal.fatal)
|
||||
<< "Ledger: " << valSeq
|
||||
<< " does not have hash for " << seq;
|
||||
assert (false);
|
||||
}
|
||||
else
|
||||
{
|
||||
ledger = mLedgerHistory.getLedgerByHash (*hash);
|
||||
}
|
||||
|
||||
// Can we try to acquire the ledger we need?
|
||||
if (! ledger && (++acqCount < 4))
|
||||
ledger = app_.getInboundLedgers ().acquire(
|
||||
*hash, seq, InboundLedger::fcGENERIC);
|
||||
|
||||
// Did we acquire the next ledger we need to publish?
|
||||
if (ledger && (ledger->info().seq == pubSeq))
|
||||
{
|
||||
ledger->setValidated();
|
||||
ret.push_back (ledger);
|
||||
++pubSeq;
|
||||
}
|
||||
// Can we try to acquire the ledger we need?
|
||||
if (! ledger && (++acqCount < 4))
|
||||
ledger = app_.getInboundLedgers ().acquire(
|
||||
*hash, seq, InboundLedger::fcGENERIC);
|
||||
|
||||
// Did we acquire the next ledger we need to publish?
|
||||
if (ledger && (ledger->info().seq == pubSeq))
|
||||
{
|
||||
ledger->setValidated();
|
||||
ret.push_back (ledger);
|
||||
++pubSeq;
|
||||
}
|
||||
}
|
||||
catch (std::exception const&)
|
||||
{
|
||||
JLOG (m_journal.error)
|
||||
<< "findNewLedgersToPublish catches an exception";
|
||||
}
|
||||
|
||||
JLOG(m_journal.trace) <<
|
||||
"ready to publish " << ret.size() << " ledgers.";
|
||||
}
|
||||
catch (std::exception const&)
|
||||
{
|
||||
JLOG(m_journal.error) <<
|
||||
"Exception while trying to find ledgers to publish.";
|
||||
}
|
||||
|
||||
JLOG (m_journal.trace)
|
||||
<< "findNewLedgersToPublish> " << ret.size();
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1096,7 +1119,9 @@ LedgerMaster::tryAdvance()
|
||||
// Return the hash of the valid ledger with a particular sequence, given a
|
||||
// subsequent ledger known valid.
|
||||
boost::optional<LedgerHash>
|
||||
LedgerMaster::getLedgerHash(std::uint32_t desiredSeq, Ledger::ref knownGoodLedger)
|
||||
LedgerMaster::getLedgerHash(
|
||||
std::uint32_t desiredSeq,
|
||||
std::shared_ptr<ReadView const> const& knownGoodLedger)
|
||||
{
|
||||
assert(desiredSeq < knownGoodLedger->info().seq);
|
||||
|
||||
@@ -1111,8 +1136,7 @@ LedgerMaster::getLedgerHash(std::uint32_t desiredSeq, Ledger::ref knownGoodLedge
|
||||
hash = hashOfSeq(*knownGoodLedger, seq, m_journal);
|
||||
if (hash)
|
||||
{
|
||||
auto l = getLedgerByHash(*hash);
|
||||
if (l)
|
||||
if (auto l = getLedgerByHash(*hash))
|
||||
{
|
||||
hash = hashOfSeq(*l, desiredSeq, m_journal);
|
||||
assert (hash);
|
||||
@@ -1172,7 +1196,7 @@ LedgerMaster::updatePaths (Job& job)
|
||||
if (age > 1min)
|
||||
{
|
||||
JLOG (m_journal.debug)
|
||||
<< "Published ledger too old for updating paths";
|
||||
<< "Published ledger too old for updating paths";
|
||||
--mPathFindThread;
|
||||
return;
|
||||
}
|
||||
@@ -1186,21 +1210,23 @@ LedgerMaster::updatePaths (Job& job)
|
||||
catch (SHAMapMissingNode&)
|
||||
{
|
||||
JLOG (m_journal.info)
|
||||
<< "Missing node detected during pathfinding";
|
||||
if (lastLedger->info().open)
|
||||
<< "Missing node detected during pathfinding";
|
||||
if (lastLedger->open())
|
||||
{
|
||||
// our parent is the problem
|
||||
app_.getInboundLedgers().acquire(
|
||||
lastLedger->info().parentHash, lastLedger->info().seq - 1,
|
||||
lastLedger->info().parentHash,
|
||||
lastLedger->info().seq - 1,
|
||||
InboundLedger::fcGENERIC);
|
||||
}
|
||||
else
|
||||
{
|
||||
// this ledger is the problem
|
||||
app_.getInboundLedgers().acquire(
|
||||
lastLedger->info().hash, lastLedger->info().seq,
|
||||
lastLedger->info().hash,
|
||||
lastLedger->info().seq,
|
||||
InboundLedger::fcGENERIC);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1262,20 +1288,6 @@ LedgerMaster::getCurrentLedger ()
|
||||
return app_.openLedger().current();
|
||||
}
|
||||
|
||||
// The finalized ledger is the last closed/accepted ledger
|
||||
Ledger::pointer
|
||||
LedgerMaster::getClosedLedger ()
|
||||
{
|
||||
return mClosedLedger.get ();
|
||||
}
|
||||
|
||||
// The validated ledger is the last fully validated ledger
|
||||
Ledger::pointer
|
||||
LedgerMaster::getValidatedLedger ()
|
||||
{
|
||||
return mValidLedger.get ();
|
||||
}
|
||||
|
||||
Rules
|
||||
LedgerMaster::getValidatedRules ()
|
||||
{
|
||||
@@ -1291,44 +1303,13 @@ LedgerMaster::getValidatedRules ()
|
||||
|
||||
// This is the last ledger we published to clients and can lag the validated
|
||||
// ledger.
|
||||
Ledger::pointer
|
||||
std::shared_ptr<ReadView const>
|
||||
LedgerMaster::getPublishedLedger ()
|
||||
{
|
||||
ScopedLockType lock(m_mutex);
|
||||
return mPubLedger;
|
||||
}
|
||||
|
||||
bool
|
||||
LedgerMaster::isValidLedger(LedgerInfo const& info)
|
||||
{
|
||||
if (info.validated)
|
||||
return true;
|
||||
|
||||
if (info.open)
|
||||
return false;
|
||||
|
||||
auto seq = info.seq;
|
||||
try
|
||||
{
|
||||
// Use the skip list in the last validated ledger to see if ledger
|
||||
// comes before the last validated ledger (and thus has been
|
||||
// validated).
|
||||
auto hash = walkHashBySeq (seq);
|
||||
if (info.hash != hash)
|
||||
return false;
|
||||
}
|
||||
catch (SHAMapMissingNode const&)
|
||||
{
|
||||
JLOG (app_.journal ("RPCHandler").warning)
|
||||
<< "Missing SHANode " << std::to_string (seq);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Mark ledger as validated to save time if we see it again.
|
||||
info.validated = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
int
|
||||
LedgerMaster::getMinValidations ()
|
||||
{
|
||||
@@ -1393,16 +1374,17 @@ boost::optional<LedgerHash>
|
||||
LedgerMaster::walkHashBySeq (std::uint32_t index)
|
||||
{
|
||||
boost::optional<LedgerHash> ledgerHash;
|
||||
Ledger::pointer referenceLedger;
|
||||
|
||||
referenceLedger = mValidLedger.get ();
|
||||
if (referenceLedger)
|
||||
if (auto referenceLedger = mValidLedger.get ())
|
||||
ledgerHash = walkHashBySeq (index, referenceLedger);
|
||||
|
||||
return ledgerHash;
|
||||
}
|
||||
|
||||
boost::optional<LedgerHash>
|
||||
LedgerMaster::walkHashBySeq (std::uint32_t index, Ledger::ref referenceLedger)
|
||||
LedgerMaster::walkHashBySeq (
|
||||
std::uint32_t index,
|
||||
std::shared_ptr<ReadView const> const& referenceLedger)
|
||||
{
|
||||
if (!referenceLedger || (referenceLedger->info().seq < index))
|
||||
{
|
||||
@@ -1452,14 +1434,13 @@ LedgerMaster::walkHashBySeq (std::uint32_t index, Ledger::ref referenceLedger)
|
||||
return ledgerHash;
|
||||
}
|
||||
|
||||
Ledger::pointer
|
||||
std::shared_ptr<Ledger const>
|
||||
LedgerMaster::getLedgerBySeq (std::uint32_t index)
|
||||
{
|
||||
if (index <= mValidLedgerSeq)
|
||||
{
|
||||
// Always prefer a validated ledger
|
||||
auto valid = mValidLedger.get ();
|
||||
if (valid)
|
||||
if (auto valid = mValidLedger.get ())
|
||||
{
|
||||
if (valid->info().seq == index)
|
||||
return valid;
|
||||
@@ -1467,6 +1448,7 @@ LedgerMaster::getLedgerBySeq (std::uint32_t index)
|
||||
try
|
||||
{
|
||||
auto const hash = hashOfSeq(*valid, index, m_journal);
|
||||
|
||||
if (hash)
|
||||
return mLedgerHistory.getLedgerByHash (*hash);
|
||||
}
|
||||
@@ -1477,30 +1459,28 @@ LedgerMaster::getLedgerBySeq (std::uint32_t index)
|
||||
}
|
||||
}
|
||||
|
||||
Ledger::pointer ret = mLedgerHistory.getLedgerBySeq (index);
|
||||
if (ret)
|
||||
if (auto ret = mLedgerHistory.getLedgerBySeq (index))
|
||||
return ret;
|
||||
|
||||
ret = mClosedLedger.get ();
|
||||
auto ret = mClosedLedger.get ();
|
||||
if (ret && (ret->info().seq == index))
|
||||
return ret;
|
||||
|
||||
clearLedger (index);
|
||||
return Ledger::pointer();
|
||||
return {};
|
||||
}
|
||||
|
||||
Ledger::pointer
|
||||
std::shared_ptr<Ledger const>
|
||||
LedgerMaster::getLedgerByHash (uint256 const& hash)
|
||||
{
|
||||
Ledger::pointer ret = mLedgerHistory.getLedgerByHash (hash);
|
||||
if (ret)
|
||||
if (auto ret = mLedgerHistory.getLedgerByHash (hash))
|
||||
return ret;
|
||||
|
||||
ret = mClosedLedger.get ();
|
||||
if (ret && (ret->getHash () == hash))
|
||||
auto ret = mClosedLedger.get ();
|
||||
if (ret && (ret->info().hash == hash))
|
||||
return ret;
|
||||
|
||||
return Ledger::pointer ();
|
||||
return {};
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1628,7 +1608,7 @@ void LedgerMaster::doAdvance ()
|
||||
if (hash)
|
||||
{
|
||||
assert(hash->isNonZero());
|
||||
Ledger::pointer ledger = getLedgerByHash (*hash);
|
||||
auto ledger = getLedgerByHash (*hash);
|
||||
if (!ledger)
|
||||
{
|
||||
if (!app_.getInboundLedgers().isFailure (
|
||||
@@ -1663,8 +1643,11 @@ void LedgerMaster::doAdvance ()
|
||||
JLOG (m_journal.trace)
|
||||
<< "tryAdvance acquired "
|
||||
<< ledger->info().seq;
|
||||
setFullLedger(ledger, false, false);
|
||||
auto& parent = ledger->info().parentHash;
|
||||
setFullLedger(
|
||||
ledger,
|
||||
false,
|
||||
false);
|
||||
auto const& parent = ledger->info().parentHash;
|
||||
|
||||
int fillInProgress;
|
||||
{
|
||||
@@ -1756,7 +1739,10 @@ void LedgerMaster::doAdvance ()
|
||||
JLOG (m_journal.debug) <<
|
||||
"tryAdvance publishing seq " << ledger->info().seq;
|
||||
|
||||
setFullLedger(ledger, true, true);
|
||||
setFullLedger(
|
||||
ledger,
|
||||
true,
|
||||
true);
|
||||
}
|
||||
|
||||
setPubLedger(ledger);
|
||||
@@ -1847,7 +1833,7 @@ LedgerMaster::makeFetchPack (
|
||||
return;
|
||||
}
|
||||
|
||||
if (haveLedger->info().open)
|
||||
if (haveLedger->open())
|
||||
{
|
||||
m_journal.warning
|
||||
<< "Peer requests fetch pack from open ledger: "
|
||||
@@ -1912,10 +1898,11 @@ LedgerMaster::makeFetchPack (
|
||||
std::uint32_t lSeq = wantLedger->info().seq;
|
||||
|
||||
protocol::TMIndexedObject& newObj = *reply.add_objects ();
|
||||
newObj.set_hash (wantLedger->getHash ().begin (), 256 / 8);
|
||||
newObj.set_hash (
|
||||
wantLedger->info().hash.data(), 256 / 8);
|
||||
Serializer s (256);
|
||||
s.add32 (HashPrefix::ledgerMaster);
|
||||
wantLedger->addRaw (s);
|
||||
addRaw(wantLedger->info(), s);
|
||||
newObj.set_data (s.getDataPtr (), s.getLength ());
|
||||
newObj.set_ledgerseq (lSeq);
|
||||
|
||||
|
||||
@@ -40,13 +40,13 @@ bool isBinary(LedgerFill const& fill)
|
||||
}
|
||||
|
||||
template <class Object>
|
||||
void fillJson(Object& json, LedgerInfo const& info, bool bFull)
|
||||
void fillJson(Object& json, bool closed, LedgerInfo const& info, bool bFull)
|
||||
{
|
||||
json[jss::parent_hash] = to_string (info.parentHash);
|
||||
json[jss::ledger_index] = to_string (info.seq);
|
||||
json[jss::seqNum] = to_string (info.seq); // DEPRECATED
|
||||
|
||||
if (! info.open)
|
||||
if (closed)
|
||||
{
|
||||
json[jss::closed] = true;
|
||||
}
|
||||
@@ -64,7 +64,7 @@ void fillJson(Object& json, LedgerInfo const& info, bool bFull)
|
||||
// These next three are DEPRECATED.
|
||||
json[jss::hash] = to_string (info.hash);
|
||||
json[jss::totalCoins] = to_string (info.drops);
|
||||
json[jss::accepted] = ! info.open;
|
||||
json[jss::accepted] = closed;
|
||||
json[jss::close_flags] = info.closeFlags;
|
||||
|
||||
// Always show fields that contribute to the ledger hash
|
||||
@@ -165,7 +165,7 @@ void fillJson (Object& json, LedgerFill const& fill)
|
||||
// TODO: what happens if bBinary and bExtracted are both set?
|
||||
// Is there a way to report this back?
|
||||
auto bFull = isFull(fill);
|
||||
fillJson(json, fill.ledger.info(), bFull);
|
||||
fillJson(json, !fill.ledger.open(), fill.ledger.info(), bFull);
|
||||
|
||||
if (bFull || fill.options & LedgerFill::dumpTxrp)
|
||||
fillJsonTx(json, fill);
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
//==============================================================================
|
||||
|
||||
#include <BeastConfig.h>
|
||||
#include <ripple/app/ledger/Ledger.h>
|
||||
#include <ripple/app/ledger/LocalTxs.h>
|
||||
#include <ripple/app/main/Application.h>
|
||||
#include <ripple/protocol/Indexes.h>
|
||||
@@ -120,21 +121,6 @@ public:
|
||||
m_txns.emplace_back (index, txn);
|
||||
}
|
||||
|
||||
bool can_remove (LocalTx& txn, Ledger::ref ledger)
|
||||
{
|
||||
if (txn.isExpired (ledger->info().seq))
|
||||
return true;
|
||||
if (ledger->txExists(txn.getID()))
|
||||
return true;
|
||||
auto const sle = cachedRead(*ledger,
|
||||
keylet::account(txn.getAccount()).key, ltACCOUNT_ROOT);
|
||||
if (! sle)
|
||||
return false;
|
||||
if (sle->getFieldU32 (sfSequence) > txn.getSeq ())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
CanonicalTXSet
|
||||
getTxSet () override
|
||||
{
|
||||
@@ -152,19 +138,25 @@ public:
|
||||
return tset;
|
||||
}
|
||||
|
||||
// Remove transactions that have either been accepted into a fully-validated
|
||||
// ledger, are (now) impossible, or have expired
|
||||
void sweep (Ledger::ref validLedger) override
|
||||
// Remove transactions that have either been accepted
|
||||
// into a fully-validated ledger, are (now) impossible,
|
||||
// or have expired
|
||||
void sweep (ReadView const& view) override
|
||||
{
|
||||
std::lock_guard <std::mutex> lock (m_lock);
|
||||
|
||||
for (auto it = m_txns.begin (); it != m_txns.end (); )
|
||||
m_txns.remove_if ([&view](auto const& txn)
|
||||
{
|
||||
if (can_remove (*it, validLedger))
|
||||
it = m_txns.erase (it);
|
||||
else
|
||||
++it;
|
||||
}
|
||||
if (txn.isExpired (view.info().seq))
|
||||
return true;
|
||||
if (view.txExists(txn.getID()))
|
||||
return true;
|
||||
auto const sle = cachedRead(view,
|
||||
keylet::account(txn.getAccount()).key, ltACCOUNT_ROOT);
|
||||
if (! sle)
|
||||
return false;
|
||||
return sle->getFieldU32 (sfSequence) > txn.getSeq ();
|
||||
});
|
||||
}
|
||||
|
||||
std::size_t size () override
|
||||
|
||||
@@ -925,7 +925,10 @@ private:
|
||||
void addTxnSeqField();
|
||||
void updateTables ();
|
||||
void startGenesisLedger ();
|
||||
Ledger::pointer getLastFullLedger();
|
||||
|
||||
std::shared_ptr<Ledger>
|
||||
getLastFullLedger();
|
||||
|
||||
bool loadOldLedger (
|
||||
std::string const& ledgerID, bool replay, bool isFilename);
|
||||
};
|
||||
@@ -1207,9 +1210,8 @@ ApplicationImp::startGenesisLedger()
|
||||
m_ledgerMaster->storeLedger (genesis);
|
||||
|
||||
auto const next = std::make_shared<Ledger>(
|
||||
open_ledger, *genesis, timeKeeper().closeTime());
|
||||
*genesis, timeKeeper().closeTime());
|
||||
next->updateSkipList ();
|
||||
next->setClosed ();
|
||||
next->setImmutable (*config_);
|
||||
m_networkOPs->setLastCloseTime (next->info().closeTime);
|
||||
openLedger_.emplace(next, cachedSLEs_,
|
||||
@@ -1218,49 +1220,50 @@ ApplicationImp::startGenesisLedger()
|
||||
m_ledgerMaster->switchLCL (next);
|
||||
}
|
||||
|
||||
Ledger::pointer
|
||||
std::shared_ptr<Ledger>
|
||||
ApplicationImp::getLastFullLedger()
|
||||
{
|
||||
auto j = journal ("Ledger");
|
||||
|
||||
try
|
||||
{
|
||||
Ledger::pointer ledger;
|
||||
std::uint32_t ledgerSeq;
|
||||
uint256 ledgerHash;
|
||||
std::tie (ledger, ledgerSeq, ledgerHash) =
|
||||
loadLedgerHelper ("order by LedgerSeq desc limit 1", *this);
|
||||
std::shared_ptr<Ledger> ledger;
|
||||
std::uint32_t seq;
|
||||
uint256 hash;
|
||||
|
||||
std::tie (ledger, seq, hash) =
|
||||
loadLedgerHelper (
|
||||
"order by LedgerSeq desc limit 1", *this);
|
||||
|
||||
if (!ledger)
|
||||
return ledger;
|
||||
|
||||
ledger->setClosed ();
|
||||
ledger->setImmutable(*config_);
|
||||
|
||||
if (getLedgerMaster ().haveLedger (ledgerSeq))
|
||||
if (getLedgerMaster ().haveLedger (seq))
|
||||
ledger->setValidated ();
|
||||
|
||||
if (ledger->getHash () != ledgerHash)
|
||||
if (ledger->info().hash == hash)
|
||||
{
|
||||
auto j = journal ("Ledger");
|
||||
if (j.error)
|
||||
{
|
||||
j.error << "Failed on ledger";
|
||||
Json::Value p;
|
||||
addJson (p, {*ledger, LedgerFill::full});
|
||||
j.error << p;
|
||||
}
|
||||
|
||||
assert (false);
|
||||
return Ledger::pointer ();
|
||||
JLOG (j.trace) << "Loaded ledger: " << hash;
|
||||
return ledger;
|
||||
}
|
||||
|
||||
JLOG (journal ("Ledger").trace) << "Loaded ledger: " << ledgerHash;
|
||||
return ledger;
|
||||
if (j.error)
|
||||
{
|
||||
j.error << "Failed on ledger";
|
||||
Json::Value p;
|
||||
addJson (p, {*ledger, LedgerFill::full});
|
||||
j.error << p;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
catch (SHAMapMissingNode& sn)
|
||||
{
|
||||
JLOG (journal ("Ledger").warning)
|
||||
<< "Database contains ledger with missing nodes: " << sn;
|
||||
return Ledger::pointer ();
|
||||
JLOG (j.warning) <<
|
||||
"Ledger with missing nodes in database: " << sn;
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1269,7 +1272,7 @@ bool ApplicationImp::loadOldLedger (
|
||||
{
|
||||
try
|
||||
{
|
||||
Ledger::pointer loadLedger, replayLedger;
|
||||
std::shared_ptr<Ledger> loadLedger, replayLedger;
|
||||
|
||||
if (isFileName)
|
||||
{
|
||||
@@ -1374,7 +1377,6 @@ bool ApplicationImp::loadOldLedger (
|
||||
}
|
||||
}
|
||||
|
||||
loadLedger->setClosed ();
|
||||
loadLedger->stateMap().flushDirty
|
||||
(hotACCOUNT_NODE, loadLedger->info().seq);
|
||||
loadLedger->setAccepted (closeTime,
|
||||
@@ -1446,9 +1448,9 @@ bool ApplicationImp::loadOldLedger (
|
||||
}
|
||||
}
|
||||
|
||||
loadLedger->setClosed ();
|
||||
|
||||
JLOG(m_journal.info) << "Loading ledger " << loadLedger->getHash () << " seq:" << loadLedger->info().seq;
|
||||
JLOG(m_journal.info) <<
|
||||
"Loading ledger " << loadLedger->info().hash <<
|
||||
" seq:" << loadLedger->info().seq;
|
||||
|
||||
if (loadLedger->info().accountHash.isZero ())
|
||||
{
|
||||
@@ -1471,12 +1473,13 @@ bool ApplicationImp::loadOldLedger (
|
||||
return false;
|
||||
}
|
||||
|
||||
m_ledgerMaster->setLedgerRangePresent (loadLedger->info().seq, loadLedger->info().seq);
|
||||
m_ledgerMaster->setLedgerRangePresent (
|
||||
loadLedger->info().seq,
|
||||
loadLedger->info().seq);
|
||||
|
||||
auto const openLedger =
|
||||
std::make_shared<Ledger>(open_ledger, *loadLedger, timeKeeper().closeTime());
|
||||
m_ledgerMaster->switchLCL (loadLedger);
|
||||
m_ledgerMaster->forceValid(loadLedger);
|
||||
loadLedger->setValidated();
|
||||
m_ledgerMaster->setFullLedger(loadLedger, true, false);
|
||||
m_networkOPs->setLastCloseTime (loadLedger->info().closeTime);
|
||||
openLedger_.emplace(loadLedger, cachedSLEs_,
|
||||
logs_->journal("OpenLedger"));
|
||||
|
||||
@@ -20,7 +20,8 @@
|
||||
#ifndef RIPPLE_APP_MISC_FEEVOTE_H_INCLUDED
|
||||
#define RIPPLE_APP_MISC_FEEVOTE_H_INCLUDED
|
||||
|
||||
#include <ripple/app/ledger/Ledger.h>
|
||||
#include <ripple/ledger/ReadView.h>
|
||||
#include <ripple/shamap/SHAMap.h>
|
||||
#include <ripple/app/misc/Validations.h>
|
||||
#include <ripple/basics/BasicConfig.h>
|
||||
#include <ripple/protocol/SystemParameters.h>
|
||||
@@ -60,7 +61,7 @@ public:
|
||||
*/
|
||||
virtual
|
||||
void
|
||||
doValidation (Ledger::ref lastClosedLedger,
|
||||
doValidation (std::shared_ptr<ReadView const> const& lastClosedLedger,
|
||||
STObject& baseValidation) = 0;
|
||||
|
||||
/** Cast our local vote on the fee.
|
||||
@@ -70,8 +71,9 @@ public:
|
||||
*/
|
||||
virtual
|
||||
void
|
||||
doVoting (Ledger::ref lastClosedLedger, ValidationSet const& parentValidations,
|
||||
std::shared_ptr<SHAMap> const& initialPosition) = 0;
|
||||
doVoting (std::shared_ptr<ReadView const> const& lastClosedLedger,
|
||||
ValidationSet const& parentValidations,
|
||||
std::shared_ptr<SHAMap> const& initialPosition) = 0;
|
||||
};
|
||||
|
||||
/** Build FeeVote::Setup from a config section. */
|
||||
|
||||
@@ -98,11 +98,11 @@ public:
|
||||
FeeVoteImpl (Setup const& setup, beast::Journal journal);
|
||||
|
||||
void
|
||||
doValidation (Ledger::ref lastClosedLedger,
|
||||
doValidation (std::shared_ptr<ReadView const> const& lastClosedLedger,
|
||||
STObject& baseValidation) override;
|
||||
|
||||
void
|
||||
doVoting (Ledger::ref lastClosedLedger,
|
||||
doVoting (std::shared_ptr<ReadView const> const& lastClosedLedger,
|
||||
ValidationSet const& parentValidations,
|
||||
std::shared_ptr<SHAMap> const& initialPosition) override;
|
||||
};
|
||||
@@ -116,8 +116,9 @@ FeeVoteImpl::FeeVoteImpl (Setup const& setup, beast::Journal journal)
|
||||
}
|
||||
|
||||
void
|
||||
FeeVoteImpl::doValidation (Ledger::ref lastClosedLedger,
|
||||
STObject& baseValidation)
|
||||
FeeVoteImpl::doValidation(
|
||||
std::shared_ptr<ReadView const> const& lastClosedLedger,
|
||||
STObject& baseValidation)
|
||||
{
|
||||
if (lastClosedLedger->fees().base != target_.reference_fee)
|
||||
{
|
||||
@@ -146,9 +147,10 @@ FeeVoteImpl::doValidation (Ledger::ref lastClosedLedger,
|
||||
}
|
||||
|
||||
void
|
||||
FeeVoteImpl::doVoting (Ledger::ref lastClosedLedger,
|
||||
ValidationSet const& set,
|
||||
std::shared_ptr<SHAMap> const& initialPosition)
|
||||
FeeVoteImpl::doVoting(
|
||||
std::shared_ptr<ReadView const> const& lastClosedLedger,
|
||||
ValidationSet const& set,
|
||||
std::shared_ptr<SHAMap> const& initialPosition)
|
||||
{
|
||||
// LCL must be flag ledger
|
||||
assert ((lastClosedLedger->info().seq % 256) == 0);
|
||||
|
||||
@@ -303,7 +303,7 @@ public:
|
||||
// Used for the "jump" case.
|
||||
private:
|
||||
void switchLastClosedLedger (
|
||||
Ledger::pointer newLedger, bool duringConsensus);
|
||||
std::shared_ptr<Ledger const> const& newLCL);
|
||||
bool checkLastClosedLedger (
|
||||
const Overlay::PeerSequence&, uint256& networkClosed);
|
||||
void tryStartConsensus ();
|
||||
@@ -356,9 +356,9 @@ public:
|
||||
uint256 getConsensusLCL () override;
|
||||
void reportFeeChange () override;
|
||||
|
||||
void updateLocalTx (Ledger::ref newValidLedger) override
|
||||
void updateLocalTx (ReadView const& view) override
|
||||
{
|
||||
m_localTX->sweep (newValidLedger);
|
||||
m_localTX->sweep (view);
|
||||
}
|
||||
std::size_t getLocalTxCount () override
|
||||
{
|
||||
@@ -402,7 +402,8 @@ public:
|
||||
//
|
||||
// Monitoring: publisher side.
|
||||
//
|
||||
void pubLedger (Ledger::ref lpAccepted) override;
|
||||
void pubLedger (
|
||||
std::shared_ptr<ReadView const> const& lpAccepted) override;
|
||||
void pubProposedTransaction (
|
||||
std::shared_ptr<ReadView const> const& lpCurrent,
|
||||
std::shared_ptr<STTx const> const& stTxn, TER terResult) override;
|
||||
@@ -484,9 +485,11 @@ private:
|
||||
std::shared_ptr<ReadView const> const& lpCurrent);
|
||||
|
||||
void pubValidatedTransaction (
|
||||
Ledger::ref alAccepted, const AcceptedLedgerTx& alTransaction);
|
||||
std::shared_ptr<ReadView const> const& alAccepted,
|
||||
const AcceptedLedgerTx& alTransaction);
|
||||
void pubAccountTransaction (
|
||||
std::shared_ptr<ReadView const> const& lpCurrent, const AcceptedLedgerTx& alTransaction,
|
||||
std::shared_ptr<ReadView const> const& lpCurrent,
|
||||
const AcceptedLedgerTx& alTransaction,
|
||||
bool isAccepted);
|
||||
|
||||
void pubServer ();
|
||||
@@ -1233,12 +1236,12 @@ bool NetworkOPsImp::checkLastClosedLedger (
|
||||
|
||||
JLOG(m_journal.trace) << "NetworkOPsImp::checkLastClosedLedger";
|
||||
|
||||
Ledger::pointer ourClosed = m_ledgerMaster.getClosedLedger ();
|
||||
auto const ourClosed = m_ledgerMaster.getClosedLedger ();
|
||||
|
||||
if (!ourClosed)
|
||||
return false;
|
||||
|
||||
uint256 closedLedger = ourClosed->getHash ();
|
||||
uint256 closedLedger = ourClosed->info().hash;
|
||||
uint256 prevClosedLedger = ourClosed->info().parentHash;
|
||||
JLOG(m_journal.trace) << "OurClosed: " << closedLedger;
|
||||
JLOG(m_journal.trace) << "PrevClosed: " << prevClosedLedger;
|
||||
@@ -1331,7 +1334,7 @@ bool NetworkOPsImp::checkLastClosedLedger (
|
||||
{
|
||||
// don't switch to our own previous ledger
|
||||
JLOG(m_journal.info) << "We won't switch to our own previous ledger";
|
||||
networkClosed = ourClosed->getHash ();
|
||||
networkClosed = ourClosed->info().hash;
|
||||
switchLedgers = false;
|
||||
}
|
||||
else
|
||||
@@ -1340,18 +1343,18 @@ bool NetworkOPsImp::checkLastClosedLedger (
|
||||
if (!switchLedgers)
|
||||
return false;
|
||||
|
||||
Ledger::pointer consensus = m_ledgerMaster.getLedgerByHash (closedLedger);
|
||||
auto consensus = m_ledgerMaster.getLedgerByHash (closedLedger);
|
||||
|
||||
if (!consensus)
|
||||
consensus = app_.getInboundLedgers().acquire (
|
||||
closedLedger, 0, InboundLedger::fcCONSENSUS);
|
||||
|
||||
if (consensus &&
|
||||
! m_ledgerMaster.isCompatible (consensus, m_journal.debug,
|
||||
! m_ledgerMaster.isCompatible (*consensus, m_journal.debug,
|
||||
"Not switching"))
|
||||
{
|
||||
// Don't switch to a ledger not on the validated chain
|
||||
networkClosed = ourClosed->getHash ();
|
||||
networkClosed = ourClosed->info().hash;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1369,23 +1372,20 @@ bool NetworkOPsImp::checkLastClosedLedger (
|
||||
// FIXME: If this rewinds the ledger sequence, or has the same sequence, we
|
||||
// should update the status on any stored transactions in the invalidated
|
||||
// ledgers.
|
||||
switchLastClosedLedger (consensus, false);
|
||||
switchLastClosedLedger (consensus);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NetworkOPsImp::switchLastClosedLedger (
|
||||
Ledger::pointer newLCL, bool duringConsensus)
|
||||
std::shared_ptr<Ledger const> const& newLCL)
|
||||
{
|
||||
// set the newLCL as our last closed ledger -- this is abnormal code
|
||||
|
||||
auto msg = duringConsensus ? "JUMPdc" : "JUMP";
|
||||
JLOG(m_journal.error)
|
||||
<< msg << " last closed ledger to " << newLCL->getHash ();
|
||||
JLOG(m_journal.error) <<
|
||||
"JUMP last closed ledger to " << newLCL->info().hash;
|
||||
|
||||
clearNeedNetworkLedger ();
|
||||
newLCL->setClosed ();
|
||||
|
||||
// Update fee computations.
|
||||
// TODO: Needs an open ledger
|
||||
@@ -1420,10 +1420,12 @@ void NetworkOPsImp::switchLastClosedLedger (
|
||||
s.set_newevent (protocol::neSWITCHED_LEDGER);
|
||||
s.set_ledgerseq (newLCL->info().seq);
|
||||
s.set_networktime (app_.timeKeeper().now().time_since_epoch().count());
|
||||
uint256 hash = newLCL->info().parentHash;
|
||||
s.set_ledgerhashprevious (hash.begin (), hash.size ());
|
||||
hash = newLCL->getHash ();
|
||||
s.set_ledgerhash (hash.begin (), hash.size ());
|
||||
s.set_ledgerhashprevious (
|
||||
newLCL->info().parentHash.begin (),
|
||||
newLCL->info().parentHash.size ());
|
||||
s.set_ledgerhash (
|
||||
newLCL->info().hash.begin (),
|
||||
newLCL->info().hash.size ());
|
||||
|
||||
app_.overlay ().foreach (send_always (
|
||||
std::make_shared<Message> (s, protocol::mtSTATUS_CHANGE)));
|
||||
@@ -1439,10 +1441,10 @@ bool NetworkOPsImp::beginConsensus (uint256 const& networkClosed)
|
||||
"Consensus time for #" << closingInfo.seq <<
|
||||
" with LCL " << closingInfo.parentHash;
|
||||
|
||||
auto prevLedger = m_ledgerMaster.getLedgerByHash (
|
||||
auto prevLedger = m_ledgerMaster.getLedgerByHash(
|
||||
closingInfo.parentHash);
|
||||
|
||||
if (!prevLedger)
|
||||
if(! prevLedger)
|
||||
{
|
||||
// this shouldn't happen unless we jump ledgers
|
||||
if (mMode == omFULL)
|
||||
@@ -1454,11 +1456,9 @@ bool NetworkOPsImp::beginConsensus (uint256 const& networkClosed)
|
||||
return false;
|
||||
}
|
||||
|
||||
assert (prevLedger->getHash () == closingInfo.parentHash);
|
||||
assert (prevLedger->info().hash == closingInfo.parentHash);
|
||||
assert (closingInfo.parentHash ==
|
||||
m_ledgerMaster.getClosedLedger ()->getHash ());
|
||||
|
||||
prevLedger->setImmutable (app_.config());
|
||||
m_ledgerMaster.getClosedLedger()->info().hash);
|
||||
|
||||
mConsensus->startRound (
|
||||
*mLedgerConsensus,
|
||||
@@ -1820,11 +1820,13 @@ NetworkOPs::AccountTxs NetworkOPsImp::getAccountTxs (
|
||||
{ // Work around a bug that could leave the metadata missing
|
||||
auto const seq = rangeCheckedCast<std::uint32_t>(
|
||||
ledgerSeq.value_or (0));
|
||||
JLOG(m_journal.warning) << "Recovering ledger " << seq
|
||||
<< ", txn " << txn->getID();
|
||||
Ledger::pointer ledger = m_ledgerMaster.getLedgerBySeq(seq);
|
||||
if (ledger)
|
||||
pendSaveValidated(app_, ledger, false, false);
|
||||
|
||||
JLOG(m_journal.warning) <<
|
||||
"Recovering ledger " << seq <<
|
||||
", txn " << txn->getID();
|
||||
|
||||
if (auto l = m_ledgerMaster.getLedgerBySeq(seq))
|
||||
pendSaveValidated(app_, l, false, false);
|
||||
}
|
||||
|
||||
if (txn)
|
||||
@@ -2059,12 +2061,12 @@ Json::Value NetworkOPsImp::getServerInfo (bool human, bool admin)
|
||||
}
|
||||
|
||||
bool valid = false;
|
||||
Ledger::pointer lpClosed = m_ledgerMaster.getValidatedLedger ();
|
||||
auto lpClosed = m_ledgerMaster.getValidatedLedger ();
|
||||
|
||||
if (lpClosed)
|
||||
valid = true;
|
||||
else
|
||||
lpClosed = m_ledgerMaster.getClosedLedger ();
|
||||
lpClosed = m_ledgerMaster.getClosedLedger ();
|
||||
|
||||
if (lpClosed)
|
||||
{
|
||||
@@ -2072,7 +2074,7 @@ Json::Value NetworkOPsImp::getServerInfo (bool human, bool admin)
|
||||
std::uint64_t baseRef = lpClosed->fees().units;
|
||||
Json::Value l (Json::objectValue);
|
||||
l[jss::seq] = Json::UInt (lpClosed->info().seq);
|
||||
l[jss::hash] = to_string (lpClosed->getHash ());
|
||||
l[jss::hash] = to_string (lpClosed->info().hash);
|
||||
|
||||
if (!human)
|
||||
{
|
||||
@@ -2121,8 +2123,8 @@ Json::Value NetworkOPsImp::getServerInfo (bool human, bool admin)
|
||||
else
|
||||
info[jss::closed_ledger] = l;
|
||||
|
||||
Ledger::pointer lpPublished = m_ledgerMaster.getPublishedLedger ();
|
||||
if (!lpPublished)
|
||||
auto lpPublished = m_ledgerMaster.getPublishedLedger ();
|
||||
if (! lpPublished)
|
||||
info[jss::published_ledger] = "none";
|
||||
else if (lpPublished->info().seq != lpClosed->info().seq)
|
||||
info[jss::published_ledger] = lpPublished->info().seq;
|
||||
@@ -2175,7 +2177,8 @@ void NetworkOPsImp::pubProposedTransaction (
|
||||
pubAccountTransaction (lpCurrent, alt, false);
|
||||
}
|
||||
|
||||
void NetworkOPsImp::pubLedger (Ledger::ref lpAccepted)
|
||||
void NetworkOPsImp::pubLedger (
|
||||
std::shared_ptr<ReadView const> const& lpAccepted)
|
||||
{
|
||||
// Ledgers are published only when they acquire sufficient validations
|
||||
// Holes are filled across connection loss or other catastrophe
|
||||
@@ -2199,7 +2202,7 @@ void NetworkOPsImp::pubLedger (Ledger::ref lpAccepted)
|
||||
|
||||
jvObj[jss::type] = "ledgerClosed";
|
||||
jvObj[jss::ledger_index] = lpAccepted->info().seq;
|
||||
jvObj[jss::ledger_hash] = to_string (lpAccepted->getHash ());
|
||||
jvObj[jss::ledger_hash] = to_string (lpAccepted->info().hash);
|
||||
jvObj[jss::ledger_time]
|
||||
= Json::Value::UInt (lpAccepted->info().closeTime.time_since_epoch().count());
|
||||
|
||||
@@ -2306,7 +2309,8 @@ Json::Value NetworkOPsImp::transJson(
|
||||
}
|
||||
|
||||
void NetworkOPsImp::pubValidatedTransaction (
|
||||
Ledger::ref alAccepted, const AcceptedLedgerTx& alTx)
|
||||
std::shared_ptr<ReadView const> const& alAccepted,
|
||||
const AcceptedLedgerTx& alTx)
|
||||
{
|
||||
Json::Value jvObj = transJson (
|
||||
*alTx.getTxn (), alTx.getResult (), true, alAccepted);
|
||||
@@ -2546,7 +2550,7 @@ std::uint32_t NetworkOPsImp::acceptLedger (
|
||||
|
||||
// FIXME Could we improve on this and remove the need for a specialized
|
||||
// API in LedgerConsensus?
|
||||
beginConsensus (m_ledgerMaster.getClosedLedger ()->getHash ());
|
||||
beginConsensus (m_ledgerMaster.getClosedLedger()->info().hash);
|
||||
mLedgerConsensus->simulate (consensusDelay);
|
||||
return m_ledgerMaster.getCurrentLedger ()->info().seq;
|
||||
}
|
||||
@@ -2554,12 +2558,10 @@ std::uint32_t NetworkOPsImp::acceptLedger (
|
||||
// <-- bool: true=added, false=already there
|
||||
bool NetworkOPsImp::subLedger (InfoSub::ref isrListener, Json::Value& jvResult)
|
||||
{
|
||||
Ledger::pointer lpClosed = m_ledgerMaster.getValidatedLedger ();
|
||||
|
||||
if (lpClosed)
|
||||
if (auto lpClosed = m_ledgerMaster.getValidatedLedger ())
|
||||
{
|
||||
jvResult[jss::ledger_index] = lpClosed->info().seq;
|
||||
jvResult[jss::ledger_hash] = to_string (lpClosed->getHash ());
|
||||
jvResult[jss::ledger_hash] = to_string (lpClosed->info().hash);
|
||||
jvResult[jss::ledger_time]
|
||||
= Json::Value::UInt(lpClosed->info().closeTime.time_since_epoch().count());
|
||||
jvResult[jss::fee_ref]
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <ripple/protocol/STValidation.h>
|
||||
#include <ripple/app/ledger/Ledger.h>
|
||||
#include <ripple/app/ledger/LedgerProposal.h>
|
||||
#include <ripple/ledger/ReadView.h>
|
||||
#include <ripple/net/InfoSub.h>
|
||||
#include <memory>
|
||||
#include <beast/threads/Stoppable.h>
|
||||
@@ -197,7 +198,7 @@ public:
|
||||
|
||||
virtual void reportFeeChange () = 0;
|
||||
|
||||
virtual void updateLocalTx (Ledger::ref newValidLedger) = 0;
|
||||
virtual void updateLocalTx (ReadView const& newValidLedger) = 0;
|
||||
virtual std::size_t getLocalTxCount () = 0;
|
||||
|
||||
// client information retrieval functions
|
||||
@@ -229,7 +230,8 @@ public:
|
||||
//
|
||||
// Monitoring: publisher side
|
||||
//
|
||||
virtual void pubLedger (Ledger::ref lpAccepted) = 0;
|
||||
virtual void pubLedger (
|
||||
std::shared_ptr<ReadView const> const& lpAccepted) = 0;
|
||||
virtual void pubProposedTransaction (
|
||||
std::shared_ptr<ReadView const> const& lpCurrent,
|
||||
std::shared_ptr<STTx const> const& stTxn, TER terResult) = 0;
|
||||
|
||||
@@ -54,7 +54,7 @@ public:
|
||||
SHAMapStore (Stoppable& parent) : Stoppable ("SHAMapStore", parent) {}
|
||||
|
||||
/** Called by LedgerMaster every time a ledger validates. */
|
||||
virtual void onLedgerClosed (Ledger::pointer validatedLedger) = 0;
|
||||
virtual void onLedgerClosed(std::shared_ptr<Ledger const> const& ledger) = 0;
|
||||
|
||||
virtual std::uint32_t clampFetchDepth (std::uint32_t fetch_depth) const = 0;
|
||||
|
||||
|
||||
@@ -241,11 +241,12 @@ SHAMapStoreImp::makeDatabase (std::string const& name,
|
||||
}
|
||||
|
||||
void
|
||||
SHAMapStoreImp::onLedgerClosed (Ledger::pointer validatedLedger)
|
||||
SHAMapStoreImp::onLedgerClosed(
|
||||
std::shared_ptr<Ledger const> const& ledger)
|
||||
{
|
||||
{
|
||||
std::lock_guard <std::mutex> lock (mutex_);
|
||||
newLedger_ = validatedLedger;
|
||||
newLedger_ = ledger;
|
||||
}
|
||||
cond_.notify_one();
|
||||
}
|
||||
|
||||
@@ -93,8 +93,8 @@ private:
|
||||
bool healthy_ = true;
|
||||
mutable std::condition_variable cond_;
|
||||
mutable std::mutex mutex_;
|
||||
Ledger::pointer newLedger_;
|
||||
Ledger::pointer validatedLedger_;
|
||||
std::shared_ptr<Ledger const> newLedger_;
|
||||
std::shared_ptr<Ledger const> validatedLedger_;
|
||||
TransactionMaster& transactionMaster_;
|
||||
std::atomic <LedgerIndex> canDelete_;
|
||||
// these do not exist upon SHAMapStore creation, but do exist
|
||||
@@ -158,7 +158,7 @@ public:
|
||||
return canDelete_;
|
||||
}
|
||||
|
||||
void onLedgerClosed (Ledger::pointer validatedLedger) override;
|
||||
void onLedgerClosed (std::shared_ptr<Ledger const> const& ledger) override;
|
||||
|
||||
private:
|
||||
// callback for visitNodes
|
||||
|
||||
@@ -57,9 +57,8 @@ convertBlobsToTxResult (
|
||||
void
|
||||
saveLedgerAsync (Application& app, std::uint32_t seq)
|
||||
{
|
||||
Ledger::pointer ledger = app.getLedgerMaster().getLedgerBySeq(seq);
|
||||
if (ledger)
|
||||
pendSaveValidated(app, ledger, false, false);
|
||||
if (auto l = app.getLedgerMaster().getLedgerBySeq(seq))
|
||||
pendSaveValidated(app, l, false, false);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -58,9 +58,8 @@ struct Regression_test : public beast::unit_test::suite
|
||||
auto const aliceAmount = XRP(aliceXRP);
|
||||
|
||||
auto next = std::make_shared<Ledger>(
|
||||
open_ledger, *closed,
|
||||
*closed,
|
||||
env.app().timeKeeper().closeTime());
|
||||
next->setClosed();
|
||||
{
|
||||
// Fund alice
|
||||
auto const jt = env.jt(pay(env.master, "alice", aliceAmount));
|
||||
|
||||
@@ -683,7 +683,7 @@ Transactor::operator()()
|
||||
// Transaction succeeded fully or (retries are
|
||||
// not allowed and the transaction could claim a fee)
|
||||
|
||||
if(view().closed())
|
||||
if(!view().open())
|
||||
{
|
||||
// Charge whatever fee they specified.
|
||||
|
||||
|
||||
@@ -65,6 +65,12 @@ public:
|
||||
std::shared_ptr<SLE const>
|
||||
read (Keylet const& k) const override;
|
||||
|
||||
bool
|
||||
open() const override
|
||||
{
|
||||
return base_.open();
|
||||
}
|
||||
|
||||
LedgerInfo const&
|
||||
info() const override
|
||||
{
|
||||
|
||||
@@ -66,6 +66,7 @@ private:
|
||||
ReadView const* base_;
|
||||
detail::RawStateTable items_;
|
||||
std::shared_ptr<void const> hold_;
|
||||
bool open_ = true;
|
||||
|
||||
public:
|
||||
OpenView() = delete;
|
||||
@@ -134,6 +135,13 @@ public:
|
||||
OpenView (ReadView const* base,
|
||||
std::shared_ptr<void const> hold = nullptr);
|
||||
|
||||
/** Returns true if this reflects an open ledger. */
|
||||
bool
|
||||
open() const override
|
||||
{
|
||||
return open_;
|
||||
}
|
||||
|
||||
/** Return the number of tx inserted since creation.
|
||||
|
||||
This is used to set the "apply ordinal"
|
||||
|
||||
@@ -75,7 +75,6 @@ struct LedgerInfo
|
||||
// For all ledgers
|
||||
//
|
||||
|
||||
bool open = true;
|
||||
LedgerIndex seq = 0;
|
||||
NetClock::time_point parentCloseTime = {};
|
||||
|
||||
@@ -233,18 +232,9 @@ public:
|
||||
info() const = 0;
|
||||
|
||||
/** Returns true if this reflects an open ledger. */
|
||||
virtual
|
||||
bool
|
||||
open() const
|
||||
{
|
||||
return info().open;
|
||||
}
|
||||
|
||||
/** Returns true if this reflects a closed ledger. */
|
||||
bool
|
||||
closed() const
|
||||
{
|
||||
return ! info().open;
|
||||
}
|
||||
open() const = 0;
|
||||
|
||||
/** Returns the close time of the previous ledger. */
|
||||
NetClock::time_point
|
||||
|
||||
@@ -46,6 +46,8 @@ public:
|
||||
ReadView const* base, ApplyFlags flags);
|
||||
|
||||
// ReadView
|
||||
bool
|
||||
open() const override;
|
||||
|
||||
LedgerInfo const&
|
||||
info() const override;
|
||||
|
||||
@@ -116,7 +116,7 @@ ApplyStateTable::apply (OpenView& to,
|
||||
std::make_shared<Serializer>();
|
||||
tx.add(*sTx);
|
||||
std::shared_ptr<Serializer> sMeta;
|
||||
if (to.closed())
|
||||
if (!to.open())
|
||||
{
|
||||
TxMeta meta(j);
|
||||
// VFALCO Shouldn't TxMeta ctor do this?
|
||||
|
||||
@@ -33,6 +33,12 @@ ApplyViewBase::ApplyViewBase(
|
||||
|
||||
//---
|
||||
|
||||
bool
|
||||
ApplyViewBase::open() const
|
||||
{
|
||||
return base_->open();
|
||||
}
|
||||
|
||||
LedgerInfo const&
|
||||
ApplyViewBase::info() const
|
||||
{
|
||||
|
||||
@@ -94,7 +94,6 @@ OpenView::OpenView (open_ledger_t,
|
||||
, base_ (base)
|
||||
, hold_ (std::move(hold))
|
||||
{
|
||||
info_.open = true;
|
||||
info_.validated = false;
|
||||
info_.accepted = false;
|
||||
info_.seq = base_->info().seq + 1;
|
||||
@@ -108,6 +107,7 @@ OpenView::OpenView (ReadView const* base,
|
||||
, info_ (base->info())
|
||||
, base_ (base)
|
||||
, hold_ (std::move(hold))
|
||||
, open_ (base->open())
|
||||
{
|
||||
}
|
||||
|
||||
@@ -192,18 +192,16 @@ auto
|
||||
OpenView::txsBegin() const ->
|
||||
std::unique_ptr<txs_type::iter_base>
|
||||
{
|
||||
return std::make_unique<
|
||||
txs_iter_impl>(
|
||||
closed(), txs_.cbegin());
|
||||
return std::make_unique<txs_iter_impl>(
|
||||
!open(), txs_.cbegin());
|
||||
}
|
||||
|
||||
auto
|
||||
OpenView::txsEnd() const ->
|
||||
std::unique_ptr<txs_type::iter_base>
|
||||
{
|
||||
return std::make_unique<
|
||||
txs_iter_impl>(
|
||||
closed(), txs_.cend());
|
||||
return std::make_unique<txs_iter_impl>(
|
||||
!open(), txs_.cend());
|
||||
}
|
||||
|
||||
bool
|
||||
|
||||
@@ -43,10 +43,9 @@ class SkipList_test : public beast::unit_test::suite
|
||||
for (auto i = 0; i < 1023; ++i)
|
||||
{
|
||||
auto next = std::make_shared<Ledger>(
|
||||
open_ledger, *prev,
|
||||
*prev,
|
||||
env.app().timeKeeper().closeTime());
|
||||
next->updateSkipList();
|
||||
next->setClosed();
|
||||
history.push_back(next);
|
||||
prev = next;
|
||||
}
|
||||
|
||||
@@ -155,7 +155,7 @@ class View_test
|
||||
create_genesis, config, env.app().family());
|
||||
auto const ledger =
|
||||
std::make_shared<Ledger>(
|
||||
open_ledger, *genesis,
|
||||
*genesis,
|
||||
env.app().timeKeeper().closeTime());
|
||||
wipe(*ledger);
|
||||
ReadView& v = *ledger;
|
||||
@@ -419,7 +419,7 @@ class View_test
|
||||
std::make_shared<Ledger> (
|
||||
create_genesis, config, env.app().family());
|
||||
auto const ledger = std::make_shared<Ledger>(
|
||||
open_ledger, *genesis,
|
||||
*genesis,
|
||||
env.app().timeKeeper().closeTime());
|
||||
auto setup123 = [&ledger, this]()
|
||||
{
|
||||
@@ -761,7 +761,7 @@ class View_test
|
||||
create_genesis, config, env.app().family());
|
||||
auto const ledger =
|
||||
std::make_shared<Ledger>(
|
||||
open_ledger, *genesis,
|
||||
*genesis,
|
||||
env.app().timeKeeper().closeTime());
|
||||
wipe(*ledger);
|
||||
ledger->rawInsert(sle(1));
|
||||
|
||||
@@ -2111,7 +2111,7 @@ PeerImp::getLedger (std::shared_ptr<protocol::TMGetLedger> const& m)
|
||||
|
||||
// Figure out what ledger they want
|
||||
JLOG(p_journal_.trace) << "GetLedger: Received";
|
||||
Ledger::pointer ledger;
|
||||
std::shared_ptr<Ledger const> ledger;
|
||||
|
||||
if (packet.has_ledgerhash ())
|
||||
{
|
||||
@@ -2176,10 +2176,14 @@ PeerImp::getLedger (std::shared_ptr<protocol::TMGetLedger> const& m)
|
||||
else if (packet.has_ltype () && (packet.ltype () == protocol::ltCLOSED) )
|
||||
{
|
||||
ledger = app_.getLedgerMaster ().getClosedLedger ();
|
||||
|
||||
assert(! ledger->open());
|
||||
// VFALCO ledger should never be null!
|
||||
// VFALCO How can the closed ledger be open?
|
||||
#if 0
|
||||
if (ledger && ledger->info().open)
|
||||
ledger = app_.getLedgerMaster ().getLedgerBySeq (
|
||||
ledger->info().seq - 1);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2208,7 +2212,7 @@ PeerImp::getLedger (std::shared_ptr<protocol::TMGetLedger> const& m)
|
||||
}
|
||||
|
||||
// Fill out the reply
|
||||
uint256 lHash = ledger->getHash ();
|
||||
auto const lHash = ledger->info().hash;
|
||||
reply.set_ledgerhash (lHash.begin (), lHash.size ());
|
||||
reply.set_ledgerseq (ledger->info().seq);
|
||||
reply.set_type (packet.itype ());
|
||||
@@ -2218,7 +2222,7 @@ PeerImp::getLedger (std::shared_ptr<protocol::TMGetLedger> const& m)
|
||||
// they want the ledger base data
|
||||
JLOG(p_journal_.trace) << "GetLedger: Base data";
|
||||
Serializer nData (128);
|
||||
ledger->addRaw (nData);
|
||||
addRaw(ledger->info(), nData);
|
||||
reply.add_nodes ()->set_nodedata (
|
||||
nData.getDataPtr (), nData.getLength ());
|
||||
|
||||
|
||||
@@ -140,9 +140,11 @@ buildHello (
|
||||
|
||||
auto const closedLedger = app.getLedgerMaster().getClosedLedger();
|
||||
|
||||
if (closedLedger && !closedLedger->info().open)
|
||||
assert(! closedLedger->open());
|
||||
// VFALCO There should ALWAYS be a closed ledger
|
||||
if (closedLedger)
|
||||
{
|
||||
uint256 hash = closedLedger->getHash ();
|
||||
uint256 hash = closedLedger->info().hash;
|
||||
h.set_ledgerclosed (hash.begin (), hash.size ());
|
||||
hash = closedLedger->info().parentHash;
|
||||
h.set_ledgerprevious (hash.begin (), hash.size ());
|
||||
|
||||
@@ -33,7 +33,7 @@ Json::Value doLedgerClosed (RPC::Context& context)
|
||||
|
||||
Json::Value jvResult;
|
||||
jvResult[jss::ledger_index] = ledger->info().seq;
|
||||
jvResult[jss::ledger_hash] = to_string (ledger->getHash ());
|
||||
jvResult[jss::ledger_hash] = to_string (ledger->info().hash);
|
||||
|
||||
return jvResult;
|
||||
}
|
||||
|
||||
@@ -138,7 +138,7 @@ Json::Value doTx (RPC::Context& context)
|
||||
|
||||
if (okay)
|
||||
ret[jss::validated] = isValidated (
|
||||
context, lgr->info().seq, lgr->getHash ());
|
||||
context, lgr->info().seq, lgr->info().hash);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -111,19 +111,19 @@ Status ledgerFromRequest (T& ledger, Context& context)
|
||||
if (ledger == nullptr)
|
||||
return {rpcNO_NETWORK, "InsufficientNetworkMode"};
|
||||
|
||||
assert (! ledger->info().open);
|
||||
assert (! ledger->open());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (index.empty () || index == "current")
|
||||
{
|
||||
ledger = ledgerMaster.getCurrentLedger ();
|
||||
assert (ledger->info().open);
|
||||
assert (ledger->open());
|
||||
}
|
||||
else if (index == "closed")
|
||||
{
|
||||
ledger = ledgerMaster.getClosedLedger ();
|
||||
assert (! ledger->info().open);
|
||||
assert (! ledger->open());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -148,7 +148,7 @@ Status ledgerFromRequest (T& ledger, Context& context)
|
||||
bool isValidated (LedgerMaster& ledgerMaster, ReadView const& ledger,
|
||||
Application& app)
|
||||
{
|
||||
if (ledger.info().open)
|
||||
if (ledger.open())
|
||||
return false;
|
||||
|
||||
if (ledger.info().validated)
|
||||
@@ -220,7 +220,7 @@ Status lookupLedger (
|
||||
|
||||
auto& info = ledger->info();
|
||||
|
||||
if (!info.open)
|
||||
if (!ledger->open())
|
||||
{
|
||||
result[jss::ledger_hash] = to_string (info.hash);
|
||||
result[jss::ledger_index] = info.seq;
|
||||
|
||||
@@ -82,7 +82,7 @@ private:
|
||||
Family& f_;
|
||||
beast::Journal journal_;
|
||||
std::uint32_t seq_;
|
||||
std::uint32_t ledgerSeq_; // sequence number of ledger this is part of
|
||||
std::uint32_t ledgerSeq_ = 0; // sequence number of ledger this is part of
|
||||
std::shared_ptr<SHAMapAbstractNode> root_;
|
||||
SHAMapState state_;
|
||||
SHAMapType type_;
|
||||
@@ -131,7 +131,14 @@ public:
|
||||
// Returns a new map that's a snapshot of this one.
|
||||
// Handles copy on write for mutable snapshots.
|
||||
std::shared_ptr<SHAMap> snapShot (bool isMutable) const;
|
||||
|
||||
/* Sets metadata associated with the SHAMap
|
||||
|
||||
Marked `const` because the data is not part of
|
||||
the map contents.
|
||||
*/
|
||||
void setLedgerSeq (std::uint32_t lseq);
|
||||
|
||||
bool fetchRoot (SHAMapHash const& hash, SHAMapSyncFilter * filter);
|
||||
|
||||
// normal hash access functions
|
||||
@@ -198,7 +205,7 @@ public:
|
||||
|
||||
using fetchPackEntry_t = std::pair <uint256, Blob>;
|
||||
|
||||
void getFetchPack (SHAMap * have, bool includeLeaves, int max,
|
||||
void getFetchPack (SHAMap const* have, bool includeLeaves, int max,
|
||||
std::function<void (SHAMapHash const&, const Blob&)>) const;
|
||||
|
||||
void setUnbacked ();
|
||||
@@ -211,7 +218,7 @@ private:
|
||||
using DeltaRef = std::pair<std::shared_ptr<SHAMapItem const> const&,
|
||||
std::shared_ptr<SHAMapItem const> const&>;
|
||||
|
||||
void visitDifferences(SHAMap* have, std::function<bool(SHAMapAbstractNode&)>) const;
|
||||
void visitDifferences(SHAMap const* have, std::function<bool(SHAMapAbstractNode&)>) const;
|
||||
int unshare ();
|
||||
|
||||
// tree node cache operations
|
||||
|
||||
@@ -31,7 +31,6 @@ SHAMap::SHAMap (
|
||||
: f_ (f)
|
||||
, journal_(f.journal())
|
||||
, seq_ (seq)
|
||||
, ledgerSeq_ (0)
|
||||
, state_ (SHAMapState::Modifying)
|
||||
, type_ (t)
|
||||
{
|
||||
@@ -47,7 +46,6 @@ SHAMap::SHAMap (
|
||||
: f_ (f)
|
||||
, journal_(f.journal())
|
||||
, seq_ (1)
|
||||
, ledgerSeq_ (0)
|
||||
, state_ (SHAMapState::Synching)
|
||||
, type_ (t)
|
||||
{
|
||||
|
||||
@@ -671,7 +671,7 @@ SHAMap::hasLeafNode (uint256 const& tag, SHAMapHash const& targetNodeHash) const
|
||||
Note: a caller should set includeLeaves to false for transaction trees.
|
||||
There's no point in including the leaves of transaction trees.
|
||||
*/
|
||||
void SHAMap::getFetchPack (SHAMap* have, bool includeLeaves, int max,
|
||||
void SHAMap::getFetchPack (SHAMap const* have, bool includeLeaves, int max,
|
||||
std::function<void (SHAMapHash const&, const Blob&)> func) const
|
||||
{
|
||||
visitDifferences (have,
|
||||
@@ -691,7 +691,7 @@ void SHAMap::getFetchPack (SHAMap* have, bool includeLeaves, int max,
|
||||
}
|
||||
|
||||
void
|
||||
SHAMap::visitDifferences(SHAMap* have,
|
||||
SHAMap::visitDifferences(SHAMap const* have,
|
||||
std::function<bool (SHAMapAbstractNode&)> func) const
|
||||
{
|
||||
// Visit every node in this SHAMap that is not present
|
||||
|
||||
Reference in New Issue
Block a user