From e5a3edb5bb19ce1c84a131da95118468e6518ef2 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Thu, 19 Sep 2024 21:50:08 +0200 Subject: [PATCH] refactor: amino dht package the intention here is to have public source of truth we can reference rather than hardcoding the same amino defaults everywhere --- amino/defaults.go | 57 ++++++++++++++++++++++++++++++++++ crawler/options.go | 3 +- dht_options.go | 11 ++++--- internal/config/config.go | 16 +++++----- protocol.go | 5 +-- providers/providers_manager.go | 5 +-- 6 files changed, 79 insertions(+), 18 deletions(-) create mode 100644 amino/defaults.go diff --git a/amino/defaults.go b/amino/defaults.go new file mode 100644 index 000000000..2d702450b --- /dev/null +++ b/amino/defaults.go @@ -0,0 +1,57 @@ +// Package amino provides protocol parameters and suggested default values for the [Amino DHT]. +// +// [Amino DHT] is an implementation of the Kademlia distributed hash table (DHT) algorithm, +// originally designed for use in IPFS (InterPlanetary File System) network. +// This package defines key constants and protocol identifiers used in the Amino DHT implementation. +// +// [Amino DHT]: https://probelab.io/ipfs/amino/ +package amino + +import ( + "time" + + "github.com/libp2p/go-libp2p/core/protocol" +) + +const ( + // ProtocolPrefix is the base prefix for Amono DHT protocols. + ProtocolPrefix protocol.ID = "/ipfs" + + // ProtocolID is the latest protocol identifier for the Amino DHT. + ProtocolID protocol.ID = "/ipfs/kad/1.0.0" + + // DefaultBucketSize is the Amino DHT bucket size (k in the Kademlia paper). + // It represents the maximum number of peers stored in each + // k-bucket of the routing table. + DefaultBucketSize = 20 + + // DefaultConcurrency is the suggested number of concurrent requests (alpha + // in the Kademlia paper) for a given query path in Amino DHT. It + // determines how many parallel lookups are performed during network + // traversal. + DefaultConcurrency = 10 + + // DefaultResiliency is the suggested number of peers closest to a target + // that must have responded in order for a given query path to complete in + // Amino DHT. This helps ensure reliable results by requiring multiple + // confirmations. + DefaultResiliency = 3 + + // DefaultProvideValidity is the default time that a Provider Record should + // last on Amino DHT before it needs to be refreshed or removed. This value + // is also known as Provider Record Expiration Interval. + DefaultProvideValidity = 48 * time.Hour + + // DefaultProviderAddrTTL is the TTL to keep the multi addresses of + // provider peers around. Those addresses are returned alongside provider. + // After it expires, the returned records will require an extra lookup, to + // find the multiaddress associated with the returned peer id. + DefaultProviderAddrTTL = 24 * time.Hour +) + +var ( + // Protocols is a slice containing all supported protocol IDs for Amino DHT. + // Currently, it only includes the main ProtocolID, but it's defined as a slice + // to allow for potential future protocol versions or variants. + Protocols = []protocol.ID{ProtocolID} +) diff --git a/crawler/options.go b/crawler/options.go index 8c7602fb0..649b4d6f6 100644 --- a/crawler/options.go +++ b/crawler/options.go @@ -3,6 +3,7 @@ package crawler import ( "time" + "github.com/libp2p/go-libp2p-kad-dht/amino" "github.com/libp2p/go-libp2p/core/protocol" ) @@ -20,7 +21,7 @@ type options struct { // defaults are the default crawler options. This option will be automatically // prepended to any options you pass to the crawler constructor. var defaults = func(o *options) error { - o.protocols = []protocol.ID{"/ipfs/kad/1.0.0"} + o.protocols = amino.Protocols o.parallelism = 1000 o.connectTimeout = time.Second * 5 o.perMsgTimeout = time.Second * 5 diff --git a/dht_options.go b/dht_options.go index 250e4ca63..45d6e84bb 100644 --- a/dht_options.go +++ b/dht_options.go @@ -5,6 +5,7 @@ import ( "testing" "time" + "github.com/libp2p/go-libp2p-kad-dht/amino" dhtcfg "github.com/libp2p/go-libp2p-kad-dht/internal/config" "github.com/libp2p/go-libp2p-kad-dht/providers" "github.com/libp2p/go-libp2p-kbucket/peerdiversity" @@ -32,7 +33,7 @@ const ( ) // DefaultPrefix is the application specific prefix attached to all DHT protocols by default. -const DefaultPrefix protocol.ID = "/ipfs" +const DefaultPrefix protocol.ID = amino.ProtocolPrefix type Option = dhtcfg.Option @@ -134,7 +135,7 @@ func NamespacedValidator(ns string, v record.Validator) Option { // ProtocolPrefix sets an application specific prefix to be attached to all DHT protocols. For example, // /myapp/kad/1.0.0 instead of /ipfs/kad/1.0.0. Prefix should be of the form /myapp. // -// Defaults to dht.DefaultPrefix +// Defaults to amino.ProtocolPrefix func ProtocolPrefix(prefix protocol.ID) Option { return func(c *dhtcfg.Config) error { c.ProtocolPrefix = prefix @@ -165,7 +166,7 @@ func V1ProtocolOverride(proto protocol.ID) Option { // BucketSize configures the bucket size (k in the Kademlia paper) of the routing table. // -// The default value is 20. +// The default value is amino.DefaultBucketSize func BucketSize(bucketSize int) Option { return func(c *dhtcfg.Config) error { c.BucketSize = bucketSize @@ -175,7 +176,7 @@ func BucketSize(bucketSize int) Option { // Concurrency configures the number of concurrent requests (alpha in the Kademlia paper) for a given query path. // -// The default value is 10. +// The default value is amino.DefaultConcurrency func Concurrency(alpha int) Option { return func(c *dhtcfg.Config) error { c.Concurrency = alpha @@ -186,7 +187,7 @@ func Concurrency(alpha int) Option { // Resiliency configures the number of peers closest to a target that must have responded in order for a given query // path to complete. // -// The default value is 3. +// The default value is amino.DefaultResiliency func Resiliency(beta int) Option { return func(c *dhtcfg.Config) error { c.Resiliency = beta diff --git a/internal/config/config.go b/internal/config/config.go index bacd2e4df..ea8678458 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -7,6 +7,7 @@ import ( "github.com/ipfs/boxo/ipns" ds "github.com/ipfs/go-datastore" dssync "github.com/ipfs/go-datastore/sync" + "github.com/libp2p/go-libp2p-kad-dht/amino" "github.com/libp2p/go-libp2p-kad-dht/providers" "github.com/libp2p/go-libp2p-kbucket/peerdiversity" record "github.com/libp2p/go-libp2p-record" @@ -17,9 +18,7 @@ import ( ) // DefaultPrefix is the application specific prefix attached to all DHT protocols by default. -const DefaultPrefix protocol.ID = "/ipfs" - -const defaultBucketSize = 20 +const DefaultPrefix protocol.ID = amino.ProtocolPrefix // ModeOpt describes what mode the dht should operate in type ModeOpt int @@ -123,9 +122,9 @@ var Defaults = func(o *Config) error { o.MaxRecordAge = providers.ProvideValidity - o.BucketSize = defaultBucketSize - o.Concurrency = 10 - o.Resiliency = 3 + o.BucketSize = amino.DefaultBucketSize + o.Concurrency = amino.DefaultConcurrency + o.Resiliency = amino.DefaultResiliency o.LookupCheckConcurrency = 256 // MAGIC: It makes sense to set it to a multiple of OptProvReturnRatio * BucketSize. We chose a multiple of 4. @@ -135,11 +134,12 @@ var Defaults = func(o *Config) error { } func (c *Config) Validate() error { + // Configuration is validated and enforced only if prefix matches Amino DHT if c.ProtocolPrefix != DefaultPrefix { return nil } - if c.BucketSize != defaultBucketSize { - return fmt.Errorf("protocol prefix %s must use bucket size %d", DefaultPrefix, defaultBucketSize) + if c.BucketSize != amino.DefaultBucketSize { + return fmt.Errorf("protocol prefix %s must use bucket size %d", DefaultPrefix, amino.DefaultBucketSize) } if !c.EnableProviders { return fmt.Errorf("protocol prefix %s must have providers enabled", DefaultPrefix) diff --git a/protocol.go b/protocol.go index 5e1334d13..3081a57d9 100644 --- a/protocol.go +++ b/protocol.go @@ -1,12 +1,13 @@ package dht import ( + "github.com/libp2p/go-libp2p-kad-dht/amino" "github.com/libp2p/go-libp2p/core/protocol" ) var ( // ProtocolDHT is the default DHT protocol. - ProtocolDHT protocol.ID = "/ipfs/kad/1.0.0" + ProtocolDHT protocol.ID = amino.ProtocolID // DefaultProtocols spoken by the DHT. - DefaultProtocols = []protocol.ID{ProtocolDHT} + DefaultProtocols = amino.Protocols ) diff --git a/providers/providers_manager.go b/providers/providers_manager.go index 1400dc76c..d740297a7 100644 --- a/providers/providers_manager.go +++ b/providers/providers_manager.go @@ -14,6 +14,7 @@ import ( "github.com/ipfs/go-datastore/autobatch" dsq "github.com/ipfs/go-datastore/query" logging "github.com/ipfs/go-log/v2" + "github.com/libp2p/go-libp2p-kad-dht/amino" "github.com/libp2p/go-libp2p-kad-dht/internal" "github.com/libp2p/go-libp2p/core/peer" "github.com/libp2p/go-libp2p/core/peerstore" @@ -30,12 +31,12 @@ const ( // peers around. Those addresses are returned alongside provider. After // it expires, the returned records will require an extra lookup, to // find the multiaddress associated with the returned peer id. - ProviderAddrTTL = 24 * time.Hour + ProviderAddrTTL = amino.DefaultProviderAddrTTL ) // ProvideValidity is the default time that a Provider Record should last on DHT // This value is also known as Provider Record Expiration Interval. -var ProvideValidity = time.Hour * 48 +var ProvideValidity = amino.DefaultProvideValidity var defaultCleanupInterval = time.Hour var lruCacheSize = 256 var batchBufferSize = 256