mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
New canonical transaction order code. Tested and working.
CanonicalTXSet acts much like a map, but sorts the transactions in a simple order that makes them take fewer passed.
This commit is contained in:
53
src/CanonicalTXSet.cpp
Normal file
53
src/CanonicalTXSet.cpp
Normal file
@@ -0,0 +1,53 @@
|
||||
|
||||
#include "CanonicalTXSet.h"
|
||||
|
||||
bool CanonicalTXKey::operator<(const CanonicalTXKey& key) const
|
||||
{
|
||||
if (mAccount < key.mAccount) return true;
|
||||
if (mAccount > key.mAccount) return false;
|
||||
if (mSeq < key.mSeq) return true;
|
||||
if (mSeq > key.mSeq) return false;
|
||||
return mTXid < key.mTXid;
|
||||
}
|
||||
|
||||
bool CanonicalTXKey::operator>(const CanonicalTXKey& key) const
|
||||
{
|
||||
if (mAccount > key.mAccount) return true;
|
||||
if (mAccount < key.mAccount) return false;
|
||||
if (mSeq > key.mSeq) return true;
|
||||
if (mSeq < key.mSeq) return false;
|
||||
return mTXid > key.mTXid;
|
||||
}
|
||||
|
||||
bool CanonicalTXKey::operator<=(const CanonicalTXKey& key) const
|
||||
{
|
||||
if (mAccount < key.mAccount) return true;
|
||||
if (mAccount > key.mAccount) return false;
|
||||
if (mSeq < key.mSeq) return true;
|
||||
if (mSeq > key.mSeq) return false;
|
||||
return mTXid <= key.mTXid;
|
||||
}
|
||||
|
||||
bool CanonicalTXKey::operator>=(const CanonicalTXKey& key)const
|
||||
{
|
||||
if (mAccount > key.mAccount) return true;
|
||||
if (mAccount < key.mAccount) return false;
|
||||
if (mSeq > key.mSeq) return true;
|
||||
if (mSeq < key.mSeq) return false;
|
||||
return mTXid >= key.mTXid;
|
||||
}
|
||||
|
||||
void CanonicalTXSet::push_back(SerializedTransaction::pointer txn)
|
||||
{
|
||||
uint256 effectiveAccount = mSetHash;
|
||||
effectiveAccount ^= txn->getSourceAccount().getAccountID().to256();
|
||||
mMap.insert(std::make_pair(CanonicalTXKey(effectiveAccount, txn->getSequence(), txn->getTransactionID()), txn));
|
||||
}
|
||||
|
||||
void CanonicalTXSet::eraseInc(iterator& it)
|
||||
{
|
||||
iterator tmp = it++;
|
||||
mMap.erase(tmp);
|
||||
}
|
||||
|
||||
|
||||
53
src/CanonicalTXSet.h
Normal file
53
src/CanonicalTXSet.h
Normal file
@@ -0,0 +1,53 @@
|
||||
#ifndef __CANONICAL_TX_SET_
|
||||
#define __CANONICAL_TX_SET_
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "uint256.h"
|
||||
#include "SerializedTransaction.h"
|
||||
|
||||
class CanonicalTXKey
|
||||
{
|
||||
protected:
|
||||
uint256 mAccount, mTXid;
|
||||
uint32 mSeq;
|
||||
|
||||
public:
|
||||
CanonicalTXKey(const uint256& account, uint32 seq, const uint256& id)
|
||||
: mAccount(account), mTXid(id), mSeq(seq) { ; }
|
||||
|
||||
bool operator<(const CanonicalTXKey&) const;
|
||||
bool operator>(const CanonicalTXKey&) const;
|
||||
bool operator<=(const CanonicalTXKey&) const;
|
||||
bool operator>=(const CanonicalTXKey&) const;
|
||||
|
||||
bool operator==(const CanonicalTXKey& k) const { return mTXid == k.mTXid; }
|
||||
bool operator!=(const CanonicalTXKey& k) const { return mTXid != k.mTXid; }
|
||||
};
|
||||
|
||||
class CanonicalTXSet
|
||||
{
|
||||
public:
|
||||
typedef std::map<CanonicalTXKey, SerializedTransaction::pointer>::iterator iterator;
|
||||
typedef std::map<CanonicalTXKey, SerializedTransaction::pointer>::const_iterator const_iterator;
|
||||
|
||||
protected:
|
||||
uint256 mSetHash;
|
||||
std::map<CanonicalTXKey, SerializedTransaction::pointer> mMap;
|
||||
|
||||
public:
|
||||
CanonicalTXSet(const uint256& lclHash) : mSetHash(lclHash) { ; }
|
||||
|
||||
void push_back(SerializedTransaction::pointer txn);
|
||||
void erase(const iterator& it) { mMap.erase(it); }
|
||||
void eraseInc(iterator& it);
|
||||
|
||||
iterator begin() { return mMap.begin(); }
|
||||
iterator end() { return mMap.end(); }
|
||||
const_iterator begin() const { return mMap.begin(); }
|
||||
const_iterator end() const { return mMap.end(); }
|
||||
size_t size() const { return mMap.size(); }
|
||||
bool empty() const { return mMap.empty(); }
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -577,7 +577,7 @@ void LedgerConsensus::Saccept(boost::shared_ptr<LedgerConsensus> This, SHAMap::p
|
||||
}
|
||||
|
||||
void LedgerConsensus::applyTransactions(SHAMap::pointer set, Ledger::pointer ledger,
|
||||
std::list<SerializedTransaction::pointer>& failedTransactions)
|
||||
CanonicalTXSet& failedTransactions)
|
||||
{
|
||||
TransactionEngine engine(ledger);
|
||||
|
||||
@@ -620,16 +620,17 @@ void LedgerConsensus::applyTransactions(SHAMap::pointer set, Ledger::pointer led
|
||||
do
|
||||
{
|
||||
successes = 0;
|
||||
std::list<SerializedTransaction::pointer>::iterator it = failedTransactions.begin();
|
||||
CanonicalTXSet::iterator it = failedTransactions.begin();
|
||||
while (it != failedTransactions.end())
|
||||
{
|
||||
try
|
||||
{
|
||||
TransactionEngineResult result = engine.applyTransaction(**it, tepNO_CHECK_FEE | tepUPDATE_TOTAL, 0);
|
||||
TransactionEngineResult result =
|
||||
engine.applyTransaction(*it->second, tepNO_CHECK_FEE | tepUPDATE_TOTAL, 0);
|
||||
if (result <= 0)
|
||||
{
|
||||
if (result == 0) ++successes;
|
||||
failedTransactions.erase(it++);
|
||||
failedTransactions.eraseInc(it);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -639,7 +640,7 @@ void LedgerConsensus::applyTransactions(SHAMap::pointer set, Ledger::pointer led
|
||||
catch (...)
|
||||
{
|
||||
Log(lsWARNING) << " Throws";
|
||||
failedTransactions.erase(it++);
|
||||
failedTransactions.eraseInc(it);
|
||||
}
|
||||
}
|
||||
} while (successes > 0);
|
||||
@@ -665,7 +666,7 @@ void LedgerConsensus::accept(SHAMap::pointer set)
|
||||
}
|
||||
#endif
|
||||
|
||||
std::list<SerializedTransaction::pointer> failedTransactions;
|
||||
CanonicalTXSet failedTransactions(set->getHash());
|
||||
applyTransactions(set, newLCL, failedTransactions);
|
||||
newLCL->setClosed();
|
||||
newLCL->setAccepted();
|
||||
@@ -703,8 +704,7 @@ void LedgerConsensus::accept(SHAMap::pointer set)
|
||||
|
||||
ScopedLock sl = theApp->getMasterLedger().getLock();
|
||||
|
||||
applyTransactions(theApp->getMasterLedger().getCurrentLedger()->peekTransactionMap(),
|
||||
newOL, failedTransactions);
|
||||
applyTransactions(theApp->getMasterLedger().getCurrentLedger()->peekTransactionMap(), newOL, failedTransactions);
|
||||
theApp->getMasterLedger().pushLedger(newLCL, newOL);
|
||||
mState = lcsACCEPTED;
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "LedgerAcquire.h"
|
||||
#include "LedgerProposal.h"
|
||||
#include "Peer.h"
|
||||
#include "CanonicalTXSet.h"
|
||||
|
||||
class TransactionAcquire : public PeerSet, public boost::enable_shared_from_this<TransactionAcquire>
|
||||
{ // A transaction set we are trying to acquire
|
||||
@@ -113,7 +114,7 @@ protected:
|
||||
void removePosition(LedgerProposal&, bool ours);
|
||||
void sendHaveTxSet(const uint256& set, bool direct);
|
||||
void applyTransactions(SHAMap::pointer transactionSet, Ledger::pointer targetLedger,
|
||||
std::list<SerializedTransaction::pointer>& failedTransactions);
|
||||
CanonicalTXSet& failedTransactions);
|
||||
|
||||
// manipulating our own position
|
||||
void takeInitialPosition(Ledger::pointer initialLedger);
|
||||
|
||||
Reference in New Issue
Block a user