From 0250d2f696c9b0d7f6a484904015cc80d023b228 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sun, 16 Feb 2014 12:45:01 +0000 Subject: [PATCH] Fix for initial network-peer state. --- libethereum/BlockChain.cpp | 2 +- libethereum/PeerNetwork.cpp | 40 +++++++++++++++++++++++-------------- libethereum/PeerNetwork.h | 8 +++++++- 3 files changed, 33 insertions(+), 17 deletions(-) diff --git a/libethereum/BlockChain.cpp b/libethereum/BlockChain.cpp index 54fb52a06..69335cc87 100644 --- a/libethereum/BlockChain.cpp +++ b/libethereum/BlockChain.cpp @@ -199,7 +199,7 @@ void BlockChain::import(bytes const& _block, Overlay const& _db) { m_lastBlockHash = newHash; m_detailsDB->Put(m_writeOptions, ldb::Slice("best"), ldb::Slice((char const*)&newHash, 32)); - clog(BlockChainNote) << " Imported and best. Has" << details(bi.parentHash).children.size() << "siblings."; + clog(BlockChainNote) << " Imported and best. Has" << (details(bi.parentHash).children.size() - 1) << "siblings."; } else { diff --git a/libethereum/PeerNetwork.cpp b/libethereum/PeerNetwork.cpp index ae78afeaf..54b46cd05 100644 --- a/libethereum/PeerNetwork.cpp +++ b/libethereum/PeerNetwork.cpp @@ -169,13 +169,18 @@ bool PeerSession::interpret(RLP const& _r) // Grab their block chain off them. { + clogS(NetNote) << "Want chain. Latest:" << m_server->m_latestBlockSent << ", number:" << m_server->m_chain->details(m_server->m_latestBlockSent).number; unsigned count = std::min(c_maxHashes, m_server->m_chain->details(m_server->m_latestBlockSent).number + 1); RLPStream s; prep(s).appendList(2 + count); s << GetChainPacket; auto h = m_server->m_latestBlockSent; for (unsigned i = 0; i < count; ++i, h = m_server->m_chain->details(h).parent) + { + clogS(NetNote) << " " << i << ":" << h; s << h; + } + s << c_maxBlocksAsk; sealAndSend(s); s.clear(); @@ -781,7 +786,7 @@ void PeerServer::ensureAccepting() } m_accepting = false; - if (m_mode == NodeMode::PeerServer || m_peers.size() < m_idealPeerCount) + if (m_mode == NodeMode::PeerServer || m_peers.size() < m_idealPeerCount * 2) ensureAccepting(); }); } @@ -832,25 +837,24 @@ void PeerServer::connect(bi::tcp::endpoint const& _ep) bool PeerServer::sync() { bool ret = false; - for (auto i = m_peers.begin(); i != m_peers.end();) - { - auto p = i->second.lock(); - if (p && p->m_socket.is_open() && - (p->m_disconnect == chrono::steady_clock::time_point::max() || chrono::steady_clock::now() - p->m_disconnect < chrono::seconds(1))) // kill old peers that should be disconnected. - ++i; - else + if (isInitialised()) + for (auto i = m_peers.begin(); i != m_peers.end();) { - i = m_peers.erase(i); - ret = true; + auto p = i->second.lock(); + if (p && p->m_socket.is_open() && + (p->m_disconnect == chrono::steady_clock::time_point::max() || chrono::steady_clock::now() - p->m_disconnect < chrono::seconds(1))) // kill old peers that should be disconnected. + ++i; + else + { + i = m_peers.erase(i); + ret = true; + } } - } return ret; } -bool PeerServer::sync(BlockChain& _bc, TransactionQueue& _tq, Overlay& _o) +bool PeerServer::ensureInitialised(BlockChain& _bc, TransactionQueue& _tq) { - bool ret = false; - if (m_latestBlockSent == h256()) { // First time - just initialise. @@ -860,8 +864,14 @@ bool PeerServer::sync(BlockChain& _bc, TransactionQueue& _tq, Overlay& _o) for (auto const& i: _tq.transactions()) m_transactionsSent.insert(i.first); m_lastPeersRequest = chrono::steady_clock::time_point::min(); - ret = true; + return true; } + return false; +} + +bool PeerServer::sync(BlockChain& _bc, TransactionQueue& _tq, Overlay& _o) +{ + bool ret = ensureInitialised(_bc, _tq); if (sync()) ret = true; diff --git a/libethereum/PeerNetwork.h b/libethereum/PeerNetwork.h index 47856f99f..c0a8f4402 100644 --- a/libethereum/PeerNetwork.h +++ b/libethereum/PeerNetwork.h @@ -168,7 +168,7 @@ public: /// Conduct I/O, polling, syncing, whatever. /// Ideally all time-consuming I/O is done in a background thread or otherwise asynchronously, but you get this call every 100ms or so anyway. /// This won't touch alter the blockchain. - void process() { m_ioService.poll(); } + void process() { if (isInitialised()) m_ioService.poll(); } /// Set ideal number of peers. void setIdealPeerCount(unsigned _n) { m_idealPeerCount = _n; } @@ -195,6 +195,12 @@ private: void populateAddresses(); void determinePublic(std::string const& _publicAddress, bool _upnp); void ensureAccepting(); + + /// Check to see if the network peer-state initialisation has happened. + bool isInitialised() const { return m_latestBlockSent; } + /// Initialises the network peer-state, doing the stuff that needs to be once-only. @returns true if it really was first. + bool ensureInitialised(BlockChain& _bc, TransactionQueue& _tq); + std::map potentialPeers(); std::string m_clientVersion;