mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Bugfixes to consensus:
1) Don't apply to new open ledger in final mode. 2) Re-apply any NO transactions to the new open ledger.
This commit is contained in:
@@ -155,23 +155,10 @@ void LCTransaction::setVote(const uint160& peer, bool votesYes)
|
||||
|
||||
bool LCTransaction::updatePosition(int seconds)
|
||||
{ // this many seconds after close, should our position change
|
||||
#ifdef LC_DEBUG
|
||||
Log(lsTRACE) << "Checking our position on " << mTransactionID.GetHex();
|
||||
#endif
|
||||
if (mOurPosition && (mNays == 0))
|
||||
{
|
||||
#ifdef LC_DEBUG
|
||||
Log(lsTRACE) << "YES and no NOs";
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
if (!mOurPosition && (mYays == 0))
|
||||
{
|
||||
#ifdef LC_DEBUG
|
||||
Log(lsTRACE) << "NO and no YESes";
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
// This is basically the percentage of nodes voting 'yes' (including us)
|
||||
int weight = (mYays * 100 + (mOurPosition ? 100 : 0)) / (mNays + mYays + 1);
|
||||
@@ -431,10 +418,6 @@ bool LedgerConsensus::updateOurPositions(int sinceClose)
|
||||
SHAMap::pointer ourPosition;
|
||||
std::vector<uint256> addedTx, removedTx;
|
||||
|
||||
|
||||
#ifdef LC_DEBUG
|
||||
Log(lsTRACE) << "updating our positions";
|
||||
#endif
|
||||
for(boost::unordered_map<uint256, LCTransaction::pointer>::iterator it = mDisputes.begin(),
|
||||
end = mDisputes.end(); it != end; ++it)
|
||||
{
|
||||
@@ -643,9 +626,44 @@ void LedgerConsensus::Saccept(boost::shared_ptr<LedgerConsensus> This, SHAMap::p
|
||||
This->accept(txSet);
|
||||
}
|
||||
|
||||
void LedgerConsensus::applyTransactions(SHAMap::pointer set, Ledger::pointer ledger,
|
||||
CanonicalTXSet& failedTransactions)
|
||||
void LedgerConsensus::applyTransaction(TransactionEngine& engine, SerializedTransaction::pointer txn,
|
||||
Ledger::pointer ledger, CanonicalTXSet& failedTransactions, bool final)
|
||||
{
|
||||
TransactionEngineParams parms = final ? (tepNO_CHECK_FEE | tepUPDATE_TOTAL) : tepNONE;
|
||||
#ifndef TRUST_NETWORK
|
||||
try
|
||||
{
|
||||
#endif
|
||||
TransactionEngineResult result = engine.applyTransaction(*txn, parms, 0);
|
||||
if (result > 0)
|
||||
{
|
||||
Log(lsINFO) << " retry";
|
||||
assert(!ledger->hasTransaction(txn->getTransactionID()));
|
||||
failedTransactions.push_back(txn);
|
||||
}
|
||||
else if (result == 0)
|
||||
{
|
||||
Log(lsDEBUG) << " success";
|
||||
assert(ledger->hasTransaction(txn->getTransactionID()));
|
||||
}
|
||||
else
|
||||
{
|
||||
Log(lsINFO) << " hard fail";
|
||||
assert(!ledger->hasTransaction(txn->getTransactionID()));
|
||||
}
|
||||
#ifndef TRUST_NETWORK
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
Log(lsWARNING) << " Throws";
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void LedgerConsensus::applyTransactions(SHAMap::pointer set, Ledger::pointer ledger,
|
||||
CanonicalTXSet& failedTransactions, bool final)
|
||||
{
|
||||
TransactionEngineParams parms = final ? (tepNO_CHECK_FEE | tepUPDATE_TOTAL) : tepNONE;
|
||||
TransactionEngine engine(ledger);
|
||||
|
||||
for (SHAMapItem::pointer item = set->peekFirstItem(); !!item; item = set->peekNextItem(item->getTag()))
|
||||
@@ -657,23 +675,7 @@ void LedgerConsensus::applyTransactions(SHAMap::pointer set, Ledger::pointer led
|
||||
#endif
|
||||
SerializerIterator sit(item->peekSerializer());
|
||||
SerializedTransaction::pointer txn = boost::make_shared<SerializedTransaction>(boost::ref(sit));
|
||||
TransactionEngineResult result = engine.applyTransaction(*txn, tepNO_CHECK_FEE | tepUPDATE_TOTAL, 0);
|
||||
if (result > 0)
|
||||
{
|
||||
Log(lsINFO) << " retry";
|
||||
assert(!ledger->hasTransaction(item->getTag()));
|
||||
failedTransactions.push_back(txn);
|
||||
}
|
||||
else if (result == 0)
|
||||
{
|
||||
Log(lsDEBUG) << " success";
|
||||
assert(ledger->hasTransaction(item->getTag()));
|
||||
}
|
||||
else
|
||||
{
|
||||
Log(lsINFO) << " hard fail";
|
||||
assert(!ledger->hasTransaction(item->getTag()));
|
||||
}
|
||||
applyTransaction(engine, txn, ledger, failedTransactions, final);
|
||||
#ifndef TRUST_NETWORK
|
||||
}
|
||||
catch (...)
|
||||
@@ -692,8 +694,7 @@ void LedgerConsensus::applyTransactions(SHAMap::pointer set, Ledger::pointer led
|
||||
{
|
||||
try
|
||||
{
|
||||
TransactionEngineResult result =
|
||||
engine.applyTransaction(*it->second, tepNO_CHECK_FEE | tepUPDATE_TOTAL, 0);
|
||||
TransactionEngineResult result = engine.applyTransaction(*it->second, parms, 0);
|
||||
if (result <= 0)
|
||||
{
|
||||
if (result == 0) ++successes;
|
||||
@@ -734,11 +735,12 @@ void LedgerConsensus::accept(SHAMap::pointer set)
|
||||
#endif
|
||||
|
||||
CanonicalTXSet failedTransactions(set->getHash());
|
||||
applyTransactions(set, newLCL, failedTransactions);
|
||||
applyTransactions(set, newLCL, failedTransactions, true);
|
||||
newLCL->setClosed();
|
||||
newLCL->setAccepted();
|
||||
newLCL->updateHash();
|
||||
uint256 newLCLHash = newLCL->getHash();
|
||||
Log(lsTRACE) << "newLCL " << newLCLHash.GetHex();
|
||||
|
||||
#ifdef DEBUG
|
||||
if (1)
|
||||
@@ -770,8 +772,29 @@ void LedgerConsensus::accept(SHAMap::pointer set)
|
||||
#endif
|
||||
|
||||
ScopedLock sl = theApp->getMasterLedger().getLock();
|
||||
applyTransactions(theApp->getMasterLedger().getCurrentLedger()->peekTransactionMap(), newOL, failedTransactions);
|
||||
// FIXME: Apply disputed transactions not voted into the candidate set
|
||||
|
||||
// Apply disputed transactions that didn't get in
|
||||
TransactionEngine engine(newOL);
|
||||
for (boost::unordered_map<uint256, LCTransaction::pointer>::iterator it = mDisputes.begin(),
|
||||
end = mDisputes.end(); it != end; ++it)
|
||||
{
|
||||
if (!it->second->getOurPosition())
|
||||
{ // we voted NO
|
||||
try
|
||||
{
|
||||
SerializerIterator sit(it->second->peekTransaction());
|
||||
SerializedTransaction::pointer txn = boost::make_shared<SerializedTransaction>(boost::ref(sit));
|
||||
applyTransaction(engine, txn, newOL, failedTransactions, false);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
Log(lsINFO) << "Failed to apply transaction we voted NO on";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
applyTransactions(theApp->getMasterLedger().getCurrentLedger()->peekTransactionMap(), newOL,
|
||||
failedTransactions, false);
|
||||
theApp->getMasterLedger().pushLedger(newLCL, newOL);
|
||||
mState = lcsACCEPTED;
|
||||
sl.unlock();
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "LedgerProposal.h"
|
||||
#include "Peer.h"
|
||||
#include "CanonicalTXSet.h"
|
||||
#include "TransactionEngine.h"
|
||||
|
||||
class TransactionAcquire : public PeerSet, public boost::enable_shared_from_this<TransactionAcquire>
|
||||
{ // A transaction set we are trying to acquire
|
||||
@@ -47,7 +48,7 @@ protected:
|
||||
uint256 mTransactionID;
|
||||
int mYays, mNays;
|
||||
bool mOurPosition;
|
||||
std::vector<unsigned char> transaction;
|
||||
Serializer transaction;
|
||||
boost::unordered_map<uint160, bool> mVotes;
|
||||
|
||||
public:
|
||||
@@ -58,7 +59,7 @@ public:
|
||||
|
||||
const uint256& getTransactionID() const { return mTransactionID; }
|
||||
bool getOurPosition() const { return mOurPosition; }
|
||||
const std::vector<unsigned char>& peekTransaction() { return transaction; }
|
||||
Serializer& peekTransaction() { return transaction; }
|
||||
|
||||
void setVote(const uint160& peer, bool votesYes);
|
||||
|
||||
@@ -115,7 +116,9 @@ protected:
|
||||
void removePosition(LedgerProposal&, bool ours);
|
||||
void sendHaveTxSet(const uint256& set, bool direct);
|
||||
void applyTransactions(SHAMap::pointer transactionSet, Ledger::pointer targetLedger,
|
||||
CanonicalTXSet& failedTransactions);
|
||||
CanonicalTXSet& failedTransactions, bool final);
|
||||
void applyTransaction(TransactionEngine& engine, SerializedTransaction::pointer txn, Ledger::pointer targetLedger,
|
||||
CanonicalTXSet& failedTransactions, bool final);
|
||||
|
||||
// manipulating our own position
|
||||
void takeInitialPosition(Ledger::pointer initialLedger);
|
||||
|
||||
Reference in New Issue
Block a user