Browse Source

coding standards, h512 node id, mute warnings for clang builds. attempt inherited constructor fix for windows.

cl-refactor
subtly 10 years ago
parent
commit
44f80248ad
  1. 6
      libdevcore/Common.h
  2. 34
      libp2p/NodeTable.cpp
  3. 65
      libp2p/NodeTable.h
  4. 2
      libp2p/UDP.cpp
  5. 6
      libp2p/UDP.h
  6. 4
      test/boostTest.cpp
  7. 6
      test/net.cpp

6
libdevcore/Common.h

@ -36,7 +36,12 @@
#include <map>
#include <vector>
#include <set>
#pragma warning(push)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#include <boost/multiprecision/cpp_int.hpp>
#pragma warning(pop)
#pragma GCC diagnostic pop
#include "vector_ref.h"
#include "debugbreak.h"
@ -64,6 +69,7 @@ using u256 = boost::multiprecision::number<boost::multiprecision::cpp_int_backe
using s256 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<256, 256, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void>>;
using u160 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<160, 160, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>;
using s160 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<160, 160, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void>>;
using u512 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<512, 512, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>;
using u256s = std::vector<u256>;
using u160s = std::vector<u160>;
using u256Set = std::set<u256>;

34
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<Address> NodeTable::nodes() const
std::list<NodeId> NodeTable::nodes() const
{
std::list<Address> nodes;
std::list<NodeId> nodes;
Guard l(x_nodes);
for (auto& i: m_nodes)
nodes.push_back(i.second->id);
@ -70,20 +74,20 @@ list<NodeTable::NodeEntry> 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<std::set<std::shared_ptr<NodeEntry>>> _tried)
void NodeTable::doFindNode(NodeId _node, unsigned _round, std::shared_ptr<std::set<std::shared_ptr<NodeEntry>>> _tried)
{
if (!m_socketPtr->isOpen() || _round == s_maxSteps)
return;
@ -131,7 +135,7 @@ void NodeTable::doFindNode(Address _node, unsigned _round, std::shared_ptr<std::
});
}
std::vector<std::shared_ptr<NodeTable::NodeEntry>> NodeTable::findNearest(Address _target)
std::vector<std::shared_ptr<NodeTable::NodeEntry>> 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<NodeEntry> _leastSeen, std::shared_ptr<Nod
void NodeTable::noteNode(Public const& _pubk, bi::udp::endpoint const& _endpoint)
{
Address id = right160(sha3(_pubk));
// Don't add ourself
if (id == m_node.address())
if (_pubk == m_node.address())
return;
std::shared_ptr<NodeEntry> 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;
}
}

65
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<PingNode> m_cachedPingPacket;
* @todo std::shared_ptr<FindNeighbors> 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<NodeTable>
friend struct Neighbors;
using NodeSocket = UDPSocket<NodeTable, 1280>;
using TimePoint = std::chrono::steady_clock::time_point;
using EvictionTimeout = std::pair<std::pair<Address,TimePoint>,Address>;
using EvictionTimeout = std::pair<std::pair<NodeId,TimePoint>,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<NodeTable>
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<NodeTable>
*/
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<s_bits>::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<Address> nodes() const;
NodeEntry root() const { return NodeEntry(m_node, m_node.publicKey(), m_node.endpoint.udp); }
std::list<NodeId> nodes() const;
std::list<NodeEntry> 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<std::set<std::shared_ptr<NodeEntry>>> _tried = std::shared_ptr<std::set<std::shared_ptr<NodeEntry>>>());
void doFindNode(NodeId _node, unsigned _round = 0, std::shared_ptr<std::set<std::shared_ptr<NodeEntry>>> _tried = std::shared_ptr<std::set<std::shared_ptr<NodeEntry>>>());
/// Returns nodes nearest to target.
std::vector<std::shared_ptr<NodeEntry>> findNearest(Address _target);
std::vector<std::shared_ptr<NodeEntry>> 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<Address, std::shared_ptr<NodeEntry>> m_nodes; ///< Address -> Node table (most common lookup path)
std::map<NodeId, std::shared_ptr<NodeEntry>> m_nodes; ///< NodeId -> Node table (most common lookup path)
mutable Mutex x_state;
std::array<NodeBucket, s_bins> m_state; ///< State table of binned nodes.
@ -233,9 +233,9 @@ inline std::ostream& operator<<(std::ostream& _out, NodeTable const& _nodeTable)
*/
struct PingNode: RLPXDatagram<PingNode>
{
using RLPXDatagram<PingNode>::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<PingNode>(_ep) {}
PingNode(bi::udp::endpoint _ep, std::string _src, uint16_t _srcPort, std::chrono::seconds _expiration = std::chrono::seconds(60)): RLPXDatagram<PingNode>(_ep), ipAddress(_src), port(_srcPort), expiration(futureFromEpoch(_expiration)) {}
std::string ipAddress;
unsigned port;
unsigned expiration;
@ -257,7 +257,7 @@ struct PingNode: RLPXDatagram<PingNode>
*/
struct Pong: RLPXDatagram<Pong>
{
using RLPXDatagram<Pong>::RLPXDatagram;
Pong(bi::udp::endpoint _ep): RLPXDatagram<Pong>(_ep) {}
h256 replyTo; // hash of rlp of PingNode
unsigned expiration;
@ -275,20 +275,20 @@ struct Pong: RLPXDatagram<Pong>
* 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<FindNode>
{
using RLPXDatagram<FindNode>::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<FindNode>(_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<h160>(); expiration = r[1].toInt<unsigned>(); }
void interpretRLP(bytesConstRef _bytes) { RLP r(_bytes); target = r[0].toHash<h512>(); expiration = r[1].toInt<unsigned>(); }
};
/**
@ -317,7 +317,7 @@ struct Neighbors: RLPXDatagram<Neighbors>
};
using RLPXDatagram<Neighbors>::RLPXDatagram;
Neighbors(bi::udp::endpoint _to, std::vector<std::shared_ptr<NodeTable::NodeEntry>> const& _nearest, unsigned _offset = 0, unsigned _limit = 0): RLPXDatagram(_to)
Neighbors(bi::udp::endpoint _to, std::vector<std::shared_ptr<NodeTable::NodeEntry>> const& _nearest, unsigned _offset = 0, unsigned _limit = 0): RLPXDatagram<Neighbors>(_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<Neighbors>
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<Node> nodes;

2
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);

6
libp2p/UDP.h

@ -60,10 +60,8 @@ protected:
* @todo compact templates
* @todo make data private/functional (see UDPDatagram)
*/
//template <class T>
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::milliseconds>((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::milliseconds>((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 <class T>
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); }
};
/**

4
test/boostTest.cpp

@ -21,4 +21,8 @@
*/
#define BOOST_TEST_MODULE EthereumTests
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#include <boost/test/included/unit_test.hpp>
#pragma warning(pop)
#pragma GCC diagnostic pop

6
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.

Loading…
Cancel
Save