Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 90 additions & 0 deletions api/server/structs/conversions_block_gloas_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,93 @@ func TestBlockContentsGloasFromConsensus(t *testing.T) {
require.Equal(t, 1, len(result.Blobs))
require.Equal(t, hexutil.Encode(blobs[0]), result.Blobs[0])
}

func validProposerPreferences() *ProposerPreferences {
return &ProposerPreferences{
DependentRoot: hexutil.Encode(bytes.Repeat([]byte{0xcc}, fieldparams.RootLength)),
ProposalSlot: "32",
ValidatorIndex: "2",
FeeRecipient: hexutil.Encode(bytes.Repeat([]byte{0xab}, 20)),
TargetGasLimit: "30000000",
}
}

func TestSignedProposerPreferences_ToConsensus_NilMessage(t *testing.T) {
s := &SignedProposerPreferences{Message: nil, Signature: ""}
_, err := s.ToConsensus()
require.ErrorContains(t, errNilValue.Error(), err)
}

func TestSignedProposerPreferences_ToConsensus_NilReceiver(t *testing.T) {
var s *SignedProposerPreferences
_, err := s.ToConsensus()
require.ErrorContains(t, errNilValue.Error(), err)
}

func TestSignedProposerPreferences_ToConsensus_BadSignature(t *testing.T) {
s := &SignedProposerPreferences{Message: validProposerPreferences(), Signature: "0xnothex"}
_, err := s.ToConsensus()
require.ErrorContains(t, "Signature", err)
}

func TestSignedProposerPreferences_ToConsensus_OK(t *testing.T) {
sig := hexutil.Encode(bytes.Repeat([]byte{0x01}, fieldparams.BLSSignatureLength))
s := &SignedProposerPreferences{Message: validProposerPreferences(), Signature: sig}
out, err := s.ToConsensus()
require.NoError(t, err)
require.Equal(t, uint64(30_000_000), out.Message.TargetGasLimit)
require.Equal(t, uint64(32), uint64(out.Message.ProposalSlot))
require.Equal(t, uint64(2), uint64(out.Message.ValidatorIndex))
require.Equal(t, fieldparams.BLSSignatureLength, len(out.Signature))
require.Equal(t, 20, len(out.Message.FeeRecipient))
require.Equal(t, fieldparams.RootLength, len(out.Message.DependentRoot))
}

func TestProposerPreferences_ToConsensus_BadDependentRootHex(t *testing.T) {
p := validProposerPreferences()
p.DependentRoot = "0xnothex"
_, err := p.ToConsensus()
require.ErrorContains(t, "DependentRoot", err)
}

func TestProposerPreferences_ToConsensus_ShortDependentRoot(t *testing.T) {
p := validProposerPreferences()
p.DependentRoot = "0xcc"
_, err := p.ToConsensus()
require.ErrorContains(t, "DependentRoot", err)
}

func TestProposerPreferences_ToConsensus_BadProposalSlot(t *testing.T) {
p := validProposerPreferences()
p.ProposalSlot = "nope"
_, err := p.ToConsensus()
require.ErrorContains(t, "ProposalSlot", err)
}

func TestProposerPreferences_ToConsensus_BadValidatorIndex(t *testing.T) {
p := validProposerPreferences()
p.ValidatorIndex = "nope"
_, err := p.ToConsensus()
require.ErrorContains(t, "ValidatorIndex", err)
}

func TestProposerPreferences_ToConsensus_BadFeeRecipientHex(t *testing.T) {
p := validProposerPreferences()
p.FeeRecipient = "0xnothex"
_, err := p.ToConsensus()
require.ErrorContains(t, "FeeRecipient", err)
}

func TestProposerPreferences_ToConsensus_ShortFeeRecipient(t *testing.T) {
p := validProposerPreferences()
p.FeeRecipient = "0xab"
_, err := p.ToConsensus()
require.ErrorContains(t, "FeeRecipient", err)
}

func TestProposerPreferences_ToConsensus_BadTargetGasLimit(t *testing.T) {
p := validProposerPreferences()
p.TargetGasLimit = "nope"
_, err := p.ToConsensus()
require.ErrorContains(t, "TargetGasLimit", err)
}
80 changes: 80 additions & 0 deletions api/server/structs/conversions_gloas.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,15 @@ package structs

import (
"fmt"
"strconv"

"github.com/OffchainLabs/prysm/v7/api/server"
fieldparams "github.com/OffchainLabs/prysm/v7/config/fieldparams"
"github.com/OffchainLabs/prysm/v7/consensus-types/interfaces"
"github.com/OffchainLabs/prysm/v7/consensus-types/primitives"
"github.com/OffchainLabs/prysm/v7/encoding/bytesutil"
ethpb "github.com/OffchainLabs/prysm/v7/proto/prysm/v1alpha1"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
)

