diff --git a/packages/network/src/node.ts b/packages/network/src/node.ts index 788eca14..e599d833 100644 --- a/packages/network/src/node.ts +++ b/packages/network/src/node.ts @@ -5,10 +5,15 @@ import { } from "@chainsafe/libp2p-gossipsub"; import { noise } from "@chainsafe/libp2p-noise"; import { yamux } from "@chainsafe/libp2p-yamux"; -import { circuitRelayTransport } from "@libp2p/circuit-relay-v2"; +import { + circuitRelayServer, + circuitRelayTransport, +} from "@libp2p/circuit-relay-v2"; +import { generateKeyPairFromSeed } from "@libp2p/crypto/keys"; import { dcutr } from "@libp2p/dcutr"; import { identify } from "@libp2p/identify"; import { EventHandler, PubSub, Stream, StreamHandler } from "@libp2p/interface"; +import { createFromPrivKey } from "@libp2p/peer-id-factory"; import { pubsubPeerDiscovery } from "@libp2p/pubsub-peer-discovery"; import { webRTC, webRTCDirect } from "@libp2p/webrtc"; import { webSockets } from "@libp2p/websockets"; @@ -17,11 +22,15 @@ import { Libp2p, createLibp2p } from "libp2p"; import { stringToStream } from "./stream.js"; import { bootstrap } from "@libp2p/bootstrap"; import { webTransport } from "@libp2p/webtransport"; +import { autoNAT } from "@libp2p/autonat"; +import { fromString as uint8ArrayFromString } from "uint8arrays/from-string"; // snake_casing to match the JSON config export interface TopologyNetworkNodeConfig { - addresses: string[]; - bootstrap_peers: string[]; + addresses?: string[]; + bootstrap?: boolean; + bootstrap_peers?: string[]; + private_key_seed?: string; } export class TopologyNetworkNode { @@ -36,9 +45,22 @@ export class TopologyNetworkNode { } async start() { + let privateKey; + if (this._config?.private_key_seed) { + let tmp = this._config.private_key_seed.padEnd(32, "0"); + privateKey = await generateKeyPairFromSeed( + "Ed25519", + uint8ArrayFromString(tmp), + ); + } + this._node = await createLibp2p({ + peerId: privateKey ? await createFromPrivKey(privateKey) : undefined, addresses: { - listen: this._config ? this._config.addresses : ["/webrtc"], + listen: + this._config && this._config.addresses + ? this._config.addresses + : ["/webrtc"], }, connectionEncryption: [noise()], connectionGater: { @@ -52,19 +74,21 @@ export class TopologyNetworkNode { topics: ["topology::discovery"], }), bootstrap({ - list: this._config - ? this._config.bootstrap_peers - : [ - "/dns4/relay.droak.sh/tcp/443/wss/p2p/Qma3GsJmB47xYuyahPZPSadh1avvxfyYQwk8R3UnFrQ6aP", - ], + list: + this._config && this._config.bootstrap_peers + ? this._config.bootstrap_peers + : [ + "/dns4/relay.droak.sh/tcp/443/wss/p2p/Qma3GsJmB47xYuyahPZPSadh1avvxfyYQwk8R3UnFrQ6aP", + ], }), ], services: { + autonat: autoNAT(), + dcutr: dcutr(), identify: identify(), pubsub: gossipsub({ allowPublishToZeroTopicPeers: true, }), - dcutr: dcutr(), }, streamMuxers: [yamux()], transports: [ @@ -79,6 +103,15 @@ export class TopologyNetworkNode { ], }); + if (this._config?.bootstrap) + this._node.services.relay = circuitRelayServer(); + + if (!this._config?.bootstrap) { + for (const addr of this._config?.bootstrap_peers || []) { + this._node.dial(multiaddr(addr)); + } + } + this._pubsub = this._node.services.pubsub as PubSub; this.peerId = this._node.peerId.toString(); diff --git a/packages/network/src/peer-id-relayer.ts b/packages/network/src/peer-id-relayer.ts deleted file mode 100644 index 7105c9e4..00000000 --- a/packages/network/src/peer-id-relayer.ts +++ /dev/null @@ -1,7 +0,0 @@ -export default { - id: "Qma3GsJmB47xYuyahPZPSadh1avvxfyYQwk8R3UnFrQ6aP", - privKey: - "CAASpwkwggSjAgEAAoIBAQCaNSDOjPz6T8HZsf7LDpxiQRiN2OjeyIHUS05p8QWOr3EFUCFsC31R4moihE5HN+FxNalUyyFZU//yjf1pdnlMJqrVByJSMa+y2y4x2FucpoCAO97Tx+iWzwlZ2UXEUXM1Y81mhPbeWXy+wP2xElTgIER0Tsn/thoA0SD2u9wJuVvM7dB7cBcHYmqV6JH+KWCedRTum6O1BssqP/4Lbm2+rkrbZ4+oVRoU2DRLoFhKqwqLtylrbuj4XOI3XykMXV5+uQXz1JzubNOB9lsc6K+eRC+w8hhhDuFMgzkZ4qomCnx3uhO67KaICd8yqqBa6PJ/+fBM5Xk4hjyR40bwcf41AgMBAAECggEAZnrCJ6IYiLyyRdr9SbKXCNDb4YByGYPEi/HT1aHgIJfFE1PSMjxcdytxfyjP4JJpVtPjiT9JFVU2ddoYu5qJN6tGwjVwgJEWg1UXmPaAw1T/drjS94kVsAs82qICtFmwp52Apg3dBZ0Qwq/8qE1XbG7lLyohIbfCBiL0tiPYMfkcsN9gnFT/kFCX0LVs2pa9fHCRMY9rqCc4/rWJa1w8sMuQ23y4lDaxKF9OZVvOHFQkbBDrkquWHE4r55fchCz/rJklkPJUNENuncBRu0/2X+p4IKFD1DnttXNwb8j4LPiSlLro1T0hiUr5gO2QmdYwXFF63Q3mjQy0+5I4eNbjjQKBgQDZvZy3gUKS/nQNkYfq9za80uLbIj/cWbO+ZZjXCsj0fNIcQFJcKMBoA7DjJvu2S/lf86/41YHkPdmrLAEQAkJ+5BBNOycjYK9minTEjIMMmZDTXXugZ62wnU6F46uLkgEChTqEP57Y6xwwV+JaEDFEsW5N1eE9lEVX9nGIr4phMwKBgQC1TazLuEt1WBx/iUT83ita7obXqoKNzwsS/MWfY2innzYZKDOqeSYZzLtt9uTtp4X4uLyPbYs0qFYhXLsUYMoGHNN8+NdjoyxCjQRJRBkMtaNR0lc5lVDWl3bTuJovjFCgAr9uqJrmI5OHcCIk/cDpdWb3nWaMihVlePmiTcTy9wKBgQCU0u7c1jKkudqks4XM6a+2HAYGdUBk4cLjLhnrUWnNAcuyl5wzdX8dGPi8KZb+IKuQE8WBNJ2VXVj7kBYh1QmSJVunDflQSvNYCOaKuOeRoxzD+y9Wkca74qkbBmPn/6FFEb7PSZTO+tPHjyodGNgz9XpJJRjQuBk1aDJtlF3m1QKBgE5SAr5ym65SZOU3UGUIOKRsfDW4Q/OsqDUImvpywCgBICaX9lHDShFFHwau7FA52ScL7vDquoMB4UtCOtLfyQYA9995w9oYCCurrVlVIJkb8jSLcADBHw3EmqF1kq3NqJqm9TmBfoDCh52vdCCUufxgKh33kfBOSlXuf7B8dgMbAoGAZ3r0/mBQX6S+s5+xCETMTSNv7TQzxgtURIpVs+ZVr2cMhWhiv+n0Omab9X9Z50se8cWl5lkvx8vn3D/XHHIPrMF6qk7RAXtvReb+PeitNvm0odqjFv0J2qki6fDs0HKwq4kojAXI1Md8Th0eobNjsy21fEEJT7uKMJdovI/SErI=", - pubKey: - "CAASpgIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCaNSDOjPz6T8HZsf7LDpxiQRiN2OjeyIHUS05p8QWOr3EFUCFsC31R4moihE5HN+FxNalUyyFZU//yjf1pdnlMJqrVByJSMa+y2y4x2FucpoCAO97Tx+iWzwlZ2UXEUXM1Y81mhPbeWXy+wP2xElTgIER0Tsn/thoA0SD2u9wJuVvM7dB7cBcHYmqV6JH+KWCedRTum6O1BssqP/4Lbm2+rkrbZ4+oVRoU2DRLoFhKqwqLtylrbuj4XOI3XykMXV5+uQXz1JzubNOB9lsc6K+eRC+w8hhhDuFMgzkZ4qomCnx3uhO67KaICd8yqqBa6PJ/+fBM5Xk4hjyR40bwcf41AgMBAAE=", -}; diff --git a/packages/network/src/relay.ts b/packages/network/src/relay.ts deleted file mode 100644 index 431636cc..00000000 --- a/packages/network/src/relay.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { gossipsub } from "@chainsafe/libp2p-gossipsub"; -import { noise } from "@chainsafe/libp2p-noise"; -import { yamux } from "@chainsafe/libp2p-yamux"; -import { circuitRelayServer } from "@libp2p/circuit-relay-v2"; -import { identify } from "@libp2p/identify"; -import { createFromJSON } from "@libp2p/peer-id-factory"; -import { pubsubPeerDiscovery } from "@libp2p/pubsub-peer-discovery"; -import { webSockets } from "@libp2p/websockets"; -import { createLibp2p } from "libp2p"; - -import relayerJson from "./peer-id-relayer.js"; -import { autoNAT } from "@libp2p/autonat"; -import { TopologyNetworkNodeConfig } from "./node.js"; - -// TODO: -// - remove the peer-id-relayer in favor of static configs -// - create a "relay" mode that can be activated in the main node.ts logic -// - improve the circuit-relay setup -export const createRelayNode = async (config?: TopologyNetworkNodeConfig) => { - const idRelayer = await createFromJSON(relayerJson); - const node = await createLibp2p({ - peerId: idRelayer, - addresses: { - listen: config - ? config.addresses - : ["/ip4/0.0.0.0/tcp/50000/ws", "/ip4/0.0.0.0/tcp/50001"], - }, - connectionEncryption: [noise()], - peerDiscovery: [ - pubsubPeerDiscovery({ - interval: 10_000, - topics: ["topology::discovery"], - }), - ], - services: { - autonat: autoNAT(), - identify: identify(), - pubsub: gossipsub(), - relay: circuitRelayServer(), - }, - streamMuxers: [yamux()], - transports: [webSockets()], - }); - - // Log a message when a remote peer connects to us - node.addEventListener("peer:connect", (e) => { - const remotePeer = e.detail; - console.log("connected to: ", remotePeer.toString()); - }); - - return node; -}; diff --git a/packages/node/configs/relay.json b/packages/node/configs/bootstrap.json similarity index 77% rename from packages/node/configs/relay.json rename to packages/node/configs/bootstrap.json index bb57fd23..549106bb 100644 --- a/packages/node/configs/relay.json +++ b/packages/node/configs/bootstrap.json @@ -1,8 +1,10 @@ { "network_config": { "addresses": ["/ip4/0.0.0.0/tcp/50000/ws", "/ip4/0.0.0.0/tcp/50001"], + "bootstrap": true, "bootstrap_peers": [ "/dns4/relay.droak.sh/tcp/443/wss/p2p/Qma3GsJmB47xYuyahPZPSadh1avvxfyYQwk8R3UnFrQ6aP" - ] + ], + "private_key_seed": "bootstrap" } } diff --git a/packages/node/configs/node.json b/packages/node/configs/node.json index 0408bf4e..d660844a 100644 --- a/packages/node/configs/node.json +++ b/packages/node/configs/node.json @@ -2,7 +2,8 @@ "network_config": { "addresses": ["/webrtc"], "bootstrap_peers": [ - "/dns4/relay.droak.sh/tcp/443/wss/p2p/Qma3GsJmB47xYuyahPZPSadh1avvxfyYQwk8R3UnFrQ6aP" - ] + "/ip4/127.0.0.1/tcp/50000/ws/p2p/12D3KooWC6sm9iwmYbeQJCJipKTRghmABNz1wnpJANvSMabvecwJ" + ], + "private_key_seed": "node" } } diff --git a/packages/node/src/run.ts b/packages/node/src/run.ts index f0c78fb8..ee79a9e8 100644 --- a/packages/node/src/run.ts +++ b/packages/node/src/run.ts @@ -8,14 +8,6 @@ async function startNode(config?: TopologyNodeConfig) { node.start(); } -async function startRelay(config?: TopologyNodeConfig) { - const node = await createRelayNode(config?.network_config); - console.log("peer_id:", node.peerId.toString()); - for (let ma of node.getMultiaddrs()) { - console.log(ma); - } -} - const run = () => { program.parse(process.argv); const opts = program.opts(); @@ -25,11 +17,7 @@ const run = () => { config = JSON.parse(fs.readFileSync(opts.config, "utf8")); } - if (opts.mode === "node") { - startNode(config); - } else if (opts.mode === "relay") { - startRelay(config); - } + startNode(config); }; run();