From 2ec5914b4adb48bad48caa3d7370d220f09cbc49 Mon Sep 17 00:00:00 2001 From: james-prysm <90280386+james-prysm@users.noreply.github.com> Date: Thu, 7 Aug 2025 20:42:55 -0500 Subject: [PATCH] fixing builder version check (#15568) * adding fix * fixing test --- .../v1alpha1/validator/proposer_bellatrix.go | 14 +- .../validator/proposer_bellatrix_test.go | 139 ++++++++++-------- .../james-prysm_fix-builder-version-check.md | 3 + 3 files changed, 89 insertions(+), 67 deletions(-) create mode 100644 changelog/james-prysm_fix-builder-version-check.md diff --git a/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_bellatrix.go b/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_bellatrix.go index 619f7b3096..36d3f40d98 100644 --- a/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_bellatrix.go +++ b/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_bellatrix.go @@ -18,6 +18,7 @@ import ( "github.com/OffchainLabs/prysm/v6/encoding/ssz" "github.com/OffchainLabs/prysm/v6/monitoring/tracing" "github.com/OffchainLabs/prysm/v6/monitoring/tracing/trace" + "github.com/OffchainLabs/prysm/v6/network/forks" enginev1 "github.com/OffchainLabs/prysm/v6/proto/engine/v1" "github.com/OffchainLabs/prysm/v6/runtime/version" "github.com/OffchainLabs/prysm/v6/time/slots" @@ -219,9 +220,16 @@ func (vs *Server) getPayloadHeaderFromBuilder( return nil, errors.New("builder returned nil bid") } bidVersion := signedBid.Version() - headBlockVersion := b.Version() - if !isVersionCompatible(bidVersion, headBlockVersion) { - return nil, fmt.Errorf("builder bid response version: %d is not compatible with head block version: %d for epoch %d", bidVersion, headBlockVersion, slots.ToEpoch(slot)) + fork, err := forks.Fork(slots.ToEpoch(slot)) + if err != nil { + return nil, errors.Wrap(err, "unable to get fork information") + } + forkVersion, ok := params.ConfigForkVersions(params.BeaconConfig())[bytesutil.ToBytes4(fork.CurrentVersion)] + if !ok { + return nil, errors.New("unable to find current fork in schedule") + } + if !isVersionCompatible(bidVersion, forkVersion) { + return nil, fmt.Errorf("builder bid response version: %d is not compatible with expected version: %d for epoch %d", bidVersion, forkVersion, slots.ToEpoch(slot)) } bid, err := signedBid.Message() diff --git a/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_bellatrix_test.go b/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_bellatrix_test.go index 64cd7d4dca..572738227e 100644 --- a/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_bellatrix_test.go +++ b/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_bellatrix_test.go @@ -873,6 +873,7 @@ func TestServer_getPayloadHeader(t *testing.T) { err string returnedHeader *v1.ExecutionPayloadHeader returnedHeaderCapella *v1.ExecutionPayloadHeaderCapella + forkVersion int }{ { name: "can't request before bellatrix epoch", @@ -974,7 +975,7 @@ func TestServer_getPayloadHeader(t *testing.T) { return wb }(), }, - err: "builder bid response version: 3 is not compatible with head block version: 2 for epoch 1", + err: "builder bid response version: 3 is not compatible with expected version: 2 for epoch 1", }, { name: "different bid version during hard fork", @@ -1085,10 +1086,21 @@ func TestServer_getPayloadHeader(t *testing.T) { }(), }, // Should succeed because Electra bids are compatible with Fulu head blocks + forkVersion: version.Fulu, }, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { + if tc.forkVersion != 0 { + params.SetupTestConfigCleanup(t) + cfg := params.BeaconConfig() + if tc.forkVersion == version.Fulu { + cfg.FuluForkEpoch = 0 + cfg.BellatrixForkEpoch = 0 + cfg.InitializeForkSchedule() + } + params.OverrideBeaconConfig(cfg) + } vs := &Server{BeaconDB: dbTest.SetupDB(t), BlockBuilder: tc.mock, HeadFetcher: tc.fetcher, TimeFetcher: &blockchainTest.ChainService{ Genesis: genesis, }} @@ -1305,104 +1317,103 @@ func Test_expectedGasLimit(t *testing.T) { } func TestIsVersionCompatible(t *testing.T) { - tests := []struct { - name string - bidVersion int - headBlockVersion int - want bool + name string + bidVersion int + currentForkVersion int + want bool }{ { - name: "Exact version match - Bellatrix", - bidVersion: version.Bellatrix, - headBlockVersion: version.Bellatrix, - want: true, + name: "Exact version match - Bellatrix", + bidVersion: version.Bellatrix, + currentForkVersion: version.Bellatrix, + want: true, }, { - name: "Exact version match - Capella", - bidVersion: version.Capella, - headBlockVersion: version.Capella, - want: true, + name: "Exact version match - Capella", + bidVersion: version.Capella, + currentForkVersion: version.Capella, + want: true, }, { - name: "Exact version match - Deneb", - bidVersion: version.Deneb, - headBlockVersion: version.Deneb, - want: true, + name: "Exact version match - Deneb", + bidVersion: version.Deneb, + currentForkVersion: version.Deneb, + want: true, }, { - name: "Exact version match - Electra", - bidVersion: version.Electra, - headBlockVersion: version.Electra, - want: true, + name: "Exact version match - Electra", + bidVersion: version.Electra, + currentForkVersion: version.Electra, + want: true, }, { - name: "Exact version match - Fulu", - bidVersion: version.Fulu, - headBlockVersion: version.Fulu, - want: true, + name: "Exact version match - Fulu", + bidVersion: version.Fulu, + currentForkVersion: version.Fulu, + want: true, }, { - name: "Electra bid with Fulu head block - Compatible", - bidVersion: version.Electra, - headBlockVersion: version.Fulu, - want: true, + name: "Electra bid with Fulu head block - Compatible", + bidVersion: version.Electra, + currentForkVersion: version.Fulu, + want: true, }, { - name: "Fulu bid with Electra head block - Not compatible", - bidVersion: version.Fulu, - headBlockVersion: version.Electra, - want: false, + name: "Fulu bid with Electra head block - Not compatible", + bidVersion: version.Fulu, + currentForkVersion: version.Electra, + want: false, }, { - name: "Deneb bid with Electra head block - Not compatible", - bidVersion: version.Deneb, - headBlockVersion: version.Electra, - want: false, + name: "Deneb bid with Electra head block - Not compatible", + bidVersion: version.Deneb, + currentForkVersion: version.Electra, + want: false, }, { - name: "Electra bid with Deneb head block - Not compatible", - bidVersion: version.Electra, - headBlockVersion: version.Deneb, - want: false, + name: "Electra bid with Deneb head block - Not compatible", + bidVersion: version.Electra, + currentForkVersion: version.Deneb, + want: false, }, { - name: "Capella bid with Deneb head block - Not compatible", - bidVersion: version.Capella, - headBlockVersion: version.Deneb, - want: false, + name: "Capella bid with Deneb head block - Not compatible", + bidVersion: version.Capella, + currentForkVersion: version.Deneb, + want: false, }, { - name: "Bellatrix bid with Capella head block - Not compatible", - bidVersion: version.Bellatrix, - headBlockVersion: version.Capella, - want: false, + name: "Bellatrix bid with Capella head block - Not compatible", + bidVersion: version.Bellatrix, + currentForkVersion: version.Capella, + want: false, }, { - name: "Phase0 bid with Altair head block - Not compatible", - bidVersion: version.Phase0, - headBlockVersion: version.Altair, - want: false, + name: "Phase0 bid with Altair head block - Not compatible", + bidVersion: version.Phase0, + currentForkVersion: version.Altair, + want: false, }, { - name: "Deneb bid with Fulu head block - Not compatible", - bidVersion: version.Deneb, - headBlockVersion: version.Fulu, - want: false, + name: "Deneb bid with Fulu head block - Not compatible", + bidVersion: version.Deneb, + currentForkVersion: version.Fulu, + want: false, }, { - name: "Capella bid with Fulu head block - Not compatible", - bidVersion: version.Capella, - headBlockVersion: version.Fulu, - want: false, + name: "Capella bid with Fulu head block - Not compatible", + bidVersion: version.Capella, + currentForkVersion: version.Fulu, + want: false, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got := isVersionCompatible(tt.bidVersion, tt.headBlockVersion) + got := isVersionCompatible(tt.bidVersion, tt.currentForkVersion) if got != tt.want { - t.Errorf("isVersionCompatible(%d, %d) = %v, want %v", tt.bidVersion, tt.headBlockVersion, got, tt.want) + t.Errorf("isVersionCompatible(%d, %d) = %v, want %v", tt.bidVersion, tt.currentForkVersion, got, tt.want) } }) } diff --git a/changelog/james-prysm_fix-builder-version-check.md b/changelog/james-prysm_fix-builder-version-check.md new file mode 100644 index 0000000000..1ca5a30636 --- /dev/null +++ b/changelog/james-prysm_fix-builder-version-check.md @@ -0,0 +1,3 @@ +### Fixed + +- builder version check was using head block version instead of current fork's version based on slot, fixes e2e from https://github.com/OffchainLabs/prysm/commit/57e27199bdb9b3ef1af14c3374999aba5e0788a3. \ No newline at end of file