diff --git a/beacon-chain/rpc/eth/beacon/BUILD.bazel b/beacon-chain/rpc/eth/beacon/BUILD.bazel index 82a64dc146a9..89fa9fe1f567 100644 --- a/beacon-chain/rpc/eth/beacon/BUILD.bazel +++ b/beacon-chain/rpc/eth/beacon/BUILD.bazel @@ -137,6 +137,7 @@ go_test( "//testing/util:go_default_library", "//time/slots:go_default_library", "@com_github_ethereum_go_ethereum//common:go_default_library", + "@com_github_ethereum_go_ethereum//common/hexutil:go_default_library", "@com_github_golang_mock//gomock:go_default_library", "@com_github_grpc_ecosystem_grpc_gateway_v2//runtime:go_default_library", "@com_github_prysmaticlabs_go_bitfield//:go_default_library", diff --git a/beacon-chain/rpc/eth/beacon/handlers.go b/beacon-chain/rpc/eth/beacon/handlers.go index db6057834165..36c5dab07cde 100644 --- a/beacon-chain/rpc/eth/beacon/handlers.go +++ b/beacon-chain/rpc/eth/beacon/handlers.go @@ -59,6 +59,33 @@ func publishBlindedBlockV2SSZ(bs *Server, w http.ResponseWriter, r *http.Request network.WriteError(w, errJson) return } + denebBlockContents := ðpbv2.SignedBlindedBeaconBlockContentsDeneb{} + if err := denebBlockContents.UnmarshalSSZ(body); err == nil { + v1block, err := migration.BlindedDenebBlockContentsToV1Alpha1(denebBlockContents) + if err != nil { + errJson := &network.DefaultErrorJson{ + Message: "Could not decode request body into consensus block: " + err.Error(), + Code: http.StatusBadRequest, + } + network.WriteError(w, errJson) + return + } + genericBlock := ð.GenericSignedBeaconBlock{ + Block: ð.GenericSignedBeaconBlock_BlindedDeneb{ + BlindedDeneb: v1block, + }, + } + if err = bs.validateBroadcast(r, genericBlock); err != nil { + errJson := &network.DefaultErrorJson{ + Message: err.Error(), + Code: http.StatusBadRequest, + } + network.WriteError(w, errJson) + return + } + bs.proposeBlock(r.Context(), w, genericBlock) + return + } capellaBlock := ðpbv2.SignedBlindedBeaconBlockCapella{} if err := capellaBlock.UnmarshalSSZ(body); err == nil { v1block, err := migration.BlindedCapellaToV1Alpha1SignedBlock(capellaBlock) @@ -187,6 +214,30 @@ func publishBlindedBlockV2(bs *Server, w http.ResponseWriter, r *http.Request) { network.WriteError(w, errJson) return } + var denebBlockContents *SignedBlindedBeaconBlockContentsDeneb + if err = unmarshalStrict(body, &denebBlockContents); err == nil { + if err = validate.Struct(denebBlockContents); err == nil { + consensusBlock, err := denebBlockContents.ToGeneric() + if err != nil { + errJson := &network.DefaultErrorJson{ + Message: "Could not decode request body into consensus block: " + err.Error(), + Code: http.StatusBadRequest, + } + network.WriteError(w, errJson) + return + } + if err = bs.validateBroadcast(r, consensusBlock); err != nil { + errJson := &network.DefaultErrorJson{ + Message: err.Error(), + Code: http.StatusBadRequest, + } + network.WriteError(w, errJson) + return + } + bs.proposeBlock(r.Context(), w, consensusBlock) + return + } + } var capellaBlock *SignedBlindedBeaconBlockCapella if err = unmarshalStrict(body, &capellaBlock); err == nil { @@ -314,7 +365,6 @@ func (bs *Server) PublishBlockV2(w http.ResponseWriter, r *http.Request) { } func publishBlockV2SSZ(bs *Server, w http.ResponseWriter, r *http.Request) { - validate := validator.New() body, err := io.ReadAll(r.Body) if err != nil { errJson := &network.DefaultErrorJson{ @@ -324,121 +374,140 @@ func publishBlockV2SSZ(bs *Server, w http.ResponseWriter, r *http.Request) { network.WriteError(w, errJson) return } + denebBlockContents := ðpbv2.SignedBeaconBlockContentsDeneb{} + if err := denebBlockContents.UnmarshalSSZ(body); err == nil { + v1BlockContents, err := migration.DenebBlockContentsToV1Alpha1(denebBlockContents) + if err != nil { + errJson := &network.DefaultErrorJson{ + Message: "Could not decode request body into consensus block: " + err.Error(), + Code: http.StatusBadRequest, + } + network.WriteError(w, errJson) + return + } + genericBlock := ð.GenericSignedBeaconBlock{ + Block: ð.GenericSignedBeaconBlock_Deneb{ + Deneb: v1BlockContents, + }, + } + if err = bs.validateBroadcast(r, genericBlock); err != nil { + errJson := &network.DefaultErrorJson{ + Message: err.Error(), + Code: http.StatusBadRequest, + } + network.WriteError(w, errJson) + return + } + bs.proposeBlock(r.Context(), w, genericBlock) + return + } capellaBlock := ðpbv2.SignedBeaconBlockCapella{} if err := capellaBlock.UnmarshalSSZ(body); err == nil { - if err = validate.Struct(capellaBlock); err == nil { - v1block, err := migration.CapellaToV1Alpha1SignedBlock(capellaBlock) - if err != nil { - errJson := &network.DefaultErrorJson{ - Message: "Could not decode request body into consensus block: " + err.Error(), - Code: http.StatusBadRequest, - } - network.WriteError(w, errJson) - return - } - genericBlock := ð.GenericSignedBeaconBlock{ - Block: ð.GenericSignedBeaconBlock_Capella{ - Capella: v1block, - }, + v1block, err := migration.CapellaToV1Alpha1SignedBlock(capellaBlock) + if err != nil { + errJson := &network.DefaultErrorJson{ + Message: "Could not decode request body into consensus block: " + err.Error(), + Code: http.StatusBadRequest, } - if err = bs.validateBroadcast(r, genericBlock); err != nil { - errJson := &network.DefaultErrorJson{ - Message: err.Error(), - Code: http.StatusBadRequest, - } - network.WriteError(w, errJson) - return + network.WriteError(w, errJson) + return + } + genericBlock := ð.GenericSignedBeaconBlock{ + Block: ð.GenericSignedBeaconBlock_Capella{ + Capella: v1block, + }, + } + if err = bs.validateBroadcast(r, genericBlock); err != nil { + errJson := &network.DefaultErrorJson{ + Message: err.Error(), + Code: http.StatusBadRequest, } - bs.proposeBlock(r.Context(), w, genericBlock) + network.WriteError(w, errJson) return } + bs.proposeBlock(r.Context(), w, genericBlock) + return } bellatrixBlock := ðpbv2.SignedBeaconBlockBellatrix{} if err := bellatrixBlock.UnmarshalSSZ(body); err == nil { - if err = validate.Struct(bellatrixBlock); err == nil { - v1block, err := migration.BellatrixToV1Alpha1SignedBlock(bellatrixBlock) - if err != nil { - errJson := &network.DefaultErrorJson{ - Message: "Could not decode request body into consensus block: " + err.Error(), - Code: http.StatusBadRequest, - } - network.WriteError(w, errJson) - return - } - genericBlock := ð.GenericSignedBeaconBlock{ - Block: ð.GenericSignedBeaconBlock_Bellatrix{ - Bellatrix: v1block, - }, + v1block, err := migration.BellatrixToV1Alpha1SignedBlock(bellatrixBlock) + if err != nil { + errJson := &network.DefaultErrorJson{ + Message: "Could not decode request body into consensus block: " + err.Error(), + Code: http.StatusBadRequest, } - if err = bs.validateBroadcast(r, genericBlock); err != nil { - errJson := &network.DefaultErrorJson{ - Message: err.Error(), - Code: http.StatusBadRequest, - } - network.WriteError(w, errJson) - return + network.WriteError(w, errJson) + return + } + genericBlock := ð.GenericSignedBeaconBlock{ + Block: ð.GenericSignedBeaconBlock_Bellatrix{ + Bellatrix: v1block, + }, + } + if err = bs.validateBroadcast(r, genericBlock); err != nil { + errJson := &network.DefaultErrorJson{ + Message: err.Error(), + Code: http.StatusBadRequest, } - bs.proposeBlock(r.Context(), w, genericBlock) + network.WriteError(w, errJson) return } + bs.proposeBlock(r.Context(), w, genericBlock) + return } altairBlock := ðpbv2.SignedBeaconBlockAltair{} if err := altairBlock.UnmarshalSSZ(body); err == nil { - if err = validate.Struct(altairBlock); err == nil { - v1block, err := migration.AltairToV1Alpha1SignedBlock(altairBlock) - if err != nil { - errJson := &network.DefaultErrorJson{ - Message: "Could not decode request body into consensus block: " + err.Error(), - Code: http.StatusBadRequest, - } - network.WriteError(w, errJson) - return - } - genericBlock := ð.GenericSignedBeaconBlock{ - Block: ð.GenericSignedBeaconBlock_Altair{ - Altair: v1block, - }, + v1block, err := migration.AltairToV1Alpha1SignedBlock(altairBlock) + if err != nil { + errJson := &network.DefaultErrorJson{ + Message: "Could not decode request body into consensus block: " + err.Error(), + Code: http.StatusBadRequest, } - if err = bs.validateBroadcast(r, genericBlock); err != nil { - errJson := &network.DefaultErrorJson{ - Message: err.Error(), - Code: http.StatusBadRequest, - } - network.WriteError(w, errJson) - return + network.WriteError(w, errJson) + return + } + genericBlock := ð.GenericSignedBeaconBlock{ + Block: ð.GenericSignedBeaconBlock_Altair{ + Altair: v1block, + }, + } + if err = bs.validateBroadcast(r, genericBlock); err != nil { + errJson := &network.DefaultErrorJson{ + Message: err.Error(), + Code: http.StatusBadRequest, } - bs.proposeBlock(r.Context(), w, genericBlock) + network.WriteError(w, errJson) return } + bs.proposeBlock(r.Context(), w, genericBlock) + return } phase0Block := ðpbv1.SignedBeaconBlock{} if err := phase0Block.UnmarshalSSZ(body); err == nil { - if err = validate.Struct(phase0Block); err == nil { - v1block, err := migration.V1ToV1Alpha1SignedBlock(phase0Block) - if err != nil { - errJson := &network.DefaultErrorJson{ - Message: "Could not decode request body into consensus block: " + err.Error(), - Code: http.StatusBadRequest, - } - network.WriteError(w, errJson) - return - } - genericBlock := ð.GenericSignedBeaconBlock{ - Block: ð.GenericSignedBeaconBlock_Phase0{ - Phase0: v1block, - }, + v1block, err := migration.V1ToV1Alpha1SignedBlock(phase0Block) + if err != nil { + errJson := &network.DefaultErrorJson{ + Message: "Could not decode request body into consensus block: " + err.Error(), + Code: http.StatusBadRequest, } - if err = bs.validateBroadcast(r, genericBlock); err != nil { - errJson := &network.DefaultErrorJson{ - Message: err.Error(), - Code: http.StatusBadRequest, - } - network.WriteError(w, errJson) - return + network.WriteError(w, errJson) + return + } + genericBlock := ð.GenericSignedBeaconBlock{ + Block: ð.GenericSignedBeaconBlock_Phase0{ + Phase0: v1block, + }, + } + if err = bs.validateBroadcast(r, genericBlock); err != nil { + errJson := &network.DefaultErrorJson{ + Message: err.Error(), + Code: http.StatusBadRequest, } - bs.proposeBlock(r.Context(), w, genericBlock) + network.WriteError(w, errJson) return } + bs.proposeBlock(r.Context(), w, genericBlock) + return } errJson := &network.DefaultErrorJson{ Message: "Body does not represent a valid block type", @@ -458,6 +527,30 @@ func publishBlockV2(bs *Server, w http.ResponseWriter, r *http.Request) { network.WriteError(w, errJson) return } + var denebBlockContents *SignedBeaconBlockContentsDeneb + if err = unmarshalStrict(body, &denebBlockContents); err == nil { + if err = validate.Struct(denebBlockContents); err == nil { + consensusBlock, err := denebBlockContents.ToGeneric() + if err != nil { + errJson := &network.DefaultErrorJson{ + Message: "Could not decode request body into consensus block: " + err.Error(), + Code: http.StatusBadRequest, + } + network.WriteError(w, errJson) + return + } + if err = bs.validateBroadcast(r, consensusBlock); err != nil { + errJson := &network.DefaultErrorJson{ + Message: err.Error(), + Code: http.StatusBadRequest, + } + network.WriteError(w, errJson) + return + } + bs.proposeBlock(r.Context(), w, consensusBlock) + return + } + } var capellaBlock *SignedBeaconBlockCapella if err = unmarshalStrict(body, &capellaBlock); err == nil { if err = validate.Struct(capellaBlock); err == nil { diff --git a/beacon-chain/rpc/eth/beacon/handlers_test.go b/beacon-chain/rpc/eth/beacon/handlers_test.go index 58d4ed8cf055..a3ced79e24d1 100644 --- a/beacon-chain/rpc/eth/beacon/handlers_test.go +++ b/beacon-chain/rpc/eth/beacon/handlers_test.go @@ -3,14 +3,17 @@ package beacon import ( "bytes" "encoding/json" + "fmt" "net/http" "net/http/httptest" "strings" "testing" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/golang/mock/gomock" testing2 "github.com/prysmaticlabs/prysm/v4/beacon-chain/blockchain/testing" mockSync "github.com/prysmaticlabs/prysm/v4/beacon-chain/sync/initial-sync/testing" + "github.com/prysmaticlabs/prysm/v4/proto/migration" eth "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1" "github.com/prysmaticlabs/prysm/v4/testing/assert" mock2 "github.com/prysmaticlabs/prysm/v4/testing/mock" @@ -89,6 +92,23 @@ func TestPublishBlockV2(t *testing.T) { server.PublishBlockV2(writer, request) assert.Equal(t, http.StatusOK, writer.Code) }) + t.Run("Deneb", func(t *testing.T) { + v1alpha1Server := mock2.NewMockBeaconNodeValidatorServer(ctrl) + v1alpha1Server.EXPECT().ProposeBeaconBlock(gomock.Any(), mock.MatchedBy(func(req *eth.GenericSignedBeaconBlock) bool { + _, ok := req.Block.(*eth.GenericSignedBeaconBlock_Deneb) + return ok + })) + server := &Server{ + V1Alpha1ValidatorServer: v1alpha1Server, + SyncChecker: &mockSync.Sync{IsSyncing: false}, + } + + request := httptest.NewRequest(http.MethodPost, "http://foo.example", bytes.NewReader([]byte(denebBlockContents))) + writer := httptest.NewRecorder() + writer.Body = &bytes.Buffer{} + server.PublishBlockV2(writer, request) + assert.Equal(t, http.StatusOK, writer.Code) + }) t.Run("invalid block", func(t *testing.T) { server := &Server{ SyncChecker: &mockSync.Sync{IsSyncing: false}, @@ -121,7 +141,6 @@ func TestPublishBlockV2(t *testing.T) { func TestPublishBlockV2SSZ(t *testing.T) { ctrl := gomock.NewController(t) - t.Run("Bellatrix", func(t *testing.T) { v1alpha1Server := mock2.NewMockBeaconNodeValidatorServer(ctrl) v1alpha1Server.EXPECT().ProposeBeaconBlock(gomock.Any(), mock.MatchedBy(func(req *eth.GenericSignedBeaconBlock) bool { @@ -171,6 +190,33 @@ func TestPublishBlockV2SSZ(t *testing.T) { server.PublishBlockV2(writer, request) assert.Equal(t, http.StatusOK, writer.Code) }) + t.Run("Deneb", func(t *testing.T) { + v1alpha1Server := mock2.NewMockBeaconNodeValidatorServer(ctrl) + v1alpha1Server.EXPECT().ProposeBeaconBlock(gomock.Any(), mock.MatchedBy(func(req *eth.GenericSignedBeaconBlock) bool { + _, ok := req.Block.(*eth.GenericSignedBeaconBlock_Deneb) + return ok + })) + server := &Server{ + V1Alpha1ValidatorServer: v1alpha1Server, + SyncChecker: &mockSync.Sync{IsSyncing: false}, + } + + var dblock SignedBeaconBlockContentsDeneb + err := json.Unmarshal([]byte(denebBlockContents), &dblock) + require.NoError(t, err) + genericBlock, err := dblock.ToGeneric() + require.NoError(t, err) + v2block, err := migration.V1Alpha1SignedBeaconBlockDenebAndBlobsToV2(genericBlock.GetDeneb()) + require.NoError(t, err) + sszvalue, err := v2block.MarshalSSZ() + require.NoError(t, err) + request := httptest.NewRequest(http.MethodPost, "http://foo.example", bytes.NewReader(sszvalue)) + request.Header.Set("Accept", "application/octet-stream") + writer := httptest.NewRecorder() + writer.Body = &bytes.Buffer{} + server.PublishBlockV2(writer, request) + assert.Equal(t, http.StatusOK, writer.Code) + }) t.Run("invalid block", func(t *testing.T) { server := &Server{ SyncChecker: &mockSync.Sync{IsSyncing: false}, @@ -255,6 +301,23 @@ func TestPublishBlindedBlockV2(t *testing.T) { server.PublishBlindedBlockV2(writer, request) assert.Equal(t, http.StatusOK, writer.Code) }) + t.Run("Deneb", func(t *testing.T) { + v1alpha1Server := mock2.NewMockBeaconNodeValidatorServer(ctrl) + v1alpha1Server.EXPECT().ProposeBeaconBlock(gomock.Any(), mock.MatchedBy(func(req *eth.GenericSignedBeaconBlock) bool { + _, ok := req.Block.(*eth.GenericSignedBeaconBlock_BlindedDeneb) + return ok + })) + server := &Server{ + V1Alpha1ValidatorServer: v1alpha1Server, + SyncChecker: &mockSync.Sync{IsSyncing: false}, + } + + request := httptest.NewRequest(http.MethodPost, "http://foo.example", bytes.NewReader([]byte(blindedDenebBlockContents))) + writer := httptest.NewRecorder() + writer.Body = &bytes.Buffer{} + server.PublishBlindedBlockV2(writer, request) + assert.Equal(t, http.StatusOK, writer.Code) + }) t.Run("invalid block", func(t *testing.T) { server := &Server{ SyncChecker: &mockSync.Sync{IsSyncing: false}, @@ -337,6 +400,33 @@ func TestPublishBlindedBlockV2SSZ(t *testing.T) { server.PublishBlindedBlockV2(writer, request) assert.Equal(t, http.StatusOK, writer.Code) }) + t.Run("Deneb", func(t *testing.T) { + v1alpha1Server := mock2.NewMockBeaconNodeValidatorServer(ctrl) + v1alpha1Server.EXPECT().ProposeBeaconBlock(gomock.Any(), mock.MatchedBy(func(req *eth.GenericSignedBeaconBlock) bool { + _, ok := req.Block.(*eth.GenericSignedBeaconBlock_BlindedDeneb) + return ok + })) + server := &Server{ + V1Alpha1ValidatorServer: v1alpha1Server, + SyncChecker: &mockSync.Sync{IsSyncing: false}, + } + + var cblock SignedBlindedBeaconBlockContentsDeneb + err := json.Unmarshal([]byte(blindedDenebBlockContents), &cblock) + require.NoError(t, err) + genericBlock, err := cblock.ToGeneric() + require.NoError(t, err) + v1block, err := migration.V1Alpha1SignedBlindedBlockAndBlobsDenebToV2Blinded(genericBlock.GetBlindedDeneb()) + require.NoError(t, err) + sszvalue, err := v1block.MarshalSSZ() + require.NoError(t, err) + request := httptest.NewRequest(http.MethodPost, "http://foo.example", bytes.NewReader(sszvalue)) + request.Header.Set("Accept", "application/octet-stream") + writer := httptest.NewRecorder() + writer.Body = &bytes.Buffer{} + server.PublishBlindedBlockV2(writer, request) + assert.Equal(t, http.StatusOK, writer.Code) + }) t.Run("invalid block", func(t *testing.T) { server := &Server{ SyncChecker: &mockSync.Sync{IsSyncing: false}, @@ -1408,5 +1498,427 @@ const ( } }, "signature": "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" +}` + blindedDenebBlockContents = `{ + "signed_blinded_block":{ + "message": { + "slot": "1", + "proposer_index": "1", + "parent_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "state_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "body": { + "randao_reveal": "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505", + "eth1_data": { + "deposit_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "deposit_count": "1", + "block_hash": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2" + }, + "graffiti": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "proposer_slashings": [ + { + "signed_header_1": { + "message": { + "slot": "1", + "proposer_index": "1", + "parent_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "state_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "body_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2" + }, + "signature": "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" + }, + "signed_header_2": { + "message": { + "slot": "1", + "proposer_index": "1", + "parent_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "state_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "body_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2" + }, + "signature": "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" + } + } + ], + "attester_slashings": [ + { + "attestation_1": { + "attesting_indices": [ + "1" + ], + "signature": "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505", + "data": { + "slot": "1", + "index": "1", + "beacon_block_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "source": { + "epoch": "1", + "root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2" + }, + "target": { + "epoch": "1", + "root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2" + } + } + }, + "attestation_2": { + "attesting_indices": [ + "1" + ], + "signature": "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505", + "data": { + "slot": "1", + "index": "1", + "beacon_block_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "source": { + "epoch": "1", + "root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2" + }, + "target": { + "epoch": "1", + "root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2" + } + } + } + } + ], + "attestations": [ + { + "aggregation_bits": "0x01", + "signature": "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505", + "data": { + "slot": "1", + "index": "1", + "beacon_block_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "source": { + "epoch": "1", + "root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2" + }, + "target": { + "epoch": "1", + "root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2" + } + } + } + ], + "deposits": [ + { + "proof": [ + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2" + ], + "data": { + "pubkey": "0x93247f2209abcacf57b75a51dafae777f9dd38bc7053d1af526f220a7489a6d3a2753e5f3e8b1cfe39b56f43611df74a", + "withdrawal_credentials": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "amount": "1", + "signature": "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" + } + } + ], + "voluntary_exits": [ + { + "message": { + "epoch": "1", + "validator_index": "1" + }, + "signature": "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" + } + ], + "sync_aggregate": { + "sync_committee_bits": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "sync_committee_signature": "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" + }, + "execution_payload_header": { + "parent_hash": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "fee_recipient": "0xabcf8e0d4e9587369b2301d0790347320302cc09", + "state_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "receipts_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "logs_bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prev_randao": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "block_number": "1", + "gas_limit": "1", + "gas_used": "1", + "timestamp": "1", + "extra_data": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "base_fee_per_gas": "1", + "block_hash": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "data_gas_used": "1", + "excess_data_gas": "2", + "transactions_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "withdrawals_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2" + }, + "bls_to_execution_changes": [ + { + "message": { + "validator_index": "1", + "from_bls_pubkey": "0x93247f2209abcacf57b75a51dafae777f9dd38bc7053d1af526f220a7489a6d3a2753e5f3e8b1cfe39b56f43611df74a", + "to_execution_address": "0xabcf8e0d4e9587369b2301d0790347320302cc09" + }, + "signature": "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" + } + ], + "blob_kzg_commitments":["0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8000"] + } + }, + "signature": "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" +}, +"signed_blinded_blob_sidecars":[{ + "message":{ + "block_root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "index":"1", + "slot":"1", + "block_parent_root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "proposer_index":"1", + "blob_root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "kzg_commitment":"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8000", + "kzg_proof":"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8000" + }, + "signature":"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" + }] }` ) + +var denebBlockContents = fmt.Sprintf(`{ + "signed_block":{ + "message": { + "slot": "1", + "proposer_index": "1", + "parent_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "state_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "body": { + "randao_reveal": "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505", + "eth1_data": { + "deposit_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "deposit_count": "1", + "block_hash": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2" + }, + "graffiti": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "proposer_slashings": [ + { + "signed_header_1": { + "message": { + "slot": "1", + "proposer_index": "1", + "parent_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "state_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "body_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2" + }, + "signature": "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" + }, + "signed_header_2": { + "message": { + "slot": "1", + "proposer_index": "1", + "parent_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "state_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "body_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2" + }, + "signature": "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" + } + } + ], + "attester_slashings": [ + { + "attestation_1": { + "attesting_indices": [ + "1" + ], + "signature": "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505", + "data": { + "slot": "1", + "index": "1", + "beacon_block_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "source": { + "epoch": "1", + "root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2" + }, + "target": { + "epoch": "1", + "root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2" + } + } + }, + "attestation_2": { + "attesting_indices": [ + "1" + ], + "signature": "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505", + "data": { + "slot": "1", + "index": "1", + "beacon_block_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "source": { + "epoch": "1", + "root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2" + }, + "target": { + "epoch": "1", + "root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2" + } + } + } + } + ], + "attestations": [ + { + "aggregation_bits": "0x01", + "signature": "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505", + "data": { + "slot": "1", + "index": "1", + "beacon_block_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "source": { + "epoch": "1", + "root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2" + }, + "target": { + "epoch": "1", + "root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2" + } + } + } + ], + "deposits": [ + { + "proof": [ + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2" + ], + "data": { + "pubkey": "0x93247f2209abcacf57b75a51dafae777f9dd38bc7053d1af526f220a7489a6d3a2753e5f3e8b1cfe39b56f43611df74a", + "withdrawal_credentials": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "amount": "1", + "signature": "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" + } + } + ], + "voluntary_exits": [ + { + "message": { + "epoch": "1", + "validator_index": "1" + }, + "signature": "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" + } + ], + "sync_aggregate": { + "sync_committee_bits": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "sync_committee_signature": "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" + }, + "execution_payload": { + "parent_hash": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "fee_recipient": "0xabcf8e0d4e9587369b2301d0790347320302cc09", + "state_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "receipts_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "logs_bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prev_randao": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "block_number": "1", + "gas_limit": "1", + "gas_used": "1", + "timestamp": "1", + "extra_data": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "base_fee_per_gas": "1", + "block_hash": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "data_gas_used": "1", + "excess_data_gas": "2", + "transactions": [ + "0x02f878831469668303f51d843b9ac9f9843b9aca0082520894c93269b73096998db66be0441e836d873535cb9c8894a19041886f000080c001a031cc29234036afbf9a1fb9476b463367cb1f957ac0b919b69bbc798436e604aaa018c4e9c3914eb27aadd0b91e10b18655739fcf8c1fc398763a9f1beecb8ddc86" + ], + "withdrawals": [ + { + "index": "1", + "validator_index": "1", + "address": "0xabcf8e0d4e9587369b2301d0790347320302cc09", + "amount": "1" + } + ] + }, + "bls_to_execution_changes": [ + { + "message": { + "validator_index": "1", + "from_bls_pubkey": "0x93247f2209abcacf57b75a51dafae777f9dd38bc7053d1af526f220a7489a6d3a2753e5f3e8b1cfe39b56f43611df74a", + "to_execution_address": "0xabcf8e0d4e9587369b2301d0790347320302cc09" + }, + "signature": "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" + } + ], + "blob_kzg_commitments":["0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8000"] + } + }, + "signature": "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" + }, + "signed_blob_sidecars":[{ + "message":{ + "block_root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "index":"1", + "slot":"1", + "block_parent_root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "proposer_index":"1", + "blob":%s, + "kzg_commitment":"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8000", + "kzg_proof":"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8000" + }, + "signature":"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" + }] +}`, hexutil.Encode(make([]byte, 131072))) diff --git a/beacon-chain/rpc/eth/beacon/structs.go b/beacon-chain/rpc/eth/beacon/structs.go index 0d6f4cd7e236..6671f97dce06 100644 --- a/beacon-chain/rpc/eth/beacon/structs.go +++ b/beacon-chain/rpc/eth/beacon/structs.go @@ -1,6 +1,7 @@ package beacon import ( + "fmt" "math/big" "strconv" @@ -14,158 +15,281 @@ import ( ) type SignedBeaconBlock struct { - Message BeaconBlock `json:"message" validate:"required"` - Signature string `json:"signature" validate:"required"` + Message *BeaconBlock `json:"message" validate:"required"` + Signature string `json:"signature" validate:"required"` } type BeaconBlock struct { - Slot string `json:"slot" validate:"required"` - ProposerIndex string `json:"proposer_index" validate:"required"` - ParentRoot string `json:"parent_root" validate:"required"` - StateRoot string `json:"state_root" validate:"required"` - Body BeaconBlockBody `json:"body" validate:"required"` + Slot string `json:"slot" validate:"required"` + ProposerIndex string `json:"proposer_index" validate:"required"` + ParentRoot string `json:"parent_root" validate:"required"` + StateRoot string `json:"state_root" validate:"required"` + Body *BeaconBlockBody `json:"body" validate:"required"` } type BeaconBlockBody struct { - RandaoReveal string `json:"randao_reveal" validate:"required"` - Eth1Data Eth1Data `json:"eth1_data" validate:"required"` - Graffiti string `json:"graffiti" validate:"required"` - ProposerSlashings []ProposerSlashing `json:"proposer_slashings" validate:"required"` - AttesterSlashings []AttesterSlashing `json:"attester_slashings" validate:"required"` - Attestations []Attestation `json:"attestations" validate:"required"` - Deposits []Deposit `json:"deposits" validate:"required"` - VoluntaryExits []SignedVoluntaryExit `json:"voluntary_exits" validate:"required"` + RandaoReveal string `json:"randao_reveal" validate:"required"` + Eth1Data *Eth1Data `json:"eth1_data" validate:"required"` + Graffiti string `json:"graffiti" validate:"required"` + ProposerSlashings []*ProposerSlashing `json:"proposer_slashings" validate:"required"` + AttesterSlashings []*AttesterSlashing `json:"attester_slashings" validate:"required"` + Attestations []*Attestation `json:"attestations" validate:"required"` + Deposits []*Deposit `json:"deposits" validate:"required"` + VoluntaryExits []*SignedVoluntaryExit `json:"voluntary_exits" validate:"required"` } type SignedBeaconBlockAltair struct { - Message BeaconBlockAltair `json:"message" validate:"required"` - Signature string `json:"signature" validate:"required"` + Message *BeaconBlockAltair `json:"message" validate:"required"` + Signature string `json:"signature" validate:"required"` } type BeaconBlockAltair struct { - Slot string `json:"slot" validate:"required"` - ProposerIndex string `json:"proposer_index" validate:"required"` - ParentRoot string `json:"parent_root" validate:"required"` - StateRoot string `json:"state_root" validate:"required"` - Body BeaconBlockBodyAltair `json:"body" validate:"required"` + Slot string `json:"slot" validate:"required"` + ProposerIndex string `json:"proposer_index" validate:"required"` + ParentRoot string `json:"parent_root" validate:"required"` + StateRoot string `json:"state_root" validate:"required"` + Body *BeaconBlockBodyAltair `json:"body" validate:"required"` } type BeaconBlockBodyAltair struct { - RandaoReveal string `json:"randao_reveal" validate:"required"` - Eth1Data Eth1Data `json:"eth1_data" validate:"required"` - Graffiti string `json:"graffiti" validate:"required"` - ProposerSlashings []ProposerSlashing `json:"proposer_slashings" validate:"required"` - AttesterSlashings []AttesterSlashing `json:"attester_slashings" validate:"required"` - Attestations []Attestation `json:"attestations" validate:"required"` - Deposits []Deposit `json:"deposits" validate:"required"` - VoluntaryExits []SignedVoluntaryExit `json:"voluntary_exits" validate:"required"` - SyncAggregate SyncAggregate `json:"sync_aggregate" validate:"required"` + RandaoReveal string `json:"randao_reveal" validate:"required"` + Eth1Data *Eth1Data `json:"eth1_data" validate:"required"` + Graffiti string `json:"graffiti" validate:"required"` + ProposerSlashings []*ProposerSlashing `json:"proposer_slashings" validate:"required"` + AttesterSlashings []*AttesterSlashing `json:"attester_slashings" validate:"required"` + Attestations []*Attestation `json:"attestations" validate:"required"` + Deposits []*Deposit `json:"deposits" validate:"required"` + VoluntaryExits []*SignedVoluntaryExit `json:"voluntary_exits" validate:"required"` + SyncAggregate *SyncAggregate `json:"sync_aggregate" validate:"required"` } type SignedBeaconBlockBellatrix struct { - Message BeaconBlockBellatrix `json:"message" validate:"required"` - Signature string `json:"signature" validate:"required"` + Message *BeaconBlockBellatrix `json:"message" validate:"required"` + Signature string `json:"signature" validate:"required"` } type BeaconBlockBellatrix struct { - Slot string `json:"slot" validate:"required"` - ProposerIndex string `json:"proposer_index" validate:"required"` - ParentRoot string `json:"parent_root" validate:"required"` - StateRoot string `json:"state_root" validate:"required"` - Body BeaconBlockBodyBellatrix `json:"body" validate:"required"` + Slot string `json:"slot" validate:"required"` + ProposerIndex string `json:"proposer_index" validate:"required"` + ParentRoot string `json:"parent_root" validate:"required"` + StateRoot string `json:"state_root" validate:"required"` + Body *BeaconBlockBodyBellatrix `json:"body" validate:"required"` } type BeaconBlockBodyBellatrix struct { - RandaoReveal string `json:"randao_reveal" validate:"required"` - Eth1Data Eth1Data `json:"eth1_data" validate:"required"` - Graffiti string `json:"graffiti" validate:"required"` - ProposerSlashings []ProposerSlashing `json:"proposer_slashings" validate:"required"` - AttesterSlashings []AttesterSlashing `json:"attester_slashings" validate:"required"` - Attestations []Attestation `json:"attestations" validate:"required"` - Deposits []Deposit `json:"deposits" validate:"required"` - VoluntaryExits []SignedVoluntaryExit `json:"voluntary_exits" validate:"required"` - SyncAggregate SyncAggregate `json:"sync_aggregate" validate:"required"` - ExecutionPayload ExecutionPayload `json:"execution_payload" validate:"required"` + RandaoReveal string `json:"randao_reveal" validate:"required"` + Eth1Data *Eth1Data `json:"eth1_data" validate:"required"` + Graffiti string `json:"graffiti" validate:"required"` + ProposerSlashings []*ProposerSlashing `json:"proposer_slashings" validate:"required"` + AttesterSlashings []*AttesterSlashing `json:"attester_slashings" validate:"required"` + Attestations []*Attestation `json:"attestations" validate:"required"` + Deposits []*Deposit `json:"deposits" validate:"required"` + VoluntaryExits []*SignedVoluntaryExit `json:"voluntary_exits" validate:"required"` + SyncAggregate *SyncAggregate `json:"sync_aggregate" validate:"required"` + ExecutionPayload *ExecutionPayload `json:"execution_payload" validate:"required"` } type SignedBlindedBeaconBlockBellatrix struct { - Message BlindedBeaconBlockBellatrix `json:"message" validate:"required"` - Signature string `json:"signature" validate:"required"` + Message *BlindedBeaconBlockBellatrix `json:"message" validate:"required"` + Signature string `json:"signature" validate:"required"` } type BlindedBeaconBlockBellatrix struct { - Slot string `json:"slot" validate:"required"` - ProposerIndex string `json:"proposer_index" validate:"required"` - ParentRoot string `json:"parent_root" validate:"required"` - StateRoot string `json:"state_root" validate:"required"` - Body BlindedBeaconBlockBodyBellatrix `json:"body" validate:"required"` + Slot string `json:"slot" validate:"required"` + ProposerIndex string `json:"proposer_index" validate:"required"` + ParentRoot string `json:"parent_root" validate:"required"` + StateRoot string `json:"state_root" validate:"required"` + Body *BlindedBeaconBlockBodyBellatrix `json:"body" validate:"required"` } type BlindedBeaconBlockBodyBellatrix struct { - RandaoReveal string `json:"randao_reveal" validate:"required"` - Eth1Data Eth1Data `json:"eth1_data" validate:"required"` - Graffiti string `json:"graffiti" validate:"required"` - ProposerSlashings []ProposerSlashing `json:"proposer_slashings" validate:"required"` - AttesterSlashings []AttesterSlashing `json:"attester_slashings" validate:"required"` - Attestations []Attestation `json:"attestations" validate:"required"` - Deposits []Deposit `json:"deposits" validate:"required"` - VoluntaryExits []SignedVoluntaryExit `json:"voluntary_exits" validate:"required"` - SyncAggregate SyncAggregate `json:"sync_aggregate" validate:"required"` - ExecutionPayloadHeader ExecutionPayloadHeader `json:"execution_payload_header" validate:"required"` + RandaoReveal string `json:"randao_reveal" validate:"required"` + Eth1Data *Eth1Data `json:"eth1_data" validate:"required"` + Graffiti string `json:"graffiti" validate:"required"` + ProposerSlashings []*ProposerSlashing `json:"proposer_slashings" validate:"required"` + AttesterSlashings []*AttesterSlashing `json:"attester_slashings" validate:"required"` + Attestations []*Attestation `json:"attestations" validate:"required"` + Deposits []*Deposit `json:"deposits" validate:"required"` + VoluntaryExits []*SignedVoluntaryExit `json:"voluntary_exits" validate:"required"` + SyncAggregate *SyncAggregate `json:"sync_aggregate" validate:"required"` + ExecutionPayloadHeader *ExecutionPayloadHeader `json:"execution_payload_header" validate:"required"` } type SignedBeaconBlockCapella struct { - Message BeaconBlockCapella `json:"message" validate:"required"` - Signature string `json:"signature" validate:"required"` + Message *BeaconBlockCapella `json:"message" validate:"required"` + Signature string `json:"signature" validate:"required"` } type BeaconBlockCapella struct { - Slot string `json:"slot" validate:"required"` - ProposerIndex string `json:"proposer_index" validate:"required"` - ParentRoot string `json:"parent_root" validate:"required"` - StateRoot string `json:"state_root" validate:"required"` - Body BeaconBlockBodyCapella `json:"body" validate:"required"` + Slot string `json:"slot" validate:"required"` + ProposerIndex string `json:"proposer_index" validate:"required"` + ParentRoot string `json:"parent_root" validate:"required"` + StateRoot string `json:"state_root" validate:"required"` + Body *BeaconBlockBodyCapella `json:"body" validate:"required"` } type BeaconBlockBodyCapella struct { - RandaoReveal string `json:"randao_reveal" validate:"required"` - Eth1Data Eth1Data `json:"eth1_data" validate:"required"` - Graffiti string `json:"graffiti" validate:"required"` - ProposerSlashings []ProposerSlashing `json:"proposer_slashings" validate:"required"` - AttesterSlashings []AttesterSlashing `json:"attester_slashings" validate:"required"` - Attestations []Attestation `json:"attestations" validate:"required"` - Deposits []Deposit `json:"deposits" validate:"required"` - VoluntaryExits []SignedVoluntaryExit `json:"voluntary_exits" validate:"required"` - SyncAggregate SyncAggregate `json:"sync_aggregate" validate:"required"` - ExecutionPayload ExecutionPayloadCapella `json:"execution_payload" validate:"required"` - BlsToExecutionChanges []SignedBlsToExecutionChange `json:"bls_to_execution_changes" validate:"required"` + RandaoReveal string `json:"randao_reveal" validate:"required"` + Eth1Data *Eth1Data `json:"eth1_data" validate:"required"` + Graffiti string `json:"graffiti" validate:"required"` + ProposerSlashings []*ProposerSlashing `json:"proposer_slashings" validate:"required"` + AttesterSlashings []*AttesterSlashing `json:"attester_slashings" validate:"required"` + Attestations []*Attestation `json:"attestations" validate:"required"` + Deposits []*Deposit `json:"deposits" validate:"required"` + VoluntaryExits []*SignedVoluntaryExit `json:"voluntary_exits" validate:"required"` + SyncAggregate *SyncAggregate `json:"sync_aggregate" validate:"required"` + ExecutionPayload *ExecutionPayloadCapella `json:"execution_payload" validate:"required"` + BlsToExecutionChanges []*SignedBlsToExecutionChange `json:"bls_to_execution_changes" validate:"required"` } type SignedBlindedBeaconBlockCapella struct { - Message BlindedBeaconBlockCapella `json:"message" validate:"required"` - Signature string `json:"signature" validate:"required"` + Message *BlindedBeaconBlockCapella `json:"message" validate:"required"` + Signature string `json:"signature" validate:"required"` } type BlindedBeaconBlockCapella struct { - Slot string `json:"slot" validate:"required"` - ProposerIndex string `json:"proposer_index" validate:"required"` - ParentRoot string `json:"parent_root" validate:"required"` - StateRoot string `json:"state_root" validate:"required"` - Body BlindedBeaconBlockBodyCapella `json:"body" validate:"required"` + Slot string `json:"slot" validate:"required"` + ProposerIndex string `json:"proposer_index" validate:"required"` + ParentRoot string `json:"parent_root" validate:"required"` + StateRoot string `json:"state_root" validate:"required"` + Body *BlindedBeaconBlockBodyCapella `json:"body" validate:"required"` } type BlindedBeaconBlockBodyCapella struct { + RandaoReveal string `json:"randao_reveal" validate:"required"` + Eth1Data *Eth1Data `json:"eth1_data" validate:"required"` + Graffiti string `json:"graffiti" validate:"required"` + ProposerSlashings []*ProposerSlashing `json:"proposer_slashings" validate:"required"` + AttesterSlashings []*AttesterSlashing `json:"attester_slashings" validate:"required"` + Attestations []*Attestation `json:"attestations" validate:"required"` + Deposits []*Deposit `json:"deposits" validate:"required"` + VoluntaryExits []*SignedVoluntaryExit `json:"voluntary_exits" validate:"required"` + SyncAggregate *SyncAggregate `json:"sync_aggregate" validate:"required"` + ExecutionPayloadHeader *ExecutionPayloadHeaderCapella `json:"execution_payload_header" validate:"required"` + BlsToExecutionChanges []*SignedBlsToExecutionChange `json:"bls_to_execution_changes" validate:"required"` +} + +type SignedBeaconBlockContentsDeneb struct { + SignedBlock *SignedBeaconBlockDeneb `json:"signed_block" validate:"required"` + SignedBlobSidecars []*SignedBlobSidecar `json:"signed_blob_sidecars"` +} + +type SignedBeaconBlockDeneb struct { + Message *BeaconBlockDeneb `json:"message" validate:"required"` + Signature string `json:"signature" validate:"required"` +} + +type BeaconBlockDeneb struct { + Slot string `json:"slot" validate:"required"` + ProposerIndex string `json:"proposer_index" validate:"required"` + ParentRoot string `json:"parent_root" validate:"required"` + StateRoot string `json:"state_root" validate:"required"` + Body *BeaconBlockBodyDeneb `json:"body" validate:"required"` +} + +type BeaconBlockBodyDeneb struct { + RandaoReveal string `json:"randao_reveal" validate:"required"` + Eth1Data *Eth1Data `json:"eth1_data" validate:"required"` + Graffiti string `json:"graffiti" validate:"required"` + ProposerSlashings []*ProposerSlashing `json:"proposer_slashings" validate:"required"` + AttesterSlashings []*AttesterSlashing `json:"attester_slashings" validate:"required"` + Attestations []*Attestation `json:"attestations" validate:"required"` + Deposits []*Deposit `json:"deposits" validate:"required"` + VoluntaryExits []*SignedVoluntaryExit `json:"voluntary_exits" validate:"required"` + SyncAggregate *SyncAggregate `json:"sync_aggregate" validate:"required"` + ExecutionPayload *ExecutionPayloadDeneb `json:"execution_payload" validate:"required"` + BLSToExecutionChanges []*SignedBlsToExecutionChange `json:"bls_to_execution_changes" validate:"required"` + BlobKzgCommitments []string `json:"blob_kzg_commitments" validate:"required"` +} + +type ExecutionPayloadDeneb struct { + ParentHash string `json:"parent_hash" validate:"required"` + FeeRecipient string `json:"fee_recipient" validate:"required"` + StateRoot string `json:"state_root" validate:"required"` + ReceiptsRoot string `json:"receipts_root" validate:"required"` + LogsBloom string `json:"logs_bloom" validate:"required"` + PrevRandao string `json:"prev_randao" validate:"required"` + BlockNumber string `json:"block_number" validate:"required"` + GasLimit string `json:"gas_limit" validate:"required"` + GasUsed string `json:"gas_used" validate:"required"` + TimeStamp string `json:"timestamp" validate:"required"` + ExtraData string `json:"extra_data" validate:"required"` + BaseFeePerGas string `json:"base_fee_per_gas" validate:"required"` + DataGasUsed string `json:"data_gas_used" validate:"required"` // new in deneb + ExcessDataGas string `json:"excess_data_gas" validate:"required"` // new in deneb + BlockHash string `json:"block_hash" validate:"required"` + Transactions []string `json:"transactions" validate:"required"` + Withdrawals []*Withdrawal `json:"withdrawals" validate:"required"` +} + +type SignedBlindedBeaconBlockContentsDeneb struct { + SignedBlindedBlock *SignedBlindedBeaconBlockDeneb `json:"signed_blinded_block" validate:"required"` + SignedBlindedBlobSidecars []*SignedBlindedBlobSidecar `json:"signed_blinded_blob_sidecars"` +} + +type BlindedBeaconBlockContentsDeneb struct { + BlindedBlock *BlindedBeaconBlockDeneb `json:"blinded_block" validate:"required"` + BlindedBlobSidecars []*BlindedBlobSidecar `json:"blinded_blob_sidecars"` +} + +type BlindedBeaconBlockDeneb struct { + Slot string `json:"slot" validate:"required"` + ProposerIndex string `json:"proposer_index" validate:"required"` + ParentRoot string `json:"parent_root" validate:"required"` + StateRoot string `json:"state_root" validate:"required"` + Body *BlindedBeaconBlockBodyDeneb `json:"body" validate:"required"` +} + +type SignedBlindedBeaconBlockDeneb struct { + Message *BlindedBeaconBlockDeneb `json:"message" validate:"required"` + Signature string `json:"signature" validate:"required"` +} + +type BlindedBeaconBlockBodyDeneb struct { RandaoReveal string `json:"randao_reveal" validate:"required"` - Eth1Data Eth1Data `json:"eth1_data" validate:"required"` + Eth1Data *Eth1Data `json:"eth1_data" validate:"required"` Graffiti string `json:"graffiti" validate:"required"` - ProposerSlashings []ProposerSlashing `json:"proposer_slashings" validate:"required"` - AttesterSlashings []AttesterSlashing `json:"attester_slashings" validate:"required"` - Attestations []Attestation `json:"attestations" validate:"required"` - Deposits []Deposit `json:"deposits" validate:"required"` - VoluntaryExits []SignedVoluntaryExit `json:"voluntary_exits" validate:"required"` - SyncAggregate SyncAggregate `json:"sync_aggregate" validate:"required"` - ExecutionPayloadHeader ExecutionPayloadHeaderCapella `json:"execution_payload_header" validate:"required"` - BlsToExecutionChanges []SignedBlsToExecutionChange `json:"bls_to_execution_changes" validate:"required"` + ProposerSlashings []*ProposerSlashing `json:"proposer_slashings" validate:"required"` + AttesterSlashings []*AttesterSlashing `json:"attester_slashings" validate:"required"` + Attestations []*Attestation `json:"attestations" validate:"required"` + Deposits []*Deposit `json:"deposits" validate:"required"` + VoluntaryExits []*SignedVoluntaryExit `json:"voluntary_exits" validate:"required"` + SyncAggregate *SyncAggregate `json:"sync_aggregate" validate:"required"` + ExecutionPayloadHeader *ExecutionPayloadHeaderDeneb `json:"execution_payload_header" validate:"required"` + BlsToExecutionChanges []*SignedBlsToExecutionChange `json:"bls_to_execution_changes" validate:"required"` + BlobKzgCommitments []string `json:"blob_kzg_commitments" validate:"required"` +} + +type SignedBlindedBlobSidecar struct { + Message *BlindedBlobSidecar `json:"message" validate:"required"` + Signature string `json:"signature" validate:"required"` +} + +type SignedBlobSidecar struct { + Message *BlobSidecar `json:"message" validate:"required"` + Signature string `json:"signature" validate:"required"` +} + +type BlindedBlobSidecar struct { + BlockRoot string `json:"block_root" validate:"required"` + Index string `json:"index" validate:"required"` + Slot string `json:"slot" validate:"required"` + BlockParentRoot string `json:"block_parent_root" validate:"required"` + ProposerIndex string `json:"proposer_index" validate:"required"` + BlobRoot string `json:"blob_root" validate:"required"` + KzgCommitment string `json:"kzg_commitment" validate:"required"` // pattern: "^0x[a-fA-F0-9]{96}$" ssz-size:"48" + KzgProof string `json:"kzg_proof" validate:"required"` // pattern: "^0x[a-fA-F0-9]{96}$" ssz-size:"48" +} + +type BlobSidecar struct { + BlockRoot string `json:"block_root" validate:"required"` + Index string `json:"index" validate:"required"` + Slot string `json:"slot" validate:"required"` + BlockParentRoot string `json:"block_parent_root" validate:"required"` + ProposerIndex string `json:"proposer_index" validate:"required"` + Blob string `json:"blob" validate:"required"` // pattern: "^0x[a-fA-F0-9]{262144}$" + KzgCommitment string `json:"kzg_commitment" validate:"required"` // pattern: "^0x[a-fA-F0-9]{96}$" ssz-size:"48" + KzgProof string `json:"kzg_proof" validate:"required"` // pattern: "^0x[a-fA-F0-9]{96}$" ssz-size:"48" } type Eth1Data struct { @@ -319,6 +443,26 @@ type ExecutionPayloadHeaderCapella struct { WithdrawalsRoot string `json:"withdrawals_root" validate:"required"` } +type ExecutionPayloadHeaderDeneb struct { + ParentHash string `json:"parent_hash" validate:"required"` + FeeRecipient string `json:"fee_recipient" validate:"required"` + StateRoot string `json:"state_root" validate:"required"` + ReceiptsRoot string `json:"receipts_root" validate:"required"` + LogsBloom string `json:"logs_bloom" validate:"required"` + PrevRandao string `json:"prev_randao" validate:"required"` + BlockNumber string `json:"block_number" validate:"required"` + GasLimit string `json:"gas_limit" validate:"required"` + GasUsed string `json:"gas_used" validate:"required"` + Timestamp string `json:"timestamp" validate:"required"` + ExtraData string `json:"extra_data" validate:"required"` + BaseFeePerGas string `json:"base_fee_per_gas" validate:"required"` + DataGasUsed string `json:"data_gas_used" validate:"required"` // new in deneb + ExcessDataGas string `json:"excess_data_gas" validate:"required"` // new in deneb + BlockHash string `json:"block_hash" validate:"required"` + TransactionsRoot string `json:"transactions_root" validate:"required"` + WithdrawalsRoot string `json:"withdrawals_root" validate:"required"` +} + type Withdrawal struct { WithdrawalIndex string `json:"index" validate:"required"` ValidatorIndex string `json:"validator_index" validate:"required"` @@ -1260,11 +1404,575 @@ func (b *SignedBlindedBeaconBlockCapella) ToGeneric() (*eth.GenericSignedBeaconB return ð.GenericSignedBeaconBlock{Block: ð.GenericSignedBeaconBlock_BlindedCapella{BlindedCapella: block}}, nil } -func convertProposerSlashings(src []ProposerSlashing) ([]*eth.ProposerSlashing, error) { +func (b *SignedBeaconBlockContentsDeneb) ToGeneric() (*eth.GenericSignedBeaconBlock, error) { + var signedBlobSidecars []*eth.SignedBlobSidecar + if len(b.SignedBlobSidecars) != 0 { + signedBlobSidecars = make([]*eth.SignedBlobSidecar, len(b.SignedBlobSidecars)) + for i, s := range b.SignedBlobSidecars { + signedBlob, err := convertToSignedBlobSidecar(i, s) + if err != nil { + return nil, err + } + signedBlobSidecars[i] = signedBlob + } + } + signedDenebBlock, err := convertToSignedDenebBlock(b.SignedBlock) + if err != nil { + return nil, err + } + block := ð.SignedBeaconBlockAndBlobsDeneb{ + Block: signedDenebBlock, + Blobs: signedBlobSidecars, + } + return ð.GenericSignedBeaconBlock{Block: ð.GenericSignedBeaconBlock_Deneb{Deneb: block}}, nil +} + +func convertToSignedDenebBlock(signedBlock *SignedBeaconBlockDeneb) (*eth.SignedBeaconBlockDeneb, error) { + sig, err := hexutil.Decode(signedBlock.Signature) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlock .Signature") + } + slot, err := strconv.ParseUint(signedBlock.Message.Slot, 10, 64) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlock.Message.Slot") + } + proposerIndex, err := strconv.ParseUint(signedBlock.Message.ProposerIndex, 10, 64) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlock.Message.ProposerIndex") + } + parentRoot, err := hexutil.Decode(signedBlock.Message.ParentRoot) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlock.Message.ParentRoot") + } + stateRoot, err := hexutil.Decode(signedBlock.Message.StateRoot) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlock.Message.StateRoot") + } + randaoReveal, err := hexutil.Decode(signedBlock.Message.Body.RandaoReveal) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlock.Message.Body.RandaoReveal") + } + depositRoot, err := hexutil.Decode(signedBlock.Message.Body.Eth1Data.DepositRoot) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlock.Message.Body.Eth1Data.DepositRoot") + } + depositCount, err := strconv.ParseUint(signedBlock.Message.Body.Eth1Data.DepositCount, 10, 64) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlock.Message.Body.Eth1Data.DepositCount") + } + blockHash, err := hexutil.Decode(signedBlock.Message.Body.Eth1Data.BlockHash) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlock.Message.Body.Eth1Data.BlockHash") + } + graffiti, err := hexutil.Decode(signedBlock.Message.Body.Graffiti) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlock.Message.Body.Graffiti") + } + proposerSlashings, err := convertProposerSlashings(signedBlock.Message.Body.ProposerSlashings) + if err != nil { + return nil, err + } + attesterSlashings, err := convertAttesterSlashings(signedBlock.Message.Body.AttesterSlashings) + if err != nil { + return nil, err + } + atts, err := convertAtts(signedBlock.Message.Body.Attestations) + if err != nil { + return nil, err + } + deposits, err := convertDeposits(signedBlock.Message.Body.Deposits) + if err != nil { + return nil, err + } + exits, err := convertExits(signedBlock.Message.Body.VoluntaryExits) + if err != nil { + return nil, err + } + syncCommitteeBits, err := bytesutil.FromHexString(signedBlock.Message.Body.SyncAggregate.SyncCommitteeBits) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlock.Message.Body.SyncAggregate.SyncCommitteeBits") + } + syncCommitteeSig, err := hexutil.Decode(signedBlock.Message.Body.SyncAggregate.SyncCommitteeSignature) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlock.Message.Body.SyncAggregate.SyncCommitteeSignature") + } + payloadParentHash, err := hexutil.Decode(signedBlock.Message.Body.ExecutionPayload.ParentHash) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlock.Message.Body.ExecutionPayload.ParentHash") + } + payloadFeeRecipient, err := hexutil.Decode(signedBlock.Message.Body.ExecutionPayload.FeeRecipient) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlock.Message.Body.ExecutionPayload.FeeRecipient") + } + payloadStateRoot, err := hexutil.Decode(signedBlock.Message.Body.ExecutionPayload.StateRoot) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlock.Message.Body.ExecutionPayload.StateRoot") + } + payloadReceiptsRoot, err := hexutil.Decode(signedBlock.Message.Body.ExecutionPayload.ReceiptsRoot) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlock.Message.Body.ExecutionPayload.ReceiptsRoot") + } + payloadLogsBloom, err := hexutil.Decode(signedBlock.Message.Body.ExecutionPayload.LogsBloom) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlock.Message.Body.ExecutionPayload.LogsBloom") + } + payloadPrevRandao, err := hexutil.Decode(signedBlock.Message.Body.ExecutionPayload.PrevRandao) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlock.Message.Body.ExecutionPayload.PrevRandao") + } + payloadBlockNumber, err := strconv.ParseUint(signedBlock.Message.Body.ExecutionPayload.BlockNumber, 10, 64) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlock.Message.Body.ExecutionPayload.BlockNumber") + } + payloadGasLimit, err := strconv.ParseUint(signedBlock.Message.Body.ExecutionPayload.GasLimit, 10, 64) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlock.Message.Body.ExecutionPayload.GasLimit") + } + payloadGasUsed, err := strconv.ParseUint(signedBlock.Message.Body.ExecutionPayload.GasUsed, 10, 64) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlock.Message.Body.ExecutionPayload.GasUsed") + } + payloadTimestamp, err := strconv.ParseUint(signedBlock.Message.Body.ExecutionPayload.TimeStamp, 10, 64) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlock.Message.Body.ExecutionPayloadHeader.Timestamp") + } + payloadExtraData, err := hexutil.Decode(signedBlock.Message.Body.ExecutionPayload.ExtraData) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlock.Message.Body.ExecutionPayload.ExtraData") + } + payloadBaseFeePerGas, err := uint256ToHex(signedBlock.Message.Body.ExecutionPayload.BaseFeePerGas) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlock.Message.Body.ExecutionPayload.BaseFeePerGas") + } + payloadBlockHash, err := hexutil.Decode(signedBlock.Message.Body.ExecutionPayload.BlockHash) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlock.Message.Body.ExecutionPayload.BlockHash") + } + txs := make([][]byte, len(signedBlock.Message.Body.ExecutionPayload.Transactions)) + for i, tx := range signedBlock.Message.Body.ExecutionPayload.Transactions { + txs[i], err = hexutil.Decode(tx) + if err != nil { + return nil, errors.Wrapf(err, "could not decode signedBlock.Message.Body.ExecutionPayload.Transactions[%d]", i) + } + } + withdrawals := make([]*enginev1.Withdrawal, len(signedBlock.Message.Body.ExecutionPayload.Withdrawals)) + for i, w := range signedBlock.Message.Body.ExecutionPayload.Withdrawals { + withdrawalIndex, err := strconv.ParseUint(w.WithdrawalIndex, 10, 64) + if err != nil { + return nil, errors.Wrapf(err, "could not decode signedBlock.Message.Body.ExecutionPayload.Withdrawals[%d].WithdrawalIndex", i) + } + validatorIndex, err := strconv.ParseUint(w.ValidatorIndex, 10, 64) + if err != nil { + return nil, errors.Wrapf(err, "could not decode signedBlock.Message.Body.ExecutionPayload.Withdrawals[%d].ValidatorIndex", i) + } + address, err := hexutil.Decode(w.ExecutionAddress) + if err != nil { + return nil, errors.Wrapf(err, "could not decode b.Message.Body.ExecutionPayload.Withdrawals[%d].ExecutionAddress", i) + } + amount, err := strconv.ParseUint(w.Amount, 10, 64) + if err != nil { + return nil, errors.Wrapf(err, "could not decode b.Message.Body.ExecutionPayload.Withdrawals[%d].Amount", i) + } + withdrawals[i] = &enginev1.Withdrawal{ + Index: withdrawalIndex, + ValidatorIndex: primitives.ValidatorIndex(validatorIndex), + Address: address, + Amount: amount, + } + } + blsChanges, err := convertBlsChanges(signedBlock.Message.Body.BLSToExecutionChanges) + if err != nil { + return nil, err + } + payloadDataGasUsed, err := strconv.ParseUint(signedBlock.Message.Body.ExecutionPayload.DataGasUsed, 10, 64) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlock.Message.Body.ExecutionPayload.DataGasUsed") + } + payloadExcessDataGas, err := strconv.ParseUint(signedBlock.Message.Body.ExecutionPayload.ExcessDataGas, 10, 64) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlock.Message.Body.ExecutionPayload.ExcessDataGas") + } + return ð.SignedBeaconBlockDeneb{ + Block: ð.BeaconBlockDeneb{ + Slot: primitives.Slot(slot), + ProposerIndex: primitives.ValidatorIndex(proposerIndex), + ParentRoot: parentRoot, + StateRoot: stateRoot, + Body: ð.BeaconBlockBodyDeneb{ + RandaoReveal: randaoReveal, + Eth1Data: ð.Eth1Data{ + DepositRoot: depositRoot, + DepositCount: depositCount, + BlockHash: blockHash, + }, + Graffiti: graffiti, + ProposerSlashings: proposerSlashings, + AttesterSlashings: attesterSlashings, + Attestations: atts, + Deposits: deposits, + VoluntaryExits: exits, + SyncAggregate: ð.SyncAggregate{ + SyncCommitteeBits: syncCommitteeBits, + SyncCommitteeSignature: syncCommitteeSig, + }, + ExecutionPayload: &enginev1.ExecutionPayloadDeneb{ + ParentHash: payloadParentHash, + FeeRecipient: payloadFeeRecipient, + StateRoot: payloadStateRoot, + ReceiptsRoot: payloadReceiptsRoot, + LogsBloom: payloadLogsBloom, + PrevRandao: payloadPrevRandao, + BlockNumber: payloadBlockNumber, + GasLimit: payloadGasLimit, + GasUsed: payloadGasUsed, + Timestamp: payloadTimestamp, + ExtraData: payloadExtraData, + BaseFeePerGas: payloadBaseFeePerGas, + BlockHash: payloadBlockHash, + Transactions: txs, + Withdrawals: withdrawals, + DataGasUsed: payloadDataGasUsed, + ExcessDataGas: payloadExcessDataGas, + }, + BlsToExecutionChanges: blsChanges, + }, + }, + Signature: sig, + }, nil +} + +func convertToSignedBlobSidecar(i int, signedBlob *SignedBlobSidecar) (*eth.SignedBlobSidecar, error) { + blobSig, err := hexutil.Decode(signedBlob.Signature) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlob.Signature") + } + if signedBlob.Message == nil { + return nil, fmt.Errorf("blobsidecar message was empty at index %d", i) + } + blockRoot, err := hexutil.Decode(signedBlob.Message.BlockRoot) + if err != nil { + return nil, errors.Wrap(err, fmt.Sprintf("could not decode signedBlob.Message.BlockRoot at index %d", i)) + } + index, err := strconv.ParseUint(signedBlob.Message.Index, 10, 64) + if err != nil { + return nil, errors.Wrap(err, fmt.Sprintf("could not decode signedBlob.Message.Index at index %d", i)) + } + slot, err := strconv.ParseUint(signedBlob.Message.Slot, 10, 64) + if err != nil { + return nil, errors.Wrap(err, fmt.Sprintf("could not decode signedBlob.Message.Index at index %d", i)) + } + blockParentRoot, err := hexutil.Decode(signedBlob.Message.BlockParentRoot) + if err != nil { + return nil, errors.Wrap(err, fmt.Sprintf("could not decode signedBlob.Message.BlockParentRoot at index %d", i)) + } + proposerIndex, err := strconv.ParseUint(signedBlob.Message.ProposerIndex, 10, 64) + if err != nil { + return nil, errors.Wrap(err, fmt.Sprintf("could not decode signedBlob.Message.ProposerIndex at index %d", i)) + } + blob, err := hexutil.Decode(signedBlob.Message.Blob) + if err != nil { + return nil, errors.Wrap(err, fmt.Sprintf("could not decode signedBlob.Message.Blob at index %d", i)) + } + kzgCommitment, err := hexutil.Decode(signedBlob.Message.KzgCommitment) + if err != nil { + return nil, errors.Wrap(err, fmt.Sprintf("could not decode signedBlob.Message.KzgCommitment at index %d", i)) + } + kzgProof, err := hexutil.Decode(signedBlob.Message.KzgProof) + if err != nil { + return nil, errors.Wrap(err, fmt.Sprintf("could not decode signedBlob.Message.KzgProof at index %d", i)) + } + bsc := ð.BlobSidecar{ + BlockRoot: blockRoot, + Index: index, + Slot: primitives.Slot(slot), + BlockParentRoot: blockParentRoot, + ProposerIndex: primitives.ValidatorIndex(proposerIndex), + Blob: blob, + KzgCommitment: kzgCommitment, + KzgProof: kzgProof, + } + return ð.SignedBlobSidecar{ + Message: bsc, + Signature: blobSig, + }, nil +} + +func (b *SignedBlindedBeaconBlockContentsDeneb) ToGeneric() (*eth.GenericSignedBeaconBlock, error) { + var signedBlindedBlobSidecars []*eth.SignedBlindedBlobSidecar + if len(b.SignedBlindedBlobSidecars) != 0 { + signedBlindedBlobSidecars = make([]*eth.SignedBlindedBlobSidecar, len(b.SignedBlindedBlobSidecars)) + for i, s := range b.SignedBlindedBlobSidecars { + signedBlob, err := convertToSignedBlindedBlobSidecar(i, s) + if err != nil { + return nil, err + } + signedBlindedBlobSidecars[i] = signedBlob + } + } + signedBlindedBlock, err := convertToSignedBlindedDenebBlock(b.SignedBlindedBlock) + if err != nil { + return nil, err + } + block := ð.SignedBlindedBeaconBlockAndBlobsDeneb{ + Block: signedBlindedBlock, + Blobs: signedBlindedBlobSidecars, + } + return ð.GenericSignedBeaconBlock{Block: ð.GenericSignedBeaconBlock_BlindedDeneb{BlindedDeneb: block}}, nil +} + +func convertToSignedBlindedDenebBlock(signedBlindedBlock *SignedBlindedBeaconBlockDeneb) (*eth.SignedBlindedBeaconBlockDeneb, error) { + if signedBlindedBlock == nil { + return nil, errors.New("signed blinded block is empty") + } + sig, err := hexutil.Decode(signedBlindedBlock.Signature) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlindedBlock.Signature") + } + slot, err := strconv.ParseUint(signedBlindedBlock.Message.Slot, 10, 64) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlindedBlock.Message.Slot") + } + proposerIndex, err := strconv.ParseUint(signedBlindedBlock.Message.ProposerIndex, 10, 64) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlindedBlock.Message.ProposerIndex") + } + parentRoot, err := hexutil.Decode(signedBlindedBlock.Message.ParentRoot) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlindedBlock.Message.ParentRoot") + } + stateRoot, err := hexutil.Decode(signedBlindedBlock.Message.StateRoot) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlindedBlock.Message.StateRoot") + } + randaoReveal, err := hexutil.Decode(signedBlindedBlock.Message.Body.RandaoReveal) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlindedBlock.Message.Body.RandaoReveal") + } + depositRoot, err := hexutil.Decode(signedBlindedBlock.Message.Body.Eth1Data.DepositRoot) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlindedBlock.Message.Body.Eth1Data.DepositRoot") + } + depositCount, err := strconv.ParseUint(signedBlindedBlock.Message.Body.Eth1Data.DepositCount, 10, 64) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlindedBlock.Message.Body.Eth1Data.DepositCount") + } + blockHash, err := hexutil.Decode(signedBlindedBlock.Message.Body.Eth1Data.BlockHash) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlindedBlock.Message.Body.Eth1Data.BlockHash") + } + graffiti, err := hexutil.Decode(signedBlindedBlock.Message.Body.Graffiti) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlindedBlock.Message.Body.Graffiti") + } + proposerSlashings, err := convertProposerSlashings(signedBlindedBlock.Message.Body.ProposerSlashings) + if err != nil { + return nil, err + } + attesterSlashings, err := convertAttesterSlashings(signedBlindedBlock.Message.Body.AttesterSlashings) + if err != nil { + return nil, err + } + atts, err := convertAtts(signedBlindedBlock.Message.Body.Attestations) + if err != nil { + return nil, err + } + deposits, err := convertDeposits(signedBlindedBlock.Message.Body.Deposits) + if err != nil { + return nil, err + } + exits, err := convertExits(signedBlindedBlock.Message.Body.VoluntaryExits) + if err != nil { + return nil, err + } + syncCommitteeBits, err := bytesutil.FromHexString(signedBlindedBlock.Message.Body.SyncAggregate.SyncCommitteeBits) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlindedBlock.Message.Body.SyncAggregate.SyncCommitteeBits") + } + syncCommitteeSig, err := hexutil.Decode(signedBlindedBlock.Message.Body.SyncAggregate.SyncCommitteeSignature) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlindedBlock.Message.Body.SyncAggregate.SyncCommitteeSignature") + } + payloadParentHash, err := hexutil.Decode(signedBlindedBlock.Message.Body.ExecutionPayloadHeader.ParentHash) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlindedBlock.Message.Body.ExecutionPayloadHeader.ParentHash") + } + payloadFeeRecipient, err := hexutil.Decode(signedBlindedBlock.Message.Body.ExecutionPayloadHeader.FeeRecipient) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlindedBlock.Message.Body.ExecutionPayloadHeader.FeeRecipient") + } + payloadStateRoot, err := hexutil.Decode(signedBlindedBlock.Message.Body.ExecutionPayloadHeader.StateRoot) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlindedBlock.Message.Body.ExecutionPayloadHeader.StateRoot") + } + payloadReceiptsRoot, err := hexutil.Decode(signedBlindedBlock.Message.Body.ExecutionPayloadHeader.ReceiptsRoot) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlindedBlock.Message.Body.ExecutionPayloadHeader.ReceiptsRoot") + } + payloadLogsBloom, err := hexutil.Decode(signedBlindedBlock.Message.Body.ExecutionPayloadHeader.LogsBloom) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlindedBlock.Message.Body.ExecutionPayloadHeader.LogsBloom") + } + payloadPrevRandao, err := hexutil.Decode(signedBlindedBlock.Message.Body.ExecutionPayloadHeader.PrevRandao) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlindedBlock.Message.Body.ExecutionPayloadHeader.PrevRandao") + } + payloadBlockNumber, err := strconv.ParseUint(signedBlindedBlock.Message.Body.ExecutionPayloadHeader.BlockNumber, 10, 64) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlindedBlock.Message.Body.ExecutionPayloadHeader.BlockNumber") + } + payloadGasLimit, err := strconv.ParseUint(signedBlindedBlock.Message.Body.ExecutionPayloadHeader.GasLimit, 10, 64) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlindedBlock.Message.Body.ExecutionPayloadHeader.GasLimit") + } + payloadGasUsed, err := strconv.ParseUint(signedBlindedBlock.Message.Body.ExecutionPayloadHeader.GasUsed, 10, 64) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlindedBlock.Message.Body.ExecutionPayloadHeader.GasUsed") + } + payloadTimestamp, err := strconv.ParseUint(signedBlindedBlock.Message.Body.ExecutionPayloadHeader.Timestamp, 10, 64) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlindedBlock.Message.Body.ExecutionPayloadHeader.Timestamp") + } + payloadExtraData, err := hexutil.Decode(signedBlindedBlock.Message.Body.ExecutionPayloadHeader.ExtraData) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlindedBlock.Message.Body.ExecutionPayloadHeader.ExtraData") + } + payloadBaseFeePerGas, err := uint256ToHex(signedBlindedBlock.Message.Body.ExecutionPayloadHeader.BaseFeePerGas) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlindedBlock.Message.Body.ExecutionPayloadHeader.BaseFeePerGas") + } + payloadBlockHash, err := hexutil.Decode(signedBlindedBlock.Message.Body.ExecutionPayloadHeader.BlockHash) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlindedBlock.Message.Body.ExecutionPayloadHeader.BlockHash") + } + payloadTxsRoot, err := hexutil.Decode(signedBlindedBlock.Message.Body.ExecutionPayloadHeader.TransactionsRoot) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlindedBlock.Message.Body.ExecutionPayloadHeader.TransactionsRoot") + } + payloadWithdrawalsRoot, err := hexutil.Decode(signedBlindedBlock.Message.Body.ExecutionPayloadHeader.WithdrawalsRoot) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlindedBlock.Message.Body.ExecutionPayloadHeader.WithdrawalsRoot") + } + blsChanges, err := convertBlsChanges(signedBlindedBlock.Message.Body.BlsToExecutionChanges) + if err != nil { + return nil, err + } + payloadDataGasUsed, err := strconv.ParseUint(signedBlindedBlock.Message.Body.ExecutionPayloadHeader.DataGasUsed, 10, 64) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlindedBlock.Message.Body.ExecutionPayload.DataGasUsed") + } + payloadExcessDataGas, err := strconv.ParseUint(signedBlindedBlock.Message.Body.ExecutionPayloadHeader.ExcessDataGas, 10, 64) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlindedBlock.Message.Body.ExecutionPayload.ExcessDataGas") + } + return ð.SignedBlindedBeaconBlockDeneb{ + Block: ð.BlindedBeaconBlockDeneb{ + Slot: primitives.Slot(slot), + ProposerIndex: primitives.ValidatorIndex(proposerIndex), + ParentRoot: parentRoot, + StateRoot: stateRoot, + Body: ð.BlindedBeaconBlockBodyDeneb{ + RandaoReveal: randaoReveal, + Eth1Data: ð.Eth1Data{ + DepositRoot: depositRoot, + DepositCount: depositCount, + BlockHash: blockHash, + }, + Graffiti: graffiti, + ProposerSlashings: proposerSlashings, + AttesterSlashings: attesterSlashings, + Attestations: atts, + Deposits: deposits, + VoluntaryExits: exits, + SyncAggregate: ð.SyncAggregate{ + SyncCommitteeBits: syncCommitteeBits, + SyncCommitteeSignature: syncCommitteeSig, + }, + ExecutionPayloadHeader: &enginev1.ExecutionPayloadHeaderDeneb{ + ParentHash: payloadParentHash, + FeeRecipient: payloadFeeRecipient, + StateRoot: payloadStateRoot, + ReceiptsRoot: payloadReceiptsRoot, + LogsBloom: payloadLogsBloom, + PrevRandao: payloadPrevRandao, + BlockNumber: payloadBlockNumber, + GasLimit: payloadGasLimit, + GasUsed: payloadGasUsed, + Timestamp: payloadTimestamp, + ExtraData: payloadExtraData, + BaseFeePerGas: payloadBaseFeePerGas, + BlockHash: payloadBlockHash, + TransactionsRoot: payloadTxsRoot, + WithdrawalsRoot: payloadWithdrawalsRoot, + DataGasUsed: payloadDataGasUsed, + ExcessDataGas: payloadExcessDataGas, + }, + BlsToExecutionChanges: blsChanges, + }, + }, + Signature: sig, + }, nil +} + +func convertToSignedBlindedBlobSidecar(i int, signedBlob *SignedBlindedBlobSidecar) (*eth.SignedBlindedBlobSidecar, error) { + blobSig, err := hexutil.Decode(signedBlob.Signature) + if err != nil { + return nil, errors.Wrap(err, "could not decode signedBlob.Signature") + } + if signedBlob.Message == nil { + return nil, fmt.Errorf("blobsidecar message was empty at index %d", i) + } + blockRoot, err := hexutil.Decode(signedBlob.Message.BlockRoot) + if err != nil { + return nil, errors.Wrap(err, fmt.Sprintf("could not decode signedBlob.Message.BlockRoot at index %d", i)) + } + index, err := strconv.ParseUint(signedBlob.Message.Index, 10, 64) + if err != nil { + return nil, errors.Wrap(err, fmt.Sprintf("could not decode signedBlob.Message.Index at index %d", i)) + } + denebSlot, err := strconv.ParseUint(signedBlob.Message.Slot, 10, 64) + if err != nil { + return nil, errors.Wrap(err, fmt.Sprintf("could not decode signedBlob.Message.Index at index %d", i)) + } + blockParentRoot, err := hexutil.Decode(signedBlob.Message.BlockParentRoot) + if err != nil { + return nil, errors.Wrap(err, fmt.Sprintf("could not decode signedBlob.Message.BlockParentRoot at index %d", i)) + } + proposerIndex, err := strconv.ParseUint(signedBlob.Message.ProposerIndex, 10, 64) + if err != nil { + return nil, errors.Wrap(err, fmt.Sprintf("could not decode signedBlob.Message.ProposerIndex at index %d", i)) + } + blobRoot, err := hexutil.Decode(signedBlob.Message.BlobRoot) + if err != nil { + return nil, errors.Wrap(err, fmt.Sprintf("could not decode signedBlob.Message.BlobRoot at index %d", i)) + } + kzgCommitment, err := hexutil.Decode(signedBlob.Message.KzgCommitment) + if err != nil { + return nil, errors.Wrap(err, fmt.Sprintf("could not decode signedBlob.Message.KzgCommitment at index %d", i)) + } + kzgProof, err := hexutil.Decode(signedBlob.Message.KzgProof) + if err != nil { + return nil, errors.Wrap(err, fmt.Sprintf("could not decode signedBlob.Message.KzgProof at index %d", i)) + } + bsc := ð.BlindedBlobSidecar{ + BlockRoot: blockRoot, + Index: index, + Slot: primitives.Slot(denebSlot), + BlockParentRoot: blockParentRoot, + ProposerIndex: primitives.ValidatorIndex(proposerIndex), + BlobRoot: blobRoot, + KzgCommitment: kzgCommitment, + KzgProof: kzgProof, + } + return ð.SignedBlindedBlobSidecar{ + Message: bsc, + Signature: blobSig, + }, nil +} + +func convertProposerSlashings(src []*ProposerSlashing) ([]*eth.ProposerSlashing, error) { if src == nil { return nil, errors.New("nil b.Message.Body.ProposerSlashings") } - proposerSlashings := make([]*eth.ProposerSlashing, len(src)) for i, s := range src { h1Sig, err := hexutil.Decode(s.SignedHeader1.Signature) @@ -1341,11 +2049,10 @@ func convertProposerSlashings(src []ProposerSlashing) ([]*eth.ProposerSlashing, return proposerSlashings, nil } -func convertAttesterSlashings(src []AttesterSlashing) ([]*eth.AttesterSlashing, error) { +func convertAttesterSlashings(src []*AttesterSlashing) ([]*eth.AttesterSlashing, error) { if src == nil { return nil, errors.New("nil b.Message.Body.AttesterSlashings") } - attesterSlashings := make([]*eth.AttesterSlashing, len(src)) for i, s := range src { a1Sig, err := hexutil.Decode(s.Attestation1.Signature) @@ -1468,11 +2175,10 @@ func convertAttesterSlashings(src []AttesterSlashing) ([]*eth.AttesterSlashing, return attesterSlashings, nil } -func convertAtts(src []Attestation) ([]*eth.Attestation, error) { +func convertAtts(src []*Attestation) ([]*eth.Attestation, error) { if src == nil { return nil, errors.New("nil b.Message.Body.Attestations") } - atts := make([]*eth.Attestation, len(src)) for i, a := range src { sig, err := hexutil.Decode(a.Signature) @@ -1528,11 +2234,10 @@ func convertAtts(src []Attestation) ([]*eth.Attestation, error) { return atts, nil } -func convertDeposits(src []Deposit) ([]*eth.Deposit, error) { +func convertDeposits(src []*Deposit) ([]*eth.Deposit, error) { if src == nil { return nil, errors.New("nil b.Message.Body.Deposits") } - deposits := make([]*eth.Deposit, len(src)) for i, d := range src { proof := make([][]byte, len(d.Proof)) @@ -1572,11 +2277,10 @@ func convertDeposits(src []Deposit) ([]*eth.Deposit, error) { return deposits, nil } -func convertExits(src []SignedVoluntaryExit) ([]*eth.SignedVoluntaryExit, error) { +func convertExits(src []*SignedVoluntaryExit) ([]*eth.SignedVoluntaryExit, error) { if src == nil { return nil, errors.New("nil b.Message.Body.VoluntaryExits") } - exits := make([]*eth.SignedVoluntaryExit, len(src)) for i, e := range src { sig, err := hexutil.Decode(e.Signature) @@ -1602,11 +2306,10 @@ func convertExits(src []SignedVoluntaryExit) ([]*eth.SignedVoluntaryExit, error) return exits, nil } -func convertBlsChanges(src []SignedBlsToExecutionChange) ([]*eth.SignedBLSToExecutionChange, error) { +func convertBlsChanges(src []*SignedBlsToExecutionChange) ([]*eth.SignedBLSToExecutionChange, error) { if src == nil { return nil, errors.New("nil b.Message.Body.BlsToExecutionChanges") } - changes := make([]*eth.SignedBLSToExecutionChange, len(src)) for i, ch := range src { sig, err := hexutil.Decode(ch.Signature) diff --git a/network/BUILD.bazel b/network/BUILD.bazel index 0e168fc3744a..55de9435297f 100644 --- a/network/BUILD.bazel +++ b/network/BUILD.bazel @@ -12,6 +12,7 @@ go_library( importpath = "github.com/prysmaticlabs/prysm/v4/network", visibility = ["//visibility:public"], deps = [ + "//api:go_default_library", "//network/authorization:go_default_library", "@com_github_ethereum_go_ethereum//rpc:go_default_library", "@com_github_golang_jwt_jwt_v4//:go_default_library", diff --git a/network/reader.go b/network/reader.go index 99a24cecc4a8..ee5d9e6872b9 100644 --- a/network/reader.go +++ b/network/reader.go @@ -5,6 +5,8 @@ import ( "regexp" "strconv" "strings" + + "github.com/prysmaticlabs/prysm/v4/api" ) // match a number with optional decimals @@ -21,7 +23,7 @@ func SszRequested(req *http.Request) (bool, error) { for _, t := range types { values := strings.Split(t, ";") name := values[0] - if name != jsonMediaType && name != octetStreamMediaType { + if name != api.JsonMediaType && name != api.OctetStreamMediaType { continue } // no params specified @@ -47,5 +49,5 @@ func SszRequested(req *http.Request) (bool, error) { } } - return currentType == octetStreamMediaType, nil + return currentType == api.OctetStreamMediaType, nil } diff --git a/proto/migration/BUILD.bazel b/proto/migration/BUILD.bazel index 690e0b1c5355..94d384040d4d 100644 --- a/proto/migration/BUILD.bazel +++ b/proto/migration/BUILD.bazel @@ -6,6 +6,7 @@ go_library( "enums.go", "v1alpha1_to_v1.go", "v1alpha1_to_v2.go", + "v2_to_v1alpha1.go", ], importpath = "github.com/prysmaticlabs/prysm/v4/proto/migration", visibility = ["//visibility:public"], @@ -30,6 +31,7 @@ go_test( "enums_test.go", "v1alpha1_to_v1_test.go", "v1alpha1_to_v2_test.go", + "v2_to_v1alpha1_test.go", ], embed = [":go_default_library"], deps = [ diff --git a/proto/migration/v1alpha1_to_v2.go b/proto/migration/v1alpha1_to_v2.go index 4e4720987330..e83641b7e153 100644 --- a/proto/migration/v1alpha1_to_v2.go +++ b/proto/migration/v1alpha1_to_v2.go @@ -39,97 +39,6 @@ func V1Alpha1BeaconBlockAltairToV2Signed(v1alpha1Block *ethpbalpha.SignedBeaconB return v2Block, nil } -// AltairToV1Alpha1SignedBlock converts a v2 SignedBeaconBlockAltair proto to a v1alpha1 proto. -func AltairToV1Alpha1SignedBlock(altairBlk *ethpbv2.SignedBeaconBlockAltair) (*ethpbalpha.SignedBeaconBlockAltair, error) { - marshaledBlk, err := proto.Marshal(altairBlk) - if err != nil { - return nil, errors.Wrap(err, "could not marshal block") - } - v1alpha1Block := ðpbalpha.SignedBeaconBlockAltair{} - if err := proto.Unmarshal(marshaledBlk, v1alpha1Block); err != nil { - return nil, errors.Wrap(err, "could not unmarshal block") - } - return v1alpha1Block, nil -} - -// BellatrixToV1Alpha1SignedBlock converts a v2 SignedBeaconBlockBellatrix proto to a v1alpha1 proto. -func BellatrixToV1Alpha1SignedBlock(bellatrixBlk *ethpbv2.SignedBeaconBlockBellatrix) (*ethpbalpha.SignedBeaconBlockBellatrix, error) { - marshaledBlk, err := proto.Marshal(bellatrixBlk) - if err != nil { - return nil, errors.Wrap(err, "could not marshal block") - } - v1alpha1Block := ðpbalpha.SignedBeaconBlockBellatrix{} - if err := proto.Unmarshal(marshaledBlk, v1alpha1Block); err != nil { - return nil, errors.Wrap(err, "could not unmarshal block") - } - return v1alpha1Block, nil -} - -// CapellaToV1Alpha1SignedBlock converts a v2 SignedBeaconBlockCapella proto to a v1alpha1 proto. -func CapellaToV1Alpha1SignedBlock(capellaBlk *ethpbv2.SignedBeaconBlockCapella) (*ethpbalpha.SignedBeaconBlockCapella, error) { - marshaledBlk, err := proto.Marshal(capellaBlk) - if err != nil { - return nil, errors.Wrap(err, "could not marshal block") - } - v1alpha1Block := ðpbalpha.SignedBeaconBlockCapella{} - if err := proto.Unmarshal(marshaledBlk, v1alpha1Block); err != nil { - return nil, errors.Wrap(err, "could not unmarshal block") - } - return v1alpha1Block, nil -} - -// DenebToV1Alpha1SignedBlock converts a v2 SignedBeaconBlockDeneb proto to a v1alpha1 proto. -func DenebToV1Alpha1SignedBlock(denebBlk *ethpbv2.SignedBeaconBlockDeneb) (*ethpbalpha.SignedBeaconBlockDeneb, error) { - marshaledBlk, err := proto.Marshal(denebBlk) - if err != nil { - return nil, errors.Wrap(err, "could not marshal block") - } - v1alpha1Block := ðpbalpha.SignedBeaconBlockDeneb{} - if err := proto.Unmarshal(marshaledBlk, v1alpha1Block); err != nil { - return nil, errors.Wrap(err, "could not unmarshal block") - } - return v1alpha1Block, nil -} - -// BlindedBellatrixToV1Alpha1SignedBlock converts a v2 SignedBlindedBeaconBlockBellatrix proto to a v1alpha1 proto. -func BlindedBellatrixToV1Alpha1SignedBlock(bellatrixBlk *ethpbv2.SignedBlindedBeaconBlockBellatrix) (*ethpbalpha.SignedBlindedBeaconBlockBellatrix, error) { - marshaledBlk, err := proto.Marshal(bellatrixBlk) - if err != nil { - return nil, errors.Wrap(err, "could not marshal block") - } - v1alpha1Block := ðpbalpha.SignedBlindedBeaconBlockBellatrix{} - if err := proto.Unmarshal(marshaledBlk, v1alpha1Block); err != nil { - return nil, errors.Wrap(err, "could not unmarshal block") - } - return v1alpha1Block, nil -} - -// BlindedCapellaToV1Alpha1SignedBlock converts a v2 SignedBlindedBeaconBlockCapella proto to a v1alpha1 proto. -func BlindedCapellaToV1Alpha1SignedBlock(capellaBlk *ethpbv2.SignedBlindedBeaconBlockCapella) (*ethpbalpha.SignedBlindedBeaconBlockCapella, error) { - marshaledBlk, err := proto.Marshal(capellaBlk) - if err != nil { - return nil, errors.Wrap(err, "could not marshal block") - } - v1alpha1Block := ðpbalpha.SignedBlindedBeaconBlockCapella{} - if err := proto.Unmarshal(marshaledBlk, v1alpha1Block); err != nil { - return nil, errors.Wrap(err, "could not unmarshal block") - } - return v1alpha1Block, nil -} - -// BlindedDenebToV1Alpha1SignedBlock converts a v2 SignedBlindedBeaconBlockDeneb proto to a v1alpha1 proto. -func BlindedDenebToV1Alpha1SignedBlock(denebBlk *ethpbv2.SignedBlindedBeaconBlockDeneb) (*ethpbalpha.SignedBlindedBeaconBlockDeneb, error) { - marshaledBlk, err := proto.Marshal(denebBlk) - if err != nil { - return nil, errors.Wrap(err, "could not marshal block") - } - v1alpha1Block := ðpbalpha.SignedBlindedBeaconBlockDeneb{} - if err := proto.Unmarshal(marshaledBlk, v1alpha1Block); err != nil { - return nil, errors.Wrap(err, "could not unmarshal block") - } - return v1alpha1Block, nil -} - // V1Alpha1BeaconBlockBellatrixToV2 converts a v1alpha1 Bellatrix beacon block to a v2 // Bellatrix block. func V1Alpha1BeaconBlockBellatrixToV2(v1alpha1Block *ethpbalpha.BeaconBlockBellatrix) (*ethpbv2.BeaconBlockBellatrix, error) { @@ -172,18 +81,18 @@ func V1Alpha1BeaconBlockDenebToV2(v1alpha1Block *ethpbalpha.BeaconBlockDeneb) (* return v2Block, nil } -// V2BeaconBlockDenebToV1Alpha1 converts a v2 Deneb beacon block to a v1alpha1 +// V1Alpha1SignedBeaconBlockDenebToV2 converts a v1alpha1 signed Deneb beacon block to a v2 // Deneb block. -func V2BeaconBlockDenebToV1Alpha1(v2block *ethpbv2.BeaconBlockDeneb) (*ethpbalpha.BeaconBlockDeneb, error) { - marshaledBlk, err := proto.Marshal(v2block) +func V1Alpha1SignedBeaconBlockDenebToV2(v1alpha1Block *ethpbalpha.SignedBeaconBlockDeneb) (*ethpbv2.SignedBeaconBlockDeneb, error) { + marshaledBlk, err := proto.Marshal(v1alpha1Block) if err != nil { return nil, errors.Wrap(err, "could not marshal block") } - v1alpha1block := ðpbalpha.BeaconBlockDeneb{} - if err := proto.Unmarshal(marshaledBlk, v1alpha1block); err != nil { + v2Block := ðpbv2.SignedBeaconBlockDeneb{} + if err := proto.Unmarshal(marshaledBlk, v2Block); err != nil { return nil, errors.Wrap(err, "could not unmarshal block") } - return v1alpha1block, nil + return v2Block, nil } // V1Alpha1BlobSidecarsToV2 converts an array of v1alpha1 blinded blob sidecars to its v2 equivalent. @@ -220,6 +129,48 @@ func V1Alpha1BlindedBlobSidecarsToV2(v1alpha1Blobs []*ethpbalpha.BlindedBlobSide return v2Blobs, nil } +// V1Alpha1SignedBlindedBlobSidecarsToV2 converts an array of v1alpha1 objects to its v2 SignedBlindedBlobSidecar equivalent. +func V1Alpha1SignedBlindedBlobSidecarsToV2(sidecars []*ethpbalpha.SignedBlindedBlobSidecar) []*ethpbv2.SignedBlindedBlobSidecar { + result := make([]*ethpbv2.SignedBlindedBlobSidecar, len(sidecars)) + for i, sc := range sidecars { + result[i] = ðpbv2.SignedBlindedBlobSidecar{ + Message: ðpbv2.BlindedBlobSidecar{ + BlockRoot: bytesutil.SafeCopyBytes(sc.Message.BlockRoot), + Index: sc.Message.Index, + Slot: sc.Message.Slot, + BlockParentRoot: bytesutil.SafeCopyBytes(sc.Message.BlockParentRoot), + ProposerIndex: sc.Message.ProposerIndex, + BlobRoot: bytesutil.SafeCopyBytes(sc.Message.BlobRoot), + KzgCommitment: bytesutil.SafeCopyBytes(sc.Message.KzgCommitment), + KzgProof: bytesutil.SafeCopyBytes(sc.Message.KzgProof), + }, + Signature: bytesutil.SafeCopyBytes(sc.Signature), + } + } + return result +} + +// V1Alpha1SignedBlobsToV2 converts an array of v1alpha1 objects to its v2 SignedBlobSidecar equivalent. +func V1Alpha1SignedBlobsToV2(sidecars []*ethpbalpha.SignedBlobSidecar) []*ethpbv2.SignedBlobSidecar { + result := make([]*ethpbv2.SignedBlobSidecar, len(sidecars)) + for i, sc := range sidecars { + result[i] = ðpbv2.SignedBlobSidecar{ + Message: ðpbv2.BlobSidecar{ + BlockRoot: bytesutil.SafeCopyBytes(sc.Message.BlockRoot), + Index: sc.Message.Index, + Slot: sc.Message.Slot, + BlockParentRoot: bytesutil.SafeCopyBytes(sc.Message.BlockParentRoot), + ProposerIndex: sc.Message.ProposerIndex, + Blob: bytesutil.SafeCopyBytes(sc.Message.Blob), + KzgCommitment: bytesutil.SafeCopyBytes(sc.Message.KzgCommitment), + KzgProof: bytesutil.SafeCopyBytes(sc.Message.KzgProof), + }, + Signature: bytesutil.SafeCopyBytes(sc.Signature), + } + } + return result +} + // V1Alpha1BeaconBlockDenebAndBlobsToV2 converts a v1alpha1 Deneb beacon block and blobs to a v2 // Deneb block. func V1Alpha1BeaconBlockDenebAndBlobsToV2(v1alpha1Block *ethpbalpha.BeaconBlockAndBlobsDeneb) (*ethpbv2.BeaconBlockContentsDeneb, error) { @@ -234,19 +185,18 @@ func V1Alpha1BeaconBlockDenebAndBlobsToV2(v1alpha1Block *ethpbalpha.BeaconBlockA return ðpbv2.BeaconBlockContentsDeneb{Block: v2Block, BlobSidecars: v2Blobs}, nil } -// V1Alpha1BlindedBlockAndBlobsDenebToV2Blinded converts a v1alpha1 Deneb blinded beacon block and blobs to v2 blinded block contents. -func V1Alpha1BlindedBlockAndBlobsDenebToV2Blinded( - v1Alpha1BlkAndBlobs *ethpbalpha.BlindedBeaconBlockAndBlobsDeneb, -) (*ethpbv2.BlindedBeaconBlockContentsDeneb, error) { - v2Block, err := V1Alpha1BeaconBlockBlindedDenebToV2Blinded(v1Alpha1BlkAndBlobs.Block) +// V1Alpha1SignedBeaconBlockDenebAndBlobsToV2 converts a signed v1alpha1 Deneb beacon block and blobs to a v2 +// Deneb block. +func V1Alpha1SignedBeaconBlockDenebAndBlobsToV2(v1alpha1Block *ethpbalpha.SignedBeaconBlockAndBlobsDeneb) (*ethpbv2.SignedBeaconBlockContentsDeneb, error) { + v2Block, err := V1Alpha1SignedBeaconBlockDenebToV2(v1alpha1Block.Block) if err != nil { return nil, errors.Wrap(err, "could not convert block") } - v2Blobs, err := V1Alpha1BlindedBlobSidecarsToV2(v1Alpha1BlkAndBlobs.Blobs) - if err != nil { - return nil, errors.Wrap(err, "could not convert blobs") - } - return ðpbv2.BlindedBeaconBlockContentsDeneb{BlindedBlock: v2Block, BlindedBlobSidecars: v2Blobs}, nil + v2Blobs := V1Alpha1SignedBlobsToV2(v1alpha1Block.Blobs) + return ðpbv2.SignedBeaconBlockContentsDeneb{ + SignedBlock: v2Block, + SignedBlobSidecars: v2Blobs, + }, nil } // V1Alpha1BeaconBlockBlindedBellatrixToV2Blinded converts a v1alpha1 Blinded Bellatrix beacon block to a v2 Blinded Bellatrix block. @@ -288,6 +238,49 @@ func V1Alpha1BeaconBlockBlindedDenebToV2Blinded(v1alpha1Block *ethpbalpha.Blinde return v2Block, nil } +// V1Alpha1SignedBeaconBlockBlindedDenebToV2Blinded converts a v1alpha1 Signed Blinded Deneb beacon block to a v2 Blinded Deneb block. +func V1Alpha1SignedBeaconBlockBlindedDenebToV2Blinded(v1alpha1Block *ethpbalpha.SignedBlindedBeaconBlockDeneb) (*ethpbv2.SignedBlindedBeaconBlockDeneb, error) { + marshaledBlk, err := proto.Marshal(v1alpha1Block) + if err != nil { + return nil, errors.Wrap(err, "could not marshal block") + } + v2Block := ðpbv2.SignedBlindedBeaconBlockDeneb{} + if err := proto.Unmarshal(marshaledBlk, v2Block); err != nil { + return nil, errors.Wrap(err, "could not unmarshal block") + } + return v2Block, nil +} + +// V1Alpha1BlindedBlockAndBlobsDenebToV2Blinded converts a v1alpha1 Deneb blinded beacon block and blobs to v2 blinded block contents. +func V1Alpha1BlindedBlockAndBlobsDenebToV2Blinded( + v1Alpha1BlkAndBlobs *ethpbalpha.BlindedBeaconBlockAndBlobsDeneb, +) (*ethpbv2.BlindedBeaconBlockContentsDeneb, error) { + v2Block, err := V1Alpha1BeaconBlockBlindedDenebToV2Blinded(v1Alpha1BlkAndBlobs.Block) + if err != nil { + return nil, errors.Wrap(err, "could not convert block") + } + v2Blobs, err := V1Alpha1BlindedBlobSidecarsToV2(v1Alpha1BlkAndBlobs.Blobs) + if err != nil { + return nil, errors.Wrap(err, "could not convert blobs") + } + return ðpbv2.BlindedBeaconBlockContentsDeneb{BlindedBlock: v2Block, BlindedBlobSidecars: v2Blobs}, nil +} + +// V1Alpha1SignedBlindedBlockAndBlobsDenebToV2Blinded converts a v1alpha1 signed Deneb blinded beacon block and blobs to v2 blinded block contents. +func V1Alpha1SignedBlindedBlockAndBlobsDenebToV2Blinded( + v1Alpha1BlkAndBlobs *ethpbalpha.SignedBlindedBeaconBlockAndBlobsDeneb, +) (*ethpbv2.SignedBlindedBeaconBlockContentsDeneb, error) { + v2Block, err := V1Alpha1SignedBeaconBlockBlindedDenebToV2Blinded(v1Alpha1BlkAndBlobs.Block) + if err != nil { + return nil, errors.Wrap(err, "could not convert block") + } + v2Blobs := V1Alpha1SignedBlindedBlobSidecarsToV2(v1Alpha1BlkAndBlobs.Blobs) + return ðpbv2.SignedBlindedBeaconBlockContentsDeneb{ + SignedBlindedBlock: v2Block, + SignedBlindedBlobSidecars: v2Blobs, + }, nil +} + // V1Alpha1BeaconBlockBellatrixToV2Blinded converts a v1alpha1 Bellatrix beacon block to a v2 // blinded Bellatrix block. func V1Alpha1BeaconBlockBellatrixToV2Blinded(v1alpha1Block *ethpbalpha.BeaconBlockBellatrix) (*ethpbv2.BlindedBeaconBlockBellatrix, error) { @@ -1289,45 +1282,3 @@ func V1Alpha1SignedBLSToExecChangeToV2(alphaChange *ethpbalpha.SignedBLSToExecut } return result } - -// SignedBlindedBlobsToV1Alpha1SignedBlindedBlobs converts an array of v2 SignedBlindedBlobSidecar objects to its v1alpha1 equivalent. -func SignedBlindedBlobsToV1Alpha1SignedBlindedBlobs(sidecars []*ethpbv2.SignedBlindedBlobSidecar) []*ethpbalpha.SignedBlindedBlobSidecar { - result := make([]*ethpbalpha.SignedBlindedBlobSidecar, len(sidecars)) - for i, sc := range sidecars { - result[i] = ðpbalpha.SignedBlindedBlobSidecar{ - Message: ðpbalpha.BlindedBlobSidecar{ - BlockRoot: bytesutil.SafeCopyBytes(sc.Message.BlockRoot), - Index: sc.Message.Index, - Slot: sc.Message.Slot, - BlockParentRoot: bytesutil.SafeCopyBytes(sc.Message.BlockParentRoot), - ProposerIndex: sc.Message.ProposerIndex, - BlobRoot: bytesutil.SafeCopyBytes(sc.Message.BlobRoot), - KzgCommitment: bytesutil.SafeCopyBytes(sc.Message.KzgCommitment), - KzgProof: bytesutil.SafeCopyBytes(sc.Message.KzgProof), - }, - Signature: bytesutil.SafeCopyBytes(sc.Signature), - } - } - return result -} - -// SignedBlobsToV1Alpha1SignedBlobs converts an array of v2 SignedBlobSidecar objects to its v1alpha1 equivalent. -func SignedBlobsToV1Alpha1SignedBlobs(sidecars []*ethpbv2.SignedBlobSidecar) []*ethpbalpha.SignedBlobSidecar { - result := make([]*ethpbalpha.SignedBlobSidecar, len(sidecars)) - for i, sc := range sidecars { - result[i] = ðpbalpha.SignedBlobSidecar{ - Message: ðpbalpha.BlobSidecar{ - BlockRoot: bytesutil.SafeCopyBytes(sc.Message.BlockRoot), - Index: sc.Message.Index, - Slot: sc.Message.Slot, - BlockParentRoot: bytesutil.SafeCopyBytes(sc.Message.BlockParentRoot), - ProposerIndex: sc.Message.ProposerIndex, - Blob: bytesutil.SafeCopyBytes(sc.Message.Blob), - KzgCommitment: bytesutil.SafeCopyBytes(sc.Message.KzgCommitment), - KzgProof: bytesutil.SafeCopyBytes(sc.Message.KzgProof), - }, - Signature: bytesutil.SafeCopyBytes(sc.Signature), - } - } - return result -} diff --git a/proto/migration/v1alpha1_to_v2_test.go b/proto/migration/v1alpha1_to_v2_test.go index 11c208c82618..1a8133fe3b67 100644 --- a/proto/migration/v1alpha1_to_v2_test.go +++ b/proto/migration/v1alpha1_to_v2_test.go @@ -7,8 +7,6 @@ import ( "github.com/prysmaticlabs/prysm/v4/consensus-types/primitives" "github.com/prysmaticlabs/prysm/v4/encoding/bytesutil" enginev1 "github.com/prysmaticlabs/prysm/v4/proto/engine/v1" - ethpbv1 "github.com/prysmaticlabs/prysm/v4/proto/eth/v1" - ethpbv2 "github.com/prysmaticlabs/prysm/v4/proto/eth/v2" ethpbalpha "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1" "github.com/prysmaticlabs/prysm/v4/testing/assert" "github.com/prysmaticlabs/prysm/v4/testing/require" @@ -74,125 +72,6 @@ func Test_V1Alpha1BeaconBlockAltairToV2(t *testing.T) { assert.DeepEqual(t, alphaRoot, v2Root) } -func Test_AltairToV1Alpha1SignedBlock(t *testing.T) { - v2Block := util.HydrateV2AltairSignedBeaconBlock(ðpbv2.SignedBeaconBlockAltair{}) - v2Block.Message.Slot = slot - v2Block.Message.ProposerIndex = validatorIndex - v2Block.Message.ParentRoot = parentRoot - v2Block.Message.StateRoot = stateRoot - v2Block.Message.Body.RandaoReveal = randaoReveal - v2Block.Message.Body.Eth1Data = ðpbv1.Eth1Data{ - DepositRoot: depositRoot, - DepositCount: depositCount, - BlockHash: blockHash, - } - syncCommitteeBits := bitfield.NewBitvector512() - syncCommitteeBits.SetBitAt(100, true) - v2Block.Message.Body.SyncAggregate = ðpbv1.SyncAggregate{ - SyncCommitteeBits: syncCommitteeBits, - SyncCommitteeSignature: signature, - } - v2Block.Signature = signature - - alphaBlock, err := AltairToV1Alpha1SignedBlock(v2Block) - require.NoError(t, err) - alphaRoot, err := alphaBlock.HashTreeRoot() - require.NoError(t, err) - v2Root, err := v2Block.HashTreeRoot() - require.NoError(t, err) - assert.DeepEqual(t, v2Root, alphaRoot) -} - -func Test_BellatrixToV1Alpha1SignedBlock(t *testing.T) { - v2Block := util.HydrateV2BellatrixSignedBeaconBlock(ðpbv2.SignedBeaconBlockBellatrix{}) - v2Block.Message.Slot = slot - v2Block.Message.ProposerIndex = validatorIndex - v2Block.Message.ParentRoot = parentRoot - v2Block.Message.StateRoot = stateRoot - v2Block.Message.Body.RandaoReveal = randaoReveal - v2Block.Message.Body.Eth1Data = ðpbv1.Eth1Data{ - DepositRoot: depositRoot, - DepositCount: depositCount, - BlockHash: blockHash, - } - syncCommitteeBits := bitfield.NewBitvector512() - syncCommitteeBits.SetBitAt(100, true) - v2Block.Message.Body.SyncAggregate = ðpbv1.SyncAggregate{ - SyncCommitteeBits: syncCommitteeBits, - SyncCommitteeSignature: signature, - } - v2Block.Message.Body.ExecutionPayload = &enginev1.ExecutionPayload{ - ParentHash: parentHash, - FeeRecipient: feeRecipient, - StateRoot: stateRoot, - ReceiptsRoot: receiptsRoot, - LogsBloom: logsBloom, - PrevRandao: prevRandao, - BlockNumber: blockNumber, - GasLimit: gasLimit, - GasUsed: gasUsed, - Timestamp: timestamp, - ExtraData: extraData, - BaseFeePerGas: baseFeePerGas, - BlockHash: blockHash, - Transactions: [][]byte{[]byte("transaction1"), []byte("transaction2")}, - } - v2Block.Signature = signature - - alphaBlock, err := BellatrixToV1Alpha1SignedBlock(v2Block) - require.NoError(t, err) - alphaRoot, err := alphaBlock.HashTreeRoot() - require.NoError(t, err) - v2Root, err := v2Block.HashTreeRoot() - require.NoError(t, err) - assert.DeepEqual(t, v2Root, alphaRoot) -} - -func Test_BlindedBellatrixToV1Alpha1SignedBlock(t *testing.T) { - v2Block := util.HydrateV2SignedBlindedBeaconBlockBellatrix(ðpbv2.SignedBlindedBeaconBlockBellatrix{}) - v2Block.Message.Slot = slot - v2Block.Message.ProposerIndex = validatorIndex - v2Block.Message.ParentRoot = parentRoot - v2Block.Message.StateRoot = stateRoot - v2Block.Message.Body.RandaoReveal = randaoReveal - v2Block.Message.Body.Eth1Data = ðpbv1.Eth1Data{ - DepositRoot: depositRoot, - DepositCount: depositCount, - BlockHash: blockHash, - } - syncCommitteeBits := bitfield.NewBitvector512() - syncCommitteeBits.SetBitAt(100, true) - v2Block.Message.Body.SyncAggregate = ðpbv1.SyncAggregate{ - SyncCommitteeBits: syncCommitteeBits, - SyncCommitteeSignature: signature, - } - v2Block.Message.Body.ExecutionPayloadHeader = &enginev1.ExecutionPayloadHeader{ - ParentHash: parentHash, - FeeRecipient: feeRecipient, - StateRoot: stateRoot, - ReceiptsRoot: receiptsRoot, - LogsBloom: logsBloom, - PrevRandao: prevRandao, - BlockNumber: blockNumber, - GasLimit: gasLimit, - GasUsed: gasUsed, - Timestamp: timestamp, - ExtraData: extraData, - BaseFeePerGas: baseFeePerGas, - BlockHash: blockHash, - TransactionsRoot: transactionsRoot, - } - v2Block.Signature = signature - - alphaBlock, err := BlindedBellatrixToV1Alpha1SignedBlock(v2Block) - require.NoError(t, err) - alphaRoot, err := alphaBlock.HashTreeRoot() - require.NoError(t, err) - v2Root, err := v2Block.HashTreeRoot() - require.NoError(t, err) - assert.DeepEqual(t, v2Root, alphaRoot) -} - func Test_V1Alpha1BeaconBlockBellatrixToV2(t *testing.T) { alphaBlock := util.HydrateBeaconBlockBellatrix(ðpbalpha.BeaconBlockBellatrix{}) alphaBlock.Slot = slot diff --git a/proto/migration/v2_to_v1alpha1.go b/proto/migration/v2_to_v1alpha1.go new file mode 100644 index 000000000000..01e297c651a6 --- /dev/null +++ b/proto/migration/v2_to_v1alpha1.go @@ -0,0 +1,176 @@ +package migration + +import ( + "github.com/pkg/errors" + "github.com/prysmaticlabs/prysm/v4/encoding/bytesutil" + ethpbv2 "github.com/prysmaticlabs/prysm/v4/proto/eth/v2" + ethpbalpha "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1" + "google.golang.org/protobuf/proto" +) + +// AltairToV1Alpha1SignedBlock converts a v2 SignedBeaconBlockAltair proto to a v1alpha1 proto. +func AltairToV1Alpha1SignedBlock(altairBlk *ethpbv2.SignedBeaconBlockAltair) (*ethpbalpha.SignedBeaconBlockAltair, error) { + marshaledBlk, err := proto.Marshal(altairBlk) + if err != nil { + return nil, errors.Wrap(err, "could not marshal block") + } + v1alpha1Block := ðpbalpha.SignedBeaconBlockAltair{} + if err := proto.Unmarshal(marshaledBlk, v1alpha1Block); err != nil { + return nil, errors.Wrap(err, "could not unmarshal block") + } + return v1alpha1Block, nil +} + +// BellatrixToV1Alpha1SignedBlock converts a v2 SignedBeaconBlockBellatrix proto to a v1alpha1 proto. +func BellatrixToV1Alpha1SignedBlock(bellatrixBlk *ethpbv2.SignedBeaconBlockBellatrix) (*ethpbalpha.SignedBeaconBlockBellatrix, error) { + marshaledBlk, err := proto.Marshal(bellatrixBlk) + if err != nil { + return nil, errors.Wrap(err, "could not marshal block") + } + v1alpha1Block := ðpbalpha.SignedBeaconBlockBellatrix{} + if err := proto.Unmarshal(marshaledBlk, v1alpha1Block); err != nil { + return nil, errors.Wrap(err, "could not unmarshal block") + } + return v1alpha1Block, nil +} + +// CapellaToV1Alpha1SignedBlock converts a v2 SignedBeaconBlockCapella proto to a v1alpha1 proto. +func CapellaToV1Alpha1SignedBlock(capellaBlk *ethpbv2.SignedBeaconBlockCapella) (*ethpbalpha.SignedBeaconBlockCapella, error) { + marshaledBlk, err := proto.Marshal(capellaBlk) + if err != nil { + return nil, errors.Wrap(err, "could not marshal block") + } + v1alpha1Block := ðpbalpha.SignedBeaconBlockCapella{} + if err := proto.Unmarshal(marshaledBlk, v1alpha1Block); err != nil { + return nil, errors.Wrap(err, "could not unmarshal block") + } + return v1alpha1Block, nil +} + +// DenebToV1Alpha1SignedBlock converts a v2 SignedBeaconBlockDeneb proto to a v1alpha1 proto. +func DenebToV1Alpha1SignedBlock(denebBlk *ethpbv2.SignedBeaconBlockDeneb) (*ethpbalpha.SignedBeaconBlockDeneb, error) { + marshaledBlk, err := proto.Marshal(denebBlk) + if err != nil { + return nil, errors.Wrap(err, "could not marshal block") + } + v1alpha1Block := ðpbalpha.SignedBeaconBlockDeneb{} + if err := proto.Unmarshal(marshaledBlk, v1alpha1Block); err != nil { + return nil, errors.Wrap(err, "could not unmarshal block") + } + return v1alpha1Block, nil +} + +// V2BeaconBlockDenebToV1Alpha1 converts a v2 Deneb beacon block to a v1alpha1 +// Deneb block. +func V2BeaconBlockDenebToV1Alpha1(v2block *ethpbv2.BeaconBlockDeneb) (*ethpbalpha.BeaconBlockDeneb, error) { + marshaledBlk, err := proto.Marshal(v2block) + if err != nil { + return nil, errors.Wrap(err, "could not marshal block") + } + v1alpha1block := ðpbalpha.BeaconBlockDeneb{} + if err := proto.Unmarshal(marshaledBlk, v1alpha1block); err != nil { + return nil, errors.Wrap(err, "could not unmarshal block") + } + return v1alpha1block, nil +} + +// BlindedBellatrixToV1Alpha1SignedBlock converts a v2 SignedBlindedBeaconBlockBellatrix proto to a v1alpha1 proto. +func BlindedBellatrixToV1Alpha1SignedBlock(bellatrixBlk *ethpbv2.SignedBlindedBeaconBlockBellatrix) (*ethpbalpha.SignedBlindedBeaconBlockBellatrix, error) { + marshaledBlk, err := proto.Marshal(bellatrixBlk) + if err != nil { + return nil, errors.Wrap(err, "could not marshal block") + } + v1alpha1Block := ðpbalpha.SignedBlindedBeaconBlockBellatrix{} + if err := proto.Unmarshal(marshaledBlk, v1alpha1Block); err != nil { + return nil, errors.Wrap(err, "could not unmarshal block") + } + return v1alpha1Block, nil +} + +// BlindedCapellaToV1Alpha1SignedBlock converts a v2 SignedBlindedBeaconBlockCapella proto to a v1alpha1 proto. +func BlindedCapellaToV1Alpha1SignedBlock(capellaBlk *ethpbv2.SignedBlindedBeaconBlockCapella) (*ethpbalpha.SignedBlindedBeaconBlockCapella, error) { + marshaledBlk, err := proto.Marshal(capellaBlk) + if err != nil { + return nil, errors.Wrap(err, "could not marshal block") + } + v1alpha1Block := ðpbalpha.SignedBlindedBeaconBlockCapella{} + if err := proto.Unmarshal(marshaledBlk, v1alpha1Block); err != nil { + return nil, errors.Wrap(err, "could not unmarshal block") + } + return v1alpha1Block, nil +} + +// BlindedDenebToV1Alpha1SignedBlock converts a v2 SignedBlindedBeaconBlockDeneb proto to a v1alpha1 proto. +func BlindedDenebToV1Alpha1SignedBlock(denebBlk *ethpbv2.SignedBlindedBeaconBlockDeneb) (*ethpbalpha.SignedBlindedBeaconBlockDeneb, error) { + marshaledBlk, err := proto.Marshal(denebBlk) + if err != nil { + return nil, errors.Wrap(err, "could not marshal block") + } + v1alpha1Block := ðpbalpha.SignedBlindedBeaconBlockDeneb{} + if err := proto.Unmarshal(marshaledBlk, v1alpha1Block); err != nil { + return nil, errors.Wrap(err, "could not unmarshal block") + } + return v1alpha1Block, nil +} + +// SignedBlindedBlobsToV1Alpha1SignedBlindedBlobs converts an array of v2 SignedBlindedBlobSidecar objects to its v1alpha1 equivalent. +func SignedBlindedBlobsToV1Alpha1SignedBlindedBlobs(sidecars []*ethpbv2.SignedBlindedBlobSidecar) []*ethpbalpha.SignedBlindedBlobSidecar { + result := make([]*ethpbalpha.SignedBlindedBlobSidecar, len(sidecars)) + for i, sc := range sidecars { + result[i] = ðpbalpha.SignedBlindedBlobSidecar{ + Message: ðpbalpha.BlindedBlobSidecar{ + BlockRoot: bytesutil.SafeCopyBytes(sc.Message.BlockRoot), + Index: sc.Message.Index, + Slot: sc.Message.Slot, + BlockParentRoot: bytesutil.SafeCopyBytes(sc.Message.BlockParentRoot), + ProposerIndex: sc.Message.ProposerIndex, + BlobRoot: bytesutil.SafeCopyBytes(sc.Message.BlobRoot), + KzgCommitment: bytesutil.SafeCopyBytes(sc.Message.KzgCommitment), + KzgProof: bytesutil.SafeCopyBytes(sc.Message.KzgProof), + }, + Signature: bytesutil.SafeCopyBytes(sc.Signature), + } + } + return result +} + +// SignedBlobsToV1Alpha1SignedBlobs converts an array of v2 SignedBlobSidecar objects to its v1alpha1 equivalent. +func SignedBlobsToV1Alpha1SignedBlobs(sidecars []*ethpbv2.SignedBlobSidecar) []*ethpbalpha.SignedBlobSidecar { + result := make([]*ethpbalpha.SignedBlobSidecar, len(sidecars)) + for i, sc := range sidecars { + result[i] = ðpbalpha.SignedBlobSidecar{ + Message: ðpbalpha.BlobSidecar{ + BlockRoot: bytesutil.SafeCopyBytes(sc.Message.BlockRoot), + Index: sc.Message.Index, + Slot: sc.Message.Slot, + BlockParentRoot: bytesutil.SafeCopyBytes(sc.Message.BlockParentRoot), + ProposerIndex: sc.Message.ProposerIndex, + Blob: bytesutil.SafeCopyBytes(sc.Message.Blob), + KzgCommitment: bytesutil.SafeCopyBytes(sc.Message.KzgCommitment), + KzgProof: bytesutil.SafeCopyBytes(sc.Message.KzgProof), + }, + Signature: bytesutil.SafeCopyBytes(sc.Signature), + } + } + return result +} + +// DenebBlockContentsToV1Alpha1 converts signed deneb block contents to signed beacon block and blobs deneb +func DenebBlockContentsToV1Alpha1(blockcontents *ethpbv2.SignedBeaconBlockContentsDeneb) (*ethpbalpha.SignedBeaconBlockAndBlobsDeneb, error) { + block, err := DenebToV1Alpha1SignedBlock(blockcontents.SignedBlock) + if err != nil { + return nil, errors.Wrap(err, "could not convert block") + } + blobs := SignedBlobsToV1Alpha1SignedBlobs(blockcontents.SignedBlobSidecars) + return ðpbalpha.SignedBeaconBlockAndBlobsDeneb{Block: block, Blobs: blobs}, nil +} + +// BlindedDenebBlockContentsToV1Alpha1 converts signed blinded deneb block contents to signed blinded beacon block and blobs deneb +func BlindedDenebBlockContentsToV1Alpha1(blockcontents *ethpbv2.SignedBlindedBeaconBlockContentsDeneb) (*ethpbalpha.SignedBlindedBeaconBlockAndBlobsDeneb, error) { + block, err := BlindedDenebToV1Alpha1SignedBlock(blockcontents.SignedBlindedBlock) + if err != nil { + return nil, errors.Wrap(err, "could not convert block") + } + blobs := SignedBlindedBlobsToV1Alpha1SignedBlindedBlobs(blockcontents.SignedBlindedBlobSidecars) + return ðpbalpha.SignedBlindedBeaconBlockAndBlobsDeneb{Block: block, Blobs: blobs}, nil +} diff --git a/proto/migration/v2_to_v1alpha1_test.go b/proto/migration/v2_to_v1alpha1_test.go new file mode 100644 index 000000000000..82c556080bed --- /dev/null +++ b/proto/migration/v2_to_v1alpha1_test.go @@ -0,0 +1,132 @@ +package migration + +import ( + "testing" + + "github.com/prysmaticlabs/go-bitfield" + enginev1 "github.com/prysmaticlabs/prysm/v4/proto/engine/v1" + ethpbv1 "github.com/prysmaticlabs/prysm/v4/proto/eth/v1" + ethpbv2 "github.com/prysmaticlabs/prysm/v4/proto/eth/v2" + "github.com/prysmaticlabs/prysm/v4/testing/assert" + "github.com/prysmaticlabs/prysm/v4/testing/require" + "github.com/prysmaticlabs/prysm/v4/testing/util" +) + +func Test_AltairToV1Alpha1SignedBlock(t *testing.T) { + v2Block := util.HydrateV2AltairSignedBeaconBlock(ðpbv2.SignedBeaconBlockAltair{}) + v2Block.Message.Slot = slot + v2Block.Message.ProposerIndex = validatorIndex + v2Block.Message.ParentRoot = parentRoot + v2Block.Message.StateRoot = stateRoot + v2Block.Message.Body.RandaoReveal = randaoReveal + v2Block.Message.Body.Eth1Data = ðpbv1.Eth1Data{ + DepositRoot: depositRoot, + DepositCount: depositCount, + BlockHash: blockHash, + } + syncCommitteeBits := bitfield.NewBitvector512() + syncCommitteeBits.SetBitAt(100, true) + v2Block.Message.Body.SyncAggregate = ðpbv1.SyncAggregate{ + SyncCommitteeBits: syncCommitteeBits, + SyncCommitteeSignature: signature, + } + v2Block.Signature = signature + + alphaBlock, err := AltairToV1Alpha1SignedBlock(v2Block) + require.NoError(t, err) + alphaRoot, err := alphaBlock.HashTreeRoot() + require.NoError(t, err) + v2Root, err := v2Block.HashTreeRoot() + require.NoError(t, err) + assert.DeepEqual(t, v2Root, alphaRoot) +} + +func Test_BellatrixToV1Alpha1SignedBlock(t *testing.T) { + v2Block := util.HydrateV2BellatrixSignedBeaconBlock(ðpbv2.SignedBeaconBlockBellatrix{}) + v2Block.Message.Slot = slot + v2Block.Message.ProposerIndex = validatorIndex + v2Block.Message.ParentRoot = parentRoot + v2Block.Message.StateRoot = stateRoot + v2Block.Message.Body.RandaoReveal = randaoReveal + v2Block.Message.Body.Eth1Data = ðpbv1.Eth1Data{ + DepositRoot: depositRoot, + DepositCount: depositCount, + BlockHash: blockHash, + } + syncCommitteeBits := bitfield.NewBitvector512() + syncCommitteeBits.SetBitAt(100, true) + v2Block.Message.Body.SyncAggregate = ðpbv1.SyncAggregate{ + SyncCommitteeBits: syncCommitteeBits, + SyncCommitteeSignature: signature, + } + v2Block.Message.Body.ExecutionPayload = &enginev1.ExecutionPayload{ + ParentHash: parentHash, + FeeRecipient: feeRecipient, + StateRoot: stateRoot, + ReceiptsRoot: receiptsRoot, + LogsBloom: logsBloom, + PrevRandao: prevRandao, + BlockNumber: blockNumber, + GasLimit: gasLimit, + GasUsed: gasUsed, + Timestamp: timestamp, + ExtraData: extraData, + BaseFeePerGas: baseFeePerGas, + BlockHash: blockHash, + Transactions: [][]byte{[]byte("transaction1"), []byte("transaction2")}, + } + v2Block.Signature = signature + + alphaBlock, err := BellatrixToV1Alpha1SignedBlock(v2Block) + require.NoError(t, err) + alphaRoot, err := alphaBlock.HashTreeRoot() + require.NoError(t, err) + v2Root, err := v2Block.HashTreeRoot() + require.NoError(t, err) + assert.DeepEqual(t, v2Root, alphaRoot) +} + +func Test_BlindedBellatrixToV1Alpha1SignedBlock(t *testing.T) { + v2Block := util.HydrateV2SignedBlindedBeaconBlockBellatrix(ðpbv2.SignedBlindedBeaconBlockBellatrix{}) + v2Block.Message.Slot = slot + v2Block.Message.ProposerIndex = validatorIndex + v2Block.Message.ParentRoot = parentRoot + v2Block.Message.StateRoot = stateRoot + v2Block.Message.Body.RandaoReveal = randaoReveal + v2Block.Message.Body.Eth1Data = ðpbv1.Eth1Data{ + DepositRoot: depositRoot, + DepositCount: depositCount, + BlockHash: blockHash, + } + syncCommitteeBits := bitfield.NewBitvector512() + syncCommitteeBits.SetBitAt(100, true) + v2Block.Message.Body.SyncAggregate = ðpbv1.SyncAggregate{ + SyncCommitteeBits: syncCommitteeBits, + SyncCommitteeSignature: signature, + } + v2Block.Message.Body.ExecutionPayloadHeader = &enginev1.ExecutionPayloadHeader{ + ParentHash: parentHash, + FeeRecipient: feeRecipient, + StateRoot: stateRoot, + ReceiptsRoot: receiptsRoot, + LogsBloom: logsBloom, + PrevRandao: prevRandao, + BlockNumber: blockNumber, + GasLimit: gasLimit, + GasUsed: gasUsed, + Timestamp: timestamp, + ExtraData: extraData, + BaseFeePerGas: baseFeePerGas, + BlockHash: blockHash, + TransactionsRoot: transactionsRoot, + } + v2Block.Signature = signature + + alphaBlock, err := BlindedBellatrixToV1Alpha1SignedBlock(v2Block) + require.NoError(t, err) + alphaRoot, err := alphaBlock.HashTreeRoot() + require.NoError(t, err) + v2Root, err := v2Block.HashTreeRoot() + require.NoError(t, err) + assert.DeepEqual(t, v2Root, alphaRoot) +}