Skip to content

Commit

Permalink
Merge branch 'feat/add-event-bus' into arbitrary-modules
Browse files Browse the repository at this point in the history
  • Loading branch information
achingbrain committed Apr 25, 2023
2 parents 1554505 + 76aa8ce commit 803609b
Show file tree
Hide file tree
Showing 86 changed files with 1,341 additions and 1,008 deletions.
2 changes: 1 addition & 1 deletion doc/GETTING_STARTED.md
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ node.addEventListener('peer:discovery', (evt) => {
console.log('Discovered %s', evt.detail.id.toString()) // Log discovered peer
})

node.connectionManager.addEventListener('peer:connect', (evt) => {
node.addEventListener('peer:connect', (evt) => {
console.log('Connected to %s', evt.detail.remotePeer.toString()) // Log connected peer
})
```
Expand Down
170 changes: 170 additions & 0 deletions doc/migrations/v0.44-v0.45.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
# Migrating to libp2p@45 <!-- omit in toc -->

A migration guide for refactoring your application code from libp2p v0.44.x to v0.45.0.

## Table of Contents <!-- omit in toc -->

- [Events](#events)
- [Emitters](#emitters)
- [Event changes](#event-changes)
- [`peer:connect`](#peerconnect)
- [`peer:disconnect`](#peerdisconnect)
- [`peer:update`](#peerupdate)
- [`self:peer:update`](#selfpeerupdate)
- [Atomic peer store methods](#atomic-peer-store-methods)

## Events

The events emitted by libp2p have been refactored to be more consistent and to give more insight into the inner workings of libp2p.

> Please see the [API docs](https://libp2p.github.io/js-libp2p-interfaces/interfaces/_libp2p_interface_libp2p.Libp2pEvents.html) for an exhaustive list of events emitted by Libp2p.
### Emitters

The primary interaction point for events is now the libp2p node itself, no need to access internal properties to set up listeners.

**Before**

```js
import { createLibp2p } from 'libp2p'

const node = await createLibp2p({ /* ... */ })
node.connectionManager.addEventListener('peer:connect', () => {})
```

**After**

```js
import { createLibp2p } from 'libp2p'

const node = await createLibp2p({ /* ... */ })
node.addEventListener('peer:connect', () => {})
```

### Event changes

Some types have changed.

> Please see the [API docs](https://libp2p.github.io/js-libp2p-interfaces/interfaces/_libp2p_interface_libp2p.Libp2pEvents.html) for an exhaustive list of events emitted by Libp2p.
#### `peer:connect`

The detail field for this event was a [Connection] now it is a [PeerId]

It is emitted when a new peer opens it's first connection.

To receive notifications of the opening of individual connections, listen for the `connection:open` event instead.

#### `peer:disconnect`

The detail field for this event was a [Connection] now it is a [PeerId]

It is emitted when all connections for the peer have been closed.

To receive notifications of the closing of individual connections, listen for the `connection:close` event instead.

#### `peer:update`

This event is emitted when a peer's data has been changed in the peer store. This can be in response to a user manually updating the peer, or after the [Identify] protocol has completed.

#### `self:peer:update`

This event occurs when the data of the running node has changed. It may have started listening on a new multiaddr, [AutoNAT] may have given us new confidence in an external address or a user may have manually updated the information.

## Atomic peer store methods

The libp2p peer store has been refactored to reduce the number of methods it exposes.

Previously it had separate components for managing addresses, protocols, metadata, etc, all of which exposed async methods which meant updating the data for a peer could involve multiple async calls which required complicated internal locking mechanisms which introduced a lot of latency into libp2p nodes performing many peer operations.

The updated peer store has simple `save`, `patch` and `merge` methods which update all fields in a peer's stored data at once.

**Before**

```js
import { createLibp2p } from 'libp2p'

const node = await createLibp2p({ /* ... */ })

// add addresses
await node.peerStore.addressBook.add(peerId, [
multiaddr('/ip4/43.14.67.21/tcp/3847')
])

// set protocols
await node.peerStore.protoBook.set(peerId, [
'/a-proto/1.0.0',
'/another-proto/1.0.0'
])

// add metadata
await node.peerStore.metadataBook.set(peerId, 'key', Uint8Array.from([0, 1, 2, 3]))

// add tags
await node.peerStore.tagPeer(peerId, 'tag-name', { value: 10 })
```

**After**

```js
import { createLibp2p } from 'libp2p'

const node = await createLibp2p({ /* ... */ })

// `save` replaces all data for the peer. Use with caution - any fields not passed
// will be deleted
await node.peerStore.save(peerId, {
multiaddrs: [
multiaddr('/ip4/43.14.67.21/tcp/3847')
],
protocols: [
'/a-proto/1.0.0',
'/another-proto/1.0.0'
],
metadata: {
key: Uint8Array.from([0, 1, 2, 3])
},
tags: {
'tag-name': { value: 10 }
}
})
```

Other ways to update peers are available which are more concise and allow you to just update specific fields:

```js
// `patch` replaces only the passed fields and retains all other data
await node.peerStore.patch(peerId, {
multiaddrs: [
multiaddr('/ip4/43.14.67.21/tcp/3847')
]
})

// `merge` behaves like `patch` but deeply merges multiaddrs, protocols, metadata,
// and tags, removing duplicates. any existing metadata/tags with the same
// keys/tag names will be overwritten.
await node.peerStore.merge(peerId, {
multiaddrs: [
multiaddr('/ip4/43.14.67.21/tcp/3847')
]
})
```

You can also remove fields quickly:

```js
// passing `undefined` to `merge` is a quick way of deleting metadata/tags
await node.peerStore.merge(peerId, {
metadata: {
key: undefined
},
tags: {
'tag-name': undefined
}
})
```

[Connection]: https://libp2p.github.io/js-libp2p-interfaces/interfaces/_libp2p_interface_connection.Connection.html
[PeerId]: https://libp2p.github.io/js-libp2p-interfaces/types/_libp2p_interface_peer_id.PeerId.html
[Identify]: https://github.com/libp2p/specs/blob/master/identify/README.md
[AutoNAT]: https://github.com/libp2p/specs/blob/master/autonat/README.md
6 changes: 2 additions & 4 deletions examples/auto-relay/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,9 @@ const conn = await node.dial(relayAddr)
console.log(`Connected to the HOP relay ${conn.remotePeer.toString()}`)

// Wait for connection and relay to be bind for the example purpose
node.peerStore.addEventListener('change:multiaddrs', (evt) => {
node.addEventListener('self:peer:update', (evt) => {
// Updated self multiaddrs?
if (evt.detail.peerId.equals(node.peerId)) {
console.log(`Advertising with a relay address of ${node.getMultiaddrs()[0].toString()}`)
}
console.log(`Advertising with a relay address of ${node.getMultiaddrs()[0].toString()}`)
})
```

Expand Down
8 changes: 2 additions & 6 deletions examples/auto-relay/listener.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,9 @@ async function main () {
console.log(`Connected to the HOP relay ${conn.remotePeer.toString()}`)

// Wait for connection and relay to be bind for the example purpose
node.peerStore.addEventListener('change:multiaddrs', (evt) => {
const { peerId } = evt.detail

node.addEventListener('self:peer:update', (evt) => {
// Updated self multiaddrs?
if (peerId.equals(node.peerId)) {
console.log(`Advertising with a relay address of ${node.getMultiaddrs()[0].toString()}`)
}
console.log(`Advertising with a relay address of ${node.getMultiaddrs()[0].toString()}`)
})
}

Expand Down
2 changes: 1 addition & 1 deletion examples/chat/src/listener.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ async function run () {
})

// Log a message when a remote peer connects to us
nodeListener.connectionManager.addEventListener('peer:connect', (evt) => {
nodeListener.addEventListener('peer:connect', (evt) => {
const connection = evt.detail
console.log('connected to: ', connection.remotePeer.toString())
})
Expand Down
4 changes: 3 additions & 1 deletion examples/connection-encryption/1.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ const createNode = async () => {
createNode()
])

await node1.peerStore.addressBook.set(node2.peerId, node2.getMultiaddrs())
await node1.peerStore.patch(node2.peerId, {
multiaddrs: node2.getMultiaddrs()
})

node2.handle('/a-protocol', ({ stream }) => {
pipe(
Expand Down
8 changes: 4 additions & 4 deletions examples/delegated-routing/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@
"libp2p": "file:../../",
"@libp2p/delegated-content-routing": "^4.0.0",
"@libp2p/delegated-peer-routing": "^4.0.0",
"@libp2p/kad-dht": "^8.0.7",
"@libp2p/mplex": "^7.1.6",
"@libp2p/webrtc-star": "^6.0.0",
"@libp2p/websockets": "^5.0.0",
"@libp2p/kad-dht": "^9.0.0",
"@libp2p/mplex": "^8.0.1",
"@libp2p/webrtc-star": "^7.0.0",
"@libp2p/websockets": "^6.0.1",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-scripts": "5.0.0"
Expand Down
10 changes: 5 additions & 5 deletions examples/discovery-mechanisms/1.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,14 @@ import bootstrappers from './bootstrappers.js'
]
})

node.connectionManager.addEventListener('peer:connect', (evt) => {
const connection = evt.detail
console.log('Connection established to:', connection.remotePeer.toString()) // Emitted when a peer has been found
node.addEventListener('peer:connect', (evt) => {
const peerId = evt.detail
console.log('Connection established to:', peerId.toString()) // Emitted when a peer has been found
})

node.addEventListener('peer:discovery', (evt) => {
const peer = evt.detail
const peerId = evt.detail

console.log('Discovered:', peer.id.toString())
console.log('Discovered:', peerId.toString())
})
})();
2 changes: 1 addition & 1 deletion examples/discovery-mechanisms/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ const node = await createLibp2p({
]
})

node.connectionManager.addEventListener('peer:connect', (evt) => {
node.addEventListener('peer:connect', (evt) => {
console.log('Connection established to:', evt.detail.remotePeer.toString()) // Emitted when a new connection has been created
})

Expand Down
2 changes: 1 addition & 1 deletion examples/echo/src/listener.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ async function run() {
})

// Log a message when we receive a connection
listenerNode.connectionManager.addEventListener('peer:connect', (evt) => {
listenerNode.addEventListener('peer:connect', (evt) => {
const connection = evt.detail
console.log('received dial to me from:', connection.remotePeer.toString())
})
Expand Down
20 changes: 10 additions & 10 deletions examples/libp2p-in-the-browser/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,25 +52,25 @@ document.addEventListener('DOMContentLoaded', async () => {

// Listen for new peers
libp2p.addEventListener('peer:discovery', (evt) => {
const peer = evt.detail
log(`Found peer ${peer.id.toString()}`)
const peerInfo = evt.detail
log(`Found peer ${peerInfo.id.toString()}`)

// dial them when we discover them
libp2p.dial(evt.detail.id).catch(err => {
log(`Could not dial ${evt.detail.id}`, err)
libp2p.dial(peerInfo.id).catch(err => {
log(`Could not dial ${peerInfo.id.toString()}`, err)
})
})

// Listen for new connections to peers
libp2p.connectionManager.addEventListener('peer:connect', (evt) => {
const connection = evt.detail
log(`Connected to ${connection.remotePeer.toString()}`)
libp2p.addEventListener('peer:connect', (evt) => {
const peerId = evt.detail
log(`Connected to ${peerId.toString()}`)
})

// Listen for peers disconnecting
libp2p.connectionManager.addEventListener('peer:disconnect', (evt) => {
const connection = evt.detail
log(`Disconnected from ${connection.remotePeer.toString()}`)
libp2p.addEventListener('peer:disconnect', (evt) => {
const peerId = evt.detail
log(`Disconnected from ${peerId.toString()}`)
})

status.innerText = 'libp2p started!'
Expand Down
8 changes: 4 additions & 4 deletions examples/libp2p-in-the-browser/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@
"license": "ISC",
"dependencies": {
"@chainsafe/libp2p-noise": "^11.0.0",
"@libp2p/bootstrap": "^6.0.0",
"@libp2p/mplex": "^7.1.6",
"@libp2p/webrtc-star": "^6.0.0",
"@libp2p/websockets": "^5.0.0",
"@libp2p/bootstrap": "^7.0.0",
"@libp2p/mplex": "^8.0.1",
"@libp2p/webrtc-star": "^7.0.0",
"@libp2p/websockets": "^6.0.1",
"libp2p": "file:../../"
},
"devDependencies": {
Expand Down
2 changes: 1 addition & 1 deletion examples/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
},
"license": "MIT",
"dependencies": {
"@libp2p/floodsub": "^6.0.0",
"@libp2p/floodsub": "^7.0.1",
"@libp2p/pubsub-peer-discovery": "^8.0.0",
"@nodeutils/defaults-deep": "^1.1.0",
"execa": "^6.1.0",
Expand Down
8 changes: 6 additions & 2 deletions examples/peer-and-content-routing/1.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,12 @@ const createNode = async () => {
createNode()
])

await node1.peerStore.addressBook.set(node2.peerId, node2.getMultiaddrs())
await node2.peerStore.addressBook.set(node3.peerId, node3.getMultiaddrs())
await node1.peerStore.patch(node2.peerId, {
multiaddrs: node2.getMultiaddrs()
})
await node2.peerStore.patch(node3.peerId, {
multiaddrs: node3.getMultiaddrs()
})

await Promise.all([
node1.dial(node2.peerId),
Expand Down
8 changes: 6 additions & 2 deletions examples/peer-and-content-routing/2.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,12 @@ const createNode = async () => {
createNode()
])

await node1.peerStore.addressBook.set(node2.peerId, node2.getMultiaddrs())
await node2.peerStore.addressBook.set(node3.peerId, node3.getMultiaddrs())
await node1.peerStore.patch(node2.peerId, {
multiaddrs: node2.getMultiaddrs()
})
await node2.peerStore.patch(node3.peerId, {
multiaddrs: node3.getMultiaddrs()
})

await Promise.all([
node1.dial(node2.peerId),
Expand Down
8 changes: 6 additions & 2 deletions examples/peer-and-content-routing/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,12 @@ const [node1, node2, node3] = await Promise.all([
createNode()
])

await node1.peerStore.addressBook.set(node2.peerId, node2.getMultiaddrs())
await node2.peerStore.addressBook.set(node3.peerId, node3.getMultiaddrs())
await node1.peerStore.patch(node2.peerId, {
multiaddrs: node2.getMultiaddrs()
})
await node2.peerStore.patch(node3.peerId, {
mulitaddrs: node3.getMultiaddrs()
})

await Promise.all([
node1.dial(node2.peerId),
Expand Down
4 changes: 3 additions & 1 deletion examples/pnet/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ generateKey(otherSwarmKey)
console.log('nodes started...')

// Add node 2 data to node1's PeerStore
await node1.peerStore.addressBook.set(node2.peerId, node2.getMultiaddrs())
await node1.peerStore.patch(node2.peerId, {
multiaddrs: node2.getMultiaddrs()
})
await node1.dial(node2.peerId)

node2.handle('/private', ({ stream }) => {
Expand Down
Loading

0 comments on commit 803609b

Please sign in to comment.