diff --git a/go.mod b/go.mod index 3960fed9..19f7f279 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.25.7 require ( github.com/ethereum/go-ethereum v1.17.3 github.com/ethpandaops/go-eth-engine-client v0.0.0-20260616025304-fcd77b340b2a - github.com/ethpandaops/go-eth2-client v0.1.3 + github.com/ethpandaops/go-eth2-client v0.1.4-0.20260618225213-e8d135e8cdc1 github.com/ethpandaops/service-authenticatoor v0.0.1 github.com/glebarez/go-sqlite v1.22.0 github.com/goccy/go-yaml v1.19.2 diff --git a/go.sum b/go.sum index 6785911a..b97551b6 100644 --- a/go.sum +++ b/go.sum @@ -68,8 +68,8 @@ github.com/ethereum/go-ethereum v1.17.3 h1:Ev/sQHH+UdKZHWjuVzhu2pxhi/sXaPZl23Q+Q github.com/ethereum/go-ethereum v1.17.3/go.mod h1:f2EhRwqewIZkGoQekywI2Y2RZAMTSavLNkD9qItFy1A= github.com/ethpandaops/go-eth-engine-client v0.0.0-20260616025304-fcd77b340b2a h1:JEFHklBYWjZgxnTKWF7Iv7iSKgfHJVRDgA3Ar3ncUNI= github.com/ethpandaops/go-eth-engine-client v0.0.0-20260616025304-fcd77b340b2a/go.mod h1:/DCIjcCCWKAUGu3UpmhjfchEq2MQCuWghu/crSEXzXc= -github.com/ethpandaops/go-eth2-client v0.1.3 h1:ZftRDaJfjT+fzgYAkOsFJmyWGnfkyKu7WYuXGLJtwQ8= -github.com/ethpandaops/go-eth2-client v0.1.3/go.mod h1:U3KdR8QSq8vqs9LWSGAF4ETHJpcB62E1DFf0gVMgWv0= +github.com/ethpandaops/go-eth2-client v0.1.4-0.20260618225213-e8d135e8cdc1 h1:kQC/fTbBdZ8uZxFd779/EezbpWb6KMd+wPIlXjUMoDo= +github.com/ethpandaops/go-eth2-client v0.1.4-0.20260618225213-e8d135e8cdc1/go.mod h1:U3KdR8QSq8vqs9LWSGAF4ETHJpcB62E1DFf0gVMgWv0= github.com/ethpandaops/service-authenticatoor v0.0.1 h1:yZ0gKYf+kkj92piqqYprpF6HkhEIhCNmzDrsYth92KI= github.com/ethpandaops/service-authenticatoor v0.0.1/go.mod h1:+C6sQMBxY2E3u6BITSZakQrGRovNnB1CamuQh/RIaXI= github.com/ferranbt/fastssz v0.1.4 h1:OCDB+dYDEQDvAgtAGnTSidK1Pe2tW3nFV40XyMkTeDY= diff --git a/pkg/builderapi/fulu/bid.go b/pkg/builderapi/fulu/bid.go index 53322b5c..89abc514 100644 --- a/pkg/builderapi/fulu/bid.go +++ b/pkg/builderapi/fulu/bid.go @@ -4,9 +4,10 @@ package fulu import ( "encoding/json" + eth2all "github.com/ethpandaops/go-eth2-client/spec/all" "github.com/ethpandaops/go-eth2-client/spec/deneb" - "github.com/ethpandaops/go-eth2-client/spec/electra" "github.com/ethpandaops/go-eth2-client/spec/phase0" + "github.com/ethpandaops/go-eth2-client/spec/version" "github.com/holiman/uint256" "github.com/pk910/dynamic-ssz/hasher" "github.com/pk910/dynamic-ssz/sszutils" @@ -16,7 +17,7 @@ import ( type BuilderBid struct { Header *deneb.ExecutionPayloadHeader `json:"header"` BlobKZGCommitments []deneb.KZGCommitment `json:"blob_kzg_commitments"` - ExecutionRequests *electra.ExecutionRequests `json:"execution_requests"` + ExecutionRequests *eth2all.ExecutionRequests `json:"execution_requests"` Value *uint256.Int `json:"value"` // wei as uint256 in spec Pubkey phase0.BLSPubKey `json:"pubkey"` } @@ -80,7 +81,7 @@ func (b *BuilderBid) HashTreeRootWith(hh sszutils.HashWalker) error { return err } } else { - empty := &electra.ExecutionRequests{} + empty := ð2all.ExecutionRequests{Version: version.DataVersionFulu} if err := empty.HashTreeRootWith(hh); err != nil { return err } @@ -116,7 +117,7 @@ type GetHeaderResponse struct { type builderBidJSON struct { Header *deneb.ExecutionPayloadHeader `json:"header"` BlobKZGCommitments []deneb.KZGCommitment `json:"blob_kzg_commitments"` - ExecutionRequests *electra.ExecutionRequests `json:"execution_requests"` + ExecutionRequests *eth2all.ExecutionRequests `json:"execution_requests"` Value string `json:"value"` Pubkey phase0.BLSPubKey `json:"pubkey"` } diff --git a/pkg/builderapi/fulu/build.go b/pkg/builderapi/fulu/build.go index 0beb8649..297ab45c 100644 --- a/pkg/builderapi/fulu/build.go +++ b/pkg/builderapi/fulu/build.go @@ -2,8 +2,9 @@ package fulu import ( - "github.com/ethpandaops/go-eth2-client/spec/electra" + eth2all "github.com/ethpandaops/go-eth2-client/spec/all" "github.com/ethpandaops/go-eth2-client/spec/phase0" + "github.com/ethpandaops/go-eth2-client/spec/version" "github.com/holiman/uint256" "github.com/ethpandaops/buildoor/pkg/payload_builder" @@ -36,9 +37,13 @@ func BuildSignedBuilderBid( return nil, err } - execRequests := event.ExecutionRequests - if execRequests == nil { - execRequests = &electra.ExecutionRequests{} + // Fulu Builder API wire format uses the Electra layout; builder + // deposit/exit requests (Gloas+) do not exist in this spec version. + execRequests := ð2all.ExecutionRequests{Version: version.DataVersionFulu} + if event.ExecutionRequests != nil { + execRequests.Deposits = event.ExecutionRequests.Deposits + execRequests.Withdrawals = event.ExecutionRequests.Withdrawals + execRequests.Consolidations = event.ExecutionRequests.Consolidations } value, overflow := uint256.FromBig(event.BlockValue) diff --git a/pkg/payload_bidder/bid.go b/pkg/payload_bidder/bid.go index c7dc2328..4c3b3048 100644 --- a/pkg/payload_bidder/bid.go +++ b/pkg/payload_bidder/bid.go @@ -6,7 +6,6 @@ import ( eth2all "github.com/ethpandaops/go-eth2-client/spec/all" "github.com/ethpandaops/go-eth2-client/spec/bellatrix" "github.com/ethpandaops/go-eth2-client/spec/deneb" - "github.com/ethpandaops/go-eth2-client/spec/electra" "github.com/ethpandaops/go-eth2-client/spec/gloas" "github.com/ethpandaops/go-eth2-client/spec/phase0" dynssz "github.com/pk910/dynamic-ssz" @@ -38,7 +37,7 @@ func BuildSignedBid( ) (*eth2all.SignedExecutionPayloadBid, error) { execRequests := p.ExecutionRequests if execRequests == nil { - execRequests = &electra.ExecutionRequests{} + execRequests = ð2all.ExecutionRequests{Version: p.ExecutionPayload.Version} } // dynssz so preset-dependent list limits resolve from the global spec. diff --git a/pkg/payload_bidder/reveal.go b/pkg/payload_bidder/reveal.go index 83a7c43d..ee702c10 100644 --- a/pkg/payload_bidder/reveal.go +++ b/pkg/payload_bidder/reveal.go @@ -4,7 +4,6 @@ import ( "fmt" eth2all "github.com/ethpandaops/go-eth2-client/spec/all" - "github.com/ethpandaops/go-eth2-client/spec/electra" "github.com/ethpandaops/go-eth2-client/spec/gloas" "github.com/ethpandaops/go-eth2-client/spec/phase0" @@ -33,11 +32,7 @@ func BuildSignedEnvelope( ) (signed *eth2all.SignedExecutionPayloadEnvelope, blobs, proofs [][]byte, err error) { execRequests := p.ExecutionRequests if execRequests == nil { - execRequests = &electra.ExecutionRequests{ - Deposits: []*electra.DepositRequest{}, - Withdrawals: []*electra.WithdrawalRequest{}, - Consolidations: []*electra.ConsolidationRequest{}, - } + execRequests = ð2all.ExecutionRequests{Version: p.ExecutionPayload.Version} } envelope := ð2all.ExecutionPayloadEnvelope{ diff --git a/pkg/payload_builder/execution_requests.go b/pkg/payload_builder/execution_requests.go index 7a428855..8bb33c64 100644 --- a/pkg/payload_builder/execution_requests.go +++ b/pkg/payload_builder/execution_requests.go @@ -7,26 +7,36 @@ import ( "github.com/ethpandaops/go-eth-engine-client/spec/prague" "github.com/ethpandaops/go-eth2-client/spec/bellatrix" "github.com/ethpandaops/go-eth2-client/spec/electra" + "github.com/ethpandaops/go-eth2-client/spec/gloas" "github.com/ethpandaops/go-eth2-client/spec/phase0" + "github.com/ethpandaops/go-eth2-client/spec/version" + + eth2all "github.com/ethpandaops/go-eth2-client/spec/all" ) const ( - depositRequestType = 0x00 - withdrawalRequestType = 0x01 - consolidationRequestType = 0x02 - - depositRequestSize = 192 // 48 + 32 + 8 + 96 + 8 - withdrawalRequestSize = 76 // 20 + 48 + 8 - consolidationRequestSize = 116 // 20 + 48 + 48 + depositRequestType = 0x00 + withdrawalRequestType = 0x01 + consolidationRequestType = 0x02 + builderDepositRequestType = 0x03 // EIP-8282, Gloas+ + builderExitRequestType = 0x04 // EIP-8282, Gloas+ + + depositRequestSize = 192 // 48 + 32 + 8 + 96 + 8 + withdrawalRequestSize = 76 // 20 + 48 + 8 + consolidationRequestSize = 116 // 20 + 48 + 48 + builderDepositRequestSize = 184 // 48 + 32 + 8 + 96 + builderExitRequestSize = 68 // 20 + 48 ) // ParseExecutionRequests decodes raw EIP-7685 execution request bytes from the -// Engine API into typed electra.ExecutionRequests. +// Engine API into a versioned eth2all.ExecutionRequests. // // Each element in raw is: [type_prefix_byte || request_1 || request_2 || ...] // where all requests of the same type are concatenated after a single prefix byte. -func ParseExecutionRequests(raw []prague.ExecutionRequest) (*electra.ExecutionRequests, error) { - result := &electra.ExecutionRequests{ +// Builder deposit (0x03) and builder exit (0x04) requests are only valid from Gloas onwards. +func ParseExecutionRequests(raw []prague.ExecutionRequest, dataVersion version.DataVersion) (*eth2all.ExecutionRequests, error) { + result := ð2all.ExecutionRequests{ + Version: dataVersion, Deposits: make([]*electra.DepositRequest, 0), Withdrawals: make([]*electra.WithdrawalRequest, 0), Consolidations: make([]*electra.ConsolidationRequest, 0), @@ -68,6 +78,26 @@ func ParseExecutionRequests(raw []prague.ExecutionRequest) (*electra.ExecutionRe } result.Consolidations = consolidations + case builderDepositRequestType: + if dataVersion < version.DataVersionGloas { + return nil, fmt.Errorf("execution request %d: builder deposit request not valid before Gloas", i) + } + builderDeposits, err := parseBuilderDepositRequests(data) + if err != nil { + return nil, fmt.Errorf("execution request %d: %w", i, err) + } + result.BuilderDeposits = builderDeposits + + case builderExitRequestType: + if dataVersion < version.DataVersionGloas { + return nil, fmt.Errorf("execution request %d: builder exit request not valid before Gloas", i) + } + builderExits, err := parseBuilderExitRequests(data) + if err != nil { + return nil, fmt.Errorf("execution request %d: %w", i, err) + } + result.BuilderExits = builderExits + default: return nil, fmt.Errorf("execution request %d: unknown type 0x%02x", i, reqType) } @@ -170,3 +200,62 @@ func parseConsolidationRequests(data []byte) ([]*electra.ConsolidationRequest, e return consolidations, nil } + +func parseBuilderDepositRequests(data []byte) ([]*gloas.BuilderDepositRequest, error) { + if len(data)%builderDepositRequestSize != 0 { + return nil, fmt.Errorf("builder deposit requests: length %d not divisible by %d", len(data), builderDepositRequestSize) + } + + count := len(data) / builderDepositRequestSize + deposits := make([]*gloas.BuilderDepositRequest, count) + + for i := range count { + d := data[i*builderDepositRequestSize : (i+1)*builderDepositRequestSize] + + var pubkey phase0.BLSPubKey + copy(pubkey[:], d[0:48]) + + withdrawalCreds := make([]byte, 32) + copy(withdrawalCreds, d[48:80]) + + amount := phase0.Gwei(binary.LittleEndian.Uint64(d[80:88])) + + var sig phase0.BLSSignature + copy(sig[:], d[88:184]) + + deposits[i] = &gloas.BuilderDepositRequest{ + Pubkey: pubkey, + WithdrawalCredentials: withdrawalCreds, + Amount: amount, + Signature: sig, + } + } + + return deposits, nil +} + +func parseBuilderExitRequests(data []byte) ([]*gloas.BuilderExitRequest, error) { + if len(data)%builderExitRequestSize != 0 { + return nil, fmt.Errorf("builder exit requests: length %d not divisible by %d", len(data), builderExitRequestSize) + } + + count := len(data) / builderExitRequestSize + exits := make([]*gloas.BuilderExitRequest, count) + + for i := range count { + d := data[i*builderExitRequestSize : (i+1)*builderExitRequestSize] + + var addr bellatrix.ExecutionAddress + copy(addr[:], d[0:20]) + + var pubkey phase0.BLSPubKey + copy(pubkey[:], d[20:68]) + + exits[i] = &gloas.BuilderExitRequest{ + SourceAddress: addr, + Pubkey: pubkey, + } + } + + return exits, nil +} diff --git a/pkg/payload_builder/execution_requests_test.go b/pkg/payload_builder/execution_requests_test.go index d21ce090..8e002bf9 100644 --- a/pkg/payload_builder/execution_requests_test.go +++ b/pkg/payload_builder/execution_requests_test.go @@ -7,12 +7,13 @@ import ( "github.com/ethpandaops/go-eth-engine-client/spec/prague" "github.com/ethpandaops/go-eth2-client/spec/bellatrix" "github.com/ethpandaops/go-eth2-client/spec/phase0" + "github.com/ethpandaops/go-eth2-client/spec/version" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestParseExecutionRequests_Empty(t *testing.T) { - result, err := ParseExecutionRequests(nil) + result, err := ParseExecutionRequests(nil, version.DataVersionFulu) require.NoError(t, err) assert.Empty(t, result.Deposits) assert.Empty(t, result.Withdrawals) @@ -41,7 +42,7 @@ func TestParseExecutionRequests_SingleDeposit(t *testing.T) { entry := append([]byte{depositRequestType}, deposit...) - result, err := ParseExecutionRequests([]prague.ExecutionRequest{prague.ExecutionRequest(entry)}) + result, err := ParseExecutionRequests([]prague.ExecutionRequest{prague.ExecutionRequest(entry)}, version.DataVersionFulu) require.NoError(t, err) require.Len(t, result.Deposits, 1) @@ -80,7 +81,7 @@ func TestParseExecutionRequests_MultipleDeposits(t *testing.T) { data := append(d1, d2...) entry := append([]byte{depositRequestType}, data...) - result, err := ParseExecutionRequests([]prague.ExecutionRequest{prague.ExecutionRequest(entry)}) + result, err := ParseExecutionRequests([]prague.ExecutionRequest{prague.ExecutionRequest(entry)}, version.DataVersionFulu) require.NoError(t, err) require.Len(t, result.Deposits, 2) assert.Equal(t, uint64(1), result.Deposits[0].Index) @@ -100,7 +101,7 @@ func TestParseExecutionRequests_SingleWithdrawal(t *testing.T) { entry := append([]byte{withdrawalRequestType}, w...) - result, err := ParseExecutionRequests([]prague.ExecutionRequest{prague.ExecutionRequest(entry)}) + result, err := ParseExecutionRequests([]prague.ExecutionRequest{prague.ExecutionRequest(entry)}, version.DataVersionFulu) require.NoError(t, err) require.Len(t, result.Withdrawals, 1) @@ -135,7 +136,7 @@ func TestParseExecutionRequests_SingleConsolidation(t *testing.T) { entry := append([]byte{consolidationRequestType}, c...) - result, err := ParseExecutionRequests([]prague.ExecutionRequest{prague.ExecutionRequest(entry)}) + result, err := ParseExecutionRequests([]prague.ExecutionRequest{prague.ExecutionRequest(entry)}, version.DataVersionFulu) require.NoError(t, err) require.Len(t, result.Consolidations, 1) @@ -176,7 +177,7 @@ func TestParseExecutionRequests_AllThreeTypes(t *testing.T) { prague.ExecutionRequest(append([]byte{consolidationRequestType}, consolidation...)), } - result, err := ParseExecutionRequests(raw) + result, err := ParseExecutionRequests(raw, version.DataVersionFulu) require.NoError(t, err) require.Len(t, result.Deposits, 1) require.Len(t, result.Withdrawals, 1) @@ -185,6 +186,85 @@ func TestParseExecutionRequests_AllThreeTypes(t *testing.T) { assert.Equal(t, phase0.Gwei(500), result.Withdrawals[0].Amount) } +func TestParseExecutionRequests_AllFiveTypes(t *testing.T) { + deposit := make([]byte, depositRequestSize) + binary.LittleEndian.PutUint64(deposit[184:192], 99) + + withdrawal := make([]byte, withdrawalRequestSize) + binary.LittleEndian.PutUint64(withdrawal[68:76], 500) + + consolidation := make([]byte, consolidationRequestSize) + + builderDeposit := make([]byte, builderDepositRequestSize) + binary.LittleEndian.PutUint64(builderDeposit[80:88], 64_000_000_000) + + builderExit := make([]byte, builderExitRequestSize) + for i := 0; i < 20; i++ { + builderExit[i] = 0xCC + } + + raw := []prague.ExecutionRequest{ + prague.ExecutionRequest(append([]byte{depositRequestType}, deposit...)), + prague.ExecutionRequest(append([]byte{withdrawalRequestType}, withdrawal...)), + prague.ExecutionRequest(append([]byte{consolidationRequestType}, consolidation...)), + prague.ExecutionRequest(append([]byte{builderDepositRequestType}, builderDeposit...)), + prague.ExecutionRequest(append([]byte{builderExitRequestType}, builderExit...)), + } + + result, err := ParseExecutionRequests(raw, version.DataVersionGloas) + require.NoError(t, err) + require.Len(t, result.Deposits, 1) + require.Len(t, result.Withdrawals, 1) + require.Len(t, result.Consolidations, 1) + require.Len(t, result.BuilderDeposits, 1) + require.Len(t, result.BuilderExits, 1) + assert.Equal(t, uint64(99), result.Deposits[0].Index) + assert.Equal(t, phase0.Gwei(500), result.Withdrawals[0].Amount) + assert.Equal(t, phase0.Gwei(64_000_000_000), result.BuilderDeposits[0].Amount) + + var expectedAddr bellatrix.ExecutionAddress + for i := range expectedAddr { + expectedAddr[i] = 0xCC + } + assert.Equal(t, expectedAddr, result.BuilderExits[0].SourceAddress) +} + +func TestParseExecutionRequests_BuilderDepositBeforeGloas(t *testing.T) { + bd := make([]byte, builderDepositRequestSize) + entry := append([]byte{builderDepositRequestType}, bd...) + raw := []prague.ExecutionRequest{prague.ExecutionRequest(entry)} + _, err := ParseExecutionRequests(raw, version.DataVersionFulu) + assert.Error(t, err) + assert.Contains(t, err.Error(), "builder deposit request not valid before Gloas") +} + +func TestParseExecutionRequests_BuilderExitBeforeGloas(t *testing.T) { + be := make([]byte, builderExitRequestSize) + entry := append([]byte{builderExitRequestType}, be...) + raw := []prague.ExecutionRequest{prague.ExecutionRequest(entry)} + _, err := ParseExecutionRequests(raw, version.DataVersionFulu) + assert.Error(t, err) + assert.Contains(t, err.Error(), "builder exit request not valid before Gloas") +} + +func TestParseExecutionRequests_InvalidBuilderDepositLength(t *testing.T) { + data := make([]byte, 100) // not divisible by 184 + entry := append([]byte{builderDepositRequestType}, data...) + raw := []prague.ExecutionRequest{prague.ExecutionRequest(entry)} + _, err := ParseExecutionRequests(raw, version.DataVersionGloas) + assert.Error(t, err) + assert.Contains(t, err.Error(), "not divisible by") +} + +func TestParseExecutionRequests_InvalidBuilderExitLength(t *testing.T) { + data := make([]byte, 50) // not divisible by 68 + entry := append([]byte{builderExitRequestType}, data...) + raw := []prague.ExecutionRequest{prague.ExecutionRequest(entry)} + _, err := ParseExecutionRequests(raw, version.DataVersionGloas) + assert.Error(t, err) + assert.Contains(t, err.Error(), "not divisible by") +} + func TestParseExecutionRequests_TypePrefixOnly(t *testing.T) { // Entry with only type prefix and no data should be skipped raw := []prague.ExecutionRequest{ @@ -193,7 +273,7 @@ func TestParseExecutionRequests_TypePrefixOnly(t *testing.T) { {consolidationRequestType}, } - result, err := ParseExecutionRequests(raw) + result, err := ParseExecutionRequests(raw, version.DataVersionFulu) require.NoError(t, err) assert.Empty(t, result.Deposits) assert.Empty(t, result.Withdrawals) @@ -202,14 +282,14 @@ func TestParseExecutionRequests_TypePrefixOnly(t *testing.T) { func TestParseExecutionRequests_EmptyEntry(t *testing.T) { raw := []prague.ExecutionRequest{{}} - _, err := ParseExecutionRequests(raw) + _, err := ParseExecutionRequests(raw, version.DataVersionFulu) assert.Error(t, err) assert.Contains(t, err.Error(), "empty entry") } func TestParseExecutionRequests_UnknownType(t *testing.T) { raw := []prague.ExecutionRequest{{0xFF, 0x01}} - _, err := ParseExecutionRequests(raw) + _, err := ParseExecutionRequests(raw, version.DataVersionFulu) assert.Error(t, err) assert.Contains(t, err.Error(), "unknown type 0xff") } @@ -219,7 +299,7 @@ func TestParseExecutionRequests_InvalidDepositLength(t *testing.T) { data := make([]byte, 100) entry := append([]byte{depositRequestType}, data...) raw := []prague.ExecutionRequest{prague.ExecutionRequest(entry)} - _, err := ParseExecutionRequests(raw) + _, err := ParseExecutionRequests(raw, version.DataVersionFulu) assert.Error(t, err) assert.Contains(t, err.Error(), "not divisible by") } @@ -228,7 +308,7 @@ func TestParseExecutionRequests_InvalidWithdrawalLength(t *testing.T) { data := make([]byte, 50) // not divisible by 76 entry := append([]byte{withdrawalRequestType}, data...) raw := []prague.ExecutionRequest{prague.ExecutionRequest(entry)} - _, err := ParseExecutionRequests(raw) + _, err := ParseExecutionRequests(raw, version.DataVersionFulu) assert.Error(t, err) assert.Contains(t, err.Error(), "not divisible by") } @@ -237,7 +317,7 @@ func TestParseExecutionRequests_InvalidConsolidationLength(t *testing.T) { data := make([]byte, 50) // not divisible by 116 entry := append([]byte{consolidationRequestType}, data...) raw := []prague.ExecutionRequest{prague.ExecutionRequest(entry)} - _, err := ParseExecutionRequests(raw) + _, err := ParseExecutionRequests(raw, version.DataVersionFulu) assert.Error(t, err) assert.Contains(t, err.Error(), "not divisible by") } diff --git a/pkg/payload_builder/payload.go b/pkg/payload_builder/payload.go index 08e7bfba..8c5d4ba1 100644 --- a/pkg/payload_builder/payload.go +++ b/pkg/payload_builder/payload.go @@ -7,7 +7,6 @@ import ( "github.com/ethereum/go-ethereum/common" eth2all "github.com/ethpandaops/go-eth2-client/spec/all" - "github.com/ethpandaops/go-eth2-client/spec/electra" "github.com/ethpandaops/go-eth2-client/spec/phase0" "github.com/ethpandaops/buildoor/pkg/rpc/beacon" @@ -28,8 +27,8 @@ type Payload struct { ExecutionPayload *eth2all.ExecutionPayload // BlobsBundle holds the blobs/commitments/proofs (Deneb+), nil if none. BlobsBundle *BlobsBundle - // ExecutionRequests are the parsed execution requests (Electra+). - ExecutionRequests *electra.ExecutionRequests + // ExecutionRequests are the parsed execution requests (Electra+), versioned for the active fork. + ExecutionRequests *eth2all.ExecutionRequests // Metadata not carried by the objects above. BlockHash phase0.Hash32 // block hash after extra-data injection diff --git a/pkg/payload_builder/payload_builder.go b/pkg/payload_builder/payload_builder.go index 66fd6cbf..da9a2ab5 100644 --- a/pkg/payload_builder/payload_builder.go +++ b/pkg/payload_builder/payload_builder.go @@ -279,7 +279,7 @@ func (b *PayloadBuilder) BuildPayloadFromAttributes( // so consumers never touch the raw engine forms. beaconPayload := beaconPayloadFromEngine(enginePayload, beaconFork) - execRequests, err := ParseExecutionRequests(resp.ExecutionRequests) + execRequests, err := ParseExecutionRequests(resp.ExecutionRequests, beaconFork) if err != nil { return nil, fmt.Errorf("failed to parse execution requests: %w", err) }