Browse Source

Better state management.

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

2
libethereum/EthereumHost.h

@ -101,7 +101,7 @@ private:
virtual void onStarting() { startWorking(); }
virtual void onStopping() { stopWorking(); }
void updateSyncer(EthereumPeer* _ignore);
void changeSyncer(EthereumPeer* _ignore);
BlockChain const& m_chain;
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_syncingTotalDifficulty = m_totalDifficulty;
m_latestHash = h256();
resetNeedsSyncing();
setAsking(_a, true);
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() << "]";
m_syncingLatestHash = h256();
host()->m_man.resetToChain(m_syncingNeededBlocks);
host()->m_latestBlockSent = m_syncingLatestHash;
}
else
{
clog(NetNote) << "Difficulty of hashchain not HIGHER. Ignoring.";
m_latestHash = h256();
m_syncingLatestHash = h256();
setAsking(Asking::Nothing, false);
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)
{
// 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);
if (blocks.size())
{
@ -202,9 +201,12 @@ void EthereumPeer::transition(Asking _a, bool _force)
void EthereumPeer::setAsking(Asking _a, bool _isSyncing)
{
bool changedAsking = (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)
{
m_syncingLatestHash = h256();
@ -221,7 +223,10 @@ void EthereumPeer::setNeedsSyncing(h256 _latestHash, u256 _td)
m_latestHash = _latestHash;
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
@ -269,7 +274,7 @@ void EthereumPeer::attemptSync()
if (td >= m_totalDifficulty)
{
clogS(NetAllDetail) << "No. Our chain is better.";
m_latestHash = h256();
resetNeedsSyncing();
transition(Asking::Nothing);
}
else
@ -287,6 +292,8 @@ bool EthereumPeer::interpret(RLP const& _r)
{
m_protocolVersion = _r[1].toInt<unsigned>();
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_latestHash = _r[4].toHash<h256>();
auto genesisHash = _r[5].toHash<h256>();

1
libethereum/EthereumPeer.h

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

Loading…
Cancel
Save