1- import { symbol } from '@libp2p/interface-peer-discovery'
1+ import { type ContentRouting , contentRouting } from '@libp2p/interface-content-routing'
2+ import { type PeerDiscovery , peerDiscovery , type PeerDiscoveryEvents } from '@libp2p/interface-peer-discovery'
3+ import { type PeerRouting , peerRouting } from '@libp2p/interface-peer-routing'
24import { CodeError } from '@libp2p/interfaces/errors'
35import { EventEmitter , CustomEvent } from '@libp2p/interfaces/events'
46import { logger } from '@libp2p/logger'
7+ import drain from 'it-drain'
58import merge from 'it-merge'
9+ import { DefaultKadDHT } from './kad-dht.js'
610import { queryErrorEvent } from './query/events.js'
7- import type { KadDHTComponents } from './index.js'
8- import type { KadDHT } from './kad-dht.js'
9- import type { DualDHT , QueryEvent , QueryOptions } from '@libp2p/interface-dht'
10- import type { PeerDiscoveryEvents } from '@libp2p/interface-peer-discovery'
11+ import type { DualKadDHT , KadDHT , KadDHTComponents , KadDHTInit , QueryEvent , QueryOptions } from './index.js'
1112import type { PeerId } from '@libp2p/interface-peer-id'
13+ import type { PeerInfo } from '@libp2p/interface-peer-info'
1214import type { AbortOptions } from '@libp2p/interfaces'
13- import type { CID } from 'multiformats'
15+ import type { CID } from 'multiformats/cid '
1416
1517const log = logger ( 'libp2p:kad-dht' )
1618
19+ /**
20+ * Wrapper class to convert events into returned values
21+ */
22+ class DHTContentRouting implements ContentRouting {
23+ private readonly dht : KadDHT
24+
25+ constructor ( dht : KadDHT ) {
26+ this . dht = dht
27+ }
28+
29+ async provide ( cid : CID ) : Promise < void > {
30+ await drain ( this . dht . provide ( cid ) )
31+ }
32+
33+ async * findProviders ( cid : CID , options : AbortOptions = { } ) : AsyncGenerator < PeerInfo , void , undefined > {
34+ for await ( const event of this . dht . findProviders ( cid , options ) ) {
35+ if ( event . name === 'PROVIDER' ) {
36+ yield * event . providers
37+ }
38+ }
39+ }
40+
41+ async put ( key : Uint8Array , value : Uint8Array , options ?: AbortOptions ) : Promise < void > {
42+ await drain ( this . dht . put ( key , value , options ) )
43+ }
44+
45+ async get ( key : Uint8Array , options ?: AbortOptions ) : Promise < Uint8Array > {
46+ for await ( const event of this . dht . get ( key , options ) ) {
47+ if ( event . name === 'VALUE' ) {
48+ return event . value
49+ }
50+ }
51+
52+ throw new CodeError ( 'Not found' , 'ERR_NOT_FOUND' )
53+ }
54+ }
55+
56+ /**
57+ * Wrapper class to convert events into returned values
58+ */
59+ class DHTPeerRouting implements PeerRouting {
60+ private readonly dht : KadDHT
61+
62+ constructor ( dht : KadDHT ) {
63+ this . dht = dht
64+ }
65+
66+ async findPeer ( peerId : PeerId , options : AbortOptions = { } ) : Promise < PeerInfo > {
67+ for await ( const event of this . dht . findPeer ( peerId , options ) ) {
68+ if ( event . name === 'FINAL_PEER' ) {
69+ return event . peer
70+ }
71+ }
72+
73+ throw new CodeError ( 'Not found' , 'ERR_NOT_FOUND' )
74+ }
75+
76+ async * getClosestPeers ( key : Uint8Array , options : AbortOptions = { } ) : AsyncIterable < PeerInfo > {
77+ for await ( const event of this . dht . getClosestPeers ( key , options ) ) {
78+ if ( event . name === 'FINAL_PEER' ) {
79+ yield event . peer
80+ }
81+ }
82+ }
83+ }
84+
1785/**
1886 * A DHT implementation modelled after Kademlia with S/Kademlia modifications.
1987 * Original implementation in go: https://github.com/libp2p/go-libp2p-kad-dht.
2088 */
21- export class DualKadDHT extends EventEmitter < PeerDiscoveryEvents > implements DualDHT {
22- public readonly wan : KadDHT
23- public readonly lan : KadDHT
89+ export class DefaultDualKadDHT extends EventEmitter < PeerDiscoveryEvents > implements DualKadDHT , PeerDiscovery {
90+ public readonly wan : DefaultKadDHT
91+ public readonly lan : DefaultKadDHT
2492 public readonly components : KadDHTComponents
93+ private readonly contentRouting : ContentRouting
94+ private readonly peerRouting : PeerRouting
2595
26- constructor ( components : KadDHTComponents , wan : KadDHT , lan : KadDHT ) {
96+ constructor ( components : KadDHTComponents , init : KadDHTInit = { } ) {
2797 super ( )
2898
2999 this . components = components
30- this . wan = wan
31- this . lan = lan
100+
101+ this . wan = new DefaultKadDHT ( components , {
102+ protocolPrefix : '/ipfs' ,
103+ ...init ,
104+ lan : false
105+ } )
106+ this . lan = new DefaultKadDHT ( components , {
107+ protocolPrefix : '/ipfs' ,
108+ ...init ,
109+ clientMode : false ,
110+ lan : true
111+ } )
112+
113+ this . contentRouting = new DHTContentRouting ( this )
114+ this . peerRouting = new DHTPeerRouting ( this )
32115
33116 // handle peers being discovered during processing of DHT messages
34117 this . wan . addEventListener ( 'peer' , ( evt ) => {
@@ -43,10 +126,20 @@ export class DualKadDHT extends EventEmitter<PeerDiscoveryEvents> implements Dua
43126 } )
44127 }
45128
46- readonly [ symbol ] = true
47-
48129 readonly [ Symbol . toStringTag ] = '@libp2p/dual-kad-dht'
49130
131+ get [ contentRouting ] ( ) : ContentRouting {
132+ return this . contentRouting
133+ }
134+
135+ get [ peerRouting ] ( ) : PeerRouting {
136+ return this . peerRouting
137+ }
138+
139+ get [ peerDiscovery ] ( ) : PeerDiscovery {
140+ return this
141+ }
142+
50143 /**
51144 * Is this DHT running.
52145 */
0 commit comments