Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot use kad-dht for contentRouting query #2661

Open
wlynxg opened this issue Aug 14, 2024 · 4 comments
Open

Cannot use kad-dht for contentRouting query #2661

wlynxg opened this issue Aug 14, 2024 · 4 comments
Labels
need/author-input Needs input from the original author

Comments

@wlynxg
Copy link
Contributor

wlynxg commented Aug 14, 2024

  • Version:
"@chainsafe/libp2p-noise": "^15.1.1",
"@chainsafe/libp2p-yamux": "^6.0.2",
"@libp2p/bootstrap": "^10.1.4",
"@libp2p/circuit-relay-v2": "^1.1.4",
"@libp2p/identify": "^2.1.4",
"@libp2p/kad-dht": "^12.1.4",
"@libp2p/mplex": "^10.1.4",
"@libp2p/websockets": "^8.1.4",
"cid": "github:multiformats/cid",
"libp2p": "^1.8.3",
"multiformats": "^13.2.2"
  • Platform:
Linux ubuntu 5.15.0-60-generic #66-Ubuntu SMP Fri Jan 20 14:29:49 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
  • Subsystem:

Severity: High

Description:

  • "What you did": I created two nodes, one node executed provide and the other node executed findProvider, and both nodes used the same CID.
  • "What happened": The operation failed.
  • " What you expected to happen": The operation was successfully performed

Steps to reproduce the error:

import {createLibp2p} from "libp2p";
import {webSockets} from "@libp2p/websockets";
import * as filters from "@libp2p/websockets/filters";
import {bootstrap} from "@libp2p/bootstrap";
import {kadDHT} from "@libp2p/kad-dht";
import {circuitRelayTransport} from "@libp2p/circuit-relay-v2";
import { mplex } from '@libp2p/mplex';
import {identify} from "@libp2p/identify";

import {yamux} from "@chainsafe/libp2p-yamux";
import {noise} from "@chainsafe/libp2p-noise";

import {CID} from "multiformats/cid";
import {sha256} from "multiformats/hashes/sha2";
import * as raw from "multiformats/codecs/raw";

const createNode = async () => {
    return await createLibp2p({
        transports: [
            webSockets({filter: filters.all}),
            circuitRelayTransport({
                discoverRelays: 10,
            }),
        ],
        streamMuxers: [yamux(), mplex()],
        connectionEncryption: [noise()],
        peerDiscovery: [
            bootstrap({
                list: [
                    "/dnsaddr/bootstrap.libp2p.io/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN",
                    "/dnsaddr/bootstrap.libp2p.io/p2p/QmQCU2EcMqAqQPR2i9bChDtGNJchTbq5TbXJJ16u19uLTa",
                    "/dnsaddr/bootstrap.libp2p.io/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb",
                    "/dnsaddr/bootstrap.libp2p.io/p2p/QmcZf59bWwK5XFi76CZX8cbJ4BhTzzA3gU1ZjYZcYW3dwt",
                    "/ip4/104.131.131.82/tcp/4001/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ",
                    "/ip4/104.131.131.82/udp/4001/quic/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ",
                    "/ip4/104.131.131.82/tcp/4001/ipfs/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ",
                    "/dnsaddr/bootstrap.libp2p.io/ipfs/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN",
                    "/dnsaddr/bootstrap.libp2p.io/ipfs/QmQCU2EcMqAqQPR2i9bChDtGNJchTbq5TbXJJ16u19uLTa",
                ],
            }),],
        services: {
            identify: identify(),
            dht: kadDHT({
                clientMode: true,
                maxInboundStreams: 100,
                maxOutboundStreams: 100,
                querySelfInterval: 10,
            }),
        }
    })
}


let node1 = await createNode();
let node2 = await createNode();

await node1.start();
await node2.start();

console.log("node1 id",node1.peerId);
console.log("node2 id",node2.peerId);

await node1.services.dht.refreshRoutingTable();
await node2.services.dht.refreshRoutingTable();

const addr = "js-libp2p-dht-test";
const cid = CID.create(1, raw.code, await sha256.digest(new TextEncoder().encode(addr)));

await node2.contentRouting.provide(cid);


while (true) {
    try {
        for await (const provider of node1.contentRouting.findProviders(cid,{
            useNetwork:true,
            useCache:true,
        })) {
            console.log(provider)
        }

        console.log("Waiting for the next round of query...")
        await new Promise(resolve => setTimeout(resolve, 5000));
    } catch (error) {
        console.error("Error occurred while finding provider:", error);
        await new Promise(resolve => setTimeout(resolve, 5000));
    }
}

Output:

