Skip to content

Commit

Permalink
Simplify client transports (#3069)
Browse files Browse the repository at this point in the history
* Remove transports param

* make servers a server

* Clean up transports references

* Clean up sync mode docs

* Fix logging

* remove console log

* fix integration tests
  • Loading branch information
acolytec3 authored Sep 29, 2023
1 parent f99a295 commit 001d498
Show file tree
Hide file tree
Showing 52 changed files with 222 additions and 336 deletions.
8 changes: 1 addition & 7 deletions packages/client/bin/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ const networks = Object.entries(Common.getInitializedChains().names)

let logger: Logger

// @ts-ignore because yargs isn't typing our args closely enough yet for arrays of strings (i.e. args.transports, args.bootnodes, etc)
// @ts-ignore because yargs isn't typing our args closely enough yet for arrays of strings (i.e. args.bootnodes, etc)
const args: ClientOpts = yargs(hideBin(process.argv))
.parserConfiguration({
'dot-notation': false,
Expand Down Expand Up @@ -101,11 +101,6 @@ const args: ClientOpts = yargs(hideBin(process.argv))
boolean: true,
default: true,
})
.option('transports', {
describe: 'Network transports',
default: Config.TRANSPORTS_DEFAULT,
array: true,
})
.option('bootnodes', {
describe: 'Comma-separated list of network bootnodes',
array: true,
Expand Down Expand Up @@ -829,7 +824,6 @@ async function run() {
disableBeaconSync: args.disableBeaconSync,
forceSnapSync: args.forceSnapSync,
prefixStorageTrieKeys: args.prefixStorageTrieKeys,
transports: args.transports?.length === 0 ? args.transports : undefined,
txLookupLimit: args.txLookupLimit,
})
config.events.setMaxListeners(50)
Expand Down
1 change: 0 additions & 1 deletion packages/client/browser/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ export async function createClient(args: any) {
const config = new Config({
common,
key,
transports: ['rlpx'],
syncmode: SyncMode.None,
bootnodes,
multiaddrs: [],
Expand Down
28 changes: 12 additions & 16 deletions packages/client/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,13 +148,10 @@ export class EthereumClient {
this.config.logger.info('Setup networking and services.')

await Promise.all(this.services.map((s) => s.start()))
await Promise.all(this.config.servers.map((s) => s.start()))
await Promise.all(
this.config.servers.map(async (s) => {
// Only call bootstrap if servers are actually started
if (s.started) await s.bootstrap()
})
)
this.config.server && (await this.config.server.start())
// Only call bootstrap if servers are actually started
this.config.server && this.config.server.started && (await this.config.server.bootstrap())

this.started = true
}

Expand All @@ -167,23 +164,22 @@ export class EthereumClient {
}
this.config.events.emit(Event.CLIENT_SHUTDOWN)
await Promise.all(this.services.map((s) => s.stop()))
await Promise.all(this.config.servers.map((s) => s.stop()))
this.config.server && this.config.server.started && (await this.config.server.stop())
this.started = false
}

/**
*
* @returns the RLPx server (if it exists)
*/
server() {
return this.config.server
}
/**
* Returns the service with the specified name.
* @param name name of service
*/
service(name: string) {
return this.services.find((s) => s.name === name)
}

/**
* Returns the server with the specified name.
* @param name name of server
*/
server(name: string) {
return this.config.servers.find((s) => s.name === name)
}
}
51 changes: 15 additions & 36 deletions packages/client/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { Level } from 'level'
import { getLogger } from './logging'
import { RlpxServer } from './net/server'
import { Event, EventBus } from './types'
import { isBrowser, parseTransports, short } from './util'
import { isBrowser, short } from './util'

import type { Logger } from './logging'
import type { EventBusType, MultiaddrLike } from './types'
Expand Down Expand Up @@ -36,7 +36,7 @@ export interface ConfigOptions {
common?: Common

/**
* Synchronization mode ('full' or 'light')
* Synchronization mode ('full', 'light', 'none')
*
* Default: 'full'
*/
Expand Down Expand Up @@ -94,13 +94,6 @@ export interface ConfigOptions {
*/
key?: Uint8Array

/**
* Network transports ('rlpx')
*
* Default: `['rlpx']`
*/
transports?: string[]

/**
* Network bootnodes
* (e.g. [email protected] or /ip4/127.0.0.1/tcp/50505/p2p/QmABC)
Expand All @@ -127,11 +120,9 @@ export interface ConfigOptions {

/**
* Transport servers (RLPx)
* Use `transports` option, only used for testing purposes
*
* Default: servers created from `transports` option
* Only used for testing purposes
*/
servers?: RlpxServer[]
server?: RlpxServer

/**
* Save tx receipts and logs in the meta db (default: false)
Expand Down Expand Up @@ -335,7 +326,6 @@ export class Config {
public static readonly SYNCMODE_DEFAULT = SyncMode.Full
public static readonly LIGHTSERV_DEFAULT = false
public static readonly DATADIR_DEFAULT = `./datadir`
public static readonly TRANSPORTS_DEFAULT = ['rlpx']
public static readonly PORT_DEFAULT = 30303
public static readonly MAXPERREQUEST_DEFAULT = 100
public static readonly MAXFETCHERJOBS_DEFAULT = 100
Expand Down Expand Up @@ -368,7 +358,6 @@ export class Config {
public readonly lightserv: boolean
public readonly datadir: string
public readonly key: Uint8Array
public readonly transports: string[]
public readonly bootnodes?: Multiaddr[]
public readonly port?: number
public readonly extIP?: string
Expand Down Expand Up @@ -422,15 +411,14 @@ export class Config {
public readonly chainCommon: Common
public readonly execCommon: Common

public readonly servers: RlpxServer[] = []
public readonly server: RlpxServer | undefined = undefined

constructor(options: ConfigOptions = {}) {
this.events = new EventBus() as EventBusType

this.syncmode = options.syncmode ?? Config.SYNCMODE_DEFAULT
this.vm = options.vm
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.extIP = options.extIP
Expand Down Expand Up @@ -497,26 +485,17 @@ export class Config {

this.logger = options.logger ?? getLogger({ loglevel: 'error' })

if (options.servers) {
if (options.transports) {
throw new Error(
'Config initialization with both servers and transports options not allowed'
)
this.logger.info(`Sync Mode ${this.syncmode}`)
if (this.syncmode !== SyncMode.None) {
if (options.server !== undefined) {
this.server = options.server
} else if (isBrowser() !== true) {
// Otherwise start server
const bootnodes: MultiaddrLike =
this.bootnodes ?? (this.chainCommon.bootstrapNodes() as any)
const dnsNetworks = options.dnsNetworks ?? this.chainCommon.dnsNetworks()
this.server = new RlpxServer({ config: this, bootnodes, dnsNetworks })
}
// Servers option takes precedence
this.servers = options.servers
} else if (isBrowser() !== true) {
// Otherwise parse transports from transports option
this.servers = parseTransports(this.transports).map((t) => {
if (t.name === 'rlpx') {
const bootnodes: MultiaddrLike =
this.bootnodes ?? (this.chainCommon.bootstrapNodes() as any)
const dnsNetworks = options.dnsNetworks ?? this.chainCommon.dnsNetworks()
return new RlpxServer({ config: this, bootnodes, dnsNetworks })
} else {
throw new Error(`unknown transport: ${t.name}`)
}
})
}

this.events.once(Event.CLIENT_SHUTDOWN, () => {
Expand Down
27 changes: 10 additions & 17 deletions packages/client/src/net/peerpool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ import { Hardfork } from '@ethereumjs/common'

import { Event } from '../types'

import { RlpxServer } from './server'

import type { Config } from '../config'
import type { Peer } from './peer'

Expand Down Expand Up @@ -236,23 +234,18 @@ export class PeerPool {
this.noPeerPeriods += 1
if (this.noPeerPeriods >= NO_PEER_PERIOD_COUNT) {
this.noPeerPeriods = 0
const promises = this.config.servers.map(async (server) => {
if (server instanceof RlpxServer) {
this.config.logger.info('Restarting RLPx server')
await server.stop()
await server.start()
this.config.logger.info('Reinitiating server bootstrap')
await server.bootstrap()
}
})
await Promise.all(promises)
if (this.config.server !== undefined) {
this.config.logger.info('Restarting RLPx server')
await this.config.server.stop()
await this.config.server.start()
this.config.logger.info('Reinitiating server bootstrap')
await this.config.server.bootstrap()
}
} else {
let tablesize: number | undefined = 0
for (const server of this.config.servers) {
if (server instanceof RlpxServer && server.discovery) {
tablesize = server.dpt?.getPeers().length
this.config.logger.info(`Looking for suited peers: peertablesize=${tablesize}`)
}
if (this.config.server !== undefined && this.config.server.discovery) {
tablesize = this.config.server.dpt?.getPeers().length
this.config.logger.info(`Looking for suited peers: peertablesize=${tablesize}`)
}
}
} else {
Expand Down
3 changes: 1 addition & 2 deletions packages/client/src/rpc/modules/admin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { middleware } from '../validation'

import type { Chain } from '../../blockchain'
import type { EthereumClient } from '../../client'
import type { RlpxServer } from '../../net/server'
import type { Service } from '../../service'

/**
Expand Down Expand Up @@ -34,7 +33,7 @@ export class Admin {
* @param params An empty array
*/
async nodeInfo(_params: []) {
const rlpxInfo = (this._client.server('rlpx') as RlpxServer).getRlpxInfo()
const rlpxInfo = this._client.config.server!.getRlpxInfo()
const { enode, id, ip, listenAddr, ports } = rlpxInfo
const { discovery, listener } = ports
const clientName = getClientVersion()
Expand Down
2 changes: 1 addition & 1 deletion packages/client/src/service/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ export class Service {
return false
}
const protocols = this.protocols
this.config.servers.map((s) => s.addProtocols(protocols))
this.config.server && this.config.server.addProtocols(protocols)

this.config.events.on(Event.POOL_PEER_BANNED, (peer) =>
this.config.logger.debug(`Peer banned: ${peer}`)
Expand Down
1 change: 0 additions & 1 deletion packages/client/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,6 @@ export interface ClientOpts {
gethGenesis?: string
trustedSetup?: string
mergeForkIdPostMerge?: boolean
transports?: string[]
bootnodes?: string | string[]
port?: number
extIP?: string
Expand Down
14 changes: 0 additions & 14 deletions packages/client/src/util/parse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,20 +69,6 @@ export function parseMultiaddrs(input: MultiaddrLike): Multiaddr[] {
}
}

export function parseTransports(transports: string[]) {
return transports.map((t) => {
const options: { [key: string]: string } = {}
const [name, ...pairs] = t.split(':')
if (pairs.length) {
for (const p of pairs.join(':').split(',')) {
const [key, value] = p.split('=')
options[key] = value
}
}
return { name, options }
})
}

/**
* Returns Uint8Array from input hexadecimal string or Uint8Array
* @param input hexadecimal string or Uint8Array
Expand Down
1 change: 0 additions & 1 deletion packages/client/test/cli/cli.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,6 @@ describe('[CLI]', () => {
'--port=30304',
'--dev=poa',
'--bootnodes=enode://[email protected]:30303',
'--transports=rlpx',
'--multiaddrs=enode://[email protected]:30303',
'--discDns=false',
'--discV4=false',
Expand Down
12 changes: 6 additions & 6 deletions packages/client/test/client.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { PeerPool } from '../src/net/peerpool'
import { RlpxServer } from '../src/net/server'

describe('[EthereumClient]', async () => {
const config = new Config({ transports: [], accountCache: 10000, storageCache: 1000 })
const config = new Config({ accountCache: 10000, storageCache: 1000 })
class FullEthereumService {
open() {}
start() {}
Expand Down Expand Up @@ -41,16 +41,16 @@ describe('[EthereumClient]', async () => {
})

it('should initialize correctly', async () => {
const config = new Config({ transports: [], accountCache: 10000, storageCache: 1000 })
const config = new Config({ accountCache: 10000, storageCache: 1000 })
const client = await EthereumClient.create({ config })
assert.ok('lightserv' in client.services[0], 'added FullEthereumService')
assert.ok('execution' in client.services[0], 'added FullEthereumService')
assert.ok('txPool' in client.services[0], 'added FullEthereumService')
})

it('should open', async () => {
const servers = [new RlpxServer({ config: new Config() })]
const config = new Config({ servers, accountCache: 10000, storageCache: 1000 })
const server = new RlpxServer({ config: new Config() })
const config = new Config({ server, accountCache: 10000, storageCache: 1000 })
const client = await EthereumClient.create({ config, metaDB: new MemoryLevel() })

await client.open()
Expand All @@ -59,8 +59,8 @@ describe('[EthereumClient]', async () => {
}, 30000)

it('should start/stop', async () => {
const servers = [new Server()] as any
const config = new Config({ servers, accountCache: 10000, storageCache: 1000 })
const server = new Server() as any
const config = new Config({ server, accountCache: 10000, storageCache: 1000 })
const client = await EthereumClient.create({ config, metaDB: new MemoryLevel() })
await client.start()
assert.ok(client.started, 'started')
Expand Down
4 changes: 2 additions & 2 deletions packages/client/test/execution/vmexecution.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ import shanghaiJSON from '../testdata/geth-genesis/withdrawals.json'
describe('[VMExecution]', async () => {
it('Initialization', async () => {
const vm = await VM.create()
const config = new Config({ vm, transports: [], accountCache: 10000, storageCache: 1000 })
const config = new Config({ vm, accountCache: 10000, storageCache: 1000 })
const chain = await Chain.create({ config })
const exec = new VMExecution({ config, chain })
assert.equal(exec.vm, vm, 'should use vm provided')
})

async function testSetup(blockchain: Blockchain, common?: Common) {
const config = new Config({ common, transports: [], accountCache: 10000, storageCache: 1000 })
const config = new Config({ common, accountCache: 10000, storageCache: 1000 })
const chain = await Chain.create({ config, blockchain })
const exec = new VMExecution({ config, chain })
await chain.open()
Expand Down
8 changes: 4 additions & 4 deletions packages/client/test/integration/client.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,17 @@ import { MockServer } from './mocks/mockserver'

describe('[Integration:EthereumClient]', async () => {
const serverConfig = new Config({ accountCache: 10000, storageCache: 1000 })
const servers = [new MockServer({ config: serverConfig }) as any]
const server = new MockServer({ config: serverConfig }) as any
const config = new Config({
servers,
server,
syncmode: SyncMode.Full,
lightserv: false,
accountCache: 10000,
storageCache: 1000,
})

// attach server to centralized event bus
;(config.servers[0].config as any).events = config.events
;(config.server!.config as any).events = config.events
const client = await EthereumClient.create({ config })

it('should start/stop', async () => {
Expand All @@ -30,7 +30,7 @@ describe('[Integration:EthereumClient]', async () => {
})
await client.open()
;(client.service('eth') as any).interval = 100
client.config.events.emit(Event.SERVER_ERROR, new Error('err0'), client.config.servers[0])
client.config.events.emit(Event.SERVER_ERROR, new Error('err0'), client.config.server!)
await client.start()
assert.ok((client.service('eth') as any).synchronizer.running, 'sync running')
await client.stop()
Expand Down
Loading

0 comments on commit 001d498

Please sign in to comment.