diff --git a/go-peer/main.go b/go-peer/main.go index 5ec66ab5..f1029a61 100644 --- a/go-peer/main.go +++ b/go-peer/main.go @@ -45,7 +45,6 @@ var logger = log.Logger("app") // NewDHT attempts to connect to a bunch of bootstrap peers and returns a new DHT. // If you don't have any bootstrapPeers, you can use dht.DefaultBootstrapPeers or an empty list. func NewDHT(ctx context.Context, host host.Host, bootstrapPeers []multiaddr.Multiaddr) (*dht.IpfsDHT, error) { - kdht, err := dht.New(ctx, host, dht.BootstrapPeers(dht.GetDefaultBootstrapPeerAddrInfos()...), dht.Mode(dht.ModeAuto), @@ -109,6 +108,10 @@ func main() { nickFlag := flag.String("nick", "", "nickname to use in chat. will be generated if empty") idPath := flag.String("identity", "identity.key", "path to the private key (PeerID) file") headless := flag.Bool("headless", false, "run without chat UI") + bootstrapper := flag.Bool("bootstrapper", false, "run as a bootstrap peer") + + var directPeers stringSlice + flag.Var(&directPeers, "directpeer", "reciprocal gossipsub bootstrap peers (can be used multiple times)") var addrsToConnectTo stringSlice flag.Var(&addrsToConnectTo, "connect", "address to connect to (can be used multiple times)") @@ -198,8 +201,32 @@ func main() { panic(err) } + gossipSubOpts := []pubsub.Option{ + pubsub.WithFloodPublish(true), + } + + if *bootstrapper { + gossipSubOpts = append(gossipSubOpts, pubsub.WithPeerExchange(true)) + + if len(directPeers) > 0 { + dp := peerStrSliceToAddrInfoSlice(directPeers) + gossipSubOpts = append( + gossipSubOpts, + pubsub.WithDirectPeers(dp), + pubsub.WithDirectConnectTicks(60), // attempt to reconnect to direct peers every 60 ticks (seconds) + ) + } + + // // See https://github.com/libp2p/specs/blob/master/pubsub/gossipsub/gossipsub-v1.1.md#recommendations-for-network-operators + pubsub.GossipSubD = 0 + pubsub.GossipSubDlo = 0 + pubsub.GossipSubDhi = 0 + pubsub.GossipSubDout = 0 + pubsub.GossipSubDscore = 0 + } + // create a new PubSub service using the GossipSub router - ps, err := pubsub.NewGossipSub(ctx, h) + ps, err := pubsub.NewGossipSub(ctx, h, gossipSubOpts...) if err != nil { panic(err) } @@ -304,8 +331,24 @@ func main() { } } +func peerStrSliceToAddrInfoSlice(peerStrs []string) []peer.AddrInfo { + var addrInfos []peer.AddrInfo + + for _, addr := range peerStrs { + peerInfo, err := peer.AddrInfoFromString(addr) + if err != nil { + LogMsgf("Failed to parse multiaddr: %s", err.Error()) + continue + } + + addrInfos = append(addrInfos, *peerInfo) + } + + return addrInfos +} + // printErr is like fmt.Printf, but writes to stderr. -func printErr(m string, args ...interface{}) { +func printErr(m string, args ...any) { fmt.Fprintf(os.Stderr, m, args...) }