GithubHelp home page GithubHelp logo

how to create my own bootstrap peer like DefaultBootstrapPeers in github.com/libp2p/go-libp2p-kad-dht/dht_bootstrap.go:16 about go-libp2p-examples HOT 8 OPEN

libp2p avatar libp2p commented on July 23, 2024
how to create my own bootstrap peer like DefaultBootstrapPeers in github.com/libp2p/go-libp2p-kad-dht/dht_bootstrap.go:16

from go-libp2p-examples.

Comments (8)

maimai88 avatar maimai88 commented on July 23, 2024 1

@maimai88 Relay dials are enabled by default but you need to connect it to a node which acts as a relay. You can do that by spawning a new node (on a publicly accessible ip:port) and passing circuit.OptHop in Libp2p.Option.

Now connect all your nodes (A -> R, B -> R) to this relay node. Now you can dial A -> B and it would use the relay node if it could not dial directly.


Thanks sir @upperwal
Imitation relay example

Node R

Node_JP is a server in Japan that has a separate public IP.I use it as a relay node.

deploy code:

package main

import (
	"context"
	"flag"
	"fmt"

	"github.com/libp2p/go-libp2p"
	circuit "github.com/libp2p/go-libp2p-circuit"
)

func main() {

	listenPort := flag.Int("l", 3000, "wait for incoming connections")
	flag.Parse()

	// Tell the host to relay connections for other peers (The ability to *use*
	// a relay vs the ability to *be* a relay)
	h2, err := libp2p.New(
		context.Background(),
		libp2p.ListenAddrStrings(fmt.Sprintf("/ip4/0.0.0.0/tcp/%d", *listenPort)),
		libp2p.EnableRelay(circuit.OptHop))
	if err != nil {
		panic(err)
	}

	for _, ips := range h2.Addrs() {
		fmt.Printf("%s/p2p/%s\n", ips, h2.ID())
	}

	select {}

}

Node A

deploy code:

package main

import (
	"context"
	"flag"
	"fmt"

	"github.com/libp2p/go-libp2p-core/network"
	"github.com/libp2p/go-libp2p-core/peer"

	"github.com/libp2p/go-libp2p"
	"github.com/multiformats/go-multiaddr"
	ma "github.com/multiformats/go-multiaddr"
)

func addr2info(addrStr string) (*peer.AddrInfo, error) {

	addr, err := multiaddr.NewMultiaddr(addrStr)
	if err != nil {
		panic(err)
	}

	//peerstore.InfoFromP2pAddr(addr)

	return peer.AddrInfoFromP2pAddr(addr)
}

func main() {

	var relayHost string
	var dialID string

	flag.StringVar(&relayHost, "relay", "", "relay addr")
	flag.StringVar(&dialID, "dial", "", "dial Node ID")

	flag.Parse()

	relayAddrInfo, err := addr2info(relayHost)

	// Zero out the listen addresses for the host, so it can only communicate
	// via p2p-circuit for our example
	h3, err := libp2p.New(context.Background(), libp2p.ListenAddrs(), libp2p.EnableRelay())
	if err != nil {
		panic(err)
	}

	if err := h3.Connect(context.Background(), *relayAddrInfo); err != nil {
		panic(err)
	}

	// Now, to test things, let's set up a protocol handler on h3
	h3.SetStreamHandler("/cats", func(s network.Stream) {
		fmt.Println("Meow! It worked!")
		s.Close()
	})

	// Creates a relay address
	relayaddr, err := ma.NewMultiaddr("/p2p-circuit/p2p/" + h3.ID().Pretty())
	if err != nil {
		panic(err)
	}

	fmt.Println(relayaddr)
	fmt.Println(h3.ID())

	select {}
}

Node B

package main

import (
	"context"
	"flag"
	"fmt"

	swarm "github.com/libp2p/go-libp2p-swarm"

	"github.com/libp2p/go-libp2p-core/peer"

	"github.com/multiformats/go-multiaddr"
	ma "github.com/multiformats/go-multiaddr"

	"github.com/libp2p/go-libp2p"
	circuit "github.com/libp2p/go-libp2p-circuit"
)

func addr2info(addrStr string) (*peer.AddrInfo, error) {

	addr, err := multiaddr.NewMultiaddr(addrStr)
	if err != nil {
		panic(err)
	}

	//peerstore.InfoFromP2pAddr(addr)

	return peer.AddrInfoFromP2pAddr(addr)
}

