Skip to content
This repository was archived by the owner on Oct 3, 2023. It is now read-only.

Commit 772acc1

Browse files
authoredOct 12, 2022
fix!: remove @libp2p/components (#144)
`@libp2p/components` is a choke-point for our dependency graph as it depends on every interface, meaning when one interface revs a major `@libp2p/components` major has to change too which means every module depending on it also needs a major. Switch instead to constructor injection of simple objects that let modules declare their dependencies on interfaces directly instead of indirectly via `@libp2p/components` Refs libp2p/js-libp2p-components#6 BREAKING CHANGE: modules no longer implement `Initializable` instead switching to constructor injection
1 parent d141806 commit 772acc1

File tree

4 files changed

+58
-59
lines changed

4 files changed

+58
-59
lines changed
 

‎package.json

+4-3
Original file line numberDiff line numberDiff line change
@@ -138,19 +138,20 @@
138138
"release": "aegir release"
139139
},
140140
"dependencies": {
141-
"@libp2p/components": "^3.0.0",
142141
"@libp2p/interface-peer-discovery": "^1.0.1",
143142
"@libp2p/interface-peer-info": "^1.0.3",
143+
"@libp2p/interface-peer-store": "^1.2.2",
144144
"@libp2p/interfaces": "^3.0.3",
145145
"@libp2p/logger": "^2.0.1",
146146
"@libp2p/peer-id": "^1.1.15",
147147
"@multiformats/mafmt": "^11.0.3",
148148
"@multiformats/multiaddr": "^11.0.0"
149149
},
150150
"devDependencies": {
151-
"@libp2p/interface-peer-discovery-compliance-tests": "^1.0.2",
151+
"@libp2p/interface-peer-discovery-compliance-tests": "^2.0.0",
152152
"@libp2p/interface-peer-id": "^1.0.4",
153-
"@libp2p/peer-store": "^4.0.0",
153+
"@libp2p/peer-id-factory": "^1.0.18",
154+
"@libp2p/peer-store": "^5.0.0",
154155
"aegir": "^37.5.3",
155156
"datastore-core": "^8.0.1",
156157
"delay": "^5.0.0"

‎src/index.ts

+17-11
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ import type { PeerDiscovery, PeerDiscoveryEvents } from '@libp2p/interface-peer-
66
import type { PeerInfo } from '@libp2p/interface-peer-info'
77
import { peerIdFromString } from '@libp2p/peer-id'
88
import { symbol } from '@libp2p/interface-peer-discovery'
9-
import { Components, Initializable } from '@libp2p/components'
9+
import type { Startable } from '@libp2p/interfaces/dist/src/startable'
10+
import type { PeerStore } from '@libp2p/interface-peer-store'
1011

1112
const log = logger('libp2p:bootstrap')
1213

@@ -15,7 +16,7 @@ const DEFAULT_BOOTSTRAP_TAG_VALUE = 50
1516
const DEFAULT_BOOTSTRAP_TAG_TTL = 120000
1617
const DEFAULT_BOOTSTRAP_DISCOVERY_TIMEOUT = 1000
1718

18-
export interface BootstrapOptions {
19+
export interface BootstrapInit {
1920
/**
2021
* The list of peer addresses in multi-address format
2122
*/
@@ -42,24 +43,29 @@ export interface BootstrapOptions {
4243
tagTTL?: number
4344
}
4445

46+
export interface BootstrapComponents {
47+
peerStore: PeerStore
48+
}
49+
4550
/**
4651
* Emits 'peer' events on a regular interval for each peer in the provided list.
4752
*/
48-
export class Bootstrap extends EventEmitter<PeerDiscoveryEvents> implements PeerDiscovery, Initializable {
53+
class Bootstrap extends EventEmitter<PeerDiscoveryEvents> implements PeerDiscovery, Startable {
4954
static tag = 'bootstrap'
5055

5156
private timer?: ReturnType<typeof setTimeout>
5257
private readonly list: PeerInfo[]
5358
private readonly timeout: number
54-
private components: Components = new Components()
55-
private readonly _init: BootstrapOptions
59+
private readonly components: BootstrapComponents
60+
private readonly _init: BootstrapInit
5661

57-
constructor (options: BootstrapOptions = { list: [] }) {
62+
constructor (components: BootstrapComponents, options: BootstrapInit = { list: [] }) {
5863
if (options.list == null || options.list.length === 0) {
5964
throw new Error('Bootstrap requires a list of peer addresses')
6065
}
6166
super()
6267

68+
this.components = components
6369
this.timeout = options.timeout ?? DEFAULT_BOOTSTRAP_DISCOVERY_TIMEOUT
6470
this.list = []
6571

@@ -89,10 +95,6 @@ export class Bootstrap extends EventEmitter<PeerDiscoveryEvents> implements Peer
8995
this._init = options
9096
}
9197

92-
init (components: Components) {
93-
this.components = components
94-
}
95-
9698
get [symbol] (): true {
9799
return true
98100
}
@@ -131,7 +133,7 @@ export class Bootstrap extends EventEmitter<PeerDiscoveryEvents> implements Peer
131133
}
132134

133135
for (const peerData of this.list) {
134-
await this.components.getPeerStore().tagPeer(peerData.id, this._init.tagName ?? DEFAULT_BOOTSTRAP_TAG_NAME, {
136+
await this.components.peerStore.tagPeer(peerData.id, this._init.tagName ?? DEFAULT_BOOTSTRAP_TAG_NAME, {
135137
value: this._init.tagValue ?? DEFAULT_BOOTSTRAP_TAG_VALUE,
136138
ttl: this._init.tagTTL ?? DEFAULT_BOOTSTRAP_TAG_TTL
137139
})
@@ -156,3 +158,7 @@ export class Bootstrap extends EventEmitter<PeerDiscoveryEvents> implements Peer
156158
this.timer = undefined
157159
}
158160
}
161+
162+
export function bootstrap (init: BootstrapInit): (components: BootstrapComponents) => PeerDiscovery {
163+
return (components: BootstrapComponents) => new Bootstrap(components, init)
164+
}

‎test/bootstrap.spec.ts

+27-31
Original file line numberDiff line numberDiff line change
@@ -2,52 +2,50 @@
22

33
import { expect } from 'aegir/chai'
44
import { IPFS } from '@multiformats/mafmt'
5-
import { Bootstrap } from '../src/index.js'
5+
import { bootstrap, BootstrapComponents } from '../src/index.js'
66
import peerList from './fixtures/default-peers.js'
77
import partialValidPeerList from './fixtures/some-invalid-peers.js'
88
import { isPeerId } from '@libp2p/interface-peer-id'
9-
import { Components } from '@libp2p/components'
109
import { PersistentPeerStore } from '@libp2p/peer-store'
1110
import { MemoryDatastore } from 'datastore-core'
1211
import { multiaddr } from '@multiformats/multiaddr'
1312
import { peerIdFromString } from '@libp2p/peer-id'
1413
import delay from 'delay'
14+
import { start, stop } from '@libp2p/interfaces/startable'
15+
import { createEd25519PeerId } from '@libp2p/peer-id-factory'
1516

1617
describe('bootstrap', () => {
17-
let components: Components
18+
let components: BootstrapComponents
1819

19-
beforeEach(() => {
20-
const datastore = new MemoryDatastore()
21-
const peerStore = new PersistentPeerStore()
22-
23-
components = new Components({
24-
peerStore,
25-
datastore
26-
})
27-
28-
peerStore.init(components)
20+
beforeEach(async () => {
21+
components = {
22+
peerStore: new PersistentPeerStore({
23+
peerId: await createEd25519PeerId(),
24+
datastore: new MemoryDatastore()
25+
})
26+
}
2927
})
3028

3129
it('should throw if no peer list is provided', () => {
32-
expect(() => new Bootstrap())
30+
// @ts-expect-error missing args
31+
expect(() => bootstrap()())
3332
.to.throw('Bootstrap requires a list of peer addresses')
3433
})
3534

3635
it('should discover bootstrap peers', async function () {
3736
this.timeout(5 * 1000)
38-
const r = new Bootstrap({
37+
const r = bootstrap({
3938
list: peerList,
4039
timeout: 100
41-
})
42-
r.init(components)
40+
})(components)
4341

4442
const p = new Promise((resolve) => r.addEventListener('peer', resolve, {
4543
once: true
4644
}))
47-
r.start()
45+
await start(r)
4846

4947
await p
50-
r.stop()
48+
await stop(r)
5149
})
5250

5351
it('should tag bootstrap peers', async function () {
@@ -57,19 +55,18 @@ describe('bootstrap', () => {
5755
const tagValue = 10
5856
const tagTTL = 50
5957

60-
const r = new Bootstrap({
58+
const r = bootstrap({
6159
list: peerList,
6260
timeout: 100,
6361
tagName,
6462
tagValue,
6563
tagTTL
66-
})
67-
r.init(components)
64+
})(components)
6865

6966
const p = new Promise((resolve) => r.addEventListener('peer', resolve, {
7067
once: true
7168
}))
72-
r.start()
69+
await start(r)
7370

7471
await p
7572

@@ -82,29 +79,28 @@ describe('bootstrap', () => {
8279

8380
const bootstrapper0PeerId = peerIdFromString(bootstrapper0PeerIdStr)
8481

85-
const tags = await components.getPeerStore().getTags(bootstrapper0PeerId)
82+
const tags = await components.peerStore.getTags(bootstrapper0PeerId)
8683

8784
expect(tags).to.have.lengthOf(1, 'bootstrap tag was not set')
8885
expect(tags).to.have.nested.property('[0].name', tagName, 'bootstrap tag had incorrect name')
8986
expect(tags).to.have.nested.property('[0].value', tagValue, 'bootstrap tag had incorrect value')
9087

9188
await delay(tagTTL * 2)
9289

93-
const tags2 = await components.getPeerStore().getTags(bootstrapper0PeerId)
90+
const tags2 = await components.peerStore.getTags(bootstrapper0PeerId)
9491

9592
expect(tags2).to.have.lengthOf(0, 'bootstrap tag did not expire')
9693

97-
r.stop()
94+
await stop(r)
9895
})
9996

10097
it('should not fail on malformed peers in peer list', async function () {
10198
this.timeout(5 * 1000)
10299

103-
const r = new Bootstrap({
100+
const r = bootstrap({
104101
list: partialValidPeerList,
105102
timeout: 100
106-
})
107-
r.init(components)
103+
})(components)
108104

109105
const p = new Promise<void>((resolve) => {
110106
r.addEventListener('peer', (evt) => {
@@ -118,9 +114,9 @@ describe('bootstrap', () => {
118114
})
119115
})
120116

121-
r.start()
117+
await start(r)
122118

123119
await p
124-
r.stop()
120+
await stop(r)
125121
})
126122
})

‎test/compliance.spec.ts

+10-14
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,26 @@
11
/* eslint-env mocha */
22

33
import tests from '@libp2p/interface-peer-discovery-compliance-tests'
4-
import { Bootstrap } from '../src/index.js'
4+
import { bootstrap } from '../src/index.js'
55
import peerList from './fixtures/default-peers.js'
6-
import { Components } from '@libp2p/components'
76
import { PersistentPeerStore } from '@libp2p/peer-store'
87
import { MemoryDatastore } from 'datastore-core'
8+
import { createEd25519PeerId } from '@libp2p/peer-id-factory'
99

1010
describe('compliance tests', () => {
1111
tests({
1212
async setup () {
13-
const datastore = new MemoryDatastore()
14-
const peerStore = new PersistentPeerStore()
15-
const components = new Components({
16-
peerStore,
17-
datastore
18-
})
19-
peerStore.init(components)
13+
const components = {
14+
peerStore: new PersistentPeerStore({
15+
peerId: await createEd25519PeerId(),
16+
datastore: new MemoryDatastore()
17+
})
18+
}
2019

21-
const bootstrap = new Bootstrap({
20+
return bootstrap({
2221
list: peerList,
2322
timeout: 100
24-
})
25-
bootstrap.init(components)
26-
27-
return bootstrap
23+
})(components)
2824
},
2925
async teardown () {}
3026
})

0 commit comments

Comments
 (0)
This repository has been archived.