Browse Source

Avoid reprocessing future transactions until it's possible they're

valid.
cl-refactor
Gav Wood 11 years ago
parent
commit
7e38de2710
  1. 5
      libethereum/PeerNetwork.cpp
  2. 44
      libethereum/State.cpp
  3. 17
      libethereum/TransactionQueue.cpp
  4. 6
      libethereum/TransactionQueue.h

5
libethereum/PeerNetwork.cpp

@ -830,9 +830,8 @@ void PeerServer::ensureAccepting()
{ {
clog(NetWarn) << "ERROR: " << _e.what(); clog(NetWarn) << "ERROR: " << _e.what();
} }
m_accepting = false; m_accepting = false;
if (m_mode == NodeMode::PeerServer || m_peers.size() < m_idealPeerCount * 2) if (ec.value() != 1 && m_mode == NodeMode::PeerServer || m_peers.size() < m_idealPeerCount * 2)
ensureAccepting(); ensureAccepting();
}); });
} }
@ -926,7 +925,7 @@ bool PeerServer::sync(BlockChain& _bc, TransactionQueue& _tq, Overlay& _o)
{ {
for (auto it = m_incomingTransactions.begin(); it != m_incomingTransactions.end(); ++it) for (auto it = m_incomingTransactions.begin(); it != m_incomingTransactions.end(); ++it)
if (_tq.import(*it)) if (_tq.import(*it))
ret = true; {}//ret = true; // just putting a transaction in the queue isn't enough to change the state - it might have an invalid nonce...
else else
m_transactionsSent.insert(sha3(*it)); // if we already had the transaction, then don't bother sending it on. m_transactionsSent.insert(sha3(*it)); // if we already had the transaction, then don't bother sending it on.
m_incomingTransactions.clear(); m_incomingTransactions.clear();

44
libethereum/State.cpp

@ -288,31 +288,41 @@ bool State::sync(TransactionQueue& _tq)
// TRANSACTIONS // TRANSACTIONS
bool ret = false; bool ret = false;
auto ts = _tq.transactions(); auto ts = _tq.transactions();
for (auto const& i: ts) vector<pair<h256, bytes>> futures;
for (int goodTxs = 1; goodTxs;)
{ {
if (!m_transactionSet.count(i.first)) goodTxs = 0;
for (auto const& i: ts)
{ {
// don't have it yet! Execute it now. if (!m_transactionSet.count(i.first))
try
{ {
execute(i.second); // don't have it yet! Execute it now.
ret = true; try
} {
catch (InvalidNonce const& in) execute(i.second);
{ ret = true;
if (in.required > in.candidate) _tq.noteGood(i);
++goodTxs;
}
catch (InvalidNonce const& in)
{
if (in.required > in.candidate)
{
// too old
_tq.drop(i.first);
ret = true;
}
else
_tq.setFuture(i);
}
catch (std::exception const&)
{ {
// too old // Something else went wrong - drop it.
_tq.drop(i.first); _tq.drop(i.first);
ret = true; ret = true;
} }
} }
catch (std::exception const&)
{
// Something else went wrong - drop it.
_tq.drop(i.first);
ret = true;
}
} }
} }
return ret; return ret;

17
libethereum/TransactionQueue.cpp

@ -51,3 +51,20 @@ bool TransactionQueue::import(bytes const& _block)
return true; return true;
} }
void TransactionQueue::setFuture(std::pair<h256, bytes> const& _t)
{
if (m_data.count(_t.first))
{
m_data.erase(_t.first);
m_future.insert(make_pair(Transaction(_t.second).sender(), _t));
}
}
void TransactionQueue::noteGood(std::pair<h256, bytes> const& _t)
{
auto r = m_future.equal_range(Transaction(_t.second).sender());
for (auto it = r.first; it != r.second; ++it)
m_data.insert(_t);
m_future.erase(r.first);
}

6
libethereum/TransactionQueue.h

@ -40,14 +40,18 @@ public:
void drop(h256 _txHash) { m_data.erase(_txHash); } void drop(h256 _txHash) { m_data.erase(_txHash); }
std::map<h256, bytes> const& transactions() const { return m_data; } std::map<h256, bytes> const& transactions() const { return m_data; }
void setFuture(std::pair<h256, bytes> const& _t);
void noteGood(std::pair<h256, bytes> const& _t);
Transactions interestQueue() { Transactions ret; swap(ret, m_interestQueue); return ret; } Transactions interestQueue() { Transactions ret; swap(ret, m_interestQueue); return ret; }
void pushInterest(Address _a) { m_interest[_a]++; } void pushInterest(Address _a) { m_interest[_a]++; }
void popInterest(Address _a) { if (m_interest[_a] > 1) m_interest[_a]--; else if (m_interest[_a]) m_interest.erase(_a); } void popInterest(Address _a) { if (m_interest[_a] > 1) m_interest[_a]--; else if (m_interest[_a]) m_interest.erase(_a); }
private: private:
std::map<h256, bytes> m_data; ///< the queue. std::map<h256, bytes> m_data; ///< Map of SHA3(tx) to tx.
Transactions m_interestQueue; Transactions m_interestQueue;
std::map<Address, int> m_interest; std::map<Address, int> m_interest;
std::multimap<Address, std::pair<h256, bytes>> m_future; ///< For transactions that have a future nonce; we map their sender address to the tx stuff, and insert once the sender has a valid TX.
}; };
} }

Loading…
Cancel
Save