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'
2
4
import { CodeError } from '@libp2p/interfaces/errors'
3
5
import { EventEmitter , CustomEvent } from '@libp2p/interfaces/events'
4
6
import { logger } from '@libp2p/logger'
7
+ import drain from 'it-drain'
5
8
import merge from 'it-merge'
9
+ import { DefaultKadDHT } from './kad-dht.js'
6
10
import { 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'
11
12
import type { PeerId } from '@libp2p/interface-peer-id'
13
+ import type { PeerInfo } from '@libp2p/interface-peer-info'
12
14
import type { AbortOptions } from '@libp2p/interfaces'
13
- import type { CID } from 'multiformats'
15
+ import type { CID } from 'multiformats/cid '
14
16
15
17
const log = logger ( 'libp2p:kad-dht' )
16
18
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
+
17
85
/**
18
86
* A DHT implementation modelled after Kademlia with S/Kademlia modifications.
19
87
* Original implementation in go: https://github.com/libp2p/go-libp2p-kad-dht.
20
88
*/
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
24
92
public readonly components : KadDHTComponents
93
+ private readonly contentRouting : ContentRouting
94
+ private readonly peerRouting : PeerRouting
25
95
26
- constructor ( components : KadDHTComponents , wan : KadDHT , lan : KadDHT ) {
96
+ constructor ( components : KadDHTComponents , init : KadDHTInit = { } ) {
27
97
super ( )
28
98
29
99
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 )
32
115
33
116
// handle peers being discovered during processing of DHT messages
34
117
this . wan . addEventListener ( 'peer' , ( evt ) => {
@@ -43,10 +126,20 @@ export class DualKadDHT extends EventEmitter<PeerDiscoveryEvents> implements Dua
43
126
} )
44
127
}
45
128
46
- readonly [ symbol ] = true
47
-
48
129
readonly [ Symbol . toStringTag ] = '@libp2p/dual-kad-dht'
49
130
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
+
50
143
/**
51
144
* Is this DHT running.
52
145
*/
0 commit comments