Skip to content

Commit b8a62e1

Browse files
committed
Added option to set DHT to client mode only and configure the cleanup interval
1 parent d7ceda3 commit b8a62e1

File tree

4 files changed

+481
-3
lines changed

4 files changed

+481
-3
lines changed

client.go

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919

2020
"github.com/libp2p/go-libp2p"
2121
dht "github.com/libp2p/go-libp2p-kad-dht"
22+
"github.com/libp2p/go-libp2p-kad-dht/records"
2223
pubsub "github.com/libp2p/go-libp2p-pubsub"
2324
"github.com/libp2p/go-libp2p/core/crypto"
2425
"github.com/libp2p/go-libp2p/core/host"
@@ -27,6 +28,9 @@ import (
2728
"github.com/libp2p/go-libp2p/p2p/discovery/mdns"
2829
drouting "github.com/libp2p/go-libp2p/p2p/discovery/routing"
2930
"github.com/multiformats/go-multiaddr"
31+
32+
ds "github.com/ipfs/go-datastore"
33+
dssync "github.com/ipfs/go-datastore/sync"
3034
)
3135

3236
var (
@@ -92,7 +96,7 @@ func NewClient(config Config) (Client, error) {
9296
}
9397

9498
// Set up DHT
95-
kadDHT, err := setupDHT(ctx, h, bootstrapPeers, clientLogger, cancel)
99+
kadDHT, err := setupDHT(ctx, h, config, bootstrapPeers, clientLogger, cancel)
96100
if err != nil {
97101
return nil, err
98102
}
@@ -204,8 +208,46 @@ func createHost(_ context.Context, hostOpts []libp2p.Option, config Config, rela
204208
return h, nil
205209
}
206210

207-
func setupDHT(ctx context.Context, h host.Host, bootstrapPeers []peer.AddrInfo, _ logger, cancel context.CancelFunc) (*dht.IpfsDHT, error) {
208-
kadDHT, err := dht.New(ctx, h, dht.Mode(dht.ModeServer), dht.BootstrapPeers(bootstrapPeers...))
211+
func setupDHT(ctx context.Context, h host.Host, config Config, bootstrapPeers []peer.AddrInfo, log logger, cancel context.CancelFunc) (*dht.IpfsDHT, error) {
212+
// Determine DHT mode (default to server)
213+
mode := dht.ModeServer
214+
if config.DHTMode == "client" {
215+
mode = dht.ModeClient
216+
log.Infof("DHT mode: client (query-only, no provider storage)")
217+
} else {
218+
log.Infof("DHT mode: server (will advertise and store provider records)")
219+
}
220+
221+
// Build DHT options
222+
dhtOpts := []dht.Option{
223+
dht.Mode(mode),
224+
dht.BootstrapPeers(bootstrapPeers...),
225+
}
226+
227+
// If server mode and custom cleanup interval specified, configure ProviderManager
228+
if mode == dht.ModeServer && config.DHTCleanupInterval > 0 {
229+
log.Infof("Configuring DHT cleanup interval: %v", config.DHTCleanupInterval)
230+
231+
// Create an in-memory datastore for the provider manager
232+
// Same as default DHT datastore creation
233+
datastore := dssync.MutexWrap(ds.NewMapDatastore())
234+
235+
providerManager, err := records.NewProviderManager(
236+
ctx,
237+
h.ID(),
238+
h.Peerstore(),
239+
datastore,
240+
records.CleanupInterval(config.DHTCleanupInterval),
241+
)
242+
if err != nil {
243+
_ = h.Close()
244+
cancel()
245+
return nil, fmt.Errorf("failed to create provider manager: %w", err)
246+
}
247+
dhtOpts = append(dhtOpts, dht.ProviderStore(providerManager))
248+
}
249+
250+
kadDHT, err := dht.New(ctx, h, dhtOpts...)
209251
if err != nil {
210252
_ = h.Close()
211253
cancel()

config.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,4 +79,22 @@ type Config struct {
7979
// If not provided, bootstrap peers will be used as relays.
8080
// Example: []string{"/ip4/1.2.3.4/tcp/4001/p2p/QmPeerID"}
8181
RelayPeers []string
82+
83+
// DHTMode specifies whether this node runs the DHT in client or server mode.
84+
// Valid values: "client", "server"
85+
// - "client": Can query DHT but doesn't advertise itself or store provider records.
86+
// No ProviderManager cleanup overhead.
87+
// - "server": Participates fully in DHT, advertises itself, stores provider records.
88+
// Has periodic cleanup overhead. Default mode for proper P2P networks.
89+
// If not provided or empty, defaults to "server" mode.
90+
DHTMode string
91+
92+
// DHTCleanupInterval is the interval at which the DHT's ProviderManager performs
93+
// garbage collection of expired provider records. The cleanup involves querying all
94+
// provider records and removing expired entries.
95+
// Only applies when DHTMode is "server".
96+
// If not provided or zero, uses the DHT default (1 hour).
97+
// Recommended: 6-24 hours for production to reduce CPU overhead.
98+
// The cleanup frequency trades off between memory usage (stale records) and CPU usage.
99+
DHTCleanupInterval time.Duration
82100
}

0 commit comments

Comments
 (0)