Expand Down Expand Up @@ -108,3 +114,77 @@ func PTCsFromConsensus(p *ethpb.PTCs) *PTCs {
}
return &PTCs{ValidatorIndices: indices}
}

func (s *SignedProposerPreferences) ToConsensus() (*ethpb.SignedProposerPreferences, error) {
if s == nil {
return nil, server.NewDecodeError(errNilValue, "SignedProposerPreferences")
}
if s.Message == nil {
return nil, server.NewDecodeError(errNilValue, "Message")
}
msg, err := s.Message.ToConsensus()
if err != nil {
return nil, server.NewDecodeError(err, "Message")
}
sig, err := bytesutil.DecodeHexWithLength(s.Signature, fieldparams.BLSSignatureLength)
if err != nil {
return nil, server.NewDecodeError(err, "Signature")
}
return &ethpb.SignedProposerPreferences{
Message: msg,
Signature: sig,
}, nil
}

func SignedProposerPreferencesFromConsensus(s *ethpb.SignedProposerPreferences) *SignedProposerPreferences {
if s == nil {
return nil
}
return &SignedProposerPreferences{
Message: ProposerPreferencesFromConsensus(s.Message),
Signature: hexutil.Encode(s.Signature),
}
}

func ProposerPreferencesFromConsensus(p *ethpb.ProposerPreferences) *ProposerPreferences {
if p == nil {
return nil
}
return &ProposerPreferences{
DependentRoot: hexutil.Encode(p.DependentRoot),
ProposalSlot: fmt.Sprintf("%d", p.ProposalSlot),
ValidatorIndex: fmt.Sprintf("%d", p.ValidatorIndex),
FeeRecipient: hexutil.Encode(p.FeeRecipient),
TargetGasLimit: fmt.Sprintf("%d", p.TargetGasLimit),
}
}

func (p *ProposerPreferences) ToConsensus() (*ethpb.ProposerPreferences, error) {
dependentRoot, err := bytesutil.DecodeHexWithLength(p.DependentRoot, fieldparams.RootLength)
if err != nil {
return nil, server.NewDecodeError(err, "DependentRoot")
}
slot, err := strconv.ParseUint(p.ProposalSlot, 10, 64)
if err != nil {
return nil, server.NewDecodeError(err, "ProposalSlot")
}
valIdx, err := strconv.ParseUint(p.ValidatorIndex, 10, 64)
if err != nil {
return nil, server.NewDecodeError(err, "ValidatorIndex")
}
feeRecipient, err := bytesutil.DecodeHexWithLength(p.FeeRecipient, common.AddressLength)
if err != nil {
return nil, server.NewDecodeError(err, "FeeRecipient")
}
gasLimit, err := strconv.ParseUint(p.TargetGasLimit, 10, 64)
if err != nil {
return nil, server.NewDecodeError(err, "TargetGasLimit")
}
return &ethpb.ProposerPreferences{
DependentRoot: dependentRoot,
ProposalSlot: primitives.Slot(slot),
ValidatorIndex: primitives.ValidatorIndex(valIdx),
FeeRecipient: feeRecipient,
TargetGasLimit: gasLimit,
}, nil
}
5 changes: 5 additions & 0 deletions api/server/structs/endpoints_events.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,11 @@ type LightClientOptimisticUpdateEvent struct {
Data *LightClientOptimisticUpdate `json:"data"`
}

type ProposerPreferencesEvent struct {
Version string `json:"version"`
Data *SignedProposerPreferences `json:"data"`
}

