Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deneb Support #564

Merged
merged 32 commits into from
Jan 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
251af19
Remove bellatrix from wrapper types (#475)
avalonche Jun 29, 2023
c8f3b84
Remove get header wrapper types (#477)
avalonche Jul 20, 2023
b5a41c9
Remove signed blinded beacon block wrapper (#482)
avalonche Jul 26, 2023
3037d66
remove signed beacon block wrapper types (#483)
avalonche Jul 26, 2023
ece5601
Remove submit block request wrapper (#485)
avalonche Jul 26, 2023
d4bb90a
Upgrade go-boost-utils (#488)
avalonche Jul 28, 2023
0d01945
Add custom json marshalling for versioned structs (#493)
avalonche Aug 2, 2023
45155e1
Add deneb signature checking for block contents
avalonche Aug 2, 2023
b555890
Add deneb support for type conversions
avalonche Aug 2, 2023
7b6ee4d
Add redis and database tests to store deneb payloads
avalonche Aug 2, 2023
33cf57a
Block submission to v3 validation endpoint
avalonche Aug 3, 2023
0ee8e87
Update signed block conversions
avalonche Aug 10, 2023
22df427
Replace some expectCont with expectOk (#509)
jtraglia Aug 17, 2023
0f3dd95
Allow fork epochs to be 0
avalonche Aug 26, 2023
a4f4509
Make attestantio import names consistent (#510)
jtraglia Sep 4, 2023
7fdbbe3
Fix mistake in redis prefix name (#517)
jtraglia Sep 5, 2023
f081c32
rebase conflicts from main
avalonche Sep 29, 2023
f72a2c5
update submit block request
avalonche Sep 29, 2023
632ab77
bug fixes
avalonche Oct 3, 2023
ab492b9
fix blob sidecar signature
avalonche Oct 16, 2023
c4b2cc1
ssz encode request to publish block
avalonche Oct 21, 2023
289b134
use v2 publish endpoint by default
avalonche Oct 24, 2023
f89b8fc
go mod tidy
avalonche Oct 31, 2023
8cad8d3
update relay to latest builder-specs
avalonche Nov 21, 2023
fa166ee
update go mod
avalonche Dec 6, 2023
356b06d
fix lint and tests
avalonche Jan 4, 2024
36a22c4
switch to json encoding instead of ssz for block publishing v2
avalonche Jan 16, 2024
c1af95e
add blob logging
avalonche Jan 19, 2024
d2237f8
address pr comments
avalonche Jan 25, 2024
0346f6f
Handle no deneb fork schedule from beacon client (#572)
avalonche Jan 25, 2024
1ffdc1a
change specific error log to info because it's expected nowadays (#574)
metachris Jan 25, 2024
14e4188
Add json and ssz marshalling tests (#573)
avalonche Jan 30, 2024
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
8 changes: 8 additions & 0 deletions .golangci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ linters:
enable-all: true
disable:
- cyclop
- depguard
- forbidigo
- funlen
- gochecknoglobals
Expand Down Expand Up @@ -69,6 +70,7 @@ linters-settings:

gomoddirectives:
replace-allow-list:
- github.com/attestantio/go-builder-client
- github.com/attestantio/go-eth2-client

maintidx:
Expand All @@ -88,6 +90,12 @@ linters-settings:
# Because it's easier to read without the other fields.
#
- 'GetPayloadsFilters'
#
# Easier to read with only one of the versioned payloads.
#
- 'VersionedSubmitBlindedBlockResponse'
- 'VersionedExecutionPayload'
- 'VersionedSignedBuilderBid'

#
# Structures outside our control that have a ton of settings. It doesn't
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ redis-cli DEL boost-relay/sepolia:validators-registration boost-relay/sepolia:va
* `DISABLE_LOWPRIO_BUILDERS` - reject block submissions by low-prio builders
* `FORCE_GET_HEADER_204` - force 204 as getHeader response
* `ENABLE_IGNORABLE_VALIDATION_ERRORS` - enable ignorable validation errors
* `USE_V2_PUBLISH_BLOCK_ENDPOINT` - uses the v2 publish block endpoint on the beacon node
* `USE_V1_PUBLISH_BLOCK_ENDPOINT` - uses the v1 publish block endpoint on the beacon node
avalonche marked this conversation as resolved.
Show resolved Hide resolved

#### Development Environment Variables

Expand Down
4 changes: 1 addition & 3 deletions beaconclient/beacon_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"testing"
"time"

"github.com/flashbots/go-boost-utils/types"
"github.com/flashbots/mev-boost-relay/common"
"github.com/gorilla/mux"
"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -194,11 +193,10 @@ func TestFetchValidators(t *testing.T) {

// only beacon 2 should have a validator, and should be used by default
backend.beaconInstances[0].MockFetchValidatorsErr = nil
backend.beaconInstances[1].SetValidators(make(map[types.PubkeyHex]ValidatorResponseEntry))
backend.beaconInstances[1].SetValidators(make(map[common.PubkeyHex]ValidatorResponseEntry))
backend.beaconInstances[2].MockFetchValidatorsErr = nil
backend.beaconInstances[2].AddValidator(entry)

// t.Log("beacon0/1/2 validators:", backend.beaconInstances[0].NumValidators(), backend.beaconInstances[1].NumValidators(), backend.beaconInstances[2].NumValidators())
validators, err = backend.beaconClient.GetStateValidators("1")
require.NoError(t, err)
require.Equal(t, 1, len(validators.Data))
Expand Down
17 changes: 6 additions & 11 deletions beaconclient/mock_beacon_instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,12 @@ import (
"sync"
"time"

"github.com/flashbots/go-boost-utils/types"
"github.com/flashbots/mev-boost-relay/common"
)

type MockBeaconInstance struct {
mu sync.RWMutex
validatorSet map[types.PubkeyHex]ValidatorResponseEntry
validatorSet map[common.PubkeyHex]ValidatorResponseEntry

MockSyncStatus *SyncStatusPayloadData
MockSyncStatusErr error
Expand All @@ -23,7 +22,7 @@ type MockBeaconInstance struct {

func NewMockBeaconInstance() *MockBeaconInstance {
return &MockBeaconInstance{
validatorSet: make(map[types.PubkeyHex]ValidatorResponseEntry),
validatorSet: make(map[common.PubkeyHex]ValidatorResponseEntry),

MockSyncStatus: &SyncStatusPayloadData{
HeadSlot: 1,
Expand All @@ -44,17 +43,17 @@ func NewMockBeaconInstance() *MockBeaconInstance {

func (c *MockBeaconInstance) AddValidator(entry ValidatorResponseEntry) {
c.mu.Lock()
c.validatorSet[types.NewPubkeyHex(entry.Validator.Pubkey)] = entry
c.validatorSet[common.NewPubkeyHex(entry.Validator.Pubkey)] = entry
c.mu.Unlock()
}

func (c *MockBeaconInstance) SetValidators(validatorSet map[types.PubkeyHex]ValidatorResponseEntry) {
func (c *MockBeaconInstance) SetValidators(validatorSet map[common.PubkeyHex]ValidatorResponseEntry) {
c.mu.Lock()
c.validatorSet = validatorSet
c.mu.Unlock()
}

func (c *MockBeaconInstance) IsValidator(pubkey types.PubkeyHex) bool {
func (c *MockBeaconInstance) IsValidator(pubkey common.PubkeyHex) bool {
c.mu.RLock()
_, found := c.validatorSet[pubkey]
c.mu.RUnlock()
Expand Down Expand Up @@ -107,18 +106,14 @@ func (c *MockBeaconInstance) addDelay() {
}
}

func (c *MockBeaconInstance) PublishBlock(block *common.SignedBeaconBlock, broadcaseMode BroadcastMode) (code int, err error) {
func (c *MockBeaconInstance) PublishBlock(block *common.VersionedSignedProposal, broadcaseMode BroadcastMode) (code int, err error) {
return 0, nil
}

func (c *MockBeaconInstance) GetGenesis() (*GetGenesisResponse, error) {
return nil, nil
}

func (c *MockBeaconInstance) GetBlock(blockID string) (block *GetBlockResponse, err error) {
return nil, nil
}

func (c *MockBeaconInstance) GetSpec() (spec *GetSpecResponse, err error) {
return nil, nil
}
Expand Down
10 changes: 1 addition & 9 deletions beaconclient/mock_multi_beacon_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,6 @@ func (*MockMultiBeaconClient) SubscribeToHeadEvents(slotC chan HeadEventData) {}
func (*MockMultiBeaconClient) SubscribeToPayloadAttributesEvents(payloadAttrC chan PayloadAttributesEvent) {
}

// func (*MockMultiBeaconClient) FetchValidators(headSlot uint64) (map[types.PubkeyHex]ValidatorResponseEntry, error) {
// return nil, nil
// }

func (*MockMultiBeaconClient) GetStateValidators(stateID string) (*GetStateValidatorsResponse, error) {
return nil, nil
}
Expand All @@ -32,7 +28,7 @@ func (*MockMultiBeaconClient) GetProposerDuties(epoch uint64) (*ProposerDutiesRe
return nil, nil
}

func (*MockMultiBeaconClient) PublishBlock(block *common.SignedBeaconBlock) (code int, err error) {
func (*MockMultiBeaconClient) PublishBlock(block *common.VersionedSignedProposal) (code int, err error) {
return 0, nil
}

Expand Down Expand Up @@ -62,10 +58,6 @@ func (*MockMultiBeaconClient) GetForkSchedule() (spec *GetForkScheduleResponse,
return resp, nil
}

func (*MockMultiBeaconClient) GetBlock(blockID string) (block *GetBlockResponse, err error) {
return nil, nil
}

func (*MockMultiBeaconClient) GetRandao(slot uint64) (spec *GetRandaoResponse, err error) {
return nil, nil
}
Expand Down
55 changes: 21 additions & 34 deletions beaconclient/multi_beacon_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,14 @@ var (
ErrBeaconBlock202 = errors.New("beacon block failed validation but was still broadcast (202)")
)

type BroadcastMode int
type BroadcastMode string

const (
Gossip BroadcastMode = iota // lightweight gossip checks only
Consensus // full consensus checks, including validation of all signatures and blocks fields
ConsensusAndEquivocation // the same as `consensus`, with an extra equivocation check
Gossip BroadcastMode = "gossip" // lightweight gossip checks only
Consensus BroadcastMode = "consensus" // full consensus checks, including validation of all signatures and blocks fields
ConsensusAndEquivocation BroadcastMode = "consensus_and_equivocation" // the same as `consensus`, with an extra equivocation check
)

func (b BroadcastMode) String() string {
return [...]string{"gossip", "consensus", "consensus_and_equivocation"}[b]
}

// IMultiBeaconClient is the interface for the MultiBeaconClient, which can manage several beacon client instances under the hood
type IMultiBeaconClient interface {
BestSyncStatus() (*SyncStatusPayloadData, error)
Expand All @@ -42,11 +38,10 @@ type IMultiBeaconClient interface {
// GetStateValidators returns all active and pending validators from the beacon node
GetStateValidators(stateID string) (*GetStateValidatorsResponse, error)
GetProposerDuties(epoch uint64) (*ProposerDutiesResponse, error)
PublishBlock(block *common.SignedBeaconBlock) (code int, err error)
PublishBlock(block *common.VersionedSignedProposal) (code int, err error)
GetGenesis() (*GetGenesisResponse, error)
GetSpec() (spec *GetSpecResponse, err error)
GetForkSchedule() (spec *GetForkScheduleResponse, err error)
GetBlock(blockID string) (block *GetBlockResponse, err error)
GetRandao(slot uint64) (spec *GetRandaoResponse, err error)
GetWithdrawals(slot uint64) (spec *GetWithdrawalsResponse, err error)
}
Expand All @@ -60,11 +55,10 @@ type IBeaconInstance interface {
GetStateValidators(stateID string) (*GetStateValidatorsResponse, error)
GetProposerDuties(epoch uint64) (*ProposerDutiesResponse, error)
GetURI() string
PublishBlock(block *common.SignedBeaconBlock, broadcastMode BroadcastMode) (code int, err error)
PublishBlock(block *common.VersionedSignedProposal, broadcastMode BroadcastMode) (code int, err error)
GetGenesis() (*GetGenesisResponse, error)
GetSpec() (spec *GetSpecResponse, err error)
GetForkSchedule() (spec *GetForkScheduleResponse, err error)
GetBlock(blockID string) (*GetBlockResponse, error)
GetRandao(slot uint64) (spec *GetRandaoResponse, err error)
GetWithdrawals(slot uint64) (spec *GetWithdrawalsResponse, err error)
}
Expand Down Expand Up @@ -99,10 +93,10 @@ func NewMultiBeaconClient(log *logrus.Entry, beaconInstances []IBeaconInstance)
if broadcastModeStr != "" {
broadcastMode, ok := parseBroadcastModeString(broadcastModeStr)
if !ok {
msg := fmt.Sprintf("env: BROADCAST_MODE: invalid value %s, leaving to default value %s", broadcastModeStr, client.broadcastMode.String())
msg := fmt.Sprintf("env: BROADCAST_MODE: invalid value %s, leaving to default value %s", broadcastModeStr, client.broadcastMode)
client.log.Warn(msg)
} else {
client.log.Info(fmt.Sprintf("env: BROADCAST_MODE: setting mode to %s", broadcastMode.String()))
client.log.Info(fmt.Sprintf("env: BROADCAST_MODE: setting mode to %s", broadcastMode))
client.broadcastMode = broadcastMode
}
}
Expand Down Expand Up @@ -255,10 +249,20 @@ type publishResp struct {
}

// PublishBlock publishes the signed beacon block via https://ethereum.github.io/beacon-APIs/#/ValidatorRequiredApi/publishBlock
func (c *MultiBeaconClient) PublishBlock(block *common.SignedBeaconBlock) (code int, err error) {
func (c *MultiBeaconClient) PublishBlock(block *common.VersionedSignedProposal) (code int, err error) {
slot, err := block.Slot()
if err != nil {
c.log.WithError(err).Warn("failed to publish block as block slot is missing")
return 0, err
}
blockHash, err := block.ExecutionBlockHash()
if err != nil {
c.log.WithError(err).Warn("failed to publish block as block hash is missing")
return 0, err
}
log := c.log.WithFields(logrus.Fields{
"slot": block.Slot(),
"blockHash": block.BlockHash(),
"slot": slot,
"blockHash": blockHash.String(),
avalonche marked this conversation as resolved.
Show resolved Hide resolved
})

clients := c.beaconInstancesByLastResponse()
Expand Down Expand Up @@ -360,23 +364,6 @@ func (c *MultiBeaconClient) GetForkSchedule() (spec *GetForkScheduleResponse, er
return nil, err
}

// GetBlock returns a block - https://ethereum.github.io/beacon-APIs/#/Beacon/getBlockV2
func (c *MultiBeaconClient) GetBlock(blockID string) (block *GetBlockResponse, err error) {
clients := c.beaconInstancesByLastResponse()
for _, client := range clients {
log := c.log.WithField("uri", client.GetURI())
if block, err = client.GetBlock(blockID); err != nil {
log.WithField("blockID", blockID).WithError(err).Warn("failed to get block")
continue
}

return block, nil
}

c.log.WithField("blockID", blockID).WithError(err).Error("failed to get block from any CL node")
return nil, err
}

// GetRandao - 3500/eth/v1/beacon/states/<slot>/randao
func (c *MultiBeaconClient) GetRandao(slot uint64) (randaoResp *GetRandaoResponse, err error) {
clients := c.beaconInstancesByLastResponse()
Expand Down
Loading
Loading