diff --git a/core/node/groups.go b/core/node/groups.go index 914e7c59b92..15b45fc8028 100644 --- a/core/node/groups.go +++ b/core/node/groups.go @@ -145,7 +145,7 @@ func LibP2P(bcfg *BuildCfg, cfg *config.Config) fx.Option { BaseLibP2P, fx.Provide(libp2p.AddrFilters(cfg.Swarm.AddrFilters)), - fx.Provide(libp2p.AddrsFactory(cfg.Addresses.Announce, cfg.Addresses.NoAnnounce)), + fx.Provide(libp2p.AddrsFactory(cfg.Addresses.Announce, cfg.Addresses.AppendAnnounce, cfg.Addresses.NoAnnounce)), fx.Provide(libp2p.SmuxTransport(cfg.Swarm.Transports)), fx.Provide(libp2p.RelayTransport(enableRelayTransport)), fx.Provide(libp2p.RelayService(cfg.Swarm.RelayService.Enabled.WithDefault(true), cfg.Swarm.RelayService)), diff --git a/core/node/libp2p/addrs.go b/core/node/libp2p/addrs.go index 818385194a7..827c6cc4c9d 100644 --- a/core/node/libp2p/addrs.go +++ b/core/node/libp2p/addrs.go @@ -25,14 +25,30 @@ func AddrFilters(filters []string) func() (*ma.Filters, Libp2pOpts, error) { } } -func makeAddrsFactory(announce []string, noAnnounce []string) (p2pbhost.AddrsFactory, error) { - var annAddrs []ma.Multiaddr - for _, addr := range announce { - maddr, err := ma.NewMultiaddr(addr) +func makeAddrsFactory(announce []string, appendAnnouce []string, noAnnounce []string) (p2pbhost.AddrsFactory, error) { + var err error // To assign to the slice in the for loop + existing := make(map[string]bool) // To avoid duplicates + + annAddrs := make([]ma.Multiaddr, len(announce)) + for i, addr := range announce { + annAddrs[i], err = ma.NewMultiaddr(addr) + if err != nil { + return nil, err + } + existing[addr] = true + } + + var appendAnnAddrs []ma.Multiaddr + for _, addr := range appendAnnouce { + if existing[addr] { + // skip AppendAnnounce that is on the Announce list already + continue + } + appendAddr, err := ma.NewMultiaddr(addr) if err != nil { return nil, err } - annAddrs = append(annAddrs, maddr) + appendAnnAddrs = append(appendAnnAddrs, appendAddr) } filters := ma.NewFilters() @@ -57,6 +73,7 @@ func makeAddrsFactory(announce []string, noAnnounce []string) (p2pbhost.AddrsFac } else { addrs = allAddrs } + addrs = append(addrs, appendAnnAddrs...) var out []ma.Multiaddr for _, maddr := range addrs { @@ -71,9 +88,9 @@ func makeAddrsFactory(announce []string, noAnnounce []string) (p2pbhost.AddrsFac }, nil } -func AddrsFactory(announce []string, noAnnounce []string) func() (opts Libp2pOpts, err error) { +func AddrsFactory(announce []string, appendAnnouce []string, noAnnounce []string) func() (opts Libp2pOpts, err error) { return func() (opts Libp2pOpts, err error) { - addrsFactory, err := makeAddrsFactory(announce, noAnnounce) + addrsFactory, err := makeAddrsFactory(announce, appendAnnouce, noAnnounce) if err != nil { return opts, err } diff --git a/docs/config.md b/docs/config.md index 3a9fb90127c..7be7ddd5a83 100644 --- a/docs/config.md +++ b/docs/config.md @@ -21,6 +21,7 @@ config file at runtime. - [`Addresses.Gateway`](#addressesgateway) - [`Addresses.Swarm`](#addressesswarm) - [`Addresses.Announce`](#addressesannounce) + - [`Addresses.AppendAnnounce`](#addressesappendannounce) - [`Addresses.NoAnnounce`](#addressesnoannounce) - [`API`](#api) - [`API.HTTPHeaders`](#apihttpheaders) @@ -336,8 +337,19 @@ Default: `[]` Type: `array[string]` (multiaddrs) +### `Addresses.AppendAnnounce` + +Similar to [`Addresses.Announce`](#addressesannounce) except this doesn't +override inferred swarm addresses if non-empty. + +Default: `[]` + +Type: `array[string]` (multiaddrs) + ### `Addresses.NoAnnounce` + An array of swarm addresses not to announce to the network. +Takes precedence over `Addresses.Announce` and `Addresses.AppendAnnounce`. Default: `[]` diff --git a/test/sharness/t0140-swarm.sh b/test/sharness/t0140-swarm.sh index 20994c13e7c..d65831d3e22 100755 --- a/test/sharness/t0140-swarm.sh +++ b/test/sharness/t0140-swarm.sh @@ -65,6 +65,33 @@ test_expect_success 'Addresses.Announce affects addresses' ' test_kill_ipfs_daemon + +announceCfg='["/ip4/127.0.0.1/tcp/4001", "/ip4/1.2.3.4/tcp/1234"]' +test_expect_success "test_config_set succeeds" " + ipfs config --json Addresses.Announce '$announceCfg' +" +# Include "/ip4/1.2.3.4/tcp/1234" to ensure we deduplicate addrs already present in Swarm.Announce +appendAnnounceCfg='["/dnsaddr/dynamic.example.com", "/ip4/10.20.30.40/tcp/4321", "/ip4/1.2.3.4/tcp/1234"]' +test_expect_success "test_config_set Announce and AppendAnnounce succeeds" " + ipfs config --json Addresses.Announce '$announceCfg' && + ipfs config --json Addresses.AppendAnnounce '$appendAnnounceCfg' +" + +test_launch_ipfs_daemon + +test_expect_success 'Addresses.AppendAnnounce is applied on top of Announce' ' + ipfs swarm addrs local >actual && + grep "/ip4/1.2.3.4/tcp/1234" actual && + grep "/dnsaddr/dynamic.example.com" actual && + grep "/ip4/10.20.30.40/tcp/4321" actual && + ipfs id -f"" | xargs -n1 echo | tee actual && + grep "/ip4/1.2.3.4/tcp/1234/p2p" actual && + grep "/dnsaddr/dynamic.example.com/p2p/" actual && + grep "/ip4/10.20.30.40/tcp/4321/p2p/" actual +' + +test_kill_ipfs_daemon + noAnnounceCfg='["/ip4/1.2.3.4/tcp/1234"]' test_expect_success "test_config_set succeeds" " ipfs config --json Addresses.NoAnnounce '$noAnnounceCfg' @@ -72,11 +99,13 @@ test_expect_success "test_config_set succeeds" " test_launch_ipfs_daemon -test_expect_success "Addresses.NoAnnounce affects addresses" ' +test_expect_success "Addresses.NoAnnounce affects addresses from Announce and AppendAnnounce" ' ipfs swarm addrs local >actual && grep -v "/ip4/1.2.3.4/tcp/1234" actual && + grep -v "/ip4/10.20.30.40/tcp/4321" actual && ipfs id -f"" | xargs -n1 echo >actual && - grep -v "/ip4/1.2.3.4/tcp/1234" actual + grep -v "/ip4/1.2.3.4/tcp/1234" actual && + grep -v "//ip4/10.20.30.40/tcp/4321" actual ' test_kill_ipfs_daemon