func main() {

	var relayHost string
	var dialID string

	flag.StringVar(&relayHost, "relay", "", "relay addr")
	flag.StringVar(&dialID, "dial", "", "dial Node ID")

	flag.Parse()

	relayAddrInfo, err := addr2info(relayHost)

	h1, err := libp2p.New(context.Background(), libp2p.EnableRelay(circuit.OptDiscovery))
	if err != nil {
		panic(err)
	}

	if err := h1.Connect(context.Background(), *relayAddrInfo); err != nil {
		panic(err)
	}

	dialNodeID, err := peer.IDB58Decode(dialID)

	if err != nil {
		panic(err)
	}

	_, err = h1.NewStream(context.Background(), dialNodeID, "/cats")
	if err == nil {
		fmt.Println("Didnt actually expect to get a stream here. What happened?")
		return
	}
	fmt.Println("Okay, no connection from h1 to h3: ", err)
	fmt.Println("Just as we suspected")

	h1.Network().(*swarm.Swarm).Backoff().Clear(dialNodeID)

	relayaddr, err := ma.NewMultiaddr("/p2p-circuit/p2p/" + dialNodeID.Pretty())
	if err != nil {
		panic(err)
	}

	h3relayInfo := peer.AddrInfo{
		ID:    dialNodeID,
		Addrs: []ma.Multiaddr{relayaddr},
	}

	if err := h1.Connect(context.Background(), h3relayInfo); err != nil {
		panic(err)
	}

	// Woohoo! we're connected!
	s, err := h1.NewStream(context.Background(), dialNodeID, "/cats")
	if err != nil {
		fmt.Println("huh, this should have worked: ", err)
		return
	}

	s.Read(make([]byte, 1)) // block until the handler closes the stream

	fmt.Println("end")

}


Run

Run 3 nodes separately

Run Node R

> go run R.go -l 3000

// get result 
/ip4/163.44.166.18/tcp/3000/p2p/QmRFNL6GS9wKsyx678gqEmYcxPX2Nqp355YCwzxiGdrKLE

Run Node A

> go run A.go -relay /ip4/163.44.166.18/tcp/3000/p2p/QmRFNL6GS9wKsyx678gqEmYcxPX2Nqp355YCwzxiGdrKLE

// get result
/p2p-circuit/ipfs/QmUKYigrdedpDLeNJ1ZFcKmwBGB4VXnqaPJBWenEu9mdtb
QmUKYigrdedpDLeNJ1ZFcKmwBGB4VXnqaPJBWenEu9mdtb

Run Node B

> go run B.go -relay /ip4/163.44.166.18/tcp/3000/p2p/QmRFNL6GS9wKsyx678gqEmYcxPX2Nqp355YCwzxiGdrKLE -dial QmUKYigrdedpDLeNJ1ZFcKmwBGB4VXnqaPJBWenEu9mdtb

get result



Okay, no connection from h1 to h3:  failed to dial QmUKYigrdedpDLeNJ1ZFcKmwBGB4VXnqaPJBWenEu9mdtb: no addresses
Just as we suspected
panic: failed to dial : all dials failed
  * [/p2p-circuit/ipfs/QmUKYigrdedpDLeNJ1ZFcKmwBGB4VXnqaPJBWenEu9mdtb] Failed to dial through 0 known relay hosts

goroutine 1 [running]:
main.main()
	/go/src/demo/p2p/simple/relay/B.go:79 +0xb35
exit status 2

PS:If node A and node B are in the same network segment, there is no problem sending data from B to A. Terminal direct output

Meow! It worked!

from go-libp2p-examples.

maimai88 avatar maimai88 commented on July 23, 2024 1

@maimai88 Relay dials are enabled by default but you need to connect it to a node which acts as a relay. You can do that by spawning a new node (on a publicly accessible ip:port) and passing circuit.OptHop in Libp2p.Option.

Now connect all your nodes (A -> R, B -> R) to this relay node. Now you can dial A -> B and it would use the relay node if it could not dial directly.


thanks @upperwal

I find a relay peer example in go-libp2p-relay .
Following the project's README.md i get the results I want.

thanks again

from go-libp2p-examples.

th3kave avatar th3kave commented on July 23, 2024 1

Hi,

