Skip to content

Commit 22c8a4a

Browse files
authored
Merge pull request #1097 from ethereumjs/1459-tuning
Add node discovery mode flags & define network-based defaults
2 parents 0a672de + 353c520 commit 22c8a4a

File tree

7 files changed

+133
-19
lines changed

7 files changed

+133
-19
lines changed

packages/client/bin/cli.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,14 @@ const args = require('yargs')
9393
boolean: true,
9494
default: Config.DEBUGCODE_DEFAULT,
9595
},
96+
discDns: {
97+
describe: 'Query EIP-1459 DNS TXT records for peer discovery',
98+
boolean: true,
99+
},
100+
discV4: {
101+
describe: 'Use v4 ("findneighbour" node requests) for peer discovery',
102+
boolean: true,
103+
},
96104
})
97105
.locale('en_EN').argv
98106

@@ -174,6 +182,8 @@ async function run() {
174182
dnsAddr: args.dnsAddr,
175183
dnsNetworks: args.dnsNetworks,
176184
debugCode: args.debugCode,
185+
discDns: args.discDns,
186+
discV4: args.discV4,
177187
})
178188
logger = config.logger
179189

packages/client/lib/config.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,20 @@ export interface ConfigOptions {
123123
* (meant to be used internally for the most part)
124124
*/
125125
debugCode?: boolean
126+
127+
/**
128+
* Query EIP-1459 DNS TXT records for peer discovery
129+
*
130+
* Default: `true` for testnets, false for mainnet
131+
*/
132+
discDns?: boolean
133+
134+
/**
135+
* Use v4 ("findneighbour" node requests) for peer discovery
136+
*
137+
* Default: `false` for testnets, true for mainnet
138+
*/
139+
discV4?: boolean
126140
}
127141

