-
Notifications
You must be signed in to change notification settings - Fork 27
Expand file tree
/
Copy pathconfig.ts
More file actions
128 lines (117 loc) · 3.68 KB
/
config.ts
File metadata and controls
128 lines (117 loc) · 3.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import { execSync } from 'child_process'
import { readFileSync } from 'fs'
import { SignableENR } from '@chainsafe/enr'
import { hexToBytes } from '@ethereumjs/util'
import { keys } from '@libp2p/crypto'
import { multiaddr } from '@multiformats/multiaddr'
import { Level } from 'level'
import { NetworkId } from '../networks/types.js'
import { setupMetrics } from './metrics.js'
import type { NetworkConfig, PortalNetworkOpts } from '../client'
import { DEFAULT_BOOTNODES } from './bootnodes.js'
export type AsyncReturnType<T extends (...args: any) => Promise<any>> = T extends (
...args: any
) => Promise<infer R>
? R
: any
export interface PortalClientOpts {
pk?: string
bootnode?: string
bindAddress?: string
bootnodeList?: string
dataDir?: string
networks: string
storage: string
trustedBlockRoot?: string
gossipCount?: number
}
export const NetworkStrings: Record<string, NetworkId> = {
history: NetworkId.HistoryNetwork,
beacon: NetworkId.BeaconChainNetwork,
state: NetworkId.StateNetwork,
}
export const cliConfig = async (args: PortalClientOpts) => {
const cmd = 'hostname -I'
const ip =
args.bindAddress !== undefined
? args.bindAddress.split(':')[0]
: execSync(cmd).toString().split(' ')[0].trim()
const bindPort = args.bindAddress !== undefined ? args.bindAddress.split(':')[1] : 9000 // Default discv5 port
let privateKey: AsyncReturnType<typeof keys.generateKeyPair>
try {
if (args.pk === undefined) {
privateKey = await keys.generateKeyPair('secp256k1')
} else {
privateKey = keys.privateKeyFromRaw(hexToBytes(args.pk).slice(-32))
}
} catch (err: any) {
throw new Error(`Error using pk: ${args.pk}\n${err.message}`)
}
const enr = SignableENR.createFromPrivateKey(privateKey)
const initMa = multiaddr(`/ip4/${ip}/udp/${bindPort}`)
enr.setLocationMultiaddr(initMa)
let db
if (args.dataDir !== undefined) {
db = new Level<string, string>(args.dataDir)
}
const config = {
enr,
privateKey,
config: {
enrUpdate: true,
addrVotesToUpdateEnr: 5,
allowUnverifiedSessions: true,
requestTimeout: 3000,
},
bindAddrs: {
ip4: initMa,
},
trustedBlockRoot: args.trustedBlockRoot,
} as any
const networks: NetworkConfig[] = []
const argsNetworks = args.networks.split(',')
const argsStorage = args.storage.split(',').map((x) => parseInt(x))
for (const [i, network] of argsNetworks.entries()) {
let networkdb
if (args.dataDir !== undefined) {
networkdb = {
db: new Level<string, string>(args.dataDir + '/' + network, { createIfMissing: true }),
path: args.dataDir + '/' + network,
}
}
networks.push({
networkId: NetworkStrings[network],
maxStorage: argsStorage[i],
//@ts-ignore Because level doesn't know how to get along with itself
db: networkdb,
})
}
const bootnodes: Array<string> = []
if (args.bootnode !== undefined) {
bootnodes.push(args.bootnode)
}
if (args.bootnodeList !== undefined) {
const bootnodeData = readFileSync(args.bootnodeList, 'utf-8')
const bootnodeList = bootnodeData.split('\n')
for (const bootnode of bootnodeList) {
bootnodes.push(bootnode)
}
}
const metrics = setupMetrics(networks.map((x) => x.networkId))
const clientConfig: Partial<PortalNetworkOpts> = {
config,
//@ts-ignore Because level doesn't know how to get along with itself
db,
metrics,
supportedNetworks: networks,
dataDir: args.dataDir,
trustedBlockRoot: args.trustedBlockRoot,
bootnodes,
gossipCount: args.gossipCount,
}
return clientConfig
}
export const DEFAULT_OPTS = {
bindAddress: '0.0.0.0',
bootnodes: DEFAULT_BOOTNODES.mainnet,
}