1package dht 2 3import ( 4 "context" 5 "time" 6 7 "github.com/libp2p/go-libp2p-core/peer" 8 9 "github.com/multiformats/go-multiaddr" 10) 11 12// DefaultBootstrapPeers is a set of public DHT bootstrap peers provided by libp2p. 13var DefaultBootstrapPeers []multiaddr.Multiaddr 14 15// Minimum number of peers in the routing table. If we drop below this and we 16// see a new peer, we trigger a bootstrap round. 17var minRTRefreshThreshold = 10 18 19const ( 20 periodicBootstrapInterval = 2 * time.Minute 21 maxNBoostrappers = 2 22) 23 24func init() { 25 for _, s := range []string{ 26 "/dnsaddr/bootstrap.libp2p.io/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN", 27 "/dnsaddr/bootstrap.libp2p.io/p2p/QmQCU2EcMqAqQPR2i9bChDtGNJchTbq5TbXJJ16u19uLTa", 28 "/dnsaddr/bootstrap.libp2p.io/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb", 29 "/dnsaddr/bootstrap.libp2p.io/p2p/QmcZf59bWwK5XFi76CZX8cbJ4BhTzzA3gU1ZjYZcYW3dwt", 30 "/ip4/104.131.131.82/tcp/4001/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ", // mars.i.ipfs.io 31 } { 32 ma, err := multiaddr.NewMultiaddr(s) 33 if err != nil { 34 panic(err) 35 } 36 DefaultBootstrapPeers = append(DefaultBootstrapPeers, ma) 37 } 38} 39 40// GetDefaultBootstrapPeerAddrInfos returns the peer.AddrInfos for the default 41// bootstrap peers so we can use these for initializing the DHT by passing these to the 42// BootstrapPeers(...) option. 43func GetDefaultBootstrapPeerAddrInfos() []peer.AddrInfo { 44 ds := make([]peer.AddrInfo, 0, len(DefaultBootstrapPeers)) 45 46 for i := range DefaultBootstrapPeers { 47 info, err := peer.AddrInfoFromP2pAddr(DefaultBootstrapPeers[i]) 48 if err != nil { 49 logger.Errorw("failed to convert bootstrapper address to peer addr info", "address", 50 DefaultBootstrapPeers[i].String(), err, "err") 51 continue 52 } 53 ds = append(ds, *info) 54 } 55 return ds 56} 57 58// Bootstrap tells the DHT to get into a bootstrapped state satisfying the 59// IpfsRouter interface. 60func (dht *IpfsDHT) Bootstrap(ctx context.Context) error { 61 dht.fixRTIfNeeded() 62 dht.rtRefreshManager.RefreshNoWait() 63 return nil 64} 65 66// RefreshRoutingTable tells the DHT to refresh it's routing tables. 67// 68// The returned channel will block until the refresh finishes, then yield the 69// error and close. The channel is buffered and safe to ignore. 70func (dht *IpfsDHT) RefreshRoutingTable() <-chan error { 71 return dht.rtRefreshManager.Refresh(false) 72} 73 74// ForceRefresh acts like RefreshRoutingTable but forces the DHT to refresh all 75// buckets in the Routing Table irrespective of when they were last refreshed. 76// 77// The returned channel will block until the refresh finishes, then yield the 78// error and close. The channel is buffered and safe to ignore. 79func (dht *IpfsDHT) ForceRefresh() <-chan error { 80 return dht.rtRefreshManager.Refresh(true) 81} 82