ipfs-shipyard / js-libp2p-react-native

A demo app running js-libp2p in a React Native app
7 stars 3 forks source link

Cannot connect to circuit relay server. #5

Closed sleep9 closed 4 months ago

sleep9 commented 4 months ago

My node client/server is working and I am getting pubsub discovery messages via the circut relay server. However when I try this on ios, the circuit relay node is discovered but will not connect. I get the following output from debug.enable('libp2p:,:trace')

I think there might be something going wrong with the react-native module used for tcp.

libp2p:tcp dialing /ip4/${my_server_ip}/tcp/59835/p2p/12D3KooWDYhZLWM7XagHSf9HSZT338UN9LesS1ckQRhdnnQSSkk6 +0ms libp2p:connection-manager:dial-queue:error dial failed to /ip4/${my_server_ip}/tcp/59835/p2p/12D3KooWDYhZLWM7XagHSf9HSZT338UN9LesS1ckQRhdnnQSSkk6 +0ms [Error: Exception in HostFunction: Malformed calls from JS: field sizes are different. [[66,66,66,66,66,34],[11,11,11,11,0,0],[["error"],["close"],["connect"],["written"],[553,100,1706985960568,false]],160]]

The following is the node.js server code. ` import { createLibp2p } from 'libp2p'; import { tcp } from '@libp2p/tcp' import { mplex } from '@libp2p/mplex' import { yamux } from '@chainsafe/libp2p-yamux' import { noise } from '@chainsafe/libp2p-noise' import { circuitRelayServer} from "@libp2p/circuit-relay-v2" import { kadDHT } from '@libp2p/kad-dht' import { identify } from '@libp2p/identify' import { gossipsub } from '@chainsafe/libp2p-gossipsub' import { peerIdFromKeys } from '@libp2p/peer-id'; import bip39 from 'bip39' import {generateKeyPairFromSeed} from '@libp2p/crypto/keys' import { pubsubPeerDiscovery } from '@libp2p/pubsub-peer-discovery'

const generateRandomKeyPair = async (mnemonic = null) => {

if(mnemonic === null) mnemonic = bip39.generateMnemonic()
console.log('mnemonic: ', mnemonic);

let seed = bip39.mnemonicToSeedSync(mnemonic);
return generateKeyPairFromSeed('Ed25519',seed.slice(0, 32));

}

const createRelayNode = async (peerId)=>{ return await createLibp2p({ peerId, addresses: { listen: ['/ip4/0.0.0.0/tcp/59835'], }, transports: [ tcp() ], streamMuxers: [ yamux(),mplex() ], connectionManager: { }, connectionEncryption: [ noise() ],

    services: {
        identify: identify(),
        relay: circuitRelayServer({
            reservations: {
                maxReservations: Infinity
            },
            advertise: true
        }),
        pubsub: gossipsub({ 

            runOnTransientConnection: true,
            allowPublishToZeroPeers: true,
         })
    },
    peerDiscovery: [
        pubsubPeerDiscovery({
            interval: 1000,
            listenOnly: false
        })
    ]
  })

} const main = async () => {

let keypair = await generateRandomKeyPair(`${hidden_seed}`);
let moonId = await peerIdFromKeys(keypair.public.bytes,keypair.bytes);
const circuit = await createRelayNode(moonId); 
console.log('main: ', circuit.getMultiaddrs().toString());

} main(); ` The following is a working node circuit relay client code.

