diff --git a/cmd/ipfs/daemon.go b/cmd/ipfs/daemon.go index 21495c498fa4..880d26b0e425 100644 --- a/cmd/ipfs/daemon.go +++ b/cmd/ipfs/daemon.go @@ -45,32 +45,33 @@ import ( ) const ( - adjustFDLimitKwd = "manage-fdlimit" - enableGCKwd = "enable-gc" - initOptionKwd = "init" - initConfigOptionKwd = "init-config" - initProfileOptionKwd = "init-profile" - ipfsMountKwd = "mount-ipfs" - ipnsMountKwd = "mount-ipns" - migrateKwd = "migrate" - mountKwd = "mount" - offlineKwd = "offline" // global option - routingOptionKwd = "routing" - routingOptionSupernodeKwd = "supernode" - routingOptionDHTClientKwd = "dhtclient" - routingOptionDHTKwd = "dht" - routingOptionDHTServerKwd = "dhtserver" - routingOptionNoneKwd = "none" - routingOptionCustomKwd = "custom" - routingOptionDefaultKwd = "default" - routingOptionAutoKwd = "auto" - unencryptTransportKwd = "disable-transport-encryption" - unrestrictedAPIAccessKwd = "unrestricted-api" - writableKwd = "writable" - enablePubSubKwd = "enable-pubsub-experiment" - enableIPNSPubSubKwd = "enable-namesys-pubsub" - enableMultiplexKwd = "enable-mplex-experiment" - agentVersionSuffix = "agent-version-suffix" + adjustFDLimitKwd = "manage-fdlimit" + enableGCKwd = "enable-gc" + initOptionKwd = "init" + initConfigOptionKwd = "init-config" + initProfileOptionKwd = "init-profile" + ipfsMountKwd = "mount-ipfs" + ipnsMountKwd = "mount-ipns" + migrateKwd = "migrate" + mountKwd = "mount" + offlineKwd = "offline" // global option + routingOptionKwd = "routing" + routingOptionSupernodeKwd = "supernode" + routingOptionDHTClientKwd = "dhtclient" + routingOptionDHTKwd = "dht" + routingOptionDHTServerKwd = "dhtserver" + routingOptionNoneKwd = "none" + routingOptionCustomKwd = "custom" + routingOptionDefaultKwd = "default" + routingOptionAutoKwd = "auto" + routingOptionAutoClientKwd = "autoclient" + unencryptTransportKwd = "disable-transport-encryption" + unrestrictedAPIAccessKwd = "unrestricted-api" + writableKwd = "writable" + enablePubSubKwd = "enable-pubsub-experiment" + enableIPNSPubSubKwd = "enable-namesys-pubsub" + enableMultiplexKwd = "enable-mplex-experiment" + agentVersionSuffix = "agent-version-suffix" // apiAddrKwd = "address-api" // swarmAddrKwd = "address-swarm" ) @@ -416,6 +417,14 @@ func daemonFunc(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment cfg.Identity.PeerID, cfg.Addresses.Swarm, cfg.Identity.PrivKey, + libp2p.DHTOption, + ) + case routingOptionAutoClientKwd: + ncfg.Routing = libp2p.ConstructDefaultRouting( + cfg.Identity.PeerID, + cfg.Addresses.Swarm, + cfg.Identity.PrivKey, + libp2p.DHTClientOption, ) case routingOptionDHTClientKwd: ncfg.Routing = libp2p.DHTClientOption diff --git a/config/routing.go b/config/routing.go index f19414ff3086..1210bb3cecc3 100644 --- a/config/routing.go +++ b/config/routing.go @@ -10,7 +10,7 @@ import ( type Routing struct { // Type sets default daemon routing mode. // - // Can be one of "auto", "dht", "dhtclient", "dhtserver", "none", or "custom". + // Can be one of "auto", "autoclient", "dht", "dhtclient", "dhtserver", "none", or "custom". // When unset or set to "auto", DHT and implicit routers are used. // When "custom" is set, user-provided Routing.Routers is used. Type *OptionalString `json:",omitempty"` diff --git a/core/node/libp2p/routingopt.go b/core/node/libp2p/routingopt.go index bfb45971cc9e..d54f37acc5c8 100644 --- a/core/node/libp2p/routingopt.go +++ b/core/node/libp2p/routingopt.go @@ -40,7 +40,7 @@ func init() { } // ConstructDefaultRouting returns routers used when Routing.Type is unset or set to "auto" -func ConstructDefaultRouting(peerID string, addrs []string, privKey string) func( +func ConstructDefaultRouting(peerID string, addrs []string, privKey string, routingOpt RoutingOption) func( ctx context.Context, host host.Host, dstore datastore.Batching, @@ -58,8 +58,7 @@ func ConstructDefaultRouting(peerID string, addrs []string, privKey string) func // Different trade-offs can be made by setting Routing.Type = "custom" with own Routing.Routers var routers []*routinghelpers.ParallelRouter - // Run the default DHT routing (same as Routing.Type = "dht") - dhtRouting, err := DHTOption(ctx, host, dstore, validator, bootstrapPeers...) + dhtRouting, err := routingOpt(ctx, host, dstore, validator, bootstrapPeers...) if err != nil { return nil, err } diff --git a/docs/config.md b/docs/config.md index adf956ce01d3..686661918024 100644 --- a/docs/config.md +++ b/docs/config.md @@ -1349,11 +1349,13 @@ Contains options for content, peer, and IPNS routing mechanisms. ### `Routing.Type` -There are multiple routing options: "auto", "none", "dht" and "custom". +There are multiple routing options: "auto", "autoclient", "none", "dht", "dhtclient", and "custom". * **DEFAULT:** If unset, or set to "auto", your node will use the IPFS DHT and parallel HTTP routers listed below for additional speed. +* If set to "autoclient", your node will behave as in "auto" but without running a DHT server. + * If set to "none", your node will use _no_ routing system. You'll have to explicitly connect to peers that have the content you're looking for. @@ -1379,7 +1381,7 @@ To force a specific DHT-only mode, client or server, set `Routing.Type` to `dhtclient` or `dhtserver` respectively. Please do not set this to `dhtserver` unless you're sure your node is reachable from the public network. -When `Routing.Type` is set to `auto` your node will accelerate some types of routing +When `Routing.Type` is set to `auto` or `autoclient` your node will accelerate some types of routing by leveraging HTTP endpoints compatible with [IPIP-337](https://github.com/ipfs/specs/pull/337) in addition to the IPFS DHT. By default, an instance of [IPNI](https://github.com/ipni/specs/blob/main/IPNI.md#readme) diff --git a/test/cli/delegated_routing_http_test.go b/test/cli/delegated_routing_http_test.go index 0b39a9b12e67..446ea515049e 100644 --- a/test/cli/delegated_routing_http_test.go +++ b/test/cli/delegated_routing_http_test.go @@ -94,7 +94,7 @@ func TestHTTPDelegatedRouting(t *testing.T) { })) t.Cleanup(server.Close) - node.IPFS("config", "Routing.Type", "--json", `"custom"`) + node.IPFS("config", "Routing.Type", "custom") node.IPFS("config", "Routing.Routers.TestDelegatedRouter", "--json", ToJSONStr(JSONObj{ "Type": "http", "Parameters": JSONObj{ diff --git a/test/cli/dht_autoclient_test.go b/test/cli/dht_autoclient_test.go new file mode 100644 index 000000000000..749e34b348ec --- /dev/null +++ b/test/cli/dht_autoclient_test.go @@ -0,0 +1,39 @@ +package cli + +import ( + "bytes" + "testing" + + "github.com/ipfs/kubo/test/cli/harness" + "github.com/ipfs/kubo/test/cli/testutils" + "github.com/stretchr/testify/assert" +) + +func TestDHTAutoclient(t *testing.T) { + t.Parallel() + nodes := harness.NewT(t).NewNodes(10).Init() + harness.Nodes(nodes[8:]).ForEachPar(func(node *harness.Node) { + node.IPFS("config", "Routing.Type", "autoclient") + }) + nodes.StartDaemons().Connect() + + t.Run("file added on node in client mode is retrievable from node in client mode", func(t *testing.T) { + t.Parallel() + randomBytes := testutils.RandomBytes(1000) + hash := nodes[8].IPFSAdd(bytes.NewReader(randomBytes)) + + res := nodes[9].IPFS("cat", hash) + assert.Equal(t, randomBytes, []byte(res.Stdout.Trimmed())) + }) + + t.Run("file added on node in server mode is retrievable from all nodes", func(t *testing.T) { + t.Parallel() + randomBytes := testutils.RandomBytes(1000) + hash := nodes[0].IPFSAdd(bytes.NewReader(randomBytes)) + + for i := 0; i < 10; i++ { + res := nodes[i].IPFS("cat", hash) + assert.Equal(t, randomBytes, []byte(res.Stdout.Trimmed())) + } + }) +}