For benefit of anyone trying to do this with later versions of libp2p, I wasn't able to get the bootstrap host working with version 0.13.0 (github.com/libp2p/go-libp2p v0.13.0) until I added the option libp2p.ForceReachabilityPublic() as follows:

   ....
   ....
      opts := []libp2p.Option{
		libp2p.ListenAddrs(sourceMultiAddr),
                libp2p.ForceReachabilityPublic(),    //  <--- ADD THIS OPTION
		//libp2p.NATPortMap(),
		//libp2p.DefaultSecurity,
		//libp2p.EnableRelay(circuit.OptActive, circuit.OptHop, circuit.OptDiscovery),
		libp2p.Identity(prvKey),
	}
   ....
   ....

Would be amazing if you guys could elaborate on how this option should be used or how to configure a bootstrap to be used privately.

Thanks a lot :)

from go-libp2p-examples.

upperwal avatar upperwal commented on July 23, 2024

@maimai88 You can try this code.

Peers in the same network can be interconnected, and different networks can't communicate. If all nodes use the default dht.DefaultBootstrapPeers, different networks can communicate.

This should not happen. Can you enable logs and say more about the failures.

from go-libp2p-examples.

maimai88 avatar maimai88 commented on July 23, 2024

@maimai88 You can try this code.

Peers in the same network can be interconnected, and different networks can't communicate. If all nodes use the default dht.DefaultBootstrapPeers, different networks can communicate.

This should not happen. Can you enable logs and say more about the failures.


Thanks upperwal

@upperwal
First of all, thank you very much for your reply.
I don't know why, I still didn't succeed.
My code is as follows


I have three nodes in Japan, Hong Kong and South Korea.

  • Node Japan as bootstrap node
  • Node Hong Kong as chat_HK node
  • Node South Korea as chat_SK node

bootstrap node

A node in Japan as bootstrap server, the code running on this node like this

(from your suggestion code)

libp2p_with_dht.go

package main

import (
	"context"
	"fmt"

	"github.com/libp2p/go-libp2p"
	crypto "github.com/libp2p/go-libp2p-crypto"
	dht "github.com/libp2p/go-libp2p-kad-dht"

	//inet "github.com/libp2p/go-libp2p-net"
	mrand "math/rand"

	ma "github.com/multiformats/go-multiaddr"
)

func main() {
	ctx := context.Background()

	// libp2p.New constructs a new libp2p Host.
	// Other options can be added here.
	sourceMultiAddr, _ := ma.NewMultiaddr("/ip4/0.0.0.0/tcp/3000")

	r := mrand.New(mrand.NewSource(int64(10)))

	prvKey, _, err := crypto.GenerateKeyPairWithReader(crypto.RSA, 2048, r)

	if err != nil {
		panic(err)
	}

	opts := []libp2p.Option{
		libp2p.ListenAddrs(sourceMultiAddr),
		//libp2p.NATPortMap(),
		//libp2p.DefaultSecurity,
		//libp2p.EnableRelay(circuit.OptActive, circuit.OptHop, circuit.OptDiscovery),
		libp2p.Identity(prvKey),
	}

	host, err := libp2p.New(ctx, opts...)
	if err != nil {
		panic(err)
	}

	fmt.Println("This node: ", host.ID().Pretty(), " ", host.Addrs())

	_, err = dht.New(ctx, host)
	if err != nil {
		panic(err)
	}

	select {}
}

The result of running the code above in the terminal:

> go run libp2p_with_dht.go

This node:  QmQnAZsyiJSovuqg8zjP3nKdm6Pwb75Mpn8HnGyD5WYZ15   [/ip4/127.0.0.1/tcp/3000 /ip4/163.44.166.18/tcp/3000]

chat_HK node

the code from https://github.com/libp2p/go-libp2p-examples/tree/master/chat-with-rendezvous

chat.go

package main

import (
	"bufio"
	"context"
	"flag"
	"fmt"
	"time"

	//"net/http"
	"os"
	"strings"
	"sync"

	"github.com/libp2p/go-libp2p"
	"github.com/libp2p/go-libp2p-core/network"
	"github.com/libp2p/go-libp2p-core/peer"
	"github.com/libp2p/go-libp2p-core/protocol"
	discovery "github.com/libp2p/go-libp2p-discovery"
	logging "github.com/whyrusleeping/go-logging"

	dht "github.com/libp2p/go-libp2p-kad-dht"
	multiaddr "github.com/multiformats/go-multiaddr"

	"github.com/ipfs/go-log"
	maddr "github.com/multiformats/go-multiaddr"
)

// A new type we need for writing a custom flag parser
type addrList []maddr.Multiaddr

func (al *addrList) String() string {
	strs := make([]string, len(*al))
	for i, addr := range *al {
		strs[i] = addr.String()
	}
	return strings.Join(strs, ",")
}

