fix generateGenesis setting toBalance, don't overwrite codeHash and stateRoot, tidy
fix chalk output, update chalk to latest, tidy file and add typedocs
attempt to resolve peer:error event handler memory leak by removing bound listener after disconnect, tidy
fix new webpack polyfill errors from node-fetch, which we don't use so can safely pass false
nit: more stateManager generateGenesis code tidying
update multiaddrs to latest to fix libp2p so it doesn't bring node-fetch into webpack/karma
Showing 10 of 21 files from the diff.
packages/client/lib/logging.ts
changed.
packages/devp2p/src/dns/enr.ts
changed.
packages/client/lib/types.ts
changed.
packages/client/lib/config.ts
changed.
packages/client/lib/util/parse.ts
changed.
Other files ignored by Codecov
packages/client/test/logging.spec.ts
has changed.
packages/client/test/util/parse.spec.ts
has changed.
packages/vm/src/state/stateManager.ts
has changed.
package-lock.json
has changed.
packages/client/package.json
has changed.
packages/client/webpack.config.js
has changed.
packages/devp2p/package.json
has changed.
packages/client/browser/libp2pnode.ts
has changed.
packages/client/test/net/server/rlpxserver.spec.ts
has changed.
packages/client/test/net/peer/libp2ppeer.spec.ts
has changed.
@@ -1,4 +1,4 @@
Loading
1 | - | import multiaddr from 'multiaddr' |
|
1 | + | import { Multiaddr, multiaddr } from 'multiaddr' |
|
2 | 2 | import PeerId from 'peer-id' |
|
3 | 3 | import { Libp2pMuxedStream as MuxedStream } from '../../types' |
|
4 | 4 | import { Libp2pSender } from '../protocol/libp2psender' |
@@ -7,9 +7,10 @@
Loading
7 | 7 | import { Protocol } from '../protocol' |
|
8 | 8 | import { Libp2pServer } from '../server' |
|
9 | 9 | import { Event } from '../../types' |
|
10 | + | ||
10 | 11 | export interface Libp2pPeerOptions extends Omit<PeerOptions, 'address' | 'transport'> { |
|
11 | 12 | /* Multiaddrs to listen on */ |
|
12 | - | multiaddrs?: multiaddr[] |
|
13 | + | multiaddrs?: Multiaddr[] |
|
13 | 14 | } |
|
14 | 15 | ||
15 | 16 | /** |
@@ -17,7 +18,7 @@
Loading
17 | 18 | * @memberof module:net/peer |
|
18 | 19 | * @example |
|
19 | 20 | * ```typescript |
|
20 | - | * import multiaddr from 'multiaddr' |
|
21 | + | * import { multiaddr } from 'multiaddr' |
|
21 | 22 | * import { Libp2pPeer } from './lib/net/peer' |
|
22 | 23 | * import { Chain } from './lib/blockchain' |
|
23 | 24 | * import { EthProtocol } from './lib/net/protocol' |
@@ -35,7 +36,7 @@
Loading
35 | 36 | * ``` |
|
36 | 37 | */ |
|
37 | 38 | export class Libp2pPeer extends Peer { |
|
38 | - | private multiaddrs: multiaddr[] |
|
39 | + | private multiaddrs: Multiaddr[] |
|
39 | 40 | private connected: boolean |
|
40 | 41 | ||
41 | 42 | /** |
@@ -63,7 +64,7 @@
Loading
63 | 64 | const node = new Libp2pNode({ peerId, addresses }) |
|
64 | 65 | await node.start() |
|
65 | 66 | for (const ma of this.multiaddrs) { |
|
66 | - | await node.dial(ma) |
|
67 | + | await node.dial(ma as any) |
|
67 | 68 | await this.bindProtocols(node, ma) |
|
68 | 69 | } |
|
69 | 70 | this.config.events.emit(Event.PEER_CONNECTED, this) |
@@ -86,7 +87,7 @@
Loading
86 | 87 | */ |
|
87 | 88 | async bindProtocols( |
|
88 | 89 | node: Libp2pNode, |
|
89 | - | peer: PeerId | multiaddr, |
|
90 | + | peer: PeerId | Multiaddr, |
|
90 | 91 | server?: Libp2pServer |
|
91 | 92 | ): Promise<void> { |
|
92 | 93 | await Promise.all( |
@@ -94,7 +95,7 @@
Loading
94 | 95 | await p.open() |
|
95 | 96 | const protocol = `/${p.name}/${p.versions[0]}` |
|
96 | 97 | try { |
|
97 | - | const { stream } = await node.dialProtocol(peer, protocol) |
|
98 | + | const { stream } = await node.dialProtocol(peer as any, protocol) |
|
98 | 99 | await this.bindProtocol(p, new Libp2pSender(stream)) |
|
99 | 100 | } catch (err: any) { |
|
100 | 101 | const peerInfo = peer instanceof PeerId ? `id=${peer.toB58String()}` : `multiaddr=${peer}` |
@@ -4,32 +4,41 @@
Loading
4 | 4 | ||
5 | 5 | export type Logger = WinstonLogger |
|
6 | 6 | ||
7 | - | const levelColors = { |
|
8 | - | error: 'red', |
|
9 | - | warn: 'yellow', |
|
10 | - | info: 'green', |
|
11 | - | debug: 'white', |
|
12 | - | } |
|
13 | - | ||
14 | 7 | const { combine, timestamp, label, printf } = format |
|
15 | 8 | ||
9 | + | /** |
|
10 | + | * Colors for logger levels |
|
11 | + | */ |
|
12 | + | enum LevelColors { |
|
13 | + | error = 'red', |
|
14 | + | warn = 'yellow', |
|
15 | + | info = 'green', |
|
16 | + | debug = 'white', |
|
17 | + | } |
|
18 | + | ||
19 | + | /* |
|
20 | + | * Adds stack trace to error message if included |
|
21 | + | */ |
|
16 | 22 | const errorFormat = format((info: any) => { |
|
17 | 23 | if (info.message instanceof Error && info.message.stack) { |
|
18 | - | info.message = info.message.stack |
|
24 | + | return { ...info, message: info.message.stack } |
|
19 | 25 | } |
|
20 | 26 | if (info instanceof Error && info.stack) { |
|
21 | - | return Object.assign({}, info, { message: info.stack }) |
|
27 | + | return { ...info, message: info.stack } |
|
22 | 28 | } |
|
23 | 29 | return info |
|
24 | 30 | }) |
|
25 | 31 | ||
26 | - | function logFormat(colors = true) { |
|
32 | + | /** |
|
33 | + | * Returns the formatted log output optionally with colors enabled |
|
34 | + | */ |
|
35 | + | function logFormat(colors = false) { |
|
27 | 36 | return printf((info: any) => { |
|
28 | 37 | let level = info.level.toUpperCase() |
|
29 | 38 | if (colors) { |
|
30 | - | // @ts-ignore: implicitly has an 'any' TODO |
|
31 | - | const color = chalk[levelColors[info.level]].bind(chalk) |
|
32 | - | level = color(info.level.toUpperCase()) |
|
39 | + | const colorLevel = LevelColors[info.level as keyof typeof LevelColors] |
|
40 | + | const color = chalk.keyword(colorLevel).bind(chalk) |
|
41 | + | level = color(level) |
|
33 | 42 | const re = /(\w+)=(.+?)(?:\s|$)/g |
|
34 | 43 | info.message = info.message.replace( |
|
35 | 44 | re, |
@@ -40,7 +49,10 @@
Loading
40 | 49 | }) |
|
41 | 50 | } |
|
42 | 51 | ||
43 | - | function formatConfig(colors = true) { |
|
52 | + | /** |
|
53 | + | * Returns the complete logger format |
|
54 | + | */ |
|
55 | + | function formatConfig(colors = false) { |
|
44 | 56 | return combine( |
|
45 | 57 | errorFormat(), |
|
46 | 58 | format.splat(), |
@@ -50,44 +62,46 @@
Loading
50 | 62 | ) |
|
51 | 63 | } |
|
52 | 64 | ||
65 | + | /** |
|
66 | + | * Returns a transport with log file saving (rotates if args.logRotate is true) |
|
67 | + | */ |
|
68 | + | function logFileTransport(args: any) { |
|
69 | + | let filename = args.logFile === true ? 'ethereumjs.log' : args.logFile |
|
70 | + | const opts = { |
|
71 | + | level: args.logLevelFile, |
|
72 | + | format: formatConfig(), |
|
73 | + | } |
|
74 | + | if (!args.logRotate) { |
|
75 | + | return new wTransports.File({ |
|
76 | + | ...opts, |
|
77 | + | filename, |
|
78 | + | }) |
|
79 | + | } else { |
|
80 | + | // Insert %DATE% before the last period |
|
81 | + | const lastPeriod = filename.lastIndexOf('.') |
|
82 | + | filename = `${filename.substring(0, lastPeriod)}.%DATE%${filename.substring(lastPeriod)}` |
|
83 | + | return new DailyRotateFile({ |
|
84 | + | ...opts, |
|
85 | + | filename, |
|
86 | + | maxFiles: args.logMaxFiles, |
|
87 | + | }) |
|
88 | + | } |
|
89 | + | } |
|
90 | + | ||
91 | + | /** |
|
92 | + | * Returns a formatted {@link Logger} |
|
93 | + | */ |
|
53 | 94 | export function getLogger(args: { [key: string]: any } = { loglevel: 'info' }) { |
|
54 | 95 | const transports: any[] = [ |
|
55 | 96 | new wTransports.Console({ |
|
56 | 97 | level: args.loglevel, |
|
57 | 98 | silent: args.loglevel === 'off', |
|
58 | - | format: formatConfig(), |
|
99 | + | format: formatConfig(true), |
|
59 | 100 | }), |
|
60 | 101 | ] |
|
61 | - | let filename = args.logFile === true ? 'ethereumjs.log' : args.logFile |
|
62 | - | if (filename) { |
|
63 | - | const opts = { |
|
64 | - | level: args.logLevelFile, |
|
65 | - | format: formatConfig(false), |
|
66 | - | } |
|
67 | - | if (args.logRotate) { |
|
68 | - | // Insert %DATE% before the last period |
|
69 | - | const lastPeriod = filename.lastIndexOf('.') |
|
70 | - | filename = `${filename.substring(0, lastPeriod)}.%DATE%${filename.substring(lastPeriod)}` |
|
71 | - | transports.push( |
|
72 | - | new DailyRotateFile({ |
|
73 | - | ...opts, |
|
74 | - | filename, |
|
75 | - | maxFiles: args.logMaxFiles, |
|
76 | - | }) |
|
77 | - | ) |
|
78 | - | } else { |
|
79 | - | transports.push( |
|
80 | - | new wTransports.File({ |
|
81 | - | ...opts, |
|
82 | - | filename, |
|
83 | - | }) |
|
84 | - | ) |
|
85 | - | } |
|
86 | - | } |
|
87 | - | ||
88 | - | const logger = createLogger({ format: formatConfig(), transports }) |
|
89 | - | if (filename) { |
|
90 | - | logger.debug(`Writing log file=${filename}`) |
|
102 | + | if (args.logFile) { |
|
103 | + | transports.push(logFileTransport(args)) |
|
91 | 104 | } |
|
105 | + | const logger = createLogger({ transports }) |
|
92 | 106 | return logger |
|
93 | 107 | } |
@@ -109,29 +109,31 @@
Loading
109 | 109 | address: this.host, |
|
110 | 110 | tcpPort: this.port, |
|
111 | 111 | }) |
|
112 | - | this.rlpx.on('peer:error', (_: Devp2pRlpxPeer, error: Error) => { |
|
112 | + | ||
113 | + | const peerErrorHandler = (_: Devp2pRlpxPeer, error: Error) => { |
|
113 | 114 | this.config.events.emit(Event.PEER_ERROR, error, this) |
|
114 | - | }) |
|
115 | - | this.rlpx.once('peer:added', async (rlpxPeer: Devp2pRlpxPeer) => { |
|
115 | + | } |
|
116 | + | const peerErrorHandlerBound = peerErrorHandler.bind(this) |
|
117 | + | const peerAddedHandler = async (rlpxPeer: Devp2pRlpxPeer) => { |
|
116 | 118 | try { |
|
117 | 119 | await this.bindProtocols(rlpxPeer) |
|
118 | 120 | this.config.events.emit(Event.PEER_CONNECTED, this) |
|
119 | 121 | } catch (error: any) { |
|
120 | 122 | this.config.events.emit(Event.PEER_ERROR, error, this) |
|
121 | 123 | } |
|
122 | - | }) |
|
123 | - | this.rlpx.once('peer:removed', (rlpxPeer: Devp2pRlpxPeer) => { |
|
124 | - | try { |
|
125 | - | if (rlpxPeer !== this.rlpxPeer) { |
|
126 | - | return |
|
127 | - | } |
|
128 | - | this.rlpxPeer = null |
|
129 | - | this.connected = false |
|
130 | - | this.config.events.emit(Event.PEER_DISCONNECTED, this) |
|
131 | - | } catch (error: any) { |
|
132 | - | this.config.events.emit(Event.PEER_ERROR, error, this) |
|
124 | + | } |
|
125 | + | const peerRemovedHandler = (rlpxPeer: Devp2pRlpxPeer) => { |
|
126 | + | if (rlpxPeer !== this.rlpxPeer) { |
|
127 | + | return |
|
133 | 128 | } |
|
134 | - | }) |
|
129 | + | this.rlpxPeer = null |
|
130 | + | this.connected = false |
|
131 | + | this.config.events.emit(Event.PEER_DISCONNECTED, this) |
|
132 | + | this.rlpx?.removeListener('peer:error', peerErrorHandlerBound) |
|
133 | + | } |
|
134 | + | this.rlpx.on('peer:error', peerErrorHandlerBound) |
|
135 | + | this.rlpx.once('peer:added', peerAddedHandler.bind(this)) |
|
136 | + | this.rlpx.once('peer:removed', peerRemovedHandler.bind(this)) |
|
135 | 137 | } |
|
136 | 138 | ||
137 | 139 | /** |
@@ -1,7 +1,7 @@
Loading
1 | 1 | import PeerId from 'peer-id' |
|
2 | 2 | // eslint-disable-next-line implicit-dependencies/no-implicit |
|
3 | 3 | import crypto from 'libp2p-crypto' |
|
4 | - | import multiaddr from 'multiaddr' |
|
4 | + | import { Multiaddr, multiaddr } from 'multiaddr' |
|
5 | 5 | import { Event, Libp2pConnection as Connection } from '../../types' |
|
6 | 6 | import { Libp2pNode } from '../peer/libp2pnode' |
|
7 | 7 | import { Libp2pPeer } from '../peer' |
@@ -9,7 +9,7 @@
Loading
9 | 9 | ||
10 | 10 | export interface Libp2pServerOptions extends ServerOptions { |
|
11 | 11 | /* Multiaddrs to listen on */ |
|
12 | - | multiaddrs?: multiaddr[] |
|
12 | + | multiaddrs?: Multiaddr[] |
|
13 | 13 | } |
|
14 | 14 | ||
15 | 15 | /** |
@@ -19,7 +19,7 @@
Loading
19 | 19 | export class Libp2pServer extends Server { |
|
20 | 20 | private peers: Map<string, Libp2pPeer> = new Map() |
|
21 | 21 | private banned: Map<string, number> = new Map() |
|
22 | - | private multiaddrs: multiaddr[] |
|
22 | + | private multiaddrs: Multiaddr[] |
|
23 | 23 | private node: Libp2pNode | null |
|
24 | 24 | ||
25 | 25 | /** |
@@ -156,11 +156,11 @@
Loading
156 | 156 | return PeerId.createFromPrivKey(protoBuf) |
|
157 | 157 | } |
|
158 | 158 | ||
159 | - | getPeerInfo(connection: Connection): [PeerId, multiaddr] { |
|
159 | + | getPeerInfo(connection: Connection): [PeerId, Multiaddr] { |
|
160 | 160 | return [connection.remotePeer, connection.remoteAddr] |
|
161 | 161 | } |
|
162 | 162 | ||
163 | - | createPeer(peerId: PeerId, multiaddrs?: multiaddr[]) { |
|
163 | + | createPeer(peerId: PeerId, multiaddrs?: Multiaddr[]) { |
|
164 | 164 | const peer = new Libp2pPeer({ |
|
165 | 165 | config: this.config, |
|
166 | 166 | id: peerId.toB58String(), |
@@ -3,7 +3,7 @@
Loading
3 | 3 | import * as rlp from 'rlp' |
|
4 | 4 | import { sscanf } from 'scanf' |
|
5 | 5 | import { ecdsaVerify } from 'secp256k1' |
|
6 | - | import Multiaddr from 'multiaddr' |
|
6 | + | import { Multiaddr } from 'multiaddr' |
|
7 | 7 | import base64url from 'base64url' |
|
8 | 8 | import { PeerInfo } from '../dpt' |
|
9 | 9 | import { toNewUint8Array, keccak256 } from '../util' |
@@ -74,8 +74,8 @@
Loading
74 | 74 | ||
75 | 75 | const peerInfo: PeerInfo = { |
|
76 | 76 | address: Convert.toString(ipCode, obj.ip) as string, |
|
77 | - | tcpPort: Convert.toString(tcpCode, toNewUint8Array(obj.tcp)) as number, |
|
78 | - | udpPort: Convert.toString(udpCode, toNewUint8Array(obj.udp)) as number, |
|
77 | + | tcpPort: Number(Convert.toString(tcpCode, toNewUint8Array(obj.tcp))), |
|
78 | + | udpPort: Number(Convert.toString(udpCode, toNewUint8Array(obj.udp))), |
|
79 | 79 | } |
|
80 | 80 | ||
81 | 81 | return peerInfo |
@@ -1,4 +1,4 @@
Loading
1 | - | import multiaddr from 'multiaddr' |
|
1 | + | import { Multiaddr } from 'multiaddr' |
|
2 | 2 | import { Config } from '../../config' |
|
3 | 3 | import { MultiaddrLike, KeyLike, DnsNetwork } from '../../types' |
|
4 | 4 | import { parseKey, parseMultiaddrs } from '../../util/parse' |
@@ -28,7 +28,7 @@
Loading
28 | 28 | export class Server { |
|
29 | 29 | public config: Config |
|
30 | 30 | public key: Buffer |
|
31 | - | public bootnodes: multiaddr[] = [] |
|
31 | + | public bootnodes: Multiaddr[] = [] |
|
32 | 32 | public dnsNetworks: DnsNetwork[] |
|
33 | 33 | ||
34 | 34 | protected refreshInterval: number |
@@ -1,6 +1,6 @@
Loading
1 | 1 | import { EventEmitter } from 'events' |
|
2 | - | import type multiaddr from 'multiaddr' |
|
3 | 2 | import { BN } from 'ethereumjs-util' |
|
3 | + | import type { Multiaddr } from 'multiaddr' |
|
4 | 4 | import type { Block, BlockHeader } from '@ethereumjs/block' |
|
5 | 5 | import type Connection from '../../../node_modules/libp2p-interfaces/dist/src/connection/connection' |
|
6 | 6 | import type { MuxedStream } from '../../../node_modules/libp2p-interfaces/dist/src/stream-muxer/types' |
@@ -78,7 +78,7 @@
Loading
78 | 78 | export type Key = Buffer |
|
79 | 79 | export type KeyLike = string | Key |
|
80 | 80 | ||
81 | - | export type MultiaddrLike = string | string[] | multiaddr | multiaddr[] |
|
81 | + | export type MultiaddrLike = string | string[] | Multiaddr | Multiaddr[] |
|
82 | 82 | ||
83 | 83 | /** |
|
84 | 84 | * DNS |
@@ -2,7 +2,7 @@
Loading
2 | 2 | import VM from '@ethereumjs/vm' |
|
3 | 3 | import { genPrivateKey } from '@ethereumjs/devp2p' |
|
4 | 4 | import { Address } from 'ethereumjs-util' |
|
5 | - | import Multiaddr from 'multiaddr' |
|
5 | + | import { Multiaddr } from 'multiaddr' |
|
6 | 6 | import { Logger, getLogger } from './logging' |
|
7 | 7 | import { Libp2pServer, RlpxServer } from './net/server' |
|
8 | 8 | import { parseTransports } from './util' |
@@ -3,7 +3,7 @@
Loading
3 | 3 | * @memberof module:net/peer |
|
4 | 4 | */ |
|
5 | 5 | ||
6 | - | import multiaddr from 'multiaddr' |
|
6 | + | import { Multiaddr } from 'multiaddr' |
|
7 | 7 | import LibP2p from 'libp2p' |
|
8 | 8 | import { NOISE } from '@chainsafe/libp2p-noise' |
|
9 | 9 | import PeerId from 'peer-id' |
@@ -24,11 +24,11 @@
Loading
24 | 24 | addresses?: { |
|
25 | 25 | listen?: string[] |
|
26 | 26 | announce?: string[] |
|
27 | - | announceFilter?: (ma: multiaddr[]) => multiaddr[] |
|
27 | + | announceFilter?: (ma: Multiaddr[]) => Multiaddr[] |
|
28 | 28 | } |
|
29 | 29 | ||
30 | 30 | /* Bootnodes */ |
|
31 | - | bootnodes?: multiaddr[] |
|
31 | + | bootnodes?: Multiaddr[] |
|
32 | 32 | } |
|
33 | 33 | ||
34 | 34 | export class Libp2pNode extends LibP2p { |
@@ -1,5 +1,5 @@
Loading
1 | 1 | import { URL } from 'url' |
|
2 | - | import multiaddr from 'multiaddr' |
|
2 | + | import { Multiaddr, multiaddr } from 'multiaddr' |
|
3 | 3 | import { BlockHeader } from '@ethereumjs/block' |
|
4 | 4 | import Common, { Hardfork } from '@ethereumjs/common' |
|
5 | 5 | import { SecureTrie as Trie } from 'merkle-patricia-tree' |
@@ -23,19 +23,19 @@
Loading
23 | 23 | * Parses multiaddrs and bootnodes to multiaddr format. |
|
24 | 24 | * @param input comma separated string |
|
25 | 25 | */ |
|
26 | - | export function parseMultiaddrs(input: MultiaddrLike): multiaddr[] { |
|
26 | + | export function parseMultiaddrs(input: MultiaddrLike): Multiaddr[] { |
|
27 | 27 | if (!input) { |
|
28 | 28 | return [] |
|
29 | 29 | } |
|
30 | 30 | if (!Array.isArray(input) && typeof input === 'object') { |
|
31 | - | return [input] as multiaddr[] |
|
31 | + | return [input] as Multiaddr[] |
|
32 | 32 | } |
|
33 | 33 | if (!Array.isArray(input)) { |
|
34 | 34 | input = input.split(',') |
|
35 | 35 | } |
|
36 | 36 | try { |
|
37 | 37 | return (input as string[]).map((s) => { |
|
38 | - | if (multiaddr.isMultiaddr(s)) { |
|
38 | + | if (Multiaddr.isMultiaddr(s)) { |
|
39 | 39 | return s |
|
40 | 40 | } |
|
41 | 41 | // parse as multiaddr |
Files | Coverage |
---|---|
packages | 82.06% |
Project Totals (81 files) | 82.06% |
Sunburst
The inner-most circle is the entire project, moving away from the center are folders then, finally, a single file.
The size and color of each slice is representing the number of statements and the coverage, respectively.
Icicle
The top section represents the entire project. Proceeding with folders and finally individual files.
The size and color of each slice is representing the number of statements and the coverage, respectively.