LibP2P: Connecting Rust and JS

Hi! I’m trying to connect libp2p in Rust and JavaScript, but I’m having troubles doing that.

Here’s the code https://github.com/folex/libp2p-multilang

What I’m doing in rust is basically:

let transport = libp2p::build_development_transport(local_key);
let behaviour = Ping::new(PingConfig::new().with_keep_alive(true));
let mut swarm = Swarm::new(transport, behaviour, local_peer_id.clone());
Swarm::listen_on(&mut swarm, addr.clone()).unwrap();

And JS:

class MyBundle extends libp2p {
  constructor(_options) {
    const defaults = {
  modules: {
    transport: [TCP],
    streamMuxer: [Mplex],
    connEncryption: [SECIO],
  },
    };

    super(defaultsDeep(_options, defaults))
  }
}

RUST_PEER = "/ip4/127.0.0.1/tcp/30000/p2p/12D3KooWSwNXzEeGjgwEocRJBzbdoDqxbz3LdrwgSuKmKeGvbM4G";
node = new MyBundle(...);
node.dial(RUST_PEER, cb)

Both snippets are heavily simplified, full versions can be seen in the repo

And then there are two different cases:

  1. If I use PeerID QmTESkr2vWDCKqiHVsyvf4iRQCBgvNDqBJ6P3yTTDb6haw, then JS says dialed to the wrong peer, Ids do not match
  2. If I use PeerID that JS derives from Rust’s public key 12D3KooWSwNXzEeGjgwEocRJBzbdoDqxbz3LdrwgSuKmKeGvbM4G, then SecIO handshake hangs.

Tail logs from Rust hanging:

[2019-12-23T15:53:25Z TRACE libp2p_secio::handshake] sending exchange to remote
[2019-12-23T15:53:25Z TRACE tokio_io::framed_read] attempting to decode a frame
[2019-12-23T15:53:45Z DEBUG libp2p_core::transport::timeout] timeout elapsed for connection
[2019-12-23T15:53:45Z DEBUG libp2p_tcp] Dropped TCP connection to V4(127.0.0.1:49760)

Tail logs from JS hanging:

  libp2p:secio 1. propose - start +0ms
  libp2p:secio 1. propose - writing proposal +0ms
  libp2p:secio 1. propose - reading proposal <Buffer 0a 10 e4 45 11 3d 27 24 1c 03 a9 7b 79 ff e8 ef d1 cc 12 24 08 01 12 20 fe 62 28 54 de 53 5d 1a 5d a2 b8 7d fb 93 2d b3 b2 37 6f fc d2 43 ce cd 75 0b ... > +2ms
  libp2p:secio 1.1 identify +0ms
  libp2p:secio 1.1 identify - QmSAmTQf4nKgQypvNmq2XFvDFhnu4k8j1Jqo2wqUiaivff - identified remote peer as 12D3KooWSwNXzEeGjgwEocRJBzbdoDqxbz3LdrwgSuKmKeGvbM4G +1ms
  libp2p:secio 1.2 selection +0ms
  libp2p:secio 1. propose - finish +2ms
  libp2p:secio 2. exchange - start +0ms
  libp2p:secio 2. exchange - writing exchange +0ms

Full logs can be found in README of in the repo https://github.com/folex/libp2p-multilang

To reproduce, simply clone repo and:

  1. In one terminal, execute make rust
  2. In another one execute make js-rust-peerid for first case, and make js for the second case

So my question is, is it possible to connect libp2p Rust + JS? If so, could you please point where I’m doing that wrong?

Thanks in advance!

I’ve managed to connect Rust and JS via floodsub (see floodsub branch for code).

Seems like issue was at least twofold:

  1. js-libp2p hangs on secio handshake in crypto.js :: createExchange crypto.js#L48 as of version 0.11.1
  2. No compatible protocols was enabled, fixed by enabling Identify protocol

Seems like js-libp2p-secio is updated to 0.12.1 (but not published to npm yet), maybe this fill fix the freeze. In the meantime, I’ve patched it directly: github.com/folex/libp2p-multilang/blob/floodsub/js/node_modules/libp2p-secio/src/handshake/crypto.js#L57-L69 (sorry it’s not a link, I can’t post more than 2 links).

However, I’m still not sure how to pass PeerID between Rust and JS.

Also peers automatically disconnect after some time, I haven’t figured out the reasons, but I guess it’s because JS doesn’t send any ping-pongs.