diff --git a/libethereum/BlockChain.cpp b/libethereum/BlockChain.cpp index 52be37d51..ac9e9dc37 100644 --- a/libethereum/BlockChain.cpp +++ b/libethereum/BlockChain.cpp @@ -329,7 +329,7 @@ h256s BlockChain::import(bytes const& _block, OverlayDB const& _db) return ret; } -h256s BlockChain::treeRoute(h256 _from, h256 _to, h256* o_common) const +h256s BlockChain::treeRoute(h256 _from, h256 _to, h256* o_common, bool _pre, bool _post) const { h256s ret; h256s back; @@ -337,20 +337,24 @@ h256s BlockChain::treeRoute(h256 _from, h256 _to, h256* o_common) const unsigned tn = details(_to).number; while (fn > tn) { - ret.push_back(_from); + if (_pre) + ret.push_back(_from); _from = details(_from).parent; fn--; } while (fn < tn) { - back.push_back(_to); + if (_post) + back.push_back(_to); _to = details(_to).parent; tn--; } while (_from != _to) { - _from = details(_from).parent; - _to = details(_to).parent; + if (_pre) + _from = details(_from).parent; + if (_post) + _to = details(_to).parent; ret.push_back(_from); back.push_back(_to); } diff --git a/libethereum/BlockChain.h b/libethereum/BlockChain.h index 1c4e5e8fd..d13ef7614 100644 --- a/libethereum/BlockChain.h +++ b/libethereum/BlockChain.h @@ -128,7 +128,7 @@ public: * treeRoute(1b, 2a) == { 1b, 1a, 2a }; // *o_common == g * @endcode */ - h256s treeRoute(h256 _from, h256 _to, h256* o_common = nullptr) const; + h256s treeRoute(h256 _from, h256 _to, h256* o_common = nullptr, bool _pre = true, bool _post = true) const; private: template T queryExtras(h256 _h, std::map& _m, boost::shared_mutex& _x, T const& _n) const diff --git a/libethereum/PeerServer.cpp b/libethereum/PeerServer.cpp index 3117163f1..cd5ceaad4 100644 --- a/libethereum/PeerServer.cpp +++ b/libethereum/PeerServer.cpp @@ -507,12 +507,18 @@ void PeerServer::maintainBlocks(BlockQueue& _bq, h256 _currentHash) // Send any new blocks. if (_currentHash != m_latestBlockSent) { - // TODO: find where they diverge and send complete new branch. RLPStream ts; PeerSession::prep(ts); - ts.appendList(2) << BlocksPacket; + bytes bs; + unsigned c = 0; + for (auto h: m_chain->treeRoute(m_latestBlockSent, _currentHash, nullptr, false, true)) + { + bs += m_chain->block(h); + ++c; + } + ts.appendList(1 + c).append(BlocksPacket).appendRaw(bs, c); bytes b; - ts.appendRaw(m_chain->block()).swapOut(b); + ts.swapOut(b); seal(b); Guard l(x_peers);