2023-01-16 15:00:11 +00:00
|
|
|
package sync
|
|
|
|
|
|
|
|
import (
|
2023-01-31 17:31:22 +00:00
|
|
|
"context"
|
|
|
|
"time"
|
|
|
|
|
2023-03-17 18:52:56 +00:00
|
|
|
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/blocks"
|
|
|
|
"github.com/prysmaticlabs/prysm/v4/config/params"
|
|
|
|
types "github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
|
|
|
|
"github.com/prysmaticlabs/prysm/v4/crypto/rand"
|
|
|
|
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
|
|
|
"github.com/prysmaticlabs/prysm/v4/time/slots"
|
2023-01-16 15:00:11 +00:00
|
|
|
)
|
|
|
|
|
2023-01-31 17:31:22 +00:00
|
|
|
const broadcastBLSChangesRateLimit = 128
|
|
|
|
|
2023-01-26 23:13:28 +00:00
|
|
|
// This routine broadcasts known BLS changes at the Capella fork.
|
|
|
|
func (s *Service) broadcastBLSChanges(currSlot types.Slot) {
|
2023-01-16 15:00:11 +00:00
|
|
|
capellaSlotStart, err := slots.EpochStart(params.BeaconConfig().CapellaForkEpoch)
|
|
|
|
if err != nil {
|
2023-01-17 10:59:51 +00:00
|
|
|
// only possible error is an overflow, so we exit early from the method
|
2023-01-26 23:13:28 +00:00
|
|
|
return
|
2023-01-16 15:00:11 +00:00
|
|
|
}
|
2023-01-26 23:13:28 +00:00
|
|
|
if currSlot != capellaSlotStart {
|
|
|
|
return
|
2023-01-16 15:00:11 +00:00
|
|
|
}
|
2023-01-26 23:13:28 +00:00
|
|
|
changes, err := s.cfg.blsToExecPool.PendingBLSToExecChanges()
|
|
|
|
if err != nil {
|
|
|
|
log.WithError(err).Error("could not get BLS to execution changes")
|
|
|
|
}
|
|
|
|
if len(changes) == 0 {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
source := rand.NewGenerator()
|
2023-01-31 17:31:22 +00:00
|
|
|
length := len(changes)
|
|
|
|
broadcastChanges := make([]*ethpb.SignedBLSToExecutionChange, length)
|
|
|
|
for i := 0; i < length; i++ {
|
2023-01-26 23:13:28 +00:00
|
|
|
idx := source.Intn(len(changes))
|
|
|
|
broadcastChanges[i] = changes[idx]
|
|
|
|
changes = append(changes[:idx], changes[idx+1:]...)
|
|
|
|
}
|
2023-01-31 17:31:22 +00:00
|
|
|
|
|
|
|
go s.rateBLSChanges(s.ctx, broadcastChanges)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Service) broadcastBLSBatch(ctx context.Context, ptr *[]*ethpb.SignedBLSToExecutionChange) {
|
|
|
|
limit := broadcastBLSChangesRateLimit
|
2023-02-02 00:01:46 +00:00
|
|
|
if len(*ptr) < broadcastBLSChangesRateLimit {
|
|
|
|
limit = len(*ptr)
|
2023-01-31 17:31:22 +00:00
|
|
|
}
|
2023-02-01 06:01:10 +00:00
|
|
|
st, err := s.cfg.chain.HeadStateReadOnly(ctx)
|
2023-01-31 17:31:22 +00:00
|
|
|
if err != nil {
|
|
|
|
log.WithError(err).Error("could not get head state")
|
|
|
|
return
|
|
|
|
}
|
2023-02-02 00:01:46 +00:00
|
|
|
for _, ch := range (*ptr)[:limit] {
|
2023-01-31 17:31:22 +00:00
|
|
|
if ch != nil {
|
|
|
|
_, err := blocks.ValidateBLSToExecutionChange(st, ch)
|
|
|
|
if err != nil {
|
|
|
|
log.WithError(err).Error("could not validate BLS to execution change")
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
if err := s.cfg.p2p.Broadcast(ctx, ch); err != nil {
|
|
|
|
log.WithError(err).Error("could not broadcast BLS to execution changes.")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-02-02 00:01:46 +00:00
|
|
|
*ptr = (*ptr)[limit:]
|
2023-01-31 17:31:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Service) rateBLSChanges(ctx context.Context, changes []*ethpb.SignedBLSToExecutionChange) {
|
|
|
|
s.broadcastBLSBatch(ctx, &changes)
|
|
|
|
if len(changes) == 0 {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
ticker := time.NewTicker(500 * time.Millisecond)
|
|
|
|
for {
|
|
|
|
select {
|
|
|
|
case <-s.ctx.Done():
|
|
|
|
return
|
|
|
|
case <-ticker.C:
|
|
|
|
s.broadcastBLSBatch(ctx, &changes)
|
|
|
|
if len(changes) == 0 {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-01-16 15:00:11 +00:00
|
|
|
}
|