diff --git a/package-lock.json b/package-lock.json index a470beb9a9..ed8dcbc662 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2756,9 +2756,9 @@ } }, "node_modules/@libp2p/interface-peer-discovery-compliance-tests": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@libp2p/interface-peer-discovery-compliance-tests/-/interface-peer-discovery-compliance-tests-2.0.3.tgz", - "integrity": "sha512-tYz2HZ2OWZTxn6E37LSmbomJIyRXs6gDb2RCVhJSQN6Md8pL50rrDNEUNlzjdhkp8NF/3uc+0JaVTg35IVJs6w==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@libp2p/interface-peer-discovery-compliance-tests/-/interface-peer-discovery-compliance-tests-2.0.4.tgz", + "integrity": "sha512-RxcyOUG0pwV/kCQyQSc0FzUvgg6GMjkBx1obIi3t1E9Bmsc08MPs8uWLAl+QNTB8U0iUkUcyZc94Ek9QPEzeSg==", "dependencies": { "@libp2p/interface-compliance-tests": "^3.0.0", "@libp2p/interface-peer-discovery": "^1.0.0", @@ -27561,6 +27561,7 @@ "uint8arrays": "^4.0.2" }, "devDependencies": { + "@libp2p/interface-peer-discovery-compliance-tests": "^2.0.4", "@libp2p/peer-id-factory": "^1.0.15", "@multiformats/multiaddr": "^11.0.6", "@rollup/plugin-commonjs": "^22.0.0", @@ -29762,9 +29763,9 @@ } }, "@libp2p/interface-peer-discovery-compliance-tests": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@libp2p/interface-peer-discovery-compliance-tests/-/interface-peer-discovery-compliance-tests-2.0.3.tgz", - "integrity": "sha512-tYz2HZ2OWZTxn6E37LSmbomJIyRXs6gDb2RCVhJSQN6Md8pL50rrDNEUNlzjdhkp8NF/3uc+0JaVTg35IVJs6w==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@libp2p/interface-peer-discovery-compliance-tests/-/interface-peer-discovery-compliance-tests-2.0.4.tgz", + "integrity": "sha512-RxcyOUG0pwV/kCQyQSc0FzUvgg6GMjkBx1obIi3t1E9Bmsc08MPs8uWLAl+QNTB8U0iUkUcyZc94Ek9QPEzeSg==", "requires": { "@libp2p/interface-compliance-tests": "^3.0.0", "@libp2p/interface-peer-discovery": "^1.0.0", @@ -31761,6 +31762,7 @@ "version": "file:packages/dns-discovery", "requires": { "@libp2p/interface-peer-discovery": "^1.0.0", + "@libp2p/interface-peer-discovery-compliance-tests": "^2.0.4", "@libp2p/interface-peer-info": "^1.0.1", "@libp2p/interfaces": "^3.0.2", "@libp2p/peer-id": "^1.1.10", diff --git a/packages/dns-discovery/package.json b/packages/dns-discovery/package.json index 8fdce32bb6..b3849205f7 100644 --- a/packages/dns-discovery/package.json +++ b/packages/dns-discovery/package.json @@ -82,6 +82,7 @@ "cspell": "^6.17.0", "eslint": "^8.6.0", "eslint-config-prettier": "^8.3.0", + "@libp2p/interface-peer-discovery-compliance-tests": "^2.0.4", "eslint-plugin-eslint-comments": "^3.2.0", "eslint-plugin-functional": "^4.0.2", "eslint-plugin-import": "^2.25.3", diff --git a/packages/dns-discovery/src/dns.spec.ts b/packages/dns-discovery/src/dns.spec.ts index 7182e884f6..550d46b1b8 100644 --- a/packages/dns-discovery/src/dns.spec.ts +++ b/packages/dns-discovery/src/dns.spec.ts @@ -260,7 +260,7 @@ describe("DNS Node Discovery w/ capabilities", () => { }); describe("DNS Node Discovery [live data]", function () { - const publicKey = "AOFTICU2XWDULNLZGRMQS4RIZPAZEHYMV4FYHAPW563HNRAOERP7C"; + const publicKey = "AOGECG2SPND25EEFMAJ5WF3KSGJNSGV356DSTL2YVLLZWIV6SAYBM"; const fqdn = "test.waku.nodes.status.im"; const enrTree = `enrtree://${publicKey}@${fqdn}`; const maxQuantity = 3; diff --git a/packages/dns-discovery/src/dns.ts b/packages/dns-discovery/src/dns.ts index e227793e1b..6052be6df8 100644 --- a/packages/dns-discovery/src/dns.ts +++ b/packages/dns-discovery/src/dns.ts @@ -42,10 +42,10 @@ export class DnsNodeDiscovery { /** * Returns a list of verified peers listed in an EIP-1459 DNS tree. Method may - * return fewer peers than requested if [[wantedNodeCapabilityCount]] requires + * return fewer peers than requested if @link wantedNodeCapabilityCount requires * larger quantity of peers than available or the number of errors/duplicate * peers encountered by randomized search exceeds the sum of the fields of - * [[wantedNodeCapabilityCount]] plus the [[_errorTolerance]] factor. + * @link wantedNodeCapabilityCount plus the @link _errorTolerance factor. */ async getPeers( enrTreeUrls: string[], @@ -82,7 +82,7 @@ export class DnsNodeDiscovery { } /** - * {@docInherit getPeers} + * {@inheritDoc getPeers} */ async *getNextPeer( enrTreeUrls: string[], diff --git a/packages/dns-discovery/src/enrtree.ts b/packages/dns-discovery/src/enrtree.ts index a2b1347b91..04b8533eb6 100644 --- a/packages/dns-discovery/src/enrtree.ts +++ b/packages/dns-discovery/src/enrtree.ts @@ -39,6 +39,7 @@ export class ENRTree { // of the record content, excluding the `sig=` part, encoded as URL-safe base64 string // (Trailing recovery bit must be trimmed to pass `ecdsaVerify` method) const signedComponent = root.split(" sig")[0]; + const signedComponentBuffer = utf8ToBytes(signedComponent); const signatureBuffer = fromString(rootValues.signature, "base64url").slice( 0, diff --git a/packages/dns-discovery/src/index.ts b/packages/dns-discovery/src/index.ts index d8bffa326e..f077682fe9 100644 --- a/packages/dns-discovery/src/index.ts +++ b/packages/dns-discovery/src/index.ts @@ -42,7 +42,7 @@ export class PeerDiscoveryDns const dns = DnsNodeDiscovery.dnsOverHttp(); this.nextPeer = dns.getNextPeer.bind( - {}, + dns, [enrUrl], wantedNodeCapabilityCount ); @@ -81,3 +81,12 @@ export class PeerDiscoveryDns return "@waku/bootstrap"; } } + +export function wakuDnsDiscovery( + enrUrl: string, + wantedNodeCapabilityCount: Partial +): () => PeerDiscoveryDns { + return () => new PeerDiscoveryDns(enrUrl, wantedNodeCapabilityCount); +} + +export { DnsNodeDiscovery, SearchContext, DnsClient } from "./dns.js"; diff --git a/packages/tests/package.json b/packages/tests/package.json index d705346ac6..7c1dd80d9c 100644 --- a/packages/tests/package.json +++ b/packages/tests/package.json @@ -68,7 +68,8 @@ "@waku/enr": "*", "@waku/interfaces": "*", "@waku/message-encryption": "*", - "@waku/peer-exchange": "*" + "@waku/peer-exchange": "*", + "@waku/dns-discovery": "*" }, "devDependencies": { "@libp2p/bootstrap": "^5.0.0", diff --git a/packages/tests/tests/dns-peer-discovery.spec.ts b/packages/tests/tests/dns-peer-discovery.spec.ts new file mode 100644 index 0000000000..5e014a2b26 --- /dev/null +++ b/packages/tests/tests/dns-peer-discovery.spec.ts @@ -0,0 +1,78 @@ +import tests from "@libp2p/interface-peer-discovery-compliance-tests"; +import { createLightNode } from "@waku/create"; +import { DnsNodeDiscovery, wakuDnsDiscovery } from "@waku/dns-discovery"; +import { expect } from "chai"; + +const publicKey = "AOGECG2SPND25EEFMAJ5WF3KSGJNSGV356DSTL2YVLLZWIV6SAYBM"; +const fqdn = "test.waku.nodes.status.im"; +const enrTree = `enrtree://${publicKey}@${fqdn}`; +const maxQuantity = 3; + +describe("DNS Discovery: Compliance Test", async function () { + this.timeout(5000); + tests({ + async setup() { + return wakuDnsDiscovery(enrTree, { + filter: 1, + })(); + }, + async teardown() { + // + }, + }); +}); + +describe("DNS Node Discovery [live data]", function () { + before(function () { + if (process.env.CI) { + this.skip(); + } + }); + + it(`should use DNS peer discovery with light client`, async function () { + this.timeout(100000); + const maxQuantity = 3; + + const nodeRequirements = { + relay: maxQuantity, + store: maxQuantity, + filter: maxQuantity, + lightPush: maxQuantity, + }; + + const waku = await createLightNode({ + libp2p: { + peerDiscovery: [wakuDnsDiscovery(enrTree, nodeRequirements)], + }, + }); + + await waku.start(); + + const peersFound = await waku.libp2p.peerStore.all(); + expect(peersFound.length).to.eq(maxQuantity); + }); + + it(`should retrieve ${maxQuantity} multiaddrs for prod.nodes.status.im`, async function () { + this.timeout(10000); + // Google's dns server address. Needs to be set explicitly to run in CI + const dnsNodeDiscovery = DnsNodeDiscovery.dnsOverHttp(); + + const peers = await dnsNodeDiscovery.getPeers([enrTree], { + relay: maxQuantity, + store: maxQuantity, + filter: maxQuantity, + lightPush: maxQuantity, + }); + + expect(peers.length).to.eq(maxQuantity); + + const multiaddrs = peers.map((peer) => peer.multiaddrs).flat(); + + const seen: string[] = []; + for (const ma of multiaddrs) { + expect(ma).to.not.be.undefined; + expect(seen).to.not.include(ma!.toString()); + seen.push(ma!.toString()); + } + }); +});