Connects to a limited number of bootstrap nodes, defaults to 1

This commit is contained in:
Franck Royer 2021-09-15 16:53:55 +10:00
parent 1a9ab2ec77
commit 6504106a9e
No known key found for this signature in database
GPG Key ID: A82ED75A8DFC50A4
3 changed files with 60 additions and 3 deletions

View File

@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed ### Changed
- Upgrade libp2p libraries: @chainsafe/libp2p-noise@4.1.1, libp2p@0.32.4, libp2p-gossipsub@0.11.1. - Upgrade libp2p libraries: @chainsafe/libp2p-noise@4.1.1, libp2p@0.32.4, libp2p-gossipsub@0.11.1.
- Connects to a limited number of bootstrap nodes, defaults to 1.
## [0.12.0] - 2021-09-2 ## [0.12.0] - 2021-09-2

View File

@ -0,0 +1,35 @@
import { expect } from 'chai';
import { getPseudoRandomSubset } from './discovery';
describe('Discovery', () => {
it('returns all values when wanted number matches available values', function () {
const values = ['a', 'b', 'c'];
const res = getPseudoRandomSubset(values, 3);
expect(res.length).to.eq(3);
expect(res.includes('a')).to.be.true;
expect(res.includes('b')).to.be.true;
expect(res.includes('c')).to.be.true;
});
it('returns all values when wanted number is greater than available values', function () {
const values = ['a', 'b', 'c'];
const res = getPseudoRandomSubset(values, 5);
expect(res.length).to.eq(3);
expect(res.includes('a')).to.be.true;
expect(res.includes('b')).to.be.true;
expect(res.includes('c')).to.be.true;
});
it('returns a subset of values when wanted number is lesser than available values', function () {
const values = ['a', 'b', 'c'];
const res = getPseudoRandomSubset(values, 2);
expect(res.length).to.eq(2);
});
});

View File

@ -1,8 +1,11 @@
import axios from 'axios'; import axios from 'axios';
import debug from 'debug'; import debug from 'debug';
import { shuffle } from 'libp2p-gossipsub/src/utils';
const dbg = debug('waku:discovery'); const dbg = debug('waku:discovery');
const DefaultWantedNumber = 1;
/** /**
* GET list of nodes from remote HTTP host. * GET list of nodes from remote HTTP host.
* *
@ -14,6 +17,7 @@ const dbg = debug('waku:discovery');
* request returns `{ foo: { bar: [address1, address2] } }` then `path` should be * request returns `{ foo: { bar: [address1, address2] } }` then `path` should be
* `[ "foo", "bar" ]`. * `[ "foo", "bar" ]`.
* @param url Remote host containing bootstrap peers in JSON format. * @param url Remote host containing bootstrap peers in JSON format.
* @param wantedNumber The number of connections desired. Defaults to [DefaultWantedNumber].
* *
* @returns An array of multiaddresses. * @returns An array of multiaddresses.
* @throws If the remote host is unreachable or the response cannot be parsed * @throws If the remote host is unreachable or the response cannot be parsed
@ -21,8 +25,13 @@ const dbg = debug('waku:discovery');
*/ */
export async function getBootstrapNodes( export async function getBootstrapNodes(
path: string[] = ['fleets', 'wakuv2.prod', 'waku-websocket'], path: string[] = ['fleets', 'wakuv2.prod', 'waku-websocket'],
url = 'https://fleets.status.im/' url = 'https://fleets.status.im/',
wantedNumber: number = DefaultWantedNumber
): Promise<string[]> { ): Promise<string[]> {
if (wantedNumber <= 0) {
return [];
}
const res = await axios.get(url, { const res = await axios.get(url, {
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
}); });
@ -43,7 +52,7 @@ export async function getBootstrapNodes(
} }
if (Array.isArray(nodes)) { if (Array.isArray(nodes)) {
return nodes; return getPseudoRandomSubset(nodes, wantedNumber);
} }
if (typeof nodes === 'string') { if (typeof nodes === 'string') {
@ -51,10 +60,22 @@ export async function getBootstrapNodes(
} }
if (typeof nodes === 'object') { if (typeof nodes === 'object') {
return Object.values(nodes); nodes = Object.values(nodes);
getPseudoRandomSubset(nodes, wantedNumber);
} }
throw `Failed to retrieve bootstrap nodes: response format is not supported: ${JSON.stringify( throw `Failed to retrieve bootstrap nodes: response format is not supported: ${JSON.stringify(
nodes nodes
)}`; )}`;
} }
export function getPseudoRandomSubset(
values: string[],
wantedNumber: number
): string[] {
if (values.length <= wantedNumber) {
return values;
}
return shuffle(values).slice(0, wantedNumber);
}