Skip to content

Commit

Permalink
p2p: add spread to the discovery advertisement interval (#5815)
Browse files Browse the repository at this point in the history
## Motivation

Need to lessen DHT overload from the routing discovery mechanism
  • Loading branch information
ivan4th committed Apr 9, 2024
1 parent 6f4d2d2 commit 0959ae1
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 18 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ See [RELEASE](./RELEASE.md) for workflow instructions.

* [#5803](https://github.com/spacemeshos/go-spacemesh/pull/5803) Fixed PoST verifiers autoscaling for 1:N setups.

* [#5815](https://github.com/spacemeshos/go-spacemesh/pull/5815) Add spread to the discovery advertisement interval.

### Features

## Release v1.4.4
Expand Down
40 changes: 30 additions & 10 deletions p2p/dhtdiscovery/discovery.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"errors"
"fmt"
"math/rand/v2"
"sync"
"time"

Expand All @@ -28,6 +29,7 @@ const (
discoveryHighPeersDelay = 10 * time.Second
protocolPrefix = "/spacekad"
ProtocolID = protocolPrefix + "/kad/1.0.0"
recheckInterval = time.Minute
)

type Opt func(*Discovery)
Expand Down Expand Up @@ -140,6 +142,12 @@ func WithAdvertiseInterval(value time.Duration) Opt {
}
}

func WithAdvertiseIntervalSpread(value time.Duration) Opt {
return func(d *Discovery) {
d.advertiseIntervalSpread = value
}
}

func WithFindPeersRetryDelay(value time.Duration) Opt {
return func(d *Discovery) {
d.findPeersRetryDelay = value
Expand Down Expand Up @@ -197,14 +205,15 @@ type Discovery struct {
// how often to check if we have enough peers
period time.Duration
// timeout used for connections
timeout time.Duration
bootstrapDuration time.Duration
minPeers, highPeers int
backup, bootnodes []peer.AddrInfo
advertiseDelay time.Duration
advertiseInterval time.Duration
advertiseRetryDelay time.Duration
findPeersRetryDelay time.Duration
timeout time.Duration
bootstrapDuration time.Duration
minPeers, highPeers int
backup, bootnodes []peer.AddrInfo
advertiseDelay time.Duration
advertiseInterval time.Duration
advertiseIntervalSpread time.Duration
advertiseRetryDelay time.Duration
findPeersRetryDelay time.Duration
}

func (d *Discovery) FindPeer(ctx context.Context, p peer.ID) (peer.AddrInfo, error) {
Expand Down Expand Up @@ -395,6 +404,14 @@ func (d *Discovery) peerHasTag(p peer.ID) bool {
return found
}

func (d *Discovery) advInterval() time.Duration {
if d.advertiseIntervalSpread == 0 {
return d.advertiseInterval
}

return d.advertiseInterval - d.advertiseIntervalSpread + rand.N(2*d.advertiseIntervalSpread)
}

func (d *Discovery) advertiseNS(ctx context.Context, ns string, active func() bool) error {
if d.advertiseDelay != 0 {
select {
Expand All @@ -408,13 +425,16 @@ func (d *Discovery) advertiseNS(ctx context.Context, ns string, active func() bo
if active == nil || active() {
var err error
d.logger.Debug("advertising for routing discovery", zap.String("ns", ns))
ttl, err = d.disc.Advertise(ctx, ns, p2pdisc.TTL(d.advertiseInterval))
ttl, err = d.disc.Advertise(ctx, ns, p2pdisc.TTL(d.advInterval()))
if err != nil {
d.logger.Error("failed to re-advertise for discovery", zap.String("ns", ns), zap.Error(err))
ttl = d.advertiseRetryDelay
}
} else {
ttl = d.advertiseInterval
// At this moment, advertisement is not needed.
// There was previous delay already, just need to recheck if we need
// to start advertising again
ttl = recheckInterval
}
select {
case <-ctx.Done():
Expand Down
22 changes: 14 additions & 8 deletions p2p/host.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,11 @@ func DefaultConfig() Config {
ResetPeriod: time.Minute,
},
DiscoveryTimings: DiscoveryTimings{
AdvertiseDelay: time.Hour,
AdvertiseInterval: time.Hour,
AdvertiseRetryDelay: time.Minute,
FindPeersRetryDelay: time.Minute,
AdvertiseDelay: time.Hour,
AdvertiseInterval: 2 * time.Hour,
AdvertiseIntervalSpread: time.Hour,
AdvertiseRetryDelay: time.Minute,
FindPeersRetryDelay: time.Minute,
},
}
}
Expand Down Expand Up @@ -161,10 +162,11 @@ type Config struct {
}

type DiscoveryTimings struct {
AdvertiseDelay time.Duration `mapstructure:"advertise-delay"`
AdvertiseInterval time.Duration `mapstructure:"advertise-interval"`
AdvertiseRetryDelay time.Duration `mapstructure:"advertise-retry-delay"`
FindPeersRetryDelay time.Duration `mapstructure:"find-peers-retry-delay"`
AdvertiseDelay time.Duration `mapstructure:"advertise-delay"`
AdvertiseInterval time.Duration `mapstructure:"advertise-interval"`
AdvertiseIntervalSpread time.Duration `mapstructure:"advertise-interval-spread"`
AdvertiseRetryDelay time.Duration `mapstructure:"advertise-retry-delay"`
FindPeersRetryDelay time.Duration `mapstructure:"find-peers-retry-delay"`
}

type AutoNATServer struct {
Expand Down Expand Up @@ -209,6 +211,10 @@ func (cfg *Config) Validate() error {
}
}

if cfg.DiscoveryTimings.AdvertiseIntervalSpread > cfg.DiscoveryTimings.AdvertiseInterval {
return errors.New("advertise-interval-spread cannot be greater than advertise-interval")
}

return nil
}

Expand Down
1 change: 1 addition & 0 deletions p2p/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ func Upgrade(h host.Host, opts ...Opt) (*Host, error) {
discovery.WithLogger(fh.logger.Zap()),
discovery.WithAdvertiseDelay(fh.cfg.DiscoveryTimings.AdvertiseDelay),
discovery.WithAdvertiseInterval(fh.cfg.DiscoveryTimings.AdvertiseInterval),
discovery.WithAdvertiseIntervalSpread(fh.cfg.DiscoveryTimings.AdvertiseIntervalSpread),
discovery.WithAdvertiseRetryDelay(fh.cfg.DiscoveryTimings.AdvertiseInterval),
discovery.WithFindPeersRetryDelay(fh.cfg.DiscoveryTimings.FindPeersRetryDelay),
}
Expand Down

0 comments on commit 0959ae1

Please sign in to comment.