mirror of
https://gitlab.com/pulsechaincom/prysm-pulse.git
synced 2024-12-24 20:37:17 +00:00
QSP-45 Add Check for No Connected Peers BestFinalized (#6402)
* no error returned * no target root * fix build * Merge refs/heads/master into best-finalized
This commit is contained in:
parent
252f758baa
commit
ab89053597
@ -9,7 +9,6 @@ go_library(
|
||||
deps = [
|
||||
"//beacon-chain/core/helpers:go_default_library",
|
||||
"//proto/beacon/p2p/v1:go_default_library",
|
||||
"//shared/bytesutil:go_default_library",
|
||||
"//shared/roughtime:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//p2p/enr:go_default_library",
|
||||
"@com_github_gogo_protobuf//proto:go_default_library",
|
||||
|
@ -34,7 +34,6 @@ import (
|
||||
"github.com/prysmaticlabs/go-bitfield"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
"github.com/prysmaticlabs/prysm/shared/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/roughtime"
|
||||
)
|
||||
|
||||
@ -427,33 +426,29 @@ func (p *Status) Decay() {
|
||||
// Ideally, all peers would be reporting the same finalized epoch but some may be behind due to their own latency, or because of
|
||||
// their finalized epoch at the time we queried them.
|
||||
// Returns the best finalized root, epoch number, and list of peers that are at or beyond that epoch.
|
||||
func (p *Status) BestFinalized(maxPeers int, ourFinalizedEpoch uint64) ([]byte, uint64, []peer.ID) {
|
||||
func (p *Status) BestFinalized(maxPeers int, ourFinalizedEpoch uint64) (uint64, []peer.ID) {
|
||||
connected := p.Connected()
|
||||
finalized := make(map[[32]byte]uint64)
|
||||
rootToEpoch := make(map[[32]byte]uint64)
|
||||
finalizedEpochVotes := make(map[uint64]uint64)
|
||||
pidEpoch := make(map[peer.ID]uint64)
|
||||
potentialPIDs := make([]peer.ID, 0, len(connected))
|
||||
for _, pid := range connected {
|
||||
peerChainState, err := p.ChainState(pid)
|
||||
if err == nil && peerChainState != nil && peerChainState.FinalizedEpoch >= ourFinalizedEpoch {
|
||||
root := bytesutil.ToBytes32(peerChainState.FinalizedRoot)
|
||||
finalized[root]++
|
||||
rootToEpoch[root] = peerChainState.FinalizedEpoch
|
||||
finalizedEpochVotes[peerChainState.FinalizedEpoch]++
|
||||
pidEpoch[pid] = peerChainState.FinalizedEpoch
|
||||
potentialPIDs = append(potentialPIDs, pid)
|
||||
}
|
||||
}
|
||||
|
||||
// Select the target epoch, which is the epoch most peers agree upon.
|
||||
var targetRoot [32]byte
|
||||
var targetEpoch uint64
|
||||
var mostVotes uint64
|
||||
for root, count := range finalized {
|
||||
for epoch, count := range finalizedEpochVotes {
|
||||
if count > mostVotes {
|
||||
mostVotes = count
|
||||
targetRoot = root
|
||||
targetEpoch = epoch
|
||||
}
|
||||
}
|
||||
targetEpoch := rootToEpoch[targetRoot]
|
||||
|
||||
// Sort PIDs by finalized epoch, in decreasing order.
|
||||
sort.Slice(potentialPIDs, func(i, j int) bool {
|
||||
@ -473,7 +468,7 @@ func (p *Status) BestFinalized(maxPeers int, ourFinalizedEpoch uint64) ([]byte,
|
||||
potentialPIDs = potentialPIDs[:maxPeers]
|
||||
}
|
||||
|
||||
return targetRoot[:], targetEpoch, potentialPIDs
|
||||
return targetEpoch, potentialPIDs
|
||||
}
|
||||
|
||||
// fetch is a helper function that fetches a peer status, possibly creating it.
|
||||
|
@ -1,7 +1,6 @@
|
||||
package peers_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
"reflect"
|
||||
@ -12,6 +11,7 @@ import (
|
||||
peer "github.com/libp2p/go-libp2p-peer"
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
"github.com/prysmaticlabs/go-bitfield"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/p2p/peers"
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
@ -561,7 +561,7 @@ func TestTrimmedOrderedPeers(t *testing.T) {
|
||||
FinalizedRoot: mockroot2[:],
|
||||
})
|
||||
|
||||
_, target, pids := p.BestFinalized(maxPeers, 0)
|
||||
target, pids := p.BestFinalized(maxPeers, 0)
|
||||
if target != expectedTarget {
|
||||
t.Errorf("Incorrect target epoch retrieved; wanted %v but got %v", expectedTarget, target)
|
||||
}
|
||||
@ -624,10 +624,7 @@ func TestBestPeer(t *testing.T) {
|
||||
FinalizedEpoch: 3,
|
||||
FinalizedRoot: junkRoot[:],
|
||||
})
|
||||
retRoot, retEpoch, _ := p.BestFinalized(15, 0)
|
||||
if !bytes.Equal(retRoot, expectedRoot[:]) {
|
||||
t.Errorf("Incorrect Finalized Root retrieved; wanted %v but got %v", expectedRoot, retRoot)
|
||||
}
|
||||
retEpoch, _ := p.BestFinalized(15, 0)
|
||||
if retEpoch != expectedFinEpoch {
|
||||
t.Errorf("Incorrect Finalized epoch retrieved; wanted %v but got %v", expectedFinEpoch, retEpoch)
|
||||
}
|
||||
@ -646,7 +643,7 @@ func TestBestFinalized_returnsMaxValue(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
_, _, pids := p.BestFinalized(maxPeers, 0)
|
||||
_, pids := p.BestFinalized(maxPeers, 0)
|
||||
if len(pids) != maxPeers {
|
||||
t.Fatalf("returned wrong number of peers, wanted %d, got %d", maxPeers, len(pids))
|
||||
}
|
||||
|
@ -233,8 +233,7 @@ func (f *blocksFetcher) handleRequest(ctx context.Context, start, count uint64)
|
||||
}
|
||||
|
||||
headEpoch := helpers.SlotToEpoch(f.headFetcher.HeadSlot())
|
||||
_, finalizedEpoch, peers := f.p2p.Peers().BestFinalized(params.BeaconConfig().MaxPeersToSync, headEpoch)
|
||||
|
||||
finalizedEpoch, peers := f.p2p.Peers().BestFinalized(params.BeaconConfig().MaxPeersToSync, headEpoch)
|
||||
if len(peers) == 0 {
|
||||
response.err = errNoPeersAvailable
|
||||
return response
|
||||
@ -401,7 +400,7 @@ func (f *blocksFetcher) waitForMinimumPeers(ctx context.Context) ([]peer.ID, err
|
||||
return nil, ctx.Err()
|
||||
}
|
||||
headEpoch := helpers.SlotToEpoch(f.headFetcher.HeadSlot())
|
||||
_, _, peers := f.p2p.Peers().BestFinalized(params.BeaconConfig().MaxPeersToSync, headEpoch)
|
||||
_, peers := f.p2p.Peers().BestFinalized(params.BeaconConfig().MaxPeersToSync, headEpoch)
|
||||
if len(peers) >= required {
|
||||
return peers, nil
|
||||
}
|
||||
@ -459,7 +458,7 @@ func (f *blocksFetcher) nonSkippedSlotAfter(ctx context.Context, slot uint64) (u
|
||||
defer span.End()
|
||||
|
||||
headEpoch := helpers.SlotToEpoch(f.headFetcher.HeadSlot())
|
||||
_, epoch, peers := f.p2p.Peers().BestFinalized(params.BeaconConfig().MaxPeersToSync, headEpoch)
|
||||
epoch, peers := f.p2p.Peers().BestFinalized(params.BeaconConfig().MaxPeersToSync, headEpoch)
|
||||
var err error
|
||||
peers, err = f.filterPeers(peers, peersPercentagePerRequest)
|
||||
if err != nil {
|
||||
@ -541,6 +540,6 @@ func (f *blocksFetcher) nonSkippedSlotAfter(ctx context.Context, slot uint64) (u
|
||||
// bestFinalizedSlot returns the highest finalized slot of the majority of connected peers.
|
||||
func (f *blocksFetcher) bestFinalizedSlot() uint64 {
|
||||
headEpoch := helpers.SlotToEpoch(f.headFetcher.HeadSlot())
|
||||
_, finalizedEpoch, _ := f.p2p.Peers().BestFinalized(params.BeaconConfig().MaxPeersToSync, headEpoch)
|
||||
finalizedEpoch, _ := f.p2p.Peers().BestFinalized(params.BeaconConfig().MaxPeersToSync, headEpoch)
|
||||
return helpers.StartSlot(finalizedEpoch)
|
||||
}
|
||||
|
@ -503,7 +503,7 @@ func TestBlocksFetcher_requestBeaconBlocksByRange(t *testing.T) {
|
||||
p2p: p2p,
|
||||
})
|
||||
|
||||
_, _, peers := p2p.Peers().BestFinalized(params.BeaconConfig().MaxPeersToSync, helpers.SlotToEpoch(mc.HeadSlot()))
|
||||
_, peers := p2p.Peers().BestFinalized(params.BeaconConfig().MaxPeersToSync, helpers.SlotToEpoch(mc.HeadSlot()))
|
||||
req := &p2ppb.BeaconBlocksByRangeRequest{
|
||||
StartSlot: 1,
|
||||
Step: 1,
|
||||
|
@ -84,11 +84,11 @@ func (s *Service) roundRobinSync(genesis time.Time) error {
|
||||
p2p: s.p2p,
|
||||
headFetcher: s.chain,
|
||||
})
|
||||
_, _, pids := s.p2p.Peers().BestFinalized(1 /* maxPeers */, s.highestFinalizedEpoch())
|
||||
_, pids := s.p2p.Peers().BestFinalized(1 /* maxPeers */, s.highestFinalizedEpoch())
|
||||
for len(pids) == 0 {
|
||||
log.Info("Waiting for a suitable peer before syncing to the head of the chain")
|
||||
time.Sleep(refreshTime)
|
||||
_, _, pids = s.p2p.Peers().BestFinalized(1 /* maxPeers */, s.highestFinalizedEpoch())
|
||||
_, pids = s.p2p.Peers().BestFinalized(1 /* maxPeers */, s.highestFinalizedEpoch())
|
||||
}
|
||||
best := pids[0]
|
||||
|
||||
|
@ -214,7 +214,7 @@ func (s *Service) waitForMinimumPeers() {
|
||||
required = flags.Get().MinimumSyncPeers
|
||||
}
|
||||
for {
|
||||
_, _, peers := s.p2p.Peers().BestFinalized(params.BeaconConfig().MaxPeersToSync, s.chain.FinalizedCheckpt().Epoch)
|
||||
_, peers := s.p2p.Peers().BestFinalized(params.BeaconConfig().MaxPeersToSync, s.chain.FinalizedCheckpt().Epoch)
|
||||
if len(peers) >= required {
|
||||
break
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ func (s *Service) resyncIfBehind() {
|
||||
runutil.RunEvery(s.ctx, interval, func() {
|
||||
if s.shouldReSync() {
|
||||
syncedEpoch := helpers.SlotToEpoch(s.chain.HeadSlot())
|
||||
_, highestEpoch, _ := s.p2p.Peers().BestFinalized(params.BeaconConfig().MaxPeersToSync, syncedEpoch)
|
||||
highestEpoch, _ := s.p2p.Peers().BestFinalized(params.BeaconConfig().MaxPeersToSync, syncedEpoch)
|
||||
if helpers.StartSlot(highestEpoch) > s.chain.HeadSlot() {
|
||||
log.WithFields(logrus.Fields{
|
||||
"currentEpoch": helpers.SlotToEpoch(s.chain.CurrentSlot()),
|
||||
|
Loading…
Reference in New Issue
Block a user