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

Commit abe5207

Browse files
authored
fix!: remove @libp2p/components (#386)
`@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 a5555d1 commit abe5207

35 files changed

+442
-440
lines changed

README.md

+10-12
Original file line numberDiff line numberDiff line change
@@ -46,19 +46,17 @@ The libp2p-kad-dht module offers 3 APIs: Peer Routing, Content Routing and Peer
4646
### Custom secondary DHT in libp2p
4747

4848
```js
49-
import { create } from '@libp2p/kad-dht'
49+
import { createLibp2pNode } from 'libp2p'
50+
import { kadDht } from '@libp2p/kad-dht'
51+
52+
const node = await createLibp2pNode({
53+
dht: kadDht()
54+
//... other config
55+
})
56+
await node.start()
5057

51-
/**
52-
* @param {Libp2p} libp2p
53-
*/
54-
async function addDHT(libp2p) {
55-
const customDHT = create({
56-
libp2p,
57-
protocolPrefix: '/custom'
58-
})
59-
await customDHT.start()
60-
61-
return customDHT
58+
for await (const event of node.dht.findPeer(node.peerId)) {
59+
console.info(event)
6260
}
6361
```
6462

package.json

+7-7
Original file line numberDiff line numberDiff line change
@@ -137,12 +137,12 @@
137137
"release": "aegir release"
138138
},
139139
"dependencies": {
140-
"@libp2p/components": "^3.0.0",
141140
"@libp2p/crypto": "^1.0.4",
142141
"@libp2p/interface-address-manager": "^2.0.0",
143142
"@libp2p/interface-connection": "^3.0.2",
144143
"@libp2p/interface-connection-manager": "^1.1.1",
145144
"@libp2p/interface-dht": "^1.0.1",
145+
"@libp2p/interface-metrics": "^3.0.0",
146146
"@libp2p/interface-peer-discovery": "^1.0.1",
147147
"@libp2p/interface-peer-id": "^1.0.4",
148148
"@libp2p/interface-peer-info": "^1.0.3",
@@ -173,20 +173,20 @@
173173
"it-stream-types": "^1.0.4",
174174
"it-take": "^1.0.2",
175175
"k-bucket": "^5.1.0",
176-
"multiformats": "^9.6.3",
176+
"multiformats": "^10.0.0",
177177
"p-defer": "^4.0.0",
178178
"p-queue": "^7.2.0",
179179
"private-ip": "^2.3.3",
180-
"protons-runtime": "^3.1.0",
180+
"protons-runtime": "^4.0.1",
181181
"timeout-abort-controller": "^3.0.0",
182182
"uint8arraylist": "^2.0.0",
183-
"uint8arrays": "^3.0.0",
183+
"uint8arrays": "^4.0.2",
184184
"varint": "^6.0.0"
185185
},
186186
"devDependencies": {
187-
"@libp2p/interface-mocks": "^6.0.0",
187+
"@libp2p/interface-mocks": "^7.0.1",
188188
"@libp2p/peer-id-factory": "^1.0.18",
189-
"@libp2p/peer-store": "^4.0.0",
189+
"@libp2p/peer-store": "^5.0.0",
190190
"@types/lodash.random": "^3.2.6",
191191
"@types/lodash.range": "^3.2.6",
192192
"@types/varint": "^6.0.0",
@@ -202,7 +202,7 @@
202202
"lodash.range": "^3.2.0",
203203
"p-retry": "^5.0.0",
204204
"p-wait-for": "^5.0.0",
205-
"protons": "^5.1.0",
205+
"protons": "^6.0.0",
206206
"sinon": "^14.0.0",
207207
"ts-sinon": "^2.0.2",
208208
"which": "^2.0.2"

src/content-fetching/index.ts

+12-14
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import type { Network } from '../network.js'
2424
import type { Logger } from '@libp2p/logger'
2525
import type { AbortOptions } from '@libp2p/interfaces'
2626
import type { QueryFunc } from '../query/types.js'
27-
import { Components, Initializable } from '@libp2p/components'
27+
import type { KadDHTComponents } from '../index.js'
2828

2929
export interface ContentFetchingInit {
3030
validators: Validators
@@ -36,18 +36,20 @@ export interface ContentFetchingInit {
3636
lan: boolean
3737
}
3838

39-
export class ContentFetching implements Initializable {
39+
export class ContentFetching {
4040
private readonly log: Logger
41-
private components: Components = new Components()
41+
private readonly components: KadDHTComponents
4242
private readonly validators: Validators
4343
private readonly selectors: Selectors
4444
private readonly peerRouting: PeerRouting
4545
private readonly queryManager: QueryManager
4646
private readonly routingTable: RoutingTable
4747
private readonly network: Network
4848

49-
constructor (init: ContentFetchingInit) {
49+
constructor (components: KadDHTComponents, init: ContentFetchingInit) {
5050
const { validators, selectors, peerRouting, queryManager, routingTable, network, lan } = init
51+
52+
this.components = components
5153
this.log = logger(`libp2p:kad-dht:${lan ? 'lan' : 'wan'}:content-fetching`)
5254
this.validators = validators
5355
this.selectors = selectors
@@ -57,13 +59,9 @@ export class ContentFetching implements Initializable {
5759
this.network = network
5860
}
5961

60-
init (components: Components): void {
61-
this.components = components
62-
}
63-
6462
async putLocal (key: Uint8Array, rec: Uint8Array) { // eslint-disable-line require-await
6563
const dsKey = bufferToRecordKey(key)
66-
await this.components.getDatastore().put(dsKey, rec)
64+
await this.components.datastore.put(dsKey, rec)
6765
}
6866

6967
/**
@@ -77,7 +75,7 @@ export class ContentFetching implements Initializable {
7775

7876
this.log('fetching record for key %k', dsKey)
7977

80-
const raw = await this.components.getDatastore().get(dsKey)
78+
const raw = await this.components.datastore.get(dsKey)
8179
this.log('found %k in local datastore', dsKey)
8280

8381
const rec = Libp2pRecord.deserialize(raw)
@@ -102,11 +100,11 @@ export class ContentFetching implements Initializable {
102100
}
103101

104102
// correct ourself
105-
if (this.components.getPeerId().equals(from)) {
103+
if (this.components.peerId.equals(from)) {
106104
try {
107105
const dsKey = bufferToRecordKey(key)
108106
this.log(`Storing corrected record for key ${dsKey.toString()}`)
109-
await this.components.getDatastore().put(dsKey, fixupRec.subarray())
107+
await this.components.datastore.put(dsKey, fixupRec.subarray())
110108
} catch (err: any) {
111109
this.log.error('Failed error correcting self', err)
112110
}
@@ -147,7 +145,7 @@ export class ContentFetching implements Initializable {
147145
// store the record locally
148146
const dsKey = bufferToRecordKey(key)
149147
this.log(`storing record for key ${dsKey.toString()}`)
150-
await this.components.getDatastore().put(dsKey, record.subarray())
148+
await this.components.datastore.put(dsKey, record.subarray())
151149

152150
// put record to the closest peers
153151
yield * pipe(
@@ -246,7 +244,7 @@ export class ContentFetching implements Initializable {
246244

247245
yield valueEvent({
248246
value: localRec.value,
249-
from: this.components.getPeerId()
247+
from: this.components.peerId
250248
})
251249
} catch (err: any) {
252250
this.log('error getting local value for %b', key, err)

src/content-routing/index.ts

+10-13
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import type { CID } from 'multiformats/cid'
2222
import type { AbortOptions } from '@libp2p/interfaces'
2323
import type { Multiaddr } from '@multiformats/multiaddr'
2424
import type { PeerInfo } from '@libp2p/interface-peer-info'
25-
import { Components, Initializable } from '@libp2p/components'
25+
import type { KadDHTComponents } from '../index.js'
2626

2727
export interface ContentRoutingInit {
2828
network: Network
@@ -33,18 +33,19 @@ export interface ContentRoutingInit {
3333
lan: boolean
3434
}
3535

36-
export class ContentRouting implements Initializable {
36+
export class ContentRouting {
3737
private readonly log: Logger
38-
private components: Components = new Components()
38+
private readonly components: KadDHTComponents
3939
private readonly network: Network
4040
private readonly peerRouting: PeerRouting
4141
private readonly queryManager: QueryManager
4242
private readonly routingTable: RoutingTable
4343
private readonly providers: Providers
4444

45-
constructor (init: ContentRoutingInit) {
45+
constructor (components: KadDHTComponents, init: ContentRoutingInit) {
4646
const { network, peerRouting, queryManager, routingTable, providers, lan } = init
4747

48+
this.components = components
4849
this.log = logger(`libp2p:kad-dht:${lan ? 'lan' : 'wan'}:content-routing`)
4950
this.network = network
5051
this.peerRouting = peerRouting
@@ -53,10 +54,6 @@ export class ContentRouting implements Initializable {
5354
this.providers = providers
5455
}
5556

56-
init (components: Components): void {
57-
this.components = components
58-
}
59-
6057
/**
6158
* Announce to the network that we can provide the value for a given key and
6259
* are contactable on the given multiaddrs
@@ -65,11 +62,11 @@ export class ContentRouting implements Initializable {
6562
this.log('provide %s', key)
6663

6764
// Add peer as provider
68-
await this.providers.addProvider(key, this.components.getPeerId())
65+
await this.providers.addProvider(key, this.components.peerId)
6966

7067
const msg = new Message(MESSAGE_TYPE.ADD_PROVIDER, key.bytes, 0)
7168
msg.providerPeers = [{
72-
id: this.components.getPeerId(),
69+
id: this.components.peerId,
7370
multiaddrs,
7471
protocols: []
7572
}]
@@ -144,13 +141,13 @@ export class ContentRouting implements Initializable {
144141
for (const peerId of provs.slice(0, toFind)) {
145142
providers.push({
146143
id: peerId,
147-
multiaddrs: ((await this.components.getPeerStore().addressBook.get(peerId)) ?? []).map(address => address.multiaddr),
144+
multiaddrs: ((await this.components.peerStore.addressBook.get(peerId)) ?? []).map(address => address.multiaddr),
148145
protocols: []
149146
})
150147
}
151148

152-
yield peerResponseEvent({ from: this.components.getPeerId(), messageType: MESSAGE_TYPE.GET_PROVIDERS, providers })
153-
yield providerEvent({ from: this.components.getPeerId(), providers: providers })
149+
yield peerResponseEvent({ from: this.components.peerId, messageType: MESSAGE_TYPE.GET_PROVIDERS, providers })
150+
yield providerEvent({ from: this.components.peerId, providers: providers })
154151
}
155152

156153
// All done

src/dual-kad-dht.ts

+8-13
Original file line numberDiff line numberDiff line change
@@ -9,23 +9,24 @@ import { EventEmitter, CustomEvent } from '@libp2p/interfaces/events'
99
import type { CID } from 'multiformats'
1010
import type { PeerId } from '@libp2p/interface-peer-id'
1111
import type { PeerDiscoveryEvents } from '@libp2p/interface-peer-discovery'
12-
import { Components, Initializable } from '@libp2p/components'
1312
import { symbol } from '@libp2p/interface-peer-discovery'
13+
import type { KadDHTComponents } from './index.js'
1414

1515
const log = logger('libp2p:kad-dht')
1616

1717
/**
1818
* A DHT implementation modelled after Kademlia with S/Kademlia modifications.
1919
* Original implementation in go: https://github.com/libp2p/go-libp2p-kad-dht.
2020
*/
21-
export class DualKadDHT extends EventEmitter<PeerDiscoveryEvents> implements DualDHT, Initializable {
22-
public wan: KadDHT
23-
public lan: KadDHT
24-
public components: Components = new Components()
21+
export class DualKadDHT extends EventEmitter<PeerDiscoveryEvents> implements DualDHT {
22+
public readonly wan: KadDHT
23+
public readonly lan: KadDHT
24+
public readonly components: KadDHTComponents
2525

26-
constructor (wan: KadDHT, lan: KadDHT) {
26+
constructor (components: KadDHTComponents, wan: KadDHT, lan: KadDHT) {
2727
super()
2828

29+
this.components = components
2930
this.wan = wan
3031
this.lan = lan
3132

@@ -50,12 +51,6 @@ export class DualKadDHT extends EventEmitter<PeerDiscoveryEvents> implements Dua
5051
return '@libp2p/dual-kad-dht'
5152
}
5253

53-
init (components: Components): void {
54-
this.components = components
55-
this.wan.init(components)
56-
this.lan.init(components)
57-
}
58-
5954
/**
6055
* Is this DHT running.
6156
*/
@@ -146,7 +141,7 @@ export class DualKadDHT extends EventEmitter<PeerDiscoveryEvents> implements Dua
146141

147142
if (!foundValue) {
148143
yield queryErrorEvent({
149-
from: this.components.getPeerId(),
144+
from: this.components.peerId,
150145
error: errCode(new Error('Not found'), 'ERR_NOT_FOUND')
151146
})
152147
}

src/index.ts

+25-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
import { KadDHT as SingleKadDHT } from './kad-dht.js'
22
import { DualKadDHT } from './dual-kad-dht.js'
33
import type { Selectors, Validators } from '@libp2p/interface-dht'
4+
import type { Registrar } from '@libp2p/interface-registrar'
5+
import type { AddressManager } from '@libp2p/interface-address-manager'
6+
import type { PeerStore } from '@libp2p/interface-peer-store'
7+
import type { ConnectionManager } from '@libp2p/interface-connection-manager'
8+
import type { Metrics } from '@libp2p/interface-metrics'
9+
import type { PeerId } from '@libp2p/interface-peer-id'
10+
import type { Datastore } from 'interface-datastore'
411

512
export interface KadDHTInit {
613
/**
@@ -57,18 +64,32 @@ export interface KadDHTInit {
5764
maxOutboundStreams?: number
5865
}
5966

60-
export class KadDHT extends DualKadDHT {
61-
constructor (init?: KadDHTInit) {
62-
super(new SingleKadDHT({
67+
export interface KadDHTComponents {
68+
peerId: PeerId
69+
registrar: Registrar
70+
addressManager: AddressManager
71+
peerStore: PeerStore
72+
metrics?: Metrics
73+
connectionManager: ConnectionManager
74+
datastore: Datastore
75+
}
76+
77+
class KadDHT extends DualKadDHT {
78+
constructor (components: KadDHTComponents, init?: KadDHTInit) {
79+
super(components, new SingleKadDHT(components, {
6380
protocolPrefix: '/ipfs',
6481
...init,
6582
lan: false
6683
}),
67-
new SingleKadDHT({
84+
new SingleKadDHT(components, {
6885
protocolPrefix: '/ipfs',
6986
...init,
7087
clientMode: false,
7188
lan: true
7289
}))
7390
}
7491
}
92+
93+
export function kadDht (init?: KadDHTInit): (components: KadDHTComponents) => DualKadDHT {
94+
return (components: KadDHTComponents) => new KadDHT(components, init)
95+
}

0 commit comments

Comments
 (0)