Browse Source

Better state management.

cl-refactor
Gav Wood 11 years ago
parent
commit
4f5b153452
  1. 14
      libethereum/EthereumHost.cpp
  2. 2
      libethereum/EthereumHost.h
  3. 25
      libethereum/EthereumPeer.cpp
  4. 1
      libethereum/EthereumPeer.h

14
libethereum/EthereumHost.cpp

@ -84,13 +84,15 @@ void EthereumHost::noteNeedsSyncing(EthereumPeer* _who)
_who->attemptSync(); _who->attemptSync();
} }
void EthereumHost::updateSyncer(EthereumPeer* _syncer) void EthereumHost::changeSyncer(EthereumPeer* _syncer)
{ {
if (_syncer) m_syncer = _syncer;
if (isSyncing())
{ {
for (auto j: peers()) if (_syncer->m_asking == Asking::Blocks)
if (j->cap<EthereumPeer>().get() != _syncer && j->cap<EthereumPeer>()->m_asking == Asking::Nothing) for (auto j: peers())
j->cap<EthereumPeer>()->transition(Asking::Blocks); if (j->cap<EthereumPeer>().get() != _syncer && j->cap<EthereumPeer>()->m_asking == Asking::Nothing)
j->cap<EthereumPeer>()->transition(Asking::Blocks);
} }
else else
{ {
@ -115,7 +117,7 @@ void EthereumHost::noteDoneBlocks(EthereumPeer* _who, bool _clemency)
_who->addRating(m_man.chain().size() / 100); _who->addRating(m_man.chain().size() / 100);
m_man.reset(); m_man.reset();
} }
if (_who->isSyncing()) else if (_who->isSyncing())
{ {
if (_clemency) if (_clemency)
clog(NetNote) << "Chain download failed. Aborted while incomplete."; clog(NetNote) << "Chain download failed. Aborted while incomplete.";

2
libethereum/EthereumHost.h

@ -101,7 +101,7 @@ private:
virtual void onStarting() { startWorking(); } virtual void onStarting() { startWorking(); }
virtual void onStopping() { stopWorking(); } virtual void onStopping() { stopWorking(); }
void updateSyncer(EthereumPeer* _ignore); void changeSyncer(EthereumPeer* _ignore);
BlockChain const& m_chain; BlockChain const& m_chain;
TransactionQueue& m_tq; ///< Maintains a list of incoming transactions not yet in a block on the blockchain. TransactionQueue& m_tq; ///< Maintains a list of incoming transactions not yet in a block on the blockchain.

25
libethereum/EthereumPeer.cpp

@ -105,7 +105,7 @@ void EthereumPeer::transition(Asking _a, bool _force)
m_syncingLatestHash = m_latestHash; m_syncingLatestHash = m_latestHash;
m_syncingTotalDifficulty = m_totalDifficulty; m_syncingTotalDifficulty = m_totalDifficulty;
m_latestHash = h256(); resetNeedsSyncing();
setAsking(_a, true); setAsking(_a, true);
s.appendList(3) << GetBlockHashesPacket << m_syncingLatestHash << c_maxHashesAsk; s.appendList(3) << GetBlockHashesPacket << m_syncingLatestHash << c_maxHashesAsk;
@ -134,15 +134,14 @@ void EthereumPeer::transition(Asking _a, bool _force)
{ {
clog(NetNote) << "Difficulty of hashchain HIGHER. Grabbing" << m_syncingNeededBlocks.size() << "blocks [latest now" << m_syncingLatestHash.abridged() << ", was" << host()->m_latestBlockSent.abridged() << "]"; clog(NetNote) << "Difficulty of hashchain HIGHER. Grabbing" << m_syncingNeededBlocks.size() << "blocks [latest now" << m_syncingLatestHash.abridged() << ", was" << host()->m_latestBlockSent.abridged() << "]";
m_syncingLatestHash = h256();
host()->m_man.resetToChain(m_syncingNeededBlocks); host()->m_man.resetToChain(m_syncingNeededBlocks);
host()->m_latestBlockSent = m_syncingLatestHash; host()->m_latestBlockSent = m_syncingLatestHash;
} }
else else
{ {
clog(NetNote) << "Difficulty of hashchain not HIGHER. Ignoring."; clog(NetNote) << "Difficulty of hashchain not HIGHER. Ignoring.";
m_latestHash = h256(); m_syncingLatestHash = h256();
setAsking(Asking::Nothing, false); setAsking(Asking::Nothing, false);
return; return;
} }
@ -151,7 +150,7 @@ void EthereumPeer::transition(Asking _a, bool _force)
if (m_asking == Asking::Nothing || m_asking == Asking::Hashes || m_asking == Asking::Blocks) if (m_asking == Asking::Nothing || m_asking == Asking::Hashes || m_asking == Asking::Blocks)
{ {
// Looks like it's the best yet for total difficulty. Set to download. // Looks like it's the best yet for total difficulty. Set to download.
setAsking(Asking::Blocks, true); setAsking(Asking::Blocks, true); // will kick off other peers to help if available.
auto blocks = m_sub.nextFetch(c_maxBlocksAsk); auto blocks = m_sub.nextFetch(c_maxBlocksAsk);
if (blocks.size()) if (blocks.size())
{ {
@ -202,9 +201,12 @@ void EthereumPeer::transition(Asking _a, bool _force)
void EthereumPeer::setAsking(Asking _a, bool _isSyncing) void EthereumPeer::setAsking(Asking _a, bool _isSyncing)
{ {
bool changedAsking = (m_asking != _a);
m_asking = _a; m_asking = _a;
if (_isSyncing != (host()->m_syncer == this))
host()->updateSyncer(_isSyncing ? this : nullptr); if (_isSyncing != (host()->m_syncer == this) || (_isSyncing && changedAsking))
host()->changeSyncer(_isSyncing ? this : nullptr);
if (!_isSyncing) if (!_isSyncing)
{ {
m_syncingLatestHash = h256(); m_syncingLatestHash = h256();
@ -221,7 +223,10 @@ void EthereumPeer::setNeedsSyncing(h256 _latestHash, u256 _td)
m_latestHash = _latestHash; m_latestHash = _latestHash;
m_totalDifficulty = _td; m_totalDifficulty = _td;
host()->noteNeedsSyncing(this); if (m_latestHash)
host()->noteNeedsSyncing(this);
session()->addNote("sync", string(isSyncing() ? "ongoing" : "holding") + (needsSyncing() ? " & needed" : ""));
} }
bool EthereumPeer::isSyncing() const bool EthereumPeer::isSyncing() const
@ -269,7 +274,7 @@ void EthereumPeer::attemptSync()
if (td >= m_totalDifficulty) if (td >= m_totalDifficulty)
{ {
clogS(NetAllDetail) << "No. Our chain is better."; clogS(NetAllDetail) << "No. Our chain is better.";
m_latestHash = h256(); resetNeedsSyncing();
transition(Asking::Nothing); transition(Asking::Nothing);
} }
else else
@ -287,6 +292,8 @@ bool EthereumPeer::interpret(RLP const& _r)
{ {
m_protocolVersion = _r[1].toInt<unsigned>(); m_protocolVersion = _r[1].toInt<unsigned>();
m_networkId = _r[2].toInt<u256>(); m_networkId = _r[2].toInt<u256>();
// a bit dirty as we're misusing these to communicate the values to transition, but harmless.
m_totalDifficulty = _r[3].toInt<u256>(); m_totalDifficulty = _r[3].toInt<u256>();
m_latestHash = _r[4].toHash<h256>(); m_latestHash = _r[4].toHash<h256>();
auto genesisHash = _r[5].toHash<h256>(); auto genesisHash = _r[5].toHash<h256>();

1
libethereum/EthereumPeer.h

@ -82,6 +82,7 @@ private:
/// Update our syncing requirements state. /// Update our syncing requirements state.
void setNeedsSyncing(h256 _latestHash, u256 _td); void setNeedsSyncing(h256 _latestHash, u256 _td);
void resetNeedsSyncing() { setNeedsSyncing(h256(), 0); }
/// Do we presently need syncing with this peer? /// Do we presently need syncing with this peer?
bool needsSyncing() const { return !!m_latestHash; } bool needsSyncing() const { return !!m_latestHash; }

Loading…
Cancel
Save