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

Commit

Permalink
feat: use symbols to return routers
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
achingbrain committed Apr 27, 2023
1 parent 13c8cdb commit b39f997
Showing 1 changed file with 95 additions and 2 deletions.
97 changes: 95 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,23 @@
import { KadDHT as SingleKadDHT } from './kad-dht.js'
import { DualKadDHT } from './dual-kad-dht.js'
import drain from 'it-drain'
import { CodeError } from '@libp2p/interfaces/errors'
import type { DHT, DualDHT } from '@libp2p/interface-dht'
import { ContentRouting, contentRouting } from '@libp2p/interface-content-routing'
import type { CID } from 'multiformats/cid'
import type { AbortOptions } from '@libp2p/interfaces'
import type { PeerInfo } from '@libp2p/interface-peer-info'
import type { ProvidersInit } from './providers.js'
import type { Selectors, Validators } from '@libp2p/interface-dht'
import type { Registrar } from '@libp2p/interface-registrar'
import type { AddressManager } from '@libp2p/interface-address-manager'
import type { PeerStore } from '@libp2p/interface-peer-store'
import type { ConnectionManager } from '@libp2p/interface-connection-manager'
import type { Metrics } from '@libp2p/interface-metrics'
import type { PeerId } from '@libp2p/interface-peer-id'
import type { Datastore } from 'interface-datastore'
import { PeerRouting, peerRouting } from '@libp2p/interface-peer-routing'
import { PeerDiscovery, peerDiscovery } from '@libp2p/interface-peer-discovery'
import type { PeerId } from '@libp2p/interface-peer-id'

export interface KadDHTInit {
/**
Expand Down Expand Up @@ -80,7 +89,76 @@ export interface KadDHTComponents {
datastore: Datastore
}

/**
* Wrapper class to convert events into returned values
*/
export class DHTContentRouting implements ContentRouting {
private readonly dht: DHT

constructor (dht: DHT) {
this.dht = dht
}

async provide (cid: CID): Promise<void> {
await drain(this.dht.provide(cid))
}

async * findProviders (cid: CID, options: AbortOptions = {}): AsyncGenerator<PeerInfo, void, undefined> {
for await (const event of this.dht.findProviders(cid, options)) {
if (event.name === 'PROVIDER') {
yield * event.providers
}
}
}

async put (key: Uint8Array, value: Uint8Array, options?: AbortOptions): Promise<void> {
await drain(this.dht.put(key, value, options))
}

async get (key: Uint8Array, options?: AbortOptions): Promise<Uint8Array> {
for await (const event of this.dht.get(key, options)) {
if (event.name === 'VALUE') {
return event.value
}
}

throw new CodeError('Not found', 'ERR_NOT_FOUND')
}
}

/**
* Wrapper class to convert events into returned values
*/
export class DHTPeerRouting implements PeerRouting {
private readonly dht: DHT

constructor (dht: DHT) {
this.dht = dht
}

async findPeer (peerId: PeerId, options: AbortOptions = {}): Promise<PeerInfo> {
for await (const event of this.dht.findPeer(peerId, options)) {
if (event.name === 'FINAL_PEER') {
return event.peer
}
}

throw new CodeError('Not found', 'ERR_NOT_FOUND')
}

async * getClosestPeers (key: Uint8Array, options: AbortOptions = {}): AsyncIterable<PeerInfo> {
for await (const event of this.dht.getClosestPeers(key, options)) {
if (event.name === 'FINAL_PEER') {
yield event.peer
}
}
}
}

class KadDHT extends DualKadDHT {
private contentRouting: ContentRouting
private peerRouting: PeerRouting

constructor (components: KadDHTComponents, init?: KadDHTInit) {
super(components, new SingleKadDHT(components, {
protocolPrefix: '/ipfs',
Expand All @@ -93,9 +171,24 @@ class KadDHT extends DualKadDHT {
clientMode: false,
lan: true
}))

this.contentRouting = new DHTContentRouting(this)
this.peerRouting = new DHTPeerRouting(this)
}

get [contentRouting] (): ContentRouting {
return this.contentRouting
}

get [peerRouting] (): PeerRouting {
return this.peerRouting
}

get [peerDiscovery] (): PeerDiscovery {
return this
}
}

export function kadDHT (init?: KadDHTInit): (components: KadDHTComponents) => DualKadDHT {
export function kadDHT (init?: KadDHTInit): (components: KadDHTComponents) => DualDHT {
return (components: KadDHTComponents) => new KadDHT(components, init)
}

0 comments on commit b39f997

Please sign in to comment.