### Install go-libp2p-kad-dht Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/README.md Use this command to install the go-libp2p-kad-dht library. ```sh go get github.com/libp2p/go-libp2p-kad-dht ``` -------------------------------- ### Basic Server Setup Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/INDEX.md Initialize a new libp2p host and create a DHT node in server mode. This is a fundamental setup for participating in the DHT network as a server. ```go ctx := context.Background() h, _ := libp2p.New() dht, _ := dht.New(ctx, h, dht.Mode(dht.ModeServer)) dht.Bootstrap(ctx) ``` -------------------------------- ### Example: Configure DHT with Options Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/types.md Demonstrates how to create a new DHT instance using functional options for bucket size and operating mode. ```go opt1 := dht.BucketSize(20) opt2 := dht.Mode(dht.ModeServer) dht, _ := dht.New(ctx, host, opt1, opt2) ``` -------------------------------- ### HandleQueryFail Example Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/types.md An example demonstrating the use of the HandleQueryFail callback with Crawler.Run() to log errors when a query to a peer fails. ```go c.Run(ctx, bootstrapPeers, nil, func(p peer.ID, err error) { log.Printf("Query to %s failed: %v", p, err) }, ) ``` -------------------------------- ### Example Usage of PeerIPGroupFilter Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/types.md Demonstrates how to use a custom PeerIPGroupFilter with the DHT constructor. ```go dht, _ := dht.New(ctx, host, dht.RoutingTablePeerDiversityFilter(myIPGroupFilter), ) ``` -------------------------------- ### Get Value from Dual DHT Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/dual-dht.md This example demonstrates how to retrieve a value from the Dual DHT. It automatically queries both WAN and LAN instances. ```go // This automatically queries both WAN and LAN value, err := dualDHT.GetValue(ctx, "/mykey") ``` -------------------------------- ### Full Network Client Setup Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/INDEX.md Initialize a FullRT client for interacting with the IPFS network. It checks for readiness before attempting to find providers. ```go frt, _ := fullrt.NewFullRT(h, "/ipfs") if frt.Ready() { providers, _ := frt.FindProviders(ctx, cid) } ``` -------------------------------- ### HandleQueryResult Example Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/types.md An example demonstrating how to use the HandleQueryResult callback within the Crawler.Run() method to log the number of peers returned from a query. ```go c.Run(ctx, bootstrapPeers, func(p peer.ID, rtPeers []*peer.AddrInfo) { log.Printf("Query to %s returned %d peers", p, len(rtPeers)) }, nil, ) ``` -------------------------------- ### Dual DHT Setup Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/INDEX.md Initialize a dual DHT instance, which combines functionalities, and use it to find providers. This pattern is useful for more complex network interactions. ```go dual, _ := dual.New(ctx, h) providers, _ := dual.FindProviders(ctx, cid) ``` -------------------------------- ### Example: Custom Query Filter Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/types.md Shows how to implement a custom query filter function to include peers with at least one address. ```go dht, _ := dht.New(ctx, host, dht.QueryFilter(func(any peer.AddrInfo) bool { return len(pi.Addrs) > 0 }), ) ``` -------------------------------- ### Basic Client Setup Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/INDEX.md Initialize a DHT node in client mode and use it to find providers for a given content identifier (CID). This is suitable for nodes that primarily query the DHT. ```go dht, _ := dht.New(ctx, h, dht.Mode(dht.ModeClient)) dht.Bootstrap(ctx) providers, _ := dht.FindProviders(ctx, cid) ``` -------------------------------- ### LAN DHT Protocol Example Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/dual-dht.md Illustrates the resulting protocol IDs for WAN and LAN DHTs when the LanExtension is applied. The LAN protocol is modified to ensure separation. ```go // WAN DHT uses: /ipfs/kad/1.0.0 // LAN DHT uses: /ipfs/lan/kad/1.0.0 (due to LanExtension) ``` -------------------------------- ### Find Providers with Dual DHT Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/dual-dht.md This example shows how to find providers for a given content identifier using the Dual DHT. It searches both WAN and LAN DHTs and returns results from either. ```go // This searches both DHTs and returns results from either providers, err := dualDHT.FindProviders(ctx, contentCID) ``` -------------------------------- ### New Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/ipfsdht.md Creates a new DHT with the specified host and options. The DHT starts in the mode specified by options (default: ModeAuto), which may dynamically switch between client and server modes based on network conditions. ```APIDOC ## New ### Description Creates a new DHT with the specified host and options. The DHT starts in the mode specified by options (default: ModeAuto), which may dynamically switch between client and server modes based on network conditions. ### Parameters #### Path Parameters - **ctx** (context.Context) - Required - Context used for cancellation and timeout management - **h** (host.Host) - Required - libp2p host instance with network and peer store - **options** (...Option) - Optional - Variadic configuration options ### Returns Pointer to initialized IpfsDHT instance, or error if initialization fails. ### Error conditions: - Invalid configuration options - Datastore initialization failure - Routing table construction failure - Provider store initialization failure ### Example: ```go ctx, cancel := context.WithCancel(context.Background()) defuncel() dht, err := dht.New(ctx, host) if err != nil { log.Fatal(err) } defuncel() // Use DHT for routing operations peers, err := dht.GetClosestPeers(ctx, "/mykey") ``` ``` -------------------------------- ### Run Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/crawler.md Runs the crawler starting from a set of bootstrap peers to systematically query peers and discover the network topology. This method blocks until the crawler finishes or the context is cancelled. ```APIDOC ## Run ### Description Runs the crawler starting from a set of bootstrap peers. Systematically queries peers to discover the network topology. Blocks until the crawler finishes or context is cancelled. ### Method ```go func (c *DefaultCrawler) Run(ctx context.Context, startingPeers []*peer.AddrInfo, handleSuccess HandleQueryResult, handleFail HandleQueryFail) ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters Table | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | ctx | context.Context | Yes | — | Context for cancellation | | startingPeers | []*peer.AddrInfo | Yes | — | Initial peers to query | | handleSuccess | HandleQueryResult | Yes | — | Callback for successful queries | | handleFail | HandleQueryFail | Yes | — | Callback for failed queries | ### Returns None (blocks until crawl completes or context cancelled). ### Callback Signatures ```go type HandleQueryResult func(p peer.ID, rtPeers []*peer.AddrInfo) type HandleQueryFail func(p peer.ID, err error) ``` ### Example ```go discoveredPeers := make(map[peer.ID]*peer.AddrInfo) c.Run(ctx, bootstrapPeers, // Success callback: receives routing table peers from a query func(p peer.ID, rtPeers []*peer.AddrInfo) { log.Printf("Queried %s, got %d peers", p, len(rtPeers)) for _, pi := range rtPeers { discoveredPeers[pi.ID] = pi } }, // Fail callback: receives query errors func(p peer.ID, err error) { log.Printf("Query to %s failed: %v", p, err) }, ) log.Printf("Discovered %d unique peers", len(discoveredPeers)) ``` ``` -------------------------------- ### NewRTPeerDiversityFilter Example Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/filters.md Creates a diversity filter that limits peers per IP group/subnet. Used by the default Dual DHT WAN instance to prevent network centralization. ```go dht, _ := dht.New(ctx, host, dht.RoutingTablePeerDiversityFilter( dht.NewRTPeerDiversityFilter(host, 2, 4), ), ) ``` -------------------------------- ### Run Crawler and Handle Results Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/crawler.md Executes the crawler starting from bootstrap peers. Define callbacks for successful queries and failures. The function blocks until the crawl completes or the context is cancelled. ```go discoveredPeers := make(map[peer.ID]*peer.AddrInfo) c.Run(ctx, bootstrapPeers, // Success callback: receives routing table peers from a query func(p peer.ID, rtPeers []*peer.AddrInfo) { log.Printf("Queried %s, got %d peers", p, len(rtPeers)) for _, pi := range rtPeers { discoveredPeers[pi.ID] = pi } }, // Fail callback: receives query errors func(p peer.ID, err error) { log.Printf("Query to %s failed: %v", p, err) }, ) log.Printf("Discovered %d unique peers", len(discoveredPeers)) ``` -------------------------------- ### Get Default Bootstrap Peer Addresses Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/configuration.md Retrieves the default bootstrap peer addresses, which are the Kubo bootstrap nodes. These are used to initialize the DHT with known peers. ```go peers := dht.GetDefaultBootstrapPeerAddrInfos() dht, _ := dht.New(ctx, host, dht.BootstrapPeers(peers...), ) ``` -------------------------------- ### Get Closest Peers to Key Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/fullrt.md Returns the k closest peers to the given key from the full routing table, using the XOR metric. The key is used for distance calculation. ```go func (frt *FullRT) GetClosestPeers(ctx context.Context, key string) ([]peer.ID, error) ``` -------------------------------- ### Get Default Bootstrap Peers Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/bootstrap.md Retrieves the default IPFS bootstrap peers (Kubo nodes). These are stable, well-known nodes for joining the network. Use this when you need a predefined set of entry points. ```go bootstrapPeers := dht.GetDefaultBootstrapPeerAddrInfos() log.Printf("Found %d default bootstrap peers", len(bootstrapPeers)) dht, _ := dht.New(ctx, host, dht.BootstrapPeers(bootstrapPeers...), ) // Then bootstrap the routing table if err := dht.Bootstrap(ctx); err != nil { log.Printf("Bootstrap failed: %v", err) } ``` -------------------------------- ### Configure DHT with Custom Options Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/00-START-HERE.md Illustrates creating a DHT with various custom configurations, including server mode, bucket size, concurrency, query filtering, datastore, and bootstrap peers. ```go dht, _ := dht.New(ctx, h, dht.Mode(dht.ModeServer), dht.BucketSize(20), dht.Concurrency(3), dht.QueryFilter(dht.PublicQueryFilter), dht.Datastore(persistentStore), dht.BootstrapPeers(peers...), ) ``` -------------------------------- ### Create and Use a DHT Node Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/00-START-HERE.md Demonstrates how to create a server-mode DHT node, join the network, and perform a provider query. Ensure libp2p is initialized before creating the DHT. ```go ctx := context.Background() h, _ := libp2p.New() // Create server-mode DHT dht, _ := dht.New(ctx, h, dht.Mode(dht.ModeServer)) defer dht.Close() // Join the network dht.Bootstrap(ctx) // Use it providers, _ := dht.FindProviders(ctx, contentCID) ``` -------------------------------- ### Get IpfsDHT Mode Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/ipfsdht.md Determines the current operational mode of the DHT, which can be either client-only or server (handling queries and responses). ```go mode := dht.Mode() if mode == dht.ModeServer { log.Println("DHT is in server mode") } else { log.Println("DHT is in client mode") } ``` -------------------------------- ### Bootstrap() Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/bootstrap.md Initiates the network entry process by connecting to bootstrap peers, querying their routing tables, and adding discovered peers to the DHT's routing table. It recursively queries discovered peers to fully populate the table. Returns an error if all bootstrap attempts fail. ```APIDOC ## Bootstrap() ### Description Performs network entry by connecting to bootstrap peers, querying their routing tables, and adding discovered peers to the DHT routing table. It recursively queries discovered peers to fill the routing table. ### Method `func (dht *IpfsDHT) Bootstrap(ctx context.Context) error` ### Parameters * `ctx` (context.Context) - The context for the operation. ### Returns * `error` - An error if all bootstrap attempts fail. ### Example ```go dht, _ := dht.New(ctx, host, dht.BootstrapPeers(peers...)) // Bootstrap the routing table if err := dht.Bootstrap(ctx); err != nil { log.Printf("Warning: bootstrap failed: %v", err) // Can continue, but routing table may be empty } // Wait for bootstrap to propagate time.Sleep(1 * time.Second) // Now the routing table is populated log.Printf("Routing table has %d peers", dht.RoutingTable().Size()) ``` ``` -------------------------------- ### Dual DHT Bootstrap for WAN and LAN Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/bootstrap.md Initialize Dual DHT to automatically bootstrap both WAN and LAN instances. Use DHTOption to specify bootstrap peers for the WAN instance. The LAN instance discovers private peers via host connections. ```go dualDHT, _ := dual.New(ctx, host, dual.DHTOption( dht.BootstrapPeers(dht.GetDefaultBootstrapPeerAddrInfos()...), ), ) // Both WAN DHT (public peers) and LAN DHT (private peers) are ready providers, _ := dualDHT.FindProviders(ctx, cid) ``` -------------------------------- ### Get DHT Peer Key Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/ipfsdht.md Obtain the binary representation of the node's peer key within the Kademlia keyspace. This is a 32-byte value. ```go func (dht *IpfsDHT) PeerKey() []byte ``` -------------------------------- ### Get IpfsDHT Peer ID Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/ipfsdht.md Returns the unique peer ID of the local node running the DHT. This ID is used for network identification. ```go id := dht.PeerID() log.Printf("This node's peer ID: %s", id) ``` -------------------------------- ### Get IpfsDHT Host Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/ipfsdht.md Retrieves the underlying libp2p host instance managed by the DHT. This allows access to the host's network interfaces and configurations. ```go h := dht.Host() addrs := h.Addrs() ``` -------------------------------- ### WithBootstrapPeers Option Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/fullrt.md Sets the bootstrap peers for initial network connectivity. This is crucial for bootstrapping the DHT and connecting to the network. ```APIDOC ## WithBootstrapPeers ### Description Sets bootstrap peers for initial network connectivity. ### Method Signature ```go func WithBootstrapPeers(peers ...peer.AddrInfo) Option ``` ### Example ```go fullrt, _ := fullrt.NewFullRT(h, "/ipfs", fullrt.WithBootstrapPeers(bootstrapPeerInfo), ) ``` ``` -------------------------------- ### Get DHT Message Sender Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/ipfsdht.md Retrieve the protocol message sender interface used by the DHT for communication. This provides low-level access for sending messages directly. ```go func (dht *IpfsDHT) MessageSender() pb.MessageSender ``` -------------------------------- ### Configure Bootstrap Peers Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/fullrt.md Sets bootstrap peers for initial network connectivity. ```go func WithBootstrapPeers(peers ...peer.AddrInfo) Option ``` ```go fullrt, _ := fullrt.NewFullRT(h, "/ipfs", fullrt.WithBootstrapPeers(bootstrapPeerInfo), ) ``` -------------------------------- ### Create Default Crawler Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/crawler.md Initializes a new network crawler. Configure protocols and parallelism using options. Ensure the libp2p host instance is provided. ```go c, err := crawler.NewDefaultCrawler(host, crawler.WithProtocols([]protocol.ID{"/ipfs/kad/1.0.0"}), crawler.WithParallelism(20), ) if err != nil { log.Fatal(err) } // Use crawler to discover network crawledPeers := []*peer.AddrInfo{} c.Run(ctx, bootstrapPeers, func(p peer.ID, rtPeers []*peer.AddrInfo) { crawledPeers = append(crawledPeers, rtPeers...) }, func(p peer.ID, err error) { log.Printf("Failed to query %s: %v", p, err) }, ) ``` -------------------------------- ### Get IpfsDHT Routing Table Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/ipfsdht.md Retrieves the underlying Kademlia bucket routing table for direct inspection of its state. Use this to examine the current peer distribution. ```go rt := dht.RoutingTable() peersInRT := rt.GetPeers() ``` -------------------------------- ### Catching DHT Initialization Configuration Errors Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/errors.md Demonstrates how to catch configuration validation errors during DHT initialization. Use this pattern to handle invalid DHT modes or other configuration issues. ```go dht, err := dht.New(ctx, host, dht.Mode(999)) if err != nil { log.Printf("Configuration error: %v", err) } ``` -------------------------------- ### Get Filtered Node Addresses Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/ipfsdht.md Retrieve the node's network addresses after applying any configured address filters, such as excluding localhost addresses. Returns a slice of multiaddresses. ```go func (dht *IpfsDHT) FilteredAddrs() []ma.Multiaddr ``` -------------------------------- ### Create New FullRT DHT Client Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/fullrt.md Initializes a new FullRT DHT client. Use this to create an accelerated client that tracks the full network using a trie-based routing table. Ensure the libp2p host and protocol prefix are valid. ```go func NewFullRT(h host.Host, protocolPrefix protocol.ID, options ...Option) (*FullRT, error) ``` ```go ctx := context.Background() h, _ := libp2p.New() fullrt, err := fullrt.NewFullRT(h, "/ipfs") if err != nil { log.Fatal(err) } // Wait until routing table is ready if fullrt.Ready() { log.Println("Routing table refreshed") } providers, _ := fullrt.FindProviders(ctx, cid) ``` -------------------------------- ### Get IpfsDHT Provider Store Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/ipfsdht.md Accesses the provider storage backend responsible for managing provider announcements. Use this to interact directly with the DHT's record storage. ```go ps := dht.ProviderStore() // Can be used to directly query provider records ``` -------------------------------- ### Get IpfsDHT Context Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/ipfsdht.md Retrieves the internal context associated with the DHT's lifecycle. This context is automatically cancelled when the DHT is closed, useful for operations that should terminate with the DHT. ```go ctx := dht.Context() // Use for operations that should stop when DHT closes ``` -------------------------------- ### Configure Both WAN and LAN DHT Instances Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/dual-dht.md Use DHTOption to apply the same DHT configurations to both the WAN and LAN DHT instances simultaneously. This is useful for setting common parameters like custom validators or maximum record age for all DHT operations. ```go dualDHT, _ := dual.New(ctx, h, dual.DHTOption( dht.Validator(customValidator), dht.MaxRecordAge(1*time.Hour), ), ) ``` -------------------------------- ### Initialize Dual DHT for Hybrid Networks Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/bootstrap.md Use Dual DHT for hybrid networks (WAN + LAN). It automatically manages bootstrap for both Wide Area Network and Local Area Network DHTs. ```go dualDHT, _ := dual.New(ctx, host) // Both WAN and LAN DHTs are bootstrapped automatically ``` -------------------------------- ### Handle Bootstrap Failure in go-libp2p-kad-dht Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/bootstrap.md If initial bootstrap fails, log the error and attempt a retry after a short delay. Check the routing table size after bootstrapping to ensure sufficient peers. ```go err := dht.Bootstrap(ctx) if err != nil { log.Printf("Initial bootstrap failed: %v", err) // DHT will continue operating but may have empty routing table // Can try again later: time.Sleep(5 * time.Second) if err := dht.Bootstrap(ctx); err != nil { log.Printf("Retry failed: %v", err) } } // Check if we got any peers if dht.RoutingTable().Size() < dht.BucketSize() { log.Printf("Warning: only %d peers in routing table", dht.RoutingTable().Size()) } ``` -------------------------------- ### Configure Quick Bootstrap Timeout (LAN) Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/bootstrap.md Set a short timeout for quick bootstrap, suitable for Local Area Networks where peers are expected to be highly responsive. ```go ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) def cancel() dht.Bootstrap(ctx) ``` -------------------------------- ### Create Basic DHT Client Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/README.md Instantiate a DHT node in client mode. This node primarily queries the network for information and does not store records. It requires an existing host and context. ```go // Create client-mode DHT d, _ := dht.New(ctx, h, dht.Mode(dht.ModeClient)) deferr d.Close() d.Bootstrap(ctx) // Query the network providers, _ := d.FindProviders(ctx, contentCID) ``` -------------------------------- ### Configure Static Bootstrap Peers Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/bootstrap.md Sets a static list of bootstrap peers for the DHT using `BootstrapPeers` option. Provide a slice of `peer.AddrInfo` representing the nodes to connect to. ```go customBootstrap := []peer.AddrInfo{ { ID: peerID1, Addrs: []ma.Multiaddr{ ma.StringCast("/ip4/192.0.2.1/tcp/4001"), }, }, { ID: peerID2, Addrs: []ma.Multiaddr{ ma.StringCast("/ip4/192.0.2.2/tcp/4001"), }, }, } dht, _ := dht.New(ctx, host, dht.BootstrapPeers(customBootstrap...), ) ``` -------------------------------- ### Get IpfsDHT Bucket Size Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/ipfsdht.md Retrieves the configured bucket size (k parameter) for the DHT's routing table. This value typically defaults to 20 peers per bucket. ```go k := dht.BucketSize() // Usually 20 ``` -------------------------------- ### Create Basic DHT Server Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/README.md Instantiate a DHT node in server mode. This node will actively participate in the DHT network by storing and providing records. Ensure proper context and host initialization. ```go import ( "context" dht "github.com/libp2p/go-libp2p-kad-dht" ) ctx := context.Background() h, _ := libp2p.New() // Create server-mode DHT d, _ := dht.New(ctx, h, dht.Mode(dht.ModeServer)) deferr d.Close() // Bootstrap network d.Bootstrap(ctx) // Now ready for queries and responses ``` -------------------------------- ### Get IpfsDHT Routing Table Diversity Stats Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/ipfsdht.md Fetches statistics detailing the diversity of peer IP addresses within each bucket of the routing table. This helps in analyzing network connectivity and address distribution. ```go stats := dht.GetRoutingTableDiversityStats() for i, stat := range stats { log.Printf("Bucket %d: %d peers, %d unique IPs", i, stat.PeerCount, stat.IpCount) } ``` -------------------------------- ### Enable Optimistic Provide Optimization Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/configuration.md Enables an experimental optimization for the provide process. This feature is experimental and may be changed or removed. ```go dht, _ := dht.New(ctx, host, dht.EnableOptimisticProvide(), ) ``` -------------------------------- ### Create New IpfsDHT Instance Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/ipfsdht.md Initializes a new IpfsDHT instance with a given host and context. Supports various configuration options to control its operational mode. Use this for general-purpose DHT usage. ```go ctx, cancel := context.WithCancel(context.Background()) def cancel(): dht, err := dht.New(ctx, host) if err != nil { log.Fatal(err) } defer dht.Close() // Use DHT for routing operations peers, err := dht.GetClosestPeers(ctx, "/mykey") ``` -------------------------------- ### Configure WAN DHT Instance Options Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/dual-dht.md Use WanDHTOption to apply specific DHT configurations exclusively to the WAN DHT instance. This is useful for tuning WAN-specific parameters like bucket size and concurrency. ```go dualDHT, _ := dual.New(ctx, h, dual.WanDHTOption( dht.BucketSize(30), dht.Concurrency(3), ), ) ``` -------------------------------- ### Context Usage for Timeout Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/types.md Demonstrates using Go's standard context package with `context.WithTimeout` to set an operation deadline. Ensure `cancel()` is deferred to release resources. ```go ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() value, err := dht.GetValue(ctx, "/mykey") ``` -------------------------------- ### Configure Private Network Bootstrap Peers Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/bootstrap.md For private networks, specify your organization's bootstrap peers and a custom protocol prefix. Ensure these peers are running with your custom protocol prefix. ```go privatePeers := []peer.AddrInfo{ // Peers managed by your organization // These must be running with your custom protocol prefix } dht, _ := dht.New(ctx, host, dht.ProtocolPrefix("/myorg"), dht.BootstrapPeers(privatePeers...), ) dht.Bootstrap(ctx) ``` -------------------------------- ### Configure Dynamic Bootstrap Peers Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/bootstrap.md Sets a function that dynamically provides bootstrap peers using `BootstrapPeersFunc`. This allows for runtime selection of peers based on conditions, useful for adaptive network entry. ```go dht, _ := dht.New(ctx, host, dht.BootstrapPeersFunc(func() []peer.AddrInfo { // Dynamic bootstrap peer selection if isPublicNode { return getPublicBootstrap() } else { return getPrivateBootstrap() } }), ) ``` -------------------------------- ### Custom DHT Configuration Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/INDEX.md Configure a DHT node with custom settings including mode, bucket size, datastore, and bootstrap peers. This allows fine-tuning the DHT's behavior. ```go dht, _ := dht.New(ctx, h, dht.Mode(dht.ModeServer), dht.BucketSize(30), dht.Datastore(store), dht.BootstrapPeers(peers...), ) ``` -------------------------------- ### Create Dual DHT Instance Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/dual-dht.md Initializes a new Dual DHT with separate WAN and LAN routing tables. The WAN DHT filters for public addresses, and the LAN DHT filters for private addresses. Both operate with independent protocol prefixes. Use this constructor when you need to manage distinct routing for global and local networks. ```go ctx := context.Background() h, _ := libp2p.New() dualDHT, err := dual.New(ctx, h) if err != nil { log.Fatal(err) } deferral dualDHT.Close() ``` -------------------------------- ### Create Dual DHT (WAN + LAN) Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/README.md Initialize a DHT that manages both Wide Area Network (WAN) and Local Area Network (LAN) routing tables. This allows for efficient peer discovery and data retrieval across different network scopes. ```go import "github.com/libp2p/go-libp2p-kad-dht/dual" // Creates both WAN and LAN DHTs with appropriate filtering dualDHT, _ := dual.New(ctx, h) deferr dualDHT.Close() // Queries go to appropriate DHT based on peer type providers, _ := dualDHT.FindProviders(ctx, cid) ``` -------------------------------- ### Bootstrap Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/ipfsdht.md Populates the routing table by querying bootstrap peers to discover network peers. This should be called after DHT creation. ```APIDOC ## Bootstrap ### Description Populates the routing table from a set of bootstrap peers. Queries bootstrap peers to discover network peers and fill the routing table. Should be called after DHT creation. ### Method Not applicable (Go function signature provided) ### Endpoint Not applicable (Go function signature provided) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```go dht, _ := dht.New(ctx, host) defer dht.Close() if err := dht.Bootstrap(ctx); err != nil { log.Printf("Bootstrap failed: %v", err) } // Now routing table is seeded with network peers ``` ### Response #### Success Response None (returns nil error) #### Response Example (See Request Example for usage) **Error conditions:** - No bootstrap peers available - Cannot connect to any bootstrap peers - All bootstrap queries fail ``` -------------------------------- ### Implement Bootstrap Fallback Strategy Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/bootstrap.md If primary bootstrap peers fail, this strategy attempts to connect using default peers and includes a timeout with a fallback to force refresh if necessary. It also warns if the routing table remains empty. ```go bootstrapPeers := dht.GetDefaultBootstrapPeerAddrInfos() dht, _ := dht.New(ctx, host, dht.BootstrapPeers(bootstrapPeers...)) ctx, cancel := context.WithTimeout(ctx, 30*time.Second) def cancel() err := dht.Bootstrap(ctx) if err != nil { log.Printf("Bootstrap failed: %v, trying force refresh", err) <-dht.ForceRefresh() } if dht.RoutingTable().Size() == 0 { log.Println("Warning: routing table is empty") } ``` -------------------------------- ### Create New IpfsDHT in Client Mode Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/ipfsdht.md Convenience constructor to create an IpfsDHT instance that operates exclusively in client mode, only querying other peers. It will not respond to incoming DHT queries. Panics if initialization fails. Requires a datastore for record persistence. ```go dht := dht.NewDHTClient(context.Background(), host, datastore) def dht.Close() ``` -------------------------------- ### Set Static Bootstrap Peers Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/configuration.md Use BootstrapPeers to provide a fixed list of initial peers for the DHT. This is useful when you have a known set of bootstrap nodes. ```go peers := []peer.AddrInfo{peer1, peer2, peer3} dht, _ := dht.New(ctx, host, dht.BootstrapPeers(peers...), ) ``` -------------------------------- ### Configure Standard Bootstrap Timeout (WAN) Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/bootstrap.md Use a standard timeout for Wide Area Network bootstrap. This provides a balance between responsiveness and allowing sufficient time for remote peers to connect. ```go ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) def cancel() dht.Bootstrap(ctx) ``` -------------------------------- ### Configure Aggressive Bootstrap Timeout (Slow Networks) Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/bootstrap.md Employ an aggressive timeout for bootstrap operations on slow or unreliable networks. This allows a longer duration for peers to establish connections. ```go ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) def cancel() dht.Bootstrap(ctx) ``` -------------------------------- ### DHTOption Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/dual-dht.md Creates an option that applies the given DHT options to both WAN and LAN DHT instances. This is useful for applying common configurations to both. ```APIDOC ## DHTOption ### Description Creates an option that applies the given DHT options to both WAN and LAN DHT instances. ### Method Signature ```go func DHTOption(opts ...dht.Option) Option ``` ### Parameters #### Variadic Parameters - **opts** (...dht.Option) - Required - DHT configuration options ### Returns - **Option** - An option that modifies both DHT instances. ### Example ```go dualDHT, _ := dual.New(ctx, h, dual.DHTOption( dht.Validator(customValidator), dht.MaxRecordAge(1*time.Hour), ), ) ``` ``` -------------------------------- ### Configure DHT Mode Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/configuration.md Sets the operating mode for the DHT. Use ModeServer to enable responding to incoming queries. ```go dht, err := dht.New(ctx, host, dht.Mode(dht.ModeServer), ) ``` -------------------------------- ### Create New IpfsDHT in Server Mode Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/ipfsdht.md Convenience constructor to create an IpfsDHT instance that operates exclusively in server mode, responding to incoming DHT queries. Panics if initialization fails. Requires a datastore for record persistence. ```go dht := dht.NewDHT(context.Background(), host, datastore) def dht.Close() ``` -------------------------------- ### Announce Content Provider Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/ipfsdht.md Use Provide to announce that this node can provide the content identified by a CID. The node announces itself as a provider to peers closest to the content hash. The 'brdcst' parameter is unused. ```go c, _ := cid.Parse("QmXxxx...") err := dht.Provide(ctx, c, true) if err != nil { log.Printf("Failed to announce provider: %v", err) } ``` -------------------------------- ### Bootstrap Kademlia DHT Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/ipfsdht.md Call Bootstrap after DHT creation to populate the routing table from bootstrap peers. This method queries bootstrap peers to discover network peers and fill the table. Ensure context is managed for operation timeouts and cancellation. ```go dht, _ := dht.New(ctx, host) defer dht.Close() if err := dht.Bootstrap(ctx); err != nil { log.Printf("Bootstrap failed: %v", err) } // Now routing table is seeded with network peers ``` -------------------------------- ### New Dual DHT Constructor Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/dual-dht.md Creates a new Dual DHT instance with separate WAN and LAN routing tables. The WAN DHT is for public addresses and global routing, while the LAN DHT is for private addresses and local routing. Both operate with independent protocol prefixes. ```APIDOC ## New Dual DHT Constructor ### Description Creates a new Dual DHT with separate WAN and LAN routing tables. The WAN DHT filters for public addresses only, while the LAN DHT filters for private addresses. Both instances operate with independent protocol prefixes. ### Function Signature ```go func New(ctx context.Context, h host.Host, options ...Option) (*DHT, error) ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters Table | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | ctx | context.Context | Yes | — | Context for DHT lifetime management | | h | host.Host | Yes | — | libp2p host instance | | options | ...Option | No | — | Configuration options for WAN/LAN instances | ### Returns - `*DHT`: Pointer to initialized Dual DHT. - `error`: Error on failure (e.g., invalid configuration, WAN/LAN DHT creation failure). ### Example ```go ctx := context.Background() h, _ := libp2p.New() dualDHT, err := dual.New(ctx, h) if err != nil { log.Fatal(err) } defer dualDHT.Close() ``` ``` -------------------------------- ### Configure Crawler Protocols Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/crawler.md Sets the DHT protocols the crawler will use when querying peers. Specify the protocol IDs to support. ```go c, _ := crawler.NewDefaultCrawler(host, crawler.WithProtocols([]protocol.ID{"/ipfs/kad/1.0.0"}), ) ``` -------------------------------- ### Provide Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/fullrt.md Announces this node as a provider for the given content. Sends provider announcements to k closest peers. ```APIDOC ## Provide ### Description Announces this node as a provider for the given content. Sends provider announcements to k closest peers. ### Method POST ### Endpoint /provide/{key} ### Parameters #### Path Parameters - **key** (cid.Cid) - Required - Content identifier #### Query Parameters - **ctx** (context.Context) - Required - Context for timeout - **brdcst** (bool) - Required - Unused (interface compatibility) ### Request Example ```json { "key": "QmXxxx...", "brdcst": true } ``` ### Response #### Success Response (200) - **message** (string) - Indicates success. ### Error Handling - Error if announcement fails. ``` -------------------------------- ### Use Default IPFS Bootstrap Peers Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/bootstrap.md For public networks, utilize the default IPFS bootstrap peers. This is the standard approach for connecting to the public IPFS network. ```go dht, _ := dht.New(ctx, host, dht.BootstrapPeers(dht.GetDefaultBootstrapPeerAddrInfos()...), ) dht.Bootstrap(ctx) ``` -------------------------------- ### Configure Datastore for DHT Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/configuration.md Sets the datastore for persisting DHT records. Use a persistent datastore like Pebble for production environments. ```go // Use Pebble datastore for persistence store, _ := pebbleds.NewDatastore("/tmp/dht", nil) dht, _ := dht.New(ctx, host, dht.Datastore(store), ) ``` -------------------------------- ### Configure Default Provider Manager Options Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/configuration.md Pass options to the default provider manager when not using a custom ProviderStore. This allows fine-tuning of the default behavior. ```go dht, _ := dht.New(ctx, host, dht.ProviderManagerOpts( records.GcInterval(1*time.Hour), ), ) ``` -------------------------------- ### Configure Crawler Parallelism Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/crawler.md Sets the maximum number of concurrent peer queries. Higher parallelism speeds up crawling but uses more resources. ```go c, _ := crawler.NewDefaultCrawler(host, crawler.WithParallelism(30), ) ``` -------------------------------- ### Provide Operation Flow Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/internal-architecture.md Illustrates the sequence of operations for the Provide operation in the DHT. This involves storing a value locally and then propagating it to closest peers. ```text PutValue() call ↓ Get k closest peers (GetClosestPeers query) ↓ Store value in local datastore ↓ Send PutValue to k closest peers ↓ Wait for responses from all k peers ↓ Return (success if at least one peer stored) ``` -------------------------------- ### Configure LAN DHT Instance Options Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/dual-dht.md Use LanDHTOption to apply specific DHT configurations exclusively to the LAN DHT instance. This is useful for disabling features like auto-refresh or setting the mode to server for LAN-specific behavior. ```go dualDHT, _ := dual.New(ctx, h, dual.LanDHTOption( dht.DisableAutoRefresh(), dht.Mode(dht.ModeServer), ), ) ``` -------------------------------- ### Provide Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/ipfsdht.md Announces that this node can provide the content identified by the given CID. The node announces itself as a provider to peers closest to the content hash. ```APIDOC ## Provide ### Description Announces that this node can provide the content identified by the given CID. The node announces itself as a provider to peers closest to the content hash. ### Method POST ### Endpoint /ipfs/dht/provide ### Parameters #### Path Parameters - **key** (cid.Cid) - Required - The content identifier to provide. #### Query Parameters - **brdcst** (bool) - Required - Unused (kept for interface compatibility). ### Request Example ```go c, _ := cid.Parse("QmXxxx...") err := dht.Provide(ctx, c, true) if err != nil { log.Printf("Failed to announce provider: %v", err) } ``` ### Response #### Success Response (200) - **None** - Returns an error if announcement fails. #### Response Example ```json null ``` **Error conditions:** - Providers disabled (routing.ErrNotSupported) - Invalid CID - Network errors during provider announcement ``` -------------------------------- ### NewFullRT Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/fullrt.md Creates a new accelerated DHT client that tracks the full network. FullRT maintains an XOR-based trie structure for routing table storage instead of the standard k-bucket structure, allowing it to track more comprehensive peer information. ```APIDOC ## NewFullRT ### Description Creates a new accelerated DHT client that tracks the full network. FullRT maintains an XOR-based trie structure for routing table storage instead of the standard k-bucket structure, allowing it to track more comprehensive peer information. ### Method Constructor ### Parameters #### Path Parameters - **h** (host.Host) - Required - libp2p host instance - **protocolPrefix** (protocol.ID) - Required - Protocol prefix (e.g., /ipfs for /ipfs/kad/1.0.0) - **options** (...Option) - Optional - FullRT configuration options ### Response Pointer to initialized FullRT instance, or error on failure. ### Error conditions: - Invalid protocol prefix - Host initialization failure - Resource Manager limits exceeded - Invalid configuration options ``` -------------------------------- ### NewDHTClient Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/ipfsdht.md Convenience constructor that creates a DHT in client mode (querier only). The DHT will not respond to incoming DHT queries. Panics if initialization fails. ```APIDOC ## NewDHTClient ### Description Convenience constructor that creates a DHT in client mode (querier only). The DHT will not respond to incoming DHT queries. Panics if initialization fails. ### Parameters #### Path Parameters - **ctx** (context.Context) - Required - Context for DHT lifetime - **h** (host.Host) - Required - libp2p host instance - **dstore** (ds.Batching) - Required - Datastore for persisting records ### Returns Initialized IpfsDHT instance in client mode. Panics on error. ### Example: ```go dht := dht.NewDHTClient(context.Background(), host, datastore) defuncel() ``` ``` -------------------------------- ### Bootstrap DHT Routing Table Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/bootstrap.md Connects to bootstrap peers, queries their routing tables, and adds discovered peers to the DHT's routing table. Handles errors if all bootstrap attempts fail. ```go dht, _ := dht.New(ctx, host, dht.BootstrapPeers(peers...)) // Bootstrap the routing table if err := dht.Bootstrap(ctx); err != nil { log.Printf("Warning: bootstrap failed: %v", err) // Can continue, but routing table may be empty } // Wait for bootstrap to propagate time.Sleep(1 * time.Second) // Now the routing table is populated log.Printf("Routing table has %d peers", dht.RoutingTable().Size()) ``` -------------------------------- ### FindProviders Operation Flow Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/internal-architecture.md Details the steps involved in the FindProviders operation. It includes querying local stores, streaming results, and recursively querying peers for more providers. ```text FindProviders() call ↓ GetProviders query (like GetClosestPeers but for providers) ↓ Check local provider store ↓ Stream providers to caller ↓ Query closest peers for more providers ↓ Continue until count reached or timeout ↓ Return all found providers ``` -------------------------------- ### Create Custom Address Filters Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/filters.md Create custom filters by providing a function to AddressFilter(). This allows for custom filtering logic. ```go dht, _ := dht.New(ctx, host, dht.AddressFilter(func(addrs []ma.Multiaddr) []ma.Multiaddr { var filtered []ma.Multiaddr for _, addr := range addrs { // Custom filtering logic if shouldKeep(addr) { filtered = append(filtered, addr) } } return filtered }), ) ``` -------------------------------- ### Use Dual WAN/LAN Routing Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/00-START-HERE.md Sets up a DHT that automatically manages both public (WAN) and private (LAN) peers. Queries are intelligently routed to the appropriate network segment. ```go // Automatically manages public and private peers dual, _ := dual.New(ctx, h) defer dual.Close() // Queries go to the right DHT providers, _ := dual.FindProviders(ctx, cid) ``` -------------------------------- ### Asynchronously Find Providers for Content Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/fullrt.md Asynchronously searches for providers of a given content CID and streams results as they arrive. Returns immediately with a channel. Specify the desired number of providers. ```go func (frt *FullRT) FindProvidersAsync(ctx context.Context, key cid.Cid, count int) <-chan peer.AddrInfo ``` -------------------------------- ### Configure Kademlia Bucket Size Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/configuration.md Sets the k parameter (bucket size) for the Kademlia routing table. The default value is 20, matching standard IPFS configurations. ```go dht, _ := dht.New(ctx, host, dht.BucketSize(20), ) ``` -------------------------------- ### NewDHT Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/ipfsdht.md Convenience constructor that creates a DHT in server mode (responder). The DHT will respond to incoming DHT queries from other peers. Panics if initialization fails. ```APIDOC ## NewDHT ### Description Convenience constructor that creates a DHT in server mode (responder). The DHT will respond to incoming DHT queries from other peers. Panics if initialization fails. ### Parameters #### Path Parameters - **ctx** (context.Context) - Required - Context for DHT lifetime - **h** (host.Host) - Required - libp2p host instance - **dstore** (ds.Batching) - Required - Datastore for persisting records ### Returns Initialized IpfsDHT instance in server mode. Panics on error. ### Example: ```go dht := dht.NewDHT(context.Background(), host, datastore) defuncel() ``` ``` -------------------------------- ### Define AddrInfo Struct Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/types.md Defines the AddrInfo struct, which holds complete address information for a peer, including its ID and a slice of multiaddresses where it is reachable. ```go type AddrInfo struct { ID PeerID Addrs []ma.Multiaddr } ``` -------------------------------- ### Find Providers Asynchronously Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/ipfsdht.md Asynchronously searches for providers and streams results as they arrive. Use when you want to process providers as they are discovered without waiting for the entire search to complete. Errors are not explicitly returned; missing providers indicate failure. ```go c, _ := cid.Parse("QmXxxx...") providerChan := dht.FindProvidersAsync(ctx, c, 20) for provider := range providerChan { log.Printf("Found provider: %s", provider.ID) } ``` -------------------------------- ### Complete Network Discovery Source: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/_autodocs/api-reference/crawler.md This function demonstrates a complete network crawl using the crawler. It configures parallelism and message timeouts. The results are collected in a map of peer IDs to AddrInfo. ```go func discoverNetwork(ctx context.Context, h host.Host) (map[peer.ID]*peer.AddrInfo, error) { c, err := crawler.NewDefaultCrawler(h, crawler.WithParallelism(20), crawler.WithMsgTimeout(5*time.Second), ) if err != nil { return nil, err } discovered := make(map[peer.ID]*peer.AddrInfo) var mu sync.Mutex c.Run(ctx, bootstrapPeers, func(p peer.ID, rtPeers []*peer.AddrInfo) { mu.Lock() defer mu.Unlock() for _, pi := range rtPeers { if _, exists := discovered[pi.ID]; !exists { discovered[pi.ID] = pi } } }, func(p peer.ID, err error) { log.Debugf("Crawler query failed for %s: %v", p, err) }, ) return discovered, nil } ```