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

Commit d681aaf

Browse files
authored
feat: use symbols to return routers (#464)
The DHT interface is similar to the content/peer routing interfaces but different. In order to detect content/peer routers and peer discovery implementations in [arbitrary libp2p modules](libp2p/js-libp2p#1563) use the exported symbols to create getters for them. The DHTContentRouting and DHTPeerRouting classes have been ported over from libp2p.
1 parent 13c8cdb commit d681aaf

File tree

2 files changed

+97
-3
lines changed

2 files changed

+97
-3
lines changed

package.json

+2
Original file line numberDiff line numberDiff line change
@@ -146,11 +146,13 @@
146146
"@libp2p/interface-address-manager": "^3.0.0",
147147
"@libp2p/interface-connection": "^5.0.1",
148148
"@libp2p/interface-connection-manager": "^3.0.0",
149+
"@libp2p/interface-content-routing": "^2.1.0",
149150
"@libp2p/interface-dht": "^2.0.0",
150151
"@libp2p/interface-metrics": "^4.0.0",
151152
"@libp2p/interface-peer-discovery": "^1.0.1",
152153
"@libp2p/interface-peer-id": "^2.0.0",
153154
"@libp2p/interface-peer-info": "^1.0.3",
155+
"@libp2p/interface-peer-routing": "^1.1.0",
154156
"@libp2p/interface-peer-store": "^2.0.0",
155157
"@libp2p/interface-registrar": "^2.0.11",
156158
"@libp2p/interfaces": "^3.2.0",

src/index.ts

+95-3
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,22 @@
11
import { KadDHT as SingleKadDHT } from './kad-dht.js'
22
import { DualKadDHT } from './dual-kad-dht.js'
3+
import drain from 'it-drain'
4+
import { CodeError } from '@libp2p/interfaces/errors'
5+
import type { DHT, DualDHT, Selectors, Validators } from '@libp2p/interface-dht'
6+
import { ContentRouting, contentRouting } from '@libp2p/interface-content-routing'
7+
import type { CID } from 'multiformats/cid'
8+
import type { AbortOptions } from '@libp2p/interfaces'
9+
import type { PeerInfo } from '@libp2p/interface-peer-info'
310
import type { ProvidersInit } from './providers.js'
4-
import type { Selectors, Validators } from '@libp2p/interface-dht'
511
import type { Registrar } from '@libp2p/interface-registrar'
612
import type { AddressManager } from '@libp2p/interface-address-manager'
713
import type { PeerStore } from '@libp2p/interface-peer-store'
814
import type { ConnectionManager } from '@libp2p/interface-connection-manager'
915
import type { Metrics } from '@libp2p/interface-metrics'
10-
import type { PeerId } from '@libp2p/interface-peer-id'
1116
import type { Datastore } from 'interface-datastore'
17+
import { PeerRouting, peerRouting } from '@libp2p/interface-peer-routing'
18+
import { PeerDiscovery, peerDiscovery } from '@libp2p/interface-peer-discovery'
19+
import type { PeerId } from '@libp2p/interface-peer-id'
1220

1321
export interface KadDHTInit {
1422
/**
@@ -80,7 +88,76 @@ export interface KadDHTComponents {
8088
datastore: Datastore
8189
}
8290

91+
/**
92+
* Wrapper class to convert events into returned values
93+
*/
94+
export class DHTContentRouting implements ContentRouting {
95+
private readonly dht: DHT
96+
97+
constructor (dht: DHT) {
98+
this.dht = dht
99+
}
100+
101+
async provide (cid: CID): Promise<void> {
102+
await drain(this.dht.provide(cid))
103+
}
104+
105+
async * findProviders (cid: CID, options: AbortOptions = {}): AsyncGenerator<PeerInfo, void, undefined> {
106+
for await (const event of this.dht.findProviders(cid, options)) {
107+
if (event.name === 'PROVIDER') {
108+
yield * event.providers
109+
}
110+
}
111+
}
112+
113+
async put (key: Uint8Array, value: Uint8Array, options?: AbortOptions): Promise<void> {
114+
await drain(this.dht.put(key, value, options))
115+
}
116+
117+
async get (key: Uint8Array, options?: AbortOptions): Promise<Uint8Array> {
118+
for await (const event of this.dht.get(key, options)) {
119+
if (event.name === 'VALUE') {
120+
return event.value
121+
}
122+
}
123+
124+
throw new CodeError('Not found', 'ERR_NOT_FOUND')
125+
}
126+
}
127+
128+
/**
129+
* Wrapper class to convert events into returned values
130+
*/
131+
export class DHTPeerRouting implements PeerRouting {
132+
private readonly dht: DHT
133+
134+
constructor (dht: DHT) {
135+
this.dht = dht
136+
}
137+
138+
async findPeer (peerId: PeerId, options: AbortOptions = {}): Promise<PeerInfo> {
139+
for await (const event of this.dht.findPeer(peerId, options)) {
140+
if (event.name === 'FINAL_PEER') {
141+
return event.peer
142+
}
143+
}
144+
145+
throw new CodeError('Not found', 'ERR_NOT_FOUND')
146+
}
147+
148+
async * getClosestPeers (key: Uint8Array, options: AbortOptions = {}): AsyncIterable<PeerInfo> {
149+
for await (const event of this.dht.getClosestPeers(key, options)) {
150+
if (event.name === 'FINAL_PEER') {
151+
yield event.peer
152+
}
153+
}
154+
}
155+
}
156+
83157
class KadDHT extends DualKadDHT {
158+
private readonly contentRouting: ContentRouting
159+
private readonly peerRouting: PeerRouting
160+
84161
constructor (components: KadDHTComponents, init?: KadDHTInit) {
85162
super(components, new SingleKadDHT(components, {
86163
protocolPrefix: '/ipfs',
@@ -93,9 +170,24 @@ class KadDHT extends DualKadDHT {
93170
clientMode: false,
94171
lan: true
95172
}))
173+
174+
this.contentRouting = new DHTContentRouting(this)
175+
this.peerRouting = new DHTPeerRouting(this)
176+
}
177+
178+
get [contentRouting] (): ContentRouting {
179+
return this.contentRouting
180+
}
181+
182+
get [peerRouting] (): PeerRouting {
183+
return this.peerRouting
184+
}
185+
186+
get [peerDiscovery] (): PeerDiscovery {
187+
return this
96188
}
97189
}
98190

99-
export function kadDHT (init?: KadDHTInit): (components: KadDHTComponents) => DualKadDHT {
191+
export function kadDHT (init?: KadDHTInit): (components: KadDHTComponents) => DualDHT {
100192
return (components: KadDHTComponents) => new KadDHT(components, init)
101193
}

0 commit comments

Comments
 (0)