diff --git a/libethereum/BlockChain.h b/libethereum/BlockChain.h index cd60f4e9ab4..5def0308ed5 100644 --- a/libethereum/BlockChain.h +++ b/libethereum/BlockChain.h @@ -311,6 +311,9 @@ class BlockChain /// Change the chain start block. void setChainStartBlockNumber(unsigned _number); + FixedHash<4> forkHash() const { return {}; } + unsigned nextForkBlockNumber() const { return 0; } + private: static h256 chunkId(unsigned _level, unsigned _index) { return h256(_index * 0xff + _level); } diff --git a/libp2p/Host.h b/libp2p/Host.h index cf0cc2468a5..8d2f6028671 100644 --- a/libp2p/Host.h +++ b/libp2p/Host.h @@ -257,6 +257,13 @@ class Host: public Worker return m_nodeTable ? m_nodeTable->hostENR() : m_restoredENR; } + void updateForkID(FixedHash<4> const& _forkHash, uint64_t _forkNext) + { + Guard l(x_nodeTable); + if (m_nodeTable) + m_nodeTable->updateENRForkID(_forkHash, _forkNext); + } + /// Apply function to each session void forEachPeer( std::string const& _capabilityName, std::function _f) const; diff --git a/libp2p/NodeTable.cpp b/libp2p/NodeTable.cpp index 8ab37bfe67f..c72100cc230 100644 --- a/libp2p/NodeTable.cpp +++ b/libp2p/NodeTable.cpp @@ -560,6 +560,7 @@ shared_ptr NodeTable::handlePong( newUdpEndpoint.address(), newUdpEndpoint.port(), m_hostNodeEndpoint.tcpPort()}; { Guard l(m_hostENRMutex); + // TODO include m_hostForkHash and m_hostForkNext in ENR m_hostENR = IdentitySchemeV4::updateENR(m_hostENR, m_secret, m_hostNodeEndpoint.address(), m_hostNodeEndpoint.tcpPort(), m_hostNodeEndpoint.udpPort()); diff --git a/libp2p/NodeTable.h b/libp2p/NodeTable.h index 2a9bc80d0db..982c81a6813 100644 --- a/libp2p/NodeTable.h +++ b/libp2p/NodeTable.h @@ -187,6 +187,23 @@ class NodeTable : UDPSocketEvents void cancelTimer(std::shared_ptr _timer); + void updateENRForkID(FixedHash<4> const& _forkHash, uint64_t _forkNext) + { + if (_forkHash != m_hostForkHash && _forkNext != m_hostForkNext) + { + m_hostForkHash = _forkHash; + m_hostForkNext = _forkNext; + + { + Guard l(m_hostENRMutex); + // TODO include forkHash and forkNext in ENR + m_hostENR = IdentitySchemeV4::updateENR(m_hostENR, m_secret, m_hostNodeEndpoint.address(), + m_hostNodeEndpoint.tcpPort(), m_hostNodeEndpoint.udpPort()); + } + clog(VerbosityInfo, "net") << "ENR updated: " << m_hostENR; + } + } + // protected only for derived classes in tests protected: /** @@ -339,6 +356,8 @@ class NodeTable : UDPSocketEvents bi::address const m_hostStaticIP; // Dynamically updated host endpoint NodeIPEndpoint m_hostNodeEndpoint; + FixedHash<4> m_hostForkHash; + uint64_t m_hostForkNext = 0; ENR m_hostENR; mutable Mutex m_hostENRMutex; Secret m_secret; ///< This nodes secret key. diff --git a/libwebthree/WebThree.cpp b/libwebthree/WebThree.cpp index 8e5bdda513e..4ec172b7fef 100644 --- a/libwebthree/WebThree.cpp +++ b/libwebthree/WebThree.cpp @@ -34,6 +34,9 @@ WebThreeDirect::WebThreeDirect(std::string const& _clientVersion, m_ethereum.reset(new eth::Client(_params, (int)_params.networkID, m_net, shared_ptr(), _dbPath, _snapshotPath, _we)); + m_chainChangedHandler = + m_ethereum->setOnChainChanged([this](h256s const&, h256s const&) { onChainChanged(); }); + m_ethereum->startWorking(); const auto* buildinfo = aleth_get_buildinfo(); m_ethereum->setExtraData(rlpList(0, string{buildinfo->project_version}.substr(0, 5) + "++" + @@ -105,3 +108,9 @@ void WebThreeDirect::addPeer(NodeSpec const& _s, PeerType _t) m_net.addPeer(_s, _t); } +void WebThreeDirect::onChainChanged() +{ + const auto forkHash = m_ethereum->blockChain().forkHash(); + const auto forkNext = m_ethereum->blockChain().nextForkBlockNumber(); + m_net.updateForkID(forkHash, forkNext); +} diff --git a/libwebthree/WebThree.h b/libwebthree/WebThree.h index 92d02dca420..350b08c2be7 100644 --- a/libwebthree/WebThree.h +++ b/libwebthree/WebThree.h @@ -170,11 +170,15 @@ class WebThreeDirect: public NetworkFace bool isNetworkStarted() const override { return m_net.isStarted(); } private: + void onChainChanged(); + std::string m_clientVersion; ///< Our end-application client's name/version. std::unique_ptr m_ethereum; ///< Client for Ethereum ("eth") protocol. p2p::Host m_net; ///< Should run in background and send us events when blocks found and allow us to send blocks as required. + + eth::Handler m_chainChangedHandler; };