fix(dns-discovery): Use DOH list from dns-query

To make the library more robust as not all DOH allow CORS. Previous
default DOH got CORS disabled.
This commit is contained in:
fryorcraken.eth 2023-04-03 15:59:07 +10:00
parent e385652411
commit 1dd32101ba
No known key found for this signature in database
GPG Key ID: A82ED75A8DFC50A4
9 changed files with 70 additions and 46 deletions

8
package-lock.json generated
View File

@ -29124,6 +29124,10 @@
"eslint-plugin-functional": "^5.0.4",
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-prettier": "^4.2.1",
"karma": "^6.4.1",
"karma-chrome-launcher": "^3.1.1",
"karma-mocha": "^2.0.1",
"karma-webpack": "^5.0.0",
"mocha": "^10.2.0",
"npm-run-all": "^4.1.5",
"prettier": "^2.8.4",
@ -34119,6 +34123,10 @@
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-prettier": "^4.2.1",
"hi-base32": "^0.5.1",
"karma": "^6.4.1",
"karma-chrome-launcher": "^3.1.1",
"karma-mocha": "^2.0.1",
"karma-webpack": "^5.0.0",
"mocha": "^10.2.0",
"npm-run-all": "^4.1.5",
"prettier": "^2.8.4",

View File

@ -4,9 +4,9 @@ const webpack = require("webpack");
module.exports = function (config) {
config.set({
frameworks: ["webpack", "mocha"],
files: ["src/**/*.ts"],
files: ["src/**/!(node).spec.ts"],
preprocessors: {
"src/**/*.ts": ["webpack"],
"src/**/!(node).spec.ts": ["webpack"],
},
envPreprocessor: ["CI"],
reporters: ["progress"],
@ -20,7 +20,19 @@ module.exports = function (config) {
webpack: {
mode: "development",
module: {
rules: [{ test: /\.([cm]?ts|tsx)$/, loader: "ts-loader" }],
rules: [
{
test: /\.([cm]?ts|tsx)$/,
use: [
{
loader: "ts-loader",
options: {
configFile: "tsconfig.karma.json",
},
},
],
},
],
},
plugins: [
new webpack.DefinePlugin({

View File

@ -53,7 +53,8 @@
"prepublish": "npm run build",
"reset-hard": "git clean -dfx -e .idea && git reset --hard && npm i && npm run build",
"test": "run-s test:*",
"test:node": "TS_NODE_PROJECT=./tsconfig.dev.json mocha"
"test:node": "TS_NODE_PROJECT=./tsconfig.dev.json mocha",
"test:browser": "karma start karma.conf.cjs"
},
"engines": {
"node": ">=16"
@ -90,6 +91,10 @@
"eslint-plugin-functional": "^5.0.4",
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-prettier": "^4.2.1",
"karma": "^6.4.1",
"karma-chrome-launcher": "^3.1.1",
"karma-mocha": "^2.0.1",
"karma-webpack": "^5.0.0",
"mocha": "^10.2.0",
"npm-run-all": "^4.1.5",
"prettier": "^2.8.4",

View File

@ -273,7 +273,7 @@ describe("DNS Node Discovery [live data]", function () {
it(`should retrieve ${maxQuantity} multiaddrs for test.waku.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 dnsNodeDiscovery = await DnsNodeDiscovery.dnsOverHttp();
const peers = await dnsNodeDiscovery.getPeers([enrTree.TEST], {
relay: maxQuantity,
store: maxQuantity,
@ -296,7 +296,7 @@ describe("DNS Node Discovery [live data]", function () {
it(`should retrieve ${maxQuantity} multiaddrs for prod.waku.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 dnsNodeDiscovery = await DnsNodeDiscovery.dnsOverHttp();
const peers = await dnsNodeDiscovery.getPeers([enrTree.PROD], {
relay: maxQuantity,
store: maxQuantity,

View File

@ -33,9 +33,11 @@ export class DnsNodeDiscovery {
private readonly _DNSTreeCache: { [key: string]: string };
private readonly _errorTolerance: number = 10;
public static dnsOverHttp(dnsClient?: DnsClient): DnsNodeDiscovery {
public static async dnsOverHttp(
dnsClient?: DnsClient
): Promise<DnsNodeDiscovery> {
if (!dnsClient) {
dnsClient = new DnsOverHttps();
dnsClient = await DnsOverHttps.create();
}
return new DnsNodeDiscovery(dnsClient);
}

View File

@ -1,45 +1,32 @@
import { bytesToUtf8 } from "@waku/utils/bytes";
import debug from "debug";
import { Endpoint, query, toEndpoint } from "dns-query";
import { Endpoint, query, wellknown } from "dns-query";
import { DnsClient } from "./dns.js";
const log = debug("waku:dns-over-https");
export class DnsOverHttps implements DnsClient {
/**
* Default endpoints to use for DNS queries.
* Taken from https://github.com/martinheidegger/dns-query as static data
* to avoid dynamic queries.
*
* To dynamically retrieve other endpoints, use https://github.com/martinheidegger/dns-query#well-known-endpoints
*/
static DefaultEndpoints: Endpoint[] = [
toEndpoint({
name: "AhaDNS",
protocol: "https:",
host: "doh.la.ahadns.net",
ipv4: "45.67.219.208",
}),
toEndpoint({
name: "cloudflare",
protocol: "https:",
host: "dns.cloudflare.com",
ipv4: "1.0.0.1",
}),
];
/**
* Create new Dns-Over-Http DNS client.
*
* @param endpoints The endpoints for Dns-Over-Https queries;
* Defaults to [[DnsOverHttps.DefaultEndpoints]].
* Defaults to using dns-query's API..
* @param retries Retries if a given endpoint fails.
*
* @throws {code: string} If DNS query fails.
*/
public constructor(
private endpoints: Endpoint[] = DnsOverHttps.DefaultEndpoints,
public static async create(
endpoints?: Endpoint[],
retries?: number
): Promise<DnsOverHttps> {
const _endpoints = endpoints ?? (await wellknown.endpoints("doh"));
return new DnsOverHttps(_endpoints, retries);
}
private constructor(
private endpoints: Endpoint[],
private retries: number = 3
) {}

View File

@ -60,7 +60,7 @@ export class PeerDiscoveryDns
extends EventEmitter<PeerDiscoveryEvents>
implements PeerDiscovery
{
private readonly nextPeer: () => AsyncGenerator<IEnr>;
private nextPeer: (() => AsyncGenerator<IEnr>) | undefined;
private _started: boolean;
private _components: DnsDiscoveryComponents;
private _options: Options;
@ -71,17 +71,8 @@ export class PeerDiscoveryDns
this._components = components;
this._options = options;
const { enrUrl, wantedNodeCapabilityCount } = options;
const { enrUrl } = options;
log("Use following EIP-1459 ENR Tree URL: ", enrUrl);
const dns = DnsNodeDiscovery.dnsOverHttp();
this.nextPeer = dns.getNextPeer.bind(
dns,
[enrUrl],
wantedNodeCapabilityCount
);
}
/**
@ -91,6 +82,18 @@ export class PeerDiscoveryDns
log("Starting peer discovery via dns");
this._started = true;
if (this.nextPeer === undefined) {
const { enrUrl, wantedNodeCapabilityCount } = this._options;
const dns = await DnsNodeDiscovery.dnsOverHttp();
this.nextPeer = dns.getNextPeer.bind(
dns,
[enrUrl],
wantedNodeCapabilityCount
);
}
for await (const peer of this.nextPeer()) {
if (!this._started) return;

View File

@ -0,0 +1,7 @@
{
"extends": "./tsconfig",
"compilerOptions": {
"module": "esnext"
},
"exclude": []
}

View File

@ -90,7 +90,7 @@ describe("DNS Node Discovery [live data]", function () {
this.timeout(10000);
// Google's dns server address. Needs to be set explicitly to run in CI
const dnsNodeDiscovery = DnsNodeDiscovery.dnsOverHttp();
const dnsNodeDiscovery = await DnsNodeDiscovery.dnsOverHttp();
const peers = await dnsNodeDiscovery.getPeers([enrTree["PROD"]], {
relay: maxQuantity,