From 86cd884ae2eeef3e8de63ded8b172f4a2d312fb5 Mon Sep 17 00:00:00 2001 From: StephenButtolph Date: Wed, 10 Jun 2020 02:22:37 -0400 Subject: [PATCH] Randomized the retry delay --- network/builder_test.go | 10 +--- network/commands.go | 30 +++++------ network/network.go | 112 ++++++++++++++++++++++------------------ 3 files changed, 79 insertions(+), 73 deletions(-) diff --git a/network/builder_test.go b/network/builder_test.go index 7511d83..5d78e40 100644 --- a/network/builder_test.go +++ b/network/builder_test.go @@ -79,14 +79,8 @@ func TestBuildGetPeerList(t *testing.T) { func TestBuildPeerList(t *testing.T) { ips := []utils.IPDesc{ - utils.IPDesc{ - IP: net.IPv6loopback, - Port: 12345, - }, - utils.IPDesc{ - IP: net.IPv6loopback, - Port: 54321, - }, + {IP: net.IPv6loopback, Port: 12345}, + {IP: net.IPv6loopback, Port: 54321}, } msg, err := TestBuilder.PeerList(ips) diff --git a/network/commands.go b/network/commands.go index 2143329..c5feb89 100644 --- a/network/commands.go +++ b/network/commands.go @@ -188,22 +188,22 @@ const ( var ( Messages = map[Op][]Field{ // Handshake: - GetVersion: []Field{}, - Version: []Field{NetworkID, NodeID, MyTime, IP, VersionStr}, - GetPeerList: []Field{}, - PeerList: []Field{Peers}, + GetVersion: {}, + Version: {NetworkID, NodeID, MyTime, IP, VersionStr}, + GetPeerList: {}, + PeerList: {Peers}, // Bootstrapping: - GetAcceptedFrontier: []Field{ChainID, RequestID}, - AcceptedFrontier: []Field{ChainID, RequestID, ContainerIDs}, - GetAccepted: []Field{ChainID, RequestID, ContainerIDs}, - Accepted: []Field{ChainID, RequestID, ContainerIDs}, - GetAncestors: []Field{ChainID, RequestID, ContainerID}, - MultiPut: []Field{ChainID, RequestID, MultiContainerBytes}, + GetAcceptedFrontier: {ChainID, RequestID}, + AcceptedFrontier: {ChainID, RequestID, ContainerIDs}, + GetAccepted: {ChainID, RequestID, ContainerIDs}, + Accepted: {ChainID, RequestID, ContainerIDs}, + GetAncestors: {ChainID, RequestID, ContainerID}, + MultiPut: {ChainID, RequestID, MultiContainerBytes}, // Consensus: - Get: []Field{ChainID, RequestID, ContainerID}, - Put: []Field{ChainID, RequestID, ContainerID, ContainerBytes}, - PushQuery: []Field{ChainID, RequestID, ContainerID, ContainerBytes}, - PullQuery: []Field{ChainID, RequestID, ContainerID}, - Chits: []Field{ChainID, RequestID, ContainerIDs}, + Get: {ChainID, RequestID, ContainerID}, + Put: {ChainID, RequestID, ContainerID, ContainerBytes}, + PushQuery: {ChainID, RequestID, ContainerID, ContainerBytes}, + PullQuery: {ChainID, RequestID, ContainerID}, + Chits: {ChainID, RequestID, ContainerIDs}, } ) diff --git a/network/network.go b/network/network.go index 9780c07..cb14ff5 100644 --- a/network/network.go +++ b/network/network.go @@ -27,18 +27,21 @@ import ( "github.com/ava-labs/gecko/version" ) +// reasonable default values const ( - defaultInitialReconnectDelay = time.Second - defaultMaxReconnectDelay = time.Hour - DefaultMaxMessageSize uint32 = 1 << 21 - defaultSendQueueSize = 1 << 10 - defaultMaxClockDifference = time.Minute - defaultPeerListGossipSpacing = time.Minute - defaultPeerListGossipSize = 100 - defaultPeerListStakerGossipFraction = 2 - defaultGetVersionTimeout = 2 * time.Second - defaultAllowPrivateIPs = true - defaultGossipSize = 50 + defaultInitialReconnectDelay = time.Second + defaultMaxReconnectDelay = time.Hour + DefaultMaxMessageSize uint32 = 1 << 21 + defaultSendQueueSize = 1 << 10 + defaultMaxNetworkPendingSendBytes = 1 << 28 // 256MB + defaultNetworkPendingSendBytesToRateLimit = defaultMaxNetworkPendingSendBytes / 4 + defaultMaxClockDifference = time.Minute + defaultPeerListGossipSpacing = time.Minute + defaultPeerListGossipSize = 100 + defaultPeerListStakerGossipFraction = 2 + defaultGetVersionTimeout = 2 * time.Second + defaultAllowPrivateIPs = true + defaultGossipSize = 50 ) // Network defines the functionality of the networking library. @@ -102,17 +105,19 @@ type network struct { clock timer.Clock lastHeartbeat int64 - initialReconnectDelay time.Duration - maxReconnectDelay time.Duration - maxMessageSize uint32 - sendQueueSize int - maxClockDifference time.Duration - peerListGossipSpacing time.Duration - peerListGossipSize int - peerListStakerGossipFraction int - getVersionTimeout time.Duration - allowPrivateIPs bool - gossipSize int + initialReconnectDelay time.Duration + maxReconnectDelay time.Duration + maxMessageSize uint32 + sendQueueSize int + maxNetworkPendingSendBytes int + networkPendingSendBytesToRateLimit int + maxClockDifference time.Duration + peerListGossipSpacing time.Duration + peerListGossipSize int + peerListStakerGossipFraction int + getVersionTimeout time.Duration + allowPrivateIPs bool + gossipSize int executor timer.Executor @@ -164,6 +169,8 @@ func NewDefaultNetwork( defaultMaxReconnectDelay, DefaultMaxMessageSize, defaultSendQueueSize, + defaultMaxNetworkPendingSendBytes, + defaultNetworkPendingSendBytesToRateLimit, defaultMaxClockDifference, defaultPeerListGossipSpacing, defaultPeerListGossipSize, @@ -193,6 +200,8 @@ func NewNetwork( maxReconnectDelay time.Duration, maxMessageSize uint32, sendQueueSize int, + maxNetworkPendingSendBytes int, + networkPendingSendBytesToRateLimit int, maxClockDifference time.Duration, peerListGossipSpacing time.Duration, peerListGossipSize int, @@ -202,35 +211,37 @@ func NewNetwork( gossipSize int, ) Network { net := &network{ - log: log, - id: id, - ip: ip, - networkID: networkID, - version: version, - parser: parser, - listener: listener, - dialer: dialer, - serverUpgrader: serverUpgrader, - clientUpgrader: clientUpgrader, - vdrs: vdrs, - router: router, - nodeID: rand.Uint32(), - initialReconnectDelay: initialReconnectDelay, - maxReconnectDelay: maxReconnectDelay, - maxMessageSize: maxMessageSize, - sendQueueSize: sendQueueSize, - maxClockDifference: maxClockDifference, - peerListGossipSpacing: peerListGossipSpacing, - peerListGossipSize: peerListGossipSize, - peerListStakerGossipFraction: peerListStakerGossipFraction, - getVersionTimeout: getVersionTimeout, - allowPrivateIPs: allowPrivateIPs, - gossipSize: gossipSize, + log: log, + id: id, + ip: ip, + networkID: networkID, + version: version, + parser: parser, + listener: listener, + dialer: dialer, + serverUpgrader: serverUpgrader, + clientUpgrader: clientUpgrader, + vdrs: vdrs, + router: router, + nodeID: rand.Uint32(), + initialReconnectDelay: initialReconnectDelay, + maxReconnectDelay: maxReconnectDelay, + maxMessageSize: maxMessageSize, + sendQueueSize: sendQueueSize, + maxNetworkPendingSendBytes: maxNetworkPendingSendBytes, + networkPendingSendBytesToRateLimit: networkPendingSendBytesToRateLimit, + maxClockDifference: maxClockDifference, + peerListGossipSpacing: peerListGossipSpacing, + peerListGossipSize: peerListGossipSize, + peerListStakerGossipFraction: peerListStakerGossipFraction, + getVersionTimeout: getVersionTimeout, + allowPrivateIPs: allowPrivateIPs, + gossipSize: gossipSize, disconnectedIPs: make(map[string]struct{}), connectedIPs: make(map[string]struct{}), retryDelay: make(map[string]time.Duration), - myIPs: map[string]struct{}{ip.String(): struct{}{}}, + myIPs: map[string]struct{}{ip.String(): {}}, peers: make(map[[20]byte]*peer), } net.initialize(registerer) @@ -738,11 +749,12 @@ func (n *network) connectTo(ip utils.IPDesc) { if delay == 0 { delay = n.initialReconnectDelay - } else { - delay *= 2 } + + delay = time.Duration(float64(delay) * (1 + rand.Float64())) if delay > n.maxReconnectDelay { - delay = n.maxReconnectDelay + // set the timeout to [.75, 1) * maxReconnectDelay + delay = time.Duration(float64(n.maxReconnectDelay) * (3 + rand.Float64()) / 4) } n.stateLock.Lock()