Browse Source

Fixed block buffer issue.

cl-refactor
Gav Wood 11 years ago
parent
commit
2d37f0151d
  1. 2
      libethcore/CommonEth.cpp
  2. 2
      libethential/Common.cpp
  3. 1
      libethereum/BlockChain.cpp
  4. 25
      libethereum/BlockQueue.cpp
  5. 7
      libethereum/BlockQueue.h

2
libethcore/CommonEth.cpp

@ -29,7 +29,7 @@ using namespace eth;
//#define ETH_ADDRESS_DEBUG 1
const unsigned eth::c_protocolVersion = 24;
const unsigned eth::c_protocolVersion = 23;
const unsigned eth::c_databaseVersion = 1;
static const vector<pair<u256, string>> g_units =

2
libethential/Common.cpp

@ -27,6 +27,6 @@ using namespace eth;
namespace eth
{
char const* EthVersion = "0.6.1";
char const* EthVersion = "0.5.18";
}

1
libethereum/BlockChain.cpp

@ -186,6 +186,7 @@ h256s BlockChain::sync(BlockQueue& _bq, OverlayDB const& _stateDB, unsigned _max
}
catch (...){}
}
_bq.doneDrain();
return ret;
}

25
libethereum/BlockQueue.cpp

@ -34,7 +34,8 @@ bool BlockQueue::import(bytesConstRef _block, BlockChain const& _bc)
h256 h = sha3(_block);
UpgradableGuard l(m_lock);
if (m_readySet.count(h) || m_futureSet.count(h))
if (m_readySet.count(h) || m_drainingSet.count(h) || m_futureSet.count(h))
// Already know about this one.
return false;
@ -65,39 +66,43 @@ bool BlockQueue::import(bytesConstRef _block, BlockChain const& _bc)
if (bi.timestamp > (u256)time(0))
return false;
{
UpgradeGuard ul(l);
// We now know it.
if (!m_readySet.count(bi.parentHash) && !_bc.details(bi.parentHash))
if (!m_readySet.count(bi.parentHash) && !m_drainingSet.count(bi.parentHash) && !_bc.details(bi.parentHash))
{
// We don't know the parent (yet) - queue it up for later. It'll get resent to us if we find out about its ancestry later on.
m_future.insert(make_pair(bi.parentHash, make_pair(h, _block.toBytes())));
m_futureSet.insert(h);
return true;
}
else
{
// If valid, append to blocks.
m_ready.push_back(_block.toBytes());
m_readySet.insert(h);
noteReadyWithoutWriteGuard(h);
}
}
return true;
}
void BlockQueue::noteReadyWithoutWriteGuard(h256 _good)
{
h256s goodQueue(1, _good);
list<h256> goodQueue(1, _good);
while (goodQueue.size())
{
auto r = m_future.equal_range(goodQueue.back());
goodQueue.pop_back();
auto r = m_future.equal_range(goodQueue.front());
goodQueue.pop_front();
for (auto it = r.first; it != r.second; ++it)
{
m_futureSet.erase(it->second.first);
m_ready.push_back(it->second.second);
m_readySet.erase(it->second.first);
goodQueue.push_back(it->second.first);
auto newReady = it->second.first;
m_futureSet.erase(newReady);
m_readySet.insert(newReady);
goodQueue.push_back(newReady);
}
m_future.erase(r.first, r.second);
}

7
libethereum/BlockQueue.h

@ -43,7 +43,11 @@ public:
bool import(bytesConstRef _tx, BlockChain const& _bc);
/// Grabs the blocks that are ready, giving them in the correct order for insertion into the chain.
void drain(std::vector<bytes>& o_out) { WriteGuard l(m_lock); swap(o_out, m_ready); m_readySet.clear(); }
/// Don't forget to call doneDrain() once you're done importing.
void drain(std::vector<bytes>& o_out) { WriteGuard l(m_lock); if (m_drainingSet.empty()) { swap(o_out, m_ready); swap(m_drainingSet, m_readySet); } }
/// Must be called after a drain() call. Notes that the drained blocks have been imported into the blockchain, so we can forget about them.
void doneDrain() { WriteGuard l(m_lock); m_drainingSet.clear(); }
/// Notify the queue that the chain has changed and a new block has attained 'ready' status (i.e. is in the chain).
void noteReady(h256 _b) { WriteGuard l(m_lock); noteReadyWithoutWriteGuard(_b); }
@ -56,6 +60,7 @@ private:
mutable boost::shared_mutex m_lock; ///< General lock.
std::set<h256> m_readySet; ///< All blocks ready for chain-import.
std::set<h256> m_drainingSet; ///< All blocks being imported.
std::vector<bytes> m_ready; ///< List of blocks, in correct order, ready for chain-import.
std::set<h256> m_futureSet; ///< Set of all blocks whose parents are not ready/in-chain.
std::multimap<h256, std::pair<h256, bytes>> m_future; ///< For transactions that have an unknown parent; we map their parent hash to the block stuff, and insert once the block appears.

Loading…
Cancel
Save