Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify client transports #3069

Merged
merged 9 commits into from
Sep 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 { 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 @@
common?: Common

/**
* Synchronization mode ('full' or 'light')
* Synchronization mode ('full', 'light', 'none')
*
* Default: 'full'
*/
Expand Down Expand Up @@ -94,13 +94,6 @@
*/
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 @@

/**
* 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 @@
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 @@
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 @@
public readonly chainCommon: Common
public readonly execCommon: Common

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

Check warning on line 414 in packages/client/src/config.ts

View check run for this annotation

Codecov / codecov/patch

packages/client/src/config.ts#L414

Added line #L414 was not covered by tests

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 @@

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 { 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 @@
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()
}

Check warning on line 243 in packages/client/src/net/peerpool.ts

View check run for this annotation

Codecov / codecov/patch

packages/client/src/net/peerpool.ts#L237-L243

Added lines #L237 - L243 were not covered by tests
} 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) {

Check warning on line 246 in packages/client/src/net/peerpool.ts

View check run for this annotation

Codecov / codecov/patch

packages/client/src/net/peerpool.ts#L246

Added line #L246 was not covered by tests
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
Loading