diff --git a/beacon-chain/execution/engine_client.go b/beacon-chain/execution/engine_client.go index 12fe2682f64f..b5cf5cc74405 100644 --- a/beacon-chain/execution/engine_client.go +++ b/beacon-chain/execution/engine_client.go @@ -552,15 +552,6 @@ func (s *Service) GetPayloadBodiesByRange(ctx context.Context, start, count uint return result, handleRPCError(err) } -func emptyBody() *pb.ExecutionPayloadBodyV1Or2 { - return &pb.ExecutionPayloadBodyV1Or2{ - Transactions: make([]hexutil.Bytes, 0), - Withdrawals: make([]*pb.Withdrawal, 0), - WithdrawalRequests: make([]pb.WithdrawalRequestV1, 0), - DepositRequests: make([]pb.DepositRequestV1, 0), - } -} - // ReconstructFullBlock takes in a blinded beacon block and reconstructs // a beacon block with a full execution payload via the engine API. func (s *Service) ReconstructFullBlock( @@ -582,98 +573,6 @@ func (s *Service) ReconstructFullBellatrixBlockBatch( ctx context.Context, blindedBlocks []interfaces.ReadOnlySignedBeaconBlock, ) ([]interfaces.SignedBeaconBlock, error) { return reconstructBlindedBlockBatch(ctx, s.rpcClient, blindedBlocks) - /* - if len(blindedBlocks) == 0 { - return []interfaces.SignedBeaconBlock{}, nil - } - var executionHashes []common.Hash - var validExecPayloads []int - var zeroExecPayloads []int - for i, b := range blindedBlocks { - if err := blocks.BeaconBlockIsNil(b); err != nil { - return nil, errors.Wrap(err, "cannot reconstruct bellatrix block from nil data") - } - if !b.Block().IsBlinded() { - return nil, errors.New("can only reconstruct block from blinded block format") - } - header, err := b.Block().Body().Execution() - if err != nil { - return nil, err - } - if header.IsNil() { - return nil, errors.New("execution payload header in blinded block was nil") - } - // Determine if the block is pre-merge or post-merge. Depending on the result, - // we will ask the execution engine for the full payload. - if bytes.Equal(header.BlockHash(), params.BeaconConfig().ZeroHash[:]) { - zeroExecPayloads = append(zeroExecPayloads, i) - } else { - executionBlockHash := common.BytesToHash(header.BlockHash()) - validExecPayloads = append(validExecPayloads, i) - executionHashes = append(executionHashes, executionBlockHash) - } - } - fullBlocks, err := s.retrievePayloadsFromExecutionHashes(ctx, executionHashes, validExecPayloads, blindedBlocks) - if err != nil { - return nil, err - } - // For blocks that are pre-merge we simply reconstruct them via an empty - // execution payload. - for _, realIdx := range zeroExecPayloads { - bblock := blindedBlocks[realIdx] - payload, err := buildEmptyExecutionPayload(bblock.Version()) - if err != nil { - return nil, err - } - fullBlock, err := blocks.BuildSignedBeaconBlockFromExecutionPayload(blindedBlocks[realIdx], payload) - if err != nil { - return nil, err - } - fullBlocks[realIdx] = fullBlock - } - reconstructedExecutionPayloadCount.Add(float64(len(blindedBlocks))) - return fullBlocks, nil - */ -} - -// This method assumes that the provided execution hashes are all valid and part of the -// canonical chain. -func (s *Service) retrievePayloadsFromExecutionHashes( - ctx context.Context, - executionHashes []common.Hash, - validExecPayloads []int, - blindedBlocks []interfaces.ReadOnlySignedBeaconBlock) ([]interfaces.SignedBeaconBlock, error) { - - payloadBodies, err := s.GetPayloadBodiesByHash(ctx, executionHashes) - if err != nil { - return nil, fmt.Errorf("could not fetch payload bodies by hash %#x: %v", executionHashes, err) - } - if len(payloadBodies) != len(executionHashes) { - return nil, errors.Wrapf(errInvalidPayloadBodyResponse, "invalid number of payload bodies returned, want=%d, got=%d", len(executionHashes), len(payloadBodies)) - } - - fullBlocks := make([]interfaces.SignedBeaconBlock, len(blindedBlocks)) - // For each valid payload, we reconstruct the full block from it with the - // blinded block. - for sliceIdx, realIdx := range validExecPayloads { - var payload interfaces.ExecutionData - bblock := blindedBlocks[realIdx] - b := payloadBodies[sliceIdx] - header, err := bblock.Block().Body().Execution() - if err != nil { - return nil, err - } - payload, err = fullPayloadFromPayloadBody(header, b, bblock.Version()) - if err != nil { - return nil, err - } - fullBlock, err := blocks.BuildSignedBeaconBlockFromExecutionPayload(bblock, payload.Proto()) - if err != nil { - return nil, err - } - fullBlocks[realIdx] = fullBlock - } - return fullBlocks, nil } func fullPayloadFromPayloadBody( diff --git a/beacon-chain/execution/engine_client_test.go b/beacon-chain/execution/engine_client_test.go index c87874499fc9..4726c8cb3f7c 100644 --- a/beacon-chain/execution/engine_client_test.go +++ b/beacon-chain/execution/engine_client_test.go @@ -31,6 +31,7 @@ import ( "github.com/prysmaticlabs/prysm/v5/testing/assert" "github.com/prysmaticlabs/prysm/v5/testing/require" "github.com/prysmaticlabs/prysm/v5/testing/util" + "github.com/prysmaticlabs/prysm/v5/time/slots" logTest "github.com/sirupsen/logrus/hooks/test" ) @@ -2077,36 +2078,21 @@ func newPayloadV4Setup(t *testing.T, status *pb.PayloadStatus, payload *pb.Execu func TestCapella_PayloadBodiesByHash(t *testing.T) { t.Run("empty response works", func(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json") - defer func() { - require.NoError(t, r.Body.Close()) - }() - executionPayloadBodies := make([]*pb.ExecutionPayloadBodyV1Or2, 0) - resp := map[string]interface{}{ - "jsonrpc": "2.0", - "id": 1, - "result": executionPayloadBodies, - } - err := json.NewEncoder(w).Encode(resp) - require.NoError(t, err) + t.Fatal("http request should not be made") })) ctx := context.Background() rpcClient, err := rpc.DialHTTP(srv.URL) require.NoError(t, err) - service := &Service{} - service.rpcClient = rpcClient - - results, err := service.GetPayloadBodiesByHash(ctx, []common.Hash{}) + results, err := reconstructBlindedBlockBatch(ctx, rpcClient, []interfaces.ReadOnlySignedBeaconBlock{}) require.NoError(t, err) require.Equal(t, 0, len(results)) - - for _, item := range results { - require.NotNil(t, item) - } }) t.Run("single element response null works", func(t *testing.T) { + slot, err := slots.EpochStart(params.BeaconConfig().DenebForkEpoch) + require.NoError(t, err) + blk, _ := util.GenerateTestDenebBlockWithSidecar(t, [32]byte{}, slot, 0) srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") defer func() { @@ -2128,15 +2114,12 @@ func TestCapella_PayloadBodiesByHash(t *testing.T) { rpcClient, err := rpc.DialHTTP(srv.URL) require.NoError(t, err) + blinded, err := blk.ToBlinded() + require.NoError(t, err) service := &Service{} service.rpcClient = rpcClient - - bRoot := [32]byte{} - copy(bRoot[:], "hash") - results, err := service.GetPayloadBodiesByHash(ctx, []common.Hash{bRoot}) - require.NoError(t, err) - require.Equal(t, 1, len(results)) - require.IsNil(t, results[0]) + _, err = service.ReconstructFullBlock(ctx, blinded) + require.ErrorIs(t, err, errNilPayloadBody) }) t.Run("empty, null, full works", func(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { diff --git a/beacon-chain/execution/payload_body.go b/beacon-chain/execution/payload_body.go index 0f54fba3cb08..a82f311be94f 100644 --- a/beacon-chain/execution/payload_body.go +++ b/beacon-chain/execution/payload_body.go @@ -14,6 +14,8 @@ import ( "google.golang.org/protobuf/proto" ) +var errNilPayloadBody = errors.New("nil payload body for block") + type blockWithHeader struct { block interfaces.ReadOnlySignedBeaconBlock header interfaces.ExecutionData @@ -137,7 +139,7 @@ func (r *blindedBlockReconstructor) unblinded() ([]interfaces.SignedBeaconBlock, } else { body, ok := r.bodies[bodyKey] if !ok { - return nil, errors.Errorf("missing payload body for block hash %#x", bodyKey) + return nil, errors.Wrapf(errNilPayloadBody, "hash %#x", bodyKey) } ed, err := fullPayloadFromPayloadBody(header, body, blk.Version()) if err != nil {