diff --git a/eth_p2p/peer_pool.nim b/eth_p2p/peer_pool.nim index 7cf144b..7b6bbdf 100644 --- a/eth_p2p/peer_pool.nim +++ b/eth_p2p/peer_pool.nim @@ -17,6 +17,7 @@ type keyPair: KeyPair networkId: int minPeers: int + clientId: string discovery: DiscoveryProtocol lastLookupTime: float connectedNodes: Table[Node, Peer] @@ -33,14 +34,15 @@ const connectLoopSleepMs = 2000 proc newPeerPool*(chainDb: AsyncChainDb, networkId: int, keyPair: KeyPair, - discovery: DiscoveryProtocol, minPeers = 10): PeerPool = + discovery: DiscoveryProtocol, clientId: string, + listenPort = Port(30303), minPeers = 10): PeerPool = result.new() result.keyPair = keyPair result.minPeers = minPeers result.networkId = networkId result.discovery = discovery result.connectedNodes = initTable[Node, Peer]() - result.listenPort = Port(30303) + result.listenPort = listenPort template ensureFuture(f: untyped) = asyncCheck f @@ -73,7 +75,7 @@ proc connect(p: PeerPool, remote: Node): Future[Peer] {.async.} = debug "Skipping ", remote, "; already connected to it" return nil - result = await remote.rlpxConnect(p.keyPair, p.listenPort) + result = await remote.rlpxConnect(p.keyPair, p.listenPort, p.clientId) # expected_exceptions = ( # UnreachablePeer, TimeoutError, PeerConnectionLost, HandshakeFailure) diff --git a/eth_p2p/rlpx.nim b/eth_p2p/rlpx.nim index 982e1b6..01e3bb7 100644 --- a/eth_p2p/rlpx.nim +++ b/eth_p2p/rlpx.nim @@ -73,7 +73,6 @@ type const baseProtocolVersion = 4 - clienId = "Nimbus 0.1.0" # TODO: Usage of this variables causes GCSAFE problems. var @@ -536,8 +535,8 @@ proc initSecretState(hs: var Handshake, authMsg, ackMsg: openarray[byte], initSecretState(secrets, p.secretsState) burnMem(secrets) -proc rlpxConnect*(remote: Node, myKeys: KeyPair, - listenPort: Port): Future[Peer] {.async.} = +proc rlpxConnect*(remote: Node, myKeys: KeyPair, listenPort: Port, + clientId: string): Future[Peer] {.async.} = new result result.remote = remote let ta = initTAddress(remote.node.address.ip, remote.node.address.tcpPort) @@ -571,7 +570,7 @@ proc rlpxConnect*(remote: Node, myKeys: KeyPair, # if handshake.remoteHPubkey != remote.node.pubKey: # raise newException(Exception, "Remote pubkey is wrong") - discard result.hello(baseProtocolVersion, clienId, rlpxCapabilities, + discard result.hello(baseProtocolVersion, clientId, rlpxCapabilities, uint(listenPort), myKeys.pubkey.getRaw()) var response = await result.nextMsg(p2p.hello, discardOthers = true) @@ -584,8 +583,8 @@ proc rlpxConnect*(remote: Node, myKeys: KeyPair, if not isNil(result.transp): result.transp.close() -proc rlpxAccept*(transp: StreamTransport, - myKeys: KeyPair): Future[Peer] {.async.} = +proc rlpxAccept*(transp: StreamTransport, myKeys: KeyPair, + clientId: string): Future[Peer] {.async.} = new result result.transp = transp var handshake = newHandshake({Responder}) @@ -613,8 +612,9 @@ proc rlpxAccept*(transp: StreamTransport, var response = await result.nextMsg(p2p.hello, discardOthers = true) let listenPort = transp.localAddress().port - discard result.hello(baseProtocolVersion, clienId, - rlpxCapabilities, listenPort.uint, myKeys.pubkey.getRaw()) + discard result.hello(baseProtocolVersion, clientId, + rlpxCapabilities, listenPort.uint, + myKeys.pubkey.getRaw()) if validatePubKeyInHello(response, handshake.remoteHPubkey): warn "Remote nodeId is not its public key" # XXX: Do we care? @@ -669,4 +669,3 @@ when isMainModule: dispatchMsgPtr = dispatchMsg recvMsgPtr: GcSafeRecvMsg = recvMsg acceptPtr: GcSafeAccept = rlpxAccept - diff --git a/eth_p2p/server.nim b/eth_p2p/server.nim index 13bb9c4..01e37f6 100644 --- a/eth_p2p/server.nim +++ b/eth_p2p/server.nim @@ -18,13 +18,14 @@ type keyPair: KeyPair address: Address networkId: int + clientId: string discovery: DiscoveryProtocol peerPool: PeerPool proc processIncoming(server: StreamServer, remote: StreamTransport): Future[void] {.async, gcsafe.} = var p2p = getUserData[P2PServer](server) - let peerfut = remote.rlpxAccept(p2p.keyPair) + let peerfut = remote.rlpxAccept(p2p.keyPair, p2p.clientId) yield peerfut if not peerfut.failed: let peer = peerfut.read() @@ -35,16 +36,18 @@ proc processIncoming(server: StreamServer, remote.close() proc newP2PServer*(keyPair: KeyPair, address: Address, chainDb: AsyncChainDB, - bootstrapNodes: openarray[ENode], + bootstrapNodes: openarray[ENode], clientId: string, networkId: int): P2PServer = result.new() result.chainDb = chainDb result.keyPair = keyPair result.address = address + result.clientId = clientId result.networkId = networkId result.discovery = newDiscoveryProtocol(keyPair.seckey, address, bootstrapNodes) - result.peerPool = newPeerPool(chainDb, networkId, keyPair, result.discovery) + result.peerPool = newPeerPool(chainDb, networkId, keyPair, result.discovery, + clientId, address.tcpPort) let ta = initTAddress(address.ip, address.tcpPort) result.server = createStreamServer(ta, processIncoming, {ReuseAddr}, diff --git a/tests/tdiscovery.nim b/tests/tdiscovery.nim index 8bc0854..d2bff96 100644 --- a/tests/tdiscovery.nim +++ b/tests/tdiscovery.nim @@ -11,6 +11,8 @@ import sequtils, logging import eth_keys, asyncdispatch2, byteutils import eth_p2p/[discovery, kademlia, peer_pool, enode] +const clientId = "nim-eth-p2p/0.0.1" + addHandler(newConsoleLogger()) proc startDiscoveryNode(privKey: PrivateKey, address: Address, bootnodes: seq[ENode]): Future[DiscoveryProtocol] {.async.} = @@ -42,7 +44,9 @@ proc test() {.async.} = var nodeAddrs = newSeqOfCap[Address](nodeKeys.len) for i in 0 ..< nodeKeys.len: nodeAddrs.add(localAddress(20302 + i)) - var nodes = await all(zip(nodeKeys, nodeAddrs).mapIt(startDiscoveryNode(it.a, it.b, @[bootENode]))) + var nodes = await all(zip(nodeKeys, nodeAddrs).mapIt( + startDiscoveryNode(it.a, it.b, @[bootENode])) + ) nodes.add(bootNode) for i in nodes: diff --git a/tests/tserver.nim b/tests/tserver.nim index 78d8315..e61aedc 100644 --- a/tests/tserver.nim +++ b/tests/tserver.nim @@ -11,6 +11,8 @@ import sequtils import eth_keys, asyncdispatch2 import eth_p2p/[discovery, kademlia, peer_pool, enode, server, rlpx] +const clientId = "nim-eth-p2p/0.0.1" + proc localAddress(port: int): Address = let port = Port(port) result = Address(udpPort: port, tcpPort: port, ip: parseIpAddress("127.0.0.1")) @@ -19,11 +21,11 @@ proc test() {.async.} = let kp = newKeyPair() let address = localAddress(20301) - let s = newP2PServer(kp, address, nil, [], 1) + let s = newP2PServer(kp, address, nil, [], clientId, 1) s.start() let n = newNode(initENode(kp.pubKey, address)) - let peer = await rlpxConnect(n, newKeyPair(), Port(1234)) + let peer = await rlpxConnect(n, newKeyPair(), Port(1234), clientId) doAssert(not peer.isNil)