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:
Nik Bougalis
2016-02-21 16:56:18 -05:00
parent 77a4218a9e
commit 34e85ccb62
50 changed files with 788 additions and 782 deletions

View File

@@ -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