func (al *addrList) Set(value string) error {
	addr, err := maddr.NewMultiaddr(value)
	if err != nil {
		return err
	}
	*al = append(*al, addr)
	return nil
}

func StringsToAddrs(addrStrings []string) (maddrs []maddr.Multiaddr, err error) {
	for _, addrString := range addrStrings {
		addr, err := maddr.NewMultiaddr(addrString)
		if err != nil {
			return maddrs, err
		}
		maddrs = append(maddrs, addr)
	}
	return
}

type Config struct {
	RendezvousString string
	BootstrapPeers   addrList
	ListenAddresses  addrList
	ProtocolID       string
}

func ParseFlags() (Config, error) {
	config := Config{}
	flag.StringVar(&config.RendezvousString, "rendezvous", "meet me here",
		"Unique string to identify group of nodes. Share this with your friends to let them connect with you")
	flag.Var(&config.BootstrapPeers, "peer", "Adds a peer multiaddress to the bootstrap list")
	flag.Var(&config.ListenAddresses, "listen", "Adds a multiaddress to the listen list")
	flag.StringVar(&config.ProtocolID, "pid", "/chat/1.1.0", "Sets a protocol id for stream headers")
	flag.Parse()

	if len(config.BootstrapPeers) == 0 {
		config.BootstrapPeers = dht.DefaultBootstrapPeers
	}

	return config, nil
}

var logger = log.Logger("rendezvous")

func handleStream(stream network.Stream) {
	logger.Info("Got a new stream!")

	// Create a buffer stream for non blocking read and write.
	rw := bufio.NewReadWriter(bufio.NewReader(stream), bufio.NewWriter(stream))

	go readData(rw)
	go writeData(rw)

	// 'stream' will stay open until you close it (or the other side closes it).
}

func readData(rw *bufio.ReadWriter) {
	for {
		str, err := rw.ReadString('\n')
		if err != nil {
			fmt.Println("Error reading from buffer")
			panic(err)
		}

		if str == "" {
			return
		}
		if str != "\n" {
			// Green console colour: 	\x1b[32m
			// Reset console colour: 	\x1b[0m
			fmt.Printf("\x1b[32m%s\x1b[0m> ", str)
		}

	}
}

func writeData(rw *bufio.ReadWriter) {
	stdReader := bufio.NewReader(os.Stdin)

	for {
		fmt.Print("> ")
		sendData, err := stdReader.ReadString('\n')
		if err != nil {
			fmt.Println("Error reading from stdin")
			panic(err)
		}

		_, err = rw.WriteString(fmt.Sprintf("%s\n", sendData))
		if err != nil {
			fmt.Println("Error writing to buffer")
			panic(err)
		}
		err = rw.Flush()
		if err != nil {
			fmt.Println("Error flushing buffer")
			panic(err)
		}
	}
}

