diff --git a/libdevcore/Common.h b/libdevcore/Common.h index 198119f24..aa9a5ae03 100644 --- a/libdevcore/Common.h +++ b/libdevcore/Common.h @@ -36,7 +36,12 @@ #include #include #include +#pragma warning(push) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" #include +#pragma warning(pop) +#pragma GCC diagnostic pop #include "vector_ref.h" #include "debugbreak.h" @@ -64,6 +69,7 @@ using u256 = boost::multiprecision::number>; using u160 = boost::multiprecision::number>; using s160 = boost::multiprecision::number>; +using u512 = boost::multiprecision::number>; using u256s = std::vector; using u160s = std::vector; using u256Set = std::set; diff --git a/libp2p/NodeTable.cpp b/libp2p/NodeTable.cpp index 7a98950ea..20f9f5fdf 100644 --- a/libp2p/NodeTable.cpp +++ b/libp2p/NodeTable.cpp @@ -25,7 +25,7 @@ using namespace dev; using namespace dev::p2p; NodeTable::NodeTable(ba::io_service& _io, KeyPair _alias, uint16_t _listenPort): - m_node(Node(_alias.address(), _alias.pub(), bi::udp::endpoint())), + m_node(Node(_alias.pub(), bi::udp::endpoint())), m_secret(_alias.sec()), m_socket(new NodeSocket(_io, *this, _listenPort)), m_socketPtr(m_socket.get()), @@ -34,7 +34,11 @@ NodeTable::NodeTable(ba::io_service& _io, KeyPair _alias, uint16_t _listenPort): m_evictionCheckTimer(m_io) { for (unsigned i = 0; i < s_bins; i++) - m_state[i].distance = i, m_state[i].modified = chrono::steady_clock::now() - chrono::seconds(1); + { + m_state[i].distance = i; + m_state[i].modified = chrono::steady_clock::now() - chrono::seconds(1); + } + m_socketPtr->connect(); doRefreshBuckets(boost::system::error_code()); } @@ -51,9 +55,9 @@ void NodeTable::join() doFindNode(m_node.id); } -std::list
NodeTable::nodes() const +std::list NodeTable::nodes() const { - std::list
nodes; + std::list nodes; Guard l(x_nodes); for (auto& i: m_nodes) nodes.push_back(i.second->id); @@ -70,20 +74,20 @@ list NodeTable::state() const return move(ret); } -NodeTable::NodeEntry NodeTable::operator[](Address _id) +NodeTable::NodeEntry NodeTable::operator[](NodeId _id) { Guard l(x_nodes); return *m_nodes[_id]; } -void NodeTable::requestNeighbors(NodeEntry const& _node, Address _target) const +void NodeTable::requestNeighbors(NodeEntry const& _node, NodeId _target) const { FindNode p(_node.endpoint.udp, _target); p.sign(m_secret); m_socketPtr->send(p); } -void NodeTable::doFindNode(Address _node, unsigned _round, std::shared_ptr>> _tried) +void NodeTable::doFindNode(NodeId _node, unsigned _round, std::shared_ptr>> _tried) { if (!m_socketPtr->isOpen() || _round == s_maxSteps) return; @@ -131,7 +135,7 @@ void NodeTable::doFindNode(Address _node, unsigned _round, std::shared_ptr> NodeTable::findNearest(Address _target) +std::vector> NodeTable::findNearest(NodeId _target) { // send s_alpha FindNode packets to nodes we know, closest to target static unsigned lastBin = s_bins - 1; @@ -234,26 +238,24 @@ void NodeTable::evict(std::shared_ptr _leastSeen, std::shared_ptr node; { Guard l(x_nodes); - auto n = m_nodes.find(id); + auto n = m_nodes.find(_pubk); if (n == m_nodes.end()) { - node.reset(new NodeEntry(m_node, id, _pubk, _endpoint)); - m_nodes[id] = node; -// clog(NodeTableMessageSummary) << "Adding node to cache: " << id; + node.reset(new NodeEntry(m_node, _pubk, _endpoint)); + m_nodes[_pubk] = node; +// clog(NodeTableMessageSummary) << "Adding node to cache: " << _pubk; } else { node = n->second; -// clog(NodeTableMessageSummary) << "Found node in cache: " << id; +// clog(NodeTableMessageSummary) << "Found node in cache: " << _pubk; } } diff --git a/libp2p/NodeTable.h b/libp2p/NodeTable.h index 314775955..5466a3ae3 100644 --- a/libp2p/NodeTable.h +++ b/libp2p/NodeTable.h @@ -50,6 +50,7 @@ namespace p2p * @todo expiration and sha3(id) 'to' for messages which are replies (prevents replay) * @todo std::shared_ptr m_cachedPingPacket; * @todo std::shared_ptr m_cachedFindSelfPacket; + * @todo store root node in table? * * [Networking] * @todo TCP endpoints @@ -68,7 +69,7 @@ class NodeTable: UDPSocketEvents, public std::enable_shared_from_this friend struct Neighbors; using NodeSocket = UDPSocket; using TimePoint = std::chrono::steady_clock::time_point; - using EvictionTimeout = std::pair,Address>; + using EvictionTimeout = std::pair,NodeId>; ///< First NodeId may be evicted and replaced with second NodeId. struct NodeDefaultEndpoint { @@ -78,14 +79,13 @@ class NodeTable: UDPSocketEvents, public std::enable_shared_from_this struct Node { - Node(Address _id, Public _pubk, NodeDefaultEndpoint _udp): id(_id), pubk(_pubk), endpoint(_udp) {} - Node(Address _id, Public _pubk, bi::udp::endpoint _udp): Node(_id, _pubk, NodeDefaultEndpoint(_udp)) {} + Node(Public _pubk, NodeDefaultEndpoint _udp): id(_pubk), endpoint(_udp) {} + Node(Public _pubk, bi::udp::endpoint _udp): Node(_pubk, NodeDefaultEndpoint(_udp)) {} - virtual Address const& address() const { return id; } - virtual Public const& publicKey() const { return pubk; } + virtual NodeId const& address() const { return id; } + virtual Public const& publicKey() const { return id; } - Address id; - Public pubk; + NodeId id; NodeDefaultEndpoint endpoint; }; @@ -95,8 +95,8 @@ class NodeTable: UDPSocketEvents, public std::enable_shared_from_this */ struct NodeEntry: public Node { - NodeEntry(Node _src, Address _id, Public _pubk, NodeDefaultEndpoint _gw): Node(_id, _pubk, _gw), distance(dist(_src.id,_id)) {} - NodeEntry(Node _src, Address _id, Public _pubk, bi::udp::endpoint _udp): Node(_id, _pubk, NodeDefaultEndpoint(_udp)), distance(dist(_src.id,_id)) {} + NodeEntry(Node _src, Public _pubk, NodeDefaultEndpoint _gw): Node(_pubk, _gw), distance(dist(_src.id,_pubk)) {} + NodeEntry(Node _src, Public _pubk, bi::udp::endpoint _udp): Node(_pubk, NodeDefaultEndpoint(_udp)), distance(dist(_src.id,_pubk)) {} const unsigned distance; ///< Node's distance from _src (see constructor). }; @@ -114,7 +114,7 @@ public: /// Constants for Kademlia, mostly derived from address space. - static unsigned const s_addressByteSize = sizeof(Node::id); ///< Size of address type in bytes. + static unsigned const s_addressByteSize = sizeof(NodeId); ///< Size of address type in bytes. static unsigned const s_bits = 8 * s_addressByteSize; ///< Denoted by n in [Kademlia]. static unsigned const s_bins = s_bits - 1; ///< Size of m_state (excludes root, which is us). static unsigned const s_maxSteps = boost::static_log2::value; ///< Max iterations of discovery. (doFindNode) @@ -130,23 +130,23 @@ public: std::chrono::milliseconds const c_reqTimeout = std::chrono::milliseconds(300); ///< How long to wait for requests (evict, find iterations). std::chrono::seconds const c_bucketRefresh = std::chrono::seconds(3600); ///< Refresh interval prevents bucket from becoming stale. [Kademlia] - static unsigned dist(Address const& _a, Address const& _b) { u160 d = _a ^ _b; unsigned ret; for (ret = 0; d >>= 1; ++ret) {}; return ret; } + static unsigned dist(NodeId const& _a, NodeId const& _b) { u512 d = _a ^ _b; unsigned ret; for (ret = 0; d >>= 1; ++ret) {}; return ret; } void join(); - NodeEntry root() const { return NodeEntry(m_node, m_node.address(), m_node.publicKey(), m_node.endpoint.udp); } - std::list
nodes() const; + NodeEntry root() const { return NodeEntry(m_node, m_node.publicKey(), m_node.endpoint.udp); } + std::list nodes() const; std::list state() const; - NodeEntry operator[](Address _id); + NodeEntry operator[](NodeId _id); protected: /// Repeatedly sends s_alpha concurrent requests to nodes nearest to target, for nodes nearest to target, up to s_maxSteps rounds. - void doFindNode(Address _node, unsigned _round = 0, std::shared_ptr>> _tried = std::shared_ptr>>()); + void doFindNode(NodeId _node, unsigned _round = 0, std::shared_ptr>> _tried = std::shared_ptr>>()); /// Returns nodes nearest to target. - std::vector> findNearest(Address _target); + std::vector> findNearest(NodeId _target); void ping(bi::udp::endpoint _to) const; @@ -180,13 +180,13 @@ private: protected: #endif /// Sends FindNeighbor packet. See doFindNode. - void requestNeighbors(NodeEntry const& _node, Address _target) const; + void requestNeighbors(NodeEntry const& _node, NodeId _target) const; Node m_node; ///< This node. Secret m_secret; ///< This nodes secret key. mutable Mutex x_nodes; ///< Mutable for thread-safe copy in nodes() const. - std::map> m_nodes; ///< Address -> Node table (most common lookup path) + std::map> m_nodes; ///< NodeId -> Node table (most common lookup path) mutable Mutex x_state; std::array m_state; ///< State table of binned nodes. @@ -233,9 +233,9 @@ inline std::ostream& operator<<(std::ostream& _out, NodeTable const& _nodeTable) */ struct PingNode: RLPXDatagram { - using RLPXDatagram::RLPXDatagram; - PingNode(bi::udp::endpoint _ep, std::string _src, uint16_t _srcPort, std::chrono::seconds _expiration = std::chrono::seconds(60)): RLPXDatagram(_ep), ipAddress(_src), port(_srcPort), expiration(futureFromEpoch(_expiration)) {} - + PingNode(bi::udp::endpoint _ep): RLPXDatagram(_ep) {} + PingNode(bi::udp::endpoint _ep, std::string _src, uint16_t _srcPort, std::chrono::seconds _expiration = std::chrono::seconds(60)): RLPXDatagram(_ep), ipAddress(_src), port(_srcPort), expiration(futureFromEpoch(_expiration)) {} + std::string ipAddress; unsigned port; unsigned expiration; @@ -257,7 +257,7 @@ struct PingNode: RLPXDatagram */ struct Pong: RLPXDatagram { - using RLPXDatagram::RLPXDatagram; + Pong(bi::udp::endpoint _ep): RLPXDatagram(_ep) {} h256 replyTo; // hash of rlp of PingNode unsigned expiration; @@ -275,20 +275,20 @@ struct Pong: RLPXDatagram * Minimum Encoded Size: 21 bytes * Maximum Encoded Size: 30 bytes * - * target: Address of node. The responding node will send back nodes closest to the target. + * target: NodeId of node. The responding node will send back nodes closest to the target. * expiration: Triggers regeneration of packet. May also provide control over synchronization. * */ struct FindNode: RLPXDatagram { using RLPXDatagram::RLPXDatagram; - FindNode(bi::udp::endpoint _ep, Address _target, std::chrono::seconds _expiration = std::chrono::seconds(30)): RLPXDatagram(_ep), target(_target), expiration(futureFromEpoch(_expiration)) {} + FindNode(bi::udp::endpoint _ep, NodeId _target, std::chrono::seconds _expiration = std::chrono::seconds(30)): RLPXDatagram(_ep), target(_target), expiration(futureFromEpoch(_expiration)) {} - h160 target; + h512 target; unsigned expiration; - + void streamRLP(RLPStream& _s) const { _s.appendList(2); _s << target << expiration; } - void interpretRLP(bytesConstRef _bytes) { RLP r(_bytes); target = r[0].toHash(); expiration = r[1].toInt(); } + void interpretRLP(bytesConstRef _bytes) { RLP r(_bytes); target = r[0].toHash(); expiration = r[1].toInt(); } }; /** @@ -317,7 +317,7 @@ struct Neighbors: RLPXDatagram }; using RLPXDatagram::RLPXDatagram; - Neighbors(bi::udp::endpoint _to, std::vector> const& _nearest, unsigned _offset = 0, unsigned _limit = 0): RLPXDatagram(_to) + Neighbors(bi::udp::endpoint _to, std::vector> const& _nearest, unsigned _offset = 0, unsigned _limit = 0): RLPXDatagram(_to) { auto limit = _limit ? std::min(_nearest.size(), (size_t)(_offset + _limit)) : _nearest.size(); for (auto i = _offset; i < limit; i++) @@ -328,15 +328,6 @@ struct Neighbors: RLPXDatagram node.node = _nearest[i]->publicKey(); nodes.push_back(node); } - -// for (auto& n: _nearest) -// { -// Node node; -// node.ipAddress = n->endpoint.udp.address().to_string(); // 16 -// node.port = n->endpoint.udp.port(); // 3 -// node.node = n->publicKey();// 67 -// nodes.push_back(node); -// } } std::list nodes; diff --git a/libp2p/UDP.cpp b/libp2p/UDP.cpp index 8b60196e9..b1f87e409 100644 --- a/libp2p/UDP.cpp +++ b/libp2p/UDP.cpp @@ -37,7 +37,7 @@ h256 RLPXDatagramFace::sign(Secret const& _k) bytesConstRef packetHash(&data[0], h256::size); bytesConstRef signedPayload(&data[h256::size], Signature::size + rlp.size()); bytesConstRef payloadSig(&data[h256::size], Signature::size); - bytesConstRef payload(&data[h256::size+Signature::size], rlp.size()); + bytesConstRef payload(&data[h256::size + Signature::size], rlp.size()); sig.ref().copyTo(payloadSig); rlp.copyTo(payload); diff --git a/libp2p/UDP.h b/libp2p/UDP.h index cc8e58b9f..ac4afb0b1 100644 --- a/libp2p/UDP.h +++ b/libp2p/UDP.h @@ -60,10 +60,8 @@ protected: * @todo compact templates * @todo make data private/functional (see UDPDatagram) */ -//template struct RLPXDatagramFace: public UDPDatagram { -// static T fromBytesConstRef(bi::udp::endpoint const& _ep, bytesConstRef _bytes) { T t(_ep); t.interpretRLP(_bytes); return std::move(t); } static uint64_t futureFromEpoch(std::chrono::milliseconds _ms) { return std::chrono::duration_cast((std::chrono::system_clock::now() + _ms).time_since_epoch()).count(); } static uint64_t futureFromEpoch(std::chrono::seconds _sec) { return std::chrono::duration_cast((std::chrono::system_clock::now() + _sec).time_since_epoch()).count(); } static Public authenticate(bytesConstRef _sig, bytesConstRef _rlp); @@ -74,12 +72,12 @@ struct RLPXDatagramFace: public UDPDatagram virtual void streamRLP(RLPStream&) const =0; virtual void interpretRLP(bytesConstRef _bytes) =0; }; - + template struct RLPXDatagram: public RLPXDatagramFace { - static T fromBytesConstRef(bi::udp::endpoint const& _ep, bytesConstRef _bytes) { T t(_ep); t.interpretRLP(_bytes); return std::move(t); } using RLPXDatagramFace::RLPXDatagramFace; + static T fromBytesConstRef(bi::udp::endpoint const& _ep, bytesConstRef _bytes) { T t(_ep); t.interpretRLP(_bytes); return std::move(t); } }; /** diff --git a/test/boostTest.cpp b/test/boostTest.cpp index 7d89f853c..cef3cc0a7 100644 --- a/test/boostTest.cpp +++ b/test/boostTest.cpp @@ -21,4 +21,8 @@ */ #define BOOST_TEST_MODULE EthereumTests +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" #include +#pragma warning(pop) +#pragma GCC diagnostic pop diff --git a/test/net.cpp b/test/net.cpp index 8a2e2af78..0a008d6eb 100644 --- a/test/net.cpp +++ b/test/net.cpp @@ -171,6 +171,12 @@ BOOST_AUTO_TEST_CASE(test_findnode_neighbors) // into the same list of nearest nodes. } +BOOST_AUTO_TEST_CASE(test_windows_template) +{ + bi::udp::endpoint ep; + PingNode p(ep); +} + BOOST_AUTO_TEST_CASE(kademlia) { // Not yet a 'real' test.