---
# System prepended metadata

title: Modular DHT - High Level Package Design

---

# Modular DHT - High Level Package Design

This idea draws some inspiration for package design from Go's [fs](https://pkg.go.dev/io/fs) package. The principle here is that key algorithms are implemented as free functions ([Glob](https://pkg.go.dev/io/fs#Glob), [ReadFile](https://pkg.go.dev/io/fs#ReadFile), [WalkDir](https://pkg.go.dev/io/fs#WalkDir)) that act on a simple data type interface ([FS](https://pkg.go.dev/io/fs#FS)). The interface can be specialised for more efficient implementations of the generic algorithm. For example the `ReadFile` function tests whether the passed `FS` implements the [ReadFileFS](https://pkg.go.dev/io/fs#ReadFileFS) interfacce and, if so, calls the optimized `ReadFile` method on the passed type.


## DHT Package

The key algorithms for the DHT package are:

```Go
func FindPeer(ctx context.Context, t DHT, p peer.ID) (peer.AddrInfo, error)
```

If `t` implements `FindPeerDHT`, `FindPeer` calls `t.FindPeer`. Otherwise `FindPeer` calls `t.FindClosestPeers` recursively until the peer is found.

```Go
func GetValue(ctx context.Context, t DHT, key string, q int) (*Record, error) 
```

If `t` implements `ValueDHT`, `FindPeer` calls `t.GetValue`. Otherwise `GetValue` calls `t.FindClosestPeers` recursively until `q` values that agree have been returned (a quorum).
    
    
```Go    
func SetValue(ctx context.Context, t DHT, key string, r *Record) error
```

If `t` implements `ValueDHT`, `FindPeer` calls `t.SetValue`. Otherwise `SetValue` calls `t.FindClosestPeers` recursively until `k` peers have been found then invokes the `PUT_VALUE` RPC on each discovered peer.


```Go
func FindFeaturePeers(ctx context.Context, t DHT, f feature.ID, n int) ([]peer.AddrInfo, error)
```

`FindFeaturePeers` calls `t.FindClosestPeers` recursively until `n` peers have been found that support the given feature.


The fundamental type is `DHT`:

```Go
type DHT interface {
    FindClosestPeers(ctx context.Context, key string, n int) ([]peer.AddrInfo, error)
}

```

Some specialized DHT interfaces that allow implementations to provide optimized versions of algorithms:

```Go
type FindPeerDHT interface {
    DHT
    
    FindPeer(ctx context.Context, p peer.ID) (peer.AddrInfo, error)
}

```

```Go
type ValueDHT interface {
    DHT
    
    GetValue(ctx context.Context, key string, q int) (*Record, error)
    SetValue(ctx context.Context, key string, r *Record) error
}

```




## IPFS Feature Package

The ipfs feature package provides IPFS-specific protocol features using the  types and algorithms provided by the DHT package.


```Go
func FindProviders(ctx context.Context, t DHT, c cid.Cid) ([]peer.AddrInfo, error)
```

If `t` implements `FindProvidersDHT`, `FindProviders` calls `t.FindProviders`. Otherwise `FindProviders` calls `t.FindFeaturePeers` passing the `IPFSGetProviders` feature and sends the RPC `GET_PROVIDERS` to the peers recursively until enough provider peers are found.



```Go
func Provide(ctx context.Context, t DHT, p peer.ID, c cid.Cid) error
```

If `t` implements `ProvideDHT`, `Provide` calls `t.Provide`. Otherwise `Provide` calls `t.FindFeaturePeers` with the `IPFSProvide` feature and sends the RPC `ADD_PROVIDER` to the discovered peers.


FindProvidersDHT allows DHT implementations to signal that they have an optimized version of the FindProviders algorithm.


```Go
type FindProvidersDHT interface {
    dht.DHT
    
    FindProviders(ctx context.Context, c cid.Cid) ([]peer.AddrInfo, error)
}
```

ProvideDHT allows DHT implementations to signal that they have an optimized version of the Provide algorithm.

```Go
type ProvideDHT interface {
    dht.DHT
    
    Provide(ctx context.Context, p peer.ID, c cid.Cid) error
}

```