func main() {
	log.SetAllLoggers(logging.WARNING)
	//log.SetAllLoggers(logging.DEBUG)
	log.SetLogLevel("rendezvous", "info")
	help := flag.Bool("h", false, "Display Help")
	config, err := ParseFlags()
	if err != nil {
		panic(err)
	}

	if *help {
		fmt.Println("This program demonstrates a simple p2p chat application using libp2p")
		fmt.Println()
		fmt.Println("Usage: Run './chat in two different terminals. Let them connect to the bootstrap nodes, announce themselves and connect to the peers")
		flag.PrintDefaults()
		return
	}

	ctx := context.Background()

	// libp2p.New constructs a new libp2p Host. Other options can be added
	// here.
	host, err := libp2p.New(ctx,
		libp2p.ListenAddrs([]multiaddr.Multiaddr(config.ListenAddresses)...),
	)
	if err != nil {
		panic(err)
	}
	logger.Info("Host created. We are:", host.ID())
	logger.Info(host.Addrs())

	// Set a function as stream handler. This function is called when a peer
	// initiates a connection and starts a stream with this peer.
	host.SetStreamHandler(protocol.ID(config.ProtocolID), handleStream)

	// Start a DHT, for use in peer discovery. We can't just make a new DHT
	// client because we want each peer to maintain its own local copy of the
	// DHT, so that the bootstrapping node of the DHT can go down without
	// inhibiting future peer discovery.
	kademliaDHT, err := dht.New(ctx, host)
	if err != nil {
		panic(err)
	}

	// Bootstrap the DHT. In the default configuration, this spawns a Background
	// thread that will refresh the peer table every five minutes.
	logger.Debug("Bootstrapping the DHT")
	//if err = kademliaDHT.Bootstrap(ctx); err != nil {
	//	panic(err)
	//}

	cfg := dht.BootstrapConfig{1, 10 * time.Second, 10 * time.Second}
	if err = kademliaDHT.BootstrapWithConfig(ctx, cfg); err != nil {
		panic(err)
	}

	// Let's connect to the bootstrap nodes first. They will tell us about the
	// other nodes in the network.
	var wg sync.WaitGroup
	for _, peerAddr := range config.BootstrapPeers {
		peerinfo, _ := peer.AddrInfoFromP2pAddr(peerAddr)
		wg.Add(1)
		go func() {
			defer wg.Done()
			if err := host.Connect(ctx, *peerinfo); err != nil {
				logger.Warning(err)
			} else {
				logger.Info("Connection established with bootstrap node:", *peerinfo)
			}
		}()
	}
	wg.Wait()

	// We use a rendezvous point "meet me here" to announce our location.
	// This is like telling your friends to meet you at the Eiffel Tower.
	logger.Info("Announcing ourselves...")
	routingDiscovery := discovery.NewRoutingDiscovery(kademliaDHT)
	discovery.Advertise(ctx, routingDiscovery, config.RendezvousString)
	logger.Debug("Successfully announced!")

	// Now, look for others who have announced
	// This is like your friend telling you the location to meet you.
	logger.Debug("Searching for other peers...")
	peerChan, err := routingDiscovery.FindPeers(ctx, config.RendezvousString)
	if err != nil {
		panic(err)
	}

	for peer := range peerChan {

		if peer.ID == host.ID() {
			continue
		}
		logger.Debug("Found peer:", peer)

		logger.Debug("Connecting to:", peer)
		stream, err := host.NewStream(ctx, peer.ID, protocol.ID(config.ProtocolID))

		if err != nil {
			logger.Warning("Connection failed:", err)
			continue
		} else {
			rw := bufio.NewReadWriter(bufio.NewReader(stream), bufio.NewWriter(stream))

			go writeData(rw)
			go readData(rw)
		}

		logger.Info("Connected to:", peer)
	}

	select {}
}


Execute commands at the terminal

go run chat.go -peer /ip4/163.44.166.18/tcp/3000/p2p/QmQnAZsyiJSovuqg8zjP3nKdm6Pwb75Mpn8HnGyD5WYZ15

18:47:41.336  INFO rendezvous: Host created. We are: QmbwMU1kZundvxRRELASN5ZkLZ5JX8qUCwL4dsES5vbXyB chat.go:169
18:47:41.336  INFO rendezvous: [/ip6/::1/tcp/56472 /ip4/127.0.0.1/tcp/56471 /ip4/192.168.31.32/tcp/56471] chat.go:170
18:47:41.337 WARNI        dht: error bootstrapping: failed to find any peer in table dht_bootstrap.go:86
18:47:42.428  INFO rendezvous: Connection established with bootstrap node: {QmQnAZsyiJSovuqg8zjP3nKdm6Pwb75Mpn8HnGyD5WYZ15: [/ip4/163.44.166.18/tcp/3000]} chat.go:208
18:47:42.428  INFO rendezvous: Announcing ourselves... chat.go:216
18:47:47.557 WARNI rendezvous: Connection failed: failed to dial : all dials failed
  * [/ip4/127.0.0.1/tcp/33618] dial tcp4 127.0.0.1:33618: connect: connection refused
  * [/ip4/172.21.0.1/tcp/33618] dial tcp4 0.0.0.0:56471->172.21.0.1:33618: i/o timeout
  * [/ip4/172.18.0.1/tcp/33618] dial tcp4 0.0.0.0:56471->172.18.0.1:33618: i/o timeout
  * [/ip4/172.20.0.1/tcp/33618] dial tcp4 0.0.0.0:56471->172.20.0.1:33618: i/o timeout
  * [/ip4/172.22.0.1/tcp/33618] dial tcp4 0.0.0.0:56471->172.22.0.1:33618: i/o timeout
  * [/ip4/172.17.55.60/tcp/33618] dial tcp4 0.0.0.0:56471->172.17.55.60:33618: i/o timeout chat.go:240
18:47:47.559 WARNI rendezvous: Connection failed: failed to dial : all dials failed
  * [/ip6/::1/tcp/56454] dial tcp6 [::1]:56454: connect: connection refused
  * [/ip4/192.168.31.32/tcp/56453] dial tcp4 192.168.31.32:56453: connect: connection refused
  * [/ip4/127.0.0.1/tcp/56453] dial tcp4 127.0.0.1:56453: connect: connection refused chat.go:240


