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();
}
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();
});
}
@ -926,7 +925,7 @@ bool PeerServer::sync(BlockChain& _bc, TransactionQueue& _tq, Overlay& _o)
{
for (auto it = m_incomingTransactions.begin(); it != m_incomingTransactions.end(); ++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
m_transactionsSent.insert(sha3(*it)); // if we already had the transaction, then don't bother sending it on.
m_incomingTransactions.clear();

44
libethereum/State.cpp

@ -288,31 +288,41 @@ bool State::sync(TransactionQueue& _tq)
// TRANSACTIONS
bool ret = false;
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.
try
if (!m_transactionSet.count(i.first))
{
execute(i.second);
ret = true;
}
catch (InvalidNonce const& in)
{
if (in.required > in.candidate)
// don't have it yet! Execute it now.
try
{
execute(i.second);
ret = true;
_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);
ret = true;
}
}
catch (std::exception const&)
{
// Something else went wrong - drop it.
_tq.drop(i.first);
ret = true;
}
}
}
return ret;

17
libethereum/TransactionQueue.cpp

@ -51,3 +51,20 @@ bool TransactionQueue::import(bytes const& _block)
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); }
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; }
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); }
private:
std::map<h256, bytes> m_data; ///< the queue.
std::map<h256, bytes> m_data; ///< Map of SHA3(tx) to tx.
Transactions m_interestQueue;
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