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:
JoelKatz
2012-06-08 05:09:23 -07:00
parent 261b34e0c3
commit 4b79e7dca8
4 changed files with 116 additions and 9 deletions

53
src/CanonicalTXSet.cpp Normal file
View 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
View 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

View File

@@ -577,7 +577,7 @@ void LedgerConsensus::Saccept(boost::shared_ptr<LedgerConsensus> This, SHAMap::p
} }
void LedgerConsensus::applyTransactions(SHAMap::pointer set, Ledger::pointer ledger, void LedgerConsensus::applyTransactions(SHAMap::pointer set, Ledger::pointer ledger,
std::list<SerializedTransaction::pointer>& failedTransactions) CanonicalTXSet& failedTransactions)
{ {
TransactionEngine engine(ledger); TransactionEngine engine(ledger);
@@ -620,16 +620,17 @@ void LedgerConsensus::applyTransactions(SHAMap::pointer set, Ledger::pointer led
do do
{ {
successes = 0; successes = 0;
std::list<SerializedTransaction::pointer>::iterator it = failedTransactions.begin(); CanonicalTXSet::iterator it = failedTransactions.begin();
while (it != failedTransactions.end()) while (it != failedTransactions.end())
{ {
try 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)
{ {
if (result == 0) ++successes; if (result == 0) ++successes;
failedTransactions.erase(it++); failedTransactions.eraseInc(it);
} }
else else
{ {
@@ -639,7 +640,7 @@ void LedgerConsensus::applyTransactions(SHAMap::pointer set, Ledger::pointer led
catch (...) catch (...)
{ {
Log(lsWARNING) << " Throws"; Log(lsWARNING) << " Throws";
failedTransactions.erase(it++); failedTransactions.eraseInc(it);
} }
} }
} while (successes > 0); } while (successes > 0);
@@ -665,7 +666,7 @@ void LedgerConsensus::accept(SHAMap::pointer set)
} }
#endif #endif
std::list<SerializedTransaction::pointer> failedTransactions; CanonicalTXSet failedTransactions(set->getHash());
applyTransactions(set, newLCL, failedTransactions); applyTransactions(set, newLCL, failedTransactions);
newLCL->setClosed(); newLCL->setClosed();
newLCL->setAccepted(); newLCL->setAccepted();
@@ -703,8 +704,7 @@ void LedgerConsensus::accept(SHAMap::pointer set)
ScopedLock sl = theApp->getMasterLedger().getLock(); ScopedLock sl = theApp->getMasterLedger().getLock();
applyTransactions(theApp->getMasterLedger().getCurrentLedger()->peekTransactionMap(), applyTransactions(theApp->getMasterLedger().getCurrentLedger()->peekTransactionMap(), newOL, failedTransactions);
newOL, failedTransactions);
theApp->getMasterLedger().pushLedger(newLCL, newOL); theApp->getMasterLedger().pushLedger(newLCL, newOL);
mState = lcsACCEPTED; mState = lcsACCEPTED;

View File

@@ -12,6 +12,7 @@
#include "LedgerAcquire.h" #include "LedgerAcquire.h"
#include "LedgerProposal.h" #include "LedgerProposal.h"
#include "Peer.h" #include "Peer.h"
#include "CanonicalTXSet.h"
class TransactionAcquire : public PeerSet, public boost::enable_shared_from_this<TransactionAcquire> class TransactionAcquire : public PeerSet, public boost::enable_shared_from_this<TransactionAcquire>
{ // A transaction set we are trying to acquire { // A transaction set we are trying to acquire
@@ -113,7 +114,7 @@ protected:
void removePosition(LedgerProposal&, bool ours); void removePosition(LedgerProposal&, bool ours);
void sendHaveTxSet(const uint256& set, bool direct); void sendHaveTxSet(const uint256& set, bool direct);
void applyTransactions(SHAMap::pointer transactionSet, Ledger::pointer targetLedger, void applyTransactions(SHAMap::pointer transactionSet, Ledger::pointer targetLedger,
std::list<SerializedTransaction::pointer>& failedTransactions); CanonicalTXSet& failedTransactions);
// manipulating our own position // manipulating our own position
void takeInitialPosition(Ledger::pointer initialLedger); void takeInitialPosition(Ledger::pointer initialLedger);