From 1acba76522db6bf645a157fa1e2145f9fa5d161a Mon Sep 17 00:00:00 2001 From: prathamesh0 Date: Tue, 3 Jan 2023 16:05:05 +0530 Subject: [PATCH] Use webrtc-direct transport with pubsub based discovery --- packages/cli/README.md | 14 +----- packages/cli/src/chat.ts | 13 ++--- packages/peer-test-app/.env | 1 - packages/peer-test-app/README.md | 16 ++----- packages/peer-test-app/src/App.tsx | 10 +++- packages/peer/package.json | 3 +- packages/peer/src/constants.ts | 1 + packages/peer/src/index.ts | 76 ++++++++++++------------------ packages/peer/src/relay.ts | 40 ++-------------- yarn.lock | 55 ++++++++++----------- 10 files changed, 77 insertions(+), 152 deletions(-) diff --git a/packages/cli/README.md b/packages/cli/README.md index fecfd694..f078f7ce 100644 --- a/packages/cli/README.md +++ b/packages/cli/README.md @@ -17,30 +17,20 @@ A basic CLI to pass messages between peers using `stdin`/`stdout` yarn build ``` -* (Optional) Run a local signalling server: - - ```bash - # In packages/peer - yarn signal-server - ``` - * (Optional) Run a local relay node: ```bash # In packages/peer - yarn relay-node --signal-server [SIGNAL_SERVER_URL] + yarn relay-node ``` - * `signal-server`: multiaddr of a signalling server (default: local signalling server multiaddr) - * Start the node: ```bash # In packages/cli - yarn chat --signal-server [SIGNAL_SERVER_URL] --relay-node [RELAY_NODE_URL] + yarn chat --relay-node ``` - * `signal-server`: multiaddr of a signalling server (default: local signalling server multiaddr) * `relay-node`: multiaddr of a hop enabled relay node * The process starts reading from `stdin` and outputs messages from others peers to `stdout`. diff --git a/packages/cli/src/chat.ts b/packages/cli/src/chat.ts index b8c09330..4fcd54a7 100644 --- a/packages/cli/src/chat.ts +++ b/packages/cli/src/chat.ts @@ -10,20 +10,16 @@ import yargs from 'yargs'; import { PeerId } from '@libp2p/interface-peer-id'; interface Arguments { - signalServer: string; relayNode: string; } async function main (): Promise { const argv: Arguments = _getArgv(); - if (!argv.signalServer) { - console.log('Using the default signalling server URL'); - } // https://adamcoster.com/blog/commonjs-and-esm-importexport-compatibility-examples#importing-esm-into-commonjs-cjs const { Peer } = await import('@cerc-io/peer'); const peer = new Peer(true); - await peer.init(argv.signalServer, argv.relayNode); + await peer.init(argv.relayNode); peer.subscribeMessage((peerId: PeerId, message: string) => { console.log(`> ${peerId.toString()} > ${message}`); @@ -47,13 +43,10 @@ function _getArgv (): any { return yargs(hideBin(process.argv)).parserConfiguration({ 'parse-numbers': false }).options({ - signalServer: { - type: 'string', - describe: 'Signalling server URL' - }, relayNode: { type: 'string', - describe: 'Relay node URL' + describe: 'Relay node URL', + demandOption: true } }).argv; } diff --git a/packages/peer-test-app/.env b/packages/peer-test-app/.env index 3c8478ec..097e24ce 100644 --- a/packages/peer-test-app/.env +++ b/packages/peer-test-app/.env @@ -1,2 +1 @@ -REACT_APP_SIGNAL_SERVER=/ip4/127.0.0.1/tcp/13579/ws/p2p-webrtc-star/ REACT_APP_RELAY_NODE= diff --git a/packages/peer-test-app/README.md b/packages/peer-test-app/README.md index 9755498f..3cbaa044 100644 --- a/packages/peer-test-app/README.md +++ b/packages/peer-test-app/README.md @@ -19,27 +19,17 @@ This project was bootstrapped with [Create React App](https://github.com/faceboo yarn build ``` -* (Optional) Run a local signalling server: - - ```bash - # In packages/peer - yarn signal-server - ``` - * (Optional) Run a local relay node: ```bash # In packages/peer - yarn relay-node --signal-server [SIGNAL_SERVER_URL] + yarn relay-node ``` - * `signal-server`: multiaddr of a signalling server (default: local signalling server multiaddr) - -* Set the signalling server and relay node multiaddrs in the [env](./.env) file: +* Set the relay node multiaddr in the [env](./.env) file: ``` - REACT_APP_SIGNAL_SERVER=/ip4/127.0.0.1/tcp/13579/ws/p2p-webrtc-star/ - REACT_APP_RELAY_NODE=/ip4/127.0.0.1/tcp/13579/wss/p2p-webrtc-star/p2p/12D3KooWRzH3ZRFP6RDbs2EKA8jSrD4Y6VYtLnCRMj3mYCiMHCJP + REACT_APP_RELAY_NODE=/ip4/0.0.0.0/tcp/9090/http/p2p-webrtc-direct/p2p/12D3KooWFn2tjcv1ciot6sXJDiCdxXAPh37pzxjBC1UmCkbP3QBo ``` * Start the react app in development mode: diff --git a/packages/peer-test-app/src/App.tsx b/packages/peer-test-app/src/App.tsx index 6a3c5732..a4c9cd6c 100644 --- a/packages/peer-test-app/src/App.tsx +++ b/packages/peer-test-app/src/App.tsx @@ -14,8 +14,14 @@ function App() { useEffect(() => { (async () => { if (peer) { - await peer.init(process.env.REACT_APP_SIGNAL_SERVER, process.env.REACT_APP_RELAY_NODE) - console.log(`Peer ID is ${peer.peerId!.toString()}`); + const relayNode = process.env.REACT_APP_RELAY_NODE; + if (!relayNode) { + console.log('REACT_APP_RELAY_NODE not set') + return; + } + + await peer.init(relayNode) + console.log(`Peer ID: ${peer.peerId!.toString()}`); peer.subscribeMessage((peerId, message) => { console.log(`${peerId.toString()} > ${message}`) diff --git a/packages/peer/package.json b/packages/peer/package.json index cdee476b..6f4edfe9 100644 --- a/packages/peer/package.json +++ b/packages/peer/package.json @@ -22,7 +22,6 @@ "build": "tsc", "lint": "eslint .", "dev": "node dist/index.js", - "signal-server": "webrtc-star --port=13579 --host=0.0.0.0", "relay-node": "node dist/relay.js" }, "dependencies": { @@ -30,8 +29,8 @@ "@libp2p/bootstrap": "^5.0.2", "@libp2p/floodsub": "^5.0.0", "@libp2p/mplex": "^7.1.1", + "@libp2p/webrtc-direct": "^4.0.2", "@libp2p/pubsub-peer-discovery": "^7.0.1", - "@libp2p/webrtc-star": "^5.0.3", "@libp2p/websockets": "^5.0.2", "@multiformats/multiaddr": "^11.1.4", "assert": "^2.0.0", diff --git a/packages/peer/src/constants.ts b/packages/peer/src/constants.ts index 0c2cb3bb..1439a409 100644 --- a/packages/peer/src/constants.ts +++ b/packages/peer/src/constants.ts @@ -3,3 +3,4 @@ // export const PUBSUB_DISCOVERY_INTERVAL = 10000; +export const RELAY_NODE_LISTEN_ADDRESS = '/ip4/0.0.0.0/tcp/9090/http/p2p-webrtc-direct'; diff --git a/packages/peer/src/index.ts b/packages/peer/src/index.ts index 616f46ba..af9999ff 100644 --- a/packages/peer/src/index.ts +++ b/packages/peer/src/index.ts @@ -13,9 +13,10 @@ import { pushable, Pushable } from 'it-pushable'; import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'; import { toString as uint8ArrayToString } from 'uint8arrays/to-string'; -import { webRTCStar, WebRTCStarTuple } from '@libp2p/webrtc-star'; +import { webRTCDirect } from '@libp2p/webrtc-direct'; import { noise } from '@chainsafe/libp2p-noise'; import { mplex } from '@libp2p/mplex'; +import type { Transport } from '@libp2p/interface-transport'; import type { Stream as P2PStream, Connection } from '@libp2p/interface-connection'; import type { PeerInfo } from '@libp2p/interface-peer-info'; import { PeerId } from '@libp2p/interface-peer-id'; @@ -23,14 +24,12 @@ import { multiaddr, Multiaddr } from '@multiformats/multiaddr'; import { bootstrap } from '@libp2p/bootstrap'; import { floodsub } from '@libp2p/floodsub'; import { pubsubPeerDiscovery } from '@libp2p/pubsub-peer-discovery'; -import { PUBSUB_DISCOVERY_INTERVAL } from './constants.js'; export const PROTOCOL = '/chat/1.0.0'; -export const DEFAULT_SIGNAL_SERVER_URL = '/ip4/127.0.0.1/tcp/13579/wss/p2p-webrtc-star'; export class Peer { _node?: Libp2p - _wrtcStar: WebRTCStarTuple + _wrtcTransport: () => Transport _relayNodeMultiaddr?: Multiaddr _remotePeerIds: PeerId[] = [] @@ -40,9 +39,9 @@ export class Peer { constructor (nodejs?: boolean) { // Instantiation in nodejs. if (nodejs) { - this._wrtcStar = webRTCStar({ wrtc }); + this._wrtcTransport = webRTCDirect({ wrtc }); } else { - this._wrtcStar = webRTCStar(); + this._wrtcTransport = webRTCDirect(); } } @@ -50,38 +49,22 @@ export class Peer { return this._node?.peerId; } - async init (signalServerURL = DEFAULT_SIGNAL_SERVER_URL, relayNodeURL?: string): Promise { - let peerDiscovery: any; - if (relayNodeURL) { - this._relayNodeMultiaddr = multiaddr(relayNodeURL); - console.log(`Bootstrapping with relay node ${this._relayNodeMultiaddr.toString()}`); - peerDiscovery = [ - bootstrap({ - list: [this._relayNodeMultiaddr.toString()] - }), - pubsubPeerDiscovery({ - interval: PUBSUB_DISCOVERY_INTERVAL - }) - ]; - } else { - peerDiscovery = [this._wrtcStar.discovery]; - } + async init (relayNodeURL: string): Promise { + this._relayNodeMultiaddr = multiaddr(relayNodeURL); + + console.log(`Bootstrapping with relay node ${this._relayNodeMultiaddr.toString()}`); + const peerDiscovery = [ + bootstrap({ + list: [this._relayNodeMultiaddr.toString()] + }), + // Add pubsub discovery; relay server acts as a peer discovery source + pubsubPeerDiscovery({ + interval: 1000 + }) + ]; this._node = await createLibp2p({ - addresses: { - // Add the signaling server address, along with our PeerId to our multiaddrs list - // libp2p will automatically attempt to dial to the signaling server so that it can - // receive inbound connections from other peers - listen: [ - // Public signal servers - // '/dns4/wrtc-star1.par.dwebops.pub/tcp/443/wss/p2p-webrtc-star', - // '/dns4/wrtc-star2.sjc.dwebops.pub/tcp/443/wss/p2p-webrtc-star' - signalServerURL - ] - }, - transports: [ - this._wrtcStar.transport - ], + transports: [this._wrtcTransport], connectionEncryption: [noise()], streamMuxers: [mplex()], pubsub: floodsub(), @@ -137,6 +120,7 @@ export class Peer { async close (): Promise { assert(this._node); + this._node.peerStore.removeEventListener('change:multiaddrs'); this._node.removeEventListener('peer:discovery'); this._node.connectionManager.removeEventListener('peer:connect'); this._node.connectionManager.removeEventListener('peer:disconnect'); @@ -189,20 +173,20 @@ export class Peer { async _connectPeer (peer: PeerInfo): Promise { assert(this._node); + assert(this._relayNodeMultiaddr); + console.log(`Dialling peer ${peer.id.toString()}`); // Check if discovered the relay node - if (this._relayNodeMultiaddr) { - const relayMultiaddr = this._relayNodeMultiaddr; - const relayNodePeerId = relayMultiaddr.getPeerId(); + const relayMultiaddr = this._relayNodeMultiaddr; + const relayNodePeerId = relayMultiaddr.getPeerId(); - if (relayNodePeerId && relayNodePeerId === peer.id.toString()) { - console.log(`Dialling relay peer ${peer.id.toString()} using multiaddr ${relayMultiaddr.toString()}`); - await this._node.dial(relayMultiaddr).catch(err => { - console.log(`Could not dial relay ${relayMultiaddr.toString()}`, err); - }); + if (relayNodePeerId && relayNodePeerId === peer.id.toString()) { + console.log(`Dialling relay peer ${peer.id.toString()} using multiaddr ${relayMultiaddr.toString()}`); + await this._node.dial(relayMultiaddr).catch(err => { + console.log(`Could not dial relay ${relayMultiaddr.toString()}`, err); + }); - return; - } + return; } // Dial them when we discover them diff --git a/packages/peer/src/relay.ts b/packages/peer/src/relay.ts index 03de8c4f..be0d3f08 100644 --- a/packages/peer/src/relay.ts +++ b/packages/peer/src/relay.ts @@ -4,38 +4,21 @@ import { createLibp2p } from 'libp2p'; import wrtc from 'wrtc'; -import { hideBin } from 'yargs/helpers'; -import yargs from 'yargs'; import { noise } from '@chainsafe/libp2p-noise'; import { mplex } from '@libp2p/mplex'; -import { webRTCStar, WebRTCStarTuple } from '@libp2p/webrtc-star'; +import { webRTCDirect } from '@libp2p/webrtc-direct'; import { floodsub } from '@libp2p/floodsub'; import { pubsubPeerDiscovery } from '@libp2p/pubsub-peer-discovery'; -import { DEFAULT_SIGNAL_SERVER_URL } from './index.js'; -import { PUBSUB_DISCOVERY_INTERVAL } from './constants.js'; - -interface Arguments { - signalServer: string; -} +import { PUBSUB_DISCOVERY_INTERVAL, RELAY_NODE_LISTEN_ADDRESS } from './constants.js'; async function main (): Promise { - const argv: Arguments = _getArgv(); - if (!argv.signalServer) { - console.log('Using the default signalling server URL'); - } - - const wrtcStar: WebRTCStarTuple = webRTCStar({ wrtc }); const node = await createLibp2p({ addresses: { - listen: [ - argv.signalServer || DEFAULT_SIGNAL_SERVER_URL - ] + listen: [RELAY_NODE_LISTEN_ADDRESS] }, - transports: [ - wrtcStar.transport - ], + transports: [webRTCDirect({ wrtc })], connectionEncryption: [noise()], streamMuxers: [mplex()], pubsub: floodsub(), @@ -60,21 +43,6 @@ async function main (): Promise { node.getMultiaddrs().forEach((ma) => console.log(ma.toString())); } -function _getArgv (): any { - return yargs(hideBin(process.argv)).parserConfiguration({ - 'parse-numbers': false - }).options({ - signalServer: { - type: 'string', - describe: 'Signalling server URL' - }, - relayNode: { - type: 'string', - describe: 'Relay node URL' - } - }).argv; -} - main().catch(err => { console.log(err); }); diff --git a/yarn.lock b/yarn.lock index 08b4e1d0..6bf58eb7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4245,7 +4245,7 @@ uint8arraylist "^2.0.0" uint8arrays "^4.0.2" -"@libp2p/peer-id@^1.0.0", "@libp2p/peer-id@^1.1.0", "@libp2p/peer-id@^1.1.13", "@libp2p/peer-id@^1.1.15", "@libp2p/peer-id@^1.1.8", "@libp2p/peer-id@^1.1.9": +"@libp2p/peer-id@^1.0.0", "@libp2p/peer-id@^1.1.0", "@libp2p/peer-id@^1.1.13", "@libp2p/peer-id@^1.1.15", "@libp2p/peer-id@^1.1.8": version "1.1.18" resolved "https://registry.npmjs.org/@libp2p/peer-id/-/peer-id-1.1.18.tgz" integrity sha512-Zh3gzbrQZKDMLpoJAJB8gdGtyYFSBKV0dU5vflQ18/7MJDJmjsgKO+sJTYi72yN5sWREs1eGKMhxLo+N1ust5w== @@ -4367,7 +4367,7 @@ dependencies: "@libp2p/interface-metrics" "^4.0.0" -"@libp2p/utils@^3.0.0", "@libp2p/utils@^3.0.1", "@libp2p/utils@^3.0.2": +"@libp2p/utils@^3.0.0", "@libp2p/utils@^3.0.2": version "3.0.4" resolved "https://registry.npmjs.org/@libp2p/utils/-/utils-3.0.4.tgz" integrity sha512-EWJNJtlop2ylmGE1BNiMA0u4eTLKoY0LbZ/DOvSDs9VlGSLua9J+LUjp6XV8lazGv7l1rOLiU+1hP5fcmg1+eg== @@ -4384,6 +4384,27 @@ private-ip "^3.0.0" uint8arraylist "^2.3.2" +"@libp2p/webrtc-direct@^4.0.2": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@libp2p/webrtc-direct/-/webrtc-direct-4.0.2.tgz#2227746279950f3586d5f823edc865c673a31897" + integrity sha512-mnGBsxECXdsx6UyIbxjEEGM+9FkyfamcInALjpuW+34KNlF/OlLCJV+PBOxDQK9NSGIoVDSJ8VwYItn5MU51Fg== + dependencies: + "@libp2p/interface-transport" "^2.0.0" + "@libp2p/interfaces" "^3.0.3" + "@libp2p/logger" "^2.0.1" + "@libp2p/utils" "^3.0.2" + "@libp2p/webrtc-peer" "^2.0.0" + "@multiformats/mafmt" "^11.0.3" + "@multiformats/multiaddr" "^11.0.0" + abortable-iterator "^4.0.2" + err-code "^3.0.0" + multiformats "^10.0.0" + native-fetch "^4.0.2" + p-event "^5.0.1" + uint8arrays "^4.0.2" + undici "^5.2.0" + wherearewe "^2.0.1" + "@libp2p/webrtc-peer@^2.0.0": version "2.0.2" resolved "https://registry.npmjs.org/@libp2p/webrtc-peer/-/webrtc-peer-2.0.2.tgz" @@ -4424,32 +4445,6 @@ socket.io "^4.1.2" socket.io-client "^4.1.2" -"@libp2p/webrtc-star@^5.0.3": - version "5.0.3" - resolved "https://registry.npmjs.org/@libp2p/webrtc-star/-/webrtc-star-5.0.3.tgz" - integrity sha512-tGH72ARnuHaj5FlLMrdU4B2PIZMgUKdS40YqlIu5w9zo4csZ8n07oRHt0B+gRnahLd8wY80uiS6CnmTC5c0skg== - dependencies: - "@libp2p/interface-connection" "^3.0.1" - "@libp2p/interface-peer-discovery" "^1.0.0" - "@libp2p/interface-peer-id" "^1.0.2" - "@libp2p/interface-transport" "^2.0.0" - "@libp2p/interfaces" "^3.0.2" - "@libp2p/logger" "^2.0.0" - "@libp2p/peer-id" "^1.1.9" - "@libp2p/utils" "^3.0.1" - "@libp2p/webrtc-peer" "^2.0.0" - "@libp2p/webrtc-star-protocol" "^2.0.0" - "@multiformats/mafmt" "^11.0.2" - "@multiformats/multiaddr" "^11.0.0" - abortable-iterator "^4.0.2" - delay "^5.0.0" - err-code "^3.0.1" - iso-random-stream "^2.0.2" - multiformats "^10.0.0" - p-defer "^4.0.0" - socket.io-client "^4.1.2" - uint8arrays "^4.0.2" - "@libp2p/websockets@^5.0.2": version "5.0.2" resolved "https://registry.npmjs.org/@libp2p/websockets/-/websockets-5.0.2.tgz" @@ -10702,7 +10697,7 @@ err-code@^2.0.2: resolved "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz" integrity sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA== -err-code@^3.0.1: +err-code@^3.0.0, err-code@^3.0.1: version "3.0.1" resolved "https://registry.npmjs.org/err-code/-/err-code-3.0.1.tgz" integrity sha512-GiaH0KJUewYok+eeY05IIgjtAe4Yltygk9Wqp1V5yVWLdhf0hYZchRjNIT9bb0mSwRcIusT3cx7PJUf3zEIfUA== @@ -22788,7 +22783,7 @@ underscore@1.9.1: resolved "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz" integrity sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg== -undici@^5.12.0: +undici@^5.12.0, undici@^5.2.0: version "5.14.0" resolved "https://registry.npmjs.org/undici/-/undici-5.14.0.tgz" integrity sha512-yJlHYw6yXPPsuOH0x2Ib1Km61vu4hLiRRQoafs+WUgX1vO64vgnxiCEN9dpIrhZyHFsai3F0AEj4P9zy19enEQ==