type ExecutionPayloadAvailableEvent struct {
Slot string `json:"slot"`
BlockRoot string `json:"block_root"`
Expand Down
13 changes: 13 additions & 0 deletions api/server/structs/other.go
Original file line number Diff line number Diff line change
Expand Up @@ -286,3 +286,16 @@ type BuilderPendingWithdrawal struct {
type PTCs struct {
ValidatorIndices []string `json:"validator_indices"`
}

type ProposerPreferences struct {
DependentRoot string `json:"dependent_root"`
ProposalSlot string `json:"proposal_slot"`
ValidatorIndex string `json:"validator_index"`
FeeRecipient string `json:"fee_recipient"`
TargetGasLimit string `json:"target_gas_limit"`
}

type SignedProposerPreferences struct {
Message *ProposerPreferences `json:"message"`
Signature string `json:"signature"`
}
8 changes: 8 additions & 0 deletions beacon-chain/core/feed/operation/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ const (
// ExecutionPayloadGossipReceived is sent after an execution payload envelope has been received from
// gossip or API that passes validation rules.
ExecutionPayloadGossipReceived = 14

// ProposerPreferencesReceived is sent after signed proposer preferences are received from gossip or rpc.
ProposerPreferencesReceived = 15
)

// UnAggregatedAttReceivedData is the data sent with UnaggregatedAttReceived events.
Expand Down Expand Up @@ -134,3 +137,8 @@ type ExecutionPayloadGossipReceivedData struct {
BlockHash [32]byte
BlockRoot [32]byte
}

// ProposerPreferencesReceivedData is the data sent with ProposerPreferencesReceived events.
type ProposerPreferencesReceivedData struct {
Data *ethpb.SignedProposerPreferences
}
11 changes: 11 additions & 0 deletions beacon-chain/rpc/endpoints.go
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,17 @@ func (s *Service) validatorEndpoints(
handler: server.PrepareBeaconProposer,
methods: []string{http.MethodPost},
},
{
template: "/eth/v1/validator/proposer_preferences",
name: namespace + ".SubmitSignedProposerPreferences",
middleware: []middleware.Middleware{
middleware.ContentTypeHandler([]string{api.JsonMediaType}),
middleware.AcceptHeaderHandler([]string{api.JsonMediaType}),
middleware.AcceptEncodingHeaderHandler(),
},
handler: server.SubmitSignedProposerPreferences,
methods: []string{http.MethodPost},
},
{
template: "/eth/v1/validator/liveness/{epoch}",
name: namespace + ".GetLiveness",
Expand Down
3 changes: 2 additions & 1 deletion beacon-chain/rpc/endpoints_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,10 @@ func Test_endpoints(t *testing.T) {
"/eth/v1/validator/sync_committee_contribution": {http.MethodGet},
"/eth/v1/validator/contribution_and_proofs": {http.MethodPost},
"/eth/v1/validator/prepare_beacon_proposer": {http.MethodPost},
"/eth/v1/validator/proposer_preferences": {http.MethodPost},
"/eth/v1/validator/register_validator": {http.MethodPost},
"/eth/v1/validator/liveness/{epoch}": {http.MethodPost},
"/eth/v1/validator/payload_attestation_data/{slot}": {http.MethodGet},
"/eth/v1/validator/payload_attestation_data/{slot}": {http.MethodGet},
}

prysmBeaconRoutes := map[string][]string{
Expand Down
1 change: 1 addition & 0 deletions beacon-chain/rpc/eth/events/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ go_test(
],
embed = [":go_default_library"],
deps = [
"//api/server/structs:go_default_library",
"//beacon-chain/blockchain/testing:go_default_library",
"//beacon-chain/cache:go_default_library",
"//beacon-chain/core/feed:go_default_library",
Expand Down
13 changes: 13 additions & 0 deletions beacon-chain/rpc/eth/events/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ const (
ExecutionPayloadBidTopic = "execution_payload_bid"
// PayloadAttestationMessageTopic represents a new payload attestation message event topic.
PayloadAttestationMessageTopic = "payload_attestation_message"
// ProposerPreferencesTopic represents a new signed proposer preferences event topic.
ProposerPreferencesTopic = "proposer_preferences"
)

var (
Expand Down Expand Up @@ -124,6 +126,7 @@ var opsFeedEventTopics = map[feed.EventType]string{
operation.BlockGossipReceived: BlockGossipTopic,
operation.DataColumnReceived: DataColumnTopic,
operation.PayloadAttestationMessageReceived: PayloadAttestationMessageTopic,
operation.ProposerPreferencesReceived: ProposerPreferencesTopic,
operation.ExecutionPayloadGossipReceived: ExecutionPayloadGossipTopic,
}

Expand Down Expand Up @@ -491,6 +494,8 @@ func topicForEvent(event *feed.Event) string {
return DataColumnTopic
case *operation.PayloadAttestationMessageReceivedData:
return PayloadAttestationMessageTopic
case *operation.ProposerPreferencesReceivedData:
return ProposerPreferencesTopic
case *statefeed.ExecutionPayloadAvailableData:
return ExecutionPayloadAvailableTopic
case *statefeed.ExecutionPayloadProcessedData:
Expand Down Expand Up @@ -673,6 +678,14 @@ func (s *Server) lazyReaderForEvent(ctx context.Context, event *feed.Event, topi
return func() io.Reader {
return jsonMarshalReader(eventName, structs.PayloadAttestationMessageFromConsensus(v.Message))
}, nil
case *operation.ProposerPreferencesReceivedData:
return func() io.Reader {
epoch := slots.ToEpoch(v.Data.Message.ProposalSlot)
return jsonMarshalReader(eventName, &structs.ProposerPreferencesEvent{
Version: version.String(params.GetNetworkScheduleEntry(epoch).VersionEnum),
Data: structs.SignedProposerPreferencesFromConsensus(v.Data),
})
}, nil
Comment thread
syjn99 marked this conversation as resolved.
case *statefeed.ExecutionPayloadAvailableData:
return func() io.Reader {
return jsonMarshalReader(eventName, &structs.ExecutionPayloadAvailableEvent{
Expand Down
Loading
Loading