Skip to content
This repository was archived by the owner on Jun 26, 2023. It is now read-only.

Commit 071c718

Browse files
authored
feat!: add libp2p events (#373)
Removes events from some internal components and adds them to the event bus. Decouples internal components from each other since they can listen to the bus for events rather than having to know about the component that dispatches them. Refs: libp2p/js-libp2p#1693
1 parent 1e03f2a commit 071c718

File tree

10 files changed

+116
-96
lines changed

10 files changed

+116
-96
lines changed

packages/interface-address-manager/src/index.ts

+1-9
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,6 @@
11
import type { Multiaddr } from '@multiformats/multiaddr'
2-
import type { EventEmitter } from '@libp2p/interfaces/events'
32

4-
export interface AddressManagerEvents {
5-
/**
6-
* Emitted when the current node's addresses change
7-
*/
8-
'change:addresses': CustomEvent
9-
}
10-
11-
export interface AddressManager extends EventEmitter<AddressManagerEvents> {
3+
export interface AddressManager {
124
/**
135
* Get peer listen multiaddrs
146
*/

packages/interface-connection-manager/src/index.ts

+1-50
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import type { AbortOptions } from '@libp2p/interfaces'
2-
import type { EventEmitter } from '@libp2p/interfaces/events'
32
import type { Connection, MultiaddrConnection } from '@libp2p/interface-connection'
43
import type { PeerId } from '@libp2p/interface-peer-id'
54
import type { Multiaddr } from '@multiformats/multiaddr'
@@ -14,55 +13,7 @@ export interface PendingDial {
1413
multiaddrs: Multiaddr[]
1514
}
1615

17-
export interface ConnectionManagerEvents {
18-
/**
19-
* This event will be triggered any time a new Connection is established to another peer.
20-
*
21-
* @example
22-
*
23-
* ```js
24-
* libp2p.connectionManager.addEventListener('peer:connect', (event) => {
25-
* const connection = event.detail
26-
* // ...
27-
* })
28-
* ```
29-
*/
30-
'peer:connect': CustomEvent<Connection>
31-
32-
/**
33-
* This event will be triggered any time we are disconnected from another peer, regardless of
34-
* the circumstances of that disconnection. If we happen to have multiple connections to a
35-
* peer, this event will **only** be triggered when the last connection is closed.
36-
*
37-
* @example
38-
*
39-
* ```js
40-
* libp2p.connectionManager.addEventListener('peer:disconnect', (event) => {
41-
* const connection = event.detail
42-
* // ...
43-
* })
44-
* ```
45-
*/
46-
'peer:disconnect': CustomEvent<Connection>
47-
48-
/**
49-
* This event will be triggered when the connection manager has more connections than the
50-
* configured limit. The event detail contains the list of PeerIds from the connections
51-
* that were closed to bring the node back under the max connections limit.
52-
*
53-
* @example
54-
*
55-
* ```js
56-
* libp2p.connectionManager.addEventListener('peer:prune', (event) => {
57-
* const connection = event.detail
58-
* // ...
59-
* })
60-
* ```
61-
*/
62-
'peer:prune': CustomEvent<PeerId[]>
63-
}
64-
65-
export interface ConnectionManager extends EventEmitter<ConnectionManagerEvents> {
16+
export interface ConnectionManager {
6617
/**
6718
* Return connections, optionally filtering by a PeerId
6819
*

packages/interface-libp2p/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@
143143
"@libp2p/interface-peer-store": "^2.0.0",
144144
"@libp2p/interface-pubsub": "^4.0.0",
145145
"@libp2p/interface-registrar": "^2.0.0",
146+
"@libp2p/interface-transport": "^2.1.3",
146147
"@libp2p/interfaces": "^3.0.0",
147148
"@multiformats/multiaddr": "^12.0.0"
148149
},

packages/interface-libp2p/src/index.ts

+85-6
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import type { EventEmitter } from '@libp2p/interfaces/events'
1919
import type { Startable } from '@libp2p/interfaces/startable'
2020
import type { Multiaddr } from '@multiformats/multiaddr'
2121
import type { DualDHT } from '@libp2p/interface-dht'
22-
import type { PeerStore } from '@libp2p/interface-peer-store'
22+
import type { Address, Peer, PeerStore } from '@libp2p/interface-peer-store'
2323
import type { PeerId } from '@libp2p/interface-peer-id'
2424
import type { Connection, Stream } from '@libp2p/interface-connection'
2525
import type { PeerRouting } from '@libp2p/interface-peer-routing'
@@ -29,12 +29,34 @@ import type { StreamHandler, StreamHandlerOptions, Topology } from '@libp2p/inte
2929
import type { Metrics } from '@libp2p/interface-metrics'
3030
import type { PeerInfo } from '@libp2p/interface-peer-info'
3131
import type { KeyChain } from '@libp2p/interface-keychain'
32+
import type { Listener } from '@libp2p/interface-transport'
3233

3334
/**
34-
* Once you have a libp2p instance, you can listen to several events it emits, so that you can be notified of relevant network events.
35+
* Used by the connection manager to sort addresses into order before dialling
36+
*/
37+
export interface AddressSorter {
38+
(a: Address, b: Address): -1 | 0 | 1
39+
}
40+
41+
/**
42+
* Event detail emitted when peer data changes
43+
*/
44+
export interface PeerUpdate {
45+
peer: Peer
46+
previous?: Peer
47+
}
48+
49+
/**
50+
* Once you have a libp2p instance, you can listen to several events it emits,
51+
* so that you can be notified of relevant network events.
52+
*
53+
* Event names are `noun:adjective` so the first part is the name of the object
54+
* being acted on and the second is the action.
3555
*/
3656
export interface Libp2pEvents {
3757
/**
58+
* This event is dispatched when a new network peer is discovered.
59+
*
3860
* @example
3961
*
4062
* ```js
@@ -47,18 +69,18 @@ export interface Libp2pEvents {
4769
'peer:discovery': CustomEvent<PeerInfo>
4870

4971
/**
50-
* This event will be triggered anytime a new Connection is established to another peer.
72+
* This event will be triggered anytime a new peer connects.
5173
*
5274
* @example
5375
*
5476
* ```js
5577
* libp2p.connectionManager.addEventListener('peer:connect', (event) => {
56-
* const connection = event.detail
78+
* const peerId = event.detail
5779
* // ...
5880
* })
5981
* ```
6082
*/
61-
'peer:connect': CustomEvent<Connection>
83+
'peer:connect': CustomEvent<PeerId>
6284

6385
/**
6486
* This event will be triggered anytime we are disconnected from another peer, regardless of
@@ -74,7 +96,64 @@ export interface Libp2pEvents {
7496
* })
7597
* ```
7698
*/
77-
'peer:disconnect': CustomEvent<Connection>
99+
'peer:disconnect': CustomEvent<PeerId>
100+
101+
/**
102+
* This event is dispatched when the peer store data for a peer has been
103+
* updated - e.g. their multiaddrs, protocols etc have changed.
104+
*
105+
* If they were previously known to this node, the old peer data will be
106+
* set in the `previous` field.
107+
*
108+
* This may be in response to the identify protocol running, a manual
109+
* update or some other event.
110+
*/
111+
'peer:update': CustomEvent<PeerUpdate>
112+
113+
/**
114+
* This event is dispatched when the current node's peer record changes -
115+
* for example a transport started listening on a new address or a new
116+
* protocol handler was registered.
117+
*
118+
* @example
119+
*
120+
* ```js
121+
* libp2p.addEventListener('self:peer:update', (event) => {
122+
* const { peer } = event.detail
123+
* // ...
124+
* })
125+
* ```
126+
*/
127+
'self:peer:update': CustomEvent<PeerUpdate>
128+
129+
/**
130+
* This event is dispatched when a transport begins listening on a new address
131+
*/
132+
'transport:listening': CustomEvent<Listener>
133+
134+
/**
135+
* This event is dispatched when a transport stops listening on an address
136+
*/
137+
'transport:close': CustomEvent<Listener>
138+
139+
/**
140+
* This event is dispatched when the connection manager has more than the
141+
* configured allowable max connections and has closed some connections to
142+
* bring the node back under the limit.
143+
*/
144+
'connection:prune': CustomEvent<Connection[]>
145+
146+
/**
147+
* This event notifies listeners when new incoming or outgoing connections
148+
* are opened.
149+
*/
150+
'connection:open': CustomEvent<Connection>
151+
152+
/**
153+
* This event notifies listeners when incoming or outgoing connections are
154+
* closed.
155+
*/
156+
'connection:close': CustomEvent<Connection>
78157
}
79158

80159
/**

packages/interface-mocks/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@
143143
"@libp2p/interface-connection-encrypter": "^4.0.0",
144144
"@libp2p/interface-connection-gater": "^3.0.0",
145145
"@libp2p/interface-connection-manager": "^2.0.0",
146+
"@libp2p/interface-libp2p": "^1.0.0",
146147
"@libp2p/interface-metrics": "^4.0.0",
147148
"@libp2p/interface-peer-discovery": "^1.0.0",
148149
"@libp2p/interface-peer-id": "^2.0.0",

packages/interface-mocks/src/connection-manager.ts

+8-7
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,23 @@
1-
import { EventEmitter } from '@libp2p/interfaces/events'
1+
import type { EventEmitter } from '@libp2p/interfaces/events'
22
import type { Startable } from '@libp2p/interfaces/startable'
33
import type { Connection } from '@libp2p/interface-connection'
44
import { isPeerId, PeerId } from '@libp2p/interface-peer-id'
5-
import type { ConnectionManager, ConnectionManagerEvents, PendingDial } from '@libp2p/interface-connection-manager'
5+
import type { ConnectionManager, PendingDial } from '@libp2p/interface-connection-manager'
66
import { connectionPair } from './connection.js'
77
import { CodeError } from '@libp2p/interfaces/errors'
88
import type { Registrar } from '@libp2p/interface-registrar'
99
import type { PubSub } from '@libp2p/interface-pubsub'
1010
import { isMultiaddr, Multiaddr } from '@multiformats/multiaddr'
1111
import { peerIdFromString } from '@libp2p/peer-id'
1212
import { PeerMap } from '@libp2p/peer-collections'
13+
import type { Libp2pEvents } from '@libp2p/interface-libp2p'
1314

1415
export interface MockNetworkComponents {
1516
peerId: PeerId
1617
registrar: Registrar
1718
connectionManager: ConnectionManager
1819
pubsub?: PubSub
20+
events: EventEmitter<Libp2pEvents>
1921
}
2022

2123
class MockNetwork {
@@ -49,16 +51,15 @@ export const mockNetwork = new MockNetwork()
4951
export interface MockConnectionManagerComponents {
5052
peerId: PeerId
5153
registrar: Registrar
54+
events: EventEmitter<Libp2pEvents>
5255
}
5356

54-
class MockConnectionManager extends EventEmitter<ConnectionManagerEvents> implements ConnectionManager, Startable {
57+
class MockConnectionManager implements ConnectionManager, Startable {
5558
private connections: Connection[] = []
5659
private readonly components: MockConnectionManagerComponents
5760
private started = false
5861

5962
constructor (components: MockConnectionManagerComponents) {
60-
super()
61-
6263
this.components = components
6364
}
6465

@@ -129,7 +130,7 @@ class MockConnectionManager extends EventEmitter<ConnectionManagerEvents> implem
129130
this.connections.push(aToB)
130131
;(componentsB.connectionManager as MockConnectionManager).connections.push(bToA)
131132

132-
this.safeDispatchEvent<Connection>('peer:connect', {
133+
this.components.events.safeDispatchEvent('connection:open', {
133134
detail: aToB
134135
})
135136

@@ -139,7 +140,7 @@ class MockConnectionManager extends EventEmitter<ConnectionManagerEvents> implem
139140
}
140141
}
141142

142-
componentsB.connectionManager.safeDispatchEvent<Connection>('peer:connect', {
143+
componentsB.events.safeDispatchEvent('connection:open', {
143144
detail: bToA
144145
})
145146

+11-9
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
11
import { mockConnection } from './connection.js'
2-
import type { Upgrader, UpgraderEvents, UpgraderOptions } from '@libp2p/interface-transport'
2+
import type { Upgrader, UpgraderOptions } from '@libp2p/interface-transport'
33
import type { Connection, MultiaddrConnection } from '@libp2p/interface-connection'
44
import type { Registrar } from '@libp2p/interface-registrar'
5-
import { CustomEvent, EventEmitter } from '@libp2p/interfaces/events'
5+
import type { EventEmitter } from '@libp2p/interfaces/events'
6+
import type { Libp2pEvents } from '@libp2p/interface-libp2p'
67

78
export interface MockUpgraderInit {
89
registrar?: Registrar
10+
events: EventEmitter<Libp2pEvents>
911
}
1012

11-
class MockUpgrader extends EventEmitter<UpgraderEvents> implements Upgrader {
13+
class MockUpgrader implements Upgrader {
1214
private readonly registrar?: Registrar
15+
private readonly events: EventEmitter<Libp2pEvents>
1316

14-
constructor (init: MockUpgraderInit = {}) {
15-
super()
16-
17+
constructor (init: MockUpgraderInit) {
1718
this.registrar = init.registrar
19+
this.events = init.events
1820
}
1921

2022
async upgradeOutbound (multiaddrConnection: MultiaddrConnection, opts: UpgraderOptions = {}): Promise<Connection> {
@@ -24,7 +26,7 @@ class MockUpgrader extends EventEmitter<UpgraderEvents> implements Upgrader {
2426
...opts
2527
})
2628

27-
this.dispatchEvent(new CustomEvent<Connection>('connection', { detail: connection }))
29+
this.events.safeDispatchEvent('connection:open', { detail: connection })
2830

2931
return connection
3032
}
@@ -36,12 +38,12 @@ class MockUpgrader extends EventEmitter<UpgraderEvents> implements Upgrader {
3638
...opts
3739
})
3840

39-
this.dispatchEvent(new CustomEvent<Connection>('connection', { detail: connection }))
41+
this.events.safeDispatchEvent('connection:open', { detail: connection })
4042

4143
return connection
4244
}
4345
}
4446

45-
export function mockUpgrader (init: MockUpgraderInit = {}): Upgrader {
47+
export function mockUpgrader (init: MockUpgraderInit): Upgrader {
4648
return new MockUpgrader(init)
4749
}

packages/interface-transport-compliance-tests/src/dial-test.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import type { Transport, Listener, Upgrader } from '@libp2p/interface-transport'
1212
import type { TransportTestFixtures, Connector } from './index.js'
1313
import type { Multiaddr } from '@multiformats/multiaddr'
1414
import type { Registrar } from '@libp2p/interface-registrar'
15+
import { EventEmitter } from '@libp2p/interfaces/events'
1516

1617
export default (common: TestSetup<TransportTestFixtures>): void => {
1718
describe('dial', () => {
@@ -25,7 +26,8 @@ export default (common: TestSetup<TransportTestFixtures>): void => {
2526
before(async () => {
2627
registrar = mockRegistrar()
2728
upgrader = mockUpgrader({
28-
registrar
29+
registrar,
30+
events: new EventEmitter()
2931
});
3032

3133
({ addrs, transport, connector } = await common.setup())

packages/interface-transport-compliance-tests/src/listen-test.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { isValidTick } from '@libp2p/interface-compliance-tests/is-valid-tick'
88
import { mockUpgrader, mockRegistrar } from '@libp2p/interface-mocks'
99
import defer from 'p-defer'
1010
import drain from 'it-drain'
11-
import { CustomEvent } from '@libp2p/interfaces/events'
11+
import { CustomEvent, EventEmitter } from '@libp2p/interfaces/events'
1212
import type { TestSetup } from '@libp2p/interface-compliance-tests'
1313
import type { Transport, Upgrader } from '@libp2p/interface-transport'
1414
import type { TransportTestFixtures } from './index.js'
@@ -26,7 +26,8 @@ export default (common: TestSetup<TransportTestFixtures>): void => {
2626
before(async () => {
2727
registrar = mockRegistrar()
2828
upgrader = mockUpgrader({
29-
registrar
29+
registrar,
30+
events: new EventEmitter()
3031
});
3132

3233
({ transport, addrs } = await common.setup())

0 commit comments

Comments
 (0)