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

Add support for Electra payloads #651

Open
wants to merge 10 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 9 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
14 changes: 7 additions & 7 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ require (
github.com/google/uuid v1.6.0
github.com/gorilla/mux v1.8.1
github.com/holiman/uint256 v1.2.4
github.com/prysmaticlabs/go-bitfield v0.0.0-20210809151128-385d8c5e3fb7
github.com/prysmaticlabs/go-bitfield v0.0.0-20240328144219-a1caa50c3a1e
github.com/sirupsen/logrus v1.9.3
github.com/stretchr/testify v1.8.4
)
Expand All @@ -31,7 +31,7 @@ require (
github.com/fatih/color v1.16.0 // indirect
github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 // indirect
github.com/getsentry/sentry-go v0.18.0 // indirect
github.com/goccy/go-yaml v1.11.2 // indirect
github.com/goccy/go-yaml v1.11.3 // indirect
github.com/gofrs/flock v0.8.1 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.3 // indirect
Expand Down Expand Up @@ -59,8 +59,8 @@ require (

require (
github.com/StackExchange/wmi v1.2.1 // indirect
github.com/attestantio/go-builder-client v0.4.2
github.com/attestantio/go-eth2-client v0.19.10
github.com/attestantio/go-builder-client v0.4.6-0.20240508205504-2210689d2f24
github.com/attestantio/go-eth2-client v0.21.4-0.20240517101940-c13fd7112c55
github.com/btcsuite/btcd v0.22.0-beta // indirect
github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
Expand All @@ -69,7 +69,7 @@ require (
github.com/ferranbt/fastssz v0.1.3 // indirect
github.com/go-ole/go-ole v1.3.0 // indirect
github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect
github.com/klauspost/cpuid/v2 v2.2.6 // indirect
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
github.com/mattn/go-runewidth v0.0.13 // indirect
github.com/minio/sha256-simd v1.0.1 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
Expand All @@ -82,8 +82,8 @@ require (
github.com/tklauser/numcpus v0.6.1 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.25.0 // indirect
golang.org/x/crypto v0.18.0 // indirect
golang.org/x/sys v0.16.0 // indirect
golang.org/x/crypto v0.22.0 // indirect
golang.org/x/sys v0.19.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
32 changes: 16 additions & 16 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ github.com/VictoriaMetrics/fastcache v1.12.1/go.mod h1:tX04vaqcNoQeGLD+ra5pU5sWk
github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/attestantio/go-builder-client v0.4.2 h1:EycfAFqQV+ooc2z6hmTsbuH4TCLknr0aO0nHLHLMpJM=
github.com/attestantio/go-builder-client v0.4.2/go.mod h1:e02i/WO4fjs3/u9oIZEjiC8CK1Qyxy4cpiMMGKx4VqQ=
github.com/attestantio/go-eth2-client v0.19.10 h1:NLs9mcBvZpBTZ3du7Ey2NHQoj8d3UePY7pFBXX6C6qs=
github.com/attestantio/go-eth2-client v0.19.10/go.mod h1:TTz7YF6w4z6ahvxKiHuGPn6DbQn7gH6HPuWm/DEQeGE=
github.com/attestantio/go-builder-client v0.4.6-0.20240508205504-2210689d2f24 h1:KXWQwsxrrJD1G7rp+18uESZ0BSPmUdady46iAfCgwDY=
github.com/attestantio/go-builder-client v0.4.6-0.20240508205504-2210689d2f24/go.mod h1:bs7HF4beRWCjcvKsHH8nEl3aDzrTqeUjXOfqpfrYTJQ=
github.com/attestantio/go-eth2-client v0.21.4-0.20240517101940-c13fd7112c55 h1:3HjnisE8nFHBhf20H4ya9Q+4HvX1bbV8lCM6LJLLcg0=
github.com/attestantio/go-eth2-client v0.21.4-0.20240517101940-c13fd7112c55/go.mod h1:RssbJ8txdfZ+O7cIjOKCvizcTWHzgPuJNByrwtQ6tBQ=
github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g=
github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A=
github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
Expand Down Expand Up @@ -134,8 +134,8 @@ github.com/go-playground/validator/v10 v10.11.1/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo=
github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM=
github.com/goccy/go-yaml v1.11.2 h1:joq77SxuyIs9zzxEjgyLBugMQ9NEgTWxXfz2wVqwAaQ=
github.com/goccy/go-yaml v1.11.2/go.mod h1:wKnAMd44+9JAAnGQpWVEgBzGt3YuTaQ4uXoHvE4m7WU=
github.com/goccy/go-yaml v1.11.3 h1:B3W9IdWbvrUu2OYQGwvU1nZtvMQJPBKgBUuweJjLj6I=
github.com/goccy/go-yaml v1.11.3/go.mod h1:wKnAMd44+9JAAnGQpWVEgBzGt3YuTaQ4uXoHvE4m7WU=
github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw=
github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
github.com/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
Expand Down Expand Up @@ -221,8 +221,8 @@ github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0
github.com/klauspost/compress v1.15.15 h1:EF27CXIuDsYJ6mmvtBRlEuB2UVOqHG1tAXgZ7yIO+lw=
github.com/klauspost/compress v1.15.15/go.mod h1:ZcK2JAFqKOpnBlxcLsJzYfrS9X1akm9fHZNnD9+Vo/4=
github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc=
github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
Expand Down Expand Up @@ -312,8 +312,8 @@ github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI
github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc=
github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg=
github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM=
github.com/prysmaticlabs/go-bitfield v0.0.0-20210809151128-385d8c5e3fb7 h1:0tVE4tdWQK9ZpYygoV7+vS6QkDvQVySboMVEIxBJmXw=
github.com/prysmaticlabs/go-bitfield v0.0.0-20210809151128-385d8c5e3fb7/go.mod h1:wmuf/mdK4VMD+jA9ThwcUKjg3a2XWM9cVfFYjDyY4j4=
github.com/prysmaticlabs/go-bitfield v0.0.0-20240328144219-a1caa50c3a1e h1:ATgOe+abbzfx9kCPeXIW4fiWyDdxlwHw07j8UGhdTd4=
github.com/prysmaticlabs/go-bitfield v0.0.0-20240328144219-a1caa50c3a1e/go.mod h1:wmuf/mdK4VMD+jA9ThwcUKjg3a2XWM9cVfFYjDyY4j4=
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
Expand Down Expand Up @@ -396,8 +396,8 @@ golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc=
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ=
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE=
Expand Down Expand Up @@ -429,8 +429,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.18.0 h1:mIYleuAkSbHh0tCv7RvjL3F6ZVbLjq4+R7zbOn3Kokg=
golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ=
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
Expand Down Expand Up @@ -477,8 +477,8 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
Expand Down
27 changes: 27 additions & 0 deletions server/mock/mock_relay.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@ import (
builderApi "github.com/attestantio/go-builder-client/api"
builderApiCapella "github.com/attestantio/go-builder-client/api/capella"
builderApiDeneb "github.com/attestantio/go-builder-client/api/deneb"
builderApiElectra "github.com/attestantio/go-builder-client/api/electra"
builderApiV1 "github.com/attestantio/go-builder-client/api/v1"
builderSpec "github.com/attestantio/go-builder-client/spec"
"github.com/attestantio/go-eth2-client/spec"
"github.com/attestantio/go-eth2-client/spec/capella"
"github.com/attestantio/go-eth2-client/spec/deneb"
"github.com/attestantio/go-eth2-client/spec/electra"
"github.com/attestantio/go-eth2-client/spec/phase0"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/flashbots/go-boost-utils/bls"
Expand Down Expand Up @@ -219,6 +221,31 @@ func (m *Relay) MakeGetHeaderResponse(value uint64, blockHash, parentHash, publi
Signature: signature,
},
}
case spec.DataVersionElectra:
message := &builderApiElectra.BuilderBid{
Header: &electra.ExecutionPayloadHeader{
BlockHash: HexToHash(blockHash),
ParentHash: HexToHash(parentHash),
WithdrawalsRoot: phase0.Root{},
BaseFeePerGas: uint256.NewInt(0),
WithdrawalRequestsRoot: phase0.Root{},
},
BlobKZGCommitments: make([]deneb.KZGCommitment, 0),
Value: uint256.NewInt(value),
Pubkey: HexToPubkey(publicKey),
}

// Sign the message.
signature, err := ssz.SignMessage(message, ssz.DomainBuilder, m.secretKey)
require.NoError(m.t, err)

return &builderSpec.VersionedSignedBuilderBid{
Version: spec.DataVersionElectra,
Electra: &builderApiElectra.SignedBuilderBid{
Message: message,
Signature: signature,
},
}
case spec.DataVersionUnknown, spec.DataVersionPhase0, spec.DataVersionAltair, spec.DataVersionBellatrix:
return nil
}
Expand Down
162 changes: 154 additions & 8 deletions server/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
builderSpec "github.com/attestantio/go-builder-client/spec"
eth2ApiV1Capella "github.com/attestantio/go-eth2-client/api/v1/capella"
eth2ApiV1Deneb "github.com/attestantio/go-eth2-client/api/v1/deneb"
eth2ApiV1Electra "github.com/attestantio/go-eth2-client/api/v1/electra"
"github.com/attestantio/go-eth2-client/spec/phase0"
"github.com/flashbots/go-boost-utils/ssz"
"github.com/flashbots/go-boost-utils/utils"
Expand Down Expand Up @@ -766,6 +767,146 @@ func (m *BoostService) processDenebPayload(w http.ResponseWriter, req *http.Requ
m.respondOK(w, result)
}

func (m *BoostService) processElectraPayload(w http.ResponseWriter, req *http.Request, log *logrus.Entry, blindedBlock *eth2ApiV1Electra.SignedBlindedBeaconBlock) {
// Get the currentSlotUID for this slot
currentSlotUID := ""
m.slotUIDLock.Lock()
if m.slotUID.slot == uint64(blindedBlock.Message.Slot) {
currentSlotUID = m.slotUID.uid.String()
} else {
log.Warnf("latest slotUID is for slot %d rather than payload slot %d", m.slotUID.slot, blindedBlock.Message.Slot)
}
m.slotUIDLock.Unlock()

// Prepare logger
ua := UserAgent(req.Header.Get("User-Agent"))
log = log.WithFields(logrus.Fields{
"ua": ua,
"slot": blindedBlock.Message.Slot,
"blockHash": blindedBlock.Message.Body.ExecutionPayloadHeader.BlockHash.String(),
"parentHash": blindedBlock.Message.Body.ExecutionPayloadHeader.ParentHash.String(),
"slotUID": currentSlotUID,
})

// Log how late into the slot the request starts
slotStartTimestamp := m.genesisTime + uint64(blindedBlock.Message.Slot)*config.SlotTimeSec
msIntoSlot := uint64(time.Now().UTC().UnixMilli()) - slotStartTimestamp*1000
log.WithFields(logrus.Fields{
"genesisTime": m.genesisTime,
"slotTimeSec": config.SlotTimeSec,
"msIntoSlot": msIntoSlot,
}).Infof("submitBlindedBlock request start - %d milliseconds into slot %d", msIntoSlot, blindedBlock.Message.Slot)

// Get the bid!
bidKey := bidRespKey{slot: uint64(blindedBlock.Message.Slot), blockHash: blindedBlock.Message.Body.ExecutionPayloadHeader.BlockHash.String()}
m.bidsLock.Lock()
originalBid := m.bids[bidKey]
m.bidsLock.Unlock()
if originalBid.response.IsEmpty() {
log.Error("no bid for this getPayload payload found, was getHeader called before?")
} else if len(originalBid.relays) == 0 {
log.Warn("bid found but no associated relays")
}

// Add request headers
headers := map[string]string{HeaderKeySlotUID: currentSlotUID}

// Prepare for requests
var wg sync.WaitGroup
var mu sync.Mutex
result := new(builderApi.VersionedSubmitBlindedBlockResponse)

// Prepare the request context, which will be cancelled after the first successful response from a relay
requestCtx, requestCtxCancel := context.WithCancel(context.Background())
defer requestCtxCancel()

for _, relay := range m.relays {
wg.Add(1)
go func(relay types.RelayEntry) {
defer wg.Done()
url := relay.GetURI(params.PathGetPayload)
log := log.WithField("url", url)
log.Debug("calling getPayload")

responsePayload := new(builderApi.VersionedSubmitBlindedBlockResponse)
_, err := SendHTTPRequestWithRetries(requestCtx, m.httpClientGetPayload, http.MethodPost, url, ua, headers, blindedBlock, responsePayload, m.requestMaxRetries, log)
if err != nil {
if errors.Is(requestCtx.Err(), context.Canceled) {
log.Info("request was cancelled") // this is expected, if payload has already been received by another relay
} else {
log.WithError(err).Error("error making request to relay")
}
return
}

if getPayloadResponseIsEmpty(responsePayload) {
log.Error("response with empty data!")
return
}

payload := responsePayload.Electra.ExecutionPayload
blobs := responsePayload.Electra.BlobsBundle

// Ensure the response blockhash matches the request
if blindedBlock.Message.Body.ExecutionPayloadHeader.BlockHash != payload.BlockHash {
log.WithFields(logrus.Fields{
"responseBlockHash": payload.BlockHash.String(),
}).Error("requestBlockHash does not equal responseBlockHash")
return
}

commitments := blindedBlock.Message.Body.BlobKZGCommitments
// Ensure that blobs are valid and matches the request
if len(commitments) != len(blobs.Blobs) || len(commitments) != len(blobs.Commitments) || len(commitments) != len(blobs.Proofs) {
log.WithFields(logrus.Fields{
"requestBlobCommitments": len(commitments),
"responseBlobs": len(blobs.Blobs),
"responseBlobCommitments": len(blobs.Commitments),
"responseBlobProofs": len(blobs.Proofs),
}).Error("block KZG commitment length does not equal responseBlobs length")
return
}

for i, commitment := range commitments {
if commitment != blobs.Commitments[i] {
log.WithFields(logrus.Fields{
"requestBlobCommitment": commitment.String(),
"responseBlobCommitment": blobs.Commitments[i].String(),
"index": i,
}).Error("requestBlobCommitment does not equal responseBlobCommitment")
return
}
}

// Lock before accessing the shared payload
mu.Lock()
defer mu.Unlock()

if requestCtx.Err() != nil { // request has been cancelled (or deadline exceeded)
return
}

// Received successful response. Now cancel other requests and return immediately
requestCtxCancel()
*result = *responsePayload
log.Info("received payload from relay")
}(relay)
}

// Wait for all requests to complete...
wg.Wait()

// If no payload has been received from relay, log loudly about withholding!
if getPayloadResponseIsEmpty(result) {
originRelays := types.RelayEntriesToStrings(originalBid.relays)
log.WithField("relaysWithBid", strings.Join(originRelays, ", ")).Error("no payload received from relay!")
m.respondError(w, http.StatusBadGateway, errNoSuccessfulRelayResponse.Error())
return
}

m.respondOK(w, result)
}

func (m *BoostService) handleGetPayload(w http.ResponseWriter, req *http.Request) {
log := m.log.WithField("method", "getPayload")
log.Debug("getPayload request starts")
Expand All @@ -779,19 +920,24 @@ func (m *BoostService) handleGetPayload(w http.ResponseWriter, req *http.Request
}

// Decode the body now
payload := new(eth2ApiV1Deneb.SignedBlindedBeaconBlock)
payload := new(eth2ApiV1Electra.SignedBlindedBeaconBlock)
if err := DecodeJSON(bytes.NewReader(body), payload); err != nil {
log.Debug("could not decode Deneb request payload, attempting to decode body into Capella payload")
payload := new(eth2ApiV1Capella.SignedBlindedBeaconBlock)
log.Debug("could not decode Electra request payload, attempting to decode body into Deneb payload")
payload := new(eth2ApiV1Deneb.SignedBlindedBeaconBlock)
if err := DecodeJSON(bytes.NewReader(body), payload); err != nil {
log.WithError(err).WithField("body", string(body)).Error("could not decode request payload from the beacon-node (signed blinded beacon block)")
m.respondError(w, http.StatusBadRequest, err.Error())
log.Debug("could not decode Deneb request payload, attempting to decode body into Capella payload")
payload := new(eth2ApiV1Capella.SignedBlindedBeaconBlock)
if err := DecodeJSON(bytes.NewReader(body), payload); err != nil {
log.WithError(err).WithField("body", string(body)).Error("could not decode request payload from the beacon-node (signed blinded beacon block)")
m.respondError(w, http.StatusBadRequest, err.Error())
return
}
m.processCapellaPayload(w, req, log, payload, body)
return
}
m.processCapellaPayload(w, req, log, payload, body)
return
m.processDenebPayload(w, req, log, payload)
}
m.processDenebPayload(w, req, log, payload)
m.processElectraPayload(w, req, log, payload)
}

// CheckRelays sends a request to each one of the relays previously registered to get their status
Expand Down
6 changes: 6 additions & 0 deletions server/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,12 @@ func getPayloadResponseIsEmpty(payload *builderApi.VersionedSubmitBlindedBlockRe
payload.Deneb.BlobsBundle == nil {
return true
}
case spec.DataVersionElectra:
if payload.Electra == nil || payload.Electra.ExecutionPayload == nil ||
payload.Electra.ExecutionPayload.BlockHash == nilHash ||
payload.Electra.BlobsBundle == nil {
return true
}
case spec.DataVersionUnknown, spec.DataVersionPhase0, spec.DataVersionAltair, spec.DataVersionBellatrix:
return true
}
Expand Down
Loading