From 34ec4df0a546f1c6998ac6241e50c509ad0f9eaa Mon Sep 17 00:00:00 2001 From: holgerd77 Date: Thu, 11 Mar 2021 13:49:56 +0100 Subject: [PATCH 1/6] client: added RLPXServer discovery info, only restart RLPx server and provide feedback on peer searching when discovery enabled --- packages/client/lib/net/peerpool.ts | 6 +++--- packages/client/lib/net/server/rlpxserver.ts | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/client/lib/net/peerpool.ts b/packages/client/lib/net/peerpool.ts index e01a69c137c..6536779f911 100644 --- a/packages/client/lib/net/peerpool.ts +++ b/packages/client/lib/net/peerpool.ts @@ -204,7 +204,7 @@ export class PeerPool extends EventEmitter { this.noPeerPeriods += 1 if (this.noPeerPeriods >= 3) { const promises = this.config.servers.map(async (server) => { - if (server instanceof RlpxServer) { + if (server instanceof RlpxServer && server.discovery) { this.config.logger.info('Restarting RLPx server: bootstrap') await server.stop() await server.start() @@ -215,11 +215,11 @@ export class PeerPool extends EventEmitter { } else { let tablesize: number | undefined = 0 this.config.servers.forEach((server) => { - if (server instanceof RlpxServer) { + if (server instanceof RlpxServer && server.discovery) { tablesize = server.dpt?.getPeers().length + this.config.logger.info(`Looking for suited peers: peertablesize=${tablesize}`) } }) - this.config.logger.info(`Looking for suited peers: peertablesize=${tablesize}`) } } else { this.noPeerPeriods = 0 diff --git a/packages/client/lib/net/server/rlpxserver.ts b/packages/client/lib/net/server/rlpxserver.ts index 5ee2adad7ea..ec0716fae48 100644 --- a/packages/client/lib/net/server/rlpxserver.ts +++ b/packages/client/lib/net/server/rlpxserver.ts @@ -50,6 +50,7 @@ export class RlpxServer extends Server { private peers: Map = new Map() public port: number + public discovery: boolean private clientFilter: string[] public rlpx: Devp2pRLPx | null = null @@ -66,6 +67,7 @@ export class RlpxServer extends Server { // TODO: get the external ip from the upnp service this.ip = '::' this.port = options.port ?? 30303 + this.discovery = options.config.discV4 || options.config.discDns this.clientFilter = options.clientFilter ?? [ 'go1.5', 'go1.6', From 244796c27d69bbfe04d5bf2067b8d9f3c4ba18a4 Mon Sep 17 00:00:00 2001 From: holgerd77 Date: Thu, 11 Mar 2021 14:25:43 +0100 Subject: [PATCH 2/6] client: added RLPx port as a CLI option (local option was inactive before -> always defaulted to 30303) --- packages/client/bin/cli.ts | 5 ++++ packages/client/lib/config.ts | 14 +++++++++-- packages/client/lib/net/server/rlpxserver.ts | 25 ++++++++----------- .../client/test/net/server/rlpxserver.spec.ts | 4 +-- 4 files changed, 29 insertions(+), 19 deletions(-) diff --git a/packages/client/bin/cli.ts b/packages/client/bin/cli.ts index a9da2978d50..b3415e3093f 100755 --- a/packages/client/bin/cli.ts +++ b/packages/client/bin/cli.ts @@ -50,6 +50,10 @@ const args = require('yargs') describe: 'Network bootnodes', array: true, }, + port: { + describe: 'RLPx listening port', + default: Config.PORT_DEFAULT, + }, multiaddrs: { describe: 'Network multiaddrs', array: true, @@ -185,6 +189,7 @@ async function run() { key, transports: args.transports, bootnodes: args.bootnodes ? parseMultiaddrs(args.bootnodes) : undefined, + port: args.port, multiaddrs: args.multiaddrs ? parseMultiaddrs(args.multiaddrs) : undefined, rpc: args.rpc, rpcport: args.rpcport, diff --git a/packages/client/lib/config.ts b/packages/client/lib/config.ts index 8760480512e..234f6173d02 100644 --- a/packages/client/lib/config.ts +++ b/packages/client/lib/config.ts @@ -53,7 +53,7 @@ export interface ConfigOptions { /** * Network transports ('rlpx' and/or 'libp2p') * - * Default: `['rlpx:port=30303', 'libp2p']` + * Default: `['rlpx', 'libp2p']` */ transports?: string[] @@ -63,6 +63,13 @@ export interface ConfigOptions { */ bootnodes?: Multiaddr[] + /** + * RLPx listening port + * + * Default: `30303` + */ + port?: number + /** * Network multiaddrs for libp2p * (e.g. /ip4/127.0.0.1/tcp/50505/p2p/QmABC) @@ -167,7 +174,8 @@ export class Config { public static readonly SYNCMODE_DEFAULT = 'full' public static readonly LIGHTSERV_DEFAULT = false public static readonly DATADIR_DEFAULT = `./datadir` - public static readonly TRANSPORTS_DEFAULT = ['rlpx:port=30303', 'libp2p'] + public static readonly TRANSPORTS_DEFAULT = ['rlpx', 'libp2p'] + public static readonly PORT_DEFAULT = 30303 public static readonly RPC_DEFAULT = false public static readonly RPCPORT_DEFAULT = 8545 public static readonly RPCADDR_DEFAULT = 'localhost' @@ -185,6 +193,7 @@ export class Config { public readonly key: Buffer public readonly transports: string[] public readonly bootnodes?: Multiaddr[] + public readonly port?: number public readonly multiaddrs?: Multiaddr[] public readonly rpc: boolean public readonly rpcport: number @@ -208,6 +217,7 @@ export class Config { this.lightserv = options.lightserv ?? Config.LIGHTSERV_DEFAULT this.transports = options.transports ?? Config.TRANSPORTS_DEFAULT this.bootnodes = options.bootnodes + this.port = options.port ?? Config.PORT_DEFAULT this.multiaddrs = options.multiaddrs this.datadir = options.datadir ?? Config.DATADIR_DEFAULT this.key = options.key ?? genPrivateKey() diff --git a/packages/client/lib/net/server/rlpxserver.ts b/packages/client/lib/net/server/rlpxserver.ts index ec0716fae48..c5bf5ac2f85 100644 --- a/packages/client/lib/net/server/rlpxserver.ts +++ b/packages/client/lib/net/server/rlpxserver.ts @@ -3,9 +3,6 @@ import { RlpxPeer } from '../peer/rlpxpeer' import { Server, ServerOptions } from './server' export interface RlpxServerOptions extends ServerOptions { - /* Local port to listen on (default: 30303) */ - port?: number - /* List of supported clients */ clientFilter?: string[] } @@ -49,7 +46,6 @@ const ignoredErrors = new RegExp( export class RlpxServer extends Server { private peers: Map = new Map() - public port: number public discovery: boolean private clientFilter: string[] @@ -66,7 +62,6 @@ export class RlpxServer extends Server { // TODO: get the external ip from the upnp service this.ip = '::' - this.port = options.port ?? 30303 this.discovery = options.config.discV4 || options.config.discDns this.clientFilter = options.clientFilter ?? [ 'go1.5', @@ -99,17 +94,17 @@ export class RlpxServer extends Server { enode: undefined, id: undefined, ip: this.ip, - listenAddr: `[${this.ip}]:${this.port}`, - ports: { discovery: this.port, listener: this.port }, + listenAddr: `[${this.ip}]:${this.config.port}`, + ports: { discovery: this.config.port, listener: this.config.port }, } } const id = this.rlpx._id.toString('hex') return { - enode: `enode://${id}@[${this.ip}]:${this.port}`, + enode: `enode://${id}@[${this.ip}]:${this.config.port}`, id: id, ip: this.ip, - listenAddr: `[${this.ip}]:${this.port}`, - ports: { discovery: this.port, listener: this.port }, + listenAddr: `[${this.ip}]:${this.config.port}`, + ports: { discovery: this.config.port, listener: this.config.port }, } } @@ -232,8 +227,8 @@ export class RlpxServer extends Server { this.dpt.on('error', (e: Error) => this.error(e)) - if (this.port) { - this.dpt.bind(this.port, '0.0.0.0') + if (this.config.port) { + this.dpt.bind(this.config.port, '0.0.0.0') } } @@ -247,7 +242,7 @@ export class RlpxServer extends Server { maxPeers: this.config.maxPeers, capabilities: RlpxPeer.capabilities(Array.from(this.protocols)), remoteClientIdFilter: this.clientFilter, - listenPort: this.port, + listenPort: this.config.port, common: this.config.chainCommon, }) @@ -303,8 +298,8 @@ export class RlpxServer extends Server { }) }) - if (this.port) { - this.rlpx.listen(this.port, '0.0.0.0') + if (this.config.port) { + this.rlpx.listen(this.config.port, '0.0.0.0') } } } diff --git a/packages/client/test/net/server/rlpxserver.spec.ts b/packages/client/test/net/server/rlpxserver.spec.ts index 3d787790eb1..2d476ea7bae 100644 --- a/packages/client/test/net/server/rlpxserver.spec.ts +++ b/packages/client/test/net/server/rlpxserver.spec.ts @@ -179,7 +179,7 @@ tape('[RlpxServer]', async (t) => { const config = new Config({ loglevel: 'error', transports: [] }) const server = new RlpxServer({ config }) server.initDpt() - td.verify((server.dpt as any).bind(server.port, '0.0.0.0')) + td.verify((server.dpt as any).bind(server.config.port, '0.0.0.0')) server.on('error', (err: any) => t.equals(err, 'err0', 'got error')) ;(server.dpt as any).emit('error', 'err0') }) @@ -193,7 +193,7 @@ tape('[RlpxServer]', async (t) => { td.when(RlpxPeer.prototype.accept(rlpxPeer, td.matchers.isA(RlpxServer))).thenResolve() server.initRlpx() td.verify(RlpxPeer.capabilities(Array.from((server as any).protocols))) - td.verify(server.rlpx!.listen(server.port, '0.0.0.0')) + td.verify(server.rlpx!.listen(server.config.port, '0.0.0.0')) server.on('connected', (peer: any) => t.ok(peer instanceof RlpxPeer, 'connected')) server.on('disconnected', (peer: any) => t.equals(peer.id, '01', 'disconnected')) server.on('error', (err: Error) => t.equals(err.message, 'err0', 'got error')) From 5fe3b37c0cdfc16bf8a056804684c64bd12ec879 Mon Sep 17 00:00:00 2001 From: holgerd77 Date: Thu, 11 Mar 2021 14:49:55 +0100 Subject: [PATCH 3/6] client: added dedicated dev node start commands for local client connection debugging, added networking debugging section in developer README --- packages/client/README.md | 21 +++++++++++++++++++++ packages/client/package.json | 2 ++ 2 files changed, 23 insertions(+) diff --git a/packages/client/README.md b/packages/client/README.md index 6ae2ac453da..fe43e2d189e 100644 --- a/packages/client/README.md +++ b/packages/client/README.md @@ -337,6 +337,27 @@ to help contributors better understand how the project is organized. ## Developer +### Debugging + +#### Networking + +For debugging on networking issues two npm start scripts exist to set up two local client nodes to test networking connection flow. + +Start a first client listening on the default port and using the default data directory with: + +```shell +DEBUG=devp2p:* npm run client:start:dev1 +DEBUG=devp2p:* npm run client:start:dev1 -- --datadir=datadir-dev1 +``` + +Then take the enode address from the started client instance (use `127.0.0.1` for the IP address) and start a second client with: + +```shell +DEBUG=devp2p:* npm run client:start:dev2 -- --bootnodes=enode://[NODE_ID]@127.0.0.1:30303 +``` + +This second client is using './datadir-dev2' for its data directory. + ### Diagram Updates To update the structure diagram files in the root folder open the `client.drawio` file in [draw.io](https://draw.io/), make your changes, and open a PR with the updated files. Export `svg` and `png` with `border` `width=20` and `transparency=false`. For `png` go to "Advanced" and select `300 DPI`. diff --git a/packages/client/package.json b/packages/client/package.json index 5cfa3fdd659..ee3fb196578 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -19,6 +19,8 @@ "prepublishOnly": "npm run build && npm run test", "bundle": "webpack", "client:start": "ts-node bin/cli.ts", + "client:start:dev1": "ts-node bin/cli.ts --discDns=false --discV4=false --bootnodes", + "client:start:dev2": "ts-node bin/cli.ts --discDns=false --discV4=false --transports=rlpx --port=30304 --datadir=datadir-dev2", "coverage": "nyc npm run test && nyc report --reporter=lcov", "docs:build": "typedoc --tsconfig tsconfig.prod.json", "lint": "ethereumjs-config-lint", From 0959546b9edb54ddb24c526c540168288ab5fed8 Mon Sep 17 00:00:00 2001 From: holgerd77 Date: Fri, 12 Mar 2021 10:55:59 +0100 Subject: [PATCH 4/6] client: ensure config directory in CLI (fixes bug when starting with custom datadir) --- packages/client/bin/cli.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/client/bin/cli.ts b/packages/client/bin/cli.ts index b3415e3093f..d9e59ea273f 100755 --- a/packages/client/bin/cli.ts +++ b/packages/client/bin/cli.ts @@ -180,6 +180,8 @@ async function run() { const common = new Common({ chain, hardfork: 'chainstart' }) const datadir = args.datadir ?? Config.DATADIR_DEFAULT + const configDirectory = `${datadir}/${common.chainName()}/config` + fs.ensureDirSync(configDirectory) const key = await Config.getClientKey(datadir, common) const config = new Config({ common, From 63e7780bc136b673ede54c6d1c3856d8cc69f3c1 Mon Sep 17 00:00:00 2001 From: holgerd77 Date: Fri, 12 Mar 2021 12:21:03 +0100 Subject: [PATCH 5/6] client: added local geth connection instructions to developer debug section in README --- packages/client/README.md | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/packages/client/README.md b/packages/client/README.md index fe43e2d189e..d04d21a5b01 100644 --- a/packages/client/README.md +++ b/packages/client/README.md @@ -341,7 +341,9 @@ to help contributors better understand how the project is organized. #### Networking -For debugging on networking issues two npm start scripts exist to set up two local client nodes to test networking connection flow. +##### Local Connection: EthereumJS <- EthereumJS + +For debugging on networking issues there are two custom npm start scripts with appropriate settings. Start a first client listening on the default port and using the default data directory with: @@ -353,11 +355,43 @@ DEBUG=devp2p:* npm run client:start:dev1 -- --datadir=datadir-dev1 Then take the enode address from the started client instance (use `127.0.0.1` for the IP address) and start a second client with: ```shell -DEBUG=devp2p:* npm run client:start:dev2 -- --bootnodes=enode://[NODE_ID]@127.0.0.1:30303 +DEBUG=devp2p:* npm run client:start:dev2 -- --bootnodes=enode://[DEV1_NODE_ID]@127.0.0.1:30303 ``` This second client is using './datadir-dev2' for its data directory. +##### Local Connection: EthereumJS <- Geth + +To connect Geth to a running EthereumJS instance start a client with: + +```shell +DEBUG=devp2p:* npm run client:start:dev1 +``` + +Then connect with your Geth instance via: + +```shell +geth --maxpeers=1 --bootnodes=enode://[DEV1_NODE_ID]@127.0.0.1:30303 +``` + +Depending on your use case you might want to turn off your internet connection to not allow further incoming connections on your Geth instance in case the EthereumJS connection gets disconnected. + +##### Local Connection: Geth <- EthereumJS + +Start your Geth instance: + +```shell +geth [--syncmode=full] [--verbosity=5] +``` + +Note that you might want to turn off your internet connection to limit on the Geth discovery process (setting the `--nodiscover` flag won't work since this also disallows our local client from connecting). + +Then connect with your EthereumJS instance via: + +```shell +DEBUG=devp2p:* npm run client:start:dev2 -- --bootnodes=enode://[GETH_NODE_ID]@127.0.0.1:30303 +``` + ### Diagram Updates To update the structure diagram files in the root folder open the `client.drawio` file in [draw.io](https://draw.io/), make your changes, and open a PR with the updated files. Export `svg` and `png` with `border` `width=20` and `transparency=false`. For `png` go to "Advanced" and select `300 DPI`. From 8861290c515590823617f22936c295253e2b5154 Mon Sep 17 00:00:00 2001 From: Ryan Ghods Date: Fri, 12 Mar 2021 13:14:02 -0800 Subject: [PATCH 6/6] dedupe `client:start` script --- packages/client/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/client/package.json b/packages/client/package.json index ee3fb196578..2142790c5a8 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -19,8 +19,8 @@ "prepublishOnly": "npm run build && npm run test", "bundle": "webpack", "client:start": "ts-node bin/cli.ts", - "client:start:dev1": "ts-node bin/cli.ts --discDns=false --discV4=false --bootnodes", - "client:start:dev2": "ts-node bin/cli.ts --discDns=false --discV4=false --transports=rlpx --port=30304 --datadir=datadir-dev2", + "client:start:dev1": "npm run client:start -- --discDns=false --discV4=false --bootnodes", + "client:start:dev2": "npm run client:start -- --discDns=false --discV4=false --transports=rlpx --port=30304 --datadir=datadir-dev2", "coverage": "nyc npm run test && nyc report --reporter=lcov", "docs:build": "typedoc --tsconfig tsconfig.prod.json", "lint": "ethereumjs-config-lint",