chat_SK node

chat.go is the same as the HK node

go run chat.go -peer /ip4/163.44.166.18/tcp/3000/p2p/QmQnAZsyiJSovuqg8zjP3nKdm6Pwb75Mpn8HnGyD5WYZ15
go: finding github.com/whyrusleeping/go-logging latest
18:46:22.476  INFO rendezvous: Host created. We are: QmNwfDzHQEWyLnU38zmi7UewedoMyq52r5DJEXhjck6j6e chat.go:170
18:46:22.477  INFO rendezvous: [/ip4/127.0.0.1/tcp/33618 /ip4/172.17.55.60/tcp/33618 /ip4/172.22.0.1/tcp/33618 /ip4/172.18.0.1/tcp/33618 /ip4/172.20.0.1/tcp/33618 /ip4/172.21.0.1/tcp/33618] chat.go:171
18:46:22.477 WARNI        dht: error bootstrapping: failed to find any peer in table dht_bootstrap.go:86
18:46:23.421  INFO rendezvous: Connection established with bootstrap node: {QmQnAZsyiJSovuqg8zjP3nKdm6Pwb75Mpn8HnGyD5WYZ15: [/ip4/163.44.166.18/tcp/3000]} chat.go:209
18:46:23.421  INFO rendezvous: Announcing ourselves... chat.go:217


from go-libp2p-examples.

upperwal avatar upperwal commented on July 23, 2024

@maimai88

18:47:47.557 WARNI rendezvous: Connection failed: failed to dial : all dials failed
  * [/ip4/127.0.0.1/tcp/33618] dial tcp4 127.0.0.1:33618: connect: connection refused
  * [/ip4/172.21.0.1/tcp/33618] dial tcp4 0.0.0.0:56471->172.21.0.1:33618: i/o timeout
  * [/ip4/172.18.0.1/tcp/33618] dial tcp4 0.0.0.0:56471->172.18.0.1:33618: i/o timeout
  * [/ip4/172.20.0.1/tcp/33618] dial tcp4 0.0.0.0:56471->172.20.0.1:33618: i/o timeout
  * [/ip4/172.22.0.1/tcp/33618] dial tcp4 0.0.0.0:56471->172.22.0.1:33618: i/o timeout
  * [/ip4/172.17.55.60/tcp/33618] dial tcp4 0.0.0.0:56471->172.17.55.60:33618: i/o timeout chat.go:240

The above shows that chat_HK node is able to discover chat_SK node via bootstrap node but chat_HK node could not connect to chat_SK node. One of the reason this could happen is because node chat_SK node is behind a NAT and you can't dial to 172.21.0.1:33618.

Solutions:

  1. If you have access to the firewall:
    a) Enable UPnP in your firewall/router and pass libp2p.NATPortMap() as libp2p.Option.
    b) Open and forward a port manually on your farewall/router.
  2. If you don't have access to the firewall, setup a relay node (should have a dialable public IP) and use it to connect chat_HK and chat_SK.

from go-libp2p-examples.

maimai88 avatar maimai88 commented on July 23, 2024

2. chat_HK and chat_SK


Thanks again @upperwal

I don't have access to the firewall, so I modified the code above,when I created the host, I added the libp2p.EnableRelay() option to them.

...

libp2p.New(ctx,
		libp2p.ListenAddrs([]multiaddr.Multiaddr(config.ListenAddresses)...),

		libp2p.EnableRelay(),
		# ===== Also tried the following options ======
		//libp2p.EnableRelay(circuit.OptHop),
		//libp2p.EnableRelay(circuit.OptHop, circuit.OptDiscovery),
		//libp2p.EnableRelay(circuit.OptActive, circuit.OptHop, circuit.OptDiscovery),
	)

...

But the node chat_HK and the node chat_SK still can't connect

Can you help me give me a relay example? Thank you.

Thanks again

from go-libp2p-examples.

upperwal avatar upperwal commented on July 23, 2024

@maimai88 Relay dials are enabled by default but you need to connect it to a node which acts as a relay. You can do that by spawning a new node (on a publicly accessible ip:port) and passing circuit.OptHop in Libp2p.Option.

Now connect all your nodes (A -> R, B -> R) to this relay node. Now you can dial A -> B and it would use the relay node if it could not dial directly.

from go-libp2p-examples.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.