@libp2p/bootstrap 2.0.1 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -24,37 +24,49 @@ $ npm i @libp2p/bootstrap
24
24
 
25
25
  ## Usage
26
26
 
27
+ The configured bootstrap peers will be discovered after the configured timeout. This will ensure
28
+ there are some peers in the peer store for the node to use to discover other peers.
29
+
30
+ They will be tagged with a tag with the name `'bootstrap'` tag, the value `50` and it will expire
31
+ after two minutes which means the nodes connections may be closed if the maximum number of
32
+ connections is reached.
33
+
34
+ Clients that need constant connections to bootstrap nodes (e.g. browsers) can set the TTL to `Infinity`.
35
+
27
36
  ```JavaScript
28
- const Libp2p = require('libp2p')
29
- const Bootstrap = require('libp2p-bootstrap')
30
- const TCP = require('libp2p-tcp')
31
- const { NOISE } = require('libp2p-noise')
32
- const MPLEX = require('libp2p-mplex')
37
+ import { createLibp2p } from 'libp2p'
38
+ import { Bootstrap } from '@libp2p/bootstrap'
39
+ import { TCP } from 'libp2p/tcp'
40
+ import { Noise } from '@libp2p/noise'
41
+ import { Mplex } from '@libp2p/mplex'
33
42
 
34
43
  let options = {
35
- modules: {
36
- transport: [ TCP ],
37
- peerDiscovery: [ Bootstrap ],
38
- streamMuxer: [ MPLEX ],
39
- encryption: [ NOISE ]
40
- },
41
- config: {
42
- peerDiscovery: {
43
- [Bootstrap.tag]: {
44
- list: [ // a list of bootstrap peer multiaddrs to connect to on node startup
45
- "/ip4/104.131.131.82/tcp/4001/ipfs/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ",
46
- "/dnsaddr/bootstrap.libp2p.io/ipfs/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN",
47
- "/dnsaddr/bootstrap.libp2p.io/ipfs/QmQCU2EcMqAqQPR2i9bChDtGNJchTbq5TbXJJ16u19uLTa"
48
- ],
49
- interval: 5000 // default is 10 ms,
50
- enabled: true
51
- }
52
- }
53
- }
44
+ transports: [
45
+ new TCP()
46
+ ],
47
+ streamMuxers: [
48
+ new Mplex()
49
+ ],
50
+ connectionEncryption: [
51
+ new Noise()
52
+ ],
53
+ peerDiscovery: [
54
+ new Bootstrap({
55
+ list: [ // a list of bootstrap peer multiaddrs to connect to on node startup
56
+ "/ip4/104.131.131.82/tcp/4001/ipfs/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ",
57
+ "/dnsaddr/bootstrap.libp2p.io/ipfs/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN",
58
+ "/dnsaddr/bootstrap.libp2p.io/ipfs/QmQCU2EcMqAqQPR2i9bChDtGNJchTbq5TbXJJ16u19uLTa"
59
+ ],
60
+ timeout: 1000, // in ms,
61
+ tagName: 'bootstrap',
62
+ tagValue: 50,
63
+ tagTTL: 120000 // in ms
64
+ })
65
+ ]
54
66
  }
55
67
 
56
68
  async function start () {
57
- let libp2p = await Libp2p.create(options)
69
+ let libp2p = await createLibp2p(options)
58
70
 
59
71
  libp2p.on('peer:discovery', function (peerId) {
60
72
  console.log('found peer: ', peerId.toB58String())
@@ -1,25 +1,41 @@
1
1
  import { EventEmitter } from '@libp2p/interfaces/events';
2
2
  import type { PeerDiscovery, PeerDiscoveryEvents } from '@libp2p/interface-peer-discovery';
3
3
  import { symbol } from '@libp2p/interface-peer-discovery';
4
+ import { Components, Initializable } from '@libp2p/components';
4
5
  export interface BootstrapOptions {
5
6
  /**
6
7
  * The list of peer addresses in multi-address format
7
8
  */
8
9
  list: string[];
9
10
  /**
10
- * The interval between emitting addresses in milliseconds
11
+ * How long to wait before discovering bootstrap nodes
11
12
  */
12
- interval?: number;
13
+ timeout?: number;
14
+ /**
15
+ * Tag a bootstrap peer with this name before "discovering" it (default: 'bootstrap')
16
+ */
17
+ tagName?: string;
18
+ /**
19
+ * The bootstrap peer tag will have this value (default: 50)
20
+ */
21
+ tagValue?: number;
22
+ /**
23
+ * Cause the bootstrap peer tag to be removed after this number of ms (default: 2 minutes)
24
+ */
25
+ tagTTL?: number;
13
26
  }
14
27
  /**
15
28
  * Emits 'peer' events on a regular interval for each peer in the provided list.
16
29
  */
17
- export declare class Bootstrap extends EventEmitter<PeerDiscoveryEvents> implements PeerDiscovery {
30
+ export declare class Bootstrap extends EventEmitter<PeerDiscoveryEvents> implements PeerDiscovery, Initializable {
18
31
  static tag: string;
19
32
  private timer?;
20
33
  private readonly list;
21
- private readonly interval;
34
+ private readonly timeout;
35
+ private components;
36
+ private readonly _init;
22
37
  constructor(options?: BootstrapOptions);
38
+ init(components: Components): void;
23
39
  get [symbol](): true;
24
40
  get [Symbol.toStringTag](): string;
25
41
  isStarted(): boolean;
@@ -30,7 +46,7 @@ export declare class Bootstrap extends EventEmitter<PeerDiscoveryEvents> impleme
30
46
  /**
31
47
  * Emit each address in the list as a PeerInfo
32
48
  */
33
- _discoverBootstrapPeers(): void;
49
+ _discoverBootstrapPeers(): Promise<void>;
34
50
  /**
35
51
  * Stop emitting events
36
52
  */
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAe,YAAY,EAAE,MAAM,2BAA2B,CAAA;AAErE,OAAO,KAAK,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAA;AAG1F,OAAO,EAAE,MAAM,EAAE,MAAM,kCAAkC,CAAA;AAIzD,MAAM,WAAW,gBAAgB;IAC/B;;OAEG;IACH,IAAI,EAAE,MAAM,EAAE,CAAA;IAEd;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED;;GAEG;AACH,qBAAa,SAAU,SAAQ,YAAY,CAAC,mBAAmB,CAAE,YAAW,aAAa;IACvF,MAAM,CAAC,GAAG,SAAc;IAExB,OAAO,CAAC,KAAK,CAAC,CAAgC;IAC9C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAY;IACjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAQ;gBAEpB,OAAO,GAAE,gBAA+B;IAiCrD,IAAI,CAAC,MAAM,CAAC,IAAK,IAAI,CAEpB;IAED,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,WAEvB;IAED,SAAS;IAIT;;OAEG;IACH,KAAK;IAUL;;OAEG;IACH,uBAAuB;IAUvB;;OAEG;IACH,IAAI;CAOL"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAe,YAAY,EAAE,MAAM,2BAA2B,CAAA;AAErE,OAAO,KAAK,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAA;AAG1F,OAAO,EAAE,MAAM,EAAE,MAAM,kCAAkC,CAAA;AACzD,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAS9D,MAAM,WAAW,gBAAgB;IAC/B;;OAEG;IACH,IAAI,EAAE,MAAM,EAAE,CAAA;IAEd;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;IAEhB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;IAEhB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IAEjB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED;;GAEG;AACH,qBAAa,SAAU,SAAQ,YAAY,CAAC,mBAAmB,CAAE,YAAW,aAAa,EAAE,aAAa;IACtG,MAAM,CAAC,GAAG,SAAc;IAExB,OAAO,CAAC,KAAK,CAAC,CAA+B;IAC7C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAY;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAQ;IAChC,OAAO,CAAC,UAAU,CAA+B;IACjD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAkB;gBAE3B,OAAO,GAAE,gBAA+B;IAmCrD,IAAI,CAAE,UAAU,EAAE,UAAU;IAI5B,IAAI,CAAC,MAAM,CAAC,IAAK,IAAI,CAEpB;IAED,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,WAEvB;IAED,SAAS;IAIT;;OAEG;IACH,KAAK;IAcL;;OAEG;IACG,uBAAuB;IAoB7B;;OAEG;IACH,IAAI;CAOL"}
package/dist/src/index.js CHANGED
@@ -4,7 +4,12 @@ import { CustomEvent, EventEmitter } from '@libp2p/interfaces/events';
4
4
  import { logger } from '@libp2p/logger';
5
5
  import { peerIdFromString } from '@libp2p/peer-id';
6
6
  import { symbol } from '@libp2p/interface-peer-discovery';
7
+ import { Components } from '@libp2p/components';
7
8
  const log = logger('libp2p:bootstrap');
9
+ const DEFAULT_BOOTSTRAP_TAG_NAME = 'bootstrap';
10
+ const DEFAULT_BOOTSTRAP_TAG_VALUE = 50;
11
+ const DEFAULT_BOOTSTRAP_TAG_TTL = 120000;
12
+ const DEFAULT_BOOTSTRAP_DISCOVERY_TIMEOUT = 1000;
8
13
  /**
9
14
  * Emits 'peer' events on a regular interval for each peer in the provided list.
10
15
  */
@@ -14,7 +19,8 @@ export class Bootstrap extends EventEmitter {
14
19
  throw new Error('Bootstrap requires a list of peer addresses');
15
20
  }
16
21
  super();
17
- this.interval = options.interval ?? 10000;
22
+ this.components = new Components();
23
+ this.timeout = options.timeout ?? DEFAULT_BOOTSTRAP_DISCOVERY_TIMEOUT;
18
24
  this.list = [];
19
25
  for (const candidate of options.list) {
20
26
  if (!P2P.matches(candidate)) {
@@ -34,6 +40,10 @@ export class Bootstrap extends EventEmitter {
34
40
  };
35
41
  this.list.push(peerData);
36
42
  }
43
+ this._init = options;
44
+ }
45
+ init(components) {
46
+ this.components = components;
37
47
  }
38
48
  get [symbol]() {
39
49
  return true;
@@ -48,30 +58,42 @@ export class Bootstrap extends EventEmitter {
48
58
  * Start emitting events
49
59
  */
50
60
  start() {
51
- if (this.timer != null) {
61
+ if (this.isStarted()) {
52
62
  return;
53
63
  }
54
- this.timer = setInterval(() => this._discoverBootstrapPeers(), this.interval);
55
- log('Starting bootstrap node discovery');
56
- this._discoverBootstrapPeers();
64
+ log('Starting bootstrap node discovery, discovering peers after %s ms', this.timeout);
65
+ this.timer = setTimeout(() => {
66
+ void this._discoverBootstrapPeers()
67
+ .catch(err => {
68
+ log.error(err);
69
+ });
70
+ }, this.timeout);
57
71
  }
58
72
  /**
59
73
  * Emit each address in the list as a PeerInfo
60
74
  */
61
- _discoverBootstrapPeers() {
75
+ async _discoverBootstrapPeers() {
62
76
  if (this.timer == null) {
63
77
  return;
64
78
  }
65
- this.list.forEach((peerData) => {
79
+ for (const peerData of this.list) {
80
+ await this.components.getPeerStore().tagPeer(peerData.id, this._init.tagName ?? DEFAULT_BOOTSTRAP_TAG_NAME, {
81
+ value: this._init.tagValue ?? DEFAULT_BOOTSTRAP_TAG_VALUE,
82
+ ttl: this._init.tagTTL ?? DEFAULT_BOOTSTRAP_TAG_TTL
83
+ });
84
+ // check we are still running
85
+ if (this.timer == null) {
86
+ return;
87
+ }
66
88
  this.dispatchEvent(new CustomEvent('peer', { detail: peerData }));
67
- });
89
+ }
68
90
  }
69
91
  /**
70
92
  * Stop emitting events
71
93
  */
72
94
  stop() {
73
95
  if (this.timer != null) {
74
- clearInterval(this.timer);
96
+ clearTimeout(this.timer);
75
97
  }
76
98
  this.timer = undefined;
77
99
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@libp2p/bootstrap",
3
- "version": "2.0.1",
3
+ "version": "4.0.0",
4
4
  "description": "Node.js IPFS Implementation of the railing process of a Node through a bootstrap peer list",
5
5
  "license": "Apache-2.0 OR MIT",
6
6
  "homepage": "https://github.com/libp2p/js-libp2p-bootstrap#readme",
@@ -138,10 +138,11 @@
138
138
  "release": "aegir release"
139
139
  },
140
140
  "dependencies": {
141
+ "@libp2p/components": "^3.0.0",
141
142
  "@libp2p/interface-peer-discovery": "^1.0.1",
142
143
  "@libp2p/interface-peer-info": "^1.0.3",
143
144
  "@libp2p/interfaces": "^3.0.3",
144
- "@libp2p/logger": "^2.0.0",
145
+ "@libp2p/logger": "^2.0.1",
145
146
  "@libp2p/peer-id": "^1.1.15",
146
147
  "@multiformats/mafmt": "^11.0.3",
147
148
  "@multiformats/multiaddr": "^11.0.0"
@@ -149,6 +150,9 @@
149
150
  "devDependencies": {
150
151
  "@libp2p/interface-peer-discovery-compliance-tests": "^1.0.2",
151
152
  "@libp2p/interface-peer-id": "^1.0.4",
152
- "aegir": "^37.5.3"
153
+ "@libp2p/peer-store": "^4.0.0",
154
+ "aegir": "^37.5.3",
155
+ "datastore-core": "^8.0.1",
156
+ "delay": "^5.0.0"
153
157
  }
154
158
  }
package/src/index.ts CHANGED
@@ -6,9 +6,15 @@ import type { PeerDiscovery, PeerDiscoveryEvents } from '@libp2p/interface-peer-
6
6
  import type { PeerInfo } from '@libp2p/interface-peer-info'
7
7
  import { peerIdFromString } from '@libp2p/peer-id'
8
8
  import { symbol } from '@libp2p/interface-peer-discovery'
9
+ import { Components, Initializable } from '@libp2p/components'
9
10
 
10
11
  const log = logger('libp2p:bootstrap')
11
12
 
13
+ const DEFAULT_BOOTSTRAP_TAG_NAME = 'bootstrap'
14
+ const DEFAULT_BOOTSTRAP_TAG_VALUE = 50
15
+ const DEFAULT_BOOTSTRAP_TAG_TTL = 120000
16
+ const DEFAULT_BOOTSTRAP_DISCOVERY_TIMEOUT = 1000
17
+
12
18
  export interface BootstrapOptions {
13
19
  /**
14
20
  * The list of peer addresses in multi-address format
@@ -16,20 +22,37 @@ export interface BootstrapOptions {
16
22
  list: string[]
17
23
 
18
24
  /**
19
- * The interval between emitting addresses in milliseconds
25
+ * How long to wait before discovering bootstrap nodes
26
+ */
27
+ timeout?: number
28
+
29
+ /**
30
+ * Tag a bootstrap peer with this name before "discovering" it (default: 'bootstrap')
31
+ */
32
+ tagName?: string
33
+
34
+ /**
35
+ * The bootstrap peer tag will have this value (default: 50)
36
+ */
37
+ tagValue?: number
38
+
39
+ /**
40
+ * Cause the bootstrap peer tag to be removed after this number of ms (default: 2 minutes)
20
41
  */
21
- interval?: number
42
+ tagTTL?: number
22
43
  }
23
44
 
24
45
  /**
25
46
  * Emits 'peer' events on a regular interval for each peer in the provided list.
26
47
  */
27
- export class Bootstrap extends EventEmitter<PeerDiscoveryEvents> implements PeerDiscovery {
48
+ export class Bootstrap extends EventEmitter<PeerDiscoveryEvents> implements PeerDiscovery, Initializable {
28
49
  static tag = 'bootstrap'
29
50
 
30
- private timer?: ReturnType<typeof setInterval>
51
+ private timer?: ReturnType<typeof setTimeout>
31
52
  private readonly list: PeerInfo[]
32
- private readonly interval: number
53
+ private readonly timeout: number
54
+ private components: Components = new Components()
55
+ private readonly _init: BootstrapOptions
33
56
 
34
57
  constructor (options: BootstrapOptions = { list: [] }) {
35
58
  if (options.list == null || options.list.length === 0) {
@@ -37,7 +60,7 @@ export class Bootstrap extends EventEmitter<PeerDiscoveryEvents> implements Peer
37
60
  }
38
61
  super()
39
62
 
40
- this.interval = options.interval ?? 10000
63
+ this.timeout = options.timeout ?? DEFAULT_BOOTSTRAP_DISCOVERY_TIMEOUT
41
64
  this.list = []
42
65
 
43
66
  for (const candidate of options.list) {
@@ -62,6 +85,12 @@ export class Bootstrap extends EventEmitter<PeerDiscoveryEvents> implements Peer
62
85
 
63
86
  this.list.push(peerData)
64
87
  }
88
+
89
+ this._init = options
90
+ }
91
+
92
+ init (components: Components) {
93
+ this.components = components
65
94
  }
66
95
 
67
96
  get [symbol] (): true {
@@ -80,26 +109,40 @@ export class Bootstrap extends EventEmitter<PeerDiscoveryEvents> implements Peer
80
109
  * Start emitting events
81
110
  */
82
111
  start () {
83
- if (this.timer != null) {
112
+ if (this.isStarted()) {
84
113
  return
85
114
  }
86
115
 
87
- this.timer = setInterval(() => this._discoverBootstrapPeers(), this.interval)
88
- log('Starting bootstrap node discovery')
89
- this._discoverBootstrapPeers()
116
+ log('Starting bootstrap node discovery, discovering peers after %s ms', this.timeout)
117
+ this.timer = setTimeout(() => {
118
+ void this._discoverBootstrapPeers()
119
+ .catch(err => {
120
+ log.error(err)
121
+ })
122
+ }, this.timeout)
90
123
  }
91
124
 
92
125
  /**
93
126
  * Emit each address in the list as a PeerInfo
94
127
  */
95
- _discoverBootstrapPeers () {
128
+ async _discoverBootstrapPeers () {
96
129
  if (this.timer == null) {
97
130
  return
98
131
  }
99
132
 
100
- this.list.forEach((peerData) => {
133
+ for (const peerData of this.list) {
134
+ await this.components.getPeerStore().tagPeer(peerData.id, this._init.tagName ?? DEFAULT_BOOTSTRAP_TAG_NAME, {
135
+ value: this._init.tagValue ?? DEFAULT_BOOTSTRAP_TAG_VALUE,
136
+ ttl: this._init.tagTTL ?? DEFAULT_BOOTSTRAP_TAG_TTL
137
+ })
138
+
139
+ // check we are still running
140
+ if (this.timer == null) {
141
+ return
142
+ }
143
+
101
144
  this.dispatchEvent(new CustomEvent<PeerInfo>('peer', { detail: peerData }))
102
- })
145
+ }
103
146
  }
104
147
 
105
148
  /**
@@ -107,7 +150,7 @@ export class Bootstrap extends EventEmitter<PeerDiscoveryEvents> implements Peer
107
150
  */
108
151
  stop () {
109
152
  if (this.timer != null) {
110
- clearInterval(this.timer)
153
+ clearTimeout(this.timer)
111
154
  }
112
155
 
113
156
  this.timer = undefined