Files
prysm/beacon-chain/sync/rpc_light_client.go
Preston Van Loon 2fd6bd8150 Add golang.org/x/tools modernize static analyzer and fix violations (#15946)
* Ran gopls modernize to fix everything

go run golang.org/x/tools/gopls/internal/analysis/modernize/cmd/modernize@latest -fix -test ./...

* Override rules_go provided dependency for golang.org/x/tools to v0.38.0.

To update this, checked out rules_go, then ran `bazel run //go/tools/releaser -- upgrade-dep -mirror=false org_golang_x_tools` and copied the patches.

* Fix buildtag violations and ignore buildtag violations in external

* Introduce modernize analyzer package.

* Add modernize "any" analyzer.

* Fix violations of any analyzer

* Add modernize "appendclipped" analyzer.

* Fix violations of appendclipped

* Add modernize "bloop" analyzer.

* Add modernize "fmtappendf" analyzer.

* Add modernize "forvar" analyzer.

* Add modernize "mapsloop" analyzer.

* Add modernize "minmax" analyzer.

* Fix violations of minmax analyzer

* Add modernize "omitzero" analyzer.

* Add modernize "rangeint" analyzer.

* Fix violations of rangeint.

* Add modernize "reflecttypefor" analyzer.

* Fix violations of reflecttypefor analyzer.

* Add modernize "slicescontains" analyzer.

* Add modernize "slicessort" analyzer.

* Add modernize "slicesdelete" analyzer. This is disabled by default for now. See https://go.dev/issue/73686.

* Add modernize "stringscutprefix" analyzer.

* Add modernize "stringsbuilder" analyzer.

* Fix violations of stringsbuilder analyzer.

* Add modernize "stringsseq" analyzer.

* Add modernize "testingcontext" analyzer.

* Add modernize "waitgroup" analyzer.

* Changelog fragment

* gofmt

* gazelle

* Add modernize "newexpr" analyzer.

* Disable newexpr until go1.26

* Add more details in WORKSPACE on how to update the override

* @nalepae feedback on min()

* gofmt

* Fix violations of forvar
2025-11-14 01:27:22 +00:00

228 lines
8.3 KiB
Go

package sync
import (
"context"
"fmt"
"github.com/OffchainLabs/prysm/v7/beacon-chain/p2p"
"github.com/OffchainLabs/prysm/v7/beacon-chain/p2p/types"
fieldparams "github.com/OffchainLabs/prysm/v7/config/fieldparams"
"github.com/OffchainLabs/prysm/v7/config/params"
"github.com/OffchainLabs/prysm/v7/math"
"github.com/OffchainLabs/prysm/v7/monitoring/tracing"
"github.com/OffchainLabs/prysm/v7/monitoring/tracing/trace"
eth "github.com/OffchainLabs/prysm/v7/proto/prysm/v1alpha1"
libp2pcore "github.com/libp2p/go-libp2p/core"
)
// lightClientBootstrapRPCHandler handles the /eth2/beacon_chain/req/light_client_bootstrap/1/ RPC request.
func (s *Service) lightClientBootstrapRPCHandler(ctx context.Context, msg any, stream libp2pcore.Stream) error {
ctx, span := trace.StartSpan(ctx, "sync.lightClientBootstrapRPCHandler")
defer span.End()
ctx, cancel := context.WithTimeout(ctx, ttfbTimeout)
defer cancel()
logger := log.WithField("handler", p2p.LightClientBootstrapName[1:])
SetRPCStreamDeadlines(stream)
if err := s.rateLimiter.validateRequest(stream, 1); err != nil {
logger.WithError(err).Error("Cannot validate request")
return err
}
s.rateLimiter.add(stream, 1)
rawMsg, ok := msg.(*[fieldparams.RootLength]byte)
if !ok {
logger.Error("Message is not *types.LightClientBootstrapReq")
return fmt.Errorf("message is not type %T", &[fieldparams.RootLength]byte{})
}
blkRoot := *rawMsg
bootstrap, err := s.lcStore.LightClientBootstrap(ctx, blkRoot)
if err != nil {
s.writeErrorResponseToStream(responseCodeServerError, types.ErrGeneric.Error(), stream)
tracing.AnnotateError(span, err)
logger.WithError(err).Error("Cannot bootstrap light client")
return err
}
if bootstrap == nil {
s.writeErrorResponseToStream(responseCodeResourceUnavailable, types.ErrResourceUnavailable.Error(), stream)
tracing.AnnotateError(span, err)
logger.WithError(err).Error(fmt.Sprintf("nil bootstrap for root %#x", blkRoot))
return err
}
SetStreamWriteDeadline(stream, defaultWriteDuration)
if err = WriteLightClientBootstrapChunk(stream, s.cfg.clock, s.cfg.p2p.Encoding(), bootstrap); err != nil {
s.writeErrorResponseToStream(responseCodeServerError, types.ErrGeneric.Error(), stream)
tracing.AnnotateError(span, err)
logger.WithError(err).Error("WriteLightClientBootstrapChunk")
return err
}
logger.Info("lightClientBootstrapRPCHandler completed")
closeStream(stream, logger)
return nil
}
// lightClientUpdatesByRangeRPCHandler handles the /eth2/beacon_chain/req/light_client_updates_by_range/1/ RPC request.
func (s *Service) lightClientUpdatesByRangeRPCHandler(ctx context.Context, msg any, stream libp2pcore.Stream) error {
ctx, span := trace.StartSpan(ctx, "sync.lightClientUpdatesByRangeRPCHandler")
defer span.End()
ctx, cancel := context.WithTimeout(ctx, ttfbTimeout)
defer cancel()
logger := log.WithField("handler", p2p.LightClientUpdatesByRangeName[1:])
remotePeer := stream.Conn().RemotePeer()
SetRPCStreamDeadlines(stream)
if err := s.rateLimiter.validateRequest(stream, 1); err != nil {
logger.WithError(err).Error("Cannot validate request")
return err
}
s.rateLimiter.add(stream, 1)
r, ok := msg.(*eth.LightClientUpdatesByRangeRequest)
if !ok {
logger.Error("Message is not *eth.LightClientUpdatesByRangeReq")
return fmt.Errorf("message is not type %T", &eth.LightClientUpdatesByRangeRequest{})
}
if r.Count == 0 {
s.writeErrorResponseToStream(responseCodeInvalidRequest, "count is 0", stream)
s.downscorePeer(remotePeer, "lightClientUpdatesByRangeRPCHandlerCount0")
logger.Error("Count is 0")
return nil
}
if r.Count > params.BeaconConfig().MaxRequestLightClientUpdates {
r.Count = params.BeaconConfig().MaxRequestLightClientUpdates
}
endPeriod, err := math.Add64(r.StartPeriod, r.Count-1)
if err != nil {
s.writeErrorResponseToStream(responseCodeInvalidRequest, err.Error(), stream)
s.downscorePeer(remotePeer, "lightClientUpdatesByRangeRPCHandlerEndPeriodOverflow")
tracing.AnnotateError(span, err)
logger.WithError(err).Error("End period overflows")
return err
}
logger.Infof("LC: requesting updates by range (StartPeriod: %d, EndPeriod: %d)", r.StartPeriod, r.StartPeriod+r.Count-1)
headBlock, err := s.cfg.chain.HeadBlock(ctx)
if err != nil {
s.writeErrorResponseToStream(responseCodeServerError, types.ErrGeneric.Error(), stream)
tracing.AnnotateError(span, err)
logger.WithError(err).Error("Cannot retrieve head block")
return err
}
updates, err := s.lcStore.LightClientUpdates(ctx, r.StartPeriod, endPeriod, headBlock)
if err != nil {
s.writeErrorResponseToStream(responseCodeServerError, types.ErrGeneric.Error(), stream)
tracing.AnnotateError(span, err)
logger.WithError(err).Error("Cannot retrieve light client updates")
return err
}
if len(updates) == 0 {
s.writeErrorResponseToStream(responseCodeResourceUnavailable, types.ErrResourceUnavailable.Error(), stream)
tracing.AnnotateError(span, err)
logger.Debugf("No update available for start period %d", r.StartPeriod)
return nil
}
for _, u := range updates {
SetStreamWriteDeadline(stream, defaultWriteDuration)
if err = WriteLightClientUpdateChunk(stream, s.cfg.clock, s.cfg.p2p.Encoding(), u); err != nil {
s.writeErrorResponseToStream(responseCodeServerError, types.ErrGeneric.Error(), stream)
tracing.AnnotateError(span, err)
logger.WithError(err).Error("WriteLightClientUpdateChunk")
return err
}
s.rateLimiter.add(stream, 1)
}
logger.Info("lightClientUpdatesByRangeRPCHandler completed")
closeStream(stream, logger)
return nil
}
// lightClientFinalityUpdateRPCHandler handles the /eth2/beacon_chain/req/light_client_finality_update/1/ RPC request.
func (s *Service) lightClientFinalityUpdateRPCHandler(ctx context.Context, _ any, stream libp2pcore.Stream) error {
ctx, span := trace.StartSpan(ctx, "sync.lightClientFinalityUpdateRPCHandler")
defer span.End()
_, cancel := context.WithTimeout(ctx, ttfbTimeout)
defer cancel()
logger := log.WithField("handler", p2p.LightClientFinalityUpdateName[1:])
SetRPCStreamDeadlines(stream)
if err := s.rateLimiter.validateRequest(stream, 1); err != nil {
logger.WithError(err).Error("Cannot validate request")
return err
}
s.rateLimiter.add(stream, 1)
if s.lcStore.LastFinalityUpdate() == nil {
s.writeErrorResponseToStream(responseCodeResourceUnavailable, types.ErrResourceUnavailable.Error(), stream)
logger.Error("No finality update available")
return nil
}
SetStreamWriteDeadline(stream, defaultWriteDuration)
if err := WriteLightClientFinalityUpdateChunk(stream, s.cfg.clock, s.cfg.p2p.Encoding(), s.lcStore.LastFinalityUpdate()); err != nil {
s.writeErrorResponseToStream(responseCodeServerError, types.ErrGeneric.Error(), stream)
tracing.AnnotateError(span, err)
logger.WithError(err).Error("WriteLightClientFinalityUpdateChunk")
return err
}
logger.Info("lightClientFinalityUpdateRPCHandler completed")
closeStream(stream, logger)
return nil
}
// lightClientOptimisticUpdateRPCHandler handles the /eth2/beacon_chain/req/light_client_optimistic_update/1/ RPC request.
func (s *Service) lightClientOptimisticUpdateRPCHandler(ctx context.Context, _ any, stream libp2pcore.Stream) error {
ctx, span := trace.StartSpan(ctx, "sync.lightClientOptimisticUpdateRPCHandler")
defer span.End()
_, cancel := context.WithTimeout(ctx, ttfbTimeout)
defer cancel()
logger := log.WithField("handler", p2p.LightClientOptimisticUpdateName[1:])
logger.Info("lightClientOptimisticUpdateRPCHandler invoked")
SetRPCStreamDeadlines(stream)
if err := s.rateLimiter.validateRequest(stream, 1); err != nil {
logger.WithError(err).Error("Cannot validate request")
return err
}
s.rateLimiter.add(stream, 1)
if s.lcStore.LastOptimisticUpdate() == nil {
s.writeErrorResponseToStream(responseCodeResourceUnavailable, types.ErrResourceUnavailable.Error(), stream)
logger.Error("No optimistic update available")
return nil
}
SetStreamWriteDeadline(stream, defaultWriteDuration)
if err := WriteLightClientOptimisticUpdateChunk(stream, s.cfg.clock, s.cfg.p2p.Encoding(), s.lcStore.LastOptimisticUpdate()); err != nil {
s.writeErrorResponseToStream(responseCodeServerError, types.ErrGeneric.Error(), stream)
tracing.AnnotateError(span, err)
logger.WithError(err).Error("WriteLightClientOptimisticUpdateChunk")
return err
}
logger.Info("lightClientOptimisticUpdateRPCHandler completed")
closeStream(stream, logger)
return nil
}