` 'use strict' import { Buffer } from 'buffer'; import { bootstrap } from '@libp2p/bootstrap' import { createLibp2p } from 'libp2p'; import { tcp } from '@libp2p/tcp' import { mplex } from '@libp2p/mplex' import { yamux } from '@chainsafe/libp2p-yamux' import { noise } from '@chainsafe/libp2p-noise' import { circuitRelayTransport } from '@libp2p/circuit-relay-v2'; import { kadDHT } from '@libp2p/kad-dht' import { identify } from '@libp2p/identify' import { gossipsub } from '@chainsafe/libp2p-gossipsub' import { pubsubPeerDiscovery } from '@libp2p/pubsub-peer-discovery'

const createNode = async (relay:string)=>{ return createLibp2p({ addresses: { listen: ['/ip4/0.0.0.0/tcp/0'] }, transports: [tcp(), circuitRelayTransport({ discoverRelays: 1 })], streamMuxers: [ yamux(),mplex() ], connectionManager: {

    },
    connectionEncryption: [
      noise()
    ],
    services: {

        pubsub: gossipsub({ 
            fallbackToFloodsub:true,
            runOnTransientConnection: true,
            allowPublishToZeroPeers: false 
        }),
        identify: identify()

    },
    peerDiscovery: [
      bootstrap({
        list: [relay]
      }),

        pubsubPeerDiscovery({
            interval: 5000,
            listenOnly: false
        })
    ]
  })

}

const main = async () => {

const topic = 'news'
let relayAddr = `/ip4/${my_server_ip}/tcp/59835/p2p/12D3KooWDYhZLWM7XagHSf9HSZT338UN9LesS1ckQRhdnnQSSkk6`;

const node1 = await createNode(relayAddr);
const node2 = await createNode(relayAddr);

console.log('node: ', node1.peerId.toString());
node1.addEventListener('peer:discovery', (evt) => console.log('Node1: Discovered:', evt.detail.id.toString()))
node2.addEventListener('peer:discovery', (evt) => console.log('Node2: Discovered:', evt.detail.id.toString()))

node1.services.pubsub.subscribe(topic)

node2.addEventListener("peer:connect", (_evt) => {
    console.log(`Node2: Connected to ${_evt.detail.toString()}`)
})

node1.addEventListener("peer:connect", (_evt) => {
    console.log(`Node1: Connected to ${_evt.detail.toString()}`)
})

node1.services.pubsub.addEventListener('message', (message:any) => {
    console.log(`${message.detail.topic}:`, message.detail.data.toString())
})

setInterval(() => {

    const node1Peers = node1.services.pubsub.getSubscribers(topic);
    const node2Peers = node2.services.pubsub.getSubscribers(topic);

    console.log('node1peers: ', node1Peers)
    console.log('node2peers: ', node2Peers)

    node2.services.pubsub.publish(topic, Buffer.from('bird bird bird')).catch(err => {
        console.error(err)
    })

}, 10000)

} main(); `

The following is the App client code. ` import './globals.js' import { StatusBar } from 'expo-status-bar' import { StyleSheet, Text, View } from 'react-native' import { useState, useEffect } from 'react' import { createLibp2p } from 'libp2p' import { bootstrap } from '@libp2p/bootstrap' import { noise } from '@chainsafe/libp2p-noise' import { yamux } from '@chainsafe/libp2p-yamux' import { mplex } from '@libp2p/mplex' import { identify } from '@libp2p/identify' import { circuitRelayTransport } from '@libp2p/circuit-relay-v2' import { tcp } from '@libp2p/tcp' import debug from 'debug' import { gossipsub } from '@chainsafe/libp2p-gossipsub' // https://github.com/ChainSafe/js-libp2p-gossipsub import { pubsubPeerDiscovery } from '@libp2p/pubsub-peer-discovery'

debug.enable('libp2p:,:trace')

const useConstructor = (callBack = () => {}) => { const [hasBeenCalled, setHasBeenCalled] = useState(false); if (hasBeenCalled) return; callBack(); setHasBeenCalled(true); }

export default function App () {

async function createNode(relay) { return createLibp2p({ transports: [ tcp(), circuitRelayTransport({ discoverRelays: 1 }), ], connectionManager: {

      },
      connectionEncryption: [
        noise()
      ],
      streamMuxers: [
        yamux(),mplex()
      ],
      peerDiscovery: [
        bootstrap({
          list: relay
        }),
        pubsubPeerDiscovery({
          interval: 5000,
          listenOnly: false
        }),
      ],
      services: {

        identify: identify(),
        pubsub: gossipsub({ 
          runOnTransientConnection: true,
          allowPublishToZeroPeers: false 
        }),
      }
    })
  }

useConstructor(async () => {

const topic = 'news'

console.log('useConstructor');

let relayAddrs  = [
  `/ip4/${my_server_ip}/tcp/59835/p2p/12D3KooWDYhZLWM7XagHSf9HSZT338UN9LesS1ckQRhdnnQSSkk6`
];

const node = await createNode(relayAddrs);

node.services.pubsub.subscribe(topic);

node.services.pubsub.addEventListener('message', (message) => {
  console.log(`${message.detail.topic}:`, message.detail.data.toString())
})

node.addEventListener('peer:discovery', async (evt) => { 

  const node1Peers = node.services.pubsub.getSubscribers(topic);
  console.log('Node: Discovered:', evt.detail.id.toString())

});

node.addEventListener("peer:connect", (_evt) => { 

  console.log(`Node: Connected to ${_evt.detail.toString()}`)

});

const node1Peers = node.services.pubsub.getSubscribers(topic);

});

} `

sleep9 commented 4 months ago

Switching to websockets transport worked.