@libp2p/kad-dht 11.0.8 → 12.0.0-28587d24f
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +78 -0
- package/dist/index.min.js +20 -20
- package/dist/src/constants.d.ts +2 -4
- package/dist/src/constants.d.ts.map +1 -1
- package/dist/src/constants.js +7 -9
- package/dist/src/constants.js.map +1 -1
- package/dist/src/content-fetching/index.d.ts +7 -7
- package/dist/src/content-fetching/index.d.ts.map +1 -1
- package/dist/src/content-fetching/index.js +13 -7
- package/dist/src/content-fetching/index.js.map +1 -1
- package/dist/src/content-routing/index.d.ts +5 -4
- package/dist/src/content-routing/index.d.ts.map +1 -1
- package/dist/src/content-routing/index.js +23 -13
- package/dist/src/content-routing/index.js.map +1 -1
- package/dist/src/index.d.ts +142 -28
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +87 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/kad-dht.d.ts +20 -21
- package/dist/src/kad-dht.d.ts.map +1 -1
- package/dist/src/kad-dht.js +181 -35
- package/dist/src/kad-dht.js.map +1 -1
- package/dist/src/message/dht.d.ts +35 -35
- package/dist/src/message/dht.d.ts.map +1 -1
- package/dist/src/message/dht.js +150 -130
- package/dist/src/message/dht.js.map +1 -1
- package/dist/src/message/utils.d.ts +5 -0
- package/dist/src/message/utils.d.ts.map +1 -0
- package/dist/src/message/utils.js +20 -0
- package/dist/src/message/utils.js.map +1 -0
- package/dist/src/network.d.ts +8 -8
- package/dist/src/network.d.ts.map +1 -1
- package/dist/src/network.js +30 -18
- package/dist/src/network.js.map +1 -1
- package/dist/src/peer-routing/index.d.ts +6 -6
- package/dist/src/peer-routing/index.d.ts.map +1 -1
- package/dist/src/peer-routing/index.js +48 -35
- package/dist/src/peer-routing/index.js.map +1 -1
- package/dist/src/providers.d.ts +7 -0
- package/dist/src/providers.d.ts.map +1 -1
- package/dist/src/providers.js.map +1 -1
- package/dist/src/query/events.d.ts +13 -12
- package/dist/src/query/events.d.ts.map +1 -1
- package/dist/src/query/events.js +2 -2
- package/dist/src/query/events.js.map +1 -1
- package/dist/src/query/manager.d.ts +8 -5
- package/dist/src/query/manager.d.ts.map +1 -1
- package/dist/src/query/manager.js +6 -6
- package/dist/src/query/manager.js.map +1 -1
- package/dist/src/query/query-path.d.ts +3 -3
- package/dist/src/query/query-path.d.ts.map +1 -1
- package/dist/src/query-self.d.ts +1 -1
- package/dist/src/query-self.d.ts.map +1 -1
- package/dist/src/query-self.js +2 -2
- package/dist/src/query-self.js.map +1 -1
- package/dist/src/routing-table/index.d.ts +5 -6
- package/dist/src/routing-table/index.d.ts.map +1 -1
- package/dist/src/routing-table/index.js +72 -58
- package/dist/src/routing-table/index.js.map +1 -1
- package/dist/src/routing-table/refresh.d.ts +1 -1
- package/dist/src/routing-table/refresh.d.ts.map +1 -1
- package/dist/src/routing-table/refresh.js +2 -2
- package/dist/src/routing-table/refresh.js.map +1 -1
- package/dist/src/rpc/handlers/add-provider.d.ts +2 -1
- package/dist/src/rpc/handlers/add-provider.d.ts.map +1 -1
- package/dist/src/rpc/handlers/add-provider.js +8 -6
- package/dist/src/rpc/handlers/add-provider.js.map +1 -1
- package/dist/src/rpc/handlers/find-node.d.ts +5 -3
- package/dist/src/rpc/handlers/find-node.d.ts.map +1 -1
- package/dist/src/rpc/handlers/find-node.js +22 -14
- package/dist/src/rpc/handlers/find-node.js.map +1 -1
- package/dist/src/rpc/handlers/get-providers.d.ts +5 -3
- package/dist/src/rpc/handlers/get-providers.d.ts.map +1 -1
- package/dist/src/rpc/handlers/get-providers.js +29 -16
- package/dist/src/rpc/handlers/get-providers.js.map +1 -1
- package/dist/src/rpc/handlers/get-value.d.ts +2 -1
- package/dist/src/rpc/handlers/get-value.d.ts.map +1 -1
- package/dist/src/rpc/handlers/get-value.js +16 -7
- package/dist/src/rpc/handlers/get-value.js.map +1 -1
- package/dist/src/rpc/handlers/ping.d.ts +5 -2
- package/dist/src/rpc/handlers/ping.d.ts.map +1 -1
- package/dist/src/rpc/handlers/ping.js +2 -2
- package/dist/src/rpc/handlers/ping.js.map +1 -1
- package/dist/src/rpc/handlers/put-value.d.ts +2 -1
- package/dist/src/rpc/handlers/put-value.d.ts.map +1 -1
- package/dist/src/rpc/handlers/put-value.js +8 -7
- package/dist/src/rpc/handlers/put-value.js.map +1 -1
- package/dist/src/rpc/index.d.ts +4 -3
- package/dist/src/rpc/index.d.ts.map +1 -1
- package/dist/src/rpc/index.js +11 -11
- package/dist/src/rpc/index.js.map +1 -1
- package/dist/src/topology-listener.d.ts +1 -1
- package/dist/src/topology-listener.d.ts.map +1 -1
- package/dist/src/topology-listener.js +2 -2
- package/dist/src/topology-listener.js.map +1 -1
- package/dist/src/utils.d.ts +5 -2
- package/dist/src/utils.d.ts.map +1 -1
- package/dist/src/utils.js +32 -2
- package/dist/src/utils.js.map +1 -1
- package/package.json +13 -11
- package/src/constants.ts +7 -11
- package/src/content-fetching/index.ts +21 -14
- package/src/content-routing/index.ts +29 -18
- package/src/index.ts +148 -32
- package/src/kad-dht.ts +225 -56
- package/src/message/dht.proto +32 -32
- package/src/message/dht.ts +155 -138
- package/src/message/utils.ts +25 -0
- package/src/network.ts +41 -25
- package/src/peer-routing/index.ts +57 -42
- package/src/providers.ts +7 -0
- package/src/query/events.ts +14 -14
- package/src/query/manager.ts +14 -10
- package/src/query/query-path.ts +3 -3
- package/src/query-self.ts +3 -3
- package/src/routing-table/index.ts +86 -64
- package/src/routing-table/refresh.ts +4 -4
- package/src/rpc/handlers/add-provider.ts +10 -7
- package/src/rpc/handlers/find-node.ts +27 -18
- package/src/rpc/handlers/get-providers.ts +33 -20
- package/src/rpc/handlers/get-value.ts +18 -7
- package/src/rpc/handlers/ping.ts +7 -3
- package/src/rpc/handlers/put-value.ts +11 -9
- package/src/rpc/index.ts +14 -13
- package/src/topology-listener.ts +3 -3
- package/src/utils.ts +41 -2
- package/dist/src/dual-kad-dht.d.ts +0 -69
- package/dist/src/dual-kad-dht.d.ts.map +0 -1
- package/dist/src/dual-kad-dht.js +0 -304
- package/dist/src/dual-kad-dht.js.map +0 -1
- package/dist/src/message/index.d.ts +0 -35
- package/dist/src/message/index.d.ts.map +0 -1
- package/dist/src/message/index.js +0 -92
- package/dist/src/message/index.js.map +0 -1
- package/dist/typedoc-urls.json +0 -55
- package/src/dual-kad-dht.ts +0 -384
- package/src/message/index.ts +0 -117
|
@@ -21,7 +21,7 @@ export interface RoutingTableRefreshComponents {
|
|
|
21
21
|
export interface RoutingTableRefreshInit {
|
|
22
22
|
peerRouting: PeerRouting
|
|
23
23
|
routingTable: RoutingTable
|
|
24
|
-
|
|
24
|
+
logPrefix: string
|
|
25
25
|
refreshInterval?: number
|
|
26
26
|
refreshQueryTimeout?: number
|
|
27
27
|
}
|
|
@@ -40,8 +40,8 @@ export class RoutingTableRefresh {
|
|
|
40
40
|
private refreshTimeoutId?: ReturnType<typeof setTimeout>
|
|
41
41
|
|
|
42
42
|
constructor (components: RoutingTableRefreshComponents, init: RoutingTableRefreshInit) {
|
|
43
|
-
const { peerRouting, routingTable, refreshInterval, refreshQueryTimeout,
|
|
44
|
-
this.log = components.logger.forComponent(
|
|
43
|
+
const { peerRouting, routingTable, refreshInterval, refreshQueryTimeout, logPrefix } = init
|
|
44
|
+
this.log = components.logger.forComponent(`${logPrefix}:routing-table:refresh`)
|
|
45
45
|
this.peerRouting = peerRouting
|
|
46
46
|
this.routingTable = routingTable
|
|
47
47
|
this.refreshInterval = refreshInterval ?? TABLE_REFRESH_INTERVAL
|
|
@@ -147,7 +147,7 @@ export class RoutingTableRefresh {
|
|
|
147
147
|
maxCommonPrefix = MAX_COMMON_PREFIX_LENGTH
|
|
148
148
|
}
|
|
149
149
|
|
|
150
|
-
const dates = []
|
|
150
|
+
const dates: Date[] = []
|
|
151
151
|
|
|
152
152
|
for (let i = 0; i <= maxCommonPrefix; i++) {
|
|
153
153
|
// defaults to the zero value if we haven't refreshed it yet.
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { CodeError } from '@libp2p/interface'
|
|
2
|
+
import { peerIdFromBytes } from '@libp2p/peer-id'
|
|
3
|
+
import { multiaddr } from '@multiformats/multiaddr'
|
|
2
4
|
import { CID } from 'multiformats/cid'
|
|
3
|
-
import type { Message } from '../../message/
|
|
5
|
+
import type { Message } from '../../message/dht.js'
|
|
4
6
|
import type { Providers } from '../../providers'
|
|
5
7
|
import type { DHTMessageHandler } from '../index.js'
|
|
6
8
|
import type { ComponentLogger, Logger, PeerId } from '@libp2p/interface'
|
|
@@ -11,6 +13,7 @@ export interface AddProviderComponents {
|
|
|
11
13
|
|
|
12
14
|
export interface AddProviderHandlerInit {
|
|
13
15
|
providers: Providers
|
|
16
|
+
logPrefix: string
|
|
14
17
|
}
|
|
15
18
|
|
|
16
19
|
export class AddProviderHandler implements DHTMessageHandler {
|
|
@@ -18,7 +21,7 @@ export class AddProviderHandler implements DHTMessageHandler {
|
|
|
18
21
|
private readonly log: Logger
|
|
19
22
|
|
|
20
23
|
constructor (components: AddProviderComponents, init: AddProviderHandlerInit) {
|
|
21
|
-
this.log = components.logger.forComponent(
|
|
24
|
+
this.log = components.logger.forComponent(`${init.logPrefix}:rpc:handlers:add-provider`)
|
|
22
25
|
this.providers = init.providers
|
|
23
26
|
}
|
|
24
27
|
|
|
@@ -37,14 +40,14 @@ export class AddProviderHandler implements DHTMessageHandler {
|
|
|
37
40
|
throw new CodeError('Invalid CID', 'ERR_INVALID_CID')
|
|
38
41
|
}
|
|
39
42
|
|
|
40
|
-
if (msg.
|
|
43
|
+
if (msg.providers == null || msg.providers.length === 0) {
|
|
41
44
|
this.log.error('no providers found in message')
|
|
42
45
|
}
|
|
43
46
|
|
|
44
47
|
await Promise.all(
|
|
45
|
-
msg.
|
|
48
|
+
msg.providers.map(async (pi) => {
|
|
46
49
|
// Ignore providers not from the originator
|
|
47
|
-
if (!pi.id
|
|
50
|
+
if (!peerId.equals(pi.id)) {
|
|
48
51
|
this.log('invalid provider peer %p from %p', pi.id, peerId)
|
|
49
52
|
return
|
|
50
53
|
}
|
|
@@ -54,9 +57,9 @@ export class AddProviderHandler implements DHTMessageHandler {
|
|
|
54
57
|
return
|
|
55
58
|
}
|
|
56
59
|
|
|
57
|
-
this.log('received provider %p for %s (addrs %s)', peerId, cid, pi.multiaddrs.map((m) => m.toString()))
|
|
60
|
+
this.log('received provider %p for %s (addrs %s)', peerId, cid, pi.multiaddrs.map((m) => multiaddr(m).toString()))
|
|
58
61
|
|
|
59
|
-
await this.providers.addProvider(cid, pi.id)
|
|
62
|
+
await this.providers.addProvider(cid, peerIdFromBytes(pi.id))
|
|
60
63
|
})
|
|
61
64
|
)
|
|
62
65
|
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
+
import { CodeError } from '@libp2p/interface'
|
|
1
2
|
import { protocols } from '@multiformats/multiaddr'
|
|
2
3
|
import { equals as uint8ArrayEquals } from 'uint8arrays'
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
removePublicAddresses
|
|
7
|
-
} from '../../utils.js'
|
|
4
|
+
import { MessageType } from '../../message/dht.js'
|
|
5
|
+
import type { PeerInfoMapper } from '../../index.js'
|
|
6
|
+
import type { Message } from '../../message/dht.js'
|
|
8
7
|
import type { PeerRouting } from '../../peer-routing/index.js'
|
|
9
8
|
import type { DHTMessageHandler } from '../index.js'
|
|
10
9
|
import type { ComponentLogger, Logger, PeerId, PeerInfo } from '@libp2p/interface'
|
|
@@ -12,7 +11,8 @@ import type { AddressManager } from '@libp2p/interface-internal'
|
|
|
12
11
|
|
|
13
12
|
export interface FindNodeHandlerInit {
|
|
14
13
|
peerRouting: PeerRouting
|
|
15
|
-
|
|
14
|
+
logPrefix: string
|
|
15
|
+
peerInfoMapper: PeerInfoMapper
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
export interface FindNodeHandlerComponents {
|
|
@@ -23,19 +23,19 @@ export interface FindNodeHandlerComponents {
|
|
|
23
23
|
|
|
24
24
|
export class FindNodeHandler implements DHTMessageHandler {
|
|
25
25
|
private readonly peerRouting: PeerRouting
|
|
26
|
-
private readonly
|
|
26
|
+
private readonly peerInfoMapper: PeerInfoMapper
|
|
27
27
|
private readonly peerId: PeerId
|
|
28
28
|
private readonly addressManager: AddressManager
|
|
29
29
|
private readonly log: Logger
|
|
30
30
|
|
|
31
31
|
constructor (components: FindNodeHandlerComponents, init: FindNodeHandlerInit) {
|
|
32
|
-
const { peerRouting,
|
|
32
|
+
const { peerRouting, logPrefix } = init
|
|
33
33
|
|
|
34
|
-
this.log = components.logger.forComponent(
|
|
34
|
+
this.log = components.logger.forComponent(`${logPrefix}:rpc:handlers:find-node`)
|
|
35
35
|
this.peerId = components.peerId
|
|
36
36
|
this.addressManager = components.addressManager
|
|
37
37
|
this.peerRouting = peerRouting
|
|
38
|
-
this.
|
|
38
|
+
this.peerInfoMapper = init.peerInfoMapper
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
/**
|
|
@@ -46,6 +46,10 @@ export class FindNodeHandler implements DHTMessageHandler {
|
|
|
46
46
|
|
|
47
47
|
let closer: PeerInfo[] = []
|
|
48
48
|
|
|
49
|
+
if (msg.key == null) {
|
|
50
|
+
throw new CodeError('Invalid FIND_NODE message received - key was missing', 'ERR_INVALID_MESSAGE')
|
|
51
|
+
}
|
|
52
|
+
|
|
49
53
|
if (uint8ArrayEquals(this.peerId.toBytes(), msg.key)) {
|
|
50
54
|
closer = [{
|
|
51
55
|
id: this.peerId,
|
|
@@ -55,15 +59,20 @@ export class FindNodeHandler implements DHTMessageHandler {
|
|
|
55
59
|
closer = await this.peerRouting.getCloserPeersOffline(msg.key, peerId)
|
|
56
60
|
}
|
|
57
61
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
62
|
+
const response: Message = {
|
|
63
|
+
type: MessageType.FIND_NODE,
|
|
64
|
+
clusterLevel: msg.clusterLevel,
|
|
65
|
+
closer: closer
|
|
66
|
+
.map(this.peerInfoMapper)
|
|
67
|
+
.filter(({ multiaddrs }) => multiaddrs.length)
|
|
68
|
+
.map(peerInfo => ({
|
|
69
|
+
id: peerInfo.id.toBytes(),
|
|
70
|
+
multiaddrs: peerInfo.multiaddrs.map(ma => ma.bytes)
|
|
71
|
+
})),
|
|
72
|
+
providers: []
|
|
73
|
+
}
|
|
63
74
|
|
|
64
|
-
if (closer.length
|
|
65
|
-
response.closerPeers = closer
|
|
66
|
-
} else {
|
|
75
|
+
if (response.closer.length === 0) {
|
|
67
76
|
this.log('could not find any peers closer to %b than %p', msg.key, peerId)
|
|
68
77
|
}
|
|
69
78
|
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import { CodeError } from '@libp2p/interface'
|
|
2
2
|
import { CID } from 'multiformats/cid'
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
removePublicAddresses
|
|
7
|
-
} from '../../utils.js'
|
|
3
|
+
import { MessageType } from '../../message/dht.js'
|
|
4
|
+
import type { PeerInfoMapper } from '../../index.js'
|
|
5
|
+
import type { Message } from '../../message/dht.js'
|
|
8
6
|
import type { PeerRouting } from '../../peer-routing/index.js'
|
|
9
7
|
import type { Providers } from '../../providers.js'
|
|
10
8
|
import type { DHTMessageHandler } from '../index.js'
|
|
@@ -14,7 +12,8 @@ import type { Multiaddr } from '@multiformats/multiaddr'
|
|
|
14
12
|
export interface GetProvidersHandlerInit {
|
|
15
13
|
peerRouting: PeerRouting
|
|
16
14
|
providers: Providers
|
|
17
|
-
|
|
15
|
+
logPrefix: string
|
|
16
|
+
peerInfoMapper: PeerInfoMapper
|
|
18
17
|
}
|
|
19
18
|
|
|
20
19
|
export interface GetProvidersHandlerComponents {
|
|
@@ -25,21 +24,25 @@ export interface GetProvidersHandlerComponents {
|
|
|
25
24
|
export class GetProvidersHandler implements DHTMessageHandler {
|
|
26
25
|
private readonly peerRouting: PeerRouting
|
|
27
26
|
private readonly providers: Providers
|
|
28
|
-
private readonly lan: boolean
|
|
29
27
|
private readonly peerStore: PeerStore
|
|
28
|
+
private readonly peerInfoMapper: PeerInfoMapper
|
|
30
29
|
private readonly log: Logger
|
|
31
30
|
|
|
32
31
|
constructor (components: GetProvidersHandlerComponents, init: GetProvidersHandlerInit) {
|
|
33
|
-
const { peerRouting, providers,
|
|
32
|
+
const { peerRouting, providers, logPrefix } = init
|
|
34
33
|
|
|
35
|
-
this.log = components.logger.forComponent(
|
|
34
|
+
this.log = components.logger.forComponent(`${logPrefix}:rpc:handlers:get-providers`)
|
|
36
35
|
this.peerStore = components.peerStore
|
|
37
36
|
this.peerRouting = peerRouting
|
|
38
37
|
this.providers = providers
|
|
39
|
-
this.
|
|
38
|
+
this.peerInfoMapper = init.peerInfoMapper
|
|
40
39
|
}
|
|
41
40
|
|
|
42
41
|
async handle (peerId: PeerId, msg: Message): Promise<Message> {
|
|
42
|
+
if (msg.key == null) {
|
|
43
|
+
throw new CodeError('Invalid FIND_NODE message received - key was missing', 'ERR_INVALID_MESSAGE')
|
|
44
|
+
}
|
|
45
|
+
|
|
43
46
|
let cid
|
|
44
47
|
try {
|
|
45
48
|
cid = CID.decode(msg.key)
|
|
@@ -56,17 +59,28 @@ export class GetProvidersHandler implements DHTMessageHandler {
|
|
|
56
59
|
|
|
57
60
|
const providerPeers = await this._getPeers(peers)
|
|
58
61
|
const closerPeers = await this._getPeers(closer.map(({ id }) => id))
|
|
59
|
-
const response
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
62
|
+
const response: Message = {
|
|
63
|
+
type: MessageType.GET_PROVIDERS,
|
|
64
|
+
key: msg.key,
|
|
65
|
+
clusterLevel: msg.clusterLevel,
|
|
66
|
+
closer: closerPeers
|
|
67
|
+
.map(this.peerInfoMapper)
|
|
68
|
+
.filter(({ multiaddrs }) => multiaddrs.length)
|
|
69
|
+
.map(peerInfo => ({
|
|
70
|
+
id: peerInfo.id.toBytes(),
|
|
71
|
+
multiaddrs: peerInfo.multiaddrs.map(ma => ma.bytes)
|
|
72
|
+
})),
|
|
73
|
+
providers: providerPeers
|
|
74
|
+
.map(this.peerInfoMapper)
|
|
75
|
+
.filter(({ multiaddrs }) => multiaddrs.length)
|
|
76
|
+
.map(peerInfo => ({
|
|
77
|
+
id: peerInfo.id.toBytes(),
|
|
78
|
+
multiaddrs: peerInfo.multiaddrs.map(ma => ma.bytes)
|
|
79
|
+
}))
|
|
63
80
|
}
|
|
64
81
|
|
|
65
|
-
|
|
66
|
-
response.closerPeers = closerPeers
|
|
67
|
-
}
|
|
82
|
+
this.log('got %s providers %s closerPeers', response.providers.length, response.closer.length)
|
|
68
83
|
|
|
69
|
-
this.log('got %s providers %s closerPeers', providerPeers.length, closerPeers.length)
|
|
70
84
|
return response
|
|
71
85
|
}
|
|
72
86
|
|
|
@@ -76,13 +90,12 @@ export class GetProvidersHandler implements DHTMessageHandler {
|
|
|
76
90
|
|
|
77
91
|
async _getPeers (peerIds: PeerId[]): Promise<PeerInfo[]> {
|
|
78
92
|
const output: PeerInfo[] = []
|
|
79
|
-
const addrFilter = this.lan ? removePublicAddresses : removePrivateAddresses
|
|
80
93
|
|
|
81
94
|
for (const peerId of peerIds) {
|
|
82
95
|
try {
|
|
83
96
|
const peer = await this.peerStore.get(peerId)
|
|
84
97
|
|
|
85
|
-
const peerAfterFilter =
|
|
98
|
+
const peerAfterFilter = this.peerInfoMapper({
|
|
86
99
|
id: peerId,
|
|
87
100
|
multiaddrs: peer.addresses.map(({ multiaddr }) => multiaddr)
|
|
88
101
|
})
|
|
@@ -2,9 +2,10 @@ import { CodeError } from '@libp2p/interface'
|
|
|
2
2
|
import {
|
|
3
3
|
MAX_RECORD_AGE
|
|
4
4
|
} from '../../constants.js'
|
|
5
|
-
import {
|
|
5
|
+
import { MessageType } from '../../message/dht.js'
|
|
6
6
|
import { Libp2pRecord } from '../../record/index.js'
|
|
7
7
|
import { bufferToRecordKey, isPublicKeyKey, fromPublicKeyKey } from '../../utils.js'
|
|
8
|
+
import type { Message } from '../../message/dht.js'
|
|
8
9
|
import type { PeerRouting } from '../../peer-routing/index.js'
|
|
9
10
|
import type { DHTMessageHandler } from '../index.js'
|
|
10
11
|
import type { ComponentLogger, Logger, PeerId, PeerStore } from '@libp2p/interface'
|
|
@@ -12,6 +13,7 @@ import type { Datastore } from 'interface-datastore'
|
|
|
12
13
|
|
|
13
14
|
export interface GetValueHandlerInit {
|
|
14
15
|
peerRouting: PeerRouting
|
|
16
|
+
logPrefix: string
|
|
15
17
|
}
|
|
16
18
|
|
|
17
19
|
export interface GetValueHandlerComponents {
|
|
@@ -27,7 +29,7 @@ export class GetValueHandler implements DHTMessageHandler {
|
|
|
27
29
|
private readonly log: Logger
|
|
28
30
|
|
|
29
31
|
constructor (components: GetValueHandlerComponents, init: GetValueHandlerInit) {
|
|
30
|
-
this.log = components.logger.forComponent(
|
|
32
|
+
this.log = components.logger.forComponent(`${init.logPrefix}:rpc:handlers:get-value`)
|
|
31
33
|
this.peerStore = components.peerStore
|
|
32
34
|
this.datastore = components.datastore
|
|
33
35
|
this.peerRouting = init.peerRouting
|
|
@@ -42,7 +44,13 @@ export class GetValueHandler implements DHTMessageHandler {
|
|
|
42
44
|
throw new CodeError('Invalid key', 'ERR_INVALID_KEY')
|
|
43
45
|
}
|
|
44
46
|
|
|
45
|
-
const response
|
|
47
|
+
const response: Message = {
|
|
48
|
+
type: MessageType.GET_VALUE,
|
|
49
|
+
key,
|
|
50
|
+
clusterLevel: msg.clusterLevel,
|
|
51
|
+
closer: [],
|
|
52
|
+
providers: []
|
|
53
|
+
}
|
|
46
54
|
|
|
47
55
|
if (isPublicKeyKey(key)) {
|
|
48
56
|
this.log('is public key')
|
|
@@ -65,24 +73,27 @@ export class GetValueHandler implements DHTMessageHandler {
|
|
|
65
73
|
|
|
66
74
|
if (pubKey != null) {
|
|
67
75
|
this.log('returning found public key')
|
|
68
|
-
response.record = new Libp2pRecord(key, pubKey, new Date())
|
|
76
|
+
response.record = new Libp2pRecord(key, pubKey, new Date()).serialize()
|
|
69
77
|
return response
|
|
70
78
|
}
|
|
71
79
|
}
|
|
72
80
|
|
|
73
81
|
const [record, closer] = await Promise.all([
|
|
74
82
|
this._checkLocalDatastore(key),
|
|
75
|
-
this.peerRouting.getCloserPeersOffline(
|
|
83
|
+
this.peerRouting.getCloserPeersOffline(key, peerId)
|
|
76
84
|
])
|
|
77
85
|
|
|
78
86
|
if (record != null) {
|
|
79
87
|
this.log('had record for %b in local datastore', key)
|
|
80
|
-
response.record = record
|
|
88
|
+
response.record = record.serialize()
|
|
81
89
|
}
|
|
82
90
|
|
|
83
91
|
if (closer.length > 0) {
|
|
84
92
|
this.log('had %s closer peers in routing table', closer.length)
|
|
85
|
-
response.
|
|
93
|
+
response.closer = closer.map(peerInfo => ({
|
|
94
|
+
id: peerInfo.id.toBytes(),
|
|
95
|
+
multiaddrs: peerInfo.multiaddrs.map(ma => ma.bytes)
|
|
96
|
+
}))
|
|
86
97
|
}
|
|
87
98
|
|
|
88
99
|
return response
|
package/src/rpc/handlers/ping.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Message } from '../../message/
|
|
1
|
+
import type { Message } from '../../message/dht.js'
|
|
2
2
|
import type { DHTMessageHandler } from '../index.js'
|
|
3
3
|
import type { ComponentLogger, Logger, PeerId } from '@libp2p/interface'
|
|
4
4
|
|
|
@@ -6,11 +6,15 @@ export interface PingComponents {
|
|
|
6
6
|
logger: ComponentLogger
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
+
export interface PingHandlerInit {
|
|
10
|
+
logPrefix: string
|
|
11
|
+
}
|
|
12
|
+
|
|
9
13
|
export class PingHandler implements DHTMessageHandler {
|
|
10
14
|
private readonly log: Logger
|
|
11
15
|
|
|
12
|
-
constructor (components: PingComponents) {
|
|
13
|
-
this.log = components.logger.forComponent(
|
|
16
|
+
constructor (components: PingComponents, init: PingHandlerInit) {
|
|
17
|
+
this.log = components.logger.forComponent(`${init.logPrefix}:rpc:handlers:ping`)
|
|
14
18
|
}
|
|
15
19
|
|
|
16
20
|
async handle (peerId: PeerId, msg: Message): Promise<Message> {
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import { CodeError } from '@libp2p/interface'
|
|
2
|
+
import { Libp2pRecord } from '../../record/index.js'
|
|
2
3
|
import { verifyRecord } from '../../record/validators.js'
|
|
3
4
|
import { bufferToRecordKey } from '../../utils.js'
|
|
4
5
|
import type { Validators } from '../../index.js'
|
|
5
|
-
import type { Message } from '../../message/
|
|
6
|
+
import type { Message } from '../../message/dht.js'
|
|
6
7
|
import type { DHTMessageHandler } from '../index.js'
|
|
7
8
|
import type { ComponentLogger, Logger, PeerId } from '@libp2p/interface'
|
|
8
9
|
import type { Datastore } from 'interface-datastore'
|
|
9
10
|
|
|
10
11
|
export interface PutValueHandlerInit {
|
|
11
12
|
validators: Validators
|
|
13
|
+
logPrefix: string
|
|
12
14
|
}
|
|
13
15
|
|
|
14
16
|
export interface PutValueHandlerComponents {
|
|
@@ -25,7 +27,7 @@ export class PutValueHandler implements DHTMessageHandler {
|
|
|
25
27
|
const { validators } = init
|
|
26
28
|
|
|
27
29
|
this.components = components
|
|
28
|
-
this.log = components.logger.forComponent(
|
|
30
|
+
this.log = components.logger.forComponent(`${init.logPrefix}:rpc:handlers:put-value`)
|
|
29
31
|
this.validators = validators
|
|
30
32
|
}
|
|
31
33
|
|
|
@@ -33,9 +35,7 @@ export class PutValueHandler implements DHTMessageHandler {
|
|
|
33
35
|
const key = msg.key
|
|
34
36
|
this.log('%p asked us to store value for key %b', peerId, key)
|
|
35
37
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
if (record == null) {
|
|
38
|
+
if (msg.record == null) {
|
|
39
39
|
const errMsg = `Empty record from: ${peerId.toString()}`
|
|
40
40
|
|
|
41
41
|
this.log.error(errMsg)
|
|
@@ -43,11 +43,13 @@ export class PutValueHandler implements DHTMessageHandler {
|
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
try {
|
|
46
|
-
|
|
46
|
+
const deserializedRecord = Libp2pRecord.deserialize(msg.record)
|
|
47
|
+
|
|
48
|
+
await verifyRecord(this.validators, deserializedRecord)
|
|
47
49
|
|
|
48
|
-
|
|
49
|
-
const recordKey = bufferToRecordKey(
|
|
50
|
-
await this.components.datastore.put(recordKey,
|
|
50
|
+
deserializedRecord.timeReceived = new Date()
|
|
51
|
+
const recordKey = bufferToRecordKey(deserializedRecord.key)
|
|
52
|
+
await this.components.datastore.put(recordKey, deserializedRecord.serialize().subarray())
|
|
51
53
|
this.log('put record for %b into datastore under key %k', key, recordKey)
|
|
52
54
|
} catch (err: any) {
|
|
53
55
|
this.log('did not put record for key %b into datastore %o', key, err)
|
package/src/rpc/index.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import * as lp from 'it-length-prefixed'
|
|
2
2
|
import { pipe } from 'it-pipe'
|
|
3
|
-
import { Message,
|
|
3
|
+
import { Message, MessageType } from '../message/dht.js'
|
|
4
4
|
import { AddProviderHandler } from './handlers/add-provider.js'
|
|
5
5
|
import { FindNodeHandler, type FindNodeHandlerComponents } from './handlers/find-node.js'
|
|
6
6
|
import { GetProvidersHandler, type GetProvidersHandlerComponents } from './handlers/get-providers.js'
|
|
7
7
|
import { GetValueHandler, type GetValueHandlerComponents } from './handlers/get-value.js'
|
|
8
8
|
import { PingHandler } from './handlers/ping.js'
|
|
9
9
|
import { PutValueHandler, type PutValueHandlerComponents } from './handlers/put-value.js'
|
|
10
|
-
import type { Validators } from '../index.js'
|
|
10
|
+
import type { PeerInfoMapper, Validators } from '../index.js'
|
|
11
11
|
import type { PeerRouting } from '../peer-routing'
|
|
12
12
|
import type { Providers } from '../providers'
|
|
13
13
|
import type { RoutingTable } from '../routing-table'
|
|
@@ -23,7 +23,8 @@ export interface RPCInit {
|
|
|
23
23
|
providers: Providers
|
|
24
24
|
peerRouting: PeerRouting
|
|
25
25
|
validators: Validators
|
|
26
|
-
|
|
26
|
+
logPrefix: string
|
|
27
|
+
peerInfoMapper: PeerInfoMapper
|
|
27
28
|
}
|
|
28
29
|
|
|
29
30
|
export interface RPCComponents extends GetValueHandlerComponents, PutValueHandlerComponents, FindNodeHandlerComponents, GetProvidersHandlerComponents {
|
|
@@ -36,17 +37,17 @@ export class RPC {
|
|
|
36
37
|
private readonly log: Logger
|
|
37
38
|
|
|
38
39
|
constructor (components: RPCComponents, init: RPCInit) {
|
|
39
|
-
const { providers, peerRouting, validators,
|
|
40
|
+
const { providers, peerRouting, validators, logPrefix, peerInfoMapper } = init
|
|
40
41
|
|
|
41
|
-
this.log = components.logger.forComponent(
|
|
42
|
+
this.log = components.logger.forComponent(`${logPrefix}:rpc`)
|
|
42
43
|
this.routingTable = init.routingTable
|
|
43
44
|
this.handlers = {
|
|
44
|
-
[
|
|
45
|
-
[
|
|
46
|
-
[
|
|
47
|
-
[
|
|
48
|
-
[
|
|
49
|
-
[
|
|
45
|
+
[MessageType.GET_VALUE.toString()]: new GetValueHandler(components, { peerRouting, logPrefix }),
|
|
46
|
+
[MessageType.PUT_VALUE.toString()]: new PutValueHandler(components, { validators, logPrefix }),
|
|
47
|
+
[MessageType.FIND_NODE.toString()]: new FindNodeHandler(components, { peerRouting, logPrefix, peerInfoMapper }),
|
|
48
|
+
[MessageType.ADD_PROVIDER.toString()]: new AddProviderHandler(components, { providers, logPrefix }),
|
|
49
|
+
[MessageType.GET_PROVIDERS.toString()]: new GetProvidersHandler(components, { peerRouting, providers, logPrefix, peerInfoMapper }),
|
|
50
|
+
[MessageType.PING.toString()]: new PingHandler(components, { logPrefix })
|
|
50
51
|
}
|
|
51
52
|
}
|
|
52
53
|
|
|
@@ -93,13 +94,13 @@ export class RPC {
|
|
|
93
94
|
async function * (source) {
|
|
94
95
|
for await (const msg of source) {
|
|
95
96
|
// handle the message
|
|
96
|
-
const desMessage = Message.
|
|
97
|
+
const desMessage = Message.decode(msg)
|
|
97
98
|
self.log('incoming %s from %p', desMessage.type, peerId)
|
|
98
99
|
const res = await self.handleMessage(peerId, desMessage)
|
|
99
100
|
|
|
100
101
|
// Not all handlers will return a response
|
|
101
102
|
if (res != null) {
|
|
102
|
-
yield
|
|
103
|
+
yield Message.encode(res)
|
|
103
104
|
}
|
|
104
105
|
}
|
|
105
106
|
},
|
package/src/topology-listener.ts
CHANGED
|
@@ -4,7 +4,7 @@ import type { Logger, PeerId, Startable } from '@libp2p/interface'
|
|
|
4
4
|
|
|
5
5
|
export interface TopologyListenerInit {
|
|
6
6
|
protocol: string
|
|
7
|
-
|
|
7
|
+
logPrefix: string
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
export interface TopologyListenerEvents {
|
|
@@ -24,10 +24,10 @@ export class TopologyListener extends TypedEventEmitter<TopologyListenerEvents>
|
|
|
24
24
|
constructor (components: KadDHTComponents, init: TopologyListenerInit) {
|
|
25
25
|
super()
|
|
26
26
|
|
|
27
|
-
const { protocol,
|
|
27
|
+
const { protocol, logPrefix } = init
|
|
28
28
|
|
|
29
29
|
this.components = components
|
|
30
|
-
this.log = components.logger.forComponent(
|
|
30
|
+
this.log = components.logger.forComponent(`${logPrefix}:topology-listener`)
|
|
31
31
|
this.running = false
|
|
32
32
|
this.protocol = protocol
|
|
33
33
|
}
|
package/src/utils.ts
CHANGED
|
@@ -8,11 +8,12 @@ import { toString as uint8ArrayToString } from 'uint8arrays/to-string'
|
|
|
8
8
|
import { RECORD_KEY_PREFIX } from './constants.js'
|
|
9
9
|
import { Libp2pRecord } from './record/index.js'
|
|
10
10
|
import type { PeerId, PeerInfo } from '@libp2p/interface'
|
|
11
|
+
import type { Multiaddr } from '@multiformats/multiaddr'
|
|
11
12
|
|
|
12
13
|
// const IPNS_PREFIX = uint8ArrayFromString('/ipns/')
|
|
13
14
|
const PK_PREFIX = uint8ArrayFromString('/pk/')
|
|
14
15
|
|
|
15
|
-
export function
|
|
16
|
+
export function removePrivateAddressesMapper (peer: PeerInfo): PeerInfo {
|
|
16
17
|
return {
|
|
17
18
|
...peer,
|
|
18
19
|
multiaddrs: peer.multiaddrs.filter(multiaddr => {
|
|
@@ -48,7 +49,7 @@ export function removePrivateAddresses (peer: PeerInfo): PeerInfo {
|
|
|
48
49
|
}
|
|
49
50
|
}
|
|
50
51
|
|
|
51
|
-
export function
|
|
52
|
+
export function removePublicAddressesMapper (peer: PeerInfo): PeerInfo {
|
|
52
53
|
return {
|
|
53
54
|
...peer,
|
|
54
55
|
multiaddrs: peer.multiaddrs.filter(multiaddr => {
|
|
@@ -78,6 +79,10 @@ export function removePublicAddresses (peer: PeerInfo): PeerInfo {
|
|
|
78
79
|
}
|
|
79
80
|
}
|
|
80
81
|
|
|
82
|
+
export function passthroughMapper (info: PeerInfo): PeerInfo {
|
|
83
|
+
return info
|
|
84
|
+
}
|
|
85
|
+
|
|
81
86
|
/**
|
|
82
87
|
* Creates a DHT ID by hashing a given Uint8Array
|
|
83
88
|
*/
|
|
@@ -148,3 +153,37 @@ export function debounce (callback: () => void, wait: number = 100): () => void
|
|
|
148
153
|
timeout = setTimeout(() => { callback() }, wait)
|
|
149
154
|
}
|
|
150
155
|
}
|
|
156
|
+
|
|
157
|
+
// see https://github.com/multiformats/multiaddr/blob/master/protocols.csv
|
|
158
|
+
const P2P_CIRCUIT_CODE = 290
|
|
159
|
+
const DNS4_CODE = 54
|
|
160
|
+
const DNS6_CODE = 55
|
|
161
|
+
const DNSADDR_CODE = 56
|
|
162
|
+
const IP4_CODE = 4
|
|
163
|
+
const IP6_CODE = 41
|
|
164
|
+
|
|
165
|
+
export function multiaddrIsPublic (multiaddr: Multiaddr): boolean {
|
|
166
|
+
const tuples = multiaddr.stringTuples()
|
|
167
|
+
|
|
168
|
+
// p2p-circuit should not enable server mode
|
|
169
|
+
for (const tuple of tuples) {
|
|
170
|
+
if (tuple[0] === P2P_CIRCUIT_CODE) {
|
|
171
|
+
return false
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// dns4 or dns6 or dnsaddr
|
|
176
|
+
if (tuples[0][0] === DNS4_CODE || tuples[0][0] === DNS6_CODE || tuples[0][0] === DNSADDR_CODE) {
|
|
177
|
+
return true
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// ip4 or ip6
|
|
181
|
+
if (tuples[0][0] === IP4_CODE || tuples[0][0] === IP6_CODE) {
|
|
182
|
+
const result = isPrivateIp(`${tuples[0][1]}`)
|
|
183
|
+
const isPublic = result == null || !result
|
|
184
|
+
|
|
185
|
+
return isPublic
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
return false
|
|
189
|
+
}
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
import { contentRoutingSymbol, peerDiscoverySymbol, peerRoutingSymbol, TypedEventEmitter } from '@libp2p/interface';
|
|
2
|
-
import { DefaultKadDHT } from './kad-dht.js';
|
|
3
|
-
import type { DualKadDHT, KadDHTComponents, KadDHTInit, QueryEvent, QueryOptions } from './index.js';
|
|
4
|
-
import type { PeerDiscovery, PeerDiscoveryEvents, PeerRouting, ContentRouting, PeerId } from '@libp2p/interface';
|
|
5
|
-
import type { CID } from 'multiformats/cid';
|
|
6
|
-
/**
|
|
7
|
-
* A DHT implementation modelled after Kademlia with S/Kademlia modifications.
|
|
8
|
-
* Original implementation in go: https://github.com/libp2p/go-libp2p-kad-dht.
|
|
9
|
-
*/
|
|
10
|
-
export declare class DefaultDualKadDHT extends TypedEventEmitter<PeerDiscoveryEvents> implements DualKadDHT, PeerDiscovery {
|
|
11
|
-
readonly wan: DefaultKadDHT;
|
|
12
|
-
readonly lan: DefaultKadDHT;
|
|
13
|
-
readonly components: KadDHTComponents;
|
|
14
|
-
private readonly contentRouting;
|
|
15
|
-
private readonly peerRouting;
|
|
16
|
-
private readonly log;
|
|
17
|
-
constructor(components: KadDHTComponents, init?: KadDHTInit);
|
|
18
|
-
readonly [Symbol.toStringTag] = "@libp2p/dual-kad-dht";
|
|
19
|
-
get [contentRoutingSymbol](): ContentRouting;
|
|
20
|
-
get [peerRoutingSymbol](): PeerRouting;
|
|
21
|
-
get [peerDiscoverySymbol](): PeerDiscovery;
|
|
22
|
-
/**
|
|
23
|
-
* Is this DHT running.
|
|
24
|
-
*/
|
|
25
|
-
isStarted(): boolean;
|
|
26
|
-
/**
|
|
27
|
-
* If 'server' this node will respond to DHT queries, if 'client' this node will not
|
|
28
|
-
*/
|
|
29
|
-
getMode(): Promise<'client' | 'server'>;
|
|
30
|
-
/**
|
|
31
|
-
* If 'server' this node will respond to DHT queries, if 'client' this node will not
|
|
32
|
-
*/
|
|
33
|
-
setMode(mode: 'client' | 'server'): Promise<void>;
|
|
34
|
-
/**
|
|
35
|
-
* Start listening to incoming connections.
|
|
36
|
-
*/
|
|
37
|
-
start(): Promise<void>;
|
|
38
|
-
/**
|
|
39
|
-
* Stop accepting incoming connections and sending outgoing
|
|
40
|
-
* messages.
|
|
41
|
-
*/
|
|
42
|
-
stop(): Promise<void>;
|
|
43
|
-
/**
|
|
44
|
-
* Store the given key/value pair in the DHT
|
|
45
|
-
*/
|
|
46
|
-
put(key: Uint8Array, value: Uint8Array, options?: QueryOptions): AsyncGenerator<QueryEvent>;
|
|
47
|
-
/**
|
|
48
|
-
* Get the value that corresponds to the passed key
|
|
49
|
-
*/
|
|
50
|
-
get(key: Uint8Array, options?: QueryOptions): AsyncGenerator<QueryEvent>;
|
|
51
|
-
/**
|
|
52
|
-
* Announce to the network that we can provide given key's value
|
|
53
|
-
*/
|
|
54
|
-
provide(key: CID, options?: QueryOptions): AsyncGenerator<QueryEvent>;
|
|
55
|
-
/**
|
|
56
|
-
* Search the dht for up to `K` providers of the given CID
|
|
57
|
-
*/
|
|
58
|
-
findProviders(key: CID, options?: QueryOptions): AsyncGenerator<QueryEvent, void, undefined>;
|
|
59
|
-
/**
|
|
60
|
-
* Search for a peer with the given ID
|
|
61
|
-
*/
|
|
62
|
-
findPeer(id: PeerId, options?: QueryOptions): AsyncGenerator<QueryEvent>;
|
|
63
|
-
/**
|
|
64
|
-
* Kademlia 'node lookup' operation
|
|
65
|
-
*/
|
|
66
|
-
getClosestPeers(key: Uint8Array, options?: QueryOptions): AsyncGenerator<QueryEvent, void, undefined>;
|
|
67
|
-
refreshRoutingTable(): Promise<void>;
|
|
68
|
-
}
|
|
69
|
-
//# sourceMappingURL=dual-kad-dht.d.ts.map
|