@cryptotaxi247 / kubo / commits / 36b28a0af

fix(config): wire up `Provider.Enabled` flag (#10804)

* fix(config): explicit Provider.Enabled flag Adds missing config option described in https://github.com/ipfs/kubo/issues/10803 * refactor: remove Experimental.StrategicProviding removing experiment, replaced with Provider.Enabled * test(cli): routing [re]provide updated and added tests for manually triggering provide and reprovide and making them respect global configuration flag to avoid inconsistent behaviors * docs: improve DelegatedRouters * refactor: default DefaultProviderWorkerCount=16 - simplified default for both - 16 is safer for non-accelerated DHT client - acceletated DHT performs better without limit anyway - updated docs (cherry picked from commit 2ab3f58c992104bac45fbc204d5475300d250355)

Marcin Rataj committed May 15, 2025 at 19:19 UTC 36b28a0af240c5da982f9527670b1fe343ca7be4
13 files changed +193 -84
cmd/ipfs/kubo/daemon.go
+12 -5
@@ -491,6 +491,11 @@ func daemonFunc(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment
491 if cfg.Provider.Strategy.WithDefault("") != "" && cfg.Reprovider.Strategy.IsDefault() {
492 log.Fatal("Invalid config. Remove unused Provider.Strategy and set Reprovider.Strategy instead. Documentation: https://github.com/ipfs/kubo/blob/master/docs/config.md#reproviderstrategy")
493 }
494 + if cfg.Experimental.StrategicProviding {
495 + log.Error("Experimental.StrategicProviding was removed. Remove it from your config and set Provider.Enabled=false to remove this message. Documentation: https://github.com/ipfs/kubo/blob/master/docs/experimental-features.md#strategic-providing")
496 + cfg.Experimental.StrategicProviding = false
497 + cfg.Provider.Enabled = config.False
498 + }
499
500 printLibp2pPorts(node)
501
@@ -625,17 +630,19 @@ take effect.
630 }()
631
632 if !offline {
628 - // Warn users who were victims of 'lowprofile' footgun (https://github.com/ipfs/kubo/pull/10524)
629 - if cfg.Experimental.StrategicProviding {
633 + // Warn users when provide systems are disabled
634 + if !cfg.Provider.Enabled.WithDefault(config.DefaultProviderEnabled) {
635 fmt.Print(`
631 -⚠️ Reprovide system is disabled due to 'Experimental.StrategicProviding=true'
636 +
637 +⚠️ Provide and Reprovide systems are disabled due to 'Provide.Enabled=false'
638 ⚠️ Local CIDs will not be announced to Amino DHT, making them impossible to retrieve without manual peering
633 -⚠️ If this is not intentional, call 'ipfs config profile apply announce-on'
639 +⚠️ If this is not intentional, call 'ipfs config profile apply announce-on' or set Provide.Enabled=true'
640
641 `)
642 } else if cfg.Reprovider.Interval.WithDefault(config.DefaultReproviderInterval) == 0 {
643 fmt.Print(`
638 -⚠️ Reprovider system is disabled due to 'Reprovider.Interval=0'
644 +
645 +⚠️ Provide and Reprovide systems are disabled due to 'Reprovider.Interval=0'
646 ⚠️ Local CIDs will not be announced to Amino DHT, making them impossible to retrieve without manual peering
647 ⚠️ If this is not intentional, call 'ipfs config profile apply announce-on', or set 'Reprovider.Interval=22h'
648
config/experiments.go
+1 -1
@@ -6,7 +6,7 @@ type Experiments struct {
6 ShardingEnabled bool `json:",omitempty"` // deprecated by autosharding: https://github.com/ipfs/kubo/pull/8527
7 Libp2pStreamMounting bool
8 P2pHttpProxy bool //nolint
9 - StrategicProviding bool
9 + StrategicProviding bool `json:",omitempty"` // removed, use Provider.Enabled instead
10 OptimisticProvide bool
11 OptimisticProvideJobsPoolSize int
12 GatewayOverLibp2p bool `json:",omitempty"`
config/profile.go
+4 -4
@@ -270,7 +270,7 @@ fetching may be degraded.
270 },
271 },
272 "announce-off": {
273 - Description: `Disables Reprovide system (and announcing to Amino DHT).
273 + Description: `Disables Provide and Reprovide systems (announcing to Amino DHT).
274
275 USE WITH CAUTION:
276 The main use case for this is setups with manual Peering.Peers config.
@@ -279,16 +279,16 @@ fetching may be degraded.
279 one hosting it, and other peers are not already connected to it.
280 `,
281 Transform: func(c *Config) error {
282 + c.Provider.Enabled = False
283 c.Reprovider.Interval = NewOptionalDuration(0) // 0 disables periodic reprovide
283 - c.Experimental.StrategicProviding = true // this is not a typo (the name is counter-intuitive)
284 return nil
285 },
286 },
287 "announce-on": {
288 - Description: `Re-enables Reprovide system (reverts announce-off profile).`,
288 + Description: `Re-enables Provide and Reprovide systems (reverts announce-off profile).`,
289 Transform: func(c *Config) error {
290 + c.Provider.Enabled = True
291 c.Reprovider.Interval = NewOptionalDuration(DefaultReproviderInterval) // have to apply explicit default because nil would be ignored
291 - c.Experimental.StrategicProviding = false // this is not a typo (the name is counter-intuitive)
292 return nil
293 },
294 },
config/provider.go
+3 -1
@@ -1,12 +1,14 @@
1 package config
2
3 const (
4 - DefaultProviderWorkerCount = 64
4 + DefaultProviderEnabled = true
5 + DefaultProviderWorkerCount = 16
6 )
7
8 // Provider configuration describes how NEW CIDs are announced the moment they are created.
9 // For periodical reprovide configuration, see Reprovider.*
10 type Provider struct {
11 + Enabled Flag `json:",omitempty"`
12 Strategy *OptionalString `json:",omitempty"` // Unused, you are likely looking for Reprovider.Strategy instead
13 WorkerCount *OptionalInteger `json:",omitempty"` // Number of concurrent provides allowed, 0 means unlimited
14 }
config/routing.go
+2 -1
@@ -48,10 +48,11 @@ type Routing struct {
48
49 IgnoreProviders []string `json:",omitempty"`
50
51 + // Simplified configuration used by default when Routing.Type=auto|autoclient
52 DelegatedRouters []string `json:",omitempty"`
53
54 + // Advanced configuration used when Routing.Type=custom
55 Routers Routers `json:",omitempty"`
54 -
56 Methods Methods `json:",omitempty"`
57 }
58
core/commands/routing.go
+21
@@ -9,6 +9,7 @@ import (
9 "strings"
10 "time"
11
12 + "github.com/ipfs/kubo/config"
13 cmdenv "github.com/ipfs/kubo/core/commands/cmdenv"
14
15 dag "github.com/ipfs/boxo/ipld/merkledag"
@@ -158,6 +159,14 @@ var provideRefRoutingCmd = &cmds.Command{
159 if !nd.IsOnline {
160 return ErrNotOnline
161 }
162 + // respect global config
163 + cfg, err := nd.Repo.Config()
164 + if err != nil {
165 + return err
166 + }
167 + if !cfg.Provider.Enabled.WithDefault(config.DefaultProviderEnabled) {
168 + return errors.New("invalid configuration: Provider.Enabled is set to 'false'")
169 + }
170
171 if len(nd.PeerHost.Network().Conns()) == 0 {
172 return errors.New("cannot provide, no connected peers")
@@ -254,6 +263,18 @@ Trigger reprovider to announce our data to network.
263 return ErrNotOnline
264 }
265
266 + // respect global config
267 + cfg, err := nd.Repo.Config()
268 + if err != nil {
269 + return err
270 + }
271 + if !cfg.Provider.Enabled.WithDefault(config.DefaultProviderEnabled) {
272 + return errors.New("invalid configuration: Provider.Enabled is set to 'false'")
273 + }
274 + if cfg.Reprovider.Interval.WithDefault(config.DefaultReproviderInterval) == 0 {
275 + return errors.New("invalid configuration: Reprovider.Interval is set to '0'")
276 + }
277 +
278 err = nd.Provider.Reprovide(req.Context)
279 if err != nil {
280 return err
core/node/bitswap.go
+4 -3
@@ -83,7 +83,7 @@ type bitswapIn struct {
83 // Bitswap creates the BitSwap server/client instance.
84 // If Bitswap.ServerEnabled is false, the node will act only as a client
85 // using an empty blockstore to prevent serving blocks to other peers.
86 -func Bitswap(serverEnabled bool) interface{} {
86 +func Bitswap(serverEnabled, libp2pEnabled, httpEnabled bool) interface{} {
87 return func(in bitswapIn, lc fx.Lifecycle) (*bitswap.Bitswap, error) {
88 var bitswapNetworks, bitswapLibp2p network.BitSwapNetwork
89 var bitswapBlockstore blockstore.Blockstore = in.Bs
@@ -93,7 +93,8 @@ func Bitswap(serverEnabled bool) interface{} {
93 bitswapLibp2p = bsnet.NewFromIpfsHost(in.Host)
94 }
95
96 - if httpCfg := in.Cfg.HTTPRetrieval; httpCfg.Enabled.WithDefault(config.DefaultHTTPRetrievalEnabled) {
96 + if httpEnabled {
97 + httpCfg := in.Cfg.HTTPRetrieval
98 maxBlockSize, err := humanize.ParseBytes(httpCfg.MaxBlockSize.WithDefault(config.DefaultHTTPRetrievalMaxBlockSize))
99 if err != nil {
100 return nil, err
@@ -136,7 +137,7 @@ func Bitswap(serverEnabled bool) interface{} {
137 return nil, err
138 }
139
139 - // Explicitly enable/disable server to ensure desired provide mode
140 + // Explicitly enable/disable server
141 in.BitswapOpts = append(in.BitswapOpts, bitswap.WithServerEnabled(serverEnabled))
142
143 bs := bitswap.New(helpers.LifecycleCtx(in.Mctx, lc), bitswapNetworks, providerQueryMgr, bitswapBlockstore, in.BitswapOpts...)
core/node/groups.go
+7 -5
@@ -337,16 +337,18 @@ func Online(bcfg *BuildCfg, cfg *config.Config, userResourceOverrides rcmgr.Part
337
338 isBitswapLibp2pEnabled := cfg.Bitswap.Libp2pEnabled.WithDefault(config.DefaultBitswapLibp2pEnabled)
339 isBitswapServerEnabled := cfg.Bitswap.ServerEnabled.WithDefault(config.DefaultBitswapServerEnabled)
340 + isHTTPRetrievalEnabled := cfg.HTTPRetrieval.Enabled.WithDefault(config.DefaultHTTPRetrievalEnabled)
341
341 - // Don't provide from bitswap when the legacy noop experiment "strategic provider service" is active
342 - isBitswapServerEnabled = isBitswapServerEnabled && !cfg.Experimental.StrategicProviding
342 + // Right now Provider and Reprovider systems are tied together - disabling Reprovider by setting interval to 0 disables Provider
343 + // and vice versa: Provider.Enabled=false will disable both Provider of new CIDs and the Reprovider of old ones.
344 + isProviderEnabled := cfg.Provider.Enabled.WithDefault(config.DefaultProviderEnabled) && cfg.Reprovider.Interval.WithDefault(config.DefaultReproviderInterval) != 0
345
346 return fx.Options(
347 fx.Provide(BitswapOptions(cfg)),
346 - fx.Provide(Bitswap(isBitswapServerEnabled)),
348 + fx.Provide(Bitswap(isBitswapServerEnabled, isBitswapLibp2pEnabled, isHTTPRetrievalEnabled)),
349 fx.Provide(OnlineExchange(isBitswapLibp2pEnabled)),
350 // Replace our Exchange with a Providing exchange!
349 - fx.Decorate(ProvidingExchange(isBitswapServerEnabled)),
351 + fx.Decorate(ProvidingExchange(isProviderEnabled && isBitswapServerEnabled)),
352 fx.Provide(DNSResolver),
353 fx.Provide(Namesys(ipnsCacheSize, cfg.Ipns.MaxCacheTTL.WithDefault(config.DefaultIpnsMaxCacheTTL))),
354 fx.Provide(Peering),
@@ -358,7 +360,7 @@ func Online(bcfg *BuildCfg, cfg *config.Config, userResourceOverrides rcmgr.Part
360
361 LibP2P(bcfg, cfg, userResourceOverrides),
362 OnlineProviders(
361 - cfg.Experimental.StrategicProviding,
363 + isProviderEnabled,
364 cfg.Reprovider.Strategy.WithDefault(config.DefaultReproviderStrategy),
365 cfg.Reprovider.Interval.WithDefault(config.DefaultReproviderInterval),
366 cfg.Routing.AcceleratedDHTClient.WithDefault(config.DefaultAcceleratedDHTClient),
core/node/provider.go
+2 -2
@@ -132,8 +132,8 @@ https://github.com/ipfs/kubo/blob/master/docs/config.md#routingaccelerateddhtcli
132 // ONLINE/OFFLINE
133
134 // OnlineProviders groups units managing provider routing records online
135 -func OnlineProviders(useStrategicProviding bool, reprovideStrategy string, reprovideInterval time.Duration, acceleratedDHTClient bool, provideWorkerCount int) fx.Option {
136 - if useStrategicProviding {
135 +func OnlineProviders(provide bool, reprovideStrategy string, reprovideInterval time.Duration, acceleratedDHTClient bool, provideWorkerCount int) fx.Option {
136 + if !provide {
137 return OfflineProviders()
138 }
139
docs/changelogs/v0.35.md
+8 -4
@@ -181,12 +181,16 @@ to delays in initial advertisements (provides).
181 Provides and Reprovides now have separate queues, allowing for immediate
182 provide of new CIDs and optimised batching of reprovides.
183
184 -This change introduces a new configuration option for limiting the number of
185 -concurrent provide operations:
186 -[`Provider.WorkerCount`](https://github.com/ipfs/kubo/blob/master/docs/config.md#providerworkercount).
184 +###### New `Provider` configuration options
185 +
186 +This change introduces a new configuration options:
187 +
188 +- [`Provider.Enabled`](https://github.com/ipfs/kubo/blob/master/docs/config.md#providerenabled) is a global flag for disabling both [Provider](https://github.com/ipfs/kubo/blob/master/docs/config.md#provider) and [Reprovider](https://github.com/ipfs/kubo/blob/master/docs/config.md#reprovider) systems (announcing new/old CIDs to amino DHT).
189 +- [`Provider.WorkerCount`](https://github.com/ipfs/kubo/blob/master/docs/config.md#providerworkercount) for limiting the number of concurrent provide operations, allows for fine-tuning the trade-off between announcement speed and system load when announcing new CIDs.
190 +- Removed `Experimental.StrategicProviding`. Superseded by `Provider.Enabled`, `Reprovider.Interval` and [`Reprovider.Strategy`](https://github.com/ipfs/kubo/blob/master/docs/config.md#reproviderstrategy).
191
192 > [!TIP]
189 -> Users who need to provide large volumes of content immediately should consider removing the cap on concurrent provide operations and also set `Routing.AcceleratedDHTClient` to `true`.
193 +> Users who need to provide large volumes of content immediately should consider setting `Routing.AcceleratedDHTClient` to `true`. If that is not enough, consider adjusting `Provider.WorkerCount` to a higher value.
194
195 ###### Deprecated `ipfs stats provider`
196
docs/config.md
+53 -18
@@ -110,6 +110,7 @@ config file at runtime.
110 - [`Pinning.RemoteServices: Policies.MFS.PinName`](#pinningremoteservices-policiesmfspinname)
111 - [`Pinning.RemoteServices: Policies.MFS.RepinInterval`](#pinningremoteservices-policiesmfsrepininterval)
112 - [`Provider`](#provider)
113 + - [`Provider.Enabled`](#providerenabled)
114 - [`Provider.Strategy`](#providerstrategy)
115 - [`Provider.WorkerCount`](#providerworkercount)
116 - [`Pubsub`](#pubsub)
@@ -962,7 +963,7 @@ We are working on developing a modern replacement. To support our efforts, pleas
963 on specified hostnames that point at your Kubo instance.
964
965 It is useful when you want to run [Path gateway](https://specs.ipfs.tech/http-gateways/path-gateway/) on `example.com/ipfs/cid`,
965 -and [Subdomain gateway](https://specs.ipfs.tech/http-gateways/subdomain-gateway/) on `cid.ipfs.example.org`,
966 +and [Subdomain gateway](https://specs.ipfs.tech/http-gateways/subdomain-gateway/) on `cid.ipfs.example.org`,
967 or limit `verifiable.example.net` to response types defined in [Trustless Gateway](https://specs.ipfs.tech/http-gateways/trustless-gateway/) specification.
968
969 > [!CAUTION]
@@ -1000,7 +1001,7 @@ Type: `array[string]`
1001 #### `Gateway.PublicGateways: UseSubdomains`
1002
1003 A boolean to configure whether the gateway at the hostname should be
1003 -a [Subdomain Gateway](https://specs.ipfs.tech/http-gateways/subdomain-gateway/)
1004 +a [Subdomain Gateway](https://specs.ipfs.tech/http-gateways/subdomain-gateway/)
1005 and provide [Origin isolation](https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy)
1006 between content roots.
1007
@@ -1110,7 +1111,7 @@ $ ipfs config --json Gateway.PublicGateways '{"localhost": null }'
1111
1112 ### `Gateway` recipes
1113
1113 -Below is a list of the most common public gateway setups.
1114 +Below is a list of the most common gateway setups.
1115
1116 * Public [subdomain gateway](https://docs.ipfs.tech/how-to/address-ipfs-on-web/#subdomain-gateway) at `http://{cid}.ipfs.dweb.link` (each content root gets its own Origin)
1117 ```console
@@ -1121,6 +1122,7 @@ Below is a list of the most common public gateway setups.
1122 }
1123 }'
1124 ```
1125 + - **Performance:** consider running with `Routing.AcceleratedDHTClient=true` and either `Provider.Enabled=false` (avoid providing newly retrieved blocks) or `Provider.WorkerCount=0` (provide as fast as possible, at the cost of increased load)
1126 - **Backward-compatible:** this feature enables automatic redirects from content paths to subdomains:
1127
1128 `http://dweb.link/ipfs/{cid}` → `http://{cid}.ipfs.dweb.link`
@@ -1145,6 +1147,7 @@ Below is a list of the most common public gateway setups.
1147 }
1148 }'
1149 ```
1150 + - **Performance:** when running an open, recursive gateway consider running with `Routing.AcceleratedDHTClient=true` and either `Provider.Enabled=false` (avoid providing newly retrieved blocks) or `Provider.WorkerCount=0` (provide as fast as possible, at the cost of increased load)
1151
1152 * Public [DNSLink](https://dnslink.io/) gateway resolving every hostname passed in `Host` header.
1153 ```console
@@ -1503,15 +1506,28 @@ commands.
1506
1507 For periodical DHT reprovide settings, see [`Reprovide.*`](#reprovider).
1508
1509 +### `Provider.Enabled`
1510 +
1511 +Controls whether Kubo provider and reprovide systems are enabled.
1512 +
1513 +> [!CAUTION]
1514 +> Disabling this, will disable BOTH `Provider` system for new CIDs
1515 +> and the periodical reprovide ([`Reprovider.Interval`](#reprovider)) of old CIDs.
1516 +
1517 +Default: `true`
1518 +
1519 +Type: `flag`
1520 +
1521 ### `Provider.Strategy`
1522
1523 Legacy, not used at the moment, see [`Reprovider.Strategy`](#reproviderstrategy) instead.
1524
1525 ### `Provider.WorkerCount`
1526
1512 -Sets the maximum number of _concurrent_ DHT provide operations. DHT reprovides
1513 -operations do **not** count against that limit. A value of `0` allows an
1514 -unlimited number of provide workers.
1527 +Sets the maximum number of _concurrent_ DHT provide operations (announcement of new CIDs).
1528 +
1529 +[`Reprovider`](#reprovider) operations do **not** count against this limit.
1530 +A value of `0` allows an unlimited number of provide workers.
1531
1532 If the [accelerated DHT client](#routingaccelerateddhtclient) is enabled, each
1533 provide operation opens ~20 connections in parallel. With the standard DHT
@@ -1520,13 +1536,17 @@ connections, with at most 10 active at once. Provides complete more quickly
1536 when using the accelerated client. Be mindful of how many simultaneous
1537 connections this setting can generate.
1538
1523 -For nodes without strict connection limits that need to provide large volumes
1524 -of content immediately, we recommend enabling the `Routing.AcceleratedDHTClient` and
1525 -setting `Provider.WorkerCount` to `0` (unlimited).
1539 +> [!CAUTION]
1540 +> For nodes without strict connection limits that need to provide large volumes
1541 +> of content immediately, we recommend enabling the `Routing.AcceleratedDHTClient` and
1542 +> setting `Provider.WorkerCount` to `0` (unlimited).
1543 +>
1544 +> At the same time, mind that raising this value too high may lead to increased load.
1545 +> Proceed with caution, ensure proper hardware and networking are in place.
1546
1527 -Default: `64`
1547 +Default: `16`
1548
1529 -Type: `integer` (non-negative; `0` means unlimited number of workers)
1549 +Type: `optionalInteger` (non-negative; `0` means unlimited number of workers)
1550
1551 ## `Pubsub`
1552
@@ -1704,7 +1724,11 @@ system.
1724 Note: disabling content reproviding will result in other nodes on the network
1725 not being able to discover that you have the objects that you have. If you want
1726 to have this disabled and keep the network aware of what you have, you must
1707 -manually announce your content periodically.
1727 +manually announce your content periodically or run your own routing system
1728 +and convince users to add it to [`Routing.DelegatedRouters`](https://github.com/ipfs/kubo/blob/master/docs/config.md#routingdelegatedrouters).
1729 +
1730 +> [!CAUTION]
1731 +> To maintain backward-compatibility, setting `Reprovider.Interval=0` will also disable Provider system (equivalent of `Provider.Enabled=false`)
1732
1733 Default: `22h` (`DefaultReproviderInterval`)
1734
@@ -1868,12 +1892,13 @@ Type: `array[string]`
1892
1893 ### `Routing.DelegatedRouters`
1894
1871 -This is an array of URL hostnames that support the [Delegated Routing V1 HTTP API](https://specs.ipfs.tech/routing/http-routing-v1/) which are used alongside the DHT when [`Routing.Type`](#routingtype) is set to `auto` or `autoclient`.
1895 +An array of URL hostnames for delegated routers to be queried in addition to the Amino DHT when `Routing.Type` is set to `auto` (default) or `autoclient`.
1896 +These endpoints must support the [Delegated Routing V1 HTTP API](https://specs.ipfs.tech/routing/http-routing-v1/).
1897
1898 > [!TIP]
1899 > Delegated routing allows IPFS implementations to offload tasks like content routing, peer routing, and naming to a separate process or server while also benefiting from HTTP caching.
1900 >
1876 -> One can run their own delegated router either by implementing the [Delegated Routing V1 HTTP API](https://specs.ipfs.tech/routing/http-routing-v1/) themselves, or by using [Someguy](https://github.com/ipfs/someguy), a turn-key implementation that proxies requests to the Amino DHT and other delegated routing servers, such as the Network Indexer at `cid.contact`. Public utility instance of Someguy is hosted at [`https://delegated-ipfs.dev`](https://docs.ipfs.tech/concepts/public-utilities/#delegated-routing).
1901 +> One can run their own delegated router either by implementing the [Delegated Routing V1 HTTP API](https://specs.ipfs.tech/routing/http-routing-v1/) themselves, or by using [Someguy](https://github.com/ipfs/someguy), a turn-key implementation that proxies requests to other routing systems. A public utility instance of Someguy is hosted at [`https://delegated-ipfs.dev`](https://docs.ipfs.tech/concepts/public-utilities/#delegated-routing).
1902
1903 Default: `["https://cid.contact"]` (empty or `nil` will also use this default; to disable delegated routing, set `Routing.Type` to `dht` or `dhtclient`)
1904
@@ -1881,11 +1906,14 @@ Type: `array[string]`
1906
1907 ### `Routing.Routers`
1908
1884 -**EXPERIMENTAL: `Routing.Routers` configuration may change in future release**
1909 +Alternative configuration used when `Routing.Type=custom`.
1910
1886 -Map of additional Routers.
1911 +> [!WARNING]
1912 +> **EXPERIMENTAL: `Routing.Routers` configuration may change in future release**
1913 +>
1914 +> Consider this advanced low-level config: Most users can simply use `Routing.Type=auto` or `autoclient` and set up basic config in user-friendly [`Routing.DelegatedRouters`](https://github.com/ipfs/kubo/blob/master/docs/config.md#routingdelegatedrouters).
1915
1888 -Allows for extending the default routing (Amino DHT) with alternative Router
1916 +Allows for replacing the default routing (Amino DHT) with alternative Router
1917 implementations.
1918
1919 The map key is a name of a Router, and the value is its configuration.
@@ -1945,7 +1973,14 @@ Type: `object[string->string]`
1973
1974 ### `Routing: Methods`
1975
1948 -`Methods:map` will define which routers will be executed per method. The key will be the name of the method: `"provide"`, `"find-providers"`, `"find-peers"`, `"put-ipns"`, `"get-ipns"`. All methods must be added to the list.
1976 +`Methods:map` will define which routers will be executed per method used when `Routing.Type=custom`.
1977 +
1978 +> [!WARNING]
1979 +> **EXPERIMENTAL: `Routing.Routers` configuration may change in future release**
1980 +>
1981 +> Consider this advanced low-level config: Most users can simply use `Routing.Type=auto` or `autoclient` and set up basic config in user-friendly [`Routing.DelegatedRouters`](https://github.com/ipfs/kubo/blob/master/docs/config.md#routingdelegatedrouters).
1982 +
1983 +The key will be the name of the method: `"provide"`, `"find-providers"`, `"find-peers"`, `"put-ipns"`, `"get-ipns"`. All methods must be added to the list.
1984
1985 The value will contain:
1986 - `RouterName:string`: Name of the router. It should be one of the previously added to `Routing.Routers` list.
docs/experimental-features.md
+2 -20
@@ -537,27 +537,9 @@ ipfs config --json Swarm.RelayClient.Enabled true
537
538 ### State
539
540 -Experimental, disabled by default.
541 -
542 -Replaces the existing provide mechanism with a robust, strategic provider system. Currently enabling this option will provide nothing.
543 -
544 -### How to enable
545 -
546 -Modify your ipfs config:
547 -
548 -```
549 -ipfs config --json Experimental.StrategicProviding true
550 -```
551 -
552 -### Road to being a real feature
540 +`Experimental.StrategicProviding` was removed in Kubo v0.35.
541
554 -- [ ] needs real-world testing
555 -- [ ] needs adoption
556 -- [ ] needs to support all provider subsystem features
557 - - [X] provide nothing
558 - - [ ] provide roots
559 - - [ ] provide all
560 - - [ ] provide strategic
542 +Replaced by [`Provide.Enabled`](https://github.com/ipfs/kubo/blob/master/docs/config.md#providerenabled) and [`Reprovider.Strategy`](https://github.com/ipfs/kubo/blob/master/docs/config.md#reproviderstrategy).
543
544 ## GraphSync
545
test/cli/provider_test.go
+74 -20
@@ -7,6 +7,7 @@ import (
7
8 "github.com/ipfs/kubo/test/cli/harness"
9 "github.com/ipfs/kubo/test/cli/testutils"
10 + "github.com/stretchr/testify/assert"
11 "github.com/stretchr/testify/require"
12 )
13
@@ -33,11 +34,11 @@ func TestProvider(t *testing.T) {
34 }
35 }
36
36 - t.Run("Basic Providing", func(t *testing.T) {
37 + t.Run("Provider.Enabled=true announces new CIDs created by ipfs add", func(t *testing.T) {
38 t.Parallel()
39
40 nodes := initNodes(t, 2, func(n *harness.Node) {
40 - n.SetIPFSConfig("Experimental.StrategicProviding", false)
41 + n.SetIPFSConfig("Provider.Enabled", true)
42 })
43 defer nodes.StopDaemons()
44
@@ -48,11 +49,11 @@ func TestProvider(t *testing.T) {
49 expectProviders(t, cid, nodes[0].PeerID().String(), nodes[1:]...)
50 })
51
51 - t.Run("Basic Strategic Providing", func(t *testing.T) {
52 + t.Run("Provider.Enabled=false disables announcement of new CID from ipfs add", func(t *testing.T) {
53 t.Parallel()
54
55 nodes := initNodes(t, 2, func(n *harness.Node) {
55 - n.SetIPFSConfig("Experimental.StrategicProviding", true)
56 + n.SetIPFSConfig("Provider.Enabled", false)
57 })
58 defer nodes.StopDaemons()
59
@@ -60,6 +61,75 @@ func TestProvider(t *testing.T) {
61 expectNoProviders(t, cid, nodes[1:]...)
62 })
63
64 + t.Run("Provider.Enabled=false disables manual announcement via RPC command", func(t *testing.T) {
65 + t.Parallel()
66 +
67 + nodes := initNodes(t, 2, func(n *harness.Node) {
68 + n.SetIPFSConfig("Provider.Enabled", false)
69 + })
70 + defer nodes.StopDaemons()
71 +
72 + cid := nodes[0].IPFSAddStr(time.Now().String())
73 + res := nodes[0].RunIPFS("routing", "provide", cid)
74 + assert.Contains(t, res.Stderr.Trimmed(), "invalid configuration: Provider.Enabled is set to 'false'")
75 + assert.Equal(t, 1, res.ExitCode())
76 +
77 + expectNoProviders(t, cid, nodes[1:]...)
78 + })
79 +
80 + // Right now Provide and Reprovide are tied together
81 + t.Run("Reprovide.Interval=0 disables announcement of new CID too", func(t *testing.T) {
82 + t.Parallel()
83 +
84 + nodes := initNodes(t, 2, func(n *harness.Node) {
85 + n.SetIPFSConfig("Reprovider.Interval", "0")
86 + })
87 + defer nodes.StopDaemons()
88 +
89 + cid := nodes[0].IPFSAddStr(time.Now().String())
90 + expectNoProviders(t, cid, nodes[1:]...)
91 + })
92 +
93 + // It is a lesser evil - forces users to fix their config and have some sort of interval
94 + t.Run("Manual Reprovider trigger does not work when periodic Reprovider is disabled", func(t *testing.T) {
95 + t.Parallel()
96 +
97 + nodes := initNodes(t, 2, func(n *harness.Node) {
98 + n.SetIPFSConfig("Reprovider.Interval", "0")
99 + })
100 + defer nodes.StopDaemons()
101 +
102 + cid := nodes[0].IPFSAddStr(time.Now().String(), "--offline")
103 +
104 + expectNoProviders(t, cid, nodes[1:]...)
105 +
106 + res := nodes[0].RunIPFS("routing", "reprovide")
107 + assert.Contains(t, res.Stderr.Trimmed(), "invalid configuration: Reprovider.Interval is set to '0'")
108 + assert.Equal(t, 1, res.ExitCode())
109 +
110 + expectNoProviders(t, cid, nodes[1:]...)
111 + })
112 +
113 + // It is a lesser evil - forces users to fix their config and have some sort of interval
114 + t.Run("Manual Reprovider trigger does not work when Provider system is disabled", func(t *testing.T) {
115 + t.Parallel()
116 +
117 + nodes := initNodes(t, 2, func(n *harness.Node) {
118 + n.SetIPFSConfig("Provider.Enabled", false)
119 + })
120 + defer nodes.StopDaemons()
121 +
122 + cid := nodes[0].IPFSAddStr(time.Now().String(), "--offline")
123 +
124 + expectNoProviders(t, cid, nodes[1:]...)
125 +
126 + res := nodes[0].RunIPFS("routing", "reprovide")
127 + assert.Contains(t, res.Stderr.Trimmed(), "invalid configuration: Provider.Enabled is set to 'false'")
128 + assert.Equal(t, 1, res.ExitCode())
129 +
130 + expectNoProviders(t, cid, nodes[1:]...)
131 + })
132 +
133 t.Run("Reprovides with 'all' strategy", func(t *testing.T) {
134 t.Parallel()
135
@@ -149,20 +219,4 @@ func TestProvider(t *testing.T) {
219 expectProviders(t, cidBarDir, nodes[0].PeerID().String(), nodes[1:]...)
220 })
221
152 - t.Run("Providing works without ticking", func(t *testing.T) {
153 - t.Parallel()
154 -
155 - nodes := initNodes(t, 2, func(n *harness.Node) {
156 - n.SetIPFSConfig("Reprovider.Interval", "0")
157 - })
158 - defer nodes.StopDaemons()
159 -
160 - cid := nodes[0].IPFSAddStr(time.Now().String(), "--offline")
161 -
162 - expectNoProviders(t, cid, nodes[1:]...)
163 -
164 - nodes[0].IPFS("routing", "reprovide")
165 -
166 - expectProviders(t, cid, nodes[0].PeerID().String(), nodes[1:]...)
167 - })
222 }