Skip to content

Kademlia peer discovery fails despite passing .with_known_addresses(addrs) in litep2p config #556

Description

@jsdw

If I instantiate litep2p like this:

// --- Kademlia ---
let kad_protocol = ProtocolName::from(format!("/{}/kad", genesis_hash_hex));
let (kad_config, mut kad_handle) = kademlia::ConfigBuilder::new()
    .with_protocol_names(vec![kad_protocol])
    .build();

// ...

    
// --- Build litep2p ---
let config = ConfigBuilder::new()
    .with_tcp(TcpConfig {
        listen_addresses: vec!["/ip4/0.0.0.0/tcp/0".parse().unwrap()],
        ..Default::default()
    })
    .with_libp2p_kademlia(kad_config)
    .with_notification_protocol(ba_config)
    .with_notification_protocol(grandpa_config)
    .with_request_response_protocol(warp_config)
    .with_request_response_protocol(sync_config)
    .with_known_addresses(bootnodes.clone().into_iter())
    .build();

And then wait to connect to some nodes, and then call:

kad_handle.find_node(PeerId::random()).await;

The FIND NODE query consistently fails. The kademlia logs looks like:

2026-03-10T11:50:04.462615Z DEBUG litep2p::ipfs::kademlia: starting kademlia event loop
2026-03-10T11:50:04.462682Z DEBUG litep2p::ipfs::kademlia: starting `FIND_NODE` query peer=PeerId("1AfxHqzipQLx2CsWZedwTfvg8QtJXEQ4vvog4B5v4AwCsk") query=QueryId(0)
2026-03-10T11:50:04.462777Z DEBUG litep2p::ipfs::kademlia::query: start `FIND_NODE` query query_id=QueryId(0) target=PeerId("1AfxHqzipQLx2CsWZedwTfvg8QtJXEQ4vvog4B5v4AwCsk") num_peers=0
2026-03-10T11:50:04.462860Z TRACE litep2p::ipfs::kademlia::query::find_node: query finished query=QueryId(0) pending=0 candidates=0
2026-03-10T11:50:04.462895Z DEBUG litep2p::ipfs::kademlia: query failed query=QueryId(0)
2026-03-10T11:50:04.931158Z TRACE litep2p::ipfs::kademlia: connection established peer=PeerId("12D3KooWS9ZcvRxyzrSf6p63QfTCWs12nLoNKhGux865crgxVA4H")
2026-03-10T11:50:04.931254Z TRACE litep2p::ipfs::kademlia::routing_table: on connection established key=Key { preimage: PeerId("12D3KooWS9ZcvRxyzrSf6p63QfTCWs12nLoNKhGux865crgxVA4H"), bytes: KeyBytes([83, 223, 240, 103, 46, 63, 164, 37, 193, 105, 137, 73, 153, 154, 190, 140, 114, 190, 75, 113, 53, 167, 190, 22, 117, 16, 205, 89, 8, 219, 231, 63]) } endpoint=Dialer { address: "/dns/boot-node.helikon.io/tcp/7070", connection_id: ConnectionId(2) }
2026-03-10T11:50:05.053687Z TRACE litep2p::ipfs::kademlia: connection established peer=PeerId("12D3KooWSz8r2WyCdsfWHgPyvD8GKQdJ1UAiRmrcrs8sQB3fe2KU")
2026-03-10T11:50:05.053887Z TRACE litep2p::ipfs::kademlia::routing_table: on connection established key=Key { preimage: PeerId("12D3KooWSz8r2WyCdsfWHgPyvD8GKQdJ1UAiRmrcrs8sQB3fe2KU"), bytes: KeyBytes([225, 110, 10, 19, 12, 50, 107, 79, 36, 31, 230, 219, 78, 10, 96, 142, 99, 32, 171, 40, 247, 193, 173, 74, 240, 162, 13, 137, 91, 221, 127, 4]) } endpoint=Dialer { address: "/dns/polkadot-bootnode-0.polkadot.io/tcp/30333", connection_id: ConnectionId(0) }
2026-03-10T11:50:14.498953Z DEBUG litep2p::ipfs::kademlia: starting `FIND_NODE` query peer=PeerId("1AY9sD5jc98AxF7zCmhA2yDapdV5AJc2BbNtEpE9aCcwLW") query=QueryId(1)
2026-03-10T11:50:14.499105Z DEBUG litep2p::ipfs::kademlia::query: start `FIND_NODE` query query_id=QueryId(1) target=PeerId("1AY9sD5jc98AxF7zCmhA2yDapdV5AJc2BbNtEpE9aCcwLW") num_peers=0
2026-03-10T11:50:14.499167Z TRACE litep2p::ipfs::kademlia::query::find_node: query finished query=QueryId(1) pending=0 candidates=0
2026-03-10T11:50:14.499183Z DEBUG litep2p::ipfs::kademlia: query failed query=QueryId(1)
2026-03-10T11:50:14.499201Z TRACE litep2p::ipfs::kademlia: failed to dial peer peer=PeerId("12D3KooWKT4ZHNxXH4icMjdrv7EwWBkfbz5duxE5sdJKKeWFYi5n") addresses=["/dns/boot.stake.plus/tcp/30333/p2p/12D3KooWKT4ZHNxXH4icMjdrv7EwWBkfbz5duxE5sdJKKeWFYi5n"]
2026-03-10T11:50:14.499248Z TRACE litep2p::ipfs::kademlia::routing_table: on dial failure key=Key { preimage: PeerId("12D3KooWKT4ZHNxXH4icMjdrv7EwWBkfbz5duxE5sdJKKeWFYi5n"), bytes: KeyBytes([81, 82, 89, 99, 244, 128, 26, 239, 7, 167, 165, 199, 100, 205, 100, 171, 98, 122, 249, 69, 40, 229, 226, 24, 193, 119, 129, 188, 73, 10, 201, 117]) } addresses=["/dns/boot.stake.plus/tcp/30333/p2p/12D3KooWKT4ZHNxXH4icMjdrv7EwWBkfbz5duxE5sdJKKeWFYi5n"]
2026-03-10T11:50:14.833020Z TRACE litep2p::ipfs::kademlia: connection established peer=PeerId("12D3KooWHJBMZgt7ymAdTRtadPcGXpJw79vBGe8z53r9JMkZW7Ha")
2026-03-10T11:50:14.833073Z TRACE litep2p::ipfs::kademlia::routing_table: on connection established key=Key { preimage: PeerId("12D3KooWHJBMZgt7ymAdTRtadPcGXpJw79vBGe8z53r9JMkZW7Ha"), bytes: KeyBytes([233, 121, 85, 104, 93, 234, 82, 199, 3, 213, 14, 187, 252, 74, 70, 164, 146, 84, 30, 42, 252, 60, 75, 34, 17, 184, 242, 78, 225, 219, 199, 233]) } endpoint=Dialer { address: "/dns/polkadot-bootnode.turboflakes.io/tcp/30300", connection_id: ConnectionId(3) }
2026-03-10T11:50:34.500610Z DEBUG litep2p::ipfs::kademlia: starting `FIND_NODE` query peer=PeerId("1AWTVvEVPR7EA2JhsBe395JC7F3AXg8DDbFqFQPNHELNqz") query=QueryId(2)
2026-03-10T11:50:34.500761Z DEBUG litep2p::ipfs::kademlia::query: start `FIND_NODE` query query_id=QueryId(2) target=PeerId("1AWTVvEVPR7EA2JhsBe395JC7F3AXg8DDbFqFQPNHELNqz") num_peers=0
2026-03-10T11:50:34.500844Z TRACE litep2p::ipfs::kademlia::query::find_node: query finished query=QueryId(2) pending=0 candidates=0
2026-03-10T11:50:34.500861Z DEBUG litep2p::ipfs::kademlia: query failed query=QueryId(2)

If I then modify the kademlia config to also provide it a list of known addresses, ie:

let kad_protocol = ProtocolName::from(format!("/{}/kad", genesis_hash_hex));
let (kad_config, mut kad_handle) = kademlia::ConfigBuilder::new()
    .with_protocol_names(vec![kad_protocol])
    .with_known_peers(bootnodes.clone().into_iter().collect())
    .build();

Then everything works as expected and peers are discovered.

My hopes would be that:

  1. The addresses passed to the litep2p config via .with_known_addresses(bootnodes.clone().into_iter()) should be forwarded on / used by Kademlia as needed, or
  2. If I don't add any known addresses anywhere, then when I dial peers like litep2p.dial_address(addr).await, then those addresses should be usable if I later do a kademlia query.

I am a litep2p newbie though so I could well be holding things wrong :)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions