Skip to content

Commit 197179f

Browse files
Improve bootstrapping peer selection (#2946)
Signed-off-by: Stephen Buttolph <stephen@avalabs.org> Co-authored-by: Joshua Kim <20001595+joshua-kim@users.noreply.github.com>
1 parent d701e25 commit 197179f

File tree

13 files changed

+498
-271
lines changed

13 files changed

+498
-271
lines changed

chains/manager.go

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import (
2727
"github.com/ava-labs/avalanchego/ids"
2828
"github.com/ava-labs/avalanchego/message"
2929
"github.com/ava-labs/avalanchego/network"
30-
"github.com/ava-labs/avalanchego/proto/pb/p2p"
30+
"github.com/ava-labs/avalanchego/network/p2p"
3131
"github.com/ava-labs/avalanchego/snow"
3232
"github.com/ava-labs/avalanchego/snow/engine/avalanche/bootstrap/queue"
3333
"github.com/ava-labs/avalanchego/snow/engine/avalanche/state"
@@ -62,6 +62,7 @@ import (
6262
"github.com/ava-labs/avalanchego/vms/secp256k1fx"
6363
"github.com/ava-labs/avalanchego/vms/tracedvm"
6464

65+
p2ppb "github.com/ava-labs/avalanchego/proto/pb/p2p"
6566
smcon "github.com/ava-labs/avalanchego/snow/consensus/snowman"
6667
aveng "github.com/ava-labs/avalanchego/snow/engine/avalanche"
6768
avbootstrap "github.com/ava-labs/avalanchego/snow/engine/avalanche/bootstrap"
@@ -556,7 +557,7 @@ func (m *manager) createAvalancheChain(
556557
defer ctx.Lock.Unlock()
557558

558559
ctx.State.Set(snow.EngineState{
559-
Type: p2p.EngineType_ENGINE_TYPE_AVALANCHE,
560+
Type: p2ppb.EngineType_ENGINE_TYPE_AVALANCHE,
560561
State: snow.Initializing,
561562
})
562563

@@ -587,7 +588,7 @@ func (m *manager) createAvalancheChain(
587588
m.Net,
588589
m.ManagerConfig.Router,
589590
m.TimeoutManager,
590-
p2p.EngineType_ENGINE_TYPE_AVALANCHE,
591+
p2ppb.EngineType_ENGINE_TYPE_AVALANCHE,
591592
sb,
592593
)
593594
if err != nil {
@@ -605,7 +606,7 @@ func (m *manager) createAvalancheChain(
605606
m.Net,
606607
m.ManagerConfig.Router,
607608
m.TimeoutManager,
608-
p2p.EngineType_ENGINE_TYPE_SNOWMAN,
609+
p2ppb.EngineType_ENGINE_TYPE_SNOWMAN,
609610
sb,
610611
)
611612
if err != nil {
@@ -763,6 +764,17 @@ func (m *manager) createAvalancheChain(
763764
}
764765
vdrs.RegisterCallbackListener(ctx.SubnetID, connectedValidators)
765766

767+
peerTracker, err := p2p.NewPeerTracker(
768+
ctx.Log,
769+
"peer_tracker",
770+
ctx.Registerer,
771+
set.Of(ctx.NodeID),
772+
nil,
773+
)
774+
if err != nil {
775+
return nil, fmt.Errorf("error creating peer tracker: %w", err)
776+
}
777+
766778
// Asynchronously passes messages from the network to the consensus engine
767779
h, err := handler.New(
768780
ctx,
@@ -774,6 +786,7 @@ func (m *manager) createAvalancheChain(
774786
validators.UnhandledSubnetConnector, // avalanche chains don't use subnet connector
775787
sb,
776788
connectedValidators,
789+
peerTracker,
777790
)
778791
if err != nil {
779792
return nil, fmt.Errorf("error initializing network handler: %w", err)
@@ -832,6 +845,7 @@ func (m *manager) createAvalancheChain(
832845
Sender: snowmanMessageSender,
833846
BootstrapTracker: sb,
834847
Timer: h,
848+
PeerTracker: peerTracker,
835849
AncestorsMaxContainersReceived: m.BootstrapAncestorsMaxContainersReceived,
836850
DB: blockBootstrappingDB,
837851
VM: vmWrappingProposerVM,
@@ -936,7 +950,7 @@ func (m *manager) createSnowmanChain(
936950
defer ctx.Lock.Unlock()
937951

938952
ctx.State.Set(snow.EngineState{
939-
Type: p2p.EngineType_ENGINE_TYPE_SNOWMAN,
953+
Type: p2ppb.EngineType_ENGINE_TYPE_SNOWMAN,
940954
State: snow.Initializing,
941955
})
942956

@@ -955,7 +969,7 @@ func (m *manager) createSnowmanChain(
955969
m.Net,
956970
m.ManagerConfig.Router,
957971
m.TimeoutManager,
958-
p2p.EngineType_ENGINE_TYPE_SNOWMAN,
972+
p2ppb.EngineType_ENGINE_TYPE_SNOWMAN,
959973
sb,
960974
)
961975
if err != nil {
@@ -1095,6 +1109,17 @@ func (m *manager) createSnowmanChain(
10951109
}
10961110
vdrs.RegisterCallbackListener(ctx.SubnetID, connectedValidators)
10971111

1112+
peerTracker, err := p2p.NewPeerTracker(
1113+
ctx.Log,
1114+
"peer_tracker",
1115+
ctx.Registerer,
1116+
set.Of(ctx.NodeID),
1117+
nil,
1118+
)
1119+
if err != nil {
1120+
return nil, fmt.Errorf("error creating peer tracker: %w", err)
1121+
}
1122+
10981123
// Asynchronously passes messages from the network to the consensus engine
10991124
h, err := handler.New(
11001125
ctx,
@@ -1106,6 +1131,7 @@ func (m *manager) createSnowmanChain(
11061131
subnetConnector,
11071132
sb,
11081133
connectedValidators,
1134+
peerTracker,
11091135
)
11101136
if err != nil {
11111137
return nil, fmt.Errorf("couldn't initialize message handler: %w", err)
@@ -1165,6 +1191,7 @@ func (m *manager) createSnowmanChain(
11651191
Sender: messageSender,
11661192
BootstrapTracker: sb,
11671193
Timer: h,
1194+
PeerTracker: peerTracker,
11681195
AncestorsMaxContainersReceived: m.BootstrapAncestorsMaxContainersReceived,
11691196
DB: bootstrappingDB,
11701197
VM: vm,

snow/engine/common/tracker/peers.go

Lines changed: 4 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,9 @@ type Peers interface {
3131
ConnectedWeight() uint64
3232
// ConnectedPercent returns the currently connected stake percentage [0, 1]
3333
ConnectedPercent() float64
34-
// TotalWeight returns the total validator weight
35-
TotalWeight() uint64
3634
// SampleValidator returns a randomly selected connected validator. If there
3735
// are no currently connected validators then it will return false.
3836
SampleValidator() (ids.NodeID, bool)
39-
// PreferredPeers returns the currently connected validators. If there are
40-
// no currently connected validators then it will return the currently
41-
// connected peers.
42-
PreferredPeers() set.Set[ids.NodeID]
4337
}
4438

4539
type lockedPeers struct {
@@ -104,27 +98,13 @@ func (p *lockedPeers) ConnectedPercent() float64 {
10498
return p.peers.ConnectedPercent()
10599
}
106100

107-
func (p *lockedPeers) TotalWeight() uint64 {
108-
p.lock.RLock()
109-
defer p.lock.RUnlock()
110-
111-
return p.peers.TotalWeight()
112-
}
113-
114101
func (p *lockedPeers) SampleValidator() (ids.NodeID, bool) {
115102
p.lock.RLock()
116103
defer p.lock.RUnlock()
117104

118105
return p.peers.SampleValidator()
119106
}
120107

121-
func (p *lockedPeers) PreferredPeers() set.Set[ids.NodeID] {
122-
p.lock.RLock()
123-
defer p.lock.RUnlock()
124-
125-
return p.peers.PreferredPeers()
126-
}
127-
128108
type meteredPeers struct {
129109
Peers
130110

@@ -169,20 +149,21 @@ func NewMeteredPeers(namespace string, reg prometheus.Registerer) (Peers, error)
169149
func (p *meteredPeers) OnValidatorAdded(nodeID ids.NodeID, pk *bls.PublicKey, txID ids.ID, weight uint64) {
170150
p.Peers.OnValidatorAdded(nodeID, pk, txID, weight)
171151
p.numValidators.Inc()
172-
p.totalWeight.Set(float64(p.Peers.TotalWeight()))
152+
p.totalWeight.Add(float64(weight))
173153
p.percentConnected.Set(p.Peers.ConnectedPercent())
174154
}
175155

176156
func (p *meteredPeers) OnValidatorRemoved(nodeID ids.NodeID, weight uint64) {
177157
p.Peers.OnValidatorRemoved(nodeID, weight)
178158
p.numValidators.Dec()
179-
p.totalWeight.Set(float64(p.Peers.TotalWeight()))
159+
p.totalWeight.Sub(float64(weight))
180160
p.percentConnected.Set(p.Peers.ConnectedPercent())
181161
}
182162

183163
func (p *meteredPeers) OnValidatorWeightChanged(nodeID ids.NodeID, oldWeight, newWeight uint64) {
184164
p.Peers.OnValidatorWeightChanged(nodeID, oldWeight, newWeight)
185-
p.totalWeight.Set(float64(p.Peers.TotalWeight()))
165+
p.totalWeight.Sub(float64(oldWeight))
166+
p.totalWeight.Add(float64(newWeight))
186167
p.percentConnected.Set(p.Peers.ConnectedPercent())
187168
}
188169

@@ -269,22 +250,6 @@ func (p *peerData) ConnectedPercent() float64 {
269250
return float64(p.connectedWeight) / float64(p.totalWeight)
270251
}
271252

272-
func (p *peerData) TotalWeight() uint64 {
273-
return p.totalWeight
274-
}
275-
276253
func (p *peerData) SampleValidator() (ids.NodeID, bool) {
277254
return p.connectedValidators.Peek()
278255
}
279-
280-
func (p *peerData) PreferredPeers() set.Set[ids.NodeID] {
281-
if p.connectedValidators.Len() == 0 {
282-
connectedPeers := set.NewSet[ids.NodeID](p.connectedPeers.Len())
283-
connectedPeers.Union(p.connectedPeers)
284-
return connectedPeers
285-
}
286-
287-
connectedValidators := set.NewSet[ids.NodeID](p.connectedValidators.Len())
288-
connectedValidators.Union(p.connectedValidators)
289-
return connectedValidators
290-
}

snow/engine/common/tracker/peers_test.go

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,36 +20,23 @@ func TestPeers(t *testing.T) {
2020

2121
p := NewPeers()
2222

23-
require.Zero(p.TotalWeight())
2423
require.Zero(p.ConnectedWeight())
25-
require.Empty(p.PreferredPeers())
2624

2725
p.OnValidatorAdded(nodeID, nil, ids.Empty, 5)
2826
require.Zero(p.ConnectedWeight())
29-
require.Equal(uint64(5), p.TotalWeight())
30-
require.Empty(p.PreferredPeers())
3127

3228
require.NoError(p.Connected(context.Background(), nodeID, version.CurrentApp))
3329
require.Equal(uint64(5), p.ConnectedWeight())
34-
require.Contains(p.PreferredPeers(), nodeID)
3530

3631
p.OnValidatorWeightChanged(nodeID, 5, 10)
3732
require.Equal(uint64(10), p.ConnectedWeight())
38-
require.Equal(uint64(10), p.TotalWeight())
39-
require.Contains(p.PreferredPeers(), nodeID)
4033

4134
p.OnValidatorRemoved(nodeID, 10)
4235
require.Zero(p.ConnectedWeight())
43-
require.Zero(p.TotalWeight())
44-
require.Contains(p.PreferredPeers(), nodeID)
4536

4637
p.OnValidatorAdded(nodeID, nil, ids.Empty, 5)
4738
require.Equal(uint64(5), p.ConnectedWeight())
48-
require.Equal(uint64(5), p.TotalWeight())
49-
require.Contains(p.PreferredPeers(), nodeID)
5039

5140
require.NoError(p.Disconnected(context.Background(), nodeID))
5241
require.Zero(p.ConnectedWeight())
53-
require.Equal(uint64(5), p.TotalWeight())
54-
require.Empty(p.PreferredPeers())
5542
}

0 commit comments

Comments
 (0)