Need help setting up Kad DHT using nodejs #2503
Unanswered
muzahidul-islam-sbu
asked this question in
Q&A
Replies: 1 comment
-
Two nodes isn't really enough to make a DHT, so to make the example work you have to take some shortcuts. Ordinarily the steps you take when connecting to a DHT are:
Next is configuring the DHT properly: import { kadDHT, removePublicAddressesMapper } from '@libp2p/kad-dht'
kadDHT: kadDHT({
// must be in server mode to accept records from peers
// - normally this is auto-detected based on having public addresses but here
// we are local-only so just enable server mode
clientMode: false,
// use a custom protocol to ensure our local nodes are actually doing the work
protocol: '/ipfs/lan/kad/1.0.0',
// remove any public addresses from peer records because we are LAN-only
peerInfoMapper: removePublicAddressesMapper,
// ensure we can publish/resolve records with a custom prefix
// if validators/selectors for the key prefix are missing the records will be ignored
validators: {
'my-prefix': async (key, value) => {
// do nothing, it's valid
}
},
// select a record when there are multiples resolved for the same key
selectors: {
'my-prefix': (key, records) => {
// take the first record
return 0
}
}
}) Finally put it all together. Because we aren't bootstrapping to any peers to start filling out our routing table, we'll just dial whatever peers are discovered by mDNS.
{
"type": "module",
"dependencies": {
"@chainsafe/libp2p-noise": "^16.0.0",
"@chainsafe/libp2p-yamux": "^7.0.1",
"@libp2p/identify": "^3.0.13",
"@libp2p/kad-dht": "^14.1.4",
"@libp2p/mdns": "^11.0.14",
"@libp2p/ping": "^2.0.13",
"@libp2p/tcp": "^10.0.14"
}
}
import { noise } from '@chainsafe/libp2p-noise'
import { yamux } from '@chainsafe/libp2p-yamux'
import { identify, identifyPush } from '@libp2p/identify'
import { kadDHT, removePublicAddressesMapper } from '@libp2p/kad-dht'
import { tcp } from '@libp2p/tcp'
import { createLibp2p } from 'libp2p'
import { mdns } from '@libp2p/mdns'
import { ping } from '@libp2p/ping'
const prefix = 'my-prefix'
const node = await createLibp2p({
addresses: {
listen: ['/ip4/0.0.0.0/tcp/0']
},
transports: [tcp()],
streamMuxers: [yamux()],
connectionEncrypters: [noise()],
peerDiscovery: [
mdns()
],
services: {
kadDHT: kadDHT({
clientMode: false,
protocol: '/ipfs/lan/kad/1.0.0',
peerInfoMapper: removePublicAddressesMapper,
validators: {
[prefix]: async (key, value) => {
// do nothing, it's valid
}
},
selectors: {
[prefix]: (key, records) => {
// take the first record
return 0
}
}
}),
identify: identify(),
identifyPush: identifyPush(),
ping: ping()
}
})
node.addEventListener('peer:connect', (evt) => {
const peerId = evt.detail
console.log('Connection established to:', peerId.toString()) // Emitted when a peer has been found
})
node.addEventListener('peer:discovery', async (evt) => {
const peerInfo = evt.detail
console.log('Discovered:', peerInfo.id.toString())
// we aren't bootstrapping to an existing network so just dial any peers
// that are discovered
try {
await node.dial(peerInfo.multiaddrs)
} catch {}
const key = `/${prefix}/hello`
const value = 'world'
const keyUint8Array = Buffer.from(key)
const valueUint8Array = Buffer.from(value)
console.info('putting value')
await node.contentRouting.put(keyUint8Array, valueUint8Array)
console.info('put value')
})
console.info('Publisher:', node.peerId.toString())
import { noise } from '@chainsafe/libp2p-noise'
import { yamux } from '@chainsafe/libp2p-yamux'
import { identify, identifyPush } from '@libp2p/identify'
import { kadDHT, removePublicAddressesMapper } from '@libp2p/kad-dht'
import { tcp } from '@libp2p/tcp'
import { createLibp2p } from 'libp2p'
import { mdns } from '@libp2p/mdns'
import { ping } from '@libp2p/ping'
const prefix = 'my-prefix'
const node = await createLibp2p({
addresses: {
listen: ['/ip4/0.0.0.0/tcp/0']
},
transports: [tcp()],
streamMuxers: [yamux()],
connectionEncrypters: [noise()],
peerDiscovery: [
mdns()
],
services: {
kadDHT: kadDHT({
clientMode: false,
protocol: '/ipfs/lan/kad/1.0.0',
peerInfoMapper: removePublicAddressesMapper,
validators: {
[prefix]: async (key, value) => {
// do nothing, it's valid
}
},
selectors: {
[prefix]: (key, records) => {
// take the first record
return 0
}
}
}),
identify: identify(),
identifyPush: identifyPush(),
ping: ping()
}
})
node.addEventListener('peer:connect', (evt) => {
const peerId = evt.detail
console.log('Connection established to:', peerId.toString()) // Emitted when a peer has been found
})
node.addEventListener('peer:discovery', async (evt) => {
const peerInfo = evt.detail
console.log('Discovered:', peerInfo.id.toString())
// we aren't bootstrapping to an existing network so just dial any peers
// that are discovered
try {
await node.dial(peerInfo.multiaddrs)
} catch {}
const key = `/${prefix}/hello`
const keyUint8Array = Buffer.from(key)
console.info('get value')
const value = await node.contentRouting.get(keyUint8Array)
console.info(`got value "${value}"`)
})
console.info('Resolver:', node.peerId.toString()) Start the publisher, then start the resolver. % node ./publisher.js
Publisher: 12D3KooWGT2Du2GGQ1vtescifyqzg5RxZWiuTEDxcxqK3jdxMCJ5
Discovered: 12D3KooWGSWBiG1am6iwChjoCiK8C8apEe9jjsVoK1aLZU8W3d7W
Connection established to: 12D3KooWGSWBiG1am6iwChjoCiK8C8apEe9jjsVoK1aLZU8W3d7W
putting value
put value % node resolver.js
Resolver: 12D3KooWGSWBiG1am6iwChjoCiK8C8apEe9jjsVoK1aLZU8W3d7W
Discovered: 12D3KooWGT2Du2GGQ1vtescifyqzg5RxZWiuTEDxcxqK3jdxMCJ5
Connection established to: 12D3KooWGT2Du2GGQ1vtescifyqzg5RxZWiuTEDxcxqK3jdxMCJ5
get value
got value "world" |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
I'm trying to set up a Kad DHT for local peers (will move to remote peers later), but am having trouble with the DHT replicating the keys and values.
The goal is that I want to start a peer node in one process, and another peer node in a different process. Then I want to put a key value pair in node 1 (for example key = 'hello', value = 'world), and I then want to retrieve this value in node 2.
Currently, I can put and get to the DHT fine in a single node, and the nodes connect to each other using mdns, but I can't copy the DHT key/values between two nodes. Here is my code:
Beta Was this translation helpful? Give feedback.
All reactions