128142
export class Config {
@@ -154,6 +168,8 @@ export class Config {
154168
public readonly maxPeers: number
155169
public readonly dnsAddr: string
156170
public readonly debugCode: boolean
171+
public readonly discDns: boolean
172+
public readonly discV4: boolean
157173

158174
public readonly chainCommon: Common
159175
public readonly execCommon: Common
@@ -181,6 +197,9 @@ export class Config {
181197
this.chainCommon = Object.assign(Object.create(Object.getPrototypeOf(common)), common)
182198
this.execCommon = Object.assign(Object.create(Object.getPrototypeOf(common)), common)
183199

200+
this.discDns = this.getDnsDiscovery(options.discDns)
201+
this.discV4 = this.getV4Discovery(options.discV4)
202+
184203
if (options.logger) {
185204
if (options.loglevel) {
186205
throw new Error('Config initialization with both logger and loglevel options not allowed')
@@ -244,4 +263,23 @@ export class Config {
244263
const dataDir = `${this.datadir}/${networkDirName}/state`
245264
return dataDir
246265
}
266+
267+
/**
268+
* Returns specified option or the default setting for whether DNS-based peer discovery
269+
* is enabled based on chainName. `true` for ropsten, rinkeby, and goerli
270+
*/
271+
getDnsDiscovery(option: boolean | undefined): boolean {
272+
if (option !== undefined) return option
273+
const dnsNets = ['ropsten', 'rinkeby', 'goerli']
274+
return dnsNets.includes(this.chainCommon.chainName())
275+
}
276+
277+
/**
278+
* Returns specified option or the default setting for whether v4 peer discovery
279+
* is enabled based on chainName. `true` for `mainnet`
280+
*/
281+
getV4Discovery(option: boolean | undefined): boolean {
282+
if (option !== undefined) return option
283+
return this.chainCommon.chainName() === 'mainnet'
284+
}
247285
}

packages/client/lib/net/server/rlpxserver.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,10 @@ export class RlpxServer extends Server {
150150
})
151151

152152
// DNS peers
153-
const dnsPeers = (await this.dpt?.getDnsPeers()) ?? []
154-
promises = promises.concat(dnsPeers.map((node) => self.dpt!.bootstrap(node)))
153+
if (this.config.discDns) {
154+
const dnsPeers = (await this.dpt?.getDnsPeers()) ?? []
155+
promises = promises.concat(dnsPeers.map((node) => self.dpt!.bootstrap(node)))
156+
}
155157

156158
for (const promise of promises) {
157159
try {
@@ -219,7 +221,8 @@ export class RlpxServer extends Server {
219221
udpPort: null,
220222
tcpPort: null,
221223
},
222-
shouldFindNeighbours: this.dnsNetworks.length ? false : true,
224+
shouldFindNeighbours: this.config.discV4,
225+
shouldGetDnsPeers: this.config.discDns,
223226
dnsRefreshQuantity: this.config.maxPeers,
224227
dnsNetworks: this.dnsNetworks,
225228
dnsAddr: this.config.dnsAddr,

packages/client/test/config.spec.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import tape from 'tape-catch'
22
import { Config } from '../lib/config'
3+
import Common from '@ethereumjs/common'
34

45
tape('[Config]', (t) => {
56
t.test('Initialization with default parameters', (t) => {
@@ -25,4 +26,54 @@ tape('[Config]', (t) => {
2526
t.equal(config.getStateDataDirectory(), './datadir/mainnet/state')
2627
t.end()
2728
})
29+
30+
t.test('peer discovery default mainnet setting', (t) => {
31+
const common = new Common({ chain: 'mainnet' })
32+
const config = new Config({ common })
33+
t.equal(config.discDns, false, 'disables DNS peer discovery for mainnet')
34+
t.equal(config.discV4, true, 'enables DNS peer discovery for mainnet')
35+
t.end()
36+
})
37+
38+
t.test('peer discovery default testnet settings', (t) => {
39+
let config
40+
41+
for (const chain of ['rinkeby', 'goerli', 'ropsten']) {
42+
const common = new Common({ chain })
43+
config = new Config({ common })
44+
t.equal(config.discDns, true, `enables DNS peer discovery for ${chain}`)
45+
t.equal(config.discV4, false, `disables V4 peer discovery for ${chain}`)
46+
}
47+
t.end()
48+
})
49+
50+
t.test('--discDns=true/false', (t) => {
51+
let common, config, chain
52+
53+
chain = 'mainnet'
54+
common = new Common({ chain })
55+
config = new Config({ common, discDns: true })
56+
t.equal(config.discDns, true, `default discDns setting can be overridden to true`)
57+
58+
chain = 'rinkeby'
59+
common = new Common({ chain })
60+
config = new Config({ common, discDns: false })
61+
t.equal(config.discDns, false, `default discDns setting can be overridden to false`)
62+
t.end()
63+
})
64+
65+
t.test('--discV4=true/false', (t) => {
66+
let common, config, chain
67+
68+
chain = 'mainnet'
69+
common = new Common({ chain })
70+
config = new Config({ common, discV4: false })
71+
t.equal(config.discDns, false, `default discV4 setting can be overridden to false`)
72+
73+
chain = 'rinkeby'
74+
common = new Common({ chain })
75+
config = new Config({ common, discV4: true })
76+
t.equal(config.discDns, true, `default discV4 setting can be overridden to true`)
77+
t.end()
78+
})
2879
})

packages/client/test/net/server/rlpxserver.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ tape('[RlpxServer]', async (t) => {
9090

9191
t.test('should bootstrap with dns acquired peers', async (t) => {
9292
const dnsPeerInfo = { address: '10.0.0.5', udpPort: 1234, tcpPort: 1234 }
93-
const config = new Config({ loglevel: 'error', transports: [] })
93+
const config = new Config({ loglevel: 'error', transports: [], discDns: true })
9494
const server = new RlpxServer({
9595
config,
9696
dnsNetworks: ['enrtree:A'],

packages/devp2p/src/dpt/dpt.ts

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,13 @@ export interface DPTOptions {
5555
*/
5656
shouldFindNeighbours?: boolean
5757

58+
/**
59+
* Toggles whether or not peers should be discovered by querying EIP-1459 DNS lists
60+
*
61+
* Default: false
62+
*/
63+
shouldGetDnsPeers?: boolean
64+
5865
/**
5966
* Max number of candidate peers to retrieve from DNS records when
6067
* attempting to discover new nodes
@@ -87,6 +94,7 @@ export class DPT extends EventEmitter {
8794
private _refreshIntervalId: NodeJS.Timeout
8895
private _refreshIntervalSelectionCounter: number = 0
8996
private _shouldFindNeighbours: boolean
97+
private _shouldGetDnsPeers: boolean
9098
private _dnsRefreshQuantity: number
9199
private _dnsNetworks: string[]
92100
private _dnsAddr: string
@@ -97,6 +105,7 @@ export class DPT extends EventEmitter {
97105
this.privateKey = Buffer.from(privateKey)
98106
this._id = pk2id(Buffer.from(publicKeyCreate(this.privateKey, false)))
99107
this._shouldFindNeighbours = options.shouldFindNeighbours === false ? false : true
108+
this._shouldGetDnsPeers = options.shouldGetDnsPeers ?? false
100109
// By default, tries to connect to 12 new peers every 3s
101110
this._dnsRefreshQuantity = Math.floor((options.dnsRefreshQuantity ?? 25) / 2)
102111
this._dnsNetworks = options.dnsNetworks ?? []
@@ -117,9 +126,15 @@ export class DPT extends EventEmitter {
117126
})
118127
this._server.once('listening', () => this.emit('listening'))
119128
this._server.once('close', () => this.emit('close'))
120-
this._server.on('peers', (peers) => this._onServerPeers(peers))
121129
this._server.on('error', (err) => this.emit('error', err))
122130

131+
// When not using peer neighbour discovery we don't add peers here
132+
// because it results in duplicate calls for the same targets
133+
this._server.on('peers', (peers) => {
134+
if (!this._shouldFindNeighbours) return
135+
this._addPeerBatch(peers)
136+
})
137+
123138
// By default calls refresh every 3s
124139
const refreshIntervalSubdivided = Math.floor((options.refreshInterval ?? ms('60s')) / 10)
125140
this._refreshIntervalId = setInterval(() => this.refresh(), refreshIntervalSubdivided)
@@ -155,12 +170,7 @@ export class DPT extends EventEmitter {
155170
}
156171
}
157172

158-
_onServerPeers(peers: PeerInfo[]): void {
159-
// We don't want this to run when using
160-
// dns - it's fired in the server.on:peer hook
161-
// and results in duplicate addition attempts
162-
if (!this._shouldFindNeighbours) return
163-
173+
_addPeerBatch(peers: PeerInfo[]): void {
164174
const DIFF_TIME_MS = 200
165175
let ms = 0
166176
for (const peer of peers) {
@@ -251,16 +261,16 @@ export class DPT extends EventEmitter {
251261
}
252262
}
253263

254-
const dnsPeers = await this.getDnsPeers()
264+
if (this._shouldGetDnsPeers) {
265+
const dnsPeers = await this.getDnsPeers()
255266

256-
debug(
257-
`.refresh() (Adding ${dnsPeers.length}) from DNS tree, (${
258-
this.getPeers().length
259-
} current peers in table)`
260-
)
267+
debug(
268+
`.refresh() Adding ${dnsPeers.length} from DNS tree, (${
269+
this.getPeers().length
270+
} current peers in table)`
271+
)
261272

262-
for (const peer of dnsPeers) {
263-
await this.bootstrap(peer)
273+
this._addPeerBatch(dnsPeers)
264274
}
265275
}
266276
}

packages/devp2p/test/integration/util.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ export function getTestDPTsWithDns(numDPTs: number) {
3737
timeout: 100,
3838
refreshInterval: 10,
3939
dnsNetworks: [testdata.dns.enrTree],
40+
shouldFindNeighbours: false,
41+
shouldGetDnsPeers: true,
4042
})
4143
dpt.bind(basePort + i)
4244
dpts.push(dpt)

0 commit comments

Comments
 (0)