mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-09 15:37:56 -05:00
* 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
366 lines
13 KiB
Go
366 lines
13 KiB
Go
package p2p
|
|
|
|
import (
|
|
"reflect"
|
|
|
|
p2ptypes "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/consensus-types/primitives"
|
|
pb "github.com/OffchainLabs/prysm/v7/proto/prysm/v1alpha1"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
const (
|
|
// SchemaVersionV1 specifies the schema version for our rpc protocol ID.
|
|
SchemaVersionV1 = "/1"
|
|
|
|
// SchemaVersionV2 specifies the next schema version for our rpc protocol ID.
|
|
SchemaVersionV2 = "/2"
|
|
|
|
// SchemaVersionV3 specifies the next schema version for our rpc protocol ID.
|
|
SchemaVersionV3 = "/3"
|
|
)
|
|
|
|
const (
|
|
// Specifies the protocol prefix for all our Req/Resp topics.
|
|
protocolPrefix = "/eth2/beacon_chain/req"
|
|
|
|
// StatusMessageName specifies the name for the status message topic.
|
|
StatusMessageName = "/status"
|
|
|
|
// GoodbyeMessageName specifies the name for the goodbye message topic.
|
|
GoodbyeMessageName = "/goodbye"
|
|
|
|
// BeaconBlocksByRangeMessageName specifies the name for the beacon blocks by range message topic.
|
|
BeaconBlocksByRangeMessageName = "/beacon_blocks_by_range"
|
|
|
|
// BeaconBlocksByRootsMessageName specifies the name for the beacon blocks by root message topic.
|
|
BeaconBlocksByRootsMessageName = "/beacon_blocks_by_root"
|
|
|
|
// PingMessageName Specifies the name for the ping message topic.
|
|
PingMessageName = "/ping"
|
|
|
|
// MetadataMessageName specifies the name for the metadata message topic.
|
|
MetadataMessageName = "/metadata"
|
|
|
|
// BlobSidecarsByRangeName is the name for the BlobSidecarsByRange v1 message topic.
|
|
BlobSidecarsByRangeName = "/blob_sidecars_by_range"
|
|
|
|
// BlobSidecarsByRootName is the name for the BlobSidecarsByRoot v1 message topic.
|
|
BlobSidecarsByRootName = "/blob_sidecars_by_root"
|
|
|
|
// LightClientBootstrapName is the name for the LightClientBootstrap message topic,
|
|
LightClientBootstrapName = "/light_client_bootstrap"
|
|
|
|
// LightClientUpdatesByRangeName is the name for the LightClientUpdatesByRange topic.
|
|
LightClientUpdatesByRangeName = "/light_client_updates_by_range"
|
|
|
|
// LightClientFinalityUpdateName is the name for the LightClientFinalityUpdate topic.
|
|
LightClientFinalityUpdateName = "/light_client_finality_update"
|
|
|
|
// LightClientOptimisticUpdateName is the name for the LightClientOptimisticUpdate topic.
|
|
LightClientOptimisticUpdateName = "/light_client_optimistic_update"
|
|
|
|
// DataColumnSidecarsByRootName is the name for the DataColumnSidecarsByRoot v1 message topic.
|
|
DataColumnSidecarsByRootName = "/data_column_sidecars_by_root"
|
|
|
|
// DataColumnSidecarsByRangeName is the name for the DataColumnSidecarsByRange v1 message topic.
|
|
DataColumnSidecarsByRangeName = "/data_column_sidecars_by_range"
|
|
)
|
|
|
|
const (
|
|
// V1 RPC Topics
|
|
// RPCStatusTopicV1 defines the v1 topic for the status rpc method.
|
|
RPCStatusTopicV1 = protocolPrefix + StatusMessageName + SchemaVersionV1
|
|
// RPCGoodByeTopicV1 defines the v1 topic for the goodbye rpc method.
|
|
RPCGoodByeTopicV1 = protocolPrefix + GoodbyeMessageName + SchemaVersionV1
|
|
// RPCBlocksByRangeTopicV1 defines v1 the topic for the blocks by range rpc method.
|
|
RPCBlocksByRangeTopicV1 = protocolPrefix + BeaconBlocksByRangeMessageName + SchemaVersionV1
|
|
// RPCBlocksByRootTopicV1 defines the v1 topic for the blocks by root rpc method.
|
|
RPCBlocksByRootTopicV1 = protocolPrefix + BeaconBlocksByRootsMessageName + SchemaVersionV1
|
|
// RPCPingTopicV1 defines the v1 topic for the ping rpc method.
|
|
RPCPingTopicV1 = protocolPrefix + PingMessageName + SchemaVersionV1
|
|
// RPCMetaDataTopicV1 defines the v1 topic for the metadata rpc method.
|
|
RPCMetaDataTopicV1 = protocolPrefix + MetadataMessageName + SchemaVersionV1
|
|
|
|
// RPCBlobSidecarsByRangeTopicV1 is a topic for requesting blob sidecars
|
|
// in the slot range [start_slot, start_slot + count), leading up to the current head block as selected by fork choice.
|
|
// /eth2/beacon_chain/req/blob_sidecars_by_range/1/ - New in deneb.
|
|
RPCBlobSidecarsByRangeTopicV1 = protocolPrefix + BlobSidecarsByRangeName + SchemaVersionV1
|
|
// RPCBlobSidecarsByRootTopicV1 is a topic for requesting blob sidecars by their block root.
|
|
// /eth2/beacon_chain/req/blob_sidecars_by_root/1/ - New in deneb.
|
|
RPCBlobSidecarsByRootTopicV1 = protocolPrefix + BlobSidecarsByRootName + SchemaVersionV1
|
|
|
|
// RPCLightClientBootstrapTopicV1 is a topic for requesting a light client bootstrap.
|
|
RPCLightClientBootstrapTopicV1 = protocolPrefix + LightClientBootstrapName + SchemaVersionV1
|
|
// RPCLightClientUpdatesByRangeTopicV1 is a topic for requesting light client updates by range.
|
|
RPCLightClientUpdatesByRangeTopicV1 = protocolPrefix + LightClientUpdatesByRangeName + SchemaVersionV1
|
|
// RPCLightClientFinalityUpdateTopicV1 is a topic for requesting a light client finality update.
|
|
RPCLightClientFinalityUpdateTopicV1 = protocolPrefix + LightClientFinalityUpdateName + SchemaVersionV1
|
|
// RPCLightClientOptimisticUpdateTopicV1 is a topic for requesting a light client Optimistic update.
|
|
RPCLightClientOptimisticUpdateTopicV1 = protocolPrefix + LightClientOptimisticUpdateName + SchemaVersionV1
|
|
// RPCDataColumnSidecarsByRootTopicV1 is a topic for requesting data column sidecars by their block root.
|
|
// /eth2/beacon_chain/req/data_column_sidecars_by_root/1 - New in Fulu.
|
|
RPCDataColumnSidecarsByRootTopicV1 = protocolPrefix + DataColumnSidecarsByRootName + SchemaVersionV1
|
|
// RPCDataColumnSidecarsByRangeTopicV1 is a topic for requesting data column sidecars by their slot.
|
|
// /eth2/beacon_chain/req/data_column_sidecars_by_range/1 - New in Fulu.
|
|
RPCDataColumnSidecarsByRangeTopicV1 = protocolPrefix + DataColumnSidecarsByRangeName + SchemaVersionV1
|
|
|
|
// V2 RPC Topics
|
|
// RPCStatusTopicV2 defines the v1 topic for the status rpc method.
|
|
RPCStatusTopicV2 = protocolPrefix + StatusMessageName + SchemaVersionV2
|
|
// RPCBlocksByRangeTopicV2 defines v2 the topic for the blocks by range rpc method.
|
|
RPCBlocksByRangeTopicV2 = protocolPrefix + BeaconBlocksByRangeMessageName + SchemaVersionV2
|
|
// RPCBlocksByRootTopicV2 defines the v2 topic for the blocks by root rpc method.
|
|
RPCBlocksByRootTopicV2 = protocolPrefix + BeaconBlocksByRootsMessageName + SchemaVersionV2
|
|
// RPCMetaDataTopicV2 defines the v2 topic for the metadata rpc method.
|
|
RPCMetaDataTopicV2 = protocolPrefix + MetadataMessageName + SchemaVersionV2
|
|
|
|
// V3 RPC Topics
|
|
// RPCMetaDataTopicV3 defines the v3 topic for the metadata rpc method.
|
|
RPCMetaDataTopicV3 = protocolPrefix + MetadataMessageName + SchemaVersionV3
|
|
)
|
|
|
|
// RPC errors for topic parsing.
|
|
const (
|
|
invalidRPCMessageType = "provided message type doesn't have a registered mapping"
|
|
)
|
|
|
|
// RPCTopicMappings map the base message type to the rpc request.
|
|
var (
|
|
RPCTopicMappings = map[string]any{
|
|
// RPC Status Message
|
|
RPCStatusTopicV1: new(pb.Status),
|
|
RPCStatusTopicV2: new(pb.StatusV2),
|
|
|
|
// RPC Goodbye Message
|
|
RPCGoodByeTopicV1: new(primitives.SSZUint64),
|
|
|
|
// RPC Block By Range Message
|
|
RPCBlocksByRangeTopicV1: new(pb.BeaconBlocksByRangeRequest),
|
|
RPCBlocksByRangeTopicV2: new(pb.BeaconBlocksByRangeRequest),
|
|
|
|
// RPC Block By Root Message
|
|
RPCBlocksByRootTopicV1: new(p2ptypes.BeaconBlockByRootsReq),
|
|
RPCBlocksByRootTopicV2: new(p2ptypes.BeaconBlockByRootsReq),
|
|
|
|
// RPC Ping Message
|
|
RPCPingTopicV1: new(primitives.SSZUint64),
|
|
|
|
// RPC Metadata Message
|
|
RPCMetaDataTopicV1: new(any),
|
|
RPCMetaDataTopicV2: new(any),
|
|
RPCMetaDataTopicV3: new(any),
|
|
|
|
// BlobSidecarsByRange v1 Message
|
|
RPCBlobSidecarsByRangeTopicV1: new(pb.BlobSidecarsByRangeRequest),
|
|
|
|
// BlobSidecarsByRoot v1 Message
|
|
RPCBlobSidecarsByRootTopicV1: new(p2ptypes.BlobSidecarsByRootReq),
|
|
|
|
// Light client
|
|
RPCLightClientBootstrapTopicV1: new([fieldparams.RootLength]byte),
|
|
RPCLightClientUpdatesByRangeTopicV1: new(pb.LightClientUpdatesByRangeRequest),
|
|
RPCLightClientFinalityUpdateTopicV1: new(any),
|
|
RPCLightClientOptimisticUpdateTopicV1: new(any),
|
|
|
|
// DataColumnSidecarsByRange v1 Message
|
|
RPCDataColumnSidecarsByRangeTopicV1: new(pb.DataColumnSidecarsByRangeRequest),
|
|
|
|
// DataColumnSidecarsByRoot v1 Message
|
|
RPCDataColumnSidecarsByRootTopicV1: p2ptypes.DataColumnsByRootIdentifiers{},
|
|
}
|
|
|
|
// Maps all registered protocol prefixes.
|
|
protocolMapping = map[string]bool{
|
|
protocolPrefix: true,
|
|
}
|
|
|
|
// Maps all the protocol message names for the different rpc topics.
|
|
messageMapping = map[string]bool{
|
|
StatusMessageName: true,
|
|
GoodbyeMessageName: true,
|
|
BeaconBlocksByRangeMessageName: true,
|
|
BeaconBlocksByRootsMessageName: true,
|
|
PingMessageName: true,
|
|
MetadataMessageName: true,
|
|
BlobSidecarsByRangeName: true,
|
|
BlobSidecarsByRootName: true,
|
|
LightClientBootstrapName: true,
|
|
LightClientUpdatesByRangeName: true,
|
|
LightClientFinalityUpdateName: true,
|
|
LightClientOptimisticUpdateName: true,
|
|
DataColumnSidecarsByRootName: true,
|
|
DataColumnSidecarsByRangeName: true,
|
|
}
|
|
|
|
// Maps all the RPC messages which are to updated in altair.
|
|
altairMapping = map[string]string{
|
|
BeaconBlocksByRangeMessageName: SchemaVersionV2,
|
|
BeaconBlocksByRootsMessageName: SchemaVersionV2,
|
|
MetadataMessageName: SchemaVersionV2,
|
|
}
|
|
|
|
// Maps all the RPC messages which are to updated in fulu.
|
|
fuluMapping = map[string]string{
|
|
StatusMessageName: SchemaVersionV2,
|
|
MetadataMessageName: SchemaVersionV3,
|
|
}
|
|
|
|
versionMapping = map[string]bool{
|
|
SchemaVersionV1: true,
|
|
SchemaVersionV2: true,
|
|
SchemaVersionV3: true,
|
|
}
|
|
|
|
// OmitContextBytesV1 keeps track of which RPC methods do not write context bytes in their v1 incarnations.
|
|
// Phase0 did not have the notion of context bytes, which prefix wire-encoded values with a [4]byte identifier
|
|
// to convey the schema for the receiver to use. These RPCs had a version bump to V2 when the context byte encoding
|
|
// was introduced. For other RPC methods, context bytes are always required.
|
|
OmitContextBytesV1 = map[string]bool{
|
|
StatusMessageName: true,
|
|
GoodbyeMessageName: true,
|
|
BeaconBlocksByRangeMessageName: true,
|
|
BeaconBlocksByRootsMessageName: true,
|
|
PingMessageName: true,
|
|
MetadataMessageName: true,
|
|
}
|
|
)
|
|
|
|
// VerifyTopicMapping verifies that the topic and its accompanying
|
|
// message type is correct.
|
|
func VerifyTopicMapping(topic string, msg any) error {
|
|
msgType, ok := RPCTopicMappings[topic]
|
|
if !ok {
|
|
return errors.New("rpc topic is not registered currently")
|
|
}
|
|
receivedType := reflect.TypeOf(msg)
|
|
registeredType := reflect.TypeOf(msgType)
|
|
typeMatches := registeredType.AssignableTo(receivedType)
|
|
|
|
if !typeMatches {
|
|
return errors.Errorf("accompanying message type is incorrect for topic: wanted %v but got %v",
|
|
registeredType.String(), receivedType.String())
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// TopicDeconstructor splits the provided topic to its logical sub-sections.
|
|
// It is assumed all input topics will follow the specific schema:
|
|
// /protocol-prefix/message-name/schema-version/...
|
|
// For the purposes of deconstruction, only the first 3 components are
|
|
// relevant.
|
|
func TopicDeconstructor(topic string) (string, string, string, error) {
|
|
origTopic := topic
|
|
protPrefix := ""
|
|
message := ""
|
|
version := ""
|
|
|
|
// Iterate through all the relevant mappings to find the relevant prefixes,messages
|
|
// and version for this topic.
|
|
for k := range protocolMapping {
|
|
keyLen := len(k)
|
|
if keyLen > len(topic) {
|
|
continue
|
|
}
|
|
if topic[:keyLen] == k {
|
|
protPrefix = k
|
|
topic = topic[keyLen:]
|
|
}
|
|
}
|
|
|
|
if protPrefix == "" {
|
|
return "", "", "", errors.Errorf("unable to find a valid protocol prefix for %s", origTopic)
|
|
}
|
|
|
|
for k := range messageMapping {
|
|
keyLen := len(k)
|
|
if keyLen > len(topic) {
|
|
continue
|
|
}
|
|
if topic[:keyLen] == k {
|
|
message = k
|
|
topic = topic[keyLen:]
|
|
}
|
|
}
|
|
|
|
if message == "" {
|
|
return "", "", "", errors.Errorf("unable to find a valid message for %s", origTopic)
|
|
}
|
|
|
|
for k := range versionMapping {
|
|
keyLen := len(k)
|
|
if keyLen > len(topic) {
|
|
continue
|
|
}
|
|
if topic[:keyLen] == k {
|
|
version = k
|
|
topic = topic[keyLen:]
|
|
}
|
|
}
|
|
|
|
if version == "" {
|
|
return "", "", "", errors.Errorf("unable to find a valid schema version for %s", origTopic)
|
|
}
|
|
|
|
return protPrefix, message, version, nil
|
|
}
|
|
|
|
// RPCTopic is a type used to denote and represent a req/resp topic.
|
|
type RPCTopic string
|
|
|
|
// ProtocolPrefix returns the protocol prefix of the rpc topic.
|
|
func (r RPCTopic) ProtocolPrefix() string {
|
|
prefix, _, _, err := TopicDeconstructor(string(r))
|
|
if err != nil {
|
|
return ""
|
|
}
|
|
return prefix
|
|
}
|
|
|
|
// MessageType returns the message type of the rpc topic.
|
|
func (r RPCTopic) MessageType() string {
|
|
_, message, _, err := TopicDeconstructor(string(r))
|
|
if err != nil {
|
|
return ""
|
|
}
|
|
return message
|
|
}
|
|
|
|
// Version returns the schema version of the rpc topic.
|
|
func (r RPCTopic) Version() string {
|
|
_, _, version, err := TopicDeconstructor(string(r))
|
|
if err != nil {
|
|
return ""
|
|
}
|
|
return version
|
|
}
|
|
|
|
// TopicFromMessage constructs the rpc topic from the provided message
|
|
// type and epoch.
|
|
func TopicFromMessage(msg string, epoch primitives.Epoch) (string, error) {
|
|
// Check if the topic is known.
|
|
if !messageMapping[msg] {
|
|
return "", errors.Errorf("%s: %s", invalidRPCMessageType, msg)
|
|
}
|
|
|
|
cfg := params.BeaconConfig()
|
|
|
|
// Check if the message is to be updated in fulu.
|
|
if epoch >= cfg.FuluForkEpoch {
|
|
if version, ok := fuluMapping[msg]; ok {
|
|
return protocolPrefix + msg + version, nil
|
|
}
|
|
}
|
|
|
|
// Check if the message is to be updated in altair.
|
|
if epoch >= cfg.AltairForkEpoch {
|
|
if version, ok := altairMapping[msg]; ok {
|
|
return protocolPrefix + msg + version, nil
|
|
}
|
|
}
|
|
|
|
return protocolPrefix + msg + SchemaVersionV1, nil
|
|
}
|