Files
node/mesh/tracked_ip.go
zeekayandHanzo Dev 37e2940ead mesh is the peer layer, network is the validator set
Two packages were named for the same word and meant different things. network/
dialed peers, exchanged keys, throttled and tracked them; nets/ tracked which
chains share a validator set and when they have all bootstrapped. One letter
apart, and neither name said which was which.

The peer layer is mesh — the word this estate already uses for it, in
lux-rs/node's own mesh.rs. That frees network for the thing that is actually a
network: a set of chains sharing a validator set. A network holds chains; a
chain belongs to one network.

github.com/luxfi/p2p stays what it is, the gossip library the VMs use. Three
concerns, three names, none of them borrowed from another.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-07 21:17:09 -07:00

78 lines
1.9 KiB
Go

// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package mesh
import (
"math/rand"
"sync"
"time"
"github.com/luxfi/net/endpoints"
)
func init() {
rand.Seed(time.Now().UnixNano())
}
// trackedIP tracks an endpoint that we are trying to connect to.
// The endpoint can be either an IP address or a hostname.
type trackedIP struct {
delayLock sync.RWMutex
delay time.Duration
endpoint endpoints.Endpoint
stopTrackingOnce sync.Once
onStopTracking chan struct{}
}
func newTrackedIP(endpoint endpoints.Endpoint) *trackedIP {
return &trackedIP{
endpoint: endpoint,
onStopTracking: make(chan struct{}),
}
}
func (ip *trackedIP) trackNewEndpoint(newEndpoint endpoints.Endpoint) *trackedIP {
ip.stopTracking()
return &trackedIP{
delay: ip.getDelay(),
endpoint: newEndpoint,
onStopTracking: make(chan struct{}),
}
}
func (ip *trackedIP) getDelay() time.Duration {
ip.delayLock.RLock()
delay := ip.delay
ip.delayLock.RUnlock()
return delay
}
func (ip *trackedIP) increaseDelay(initialDelay, maxDelay time.Duration) {
ip.delayLock.Lock()
defer ip.delayLock.Unlock()
// If the timeout was previously 0, ensure that there is a reasonable delay.
if ip.delay <= 0 {
ip.delay = initialDelay
}
// Randomization is only performed here to distribute reconnection
// attempts to a node that previously shut down. This doesn't
// require cryptographically secure random number generation.
// set the timeout to [1, 2) * timeout
ip.delay = time.Duration(float64(ip.delay) * (1 + rand.Float64())) // #nosec G404
if ip.delay > maxDelay {
// set the timeout to [.75, 1) * maxDelay
ip.delay = time.Duration(float64(maxDelay) * (3 + rand.Float64()) / 4) // #nosec G404
}
}
func (ip *trackedIP) stopTracking() {
ip.stopTrackingOnce.Do(func() {
close(ip.onStopTracking)
})
}