-
Notifications
You must be signed in to change notification settings - Fork 6
[wip] feat: upgrade libp2p, apply breaking changes #2
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
base: master
Are you sure you want to change the base?
Changes from all commits
3b64c4e
923e518
f2d4e15
38ee88a
020b006
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,10 +1,10 @@ | ||
| import Provider from "./index" | ||
| import { Provider } from "./index.js" | ||
| import { Doc, Doc as YDoc, } from 'yjs' | ||
| import { Uint8ArrayEquals } from "./util" | ||
| import { Uint8ArrayEquals } from "./util.js" | ||
| import * as Y from 'yjs' | ||
| // @ts-ignore | ||
| import * as awarenessProtocol from 'y-protocols/dist/awareness.cjs' | ||
| import Libp2p from 'libp2p' | ||
| import {Libp2p as ILibp2p} from 'libp2p' | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why this change?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was using |
||
| // @ts-ignore | ||
| import { createPeer } from './test-utils/create-peer.js' | ||
|
|
||
|
|
@@ -25,8 +25,8 @@ it.only('Provider syncs doc across 2 peers', async () => { | |
| const ydoc1 = new YDoc() | ||
| const ydoc2 = new YDoc() | ||
|
|
||
| const node1: Libp2p = await createPeer() | ||
| const node2: Libp2p = await createPeer() | ||
| const node1: ILibp2p = await createPeer() | ||
| const node2: ILibp2p = await createPeer() | ||
|
|
||
| const provider1 = new Provider(ydoc1, node1, topic) | ||
| const provider2 = new Provider(ydoc2, node2, topic) | ||
|
|
@@ -60,8 +60,8 @@ it('Provider syncs doc across 2 unsynced peers', async () => { | |
| const ydoc2 = new YDoc() | ||
| ydoc2.getText("testDoc").insert(0, "Good bye") | ||
|
|
||
| const node1: Libp2p = await createPeer() | ||
| const node2: Libp2p = await createPeer() | ||
| const node1: ILibp2p = await createPeer() | ||
| const node2: ILibp2p = await createPeer() | ||
|
|
||
| const provider1 = new Provider(ydoc1, node1, topic) | ||
| const provider2 = new Provider(ydoc2, node2, topic) | ||
|
|
@@ -96,11 +96,11 @@ function printStates(docs: { [key: string]: YDoc }) { | |
| console.log("--- Doc States ---" + str) | ||
| } | ||
|
|
||
| async function connectNodes(nodes: Libp2p[]) { | ||
| async function connectNodes(nodes: ILibp2p[]) { | ||
| const firstNode = nodes[0] | ||
| for (let i = 1; i < nodes.length; i++) { | ||
| const node = nodes[i] | ||
| await firstNode.dial(node.multiaddrs[0] + '/p2p/' + node.peerId.toB58String()) | ||
| await firstNode.dial(node.peerId) | ||
| await firstNode.ping(node.peerId) | ||
| await node.ping(firstNode.peerId) | ||
| } | ||
|
|
@@ -110,7 +110,7 @@ async function connectNodes(nodes: Libp2p[]) { | |
| if (i === j) continue | ||
| const node = nodes[i] | ||
| const otherNode = nodes[j] | ||
| node.peerStore.addressBook.set(otherNode.peerId, otherNode.multiaddrs) | ||
| node.peerStore.addressBook.set(otherNode.peerId, otherNode.getMultiaddrs()) | ||
| } | ||
| } | ||
| } | ||
|
|
@@ -120,8 +120,8 @@ it('Provider syncs awareness across 2 peers', async () => { | |
| const ydoc1 = new YDoc() | ||
| const ydoc2 = new YDoc() | ||
|
|
||
| const node1: Libp2p = await createPeer() | ||
| const node2: Libp2p = await createPeer() | ||
| const node1: ILibp2p = await createPeer() | ||
| const node2: ILibp2p = await createPeer() | ||
|
|
||
| const provider1 = new Provider(ydoc1, node1, topic) | ||
| const provider2 = new Provider(ydoc2, node2, topic) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,24 +1,24 @@ | ||
| import * as Y from 'yjs' | ||
| import type { Doc as YDoc } from 'yjs' | ||
| import type Libp2p from 'libp2p' | ||
| import { Uint8ArrayEquals } from './util' | ||
| import PeerId from 'peer-id' | ||
| import type { BufferList } from 'libp2p-interfaces/src/pubsub' | ||
| import { Connection } from 'libp2p-interfaces/src/topology' | ||
| import { Libp2p as ILibp2p } from "libp2p"; | ||
| import { Uint8ArrayEquals } from './util.js' | ||
| import { Connection } from '@libp2p/interface-connection'; | ||
| // @ts-ignore | ||
| import * as awarenessProtocol from 'y-protocols/dist/awareness.cjs' | ||
| import type { Awareness } from 'y-protocols/awareness' | ||
|
|
||
| import { peerIdFromString } from "@libp2p/peer-id"; | ||
|
|
||
| // the Muxedstream type is wrong for the protocol streams | ||
| type ProtocolStream = { | ||
| sink: (data: Iterable<any> | AsyncIterable<any>) => Promise<void> | ||
| source: AsyncIterable<BufferList> | ||
| source: AsyncIterable<Uint8Array> | ||
| close: () => void | ||
| } | ||
|
|
||
|
|
||
| function changesTopic(topic: string): string { | ||
| return `/marcopolo/gossipPad/${topic}/changes/0.0.01` | ||
| return `/marcopolo/gossipPad/${topic}/changes/0.0.01`; | ||
| } | ||
|
|
||
| function stateVectorTopic(topic: string): string { | ||
|
|
@@ -33,9 +33,9 @@ function awarenessProtocolTopic(topic: string): string { | |
| return `/marcopolo/gossipPad/${topic}/awareness/0.0.1` | ||
| } | ||
|
|
||
| class Provider { | ||
| export class Provider { | ||
| ydoc: YDoc; | ||
| node: Libp2p; | ||
| node: ILibp2p; | ||
| peerID: string; | ||
| topic: string | ||
| stateVectors: { [key: string]: Uint8Array } = {}; | ||
|
|
@@ -46,11 +46,11 @@ class Provider { | |
|
|
||
| aggressivelyKeepPeersUpdated: boolean = true; | ||
|
|
||
| constructor(ydoc: YDoc, node: Libp2p, topic: string) { | ||
| constructor(ydoc: YDoc, node: ILibp2p, topic: string) { | ||
| this.ydoc = ydoc; | ||
| this.node = node; | ||
| this.topic = topic; | ||
| this.peerID = this.node.peerId.toB58String() | ||
| this.peerID = this.node.peerId.toString() | ||
| this.stateVectors[this.peerID] = Y.encodeStateVector(this.ydoc) | ||
| this.awareness = new awarenessProtocol.Awareness(ydoc) | ||
|
|
||
|
|
@@ -61,14 +61,23 @@ class Provider { | |
| ydoc.on('update', this.onUpdate.bind(this)); | ||
|
|
||
| node.pubsub.subscribe(changesTopic(topic)) | ||
| node.pubsub.on(changesTopic(topic), this.onPubSubChanges.bind(this)); | ||
|
|
||
| node.pubsub.subscribe(stateVectorTopic(topic)) | ||
| node.pubsub.on(stateVectorTopic(topic), this.onPubSubStateVector.bind(this)); | ||
|
|
||
| node.pubsub.subscribe(awarenessProtocolTopic(topic)) | ||
| node.pubsub.on(awarenessProtocolTopic(topic), this.onPubSubAwareness.bind(this)); | ||
|
|
||
| this.node.pubsub.addEventListener('message', async (event) => { | ||
| if (event.detail.topic === changesTopic(topic)) { | ||
| this.onPubSubChanges.bind(this) | ||
| } | ||
|
|
||
| if (event.detail.topic === stateVectorTopic(topic)) { | ||
| this.onPubSubStateVector.bind(this) | ||
| } | ||
|
|
||
| if (event.detail.topic === awarenessProtocolTopic(topic)) { | ||
| this.onPubSubAwareness.bind(this) | ||
| } | ||
| }); | ||
|
|
||
| // @ts-ignore | ||
| node.handle(syncProtocol(topic), this.onSyncMsg.bind(this)); | ||
|
|
||
|
|
@@ -77,13 +86,10 @@ class Provider { | |
|
|
||
| destroy() { | ||
| this.node.pubsub.unsubscribe(changesTopic(this.topic)) | ||
| this.node.pubsub.removeAllListeners(changesTopic(this.topic)) | ||
|
|
||
| this.node.pubsub.unsubscribe(stateVectorTopic(this.topic)) | ||
| this.node.pubsub.removeAllListeners(stateVectorTopic(this.topic)) | ||
|
|
||
| this.node.pubsub.unsubscribe(awarenessProtocolTopic(this.topic)) | ||
| this.node.pubsub.removeAllListeners(awarenessProtocolTopic(this.topic)) | ||
|
|
||
| this.node.pubsub.removeEventListener('message'); | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Did this change in the new version of js libp2p?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
|
||
| // @ts-ignore | ||
| node.unhandle(syncProtocol(topic)) | ||
|
|
@@ -92,15 +98,17 @@ class Provider { | |
| } | ||
|
|
||
| // Not required, but nice if we can get synced against a peer sooner rather than latter | ||
| private async tryInitialSync(updateData: Uint8Array, origin: this | any) { | ||
| private async tryInitialSync(updateData: Uint8Array, origin: this | any): Promise<Boolean | void> { | ||
| const tries = 10; | ||
| const maxWaitTime = 1000; | ||
| let waitTime = 100; | ||
| for (let i = 0; i < tries; i++) { | ||
| if (this.initialSync) { | ||
| return | ||
| } | ||
| const peers = [...this.node.pubsub.topics.get(stateVectorTopic(this.topic)) || []] | ||
|
|
||
| // needed to type hack | ||
| const peers = [...(this.node as any).pubsub.topics.get(stateVectorTopic(this.topic)) || []] | ||
|
|
||
| if (peers.length !== 0) { | ||
| const peer = peers[i % peers.length] | ||
|
|
@@ -199,7 +207,7 @@ class Provider { | |
| } | ||
|
|
||
| private async onSyncMsg({ stream, connection, ...rest }: { stream: ProtocolStream, connection: Connection }) { | ||
| await this.runSyncProtocol(stream, connection.remotePeer.toB58String(), false) | ||
| await this.runSyncProtocol(stream, connection.remotePeer.toString(), false) | ||
| } | ||
|
|
||
| private queuePeerSync(peerID: string) { | ||
|
|
@@ -215,22 +223,14 @@ class Provider { | |
|
|
||
| private async syncPeer(peerID: string) { | ||
| const thiz = this; | ||
| const multiaddrs = await this.node.peerStore.addressBook.getMultiaddrsForPeer(PeerId.createFromB58String(peerID)); | ||
| let success = false; | ||
| if (!multiaddrs) { | ||
| try { | ||
| const stream = await this.node.dialProtocol(peerIdFromString(peerID), syncProtocol(this.topic)) as any as { stream: ProtocolStream } | ||
| await this.runSyncProtocol(stream as any, peerID, true) | ||
| success = true; | ||
| return | ||
| } | ||
| for (const ma of multiaddrs) { | ||
| const maStr = ma.toString() | ||
| try { | ||
| const { stream } = await this.node.dialProtocol(maStr, syncProtocol(this.topic)) as any as { stream: ProtocolStream } | ||
| await this.runSyncProtocol(stream, peerID, true) | ||
| success = true; | ||
| return | ||
| } catch (e) { | ||
| console.warn(`Failed to sync with ${maStr}`, e) | ||
| continue; | ||
| } | ||
| } catch (e) { | ||
| console.warn(`Failed to sync with ${peerIdFromString(peerID)}`, e) | ||
| } | ||
|
|
||
| throw new Error("Failed to sync with peer") | ||
|
|
@@ -239,4 +239,3 @@ class Provider { | |
|
|
||
| // TODO awareness | ||
|
|
||
| export default Provider | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You need to update the peer dependency below
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, will do. thanks