root@ubuntu:~/jsp2p# node client.js 
node1 id PeerId(12D3KooWFXcg3a8Hi6mEpeqaH2tTrWg44DbPyHGRCMrGDqfAFSrt)
node2 id PeerId(12D3KooWSNV1Cksmn4YTzz7kfm1FdRMXSX2mBV162PRAuccnPQ92)
Waiting for the next round of query...
Waiting for the next round of query...
Waiting for the next round of query...
Waiting for the next round of query...
Waiting for the next round of query...
Waiting for the next round of query...
...
@wlynxg wlynxg added the need/triage Needs initial labeling and prioritization label Aug 14, 2024
@dozyio
Copy link
Contributor

dozyio commented Feb 20, 2025

Few issues in your sample code, but the below works

  • your node needs to publicly accessible to be able to provide, so added addresses
  • your dht client needs to be running in server mode so that it can provide, so added clientMode: false
import { createLibp2p } from "libp2p";
import { webSockets } from "@libp2p/websockets";
import { tcp } from "@libp2p/tcp";
import * as filters from "@libp2p/websockets/filters";
import { bootstrap } from "@libp2p/bootstrap";
import { kadDHT } from "@libp2p/kad-dht";
import { circuitRelayTransport } from "@libp2p/circuit-relay-v2";
import { identify, identifyPush } from "@libp2p/identify";

import { yamux } from "@chainsafe/libp2p-yamux";
import { noise } from "@chainsafe/libp2p-noise";

import { CID } from "multiformats/cid";
import { sha256 } from "multiformats/hashes/sha2";
import * as raw from "multiformats/codecs/raw";

const createNode = async () => {
  return await createLibp2p({
    addresses: {
      listen: [
        "/p2p-circuit"
      ],
    },
    transports: [
      webSockets({ filter: filters.all }),
      circuitRelayTransport(),
      tcp(),
    ],
    streamMuxers: [yamux()],
    connectionEncrypters: [noise()],
    peerDiscovery: [
      bootstrap({
        list: [
          "/dnsaddr/bootstrap.libp2p.io/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN",
          "/dnsaddr/bootstrap.libp2p.io/p2p/QmQCU2EcMqAqQPR2i9bChDtGNJchTbq5TbXJJ16u19uLTa",
          "/dnsaddr/bootstrap.libp2p.io/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb",
          "/dnsaddr/bootstrap.libp2p.io/p2p/QmcZf59bWwK5XFi76CZX8cbJ4BhTzzA3gU1ZjYZcYW3dwt",
          "/ip4/104.131.131.82/tcp/4001/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ",
        ],
      }),],
    services: {
      identify: identify(),
      identifyPush: identifyPush(),
      dht: kadDHT({
        clientMode: true,
        querySelfInterval: 10
      }),
    },
  })
}


let node1 = await createNode();
let node2 = await createNode();

await node1.start();
await node2.start();

console.log("node1 id",node1.peerId);
console.log("node2 id",node2.peerId);

// wait to get p2p-circuit connections
await new Promise(resolve => setTimeout(resolve, 5000))

const addr = "js-libp2p-dht-test";
const cid = CID.create(1, raw.code, await sha256.digest(new TextEncoder().encode(addr)));
console.log("providing to network, will take minute or so...")
await node2.contentRouting.provide(cid, { useNetwork: true, useCache: true })
console.log("provide done by node2")

console.log("node1 looking for provider...")
try {
  for await (const provider of node1.contentRouting.findProviders(cid, {
    useNetwork: true,
    useCache: true,
  })) {
    console.log(provider)
  }
} catch (error) {
  console.error("Error occurred while finding provider:", error);
}

@achingbrain achingbrain added need/author-input Needs input from the original author and removed need/triage Needs initial labeling and prioritization labels Feb 21, 2025
Copy link
Contributor

Oops, seems like we needed more information for this issue, please comment with more details or this issue will be closed in 7 days.

@2color
Copy link
Contributor

2color commented Feb 28, 2025

your dht client needs to be running in server mode so that it can provide, so added clientMode: false

I'm pretty sure you can provide without being a server. Being a DHT server is more about whether you're publicly reachable.

@dozyio
Copy link
Contributor

dozyio commented Feb 28, 2025

your dht client needs to be running in server mode so that it can provide, so added clientMode: false

I'm pretty sure you can provide without being a server. Being a DHT server is more about whether you're publicly reachable.

Thanks @2color - I was always under the assumption that you need to be running as a DHT server to be able provide CID's to the network. Edited the above.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
need/author-input Needs input from the original author
Projects
None yet
Development

No branches or pull requests

4 participants