46 namespace bi = ba::ip;
52 size_t operator()(pair<dev::p2p::NodeID, string>
const& _value)
const 54 size_t ret = hash<dev::p2p::NodeID>()(_value.first);
55 return ret ^ (hash<string>()(_value.second) + 0x9e3779b9 + (ret << 6) + (ret >> 2));
90 std::unordered_map<std::string, SubReputation>
subs;
98 void noteRude(
SessionFace const& _s, std::string
const& _sub = std::string());
99 bool isRude(
SessionFace const& _s, std::string
const& _sub = std::string())
const;
100 void setData(
SessionFace const& _s, std::string
const& _sub,
bytes const& _data);
111 NodeInfo(
NodeID const& _id, std::string
const& _address,
unsigned _port, std::string
const& _version):
140 std::string
const& _clientVersion,
148 std::string
const& _clientVersion,
157 static std::unordered_map<Public, std::string> pocHosts();
160 template <
class T> std::shared_ptr<T>
registerCapability(std::shared_ptr<T>
const& _t) { _t->m_host =
this; m_capabilities[std::make_pair(T::staticName(), T::staticVersion())] = _t;
return _t; }
161 template <
class T>
void addCapability(std::shared_ptr<T>
const & _p, std::string
const& _name,
u256 const& _version) { m_capabilities[std::make_pair(_name, _version)] = _p; }
164 CapDescs caps()
const {
CapDescs ret;
for (
auto const& i: m_capabilities) ret.push_back(i.first);
return ret; }
165 template <
class T> std::shared_ptr<T>
cap()
const {
try {
return std::static_pointer_cast<
T>(m_capabilities.at(std::make_pair(T::staticName(), T::staticVersion()))); }
catch (...) {
return nullptr; } }
180 void relinquishPeer(
NodeID const& _node);
192 size_t peerCount()
const;
195 std::string
listenAddress()
const {
return m_tcpPublic.address().is_unspecified() ?
"0.0.0.0" : m_tcpPublic.address().to_string(); }
201 bytes saveNetwork()
const;
227 void startPeerSession(
Public const& _id,
RLP const& _hello, std::unique_ptr<RLPXFrameCoder>&& _io, std::shared_ptr<RLPXSocket>
const& _s);
230 std::shared_ptr<SessionFace>
peerSession(
NodeID const& _id) {
RecursiveGuard l(x_sessions);
return m_sessions.count(_id) ? m_sessions[_id].lock() : std::shared_ptr<SessionFace>(); }
236 bi::tcp::endpoint
const&
tcpPublic()
const {
return m_tcpPublic; }
239 std::string
enode()
const {
return "enode://" + id().hex() +
"@" + (networkPreferences().publicIPAddress.empty() ? m_tcpPublic.address().to_string() : networkPreferences().publicIPAddress) +
":" +
toString(m_tcpPublic.port()); }
242 p2p::NodeInfo nodeInfo()
const {
return NodeInfo(
id(), (networkPreferences().publicIPAddress.empty() ? m_tcpPublic.address().to_string() : networkPreferences().publicIPAddress), m_tcpPublic.port(), m_clientVersion); }
253 unsigned peerSlots(
PeerSlotType _type) {
return _type == Egress ? m_idealPeerCount : m_idealPeerCount * m_stretchPeers; }
258 void determinePublic();
260 void connect(std::shared_ptr<Peer>
const& _p);
266 void keepAlivePeers();
269 void disconnectLatePeers();
275 virtual void startedWorking();
277 void run(boost::system::error_code
const&
error);
280 virtual void doWork();
283 virtual void doneWorking();
300 int m_listenPort = -1;
305 std::unique_ptr<boost::asio::deadline_timer>
m_timer;
306 static const unsigned c_timerInterval = 100;
316 std::unordered_map<NodeID, std::shared_ptr<Peer>>
m_peers;
324 mutable std::unordered_map<NodeID, std::weak_ptr<SessionFace>>
m_sessions;
330 unsigned m_idealPeerCount = 11;
331 unsigned m_stretchPeers = 7;
336 std::list<std::shared_ptr<boost::asio::deadline_timer>>
m_timers;
340 bool m_accepting =
false;
341 bool m_dropPeers =
false;
bool peerSlotsAvailable(PeerSlotType _type=Ingress)
Returns true if pending and connected peer count is less than maximum.
Host const & host() const
Adapted from code found on http://stackoverflow.com/questions/180947/base64-decode-snippet-in-c Origi...
NodeInfo(NodeID const &_id, std::string const &_address, unsigned _port, std::string const &_version)
bool error(const char *fmt, const Args &...args)
void setIdealPeerCount(unsigned _n)
Set ideal number of peers.
bi::tcp::endpoint m_tcpPublic
Our public listening endpoint.
std::unique_ptr< boost::asio::deadline_timer > m_timer
Timer which, when network is running, calls scheduler() every c_timerInterval ms. ...
std::shared_ptr< NodeTable > m_nodeTable
Node table (uses kademlia-like discovery).
std::mutex x_runTimer
Start/stop mutex.
std::pair< std::string, u256 > CapDesc
NetworkPreferences const & networkPreferences() const
unsigned peerSlots(PeerSlotType _type)
RecursiveMutex x_sessions
Simple class that represents a "key pair".
The Host class Capabilities should be registered prior to startNetwork, since m_capabilities is not t...
std::vector< PeerSessionInfo > PeerSessionInfos
std::map< CapDesc, std::shared_ptr< HostCapabilityFace > > m_capabilities
Each of the capabilities we support.
std::string m_clientVersion
Our version string.
std::list< std::shared_ptr< boost::asio::deadline_timer > > m_timers
Deadline timers used for isolated network events. GC'd by run.
unsigned short listenPort() const
Get the port we're listening on currently.
Mutex x_pendingNodeConns
Used only by connect(Peer&) to limit concurrently connecting to same node. See connect(shared_ptr<Pee...
std::string listenAddress() const
Get the address we're listening on currently.
bi::tcp::endpoint const & tcpPublic() const
Get the public TCP endpoint.
std::hash for asio::adress
std::string toString(string32 const &_s)
Make normal string from fixed-length string.
NetworkPreferences m_netPrefs
Network settings.
std::set< NodeID > m_requiredPeers
Peers we try to connect regardless of p2p network.
std::set< bi::address > m_ifAddresses
Interface addresses (private, public)
ba::io_service m_ioService
IOService for network stuff.
bytes m_restoreNetwork
Set by constructor and used to set Host key and restore network peers & nodes.
std::recursive_mutex RecursiveMutex
bool havePeerSession(NodeID const &_id)
std::string enode() const
NodeID id() const
Get our current node ID.
std::vector< Peer > Peers
std::unordered_map< std::string, SubReputation > subs
std::lock_guard< std::mutex > Guard
p2p::NodeInfo nodeInfo() const
Get the node information.
void requirePeer(NodeID const &_node, bi::address const &_addr, unsigned short _udpPort, unsigned short _tcpPort)
Create Peer and attempt keeping peer connected.
std::list< std::weak_ptr< RLPXHandshake > > m_connecting
Pending connections.
std::vector< byte > bytes
KeyPair m_alias
Alias for network communication. Network address is k*G. k is key material. TODO: Replace KeyPair...
vector_ref< byte const > bytesConstRef
void setPeerStretch(unsigned _n)
Set multipier for max accepted connections.
bool haveCapability(CapDesc const &_name) const
boost::multiprecision::number< boost::multiprecision::cpp_int_backend< 256, 256, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void >> u256
std::set< Peer * > m_pendingPeerConns
std::vector< CapDesc > CapDescs
void addCapability(std::shared_ptr< T > const &_p, std::string const &_name, u256 const &_version)
ReputationManager m_repMan
std::shared_ptr< T > registerCapability(std::shared_ptr< T > const &_t)
Register a peer-capability; all new peer connections will have this capability.
size_t operator()(pair< dev::p2p::NodeID, string > const &_value) const
std::unordered_map< NodeID, std::weak_ptr< SessionFace > > m_sessions
The nodes to which we are currently connected.
boost::shared_mutex SharedMutex
clock::time_point time_point
bi::tcp::acceptor m_tcp4Acceptor
Listening acceptor.
std::shared_ptr< T > cap() const
std::lock_guard< std::recursive_mutex > RecursiveGuard
std::string enode() const
Get the public endpoint information.
dev::WithExisting max(dev::WithExisting _a, dev::WithExisting _b)
Mutex x_connecting
Mutex for m_connecting.
std::chrono::steady_clock::time_point m_lastPing
Time we sent the last ping to all peers.
struct evm_uint160be address(struct evm_env *env)
std::unordered_map< std::pair< p2p::NodeID, std::string >, Reputation > m_nodes
Nodes that were impolite while syncing. We avoid syncing from these if possible.
void setNetworkPreferences(NetworkPreferences const &_p, bool _dropPeers=false)
Class for interpreting Recursive Linear-Prefix Data.
std::unordered_map< NodeID, std::shared_ptr< Peer > > m_peers
Shared storage of Peer objects. Peers are created or destroyed on demand by the Host. Active sessions maintain a shared_ptr to a Peer;.
UniValue stop(const JSONRPCRequest &jsonRequest)
std::shared_ptr< SessionFace > peerSession(NodeID const &_id)
Get session by id.
ReputationManager & repMan()
Setup inbound or outbound connection for communication over RLPXFrameCoder.