From 47fe2d33555d4b341f38d444b91b474fb56778cb Mon Sep 17 00:00:00 2001 From: Inspector-Butters Date: Tue, 8 Oct 2024 16:39:22 +0200 Subject: [PATCH 01/35] change updatebyrange --- beacon-chain/rpc/eth/light-client/handlers.go | 112 +++--------------- 1 file changed, 15 insertions(+), 97 deletions(-) diff --git a/beacon-chain/rpc/eth/light-client/handlers.go b/beacon-chain/rpc/eth/light-client/handlers.go index 245d703eaafd..4fcf91eb0189 100644 --- a/beacon-chain/rpc/eth/light-client/handlers.go +++ b/beacon-chain/rpc/eth/light-client/handlers.go @@ -11,10 +11,8 @@ import ( "github.com/prysmaticlabs/prysm/v5/api" "github.com/prysmaticlabs/prysm/v5/api/server/structs" "github.com/prysmaticlabs/prysm/v5/beacon-chain/rpc/eth/shared" - "github.com/prysmaticlabs/prysm/v5/beacon-chain/state" "github.com/prysmaticlabs/prysm/v5/config/params" "github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces" - types "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" "github.com/prysmaticlabs/prysm/v5/monitoring/tracing/trace" "github.com/prysmaticlabs/prysm/v5/network/httputil" "github.com/prysmaticlabs/prysm/v5/runtime/version" @@ -117,108 +115,28 @@ func (s *Server) GetLightClientUpdatesByRange(w http.ResponseWriter, req *http.R endPeriod = maxSlot / slotsPerPeriod } - // Populate updates - var updates []*structs.LightClientUpdateResponse - for period := startPeriod; period <= endPeriod; period++ { - // Get the last known state of the period, - // 1. We wish the block has a parent in the same period if possible - // 2. We wish the block has a state in the same period - lastSlotInPeriod := period*slotsPerPeriod + slotsPerPeriod - 1 - if lastSlotInPeriod > maxSlot { - lastSlotInPeriod = maxSlot - } - firstSlotInPeriod := period * slotsPerPeriod - - // Let's not use the first slot in the period, otherwise the attested header will be in previous period - firstSlotInPeriod++ - - var state state.BeaconState - var block interfaces.ReadOnlySignedBeaconBlock - for slot := lastSlotInPeriod; slot >= firstSlotInPeriod; slot-- { - state, err = s.Stater.StateBySlot(ctx, types.Slot(slot)) - if err != nil { - continue - } - - // Get the block - latestBlockHeader := state.LatestBlockHeader() - latestStateRoot, err := state.HashTreeRoot(ctx) - if err != nil { - continue - } - latestBlockHeader.StateRoot = latestStateRoot[:] - blockRoot, err := latestBlockHeader.HashTreeRoot() - if err != nil { - continue - } - - block, err = s.Blocker.Block(ctx, blockRoot[:]) - if err != nil || block == nil { - continue - } - - syncAggregate, err := block.Block().Body().SyncAggregate() - if err != nil || syncAggregate == nil { - continue - } - - if syncAggregate.SyncCommitteeBits.Count()*3 < config.SyncCommitteeSize*2 { - // Not enough votes - continue - } + // get updates + updatesMap, err := s.BeaconDB.LightClientUpdates(ctx, startPeriod, endPeriod) + if err != nil { + httputil.HandleError(w, "could not get light client updates: "+err.Error(), http.StatusInternalServerError) + return + } + updates := make([]*structs.LightClientUpdateResponse, len(updatesMap)) + for i, j := startPeriod, 0; i <= endPeriod; i, j = i+1, j+1 { + update, ok := updatesMap[i] + if !ok { + // Only return the first contiguous range of updates break } - if block == nil { - // No valid block found for the period - continue - } - - // Get attested state - attestedRoot := block.Block().ParentRoot() - attestedBlock, err := s.Blocker.Block(ctx, attestedRoot[:]) - if err != nil || attestedBlock == nil { - continue - } - - attestedSlot := attestedBlock.Block().Slot() - attestedState, err := s.Stater.StateBySlot(ctx, attestedSlot) + updateResponse, err := structs.LightClientUpdateResponseFromConsensus(update) if err != nil { - continue - } - - // Get finalized block - var finalizedBlock interfaces.ReadOnlySignedBeaconBlock - finalizedCheckPoint := attestedState.FinalizedCheckpoint() - if finalizedCheckPoint != nil { - finalizedRoot := bytesutil.ToBytes32(finalizedCheckPoint.Root) - finalizedBlock, err = s.Blocker.Block(ctx, finalizedRoot[:]) - if err != nil { - finalizedBlock = nil - } + httputil.HandleError(w, "could not convert light client update: "+err.Error(), http.StatusInternalServerError) + return } - update, err := newLightClientUpdateFromBeaconState( - ctx, - state, - block, - attestedState, - attestedBlock, - finalizedBlock, - ) - - if err == nil { - updates = append(updates, &structs.LightClientUpdateResponse{ - Version: version.String(attestedState.Version()), - Data: update, - }) - } - } - - if len(updates) == 0 { - httputil.HandleError(w, "no updates found", http.StatusNotFound) - return + updates[j] = updateResponse } httputil.WriteJson(w, updates) From b446e03693917b9d6c0d36a64b3be9dab78359e2 Mon Sep 17 00:00:00 2001 From: Inspector-Butters Date: Tue, 8 Oct 2024 16:40:45 +0200 Subject: [PATCH 02/35] lcupdateresponse from consensus --- api/server/structs/conversions_lightclient.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/api/server/structs/conversions_lightclient.go b/api/server/structs/conversions_lightclient.go index 50e6281ef9b9..662266f01172 100644 --- a/api/server/structs/conversions_lightclient.go +++ b/api/server/structs/conversions_lightclient.go @@ -10,8 +10,21 @@ import ( v1 "github.com/prysmaticlabs/prysm/v5/proto/eth/v1" v2 "github.com/prysmaticlabs/prysm/v5/proto/eth/v2" "github.com/prysmaticlabs/prysm/v5/proto/migration" + "github.com/prysmaticlabs/prysm/v5/runtime/version" ) +func LightClientUpdateResponseFromConsensus(update *v2.LightClientUpdateWithVersion) (*LightClientUpdateResponse, error) { + data, err := LightClientUpdateFromConsensus(update.Data) + if err != nil { + return nil, err + } + + return &LightClientUpdateResponse{ + Version: version.String(int(update.Version)), + Data: data, + }, nil +} + func LightClientUpdateFromConsensus(update *v2.LightClientUpdate) (*LightClientUpdate, error) { attestedHeader, err := lightClientHeaderContainerToJSON(update.AttestedHeader) if err != nil { From 5689d45ae1aba24d14b7d31103369c32bcff0c93 Mon Sep 17 00:00:00 2001 From: Inspector-Butters Date: Thu, 10 Oct 2024 12:40:58 +0200 Subject: [PATCH 03/35] range altair test --- api/server/structs/BUILD.bazel | 1 + beacon-chain/rpc/eth/light-client/BUILD.bazel | 1 - .../rpc/eth/light-client/handlers_test.go | 1588 +++++++++-------- 3 files changed, 843 insertions(+), 747 deletions(-) diff --git a/api/server/structs/BUILD.bazel b/api/server/structs/BUILD.bazel index c194d502ee02..d6532e7bcdee 100644 --- a/api/server/structs/BUILD.bazel +++ b/api/server/structs/BUILD.bazel @@ -39,6 +39,7 @@ go_library( "//proto/eth/v2:go_default_library", "//proto/migration:go_default_library", "//proto/prysm/v1alpha1:go_default_library", + "//runtime/version:go_default_library", "@com_github_ethereum_go_ethereum//common:go_default_library", "@com_github_ethereum_go_ethereum//common/hexutil:go_default_library", "@com_github_pkg_errors//:go_default_library", diff --git a/beacon-chain/rpc/eth/light-client/BUILD.bazel b/beacon-chain/rpc/eth/light-client/BUILD.bazel index 85b46a07ecc4..d21b3b2ebc03 100644 --- a/beacon-chain/rpc/eth/light-client/BUILD.bazel +++ b/beacon-chain/rpc/eth/light-client/BUILD.bazel @@ -21,7 +21,6 @@ go_library( "//config/fieldparams:go_default_library", "//config/params:go_default_library", "//consensus-types/interfaces:go_default_library", - "//consensus-types/primitives:go_default_library", "//monitoring/tracing/trace:go_default_library", "//network/httputil:go_default_library", "//proto/eth/v2:go_default_library", diff --git a/beacon-chain/rpc/eth/light-client/handlers_test.go b/beacon-chain/rpc/eth/light-client/handlers_test.go index 342ea679ee3c..b32e923c8f68 100644 --- a/beacon-chain/rpc/eth/light-client/handlers_test.go +++ b/beacon-chain/rpc/eth/light-client/handlers_test.go @@ -14,13 +14,18 @@ import ( "github.com/prysmaticlabs/prysm/v5/api/server/structs" mock "github.com/prysmaticlabs/prysm/v5/beacon-chain/blockchain/testing" "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/helpers" + "github.com/prysmaticlabs/prysm/v5/beacon-chain/db/kv" "github.com/prysmaticlabs/prysm/v5/beacon-chain/rpc/testutil" "github.com/prysmaticlabs/prysm/v5/beacon-chain/state" "github.com/prysmaticlabs/prysm/v5/config/params" "github.com/prysmaticlabs/prysm/v5/consensus-types/blocks" "github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces" "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" + enginev1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1" + ethpbv1 "github.com/prysmaticlabs/prysm/v5/proto/eth/v1" + ethpbv2 "github.com/prysmaticlabs/prysm/v5/proto/eth/v2" ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" + "github.com/prysmaticlabs/prysm/v5/runtime/version" "github.com/prysmaticlabs/prysm/v5/testing/require" "github.com/prysmaticlabs/prysm/v5/testing/util" ) @@ -291,536 +296,42 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeAltair(t *testing.T) { root, err := block.Block.HashTreeRoot() require.NoError(t, err) - mockBlocker := &testutil.MockBlocker{ - RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ - parentRoot: signedParent, - root: signedBlock, - }, - SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ - slot.Sub(1): signedParent, - slot: signedBlock, - }, - } - mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st} - s := &Server{ - Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ - slot.Sub(1): attestedState, - slot: st, - }}, - Blocker: mockBlocker, - HeadFetcher: mockChainService, - } - startPeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - url := fmt.Sprintf("http://foo.com/?count=1&start_period=%d", startPeriod) - request := httptest.NewRequest("GET", url, nil) - writer := httptest.NewRecorder() - writer.Body = &bytes.Buffer{} - - s.GetLightClientUpdatesByRange(writer, request) - - require.Equal(t, http.StatusOK, writer.Code) - var resp structs.LightClientUpdatesByRangeResponse - err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) - require.NoError(t, err) - var respHeader structs.LightClientHeader - err = json.Unmarshal(resp.Updates[0].Data.AttestedHeader, &respHeader) - require.NoError(t, err) - require.Equal(t, 1, len(resp.Updates)) - require.Equal(t, "altair", resp.Updates[0].Version) - require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot) - require.NotNil(t, resp) -} - -func TestLightClientHandler_GetLightClientUpdatesByRangeCapella(t *testing.T) { - helpers.ClearCache() - ctx := context.Background() - config := params.BeaconConfig() - slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) - - attestedState, err := util.NewBeaconStateCapella() - require.NoError(t, err) - err = attestedState.SetSlot(slot.Sub(1)) - require.NoError(t, err) - - parent := util.NewBeaconBlockCapella() - parent.Block.Slot = slot.Sub(1) - - signedParent, err := blocks.NewSignedBeaconBlock(parent) - require.NoError(t, err) - - parentHeader, err := signedParent.Header() - require.NoError(t, err) - attestedHeader := parentHeader.Header - - err = attestedState.SetLatestBlockHeader(attestedHeader) - require.NoError(t, err) - attestedStateRoot, err := attestedState.HashTreeRoot(ctx) - require.NoError(t, err) - - // get a new signed block so the root is updated with the new state root - parent.Block.StateRoot = attestedStateRoot[:] - signedParent, err = blocks.NewSignedBeaconBlock(parent) - require.NoError(t, err) - - st, err := util.NewBeaconStateCapella() - require.NoError(t, err) - err = st.SetSlot(slot) - require.NoError(t, err) - - parentRoot, err := signedParent.Block().HashTreeRoot() - require.NoError(t, err) - - block := util.NewBeaconBlockCapella() - block.Block.Slot = slot - block.Block.ParentRoot = parentRoot[:] - - for i := uint64(0); i < config.SyncCommitteeSize; i++ { - block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) - } - - signedBlock, err := blocks.NewSignedBeaconBlock(block) - require.NoError(t, err) - - h, err := signedBlock.Header() - require.NoError(t, err) - - err = st.SetLatestBlockHeader(h.Header) - require.NoError(t, err) - stateRoot, err := st.HashTreeRoot(ctx) - require.NoError(t, err) - - // get a new signed block so the root is updated with the new state root - block.Block.StateRoot = stateRoot[:] - signedBlock, err = blocks.NewSignedBeaconBlock(block) - require.NoError(t, err) - - root, err := block.Block.HashTreeRoot() - require.NoError(t, err) - - mockBlocker := &testutil.MockBlocker{ - RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ - parentRoot: signedParent, - root: signedBlock, - }, - SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ - slot.Sub(1): signedParent, - slot: signedBlock, - }, - } - mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st} - s := &Server{ - Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ - slot.Sub(1): attestedState, - slot: st, - }}, - Blocker: mockBlocker, - HeadFetcher: mockChainService, - } - startPeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - url := fmt.Sprintf("http://foo.com/?count=1&start_period=%d", startPeriod) - request := httptest.NewRequest("GET", url, nil) - writer := httptest.NewRecorder() - writer.Body = &bytes.Buffer{} - - s.GetLightClientUpdatesByRange(writer, request) - - require.Equal(t, http.StatusOK, writer.Code) - var resp structs.LightClientUpdatesByRangeResponse - err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) - require.NoError(t, err) - var respHeader structs.LightClientHeaderCapella - err = json.Unmarshal(resp.Updates[0].Data.AttestedHeader, &respHeader) - require.NoError(t, err) - require.Equal(t, 1, len(resp.Updates)) - require.Equal(t, "capella", resp.Updates[0].Version) - require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot) - require.NotNil(t, resp) -} - -func TestLightClientHandler_GetLightClientUpdatesByRangeDeneb(t *testing.T) { - helpers.ClearCache() - ctx := context.Background() - config := params.BeaconConfig() - slot := primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) - - attestedState, err := util.NewBeaconStateDeneb() - require.NoError(t, err) - err = attestedState.SetSlot(slot.Sub(1)) - require.NoError(t, err) - - parent := util.NewBeaconBlockDeneb() - parent.Block.Slot = slot.Sub(1) - - signedParent, err := blocks.NewSignedBeaconBlock(parent) - require.NoError(t, err) - - parentHeader, err := signedParent.Header() - require.NoError(t, err) - attestedHeader := parentHeader.Header - - err = attestedState.SetLatestBlockHeader(attestedHeader) - require.NoError(t, err) - attestedStateRoot, err := attestedState.HashTreeRoot(ctx) - require.NoError(t, err) - - // get a new signed block so the root is updated with the new state root - parent.Block.StateRoot = attestedStateRoot[:] - signedParent, err = blocks.NewSignedBeaconBlock(parent) - require.NoError(t, err) - - st, err := util.NewBeaconStateDeneb() - require.NoError(t, err) - err = st.SetSlot(slot) - require.NoError(t, err) - - parentRoot, err := signedParent.Block().HashTreeRoot() - require.NoError(t, err) - - block := util.NewBeaconBlockDeneb() - block.Block.Slot = slot - block.Block.ParentRoot = parentRoot[:] - - for i := uint64(0); i < config.SyncCommitteeSize; i++ { - block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) - } - - signedBlock, err := blocks.NewSignedBeaconBlock(block) - require.NoError(t, err) - - h, err := signedBlock.Header() - require.NoError(t, err) - - err = st.SetLatestBlockHeader(h.Header) - require.NoError(t, err) - stateRoot, err := st.HashTreeRoot(ctx) - require.NoError(t, err) - - // get a new signed block so the root is updated with the new state root - block.Block.StateRoot = stateRoot[:] - signedBlock, err = blocks.NewSignedBeaconBlock(block) - require.NoError(t, err) - - root, err := block.Block.HashTreeRoot() - require.NoError(t, err) - - mockBlocker := &testutil.MockBlocker{ - RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ - parentRoot: signedParent, - root: signedBlock, - }, - SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ - slot.Sub(1): signedParent, - slot: signedBlock, - }, - } - mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st} - s := &Server{ - Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ - slot.Sub(1): attestedState, - slot: st, - }}, - Blocker: mockBlocker, - HeadFetcher: mockChainService, - } - startPeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - url := fmt.Sprintf("http://foo.com/?count=1&start_period=%d", startPeriod) - request := httptest.NewRequest("GET", url, nil) - writer := httptest.NewRecorder() - writer.Body = &bytes.Buffer{} - - s.GetLightClientUpdatesByRange(writer, request) - - require.Equal(t, http.StatusOK, writer.Code) - var resp structs.LightClientUpdatesByRangeResponse - err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) - require.NoError(t, err) - var respHeader structs.LightClientHeaderDeneb - err = json.Unmarshal(resp.Updates[0].Data.AttestedHeader, &respHeader) - require.NoError(t, err) - require.Equal(t, 1, len(resp.Updates)) - require.Equal(t, "deneb", resp.Updates[0].Version) - require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot) - require.NotNil(t, resp) -} - -func TestLightClientHandler_GetLightClientUpdatesByRange_TooBigInputCountAltair(t *testing.T) { - helpers.ClearCache() - ctx := context.Background() - config := params.BeaconConfig() - slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) - - attestedState, err := util.NewBeaconStateAltair() - require.NoError(t, err) - err = attestedState.SetSlot(slot.Sub(1)) - require.NoError(t, err) - - parent := util.NewBeaconBlockAltair() - parent.Block.Slot = slot.Sub(1) - - signedParent, err := blocks.NewSignedBeaconBlock(parent) - require.NoError(t, err) - - parentHeader, err := signedParent.Header() - require.NoError(t, err) - attestedHeader := parentHeader.Header - - err = attestedState.SetLatestBlockHeader(attestedHeader) - require.NoError(t, err) - attestedStateRoot, err := attestedState.HashTreeRoot(ctx) - require.NoError(t, err) - - // get a new signed block so the root is updated with the new state root - parent.Block.StateRoot = attestedStateRoot[:] - signedParent, err = blocks.NewSignedBeaconBlock(parent) - require.NoError(t, err) - - st, err := util.NewBeaconStateAltair() - require.NoError(t, err) - err = st.SetSlot(slot) - require.NoError(t, err) - - parentRoot, err := signedParent.Block().HashTreeRoot() - require.NoError(t, err) - - block := util.NewBeaconBlockAltair() - block.Block.Slot = slot - block.Block.ParentRoot = parentRoot[:] - - for i := uint64(0); i < config.SyncCommitteeSize; i++ { - block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) - } - - signedBlock, err := blocks.NewSignedBeaconBlock(block) - require.NoError(t, err) - - h, err := signedBlock.Header() - require.NoError(t, err) - - err = st.SetLatestBlockHeader(h.Header) - require.NoError(t, err) - stateRoot, err := st.HashTreeRoot(ctx) - require.NoError(t, err) - - // get a new signed block so the root is updated with the new state root - block.Block.StateRoot = stateRoot[:] - signedBlock, err = blocks.NewSignedBeaconBlock(block) - require.NoError(t, err) - - root, err := block.Block.HashTreeRoot() - require.NoError(t, err) - - mockBlocker := &testutil.MockBlocker{ - RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ - parentRoot: signedParent, - root: signedBlock, - }, - SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ - slot.Sub(1): signedParent, - slot: signedBlock, - }, - } - mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st} - s := &Server{ - Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ - slot.Sub(1): attestedState, - slot: st, - }}, - Blocker: mockBlocker, - HeadFetcher: mockChainService, - } - startPeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - count := 129 // config.MaxRequestLightClientUpdates is 128 - url := fmt.Sprintf("http://foo.com/?count=%d&start_period=%d", count, startPeriod) - request := httptest.NewRequest("GET", url, nil) - writer := httptest.NewRecorder() - writer.Body = &bytes.Buffer{} - - s.GetLightClientUpdatesByRange(writer, request) - - require.Equal(t, http.StatusOK, writer.Code) - var resp structs.LightClientUpdatesByRangeResponse - err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) - require.NoError(t, err) - var respHeader structs.LightClientHeader - err = json.Unmarshal(resp.Updates[0].Data.AttestedHeader, &respHeader) - require.NoError(t, err) - require.Equal(t, 1, len(resp.Updates)) // Even with big count input, the response is still the max available period, which is 1 in test case. - require.Equal(t, "altair", resp.Updates[0].Version) - require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot) - require.NotNil(t, resp) -} - -func TestLightClientHandler_GetLightClientUpdatesByRange_TooBigInputCountCapella(t *testing.T) { - helpers.ClearCache() - ctx := context.Background() - config := params.BeaconConfig() - slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) - - attestedState, err := util.NewBeaconStateCapella() - require.NoError(t, err) - err = attestedState.SetSlot(slot.Sub(1)) - require.NoError(t, err) - - parent := util.NewBeaconBlockCapella() - parent.Block.Slot = slot.Sub(1) - - signedParent, err := blocks.NewSignedBeaconBlock(parent) - require.NoError(t, err) - - parentHeader, err := signedParent.Header() - require.NoError(t, err) - attestedHeader := parentHeader.Header - - err = attestedState.SetLatestBlockHeader(attestedHeader) - require.NoError(t, err) - attestedStateRoot, err := attestedState.HashTreeRoot(ctx) - require.NoError(t, err) - - // get a new signed block so the root is updated with the new state root - parent.Block.StateRoot = attestedStateRoot[:] - signedParent, err = blocks.NewSignedBeaconBlock(parent) - require.NoError(t, err) - - st, err := util.NewBeaconStateCapella() - require.NoError(t, err) - err = st.SetSlot(slot) - require.NoError(t, err) - - parentRoot, err := signedParent.Block().HashTreeRoot() - require.NoError(t, err) - - block := util.NewBeaconBlockCapella() - block.Block.Slot = slot - block.Block.ParentRoot = parentRoot[:] - - for i := uint64(0); i < config.SyncCommitteeSize; i++ { - block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) - } - - signedBlock, err := blocks.NewSignedBeaconBlock(block) - require.NoError(t, err) - - h, err := signedBlock.Header() - require.NoError(t, err) - - err = st.SetLatestBlockHeader(h.Header) - require.NoError(t, err) - stateRoot, err := st.HashTreeRoot(ctx) - require.NoError(t, err) - - // get a new signed block so the root is updated with the new state root - block.Block.StateRoot = stateRoot[:] - signedBlock, err = blocks.NewSignedBeaconBlock(block) - require.NoError(t, err) - - root, err := block.Block.HashTreeRoot() - require.NoError(t, err) - - mockBlocker := &testutil.MockBlocker{ - RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ - parentRoot: signedParent, - root: signedBlock, - }, - SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ - slot.Sub(1): signedParent, - slot: signedBlock, - }, - } - mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st} - s := &Server{ - Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ - slot.Sub(1): attestedState, - slot: st, - }}, - Blocker: mockBlocker, - HeadFetcher: mockChainService, - } - startPeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - count := 129 // config.MaxRequestLightClientUpdates is 128 - url := fmt.Sprintf("http://foo.com/?count=%d&start_period=%d", count, startPeriod) - request := httptest.NewRequest("GET", url, nil) - writer := httptest.NewRecorder() - writer.Body = &bytes.Buffer{} - - s.GetLightClientUpdatesByRange(writer, request) - - require.Equal(t, http.StatusOK, writer.Code) - var resp structs.LightClientUpdatesByRangeResponse - err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) - require.NoError(t, err) - var respHeader structs.LightClientHeaderCapella - err = json.Unmarshal(resp.Updates[0].Data.AttestedHeader, &respHeader) - require.NoError(t, err) - require.Equal(t, 1, len(resp.Updates)) // Even with big count input, the response is still the max available period, which is 1 in test case. - require.Equal(t, "capella", resp.Updates[0].Version) - require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot) - require.NotNil(t, resp) -} - -func TestLightClientHandler_GetLightClientUpdatesByRange_TooBigInputCountDeneb(t *testing.T) { - helpers.ClearCache() - ctx := context.Background() - config := params.BeaconConfig() - slot := primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) - - attestedState, err := util.NewBeaconStateDeneb() - require.NoError(t, err) - err = attestedState.SetSlot(slot.Sub(1)) - require.NoError(t, err) - - parent := util.NewBeaconBlockDeneb() - parent.Block.Slot = slot.Sub(1) - - signedParent, err := blocks.NewSignedBeaconBlock(parent) - require.NoError(t, err) - - parentHeader, err := signedParent.Header() - require.NoError(t, err) - attestedHeader := parentHeader.Header - - err = attestedState.SetLatestBlockHeader(attestedHeader) - require.NoError(t, err) - attestedStateRoot, err := attestedState.HashTreeRoot(ctx) - require.NoError(t, err) + db := setupDB(t) - // get a new signed block so the root is updated with the new state root - parent.Block.StateRoot = attestedStateRoot[:] - signedParent, err = blocks.NewSignedBeaconBlock(parent) - require.NoError(t, err) - - st, err := util.NewBeaconStateDeneb() - require.NoError(t, err) - err = st.SetSlot(slot) - require.NoError(t, err) - - parentRoot, err := signedParent.Block().HashTreeRoot() - require.NoError(t, err) - - block := util.NewBeaconBlockDeneb() - block.Block.Slot = slot - block.Block.ParentRoot = parentRoot[:] + updatePeriod := uint64(slot.Sub(1).Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch))) - for i := uint64(0); i < config.SyncCommitteeSize; i++ { - block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) + update := ðpbv2.LightClientUpdate{ + AttestedHeader: ðpbv2.LightClientHeaderContainer{ + Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ + HeaderAltair: ðpbv2.LightClientHeader{ + Beacon: ðpbv1.BeaconBlockHeader{ + Slot: slot.Sub(1), + ProposerIndex: 1, + ParentRoot: []byte{1, 1, 1}, + StateRoot: []byte{1, 1, 1}, + BodyRoot: []byte{1, 1, 1}, + }, + }, + }, + }, + NextSyncCommittee: ðpbv2.SyncCommittee{ + Pubkeys: nil, + AggregatePubkey: nil, + }, + NextSyncCommitteeBranch: nil, + FinalizedHeader: nil, + FinalityBranch: nil, + SyncAggregate: ðpbv1.SyncAggregate{ + SyncCommitteeBits: []byte{1, 1, 1}, + SyncCommitteeSignature: []byte{1, 1, 1}, + }, + SignatureSlot: 7, } - signedBlock, err := blocks.NewSignedBeaconBlock(block) - require.NoError(t, err) - - h, err := signedBlock.Header() - require.NoError(t, err) - - err = st.SetLatestBlockHeader(h.Header) - require.NoError(t, err) - stateRoot, err := st.HashTreeRoot(ctx) - require.NoError(t, err) - - // get a new signed block so the root is updated with the new state root - block.Block.StateRoot = stateRoot[:] - signedBlock, err = blocks.NewSignedBeaconBlock(block) - require.NoError(t, err) - - root, err := block.Block.HashTreeRoot() + err = db.SaveLightClientUpdate(ctx, updatePeriod, ðpbv2.LightClientUpdateWithVersion{ + Version: version.Altair, + Data: update, + }) require.NoError(t, err) mockBlocker := &testutil.MockBlocker{ @@ -841,10 +352,10 @@ func TestLightClientHandler_GetLightClientUpdatesByRange_TooBigInputCountDeneb(t }}, Blocker: mockBlocker, HeadFetcher: mockChainService, + BeaconDB: db, } startPeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - count := 129 // config.MaxRequestLightClientUpdates is 128 - url := fmt.Sprintf("http://foo.com/?count=%d&start_period=%d", count, startPeriod) + url := fmt.Sprintf("http://foo.com/?count=1&start_period=%d", startPeriod) request := httptest.NewRequest("GET", url, nil) writer := httptest.NewRecorder() writer.Body = &bytes.Buffer{} @@ -855,28 +366,26 @@ func TestLightClientHandler_GetLightClientUpdatesByRange_TooBigInputCountDeneb(t var resp structs.LightClientUpdatesByRangeResponse err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) require.NoError(t, err) - var respHeader structs.LightClientHeaderDeneb - err = json.Unmarshal(resp.Updates[0].Data.AttestedHeader, &respHeader) + require.Equal(t, 1, len(resp.Updates)) require.NoError(t, err) - require.Equal(t, 1, len(resp.Updates)) // Even with big count input, the response is still the max available period, which is 1 in test case. - require.Equal(t, "deneb", resp.Updates[0].Version) - require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot) - require.NotNil(t, resp) + require.Equal(t, "altair", resp.Updates[0].Version) + updateJson, err := structs.LightClientUpdateFromConsensus(update) + require.NoError(t, err) + require.DeepEqual(t, updateJson, resp.Updates[0].Data) } -// TODO - check for not having any blocks from the min period, and startPeriod being too early -func TestLightClientHandler_GetLightClientUpdatesByRange_TooEarlyPeriodAltair(t *testing.T) { +func TestLightClientHandler_GetLightClientUpdatesByRangeCapella(t *testing.T) { helpers.ClearCache() ctx := context.Background() config := params.BeaconConfig() - slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) + slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) - attestedState, err := util.NewBeaconStateAltair() + attestedState, err := util.NewBeaconStateCapella() require.NoError(t, err) err = attestedState.SetSlot(slot.Sub(1)) require.NoError(t, err) - parent := util.NewBeaconBlockAltair() + parent := util.NewBeaconBlockCapella() parent.Block.Slot = slot.Sub(1) signedParent, err := blocks.NewSignedBeaconBlock(parent) @@ -896,7 +405,7 @@ func TestLightClientHandler_GetLightClientUpdatesByRange_TooEarlyPeriodAltair(t signedParent, err = blocks.NewSignedBeaconBlock(parent) require.NoError(t, err) - st, err := util.NewBeaconStateAltair() + st, err := util.NewBeaconStateCapella() require.NoError(t, err) err = st.SetSlot(slot) require.NoError(t, err) @@ -904,7 +413,7 @@ func TestLightClientHandler_GetLightClientUpdatesByRange_TooEarlyPeriodAltair(t parentRoot, err := signedParent.Block().HashTreeRoot() require.NoError(t, err) - block := util.NewBeaconBlockAltair() + block := util.NewBeaconBlockCapella() block.Block.Slot = slot block.Block.ParentRoot = parentRoot[:] @@ -931,113 +440,48 @@ func TestLightClientHandler_GetLightClientUpdatesByRange_TooEarlyPeriodAltair(t root, err := block.Block.HashTreeRoot() require.NoError(t, err) - mockBlocker := &testutil.MockBlocker{ - RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ - parentRoot: signedParent, - root: signedBlock, + update := ðpbv2.LightClientUpdate{ + AttestedHeader: ðpbv2.LightClientHeaderContainer{ + Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ + HeaderCapella: ðpbv2.LightClientHeaderCapella{ + Beacon: ðpbv1.BeaconBlockHeader{ + Slot: 1, + ProposerIndex: 1, + ParentRoot: []byte{1, 1, 1}, + StateRoot: []byte{1, 1, 1}, + BodyRoot: []byte{1, 1, 1}, + }, + Execution: &enginev1.ExecutionPayloadHeaderCapella{ + FeeRecipient: []byte{1, 2, 3}, + }, + ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, + }, + }, }, - SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ - slot.Sub(1): signedParent, - slot: signedBlock, + NextSyncCommittee: ðpbv2.SyncCommittee{ + Pubkeys: nil, + AggregatePubkey: nil, }, + NextSyncCommitteeBranch: nil, + FinalizedHeader: ðpbv2.LightClientHeaderContainer{ + Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ + HeaderCapella: ðpbv2.LightClientHeaderCapella{ + Beacon: ðpbv1.BeaconBlockHeader{ + Slot: 1, + ProposerIndex: 1, + ParentRoot: []byte{1, 1, 1}, + StateRoot: []byte{1, 1, 1}, + BodyRoot: []byte{1, 1, 1}, + }, + Execution: nil, + ExecutionBranch: nil, + }, + }, + }, + FinalityBranch: nil, + SyncAggregate: nil, + SignatureSlot: 7, } - mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st} - s := &Server{ - Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ - slot.Sub(1): attestedState, - slot: st, - }}, - Blocker: mockBlocker, - HeadFetcher: mockChainService, - } - startPeriod := 1 // very early period before Altair fork - count := 1 - url := fmt.Sprintf("http://foo.com/?count=%d&start_period=%d", count, startPeriod) - request := httptest.NewRequest("GET", url, nil) - writer := httptest.NewRecorder() - writer.Body = &bytes.Buffer{} - - s.GetLightClientUpdatesByRange(writer, request) - - require.Equal(t, http.StatusOK, writer.Code) - var resp structs.LightClientUpdatesByRangeResponse - err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) - require.NoError(t, err) - var respHeader structs.LightClientHeader - err = json.Unmarshal(resp.Updates[0].Data.AttestedHeader, &respHeader) - require.NoError(t, err) - require.Equal(t, 1, len(resp.Updates)) - require.Equal(t, "altair", resp.Updates[0].Version) - require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot) - require.NotNil(t, resp) -} - -// TODO - same as above -func TestLightClientHandler_GetLightClientUpdatesByRange_TooBigCountAltair(t *testing.T) { - helpers.ClearCache() - ctx := context.Background() - config := params.BeaconConfig() - slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) - - attestedState, err := util.NewBeaconStateAltair() - require.NoError(t, err) - err = attestedState.SetSlot(slot.Sub(1)) - require.NoError(t, err) - - parent := util.NewBeaconBlockAltair() - parent.Block.Slot = slot.Sub(1) - - signedParent, err := blocks.NewSignedBeaconBlock(parent) - require.NoError(t, err) - - parentHeader, err := signedParent.Header() - require.NoError(t, err) - attestedHeader := parentHeader.Header - - err = attestedState.SetLatestBlockHeader(attestedHeader) - require.NoError(t, err) - attestedStateRoot, err := attestedState.HashTreeRoot(ctx) - require.NoError(t, err) - - // get a new signed block so the root is updated with the new state root - parent.Block.StateRoot = attestedStateRoot[:] - signedParent, err = blocks.NewSignedBeaconBlock(parent) - require.NoError(t, err) - - st, err := util.NewBeaconStateAltair() - require.NoError(t, err) - err = st.SetSlot(slot) - require.NoError(t, err) - - parentRoot, err := signedParent.Block().HashTreeRoot() - require.NoError(t, err) - - block := util.NewBeaconBlockAltair() - block.Block.Slot = slot - block.Block.ParentRoot = parentRoot[:] - - for i := uint64(0); i < config.SyncCommitteeSize; i++ { - block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) - } - - signedBlock, err := blocks.NewSignedBeaconBlock(block) - require.NoError(t, err) - - h, err := signedBlock.Header() - require.NoError(t, err) - - err = st.SetLatestBlockHeader(h.Header) - require.NoError(t, err) - stateRoot, err := st.HashTreeRoot(ctx) - require.NoError(t, err) - - // get a new signed block so the root is updated with the new state root - block.Block.StateRoot = stateRoot[:] - signedBlock, err = blocks.NewSignedBeaconBlock(block) - require.NoError(t, err) - - root, err := block.Block.HashTreeRoot() - require.NoError(t, err) mockBlocker := &testutil.MockBlocker{ RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ @@ -1058,9 +502,8 @@ func TestLightClientHandler_GetLightClientUpdatesByRange_TooBigCountAltair(t *te Blocker: mockBlocker, HeadFetcher: mockChainService, } - startPeriod := 1 // very early period before Altair fork - count := 10 // This is big count as we only have one period in test case. - url := fmt.Sprintf("http://foo.com/?count=%d&start_period=%d", count, startPeriod) + startPeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) + url := fmt.Sprintf("http://foo.com/?count=1&start_period=%d", startPeriod) request := httptest.NewRequest("GET", url, nil) writer := httptest.NewRecorder() writer.Body = &bytes.Buffer{} @@ -1071,111 +514,754 @@ func TestLightClientHandler_GetLightClientUpdatesByRange_TooBigCountAltair(t *te var resp structs.LightClientUpdatesByRangeResponse err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) require.NoError(t, err) - var respHeader structs.LightClientHeader + var respHeader structs.LightClientHeaderCapella err = json.Unmarshal(resp.Updates[0].Data.AttestedHeader, &respHeader) require.NoError(t, err) require.Equal(t, 1, len(resp.Updates)) - require.Equal(t, "altair", resp.Updates[0].Version) + require.Equal(t, "capella", resp.Updates[0].Version) require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot) require.NotNil(t, resp) } -func TestLightClientHandler_GetLightClientUpdatesByRange_BeforeAltair(t *testing.T) { - helpers.ClearCache() - ctx := context.Background() - config := params.BeaconConfig() - slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Sub(1) - - attestedState, err := util.NewBeaconStateCapella() - require.NoError(t, err) - err = attestedState.SetSlot(slot.Sub(1)) - require.NoError(t, err) - - parent := util.NewBeaconBlockCapella() - parent.Block.Slot = slot.Sub(1) - - signedParent, err := blocks.NewSignedBeaconBlock(parent) - require.NoError(t, err) - - parentHeader, err := signedParent.Header() - require.NoError(t, err) - attestedHeader := parentHeader.Header - - err = attestedState.SetLatestBlockHeader(attestedHeader) - require.NoError(t, err) - attestedStateRoot, err := attestedState.HashTreeRoot(ctx) - require.NoError(t, err) - - // get a new signed block so the root is updated with the new state root - parent.Block.StateRoot = attestedStateRoot[:] - signedParent, err = blocks.NewSignedBeaconBlock(parent) - require.NoError(t, err) - - st, err := util.NewBeaconStateCapella() - require.NoError(t, err) - err = st.SetSlot(slot) - require.NoError(t, err) - - parentRoot, err := signedParent.Block().HashTreeRoot() - require.NoError(t, err) - - block := util.NewBeaconBlockCapella() - block.Block.Slot = slot - block.Block.ParentRoot = parentRoot[:] - - for i := uint64(0); i < config.SyncCommitteeSize; i++ { - block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) - } - - signedBlock, err := blocks.NewSignedBeaconBlock(block) - require.NoError(t, err) - - h, err := signedBlock.Header() - require.NoError(t, err) - - err = st.SetLatestBlockHeader(h.Header) - require.NoError(t, err) - stateRoot, err := st.HashTreeRoot(ctx) - require.NoError(t, err) - - // get a new signed block so the root is updated with the new state root - block.Block.StateRoot = stateRoot[:] - signedBlock, err = blocks.NewSignedBeaconBlock(block) - require.NoError(t, err) - - root, err := block.Block.HashTreeRoot() - require.NoError(t, err) - - mockBlocker := &testutil.MockBlocker{ - RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ - parentRoot: signedParent, - root: signedBlock, - }, - SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ - slot.Sub(1): signedParent, - slot: signedBlock, - }, - } - mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st} - s := &Server{ - Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ - slot.Sub(1): attestedState, - slot: st, - }}, - Blocker: mockBlocker, - HeadFetcher: mockChainService, - } - startPeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - count := 1 - url := fmt.Sprintf("http://foo.com/?count=%d&start_period=%d", count, startPeriod) - request := httptest.NewRequest("GET", url, nil) - writer := httptest.NewRecorder() - writer.Body = &bytes.Buffer{} - - s.GetLightClientUpdatesByRange(writer, request) - - require.Equal(t, http.StatusNotFound, writer.Code) -} +//func TestLightClientHandler_GetLightClientUpdatesByRangeDeneb(t *testing.T) { +// helpers.ClearCache() +// ctx := context.Background() +// config := params.BeaconConfig() +// slot := primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) +// +// attestedState, err := util.NewBeaconStateDeneb() +// require.NoError(t, err) +// err = attestedState.SetSlot(slot.Sub(1)) +// require.NoError(t, err) +// +// parent := util.NewBeaconBlockDeneb() +// parent.Block.Slot = slot.Sub(1) +// +// signedParent, err := blocks.NewSignedBeaconBlock(parent) +// require.NoError(t, err) +// +// parentHeader, err := signedParent.Header() +// require.NoError(t, err) +// attestedHeader := parentHeader.Header +// +// err = attestedState.SetLatestBlockHeader(attestedHeader) +// require.NoError(t, err) +// attestedStateRoot, err := attestedState.HashTreeRoot(ctx) +// require.NoError(t, err) +// +// // get a new signed block so the root is updated with the new state root +// parent.Block.StateRoot = attestedStateRoot[:] +// signedParent, err = blocks.NewSignedBeaconBlock(parent) +// require.NoError(t, err) +// +// st, err := util.NewBeaconStateDeneb() +// require.NoError(t, err) +// err = st.SetSlot(slot) +// require.NoError(t, err) +// +// parentRoot, err := signedParent.Block().HashTreeRoot() +// require.NoError(t, err) +// +// block := util.NewBeaconBlockDeneb() +// block.Block.Slot = slot +// block.Block.ParentRoot = parentRoot[:] +// +// for i := uint64(0); i < config.SyncCommitteeSize; i++ { +// block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) +// } +// +// signedBlock, err := blocks.NewSignedBeaconBlock(block) +// require.NoError(t, err) +// +// h, err := signedBlock.Header() +// require.NoError(t, err) +// +// err = st.SetLatestBlockHeader(h.Header) +// require.NoError(t, err) +// stateRoot, err := st.HashTreeRoot(ctx) +// require.NoError(t, err) +// +// // get a new signed block so the root is updated with the new state root +// block.Block.StateRoot = stateRoot[:] +// signedBlock, err = blocks.NewSignedBeaconBlock(block) +// require.NoError(t, err) +// +// root, err := block.Block.HashTreeRoot() +// require.NoError(t, err) +// +// mockBlocker := &testutil.MockBlocker{ +// RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ +// parentRoot: signedParent, +// root: signedBlock, +// }, +// SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ +// slot.Sub(1): signedParent, +// slot: signedBlock, +// }, +// } +// mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st} +// s := &Server{ +// Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ +// slot.Sub(1): attestedState, +// slot: st, +// }}, +// Blocker: mockBlocker, +// HeadFetcher: mockChainService, +// } +// startPeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) +// url := fmt.Sprintf("http://foo.com/?count=1&start_period=%d", startPeriod) +// request := httptest.NewRequest("GET", url, nil) +// writer := httptest.NewRecorder() +// writer.Body = &bytes.Buffer{} +// +// s.GetLightClientUpdatesByRange(writer, request) +// +// require.Equal(t, http.StatusOK, writer.Code) +// var resp structs.LightClientUpdatesByRangeResponse +// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) +// require.NoError(t, err) +// var respHeader structs.LightClientHeaderDeneb +// err = json.Unmarshal(resp.Updates[0].Data.AttestedHeader, &respHeader) +// require.NoError(t, err) +// require.Equal(t, 1, len(resp.Updates)) +// require.Equal(t, "deneb", resp.Updates[0].Version) +// require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot) +// require.NotNil(t, resp) +//} +// +//func TestLightClientHandler_GetLightClientUpdatesByRange_TooBigInputCountAltair(t *testing.T) { +// helpers.ClearCache() +// ctx := context.Background() +// config := params.BeaconConfig() +// slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) +// +// attestedState, err := util.NewBeaconStateAltair() +// require.NoError(t, err) +// err = attestedState.SetSlot(slot.Sub(1)) +// require.NoError(t, err) +// +// parent := util.NewBeaconBlockAltair() +// parent.Block.Slot = slot.Sub(1) +// +// signedParent, err := blocks.NewSignedBeaconBlock(parent) +// require.NoError(t, err) +// +// parentHeader, err := signedParent.Header() +// require.NoError(t, err) +// attestedHeader := parentHeader.Header +// +// err = attestedState.SetLatestBlockHeader(attestedHeader) +// require.NoError(t, err) +// attestedStateRoot, err := attestedState.HashTreeRoot(ctx) +// require.NoError(t, err) +// +// // get a new signed block so the root is updated with the new state root +// parent.Block.StateRoot = attestedStateRoot[:] +// signedParent, err = blocks.NewSignedBeaconBlock(parent) +// require.NoError(t, err) +// +// st, err := util.NewBeaconStateAltair() +// require.NoError(t, err) +// err = st.SetSlot(slot) +// require.NoError(t, err) +// +// parentRoot, err := signedParent.Block().HashTreeRoot() +// require.NoError(t, err) +// +// block := util.NewBeaconBlockAltair() +// block.Block.Slot = slot +// block.Block.ParentRoot = parentRoot[:] +// +// for i := uint64(0); i < config.SyncCommitteeSize; i++ { +// block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) +// } +// +// signedBlock, err := blocks.NewSignedBeaconBlock(block) +// require.NoError(t, err) +// +// h, err := signedBlock.Header() +// require.NoError(t, err) +// +// err = st.SetLatestBlockHeader(h.Header) +// require.NoError(t, err) +// stateRoot, err := st.HashTreeRoot(ctx) +// require.NoError(t, err) +// +// // get a new signed block so the root is updated with the new state root +// block.Block.StateRoot = stateRoot[:] +// signedBlock, err = blocks.NewSignedBeaconBlock(block) +// require.NoError(t, err) +// +// root, err := block.Block.HashTreeRoot() +// require.NoError(t, err) +// +// mockBlocker := &testutil.MockBlocker{ +// RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ +// parentRoot: signedParent, +// root: signedBlock, +// }, +// SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ +// slot.Sub(1): signedParent, +// slot: signedBlock, +// }, +// } +// mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st} +// s := &Server{ +// Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ +// slot.Sub(1): attestedState, +// slot: st, +// }}, +// Blocker: mockBlocker, +// HeadFetcher: mockChainService, +// } +// startPeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) +// count := 129 // config.MaxRequestLightClientUpdates is 128 +// url := fmt.Sprintf("http://foo.com/?count=%d&start_period=%d", count, startPeriod) +// request := httptest.NewRequest("GET", url, nil) +// writer := httptest.NewRecorder() +// writer.Body = &bytes.Buffer{} +// +// s.GetLightClientUpdatesByRange(writer, request) +// +// require.Equal(t, http.StatusOK, writer.Code) +// var resp structs.LightClientUpdatesByRangeResponse +// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) +// require.NoError(t, err) +// var respHeader structs.LightClientHeader +// err = json.Unmarshal(resp.Updates[0].Data.AttestedHeader, &respHeader) +// require.NoError(t, err) +// require.Equal(t, 1, len(resp.Updates)) // Even with big count input, the response is still the max available period, which is 1 in test case. +// require.Equal(t, "altair", resp.Updates[0].Version) +// require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot) +// require.NotNil(t, resp) +//} +// +//func TestLightClientHandler_GetLightClientUpdatesByRange_TooBigInputCountCapella(t *testing.T) { +// helpers.ClearCache() +// ctx := context.Background() +// config := params.BeaconConfig() +// slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) +// +// attestedState, err := util.NewBeaconStateCapella() +// require.NoError(t, err) +// err = attestedState.SetSlot(slot.Sub(1)) +// require.NoError(t, err) +// +// parent := util.NewBeaconBlockCapella() +// parent.Block.Slot = slot.Sub(1) +// +// signedParent, err := blocks.NewSignedBeaconBlock(parent) +// require.NoError(t, err) +// +// parentHeader, err := signedParent.Header() +// require.NoError(t, err) +// attestedHeader := parentHeader.Header +// +// err = attestedState.SetLatestBlockHeader(attestedHeader) +// require.NoError(t, err) +// attestedStateRoot, err := attestedState.HashTreeRoot(ctx) +// require.NoError(t, err) +// +// // get a new signed block so the root is updated with the new state root +// parent.Block.StateRoot = attestedStateRoot[:] +// signedParent, err = blocks.NewSignedBeaconBlock(parent) +// require.NoError(t, err) +// +// st, err := util.NewBeaconStateCapella() +// require.NoError(t, err) +// err = st.SetSlot(slot) +// require.NoError(t, err) +// +// parentRoot, err := signedParent.Block().HashTreeRoot() +// require.NoError(t, err) +// +// block := util.NewBeaconBlockCapella() +// block.Block.Slot = slot +// block.Block.ParentRoot = parentRoot[:] +// +// for i := uint64(0); i < config.SyncCommitteeSize; i++ { +// block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) +// } +// +// signedBlock, err := blocks.NewSignedBeaconBlock(block) +// require.NoError(t, err) +// +// h, err := signedBlock.Header() +// require.NoError(t, err) +// +// err = st.SetLatestBlockHeader(h.Header) +// require.NoError(t, err) +// stateRoot, err := st.HashTreeRoot(ctx) +// require.NoError(t, err) +// +// // get a new signed block so the root is updated with the new state root +// block.Block.StateRoot = stateRoot[:] +// signedBlock, err = blocks.NewSignedBeaconBlock(block) +// require.NoError(t, err) +// +// root, err := block.Block.HashTreeRoot() +// require.NoError(t, err) +// +// mockBlocker := &testutil.MockBlocker{ +// RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ +// parentRoot: signedParent, +// root: signedBlock, +// }, +// SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ +// slot.Sub(1): signedParent, +// slot: signedBlock, +// }, +// } +// mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st} +// s := &Server{ +// Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ +// slot.Sub(1): attestedState, +// slot: st, +// }}, +// Blocker: mockBlocker, +// HeadFetcher: mockChainService, +// } +// startPeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) +// count := 129 // config.MaxRequestLightClientUpdates is 128 +// url := fmt.Sprintf("http://foo.com/?count=%d&start_period=%d", count, startPeriod) +// request := httptest.NewRequest("GET", url, nil) +// writer := httptest.NewRecorder() +// writer.Body = &bytes.Buffer{} +// +// s.GetLightClientUpdatesByRange(writer, request) +// +// require.Equal(t, http.StatusOK, writer.Code) +// var resp structs.LightClientUpdatesByRangeResponse +// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) +// require.NoError(t, err) +// var respHeader structs.LightClientHeaderCapella +// err = json.Unmarshal(resp.Updates[0].Data.AttestedHeader, &respHeader) +// require.NoError(t, err) +// require.Equal(t, 1, len(resp.Updates)) // Even with big count input, the response is still the max available period, which is 1 in test case. +// require.Equal(t, "capella", resp.Updates[0].Version) +// require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot) +// require.NotNil(t, resp) +//} +// +//func TestLightClientHandler_GetLightClientUpdatesByRange_TooBigInputCountDeneb(t *testing.T) { +// helpers.ClearCache() +// ctx := context.Background() +// config := params.BeaconConfig() +// slot := primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) +// +// attestedState, err := util.NewBeaconStateDeneb() +// require.NoError(t, err) +// err = attestedState.SetSlot(slot.Sub(1)) +// require.NoError(t, err) +// +// parent := util.NewBeaconBlockDeneb() +// parent.Block.Slot = slot.Sub(1) +// +// signedParent, err := blocks.NewSignedBeaconBlock(parent) +// require.NoError(t, err) +// +// parentHeader, err := signedParent.Header() +// require.NoError(t, err) +// attestedHeader := parentHeader.Header +// +// err = attestedState.SetLatestBlockHeader(attestedHeader) +// require.NoError(t, err) +// attestedStateRoot, err := attestedState.HashTreeRoot(ctx) +// require.NoError(t, err) +// +// // get a new signed block so the root is updated with the new state root +// parent.Block.StateRoot = attestedStateRoot[:] +// signedParent, err = blocks.NewSignedBeaconBlock(parent) +// require.NoError(t, err) +// +// st, err := util.NewBeaconStateDeneb() +// require.NoError(t, err) +// err = st.SetSlot(slot) +// require.NoError(t, err) +// +// parentRoot, err := signedParent.Block().HashTreeRoot() +// require.NoError(t, err) +// +// block := util.NewBeaconBlockDeneb() +// block.Block.Slot = slot +// block.Block.ParentRoot = parentRoot[:] +// +// for i := uint64(0); i < config.SyncCommitteeSize; i++ { +// block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) +// } +// +// signedBlock, err := blocks.NewSignedBeaconBlock(block) +// require.NoError(t, err) +// +// h, err := signedBlock.Header() +// require.NoError(t, err) +// +// err = st.SetLatestBlockHeader(h.Header) +// require.NoError(t, err) +// stateRoot, err := st.HashTreeRoot(ctx) +// require.NoError(t, err) +// +// // get a new signed block so the root is updated with the new state root +// block.Block.StateRoot = stateRoot[:] +// signedBlock, err = blocks.NewSignedBeaconBlock(block) +// require.NoError(t, err) +// +// root, err := block.Block.HashTreeRoot() +// require.NoError(t, err) +// +// mockBlocker := &testutil.MockBlocker{ +// RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ +// parentRoot: signedParent, +// root: signedBlock, +// }, +// SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ +// slot.Sub(1): signedParent, +// slot: signedBlock, +// }, +// } +// mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st} +// s := &Server{ +// Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ +// slot.Sub(1): attestedState, +// slot: st, +// }}, +// Blocker: mockBlocker, +// HeadFetcher: mockChainService, +// } +// startPeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) +// count := 129 // config.MaxRequestLightClientUpdates is 128 +// url := fmt.Sprintf("http://foo.com/?count=%d&start_period=%d", count, startPeriod) +// request := httptest.NewRequest("GET", url, nil) +// writer := httptest.NewRecorder() +// writer.Body = &bytes.Buffer{} +// +// s.GetLightClientUpdatesByRange(writer, request) +// +// require.Equal(t, http.StatusOK, writer.Code) +// var resp structs.LightClientUpdatesByRangeResponse +// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) +// require.NoError(t, err) +// var respHeader structs.LightClientHeaderDeneb +// err = json.Unmarshal(resp.Updates[0].Data.AttestedHeader, &respHeader) +// require.NoError(t, err) +// require.Equal(t, 1, len(resp.Updates)) // Even with big count input, the response is still the max available period, which is 1 in test case. +// require.Equal(t, "deneb", resp.Updates[0].Version) +// require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot) +// require.NotNil(t, resp) +//} +// +//// TODO - check for not having any blocks from the min period, and startPeriod being too early +//func TestLightClientHandler_GetLightClientUpdatesByRange_TooEarlyPeriodAltair(t *testing.T) { +// helpers.ClearCache() +// ctx := context.Background() +// config := params.BeaconConfig() +// slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) +// +// attestedState, err := util.NewBeaconStateAltair() +// require.NoError(t, err) +// err = attestedState.SetSlot(slot.Sub(1)) +// require.NoError(t, err) +// +// parent := util.NewBeaconBlockAltair() +// parent.Block.Slot = slot.Sub(1) +// +// signedParent, err := blocks.NewSignedBeaconBlock(parent) +// require.NoError(t, err) +// +// parentHeader, err := signedParent.Header() +// require.NoError(t, err) +// attestedHeader := parentHeader.Header +// +// err = attestedState.SetLatestBlockHeader(attestedHeader) +// require.NoError(t, err) +// attestedStateRoot, err := attestedState.HashTreeRoot(ctx) +// require.NoError(t, err) +// +// // get a new signed block so the root is updated with the new state root +// parent.Block.StateRoot = attestedStateRoot[:] +// signedParent, err = blocks.NewSignedBeaconBlock(parent) +// require.NoError(t, err) +// +// st, err := util.NewBeaconStateAltair() +// require.NoError(t, err) +// err = st.SetSlot(slot) +// require.NoError(t, err) +// +// parentRoot, err := signedParent.Block().HashTreeRoot() +// require.NoError(t, err) +// +// block := util.NewBeaconBlockAltair() +// block.Block.Slot = slot +// block.Block.ParentRoot = parentRoot[:] +// +// for i := uint64(0); i < config.SyncCommitteeSize; i++ { +// block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) +// } +// +// signedBlock, err := blocks.NewSignedBeaconBlock(block) +// require.NoError(t, err) +// +// h, err := signedBlock.Header() +// require.NoError(t, err) +// +// err = st.SetLatestBlockHeader(h.Header) +// require.NoError(t, err) +// stateRoot, err := st.HashTreeRoot(ctx) +// require.NoError(t, err) +// +// // get a new signed block so the root is updated with the new state root +// block.Block.StateRoot = stateRoot[:] +// signedBlock, err = blocks.NewSignedBeaconBlock(block) +// require.NoError(t, err) +// +// root, err := block.Block.HashTreeRoot() +// require.NoError(t, err) +// +// mockBlocker := &testutil.MockBlocker{ +// RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ +// parentRoot: signedParent, +// root: signedBlock, +// }, +// SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ +// slot.Sub(1): signedParent, +// slot: signedBlock, +// }, +// } +// mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st} +// s := &Server{ +// Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ +// slot.Sub(1): attestedState, +// slot: st, +// }}, +// Blocker: mockBlocker, +// HeadFetcher: mockChainService, +// } +// startPeriod := 1 // very early period before Altair fork +// count := 1 +// url := fmt.Sprintf("http://foo.com/?count=%d&start_period=%d", count, startPeriod) +// request := httptest.NewRequest("GET", url, nil) +// writer := httptest.NewRecorder() +// writer.Body = &bytes.Buffer{} +// +// s.GetLightClientUpdatesByRange(writer, request) +// +// require.Equal(t, http.StatusOK, writer.Code) +// var resp structs.LightClientUpdatesByRangeResponse +// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) +// require.NoError(t, err) +// var respHeader structs.LightClientHeader +// err = json.Unmarshal(resp.Updates[0].Data.AttestedHeader, &respHeader) +// require.NoError(t, err) +// require.Equal(t, 1, len(resp.Updates)) +// require.Equal(t, "altair", resp.Updates[0].Version) +// require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot) +// require.NotNil(t, resp) +//} +// +//// TODO - same as above +//func TestLightClientHandler_GetLightClientUpdatesByRange_TooBigCountAltair(t *testing.T) { +// helpers.ClearCache() +// ctx := context.Background() +// config := params.BeaconConfig() +// slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) +// +// attestedState, err := util.NewBeaconStateAltair() +// require.NoError(t, err) +// err = attestedState.SetSlot(slot.Sub(1)) +// require.NoError(t, err) +// +// parent := util.NewBeaconBlockAltair() +// parent.Block.Slot = slot.Sub(1) +// +// signedParent, err := blocks.NewSignedBeaconBlock(parent) +// require.NoError(t, err) +// +// parentHeader, err := signedParent.Header() +// require.NoError(t, err) +// attestedHeader := parentHeader.Header +// +// err = attestedState.SetLatestBlockHeader(attestedHeader) +// require.NoError(t, err) +// attestedStateRoot, err := attestedState.HashTreeRoot(ctx) +// require.NoError(t, err) +// +// // get a new signed block so the root is updated with the new state root +// parent.Block.StateRoot = attestedStateRoot[:] +// signedParent, err = blocks.NewSignedBeaconBlock(parent) +// require.NoError(t, err) +// +// st, err := util.NewBeaconStateAltair() +// require.NoError(t, err) +// err = st.SetSlot(slot) +// require.NoError(t, err) +// +// parentRoot, err := signedParent.Block().HashTreeRoot() +// require.NoError(t, err) +// +// block := util.NewBeaconBlockAltair() +// block.Block.Slot = slot +// block.Block.ParentRoot = parentRoot[:] +// +// for i := uint64(0); i < config.SyncCommitteeSize; i++ { +// block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) +// } +// +// signedBlock, err := blocks.NewSignedBeaconBlock(block) +// require.NoError(t, err) +// +// h, err := signedBlock.Header() +// require.NoError(t, err) +// +// err = st.SetLatestBlockHeader(h.Header) +// require.NoError(t, err) +// stateRoot, err := st.HashTreeRoot(ctx) +// require.NoError(t, err) +// +// // get a new signed block so the root is updated with the new state root +// block.Block.StateRoot = stateRoot[:] +// signedBlock, err = blocks.NewSignedBeaconBlock(block) +// require.NoError(t, err) +// +// root, err := block.Block.HashTreeRoot() +// require.NoError(t, err) +// +// mockBlocker := &testutil.MockBlocker{ +// RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ +// parentRoot: signedParent, +// root: signedBlock, +// }, +// SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ +// slot.Sub(1): signedParent, +// slot: signedBlock, +// }, +// } +// mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st} +// s := &Server{ +// Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ +// slot.Sub(1): attestedState, +// slot: st, +// }}, +// Blocker: mockBlocker, +// HeadFetcher: mockChainService, +// } +// startPeriod := 1 // very early period before Altair fork +// count := 10 // This is big count as we only have one period in test case. +// url := fmt.Sprintf("http://foo.com/?count=%d&start_period=%d", count, startPeriod) +// request := httptest.NewRequest("GET", url, nil) +// writer := httptest.NewRecorder() +// writer.Body = &bytes.Buffer{} +// +// s.GetLightClientUpdatesByRange(writer, request) +// +// require.Equal(t, http.StatusOK, writer.Code) +// var resp structs.LightClientUpdatesByRangeResponse +// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) +// require.NoError(t, err) +// var respHeader structs.LightClientHeader +// err = json.Unmarshal(resp.Updates[0].Data.AttestedHeader, &respHeader) +// require.NoError(t, err) +// require.Equal(t, 1, len(resp.Updates)) +// require.Equal(t, "altair", resp.Updates[0].Version) +// require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot) +// require.NotNil(t, resp) +//} +// +//func TestLightClientHandler_GetLightClientUpdatesByRange_BeforeAltair(t *testing.T) { +// helpers.ClearCache() +// ctx := context.Background() +// config := params.BeaconConfig() +// slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Sub(1) +// +// attestedState, err := util.NewBeaconStateCapella() +// require.NoError(t, err) +// err = attestedState.SetSlot(slot.Sub(1)) +// require.NoError(t, err) +// +// parent := util.NewBeaconBlockCapella() +// parent.Block.Slot = slot.Sub(1) +// +// signedParent, err := blocks.NewSignedBeaconBlock(parent) +// require.NoError(t, err) +// +// parentHeader, err := signedParent.Header() +// require.NoError(t, err) +// attestedHeader := parentHeader.Header +// +// err = attestedState.SetLatestBlockHeader(attestedHeader) +// require.NoError(t, err) +// attestedStateRoot, err := attestedState.HashTreeRoot(ctx) +// require.NoError(t, err) +// +// // get a new signed block so the root is updated with the new state root +// parent.Block.StateRoot = attestedStateRoot[:] +// signedParent, err = blocks.NewSignedBeaconBlock(parent) +// require.NoError(t, err) +// +// st, err := util.NewBeaconStateCapella() +// require.NoError(t, err) +// err = st.SetSlot(slot) +// require.NoError(t, err) +// +// parentRoot, err := signedParent.Block().HashTreeRoot() +// require.NoError(t, err) +// +// block := util.NewBeaconBlockCapella() +// block.Block.Slot = slot +// block.Block.ParentRoot = parentRoot[:] +// +// for i := uint64(0); i < config.SyncCommitteeSize; i++ { +// block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) +// } +// +// signedBlock, err := blocks.NewSignedBeaconBlock(block) +// require.NoError(t, err) +// +// h, err := signedBlock.Header() +// require.NoError(t, err) +// +// err = st.SetLatestBlockHeader(h.Header) +// require.NoError(t, err) +// stateRoot, err := st.HashTreeRoot(ctx) +// require.NoError(t, err) +// +// // get a new signed block so the root is updated with the new state root +// block.Block.StateRoot = stateRoot[:] +// signedBlock, err = blocks.NewSignedBeaconBlock(block) +// require.NoError(t, err) +// +// root, err := block.Block.HashTreeRoot() +// require.NoError(t, err) +// +// mockBlocker := &testutil.MockBlocker{ +// RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ +// parentRoot: signedParent, +// root: signedBlock, +// }, +// SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ +// slot.Sub(1): signedParent, +// slot: signedBlock, +// }, +// } +// mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st} +// s := &Server{ +// Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ +// slot.Sub(1): attestedState, +// slot: st, +// }}, +// Blocker: mockBlocker, +// HeadFetcher: mockChainService, +// } +// startPeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) +// count := 1 +// url := fmt.Sprintf("http://foo.com/?count=%d&start_period=%d", count, startPeriod) +// request := httptest.NewRequest("GET", url, nil) +// writer := httptest.NewRecorder() +// writer.Body = &bytes.Buffer{} +// +// s.GetLightClientUpdatesByRange(writer, request) +// +// require.Equal(t, http.StatusNotFound, writer.Code) +//} func TestLightClientHandler_GetLightClientFinalityUpdateAltair(t *testing.T) { helpers.ClearCache() @@ -2047,3 +2133,13 @@ func TestLightClientHandler_GetLightClientEventBlock_NeedFetchParent(t *testing. require.Equal(t, true, syncAggregate.SyncCommitteeBits.Count() >= minSignaturesRequired) require.Equal(t, slot-1, eventBlock.Block().Slot()) } + +// setupDB instantiates and returns a Store instance. +func setupDB(t testing.TB) *kv.Store { + db, err := kv.NewKVStore(context.Background(), t.TempDir()) + require.NoError(t, err, "Failed to instantiate DB") + t.Cleanup(func() { + require.NoError(t, db.Close(), "Failed to close database") + }) + return db +} From dedfacb046c31944474ecb64fee50187f8735e64 Mon Sep 17 00:00:00 2001 From: Inspector-Butters Date: Sun, 13 Oct 2024 16:12:49 +0200 Subject: [PATCH 04/35] range forks tests --- .../rpc/eth/light-client/handlers_test.go | 307 +++++++++++------- 1 file changed, 190 insertions(+), 117 deletions(-) diff --git a/beacon-chain/rpc/eth/light-client/handlers_test.go b/beacon-chain/rpc/eth/light-client/handlers_test.go index b32e923c8f68..b124f0c6e880 100644 --- a/beacon-chain/rpc/eth/light-client/handlers_test.go +++ b/beacon-chain/rpc/eth/light-client/handlers_test.go @@ -440,12 +440,16 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeCapella(t *testing.T) { root, err := block.Block.HashTreeRoot() require.NoError(t, err) + db := setupDB(t) + + updatePeriod := uint64(slot.Sub(1).Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch))) + update := ðpbv2.LightClientUpdate{ AttestedHeader: ðpbv2.LightClientHeaderContainer{ Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ HeaderCapella: ðpbv2.LightClientHeaderCapella{ Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 1, + Slot: slot.Sub(1), ProposerIndex: 1, ParentRoot: []byte{1, 1, 1}, StateRoot: []byte{1, 1, 1}, @@ -467,22 +471,33 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeCapella(t *testing.T) { Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ HeaderCapella: ðpbv2.LightClientHeaderCapella{ Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 1, + Slot: 12, ProposerIndex: 1, ParentRoot: []byte{1, 1, 1}, StateRoot: []byte{1, 1, 1}, BodyRoot: []byte{1, 1, 1}, }, - Execution: nil, - ExecutionBranch: nil, + Execution: &enginev1.ExecutionPayloadHeaderCapella{ + FeeRecipient: []byte{1, 2, 3}, + }, + ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, }, }, }, FinalityBranch: nil, - SyncAggregate: nil, - SignatureSlot: 7, + SyncAggregate: ðpbv1.SyncAggregate{ + SyncCommitteeBits: []byte{1, 1, 1}, + SyncCommitteeSignature: []byte{1, 1, 1}, + }, + SignatureSlot: 7, } + err = db.SaveLightClientUpdate(ctx, updatePeriod, ðpbv2.LightClientUpdateWithVersion{ + Version: version.Capella, + Data: update, + }) + require.NoError(t, err) + mockBlocker := &testutil.MockBlocker{ RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ parentRoot: signedParent, @@ -501,6 +516,7 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeCapella(t *testing.T) { }}, Blocker: mockBlocker, HeadFetcher: mockChainService, + BeaconDB: db, } startPeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) url := fmt.Sprintf("http://foo.com/?count=1&start_period=%d", startPeriod) @@ -514,121 +530,178 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeCapella(t *testing.T) { var resp structs.LightClientUpdatesByRangeResponse err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) require.NoError(t, err) - var respHeader structs.LightClientHeaderCapella - err = json.Unmarshal(resp.Updates[0].Data.AttestedHeader, &respHeader) - require.NoError(t, err) require.Equal(t, 1, len(resp.Updates)) + require.NoError(t, err) require.Equal(t, "capella", resp.Updates[0].Version) - require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot) - require.NotNil(t, resp) + updateJson, err := structs.LightClientUpdateFromConsensus(update) + require.NoError(t, err) + require.DeepEqual(t, updateJson, resp.Updates[0].Data) +} + +func TestLightClientHandler_GetLightClientUpdatesByRangeDeneb(t *testing.T) { + helpers.ClearCache() + ctx := context.Background() + config := params.BeaconConfig() + slot := primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) + + attestedState, err := util.NewBeaconStateDeneb() + require.NoError(t, err) + err = attestedState.SetSlot(slot.Sub(1)) + require.NoError(t, err) + + parent := util.NewBeaconBlockDeneb() + parent.Block.Slot = slot.Sub(1) + + signedParent, err := blocks.NewSignedBeaconBlock(parent) + require.NoError(t, err) + + parentHeader, err := signedParent.Header() + require.NoError(t, err) + attestedHeader := parentHeader.Header + + err = attestedState.SetLatestBlockHeader(attestedHeader) + require.NoError(t, err) + attestedStateRoot, err := attestedState.HashTreeRoot(ctx) + require.NoError(t, err) + + // get a new signed block so the root is updated with the new state root + parent.Block.StateRoot = attestedStateRoot[:] + signedParent, err = blocks.NewSignedBeaconBlock(parent) + require.NoError(t, err) + + st, err := util.NewBeaconStateDeneb() + require.NoError(t, err) + err = st.SetSlot(slot) + require.NoError(t, err) + + parentRoot, err := signedParent.Block().HashTreeRoot() + require.NoError(t, err) + + block := util.NewBeaconBlockDeneb() + block.Block.Slot = slot + block.Block.ParentRoot = parentRoot[:] + + for i := uint64(0); i < config.SyncCommitteeSize; i++ { + block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) + } + + signedBlock, err := blocks.NewSignedBeaconBlock(block) + require.NoError(t, err) + + h, err := signedBlock.Header() + require.NoError(t, err) + + err = st.SetLatestBlockHeader(h.Header) + require.NoError(t, err) + stateRoot, err := st.HashTreeRoot(ctx) + require.NoError(t, err) + + // get a new signed block so the root is updated with the new state root + block.Block.StateRoot = stateRoot[:] + signedBlock, err = blocks.NewSignedBeaconBlock(block) + require.NoError(t, err) + + root, err := block.Block.HashTreeRoot() + require.NoError(t, err) + + db := setupDB(t) + + updatePeriod := uint64(slot.Sub(1).Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch))) + + update := ðpbv2.LightClientUpdate{ + AttestedHeader: ðpbv2.LightClientHeaderContainer{ + Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ + HeaderCapella: ðpbv2.LightClientHeaderCapella{ + Beacon: ðpbv1.BeaconBlockHeader{ + Slot: slot.Sub(1), + ProposerIndex: 1, + ParentRoot: []byte{1, 1, 1}, + StateRoot: []byte{1, 1, 1}, + BodyRoot: []byte{1, 1, 1}, + }, + Execution: &enginev1.ExecutionPayloadHeaderCapella{ + FeeRecipient: []byte{1, 2, 3}, + }, + ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, + }, + }, + }, + NextSyncCommittee: ðpbv2.SyncCommittee{ + Pubkeys: nil, + AggregatePubkey: nil, + }, + NextSyncCommitteeBranch: nil, + FinalizedHeader: ðpbv2.LightClientHeaderContainer{ + Header: ðpbv2.LightClientHeaderContainer_HeaderDeneb{ + HeaderDeneb: ðpbv2.LightClientHeaderDeneb{ + Beacon: ðpbv1.BeaconBlockHeader{ + Slot: 12, + ProposerIndex: 1, + ParentRoot: []byte{1, 1, 1}, + StateRoot: []byte{1, 1, 1}, + BodyRoot: []byte{1, 1, 1}, + }, + Execution: &enginev1.ExecutionPayloadHeaderDeneb{ + FeeRecipient: []byte{1, 2, 3}, + }, + ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, + }, + }, + }, + FinalityBranch: nil, + SyncAggregate: ðpbv1.SyncAggregate{ + SyncCommitteeBits: []byte{1, 1, 1}, + SyncCommitteeSignature: []byte{1, 1, 1}, + }, + SignatureSlot: 7, + } + + err = db.SaveLightClientUpdate(ctx, updatePeriod, ðpbv2.LightClientUpdateWithVersion{ + Version: version.Deneb, + Data: update, + }) + require.NoError(t, err) + + mockBlocker := &testutil.MockBlocker{ + RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ + parentRoot: signedParent, + root: signedBlock, + }, + SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ + slot.Sub(1): signedParent, + slot: signedBlock, + }, + } + mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st} + s := &Server{ + Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ + slot.Sub(1): attestedState, + slot: st, + }}, + Blocker: mockBlocker, + HeadFetcher: mockChainService, + BeaconDB: db, + } + startPeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) + url := fmt.Sprintf("http://foo.com/?count=1&start_period=%d", startPeriod) + request := httptest.NewRequest("GET", url, nil) + writer := httptest.NewRecorder() + writer.Body = &bytes.Buffer{} + + s.GetLightClientUpdatesByRange(writer, request) + + require.Equal(t, http.StatusOK, writer.Code) + var resp structs.LightClientUpdatesByRangeResponse + err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) + require.NoError(t, err) + require.Equal(t, 1, len(resp.Updates)) + require.NoError(t, err) + require.Equal(t, "deneb", resp.Updates[0].Version) + updateJson, err := structs.LightClientUpdateFromConsensus(update) + require.NoError(t, err) + require.DeepEqual(t, updateJson, resp.Updates[0].Data) } -//func TestLightClientHandler_GetLightClientUpdatesByRangeDeneb(t *testing.T) { -// helpers.ClearCache() -// ctx := context.Background() -// config := params.BeaconConfig() -// slot := primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) -// -// attestedState, err := util.NewBeaconStateDeneb() -// require.NoError(t, err) -// err = attestedState.SetSlot(slot.Sub(1)) -// require.NoError(t, err) -// -// parent := util.NewBeaconBlockDeneb() -// parent.Block.Slot = slot.Sub(1) -// -// signedParent, err := blocks.NewSignedBeaconBlock(parent) -// require.NoError(t, err) -// -// parentHeader, err := signedParent.Header() -// require.NoError(t, err) -// attestedHeader := parentHeader.Header -// -// err = attestedState.SetLatestBlockHeader(attestedHeader) -// require.NoError(t, err) -// attestedStateRoot, err := attestedState.HashTreeRoot(ctx) -// require.NoError(t, err) -// -// // get a new signed block so the root is updated with the new state root -// parent.Block.StateRoot = attestedStateRoot[:] -// signedParent, err = blocks.NewSignedBeaconBlock(parent) -// require.NoError(t, err) -// -// st, err := util.NewBeaconStateDeneb() -// require.NoError(t, err) -// err = st.SetSlot(slot) -// require.NoError(t, err) -// -// parentRoot, err := signedParent.Block().HashTreeRoot() -// require.NoError(t, err) -// -// block := util.NewBeaconBlockDeneb() -// block.Block.Slot = slot -// block.Block.ParentRoot = parentRoot[:] -// -// for i := uint64(0); i < config.SyncCommitteeSize; i++ { -// block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) -// } -// -// signedBlock, err := blocks.NewSignedBeaconBlock(block) -// require.NoError(t, err) -// -// h, err := signedBlock.Header() -// require.NoError(t, err) -// -// err = st.SetLatestBlockHeader(h.Header) -// require.NoError(t, err) -// stateRoot, err := st.HashTreeRoot(ctx) -// require.NoError(t, err) -// -// // get a new signed block so the root is updated with the new state root -// block.Block.StateRoot = stateRoot[:] -// signedBlock, err = blocks.NewSignedBeaconBlock(block) -// require.NoError(t, err) -// -// root, err := block.Block.HashTreeRoot() -// require.NoError(t, err) -// -// mockBlocker := &testutil.MockBlocker{ -// RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ -// parentRoot: signedParent, -// root: signedBlock, -// }, -// SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ -// slot.Sub(1): signedParent, -// slot: signedBlock, -// }, -// } -// mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st} -// s := &Server{ -// Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ -// slot.Sub(1): attestedState, -// slot: st, -// }}, -// Blocker: mockBlocker, -// HeadFetcher: mockChainService, -// } -// startPeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) -// url := fmt.Sprintf("http://foo.com/?count=1&start_period=%d", startPeriod) -// request := httptest.NewRequest("GET", url, nil) -// writer := httptest.NewRecorder() -// writer.Body = &bytes.Buffer{} -// -// s.GetLightClientUpdatesByRange(writer, request) -// -// require.Equal(t, http.StatusOK, writer.Code) -// var resp structs.LightClientUpdatesByRangeResponse -// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) -// require.NoError(t, err) -// var respHeader structs.LightClientHeaderDeneb -// err = json.Unmarshal(resp.Updates[0].Data.AttestedHeader, &respHeader) -// require.NoError(t, err) -// require.Equal(t, 1, len(resp.Updates)) -// require.Equal(t, "deneb", resp.Updates[0].Version) -// require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot) -// require.NotNil(t, resp) -//} -// //func TestLightClientHandler_GetLightClientUpdatesByRange_TooBigInputCountAltair(t *testing.T) { // helpers.ClearCache() // ctx := context.Background() From b1831caf13e5ec111262e9bb470d5142eb9013f6 Mon Sep 17 00:00:00 2001 From: Inspector-Butters Date: Mon, 14 Oct 2024 13:16:31 +0200 Subject: [PATCH 05/35] finish tests --- beacon-chain/rpc/eth/light-client/BUILD.bazel | 3 + beacon-chain/rpc/eth/light-client/handlers.go | 4 +- .../rpc/eth/light-client/handlers_test.go | 1993 ++++++++++------- 3 files changed, 1156 insertions(+), 844 deletions(-) diff --git a/beacon-chain/rpc/eth/light-client/BUILD.bazel b/beacon-chain/rpc/eth/light-client/BUILD.bazel index d21b3b2ebc03..498cce61e0b5 100644 --- a/beacon-chain/rpc/eth/light-client/BUILD.bazel +++ b/beacon-chain/rpc/eth/light-client/BUILD.bazel @@ -45,6 +45,7 @@ go_test( "//beacon-chain/blockchain/testing:go_default_library", "//beacon-chain/core/helpers:go_default_library", "//beacon-chain/core/light-client:go_default_library", + "//beacon-chain/db/kv:go_default_library", "//beacon-chain/rpc/testutil:go_default_library", "//beacon-chain/state:go_default_library", "//config/fieldparams:go_default_library", @@ -52,9 +53,11 @@ go_test( "//consensus-types/blocks:go_default_library", "//consensus-types/interfaces:go_default_library", "//consensus-types/primitives:go_default_library", + "//proto/engine/v1:go_default_library", "//proto/eth/v1:go_default_library", "//proto/eth/v2:go_default_library", "//proto/prysm/v1alpha1:go_default_library", + "//runtime/version:go_default_library", "//testing/assert:go_default_library", "//testing/require:go_default_library", "//testing/util:go_default_library", diff --git a/beacon-chain/rpc/eth/light-client/handlers.go b/beacon-chain/rpc/eth/light-client/handlers.go index 4fcf91eb0189..fc81bcc57010 100644 --- a/beacon-chain/rpc/eth/light-client/handlers.go +++ b/beacon-chain/rpc/eth/light-client/handlers.go @@ -123,6 +123,7 @@ func (s *Server) GetLightClientUpdatesByRange(w http.ResponseWriter, req *http.R } updates := make([]*structs.LightClientUpdateResponse, len(updatesMap)) + updatesCount := 0 for i, j := startPeriod, 0; i <= endPeriod; i, j = i+1, j+1 { update, ok := updatesMap[i] if !ok { @@ -137,9 +138,10 @@ func (s *Server) GetLightClientUpdatesByRange(w http.ResponseWriter, req *http.R } updates[j] = updateResponse + updatesCount++ } - httputil.WriteJson(w, updates) + httputil.WriteJson(w, updates[:updatesCount]) } // GetLightClientFinalityUpdate - implements https://github.com/ethereum/beacon-APIs/blob/263f4ed6c263c967f13279c7a9f5629b51c5fc55/apis/beacon/light_client/finality_update.yaml diff --git a/beacon-chain/rpc/eth/light-client/handlers_test.go b/beacon-chain/rpc/eth/light-client/handlers_test.go index b124f0c6e880..0b23c42c7bfc 100644 --- a/beacon-chain/rpc/eth/light-client/handlers_test.go +++ b/beacon-chain/rpc/eth/light-client/handlers_test.go @@ -230,75 +230,22 @@ func TestLightClientHandler_GetLightClientBootstrap_Electra(t *testing.T) { require.NotNil(t, resp.Data.CurrentSyncCommitteeBranch) } +// GetLightClientByRange tests + func TestLightClientHandler_GetLightClientUpdatesByRangeAltair(t *testing.T) { helpers.ClearCache() ctx := context.Background() config := params.BeaconConfig() slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) - attestedState, err := util.NewBeaconStateAltair() - require.NoError(t, err) - err = attestedState.SetSlot(slot.Sub(1)) - require.NoError(t, err) - - parent := util.NewBeaconBlockAltair() - parent.Block.Slot = slot.Sub(1) - - signedParent, err := blocks.NewSignedBeaconBlock(parent) - require.NoError(t, err) - - parentHeader, err := signedParent.Header() - require.NoError(t, err) - attestedHeader := parentHeader.Header - - err = attestedState.SetLatestBlockHeader(attestedHeader) - require.NoError(t, err) - attestedStateRoot, err := attestedState.HashTreeRoot(ctx) - require.NoError(t, err) - - // get a new signed block so the root is updated with the new state root - parent.Block.StateRoot = attestedStateRoot[:] - signedParent, err = blocks.NewSignedBeaconBlock(parent) - require.NoError(t, err) - st, err := util.NewBeaconStateAltair() require.NoError(t, err) err = st.SetSlot(slot) require.NoError(t, err) - parentRoot, err := signedParent.Block().HashTreeRoot() - require.NoError(t, err) - - block := util.NewBeaconBlockAltair() - block.Block.Slot = slot - block.Block.ParentRoot = parentRoot[:] - - for i := uint64(0); i < config.SyncCommitteeSize; i++ { - block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) - } - - signedBlock, err := blocks.NewSignedBeaconBlock(block) - require.NoError(t, err) - - h, err := signedBlock.Header() - require.NoError(t, err) - - err = st.SetLatestBlockHeader(h.Header) - require.NoError(t, err) - stateRoot, err := st.HashTreeRoot(ctx) - require.NoError(t, err) - - // get a new signed block so the root is updated with the new state root - block.Block.StateRoot = stateRoot[:] - signedBlock, err = blocks.NewSignedBeaconBlock(block) - require.NoError(t, err) - - root, err := block.Block.HashTreeRoot() - require.NoError(t, err) - db := setupDB(t) - updatePeriod := uint64(slot.Sub(1).Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch))) + updatePeriod := uint64(slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch))) update := ðpbv2.LightClientUpdate{ AttestedHeader: ðpbv2.LightClientHeaderContainer{ @@ -334,22 +281,10 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeAltair(t *testing.T) { }) require.NoError(t, err) - mockBlocker := &testutil.MockBlocker{ - RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ - parentRoot: signedParent, - root: signedBlock, - }, - SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ - slot.Sub(1): signedParent, - slot: signedBlock, - }, - } + mockBlocker := &testutil.MockBlocker{} mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st} s := &Server{ - Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ - slot.Sub(1): attestedState, - slot: st, - }}, + Stater: &testutil.MockStater{}, Blocker: mockBlocker, HeadFetcher: mockChainService, BeaconDB: db, @@ -380,69 +315,14 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeCapella(t *testing.T) { config := params.BeaconConfig() slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) - attestedState, err := util.NewBeaconStateCapella() - require.NoError(t, err) - err = attestedState.SetSlot(slot.Sub(1)) - require.NoError(t, err) - - parent := util.NewBeaconBlockCapella() - parent.Block.Slot = slot.Sub(1) - - signedParent, err := blocks.NewSignedBeaconBlock(parent) - require.NoError(t, err) - - parentHeader, err := signedParent.Header() - require.NoError(t, err) - attestedHeader := parentHeader.Header - - err = attestedState.SetLatestBlockHeader(attestedHeader) - require.NoError(t, err) - attestedStateRoot, err := attestedState.HashTreeRoot(ctx) - require.NoError(t, err) - - // get a new signed block so the root is updated with the new state root - parent.Block.StateRoot = attestedStateRoot[:] - signedParent, err = blocks.NewSignedBeaconBlock(parent) - require.NoError(t, err) - st, err := util.NewBeaconStateCapella() require.NoError(t, err) err = st.SetSlot(slot) require.NoError(t, err) - parentRoot, err := signedParent.Block().HashTreeRoot() - require.NoError(t, err) - - block := util.NewBeaconBlockCapella() - block.Block.Slot = slot - block.Block.ParentRoot = parentRoot[:] - - for i := uint64(0); i < config.SyncCommitteeSize; i++ { - block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) - } - - signedBlock, err := blocks.NewSignedBeaconBlock(block) - require.NoError(t, err) - - h, err := signedBlock.Header() - require.NoError(t, err) - - err = st.SetLatestBlockHeader(h.Header) - require.NoError(t, err) - stateRoot, err := st.HashTreeRoot(ctx) - require.NoError(t, err) - - // get a new signed block so the root is updated with the new state root - block.Block.StateRoot = stateRoot[:] - signedBlock, err = blocks.NewSignedBeaconBlock(block) - require.NoError(t, err) - - root, err := block.Block.HashTreeRoot() - require.NoError(t, err) - db := setupDB(t) - updatePeriod := uint64(slot.Sub(1).Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch))) + updatePeriod := uint64(slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch))) update := ðpbv2.LightClientUpdate{ AttestedHeader: ðpbv2.LightClientHeaderContainer{ @@ -498,22 +378,10 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeCapella(t *testing.T) { }) require.NoError(t, err) - mockBlocker := &testutil.MockBlocker{ - RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ - parentRoot: signedParent, - root: signedBlock, - }, - SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ - slot.Sub(1): signedParent, - slot: signedBlock, - }, - } + mockBlocker := &testutil.MockBlocker{} mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st} s := &Server{ - Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ - slot.Sub(1): attestedState, - slot: st, - }}, + Stater: &testutil.MockStater{}, Blocker: mockBlocker, HeadFetcher: mockChainService, BeaconDB: db, @@ -544,69 +412,14 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeDeneb(t *testing.T) { config := params.BeaconConfig() slot := primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) - attestedState, err := util.NewBeaconStateDeneb() - require.NoError(t, err) - err = attestedState.SetSlot(slot.Sub(1)) - require.NoError(t, err) - - parent := util.NewBeaconBlockDeneb() - parent.Block.Slot = slot.Sub(1) - - signedParent, err := blocks.NewSignedBeaconBlock(parent) - require.NoError(t, err) - - parentHeader, err := signedParent.Header() - require.NoError(t, err) - attestedHeader := parentHeader.Header - - err = attestedState.SetLatestBlockHeader(attestedHeader) - require.NoError(t, err) - attestedStateRoot, err := attestedState.HashTreeRoot(ctx) - require.NoError(t, err) - - // get a new signed block so the root is updated with the new state root - parent.Block.StateRoot = attestedStateRoot[:] - signedParent, err = blocks.NewSignedBeaconBlock(parent) - require.NoError(t, err) - st, err := util.NewBeaconStateDeneb() require.NoError(t, err) err = st.SetSlot(slot) require.NoError(t, err) - parentRoot, err := signedParent.Block().HashTreeRoot() - require.NoError(t, err) - - block := util.NewBeaconBlockDeneb() - block.Block.Slot = slot - block.Block.ParentRoot = parentRoot[:] - - for i := uint64(0); i < config.SyncCommitteeSize; i++ { - block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) - } - - signedBlock, err := blocks.NewSignedBeaconBlock(block) - require.NoError(t, err) - - h, err := signedBlock.Header() - require.NoError(t, err) - - err = st.SetLatestBlockHeader(h.Header) - require.NoError(t, err) - stateRoot, err := st.HashTreeRoot(ctx) - require.NoError(t, err) - - // get a new signed block so the root is updated with the new state root - block.Block.StateRoot = stateRoot[:] - signedBlock, err = blocks.NewSignedBeaconBlock(block) - require.NoError(t, err) - - root, err := block.Block.HashTreeRoot() - require.NoError(t, err) - db := setupDB(t) - updatePeriod := uint64(slot.Sub(1).Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch))) + updatePeriod := uint64(slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch))) update := ðpbv2.LightClientUpdate{ AttestedHeader: ðpbv2.LightClientHeaderContainer{ @@ -662,22 +475,10 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeDeneb(t *testing.T) { }) require.NoError(t, err) - mockBlocker := &testutil.MockBlocker{ - RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ - parentRoot: signedParent, - root: signedBlock, - }, - SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ - slot.Sub(1): signedParent, - slot: signedBlock, - }, - } + mockBlocker := &testutil.MockBlocker{} mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st} s := &Server{ - Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ - slot.Sub(1): attestedState, - slot: st, - }}, + Stater: &testutil.MockStater{}, Blocker: mockBlocker, HeadFetcher: mockChainService, BeaconDB: db, @@ -702,639 +503,1145 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeDeneb(t *testing.T) { require.DeepEqual(t, updateJson, resp.Updates[0].Data) } -//func TestLightClientHandler_GetLightClientUpdatesByRange_TooBigInputCountAltair(t *testing.T) { -// helpers.ClearCache() -// ctx := context.Background() -// config := params.BeaconConfig() -// slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) -// -// attestedState, err := util.NewBeaconStateAltair() -// require.NoError(t, err) -// err = attestedState.SetSlot(slot.Sub(1)) -// require.NoError(t, err) -// -// parent := util.NewBeaconBlockAltair() -// parent.Block.Slot = slot.Sub(1) -// -// signedParent, err := blocks.NewSignedBeaconBlock(parent) -// require.NoError(t, err) -// -// parentHeader, err := signedParent.Header() -// require.NoError(t, err) -// attestedHeader := parentHeader.Header -// -// err = attestedState.SetLatestBlockHeader(attestedHeader) -// require.NoError(t, err) -// attestedStateRoot, err := attestedState.HashTreeRoot(ctx) -// require.NoError(t, err) -// -// // get a new signed block so the root is updated with the new state root -// parent.Block.StateRoot = attestedStateRoot[:] -// signedParent, err = blocks.NewSignedBeaconBlock(parent) -// require.NoError(t, err) -// -// st, err := util.NewBeaconStateAltair() -// require.NoError(t, err) -// err = st.SetSlot(slot) -// require.NoError(t, err) -// -// parentRoot, err := signedParent.Block().HashTreeRoot() -// require.NoError(t, err) -// -// block := util.NewBeaconBlockAltair() -// block.Block.Slot = slot -// block.Block.ParentRoot = parentRoot[:] -// -// for i := uint64(0); i < config.SyncCommitteeSize; i++ { -// block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) -// } -// -// signedBlock, err := blocks.NewSignedBeaconBlock(block) -// require.NoError(t, err) -// -// h, err := signedBlock.Header() -// require.NoError(t, err) -// -// err = st.SetLatestBlockHeader(h.Header) -// require.NoError(t, err) -// stateRoot, err := st.HashTreeRoot(ctx) -// require.NoError(t, err) -// -// // get a new signed block so the root is updated with the new state root -// block.Block.StateRoot = stateRoot[:] -// signedBlock, err = blocks.NewSignedBeaconBlock(block) -// require.NoError(t, err) -// -// root, err := block.Block.HashTreeRoot() -// require.NoError(t, err) -// -// mockBlocker := &testutil.MockBlocker{ -// RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ -// parentRoot: signedParent, -// root: signedBlock, -// }, -// SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ -// slot.Sub(1): signedParent, -// slot: signedBlock, -// }, -// } -// mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st} -// s := &Server{ -// Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ -// slot.Sub(1): attestedState, -// slot: st, -// }}, -// Blocker: mockBlocker, -// HeadFetcher: mockChainService, -// } -// startPeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) -// count := 129 // config.MaxRequestLightClientUpdates is 128 -// url := fmt.Sprintf("http://foo.com/?count=%d&start_period=%d", count, startPeriod) -// request := httptest.NewRequest("GET", url, nil) -// writer := httptest.NewRecorder() -// writer.Body = &bytes.Buffer{} -// -// s.GetLightClientUpdatesByRange(writer, request) -// -// require.Equal(t, http.StatusOK, writer.Code) -// var resp structs.LightClientUpdatesByRangeResponse -// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) -// require.NoError(t, err) -// var respHeader structs.LightClientHeader -// err = json.Unmarshal(resp.Updates[0].Data.AttestedHeader, &respHeader) -// require.NoError(t, err) -// require.Equal(t, 1, len(resp.Updates)) // Even with big count input, the response is still the max available period, which is 1 in test case. -// require.Equal(t, "altair", resp.Updates[0].Version) -// require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot) -// require.NotNil(t, resp) -//} -// -//func TestLightClientHandler_GetLightClientUpdatesByRange_TooBigInputCountCapella(t *testing.T) { -// helpers.ClearCache() -// ctx := context.Background() -// config := params.BeaconConfig() -// slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) -// -// attestedState, err := util.NewBeaconStateCapella() -// require.NoError(t, err) -// err = attestedState.SetSlot(slot.Sub(1)) -// require.NoError(t, err) -// -// parent := util.NewBeaconBlockCapella() -// parent.Block.Slot = slot.Sub(1) -// -// signedParent, err := blocks.NewSignedBeaconBlock(parent) -// require.NoError(t, err) -// -// parentHeader, err := signedParent.Header() -// require.NoError(t, err) -// attestedHeader := parentHeader.Header -// -// err = attestedState.SetLatestBlockHeader(attestedHeader) -// require.NoError(t, err) -// attestedStateRoot, err := attestedState.HashTreeRoot(ctx) -// require.NoError(t, err) -// -// // get a new signed block so the root is updated with the new state root -// parent.Block.StateRoot = attestedStateRoot[:] -// signedParent, err = blocks.NewSignedBeaconBlock(parent) -// require.NoError(t, err) -// -// st, err := util.NewBeaconStateCapella() -// require.NoError(t, err) -// err = st.SetSlot(slot) -// require.NoError(t, err) -// -// parentRoot, err := signedParent.Block().HashTreeRoot() -// require.NoError(t, err) -// -// block := util.NewBeaconBlockCapella() -// block.Block.Slot = slot -// block.Block.ParentRoot = parentRoot[:] -// -// for i := uint64(0); i < config.SyncCommitteeSize; i++ { -// block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) -// } -// -// signedBlock, err := blocks.NewSignedBeaconBlock(block) -// require.NoError(t, err) -// -// h, err := signedBlock.Header() -// require.NoError(t, err) -// -// err = st.SetLatestBlockHeader(h.Header) -// require.NoError(t, err) -// stateRoot, err := st.HashTreeRoot(ctx) -// require.NoError(t, err) -// -// // get a new signed block so the root is updated with the new state root -// block.Block.StateRoot = stateRoot[:] -// signedBlock, err = blocks.NewSignedBeaconBlock(block) -// require.NoError(t, err) -// -// root, err := block.Block.HashTreeRoot() -// require.NoError(t, err) -// -// mockBlocker := &testutil.MockBlocker{ -// RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ -// parentRoot: signedParent, -// root: signedBlock, -// }, -// SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ -// slot.Sub(1): signedParent, -// slot: signedBlock, -// }, -// } -// mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st} -// s := &Server{ -// Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ -// slot.Sub(1): attestedState, -// slot: st, -// }}, -// Blocker: mockBlocker, -// HeadFetcher: mockChainService, -// } -// startPeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) -// count := 129 // config.MaxRequestLightClientUpdates is 128 -// url := fmt.Sprintf("http://foo.com/?count=%d&start_period=%d", count, startPeriod) -// request := httptest.NewRequest("GET", url, nil) -// writer := httptest.NewRecorder() -// writer.Body = &bytes.Buffer{} -// -// s.GetLightClientUpdatesByRange(writer, request) -// -// require.Equal(t, http.StatusOK, writer.Code) -// var resp structs.LightClientUpdatesByRangeResponse -// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) -// require.NoError(t, err) -// var respHeader structs.LightClientHeaderCapella -// err = json.Unmarshal(resp.Updates[0].Data.AttestedHeader, &respHeader) -// require.NoError(t, err) -// require.Equal(t, 1, len(resp.Updates)) // Even with big count input, the response is still the max available period, which is 1 in test case. -// require.Equal(t, "capella", resp.Updates[0].Version) -// require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot) -// require.NotNil(t, resp) -//} -// -//func TestLightClientHandler_GetLightClientUpdatesByRange_TooBigInputCountDeneb(t *testing.T) { -// helpers.ClearCache() -// ctx := context.Background() -// config := params.BeaconConfig() -// slot := primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) -// -// attestedState, err := util.NewBeaconStateDeneb() -// require.NoError(t, err) -// err = attestedState.SetSlot(slot.Sub(1)) -// require.NoError(t, err) -// -// parent := util.NewBeaconBlockDeneb() -// parent.Block.Slot = slot.Sub(1) -// -// signedParent, err := blocks.NewSignedBeaconBlock(parent) -// require.NoError(t, err) -// -// parentHeader, err := signedParent.Header() -// require.NoError(t, err) -// attestedHeader := parentHeader.Header -// -// err = attestedState.SetLatestBlockHeader(attestedHeader) -// require.NoError(t, err) -// attestedStateRoot, err := attestedState.HashTreeRoot(ctx) -// require.NoError(t, err) -// -// // get a new signed block so the root is updated with the new state root -// parent.Block.StateRoot = attestedStateRoot[:] -// signedParent, err = blocks.NewSignedBeaconBlock(parent) -// require.NoError(t, err) -// -// st, err := util.NewBeaconStateDeneb() -// require.NoError(t, err) -// err = st.SetSlot(slot) -// require.NoError(t, err) -// -// parentRoot, err := signedParent.Block().HashTreeRoot() -// require.NoError(t, err) -// -// block := util.NewBeaconBlockDeneb() -// block.Block.Slot = slot -// block.Block.ParentRoot = parentRoot[:] -// -// for i := uint64(0); i < config.SyncCommitteeSize; i++ { -// block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) -// } -// -// signedBlock, err := blocks.NewSignedBeaconBlock(block) -// require.NoError(t, err) -// -// h, err := signedBlock.Header() -// require.NoError(t, err) -// -// err = st.SetLatestBlockHeader(h.Header) -// require.NoError(t, err) -// stateRoot, err := st.HashTreeRoot(ctx) -// require.NoError(t, err) -// -// // get a new signed block so the root is updated with the new state root -// block.Block.StateRoot = stateRoot[:] -// signedBlock, err = blocks.NewSignedBeaconBlock(block) -// require.NoError(t, err) -// -// root, err := block.Block.HashTreeRoot() -// require.NoError(t, err) -// -// mockBlocker := &testutil.MockBlocker{ -// RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ -// parentRoot: signedParent, -// root: signedBlock, -// }, -// SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ -// slot.Sub(1): signedParent, -// slot: signedBlock, -// }, -// } -// mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st} -// s := &Server{ -// Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ -// slot.Sub(1): attestedState, -// slot: st, -// }}, -// Blocker: mockBlocker, -// HeadFetcher: mockChainService, -// } -// startPeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) -// count := 129 // config.MaxRequestLightClientUpdates is 128 -// url := fmt.Sprintf("http://foo.com/?count=%d&start_period=%d", count, startPeriod) -// request := httptest.NewRequest("GET", url, nil) -// writer := httptest.NewRecorder() -// writer.Body = &bytes.Buffer{} -// -// s.GetLightClientUpdatesByRange(writer, request) -// -// require.Equal(t, http.StatusOK, writer.Code) -// var resp structs.LightClientUpdatesByRangeResponse -// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) -// require.NoError(t, err) -// var respHeader structs.LightClientHeaderDeneb -// err = json.Unmarshal(resp.Updates[0].Data.AttestedHeader, &respHeader) -// require.NoError(t, err) -// require.Equal(t, 1, len(resp.Updates)) // Even with big count input, the response is still the max available period, which is 1 in test case. -// require.Equal(t, "deneb", resp.Updates[0].Version) -// require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot) -// require.NotNil(t, resp) -//} -// -//// TODO - check for not having any blocks from the min period, and startPeriod being too early -//func TestLightClientHandler_GetLightClientUpdatesByRange_TooEarlyPeriodAltair(t *testing.T) { -// helpers.ClearCache() -// ctx := context.Background() -// config := params.BeaconConfig() -// slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) -// -// attestedState, err := util.NewBeaconStateAltair() -// require.NoError(t, err) -// err = attestedState.SetSlot(slot.Sub(1)) -// require.NoError(t, err) -// -// parent := util.NewBeaconBlockAltair() -// parent.Block.Slot = slot.Sub(1) -// -// signedParent, err := blocks.NewSignedBeaconBlock(parent) -// require.NoError(t, err) -// -// parentHeader, err := signedParent.Header() -// require.NoError(t, err) -// attestedHeader := parentHeader.Header -// -// err = attestedState.SetLatestBlockHeader(attestedHeader) -// require.NoError(t, err) -// attestedStateRoot, err := attestedState.HashTreeRoot(ctx) -// require.NoError(t, err) -// -// // get a new signed block so the root is updated with the new state root -// parent.Block.StateRoot = attestedStateRoot[:] -// signedParent, err = blocks.NewSignedBeaconBlock(parent) -// require.NoError(t, err) -// -// st, err := util.NewBeaconStateAltair() -// require.NoError(t, err) -// err = st.SetSlot(slot) -// require.NoError(t, err) -// -// parentRoot, err := signedParent.Block().HashTreeRoot() -// require.NoError(t, err) -// -// block := util.NewBeaconBlockAltair() -// block.Block.Slot = slot -// block.Block.ParentRoot = parentRoot[:] -// -// for i := uint64(0); i < config.SyncCommitteeSize; i++ { -// block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) -// } -// -// signedBlock, err := blocks.NewSignedBeaconBlock(block) -// require.NoError(t, err) -// -// h, err := signedBlock.Header() -// require.NoError(t, err) -// -// err = st.SetLatestBlockHeader(h.Header) -// require.NoError(t, err) -// stateRoot, err := st.HashTreeRoot(ctx) -// require.NoError(t, err) -// -// // get a new signed block so the root is updated with the new state root -// block.Block.StateRoot = stateRoot[:] -// signedBlock, err = blocks.NewSignedBeaconBlock(block) -// require.NoError(t, err) -// -// root, err := block.Block.HashTreeRoot() -// require.NoError(t, err) -// -// mockBlocker := &testutil.MockBlocker{ -// RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ -// parentRoot: signedParent, -// root: signedBlock, -// }, -// SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ -// slot.Sub(1): signedParent, -// slot: signedBlock, -// }, -// } -// mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st} -// s := &Server{ -// Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ -// slot.Sub(1): attestedState, -// slot: st, -// }}, -// Blocker: mockBlocker, -// HeadFetcher: mockChainService, -// } -// startPeriod := 1 // very early period before Altair fork -// count := 1 -// url := fmt.Sprintf("http://foo.com/?count=%d&start_period=%d", count, startPeriod) -// request := httptest.NewRequest("GET", url, nil) -// writer := httptest.NewRecorder() -// writer.Body = &bytes.Buffer{} -// -// s.GetLightClientUpdatesByRange(writer, request) -// -// require.Equal(t, http.StatusOK, writer.Code) -// var resp structs.LightClientUpdatesByRangeResponse -// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) -// require.NoError(t, err) -// var respHeader structs.LightClientHeader -// err = json.Unmarshal(resp.Updates[0].Data.AttestedHeader, &respHeader) -// require.NoError(t, err) -// require.Equal(t, 1, len(resp.Updates)) -// require.Equal(t, "altair", resp.Updates[0].Version) -// require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot) -// require.NotNil(t, resp) -//} -// -//// TODO - same as above -//func TestLightClientHandler_GetLightClientUpdatesByRange_TooBigCountAltair(t *testing.T) { -// helpers.ClearCache() -// ctx := context.Background() -// config := params.BeaconConfig() -// slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) -// -// attestedState, err := util.NewBeaconStateAltair() -// require.NoError(t, err) -// err = attestedState.SetSlot(slot.Sub(1)) -// require.NoError(t, err) -// -// parent := util.NewBeaconBlockAltair() -// parent.Block.Slot = slot.Sub(1) -// -// signedParent, err := blocks.NewSignedBeaconBlock(parent) -// require.NoError(t, err) -// -// parentHeader, err := signedParent.Header() -// require.NoError(t, err) -// attestedHeader := parentHeader.Header -// -// err = attestedState.SetLatestBlockHeader(attestedHeader) -// require.NoError(t, err) -// attestedStateRoot, err := attestedState.HashTreeRoot(ctx) -// require.NoError(t, err) -// -// // get a new signed block so the root is updated with the new state root -// parent.Block.StateRoot = attestedStateRoot[:] -// signedParent, err = blocks.NewSignedBeaconBlock(parent) -// require.NoError(t, err) -// -// st, err := util.NewBeaconStateAltair() -// require.NoError(t, err) -// err = st.SetSlot(slot) -// require.NoError(t, err) -// -// parentRoot, err := signedParent.Block().HashTreeRoot() -// require.NoError(t, err) -// -// block := util.NewBeaconBlockAltair() -// block.Block.Slot = slot -// block.Block.ParentRoot = parentRoot[:] -// -// for i := uint64(0); i < config.SyncCommitteeSize; i++ { -// block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) -// } -// -// signedBlock, err := blocks.NewSignedBeaconBlock(block) -// require.NoError(t, err) -// -// h, err := signedBlock.Header() -// require.NoError(t, err) -// -// err = st.SetLatestBlockHeader(h.Header) -// require.NoError(t, err) -// stateRoot, err := st.HashTreeRoot(ctx) -// require.NoError(t, err) -// -// // get a new signed block so the root is updated with the new state root -// block.Block.StateRoot = stateRoot[:] -// signedBlock, err = blocks.NewSignedBeaconBlock(block) -// require.NoError(t, err) -// -// root, err := block.Block.HashTreeRoot() -// require.NoError(t, err) -// -// mockBlocker := &testutil.MockBlocker{ -// RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ -// parentRoot: signedParent, -// root: signedBlock, -// }, -// SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ -// slot.Sub(1): signedParent, -// slot: signedBlock, -// }, -// } -// mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st} -// s := &Server{ -// Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ -// slot.Sub(1): attestedState, -// slot: st, -// }}, -// Blocker: mockBlocker, -// HeadFetcher: mockChainService, -// } -// startPeriod := 1 // very early period before Altair fork -// count := 10 // This is big count as we only have one period in test case. -// url := fmt.Sprintf("http://foo.com/?count=%d&start_period=%d", count, startPeriod) -// request := httptest.NewRequest("GET", url, nil) -// writer := httptest.NewRecorder() -// writer.Body = &bytes.Buffer{} -// -// s.GetLightClientUpdatesByRange(writer, request) -// -// require.Equal(t, http.StatusOK, writer.Code) -// var resp structs.LightClientUpdatesByRangeResponse -// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) -// require.NoError(t, err) -// var respHeader structs.LightClientHeader -// err = json.Unmarshal(resp.Updates[0].Data.AttestedHeader, &respHeader) -// require.NoError(t, err) -// require.Equal(t, 1, len(resp.Updates)) -// require.Equal(t, "altair", resp.Updates[0].Version) -// require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot) -// require.NotNil(t, resp) -//} -// -//func TestLightClientHandler_GetLightClientUpdatesByRange_BeforeAltair(t *testing.T) { -// helpers.ClearCache() -// ctx := context.Background() -// config := params.BeaconConfig() -// slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Sub(1) -// -// attestedState, err := util.NewBeaconStateCapella() -// require.NoError(t, err) -// err = attestedState.SetSlot(slot.Sub(1)) -// require.NoError(t, err) -// -// parent := util.NewBeaconBlockCapella() -// parent.Block.Slot = slot.Sub(1) -// -// signedParent, err := blocks.NewSignedBeaconBlock(parent) -// require.NoError(t, err) -// -// parentHeader, err := signedParent.Header() -// require.NoError(t, err) -// attestedHeader := parentHeader.Header -// -// err = attestedState.SetLatestBlockHeader(attestedHeader) -// require.NoError(t, err) -// attestedStateRoot, err := attestedState.HashTreeRoot(ctx) -// require.NoError(t, err) -// -// // get a new signed block so the root is updated with the new state root -// parent.Block.StateRoot = attestedStateRoot[:] -// signedParent, err = blocks.NewSignedBeaconBlock(parent) -// require.NoError(t, err) -// -// st, err := util.NewBeaconStateCapella() -// require.NoError(t, err) -// err = st.SetSlot(slot) -// require.NoError(t, err) -// -// parentRoot, err := signedParent.Block().HashTreeRoot() -// require.NoError(t, err) -// -// block := util.NewBeaconBlockCapella() -// block.Block.Slot = slot -// block.Block.ParentRoot = parentRoot[:] -// -// for i := uint64(0); i < config.SyncCommitteeSize; i++ { -// block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) -// } -// -// signedBlock, err := blocks.NewSignedBeaconBlock(block) -// require.NoError(t, err) -// -// h, err := signedBlock.Header() -// require.NoError(t, err) -// -// err = st.SetLatestBlockHeader(h.Header) -// require.NoError(t, err) -// stateRoot, err := st.HashTreeRoot(ctx) -// require.NoError(t, err) -// -// // get a new signed block so the root is updated with the new state root -// block.Block.StateRoot = stateRoot[:] -// signedBlock, err = blocks.NewSignedBeaconBlock(block) -// require.NoError(t, err) -// -// root, err := block.Block.HashTreeRoot() -// require.NoError(t, err) -// -// mockBlocker := &testutil.MockBlocker{ -// RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ -// parentRoot: signedParent, -// root: signedBlock, -// }, -// SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ -// slot.Sub(1): signedParent, -// slot: signedBlock, -// }, -// } -// mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st} -// s := &Server{ -// Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ -// slot.Sub(1): attestedState, -// slot: st, -// }}, -// Blocker: mockBlocker, -// HeadFetcher: mockChainService, -// } -// startPeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) -// count := 1 -// url := fmt.Sprintf("http://foo.com/?count=%d&start_period=%d", count, startPeriod) -// request := httptest.NewRequest("GET", url, nil) -// writer := httptest.NewRecorder() -// writer.Body = &bytes.Buffer{} -// -// s.GetLightClientUpdatesByRange(writer, request) -// -// require.Equal(t, http.StatusNotFound, writer.Code) -//} +func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleAltair(t *testing.T) { + helpers.ClearCache() + ctx := context.Background() + config := params.BeaconConfig() + slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) + + st, err := util.NewBeaconStateAltair() + require.NoError(t, err) + headSlot := slot.Add(820000) + err = st.SetSlot(headSlot) + require.NoError(t, err) + + db := setupDB(t) + + updates := make([]*ethpbv2.LightClientUpdate, 100) + + updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) + + for i := 0; i < 100; i++ { + newSlot := slot.Add(uint64(i)) + + update := ðpbv2.LightClientUpdate{ + AttestedHeader: ðpbv2.LightClientHeaderContainer{ + Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ + HeaderAltair: ðpbv2.LightClientHeader{ + Beacon: ðpbv1.BeaconBlockHeader{ + Slot: newSlot, + ProposerIndex: 1, + ParentRoot: []byte{1, 1, 1}, + StateRoot: []byte{1, 1, 1}, + BodyRoot: []byte{1, 1, 1}, + }, + }, + }, + }, + NextSyncCommittee: ðpbv2.SyncCommittee{ + Pubkeys: nil, + AggregatePubkey: nil, + }, + NextSyncCommitteeBranch: nil, + FinalizedHeader: nil, + FinalityBranch: nil, + SyncAggregate: ðpbv1.SyncAggregate{ + SyncCommitteeBits: []byte{1, 1, 1}, + SyncCommitteeSignature: []byte{1, 1, 1}, + }, + SignatureSlot: 7, + } + + updates[i] = update + + err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ + Version: version.Altair, + Data: update, + }) + require.NoError(t, err) + + updatePeriod++ + } + + mockBlocker := &testutil.MockBlocker{} + mockChainService := &mock.ChainService{Optimistic: true, Slot: &headSlot, State: st} + s := &Server{ + Stater: &testutil.MockStater{}, + Blocker: mockBlocker, + HeadFetcher: mockChainService, + BeaconDB: db, + } + startPeriod := slot.Sub(1).Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) + url := fmt.Sprintf("http://foo.com/?count=100&start_period=%d", startPeriod) + request := httptest.NewRequest("GET", url, nil) + writer := httptest.NewRecorder() + writer.Body = &bytes.Buffer{} + + s.GetLightClientUpdatesByRange(writer, request) + + require.Equal(t, http.StatusOK, writer.Code) + var resp structs.LightClientUpdatesByRangeResponse + err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) + require.NoError(t, err) + require.Equal(t, 100, len(resp.Updates)) + require.NoError(t, err) + for i, update := range updates { + require.Equal(t, "altair", resp.Updates[i].Version) + updateJson, err := structs.LightClientUpdateFromConsensus(update) + require.NoError(t, err) + require.DeepEqual(t, updateJson, resp.Updates[i].Data) + } +} + +func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleCapella(t *testing.T) { + helpers.ClearCache() + ctx := context.Background() + config := params.BeaconConfig() + slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) + + st, err := util.NewBeaconStateAltair() + require.NoError(t, err) + headSlot := slot.Add(820000) + err = st.SetSlot(headSlot) + require.NoError(t, err) + + db := setupDB(t) + + updates := make([]*ethpbv2.LightClientUpdate, 100) + + updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) + + for i := 0; i < 100; i++ { + + newSlot := slot.Add(uint64(i)) + + update := ðpbv2.LightClientUpdate{ + AttestedHeader: ðpbv2.LightClientHeaderContainer{ + Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ + HeaderCapella: ðpbv2.LightClientHeaderCapella{ + Beacon: ðpbv1.BeaconBlockHeader{ + Slot: newSlot, + ProposerIndex: 1, + ParentRoot: []byte{1, 1, 1}, + StateRoot: []byte{1, 1, 1}, + BodyRoot: []byte{1, 1, 1}, + }, + Execution: &enginev1.ExecutionPayloadHeaderCapella{ + FeeRecipient: []byte{1, 2, 3}, + }, + ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, + }, + }, + }, + NextSyncCommittee: ðpbv2.SyncCommittee{ + Pubkeys: nil, + AggregatePubkey: nil, + }, + NextSyncCommitteeBranch: nil, + FinalizedHeader: ðpbv2.LightClientHeaderContainer{ + Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ + HeaderCapella: ðpbv2.LightClientHeaderCapella{ + Beacon: ðpbv1.BeaconBlockHeader{ + Slot: 12, + ProposerIndex: 1, + ParentRoot: []byte{1, 1, 1}, + StateRoot: []byte{1, 1, 1}, + BodyRoot: []byte{1, 1, 1}, + }, + Execution: &enginev1.ExecutionPayloadHeaderCapella{ + FeeRecipient: []byte{1, 2, 3}, + }, + ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, + }, + }, + }, + FinalityBranch: nil, + SyncAggregate: ðpbv1.SyncAggregate{ + SyncCommitteeBits: []byte{1, 1, 1}, + SyncCommitteeSignature: []byte{1, 1, 1}, + }, + SignatureSlot: 7, + } + + updates[i] = update + + err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ + Version: version.Capella, + Data: update, + }) + require.NoError(t, err) + + updatePeriod++ + } + + mockBlocker := &testutil.MockBlocker{} + mockChainService := &mock.ChainService{Optimistic: true, Slot: &headSlot, State: st} + s := &Server{ + Stater: &testutil.MockStater{}, + Blocker: mockBlocker, + HeadFetcher: mockChainService, + BeaconDB: db, + } + startPeriod := slot.Sub(1).Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) + url := fmt.Sprintf("http://foo.com/?count=100&start_period=%d", startPeriod) + request := httptest.NewRequest("GET", url, nil) + writer := httptest.NewRecorder() + writer.Body = &bytes.Buffer{} + + s.GetLightClientUpdatesByRange(writer, request) + + require.Equal(t, http.StatusOK, writer.Code) + var resp structs.LightClientUpdatesByRangeResponse + err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) + require.NoError(t, err) + require.Equal(t, 100, len(resp.Updates)) + require.NoError(t, err) + for i, update := range updates { + require.Equal(t, "capella", resp.Updates[i].Version) + updateJson, err := structs.LightClientUpdateFromConsensus(update) + require.NoError(t, err) + require.DeepEqual(t, updateJson, resp.Updates[i].Data) + } +} + +func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleDeneb(t *testing.T) { + helpers.ClearCache() + ctx := context.Background() + config := params.BeaconConfig() + slot := primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) + + st, err := util.NewBeaconStateAltair() + require.NoError(t, err) + headSlot := slot.Add(820000) + err = st.SetSlot(headSlot) + require.NoError(t, err) + + db := setupDB(t) + + updates := make([]*ethpbv2.LightClientUpdate, 100) + + updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) + + for i := 0; i < 100; i++ { + + newSlot := slot.Add(uint64(i)) + + update := ðpbv2.LightClientUpdate{ + AttestedHeader: ðpbv2.LightClientHeaderContainer{ + Header: ðpbv2.LightClientHeaderContainer_HeaderDeneb{ + HeaderDeneb: ðpbv2.LightClientHeaderDeneb{ + Beacon: ðpbv1.BeaconBlockHeader{ + Slot: newSlot, + ProposerIndex: 1, + ParentRoot: []byte{1, 1, 1}, + StateRoot: []byte{1, 1, 1}, + BodyRoot: []byte{1, 1, 1}, + }, + Execution: &enginev1.ExecutionPayloadHeaderDeneb{ + FeeRecipient: []byte{1, 2, 3}, + }, + ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, + }, + }, + }, + NextSyncCommittee: ðpbv2.SyncCommittee{ + Pubkeys: nil, + AggregatePubkey: nil, + }, + NextSyncCommitteeBranch: nil, + FinalizedHeader: ðpbv2.LightClientHeaderContainer{ + Header: ðpbv2.LightClientHeaderContainer_HeaderDeneb{ + HeaderDeneb: ðpbv2.LightClientHeaderDeneb{ + Beacon: ðpbv1.BeaconBlockHeader{ + Slot: 12, + ProposerIndex: 1, + ParentRoot: []byte{1, 1, 1}, + StateRoot: []byte{1, 1, 1}, + BodyRoot: []byte{1, 1, 1}, + }, + Execution: &enginev1.ExecutionPayloadHeaderDeneb{ + FeeRecipient: []byte{1, 2, 3}, + }, + ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, + }, + }, + }, + FinalityBranch: nil, + SyncAggregate: ðpbv1.SyncAggregate{ + SyncCommitteeBits: []byte{1, 1, 1}, + SyncCommitteeSignature: []byte{1, 1, 1}, + }, + SignatureSlot: 7, + } + + updates[i] = update + + err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ + Version: version.Deneb, + Data: update, + }) + require.NoError(t, err) + + updatePeriod++ + } + + mockBlocker := &testutil.MockBlocker{} + mockChainService := &mock.ChainService{Optimistic: true, Slot: &headSlot, State: st} + s := &Server{ + Stater: &testutil.MockStater{}, + Blocker: mockBlocker, + HeadFetcher: mockChainService, + BeaconDB: db, + } + startPeriod := slot.Sub(1).Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) + url := fmt.Sprintf("http://foo.com/?count=100&start_period=%d", startPeriod) + request := httptest.NewRequest("GET", url, nil) + writer := httptest.NewRecorder() + writer.Body = &bytes.Buffer{} + + s.GetLightClientUpdatesByRange(writer, request) + + require.Equal(t, http.StatusOK, writer.Code) + var resp structs.LightClientUpdatesByRangeResponse + err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) + require.NoError(t, err) + require.Equal(t, 100, len(resp.Updates)) + require.NoError(t, err) + for i, update := range updates { + require.Equal(t, "deneb", resp.Updates[i].Version) + updateJson, err := structs.LightClientUpdateFromConsensus(update) + require.NoError(t, err) + require.DeepEqual(t, updateJson, resp.Updates[i].Data) + } +} + +func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleForksAltairCapella(t *testing.T) { + helpers.ClearCache() + ctx := context.Background() + config := params.BeaconConfig() + slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) + + st, err := util.NewBeaconStateAltair() + require.NoError(t, err) + headSlot := slot.Add(820000) + err = st.SetSlot(headSlot) + require.NoError(t, err) + + db := setupDB(t) + + updates := make([]*ethpbv2.LightClientUpdate, 100) + + updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) + updatePeriod-- + for i := 1; i < 51; i++ { + + newSlot := slot.Sub(uint64(i)) + + update := ðpbv2.LightClientUpdate{ + AttestedHeader: ðpbv2.LightClientHeaderContainer{ + Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ + HeaderAltair: ðpbv2.LightClientHeader{ + Beacon: ðpbv1.BeaconBlockHeader{ + Slot: newSlot, + ProposerIndex: 1, + ParentRoot: []byte{1, 1, 1}, + StateRoot: []byte{1, 1, 1}, + BodyRoot: []byte{1, 1, 1}, + }, + }, + }, + }, + NextSyncCommittee: ðpbv2.SyncCommittee{ + Pubkeys: nil, + AggregatePubkey: nil, + }, + NextSyncCommitteeBranch: nil, + FinalizedHeader: ðpbv2.LightClientHeaderContainer{ + Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ + HeaderAltair: ðpbv2.LightClientHeader{ + Beacon: ðpbv1.BeaconBlockHeader{ + Slot: 12, + ProposerIndex: 1, + ParentRoot: []byte{1, 1, 1}, + StateRoot: []byte{1, 1, 1}, + BodyRoot: []byte{1, 1, 1}, + }, + }, + }, + }, + FinalityBranch: nil, + SyncAggregate: ðpbv1.SyncAggregate{ + SyncCommitteeBits: []byte{1, 1, 1}, + SyncCommitteeSignature: []byte{1, 1, 1}, + }, + SignatureSlot: newSlot, + } + + updates[50-i] = update + + err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ + Version: version.Altair, + Data: update, + }) + require.NoError(t, err) + + updatePeriod-- + } + + updatePeriod = slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) + + for i := 50; i < 100; i++ { + + newSlot := slot.Add(uint64(i)) + + update := ðpbv2.LightClientUpdate{ + AttestedHeader: ðpbv2.LightClientHeaderContainer{ + Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ + HeaderCapella: ðpbv2.LightClientHeaderCapella{ + Beacon: ðpbv1.BeaconBlockHeader{ + Slot: newSlot, + ProposerIndex: 1, + ParentRoot: []byte{1, 1, 1}, + StateRoot: []byte{1, 1, 1}, + BodyRoot: []byte{1, 1, 1}, + }, + Execution: &enginev1.ExecutionPayloadHeaderCapella{ + FeeRecipient: []byte{1, 2, 3}, + }, + ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, + }, + }, + }, + NextSyncCommittee: ðpbv2.SyncCommittee{ + Pubkeys: nil, + AggregatePubkey: nil, + }, + NextSyncCommitteeBranch: nil, + FinalizedHeader: ðpbv2.LightClientHeaderContainer{ + Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ + HeaderCapella: ðpbv2.LightClientHeaderCapella{ + Beacon: ðpbv1.BeaconBlockHeader{ + Slot: 12, + ProposerIndex: 1, + ParentRoot: []byte{1, 1, 1}, + StateRoot: []byte{1, 1, 1}, + BodyRoot: []byte{1, 1, 1}, + }, + Execution: &enginev1.ExecutionPayloadHeaderCapella{ + FeeRecipient: []byte{1, 2, 3}, + }, + ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, + }, + }, + }, + FinalityBranch: nil, + SyncAggregate: ðpbv1.SyncAggregate{ + SyncCommitteeBits: []byte{1, 1, 1}, + SyncCommitteeSignature: []byte{1, 1, 1}, + }, + SignatureSlot: newSlot, + } + + updates[i] = update + + err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ + Version: version.Capella, + Data: update, + }) + require.NoError(t, err) + + updatePeriod++ + } + + mockBlocker := &testutil.MockBlocker{} + mockChainService := &mock.ChainService{Optimistic: true, Slot: &headSlot, State: st} + s := &Server{ + Stater: &testutil.MockStater{}, + Blocker: mockBlocker, + HeadFetcher: mockChainService, + BeaconDB: db, + } + startPeriod := slot.Sub(1).Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) + url := fmt.Sprintf("http://foo.com/?count=100&start_period=%d", startPeriod.Sub(50)) + request := httptest.NewRequest("GET", url, nil) + writer := httptest.NewRecorder() + writer.Body = &bytes.Buffer{} + + s.GetLightClientUpdatesByRange(writer, request) + + require.Equal(t, http.StatusOK, writer.Code) + var resp structs.LightClientUpdatesByRangeResponse + err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) + require.NoError(t, err) + require.Equal(t, 100, len(resp.Updates)) + require.NoError(t, err) + for i, update := range updates { + if i < 50 { + require.Equal(t, "altair", resp.Updates[i].Version) + } else { + require.Equal(t, "capella", resp.Updates[i].Version) + } + updateJson, err := structs.LightClientUpdateFromConsensus(update) + require.NoError(t, err) + require.DeepEqual(t, updateJson, resp.Updates[i].Data) + } +} + +func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleForksCapellaDeneb(t *testing.T) { + helpers.ClearCache() + ctx := context.Background() + config := params.BeaconConfig() + slot := primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) + + st, err := util.NewBeaconStateAltair() + require.NoError(t, err) + headSlot := slot.Add(820000) + err = st.SetSlot(headSlot) + require.NoError(t, err) + + db := setupDB(t) + + updates := make([]*ethpbv2.LightClientUpdate, 100) + + updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) + updatePeriod-- + for i := 1; i < 51; i++ { + + newSlot := slot.Sub(uint64(i)) + + update := ðpbv2.LightClientUpdate{ + AttestedHeader: ðpbv2.LightClientHeaderContainer{ + Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ + HeaderCapella: ðpbv2.LightClientHeaderCapella{ + Beacon: ðpbv1.BeaconBlockHeader{ + Slot: newSlot, + ProposerIndex: 1, + ParentRoot: []byte{1, 1, 1}, + StateRoot: []byte{1, 1, 1}, + BodyRoot: []byte{1, 1, 1}, + }, + Execution: &enginev1.ExecutionPayloadHeaderCapella{ + FeeRecipient: []byte{1, 2, 3}, + }, + ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, + }, + }, + }, + NextSyncCommittee: ðpbv2.SyncCommittee{ + Pubkeys: nil, + AggregatePubkey: nil, + }, + NextSyncCommitteeBranch: nil, + FinalizedHeader: ðpbv2.LightClientHeaderContainer{ + Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ + HeaderCapella: ðpbv2.LightClientHeaderCapella{ + Beacon: ðpbv1.BeaconBlockHeader{ + Slot: 12, + ProposerIndex: 1, + ParentRoot: []byte{1, 1, 1}, + StateRoot: []byte{1, 1, 1}, + BodyRoot: []byte{1, 1, 1}, + }, + Execution: &enginev1.ExecutionPayloadHeaderCapella{ + FeeRecipient: []byte{1, 2, 3}, + }, + ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, + }, + }, + }, + FinalityBranch: nil, + SyncAggregate: ðpbv1.SyncAggregate{ + SyncCommitteeBits: []byte{1, 1, 1}, + SyncCommitteeSignature: []byte{1, 1, 1}, + }, + SignatureSlot: newSlot, + } + + updates[50-i] = update + + err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ + Version: version.Capella, + Data: update, + }) + require.NoError(t, err) + + updatePeriod-- + } + + updatePeriod = slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) + + for i := 50; i < 100; i++ { + + newSlot := slot.Add(uint64(i)) + + update := ðpbv2.LightClientUpdate{ + AttestedHeader: ðpbv2.LightClientHeaderContainer{ + Header: ðpbv2.LightClientHeaderContainer_HeaderDeneb{ + HeaderDeneb: ðpbv2.LightClientHeaderDeneb{ + Beacon: ðpbv1.BeaconBlockHeader{ + Slot: newSlot, + ProposerIndex: 1, + ParentRoot: []byte{1, 1, 1}, + StateRoot: []byte{1, 1, 1}, + BodyRoot: []byte{1, 1, 1}, + }, + Execution: &enginev1.ExecutionPayloadHeaderDeneb{ + FeeRecipient: []byte{1, 2, 3}, + }, + ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, + }, + }, + }, + NextSyncCommittee: ðpbv2.SyncCommittee{ + Pubkeys: nil, + AggregatePubkey: nil, + }, + NextSyncCommitteeBranch: nil, + FinalizedHeader: ðpbv2.LightClientHeaderContainer{ + Header: ðpbv2.LightClientHeaderContainer_HeaderDeneb{ + HeaderDeneb: ðpbv2.LightClientHeaderDeneb{ + Beacon: ðpbv1.BeaconBlockHeader{ + Slot: 12, + ProposerIndex: 1, + ParentRoot: []byte{1, 1, 1}, + StateRoot: []byte{1, 1, 1}, + BodyRoot: []byte{1, 1, 1}, + }, + Execution: &enginev1.ExecutionPayloadHeaderDeneb{ + FeeRecipient: []byte{1, 2, 3}, + }, + ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, + }, + }, + }, + FinalityBranch: nil, + SyncAggregate: ðpbv1.SyncAggregate{ + SyncCommitteeBits: []byte{1, 1, 1}, + SyncCommitteeSignature: []byte{1, 1, 1}, + }, + SignatureSlot: newSlot, + } + + updates[i] = update + + err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ + Version: version.Deneb, + Data: update, + }) + require.NoError(t, err) + + updatePeriod++ + } + + mockBlocker := &testutil.MockBlocker{} + mockChainService := &mock.ChainService{Optimistic: true, Slot: &headSlot, State: st} + s := &Server{ + Stater: &testutil.MockStater{}, + Blocker: mockBlocker, + HeadFetcher: mockChainService, + BeaconDB: db, + } + startPeriod := slot.Sub(1).Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) + url := fmt.Sprintf("http://foo.com/?count=100&start_period=%d", startPeriod.Sub(50)) + request := httptest.NewRequest("GET", url, nil) + writer := httptest.NewRecorder() + writer.Body = &bytes.Buffer{} + + s.GetLightClientUpdatesByRange(writer, request) + + require.Equal(t, http.StatusOK, writer.Code) + var resp structs.LightClientUpdatesByRangeResponse + err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) + require.NoError(t, err) + require.Equal(t, 100, len(resp.Updates)) + require.NoError(t, err) + for i, update := range updates { + if i < 50 { + require.Equal(t, "capella", resp.Updates[i].Version) + } else { + require.Equal(t, "deneb", resp.Updates[i].Version) + } + updateJson, err := structs.LightClientUpdateFromConsensus(update) + require.NoError(t, err) + require.DeepEqual(t, updateJson, resp.Updates[i].Data) + } +} + +func TestLightClientHandler_GetLightClientUpdatesByRangeCountBiggerThanLimit(t *testing.T) { + helpers.ClearCache() + ctx := context.Background() + config := params.BeaconConfig() + slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) + + st, err := util.NewBeaconStateAltair() + require.NoError(t, err) + headSlot := slot.Add(5000000) + err = st.SetSlot(headSlot) + require.NoError(t, err) + + db := setupDB(t) + + updates := make([]*ethpbv2.LightClientUpdate, 150) + + updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) + + for i := 0; i < 150; i++ { + newSlot := slot.Add(uint64(i)) + + update := ðpbv2.LightClientUpdate{ + AttestedHeader: ðpbv2.LightClientHeaderContainer{ + Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ + HeaderAltair: ðpbv2.LightClientHeader{ + Beacon: ðpbv1.BeaconBlockHeader{ + Slot: newSlot, + ProposerIndex: 1, + ParentRoot: []byte{1, 1, 1}, + StateRoot: []byte{1, 1, 1}, + BodyRoot: []byte{1, 1, 1}, + }, + }, + }, + }, + NextSyncCommittee: ðpbv2.SyncCommittee{ + Pubkeys: nil, + AggregatePubkey: nil, + }, + NextSyncCommitteeBranch: nil, + FinalizedHeader: nil, + FinalityBranch: nil, + SyncAggregate: ðpbv1.SyncAggregate{ + SyncCommitteeBits: []byte{1, 1, 1}, + SyncCommitteeSignature: []byte{1, 1, 1}, + }, + SignatureSlot: 7, + } + + updates[i] = update + + err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ + Version: version.Altair, + Data: update, + }) + require.NoError(t, err) + + updatePeriod++ + } + + mockBlocker := &testutil.MockBlocker{} + mockChainService := &mock.ChainService{Optimistic: true, Slot: &headSlot, State: st} + s := &Server{ + Stater: &testutil.MockStater{}, + Blocker: mockBlocker, + HeadFetcher: mockChainService, + BeaconDB: db, + } + startPeriod := slot.Sub(1).Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) + url := fmt.Sprintf("http://foo.com/?count=150&start_period=%d", startPeriod) + request := httptest.NewRequest("GET", url, nil) + writer := httptest.NewRecorder() + writer.Body = &bytes.Buffer{} + + s.GetLightClientUpdatesByRange(writer, request) + + require.Equal(t, http.StatusOK, writer.Code) + var resp structs.LightClientUpdatesByRangeResponse + err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) + require.NoError(t, err) + require.Equal(t, 128, len(resp.Updates)) + require.NoError(t, err) + for i, update := range updates { + if i < 128 { + require.Equal(t, "altair", resp.Updates[i].Version) + updateJson, err := structs.LightClientUpdateFromConsensus(update) + require.NoError(t, err) + require.DeepEqual(t, updateJson, resp.Updates[i].Data) + } + } +} + +func TestLightClientHandler_GetLightClientUpdatesByRangeCountBiggerThanMax(t *testing.T) { + helpers.ClearCache() + ctx := context.Background() + config := params.BeaconConfig() + slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) + + st, err := util.NewBeaconStateAltair() + require.NoError(t, err) + headSlot := slot.Add(900000) + err = st.SetSlot(headSlot) + require.NoError(t, err) + + db := setupDB(t) + + updates := make([]*ethpbv2.LightClientUpdate, 150) + + updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) + + for i := 0; i < 150; i++ { + newSlot := slot.Add(uint64(i)) + + update := ðpbv2.LightClientUpdate{ + AttestedHeader: ðpbv2.LightClientHeaderContainer{ + Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ + HeaderAltair: ðpbv2.LightClientHeader{ + Beacon: ðpbv1.BeaconBlockHeader{ + Slot: newSlot, + ProposerIndex: 1, + ParentRoot: []byte{1, 1, 1}, + StateRoot: []byte{1, 1, 1}, + BodyRoot: []byte{1, 1, 1}, + }, + }, + }, + }, + NextSyncCommittee: ðpbv2.SyncCommittee{ + Pubkeys: nil, + AggregatePubkey: nil, + }, + NextSyncCommitteeBranch: nil, + FinalizedHeader: nil, + FinalityBranch: nil, + SyncAggregate: ðpbv1.SyncAggregate{ + SyncCommitteeBits: []byte{1, 1, 1}, + SyncCommitteeSignature: []byte{1, 1, 1}, + }, + SignatureSlot: 7, + } + + updates[i] = update + + err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ + Version: version.Altair, + Data: update, + }) + require.NoError(t, err) + + updatePeriod++ + } + + mockBlocker := &testutil.MockBlocker{} + mockChainService := &mock.ChainService{Optimistic: true, Slot: &headSlot, State: st} + s := &Server{ + Stater: &testutil.MockStater{}, + Blocker: mockBlocker, + HeadFetcher: mockChainService, + BeaconDB: db, + } + startPeriod := slot.Sub(1).Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) + url := fmt.Sprintf("http://foo.com/?count=150&start_period=%d", startPeriod) + request := httptest.NewRequest("GET", url, nil) + writer := httptest.NewRecorder() + writer.Body = &bytes.Buffer{} + + s.GetLightClientUpdatesByRange(writer, request) + + maxSlot := slot.Add(900000).Div(uint64(config.SlotsPerEpoch)).Div(uint64(config.EpochsPerSyncCommitteePeriod)) + updatePeriod = slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) + diffSlots := maxSlot - updatePeriod + 1 + + require.Equal(t, http.StatusOK, writer.Code) + var resp structs.LightClientUpdatesByRangeResponse + err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) + require.NoError(t, err) + require.Equal(t, int(diffSlots), len(resp.Updates)) + require.NoError(t, err) + for i, update := range updates { + if i < int(diffSlots) { + require.Equal(t, "altair", resp.Updates[i].Version) + updateJson, err := structs.LightClientUpdateFromConsensus(update) + require.NoError(t, err) + require.DeepEqual(t, updateJson, resp.Updates[i].Data) + } + } +} + +func TestLightClientHandler_GetLightClientUpdatesByRangeStartPeriodBeforeAltair(t *testing.T) { + helpers.ClearCache() + ctx := context.Background() + config := params.BeaconConfig() + slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) + + st, err := util.NewBeaconStateAltair() + require.NoError(t, err) + headSlot := slot.Add(820000) + err = st.SetSlot(headSlot) + require.NoError(t, err) + + db := setupDB(t) + + updates := make([]*ethpbv2.LightClientUpdate, 100) + + updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) + + for i := 0; i < 100; i++ { + newSlot := slot.Add(uint64(i)) + + update := ðpbv2.LightClientUpdate{ + AttestedHeader: ðpbv2.LightClientHeaderContainer{ + Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ + HeaderAltair: ðpbv2.LightClientHeader{ + Beacon: ðpbv1.BeaconBlockHeader{ + Slot: newSlot, + ProposerIndex: 1, + ParentRoot: []byte{1, 1, 1}, + StateRoot: []byte{1, 1, 1}, + BodyRoot: []byte{1, 1, 1}, + }, + }, + }, + }, + NextSyncCommittee: ðpbv2.SyncCommittee{ + Pubkeys: nil, + AggregatePubkey: nil, + }, + NextSyncCommitteeBranch: nil, + FinalizedHeader: nil, + FinalityBranch: nil, + SyncAggregate: ðpbv1.SyncAggregate{ + SyncCommitteeBits: []byte{1, 1, 1}, + SyncCommitteeSignature: []byte{1, 1, 1}, + }, + SignatureSlot: 7, + } + + updates[i] = update + + err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ + Version: version.Altair, + Data: update, + }) + require.NoError(t, err) + + updatePeriod++ + } + + mockBlocker := &testutil.MockBlocker{} + mockChainService := &mock.ChainService{Optimistic: true, Slot: &headSlot, State: st} + s := &Server{ + Stater: &testutil.MockStater{}, + Blocker: mockBlocker, + HeadFetcher: mockChainService, + BeaconDB: db, + } + startPeriod := slot.Sub(1).Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) + url := fmt.Sprintf("http://foo.com/?count=100&start_period=%d", startPeriod-20) + request := httptest.NewRequest("GET", url, nil) + writer := httptest.NewRecorder() + writer.Body = &bytes.Buffer{} + + s.GetLightClientUpdatesByRange(writer, request) + + require.Equal(t, http.StatusOK, writer.Code) + var resp structs.LightClientUpdatesByRangeResponse + err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) + require.NoError(t, err) + require.Equal(t, 100, len(resp.Updates)) + require.NoError(t, err) + for i, update := range updates { + require.Equal(t, "altair", resp.Updates[i].Version) + updateJson, err := structs.LightClientUpdateFromConsensus(update) + require.NoError(t, err) + require.DeepEqual(t, updateJson, resp.Updates[i].Data) + } +} + +func TestLightClientHandler_GetLightClientUpdatesByRangeMissingUpdates(t *testing.T) { + helpers.ClearCache() + ctx := context.Background() + config := params.BeaconConfig() + slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) + + st, err := util.NewBeaconStateAltair() + require.NoError(t, err) + headSlot := slot.Add(820000) + err = st.SetSlot(headSlot) + require.NoError(t, err) + + db := setupDB(t) + + updates := make([]*ethpbv2.LightClientUpdate, 100) + + updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) + + validUpdatesLen := 70 + + for i := 0; i < 100; i++ { + if i == validUpdatesLen { // skip this update + updatePeriod++ + continue + } + newSlot := slot.Add(uint64(i)) + + update := ðpbv2.LightClientUpdate{ + AttestedHeader: ðpbv2.LightClientHeaderContainer{ + Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ + HeaderAltair: ðpbv2.LightClientHeader{ + Beacon: ðpbv1.BeaconBlockHeader{ + Slot: newSlot, + ProposerIndex: 1, + ParentRoot: []byte{1, 1, 1}, + StateRoot: []byte{1, 1, 1}, + BodyRoot: []byte{1, 1, 1}, + }, + }, + }, + }, + NextSyncCommittee: ðpbv2.SyncCommittee{ + Pubkeys: nil, + AggregatePubkey: nil, + }, + NextSyncCommitteeBranch: nil, + FinalizedHeader: nil, + FinalityBranch: nil, + SyncAggregate: ðpbv1.SyncAggregate{ + SyncCommitteeBits: []byte{1, 1, 1}, + SyncCommitteeSignature: []byte{1, 1, 1}, + }, + SignatureSlot: 7, + } + + updates[i] = update + + err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ + Version: version.Altair, + Data: update, + }) + require.NoError(t, err) + + updatePeriod++ + } + + mockBlocker := &testutil.MockBlocker{} + mockChainService := &mock.ChainService{Optimistic: true, Slot: &headSlot, State: st} + s := &Server{ + Stater: &testutil.MockStater{}, + Blocker: mockBlocker, + HeadFetcher: mockChainService, + BeaconDB: db, + } + startPeriod := slot.Sub(1).Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) + url := fmt.Sprintf("http://foo.com/?count=100&start_period=%d", startPeriod) + request := httptest.NewRequest("GET", url, nil) + writer := httptest.NewRecorder() + writer.Body = &bytes.Buffer{} + + s.GetLightClientUpdatesByRange(writer, request) + + require.Equal(t, http.StatusOK, writer.Code) + var resp structs.LightClientUpdatesByRangeResponse + err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) + require.NoError(t, err) + require.Equal(t, validUpdatesLen, len(resp.Updates)) + require.NoError(t, err) + for i, update := range updates { + if i < validUpdatesLen { + require.Equal(t, "altair", resp.Updates[i].Version) + updateJson, err := structs.LightClientUpdateFromConsensus(update) + require.NoError(t, err) + require.DeepEqual(t, updateJson, resp.Updates[i].Data) + } + } +} + +func TestLightClientHandler_GetLightClientUpdatesByRangeMissingUpdates2(t *testing.T) { + helpers.ClearCache() + ctx := context.Background() + config := params.BeaconConfig() + slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) + + st, err := util.NewBeaconStateAltair() + require.NoError(t, err) + headSlot := slot.Add(820000) + err = st.SetSlot(headSlot) + require.NoError(t, err) + + db := setupDB(t) + + updates := make([]*ethpbv2.LightClientUpdate, 100) + + updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) + + validUpdatesLen := 0 + + for i := 0; i < 100; i++ { + if i == validUpdatesLen { // skip this update + updatePeriod++ + continue + } + newSlot := slot.Add(uint64(i)) + + update := ðpbv2.LightClientUpdate{ + AttestedHeader: ðpbv2.LightClientHeaderContainer{ + Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ + HeaderAltair: ðpbv2.LightClientHeader{ + Beacon: ðpbv1.BeaconBlockHeader{ + Slot: newSlot, + ProposerIndex: 1, + ParentRoot: []byte{1, 1, 1}, + StateRoot: []byte{1, 1, 1}, + BodyRoot: []byte{1, 1, 1}, + }, + }, + }, + }, + NextSyncCommittee: ðpbv2.SyncCommittee{ + Pubkeys: nil, + AggregatePubkey: nil, + }, + NextSyncCommitteeBranch: nil, + FinalizedHeader: nil, + FinalityBranch: nil, + SyncAggregate: ðpbv1.SyncAggregate{ + SyncCommitteeBits: []byte{1, 1, 1}, + SyncCommitteeSignature: []byte{1, 1, 1}, + }, + SignatureSlot: 7, + } + + updates[i] = update + + err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ + Version: version.Altair, + Data: update, + }) + require.NoError(t, err) + + updatePeriod++ + } + + mockBlocker := &testutil.MockBlocker{} + mockChainService := &mock.ChainService{Optimistic: true, Slot: &headSlot, State: st} + s := &Server{ + Stater: &testutil.MockStater{}, + Blocker: mockBlocker, + HeadFetcher: mockChainService, + BeaconDB: db, + } + startPeriod := slot.Sub(1).Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) + url := fmt.Sprintf("http://foo.com/?count=100&start_period=%d", startPeriod) + request := httptest.NewRequest("GET", url, nil) + writer := httptest.NewRecorder() + writer.Body = &bytes.Buffer{} + + s.GetLightClientUpdatesByRange(writer, request) + + require.Equal(t, http.StatusOK, writer.Code) + var resp structs.LightClientUpdatesByRangeResponse + err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) + require.NoError(t, err) + require.Equal(t, validUpdatesLen, len(resp.Updates)) + require.NoError(t, err) + for i, update := range updates { + if i < validUpdatesLen { + require.Equal(t, "altair", resp.Updates[i].Version) + updateJson, err := structs.LightClientUpdateFromConsensus(update) + require.NoError(t, err) + require.DeepEqual(t, updateJson, resp.Updates[i].Data) + } + } +} + +// TestLightClientHandler_GetLightClientFinalityUpdate tests func TestLightClientHandler_GetLightClientFinalityUpdateAltair(t *testing.T) { helpers.ClearCache() From 3bef6f5f31de58cb7aca01aa13a23eab8c912b69 Mon Sep 17 00:00:00 2001 From: Inspector-Butters Date: Mon, 14 Oct 2024 13:21:06 +0200 Subject: [PATCH 06/35] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 878a96a0b17d..a794ff648501 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,6 +58,7 @@ The format is based on Keep a Changelog, and this project adheres to Semantic Ve - Make committee aware packing the default by deprecating `--enable-committee-aware-packing`. - Moved `ConvertKzgCommitmentToVersionedHash` to the `primitives` package. - reversed the boolean return on `BatchVerifyDepositsSignatures`, from need verification, to all keys successfully verified +- Changed `GetLightClientUpdatesByRange` API to read from the DB instead of computing. ### Deprecated - `--disable-grpc-gateway` flag is deprecated due to grpc gateway removal. From aff629f6e39877a51c7a41410386c1359b17652e Mon Sep 17 00:00:00 2001 From: Inspector-Butters Date: Mon, 14 Oct 2024 13:32:23 +0200 Subject: [PATCH 07/35] remove unused functions --- beacon-chain/rpc/eth/light-client/helpers.go | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/beacon-chain/rpc/eth/light-client/helpers.go b/beacon-chain/rpc/eth/light-client/helpers.go index ce989a7d5672..da19a591fd2e 100644 --- a/beacon-chain/rpc/eth/light-client/helpers.go +++ b/beacon-chain/rpc/eth/light-client/helpers.go @@ -245,22 +245,6 @@ func createLightClientBootstrapDeneb(ctx context.Context, state state.BeaconStat return result, nil } -func newLightClientUpdateFromBeaconState( - ctx context.Context, - state state.BeaconState, - block interfaces.ReadOnlySignedBeaconBlock, - attestedState state.BeaconState, - attestedBlock interfaces.ReadOnlySignedBeaconBlock, - finalizedBlock interfaces.ReadOnlySignedBeaconBlock, -) (*structs.LightClientUpdate, error) { - result, err := lightclient.NewLightClientUpdateFromBeaconState(ctx, state, block, attestedState, attestedBlock, finalizedBlock) - if err != nil { - return nil, err - } - - return structs.LightClientUpdateFromConsensus(result) -} - func newLightClientFinalityUpdateFromBeaconState( ctx context.Context, state state.BeaconState, From 2f16a91fef9e1b5d0f637f75a194d317d1b32c31 Mon Sep 17 00:00:00 2001 From: Bastin <43618253+Inspector-Butters@users.noreply.github.com> Date: Mon, 14 Oct 2024 17:49:29 +0200 Subject: [PATCH 08/35] Update beacon-chain/rpc/eth/light-client/handlers.go MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: RadosÅ‚aw Kapka --- beacon-chain/rpc/eth/light-client/handlers.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beacon-chain/rpc/eth/light-client/handlers.go b/beacon-chain/rpc/eth/light-client/handlers.go index fc81bcc57010..3ebc9134eb07 100644 --- a/beacon-chain/rpc/eth/light-client/handlers.go +++ b/beacon-chain/rpc/eth/light-client/handlers.go @@ -118,7 +118,7 @@ func (s *Server) GetLightClientUpdatesByRange(w http.ResponseWriter, req *http.R // get updates updatesMap, err := s.BeaconDB.LightClientUpdates(ctx, startPeriod, endPeriod) if err != nil { - httputil.HandleError(w, "could not get light client updates: "+err.Error(), http.StatusInternalServerError) + httputil.HandleError(w, "Could not get light client updates from DB: "+err.Error(), http.StatusInternalServerError) return } From 5caba412f80a50b99bf214f9e953f9ef7ec3bf96 Mon Sep 17 00:00:00 2001 From: Bastin <43618253+Inspector-Butters@users.noreply.github.com> Date: Mon, 14 Oct 2024 17:49:34 +0200 Subject: [PATCH 09/35] Update beacon-chain/rpc/eth/light-client/handlers.go MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: RadosÅ‚aw Kapka --- beacon-chain/rpc/eth/light-client/handlers.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beacon-chain/rpc/eth/light-client/handlers.go b/beacon-chain/rpc/eth/light-client/handlers.go index 3ebc9134eb07..055352731f30 100644 --- a/beacon-chain/rpc/eth/light-client/handlers.go +++ b/beacon-chain/rpc/eth/light-client/handlers.go @@ -133,7 +133,7 @@ func (s *Server) GetLightClientUpdatesByRange(w http.ResponseWriter, req *http.R updateResponse, err := structs.LightClientUpdateResponseFromConsensus(update) if err != nil { - httputil.HandleError(w, "could not convert light client update: "+err.Error(), http.StatusInternalServerError) + httputil.HandleError(w, "Could not convert light client update: "+err.Error(), http.StatusInternalServerError) return } From 4866873d277d3483f6101d4e49104d46df005ffd Mon Sep 17 00:00:00 2001 From: Inspector-Butters Date: Mon, 14 Oct 2024 18:00:29 +0200 Subject: [PATCH 10/35] use slice instead of array --- beacon-chain/rpc/eth/light-client/handlers.go | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/beacon-chain/rpc/eth/light-client/handlers.go b/beacon-chain/rpc/eth/light-client/handlers.go index 055352731f30..4dbce4fc01a3 100644 --- a/beacon-chain/rpc/eth/light-client/handlers.go +++ b/beacon-chain/rpc/eth/light-client/handlers.go @@ -122,9 +122,9 @@ func (s *Server) GetLightClientUpdatesByRange(w http.ResponseWriter, req *http.R return } - updates := make([]*structs.LightClientUpdateResponse, len(updatesMap)) - updatesCount := 0 - for i, j := startPeriod, 0; i <= endPeriod; i, j = i+1, j+1 { + updates := make([]*structs.LightClientUpdateResponse, 0, len(updatesMap)) + + for i := startPeriod; i <= endPeriod; i = i + 1 { update, ok := updatesMap[i] if !ok { // Only return the first contiguous range of updates @@ -137,11 +137,10 @@ func (s *Server) GetLightClientUpdatesByRange(w http.ResponseWriter, req *http.R return } - updates[j] = updateResponse - updatesCount++ + updates = append(updates, updateResponse) } - httputil.WriteJson(w, updates[:updatesCount]) + httputil.WriteJson(w, updates) } // GetLightClientFinalityUpdate - implements https://github.com/ethereum/beacon-APIs/blob/263f4ed6c263c967f13279c7a9f5629b51c5fc55/apis/beacon/light_client/finality_update.yaml From 2c4ea0bcd0e5dd0e2b0ff7c8ce492950ac917642 Mon Sep 17 00:00:00 2001 From: Mohamad Bastin Date: Tue, 15 Oct 2024 13:50:12 +0200 Subject: [PATCH 11/35] refactor code --- beacon-chain/rpc/eth/light-client/handlers.go | 2 +- beacon-chain/rpc/eth/light-client/handlers_test.go | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/beacon-chain/rpc/eth/light-client/handlers.go b/beacon-chain/rpc/eth/light-client/handlers.go index 4dbce4fc01a3..2df55fbad624 100644 --- a/beacon-chain/rpc/eth/light-client/handlers.go +++ b/beacon-chain/rpc/eth/light-client/handlers.go @@ -124,7 +124,7 @@ func (s *Server) GetLightClientUpdatesByRange(w http.ResponseWriter, req *http.R updates := make([]*structs.LightClientUpdateResponse, 0, len(updatesMap)) - for i := startPeriod; i <= endPeriod; i = i + 1 { + for i := startPeriod; i <= endPeriod; i++ { update, ok := updatesMap[i] if !ok { // Only return the first contiguous range of updates diff --git a/beacon-chain/rpc/eth/light-client/handlers_test.go b/beacon-chain/rpc/eth/light-client/handlers_test.go index 0b23c42c7bfc..1cabfef8656e 100644 --- a/beacon-chain/rpc/eth/light-client/handlers_test.go +++ b/beacon-chain/rpc/eth/light-client/handlers_test.go @@ -302,7 +302,6 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeAltair(t *testing.T) { err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) require.NoError(t, err) require.Equal(t, 1, len(resp.Updates)) - require.NoError(t, err) require.Equal(t, "altair", resp.Updates[0].Version) updateJson, err := structs.LightClientUpdateFromConsensus(update) require.NoError(t, err) @@ -399,7 +398,6 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeCapella(t *testing.T) { err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) require.NoError(t, err) require.Equal(t, 1, len(resp.Updates)) - require.NoError(t, err) require.Equal(t, "capella", resp.Updates[0].Version) updateJson, err := structs.LightClientUpdateFromConsensus(update) require.NoError(t, err) @@ -496,7 +494,6 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeDeneb(t *testing.T) { err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) require.NoError(t, err) require.Equal(t, 1, len(resp.Updates)) - require.NoError(t, err) require.Equal(t, "deneb", resp.Updates[0].Version) updateJson, err := structs.LightClientUpdateFromConsensus(update) require.NoError(t, err) @@ -584,7 +581,6 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleAltair(t *testin err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) require.NoError(t, err) require.Equal(t, 100, len(resp.Updates)) - require.NoError(t, err) for i, update := range updates { require.Equal(t, "altair", resp.Updates[i].Version) updateJson, err := structs.LightClientUpdateFromConsensus(update) From 9dab7a99f640fa9f67f42838c5fea9584fe0b52a Mon Sep 17 00:00:00 2001 From: Inspector-Butters Date: Wed, 16 Oct 2024 17:52:35 +0200 Subject: [PATCH 12/35] refactor tests --- beacon-chain/rpc/eth/light-client/handlers_test.go | 9 --------- 1 file changed, 9 deletions(-) diff --git a/beacon-chain/rpc/eth/light-client/handlers_test.go b/beacon-chain/rpc/eth/light-client/handlers_test.go index 1cabfef8656e..7483948e1ba7 100644 --- a/beacon-chain/rpc/eth/light-client/handlers_test.go +++ b/beacon-chain/rpc/eth/light-client/handlers_test.go @@ -691,7 +691,6 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleCapella(t *testi err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) require.NoError(t, err) require.Equal(t, 100, len(resp.Updates)) - require.NoError(t, err) for i, update := range updates { require.Equal(t, "capella", resp.Updates[i].Version) updateJson, err := structs.LightClientUpdateFromConsensus(update) @@ -802,7 +801,6 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleDeneb(t *testing err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) require.NoError(t, err) require.Equal(t, 100, len(resp.Updates)) - require.NoError(t, err) for i, update := range updates { require.Equal(t, "deneb", resp.Updates[i].Version) updateJson, err := structs.LightClientUpdateFromConsensus(update) @@ -970,7 +968,6 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleForksAltairCapel err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) require.NoError(t, err) require.Equal(t, 100, len(resp.Updates)) - require.NoError(t, err) for i, update := range updates { if i < 50 { require.Equal(t, "altair", resp.Updates[i].Version) @@ -1150,7 +1147,6 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleForksCapellaDene err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) require.NoError(t, err) require.Equal(t, 100, len(resp.Updates)) - require.NoError(t, err) for i, update := range updates { if i < 50 { require.Equal(t, "capella", resp.Updates[i].Version) @@ -1244,7 +1240,6 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeCountBiggerThanLimit(t * err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) require.NoError(t, err) require.Equal(t, 128, len(resp.Updates)) - require.NoError(t, err) for i, update := range updates { if i < 128 { require.Equal(t, "altair", resp.Updates[i].Version) @@ -1340,7 +1335,6 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeCountBiggerThanMax(t *te err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) require.NoError(t, err) require.Equal(t, int(diffSlots), len(resp.Updates)) - require.NoError(t, err) for i, update := range updates { if i < int(diffSlots) { require.Equal(t, "altair", resp.Updates[i].Version) @@ -1432,7 +1426,6 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeStartPeriodBeforeAltair( err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) require.NoError(t, err) require.Equal(t, 100, len(resp.Updates)) - require.NoError(t, err) for i, update := range updates { require.Equal(t, "altair", resp.Updates[i].Version) updateJson, err := structs.LightClientUpdateFromConsensus(update) @@ -1528,7 +1521,6 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeMissingUpdates(t *testin err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) require.NoError(t, err) require.Equal(t, validUpdatesLen, len(resp.Updates)) - require.NoError(t, err) for i, update := range updates { if i < validUpdatesLen { require.Equal(t, "altair", resp.Updates[i].Version) @@ -1626,7 +1618,6 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeMissingUpdates2(t *testi err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) require.NoError(t, err) require.Equal(t, validUpdatesLen, len(resp.Updates)) - require.NoError(t, err) for i, update := range updates { if i < validUpdatesLen { require.Equal(t, "altair", resp.Updates[i].Version) From 7427c303469681c5290bb981057fdcb2c99901ab Mon Sep 17 00:00:00 2001 From: Inspector-Butters Date: Thu, 17 Oct 2024 14:30:03 +0200 Subject: [PATCH 13/35] refactor tests --- .../rpc/eth/light-client/handlers_test.go | 737 +++++++++--------- 1 file changed, 351 insertions(+), 386 deletions(-) diff --git a/beacon-chain/rpc/eth/light-client/handlers_test.go b/beacon-chain/rpc/eth/light-client/handlers_test.go index 7483948e1ba7..7dc776752391 100644 --- a/beacon-chain/rpc/eth/light-client/handlers_test.go +++ b/beacon-chain/rpc/eth/light-client/handlers_test.go @@ -235,7 +235,12 @@ func TestLightClientHandler_GetLightClientBootstrap_Electra(t *testing.T) { func TestLightClientHandler_GetLightClientUpdatesByRangeAltair(t *testing.T) { helpers.ClearCache() ctx := context.Background() + + params.SetupTestConfigCleanup(t) config := params.BeaconConfig() + config.AltairForkEpoch = 0 + params.OverrideBeaconConfig(config) + slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) st, err := util.NewBeaconStateAltair() @@ -281,11 +286,8 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeAltair(t *testing.T) { }) require.NoError(t, err) - mockBlocker := &testutil.MockBlocker{} - mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st} + mockChainService := &mock.ChainService{State: st} s := &Server{ - Stater: &testutil.MockStater{}, - Blocker: mockBlocker, HeadFetcher: mockChainService, BeaconDB: db, } @@ -311,7 +313,11 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeAltair(t *testing.T) { func TestLightClientHandler_GetLightClientUpdatesByRangeCapella(t *testing.T) { helpers.ClearCache() ctx := context.Background() + params.SetupTestConfigCleanup(t) config := params.BeaconConfig() + config.AltairForkEpoch = 0 + config.CapellaForkEpoch = 1 + params.OverrideBeaconConfig(config) slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) st, err := util.NewBeaconStateCapella() @@ -377,11 +383,8 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeCapella(t *testing.T) { }) require.NoError(t, err) - mockBlocker := &testutil.MockBlocker{} - mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st} + mockChainService := &mock.ChainService{State: st} s := &Server{ - Stater: &testutil.MockStater{}, - Blocker: mockBlocker, HeadFetcher: mockChainService, BeaconDB: db, } @@ -407,7 +410,11 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeCapella(t *testing.T) { func TestLightClientHandler_GetLightClientUpdatesByRangeDeneb(t *testing.T) { helpers.ClearCache() ctx := context.Background() + params.SetupTestConfigCleanup(t) config := params.BeaconConfig() + config.AltairForkEpoch = 0 + config.DenebForkEpoch = 1 + params.OverrideBeaconConfig(config) slot := primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) st, err := util.NewBeaconStateDeneb() @@ -473,11 +480,8 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeDeneb(t *testing.T) { }) require.NoError(t, err) - mockBlocker := &testutil.MockBlocker{} - mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st} + mockChainService := &mock.ChainService{State: st} s := &Server{ - Stater: &testutil.MockStater{}, - Blocker: mockBlocker, HeadFetcher: mockChainService, BeaconDB: db, } @@ -503,22 +507,26 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeDeneb(t *testing.T) { func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleAltair(t *testing.T) { helpers.ClearCache() ctx := context.Background() + params.SetupTestConfigCleanup(t) config := params.BeaconConfig() + config.AltairForkEpoch = 0 + config.EpochsPerSyncCommitteePeriod = 1 + params.OverrideBeaconConfig(config) slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) st, err := util.NewBeaconStateAltair() require.NoError(t, err) - headSlot := slot.Add(820000) + headSlot := slot.Add(33) // 2 periods err = st.SetSlot(headSlot) require.NoError(t, err) db := setupDB(t) - updates := make([]*ethpbv2.LightClientUpdate, 100) + updates := make([]*ethpbv2.LightClientUpdate, 2) updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - for i := 0; i < 100; i++ { + for i := 0; i < 2; i++ { newSlot := slot.Add(uint64(i)) update := ðpbv2.LightClientUpdate{ @@ -560,11 +568,8 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleAltair(t *testin updatePeriod++ } - mockBlocker := &testutil.MockBlocker{} - mockChainService := &mock.ChainService{Optimistic: true, Slot: &headSlot, State: st} + mockChainService := &mock.ChainService{State: st} s := &Server{ - Stater: &testutil.MockStater{}, - Blocker: mockBlocker, HeadFetcher: mockChainService, BeaconDB: db, } @@ -580,7 +585,7 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleAltair(t *testin var resp structs.LightClientUpdatesByRangeResponse err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) require.NoError(t, err) - require.Equal(t, 100, len(resp.Updates)) + require.Equal(t, 2, len(resp.Updates)) for i, update := range updates { require.Equal(t, "altair", resp.Updates[i].Version) updateJson, err := structs.LightClientUpdateFromConsensus(update) @@ -592,22 +597,27 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleAltair(t *testin func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleCapella(t *testing.T) { helpers.ClearCache() ctx := context.Background() + params.SetupTestConfigCleanup(t) config := params.BeaconConfig() + config.AltairForkEpoch = 0 + config.CapellaForkEpoch = 1 + config.EpochsPerSyncCommitteePeriod = 1 + params.OverrideBeaconConfig(config) slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) st, err := util.NewBeaconStateAltair() require.NoError(t, err) - headSlot := slot.Add(820000) + headSlot := slot.Add(33) // 2 periods err = st.SetSlot(headSlot) require.NoError(t, err) db := setupDB(t) - updates := make([]*ethpbv2.LightClientUpdate, 100) + updates := make([]*ethpbv2.LightClientUpdate, 2) updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - for i := 0; i < 100; i++ { + for i := 0; i < 2; i++ { newSlot := slot.Add(uint64(i)) @@ -670,11 +680,8 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleCapella(t *testi updatePeriod++ } - mockBlocker := &testutil.MockBlocker{} - mockChainService := &mock.ChainService{Optimistic: true, Slot: &headSlot, State: st} + mockChainService := &mock.ChainService{State: st} s := &Server{ - Stater: &testutil.MockStater{}, - Blocker: mockBlocker, HeadFetcher: mockChainService, BeaconDB: db, } @@ -690,7 +697,7 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleCapella(t *testi var resp structs.LightClientUpdatesByRangeResponse err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) require.NoError(t, err) - require.Equal(t, 100, len(resp.Updates)) + require.Equal(t, 2, len(resp.Updates)) for i, update := range updates { require.Equal(t, "capella", resp.Updates[i].Version) updateJson, err := structs.LightClientUpdateFromConsensus(update) @@ -702,22 +709,27 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleCapella(t *testi func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleDeneb(t *testing.T) { helpers.ClearCache() ctx := context.Background() + params.SetupTestConfigCleanup(t) config := params.BeaconConfig() + config.AltairForkEpoch = 0 + config.DenebForkEpoch = 1 + config.EpochsPerSyncCommitteePeriod = 1 + params.OverrideBeaconConfig(config) slot := primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) st, err := util.NewBeaconStateAltair() require.NoError(t, err) - headSlot := slot.Add(820000) + headSlot := slot.Add(33) err = st.SetSlot(headSlot) require.NoError(t, err) db := setupDB(t) - updates := make([]*ethpbv2.LightClientUpdate, 100) + updates := make([]*ethpbv2.LightClientUpdate, 2) updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - for i := 0; i < 100; i++ { + for i := 0; i < 2; i++ { newSlot := slot.Add(uint64(i)) @@ -780,11 +792,8 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleDeneb(t *testing updatePeriod++ } - mockBlocker := &testutil.MockBlocker{} - mockChainService := &mock.ChainService{Optimistic: true, Slot: &headSlot, State: st} + mockChainService := &mock.ChainService{State: st} s := &Server{ - Stater: &testutil.MockStater{}, - Blocker: mockBlocker, HeadFetcher: mockChainService, BeaconDB: db, } @@ -800,7 +809,7 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleDeneb(t *testing var resp structs.LightClientUpdatesByRangeResponse err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) require.NoError(t, err) - require.Equal(t, 100, len(resp.Updates)) + require.Equal(t, 2, len(resp.Updates)) for i, update := range updates { require.Equal(t, "deneb", resp.Updates[i].Version) updateJson, err := structs.LightClientUpdateFromConsensus(update) @@ -812,151 +821,140 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleDeneb(t *testing func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleForksAltairCapella(t *testing.T) { helpers.ClearCache() ctx := context.Background() + params.SetupTestConfigCleanup(t) config := params.BeaconConfig() - slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) + config.AltairForkEpoch = 0 + config.CapellaForkEpoch = 1 + config.EpochsPerSyncCommitteePeriod = 1 + params.OverrideBeaconConfig(config) + slotCapella := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) + slotAltair := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) st, err := util.NewBeaconStateAltair() require.NoError(t, err) - headSlot := slot.Add(820000) + headSlot := slotCapella.Add(1) err = st.SetSlot(headSlot) require.NoError(t, err) db := setupDB(t) - updates := make([]*ethpbv2.LightClientUpdate, 100) - - updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - updatePeriod-- - for i := 1; i < 51; i++ { + updates := make([]*ethpbv2.LightClientUpdate, 2) - newSlot := slot.Sub(uint64(i)) + updatePeriod := slotAltair.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - update := ðpbv2.LightClientUpdate{ - AttestedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: ðpbv2.LightClientHeader{ - Beacon: ðpbv1.BeaconBlockHeader{ - Slot: newSlot, - ProposerIndex: 1, - ParentRoot: []byte{1, 1, 1}, - StateRoot: []byte{1, 1, 1}, - BodyRoot: []byte{1, 1, 1}, - }, + update := ðpbv2.LightClientUpdate{ + AttestedHeader: ðpbv2.LightClientHeaderContainer{ + Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ + HeaderAltair: ðpbv2.LightClientHeader{ + Beacon: ðpbv1.BeaconBlockHeader{ + Slot: slotAltair, + ProposerIndex: 1, + ParentRoot: []byte{1, 1, 1}, + StateRoot: []byte{1, 1, 1}, + BodyRoot: []byte{1, 1, 1}, }, }, }, - NextSyncCommittee: ðpbv2.SyncCommittee{ - Pubkeys: nil, - AggregatePubkey: nil, - }, - NextSyncCommitteeBranch: nil, - FinalizedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: ðpbv2.LightClientHeader{ - Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 12, - ProposerIndex: 1, - ParentRoot: []byte{1, 1, 1}, - StateRoot: []byte{1, 1, 1}, - BodyRoot: []byte{1, 1, 1}, - }, + }, + NextSyncCommittee: ðpbv2.SyncCommittee{ + Pubkeys: nil, + AggregatePubkey: nil, + }, + NextSyncCommitteeBranch: nil, + FinalizedHeader: ðpbv2.LightClientHeaderContainer{ + Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ + HeaderAltair: ðpbv2.LightClientHeader{ + Beacon: ðpbv1.BeaconBlockHeader{ + Slot: 12, + ProposerIndex: 1, + ParentRoot: []byte{1, 1, 1}, + StateRoot: []byte{1, 1, 1}, + BodyRoot: []byte{1, 1, 1}, }, }, }, - FinalityBranch: nil, - SyncAggregate: ðpbv1.SyncAggregate{ - SyncCommitteeBits: []byte{1, 1, 1}, - SyncCommitteeSignature: []byte{1, 1, 1}, - }, - SignatureSlot: newSlot, - } - - updates[50-i] = update - - err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ - Version: version.Altair, - Data: update, - }) - require.NoError(t, err) - - updatePeriod-- + }, + FinalityBranch: nil, + SyncAggregate: ðpbv1.SyncAggregate{ + SyncCommitteeBits: []byte{1, 1, 1}, + SyncCommitteeSignature: []byte{1, 1, 1}, + }, + SignatureSlot: slotAltair, } - updatePeriod = slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) + updates[0] = update - for i := 50; i < 100; i++ { + err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ + Version: version.Altair, + Data: update, + }) + require.NoError(t, err) - newSlot := slot.Add(uint64(i)) + updatePeriod = slotCapella.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - update := ðpbv2.LightClientUpdate{ - AttestedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ - HeaderCapella: ðpbv2.LightClientHeaderCapella{ - Beacon: ðpbv1.BeaconBlockHeader{ - Slot: newSlot, - ProposerIndex: 1, - ParentRoot: []byte{1, 1, 1}, - StateRoot: []byte{1, 1, 1}, - BodyRoot: []byte{1, 1, 1}, - }, - Execution: &enginev1.ExecutionPayloadHeaderCapella{ - FeeRecipient: []byte{1, 2, 3}, - }, - ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, + update = ðpbv2.LightClientUpdate{ + AttestedHeader: ðpbv2.LightClientHeaderContainer{ + Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ + HeaderCapella: ðpbv2.LightClientHeaderCapella{ + Beacon: ðpbv1.BeaconBlockHeader{ + Slot: slotCapella, + ProposerIndex: 1, + ParentRoot: []byte{1, 1, 1}, + StateRoot: []byte{1, 1, 1}, + BodyRoot: []byte{1, 1, 1}, + }, + Execution: &enginev1.ExecutionPayloadHeaderCapella{ + FeeRecipient: []byte{1, 2, 3}, }, + ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, }, }, - NextSyncCommittee: ðpbv2.SyncCommittee{ - Pubkeys: nil, - AggregatePubkey: nil, - }, - NextSyncCommitteeBranch: nil, - FinalizedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ - HeaderCapella: ðpbv2.LightClientHeaderCapella{ - Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 12, - ProposerIndex: 1, - ParentRoot: []byte{1, 1, 1}, - StateRoot: []byte{1, 1, 1}, - BodyRoot: []byte{1, 1, 1}, - }, - Execution: &enginev1.ExecutionPayloadHeaderCapella{ - FeeRecipient: []byte{1, 2, 3}, - }, - ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, + }, + NextSyncCommittee: ðpbv2.SyncCommittee{ + Pubkeys: nil, + AggregatePubkey: nil, + }, + NextSyncCommitteeBranch: nil, + FinalizedHeader: ðpbv2.LightClientHeaderContainer{ + Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ + HeaderCapella: ðpbv2.LightClientHeaderCapella{ + Beacon: ðpbv1.BeaconBlockHeader{ + Slot: 12, + ProposerIndex: 1, + ParentRoot: []byte{1, 1, 1}, + StateRoot: []byte{1, 1, 1}, + BodyRoot: []byte{1, 1, 1}, }, + Execution: &enginev1.ExecutionPayloadHeaderCapella{ + FeeRecipient: []byte{1, 2, 3}, + }, + ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, }, }, - FinalityBranch: nil, - SyncAggregate: ðpbv1.SyncAggregate{ - SyncCommitteeBits: []byte{1, 1, 1}, - SyncCommitteeSignature: []byte{1, 1, 1}, - }, - SignatureSlot: newSlot, - } - - updates[i] = update + }, + FinalityBranch: nil, + SyncAggregate: ðpbv1.SyncAggregate{ + SyncCommitteeBits: []byte{1, 1, 1}, + SyncCommitteeSignature: []byte{1, 1, 1}, + }, + SignatureSlot: slotCapella, + } - err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ - Version: version.Capella, - Data: update, - }) - require.NoError(t, err) + updates[1] = update - updatePeriod++ - } + err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ + Version: version.Capella, + Data: update, + }) + require.NoError(t, err) - mockBlocker := &testutil.MockBlocker{} - mockChainService := &mock.ChainService{Optimistic: true, Slot: &headSlot, State: st} + mockChainService := &mock.ChainService{State: st} s := &Server{ - Stater: &testutil.MockStater{}, - Blocker: mockBlocker, HeadFetcher: mockChainService, BeaconDB: db, } - startPeriod := slot.Sub(1).Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - url := fmt.Sprintf("http://foo.com/?count=100&start_period=%d", startPeriod.Sub(50)) + startPeriod := 0 + url := fmt.Sprintf("http://foo.com/?count=100&start_period=%d", startPeriod) request := httptest.NewRequest("GET", url, nil) writer := httptest.NewRecorder() writer.Body = &bytes.Buffer{} @@ -967,9 +965,9 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleForksAltairCapel var resp structs.LightClientUpdatesByRangeResponse err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) require.NoError(t, err) - require.Equal(t, 100, len(resp.Updates)) + require.Equal(t, 2, len(resp.Updates)) for i, update := range updates { - if i < 50 { + if i < 1 { require.Equal(t, "altair", resp.Updates[i].Version) } else { require.Equal(t, "capella", resp.Updates[i].Version) @@ -983,159 +981,149 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleForksAltairCapel func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleForksCapellaDeneb(t *testing.T) { helpers.ClearCache() ctx := context.Background() + params.SetupTestConfigCleanup(t) config := params.BeaconConfig() - slot := primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) + config.AltairForkEpoch = 0 + config.CapellaForkEpoch = 1 + config.DenebForkEpoch = 2 + config.EpochsPerSyncCommitteePeriod = 1 + params.OverrideBeaconConfig(config) + slotDeneb := primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) + slotCapella := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) st, err := util.NewBeaconStateAltair() require.NoError(t, err) - headSlot := slot.Add(820000) + headSlot := slotDeneb.Add(1) err = st.SetSlot(headSlot) require.NoError(t, err) db := setupDB(t) - updates := make([]*ethpbv2.LightClientUpdate, 100) + updates := make([]*ethpbv2.LightClientUpdate, 2) - updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - updatePeriod-- - for i := 1; i < 51; i++ { - - newSlot := slot.Sub(uint64(i)) + updatePeriod := slotCapella.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - update := ðpbv2.LightClientUpdate{ - AttestedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ - HeaderCapella: ðpbv2.LightClientHeaderCapella{ - Beacon: ðpbv1.BeaconBlockHeader{ - Slot: newSlot, - ProposerIndex: 1, - ParentRoot: []byte{1, 1, 1}, - StateRoot: []byte{1, 1, 1}, - BodyRoot: []byte{1, 1, 1}, - }, - Execution: &enginev1.ExecutionPayloadHeaderCapella{ - FeeRecipient: []byte{1, 2, 3}, - }, - ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, + update := ðpbv2.LightClientUpdate{ + AttestedHeader: ðpbv2.LightClientHeaderContainer{ + Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ + HeaderCapella: ðpbv2.LightClientHeaderCapella{ + Beacon: ðpbv1.BeaconBlockHeader{ + Slot: slotCapella, + ProposerIndex: 1, + ParentRoot: []byte{1, 1, 1}, + StateRoot: []byte{1, 1, 1}, + BodyRoot: []byte{1, 1, 1}, }, + Execution: &enginev1.ExecutionPayloadHeaderCapella{ + FeeRecipient: []byte{1, 2, 3}, + }, + ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, }, }, - NextSyncCommittee: ðpbv2.SyncCommittee{ - Pubkeys: nil, - AggregatePubkey: nil, - }, - NextSyncCommitteeBranch: nil, - FinalizedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ - HeaderCapella: ðpbv2.LightClientHeaderCapella{ - Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 12, - ProposerIndex: 1, - ParentRoot: []byte{1, 1, 1}, - StateRoot: []byte{1, 1, 1}, - BodyRoot: []byte{1, 1, 1}, - }, - Execution: &enginev1.ExecutionPayloadHeaderCapella{ - FeeRecipient: []byte{1, 2, 3}, - }, - ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, + }, + NextSyncCommittee: ðpbv2.SyncCommittee{ + Pubkeys: nil, + AggregatePubkey: nil, + }, + NextSyncCommitteeBranch: nil, + FinalizedHeader: ðpbv2.LightClientHeaderContainer{ + Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ + HeaderCapella: ðpbv2.LightClientHeaderCapella{ + Beacon: ðpbv1.BeaconBlockHeader{ + Slot: 12, + ProposerIndex: 1, + ParentRoot: []byte{1, 1, 1}, + StateRoot: []byte{1, 1, 1}, + BodyRoot: []byte{1, 1, 1}, + }, + Execution: &enginev1.ExecutionPayloadHeaderCapella{ + FeeRecipient: []byte{1, 2, 3}, }, + ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, }, }, - FinalityBranch: nil, - SyncAggregate: ðpbv1.SyncAggregate{ - SyncCommitteeBits: []byte{1, 1, 1}, - SyncCommitteeSignature: []byte{1, 1, 1}, - }, - SignatureSlot: newSlot, - } - - updates[50-i] = update - - err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ - Version: version.Capella, - Data: update, - }) - require.NoError(t, err) - - updatePeriod-- + }, + FinalityBranch: nil, + SyncAggregate: ðpbv1.SyncAggregate{ + SyncCommitteeBits: []byte{1, 1, 1}, + SyncCommitteeSignature: []byte{1, 1, 1}, + }, + SignatureSlot: slotCapella, } - updatePeriod = slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) + updates[0] = update - for i := 50; i < 100; i++ { + err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ + Version: version.Capella, + Data: update, + }) + require.NoError(t, err) - newSlot := slot.Add(uint64(i)) + updatePeriod = slotDeneb.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - update := ðpbv2.LightClientUpdate{ - AttestedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderDeneb{ - HeaderDeneb: ðpbv2.LightClientHeaderDeneb{ - Beacon: ðpbv1.BeaconBlockHeader{ - Slot: newSlot, - ProposerIndex: 1, - ParentRoot: []byte{1, 1, 1}, - StateRoot: []byte{1, 1, 1}, - BodyRoot: []byte{1, 1, 1}, - }, - Execution: &enginev1.ExecutionPayloadHeaderDeneb{ - FeeRecipient: []byte{1, 2, 3}, - }, - ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, + update = ðpbv2.LightClientUpdate{ + AttestedHeader: ðpbv2.LightClientHeaderContainer{ + Header: ðpbv2.LightClientHeaderContainer_HeaderDeneb{ + HeaderDeneb: ðpbv2.LightClientHeaderDeneb{ + Beacon: ðpbv1.BeaconBlockHeader{ + Slot: slotDeneb, + ProposerIndex: 1, + ParentRoot: []byte{1, 1, 1}, + StateRoot: []byte{1, 1, 1}, + BodyRoot: []byte{1, 1, 1}, + }, + Execution: &enginev1.ExecutionPayloadHeaderDeneb{ + FeeRecipient: []byte{1, 2, 3}, }, + ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, }, }, - NextSyncCommittee: ðpbv2.SyncCommittee{ - Pubkeys: nil, - AggregatePubkey: nil, - }, - NextSyncCommitteeBranch: nil, - FinalizedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderDeneb{ - HeaderDeneb: ðpbv2.LightClientHeaderDeneb{ - Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 12, - ProposerIndex: 1, - ParentRoot: []byte{1, 1, 1}, - StateRoot: []byte{1, 1, 1}, - BodyRoot: []byte{1, 1, 1}, - }, - Execution: &enginev1.ExecutionPayloadHeaderDeneb{ - FeeRecipient: []byte{1, 2, 3}, - }, - ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, + }, + NextSyncCommittee: ðpbv2.SyncCommittee{ + Pubkeys: nil, + AggregatePubkey: nil, + }, + NextSyncCommitteeBranch: nil, + FinalizedHeader: ðpbv2.LightClientHeaderContainer{ + Header: ðpbv2.LightClientHeaderContainer_HeaderDeneb{ + HeaderDeneb: ðpbv2.LightClientHeaderDeneb{ + Beacon: ðpbv1.BeaconBlockHeader{ + Slot: 12, + ProposerIndex: 1, + ParentRoot: []byte{1, 1, 1}, + StateRoot: []byte{1, 1, 1}, + BodyRoot: []byte{1, 1, 1}, }, + Execution: &enginev1.ExecutionPayloadHeaderDeneb{ + FeeRecipient: []byte{1, 2, 3}, + }, + ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, }, }, - FinalityBranch: nil, - SyncAggregate: ðpbv1.SyncAggregate{ - SyncCommitteeBits: []byte{1, 1, 1}, - SyncCommitteeSignature: []byte{1, 1, 1}, - }, - SignatureSlot: newSlot, - } - - updates[i] = update + }, + FinalityBranch: nil, + SyncAggregate: ðpbv1.SyncAggregate{ + SyncCommitteeBits: []byte{1, 1, 1}, + SyncCommitteeSignature: []byte{1, 1, 1}, + }, + SignatureSlot: slotDeneb, + } - err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ - Version: version.Deneb, - Data: update, - }) - require.NoError(t, err) + updates[1] = update - updatePeriod++ - } + err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ + Version: version.Deneb, + Data: update, + }) + require.NoError(t, err) - mockBlocker := &testutil.MockBlocker{} - mockChainService := &mock.ChainService{Optimistic: true, Slot: &headSlot, State: st} + mockChainService := &mock.ChainService{State: st} s := &Server{ - Stater: &testutil.MockStater{}, - Blocker: mockBlocker, HeadFetcher: mockChainService, BeaconDB: db, } - startPeriod := slot.Sub(1).Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - url := fmt.Sprintf("http://foo.com/?count=100&start_period=%d", startPeriod.Sub(50)) + startPeriod := 1 + url := fmt.Sprintf("http://foo.com/?count=100&start_period=%d", startPeriod) request := httptest.NewRequest("GET", url, nil) writer := httptest.NewRecorder() writer.Body = &bytes.Buffer{} @@ -1146,9 +1134,9 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleForksCapellaDene var resp structs.LightClientUpdatesByRangeResponse err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) require.NoError(t, err) - require.Equal(t, 100, len(resp.Updates)) + require.Equal(t, 2, len(resp.Updates)) for i, update := range updates { - if i < 50 { + if i < 1 { require.Equal(t, "capella", resp.Updates[i].Version) } else { require.Equal(t, "deneb", resp.Updates[i].Version) @@ -1162,23 +1150,28 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleForksCapellaDene func TestLightClientHandler_GetLightClientUpdatesByRangeCountBiggerThanLimit(t *testing.T) { helpers.ClearCache() ctx := context.Background() + params.SetupTestConfigCleanup(t) config := params.BeaconConfig() + config.AltairForkEpoch = 0 + config.EpochsPerSyncCommitteePeriod = 1 + config.MaxRequestLightClientUpdates = 2 + params.OverrideBeaconConfig(config) slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) st, err := util.NewBeaconStateAltair() require.NoError(t, err) - headSlot := slot.Add(5000000) + headSlot := slot.Add(65) err = st.SetSlot(headSlot) require.NoError(t, err) db := setupDB(t) - updates := make([]*ethpbv2.LightClientUpdate, 150) + updates := make([]*ethpbv2.LightClientUpdate, 3) updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - for i := 0; i < 150; i++ { - newSlot := slot.Add(uint64(i)) + for i := 0; i < 3; i++ { + newSlot := slot.Add(uint64(i * 32)) update := ðpbv2.LightClientUpdate{ AttestedHeader: ðpbv2.LightClientHeaderContainer{ @@ -1219,16 +1212,13 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeCountBiggerThanLimit(t * updatePeriod++ } - mockBlocker := &testutil.MockBlocker{} - mockChainService := &mock.ChainService{Optimistic: true, Slot: &headSlot, State: st} + mockChainService := &mock.ChainService{State: st} s := &Server{ - Stater: &testutil.MockStater{}, - Blocker: mockBlocker, HeadFetcher: mockChainService, BeaconDB: db, } - startPeriod := slot.Sub(1).Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - url := fmt.Sprintf("http://foo.com/?count=150&start_period=%d", startPeriod) + startPeriod := 0 + url := fmt.Sprintf("http://foo.com/?count=4&start_period=%d", startPeriod) request := httptest.NewRequest("GET", url, nil) writer := httptest.NewRecorder() writer.Body = &bytes.Buffer{} @@ -1239,9 +1229,9 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeCountBiggerThanLimit(t * var resp structs.LightClientUpdatesByRangeResponse err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) require.NoError(t, err) - require.Equal(t, 128, len(resp.Updates)) + require.Equal(t, 2, len(resp.Updates)) for i, update := range updates { - if i < 128 { + if i < 2 { require.Equal(t, "altair", resp.Updates[i].Version) updateJson, err := structs.LightClientUpdateFromConsensus(update) require.NoError(t, err) @@ -1253,23 +1243,28 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeCountBiggerThanLimit(t * func TestLightClientHandler_GetLightClientUpdatesByRangeCountBiggerThanMax(t *testing.T) { helpers.ClearCache() ctx := context.Background() + params.SetupTestConfigCleanup(t) config := params.BeaconConfig() + config.AltairForkEpoch = 0 + config.EpochsPerSyncCommitteePeriod = 1 + config.MaxRequestLightClientUpdates = 2 + params.OverrideBeaconConfig(config) slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) st, err := util.NewBeaconStateAltair() require.NoError(t, err) - headSlot := slot.Add(900000) + headSlot := slot.Add(65) err = st.SetSlot(headSlot) require.NoError(t, err) db := setupDB(t) - updates := make([]*ethpbv2.LightClientUpdate, 150) + updates := make([]*ethpbv2.LightClientUpdate, 3) updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - for i := 0; i < 150; i++ { - newSlot := slot.Add(uint64(i)) + for i := 0; i < 3; i++ { + newSlot := slot.Add(uint64(i * 32)) update := ðpbv2.LightClientUpdate{ AttestedHeader: ðpbv2.LightClientHeaderContainer{ @@ -1300,7 +1295,6 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeCountBiggerThanMax(t *te } updates[i] = update - err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ Version: version.Altair, Data: update, @@ -1310,33 +1304,26 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeCountBiggerThanMax(t *te updatePeriod++ } - mockBlocker := &testutil.MockBlocker{} - mockChainService := &mock.ChainService{Optimistic: true, Slot: &headSlot, State: st} + mockChainService := &mock.ChainService{State: st} s := &Server{ - Stater: &testutil.MockStater{}, - Blocker: mockBlocker, HeadFetcher: mockChainService, BeaconDB: db, } - startPeriod := slot.Sub(1).Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - url := fmt.Sprintf("http://foo.com/?count=150&start_period=%d", startPeriod) + startPeriod := 0 + url := fmt.Sprintf("http://foo.com/?count=10&start_period=%d", startPeriod) request := httptest.NewRequest("GET", url, nil) writer := httptest.NewRecorder() writer.Body = &bytes.Buffer{} s.GetLightClientUpdatesByRange(writer, request) - maxSlot := slot.Add(900000).Div(uint64(config.SlotsPerEpoch)).Div(uint64(config.EpochsPerSyncCommitteePeriod)) - updatePeriod = slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - diffSlots := maxSlot - updatePeriod + 1 - require.Equal(t, http.StatusOK, writer.Code) var resp structs.LightClientUpdatesByRangeResponse err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) require.NoError(t, err) - require.Equal(t, int(diffSlots), len(resp.Updates)) + require.Equal(t, 2, len(resp.Updates)) for i, update := range updates { - if i < int(diffSlots) { + if i < 2 { require.Equal(t, "altair", resp.Updates[i].Version) updateJson, err := structs.LightClientUpdateFromConsensus(update) require.NoError(t, err) @@ -1349,72 +1336,62 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeStartPeriodBeforeAltair( helpers.ClearCache() ctx := context.Background() config := params.BeaconConfig() + config.AltairForkEpoch = 1 + config.EpochsPerSyncCommitteePeriod = 1 + params.OverrideBeaconConfig(config) slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) st, err := util.NewBeaconStateAltair() require.NoError(t, err) - headSlot := slot.Add(820000) + headSlot := slot.Add(1) err = st.SetSlot(headSlot) require.NoError(t, err) db := setupDB(t) - updates := make([]*ethpbv2.LightClientUpdate, 100) - updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - for i := 0; i < 100; i++ { - newSlot := slot.Add(uint64(i)) - - update := ðpbv2.LightClientUpdate{ - AttestedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: ðpbv2.LightClientHeader{ - Beacon: ðpbv1.BeaconBlockHeader{ - Slot: newSlot, - ProposerIndex: 1, - ParentRoot: []byte{1, 1, 1}, - StateRoot: []byte{1, 1, 1}, - BodyRoot: []byte{1, 1, 1}, - }, + update := ðpbv2.LightClientUpdate{ + AttestedHeader: ðpbv2.LightClientHeaderContainer{ + Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ + HeaderAltair: ðpbv2.LightClientHeader{ + Beacon: ðpbv1.BeaconBlockHeader{ + Slot: slot, + ProposerIndex: 1, + ParentRoot: []byte{1, 1, 1}, + StateRoot: []byte{1, 1, 1}, + BodyRoot: []byte{1, 1, 1}, }, }, }, - NextSyncCommittee: ðpbv2.SyncCommittee{ - Pubkeys: nil, - AggregatePubkey: nil, - }, - NextSyncCommitteeBranch: nil, - FinalizedHeader: nil, - FinalityBranch: nil, - SyncAggregate: ðpbv1.SyncAggregate{ - SyncCommitteeBits: []byte{1, 1, 1}, - SyncCommitteeSignature: []byte{1, 1, 1}, - }, - SignatureSlot: 7, - } - - updates[i] = update - - err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ - Version: version.Altair, - Data: update, - }) - require.NoError(t, err) - - updatePeriod++ + }, + NextSyncCommittee: ðpbv2.SyncCommittee{ + Pubkeys: nil, + AggregatePubkey: nil, + }, + NextSyncCommitteeBranch: nil, + FinalizedHeader: nil, + FinalityBranch: nil, + SyncAggregate: ðpbv1.SyncAggregate{ + SyncCommitteeBits: []byte{1, 1, 1}, + SyncCommitteeSignature: []byte{1, 1, 1}, + }, + SignatureSlot: 7, } - mockBlocker := &testutil.MockBlocker{} - mockChainService := &mock.ChainService{Optimistic: true, Slot: &headSlot, State: st} + err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ + Version: version.Altair, + Data: update, + }) + require.NoError(t, err) + + mockChainService := &mock.ChainService{State: st} s := &Server{ - Stater: &testutil.MockStater{}, - Blocker: mockBlocker, HeadFetcher: mockChainService, BeaconDB: db, } - startPeriod := slot.Sub(1).Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - url := fmt.Sprintf("http://foo.com/?count=100&start_period=%d", startPeriod-20) + startPeriod := 0 + url := fmt.Sprintf("http://foo.com/?count=2&start_period=%d", startPeriod) request := httptest.NewRequest("GET", url, nil) writer := httptest.NewRecorder() writer.Body = &bytes.Buffer{} @@ -1425,41 +1402,42 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeStartPeriodBeforeAltair( var resp structs.LightClientUpdatesByRangeResponse err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) require.NoError(t, err) - require.Equal(t, 100, len(resp.Updates)) - for i, update := range updates { - require.Equal(t, "altair", resp.Updates[i].Version) - updateJson, err := structs.LightClientUpdateFromConsensus(update) - require.NoError(t, err) - require.DeepEqual(t, updateJson, resp.Updates[i].Data) - } + require.Equal(t, 1, len(resp.Updates)) + + require.Equal(t, "altair", resp.Updates[0].Version) + updateJson, err := structs.LightClientUpdateFromConsensus(update) + require.NoError(t, err) + require.DeepEqual(t, updateJson, resp.Updates[0].Data) + } func TestLightClientHandler_GetLightClientUpdatesByRangeMissingUpdates(t *testing.T) { helpers.ClearCache() ctx := context.Background() config := params.BeaconConfig() + config.AltairForkEpoch = 0 + config.EpochsPerSyncCommitteePeriod = 1 + params.OverrideBeaconConfig(config) slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) st, err := util.NewBeaconStateAltair() require.NoError(t, err) - headSlot := slot.Add(820000) + headSlot := slot.Add(65) err = st.SetSlot(headSlot) require.NoError(t, err) db := setupDB(t) - updates := make([]*ethpbv2.LightClientUpdate, 100) + updates := make([]*ethpbv2.LightClientUpdate, 3) updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - validUpdatesLen := 70 - - for i := 0; i < 100; i++ { - if i == validUpdatesLen { // skip this update + for i := 0; i < 3; i++ { + if i == 1 { // skip this update updatePeriod++ continue } - newSlot := slot.Add(uint64(i)) + newSlot := slot.Add(uint64(i * 32)) update := ðpbv2.LightClientUpdate{ AttestedHeader: ðpbv2.LightClientHeaderContainer{ @@ -1500,16 +1478,13 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeMissingUpdates(t *testin updatePeriod++ } - mockBlocker := &testutil.MockBlocker{} - mockChainService := &mock.ChainService{Optimistic: true, Slot: &headSlot, State: st} + mockChainService := &mock.ChainService{State: st} s := &Server{ - Stater: &testutil.MockStater{}, - Blocker: mockBlocker, HeadFetcher: mockChainService, BeaconDB: db, } - startPeriod := slot.Sub(1).Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - url := fmt.Sprintf("http://foo.com/?count=100&start_period=%d", startPeriod) + startPeriod := 0 + url := fmt.Sprintf("http://foo.com/?count=10&start_period=%d", startPeriod) request := httptest.NewRequest("GET", url, nil) writer := httptest.NewRecorder() writer.Body = &bytes.Buffer{} @@ -1520,9 +1495,9 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeMissingUpdates(t *testin var resp structs.LightClientUpdatesByRangeResponse err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) require.NoError(t, err) - require.Equal(t, validUpdatesLen, len(resp.Updates)) + require.Equal(t, 1, len(resp.Updates)) for i, update := range updates { - if i < validUpdatesLen { + if i < 1 { require.Equal(t, "altair", resp.Updates[i].Version) updateJson, err := structs.LightClientUpdateFromConsensus(update) require.NoError(t, err) @@ -1535,24 +1510,25 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeMissingUpdates2(t *testi helpers.ClearCache() ctx := context.Background() config := params.BeaconConfig() + config.AltairForkEpoch = 0 + config.EpochsPerSyncCommitteePeriod = 1 + params.OverrideBeaconConfig(config) slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) st, err := util.NewBeaconStateAltair() require.NoError(t, err) - headSlot := slot.Add(820000) + headSlot := slot.Add(65) err = st.SetSlot(headSlot) require.NoError(t, err) db := setupDB(t) - updates := make([]*ethpbv2.LightClientUpdate, 100) + updates := make([]*ethpbv2.LightClientUpdate, 3) updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - validUpdatesLen := 0 - - for i := 0; i < 100; i++ { - if i == validUpdatesLen { // skip this update + for i := 0; i < 3; i++ { + if i == 0 { // skip this update updatePeriod++ continue } @@ -1597,16 +1573,13 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeMissingUpdates2(t *testi updatePeriod++ } - mockBlocker := &testutil.MockBlocker{} - mockChainService := &mock.ChainService{Optimistic: true, Slot: &headSlot, State: st} + mockChainService := &mock.ChainService{State: st} s := &Server{ - Stater: &testutil.MockStater{}, - Blocker: mockBlocker, HeadFetcher: mockChainService, BeaconDB: db, } - startPeriod := slot.Sub(1).Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - url := fmt.Sprintf("http://foo.com/?count=100&start_period=%d", startPeriod) + startPeriod := 0 + url := fmt.Sprintf("http://foo.com/?count=10&start_period=%d", startPeriod) request := httptest.NewRequest("GET", url, nil) writer := httptest.NewRecorder() writer.Body = &bytes.Buffer{} @@ -1617,15 +1590,7 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeMissingUpdates2(t *testi var resp structs.LightClientUpdatesByRangeResponse err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) require.NoError(t, err) - require.Equal(t, validUpdatesLen, len(resp.Updates)) - for i, update := range updates { - if i < validUpdatesLen { - require.Equal(t, "altair", resp.Updates[i].Version) - updateJson, err := structs.LightClientUpdateFromConsensus(update) - require.NoError(t, err) - require.DeepEqual(t, updateJson, resp.Updates[i].Data) - } - } + require.Equal(t, 0, len(resp.Updates)) } // TestLightClientHandler_GetLightClientFinalityUpdate tests From a0a2af2ceb63733a90eda50f87c3d1dfcd7f6073 Mon Sep 17 00:00:00 2001 From: Inspector-Butters Date: Thu, 17 Oct 2024 21:13:58 +0200 Subject: [PATCH 14/35] refactor tests --- beacon-chain/rpc/eth/light-client/helpers_test.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/beacon-chain/rpc/eth/light-client/helpers_test.go b/beacon-chain/rpc/eth/light-client/helpers_test.go index 9b27204fc22e..8fe4d0460da8 100644 --- a/beacon-chain/rpc/eth/light-client/helpers_test.go +++ b/beacon-chain/rpc/eth/light-client/helpers_test.go @@ -4,8 +4,8 @@ import ( "testing" lightclient "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/light-client" - fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams" + "github.com/prysmaticlabs/prysm/v5/config/params" ethpbv1 "github.com/prysmaticlabs/prysm/v5/proto/eth/v1" ethpbv2 "github.com/prysmaticlabs/prysm/v5/proto/eth/v2" "github.com/prysmaticlabs/prysm/v5/testing/assert" @@ -26,6 +26,11 @@ func createNonEmptyFinalityBranch() [][]byte { } func TestIsBetterUpdate(t *testing.T) { + + params.SetupTestConfigCleanup(t) + config := params.MainnetConfig() + params.OverrideBeaconConfig(config) + testCases := []struct { name string oldUpdate *ethpbv2.LightClientUpdate From 1a8f20c0febb97afd1cacd5a681b15df90a7ccb9 Mon Sep 17 00:00:00 2001 From: Mohamad Bastin Date: Mon, 21 Oct 2024 13:11:26 +0200 Subject: [PATCH 15/35] add configCleanup in tests --- beacon-chain/rpc/eth/light-client/handlers_test.go | 11 +++++++++++ beacon-chain/rpc/eth/light-client/helpers_test.go | 2 -- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/beacon-chain/rpc/eth/light-client/handlers_test.go b/beacon-chain/rpc/eth/light-client/handlers_test.go index 7dc776752391..99bd45b2fd1b 100644 --- a/beacon-chain/rpc/eth/light-client/handlers_test.go +++ b/beacon-chain/rpc/eth/light-client/handlers_test.go @@ -1335,6 +1335,7 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeCountBiggerThanMax(t *te func TestLightClientHandler_GetLightClientUpdatesByRangeStartPeriodBeforeAltair(t *testing.T) { helpers.ClearCache() ctx := context.Background() + params.SetupTestConfigCleanup(t) config := params.BeaconConfig() config.AltairForkEpoch = 1 config.EpochsPerSyncCommitteePeriod = 1 @@ -1414,6 +1415,7 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeStartPeriodBeforeAltair( func TestLightClientHandler_GetLightClientUpdatesByRangeMissingUpdates(t *testing.T) { helpers.ClearCache() ctx := context.Background() + params.SetupTestConfigCleanup(t) config := params.BeaconConfig() config.AltairForkEpoch = 0 config.EpochsPerSyncCommitteePeriod = 1 @@ -1509,6 +1511,7 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeMissingUpdates(t *testin func TestLightClientHandler_GetLightClientUpdatesByRangeMissingUpdates2(t *testing.T) { helpers.ClearCache() ctx := context.Background() + params.SetupTestConfigCleanup(t) config := params.BeaconConfig() config.AltairForkEpoch = 0 config.EpochsPerSyncCommitteePeriod = 1 @@ -1598,6 +1601,7 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeMissingUpdates2(t *testi func TestLightClientHandler_GetLightClientFinalityUpdateAltair(t *testing.T) { helpers.ClearCache() ctx := context.Background() + params.SetupTestConfigCleanup(t) config := params.BeaconConfig() slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) @@ -1708,6 +1712,7 @@ func TestLightClientHandler_GetLightClientFinalityUpdateAltair(t *testing.T) { func TestLightClientHandler_GetLightClientFinalityUpdateCapella(t *testing.T) { helpers.ClearCache() ctx := context.Background() + params.SetupTestConfigCleanup(t) config := params.BeaconConfig() slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) @@ -1818,6 +1823,7 @@ func TestLightClientHandler_GetLightClientFinalityUpdateCapella(t *testing.T) { func TestLightClientHandler_GetLightClientFinalityUpdateDeneb(t *testing.T) { helpers.ClearCache() ctx := context.Background() + params.SetupTestConfigCleanup(t) config := params.BeaconConfig() slot := primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) @@ -1928,6 +1934,7 @@ func TestLightClientHandler_GetLightClientFinalityUpdateDeneb(t *testing.T) { func TestLightClientHandler_GetLightClientOptimisticUpdateAltair(t *testing.T) { helpers.ClearCache() ctx := context.Background() + params.SetupTestConfigCleanup(t) config := params.BeaconConfig() slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) @@ -2038,6 +2045,7 @@ func TestLightClientHandler_GetLightClientOptimisticUpdateAltair(t *testing.T) { func TestLightClientHandler_GetLightClientOptimisticUpdateCapella(t *testing.T) { helpers.ClearCache() ctx := context.Background() + params.SetupTestConfigCleanup(t) config := params.BeaconConfig() slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) @@ -2148,6 +2156,7 @@ func TestLightClientHandler_GetLightClientOptimisticUpdateCapella(t *testing.T) func TestLightClientHandler_GetLightClientOptimisticUpdateDeneb(t *testing.T) { helpers.ClearCache() ctx := context.Background() + params.SetupTestConfigCleanup(t) config := params.BeaconConfig() slot := primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) @@ -2258,6 +2267,7 @@ func TestLightClientHandler_GetLightClientOptimisticUpdateDeneb(t *testing.T) { func TestLightClientHandler_GetLightClientEventBlock(t *testing.T) { helpers.ClearCache() ctx := context.Background() + params.SetupTestConfigCleanup(t) config := params.BeaconConfig() slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) @@ -2362,6 +2372,7 @@ func TestLightClientHandler_GetLightClientEventBlock(t *testing.T) { func TestLightClientHandler_GetLightClientEventBlock_NeedFetchParent(t *testing.T) { helpers.ClearCache() ctx := context.Background() + params.SetupTestConfigCleanup(t) config := params.BeaconConfig() slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) diff --git a/beacon-chain/rpc/eth/light-client/helpers_test.go b/beacon-chain/rpc/eth/light-client/helpers_test.go index 8fe4d0460da8..dfaab098316e 100644 --- a/beacon-chain/rpc/eth/light-client/helpers_test.go +++ b/beacon-chain/rpc/eth/light-client/helpers_test.go @@ -28,8 +28,6 @@ func createNonEmptyFinalityBranch() [][]byte { func TestIsBetterUpdate(t *testing.T) { params.SetupTestConfigCleanup(t) - config := params.MainnetConfig() - params.OverrideBeaconConfig(config) testCases := []struct { name string From 52f37ec628fdb21b921536d544be80d7d69ec3ed Mon Sep 17 00:00:00 2001 From: Mohamad Bastin Date: Mon, 21 Oct 2024 13:17:42 +0200 Subject: [PATCH 16/35] refactor missing updates testcase --- .../rpc/eth/light-client/handlers_test.go | 270 ++++++++---------- 1 file changed, 127 insertions(+), 143 deletions(-) diff --git a/beacon-chain/rpc/eth/light-client/handlers_test.go b/beacon-chain/rpc/eth/light-client/handlers_test.go index 99bd45b2fd1b..6e2e82223079 100644 --- a/beacon-chain/rpc/eth/light-client/handlers_test.go +++ b/beacon-chain/rpc/eth/light-client/handlers_test.go @@ -1428,172 +1428,156 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeMissingUpdates(t *testin err = st.SetSlot(headSlot) require.NoError(t, err) - db := setupDB(t) + t.Run("missing update in the middle", func(t *testing.T) { + db := setupDB(t) + + updates := make([]*ethpbv2.LightClientUpdate, 3) + + updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) + + for i := 0; i < 3; i++ { + if i == 1 { // skip this update + updatePeriod++ + continue + } + newSlot := slot.Add(uint64(i * 32)) + + update := ðpbv2.LightClientUpdate{ + AttestedHeader: ðpbv2.LightClientHeaderContainer{ + Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ + HeaderAltair: ðpbv2.LightClientHeader{ + Beacon: ðpbv1.BeaconBlockHeader{ + Slot: newSlot, + ProposerIndex: 1, + ParentRoot: []byte{1, 1, 1}, + StateRoot: []byte{1, 1, 1}, + BodyRoot: []byte{1, 1, 1}, + }, + }, + }, + }, + NextSyncCommittee: ðpbv2.SyncCommittee{ + Pubkeys: nil, + AggregatePubkey: nil, + }, + NextSyncCommitteeBranch: nil, + FinalizedHeader: nil, + FinalityBranch: nil, + SyncAggregate: ðpbv1.SyncAggregate{ + SyncCommitteeBits: []byte{1, 1, 1}, + SyncCommitteeSignature: []byte{1, 1, 1}, + }, + SignatureSlot: 7, + } - updates := make([]*ethpbv2.LightClientUpdate, 3) + updates[i] = update - updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) + err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ + Version: version.Altair, + Data: update, + }) + require.NoError(t, err) - for i := 0; i < 3; i++ { - if i == 1 { // skip this update updatePeriod++ - continue } - newSlot := slot.Add(uint64(i * 32)) - update := ðpbv2.LightClientUpdate{ - AttestedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: ðpbv2.LightClientHeader{ - Beacon: ðpbv1.BeaconBlockHeader{ - Slot: newSlot, - ProposerIndex: 1, - ParentRoot: []byte{1, 1, 1}, - StateRoot: []byte{1, 1, 1}, - BodyRoot: []byte{1, 1, 1}, - }, - }, - }, - }, - NextSyncCommittee: ðpbv2.SyncCommittee{ - Pubkeys: nil, - AggregatePubkey: nil, - }, - NextSyncCommitteeBranch: nil, - FinalizedHeader: nil, - FinalityBranch: nil, - SyncAggregate: ðpbv1.SyncAggregate{ - SyncCommitteeBits: []byte{1, 1, 1}, - SyncCommitteeSignature: []byte{1, 1, 1}, - }, - SignatureSlot: 7, + mockChainService := &mock.ChainService{State: st} + s := &Server{ + HeadFetcher: mockChainService, + BeaconDB: db, } + startPeriod := 0 + url := fmt.Sprintf("http://foo.com/?count=10&start_period=%d", startPeriod) + request := httptest.NewRequest("GET", url, nil) + writer := httptest.NewRecorder() + writer.Body = &bytes.Buffer{} - updates[i] = update + s.GetLightClientUpdatesByRange(writer, request) - err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ - Version: version.Altair, - Data: update, - }) + require.Equal(t, http.StatusOK, writer.Code) + var resp structs.LightClientUpdatesByRangeResponse + err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) require.NoError(t, err) + require.Equal(t, 1, len(resp.Updates)) + require.Equal(t, "altair", resp.Updates[0].Version) + updateJson, err := structs.LightClientUpdateFromConsensus(updates[0]) + require.NoError(t, err) + require.DeepEqual(t, updateJson, resp.Updates[0].Data) + }) - updatePeriod++ - } - - mockChainService := &mock.ChainService{State: st} - s := &Server{ - HeadFetcher: mockChainService, - BeaconDB: db, - } - startPeriod := 0 - url := fmt.Sprintf("http://foo.com/?count=10&start_period=%d", startPeriod) - request := httptest.NewRequest("GET", url, nil) - writer := httptest.NewRecorder() - writer.Body = &bytes.Buffer{} + t.Run("missing update at the beginning", func(t *testing.T) { + db := setupDB(t) + + updates := make([]*ethpbv2.LightClientUpdate, 3) + + updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) + + for i := 0; i < 3; i++ { + if i == 0 { // skip this update + updatePeriod++ + continue + } + newSlot := slot.Add(uint64(i)) + + update := ðpbv2.LightClientUpdate{ + AttestedHeader: ðpbv2.LightClientHeaderContainer{ + Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ + HeaderAltair: ðpbv2.LightClientHeader{ + Beacon: ðpbv1.BeaconBlockHeader{ + Slot: newSlot, + ProposerIndex: 1, + ParentRoot: []byte{1, 1, 1}, + StateRoot: []byte{1, 1, 1}, + BodyRoot: []byte{1, 1, 1}, + }, + }, + }, + }, + NextSyncCommittee: ðpbv2.SyncCommittee{ + Pubkeys: nil, + AggregatePubkey: nil, + }, + NextSyncCommitteeBranch: nil, + FinalizedHeader: nil, + FinalityBranch: nil, + SyncAggregate: ðpbv1.SyncAggregate{ + SyncCommitteeBits: []byte{1, 1, 1}, + SyncCommitteeSignature: []byte{1, 1, 1}, + }, + SignatureSlot: 7, + } - s.GetLightClientUpdatesByRange(writer, request) + updates[i] = update - require.Equal(t, http.StatusOK, writer.Code) - var resp structs.LightClientUpdatesByRangeResponse - err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) - require.NoError(t, err) - require.Equal(t, 1, len(resp.Updates)) - for i, update := range updates { - if i < 1 { - require.Equal(t, "altair", resp.Updates[i].Version) - updateJson, err := structs.LightClientUpdateFromConsensus(update) + err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ + Version: version.Altair, + Data: update, + }) require.NoError(t, err) - require.DeepEqual(t, updateJson, resp.Updates[i].Data) - } - } -} -func TestLightClientHandler_GetLightClientUpdatesByRangeMissingUpdates2(t *testing.T) { - helpers.ClearCache() - ctx := context.Background() - params.SetupTestConfigCleanup(t) - config := params.BeaconConfig() - config.AltairForkEpoch = 0 - config.EpochsPerSyncCommitteePeriod = 1 - params.OverrideBeaconConfig(config) - slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) - - st, err := util.NewBeaconStateAltair() - require.NoError(t, err) - headSlot := slot.Add(65) - err = st.SetSlot(headSlot) - require.NoError(t, err) - - db := setupDB(t) - - updates := make([]*ethpbv2.LightClientUpdate, 3) - - updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - - for i := 0; i < 3; i++ { - if i == 0 { // skip this update updatePeriod++ - continue } - newSlot := slot.Add(uint64(i)) - update := ðpbv2.LightClientUpdate{ - AttestedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: ðpbv2.LightClientHeader{ - Beacon: ðpbv1.BeaconBlockHeader{ - Slot: newSlot, - ProposerIndex: 1, - ParentRoot: []byte{1, 1, 1}, - StateRoot: []byte{1, 1, 1}, - BodyRoot: []byte{1, 1, 1}, - }, - }, - }, - }, - NextSyncCommittee: ðpbv2.SyncCommittee{ - Pubkeys: nil, - AggregatePubkey: nil, - }, - NextSyncCommitteeBranch: nil, - FinalizedHeader: nil, - FinalityBranch: nil, - SyncAggregate: ðpbv1.SyncAggregate{ - SyncCommitteeBits: []byte{1, 1, 1}, - SyncCommitteeSignature: []byte{1, 1, 1}, - }, - SignatureSlot: 7, + mockChainService := &mock.ChainService{State: st} + s := &Server{ + HeadFetcher: mockChainService, + BeaconDB: db, } + startPeriod := 0 + url := fmt.Sprintf("http://foo.com/?count=10&start_period=%d", startPeriod) + request := httptest.NewRequest("GET", url, nil) + writer := httptest.NewRecorder() + writer.Body = &bytes.Buffer{} - updates[i] = update + s.GetLightClientUpdatesByRange(writer, request) - err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ - Version: version.Altair, - Data: update, - }) + require.Equal(t, http.StatusOK, writer.Code) + var resp structs.LightClientUpdatesByRangeResponse + err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) require.NoError(t, err) + require.Equal(t, 0, len(resp.Updates)) + }) - updatePeriod++ - } - - mockChainService := &mock.ChainService{State: st} - s := &Server{ - HeadFetcher: mockChainService, - BeaconDB: db, - } - startPeriod := 0 - url := fmt.Sprintf("http://foo.com/?count=10&start_period=%d", startPeriod) - request := httptest.NewRequest("GET", url, nil) - writer := httptest.NewRecorder() - writer.Body = &bytes.Buffer{} - - s.GetLightClientUpdatesByRange(writer, request) - - require.Equal(t, http.StatusOK, writer.Code) - var resp structs.LightClientUpdatesByRangeResponse - err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) - require.NoError(t, err) - require.Equal(t, 0, len(resp.Updates)) } // TestLightClientHandler_GetLightClientFinalityUpdate tests From 0e7deffc9e5079f05fb49b0f0e4161444c5a3f56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20Kapka?= Date: Mon, 21 Oct 2024 19:45:16 +0700 Subject: [PATCH 17/35] Light Client - use the new consensus types (#14549) * in progress * completed logic * var name * additional logic changes * fix createDefaultLightClientUpdate * empty fields * unused context --- api/server/structs/BUILD.bazel | 3 +- api/server/structs/conversions.go | 7 + api/server/structs/conversions_lightclient.go | 136 +++-- .../blockchain/process_block_helpers.go | 21 +- beacon-chain/core/light-client/BUILD.bazel | 7 +- beacon-chain/core/light-client/lightclient.go | 500 ++++++++++-------- beacon-chain/db/iface/BUILD.bazel | 1 - beacon-chain/db/iface/interface.go | 8 +- beacon-chain/db/kv/BUILD.bazel | 2 +- beacon-chain/db/kv/lightclient.go | 107 +++- beacon-chain/execution/engine_client.go | 2 +- beacon-chain/execution/payload_body.go | 2 +- beacon-chain/rpc/endpoints.go | 9 +- beacon-chain/rpc/eth/events/events.go | 14 +- beacon-chain/rpc/eth/light-client/BUILD.bazel | 2 - beacon-chain/rpc/eth/light-client/handlers.go | 7 +- beacon-chain/rpc/eth/light-client/helpers.go | 257 +++------ beacon-chain/rpc/eth/light-client/server.go | 9 +- consensus-types/interfaces/light_client.go | 13 + .../light-client/finality_update.go | 71 +++ consensus-types/light-client/header.go | 12 + consensus-types/light-client/helpers.go | 3 +- .../light-client/optimistic_update.go | 115 ++-- consensus-types/light-client/update.go | 230 +++++++- 24 files changed, 956 insertions(+), 582 deletions(-) diff --git a/api/server/structs/BUILD.bazel b/api/server/structs/BUILD.bazel index c194d502ee02..54ed0b02a9e3 100644 --- a/api/server/structs/BUILD.bazel +++ b/api/server/structs/BUILD.bazel @@ -36,9 +36,8 @@ go_library( "//math:go_default_library", "//proto/engine/v1:go_default_library", "//proto/eth/v1:go_default_library", - "//proto/eth/v2:go_default_library", - "//proto/migration:go_default_library", "//proto/prysm/v1alpha1:go_default_library", + "//runtime/version:go_default_library", "@com_github_ethereum_go_ethereum//common:go_default_library", "@com_github_ethereum_go_ethereum//common/hexutil:go_default_library", "@com_github_pkg_errors//:go_default_library", diff --git a/api/server/structs/conversions.go b/api/server/structs/conversions.go index 9ed1f50e4e67..74af3c41aba5 100644 --- a/api/server/structs/conversions.go +++ b/api/server/structs/conversions.go @@ -1546,3 +1546,10 @@ func EventChainReorgFromV1(event *ethv1.EventChainReorg) *ChainReorgEvent { ExecutionOptimistic: event.ExecutionOptimistic, } } + +func SyncAggregateFromConsensus(sa *eth.SyncAggregate) *SyncAggregate { + return &SyncAggregate{ + SyncCommitteeBits: hexutil.Encode(sa.SyncCommitteeBits), + SyncCommitteeSignature: hexutil.Encode(sa.SyncCommitteeSignature), + } +} diff --git a/api/server/structs/conversions_lightclient.go b/api/server/structs/conversions_lightclient.go index 50e6281ef9b9..0c809c70b146 100644 --- a/api/server/structs/conversions_lightclient.go +++ b/api/server/structs/conversions_lightclient.go @@ -3,125 +3,153 @@ package structs import ( "encoding/json" "fmt" - "strconv" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/pkg/errors" - v1 "github.com/prysmaticlabs/prysm/v5/proto/eth/v1" - v2 "github.com/prysmaticlabs/prysm/v5/proto/eth/v2" - "github.com/prysmaticlabs/prysm/v5/proto/migration" + "github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces" + enginev1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1" + "github.com/prysmaticlabs/prysm/v5/runtime/version" ) -func LightClientUpdateFromConsensus(update *v2.LightClientUpdate) (*LightClientUpdate, error) { - attestedHeader, err := lightClientHeaderContainerToJSON(update.AttestedHeader) +func LightClientUpdateFromConsensus(update interfaces.LightClientUpdate) (*LightClientUpdate, error) { + attestedHeader, err := lightClientHeaderToJSON(update.AttestedHeader()) if err != nil { return nil, errors.Wrap(err, "could not marshal attested light client header") } - finalizedHeader, err := lightClientHeaderContainerToJSON(update.FinalizedHeader) + finalizedHeader, err := lightClientHeaderToJSON(update.FinalizedHeader()) if err != nil { return nil, errors.Wrap(err, "could not marshal finalized light client header") } + finalityBranch := update.FinalityBranch() + + var scBranch [][32]byte + if update.Version() >= version.Electra { + b, err := update.NextSyncCommitteeBranchElectra() + if err != nil { + return nil, err + } + scBranch = b[:] + } else { + b, err := update.NextSyncCommitteeBranch() + if err != nil { + return nil, err + } + scBranch = b[:] + } return &LightClientUpdate{ AttestedHeader: attestedHeader, - NextSyncCommittee: SyncCommitteeFromConsensus(migration.V2SyncCommitteeToV1Alpha1(update.NextSyncCommittee)), - NextSyncCommitteeBranch: branchToJSON(update.NextSyncCommitteeBranch), + NextSyncCommittee: SyncCommitteeFromConsensus(update.NextSyncCommittee()), + NextSyncCommitteeBranch: branchToJSON(scBranch), FinalizedHeader: finalizedHeader, - FinalityBranch: branchToJSON(update.FinalityBranch), - SyncAggregate: syncAggregateToJSON(update.SyncAggregate), - SignatureSlot: strconv.FormatUint(uint64(update.SignatureSlot), 10), + FinalityBranch: branchToJSON(finalityBranch[:]), + SyncAggregate: SyncAggregateFromConsensus(update.SyncAggregate()), + SignatureSlot: fmt.Sprintf("%d", update.SignatureSlot()), }, nil } -func LightClientFinalityUpdateFromConsensus(update *v2.LightClientFinalityUpdate) (*LightClientFinalityUpdate, error) { - attestedHeader, err := lightClientHeaderContainerToJSON(update.AttestedHeader) +func LightClientFinalityUpdateFromConsensus(update interfaces.LightClientFinalityUpdate) (*LightClientFinalityUpdate, error) { + attestedHeader, err := lightClientHeaderToJSON(update.AttestedHeader()) if err != nil { return nil, errors.Wrap(err, "could not marshal attested light client header") } - finalizedHeader, err := lightClientHeaderContainerToJSON(update.FinalizedHeader) + finalizedHeader, err := lightClientHeaderToJSON(update.FinalizedHeader()) if err != nil { return nil, errors.Wrap(err, "could not marshal finalized light client header") } + finalityBranch := update.FinalityBranch() return &LightClientFinalityUpdate{ AttestedHeader: attestedHeader, FinalizedHeader: finalizedHeader, - FinalityBranch: branchToJSON(update.FinalityBranch), - SyncAggregate: syncAggregateToJSON(update.SyncAggregate), - SignatureSlot: strconv.FormatUint(uint64(update.SignatureSlot), 10), + FinalityBranch: branchToJSON(finalityBranch[:]), + SyncAggregate: SyncAggregateFromConsensus(update.SyncAggregate()), + SignatureSlot: fmt.Sprintf("%d", update.SignatureSlot()), }, nil } -func LightClientOptimisticUpdateFromConsensus(update *v2.LightClientOptimisticUpdate) (*LightClientOptimisticUpdate, error) { - attestedHeader, err := lightClientHeaderContainerToJSON(update.AttestedHeader) +func LightClientOptimisticUpdateFromConsensus(update interfaces.LightClientOptimisticUpdate) (*LightClientOptimisticUpdate, error) { + attestedHeader, err := lightClientHeaderToJSON(update.AttestedHeader()) if err != nil { return nil, errors.Wrap(err, "could not marshal attested light client header") } return &LightClientOptimisticUpdate{ AttestedHeader: attestedHeader, - SyncAggregate: syncAggregateToJSON(update.SyncAggregate), - SignatureSlot: strconv.FormatUint(uint64(update.SignatureSlot), 10), + SyncAggregate: SyncAggregateFromConsensus(update.SyncAggregate()), + SignatureSlot: fmt.Sprintf("%d", update.SignatureSlot()), }, nil } -func branchToJSON(branchBytes [][]byte) []string { +func branchToJSON[S [][32]byte](branchBytes S) []string { if branchBytes == nil { return nil } branch := make([]string, len(branchBytes)) for i, root := range branchBytes { - branch[i] = hexutil.Encode(root) + branch[i] = hexutil.Encode(root[:]) } return branch } -func syncAggregateToJSON(input *v1.SyncAggregate) *SyncAggregate { - return &SyncAggregate{ - SyncCommitteeBits: hexutil.Encode(input.SyncCommitteeBits), - SyncCommitteeSignature: hexutil.Encode(input.SyncCommitteeSignature), - } -} - -func lightClientHeaderContainerToJSON(container *v2.LightClientHeaderContainer) (json.RawMessage, error) { +func lightClientHeaderToJSON(header interfaces.LightClientHeader) (json.RawMessage, error) { // In the case that a finalizedHeader is nil. - if container == nil { + if header == nil { return nil, nil } - beacon, err := container.GetBeacon() - if err != nil { - return nil, errors.Wrap(err, "could not get beacon block header") - } - - var header any + var result any - switch t := (container.Header).(type) { - case *v2.LightClientHeaderContainer_HeaderAltair: - header = &LightClientHeader{Beacon: BeaconBlockHeaderFromConsensus(migration.V1HeaderToV1Alpha1(beacon))} - case *v2.LightClientHeaderContainer_HeaderCapella: - execution, err := ExecutionPayloadHeaderCapellaFromConsensus(t.HeaderCapella.Execution) + switch v := header.Version(); v { + case version.Altair: + result = &LightClientHeader{Beacon: BeaconBlockHeaderFromConsensus(header.Beacon())} + case version.Capella: + exInterface, err := header.Execution() if err != nil { return nil, err } - header = &LightClientHeaderCapella{ - Beacon: BeaconBlockHeaderFromConsensus(migration.V1HeaderToV1Alpha1(beacon)), + ex, ok := exInterface.Proto().(*enginev1.ExecutionPayloadHeaderCapella) + if !ok { + return nil, fmt.Errorf("execution data is not %T", &enginev1.ExecutionPayloadHeaderCapella{}) + } + execution, err := ExecutionPayloadHeaderCapellaFromConsensus(ex) + if err != nil { + return nil, err + } + executionBranch, err := header.ExecutionBranch() + if err != nil { + return nil, err + } + result = &LightClientHeaderCapella{ + Beacon: BeaconBlockHeaderFromConsensus(header.Beacon()), Execution: execution, - ExecutionBranch: branchToJSON(t.HeaderCapella.ExecutionBranch), + ExecutionBranch: branchToJSON(executionBranch[:]), + } + case version.Deneb: + exInterface, err := header.Execution() + if err != nil { + return nil, err + } + ex, ok := exInterface.Proto().(*enginev1.ExecutionPayloadHeaderDeneb) + if !ok { + return nil, fmt.Errorf("execution data is not %T", &enginev1.ExecutionPayloadHeaderDeneb{}) + } + execution, err := ExecutionPayloadHeaderDenebFromConsensus(ex) + if err != nil { + return nil, err } - case *v2.LightClientHeaderContainer_HeaderDeneb: - execution, err := ExecutionPayloadHeaderDenebFromConsensus(t.HeaderDeneb.Execution) + executionBranch, err := header.ExecutionBranch() if err != nil { return nil, err } - header = &LightClientHeaderDeneb{ - Beacon: BeaconBlockHeaderFromConsensus(migration.V1HeaderToV1Alpha1(beacon)), + result = &LightClientHeaderDeneb{ + Beacon: BeaconBlockHeaderFromConsensus(header.Beacon()), Execution: execution, - ExecutionBranch: branchToJSON(t.HeaderDeneb.ExecutionBranch), + ExecutionBranch: branchToJSON(executionBranch[:]), } default: - return nil, fmt.Errorf("unsupported header type %T", t) + return nil, fmt.Errorf("unsupported header version %s", version.String(v)) } - return json.Marshal(header) + return json.Marshal(result) } diff --git a/beacon-chain/blockchain/process_block_helpers.go b/beacon-chain/blockchain/process_block_helpers.go index 8f3da0a4236c..7b7a5f07fba7 100644 --- a/beacon-chain/blockchain/process_block_helpers.go +++ b/beacon-chain/blockchain/process_block_helpers.go @@ -129,7 +129,12 @@ func (s *Service) sendLightClientFeeds(cfg *postBlockProcessConfig) { } } -func (s *Service) tryPublishLightClientFinalityUpdate(ctx context.Context, signed interfaces.ReadOnlySignedBeaconBlock, finalized *forkchoicetypes.Checkpoint, postState state.BeaconState) { +func (s *Service) tryPublishLightClientFinalityUpdate( + ctx context.Context, + signed interfaces.ReadOnlySignedBeaconBlock, + finalized *forkchoicetypes.Checkpoint, + postState state.BeaconState, +) { if finalized.Epoch <= s.lastPublishedLightClientEpoch { return } @@ -182,15 +187,15 @@ func (s *Service) sendLightClientFinalityUpdate(ctx context.Context, signed inte } } - update, err := lightclient.NewLightClientFinalityUpdateFromBeaconState( + _, err = lightclient.NewLightClientFinalityUpdateFromBeaconState( ctx, + postState.Slot(), postState, signed, attestedState, attestedBlock, finalizedBlock, ) - if err != nil { return 0, errors.Wrap(err, "could not create light client update") } @@ -198,7 +203,8 @@ func (s *Service) sendLightClientFinalityUpdate(ctx context.Context, signed inte // Return the result result := ðpbv2.LightClientFinalityUpdateWithVersion{ Version: ethpbv2.Version(signed.Version()), - Data: update, + // TODO: Get back to this when revisiting events + //Data: update, } // Send event @@ -222,14 +228,14 @@ func (s *Service) sendLightClientOptimisticUpdate(ctx context.Context, signed in return 0, errors.Wrap(err, "could not get attested state") } - update, err := lightclient.NewLightClientOptimisticUpdateFromBeaconState( + _, err = lightclient.NewLightClientOptimisticUpdateFromBeaconState( ctx, + postState.Slot(), postState, signed, attestedState, attestedBlock, ) - if err != nil { return 0, errors.Wrap(err, "could not create light client update") } @@ -237,7 +243,8 @@ func (s *Service) sendLightClientOptimisticUpdate(ctx context.Context, signed in // Return the result result := ðpbv2.LightClientOptimisticUpdateWithVersion{ Version: ethpbv2.Version(signed.Version()), - Data: update, + // TODO: Get back to this when revisiting events + //Data: update, } return s.cfg.StateNotifier.StateFeed().Send(&feed.Event{ diff --git a/beacon-chain/core/light-client/BUILD.bazel b/beacon-chain/core/light-client/BUILD.bazel index c7a264c71bb6..327e1922055f 100644 --- a/beacon-chain/core/light-client/BUILD.bazel +++ b/beacon-chain/core/light-client/BUILD.bazel @@ -6,19 +6,22 @@ go_library( importpath = "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/light-client", visibility = ["//visibility:public"], deps = [ + "//beacon-chain/execution:go_default_library", "//beacon-chain/state:go_default_library", "//config/fieldparams:go_default_library", "//config/params:go_default_library", "//consensus-types:go_default_library", "//consensus-types/blocks:go_default_library", "//consensus-types/interfaces:go_default_library", + "//consensus-types/light-client:go_default_library", + "//consensus-types/primitives:go_default_library", "//encoding/ssz:go_default_library", "//proto/engine/v1:go_default_library", - "//proto/eth/v1:go_default_library", - "//proto/eth/v2:go_default_library", + "//proto/prysm/v1alpha1:go_default_library", "//runtime/version:go_default_library", "//time/slots:go_default_library", "@com_github_pkg_errors//:go_default_library", + "@org_golang_google_protobuf//proto:go_default_library", ], ) diff --git a/beacon-chain/core/light-client/lightclient.go b/beacon-chain/core/light-client/lightclient.go index 1173ec355331..7c60a163cf05 100644 --- a/beacon-chain/core/light-client/lightclient.go +++ b/beacon-chain/core/light-client/lightclient.go @@ -6,85 +6,75 @@ import ( "fmt" "github.com/pkg/errors" + "github.com/prysmaticlabs/prysm/v5/beacon-chain/execution" "github.com/prysmaticlabs/prysm/v5/beacon-chain/state" fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams" "github.com/prysmaticlabs/prysm/v5/config/params" consensus_types "github.com/prysmaticlabs/prysm/v5/consensus-types" "github.com/prysmaticlabs/prysm/v5/consensus-types/blocks" "github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces" + light_client "github.com/prysmaticlabs/prysm/v5/consensus-types/light-client" + "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" "github.com/prysmaticlabs/prysm/v5/encoding/ssz" - v11 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1" - ethpbv1 "github.com/prysmaticlabs/prysm/v5/proto/eth/v1" - ethpbv2 "github.com/prysmaticlabs/prysm/v5/proto/eth/v2" + enginev1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1" + pb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" "github.com/prysmaticlabs/prysm/v5/runtime/version" "github.com/prysmaticlabs/prysm/v5/time/slots" + "google.golang.org/protobuf/proto" ) const ( - FinalityBranchNumOfLeaves = 6 - executionBranchNumOfLeaves = 4 + FinalityBranchNumOfLeaves = 6 ) -func createLightClientFinalityUpdate(update *ethpbv2.LightClientUpdate) *ethpbv2.LightClientFinalityUpdate { - finalityUpdate := ðpbv2.LightClientFinalityUpdate{ - AttestedHeader: update.AttestedHeader, - FinalizedHeader: update.FinalizedHeader, - FinalityBranch: update.FinalityBranch, - SyncAggregate: update.SyncAggregate, - SignatureSlot: update.SignatureSlot, - } - - return finalityUpdate -} - -func createLightClientOptimisticUpdate(update *ethpbv2.LightClientUpdate) *ethpbv2.LightClientOptimisticUpdate { - optimisticUpdate := ðpbv2.LightClientOptimisticUpdate{ - AttestedHeader: update.AttestedHeader, - SyncAggregate: update.SyncAggregate, - SignatureSlot: update.SignatureSlot, - } - - return optimisticUpdate -} - func NewLightClientFinalityUpdateFromBeaconState( ctx context.Context, + currentSlot primitives.Slot, state state.BeaconState, block interfaces.ReadOnlySignedBeaconBlock, attestedState state.BeaconState, attestedBlock interfaces.ReadOnlySignedBeaconBlock, finalizedBlock interfaces.ReadOnlySignedBeaconBlock, -) (*ethpbv2.LightClientFinalityUpdate, error) { - update, err := NewLightClientUpdateFromBeaconState(ctx, state, block, attestedState, attestedBlock, finalizedBlock) +) (interfaces.LightClientFinalityUpdate, error) { + update, err := NewLightClientUpdateFromBeaconState(ctx, currentSlot, state, block, attestedState, attestedBlock, finalizedBlock) if err != nil { return nil, err } - return createLightClientFinalityUpdate(update), nil + return light_client.NewFinalityUpdateFromUpdate(update) } func NewLightClientOptimisticUpdateFromBeaconState( ctx context.Context, + currentSlot primitives.Slot, state state.BeaconState, block interfaces.ReadOnlySignedBeaconBlock, attestedState state.BeaconState, attestedBlock interfaces.ReadOnlySignedBeaconBlock, -) (*ethpbv2.LightClientOptimisticUpdate, error) { - update, err := NewLightClientUpdateFromBeaconState(ctx, state, block, attestedState, attestedBlock, nil) +) (interfaces.LightClientOptimisticUpdate, error) { + update, err := NewLightClientUpdateFromBeaconState(ctx, currentSlot, state, block, attestedState, attestedBlock, nil) if err != nil { return nil, err } - return createLightClientOptimisticUpdate(update), nil + return light_client.NewOptimisticUpdateFromUpdate(update) } +// To form a LightClientUpdate, the following historical states and blocks are needed: +// - state: the post state of any block with a post-Altair parent block +// - block: the corresponding block +// - attested_state: the post state of attested_block +// - attested_block: the block referred to by block.parent_root +// - finalized_block: the block referred to by attested_state.finalized_checkpoint.root, +// if locally available (may be unavailable, e.g., when using checkpoint sync, or if it was pruned locally) func NewLightClientUpdateFromBeaconState( ctx context.Context, + currentSlot primitives.Slot, state state.BeaconState, block interfaces.ReadOnlySignedBeaconBlock, attestedState state.BeaconState, attestedBlock interfaces.ReadOnlySignedBeaconBlock, - finalizedBlock interfaces.ReadOnlySignedBeaconBlock) (*ethpbv2.LightClientUpdate, error) { + finalizedBlock interfaces.ReadOnlySignedBeaconBlock) (interfaces.LightClientUpdate, error) { // assert compute_epoch_at_slot(attested_state.slot) >= ALTAIR_FORK_EPOCH attestedEpoch := slots.ToEpoch(attestedState.Slot()) if attestedEpoch < params.BeaconConfig().AltairForkEpoch { @@ -129,7 +119,11 @@ func NewLightClientUpdateFromBeaconState( // assert attested_state.slot == attested_state.latest_block_header.slot if attestedState.Slot() != attestedState.LatestBlockHeader().Slot { - return nil, fmt.Errorf("attested state slot %d not equal to attested latest block header slot %d", attestedState.Slot(), attestedState.LatestBlockHeader().Slot) + return nil, fmt.Errorf( + "attested state slot %d not equal to attested latest block header slot %d", + attestedState.Slot(), + attestedState.LatestBlockHeader().Slot, + ) } // attested_header = attested_state.latest_block_header.copy() @@ -153,46 +147,56 @@ func NewLightClientUpdateFromBeaconState( } // assert hash_tree_root(attested_header) == hash_tree_root(attested_block.message) == block.message.parent_root if attestedHeaderRoot != block.Block().ParentRoot() || attestedHeaderRoot != attestedBlockRoot { - return nil, fmt.Errorf("attested header root %#x not equal to block parent root %#x or attested block root %#x", attestedHeaderRoot, block.Block().ParentRoot(), attestedBlockRoot) + return nil, fmt.Errorf( + "attested header root %#x not equal to block parent root %#x or attested block root %#x", + attestedHeaderRoot, + block.Block().ParentRoot(), + attestedBlockRoot, + ) } // update_attested_period = compute_sync_committee_period_at_slot(attested_block.message.slot) updateAttestedPeriod := slots.SyncCommitteePeriod(slots.ToEpoch(attestedBlock.Block().Slot())) // update = LightClientUpdate() - result, err := createDefaultLightClientUpdate() + result, err := createDefaultLightClientUpdate(currentSlot) if err != nil { return nil, errors.Wrap(err, "could not create default light client update") } // update.attested_header = block_to_light_client_header(attested_block) - attestedLightClientHeader, err := BlockToLightClientHeader(attestedBlock) + attestedLightClientHeader, err := BlockToLightClientHeader(ctx, currentSlot, attestedBlock) if err != nil { return nil, errors.Wrap(err, "could not get attested light client header") } - result.AttestedHeader = attestedLightClientHeader + result.SetAttestedHeader(attestedLightClientHeader) // if update_attested_period == update_signature_period if updateAttestedPeriod == updateSignaturePeriod { + // update.next_sync_committee = attested_state.next_sync_committee tempNextSyncCommittee, err := attestedState.NextSyncCommittee() if err != nil { return nil, errors.Wrap(err, "could not get next sync committee") } - nextSyncCommittee := ðpbv2.SyncCommittee{ + nextSyncCommittee := &pb.SyncCommittee{ Pubkeys: tempNextSyncCommittee.Pubkeys, AggregatePubkey: tempNextSyncCommittee.AggregatePubkey, } + result.SetNextSyncCommittee(nextSyncCommittee) + + // update.next_sync_committee_branch = NextSyncCommitteeBranch( + // compute_merkle_proof(attested_state, next_sync_committee_gindex_at_slot(attested_state.slot))) nextSyncCommitteeBranch, err := attestedState.NextSyncCommitteeProof(ctx) if err != nil { return nil, errors.Wrap(err, "could not get next sync committee proof") } - - // update.next_sync_committee = attested_state.next_sync_committee - result.NextSyncCommittee = nextSyncCommittee - - // update.next_sync_committee_branch = NextSyncCommitteeBranch( - // compute_merkle_proof(attested_state, next_sync_committee_gindex_at_slot(attested_state.slot))) - result.NextSyncCommitteeBranch = nextSyncCommitteeBranch + if attestedBlock.Version() >= version.Electra { + if err = result.SetNextSyncCommitteeBranchElectra(nextSyncCommitteeBranch); err != nil { + return nil, errors.Wrap(err, "could not set next sync committee branch") + } + } else if err = result.SetNextSyncCommitteeBranch(nextSyncCommitteeBranch); err != nil { + return nil, errors.Wrap(err, "could not set next sync committee branch") + } } // if finalized_block is not None @@ -200,11 +204,11 @@ func NewLightClientUpdateFromBeaconState( // if finalized_block.message.slot != GENESIS_SLOT if finalizedBlock.Block().Slot() != 0 { // update.finalized_header = block_to_light_client_header(finalized_block) - finalizedLightClientHeader, err := BlockToLightClientHeader(finalizedBlock) + finalizedLightClientHeader, err := BlockToLightClientHeader(ctx, currentSlot, finalizedBlock) if err != nil { return nil, errors.Wrap(err, "could not get finalized light client header") } - result.FinalizedHeader = finalizedLightClientHeader + result.SetFinalizedHeader(finalizedLightClientHeader) } else { // assert attested_state.finalized_checkpoint.root == Bytes32() if !bytes.Equal(attestedState.FinalizedCheckpoint().Root, make([]byte, 32)) { @@ -218,49 +222,83 @@ func NewLightClientUpdateFromBeaconState( if err != nil { return nil, errors.Wrap(err, "could not get finalized root proof") } - result.FinalityBranch = finalityBranch + if err = result.SetFinalityBranch(finalityBranch); err != nil { + return nil, errors.Wrap(err, "could not set finality branch") + } } // update.sync_aggregate = block.message.body.sync_aggregate - result.SyncAggregate = ðpbv1.SyncAggregate{ + result.SetSyncAggregate(&pb.SyncAggregate{ SyncCommitteeBits: syncAggregate.SyncCommitteeBits, SyncCommitteeSignature: syncAggregate.SyncCommitteeSignature, - } + }) // update.signature_slot = block.message.slot - result.SignatureSlot = block.Block().Slot() + result.SetSignatureSlot(block.Block().Slot()) return result, nil } -func createDefaultLightClientUpdate() (*ethpbv2.LightClientUpdate, error) { +func createDefaultLightClientUpdate(currentSlot primitives.Slot) (interfaces.LightClientUpdate, error) { + currentEpoch := slots.ToEpoch(currentSlot) + syncCommitteeSize := params.BeaconConfig().SyncCommitteeSize pubKeys := make([][]byte, syncCommitteeSize) for i := uint64(0); i < syncCommitteeSize; i++ { pubKeys[i] = make([]byte, fieldparams.BLSPubkeyLength) } - nextSyncCommittee := ðpbv2.SyncCommittee{ + nextSyncCommittee := &pb.SyncCommittee{ Pubkeys: pubKeys, AggregatePubkey: make([]byte, fieldparams.BLSPubkeyLength), } - nextSyncCommitteeBranch := make([][]byte, fieldparams.SyncCommitteeBranchDepth) - for i := 0; i < fieldparams.SyncCommitteeBranchDepth; i++ { + + var nextSyncCommitteeBranch [][]byte + if currentEpoch >= params.BeaconConfig().ElectraForkEpoch { + nextSyncCommitteeBranch = make([][]byte, fieldparams.SyncCommitteeBranchDepthElectra) + } else { + nextSyncCommitteeBranch = make([][]byte, fieldparams.SyncCommitteeBranchDepth) + } + for i := 0; i < len(nextSyncCommitteeBranch); i++ { nextSyncCommitteeBranch[i] = make([]byte, fieldparams.RootLength) } - executionBranch := make([][]byte, executionBranchNumOfLeaves) - for i := 0; i < executionBranchNumOfLeaves; i++ { + + executionBranch := make([][]byte, fieldparams.ExecutionBranchDepth) + for i := 0; i < fieldparams.ExecutionBranchDepth; i++ { executionBranch[i] = make([]byte, 32) } - finalityBranch := make([][]byte, FinalityBranchNumOfLeaves) - for i := 0; i < FinalityBranchNumOfLeaves; i++ { + finalityBranch := make([][]byte, fieldparams.FinalityBranchDepth) + for i := 0; i < fieldparams.FinalityBranchDepth; i++ { finalityBranch[i] = make([]byte, 32) } - return ðpbv2.LightClientUpdate{ - NextSyncCommittee: nextSyncCommittee, - NextSyncCommitteeBranch: nextSyncCommitteeBranch, - FinalityBranch: finalityBranch, - }, nil + var m proto.Message + if currentEpoch < params.BeaconConfig().CapellaForkEpoch { + m = &pb.LightClientUpdateAltair{ + NextSyncCommittee: nextSyncCommittee, + NextSyncCommitteeBranch: nextSyncCommitteeBranch, + FinalityBranch: finalityBranch, + } + } else if currentEpoch < params.BeaconConfig().DenebForkEpoch { + m = &pb.LightClientUpdateCapella{ + NextSyncCommittee: nextSyncCommittee, + NextSyncCommitteeBranch: nextSyncCommitteeBranch, + FinalityBranch: finalityBranch, + } + } else if currentEpoch < params.BeaconConfig().ElectraForkEpoch { + m = &pb.LightClientUpdateDeneb{ + NextSyncCommittee: nextSyncCommittee, + NextSyncCommitteeBranch: nextSyncCommitteeBranch, + FinalityBranch: finalityBranch, + } + } else { + m = &pb.LightClientUpdateElectra{ + NextSyncCommittee: nextSyncCommittee, + NextSyncCommitteeBranch: nextSyncCommitteeBranch, + FinalityBranch: finalityBranch, + } + } + + return light_client.NewWrappedUpdate(m) } func ComputeTransactionsRoot(payload interfaces.ExecutionData) ([]byte, error) { @@ -299,47 +337,14 @@ func ComputeWithdrawalsRoot(payload interfaces.ExecutionData) ([]byte, error) { return withdrawalsRoot, nil } -func BlockToLightClientHeader(block interfaces.ReadOnlySignedBeaconBlock) (*ethpbv2.LightClientHeaderContainer, error) { - switch block.Version() { - case version.Altair, version.Bellatrix: - altairHeader, err := blockToLightClientHeaderAltair(block) - if err != nil { - return nil, errors.Wrap(err, "could not get header") - } - return ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: altairHeader, - }, - }, nil - case version.Capella: - capellaHeader, err := blockToLightClientHeaderCapella(context.Background(), block) - if err != nil { - return nil, errors.Wrap(err, "could not get capella header") - } - return ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ - HeaderCapella: capellaHeader, - }, - }, nil - case version.Deneb, version.Electra: - denebHeader, err := blockToLightClientHeaderDeneb(context.Background(), block) - if err != nil { - return nil, errors.Wrap(err, "could not get header") - } - return ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderDeneb{ - HeaderDeneb: denebHeader, - }, - }, nil - default: - return nil, fmt.Errorf("unsupported block version %s", version.String(block.Version())) - } -} - -func blockToLightClientHeaderAltair(block interfaces.ReadOnlySignedBeaconBlock) (*ethpbv2.LightClientHeader, error) { - if block.Version() < version.Altair { - return nil, fmt.Errorf("block version is %s instead of Altair", version.String(block.Version())) - } +func BlockToLightClientHeader( + ctx context.Context, + currentSlot primitives.Slot, + block interfaces.ReadOnlySignedBeaconBlock, +) (interfaces.LightClientHeader, error) { + var m proto.Message + currentEpoch := slots.ToEpoch(currentSlot) + blockEpoch := slots.ToEpoch(block.Block().Slot()) parentRoot := block.Block().ParentRoot() stateRoot := block.Block().StateRoot() @@ -348,147 +353,172 @@ func blockToLightClientHeaderAltair(block interfaces.ReadOnlySignedBeaconBlock) return nil, errors.Wrap(err, "could not get body root") } - return ðpbv2.LightClientHeader{ - Beacon: ðpbv1.BeaconBlockHeader{ - Slot: block.Block().Slot(), - ProposerIndex: block.Block().ProposerIndex(), - ParentRoot: parentRoot[:], - StateRoot: stateRoot[:], - BodyRoot: bodyRoot[:], - }, - }, nil -} + if currentEpoch < params.BeaconConfig().CapellaForkEpoch { + m = &pb.LightClientHeaderAltair{ + Beacon: &pb.BeaconBlockHeader{ + Slot: block.Block().Slot(), + ProposerIndex: block.Block().ProposerIndex(), + ParentRoot: parentRoot[:], + StateRoot: stateRoot[:], + BodyRoot: bodyRoot[:], + }, + } + } else if currentEpoch < params.BeaconConfig().DenebForkEpoch { + var payloadHeader *enginev1.ExecutionPayloadHeaderCapella + var payloadProof [][]byte -func blockToLightClientHeaderCapella(ctx context.Context, block interfaces.ReadOnlySignedBeaconBlock) (*ethpbv2.LightClientHeaderCapella, error) { - if block.Version() < version.Capella { - return nil, fmt.Errorf("block version is %s instead of Capella", version.String(block.Version())) - } + if blockEpoch < params.BeaconConfig().CapellaForkEpoch { + var ok bool - payload, err := block.Block().Body().Execution() - if err != nil { - return nil, errors.Wrap(err, "could not get execution payload") - } + p, err := execution.EmptyExecutionPayload(version.Capella) + if err != nil { + return nil, errors.Wrap(err, "could not get payload header") + } + payloadHeader, ok = p.(*enginev1.ExecutionPayloadHeaderCapella) + if !ok { + return nil, errors.Wrapf(err, "payload header type %T is not %T", payloadHeader, &enginev1.ExecutionPayloadHeaderCapella{}) + } + payloadProof = emptyPayloadProof() + } else { + payload, err := block.Block().Body().Execution() + if err != nil { + return nil, errors.Wrap(err, "could not get execution payload") + } + transactionsRoot, err := ComputeTransactionsRoot(payload) + if err != nil { + return nil, errors.Wrap(err, "could not get transactions root") + } + withdrawalsRoot, err := ComputeWithdrawalsRoot(payload) + if err != nil { + return nil, errors.Wrap(err, "could not get withdrawals root") + } - transactionsRoot, err := ComputeTransactionsRoot(payload) - if err != nil { - return nil, err - } - withdrawalsRoot, err := ComputeWithdrawalsRoot(payload) - if err != nil { - return nil, err - } + payloadHeader = &enginev1.ExecutionPayloadHeaderCapella{ + ParentHash: payload.ParentHash(), + FeeRecipient: payload.FeeRecipient(), + StateRoot: payload.StateRoot(), + ReceiptsRoot: payload.ReceiptsRoot(), + LogsBloom: payload.LogsBloom(), + PrevRandao: payload.PrevRandao(), + BlockNumber: payload.BlockNumber(), + GasLimit: payload.GasLimit(), + GasUsed: payload.GasUsed(), + Timestamp: payload.Timestamp(), + ExtraData: payload.ExtraData(), + BaseFeePerGas: payload.BaseFeePerGas(), + BlockHash: payload.BlockHash(), + TransactionsRoot: transactionsRoot, + WithdrawalsRoot: withdrawalsRoot, + } - executionHeader := &v11.ExecutionPayloadHeaderCapella{ - ParentHash: payload.ParentHash(), - FeeRecipient: payload.FeeRecipient(), - StateRoot: payload.StateRoot(), - ReceiptsRoot: payload.ReceiptsRoot(), - LogsBloom: payload.LogsBloom(), - PrevRandao: payload.PrevRandao(), - BlockNumber: payload.BlockNumber(), - GasLimit: payload.GasLimit(), - GasUsed: payload.GasUsed(), - Timestamp: payload.Timestamp(), - ExtraData: payload.ExtraData(), - BaseFeePerGas: payload.BaseFeePerGas(), - BlockHash: payload.BlockHash(), - TransactionsRoot: transactionsRoot, - WithdrawalsRoot: withdrawalsRoot, - } + payloadProof, err = blocks.PayloadProof(ctx, block.Block()) + if err != nil { + return nil, errors.Wrap(err, "could not get execution payload proof") + } + } - executionPayloadProof, err := blocks.PayloadProof(ctx, block.Block()) - if err != nil { - return nil, errors.Wrap(err, "could not get execution payload proof") - } + m = &pb.LightClientHeaderCapella{ + Beacon: &pb.BeaconBlockHeader{ + Slot: block.Block().Slot(), + ProposerIndex: block.Block().ProposerIndex(), + ParentRoot: parentRoot[:], + StateRoot: stateRoot[:], + BodyRoot: bodyRoot[:], + }, + Execution: payloadHeader, + ExecutionBranch: payloadProof, + } + } else { + var payloadHeader *enginev1.ExecutionPayloadHeaderDeneb + var payloadProof [][]byte - parentRoot := block.Block().ParentRoot() - stateRoot := block.Block().StateRoot() - bodyRoot, err := block.Block().Body().HashTreeRoot() - if err != nil { - return nil, errors.Wrap(err, "could not get body root") - } + if blockEpoch < params.BeaconConfig().CapellaForkEpoch { + var ok bool - return ðpbv2.LightClientHeaderCapella{ - Beacon: ðpbv1.BeaconBlockHeader{ - Slot: block.Block().Slot(), - ProposerIndex: block.Block().ProposerIndex(), - ParentRoot: parentRoot[:], - StateRoot: stateRoot[:], - BodyRoot: bodyRoot[:], - }, - Execution: executionHeader, - ExecutionBranch: executionPayloadProof, - }, nil -} + p, err := execution.EmptyExecutionPayload(version.Deneb) + if err != nil { + return nil, errors.Wrap(err, "could not get payload header") + } + payloadHeader, ok = p.(*enginev1.ExecutionPayloadHeaderDeneb) + if !ok { + return nil, errors.Wrapf(err, "payload header type %T is not %T", payloadHeader, &enginev1.ExecutionPayloadHeaderDeneb{}) + } + payloadProof = emptyPayloadProof() + } else { + payload, err := block.Block().Body().Execution() + if err != nil { + return nil, errors.Wrap(err, "could not get execution payload") + } + transactionsRoot, err := ComputeTransactionsRoot(payload) + if err != nil { + return nil, errors.Wrap(err, "could not get transactions root") + } + withdrawalsRoot, err := ComputeWithdrawalsRoot(payload) + if err != nil { + return nil, errors.Wrap(err, "could not get withdrawals root") + } -func blockToLightClientHeaderDeneb(ctx context.Context, block interfaces.ReadOnlySignedBeaconBlock) (*ethpbv2.LightClientHeaderDeneb, error) { - if block.Version() < version.Deneb { - return nil, fmt.Errorf("block version is %s instead of Deneb/Electra", version.String(block.Version())) - } + var blobGasUsed uint64 + var excessBlobGas uint64 + + if blockEpoch >= params.BeaconConfig().DenebForkEpoch { + blobGasUsed, err = payload.BlobGasUsed() + if err != nil { + return nil, errors.Wrap(err, "could not get blob gas used") + } + excessBlobGas, err = payload.ExcessBlobGas() + if err != nil { + return nil, errors.Wrap(err, "could not get excess blob gas") + } + } - payload, err := block.Block().Body().Execution() - if err != nil { - return nil, errors.Wrap(err, "could not get execution payload") - } + payloadHeader = &enginev1.ExecutionPayloadHeaderDeneb{ + ParentHash: payload.ParentHash(), + FeeRecipient: payload.FeeRecipient(), + StateRoot: payload.StateRoot(), + ReceiptsRoot: payload.ReceiptsRoot(), + LogsBloom: payload.LogsBloom(), + PrevRandao: payload.PrevRandao(), + BlockNumber: payload.BlockNumber(), + GasLimit: payload.GasLimit(), + GasUsed: payload.GasUsed(), + Timestamp: payload.Timestamp(), + ExtraData: payload.ExtraData(), + BaseFeePerGas: payload.BaseFeePerGas(), + BlockHash: payload.BlockHash(), + TransactionsRoot: transactionsRoot, + WithdrawalsRoot: withdrawalsRoot, + BlobGasUsed: blobGasUsed, + ExcessBlobGas: excessBlobGas, + } - transactionsRoot, err := ComputeTransactionsRoot(payload) - if err != nil { - return nil, err - } - withdrawalsRoot, err := ComputeWithdrawalsRoot(payload) - if err != nil { - return nil, err - } - blobGasUsed, err := payload.BlobGasUsed() - if err != nil { - return nil, errors.Wrap(err, "could not get blob gas used") - } - excessBlobGas, err := payload.ExcessBlobGas() - if err != nil { - return nil, errors.Wrap(err, "could not get excess blob gas") - } + payloadProof, err = blocks.PayloadProof(ctx, block.Block()) + if err != nil { + return nil, errors.Wrap(err, "could not get execution payload proof") + } + } - executionHeader := &v11.ExecutionPayloadHeaderDeneb{ - ParentHash: payload.ParentHash(), - FeeRecipient: payload.FeeRecipient(), - StateRoot: payload.StateRoot(), - ReceiptsRoot: payload.ReceiptsRoot(), - LogsBloom: payload.LogsBloom(), - PrevRandao: payload.PrevRandao(), - BlockNumber: payload.BlockNumber(), - GasLimit: payload.GasLimit(), - GasUsed: payload.GasUsed(), - Timestamp: payload.Timestamp(), - ExtraData: payload.ExtraData(), - BaseFeePerGas: payload.BaseFeePerGas(), - BlockHash: payload.BlockHash(), - TransactionsRoot: transactionsRoot, - WithdrawalsRoot: withdrawalsRoot, - BlobGasUsed: blobGasUsed, - ExcessBlobGas: excessBlobGas, + m = &pb.LightClientHeaderDeneb{ + Beacon: &pb.BeaconBlockHeader{ + Slot: block.Block().Slot(), + ProposerIndex: block.Block().ProposerIndex(), + ParentRoot: parentRoot[:], + StateRoot: stateRoot[:], + BodyRoot: bodyRoot[:], + }, + Execution: payloadHeader, + ExecutionBranch: payloadProof, + } } - executionPayloadProof, err := blocks.PayloadProof(ctx, block.Block()) - if err != nil { - return nil, errors.Wrap(err, "could not get execution payload proof") - } + return light_client.NewWrappedHeader(m) +} - parentRoot := block.Block().ParentRoot() - stateRoot := block.Block().StateRoot() - bodyRoot, err := block.Block().Body().HashTreeRoot() - if err != nil { - return nil, errors.Wrap(err, "could not get body root") +func emptyPayloadProof() [][]byte { + branch := interfaces.LightClientExecutionBranch{} + proof := make([][]byte, len(branch)) + for i, b := range branch { + proof[i] = b[:] } - - return ðpbv2.LightClientHeaderDeneb{ - Beacon: ðpbv1.BeaconBlockHeader{ - Slot: block.Block().Slot(), - ProposerIndex: block.Block().ProposerIndex(), - ParentRoot: parentRoot[:], - StateRoot: stateRoot[:], - BodyRoot: bodyRoot[:], - }, - Execution: executionHeader, - ExecutionBranch: executionPayloadProof, - }, nil + return proof } diff --git a/beacon-chain/db/iface/BUILD.bazel b/beacon-chain/db/iface/BUILD.bazel index 993d1fd84c98..81929a26a47d 100644 --- a/beacon-chain/db/iface/BUILD.bazel +++ b/beacon-chain/db/iface/BUILD.bazel @@ -18,7 +18,6 @@ go_library( "//consensus-types/primitives:go_default_library", "//monitoring/backup:go_default_library", "//proto/dbval:go_default_library", - "//proto/eth/v2:go_default_library", "//proto/prysm/v1alpha1:go_default_library", "@com_github_ethereum_go_ethereum//common:go_default_library", ], diff --git a/beacon-chain/db/iface/interface.go b/beacon-chain/db/iface/interface.go index b75960ef553c..fc2ef7af4faa 100644 --- a/beacon-chain/db/iface/interface.go +++ b/beacon-chain/db/iface/interface.go @@ -7,8 +7,6 @@ import ( "context" "io" - ethpbv2 "github.com/prysmaticlabs/prysm/v5/proto/eth/v2" - "github.com/ethereum/go-ethereum/common" "github.com/prysmaticlabs/prysm/v5/beacon-chain/db/filters" slashertypes "github.com/prysmaticlabs/prysm/v5/beacon-chain/slasher/types" @@ -59,8 +57,8 @@ type ReadOnlyDatabase interface { FeeRecipientByValidatorID(ctx context.Context, id primitives.ValidatorIndex) (common.Address, error) RegistrationByValidatorID(ctx context.Context, id primitives.ValidatorIndex) (*ethpb.ValidatorRegistrationV1, error) // light client operations - LightClientUpdates(ctx context.Context, startPeriod, endPeriod uint64) (map[uint64]*ethpbv2.LightClientUpdateWithVersion, error) - LightClientUpdate(ctx context.Context, period uint64) (*ethpbv2.LightClientUpdateWithVersion, error) + LightClientUpdates(ctx context.Context, startPeriod, endPeriod uint64) (map[uint64]interfaces.LightClientUpdate, error) + LightClientUpdate(ctx context.Context, period uint64) (interfaces.LightClientUpdate, error) // origin checkpoint sync support OriginCheckpointBlockRoot(ctx context.Context) ([32]byte, error) @@ -98,7 +96,7 @@ type NoHeadAccessDatabase interface { SaveFeeRecipientsByValidatorIDs(ctx context.Context, ids []primitives.ValidatorIndex, addrs []common.Address) error SaveRegistrationsByValidatorIDs(ctx context.Context, ids []primitives.ValidatorIndex, regs []*ethpb.ValidatorRegistrationV1) error // light client operations - SaveLightClientUpdate(ctx context.Context, period uint64, update *ethpbv2.LightClientUpdateWithVersion) error + SaveLightClientUpdate(ctx context.Context, period uint64, update interfaces.LightClientUpdate) error CleanUpDirtyStates(ctx context.Context, slotsPerArchivedPoint primitives.Slot) error } diff --git a/beacon-chain/db/kv/BUILD.bazel b/beacon-chain/db/kv/BUILD.bazel index 732da2fb5b2a..0a95e714aeb3 100644 --- a/beacon-chain/db/kv/BUILD.bazel +++ b/beacon-chain/db/kv/BUILD.bazel @@ -44,6 +44,7 @@ go_library( "//config/params:go_default_library", "//consensus-types/blocks:go_default_library", "//consensus-types/interfaces:go_default_library", + "//consensus-types/light-client:go_default_library", "//consensus-types/primitives:go_default_library", "//container/slice:go_default_library", "//encoding/bytesutil:go_default_library", @@ -53,7 +54,6 @@ go_library( "//monitoring/tracing:go_default_library", "//monitoring/tracing/trace:go_default_library", "//proto/dbval:go_default_library", - "//proto/eth/v2:go_default_library", "//proto/prysm/v1alpha1:go_default_library", "//runtime/version:go_default_library", "//time:go_default_library", diff --git a/beacon-chain/db/kv/lightclient.go b/beacon-chain/db/kv/lightclient.go index 3c7bef3ff5f1..d7bbc1796814 100644 --- a/beacon-chain/db/kv/lightclient.go +++ b/beacon-chain/db/kv/lightclient.go @@ -5,35 +5,41 @@ import ( "encoding/binary" "fmt" + "github.com/golang/snappy" + "github.com/pkg/errors" + "github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces" + light_client "github.com/prysmaticlabs/prysm/v5/consensus-types/light-client" "github.com/prysmaticlabs/prysm/v5/encoding/bytesutil" "github.com/prysmaticlabs/prysm/v5/monitoring/tracing/trace" - ethpbv2 "github.com/prysmaticlabs/prysm/v5/proto/eth/v2" + ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" + "github.com/prysmaticlabs/prysm/v5/runtime/version" bolt "go.etcd.io/bbolt" + "google.golang.org/protobuf/proto" ) -func (s *Store) SaveLightClientUpdate(ctx context.Context, period uint64, update *ethpbv2.LightClientUpdateWithVersion) error { - ctx, span := trace.StartSpan(ctx, "BeaconDB.saveLightClientUpdate") +func (s *Store) SaveLightClientUpdate(ctx context.Context, period uint64, update interfaces.LightClientUpdate) error { + _, span := trace.StartSpan(ctx, "BeaconDB.SaveLightClientUpdate") defer span.End() return s.db.Update(func(tx *bolt.Tx) error { bkt := tx.Bucket(lightClientUpdatesBucket) - updateMarshalled, err := encode(ctx, update) + enc, err := encodeLightClientUpdate(update) if err != nil { return err } - return bkt.Put(bytesutil.Uint64ToBytesBigEndian(period), updateMarshalled) + return bkt.Put(bytesutil.Uint64ToBytesBigEndian(period), enc) }) } -func (s *Store) LightClientUpdates(ctx context.Context, startPeriod, endPeriod uint64) (map[uint64]*ethpbv2.LightClientUpdateWithVersion, error) { - ctx, span := trace.StartSpan(ctx, "BeaconDB.LightClientUpdates") +func (s *Store) LightClientUpdates(ctx context.Context, startPeriod, endPeriod uint64) (map[uint64]interfaces.LightClientUpdate, error) { + _, span := trace.StartSpan(ctx, "BeaconDB.LightClientUpdates") defer span.End() if startPeriod > endPeriod { return nil, fmt.Errorf("start period %d is greater than end period %d", startPeriod, endPeriod) } - updates := make(map[uint64]*ethpbv2.LightClientUpdateWithVersion) + updates := make(map[uint64]interfaces.LightClientUpdate) err := s.db.View(func(tx *bolt.Tx) error { bkt := tx.Bucket(lightClientUpdatesBucket) c := bkt.Cursor() @@ -46,11 +52,11 @@ func (s *Store) LightClientUpdates(ctx context.Context, startPeriod, endPeriod u for k, v := c.Seek(bytesutil.Uint64ToBytesBigEndian(startPeriod)); k != nil && binary.BigEndian.Uint64(k) <= endPeriod; k, v = c.Next() { currentPeriod := binary.BigEndian.Uint64(k) - var update ethpbv2.LightClientUpdateWithVersion - if err := decode(ctx, v, &update); err != nil { + update, err := decodeLightClientUpdate(v) + if err != nil { return err } - updates[currentPeriod] = &update + updates[currentPeriod] = update } return nil @@ -62,18 +68,87 @@ func (s *Store) LightClientUpdates(ctx context.Context, startPeriod, endPeriod u return updates, err } -func (s *Store) LightClientUpdate(ctx context.Context, period uint64) (*ethpbv2.LightClientUpdateWithVersion, error) { - ctx, span := trace.StartSpan(ctx, "BeaconDB.LightClientUpdate") +func (s *Store) LightClientUpdate(ctx context.Context, period uint64) (interfaces.LightClientUpdate, error) { + _, span := trace.StartSpan(ctx, "BeaconDB.LightClientUpdate") defer span.End() - var update ethpbv2.LightClientUpdateWithVersion + var update interfaces.LightClientUpdate err := s.db.View(func(tx *bolt.Tx) error { bkt := tx.Bucket(lightClientUpdatesBucket) updateBytes := bkt.Get(bytesutil.Uint64ToBytesBigEndian(period)) if updateBytes == nil { return nil } - return decode(ctx, updateBytes, &update) + var err error + update, err = decodeLightClientUpdate(updateBytes) + return err }) - return &update, err + return update, err +} + +func encodeLightClientUpdate(update interfaces.LightClientUpdate) ([]byte, error) { + key, err := keyForLightClientUpdate(update) + if err != nil { + return nil, err + } + enc, err := update.MarshalSSZ() + if err != nil { + return nil, errors.Wrap(err, "could not marshal light client update") + } + fullEnc := make([]byte, len(key)+len(enc)) + copy(fullEnc[len(key):], enc) + return snappy.Encode(nil, fullEnc), nil +} + +func decodeLightClientUpdate(enc []byte) (interfaces.LightClientUpdate, error) { + var err error + enc, err = snappy.Decode(nil, enc) + if err != nil { + return nil, errors.Wrap(err, "could not snappy decode light client update") + } + var m proto.Message + switch { + case hasAltairKey(enc): + update := ðpb.LightClientUpdateAltair{} + if err := update.UnmarshalSSZ(enc[len(altairKey):]); err != nil { + return nil, errors.Wrap(err, "could not unmarshal Altair light client update") + } + m = update + case hasCapellaKey(enc): + update := ðpb.LightClientUpdateCapella{} + if err := update.UnmarshalSSZ(enc[len(capellaKey):]); err != nil { + return nil, errors.Wrap(err, "could not unmarshal Capella light client update") + } + m = update + case hasDenebKey(enc): + update := ðpb.LightClientUpdateDeneb{} + if err := update.UnmarshalSSZ(enc[len(denebKey):]); err != nil { + return nil, errors.Wrap(err, "could not unmarshal Deneb light client update") + } + m = update + case hasElectraKey(enc): + update := ðpb.LightClientUpdateElectra{} + if err := update.UnmarshalSSZ(enc[len(electraKey):]); err != nil { + return nil, errors.Wrap(err, "could not unmarshal Electra light client update") + } + m = update + default: + return nil, errors.New("decoding of saved light client update is unsupported") + } + return light_client.NewWrappedUpdate(m) +} + +func keyForLightClientUpdate(update interfaces.LightClientUpdate) ([]byte, error) { + switch v := update.Version(); v { + case version.Electra: + return electraKey, nil + case version.Deneb: + return denebKey, nil + case version.Capella: + return capellaKey, nil + case version.Altair: + return altairKey, nil + default: + return nil, fmt.Errorf("unsupported light client update version %s", version.String(v)) + } } diff --git a/beacon-chain/execution/engine_client.go b/beacon-chain/execution/engine_client.go index 2dfc479f4214..e3a295424083 100644 --- a/beacon-chain/execution/engine_client.go +++ b/beacon-chain/execution/engine_client.go @@ -687,7 +687,7 @@ func tDStringToUint256(td string) (*uint256.Int, error) { return i, nil } -func buildEmptyExecutionPayload(v int) (proto.Message, error) { +func EmptyExecutionPayload(v int) (proto.Message, error) { switch v { case version.Bellatrix: return &pb.ExecutionPayload{ diff --git a/beacon-chain/execution/payload_body.go b/beacon-chain/execution/payload_body.go index 17aba3329e0f..4021bb2339f2 100644 --- a/beacon-chain/execution/payload_body.go +++ b/beacon-chain/execution/payload_body.go @@ -205,7 +205,7 @@ func (r *blindedBlockReconstructor) requestBodiesByHash(ctx context.Context, cli func (r *blindedBlockReconstructor) payloadForHeader(header interfaces.ExecutionData, v int) (proto.Message, error) { bodyKey := bytesutil.ToBytes32(header.BlockHash()) if bodyKey == params.BeaconConfig().ZeroHash { - payload, err := buildEmptyExecutionPayload(v) + payload, err := EmptyExecutionPayload(v) if err != nil { return nil, errors.Wrapf(err, "failed to reconstruct payload for body hash %#x", bodyKey) } diff --git a/beacon-chain/rpc/endpoints.go b/beacon-chain/rpc/endpoints.go index f6b47009582b..fada0a671505 100644 --- a/beacon-chain/rpc/endpoints.go +++ b/beacon-chain/rpc/endpoints.go @@ -848,10 +848,11 @@ func (*Service) configEndpoints() []endpoint { func (s *Service) lightClientEndpoints(blocker lookup.Blocker, stater lookup.Stater) []endpoint { server := &lightclient.Server{ - Blocker: blocker, - Stater: stater, - HeadFetcher: s.cfg.HeadFetcher, - BeaconDB: s.cfg.BeaconDB, + Blocker: blocker, + Stater: stater, + HeadFetcher: s.cfg.HeadFetcher, + ChainInfoFetcher: s.cfg.ChainInfoFetcher, + BeaconDB: s.cfg.BeaconDB, } const namespace = "lightclient" diff --git a/beacon-chain/rpc/eth/events/events.go b/beacon-chain/rpc/eth/events/events.go index 7698d2fb9017..f50687fe9436 100644 --- a/beacon-chain/rpc/eth/events/events.go +++ b/beacon-chain/rpc/eth/events/events.go @@ -485,28 +485,30 @@ func (s *Server) lazyReaderForEvent(ctx context.Context, event *feed.Event, topi return jsonMarshalReader(eventName, structs.FinalizedCheckpointEventFromV1(v)) }, nil case *ethpbv2.LightClientFinalityUpdateWithVersion: - cv, err := structs.LightClientFinalityUpdateFromConsensus(v.Data) + // TODO: Get back to this when revisiting events + /*cv, err := structs.LightClientFinalityUpdateFromConsensus(v.Data) if err != nil { return nil, errors.Wrap(err, "LightClientFinalityUpdateWithVersion event conversion failure") } ev := &structs.LightClientFinalityUpdateEvent{ Version: version.String(int(v.Version)), Data: cv, - } + }*/ return func() io.Reader { - return jsonMarshalReader(eventName, ev) + return jsonMarshalReader(eventName, struct{}{}) }, nil case *ethpbv2.LightClientOptimisticUpdateWithVersion: - cv, err := structs.LightClientOptimisticUpdateFromConsensus(v.Data) + // TODO: Get back to this when revisiting events + /*cv, err := structs.LightClientOptimisticUpdateFromConsensus(v.Data) if err != nil { return nil, errors.Wrap(err, "LightClientOptimisticUpdateWithVersion event conversion failure") } ev := &structs.LightClientOptimisticUpdateEvent{ Version: version.String(int(v.Version)), Data: cv, - } + }*/ return func() io.Reader { - return jsonMarshalReader(eventName, ev) + return jsonMarshalReader(eventName, struct{}{}) }, nil case *ethpb.EventChainReorg: return func() io.Reader { diff --git a/beacon-chain/rpc/eth/light-client/BUILD.bazel b/beacon-chain/rpc/eth/light-client/BUILD.bazel index 85b46a07ecc4..d0fa6cb7a801 100644 --- a/beacon-chain/rpc/eth/light-client/BUILD.bazel +++ b/beacon-chain/rpc/eth/light-client/BUILD.bazel @@ -24,8 +24,6 @@ go_library( "//consensus-types/primitives:go_default_library", "//monitoring/tracing/trace:go_default_library", "//network/httputil:go_default_library", - "//proto/eth/v2:go_default_library", - "//proto/migration:go_default_library", "//runtime/version:go_default_library", "//time/slots:go_default_library", "@com_github_ethereum_go_ethereum//common/hexutil:go_default_library", diff --git a/beacon-chain/rpc/eth/light-client/handlers.go b/beacon-chain/rpc/eth/light-client/handlers.go index 245d703eaafd..3bc6909486da 100644 --- a/beacon-chain/rpc/eth/light-client/handlers.go +++ b/beacon-chain/rpc/eth/light-client/handlers.go @@ -47,7 +47,7 @@ func (s *Server) GetLightClientBootstrap(w http.ResponseWriter, req *http.Reques return } - bootstrap, err := createLightClientBootstrap(ctx, state, blk) + bootstrap, err := createLightClientBootstrap(ctx, s.ChainInfoFetcher.CurrentSlot(), state, blk) if err != nil { httputil.HandleError(w, "could not get light client bootstrap: "+err.Error(), http.StatusInternalServerError) return @@ -201,6 +201,7 @@ func (s *Server) GetLightClientUpdatesByRange(w http.ResponseWriter, req *http.R update, err := newLightClientUpdateFromBeaconState( ctx, + s.ChainInfoFetcher.CurrentSlot(), state, block, attestedState, @@ -268,7 +269,7 @@ func (s *Server) GetLightClientFinalityUpdate(w http.ResponseWriter, req *http.R return } - update, err := newLightClientFinalityUpdateFromBeaconState(ctx, st, block, attestedState, attestedBlock, finalizedBlock) + update, err := newLightClientFinalityUpdateFromBeaconState(ctx, s.ChainInfoFetcher.CurrentSlot(), st, block, attestedState, attestedBlock, finalizedBlock) if err != nil { httputil.HandleError(w, "Could not get light client finality update: "+err.Error(), http.StatusInternalServerError) return @@ -313,7 +314,7 @@ func (s *Server) GetLightClientOptimisticUpdate(w http.ResponseWriter, req *http return } - update, err := newLightClientOptimisticUpdateFromBeaconState(ctx, st, block, attestedState, attestedBlock) + update, err := newLightClientOptimisticUpdateFromBeaconState(ctx, s.ChainInfoFetcher.CurrentSlot(), st, block, attestedState, attestedBlock) if err != nil { httputil.HandleError(w, "Could not get light client optimistic update: "+err.Error(), http.StatusInternalServerError) return diff --git a/beacon-chain/rpc/eth/light-client/helpers.go b/beacon-chain/rpc/eth/light-client/helpers.go index ce989a7d5672..f1f6cbdf7af1 100644 --- a/beacon-chain/rpc/eth/light-client/helpers.go +++ b/beacon-chain/rpc/eth/light-client/helpers.go @@ -7,7 +7,8 @@ import ( "reflect" "github.com/pkg/errors" - "github.com/prysmaticlabs/prysm/v5/proto/migration" + fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams" + "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" lightclient "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/light-client" "github.com/prysmaticlabs/prysm/v5/runtime/version" @@ -15,28 +16,17 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" "github.com/prysmaticlabs/prysm/v5/api/server/structs" "github.com/prysmaticlabs/prysm/v5/beacon-chain/state" - fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams" "github.com/prysmaticlabs/prysm/v5/config/params" "github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces" - v2 "github.com/prysmaticlabs/prysm/v5/proto/eth/v2" "github.com/prysmaticlabs/prysm/v5/time/slots" ) -func createLightClientBootstrap(ctx context.Context, state state.BeaconState, blk interfaces.ReadOnlySignedBeaconBlock) (*structs.LightClientBootstrap, error) { - switch blk.Version() { - case version.Phase0: - return nil, fmt.Errorf("light client bootstrap is not supported for phase0") - case version.Altair, version.Bellatrix: - return createLightClientBootstrapAltair(ctx, state, blk) - case version.Capella: - return createLightClientBootstrapCapella(ctx, state, blk) - case version.Deneb, version.Electra: - return createLightClientBootstrapDeneb(ctx, state, blk) - } - return nil, fmt.Errorf("unsupported block version %s", version.String(blk.Version())) -} - -func createLightClientBootstrapAltair(ctx context.Context, state state.BeaconState, block interfaces.ReadOnlySignedBeaconBlock) (*structs.LightClientBootstrap, error) { +func createLightClientBootstrap( + ctx context.Context, + currentSlot primitives.Slot, + state state.BeaconState, + block interfaces.ReadOnlySignedBeaconBlock, +) (*structs.LightClientBootstrap, error) { // assert compute_epoch_at_slot(state.slot) >= ALTAIR_FORK_EPOCH if slots.ToEpoch(state.Slot()) < params.BeaconConfig().AltairForkEpoch { return nil, fmt.Errorf("light client bootstrap is not supported before Altair, invalid slot %d", state.Slot()) @@ -68,82 +58,13 @@ func createLightClientBootstrapAltair(ctx context.Context, state state.BeaconSta return nil, fmt.Errorf("latest block header root %#x not equal to block root %#x", latestBlockHeaderRoot, beaconBlockRoot) } - lightClientHeaderContainer, err := lightclient.BlockToLightClientHeader(block) - if err != nil { - return nil, errors.Wrap(err, "could not convert block to light client header") - } - lightClientHeader := lightClientHeaderContainer.GetHeaderAltair() - - apiLightClientHeader := &structs.LightClientHeader{ - Beacon: structs.BeaconBlockHeaderFromConsensus(migration.V1HeaderToV1Alpha1(lightClientHeader.Beacon)), - } - - headerJSON, err := json.Marshal(apiLightClientHeader) - if err != nil { - return nil, errors.Wrap(err, "could not convert header to raw message") - } - currentSyncCommittee, err := state.CurrentSyncCommittee() - if err != nil { - return nil, errors.Wrap(err, "could not get current sync committee") - } - currentSyncCommitteeProof, err := state.CurrentSyncCommitteeProof(ctx) - if err != nil { - return nil, errors.Wrap(err, "could not get current sync committee proof") - } - - branch := make([]string, fieldparams.SyncCommitteeBranchDepth) - for i, proof := range currentSyncCommitteeProof { - branch[i] = hexutil.Encode(proof) - } - result := &structs.LightClientBootstrap{ - Header: headerJSON, - CurrentSyncCommittee: structs.SyncCommitteeFromConsensus(currentSyncCommittee), - CurrentSyncCommitteeBranch: branch, - } - - return result, nil -} - -func createLightClientBootstrapCapella(ctx context.Context, state state.BeaconState, block interfaces.ReadOnlySignedBeaconBlock) (*structs.LightClientBootstrap, error) { - // assert compute_epoch_at_slot(state.slot) >= CAPELLA_FORK_EPOCH - if slots.ToEpoch(state.Slot()) < params.BeaconConfig().CapellaForkEpoch { - return nil, fmt.Errorf("creating Capella light client bootstrap is not supported before Capella, invalid slot %d", state.Slot()) - } - - // assert state.slot == state.latest_block_header.slot - latestBlockHeader := state.LatestBlockHeader() - if state.Slot() != latestBlockHeader.Slot { - return nil, fmt.Errorf("state slot %d not equal to latest block header slot %d", state.Slot(), latestBlockHeader.Slot) - } - - // header.state_root = hash_tree_root(state) - stateRoot, err := state.HashTreeRoot(ctx) - if err != nil { - return nil, errors.Wrap(err, "could not get state root") - } - latestBlockHeader.StateRoot = stateRoot[:] - - // assert hash_tree_root(header) == hash_tree_root(block.message) - latestBlockHeaderRoot, err := latestBlockHeader.HashTreeRoot() - if err != nil { - return nil, errors.Wrap(err, "could not get latest block header root") - } - beaconBlockRoot, err := block.Block().HashTreeRoot() - if err != nil { - return nil, errors.Wrap(err, "could not get block root") - } - if latestBlockHeaderRoot != beaconBlockRoot { - return nil, fmt.Errorf("latest block header root %#x not equal to block root %#x", latestBlockHeaderRoot, beaconBlockRoot) - } - - lightClientHeaderContainer, err := lightclient.BlockToLightClientHeader(block) + lightClientHeader, err := lightclient.BlockToLightClientHeader(ctx, currentSlot, block) if err != nil { return nil, errors.Wrap(err, "could not convert block to light client header") } - lightClientHeader := lightClientHeaderContainer.GetHeaderCapella() apiLightClientHeader := &structs.LightClientHeader{ - Beacon: structs.BeaconBlockHeaderFromConsensus(migration.V1HeaderToV1Alpha1(lightClientHeader.Beacon)), + Beacon: structs.BeaconBlockHeaderFromConsensus(lightClientHeader.Beacon()), } headerJSON, err := json.Marshal(apiLightClientHeader) @@ -159,83 +80,16 @@ func createLightClientBootstrapCapella(ctx context.Context, state state.BeaconSt return nil, errors.Wrap(err, "could not get current sync committee proof") } - branch := make([]string, fieldparams.SyncCommitteeBranchDepth) - for i, proof := range currentSyncCommitteeProof { - branch[i] = hexutil.Encode(proof) - } - result := &structs.LightClientBootstrap{ - Header: headerJSON, - CurrentSyncCommittee: structs.SyncCommitteeFromConsensus(currentSyncCommittee), - CurrentSyncCommitteeBranch: branch, - } - - return result, nil -} - -func createLightClientBootstrapDeneb(ctx context.Context, state state.BeaconState, block interfaces.ReadOnlySignedBeaconBlock) (*structs.LightClientBootstrap, error) { - // assert compute_epoch_at_slot(state.slot) >= DENEB_FORK_EPOCH - if slots.ToEpoch(state.Slot()) < params.BeaconConfig().DenebForkEpoch { - return nil, fmt.Errorf("creating Deneb light client bootstrap is not supported before Deneb, invalid slot %d", state.Slot()) - } - - // assert state.slot == state.latest_block_header.slot - latestBlockHeader := state.LatestBlockHeader() - if state.Slot() != latestBlockHeader.Slot { - return nil, fmt.Errorf("state slot %d not equal to latest block header slot %d", state.Slot(), latestBlockHeader.Slot) - } - - // header.state_root = hash_tree_root(state) - stateRoot, err := state.HashTreeRoot(ctx) - if err != nil { - return nil, errors.Wrap(err, "could not get state root") - } - latestBlockHeader.StateRoot = stateRoot[:] - - // assert hash_tree_root(header) == hash_tree_root(block.message) - latestBlockHeaderRoot, err := latestBlockHeader.HashTreeRoot() - if err != nil { - return nil, errors.Wrap(err, "could not get latest block header root") - } - beaconBlockRoot, err := block.Block().HashTreeRoot() - if err != nil { - return nil, errors.Wrap(err, "could not get block root") - } - if latestBlockHeaderRoot != beaconBlockRoot { - return nil, fmt.Errorf("latest block header root %#x not equal to block root %#x", latestBlockHeaderRoot, beaconBlockRoot) - } - - lightClientHeaderContainer, err := lightclient.BlockToLightClientHeader(block) - if err != nil { - return nil, errors.Wrap(err, "could not convert block to light client header") - } - lightClientHeader := lightClientHeaderContainer.GetHeaderDeneb() - - apiLightClientHeader := &structs.LightClientHeader{ - Beacon: structs.BeaconBlockHeaderFromConsensus(migration.V1HeaderToV1Alpha1(lightClientHeader.Beacon)), - } - - headerJSON, err := json.Marshal(apiLightClientHeader) - if err != nil { - return nil, errors.Wrap(err, "could not convert header to raw message") - } - currentSyncCommittee, err := state.CurrentSyncCommittee() - if err != nil { - return nil, errors.Wrap(err, "could not get current sync committee") - } - currentSyncCommitteeProof, err := state.CurrentSyncCommitteeProof(ctx) - if err != nil { - return nil, errors.Wrap(err, "could not get current sync committee proof") - } var branch []string - switch block.Version() { - case version.Deneb: - branch = make([]string, fieldparams.SyncCommitteeBranchDepth) - case version.Electra: + if state.Version() >= version.Electra { branch = make([]string, fieldparams.SyncCommitteeBranchDepthElectra) + } else { + branch = make([]string, fieldparams.SyncCommitteeBranchDepth) } for i, proof := range currentSyncCommitteeProof { branch[i] = hexutil.Encode(proof) } + result := &structs.LightClientBootstrap{ Header: headerJSON, CurrentSyncCommittee: structs.SyncCommitteeFromConsensus(currentSyncCommittee), @@ -247,13 +101,14 @@ func createLightClientBootstrapDeneb(ctx context.Context, state state.BeaconStat func newLightClientUpdateFromBeaconState( ctx context.Context, + currentSlot primitives.Slot, state state.BeaconState, block interfaces.ReadOnlySignedBeaconBlock, attestedState state.BeaconState, attestedBlock interfaces.ReadOnlySignedBeaconBlock, finalizedBlock interfaces.ReadOnlySignedBeaconBlock, ) (*structs.LightClientUpdate, error) { - result, err := lightclient.NewLightClientUpdateFromBeaconState(ctx, state, block, attestedState, attestedBlock, finalizedBlock) + result, err := lightclient.NewLightClientUpdateFromBeaconState(ctx, currentSlot, state, block, attestedState, attestedBlock, finalizedBlock) if err != nil { return nil, err } @@ -263,13 +118,14 @@ func newLightClientUpdateFromBeaconState( func newLightClientFinalityUpdateFromBeaconState( ctx context.Context, + currentSlot primitives.Slot, state state.BeaconState, block interfaces.ReadOnlySignedBeaconBlock, attestedState state.BeaconState, attestedBlock interfaces.ReadOnlySignedBeaconBlock, finalizedBlock interfaces.ReadOnlySignedBeaconBlock, ) (*structs.LightClientFinalityUpdate, error) { - result, err := lightclient.NewLightClientFinalityUpdateFromBeaconState(ctx, state, block, attestedState, attestedBlock, finalizedBlock) + result, err := lightclient.NewLightClientFinalityUpdateFromBeaconState(ctx, currentSlot, state, block, attestedState, attestedBlock, finalizedBlock) if err != nil { return nil, err } @@ -279,12 +135,13 @@ func newLightClientFinalityUpdateFromBeaconState( func newLightClientOptimisticUpdateFromBeaconState( ctx context.Context, + currentSlot primitives.Slot, state state.BeaconState, block interfaces.ReadOnlySignedBeaconBlock, attestedState state.BeaconState, attestedBlock interfaces.ReadOnlySignedBeaconBlock, ) (*structs.LightClientOptimisticUpdate, error) { - result, err := lightclient.NewLightClientOptimisticUpdateFromBeaconState(ctx, state, block, attestedState, attestedBlock) + result, err := lightclient.NewLightClientOptimisticUpdateFromBeaconState(ctx, currentSlot, state, block, attestedState, attestedBlock) if err != nil { return nil, err } @@ -292,20 +149,29 @@ func newLightClientOptimisticUpdateFromBeaconState( return structs.LightClientOptimisticUpdateFromConsensus(result) } -func IsSyncCommitteeUpdate(update *v2.LightClientUpdate) bool { - nextSyncCommitteeBranch := make([][]byte, fieldparams.SyncCommitteeBranchDepth) - return !reflect.DeepEqual(update.NextSyncCommitteeBranch, nextSyncCommitteeBranch) +func HasRelevantSyncCommittee(update interfaces.LightClientUpdate) (bool, error) { + if update.Version() >= version.Electra { + branch, err := update.NextSyncCommitteeBranchElectra() + if err != nil { + return false, err + } + return !reflect.DeepEqual(branch, interfaces.LightClientSyncCommitteeBranchElectra{}), nil + } + branch, err := update.NextSyncCommitteeBranch() + if err != nil { + return false, err + } + return !reflect.DeepEqual(branch, interfaces.LightClientSyncCommitteeBranch{}), nil } -func IsFinalityUpdate(update *v2.LightClientUpdate) bool { - finalityBranch := make([][]byte, lightclient.FinalityBranchNumOfLeaves) - return !reflect.DeepEqual(update.FinalityBranch, finalityBranch) +func HasFinality(update interfaces.LightClientUpdate) bool { + return !reflect.DeepEqual(update.FinalityBranch(), interfaces.LightClientFinalityBranch{}) } -func IsBetterUpdate(newUpdate, oldUpdate *v2.LightClientUpdate) (bool, error) { - maxActiveParticipants := newUpdate.SyncAggregate.SyncCommitteeBits.Len() - newNumActiveParticipants := newUpdate.SyncAggregate.SyncCommitteeBits.Count() - oldNumActiveParticipants := oldUpdate.SyncAggregate.SyncCommitteeBits.Count() +func IsBetterUpdate(newUpdate, oldUpdate interfaces.LightClientUpdate) (bool, error) { + maxActiveParticipants := newUpdate.SyncAggregate().SyncCommitteeBits.Len() + newNumActiveParticipants := newUpdate.SyncAggregate().SyncCommitteeBits.Count() + oldNumActiveParticipants := oldUpdate.SyncAggregate().SyncCommitteeBits.Count() newHasSupermajority := newNumActiveParticipants*3 >= maxActiveParticipants*2 oldHasSupermajority := oldNumActiveParticipants*3 >= maxActiveParticipants*2 @@ -316,43 +182,45 @@ func IsBetterUpdate(newUpdate, oldUpdate *v2.LightClientUpdate) (bool, error) { return newNumActiveParticipants > oldNumActiveParticipants, nil } - newUpdateAttestedHeaderBeacon, err := newUpdate.AttestedHeader.GetBeacon() + newUpdateAttestedHeaderBeacon := newUpdate.AttestedHeader().Beacon() + oldUpdateAttestedHeaderBeacon := oldUpdate.AttestedHeader().Beacon() + + // Compare presence of relevant sync committee + newHasRelevantSyncCommittee, err := HasRelevantSyncCommittee(newUpdate) if err != nil { - return false, errors.Wrap(err, "could not get attested header beacon") + return false, err } - oldUpdateAttestedHeaderBeacon, err := oldUpdate.AttestedHeader.GetBeacon() + newHasRelevantSyncCommittee = newHasRelevantSyncCommittee && + (slots.SyncCommitteePeriod(slots.ToEpoch(newUpdateAttestedHeaderBeacon.Slot)) == slots.SyncCommitteePeriod(slots.ToEpoch(newUpdate.SignatureSlot()))) + oldHasRelevantSyncCommittee, err := HasRelevantSyncCommittee(oldUpdate) if err != nil { - return false, errors.Wrap(err, "could not get attested header beacon") + return false, err } - - // Compare presence of relevant sync committee - newHasRelevantSyncCommittee := IsSyncCommitteeUpdate(newUpdate) && (slots.SyncCommitteePeriod(slots.ToEpoch(newUpdateAttestedHeaderBeacon.Slot)) == slots.SyncCommitteePeriod(slots.ToEpoch(newUpdate.SignatureSlot))) - oldHasRelevantSyncCommittee := IsSyncCommitteeUpdate(oldUpdate) && (slots.SyncCommitteePeriod(slots.ToEpoch(oldUpdateAttestedHeaderBeacon.Slot)) == slots.SyncCommitteePeriod(slots.ToEpoch(oldUpdate.SignatureSlot))) + oldHasRelevantSyncCommittee = oldHasRelevantSyncCommittee && + (slots.SyncCommitteePeriod(slots.ToEpoch(oldUpdateAttestedHeaderBeacon.Slot)) == slots.SyncCommitteePeriod(slots.ToEpoch(oldUpdate.SignatureSlot()))) if newHasRelevantSyncCommittee != oldHasRelevantSyncCommittee { return newHasRelevantSyncCommittee, nil } // Compare indication of any finality - newHasFinality := IsFinalityUpdate(newUpdate) - oldHasFinality := IsFinalityUpdate(oldUpdate) + newHasFinality := HasFinality(newUpdate) + oldHasFinality := HasFinality(oldUpdate) if newHasFinality != oldHasFinality { return newHasFinality, nil } - newUpdateFinalizedHeaderBeacon, err := newUpdate.FinalizedHeader.GetBeacon() - if err != nil { - return false, errors.Wrap(err, "could not get finalized header beacon") - } - oldUpdateFinalizedHeaderBeacon, err := oldUpdate.FinalizedHeader.GetBeacon() - if err != nil { - return false, errors.Wrap(err, "could not get finalized header beacon") - } + newUpdateFinalizedHeaderBeacon := newUpdate.FinalizedHeader().Beacon() + oldUpdateFinalizedHeaderBeacon := oldUpdate.FinalizedHeader().Beacon() // Compare sync committee finality if newHasFinality { - newHasSyncCommitteeFinality := slots.SyncCommitteePeriod(slots.ToEpoch(newUpdateFinalizedHeaderBeacon.Slot)) == slots.SyncCommitteePeriod(slots.ToEpoch(newUpdateAttestedHeaderBeacon.Slot)) - oldHasSyncCommitteeFinality := slots.SyncCommitteePeriod(slots.ToEpoch(oldUpdateFinalizedHeaderBeacon.Slot)) == slots.SyncCommitteePeriod(slots.ToEpoch(oldUpdateAttestedHeaderBeacon.Slot)) + newHasSyncCommitteeFinality := + slots.SyncCommitteePeriod(slots.ToEpoch(newUpdateFinalizedHeaderBeacon.Slot)) == + slots.SyncCommitteePeriod(slots.ToEpoch(newUpdateAttestedHeaderBeacon.Slot)) + oldHasSyncCommitteeFinality := + slots.SyncCommitteePeriod(slots.ToEpoch(oldUpdateFinalizedHeaderBeacon.Slot)) == + slots.SyncCommitteePeriod(slots.ToEpoch(oldUpdateAttestedHeaderBeacon.Slot)) if newHasSyncCommitteeFinality != oldHasSyncCommitteeFinality { return newHasSyncCommitteeFinality, nil @@ -368,5 +236,6 @@ func IsBetterUpdate(newUpdate, oldUpdate *v2.LightClientUpdate) (bool, error) { if newUpdateAttestedHeaderBeacon.Slot != oldUpdateAttestedHeaderBeacon.Slot { return newUpdateAttestedHeaderBeacon.Slot < oldUpdateAttestedHeaderBeacon.Slot, nil } - return newUpdate.SignatureSlot < oldUpdate.SignatureSlot, nil + + return newUpdate.SignatureSlot() < oldUpdate.SignatureSlot(), nil } diff --git a/beacon-chain/rpc/eth/light-client/server.go b/beacon-chain/rpc/eth/light-client/server.go index e0773a306405..84b061379fc1 100644 --- a/beacon-chain/rpc/eth/light-client/server.go +++ b/beacon-chain/rpc/eth/light-client/server.go @@ -7,8 +7,9 @@ import ( ) type Server struct { - Blocker lookup.Blocker - Stater lookup.Stater - HeadFetcher blockchain.HeadFetcher - BeaconDB db.HeadAccessDatabase + Blocker lookup.Blocker + Stater lookup.Stater + HeadFetcher blockchain.HeadFetcher + ChainInfoFetcher blockchain.ChainInfoFetcher + BeaconDB db.HeadAccessDatabase } diff --git a/consensus-types/interfaces/light_client.go b/consensus-types/interfaces/light_client.go index 217a086497d4..994470c65a42 100644 --- a/consensus-types/interfaces/light_client.go +++ b/consensus-types/interfaces/light_client.go @@ -5,6 +5,7 @@ import ( fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams" "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" pb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" + "google.golang.org/protobuf/proto" ) type LightClientExecutionBranch = [fieldparams.ExecutionBranchDepth][fieldparams.RootLength]byte @@ -14,6 +15,7 @@ type LightClientFinalityBranch = [fieldparams.FinalityBranchDepth][fieldparams.R type LightClientHeader interface { ssz.Marshaler + Proto() proto.Message Version() int Beacon() *pb.BeaconBlockHeader Execution() (ExecutionData, error) @@ -31,19 +33,29 @@ type LightClientBootstrap interface { type LightClientUpdate interface { ssz.Marshaler + Proto() proto.Message Version() int AttestedHeader() LightClientHeader + SetAttestedHeader(header LightClientHeader) NextSyncCommittee() *pb.SyncCommittee + SetNextSyncCommittee(sc *pb.SyncCommittee) NextSyncCommitteeBranch() (LightClientSyncCommitteeBranch, error) + SetNextSyncCommitteeBranch(branch [][]byte) error NextSyncCommitteeBranchElectra() (LightClientSyncCommitteeBranchElectra, error) + SetNextSyncCommitteeBranchElectra(branch [][]byte) error FinalizedHeader() LightClientHeader + SetFinalizedHeader(header LightClientHeader) FinalityBranch() LightClientFinalityBranch + SetFinalityBranch(branch [][]byte) error SyncAggregate() *pb.SyncAggregate + SetSyncAggregate(sa *pb.SyncAggregate) SignatureSlot() primitives.Slot + SetSignatureSlot(slot primitives.Slot) } type LightClientFinalityUpdate interface { ssz.Marshaler + Proto() proto.Message Version() int AttestedHeader() LightClientHeader FinalizedHeader() LightClientHeader @@ -54,6 +66,7 @@ type LightClientFinalityUpdate interface { type LightClientOptimisticUpdate interface { ssz.Marshaler + Proto() proto.Message Version() int AttestedHeader() LightClientHeader SyncAggregate() *pb.SyncAggregate diff --git a/consensus-types/light-client/finality_update.go b/consensus-types/light-client/finality_update.go index 37de560e60ed..dad1259f2e75 100644 --- a/consensus-types/light-client/finality_update.go +++ b/consensus-types/light-client/finality_update.go @@ -28,6 +28,65 @@ func NewWrappedFinalityUpdate(m proto.Message) (interfaces.LightClientFinalityUp } } +func NewFinalityUpdateFromUpdate(update interfaces.LightClientUpdate) (interfaces.LightClientFinalityUpdate, error) { + switch t := update.(type) { + case *updateAltair: + return &finalityUpdateAltair{ + p: &pb.LightClientFinalityUpdateAltair{ + AttestedHeader: t.p.AttestedHeader, + FinalizedHeader: t.p.FinalizedHeader, + FinalityBranch: t.p.FinalityBranch, + SyncAggregate: t.p.SyncAggregate, + SignatureSlot: t.p.SignatureSlot, + }, + attestedHeader: t.attestedHeader, + finalizedHeader: t.finalizedHeader, + finalityBranch: t.finalityBranch, + }, nil + case *updateCapella: + return &finalityUpdateCapella{ + p: &pb.LightClientFinalityUpdateCapella{ + AttestedHeader: t.p.AttestedHeader, + FinalizedHeader: t.p.FinalizedHeader, + FinalityBranch: t.p.FinalityBranch, + SyncAggregate: t.p.SyncAggregate, + SignatureSlot: t.p.SignatureSlot, + }, + attestedHeader: t.attestedHeader, + finalizedHeader: t.finalizedHeader, + finalityBranch: t.finalityBranch, + }, nil + case *updateDeneb: + return &finalityUpdateDeneb{ + p: &pb.LightClientFinalityUpdateDeneb{ + AttestedHeader: t.p.AttestedHeader, + FinalizedHeader: t.p.FinalizedHeader, + FinalityBranch: t.p.FinalityBranch, + SyncAggregate: t.p.SyncAggregate, + SignatureSlot: t.p.SignatureSlot, + }, + attestedHeader: t.attestedHeader, + finalizedHeader: t.finalizedHeader, + finalityBranch: t.finalityBranch, + }, nil + case *updateElectra: + return &finalityUpdateDeneb{ + p: &pb.LightClientFinalityUpdateDeneb{ + AttestedHeader: t.p.AttestedHeader, + FinalizedHeader: t.p.FinalizedHeader, + FinalityBranch: t.p.FinalityBranch, + SyncAggregate: t.p.SyncAggregate, + SignatureSlot: t.p.SignatureSlot, + }, + attestedHeader: t.attestedHeader, + finalizedHeader: t.finalizedHeader, + finalityBranch: t.finalityBranch, + }, nil + default: + return nil, fmt.Errorf("unsupported type %T", t) + } +} + type finalityUpdateAltair struct { p *pb.LightClientFinalityUpdateAltair attestedHeader interfaces.LightClientHeader @@ -78,6 +137,10 @@ func (u *finalityUpdateAltair) SizeSSZ() int { return u.p.SizeSSZ() } +func (u *finalityUpdateAltair) Proto() proto.Message { + return u.p +} + func (u *finalityUpdateAltair) Version() int { return version.Altair } @@ -152,6 +215,10 @@ func (u *finalityUpdateCapella) SizeSSZ() int { return u.p.SizeSSZ() } +func (u *finalityUpdateCapella) Proto() proto.Message { + return u.p +} + func (u *finalityUpdateCapella) Version() int { return version.Capella } @@ -226,6 +293,10 @@ func (u *finalityUpdateDeneb) SizeSSZ() int { return u.p.SizeSSZ() } +func (u *finalityUpdateDeneb) Proto() proto.Message { + return u.p +} + func (u *finalityUpdateDeneb) Version() int { return version.Deneb } diff --git a/consensus-types/light-client/header.go b/consensus-types/light-client/header.go index 496a48424c7e..32b344227480 100644 --- a/consensus-types/light-client/header.go +++ b/consensus-types/light-client/header.go @@ -53,6 +53,10 @@ func (h *headerAltair) SizeSSZ() int { return h.p.SizeSSZ() } +func (h *headerAltair) Proto() proto.Message { + return h.p +} + func (h *headerAltair) Version() int { return version.Altair } @@ -114,6 +118,10 @@ func (h *headerCapella) SizeSSZ() int { return h.p.SizeSSZ() } +func (h *headerCapella) Proto() proto.Message { + return h.p +} + func (h *headerCapella) Version() int { return version.Capella } @@ -175,6 +183,10 @@ func (h *headerDeneb) SizeSSZ() int { return h.p.SizeSSZ() } +func (h *headerDeneb) Proto() proto.Message { + return h.p +} + func (h *headerDeneb) Version() int { return version.Deneb } diff --git a/consensus-types/light-client/helpers.go b/consensus-types/light-client/helpers.go index c2fc9b05922c..0d100314a4f9 100644 --- a/consensus-types/light-client/helpers.go +++ b/consensus-types/light-client/helpers.go @@ -4,12 +4,11 @@ import ( "fmt" fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams" - "github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces" "github.com/prysmaticlabs/prysm/v5/encoding/bytesutil" ) type branchConstraint interface { - ~interfaces.LightClientExecutionBranch | ~interfaces.LightClientSyncCommitteeBranch | ~interfaces.LightClientFinalityBranch + [4][32]byte | [5][32]byte | [6][32]byte } func createBranch[T branchConstraint](name string, input [][]byte, depth int) (T, error) { diff --git a/consensus-types/light-client/optimistic_update.go b/consensus-types/light-client/optimistic_update.go index f1f43d12cfa4..dd15ba02267e 100644 --- a/consensus-types/light-client/optimistic_update.go +++ b/consensus-types/light-client/optimistic_update.go @@ -27,12 +27,55 @@ func NewWrappedOptimisticUpdate(m proto.Message) (interfaces.LightClientOptimist } } -type OptimisticUpdateAltair struct { +func NewOptimisticUpdateFromUpdate(update interfaces.LightClientUpdate) (interfaces.LightClientOptimisticUpdate, error) { + switch t := update.(type) { + case *updateAltair: + return &optimisticUpdateAltair{ + p: &pb.LightClientOptimisticUpdateAltair{ + AttestedHeader: t.p.AttestedHeader, + SyncAggregate: t.p.SyncAggregate, + SignatureSlot: t.p.SignatureSlot, + }, + attestedHeader: t.attestedHeader, + }, nil + case *updateCapella: + return &optimisticUpdateCapella{ + p: &pb.LightClientOptimisticUpdateCapella{ + AttestedHeader: t.p.AttestedHeader, + SyncAggregate: t.p.SyncAggregate, + SignatureSlot: t.p.SignatureSlot, + }, + attestedHeader: t.attestedHeader, + }, nil + case *updateDeneb: + return &optimisticUpdateDeneb{ + p: &pb.LightClientOptimisticUpdateDeneb{ + AttestedHeader: t.p.AttestedHeader, + SyncAggregate: t.p.SyncAggregate, + SignatureSlot: t.p.SignatureSlot, + }, + attestedHeader: t.attestedHeader, + }, nil + case *updateElectra: + return &optimisticUpdateDeneb{ + p: &pb.LightClientOptimisticUpdateDeneb{ + AttestedHeader: t.p.AttestedHeader, + SyncAggregate: t.p.SyncAggregate, + SignatureSlot: t.p.SignatureSlot, + }, + attestedHeader: t.attestedHeader, + }, nil + default: + return nil, fmt.Errorf("unsupported type %T", t) + } +} + +type optimisticUpdateAltair struct { p *pb.LightClientOptimisticUpdateAltair attestedHeader interfaces.LightClientHeader } -var _ interfaces.LightClientOptimisticUpdate = &OptimisticUpdateAltair{} +var _ interfaces.LightClientOptimisticUpdate = &optimisticUpdateAltair{} func NewWrappedOptimisticUpdateAltair(p *pb.LightClientOptimisticUpdateAltair) (interfaces.LightClientOptimisticUpdate, error) { if p == nil { @@ -43,46 +86,50 @@ func NewWrappedOptimisticUpdateAltair(p *pb.LightClientOptimisticUpdateAltair) ( return nil, err } - return &OptimisticUpdateAltair{ + return &optimisticUpdateAltair{ p: p, attestedHeader: attestedHeader, }, nil } -func (u *OptimisticUpdateAltair) MarshalSSZTo(dst []byte) ([]byte, error) { +func (u *optimisticUpdateAltair) MarshalSSZTo(dst []byte) ([]byte, error) { return u.p.MarshalSSZTo(dst) } -func (u *OptimisticUpdateAltair) MarshalSSZ() ([]byte, error) { +func (u *optimisticUpdateAltair) MarshalSSZ() ([]byte, error) { return u.p.MarshalSSZ() } -func (u *OptimisticUpdateAltair) SizeSSZ() int { +func (u *optimisticUpdateAltair) SizeSSZ() int { return u.p.SizeSSZ() } -func (u *OptimisticUpdateAltair) Version() int { +func (u *optimisticUpdateAltair) Proto() proto.Message { + return u.p +} + +func (u *optimisticUpdateAltair) Version() int { return version.Altair } -func (u *OptimisticUpdateAltair) AttestedHeader() interfaces.LightClientHeader { +func (u *optimisticUpdateAltair) AttestedHeader() interfaces.LightClientHeader { return u.attestedHeader } -func (u *OptimisticUpdateAltair) SyncAggregate() *pb.SyncAggregate { +func (u *optimisticUpdateAltair) SyncAggregate() *pb.SyncAggregate { return u.p.SyncAggregate } -func (u *OptimisticUpdateAltair) SignatureSlot() primitives.Slot { +func (u *optimisticUpdateAltair) SignatureSlot() primitives.Slot { return u.p.SignatureSlot } -type OptimisticUpdateCapella struct { +type optimisticUpdateCapella struct { p *pb.LightClientOptimisticUpdateCapella attestedHeader interfaces.LightClientHeader } -var _ interfaces.LightClientOptimisticUpdate = &OptimisticUpdateCapella{} +var _ interfaces.LightClientOptimisticUpdate = &optimisticUpdateCapella{} func NewWrappedOptimisticUpdateCapella(p *pb.LightClientOptimisticUpdateCapella) (interfaces.LightClientOptimisticUpdate, error) { if p == nil { @@ -93,46 +140,50 @@ func NewWrappedOptimisticUpdateCapella(p *pb.LightClientOptimisticUpdateCapella) return nil, err } - return &OptimisticUpdateCapella{ + return &optimisticUpdateCapella{ p: p, attestedHeader: attestedHeader, }, nil } -func (u *OptimisticUpdateCapella) MarshalSSZTo(dst []byte) ([]byte, error) { +func (u *optimisticUpdateCapella) MarshalSSZTo(dst []byte) ([]byte, error) { return u.p.MarshalSSZTo(dst) } -func (u *OptimisticUpdateCapella) MarshalSSZ() ([]byte, error) { +func (u *optimisticUpdateCapella) MarshalSSZ() ([]byte, error) { return u.p.MarshalSSZ() } -func (u *OptimisticUpdateCapella) SizeSSZ() int { +func (u *optimisticUpdateCapella) SizeSSZ() int { return u.p.SizeSSZ() } -func (u *OptimisticUpdateCapella) Version() int { +func (u *optimisticUpdateCapella) Proto() proto.Message { + return u.p +} + +func (u *optimisticUpdateCapella) Version() int { return version.Capella } -func (u *OptimisticUpdateCapella) AttestedHeader() interfaces.LightClientHeader { +func (u *optimisticUpdateCapella) AttestedHeader() interfaces.LightClientHeader { return u.attestedHeader } -func (u *OptimisticUpdateCapella) SyncAggregate() *pb.SyncAggregate { +func (u *optimisticUpdateCapella) SyncAggregate() *pb.SyncAggregate { return u.p.SyncAggregate } -func (u *OptimisticUpdateCapella) SignatureSlot() primitives.Slot { +func (u *optimisticUpdateCapella) SignatureSlot() primitives.Slot { return u.p.SignatureSlot } -type OptimisticUpdateDeneb struct { +type optimisticUpdateDeneb struct { p *pb.LightClientOptimisticUpdateDeneb attestedHeader interfaces.LightClientHeader } -var _ interfaces.LightClientOptimisticUpdate = &OptimisticUpdateDeneb{} +var _ interfaces.LightClientOptimisticUpdate = &optimisticUpdateDeneb{} func NewWrappedOptimisticUpdateDeneb(p *pb.LightClientOptimisticUpdateDeneb) (interfaces.LightClientOptimisticUpdate, error) { if p == nil { @@ -143,36 +194,40 @@ func NewWrappedOptimisticUpdateDeneb(p *pb.LightClientOptimisticUpdateDeneb) (in return nil, err } - return &OptimisticUpdateDeneb{ + return &optimisticUpdateDeneb{ p: p, attestedHeader: attestedHeader, }, nil } -func (u *OptimisticUpdateDeneb) MarshalSSZTo(dst []byte) ([]byte, error) { +func (u *optimisticUpdateDeneb) MarshalSSZTo(dst []byte) ([]byte, error) { return u.p.MarshalSSZTo(dst) } -func (u *OptimisticUpdateDeneb) MarshalSSZ() ([]byte, error) { +func (u *optimisticUpdateDeneb) MarshalSSZ() ([]byte, error) { return u.p.MarshalSSZ() } -func (u *OptimisticUpdateDeneb) SizeSSZ() int { +func (u *optimisticUpdateDeneb) SizeSSZ() int { return u.p.SizeSSZ() } -func (u *OptimisticUpdateDeneb) Version() int { +func (u *optimisticUpdateDeneb) Proto() proto.Message { + return u.p +} + +func (u *optimisticUpdateDeneb) Version() int { return version.Deneb } -func (u *OptimisticUpdateDeneb) AttestedHeader() interfaces.LightClientHeader { +func (u *optimisticUpdateDeneb) AttestedHeader() interfaces.LightClientHeader { return u.attestedHeader } -func (u *OptimisticUpdateDeneb) SyncAggregate() *pb.SyncAggregate { +func (u *optimisticUpdateDeneb) SyncAggregate() *pb.SyncAggregate { return u.p.SyncAggregate } -func (u *OptimisticUpdateDeneb) SignatureSlot() primitives.Slot { +func (u *optimisticUpdateDeneb) SignatureSlot() primitives.Slot { return u.p.SignatureSlot } diff --git a/consensus-types/light-client/update.go b/consensus-types/light-client/update.go index 66a3403f1896..81ebf87f9c69 100644 --- a/consensus-types/light-client/update.go +++ b/consensus-types/light-client/update.go @@ -23,6 +23,8 @@ func NewWrappedUpdate(m proto.Message) (interfaces.LightClientUpdate, error) { return NewWrappedUpdateCapella(t) case *pb.LightClientUpdateDeneb: return NewWrappedUpdateDeneb(t) + case *pb.LightClientUpdateElectra: + return NewWrappedUpdateElectra(t) default: return nil, fmt.Errorf("cannot construct light client update from type %T", t) } @@ -46,10 +48,15 @@ func NewWrappedUpdateAltair(p *pb.LightClientUpdateAltair) (interfaces.LightClie if err != nil { return nil, err } - finalizedHeader, err := NewWrappedHeaderAltair(p.FinalizedHeader) - if err != nil { - return nil, err + + var finalizedHeader interfaces.LightClientHeader + if p.FinalizedHeader != nil { + finalizedHeader, err = NewWrappedHeaderAltair(p.FinalizedHeader) + if err != nil { + return nil, err + } } + scBranch, err := createBranch[interfaces.LightClientSyncCommitteeBranch]( "sync committee", p.NextSyncCommitteeBranch, @@ -88,6 +95,10 @@ func (u *updateAltair) SizeSSZ() int { return u.p.SizeSSZ() } +func (u *updateAltair) Proto() proto.Message { + return u.p +} + func (u *updateAltair) Version() int { return version.Altair } @@ -96,34 +107,76 @@ func (u *updateAltair) AttestedHeader() interfaces.LightClientHeader { return u.attestedHeader } +func (u *updateAltair) SetAttestedHeader(header interfaces.LightClientHeader) { + u.attestedHeader = header +} + func (u *updateAltair) NextSyncCommittee() *pb.SyncCommittee { return u.p.NextSyncCommittee } +func (u *updateAltair) SetNextSyncCommittee(sc *pb.SyncCommittee) { + u.p.NextSyncCommittee = sc +} + func (u *updateAltair) NextSyncCommitteeBranch() (interfaces.LightClientSyncCommitteeBranch, error) { return u.nextSyncCommitteeBranch, nil } +func (u *updateAltair) SetNextSyncCommitteeBranch(branch [][]byte) error { + b, err := createBranch[interfaces.LightClientSyncCommitteeBranch]("sync committee", branch, fieldparams.SyncCommitteeBranchDepth) + if err != nil { + return err + } + u.nextSyncCommitteeBranch = b + return nil +} + func (u *updateAltair) NextSyncCommitteeBranchElectra() (interfaces.LightClientSyncCommitteeBranchElectra, error) { return [6][32]byte{}, consensustypes.ErrNotSupported("NextSyncCommitteeBranchElectra", version.Altair) } +func (u *updateAltair) SetNextSyncCommitteeBranchElectra([][]byte) error { + return consensustypes.ErrNotSupported("SetNextSyncCommitteeBranchElectra", version.Altair) +} + func (u *updateAltair) FinalizedHeader() interfaces.LightClientHeader { return u.finalizedHeader } +func (u *updateAltair) SetFinalizedHeader(header interfaces.LightClientHeader) { + u.finalizedHeader = header +} + func (u *updateAltair) FinalityBranch() interfaces.LightClientFinalityBranch { return u.finalityBranch } +func (u *updateAltair) SetFinalityBranch(branch [][]byte) error { + b, err := createBranch[interfaces.LightClientFinalityBranch]("finality", branch, fieldparams.FinalityBranchDepth) + if err != nil { + return err + } + u.finalityBranch = b + return nil +} + func (u *updateAltair) SyncAggregate() *pb.SyncAggregate { return u.p.SyncAggregate } +func (u *updateAltair) SetSyncAggregate(sa *pb.SyncAggregate) { + u.p.SyncAggregate = sa +} + func (u *updateAltair) SignatureSlot() primitives.Slot { return u.p.SignatureSlot } +func (u *updateAltair) SetSignatureSlot(slot primitives.Slot) { + u.p.SignatureSlot = slot +} + type updateCapella struct { p *pb.LightClientUpdateCapella attestedHeader interfaces.LightClientHeader @@ -142,10 +195,15 @@ func NewWrappedUpdateCapella(p *pb.LightClientUpdateCapella) (interfaces.LightCl if err != nil { return nil, err } - finalizedHeader, err := NewWrappedHeaderCapella(p.FinalizedHeader) - if err != nil { - return nil, err + + var finalizedHeader interfaces.LightClientHeader + if p.FinalizedHeader != nil { + finalizedHeader, err = NewWrappedHeaderCapella(p.FinalizedHeader) + if err != nil { + return nil, err + } } + scBranch, err := createBranch[interfaces.LightClientSyncCommitteeBranch]( "sync committee", p.NextSyncCommitteeBranch, @@ -184,6 +242,10 @@ func (u *updateCapella) SizeSSZ() int { return u.p.SizeSSZ() } +func (u *updateCapella) Proto() proto.Message { + return u.p +} + func (u *updateCapella) Version() int { return version.Capella } @@ -192,34 +254,76 @@ func (u *updateCapella) AttestedHeader() interfaces.LightClientHeader { return u.attestedHeader } +func (u *updateCapella) SetAttestedHeader(header interfaces.LightClientHeader) { + u.attestedHeader = header +} + func (u *updateCapella) NextSyncCommittee() *pb.SyncCommittee { return u.p.NextSyncCommittee } +func (u *updateCapella) SetNextSyncCommittee(sc *pb.SyncCommittee) { + u.p.NextSyncCommittee = sc +} + func (u *updateCapella) NextSyncCommitteeBranch() (interfaces.LightClientSyncCommitteeBranch, error) { return u.nextSyncCommitteeBranch, nil } +func (u *updateCapella) SetNextSyncCommitteeBranch(branch [][]byte) error { + b, err := createBranch[interfaces.LightClientSyncCommitteeBranch]("sync committee", branch, fieldparams.SyncCommitteeBranchDepth) + if err != nil { + return err + } + u.nextSyncCommitteeBranch = b + return nil +} + func (u *updateCapella) NextSyncCommitteeBranchElectra() (interfaces.LightClientSyncCommitteeBranchElectra, error) { return [6][32]byte{}, consensustypes.ErrNotSupported("NextSyncCommitteeBranchElectra", version.Capella) } +func (u *updateCapella) SetNextSyncCommitteeBranchElectra([][]byte) error { + return consensustypes.ErrNotSupported("SetNextSyncCommitteeBranchElectra", version.Capella) +} + func (u *updateCapella) FinalizedHeader() interfaces.LightClientHeader { return u.finalizedHeader } +func (u *updateCapella) SetFinalizedHeader(header interfaces.LightClientHeader) { + u.finalizedHeader = header +} + func (u *updateCapella) FinalityBranch() interfaces.LightClientFinalityBranch { return u.finalityBranch } +func (u *updateCapella) SetFinalityBranch(branch [][]byte) error { + b, err := createBranch[interfaces.LightClientFinalityBranch]("finality", branch, fieldparams.FinalityBranchDepth) + if err != nil { + return err + } + u.finalityBranch = b + return nil +} + func (u *updateCapella) SyncAggregate() *pb.SyncAggregate { return u.p.SyncAggregate } +func (u *updateCapella) SetSyncAggregate(sa *pb.SyncAggregate) { + u.p.SyncAggregate = sa +} + func (u *updateCapella) SignatureSlot() primitives.Slot { return u.p.SignatureSlot } +func (u *updateCapella) SetSignatureSlot(slot primitives.Slot) { + u.p.SignatureSlot = slot +} + type updateDeneb struct { p *pb.LightClientUpdateDeneb attestedHeader interfaces.LightClientHeader @@ -238,10 +342,15 @@ func NewWrappedUpdateDeneb(p *pb.LightClientUpdateDeneb) (interfaces.LightClient if err != nil { return nil, err } - finalizedHeader, err := NewWrappedHeaderDeneb(p.FinalizedHeader) - if err != nil { - return nil, err + + var finalizedHeader interfaces.LightClientHeader + if p.FinalizedHeader != nil { + finalizedHeader, err = NewWrappedHeaderDeneb(p.FinalizedHeader) + if err != nil { + return nil, err + } } + scBranch, err := createBranch[interfaces.LightClientSyncCommitteeBranch]( "sync committee", p.NextSyncCommitteeBranch, @@ -280,6 +389,10 @@ func (u *updateDeneb) SizeSSZ() int { return u.p.SizeSSZ() } +func (u *updateDeneb) Proto() proto.Message { + return u.p +} + func (u *updateDeneb) Version() int { return version.Deneb } @@ -288,34 +401,76 @@ func (u *updateDeneb) AttestedHeader() interfaces.LightClientHeader { return u.attestedHeader } +func (u *updateDeneb) SetAttestedHeader(header interfaces.LightClientHeader) { + u.attestedHeader = header +} + func (u *updateDeneb) NextSyncCommittee() *pb.SyncCommittee { return u.p.NextSyncCommittee } +func (u *updateDeneb) SetNextSyncCommittee(sc *pb.SyncCommittee) { + u.p.NextSyncCommittee = sc +} + func (u *updateDeneb) NextSyncCommitteeBranch() (interfaces.LightClientSyncCommitteeBranch, error) { return u.nextSyncCommitteeBranch, nil } +func (u *updateDeneb) SetNextSyncCommitteeBranch(branch [][]byte) error { + b, err := createBranch[interfaces.LightClientSyncCommitteeBranch]("sync committee", branch, fieldparams.SyncCommitteeBranchDepth) + if err != nil { + return err + } + u.nextSyncCommitteeBranch = b + return nil +} + func (u *updateDeneb) NextSyncCommitteeBranchElectra() (interfaces.LightClientSyncCommitteeBranchElectra, error) { return [6][32]byte{}, consensustypes.ErrNotSupported("NextSyncCommitteeBranchElectra", version.Deneb) } +func (u *updateDeneb) SetNextSyncCommitteeBranchElectra([][]byte) error { + return consensustypes.ErrNotSupported("SetNextSyncCommitteeBranchElectra", version.Deneb) +} + func (u *updateDeneb) FinalizedHeader() interfaces.LightClientHeader { return u.finalizedHeader } +func (u *updateDeneb) SetFinalizedHeader(header interfaces.LightClientHeader) { + u.finalizedHeader = header +} + func (u *updateDeneb) FinalityBranch() interfaces.LightClientFinalityBranch { return u.finalityBranch } +func (u *updateDeneb) SetFinalityBranch(branch [][]byte) error { + b, err := createBranch[interfaces.LightClientFinalityBranch]("finality", branch, fieldparams.FinalityBranchDepth) + if err != nil { + return err + } + u.finalityBranch = b + return nil +} + func (u *updateDeneb) SyncAggregate() *pb.SyncAggregate { return u.p.SyncAggregate } +func (u *updateDeneb) SetSyncAggregate(sa *pb.SyncAggregate) { + u.p.SyncAggregate = sa +} + func (u *updateDeneb) SignatureSlot() primitives.Slot { return u.p.SignatureSlot } +func (u *updateDeneb) SetSignatureSlot(slot primitives.Slot) { + u.p.SignatureSlot = slot +} + type updateElectra struct { p *pb.LightClientUpdateElectra attestedHeader interfaces.LightClientHeader @@ -334,10 +489,15 @@ func NewWrappedUpdateElectra(p *pb.LightClientUpdateElectra) (interfaces.LightCl if err != nil { return nil, err } - finalizedHeader, err := NewWrappedHeaderDeneb(p.FinalizedHeader) - if err != nil { - return nil, err + + var finalizedHeader interfaces.LightClientHeader + if p.FinalizedHeader != nil { + finalizedHeader, err = NewWrappedHeaderDeneb(p.FinalizedHeader) + if err != nil { + return nil, err + } } + scBranch, err := createBranch[interfaces.LightClientSyncCommitteeBranchElectra]( "sync committee", p.NextSyncCommitteeBranch, @@ -376,6 +536,10 @@ func (u *updateElectra) SizeSSZ() int { return u.p.SizeSSZ() } +func (u *updateElectra) Proto() proto.Message { + return u.p +} + func (u *updateElectra) Version() int { return version.Electra } @@ -384,30 +548,72 @@ func (u *updateElectra) AttestedHeader() interfaces.LightClientHeader { return u.attestedHeader } +func (u *updateElectra) SetAttestedHeader(header interfaces.LightClientHeader) { + u.attestedHeader = header +} + func (u *updateElectra) NextSyncCommittee() *pb.SyncCommittee { return u.p.NextSyncCommittee } +func (u *updateElectra) SetNextSyncCommittee(sc *pb.SyncCommittee) { + u.p.NextSyncCommittee = sc +} + func (u *updateElectra) NextSyncCommitteeBranch() (interfaces.LightClientSyncCommitteeBranch, error) { return [5][32]byte{}, consensustypes.ErrNotSupported("NextSyncCommitteeBranch", version.Electra) } +func (u *updateElectra) SetNextSyncCommitteeBranch([][]byte) error { + return consensustypes.ErrNotSupported("SetNextSyncCommitteeBranch", version.Electra) +} + func (u *updateElectra) NextSyncCommitteeBranchElectra() (interfaces.LightClientSyncCommitteeBranchElectra, error) { return u.nextSyncCommitteeBranch, nil } +func (u *updateElectra) SetNextSyncCommitteeBranchElectra(branch [][]byte) error { + b, err := createBranch[interfaces.LightClientSyncCommitteeBranchElectra]("sync committee", branch, fieldparams.SyncCommitteeBranchDepthElectra) + if err != nil { + return err + } + u.nextSyncCommitteeBranch = b + return nil +} + func (u *updateElectra) FinalizedHeader() interfaces.LightClientHeader { return u.finalizedHeader } +func (u *updateElectra) SetFinalizedHeader(header interfaces.LightClientHeader) { + u.finalizedHeader = header +} + func (u *updateElectra) FinalityBranch() interfaces.LightClientFinalityBranch { return u.finalityBranch } +func (u *updateElectra) SetFinalityBranch(branch [][]byte) error { + b, err := createBranch[interfaces.LightClientFinalityBranch]("finality", branch, fieldparams.FinalityBranchDepth) + if err != nil { + return err + } + u.finalityBranch = b + return nil +} + func (u *updateElectra) SyncAggregate() *pb.SyncAggregate { return u.p.SyncAggregate } +func (u *updateElectra) SetSyncAggregate(sa *pb.SyncAggregate) { + u.p.SyncAggregate = sa +} + func (u *updateElectra) SignatureSlot() primitives.Slot { return u.p.SignatureSlot } + +func (u *updateElectra) SetSignatureSlot(slot primitives.Slot) { + u.p.SignatureSlot = slot +} From fec1678716534580038d598746f631a2347b5638 Mon Sep 17 00:00:00 2001 From: Mohamad Bastin Date: Mon, 21 Oct 2024 15:18:51 +0200 Subject: [PATCH 18/35] change updatesByRange to use new structs --- api/server/structs/conversions_lightclient.go | 14 -------------- beacon-chain/rpc/eth/light-client/handlers.go | 7 ++++++- 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/api/server/structs/conversions_lightclient.go b/api/server/structs/conversions_lightclient.go index 6e1ea498e028..d3a84eada54e 100644 --- a/api/server/structs/conversions_lightclient.go +++ b/api/server/structs/conversions_lightclient.go @@ -3,8 +3,6 @@ package structs import ( "encoding/json" "fmt" - v2 "github.com/prysmaticlabs/prysm/v5/proto/eth/v2" - "github.com/ethereum/go-ethereum/common/hexutil" "github.com/pkg/errors" "github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces" @@ -12,18 +10,6 @@ import ( "github.com/prysmaticlabs/prysm/v5/runtime/version" ) -func LightClientUpdateResponseFromConsensus(update *v2.LightClientUpdateWithVersion) (*LightClientUpdateResponse, error) { - data, err := LightClientUpdateFromConsensus(update.Data) - if err != nil { - return nil, err - } - - return &LightClientUpdateResponse{ - Version: version.String(int(update.Version)), - Data: data, - }, nil -} - func LightClientUpdateFromConsensus(update interfaces.LightClientUpdate) (*LightClientUpdate, error) { attestedHeader, err := lightClientHeaderToJSON(update.AttestedHeader()) if err != nil { diff --git a/beacon-chain/rpc/eth/light-client/handlers.go b/beacon-chain/rpc/eth/light-client/handlers.go index a6136c7219c4..91746c5db135 100644 --- a/beacon-chain/rpc/eth/light-client/handlers.go +++ b/beacon-chain/rpc/eth/light-client/handlers.go @@ -131,12 +131,17 @@ func (s *Server) GetLightClientUpdatesByRange(w http.ResponseWriter, req *http.R break } - updateResponse, err := structs.LightClientUpdateResponseFromConsensus(update) + updateJson, err := structs.LightClientUpdateFromConsensus(update) if err != nil { httputil.HandleError(w, "Could not convert light client update: "+err.Error(), http.StatusInternalServerError) return } + updateResponse := &structs.LightClientUpdateResponse{ + Version: version.String(update.Version()), + Data: updateJson, + } + updates = append(updates, updateResponse) } From 497c50abdece6a5b2af8110df25deb341bf6fb23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20Kapka?= Date: Mon, 21 Oct 2024 19:45:16 +0700 Subject: [PATCH 19/35] Light Client - use the new consensus types (#14549) * in progress * completed logic * var name * additional logic changes * fix createDefaultLightClientUpdate * empty fields * unused context --- api/server/structs/BUILD.bazel | 3 +- api/server/structs/conversions.go | 7 + api/server/structs/conversions_lightclient.go | 136 +++-- .../blockchain/process_block_helpers.go | 21 +- beacon-chain/core/light-client/BUILD.bazel | 7 +- beacon-chain/core/light-client/lightclient.go | 500 ++++++++++-------- beacon-chain/db/iface/BUILD.bazel | 1 - beacon-chain/db/iface/interface.go | 8 +- beacon-chain/db/kv/BUILD.bazel | 2 +- beacon-chain/db/kv/lightclient.go | 107 +++- beacon-chain/execution/engine_client.go | 2 +- beacon-chain/execution/payload_body.go | 2 +- beacon-chain/rpc/endpoints.go | 9 +- beacon-chain/rpc/eth/events/events.go | 14 +- beacon-chain/rpc/eth/light-client/BUILD.bazel | 2 - beacon-chain/rpc/eth/light-client/handlers.go | 7 +- beacon-chain/rpc/eth/light-client/helpers.go | 257 +++------ beacon-chain/rpc/eth/light-client/server.go | 9 +- consensus-types/interfaces/light_client.go | 13 + .../light-client/finality_update.go | 71 +++ consensus-types/light-client/header.go | 12 + consensus-types/light-client/helpers.go | 3 +- .../light-client/optimistic_update.go | 115 ++-- consensus-types/light-client/update.go | 230 +++++++- 24 files changed, 956 insertions(+), 582 deletions(-) diff --git a/api/server/structs/BUILD.bazel b/api/server/structs/BUILD.bazel index c194d502ee02..54ed0b02a9e3 100644 --- a/api/server/structs/BUILD.bazel +++ b/api/server/structs/BUILD.bazel @@ -36,9 +36,8 @@ go_library( "//math:go_default_library", "//proto/engine/v1:go_default_library", "//proto/eth/v1:go_default_library", - "//proto/eth/v2:go_default_library", - "//proto/migration:go_default_library", "//proto/prysm/v1alpha1:go_default_library", + "//runtime/version:go_default_library", "@com_github_ethereum_go_ethereum//common:go_default_library", "@com_github_ethereum_go_ethereum//common/hexutil:go_default_library", "@com_github_pkg_errors//:go_default_library", diff --git a/api/server/structs/conversions.go b/api/server/structs/conversions.go index 9ed1f50e4e67..74af3c41aba5 100644 --- a/api/server/structs/conversions.go +++ b/api/server/structs/conversions.go @@ -1546,3 +1546,10 @@ func EventChainReorgFromV1(event *ethv1.EventChainReorg) *ChainReorgEvent { ExecutionOptimistic: event.ExecutionOptimistic, } } + +func SyncAggregateFromConsensus(sa *eth.SyncAggregate) *SyncAggregate { + return &SyncAggregate{ + SyncCommitteeBits: hexutil.Encode(sa.SyncCommitteeBits), + SyncCommitteeSignature: hexutil.Encode(sa.SyncCommitteeSignature), + } +} diff --git a/api/server/structs/conversions_lightclient.go b/api/server/structs/conversions_lightclient.go index 50e6281ef9b9..0c809c70b146 100644 --- a/api/server/structs/conversions_lightclient.go +++ b/api/server/structs/conversions_lightclient.go @@ -3,125 +3,153 @@ package structs import ( "encoding/json" "fmt" - "strconv" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/pkg/errors" - v1 "github.com/prysmaticlabs/prysm/v5/proto/eth/v1" - v2 "github.com/prysmaticlabs/prysm/v5/proto/eth/v2" - "github.com/prysmaticlabs/prysm/v5/proto/migration" + "github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces" + enginev1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1" + "github.com/prysmaticlabs/prysm/v5/runtime/version" ) -func LightClientUpdateFromConsensus(update *v2.LightClientUpdate) (*LightClientUpdate, error) { - attestedHeader, err := lightClientHeaderContainerToJSON(update.AttestedHeader) +func LightClientUpdateFromConsensus(update interfaces.LightClientUpdate) (*LightClientUpdate, error) { + attestedHeader, err := lightClientHeaderToJSON(update.AttestedHeader()) if err != nil { return nil, errors.Wrap(err, "could not marshal attested light client header") } - finalizedHeader, err := lightClientHeaderContainerToJSON(update.FinalizedHeader) + finalizedHeader, err := lightClientHeaderToJSON(update.FinalizedHeader()) if err != nil { return nil, errors.Wrap(err, "could not marshal finalized light client header") } + finalityBranch := update.FinalityBranch() + + var scBranch [][32]byte + if update.Version() >= version.Electra { + b, err := update.NextSyncCommitteeBranchElectra() + if err != nil { + return nil, err + } + scBranch = b[:] + } else { + b, err := update.NextSyncCommitteeBranch() + if err != nil { + return nil, err + } + scBranch = b[:] + } return &LightClientUpdate{ AttestedHeader: attestedHeader, - NextSyncCommittee: SyncCommitteeFromConsensus(migration.V2SyncCommitteeToV1Alpha1(update.NextSyncCommittee)), - NextSyncCommitteeBranch: branchToJSON(update.NextSyncCommitteeBranch), + NextSyncCommittee: SyncCommitteeFromConsensus(update.NextSyncCommittee()), + NextSyncCommitteeBranch: branchToJSON(scBranch), FinalizedHeader: finalizedHeader, - FinalityBranch: branchToJSON(update.FinalityBranch), - SyncAggregate: syncAggregateToJSON(update.SyncAggregate), - SignatureSlot: strconv.FormatUint(uint64(update.SignatureSlot), 10), + FinalityBranch: branchToJSON(finalityBranch[:]), + SyncAggregate: SyncAggregateFromConsensus(update.SyncAggregate()), + SignatureSlot: fmt.Sprintf("%d", update.SignatureSlot()), }, nil } -func LightClientFinalityUpdateFromConsensus(update *v2.LightClientFinalityUpdate) (*LightClientFinalityUpdate, error) { - attestedHeader, err := lightClientHeaderContainerToJSON(update.AttestedHeader) +func LightClientFinalityUpdateFromConsensus(update interfaces.LightClientFinalityUpdate) (*LightClientFinalityUpdate, error) { + attestedHeader, err := lightClientHeaderToJSON(update.AttestedHeader()) if err != nil { return nil, errors.Wrap(err, "could not marshal attested light client header") } - finalizedHeader, err := lightClientHeaderContainerToJSON(update.FinalizedHeader) + finalizedHeader, err := lightClientHeaderToJSON(update.FinalizedHeader()) if err != nil { return nil, errors.Wrap(err, "could not marshal finalized light client header") } + finalityBranch := update.FinalityBranch() return &LightClientFinalityUpdate{ AttestedHeader: attestedHeader, FinalizedHeader: finalizedHeader, - FinalityBranch: branchToJSON(update.FinalityBranch), - SyncAggregate: syncAggregateToJSON(update.SyncAggregate), - SignatureSlot: strconv.FormatUint(uint64(update.SignatureSlot), 10), + FinalityBranch: branchToJSON(finalityBranch[:]), + SyncAggregate: SyncAggregateFromConsensus(update.SyncAggregate()), + SignatureSlot: fmt.Sprintf("%d", update.SignatureSlot()), }, nil } -func LightClientOptimisticUpdateFromConsensus(update *v2.LightClientOptimisticUpdate) (*LightClientOptimisticUpdate, error) { - attestedHeader, err := lightClientHeaderContainerToJSON(update.AttestedHeader) +func LightClientOptimisticUpdateFromConsensus(update interfaces.LightClientOptimisticUpdate) (*LightClientOptimisticUpdate, error) { + attestedHeader, err := lightClientHeaderToJSON(update.AttestedHeader()) if err != nil { return nil, errors.Wrap(err, "could not marshal attested light client header") } return &LightClientOptimisticUpdate{ AttestedHeader: attestedHeader, - SyncAggregate: syncAggregateToJSON(update.SyncAggregate), - SignatureSlot: strconv.FormatUint(uint64(update.SignatureSlot), 10), + SyncAggregate: SyncAggregateFromConsensus(update.SyncAggregate()), + SignatureSlot: fmt.Sprintf("%d", update.SignatureSlot()), }, nil } -func branchToJSON(branchBytes [][]byte) []string { +func branchToJSON[S [][32]byte](branchBytes S) []string { if branchBytes == nil { return nil } branch := make([]string, len(branchBytes)) for i, root := range branchBytes { - branch[i] = hexutil.Encode(root) + branch[i] = hexutil.Encode(root[:]) } return branch } -func syncAggregateToJSON(input *v1.SyncAggregate) *SyncAggregate { - return &SyncAggregate{ - SyncCommitteeBits: hexutil.Encode(input.SyncCommitteeBits), - SyncCommitteeSignature: hexutil.Encode(input.SyncCommitteeSignature), - } -} - -func lightClientHeaderContainerToJSON(container *v2.LightClientHeaderContainer) (json.RawMessage, error) { +func lightClientHeaderToJSON(header interfaces.LightClientHeader) (json.RawMessage, error) { // In the case that a finalizedHeader is nil. - if container == nil { + if header == nil { return nil, nil } - beacon, err := container.GetBeacon() - if err != nil { - return nil, errors.Wrap(err, "could not get beacon block header") - } - - var header any + var result any - switch t := (container.Header).(type) { - case *v2.LightClientHeaderContainer_HeaderAltair: - header = &LightClientHeader{Beacon: BeaconBlockHeaderFromConsensus(migration.V1HeaderToV1Alpha1(beacon))} - case *v2.LightClientHeaderContainer_HeaderCapella: - execution, err := ExecutionPayloadHeaderCapellaFromConsensus(t.HeaderCapella.Execution) + switch v := header.Version(); v { + case version.Altair: + result = &LightClientHeader{Beacon: BeaconBlockHeaderFromConsensus(header.Beacon())} + case version.Capella: + exInterface, err := header.Execution() if err != nil { return nil, err } - header = &LightClientHeaderCapella{ - Beacon: BeaconBlockHeaderFromConsensus(migration.V1HeaderToV1Alpha1(beacon)), + ex, ok := exInterface.Proto().(*enginev1.ExecutionPayloadHeaderCapella) + if !ok { + return nil, fmt.Errorf("execution data is not %T", &enginev1.ExecutionPayloadHeaderCapella{}) + } + execution, err := ExecutionPayloadHeaderCapellaFromConsensus(ex) + if err != nil { + return nil, err + } + executionBranch, err := header.ExecutionBranch() + if err != nil { + return nil, err + } + result = &LightClientHeaderCapella{ + Beacon: BeaconBlockHeaderFromConsensus(header.Beacon()), Execution: execution, - ExecutionBranch: branchToJSON(t.HeaderCapella.ExecutionBranch), + ExecutionBranch: branchToJSON(executionBranch[:]), + } + case version.Deneb: + exInterface, err := header.Execution() + if err != nil { + return nil, err + } + ex, ok := exInterface.Proto().(*enginev1.ExecutionPayloadHeaderDeneb) + if !ok { + return nil, fmt.Errorf("execution data is not %T", &enginev1.ExecutionPayloadHeaderDeneb{}) + } + execution, err := ExecutionPayloadHeaderDenebFromConsensus(ex) + if err != nil { + return nil, err } - case *v2.LightClientHeaderContainer_HeaderDeneb: - execution, err := ExecutionPayloadHeaderDenebFromConsensus(t.HeaderDeneb.Execution) + executionBranch, err := header.ExecutionBranch() if err != nil { return nil, err } - header = &LightClientHeaderDeneb{ - Beacon: BeaconBlockHeaderFromConsensus(migration.V1HeaderToV1Alpha1(beacon)), + result = &LightClientHeaderDeneb{ + Beacon: BeaconBlockHeaderFromConsensus(header.Beacon()), Execution: execution, - ExecutionBranch: branchToJSON(t.HeaderDeneb.ExecutionBranch), + ExecutionBranch: branchToJSON(executionBranch[:]), } default: - return nil, fmt.Errorf("unsupported header type %T", t) + return nil, fmt.Errorf("unsupported header version %s", version.String(v)) } - return json.Marshal(header) + return json.Marshal(result) } diff --git a/beacon-chain/blockchain/process_block_helpers.go b/beacon-chain/blockchain/process_block_helpers.go index 8f3da0a4236c..7b7a5f07fba7 100644 --- a/beacon-chain/blockchain/process_block_helpers.go +++ b/beacon-chain/blockchain/process_block_helpers.go @@ -129,7 +129,12 @@ func (s *Service) sendLightClientFeeds(cfg *postBlockProcessConfig) { } } -func (s *Service) tryPublishLightClientFinalityUpdate(ctx context.Context, signed interfaces.ReadOnlySignedBeaconBlock, finalized *forkchoicetypes.Checkpoint, postState state.BeaconState) { +func (s *Service) tryPublishLightClientFinalityUpdate( + ctx context.Context, + signed interfaces.ReadOnlySignedBeaconBlock, + finalized *forkchoicetypes.Checkpoint, + postState state.BeaconState, +) { if finalized.Epoch <= s.lastPublishedLightClientEpoch { return } @@ -182,15 +187,15 @@ func (s *Service) sendLightClientFinalityUpdate(ctx context.Context, signed inte } } - update, err := lightclient.NewLightClientFinalityUpdateFromBeaconState( + _, err = lightclient.NewLightClientFinalityUpdateFromBeaconState( ctx, + postState.Slot(), postState, signed, attestedState, attestedBlock, finalizedBlock, ) - if err != nil { return 0, errors.Wrap(err, "could not create light client update") } @@ -198,7 +203,8 @@ func (s *Service) sendLightClientFinalityUpdate(ctx context.Context, signed inte // Return the result result := ðpbv2.LightClientFinalityUpdateWithVersion{ Version: ethpbv2.Version(signed.Version()), - Data: update, + // TODO: Get back to this when revisiting events + //Data: update, } // Send event @@ -222,14 +228,14 @@ func (s *Service) sendLightClientOptimisticUpdate(ctx context.Context, signed in return 0, errors.Wrap(err, "could not get attested state") } - update, err := lightclient.NewLightClientOptimisticUpdateFromBeaconState( + _, err = lightclient.NewLightClientOptimisticUpdateFromBeaconState( ctx, + postState.Slot(), postState, signed, attestedState, attestedBlock, ) - if err != nil { return 0, errors.Wrap(err, "could not create light client update") } @@ -237,7 +243,8 @@ func (s *Service) sendLightClientOptimisticUpdate(ctx context.Context, signed in // Return the result result := ðpbv2.LightClientOptimisticUpdateWithVersion{ Version: ethpbv2.Version(signed.Version()), - Data: update, + // TODO: Get back to this when revisiting events + //Data: update, } return s.cfg.StateNotifier.StateFeed().Send(&feed.Event{ diff --git a/beacon-chain/core/light-client/BUILD.bazel b/beacon-chain/core/light-client/BUILD.bazel index c7a264c71bb6..327e1922055f 100644 --- a/beacon-chain/core/light-client/BUILD.bazel +++ b/beacon-chain/core/light-client/BUILD.bazel @@ -6,19 +6,22 @@ go_library( importpath = "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/light-client", visibility = ["//visibility:public"], deps = [ + "//beacon-chain/execution:go_default_library", "//beacon-chain/state:go_default_library", "//config/fieldparams:go_default_library", "//config/params:go_default_library", "//consensus-types:go_default_library", "//consensus-types/blocks:go_default_library", "//consensus-types/interfaces:go_default_library", + "//consensus-types/light-client:go_default_library", + "//consensus-types/primitives:go_default_library", "//encoding/ssz:go_default_library", "//proto/engine/v1:go_default_library", - "//proto/eth/v1:go_default_library", - "//proto/eth/v2:go_default_library", + "//proto/prysm/v1alpha1:go_default_library", "//runtime/version:go_default_library", "//time/slots:go_default_library", "@com_github_pkg_errors//:go_default_library", + "@org_golang_google_protobuf//proto:go_default_library", ], ) diff --git a/beacon-chain/core/light-client/lightclient.go b/beacon-chain/core/light-client/lightclient.go index 1173ec355331..7c60a163cf05 100644 --- a/beacon-chain/core/light-client/lightclient.go +++ b/beacon-chain/core/light-client/lightclient.go @@ -6,85 +6,75 @@ import ( "fmt" "github.com/pkg/errors" + "github.com/prysmaticlabs/prysm/v5/beacon-chain/execution" "github.com/prysmaticlabs/prysm/v5/beacon-chain/state" fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams" "github.com/prysmaticlabs/prysm/v5/config/params" consensus_types "github.com/prysmaticlabs/prysm/v5/consensus-types" "github.com/prysmaticlabs/prysm/v5/consensus-types/blocks" "github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces" + light_client "github.com/prysmaticlabs/prysm/v5/consensus-types/light-client" + "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" "github.com/prysmaticlabs/prysm/v5/encoding/ssz" - v11 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1" - ethpbv1 "github.com/prysmaticlabs/prysm/v5/proto/eth/v1" - ethpbv2 "github.com/prysmaticlabs/prysm/v5/proto/eth/v2" + enginev1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1" + pb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" "github.com/prysmaticlabs/prysm/v5/runtime/version" "github.com/prysmaticlabs/prysm/v5/time/slots" + "google.golang.org/protobuf/proto" ) const ( - FinalityBranchNumOfLeaves = 6 - executionBranchNumOfLeaves = 4 + FinalityBranchNumOfLeaves = 6 ) -func createLightClientFinalityUpdate(update *ethpbv2.LightClientUpdate) *ethpbv2.LightClientFinalityUpdate { - finalityUpdate := ðpbv2.LightClientFinalityUpdate{ - AttestedHeader: update.AttestedHeader, - FinalizedHeader: update.FinalizedHeader, - FinalityBranch: update.FinalityBranch, - SyncAggregate: update.SyncAggregate, - SignatureSlot: update.SignatureSlot, - } - - return finalityUpdate -} - -func createLightClientOptimisticUpdate(update *ethpbv2.LightClientUpdate) *ethpbv2.LightClientOptimisticUpdate { - optimisticUpdate := ðpbv2.LightClientOptimisticUpdate{ - AttestedHeader: update.AttestedHeader, - SyncAggregate: update.SyncAggregate, - SignatureSlot: update.SignatureSlot, - } - - return optimisticUpdate -} - func NewLightClientFinalityUpdateFromBeaconState( ctx context.Context, + currentSlot primitives.Slot, state state.BeaconState, block interfaces.ReadOnlySignedBeaconBlock, attestedState state.BeaconState, attestedBlock interfaces.ReadOnlySignedBeaconBlock, finalizedBlock interfaces.ReadOnlySignedBeaconBlock, -) (*ethpbv2.LightClientFinalityUpdate, error) { - update, err := NewLightClientUpdateFromBeaconState(ctx, state, block, attestedState, attestedBlock, finalizedBlock) +) (interfaces.LightClientFinalityUpdate, error) { + update, err := NewLightClientUpdateFromBeaconState(ctx, currentSlot, state, block, attestedState, attestedBlock, finalizedBlock) if err != nil { return nil, err } - return createLightClientFinalityUpdate(update), nil + return light_client.NewFinalityUpdateFromUpdate(update) } func NewLightClientOptimisticUpdateFromBeaconState( ctx context.Context, + currentSlot primitives.Slot, state state.BeaconState, block interfaces.ReadOnlySignedBeaconBlock, attestedState state.BeaconState, attestedBlock interfaces.ReadOnlySignedBeaconBlock, -) (*ethpbv2.LightClientOptimisticUpdate, error) { - update, err := NewLightClientUpdateFromBeaconState(ctx, state, block, attestedState, attestedBlock, nil) +) (interfaces.LightClientOptimisticUpdate, error) { + update, err := NewLightClientUpdateFromBeaconState(ctx, currentSlot, state, block, attestedState, attestedBlock, nil) if err != nil { return nil, err } - return createLightClientOptimisticUpdate(update), nil + return light_client.NewOptimisticUpdateFromUpdate(update) } +// To form a LightClientUpdate, the following historical states and blocks are needed: +// - state: the post state of any block with a post-Altair parent block +// - block: the corresponding block +// - attested_state: the post state of attested_block +// - attested_block: the block referred to by block.parent_root +// - finalized_block: the block referred to by attested_state.finalized_checkpoint.root, +// if locally available (may be unavailable, e.g., when using checkpoint sync, or if it was pruned locally) func NewLightClientUpdateFromBeaconState( ctx context.Context, + currentSlot primitives.Slot, state state.BeaconState, block interfaces.ReadOnlySignedBeaconBlock, attestedState state.BeaconState, attestedBlock interfaces.ReadOnlySignedBeaconBlock, - finalizedBlock interfaces.ReadOnlySignedBeaconBlock) (*ethpbv2.LightClientUpdate, error) { + finalizedBlock interfaces.ReadOnlySignedBeaconBlock) (interfaces.LightClientUpdate, error) { // assert compute_epoch_at_slot(attested_state.slot) >= ALTAIR_FORK_EPOCH attestedEpoch := slots.ToEpoch(attestedState.Slot()) if attestedEpoch < params.BeaconConfig().AltairForkEpoch { @@ -129,7 +119,11 @@ func NewLightClientUpdateFromBeaconState( // assert attested_state.slot == attested_state.latest_block_header.slot if attestedState.Slot() != attestedState.LatestBlockHeader().Slot { - return nil, fmt.Errorf("attested state slot %d not equal to attested latest block header slot %d", attestedState.Slot(), attestedState.LatestBlockHeader().Slot) + return nil, fmt.Errorf( + "attested state slot %d not equal to attested latest block header slot %d", + attestedState.Slot(), + attestedState.LatestBlockHeader().Slot, + ) } // attested_header = attested_state.latest_block_header.copy() @@ -153,46 +147,56 @@ func NewLightClientUpdateFromBeaconState( } // assert hash_tree_root(attested_header) == hash_tree_root(attested_block.message) == block.message.parent_root if attestedHeaderRoot != block.Block().ParentRoot() || attestedHeaderRoot != attestedBlockRoot { - return nil, fmt.Errorf("attested header root %#x not equal to block parent root %#x or attested block root %#x", attestedHeaderRoot, block.Block().ParentRoot(), attestedBlockRoot) + return nil, fmt.Errorf( + "attested header root %#x not equal to block parent root %#x or attested block root %#x", + attestedHeaderRoot, + block.Block().ParentRoot(), + attestedBlockRoot, + ) } // update_attested_period = compute_sync_committee_period_at_slot(attested_block.message.slot) updateAttestedPeriod := slots.SyncCommitteePeriod(slots.ToEpoch(attestedBlock.Block().Slot())) // update = LightClientUpdate() - result, err := createDefaultLightClientUpdate() + result, err := createDefaultLightClientUpdate(currentSlot) if err != nil { return nil, errors.Wrap(err, "could not create default light client update") } // update.attested_header = block_to_light_client_header(attested_block) - attestedLightClientHeader, err := BlockToLightClientHeader(attestedBlock) + attestedLightClientHeader, err := BlockToLightClientHeader(ctx, currentSlot, attestedBlock) if err != nil { return nil, errors.Wrap(err, "could not get attested light client header") } - result.AttestedHeader = attestedLightClientHeader + result.SetAttestedHeader(attestedLightClientHeader) // if update_attested_period == update_signature_period if updateAttestedPeriod == updateSignaturePeriod { + // update.next_sync_committee = attested_state.next_sync_committee tempNextSyncCommittee, err := attestedState.NextSyncCommittee() if err != nil { return nil, errors.Wrap(err, "could not get next sync committee") } - nextSyncCommittee := ðpbv2.SyncCommittee{ + nextSyncCommittee := &pb.SyncCommittee{ Pubkeys: tempNextSyncCommittee.Pubkeys, AggregatePubkey: tempNextSyncCommittee.AggregatePubkey, } + result.SetNextSyncCommittee(nextSyncCommittee) + + // update.next_sync_committee_branch = NextSyncCommitteeBranch( + // compute_merkle_proof(attested_state, next_sync_committee_gindex_at_slot(attested_state.slot))) nextSyncCommitteeBranch, err := attestedState.NextSyncCommitteeProof(ctx) if err != nil { return nil, errors.Wrap(err, "could not get next sync committee proof") } - - // update.next_sync_committee = attested_state.next_sync_committee - result.NextSyncCommittee = nextSyncCommittee - - // update.next_sync_committee_branch = NextSyncCommitteeBranch( - // compute_merkle_proof(attested_state, next_sync_committee_gindex_at_slot(attested_state.slot))) - result.NextSyncCommitteeBranch = nextSyncCommitteeBranch + if attestedBlock.Version() >= version.Electra { + if err = result.SetNextSyncCommitteeBranchElectra(nextSyncCommitteeBranch); err != nil { + return nil, errors.Wrap(err, "could not set next sync committee branch") + } + } else if err = result.SetNextSyncCommitteeBranch(nextSyncCommitteeBranch); err != nil { + return nil, errors.Wrap(err, "could not set next sync committee branch") + } } // if finalized_block is not None @@ -200,11 +204,11 @@ func NewLightClientUpdateFromBeaconState( // if finalized_block.message.slot != GENESIS_SLOT if finalizedBlock.Block().Slot() != 0 { // update.finalized_header = block_to_light_client_header(finalized_block) - finalizedLightClientHeader, err := BlockToLightClientHeader(finalizedBlock) + finalizedLightClientHeader, err := BlockToLightClientHeader(ctx, currentSlot, finalizedBlock) if err != nil { return nil, errors.Wrap(err, "could not get finalized light client header") } - result.FinalizedHeader = finalizedLightClientHeader + result.SetFinalizedHeader(finalizedLightClientHeader) } else { // assert attested_state.finalized_checkpoint.root == Bytes32() if !bytes.Equal(attestedState.FinalizedCheckpoint().Root, make([]byte, 32)) { @@ -218,49 +222,83 @@ func NewLightClientUpdateFromBeaconState( if err != nil { return nil, errors.Wrap(err, "could not get finalized root proof") } - result.FinalityBranch = finalityBranch + if err = result.SetFinalityBranch(finalityBranch); err != nil { + return nil, errors.Wrap(err, "could not set finality branch") + } } // update.sync_aggregate = block.message.body.sync_aggregate - result.SyncAggregate = ðpbv1.SyncAggregate{ + result.SetSyncAggregate(&pb.SyncAggregate{ SyncCommitteeBits: syncAggregate.SyncCommitteeBits, SyncCommitteeSignature: syncAggregate.SyncCommitteeSignature, - } + }) // update.signature_slot = block.message.slot - result.SignatureSlot = block.Block().Slot() + result.SetSignatureSlot(block.Block().Slot()) return result, nil } -func createDefaultLightClientUpdate() (*ethpbv2.LightClientUpdate, error) { +func createDefaultLightClientUpdate(currentSlot primitives.Slot) (interfaces.LightClientUpdate, error) { + currentEpoch := slots.ToEpoch(currentSlot) + syncCommitteeSize := params.BeaconConfig().SyncCommitteeSize pubKeys := make([][]byte, syncCommitteeSize) for i := uint64(0); i < syncCommitteeSize; i++ { pubKeys[i] = make([]byte, fieldparams.BLSPubkeyLength) } - nextSyncCommittee := ðpbv2.SyncCommittee{ + nextSyncCommittee := &pb.SyncCommittee{ Pubkeys: pubKeys, AggregatePubkey: make([]byte, fieldparams.BLSPubkeyLength), } - nextSyncCommitteeBranch := make([][]byte, fieldparams.SyncCommitteeBranchDepth) - for i := 0; i < fieldparams.SyncCommitteeBranchDepth; i++ { + + var nextSyncCommitteeBranch [][]byte + if currentEpoch >= params.BeaconConfig().ElectraForkEpoch { + nextSyncCommitteeBranch = make([][]byte, fieldparams.SyncCommitteeBranchDepthElectra) + } else { + nextSyncCommitteeBranch = make([][]byte, fieldparams.SyncCommitteeBranchDepth) + } + for i := 0; i < len(nextSyncCommitteeBranch); i++ { nextSyncCommitteeBranch[i] = make([]byte, fieldparams.RootLength) } - executionBranch := make([][]byte, executionBranchNumOfLeaves) - for i := 0; i < executionBranchNumOfLeaves; i++ { + + executionBranch := make([][]byte, fieldparams.ExecutionBranchDepth) + for i := 0; i < fieldparams.ExecutionBranchDepth; i++ { executionBranch[i] = make([]byte, 32) } - finalityBranch := make([][]byte, FinalityBranchNumOfLeaves) - for i := 0; i < FinalityBranchNumOfLeaves; i++ { + finalityBranch := make([][]byte, fieldparams.FinalityBranchDepth) + for i := 0; i < fieldparams.FinalityBranchDepth; i++ { finalityBranch[i] = make([]byte, 32) } - return ðpbv2.LightClientUpdate{ - NextSyncCommittee: nextSyncCommittee, - NextSyncCommitteeBranch: nextSyncCommitteeBranch, - FinalityBranch: finalityBranch, - }, nil + var m proto.Message + if currentEpoch < params.BeaconConfig().CapellaForkEpoch { + m = &pb.LightClientUpdateAltair{ + NextSyncCommittee: nextSyncCommittee, + NextSyncCommitteeBranch: nextSyncCommitteeBranch, + FinalityBranch: finalityBranch, + } + } else if currentEpoch < params.BeaconConfig().DenebForkEpoch { + m = &pb.LightClientUpdateCapella{ + NextSyncCommittee: nextSyncCommittee, + NextSyncCommitteeBranch: nextSyncCommitteeBranch, + FinalityBranch: finalityBranch, + } + } else if currentEpoch < params.BeaconConfig().ElectraForkEpoch { + m = &pb.LightClientUpdateDeneb{ + NextSyncCommittee: nextSyncCommittee, + NextSyncCommitteeBranch: nextSyncCommitteeBranch, + FinalityBranch: finalityBranch, + } + } else { + m = &pb.LightClientUpdateElectra{ + NextSyncCommittee: nextSyncCommittee, + NextSyncCommitteeBranch: nextSyncCommitteeBranch, + FinalityBranch: finalityBranch, + } + } + + return light_client.NewWrappedUpdate(m) } func ComputeTransactionsRoot(payload interfaces.ExecutionData) ([]byte, error) { @@ -299,47 +337,14 @@ func ComputeWithdrawalsRoot(payload interfaces.ExecutionData) ([]byte, error) { return withdrawalsRoot, nil } -func BlockToLightClientHeader(block interfaces.ReadOnlySignedBeaconBlock) (*ethpbv2.LightClientHeaderContainer, error) { - switch block.Version() { - case version.Altair, version.Bellatrix: - altairHeader, err := blockToLightClientHeaderAltair(block) - if err != nil { - return nil, errors.Wrap(err, "could not get header") - } - return ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: altairHeader, - }, - }, nil - case version.Capella: - capellaHeader, err := blockToLightClientHeaderCapella(context.Background(), block) - if err != nil { - return nil, errors.Wrap(err, "could not get capella header") - } - return ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ - HeaderCapella: capellaHeader, - }, - }, nil - case version.Deneb, version.Electra: - denebHeader, err := blockToLightClientHeaderDeneb(context.Background(), block) - if err != nil { - return nil, errors.Wrap(err, "could not get header") - } - return ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderDeneb{ - HeaderDeneb: denebHeader, - }, - }, nil - default: - return nil, fmt.Errorf("unsupported block version %s", version.String(block.Version())) - } -} - -func blockToLightClientHeaderAltair(block interfaces.ReadOnlySignedBeaconBlock) (*ethpbv2.LightClientHeader, error) { - if block.Version() < version.Altair { - return nil, fmt.Errorf("block version is %s instead of Altair", version.String(block.Version())) - } +func BlockToLightClientHeader( + ctx context.Context, + currentSlot primitives.Slot, + block interfaces.ReadOnlySignedBeaconBlock, +) (interfaces.LightClientHeader, error) { + var m proto.Message + currentEpoch := slots.ToEpoch(currentSlot) + blockEpoch := slots.ToEpoch(block.Block().Slot()) parentRoot := block.Block().ParentRoot() stateRoot := block.Block().StateRoot() @@ -348,147 +353,172 @@ func blockToLightClientHeaderAltair(block interfaces.ReadOnlySignedBeaconBlock) return nil, errors.Wrap(err, "could not get body root") } - return ðpbv2.LightClientHeader{ - Beacon: ðpbv1.BeaconBlockHeader{ - Slot: block.Block().Slot(), - ProposerIndex: block.Block().ProposerIndex(), - ParentRoot: parentRoot[:], - StateRoot: stateRoot[:], - BodyRoot: bodyRoot[:], - }, - }, nil -} + if currentEpoch < params.BeaconConfig().CapellaForkEpoch { + m = &pb.LightClientHeaderAltair{ + Beacon: &pb.BeaconBlockHeader{ + Slot: block.Block().Slot(), + ProposerIndex: block.Block().ProposerIndex(), + ParentRoot: parentRoot[:], + StateRoot: stateRoot[:], + BodyRoot: bodyRoot[:], + }, + } + } else if currentEpoch < params.BeaconConfig().DenebForkEpoch { + var payloadHeader *enginev1.ExecutionPayloadHeaderCapella + var payloadProof [][]byte -func blockToLightClientHeaderCapella(ctx context.Context, block interfaces.ReadOnlySignedBeaconBlock) (*ethpbv2.LightClientHeaderCapella, error) { - if block.Version() < version.Capella { - return nil, fmt.Errorf("block version is %s instead of Capella", version.String(block.Version())) - } + if blockEpoch < params.BeaconConfig().CapellaForkEpoch { + var ok bool - payload, err := block.Block().Body().Execution() - if err != nil { - return nil, errors.Wrap(err, "could not get execution payload") - } + p, err := execution.EmptyExecutionPayload(version.Capella) + if err != nil { + return nil, errors.Wrap(err, "could not get payload header") + } + payloadHeader, ok = p.(*enginev1.ExecutionPayloadHeaderCapella) + if !ok { + return nil, errors.Wrapf(err, "payload header type %T is not %T", payloadHeader, &enginev1.ExecutionPayloadHeaderCapella{}) + } + payloadProof = emptyPayloadProof() + } else { + payload, err := block.Block().Body().Execution() + if err != nil { + return nil, errors.Wrap(err, "could not get execution payload") + } + transactionsRoot, err := ComputeTransactionsRoot(payload) + if err != nil { + return nil, errors.Wrap(err, "could not get transactions root") + } + withdrawalsRoot, err := ComputeWithdrawalsRoot(payload) + if err != nil { + return nil, errors.Wrap(err, "could not get withdrawals root") + } - transactionsRoot, err := ComputeTransactionsRoot(payload) - if err != nil { - return nil, err - } - withdrawalsRoot, err := ComputeWithdrawalsRoot(payload) - if err != nil { - return nil, err - } + payloadHeader = &enginev1.ExecutionPayloadHeaderCapella{ + ParentHash: payload.ParentHash(), + FeeRecipient: payload.FeeRecipient(), + StateRoot: payload.StateRoot(), + ReceiptsRoot: payload.ReceiptsRoot(), + LogsBloom: payload.LogsBloom(), + PrevRandao: payload.PrevRandao(), + BlockNumber: payload.BlockNumber(), + GasLimit: payload.GasLimit(), + GasUsed: payload.GasUsed(), + Timestamp: payload.Timestamp(), + ExtraData: payload.ExtraData(), + BaseFeePerGas: payload.BaseFeePerGas(), + BlockHash: payload.BlockHash(), + TransactionsRoot: transactionsRoot, + WithdrawalsRoot: withdrawalsRoot, + } - executionHeader := &v11.ExecutionPayloadHeaderCapella{ - ParentHash: payload.ParentHash(), - FeeRecipient: payload.FeeRecipient(), - StateRoot: payload.StateRoot(), - ReceiptsRoot: payload.ReceiptsRoot(), - LogsBloom: payload.LogsBloom(), - PrevRandao: payload.PrevRandao(), - BlockNumber: payload.BlockNumber(), - GasLimit: payload.GasLimit(), - GasUsed: payload.GasUsed(), - Timestamp: payload.Timestamp(), - ExtraData: payload.ExtraData(), - BaseFeePerGas: payload.BaseFeePerGas(), - BlockHash: payload.BlockHash(), - TransactionsRoot: transactionsRoot, - WithdrawalsRoot: withdrawalsRoot, - } + payloadProof, err = blocks.PayloadProof(ctx, block.Block()) + if err != nil { + return nil, errors.Wrap(err, "could not get execution payload proof") + } + } - executionPayloadProof, err := blocks.PayloadProof(ctx, block.Block()) - if err != nil { - return nil, errors.Wrap(err, "could not get execution payload proof") - } + m = &pb.LightClientHeaderCapella{ + Beacon: &pb.BeaconBlockHeader{ + Slot: block.Block().Slot(), + ProposerIndex: block.Block().ProposerIndex(), + ParentRoot: parentRoot[:], + StateRoot: stateRoot[:], + BodyRoot: bodyRoot[:], + }, + Execution: payloadHeader, + ExecutionBranch: payloadProof, + } + } else { + var payloadHeader *enginev1.ExecutionPayloadHeaderDeneb + var payloadProof [][]byte - parentRoot := block.Block().ParentRoot() - stateRoot := block.Block().StateRoot() - bodyRoot, err := block.Block().Body().HashTreeRoot() - if err != nil { - return nil, errors.Wrap(err, "could not get body root") - } + if blockEpoch < params.BeaconConfig().CapellaForkEpoch { + var ok bool - return ðpbv2.LightClientHeaderCapella{ - Beacon: ðpbv1.BeaconBlockHeader{ - Slot: block.Block().Slot(), - ProposerIndex: block.Block().ProposerIndex(), - ParentRoot: parentRoot[:], - StateRoot: stateRoot[:], - BodyRoot: bodyRoot[:], - }, - Execution: executionHeader, - ExecutionBranch: executionPayloadProof, - }, nil -} + p, err := execution.EmptyExecutionPayload(version.Deneb) + if err != nil { + return nil, errors.Wrap(err, "could not get payload header") + } + payloadHeader, ok = p.(*enginev1.ExecutionPayloadHeaderDeneb) + if !ok { + return nil, errors.Wrapf(err, "payload header type %T is not %T", payloadHeader, &enginev1.ExecutionPayloadHeaderDeneb{}) + } + payloadProof = emptyPayloadProof() + } else { + payload, err := block.Block().Body().Execution() + if err != nil { + return nil, errors.Wrap(err, "could not get execution payload") + } + transactionsRoot, err := ComputeTransactionsRoot(payload) + if err != nil { + return nil, errors.Wrap(err, "could not get transactions root") + } + withdrawalsRoot, err := ComputeWithdrawalsRoot(payload) + if err != nil { + return nil, errors.Wrap(err, "could not get withdrawals root") + } -func blockToLightClientHeaderDeneb(ctx context.Context, block interfaces.ReadOnlySignedBeaconBlock) (*ethpbv2.LightClientHeaderDeneb, error) { - if block.Version() < version.Deneb { - return nil, fmt.Errorf("block version is %s instead of Deneb/Electra", version.String(block.Version())) - } + var blobGasUsed uint64 + var excessBlobGas uint64 + + if blockEpoch >= params.BeaconConfig().DenebForkEpoch { + blobGasUsed, err = payload.BlobGasUsed() + if err != nil { + return nil, errors.Wrap(err, "could not get blob gas used") + } + excessBlobGas, err = payload.ExcessBlobGas() + if err != nil { + return nil, errors.Wrap(err, "could not get excess blob gas") + } + } - payload, err := block.Block().Body().Execution() - if err != nil { - return nil, errors.Wrap(err, "could not get execution payload") - } + payloadHeader = &enginev1.ExecutionPayloadHeaderDeneb{ + ParentHash: payload.ParentHash(), + FeeRecipient: payload.FeeRecipient(), + StateRoot: payload.StateRoot(), + ReceiptsRoot: payload.ReceiptsRoot(), + LogsBloom: payload.LogsBloom(), + PrevRandao: payload.PrevRandao(), + BlockNumber: payload.BlockNumber(), + GasLimit: payload.GasLimit(), + GasUsed: payload.GasUsed(), + Timestamp: payload.Timestamp(), + ExtraData: payload.ExtraData(), + BaseFeePerGas: payload.BaseFeePerGas(), + BlockHash: payload.BlockHash(), + TransactionsRoot: transactionsRoot, + WithdrawalsRoot: withdrawalsRoot, + BlobGasUsed: blobGasUsed, + ExcessBlobGas: excessBlobGas, + } - transactionsRoot, err := ComputeTransactionsRoot(payload) - if err != nil { - return nil, err - } - withdrawalsRoot, err := ComputeWithdrawalsRoot(payload) - if err != nil { - return nil, err - } - blobGasUsed, err := payload.BlobGasUsed() - if err != nil { - return nil, errors.Wrap(err, "could not get blob gas used") - } - excessBlobGas, err := payload.ExcessBlobGas() - if err != nil { - return nil, errors.Wrap(err, "could not get excess blob gas") - } + payloadProof, err = blocks.PayloadProof(ctx, block.Block()) + if err != nil { + return nil, errors.Wrap(err, "could not get execution payload proof") + } + } - executionHeader := &v11.ExecutionPayloadHeaderDeneb{ - ParentHash: payload.ParentHash(), - FeeRecipient: payload.FeeRecipient(), - StateRoot: payload.StateRoot(), - ReceiptsRoot: payload.ReceiptsRoot(), - LogsBloom: payload.LogsBloom(), - PrevRandao: payload.PrevRandao(), - BlockNumber: payload.BlockNumber(), - GasLimit: payload.GasLimit(), - GasUsed: payload.GasUsed(), - Timestamp: payload.Timestamp(), - ExtraData: payload.ExtraData(), - BaseFeePerGas: payload.BaseFeePerGas(), - BlockHash: payload.BlockHash(), - TransactionsRoot: transactionsRoot, - WithdrawalsRoot: withdrawalsRoot, - BlobGasUsed: blobGasUsed, - ExcessBlobGas: excessBlobGas, + m = &pb.LightClientHeaderDeneb{ + Beacon: &pb.BeaconBlockHeader{ + Slot: block.Block().Slot(), + ProposerIndex: block.Block().ProposerIndex(), + ParentRoot: parentRoot[:], + StateRoot: stateRoot[:], + BodyRoot: bodyRoot[:], + }, + Execution: payloadHeader, + ExecutionBranch: payloadProof, + } } - executionPayloadProof, err := blocks.PayloadProof(ctx, block.Block()) - if err != nil { - return nil, errors.Wrap(err, "could not get execution payload proof") - } + return light_client.NewWrappedHeader(m) +} - parentRoot := block.Block().ParentRoot() - stateRoot := block.Block().StateRoot() - bodyRoot, err := block.Block().Body().HashTreeRoot() - if err != nil { - return nil, errors.Wrap(err, "could not get body root") +func emptyPayloadProof() [][]byte { + branch := interfaces.LightClientExecutionBranch{} + proof := make([][]byte, len(branch)) + for i, b := range branch { + proof[i] = b[:] } - - return ðpbv2.LightClientHeaderDeneb{ - Beacon: ðpbv1.BeaconBlockHeader{ - Slot: block.Block().Slot(), - ProposerIndex: block.Block().ProposerIndex(), - ParentRoot: parentRoot[:], - StateRoot: stateRoot[:], - BodyRoot: bodyRoot[:], - }, - Execution: executionHeader, - ExecutionBranch: executionPayloadProof, - }, nil + return proof } diff --git a/beacon-chain/db/iface/BUILD.bazel b/beacon-chain/db/iface/BUILD.bazel index 993d1fd84c98..81929a26a47d 100644 --- a/beacon-chain/db/iface/BUILD.bazel +++ b/beacon-chain/db/iface/BUILD.bazel @@ -18,7 +18,6 @@ go_library( "//consensus-types/primitives:go_default_library", "//monitoring/backup:go_default_library", "//proto/dbval:go_default_library", - "//proto/eth/v2:go_default_library", "//proto/prysm/v1alpha1:go_default_library", "@com_github_ethereum_go_ethereum//common:go_default_library", ], diff --git a/beacon-chain/db/iface/interface.go b/beacon-chain/db/iface/interface.go index b75960ef553c..fc2ef7af4faa 100644 --- a/beacon-chain/db/iface/interface.go +++ b/beacon-chain/db/iface/interface.go @@ -7,8 +7,6 @@ import ( "context" "io" - ethpbv2 "github.com/prysmaticlabs/prysm/v5/proto/eth/v2" - "github.com/ethereum/go-ethereum/common" "github.com/prysmaticlabs/prysm/v5/beacon-chain/db/filters" slashertypes "github.com/prysmaticlabs/prysm/v5/beacon-chain/slasher/types" @@ -59,8 +57,8 @@ type ReadOnlyDatabase interface { FeeRecipientByValidatorID(ctx context.Context, id primitives.ValidatorIndex) (common.Address, error) RegistrationByValidatorID(ctx context.Context, id primitives.ValidatorIndex) (*ethpb.ValidatorRegistrationV1, error) // light client operations - LightClientUpdates(ctx context.Context, startPeriod, endPeriod uint64) (map[uint64]*ethpbv2.LightClientUpdateWithVersion, error) - LightClientUpdate(ctx context.Context, period uint64) (*ethpbv2.LightClientUpdateWithVersion, error) + LightClientUpdates(ctx context.Context, startPeriod, endPeriod uint64) (map[uint64]interfaces.LightClientUpdate, error) + LightClientUpdate(ctx context.Context, period uint64) (interfaces.LightClientUpdate, error) // origin checkpoint sync support OriginCheckpointBlockRoot(ctx context.Context) ([32]byte, error) @@ -98,7 +96,7 @@ type NoHeadAccessDatabase interface { SaveFeeRecipientsByValidatorIDs(ctx context.Context, ids []primitives.ValidatorIndex, addrs []common.Address) error SaveRegistrationsByValidatorIDs(ctx context.Context, ids []primitives.ValidatorIndex, regs []*ethpb.ValidatorRegistrationV1) error // light client operations - SaveLightClientUpdate(ctx context.Context, period uint64, update *ethpbv2.LightClientUpdateWithVersion) error + SaveLightClientUpdate(ctx context.Context, period uint64, update interfaces.LightClientUpdate) error CleanUpDirtyStates(ctx context.Context, slotsPerArchivedPoint primitives.Slot) error } diff --git a/beacon-chain/db/kv/BUILD.bazel b/beacon-chain/db/kv/BUILD.bazel index 732da2fb5b2a..0a95e714aeb3 100644 --- a/beacon-chain/db/kv/BUILD.bazel +++ b/beacon-chain/db/kv/BUILD.bazel @@ -44,6 +44,7 @@ go_library( "//config/params:go_default_library", "//consensus-types/blocks:go_default_library", "//consensus-types/interfaces:go_default_library", + "//consensus-types/light-client:go_default_library", "//consensus-types/primitives:go_default_library", "//container/slice:go_default_library", "//encoding/bytesutil:go_default_library", @@ -53,7 +54,6 @@ go_library( "//monitoring/tracing:go_default_library", "//monitoring/tracing/trace:go_default_library", "//proto/dbval:go_default_library", - "//proto/eth/v2:go_default_library", "//proto/prysm/v1alpha1:go_default_library", "//runtime/version:go_default_library", "//time:go_default_library", diff --git a/beacon-chain/db/kv/lightclient.go b/beacon-chain/db/kv/lightclient.go index 3c7bef3ff5f1..d7bbc1796814 100644 --- a/beacon-chain/db/kv/lightclient.go +++ b/beacon-chain/db/kv/lightclient.go @@ -5,35 +5,41 @@ import ( "encoding/binary" "fmt" + "github.com/golang/snappy" + "github.com/pkg/errors" + "github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces" + light_client "github.com/prysmaticlabs/prysm/v5/consensus-types/light-client" "github.com/prysmaticlabs/prysm/v5/encoding/bytesutil" "github.com/prysmaticlabs/prysm/v5/monitoring/tracing/trace" - ethpbv2 "github.com/prysmaticlabs/prysm/v5/proto/eth/v2" + ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" + "github.com/prysmaticlabs/prysm/v5/runtime/version" bolt "go.etcd.io/bbolt" + "google.golang.org/protobuf/proto" ) -func (s *Store) SaveLightClientUpdate(ctx context.Context, period uint64, update *ethpbv2.LightClientUpdateWithVersion) error { - ctx, span := trace.StartSpan(ctx, "BeaconDB.saveLightClientUpdate") +func (s *Store) SaveLightClientUpdate(ctx context.Context, period uint64, update interfaces.LightClientUpdate) error { + _, span := trace.StartSpan(ctx, "BeaconDB.SaveLightClientUpdate") defer span.End() return s.db.Update(func(tx *bolt.Tx) error { bkt := tx.Bucket(lightClientUpdatesBucket) - updateMarshalled, err := encode(ctx, update) + enc, err := encodeLightClientUpdate(update) if err != nil { return err } - return bkt.Put(bytesutil.Uint64ToBytesBigEndian(period), updateMarshalled) + return bkt.Put(bytesutil.Uint64ToBytesBigEndian(period), enc) }) } -func (s *Store) LightClientUpdates(ctx context.Context, startPeriod, endPeriod uint64) (map[uint64]*ethpbv2.LightClientUpdateWithVersion, error) { - ctx, span := trace.StartSpan(ctx, "BeaconDB.LightClientUpdates") +func (s *Store) LightClientUpdates(ctx context.Context, startPeriod, endPeriod uint64) (map[uint64]interfaces.LightClientUpdate, error) { + _, span := trace.StartSpan(ctx, "BeaconDB.LightClientUpdates") defer span.End() if startPeriod > endPeriod { return nil, fmt.Errorf("start period %d is greater than end period %d", startPeriod, endPeriod) } - updates := make(map[uint64]*ethpbv2.LightClientUpdateWithVersion) + updates := make(map[uint64]interfaces.LightClientUpdate) err := s.db.View(func(tx *bolt.Tx) error { bkt := tx.Bucket(lightClientUpdatesBucket) c := bkt.Cursor() @@ -46,11 +52,11 @@ func (s *Store) LightClientUpdates(ctx context.Context, startPeriod, endPeriod u for k, v := c.Seek(bytesutil.Uint64ToBytesBigEndian(startPeriod)); k != nil && binary.BigEndian.Uint64(k) <= endPeriod; k, v = c.Next() { currentPeriod := binary.BigEndian.Uint64(k) - var update ethpbv2.LightClientUpdateWithVersion - if err := decode(ctx, v, &update); err != nil { + update, err := decodeLightClientUpdate(v) + if err != nil { return err } - updates[currentPeriod] = &update + updates[currentPeriod] = update } return nil @@ -62,18 +68,87 @@ func (s *Store) LightClientUpdates(ctx context.Context, startPeriod, endPeriod u return updates, err } -func (s *Store) LightClientUpdate(ctx context.Context, period uint64) (*ethpbv2.LightClientUpdateWithVersion, error) { - ctx, span := trace.StartSpan(ctx, "BeaconDB.LightClientUpdate") +func (s *Store) LightClientUpdate(ctx context.Context, period uint64) (interfaces.LightClientUpdate, error) { + _, span := trace.StartSpan(ctx, "BeaconDB.LightClientUpdate") defer span.End() - var update ethpbv2.LightClientUpdateWithVersion + var update interfaces.LightClientUpdate err := s.db.View(func(tx *bolt.Tx) error { bkt := tx.Bucket(lightClientUpdatesBucket) updateBytes := bkt.Get(bytesutil.Uint64ToBytesBigEndian(period)) if updateBytes == nil { return nil } - return decode(ctx, updateBytes, &update) + var err error + update, err = decodeLightClientUpdate(updateBytes) + return err }) - return &update, err + return update, err +} + +func encodeLightClientUpdate(update interfaces.LightClientUpdate) ([]byte, error) { + key, err := keyForLightClientUpdate(update) + if err != nil { + return nil, err + } + enc, err := update.MarshalSSZ() + if err != nil { + return nil, errors.Wrap(err, "could not marshal light client update") + } + fullEnc := make([]byte, len(key)+len(enc)) + copy(fullEnc[len(key):], enc) + return snappy.Encode(nil, fullEnc), nil +} + +func decodeLightClientUpdate(enc []byte) (interfaces.LightClientUpdate, error) { + var err error + enc, err = snappy.Decode(nil, enc) + if err != nil { + return nil, errors.Wrap(err, "could not snappy decode light client update") + } + var m proto.Message + switch { + case hasAltairKey(enc): + update := ðpb.LightClientUpdateAltair{} + if err := update.UnmarshalSSZ(enc[len(altairKey):]); err != nil { + return nil, errors.Wrap(err, "could not unmarshal Altair light client update") + } + m = update + case hasCapellaKey(enc): + update := ðpb.LightClientUpdateCapella{} + if err := update.UnmarshalSSZ(enc[len(capellaKey):]); err != nil { + return nil, errors.Wrap(err, "could not unmarshal Capella light client update") + } + m = update + case hasDenebKey(enc): + update := ðpb.LightClientUpdateDeneb{} + if err := update.UnmarshalSSZ(enc[len(denebKey):]); err != nil { + return nil, errors.Wrap(err, "could not unmarshal Deneb light client update") + } + m = update + case hasElectraKey(enc): + update := ðpb.LightClientUpdateElectra{} + if err := update.UnmarshalSSZ(enc[len(electraKey):]); err != nil { + return nil, errors.Wrap(err, "could not unmarshal Electra light client update") + } + m = update + default: + return nil, errors.New("decoding of saved light client update is unsupported") + } + return light_client.NewWrappedUpdate(m) +} + +func keyForLightClientUpdate(update interfaces.LightClientUpdate) ([]byte, error) { + switch v := update.Version(); v { + case version.Electra: + return electraKey, nil + case version.Deneb: + return denebKey, nil + case version.Capella: + return capellaKey, nil + case version.Altair: + return altairKey, nil + default: + return nil, fmt.Errorf("unsupported light client update version %s", version.String(v)) + } } diff --git a/beacon-chain/execution/engine_client.go b/beacon-chain/execution/engine_client.go index 2dfc479f4214..e3a295424083 100644 --- a/beacon-chain/execution/engine_client.go +++ b/beacon-chain/execution/engine_client.go @@ -687,7 +687,7 @@ func tDStringToUint256(td string) (*uint256.Int, error) { return i, nil } -func buildEmptyExecutionPayload(v int) (proto.Message, error) { +func EmptyExecutionPayload(v int) (proto.Message, error) { switch v { case version.Bellatrix: return &pb.ExecutionPayload{ diff --git a/beacon-chain/execution/payload_body.go b/beacon-chain/execution/payload_body.go index 17aba3329e0f..4021bb2339f2 100644 --- a/beacon-chain/execution/payload_body.go +++ b/beacon-chain/execution/payload_body.go @@ -205,7 +205,7 @@ func (r *blindedBlockReconstructor) requestBodiesByHash(ctx context.Context, cli func (r *blindedBlockReconstructor) payloadForHeader(header interfaces.ExecutionData, v int) (proto.Message, error) { bodyKey := bytesutil.ToBytes32(header.BlockHash()) if bodyKey == params.BeaconConfig().ZeroHash { - payload, err := buildEmptyExecutionPayload(v) + payload, err := EmptyExecutionPayload(v) if err != nil { return nil, errors.Wrapf(err, "failed to reconstruct payload for body hash %#x", bodyKey) } diff --git a/beacon-chain/rpc/endpoints.go b/beacon-chain/rpc/endpoints.go index 2d61aee6173c..b2caf1827910 100644 --- a/beacon-chain/rpc/endpoints.go +++ b/beacon-chain/rpc/endpoints.go @@ -858,10 +858,11 @@ func (*Service) configEndpoints() []endpoint { func (s *Service) lightClientEndpoints(blocker lookup.Blocker, stater lookup.Stater) []endpoint { server := &lightclient.Server{ - Blocker: blocker, - Stater: stater, - HeadFetcher: s.cfg.HeadFetcher, - BeaconDB: s.cfg.BeaconDB, + Blocker: blocker, + Stater: stater, + HeadFetcher: s.cfg.HeadFetcher, + ChainInfoFetcher: s.cfg.ChainInfoFetcher, + BeaconDB: s.cfg.BeaconDB, } const namespace = "lightclient" diff --git a/beacon-chain/rpc/eth/events/events.go b/beacon-chain/rpc/eth/events/events.go index 7698d2fb9017..f50687fe9436 100644 --- a/beacon-chain/rpc/eth/events/events.go +++ b/beacon-chain/rpc/eth/events/events.go @@ -485,28 +485,30 @@ func (s *Server) lazyReaderForEvent(ctx context.Context, event *feed.Event, topi return jsonMarshalReader(eventName, structs.FinalizedCheckpointEventFromV1(v)) }, nil case *ethpbv2.LightClientFinalityUpdateWithVersion: - cv, err := structs.LightClientFinalityUpdateFromConsensus(v.Data) + // TODO: Get back to this when revisiting events + /*cv, err := structs.LightClientFinalityUpdateFromConsensus(v.Data) if err != nil { return nil, errors.Wrap(err, "LightClientFinalityUpdateWithVersion event conversion failure") } ev := &structs.LightClientFinalityUpdateEvent{ Version: version.String(int(v.Version)), Data: cv, - } + }*/ return func() io.Reader { - return jsonMarshalReader(eventName, ev) + return jsonMarshalReader(eventName, struct{}{}) }, nil case *ethpbv2.LightClientOptimisticUpdateWithVersion: - cv, err := structs.LightClientOptimisticUpdateFromConsensus(v.Data) + // TODO: Get back to this when revisiting events + /*cv, err := structs.LightClientOptimisticUpdateFromConsensus(v.Data) if err != nil { return nil, errors.Wrap(err, "LightClientOptimisticUpdateWithVersion event conversion failure") } ev := &structs.LightClientOptimisticUpdateEvent{ Version: version.String(int(v.Version)), Data: cv, - } + }*/ return func() io.Reader { - return jsonMarshalReader(eventName, ev) + return jsonMarshalReader(eventName, struct{}{}) }, nil case *ethpb.EventChainReorg: return func() io.Reader { diff --git a/beacon-chain/rpc/eth/light-client/BUILD.bazel b/beacon-chain/rpc/eth/light-client/BUILD.bazel index 85b46a07ecc4..d0fa6cb7a801 100644 --- a/beacon-chain/rpc/eth/light-client/BUILD.bazel +++ b/beacon-chain/rpc/eth/light-client/BUILD.bazel @@ -24,8 +24,6 @@ go_library( "//consensus-types/primitives:go_default_library", "//monitoring/tracing/trace:go_default_library", "//network/httputil:go_default_library", - "//proto/eth/v2:go_default_library", - "//proto/migration:go_default_library", "//runtime/version:go_default_library", "//time/slots:go_default_library", "@com_github_ethereum_go_ethereum//common/hexutil:go_default_library", diff --git a/beacon-chain/rpc/eth/light-client/handlers.go b/beacon-chain/rpc/eth/light-client/handlers.go index 245d703eaafd..3bc6909486da 100644 --- a/beacon-chain/rpc/eth/light-client/handlers.go +++ b/beacon-chain/rpc/eth/light-client/handlers.go @@ -47,7 +47,7 @@ func (s *Server) GetLightClientBootstrap(w http.ResponseWriter, req *http.Reques return } - bootstrap, err := createLightClientBootstrap(ctx, state, blk) + bootstrap, err := createLightClientBootstrap(ctx, s.ChainInfoFetcher.CurrentSlot(), state, blk) if err != nil { httputil.HandleError(w, "could not get light client bootstrap: "+err.Error(), http.StatusInternalServerError) return @@ -201,6 +201,7 @@ func (s *Server) GetLightClientUpdatesByRange(w http.ResponseWriter, req *http.R update, err := newLightClientUpdateFromBeaconState( ctx, + s.ChainInfoFetcher.CurrentSlot(), state, block, attestedState, @@ -268,7 +269,7 @@ func (s *Server) GetLightClientFinalityUpdate(w http.ResponseWriter, req *http.R return } - update, err := newLightClientFinalityUpdateFromBeaconState(ctx, st, block, attestedState, attestedBlock, finalizedBlock) + update, err := newLightClientFinalityUpdateFromBeaconState(ctx, s.ChainInfoFetcher.CurrentSlot(), st, block, attestedState, attestedBlock, finalizedBlock) if err != nil { httputil.HandleError(w, "Could not get light client finality update: "+err.Error(), http.StatusInternalServerError) return @@ -313,7 +314,7 @@ func (s *Server) GetLightClientOptimisticUpdate(w http.ResponseWriter, req *http return } - update, err := newLightClientOptimisticUpdateFromBeaconState(ctx, st, block, attestedState, attestedBlock) + update, err := newLightClientOptimisticUpdateFromBeaconState(ctx, s.ChainInfoFetcher.CurrentSlot(), st, block, attestedState, attestedBlock) if err != nil { httputil.HandleError(w, "Could not get light client optimistic update: "+err.Error(), http.StatusInternalServerError) return diff --git a/beacon-chain/rpc/eth/light-client/helpers.go b/beacon-chain/rpc/eth/light-client/helpers.go index ce989a7d5672..f1f6cbdf7af1 100644 --- a/beacon-chain/rpc/eth/light-client/helpers.go +++ b/beacon-chain/rpc/eth/light-client/helpers.go @@ -7,7 +7,8 @@ import ( "reflect" "github.com/pkg/errors" - "github.com/prysmaticlabs/prysm/v5/proto/migration" + fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams" + "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" lightclient "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/light-client" "github.com/prysmaticlabs/prysm/v5/runtime/version" @@ -15,28 +16,17 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" "github.com/prysmaticlabs/prysm/v5/api/server/structs" "github.com/prysmaticlabs/prysm/v5/beacon-chain/state" - fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams" "github.com/prysmaticlabs/prysm/v5/config/params" "github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces" - v2 "github.com/prysmaticlabs/prysm/v5/proto/eth/v2" "github.com/prysmaticlabs/prysm/v5/time/slots" ) -func createLightClientBootstrap(ctx context.Context, state state.BeaconState, blk interfaces.ReadOnlySignedBeaconBlock) (*structs.LightClientBootstrap, error) { - switch blk.Version() { - case version.Phase0: - return nil, fmt.Errorf("light client bootstrap is not supported for phase0") - case version.Altair, version.Bellatrix: - return createLightClientBootstrapAltair(ctx, state, blk) - case version.Capella: - return createLightClientBootstrapCapella(ctx, state, blk) - case version.Deneb, version.Electra: - return createLightClientBootstrapDeneb(ctx, state, blk) - } - return nil, fmt.Errorf("unsupported block version %s", version.String(blk.Version())) -} - -func createLightClientBootstrapAltair(ctx context.Context, state state.BeaconState, block interfaces.ReadOnlySignedBeaconBlock) (*structs.LightClientBootstrap, error) { +func createLightClientBootstrap( + ctx context.Context, + currentSlot primitives.Slot, + state state.BeaconState, + block interfaces.ReadOnlySignedBeaconBlock, +) (*structs.LightClientBootstrap, error) { // assert compute_epoch_at_slot(state.slot) >= ALTAIR_FORK_EPOCH if slots.ToEpoch(state.Slot()) < params.BeaconConfig().AltairForkEpoch { return nil, fmt.Errorf("light client bootstrap is not supported before Altair, invalid slot %d", state.Slot()) @@ -68,82 +58,13 @@ func createLightClientBootstrapAltair(ctx context.Context, state state.BeaconSta return nil, fmt.Errorf("latest block header root %#x not equal to block root %#x", latestBlockHeaderRoot, beaconBlockRoot) } - lightClientHeaderContainer, err := lightclient.BlockToLightClientHeader(block) - if err != nil { - return nil, errors.Wrap(err, "could not convert block to light client header") - } - lightClientHeader := lightClientHeaderContainer.GetHeaderAltair() - - apiLightClientHeader := &structs.LightClientHeader{ - Beacon: structs.BeaconBlockHeaderFromConsensus(migration.V1HeaderToV1Alpha1(lightClientHeader.Beacon)), - } - - headerJSON, err := json.Marshal(apiLightClientHeader) - if err != nil { - return nil, errors.Wrap(err, "could not convert header to raw message") - } - currentSyncCommittee, err := state.CurrentSyncCommittee() - if err != nil { - return nil, errors.Wrap(err, "could not get current sync committee") - } - currentSyncCommitteeProof, err := state.CurrentSyncCommitteeProof(ctx) - if err != nil { - return nil, errors.Wrap(err, "could not get current sync committee proof") - } - - branch := make([]string, fieldparams.SyncCommitteeBranchDepth) - for i, proof := range currentSyncCommitteeProof { - branch[i] = hexutil.Encode(proof) - } - result := &structs.LightClientBootstrap{ - Header: headerJSON, - CurrentSyncCommittee: structs.SyncCommitteeFromConsensus(currentSyncCommittee), - CurrentSyncCommitteeBranch: branch, - } - - return result, nil -} - -func createLightClientBootstrapCapella(ctx context.Context, state state.BeaconState, block interfaces.ReadOnlySignedBeaconBlock) (*structs.LightClientBootstrap, error) { - // assert compute_epoch_at_slot(state.slot) >= CAPELLA_FORK_EPOCH - if slots.ToEpoch(state.Slot()) < params.BeaconConfig().CapellaForkEpoch { - return nil, fmt.Errorf("creating Capella light client bootstrap is not supported before Capella, invalid slot %d", state.Slot()) - } - - // assert state.slot == state.latest_block_header.slot - latestBlockHeader := state.LatestBlockHeader() - if state.Slot() != latestBlockHeader.Slot { - return nil, fmt.Errorf("state slot %d not equal to latest block header slot %d", state.Slot(), latestBlockHeader.Slot) - } - - // header.state_root = hash_tree_root(state) - stateRoot, err := state.HashTreeRoot(ctx) - if err != nil { - return nil, errors.Wrap(err, "could not get state root") - } - latestBlockHeader.StateRoot = stateRoot[:] - - // assert hash_tree_root(header) == hash_tree_root(block.message) - latestBlockHeaderRoot, err := latestBlockHeader.HashTreeRoot() - if err != nil { - return nil, errors.Wrap(err, "could not get latest block header root") - } - beaconBlockRoot, err := block.Block().HashTreeRoot() - if err != nil { - return nil, errors.Wrap(err, "could not get block root") - } - if latestBlockHeaderRoot != beaconBlockRoot { - return nil, fmt.Errorf("latest block header root %#x not equal to block root %#x", latestBlockHeaderRoot, beaconBlockRoot) - } - - lightClientHeaderContainer, err := lightclient.BlockToLightClientHeader(block) + lightClientHeader, err := lightclient.BlockToLightClientHeader(ctx, currentSlot, block) if err != nil { return nil, errors.Wrap(err, "could not convert block to light client header") } - lightClientHeader := lightClientHeaderContainer.GetHeaderCapella() apiLightClientHeader := &structs.LightClientHeader{ - Beacon: structs.BeaconBlockHeaderFromConsensus(migration.V1HeaderToV1Alpha1(lightClientHeader.Beacon)), + Beacon: structs.BeaconBlockHeaderFromConsensus(lightClientHeader.Beacon()), } headerJSON, err := json.Marshal(apiLightClientHeader) @@ -159,83 +80,16 @@ func createLightClientBootstrapCapella(ctx context.Context, state state.BeaconSt return nil, errors.Wrap(err, "could not get current sync committee proof") } - branch := make([]string, fieldparams.SyncCommitteeBranchDepth) - for i, proof := range currentSyncCommitteeProof { - branch[i] = hexutil.Encode(proof) - } - result := &structs.LightClientBootstrap{ - Header: headerJSON, - CurrentSyncCommittee: structs.SyncCommitteeFromConsensus(currentSyncCommittee), - CurrentSyncCommitteeBranch: branch, - } - - return result, nil -} - -func createLightClientBootstrapDeneb(ctx context.Context, state state.BeaconState, block interfaces.ReadOnlySignedBeaconBlock) (*structs.LightClientBootstrap, error) { - // assert compute_epoch_at_slot(state.slot) >= DENEB_FORK_EPOCH - if slots.ToEpoch(state.Slot()) < params.BeaconConfig().DenebForkEpoch { - return nil, fmt.Errorf("creating Deneb light client bootstrap is not supported before Deneb, invalid slot %d", state.Slot()) - } - - // assert state.slot == state.latest_block_header.slot - latestBlockHeader := state.LatestBlockHeader() - if state.Slot() != latestBlockHeader.Slot { - return nil, fmt.Errorf("state slot %d not equal to latest block header slot %d", state.Slot(), latestBlockHeader.Slot) - } - - // header.state_root = hash_tree_root(state) - stateRoot, err := state.HashTreeRoot(ctx) - if err != nil { - return nil, errors.Wrap(err, "could not get state root") - } - latestBlockHeader.StateRoot = stateRoot[:] - - // assert hash_tree_root(header) == hash_tree_root(block.message) - latestBlockHeaderRoot, err := latestBlockHeader.HashTreeRoot() - if err != nil { - return nil, errors.Wrap(err, "could not get latest block header root") - } - beaconBlockRoot, err := block.Block().HashTreeRoot() - if err != nil { - return nil, errors.Wrap(err, "could not get block root") - } - if latestBlockHeaderRoot != beaconBlockRoot { - return nil, fmt.Errorf("latest block header root %#x not equal to block root %#x", latestBlockHeaderRoot, beaconBlockRoot) - } - - lightClientHeaderContainer, err := lightclient.BlockToLightClientHeader(block) - if err != nil { - return nil, errors.Wrap(err, "could not convert block to light client header") - } - lightClientHeader := lightClientHeaderContainer.GetHeaderDeneb() - - apiLightClientHeader := &structs.LightClientHeader{ - Beacon: structs.BeaconBlockHeaderFromConsensus(migration.V1HeaderToV1Alpha1(lightClientHeader.Beacon)), - } - - headerJSON, err := json.Marshal(apiLightClientHeader) - if err != nil { - return nil, errors.Wrap(err, "could not convert header to raw message") - } - currentSyncCommittee, err := state.CurrentSyncCommittee() - if err != nil { - return nil, errors.Wrap(err, "could not get current sync committee") - } - currentSyncCommitteeProof, err := state.CurrentSyncCommitteeProof(ctx) - if err != nil { - return nil, errors.Wrap(err, "could not get current sync committee proof") - } var branch []string - switch block.Version() { - case version.Deneb: - branch = make([]string, fieldparams.SyncCommitteeBranchDepth) - case version.Electra: + if state.Version() >= version.Electra { branch = make([]string, fieldparams.SyncCommitteeBranchDepthElectra) + } else { + branch = make([]string, fieldparams.SyncCommitteeBranchDepth) } for i, proof := range currentSyncCommitteeProof { branch[i] = hexutil.Encode(proof) } + result := &structs.LightClientBootstrap{ Header: headerJSON, CurrentSyncCommittee: structs.SyncCommitteeFromConsensus(currentSyncCommittee), @@ -247,13 +101,14 @@ func createLightClientBootstrapDeneb(ctx context.Context, state state.BeaconStat func newLightClientUpdateFromBeaconState( ctx context.Context, + currentSlot primitives.Slot, state state.BeaconState, block interfaces.ReadOnlySignedBeaconBlock, attestedState state.BeaconState, attestedBlock interfaces.ReadOnlySignedBeaconBlock, finalizedBlock interfaces.ReadOnlySignedBeaconBlock, ) (*structs.LightClientUpdate, error) { - result, err := lightclient.NewLightClientUpdateFromBeaconState(ctx, state, block, attestedState, attestedBlock, finalizedBlock) + result, err := lightclient.NewLightClientUpdateFromBeaconState(ctx, currentSlot, state, block, attestedState, attestedBlock, finalizedBlock) if err != nil { return nil, err } @@ -263,13 +118,14 @@ func newLightClientUpdateFromBeaconState( func newLightClientFinalityUpdateFromBeaconState( ctx context.Context, + currentSlot primitives.Slot, state state.BeaconState, block interfaces.ReadOnlySignedBeaconBlock, attestedState state.BeaconState, attestedBlock interfaces.ReadOnlySignedBeaconBlock, finalizedBlock interfaces.ReadOnlySignedBeaconBlock, ) (*structs.LightClientFinalityUpdate, error) { - result, err := lightclient.NewLightClientFinalityUpdateFromBeaconState(ctx, state, block, attestedState, attestedBlock, finalizedBlock) + result, err := lightclient.NewLightClientFinalityUpdateFromBeaconState(ctx, currentSlot, state, block, attestedState, attestedBlock, finalizedBlock) if err != nil { return nil, err } @@ -279,12 +135,13 @@ func newLightClientFinalityUpdateFromBeaconState( func newLightClientOptimisticUpdateFromBeaconState( ctx context.Context, + currentSlot primitives.Slot, state state.BeaconState, block interfaces.ReadOnlySignedBeaconBlock, attestedState state.BeaconState, attestedBlock interfaces.ReadOnlySignedBeaconBlock, ) (*structs.LightClientOptimisticUpdate, error) { - result, err := lightclient.NewLightClientOptimisticUpdateFromBeaconState(ctx, state, block, attestedState, attestedBlock) + result, err := lightclient.NewLightClientOptimisticUpdateFromBeaconState(ctx, currentSlot, state, block, attestedState, attestedBlock) if err != nil { return nil, err } @@ -292,20 +149,29 @@ func newLightClientOptimisticUpdateFromBeaconState( return structs.LightClientOptimisticUpdateFromConsensus(result) } -func IsSyncCommitteeUpdate(update *v2.LightClientUpdate) bool { - nextSyncCommitteeBranch := make([][]byte, fieldparams.SyncCommitteeBranchDepth) - return !reflect.DeepEqual(update.NextSyncCommitteeBranch, nextSyncCommitteeBranch) +func HasRelevantSyncCommittee(update interfaces.LightClientUpdate) (bool, error) { + if update.Version() >= version.Electra { + branch, err := update.NextSyncCommitteeBranchElectra() + if err != nil { + return false, err + } + return !reflect.DeepEqual(branch, interfaces.LightClientSyncCommitteeBranchElectra{}), nil + } + branch, err := update.NextSyncCommitteeBranch() + if err != nil { + return false, err + } + return !reflect.DeepEqual(branch, interfaces.LightClientSyncCommitteeBranch{}), nil } -func IsFinalityUpdate(update *v2.LightClientUpdate) bool { - finalityBranch := make([][]byte, lightclient.FinalityBranchNumOfLeaves) - return !reflect.DeepEqual(update.FinalityBranch, finalityBranch) +func HasFinality(update interfaces.LightClientUpdate) bool { + return !reflect.DeepEqual(update.FinalityBranch(), interfaces.LightClientFinalityBranch{}) } -func IsBetterUpdate(newUpdate, oldUpdate *v2.LightClientUpdate) (bool, error) { - maxActiveParticipants := newUpdate.SyncAggregate.SyncCommitteeBits.Len() - newNumActiveParticipants := newUpdate.SyncAggregate.SyncCommitteeBits.Count() - oldNumActiveParticipants := oldUpdate.SyncAggregate.SyncCommitteeBits.Count() +func IsBetterUpdate(newUpdate, oldUpdate interfaces.LightClientUpdate) (bool, error) { + maxActiveParticipants := newUpdate.SyncAggregate().SyncCommitteeBits.Len() + newNumActiveParticipants := newUpdate.SyncAggregate().SyncCommitteeBits.Count() + oldNumActiveParticipants := oldUpdate.SyncAggregate().SyncCommitteeBits.Count() newHasSupermajority := newNumActiveParticipants*3 >= maxActiveParticipants*2 oldHasSupermajority := oldNumActiveParticipants*3 >= maxActiveParticipants*2 @@ -316,43 +182,45 @@ func IsBetterUpdate(newUpdate, oldUpdate *v2.LightClientUpdate) (bool, error) { return newNumActiveParticipants > oldNumActiveParticipants, nil } - newUpdateAttestedHeaderBeacon, err := newUpdate.AttestedHeader.GetBeacon() + newUpdateAttestedHeaderBeacon := newUpdate.AttestedHeader().Beacon() + oldUpdateAttestedHeaderBeacon := oldUpdate.AttestedHeader().Beacon() + + // Compare presence of relevant sync committee + newHasRelevantSyncCommittee, err := HasRelevantSyncCommittee(newUpdate) if err != nil { - return false, errors.Wrap(err, "could not get attested header beacon") + return false, err } - oldUpdateAttestedHeaderBeacon, err := oldUpdate.AttestedHeader.GetBeacon() + newHasRelevantSyncCommittee = newHasRelevantSyncCommittee && + (slots.SyncCommitteePeriod(slots.ToEpoch(newUpdateAttestedHeaderBeacon.Slot)) == slots.SyncCommitteePeriod(slots.ToEpoch(newUpdate.SignatureSlot()))) + oldHasRelevantSyncCommittee, err := HasRelevantSyncCommittee(oldUpdate) if err != nil { - return false, errors.Wrap(err, "could not get attested header beacon") + return false, err } - - // Compare presence of relevant sync committee - newHasRelevantSyncCommittee := IsSyncCommitteeUpdate(newUpdate) && (slots.SyncCommitteePeriod(slots.ToEpoch(newUpdateAttestedHeaderBeacon.Slot)) == slots.SyncCommitteePeriod(slots.ToEpoch(newUpdate.SignatureSlot))) - oldHasRelevantSyncCommittee := IsSyncCommitteeUpdate(oldUpdate) && (slots.SyncCommitteePeriod(slots.ToEpoch(oldUpdateAttestedHeaderBeacon.Slot)) == slots.SyncCommitteePeriod(slots.ToEpoch(oldUpdate.SignatureSlot))) + oldHasRelevantSyncCommittee = oldHasRelevantSyncCommittee && + (slots.SyncCommitteePeriod(slots.ToEpoch(oldUpdateAttestedHeaderBeacon.Slot)) == slots.SyncCommitteePeriod(slots.ToEpoch(oldUpdate.SignatureSlot()))) if newHasRelevantSyncCommittee != oldHasRelevantSyncCommittee { return newHasRelevantSyncCommittee, nil } // Compare indication of any finality - newHasFinality := IsFinalityUpdate(newUpdate) - oldHasFinality := IsFinalityUpdate(oldUpdate) + newHasFinality := HasFinality(newUpdate) + oldHasFinality := HasFinality(oldUpdate) if newHasFinality != oldHasFinality { return newHasFinality, nil } - newUpdateFinalizedHeaderBeacon, err := newUpdate.FinalizedHeader.GetBeacon() - if err != nil { - return false, errors.Wrap(err, "could not get finalized header beacon") - } - oldUpdateFinalizedHeaderBeacon, err := oldUpdate.FinalizedHeader.GetBeacon() - if err != nil { - return false, errors.Wrap(err, "could not get finalized header beacon") - } + newUpdateFinalizedHeaderBeacon := newUpdate.FinalizedHeader().Beacon() + oldUpdateFinalizedHeaderBeacon := oldUpdate.FinalizedHeader().Beacon() // Compare sync committee finality if newHasFinality { - newHasSyncCommitteeFinality := slots.SyncCommitteePeriod(slots.ToEpoch(newUpdateFinalizedHeaderBeacon.Slot)) == slots.SyncCommitteePeriod(slots.ToEpoch(newUpdateAttestedHeaderBeacon.Slot)) - oldHasSyncCommitteeFinality := slots.SyncCommitteePeriod(slots.ToEpoch(oldUpdateFinalizedHeaderBeacon.Slot)) == slots.SyncCommitteePeriod(slots.ToEpoch(oldUpdateAttestedHeaderBeacon.Slot)) + newHasSyncCommitteeFinality := + slots.SyncCommitteePeriod(slots.ToEpoch(newUpdateFinalizedHeaderBeacon.Slot)) == + slots.SyncCommitteePeriod(slots.ToEpoch(newUpdateAttestedHeaderBeacon.Slot)) + oldHasSyncCommitteeFinality := + slots.SyncCommitteePeriod(slots.ToEpoch(oldUpdateFinalizedHeaderBeacon.Slot)) == + slots.SyncCommitteePeriod(slots.ToEpoch(oldUpdateAttestedHeaderBeacon.Slot)) if newHasSyncCommitteeFinality != oldHasSyncCommitteeFinality { return newHasSyncCommitteeFinality, nil @@ -368,5 +236,6 @@ func IsBetterUpdate(newUpdate, oldUpdate *v2.LightClientUpdate) (bool, error) { if newUpdateAttestedHeaderBeacon.Slot != oldUpdateAttestedHeaderBeacon.Slot { return newUpdateAttestedHeaderBeacon.Slot < oldUpdateAttestedHeaderBeacon.Slot, nil } - return newUpdate.SignatureSlot < oldUpdate.SignatureSlot, nil + + return newUpdate.SignatureSlot() < oldUpdate.SignatureSlot(), nil } diff --git a/beacon-chain/rpc/eth/light-client/server.go b/beacon-chain/rpc/eth/light-client/server.go index e0773a306405..84b061379fc1 100644 --- a/beacon-chain/rpc/eth/light-client/server.go +++ b/beacon-chain/rpc/eth/light-client/server.go @@ -7,8 +7,9 @@ import ( ) type Server struct { - Blocker lookup.Blocker - Stater lookup.Stater - HeadFetcher blockchain.HeadFetcher - BeaconDB db.HeadAccessDatabase + Blocker lookup.Blocker + Stater lookup.Stater + HeadFetcher blockchain.HeadFetcher + ChainInfoFetcher blockchain.ChainInfoFetcher + BeaconDB db.HeadAccessDatabase } diff --git a/consensus-types/interfaces/light_client.go b/consensus-types/interfaces/light_client.go index 217a086497d4..994470c65a42 100644 --- a/consensus-types/interfaces/light_client.go +++ b/consensus-types/interfaces/light_client.go @@ -5,6 +5,7 @@ import ( fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams" "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" pb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" + "google.golang.org/protobuf/proto" ) type LightClientExecutionBranch = [fieldparams.ExecutionBranchDepth][fieldparams.RootLength]byte @@ -14,6 +15,7 @@ type LightClientFinalityBranch = [fieldparams.FinalityBranchDepth][fieldparams.R type LightClientHeader interface { ssz.Marshaler + Proto() proto.Message Version() int Beacon() *pb.BeaconBlockHeader Execution() (ExecutionData, error) @@ -31,19 +33,29 @@ type LightClientBootstrap interface { type LightClientUpdate interface { ssz.Marshaler + Proto() proto.Message Version() int AttestedHeader() LightClientHeader + SetAttestedHeader(header LightClientHeader) NextSyncCommittee() *pb.SyncCommittee + SetNextSyncCommittee(sc *pb.SyncCommittee) NextSyncCommitteeBranch() (LightClientSyncCommitteeBranch, error) + SetNextSyncCommitteeBranch(branch [][]byte) error NextSyncCommitteeBranchElectra() (LightClientSyncCommitteeBranchElectra, error) + SetNextSyncCommitteeBranchElectra(branch [][]byte) error FinalizedHeader() LightClientHeader + SetFinalizedHeader(header LightClientHeader) FinalityBranch() LightClientFinalityBranch + SetFinalityBranch(branch [][]byte) error SyncAggregate() *pb.SyncAggregate + SetSyncAggregate(sa *pb.SyncAggregate) SignatureSlot() primitives.Slot + SetSignatureSlot(slot primitives.Slot) } type LightClientFinalityUpdate interface { ssz.Marshaler + Proto() proto.Message Version() int AttestedHeader() LightClientHeader FinalizedHeader() LightClientHeader @@ -54,6 +66,7 @@ type LightClientFinalityUpdate interface { type LightClientOptimisticUpdate interface { ssz.Marshaler + Proto() proto.Message Version() int AttestedHeader() LightClientHeader SyncAggregate() *pb.SyncAggregate diff --git a/consensus-types/light-client/finality_update.go b/consensus-types/light-client/finality_update.go index 37de560e60ed..dad1259f2e75 100644 --- a/consensus-types/light-client/finality_update.go +++ b/consensus-types/light-client/finality_update.go @@ -28,6 +28,65 @@ func NewWrappedFinalityUpdate(m proto.Message) (interfaces.LightClientFinalityUp } } +func NewFinalityUpdateFromUpdate(update interfaces.LightClientUpdate) (interfaces.LightClientFinalityUpdate, error) { + switch t := update.(type) { + case *updateAltair: + return &finalityUpdateAltair{ + p: &pb.LightClientFinalityUpdateAltair{ + AttestedHeader: t.p.AttestedHeader, + FinalizedHeader: t.p.FinalizedHeader, + FinalityBranch: t.p.FinalityBranch, + SyncAggregate: t.p.SyncAggregate, + SignatureSlot: t.p.SignatureSlot, + }, + attestedHeader: t.attestedHeader, + finalizedHeader: t.finalizedHeader, + finalityBranch: t.finalityBranch, + }, nil + case *updateCapella: + return &finalityUpdateCapella{ + p: &pb.LightClientFinalityUpdateCapella{ + AttestedHeader: t.p.AttestedHeader, + FinalizedHeader: t.p.FinalizedHeader, + FinalityBranch: t.p.FinalityBranch, + SyncAggregate: t.p.SyncAggregate, + SignatureSlot: t.p.SignatureSlot, + }, + attestedHeader: t.attestedHeader, + finalizedHeader: t.finalizedHeader, + finalityBranch: t.finalityBranch, + }, nil + case *updateDeneb: + return &finalityUpdateDeneb{ + p: &pb.LightClientFinalityUpdateDeneb{ + AttestedHeader: t.p.AttestedHeader, + FinalizedHeader: t.p.FinalizedHeader, + FinalityBranch: t.p.FinalityBranch, + SyncAggregate: t.p.SyncAggregate, + SignatureSlot: t.p.SignatureSlot, + }, + attestedHeader: t.attestedHeader, + finalizedHeader: t.finalizedHeader, + finalityBranch: t.finalityBranch, + }, nil + case *updateElectra: + return &finalityUpdateDeneb{ + p: &pb.LightClientFinalityUpdateDeneb{ + AttestedHeader: t.p.AttestedHeader, + FinalizedHeader: t.p.FinalizedHeader, + FinalityBranch: t.p.FinalityBranch, + SyncAggregate: t.p.SyncAggregate, + SignatureSlot: t.p.SignatureSlot, + }, + attestedHeader: t.attestedHeader, + finalizedHeader: t.finalizedHeader, + finalityBranch: t.finalityBranch, + }, nil + default: + return nil, fmt.Errorf("unsupported type %T", t) + } +} + type finalityUpdateAltair struct { p *pb.LightClientFinalityUpdateAltair attestedHeader interfaces.LightClientHeader @@ -78,6 +137,10 @@ func (u *finalityUpdateAltair) SizeSSZ() int { return u.p.SizeSSZ() } +func (u *finalityUpdateAltair) Proto() proto.Message { + return u.p +} + func (u *finalityUpdateAltair) Version() int { return version.Altair } @@ -152,6 +215,10 @@ func (u *finalityUpdateCapella) SizeSSZ() int { return u.p.SizeSSZ() } +func (u *finalityUpdateCapella) Proto() proto.Message { + return u.p +} + func (u *finalityUpdateCapella) Version() int { return version.Capella } @@ -226,6 +293,10 @@ func (u *finalityUpdateDeneb) SizeSSZ() int { return u.p.SizeSSZ() } +func (u *finalityUpdateDeneb) Proto() proto.Message { + return u.p +} + func (u *finalityUpdateDeneb) Version() int { return version.Deneb } diff --git a/consensus-types/light-client/header.go b/consensus-types/light-client/header.go index 496a48424c7e..32b344227480 100644 --- a/consensus-types/light-client/header.go +++ b/consensus-types/light-client/header.go @@ -53,6 +53,10 @@ func (h *headerAltair) SizeSSZ() int { return h.p.SizeSSZ() } +func (h *headerAltair) Proto() proto.Message { + return h.p +} + func (h *headerAltair) Version() int { return version.Altair } @@ -114,6 +118,10 @@ func (h *headerCapella) SizeSSZ() int { return h.p.SizeSSZ() } +func (h *headerCapella) Proto() proto.Message { + return h.p +} + func (h *headerCapella) Version() int { return version.Capella } @@ -175,6 +183,10 @@ func (h *headerDeneb) SizeSSZ() int { return h.p.SizeSSZ() } +func (h *headerDeneb) Proto() proto.Message { + return h.p +} + func (h *headerDeneb) Version() int { return version.Deneb } diff --git a/consensus-types/light-client/helpers.go b/consensus-types/light-client/helpers.go index c2fc9b05922c..0d100314a4f9 100644 --- a/consensus-types/light-client/helpers.go +++ b/consensus-types/light-client/helpers.go @@ -4,12 +4,11 @@ import ( "fmt" fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams" - "github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces" "github.com/prysmaticlabs/prysm/v5/encoding/bytesutil" ) type branchConstraint interface { - ~interfaces.LightClientExecutionBranch | ~interfaces.LightClientSyncCommitteeBranch | ~interfaces.LightClientFinalityBranch + [4][32]byte | [5][32]byte | [6][32]byte } func createBranch[T branchConstraint](name string, input [][]byte, depth int) (T, error) { diff --git a/consensus-types/light-client/optimistic_update.go b/consensus-types/light-client/optimistic_update.go index f1f43d12cfa4..dd15ba02267e 100644 --- a/consensus-types/light-client/optimistic_update.go +++ b/consensus-types/light-client/optimistic_update.go @@ -27,12 +27,55 @@ func NewWrappedOptimisticUpdate(m proto.Message) (interfaces.LightClientOptimist } } -type OptimisticUpdateAltair struct { +func NewOptimisticUpdateFromUpdate(update interfaces.LightClientUpdate) (interfaces.LightClientOptimisticUpdate, error) { + switch t := update.(type) { + case *updateAltair: + return &optimisticUpdateAltair{ + p: &pb.LightClientOptimisticUpdateAltair{ + AttestedHeader: t.p.AttestedHeader, + SyncAggregate: t.p.SyncAggregate, + SignatureSlot: t.p.SignatureSlot, + }, + attestedHeader: t.attestedHeader, + }, nil + case *updateCapella: + return &optimisticUpdateCapella{ + p: &pb.LightClientOptimisticUpdateCapella{ + AttestedHeader: t.p.AttestedHeader, + SyncAggregate: t.p.SyncAggregate, + SignatureSlot: t.p.SignatureSlot, + }, + attestedHeader: t.attestedHeader, + }, nil + case *updateDeneb: + return &optimisticUpdateDeneb{ + p: &pb.LightClientOptimisticUpdateDeneb{ + AttestedHeader: t.p.AttestedHeader, + SyncAggregate: t.p.SyncAggregate, + SignatureSlot: t.p.SignatureSlot, + }, + attestedHeader: t.attestedHeader, + }, nil + case *updateElectra: + return &optimisticUpdateDeneb{ + p: &pb.LightClientOptimisticUpdateDeneb{ + AttestedHeader: t.p.AttestedHeader, + SyncAggregate: t.p.SyncAggregate, + SignatureSlot: t.p.SignatureSlot, + }, + attestedHeader: t.attestedHeader, + }, nil + default: + return nil, fmt.Errorf("unsupported type %T", t) + } +} + +type optimisticUpdateAltair struct { p *pb.LightClientOptimisticUpdateAltair attestedHeader interfaces.LightClientHeader } -var _ interfaces.LightClientOptimisticUpdate = &OptimisticUpdateAltair{} +var _ interfaces.LightClientOptimisticUpdate = &optimisticUpdateAltair{} func NewWrappedOptimisticUpdateAltair(p *pb.LightClientOptimisticUpdateAltair) (interfaces.LightClientOptimisticUpdate, error) { if p == nil { @@ -43,46 +86,50 @@ func NewWrappedOptimisticUpdateAltair(p *pb.LightClientOptimisticUpdateAltair) ( return nil, err } - return &OptimisticUpdateAltair{ + return &optimisticUpdateAltair{ p: p, attestedHeader: attestedHeader, }, nil } -func (u *OptimisticUpdateAltair) MarshalSSZTo(dst []byte) ([]byte, error) { +func (u *optimisticUpdateAltair) MarshalSSZTo(dst []byte) ([]byte, error) { return u.p.MarshalSSZTo(dst) } -func (u *OptimisticUpdateAltair) MarshalSSZ() ([]byte, error) { +func (u *optimisticUpdateAltair) MarshalSSZ() ([]byte, error) { return u.p.MarshalSSZ() } -func (u *OptimisticUpdateAltair) SizeSSZ() int { +func (u *optimisticUpdateAltair) SizeSSZ() int { return u.p.SizeSSZ() } -func (u *OptimisticUpdateAltair) Version() int { +func (u *optimisticUpdateAltair) Proto() proto.Message { + return u.p +} + +func (u *optimisticUpdateAltair) Version() int { return version.Altair } -func (u *OptimisticUpdateAltair) AttestedHeader() interfaces.LightClientHeader { +func (u *optimisticUpdateAltair) AttestedHeader() interfaces.LightClientHeader { return u.attestedHeader } -func (u *OptimisticUpdateAltair) SyncAggregate() *pb.SyncAggregate { +func (u *optimisticUpdateAltair) SyncAggregate() *pb.SyncAggregate { return u.p.SyncAggregate } -func (u *OptimisticUpdateAltair) SignatureSlot() primitives.Slot { +func (u *optimisticUpdateAltair) SignatureSlot() primitives.Slot { return u.p.SignatureSlot } -type OptimisticUpdateCapella struct { +type optimisticUpdateCapella struct { p *pb.LightClientOptimisticUpdateCapella attestedHeader interfaces.LightClientHeader } -var _ interfaces.LightClientOptimisticUpdate = &OptimisticUpdateCapella{} +var _ interfaces.LightClientOptimisticUpdate = &optimisticUpdateCapella{} func NewWrappedOptimisticUpdateCapella(p *pb.LightClientOptimisticUpdateCapella) (interfaces.LightClientOptimisticUpdate, error) { if p == nil { @@ -93,46 +140,50 @@ func NewWrappedOptimisticUpdateCapella(p *pb.LightClientOptimisticUpdateCapella) return nil, err } - return &OptimisticUpdateCapella{ + return &optimisticUpdateCapella{ p: p, attestedHeader: attestedHeader, }, nil } -func (u *OptimisticUpdateCapella) MarshalSSZTo(dst []byte) ([]byte, error) { +func (u *optimisticUpdateCapella) MarshalSSZTo(dst []byte) ([]byte, error) { return u.p.MarshalSSZTo(dst) } -func (u *OptimisticUpdateCapella) MarshalSSZ() ([]byte, error) { +func (u *optimisticUpdateCapella) MarshalSSZ() ([]byte, error) { return u.p.MarshalSSZ() } -func (u *OptimisticUpdateCapella) SizeSSZ() int { +func (u *optimisticUpdateCapella) SizeSSZ() int { return u.p.SizeSSZ() } -func (u *OptimisticUpdateCapella) Version() int { +func (u *optimisticUpdateCapella) Proto() proto.Message { + return u.p +} + +func (u *optimisticUpdateCapella) Version() int { return version.Capella } -func (u *OptimisticUpdateCapella) AttestedHeader() interfaces.LightClientHeader { +func (u *optimisticUpdateCapella) AttestedHeader() interfaces.LightClientHeader { return u.attestedHeader } -func (u *OptimisticUpdateCapella) SyncAggregate() *pb.SyncAggregate { +func (u *optimisticUpdateCapella) SyncAggregate() *pb.SyncAggregate { return u.p.SyncAggregate } -func (u *OptimisticUpdateCapella) SignatureSlot() primitives.Slot { +func (u *optimisticUpdateCapella) SignatureSlot() primitives.Slot { return u.p.SignatureSlot } -type OptimisticUpdateDeneb struct { +type optimisticUpdateDeneb struct { p *pb.LightClientOptimisticUpdateDeneb attestedHeader interfaces.LightClientHeader } -var _ interfaces.LightClientOptimisticUpdate = &OptimisticUpdateDeneb{} +var _ interfaces.LightClientOptimisticUpdate = &optimisticUpdateDeneb{} func NewWrappedOptimisticUpdateDeneb(p *pb.LightClientOptimisticUpdateDeneb) (interfaces.LightClientOptimisticUpdate, error) { if p == nil { @@ -143,36 +194,40 @@ func NewWrappedOptimisticUpdateDeneb(p *pb.LightClientOptimisticUpdateDeneb) (in return nil, err } - return &OptimisticUpdateDeneb{ + return &optimisticUpdateDeneb{ p: p, attestedHeader: attestedHeader, }, nil } -func (u *OptimisticUpdateDeneb) MarshalSSZTo(dst []byte) ([]byte, error) { +func (u *optimisticUpdateDeneb) MarshalSSZTo(dst []byte) ([]byte, error) { return u.p.MarshalSSZTo(dst) } -func (u *OptimisticUpdateDeneb) MarshalSSZ() ([]byte, error) { +func (u *optimisticUpdateDeneb) MarshalSSZ() ([]byte, error) { return u.p.MarshalSSZ() } -func (u *OptimisticUpdateDeneb) SizeSSZ() int { +func (u *optimisticUpdateDeneb) SizeSSZ() int { return u.p.SizeSSZ() } -func (u *OptimisticUpdateDeneb) Version() int { +func (u *optimisticUpdateDeneb) Proto() proto.Message { + return u.p +} + +func (u *optimisticUpdateDeneb) Version() int { return version.Deneb } -func (u *OptimisticUpdateDeneb) AttestedHeader() interfaces.LightClientHeader { +func (u *optimisticUpdateDeneb) AttestedHeader() interfaces.LightClientHeader { return u.attestedHeader } -func (u *OptimisticUpdateDeneb) SyncAggregate() *pb.SyncAggregate { +func (u *optimisticUpdateDeneb) SyncAggregate() *pb.SyncAggregate { return u.p.SyncAggregate } -func (u *OptimisticUpdateDeneb) SignatureSlot() primitives.Slot { +func (u *optimisticUpdateDeneb) SignatureSlot() primitives.Slot { return u.p.SignatureSlot } diff --git a/consensus-types/light-client/update.go b/consensus-types/light-client/update.go index 66a3403f1896..81ebf87f9c69 100644 --- a/consensus-types/light-client/update.go +++ b/consensus-types/light-client/update.go @@ -23,6 +23,8 @@ func NewWrappedUpdate(m proto.Message) (interfaces.LightClientUpdate, error) { return NewWrappedUpdateCapella(t) case *pb.LightClientUpdateDeneb: return NewWrappedUpdateDeneb(t) + case *pb.LightClientUpdateElectra: + return NewWrappedUpdateElectra(t) default: return nil, fmt.Errorf("cannot construct light client update from type %T", t) } @@ -46,10 +48,15 @@ func NewWrappedUpdateAltair(p *pb.LightClientUpdateAltair) (interfaces.LightClie if err != nil { return nil, err } - finalizedHeader, err := NewWrappedHeaderAltair(p.FinalizedHeader) - if err != nil { - return nil, err + + var finalizedHeader interfaces.LightClientHeader + if p.FinalizedHeader != nil { + finalizedHeader, err = NewWrappedHeaderAltair(p.FinalizedHeader) + if err != nil { + return nil, err + } } + scBranch, err := createBranch[interfaces.LightClientSyncCommitteeBranch]( "sync committee", p.NextSyncCommitteeBranch, @@ -88,6 +95,10 @@ func (u *updateAltair) SizeSSZ() int { return u.p.SizeSSZ() } +func (u *updateAltair) Proto() proto.Message { + return u.p +} + func (u *updateAltair) Version() int { return version.Altair } @@ -96,34 +107,76 @@ func (u *updateAltair) AttestedHeader() interfaces.LightClientHeader { return u.attestedHeader } +func (u *updateAltair) SetAttestedHeader(header interfaces.LightClientHeader) { + u.attestedHeader = header +} + func (u *updateAltair) NextSyncCommittee() *pb.SyncCommittee { return u.p.NextSyncCommittee } +func (u *updateAltair) SetNextSyncCommittee(sc *pb.SyncCommittee) { + u.p.NextSyncCommittee = sc +} + func (u *updateAltair) NextSyncCommitteeBranch() (interfaces.LightClientSyncCommitteeBranch, error) { return u.nextSyncCommitteeBranch, nil } +func (u *updateAltair) SetNextSyncCommitteeBranch(branch [][]byte) error { + b, err := createBranch[interfaces.LightClientSyncCommitteeBranch]("sync committee", branch, fieldparams.SyncCommitteeBranchDepth) + if err != nil { + return err + } + u.nextSyncCommitteeBranch = b + return nil +} + func (u *updateAltair) NextSyncCommitteeBranchElectra() (interfaces.LightClientSyncCommitteeBranchElectra, error) { return [6][32]byte{}, consensustypes.ErrNotSupported("NextSyncCommitteeBranchElectra", version.Altair) } +func (u *updateAltair) SetNextSyncCommitteeBranchElectra([][]byte) error { + return consensustypes.ErrNotSupported("SetNextSyncCommitteeBranchElectra", version.Altair) +} + func (u *updateAltair) FinalizedHeader() interfaces.LightClientHeader { return u.finalizedHeader } +func (u *updateAltair) SetFinalizedHeader(header interfaces.LightClientHeader) { + u.finalizedHeader = header +} + func (u *updateAltair) FinalityBranch() interfaces.LightClientFinalityBranch { return u.finalityBranch } +func (u *updateAltair) SetFinalityBranch(branch [][]byte) error { + b, err := createBranch[interfaces.LightClientFinalityBranch]("finality", branch, fieldparams.FinalityBranchDepth) + if err != nil { + return err + } + u.finalityBranch = b + return nil +} + func (u *updateAltair) SyncAggregate() *pb.SyncAggregate { return u.p.SyncAggregate } +func (u *updateAltair) SetSyncAggregate(sa *pb.SyncAggregate) { + u.p.SyncAggregate = sa +} + func (u *updateAltair) SignatureSlot() primitives.Slot { return u.p.SignatureSlot } +func (u *updateAltair) SetSignatureSlot(slot primitives.Slot) { + u.p.SignatureSlot = slot +} + type updateCapella struct { p *pb.LightClientUpdateCapella attestedHeader interfaces.LightClientHeader @@ -142,10 +195,15 @@ func NewWrappedUpdateCapella(p *pb.LightClientUpdateCapella) (interfaces.LightCl if err != nil { return nil, err } - finalizedHeader, err := NewWrappedHeaderCapella(p.FinalizedHeader) - if err != nil { - return nil, err + + var finalizedHeader interfaces.LightClientHeader + if p.FinalizedHeader != nil { + finalizedHeader, err = NewWrappedHeaderCapella(p.FinalizedHeader) + if err != nil { + return nil, err + } } + scBranch, err := createBranch[interfaces.LightClientSyncCommitteeBranch]( "sync committee", p.NextSyncCommitteeBranch, @@ -184,6 +242,10 @@ func (u *updateCapella) SizeSSZ() int { return u.p.SizeSSZ() } +func (u *updateCapella) Proto() proto.Message { + return u.p +} + func (u *updateCapella) Version() int { return version.Capella } @@ -192,34 +254,76 @@ func (u *updateCapella) AttestedHeader() interfaces.LightClientHeader { return u.attestedHeader } +func (u *updateCapella) SetAttestedHeader(header interfaces.LightClientHeader) { + u.attestedHeader = header +} + func (u *updateCapella) NextSyncCommittee() *pb.SyncCommittee { return u.p.NextSyncCommittee } +func (u *updateCapella) SetNextSyncCommittee(sc *pb.SyncCommittee) { + u.p.NextSyncCommittee = sc +} + func (u *updateCapella) NextSyncCommitteeBranch() (interfaces.LightClientSyncCommitteeBranch, error) { return u.nextSyncCommitteeBranch, nil } +func (u *updateCapella) SetNextSyncCommitteeBranch(branch [][]byte) error { + b, err := createBranch[interfaces.LightClientSyncCommitteeBranch]("sync committee", branch, fieldparams.SyncCommitteeBranchDepth) + if err != nil { + return err + } + u.nextSyncCommitteeBranch = b + return nil +} + func (u *updateCapella) NextSyncCommitteeBranchElectra() (interfaces.LightClientSyncCommitteeBranchElectra, error) { return [6][32]byte{}, consensustypes.ErrNotSupported("NextSyncCommitteeBranchElectra", version.Capella) } +func (u *updateCapella) SetNextSyncCommitteeBranchElectra([][]byte) error { + return consensustypes.ErrNotSupported("SetNextSyncCommitteeBranchElectra", version.Capella) +} + func (u *updateCapella) FinalizedHeader() interfaces.LightClientHeader { return u.finalizedHeader } +func (u *updateCapella) SetFinalizedHeader(header interfaces.LightClientHeader) { + u.finalizedHeader = header +} + func (u *updateCapella) FinalityBranch() interfaces.LightClientFinalityBranch { return u.finalityBranch } +func (u *updateCapella) SetFinalityBranch(branch [][]byte) error { + b, err := createBranch[interfaces.LightClientFinalityBranch]("finality", branch, fieldparams.FinalityBranchDepth) + if err != nil { + return err + } + u.finalityBranch = b + return nil +} + func (u *updateCapella) SyncAggregate() *pb.SyncAggregate { return u.p.SyncAggregate } +func (u *updateCapella) SetSyncAggregate(sa *pb.SyncAggregate) { + u.p.SyncAggregate = sa +} + func (u *updateCapella) SignatureSlot() primitives.Slot { return u.p.SignatureSlot } +func (u *updateCapella) SetSignatureSlot(slot primitives.Slot) { + u.p.SignatureSlot = slot +} + type updateDeneb struct { p *pb.LightClientUpdateDeneb attestedHeader interfaces.LightClientHeader @@ -238,10 +342,15 @@ func NewWrappedUpdateDeneb(p *pb.LightClientUpdateDeneb) (interfaces.LightClient if err != nil { return nil, err } - finalizedHeader, err := NewWrappedHeaderDeneb(p.FinalizedHeader) - if err != nil { - return nil, err + + var finalizedHeader interfaces.LightClientHeader + if p.FinalizedHeader != nil { + finalizedHeader, err = NewWrappedHeaderDeneb(p.FinalizedHeader) + if err != nil { + return nil, err + } } + scBranch, err := createBranch[interfaces.LightClientSyncCommitteeBranch]( "sync committee", p.NextSyncCommitteeBranch, @@ -280,6 +389,10 @@ func (u *updateDeneb) SizeSSZ() int { return u.p.SizeSSZ() } +func (u *updateDeneb) Proto() proto.Message { + return u.p +} + func (u *updateDeneb) Version() int { return version.Deneb } @@ -288,34 +401,76 @@ func (u *updateDeneb) AttestedHeader() interfaces.LightClientHeader { return u.attestedHeader } +func (u *updateDeneb) SetAttestedHeader(header interfaces.LightClientHeader) { + u.attestedHeader = header +} + func (u *updateDeneb) NextSyncCommittee() *pb.SyncCommittee { return u.p.NextSyncCommittee } +func (u *updateDeneb) SetNextSyncCommittee(sc *pb.SyncCommittee) { + u.p.NextSyncCommittee = sc +} + func (u *updateDeneb) NextSyncCommitteeBranch() (interfaces.LightClientSyncCommitteeBranch, error) { return u.nextSyncCommitteeBranch, nil } +func (u *updateDeneb) SetNextSyncCommitteeBranch(branch [][]byte) error { + b, err := createBranch[interfaces.LightClientSyncCommitteeBranch]("sync committee", branch, fieldparams.SyncCommitteeBranchDepth) + if err != nil { + return err + } + u.nextSyncCommitteeBranch = b + return nil +} + func (u *updateDeneb) NextSyncCommitteeBranchElectra() (interfaces.LightClientSyncCommitteeBranchElectra, error) { return [6][32]byte{}, consensustypes.ErrNotSupported("NextSyncCommitteeBranchElectra", version.Deneb) } +func (u *updateDeneb) SetNextSyncCommitteeBranchElectra([][]byte) error { + return consensustypes.ErrNotSupported("SetNextSyncCommitteeBranchElectra", version.Deneb) +} + func (u *updateDeneb) FinalizedHeader() interfaces.LightClientHeader { return u.finalizedHeader } +func (u *updateDeneb) SetFinalizedHeader(header interfaces.LightClientHeader) { + u.finalizedHeader = header +} + func (u *updateDeneb) FinalityBranch() interfaces.LightClientFinalityBranch { return u.finalityBranch } +func (u *updateDeneb) SetFinalityBranch(branch [][]byte) error { + b, err := createBranch[interfaces.LightClientFinalityBranch]("finality", branch, fieldparams.FinalityBranchDepth) + if err != nil { + return err + } + u.finalityBranch = b + return nil +} + func (u *updateDeneb) SyncAggregate() *pb.SyncAggregate { return u.p.SyncAggregate } +func (u *updateDeneb) SetSyncAggregate(sa *pb.SyncAggregate) { + u.p.SyncAggregate = sa +} + func (u *updateDeneb) SignatureSlot() primitives.Slot { return u.p.SignatureSlot } +func (u *updateDeneb) SetSignatureSlot(slot primitives.Slot) { + u.p.SignatureSlot = slot +} + type updateElectra struct { p *pb.LightClientUpdateElectra attestedHeader interfaces.LightClientHeader @@ -334,10 +489,15 @@ func NewWrappedUpdateElectra(p *pb.LightClientUpdateElectra) (interfaces.LightCl if err != nil { return nil, err } - finalizedHeader, err := NewWrappedHeaderDeneb(p.FinalizedHeader) - if err != nil { - return nil, err + + var finalizedHeader interfaces.LightClientHeader + if p.FinalizedHeader != nil { + finalizedHeader, err = NewWrappedHeaderDeneb(p.FinalizedHeader) + if err != nil { + return nil, err + } } + scBranch, err := createBranch[interfaces.LightClientSyncCommitteeBranchElectra]( "sync committee", p.NextSyncCommitteeBranch, @@ -376,6 +536,10 @@ func (u *updateElectra) SizeSSZ() int { return u.p.SizeSSZ() } +func (u *updateElectra) Proto() proto.Message { + return u.p +} + func (u *updateElectra) Version() int { return version.Electra } @@ -384,30 +548,72 @@ func (u *updateElectra) AttestedHeader() interfaces.LightClientHeader { return u.attestedHeader } +func (u *updateElectra) SetAttestedHeader(header interfaces.LightClientHeader) { + u.attestedHeader = header +} + func (u *updateElectra) NextSyncCommittee() *pb.SyncCommittee { return u.p.NextSyncCommittee } +func (u *updateElectra) SetNextSyncCommittee(sc *pb.SyncCommittee) { + u.p.NextSyncCommittee = sc +} + func (u *updateElectra) NextSyncCommitteeBranch() (interfaces.LightClientSyncCommitteeBranch, error) { return [5][32]byte{}, consensustypes.ErrNotSupported("NextSyncCommitteeBranch", version.Electra) } +func (u *updateElectra) SetNextSyncCommitteeBranch([][]byte) error { + return consensustypes.ErrNotSupported("SetNextSyncCommitteeBranch", version.Electra) +} + func (u *updateElectra) NextSyncCommitteeBranchElectra() (interfaces.LightClientSyncCommitteeBranchElectra, error) { return u.nextSyncCommitteeBranch, nil } +func (u *updateElectra) SetNextSyncCommitteeBranchElectra(branch [][]byte) error { + b, err := createBranch[interfaces.LightClientSyncCommitteeBranchElectra]("sync committee", branch, fieldparams.SyncCommitteeBranchDepthElectra) + if err != nil { + return err + } + u.nextSyncCommitteeBranch = b + return nil +} + func (u *updateElectra) FinalizedHeader() interfaces.LightClientHeader { return u.finalizedHeader } +func (u *updateElectra) SetFinalizedHeader(header interfaces.LightClientHeader) { + u.finalizedHeader = header +} + func (u *updateElectra) FinalityBranch() interfaces.LightClientFinalityBranch { return u.finalityBranch } +func (u *updateElectra) SetFinalityBranch(branch [][]byte) error { + b, err := createBranch[interfaces.LightClientFinalityBranch]("finality", branch, fieldparams.FinalityBranchDepth) + if err != nil { + return err + } + u.finalityBranch = b + return nil +} + func (u *updateElectra) SyncAggregate() *pb.SyncAggregate { return u.p.SyncAggregate } +func (u *updateElectra) SetSyncAggregate(sa *pb.SyncAggregate) { + u.p.SyncAggregate = sa +} + func (u *updateElectra) SignatureSlot() primitives.Slot { return u.p.SignatureSlot } + +func (u *updateElectra) SetSignatureSlot(slot primitives.Slot) { + u.p.SignatureSlot = slot +} From 2300bf98025f2b89b4cc3fd6da82ad3344f26f5e Mon Sep 17 00:00:00 2001 From: Inspector-Butters Date: Tue, 22 Oct 2024 13:53:22 +0200 Subject: [PATCH 20/35] fix rpc/helpers_test --- beacon-chain/core/light-client/BUILD.bazel | 6 - beacon-chain/core/light-client/lightclient.go | 8 +- .../core/light-client/lightclient_test.go | 1445 +++-- beacon-chain/rpc/eth/light-client/BUILD.bazel | 17 +- .../rpc/eth/light-client/handlers_test.go | 4941 +++++++++-------- .../rpc/eth/light-client/helpers_test.go | 1207 ++-- testing/util/lightclient.go | 18 +- 7 files changed, 3823 insertions(+), 3819 deletions(-) diff --git a/beacon-chain/core/light-client/BUILD.bazel b/beacon-chain/core/light-client/BUILD.bazel index 327e1922055f..f8e8bba99f7c 100644 --- a/beacon-chain/core/light-client/BUILD.bazel +++ b/beacon-chain/core/light-client/BUILD.bazel @@ -30,13 +30,7 @@ go_test( srcs = ["lightclient_test.go"], deps = [ ":go_default_library", - "//config/fieldparams:go_default_library", - "//consensus-types:go_default_library", - "//consensus-types/blocks:go_default_library", - "//encoding/ssz:go_default_library", - "//proto/engine/v1:go_default_library", "//testing/require:go_default_library", "//testing/util:go_default_library", - "@com_github_pkg_errors//:go_default_library", ], ) diff --git a/beacon-chain/core/light-client/lightclient.go b/beacon-chain/core/light-client/lightclient.go index 7c60a163cf05..7b4e9f94ce28 100644 --- a/beacon-chain/core/light-client/lightclient.go +++ b/beacon-chain/core/light-client/lightclient.go @@ -159,7 +159,7 @@ func NewLightClientUpdateFromBeaconState( updateAttestedPeriod := slots.SyncCommitteePeriod(slots.ToEpoch(attestedBlock.Block().Slot())) // update = LightClientUpdate() - result, err := createDefaultLightClientUpdate(currentSlot) + result, err := CreateDefaultLightClientUpdate(currentSlot) if err != nil { return nil, errors.Wrap(err, "could not create default light client update") } @@ -239,7 +239,7 @@ func NewLightClientUpdateFromBeaconState( return result, nil } -func createDefaultLightClientUpdate(currentSlot primitives.Slot) (interfaces.LightClientUpdate, error) { +func CreateDefaultLightClientUpdate(currentSlot primitives.Slot) (interfaces.LightClientUpdate, error) { currentEpoch := slots.ToEpoch(currentSlot) syncCommitteeSize := params.BeaconConfig().SyncCommitteeSize @@ -274,24 +274,28 @@ func createDefaultLightClientUpdate(currentSlot primitives.Slot) (interfaces.Lig var m proto.Message if currentEpoch < params.BeaconConfig().CapellaForkEpoch { m = &pb.LightClientUpdateAltair{ + AttestedHeader: &pb.LightClientHeaderAltair{}, NextSyncCommittee: nextSyncCommittee, NextSyncCommitteeBranch: nextSyncCommitteeBranch, FinalityBranch: finalityBranch, } } else if currentEpoch < params.BeaconConfig().DenebForkEpoch { m = &pb.LightClientUpdateCapella{ + AttestedHeader: &pb.LightClientHeaderCapella{}, NextSyncCommittee: nextSyncCommittee, NextSyncCommitteeBranch: nextSyncCommitteeBranch, FinalityBranch: finalityBranch, } } else if currentEpoch < params.BeaconConfig().ElectraForkEpoch { m = &pb.LightClientUpdateDeneb{ + AttestedHeader: &pb.LightClientHeaderDeneb{}, NextSyncCommittee: nextSyncCommittee, NextSyncCommitteeBranch: nextSyncCommitteeBranch, FinalityBranch: finalityBranch, } } else { m = &pb.LightClientUpdateElectra{ + AttestedHeader: &pb.LightClientHeaderDeneb{}, NextSyncCommittee: nextSyncCommittee, NextSyncCommitteeBranch: nextSyncCommitteeBranch, FinalityBranch: finalityBranch, diff --git a/beacon-chain/core/light-client/lightclient_test.go b/beacon-chain/core/light-client/lightclient_test.go index eb6ab4417083..045eaeeadeac 100644 --- a/beacon-chain/core/light-client/lightclient_test.go +++ b/beacon-chain/core/light-client/lightclient_test.go @@ -3,13 +3,6 @@ package light_client_test import ( "testing" - "github.com/pkg/errors" - fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams" - consensustypes "github.com/prysmaticlabs/prysm/v5/consensus-types" - "github.com/prysmaticlabs/prysm/v5/consensus-types/blocks" - "github.com/prysmaticlabs/prysm/v5/encoding/ssz" - v11 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1" - lightClient "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/light-client" "github.com/prysmaticlabs/prysm/v5/testing/require" "github.com/prysmaticlabs/prysm/v5/testing/util" @@ -19,730 +12,730 @@ func TestLightClient_NewLightClientOptimisticUpdateFromBeaconState(t *testing.T) t.Run("Altair", func(t *testing.T) { l := util.NewTestLightClient(t).SetupTestAltair() - update, err := lightClient.NewLightClientOptimisticUpdateFromBeaconState(l.Ctx, l.State, l.Block, l.AttestedState, l.AttestedBlock) - require.NoError(t, err) - require.NotNil(t, update, "update is nil") - require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot, "Signature slot is not equal") - - l.CheckSyncAggregate(update.SyncAggregate) - l.CheckAttestedHeader(update.AttestedHeader) - }) - - t.Run("Capella", func(t *testing.T) { - l := util.NewTestLightClient(t).SetupTestCapella(false) - - update, err := lightClient.NewLightClientOptimisticUpdateFromBeaconState(l.Ctx, l.State, l.Block, l.AttestedState, l.AttestedBlock) + update, err := lightClient.NewLightClientOptimisticUpdateFromBeaconState(l.Ctx, l.State.Slot(), l.State, l.Block, l.AttestedState, l.AttestedBlock) require.NoError(t, err) require.NotNil(t, update, "update is nil") - require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot, "Signature slot is not equal") - l.CheckSyncAggregate(update.SyncAggregate) - l.CheckAttestedHeader(update.AttestedHeader) + l.CheckSyncAggregate(update.SyncAggregate()) + l.CheckAttestedHeader(update.AttestedHeader()) }) - t.Run("Deneb", func(t *testing.T) { - l := util.NewTestLightClient(t).SetupTestDeneb(false) - - update, err := lightClient.NewLightClientOptimisticUpdateFromBeaconState(l.Ctx, l.State, l.Block, l.AttestedState, l.AttestedBlock) - require.NoError(t, err) - require.NotNil(t, update, "update is nil") - - require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot, "Signature slot is not equal") - - l.CheckSyncAggregate(update.SyncAggregate) - l.CheckAttestedHeader(update.AttestedHeader) - }) + //t.Run("Capella", func(t *testing.T) { + // l := util.NewTestLightClient(t).SetupTestCapella(false) + // + // update, err := lightClient.NewLightClientOptimisticUpdateFromBeaconState(l.Ctx, l.State, l.Block, l.AttestedState, l.AttestedBlock) + // require.NoError(t, err) + // require.NotNil(t, update, "update is nil") + // + // require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot, "Signature slot is not equal") + // + // l.CheckSyncAggregate(update.SyncAggregate) + // l.CheckAttestedHeader(update.AttestedHeader) + //}) + // + //t.Run("Deneb", func(t *testing.T) { + // l := util.NewTestLightClient(t).SetupTestDeneb(false) + // + // update, err := lightClient.NewLightClientOptimisticUpdateFromBeaconState(l.Ctx, l.State, l.Block, l.AttestedState, l.AttestedBlock) + // require.NoError(t, err) + // require.NotNil(t, update, "update is nil") + // + // require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot, "Signature slot is not equal") + // + // l.CheckSyncAggregate(update.SyncAggregate) + // l.CheckAttestedHeader(update.AttestedHeader) + //}) } -func TestLightClient_NewLightClientFinalityUpdateFromBeaconState(t *testing.T) { - t.Run("Altair", func(t *testing.T) { - l := util.NewTestLightClient(t).SetupTestAltair() - - t.Run("FinalizedBlock Not Nil", func(t *testing.T) { - update, err := lightClient.NewLightClientFinalityUpdateFromBeaconState(l.Ctx, l.State, l.Block, l.AttestedState, l.AttestedBlock, l.FinalizedBlock) - require.NoError(t, err) - require.NotNil(t, update, "update is nil") - - require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot, "Signature slot is not equal") - - l.CheckSyncAggregate(update.SyncAggregate) - l.CheckAttestedHeader(update.AttestedHeader) - - finalizedBlockHeader, err := l.FinalizedBlock.Header() - require.NoError(t, err) - - //zeroHash := params.BeaconConfig().ZeroHash[:] - require.NotNil(t, update.FinalizedHeader, "Finalized header is nil") - updateFinalizedHeaderBeacon, err := update.FinalizedHeader.GetBeacon() - require.NoError(t, err) - require.Equal(t, finalizedBlockHeader.Header.Slot, updateFinalizedHeaderBeacon.Slot, "Finalized header slot is not equal") - require.Equal(t, finalizedBlockHeader.Header.ProposerIndex, updateFinalizedHeaderBeacon.ProposerIndex, "Finalized header proposer index is not equal") - require.DeepSSZEqual(t, finalizedBlockHeader.Header.ParentRoot, updateFinalizedHeaderBeacon.ParentRoot, "Finalized header parent root is not equal") - require.DeepSSZEqual(t, finalizedBlockHeader.Header.StateRoot, updateFinalizedHeaderBeacon.StateRoot, "Finalized header state root is not equal") - require.DeepSSZEqual(t, finalizedBlockHeader.Header.BodyRoot, updateFinalizedHeaderBeacon.BodyRoot, "Finalized header body root is not equal") - require.Equal(t, lightClient.FinalityBranchNumOfLeaves, len(update.FinalityBranch), "Invalid finality branch leaves") - - finalityBranch, err := l.AttestedState.FinalizedRootProof(l.Ctx) - require.NoError(t, err) - for i, leaf := range update.FinalityBranch { - require.DeepSSZEqual(t, finalityBranch[i], leaf, "Leaf is not equal") - } - }) - }) - - t.Run("Capella", func(t *testing.T) { - - t.Run("FinalizedBlock Not Nil", func(t *testing.T) { - l := util.NewTestLightClient(t).SetupTestCapella(false) - update, err := lightClient.NewLightClientFinalityUpdateFromBeaconState(l.Ctx, l.State, l.Block, l.AttestedState, l.AttestedBlock, l.FinalizedBlock) - require.NoError(t, err) - require.NotNil(t, update, "update is nil") - - require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot, "Signature slot is not equal") - - l.CheckSyncAggregate(update.SyncAggregate) - l.CheckAttestedHeader(update.AttestedHeader) - - finalizedBlockHeader, err := l.FinalizedBlock.Header() - require.NoError(t, err) - require.NotNil(t, update.FinalizedHeader, "Finalized header is nil") - updateFinalizedHeaderBeacon, err := update.FinalizedHeader.GetBeacon() - require.NoError(t, err) - require.Equal(t, finalizedBlockHeader.Header.Slot, updateFinalizedHeaderBeacon.Slot, "Finalized header slot is not equal") - require.Equal(t, finalizedBlockHeader.Header.ProposerIndex, updateFinalizedHeaderBeacon.ProposerIndex, "Finalized header proposer index is not equal") - require.DeepSSZEqual(t, finalizedBlockHeader.Header.ParentRoot, updateFinalizedHeaderBeacon.ParentRoot, "Finalized header parent root is not equal") - require.DeepSSZEqual(t, finalizedBlockHeader.Header.StateRoot, updateFinalizedHeaderBeacon.StateRoot, "Finalized header state root is not equal") - require.DeepSSZEqual(t, finalizedBlockHeader.Header.BodyRoot, updateFinalizedHeaderBeacon.BodyRoot, "Finalized header body root is not equal") - require.Equal(t, lightClient.FinalityBranchNumOfLeaves, len(update.FinalityBranch), "Invalid finality branch leaves") - finalityBranch, err := l.AttestedState.FinalizedRootProof(l.Ctx) - require.NoError(t, err) - for i, leaf := range update.FinalityBranch { - require.DeepSSZEqual(t, finalityBranch[i], leaf, "Leaf is not equal") - } - - // Check Execution BlockHash - payloadInterface, err := l.FinalizedBlock.Block().Body().Execution() - require.NoError(t, err) - transactionsRoot, err := payloadInterface.TransactionsRoot() - if errors.Is(err, consensustypes.ErrUnsupportedField) { - transactions, err := payloadInterface.Transactions() - require.NoError(t, err) - transactionsRootArray, err := ssz.TransactionsRoot(transactions) - require.NoError(t, err) - transactionsRoot = transactionsRootArray[:] - } else { - require.NoError(t, err) - } - withdrawalsRoot, err := payloadInterface.WithdrawalsRoot() - if errors.Is(err, consensustypes.ErrUnsupportedField) { - withdrawals, err := payloadInterface.Withdrawals() - require.NoError(t, err) - withdrawalsRootArray, err := ssz.WithdrawalSliceRoot(withdrawals, fieldparams.MaxWithdrawalsPerPayload) - require.NoError(t, err) - withdrawalsRoot = withdrawalsRootArray[:] - } else { - require.NoError(t, err) - } - execution := &v11.ExecutionPayloadHeaderCapella{ - ParentHash: payloadInterface.ParentHash(), - FeeRecipient: payloadInterface.FeeRecipient(), - StateRoot: payloadInterface.StateRoot(), - ReceiptsRoot: payloadInterface.ReceiptsRoot(), - LogsBloom: payloadInterface.LogsBloom(), - PrevRandao: payloadInterface.PrevRandao(), - BlockNumber: payloadInterface.BlockNumber(), - GasLimit: payloadInterface.GasLimit(), - GasUsed: payloadInterface.GasUsed(), - Timestamp: payloadInterface.Timestamp(), - ExtraData: payloadInterface.ExtraData(), - BaseFeePerGas: payloadInterface.BaseFeePerGas(), - BlockHash: payloadInterface.BlockHash(), - TransactionsRoot: transactionsRoot, - WithdrawalsRoot: withdrawalsRoot, - } - require.DeepSSZEqual(t, execution, update.FinalizedHeader.GetHeaderCapella().Execution, "Finalized Block Execution is not equal") - }) - - t.Run("FinalizedBlock In Previous Fork", func(t *testing.T) { - l := util.NewTestLightClient(t).SetupTestCapellaFinalizedBlockAltair(false) - update, err := lightClient.NewLightClientFinalityUpdateFromBeaconState(l.Ctx, l.State, l.Block, l.AttestedState, l.AttestedBlock, l.FinalizedBlock) - require.NoError(t, err) - require.NotNil(t, update, "update is nil") - - require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot, "Signature slot is not equal") - - l.CheckSyncAggregate(update.SyncAggregate) - l.CheckAttestedHeader(update.AttestedHeader) - - finalizedBlockHeader, err := l.FinalizedBlock.Header() - require.NoError(t, err) - require.NotNil(t, update.FinalizedHeader, "Finalized header is nil") - updateFinalizedHeaderBeacon, err := update.FinalizedHeader.GetBeacon() - require.NoError(t, err) - require.Equal(t, finalizedBlockHeader.Header.Slot, updateFinalizedHeaderBeacon.Slot, "Finalized header slot is not equal") - require.Equal(t, finalizedBlockHeader.Header.ProposerIndex, updateFinalizedHeaderBeacon.ProposerIndex, "Finalized header proposer index is not equal") - require.DeepSSZEqual(t, finalizedBlockHeader.Header.ParentRoot, updateFinalizedHeaderBeacon.ParentRoot, "Finalized header parent root is not equal") - require.DeepSSZEqual(t, finalizedBlockHeader.Header.StateRoot, updateFinalizedHeaderBeacon.StateRoot, "Finalized header state root is not equal") - require.DeepSSZEqual(t, finalizedBlockHeader.Header.BodyRoot, updateFinalizedHeaderBeacon.BodyRoot, "Finalized header body root is not equal") - require.Equal(t, lightClient.FinalityBranchNumOfLeaves, len(update.FinalityBranch), "Invalid finality branch leaves") - finalityBranch, err := l.AttestedState.FinalizedRootProof(l.Ctx) - require.NoError(t, err) - for i, leaf := range update.FinalityBranch { - require.DeepSSZEqual(t, finalityBranch[i], leaf, "Leaf is not equal") - } - }) - }) - - t.Run("Deneb", func(t *testing.T) { - - t.Run("FinalizedBlock Not Nil", func(t *testing.T) { - l := util.NewTestLightClient(t).SetupTestDeneb(false) - - update, err := lightClient.NewLightClientFinalityUpdateFromBeaconState(l.Ctx, l.State, l.Block, l.AttestedState, l.AttestedBlock, l.FinalizedBlock) - require.NoError(t, err) - require.NotNil(t, update, "update is nil") - - require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot, "Signature slot is not equal") - - l.CheckSyncAggregate(update.SyncAggregate) - l.CheckAttestedHeader(update.AttestedHeader) - - //zeroHash := params.BeaconConfig().ZeroHash[:] - finalizedBlockHeader, err := l.FinalizedBlock.Header() - require.NoError(t, err) - require.NotNil(t, update.FinalizedHeader, "Finalized header is nil") - updateFinalizedHeaderBeacon, err := update.FinalizedHeader.GetBeacon() - require.NoError(t, err) - require.Equal(t, finalizedBlockHeader.Header.Slot, updateFinalizedHeaderBeacon.Slot, "Finalized header slot is not equal") - require.Equal(t, finalizedBlockHeader.Header.ProposerIndex, updateFinalizedHeaderBeacon.ProposerIndex, "Finalized header proposer index is not equal") - require.DeepSSZEqual(t, finalizedBlockHeader.Header.ParentRoot, updateFinalizedHeaderBeacon.ParentRoot, "Finalized header parent root is not equal") - require.DeepSSZEqual(t, finalizedBlockHeader.Header.StateRoot, updateFinalizedHeaderBeacon.StateRoot, "Finalized header state root is not equal") - require.DeepSSZEqual(t, finalizedBlockHeader.Header.BodyRoot, updateFinalizedHeaderBeacon.BodyRoot, "Finalized header body root is not equal") - require.Equal(t, lightClient.FinalityBranchNumOfLeaves, len(update.FinalityBranch), "Invalid finality branch leaves") - finalityBranch, err := l.AttestedState.FinalizedRootProof(l.Ctx) - require.NoError(t, err) - for i, leaf := range update.FinalityBranch { - require.DeepSSZEqual(t, finalityBranch[i], leaf, "Leaf is not equal") - } - - // Check Execution BlockHash - payloadInterface, err := l.FinalizedBlock.Block().Body().Execution() - require.NoError(t, err) - transactionsRoot, err := payloadInterface.TransactionsRoot() - if errors.Is(err, consensustypes.ErrUnsupportedField) { - transactions, err := payloadInterface.Transactions() - require.NoError(t, err) - transactionsRootArray, err := ssz.TransactionsRoot(transactions) - require.NoError(t, err) - transactionsRoot = transactionsRootArray[:] - } else { - require.NoError(t, err) - } - withdrawalsRoot, err := payloadInterface.WithdrawalsRoot() - if errors.Is(err, consensustypes.ErrUnsupportedField) { - withdrawals, err := payloadInterface.Withdrawals() - require.NoError(t, err) - withdrawalsRootArray, err := ssz.WithdrawalSliceRoot(withdrawals, fieldparams.MaxWithdrawalsPerPayload) - require.NoError(t, err) - withdrawalsRoot = withdrawalsRootArray[:] - } else { - require.NoError(t, err) - } - execution := &v11.ExecutionPayloadHeaderDeneb{ - ParentHash: payloadInterface.ParentHash(), - FeeRecipient: payloadInterface.FeeRecipient(), - StateRoot: payloadInterface.StateRoot(), - ReceiptsRoot: payloadInterface.ReceiptsRoot(), - LogsBloom: payloadInterface.LogsBloom(), - PrevRandao: payloadInterface.PrevRandao(), - BlockNumber: payloadInterface.BlockNumber(), - GasLimit: payloadInterface.GasLimit(), - GasUsed: payloadInterface.GasUsed(), - Timestamp: payloadInterface.Timestamp(), - ExtraData: payloadInterface.ExtraData(), - BaseFeePerGas: payloadInterface.BaseFeePerGas(), - BlockHash: payloadInterface.BlockHash(), - TransactionsRoot: transactionsRoot, - WithdrawalsRoot: withdrawalsRoot, - } - require.DeepSSZEqual(t, execution, update.FinalizedHeader.GetHeaderDeneb().Execution, "Finalized Block Execution is not equal") - }) - - t.Run("FinalizedBlock In Previous Fork", func(t *testing.T) { - l := util.NewTestLightClient(t).SetupTestDenebFinalizedBlockCapella(false) - - update, err := lightClient.NewLightClientFinalityUpdateFromBeaconState(l.Ctx, l.State, l.Block, l.AttestedState, l.AttestedBlock, l.FinalizedBlock) - require.NoError(t, err) - require.NotNil(t, update, "update is nil") - - require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot, "Signature slot is not equal") - - l.CheckSyncAggregate(update.SyncAggregate) - l.CheckAttestedHeader(update.AttestedHeader) - - finalizedBlockHeader, err := l.FinalizedBlock.Header() - require.NoError(t, err) - require.NotNil(t, update.FinalizedHeader, "Finalized header is nil") - updateFinalizedHeaderBeacon, err := update.FinalizedHeader.GetBeacon() - require.NoError(t, err) - require.Equal(t, finalizedBlockHeader.Header.Slot, updateFinalizedHeaderBeacon.Slot, "Finalized header slot is not equal") - require.Equal(t, finalizedBlockHeader.Header.ProposerIndex, updateFinalizedHeaderBeacon.ProposerIndex, "Finalized header proposer index is not equal") - require.DeepSSZEqual(t, finalizedBlockHeader.Header.ParentRoot, updateFinalizedHeaderBeacon.ParentRoot, "Finalized header parent root is not equal") - require.DeepSSZEqual(t, finalizedBlockHeader.Header.StateRoot, updateFinalizedHeaderBeacon.StateRoot, "Finalized header state root is not equal") - require.DeepSSZEqual(t, finalizedBlockHeader.Header.BodyRoot, updateFinalizedHeaderBeacon.BodyRoot, "Finalized header body root is not equal") - require.Equal(t, lightClient.FinalityBranchNumOfLeaves, len(update.FinalityBranch), "Invalid finality branch leaves") - finalityBranch, err := l.AttestedState.FinalizedRootProof(l.Ctx) - require.NoError(t, err) - for i, leaf := range update.FinalityBranch { - require.DeepSSZEqual(t, finalityBranch[i], leaf, "Leaf is not equal") - } - - // Check Execution BlockHash - payloadInterface, err := l.FinalizedBlock.Block().Body().Execution() - require.NoError(t, err) - transactionsRoot, err := payloadInterface.TransactionsRoot() - if errors.Is(err, consensustypes.ErrUnsupportedField) { - transactions, err := payloadInterface.Transactions() - require.NoError(t, err) - transactionsRootArray, err := ssz.TransactionsRoot(transactions) - require.NoError(t, err) - transactionsRoot = transactionsRootArray[:] - } else { - require.NoError(t, err) - } - withdrawalsRoot, err := payloadInterface.WithdrawalsRoot() - if errors.Is(err, consensustypes.ErrUnsupportedField) { - withdrawals, err := payloadInterface.Withdrawals() - require.NoError(t, err) - withdrawalsRootArray, err := ssz.WithdrawalSliceRoot(withdrawals, fieldparams.MaxWithdrawalsPerPayload) - require.NoError(t, err) - withdrawalsRoot = withdrawalsRootArray[:] - } else { - require.NoError(t, err) - } - execution := &v11.ExecutionPayloadHeaderCapella{ - ParentHash: payloadInterface.ParentHash(), - FeeRecipient: payloadInterface.FeeRecipient(), - StateRoot: payloadInterface.StateRoot(), - ReceiptsRoot: payloadInterface.ReceiptsRoot(), - LogsBloom: payloadInterface.LogsBloom(), - PrevRandao: payloadInterface.PrevRandao(), - BlockNumber: payloadInterface.BlockNumber(), - GasLimit: payloadInterface.GasLimit(), - GasUsed: payloadInterface.GasUsed(), - Timestamp: payloadInterface.Timestamp(), - ExtraData: payloadInterface.ExtraData(), - BaseFeePerGas: payloadInterface.BaseFeePerGas(), - BlockHash: payloadInterface.BlockHash(), - TransactionsRoot: transactionsRoot, - WithdrawalsRoot: withdrawalsRoot, - } - require.DeepSSZEqual(t, execution, update.FinalizedHeader.GetHeaderCapella().Execution, "Finalized Block Execution is not equal") - }) - }) -} - -func TestLightClient_BlockToLightClientHeader(t *testing.T) { - t.Run("Altair", func(t *testing.T) { - l := util.NewTestLightClient(t).SetupTestAltair() - - container, err := lightClient.BlockToLightClientHeader(l.Block) - require.NoError(t, err) - header := container.GetHeaderAltair() - require.NotNil(t, header, "header is nil") - - parentRoot := l.Block.Block().ParentRoot() - stateRoot := l.Block.Block().StateRoot() - bodyRoot, err := l.Block.Block().Body().HashTreeRoot() - require.NoError(t, err) - - require.Equal(t, l.Block.Block().Slot(), header.Beacon.Slot, "Slot is not equal") - require.Equal(t, l.Block.Block().ProposerIndex(), header.Beacon.ProposerIndex, "Proposer index is not equal") - require.DeepSSZEqual(t, parentRoot[:], header.Beacon.ParentRoot, "Parent root is not equal") - require.DeepSSZEqual(t, stateRoot[:], header.Beacon.StateRoot, "State root is not equal") - require.DeepSSZEqual(t, bodyRoot[:], header.Beacon.BodyRoot, "Body root is not equal") - }) - - t.Run("Bellatrix", func(t *testing.T) { - l := util.NewTestLightClient(t).SetupTestBellatrix() - - container, err := lightClient.BlockToLightClientHeader(l.Block) - require.NoError(t, err) - header := container.GetHeaderAltair() - require.NotNil(t, header, "header is nil") - - parentRoot := l.Block.Block().ParentRoot() - stateRoot := l.Block.Block().StateRoot() - bodyRoot, err := l.Block.Block().Body().HashTreeRoot() - require.NoError(t, err) - - require.Equal(t, l.Block.Block().Slot(), header.Beacon.Slot, "Slot is not equal") - require.Equal(t, l.Block.Block().ProposerIndex(), header.Beacon.ProposerIndex, "Proposer index is not equal") - require.DeepSSZEqual(t, parentRoot[:], header.Beacon.ParentRoot, "Parent root is not equal") - require.DeepSSZEqual(t, stateRoot[:], header.Beacon.StateRoot, "State root is not equal") - require.DeepSSZEqual(t, bodyRoot[:], header.Beacon.BodyRoot, "Body root is not equal") - }) - - t.Run("Capella", func(t *testing.T) { - t.Run("Non-Blinded Beacon Block", func(t *testing.T) { - l := util.NewTestLightClient(t).SetupTestCapella(false) - - container, err := lightClient.BlockToLightClientHeader(l.Block) - require.NoError(t, err) - header := container.GetHeaderCapella() - require.NotNil(t, header, "header is nil") - - parentRoot := l.Block.Block().ParentRoot() - stateRoot := l.Block.Block().StateRoot() - bodyRoot, err := l.Block.Block().Body().HashTreeRoot() - require.NoError(t, err) - - payload, err := l.Block.Block().Body().Execution() - require.NoError(t, err) - - transactionsRoot, err := lightClient.ComputeTransactionsRoot(payload) - require.NoError(t, err) - - withdrawalsRoot, err := lightClient.ComputeWithdrawalsRoot(payload) - require.NoError(t, err) - - executionHeader := &v11.ExecutionPayloadHeaderCapella{ - ParentHash: payload.ParentHash(), - FeeRecipient: payload.FeeRecipient(), - StateRoot: payload.StateRoot(), - ReceiptsRoot: payload.ReceiptsRoot(), - LogsBloom: payload.LogsBloom(), - PrevRandao: payload.PrevRandao(), - BlockNumber: payload.BlockNumber(), - GasLimit: payload.GasLimit(), - GasUsed: payload.GasUsed(), - Timestamp: payload.Timestamp(), - ExtraData: payload.ExtraData(), - BaseFeePerGas: payload.BaseFeePerGas(), - BlockHash: payload.BlockHash(), - TransactionsRoot: transactionsRoot, - WithdrawalsRoot: withdrawalsRoot, - } - - executionPayloadProof, err := blocks.PayloadProof(l.Ctx, l.Block.Block()) - require.NoError(t, err) - - require.Equal(t, l.Block.Block().Slot(), header.Beacon.Slot, "Slot is not equal") - require.Equal(t, l.Block.Block().ProposerIndex(), header.Beacon.ProposerIndex, "Proposer index is not equal") - require.DeepSSZEqual(t, parentRoot[:], header.Beacon.ParentRoot, "Parent root is not equal") - require.DeepSSZEqual(t, stateRoot[:], header.Beacon.StateRoot, "State root is not equal") - require.DeepSSZEqual(t, bodyRoot[:], header.Beacon.BodyRoot, "Body root is not equal") - - require.DeepSSZEqual(t, executionHeader, header.Execution, "Execution headers are not equal") - - require.DeepSSZEqual(t, executionPayloadProof, header.ExecutionBranch, "Execution payload proofs are not equal") - }) - - t.Run("Blinded Beacon Block", func(t *testing.T) { - l := util.NewTestLightClient(t).SetupTestCapella(true) - - container, err := lightClient.BlockToLightClientHeader(l.Block) - require.NoError(t, err) - header := container.GetHeaderCapella() - require.NotNil(t, header, "header is nil") - - parentRoot := l.Block.Block().ParentRoot() - stateRoot := l.Block.Block().StateRoot() - bodyRoot, err := l.Block.Block().Body().HashTreeRoot() - require.NoError(t, err) - - payload, err := l.Block.Block().Body().Execution() - require.NoError(t, err) - - transactionsRoot, err := payload.TransactionsRoot() - require.NoError(t, err) - - withdrawalsRoot, err := payload.WithdrawalsRoot() - require.NoError(t, err) - - executionHeader := &v11.ExecutionPayloadHeaderCapella{ - ParentHash: payload.ParentHash(), - FeeRecipient: payload.FeeRecipient(), - StateRoot: payload.StateRoot(), - ReceiptsRoot: payload.ReceiptsRoot(), - LogsBloom: payload.LogsBloom(), - PrevRandao: payload.PrevRandao(), - BlockNumber: payload.BlockNumber(), - GasLimit: payload.GasLimit(), - GasUsed: payload.GasUsed(), - Timestamp: payload.Timestamp(), - ExtraData: payload.ExtraData(), - BaseFeePerGas: payload.BaseFeePerGas(), - BlockHash: payload.BlockHash(), - TransactionsRoot: transactionsRoot, - WithdrawalsRoot: withdrawalsRoot, - } - - executionPayloadProof, err := blocks.PayloadProof(l.Ctx, l.Block.Block()) - require.NoError(t, err) - - require.Equal(t, l.Block.Block().Slot(), header.Beacon.Slot, "Slot is not equal") - require.Equal(t, l.Block.Block().ProposerIndex(), header.Beacon.ProposerIndex, "Proposer index is not equal") - require.DeepSSZEqual(t, parentRoot[:], header.Beacon.ParentRoot, "Parent root is not equal") - require.DeepSSZEqual(t, stateRoot[:], header.Beacon.StateRoot, "State root is not equal") - require.DeepSSZEqual(t, bodyRoot[:], header.Beacon.BodyRoot, "Body root is not equal") - - require.DeepSSZEqual(t, executionHeader, header.Execution, "Execution headers are not equal") - - require.DeepSSZEqual(t, executionPayloadProof, header.ExecutionBranch, "Execution payload proofs are not equal") - }) - }) - - t.Run("Deneb", func(t *testing.T) { - t.Run("Non-Blinded Beacon Block", func(t *testing.T) { - l := util.NewTestLightClient(t).SetupTestDeneb(false) - - container, err := lightClient.BlockToLightClientHeader(l.Block) - require.NoError(t, err) - header := container.GetHeaderDeneb() - require.NotNil(t, header, "header is nil") - - parentRoot := l.Block.Block().ParentRoot() - stateRoot := l.Block.Block().StateRoot() - bodyRoot, err := l.Block.Block().Body().HashTreeRoot() - require.NoError(t, err) - - payload, err := l.Block.Block().Body().Execution() - require.NoError(t, err) - - transactionsRoot, err := lightClient.ComputeTransactionsRoot(payload) - require.NoError(t, err) - - withdrawalsRoot, err := lightClient.ComputeWithdrawalsRoot(payload) - require.NoError(t, err) - - blobGasUsed, err := payload.BlobGasUsed() - require.NoError(t, err) - - excessBlobGas, err := payload.ExcessBlobGas() - require.NoError(t, err) - - executionHeader := &v11.ExecutionPayloadHeaderDeneb{ - ParentHash: payload.ParentHash(), - FeeRecipient: payload.FeeRecipient(), - StateRoot: payload.StateRoot(), - ReceiptsRoot: payload.ReceiptsRoot(), - LogsBloom: payload.LogsBloom(), - PrevRandao: payload.PrevRandao(), - BlockNumber: payload.BlockNumber(), - GasLimit: payload.GasLimit(), - GasUsed: payload.GasUsed(), - Timestamp: payload.Timestamp(), - ExtraData: payload.ExtraData(), - BaseFeePerGas: payload.BaseFeePerGas(), - BlockHash: payload.BlockHash(), - TransactionsRoot: transactionsRoot, - WithdrawalsRoot: withdrawalsRoot, - BlobGasUsed: blobGasUsed, - ExcessBlobGas: excessBlobGas, - } - - executionPayloadProof, err := blocks.PayloadProof(l.Ctx, l.Block.Block()) - require.NoError(t, err) - - require.Equal(t, l.Block.Block().Slot(), header.Beacon.Slot, "Slot is not equal") - require.Equal(t, l.Block.Block().ProposerIndex(), header.Beacon.ProposerIndex, "Proposer index is not equal") - require.DeepSSZEqual(t, parentRoot[:], header.Beacon.ParentRoot, "Parent root is not equal") - require.DeepSSZEqual(t, stateRoot[:], header.Beacon.StateRoot, "State root is not equal") - require.DeepSSZEqual(t, bodyRoot[:], header.Beacon.BodyRoot, "Body root is not equal") - - require.DeepSSZEqual(t, executionHeader, header.Execution, "Execution headers are not equal") - - require.DeepSSZEqual(t, executionPayloadProof, header.ExecutionBranch, "Execution payload proofs are not equal") - }) - - t.Run("Blinded Beacon Block", func(t *testing.T) { - l := util.NewTestLightClient(t).SetupTestDeneb(true) - - container, err := lightClient.BlockToLightClientHeader(l.Block) - require.NoError(t, err) - header := container.GetHeaderDeneb() - require.NotNil(t, header, "header is nil") - - parentRoot := l.Block.Block().ParentRoot() - stateRoot := l.Block.Block().StateRoot() - bodyRoot, err := l.Block.Block().Body().HashTreeRoot() - require.NoError(t, err) - - payload, err := l.Block.Block().Body().Execution() - require.NoError(t, err) - - transactionsRoot, err := payload.TransactionsRoot() - require.NoError(t, err) - - withdrawalsRoot, err := payload.WithdrawalsRoot() - require.NoError(t, err) - - blobGasUsed, err := payload.BlobGasUsed() - require.NoError(t, err) - - excessBlobGas, err := payload.ExcessBlobGas() - require.NoError(t, err) - - executionHeader := &v11.ExecutionPayloadHeaderDeneb{ - ParentHash: payload.ParentHash(), - FeeRecipient: payload.FeeRecipient(), - StateRoot: payload.StateRoot(), - ReceiptsRoot: payload.ReceiptsRoot(), - LogsBloom: payload.LogsBloom(), - PrevRandao: payload.PrevRandao(), - BlockNumber: payload.BlockNumber(), - GasLimit: payload.GasLimit(), - GasUsed: payload.GasUsed(), - Timestamp: payload.Timestamp(), - ExtraData: payload.ExtraData(), - BaseFeePerGas: payload.BaseFeePerGas(), - BlockHash: payload.BlockHash(), - TransactionsRoot: transactionsRoot, - WithdrawalsRoot: withdrawalsRoot, - BlobGasUsed: blobGasUsed, - ExcessBlobGas: excessBlobGas, - } - - executionPayloadProof, err := blocks.PayloadProof(l.Ctx, l.Block.Block()) - require.NoError(t, err) - - require.Equal(t, l.Block.Block().Slot(), header.Beacon.Slot, "Slot is not equal") - require.Equal(t, l.Block.Block().ProposerIndex(), header.Beacon.ProposerIndex, "Proposer index is not equal") - require.DeepSSZEqual(t, parentRoot[:], header.Beacon.ParentRoot, "Parent root is not equal") - require.DeepSSZEqual(t, stateRoot[:], header.Beacon.StateRoot, "State root is not equal") - require.DeepSSZEqual(t, bodyRoot[:], header.Beacon.BodyRoot, "Body root is not equal") - - require.DeepSSZEqual(t, executionHeader, header.Execution, "Execution headers are not equal") - - require.DeepSSZEqual(t, executionPayloadProof, header.ExecutionBranch, "Execution payload proofs are not equal") - }) - }) - - t.Run("Electra", func(t *testing.T) { - t.Run("Non-Blinded Beacon Block", func(t *testing.T) { - l := util.NewTestLightClient(t).SetupTestElectra(false) - - container, err := lightClient.BlockToLightClientHeader(l.Block) - require.NoError(t, err) - header := container.GetHeaderDeneb() - require.NotNil(t, header, "header is nil") - - parentRoot := l.Block.Block().ParentRoot() - stateRoot := l.Block.Block().StateRoot() - bodyRoot, err := l.Block.Block().Body().HashTreeRoot() - require.NoError(t, err) - - payload, err := l.Block.Block().Body().Execution() - require.NoError(t, err) - - transactionsRoot, err := lightClient.ComputeTransactionsRoot(payload) - require.NoError(t, err) - - withdrawalsRoot, err := lightClient.ComputeWithdrawalsRoot(payload) - require.NoError(t, err) - - blobGasUsed, err := payload.BlobGasUsed() - require.NoError(t, err) - - excessBlobGas, err := payload.ExcessBlobGas() - require.NoError(t, err) - - executionHeader := &v11.ExecutionPayloadHeaderElectra{ - ParentHash: payload.ParentHash(), - FeeRecipient: payload.FeeRecipient(), - StateRoot: payload.StateRoot(), - ReceiptsRoot: payload.ReceiptsRoot(), - LogsBloom: payload.LogsBloom(), - PrevRandao: payload.PrevRandao(), - BlockNumber: payload.BlockNumber(), - GasLimit: payload.GasLimit(), - GasUsed: payload.GasUsed(), - Timestamp: payload.Timestamp(), - ExtraData: payload.ExtraData(), - BaseFeePerGas: payload.BaseFeePerGas(), - BlockHash: payload.BlockHash(), - TransactionsRoot: transactionsRoot, - WithdrawalsRoot: withdrawalsRoot, - BlobGasUsed: blobGasUsed, - ExcessBlobGas: excessBlobGas, - } - - executionPayloadProof, err := blocks.PayloadProof(l.Ctx, l.Block.Block()) - require.NoError(t, err) - - require.Equal(t, l.Block.Block().Slot(), header.Beacon.Slot, "Slot is not equal") - require.Equal(t, l.Block.Block().ProposerIndex(), header.Beacon.ProposerIndex, "Proposer index is not equal") - require.DeepSSZEqual(t, parentRoot[:], header.Beacon.ParentRoot, "Parent root is not equal") - require.DeepSSZEqual(t, stateRoot[:], header.Beacon.StateRoot, "State root is not equal") - require.DeepSSZEqual(t, bodyRoot[:], header.Beacon.BodyRoot, "Body root is not equal") - - require.DeepSSZEqual(t, executionHeader, header.Execution, "Execution headers are not equal") - - require.DeepSSZEqual(t, executionPayloadProof, header.ExecutionBranch, "Execution payload proofs are not equal") - }) - - t.Run("Blinded Beacon Block", func(t *testing.T) { - l := util.NewTestLightClient(t).SetupTestElectra(true) - - container, err := lightClient.BlockToLightClientHeader(l.Block) - require.NoError(t, err) - header := container.GetHeaderDeneb() - require.NotNil(t, header, "header is nil") - - parentRoot := l.Block.Block().ParentRoot() - stateRoot := l.Block.Block().StateRoot() - bodyRoot, err := l.Block.Block().Body().HashTreeRoot() - require.NoError(t, err) - - payload, err := l.Block.Block().Body().Execution() - require.NoError(t, err) - - transactionsRoot, err := payload.TransactionsRoot() - require.NoError(t, err) - - withdrawalsRoot, err := payload.WithdrawalsRoot() - require.NoError(t, err) - - blobGasUsed, err := payload.BlobGasUsed() - require.NoError(t, err) - - excessBlobGas, err := payload.ExcessBlobGas() - require.NoError(t, err) - - executionHeader := &v11.ExecutionPayloadHeaderElectra{ - ParentHash: payload.ParentHash(), - FeeRecipient: payload.FeeRecipient(), - StateRoot: payload.StateRoot(), - ReceiptsRoot: payload.ReceiptsRoot(), - LogsBloom: payload.LogsBloom(), - PrevRandao: payload.PrevRandao(), - BlockNumber: payload.BlockNumber(), - GasLimit: payload.GasLimit(), - GasUsed: payload.GasUsed(), - Timestamp: payload.Timestamp(), - ExtraData: payload.ExtraData(), - BaseFeePerGas: payload.BaseFeePerGas(), - BlockHash: payload.BlockHash(), - TransactionsRoot: transactionsRoot, - WithdrawalsRoot: withdrawalsRoot, - BlobGasUsed: blobGasUsed, - ExcessBlobGas: excessBlobGas, - } - - executionPayloadProof, err := blocks.PayloadProof(l.Ctx, l.Block.Block()) - require.NoError(t, err) - - require.Equal(t, l.Block.Block().Slot(), header.Beacon.Slot, "Slot is not equal") - require.Equal(t, l.Block.Block().ProposerIndex(), header.Beacon.ProposerIndex, "Proposer index is not equal") - require.DeepSSZEqual(t, parentRoot[:], header.Beacon.ParentRoot, "Parent root is not equal") - require.DeepSSZEqual(t, stateRoot[:], header.Beacon.StateRoot, "State root is not equal") - require.DeepSSZEqual(t, bodyRoot[:], header.Beacon.BodyRoot, "Body root is not equal") - - require.DeepSSZEqual(t, executionHeader, header.Execution, "Execution headers are not equal") - - require.DeepSSZEqual(t, executionPayloadProof, header.ExecutionBranch, "Execution payload proofs are not equal") - }) - }) -} +//func TestLightClient_NewLightClientFinalityUpdateFromBeaconState(t *testing.T) { +// t.Run("Altair", func(t *testing.T) { +// l := util.NewTestLightClient(t).SetupTestAltair() +// +// t.Run("FinalizedBlock Not Nil", func(t *testing.T) { +// update, err := lightClient.NewLightClientFinalityUpdateFromBeaconState(l.Ctx, l.State, l.Block, l.AttestedState, l.AttestedBlock, l.FinalizedBlock) +// require.NoError(t, err) +// require.NotNil(t, update, "update is nil") +// +// require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot, "Signature slot is not equal") +// +// l.CheckSyncAggregate(update.SyncAggregate) +// l.CheckAttestedHeader(update.AttestedHeader) +// +// finalizedBlockHeader, err := l.FinalizedBlock.Header() +// require.NoError(t, err) +// +// //zeroHash := params.BeaconConfig().ZeroHash[:] +// require.NotNil(t, update.FinalizedHeader, "Finalized header is nil") +// updateFinalizedHeaderBeacon, err := update.FinalizedHeader.GetBeacon() +// require.NoError(t, err) +// require.Equal(t, finalizedBlockHeader.Header.Slot, updateFinalizedHeaderBeacon.Slot, "Finalized header slot is not equal") +// require.Equal(t, finalizedBlockHeader.Header.ProposerIndex, updateFinalizedHeaderBeacon.ProposerIndex, "Finalized header proposer index is not equal") +// require.DeepSSZEqual(t, finalizedBlockHeader.Header.ParentRoot, updateFinalizedHeaderBeacon.ParentRoot, "Finalized header parent root is not equal") +// require.DeepSSZEqual(t, finalizedBlockHeader.Header.StateRoot, updateFinalizedHeaderBeacon.StateRoot, "Finalized header state root is not equal") +// require.DeepSSZEqual(t, finalizedBlockHeader.Header.BodyRoot, updateFinalizedHeaderBeacon.BodyRoot, "Finalized header body root is not equal") +// require.Equal(t, lightClient.FinalityBranchNumOfLeaves, len(update.FinalityBranch), "Invalid finality branch leaves") +// +// finalityBranch, err := l.AttestedState.FinalizedRootProof(l.Ctx) +// require.NoError(t, err) +// for i, leaf := range update.FinalityBranch { +// require.DeepSSZEqual(t, finalityBranch[i], leaf, "Leaf is not equal") +// } +// }) +// }) +// +// t.Run("Capella", func(t *testing.T) { +// +// t.Run("FinalizedBlock Not Nil", func(t *testing.T) { +// l := util.NewTestLightClient(t).SetupTestCapella(false) +// update, err := lightClient.NewLightClientFinalityUpdateFromBeaconState(l.Ctx, l.State, l.Block, l.AttestedState, l.AttestedBlock, l.FinalizedBlock) +// require.NoError(t, err) +// require.NotNil(t, update, "update is nil") +// +// require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot, "Signature slot is not equal") +// +// l.CheckSyncAggregate(update.SyncAggregate) +// l.CheckAttestedHeader(update.AttestedHeader) +// +// finalizedBlockHeader, err := l.FinalizedBlock.Header() +// require.NoError(t, err) +// require.NotNil(t, update.FinalizedHeader, "Finalized header is nil") +// updateFinalizedHeaderBeacon, err := update.FinalizedHeader.GetBeacon() +// require.NoError(t, err) +// require.Equal(t, finalizedBlockHeader.Header.Slot, updateFinalizedHeaderBeacon.Slot, "Finalized header slot is not equal") +// require.Equal(t, finalizedBlockHeader.Header.ProposerIndex, updateFinalizedHeaderBeacon.ProposerIndex, "Finalized header proposer index is not equal") +// require.DeepSSZEqual(t, finalizedBlockHeader.Header.ParentRoot, updateFinalizedHeaderBeacon.ParentRoot, "Finalized header parent root is not equal") +// require.DeepSSZEqual(t, finalizedBlockHeader.Header.StateRoot, updateFinalizedHeaderBeacon.StateRoot, "Finalized header state root is not equal") +// require.DeepSSZEqual(t, finalizedBlockHeader.Header.BodyRoot, updateFinalizedHeaderBeacon.BodyRoot, "Finalized header body root is not equal") +// require.Equal(t, lightClient.FinalityBranchNumOfLeaves, len(update.FinalityBranch), "Invalid finality branch leaves") +// finalityBranch, err := l.AttestedState.FinalizedRootProof(l.Ctx) +// require.NoError(t, err) +// for i, leaf := range update.FinalityBranch { +// require.DeepSSZEqual(t, finalityBranch[i], leaf, "Leaf is not equal") +// } +// +// // Check Execution BlockHash +// payloadInterface, err := l.FinalizedBlock.Block().Body().Execution() +// require.NoError(t, err) +// transactionsRoot, err := payloadInterface.TransactionsRoot() +// if errors.Is(err, consensustypes.ErrUnsupportedField) { +// transactions, err := payloadInterface.Transactions() +// require.NoError(t, err) +// transactionsRootArray, err := ssz.TransactionsRoot(transactions) +// require.NoError(t, err) +// transactionsRoot = transactionsRootArray[:] +// } else { +// require.NoError(t, err) +// } +// withdrawalsRoot, err := payloadInterface.WithdrawalsRoot() +// if errors.Is(err, consensustypes.ErrUnsupportedField) { +// withdrawals, err := payloadInterface.Withdrawals() +// require.NoError(t, err) +// withdrawalsRootArray, err := ssz.WithdrawalSliceRoot(withdrawals, fieldparams.MaxWithdrawalsPerPayload) +// require.NoError(t, err) +// withdrawalsRoot = withdrawalsRootArray[:] +// } else { +// require.NoError(t, err) +// } +// execution := &v11.ExecutionPayloadHeaderCapella{ +// ParentHash: payloadInterface.ParentHash(), +// FeeRecipient: payloadInterface.FeeRecipient(), +// StateRoot: payloadInterface.StateRoot(), +// ReceiptsRoot: payloadInterface.ReceiptsRoot(), +// LogsBloom: payloadInterface.LogsBloom(), +// PrevRandao: payloadInterface.PrevRandao(), +// BlockNumber: payloadInterface.BlockNumber(), +// GasLimit: payloadInterface.GasLimit(), +// GasUsed: payloadInterface.GasUsed(), +// Timestamp: payloadInterface.Timestamp(), +// ExtraData: payloadInterface.ExtraData(), +// BaseFeePerGas: payloadInterface.BaseFeePerGas(), +// BlockHash: payloadInterface.BlockHash(), +// TransactionsRoot: transactionsRoot, +// WithdrawalsRoot: withdrawalsRoot, +// } +// require.DeepSSZEqual(t, execution, update.FinalizedHeader.GetHeaderCapella().Execution, "Finalized Block Execution is not equal") +// }) +// +// t.Run("FinalizedBlock In Previous Fork", func(t *testing.T) { +// l := util.NewTestLightClient(t).SetupTestCapellaFinalizedBlockAltair(false) +// update, err := lightClient.NewLightClientFinalityUpdateFromBeaconState(l.Ctx, l.State, l.Block, l.AttestedState, l.AttestedBlock, l.FinalizedBlock) +// require.NoError(t, err) +// require.NotNil(t, update, "update is nil") +// +// require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot, "Signature slot is not equal") +// +// l.CheckSyncAggregate(update.SyncAggregate) +// l.CheckAttestedHeader(update.AttestedHeader) +// +// finalizedBlockHeader, err := l.FinalizedBlock.Header() +// require.NoError(t, err) +// require.NotNil(t, update.FinalizedHeader, "Finalized header is nil") +// updateFinalizedHeaderBeacon, err := update.FinalizedHeader.GetBeacon() +// require.NoError(t, err) +// require.Equal(t, finalizedBlockHeader.Header.Slot, updateFinalizedHeaderBeacon.Slot, "Finalized header slot is not equal") +// require.Equal(t, finalizedBlockHeader.Header.ProposerIndex, updateFinalizedHeaderBeacon.ProposerIndex, "Finalized header proposer index is not equal") +// require.DeepSSZEqual(t, finalizedBlockHeader.Header.ParentRoot, updateFinalizedHeaderBeacon.ParentRoot, "Finalized header parent root is not equal") +// require.DeepSSZEqual(t, finalizedBlockHeader.Header.StateRoot, updateFinalizedHeaderBeacon.StateRoot, "Finalized header state root is not equal") +// require.DeepSSZEqual(t, finalizedBlockHeader.Header.BodyRoot, updateFinalizedHeaderBeacon.BodyRoot, "Finalized header body root is not equal") +// require.Equal(t, lightClient.FinalityBranchNumOfLeaves, len(update.FinalityBranch), "Invalid finality branch leaves") +// finalityBranch, err := l.AttestedState.FinalizedRootProof(l.Ctx) +// require.NoError(t, err) +// for i, leaf := range update.FinalityBranch { +// require.DeepSSZEqual(t, finalityBranch[i], leaf, "Leaf is not equal") +// } +// }) +// }) +// +// t.Run("Deneb", func(t *testing.T) { +// +// t.Run("FinalizedBlock Not Nil", func(t *testing.T) { +// l := util.NewTestLightClient(t).SetupTestDeneb(false) +// +// update, err := lightClient.NewLightClientFinalityUpdateFromBeaconState(l.Ctx, l.State, l.Block, l.AttestedState, l.AttestedBlock, l.FinalizedBlock) +// require.NoError(t, err) +// require.NotNil(t, update, "update is nil") +// +// require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot, "Signature slot is not equal") +// +// l.CheckSyncAggregate(update.SyncAggregate) +// l.CheckAttestedHeader(update.AttestedHeader) +// +// //zeroHash := params.BeaconConfig().ZeroHash[:] +// finalizedBlockHeader, err := l.FinalizedBlock.Header() +// require.NoError(t, err) +// require.NotNil(t, update.FinalizedHeader, "Finalized header is nil") +// updateFinalizedHeaderBeacon, err := update.FinalizedHeader.GetBeacon() +// require.NoError(t, err) +// require.Equal(t, finalizedBlockHeader.Header.Slot, updateFinalizedHeaderBeacon.Slot, "Finalized header slot is not equal") +// require.Equal(t, finalizedBlockHeader.Header.ProposerIndex, updateFinalizedHeaderBeacon.ProposerIndex, "Finalized header proposer index is not equal") +// require.DeepSSZEqual(t, finalizedBlockHeader.Header.ParentRoot, updateFinalizedHeaderBeacon.ParentRoot, "Finalized header parent root is not equal") +// require.DeepSSZEqual(t, finalizedBlockHeader.Header.StateRoot, updateFinalizedHeaderBeacon.StateRoot, "Finalized header state root is not equal") +// require.DeepSSZEqual(t, finalizedBlockHeader.Header.BodyRoot, updateFinalizedHeaderBeacon.BodyRoot, "Finalized header body root is not equal") +// require.Equal(t, lightClient.FinalityBranchNumOfLeaves, len(update.FinalityBranch), "Invalid finality branch leaves") +// finalityBranch, err := l.AttestedState.FinalizedRootProof(l.Ctx) +// require.NoError(t, err) +// for i, leaf := range update.FinalityBranch { +// require.DeepSSZEqual(t, finalityBranch[i], leaf, "Leaf is not equal") +// } +// +// // Check Execution BlockHash +// payloadInterface, err := l.FinalizedBlock.Block().Body().Execution() +// require.NoError(t, err) +// transactionsRoot, err := payloadInterface.TransactionsRoot() +// if errors.Is(err, consensustypes.ErrUnsupportedField) { +// transactions, err := payloadInterface.Transactions() +// require.NoError(t, err) +// transactionsRootArray, err := ssz.TransactionsRoot(transactions) +// require.NoError(t, err) +// transactionsRoot = transactionsRootArray[:] +// } else { +// require.NoError(t, err) +// } +// withdrawalsRoot, err := payloadInterface.WithdrawalsRoot() +// if errors.Is(err, consensustypes.ErrUnsupportedField) { +// withdrawals, err := payloadInterface.Withdrawals() +// require.NoError(t, err) +// withdrawalsRootArray, err := ssz.WithdrawalSliceRoot(withdrawals, fieldparams.MaxWithdrawalsPerPayload) +// require.NoError(t, err) +// withdrawalsRoot = withdrawalsRootArray[:] +// } else { +// require.NoError(t, err) +// } +// execution := &v11.ExecutionPayloadHeaderDeneb{ +// ParentHash: payloadInterface.ParentHash(), +// FeeRecipient: payloadInterface.FeeRecipient(), +// StateRoot: payloadInterface.StateRoot(), +// ReceiptsRoot: payloadInterface.ReceiptsRoot(), +// LogsBloom: payloadInterface.LogsBloom(), +// PrevRandao: payloadInterface.PrevRandao(), +// BlockNumber: payloadInterface.BlockNumber(), +// GasLimit: payloadInterface.GasLimit(), +// GasUsed: payloadInterface.GasUsed(), +// Timestamp: payloadInterface.Timestamp(), +// ExtraData: payloadInterface.ExtraData(), +// BaseFeePerGas: payloadInterface.BaseFeePerGas(), +// BlockHash: payloadInterface.BlockHash(), +// TransactionsRoot: transactionsRoot, +// WithdrawalsRoot: withdrawalsRoot, +// } +// require.DeepSSZEqual(t, execution, update.FinalizedHeader.GetHeaderDeneb().Execution, "Finalized Block Execution is not equal") +// }) +// +// t.Run("FinalizedBlock In Previous Fork", func(t *testing.T) { +// l := util.NewTestLightClient(t).SetupTestDenebFinalizedBlockCapella(false) +// +// update, err := lightClient.NewLightClientFinalityUpdateFromBeaconState(l.Ctx, l.State, l.Block, l.AttestedState, l.AttestedBlock, l.FinalizedBlock) +// require.NoError(t, err) +// require.NotNil(t, update, "update is nil") +// +// require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot, "Signature slot is not equal") +// +// l.CheckSyncAggregate(update.SyncAggregate) +// l.CheckAttestedHeader(update.AttestedHeader) +// +// finalizedBlockHeader, err := l.FinalizedBlock.Header() +// require.NoError(t, err) +// require.NotNil(t, update.FinalizedHeader, "Finalized header is nil") +// updateFinalizedHeaderBeacon, err := update.FinalizedHeader.GetBeacon() +// require.NoError(t, err) +// require.Equal(t, finalizedBlockHeader.Header.Slot, updateFinalizedHeaderBeacon.Slot, "Finalized header slot is not equal") +// require.Equal(t, finalizedBlockHeader.Header.ProposerIndex, updateFinalizedHeaderBeacon.ProposerIndex, "Finalized header proposer index is not equal") +// require.DeepSSZEqual(t, finalizedBlockHeader.Header.ParentRoot, updateFinalizedHeaderBeacon.ParentRoot, "Finalized header parent root is not equal") +// require.DeepSSZEqual(t, finalizedBlockHeader.Header.StateRoot, updateFinalizedHeaderBeacon.StateRoot, "Finalized header state root is not equal") +// require.DeepSSZEqual(t, finalizedBlockHeader.Header.BodyRoot, updateFinalizedHeaderBeacon.BodyRoot, "Finalized header body root is not equal") +// require.Equal(t, lightClient.FinalityBranchNumOfLeaves, len(update.FinalityBranch), "Invalid finality branch leaves") +// finalityBranch, err := l.AttestedState.FinalizedRootProof(l.Ctx) +// require.NoError(t, err) +// for i, leaf := range update.FinalityBranch { +// require.DeepSSZEqual(t, finalityBranch[i], leaf, "Leaf is not equal") +// } +// +// // Check Execution BlockHash +// payloadInterface, err := l.FinalizedBlock.Block().Body().Execution() +// require.NoError(t, err) +// transactionsRoot, err := payloadInterface.TransactionsRoot() +// if errors.Is(err, consensustypes.ErrUnsupportedField) { +// transactions, err := payloadInterface.Transactions() +// require.NoError(t, err) +// transactionsRootArray, err := ssz.TransactionsRoot(transactions) +// require.NoError(t, err) +// transactionsRoot = transactionsRootArray[:] +// } else { +// require.NoError(t, err) +// } +// withdrawalsRoot, err := payloadInterface.WithdrawalsRoot() +// if errors.Is(err, consensustypes.ErrUnsupportedField) { +// withdrawals, err := payloadInterface.Withdrawals() +// require.NoError(t, err) +// withdrawalsRootArray, err := ssz.WithdrawalSliceRoot(withdrawals, fieldparams.MaxWithdrawalsPerPayload) +// require.NoError(t, err) +// withdrawalsRoot = withdrawalsRootArray[:] +// } else { +// require.NoError(t, err) +// } +// execution := &v11.ExecutionPayloadHeaderCapella{ +// ParentHash: payloadInterface.ParentHash(), +// FeeRecipient: payloadInterface.FeeRecipient(), +// StateRoot: payloadInterface.StateRoot(), +// ReceiptsRoot: payloadInterface.ReceiptsRoot(), +// LogsBloom: payloadInterface.LogsBloom(), +// PrevRandao: payloadInterface.PrevRandao(), +// BlockNumber: payloadInterface.BlockNumber(), +// GasLimit: payloadInterface.GasLimit(), +// GasUsed: payloadInterface.GasUsed(), +// Timestamp: payloadInterface.Timestamp(), +// ExtraData: payloadInterface.ExtraData(), +// BaseFeePerGas: payloadInterface.BaseFeePerGas(), +// BlockHash: payloadInterface.BlockHash(), +// TransactionsRoot: transactionsRoot, +// WithdrawalsRoot: withdrawalsRoot, +// } +// require.DeepSSZEqual(t, execution, update.FinalizedHeader.GetHeaderCapella().Execution, "Finalized Block Execution is not equal") +// }) +// }) +//} +// +//func TestLightClient_BlockToLightClientHeader(t *testing.T) { +// t.Run("Altair", func(t *testing.T) { +// l := util.NewTestLightClient(t).SetupTestAltair() +// +// container, err := lightClient.BlockToLightClientHeader(l.Block) +// require.NoError(t, err) +// header := container.GetHeaderAltair() +// require.NotNil(t, header, "header is nil") +// +// parentRoot := l.Block.Block().ParentRoot() +// stateRoot := l.Block.Block().StateRoot() +// bodyRoot, err := l.Block.Block().Body().HashTreeRoot() +// require.NoError(t, err) +// +// require.Equal(t, l.Block.Block().Slot(), header.Beacon.Slot, "Slot is not equal") +// require.Equal(t, l.Block.Block().ProposerIndex(), header.Beacon.ProposerIndex, "Proposer index is not equal") +// require.DeepSSZEqual(t, parentRoot[:], header.Beacon.ParentRoot, "Parent root is not equal") +// require.DeepSSZEqual(t, stateRoot[:], header.Beacon.StateRoot, "State root is not equal") +// require.DeepSSZEqual(t, bodyRoot[:], header.Beacon.BodyRoot, "Body root is not equal") +// }) +// +// t.Run("Bellatrix", func(t *testing.T) { +// l := util.NewTestLightClient(t).SetupTestBellatrix() +// +// container, err := lightClient.BlockToLightClientHeader(l.Block) +// require.NoError(t, err) +// header := container.GetHeaderAltair() +// require.NotNil(t, header, "header is nil") +// +// parentRoot := l.Block.Block().ParentRoot() +// stateRoot := l.Block.Block().StateRoot() +// bodyRoot, err := l.Block.Block().Body().HashTreeRoot() +// require.NoError(t, err) +// +// require.Equal(t, l.Block.Block().Slot(), header.Beacon.Slot, "Slot is not equal") +// require.Equal(t, l.Block.Block().ProposerIndex(), header.Beacon.ProposerIndex, "Proposer index is not equal") +// require.DeepSSZEqual(t, parentRoot[:], header.Beacon.ParentRoot, "Parent root is not equal") +// require.DeepSSZEqual(t, stateRoot[:], header.Beacon.StateRoot, "State root is not equal") +// require.DeepSSZEqual(t, bodyRoot[:], header.Beacon.BodyRoot, "Body root is not equal") +// }) +// +// t.Run("Capella", func(t *testing.T) { +// t.Run("Non-Blinded Beacon Block", func(t *testing.T) { +// l := util.NewTestLightClient(t).SetupTestCapella(false) +// +// container, err := lightClient.BlockToLightClientHeader(l.Block) +// require.NoError(t, err) +// header := container.GetHeaderCapella() +// require.NotNil(t, header, "header is nil") +// +// parentRoot := l.Block.Block().ParentRoot() +// stateRoot := l.Block.Block().StateRoot() +// bodyRoot, err := l.Block.Block().Body().HashTreeRoot() +// require.NoError(t, err) +// +// payload, err := l.Block.Block().Body().Execution() +// require.NoError(t, err) +// +// transactionsRoot, err := lightClient.ComputeTransactionsRoot(payload) +// require.NoError(t, err) +// +// withdrawalsRoot, err := lightClient.ComputeWithdrawalsRoot(payload) +// require.NoError(t, err) +// +// executionHeader := &v11.ExecutionPayloadHeaderCapella{ +// ParentHash: payload.ParentHash(), +// FeeRecipient: payload.FeeRecipient(), +// StateRoot: payload.StateRoot(), +// ReceiptsRoot: payload.ReceiptsRoot(), +// LogsBloom: payload.LogsBloom(), +// PrevRandao: payload.PrevRandao(), +// BlockNumber: payload.BlockNumber(), +// GasLimit: payload.GasLimit(), +// GasUsed: payload.GasUsed(), +// Timestamp: payload.Timestamp(), +// ExtraData: payload.ExtraData(), +// BaseFeePerGas: payload.BaseFeePerGas(), +// BlockHash: payload.BlockHash(), +// TransactionsRoot: transactionsRoot, +// WithdrawalsRoot: withdrawalsRoot, +// } +// +// executionPayloadProof, err := blocks.PayloadProof(l.Ctx, l.Block.Block()) +// require.NoError(t, err) +// +// require.Equal(t, l.Block.Block().Slot(), header.Beacon.Slot, "Slot is not equal") +// require.Equal(t, l.Block.Block().ProposerIndex(), header.Beacon.ProposerIndex, "Proposer index is not equal") +// require.DeepSSZEqual(t, parentRoot[:], header.Beacon.ParentRoot, "Parent root is not equal") +// require.DeepSSZEqual(t, stateRoot[:], header.Beacon.StateRoot, "State root is not equal") +// require.DeepSSZEqual(t, bodyRoot[:], header.Beacon.BodyRoot, "Body root is not equal") +// +// require.DeepSSZEqual(t, executionHeader, header.Execution, "Execution headers are not equal") +// +// require.DeepSSZEqual(t, executionPayloadProof, header.ExecutionBranch, "Execution payload proofs are not equal") +// }) +// +// t.Run("Blinded Beacon Block", func(t *testing.T) { +// l := util.NewTestLightClient(t).SetupTestCapella(true) +// +// container, err := lightClient.BlockToLightClientHeader(l.Block) +// require.NoError(t, err) +// header := container.GetHeaderCapella() +// require.NotNil(t, header, "header is nil") +// +// parentRoot := l.Block.Block().ParentRoot() +// stateRoot := l.Block.Block().StateRoot() +// bodyRoot, err := l.Block.Block().Body().HashTreeRoot() +// require.NoError(t, err) +// +// payload, err := l.Block.Block().Body().Execution() +// require.NoError(t, err) +// +// transactionsRoot, err := payload.TransactionsRoot() +// require.NoError(t, err) +// +// withdrawalsRoot, err := payload.WithdrawalsRoot() +// require.NoError(t, err) +// +// executionHeader := &v11.ExecutionPayloadHeaderCapella{ +// ParentHash: payload.ParentHash(), +// FeeRecipient: payload.FeeRecipient(), +// StateRoot: payload.StateRoot(), +// ReceiptsRoot: payload.ReceiptsRoot(), +// LogsBloom: payload.LogsBloom(), +// PrevRandao: payload.PrevRandao(), +// BlockNumber: payload.BlockNumber(), +// GasLimit: payload.GasLimit(), +// GasUsed: payload.GasUsed(), +// Timestamp: payload.Timestamp(), +// ExtraData: payload.ExtraData(), +// BaseFeePerGas: payload.BaseFeePerGas(), +// BlockHash: payload.BlockHash(), +// TransactionsRoot: transactionsRoot, +// WithdrawalsRoot: withdrawalsRoot, +// } +// +// executionPayloadProof, err := blocks.PayloadProof(l.Ctx, l.Block.Block()) +// require.NoError(t, err) +// +// require.Equal(t, l.Block.Block().Slot(), header.Beacon.Slot, "Slot is not equal") +// require.Equal(t, l.Block.Block().ProposerIndex(), header.Beacon.ProposerIndex, "Proposer index is not equal") +// require.DeepSSZEqual(t, parentRoot[:], header.Beacon.ParentRoot, "Parent root is not equal") +// require.DeepSSZEqual(t, stateRoot[:], header.Beacon.StateRoot, "State root is not equal") +// require.DeepSSZEqual(t, bodyRoot[:], header.Beacon.BodyRoot, "Body root is not equal") +// +// require.DeepSSZEqual(t, executionHeader, header.Execution, "Execution headers are not equal") +// +// require.DeepSSZEqual(t, executionPayloadProof, header.ExecutionBranch, "Execution payload proofs are not equal") +// }) +// }) +// +// t.Run("Deneb", func(t *testing.T) { +// t.Run("Non-Blinded Beacon Block", func(t *testing.T) { +// l := util.NewTestLightClient(t).SetupTestDeneb(false) +// +// container, err := lightClient.BlockToLightClientHeader(l.Block) +// require.NoError(t, err) +// header := container.GetHeaderDeneb() +// require.NotNil(t, header, "header is nil") +// +// parentRoot := l.Block.Block().ParentRoot() +// stateRoot := l.Block.Block().StateRoot() +// bodyRoot, err := l.Block.Block().Body().HashTreeRoot() +// require.NoError(t, err) +// +// payload, err := l.Block.Block().Body().Execution() +// require.NoError(t, err) +// +// transactionsRoot, err := lightClient.ComputeTransactionsRoot(payload) +// require.NoError(t, err) +// +// withdrawalsRoot, err := lightClient.ComputeWithdrawalsRoot(payload) +// require.NoError(t, err) +// +// blobGasUsed, err := payload.BlobGasUsed() +// require.NoError(t, err) +// +// excessBlobGas, err := payload.ExcessBlobGas() +// require.NoError(t, err) +// +// executionHeader := &v11.ExecutionPayloadHeaderDeneb{ +// ParentHash: payload.ParentHash(), +// FeeRecipient: payload.FeeRecipient(), +// StateRoot: payload.StateRoot(), +// ReceiptsRoot: payload.ReceiptsRoot(), +// LogsBloom: payload.LogsBloom(), +// PrevRandao: payload.PrevRandao(), +// BlockNumber: payload.BlockNumber(), +// GasLimit: payload.GasLimit(), +// GasUsed: payload.GasUsed(), +// Timestamp: payload.Timestamp(), +// ExtraData: payload.ExtraData(), +// BaseFeePerGas: payload.BaseFeePerGas(), +// BlockHash: payload.BlockHash(), +// TransactionsRoot: transactionsRoot, +// WithdrawalsRoot: withdrawalsRoot, +// BlobGasUsed: blobGasUsed, +// ExcessBlobGas: excessBlobGas, +// } +// +// executionPayloadProof, err := blocks.PayloadProof(l.Ctx, l.Block.Block()) +// require.NoError(t, err) +// +// require.Equal(t, l.Block.Block().Slot(), header.Beacon.Slot, "Slot is not equal") +// require.Equal(t, l.Block.Block().ProposerIndex(), header.Beacon.ProposerIndex, "Proposer index is not equal") +// require.DeepSSZEqual(t, parentRoot[:], header.Beacon.ParentRoot, "Parent root is not equal") +// require.DeepSSZEqual(t, stateRoot[:], header.Beacon.StateRoot, "State root is not equal") +// require.DeepSSZEqual(t, bodyRoot[:], header.Beacon.BodyRoot, "Body root is not equal") +// +// require.DeepSSZEqual(t, executionHeader, header.Execution, "Execution headers are not equal") +// +// require.DeepSSZEqual(t, executionPayloadProof, header.ExecutionBranch, "Execution payload proofs are not equal") +// }) +// +// t.Run("Blinded Beacon Block", func(t *testing.T) { +// l := util.NewTestLightClient(t).SetupTestDeneb(true) +// +// container, err := lightClient.BlockToLightClientHeader(l.Block) +// require.NoError(t, err) +// header := container.GetHeaderDeneb() +// require.NotNil(t, header, "header is nil") +// +// parentRoot := l.Block.Block().ParentRoot() +// stateRoot := l.Block.Block().StateRoot() +// bodyRoot, err := l.Block.Block().Body().HashTreeRoot() +// require.NoError(t, err) +// +// payload, err := l.Block.Block().Body().Execution() +// require.NoError(t, err) +// +// transactionsRoot, err := payload.TransactionsRoot() +// require.NoError(t, err) +// +// withdrawalsRoot, err := payload.WithdrawalsRoot() +// require.NoError(t, err) +// +// blobGasUsed, err := payload.BlobGasUsed() +// require.NoError(t, err) +// +// excessBlobGas, err := payload.ExcessBlobGas() +// require.NoError(t, err) +// +// executionHeader := &v11.ExecutionPayloadHeaderDeneb{ +// ParentHash: payload.ParentHash(), +// FeeRecipient: payload.FeeRecipient(), +// StateRoot: payload.StateRoot(), +// ReceiptsRoot: payload.ReceiptsRoot(), +// LogsBloom: payload.LogsBloom(), +// PrevRandao: payload.PrevRandao(), +// BlockNumber: payload.BlockNumber(), +// GasLimit: payload.GasLimit(), +// GasUsed: payload.GasUsed(), +// Timestamp: payload.Timestamp(), +// ExtraData: payload.ExtraData(), +// BaseFeePerGas: payload.BaseFeePerGas(), +// BlockHash: payload.BlockHash(), +// TransactionsRoot: transactionsRoot, +// WithdrawalsRoot: withdrawalsRoot, +// BlobGasUsed: blobGasUsed, +// ExcessBlobGas: excessBlobGas, +// } +// +// executionPayloadProof, err := blocks.PayloadProof(l.Ctx, l.Block.Block()) +// require.NoError(t, err) +// +// require.Equal(t, l.Block.Block().Slot(), header.Beacon.Slot, "Slot is not equal") +// require.Equal(t, l.Block.Block().ProposerIndex(), header.Beacon.ProposerIndex, "Proposer index is not equal") +// require.DeepSSZEqual(t, parentRoot[:], header.Beacon.ParentRoot, "Parent root is not equal") +// require.DeepSSZEqual(t, stateRoot[:], header.Beacon.StateRoot, "State root is not equal") +// require.DeepSSZEqual(t, bodyRoot[:], header.Beacon.BodyRoot, "Body root is not equal") +// +// require.DeepSSZEqual(t, executionHeader, header.Execution, "Execution headers are not equal") +// +// require.DeepSSZEqual(t, executionPayloadProof, header.ExecutionBranch, "Execution payload proofs are not equal") +// }) +// }) +// +// t.Run("Electra", func(t *testing.T) { +// t.Run("Non-Blinded Beacon Block", func(t *testing.T) { +// l := util.NewTestLightClient(t).SetupTestElectra(false) +// +// container, err := lightClient.BlockToLightClientHeader(l.Block) +// require.NoError(t, err) +// header := container.GetHeaderDeneb() +// require.NotNil(t, header, "header is nil") +// +// parentRoot := l.Block.Block().ParentRoot() +// stateRoot := l.Block.Block().StateRoot() +// bodyRoot, err := l.Block.Block().Body().HashTreeRoot() +// require.NoError(t, err) +// +// payload, err := l.Block.Block().Body().Execution() +// require.NoError(t, err) +// +// transactionsRoot, err := lightClient.ComputeTransactionsRoot(payload) +// require.NoError(t, err) +// +// withdrawalsRoot, err := lightClient.ComputeWithdrawalsRoot(payload) +// require.NoError(t, err) +// +// blobGasUsed, err := payload.BlobGasUsed() +// require.NoError(t, err) +// +// excessBlobGas, err := payload.ExcessBlobGas() +// require.NoError(t, err) +// +// executionHeader := &v11.ExecutionPayloadHeaderElectra{ +// ParentHash: payload.ParentHash(), +// FeeRecipient: payload.FeeRecipient(), +// StateRoot: payload.StateRoot(), +// ReceiptsRoot: payload.ReceiptsRoot(), +// LogsBloom: payload.LogsBloom(), +// PrevRandao: payload.PrevRandao(), +// BlockNumber: payload.BlockNumber(), +// GasLimit: payload.GasLimit(), +// GasUsed: payload.GasUsed(), +// Timestamp: payload.Timestamp(), +// ExtraData: payload.ExtraData(), +// BaseFeePerGas: payload.BaseFeePerGas(), +// BlockHash: payload.BlockHash(), +// TransactionsRoot: transactionsRoot, +// WithdrawalsRoot: withdrawalsRoot, +// BlobGasUsed: blobGasUsed, +// ExcessBlobGas: excessBlobGas, +// } +// +// executionPayloadProof, err := blocks.PayloadProof(l.Ctx, l.Block.Block()) +// require.NoError(t, err) +// +// require.Equal(t, l.Block.Block().Slot(), header.Beacon.Slot, "Slot is not equal") +// require.Equal(t, l.Block.Block().ProposerIndex(), header.Beacon.ProposerIndex, "Proposer index is not equal") +// require.DeepSSZEqual(t, parentRoot[:], header.Beacon.ParentRoot, "Parent root is not equal") +// require.DeepSSZEqual(t, stateRoot[:], header.Beacon.StateRoot, "State root is not equal") +// require.DeepSSZEqual(t, bodyRoot[:], header.Beacon.BodyRoot, "Body root is not equal") +// +// require.DeepSSZEqual(t, executionHeader, header.Execution, "Execution headers are not equal") +// +// require.DeepSSZEqual(t, executionPayloadProof, header.ExecutionBranch, "Execution payload proofs are not equal") +// }) +// +// t.Run("Blinded Beacon Block", func(t *testing.T) { +// l := util.NewTestLightClient(t).SetupTestElectra(true) +// +// container, err := lightClient.BlockToLightClientHeader(l.Block) +// require.NoError(t, err) +// header := container.GetHeaderDeneb() +// require.NotNil(t, header, "header is nil") +// +// parentRoot := l.Block.Block().ParentRoot() +// stateRoot := l.Block.Block().StateRoot() +// bodyRoot, err := l.Block.Block().Body().HashTreeRoot() +// require.NoError(t, err) +// +// payload, err := l.Block.Block().Body().Execution() +// require.NoError(t, err) +// +// transactionsRoot, err := payload.TransactionsRoot() +// require.NoError(t, err) +// +// withdrawalsRoot, err := payload.WithdrawalsRoot() +// require.NoError(t, err) +// +// blobGasUsed, err := payload.BlobGasUsed() +// require.NoError(t, err) +// +// excessBlobGas, err := payload.ExcessBlobGas() +// require.NoError(t, err) +// +// executionHeader := &v11.ExecutionPayloadHeaderElectra{ +// ParentHash: payload.ParentHash(), +// FeeRecipient: payload.FeeRecipient(), +// StateRoot: payload.StateRoot(), +// ReceiptsRoot: payload.ReceiptsRoot(), +// LogsBloom: payload.LogsBloom(), +// PrevRandao: payload.PrevRandao(), +// BlockNumber: payload.BlockNumber(), +// GasLimit: payload.GasLimit(), +// GasUsed: payload.GasUsed(), +// Timestamp: payload.Timestamp(), +// ExtraData: payload.ExtraData(), +// BaseFeePerGas: payload.BaseFeePerGas(), +// BlockHash: payload.BlockHash(), +// TransactionsRoot: transactionsRoot, +// WithdrawalsRoot: withdrawalsRoot, +// BlobGasUsed: blobGasUsed, +// ExcessBlobGas: excessBlobGas, +// } +// +// executionPayloadProof, err := blocks.PayloadProof(l.Ctx, l.Block.Block()) +// require.NoError(t, err) +// +// require.Equal(t, l.Block.Block().Slot(), header.Beacon.Slot, "Slot is not equal") +// require.Equal(t, l.Block.Block().ProposerIndex(), header.Beacon.ProposerIndex, "Proposer index is not equal") +// require.DeepSSZEqual(t, parentRoot[:], header.Beacon.ParentRoot, "Parent root is not equal") +// require.DeepSSZEqual(t, stateRoot[:], header.Beacon.StateRoot, "State root is not equal") +// require.DeepSSZEqual(t, bodyRoot[:], header.Beacon.BodyRoot, "Body root is not equal") +// +// require.DeepSSZEqual(t, executionHeader, header.Execution, "Execution headers are not equal") +// +// require.DeepSSZEqual(t, executionPayloadProof, header.ExecutionBranch, "Execution payload proofs are not equal") +// }) +// }) +//} diff --git a/beacon-chain/rpc/eth/light-client/BUILD.bazel b/beacon-chain/rpc/eth/light-client/BUILD.bazel index aa2e58d7c30b..b3a32ba5095e 100644 --- a/beacon-chain/rpc/eth/light-client/BUILD.bazel +++ b/beacon-chain/rpc/eth/light-client/BUILD.bazel @@ -21,6 +21,7 @@ go_library( "//config/fieldparams:go_default_library", "//config/params:go_default_library", "//consensus-types/interfaces:go_default_library", + "//consensus-types/primitives:go_default_library", "//monitoring/tracing/trace:go_default_library", "//network/httputil:go_default_library", "//runtime/version:go_default_library", @@ -39,26 +40,12 @@ go_test( ], embed = [":go_default_library"], deps = [ - "//api/server/structs:go_default_library", - "//beacon-chain/blockchain/testing:go_default_library", - "//beacon-chain/core/helpers:go_default_library", "//beacon-chain/core/light-client:go_default_library", - "//beacon-chain/db/kv:go_default_library", - "//beacon-chain/rpc/testutil:go_default_library", - "//beacon-chain/state:go_default_library", "//config/fieldparams:go_default_library", "//config/params:go_default_library", - "//consensus-types/blocks:go_default_library", - "//consensus-types/interfaces:go_default_library", + "//consensus-types/light-client:go_default_library", "//consensus-types/primitives:go_default_library", - "//proto/engine/v1:go_default_library", - "//proto/eth/v1:go_default_library", - "//proto/eth/v2:go_default_library", "//proto/prysm/v1alpha1:go_default_library", - "//runtime/version:go_default_library", "//testing/assert:go_default_library", - "//testing/require:go_default_library", - "//testing/util:go_default_library", - "@com_github_ethereum_go_ethereum//common/hexutil:go_default_library", ], ) diff --git a/beacon-chain/rpc/eth/light-client/handlers_test.go b/beacon-chain/rpc/eth/light-client/handlers_test.go index 6e2e82223079..398676e206db 100644 --- a/beacon-chain/rpc/eth/light-client/handlers_test.go +++ b/beacon-chain/rpc/eth/light-client/handlers_test.go @@ -1,2472 +1,2473 @@ package lightclient -import ( - "bytes" - "context" - "encoding/json" - "fmt" - "net/http" - "net/http/httptest" - "strconv" - "testing" - - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/prysmaticlabs/prysm/v5/api/server/structs" - mock "github.com/prysmaticlabs/prysm/v5/beacon-chain/blockchain/testing" - "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/helpers" - "github.com/prysmaticlabs/prysm/v5/beacon-chain/db/kv" - "github.com/prysmaticlabs/prysm/v5/beacon-chain/rpc/testutil" - "github.com/prysmaticlabs/prysm/v5/beacon-chain/state" - "github.com/prysmaticlabs/prysm/v5/config/params" - "github.com/prysmaticlabs/prysm/v5/consensus-types/blocks" - "github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces" - "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" - enginev1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1" - ethpbv1 "github.com/prysmaticlabs/prysm/v5/proto/eth/v1" - ethpbv2 "github.com/prysmaticlabs/prysm/v5/proto/eth/v2" - ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" - "github.com/prysmaticlabs/prysm/v5/runtime/version" - "github.com/prysmaticlabs/prysm/v5/testing/require" - "github.com/prysmaticlabs/prysm/v5/testing/util" -) - -func TestLightClientHandler_GetLightClientBootstrap_Altair(t *testing.T) { - l := util.NewTestLightClient(t).SetupTestAltair() - - slot := l.State.Slot() - stateRoot, err := l.State.HashTreeRoot(l.Ctx) - require.NoError(t, err) - - mockBlocker := &testutil.MockBlocker{BlockToReturn: l.Block} - mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot} - s := &Server{ - Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ - slot: l.State, - }}, - Blocker: mockBlocker, - HeadFetcher: mockChainService, - } - request := httptest.NewRequest("GET", "http://foo.com/", nil) - request.SetPathValue("block_root", hexutil.Encode(stateRoot[:])) - writer := httptest.NewRecorder() - writer.Body = &bytes.Buffer{} - - s.GetLightClientBootstrap(writer, request) - require.Equal(t, http.StatusOK, writer.Code) - var resp structs.LightClientBootstrapResponse - err = json.Unmarshal(writer.Body.Bytes(), &resp) - require.NoError(t, err) - var respHeader structs.LightClientHeader - err = json.Unmarshal(resp.Data.Header, &respHeader) - require.NoError(t, err) - require.Equal(t, "altair", resp.Version) - - blockHeader, err := l.Block.Header() - require.NoError(t, err) - require.Equal(t, hexutil.Encode(blockHeader.Header.BodyRoot), respHeader.Beacon.BodyRoot) - require.Equal(t, strconv.FormatUint(uint64(blockHeader.Header.Slot), 10), respHeader.Beacon.Slot) - - require.NotNil(t, resp.Data.CurrentSyncCommittee) - require.NotNil(t, resp.Data.CurrentSyncCommitteeBranch) -} - -func TestLightClientHandler_GetLightClientBootstrap_Bellatrix(t *testing.T) { - l := util.NewTestLightClient(t).SetupTestBellatrix() - - slot := l.State.Slot() - stateRoot, err := l.State.HashTreeRoot(l.Ctx) - require.NoError(t, err) - - mockBlocker := &testutil.MockBlocker{BlockToReturn: l.Block} - mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot} - s := &Server{ - Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ - slot: l.State, - }}, - Blocker: mockBlocker, - HeadFetcher: mockChainService, - } - request := httptest.NewRequest("GET", "http://foo.com/", nil) - request.SetPathValue("block_root", hexutil.Encode(stateRoot[:])) - writer := httptest.NewRecorder() - writer.Body = &bytes.Buffer{} - - s.GetLightClientBootstrap(writer, request) - require.Equal(t, http.StatusOK, writer.Code) - var resp structs.LightClientBootstrapResponse - err = json.Unmarshal(writer.Body.Bytes(), &resp) - require.NoError(t, err) - var respHeader structs.LightClientHeader - err = json.Unmarshal(resp.Data.Header, &respHeader) - require.NoError(t, err) - require.Equal(t, "bellatrix", resp.Version) - - blockHeader, err := l.Block.Header() - require.NoError(t, err) - require.Equal(t, hexutil.Encode(blockHeader.Header.BodyRoot), respHeader.Beacon.BodyRoot) - require.Equal(t, strconv.FormatUint(uint64(blockHeader.Header.Slot), 10), respHeader.Beacon.Slot) - - require.NotNil(t, resp.Data.CurrentSyncCommittee) - require.NotNil(t, resp.Data.CurrentSyncCommitteeBranch) -} - -func TestLightClientHandler_GetLightClientBootstrap_Capella(t *testing.T) { - l := util.NewTestLightClient(t).SetupTestCapella(false) // result is same for true and false - - slot := l.State.Slot() - stateRoot, err := l.State.HashTreeRoot(l.Ctx) - require.NoError(t, err) - - mockBlocker := &testutil.MockBlocker{BlockToReturn: l.Block} - mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot} - s := &Server{ - Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ - slot: l.State, - }}, - Blocker: mockBlocker, - HeadFetcher: mockChainService, - } - request := httptest.NewRequest("GET", "http://foo.com/", nil) - request.SetPathValue("block_root", hexutil.Encode(stateRoot[:])) - writer := httptest.NewRecorder() - writer.Body = &bytes.Buffer{} - - s.GetLightClientBootstrap(writer, request) - require.Equal(t, http.StatusOK, writer.Code) - var resp structs.LightClientBootstrapResponse - err = json.Unmarshal(writer.Body.Bytes(), &resp) - require.NoError(t, err) - var respHeader structs.LightClientHeader - err = json.Unmarshal(resp.Data.Header, &respHeader) - require.NoError(t, err) - require.Equal(t, "capella", resp.Version) - - blockHeader, err := l.Block.Header() - require.NoError(t, err) - require.Equal(t, hexutil.Encode(blockHeader.Header.BodyRoot), respHeader.Beacon.BodyRoot) - require.Equal(t, strconv.FormatUint(uint64(blockHeader.Header.Slot), 10), respHeader.Beacon.Slot) - - require.NotNil(t, resp.Data.CurrentSyncCommittee) - require.NotNil(t, resp.Data.CurrentSyncCommitteeBranch) -} - -func TestLightClientHandler_GetLightClientBootstrap_Deneb(t *testing.T) { - l := util.NewTestLightClient(t).SetupTestDeneb(false) // result is same for true and false - - slot := l.State.Slot() - stateRoot, err := l.State.HashTreeRoot(l.Ctx) - require.NoError(t, err) - - mockBlocker := &testutil.MockBlocker{BlockToReturn: l.Block} - mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot} - s := &Server{ - Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ - slot: l.State, - }}, - Blocker: mockBlocker, - HeadFetcher: mockChainService, - } - request := httptest.NewRequest("GET", "http://foo.com/", nil) - request.SetPathValue("block_root", hexutil.Encode(stateRoot[:])) - writer := httptest.NewRecorder() - writer.Body = &bytes.Buffer{} - - s.GetLightClientBootstrap(writer, request) - require.Equal(t, http.StatusOK, writer.Code) - var resp structs.LightClientBootstrapResponse - err = json.Unmarshal(writer.Body.Bytes(), &resp) - require.NoError(t, err) - var respHeader structs.LightClientHeader - err = json.Unmarshal(resp.Data.Header, &respHeader) - require.NoError(t, err) - require.Equal(t, "deneb", resp.Version) - - blockHeader, err := l.Block.Header() - require.NoError(t, err) - require.Equal(t, hexutil.Encode(blockHeader.Header.BodyRoot), respHeader.Beacon.BodyRoot) - require.Equal(t, strconv.FormatUint(uint64(blockHeader.Header.Slot), 10), respHeader.Beacon.Slot) - - require.NotNil(t, resp.Data.CurrentSyncCommittee) - require.NotNil(t, resp.Data.CurrentSyncCommitteeBranch) -} - -func TestLightClientHandler_GetLightClientBootstrap_Electra(t *testing.T) { - l := util.NewTestLightClient(t).SetupTestElectra(false) // result is same for true and false - - slot := l.State.Slot() - stateRoot, err := l.State.HashTreeRoot(l.Ctx) - require.NoError(t, err) - - mockBlocker := &testutil.MockBlocker{BlockToReturn: l.Block} - mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot} - s := &Server{ - Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ - slot: l.State, - }}, - Blocker: mockBlocker, - HeadFetcher: mockChainService, - } - request := httptest.NewRequest("GET", "http://foo.com/", nil) - request.SetPathValue("block_root", hexutil.Encode(stateRoot[:])) - writer := httptest.NewRecorder() - writer.Body = &bytes.Buffer{} - - s.GetLightClientBootstrap(writer, request) - require.Equal(t, http.StatusOK, writer.Code) - var resp structs.LightClientBootstrapResponse - err = json.Unmarshal(writer.Body.Bytes(), &resp) - require.NoError(t, err) - var respHeader structs.LightClientHeader - err = json.Unmarshal(resp.Data.Header, &respHeader) - require.NoError(t, err) - require.Equal(t, "electra", resp.Version) - - blockHeader, err := l.Block.Header() - require.NoError(t, err) - require.Equal(t, hexutil.Encode(blockHeader.Header.BodyRoot), respHeader.Beacon.BodyRoot) - require.Equal(t, strconv.FormatUint(uint64(blockHeader.Header.Slot), 10), respHeader.Beacon.Slot) - - require.NotNil(t, resp.Data.CurrentSyncCommittee) - require.NotNil(t, resp.Data.CurrentSyncCommitteeBranch) -} - -// GetLightClientByRange tests - -func TestLightClientHandler_GetLightClientUpdatesByRangeAltair(t *testing.T) { - helpers.ClearCache() - ctx := context.Background() - - params.SetupTestConfigCleanup(t) - config := params.BeaconConfig() - config.AltairForkEpoch = 0 - params.OverrideBeaconConfig(config) - - slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) - - st, err := util.NewBeaconStateAltair() - require.NoError(t, err) - err = st.SetSlot(slot) - require.NoError(t, err) - - db := setupDB(t) - - updatePeriod := uint64(slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch))) - - update := ðpbv2.LightClientUpdate{ - AttestedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: ðpbv2.LightClientHeader{ - Beacon: ðpbv1.BeaconBlockHeader{ - Slot: slot.Sub(1), - ProposerIndex: 1, - ParentRoot: []byte{1, 1, 1}, - StateRoot: []byte{1, 1, 1}, - BodyRoot: []byte{1, 1, 1}, - }, - }, - }, - }, - NextSyncCommittee: ðpbv2.SyncCommittee{ - Pubkeys: nil, - AggregatePubkey: nil, - }, - NextSyncCommitteeBranch: nil, - FinalizedHeader: nil, - FinalityBranch: nil, - SyncAggregate: ðpbv1.SyncAggregate{ - SyncCommitteeBits: []byte{1, 1, 1}, - SyncCommitteeSignature: []byte{1, 1, 1}, - }, - SignatureSlot: 7, - } - - err = db.SaveLightClientUpdate(ctx, updatePeriod, ðpbv2.LightClientUpdateWithVersion{ - Version: version.Altair, - Data: update, - }) - require.NoError(t, err) - - mockChainService := &mock.ChainService{State: st} - s := &Server{ - HeadFetcher: mockChainService, - BeaconDB: db, - } - startPeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - url := fmt.Sprintf("http://foo.com/?count=1&start_period=%d", startPeriod) - request := httptest.NewRequest("GET", url, nil) - writer := httptest.NewRecorder() - writer.Body = &bytes.Buffer{} - - s.GetLightClientUpdatesByRange(writer, request) - - require.Equal(t, http.StatusOK, writer.Code) - var resp structs.LightClientUpdatesByRangeResponse - err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) - require.NoError(t, err) - require.Equal(t, 1, len(resp.Updates)) - require.Equal(t, "altair", resp.Updates[0].Version) - updateJson, err := structs.LightClientUpdateFromConsensus(update) - require.NoError(t, err) - require.DeepEqual(t, updateJson, resp.Updates[0].Data) -} - -func TestLightClientHandler_GetLightClientUpdatesByRangeCapella(t *testing.T) { - helpers.ClearCache() - ctx := context.Background() - params.SetupTestConfigCleanup(t) - config := params.BeaconConfig() - config.AltairForkEpoch = 0 - config.CapellaForkEpoch = 1 - params.OverrideBeaconConfig(config) - slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) - - st, err := util.NewBeaconStateCapella() - require.NoError(t, err) - err = st.SetSlot(slot) - require.NoError(t, err) - - db := setupDB(t) - - updatePeriod := uint64(slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch))) - - update := ðpbv2.LightClientUpdate{ - AttestedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ - HeaderCapella: ðpbv2.LightClientHeaderCapella{ - Beacon: ðpbv1.BeaconBlockHeader{ - Slot: slot.Sub(1), - ProposerIndex: 1, - ParentRoot: []byte{1, 1, 1}, - StateRoot: []byte{1, 1, 1}, - BodyRoot: []byte{1, 1, 1}, - }, - Execution: &enginev1.ExecutionPayloadHeaderCapella{ - FeeRecipient: []byte{1, 2, 3}, - }, - ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, - }, - }, - }, - NextSyncCommittee: ðpbv2.SyncCommittee{ - Pubkeys: nil, - AggregatePubkey: nil, - }, - NextSyncCommitteeBranch: nil, - FinalizedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ - HeaderCapella: ðpbv2.LightClientHeaderCapella{ - Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 12, - ProposerIndex: 1, - ParentRoot: []byte{1, 1, 1}, - StateRoot: []byte{1, 1, 1}, - BodyRoot: []byte{1, 1, 1}, - }, - Execution: &enginev1.ExecutionPayloadHeaderCapella{ - FeeRecipient: []byte{1, 2, 3}, - }, - ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, - }, - }, - }, - FinalityBranch: nil, - SyncAggregate: ðpbv1.SyncAggregate{ - SyncCommitteeBits: []byte{1, 1, 1}, - SyncCommitteeSignature: []byte{1, 1, 1}, - }, - SignatureSlot: 7, - } - - err = db.SaveLightClientUpdate(ctx, updatePeriod, ðpbv2.LightClientUpdateWithVersion{ - Version: version.Capella, - Data: update, - }) - require.NoError(t, err) - - mockChainService := &mock.ChainService{State: st} - s := &Server{ - HeadFetcher: mockChainService, - BeaconDB: db, - } - startPeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - url := fmt.Sprintf("http://foo.com/?count=1&start_period=%d", startPeriod) - request := httptest.NewRequest("GET", url, nil) - writer := httptest.NewRecorder() - writer.Body = &bytes.Buffer{} - - s.GetLightClientUpdatesByRange(writer, request) - - require.Equal(t, http.StatusOK, writer.Code) - var resp structs.LightClientUpdatesByRangeResponse - err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) - require.NoError(t, err) - require.Equal(t, 1, len(resp.Updates)) - require.Equal(t, "capella", resp.Updates[0].Version) - updateJson, err := structs.LightClientUpdateFromConsensus(update) - require.NoError(t, err) - require.DeepEqual(t, updateJson, resp.Updates[0].Data) -} - -func TestLightClientHandler_GetLightClientUpdatesByRangeDeneb(t *testing.T) { - helpers.ClearCache() - ctx := context.Background() - params.SetupTestConfigCleanup(t) - config := params.BeaconConfig() - config.AltairForkEpoch = 0 - config.DenebForkEpoch = 1 - params.OverrideBeaconConfig(config) - slot := primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) - - st, err := util.NewBeaconStateDeneb() - require.NoError(t, err) - err = st.SetSlot(slot) - require.NoError(t, err) - - db := setupDB(t) - - updatePeriod := uint64(slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch))) - - update := ðpbv2.LightClientUpdate{ - AttestedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ - HeaderCapella: ðpbv2.LightClientHeaderCapella{ - Beacon: ðpbv1.BeaconBlockHeader{ - Slot: slot.Sub(1), - ProposerIndex: 1, - ParentRoot: []byte{1, 1, 1}, - StateRoot: []byte{1, 1, 1}, - BodyRoot: []byte{1, 1, 1}, - }, - Execution: &enginev1.ExecutionPayloadHeaderCapella{ - FeeRecipient: []byte{1, 2, 3}, - }, - ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, - }, - }, - }, - NextSyncCommittee: ðpbv2.SyncCommittee{ - Pubkeys: nil, - AggregatePubkey: nil, - }, - NextSyncCommitteeBranch: nil, - FinalizedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderDeneb{ - HeaderDeneb: ðpbv2.LightClientHeaderDeneb{ - Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 12, - ProposerIndex: 1, - ParentRoot: []byte{1, 1, 1}, - StateRoot: []byte{1, 1, 1}, - BodyRoot: []byte{1, 1, 1}, - }, - Execution: &enginev1.ExecutionPayloadHeaderDeneb{ - FeeRecipient: []byte{1, 2, 3}, - }, - ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, - }, - }, - }, - FinalityBranch: nil, - SyncAggregate: ðpbv1.SyncAggregate{ - SyncCommitteeBits: []byte{1, 1, 1}, - SyncCommitteeSignature: []byte{1, 1, 1}, - }, - SignatureSlot: 7, - } - - err = db.SaveLightClientUpdate(ctx, updatePeriod, ðpbv2.LightClientUpdateWithVersion{ - Version: version.Deneb, - Data: update, - }) - require.NoError(t, err) - - mockChainService := &mock.ChainService{State: st} - s := &Server{ - HeadFetcher: mockChainService, - BeaconDB: db, - } - startPeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - url := fmt.Sprintf("http://foo.com/?count=1&start_period=%d", startPeriod) - request := httptest.NewRequest("GET", url, nil) - writer := httptest.NewRecorder() - writer.Body = &bytes.Buffer{} - - s.GetLightClientUpdatesByRange(writer, request) - - require.Equal(t, http.StatusOK, writer.Code) - var resp structs.LightClientUpdatesByRangeResponse - err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) - require.NoError(t, err) - require.Equal(t, 1, len(resp.Updates)) - require.Equal(t, "deneb", resp.Updates[0].Version) - updateJson, err := structs.LightClientUpdateFromConsensus(update) - require.NoError(t, err) - require.DeepEqual(t, updateJson, resp.Updates[0].Data) -} - -func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleAltair(t *testing.T) { - helpers.ClearCache() - ctx := context.Background() - params.SetupTestConfigCleanup(t) - config := params.BeaconConfig() - config.AltairForkEpoch = 0 - config.EpochsPerSyncCommitteePeriod = 1 - params.OverrideBeaconConfig(config) - slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) - - st, err := util.NewBeaconStateAltair() - require.NoError(t, err) - headSlot := slot.Add(33) // 2 periods - err = st.SetSlot(headSlot) - require.NoError(t, err) - - db := setupDB(t) - - updates := make([]*ethpbv2.LightClientUpdate, 2) - - updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - - for i := 0; i < 2; i++ { - newSlot := slot.Add(uint64(i)) - - update := ðpbv2.LightClientUpdate{ - AttestedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: ðpbv2.LightClientHeader{ - Beacon: ðpbv1.BeaconBlockHeader{ - Slot: newSlot, - ProposerIndex: 1, - ParentRoot: []byte{1, 1, 1}, - StateRoot: []byte{1, 1, 1}, - BodyRoot: []byte{1, 1, 1}, - }, - }, - }, - }, - NextSyncCommittee: ðpbv2.SyncCommittee{ - Pubkeys: nil, - AggregatePubkey: nil, - }, - NextSyncCommitteeBranch: nil, - FinalizedHeader: nil, - FinalityBranch: nil, - SyncAggregate: ðpbv1.SyncAggregate{ - SyncCommitteeBits: []byte{1, 1, 1}, - SyncCommitteeSignature: []byte{1, 1, 1}, - }, - SignatureSlot: 7, - } - - updates[i] = update - - err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ - Version: version.Altair, - Data: update, - }) - require.NoError(t, err) - - updatePeriod++ - } - - mockChainService := &mock.ChainService{State: st} - s := &Server{ - HeadFetcher: mockChainService, - BeaconDB: db, - } - startPeriod := slot.Sub(1).Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - url := fmt.Sprintf("http://foo.com/?count=100&start_period=%d", startPeriod) - request := httptest.NewRequest("GET", url, nil) - writer := httptest.NewRecorder() - writer.Body = &bytes.Buffer{} - - s.GetLightClientUpdatesByRange(writer, request) - - require.Equal(t, http.StatusOK, writer.Code) - var resp structs.LightClientUpdatesByRangeResponse - err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) - require.NoError(t, err) - require.Equal(t, 2, len(resp.Updates)) - for i, update := range updates { - require.Equal(t, "altair", resp.Updates[i].Version) - updateJson, err := structs.LightClientUpdateFromConsensus(update) - require.NoError(t, err) - require.DeepEqual(t, updateJson, resp.Updates[i].Data) - } -} - -func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleCapella(t *testing.T) { - helpers.ClearCache() - ctx := context.Background() - params.SetupTestConfigCleanup(t) - config := params.BeaconConfig() - config.AltairForkEpoch = 0 - config.CapellaForkEpoch = 1 - config.EpochsPerSyncCommitteePeriod = 1 - params.OverrideBeaconConfig(config) - slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) - - st, err := util.NewBeaconStateAltair() - require.NoError(t, err) - headSlot := slot.Add(33) // 2 periods - err = st.SetSlot(headSlot) - require.NoError(t, err) - - db := setupDB(t) - - updates := make([]*ethpbv2.LightClientUpdate, 2) - - updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - - for i := 0; i < 2; i++ { - - newSlot := slot.Add(uint64(i)) - - update := ðpbv2.LightClientUpdate{ - AttestedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ - HeaderCapella: ðpbv2.LightClientHeaderCapella{ - Beacon: ðpbv1.BeaconBlockHeader{ - Slot: newSlot, - ProposerIndex: 1, - ParentRoot: []byte{1, 1, 1}, - StateRoot: []byte{1, 1, 1}, - BodyRoot: []byte{1, 1, 1}, - }, - Execution: &enginev1.ExecutionPayloadHeaderCapella{ - FeeRecipient: []byte{1, 2, 3}, - }, - ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, - }, - }, - }, - NextSyncCommittee: ðpbv2.SyncCommittee{ - Pubkeys: nil, - AggregatePubkey: nil, - }, - NextSyncCommitteeBranch: nil, - FinalizedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ - HeaderCapella: ðpbv2.LightClientHeaderCapella{ - Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 12, - ProposerIndex: 1, - ParentRoot: []byte{1, 1, 1}, - StateRoot: []byte{1, 1, 1}, - BodyRoot: []byte{1, 1, 1}, - }, - Execution: &enginev1.ExecutionPayloadHeaderCapella{ - FeeRecipient: []byte{1, 2, 3}, - }, - ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, - }, - }, - }, - FinalityBranch: nil, - SyncAggregate: ðpbv1.SyncAggregate{ - SyncCommitteeBits: []byte{1, 1, 1}, - SyncCommitteeSignature: []byte{1, 1, 1}, - }, - SignatureSlot: 7, - } - - updates[i] = update - - err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ - Version: version.Capella, - Data: update, - }) - require.NoError(t, err) - - updatePeriod++ - } - - mockChainService := &mock.ChainService{State: st} - s := &Server{ - HeadFetcher: mockChainService, - BeaconDB: db, - } - startPeriod := slot.Sub(1).Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - url := fmt.Sprintf("http://foo.com/?count=100&start_period=%d", startPeriod) - request := httptest.NewRequest("GET", url, nil) - writer := httptest.NewRecorder() - writer.Body = &bytes.Buffer{} - - s.GetLightClientUpdatesByRange(writer, request) - - require.Equal(t, http.StatusOK, writer.Code) - var resp structs.LightClientUpdatesByRangeResponse - err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) - require.NoError(t, err) - require.Equal(t, 2, len(resp.Updates)) - for i, update := range updates { - require.Equal(t, "capella", resp.Updates[i].Version) - updateJson, err := structs.LightClientUpdateFromConsensus(update) - require.NoError(t, err) - require.DeepEqual(t, updateJson, resp.Updates[i].Data) - } -} - -func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleDeneb(t *testing.T) { - helpers.ClearCache() - ctx := context.Background() - params.SetupTestConfigCleanup(t) - config := params.BeaconConfig() - config.AltairForkEpoch = 0 - config.DenebForkEpoch = 1 - config.EpochsPerSyncCommitteePeriod = 1 - params.OverrideBeaconConfig(config) - slot := primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) - - st, err := util.NewBeaconStateAltair() - require.NoError(t, err) - headSlot := slot.Add(33) - err = st.SetSlot(headSlot) - require.NoError(t, err) - - db := setupDB(t) - - updates := make([]*ethpbv2.LightClientUpdate, 2) - - updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - - for i := 0; i < 2; i++ { - - newSlot := slot.Add(uint64(i)) - - update := ðpbv2.LightClientUpdate{ - AttestedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderDeneb{ - HeaderDeneb: ðpbv2.LightClientHeaderDeneb{ - Beacon: ðpbv1.BeaconBlockHeader{ - Slot: newSlot, - ProposerIndex: 1, - ParentRoot: []byte{1, 1, 1}, - StateRoot: []byte{1, 1, 1}, - BodyRoot: []byte{1, 1, 1}, - }, - Execution: &enginev1.ExecutionPayloadHeaderDeneb{ - FeeRecipient: []byte{1, 2, 3}, - }, - ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, - }, - }, - }, - NextSyncCommittee: ðpbv2.SyncCommittee{ - Pubkeys: nil, - AggregatePubkey: nil, - }, - NextSyncCommitteeBranch: nil, - FinalizedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderDeneb{ - HeaderDeneb: ðpbv2.LightClientHeaderDeneb{ - Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 12, - ProposerIndex: 1, - ParentRoot: []byte{1, 1, 1}, - StateRoot: []byte{1, 1, 1}, - BodyRoot: []byte{1, 1, 1}, - }, - Execution: &enginev1.ExecutionPayloadHeaderDeneb{ - FeeRecipient: []byte{1, 2, 3}, - }, - ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, - }, - }, - }, - FinalityBranch: nil, - SyncAggregate: ðpbv1.SyncAggregate{ - SyncCommitteeBits: []byte{1, 1, 1}, - SyncCommitteeSignature: []byte{1, 1, 1}, - }, - SignatureSlot: 7, - } - - updates[i] = update - - err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ - Version: version.Deneb, - Data: update, - }) - require.NoError(t, err) - - updatePeriod++ - } - - mockChainService := &mock.ChainService{State: st} - s := &Server{ - HeadFetcher: mockChainService, - BeaconDB: db, - } - startPeriod := slot.Sub(1).Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - url := fmt.Sprintf("http://foo.com/?count=100&start_period=%d", startPeriod) - request := httptest.NewRequest("GET", url, nil) - writer := httptest.NewRecorder() - writer.Body = &bytes.Buffer{} - - s.GetLightClientUpdatesByRange(writer, request) - - require.Equal(t, http.StatusOK, writer.Code) - var resp structs.LightClientUpdatesByRangeResponse - err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) - require.NoError(t, err) - require.Equal(t, 2, len(resp.Updates)) - for i, update := range updates { - require.Equal(t, "deneb", resp.Updates[i].Version) - updateJson, err := structs.LightClientUpdateFromConsensus(update) - require.NoError(t, err) - require.DeepEqual(t, updateJson, resp.Updates[i].Data) - } -} - -func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleForksAltairCapella(t *testing.T) { - helpers.ClearCache() - ctx := context.Background() - params.SetupTestConfigCleanup(t) - config := params.BeaconConfig() - config.AltairForkEpoch = 0 - config.CapellaForkEpoch = 1 - config.EpochsPerSyncCommitteePeriod = 1 - params.OverrideBeaconConfig(config) - slotCapella := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) - slotAltair := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) - - st, err := util.NewBeaconStateAltair() - require.NoError(t, err) - headSlot := slotCapella.Add(1) - err = st.SetSlot(headSlot) - require.NoError(t, err) - - db := setupDB(t) - - updates := make([]*ethpbv2.LightClientUpdate, 2) - - updatePeriod := slotAltair.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - - update := ðpbv2.LightClientUpdate{ - AttestedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: ðpbv2.LightClientHeader{ - Beacon: ðpbv1.BeaconBlockHeader{ - Slot: slotAltair, - ProposerIndex: 1, - ParentRoot: []byte{1, 1, 1}, - StateRoot: []byte{1, 1, 1}, - BodyRoot: []byte{1, 1, 1}, - }, - }, - }, - }, - NextSyncCommittee: ðpbv2.SyncCommittee{ - Pubkeys: nil, - AggregatePubkey: nil, - }, - NextSyncCommitteeBranch: nil, - FinalizedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: ðpbv2.LightClientHeader{ - Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 12, - ProposerIndex: 1, - ParentRoot: []byte{1, 1, 1}, - StateRoot: []byte{1, 1, 1}, - BodyRoot: []byte{1, 1, 1}, - }, - }, - }, - }, - FinalityBranch: nil, - SyncAggregate: ðpbv1.SyncAggregate{ - SyncCommitteeBits: []byte{1, 1, 1}, - SyncCommitteeSignature: []byte{1, 1, 1}, - }, - SignatureSlot: slotAltair, - } - - updates[0] = update - - err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ - Version: version.Altair, - Data: update, - }) - require.NoError(t, err) - - updatePeriod = slotCapella.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - - update = ðpbv2.LightClientUpdate{ - AttestedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ - HeaderCapella: ðpbv2.LightClientHeaderCapella{ - Beacon: ðpbv1.BeaconBlockHeader{ - Slot: slotCapella, - ProposerIndex: 1, - ParentRoot: []byte{1, 1, 1}, - StateRoot: []byte{1, 1, 1}, - BodyRoot: []byte{1, 1, 1}, - }, - Execution: &enginev1.ExecutionPayloadHeaderCapella{ - FeeRecipient: []byte{1, 2, 3}, - }, - ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, - }, - }, - }, - NextSyncCommittee: ðpbv2.SyncCommittee{ - Pubkeys: nil, - AggregatePubkey: nil, - }, - NextSyncCommitteeBranch: nil, - FinalizedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ - HeaderCapella: ðpbv2.LightClientHeaderCapella{ - Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 12, - ProposerIndex: 1, - ParentRoot: []byte{1, 1, 1}, - StateRoot: []byte{1, 1, 1}, - BodyRoot: []byte{1, 1, 1}, - }, - Execution: &enginev1.ExecutionPayloadHeaderCapella{ - FeeRecipient: []byte{1, 2, 3}, - }, - ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, - }, - }, - }, - FinalityBranch: nil, - SyncAggregate: ðpbv1.SyncAggregate{ - SyncCommitteeBits: []byte{1, 1, 1}, - SyncCommitteeSignature: []byte{1, 1, 1}, - }, - SignatureSlot: slotCapella, - } - - updates[1] = update - - err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ - Version: version.Capella, - Data: update, - }) - require.NoError(t, err) - - mockChainService := &mock.ChainService{State: st} - s := &Server{ - HeadFetcher: mockChainService, - BeaconDB: db, - } - startPeriod := 0 - url := fmt.Sprintf("http://foo.com/?count=100&start_period=%d", startPeriod) - request := httptest.NewRequest("GET", url, nil) - writer := httptest.NewRecorder() - writer.Body = &bytes.Buffer{} - - s.GetLightClientUpdatesByRange(writer, request) - - require.Equal(t, http.StatusOK, writer.Code) - var resp structs.LightClientUpdatesByRangeResponse - err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) - require.NoError(t, err) - require.Equal(t, 2, len(resp.Updates)) - for i, update := range updates { - if i < 1 { - require.Equal(t, "altair", resp.Updates[i].Version) - } else { - require.Equal(t, "capella", resp.Updates[i].Version) - } - updateJson, err := structs.LightClientUpdateFromConsensus(update) - require.NoError(t, err) - require.DeepEqual(t, updateJson, resp.Updates[i].Data) - } -} - -func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleForksCapellaDeneb(t *testing.T) { - helpers.ClearCache() - ctx := context.Background() - params.SetupTestConfigCleanup(t) - config := params.BeaconConfig() - config.AltairForkEpoch = 0 - config.CapellaForkEpoch = 1 - config.DenebForkEpoch = 2 - config.EpochsPerSyncCommitteePeriod = 1 - params.OverrideBeaconConfig(config) - slotDeneb := primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) - slotCapella := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) - - st, err := util.NewBeaconStateAltair() - require.NoError(t, err) - headSlot := slotDeneb.Add(1) - err = st.SetSlot(headSlot) - require.NoError(t, err) - - db := setupDB(t) - - updates := make([]*ethpbv2.LightClientUpdate, 2) - - updatePeriod := slotCapella.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - - update := ðpbv2.LightClientUpdate{ - AttestedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ - HeaderCapella: ðpbv2.LightClientHeaderCapella{ - Beacon: ðpbv1.BeaconBlockHeader{ - Slot: slotCapella, - ProposerIndex: 1, - ParentRoot: []byte{1, 1, 1}, - StateRoot: []byte{1, 1, 1}, - BodyRoot: []byte{1, 1, 1}, - }, - Execution: &enginev1.ExecutionPayloadHeaderCapella{ - FeeRecipient: []byte{1, 2, 3}, - }, - ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, - }, - }, - }, - NextSyncCommittee: ðpbv2.SyncCommittee{ - Pubkeys: nil, - AggregatePubkey: nil, - }, - NextSyncCommitteeBranch: nil, - FinalizedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ - HeaderCapella: ðpbv2.LightClientHeaderCapella{ - Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 12, - ProposerIndex: 1, - ParentRoot: []byte{1, 1, 1}, - StateRoot: []byte{1, 1, 1}, - BodyRoot: []byte{1, 1, 1}, - }, - Execution: &enginev1.ExecutionPayloadHeaderCapella{ - FeeRecipient: []byte{1, 2, 3}, - }, - ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, - }, - }, - }, - FinalityBranch: nil, - SyncAggregate: ðpbv1.SyncAggregate{ - SyncCommitteeBits: []byte{1, 1, 1}, - SyncCommitteeSignature: []byte{1, 1, 1}, - }, - SignatureSlot: slotCapella, - } - - updates[0] = update - - err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ - Version: version.Capella, - Data: update, - }) - require.NoError(t, err) - - updatePeriod = slotDeneb.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - - update = ðpbv2.LightClientUpdate{ - AttestedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderDeneb{ - HeaderDeneb: ðpbv2.LightClientHeaderDeneb{ - Beacon: ðpbv1.BeaconBlockHeader{ - Slot: slotDeneb, - ProposerIndex: 1, - ParentRoot: []byte{1, 1, 1}, - StateRoot: []byte{1, 1, 1}, - BodyRoot: []byte{1, 1, 1}, - }, - Execution: &enginev1.ExecutionPayloadHeaderDeneb{ - FeeRecipient: []byte{1, 2, 3}, - }, - ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, - }, - }, - }, - NextSyncCommittee: ðpbv2.SyncCommittee{ - Pubkeys: nil, - AggregatePubkey: nil, - }, - NextSyncCommitteeBranch: nil, - FinalizedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderDeneb{ - HeaderDeneb: ðpbv2.LightClientHeaderDeneb{ - Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 12, - ProposerIndex: 1, - ParentRoot: []byte{1, 1, 1}, - StateRoot: []byte{1, 1, 1}, - BodyRoot: []byte{1, 1, 1}, - }, - Execution: &enginev1.ExecutionPayloadHeaderDeneb{ - FeeRecipient: []byte{1, 2, 3}, - }, - ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, - }, - }, - }, - FinalityBranch: nil, - SyncAggregate: ðpbv1.SyncAggregate{ - SyncCommitteeBits: []byte{1, 1, 1}, - SyncCommitteeSignature: []byte{1, 1, 1}, - }, - SignatureSlot: slotDeneb, - } - - updates[1] = update - - err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ - Version: version.Deneb, - Data: update, - }) - require.NoError(t, err) - - mockChainService := &mock.ChainService{State: st} - s := &Server{ - HeadFetcher: mockChainService, - BeaconDB: db, - } - startPeriod := 1 - url := fmt.Sprintf("http://foo.com/?count=100&start_period=%d", startPeriod) - request := httptest.NewRequest("GET", url, nil) - writer := httptest.NewRecorder() - writer.Body = &bytes.Buffer{} - - s.GetLightClientUpdatesByRange(writer, request) - - require.Equal(t, http.StatusOK, writer.Code) - var resp structs.LightClientUpdatesByRangeResponse - err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) - require.NoError(t, err) - require.Equal(t, 2, len(resp.Updates)) - for i, update := range updates { - if i < 1 { - require.Equal(t, "capella", resp.Updates[i].Version) - } else { - require.Equal(t, "deneb", resp.Updates[i].Version) - } - updateJson, err := structs.LightClientUpdateFromConsensus(update) - require.NoError(t, err) - require.DeepEqual(t, updateJson, resp.Updates[i].Data) - } -} - -func TestLightClientHandler_GetLightClientUpdatesByRangeCountBiggerThanLimit(t *testing.T) { - helpers.ClearCache() - ctx := context.Background() - params.SetupTestConfigCleanup(t) - config := params.BeaconConfig() - config.AltairForkEpoch = 0 - config.EpochsPerSyncCommitteePeriod = 1 - config.MaxRequestLightClientUpdates = 2 - params.OverrideBeaconConfig(config) - slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) - - st, err := util.NewBeaconStateAltair() - require.NoError(t, err) - headSlot := slot.Add(65) - err = st.SetSlot(headSlot) - require.NoError(t, err) - - db := setupDB(t) - - updates := make([]*ethpbv2.LightClientUpdate, 3) - - updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - - for i := 0; i < 3; i++ { - newSlot := slot.Add(uint64(i * 32)) - - update := ðpbv2.LightClientUpdate{ - AttestedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: ðpbv2.LightClientHeader{ - Beacon: ðpbv1.BeaconBlockHeader{ - Slot: newSlot, - ProposerIndex: 1, - ParentRoot: []byte{1, 1, 1}, - StateRoot: []byte{1, 1, 1}, - BodyRoot: []byte{1, 1, 1}, - }, - }, - }, - }, - NextSyncCommittee: ðpbv2.SyncCommittee{ - Pubkeys: nil, - AggregatePubkey: nil, - }, - NextSyncCommitteeBranch: nil, - FinalizedHeader: nil, - FinalityBranch: nil, - SyncAggregate: ðpbv1.SyncAggregate{ - SyncCommitteeBits: []byte{1, 1, 1}, - SyncCommitteeSignature: []byte{1, 1, 1}, - }, - SignatureSlot: 7, - } - - updates[i] = update - - err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ - Version: version.Altair, - Data: update, - }) - require.NoError(t, err) - - updatePeriod++ - } - - mockChainService := &mock.ChainService{State: st} - s := &Server{ - HeadFetcher: mockChainService, - BeaconDB: db, - } - startPeriod := 0 - url := fmt.Sprintf("http://foo.com/?count=4&start_period=%d", startPeriod) - request := httptest.NewRequest("GET", url, nil) - writer := httptest.NewRecorder() - writer.Body = &bytes.Buffer{} - - s.GetLightClientUpdatesByRange(writer, request) - - require.Equal(t, http.StatusOK, writer.Code) - var resp structs.LightClientUpdatesByRangeResponse - err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) - require.NoError(t, err) - require.Equal(t, 2, len(resp.Updates)) - for i, update := range updates { - if i < 2 { - require.Equal(t, "altair", resp.Updates[i].Version) - updateJson, err := structs.LightClientUpdateFromConsensus(update) - require.NoError(t, err) - require.DeepEqual(t, updateJson, resp.Updates[i].Data) - } - } -} - -func TestLightClientHandler_GetLightClientUpdatesByRangeCountBiggerThanMax(t *testing.T) { - helpers.ClearCache() - ctx := context.Background() - params.SetupTestConfigCleanup(t) - config := params.BeaconConfig() - config.AltairForkEpoch = 0 - config.EpochsPerSyncCommitteePeriod = 1 - config.MaxRequestLightClientUpdates = 2 - params.OverrideBeaconConfig(config) - slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) - - st, err := util.NewBeaconStateAltair() - require.NoError(t, err) - headSlot := slot.Add(65) - err = st.SetSlot(headSlot) - require.NoError(t, err) - - db := setupDB(t) - - updates := make([]*ethpbv2.LightClientUpdate, 3) - - updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - - for i := 0; i < 3; i++ { - newSlot := slot.Add(uint64(i * 32)) - - update := ðpbv2.LightClientUpdate{ - AttestedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: ðpbv2.LightClientHeader{ - Beacon: ðpbv1.BeaconBlockHeader{ - Slot: newSlot, - ProposerIndex: 1, - ParentRoot: []byte{1, 1, 1}, - StateRoot: []byte{1, 1, 1}, - BodyRoot: []byte{1, 1, 1}, - }, - }, - }, - }, - NextSyncCommittee: ðpbv2.SyncCommittee{ - Pubkeys: nil, - AggregatePubkey: nil, - }, - NextSyncCommitteeBranch: nil, - FinalizedHeader: nil, - FinalityBranch: nil, - SyncAggregate: ðpbv1.SyncAggregate{ - SyncCommitteeBits: []byte{1, 1, 1}, - SyncCommitteeSignature: []byte{1, 1, 1}, - }, - SignatureSlot: 7, - } - - updates[i] = update - err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ - Version: version.Altair, - Data: update, - }) - require.NoError(t, err) - - updatePeriod++ - } - - mockChainService := &mock.ChainService{State: st} - s := &Server{ - HeadFetcher: mockChainService, - BeaconDB: db, - } - startPeriod := 0 - url := fmt.Sprintf("http://foo.com/?count=10&start_period=%d", startPeriod) - request := httptest.NewRequest("GET", url, nil) - writer := httptest.NewRecorder() - writer.Body = &bytes.Buffer{} - - s.GetLightClientUpdatesByRange(writer, request) - - require.Equal(t, http.StatusOK, writer.Code) - var resp structs.LightClientUpdatesByRangeResponse - err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) - require.NoError(t, err) - require.Equal(t, 2, len(resp.Updates)) - for i, update := range updates { - if i < 2 { - require.Equal(t, "altair", resp.Updates[i].Version) - updateJson, err := structs.LightClientUpdateFromConsensus(update) - require.NoError(t, err) - require.DeepEqual(t, updateJson, resp.Updates[i].Data) - } - } -} - -func TestLightClientHandler_GetLightClientUpdatesByRangeStartPeriodBeforeAltair(t *testing.T) { - helpers.ClearCache() - ctx := context.Background() - params.SetupTestConfigCleanup(t) - config := params.BeaconConfig() - config.AltairForkEpoch = 1 - config.EpochsPerSyncCommitteePeriod = 1 - params.OverrideBeaconConfig(config) - slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) - - st, err := util.NewBeaconStateAltair() - require.NoError(t, err) - headSlot := slot.Add(1) - err = st.SetSlot(headSlot) - require.NoError(t, err) - - db := setupDB(t) - - updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - - update := ðpbv2.LightClientUpdate{ - AttestedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: ðpbv2.LightClientHeader{ - Beacon: ðpbv1.BeaconBlockHeader{ - Slot: slot, - ProposerIndex: 1, - ParentRoot: []byte{1, 1, 1}, - StateRoot: []byte{1, 1, 1}, - BodyRoot: []byte{1, 1, 1}, - }, - }, - }, - }, - NextSyncCommittee: ðpbv2.SyncCommittee{ - Pubkeys: nil, - AggregatePubkey: nil, - }, - NextSyncCommitteeBranch: nil, - FinalizedHeader: nil, - FinalityBranch: nil, - SyncAggregate: ðpbv1.SyncAggregate{ - SyncCommitteeBits: []byte{1, 1, 1}, - SyncCommitteeSignature: []byte{1, 1, 1}, - }, - SignatureSlot: 7, - } - - err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ - Version: version.Altair, - Data: update, - }) - require.NoError(t, err) - - mockChainService := &mock.ChainService{State: st} - s := &Server{ - HeadFetcher: mockChainService, - BeaconDB: db, - } - startPeriod := 0 - url := fmt.Sprintf("http://foo.com/?count=2&start_period=%d", startPeriod) - request := httptest.NewRequest("GET", url, nil) - writer := httptest.NewRecorder() - writer.Body = &bytes.Buffer{} - - s.GetLightClientUpdatesByRange(writer, request) - - require.Equal(t, http.StatusOK, writer.Code) - var resp structs.LightClientUpdatesByRangeResponse - err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) - require.NoError(t, err) - require.Equal(t, 1, len(resp.Updates)) - - require.Equal(t, "altair", resp.Updates[0].Version) - updateJson, err := structs.LightClientUpdateFromConsensus(update) - require.NoError(t, err) - require.DeepEqual(t, updateJson, resp.Updates[0].Data) - -} - -func TestLightClientHandler_GetLightClientUpdatesByRangeMissingUpdates(t *testing.T) { - helpers.ClearCache() - ctx := context.Background() - params.SetupTestConfigCleanup(t) - config := params.BeaconConfig() - config.AltairForkEpoch = 0 - config.EpochsPerSyncCommitteePeriod = 1 - params.OverrideBeaconConfig(config) - slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) - - st, err := util.NewBeaconStateAltair() - require.NoError(t, err) - headSlot := slot.Add(65) - err = st.SetSlot(headSlot) - require.NoError(t, err) - - t.Run("missing update in the middle", func(t *testing.T) { - db := setupDB(t) - - updates := make([]*ethpbv2.LightClientUpdate, 3) - - updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - - for i := 0; i < 3; i++ { - if i == 1 { // skip this update - updatePeriod++ - continue - } - newSlot := slot.Add(uint64(i * 32)) - - update := ðpbv2.LightClientUpdate{ - AttestedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: ðpbv2.LightClientHeader{ - Beacon: ðpbv1.BeaconBlockHeader{ - Slot: newSlot, - ProposerIndex: 1, - ParentRoot: []byte{1, 1, 1}, - StateRoot: []byte{1, 1, 1}, - BodyRoot: []byte{1, 1, 1}, - }, - }, - }, - }, - NextSyncCommittee: ðpbv2.SyncCommittee{ - Pubkeys: nil, - AggregatePubkey: nil, - }, - NextSyncCommitteeBranch: nil, - FinalizedHeader: nil, - FinalityBranch: nil, - SyncAggregate: ðpbv1.SyncAggregate{ - SyncCommitteeBits: []byte{1, 1, 1}, - SyncCommitteeSignature: []byte{1, 1, 1}, - }, - SignatureSlot: 7, - } - - updates[i] = update - - err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ - Version: version.Altair, - Data: update, - }) - require.NoError(t, err) - - updatePeriod++ - } - - mockChainService := &mock.ChainService{State: st} - s := &Server{ - HeadFetcher: mockChainService, - BeaconDB: db, - } - startPeriod := 0 - url := fmt.Sprintf("http://foo.com/?count=10&start_period=%d", startPeriod) - request := httptest.NewRequest("GET", url, nil) - writer := httptest.NewRecorder() - writer.Body = &bytes.Buffer{} - - s.GetLightClientUpdatesByRange(writer, request) - - require.Equal(t, http.StatusOK, writer.Code) - var resp structs.LightClientUpdatesByRangeResponse - err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) - require.NoError(t, err) - require.Equal(t, 1, len(resp.Updates)) - require.Equal(t, "altair", resp.Updates[0].Version) - updateJson, err := structs.LightClientUpdateFromConsensus(updates[0]) - require.NoError(t, err) - require.DeepEqual(t, updateJson, resp.Updates[0].Data) - }) - - t.Run("missing update at the beginning", func(t *testing.T) { - db := setupDB(t) - - updates := make([]*ethpbv2.LightClientUpdate, 3) - - updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - - for i := 0; i < 3; i++ { - if i == 0 { // skip this update - updatePeriod++ - continue - } - newSlot := slot.Add(uint64(i)) - - update := ðpbv2.LightClientUpdate{ - AttestedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: ðpbv2.LightClientHeader{ - Beacon: ðpbv1.BeaconBlockHeader{ - Slot: newSlot, - ProposerIndex: 1, - ParentRoot: []byte{1, 1, 1}, - StateRoot: []byte{1, 1, 1}, - BodyRoot: []byte{1, 1, 1}, - }, - }, - }, - }, - NextSyncCommittee: ðpbv2.SyncCommittee{ - Pubkeys: nil, - AggregatePubkey: nil, - }, - NextSyncCommitteeBranch: nil, - FinalizedHeader: nil, - FinalityBranch: nil, - SyncAggregate: ðpbv1.SyncAggregate{ - SyncCommitteeBits: []byte{1, 1, 1}, - SyncCommitteeSignature: []byte{1, 1, 1}, - }, - SignatureSlot: 7, - } - - updates[i] = update - - err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ - Version: version.Altair, - Data: update, - }) - require.NoError(t, err) - - updatePeriod++ - } - - mockChainService := &mock.ChainService{State: st} - s := &Server{ - HeadFetcher: mockChainService, - BeaconDB: db, - } - startPeriod := 0 - url := fmt.Sprintf("http://foo.com/?count=10&start_period=%d", startPeriod) - request := httptest.NewRequest("GET", url, nil) - writer := httptest.NewRecorder() - writer.Body = &bytes.Buffer{} - - s.GetLightClientUpdatesByRange(writer, request) - - require.Equal(t, http.StatusOK, writer.Code) - var resp structs.LightClientUpdatesByRangeResponse - err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) - require.NoError(t, err) - require.Equal(t, 0, len(resp.Updates)) - }) - -} - -// TestLightClientHandler_GetLightClientFinalityUpdate tests - -func TestLightClientHandler_GetLightClientFinalityUpdateAltair(t *testing.T) { - helpers.ClearCache() - ctx := context.Background() - params.SetupTestConfigCleanup(t) - config := params.BeaconConfig() - slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) - - attestedState, err := util.NewBeaconStateAltair() - require.NoError(t, err) - err = attestedState.SetSlot(slot.Sub(1)) - require.NoError(t, err) - - require.NoError(t, attestedState.SetFinalizedCheckpoint(ðpb.Checkpoint{ - Epoch: config.AltairForkEpoch - 10, - Root: make([]byte, 32), - })) - - parent := util.NewBeaconBlockAltair() - parent.Block.Slot = slot.Sub(1) - - signedParent, err := blocks.NewSignedBeaconBlock(parent) - require.NoError(t, err) - - parentHeader, err := signedParent.Header() - require.NoError(t, err) - attestedHeader := parentHeader.Header - - err = attestedState.SetLatestBlockHeader(attestedHeader) - require.NoError(t, err) - attestedStateRoot, err := attestedState.HashTreeRoot(ctx) - require.NoError(t, err) - - // get a new signed block so the root is updated with the new state root - parent.Block.StateRoot = attestedStateRoot[:] - signedParent, err = blocks.NewSignedBeaconBlock(parent) - require.NoError(t, err) - - st, err := util.NewBeaconStateAltair() - require.NoError(t, err) - err = st.SetSlot(slot) - require.NoError(t, err) - - parentRoot, err := signedParent.Block().HashTreeRoot() - require.NoError(t, err) - - block := util.NewBeaconBlockAltair() - block.Block.Slot = slot - block.Block.ParentRoot = parentRoot[:] - - for i := uint64(0); i < config.SyncCommitteeSize; i++ { - block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) - } - - signedBlock, err := blocks.NewSignedBeaconBlock(block) - require.NoError(t, err) - - h, err := signedBlock.Header() - require.NoError(t, err) - - err = st.SetLatestBlockHeader(h.Header) - require.NoError(t, err) - stateRoot, err := st.HashTreeRoot(ctx) - require.NoError(t, err) - - // get a new signed block so the root is updated with the new state root - block.Block.StateRoot = stateRoot[:] - signedBlock, err = blocks.NewSignedBeaconBlock(block) - require.NoError(t, err) - - root, err := block.Block.HashTreeRoot() - require.NoError(t, err) - - mockBlocker := &testutil.MockBlocker{ - RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ - parentRoot: signedParent, - root: signedBlock, - }, - SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ - slot.Sub(1): signedParent, - slot: signedBlock, - }, - } - mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st, FinalizedRoots: map[[32]byte]bool{ - root: true, - }} - s := &Server{ - Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ - slot.Sub(1): attestedState, - slot: st, - }}, - Blocker: mockBlocker, - HeadFetcher: mockChainService, - } - request := httptest.NewRequest("GET", "http://foo.com", nil) - writer := httptest.NewRecorder() - writer.Body = &bytes.Buffer{} - - s.GetLightClientFinalityUpdate(writer, request) - - require.Equal(t, http.StatusOK, writer.Code) - var resp *structs.LightClientUpdateResponse - err = json.Unmarshal(writer.Body.Bytes(), &resp) - require.NoError(t, err) - var respHeader structs.LightClientHeader - err = json.Unmarshal(resp.Data.AttestedHeader, &respHeader) - require.NoError(t, err) - require.Equal(t, "altair", resp.Version) - require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot) - require.NotNil(t, resp.Data) -} - -func TestLightClientHandler_GetLightClientFinalityUpdateCapella(t *testing.T) { - helpers.ClearCache() - ctx := context.Background() - params.SetupTestConfigCleanup(t) - config := params.BeaconConfig() - slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) - - attestedState, err := util.NewBeaconStateCapella() - require.NoError(t, err) - err = attestedState.SetSlot(slot.Sub(1)) - require.NoError(t, err) - - require.NoError(t, attestedState.SetFinalizedCheckpoint(ðpb.Checkpoint{ - Epoch: config.AltairForkEpoch - 10, - Root: make([]byte, 32), - })) - - parent := util.NewBeaconBlockCapella() - parent.Block.Slot = slot.Sub(1) - - signedParent, err := blocks.NewSignedBeaconBlock(parent) - require.NoError(t, err) - - parentHeader, err := signedParent.Header() - require.NoError(t, err) - attestedHeader := parentHeader.Header - - err = attestedState.SetLatestBlockHeader(attestedHeader) - require.NoError(t, err) - attestedStateRoot, err := attestedState.HashTreeRoot(ctx) - require.NoError(t, err) - - // get a new signed block so the root is updated with the new state root - parent.Block.StateRoot = attestedStateRoot[:] - signedParent, err = blocks.NewSignedBeaconBlock(parent) - require.NoError(t, err) - - st, err := util.NewBeaconStateCapella() - require.NoError(t, err) - err = st.SetSlot(slot) - require.NoError(t, err) - - parentRoot, err := signedParent.Block().HashTreeRoot() - require.NoError(t, err) - - block := util.NewBeaconBlockCapella() - block.Block.Slot = slot - block.Block.ParentRoot = parentRoot[:] - - for i := uint64(0); i < config.SyncCommitteeSize; i++ { - block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) - } - - signedBlock, err := blocks.NewSignedBeaconBlock(block) - require.NoError(t, err) - - h, err := signedBlock.Header() - require.NoError(t, err) - - err = st.SetLatestBlockHeader(h.Header) - require.NoError(t, err) - stateRoot, err := st.HashTreeRoot(ctx) - require.NoError(t, err) - - // get a new signed block so the root is updated with the new state root - block.Block.StateRoot = stateRoot[:] - signedBlock, err = blocks.NewSignedBeaconBlock(block) - require.NoError(t, err) - - root, err := block.Block.HashTreeRoot() - require.NoError(t, err) - - mockBlocker := &testutil.MockBlocker{ - RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ - parentRoot: signedParent, - root: signedBlock, - }, - SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ - slot.Sub(1): signedParent, - slot: signedBlock, - }, - } - mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st, FinalizedRoots: map[[32]byte]bool{ - root: true, - }} - s := &Server{ - Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ - slot.Sub(1): attestedState, - slot: st, - }}, - Blocker: mockBlocker, - HeadFetcher: mockChainService, - } - request := httptest.NewRequest("GET", "http://foo.com", nil) - writer := httptest.NewRecorder() - writer.Body = &bytes.Buffer{} - - s.GetLightClientFinalityUpdate(writer, request) - - require.Equal(t, http.StatusOK, writer.Code) - var resp *structs.LightClientUpdateResponse - err = json.Unmarshal(writer.Body.Bytes(), &resp) - require.NoError(t, err) - var respHeader structs.LightClientHeader - err = json.Unmarshal(resp.Data.AttestedHeader, &respHeader) - require.NoError(t, err) - require.Equal(t, "capella", resp.Version) - require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot) - require.NotNil(t, resp.Data) -} - -func TestLightClientHandler_GetLightClientFinalityUpdateDeneb(t *testing.T) { - helpers.ClearCache() - ctx := context.Background() - params.SetupTestConfigCleanup(t) - config := params.BeaconConfig() - slot := primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) - - attestedState, err := util.NewBeaconStateDeneb() - require.NoError(t, err) - err = attestedState.SetSlot(slot.Sub(1)) - require.NoError(t, err) - - require.NoError(t, attestedState.SetFinalizedCheckpoint(ðpb.Checkpoint{ - Epoch: config.AltairForkEpoch - 10, - Root: make([]byte, 32), - })) - - parent := util.NewBeaconBlockDeneb() - parent.Block.Slot = slot.Sub(1) - - signedParent, err := blocks.NewSignedBeaconBlock(parent) - require.NoError(t, err) - - parentHeader, err := signedParent.Header() - require.NoError(t, err) - attestedHeader := parentHeader.Header - - err = attestedState.SetLatestBlockHeader(attestedHeader) - require.NoError(t, err) - attestedStateRoot, err := attestedState.HashTreeRoot(ctx) - require.NoError(t, err) - - // get a new signed block so the root is updated with the new state root - parent.Block.StateRoot = attestedStateRoot[:] - signedParent, err = blocks.NewSignedBeaconBlock(parent) - require.NoError(t, err) - - st, err := util.NewBeaconStateDeneb() - require.NoError(t, err) - err = st.SetSlot(slot) - require.NoError(t, err) - - parentRoot, err := signedParent.Block().HashTreeRoot() - require.NoError(t, err) - - block := util.NewBeaconBlockDeneb() - block.Block.Slot = slot - block.Block.ParentRoot = parentRoot[:] - - for i := uint64(0); i < config.SyncCommitteeSize; i++ { - block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) - } - - signedBlock, err := blocks.NewSignedBeaconBlock(block) - require.NoError(t, err) - - h, err := signedBlock.Header() - require.NoError(t, err) - - err = st.SetLatestBlockHeader(h.Header) - require.NoError(t, err) - stateRoot, err := st.HashTreeRoot(ctx) - require.NoError(t, err) - - // get a new signed block so the root is updated with the new state root - block.Block.StateRoot = stateRoot[:] - signedBlock, err = blocks.NewSignedBeaconBlock(block) - require.NoError(t, err) - - root, err := block.Block.HashTreeRoot() - require.NoError(t, err) - - mockBlocker := &testutil.MockBlocker{ - RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ - parentRoot: signedParent, - root: signedBlock, - }, - SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ - slot.Sub(1): signedParent, - slot: signedBlock, - }, - } - mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st, FinalizedRoots: map[[32]byte]bool{ - root: true, - }} - s := &Server{ - Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ - slot.Sub(1): attestedState, - slot: st, - }}, - Blocker: mockBlocker, - HeadFetcher: mockChainService, - } - request := httptest.NewRequest("GET", "http://foo.com", nil) - writer := httptest.NewRecorder() - writer.Body = &bytes.Buffer{} - - s.GetLightClientFinalityUpdate(writer, request) - - require.Equal(t, http.StatusOK, writer.Code) - var resp *structs.LightClientUpdateResponse - err = json.Unmarshal(writer.Body.Bytes(), &resp) - require.NoError(t, err) - var respHeader structs.LightClientHeaderDeneb - err = json.Unmarshal(resp.Data.AttestedHeader, &respHeader) - require.NoError(t, err) - require.Equal(t, "deneb", resp.Version) - require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot) - require.NotNil(t, resp.Data) -} - -func TestLightClientHandler_GetLightClientOptimisticUpdateAltair(t *testing.T) { - helpers.ClearCache() - ctx := context.Background() - params.SetupTestConfigCleanup(t) - config := params.BeaconConfig() - slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) - - attestedState, err := util.NewBeaconStateAltair() - require.NoError(t, err) - err = attestedState.SetSlot(slot.Sub(1)) - require.NoError(t, err) - - require.NoError(t, attestedState.SetFinalizedCheckpoint(ðpb.Checkpoint{ - Epoch: config.AltairForkEpoch - 10, - Root: make([]byte, 32), - })) - - parent := util.NewBeaconBlockAltair() - parent.Block.Slot = slot.Sub(1) - - signedParent, err := blocks.NewSignedBeaconBlock(parent) - require.NoError(t, err) - - parentHeader, err := signedParent.Header() - require.NoError(t, err) - attestedHeader := parentHeader.Header - - err = attestedState.SetLatestBlockHeader(attestedHeader) - require.NoError(t, err) - attestedStateRoot, err := attestedState.HashTreeRoot(ctx) - require.NoError(t, err) - - // get a new signed block so the root is updated with the new state root - parent.Block.StateRoot = attestedStateRoot[:] - signedParent, err = blocks.NewSignedBeaconBlock(parent) - require.NoError(t, err) - - st, err := util.NewBeaconStateAltair() - require.NoError(t, err) - err = st.SetSlot(slot) - require.NoError(t, err) - - parentRoot, err := signedParent.Block().HashTreeRoot() - require.NoError(t, err) - - block := util.NewBeaconBlockAltair() - block.Block.Slot = slot - block.Block.ParentRoot = parentRoot[:] - - for i := uint64(0); i < config.SyncCommitteeSize; i++ { - block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) - } - - signedBlock, err := blocks.NewSignedBeaconBlock(block) - require.NoError(t, err) - - h, err := signedBlock.Header() - require.NoError(t, err) - - err = st.SetLatestBlockHeader(h.Header) - require.NoError(t, err) - stateRoot, err := st.HashTreeRoot(ctx) - require.NoError(t, err) - - // get a new signed block so the root is updated with the new state root - block.Block.StateRoot = stateRoot[:] - signedBlock, err = blocks.NewSignedBeaconBlock(block) - require.NoError(t, err) - - root, err := block.Block.HashTreeRoot() - require.NoError(t, err) - - mockBlocker := &testutil.MockBlocker{ - RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ - parentRoot: signedParent, - root: signedBlock, - }, - SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ - slot.Sub(1): signedParent, - slot: signedBlock, - }, - } - mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st, FinalizedRoots: map[[32]byte]bool{ - root: true, - }} - s := &Server{ - Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ - slot.Sub(1): attestedState, - slot: st, - }}, - Blocker: mockBlocker, - HeadFetcher: mockChainService, - } - request := httptest.NewRequest("GET", "http://foo.com", nil) - writer := httptest.NewRecorder() - writer.Body = &bytes.Buffer{} - - s.GetLightClientOptimisticUpdate(writer, request) - - require.Equal(t, http.StatusOK, writer.Code) - var resp *structs.LightClientUpdateResponse - err = json.Unmarshal(writer.Body.Bytes(), &resp) - require.NoError(t, err) - var respHeader structs.LightClientHeader - err = json.Unmarshal(resp.Data.AttestedHeader, &respHeader) - require.NoError(t, err) - require.Equal(t, "altair", resp.Version) - require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot) - require.NotNil(t, resp.Data) -} - -func TestLightClientHandler_GetLightClientOptimisticUpdateCapella(t *testing.T) { - helpers.ClearCache() - ctx := context.Background() - params.SetupTestConfigCleanup(t) - config := params.BeaconConfig() - slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) - - attestedState, err := util.NewBeaconStateCapella() - require.NoError(t, err) - err = attestedState.SetSlot(slot.Sub(1)) - require.NoError(t, err) - - require.NoError(t, attestedState.SetFinalizedCheckpoint(ðpb.Checkpoint{ - Epoch: config.AltairForkEpoch - 10, - Root: make([]byte, 32), - })) - - parent := util.NewBeaconBlockCapella() - parent.Block.Slot = slot.Sub(1) - - signedParent, err := blocks.NewSignedBeaconBlock(parent) - require.NoError(t, err) - - parentHeader, err := signedParent.Header() - require.NoError(t, err) - attestedHeader := parentHeader.Header - - err = attestedState.SetLatestBlockHeader(attestedHeader) - require.NoError(t, err) - attestedStateRoot, err := attestedState.HashTreeRoot(ctx) - require.NoError(t, err) - - // get a new signed block so the root is updated with the new state root - parent.Block.StateRoot = attestedStateRoot[:] - signedParent, err = blocks.NewSignedBeaconBlock(parent) - require.NoError(t, err) - - st, err := util.NewBeaconStateCapella() - require.NoError(t, err) - err = st.SetSlot(slot) - require.NoError(t, err) - - parentRoot, err := signedParent.Block().HashTreeRoot() - require.NoError(t, err) - - block := util.NewBeaconBlockCapella() - block.Block.Slot = slot - block.Block.ParentRoot = parentRoot[:] - - for i := uint64(0); i < config.SyncCommitteeSize; i++ { - block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) - } - - signedBlock, err := blocks.NewSignedBeaconBlock(block) - require.NoError(t, err) - - h, err := signedBlock.Header() - require.NoError(t, err) - - err = st.SetLatestBlockHeader(h.Header) - require.NoError(t, err) - stateRoot, err := st.HashTreeRoot(ctx) - require.NoError(t, err) - - // get a new signed block so the root is updated with the new state root - block.Block.StateRoot = stateRoot[:] - signedBlock, err = blocks.NewSignedBeaconBlock(block) - require.NoError(t, err) - - root, err := block.Block.HashTreeRoot() - require.NoError(t, err) - - mockBlocker := &testutil.MockBlocker{ - RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ - parentRoot: signedParent, - root: signedBlock, - }, - SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ - slot.Sub(1): signedParent, - slot: signedBlock, - }, - } - mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st, FinalizedRoots: map[[32]byte]bool{ - root: true, - }} - s := &Server{ - Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ - slot.Sub(1): attestedState, - slot: st, - }}, - Blocker: mockBlocker, - HeadFetcher: mockChainService, - } - request := httptest.NewRequest("GET", "http://foo.com", nil) - writer := httptest.NewRecorder() - writer.Body = &bytes.Buffer{} - - s.GetLightClientOptimisticUpdate(writer, request) - - require.Equal(t, http.StatusOK, writer.Code) - var resp *structs.LightClientUpdateResponse - err = json.Unmarshal(writer.Body.Bytes(), &resp) - require.NoError(t, err) - var respHeader structs.LightClientHeaderCapella - err = json.Unmarshal(resp.Data.AttestedHeader, &respHeader) - require.NoError(t, err) - require.Equal(t, "capella", resp.Version) - require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot) - require.NotNil(t, resp.Data) -} - -func TestLightClientHandler_GetLightClientOptimisticUpdateDeneb(t *testing.T) { - helpers.ClearCache() - ctx := context.Background() - params.SetupTestConfigCleanup(t) - config := params.BeaconConfig() - slot := primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) - - attestedState, err := util.NewBeaconStateDeneb() - require.NoError(t, err) - err = attestedState.SetSlot(slot.Sub(1)) - require.NoError(t, err) - - require.NoError(t, attestedState.SetFinalizedCheckpoint(ðpb.Checkpoint{ - Epoch: config.AltairForkEpoch - 10, - Root: make([]byte, 32), - })) - - parent := util.NewBeaconBlockDeneb() - parent.Block.Slot = slot.Sub(1) - - signedParent, err := blocks.NewSignedBeaconBlock(parent) - require.NoError(t, err) - - parentHeader, err := signedParent.Header() - require.NoError(t, err) - attestedHeader := parentHeader.Header - - err = attestedState.SetLatestBlockHeader(attestedHeader) - require.NoError(t, err) - attestedStateRoot, err := attestedState.HashTreeRoot(ctx) - require.NoError(t, err) - - // get a new signed block so the root is updated with the new state root - parent.Block.StateRoot = attestedStateRoot[:] - signedParent, err = blocks.NewSignedBeaconBlock(parent) - require.NoError(t, err) - - st, err := util.NewBeaconStateDeneb() - require.NoError(t, err) - err = st.SetSlot(slot) - require.NoError(t, err) - - parentRoot, err := signedParent.Block().HashTreeRoot() - require.NoError(t, err) - - block := util.NewBeaconBlockDeneb() - block.Block.Slot = slot - block.Block.ParentRoot = parentRoot[:] - - for i := uint64(0); i < config.SyncCommitteeSize; i++ { - block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) - } - - signedBlock, err := blocks.NewSignedBeaconBlock(block) - require.NoError(t, err) - - h, err := signedBlock.Header() - require.NoError(t, err) - - err = st.SetLatestBlockHeader(h.Header) - require.NoError(t, err) - stateRoot, err := st.HashTreeRoot(ctx) - require.NoError(t, err) - - // get a new signed block so the root is updated with the new state root - block.Block.StateRoot = stateRoot[:] - signedBlock, err = blocks.NewSignedBeaconBlock(block) - require.NoError(t, err) - - root, err := block.Block.HashTreeRoot() - require.NoError(t, err) - - mockBlocker := &testutil.MockBlocker{ - RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ - parentRoot: signedParent, - root: signedBlock, - }, - SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ - slot.Sub(1): signedParent, - slot: signedBlock, - }, - } - mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st, FinalizedRoots: map[[32]byte]bool{ - root: true, - }} - s := &Server{ - Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ - slot.Sub(1): attestedState, - slot: st, - }}, - Blocker: mockBlocker, - HeadFetcher: mockChainService, - } - request := httptest.NewRequest("GET", "http://foo.com", nil) - writer := httptest.NewRecorder() - writer.Body = &bytes.Buffer{} - - s.GetLightClientOptimisticUpdate(writer, request) - - require.Equal(t, http.StatusOK, writer.Code) - var resp *structs.LightClientUpdateResponse - err = json.Unmarshal(writer.Body.Bytes(), &resp) - require.NoError(t, err) - var respHeader structs.LightClientHeaderDeneb - err = json.Unmarshal(resp.Data.AttestedHeader, &respHeader) - require.NoError(t, err) - require.Equal(t, "deneb", resp.Version) - require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot) - require.NotNil(t, resp.Data) -} - -func TestLightClientHandler_GetLightClientEventBlock(t *testing.T) { - helpers.ClearCache() - ctx := context.Background() - params.SetupTestConfigCleanup(t) - config := params.BeaconConfig() - slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) - - attestedState, err := util.NewBeaconStateCapella() - require.NoError(t, err) - err = attestedState.SetSlot(slot.Sub(1)) - require.NoError(t, err) - - require.NoError(t, attestedState.SetFinalizedCheckpoint(ðpb.Checkpoint{ - Epoch: config.AltairForkEpoch - 10, - Root: make([]byte, 32), - })) - - parent := util.NewBeaconBlockCapella() - parent.Block.Slot = slot.Sub(1) - - signedParent, err := blocks.NewSignedBeaconBlock(parent) - require.NoError(t, err) - - parentHeader, err := signedParent.Header() - require.NoError(t, err) - attestedHeader := parentHeader.Header - - err = attestedState.SetLatestBlockHeader(attestedHeader) - require.NoError(t, err) - attestedStateRoot, err := attestedState.HashTreeRoot(ctx) - require.NoError(t, err) - - // get a new signed block so the root is updated with the new state root - parent.Block.StateRoot = attestedStateRoot[:] - signedParent, err = blocks.NewSignedBeaconBlock(parent) - require.NoError(t, err) - - st, err := util.NewBeaconStateCapella() - require.NoError(t, err) - err = st.SetSlot(slot) - require.NoError(t, err) - - parentRoot, err := signedParent.Block().HashTreeRoot() - require.NoError(t, err) - - block := util.NewBeaconBlockCapella() - block.Block.Slot = slot - block.Block.ParentRoot = parentRoot[:] - - for i := uint64(0); i < config.SyncCommitteeSize; i++ { - block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) - } - - signedBlock, err := blocks.NewSignedBeaconBlock(block) - require.NoError(t, err) - - h, err := signedBlock.Header() - require.NoError(t, err) - - err = st.SetLatestBlockHeader(h.Header) - require.NoError(t, err) - stateRoot, err := st.HashTreeRoot(ctx) - require.NoError(t, err) - - // get a new signed block so the root is updated with the new state root - block.Block.StateRoot = stateRoot[:] - signedBlock, err = blocks.NewSignedBeaconBlock(block) - require.NoError(t, err) - - root, err := block.Block.HashTreeRoot() - require.NoError(t, err) - - mockBlocker := &testutil.MockBlocker{ - RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ - parentRoot: signedParent, - root: signedBlock, - }, - SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ - slot.Sub(1): signedParent, - slot: signedBlock, - }, - } - mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st, FinalizedRoots: map[[32]byte]bool{ - root: true, - }} - s := &Server{ - Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ - slot.Sub(1): attestedState, - slot: st, - }}, - Blocker: mockBlocker, - HeadFetcher: mockChainService, - } - - minSignaturesRequired := uint64(100) - eventBlock, err := s.suitableBlock(ctx, minSignaturesRequired) - - require.NoError(t, err) - require.NotNil(t, eventBlock) - require.Equal(t, slot, eventBlock.Block().Slot()) - syncAggregate, err := eventBlock.Block().Body().SyncAggregate() - require.NoError(t, err) - require.Equal(t, true, syncAggregate.SyncCommitteeBits.Count() >= minSignaturesRequired) -} - -func TestLightClientHandler_GetLightClientEventBlock_NeedFetchParent(t *testing.T) { - helpers.ClearCache() - ctx := context.Background() - params.SetupTestConfigCleanup(t) - config := params.BeaconConfig() - slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) - - attestedState, err := util.NewBeaconStateCapella() - require.NoError(t, err) - err = attestedState.SetSlot(slot.Sub(1)) - require.NoError(t, err) - - require.NoError(t, attestedState.SetFinalizedCheckpoint(ðpb.Checkpoint{ - Epoch: config.AltairForkEpoch - 10, - Root: make([]byte, 32), - })) - - parent := util.NewBeaconBlockCapella() - parent.Block.Slot = slot.Sub(1) - for i := uint64(0); i < config.SyncCommitteeSize; i++ { - parent.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) - } - - signedParent, err := blocks.NewSignedBeaconBlock(parent) - require.NoError(t, err) - - parentHeader, err := signedParent.Header() - require.NoError(t, err) - attestedHeader := parentHeader.Header - - err = attestedState.SetLatestBlockHeader(attestedHeader) - require.NoError(t, err) - attestedStateRoot, err := attestedState.HashTreeRoot(ctx) - require.NoError(t, err) - - // get a new signed block so the root is updated with the new state root - parent.Block.StateRoot = attestedStateRoot[:] - signedParent, err = blocks.NewSignedBeaconBlock(parent) - require.NoError(t, err) - - st, err := util.NewBeaconStateCapella() - require.NoError(t, err) - err = st.SetSlot(slot) - require.NoError(t, err) - - parentRoot, err := signedParent.Block().HashTreeRoot() - require.NoError(t, err) - - block := util.NewBeaconBlockCapella() - block.Block.Slot = slot - block.Block.ParentRoot = parentRoot[:] - - for i := uint64(0); i < 10; i++ { - block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) - } - - signedBlock, err := blocks.NewSignedBeaconBlock(block) - require.NoError(t, err) - - h, err := signedBlock.Header() - require.NoError(t, err) - - err = st.SetLatestBlockHeader(h.Header) - require.NoError(t, err) - stateRoot, err := st.HashTreeRoot(ctx) - require.NoError(t, err) - - // get a new signed block so the root is updated with the new state root - block.Block.StateRoot = stateRoot[:] - signedBlock, err = blocks.NewSignedBeaconBlock(block) - require.NoError(t, err) - - root, err := block.Block.HashTreeRoot() - require.NoError(t, err) - - mockBlocker := &testutil.MockBlocker{ - RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ - parentRoot: signedParent, - root: signedBlock, - }, - SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ - slot.Sub(1): signedParent, - slot: signedBlock, - }, - } - mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st, FinalizedRoots: map[[32]byte]bool{ - root: true, - }} - s := &Server{ - Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ - slot.Sub(1): attestedState, - slot: st, - }}, - Blocker: mockBlocker, - HeadFetcher: mockChainService, - } - - minSignaturesRequired := uint64(100) - eventBlock, err := s.suitableBlock(ctx, minSignaturesRequired) - - require.NoError(t, err) - require.NotNil(t, eventBlock) - syncAggregate, err := eventBlock.Block().Body().SyncAggregate() - require.NoError(t, err) - require.Equal(t, true, syncAggregate.SyncCommitteeBits.Count() >= minSignaturesRequired) - require.Equal(t, slot-1, eventBlock.Block().Slot()) -} - -// setupDB instantiates and returns a Store instance. -func setupDB(t testing.TB) *kv.Store { - db, err := kv.NewKVStore(context.Background(), t.TempDir()) - require.NoError(t, err, "Failed to instantiate DB") - t.Cleanup(func() { - require.NoError(t, db.Close(), "Failed to close database") - }) - return db -} +// +//import ( +// "bytes" +// "context" +// "encoding/json" +// "fmt" +// "net/http" +// "net/http/httptest" +// "strconv" +// "testing" +// +// "github.com/ethereum/go-ethereum/common/hexutil" +// "github.com/prysmaticlabs/prysm/v5/api/server/structs" +// mock "github.com/prysmaticlabs/prysm/v5/beacon-chain/blockchain/testing" +// "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/helpers" +// "github.com/prysmaticlabs/prysm/v5/beacon-chain/db/kv" +// "github.com/prysmaticlabs/prysm/v5/beacon-chain/rpc/testutil" +// "github.com/prysmaticlabs/prysm/v5/beacon-chain/state" +// "github.com/prysmaticlabs/prysm/v5/config/params" +// "github.com/prysmaticlabs/prysm/v5/consensus-types/blocks" +// "github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces" +// "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" +// enginev1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1" +// ethpbv1 "github.com/prysmaticlabs/prysm/v5/proto/eth/v1" +// ethpbv2 "github.com/prysmaticlabs/prysm/v5/proto/eth/v2" +// ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" +// "github.com/prysmaticlabs/prysm/v5/runtime/version" +// "github.com/prysmaticlabs/prysm/v5/testing/require" +// "github.com/prysmaticlabs/prysm/v5/testing/util" +//) +// +//func TestLightClientHandler_GetLightClientBootstrap_Altair(t *testing.T) { +// l := util.NewTestLightClient(t).SetupTestAltair() +// +// slot := l.State.Slot() +// stateRoot, err := l.State.HashTreeRoot(l.Ctx) +// require.NoError(t, err) +// +// mockBlocker := &testutil.MockBlocker{BlockToReturn: l.Block} +// mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot} +// s := &Server{ +// Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ +// slot: l.State, +// }}, +// Blocker: mockBlocker, +// HeadFetcher: mockChainService, +// } +// request := httptest.NewRequest("GET", "http://foo.com/", nil) +// request.SetPathValue("block_root", hexutil.Encode(stateRoot[:])) +// writer := httptest.NewRecorder() +// writer.Body = &bytes.Buffer{} +// +// s.GetLightClientBootstrap(writer, request) +// require.Equal(t, http.StatusOK, writer.Code) +// var resp structs.LightClientBootstrapResponse +// err = json.Unmarshal(writer.Body.Bytes(), &resp) +// require.NoError(t, err) +// var respHeader structs.LightClientHeader +// err = json.Unmarshal(resp.Data.Header, &respHeader) +// require.NoError(t, err) +// require.Equal(t, "altair", resp.Version) +// +// blockHeader, err := l.Block.Header() +// require.NoError(t, err) +// require.Equal(t, hexutil.Encode(blockHeader.Header.BodyRoot), respHeader.Beacon.BodyRoot) +// require.Equal(t, strconv.FormatUint(uint64(blockHeader.Header.Slot), 10), respHeader.Beacon.Slot) +// +// require.NotNil(t, resp.Data.CurrentSyncCommittee) +// require.NotNil(t, resp.Data.CurrentSyncCommitteeBranch) +//} +// +//func TestLightClientHandler_GetLightClientBootstrap_Bellatrix(t *testing.T) { +// l := util.NewTestLightClient(t).SetupTestBellatrix() +// +// slot := l.State.Slot() +// stateRoot, err := l.State.HashTreeRoot(l.Ctx) +// require.NoError(t, err) +// +// mockBlocker := &testutil.MockBlocker{BlockToReturn: l.Block} +// mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot} +// s := &Server{ +// Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ +// slot: l.State, +// }}, +// Blocker: mockBlocker, +// HeadFetcher: mockChainService, +// } +// request := httptest.NewRequest("GET", "http://foo.com/", nil) +// request.SetPathValue("block_root", hexutil.Encode(stateRoot[:])) +// writer := httptest.NewRecorder() +// writer.Body = &bytes.Buffer{} +// +// s.GetLightClientBootstrap(writer, request) +// require.Equal(t, http.StatusOK, writer.Code) +// var resp structs.LightClientBootstrapResponse +// err = json.Unmarshal(writer.Body.Bytes(), &resp) +// require.NoError(t, err) +// var respHeader structs.LightClientHeader +// err = json.Unmarshal(resp.Data.Header, &respHeader) +// require.NoError(t, err) +// require.Equal(t, "bellatrix", resp.Version) +// +// blockHeader, err := l.Block.Header() +// require.NoError(t, err) +// require.Equal(t, hexutil.Encode(blockHeader.Header.BodyRoot), respHeader.Beacon.BodyRoot) +// require.Equal(t, strconv.FormatUint(uint64(blockHeader.Header.Slot), 10), respHeader.Beacon.Slot) +// +// require.NotNil(t, resp.Data.CurrentSyncCommittee) +// require.NotNil(t, resp.Data.CurrentSyncCommitteeBranch) +//} +// +//func TestLightClientHandler_GetLightClientBootstrap_Capella(t *testing.T) { +// l := util.NewTestLightClient(t).SetupTestCapella(false) // result is same for true and false +// +// slot := l.State.Slot() +// stateRoot, err := l.State.HashTreeRoot(l.Ctx) +// require.NoError(t, err) +// +// mockBlocker := &testutil.MockBlocker{BlockToReturn: l.Block} +// mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot} +// s := &Server{ +// Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ +// slot: l.State, +// }}, +// Blocker: mockBlocker, +// HeadFetcher: mockChainService, +// } +// request := httptest.NewRequest("GET", "http://foo.com/", nil) +// request.SetPathValue("block_root", hexutil.Encode(stateRoot[:])) +// writer := httptest.NewRecorder() +// writer.Body = &bytes.Buffer{} +// +// s.GetLightClientBootstrap(writer, request) +// require.Equal(t, http.StatusOK, writer.Code) +// var resp structs.LightClientBootstrapResponse +// err = json.Unmarshal(writer.Body.Bytes(), &resp) +// require.NoError(t, err) +// var respHeader structs.LightClientHeader +// err = json.Unmarshal(resp.Data.Header, &respHeader) +// require.NoError(t, err) +// require.Equal(t, "capella", resp.Version) +// +// blockHeader, err := l.Block.Header() +// require.NoError(t, err) +// require.Equal(t, hexutil.Encode(blockHeader.Header.BodyRoot), respHeader.Beacon.BodyRoot) +// require.Equal(t, strconv.FormatUint(uint64(blockHeader.Header.Slot), 10), respHeader.Beacon.Slot) +// +// require.NotNil(t, resp.Data.CurrentSyncCommittee) +// require.NotNil(t, resp.Data.CurrentSyncCommitteeBranch) +//} +// +//func TestLightClientHandler_GetLightClientBootstrap_Deneb(t *testing.T) { +// l := util.NewTestLightClient(t).SetupTestDeneb(false) // result is same for true and false +// +// slot := l.State.Slot() +// stateRoot, err := l.State.HashTreeRoot(l.Ctx) +// require.NoError(t, err) +// +// mockBlocker := &testutil.MockBlocker{BlockToReturn: l.Block} +// mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot} +// s := &Server{ +// Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ +// slot: l.State, +// }}, +// Blocker: mockBlocker, +// HeadFetcher: mockChainService, +// } +// request := httptest.NewRequest("GET", "http://foo.com/", nil) +// request.SetPathValue("block_root", hexutil.Encode(stateRoot[:])) +// writer := httptest.NewRecorder() +// writer.Body = &bytes.Buffer{} +// +// s.GetLightClientBootstrap(writer, request) +// require.Equal(t, http.StatusOK, writer.Code) +// var resp structs.LightClientBootstrapResponse +// err = json.Unmarshal(writer.Body.Bytes(), &resp) +// require.NoError(t, err) +// var respHeader structs.LightClientHeader +// err = json.Unmarshal(resp.Data.Header, &respHeader) +// require.NoError(t, err) +// require.Equal(t, "deneb", resp.Version) +// +// blockHeader, err := l.Block.Header() +// require.NoError(t, err) +// require.Equal(t, hexutil.Encode(blockHeader.Header.BodyRoot), respHeader.Beacon.BodyRoot) +// require.Equal(t, strconv.FormatUint(uint64(blockHeader.Header.Slot), 10), respHeader.Beacon.Slot) +// +// require.NotNil(t, resp.Data.CurrentSyncCommittee) +// require.NotNil(t, resp.Data.CurrentSyncCommitteeBranch) +//} +// +//func TestLightClientHandler_GetLightClientBootstrap_Electra(t *testing.T) { +// l := util.NewTestLightClient(t).SetupTestElectra(false) // result is same for true and false +// +// slot := l.State.Slot() +// stateRoot, err := l.State.HashTreeRoot(l.Ctx) +// require.NoError(t, err) +// +// mockBlocker := &testutil.MockBlocker{BlockToReturn: l.Block} +// mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot} +// s := &Server{ +// Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ +// slot: l.State, +// }}, +// Blocker: mockBlocker, +// HeadFetcher: mockChainService, +// } +// request := httptest.NewRequest("GET", "http://foo.com/", nil) +// request.SetPathValue("block_root", hexutil.Encode(stateRoot[:])) +// writer := httptest.NewRecorder() +// writer.Body = &bytes.Buffer{} +// +// s.GetLightClientBootstrap(writer, request) +// require.Equal(t, http.StatusOK, writer.Code) +// var resp structs.LightClientBootstrapResponse +// err = json.Unmarshal(writer.Body.Bytes(), &resp) +// require.NoError(t, err) +// var respHeader structs.LightClientHeader +// err = json.Unmarshal(resp.Data.Header, &respHeader) +// require.NoError(t, err) +// require.Equal(t, "electra", resp.Version) +// +// blockHeader, err := l.Block.Header() +// require.NoError(t, err) +// require.Equal(t, hexutil.Encode(blockHeader.Header.BodyRoot), respHeader.Beacon.BodyRoot) +// require.Equal(t, strconv.FormatUint(uint64(blockHeader.Header.Slot), 10), respHeader.Beacon.Slot) +// +// require.NotNil(t, resp.Data.CurrentSyncCommittee) +// require.NotNil(t, resp.Data.CurrentSyncCommitteeBranch) +//} +// +//// GetLightClientByRange tests +// +//func TestLightClientHandler_GetLightClientUpdatesByRangeAltair(t *testing.T) { +// helpers.ClearCache() +// ctx := context.Background() +// +// params.SetupTestConfigCleanup(t) +// config := params.BeaconConfig() +// config.AltairForkEpoch = 0 +// params.OverrideBeaconConfig(config) +// +// slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) +// +// st, err := util.NewBeaconStateAltair() +// require.NoError(t, err) +// err = st.SetSlot(slot) +// require.NoError(t, err) +// +// db := setupDB(t) +// +// updatePeriod := uint64(slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch))) +// +// update := ðpbv2.LightClientUpdate{ +// AttestedHeader: ðpbv2.LightClientHeaderContainer{ +// Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ +// HeaderAltair: ðpbv2.LightClientHeader{ +// Beacon: ðpbv1.BeaconBlockHeader{ +// Slot: slot.Sub(1), +// ProposerIndex: 1, +// ParentRoot: []byte{1, 1, 1}, +// StateRoot: []byte{1, 1, 1}, +// BodyRoot: []byte{1, 1, 1}, +// }, +// }, +// }, +// }, +// NextSyncCommittee: ðpbv2.SyncCommittee{ +// Pubkeys: nil, +// AggregatePubkey: nil, +// }, +// NextSyncCommitteeBranch: nil, +// FinalizedHeader: nil, +// FinalityBranch: nil, +// SyncAggregate: ðpbv1.SyncAggregate{ +// SyncCommitteeBits: []byte{1, 1, 1}, +// SyncCommitteeSignature: []byte{1, 1, 1}, +// }, +// SignatureSlot: 7, +// } +// +// err = db.SaveLightClientUpdate(ctx, updatePeriod, ðpbv2.LightClientUpdateWithVersion{ +// Version: version.Altair, +// Data: update, +// }) +// require.NoError(t, err) +// +// mockChainService := &mock.ChainService{State: st} +// s := &Server{ +// HeadFetcher: mockChainService, +// BeaconDB: db, +// } +// startPeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) +// url := fmt.Sprintf("http://foo.com/?count=1&start_period=%d", startPeriod) +// request := httptest.NewRequest("GET", url, nil) +// writer := httptest.NewRecorder() +// writer.Body = &bytes.Buffer{} +// +// s.GetLightClientUpdatesByRange(writer, request) +// +// require.Equal(t, http.StatusOK, writer.Code) +// var resp structs.LightClientUpdatesByRangeResponse +// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) +// require.NoError(t, err) +// require.Equal(t, 1, len(resp.Updates)) +// require.Equal(t, "altair", resp.Updates[0].Version) +// updateJson, err := structs.LightClientUpdateFromConsensus(update) +// require.NoError(t, err) +// require.DeepEqual(t, updateJson, resp.Updates[0].Data) +//} +// +//func TestLightClientHandler_GetLightClientUpdatesByRangeCapella(t *testing.T) { +// helpers.ClearCache() +// ctx := context.Background() +// params.SetupTestConfigCleanup(t) +// config := params.BeaconConfig() +// config.AltairForkEpoch = 0 +// config.CapellaForkEpoch = 1 +// params.OverrideBeaconConfig(config) +// slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) +// +// st, err := util.NewBeaconStateCapella() +// require.NoError(t, err) +// err = st.SetSlot(slot) +// require.NoError(t, err) +// +// db := setupDB(t) +// +// updatePeriod := uint64(slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch))) +// +// update := ðpbv2.LightClientUpdate{ +// AttestedHeader: ðpbv2.LightClientHeaderContainer{ +// Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ +// HeaderCapella: ðpbv2.LightClientHeaderCapella{ +// Beacon: ðpbv1.BeaconBlockHeader{ +// Slot: slot.Sub(1), +// ProposerIndex: 1, +// ParentRoot: []byte{1, 1, 1}, +// StateRoot: []byte{1, 1, 1}, +// BodyRoot: []byte{1, 1, 1}, +// }, +// Execution: &enginev1.ExecutionPayloadHeaderCapella{ +// FeeRecipient: []byte{1, 2, 3}, +// }, +// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, +// }, +// }, +// }, +// NextSyncCommittee: ðpbv2.SyncCommittee{ +// Pubkeys: nil, +// AggregatePubkey: nil, +// }, +// NextSyncCommitteeBranch: nil, +// FinalizedHeader: ðpbv2.LightClientHeaderContainer{ +// Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ +// HeaderCapella: ðpbv2.LightClientHeaderCapella{ +// Beacon: ðpbv1.BeaconBlockHeader{ +// Slot: 12, +// ProposerIndex: 1, +// ParentRoot: []byte{1, 1, 1}, +// StateRoot: []byte{1, 1, 1}, +// BodyRoot: []byte{1, 1, 1}, +// }, +// Execution: &enginev1.ExecutionPayloadHeaderCapella{ +// FeeRecipient: []byte{1, 2, 3}, +// }, +// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, +// }, +// }, +// }, +// FinalityBranch: nil, +// SyncAggregate: ðpbv1.SyncAggregate{ +// SyncCommitteeBits: []byte{1, 1, 1}, +// SyncCommitteeSignature: []byte{1, 1, 1}, +// }, +// SignatureSlot: 7, +// } +// +// err = db.SaveLightClientUpdate(ctx, updatePeriod, ðpbv2.LightClientUpdateWithVersion{ +// Version: version.Capella, +// Data: update, +// }) +// require.NoError(t, err) +// +// mockChainService := &mock.ChainService{State: st} +// s := &Server{ +// HeadFetcher: mockChainService, +// BeaconDB: db, +// } +// startPeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) +// url := fmt.Sprintf("http://foo.com/?count=1&start_period=%d", startPeriod) +// request := httptest.NewRequest("GET", url, nil) +// writer := httptest.NewRecorder() +// writer.Body = &bytes.Buffer{} +// +// s.GetLightClientUpdatesByRange(writer, request) +// +// require.Equal(t, http.StatusOK, writer.Code) +// var resp structs.LightClientUpdatesByRangeResponse +// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) +// require.NoError(t, err) +// require.Equal(t, 1, len(resp.Updates)) +// require.Equal(t, "capella", resp.Updates[0].Version) +// updateJson, err := structs.LightClientUpdateFromConsensus(update) +// require.NoError(t, err) +// require.DeepEqual(t, updateJson, resp.Updates[0].Data) +//} +// +//func TestLightClientHandler_GetLightClientUpdatesByRangeDeneb(t *testing.T) { +// helpers.ClearCache() +// ctx := context.Background() +// params.SetupTestConfigCleanup(t) +// config := params.BeaconConfig() +// config.AltairForkEpoch = 0 +// config.DenebForkEpoch = 1 +// params.OverrideBeaconConfig(config) +// slot := primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) +// +// st, err := util.NewBeaconStateDeneb() +// require.NoError(t, err) +// err = st.SetSlot(slot) +// require.NoError(t, err) +// +// db := setupDB(t) +// +// updatePeriod := uint64(slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch))) +// +// update := ðpbv2.LightClientUpdate{ +// AttestedHeader: ðpbv2.LightClientHeaderContainer{ +// Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ +// HeaderCapella: ðpbv2.LightClientHeaderCapella{ +// Beacon: ðpbv1.BeaconBlockHeader{ +// Slot: slot.Sub(1), +// ProposerIndex: 1, +// ParentRoot: []byte{1, 1, 1}, +// StateRoot: []byte{1, 1, 1}, +// BodyRoot: []byte{1, 1, 1}, +// }, +// Execution: &enginev1.ExecutionPayloadHeaderCapella{ +// FeeRecipient: []byte{1, 2, 3}, +// }, +// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, +// }, +// }, +// }, +// NextSyncCommittee: ðpbv2.SyncCommittee{ +// Pubkeys: nil, +// AggregatePubkey: nil, +// }, +// NextSyncCommitteeBranch: nil, +// FinalizedHeader: ðpbv2.LightClientHeaderContainer{ +// Header: ðpbv2.LightClientHeaderContainer_HeaderDeneb{ +// HeaderDeneb: ðpbv2.LightClientHeaderDeneb{ +// Beacon: ðpbv1.BeaconBlockHeader{ +// Slot: 12, +// ProposerIndex: 1, +// ParentRoot: []byte{1, 1, 1}, +// StateRoot: []byte{1, 1, 1}, +// BodyRoot: []byte{1, 1, 1}, +// }, +// Execution: &enginev1.ExecutionPayloadHeaderDeneb{ +// FeeRecipient: []byte{1, 2, 3}, +// }, +// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, +// }, +// }, +// }, +// FinalityBranch: nil, +// SyncAggregate: ðpbv1.SyncAggregate{ +// SyncCommitteeBits: []byte{1, 1, 1}, +// SyncCommitteeSignature: []byte{1, 1, 1}, +// }, +// SignatureSlot: 7, +// } +// +// err = db.SaveLightClientUpdate(ctx, updatePeriod, ðpbv2.LightClientUpdateWithVersion{ +// Version: version.Deneb, +// Data: update, +// }) +// require.NoError(t, err) +// +// mockChainService := &mock.ChainService{State: st} +// s := &Server{ +// HeadFetcher: mockChainService, +// BeaconDB: db, +// } +// startPeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) +// url := fmt.Sprintf("http://foo.com/?count=1&start_period=%d", startPeriod) +// request := httptest.NewRequest("GET", url, nil) +// writer := httptest.NewRecorder() +// writer.Body = &bytes.Buffer{} +// +// s.GetLightClientUpdatesByRange(writer, request) +// +// require.Equal(t, http.StatusOK, writer.Code) +// var resp structs.LightClientUpdatesByRangeResponse +// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) +// require.NoError(t, err) +// require.Equal(t, 1, len(resp.Updates)) +// require.Equal(t, "deneb", resp.Updates[0].Version) +// updateJson, err := structs.LightClientUpdateFromConsensus(update) +// require.NoError(t, err) +// require.DeepEqual(t, updateJson, resp.Updates[0].Data) +//} +// +//func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleAltair(t *testing.T) { +// helpers.ClearCache() +// ctx := context.Background() +// params.SetupTestConfigCleanup(t) +// config := params.BeaconConfig() +// config.AltairForkEpoch = 0 +// config.EpochsPerSyncCommitteePeriod = 1 +// params.OverrideBeaconConfig(config) +// slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) +// +// st, err := util.NewBeaconStateAltair() +// require.NoError(t, err) +// headSlot := slot.Add(33) // 2 periods +// err = st.SetSlot(headSlot) +// require.NoError(t, err) +// +// db := setupDB(t) +// +// updates := make([]*ethpbv2.LightClientUpdate, 2) +// +// updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) +// +// for i := 0; i < 2; i++ { +// newSlot := slot.Add(uint64(i)) +// +// update := ðpbv2.LightClientUpdate{ +// AttestedHeader: ðpbv2.LightClientHeaderContainer{ +// Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ +// HeaderAltair: ðpbv2.LightClientHeader{ +// Beacon: ðpbv1.BeaconBlockHeader{ +// Slot: newSlot, +// ProposerIndex: 1, +// ParentRoot: []byte{1, 1, 1}, +// StateRoot: []byte{1, 1, 1}, +// BodyRoot: []byte{1, 1, 1}, +// }, +// }, +// }, +// }, +// NextSyncCommittee: ðpbv2.SyncCommittee{ +// Pubkeys: nil, +// AggregatePubkey: nil, +// }, +// NextSyncCommitteeBranch: nil, +// FinalizedHeader: nil, +// FinalityBranch: nil, +// SyncAggregate: ðpbv1.SyncAggregate{ +// SyncCommitteeBits: []byte{1, 1, 1}, +// SyncCommitteeSignature: []byte{1, 1, 1}, +// }, +// SignatureSlot: 7, +// } +// +// updates[i] = update +// +// err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ +// Version: version.Altair, +// Data: update, +// }) +// require.NoError(t, err) +// +// updatePeriod++ +// } +// +// mockChainService := &mock.ChainService{State: st} +// s := &Server{ +// HeadFetcher: mockChainService, +// BeaconDB: db, +// } +// startPeriod := slot.Sub(1).Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) +// url := fmt.Sprintf("http://foo.com/?count=100&start_period=%d", startPeriod) +// request := httptest.NewRequest("GET", url, nil) +// writer := httptest.NewRecorder() +// writer.Body = &bytes.Buffer{} +// +// s.GetLightClientUpdatesByRange(writer, request) +// +// require.Equal(t, http.StatusOK, writer.Code) +// var resp structs.LightClientUpdatesByRangeResponse +// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) +// require.NoError(t, err) +// require.Equal(t, 2, len(resp.Updates)) +// for i, update := range updates { +// require.Equal(t, "altair", resp.Updates[i].Version) +// updateJson, err := structs.LightClientUpdateFromConsensus(update) +// require.NoError(t, err) +// require.DeepEqual(t, updateJson, resp.Updates[i].Data) +// } +//} +// +//func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleCapella(t *testing.T) { +// helpers.ClearCache() +// ctx := context.Background() +// params.SetupTestConfigCleanup(t) +// config := params.BeaconConfig() +// config.AltairForkEpoch = 0 +// config.CapellaForkEpoch = 1 +// config.EpochsPerSyncCommitteePeriod = 1 +// params.OverrideBeaconConfig(config) +// slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) +// +// st, err := util.NewBeaconStateAltair() +// require.NoError(t, err) +// headSlot := slot.Add(33) // 2 periods +// err = st.SetSlot(headSlot) +// require.NoError(t, err) +// +// db := setupDB(t) +// +// updates := make([]*ethpbv2.LightClientUpdate, 2) +// +// updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) +// +// for i := 0; i < 2; i++ { +// +// newSlot := slot.Add(uint64(i)) +// +// update := ðpbv2.LightClientUpdate{ +// AttestedHeader: ðpbv2.LightClientHeaderContainer{ +// Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ +// HeaderCapella: ðpbv2.LightClientHeaderCapella{ +// Beacon: ðpbv1.BeaconBlockHeader{ +// Slot: newSlot, +// ProposerIndex: 1, +// ParentRoot: []byte{1, 1, 1}, +// StateRoot: []byte{1, 1, 1}, +// BodyRoot: []byte{1, 1, 1}, +// }, +// Execution: &enginev1.ExecutionPayloadHeaderCapella{ +// FeeRecipient: []byte{1, 2, 3}, +// }, +// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, +// }, +// }, +// }, +// NextSyncCommittee: ðpbv2.SyncCommittee{ +// Pubkeys: nil, +// AggregatePubkey: nil, +// }, +// NextSyncCommitteeBranch: nil, +// FinalizedHeader: ðpbv2.LightClientHeaderContainer{ +// Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ +// HeaderCapella: ðpbv2.LightClientHeaderCapella{ +// Beacon: ðpbv1.BeaconBlockHeader{ +// Slot: 12, +// ProposerIndex: 1, +// ParentRoot: []byte{1, 1, 1}, +// StateRoot: []byte{1, 1, 1}, +// BodyRoot: []byte{1, 1, 1}, +// }, +// Execution: &enginev1.ExecutionPayloadHeaderCapella{ +// FeeRecipient: []byte{1, 2, 3}, +// }, +// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, +// }, +// }, +// }, +// FinalityBranch: nil, +// SyncAggregate: ðpbv1.SyncAggregate{ +// SyncCommitteeBits: []byte{1, 1, 1}, +// SyncCommitteeSignature: []byte{1, 1, 1}, +// }, +// SignatureSlot: 7, +// } +// +// updates[i] = update +// +// err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ +// Version: version.Capella, +// Data: update, +// }) +// require.NoError(t, err) +// +// updatePeriod++ +// } +// +// mockChainService := &mock.ChainService{State: st} +// s := &Server{ +// HeadFetcher: mockChainService, +// BeaconDB: db, +// } +// startPeriod := slot.Sub(1).Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) +// url := fmt.Sprintf("http://foo.com/?count=100&start_period=%d", startPeriod) +// request := httptest.NewRequest("GET", url, nil) +// writer := httptest.NewRecorder() +// writer.Body = &bytes.Buffer{} +// +// s.GetLightClientUpdatesByRange(writer, request) +// +// require.Equal(t, http.StatusOK, writer.Code) +// var resp structs.LightClientUpdatesByRangeResponse +// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) +// require.NoError(t, err) +// require.Equal(t, 2, len(resp.Updates)) +// for i, update := range updates { +// require.Equal(t, "capella", resp.Updates[i].Version) +// updateJson, err := structs.LightClientUpdateFromConsensus(update) +// require.NoError(t, err) +// require.DeepEqual(t, updateJson, resp.Updates[i].Data) +// } +//} +// +//func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleDeneb(t *testing.T) { +// helpers.ClearCache() +// ctx := context.Background() +// params.SetupTestConfigCleanup(t) +// config := params.BeaconConfig() +// config.AltairForkEpoch = 0 +// config.DenebForkEpoch = 1 +// config.EpochsPerSyncCommitteePeriod = 1 +// params.OverrideBeaconConfig(config) +// slot := primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) +// +// st, err := util.NewBeaconStateAltair() +// require.NoError(t, err) +// headSlot := slot.Add(33) +// err = st.SetSlot(headSlot) +// require.NoError(t, err) +// +// db := setupDB(t) +// +// updates := make([]*ethpbv2.LightClientUpdate, 2) +// +// updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) +// +// for i := 0; i < 2; i++ { +// +// newSlot := slot.Add(uint64(i)) +// +// update := ðpbv2.LightClientUpdate{ +// AttestedHeader: ðpbv2.LightClientHeaderContainer{ +// Header: ðpbv2.LightClientHeaderContainer_HeaderDeneb{ +// HeaderDeneb: ðpbv2.LightClientHeaderDeneb{ +// Beacon: ðpbv1.BeaconBlockHeader{ +// Slot: newSlot, +// ProposerIndex: 1, +// ParentRoot: []byte{1, 1, 1}, +// StateRoot: []byte{1, 1, 1}, +// BodyRoot: []byte{1, 1, 1}, +// }, +// Execution: &enginev1.ExecutionPayloadHeaderDeneb{ +// FeeRecipient: []byte{1, 2, 3}, +// }, +// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, +// }, +// }, +// }, +// NextSyncCommittee: ðpbv2.SyncCommittee{ +// Pubkeys: nil, +// AggregatePubkey: nil, +// }, +// NextSyncCommitteeBranch: nil, +// FinalizedHeader: ðpbv2.LightClientHeaderContainer{ +// Header: ðpbv2.LightClientHeaderContainer_HeaderDeneb{ +// HeaderDeneb: ðpbv2.LightClientHeaderDeneb{ +// Beacon: ðpbv1.BeaconBlockHeader{ +// Slot: 12, +// ProposerIndex: 1, +// ParentRoot: []byte{1, 1, 1}, +// StateRoot: []byte{1, 1, 1}, +// BodyRoot: []byte{1, 1, 1}, +// }, +// Execution: &enginev1.ExecutionPayloadHeaderDeneb{ +// FeeRecipient: []byte{1, 2, 3}, +// }, +// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, +// }, +// }, +// }, +// FinalityBranch: nil, +// SyncAggregate: ðpbv1.SyncAggregate{ +// SyncCommitteeBits: []byte{1, 1, 1}, +// SyncCommitteeSignature: []byte{1, 1, 1}, +// }, +// SignatureSlot: 7, +// } +// +// updates[i] = update +// +// err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ +// Version: version.Deneb, +// Data: update, +// }) +// require.NoError(t, err) +// +// updatePeriod++ +// } +// +// mockChainService := &mock.ChainService{State: st} +// s := &Server{ +// HeadFetcher: mockChainService, +// BeaconDB: db, +// } +// startPeriod := slot.Sub(1).Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) +// url := fmt.Sprintf("http://foo.com/?count=100&start_period=%d", startPeriod) +// request := httptest.NewRequest("GET", url, nil) +// writer := httptest.NewRecorder() +// writer.Body = &bytes.Buffer{} +// +// s.GetLightClientUpdatesByRange(writer, request) +// +// require.Equal(t, http.StatusOK, writer.Code) +// var resp structs.LightClientUpdatesByRangeResponse +// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) +// require.NoError(t, err) +// require.Equal(t, 2, len(resp.Updates)) +// for i, update := range updates { +// require.Equal(t, "deneb", resp.Updates[i].Version) +// updateJson, err := structs.LightClientUpdateFromConsensus(update) +// require.NoError(t, err) +// require.DeepEqual(t, updateJson, resp.Updates[i].Data) +// } +//} +// +//func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleForksAltairCapella(t *testing.T) { +// helpers.ClearCache() +// ctx := context.Background() +// params.SetupTestConfigCleanup(t) +// config := params.BeaconConfig() +// config.AltairForkEpoch = 0 +// config.CapellaForkEpoch = 1 +// config.EpochsPerSyncCommitteePeriod = 1 +// params.OverrideBeaconConfig(config) +// slotCapella := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) +// slotAltair := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) +// +// st, err := util.NewBeaconStateAltair() +// require.NoError(t, err) +// headSlot := slotCapella.Add(1) +// err = st.SetSlot(headSlot) +// require.NoError(t, err) +// +// db := setupDB(t) +// +// updates := make([]*ethpbv2.LightClientUpdate, 2) +// +// updatePeriod := slotAltair.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) +// +// update := ðpbv2.LightClientUpdate{ +// AttestedHeader: ðpbv2.LightClientHeaderContainer{ +// Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ +// HeaderAltair: ðpbv2.LightClientHeader{ +// Beacon: ðpbv1.BeaconBlockHeader{ +// Slot: slotAltair, +// ProposerIndex: 1, +// ParentRoot: []byte{1, 1, 1}, +// StateRoot: []byte{1, 1, 1}, +// BodyRoot: []byte{1, 1, 1}, +// }, +// }, +// }, +// }, +// NextSyncCommittee: ðpbv2.SyncCommittee{ +// Pubkeys: nil, +// AggregatePubkey: nil, +// }, +// NextSyncCommitteeBranch: nil, +// FinalizedHeader: ðpbv2.LightClientHeaderContainer{ +// Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ +// HeaderAltair: ðpbv2.LightClientHeader{ +// Beacon: ðpbv1.BeaconBlockHeader{ +// Slot: 12, +// ProposerIndex: 1, +// ParentRoot: []byte{1, 1, 1}, +// StateRoot: []byte{1, 1, 1}, +// BodyRoot: []byte{1, 1, 1}, +// }, +// }, +// }, +// }, +// FinalityBranch: nil, +// SyncAggregate: ðpbv1.SyncAggregate{ +// SyncCommitteeBits: []byte{1, 1, 1}, +// SyncCommitteeSignature: []byte{1, 1, 1}, +// }, +// SignatureSlot: slotAltair, +// } +// +// updates[0] = update +// +// err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ +// Version: version.Altair, +// Data: update, +// }) +// require.NoError(t, err) +// +// updatePeriod = slotCapella.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) +// +// update = ðpbv2.LightClientUpdate{ +// AttestedHeader: ðpbv2.LightClientHeaderContainer{ +// Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ +// HeaderCapella: ðpbv2.LightClientHeaderCapella{ +// Beacon: ðpbv1.BeaconBlockHeader{ +// Slot: slotCapella, +// ProposerIndex: 1, +// ParentRoot: []byte{1, 1, 1}, +// StateRoot: []byte{1, 1, 1}, +// BodyRoot: []byte{1, 1, 1}, +// }, +// Execution: &enginev1.ExecutionPayloadHeaderCapella{ +// FeeRecipient: []byte{1, 2, 3}, +// }, +// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, +// }, +// }, +// }, +// NextSyncCommittee: ðpbv2.SyncCommittee{ +// Pubkeys: nil, +// AggregatePubkey: nil, +// }, +// NextSyncCommitteeBranch: nil, +// FinalizedHeader: ðpbv2.LightClientHeaderContainer{ +// Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ +// HeaderCapella: ðpbv2.LightClientHeaderCapella{ +// Beacon: ðpbv1.BeaconBlockHeader{ +// Slot: 12, +// ProposerIndex: 1, +// ParentRoot: []byte{1, 1, 1}, +// StateRoot: []byte{1, 1, 1}, +// BodyRoot: []byte{1, 1, 1}, +// }, +// Execution: &enginev1.ExecutionPayloadHeaderCapella{ +// FeeRecipient: []byte{1, 2, 3}, +// }, +// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, +// }, +// }, +// }, +// FinalityBranch: nil, +// SyncAggregate: ðpbv1.SyncAggregate{ +// SyncCommitteeBits: []byte{1, 1, 1}, +// SyncCommitteeSignature: []byte{1, 1, 1}, +// }, +// SignatureSlot: slotCapella, +// } +// +// updates[1] = update +// +// err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ +// Version: version.Capella, +// Data: update, +// }) +// require.NoError(t, err) +// +// mockChainService := &mock.ChainService{State: st} +// s := &Server{ +// HeadFetcher: mockChainService, +// BeaconDB: db, +// } +// startPeriod := 0 +// url := fmt.Sprintf("http://foo.com/?count=100&start_period=%d", startPeriod) +// request := httptest.NewRequest("GET", url, nil) +// writer := httptest.NewRecorder() +// writer.Body = &bytes.Buffer{} +// +// s.GetLightClientUpdatesByRange(writer, request) +// +// require.Equal(t, http.StatusOK, writer.Code) +// var resp structs.LightClientUpdatesByRangeResponse +// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) +// require.NoError(t, err) +// require.Equal(t, 2, len(resp.Updates)) +// for i, update := range updates { +// if i < 1 { +// require.Equal(t, "altair", resp.Updates[i].Version) +// } else { +// require.Equal(t, "capella", resp.Updates[i].Version) +// } +// updateJson, err := structs.LightClientUpdateFromConsensus(update) +// require.NoError(t, err) +// require.DeepEqual(t, updateJson, resp.Updates[i].Data) +// } +//} +// +//func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleForksCapellaDeneb(t *testing.T) { +// helpers.ClearCache() +// ctx := context.Background() +// params.SetupTestConfigCleanup(t) +// config := params.BeaconConfig() +// config.AltairForkEpoch = 0 +// config.CapellaForkEpoch = 1 +// config.DenebForkEpoch = 2 +// config.EpochsPerSyncCommitteePeriod = 1 +// params.OverrideBeaconConfig(config) +// slotDeneb := primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) +// slotCapella := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) +// +// st, err := util.NewBeaconStateAltair() +// require.NoError(t, err) +// headSlot := slotDeneb.Add(1) +// err = st.SetSlot(headSlot) +// require.NoError(t, err) +// +// db := setupDB(t) +// +// updates := make([]*ethpbv2.LightClientUpdate, 2) +// +// updatePeriod := slotCapella.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) +// +// update := ðpbv2.LightClientUpdate{ +// AttestedHeader: ðpbv2.LightClientHeaderContainer{ +// Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ +// HeaderCapella: ðpbv2.LightClientHeaderCapella{ +// Beacon: ðpbv1.BeaconBlockHeader{ +// Slot: slotCapella, +// ProposerIndex: 1, +// ParentRoot: []byte{1, 1, 1}, +// StateRoot: []byte{1, 1, 1}, +// BodyRoot: []byte{1, 1, 1}, +// }, +// Execution: &enginev1.ExecutionPayloadHeaderCapella{ +// FeeRecipient: []byte{1, 2, 3}, +// }, +// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, +// }, +// }, +// }, +// NextSyncCommittee: ðpbv2.SyncCommittee{ +// Pubkeys: nil, +// AggregatePubkey: nil, +// }, +// NextSyncCommitteeBranch: nil, +// FinalizedHeader: ðpbv2.LightClientHeaderContainer{ +// Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ +// HeaderCapella: ðpbv2.LightClientHeaderCapella{ +// Beacon: ðpbv1.BeaconBlockHeader{ +// Slot: 12, +// ProposerIndex: 1, +// ParentRoot: []byte{1, 1, 1}, +// StateRoot: []byte{1, 1, 1}, +// BodyRoot: []byte{1, 1, 1}, +// }, +// Execution: &enginev1.ExecutionPayloadHeaderCapella{ +// FeeRecipient: []byte{1, 2, 3}, +// }, +// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, +// }, +// }, +// }, +// FinalityBranch: nil, +// SyncAggregate: ðpbv1.SyncAggregate{ +// SyncCommitteeBits: []byte{1, 1, 1}, +// SyncCommitteeSignature: []byte{1, 1, 1}, +// }, +// SignatureSlot: slotCapella, +// } +// +// updates[0] = update +// +// err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ +// Version: version.Capella, +// Data: update, +// }) +// require.NoError(t, err) +// +// updatePeriod = slotDeneb.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) +// +// update = ðpbv2.LightClientUpdate{ +// AttestedHeader: ðpbv2.LightClientHeaderContainer{ +// Header: ðpbv2.LightClientHeaderContainer_HeaderDeneb{ +// HeaderDeneb: ðpbv2.LightClientHeaderDeneb{ +// Beacon: ðpbv1.BeaconBlockHeader{ +// Slot: slotDeneb, +// ProposerIndex: 1, +// ParentRoot: []byte{1, 1, 1}, +// StateRoot: []byte{1, 1, 1}, +// BodyRoot: []byte{1, 1, 1}, +// }, +// Execution: &enginev1.ExecutionPayloadHeaderDeneb{ +// FeeRecipient: []byte{1, 2, 3}, +// }, +// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, +// }, +// }, +// }, +// NextSyncCommittee: ðpbv2.SyncCommittee{ +// Pubkeys: nil, +// AggregatePubkey: nil, +// }, +// NextSyncCommitteeBranch: nil, +// FinalizedHeader: ðpbv2.LightClientHeaderContainer{ +// Header: ðpbv2.LightClientHeaderContainer_HeaderDeneb{ +// HeaderDeneb: ðpbv2.LightClientHeaderDeneb{ +// Beacon: ðpbv1.BeaconBlockHeader{ +// Slot: 12, +// ProposerIndex: 1, +// ParentRoot: []byte{1, 1, 1}, +// StateRoot: []byte{1, 1, 1}, +// BodyRoot: []byte{1, 1, 1}, +// }, +// Execution: &enginev1.ExecutionPayloadHeaderDeneb{ +// FeeRecipient: []byte{1, 2, 3}, +// }, +// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, +// }, +// }, +// }, +// FinalityBranch: nil, +// SyncAggregate: ðpbv1.SyncAggregate{ +// SyncCommitteeBits: []byte{1, 1, 1}, +// SyncCommitteeSignature: []byte{1, 1, 1}, +// }, +// SignatureSlot: slotDeneb, +// } +// +// updates[1] = update +// +// err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ +// Version: version.Deneb, +// Data: update, +// }) +// require.NoError(t, err) +// +// mockChainService := &mock.ChainService{State: st} +// s := &Server{ +// HeadFetcher: mockChainService, +// BeaconDB: db, +// } +// startPeriod := 1 +// url := fmt.Sprintf("http://foo.com/?count=100&start_period=%d", startPeriod) +// request := httptest.NewRequest("GET", url, nil) +// writer := httptest.NewRecorder() +// writer.Body = &bytes.Buffer{} +// +// s.GetLightClientUpdatesByRange(writer, request) +// +// require.Equal(t, http.StatusOK, writer.Code) +// var resp structs.LightClientUpdatesByRangeResponse +// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) +// require.NoError(t, err) +// require.Equal(t, 2, len(resp.Updates)) +// for i, update := range updates { +// if i < 1 { +// require.Equal(t, "capella", resp.Updates[i].Version) +// } else { +// require.Equal(t, "deneb", resp.Updates[i].Version) +// } +// updateJson, err := structs.LightClientUpdateFromConsensus(update) +// require.NoError(t, err) +// require.DeepEqual(t, updateJson, resp.Updates[i].Data) +// } +//} +// +//func TestLightClientHandler_GetLightClientUpdatesByRangeCountBiggerThanLimit(t *testing.T) { +// helpers.ClearCache() +// ctx := context.Background() +// params.SetupTestConfigCleanup(t) +// config := params.BeaconConfig() +// config.AltairForkEpoch = 0 +// config.EpochsPerSyncCommitteePeriod = 1 +// config.MaxRequestLightClientUpdates = 2 +// params.OverrideBeaconConfig(config) +// slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) +// +// st, err := util.NewBeaconStateAltair() +// require.NoError(t, err) +// headSlot := slot.Add(65) +// err = st.SetSlot(headSlot) +// require.NoError(t, err) +// +// db := setupDB(t) +// +// updates := make([]*ethpbv2.LightClientUpdate, 3) +// +// updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) +// +// for i := 0; i < 3; i++ { +// newSlot := slot.Add(uint64(i * 32)) +// +// update := ðpbv2.LightClientUpdate{ +// AttestedHeader: ðpbv2.LightClientHeaderContainer{ +// Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ +// HeaderAltair: ðpbv2.LightClientHeader{ +// Beacon: ðpbv1.BeaconBlockHeader{ +// Slot: newSlot, +// ProposerIndex: 1, +// ParentRoot: []byte{1, 1, 1}, +// StateRoot: []byte{1, 1, 1}, +// BodyRoot: []byte{1, 1, 1}, +// }, +// }, +// }, +// }, +// NextSyncCommittee: ðpbv2.SyncCommittee{ +// Pubkeys: nil, +// AggregatePubkey: nil, +// }, +// NextSyncCommitteeBranch: nil, +// FinalizedHeader: nil, +// FinalityBranch: nil, +// SyncAggregate: ðpbv1.SyncAggregate{ +// SyncCommitteeBits: []byte{1, 1, 1}, +// SyncCommitteeSignature: []byte{1, 1, 1}, +// }, +// SignatureSlot: 7, +// } +// +// updates[i] = update +// +// err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ +// Version: version.Altair, +// Data: update, +// }) +// require.NoError(t, err) +// +// updatePeriod++ +// } +// +// mockChainService := &mock.ChainService{State: st} +// s := &Server{ +// HeadFetcher: mockChainService, +// BeaconDB: db, +// } +// startPeriod := 0 +// url := fmt.Sprintf("http://foo.com/?count=4&start_period=%d", startPeriod) +// request := httptest.NewRequest("GET", url, nil) +// writer := httptest.NewRecorder() +// writer.Body = &bytes.Buffer{} +// +// s.GetLightClientUpdatesByRange(writer, request) +// +// require.Equal(t, http.StatusOK, writer.Code) +// var resp structs.LightClientUpdatesByRangeResponse +// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) +// require.NoError(t, err) +// require.Equal(t, 2, len(resp.Updates)) +// for i, update := range updates { +// if i < 2 { +// require.Equal(t, "altair", resp.Updates[i].Version) +// updateJson, err := structs.LightClientUpdateFromConsensus(update) +// require.NoError(t, err) +// require.DeepEqual(t, updateJson, resp.Updates[i].Data) +// } +// } +//} +// +//func TestLightClientHandler_GetLightClientUpdatesByRangeCountBiggerThanMax(t *testing.T) { +// helpers.ClearCache() +// ctx := context.Background() +// params.SetupTestConfigCleanup(t) +// config := params.BeaconConfig() +// config.AltairForkEpoch = 0 +// config.EpochsPerSyncCommitteePeriod = 1 +// config.MaxRequestLightClientUpdates = 2 +// params.OverrideBeaconConfig(config) +// slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) +// +// st, err := util.NewBeaconStateAltair() +// require.NoError(t, err) +// headSlot := slot.Add(65) +// err = st.SetSlot(headSlot) +// require.NoError(t, err) +// +// db := setupDB(t) +// +// updates := make([]*ethpbv2.LightClientUpdate, 3) +// +// updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) +// +// for i := 0; i < 3; i++ { +// newSlot := slot.Add(uint64(i * 32)) +// +// update := ðpbv2.LightClientUpdate{ +// AttestedHeader: ðpbv2.LightClientHeaderContainer{ +// Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ +// HeaderAltair: ðpbv2.LightClientHeader{ +// Beacon: ðpbv1.BeaconBlockHeader{ +// Slot: newSlot, +// ProposerIndex: 1, +// ParentRoot: []byte{1, 1, 1}, +// StateRoot: []byte{1, 1, 1}, +// BodyRoot: []byte{1, 1, 1}, +// }, +// }, +// }, +// }, +// NextSyncCommittee: ðpbv2.SyncCommittee{ +// Pubkeys: nil, +// AggregatePubkey: nil, +// }, +// NextSyncCommitteeBranch: nil, +// FinalizedHeader: nil, +// FinalityBranch: nil, +// SyncAggregate: ðpbv1.SyncAggregate{ +// SyncCommitteeBits: []byte{1, 1, 1}, +// SyncCommitteeSignature: []byte{1, 1, 1}, +// }, +// SignatureSlot: 7, +// } +// +// updates[i] = update +// err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ +// Version: version.Altair, +// Data: update, +// }) +// require.NoError(t, err) +// +// updatePeriod++ +// } +// +// mockChainService := &mock.ChainService{State: st} +// s := &Server{ +// HeadFetcher: mockChainService, +// BeaconDB: db, +// } +// startPeriod := 0 +// url := fmt.Sprintf("http://foo.com/?count=10&start_period=%d", startPeriod) +// request := httptest.NewRequest("GET", url, nil) +// writer := httptest.NewRecorder() +// writer.Body = &bytes.Buffer{} +// +// s.GetLightClientUpdatesByRange(writer, request) +// +// require.Equal(t, http.StatusOK, writer.Code) +// var resp structs.LightClientUpdatesByRangeResponse +// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) +// require.NoError(t, err) +// require.Equal(t, 2, len(resp.Updates)) +// for i, update := range updates { +// if i < 2 { +// require.Equal(t, "altair", resp.Updates[i].Version) +// updateJson, err := structs.LightClientUpdateFromConsensus(update) +// require.NoError(t, err) +// require.DeepEqual(t, updateJson, resp.Updates[i].Data) +// } +// } +//} +// +//func TestLightClientHandler_GetLightClientUpdatesByRangeStartPeriodBeforeAltair(t *testing.T) { +// helpers.ClearCache() +// ctx := context.Background() +// params.SetupTestConfigCleanup(t) +// config := params.BeaconConfig() +// config.AltairForkEpoch = 1 +// config.EpochsPerSyncCommitteePeriod = 1 +// params.OverrideBeaconConfig(config) +// slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) +// +// st, err := util.NewBeaconStateAltair() +// require.NoError(t, err) +// headSlot := slot.Add(1) +// err = st.SetSlot(headSlot) +// require.NoError(t, err) +// +// db := setupDB(t) +// +// updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) +// +// update := ðpbv2.LightClientUpdate{ +// AttestedHeader: ðpbv2.LightClientHeaderContainer{ +// Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ +// HeaderAltair: ðpbv2.LightClientHeader{ +// Beacon: ðpbv1.BeaconBlockHeader{ +// Slot: slot, +// ProposerIndex: 1, +// ParentRoot: []byte{1, 1, 1}, +// StateRoot: []byte{1, 1, 1}, +// BodyRoot: []byte{1, 1, 1}, +// }, +// }, +// }, +// }, +// NextSyncCommittee: ðpbv2.SyncCommittee{ +// Pubkeys: nil, +// AggregatePubkey: nil, +// }, +// NextSyncCommitteeBranch: nil, +// FinalizedHeader: nil, +// FinalityBranch: nil, +// SyncAggregate: ðpbv1.SyncAggregate{ +// SyncCommitteeBits: []byte{1, 1, 1}, +// SyncCommitteeSignature: []byte{1, 1, 1}, +// }, +// SignatureSlot: 7, +// } +// +// err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ +// Version: version.Altair, +// Data: update, +// }) +// require.NoError(t, err) +// +// mockChainService := &mock.ChainService{State: st} +// s := &Server{ +// HeadFetcher: mockChainService, +// BeaconDB: db, +// } +// startPeriod := 0 +// url := fmt.Sprintf("http://foo.com/?count=2&start_period=%d", startPeriod) +// request := httptest.NewRequest("GET", url, nil) +// writer := httptest.NewRecorder() +// writer.Body = &bytes.Buffer{} +// +// s.GetLightClientUpdatesByRange(writer, request) +// +// require.Equal(t, http.StatusOK, writer.Code) +// var resp structs.LightClientUpdatesByRangeResponse +// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) +// require.NoError(t, err) +// require.Equal(t, 1, len(resp.Updates)) +// +// require.Equal(t, "altair", resp.Updates[0].Version) +// updateJson, err := structs.LightClientUpdateFromConsensus(update) +// require.NoError(t, err) +// require.DeepEqual(t, updateJson, resp.Updates[0].Data) +// +//} +// +//func TestLightClientHandler_GetLightClientUpdatesByRangeMissingUpdates(t *testing.T) { +// helpers.ClearCache() +// ctx := context.Background() +// params.SetupTestConfigCleanup(t) +// config := params.BeaconConfig() +// config.AltairForkEpoch = 0 +// config.EpochsPerSyncCommitteePeriod = 1 +// params.OverrideBeaconConfig(config) +// slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) +// +// st, err := util.NewBeaconStateAltair() +// require.NoError(t, err) +// headSlot := slot.Add(65) +// err = st.SetSlot(headSlot) +// require.NoError(t, err) +// +// t.Run("missing update in the middle", func(t *testing.T) { +// db := setupDB(t) +// +// updates := make([]*ethpbv2.LightClientUpdate, 3) +// +// updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) +// +// for i := 0; i < 3; i++ { +// if i == 1 { // skip this update +// updatePeriod++ +// continue +// } +// newSlot := slot.Add(uint64(i * 32)) +// +// update := ðpbv2.LightClientUpdate{ +// AttestedHeader: ðpbv2.LightClientHeaderContainer{ +// Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ +// HeaderAltair: ðpbv2.LightClientHeader{ +// Beacon: ðpbv1.BeaconBlockHeader{ +// Slot: newSlot, +// ProposerIndex: 1, +// ParentRoot: []byte{1, 1, 1}, +// StateRoot: []byte{1, 1, 1}, +// BodyRoot: []byte{1, 1, 1}, +// }, +// }, +// }, +// }, +// NextSyncCommittee: ðpbv2.SyncCommittee{ +// Pubkeys: nil, +// AggregatePubkey: nil, +// }, +// NextSyncCommitteeBranch: nil, +// FinalizedHeader: nil, +// FinalityBranch: nil, +// SyncAggregate: ðpbv1.SyncAggregate{ +// SyncCommitteeBits: []byte{1, 1, 1}, +// SyncCommitteeSignature: []byte{1, 1, 1}, +// }, +// SignatureSlot: 7, +// } +// +// updates[i] = update +// +// err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ +// Version: version.Altair, +// Data: update, +// }) +// require.NoError(t, err) +// +// updatePeriod++ +// } +// +// mockChainService := &mock.ChainService{State: st} +// s := &Server{ +// HeadFetcher: mockChainService, +// BeaconDB: db, +// } +// startPeriod := 0 +// url := fmt.Sprintf("http://foo.com/?count=10&start_period=%d", startPeriod) +// request := httptest.NewRequest("GET", url, nil) +// writer := httptest.NewRecorder() +// writer.Body = &bytes.Buffer{} +// +// s.GetLightClientUpdatesByRange(writer, request) +// +// require.Equal(t, http.StatusOK, writer.Code) +// var resp structs.LightClientUpdatesByRangeResponse +// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) +// require.NoError(t, err) +// require.Equal(t, 1, len(resp.Updates)) +// require.Equal(t, "altair", resp.Updates[0].Version) +// updateJson, err := structs.LightClientUpdateFromConsensus(updates[0]) +// require.NoError(t, err) +// require.DeepEqual(t, updateJson, resp.Updates[0].Data) +// }) +// +// t.Run("missing update at the beginning", func(t *testing.T) { +// db := setupDB(t) +// +// updates := make([]*ethpbv2.LightClientUpdate, 3) +// +// updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) +// +// for i := 0; i < 3; i++ { +// if i == 0 { // skip this update +// updatePeriod++ +// continue +// } +// newSlot := slot.Add(uint64(i)) +// +// update := ðpbv2.LightClientUpdate{ +// AttestedHeader: ðpbv2.LightClientHeaderContainer{ +// Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ +// HeaderAltair: ðpbv2.LightClientHeader{ +// Beacon: ðpbv1.BeaconBlockHeader{ +// Slot: newSlot, +// ProposerIndex: 1, +// ParentRoot: []byte{1, 1, 1}, +// StateRoot: []byte{1, 1, 1}, +// BodyRoot: []byte{1, 1, 1}, +// }, +// }, +// }, +// }, +// NextSyncCommittee: ðpbv2.SyncCommittee{ +// Pubkeys: nil, +// AggregatePubkey: nil, +// }, +// NextSyncCommitteeBranch: nil, +// FinalizedHeader: nil, +// FinalityBranch: nil, +// SyncAggregate: ðpbv1.SyncAggregate{ +// SyncCommitteeBits: []byte{1, 1, 1}, +// SyncCommitteeSignature: []byte{1, 1, 1}, +// }, +// SignatureSlot: 7, +// } +// +// updates[i] = update +// +// err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ +// Version: version.Altair, +// Data: update, +// }) +// require.NoError(t, err) +// +// updatePeriod++ +// } +// +// mockChainService := &mock.ChainService{State: st} +// s := &Server{ +// HeadFetcher: mockChainService, +// BeaconDB: db, +// } +// startPeriod := 0 +// url := fmt.Sprintf("http://foo.com/?count=10&start_period=%d", startPeriod) +// request := httptest.NewRequest("GET", url, nil) +// writer := httptest.NewRecorder() +// writer.Body = &bytes.Buffer{} +// +// s.GetLightClientUpdatesByRange(writer, request) +// +// require.Equal(t, http.StatusOK, writer.Code) +// var resp structs.LightClientUpdatesByRangeResponse +// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) +// require.NoError(t, err) +// require.Equal(t, 0, len(resp.Updates)) +// }) +// +//} +// +//// TestLightClientHandler_GetLightClientFinalityUpdate tests +// +//func TestLightClientHandler_GetLightClientFinalityUpdateAltair(t *testing.T) { +// helpers.ClearCache() +// ctx := context.Background() +// params.SetupTestConfigCleanup(t) +// config := params.BeaconConfig() +// slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) +// +// attestedState, err := util.NewBeaconStateAltair() +// require.NoError(t, err) +// err = attestedState.SetSlot(slot.Sub(1)) +// require.NoError(t, err) +// +// require.NoError(t, attestedState.SetFinalizedCheckpoint(ðpb.Checkpoint{ +// Epoch: config.AltairForkEpoch - 10, +// Root: make([]byte, 32), +// })) +// +// parent := util.NewBeaconBlockAltair() +// parent.Block.Slot = slot.Sub(1) +// +// signedParent, err := blocks.NewSignedBeaconBlock(parent) +// require.NoError(t, err) +// +// parentHeader, err := signedParent.Header() +// require.NoError(t, err) +// attestedHeader := parentHeader.Header +// +// err = attestedState.SetLatestBlockHeader(attestedHeader) +// require.NoError(t, err) +// attestedStateRoot, err := attestedState.HashTreeRoot(ctx) +// require.NoError(t, err) +// +// // get a new signed block so the root is updated with the new state root +// parent.Block.StateRoot = attestedStateRoot[:] +// signedParent, err = blocks.NewSignedBeaconBlock(parent) +// require.NoError(t, err) +// +// st, err := util.NewBeaconStateAltair() +// require.NoError(t, err) +// err = st.SetSlot(slot) +// require.NoError(t, err) +// +// parentRoot, err := signedParent.Block().HashTreeRoot() +// require.NoError(t, err) +// +// block := util.NewBeaconBlockAltair() +// block.Block.Slot = slot +// block.Block.ParentRoot = parentRoot[:] +// +// for i := uint64(0); i < config.SyncCommitteeSize; i++ { +// block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) +// } +// +// signedBlock, err := blocks.NewSignedBeaconBlock(block) +// require.NoError(t, err) +// +// h, err := signedBlock.Header() +// require.NoError(t, err) +// +// err = st.SetLatestBlockHeader(h.Header) +// require.NoError(t, err) +// stateRoot, err := st.HashTreeRoot(ctx) +// require.NoError(t, err) +// +// // get a new signed block so the root is updated with the new state root +// block.Block.StateRoot = stateRoot[:] +// signedBlock, err = blocks.NewSignedBeaconBlock(block) +// require.NoError(t, err) +// +// root, err := block.Block.HashTreeRoot() +// require.NoError(t, err) +// +// mockBlocker := &testutil.MockBlocker{ +// RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ +// parentRoot: signedParent, +// root: signedBlock, +// }, +// SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ +// slot.Sub(1): signedParent, +// slot: signedBlock, +// }, +// } +// mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st, FinalizedRoots: map[[32]byte]bool{ +// root: true, +// }} +// s := &Server{ +// Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ +// slot.Sub(1): attestedState, +// slot: st, +// }}, +// Blocker: mockBlocker, +// HeadFetcher: mockChainService, +// } +// request := httptest.NewRequest("GET", "http://foo.com", nil) +// writer := httptest.NewRecorder() +// writer.Body = &bytes.Buffer{} +// +// s.GetLightClientFinalityUpdate(writer, request) +// +// require.Equal(t, http.StatusOK, writer.Code) +// var resp *structs.LightClientUpdateResponse +// err = json.Unmarshal(writer.Body.Bytes(), &resp) +// require.NoError(t, err) +// var respHeader structs.LightClientHeader +// err = json.Unmarshal(resp.Data.AttestedHeader, &respHeader) +// require.NoError(t, err) +// require.Equal(t, "altair", resp.Version) +// require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot) +// require.NotNil(t, resp.Data) +//} +// +//func TestLightClientHandler_GetLightClientFinalityUpdateCapella(t *testing.T) { +// helpers.ClearCache() +// ctx := context.Background() +// params.SetupTestConfigCleanup(t) +// config := params.BeaconConfig() +// slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) +// +// attestedState, err := util.NewBeaconStateCapella() +// require.NoError(t, err) +// err = attestedState.SetSlot(slot.Sub(1)) +// require.NoError(t, err) +// +// require.NoError(t, attestedState.SetFinalizedCheckpoint(ðpb.Checkpoint{ +// Epoch: config.AltairForkEpoch - 10, +// Root: make([]byte, 32), +// })) +// +// parent := util.NewBeaconBlockCapella() +// parent.Block.Slot = slot.Sub(1) +// +// signedParent, err := blocks.NewSignedBeaconBlock(parent) +// require.NoError(t, err) +// +// parentHeader, err := signedParent.Header() +// require.NoError(t, err) +// attestedHeader := parentHeader.Header +// +// err = attestedState.SetLatestBlockHeader(attestedHeader) +// require.NoError(t, err) +// attestedStateRoot, err := attestedState.HashTreeRoot(ctx) +// require.NoError(t, err) +// +// // get a new signed block so the root is updated with the new state root +// parent.Block.StateRoot = attestedStateRoot[:] +// signedParent, err = blocks.NewSignedBeaconBlock(parent) +// require.NoError(t, err) +// +// st, err := util.NewBeaconStateCapella() +// require.NoError(t, err) +// err = st.SetSlot(slot) +// require.NoError(t, err) +// +// parentRoot, err := signedParent.Block().HashTreeRoot() +// require.NoError(t, err) +// +// block := util.NewBeaconBlockCapella() +// block.Block.Slot = slot +// block.Block.ParentRoot = parentRoot[:] +// +// for i := uint64(0); i < config.SyncCommitteeSize; i++ { +// block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) +// } +// +// signedBlock, err := blocks.NewSignedBeaconBlock(block) +// require.NoError(t, err) +// +// h, err := signedBlock.Header() +// require.NoError(t, err) +// +// err = st.SetLatestBlockHeader(h.Header) +// require.NoError(t, err) +// stateRoot, err := st.HashTreeRoot(ctx) +// require.NoError(t, err) +// +// // get a new signed block so the root is updated with the new state root +// block.Block.StateRoot = stateRoot[:] +// signedBlock, err = blocks.NewSignedBeaconBlock(block) +// require.NoError(t, err) +// +// root, err := block.Block.HashTreeRoot() +// require.NoError(t, err) +// +// mockBlocker := &testutil.MockBlocker{ +// RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ +// parentRoot: signedParent, +// root: signedBlock, +// }, +// SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ +// slot.Sub(1): signedParent, +// slot: signedBlock, +// }, +// } +// mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st, FinalizedRoots: map[[32]byte]bool{ +// root: true, +// }} +// s := &Server{ +// Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ +// slot.Sub(1): attestedState, +// slot: st, +// }}, +// Blocker: mockBlocker, +// HeadFetcher: mockChainService, +// } +// request := httptest.NewRequest("GET", "http://foo.com", nil) +// writer := httptest.NewRecorder() +// writer.Body = &bytes.Buffer{} +// +// s.GetLightClientFinalityUpdate(writer, request) +// +// require.Equal(t, http.StatusOK, writer.Code) +// var resp *structs.LightClientUpdateResponse +// err = json.Unmarshal(writer.Body.Bytes(), &resp) +// require.NoError(t, err) +// var respHeader structs.LightClientHeader +// err = json.Unmarshal(resp.Data.AttestedHeader, &respHeader) +// require.NoError(t, err) +// require.Equal(t, "capella", resp.Version) +// require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot) +// require.NotNil(t, resp.Data) +//} +// +//func TestLightClientHandler_GetLightClientFinalityUpdateDeneb(t *testing.T) { +// helpers.ClearCache() +// ctx := context.Background() +// params.SetupTestConfigCleanup(t) +// config := params.BeaconConfig() +// slot := primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) +// +// attestedState, err := util.NewBeaconStateDeneb() +// require.NoError(t, err) +// err = attestedState.SetSlot(slot.Sub(1)) +// require.NoError(t, err) +// +// require.NoError(t, attestedState.SetFinalizedCheckpoint(ðpb.Checkpoint{ +// Epoch: config.AltairForkEpoch - 10, +// Root: make([]byte, 32), +// })) +// +// parent := util.NewBeaconBlockDeneb() +// parent.Block.Slot = slot.Sub(1) +// +// signedParent, err := blocks.NewSignedBeaconBlock(parent) +// require.NoError(t, err) +// +// parentHeader, err := signedParent.Header() +// require.NoError(t, err) +// attestedHeader := parentHeader.Header +// +// err = attestedState.SetLatestBlockHeader(attestedHeader) +// require.NoError(t, err) +// attestedStateRoot, err := attestedState.HashTreeRoot(ctx) +// require.NoError(t, err) +// +// // get a new signed block so the root is updated with the new state root +// parent.Block.StateRoot = attestedStateRoot[:] +// signedParent, err = blocks.NewSignedBeaconBlock(parent) +// require.NoError(t, err) +// +// st, err := util.NewBeaconStateDeneb() +// require.NoError(t, err) +// err = st.SetSlot(slot) +// require.NoError(t, err) +// +// parentRoot, err := signedParent.Block().HashTreeRoot() +// require.NoError(t, err) +// +// block := util.NewBeaconBlockDeneb() +// block.Block.Slot = slot +// block.Block.ParentRoot = parentRoot[:] +// +// for i := uint64(0); i < config.SyncCommitteeSize; i++ { +// block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) +// } +// +// signedBlock, err := blocks.NewSignedBeaconBlock(block) +// require.NoError(t, err) +// +// h, err := signedBlock.Header() +// require.NoError(t, err) +// +// err = st.SetLatestBlockHeader(h.Header) +// require.NoError(t, err) +// stateRoot, err := st.HashTreeRoot(ctx) +// require.NoError(t, err) +// +// // get a new signed block so the root is updated with the new state root +// block.Block.StateRoot = stateRoot[:] +// signedBlock, err = blocks.NewSignedBeaconBlock(block) +// require.NoError(t, err) +// +// root, err := block.Block.HashTreeRoot() +// require.NoError(t, err) +// +// mockBlocker := &testutil.MockBlocker{ +// RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ +// parentRoot: signedParent, +// root: signedBlock, +// }, +// SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ +// slot.Sub(1): signedParent, +// slot: signedBlock, +// }, +// } +// mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st, FinalizedRoots: map[[32]byte]bool{ +// root: true, +// }} +// s := &Server{ +// Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ +// slot.Sub(1): attestedState, +// slot: st, +// }}, +// Blocker: mockBlocker, +// HeadFetcher: mockChainService, +// } +// request := httptest.NewRequest("GET", "http://foo.com", nil) +// writer := httptest.NewRecorder() +// writer.Body = &bytes.Buffer{} +// +// s.GetLightClientFinalityUpdate(writer, request) +// +// require.Equal(t, http.StatusOK, writer.Code) +// var resp *structs.LightClientUpdateResponse +// err = json.Unmarshal(writer.Body.Bytes(), &resp) +// require.NoError(t, err) +// var respHeader structs.LightClientHeaderDeneb +// err = json.Unmarshal(resp.Data.AttestedHeader, &respHeader) +// require.NoError(t, err) +// require.Equal(t, "deneb", resp.Version) +// require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot) +// require.NotNil(t, resp.Data) +//} +// +//func TestLightClientHandler_GetLightClientOptimisticUpdateAltair(t *testing.T) { +// helpers.ClearCache() +// ctx := context.Background() +// params.SetupTestConfigCleanup(t) +// config := params.BeaconConfig() +// slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) +// +// attestedState, err := util.NewBeaconStateAltair() +// require.NoError(t, err) +// err = attestedState.SetSlot(slot.Sub(1)) +// require.NoError(t, err) +// +// require.NoError(t, attestedState.SetFinalizedCheckpoint(ðpb.Checkpoint{ +// Epoch: config.AltairForkEpoch - 10, +// Root: make([]byte, 32), +// })) +// +// parent := util.NewBeaconBlockAltair() +// parent.Block.Slot = slot.Sub(1) +// +// signedParent, err := blocks.NewSignedBeaconBlock(parent) +// require.NoError(t, err) +// +// parentHeader, err := signedParent.Header() +// require.NoError(t, err) +// attestedHeader := parentHeader.Header +// +// err = attestedState.SetLatestBlockHeader(attestedHeader) +// require.NoError(t, err) +// attestedStateRoot, err := attestedState.HashTreeRoot(ctx) +// require.NoError(t, err) +// +// // get a new signed block so the root is updated with the new state root +// parent.Block.StateRoot = attestedStateRoot[:] +// signedParent, err = blocks.NewSignedBeaconBlock(parent) +// require.NoError(t, err) +// +// st, err := util.NewBeaconStateAltair() +// require.NoError(t, err) +// err = st.SetSlot(slot) +// require.NoError(t, err) +// +// parentRoot, err := signedParent.Block().HashTreeRoot() +// require.NoError(t, err) +// +// block := util.NewBeaconBlockAltair() +// block.Block.Slot = slot +// block.Block.ParentRoot = parentRoot[:] +// +// for i := uint64(0); i < config.SyncCommitteeSize; i++ { +// block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) +// } +// +// signedBlock, err := blocks.NewSignedBeaconBlock(block) +// require.NoError(t, err) +// +// h, err := signedBlock.Header() +// require.NoError(t, err) +// +// err = st.SetLatestBlockHeader(h.Header) +// require.NoError(t, err) +// stateRoot, err := st.HashTreeRoot(ctx) +// require.NoError(t, err) +// +// // get a new signed block so the root is updated with the new state root +// block.Block.StateRoot = stateRoot[:] +// signedBlock, err = blocks.NewSignedBeaconBlock(block) +// require.NoError(t, err) +// +// root, err := block.Block.HashTreeRoot() +// require.NoError(t, err) +// +// mockBlocker := &testutil.MockBlocker{ +// RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ +// parentRoot: signedParent, +// root: signedBlock, +// }, +// SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ +// slot.Sub(1): signedParent, +// slot: signedBlock, +// }, +// } +// mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st, FinalizedRoots: map[[32]byte]bool{ +// root: true, +// }} +// s := &Server{ +// Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ +// slot.Sub(1): attestedState, +// slot: st, +// }}, +// Blocker: mockBlocker, +// HeadFetcher: mockChainService, +// } +// request := httptest.NewRequest("GET", "http://foo.com", nil) +// writer := httptest.NewRecorder() +// writer.Body = &bytes.Buffer{} +// +// s.GetLightClientOptimisticUpdate(writer, request) +// +// require.Equal(t, http.StatusOK, writer.Code) +// var resp *structs.LightClientUpdateResponse +// err = json.Unmarshal(writer.Body.Bytes(), &resp) +// require.NoError(t, err) +// var respHeader structs.LightClientHeader +// err = json.Unmarshal(resp.Data.AttestedHeader, &respHeader) +// require.NoError(t, err) +// require.Equal(t, "altair", resp.Version) +// require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot) +// require.NotNil(t, resp.Data) +//} +// +//func TestLightClientHandler_GetLightClientOptimisticUpdateCapella(t *testing.T) { +// helpers.ClearCache() +// ctx := context.Background() +// params.SetupTestConfigCleanup(t) +// config := params.BeaconConfig() +// slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) +// +// attestedState, err := util.NewBeaconStateCapella() +// require.NoError(t, err) +// err = attestedState.SetSlot(slot.Sub(1)) +// require.NoError(t, err) +// +// require.NoError(t, attestedState.SetFinalizedCheckpoint(ðpb.Checkpoint{ +// Epoch: config.AltairForkEpoch - 10, +// Root: make([]byte, 32), +// })) +// +// parent := util.NewBeaconBlockCapella() +// parent.Block.Slot = slot.Sub(1) +// +// signedParent, err := blocks.NewSignedBeaconBlock(parent) +// require.NoError(t, err) +// +// parentHeader, err := signedParent.Header() +// require.NoError(t, err) +// attestedHeader := parentHeader.Header +// +// err = attestedState.SetLatestBlockHeader(attestedHeader) +// require.NoError(t, err) +// attestedStateRoot, err := attestedState.HashTreeRoot(ctx) +// require.NoError(t, err) +// +// // get a new signed block so the root is updated with the new state root +// parent.Block.StateRoot = attestedStateRoot[:] +// signedParent, err = blocks.NewSignedBeaconBlock(parent) +// require.NoError(t, err) +// +// st, err := util.NewBeaconStateCapella() +// require.NoError(t, err) +// err = st.SetSlot(slot) +// require.NoError(t, err) +// +// parentRoot, err := signedParent.Block().HashTreeRoot() +// require.NoError(t, err) +// +// block := util.NewBeaconBlockCapella() +// block.Block.Slot = slot +// block.Block.ParentRoot = parentRoot[:] +// +// for i := uint64(0); i < config.SyncCommitteeSize; i++ { +// block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) +// } +// +// signedBlock, err := blocks.NewSignedBeaconBlock(block) +// require.NoError(t, err) +// +// h, err := signedBlock.Header() +// require.NoError(t, err) +// +// err = st.SetLatestBlockHeader(h.Header) +// require.NoError(t, err) +// stateRoot, err := st.HashTreeRoot(ctx) +// require.NoError(t, err) +// +// // get a new signed block so the root is updated with the new state root +// block.Block.StateRoot = stateRoot[:] +// signedBlock, err = blocks.NewSignedBeaconBlock(block) +// require.NoError(t, err) +// +// root, err := block.Block.HashTreeRoot() +// require.NoError(t, err) +// +// mockBlocker := &testutil.MockBlocker{ +// RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ +// parentRoot: signedParent, +// root: signedBlock, +// }, +// SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ +// slot.Sub(1): signedParent, +// slot: signedBlock, +// }, +// } +// mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st, FinalizedRoots: map[[32]byte]bool{ +// root: true, +// }} +// s := &Server{ +// Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ +// slot.Sub(1): attestedState, +// slot: st, +// }}, +// Blocker: mockBlocker, +// HeadFetcher: mockChainService, +// } +// request := httptest.NewRequest("GET", "http://foo.com", nil) +// writer := httptest.NewRecorder() +// writer.Body = &bytes.Buffer{} +// +// s.GetLightClientOptimisticUpdate(writer, request) +// +// require.Equal(t, http.StatusOK, writer.Code) +// var resp *structs.LightClientUpdateResponse +// err = json.Unmarshal(writer.Body.Bytes(), &resp) +// require.NoError(t, err) +// var respHeader structs.LightClientHeaderCapella +// err = json.Unmarshal(resp.Data.AttestedHeader, &respHeader) +// require.NoError(t, err) +// require.Equal(t, "capella", resp.Version) +// require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot) +// require.NotNil(t, resp.Data) +//} +// +//func TestLightClientHandler_GetLightClientOptimisticUpdateDeneb(t *testing.T) { +// helpers.ClearCache() +// ctx := context.Background() +// params.SetupTestConfigCleanup(t) +// config := params.BeaconConfig() +// slot := primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) +// +// attestedState, err := util.NewBeaconStateDeneb() +// require.NoError(t, err) +// err = attestedState.SetSlot(slot.Sub(1)) +// require.NoError(t, err) +// +// require.NoError(t, attestedState.SetFinalizedCheckpoint(ðpb.Checkpoint{ +// Epoch: config.AltairForkEpoch - 10, +// Root: make([]byte, 32), +// })) +// +// parent := util.NewBeaconBlockDeneb() +// parent.Block.Slot = slot.Sub(1) +// +// signedParent, err := blocks.NewSignedBeaconBlock(parent) +// require.NoError(t, err) +// +// parentHeader, err := signedParent.Header() +// require.NoError(t, err) +// attestedHeader := parentHeader.Header +// +// err = attestedState.SetLatestBlockHeader(attestedHeader) +// require.NoError(t, err) +// attestedStateRoot, err := attestedState.HashTreeRoot(ctx) +// require.NoError(t, err) +// +// // get a new signed block so the root is updated with the new state root +// parent.Block.StateRoot = attestedStateRoot[:] +// signedParent, err = blocks.NewSignedBeaconBlock(parent) +// require.NoError(t, err) +// +// st, err := util.NewBeaconStateDeneb() +// require.NoError(t, err) +// err = st.SetSlot(slot) +// require.NoError(t, err) +// +// parentRoot, err := signedParent.Block().HashTreeRoot() +// require.NoError(t, err) +// +// block := util.NewBeaconBlockDeneb() +// block.Block.Slot = slot +// block.Block.ParentRoot = parentRoot[:] +// +// for i := uint64(0); i < config.SyncCommitteeSize; i++ { +// block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) +// } +// +// signedBlock, err := blocks.NewSignedBeaconBlock(block) +// require.NoError(t, err) +// +// h, err := signedBlock.Header() +// require.NoError(t, err) +// +// err = st.SetLatestBlockHeader(h.Header) +// require.NoError(t, err) +// stateRoot, err := st.HashTreeRoot(ctx) +// require.NoError(t, err) +// +// // get a new signed block so the root is updated with the new state root +// block.Block.StateRoot = stateRoot[:] +// signedBlock, err = blocks.NewSignedBeaconBlock(block) +// require.NoError(t, err) +// +// root, err := block.Block.HashTreeRoot() +// require.NoError(t, err) +// +// mockBlocker := &testutil.MockBlocker{ +// RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ +// parentRoot: signedParent, +// root: signedBlock, +// }, +// SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ +// slot.Sub(1): signedParent, +// slot: signedBlock, +// }, +// } +// mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st, FinalizedRoots: map[[32]byte]bool{ +// root: true, +// }} +// s := &Server{ +// Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ +// slot.Sub(1): attestedState, +// slot: st, +// }}, +// Blocker: mockBlocker, +// HeadFetcher: mockChainService, +// } +// request := httptest.NewRequest("GET", "http://foo.com", nil) +// writer := httptest.NewRecorder() +// writer.Body = &bytes.Buffer{} +// +// s.GetLightClientOptimisticUpdate(writer, request) +// +// require.Equal(t, http.StatusOK, writer.Code) +// var resp *structs.LightClientUpdateResponse +// err = json.Unmarshal(writer.Body.Bytes(), &resp) +// require.NoError(t, err) +// var respHeader structs.LightClientHeaderDeneb +// err = json.Unmarshal(resp.Data.AttestedHeader, &respHeader) +// require.NoError(t, err) +// require.Equal(t, "deneb", resp.Version) +// require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot) +// require.NotNil(t, resp.Data) +//} +// +//func TestLightClientHandler_GetLightClientEventBlock(t *testing.T) { +// helpers.ClearCache() +// ctx := context.Background() +// params.SetupTestConfigCleanup(t) +// config := params.BeaconConfig() +// slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) +// +// attestedState, err := util.NewBeaconStateCapella() +// require.NoError(t, err) +// err = attestedState.SetSlot(slot.Sub(1)) +// require.NoError(t, err) +// +// require.NoError(t, attestedState.SetFinalizedCheckpoint(ðpb.Checkpoint{ +// Epoch: config.AltairForkEpoch - 10, +// Root: make([]byte, 32), +// })) +// +// parent := util.NewBeaconBlockCapella() +// parent.Block.Slot = slot.Sub(1) +// +// signedParent, err := blocks.NewSignedBeaconBlock(parent) +// require.NoError(t, err) +// +// parentHeader, err := signedParent.Header() +// require.NoError(t, err) +// attestedHeader := parentHeader.Header +// +// err = attestedState.SetLatestBlockHeader(attestedHeader) +// require.NoError(t, err) +// attestedStateRoot, err := attestedState.HashTreeRoot(ctx) +// require.NoError(t, err) +// +// // get a new signed block so the root is updated with the new state root +// parent.Block.StateRoot = attestedStateRoot[:] +// signedParent, err = blocks.NewSignedBeaconBlock(parent) +// require.NoError(t, err) +// +// st, err := util.NewBeaconStateCapella() +// require.NoError(t, err) +// err = st.SetSlot(slot) +// require.NoError(t, err) +// +// parentRoot, err := signedParent.Block().HashTreeRoot() +// require.NoError(t, err) +// +// block := util.NewBeaconBlockCapella() +// block.Block.Slot = slot +// block.Block.ParentRoot = parentRoot[:] +// +// for i := uint64(0); i < config.SyncCommitteeSize; i++ { +// block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) +// } +// +// signedBlock, err := blocks.NewSignedBeaconBlock(block) +// require.NoError(t, err) +// +// h, err := signedBlock.Header() +// require.NoError(t, err) +// +// err = st.SetLatestBlockHeader(h.Header) +// require.NoError(t, err) +// stateRoot, err := st.HashTreeRoot(ctx) +// require.NoError(t, err) +// +// // get a new signed block so the root is updated with the new state root +// block.Block.StateRoot = stateRoot[:] +// signedBlock, err = blocks.NewSignedBeaconBlock(block) +// require.NoError(t, err) +// +// root, err := block.Block.HashTreeRoot() +// require.NoError(t, err) +// +// mockBlocker := &testutil.MockBlocker{ +// RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ +// parentRoot: signedParent, +// root: signedBlock, +// }, +// SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ +// slot.Sub(1): signedParent, +// slot: signedBlock, +// }, +// } +// mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st, FinalizedRoots: map[[32]byte]bool{ +// root: true, +// }} +// s := &Server{ +// Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ +// slot.Sub(1): attestedState, +// slot: st, +// }}, +// Blocker: mockBlocker, +// HeadFetcher: mockChainService, +// } +// +// minSignaturesRequired := uint64(100) +// eventBlock, err := s.suitableBlock(ctx, minSignaturesRequired) +// +// require.NoError(t, err) +// require.NotNil(t, eventBlock) +// require.Equal(t, slot, eventBlock.Block().Slot()) +// syncAggregate, err := eventBlock.Block().Body().SyncAggregate() +// require.NoError(t, err) +// require.Equal(t, true, syncAggregate.SyncCommitteeBits.Count() >= minSignaturesRequired) +//} +// +//func TestLightClientHandler_GetLightClientEventBlock_NeedFetchParent(t *testing.T) { +// helpers.ClearCache() +// ctx := context.Background() +// params.SetupTestConfigCleanup(t) +// config := params.BeaconConfig() +// slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) +// +// attestedState, err := util.NewBeaconStateCapella() +// require.NoError(t, err) +// err = attestedState.SetSlot(slot.Sub(1)) +// require.NoError(t, err) +// +// require.NoError(t, attestedState.SetFinalizedCheckpoint(ðpb.Checkpoint{ +// Epoch: config.AltairForkEpoch - 10, +// Root: make([]byte, 32), +// })) +// +// parent := util.NewBeaconBlockCapella() +// parent.Block.Slot = slot.Sub(1) +// for i := uint64(0); i < config.SyncCommitteeSize; i++ { +// parent.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) +// } +// +// signedParent, err := blocks.NewSignedBeaconBlock(parent) +// require.NoError(t, err) +// +// parentHeader, err := signedParent.Header() +// require.NoError(t, err) +// attestedHeader := parentHeader.Header +// +// err = attestedState.SetLatestBlockHeader(attestedHeader) +// require.NoError(t, err) +// attestedStateRoot, err := attestedState.HashTreeRoot(ctx) +// require.NoError(t, err) +// +// // get a new signed block so the root is updated with the new state root +// parent.Block.StateRoot = attestedStateRoot[:] +// signedParent, err = blocks.NewSignedBeaconBlock(parent) +// require.NoError(t, err) +// +// st, err := util.NewBeaconStateCapella() +// require.NoError(t, err) +// err = st.SetSlot(slot) +// require.NoError(t, err) +// +// parentRoot, err := signedParent.Block().HashTreeRoot() +// require.NoError(t, err) +// +// block := util.NewBeaconBlockCapella() +// block.Block.Slot = slot +// block.Block.ParentRoot = parentRoot[:] +// +// for i := uint64(0); i < 10; i++ { +// block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) +// } +// +// signedBlock, err := blocks.NewSignedBeaconBlock(block) +// require.NoError(t, err) +// +// h, err := signedBlock.Header() +// require.NoError(t, err) +// +// err = st.SetLatestBlockHeader(h.Header) +// require.NoError(t, err) +// stateRoot, err := st.HashTreeRoot(ctx) +// require.NoError(t, err) +// +// // get a new signed block so the root is updated with the new state root +// block.Block.StateRoot = stateRoot[:] +// signedBlock, err = blocks.NewSignedBeaconBlock(block) +// require.NoError(t, err) +// +// root, err := block.Block.HashTreeRoot() +// require.NoError(t, err) +// +// mockBlocker := &testutil.MockBlocker{ +// RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ +// parentRoot: signedParent, +// root: signedBlock, +// }, +// SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ +// slot.Sub(1): signedParent, +// slot: signedBlock, +// }, +// } +// mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st, FinalizedRoots: map[[32]byte]bool{ +// root: true, +// }} +// s := &Server{ +// Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ +// slot.Sub(1): attestedState, +// slot: st, +// }}, +// Blocker: mockBlocker, +// HeadFetcher: mockChainService, +// } +// +// minSignaturesRequired := uint64(100) +// eventBlock, err := s.suitableBlock(ctx, minSignaturesRequired) +// +// require.NoError(t, err) +// require.NotNil(t, eventBlock) +// syncAggregate, err := eventBlock.Block().Body().SyncAggregate() +// require.NoError(t, err) +// require.Equal(t, true, syncAggregate.SyncCommitteeBits.Count() >= minSignaturesRequired) +// require.Equal(t, slot-1, eventBlock.Block().Slot()) +//} +// +//// setupDB instantiates and returns a Store instance. +//func setupDB(t testing.TB) *kv.Store { +// db, err := kv.NewKVStore(context.Background(), t.TempDir()) +// require.NoError(t, err, "Failed to instantiate DB") +// t.Cleanup(func() { +// require.NoError(t, db.Close(), "Failed to close database") +// }) +// return db +//} diff --git a/beacon-chain/rpc/eth/light-client/helpers_test.go b/beacon-chain/rpc/eth/light-client/helpers_test.go index dfaab098316e..ef1a99f5c87e 100644 --- a/beacon-chain/rpc/eth/light-client/helpers_test.go +++ b/beacon-chain/rpc/eth/light-client/helpers_test.go @@ -1,619 +1,646 @@ package lightclient import ( + "strings" "testing" lightclient "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/light-client" fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams" "github.com/prysmaticlabs/prysm/v5/config/params" - ethpbv1 "github.com/prysmaticlabs/prysm/v5/proto/eth/v1" - ethpbv2 "github.com/prysmaticlabs/prysm/v5/proto/eth/v2" + light_client "github.com/prysmaticlabs/prysm/v5/consensus-types/light-client" + "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" + pb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" "github.com/prysmaticlabs/prysm/v5/testing/assert" ) // When the update has relevant sync committee func createNonEmptySyncCommitteeBranch() [][]byte { res := make([][]byte, fieldparams.SyncCommitteeBranchDepth) - res[0] = []byte("xyz") + res[0] = []byte(strings.Repeat("x", 32)) + for i := 1; i < len(res); i++ { + res[i] = make([]byte, fieldparams.RootLength) + } return res } // When the update has finality func createNonEmptyFinalityBranch() [][]byte { - res := make([][]byte, lightclient.FinalityBranchNumOfLeaves) - res[0] = []byte("xyz") + res := make([][]byte, fieldparams.FinalityBranchDepth) + res[0] = []byte(strings.Repeat("x", 32)) + for i := 1; i < fieldparams.FinalityBranchDepth; i++ { + res[i] = make([]byte, 32) + } return res } func TestIsBetterUpdate(t *testing.T) { params.SetupTestConfigCleanup(t) + config := params.BeaconConfig() - testCases := []struct { - name string - oldUpdate *ethpbv2.LightClientUpdate - newUpdate *ethpbv2.LightClientUpdate - expectedResult bool - }{ - { - name: "new has supermajority but old doesn't", - oldUpdate: ðpbv2.LightClientUpdate{ - SyncAggregate: ðpbv1.SyncAggregate{ - SyncCommitteeBits: []byte{0b01111100, 0b1}, // [0,0,1,1,1,1,1,0] - }, - }, - newUpdate: ðpbv2.LightClientUpdate{ - SyncAggregate: ðpbv1.SyncAggregate{ - SyncCommitteeBits: []byte{0b11111100, 0b1}, // [0,0,1,1,1,1,1,1] - }, - }, - expectedResult: true, - }, - { - name: "old has supermajority but new doesn't", - oldUpdate: ðpbv2.LightClientUpdate{ - SyncAggregate: ðpbv1.SyncAggregate{ - SyncCommitteeBits: []byte{0b11111100, 0b1}, // [0,0,1,1,1,1,1,1] - }, - }, - newUpdate: ðpbv2.LightClientUpdate{ - SyncAggregate: ðpbv1.SyncAggregate{ - SyncCommitteeBits: []byte{0b01111100, 0b1}, // [0,0,1,1,1,1,1,0] - }, - }, - expectedResult: false, - }, - { - name: "new doesn't have supermajority and newNumActiveParticipants is greater than oldNumActiveParticipants", - oldUpdate: ðpbv2.LightClientUpdate{ - SyncAggregate: ðpbv1.SyncAggregate{ - SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0] - }, - }, - newUpdate: ðpbv2.LightClientUpdate{ - SyncAggregate: ðpbv1.SyncAggregate{ - SyncCommitteeBits: []byte{0b01111100, 0b1}, // [0,0,1,1,1,1,1,0] - }, - }, - expectedResult: true, - }, - { - name: "new doesn't have supermajority and newNumActiveParticipants is lesser than oldNumActiveParticipants", - oldUpdate: ðpbv2.LightClientUpdate{ - SyncAggregate: ðpbv1.SyncAggregate{ - SyncCommitteeBits: []byte{0b01111100, 0b1}, // [0,0,1,1,1,1,1,0] - }, - }, - newUpdate: ðpbv2.LightClientUpdate{ - SyncAggregate: ðpbv1.SyncAggregate{ - SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0] - }, - }, - expectedResult: false, - }, - { - name: "new has relevant sync committee but old doesn't", - oldUpdate: ðpbv2.LightClientUpdate{ - SyncAggregate: ðpbv1.SyncAggregate{ - SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0] - }, - AttestedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 1000000, - }}, - }, - }, - NextSyncCommitteeBranch: make([][]byte, fieldparams.SyncCommitteeBranchDepth), - SignatureSlot: 9999, - }, - newUpdate: ðpbv2.LightClientUpdate{ - SyncAggregate: ðpbv1.SyncAggregate{ - SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0] - }, - AttestedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 1000001, - }}, - }, - }, - NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(), - SignatureSlot: 1000000, - }, - expectedResult: true, - }, - { - name: "old has relevant sync committee but new doesn't", - oldUpdate: ðpbv2.LightClientUpdate{ - SyncAggregate: ðpbv1.SyncAggregate{ - SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0] - }, - AttestedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 1000001, - }}, - }, - }, - NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(), - SignatureSlot: 1000000, - }, - newUpdate: ðpbv2.LightClientUpdate{ - SyncAggregate: ðpbv1.SyncAggregate{ - SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0] - }, - AttestedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 1000000, - }}, - }, - }, - NextSyncCommitteeBranch: make([][]byte, fieldparams.SyncCommitteeBranchDepth), - SignatureSlot: 9999, - }, - expectedResult: false, - }, - { - name: "new has finality but old doesn't", - oldUpdate: ðpbv2.LightClientUpdate{ - SyncAggregate: ðpbv1.SyncAggregate{ - SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0] - }, - AttestedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 1000000, - }}, - }, - }, - NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(), - SignatureSlot: 9999, - FinalityBranch: make([][]byte, lightclient.FinalityBranchNumOfLeaves), - }, - newUpdate: ðpbv2.LightClientUpdate{ - SyncAggregate: ðpbv1.SyncAggregate{ - SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0] - }, - AttestedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 1000000, - }}, - }, - }, - NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(), - SignatureSlot: 9999, - FinalityBranch: createNonEmptyFinalityBranch(), - }, - expectedResult: true, - }, - { - name: "old has finality but new doesn't", - oldUpdate: ðpbv2.LightClientUpdate{ - SyncAggregate: ðpbv1.SyncAggregate{ - SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0] - }, - AttestedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 1000000, - }}, - }, - }, - NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(), - SignatureSlot: 9999, - FinalityBranch: createNonEmptyFinalityBranch(), - }, - newUpdate: ðpbv2.LightClientUpdate{ - SyncAggregate: ðpbv1.SyncAggregate{ - SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0] - }, - AttestedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 1000000, - }}, - }, - }, - NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(), - SignatureSlot: 9999, - FinalityBranch: make([][]byte, lightclient.FinalityBranchNumOfLeaves), - }, - expectedResult: false, - }, - { - name: "new has finality and sync committee finality both but old doesn't have sync committee finality", - oldUpdate: ðpbv2.LightClientUpdate{ - SyncAggregate: ðpbv1.SyncAggregate{ - SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0] - }, - AttestedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 1000000, - }}, - }, - }, - NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(), - SignatureSlot: 9999, - FinalityBranch: createNonEmptyFinalityBranch(), - FinalizedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 9999, - }}, - }, - }, - }, - newUpdate: ðpbv2.LightClientUpdate{ - SyncAggregate: ðpbv1.SyncAggregate{ - SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0] - }, - AttestedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 1000000, - }}, - }, - }, - NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(), - SignatureSlot: 999999, - FinalityBranch: createNonEmptyFinalityBranch(), - FinalizedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 999999, - }}, - }, - }, - }, - expectedResult: true, - }, - { - name: "new has finality but doesn't have sync committee finality and old has sync committee finality", - oldUpdate: ðpbv2.LightClientUpdate{ - SyncAggregate: ðpbv1.SyncAggregate{ - SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0] - }, - AttestedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 1000000, - }}, - }, - }, - NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(), - SignatureSlot: 999999, - FinalityBranch: createNonEmptyFinalityBranch(), - FinalizedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 999999, - }}, - }, - }, - }, - newUpdate: ðpbv2.LightClientUpdate{ - SyncAggregate: ðpbv1.SyncAggregate{ - SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0] - }, - AttestedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 1000000, - }}, - }, - }, - NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(), - SignatureSlot: 9999, - FinalityBranch: createNonEmptyFinalityBranch(), - FinalizedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 9999, - }}, - }, - }, - }, - expectedResult: false, - }, - { - name: "new has more active participants than old", - oldUpdate: ðpbv2.LightClientUpdate{ - SyncAggregate: ðpbv1.SyncAggregate{ - SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0] - }, - AttestedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 1000000, - }}, - }, - }, - NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(), - SignatureSlot: 9999, - FinalityBranch: createNonEmptyFinalityBranch(), - FinalizedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 9999, - }}, - }, - }, - }, - newUpdate: ðpbv2.LightClientUpdate{ - SyncAggregate: ðpbv1.SyncAggregate{ - SyncCommitteeBits: []byte{0b01111100, 0b1}, // [0,1,1,1,1,1,0,0] - }, - AttestedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 1000000, - }}, - }, - }, - NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(), - SignatureSlot: 9999, - FinalityBranch: createNonEmptyFinalityBranch(), - FinalizedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 9999, - }}, - }, - }, - }, - expectedResult: true, - }, - { - name: "new has less active participants than old", - oldUpdate: ðpbv2.LightClientUpdate{ - SyncAggregate: ðpbv1.SyncAggregate{ - SyncCommitteeBits: []byte{0b01111100, 0b1}, // [0,1,1,1,1,1,0,0] - }, - AttestedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 1000000, - }}, - }, - }, - NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(), - SignatureSlot: 9999, - FinalityBranch: createNonEmptyFinalityBranch(), - FinalizedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 9999, - }}, - }, - }, - }, - newUpdate: ðpbv2.LightClientUpdate{ - SyncAggregate: ðpbv1.SyncAggregate{ - SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0] - }, - AttestedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 1000000, - }}, - }, - }, - NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(), - SignatureSlot: 9999, - FinalityBranch: createNonEmptyFinalityBranch(), - FinalizedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 9999, - }}, - }, - }, - }, - expectedResult: false, - }, - { - name: "new's attested header's slot is lesser than old's attested header's slot", - oldUpdate: ðpbv2.LightClientUpdate{ - SyncAggregate: ðpbv1.SyncAggregate{ - SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0] - }, - AttestedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 1000000, - }}, - }, - }, - NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(), - SignatureSlot: 9999, - FinalityBranch: createNonEmptyFinalityBranch(), - FinalizedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 9999, - }}, - }, - }, - }, - newUpdate: ðpbv2.LightClientUpdate{ - SyncAggregate: ðpbv1.SyncAggregate{ - SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0] - }, - AttestedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 999999, - }}, - }, - }, - NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(), - SignatureSlot: 9999, - FinalityBranch: createNonEmptyFinalityBranch(), - FinalizedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 9999, - }}, - }, - }, - }, - expectedResult: true, - }, - { - name: "new's attested header's slot is greater than old's attested header's slot", - oldUpdate: ðpbv2.LightClientUpdate{ - SyncAggregate: ðpbv1.SyncAggregate{ - SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0] - }, - AttestedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 999999, - }}, - }, - }, - NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(), - SignatureSlot: 9999, - FinalityBranch: createNonEmptyFinalityBranch(), - FinalizedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 9999, - }}, - }, - }, - }, - newUpdate: ðpbv2.LightClientUpdate{ - SyncAggregate: ðpbv1.SyncAggregate{ - SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0] - }, - AttestedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 1000000, - }}, - }, - }, - NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(), - SignatureSlot: 9999, - FinalityBranch: createNonEmptyFinalityBranch(), - FinalizedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 9999, - }}, - }, - }, - }, - expectedResult: false, - }, - { - name: "none of the above conditions are met and new signature's slot is less than old signature's slot", - oldUpdate: ðpbv2.LightClientUpdate{ - SyncAggregate: ðpbv1.SyncAggregate{ - SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0] - }, - AttestedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 1000000, - }}, - }, - }, - NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(), - SignatureSlot: 9999, - FinalityBranch: createNonEmptyFinalityBranch(), - FinalizedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 9999, - }}, - }, - }, - }, - newUpdate: ðpbv2.LightClientUpdate{ - SyncAggregate: ðpbv1.SyncAggregate{ - SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0] - }, - AttestedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 1000000, - }}, - }, - }, - NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(), - SignatureSlot: 9998, - FinalityBranch: createNonEmptyFinalityBranch(), - FinalizedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 9999, - }}, - }, - }, - }, - expectedResult: true, - }, - { - name: "none of the above conditions are met and new signature's slot is greater than old signature's slot", - oldUpdate: ðpbv2.LightClientUpdate{ - SyncAggregate: ðpbv1.SyncAggregate{ - SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0] - }, - AttestedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 1000000, - }}, - }, - }, - NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(), - SignatureSlot: 9998, - FinalityBranch: createNonEmptyFinalityBranch(), - FinalizedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 9999, - }}, - }, - }, - }, - newUpdate: ðpbv2.LightClientUpdate{ - SyncAggregate: ðpbv1.SyncAggregate{ - SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0] - }, - AttestedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 1000000, - }}, - }, - }, - NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(), - SignatureSlot: 9999, - FinalityBranch: createNonEmptyFinalityBranch(), - FinalizedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: ðpbv2.LightClientHeader{Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 9999, - }}, - }, - }, - }, - expectedResult: false, - }, - } + t.Run("new has supermajority but old doesn't", func(t *testing.T) { + oldUpdate, err := lightclient.CreateDefaultLightClientUpdate(primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1)) + assert.NoError(t, err) + newUpdate, err := lightclient.CreateDefaultLightClientUpdate(primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(2)) + assert.NoError(t, err) - for _, testCase := range testCases { - t.Run(testCase.name, func(t *testing.T) { - result, err := IsBetterUpdate(testCase.newUpdate, testCase.oldUpdate) - assert.NoError(t, err) - assert.Equal(t, testCase.expectedResult, result) + oldUpdate.SetSyncAggregate(&pb.SyncAggregate{ + SyncCommitteeBits: []byte{0b01111100, 0b1}, // [0,0,1,1,1,1,1,0] }) - } + newUpdate.SetSyncAggregate(&pb.SyncAggregate{ + SyncCommitteeBits: []byte{0b11111100, 0b1}, // [0,0,1,1,1,1,1,1] + }) + + result, err := IsBetterUpdate(newUpdate, oldUpdate) + assert.NoError(t, err) + assert.Equal(t, true, result) + }) + + t.Run("old has supermajority but new doesn't", func(t *testing.T) { + oldUpdate, err := lightclient.CreateDefaultLightClientUpdate(primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1)) + assert.NoError(t, err) + newUpdate, err := lightclient.CreateDefaultLightClientUpdate(primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(2)) + assert.NoError(t, err) + + oldUpdate.SetSyncAggregate(&pb.SyncAggregate{ + SyncCommitteeBits: []byte{0b11111100, 0b1}, // [0,0,1,1,1,1,1,1] + }) + newUpdate.SetSyncAggregate(&pb.SyncAggregate{ + SyncCommitteeBits: []byte{0b01111100, 0b1}, // [0,0,1,1,1,1,1,0] + }) + + result, err := IsBetterUpdate(newUpdate, oldUpdate) + assert.NoError(t, err) + assert.Equal(t, false, result) + }) + + t.Run("new doesn't have supermajority and newNumActiveParticipants is greater than oldNumActiveParticipants", func(t *testing.T) { + oldUpdate, err := lightclient.CreateDefaultLightClientUpdate(primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1)) + assert.NoError(t, err) + newUpdate, err := lightclient.CreateDefaultLightClientUpdate(primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(2)) + assert.NoError(t, err) + + oldUpdate.SetSyncAggregate(&pb.SyncAggregate{ + SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0] + }) + newUpdate.SetSyncAggregate(&pb.SyncAggregate{ + SyncCommitteeBits: []byte{0b01111100, 0b1}, // [0,0,1,1,1,1,1,0] + }) + + result, err := IsBetterUpdate(newUpdate, oldUpdate) + assert.NoError(t, err) + assert.Equal(t, true, result) + }) + + t.Run("new doesn't have supermajority and newNumActiveParticipants is lesser than oldNumActiveParticipants", func(t *testing.T) { + oldUpdate, err := lightclient.CreateDefaultLightClientUpdate(primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1)) + assert.NoError(t, err) + newUpdate, err := lightclient.CreateDefaultLightClientUpdate(primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(2)) + assert.NoError(t, err) + + oldUpdate.SetSyncAggregate(&pb.SyncAggregate{ + SyncCommitteeBits: []byte{0b01111100, 0b1}, // [0,0,1,1,1,1,1,0] + }) + newUpdate.SetSyncAggregate(&pb.SyncAggregate{ + SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0] + }) + + result, err := IsBetterUpdate(newUpdate, oldUpdate) + assert.NoError(t, err) + assert.Equal(t, false, result) + }) + + t.Run("new has relevant sync committee but old doesn't", func(t *testing.T) { + oldUpdate, err := lightclient.CreateDefaultLightClientUpdate(primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1)) + assert.NoError(t, err) + newUpdate, err := lightclient.CreateDefaultLightClientUpdate(primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(2)) + assert.NoError(t, err) + + oldUpdate.SetSyncAggregate(&pb.SyncAggregate{ + SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0] + }) + oldAttestedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{ + Beacon: &pb.BeaconBlockHeader{ + Slot: 1000000, + }, + }) + assert.NoError(t, err) + oldUpdate.SetAttestedHeader(oldAttestedHeader) + oldUpdate.SetSignatureSlot(9999) + + newUpdate.SetSyncAggregate(&pb.SyncAggregate{ + SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0] + }) + newAttestedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{ + Beacon: &pb.BeaconBlockHeader{ + Slot: 1000001, + }, + }) + assert.NoError(t, err) + newUpdate.SetAttestedHeader(newAttestedHeader) + err = newUpdate.SetNextSyncCommitteeBranch(createNonEmptySyncCommitteeBranch()) + assert.NoError(t, err) + newUpdate.SetSignatureSlot(1000000) + + result, err := IsBetterUpdate(newUpdate, oldUpdate) + assert.NoError(t, err) + assert.Equal(t, true, result) + }) + + t.Run("old has relevant sync committee but new doesn't", func(t *testing.T) { + oldUpdate, err := lightclient.CreateDefaultLightClientUpdate(primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1)) + assert.NoError(t, err) + newUpdate, err := lightclient.CreateDefaultLightClientUpdate(primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(2)) + assert.NoError(t, err) + + oldUpdate.SetSyncAggregate(&pb.SyncAggregate{ + SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0] + }) + oldAttestedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{ + Beacon: &pb.BeaconBlockHeader{ + Slot: 1000001, + }, + }) + assert.NoError(t, err) + oldUpdate.SetAttestedHeader(oldAttestedHeader) + err = oldUpdate.SetNextSyncCommitteeBranch(createNonEmptySyncCommitteeBranch()) + assert.NoError(t, err) + oldUpdate.SetSignatureSlot(1000000) + + newUpdate.SetSyncAggregate(&pb.SyncAggregate{ + SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0] + }) + newAttestedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{ + Beacon: &pb.BeaconBlockHeader{ + Slot: 1000000, + }, + }) + assert.NoError(t, err) + newUpdate.SetAttestedHeader(newAttestedHeader) + newUpdate.SetSignatureSlot(9999) + + result, err := IsBetterUpdate(newUpdate, oldUpdate) + assert.NoError(t, err) + assert.Equal(t, false, result) + }) + + t.Run("new has finality but old doesn't", func(t *testing.T) { + oldUpdate, err := lightclient.CreateDefaultLightClientUpdate(primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1)) + assert.NoError(t, err) + newUpdate, err := lightclient.CreateDefaultLightClientUpdate(primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(2)) + assert.NoError(t, err) + + oldUpdate.SetSyncAggregate(&pb.SyncAggregate{ + SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0] + }) + oldAttestedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{ + Beacon: &pb.BeaconBlockHeader{ + Slot: 1000000, + }, + }) + assert.NoError(t, err) + oldUpdate.SetAttestedHeader(oldAttestedHeader) + err = oldUpdate.SetNextSyncCommitteeBranch(createNonEmptySyncCommitteeBranch()) + assert.NoError(t, err) + oldUpdate.SetSignatureSlot(9999) + + newUpdate.SetSyncAggregate(&pb.SyncAggregate{ + SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0] + }) + newAttestedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{ + Beacon: &pb.BeaconBlockHeader{ + Slot: 1000000, + }, + }) + assert.NoError(t, err) + newUpdate.SetAttestedHeader(newAttestedHeader) + err = newUpdate.SetNextSyncCommitteeBranch(createNonEmptySyncCommitteeBranch()) + assert.NoError(t, err) + newUpdate.SetSignatureSlot(9999) + err = newUpdate.SetFinalityBranch(createNonEmptyFinalityBranch()) + assert.NoError(t, err) + + result, err := IsBetterUpdate(newUpdate, oldUpdate) + assert.NoError(t, err) + assert.Equal(t, true, result) + }) + + t.Run("old has finality but new doesn't", func(t *testing.T) { + oldUpdate, err := lightclient.CreateDefaultLightClientUpdate(primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1)) + assert.NoError(t, err) + newUpdate, err := lightclient.CreateDefaultLightClientUpdate(primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(2)) + assert.NoError(t, err) + + oldUpdate.SetSyncAggregate(&pb.SyncAggregate{ + SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0] + }) + oldAttestedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{ + Beacon: &pb.BeaconBlockHeader{ + Slot: 1000000, + }, + }) + assert.NoError(t, err) + oldUpdate.SetAttestedHeader(oldAttestedHeader) + err = oldUpdate.SetNextSyncCommitteeBranch(createNonEmptySyncCommitteeBranch()) + assert.NoError(t, err) + oldUpdate.SetSignatureSlot(9999) + err = oldUpdate.SetFinalityBranch(createNonEmptyFinalityBranch()) + assert.NoError(t, err) + + newUpdate.SetSyncAggregate(&pb.SyncAggregate{ + SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0] + }) + newAttestedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{ + Beacon: &pb.BeaconBlockHeader{ + Slot: 1000000, + }, + }) + assert.NoError(t, err) + newUpdate.SetAttestedHeader(newAttestedHeader) + err = newUpdate.SetNextSyncCommitteeBranch(createNonEmptySyncCommitteeBranch()) + assert.NoError(t, err) + newUpdate.SetSignatureSlot(9999) + + result, err := IsBetterUpdate(newUpdate, oldUpdate) + assert.NoError(t, err) + assert.Equal(t, false, result) + }) + + t.Run("new has finality and sync committee finality both but old doesn't have sync committee finality", func(t *testing.T) { + oldUpdate, err := lightclient.CreateDefaultLightClientUpdate(primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1)) + assert.NoError(t, err) + newUpdate, err := lightclient.CreateDefaultLightClientUpdate(primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(2)) + assert.NoError(t, err) + + oldUpdate.SetSyncAggregate(&pb.SyncAggregate{ + SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0] + }) + oldAttestedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{ + Beacon: &pb.BeaconBlockHeader{ + Slot: 1000000, + }, + }) + assert.NoError(t, err) + oldUpdate.SetAttestedHeader(oldAttestedHeader) + err = oldUpdate.SetNextSyncCommitteeBranch(createNonEmptySyncCommitteeBranch()) + assert.NoError(t, err) + err = oldUpdate.SetFinalityBranch(createNonEmptyFinalityBranch()) + assert.NoError(t, err) + oldUpdate.SetSignatureSlot(9999) + oldFinalizedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{ + Beacon: &pb.BeaconBlockHeader{ + Slot: 9999, + }, + }) + assert.NoError(t, err) + oldUpdate.SetFinalizedHeader(oldFinalizedHeader) + + newUpdate.SetSyncAggregate(&pb.SyncAggregate{ + SyncCommitteeBits: []byte{0b01111100, 0b1}, // [0,0,1,1,1,1,1,0] + }) + newAttestedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{ + Beacon: &pb.BeaconBlockHeader{ + Slot: 1000000, + }, + }) + assert.NoError(t, err) + newUpdate.SetAttestedHeader(newAttestedHeader) + err = newUpdate.SetNextSyncCommitteeBranch(createNonEmptySyncCommitteeBranch()) + assert.NoError(t, err) + newUpdate.SetSignatureSlot(999999) + err = newUpdate.SetFinalityBranch(createNonEmptyFinalityBranch()) + assert.NoError(t, err) + newFinalizedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{ + Beacon: &pb.BeaconBlockHeader{ + Slot: 999999, + }, + }) + assert.NoError(t, err) + newUpdate.SetFinalizedHeader(newFinalizedHeader) + + result, err := IsBetterUpdate(newUpdate, oldUpdate) + assert.NoError(t, err) + assert.Equal(t, true, result) + }) + + t.Run("new has finality but doesn't have sync committee finality and old has sync committee finality", func(t *testing.T) { + oldUpdate, err := lightclient.CreateDefaultLightClientUpdate(primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1)) + assert.NoError(t, err) + newUpdate, err := lightclient.CreateDefaultLightClientUpdate(primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(2)) + assert.NoError(t, err) + + oldUpdate.SetSyncAggregate(&pb.SyncAggregate{ + SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0] + }) + oldAttestedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{ + Beacon: &pb.BeaconBlockHeader{ + Slot: 1000000, + }, + }) + assert.NoError(t, err) + oldUpdate.SetAttestedHeader(oldAttestedHeader) + err = oldUpdate.SetNextSyncCommitteeBranch(createNonEmptySyncCommitteeBranch()) + assert.NoError(t, err) + err = oldUpdate.SetFinalityBranch(createNonEmptyFinalityBranch()) + assert.NoError(t, err) + oldUpdate.SetSignatureSlot(999999) + oldFinalizedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{ + Beacon: &pb.BeaconBlockHeader{ + Slot: 999999, + }, + }) + assert.NoError(t, err) + oldUpdate.SetFinalizedHeader(oldFinalizedHeader) + + newUpdate.SetSyncAggregate(&pb.SyncAggregate{ + SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0] + }) + newAttestedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{ + Beacon: &pb.BeaconBlockHeader{ + Slot: 1000000, + }, + }) + assert.NoError(t, err) + newUpdate.SetAttestedHeader(newAttestedHeader) + err = newUpdate.SetNextSyncCommitteeBranch(createNonEmptySyncCommitteeBranch()) + assert.NoError(t, err) + newUpdate.SetSignatureSlot(9999) + err = newUpdate.SetFinalityBranch(createNonEmptyFinalityBranch()) + assert.NoError(t, err) + newFinalizedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{ + Beacon: &pb.BeaconBlockHeader{ + Slot: 9999, + }, + }) + assert.NoError(t, err) + newUpdate.SetFinalizedHeader(newFinalizedHeader) + + result, err := IsBetterUpdate(newUpdate, oldUpdate) + assert.NoError(t, err) + assert.Equal(t, false, result) + }) + + t.Run("new has more active participants than old", func(t *testing.T) { + oldUpdate, err := lightclient.CreateDefaultLightClientUpdate(primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1)) + assert.NoError(t, err) + newUpdate, err := lightclient.CreateDefaultLightClientUpdate(primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(2)) + assert.NoError(t, err) + + oldUpdate.SetSyncAggregate(&pb.SyncAggregate{ + SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0] + }) + newUpdate.SetSyncAggregate(&pb.SyncAggregate{ + SyncCommitteeBits: []byte{0b01111100, 0b1}, // [0,1,1,1,1,1,0,0] + }) + + result, err := IsBetterUpdate(newUpdate, oldUpdate) + assert.NoError(t, err) + assert.Equal(t, true, result) + }) + + t.Run("new has less active participants than old", func(t *testing.T) { + oldUpdate, err := lightclient.CreateDefaultLightClientUpdate(primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1)) + assert.NoError(t, err) + newUpdate, err := lightclient.CreateDefaultLightClientUpdate(primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(2)) + assert.NoError(t, err) + + oldUpdate.SetSyncAggregate(&pb.SyncAggregate{ + SyncCommitteeBits: []byte{0b01111100, 0b1}, // [0,1,1,1,1,1,0,0] + }) + newUpdate.SetSyncAggregate(&pb.SyncAggregate{ + SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0] + }) + + result, err := IsBetterUpdate(newUpdate, oldUpdate) + assert.NoError(t, err) + assert.Equal(t, false, result) + }) + + t.Run("new's attested header's slot is lesser than old's attested header's slot", func(t *testing.T) { + oldUpdate, err := lightclient.CreateDefaultLightClientUpdate(primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1)) + assert.NoError(t, err) + newUpdate, err := lightclient.CreateDefaultLightClientUpdate(primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(2)) + assert.NoError(t, err) + + oldUpdate.SetSyncAggregate(&pb.SyncAggregate{ + SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0] + }) + oldAttestedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{ + Beacon: &pb.BeaconBlockHeader{ + Slot: 1000000, + }, + }) + assert.NoError(t, err) + oldUpdate.SetAttestedHeader(oldAttestedHeader) + err = oldUpdate.SetNextSyncCommitteeBranch(createNonEmptySyncCommitteeBranch()) + assert.NoError(t, err) + err = oldUpdate.SetFinalityBranch(createNonEmptyFinalityBranch()) + assert.NoError(t, err) + oldUpdate.SetSignatureSlot(9999) + oldFinalizedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{ + Beacon: &pb.BeaconBlockHeader{ + Slot: 9999, + }, + }) + assert.NoError(t, err) + oldUpdate.SetFinalizedHeader(oldFinalizedHeader) + + newUpdate.SetSyncAggregate(&pb.SyncAggregate{ + SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0] + }) + newAttestedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{ + Beacon: &pb.BeaconBlockHeader{ + Slot: 999999, + }, + }) + assert.NoError(t, err) + newUpdate.SetAttestedHeader(newAttestedHeader) + err = newUpdate.SetNextSyncCommitteeBranch(createNonEmptySyncCommitteeBranch()) + assert.NoError(t, err) + newUpdate.SetSignatureSlot(9999) + err = newUpdate.SetFinalityBranch(createNonEmptyFinalityBranch()) + assert.NoError(t, err) + newFinalizedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{ + Beacon: &pb.BeaconBlockHeader{ + Slot: 9999, + }, + }) + assert.NoError(t, err) + newUpdate.SetFinalizedHeader(newFinalizedHeader) + + result, err := IsBetterUpdate(newUpdate, oldUpdate) + assert.NoError(t, err) + assert.Equal(t, true, result) + }) + + t.Run("new's attested header's slot is greater than old's attested header's slot", func(t *testing.T) { + oldUpdate, err := lightclient.CreateDefaultLightClientUpdate(primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1)) + assert.NoError(t, err) + newUpdate, err := lightclient.CreateDefaultLightClientUpdate(primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(2)) + assert.NoError(t, err) + + oldUpdate.SetSyncAggregate(&pb.SyncAggregate{ + SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0] + }) + oldAttestedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{ + Beacon: &pb.BeaconBlockHeader{ + Slot: 999999, + }, + }) + assert.NoError(t, err) + oldUpdate.SetAttestedHeader(oldAttestedHeader) + err = oldUpdate.SetNextSyncCommitteeBranch(createNonEmptySyncCommitteeBranch()) + assert.NoError(t, err) + err = oldUpdate.SetFinalityBranch(createNonEmptyFinalityBranch()) + assert.NoError(t, err) + oldUpdate.SetSignatureSlot(9999) + oldFinalizedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{ + Beacon: &pb.BeaconBlockHeader{ + Slot: 9999, + }, + }) + assert.NoError(t, err) + oldUpdate.SetFinalizedHeader(oldFinalizedHeader) + + newUpdate.SetSyncAggregate(&pb.SyncAggregate{ + SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0] + }) + newAttestedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{ + Beacon: &pb.BeaconBlockHeader{ + Slot: 1000000, + }, + }) + assert.NoError(t, err) + newUpdate.SetAttestedHeader(newAttestedHeader) + err = newUpdate.SetNextSyncCommitteeBranch(createNonEmptySyncCommitteeBranch()) + assert.NoError(t, err) + newUpdate.SetSignatureSlot(9999) + err = newUpdate.SetFinalityBranch(createNonEmptyFinalityBranch()) + assert.NoError(t, err) + newFinalizedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{ + Beacon: &pb.BeaconBlockHeader{ + Slot: 9999, + }, + }) + assert.NoError(t, err) + newUpdate.SetFinalizedHeader(newFinalizedHeader) + + result, err := IsBetterUpdate(newUpdate, oldUpdate) + assert.NoError(t, err) + assert.Equal(t, false, result) + }) + + t.Run("none of the above conditions are met and new signature's slot is less than old signature's slot", func(t *testing.T) { + oldUpdate, err := lightclient.CreateDefaultLightClientUpdate(primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1)) + assert.NoError(t, err) + newUpdate, err := lightclient.CreateDefaultLightClientUpdate(primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(2)) + assert.NoError(t, err) + + oldUpdate.SetSyncAggregate(&pb.SyncAggregate{ + SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0] + }) + oldAttestedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{ + Beacon: &pb.BeaconBlockHeader{ + Slot: 1000000, + }, + }) + assert.NoError(t, err) + oldUpdate.SetAttestedHeader(oldAttestedHeader) + err = oldUpdate.SetNextSyncCommitteeBranch(createNonEmptySyncCommitteeBranch()) + assert.NoError(t, err) + err = oldUpdate.SetFinalityBranch(createNonEmptyFinalityBranch()) + assert.NoError(t, err) + oldUpdate.SetSignatureSlot(9999) + oldFinalizedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{ + Beacon: &pb.BeaconBlockHeader{ + Slot: 9999, + }, + }) + assert.NoError(t, err) + oldUpdate.SetFinalizedHeader(oldFinalizedHeader) + + newUpdate.SetSyncAggregate(&pb.SyncAggregate{ + SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0] + }) + newAttestedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{ + Beacon: &pb.BeaconBlockHeader{ + Slot: 1000000, + }, + }) + assert.NoError(t, err) + newUpdate.SetAttestedHeader(newAttestedHeader) + err = newUpdate.SetNextSyncCommitteeBranch(createNonEmptySyncCommitteeBranch()) + assert.NoError(t, err) + newUpdate.SetSignatureSlot(9998) + err = newUpdate.SetFinalityBranch(createNonEmptyFinalityBranch()) + assert.NoError(t, err) + newFinalizedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{ + Beacon: &pb.BeaconBlockHeader{ + Slot: 9999, + }, + }) + assert.NoError(t, err) + newUpdate.SetFinalizedHeader(newFinalizedHeader) + + result, err := IsBetterUpdate(newUpdate, oldUpdate) + assert.NoError(t, err) + assert.Equal(t, true, result) + }) + + t.Run("none of the above conditions are met and new signature's slot is greater than old signature's slot", func(t *testing.T) { + oldUpdate, err := lightclient.CreateDefaultLightClientUpdate(primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1)) + assert.NoError(t, err) + newUpdate, err := lightclient.CreateDefaultLightClientUpdate(primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(2)) + assert.NoError(t, err) + + oldUpdate.SetSyncAggregate(&pb.SyncAggregate{ + SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0] + }) + oldAttestedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{ + Beacon: &pb.BeaconBlockHeader{ + Slot: 1000000, + }, + }) + assert.NoError(t, err) + oldUpdate.SetAttestedHeader(oldAttestedHeader) + err = oldUpdate.SetNextSyncCommitteeBranch(createNonEmptySyncCommitteeBranch()) + assert.NoError(t, err) + err = oldUpdate.SetFinalityBranch(createNonEmptyFinalityBranch()) + assert.NoError(t, err) + oldUpdate.SetSignatureSlot(9998) + oldFinalizedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{ + Beacon: &pb.BeaconBlockHeader{ + Slot: 9999, + }, + }) + assert.NoError(t, err) + oldUpdate.SetFinalizedHeader(oldFinalizedHeader) + + newUpdate.SetSyncAggregate(&pb.SyncAggregate{ + SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0] + }) + newAttestedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{ + Beacon: &pb.BeaconBlockHeader{ + Slot: 1000000, + }, + }) + assert.NoError(t, err) + newUpdate.SetAttestedHeader(newAttestedHeader) + err = newUpdate.SetNextSyncCommitteeBranch(createNonEmptySyncCommitteeBranch()) + assert.NoError(t, err) + newUpdate.SetSignatureSlot(9999) + err = newUpdate.SetFinalityBranch(createNonEmptyFinalityBranch()) + assert.NoError(t, err) + newFinalizedHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{ + Beacon: &pb.BeaconBlockHeader{ + Slot: 9999, + }, + }) + assert.NoError(t, err) + newUpdate.SetFinalizedHeader(newFinalizedHeader) + + result, err := IsBetterUpdate(newUpdate, oldUpdate) + assert.NoError(t, err) + assert.Equal(t, false, result) + }) } diff --git a/testing/util/lightclient.go b/testing/util/lightclient.go index a79e7f8f72d9..3a41d2b5150f 100644 --- a/testing/util/lightclient.go +++ b/testing/util/lightclient.go @@ -14,9 +14,8 @@ import ( "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" "github.com/prysmaticlabs/prysm/v5/encoding/ssz" v11 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1" - ethpbv1 "github.com/prysmaticlabs/prysm/v5/proto/eth/v1" - ethpbv2 "github.com/prysmaticlabs/prysm/v5/proto/eth/v2" ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" + pb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" "github.com/prysmaticlabs/prysm/v5/runtime/version" "github.com/prysmaticlabs/prysm/v5/testing/require" ) @@ -765,9 +764,8 @@ func (l *TestLightClient) SetupTestDenebFinalizedBlockCapella(blinded bool) *Tes return l } -func (l *TestLightClient) CheckAttestedHeader(container *ethpbv2.LightClientHeaderContainer) { - updateAttestedHeaderBeacon, err := container.GetBeacon() - require.NoError(l.T, err) +func (l *TestLightClient) CheckAttestedHeader(header interfaces.LightClientHeader) { + updateAttestedHeaderBeacon := header.Beacon() testAttestedHeader, err := l.AttestedBlock.Header() require.NoError(l.T, err) require.Equal(l.T, l.AttestedBlock.Block().Slot(), updateAttestedHeaderBeacon.Slot, "Attested block slot is not equal") @@ -820,13 +818,13 @@ func (l *TestLightClient) CheckAttestedHeader(container *ethpbv2.LightClientHead WithdrawalsRoot: withdrawalsRoot, } - updateAttestedHeaderExecution, err := container.GetExecutionHeaderCapella() + updateAttestedHeaderExecution, err := header.Execution() require.NoError(l.T, err) require.DeepSSZEqual(l.T, execution, updateAttestedHeaderExecution, "Attested Block Execution is not equal") executionPayloadProof, err := blocks.PayloadProof(l.Ctx, l.AttestedBlock.Block()) require.NoError(l.T, err) - updateAttestedHeaderExecutionBranch, err := container.GetExecutionBranch() + updateAttestedHeaderExecutionBranch, err := header.ExecutionBranch() require.NoError(l.T, err) for i, leaf := range updateAttestedHeaderExecutionBranch { require.DeepSSZEqual(l.T, executionPayloadProof[i], leaf, "Leaf is not equal") @@ -874,13 +872,13 @@ func (l *TestLightClient) CheckAttestedHeader(container *ethpbv2.LightClientHead WithdrawalsRoot: withdrawalsRoot, } - updateAttestedHeaderExecution, err := container.GetExecutionHeaderDeneb() + updateAttestedHeaderExecution, err := header.Execution() require.NoError(l.T, err) require.DeepSSZEqual(l.T, execution, updateAttestedHeaderExecution, "Attested Block Execution is not equal") executionPayloadProof, err := blocks.PayloadProof(l.Ctx, l.AttestedBlock.Block()) require.NoError(l.T, err) - updateAttestedHeaderExecutionBranch, err := container.GetExecutionBranch() + updateAttestedHeaderExecutionBranch, err := header.ExecutionBranch() require.NoError(l.T, err) for i, leaf := range updateAttestedHeaderExecutionBranch { require.DeepSSZEqual(l.T, executionPayloadProof[i], leaf, "Leaf is not equal") @@ -888,7 +886,7 @@ func (l *TestLightClient) CheckAttestedHeader(container *ethpbv2.LightClientHead } } -func (l *TestLightClient) CheckSyncAggregate(sa *ethpbv1.SyncAggregate) { +func (l *TestLightClient) CheckSyncAggregate(sa *pb.SyncAggregate) { syncAggregate, err := l.Block.Block().Body().SyncAggregate() require.NoError(l.T, err) require.DeepSSZEqual(l.T, syncAggregate.SyncCommitteeBits, sa.SyncCommitteeBits, "SyncAggregate bits is not equal") From f8cb14cbcd80f4f3b60f74381f0d51bf1477d8b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20Kapka?= Date: Tue, 22 Oct 2024 22:25:29 +0700 Subject: [PATCH 21/35] Return the correct light client payload proof (#14565) * Return the correct payload proof * changelog <3 --- CHANGELOG.md | 1 + consensus-types/blocks/proofs.go | 18 ++++-------------- 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c8e84e164b81..fb3918d42d59 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,6 +41,7 @@ The format is based on Keep a Changelog, and this project adheres to Semantic Ve - Fixed mesh size by appending `gParams.Dhi = gossipSubDhi` - Fix skipping partial withdrawals count. - recover from panics when writing the event stream [pr](https://github.com/prysmaticlabs/prysm/pull/14545) +- Return the correct light client payload proof. [PR](https://github.com/prysmaticlabs/prysm/pull/14565) ### Security diff --git a/consensus-types/blocks/proofs.go b/consensus-types/blocks/proofs.go index 19d399a9c9b4..4bd114af9f1e 100644 --- a/consensus-types/blocks/proofs.go +++ b/consensus-types/blocks/proofs.go @@ -240,23 +240,13 @@ func PayloadProof(ctx context.Context, block interfaces.ReadOnlyBeaconBlock) ([] return nil, errors.New("failed to cast block body") } - blockBodyFieldRoots, err := ComputeBlockBodyFieldRoots(ctx, blockBody) + fieldRoots, err := ComputeBlockBodyFieldRoots(ctx, blockBody) if err != nil { return nil, err } - blockBodyFieldRootsTrie := stateutil.Merkleize(blockBodyFieldRoots) - blockBodyProof := trie.ProofFromMerkleLayers(blockBodyFieldRootsTrie, payloadFieldIndex) + fieldRootsTrie := stateutil.Merkleize(fieldRoots) + proof := trie.ProofFromMerkleLayers(fieldRootsTrie, payloadFieldIndex) - beaconBlockFieldRoots, err := ComputeBlockFieldRoots(ctx, block) - if err != nil { - return nil, err - } - - beaconBlockFieldRootsTrie := stateutil.Merkleize(beaconBlockFieldRoots) - beaconBlockProof := trie.ProofFromMerkleLayers(beaconBlockFieldRootsTrie, bodyFieldIndex) - - finalProof := append(blockBodyProof, beaconBlockProof...) - - return finalProof, nil + return proof, nil } From 36256e67d744b0d16377c66c71132a1d980c9c2c Mon Sep 17 00:00:00 2001 From: Inspector-Butters Date: Wed, 23 Oct 2024 12:07:54 +0200 Subject: [PATCH 22/35] merge --- beacon-chain/core/light-client/lightclient.go | 18 +- .../core/light-client/lightclient_test.go | 36 +- beacon-chain/db/kv/lightclient_test.go | 1579 +++---- .../rpc/eth/light-client/handlers_test.go | 3610 ++++++++--------- 4 files changed, 2656 insertions(+), 2587 deletions(-) diff --git a/beacon-chain/core/light-client/lightclient.go b/beacon-chain/core/light-client/lightclient.go index 7b4e9f94ce28..7e8eac58007f 100644 --- a/beacon-chain/core/light-client/lightclient.go +++ b/beacon-chain/core/light-client/lightclient.go @@ -281,21 +281,33 @@ func CreateDefaultLightClientUpdate(currentSlot primitives.Slot) (interfaces.Lig } } else if currentEpoch < params.BeaconConfig().DenebForkEpoch { m = &pb.LightClientUpdateCapella{ - AttestedHeader: &pb.LightClientHeaderCapella{}, + AttestedHeader: &pb.LightClientHeaderCapella{ + Beacon: &pb.BeaconBlockHeader{}, + Execution: &enginev1.ExecutionPayloadHeaderCapella{}, + ExecutionBranch: executionBranch, + }, NextSyncCommittee: nextSyncCommittee, NextSyncCommitteeBranch: nextSyncCommitteeBranch, FinalityBranch: finalityBranch, } } else if currentEpoch < params.BeaconConfig().ElectraForkEpoch { m = &pb.LightClientUpdateDeneb{ - AttestedHeader: &pb.LightClientHeaderDeneb{}, + AttestedHeader: &pb.LightClientHeaderDeneb{ + Beacon: &pb.BeaconBlockHeader{}, + Execution: &enginev1.ExecutionPayloadHeaderDeneb{}, + ExecutionBranch: executionBranch, + }, NextSyncCommittee: nextSyncCommittee, NextSyncCommitteeBranch: nextSyncCommitteeBranch, FinalityBranch: finalityBranch, } } else { m = &pb.LightClientUpdateElectra{ - AttestedHeader: &pb.LightClientHeaderDeneb{}, + AttestedHeader: &pb.LightClientHeaderDeneb{ + Beacon: &pb.BeaconBlockHeader{}, + Execution: &enginev1.ExecutionPayloadHeaderDeneb{}, + ExecutionBranch: executionBranch, + }, NextSyncCommittee: nextSyncCommittee, NextSyncCommitteeBranch: nextSyncCommitteeBranch, FinalityBranch: finalityBranch, diff --git a/beacon-chain/core/light-client/lightclient_test.go b/beacon-chain/core/light-client/lightclient_test.go index 045eaeeadeac..19568ec3cb4f 100644 --- a/beacon-chain/core/light-client/lightclient_test.go +++ b/beacon-chain/core/light-client/lightclient_test.go @@ -15,36 +15,36 @@ func TestLightClient_NewLightClientOptimisticUpdateFromBeaconState(t *testing.T) update, err := lightClient.NewLightClientOptimisticUpdateFromBeaconState(l.Ctx, l.State.Slot(), l.State, l.Block, l.AttestedState, l.AttestedBlock) require.NoError(t, err) require.NotNil(t, update, "update is nil") - require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot, "Signature slot is not equal") + require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot(), "Signature slot is not equal") + + l.CheckSyncAggregate(update.SyncAggregate()) + l.CheckAttestedHeader(update.AttestedHeader()) + }) + + t.Run("Capella", func(t *testing.T) { + l := util.NewTestLightClient(t).SetupTestCapella(false) + + update, err := lightClient.NewLightClientOptimisticUpdateFromBeaconState(l.Ctx, l.State.Slot(), l.State, l.Block, l.AttestedState, l.AttestedBlock) + require.NoError(t, err) + require.NotNil(t, update, "update is nil") + + require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot(), "Signature slot is not equal") l.CheckSyncAggregate(update.SyncAggregate()) l.CheckAttestedHeader(update.AttestedHeader()) }) - //t.Run("Capella", func(t *testing.T) { - // l := util.NewTestLightClient(t).SetupTestCapella(false) - // - // update, err := lightClient.NewLightClientOptimisticUpdateFromBeaconState(l.Ctx, l.State, l.Block, l.AttestedState, l.AttestedBlock) - // require.NoError(t, err) - // require.NotNil(t, update, "update is nil") - // - // require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot, "Signature slot is not equal") - // - // l.CheckSyncAggregate(update.SyncAggregate) - // l.CheckAttestedHeader(update.AttestedHeader) - //}) - // //t.Run("Deneb", func(t *testing.T) { // l := util.NewTestLightClient(t).SetupTestDeneb(false) // - // update, err := lightClient.NewLightClientOptimisticUpdateFromBeaconState(l.Ctx, l.State, l.Block, l.AttestedState, l.AttestedBlock) + // update, err := lightClient.NewLightClientOptimisticUpdateFromBeaconState(l.Ctx, l.State.Slot(), l.State, l.Block, l.AttestedState, l.AttestedBlock) // require.NoError(t, err) // require.NotNil(t, update, "update is nil") // - // require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot, "Signature slot is not equal") + // require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot(), "Signature slot is not equal") // - // l.CheckSyncAggregate(update.SyncAggregate) - // l.CheckAttestedHeader(update.AttestedHeader) + // l.CheckSyncAggregate(update.SyncAggregate()) + // l.CheckAttestedHeader(update.AttestedHeader()) //}) } diff --git a/beacon-chain/db/kv/lightclient_test.go b/beacon-chain/db/kv/lightclient_test.go index dd2df2acac8b..c1eb29a13028 100644 --- a/beacon-chain/db/kv/lightclient_test.go +++ b/beacon-chain/db/kv/lightclient_test.go @@ -4,786 +4,853 @@ import ( "context" "testing" + fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams" + "github.com/prysmaticlabs/prysm/v5/config/params" + "github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces" + light_client "github.com/prysmaticlabs/prysm/v5/consensus-types/light-client" "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" enginev1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1" - ethpbv1 "github.com/prysmaticlabs/prysm/v5/proto/eth/v1" - ethpbv2 "github.com/prysmaticlabs/prysm/v5/proto/eth/v2" - "github.com/prysmaticlabs/prysm/v5/runtime/version" + pb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" "github.com/prysmaticlabs/prysm/v5/testing/require" + "github.com/prysmaticlabs/prysm/v5/time/slots" + "google.golang.org/protobuf/proto" ) func TestStore_LightClientUpdate_CanSaveRetrieveAltair(t *testing.T) { db := setupDB(t) ctx := context.Background() - update := ðpbv2.LightClientUpdate{ - AttestedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: ðpbv2.LightClientHeader{ - Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 1, - ProposerIndex: 1, - ParentRoot: []byte{1, 1, 1}, - StateRoot: []byte{1, 1, 1}, - BodyRoot: []byte{1, 1, 1}, - }, - }, - }, - }, - NextSyncCommittee: ðpbv2.SyncCommittee{ - Pubkeys: nil, - AggregatePubkey: nil, - }, - NextSyncCommitteeBranch: nil, - FinalizedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ - HeaderAltair: ðpbv2.LightClientHeader{ - Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 1, - ProposerIndex: 1, - ParentRoot: []byte{1, 1, 1}, - StateRoot: []byte{1, 1, 1}, - BodyRoot: []byte{1, 1, 1}, - }, - }, - }, - }, - FinalityBranch: nil, - SyncAggregate: nil, - SignatureSlot: 7, - } - period := uint64(1) - err := db.SaveLightClientUpdate(ctx, period, ðpbv2.LightClientUpdateWithVersion{ - Version: version.Altair, - Data: update, - }) - require.NoError(t, err) - - retrievedUpdate, err := db.LightClientUpdate(ctx, period) + params.SetupTestConfigCleanup(t) + config := params.BeaconConfig() + update, err := createDefaultLightClientUpdate(primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1)) require.NoError(t, err) - require.DeepEqual(t, update, retrievedUpdate.Data, "retrieved update does not match saved update") -} - -func TestStore_LightClientUpdate_CanSaveRetrieveCapella(t *testing.T) { - db := setupDB(t) - ctx := context.Background() - update := ðpbv2.LightClientUpdate{ - AttestedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ - HeaderCapella: ðpbv2.LightClientHeaderCapella{ - Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 1, - ProposerIndex: 1, - ParentRoot: []byte{1, 1, 1}, - StateRoot: []byte{1, 1, 1}, - BodyRoot: []byte{1, 1, 1}, - }, - Execution: &enginev1.ExecutionPayloadHeaderCapella{ - FeeRecipient: []byte{1, 2, 3}, - }, - ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, - }, - }, + update.SetSignatureSlot(7) + parentRoot := make([]byte, 32) + for i := 0; i < 32; i++ { + parentRoot[i] = byte(i) + } + simpleHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{ + Beacon: &pb.BeaconBlockHeader{ + Slot: 1, + ProposerIndex: 1, + ParentRoot: parentRoot, + StateRoot: []byte{1, 1, 1}, + BodyRoot: []byte{1, 1, 1}, }, - NextSyncCommittee: ðpbv2.SyncCommittee{ - Pubkeys: nil, - AggregatePubkey: nil, - }, - NextSyncCommitteeBranch: nil, - FinalizedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ - HeaderCapella: ðpbv2.LightClientHeaderCapella{ - Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 1, - ProposerIndex: 1, - ParentRoot: []byte{1, 1, 1}, - StateRoot: []byte{1, 1, 1}, - BodyRoot: []byte{1, 1, 1}, - }, - Execution: nil, - ExecutionBranch: nil, - }, - }, - }, - FinalityBranch: nil, - SyncAggregate: nil, - SignatureSlot: 7, - } - period := uint64(1) - err := db.SaveLightClientUpdate(ctx, period, ðpbv2.LightClientUpdateWithVersion{ - Version: version.Capella, - Data: update, }) require.NoError(t, err) + update.SetAttestedHeader(simpleHeader) + update.SetFinalizedHeader(simpleHeader) - retrievedUpdate, err := db.LightClientUpdate(ctx, period) - require.NoError(t, err) - require.DeepEqual(t, update, retrievedUpdate.Data, "retrieved update does not match saved update") -} - -func TestStore_LightClientUpdate_CanSaveRetrieveDeneb(t *testing.T) { - db := setupDB(t) - ctx := context.Background() - update := ðpbv2.LightClientUpdate{ - AttestedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderDeneb{ - HeaderDeneb: ðpbv2.LightClientHeaderDeneb{ - Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 1, - ProposerIndex: 1, - ParentRoot: []byte{1, 1, 1}, - StateRoot: []byte{1, 1, 1}, - BodyRoot: []byte{1, 1, 1}, - }, - Execution: &enginev1.ExecutionPayloadHeaderDeneb{ - FeeRecipient: []byte{1, 2, 3}, - }, - ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, - }, - }, - }, - NextSyncCommittee: ðpbv2.SyncCommittee{ - Pubkeys: nil, - AggregatePubkey: nil, - }, - NextSyncCommitteeBranch: nil, - FinalizedHeader: ðpbv2.LightClientHeaderContainer{ - Header: ðpbv2.LightClientHeaderContainer_HeaderDeneb{ - HeaderDeneb: ðpbv2.LightClientHeaderDeneb{ - Beacon: ðpbv1.BeaconBlockHeader{ - Slot: 1, - ProposerIndex: 1, - ParentRoot: []byte{1, 1, 1}, - StateRoot: []byte{1, 1, 1}, - BodyRoot: []byte{1, 1, 1}, - }, - Execution: nil, - ExecutionBranch: nil, - }, - }, - }, - FinalityBranch: nil, - SyncAggregate: nil, - SignatureSlot: 7, - } period := uint64(1) - err := db.SaveLightClientUpdate(ctx, period, ðpbv2.LightClientUpdateWithVersion{ - Version: version.Deneb, - Data: update, - }) - require.NoError(t, err) - - retrievedUpdate, err := db.LightClientUpdate(ctx, period) - require.NoError(t, err) - require.DeepEqual(t, update, retrievedUpdate.Data, "retrieved update does not match saved update") -} - -func TestStore_LightClientUpdates_canRetrieveRange(t *testing.T) { - db := setupDB(t) - ctx := context.Background() - updates := []*ethpbv2.LightClientUpdateWithVersion{ - { - Version: 1, - Data: ðpbv2.LightClientUpdate{ - AttestedHeader: nil, - NextSyncCommittee: nil, - NextSyncCommitteeBranch: nil, - FinalizedHeader: nil, - FinalityBranch: nil, - SyncAggregate: nil, - SignatureSlot: 7, - }, - }, - { - Version: 1, - Data: ðpbv2.LightClientUpdate{ - AttestedHeader: nil, - NextSyncCommittee: nil, - NextSyncCommitteeBranch: nil, - FinalizedHeader: nil, - FinalityBranch: nil, - SyncAggregate: nil, - SignatureSlot: 8, - }, - }, - { - Version: 1, - Data: ðpbv2.LightClientUpdate{ - AttestedHeader: nil, - NextSyncCommittee: nil, - NextSyncCommitteeBranch: nil, - FinalizedHeader: nil, - FinalityBranch: nil, - SyncAggregate: nil, - SignatureSlot: 9, - }, - }, - } - - for i, update := range updates { - err := db.SaveLightClientUpdate(ctx, uint64(i+1), update) - require.NoError(t, err) - } - - // Retrieve the updates - retrievedUpdatesMap, err := db.LightClientUpdates(ctx, 1, 3) - require.NoError(t, err) - require.Equal(t, len(updates), len(retrievedUpdatesMap), "retrieved updates do not match saved updates") - for i, update := range updates { - require.Equal(t, update.Data.SignatureSlot, retrievedUpdatesMap[uint64(i+1)].Data.SignatureSlot, "retrieved update does not match saved update") - } -} - -func TestStore_LightClientUpdate_EndPeriodSmallerThanStartPeriod(t *testing.T) { - db := setupDB(t) - ctx := context.Background() - updates := []*ethpbv2.LightClientUpdateWithVersion{ - { - Version: 1, - Data: ðpbv2.LightClientUpdate{ - AttestedHeader: nil, - NextSyncCommittee: nil, - NextSyncCommitteeBranch: nil, - FinalizedHeader: nil, - FinalityBranch: nil, - SyncAggregate: nil, - SignatureSlot: 7, - }, - }, - { - Version: 1, - Data: ðpbv2.LightClientUpdate{ - AttestedHeader: nil, - NextSyncCommittee: nil, - NextSyncCommitteeBranch: nil, - FinalizedHeader: nil, - FinalityBranch: nil, - SyncAggregate: nil, - SignatureSlot: 8, - }, - }, - { - Version: 1, - Data: ðpbv2.LightClientUpdate{ - AttestedHeader: nil, - NextSyncCommittee: nil, - NextSyncCommitteeBranch: nil, - FinalizedHeader: nil, - FinalityBranch: nil, - SyncAggregate: nil, - SignatureSlot: 9, - }, - }, - } - - for i, update := range updates { - err := db.SaveLightClientUpdate(ctx, uint64(i+1), update) - require.NoError(t, err) - } - - // Retrieve the updates - retrievedUpdates, err := db.LightClientUpdates(ctx, 3, 1) - require.NotNil(t, err) - require.Equal(t, err.Error(), "start period 3 is greater than end period 1") - require.IsNil(t, retrievedUpdates) - -} - -func TestStore_LightClientUpdate_EndPeriodEqualToStartPeriod(t *testing.T) { - db := setupDB(t) - ctx := context.Background() - updates := []*ethpbv2.LightClientUpdateWithVersion{ - { - Version: 1, - Data: ðpbv2.LightClientUpdate{ - AttestedHeader: nil, - NextSyncCommittee: nil, - NextSyncCommitteeBranch: nil, - FinalizedHeader: nil, - FinalityBranch: nil, - SyncAggregate: nil, - SignatureSlot: 7, - }, - }, - { - Version: 1, - Data: ðpbv2.LightClientUpdate{ - AttestedHeader: nil, - NextSyncCommittee: nil, - NextSyncCommitteeBranch: nil, - FinalizedHeader: nil, - FinalityBranch: nil, - SyncAggregate: nil, - SignatureSlot: 8, - }, - }, - { - Version: 1, - Data: ðpbv2.LightClientUpdate{ - AttestedHeader: nil, - NextSyncCommittee: nil, - NextSyncCommitteeBranch: nil, - FinalizedHeader: nil, - FinalityBranch: nil, - SyncAggregate: nil, - SignatureSlot: 9, - }, - }, - } - - for i, update := range updates { - err := db.SaveLightClientUpdate(ctx, uint64(i+1), update) - require.NoError(t, err) - } - - // Retrieve the updates - retrievedUpdates, err := db.LightClientUpdates(ctx, 2, 2) + err = db.SaveLightClientUpdate(ctx, period, update) require.NoError(t, err) - require.Equal(t, 1, len(retrievedUpdates)) - require.Equal(t, updates[1].Data.SignatureSlot, retrievedUpdates[2].Data.SignatureSlot, "retrieved update does not match saved update") -} - -func TestStore_LightClientUpdate_StartPeriodBeforeFirstUpdate(t *testing.T) { - db := setupDB(t) - ctx := context.Background() - updates := []*ethpbv2.LightClientUpdateWithVersion{ - { - Version: 1, - Data: ðpbv2.LightClientUpdate{ - AttestedHeader: nil, - NextSyncCommittee: nil, - NextSyncCommitteeBranch: nil, - FinalizedHeader: nil, - FinalityBranch: nil, - SyncAggregate: nil, - SignatureSlot: 7, - }, - }, - { - Version: 1, - Data: ðpbv2.LightClientUpdate{ - AttestedHeader: nil, - NextSyncCommittee: nil, - NextSyncCommitteeBranch: nil, - FinalizedHeader: nil, - FinalityBranch: nil, - SyncAggregate: nil, - SignatureSlot: 8, - }, - }, - { - Version: 1, - Data: ðpbv2.LightClientUpdate{ - AttestedHeader: nil, - NextSyncCommittee: nil, - NextSyncCommitteeBranch: nil, - FinalizedHeader: nil, - FinalityBranch: nil, - SyncAggregate: nil, - SignatureSlot: 9, - }, - }, - } - for i, update := range updates { - err := db.SaveLightClientUpdate(ctx, uint64(i+2), update) - require.NoError(t, err) - } - - // Retrieve the updates - retrievedUpdates, err := db.LightClientUpdates(ctx, 0, 4) - require.NoError(t, err) - require.Equal(t, 3, len(retrievedUpdates)) - for i, update := range updates { - require.Equal(t, update.Data.SignatureSlot, retrievedUpdates[uint64(i+2)].Data.SignatureSlot, "retrieved update does not match saved update") - } -} - -func TestStore_LightClientUpdate_EndPeriodAfterLastUpdate(t *testing.T) { - db := setupDB(t) - ctx := context.Background() - updates := []*ethpbv2.LightClientUpdateWithVersion{ - { - Version: 1, - Data: ðpbv2.LightClientUpdate{ - AttestedHeader: nil, - NextSyncCommittee: nil, - NextSyncCommitteeBranch: nil, - FinalizedHeader: nil, - FinalityBranch: nil, - SyncAggregate: nil, - SignatureSlot: 7, - }, - }, - { - Version: 1, - Data: ðpbv2.LightClientUpdate{ - AttestedHeader: nil, - NextSyncCommittee: nil, - NextSyncCommitteeBranch: nil, - FinalizedHeader: nil, - FinalityBranch: nil, - SyncAggregate: nil, - SignatureSlot: 8, - }, - }, - { - Version: 1, - Data: ðpbv2.LightClientUpdate{ - AttestedHeader: nil, - NextSyncCommittee: nil, - NextSyncCommitteeBranch: nil, - FinalizedHeader: nil, - FinalityBranch: nil, - SyncAggregate: nil, - SignatureSlot: 9, - }, - }, - } - - for i, update := range updates { - err := db.SaveLightClientUpdate(ctx, uint64(i+1), update) - require.NoError(t, err) - } - - // Retrieve the updates - retrievedUpdates, err := db.LightClientUpdates(ctx, 1, 6) - require.NoError(t, err) - require.Equal(t, 3, len(retrievedUpdates)) - for i, update := range updates { - require.Equal(t, update.Data.SignatureSlot, retrievedUpdates[uint64(i+1)].Data.SignatureSlot, "retrieved update does not match saved update") - } -} - -func TestStore_LightClientUpdate_PartialUpdates(t *testing.T) { - db := setupDB(t) - ctx := context.Background() - updates := []*ethpbv2.LightClientUpdateWithVersion{ - { - Version: 1, - Data: ðpbv2.LightClientUpdate{ - AttestedHeader: nil, - NextSyncCommittee: nil, - NextSyncCommitteeBranch: nil, - FinalizedHeader: nil, - FinalityBranch: nil, - SyncAggregate: nil, - SignatureSlot: 7, - }, - }, - { - Version: 1, - Data: ðpbv2.LightClientUpdate{ - AttestedHeader: nil, - NextSyncCommittee: nil, - NextSyncCommitteeBranch: nil, - FinalizedHeader: nil, - FinalityBranch: nil, - SyncAggregate: nil, - SignatureSlot: 8, - }, - }, - { - Version: 1, - Data: ðpbv2.LightClientUpdate{ - AttestedHeader: nil, - NextSyncCommittee: nil, - NextSyncCommitteeBranch: nil, - FinalizedHeader: nil, - FinalityBranch: nil, - SyncAggregate: nil, - SignatureSlot: 9, - }, - }, - } - - for i, update := range updates { - err := db.SaveLightClientUpdate(ctx, uint64(i+1), update) - require.NoError(t, err) - } - - // Retrieve the updates - retrievedUpdates, err := db.LightClientUpdates(ctx, 1, 2) - require.NoError(t, err) - require.Equal(t, 2, len(retrievedUpdates)) - for i, update := range updates[:2] { - require.Equal(t, update.Data.SignatureSlot, retrievedUpdates[uint64(i+1)].Data.SignatureSlot, "retrieved update does not match saved update") - } -} - -func TestStore_LightClientUpdate_MissingPeriods_SimpleData(t *testing.T) { - db := setupDB(t) - ctx := context.Background() - updates := []*ethpbv2.LightClientUpdateWithVersion{ - { - Version: 1, - Data: ðpbv2.LightClientUpdate{ - AttestedHeader: nil, - NextSyncCommittee: nil, - NextSyncCommitteeBranch: nil, - FinalizedHeader: nil, - FinalityBranch: nil, - SyncAggregate: nil, - SignatureSlot: 7, - }, - }, - { - Version: 1, - Data: ðpbv2.LightClientUpdate{ - AttestedHeader: nil, - NextSyncCommittee: nil, - NextSyncCommitteeBranch: nil, - FinalizedHeader: nil, - FinalityBranch: nil, - SyncAggregate: nil, - SignatureSlot: 8, - }, - }, - { - Version: 1, - Data: ðpbv2.LightClientUpdate{ - AttestedHeader: nil, - NextSyncCommittee: nil, - NextSyncCommitteeBranch: nil, - FinalizedHeader: nil, - FinalityBranch: nil, - SyncAggregate: nil, - SignatureSlot: 11, - }, - }, - { - Version: 1, - Data: ðpbv2.LightClientUpdate{ - AttestedHeader: nil, - NextSyncCommittee: nil, - NextSyncCommitteeBranch: nil, - FinalizedHeader: nil, - FinalityBranch: nil, - SyncAggregate: nil, - SignatureSlot: 12, - }, - }, - } - - for _, update := range updates { - err := db.SaveLightClientUpdate(ctx, uint64(update.Data.SignatureSlot), update) - require.NoError(t, err) - } - - // Retrieve the updates - retrievedUpdates, err := db.LightClientUpdates(ctx, 7, 12) - require.NoError(t, err) - require.Equal(t, 4, len(retrievedUpdates)) - for _, update := range updates { - require.Equal(t, update.Data.SignatureSlot, retrievedUpdates[uint64(update.Data.SignatureSlot)].Data.SignatureSlot, "retrieved update does not match saved update") - } - - // Retrieve the updates from the middle - retrievedUpdates, err = db.LightClientUpdates(ctx, 8, 12) - require.NoError(t, err) - require.Equal(t, 3, len(retrievedUpdates)) - require.Equal(t, updates[1].Data.SignatureSlot, retrievedUpdates[8].Data.SignatureSlot, "retrieved update does not match saved update") - require.Equal(t, updates[2].Data.SignatureSlot, retrievedUpdates[11].Data.SignatureSlot, "retrieved update does not match saved update") - require.Equal(t, updates[3].Data.SignatureSlot, retrievedUpdates[12].Data.SignatureSlot, "retrieved update does not match saved update") - - // Retrieve the updates from after the missing period - retrievedUpdates, err = db.LightClientUpdates(ctx, 11, 12) - require.NoError(t, err) - require.Equal(t, 2, len(retrievedUpdates)) - require.Equal(t, updates[2].Data.SignatureSlot, retrievedUpdates[11].Data.SignatureSlot, "retrieved update does not match saved update") - require.Equal(t, updates[3].Data.SignatureSlot, retrievedUpdates[12].Data.SignatureSlot, "retrieved update does not match saved update") - - //retrieve the updates from before the missing period to after the missing period - retrievedUpdates, err = db.LightClientUpdates(ctx, 3, 15) + retrievedUpdate, err := db.LightClientUpdate(ctx, period) require.NoError(t, err) - require.Equal(t, 4, len(retrievedUpdates)) - require.Equal(t, updates[0].Data.SignatureSlot, retrievedUpdates[7].Data.SignatureSlot, "retrieved update does not match saved update") - require.Equal(t, updates[1].Data.SignatureSlot, retrievedUpdates[8].Data.SignatureSlot, "retrieved update does not match saved update") - require.Equal(t, updates[2].Data.SignatureSlot, retrievedUpdates[11].Data.SignatureSlot, "retrieved update does not match saved update") - require.Equal(t, updates[3].Data.SignatureSlot, retrievedUpdates[12].Data.SignatureSlot, "retrieved update does not match saved update") + require.DeepEqual(t, update, retrievedUpdate, "retrieved update does not match saved update") } -func TestStore_LightClientUpdate_EmptyDB(t *testing.T) { - db := setupDB(t) - ctx := context.Background() - - // Retrieve the updates - retrievedUpdates, err := db.LightClientUpdates(ctx, 1, 3) - require.IsNil(t, err) - require.Equal(t, 0, len(retrievedUpdates)) -} - -func TestStore_LightClientUpdate_MissingPeriodsAtTheEnd_SimpleData(t *testing.T) { - db := setupDB(t) - ctx := context.Background() - - for i := 1; i < 4; i++ { - update := ðpbv2.LightClientUpdateWithVersion{ - Version: 1, - Data: ðpbv2.LightClientUpdate{ - AttestedHeader: nil, - NextSyncCommittee: nil, - NextSyncCommitteeBranch: nil, - FinalizedHeader: nil, - FinalityBranch: nil, - SyncAggregate: nil, - SignatureSlot: primitives.Slot(uint64(i)), - }, +// +//func TestStore_LightClientUpdate_CanSaveRetrieveCapella(t *testing.T) { +// db := setupDB(t) +// ctx := context.Background() +// update := ðpbv2.LightClientUpdate{ +// AttestedHeader: ðpbv2.LightClientHeaderContainer{ +// Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ +// HeaderCapella: ðpbv2.LightClientHeaderCapella{ +// Beacon: ðpbv1.BeaconBlockHeader{ +// Slot: 1, +// ProposerIndex: 1, +// ParentRoot: []byte{1, 1, 1}, +// StateRoot: []byte{1, 1, 1}, +// BodyRoot: []byte{1, 1, 1}, +// }, +// Execution: &enginev1.ExecutionPayloadHeaderCapella{ +// FeeRecipient: []byte{1, 2, 3}, +// }, +// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, +// }, +// }, +// }, +// NextSyncCommittee: ðpbv2.SyncCommittee{ +// Pubkeys: nil, +// AggregatePubkey: nil, +// }, +// NextSyncCommitteeBranch: nil, +// FinalizedHeader: ðpbv2.LightClientHeaderContainer{ +// Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ +// HeaderCapella: ðpbv2.LightClientHeaderCapella{ +// Beacon: ðpbv1.BeaconBlockHeader{ +// Slot: 1, +// ProposerIndex: 1, +// ParentRoot: []byte{1, 1, 1}, +// StateRoot: []byte{1, 1, 1}, +// BodyRoot: []byte{1, 1, 1}, +// }, +// Execution: nil, +// ExecutionBranch: nil, +// }, +// }, +// }, +// FinalityBranch: nil, +// SyncAggregate: nil, +// SignatureSlot: 7, +// } +// period := uint64(1) +// err := db.SaveLightClientUpdate(ctx, period, ðpbv2.LightClientUpdateWithVersion{ +// Version: version.Capella, +// Data: update, +// }) +// require.NoError(t, err) +// +// retrievedUpdate, err := db.LightClientUpdate(ctx, period) +// require.NoError(t, err) +// require.DeepEqual(t, update, retrievedUpdate.Data, "retrieved update does not match saved update") +//} +// +//func TestStore_LightClientUpdate_CanSaveRetrieveDeneb(t *testing.T) { +// db := setupDB(t) +// ctx := context.Background() +// update := ðpbv2.LightClientUpdate{ +// AttestedHeader: ðpbv2.LightClientHeaderContainer{ +// Header: ðpbv2.LightClientHeaderContainer_HeaderDeneb{ +// HeaderDeneb: ðpbv2.LightClientHeaderDeneb{ +// Beacon: ðpbv1.BeaconBlockHeader{ +// Slot: 1, +// ProposerIndex: 1, +// ParentRoot: []byte{1, 1, 1}, +// StateRoot: []byte{1, 1, 1}, +// BodyRoot: []byte{1, 1, 1}, +// }, +// Execution: &enginev1.ExecutionPayloadHeaderDeneb{ +// FeeRecipient: []byte{1, 2, 3}, +// }, +// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, +// }, +// }, +// }, +// NextSyncCommittee: ðpbv2.SyncCommittee{ +// Pubkeys: nil, +// AggregatePubkey: nil, +// }, +// NextSyncCommitteeBranch: nil, +// FinalizedHeader: ðpbv2.LightClientHeaderContainer{ +// Header: ðpbv2.LightClientHeaderContainer_HeaderDeneb{ +// HeaderDeneb: ðpbv2.LightClientHeaderDeneb{ +// Beacon: ðpbv1.BeaconBlockHeader{ +// Slot: 1, +// ProposerIndex: 1, +// ParentRoot: []byte{1, 1, 1}, +// StateRoot: []byte{1, 1, 1}, +// BodyRoot: []byte{1, 1, 1}, +// }, +// Execution: nil, +// ExecutionBranch: nil, +// }, +// }, +// }, +// FinalityBranch: nil, +// SyncAggregate: nil, +// SignatureSlot: 7, +// } +// period := uint64(1) +// err := db.SaveLightClientUpdate(ctx, period, ðpbv2.LightClientUpdateWithVersion{ +// Version: version.Deneb, +// Data: update, +// }) +// require.NoError(t, err) +// +// retrievedUpdate, err := db.LightClientUpdate(ctx, period) +// require.NoError(t, err) +// require.DeepEqual(t, update, retrievedUpdate.Data, "retrieved update does not match saved update") +//} +// +//func TestStore_LightClientUpdates_canRetrieveRange(t *testing.T) { +// db := setupDB(t) +// ctx := context.Background() +// updates := []*ethpbv2.LightClientUpdateWithVersion{ +// { +// Version: 1, +// Data: ðpbv2.LightClientUpdate{ +// AttestedHeader: nil, +// NextSyncCommittee: nil, +// NextSyncCommitteeBranch: nil, +// FinalizedHeader: nil, +// FinalityBranch: nil, +// SyncAggregate: nil, +// SignatureSlot: 7, +// }, +// }, +// { +// Version: 1, +// Data: ðpbv2.LightClientUpdate{ +// AttestedHeader: nil, +// NextSyncCommittee: nil, +// NextSyncCommitteeBranch: nil, +// FinalizedHeader: nil, +// FinalityBranch: nil, +// SyncAggregate: nil, +// SignatureSlot: 8, +// }, +// }, +// { +// Version: 1, +// Data: ðpbv2.LightClientUpdate{ +// AttestedHeader: nil, +// NextSyncCommittee: nil, +// NextSyncCommitteeBranch: nil, +// FinalizedHeader: nil, +// FinalityBranch: nil, +// SyncAggregate: nil, +// SignatureSlot: 9, +// }, +// }, +// } +// +// for i, update := range updates { +// err := db.SaveLightClientUpdate(ctx, uint64(i+1), update) +// require.NoError(t, err) +// } +// +// // Retrieve the updates +// retrievedUpdatesMap, err := db.LightClientUpdates(ctx, 1, 3) +// require.NoError(t, err) +// require.Equal(t, len(updates), len(retrievedUpdatesMap), "retrieved updates do not match saved updates") +// for i, update := range updates { +// require.Equal(t, update.Data.SignatureSlot, retrievedUpdatesMap[uint64(i+1)].Data.SignatureSlot, "retrieved update does not match saved update") +// } +// +//} +// +//func TestStore_LightClientUpdate_EndPeriodSmallerThanStartPeriod(t *testing.T) { +// db := setupDB(t) +// ctx := context.Background() +// updates := []*ethpbv2.LightClientUpdateWithVersion{ +// { +// Version: 1, +// Data: ðpbv2.LightClientUpdate{ +// AttestedHeader: nil, +// NextSyncCommittee: nil, +// NextSyncCommitteeBranch: nil, +// FinalizedHeader: nil, +// FinalityBranch: nil, +// SyncAggregate: nil, +// SignatureSlot: 7, +// }, +// }, +// { +// Version: 1, +// Data: ðpbv2.LightClientUpdate{ +// AttestedHeader: nil, +// NextSyncCommittee: nil, +// NextSyncCommitteeBranch: nil, +// FinalizedHeader: nil, +// FinalityBranch: nil, +// SyncAggregate: nil, +// SignatureSlot: 8, +// }, +// }, +// { +// Version: 1, +// Data: ðpbv2.LightClientUpdate{ +// AttestedHeader: nil, +// NextSyncCommittee: nil, +// NextSyncCommitteeBranch: nil, +// FinalizedHeader: nil, +// FinalityBranch: nil, +// SyncAggregate: nil, +// SignatureSlot: 9, +// }, +// }, +// } +// +// for i, update := range updates { +// err := db.SaveLightClientUpdate(ctx, uint64(i+1), update) +// require.NoError(t, err) +// } +// +// // Retrieve the updates +// retrievedUpdates, err := db.LightClientUpdates(ctx, 3, 1) +// require.NotNil(t, err) +// require.Equal(t, err.Error(), "start period 3 is greater than end period 1") +// require.IsNil(t, retrievedUpdates) +// +//} +// +//func TestStore_LightClientUpdate_EndPeriodEqualToStartPeriod(t *testing.T) { +// db := setupDB(t) +// ctx := context.Background() +// updates := []*ethpbv2.LightClientUpdateWithVersion{ +// { +// Version: 1, +// Data: ðpbv2.LightClientUpdate{ +// AttestedHeader: nil, +// NextSyncCommittee: nil, +// NextSyncCommitteeBranch: nil, +// FinalizedHeader: nil, +// FinalityBranch: nil, +// SyncAggregate: nil, +// SignatureSlot: 7, +// }, +// }, +// { +// Version: 1, +// Data: ðpbv2.LightClientUpdate{ +// AttestedHeader: nil, +// NextSyncCommittee: nil, +// NextSyncCommitteeBranch: nil, +// FinalizedHeader: nil, +// FinalityBranch: nil, +// SyncAggregate: nil, +// SignatureSlot: 8, +// }, +// }, +// { +// Version: 1, +// Data: ðpbv2.LightClientUpdate{ +// AttestedHeader: nil, +// NextSyncCommittee: nil, +// NextSyncCommitteeBranch: nil, +// FinalizedHeader: nil, +// FinalityBranch: nil, +// SyncAggregate: nil, +// SignatureSlot: 9, +// }, +// }, +// } +// +// for i, update := range updates { +// err := db.SaveLightClientUpdate(ctx, uint64(i+1), update) +// require.NoError(t, err) +// } +// +// // Retrieve the updates +// retrievedUpdates, err := db.LightClientUpdates(ctx, 2, 2) +// require.NoError(t, err) +// require.Equal(t, 1, len(retrievedUpdates)) +// require.Equal(t, updates[1].Data.SignatureSlot, retrievedUpdates[2].Data.SignatureSlot, "retrieved update does not match saved update") +//} +// +//func TestStore_LightClientUpdate_StartPeriodBeforeFirstUpdate(t *testing.T) { +// db := setupDB(t) +// ctx := context.Background() +// updates := []*ethpbv2.LightClientUpdateWithVersion{ +// { +// Version: 1, +// Data: ðpbv2.LightClientUpdate{ +// AttestedHeader: nil, +// NextSyncCommittee: nil, +// NextSyncCommitteeBranch: nil, +// FinalizedHeader: nil, +// FinalityBranch: nil, +// SyncAggregate: nil, +// SignatureSlot: 7, +// }, +// }, +// { +// Version: 1, +// Data: ðpbv2.LightClientUpdate{ +// AttestedHeader: nil, +// NextSyncCommittee: nil, +// NextSyncCommitteeBranch: nil, +// FinalizedHeader: nil, +// FinalityBranch: nil, +// SyncAggregate: nil, +// SignatureSlot: 8, +// }, +// }, +// { +// Version: 1, +// Data: ðpbv2.LightClientUpdate{ +// AttestedHeader: nil, +// NextSyncCommittee: nil, +// NextSyncCommitteeBranch: nil, +// FinalizedHeader: nil, +// FinalityBranch: nil, +// SyncAggregate: nil, +// SignatureSlot: 9, +// }, +// }, +// } +// +// for i, update := range updates { +// err := db.SaveLightClientUpdate(ctx, uint64(i+2), update) +// require.NoError(t, err) +// } +// +// // Retrieve the updates +// retrievedUpdates, err := db.LightClientUpdates(ctx, 0, 4) +// require.NoError(t, err) +// require.Equal(t, 3, len(retrievedUpdates)) +// for i, update := range updates { +// require.Equal(t, update.Data.SignatureSlot, retrievedUpdates[uint64(i+2)].Data.SignatureSlot, "retrieved update does not match saved update") +// } +//} +// +//func TestStore_LightClientUpdate_EndPeriodAfterLastUpdate(t *testing.T) { +// db := setupDB(t) +// ctx := context.Background() +// updates := []*ethpbv2.LightClientUpdateWithVersion{ +// { +// Version: 1, +// Data: ðpbv2.LightClientUpdate{ +// AttestedHeader: nil, +// NextSyncCommittee: nil, +// NextSyncCommitteeBranch: nil, +// FinalizedHeader: nil, +// FinalityBranch: nil, +// SyncAggregate: nil, +// SignatureSlot: 7, +// }, +// }, +// { +// Version: 1, +// Data: ðpbv2.LightClientUpdate{ +// AttestedHeader: nil, +// NextSyncCommittee: nil, +// NextSyncCommitteeBranch: nil, +// FinalizedHeader: nil, +// FinalityBranch: nil, +// SyncAggregate: nil, +// SignatureSlot: 8, +// }, +// }, +// { +// Version: 1, +// Data: ðpbv2.LightClientUpdate{ +// AttestedHeader: nil, +// NextSyncCommittee: nil, +// NextSyncCommitteeBranch: nil, +// FinalizedHeader: nil, +// FinalityBranch: nil, +// SyncAggregate: nil, +// SignatureSlot: 9, +// }, +// }, +// } +// +// for i, update := range updates { +// err := db.SaveLightClientUpdate(ctx, uint64(i+1), update) +// require.NoError(t, err) +// } +// +// // Retrieve the updates +// retrievedUpdates, err := db.LightClientUpdates(ctx, 1, 6) +// require.NoError(t, err) +// require.Equal(t, 3, len(retrievedUpdates)) +// for i, update := range updates { +// require.Equal(t, update.Data.SignatureSlot, retrievedUpdates[uint64(i+1)].Data.SignatureSlot, "retrieved update does not match saved update") +// } +//} +// +//func TestStore_LightClientUpdate_PartialUpdates(t *testing.T) { +// db := setupDB(t) +// ctx := context.Background() +// updates := []*ethpbv2.LightClientUpdateWithVersion{ +// { +// Version: 1, +// Data: ðpbv2.LightClientUpdate{ +// AttestedHeader: nil, +// NextSyncCommittee: nil, +// NextSyncCommitteeBranch: nil, +// FinalizedHeader: nil, +// FinalityBranch: nil, +// SyncAggregate: nil, +// SignatureSlot: 7, +// }, +// }, +// { +// Version: 1, +// Data: ðpbv2.LightClientUpdate{ +// AttestedHeader: nil, +// NextSyncCommittee: nil, +// NextSyncCommitteeBranch: nil, +// FinalizedHeader: nil, +// FinalityBranch: nil, +// SyncAggregate: nil, +// SignatureSlot: 8, +// }, +// }, +// { +// Version: 1, +// Data: ðpbv2.LightClientUpdate{ +// AttestedHeader: nil, +// NextSyncCommittee: nil, +// NextSyncCommitteeBranch: nil, +// FinalizedHeader: nil, +// FinalityBranch: nil, +// SyncAggregate: nil, +// SignatureSlot: 9, +// }, +// }, +// } +// +// for i, update := range updates { +// err := db.SaveLightClientUpdate(ctx, uint64(i+1), update) +// require.NoError(t, err) +// } +// +// // Retrieve the updates +// retrievedUpdates, err := db.LightClientUpdates(ctx, 1, 2) +// require.NoError(t, err) +// require.Equal(t, 2, len(retrievedUpdates)) +// for i, update := range updates[:2] { +// require.Equal(t, update.Data.SignatureSlot, retrievedUpdates[uint64(i+1)].Data.SignatureSlot, "retrieved update does not match saved update") +// } +//} +// +//func TestStore_LightClientUpdate_MissingPeriods_SimpleData(t *testing.T) { +// db := setupDB(t) +// ctx := context.Background() +// updates := []*ethpbv2.LightClientUpdateWithVersion{ +// { +// Version: 1, +// Data: ðpbv2.LightClientUpdate{ +// AttestedHeader: nil, +// NextSyncCommittee: nil, +// NextSyncCommitteeBranch: nil, +// FinalizedHeader: nil, +// FinalityBranch: nil, +// SyncAggregate: nil, +// SignatureSlot: 7, +// }, +// }, +// { +// Version: 1, +// Data: ðpbv2.LightClientUpdate{ +// AttestedHeader: nil, +// NextSyncCommittee: nil, +// NextSyncCommitteeBranch: nil, +// FinalizedHeader: nil, +// FinalityBranch: nil, +// SyncAggregate: nil, +// SignatureSlot: 8, +// }, +// }, +// { +// Version: 1, +// Data: ðpbv2.LightClientUpdate{ +// AttestedHeader: nil, +// NextSyncCommittee: nil, +// NextSyncCommitteeBranch: nil, +// FinalizedHeader: nil, +// FinalityBranch: nil, +// SyncAggregate: nil, +// SignatureSlot: 11, +// }, +// }, +// { +// Version: 1, +// Data: ðpbv2.LightClientUpdate{ +// AttestedHeader: nil, +// NextSyncCommittee: nil, +// NextSyncCommitteeBranch: nil, +// FinalizedHeader: nil, +// FinalityBranch: nil, +// SyncAggregate: nil, +// SignatureSlot: 12, +// }, +// }, +// } +// +// for _, update := range updates { +// err := db.SaveLightClientUpdate(ctx, uint64(update.Data.SignatureSlot), update) +// require.NoError(t, err) +// } +// +// // Retrieve the updates +// retrievedUpdates, err := db.LightClientUpdates(ctx, 7, 12) +// require.NoError(t, err) +// require.Equal(t, 4, len(retrievedUpdates)) +// for _, update := range updates { +// require.Equal(t, update.Data.SignatureSlot, retrievedUpdates[uint64(update.Data.SignatureSlot)].Data.SignatureSlot, "retrieved update does not match saved update") +// } +// +// // Retrieve the updates from the middle +// retrievedUpdates, err = db.LightClientUpdates(ctx, 8, 12) +// require.NoError(t, err) +// require.Equal(t, 3, len(retrievedUpdates)) +// require.Equal(t, updates[1].Data.SignatureSlot, retrievedUpdates[8].Data.SignatureSlot, "retrieved update does not match saved update") +// require.Equal(t, updates[2].Data.SignatureSlot, retrievedUpdates[11].Data.SignatureSlot, "retrieved update does not match saved update") +// require.Equal(t, updates[3].Data.SignatureSlot, retrievedUpdates[12].Data.SignatureSlot, "retrieved update does not match saved update") +// +// // Retrieve the updates from after the missing period +// retrievedUpdates, err = db.LightClientUpdates(ctx, 11, 12) +// require.NoError(t, err) +// require.Equal(t, 2, len(retrievedUpdates)) +// require.Equal(t, updates[2].Data.SignatureSlot, retrievedUpdates[11].Data.SignatureSlot, "retrieved update does not match saved update") +// require.Equal(t, updates[3].Data.SignatureSlot, retrievedUpdates[12].Data.SignatureSlot, "retrieved update does not match saved update") +// +// //retrieve the updates from before the missing period to after the missing period +// retrievedUpdates, err = db.LightClientUpdates(ctx, 3, 15) +// require.NoError(t, err) +// require.Equal(t, 4, len(retrievedUpdates)) +// require.Equal(t, updates[0].Data.SignatureSlot, retrievedUpdates[7].Data.SignatureSlot, "retrieved update does not match saved update") +// require.Equal(t, updates[1].Data.SignatureSlot, retrievedUpdates[8].Data.SignatureSlot, "retrieved update does not match saved update") +// require.Equal(t, updates[2].Data.SignatureSlot, retrievedUpdates[11].Data.SignatureSlot, "retrieved update does not match saved update") +// require.Equal(t, updates[3].Data.SignatureSlot, retrievedUpdates[12].Data.SignatureSlot, "retrieved update does not match saved update") +//} +// +//func TestStore_LightClientUpdate_EmptyDB(t *testing.T) { +// db := setupDB(t) +// ctx := context.Background() +// +// // Retrieve the updates +// retrievedUpdates, err := db.LightClientUpdates(ctx, 1, 3) +// require.IsNil(t, err) +// require.Equal(t, 0, len(retrievedUpdates)) +//} +// +//func TestStore_LightClientUpdate_MissingPeriodsAtTheEnd_SimpleData(t *testing.T) { +// db := setupDB(t) +// ctx := context.Background() +// +// for i := 1; i < 4; i++ { +// update := ðpbv2.LightClientUpdateWithVersion{ +// Version: 1, +// Data: ðpbv2.LightClientUpdate{ +// AttestedHeader: nil, +// NextSyncCommittee: nil, +// NextSyncCommitteeBranch: nil, +// FinalizedHeader: nil, +// FinalityBranch: nil, +// SyncAggregate: nil, +// SignatureSlot: primitives.Slot(uint64(i)), +// }, +// } +// err := db.SaveLightClientUpdate(ctx, uint64(i), update) +// require.NoError(t, err) +// } +// for i := 7; i < 10; i++ { +// update := ðpbv2.LightClientUpdateWithVersion{ +// Version: 1, +// Data: ðpbv2.LightClientUpdate{ +// AttestedHeader: nil, +// NextSyncCommittee: nil, +// NextSyncCommitteeBranch: nil, +// FinalizedHeader: nil, +// FinalityBranch: nil, +// SyncAggregate: nil, +// SignatureSlot: primitives.Slot(uint64(i)), +// }, +// } +// err := db.SaveLightClientUpdate(ctx, uint64(i), update) +// require.NoError(t, err) +// } +// +// // Retrieve the updates from 1 to 5 +// retrievedUpdates, err := db.LightClientUpdates(ctx, 1, 5) +// require.NoError(t, err) +// require.Equal(t, 3, len(retrievedUpdates)) +// require.Equal(t, primitives.Slot(1), retrievedUpdates[1].Data.SignatureSlot, "retrieved update does not match saved update") +// require.Equal(t, primitives.Slot(2), retrievedUpdates[2].Data.SignatureSlot, "retrieved update does not match saved update") +// require.Equal(t, primitives.Slot(3), retrievedUpdates[3].Data.SignatureSlot, "retrieved update does not match saved update") +// +//} +// +//func setupLightClientTestDB(t *testing.T) (*Store, context.Context) { +// db := setupDB(t) +// ctx := context.Background() +// +// for i := 10; i < 101; i++ { // 10 to 100 +// update := ðpbv2.LightClientUpdateWithVersion{ +// Version: 1, +// Data: ðpbv2.LightClientUpdate{ +// AttestedHeader: nil, +// NextSyncCommittee: nil, +// NextSyncCommitteeBranch: nil, +// FinalizedHeader: nil, +// FinalityBranch: nil, +// SyncAggregate: nil, +// SignatureSlot: primitives.Slot(uint64(i)), +// }, +// } +// err := db.SaveLightClientUpdate(ctx, uint64(i), update) +// require.NoError(t, err) +// } +// +// for i := 110; i < 201; i++ { // 110 to 200 +// update := ðpbv2.LightClientUpdateWithVersion{ +// Version: 1, +// Data: ðpbv2.LightClientUpdate{ +// AttestedHeader: nil, +// NextSyncCommittee: nil, +// NextSyncCommitteeBranch: nil, +// FinalizedHeader: nil, +// FinalityBranch: nil, +// SyncAggregate: nil, +// SignatureSlot: primitives.Slot(uint64(i)), +// }, +// } +// err := db.SaveLightClientUpdate(ctx, uint64(i), update) +// require.NoError(t, err) +// } +// +// return db, ctx +//} +// +//func TestStore_LightClientUpdate_MissingPeriodsInTheMiddleDistributed(t *testing.T) { +// db, ctx := setupLightClientTestDB(t) +// +// // Retrieve the updates - should fail because of missing periods in the middle +// retrievedUpdates, err := db.LightClientUpdates(ctx, 1, 300) +// require.NoError(t, err) +// require.Equal(t, 91*2, len(retrievedUpdates)) +// for i := 10; i < 101; i++ { +// require.Equal(t, primitives.Slot(uint64(i)), retrievedUpdates[uint64(i)].Data.SignatureSlot, "retrieved update does not match saved update") +// } +// for i := 110; i < 201; i++ { +// require.Equal(t, primitives.Slot(uint64(i)), retrievedUpdates[uint64(i)].Data.SignatureSlot, "retrieved update does not match saved update") +// } +// +//} +// +//func TestStore_LightClientUpdate_RetrieveValidRangeFromStart(t *testing.T) { +// db, ctx := setupLightClientTestDB(t) +// +// // retrieve 1 to 100 - should work because all periods are present after the firstPeriodInDB > startPeriod +// retrievedUpdates, err := db.LightClientUpdates(ctx, 1, 100) +// require.NoError(t, err) +// require.Equal(t, 91, len(retrievedUpdates)) +// for i := 10; i < 101; i++ { +// require.Equal(t, primitives.Slot(uint64(i)), retrievedUpdates[uint64(i)].Data.SignatureSlot, "retrieved update does not match saved update") +// } +//} +// +//func TestStore_LightClientUpdate_RetrieveValidRangeInTheMiddle(t *testing.T) { +// db, ctx := setupLightClientTestDB(t) +// +// // retrieve 110 to 200 - should work because all periods are present +// retrievedUpdates, err := db.LightClientUpdates(ctx, 110, 200) +// require.NoError(t, err) +// require.Equal(t, 91, len(retrievedUpdates)) +// for i := 110; i < 201; i++ { +// require.Equal(t, primitives.Slot(uint64(i)), retrievedUpdates[uint64(i)].Data.SignatureSlot, "retrieved update does not match saved update") +// } +//} +// +//func TestStore_LightClientUpdate_MissingPeriodInTheMiddleConcentrated(t *testing.T) { +// db, ctx := setupLightClientTestDB(t) +// +// // retrieve 100 to 200 +// retrievedUpdates, err := db.LightClientUpdates(ctx, 100, 200) +// require.NoError(t, err) +// require.Equal(t, 92, len(retrievedUpdates)) +// require.Equal(t, primitives.Slot(100), retrievedUpdates[100].Data.SignatureSlot, "retrieved update does not match saved update") +// for i := 110; i < 201; i++ { +// require.Equal(t, primitives.Slot(uint64(i)), retrievedUpdates[uint64(i)].Data.SignatureSlot, "retrieved update does not match saved update") +// } +//} +// +//func TestStore_LightClientUpdate_MissingPeriodsAtTheEnd(t *testing.T) { +// db, ctx := setupLightClientTestDB(t) +// +// // retrieve 10 to 109 +// retrievedUpdates, err := db.LightClientUpdates(ctx, 10, 109) +// require.NoError(t, err) +// require.Equal(t, 91, len(retrievedUpdates)) +// for i := 10; i < 101; i++ { +// require.Equal(t, primitives.Slot(uint64(i)), retrievedUpdates[uint64(i)].Data.SignatureSlot, "retrieved update does not match saved update") +// } +//} +// +//func TestStore_LightClientUpdate_MissingPeriodsAtTheBeginning(t *testing.T) { +// db, ctx := setupLightClientTestDB(t) +// +// // retrieve 105 to 200 +// retrievedUpdates, err := db.LightClientUpdates(ctx, 105, 200) +// require.NoError(t, err) +// require.Equal(t, 91, len(retrievedUpdates)) +// for i := 110; i < 201; i++ { +// require.Equal(t, primitives.Slot(uint64(i)), retrievedUpdates[uint64(i)].Data.SignatureSlot, "retrieved update does not match saved update") +// } +//} +// +//func TestStore_LightClientUpdate_StartPeriodGreaterThanLastPeriod(t *testing.T) { +// db, ctx := setupLightClientTestDB(t) +// +// // retrieve 300 to 400 +// retrievedUpdates, err := db.LightClientUpdates(ctx, 300, 400) +// require.NoError(t, err) +// require.Equal(t, 0, len(retrievedUpdates)) +// +//} + +func createDefaultLightClientUpdate(currentSlot primitives.Slot) (interfaces.LightClientUpdate, error) { + currentEpoch := slots.ToEpoch(currentSlot) + + syncCommitteeSize := params.BeaconConfig().SyncCommitteeSize + pubKeys := make([][]byte, syncCommitteeSize) + for i := uint64(0); i < syncCommitteeSize; i++ { + pubKeys[i] = make([]byte, fieldparams.BLSPubkeyLength) + } + nextSyncCommittee := &pb.SyncCommittee{ + Pubkeys: pubKeys, + AggregatePubkey: make([]byte, fieldparams.BLSPubkeyLength), + } + + var nextSyncCommitteeBranch [][]byte + if currentEpoch >= params.BeaconConfig().ElectraForkEpoch { + nextSyncCommitteeBranch = make([][]byte, fieldparams.SyncCommitteeBranchDepthElectra) + } else { + nextSyncCommitteeBranch = make([][]byte, fieldparams.SyncCommitteeBranchDepth) + } + for i := 0; i < len(nextSyncCommitteeBranch); i++ { + nextSyncCommitteeBranch[i] = make([]byte, fieldparams.RootLength) + } + + executionBranch := make([][]byte, fieldparams.ExecutionBranchDepth) + for i := 0; i < fieldparams.ExecutionBranchDepth; i++ { + executionBranch[i] = make([]byte, 32) + } + finalityBranch := make([][]byte, fieldparams.FinalityBranchDepth) + for i := 0; i < fieldparams.FinalityBranchDepth; i++ { + finalityBranch[i] = make([]byte, 32) + } + + var m proto.Message + if currentEpoch < params.BeaconConfig().CapellaForkEpoch { + m = &pb.LightClientUpdateAltair{ + AttestedHeader: &pb.LightClientHeaderAltair{}, + NextSyncCommittee: nextSyncCommittee, + NextSyncCommitteeBranch: nextSyncCommitteeBranch, + FinalityBranch: finalityBranch, } - err := db.SaveLightClientUpdate(ctx, uint64(i), update) - require.NoError(t, err) - } - for i := 7; i < 10; i++ { - update := ðpbv2.LightClientUpdateWithVersion{ - Version: 1, - Data: ðpbv2.LightClientUpdate{ - AttestedHeader: nil, - NextSyncCommittee: nil, - NextSyncCommitteeBranch: nil, - FinalizedHeader: nil, - FinalityBranch: nil, - SyncAggregate: nil, - SignatureSlot: primitives.Slot(uint64(i)), - }, + } else if currentEpoch < params.BeaconConfig().DenebForkEpoch { + m = &pb.LightClientUpdateCapella{ + AttestedHeader: &pb.LightClientHeaderCapella{ + Beacon: &pb.BeaconBlockHeader{}, + Execution: &enginev1.ExecutionPayloadHeaderCapella{}, + ExecutionBranch: executionBranch, + }, + NextSyncCommittee: nextSyncCommittee, + NextSyncCommitteeBranch: nextSyncCommitteeBranch, + FinalityBranch: finalityBranch, } - err := db.SaveLightClientUpdate(ctx, uint64(i), update) - require.NoError(t, err) - } - - // Retrieve the updates from 1 to 5 - retrievedUpdates, err := db.LightClientUpdates(ctx, 1, 5) - require.NoError(t, err) - require.Equal(t, 3, len(retrievedUpdates)) - require.Equal(t, primitives.Slot(1), retrievedUpdates[1].Data.SignatureSlot, "retrieved update does not match saved update") - require.Equal(t, primitives.Slot(2), retrievedUpdates[2].Data.SignatureSlot, "retrieved update does not match saved update") - require.Equal(t, primitives.Slot(3), retrievedUpdates[3].Data.SignatureSlot, "retrieved update does not match saved update") - -} - -func setupLightClientTestDB(t *testing.T) (*Store, context.Context) { - db := setupDB(t) - ctx := context.Background() - - for i := 10; i < 101; i++ { // 10 to 100 - update := ðpbv2.LightClientUpdateWithVersion{ - Version: 1, - Data: ðpbv2.LightClientUpdate{ - AttestedHeader: nil, - NextSyncCommittee: nil, - NextSyncCommitteeBranch: nil, - FinalizedHeader: nil, - FinalityBranch: nil, - SyncAggregate: nil, - SignatureSlot: primitives.Slot(uint64(i)), - }, + } else if currentEpoch < params.BeaconConfig().ElectraForkEpoch { + m = &pb.LightClientUpdateDeneb{ + AttestedHeader: &pb.LightClientHeaderDeneb{ + Beacon: &pb.BeaconBlockHeader{}, + Execution: &enginev1.ExecutionPayloadHeaderDeneb{}, + ExecutionBranch: executionBranch, + }, + NextSyncCommittee: nextSyncCommittee, + NextSyncCommitteeBranch: nextSyncCommitteeBranch, + FinalityBranch: finalityBranch, } - err := db.SaveLightClientUpdate(ctx, uint64(i), update) - require.NoError(t, err) - } - - for i := 110; i < 201; i++ { // 110 to 200 - update := ðpbv2.LightClientUpdateWithVersion{ - Version: 1, - Data: ðpbv2.LightClientUpdate{ - AttestedHeader: nil, - NextSyncCommittee: nil, - NextSyncCommitteeBranch: nil, - FinalizedHeader: nil, - FinalityBranch: nil, - SyncAggregate: nil, - SignatureSlot: primitives.Slot(uint64(i)), - }, + } else { + m = &pb.LightClientUpdateElectra{ + AttestedHeader: &pb.LightClientHeaderDeneb{ + Beacon: &pb.BeaconBlockHeader{}, + Execution: &enginev1.ExecutionPayloadHeaderDeneb{}, + ExecutionBranch: executionBranch, + }, + NextSyncCommittee: nextSyncCommittee, + NextSyncCommitteeBranch: nextSyncCommitteeBranch, + FinalityBranch: finalityBranch, } - err := db.SaveLightClientUpdate(ctx, uint64(i), update) - require.NoError(t, err) } - return db, ctx -} - -func TestStore_LightClientUpdate_MissingPeriodsInTheMiddleDistributed(t *testing.T) { - db, ctx := setupLightClientTestDB(t) - - // Retrieve the updates - should fail because of missing periods in the middle - retrievedUpdates, err := db.LightClientUpdates(ctx, 1, 300) - require.NoError(t, err) - require.Equal(t, 91*2, len(retrievedUpdates)) - for i := 10; i < 101; i++ { - require.Equal(t, primitives.Slot(uint64(i)), retrievedUpdates[uint64(i)].Data.SignatureSlot, "retrieved update does not match saved update") - } - for i := 110; i < 201; i++ { - require.Equal(t, primitives.Slot(uint64(i)), retrievedUpdates[uint64(i)].Data.SignatureSlot, "retrieved update does not match saved update") - } - -} - -func TestStore_LightClientUpdate_RetrieveValidRangeFromStart(t *testing.T) { - db, ctx := setupLightClientTestDB(t) - - // retrieve 1 to 100 - should work because all periods are present after the firstPeriodInDB > startPeriod - retrievedUpdates, err := db.LightClientUpdates(ctx, 1, 100) - require.NoError(t, err) - require.Equal(t, 91, len(retrievedUpdates)) - for i := 10; i < 101; i++ { - require.Equal(t, primitives.Slot(uint64(i)), retrievedUpdates[uint64(i)].Data.SignatureSlot, "retrieved update does not match saved update") - } -} - -func TestStore_LightClientUpdate_RetrieveValidRangeInTheMiddle(t *testing.T) { - db, ctx := setupLightClientTestDB(t) - - // retrieve 110 to 200 - should work because all periods are present - retrievedUpdates, err := db.LightClientUpdates(ctx, 110, 200) - require.NoError(t, err) - require.Equal(t, 91, len(retrievedUpdates)) - for i := 110; i < 201; i++ { - require.Equal(t, primitives.Slot(uint64(i)), retrievedUpdates[uint64(i)].Data.SignatureSlot, "retrieved update does not match saved update") - } -} - -func TestStore_LightClientUpdate_MissingPeriodInTheMiddleConcentrated(t *testing.T) { - db, ctx := setupLightClientTestDB(t) - - // retrieve 100 to 200 - retrievedUpdates, err := db.LightClientUpdates(ctx, 100, 200) - require.NoError(t, err) - require.Equal(t, 92, len(retrievedUpdates)) - require.Equal(t, primitives.Slot(100), retrievedUpdates[100].Data.SignatureSlot, "retrieved update does not match saved update") - for i := 110; i < 201; i++ { - require.Equal(t, primitives.Slot(uint64(i)), retrievedUpdates[uint64(i)].Data.SignatureSlot, "retrieved update does not match saved update") - } -} - -func TestStore_LightClientUpdate_MissingPeriodsAtTheEnd(t *testing.T) { - db, ctx := setupLightClientTestDB(t) - - // retrieve 10 to 109 - retrievedUpdates, err := db.LightClientUpdates(ctx, 10, 109) - require.NoError(t, err) - require.Equal(t, 91, len(retrievedUpdates)) - for i := 10; i < 101; i++ { - require.Equal(t, primitives.Slot(uint64(i)), retrievedUpdates[uint64(i)].Data.SignatureSlot, "retrieved update does not match saved update") - } -} - -func TestStore_LightClientUpdate_MissingPeriodsAtTheBeginning(t *testing.T) { - db, ctx := setupLightClientTestDB(t) - - // retrieve 105 to 200 - retrievedUpdates, err := db.LightClientUpdates(ctx, 105, 200) - require.NoError(t, err) - require.Equal(t, 91, len(retrievedUpdates)) - for i := 110; i < 201; i++ { - require.Equal(t, primitives.Slot(uint64(i)), retrievedUpdates[uint64(i)].Data.SignatureSlot, "retrieved update does not match saved update") - } -} - -func TestStore_LightClientUpdate_StartPeriodGreaterThanLastPeriod(t *testing.T) { - db, ctx := setupLightClientTestDB(t) - - // retrieve 300 to 400 - retrievedUpdates, err := db.LightClientUpdates(ctx, 300, 400) - require.NoError(t, err) - require.Equal(t, 0, len(retrievedUpdates)) - + return light_client.NewWrappedUpdate(m) } diff --git a/beacon-chain/rpc/eth/light-client/handlers_test.go b/beacon-chain/rpc/eth/light-client/handlers_test.go index 398676e206db..c4696be5dffc 100644 --- a/beacon-chain/rpc/eth/light-client/handlers_test.go +++ b/beacon-chain/rpc/eth/light-client/handlers_test.go @@ -1,116 +1,109 @@ package lightclient -// -//import ( -// "bytes" -// "context" -// "encoding/json" -// "fmt" -// "net/http" -// "net/http/httptest" -// "strconv" -// "testing" -// -// "github.com/ethereum/go-ethereum/common/hexutil" -// "github.com/prysmaticlabs/prysm/v5/api/server/structs" -// mock "github.com/prysmaticlabs/prysm/v5/beacon-chain/blockchain/testing" -// "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/helpers" -// "github.com/prysmaticlabs/prysm/v5/beacon-chain/db/kv" -// "github.com/prysmaticlabs/prysm/v5/beacon-chain/rpc/testutil" -// "github.com/prysmaticlabs/prysm/v5/beacon-chain/state" -// "github.com/prysmaticlabs/prysm/v5/config/params" -// "github.com/prysmaticlabs/prysm/v5/consensus-types/blocks" -// "github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces" -// "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" -// enginev1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1" -// ethpbv1 "github.com/prysmaticlabs/prysm/v5/proto/eth/v1" -// ethpbv2 "github.com/prysmaticlabs/prysm/v5/proto/eth/v2" -// ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" -// "github.com/prysmaticlabs/prysm/v5/runtime/version" -// "github.com/prysmaticlabs/prysm/v5/testing/require" -// "github.com/prysmaticlabs/prysm/v5/testing/util" -//) -// -//func TestLightClientHandler_GetLightClientBootstrap_Altair(t *testing.T) { -// l := util.NewTestLightClient(t).SetupTestAltair() -// -// slot := l.State.Slot() -// stateRoot, err := l.State.HashTreeRoot(l.Ctx) -// require.NoError(t, err) -// -// mockBlocker := &testutil.MockBlocker{BlockToReturn: l.Block} -// mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot} -// s := &Server{ -// Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ -// slot: l.State, -// }}, -// Blocker: mockBlocker, -// HeadFetcher: mockChainService, -// } -// request := httptest.NewRequest("GET", "http://foo.com/", nil) -// request.SetPathValue("block_root", hexutil.Encode(stateRoot[:])) -// writer := httptest.NewRecorder() -// writer.Body = &bytes.Buffer{} -// -// s.GetLightClientBootstrap(writer, request) -// require.Equal(t, http.StatusOK, writer.Code) -// var resp structs.LightClientBootstrapResponse -// err = json.Unmarshal(writer.Body.Bytes(), &resp) -// require.NoError(t, err) -// var respHeader structs.LightClientHeader -// err = json.Unmarshal(resp.Data.Header, &respHeader) -// require.NoError(t, err) -// require.Equal(t, "altair", resp.Version) -// -// blockHeader, err := l.Block.Header() -// require.NoError(t, err) -// require.Equal(t, hexutil.Encode(blockHeader.Header.BodyRoot), respHeader.Beacon.BodyRoot) -// require.Equal(t, strconv.FormatUint(uint64(blockHeader.Header.Slot), 10), respHeader.Beacon.Slot) -// -// require.NotNil(t, resp.Data.CurrentSyncCommittee) -// require.NotNil(t, resp.Data.CurrentSyncCommitteeBranch) -//} -// -//func TestLightClientHandler_GetLightClientBootstrap_Bellatrix(t *testing.T) { -// l := util.NewTestLightClient(t).SetupTestBellatrix() -// -// slot := l.State.Slot() -// stateRoot, err := l.State.HashTreeRoot(l.Ctx) -// require.NoError(t, err) -// -// mockBlocker := &testutil.MockBlocker{BlockToReturn: l.Block} -// mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot} -// s := &Server{ -// Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ -// slot: l.State, -// }}, -// Blocker: mockBlocker, -// HeadFetcher: mockChainService, -// } -// request := httptest.NewRequest("GET", "http://foo.com/", nil) -// request.SetPathValue("block_root", hexutil.Encode(stateRoot[:])) -// writer := httptest.NewRecorder() -// writer.Body = &bytes.Buffer{} -// -// s.GetLightClientBootstrap(writer, request) -// require.Equal(t, http.StatusOK, writer.Code) -// var resp structs.LightClientBootstrapResponse -// err = json.Unmarshal(writer.Body.Bytes(), &resp) -// require.NoError(t, err) -// var respHeader structs.LightClientHeader -// err = json.Unmarshal(resp.Data.Header, &respHeader) -// require.NoError(t, err) -// require.Equal(t, "bellatrix", resp.Version) -// -// blockHeader, err := l.Block.Header() -// require.NoError(t, err) -// require.Equal(t, hexutil.Encode(blockHeader.Header.BodyRoot), respHeader.Beacon.BodyRoot) -// require.Equal(t, strconv.FormatUint(uint64(blockHeader.Header.Slot), 10), respHeader.Beacon.Slot) -// -// require.NotNil(t, resp.Data.CurrentSyncCommittee) -// require.NotNil(t, resp.Data.CurrentSyncCommitteeBranch) -//} -// +import ( + "bytes" + "context" + "encoding/json" + "net/http" + "net/http/httptest" + "strconv" + "testing" + + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/prysmaticlabs/prysm/v5/api/server/structs" + mock "github.com/prysmaticlabs/prysm/v5/beacon-chain/blockchain/testing" + "github.com/prysmaticlabs/prysm/v5/beacon-chain/db/kv" + "github.com/prysmaticlabs/prysm/v5/beacon-chain/rpc/testutil" + "github.com/prysmaticlabs/prysm/v5/beacon-chain/state" + "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" + "github.com/prysmaticlabs/prysm/v5/testing/require" + "github.com/prysmaticlabs/prysm/v5/testing/util" +) + +func TestLightClientHandler_GetLightClientBootstrap_Altair(t *testing.T) { + l := util.NewTestLightClient(t).SetupTestAltair() + + slot := l.State.Slot() + stateRoot, err := l.State.HashTreeRoot(l.Ctx) + require.NoError(t, err) + + mockBlocker := &testutil.MockBlocker{BlockToReturn: l.Block} + mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot} + mockChainInfoFetcher := &mock.ChainService{Slot: &slot} + s := &Server{ + Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ + slot: l.State, + }}, + Blocker: mockBlocker, + HeadFetcher: mockChainService, + ChainInfoFetcher: mockChainInfoFetcher, + } + request := httptest.NewRequest("GET", "http://foo.com/", nil) + request.SetPathValue("block_root", hexutil.Encode(stateRoot[:])) + writer := httptest.NewRecorder() + writer.Body = &bytes.Buffer{} + + s.GetLightClientBootstrap(writer, request) + require.Equal(t, http.StatusOK, writer.Code) + var resp structs.LightClientBootstrapResponse + err = json.Unmarshal(writer.Body.Bytes(), &resp) + require.NoError(t, err) + var respHeader structs.LightClientHeader + err = json.Unmarshal(resp.Data.Header, &respHeader) + require.NoError(t, err) + require.Equal(t, "altair", resp.Version) + + blockHeader, err := l.Block.Header() + require.NoError(t, err) + require.Equal(t, hexutil.Encode(blockHeader.Header.BodyRoot), respHeader.Beacon.BodyRoot) + require.Equal(t, strconv.FormatUint(uint64(blockHeader.Header.Slot), 10), respHeader.Beacon.Slot) + + require.NotNil(t, resp.Data.CurrentSyncCommittee) + require.NotNil(t, resp.Data.CurrentSyncCommitteeBranch) +} + +func TestLightClientHandler_GetLightClientBootstrap_Bellatrix(t *testing.T) { + l := util.NewTestLightClient(t).SetupTestBellatrix() + + slot := l.State.Slot() + stateRoot, err := l.State.HashTreeRoot(l.Ctx) + require.NoError(t, err) + + mockBlocker := &testutil.MockBlocker{BlockToReturn: l.Block} + mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot} + mockChainInfoFetcher := &mock.ChainService{Slot: &slot} + s := &Server{ + Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ + slot: l.State, + }}, + Blocker: mockBlocker, + HeadFetcher: mockChainService, + ChainInfoFetcher: mockChainInfoFetcher, + } + request := httptest.NewRequest("GET", "http://foo.com/", nil) + request.SetPathValue("block_root", hexutil.Encode(stateRoot[:])) + writer := httptest.NewRecorder() + writer.Body = &bytes.Buffer{} + + s.GetLightClientBootstrap(writer, request) + require.Equal(t, http.StatusOK, writer.Code) + var resp structs.LightClientBootstrapResponse + err = json.Unmarshal(writer.Body.Bytes(), &resp) + require.NoError(t, err) + var respHeader structs.LightClientHeader + err = json.Unmarshal(resp.Data.Header, &respHeader) + require.NoError(t, err) + require.Equal(t, "bellatrix", resp.Version) + + blockHeader, err := l.Block.Header() + require.NoError(t, err) + require.Equal(t, hexutil.Encode(blockHeader.Header.BodyRoot), respHeader.Beacon.BodyRoot) + require.Equal(t, strconv.FormatUint(uint64(blockHeader.Header.Slot), 10), respHeader.Beacon.Slot) + + require.NotNil(t, resp.Data.CurrentSyncCommittee) + require.NotNil(t, resp.Data.CurrentSyncCommitteeBranch) +} + //func TestLightClientHandler_GetLightClientBootstrap_Capella(t *testing.T) { // l := util.NewTestLightClient(t).SetupTestCapella(false) // result is same for true and false // @@ -120,12 +113,14 @@ package lightclient // // mockBlocker := &testutil.MockBlocker{BlockToReturn: l.Block} // mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot} +// mockChainInfoFetcher := &mock.ChainService{Slot: &slot} // s := &Server{ // Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ // slot: l.State, // }}, -// Blocker: mockBlocker, -// HeadFetcher: mockChainService, +// Blocker: mockBlocker, +// HeadFetcher: mockChainService, +// ChainInfoFetcher: mockChainInfoFetcher, // } // request := httptest.NewRequest("GET", "http://foo.com/", nil) // request.SetPathValue("block_root", hexutil.Encode(stateRoot[:])) @@ -150,7 +145,7 @@ package lightclient // require.NotNil(t, resp.Data.CurrentSyncCommittee) // require.NotNil(t, resp.Data.CurrentSyncCommitteeBranch) //} -// + //func TestLightClientHandler_GetLightClientBootstrap_Deneb(t *testing.T) { // l := util.NewTestLightClient(t).SetupTestDeneb(false) // result is same for true and false // @@ -230,9 +225,9 @@ package lightclient // require.NotNil(t, resp.Data.CurrentSyncCommittee) // require.NotNil(t, resp.Data.CurrentSyncCommitteeBranch) //} -// -//// GetLightClientByRange tests -// + +// GetLightClientByRange tests + //func TestLightClientHandler_GetLightClientUpdatesByRangeAltair(t *testing.T) { // helpers.ClearCache() // ctx := context.Background() @@ -253,38 +248,33 @@ package lightclient // // updatePeriod := uint64(slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch))) // -// update := ðpbv2.LightClientUpdate{ -// AttestedHeader: ðpbv2.LightClientHeaderContainer{ -// Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ -// HeaderAltair: ðpbv2.LightClientHeader{ -// Beacon: ðpbv1.BeaconBlockHeader{ -// Slot: slot.Sub(1), -// ProposerIndex: 1, -// ParentRoot: []byte{1, 1, 1}, -// StateRoot: []byte{1, 1, 1}, -// BodyRoot: []byte{1, 1, 1}, -// }, -// }, +// updateRaw := &pb.LightClientUpdateAltair{ +// AttestedHeader: &pb.LightClientHeaderAltair{ +// Beacon: &pb.BeaconBlockHeader{ +// Slot: slot.Sub(1), +// ProposerIndex: 1, +// ParentRoot: []byte{1, 1, 1}, +// StateRoot: []byte{1, 1, 1}, +// BodyRoot: []byte{1, 1, 1}, // }, // }, -// NextSyncCommittee: ðpbv2.SyncCommittee{ +// NextSyncCommittee: &pb.SyncCommittee{ // Pubkeys: nil, // AggregatePubkey: nil, // }, // NextSyncCommitteeBranch: nil, // FinalizedHeader: nil, // FinalityBranch: nil, -// SyncAggregate: ðpbv1.SyncAggregate{ +// SyncAggregate: &pb.SyncAggregate{ // SyncCommitteeBits: []byte{1, 1, 1}, // SyncCommitteeSignature: []byte{1, 1, 1}, // }, // SignatureSlot: 7, // } // -// err = db.SaveLightClientUpdate(ctx, updatePeriod, ðpbv2.LightClientUpdateWithVersion{ -// Version: version.Altair, -// Data: update, -// }) +// update, err := light_client.NewWrappedUpdate(updateRaw) +// require.NoError(t, err) +// err = db.SaveLightClientUpdate(ctx, updatePeriod, update) // require.NoError(t, err) // // mockChainService := &mock.ChainService{State: st} @@ -310,344 +300,149 @@ package lightclient // require.NoError(t, err) // require.DeepEqual(t, updateJson, resp.Updates[0].Data) //} + +// func TestLightClientHandler_GetLightClientUpdatesByRangeCapella(t *testing.T) { +// helpers.ClearCache() +// ctx := context.Background() +// params.SetupTestConfigCleanup(t) +// config := params.BeaconConfig() +// config.AltairForkEpoch = 0 +// config.CapellaForkEpoch = 1 +// params.OverrideBeaconConfig(config) +// slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) +// +// st, err := util.NewBeaconStateCapella() +// require.NoError(t, err) +// err = st.SetSlot(slot) +// require.NoError(t, err) // -//func TestLightClientHandler_GetLightClientUpdatesByRangeCapella(t *testing.T) { -// helpers.ClearCache() -// ctx := context.Background() -// params.SetupTestConfigCleanup(t) -// config := params.BeaconConfig() -// config.AltairForkEpoch = 0 -// config.CapellaForkEpoch = 1 -// params.OverrideBeaconConfig(config) -// slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) -// -// st, err := util.NewBeaconStateCapella() -// require.NoError(t, err) -// err = st.SetSlot(slot) -// require.NoError(t, err) -// -// db := setupDB(t) +// db := setupDB(t) // -// updatePeriod := uint64(slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch))) +// updatePeriod := uint64(slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch))) // -// update := ðpbv2.LightClientUpdate{ -// AttestedHeader: ðpbv2.LightClientHeaderContainer{ -// Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ -// HeaderCapella: ðpbv2.LightClientHeaderCapella{ -// Beacon: ðpbv1.BeaconBlockHeader{ -// Slot: slot.Sub(1), -// ProposerIndex: 1, -// ParentRoot: []byte{1, 1, 1}, -// StateRoot: []byte{1, 1, 1}, -// BodyRoot: []byte{1, 1, 1}, -// }, -// Execution: &enginev1.ExecutionPayloadHeaderCapella{ -// FeeRecipient: []byte{1, 2, 3}, +// update := ðpbv2.LightClientUpdate{ +// AttestedHeader: ðpbv2.LightClientHeaderContainer{ +// Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ +// HeaderCapella: ðpbv2.LightClientHeaderCapella{ +// Beacon: ðpbv1.BeaconBlockHeader{ +// Slot: slot.Sub(1), +// ProposerIndex: 1, +// ParentRoot: []byte{1, 1, 1}, +// StateRoot: []byte{1, 1, 1}, +// BodyRoot: []byte{1, 1, 1}, +// }, +// Execution: &enginev1.ExecutionPayloadHeaderCapella{ +// FeeRecipient: []byte{1, 2, 3}, +// }, +// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, // }, -// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, // }, // }, -// }, -// NextSyncCommittee: ðpbv2.SyncCommittee{ -// Pubkeys: nil, -// AggregatePubkey: nil, -// }, -// NextSyncCommitteeBranch: nil, -// FinalizedHeader: ðpbv2.LightClientHeaderContainer{ -// Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ -// HeaderCapella: ðpbv2.LightClientHeaderCapella{ -// Beacon: ðpbv1.BeaconBlockHeader{ -// Slot: 12, -// ProposerIndex: 1, -// ParentRoot: []byte{1, 1, 1}, -// StateRoot: []byte{1, 1, 1}, -// BodyRoot: []byte{1, 1, 1}, -// }, -// Execution: &enginev1.ExecutionPayloadHeaderCapella{ -// FeeRecipient: []byte{1, 2, 3}, +// NextSyncCommittee: ðpbv2.SyncCommittee{ +// Pubkeys: nil, +// AggregatePubkey: nil, +// }, +// NextSyncCommitteeBranch: nil, +// FinalizedHeader: ðpbv2.LightClientHeaderContainer{ +// Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ +// HeaderCapella: ðpbv2.LightClientHeaderCapella{ +// Beacon: ðpbv1.BeaconBlockHeader{ +// Slot: 12, +// ProposerIndex: 1, +// ParentRoot: []byte{1, 1, 1}, +// StateRoot: []byte{1, 1, 1}, +// BodyRoot: []byte{1, 1, 1}, +// }, +// Execution: &enginev1.ExecutionPayloadHeaderCapella{ +// FeeRecipient: []byte{1, 2, 3}, +// }, +// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, // }, -// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, // }, // }, -// }, -// FinalityBranch: nil, -// SyncAggregate: ðpbv1.SyncAggregate{ -// SyncCommitteeBits: []byte{1, 1, 1}, -// SyncCommitteeSignature: []byte{1, 1, 1}, -// }, -// SignatureSlot: 7, -// } -// -// err = db.SaveLightClientUpdate(ctx, updatePeriod, ðpbv2.LightClientUpdateWithVersion{ -// Version: version.Capella, -// Data: update, -// }) -// require.NoError(t, err) +// FinalityBranch: nil, +// SyncAggregate: ðpbv1.SyncAggregate{ +// SyncCommitteeBits: []byte{1, 1, 1}, +// SyncCommitteeSignature: []byte{1, 1, 1}, +// }, +// SignatureSlot: 7, +// } // -// mockChainService := &mock.ChainService{State: st} -// s := &Server{ -// HeadFetcher: mockChainService, -// BeaconDB: db, -// } -// startPeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) -// url := fmt.Sprintf("http://foo.com/?count=1&start_period=%d", startPeriod) -// request := httptest.NewRequest("GET", url, nil) -// writer := httptest.NewRecorder() -// writer.Body = &bytes.Buffer{} +// err = db.SaveLightClientUpdate(ctx, updatePeriod, ðpbv2.LightClientUpdateWithVersion{ +// Version: version.Capella, +// Data: update, +// }) +// require.NoError(t, err) // -// s.GetLightClientUpdatesByRange(writer, request) +// mockChainService := &mock.ChainService{State: st} +// s := &Server{ +// HeadFetcher: mockChainService, +// BeaconDB: db, +// } +// startPeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) +// url := fmt.Sprintf("http://foo.com/?count=1&start_period=%d", startPeriod) +// request := httptest.NewRequest("GET", url, nil) +// writer := httptest.NewRecorder() +// writer.Body = &bytes.Buffer{} // -// require.Equal(t, http.StatusOK, writer.Code) -// var resp structs.LightClientUpdatesByRangeResponse -// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) -// require.NoError(t, err) -// require.Equal(t, 1, len(resp.Updates)) -// require.Equal(t, "capella", resp.Updates[0].Version) -// updateJson, err := structs.LightClientUpdateFromConsensus(update) -// require.NoError(t, err) -// require.DeepEqual(t, updateJson, resp.Updates[0].Data) -//} +// s.GetLightClientUpdatesByRange(writer, request) // -//func TestLightClientHandler_GetLightClientUpdatesByRangeDeneb(t *testing.T) { -// helpers.ClearCache() -// ctx := context.Background() -// params.SetupTestConfigCleanup(t) -// config := params.BeaconConfig() -// config.AltairForkEpoch = 0 -// config.DenebForkEpoch = 1 -// params.OverrideBeaconConfig(config) -// slot := primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) +// require.Equal(t, http.StatusOK, writer.Code) +// var resp structs.LightClientUpdatesByRangeResponse +// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) +// require.NoError(t, err) +// require.Equal(t, 1, len(resp.Updates)) +// require.Equal(t, "capella", resp.Updates[0].Version) +// updateJson, err := structs.LightClientUpdateFromConsensus(update) +// require.NoError(t, err) +// require.DeepEqual(t, updateJson, resp.Updates[0].Data) +// } // -// st, err := util.NewBeaconStateDeneb() -// require.NoError(t, err) -// err = st.SetSlot(slot) -// require.NoError(t, err) +// func TestLightClientHandler_GetLightClientUpdatesByRangeDeneb(t *testing.T) { +// helpers.ClearCache() +// ctx := context.Background() +// params.SetupTestConfigCleanup(t) +// config := params.BeaconConfig() +// config.AltairForkEpoch = 0 +// config.DenebForkEpoch = 1 +// params.OverrideBeaconConfig(config) +// slot := primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) +// +// st, err := util.NewBeaconStateDeneb() +// require.NoError(t, err) +// err = st.SetSlot(slot) +// require.NoError(t, err) // -// db := setupDB(t) +// db := setupDB(t) // -// updatePeriod := uint64(slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch))) +// updatePeriod := uint64(slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch))) // -// update := ðpbv2.LightClientUpdate{ -// AttestedHeader: ðpbv2.LightClientHeaderContainer{ -// Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ -// HeaderCapella: ðpbv2.LightClientHeaderCapella{ -// Beacon: ðpbv1.BeaconBlockHeader{ -// Slot: slot.Sub(1), -// ProposerIndex: 1, -// ParentRoot: []byte{1, 1, 1}, -// StateRoot: []byte{1, 1, 1}, -// BodyRoot: []byte{1, 1, 1}, -// }, -// Execution: &enginev1.ExecutionPayloadHeaderCapella{ -// FeeRecipient: []byte{1, 2, 3}, +// update := ðpbv2.LightClientUpdate{ +// AttestedHeader: ðpbv2.LightClientHeaderContainer{ +// Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ +// HeaderCapella: ðpbv2.LightClientHeaderCapella{ +// Beacon: ðpbv1.BeaconBlockHeader{ +// Slot: slot.Sub(1), +// ProposerIndex: 1, +// ParentRoot: []byte{1, 1, 1}, +// StateRoot: []byte{1, 1, 1}, +// BodyRoot: []byte{1, 1, 1}, +// }, +// Execution: &enginev1.ExecutionPayloadHeaderCapella{ +// FeeRecipient: []byte{1, 2, 3}, +// }, +// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, // }, -// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, // }, // }, -// }, -// NextSyncCommittee: ðpbv2.SyncCommittee{ -// Pubkeys: nil, -// AggregatePubkey: nil, -// }, -// NextSyncCommitteeBranch: nil, -// FinalizedHeader: ðpbv2.LightClientHeaderContainer{ -// Header: ðpbv2.LightClientHeaderContainer_HeaderDeneb{ -// HeaderDeneb: ðpbv2.LightClientHeaderDeneb{ -// Beacon: ðpbv1.BeaconBlockHeader{ -// Slot: 12, -// ProposerIndex: 1, -// ParentRoot: []byte{1, 1, 1}, -// StateRoot: []byte{1, 1, 1}, -// BodyRoot: []byte{1, 1, 1}, -// }, -// Execution: &enginev1.ExecutionPayloadHeaderDeneb{ -// FeeRecipient: []byte{1, 2, 3}, -// }, -// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, -// }, -// }, -// }, -// FinalityBranch: nil, -// SyncAggregate: ðpbv1.SyncAggregate{ -// SyncCommitteeBits: []byte{1, 1, 1}, -// SyncCommitteeSignature: []byte{1, 1, 1}, -// }, -// SignatureSlot: 7, -// } -// -// err = db.SaveLightClientUpdate(ctx, updatePeriod, ðpbv2.LightClientUpdateWithVersion{ -// Version: version.Deneb, -// Data: update, -// }) -// require.NoError(t, err) -// -// mockChainService := &mock.ChainService{State: st} -// s := &Server{ -// HeadFetcher: mockChainService, -// BeaconDB: db, -// } -// startPeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) -// url := fmt.Sprintf("http://foo.com/?count=1&start_period=%d", startPeriod) -// request := httptest.NewRequest("GET", url, nil) -// writer := httptest.NewRecorder() -// writer.Body = &bytes.Buffer{} -// -// s.GetLightClientUpdatesByRange(writer, request) -// -// require.Equal(t, http.StatusOK, writer.Code) -// var resp structs.LightClientUpdatesByRangeResponse -// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) -// require.NoError(t, err) -// require.Equal(t, 1, len(resp.Updates)) -// require.Equal(t, "deneb", resp.Updates[0].Version) -// updateJson, err := structs.LightClientUpdateFromConsensus(update) -// require.NoError(t, err) -// require.DeepEqual(t, updateJson, resp.Updates[0].Data) -//} -// -//func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleAltair(t *testing.T) { -// helpers.ClearCache() -// ctx := context.Background() -// params.SetupTestConfigCleanup(t) -// config := params.BeaconConfig() -// config.AltairForkEpoch = 0 -// config.EpochsPerSyncCommitteePeriod = 1 -// params.OverrideBeaconConfig(config) -// slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) -// -// st, err := util.NewBeaconStateAltair() -// require.NoError(t, err) -// headSlot := slot.Add(33) // 2 periods -// err = st.SetSlot(headSlot) -// require.NoError(t, err) -// -// db := setupDB(t) -// -// updates := make([]*ethpbv2.LightClientUpdate, 2) -// -// updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) -// -// for i := 0; i < 2; i++ { -// newSlot := slot.Add(uint64(i)) -// -// update := ðpbv2.LightClientUpdate{ -// AttestedHeader: ðpbv2.LightClientHeaderContainer{ -// Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ -// HeaderAltair: ðpbv2.LightClientHeader{ -// Beacon: ðpbv1.BeaconBlockHeader{ -// Slot: newSlot, -// ProposerIndex: 1, -// ParentRoot: []byte{1, 1, 1}, -// StateRoot: []byte{1, 1, 1}, -// BodyRoot: []byte{1, 1, 1}, -// }, -// }, -// }, -// }, -// NextSyncCommittee: ðpbv2.SyncCommittee{ -// Pubkeys: nil, -// AggregatePubkey: nil, -// }, -// NextSyncCommitteeBranch: nil, -// FinalizedHeader: nil, -// FinalityBranch: nil, -// SyncAggregate: ðpbv1.SyncAggregate{ -// SyncCommitteeBits: []byte{1, 1, 1}, -// SyncCommitteeSignature: []byte{1, 1, 1}, -// }, -// SignatureSlot: 7, -// } -// -// updates[i] = update -// -// err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ -// Version: version.Altair, -// Data: update, -// }) -// require.NoError(t, err) -// -// updatePeriod++ -// } -// -// mockChainService := &mock.ChainService{State: st} -// s := &Server{ -// HeadFetcher: mockChainService, -// BeaconDB: db, -// } -// startPeriod := slot.Sub(1).Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) -// url := fmt.Sprintf("http://foo.com/?count=100&start_period=%d", startPeriod) -// request := httptest.NewRequest("GET", url, nil) -// writer := httptest.NewRecorder() -// writer.Body = &bytes.Buffer{} -// -// s.GetLightClientUpdatesByRange(writer, request) -// -// require.Equal(t, http.StatusOK, writer.Code) -// var resp structs.LightClientUpdatesByRangeResponse -// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) -// require.NoError(t, err) -// require.Equal(t, 2, len(resp.Updates)) -// for i, update := range updates { -// require.Equal(t, "altair", resp.Updates[i].Version) -// updateJson, err := structs.LightClientUpdateFromConsensus(update) -// require.NoError(t, err) -// require.DeepEqual(t, updateJson, resp.Updates[i].Data) -// } -//} -// -//func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleCapella(t *testing.T) { -// helpers.ClearCache() -// ctx := context.Background() -// params.SetupTestConfigCleanup(t) -// config := params.BeaconConfig() -// config.AltairForkEpoch = 0 -// config.CapellaForkEpoch = 1 -// config.EpochsPerSyncCommitteePeriod = 1 -// params.OverrideBeaconConfig(config) -// slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) -// -// st, err := util.NewBeaconStateAltair() -// require.NoError(t, err) -// headSlot := slot.Add(33) // 2 periods -// err = st.SetSlot(headSlot) -// require.NoError(t, err) -// -// db := setupDB(t) -// -// updates := make([]*ethpbv2.LightClientUpdate, 2) -// -// updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) -// -// for i := 0; i < 2; i++ { -// -// newSlot := slot.Add(uint64(i)) -// -// update := ðpbv2.LightClientUpdate{ -// AttestedHeader: ðpbv2.LightClientHeaderContainer{ -// Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ -// HeaderCapella: ðpbv2.LightClientHeaderCapella{ -// Beacon: ðpbv1.BeaconBlockHeader{ -// Slot: newSlot, -// ProposerIndex: 1, -// ParentRoot: []byte{1, 1, 1}, -// StateRoot: []byte{1, 1, 1}, -// BodyRoot: []byte{1, 1, 1}, -// }, -// Execution: &enginev1.ExecutionPayloadHeaderCapella{ -// FeeRecipient: []byte{1, 2, 3}, -// }, -// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, -// }, -// }, -// }, -// NextSyncCommittee: ðpbv2.SyncCommittee{ -// Pubkeys: nil, -// AggregatePubkey: nil, +// NextSyncCommittee: ðpbv2.SyncCommittee{ +// Pubkeys: nil, +// AggregatePubkey: nil, // }, // NextSyncCommitteeBranch: nil, // FinalizedHeader: ðpbv2.LightClientHeaderContainer{ -// Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ -// HeaderCapella: ðpbv2.LightClientHeaderCapella{ +// Header: ðpbv2.LightClientHeaderContainer_HeaderDeneb{ +// HeaderDeneb: ðpbv2.LightClientHeaderDeneb{ // Beacon: ðpbv1.BeaconBlockHeader{ // Slot: 12, // ProposerIndex: 1, @@ -655,7 +450,7 @@ package lightclient // StateRoot: []byte{1, 1, 1}, // BodyRoot: []byte{1, 1, 1}, // }, -// Execution: &enginev1.ExecutionPayloadHeaderCapella{ +// Execution: &enginev1.ExecutionPayloadHeaderDeneb{ // FeeRecipient: []byte{1, 2, 3}, // }, // ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, @@ -670,516 +465,380 @@ package lightclient // SignatureSlot: 7, // } // -// updates[i] = update -// -// err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ -// Version: version.Capella, +// err = db.SaveLightClientUpdate(ctx, updatePeriod, ðpbv2.LightClientUpdateWithVersion{ +// Version: version.Deneb, // Data: update, // }) // require.NoError(t, err) // -// updatePeriod++ -// } -// -// mockChainService := &mock.ChainService{State: st} -// s := &Server{ -// HeadFetcher: mockChainService, -// BeaconDB: db, -// } -// startPeriod := slot.Sub(1).Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) -// url := fmt.Sprintf("http://foo.com/?count=100&start_period=%d", startPeriod) -// request := httptest.NewRequest("GET", url, nil) -// writer := httptest.NewRecorder() -// writer.Body = &bytes.Buffer{} +// mockChainService := &mock.ChainService{State: st} +// s := &Server{ +// HeadFetcher: mockChainService, +// BeaconDB: db, +// } +// startPeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) +// url := fmt.Sprintf("http://foo.com/?count=1&start_period=%d", startPeriod) +// request := httptest.NewRequest("GET", url, nil) +// writer := httptest.NewRecorder() +// writer.Body = &bytes.Buffer{} // -// s.GetLightClientUpdatesByRange(writer, request) +// s.GetLightClientUpdatesByRange(writer, request) // -// require.Equal(t, http.StatusOK, writer.Code) -// var resp structs.LightClientUpdatesByRangeResponse -// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) -// require.NoError(t, err) -// require.Equal(t, 2, len(resp.Updates)) -// for i, update := range updates { -// require.Equal(t, "capella", resp.Updates[i].Version) +// require.Equal(t, http.StatusOK, writer.Code) +// var resp structs.LightClientUpdatesByRangeResponse +// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) +// require.NoError(t, err) +// require.Equal(t, 1, len(resp.Updates)) +// require.Equal(t, "deneb", resp.Updates[0].Version) // updateJson, err := structs.LightClientUpdateFromConsensus(update) // require.NoError(t, err) -// require.DeepEqual(t, updateJson, resp.Updates[i].Data) +// require.DeepEqual(t, updateJson, resp.Updates[0].Data) // } -//} -// -//func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleDeneb(t *testing.T) { -// helpers.ClearCache() -// ctx := context.Background() -// params.SetupTestConfigCleanup(t) -// config := params.BeaconConfig() -// config.AltairForkEpoch = 0 -// config.DenebForkEpoch = 1 -// config.EpochsPerSyncCommitteePeriod = 1 -// params.OverrideBeaconConfig(config) -// slot := primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) // -// st, err := util.NewBeaconStateAltair() -// require.NoError(t, err) -// headSlot := slot.Add(33) -// err = st.SetSlot(headSlot) -// require.NoError(t, err) -// -// db := setupDB(t) +// func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleAltair(t *testing.T) { +// helpers.ClearCache() +// ctx := context.Background() +// params.SetupTestConfigCleanup(t) +// config := params.BeaconConfig() +// config.AltairForkEpoch = 0 +// config.EpochsPerSyncCommitteePeriod = 1 +// params.OverrideBeaconConfig(config) +// slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) +// +// st, err := util.NewBeaconStateAltair() +// require.NoError(t, err) +// headSlot := slot.Add(33) // 2 periods +// err = st.SetSlot(headSlot) +// require.NoError(t, err) // -// updates := make([]*ethpbv2.LightClientUpdate, 2) +// db := setupDB(t) // -// updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) +// updates := make([]*ethpbv2.LightClientUpdate, 2) // -// for i := 0; i < 2; i++ { +// updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) // -// newSlot := slot.Add(uint64(i)) +// for i := 0; i < 2; i++ { +// newSlot := slot.Add(uint64(i)) // -// update := ðpbv2.LightClientUpdate{ -// AttestedHeader: ðpbv2.LightClientHeaderContainer{ -// Header: ðpbv2.LightClientHeaderContainer_HeaderDeneb{ -// HeaderDeneb: ðpbv2.LightClientHeaderDeneb{ -// Beacon: ðpbv1.BeaconBlockHeader{ -// Slot: newSlot, -// ProposerIndex: 1, -// ParentRoot: []byte{1, 1, 1}, -// StateRoot: []byte{1, 1, 1}, -// BodyRoot: []byte{1, 1, 1}, -// }, -// Execution: &enginev1.ExecutionPayloadHeaderDeneb{ -// FeeRecipient: []byte{1, 2, 3}, +// update := ðpbv2.LightClientUpdate{ +// AttestedHeader: ðpbv2.LightClientHeaderContainer{ +// Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ +// HeaderAltair: ðpbv2.LightClientHeader{ +// Beacon: ðpbv1.BeaconBlockHeader{ +// Slot: newSlot, +// ProposerIndex: 1, +// ParentRoot: []byte{1, 1, 1}, +// StateRoot: []byte{1, 1, 1}, +// BodyRoot: []byte{1, 1, 1}, +// }, // }, -// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, // }, // }, -// }, -// NextSyncCommittee: ðpbv2.SyncCommittee{ -// Pubkeys: nil, -// AggregatePubkey: nil, -// }, -// NextSyncCommitteeBranch: nil, -// FinalizedHeader: ðpbv2.LightClientHeaderContainer{ -// Header: ðpbv2.LightClientHeaderContainer_HeaderDeneb{ -// HeaderDeneb: ðpbv2.LightClientHeaderDeneb{ -// Beacon: ðpbv1.BeaconBlockHeader{ -// Slot: 12, -// ProposerIndex: 1, -// ParentRoot: []byte{1, 1, 1}, -// StateRoot: []byte{1, 1, 1}, -// BodyRoot: []byte{1, 1, 1}, -// }, -// Execution: &enginev1.ExecutionPayloadHeaderDeneb{ -// FeeRecipient: []byte{1, 2, 3}, -// }, -// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, -// }, +// NextSyncCommittee: ðpbv2.SyncCommittee{ +// Pubkeys: nil, +// AggregatePubkey: nil, // }, -// }, -// FinalityBranch: nil, -// SyncAggregate: ðpbv1.SyncAggregate{ -// SyncCommitteeBits: []byte{1, 1, 1}, -// SyncCommitteeSignature: []byte{1, 1, 1}, -// }, -// SignatureSlot: 7, -// } +// NextSyncCommitteeBranch: nil, +// FinalizedHeader: nil, +// FinalityBranch: nil, +// SyncAggregate: ðpbv1.SyncAggregate{ +// SyncCommitteeBits: []byte{1, 1, 1}, +// SyncCommitteeSignature: []byte{1, 1, 1}, +// }, +// SignatureSlot: 7, +// } // -// updates[i] = update +// updates[i] = update // -// err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ -// Version: version.Deneb, -// Data: update, -// }) -// require.NoError(t, err) +// err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ +// Version: version.Altair, +// Data: update, +// }) +// require.NoError(t, err) // -// updatePeriod++ -// } +// updatePeriod++ +// } // -// mockChainService := &mock.ChainService{State: st} -// s := &Server{ -// HeadFetcher: mockChainService, -// BeaconDB: db, -// } -// startPeriod := slot.Sub(1).Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) -// url := fmt.Sprintf("http://foo.com/?count=100&start_period=%d", startPeriod) -// request := httptest.NewRequest("GET", url, nil) -// writer := httptest.NewRecorder() -// writer.Body = &bytes.Buffer{} +// mockChainService := &mock.ChainService{State: st} +// s := &Server{ +// HeadFetcher: mockChainService, +// BeaconDB: db, +// } +// startPeriod := slot.Sub(1).Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) +// url := fmt.Sprintf("http://foo.com/?count=100&start_period=%d", startPeriod) +// request := httptest.NewRequest("GET", url, nil) +// writer := httptest.NewRecorder() +// writer.Body = &bytes.Buffer{} // -// s.GetLightClientUpdatesByRange(writer, request) +// s.GetLightClientUpdatesByRange(writer, request) // -// require.Equal(t, http.StatusOK, writer.Code) -// var resp structs.LightClientUpdatesByRangeResponse -// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) -// require.NoError(t, err) -// require.Equal(t, 2, len(resp.Updates)) -// for i, update := range updates { -// require.Equal(t, "deneb", resp.Updates[i].Version) -// updateJson, err := structs.LightClientUpdateFromConsensus(update) +// require.Equal(t, http.StatusOK, writer.Code) +// var resp structs.LightClientUpdatesByRangeResponse +// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) // require.NoError(t, err) -// require.DeepEqual(t, updateJson, resp.Updates[i].Data) +// require.Equal(t, 2, len(resp.Updates)) +// for i, update := range updates { +// require.Equal(t, "altair", resp.Updates[i].Version) +// updateJson, err := structs.LightClientUpdateFromConsensus(update) +// require.NoError(t, err) +// require.DeepEqual(t, updateJson, resp.Updates[i].Data) +// } // } -//} // -//func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleForksAltairCapella(t *testing.T) { -// helpers.ClearCache() -// ctx := context.Background() -// params.SetupTestConfigCleanup(t) -// config := params.BeaconConfig() -// config.AltairForkEpoch = 0 -// config.CapellaForkEpoch = 1 -// config.EpochsPerSyncCommitteePeriod = 1 -// params.OverrideBeaconConfig(config) -// slotCapella := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) -// slotAltair := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) +// func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleCapella(t *testing.T) { +// helpers.ClearCache() +// ctx := context.Background() +// params.SetupTestConfigCleanup(t) +// config := params.BeaconConfig() +// config.AltairForkEpoch = 0 +// config.CapellaForkEpoch = 1 +// config.EpochsPerSyncCommitteePeriod = 1 +// params.OverrideBeaconConfig(config) +// slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) +// +// st, err := util.NewBeaconStateAltair() +// require.NoError(t, err) +// headSlot := slot.Add(33) // 2 periods +// err = st.SetSlot(headSlot) +// require.NoError(t, err) // -// st, err := util.NewBeaconStateAltair() -// require.NoError(t, err) -// headSlot := slotCapella.Add(1) -// err = st.SetSlot(headSlot) -// require.NoError(t, err) +// db := setupDB(t) // -// db := setupDB(t) +// updates := make([]*ethpbv2.LightClientUpdate, 2) // -// updates := make([]*ethpbv2.LightClientUpdate, 2) +// updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) +// +// for i := 0; i < 2; i++ { // -// updatePeriod := slotAltair.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) +// newSlot := slot.Add(uint64(i)) // -// update := ðpbv2.LightClientUpdate{ -// AttestedHeader: ðpbv2.LightClientHeaderContainer{ -// Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ -// HeaderAltair: ðpbv2.LightClientHeader{ -// Beacon: ðpbv1.BeaconBlockHeader{ -// Slot: slotAltair, -// ProposerIndex: 1, -// ParentRoot: []byte{1, 1, 1}, -// StateRoot: []byte{1, 1, 1}, -// BodyRoot: []byte{1, 1, 1}, +// update := ðpbv2.LightClientUpdate{ +// AttestedHeader: ðpbv2.LightClientHeaderContainer{ +// Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ +// HeaderCapella: ðpbv2.LightClientHeaderCapella{ +// Beacon: ðpbv1.BeaconBlockHeader{ +// Slot: newSlot, +// ProposerIndex: 1, +// ParentRoot: []byte{1, 1, 1}, +// StateRoot: []byte{1, 1, 1}, +// BodyRoot: []byte{1, 1, 1}, +// }, +// Execution: &enginev1.ExecutionPayloadHeaderCapella{ +// FeeRecipient: []byte{1, 2, 3}, +// }, +// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, +// }, // }, // }, -// }, -// }, -// NextSyncCommittee: ðpbv2.SyncCommittee{ -// Pubkeys: nil, -// AggregatePubkey: nil, -// }, -// NextSyncCommitteeBranch: nil, -// FinalizedHeader: ðpbv2.LightClientHeaderContainer{ -// Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ -// HeaderAltair: ðpbv2.LightClientHeader{ -// Beacon: ðpbv1.BeaconBlockHeader{ -// Slot: 12, -// ProposerIndex: 1, -// ParentRoot: []byte{1, 1, 1}, -// StateRoot: []byte{1, 1, 1}, -// BodyRoot: []byte{1, 1, 1}, -// }, +// NextSyncCommittee: ðpbv2.SyncCommittee{ +// Pubkeys: nil, +// AggregatePubkey: nil, // }, -// }, -// }, -// FinalityBranch: nil, -// SyncAggregate: ðpbv1.SyncAggregate{ -// SyncCommitteeBits: []byte{1, 1, 1}, -// SyncCommitteeSignature: []byte{1, 1, 1}, -// }, -// SignatureSlot: slotAltair, -// } -// -// updates[0] = update -// -// err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ -// Version: version.Altair, -// Data: update, -// }) -// require.NoError(t, err) -// -// updatePeriod = slotCapella.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) -// -// update = ðpbv2.LightClientUpdate{ -// AttestedHeader: ðpbv2.LightClientHeaderContainer{ -// Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ -// HeaderCapella: ðpbv2.LightClientHeaderCapella{ -// Beacon: ðpbv1.BeaconBlockHeader{ -// Slot: slotCapella, -// ProposerIndex: 1, -// ParentRoot: []byte{1, 1, 1}, -// StateRoot: []byte{1, 1, 1}, -// BodyRoot: []byte{1, 1, 1}, -// }, -// Execution: &enginev1.ExecutionPayloadHeaderCapella{ -// FeeRecipient: []byte{1, 2, 3}, +// NextSyncCommitteeBranch: nil, +// FinalizedHeader: ðpbv2.LightClientHeaderContainer{ +// Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ +// HeaderCapella: ðpbv2.LightClientHeaderCapella{ +// Beacon: ðpbv1.BeaconBlockHeader{ +// Slot: 12, +// ProposerIndex: 1, +// ParentRoot: []byte{1, 1, 1}, +// StateRoot: []byte{1, 1, 1}, +// BodyRoot: []byte{1, 1, 1}, +// }, +// Execution: &enginev1.ExecutionPayloadHeaderCapella{ +// FeeRecipient: []byte{1, 2, 3}, +// }, +// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, +// }, // }, -// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, // }, -// }, -// }, -// NextSyncCommittee: ðpbv2.SyncCommittee{ -// Pubkeys: nil, -// AggregatePubkey: nil, -// }, -// NextSyncCommitteeBranch: nil, -// FinalizedHeader: ðpbv2.LightClientHeaderContainer{ -// Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ -// HeaderCapella: ðpbv2.LightClientHeaderCapella{ -// Beacon: ðpbv1.BeaconBlockHeader{ -// Slot: 12, -// ProposerIndex: 1, -// ParentRoot: []byte{1, 1, 1}, -// StateRoot: []byte{1, 1, 1}, -// BodyRoot: []byte{1, 1, 1}, -// }, -// Execution: &enginev1.ExecutionPayloadHeaderCapella{ -// FeeRecipient: []byte{1, 2, 3}, -// }, -// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, +// FinalityBranch: nil, +// SyncAggregate: ðpbv1.SyncAggregate{ +// SyncCommitteeBits: []byte{1, 1, 1}, +// SyncCommitteeSignature: []byte{1, 1, 1}, // }, -// }, -// }, -// FinalityBranch: nil, -// SyncAggregate: ðpbv1.SyncAggregate{ -// SyncCommitteeBits: []byte{1, 1, 1}, -// SyncCommitteeSignature: []byte{1, 1, 1}, -// }, -// SignatureSlot: slotCapella, -// } +// SignatureSlot: 7, +// } // -// updates[1] = update +// updates[i] = update // -// err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ -// Version: version.Capella, -// Data: update, -// }) -// require.NoError(t, err) +// err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ +// Version: version.Capella, +// Data: update, +// }) +// require.NoError(t, err) // -// mockChainService := &mock.ChainService{State: st} -// s := &Server{ -// HeadFetcher: mockChainService, -// BeaconDB: db, -// } -// startPeriod := 0 -// url := fmt.Sprintf("http://foo.com/?count=100&start_period=%d", startPeriod) -// request := httptest.NewRequest("GET", url, nil) -// writer := httptest.NewRecorder() -// writer.Body = &bytes.Buffer{} +// updatePeriod++ +// } // -// s.GetLightClientUpdatesByRange(writer, request) +// mockChainService := &mock.ChainService{State: st} +// s := &Server{ +// HeadFetcher: mockChainService, +// BeaconDB: db, +// } +// startPeriod := slot.Sub(1).Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) +// url := fmt.Sprintf("http://foo.com/?count=100&start_period=%d", startPeriod) +// request := httptest.NewRequest("GET", url, nil) +// writer := httptest.NewRecorder() +// writer.Body = &bytes.Buffer{} // -// require.Equal(t, http.StatusOK, writer.Code) -// var resp structs.LightClientUpdatesByRangeResponse -// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) -// require.NoError(t, err) -// require.Equal(t, 2, len(resp.Updates)) -// for i, update := range updates { -// if i < 1 { -// require.Equal(t, "altair", resp.Updates[i].Version) -// } else { +// s.GetLightClientUpdatesByRange(writer, request) +// +// require.Equal(t, http.StatusOK, writer.Code) +// var resp structs.LightClientUpdatesByRangeResponse +// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) +// require.NoError(t, err) +// require.Equal(t, 2, len(resp.Updates)) +// for i, update := range updates { // require.Equal(t, "capella", resp.Updates[i].Version) +// updateJson, err := structs.LightClientUpdateFromConsensus(update) +// require.NoError(t, err) +// require.DeepEqual(t, updateJson, resp.Updates[i].Data) // } -// updateJson, err := structs.LightClientUpdateFromConsensus(update) -// require.NoError(t, err) -// require.DeepEqual(t, updateJson, resp.Updates[i].Data) // } -//} // -//func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleForksCapellaDeneb(t *testing.T) { -// helpers.ClearCache() -// ctx := context.Background() -// params.SetupTestConfigCleanup(t) -// config := params.BeaconConfig() -// config.AltairForkEpoch = 0 -// config.CapellaForkEpoch = 1 -// config.DenebForkEpoch = 2 -// config.EpochsPerSyncCommitteePeriod = 1 -// params.OverrideBeaconConfig(config) -// slotDeneb := primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) -// slotCapella := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) -// -// st, err := util.NewBeaconStateAltair() -// require.NoError(t, err) -// headSlot := slotDeneb.Add(1) -// err = st.SetSlot(headSlot) -// require.NoError(t, err) -// -// db := setupDB(t) +// func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleDeneb(t *testing.T) { +// helpers.ClearCache() +// ctx := context.Background() +// params.SetupTestConfigCleanup(t) +// config := params.BeaconConfig() +// config.AltairForkEpoch = 0 +// config.DenebForkEpoch = 1 +// config.EpochsPerSyncCommitteePeriod = 1 +// params.OverrideBeaconConfig(config) +// slot := primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) +// +// st, err := util.NewBeaconStateAltair() +// require.NoError(t, err) +// headSlot := slot.Add(33) +// err = st.SetSlot(headSlot) +// require.NoError(t, err) // -// updates := make([]*ethpbv2.LightClientUpdate, 2) +// db := setupDB(t) // -// updatePeriod := slotCapella.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) +// updates := make([]*ethpbv2.LightClientUpdate, 2) // -// update := ðpbv2.LightClientUpdate{ -// AttestedHeader: ðpbv2.LightClientHeaderContainer{ -// Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ -// HeaderCapella: ðpbv2.LightClientHeaderCapella{ -// Beacon: ðpbv1.BeaconBlockHeader{ -// Slot: slotCapella, -// ProposerIndex: 1, -// ParentRoot: []byte{1, 1, 1}, -// StateRoot: []byte{1, 1, 1}, -// BodyRoot: []byte{1, 1, 1}, -// }, -// Execution: &enginev1.ExecutionPayloadHeaderCapella{ -// FeeRecipient: []byte{1, 2, 3}, -// }, -// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, -// }, -// }, -// }, -// NextSyncCommittee: ðpbv2.SyncCommittee{ -// Pubkeys: nil, -// AggregatePubkey: nil, -// }, -// NextSyncCommitteeBranch: nil, -// FinalizedHeader: ðpbv2.LightClientHeaderContainer{ -// Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ -// HeaderCapella: ðpbv2.LightClientHeaderCapella{ -// Beacon: ðpbv1.BeaconBlockHeader{ -// Slot: 12, -// ProposerIndex: 1, -// ParentRoot: []byte{1, 1, 1}, -// StateRoot: []byte{1, 1, 1}, -// BodyRoot: []byte{1, 1, 1}, -// }, -// Execution: &enginev1.ExecutionPayloadHeaderCapella{ -// FeeRecipient: []byte{1, 2, 3}, -// }, -// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, -// }, -// }, -// }, -// FinalityBranch: nil, -// SyncAggregate: ðpbv1.SyncAggregate{ -// SyncCommitteeBits: []byte{1, 1, 1}, -// SyncCommitteeSignature: []byte{1, 1, 1}, -// }, -// SignatureSlot: slotCapella, -// } +// updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) // -// updates[0] = update +// for i := 0; i < 2; i++ { // -// err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ -// Version: version.Capella, -// Data: update, -// }) -// require.NoError(t, err) +// newSlot := slot.Add(uint64(i)) // -// updatePeriod = slotDeneb.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) -// -// update = ðpbv2.LightClientUpdate{ -// AttestedHeader: ðpbv2.LightClientHeaderContainer{ -// Header: ðpbv2.LightClientHeaderContainer_HeaderDeneb{ -// HeaderDeneb: ðpbv2.LightClientHeaderDeneb{ -// Beacon: ðpbv1.BeaconBlockHeader{ -// Slot: slotDeneb, -// ProposerIndex: 1, -// ParentRoot: []byte{1, 1, 1}, -// StateRoot: []byte{1, 1, 1}, -// BodyRoot: []byte{1, 1, 1}, -// }, -// Execution: &enginev1.ExecutionPayloadHeaderDeneb{ -// FeeRecipient: []byte{1, 2, 3}, +// update := ðpbv2.LightClientUpdate{ +// AttestedHeader: ðpbv2.LightClientHeaderContainer{ +// Header: ðpbv2.LightClientHeaderContainer_HeaderDeneb{ +// HeaderDeneb: ðpbv2.LightClientHeaderDeneb{ +// Beacon: ðpbv1.BeaconBlockHeader{ +// Slot: newSlot, +// ProposerIndex: 1, +// ParentRoot: []byte{1, 1, 1}, +// StateRoot: []byte{1, 1, 1}, +// BodyRoot: []byte{1, 1, 1}, +// }, +// Execution: &enginev1.ExecutionPayloadHeaderDeneb{ +// FeeRecipient: []byte{1, 2, 3}, +// }, +// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, +// }, // }, -// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, // }, -// }, -// }, -// NextSyncCommittee: ðpbv2.SyncCommittee{ -// Pubkeys: nil, -// AggregatePubkey: nil, -// }, -// NextSyncCommitteeBranch: nil, -// FinalizedHeader: ðpbv2.LightClientHeaderContainer{ -// Header: ðpbv2.LightClientHeaderContainer_HeaderDeneb{ -// HeaderDeneb: ðpbv2.LightClientHeaderDeneb{ -// Beacon: ðpbv1.BeaconBlockHeader{ -// Slot: 12, -// ProposerIndex: 1, -// ParentRoot: []byte{1, 1, 1}, -// StateRoot: []byte{1, 1, 1}, -// BodyRoot: []byte{1, 1, 1}, -// }, -// Execution: &enginev1.ExecutionPayloadHeaderDeneb{ -// FeeRecipient: []byte{1, 2, 3}, +// NextSyncCommittee: ðpbv2.SyncCommittee{ +// Pubkeys: nil, +// AggregatePubkey: nil, +// }, +// NextSyncCommitteeBranch: nil, +// FinalizedHeader: ðpbv2.LightClientHeaderContainer{ +// Header: ðpbv2.LightClientHeaderContainer_HeaderDeneb{ +// HeaderDeneb: ðpbv2.LightClientHeaderDeneb{ +// Beacon: ðpbv1.BeaconBlockHeader{ +// Slot: 12, +// ProposerIndex: 1, +// ParentRoot: []byte{1, 1, 1}, +// StateRoot: []byte{1, 1, 1}, +// BodyRoot: []byte{1, 1, 1}, +// }, +// Execution: &enginev1.ExecutionPayloadHeaderDeneb{ +// FeeRecipient: []byte{1, 2, 3}, +// }, +// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, +// }, // }, -// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, // }, -// }, -// }, -// FinalityBranch: nil, -// SyncAggregate: ðpbv1.SyncAggregate{ -// SyncCommitteeBits: []byte{1, 1, 1}, -// SyncCommitteeSignature: []byte{1, 1, 1}, -// }, -// SignatureSlot: slotDeneb, -// } +// FinalityBranch: nil, +// SyncAggregate: ðpbv1.SyncAggregate{ +// SyncCommitteeBits: []byte{1, 1, 1}, +// SyncCommitteeSignature: []byte{1, 1, 1}, +// }, +// SignatureSlot: 7, +// } // -// updates[1] = update +// updates[i] = update // -// err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ -// Version: version.Deneb, -// Data: update, -// }) -// require.NoError(t, err) +// err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ +// Version: version.Deneb, +// Data: update, +// }) +// require.NoError(t, err) // -// mockChainService := &mock.ChainService{State: st} -// s := &Server{ -// HeadFetcher: mockChainService, -// BeaconDB: db, -// } -// startPeriod := 1 -// url := fmt.Sprintf("http://foo.com/?count=100&start_period=%d", startPeriod) -// request := httptest.NewRequest("GET", url, nil) -// writer := httptest.NewRecorder() -// writer.Body = &bytes.Buffer{} +// updatePeriod++ +// } // -// s.GetLightClientUpdatesByRange(writer, request) +// mockChainService := &mock.ChainService{State: st} +// s := &Server{ +// HeadFetcher: mockChainService, +// BeaconDB: db, +// } +// startPeriod := slot.Sub(1).Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) +// url := fmt.Sprintf("http://foo.com/?count=100&start_period=%d", startPeriod) +// request := httptest.NewRequest("GET", url, nil) +// writer := httptest.NewRecorder() +// writer.Body = &bytes.Buffer{} // -// require.Equal(t, http.StatusOK, writer.Code) -// var resp structs.LightClientUpdatesByRangeResponse -// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) -// require.NoError(t, err) -// require.Equal(t, 2, len(resp.Updates)) -// for i, update := range updates { -// if i < 1 { -// require.Equal(t, "capella", resp.Updates[i].Version) -// } else { +// s.GetLightClientUpdatesByRange(writer, request) +// +// require.Equal(t, http.StatusOK, writer.Code) +// var resp structs.LightClientUpdatesByRangeResponse +// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) +// require.NoError(t, err) +// require.Equal(t, 2, len(resp.Updates)) +// for i, update := range updates { // require.Equal(t, "deneb", resp.Updates[i].Version) +// updateJson, err := structs.LightClientUpdateFromConsensus(update) +// require.NoError(t, err) +// require.DeepEqual(t, updateJson, resp.Updates[i].Data) // } -// updateJson, err := structs.LightClientUpdateFromConsensus(update) -// require.NoError(t, err) -// require.DeepEqual(t, updateJson, resp.Updates[i].Data) // } -//} -// -//func TestLightClientHandler_GetLightClientUpdatesByRangeCountBiggerThanLimit(t *testing.T) { -// helpers.ClearCache() -// ctx := context.Background() -// params.SetupTestConfigCleanup(t) -// config := params.BeaconConfig() -// config.AltairForkEpoch = 0 -// config.EpochsPerSyncCommitteePeriod = 1 -// config.MaxRequestLightClientUpdates = 2 -// params.OverrideBeaconConfig(config) -// slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) -// -// st, err := util.NewBeaconStateAltair() -// require.NoError(t, err) -// headSlot := slot.Add(65) -// err = st.SetSlot(headSlot) -// require.NoError(t, err) // -// db := setupDB(t) +// func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleForksAltairCapella(t *testing.T) { +// helpers.ClearCache() +// ctx := context.Background() +// params.SetupTestConfigCleanup(t) +// config := params.BeaconConfig() +// config.AltairForkEpoch = 0 +// config.CapellaForkEpoch = 1 +// config.EpochsPerSyncCommitteePeriod = 1 +// params.OverrideBeaconConfig(config) +// slotCapella := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) +// slotAltair := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) +// +// st, err := util.NewBeaconStateAltair() +// require.NoError(t, err) +// headSlot := slotCapella.Add(1) +// err = st.SetSlot(headSlot) +// require.NoError(t, err) // -// updates := make([]*ethpbv2.LightClientUpdate, 3) +// db := setupDB(t) // -// updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) +// updates := make([]*ethpbv2.LightClientUpdate, 2) // -// for i := 0; i < 3; i++ { -// newSlot := slot.Add(uint64(i * 32)) +// updatePeriod := slotAltair.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) // // update := ðpbv2.LightClientUpdate{ // AttestedHeader: ðpbv2.LightClientHeaderContainer{ // Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ // HeaderAltair: ðpbv2.LightClientHeader{ // Beacon: ðpbv1.BeaconBlockHeader{ -// Slot: newSlot, +// Slot: slotAltair, // ProposerIndex: 1, // ParentRoot: []byte{1, 1, 1}, // StateRoot: []byte{1, 1, 1}, @@ -1193,16 +852,28 @@ package lightclient // AggregatePubkey: nil, // }, // NextSyncCommitteeBranch: nil, -// FinalizedHeader: nil, -// FinalityBranch: nil, +// FinalizedHeader: ðpbv2.LightClientHeaderContainer{ +// Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ +// HeaderAltair: ðpbv2.LightClientHeader{ +// Beacon: ðpbv1.BeaconBlockHeader{ +// Slot: 12, +// ProposerIndex: 1, +// ParentRoot: []byte{1, 1, 1}, +// StateRoot: []byte{1, 1, 1}, +// BodyRoot: []byte{1, 1, 1}, +// }, +// }, +// }, +// }, +// FinalityBranch: nil, // SyncAggregate: ðpbv1.SyncAggregate{ // SyncCommitteeBits: []byte{1, 1, 1}, // SyncCommitteeSignature: []byte{1, 1, 1}, // }, -// SignatureSlot: 7, +// SignatureSlot: slotAltair, // } // -// updates[i] = update +// updates[0] = update // // err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ // Version: version.Altair, @@ -1210,226 +881,280 @@ package lightclient // }) // require.NoError(t, err) // -// updatePeriod++ -// } +// updatePeriod = slotCapella.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) // -// mockChainService := &mock.ChainService{State: st} -// s := &Server{ -// HeadFetcher: mockChainService, -// BeaconDB: db, -// } -// startPeriod := 0 -// url := fmt.Sprintf("http://foo.com/?count=4&start_period=%d", startPeriod) -// request := httptest.NewRequest("GET", url, nil) -// writer := httptest.NewRecorder() -// writer.Body = &bytes.Buffer{} +// update = ðpbv2.LightClientUpdate{ +// AttestedHeader: ðpbv2.LightClientHeaderContainer{ +// Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ +// HeaderCapella: ðpbv2.LightClientHeaderCapella{ +// Beacon: ðpbv1.BeaconBlockHeader{ +// Slot: slotCapella, +// ProposerIndex: 1, +// ParentRoot: []byte{1, 1, 1}, +// StateRoot: []byte{1, 1, 1}, +// BodyRoot: []byte{1, 1, 1}, +// }, +// Execution: &enginev1.ExecutionPayloadHeaderCapella{ +// FeeRecipient: []byte{1, 2, 3}, +// }, +// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, +// }, +// }, +// }, +// NextSyncCommittee: ðpbv2.SyncCommittee{ +// Pubkeys: nil, +// AggregatePubkey: nil, +// }, +// NextSyncCommitteeBranch: nil, +// FinalizedHeader: ðpbv2.LightClientHeaderContainer{ +// Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ +// HeaderCapella: ðpbv2.LightClientHeaderCapella{ +// Beacon: ðpbv1.BeaconBlockHeader{ +// Slot: 12, +// ProposerIndex: 1, +// ParentRoot: []byte{1, 1, 1}, +// StateRoot: []byte{1, 1, 1}, +// BodyRoot: []byte{1, 1, 1}, +// }, +// Execution: &enginev1.ExecutionPayloadHeaderCapella{ +// FeeRecipient: []byte{1, 2, 3}, +// }, +// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, +// }, +// }, +// }, +// FinalityBranch: nil, +// SyncAggregate: ðpbv1.SyncAggregate{ +// SyncCommitteeBits: []byte{1, 1, 1}, +// SyncCommitteeSignature: []byte{1, 1, 1}, +// }, +// SignatureSlot: slotCapella, +// } // -// s.GetLightClientUpdatesByRange(writer, request) +// updates[1] = update // -// require.Equal(t, http.StatusOK, writer.Code) -// var resp structs.LightClientUpdatesByRangeResponse -// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) -// require.NoError(t, err) -// require.Equal(t, 2, len(resp.Updates)) -// for i, update := range updates { -// if i < 2 { -// require.Equal(t, "altair", resp.Updates[i].Version) +// err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ +// Version: version.Capella, +// Data: update, +// }) +// require.NoError(t, err) +// +// mockChainService := &mock.ChainService{State: st} +// s := &Server{ +// HeadFetcher: mockChainService, +// BeaconDB: db, +// } +// startPeriod := 0 +// url := fmt.Sprintf("http://foo.com/?count=100&start_period=%d", startPeriod) +// request := httptest.NewRequest("GET", url, nil) +// writer := httptest.NewRecorder() +// writer.Body = &bytes.Buffer{} +// +// s.GetLightClientUpdatesByRange(writer, request) +// +// require.Equal(t, http.StatusOK, writer.Code) +// var resp structs.LightClientUpdatesByRangeResponse +// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) +// require.NoError(t, err) +// require.Equal(t, 2, len(resp.Updates)) +// for i, update := range updates { +// if i < 1 { +// require.Equal(t, "altair", resp.Updates[i].Version) +// } else { +// require.Equal(t, "capella", resp.Updates[i].Version) +// } // updateJson, err := structs.LightClientUpdateFromConsensus(update) // require.NoError(t, err) // require.DeepEqual(t, updateJson, resp.Updates[i].Data) // } // } -//} // -//func TestLightClientHandler_GetLightClientUpdatesByRangeCountBiggerThanMax(t *testing.T) { -// helpers.ClearCache() -// ctx := context.Background() -// params.SetupTestConfigCleanup(t) -// config := params.BeaconConfig() -// config.AltairForkEpoch = 0 -// config.EpochsPerSyncCommitteePeriod = 1 -// config.MaxRequestLightClientUpdates = 2 -// params.OverrideBeaconConfig(config) -// slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) +// func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleForksCapellaDeneb(t *testing.T) { +// helpers.ClearCache() +// ctx := context.Background() +// params.SetupTestConfigCleanup(t) +// config := params.BeaconConfig() +// config.AltairForkEpoch = 0 +// config.CapellaForkEpoch = 1 +// config.DenebForkEpoch = 2 +// config.EpochsPerSyncCommitteePeriod = 1 +// params.OverrideBeaconConfig(config) +// slotDeneb := primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) +// slotCapella := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) +// +// st, err := util.NewBeaconStateAltair() +// require.NoError(t, err) +// headSlot := slotDeneb.Add(1) +// err = st.SetSlot(headSlot) +// require.NoError(t, err) // -// st, err := util.NewBeaconStateAltair() -// require.NoError(t, err) -// headSlot := slot.Add(65) -// err = st.SetSlot(headSlot) -// require.NoError(t, err) +// db := setupDB(t) // -// db := setupDB(t) +// updates := make([]*ethpbv2.LightClientUpdate, 2) +// +// updatePeriod := slotCapella.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) +// +// update := ðpbv2.LightClientUpdate{ +// AttestedHeader: ðpbv2.LightClientHeaderContainer{ +// Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ +// HeaderCapella: ðpbv2.LightClientHeaderCapella{ +// Beacon: ðpbv1.BeaconBlockHeader{ +// Slot: slotCapella, +// ProposerIndex: 1, +// ParentRoot: []byte{1, 1, 1}, +// StateRoot: []byte{1, 1, 1}, +// BodyRoot: []byte{1, 1, 1}, +// }, +// Execution: &enginev1.ExecutionPayloadHeaderCapella{ +// FeeRecipient: []byte{1, 2, 3}, +// }, +// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, +// }, +// }, +// }, +// NextSyncCommittee: ðpbv2.SyncCommittee{ +// Pubkeys: nil, +// AggregatePubkey: nil, +// }, +// NextSyncCommitteeBranch: nil, +// FinalizedHeader: ðpbv2.LightClientHeaderContainer{ +// Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ +// HeaderCapella: ðpbv2.LightClientHeaderCapella{ +// Beacon: ðpbv1.BeaconBlockHeader{ +// Slot: 12, +// ProposerIndex: 1, +// ParentRoot: []byte{1, 1, 1}, +// StateRoot: []byte{1, 1, 1}, +// BodyRoot: []byte{1, 1, 1}, +// }, +// Execution: &enginev1.ExecutionPayloadHeaderCapella{ +// FeeRecipient: []byte{1, 2, 3}, +// }, +// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, +// }, +// }, +// }, +// FinalityBranch: nil, +// SyncAggregate: ðpbv1.SyncAggregate{ +// SyncCommitteeBits: []byte{1, 1, 1}, +// SyncCommitteeSignature: []byte{1, 1, 1}, +// }, +// SignatureSlot: slotCapella, +// } // -// updates := make([]*ethpbv2.LightClientUpdate, 3) +// updates[0] = update // -// updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) +// err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ +// Version: version.Capella, +// Data: update, +// }) +// require.NoError(t, err) // -// for i := 0; i < 3; i++ { -// newSlot := slot.Add(uint64(i * 32)) +// updatePeriod = slotDeneb.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) // -// update := ðpbv2.LightClientUpdate{ +// update = ðpbv2.LightClientUpdate{ // AttestedHeader: ðpbv2.LightClientHeaderContainer{ -// Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ -// HeaderAltair: ðpbv2.LightClientHeader{ +// Header: ðpbv2.LightClientHeaderContainer_HeaderDeneb{ +// HeaderDeneb: ðpbv2.LightClientHeaderDeneb{ +// Beacon: ðpbv1.BeaconBlockHeader{ +// Slot: slotDeneb, +// ProposerIndex: 1, +// ParentRoot: []byte{1, 1, 1}, +// StateRoot: []byte{1, 1, 1}, +// BodyRoot: []byte{1, 1, 1}, +// }, +// Execution: &enginev1.ExecutionPayloadHeaderDeneb{ +// FeeRecipient: []byte{1, 2, 3}, +// }, +// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, +// }, +// }, +// }, +// NextSyncCommittee: ðpbv2.SyncCommittee{ +// Pubkeys: nil, +// AggregatePubkey: nil, +// }, +// NextSyncCommitteeBranch: nil, +// FinalizedHeader: ðpbv2.LightClientHeaderContainer{ +// Header: ðpbv2.LightClientHeaderContainer_HeaderDeneb{ +// HeaderDeneb: ðpbv2.LightClientHeaderDeneb{ // Beacon: ðpbv1.BeaconBlockHeader{ -// Slot: newSlot, +// Slot: 12, // ProposerIndex: 1, // ParentRoot: []byte{1, 1, 1}, // StateRoot: []byte{1, 1, 1}, // BodyRoot: []byte{1, 1, 1}, // }, +// Execution: &enginev1.ExecutionPayloadHeaderDeneb{ +// FeeRecipient: []byte{1, 2, 3}, +// }, +// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, // }, // }, // }, -// NextSyncCommittee: ðpbv2.SyncCommittee{ -// Pubkeys: nil, -// AggregatePubkey: nil, -// }, -// NextSyncCommitteeBranch: nil, -// FinalizedHeader: nil, -// FinalityBranch: nil, +// FinalityBranch: nil, // SyncAggregate: ðpbv1.SyncAggregate{ // SyncCommitteeBits: []byte{1, 1, 1}, // SyncCommitteeSignature: []byte{1, 1, 1}, // }, -// SignatureSlot: 7, +// SignatureSlot: slotDeneb, // } // -// updates[i] = update +// updates[1] = update +// // err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ -// Version: version.Altair, +// Version: version.Deneb, // Data: update, // }) // require.NoError(t, err) // -// updatePeriod++ -// } -// -// mockChainService := &mock.ChainService{State: st} -// s := &Server{ -// HeadFetcher: mockChainService, -// BeaconDB: db, -// } -// startPeriod := 0 -// url := fmt.Sprintf("http://foo.com/?count=10&start_period=%d", startPeriod) -// request := httptest.NewRequest("GET", url, nil) -// writer := httptest.NewRecorder() -// writer.Body = &bytes.Buffer{} +// mockChainService := &mock.ChainService{State: st} +// s := &Server{ +// HeadFetcher: mockChainService, +// BeaconDB: db, +// } +// startPeriod := 1 +// url := fmt.Sprintf("http://foo.com/?count=100&start_period=%d", startPeriod) +// request := httptest.NewRequest("GET", url, nil) +// writer := httptest.NewRecorder() +// writer.Body = &bytes.Buffer{} // -// s.GetLightClientUpdatesByRange(writer, request) +// s.GetLightClientUpdatesByRange(writer, request) // -// require.Equal(t, http.StatusOK, writer.Code) -// var resp structs.LightClientUpdatesByRangeResponse -// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) -// require.NoError(t, err) -// require.Equal(t, 2, len(resp.Updates)) -// for i, update := range updates { -// if i < 2 { -// require.Equal(t, "altair", resp.Updates[i].Version) +// require.Equal(t, http.StatusOK, writer.Code) +// var resp structs.LightClientUpdatesByRangeResponse +// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) +// require.NoError(t, err) +// require.Equal(t, 2, len(resp.Updates)) +// for i, update := range updates { +// if i < 1 { +// require.Equal(t, "capella", resp.Updates[i].Version) +// } else { +// require.Equal(t, "deneb", resp.Updates[i].Version) +// } // updateJson, err := structs.LightClientUpdateFromConsensus(update) // require.NoError(t, err) // require.DeepEqual(t, updateJson, resp.Updates[i].Data) // } // } -//} -// -//func TestLightClientHandler_GetLightClientUpdatesByRangeStartPeriodBeforeAltair(t *testing.T) { -// helpers.ClearCache() -// ctx := context.Background() -// params.SetupTestConfigCleanup(t) -// config := params.BeaconConfig() -// config.AltairForkEpoch = 1 -// config.EpochsPerSyncCommitteePeriod = 1 -// params.OverrideBeaconConfig(config) -// slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) -// -// st, err := util.NewBeaconStateAltair() -// require.NoError(t, err) -// headSlot := slot.Add(1) -// err = st.SetSlot(headSlot) -// require.NoError(t, err) -// -// db := setupDB(t) -// -// updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) -// -// update := ðpbv2.LightClientUpdate{ -// AttestedHeader: ðpbv2.LightClientHeaderContainer{ -// Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ -// HeaderAltair: ðpbv2.LightClientHeader{ -// Beacon: ðpbv1.BeaconBlockHeader{ -// Slot: slot, -// ProposerIndex: 1, -// ParentRoot: []byte{1, 1, 1}, -// StateRoot: []byte{1, 1, 1}, -// BodyRoot: []byte{1, 1, 1}, -// }, -// }, -// }, -// }, -// NextSyncCommittee: ðpbv2.SyncCommittee{ -// Pubkeys: nil, -// AggregatePubkey: nil, -// }, -// NextSyncCommitteeBranch: nil, -// FinalizedHeader: nil, -// FinalityBranch: nil, -// SyncAggregate: ðpbv1.SyncAggregate{ -// SyncCommitteeBits: []byte{1, 1, 1}, -// SyncCommitteeSignature: []byte{1, 1, 1}, -// }, -// SignatureSlot: 7, -// } -// -// err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ -// Version: version.Altair, -// Data: update, -// }) -// require.NoError(t, err) -// -// mockChainService := &mock.ChainService{State: st} -// s := &Server{ -// HeadFetcher: mockChainService, -// BeaconDB: db, -// } -// startPeriod := 0 -// url := fmt.Sprintf("http://foo.com/?count=2&start_period=%d", startPeriod) -// request := httptest.NewRequest("GET", url, nil) -// writer := httptest.NewRecorder() -// writer.Body = &bytes.Buffer{} -// -// s.GetLightClientUpdatesByRange(writer, request) -// -// require.Equal(t, http.StatusOK, writer.Code) -// var resp structs.LightClientUpdatesByRangeResponse -// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) -// require.NoError(t, err) -// require.Equal(t, 1, len(resp.Updates)) -// -// require.Equal(t, "altair", resp.Updates[0].Version) -// updateJson, err := structs.LightClientUpdateFromConsensus(update) -// require.NoError(t, err) -// require.DeepEqual(t, updateJson, resp.Updates[0].Data) -// -//} -// -//func TestLightClientHandler_GetLightClientUpdatesByRangeMissingUpdates(t *testing.T) { -// helpers.ClearCache() -// ctx := context.Background() -// params.SetupTestConfigCleanup(t) -// config := params.BeaconConfig() -// config.AltairForkEpoch = 0 -// config.EpochsPerSyncCommitteePeriod = 1 -// params.OverrideBeaconConfig(config) -// slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) // -// st, err := util.NewBeaconStateAltair() -// require.NoError(t, err) -// headSlot := slot.Add(65) -// err = st.SetSlot(headSlot) -// require.NoError(t, err) +// func TestLightClientHandler_GetLightClientUpdatesByRangeCountBiggerThanLimit(t *testing.T) { +// helpers.ClearCache() +// ctx := context.Background() +// params.SetupTestConfigCleanup(t) +// config := params.BeaconConfig() +// config.AltairForkEpoch = 0 +// config.EpochsPerSyncCommitteePeriod = 1 +// config.MaxRequestLightClientUpdates = 2 +// params.OverrideBeaconConfig(config) +// slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) +// +// st, err := util.NewBeaconStateAltair() +// require.NoError(t, err) +// headSlot := slot.Add(65) +// err = st.SetSlot(headSlot) +// require.NoError(t, err) // -// t.Run("missing update in the middle", func(t *testing.T) { // db := setupDB(t) // // updates := make([]*ethpbv2.LightClientUpdate, 3) @@ -1437,10 +1162,6 @@ package lightclient // updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) // // for i := 0; i < 3; i++ { -// if i == 1 { // skip this update -// updatePeriod++ -// continue -// } // newSlot := slot.Add(uint64(i * 32)) // // update := ðpbv2.LightClientUpdate{ @@ -1488,7 +1209,7 @@ package lightclient // BeaconDB: db, // } // startPeriod := 0 -// url := fmt.Sprintf("http://foo.com/?count=10&start_period=%d", startPeriod) +// url := fmt.Sprintf("http://foo.com/?count=4&start_period=%d", startPeriod) // request := httptest.NewRequest("GET", url, nil) // writer := httptest.NewRecorder() // writer.Body = &bytes.Buffer{} @@ -1499,14 +1220,34 @@ package lightclient // var resp structs.LightClientUpdatesByRangeResponse // err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) // require.NoError(t, err) -// require.Equal(t, 1, len(resp.Updates)) -// require.Equal(t, "altair", resp.Updates[0].Version) -// updateJson, err := structs.LightClientUpdateFromConsensus(updates[0]) +// require.Equal(t, 2, len(resp.Updates)) +// for i, update := range updates { +// if i < 2 { +// require.Equal(t, "altair", resp.Updates[i].Version) +// updateJson, err := structs.LightClientUpdateFromConsensus(update) +// require.NoError(t, err) +// require.DeepEqual(t, updateJson, resp.Updates[i].Data) +// } +// } +// } +// +// func TestLightClientHandler_GetLightClientUpdatesByRangeCountBiggerThanMax(t *testing.T) { +// helpers.ClearCache() +// ctx := context.Background() +// params.SetupTestConfigCleanup(t) +// config := params.BeaconConfig() +// config.AltairForkEpoch = 0 +// config.EpochsPerSyncCommitteePeriod = 1 +// config.MaxRequestLightClientUpdates = 2 +// params.OverrideBeaconConfig(config) +// slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) +// +// st, err := util.NewBeaconStateAltair() +// require.NoError(t, err) +// headSlot := slot.Add(65) +// err = st.SetSlot(headSlot) // require.NoError(t, err) -// require.DeepEqual(t, updateJson, resp.Updates[0].Data) -// }) // -// t.Run("missing update at the beginning", func(t *testing.T) { // db := setupDB(t) // // updates := make([]*ethpbv2.LightClientUpdate, 3) @@ -1514,11 +1255,7 @@ package lightclient // updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) // // for i := 0; i < 3; i++ { -// if i == 0 { // skip this update -// updatePeriod++ -// continue -// } -// newSlot := slot.Add(uint64(i)) +// newSlot := slot.Add(uint64(i * 32)) // // update := ðpbv2.LightClientUpdate{ // AttestedHeader: ðpbv2.LightClientHeaderContainer{ @@ -1549,7 +1286,6 @@ package lightclient // } // // updates[i] = update -// // err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ // Version: version.Altair, // Data: update, @@ -1576,898 +1312,1152 @@ package lightclient // var resp structs.LightClientUpdatesByRangeResponse // err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) // require.NoError(t, err) -// require.Equal(t, 0, len(resp.Updates)) -// }) +// require.Equal(t, 2, len(resp.Updates)) +// for i, update := range updates { +// if i < 2 { +// require.Equal(t, "altair", resp.Updates[i].Version) +// updateJson, err := structs.LightClientUpdateFromConsensus(update) +// require.NoError(t, err) +// require.DeepEqual(t, updateJson, resp.Updates[i].Data) +// } +// } +// } // -//} +// func TestLightClientHandler_GetLightClientUpdatesByRangeStartPeriodBeforeAltair(t *testing.T) { +// helpers.ClearCache() +// ctx := context.Background() +// params.SetupTestConfigCleanup(t) +// config := params.BeaconConfig() +// config.AltairForkEpoch = 1 +// config.EpochsPerSyncCommitteePeriod = 1 +// params.OverrideBeaconConfig(config) +// slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) +// +// st, err := util.NewBeaconStateAltair() +// require.NoError(t, err) +// headSlot := slot.Add(1) +// err = st.SetSlot(headSlot) +// require.NoError(t, err) // -//// TestLightClientHandler_GetLightClientFinalityUpdate tests +// db := setupDB(t) // -//func TestLightClientHandler_GetLightClientFinalityUpdateAltair(t *testing.T) { -// helpers.ClearCache() -// ctx := context.Background() -// params.SetupTestConfigCleanup(t) -// config := params.BeaconConfig() -// slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) +// updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) // -// attestedState, err := util.NewBeaconStateAltair() -// require.NoError(t, err) -// err = attestedState.SetSlot(slot.Sub(1)) -// require.NoError(t, err) +// update := ðpbv2.LightClientUpdate{ +// AttestedHeader: ðpbv2.LightClientHeaderContainer{ +// Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ +// HeaderAltair: ðpbv2.LightClientHeader{ +// Beacon: ðpbv1.BeaconBlockHeader{ +// Slot: slot, +// ProposerIndex: 1, +// ParentRoot: []byte{1, 1, 1}, +// StateRoot: []byte{1, 1, 1}, +// BodyRoot: []byte{1, 1, 1}, +// }, +// }, +// }, +// }, +// NextSyncCommittee: ðpbv2.SyncCommittee{ +// Pubkeys: nil, +// AggregatePubkey: nil, +// }, +// NextSyncCommitteeBranch: nil, +// FinalizedHeader: nil, +// FinalityBranch: nil, +// SyncAggregate: ðpbv1.SyncAggregate{ +// SyncCommitteeBits: []byte{1, 1, 1}, +// SyncCommitteeSignature: []byte{1, 1, 1}, +// }, +// SignatureSlot: 7, +// } // -// require.NoError(t, attestedState.SetFinalizedCheckpoint(ðpb.Checkpoint{ -// Epoch: config.AltairForkEpoch - 10, -// Root: make([]byte, 32), -// })) +// err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ +// Version: version.Altair, +// Data: update, +// }) +// require.NoError(t, err) // -// parent := util.NewBeaconBlockAltair() -// parent.Block.Slot = slot.Sub(1) +// mockChainService := &mock.ChainService{State: st} +// s := &Server{ +// HeadFetcher: mockChainService, +// BeaconDB: db, +// } +// startPeriod := 0 +// url := fmt.Sprintf("http://foo.com/?count=2&start_period=%d", startPeriod) +// request := httptest.NewRequest("GET", url, nil) +// writer := httptest.NewRecorder() +// writer.Body = &bytes.Buffer{} // -// signedParent, err := blocks.NewSignedBeaconBlock(parent) -// require.NoError(t, err) +// s.GetLightClientUpdatesByRange(writer, request) // -// parentHeader, err := signedParent.Header() -// require.NoError(t, err) -// attestedHeader := parentHeader.Header +// require.Equal(t, http.StatusOK, writer.Code) +// var resp structs.LightClientUpdatesByRangeResponse +// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) +// require.NoError(t, err) +// require.Equal(t, 1, len(resp.Updates)) +// +// require.Equal(t, "altair", resp.Updates[0].Version) +// updateJson, err := structs.LightClientUpdateFromConsensus(update) +// require.NoError(t, err) +// require.DeepEqual(t, updateJson, resp.Updates[0].Data) +// +// } +// +// func TestLightClientHandler_GetLightClientUpdatesByRangeMissingUpdates(t *testing.T) { +// helpers.ClearCache() +// ctx := context.Background() +// params.SetupTestConfigCleanup(t) +// config := params.BeaconConfig() +// config.AltairForkEpoch = 0 +// config.EpochsPerSyncCommitteePeriod = 1 +// params.OverrideBeaconConfig(config) +// slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) +// +// st, err := util.NewBeaconStateAltair() +// require.NoError(t, err) +// headSlot := slot.Add(65) +// err = st.SetSlot(headSlot) +// require.NoError(t, err) +// +// t.Run("missing update in the middle", func(t *testing.T) { +// db := setupDB(t) +// +// updates := make([]*ethpbv2.LightClientUpdate, 3) +// +// updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) +// +// for i := 0; i < 3; i++ { +// if i == 1 { // skip this update +// updatePeriod++ +// continue +// } +// newSlot := slot.Add(uint64(i * 32)) +// +// update := ðpbv2.LightClientUpdate{ +// AttestedHeader: ðpbv2.LightClientHeaderContainer{ +// Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ +// HeaderAltair: ðpbv2.LightClientHeader{ +// Beacon: ðpbv1.BeaconBlockHeader{ +// Slot: newSlot, +// ProposerIndex: 1, +// ParentRoot: []byte{1, 1, 1}, +// StateRoot: []byte{1, 1, 1}, +// BodyRoot: []byte{1, 1, 1}, +// }, +// }, +// }, +// }, +// NextSyncCommittee: ðpbv2.SyncCommittee{ +// Pubkeys: nil, +// AggregatePubkey: nil, +// }, +// NextSyncCommitteeBranch: nil, +// FinalizedHeader: nil, +// FinalityBranch: nil, +// SyncAggregate: ðpbv1.SyncAggregate{ +// SyncCommitteeBits: []byte{1, 1, 1}, +// SyncCommitteeSignature: []byte{1, 1, 1}, +// }, +// SignatureSlot: 7, +// } +// +// updates[i] = update +// +// err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ +// Version: version.Altair, +// Data: update, +// }) +// require.NoError(t, err) +// +// updatePeriod++ +// } +// +// mockChainService := &mock.ChainService{State: st} +// s := &Server{ +// HeadFetcher: mockChainService, +// BeaconDB: db, +// } +// startPeriod := 0 +// url := fmt.Sprintf("http://foo.com/?count=10&start_period=%d", startPeriod) +// request := httptest.NewRequest("GET", url, nil) +// writer := httptest.NewRecorder() +// writer.Body = &bytes.Buffer{} +// +// s.GetLightClientUpdatesByRange(writer, request) +// +// require.Equal(t, http.StatusOK, writer.Code) +// var resp structs.LightClientUpdatesByRangeResponse +// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) +// require.NoError(t, err) +// require.Equal(t, 1, len(resp.Updates)) +// require.Equal(t, "altair", resp.Updates[0].Version) +// updateJson, err := structs.LightClientUpdateFromConsensus(updates[0]) +// require.NoError(t, err) +// require.DeepEqual(t, updateJson, resp.Updates[0].Data) +// }) +// +// t.Run("missing update at the beginning", func(t *testing.T) { +// db := setupDB(t) +// +// updates := make([]*ethpbv2.LightClientUpdate, 3) +// +// updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) +// +// for i := 0; i < 3; i++ { +// if i == 0 { // skip this update +// updatePeriod++ +// continue +// } +// newSlot := slot.Add(uint64(i)) +// +// update := ðpbv2.LightClientUpdate{ +// AttestedHeader: ðpbv2.LightClientHeaderContainer{ +// Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ +// HeaderAltair: ðpbv2.LightClientHeader{ +// Beacon: ðpbv1.BeaconBlockHeader{ +// Slot: newSlot, +// ProposerIndex: 1, +// ParentRoot: []byte{1, 1, 1}, +// StateRoot: []byte{1, 1, 1}, +// BodyRoot: []byte{1, 1, 1}, +// }, +// }, +// }, +// }, +// NextSyncCommittee: ðpbv2.SyncCommittee{ +// Pubkeys: nil, +// AggregatePubkey: nil, +// }, +// NextSyncCommitteeBranch: nil, +// FinalizedHeader: nil, +// FinalityBranch: nil, +// SyncAggregate: ðpbv1.SyncAggregate{ +// SyncCommitteeBits: []byte{1, 1, 1}, +// SyncCommitteeSignature: []byte{1, 1, 1}, +// }, +// SignatureSlot: 7, +// } +// +// updates[i] = update +// +// err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ +// Version: version.Altair, +// Data: update, +// }) +// require.NoError(t, err) +// +// updatePeriod++ +// } +// +// mockChainService := &mock.ChainService{State: st} +// s := &Server{ +// HeadFetcher: mockChainService, +// BeaconDB: db, +// } +// startPeriod := 0 +// url := fmt.Sprintf("http://foo.com/?count=10&start_period=%d", startPeriod) +// request := httptest.NewRequest("GET", url, nil) +// writer := httptest.NewRecorder() +// writer.Body = &bytes.Buffer{} +// +// s.GetLightClientUpdatesByRange(writer, request) +// +// require.Equal(t, http.StatusOK, writer.Code) +// var resp structs.LightClientUpdatesByRangeResponse +// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) +// require.NoError(t, err) +// require.Equal(t, 0, len(resp.Updates)) +// }) +// +// } +// +// // TestLightClientHandler_GetLightClientFinalityUpdate tests +// +// func TestLightClientHandler_GetLightClientFinalityUpdateAltair(t *testing.T) { +// helpers.ClearCache() +// ctx := context.Background() +// params.SetupTestConfigCleanup(t) +// config := params.BeaconConfig() +// slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) +// +// attestedState, err := util.NewBeaconStateAltair() +// require.NoError(t, err) +// err = attestedState.SetSlot(slot.Sub(1)) +// require.NoError(t, err) +// +// require.NoError(t, attestedState.SetFinalizedCheckpoint(ðpb.Checkpoint{ +// Epoch: config.AltairForkEpoch - 10, +// Root: make([]byte, 32), +// })) +// +// parent := util.NewBeaconBlockAltair() +// parent.Block.Slot = slot.Sub(1) +// +// signedParent, err := blocks.NewSignedBeaconBlock(parent) +// require.NoError(t, err) +// +// parentHeader, err := signedParent.Header() +// require.NoError(t, err) +// attestedHeader := parentHeader.Header +// +// err = attestedState.SetLatestBlockHeader(attestedHeader) +// require.NoError(t, err) +// attestedStateRoot, err := attestedState.HashTreeRoot(ctx) +// require.NoError(t, err) +// +// // get a new signed block so the root is updated with the new state root +// parent.Block.StateRoot = attestedStateRoot[:] +// signedParent, err = blocks.NewSignedBeaconBlock(parent) +// require.NoError(t, err) // -// err = attestedState.SetLatestBlockHeader(attestedHeader) -// require.NoError(t, err) -// attestedStateRoot, err := attestedState.HashTreeRoot(ctx) -// require.NoError(t, err) +// st, err := util.NewBeaconStateAltair() +// require.NoError(t, err) +// err = st.SetSlot(slot) +// require.NoError(t, err) // -// // get a new signed block so the root is updated with the new state root -// parent.Block.StateRoot = attestedStateRoot[:] -// signedParent, err = blocks.NewSignedBeaconBlock(parent) -// require.NoError(t, err) +// parentRoot, err := signedParent.Block().HashTreeRoot() +// require.NoError(t, err) // -// st, err := util.NewBeaconStateAltair() -// require.NoError(t, err) -// err = st.SetSlot(slot) -// require.NoError(t, err) +// block := util.NewBeaconBlockAltair() +// block.Block.Slot = slot +// block.Block.ParentRoot = parentRoot[:] // -// parentRoot, err := signedParent.Block().HashTreeRoot() -// require.NoError(t, err) +// for i := uint64(0); i < config.SyncCommitteeSize; i++ { +// block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) +// } // -// block := util.NewBeaconBlockAltair() -// block.Block.Slot = slot -// block.Block.ParentRoot = parentRoot[:] +// signedBlock, err := blocks.NewSignedBeaconBlock(block) +// require.NoError(t, err) // -// for i := uint64(0); i < config.SyncCommitteeSize; i++ { -// block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) -// } +// h, err := signedBlock.Header() +// require.NoError(t, err) // -// signedBlock, err := blocks.NewSignedBeaconBlock(block) -// require.NoError(t, err) +// err = st.SetLatestBlockHeader(h.Header) +// require.NoError(t, err) +// stateRoot, err := st.HashTreeRoot(ctx) +// require.NoError(t, err) // -// h, err := signedBlock.Header() -// require.NoError(t, err) +// // get a new signed block so the root is updated with the new state root +// block.Block.StateRoot = stateRoot[:] +// signedBlock, err = blocks.NewSignedBeaconBlock(block) +// require.NoError(t, err) // -// err = st.SetLatestBlockHeader(h.Header) -// require.NoError(t, err) -// stateRoot, err := st.HashTreeRoot(ctx) -// require.NoError(t, err) +// root, err := block.Block.HashTreeRoot() +// require.NoError(t, err) // -// // get a new signed block so the root is updated with the new state root -// block.Block.StateRoot = stateRoot[:] -// signedBlock, err = blocks.NewSignedBeaconBlock(block) -// require.NoError(t, err) +// mockBlocker := &testutil.MockBlocker{ +// RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ +// parentRoot: signedParent, +// root: signedBlock, +// }, +// SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ +// slot.Sub(1): signedParent, +// slot: signedBlock, +// }, +// } +// mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st, FinalizedRoots: map[[32]byte]bool{ +// root: true, +// }} +// s := &Server{ +// Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ +// slot.Sub(1): attestedState, +// slot: st, +// }}, +// Blocker: mockBlocker, +// HeadFetcher: mockChainService, +// } +// request := httptest.NewRequest("GET", "http://foo.com", nil) +// writer := httptest.NewRecorder() +// writer.Body = &bytes.Buffer{} // -// root, err := block.Block.HashTreeRoot() -// require.NoError(t, err) +// s.GetLightClientFinalityUpdate(writer, request) // -// mockBlocker := &testutil.MockBlocker{ -// RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ -// parentRoot: signedParent, -// root: signedBlock, -// }, -// SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ -// slot.Sub(1): signedParent, -// slot: signedBlock, -// }, -// } -// mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st, FinalizedRoots: map[[32]byte]bool{ -// root: true, -// }} -// s := &Server{ -// Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ -// slot.Sub(1): attestedState, -// slot: st, -// }}, -// Blocker: mockBlocker, -// HeadFetcher: mockChainService, +// require.Equal(t, http.StatusOK, writer.Code) +// var resp *structs.LightClientUpdateResponse +// err = json.Unmarshal(writer.Body.Bytes(), &resp) +// require.NoError(t, err) +// var respHeader structs.LightClientHeader +// err = json.Unmarshal(resp.Data.AttestedHeader, &respHeader) +// require.NoError(t, err) +// require.Equal(t, "altair", resp.Version) +// require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot) +// require.NotNil(t, resp.Data) // } -// request := httptest.NewRequest("GET", "http://foo.com", nil) -// writer := httptest.NewRecorder() -// writer.Body = &bytes.Buffer{} // -// s.GetLightClientFinalityUpdate(writer, request) +// func TestLightClientHandler_GetLightClientFinalityUpdateCapella(t *testing.T) { +// helpers.ClearCache() +// ctx := context.Background() +// params.SetupTestConfigCleanup(t) +// config := params.BeaconConfig() +// slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) // -// require.Equal(t, http.StatusOK, writer.Code) -// var resp *structs.LightClientUpdateResponse -// err = json.Unmarshal(writer.Body.Bytes(), &resp) -// require.NoError(t, err) -// var respHeader structs.LightClientHeader -// err = json.Unmarshal(resp.Data.AttestedHeader, &respHeader) -// require.NoError(t, err) -// require.Equal(t, "altair", resp.Version) -// require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot) -// require.NotNil(t, resp.Data) -//} +// attestedState, err := util.NewBeaconStateCapella() +// require.NoError(t, err) +// err = attestedState.SetSlot(slot.Sub(1)) +// require.NoError(t, err) // -//func TestLightClientHandler_GetLightClientFinalityUpdateCapella(t *testing.T) { -// helpers.ClearCache() -// ctx := context.Background() -// params.SetupTestConfigCleanup(t) -// config := params.BeaconConfig() -// slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) +// require.NoError(t, attestedState.SetFinalizedCheckpoint(ðpb.Checkpoint{ +// Epoch: config.AltairForkEpoch - 10, +// Root: make([]byte, 32), +// })) // -// attestedState, err := util.NewBeaconStateCapella() -// require.NoError(t, err) -// err = attestedState.SetSlot(slot.Sub(1)) -// require.NoError(t, err) +// parent := util.NewBeaconBlockCapella() +// parent.Block.Slot = slot.Sub(1) // -// require.NoError(t, attestedState.SetFinalizedCheckpoint(ðpb.Checkpoint{ -// Epoch: config.AltairForkEpoch - 10, -// Root: make([]byte, 32), -// })) +// signedParent, err := blocks.NewSignedBeaconBlock(parent) +// require.NoError(t, err) // -// parent := util.NewBeaconBlockCapella() -// parent.Block.Slot = slot.Sub(1) +// parentHeader, err := signedParent.Header() +// require.NoError(t, err) +// attestedHeader := parentHeader.Header // -// signedParent, err := blocks.NewSignedBeaconBlock(parent) -// require.NoError(t, err) +// err = attestedState.SetLatestBlockHeader(attestedHeader) +// require.NoError(t, err) +// attestedStateRoot, err := attestedState.HashTreeRoot(ctx) +// require.NoError(t, err) // -// parentHeader, err := signedParent.Header() -// require.NoError(t, err) -// attestedHeader := parentHeader.Header +// // get a new signed block so the root is updated with the new state root +// parent.Block.StateRoot = attestedStateRoot[:] +// signedParent, err = blocks.NewSignedBeaconBlock(parent) +// require.NoError(t, err) // -// err = attestedState.SetLatestBlockHeader(attestedHeader) -// require.NoError(t, err) -// attestedStateRoot, err := attestedState.HashTreeRoot(ctx) -// require.NoError(t, err) +// st, err := util.NewBeaconStateCapella() +// require.NoError(t, err) +// err = st.SetSlot(slot) +// require.NoError(t, err) // -// // get a new signed block so the root is updated with the new state root -// parent.Block.StateRoot = attestedStateRoot[:] -// signedParent, err = blocks.NewSignedBeaconBlock(parent) -// require.NoError(t, err) +// parentRoot, err := signedParent.Block().HashTreeRoot() +// require.NoError(t, err) // -// st, err := util.NewBeaconStateCapella() -// require.NoError(t, err) -// err = st.SetSlot(slot) -// require.NoError(t, err) +// block := util.NewBeaconBlockCapella() +// block.Block.Slot = slot +// block.Block.ParentRoot = parentRoot[:] // -// parentRoot, err := signedParent.Block().HashTreeRoot() -// require.NoError(t, err) +// for i := uint64(0); i < config.SyncCommitteeSize; i++ { +// block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) +// } // -// block := util.NewBeaconBlockCapella() -// block.Block.Slot = slot -// block.Block.ParentRoot = parentRoot[:] +// signedBlock, err := blocks.NewSignedBeaconBlock(block) +// require.NoError(t, err) // -// for i := uint64(0); i < config.SyncCommitteeSize; i++ { -// block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) -// } +// h, err := signedBlock.Header() +// require.NoError(t, err) // -// signedBlock, err := blocks.NewSignedBeaconBlock(block) -// require.NoError(t, err) +// err = st.SetLatestBlockHeader(h.Header) +// require.NoError(t, err) +// stateRoot, err := st.HashTreeRoot(ctx) +// require.NoError(t, err) // -// h, err := signedBlock.Header() -// require.NoError(t, err) +// // get a new signed block so the root is updated with the new state root +// block.Block.StateRoot = stateRoot[:] +// signedBlock, err = blocks.NewSignedBeaconBlock(block) +// require.NoError(t, err) // -// err = st.SetLatestBlockHeader(h.Header) -// require.NoError(t, err) -// stateRoot, err := st.HashTreeRoot(ctx) -// require.NoError(t, err) +// root, err := block.Block.HashTreeRoot() +// require.NoError(t, err) // -// // get a new signed block so the root is updated with the new state root -// block.Block.StateRoot = stateRoot[:] -// signedBlock, err = blocks.NewSignedBeaconBlock(block) -// require.NoError(t, err) +// mockBlocker := &testutil.MockBlocker{ +// RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ +// parentRoot: signedParent, +// root: signedBlock, +// }, +// SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ +// slot.Sub(1): signedParent, +// slot: signedBlock, +// }, +// } +// mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st, FinalizedRoots: map[[32]byte]bool{ +// root: true, +// }} +// s := &Server{ +// Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ +// slot.Sub(1): attestedState, +// slot: st, +// }}, +// Blocker: mockBlocker, +// HeadFetcher: mockChainService, +// } +// request := httptest.NewRequest("GET", "http://foo.com", nil) +// writer := httptest.NewRecorder() +// writer.Body = &bytes.Buffer{} // -// root, err := block.Block.HashTreeRoot() -// require.NoError(t, err) +// s.GetLightClientFinalityUpdate(writer, request) // -// mockBlocker := &testutil.MockBlocker{ -// RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ -// parentRoot: signedParent, -// root: signedBlock, -// }, -// SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ -// slot.Sub(1): signedParent, -// slot: signedBlock, -// }, -// } -// mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st, FinalizedRoots: map[[32]byte]bool{ -// root: true, -// }} -// s := &Server{ -// Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ -// slot.Sub(1): attestedState, -// slot: st, -// }}, -// Blocker: mockBlocker, -// HeadFetcher: mockChainService, +// require.Equal(t, http.StatusOK, writer.Code) +// var resp *structs.LightClientUpdateResponse +// err = json.Unmarshal(writer.Body.Bytes(), &resp) +// require.NoError(t, err) +// var respHeader structs.LightClientHeader +// err = json.Unmarshal(resp.Data.AttestedHeader, &respHeader) +// require.NoError(t, err) +// require.Equal(t, "capella", resp.Version) +// require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot) +// require.NotNil(t, resp.Data) // } -// request := httptest.NewRequest("GET", "http://foo.com", nil) -// writer := httptest.NewRecorder() -// writer.Body = &bytes.Buffer{} // -// s.GetLightClientFinalityUpdate(writer, request) +// func TestLightClientHandler_GetLightClientFinalityUpdateDeneb(t *testing.T) { +// helpers.ClearCache() +// ctx := context.Background() +// params.SetupTestConfigCleanup(t) +// config := params.BeaconConfig() +// slot := primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) // -// require.Equal(t, http.StatusOK, writer.Code) -// var resp *structs.LightClientUpdateResponse -// err = json.Unmarshal(writer.Body.Bytes(), &resp) -// require.NoError(t, err) -// var respHeader structs.LightClientHeader -// err = json.Unmarshal(resp.Data.AttestedHeader, &respHeader) -// require.NoError(t, err) -// require.Equal(t, "capella", resp.Version) -// require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot) -// require.NotNil(t, resp.Data) -//} +// attestedState, err := util.NewBeaconStateDeneb() +// require.NoError(t, err) +// err = attestedState.SetSlot(slot.Sub(1)) +// require.NoError(t, err) // -//func TestLightClientHandler_GetLightClientFinalityUpdateDeneb(t *testing.T) { -// helpers.ClearCache() -// ctx := context.Background() -// params.SetupTestConfigCleanup(t) -// config := params.BeaconConfig() -// slot := primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) +// require.NoError(t, attestedState.SetFinalizedCheckpoint(ðpb.Checkpoint{ +// Epoch: config.AltairForkEpoch - 10, +// Root: make([]byte, 32), +// })) // -// attestedState, err := util.NewBeaconStateDeneb() -// require.NoError(t, err) -// err = attestedState.SetSlot(slot.Sub(1)) -// require.NoError(t, err) +// parent := util.NewBeaconBlockDeneb() +// parent.Block.Slot = slot.Sub(1) // -// require.NoError(t, attestedState.SetFinalizedCheckpoint(ðpb.Checkpoint{ -// Epoch: config.AltairForkEpoch - 10, -// Root: make([]byte, 32), -// })) +// signedParent, err := blocks.NewSignedBeaconBlock(parent) +// require.NoError(t, err) // -// parent := util.NewBeaconBlockDeneb() -// parent.Block.Slot = slot.Sub(1) +// parentHeader, err := signedParent.Header() +// require.NoError(t, err) +// attestedHeader := parentHeader.Header // -// signedParent, err := blocks.NewSignedBeaconBlock(parent) -// require.NoError(t, err) +// err = attestedState.SetLatestBlockHeader(attestedHeader) +// require.NoError(t, err) +// attestedStateRoot, err := attestedState.HashTreeRoot(ctx) +// require.NoError(t, err) // -// parentHeader, err := signedParent.Header() -// require.NoError(t, err) -// attestedHeader := parentHeader.Header +// // get a new signed block so the root is updated with the new state root +// parent.Block.StateRoot = attestedStateRoot[:] +// signedParent, err = blocks.NewSignedBeaconBlock(parent) +// require.NoError(t, err) // -// err = attestedState.SetLatestBlockHeader(attestedHeader) -// require.NoError(t, err) -// attestedStateRoot, err := attestedState.HashTreeRoot(ctx) -// require.NoError(t, err) +// st, err := util.NewBeaconStateDeneb() +// require.NoError(t, err) +// err = st.SetSlot(slot) +// require.NoError(t, err) // -// // get a new signed block so the root is updated with the new state root -// parent.Block.StateRoot = attestedStateRoot[:] -// signedParent, err = blocks.NewSignedBeaconBlock(parent) -// require.NoError(t, err) +// parentRoot, err := signedParent.Block().HashTreeRoot() +// require.NoError(t, err) // -// st, err := util.NewBeaconStateDeneb() -// require.NoError(t, err) -// err = st.SetSlot(slot) -// require.NoError(t, err) +// block := util.NewBeaconBlockDeneb() +// block.Block.Slot = slot +// block.Block.ParentRoot = parentRoot[:] // -// parentRoot, err := signedParent.Block().HashTreeRoot() -// require.NoError(t, err) +// for i := uint64(0); i < config.SyncCommitteeSize; i++ { +// block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) +// } // -// block := util.NewBeaconBlockDeneb() -// block.Block.Slot = slot -// block.Block.ParentRoot = parentRoot[:] +// signedBlock, err := blocks.NewSignedBeaconBlock(block) +// require.NoError(t, err) // -// for i := uint64(0); i < config.SyncCommitteeSize; i++ { -// block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) -// } +// h, err := signedBlock.Header() +// require.NoError(t, err) // -// signedBlock, err := blocks.NewSignedBeaconBlock(block) -// require.NoError(t, err) +// err = st.SetLatestBlockHeader(h.Header) +// require.NoError(t, err) +// stateRoot, err := st.HashTreeRoot(ctx) +// require.NoError(t, err) // -// h, err := signedBlock.Header() -// require.NoError(t, err) +// // get a new signed block so the root is updated with the new state root +// block.Block.StateRoot = stateRoot[:] +// signedBlock, err = blocks.NewSignedBeaconBlock(block) +// require.NoError(t, err) // -// err = st.SetLatestBlockHeader(h.Header) -// require.NoError(t, err) -// stateRoot, err := st.HashTreeRoot(ctx) -// require.NoError(t, err) +// root, err := block.Block.HashTreeRoot() +// require.NoError(t, err) // -// // get a new signed block so the root is updated with the new state root -// block.Block.StateRoot = stateRoot[:] -// signedBlock, err = blocks.NewSignedBeaconBlock(block) -// require.NoError(t, err) +// mockBlocker := &testutil.MockBlocker{ +// RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ +// parentRoot: signedParent, +// root: signedBlock, +// }, +// SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ +// slot.Sub(1): signedParent, +// slot: signedBlock, +// }, +// } +// mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st, FinalizedRoots: map[[32]byte]bool{ +// root: true, +// }} +// s := &Server{ +// Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ +// slot.Sub(1): attestedState, +// slot: st, +// }}, +// Blocker: mockBlocker, +// HeadFetcher: mockChainService, +// } +// request := httptest.NewRequest("GET", "http://foo.com", nil) +// writer := httptest.NewRecorder() +// writer.Body = &bytes.Buffer{} // -// root, err := block.Block.HashTreeRoot() -// require.NoError(t, err) +// s.GetLightClientFinalityUpdate(writer, request) // -// mockBlocker := &testutil.MockBlocker{ -// RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ -// parentRoot: signedParent, -// root: signedBlock, -// }, -// SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ -// slot.Sub(1): signedParent, -// slot: signedBlock, -// }, -// } -// mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st, FinalizedRoots: map[[32]byte]bool{ -// root: true, -// }} -// s := &Server{ -// Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ -// slot.Sub(1): attestedState, -// slot: st, -// }}, -// Blocker: mockBlocker, -// HeadFetcher: mockChainService, +// require.Equal(t, http.StatusOK, writer.Code) +// var resp *structs.LightClientUpdateResponse +// err = json.Unmarshal(writer.Body.Bytes(), &resp) +// require.NoError(t, err) +// var respHeader structs.LightClientHeaderDeneb +// err = json.Unmarshal(resp.Data.AttestedHeader, &respHeader) +// require.NoError(t, err) +// require.Equal(t, "deneb", resp.Version) +// require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot) +// require.NotNil(t, resp.Data) // } -// request := httptest.NewRequest("GET", "http://foo.com", nil) -// writer := httptest.NewRecorder() -// writer.Body = &bytes.Buffer{} -// -// s.GetLightClientFinalityUpdate(writer, request) -// -// require.Equal(t, http.StatusOK, writer.Code) -// var resp *structs.LightClientUpdateResponse -// err = json.Unmarshal(writer.Body.Bytes(), &resp) -// require.NoError(t, err) -// var respHeader structs.LightClientHeaderDeneb -// err = json.Unmarshal(resp.Data.AttestedHeader, &respHeader) -// require.NoError(t, err) -// require.Equal(t, "deneb", resp.Version) -// require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot) -// require.NotNil(t, resp.Data) -//} // -//func TestLightClientHandler_GetLightClientOptimisticUpdateAltair(t *testing.T) { -// helpers.ClearCache() -// ctx := context.Background() -// params.SetupTestConfigCleanup(t) -// config := params.BeaconConfig() -// slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) +// func TestLightClientHandler_GetLightClientOptimisticUpdateAltair(t *testing.T) { +// helpers.ClearCache() +// ctx := context.Background() +// params.SetupTestConfigCleanup(t) +// config := params.BeaconConfig() +// slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) // -// attestedState, err := util.NewBeaconStateAltair() -// require.NoError(t, err) -// err = attestedState.SetSlot(slot.Sub(1)) -// require.NoError(t, err) +// attestedState, err := util.NewBeaconStateAltair() +// require.NoError(t, err) +// err = attestedState.SetSlot(slot.Sub(1)) +// require.NoError(t, err) // -// require.NoError(t, attestedState.SetFinalizedCheckpoint(ðpb.Checkpoint{ -// Epoch: config.AltairForkEpoch - 10, -// Root: make([]byte, 32), -// })) +// require.NoError(t, attestedState.SetFinalizedCheckpoint(ðpb.Checkpoint{ +// Epoch: config.AltairForkEpoch - 10, +// Root: make([]byte, 32), +// })) // -// parent := util.NewBeaconBlockAltair() -// parent.Block.Slot = slot.Sub(1) +// parent := util.NewBeaconBlockAltair() +// parent.Block.Slot = slot.Sub(1) // -// signedParent, err := blocks.NewSignedBeaconBlock(parent) -// require.NoError(t, err) +// signedParent, err := blocks.NewSignedBeaconBlock(parent) +// require.NoError(t, err) // -// parentHeader, err := signedParent.Header() -// require.NoError(t, err) -// attestedHeader := parentHeader.Header +// parentHeader, err := signedParent.Header() +// require.NoError(t, err) +// attestedHeader := parentHeader.Header // -// err = attestedState.SetLatestBlockHeader(attestedHeader) -// require.NoError(t, err) -// attestedStateRoot, err := attestedState.HashTreeRoot(ctx) -// require.NoError(t, err) +// err = attestedState.SetLatestBlockHeader(attestedHeader) +// require.NoError(t, err) +// attestedStateRoot, err := attestedState.HashTreeRoot(ctx) +// require.NoError(t, err) // -// // get a new signed block so the root is updated with the new state root -// parent.Block.StateRoot = attestedStateRoot[:] -// signedParent, err = blocks.NewSignedBeaconBlock(parent) -// require.NoError(t, err) +// // get a new signed block so the root is updated with the new state root +// parent.Block.StateRoot = attestedStateRoot[:] +// signedParent, err = blocks.NewSignedBeaconBlock(parent) +// require.NoError(t, err) // -// st, err := util.NewBeaconStateAltair() -// require.NoError(t, err) -// err = st.SetSlot(slot) -// require.NoError(t, err) +// st, err := util.NewBeaconStateAltair() +// require.NoError(t, err) +// err = st.SetSlot(slot) +// require.NoError(t, err) // -// parentRoot, err := signedParent.Block().HashTreeRoot() -// require.NoError(t, err) +// parentRoot, err := signedParent.Block().HashTreeRoot() +// require.NoError(t, err) // -// block := util.NewBeaconBlockAltair() -// block.Block.Slot = slot -// block.Block.ParentRoot = parentRoot[:] +// block := util.NewBeaconBlockAltair() +// block.Block.Slot = slot +// block.Block.ParentRoot = parentRoot[:] // -// for i := uint64(0); i < config.SyncCommitteeSize; i++ { -// block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) -// } +// for i := uint64(0); i < config.SyncCommitteeSize; i++ { +// block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) +// } // -// signedBlock, err := blocks.NewSignedBeaconBlock(block) -// require.NoError(t, err) +// signedBlock, err := blocks.NewSignedBeaconBlock(block) +// require.NoError(t, err) // -// h, err := signedBlock.Header() -// require.NoError(t, err) +// h, err := signedBlock.Header() +// require.NoError(t, err) // -// err = st.SetLatestBlockHeader(h.Header) -// require.NoError(t, err) -// stateRoot, err := st.HashTreeRoot(ctx) -// require.NoError(t, err) +// err = st.SetLatestBlockHeader(h.Header) +// require.NoError(t, err) +// stateRoot, err := st.HashTreeRoot(ctx) +// require.NoError(t, err) // -// // get a new signed block so the root is updated with the new state root -// block.Block.StateRoot = stateRoot[:] -// signedBlock, err = blocks.NewSignedBeaconBlock(block) -// require.NoError(t, err) +// // get a new signed block so the root is updated with the new state root +// block.Block.StateRoot = stateRoot[:] +// signedBlock, err = blocks.NewSignedBeaconBlock(block) +// require.NoError(t, err) // -// root, err := block.Block.HashTreeRoot() -// require.NoError(t, err) +// root, err := block.Block.HashTreeRoot() +// require.NoError(t, err) // -// mockBlocker := &testutil.MockBlocker{ -// RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ -// parentRoot: signedParent, -// root: signedBlock, -// }, -// SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ -// slot.Sub(1): signedParent, -// slot: signedBlock, -// }, -// } -// mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st, FinalizedRoots: map[[32]byte]bool{ -// root: true, -// }} -// s := &Server{ -// Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ -// slot.Sub(1): attestedState, -// slot: st, -// }}, -// Blocker: mockBlocker, -// HeadFetcher: mockChainService, -// } -// request := httptest.NewRequest("GET", "http://foo.com", nil) -// writer := httptest.NewRecorder() -// writer.Body = &bytes.Buffer{} +// mockBlocker := &testutil.MockBlocker{ +// RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ +// parentRoot: signedParent, +// root: signedBlock, +// }, +// SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ +// slot.Sub(1): signedParent, +// slot: signedBlock, +// }, +// } +// mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st, FinalizedRoots: map[[32]byte]bool{ +// root: true, +// }} +// s := &Server{ +// Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ +// slot.Sub(1): attestedState, +// slot: st, +// }}, +// Blocker: mockBlocker, +// HeadFetcher: mockChainService, +// } +// request := httptest.NewRequest("GET", "http://foo.com", nil) +// writer := httptest.NewRecorder() +// writer.Body = &bytes.Buffer{} // -// s.GetLightClientOptimisticUpdate(writer, request) +// s.GetLightClientOptimisticUpdate(writer, request) // -// require.Equal(t, http.StatusOK, writer.Code) -// var resp *structs.LightClientUpdateResponse -// err = json.Unmarshal(writer.Body.Bytes(), &resp) -// require.NoError(t, err) -// var respHeader structs.LightClientHeader -// err = json.Unmarshal(resp.Data.AttestedHeader, &respHeader) -// require.NoError(t, err) -// require.Equal(t, "altair", resp.Version) -// require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot) -// require.NotNil(t, resp.Data) -//} +// require.Equal(t, http.StatusOK, writer.Code) +// var resp *structs.LightClientUpdateResponse +// err = json.Unmarshal(writer.Body.Bytes(), &resp) +// require.NoError(t, err) +// var respHeader structs.LightClientHeader +// err = json.Unmarshal(resp.Data.AttestedHeader, &respHeader) +// require.NoError(t, err) +// require.Equal(t, "altair", resp.Version) +// require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot) +// require.NotNil(t, resp.Data) +// } // -//func TestLightClientHandler_GetLightClientOptimisticUpdateCapella(t *testing.T) { -// helpers.ClearCache() -// ctx := context.Background() -// params.SetupTestConfigCleanup(t) -// config := params.BeaconConfig() -// slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) +// func TestLightClientHandler_GetLightClientOptimisticUpdateCapella(t *testing.T) { +// helpers.ClearCache() +// ctx := context.Background() +// params.SetupTestConfigCleanup(t) +// config := params.BeaconConfig() +// slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) // -// attestedState, err := util.NewBeaconStateCapella() -// require.NoError(t, err) -// err = attestedState.SetSlot(slot.Sub(1)) -// require.NoError(t, err) +// attestedState, err := util.NewBeaconStateCapella() +// require.NoError(t, err) +// err = attestedState.SetSlot(slot.Sub(1)) +// require.NoError(t, err) // -// require.NoError(t, attestedState.SetFinalizedCheckpoint(ðpb.Checkpoint{ -// Epoch: config.AltairForkEpoch - 10, -// Root: make([]byte, 32), -// })) +// require.NoError(t, attestedState.SetFinalizedCheckpoint(ðpb.Checkpoint{ +// Epoch: config.AltairForkEpoch - 10, +// Root: make([]byte, 32), +// })) // -// parent := util.NewBeaconBlockCapella() -// parent.Block.Slot = slot.Sub(1) +// parent := util.NewBeaconBlockCapella() +// parent.Block.Slot = slot.Sub(1) // -// signedParent, err := blocks.NewSignedBeaconBlock(parent) -// require.NoError(t, err) +// signedParent, err := blocks.NewSignedBeaconBlock(parent) +// require.NoError(t, err) // -// parentHeader, err := signedParent.Header() -// require.NoError(t, err) -// attestedHeader := parentHeader.Header +// parentHeader, err := signedParent.Header() +// require.NoError(t, err) +// attestedHeader := parentHeader.Header // -// err = attestedState.SetLatestBlockHeader(attestedHeader) -// require.NoError(t, err) -// attestedStateRoot, err := attestedState.HashTreeRoot(ctx) -// require.NoError(t, err) +// err = attestedState.SetLatestBlockHeader(attestedHeader) +// require.NoError(t, err) +// attestedStateRoot, err := attestedState.HashTreeRoot(ctx) +// require.NoError(t, err) // -// // get a new signed block so the root is updated with the new state root -// parent.Block.StateRoot = attestedStateRoot[:] -// signedParent, err = blocks.NewSignedBeaconBlock(parent) -// require.NoError(t, err) +// // get a new signed block so the root is updated with the new state root +// parent.Block.StateRoot = attestedStateRoot[:] +// signedParent, err = blocks.NewSignedBeaconBlock(parent) +// require.NoError(t, err) // -// st, err := util.NewBeaconStateCapella() -// require.NoError(t, err) -// err = st.SetSlot(slot) -// require.NoError(t, err) +// st, err := util.NewBeaconStateCapella() +// require.NoError(t, err) +// err = st.SetSlot(slot) +// require.NoError(t, err) // -// parentRoot, err := signedParent.Block().HashTreeRoot() -// require.NoError(t, err) +// parentRoot, err := signedParent.Block().HashTreeRoot() +// require.NoError(t, err) // -// block := util.NewBeaconBlockCapella() -// block.Block.Slot = slot -// block.Block.ParentRoot = parentRoot[:] +// block := util.NewBeaconBlockCapella() +// block.Block.Slot = slot +// block.Block.ParentRoot = parentRoot[:] // -// for i := uint64(0); i < config.SyncCommitteeSize; i++ { -// block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) -// } +// for i := uint64(0); i < config.SyncCommitteeSize; i++ { +// block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) +// } // -// signedBlock, err := blocks.NewSignedBeaconBlock(block) -// require.NoError(t, err) +// signedBlock, err := blocks.NewSignedBeaconBlock(block) +// require.NoError(t, err) // -// h, err := signedBlock.Header() -// require.NoError(t, err) +// h, err := signedBlock.Header() +// require.NoError(t, err) // -// err = st.SetLatestBlockHeader(h.Header) -// require.NoError(t, err) -// stateRoot, err := st.HashTreeRoot(ctx) -// require.NoError(t, err) +// err = st.SetLatestBlockHeader(h.Header) +// require.NoError(t, err) +// stateRoot, err := st.HashTreeRoot(ctx) +// require.NoError(t, err) // -// // get a new signed block so the root is updated with the new state root -// block.Block.StateRoot = stateRoot[:] -// signedBlock, err = blocks.NewSignedBeaconBlock(block) -// require.NoError(t, err) +// // get a new signed block so the root is updated with the new state root +// block.Block.StateRoot = stateRoot[:] +// signedBlock, err = blocks.NewSignedBeaconBlock(block) +// require.NoError(t, err) // -// root, err := block.Block.HashTreeRoot() -// require.NoError(t, err) +// root, err := block.Block.HashTreeRoot() +// require.NoError(t, err) // -// mockBlocker := &testutil.MockBlocker{ -// RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ -// parentRoot: signedParent, -// root: signedBlock, -// }, -// SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ -// slot.Sub(1): signedParent, -// slot: signedBlock, -// }, -// } -// mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st, FinalizedRoots: map[[32]byte]bool{ -// root: true, -// }} -// s := &Server{ -// Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ -// slot.Sub(1): attestedState, -// slot: st, -// }}, -// Blocker: mockBlocker, -// HeadFetcher: mockChainService, +// mockBlocker := &testutil.MockBlocker{ +// RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ +// parentRoot: signedParent, +// root: signedBlock, +// }, +// SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ +// slot.Sub(1): signedParent, +// slot: signedBlock, +// }, +// } +// mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st, FinalizedRoots: map[[32]byte]bool{ +// root: true, +// }} +// s := &Server{ +// Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ +// slot.Sub(1): attestedState, +// slot: st, +// }}, +// Blocker: mockBlocker, +// HeadFetcher: mockChainService, +// } +// request := httptest.NewRequest("GET", "http://foo.com", nil) +// writer := httptest.NewRecorder() +// writer.Body = &bytes.Buffer{} +// +// s.GetLightClientOptimisticUpdate(writer, request) +// +// require.Equal(t, http.StatusOK, writer.Code) +// var resp *structs.LightClientUpdateResponse +// err = json.Unmarshal(writer.Body.Bytes(), &resp) +// require.NoError(t, err) +// var respHeader structs.LightClientHeaderCapella +// err = json.Unmarshal(resp.Data.AttestedHeader, &respHeader) +// require.NoError(t, err) +// require.Equal(t, "capella", resp.Version) +// require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot) +// require.NotNil(t, resp.Data) // } -// request := httptest.NewRequest("GET", "http://foo.com", nil) -// writer := httptest.NewRecorder() -// writer.Body = &bytes.Buffer{} // -// s.GetLightClientOptimisticUpdate(writer, request) +// func TestLightClientHandler_GetLightClientOptimisticUpdateDeneb(t *testing.T) { +// helpers.ClearCache() +// ctx := context.Background() +// params.SetupTestConfigCleanup(t) +// config := params.BeaconConfig() +// slot := primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) // -// require.Equal(t, http.StatusOK, writer.Code) -// var resp *structs.LightClientUpdateResponse -// err = json.Unmarshal(writer.Body.Bytes(), &resp) -// require.NoError(t, err) -// var respHeader structs.LightClientHeaderCapella -// err = json.Unmarshal(resp.Data.AttestedHeader, &respHeader) -// require.NoError(t, err) -// require.Equal(t, "capella", resp.Version) -// require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot) -// require.NotNil(t, resp.Data) -//} +// attestedState, err := util.NewBeaconStateDeneb() +// require.NoError(t, err) +// err = attestedState.SetSlot(slot.Sub(1)) +// require.NoError(t, err) // -//func TestLightClientHandler_GetLightClientOptimisticUpdateDeneb(t *testing.T) { -// helpers.ClearCache() -// ctx := context.Background() -// params.SetupTestConfigCleanup(t) -// config := params.BeaconConfig() -// slot := primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) +// require.NoError(t, attestedState.SetFinalizedCheckpoint(ðpb.Checkpoint{ +// Epoch: config.AltairForkEpoch - 10, +// Root: make([]byte, 32), +// })) // -// attestedState, err := util.NewBeaconStateDeneb() -// require.NoError(t, err) -// err = attestedState.SetSlot(slot.Sub(1)) -// require.NoError(t, err) +// parent := util.NewBeaconBlockDeneb() +// parent.Block.Slot = slot.Sub(1) // -// require.NoError(t, attestedState.SetFinalizedCheckpoint(ðpb.Checkpoint{ -// Epoch: config.AltairForkEpoch - 10, -// Root: make([]byte, 32), -// })) +// signedParent, err := blocks.NewSignedBeaconBlock(parent) +// require.NoError(t, err) // -// parent := util.NewBeaconBlockDeneb() -// parent.Block.Slot = slot.Sub(1) +// parentHeader, err := signedParent.Header() +// require.NoError(t, err) +// attestedHeader := parentHeader.Header // -// signedParent, err := blocks.NewSignedBeaconBlock(parent) -// require.NoError(t, err) +// err = attestedState.SetLatestBlockHeader(attestedHeader) +// require.NoError(t, err) +// attestedStateRoot, err := attestedState.HashTreeRoot(ctx) +// require.NoError(t, err) // -// parentHeader, err := signedParent.Header() -// require.NoError(t, err) -// attestedHeader := parentHeader.Header +// // get a new signed block so the root is updated with the new state root +// parent.Block.StateRoot = attestedStateRoot[:] +// signedParent, err = blocks.NewSignedBeaconBlock(parent) +// require.NoError(t, err) // -// err = attestedState.SetLatestBlockHeader(attestedHeader) -// require.NoError(t, err) -// attestedStateRoot, err := attestedState.HashTreeRoot(ctx) -// require.NoError(t, err) +// st, err := util.NewBeaconStateDeneb() +// require.NoError(t, err) +// err = st.SetSlot(slot) +// require.NoError(t, err) // -// // get a new signed block so the root is updated with the new state root -// parent.Block.StateRoot = attestedStateRoot[:] -// signedParent, err = blocks.NewSignedBeaconBlock(parent) -// require.NoError(t, err) +// parentRoot, err := signedParent.Block().HashTreeRoot() +// require.NoError(t, err) // -// st, err := util.NewBeaconStateDeneb() -// require.NoError(t, err) -// err = st.SetSlot(slot) -// require.NoError(t, err) +// block := util.NewBeaconBlockDeneb() +// block.Block.Slot = slot +// block.Block.ParentRoot = parentRoot[:] // -// parentRoot, err := signedParent.Block().HashTreeRoot() -// require.NoError(t, err) +// for i := uint64(0); i < config.SyncCommitteeSize; i++ { +// block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) +// } // -// block := util.NewBeaconBlockDeneb() -// block.Block.Slot = slot -// block.Block.ParentRoot = parentRoot[:] +// signedBlock, err := blocks.NewSignedBeaconBlock(block) +// require.NoError(t, err) // -// for i := uint64(0); i < config.SyncCommitteeSize; i++ { -// block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) -// } +// h, err := signedBlock.Header() +// require.NoError(t, err) // -// signedBlock, err := blocks.NewSignedBeaconBlock(block) -// require.NoError(t, err) +// err = st.SetLatestBlockHeader(h.Header) +// require.NoError(t, err) +// stateRoot, err := st.HashTreeRoot(ctx) +// require.NoError(t, err) // -// h, err := signedBlock.Header() -// require.NoError(t, err) +// // get a new signed block so the root is updated with the new state root +// block.Block.StateRoot = stateRoot[:] +// signedBlock, err = blocks.NewSignedBeaconBlock(block) +// require.NoError(t, err) // -// err = st.SetLatestBlockHeader(h.Header) -// require.NoError(t, err) -// stateRoot, err := st.HashTreeRoot(ctx) -// require.NoError(t, err) +// root, err := block.Block.HashTreeRoot() +// require.NoError(t, err) // -// // get a new signed block so the root is updated with the new state root -// block.Block.StateRoot = stateRoot[:] -// signedBlock, err = blocks.NewSignedBeaconBlock(block) -// require.NoError(t, err) +// mockBlocker := &testutil.MockBlocker{ +// RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ +// parentRoot: signedParent, +// root: signedBlock, +// }, +// SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ +// slot.Sub(1): signedParent, +// slot: signedBlock, +// }, +// } +// mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st, FinalizedRoots: map[[32]byte]bool{ +// root: true, +// }} +// s := &Server{ +// Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ +// slot.Sub(1): attestedState, +// slot: st, +// }}, +// Blocker: mockBlocker, +// HeadFetcher: mockChainService, +// } +// request := httptest.NewRequest("GET", "http://foo.com", nil) +// writer := httptest.NewRecorder() +// writer.Body = &bytes.Buffer{} // -// root, err := block.Block.HashTreeRoot() -// require.NoError(t, err) +// s.GetLightClientOptimisticUpdate(writer, request) // -// mockBlocker := &testutil.MockBlocker{ -// RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ -// parentRoot: signedParent, -// root: signedBlock, -// }, -// SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ -// slot.Sub(1): signedParent, -// slot: signedBlock, -// }, -// } -// mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st, FinalizedRoots: map[[32]byte]bool{ -// root: true, -// }} -// s := &Server{ -// Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ -// slot.Sub(1): attestedState, -// slot: st, -// }}, -// Blocker: mockBlocker, -// HeadFetcher: mockChainService, +// require.Equal(t, http.StatusOK, writer.Code) +// var resp *structs.LightClientUpdateResponse +// err = json.Unmarshal(writer.Body.Bytes(), &resp) +// require.NoError(t, err) +// var respHeader structs.LightClientHeaderDeneb +// err = json.Unmarshal(resp.Data.AttestedHeader, &respHeader) +// require.NoError(t, err) +// require.Equal(t, "deneb", resp.Version) +// require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot) +// require.NotNil(t, resp.Data) // } -// request := httptest.NewRequest("GET", "http://foo.com", nil) -// writer := httptest.NewRecorder() -// writer.Body = &bytes.Buffer{} // -// s.GetLightClientOptimisticUpdate(writer, request) +// func TestLightClientHandler_GetLightClientEventBlock(t *testing.T) { +// helpers.ClearCache() +// ctx := context.Background() +// params.SetupTestConfigCleanup(t) +// config := params.BeaconConfig() +// slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) // -// require.Equal(t, http.StatusOK, writer.Code) -// var resp *structs.LightClientUpdateResponse -// err = json.Unmarshal(writer.Body.Bytes(), &resp) -// require.NoError(t, err) -// var respHeader structs.LightClientHeaderDeneb -// err = json.Unmarshal(resp.Data.AttestedHeader, &respHeader) -// require.NoError(t, err) -// require.Equal(t, "deneb", resp.Version) -// require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot) -// require.NotNil(t, resp.Data) -//} +// attestedState, err := util.NewBeaconStateCapella() +// require.NoError(t, err) +// err = attestedState.SetSlot(slot.Sub(1)) +// require.NoError(t, err) // -//func TestLightClientHandler_GetLightClientEventBlock(t *testing.T) { -// helpers.ClearCache() -// ctx := context.Background() -// params.SetupTestConfigCleanup(t) -// config := params.BeaconConfig() -// slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) +// require.NoError(t, attestedState.SetFinalizedCheckpoint(ðpb.Checkpoint{ +// Epoch: config.AltairForkEpoch - 10, +// Root: make([]byte, 32), +// })) // -// attestedState, err := util.NewBeaconStateCapella() -// require.NoError(t, err) -// err = attestedState.SetSlot(slot.Sub(1)) -// require.NoError(t, err) +// parent := util.NewBeaconBlockCapella() +// parent.Block.Slot = slot.Sub(1) // -// require.NoError(t, attestedState.SetFinalizedCheckpoint(ðpb.Checkpoint{ -// Epoch: config.AltairForkEpoch - 10, -// Root: make([]byte, 32), -// })) +// signedParent, err := blocks.NewSignedBeaconBlock(parent) +// require.NoError(t, err) // -// parent := util.NewBeaconBlockCapella() -// parent.Block.Slot = slot.Sub(1) +// parentHeader, err := signedParent.Header() +// require.NoError(t, err) +// attestedHeader := parentHeader.Header // -// signedParent, err := blocks.NewSignedBeaconBlock(parent) -// require.NoError(t, err) +// err = attestedState.SetLatestBlockHeader(attestedHeader) +// require.NoError(t, err) +// attestedStateRoot, err := attestedState.HashTreeRoot(ctx) +// require.NoError(t, err) // -// parentHeader, err := signedParent.Header() -// require.NoError(t, err) -// attestedHeader := parentHeader.Header +// // get a new signed block so the root is updated with the new state root +// parent.Block.StateRoot = attestedStateRoot[:] +// signedParent, err = blocks.NewSignedBeaconBlock(parent) +// require.NoError(t, err) // -// err = attestedState.SetLatestBlockHeader(attestedHeader) -// require.NoError(t, err) -// attestedStateRoot, err := attestedState.HashTreeRoot(ctx) -// require.NoError(t, err) +// st, err := util.NewBeaconStateCapella() +// require.NoError(t, err) +// err = st.SetSlot(slot) +// require.NoError(t, err) // -// // get a new signed block so the root is updated with the new state root -// parent.Block.StateRoot = attestedStateRoot[:] -// signedParent, err = blocks.NewSignedBeaconBlock(parent) -// require.NoError(t, err) +// parentRoot, err := signedParent.Block().HashTreeRoot() +// require.NoError(t, err) // -// st, err := util.NewBeaconStateCapella() -// require.NoError(t, err) -// err = st.SetSlot(slot) -// require.NoError(t, err) +// block := util.NewBeaconBlockCapella() +// block.Block.Slot = slot +// block.Block.ParentRoot = parentRoot[:] // -// parentRoot, err := signedParent.Block().HashTreeRoot() -// require.NoError(t, err) +// for i := uint64(0); i < config.SyncCommitteeSize; i++ { +// block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) +// } // -// block := util.NewBeaconBlockCapella() -// block.Block.Slot = slot -// block.Block.ParentRoot = parentRoot[:] +// signedBlock, err := blocks.NewSignedBeaconBlock(block) +// require.NoError(t, err) // -// for i := uint64(0); i < config.SyncCommitteeSize; i++ { -// block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) -// } +// h, err := signedBlock.Header() +// require.NoError(t, err) // -// signedBlock, err := blocks.NewSignedBeaconBlock(block) -// require.NoError(t, err) +// err = st.SetLatestBlockHeader(h.Header) +// require.NoError(t, err) +// stateRoot, err := st.HashTreeRoot(ctx) +// require.NoError(t, err) // -// h, err := signedBlock.Header() -// require.NoError(t, err) +// // get a new signed block so the root is updated with the new state root +// block.Block.StateRoot = stateRoot[:] +// signedBlock, err = blocks.NewSignedBeaconBlock(block) +// require.NoError(t, err) // -// err = st.SetLatestBlockHeader(h.Header) -// require.NoError(t, err) -// stateRoot, err := st.HashTreeRoot(ctx) -// require.NoError(t, err) +// root, err := block.Block.HashTreeRoot() +// require.NoError(t, err) // -// // get a new signed block so the root is updated with the new state root -// block.Block.StateRoot = stateRoot[:] -// signedBlock, err = blocks.NewSignedBeaconBlock(block) -// require.NoError(t, err) +// mockBlocker := &testutil.MockBlocker{ +// RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ +// parentRoot: signedParent, +// root: signedBlock, +// }, +// SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ +// slot.Sub(1): signedParent, +// slot: signedBlock, +// }, +// } +// mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st, FinalizedRoots: map[[32]byte]bool{ +// root: true, +// }} +// s := &Server{ +// Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ +// slot.Sub(1): attestedState, +// slot: st, +// }}, +// Blocker: mockBlocker, +// HeadFetcher: mockChainService, +// } // -// root, err := block.Block.HashTreeRoot() -// require.NoError(t, err) +// minSignaturesRequired := uint64(100) +// eventBlock, err := s.suitableBlock(ctx, minSignaturesRequired) // -// mockBlocker := &testutil.MockBlocker{ -// RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ -// parentRoot: signedParent, -// root: signedBlock, -// }, -// SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ -// slot.Sub(1): signedParent, -// slot: signedBlock, -// }, -// } -// mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st, FinalizedRoots: map[[32]byte]bool{ -// root: true, -// }} -// s := &Server{ -// Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ -// slot.Sub(1): attestedState, -// slot: st, -// }}, -// Blocker: mockBlocker, -// HeadFetcher: mockChainService, +// require.NoError(t, err) +// require.NotNil(t, eventBlock) +// require.Equal(t, slot, eventBlock.Block().Slot()) +// syncAggregate, err := eventBlock.Block().Body().SyncAggregate() +// require.NoError(t, err) +// require.Equal(t, true, syncAggregate.SyncCommitteeBits.Count() >= minSignaturesRequired) // } // -// minSignaturesRequired := uint64(100) -// eventBlock, err := s.suitableBlock(ctx, minSignaturesRequired) +// func TestLightClientHandler_GetLightClientEventBlock_NeedFetchParent(t *testing.T) { +// helpers.ClearCache() +// ctx := context.Background() +// params.SetupTestConfigCleanup(t) +// config := params.BeaconConfig() +// slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) // -// require.NoError(t, err) -// require.NotNil(t, eventBlock) -// require.Equal(t, slot, eventBlock.Block().Slot()) -// syncAggregate, err := eventBlock.Block().Body().SyncAggregate() -// require.NoError(t, err) -// require.Equal(t, true, syncAggregate.SyncCommitteeBits.Count() >= minSignaturesRequired) -//} +// attestedState, err := util.NewBeaconStateCapella() +// require.NoError(t, err) +// err = attestedState.SetSlot(slot.Sub(1)) +// require.NoError(t, err) // -//func TestLightClientHandler_GetLightClientEventBlock_NeedFetchParent(t *testing.T) { -// helpers.ClearCache() -// ctx := context.Background() -// params.SetupTestConfigCleanup(t) -// config := params.BeaconConfig() -// slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) +// require.NoError(t, attestedState.SetFinalizedCheckpoint(ðpb.Checkpoint{ +// Epoch: config.AltairForkEpoch - 10, +// Root: make([]byte, 32), +// })) // -// attestedState, err := util.NewBeaconStateCapella() -// require.NoError(t, err) -// err = attestedState.SetSlot(slot.Sub(1)) -// require.NoError(t, err) +// parent := util.NewBeaconBlockCapella() +// parent.Block.Slot = slot.Sub(1) +// for i := uint64(0); i < config.SyncCommitteeSize; i++ { +// parent.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) +// } // -// require.NoError(t, attestedState.SetFinalizedCheckpoint(ðpb.Checkpoint{ -// Epoch: config.AltairForkEpoch - 10, -// Root: make([]byte, 32), -// })) +// signedParent, err := blocks.NewSignedBeaconBlock(parent) +// require.NoError(t, err) // -// parent := util.NewBeaconBlockCapella() -// parent.Block.Slot = slot.Sub(1) -// for i := uint64(0); i < config.SyncCommitteeSize; i++ { -// parent.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) -// } +// parentHeader, err := signedParent.Header() +// require.NoError(t, err) +// attestedHeader := parentHeader.Header // -// signedParent, err := blocks.NewSignedBeaconBlock(parent) -// require.NoError(t, err) +// err = attestedState.SetLatestBlockHeader(attestedHeader) +// require.NoError(t, err) +// attestedStateRoot, err := attestedState.HashTreeRoot(ctx) +// require.NoError(t, err) // -// parentHeader, err := signedParent.Header() -// require.NoError(t, err) -// attestedHeader := parentHeader.Header +// // get a new signed block so the root is updated with the new state root +// parent.Block.StateRoot = attestedStateRoot[:] +// signedParent, err = blocks.NewSignedBeaconBlock(parent) +// require.NoError(t, err) // -// err = attestedState.SetLatestBlockHeader(attestedHeader) -// require.NoError(t, err) -// attestedStateRoot, err := attestedState.HashTreeRoot(ctx) -// require.NoError(t, err) +// st, err := util.NewBeaconStateCapella() +// require.NoError(t, err) +// err = st.SetSlot(slot) +// require.NoError(t, err) // -// // get a new signed block so the root is updated with the new state root -// parent.Block.StateRoot = attestedStateRoot[:] -// signedParent, err = blocks.NewSignedBeaconBlock(parent) -// require.NoError(t, err) +// parentRoot, err := signedParent.Block().HashTreeRoot() +// require.NoError(t, err) // -// st, err := util.NewBeaconStateCapella() -// require.NoError(t, err) -// err = st.SetSlot(slot) -// require.NoError(t, err) +// block := util.NewBeaconBlockCapella() +// block.Block.Slot = slot +// block.Block.ParentRoot = parentRoot[:] // -// parentRoot, err := signedParent.Block().HashTreeRoot() -// require.NoError(t, err) +// for i := uint64(0); i < 10; i++ { +// block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) +// } // -// block := util.NewBeaconBlockCapella() -// block.Block.Slot = slot -// block.Block.ParentRoot = parentRoot[:] +// signedBlock, err := blocks.NewSignedBeaconBlock(block) +// require.NoError(t, err) // -// for i := uint64(0); i < 10; i++ { -// block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) -// } +// h, err := signedBlock.Header() +// require.NoError(t, err) // -// signedBlock, err := blocks.NewSignedBeaconBlock(block) -// require.NoError(t, err) +// err = st.SetLatestBlockHeader(h.Header) +// require.NoError(t, err) +// stateRoot, err := st.HashTreeRoot(ctx) +// require.NoError(t, err) // -// h, err := signedBlock.Header() -// require.NoError(t, err) +// // get a new signed block so the root is updated with the new state root +// block.Block.StateRoot = stateRoot[:] +// signedBlock, err = blocks.NewSignedBeaconBlock(block) +// require.NoError(t, err) // -// err = st.SetLatestBlockHeader(h.Header) -// require.NoError(t, err) -// stateRoot, err := st.HashTreeRoot(ctx) -// require.NoError(t, err) +// root, err := block.Block.HashTreeRoot() +// require.NoError(t, err) // -// // get a new signed block so the root is updated with the new state root -// block.Block.StateRoot = stateRoot[:] -// signedBlock, err = blocks.NewSignedBeaconBlock(block) -// require.NoError(t, err) +// mockBlocker := &testutil.MockBlocker{ +// RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ +// parentRoot: signedParent, +// root: signedBlock, +// }, +// SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ +// slot.Sub(1): signedParent, +// slot: signedBlock, +// }, +// } +// mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st, FinalizedRoots: map[[32]byte]bool{ +// root: true, +// }} +// s := &Server{ +// Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ +// slot.Sub(1): attestedState, +// slot: st, +// }}, +// Blocker: mockBlocker, +// HeadFetcher: mockChainService, +// } // -// root, err := block.Block.HashTreeRoot() -// require.NoError(t, err) +// minSignaturesRequired := uint64(100) +// eventBlock, err := s.suitableBlock(ctx, minSignaturesRequired) // -// mockBlocker := &testutil.MockBlocker{ -// RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ -// parentRoot: signedParent, -// root: signedBlock, -// }, -// SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ -// slot.Sub(1): signedParent, -// slot: signedBlock, -// }, -// } -// mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st, FinalizedRoots: map[[32]byte]bool{ -// root: true, -// }} -// s := &Server{ -// Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ -// slot.Sub(1): attestedState, -// slot: st, -// }}, -// Blocker: mockBlocker, -// HeadFetcher: mockChainService, +// require.NoError(t, err) +// require.NotNil(t, eventBlock) +// syncAggregate, err := eventBlock.Block().Body().SyncAggregate() +// require.NoError(t, err) +// require.Equal(t, true, syncAggregate.SyncCommitteeBits.Count() >= minSignaturesRequired) +// require.Equal(t, slot-1, eventBlock.Block().Slot()) // } // -// minSignaturesRequired := uint64(100) -// eventBlock, err := s.suitableBlock(ctx, minSignaturesRequired) -// -// require.NoError(t, err) -// require.NotNil(t, eventBlock) -// syncAggregate, err := eventBlock.Block().Body().SyncAggregate() -// require.NoError(t, err) -// require.Equal(t, true, syncAggregate.SyncCommitteeBits.Count() >= minSignaturesRequired) -// require.Equal(t, slot-1, eventBlock.Block().Slot()) -//} -// -//// setupDB instantiates and returns a Store instance. -//func setupDB(t testing.TB) *kv.Store { -// db, err := kv.NewKVStore(context.Background(), t.TempDir()) -// require.NoError(t, err, "Failed to instantiate DB") -// t.Cleanup(func() { -// require.NoError(t, db.Close(), "Failed to close database") -// }) -// return db -//} +// setupDB instantiates and returns a Store instance. +func setupDB(t testing.TB) *kv.Store { + db, err := kv.NewKVStore(context.Background(), t.TempDir()) + require.NoError(t, err, "Failed to instantiate DB") + t.Cleanup(func() { + require.NoError(t, db.Close(), "Failed to close database") + }) + return db +} From c9c4f4650868df1b5c0f7a080db7a0ef3a22ec9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20Kapka?= Date: Thu, 24 Oct 2024 00:34:43 +0700 Subject: [PATCH 23/35] Set fields of wrapped proto object in light client setters (#14573) * Set fields of wrapped proto object in light client setters * changelog <3 --- CHANGELOG.md | 1 + beacon-chain/core/light-client/lightclient.go | 8 +- consensus-types/interfaces/light_client.go | 4 +- consensus-types/light-client/update.go | 140 +++++++++++++++++- 4 files changed, 141 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fb3918d42d59..91c3ff280bdf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,6 +42,7 @@ The format is based on Keep a Changelog, and this project adheres to Semantic Ve - Fix skipping partial withdrawals count. - recover from panics when writing the event stream [pr](https://github.com/prysmaticlabs/prysm/pull/14545) - Return the correct light client payload proof. [PR](https://github.com/prysmaticlabs/prysm/pull/14565) +- Set fields of wrapped proto object in light client setters. [PR](https://github.com/prysmaticlabs/prysm/pull/14573) ### Security diff --git a/beacon-chain/core/light-client/lightclient.go b/beacon-chain/core/light-client/lightclient.go index 7c60a163cf05..6a822012949b 100644 --- a/beacon-chain/core/light-client/lightclient.go +++ b/beacon-chain/core/light-client/lightclient.go @@ -169,7 +169,9 @@ func NewLightClientUpdateFromBeaconState( if err != nil { return nil, errors.Wrap(err, "could not get attested light client header") } - result.SetAttestedHeader(attestedLightClientHeader) + if err = result.SetAttestedHeader(attestedLightClientHeader); err != nil { + return nil, errors.Wrap(err, "could not set attested header") + } // if update_attested_period == update_signature_period if updateAttestedPeriod == updateSignaturePeriod { @@ -208,7 +210,9 @@ func NewLightClientUpdateFromBeaconState( if err != nil { return nil, errors.Wrap(err, "could not get finalized light client header") } - result.SetFinalizedHeader(finalizedLightClientHeader) + if err = result.SetFinalizedHeader(finalizedLightClientHeader); err != nil { + return nil, errors.Wrap(err, "could not set finalized header") + } } else { // assert attested_state.finalized_checkpoint.root == Bytes32() if !bytes.Equal(attestedState.FinalizedCheckpoint().Root, make([]byte, 32)) { diff --git a/consensus-types/interfaces/light_client.go b/consensus-types/interfaces/light_client.go index 994470c65a42..89ea81f07676 100644 --- a/consensus-types/interfaces/light_client.go +++ b/consensus-types/interfaces/light_client.go @@ -36,7 +36,7 @@ type LightClientUpdate interface { Proto() proto.Message Version() int AttestedHeader() LightClientHeader - SetAttestedHeader(header LightClientHeader) + SetAttestedHeader(header LightClientHeader) error NextSyncCommittee() *pb.SyncCommittee SetNextSyncCommittee(sc *pb.SyncCommittee) NextSyncCommitteeBranch() (LightClientSyncCommitteeBranch, error) @@ -44,7 +44,7 @@ type LightClientUpdate interface { NextSyncCommitteeBranchElectra() (LightClientSyncCommitteeBranchElectra, error) SetNextSyncCommitteeBranchElectra(branch [][]byte) error FinalizedHeader() LightClientHeader - SetFinalizedHeader(header LightClientHeader) + SetFinalizedHeader(header LightClientHeader) error FinalityBranch() LightClientFinalityBranch SetFinalityBranch(branch [][]byte) error SyncAggregate() *pb.SyncAggregate diff --git a/consensus-types/light-client/update.go b/consensus-types/light-client/update.go index 81ebf87f9c69..f6fb739d2996 100644 --- a/consensus-types/light-client/update.go +++ b/consensus-types/light-client/update.go @@ -30,6 +30,9 @@ func NewWrappedUpdate(m proto.Message) (interfaces.LightClientUpdate, error) { } } +// In addition to the proto object being wrapped, we store some fields that have to be +// constructed from the proto, so that we don't have to reconstruct them every time +// in getters. type updateAltair struct { p *pb.LightClientUpdateAltair attestedHeader interfaces.LightClientHeader @@ -107,8 +110,19 @@ func (u *updateAltair) AttestedHeader() interfaces.LightClientHeader { return u.attestedHeader } -func (u *updateAltair) SetAttestedHeader(header interfaces.LightClientHeader) { +func (u *updateAltair) SetAttestedHeader(header interfaces.LightClientHeader) error { + if header.Version() != version.Altair { + return fmt.Errorf("header version %s is not %s", version.String(header.Version()), version.String(version.Altair)) + } u.attestedHeader = header + + proto, ok := header.Proto().(*pb.LightClientHeaderAltair) + if !ok { + return fmt.Errorf("header type %T is not %T", proto, &pb.LightClientHeaderAltair{}) + } + u.p.AttestedHeader = proto + + return nil } func (u *updateAltair) NextSyncCommittee() *pb.SyncCommittee { @@ -129,6 +143,9 @@ func (u *updateAltair) SetNextSyncCommitteeBranch(branch [][]byte) error { return err } u.nextSyncCommitteeBranch = b + + u.p.NextSyncCommitteeBranch = branch + return nil } @@ -144,8 +161,19 @@ func (u *updateAltair) FinalizedHeader() interfaces.LightClientHeader { return u.finalizedHeader } -func (u *updateAltair) SetFinalizedHeader(header interfaces.LightClientHeader) { +func (u *updateAltair) SetFinalizedHeader(header interfaces.LightClientHeader) error { + if header.Version() != version.Altair { + return fmt.Errorf("header version %s is not %s", version.String(header.Version()), version.String(version.Altair)) + } u.finalizedHeader = header + + proto, ok := header.Proto().(*pb.LightClientHeaderAltair) + if !ok { + return fmt.Errorf("header type %T is not %T", proto, &pb.LightClientHeaderAltair{}) + } + u.p.FinalizedHeader = proto + + return nil } func (u *updateAltair) FinalityBranch() interfaces.LightClientFinalityBranch { @@ -158,6 +186,9 @@ func (u *updateAltair) SetFinalityBranch(branch [][]byte) error { return err } u.finalityBranch = b + + u.p.FinalityBranch = branch + return nil } @@ -177,6 +208,9 @@ func (u *updateAltair) SetSignatureSlot(slot primitives.Slot) { u.p.SignatureSlot = slot } +// In addition to the proto object being wrapped, we store some fields that have to be +// constructed from the proto, so that we don't have to reconstruct them every time +// in getters. type updateCapella struct { p *pb.LightClientUpdateCapella attestedHeader interfaces.LightClientHeader @@ -254,8 +288,19 @@ func (u *updateCapella) AttestedHeader() interfaces.LightClientHeader { return u.attestedHeader } -func (u *updateCapella) SetAttestedHeader(header interfaces.LightClientHeader) { +func (u *updateCapella) SetAttestedHeader(header interfaces.LightClientHeader) error { + if header.Version() != version.Capella { + return fmt.Errorf("header version %s is not %s", version.String(header.Version()), version.String(version.Capella)) + } u.attestedHeader = header + + proto, ok := header.Proto().(*pb.LightClientHeaderCapella) + if !ok { + return fmt.Errorf("header type %T is not %T", proto, &pb.LightClientHeaderCapella{}) + } + u.p.AttestedHeader = proto + + return nil } func (u *updateCapella) NextSyncCommittee() *pb.SyncCommittee { @@ -276,6 +321,9 @@ func (u *updateCapella) SetNextSyncCommitteeBranch(branch [][]byte) error { return err } u.nextSyncCommitteeBranch = b + + u.p.NextSyncCommitteeBranch = branch + return nil } @@ -291,8 +339,19 @@ func (u *updateCapella) FinalizedHeader() interfaces.LightClientHeader { return u.finalizedHeader } -func (u *updateCapella) SetFinalizedHeader(header interfaces.LightClientHeader) { +func (u *updateCapella) SetFinalizedHeader(header interfaces.LightClientHeader) error { + if header.Version() != version.Capella { + return fmt.Errorf("header version %s is not %s", version.String(header.Version()), version.String(version.Capella)) + } u.finalizedHeader = header + + proto, ok := header.Proto().(*pb.LightClientHeaderCapella) + if !ok { + return fmt.Errorf("header type %T is not %T", proto, &pb.LightClientHeaderCapella{}) + } + u.p.FinalizedHeader = proto + + return nil } func (u *updateCapella) FinalityBranch() interfaces.LightClientFinalityBranch { @@ -305,6 +364,9 @@ func (u *updateCapella) SetFinalityBranch(branch [][]byte) error { return err } u.finalityBranch = b + + u.p.FinalityBranch = branch + return nil } @@ -324,6 +386,9 @@ func (u *updateCapella) SetSignatureSlot(slot primitives.Slot) { u.p.SignatureSlot = slot } +// In addition to the proto object being wrapped, we store some fields that have to be +// constructed from the proto, so that we don't have to reconstruct them every time +// in getters. type updateDeneb struct { p *pb.LightClientUpdateDeneb attestedHeader interfaces.LightClientHeader @@ -401,8 +466,19 @@ func (u *updateDeneb) AttestedHeader() interfaces.LightClientHeader { return u.attestedHeader } -func (u *updateDeneb) SetAttestedHeader(header interfaces.LightClientHeader) { +func (u *updateDeneb) SetAttestedHeader(header interfaces.LightClientHeader) error { + if header.Version() != version.Deneb { + return fmt.Errorf("header version %s is not %s", version.String(header.Version()), version.String(version.Deneb)) + } u.attestedHeader = header + + proto, ok := header.Proto().(*pb.LightClientHeaderDeneb) + if !ok { + return fmt.Errorf("header type %T is not %T", proto, &pb.LightClientHeaderDeneb{}) + } + u.p.AttestedHeader = proto + + return nil } func (u *updateDeneb) NextSyncCommittee() *pb.SyncCommittee { @@ -423,6 +499,9 @@ func (u *updateDeneb) SetNextSyncCommitteeBranch(branch [][]byte) error { return err } u.nextSyncCommitteeBranch = b + + u.p.NextSyncCommitteeBranch = branch + return nil } @@ -438,8 +517,19 @@ func (u *updateDeneb) FinalizedHeader() interfaces.LightClientHeader { return u.finalizedHeader } -func (u *updateDeneb) SetFinalizedHeader(header interfaces.LightClientHeader) { +func (u *updateDeneb) SetFinalizedHeader(header interfaces.LightClientHeader) error { + if header.Version() != version.Deneb { + return fmt.Errorf("header version %s is not %s", version.String(header.Version()), version.String(version.Deneb)) + } u.finalizedHeader = header + + proto, ok := header.Proto().(*pb.LightClientHeaderDeneb) + if !ok { + return fmt.Errorf("header type %T is not %T", proto, &pb.LightClientHeaderDeneb{}) + } + u.p.FinalizedHeader = proto + + return nil } func (u *updateDeneb) FinalityBranch() interfaces.LightClientFinalityBranch { @@ -452,6 +542,9 @@ func (u *updateDeneb) SetFinalityBranch(branch [][]byte) error { return err } u.finalityBranch = b + + u.p.FinalityBranch = branch + return nil } @@ -471,6 +564,9 @@ func (u *updateDeneb) SetSignatureSlot(slot primitives.Slot) { u.p.SignatureSlot = slot } +// In addition to the proto object being wrapped, we store some fields that have to be +// constructed from the proto, so that we don't have to reconstruct them every time +// in getters. type updateElectra struct { p *pb.LightClientUpdateElectra attestedHeader interfaces.LightClientHeader @@ -548,8 +644,19 @@ func (u *updateElectra) AttestedHeader() interfaces.LightClientHeader { return u.attestedHeader } -func (u *updateElectra) SetAttestedHeader(header interfaces.LightClientHeader) { +func (u *updateElectra) SetAttestedHeader(header interfaces.LightClientHeader) error { + if header.Version() != version.Electra { + return fmt.Errorf("header version %s is not %s", version.String(header.Version()), version.String(version.Electra)) + } u.attestedHeader = header + + proto, ok := header.Proto().(*pb.LightClientHeaderDeneb) + if !ok { + return fmt.Errorf("header type %T is not %T", proto, &pb.LightClientHeaderDeneb{}) + } + u.p.AttestedHeader = proto + + return nil } func (u *updateElectra) NextSyncCommittee() *pb.SyncCommittee { @@ -578,6 +685,9 @@ func (u *updateElectra) SetNextSyncCommitteeBranchElectra(branch [][]byte) error return err } u.nextSyncCommitteeBranch = b + + u.p.NextSyncCommitteeBranch = branch + return nil } @@ -585,8 +695,19 @@ func (u *updateElectra) FinalizedHeader() interfaces.LightClientHeader { return u.finalizedHeader } -func (u *updateElectra) SetFinalizedHeader(header interfaces.LightClientHeader) { +func (u *updateElectra) SetFinalizedHeader(header interfaces.LightClientHeader) error { + if header.Version() != version.Electra { + return fmt.Errorf("header version %s is not %s", version.String(header.Version()), version.String(version.Electra)) + } u.finalizedHeader = header + + proto, ok := header.Proto().(*pb.LightClientHeaderDeneb) + if !ok { + return fmt.Errorf("header type %T is not %T", proto, &pb.LightClientHeaderDeneb{}) + } + u.p.FinalizedHeader = proto + + return nil } func (u *updateElectra) FinalityBranch() interfaces.LightClientFinalityBranch { @@ -599,6 +720,9 @@ func (u *updateElectra) SetFinalityBranch(branch [][]byte) error { return err } u.finalityBranch = b + + u.p.FinalityBranch = branch + return nil } From c9fedf1c291d94f3f021a1d4ea29eb71f8b0f1f9 Mon Sep 17 00:00:00 2001 From: Inspector-Butters Date: Wed, 23 Oct 2024 19:44:00 +0200 Subject: [PATCH 24/35] fixing tests... --- .../core/light-client/lightclient_test.go | 594 +++++++++--------- testing/util/lightclient.go | 8 +- 2 files changed, 301 insertions(+), 301 deletions(-) diff --git a/beacon-chain/core/light-client/lightclient_test.go b/beacon-chain/core/light-client/lightclient_test.go index 19568ec3cb4f..65124ce59756 100644 --- a/beacon-chain/core/light-client/lightclient_test.go +++ b/beacon-chain/core/light-client/lightclient_test.go @@ -34,308 +34,308 @@ func TestLightClient_NewLightClientOptimisticUpdateFromBeaconState(t *testing.T) l.CheckAttestedHeader(update.AttestedHeader()) }) - //t.Run("Deneb", func(t *testing.T) { - // l := util.NewTestLightClient(t).SetupTestDeneb(false) + t.Run("Deneb", func(t *testing.T) { + l := util.NewTestLightClient(t).SetupTestDeneb(false) + + update, err := lightClient.NewLightClientOptimisticUpdateFromBeaconState(l.Ctx, l.State.Slot(), l.State, l.Block, l.AttestedState, l.AttestedBlock) + require.NoError(t, err) + require.NotNil(t, update, "update is nil") + + require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot(), "Signature slot is not equal") + + l.CheckSyncAggregate(update.SyncAggregate()) + l.CheckAttestedHeader(update.AttestedHeader()) + }) +} + +func TestLightClient_NewLightClientFinalityUpdateFromBeaconState(t *testing.T) { + t.Run("Altair", func(t *testing.T) { + l := util.NewTestLightClient(t).SetupTestAltair() + + t.Run("FinalizedBlock Not Nil", func(t *testing.T) { + update, err := lightClient.NewLightClientFinalityUpdateFromBeaconState(l.Ctx, l.State.Slot(), l.State, l.Block, l.AttestedState, l.AttestedBlock, l.FinalizedBlock) + require.NoError(t, err) + require.NotNil(t, update, "update is nil") + + require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot(), "Signature slot is not equal") + + l.CheckSyncAggregate(update.SyncAggregate()) + l.CheckAttestedHeader(update.AttestedHeader()) + + finalizedBlockHeader, err := l.FinalizedBlock.Header() + require.NoError(t, err) + + //zeroHash := params.BeaconConfig().ZeroHash[:] + require.NotNil(t, update.FinalizedHeader(), "Finalized header is nil") + updateFinalizedHeaderBeacon := update.FinalizedHeader().Beacon() + require.Equal(t, finalizedBlockHeader.Header.Slot, updateFinalizedHeaderBeacon.Slot, "Finalized header slot is not equal") + require.Equal(t, finalizedBlockHeader.Header.ProposerIndex, updateFinalizedHeaderBeacon.ProposerIndex, "Finalized header proposer index is not equal") + require.DeepSSZEqual(t, finalizedBlockHeader.Header.ParentRoot, updateFinalizedHeaderBeacon.ParentRoot, "Finalized header parent root is not equal") + require.DeepSSZEqual(t, finalizedBlockHeader.Header.StateRoot, updateFinalizedHeaderBeacon.StateRoot, "Finalized header state root is not equal") + require.DeepSSZEqual(t, finalizedBlockHeader.Header.BodyRoot, updateFinalizedHeaderBeacon.BodyRoot, "Finalized header body root is not equal") + require.Equal(t, lightClient.FinalityBranchNumOfLeaves, len(update.FinalityBranch()), "Invalid finality branch leaves") + + finalityBranch, err := l.AttestedState.FinalizedRootProof(l.Ctx) + require.NoError(t, err) + for i, leaf := range update.FinalityBranch() { + require.DeepSSZEqual(t, finalityBranch[i], leaf[:], "Leaf is not equal") + } + }) + }) + + t.Run("Capella", func(t *testing.T) { + + //t.Run("FinalizedBlock Not Nil", func(t *testing.T) { + // l := util.NewTestLightClient(t).SetupTestCapella(false) + // update, err := lightClient.NewLightClientFinalityUpdateFromBeaconState(l.Ctx, l.State.Slot(), l.State, l.Block, l.AttestedState, l.AttestedBlock, l.FinalizedBlock) + // require.NoError(t, err) + // require.NotNil(t, update, "update is nil") + // + // require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot(), "Signature slot is not equal") + // + // l.CheckSyncAggregate(update.SyncAggregate()) + // l.CheckAttestedHeader(update.AttestedHeader()) + // + // finalizedBlockHeader, err := l.FinalizedBlock.Header() + // require.NoError(t, err) + // require.NotNil(t, update.FinalizedHeader(), "Finalized header is nil") + // updateFinalizedHeaderBeacon := update.FinalizedHeader().Beacon() + // require.Equal(t, finalizedBlockHeader.Header.Slot, updateFinalizedHeaderBeacon.Slot, "Finalized header slot is not equal") + // require.Equal(t, finalizedBlockHeader.Header.ProposerIndex, updateFinalizedHeaderBeacon.ProposerIndex, "Finalized header proposer index is not equal") + // require.DeepSSZEqual(t, finalizedBlockHeader.Header.ParentRoot, updateFinalizedHeaderBeacon.ParentRoot, "Finalized header parent root is not equal") + // require.DeepSSZEqual(t, finalizedBlockHeader.Header.StateRoot, updateFinalizedHeaderBeacon.StateRoot, "Finalized header state root is not equal") + // require.DeepSSZEqual(t, finalizedBlockHeader.Header.BodyRoot, updateFinalizedHeaderBeacon.BodyRoot, "Finalized header body root is not equal") + // require.Equal(t, lightClient.FinalityBranchNumOfLeaves, len(update.FinalityBranch()), "Invalid finality branch leaves") + // finalityBranch, err := l.AttestedState.FinalizedRootProof(l.Ctx) + // require.NoError(t, err) + // for i, leaf := range update.FinalityBranch() { + // require.DeepSSZEqual(t, finalityBranch[i], leaf[:], "Leaf is not equal") + // } + // + // // Check Execution BlockHash + // payloadInterface, err := l.FinalizedBlock.Block().Body().Execution() + // require.NoError(t, err) + // transactionsRoot, err := payloadInterface.TransactionsRoot() + // if errors.Is(err, consensustypes.ErrUnsupportedField) { + // transactions, err := payloadInterface.Transactions() + // require.NoError(t, err) + // transactionsRootArray, err := ssz.TransactionsRoot(transactions) + // require.NoError(t, err) + // transactionsRoot = transactionsRootArray[:] + // } else { + // require.NoError(t, err) + // } + // withdrawalsRoot, err := payloadInterface.WithdrawalsRoot() + // if errors.Is(err, consensustypes.ErrUnsupportedField) { + // withdrawals, err := payloadInterface.Withdrawals() + // require.NoError(t, err) + // withdrawalsRootArray, err := ssz.WithdrawalSliceRoot(withdrawals, fieldparams.MaxWithdrawalsPerPayload) + // require.NoError(t, err) + // withdrawalsRoot = withdrawalsRootArray[:] + // } else { + // require.NoError(t, err) + // } + // execution := &v11.ExecutionPayloadHeaderCapella{ + // ParentHash: payloadInterface.ParentHash(), + // FeeRecipient: payloadInterface.FeeRecipient(), + // StateRoot: payloadInterface.StateRoot(), + // ReceiptsRoot: payloadInterface.ReceiptsRoot(), + // LogsBloom: payloadInterface.LogsBloom(), + // PrevRandao: payloadInterface.PrevRandao(), + // BlockNumber: payloadInterface.BlockNumber(), + // GasLimit: payloadInterface.GasLimit(), + // GasUsed: payloadInterface.GasUsed(), + // Timestamp: payloadInterface.Timestamp(), + // ExtraData: payloadInterface.ExtraData(), + // BaseFeePerGas: payloadInterface.BaseFeePerGas(), + // BlockHash: payloadInterface.BlockHash(), + // TransactionsRoot: transactionsRoot, + // WithdrawalsRoot: withdrawalsRoot, + // } + // updateExecution, err := update.FinalizedHeader().Execution() + // require.NoError(t, err) + // require.DeepSSZEqual(t, execution, updateExecution, "Finalized Block Execution is not equal") + //}) + + // t.Run("FinalizedBlock In Previous Fork", func(t *testing.T) { + // l := util.NewTestLightClient(t).SetupTestCapellaFinalizedBlockAltair(false) + // update, err := lightClient.NewLightClientFinalityUpdateFromBeaconState(l.Ctx, l.State, l.Block, l.AttestedState, l.AttestedBlock, l.FinalizedBlock) + // require.NoError(t, err) + // require.NotNil(t, update, "update is nil") + // + // require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot, "Signature slot is not equal") + // + // l.CheckSyncAggregate(update.SyncAggregate) + // l.CheckAttestedHeader(update.AttestedHeader) + // + // finalizedBlockHeader, err := l.FinalizedBlock.Header() + // require.NoError(t, err) + // require.NotNil(t, update.FinalizedHeader, "Finalized header is nil") + // updateFinalizedHeaderBeacon, err := update.FinalizedHeader.GetBeacon() + // require.NoError(t, err) + // require.Equal(t, finalizedBlockHeader.Header.Slot, updateFinalizedHeaderBeacon.Slot, "Finalized header slot is not equal") + // require.Equal(t, finalizedBlockHeader.Header.ProposerIndex, updateFinalizedHeaderBeacon.ProposerIndex, "Finalized header proposer index is not equal") + // require.DeepSSZEqual(t, finalizedBlockHeader.Header.ParentRoot, updateFinalizedHeaderBeacon.ParentRoot, "Finalized header parent root is not equal") + // require.DeepSSZEqual(t, finalizedBlockHeader.Header.StateRoot, updateFinalizedHeaderBeacon.StateRoot, "Finalized header state root is not equal") + // require.DeepSSZEqual(t, finalizedBlockHeader.Header.BodyRoot, updateFinalizedHeaderBeacon.BodyRoot, "Finalized header body root is not equal") + // require.Equal(t, lightClient.FinalityBranchNumOfLeaves, len(update.FinalityBranch), "Invalid finality branch leaves") + // finalityBranch, err := l.AttestedState.FinalizedRootProof(l.Ctx) + // require.NoError(t, err) + // for i, leaf := range update.FinalityBranch { + // require.DeepSSZEqual(t, finalityBranch[i], leaf, "Leaf is not equal") + // } + // }) + }) + // + // t.Run("Deneb", func(t *testing.T) { + // + // t.Run("FinalizedBlock Not Nil", func(t *testing.T) { + // l := util.NewTestLightClient(t).SetupTestDeneb(false) + // + // update, err := lightClient.NewLightClientFinalityUpdateFromBeaconState(l.Ctx, l.State, l.Block, l.AttestedState, l.AttestedBlock, l.FinalizedBlock) + // require.NoError(t, err) + // require.NotNil(t, update, "update is nil") + // + // require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot, "Signature slot is not equal") + // + // l.CheckSyncAggregate(update.SyncAggregate) + // l.CheckAttestedHeader(update.AttestedHeader) // - // update, err := lightClient.NewLightClientOptimisticUpdateFromBeaconState(l.Ctx, l.State.Slot(), l.State, l.Block, l.AttestedState, l.AttestedBlock) - // require.NoError(t, err) - // require.NotNil(t, update, "update is nil") + // //zeroHash := params.BeaconConfig().ZeroHash[:] + // finalizedBlockHeader, err := l.FinalizedBlock.Header() + // require.NoError(t, err) + // require.NotNil(t, update.FinalizedHeader, "Finalized header is nil") + // updateFinalizedHeaderBeacon, err := update.FinalizedHeader.GetBeacon() + // require.NoError(t, err) + // require.Equal(t, finalizedBlockHeader.Header.Slot, updateFinalizedHeaderBeacon.Slot, "Finalized header slot is not equal") + // require.Equal(t, finalizedBlockHeader.Header.ProposerIndex, updateFinalizedHeaderBeacon.ProposerIndex, "Finalized header proposer index is not equal") + // require.DeepSSZEqual(t, finalizedBlockHeader.Header.ParentRoot, updateFinalizedHeaderBeacon.ParentRoot, "Finalized header parent root is not equal") + // require.DeepSSZEqual(t, finalizedBlockHeader.Header.StateRoot, updateFinalizedHeaderBeacon.StateRoot, "Finalized header state root is not equal") + // require.DeepSSZEqual(t, finalizedBlockHeader.Header.BodyRoot, updateFinalizedHeaderBeacon.BodyRoot, "Finalized header body root is not equal") + // require.Equal(t, lightClient.FinalityBranchNumOfLeaves, len(update.FinalityBranch), "Invalid finality branch leaves") + // finalityBranch, err := l.AttestedState.FinalizedRootProof(l.Ctx) + // require.NoError(t, err) + // for i, leaf := range update.FinalityBranch { + // require.DeepSSZEqual(t, finalityBranch[i], leaf, "Leaf is not equal") + // } // - // require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot(), "Signature slot is not equal") + // // Check Execution BlockHash + // payloadInterface, err := l.FinalizedBlock.Block().Body().Execution() + // require.NoError(t, err) + // transactionsRoot, err := payloadInterface.TransactionsRoot() + // if errors.Is(err, consensustypes.ErrUnsupportedField) { + // transactions, err := payloadInterface.Transactions() + // require.NoError(t, err) + // transactionsRootArray, err := ssz.TransactionsRoot(transactions) + // require.NoError(t, err) + // transactionsRoot = transactionsRootArray[:] + // } else { + // require.NoError(t, err) + // } + // withdrawalsRoot, err := payloadInterface.WithdrawalsRoot() + // if errors.Is(err, consensustypes.ErrUnsupportedField) { + // withdrawals, err := payloadInterface.Withdrawals() + // require.NoError(t, err) + // withdrawalsRootArray, err := ssz.WithdrawalSliceRoot(withdrawals, fieldparams.MaxWithdrawalsPerPayload) + // require.NoError(t, err) + // withdrawalsRoot = withdrawalsRootArray[:] + // } else { + // require.NoError(t, err) + // } + // execution := &v11.ExecutionPayloadHeaderDeneb{ + // ParentHash: payloadInterface.ParentHash(), + // FeeRecipient: payloadInterface.FeeRecipient(), + // StateRoot: payloadInterface.StateRoot(), + // ReceiptsRoot: payloadInterface.ReceiptsRoot(), + // LogsBloom: payloadInterface.LogsBloom(), + // PrevRandao: payloadInterface.PrevRandao(), + // BlockNumber: payloadInterface.BlockNumber(), + // GasLimit: payloadInterface.GasLimit(), + // GasUsed: payloadInterface.GasUsed(), + // Timestamp: payloadInterface.Timestamp(), + // ExtraData: payloadInterface.ExtraData(), + // BaseFeePerGas: payloadInterface.BaseFeePerGas(), + // BlockHash: payloadInterface.BlockHash(), + // TransactionsRoot: transactionsRoot, + // WithdrawalsRoot: withdrawalsRoot, + // } + // require.DeepSSZEqual(t, execution, update.FinalizedHeader.GetHeaderDeneb().Execution, "Finalized Block Execution is not equal") + // }) // - // l.CheckSyncAggregate(update.SyncAggregate()) - // l.CheckAttestedHeader(update.AttestedHeader()) - //}) + // t.Run("FinalizedBlock In Previous Fork", func(t *testing.T) { + // l := util.NewTestLightClient(t).SetupTestDenebFinalizedBlockCapella(false) + // + // update, err := lightClient.NewLightClientFinalityUpdateFromBeaconState(l.Ctx, l.State, l.Block, l.AttestedState, l.AttestedBlock, l.FinalizedBlock) + // require.NoError(t, err) + // require.NotNil(t, update, "update is nil") + // + // require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot, "Signature slot is not equal") + // + // l.CheckSyncAggregate(update.SyncAggregate) + // l.CheckAttestedHeader(update.AttestedHeader) + // + // finalizedBlockHeader, err := l.FinalizedBlock.Header() + // require.NoError(t, err) + // require.NotNil(t, update.FinalizedHeader, "Finalized header is nil") + // updateFinalizedHeaderBeacon, err := update.FinalizedHeader.GetBeacon() + // require.NoError(t, err) + // require.Equal(t, finalizedBlockHeader.Header.Slot, updateFinalizedHeaderBeacon.Slot, "Finalized header slot is not equal") + // require.Equal(t, finalizedBlockHeader.Header.ProposerIndex, updateFinalizedHeaderBeacon.ProposerIndex, "Finalized header proposer index is not equal") + // require.DeepSSZEqual(t, finalizedBlockHeader.Header.ParentRoot, updateFinalizedHeaderBeacon.ParentRoot, "Finalized header parent root is not equal") + // require.DeepSSZEqual(t, finalizedBlockHeader.Header.StateRoot, updateFinalizedHeaderBeacon.StateRoot, "Finalized header state root is not equal") + // require.DeepSSZEqual(t, finalizedBlockHeader.Header.BodyRoot, updateFinalizedHeaderBeacon.BodyRoot, "Finalized header body root is not equal") + // require.Equal(t, lightClient.FinalityBranchNumOfLeaves, len(update.FinalityBranch), "Invalid finality branch leaves") + // finalityBranch, err := l.AttestedState.FinalizedRootProof(l.Ctx) + // require.NoError(t, err) + // for i, leaf := range update.FinalityBranch { + // require.DeepSSZEqual(t, finalityBranch[i], leaf, "Leaf is not equal") + // } + // + // // Check Execution BlockHash + // payloadInterface, err := l.FinalizedBlock.Block().Body().Execution() + // require.NoError(t, err) + // transactionsRoot, err := payloadInterface.TransactionsRoot() + // if errors.Is(err, consensustypes.ErrUnsupportedField) { + // transactions, err := payloadInterface.Transactions() + // require.NoError(t, err) + // transactionsRootArray, err := ssz.TransactionsRoot(transactions) + // require.NoError(t, err) + // transactionsRoot = transactionsRootArray[:] + // } else { + // require.NoError(t, err) + // } + // withdrawalsRoot, err := payloadInterface.WithdrawalsRoot() + // if errors.Is(err, consensustypes.ErrUnsupportedField) { + // withdrawals, err := payloadInterface.Withdrawals() + // require.NoError(t, err) + // withdrawalsRootArray, err := ssz.WithdrawalSliceRoot(withdrawals, fieldparams.MaxWithdrawalsPerPayload) + // require.NoError(t, err) + // withdrawalsRoot = withdrawalsRootArray[:] + // } else { + // require.NoError(t, err) + // } + // execution := &v11.ExecutionPayloadHeaderCapella{ + // ParentHash: payloadInterface.ParentHash(), + // FeeRecipient: payloadInterface.FeeRecipient(), + // StateRoot: payloadInterface.StateRoot(), + // ReceiptsRoot: payloadInterface.ReceiptsRoot(), + // LogsBloom: payloadInterface.LogsBloom(), + // PrevRandao: payloadInterface.PrevRandao(), + // BlockNumber: payloadInterface.BlockNumber(), + // GasLimit: payloadInterface.GasLimit(), + // GasUsed: payloadInterface.GasUsed(), + // Timestamp: payloadInterface.Timestamp(), + // ExtraData: payloadInterface.ExtraData(), + // BaseFeePerGas: payloadInterface.BaseFeePerGas(), + // BlockHash: payloadInterface.BlockHash(), + // TransactionsRoot: transactionsRoot, + // WithdrawalsRoot: withdrawalsRoot, + // } + // require.DeepSSZEqual(t, execution, update.FinalizedHeader.GetHeaderCapella().Execution, "Finalized Block Execution is not equal") + // }) + // }) } -//func TestLightClient_NewLightClientFinalityUpdateFromBeaconState(t *testing.T) { -// t.Run("Altair", func(t *testing.T) { -// l := util.NewTestLightClient(t).SetupTestAltair() -// -// t.Run("FinalizedBlock Not Nil", func(t *testing.T) { -// update, err := lightClient.NewLightClientFinalityUpdateFromBeaconState(l.Ctx, l.State, l.Block, l.AttestedState, l.AttestedBlock, l.FinalizedBlock) -// require.NoError(t, err) -// require.NotNil(t, update, "update is nil") -// -// require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot, "Signature slot is not equal") -// -// l.CheckSyncAggregate(update.SyncAggregate) -// l.CheckAttestedHeader(update.AttestedHeader) -// -// finalizedBlockHeader, err := l.FinalizedBlock.Header() -// require.NoError(t, err) -// -// //zeroHash := params.BeaconConfig().ZeroHash[:] -// require.NotNil(t, update.FinalizedHeader, "Finalized header is nil") -// updateFinalizedHeaderBeacon, err := update.FinalizedHeader.GetBeacon() -// require.NoError(t, err) -// require.Equal(t, finalizedBlockHeader.Header.Slot, updateFinalizedHeaderBeacon.Slot, "Finalized header slot is not equal") -// require.Equal(t, finalizedBlockHeader.Header.ProposerIndex, updateFinalizedHeaderBeacon.ProposerIndex, "Finalized header proposer index is not equal") -// require.DeepSSZEqual(t, finalizedBlockHeader.Header.ParentRoot, updateFinalizedHeaderBeacon.ParentRoot, "Finalized header parent root is not equal") -// require.DeepSSZEqual(t, finalizedBlockHeader.Header.StateRoot, updateFinalizedHeaderBeacon.StateRoot, "Finalized header state root is not equal") -// require.DeepSSZEqual(t, finalizedBlockHeader.Header.BodyRoot, updateFinalizedHeaderBeacon.BodyRoot, "Finalized header body root is not equal") -// require.Equal(t, lightClient.FinalityBranchNumOfLeaves, len(update.FinalityBranch), "Invalid finality branch leaves") -// -// finalityBranch, err := l.AttestedState.FinalizedRootProof(l.Ctx) -// require.NoError(t, err) -// for i, leaf := range update.FinalityBranch { -// require.DeepSSZEqual(t, finalityBranch[i], leaf, "Leaf is not equal") -// } -// }) -// }) -// -// t.Run("Capella", func(t *testing.T) { -// -// t.Run("FinalizedBlock Not Nil", func(t *testing.T) { -// l := util.NewTestLightClient(t).SetupTestCapella(false) -// update, err := lightClient.NewLightClientFinalityUpdateFromBeaconState(l.Ctx, l.State, l.Block, l.AttestedState, l.AttestedBlock, l.FinalizedBlock) -// require.NoError(t, err) -// require.NotNil(t, update, "update is nil") -// -// require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot, "Signature slot is not equal") -// -// l.CheckSyncAggregate(update.SyncAggregate) -// l.CheckAttestedHeader(update.AttestedHeader) -// -// finalizedBlockHeader, err := l.FinalizedBlock.Header() -// require.NoError(t, err) -// require.NotNil(t, update.FinalizedHeader, "Finalized header is nil") -// updateFinalizedHeaderBeacon, err := update.FinalizedHeader.GetBeacon() -// require.NoError(t, err) -// require.Equal(t, finalizedBlockHeader.Header.Slot, updateFinalizedHeaderBeacon.Slot, "Finalized header slot is not equal") -// require.Equal(t, finalizedBlockHeader.Header.ProposerIndex, updateFinalizedHeaderBeacon.ProposerIndex, "Finalized header proposer index is not equal") -// require.DeepSSZEqual(t, finalizedBlockHeader.Header.ParentRoot, updateFinalizedHeaderBeacon.ParentRoot, "Finalized header parent root is not equal") -// require.DeepSSZEqual(t, finalizedBlockHeader.Header.StateRoot, updateFinalizedHeaderBeacon.StateRoot, "Finalized header state root is not equal") -// require.DeepSSZEqual(t, finalizedBlockHeader.Header.BodyRoot, updateFinalizedHeaderBeacon.BodyRoot, "Finalized header body root is not equal") -// require.Equal(t, lightClient.FinalityBranchNumOfLeaves, len(update.FinalityBranch), "Invalid finality branch leaves") -// finalityBranch, err := l.AttestedState.FinalizedRootProof(l.Ctx) -// require.NoError(t, err) -// for i, leaf := range update.FinalityBranch { -// require.DeepSSZEqual(t, finalityBranch[i], leaf, "Leaf is not equal") -// } -// -// // Check Execution BlockHash -// payloadInterface, err := l.FinalizedBlock.Block().Body().Execution() -// require.NoError(t, err) -// transactionsRoot, err := payloadInterface.TransactionsRoot() -// if errors.Is(err, consensustypes.ErrUnsupportedField) { -// transactions, err := payloadInterface.Transactions() -// require.NoError(t, err) -// transactionsRootArray, err := ssz.TransactionsRoot(transactions) -// require.NoError(t, err) -// transactionsRoot = transactionsRootArray[:] -// } else { -// require.NoError(t, err) -// } -// withdrawalsRoot, err := payloadInterface.WithdrawalsRoot() -// if errors.Is(err, consensustypes.ErrUnsupportedField) { -// withdrawals, err := payloadInterface.Withdrawals() -// require.NoError(t, err) -// withdrawalsRootArray, err := ssz.WithdrawalSliceRoot(withdrawals, fieldparams.MaxWithdrawalsPerPayload) -// require.NoError(t, err) -// withdrawalsRoot = withdrawalsRootArray[:] -// } else { -// require.NoError(t, err) -// } -// execution := &v11.ExecutionPayloadHeaderCapella{ -// ParentHash: payloadInterface.ParentHash(), -// FeeRecipient: payloadInterface.FeeRecipient(), -// StateRoot: payloadInterface.StateRoot(), -// ReceiptsRoot: payloadInterface.ReceiptsRoot(), -// LogsBloom: payloadInterface.LogsBloom(), -// PrevRandao: payloadInterface.PrevRandao(), -// BlockNumber: payloadInterface.BlockNumber(), -// GasLimit: payloadInterface.GasLimit(), -// GasUsed: payloadInterface.GasUsed(), -// Timestamp: payloadInterface.Timestamp(), -// ExtraData: payloadInterface.ExtraData(), -// BaseFeePerGas: payloadInterface.BaseFeePerGas(), -// BlockHash: payloadInterface.BlockHash(), -// TransactionsRoot: transactionsRoot, -// WithdrawalsRoot: withdrawalsRoot, -// } -// require.DeepSSZEqual(t, execution, update.FinalizedHeader.GetHeaderCapella().Execution, "Finalized Block Execution is not equal") -// }) -// -// t.Run("FinalizedBlock In Previous Fork", func(t *testing.T) { -// l := util.NewTestLightClient(t).SetupTestCapellaFinalizedBlockAltair(false) -// update, err := lightClient.NewLightClientFinalityUpdateFromBeaconState(l.Ctx, l.State, l.Block, l.AttestedState, l.AttestedBlock, l.FinalizedBlock) -// require.NoError(t, err) -// require.NotNil(t, update, "update is nil") -// -// require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot, "Signature slot is not equal") -// -// l.CheckSyncAggregate(update.SyncAggregate) -// l.CheckAttestedHeader(update.AttestedHeader) -// -// finalizedBlockHeader, err := l.FinalizedBlock.Header() -// require.NoError(t, err) -// require.NotNil(t, update.FinalizedHeader, "Finalized header is nil") -// updateFinalizedHeaderBeacon, err := update.FinalizedHeader.GetBeacon() -// require.NoError(t, err) -// require.Equal(t, finalizedBlockHeader.Header.Slot, updateFinalizedHeaderBeacon.Slot, "Finalized header slot is not equal") -// require.Equal(t, finalizedBlockHeader.Header.ProposerIndex, updateFinalizedHeaderBeacon.ProposerIndex, "Finalized header proposer index is not equal") -// require.DeepSSZEqual(t, finalizedBlockHeader.Header.ParentRoot, updateFinalizedHeaderBeacon.ParentRoot, "Finalized header parent root is not equal") -// require.DeepSSZEqual(t, finalizedBlockHeader.Header.StateRoot, updateFinalizedHeaderBeacon.StateRoot, "Finalized header state root is not equal") -// require.DeepSSZEqual(t, finalizedBlockHeader.Header.BodyRoot, updateFinalizedHeaderBeacon.BodyRoot, "Finalized header body root is not equal") -// require.Equal(t, lightClient.FinalityBranchNumOfLeaves, len(update.FinalityBranch), "Invalid finality branch leaves") -// finalityBranch, err := l.AttestedState.FinalizedRootProof(l.Ctx) -// require.NoError(t, err) -// for i, leaf := range update.FinalityBranch { -// require.DeepSSZEqual(t, finalityBranch[i], leaf, "Leaf is not equal") -// } -// }) -// }) -// -// t.Run("Deneb", func(t *testing.T) { -// -// t.Run("FinalizedBlock Not Nil", func(t *testing.T) { -// l := util.NewTestLightClient(t).SetupTestDeneb(false) -// -// update, err := lightClient.NewLightClientFinalityUpdateFromBeaconState(l.Ctx, l.State, l.Block, l.AttestedState, l.AttestedBlock, l.FinalizedBlock) -// require.NoError(t, err) -// require.NotNil(t, update, "update is nil") -// -// require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot, "Signature slot is not equal") -// -// l.CheckSyncAggregate(update.SyncAggregate) -// l.CheckAttestedHeader(update.AttestedHeader) -// -// //zeroHash := params.BeaconConfig().ZeroHash[:] -// finalizedBlockHeader, err := l.FinalizedBlock.Header() -// require.NoError(t, err) -// require.NotNil(t, update.FinalizedHeader, "Finalized header is nil") -// updateFinalizedHeaderBeacon, err := update.FinalizedHeader.GetBeacon() -// require.NoError(t, err) -// require.Equal(t, finalizedBlockHeader.Header.Slot, updateFinalizedHeaderBeacon.Slot, "Finalized header slot is not equal") -// require.Equal(t, finalizedBlockHeader.Header.ProposerIndex, updateFinalizedHeaderBeacon.ProposerIndex, "Finalized header proposer index is not equal") -// require.DeepSSZEqual(t, finalizedBlockHeader.Header.ParentRoot, updateFinalizedHeaderBeacon.ParentRoot, "Finalized header parent root is not equal") -// require.DeepSSZEqual(t, finalizedBlockHeader.Header.StateRoot, updateFinalizedHeaderBeacon.StateRoot, "Finalized header state root is not equal") -// require.DeepSSZEqual(t, finalizedBlockHeader.Header.BodyRoot, updateFinalizedHeaderBeacon.BodyRoot, "Finalized header body root is not equal") -// require.Equal(t, lightClient.FinalityBranchNumOfLeaves, len(update.FinalityBranch), "Invalid finality branch leaves") -// finalityBranch, err := l.AttestedState.FinalizedRootProof(l.Ctx) -// require.NoError(t, err) -// for i, leaf := range update.FinalityBranch { -// require.DeepSSZEqual(t, finalityBranch[i], leaf, "Leaf is not equal") -// } -// -// // Check Execution BlockHash -// payloadInterface, err := l.FinalizedBlock.Block().Body().Execution() -// require.NoError(t, err) -// transactionsRoot, err := payloadInterface.TransactionsRoot() -// if errors.Is(err, consensustypes.ErrUnsupportedField) { -// transactions, err := payloadInterface.Transactions() -// require.NoError(t, err) -// transactionsRootArray, err := ssz.TransactionsRoot(transactions) -// require.NoError(t, err) -// transactionsRoot = transactionsRootArray[:] -// } else { -// require.NoError(t, err) -// } -// withdrawalsRoot, err := payloadInterface.WithdrawalsRoot() -// if errors.Is(err, consensustypes.ErrUnsupportedField) { -// withdrawals, err := payloadInterface.Withdrawals() -// require.NoError(t, err) -// withdrawalsRootArray, err := ssz.WithdrawalSliceRoot(withdrawals, fieldparams.MaxWithdrawalsPerPayload) -// require.NoError(t, err) -// withdrawalsRoot = withdrawalsRootArray[:] -// } else { -// require.NoError(t, err) -// } -// execution := &v11.ExecutionPayloadHeaderDeneb{ -// ParentHash: payloadInterface.ParentHash(), -// FeeRecipient: payloadInterface.FeeRecipient(), -// StateRoot: payloadInterface.StateRoot(), -// ReceiptsRoot: payloadInterface.ReceiptsRoot(), -// LogsBloom: payloadInterface.LogsBloom(), -// PrevRandao: payloadInterface.PrevRandao(), -// BlockNumber: payloadInterface.BlockNumber(), -// GasLimit: payloadInterface.GasLimit(), -// GasUsed: payloadInterface.GasUsed(), -// Timestamp: payloadInterface.Timestamp(), -// ExtraData: payloadInterface.ExtraData(), -// BaseFeePerGas: payloadInterface.BaseFeePerGas(), -// BlockHash: payloadInterface.BlockHash(), -// TransactionsRoot: transactionsRoot, -// WithdrawalsRoot: withdrawalsRoot, -// } -// require.DeepSSZEqual(t, execution, update.FinalizedHeader.GetHeaderDeneb().Execution, "Finalized Block Execution is not equal") -// }) -// -// t.Run("FinalizedBlock In Previous Fork", func(t *testing.T) { -// l := util.NewTestLightClient(t).SetupTestDenebFinalizedBlockCapella(false) -// -// update, err := lightClient.NewLightClientFinalityUpdateFromBeaconState(l.Ctx, l.State, l.Block, l.AttestedState, l.AttestedBlock, l.FinalizedBlock) -// require.NoError(t, err) -// require.NotNil(t, update, "update is nil") -// -// require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot, "Signature slot is not equal") -// -// l.CheckSyncAggregate(update.SyncAggregate) -// l.CheckAttestedHeader(update.AttestedHeader) -// -// finalizedBlockHeader, err := l.FinalizedBlock.Header() -// require.NoError(t, err) -// require.NotNil(t, update.FinalizedHeader, "Finalized header is nil") -// updateFinalizedHeaderBeacon, err := update.FinalizedHeader.GetBeacon() -// require.NoError(t, err) -// require.Equal(t, finalizedBlockHeader.Header.Slot, updateFinalizedHeaderBeacon.Slot, "Finalized header slot is not equal") -// require.Equal(t, finalizedBlockHeader.Header.ProposerIndex, updateFinalizedHeaderBeacon.ProposerIndex, "Finalized header proposer index is not equal") -// require.DeepSSZEqual(t, finalizedBlockHeader.Header.ParentRoot, updateFinalizedHeaderBeacon.ParentRoot, "Finalized header parent root is not equal") -// require.DeepSSZEqual(t, finalizedBlockHeader.Header.StateRoot, updateFinalizedHeaderBeacon.StateRoot, "Finalized header state root is not equal") -// require.DeepSSZEqual(t, finalizedBlockHeader.Header.BodyRoot, updateFinalizedHeaderBeacon.BodyRoot, "Finalized header body root is not equal") -// require.Equal(t, lightClient.FinalityBranchNumOfLeaves, len(update.FinalityBranch), "Invalid finality branch leaves") -// finalityBranch, err := l.AttestedState.FinalizedRootProof(l.Ctx) -// require.NoError(t, err) -// for i, leaf := range update.FinalityBranch { -// require.DeepSSZEqual(t, finalityBranch[i], leaf, "Leaf is not equal") -// } -// -// // Check Execution BlockHash -// payloadInterface, err := l.FinalizedBlock.Block().Body().Execution() -// require.NoError(t, err) -// transactionsRoot, err := payloadInterface.TransactionsRoot() -// if errors.Is(err, consensustypes.ErrUnsupportedField) { -// transactions, err := payloadInterface.Transactions() -// require.NoError(t, err) -// transactionsRootArray, err := ssz.TransactionsRoot(transactions) -// require.NoError(t, err) -// transactionsRoot = transactionsRootArray[:] -// } else { -// require.NoError(t, err) -// } -// withdrawalsRoot, err := payloadInterface.WithdrawalsRoot() -// if errors.Is(err, consensustypes.ErrUnsupportedField) { -// withdrawals, err := payloadInterface.Withdrawals() -// require.NoError(t, err) -// withdrawalsRootArray, err := ssz.WithdrawalSliceRoot(withdrawals, fieldparams.MaxWithdrawalsPerPayload) -// require.NoError(t, err) -// withdrawalsRoot = withdrawalsRootArray[:] -// } else { -// require.NoError(t, err) -// } -// execution := &v11.ExecutionPayloadHeaderCapella{ -// ParentHash: payloadInterface.ParentHash(), -// FeeRecipient: payloadInterface.FeeRecipient(), -// StateRoot: payloadInterface.StateRoot(), -// ReceiptsRoot: payloadInterface.ReceiptsRoot(), -// LogsBloom: payloadInterface.LogsBloom(), -// PrevRandao: payloadInterface.PrevRandao(), -// BlockNumber: payloadInterface.BlockNumber(), -// GasLimit: payloadInterface.GasLimit(), -// GasUsed: payloadInterface.GasUsed(), -// Timestamp: payloadInterface.Timestamp(), -// ExtraData: payloadInterface.ExtraData(), -// BaseFeePerGas: payloadInterface.BaseFeePerGas(), -// BlockHash: payloadInterface.BlockHash(), -// TransactionsRoot: transactionsRoot, -// WithdrawalsRoot: withdrawalsRoot, -// } -// require.DeepSSZEqual(t, execution, update.FinalizedHeader.GetHeaderCapella().Execution, "Finalized Block Execution is not equal") -// }) -// }) -//} -// //func TestLightClient_BlockToLightClientHeader(t *testing.T) { // t.Run("Altair", func(t *testing.T) { // l := util.NewTestLightClient(t).SetupTestAltair() diff --git a/testing/util/lightclient.go b/testing/util/lightclient.go index 3a41d2b5150f..6c11a4c7d497 100644 --- a/testing/util/lightclient.go +++ b/testing/util/lightclient.go @@ -820,14 +820,14 @@ func (l *TestLightClient) CheckAttestedHeader(header interfaces.LightClientHeade updateAttestedHeaderExecution, err := header.Execution() require.NoError(l.T, err) - require.DeepSSZEqual(l.T, execution, updateAttestedHeaderExecution, "Attested Block Execution is not equal") + require.DeepSSZEqual(l.T, execution, updateAttestedHeaderExecution.Proto(), "Attested Block Execution is not equal") executionPayloadProof, err := blocks.PayloadProof(l.Ctx, l.AttestedBlock.Block()) require.NoError(l.T, err) updateAttestedHeaderExecutionBranch, err := header.ExecutionBranch() require.NoError(l.T, err) for i, leaf := range updateAttestedHeaderExecutionBranch { - require.DeepSSZEqual(l.T, executionPayloadProof[i], leaf, "Leaf is not equal") + require.DeepSSZEqual(l.T, executionPayloadProof[i], leaf[:], "Leaf is not equal") } } @@ -874,14 +874,14 @@ func (l *TestLightClient) CheckAttestedHeader(header interfaces.LightClientHeade updateAttestedHeaderExecution, err := header.Execution() require.NoError(l.T, err) - require.DeepSSZEqual(l.T, execution, updateAttestedHeaderExecution, "Attested Block Execution is not equal") + require.DeepSSZEqual(l.T, execution, updateAttestedHeaderExecution.Proto(), "Attested Block Execution is not equal") executionPayloadProof, err := blocks.PayloadProof(l.Ctx, l.AttestedBlock.Block()) require.NoError(l.T, err) updateAttestedHeaderExecutionBranch, err := header.ExecutionBranch() require.NoError(l.T, err) for i, leaf := range updateAttestedHeaderExecutionBranch { - require.DeepSSZEqual(l.T, executionPayloadProof[i], leaf, "Leaf is not equal") + require.DeepSSZEqual(l.T, executionPayloadProof[i], leaf[:], "Leaf is not equal") } } } From ba64324b81a129ceeb77b4cbcce47afd10f560ea Mon Sep 17 00:00:00 2001 From: Inspector-Butters Date: Thu, 24 Oct 2024 12:37:32 +0200 Subject: [PATCH 25/35] core tests fixed --- beacon-chain/core/light-client/BUILD.bazel | 7 + beacon-chain/core/light-client/lightclient.go | 21 +- .../core/light-client/lightclient_test.go | 1339 +++++++++-------- beacon-chain/db/kv/BUILD.bazel | 4 +- beacon-chain/rpc/eth/light-client/BUILD.bazel | 8 + testing/util/lightclient.go | 12 +- 6 files changed, 723 insertions(+), 668 deletions(-) diff --git a/beacon-chain/core/light-client/BUILD.bazel b/beacon-chain/core/light-client/BUILD.bazel index f8e8bba99f7c..ecf6b8f71a75 100644 --- a/beacon-chain/core/light-client/BUILD.bazel +++ b/beacon-chain/core/light-client/BUILD.bazel @@ -30,7 +30,14 @@ go_test( srcs = ["lightclient_test.go"], deps = [ ":go_default_library", + "//config/fieldparams:go_default_library", + "//consensus-types:go_default_library", + "//consensus-types/blocks:go_default_library", + "//encoding/ssz:go_default_library", + "//proto/engine/v1:go_default_library", + "//proto/prysm/v1alpha1:go_default_library", "//testing/require:go_default_library", "//testing/util:go_default_library", + "@com_github_pkg_errors//:go_default_library", ], ) diff --git a/beacon-chain/core/light-client/lightclient.go b/beacon-chain/core/light-client/lightclient.go index 90ed96876ee9..4cce693c9ec0 100644 --- a/beacon-chain/core/light-client/lightclient.go +++ b/beacon-chain/core/light-client/lightclient.go @@ -388,15 +388,18 @@ func BlockToLightClientHeader( var payloadProof [][]byte if blockEpoch < params.BeaconConfig().CapellaForkEpoch { - var ok bool - - p, err := execution.EmptyExecutionPayload(version.Capella) - if err != nil { - return nil, errors.Wrap(err, "could not get payload header") - } - payloadHeader, ok = p.(*enginev1.ExecutionPayloadHeaderCapella) - if !ok { - return nil, errors.Wrapf(err, "payload header type %T is not %T", payloadHeader, &enginev1.ExecutionPayloadHeaderCapella{}) + payloadHeader = &enginev1.ExecutionPayloadHeaderCapella{ + ParentHash: make([]byte, fieldparams.RootLength), + FeeRecipient: make([]byte, fieldparams.FeeRecipientLength), + StateRoot: make([]byte, fieldparams.RootLength), + ReceiptsRoot: make([]byte, fieldparams.RootLength), + LogsBloom: make([]byte, fieldparams.LogsBloomLength), + PrevRandao: make([]byte, fieldparams.RootLength), + ExtraData: make([]byte, 0), + BaseFeePerGas: make([]byte, fieldparams.RootLength), + BlockHash: make([]byte, fieldparams.RootLength), + TransactionsRoot: make([]byte, fieldparams.RootLength), + WithdrawalsRoot: make([]byte, fieldparams.RootLength), } payloadProof = emptyPayloadProof() } else { diff --git a/beacon-chain/core/light-client/lightclient_test.go b/beacon-chain/core/light-client/lightclient_test.go index 65124ce59756..7d787b1cb522 100644 --- a/beacon-chain/core/light-client/lightclient_test.go +++ b/beacon-chain/core/light-client/lightclient_test.go @@ -1,9 +1,17 @@ package light_client_test import ( + "reflect" "testing" + "github.com/pkg/errors" lightClient "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/light-client" + fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams" + consensustypes "github.com/prysmaticlabs/prysm/v5/consensus-types" + "github.com/prysmaticlabs/prysm/v5/consensus-types/blocks" + "github.com/prysmaticlabs/prysm/v5/encoding/ssz" + v11 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1" + pb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" "github.com/prysmaticlabs/prysm/v5/testing/require" "github.com/prysmaticlabs/prysm/v5/testing/util" ) @@ -67,6 +75,7 @@ func TestLightClient_NewLightClientFinalityUpdateFromBeaconState(t *testing.T) { //zeroHash := params.BeaconConfig().ZeroHash[:] require.NotNil(t, update.FinalizedHeader(), "Finalized header is nil") + require.Equal(t, reflect.TypeOf(update.FinalizedHeader().Proto()), reflect.TypeOf(&pb.LightClientHeaderAltair{}), "Finalized header is not Altair") updateFinalizedHeaderBeacon := update.FinalizedHeader().Beacon() require.Equal(t, finalizedBlockHeader.Header.Slot, updateFinalizedHeaderBeacon.Slot, "Finalized header slot is not equal") require.Equal(t, finalizedBlockHeader.Header.ProposerIndex, updateFinalizedHeaderBeacon.ProposerIndex, "Finalized header proposer index is not equal") @@ -85,657 +94,685 @@ func TestLightClient_NewLightClientFinalityUpdateFromBeaconState(t *testing.T) { t.Run("Capella", func(t *testing.T) { - //t.Run("FinalizedBlock Not Nil", func(t *testing.T) { - // l := util.NewTestLightClient(t).SetupTestCapella(false) - // update, err := lightClient.NewLightClientFinalityUpdateFromBeaconState(l.Ctx, l.State.Slot(), l.State, l.Block, l.AttestedState, l.AttestedBlock, l.FinalizedBlock) - // require.NoError(t, err) - // require.NotNil(t, update, "update is nil") - // - // require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot(), "Signature slot is not equal") - // - // l.CheckSyncAggregate(update.SyncAggregate()) - // l.CheckAttestedHeader(update.AttestedHeader()) - // - // finalizedBlockHeader, err := l.FinalizedBlock.Header() - // require.NoError(t, err) - // require.NotNil(t, update.FinalizedHeader(), "Finalized header is nil") - // updateFinalizedHeaderBeacon := update.FinalizedHeader().Beacon() - // require.Equal(t, finalizedBlockHeader.Header.Slot, updateFinalizedHeaderBeacon.Slot, "Finalized header slot is not equal") - // require.Equal(t, finalizedBlockHeader.Header.ProposerIndex, updateFinalizedHeaderBeacon.ProposerIndex, "Finalized header proposer index is not equal") - // require.DeepSSZEqual(t, finalizedBlockHeader.Header.ParentRoot, updateFinalizedHeaderBeacon.ParentRoot, "Finalized header parent root is not equal") - // require.DeepSSZEqual(t, finalizedBlockHeader.Header.StateRoot, updateFinalizedHeaderBeacon.StateRoot, "Finalized header state root is not equal") - // require.DeepSSZEqual(t, finalizedBlockHeader.Header.BodyRoot, updateFinalizedHeaderBeacon.BodyRoot, "Finalized header body root is not equal") - // require.Equal(t, lightClient.FinalityBranchNumOfLeaves, len(update.FinalityBranch()), "Invalid finality branch leaves") - // finalityBranch, err := l.AttestedState.FinalizedRootProof(l.Ctx) - // require.NoError(t, err) - // for i, leaf := range update.FinalityBranch() { - // require.DeepSSZEqual(t, finalityBranch[i], leaf[:], "Leaf is not equal") - // } - // - // // Check Execution BlockHash - // payloadInterface, err := l.FinalizedBlock.Block().Body().Execution() - // require.NoError(t, err) - // transactionsRoot, err := payloadInterface.TransactionsRoot() - // if errors.Is(err, consensustypes.ErrUnsupportedField) { - // transactions, err := payloadInterface.Transactions() - // require.NoError(t, err) - // transactionsRootArray, err := ssz.TransactionsRoot(transactions) - // require.NoError(t, err) - // transactionsRoot = transactionsRootArray[:] - // } else { - // require.NoError(t, err) - // } - // withdrawalsRoot, err := payloadInterface.WithdrawalsRoot() - // if errors.Is(err, consensustypes.ErrUnsupportedField) { - // withdrawals, err := payloadInterface.Withdrawals() - // require.NoError(t, err) - // withdrawalsRootArray, err := ssz.WithdrawalSliceRoot(withdrawals, fieldparams.MaxWithdrawalsPerPayload) - // require.NoError(t, err) - // withdrawalsRoot = withdrawalsRootArray[:] - // } else { - // require.NoError(t, err) - // } - // execution := &v11.ExecutionPayloadHeaderCapella{ - // ParentHash: payloadInterface.ParentHash(), - // FeeRecipient: payloadInterface.FeeRecipient(), - // StateRoot: payloadInterface.StateRoot(), - // ReceiptsRoot: payloadInterface.ReceiptsRoot(), - // LogsBloom: payloadInterface.LogsBloom(), - // PrevRandao: payloadInterface.PrevRandao(), - // BlockNumber: payloadInterface.BlockNumber(), - // GasLimit: payloadInterface.GasLimit(), - // GasUsed: payloadInterface.GasUsed(), - // Timestamp: payloadInterface.Timestamp(), - // ExtraData: payloadInterface.ExtraData(), - // BaseFeePerGas: payloadInterface.BaseFeePerGas(), - // BlockHash: payloadInterface.BlockHash(), - // TransactionsRoot: transactionsRoot, - // WithdrawalsRoot: withdrawalsRoot, - // } - // updateExecution, err := update.FinalizedHeader().Execution() - // require.NoError(t, err) - // require.DeepSSZEqual(t, execution, updateExecution, "Finalized Block Execution is not equal") - //}) - - // t.Run("FinalizedBlock In Previous Fork", func(t *testing.T) { - // l := util.NewTestLightClient(t).SetupTestCapellaFinalizedBlockAltair(false) - // update, err := lightClient.NewLightClientFinalityUpdateFromBeaconState(l.Ctx, l.State, l.Block, l.AttestedState, l.AttestedBlock, l.FinalizedBlock) - // require.NoError(t, err) - // require.NotNil(t, update, "update is nil") - // - // require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot, "Signature slot is not equal") - // - // l.CheckSyncAggregate(update.SyncAggregate) - // l.CheckAttestedHeader(update.AttestedHeader) - // - // finalizedBlockHeader, err := l.FinalizedBlock.Header() - // require.NoError(t, err) - // require.NotNil(t, update.FinalizedHeader, "Finalized header is nil") - // updateFinalizedHeaderBeacon, err := update.FinalizedHeader.GetBeacon() - // require.NoError(t, err) - // require.Equal(t, finalizedBlockHeader.Header.Slot, updateFinalizedHeaderBeacon.Slot, "Finalized header slot is not equal") - // require.Equal(t, finalizedBlockHeader.Header.ProposerIndex, updateFinalizedHeaderBeacon.ProposerIndex, "Finalized header proposer index is not equal") - // require.DeepSSZEqual(t, finalizedBlockHeader.Header.ParentRoot, updateFinalizedHeaderBeacon.ParentRoot, "Finalized header parent root is not equal") - // require.DeepSSZEqual(t, finalizedBlockHeader.Header.StateRoot, updateFinalizedHeaderBeacon.StateRoot, "Finalized header state root is not equal") - // require.DeepSSZEqual(t, finalizedBlockHeader.Header.BodyRoot, updateFinalizedHeaderBeacon.BodyRoot, "Finalized header body root is not equal") - // require.Equal(t, lightClient.FinalityBranchNumOfLeaves, len(update.FinalityBranch), "Invalid finality branch leaves") - // finalityBranch, err := l.AttestedState.FinalizedRootProof(l.Ctx) - // require.NoError(t, err) - // for i, leaf := range update.FinalityBranch { - // require.DeepSSZEqual(t, finalityBranch[i], leaf, "Leaf is not equal") - // } - // }) + t.Run("FinalizedBlock Not Nil", func(t *testing.T) { + l := util.NewTestLightClient(t).SetupTestCapella(false) + update, err := lightClient.NewLightClientFinalityUpdateFromBeaconState(l.Ctx, l.State.Slot(), l.State, l.Block, l.AttestedState, l.AttestedBlock, l.FinalizedBlock) + require.NoError(t, err) + require.NotNil(t, update, "update is nil") + + require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot(), "Signature slot is not equal") + + l.CheckSyncAggregate(update.SyncAggregate()) + l.CheckAttestedHeader(update.AttestedHeader()) + + finalizedBlockHeader, err := l.FinalizedBlock.Header() + require.NoError(t, err) + require.NotNil(t, update.FinalizedHeader(), "Finalized header is nil") + require.Equal(t, reflect.TypeOf(update.FinalizedHeader().Proto()), reflect.TypeOf(&pb.LightClientHeaderCapella{}), "Finalized header is not Capella") + updateFinalizedHeaderBeacon := update.FinalizedHeader().Beacon() + require.Equal(t, finalizedBlockHeader.Header.Slot, updateFinalizedHeaderBeacon.Slot, "Finalized header slot is not equal") + require.Equal(t, finalizedBlockHeader.Header.ProposerIndex, updateFinalizedHeaderBeacon.ProposerIndex, "Finalized header proposer index is not equal") + require.DeepSSZEqual(t, finalizedBlockHeader.Header.ParentRoot, updateFinalizedHeaderBeacon.ParentRoot, "Finalized header parent root is not equal") + require.DeepSSZEqual(t, finalizedBlockHeader.Header.StateRoot, updateFinalizedHeaderBeacon.StateRoot, "Finalized header state root is not equal") + require.DeepSSZEqual(t, finalizedBlockHeader.Header.BodyRoot, updateFinalizedHeaderBeacon.BodyRoot, "Finalized header body root is not equal") + require.Equal(t, lightClient.FinalityBranchNumOfLeaves, len(update.FinalityBranch()), "Invalid finality branch leaves") + finalityBranch, err := l.AttestedState.FinalizedRootProof(l.Ctx) + require.NoError(t, err) + for i, leaf := range update.FinalityBranch() { + require.DeepSSZEqual(t, finalityBranch[i], leaf[:], "Leaf is not equal") + } + + // Check Execution BlockHash + payloadInterface, err := l.FinalizedBlock.Block().Body().Execution() + require.NoError(t, err) + transactionsRoot, err := payloadInterface.TransactionsRoot() + if errors.Is(err, consensustypes.ErrUnsupportedField) { + transactions, err := payloadInterface.Transactions() + require.NoError(t, err) + transactionsRootArray, err := ssz.TransactionsRoot(transactions) + require.NoError(t, err) + transactionsRoot = transactionsRootArray[:] + } else { + require.NoError(t, err) + } + withdrawalsRoot, err := payloadInterface.WithdrawalsRoot() + if errors.Is(err, consensustypes.ErrUnsupportedField) { + withdrawals, err := payloadInterface.Withdrawals() + require.NoError(t, err) + withdrawalsRootArray, err := ssz.WithdrawalSliceRoot(withdrawals, fieldparams.MaxWithdrawalsPerPayload) + require.NoError(t, err) + withdrawalsRoot = withdrawalsRootArray[:] + } else { + require.NoError(t, err) + } + execution := &v11.ExecutionPayloadHeaderCapella{ + ParentHash: payloadInterface.ParentHash(), + FeeRecipient: payloadInterface.FeeRecipient(), + StateRoot: payloadInterface.StateRoot(), + ReceiptsRoot: payloadInterface.ReceiptsRoot(), + LogsBloom: payloadInterface.LogsBloom(), + PrevRandao: payloadInterface.PrevRandao(), + BlockNumber: payloadInterface.BlockNumber(), + GasLimit: payloadInterface.GasLimit(), + GasUsed: payloadInterface.GasUsed(), + Timestamp: payloadInterface.Timestamp(), + ExtraData: payloadInterface.ExtraData(), + BaseFeePerGas: payloadInterface.BaseFeePerGas(), + BlockHash: payloadInterface.BlockHash(), + TransactionsRoot: transactionsRoot, + WithdrawalsRoot: withdrawalsRoot, + } + updateExecution, err := update.FinalizedHeader().Execution() + require.NoError(t, err) + require.DeepSSZEqual(t, execution, updateExecution.Proto(), "Finalized Block Execution is not equal") + }) + + t.Run("FinalizedBlock In Previous Fork", func(t *testing.T) { + l := util.NewTestLightClient(t).SetupTestCapellaFinalizedBlockAltair(false) + update, err := lightClient.NewLightClientFinalityUpdateFromBeaconState(l.Ctx, l.State.Slot(), l.State, l.Block, l.AttestedState, l.AttestedBlock, l.FinalizedBlock) + require.NoError(t, err) + require.NotNil(t, update, "update is nil") + + require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot(), "Signature slot is not equal") + + l.CheckSyncAggregate(update.SyncAggregate()) + l.CheckAttestedHeader(update.AttestedHeader()) + + finalizedBlockHeader, err := l.FinalizedBlock.Header() + require.NoError(t, err) + require.NotNil(t, update.FinalizedHeader(), "Finalized header is nil") + require.Equal(t, reflect.TypeOf(update.FinalizedHeader().Proto()), reflect.TypeOf(&pb.LightClientHeaderCapella{}), "Finalized header is not Capella") + updateFinalizedHeaderBeacon := update.FinalizedHeader().Beacon() + require.Equal(t, finalizedBlockHeader.Header.Slot, updateFinalizedHeaderBeacon.Slot, "Finalized header slot is not equal") + require.Equal(t, finalizedBlockHeader.Header.ProposerIndex, updateFinalizedHeaderBeacon.ProposerIndex, "Finalized header proposer index is not equal") + require.DeepSSZEqual(t, finalizedBlockHeader.Header.ParentRoot, updateFinalizedHeaderBeacon.ParentRoot, "Finalized header parent root is not equal") + require.DeepSSZEqual(t, finalizedBlockHeader.Header.StateRoot, updateFinalizedHeaderBeacon.StateRoot, "Finalized header state root is not equal") + require.DeepSSZEqual(t, finalizedBlockHeader.Header.BodyRoot, updateFinalizedHeaderBeacon.BodyRoot, "Finalized header body root is not equal") + require.Equal(t, lightClient.FinalityBranchNumOfLeaves, len(update.FinalityBranch()), "Invalid finality branch leaves") + finalityBranch, err := l.AttestedState.FinalizedRootProof(l.Ctx) + require.NoError(t, err) + for i, leaf := range update.FinalityBranch() { + require.DeepSSZEqual(t, finalityBranch[i], leaf[:], "Leaf is not equal") + } + }) + }) + + t.Run("Deneb", func(t *testing.T) { + + t.Run("FinalizedBlock Not Nil", func(t *testing.T) { + l := util.NewTestLightClient(t).SetupTestDeneb(false) + + update, err := lightClient.NewLightClientFinalityUpdateFromBeaconState(l.Ctx, l.State.Slot(), l.State, l.Block, l.AttestedState, l.AttestedBlock, l.FinalizedBlock) + require.NoError(t, err) + require.NotNil(t, update, "update is nil") + + require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot(), "Signature slot is not equal") + + l.CheckSyncAggregate(update.SyncAggregate()) + l.CheckAttestedHeader(update.AttestedHeader()) + + //zeroHash := params.BeaconConfig().ZeroHash[:] + finalizedBlockHeader, err := l.FinalizedBlock.Header() + require.NoError(t, err) + require.NotNil(t, update.FinalizedHeader(), "Finalized header is nil") + updateFinalizedHeaderBeacon := update.FinalizedHeader().Beacon() + require.Equal(t, finalizedBlockHeader.Header.Slot, updateFinalizedHeaderBeacon.Slot, "Finalized header slot is not equal") + require.Equal(t, finalizedBlockHeader.Header.ProposerIndex, updateFinalizedHeaderBeacon.ProposerIndex, "Finalized header proposer index is not equal") + require.DeepSSZEqual(t, finalizedBlockHeader.Header.ParentRoot, updateFinalizedHeaderBeacon.ParentRoot, "Finalized header parent root is not equal") + require.DeepSSZEqual(t, finalizedBlockHeader.Header.StateRoot, updateFinalizedHeaderBeacon.StateRoot, "Finalized header state root is not equal") + require.DeepSSZEqual(t, finalizedBlockHeader.Header.BodyRoot, updateFinalizedHeaderBeacon.BodyRoot, "Finalized header body root is not equal") + require.Equal(t, lightClient.FinalityBranchNumOfLeaves, len(update.FinalityBranch()), "Invalid finality branch leaves") + finalityBranch, err := l.AttestedState.FinalizedRootProof(l.Ctx) + require.NoError(t, err) + for i, leaf := range update.FinalityBranch() { + require.DeepSSZEqual(t, finalityBranch[i], leaf[:], "Leaf is not equal") + } + + // Check Execution BlockHash + payloadInterface, err := l.FinalizedBlock.Block().Body().Execution() + require.NoError(t, err) + transactionsRoot, err := payloadInterface.TransactionsRoot() + if errors.Is(err, consensustypes.ErrUnsupportedField) { + transactions, err := payloadInterface.Transactions() + require.NoError(t, err) + transactionsRootArray, err := ssz.TransactionsRoot(transactions) + require.NoError(t, err) + transactionsRoot = transactionsRootArray[:] + } else { + require.NoError(t, err) + } + withdrawalsRoot, err := payloadInterface.WithdrawalsRoot() + if errors.Is(err, consensustypes.ErrUnsupportedField) { + withdrawals, err := payloadInterface.Withdrawals() + require.NoError(t, err) + withdrawalsRootArray, err := ssz.WithdrawalSliceRoot(withdrawals, fieldparams.MaxWithdrawalsPerPayload) + require.NoError(t, err) + withdrawalsRoot = withdrawalsRootArray[:] + } else { + require.NoError(t, err) + } + execution := &v11.ExecutionPayloadHeaderDeneb{ + ParentHash: payloadInterface.ParentHash(), + FeeRecipient: payloadInterface.FeeRecipient(), + StateRoot: payloadInterface.StateRoot(), + ReceiptsRoot: payloadInterface.ReceiptsRoot(), + LogsBloom: payloadInterface.LogsBloom(), + PrevRandao: payloadInterface.PrevRandao(), + BlockNumber: payloadInterface.BlockNumber(), + GasLimit: payloadInterface.GasLimit(), + GasUsed: payloadInterface.GasUsed(), + Timestamp: payloadInterface.Timestamp(), + ExtraData: payloadInterface.ExtraData(), + BaseFeePerGas: payloadInterface.BaseFeePerGas(), + BlockHash: payloadInterface.BlockHash(), + TransactionsRoot: transactionsRoot, + WithdrawalsRoot: withdrawalsRoot, + } + updateExecution, err := update.FinalizedHeader().Execution() + require.NoError(t, err) + require.DeepSSZEqual(t, execution, updateExecution.Proto(), "Finalized Block Execution is not equal") + }) + + t.Run("FinalizedBlock In Previous Fork", func(t *testing.T) { + l := util.NewTestLightClient(t).SetupTestDenebFinalizedBlockCapella(false) + + update, err := lightClient.NewLightClientFinalityUpdateFromBeaconState(l.Ctx, l.State.Slot(), l.State, l.Block, l.AttestedState, l.AttestedBlock, l.FinalizedBlock) + require.NoError(t, err) + require.NotNil(t, update, "update is nil") + + require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot(), "Signature slot is not equal") + + l.CheckSyncAggregate(update.SyncAggregate()) + l.CheckAttestedHeader(update.AttestedHeader()) + + finalizedBlockHeader, err := l.FinalizedBlock.Header() + require.NoError(t, err) + require.NotNil(t, update.FinalizedHeader(), "Finalized header is nil") + updateFinalizedHeaderBeacon := update.FinalizedHeader().Beacon() + require.Equal(t, reflect.TypeOf(update.FinalizedHeader().Proto()), reflect.TypeOf(&pb.LightClientHeaderDeneb{}), "Finalized header is not Deneb") + require.Equal(t, finalizedBlockHeader.Header.Slot, updateFinalizedHeaderBeacon.Slot, "Finalized header slot is not equal") + require.Equal(t, finalizedBlockHeader.Header.ProposerIndex, updateFinalizedHeaderBeacon.ProposerIndex, "Finalized header proposer index is not equal") + require.DeepSSZEqual(t, finalizedBlockHeader.Header.ParentRoot, updateFinalizedHeaderBeacon.ParentRoot, "Finalized header parent root is not equal") + require.DeepSSZEqual(t, finalizedBlockHeader.Header.StateRoot, updateFinalizedHeaderBeacon.StateRoot, "Finalized header state root is not equal") + require.DeepSSZEqual(t, finalizedBlockHeader.Header.BodyRoot, updateFinalizedHeaderBeacon.BodyRoot, "Finalized header body root is not equal") + require.Equal(t, lightClient.FinalityBranchNumOfLeaves, len(update.FinalityBranch()), "Invalid finality branch leaves") + finalityBranch, err := l.AttestedState.FinalizedRootProof(l.Ctx) + require.NoError(t, err) + for i, leaf := range update.FinalityBranch() { + require.DeepSSZEqual(t, finalityBranch[i], leaf[:], "Leaf is not equal") + } + + // Check Execution BlockHash + payloadInterface, err := l.FinalizedBlock.Block().Body().Execution() + require.NoError(t, err) + transactionsRoot, err := payloadInterface.TransactionsRoot() + if errors.Is(err, consensustypes.ErrUnsupportedField) { + transactions, err := payloadInterface.Transactions() + require.NoError(t, err) + transactionsRootArray, err := ssz.TransactionsRoot(transactions) + require.NoError(t, err) + transactionsRoot = transactionsRootArray[:] + } else { + require.NoError(t, err) + } + withdrawalsRoot, err := payloadInterface.WithdrawalsRoot() + if errors.Is(err, consensustypes.ErrUnsupportedField) { + withdrawals, err := payloadInterface.Withdrawals() + require.NoError(t, err) + withdrawalsRootArray, err := ssz.WithdrawalSliceRoot(withdrawals, fieldparams.MaxWithdrawalsPerPayload) + require.NoError(t, err) + withdrawalsRoot = withdrawalsRootArray[:] + } else { + require.NoError(t, err) + } + execution := &v11.ExecutionPayloadHeaderDeneb{ + ParentHash: payloadInterface.ParentHash(), + FeeRecipient: payloadInterface.FeeRecipient(), + StateRoot: payloadInterface.StateRoot(), + ReceiptsRoot: payloadInterface.ReceiptsRoot(), + LogsBloom: payloadInterface.LogsBloom(), + PrevRandao: payloadInterface.PrevRandao(), + BlockNumber: payloadInterface.BlockNumber(), + GasLimit: payloadInterface.GasLimit(), + GasUsed: payloadInterface.GasUsed(), + Timestamp: payloadInterface.Timestamp(), + ExtraData: payloadInterface.ExtraData(), + BaseFeePerGas: payloadInterface.BaseFeePerGas(), + BlockHash: payloadInterface.BlockHash(), + TransactionsRoot: transactionsRoot, + WithdrawalsRoot: withdrawalsRoot, + } + updateExecution, err := update.FinalizedHeader().Execution() + require.NoError(t, err) + require.DeepSSZEqual(t, execution, updateExecution.Proto(), "Finalized Block Execution is not equal") + }) + }) +} + +func TestLightClient_BlockToLightClientHeader(t *testing.T) { + t.Run("Altair", func(t *testing.T) { + l := util.NewTestLightClient(t).SetupTestAltair() + + header, err := lightClient.BlockToLightClientHeader(l.Ctx, l.State.Slot(), l.Block) + require.NoError(t, err) + require.NotNil(t, header, "header is nil") + + parentRoot := l.Block.Block().ParentRoot() + stateRoot := l.Block.Block().StateRoot() + bodyRoot, err := l.Block.Block().Body().HashTreeRoot() + require.NoError(t, err) + + require.Equal(t, l.Block.Block().Slot(), header.Beacon().Slot, "Slot is not equal") + require.Equal(t, l.Block.Block().ProposerIndex(), header.Beacon().ProposerIndex, "Proposer index is not equal") + require.DeepSSZEqual(t, parentRoot[:], header.Beacon().ParentRoot, "Parent root is not equal") + require.DeepSSZEqual(t, stateRoot[:], header.Beacon().StateRoot, "State root is not equal") + require.DeepSSZEqual(t, bodyRoot[:], header.Beacon().BodyRoot, "Body root is not equal") + }) + + t.Run("Bellatrix", func(t *testing.T) { + l := util.NewTestLightClient(t).SetupTestBellatrix() + + header, err := lightClient.BlockToLightClientHeader(l.Ctx, l.State.Slot(), l.Block) + require.NoError(t, err) + require.NotNil(t, header, "header is nil") + + parentRoot := l.Block.Block().ParentRoot() + stateRoot := l.Block.Block().StateRoot() + bodyRoot, err := l.Block.Block().Body().HashTreeRoot() + require.NoError(t, err) + + require.Equal(t, l.Block.Block().Slot(), header.Beacon().Slot, "Slot is not equal") + require.Equal(t, l.Block.Block().ProposerIndex(), header.Beacon().ProposerIndex, "Proposer index is not equal") + require.DeepSSZEqual(t, parentRoot[:], header.Beacon().ParentRoot, "Parent root is not equal") + require.DeepSSZEqual(t, stateRoot[:], header.Beacon().StateRoot, "State root is not equal") + require.DeepSSZEqual(t, bodyRoot[:], header.Beacon().BodyRoot, "Body root is not equal") + }) + + t.Run("Capella", func(t *testing.T) { + t.Run("Non-Blinded Beacon Block", func(t *testing.T) { + l := util.NewTestLightClient(t).SetupTestCapella(false) + + header, err := lightClient.BlockToLightClientHeader(l.Ctx, l.State.Slot(), l.Block) + require.NoError(t, err) + require.NotNil(t, header, "header is nil") + + parentRoot := l.Block.Block().ParentRoot() + stateRoot := l.Block.Block().StateRoot() + bodyRoot, err := l.Block.Block().Body().HashTreeRoot() + require.NoError(t, err) + + payload, err := l.Block.Block().Body().Execution() + require.NoError(t, err) + + transactionsRoot, err := lightClient.ComputeTransactionsRoot(payload) + require.NoError(t, err) + + withdrawalsRoot, err := lightClient.ComputeWithdrawalsRoot(payload) + require.NoError(t, err) + + executionHeader := &v11.ExecutionPayloadHeaderCapella{ + ParentHash: payload.ParentHash(), + FeeRecipient: payload.FeeRecipient(), + StateRoot: payload.StateRoot(), + ReceiptsRoot: payload.ReceiptsRoot(), + LogsBloom: payload.LogsBloom(), + PrevRandao: payload.PrevRandao(), + BlockNumber: payload.BlockNumber(), + GasLimit: payload.GasLimit(), + GasUsed: payload.GasUsed(), + Timestamp: payload.Timestamp(), + ExtraData: payload.ExtraData(), + BaseFeePerGas: payload.BaseFeePerGas(), + BlockHash: payload.BlockHash(), + TransactionsRoot: transactionsRoot, + WithdrawalsRoot: withdrawalsRoot, + } + + executionPayloadProof, err := blocks.PayloadProof(l.Ctx, l.Block.Block()) + require.NoError(t, err) + + require.Equal(t, l.Block.Block().Slot(), header.Beacon().Slot, "Slot is not equal") + require.Equal(t, l.Block.Block().ProposerIndex(), header.Beacon().ProposerIndex, "Proposer index is not equal") + require.DeepSSZEqual(t, parentRoot[:], header.Beacon().ParentRoot, "Parent root is not equal") + require.DeepSSZEqual(t, stateRoot[:], header.Beacon().StateRoot, "State root is not equal") + require.DeepSSZEqual(t, bodyRoot[:], header.Beacon().BodyRoot, "Body root is not equal") + + headerExecution, err := header.Execution() + require.NoError(t, err) + require.DeepSSZEqual(t, executionHeader, headerExecution.Proto(), "Execution headers are not equal") + + headerExecutionBranch, err := header.ExecutionBranch() + require.NoError(t, err) + require.DeepSSZEqual(t, executionPayloadProof, convertArrayToSlice(headerExecutionBranch), "Execution payload proofs are not equal") + }) + + t.Run("Blinded Beacon Block", func(t *testing.T) { + l := util.NewTestLightClient(t).SetupTestCapella(true) + + header, err := lightClient.BlockToLightClientHeader(l.Ctx, l.State.Slot(), l.Block) + require.NoError(t, err) + require.NotNil(t, header, "header is nil") + + parentRoot := l.Block.Block().ParentRoot() + stateRoot := l.Block.Block().StateRoot() + bodyRoot, err := l.Block.Block().Body().HashTreeRoot() + require.NoError(t, err) + + payload, err := l.Block.Block().Body().Execution() + require.NoError(t, err) + + transactionsRoot, err := payload.TransactionsRoot() + require.NoError(t, err) + + withdrawalsRoot, err := payload.WithdrawalsRoot() + require.NoError(t, err) + + executionHeader := &v11.ExecutionPayloadHeaderCapella{ + ParentHash: payload.ParentHash(), + FeeRecipient: payload.FeeRecipient(), + StateRoot: payload.StateRoot(), + ReceiptsRoot: payload.ReceiptsRoot(), + LogsBloom: payload.LogsBloom(), + PrevRandao: payload.PrevRandao(), + BlockNumber: payload.BlockNumber(), + GasLimit: payload.GasLimit(), + GasUsed: payload.GasUsed(), + Timestamp: payload.Timestamp(), + ExtraData: payload.ExtraData(), + BaseFeePerGas: payload.BaseFeePerGas(), + BlockHash: payload.BlockHash(), + TransactionsRoot: transactionsRoot, + WithdrawalsRoot: withdrawalsRoot, + } + + executionPayloadProof, err := blocks.PayloadProof(l.Ctx, l.Block.Block()) + require.NoError(t, err) + + require.Equal(t, l.Block.Block().Slot(), header.Beacon().Slot, "Slot is not equal") + require.Equal(t, l.Block.Block().ProposerIndex(), header.Beacon().ProposerIndex, "Proposer index is not equal") + require.DeepSSZEqual(t, parentRoot[:], header.Beacon().ParentRoot, "Parent root is not equal") + require.DeepSSZEqual(t, stateRoot[:], header.Beacon().StateRoot, "State root is not equal") + require.DeepSSZEqual(t, bodyRoot[:], header.Beacon().BodyRoot, "Body root is not equal") + + headerExecution, err := header.Execution() + require.NoError(t, err) + require.DeepSSZEqual(t, executionHeader, headerExecution.Proto(), "Execution headers are not equal") + + headerExecutionBranch, err := header.ExecutionBranch() + require.NoError(t, err) + require.DeepSSZEqual(t, executionPayloadProof, convertArrayToSlice(headerExecutionBranch), "Execution payload proofs are not equal") + }) + }) + + t.Run("Deneb", func(t *testing.T) { + t.Run("Non-Blinded Beacon Block", func(t *testing.T) { + l := util.NewTestLightClient(t).SetupTestDeneb(false) + + header, err := lightClient.BlockToLightClientHeader(l.Ctx, l.State.Slot(), l.Block) + require.NoError(t, err) + require.NotNil(t, header, "header is nil") + + parentRoot := l.Block.Block().ParentRoot() + stateRoot := l.Block.Block().StateRoot() + bodyRoot, err := l.Block.Block().Body().HashTreeRoot() + require.NoError(t, err) + + payload, err := l.Block.Block().Body().Execution() + require.NoError(t, err) + + transactionsRoot, err := lightClient.ComputeTransactionsRoot(payload) + require.NoError(t, err) + + withdrawalsRoot, err := lightClient.ComputeWithdrawalsRoot(payload) + require.NoError(t, err) + + blobGasUsed, err := payload.BlobGasUsed() + require.NoError(t, err) + + excessBlobGas, err := payload.ExcessBlobGas() + require.NoError(t, err) + + executionHeader := &v11.ExecutionPayloadHeaderDeneb{ + ParentHash: payload.ParentHash(), + FeeRecipient: payload.FeeRecipient(), + StateRoot: payload.StateRoot(), + ReceiptsRoot: payload.ReceiptsRoot(), + LogsBloom: payload.LogsBloom(), + PrevRandao: payload.PrevRandao(), + BlockNumber: payload.BlockNumber(), + GasLimit: payload.GasLimit(), + GasUsed: payload.GasUsed(), + Timestamp: payload.Timestamp(), + ExtraData: payload.ExtraData(), + BaseFeePerGas: payload.BaseFeePerGas(), + BlockHash: payload.BlockHash(), + TransactionsRoot: transactionsRoot, + WithdrawalsRoot: withdrawalsRoot, + BlobGasUsed: blobGasUsed, + ExcessBlobGas: excessBlobGas, + } + + executionPayloadProof, err := blocks.PayloadProof(l.Ctx, l.Block.Block()) + require.NoError(t, err) + + require.Equal(t, l.Block.Block().Slot(), header.Beacon().Slot, "Slot is not equal") + require.Equal(t, l.Block.Block().ProposerIndex(), header.Beacon().ProposerIndex, "Proposer index is not equal") + require.DeepSSZEqual(t, parentRoot[:], header.Beacon().ParentRoot, "Parent root is not equal") + require.DeepSSZEqual(t, stateRoot[:], header.Beacon().StateRoot, "State root is not equal") + require.DeepSSZEqual(t, bodyRoot[:], header.Beacon().BodyRoot, "Body root is not equal") + + headerExecution, err := header.Execution() + require.NoError(t, err) + require.DeepSSZEqual(t, executionHeader, headerExecution.Proto(), "Execution headers are not equal") + + headerExecutionBranch, err := header.ExecutionBranch() + require.NoError(t, err) + require.DeepSSZEqual(t, executionPayloadProof, convertArrayToSlice(headerExecutionBranch), "Execution payload proofs are not equal") + }) + + t.Run("Blinded Beacon Block", func(t *testing.T) { + l := util.NewTestLightClient(t).SetupTestDeneb(true) + + header, err := lightClient.BlockToLightClientHeader(l.Ctx, l.State.Slot(), l.Block) + require.NoError(t, err) + require.NotNil(t, header, "header is nil") + + parentRoot := l.Block.Block().ParentRoot() + stateRoot := l.Block.Block().StateRoot() + bodyRoot, err := l.Block.Block().Body().HashTreeRoot() + require.NoError(t, err) + + payload, err := l.Block.Block().Body().Execution() + require.NoError(t, err) + + transactionsRoot, err := payload.TransactionsRoot() + require.NoError(t, err) + + withdrawalsRoot, err := payload.WithdrawalsRoot() + require.NoError(t, err) + + blobGasUsed, err := payload.BlobGasUsed() + require.NoError(t, err) + + excessBlobGas, err := payload.ExcessBlobGas() + require.NoError(t, err) + + executionHeader := &v11.ExecutionPayloadHeaderDeneb{ + ParentHash: payload.ParentHash(), + FeeRecipient: payload.FeeRecipient(), + StateRoot: payload.StateRoot(), + ReceiptsRoot: payload.ReceiptsRoot(), + LogsBloom: payload.LogsBloom(), + PrevRandao: payload.PrevRandao(), + BlockNumber: payload.BlockNumber(), + GasLimit: payload.GasLimit(), + GasUsed: payload.GasUsed(), + Timestamp: payload.Timestamp(), + ExtraData: payload.ExtraData(), + BaseFeePerGas: payload.BaseFeePerGas(), + BlockHash: payload.BlockHash(), + TransactionsRoot: transactionsRoot, + WithdrawalsRoot: withdrawalsRoot, + BlobGasUsed: blobGasUsed, + ExcessBlobGas: excessBlobGas, + } + + executionPayloadProof, err := blocks.PayloadProof(l.Ctx, l.Block.Block()) + require.NoError(t, err) + + require.Equal(t, l.Block.Block().Slot(), header.Beacon().Slot, "Slot is not equal") + require.Equal(t, l.Block.Block().ProposerIndex(), header.Beacon().ProposerIndex, "Proposer index is not equal") + require.DeepSSZEqual(t, parentRoot[:], header.Beacon().ParentRoot, "Parent root is not equal") + require.DeepSSZEqual(t, stateRoot[:], header.Beacon().StateRoot, "State root is not equal") + require.DeepSSZEqual(t, bodyRoot[:], header.Beacon().BodyRoot, "Body root is not equal") + + headerExecution, err := header.Execution() + require.NoError(t, err) + require.DeepSSZEqual(t, executionHeader, headerExecution.Proto(), "Execution headers are not equal") + + headerExecutionBranch, err := header.ExecutionBranch() + require.NoError(t, err) + require.DeepSSZEqual(t, executionPayloadProof, convertArrayToSlice(headerExecutionBranch), "Execution payload proofs are not equal") + }) + }) + + t.Run("Electra", func(t *testing.T) { + t.Run("Non-Blinded Beacon Block", func(t *testing.T) { + l := util.NewTestLightClient(t).SetupTestElectra(false) + + header, err := lightClient.BlockToLightClientHeader(l.Ctx, l.State.Slot(), l.Block) + require.NoError(t, err) + require.NotNil(t, header, "header is nil") + + parentRoot := l.Block.Block().ParentRoot() + stateRoot := l.Block.Block().StateRoot() + bodyRoot, err := l.Block.Block().Body().HashTreeRoot() + require.NoError(t, err) + + payload, err := l.Block.Block().Body().Execution() + require.NoError(t, err) + + transactionsRoot, err := lightClient.ComputeTransactionsRoot(payload) + require.NoError(t, err) + + withdrawalsRoot, err := lightClient.ComputeWithdrawalsRoot(payload) + require.NoError(t, err) + + blobGasUsed, err := payload.BlobGasUsed() + require.NoError(t, err) + + excessBlobGas, err := payload.ExcessBlobGas() + require.NoError(t, err) + + executionHeader := &v11.ExecutionPayloadHeaderElectra{ + ParentHash: payload.ParentHash(), + FeeRecipient: payload.FeeRecipient(), + StateRoot: payload.StateRoot(), + ReceiptsRoot: payload.ReceiptsRoot(), + LogsBloom: payload.LogsBloom(), + PrevRandao: payload.PrevRandao(), + BlockNumber: payload.BlockNumber(), + GasLimit: payload.GasLimit(), + GasUsed: payload.GasUsed(), + Timestamp: payload.Timestamp(), + ExtraData: payload.ExtraData(), + BaseFeePerGas: payload.BaseFeePerGas(), + BlockHash: payload.BlockHash(), + TransactionsRoot: transactionsRoot, + WithdrawalsRoot: withdrawalsRoot, + BlobGasUsed: blobGasUsed, + ExcessBlobGas: excessBlobGas, + } + + executionPayloadProof, err := blocks.PayloadProof(l.Ctx, l.Block.Block()) + require.NoError(t, err) + + require.Equal(t, l.Block.Block().Slot(), header.Beacon().Slot, "Slot is not equal") + require.Equal(t, l.Block.Block().ProposerIndex(), header.Beacon().ProposerIndex, "Proposer index is not equal") + require.DeepSSZEqual(t, parentRoot[:], header.Beacon().ParentRoot, "Parent root is not equal") + require.DeepSSZEqual(t, stateRoot[:], header.Beacon().StateRoot, "State root is not equal") + require.DeepSSZEqual(t, bodyRoot[:], header.Beacon().BodyRoot, "Body root is not equal") + + headerExecution, err := header.Execution() + require.NoError(t, err) + require.DeepSSZEqual(t, executionHeader, headerExecution.Proto(), "Execution headers are not equal") + + headerExecutionBranch, err := header.ExecutionBranch() + require.NoError(t, err) + require.DeepSSZEqual(t, executionPayloadProof, convertArrayToSlice(headerExecutionBranch), "Execution payload proofs are not equal") + }) + + t.Run("Blinded Beacon Block", func(t *testing.T) { + l := util.NewTestLightClient(t).SetupTestElectra(true) + + header, err := lightClient.BlockToLightClientHeader(l.Ctx, l.State.Slot(), l.Block) + require.NoError(t, err) + require.NotNil(t, header, "header is nil") + + parentRoot := l.Block.Block().ParentRoot() + stateRoot := l.Block.Block().StateRoot() + bodyRoot, err := l.Block.Block().Body().HashTreeRoot() + require.NoError(t, err) + + payload, err := l.Block.Block().Body().Execution() + require.NoError(t, err) + + transactionsRoot, err := payload.TransactionsRoot() + require.NoError(t, err) + + withdrawalsRoot, err := payload.WithdrawalsRoot() + require.NoError(t, err) + + blobGasUsed, err := payload.BlobGasUsed() + require.NoError(t, err) + + excessBlobGas, err := payload.ExcessBlobGas() + require.NoError(t, err) + + executionHeader := &v11.ExecutionPayloadHeaderElectra{ + ParentHash: payload.ParentHash(), + FeeRecipient: payload.FeeRecipient(), + StateRoot: payload.StateRoot(), + ReceiptsRoot: payload.ReceiptsRoot(), + LogsBloom: payload.LogsBloom(), + PrevRandao: payload.PrevRandao(), + BlockNumber: payload.BlockNumber(), + GasLimit: payload.GasLimit(), + GasUsed: payload.GasUsed(), + Timestamp: payload.Timestamp(), + ExtraData: payload.ExtraData(), + BaseFeePerGas: payload.BaseFeePerGas(), + BlockHash: payload.BlockHash(), + TransactionsRoot: transactionsRoot, + WithdrawalsRoot: withdrawalsRoot, + BlobGasUsed: blobGasUsed, + ExcessBlobGas: excessBlobGas, + } + + executionPayloadProof, err := blocks.PayloadProof(l.Ctx, l.Block.Block()) + require.NoError(t, err) + + require.Equal(t, l.Block.Block().Slot(), header.Beacon().Slot, "Slot is not equal") + require.Equal(t, l.Block.Block().ProposerIndex(), header.Beacon().ProposerIndex, "Proposer index is not equal") + require.DeepSSZEqual(t, parentRoot[:], header.Beacon().ParentRoot, "Parent root is not equal") + require.DeepSSZEqual(t, stateRoot[:], header.Beacon().StateRoot, "State root is not equal") + require.DeepSSZEqual(t, bodyRoot[:], header.Beacon().BodyRoot, "Body root is not equal") + + headerExecution, err := header.Execution() + require.NoError(t, err) + require.DeepSSZEqual(t, executionHeader, headerExecution.Proto(), "Execution headers are not equal") + + headerExecutionBranch, err := header.ExecutionBranch() + require.NoError(t, err) + require.DeepSSZEqual(t, executionPayloadProof, convertArrayToSlice(headerExecutionBranch), "Execution payload proofs are not equal") + }) }) - // - // t.Run("Deneb", func(t *testing.T) { - // - // t.Run("FinalizedBlock Not Nil", func(t *testing.T) { - // l := util.NewTestLightClient(t).SetupTestDeneb(false) - // - // update, err := lightClient.NewLightClientFinalityUpdateFromBeaconState(l.Ctx, l.State, l.Block, l.AttestedState, l.AttestedBlock, l.FinalizedBlock) - // require.NoError(t, err) - // require.NotNil(t, update, "update is nil") - // - // require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot, "Signature slot is not equal") - // - // l.CheckSyncAggregate(update.SyncAggregate) - // l.CheckAttestedHeader(update.AttestedHeader) - // - // //zeroHash := params.BeaconConfig().ZeroHash[:] - // finalizedBlockHeader, err := l.FinalizedBlock.Header() - // require.NoError(t, err) - // require.NotNil(t, update.FinalizedHeader, "Finalized header is nil") - // updateFinalizedHeaderBeacon, err := update.FinalizedHeader.GetBeacon() - // require.NoError(t, err) - // require.Equal(t, finalizedBlockHeader.Header.Slot, updateFinalizedHeaderBeacon.Slot, "Finalized header slot is not equal") - // require.Equal(t, finalizedBlockHeader.Header.ProposerIndex, updateFinalizedHeaderBeacon.ProposerIndex, "Finalized header proposer index is not equal") - // require.DeepSSZEqual(t, finalizedBlockHeader.Header.ParentRoot, updateFinalizedHeaderBeacon.ParentRoot, "Finalized header parent root is not equal") - // require.DeepSSZEqual(t, finalizedBlockHeader.Header.StateRoot, updateFinalizedHeaderBeacon.StateRoot, "Finalized header state root is not equal") - // require.DeepSSZEqual(t, finalizedBlockHeader.Header.BodyRoot, updateFinalizedHeaderBeacon.BodyRoot, "Finalized header body root is not equal") - // require.Equal(t, lightClient.FinalityBranchNumOfLeaves, len(update.FinalityBranch), "Invalid finality branch leaves") - // finalityBranch, err := l.AttestedState.FinalizedRootProof(l.Ctx) - // require.NoError(t, err) - // for i, leaf := range update.FinalityBranch { - // require.DeepSSZEqual(t, finalityBranch[i], leaf, "Leaf is not equal") - // } - // - // // Check Execution BlockHash - // payloadInterface, err := l.FinalizedBlock.Block().Body().Execution() - // require.NoError(t, err) - // transactionsRoot, err := payloadInterface.TransactionsRoot() - // if errors.Is(err, consensustypes.ErrUnsupportedField) { - // transactions, err := payloadInterface.Transactions() - // require.NoError(t, err) - // transactionsRootArray, err := ssz.TransactionsRoot(transactions) - // require.NoError(t, err) - // transactionsRoot = transactionsRootArray[:] - // } else { - // require.NoError(t, err) - // } - // withdrawalsRoot, err := payloadInterface.WithdrawalsRoot() - // if errors.Is(err, consensustypes.ErrUnsupportedField) { - // withdrawals, err := payloadInterface.Withdrawals() - // require.NoError(t, err) - // withdrawalsRootArray, err := ssz.WithdrawalSliceRoot(withdrawals, fieldparams.MaxWithdrawalsPerPayload) - // require.NoError(t, err) - // withdrawalsRoot = withdrawalsRootArray[:] - // } else { - // require.NoError(t, err) - // } - // execution := &v11.ExecutionPayloadHeaderDeneb{ - // ParentHash: payloadInterface.ParentHash(), - // FeeRecipient: payloadInterface.FeeRecipient(), - // StateRoot: payloadInterface.StateRoot(), - // ReceiptsRoot: payloadInterface.ReceiptsRoot(), - // LogsBloom: payloadInterface.LogsBloom(), - // PrevRandao: payloadInterface.PrevRandao(), - // BlockNumber: payloadInterface.BlockNumber(), - // GasLimit: payloadInterface.GasLimit(), - // GasUsed: payloadInterface.GasUsed(), - // Timestamp: payloadInterface.Timestamp(), - // ExtraData: payloadInterface.ExtraData(), - // BaseFeePerGas: payloadInterface.BaseFeePerGas(), - // BlockHash: payloadInterface.BlockHash(), - // TransactionsRoot: transactionsRoot, - // WithdrawalsRoot: withdrawalsRoot, - // } - // require.DeepSSZEqual(t, execution, update.FinalizedHeader.GetHeaderDeneb().Execution, "Finalized Block Execution is not equal") - // }) - // - // t.Run("FinalizedBlock In Previous Fork", func(t *testing.T) { - // l := util.NewTestLightClient(t).SetupTestDenebFinalizedBlockCapella(false) - // - // update, err := lightClient.NewLightClientFinalityUpdateFromBeaconState(l.Ctx, l.State, l.Block, l.AttestedState, l.AttestedBlock, l.FinalizedBlock) - // require.NoError(t, err) - // require.NotNil(t, update, "update is nil") - // - // require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot, "Signature slot is not equal") - // - // l.CheckSyncAggregate(update.SyncAggregate) - // l.CheckAttestedHeader(update.AttestedHeader) - // - // finalizedBlockHeader, err := l.FinalizedBlock.Header() - // require.NoError(t, err) - // require.NotNil(t, update.FinalizedHeader, "Finalized header is nil") - // updateFinalizedHeaderBeacon, err := update.FinalizedHeader.GetBeacon() - // require.NoError(t, err) - // require.Equal(t, finalizedBlockHeader.Header.Slot, updateFinalizedHeaderBeacon.Slot, "Finalized header slot is not equal") - // require.Equal(t, finalizedBlockHeader.Header.ProposerIndex, updateFinalizedHeaderBeacon.ProposerIndex, "Finalized header proposer index is not equal") - // require.DeepSSZEqual(t, finalizedBlockHeader.Header.ParentRoot, updateFinalizedHeaderBeacon.ParentRoot, "Finalized header parent root is not equal") - // require.DeepSSZEqual(t, finalizedBlockHeader.Header.StateRoot, updateFinalizedHeaderBeacon.StateRoot, "Finalized header state root is not equal") - // require.DeepSSZEqual(t, finalizedBlockHeader.Header.BodyRoot, updateFinalizedHeaderBeacon.BodyRoot, "Finalized header body root is not equal") - // require.Equal(t, lightClient.FinalityBranchNumOfLeaves, len(update.FinalityBranch), "Invalid finality branch leaves") - // finalityBranch, err := l.AttestedState.FinalizedRootProof(l.Ctx) - // require.NoError(t, err) - // for i, leaf := range update.FinalityBranch { - // require.DeepSSZEqual(t, finalityBranch[i], leaf, "Leaf is not equal") - // } - // - // // Check Execution BlockHash - // payloadInterface, err := l.FinalizedBlock.Block().Body().Execution() - // require.NoError(t, err) - // transactionsRoot, err := payloadInterface.TransactionsRoot() - // if errors.Is(err, consensustypes.ErrUnsupportedField) { - // transactions, err := payloadInterface.Transactions() - // require.NoError(t, err) - // transactionsRootArray, err := ssz.TransactionsRoot(transactions) - // require.NoError(t, err) - // transactionsRoot = transactionsRootArray[:] - // } else { - // require.NoError(t, err) - // } - // withdrawalsRoot, err := payloadInterface.WithdrawalsRoot() - // if errors.Is(err, consensustypes.ErrUnsupportedField) { - // withdrawals, err := payloadInterface.Withdrawals() - // require.NoError(t, err) - // withdrawalsRootArray, err := ssz.WithdrawalSliceRoot(withdrawals, fieldparams.MaxWithdrawalsPerPayload) - // require.NoError(t, err) - // withdrawalsRoot = withdrawalsRootArray[:] - // } else { - // require.NoError(t, err) - // } - // execution := &v11.ExecutionPayloadHeaderCapella{ - // ParentHash: payloadInterface.ParentHash(), - // FeeRecipient: payloadInterface.FeeRecipient(), - // StateRoot: payloadInterface.StateRoot(), - // ReceiptsRoot: payloadInterface.ReceiptsRoot(), - // LogsBloom: payloadInterface.LogsBloom(), - // PrevRandao: payloadInterface.PrevRandao(), - // BlockNumber: payloadInterface.BlockNumber(), - // GasLimit: payloadInterface.GasLimit(), - // GasUsed: payloadInterface.GasUsed(), - // Timestamp: payloadInterface.Timestamp(), - // ExtraData: payloadInterface.ExtraData(), - // BaseFeePerGas: payloadInterface.BaseFeePerGas(), - // BlockHash: payloadInterface.BlockHash(), - // TransactionsRoot: transactionsRoot, - // WithdrawalsRoot: withdrawalsRoot, - // } - // require.DeepSSZEqual(t, execution, update.FinalizedHeader.GetHeaderCapella().Execution, "Finalized Block Execution is not equal") - // }) - // }) } -//func TestLightClient_BlockToLightClientHeader(t *testing.T) { -// t.Run("Altair", func(t *testing.T) { -// l := util.NewTestLightClient(t).SetupTestAltair() -// -// container, err := lightClient.BlockToLightClientHeader(l.Block) -// require.NoError(t, err) -// header := container.GetHeaderAltair() -// require.NotNil(t, header, "header is nil") -// -// parentRoot := l.Block.Block().ParentRoot() -// stateRoot := l.Block.Block().StateRoot() -// bodyRoot, err := l.Block.Block().Body().HashTreeRoot() -// require.NoError(t, err) -// -// require.Equal(t, l.Block.Block().Slot(), header.Beacon.Slot, "Slot is not equal") -// require.Equal(t, l.Block.Block().ProposerIndex(), header.Beacon.ProposerIndex, "Proposer index is not equal") -// require.DeepSSZEqual(t, parentRoot[:], header.Beacon.ParentRoot, "Parent root is not equal") -// require.DeepSSZEqual(t, stateRoot[:], header.Beacon.StateRoot, "State root is not equal") -// require.DeepSSZEqual(t, bodyRoot[:], header.Beacon.BodyRoot, "Body root is not equal") -// }) -// -// t.Run("Bellatrix", func(t *testing.T) { -// l := util.NewTestLightClient(t).SetupTestBellatrix() -// -// container, err := lightClient.BlockToLightClientHeader(l.Block) -// require.NoError(t, err) -// header := container.GetHeaderAltair() -// require.NotNil(t, header, "header is nil") -// -// parentRoot := l.Block.Block().ParentRoot() -// stateRoot := l.Block.Block().StateRoot() -// bodyRoot, err := l.Block.Block().Body().HashTreeRoot() -// require.NoError(t, err) -// -// require.Equal(t, l.Block.Block().Slot(), header.Beacon.Slot, "Slot is not equal") -// require.Equal(t, l.Block.Block().ProposerIndex(), header.Beacon.ProposerIndex, "Proposer index is not equal") -// require.DeepSSZEqual(t, parentRoot[:], header.Beacon.ParentRoot, "Parent root is not equal") -// require.DeepSSZEqual(t, stateRoot[:], header.Beacon.StateRoot, "State root is not equal") -// require.DeepSSZEqual(t, bodyRoot[:], header.Beacon.BodyRoot, "Body root is not equal") -// }) -// -// t.Run("Capella", func(t *testing.T) { -// t.Run("Non-Blinded Beacon Block", func(t *testing.T) { -// l := util.NewTestLightClient(t).SetupTestCapella(false) -// -// container, err := lightClient.BlockToLightClientHeader(l.Block) -// require.NoError(t, err) -// header := container.GetHeaderCapella() -// require.NotNil(t, header, "header is nil") -// -// parentRoot := l.Block.Block().ParentRoot() -// stateRoot := l.Block.Block().StateRoot() -// bodyRoot, err := l.Block.Block().Body().HashTreeRoot() -// require.NoError(t, err) -// -// payload, err := l.Block.Block().Body().Execution() -// require.NoError(t, err) -// -// transactionsRoot, err := lightClient.ComputeTransactionsRoot(payload) -// require.NoError(t, err) -// -// withdrawalsRoot, err := lightClient.ComputeWithdrawalsRoot(payload) -// require.NoError(t, err) -// -// executionHeader := &v11.ExecutionPayloadHeaderCapella{ -// ParentHash: payload.ParentHash(), -// FeeRecipient: payload.FeeRecipient(), -// StateRoot: payload.StateRoot(), -// ReceiptsRoot: payload.ReceiptsRoot(), -// LogsBloom: payload.LogsBloom(), -// PrevRandao: payload.PrevRandao(), -// BlockNumber: payload.BlockNumber(), -// GasLimit: payload.GasLimit(), -// GasUsed: payload.GasUsed(), -// Timestamp: payload.Timestamp(), -// ExtraData: payload.ExtraData(), -// BaseFeePerGas: payload.BaseFeePerGas(), -// BlockHash: payload.BlockHash(), -// TransactionsRoot: transactionsRoot, -// WithdrawalsRoot: withdrawalsRoot, -// } -// -// executionPayloadProof, err := blocks.PayloadProof(l.Ctx, l.Block.Block()) -// require.NoError(t, err) -// -// require.Equal(t, l.Block.Block().Slot(), header.Beacon.Slot, "Slot is not equal") -// require.Equal(t, l.Block.Block().ProposerIndex(), header.Beacon.ProposerIndex, "Proposer index is not equal") -// require.DeepSSZEqual(t, parentRoot[:], header.Beacon.ParentRoot, "Parent root is not equal") -// require.DeepSSZEqual(t, stateRoot[:], header.Beacon.StateRoot, "State root is not equal") -// require.DeepSSZEqual(t, bodyRoot[:], header.Beacon.BodyRoot, "Body root is not equal") -// -// require.DeepSSZEqual(t, executionHeader, header.Execution, "Execution headers are not equal") -// -// require.DeepSSZEqual(t, executionPayloadProof, header.ExecutionBranch, "Execution payload proofs are not equal") -// }) -// -// t.Run("Blinded Beacon Block", func(t *testing.T) { -// l := util.NewTestLightClient(t).SetupTestCapella(true) -// -// container, err := lightClient.BlockToLightClientHeader(l.Block) -// require.NoError(t, err) -// header := container.GetHeaderCapella() -// require.NotNil(t, header, "header is nil") -// -// parentRoot := l.Block.Block().ParentRoot() -// stateRoot := l.Block.Block().StateRoot() -// bodyRoot, err := l.Block.Block().Body().HashTreeRoot() -// require.NoError(t, err) -// -// payload, err := l.Block.Block().Body().Execution() -// require.NoError(t, err) -// -// transactionsRoot, err := payload.TransactionsRoot() -// require.NoError(t, err) -// -// withdrawalsRoot, err := payload.WithdrawalsRoot() -// require.NoError(t, err) -// -// executionHeader := &v11.ExecutionPayloadHeaderCapella{ -// ParentHash: payload.ParentHash(), -// FeeRecipient: payload.FeeRecipient(), -// StateRoot: payload.StateRoot(), -// ReceiptsRoot: payload.ReceiptsRoot(), -// LogsBloom: payload.LogsBloom(), -// PrevRandao: payload.PrevRandao(), -// BlockNumber: payload.BlockNumber(), -// GasLimit: payload.GasLimit(), -// GasUsed: payload.GasUsed(), -// Timestamp: payload.Timestamp(), -// ExtraData: payload.ExtraData(), -// BaseFeePerGas: payload.BaseFeePerGas(), -// BlockHash: payload.BlockHash(), -// TransactionsRoot: transactionsRoot, -// WithdrawalsRoot: withdrawalsRoot, -// } -// -// executionPayloadProof, err := blocks.PayloadProof(l.Ctx, l.Block.Block()) -// require.NoError(t, err) -// -// require.Equal(t, l.Block.Block().Slot(), header.Beacon.Slot, "Slot is not equal") -// require.Equal(t, l.Block.Block().ProposerIndex(), header.Beacon.ProposerIndex, "Proposer index is not equal") -// require.DeepSSZEqual(t, parentRoot[:], header.Beacon.ParentRoot, "Parent root is not equal") -// require.DeepSSZEqual(t, stateRoot[:], header.Beacon.StateRoot, "State root is not equal") -// require.DeepSSZEqual(t, bodyRoot[:], header.Beacon.BodyRoot, "Body root is not equal") -// -// require.DeepSSZEqual(t, executionHeader, header.Execution, "Execution headers are not equal") -// -// require.DeepSSZEqual(t, executionPayloadProof, header.ExecutionBranch, "Execution payload proofs are not equal") -// }) -// }) -// -// t.Run("Deneb", func(t *testing.T) { -// t.Run("Non-Blinded Beacon Block", func(t *testing.T) { -// l := util.NewTestLightClient(t).SetupTestDeneb(false) -// -// container, err := lightClient.BlockToLightClientHeader(l.Block) -// require.NoError(t, err) -// header := container.GetHeaderDeneb() -// require.NotNil(t, header, "header is nil") -// -// parentRoot := l.Block.Block().ParentRoot() -// stateRoot := l.Block.Block().StateRoot() -// bodyRoot, err := l.Block.Block().Body().HashTreeRoot() -// require.NoError(t, err) -// -// payload, err := l.Block.Block().Body().Execution() -// require.NoError(t, err) -// -// transactionsRoot, err := lightClient.ComputeTransactionsRoot(payload) -// require.NoError(t, err) -// -// withdrawalsRoot, err := lightClient.ComputeWithdrawalsRoot(payload) -// require.NoError(t, err) -// -// blobGasUsed, err := payload.BlobGasUsed() -// require.NoError(t, err) -// -// excessBlobGas, err := payload.ExcessBlobGas() -// require.NoError(t, err) -// -// executionHeader := &v11.ExecutionPayloadHeaderDeneb{ -// ParentHash: payload.ParentHash(), -// FeeRecipient: payload.FeeRecipient(), -// StateRoot: payload.StateRoot(), -// ReceiptsRoot: payload.ReceiptsRoot(), -// LogsBloom: payload.LogsBloom(), -// PrevRandao: payload.PrevRandao(), -// BlockNumber: payload.BlockNumber(), -// GasLimit: payload.GasLimit(), -// GasUsed: payload.GasUsed(), -// Timestamp: payload.Timestamp(), -// ExtraData: payload.ExtraData(), -// BaseFeePerGas: payload.BaseFeePerGas(), -// BlockHash: payload.BlockHash(), -// TransactionsRoot: transactionsRoot, -// WithdrawalsRoot: withdrawalsRoot, -// BlobGasUsed: blobGasUsed, -// ExcessBlobGas: excessBlobGas, -// } -// -// executionPayloadProof, err := blocks.PayloadProof(l.Ctx, l.Block.Block()) -// require.NoError(t, err) -// -// require.Equal(t, l.Block.Block().Slot(), header.Beacon.Slot, "Slot is not equal") -// require.Equal(t, l.Block.Block().ProposerIndex(), header.Beacon.ProposerIndex, "Proposer index is not equal") -// require.DeepSSZEqual(t, parentRoot[:], header.Beacon.ParentRoot, "Parent root is not equal") -// require.DeepSSZEqual(t, stateRoot[:], header.Beacon.StateRoot, "State root is not equal") -// require.DeepSSZEqual(t, bodyRoot[:], header.Beacon.BodyRoot, "Body root is not equal") -// -// require.DeepSSZEqual(t, executionHeader, header.Execution, "Execution headers are not equal") -// -// require.DeepSSZEqual(t, executionPayloadProof, header.ExecutionBranch, "Execution payload proofs are not equal") -// }) -// -// t.Run("Blinded Beacon Block", func(t *testing.T) { -// l := util.NewTestLightClient(t).SetupTestDeneb(true) -// -// container, err := lightClient.BlockToLightClientHeader(l.Block) -// require.NoError(t, err) -// header := container.GetHeaderDeneb() -// require.NotNil(t, header, "header is nil") -// -// parentRoot := l.Block.Block().ParentRoot() -// stateRoot := l.Block.Block().StateRoot() -// bodyRoot, err := l.Block.Block().Body().HashTreeRoot() -// require.NoError(t, err) -// -// payload, err := l.Block.Block().Body().Execution() -// require.NoError(t, err) -// -// transactionsRoot, err := payload.TransactionsRoot() -// require.NoError(t, err) -// -// withdrawalsRoot, err := payload.WithdrawalsRoot() -// require.NoError(t, err) -// -// blobGasUsed, err := payload.BlobGasUsed() -// require.NoError(t, err) -// -// excessBlobGas, err := payload.ExcessBlobGas() -// require.NoError(t, err) -// -// executionHeader := &v11.ExecutionPayloadHeaderDeneb{ -// ParentHash: payload.ParentHash(), -// FeeRecipient: payload.FeeRecipient(), -// StateRoot: payload.StateRoot(), -// ReceiptsRoot: payload.ReceiptsRoot(), -// LogsBloom: payload.LogsBloom(), -// PrevRandao: payload.PrevRandao(), -// BlockNumber: payload.BlockNumber(), -// GasLimit: payload.GasLimit(), -// GasUsed: payload.GasUsed(), -// Timestamp: payload.Timestamp(), -// ExtraData: payload.ExtraData(), -// BaseFeePerGas: payload.BaseFeePerGas(), -// BlockHash: payload.BlockHash(), -// TransactionsRoot: transactionsRoot, -// WithdrawalsRoot: withdrawalsRoot, -// BlobGasUsed: blobGasUsed, -// ExcessBlobGas: excessBlobGas, -// } -// -// executionPayloadProof, err := blocks.PayloadProof(l.Ctx, l.Block.Block()) -// require.NoError(t, err) -// -// require.Equal(t, l.Block.Block().Slot(), header.Beacon.Slot, "Slot is not equal") -// require.Equal(t, l.Block.Block().ProposerIndex(), header.Beacon.ProposerIndex, "Proposer index is not equal") -// require.DeepSSZEqual(t, parentRoot[:], header.Beacon.ParentRoot, "Parent root is not equal") -// require.DeepSSZEqual(t, stateRoot[:], header.Beacon.StateRoot, "State root is not equal") -// require.DeepSSZEqual(t, bodyRoot[:], header.Beacon.BodyRoot, "Body root is not equal") -// -// require.DeepSSZEqual(t, executionHeader, header.Execution, "Execution headers are not equal") -// -// require.DeepSSZEqual(t, executionPayloadProof, header.ExecutionBranch, "Execution payload proofs are not equal") -// }) -// }) -// -// t.Run("Electra", func(t *testing.T) { -// t.Run("Non-Blinded Beacon Block", func(t *testing.T) { -// l := util.NewTestLightClient(t).SetupTestElectra(false) -// -// container, err := lightClient.BlockToLightClientHeader(l.Block) -// require.NoError(t, err) -// header := container.GetHeaderDeneb() -// require.NotNil(t, header, "header is nil") -// -// parentRoot := l.Block.Block().ParentRoot() -// stateRoot := l.Block.Block().StateRoot() -// bodyRoot, err := l.Block.Block().Body().HashTreeRoot() -// require.NoError(t, err) -// -// payload, err := l.Block.Block().Body().Execution() -// require.NoError(t, err) -// -// transactionsRoot, err := lightClient.ComputeTransactionsRoot(payload) -// require.NoError(t, err) -// -// withdrawalsRoot, err := lightClient.ComputeWithdrawalsRoot(payload) -// require.NoError(t, err) -// -// blobGasUsed, err := payload.BlobGasUsed() -// require.NoError(t, err) -// -// excessBlobGas, err := payload.ExcessBlobGas() -// require.NoError(t, err) -// -// executionHeader := &v11.ExecutionPayloadHeaderElectra{ -// ParentHash: payload.ParentHash(), -// FeeRecipient: payload.FeeRecipient(), -// StateRoot: payload.StateRoot(), -// ReceiptsRoot: payload.ReceiptsRoot(), -// LogsBloom: payload.LogsBloom(), -// PrevRandao: payload.PrevRandao(), -// BlockNumber: payload.BlockNumber(), -// GasLimit: payload.GasLimit(), -// GasUsed: payload.GasUsed(), -// Timestamp: payload.Timestamp(), -// ExtraData: payload.ExtraData(), -// BaseFeePerGas: payload.BaseFeePerGas(), -// BlockHash: payload.BlockHash(), -// TransactionsRoot: transactionsRoot, -// WithdrawalsRoot: withdrawalsRoot, -// BlobGasUsed: blobGasUsed, -// ExcessBlobGas: excessBlobGas, -// } -// -// executionPayloadProof, err := blocks.PayloadProof(l.Ctx, l.Block.Block()) -// require.NoError(t, err) -// -// require.Equal(t, l.Block.Block().Slot(), header.Beacon.Slot, "Slot is not equal") -// require.Equal(t, l.Block.Block().ProposerIndex(), header.Beacon.ProposerIndex, "Proposer index is not equal") -// require.DeepSSZEqual(t, parentRoot[:], header.Beacon.ParentRoot, "Parent root is not equal") -// require.DeepSSZEqual(t, stateRoot[:], header.Beacon.StateRoot, "State root is not equal") -// require.DeepSSZEqual(t, bodyRoot[:], header.Beacon.BodyRoot, "Body root is not equal") -// -// require.DeepSSZEqual(t, executionHeader, header.Execution, "Execution headers are not equal") -// -// require.DeepSSZEqual(t, executionPayloadProof, header.ExecutionBranch, "Execution payload proofs are not equal") -// }) -// -// t.Run("Blinded Beacon Block", func(t *testing.T) { -// l := util.NewTestLightClient(t).SetupTestElectra(true) -// -// container, err := lightClient.BlockToLightClientHeader(l.Block) -// require.NoError(t, err) -// header := container.GetHeaderDeneb() -// require.NotNil(t, header, "header is nil") -// -// parentRoot := l.Block.Block().ParentRoot() -// stateRoot := l.Block.Block().StateRoot() -// bodyRoot, err := l.Block.Block().Body().HashTreeRoot() -// require.NoError(t, err) -// -// payload, err := l.Block.Block().Body().Execution() -// require.NoError(t, err) -// -// transactionsRoot, err := payload.TransactionsRoot() -// require.NoError(t, err) -// -// withdrawalsRoot, err := payload.WithdrawalsRoot() -// require.NoError(t, err) -// -// blobGasUsed, err := payload.BlobGasUsed() -// require.NoError(t, err) -// -// excessBlobGas, err := payload.ExcessBlobGas() -// require.NoError(t, err) -// -// executionHeader := &v11.ExecutionPayloadHeaderElectra{ -// ParentHash: payload.ParentHash(), -// FeeRecipient: payload.FeeRecipient(), -// StateRoot: payload.StateRoot(), -// ReceiptsRoot: payload.ReceiptsRoot(), -// LogsBloom: payload.LogsBloom(), -// PrevRandao: payload.PrevRandao(), -// BlockNumber: payload.BlockNumber(), -// GasLimit: payload.GasLimit(), -// GasUsed: payload.GasUsed(), -// Timestamp: payload.Timestamp(), -// ExtraData: payload.ExtraData(), -// BaseFeePerGas: payload.BaseFeePerGas(), -// BlockHash: payload.BlockHash(), -// TransactionsRoot: transactionsRoot, -// WithdrawalsRoot: withdrawalsRoot, -// BlobGasUsed: blobGasUsed, -// ExcessBlobGas: excessBlobGas, -// } -// -// executionPayloadProof, err := blocks.PayloadProof(l.Ctx, l.Block.Block()) -// require.NoError(t, err) -// -// require.Equal(t, l.Block.Block().Slot(), header.Beacon.Slot, "Slot is not equal") -// require.Equal(t, l.Block.Block().ProposerIndex(), header.Beacon.ProposerIndex, "Proposer index is not equal") -// require.DeepSSZEqual(t, parentRoot[:], header.Beacon.ParentRoot, "Parent root is not equal") -// require.DeepSSZEqual(t, stateRoot[:], header.Beacon.StateRoot, "State root is not equal") -// require.DeepSSZEqual(t, bodyRoot[:], header.Beacon.BodyRoot, "Body root is not equal") -// -// require.DeepSSZEqual(t, executionHeader, header.Execution, "Execution headers are not equal") -// -// require.DeepSSZEqual(t, executionPayloadProof, header.ExecutionBranch, "Execution payload proofs are not equal") -// }) -// }) -//} +func convertArrayToSlice(arr [4][32]uint8) [][]uint8 { + slice := make([][]uint8, len(arr)) + for i := range arr { + slice[i] = arr[i][:] + } + return slice +} diff --git a/beacon-chain/db/kv/BUILD.bazel b/beacon-chain/db/kv/BUILD.bazel index 0a95e714aeb3..714bfb1f26d4 100644 --- a/beacon-chain/db/kv/BUILD.bazel +++ b/beacon-chain/db/kv/BUILD.bazel @@ -112,18 +112,18 @@ go_test( "//config/params:go_default_library", "//consensus-types/blocks:go_default_library", "//consensus-types/interfaces:go_default_library", + "//consensus-types/light-client:go_default_library", "//consensus-types/primitives:go_default_library", "//encoding/bytesutil:go_default_library", "//proto/dbval:go_default_library", "//proto/engine/v1:go_default_library", - "//proto/eth/v1:go_default_library", - "//proto/eth/v2:go_default_library", "//proto/prysm/v1alpha1:go_default_library", "//proto/testing:go_default_library", "//runtime/version:go_default_library", "//testing/assert:go_default_library", "//testing/require:go_default_library", "//testing/util:go_default_library", + "//time/slots:go_default_library", "@com_github_ethereum_go_ethereum//common:go_default_library", "@com_github_golang_snappy//:go_default_library", "@com_github_pkg_errors//:go_default_library", diff --git a/beacon-chain/rpc/eth/light-client/BUILD.bazel b/beacon-chain/rpc/eth/light-client/BUILD.bazel index b3a32ba5095e..afee2233cdc9 100644 --- a/beacon-chain/rpc/eth/light-client/BUILD.bazel +++ b/beacon-chain/rpc/eth/light-client/BUILD.bazel @@ -40,12 +40,20 @@ go_test( ], embed = [":go_default_library"], deps = [ + "//api/server/structs:go_default_library", + "//beacon-chain/blockchain/testing:go_default_library", "//beacon-chain/core/light-client:go_default_library", + "//beacon-chain/db/kv:go_default_library", + "//beacon-chain/rpc/testutil:go_default_library", + "//beacon-chain/state:go_default_library", "//config/fieldparams:go_default_library", "//config/params:go_default_library", "//consensus-types/light-client:go_default_library", "//consensus-types/primitives:go_default_library", "//proto/prysm/v1alpha1:go_default_library", "//testing/assert:go_default_library", + "//testing/require:go_default_library", + "//testing/util:go_default_library", + "@com_github_ethereum_go_ethereum//common/hexutil:go_default_library", ], ) diff --git a/testing/util/lightclient.go b/testing/util/lightclient.go index 6c11a4c7d497..2edb8390a7aa 100644 --- a/testing/util/lightclient.go +++ b/testing/util/lightclient.go @@ -46,14 +46,14 @@ func (l *TestLightClient) SetupTestCapella(blinded bool) *TestLightClient { finalizedBlock, err := blocks.NewSignedBeaconBlock(NewBeaconBlockCapella()) require.NoError(l.T, err) - finalizedBlock.SetSlot(1) + finalizedBlock.SetSlot(primitives.Slot(params.BeaconConfig().CapellaForkEpoch * primitives.Epoch(params.BeaconConfig().SlotsPerEpoch))) finalizedHeader, err := finalizedBlock.Header() require.NoError(l.T, err) finalizedRoot, err := finalizedHeader.Header.HashTreeRoot() require.NoError(l.T, err) require.NoError(l.T, attestedState.SetFinalizedCheckpoint(ðpb.Checkpoint{ - Epoch: params.BeaconConfig().CapellaForkEpoch - 10, + Epoch: params.BeaconConfig().CapellaForkEpoch, Root: finalizedRoot[:], })) @@ -440,14 +440,14 @@ func (l *TestLightClient) SetupTestDeneb(blinded bool) *TestLightClient { finalizedBlock, err := blocks.NewSignedBeaconBlock(NewBeaconBlockDeneb()) require.NoError(l.T, err) - finalizedBlock.SetSlot(1) + finalizedBlock.SetSlot(primitives.Slot(params.BeaconConfig().DenebForkEpoch * primitives.Epoch(params.BeaconConfig().SlotsPerEpoch))) finalizedHeader, err := finalizedBlock.Header() require.NoError(l.T, err) finalizedRoot, err := finalizedHeader.Header.HashTreeRoot() require.NoError(l.T, err) require.NoError(l.T, attestedState.SetFinalizedCheckpoint(ðpb.Checkpoint{ - Epoch: params.BeaconConfig().DenebForkEpoch - 10, + Epoch: params.BeaconConfig().DenebForkEpoch, Root: finalizedRoot[:], })) @@ -664,14 +664,14 @@ func (l *TestLightClient) SetupTestDenebFinalizedBlockCapella(blinded bool) *Tes finalizedBlock, err := blocks.NewSignedBeaconBlock(NewBeaconBlockCapella()) require.NoError(l.T, err) - finalizedBlock.SetSlot(1) + finalizedBlock.SetSlot(primitives.Slot(params.BeaconConfig().DenebForkEpoch * primitives.Epoch(params.BeaconConfig().SlotsPerEpoch)).Sub(15)) finalizedHeader, err := finalizedBlock.Header() require.NoError(l.T, err) finalizedRoot, err := finalizedHeader.Header.HashTreeRoot() require.NoError(l.T, err) require.NoError(l.T, attestedState.SetFinalizedCheckpoint(ðpb.Checkpoint{ - Epoch: params.BeaconConfig().CapellaForkEpoch - 10, + Epoch: params.BeaconConfig().DenebForkEpoch - 1, Root: finalizedRoot[:], })) From 692f827294f2713884d236111f2dc8c92b439fa7 Mon Sep 17 00:00:00 2001 From: Inspector-Butters Date: Thu, 24 Oct 2024 14:34:47 +0200 Subject: [PATCH 26/35] kv tests fixed --- beacon-chain/db/kv/lightclient.go | 1 + beacon-chain/db/kv/lightclient_test.go | 1103 ++++++----------- .../rpc/eth/light-client/handlers_test.go | 84 +- 3 files changed, 403 insertions(+), 785 deletions(-) diff --git a/beacon-chain/db/kv/lightclient.go b/beacon-chain/db/kv/lightclient.go index d7bbc1796814..f4cf94668d30 100644 --- a/beacon-chain/db/kv/lightclient.go +++ b/beacon-chain/db/kv/lightclient.go @@ -96,6 +96,7 @@ func encodeLightClientUpdate(update interfaces.LightClientUpdate) ([]byte, error return nil, errors.Wrap(err, "could not marshal light client update") } fullEnc := make([]byte, len(key)+len(enc)) + copy(fullEnc, key) copy(fullEnc[len(key):], enc) return snappy.Encode(nil, fullEnc), nil } diff --git a/beacon-chain/db/kv/lightclient_test.go b/beacon-chain/db/kv/lightclient_test.go index c1eb29a13028..417d9312f78a 100644 --- a/beacon-chain/db/kv/lightclient_test.go +++ b/beacon-chain/db/kv/lightclient_test.go @@ -2,6 +2,8 @@ package kv import ( "context" + "fmt" + "math/rand" "testing" fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams" @@ -11,38 +13,155 @@ import ( "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" enginev1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1" pb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" + "github.com/prysmaticlabs/prysm/v5/runtime/version" "github.com/prysmaticlabs/prysm/v5/testing/require" "github.com/prysmaticlabs/prysm/v5/time/slots" "google.golang.org/protobuf/proto" ) -func TestStore_LightClientUpdate_CanSaveRetrieveAltair(t *testing.T) { - db := setupDB(t) - ctx := context.Background() +func createUpdate(t *testing.T, v int) (interfaces.LightClientUpdate, error) { params.SetupTestConfigCleanup(t) config := params.BeaconConfig() - update, err := createDefaultLightClientUpdate(primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1)) - require.NoError(t, err) - update.SetSignatureSlot(7) - parentRoot := make([]byte, 32) + var slot primitives.Slot + var header interfaces.LightClientHeader + var err error + + sampleRoot := make([]byte, 32) for i := 0; i < 32; i++ { - parentRoot[i] = byte(i) + sampleRoot[i] = byte(i) + } + + sampleExecutionBranch := make([][]byte, 4) + for i := 0; i < 4; i++ { + sampleExecutionBranch[i] = make([]byte, 32) + for j := 0; j < 32; j++ { + sampleExecutionBranch[i][j] = byte(i + j) + } + } + + switch v { + case version.Altair: + slot = primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) + header, err = light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{ + Beacon: &pb.BeaconBlockHeader{ + Slot: 1, + ProposerIndex: primitives.ValidatorIndex(rand.Int()), + ParentRoot: sampleRoot, + StateRoot: sampleRoot, + BodyRoot: sampleRoot, + }, + }) + require.NoError(t, err) + case version.Capella: + slot = primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) + header, err = light_client.NewWrappedHeader(&pb.LightClientHeaderCapella{ + Beacon: &pb.BeaconBlockHeader{ + Slot: 1, + ProposerIndex: primitives.ValidatorIndex(rand.Int()), + ParentRoot: sampleRoot, + StateRoot: sampleRoot, + BodyRoot: sampleRoot, + }, + Execution: &enginev1.ExecutionPayloadHeaderCapella{ + ParentHash: make([]byte, fieldparams.RootLength), + FeeRecipient: make([]byte, fieldparams.FeeRecipientLength), + StateRoot: make([]byte, fieldparams.RootLength), + ReceiptsRoot: make([]byte, fieldparams.RootLength), + LogsBloom: make([]byte, fieldparams.LogsBloomLength), + PrevRandao: make([]byte, fieldparams.RootLength), + ExtraData: make([]byte, 0), + BaseFeePerGas: make([]byte, fieldparams.RootLength), + BlockHash: make([]byte, fieldparams.RootLength), + TransactionsRoot: make([]byte, fieldparams.RootLength), + WithdrawalsRoot: make([]byte, fieldparams.RootLength), + }, + ExecutionBranch: sampleExecutionBranch, + }) + require.NoError(t, err) + case version.Deneb: + slot = primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) + header, err = light_client.NewWrappedHeader(&pb.LightClientHeaderDeneb{ + Beacon: &pb.BeaconBlockHeader{ + Slot: 1, + ProposerIndex: primitives.ValidatorIndex(rand.Int()), + ParentRoot: sampleRoot, + StateRoot: sampleRoot, + BodyRoot: sampleRoot, + }, + Execution: &enginev1.ExecutionPayloadHeaderDeneb{ + ParentHash: make([]byte, fieldparams.RootLength), + FeeRecipient: make([]byte, fieldparams.FeeRecipientLength), + StateRoot: make([]byte, fieldparams.RootLength), + ReceiptsRoot: make([]byte, fieldparams.RootLength), + LogsBloom: make([]byte, fieldparams.LogsBloomLength), + PrevRandao: make([]byte, fieldparams.RootLength), + ExtraData: make([]byte, 0), + BaseFeePerGas: make([]byte, fieldparams.RootLength), + BlockHash: make([]byte, fieldparams.RootLength), + TransactionsRoot: make([]byte, fieldparams.RootLength), + WithdrawalsRoot: make([]byte, fieldparams.RootLength), + }, + ExecutionBranch: sampleExecutionBranch, + }) + require.NoError(t, err) + default: + return nil, fmt.Errorf("unsupported version %v", v) } - simpleHeader, err := light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{ - Beacon: &pb.BeaconBlockHeader{ - Slot: 1, - ProposerIndex: 1, - ParentRoot: parentRoot, - StateRoot: []byte{1, 1, 1}, - BodyRoot: []byte{1, 1, 1}, - }, + + update, err := createDefaultLightClientUpdate(slot) + require.NoError(t, err) + update.SetSignatureSlot(slot - 1) + syncCommitteeBits := make([]byte, 64) + syncCommitteeSignature := make([]byte, 96) + update.SetSyncAggregate(&pb.SyncAggregate{ + SyncCommitteeBits: syncCommitteeBits, + SyncCommitteeSignature: syncCommitteeSignature, }) + require.NoError(t, err) - update.SetAttestedHeader(simpleHeader) - update.SetFinalizedHeader(simpleHeader) + err = update.SetAttestedHeader(header) + require.NoError(t, err) + err = update.SetFinalizedHeader(header) + require.NoError(t, err) + + return update, nil +} + +func TestStore_LightClientUpdate_CanSaveRetrieveAltair(t *testing.T) { + db := setupDB(t) + ctx := context.Background() + update, err := createUpdate(t, version.Altair) + require.NoError(t, err) + period := uint64(1) + + err = db.SaveLightClientUpdate(ctx, period, update) + require.NoError(t, err) + + retrievedUpdate, err := db.LightClientUpdate(ctx, period) + require.NoError(t, err) + require.DeepEqual(t, update, retrievedUpdate, "retrieved update does not match saved update") +} +func TestStore_LightClientUpdate_CanSaveRetrieveCapella(t *testing.T) { + db := setupDB(t) + ctx := context.Background() + update, err := createUpdate(t, version.Capella) + require.NoError(t, err) period := uint64(1) + err = db.SaveLightClientUpdate(ctx, period, update) + require.NoError(t, err) + + retrievedUpdate, err := db.LightClientUpdate(ctx, period) + require.NoError(t, err) + require.DeepEqual(t, update, retrievedUpdate, "retrieved update does not match saved update") +} +func TestStore_LightClientUpdate_CanSaveRetrieveDeneb(t *testing.T) { + db := setupDB(t) + ctx := context.Background() + update, err := createUpdate(t, version.Deneb) + require.NoError(t, err) + period := uint64(1) err = db.SaveLightClientUpdate(ctx, period, update) require.NoError(t, err) @@ -51,731 +170,229 @@ func TestStore_LightClientUpdate_CanSaveRetrieveAltair(t *testing.T) { require.DeepEqual(t, update, retrievedUpdate, "retrieved update does not match saved update") } -// -//func TestStore_LightClientUpdate_CanSaveRetrieveCapella(t *testing.T) { -// db := setupDB(t) -// ctx := context.Background() -// update := ðpbv2.LightClientUpdate{ -// AttestedHeader: ðpbv2.LightClientHeaderContainer{ -// Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ -// HeaderCapella: ðpbv2.LightClientHeaderCapella{ -// Beacon: ðpbv1.BeaconBlockHeader{ -// Slot: 1, -// ProposerIndex: 1, -// ParentRoot: []byte{1, 1, 1}, -// StateRoot: []byte{1, 1, 1}, -// BodyRoot: []byte{1, 1, 1}, -// }, -// Execution: &enginev1.ExecutionPayloadHeaderCapella{ -// FeeRecipient: []byte{1, 2, 3}, -// }, -// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, -// }, -// }, -// }, -// NextSyncCommittee: ðpbv2.SyncCommittee{ -// Pubkeys: nil, -// AggregatePubkey: nil, -// }, -// NextSyncCommitteeBranch: nil, -// FinalizedHeader: ðpbv2.LightClientHeaderContainer{ -// Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ -// HeaderCapella: ðpbv2.LightClientHeaderCapella{ -// Beacon: ðpbv1.BeaconBlockHeader{ -// Slot: 1, -// ProposerIndex: 1, -// ParentRoot: []byte{1, 1, 1}, -// StateRoot: []byte{1, 1, 1}, -// BodyRoot: []byte{1, 1, 1}, -// }, -// Execution: nil, -// ExecutionBranch: nil, -// }, -// }, -// }, -// FinalityBranch: nil, -// SyncAggregate: nil, -// SignatureSlot: 7, -// } -// period := uint64(1) -// err := db.SaveLightClientUpdate(ctx, period, ðpbv2.LightClientUpdateWithVersion{ -// Version: version.Capella, -// Data: update, -// }) -// require.NoError(t, err) -// -// retrievedUpdate, err := db.LightClientUpdate(ctx, period) -// require.NoError(t, err) -// require.DeepEqual(t, update, retrievedUpdate.Data, "retrieved update does not match saved update") -//} -// -//func TestStore_LightClientUpdate_CanSaveRetrieveDeneb(t *testing.T) { -// db := setupDB(t) -// ctx := context.Background() -// update := ðpbv2.LightClientUpdate{ -// AttestedHeader: ðpbv2.LightClientHeaderContainer{ -// Header: ðpbv2.LightClientHeaderContainer_HeaderDeneb{ -// HeaderDeneb: ðpbv2.LightClientHeaderDeneb{ -// Beacon: ðpbv1.BeaconBlockHeader{ -// Slot: 1, -// ProposerIndex: 1, -// ParentRoot: []byte{1, 1, 1}, -// StateRoot: []byte{1, 1, 1}, -// BodyRoot: []byte{1, 1, 1}, -// }, -// Execution: &enginev1.ExecutionPayloadHeaderDeneb{ -// FeeRecipient: []byte{1, 2, 3}, -// }, -// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, -// }, -// }, -// }, -// NextSyncCommittee: ðpbv2.SyncCommittee{ -// Pubkeys: nil, -// AggregatePubkey: nil, -// }, -// NextSyncCommitteeBranch: nil, -// FinalizedHeader: ðpbv2.LightClientHeaderContainer{ -// Header: ðpbv2.LightClientHeaderContainer_HeaderDeneb{ -// HeaderDeneb: ðpbv2.LightClientHeaderDeneb{ -// Beacon: ðpbv1.BeaconBlockHeader{ -// Slot: 1, -// ProposerIndex: 1, -// ParentRoot: []byte{1, 1, 1}, -// StateRoot: []byte{1, 1, 1}, -// BodyRoot: []byte{1, 1, 1}, -// }, -// Execution: nil, -// ExecutionBranch: nil, -// }, -// }, -// }, -// FinalityBranch: nil, -// SyncAggregate: nil, -// SignatureSlot: 7, -// } -// period := uint64(1) -// err := db.SaveLightClientUpdate(ctx, period, ðpbv2.LightClientUpdateWithVersion{ -// Version: version.Deneb, -// Data: update, -// }) -// require.NoError(t, err) -// -// retrievedUpdate, err := db.LightClientUpdate(ctx, period) -// require.NoError(t, err) -// require.DeepEqual(t, update, retrievedUpdate.Data, "retrieved update does not match saved update") -//} -// -//func TestStore_LightClientUpdates_canRetrieveRange(t *testing.T) { -// db := setupDB(t) -// ctx := context.Background() -// updates := []*ethpbv2.LightClientUpdateWithVersion{ -// { -// Version: 1, -// Data: ðpbv2.LightClientUpdate{ -// AttestedHeader: nil, -// NextSyncCommittee: nil, -// NextSyncCommitteeBranch: nil, -// FinalizedHeader: nil, -// FinalityBranch: nil, -// SyncAggregate: nil, -// SignatureSlot: 7, -// }, -// }, -// { -// Version: 1, -// Data: ðpbv2.LightClientUpdate{ -// AttestedHeader: nil, -// NextSyncCommittee: nil, -// NextSyncCommitteeBranch: nil, -// FinalizedHeader: nil, -// FinalityBranch: nil, -// SyncAggregate: nil, -// SignatureSlot: 8, -// }, -// }, -// { -// Version: 1, -// Data: ðpbv2.LightClientUpdate{ -// AttestedHeader: nil, -// NextSyncCommittee: nil, -// NextSyncCommitteeBranch: nil, -// FinalizedHeader: nil, -// FinalityBranch: nil, -// SyncAggregate: nil, -// SignatureSlot: 9, -// }, -// }, -// } -// -// for i, update := range updates { -// err := db.SaveLightClientUpdate(ctx, uint64(i+1), update) -// require.NoError(t, err) -// } -// -// // Retrieve the updates -// retrievedUpdatesMap, err := db.LightClientUpdates(ctx, 1, 3) -// require.NoError(t, err) -// require.Equal(t, len(updates), len(retrievedUpdatesMap), "retrieved updates do not match saved updates") -// for i, update := range updates { -// require.Equal(t, update.Data.SignatureSlot, retrievedUpdatesMap[uint64(i+1)].Data.SignatureSlot, "retrieved update does not match saved update") -// } -// -//} -// -//func TestStore_LightClientUpdate_EndPeriodSmallerThanStartPeriod(t *testing.T) { -// db := setupDB(t) -// ctx := context.Background() -// updates := []*ethpbv2.LightClientUpdateWithVersion{ -// { -// Version: 1, -// Data: ðpbv2.LightClientUpdate{ -// AttestedHeader: nil, -// NextSyncCommittee: nil, -// NextSyncCommitteeBranch: nil, -// FinalizedHeader: nil, -// FinalityBranch: nil, -// SyncAggregate: nil, -// SignatureSlot: 7, -// }, -// }, -// { -// Version: 1, -// Data: ðpbv2.LightClientUpdate{ -// AttestedHeader: nil, -// NextSyncCommittee: nil, -// NextSyncCommitteeBranch: nil, -// FinalizedHeader: nil, -// FinalityBranch: nil, -// SyncAggregate: nil, -// SignatureSlot: 8, -// }, -// }, -// { -// Version: 1, -// Data: ðpbv2.LightClientUpdate{ -// AttestedHeader: nil, -// NextSyncCommittee: nil, -// NextSyncCommitteeBranch: nil, -// FinalizedHeader: nil, -// FinalityBranch: nil, -// SyncAggregate: nil, -// SignatureSlot: 9, -// }, -// }, -// } -// -// for i, update := range updates { -// err := db.SaveLightClientUpdate(ctx, uint64(i+1), update) -// require.NoError(t, err) -// } -// -// // Retrieve the updates -// retrievedUpdates, err := db.LightClientUpdates(ctx, 3, 1) -// require.NotNil(t, err) -// require.Equal(t, err.Error(), "start period 3 is greater than end period 1") -// require.IsNil(t, retrievedUpdates) -// -//} -// -//func TestStore_LightClientUpdate_EndPeriodEqualToStartPeriod(t *testing.T) { -// db := setupDB(t) -// ctx := context.Background() -// updates := []*ethpbv2.LightClientUpdateWithVersion{ -// { -// Version: 1, -// Data: ðpbv2.LightClientUpdate{ -// AttestedHeader: nil, -// NextSyncCommittee: nil, -// NextSyncCommitteeBranch: nil, -// FinalizedHeader: nil, -// FinalityBranch: nil, -// SyncAggregate: nil, -// SignatureSlot: 7, -// }, -// }, -// { -// Version: 1, -// Data: ðpbv2.LightClientUpdate{ -// AttestedHeader: nil, -// NextSyncCommittee: nil, -// NextSyncCommitteeBranch: nil, -// FinalizedHeader: nil, -// FinalityBranch: nil, -// SyncAggregate: nil, -// SignatureSlot: 8, -// }, -// }, -// { -// Version: 1, -// Data: ðpbv2.LightClientUpdate{ -// AttestedHeader: nil, -// NextSyncCommittee: nil, -// NextSyncCommitteeBranch: nil, -// FinalizedHeader: nil, -// FinalityBranch: nil, -// SyncAggregate: nil, -// SignatureSlot: 9, -// }, -// }, -// } -// -// for i, update := range updates { -// err := db.SaveLightClientUpdate(ctx, uint64(i+1), update) -// require.NoError(t, err) -// } -// -// // Retrieve the updates -// retrievedUpdates, err := db.LightClientUpdates(ctx, 2, 2) -// require.NoError(t, err) -// require.Equal(t, 1, len(retrievedUpdates)) -// require.Equal(t, updates[1].Data.SignatureSlot, retrievedUpdates[2].Data.SignatureSlot, "retrieved update does not match saved update") -//} -// -//func TestStore_LightClientUpdate_StartPeriodBeforeFirstUpdate(t *testing.T) { -// db := setupDB(t) -// ctx := context.Background() -// updates := []*ethpbv2.LightClientUpdateWithVersion{ -// { -// Version: 1, -// Data: ðpbv2.LightClientUpdate{ -// AttestedHeader: nil, -// NextSyncCommittee: nil, -// NextSyncCommitteeBranch: nil, -// FinalizedHeader: nil, -// FinalityBranch: nil, -// SyncAggregate: nil, -// SignatureSlot: 7, -// }, -// }, -// { -// Version: 1, -// Data: ðpbv2.LightClientUpdate{ -// AttestedHeader: nil, -// NextSyncCommittee: nil, -// NextSyncCommitteeBranch: nil, -// FinalizedHeader: nil, -// FinalityBranch: nil, -// SyncAggregate: nil, -// SignatureSlot: 8, -// }, -// }, -// { -// Version: 1, -// Data: ðpbv2.LightClientUpdate{ -// AttestedHeader: nil, -// NextSyncCommittee: nil, -// NextSyncCommitteeBranch: nil, -// FinalizedHeader: nil, -// FinalityBranch: nil, -// SyncAggregate: nil, -// SignatureSlot: 9, -// }, -// }, -// } -// -// for i, update := range updates { -// err := db.SaveLightClientUpdate(ctx, uint64(i+2), update) -// require.NoError(t, err) -// } -// -// // Retrieve the updates -// retrievedUpdates, err := db.LightClientUpdates(ctx, 0, 4) -// require.NoError(t, err) -// require.Equal(t, 3, len(retrievedUpdates)) -// for i, update := range updates { -// require.Equal(t, update.Data.SignatureSlot, retrievedUpdates[uint64(i+2)].Data.SignatureSlot, "retrieved update does not match saved update") -// } -//} -// -//func TestStore_LightClientUpdate_EndPeriodAfterLastUpdate(t *testing.T) { -// db := setupDB(t) -// ctx := context.Background() -// updates := []*ethpbv2.LightClientUpdateWithVersion{ -// { -// Version: 1, -// Data: ðpbv2.LightClientUpdate{ -// AttestedHeader: nil, -// NextSyncCommittee: nil, -// NextSyncCommitteeBranch: nil, -// FinalizedHeader: nil, -// FinalityBranch: nil, -// SyncAggregate: nil, -// SignatureSlot: 7, -// }, -// }, -// { -// Version: 1, -// Data: ðpbv2.LightClientUpdate{ -// AttestedHeader: nil, -// NextSyncCommittee: nil, -// NextSyncCommitteeBranch: nil, -// FinalizedHeader: nil, -// FinalityBranch: nil, -// SyncAggregate: nil, -// SignatureSlot: 8, -// }, -// }, -// { -// Version: 1, -// Data: ðpbv2.LightClientUpdate{ -// AttestedHeader: nil, -// NextSyncCommittee: nil, -// NextSyncCommitteeBranch: nil, -// FinalizedHeader: nil, -// FinalityBranch: nil, -// SyncAggregate: nil, -// SignatureSlot: 9, -// }, -// }, -// } -// -// for i, update := range updates { -// err := db.SaveLightClientUpdate(ctx, uint64(i+1), update) -// require.NoError(t, err) -// } -// -// // Retrieve the updates -// retrievedUpdates, err := db.LightClientUpdates(ctx, 1, 6) -// require.NoError(t, err) -// require.Equal(t, 3, len(retrievedUpdates)) -// for i, update := range updates { -// require.Equal(t, update.Data.SignatureSlot, retrievedUpdates[uint64(i+1)].Data.SignatureSlot, "retrieved update does not match saved update") -// } -//} -// -//func TestStore_LightClientUpdate_PartialUpdates(t *testing.T) { -// db := setupDB(t) -// ctx := context.Background() -// updates := []*ethpbv2.LightClientUpdateWithVersion{ -// { -// Version: 1, -// Data: ðpbv2.LightClientUpdate{ -// AttestedHeader: nil, -// NextSyncCommittee: nil, -// NextSyncCommitteeBranch: nil, -// FinalizedHeader: nil, -// FinalityBranch: nil, -// SyncAggregate: nil, -// SignatureSlot: 7, -// }, -// }, -// { -// Version: 1, -// Data: ðpbv2.LightClientUpdate{ -// AttestedHeader: nil, -// NextSyncCommittee: nil, -// NextSyncCommitteeBranch: nil, -// FinalizedHeader: nil, -// FinalityBranch: nil, -// SyncAggregate: nil, -// SignatureSlot: 8, -// }, -// }, -// { -// Version: 1, -// Data: ðpbv2.LightClientUpdate{ -// AttestedHeader: nil, -// NextSyncCommittee: nil, -// NextSyncCommitteeBranch: nil, -// FinalizedHeader: nil, -// FinalityBranch: nil, -// SyncAggregate: nil, -// SignatureSlot: 9, -// }, -// }, -// } -// -// for i, update := range updates { -// err := db.SaveLightClientUpdate(ctx, uint64(i+1), update) -// require.NoError(t, err) -// } -// -// // Retrieve the updates -// retrievedUpdates, err := db.LightClientUpdates(ctx, 1, 2) -// require.NoError(t, err) -// require.Equal(t, 2, len(retrievedUpdates)) -// for i, update := range updates[:2] { -// require.Equal(t, update.Data.SignatureSlot, retrievedUpdates[uint64(i+1)].Data.SignatureSlot, "retrieved update does not match saved update") -// } -//} -// -//func TestStore_LightClientUpdate_MissingPeriods_SimpleData(t *testing.T) { -// db := setupDB(t) -// ctx := context.Background() -// updates := []*ethpbv2.LightClientUpdateWithVersion{ -// { -// Version: 1, -// Data: ðpbv2.LightClientUpdate{ -// AttestedHeader: nil, -// NextSyncCommittee: nil, -// NextSyncCommitteeBranch: nil, -// FinalizedHeader: nil, -// FinalityBranch: nil, -// SyncAggregate: nil, -// SignatureSlot: 7, -// }, -// }, -// { -// Version: 1, -// Data: ðpbv2.LightClientUpdate{ -// AttestedHeader: nil, -// NextSyncCommittee: nil, -// NextSyncCommitteeBranch: nil, -// FinalizedHeader: nil, -// FinalityBranch: nil, -// SyncAggregate: nil, -// SignatureSlot: 8, -// }, -// }, -// { -// Version: 1, -// Data: ðpbv2.LightClientUpdate{ -// AttestedHeader: nil, -// NextSyncCommittee: nil, -// NextSyncCommitteeBranch: nil, -// FinalizedHeader: nil, -// FinalityBranch: nil, -// SyncAggregate: nil, -// SignatureSlot: 11, -// }, -// }, -// { -// Version: 1, -// Data: ðpbv2.LightClientUpdate{ -// AttestedHeader: nil, -// NextSyncCommittee: nil, -// NextSyncCommitteeBranch: nil, -// FinalizedHeader: nil, -// FinalityBranch: nil, -// SyncAggregate: nil, -// SignatureSlot: 12, -// }, -// }, -// } -// -// for _, update := range updates { -// err := db.SaveLightClientUpdate(ctx, uint64(update.Data.SignatureSlot), update) -// require.NoError(t, err) -// } -// -// // Retrieve the updates -// retrievedUpdates, err := db.LightClientUpdates(ctx, 7, 12) -// require.NoError(t, err) -// require.Equal(t, 4, len(retrievedUpdates)) -// for _, update := range updates { -// require.Equal(t, update.Data.SignatureSlot, retrievedUpdates[uint64(update.Data.SignatureSlot)].Data.SignatureSlot, "retrieved update does not match saved update") -// } -// -// // Retrieve the updates from the middle -// retrievedUpdates, err = db.LightClientUpdates(ctx, 8, 12) -// require.NoError(t, err) -// require.Equal(t, 3, len(retrievedUpdates)) -// require.Equal(t, updates[1].Data.SignatureSlot, retrievedUpdates[8].Data.SignatureSlot, "retrieved update does not match saved update") -// require.Equal(t, updates[2].Data.SignatureSlot, retrievedUpdates[11].Data.SignatureSlot, "retrieved update does not match saved update") -// require.Equal(t, updates[3].Data.SignatureSlot, retrievedUpdates[12].Data.SignatureSlot, "retrieved update does not match saved update") -// -// // Retrieve the updates from after the missing period -// retrievedUpdates, err = db.LightClientUpdates(ctx, 11, 12) -// require.NoError(t, err) -// require.Equal(t, 2, len(retrievedUpdates)) -// require.Equal(t, updates[2].Data.SignatureSlot, retrievedUpdates[11].Data.SignatureSlot, "retrieved update does not match saved update") -// require.Equal(t, updates[3].Data.SignatureSlot, retrievedUpdates[12].Data.SignatureSlot, "retrieved update does not match saved update") -// -// //retrieve the updates from before the missing period to after the missing period -// retrievedUpdates, err = db.LightClientUpdates(ctx, 3, 15) -// require.NoError(t, err) -// require.Equal(t, 4, len(retrievedUpdates)) -// require.Equal(t, updates[0].Data.SignatureSlot, retrievedUpdates[7].Data.SignatureSlot, "retrieved update does not match saved update") -// require.Equal(t, updates[1].Data.SignatureSlot, retrievedUpdates[8].Data.SignatureSlot, "retrieved update does not match saved update") -// require.Equal(t, updates[2].Data.SignatureSlot, retrievedUpdates[11].Data.SignatureSlot, "retrieved update does not match saved update") -// require.Equal(t, updates[3].Data.SignatureSlot, retrievedUpdates[12].Data.SignatureSlot, "retrieved update does not match saved update") -//} -// -//func TestStore_LightClientUpdate_EmptyDB(t *testing.T) { -// db := setupDB(t) -// ctx := context.Background() -// -// // Retrieve the updates -// retrievedUpdates, err := db.LightClientUpdates(ctx, 1, 3) -// require.IsNil(t, err) -// require.Equal(t, 0, len(retrievedUpdates)) -//} -// -//func TestStore_LightClientUpdate_MissingPeriodsAtTheEnd_SimpleData(t *testing.T) { -// db := setupDB(t) -// ctx := context.Background() -// -// for i := 1; i < 4; i++ { -// update := ðpbv2.LightClientUpdateWithVersion{ -// Version: 1, -// Data: ðpbv2.LightClientUpdate{ -// AttestedHeader: nil, -// NextSyncCommittee: nil, -// NextSyncCommitteeBranch: nil, -// FinalizedHeader: nil, -// FinalityBranch: nil, -// SyncAggregate: nil, -// SignatureSlot: primitives.Slot(uint64(i)), -// }, -// } -// err := db.SaveLightClientUpdate(ctx, uint64(i), update) -// require.NoError(t, err) -// } -// for i := 7; i < 10; i++ { -// update := ðpbv2.LightClientUpdateWithVersion{ -// Version: 1, -// Data: ðpbv2.LightClientUpdate{ -// AttestedHeader: nil, -// NextSyncCommittee: nil, -// NextSyncCommitteeBranch: nil, -// FinalizedHeader: nil, -// FinalityBranch: nil, -// SyncAggregate: nil, -// SignatureSlot: primitives.Slot(uint64(i)), -// }, -// } -// err := db.SaveLightClientUpdate(ctx, uint64(i), update) -// require.NoError(t, err) -// } -// -// // Retrieve the updates from 1 to 5 -// retrievedUpdates, err := db.LightClientUpdates(ctx, 1, 5) -// require.NoError(t, err) -// require.Equal(t, 3, len(retrievedUpdates)) -// require.Equal(t, primitives.Slot(1), retrievedUpdates[1].Data.SignatureSlot, "retrieved update does not match saved update") -// require.Equal(t, primitives.Slot(2), retrievedUpdates[2].Data.SignatureSlot, "retrieved update does not match saved update") -// require.Equal(t, primitives.Slot(3), retrievedUpdates[3].Data.SignatureSlot, "retrieved update does not match saved update") -// -//} -// -//func setupLightClientTestDB(t *testing.T) (*Store, context.Context) { -// db := setupDB(t) -// ctx := context.Background() -// -// for i := 10; i < 101; i++ { // 10 to 100 -// update := ðpbv2.LightClientUpdateWithVersion{ -// Version: 1, -// Data: ðpbv2.LightClientUpdate{ -// AttestedHeader: nil, -// NextSyncCommittee: nil, -// NextSyncCommitteeBranch: nil, -// FinalizedHeader: nil, -// FinalityBranch: nil, -// SyncAggregate: nil, -// SignatureSlot: primitives.Slot(uint64(i)), -// }, -// } -// err := db.SaveLightClientUpdate(ctx, uint64(i), update) -// require.NoError(t, err) -// } -// -// for i := 110; i < 201; i++ { // 110 to 200 -// update := ðpbv2.LightClientUpdateWithVersion{ -// Version: 1, -// Data: ðpbv2.LightClientUpdate{ -// AttestedHeader: nil, -// NextSyncCommittee: nil, -// NextSyncCommitteeBranch: nil, -// FinalizedHeader: nil, -// FinalityBranch: nil, -// SyncAggregate: nil, -// SignatureSlot: primitives.Slot(uint64(i)), -// }, -// } -// err := db.SaveLightClientUpdate(ctx, uint64(i), update) -// require.NoError(t, err) -// } -// -// return db, ctx -//} -// -//func TestStore_LightClientUpdate_MissingPeriodsInTheMiddleDistributed(t *testing.T) { -// db, ctx := setupLightClientTestDB(t) -// -// // Retrieve the updates - should fail because of missing periods in the middle -// retrievedUpdates, err := db.LightClientUpdates(ctx, 1, 300) -// require.NoError(t, err) -// require.Equal(t, 91*2, len(retrievedUpdates)) -// for i := 10; i < 101; i++ { -// require.Equal(t, primitives.Slot(uint64(i)), retrievedUpdates[uint64(i)].Data.SignatureSlot, "retrieved update does not match saved update") -// } -// for i := 110; i < 201; i++ { -// require.Equal(t, primitives.Slot(uint64(i)), retrievedUpdates[uint64(i)].Data.SignatureSlot, "retrieved update does not match saved update") -// } -// -//} -// -//func TestStore_LightClientUpdate_RetrieveValidRangeFromStart(t *testing.T) { -// db, ctx := setupLightClientTestDB(t) -// -// // retrieve 1 to 100 - should work because all periods are present after the firstPeriodInDB > startPeriod -// retrievedUpdates, err := db.LightClientUpdates(ctx, 1, 100) -// require.NoError(t, err) -// require.Equal(t, 91, len(retrievedUpdates)) -// for i := 10; i < 101; i++ { -// require.Equal(t, primitives.Slot(uint64(i)), retrievedUpdates[uint64(i)].Data.SignatureSlot, "retrieved update does not match saved update") -// } -//} -// -//func TestStore_LightClientUpdate_RetrieveValidRangeInTheMiddle(t *testing.T) { -// db, ctx := setupLightClientTestDB(t) -// -// // retrieve 110 to 200 - should work because all periods are present -// retrievedUpdates, err := db.LightClientUpdates(ctx, 110, 200) -// require.NoError(t, err) -// require.Equal(t, 91, len(retrievedUpdates)) -// for i := 110; i < 201; i++ { -// require.Equal(t, primitives.Slot(uint64(i)), retrievedUpdates[uint64(i)].Data.SignatureSlot, "retrieved update does not match saved update") -// } -//} -// -//func TestStore_LightClientUpdate_MissingPeriodInTheMiddleConcentrated(t *testing.T) { -// db, ctx := setupLightClientTestDB(t) -// -// // retrieve 100 to 200 -// retrievedUpdates, err := db.LightClientUpdates(ctx, 100, 200) -// require.NoError(t, err) -// require.Equal(t, 92, len(retrievedUpdates)) -// require.Equal(t, primitives.Slot(100), retrievedUpdates[100].Data.SignatureSlot, "retrieved update does not match saved update") -// for i := 110; i < 201; i++ { -// require.Equal(t, primitives.Slot(uint64(i)), retrievedUpdates[uint64(i)].Data.SignatureSlot, "retrieved update does not match saved update") -// } -//} -// -//func TestStore_LightClientUpdate_MissingPeriodsAtTheEnd(t *testing.T) { -// db, ctx := setupLightClientTestDB(t) -// -// // retrieve 10 to 109 -// retrievedUpdates, err := db.LightClientUpdates(ctx, 10, 109) -// require.NoError(t, err) -// require.Equal(t, 91, len(retrievedUpdates)) -// for i := 10; i < 101; i++ { -// require.Equal(t, primitives.Slot(uint64(i)), retrievedUpdates[uint64(i)].Data.SignatureSlot, "retrieved update does not match saved update") -// } -//} -// -//func TestStore_LightClientUpdate_MissingPeriodsAtTheBeginning(t *testing.T) { -// db, ctx := setupLightClientTestDB(t) -// -// // retrieve 105 to 200 -// retrievedUpdates, err := db.LightClientUpdates(ctx, 105, 200) -// require.NoError(t, err) -// require.Equal(t, 91, len(retrievedUpdates)) -// for i := 110; i < 201; i++ { -// require.Equal(t, primitives.Slot(uint64(i)), retrievedUpdates[uint64(i)].Data.SignatureSlot, "retrieved update does not match saved update") -// } -//} -// -//func TestStore_LightClientUpdate_StartPeriodGreaterThanLastPeriod(t *testing.T) { -// db, ctx := setupLightClientTestDB(t) -// -// // retrieve 300 to 400 -// retrievedUpdates, err := db.LightClientUpdates(ctx, 300, 400) -// require.NoError(t, err) -// require.Equal(t, 0, len(retrievedUpdates)) -// -//} +func TestStore_LightClientUpdates_canRetrieveRange(t *testing.T) { + db := setupDB(t) + ctx := context.Background() + updates := make([]interfaces.LightClientUpdate, 0) + for i := 1; i <= 3; i++ { + update, err := createUpdate(t, version.Altair) + require.NoError(t, err) + updates = append(updates, update) + } + + for i, update := range updates { + err := db.SaveLightClientUpdate(ctx, uint64(i+1), update) + require.NoError(t, err) + } + + // Retrieve the updates + retrievedUpdatesMap, err := db.LightClientUpdates(ctx, 1, 3) + require.NoError(t, err) + require.Equal(t, len(updates), len(retrievedUpdatesMap), "retrieved updates do not match saved updates") + for i, update := range updates { + require.DeepEqual(t, update, retrievedUpdatesMap[uint64(i+1)], "retrieved update does not match saved update") + } + +} + +func TestStore_LightClientUpdate_EndPeriodSmallerThanStartPeriod(t *testing.T) { + db := setupDB(t) + ctx := context.Background() + updates := make([]interfaces.LightClientUpdate, 0) + for i := 1; i <= 3; i++ { + update, err := createUpdate(t, version.Altair) + require.NoError(t, err) + updates = append(updates, update) + } + + for i, update := range updates { + err := db.SaveLightClientUpdate(ctx, uint64(i+1), update) + require.NoError(t, err) + } + + // Retrieve the updates + retrievedUpdates, err := db.LightClientUpdates(ctx, 3, 1) + require.NotNil(t, err) + require.Equal(t, err.Error(), "start period 3 is greater than end period 1") + require.IsNil(t, retrievedUpdates) + +} + +func TestStore_LightClientUpdate_EndPeriodEqualToStartPeriod(t *testing.T) { + db := setupDB(t) + ctx := context.Background() + updates := make([]interfaces.LightClientUpdate, 0) + for i := 1; i <= 3; i++ { + update, err := createUpdate(t, version.Altair) + require.NoError(t, err) + updates = append(updates, update) + } + + for i, update := range updates { + err := db.SaveLightClientUpdate(ctx, uint64(i+1), update) + require.NoError(t, err) + } + + // Retrieve the updates + retrievedUpdates, err := db.LightClientUpdates(ctx, 2, 2) + require.NoError(t, err) + require.Equal(t, 1, len(retrievedUpdates)) + require.DeepEqual(t, updates[1], retrievedUpdates[2], "retrieved update does not match saved update") +} + +func TestStore_LightClientUpdate_StartPeriodBeforeFirstUpdate(t *testing.T) { + db := setupDB(t) + ctx := context.Background() + updates := make([]interfaces.LightClientUpdate, 0) + for i := 1; i <= 3; i++ { + update, err := createUpdate(t, version.Altair) + require.NoError(t, err) + updates = append(updates, update) + } + + for i, update := range updates { + err := db.SaveLightClientUpdate(ctx, uint64(i+1), update) + require.NoError(t, err) + } + + // Retrieve the updates + retrievedUpdates, err := db.LightClientUpdates(ctx, 0, 4) + require.NoError(t, err) + require.Equal(t, 3, len(retrievedUpdates)) + for i, update := range updates { + require.DeepEqual(t, update, retrievedUpdates[uint64(i+1)], "retrieved update does not match saved update") + } +} + +func TestStore_LightClientUpdate_EndPeriodAfterLastUpdate(t *testing.T) { + db := setupDB(t) + ctx := context.Background() + updates := make([]interfaces.LightClientUpdate, 0) + for i := 1; i <= 3; i++ { + update, err := createUpdate(t, version.Altair) + require.NoError(t, err) + updates = append(updates, update) + } + + for i, update := range updates { + err := db.SaveLightClientUpdate(ctx, uint64(i+1), update) + require.NoError(t, err) + } + + // Retrieve the updates + retrievedUpdates, err := db.LightClientUpdates(ctx, 1, 6) + require.NoError(t, err) + require.Equal(t, 3, len(retrievedUpdates)) + for i, update := range updates { + require.DeepEqual(t, update, retrievedUpdates[uint64(i+1)], "retrieved update does not match saved update") + } +} + +func TestStore_LightClientUpdate_PartialUpdates(t *testing.T) { + db := setupDB(t) + ctx := context.Background() + updates := make([]interfaces.LightClientUpdate, 0) + for i := 1; i <= 3; i++ { + update, err := createUpdate(t, version.Altair) + require.NoError(t, err) + updates = append(updates, update) + } + + for i, update := range updates { + err := db.SaveLightClientUpdate(ctx, uint64(i+1), update) + require.NoError(t, err) + } + + // Retrieve the updates + retrievedUpdates, err := db.LightClientUpdates(ctx, 1, 2) + require.NoError(t, err) + require.Equal(t, 2, len(retrievedUpdates)) + for i, update := range updates[:2] { + require.DeepEqual(t, update, retrievedUpdates[uint64(i+1)], "retrieved update does not match saved update") + } +} + +func TestStore_LightClientUpdate_MissingPeriods_SimpleData(t *testing.T) { + db := setupDB(t) + ctx := context.Background() + updates := make([]interfaces.LightClientUpdate, 0) + for i := 1; i <= 4; i++ { + update, err := createUpdate(t, version.Altair) + require.NoError(t, err) + updates = append(updates, update) + } + + for i, update := range updates { + if i == 1 || i == 2 { + continue + } + err := db.SaveLightClientUpdate(ctx, uint64(i+1), update) + require.NoError(t, err) + } + + // Retrieve the updates + retrievedUpdates, err := db.LightClientUpdates(ctx, 1, 4) + require.NoError(t, err) + require.Equal(t, 2, len(retrievedUpdates)) + require.DeepEqual(t, updates[0], retrievedUpdates[uint64(1)], "retrieved update does not match saved update") + require.DeepEqual(t, updates[3], retrievedUpdates[uint64(4)], "retrieved update does not match saved update") + + // Retrieve the updates from the middle + retrievedUpdates, err = db.LightClientUpdates(ctx, 2, 4) + require.NoError(t, err) + require.Equal(t, 1, len(retrievedUpdates)) + require.DeepEqual(t, updates[3], retrievedUpdates[4], "retrieved update does not match saved update") + + // Retrieve the updates from after the missing period + retrievedUpdates, err = db.LightClientUpdates(ctx, 4, 4) + require.NoError(t, err) + require.Equal(t, 1, len(retrievedUpdates)) + require.DeepEqual(t, updates[3], retrievedUpdates[4], "retrieved update does not match saved update") + + //retrieve the updates from before the missing period to after the missing period + retrievedUpdates, err = db.LightClientUpdates(ctx, 0, 6) + require.NoError(t, err) + require.Equal(t, 2, len(retrievedUpdates)) + require.DeepEqual(t, updates[0], retrievedUpdates[uint64(1)], "retrieved update does not match saved update") + require.DeepEqual(t, updates[3], retrievedUpdates[uint64(4)], "retrieved update does not match saved update") +} + +func TestStore_LightClientUpdate_EmptyDB(t *testing.T) { + db := setupDB(t) + ctx := context.Background() + + // Retrieve the updates + retrievedUpdates, err := db.LightClientUpdates(ctx, 1, 3) + require.IsNil(t, err) + require.Equal(t, 0, len(retrievedUpdates)) +} + +func TestStore_LightClientUpdate_RetrieveMissingPeriodDistributed(t *testing.T) { + db := setupDB(t) + ctx := context.Background() + updates := make([]interfaces.LightClientUpdate, 0) + for i := 1; i <= 5; i++ { + update, err := createUpdate(t, version.Altair) + require.NoError(t, err) + updates = append(updates, update) + } + + for i, update := range updates { + if i == 1 || i == 3 { + continue + } + err := db.SaveLightClientUpdate(ctx, uint64(i+1), update) + require.NoError(t, err) + } + + // Retrieve the updates + retrievedUpdates, err := db.LightClientUpdates(ctx, 0, 7) + require.NoError(t, err) + require.Equal(t, 3, len(retrievedUpdates)) + require.DeepEqual(t, updates[0], retrievedUpdates[uint64(1)], "retrieved update does not match saved update") + require.DeepEqual(t, updates[2], retrievedUpdates[uint64(3)], "retrieved update does not match saved update") + require.DeepEqual(t, updates[4], retrievedUpdates[uint64(5)], "retrieved update does not match saved update") +} func createDefaultLightClientUpdate(currentSlot primitives.Slot) (interfaces.LightClientUpdate, error) { currentEpoch := slots.ToEpoch(currentSlot) diff --git a/beacon-chain/rpc/eth/light-client/handlers_test.go b/beacon-chain/rpc/eth/light-client/handlers_test.go index c4696be5dffc..bbd269460718 100644 --- a/beacon-chain/rpc/eth/light-client/handlers_test.go +++ b/beacon-chain/rpc/eth/light-client/handlers_test.go @@ -104,47 +104,47 @@ func TestLightClientHandler_GetLightClientBootstrap_Bellatrix(t *testing.T) { require.NotNil(t, resp.Data.CurrentSyncCommitteeBranch) } -//func TestLightClientHandler_GetLightClientBootstrap_Capella(t *testing.T) { -// l := util.NewTestLightClient(t).SetupTestCapella(false) // result is same for true and false -// -// slot := l.State.Slot() -// stateRoot, err := l.State.HashTreeRoot(l.Ctx) -// require.NoError(t, err) -// -// mockBlocker := &testutil.MockBlocker{BlockToReturn: l.Block} -// mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot} -// mockChainInfoFetcher := &mock.ChainService{Slot: &slot} -// s := &Server{ -// Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ -// slot: l.State, -// }}, -// Blocker: mockBlocker, -// HeadFetcher: mockChainService, -// ChainInfoFetcher: mockChainInfoFetcher, -// } -// request := httptest.NewRequest("GET", "http://foo.com/", nil) -// request.SetPathValue("block_root", hexutil.Encode(stateRoot[:])) -// writer := httptest.NewRecorder() -// writer.Body = &bytes.Buffer{} -// -// s.GetLightClientBootstrap(writer, request) -// require.Equal(t, http.StatusOK, writer.Code) -// var resp structs.LightClientBootstrapResponse -// err = json.Unmarshal(writer.Body.Bytes(), &resp) -// require.NoError(t, err) -// var respHeader structs.LightClientHeader -// err = json.Unmarshal(resp.Data.Header, &respHeader) -// require.NoError(t, err) -// require.Equal(t, "capella", resp.Version) -// -// blockHeader, err := l.Block.Header() -// require.NoError(t, err) -// require.Equal(t, hexutil.Encode(blockHeader.Header.BodyRoot), respHeader.Beacon.BodyRoot) -// require.Equal(t, strconv.FormatUint(uint64(blockHeader.Header.Slot), 10), respHeader.Beacon.Slot) -// -// require.NotNil(t, resp.Data.CurrentSyncCommittee) -// require.NotNil(t, resp.Data.CurrentSyncCommitteeBranch) -//} +func TestLightClientHandler_GetLightClientBootstrap_Capella(t *testing.T) { + l := util.NewTestLightClient(t).SetupTestCapella(false) // result is same for true and false + + slot := l.State.Slot() + stateRoot, err := l.State.HashTreeRoot(l.Ctx) + require.NoError(t, err) + + mockBlocker := &testutil.MockBlocker{BlockToReturn: l.Block} + mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot} + mockChainInfoFetcher := &mock.ChainService{Slot: &slot} + s := &Server{ + Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ + slot: l.State, + }}, + Blocker: mockBlocker, + HeadFetcher: mockChainService, + ChainInfoFetcher: mockChainInfoFetcher, + } + request := httptest.NewRequest("GET", "http://foo.com/", nil) + request.SetPathValue("block_root", hexutil.Encode(stateRoot[:])) + writer := httptest.NewRecorder() + writer.Body = &bytes.Buffer{} + + s.GetLightClientBootstrap(writer, request) + require.Equal(t, http.StatusOK, writer.Code) + var resp structs.LightClientBootstrapResponse + err = json.Unmarshal(writer.Body.Bytes(), &resp) + require.NoError(t, err) + var respHeader structs.LightClientHeader + err = json.Unmarshal(resp.Data.Header, &respHeader) + require.NoError(t, err) + require.Equal(t, "capella", resp.Version) + + blockHeader, err := l.Block.Header() + require.NoError(t, err) + require.Equal(t, hexutil.Encode(blockHeader.Header.BodyRoot), respHeader.Beacon.BodyRoot) + require.Equal(t, strconv.FormatUint(uint64(blockHeader.Header.Slot), 10), respHeader.Beacon.Slot) + + require.NotNil(t, resp.Data.CurrentSyncCommittee) + require.NotNil(t, resp.Data.CurrentSyncCommitteeBranch) +} //func TestLightClientHandler_GetLightClientBootstrap_Deneb(t *testing.T) { // l := util.NewTestLightClient(t).SetupTestDeneb(false) // result is same for true and false @@ -185,7 +185,7 @@ func TestLightClientHandler_GetLightClientBootstrap_Bellatrix(t *testing.T) { // require.NotNil(t, resp.Data.CurrentSyncCommittee) // require.NotNil(t, resp.Data.CurrentSyncCommitteeBranch) //} -// + //func TestLightClientHandler_GetLightClientBootstrap_Electra(t *testing.T) { // l := util.NewTestLightClient(t).SetupTestElectra(false) // result is same for true and false // From 3db34bda514a6087ab488185ed7657d4628c2398 Mon Sep 17 00:00:00 2001 From: Rupam Dey Date: Fri, 25 Oct 2024 16:07:47 +0530 Subject: [PATCH 27/35] fix TODOs for events (#14570) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix TODOs for events * address review comments * Update beacon-chain/rpc/eth/events/events.go Co-authored-by: RadosÅ‚aw Kapka * Update beacon-chain/rpc/eth/events/events.go Co-authored-by: RadosÅ‚aw Kapka * nits --------- Co-authored-by: RadosÅ‚aw Kapka --- .../blockchain/process_block_helpers.go | 23 +++------------- beacon-chain/rpc/eth/events/events.go | 27 +++++++++---------- 2 files changed, 17 insertions(+), 33 deletions(-) diff --git a/beacon-chain/blockchain/process_block_helpers.go b/beacon-chain/blockchain/process_block_helpers.go index 7b7a5f07fba7..b5dce88d0784 100644 --- a/beacon-chain/blockchain/process_block_helpers.go +++ b/beacon-chain/blockchain/process_block_helpers.go @@ -23,7 +23,6 @@ import ( "github.com/prysmaticlabs/prysm/v5/encoding/bytesutil" mathutil "github.com/prysmaticlabs/prysm/v5/math" "github.com/prysmaticlabs/prysm/v5/monitoring/tracing/trace" - ethpbv2 "github.com/prysmaticlabs/prysm/v5/proto/eth/v2" ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" "github.com/prysmaticlabs/prysm/v5/time/slots" "github.com/sirupsen/logrus" @@ -187,7 +186,7 @@ func (s *Service) sendLightClientFinalityUpdate(ctx context.Context, signed inte } } - _, err = lightclient.NewLightClientFinalityUpdateFromBeaconState( + update, err := lightclient.NewLightClientFinalityUpdateFromBeaconState( ctx, postState.Slot(), postState, @@ -200,17 +199,10 @@ func (s *Service) sendLightClientFinalityUpdate(ctx context.Context, signed inte return 0, errors.Wrap(err, "could not create light client update") } - // Return the result - result := ðpbv2.LightClientFinalityUpdateWithVersion{ - Version: ethpbv2.Version(signed.Version()), - // TODO: Get back to this when revisiting events - //Data: update, - } - // Send event return s.cfg.StateNotifier.StateFeed().Send(&feed.Event{ Type: statefeed.LightClientFinalityUpdate, - Data: result, + Data: update, }), nil } @@ -228,7 +220,7 @@ func (s *Service) sendLightClientOptimisticUpdate(ctx context.Context, signed in return 0, errors.Wrap(err, "could not get attested state") } - _, err = lightclient.NewLightClientOptimisticUpdateFromBeaconState( + update, err := lightclient.NewLightClientOptimisticUpdateFromBeaconState( ctx, postState.Slot(), postState, @@ -240,16 +232,9 @@ func (s *Service) sendLightClientOptimisticUpdate(ctx context.Context, signed in return 0, errors.Wrap(err, "could not create light client update") } - // Return the result - result := ðpbv2.LightClientOptimisticUpdateWithVersion{ - Version: ethpbv2.Version(signed.Version()), - // TODO: Get back to this when revisiting events - //Data: update, - } - return s.cfg.StateNotifier.StateFeed().Send(&feed.Event{ Type: statefeed.LightClientOptimisticUpdate, - Data: result, + Data: update, }), nil } diff --git a/beacon-chain/rpc/eth/events/events.go b/beacon-chain/rpc/eth/events/events.go index f50687fe9436..6db6e87562cc 100644 --- a/beacon-chain/rpc/eth/events/events.go +++ b/beacon-chain/rpc/eth/events/events.go @@ -20,6 +20,7 @@ import ( chaintime "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/time" "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/transition" "github.com/prysmaticlabs/prysm/v5/config/params" + "github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces" "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" "github.com/prysmaticlabs/prysm/v5/monitoring/tracing/trace" "github.com/prysmaticlabs/prysm/v5/network/httputil" @@ -484,31 +485,29 @@ func (s *Server) lazyReaderForEvent(ctx context.Context, event *feed.Event, topi return func() io.Reader { return jsonMarshalReader(eventName, structs.FinalizedCheckpointEventFromV1(v)) }, nil - case *ethpbv2.LightClientFinalityUpdateWithVersion: - // TODO: Get back to this when revisiting events - /*cv, err := structs.LightClientFinalityUpdateFromConsensus(v.Data) + case interfaces.LightClientFinalityUpdate: + cv, err := structs.LightClientFinalityUpdateFromConsensus(v) if err != nil { - return nil, errors.Wrap(err, "LightClientFinalityUpdateWithVersion event conversion failure") + return nil, errors.Wrap(err, "LightClientFinalityUpdate conversion failure") } ev := &structs.LightClientFinalityUpdateEvent{ - Version: version.String(int(v.Version)), + Version: version.String(v.Version()), Data: cv, - }*/ + } return func() io.Reader { - return jsonMarshalReader(eventName, struct{}{}) + return jsonMarshalReader(eventName, ev) }, nil - case *ethpbv2.LightClientOptimisticUpdateWithVersion: - // TODO: Get back to this when revisiting events - /*cv, err := structs.LightClientOptimisticUpdateFromConsensus(v.Data) + case interfaces.LightClientOptimisticUpdate: + cv, err := structs.LightClientOptimisticUpdateFromConsensus(v) if err != nil { - return nil, errors.Wrap(err, "LightClientOptimisticUpdateWithVersion event conversion failure") + return nil, errors.Wrap(err, "LightClientOptimisticUpdate conversion failure") } ev := &structs.LightClientOptimisticUpdateEvent{ - Version: version.String(int(v.Version)), + Version: version.String(v.Version()), Data: cv, - }*/ + } return func() io.Reader { - return jsonMarshalReader(eventName, struct{}{}) + return jsonMarshalReader(eventName, ev) }, nil case *ethpb.EventChainReorg: return func() io.Reader { From ba1fac44f6993973b61a087f2d6caabc9cd0a0f9 Mon Sep 17 00:00:00 2001 From: Inspector-Butters Date: Fri, 25 Oct 2024 22:25:39 +0200 Subject: [PATCH 28/35] tests fixed --- beacon-chain/blockchain/BUILD.bazel | 1 - beacon-chain/rpc/eth/events/BUILD.bazel | 1 + beacon-chain/rpc/eth/light-client/BUILD.bazel | 5 + .../rpc/eth/light-client/handlers_test.go | 4147 ++++++++--------- .../rpc/eth/light-client/helpers_test.go | 96 +- 5 files changed, 1914 insertions(+), 2336 deletions(-) diff --git a/beacon-chain/blockchain/BUILD.bazel b/beacon-chain/blockchain/BUILD.bazel index c12a3d1340bd..2dc6f11a87f9 100644 --- a/beacon-chain/blockchain/BUILD.bazel +++ b/beacon-chain/blockchain/BUILD.bazel @@ -84,7 +84,6 @@ go_library( "//monitoring/tracing/trace:go_default_library", "//proto/engine/v1:go_default_library", "//proto/eth/v1:go_default_library", - "//proto/eth/v2:go_default_library", "//proto/prysm/v1alpha1:go_default_library", "//proto/prysm/v1alpha1/attestation:go_default_library", "//runtime/version:go_default_library", diff --git a/beacon-chain/rpc/eth/events/BUILD.bazel b/beacon-chain/rpc/eth/events/BUILD.bazel index caa311b6b515..74956d14e510 100644 --- a/beacon-chain/rpc/eth/events/BUILD.bazel +++ b/beacon-chain/rpc/eth/events/BUILD.bazel @@ -20,6 +20,7 @@ go_library( "//beacon-chain/core/time:go_default_library", "//beacon-chain/core/transition:go_default_library", "//config/params:go_default_library", + "//consensus-types/interfaces:go_default_library", "//consensus-types/primitives:go_default_library", "//monitoring/tracing/trace:go_default_library", "//network/httputil:go_default_library", diff --git a/beacon-chain/rpc/eth/light-client/BUILD.bazel b/beacon-chain/rpc/eth/light-client/BUILD.bazel index afee2233cdc9..94e29dc6f9d7 100644 --- a/beacon-chain/rpc/eth/light-client/BUILD.bazel +++ b/beacon-chain/rpc/eth/light-client/BUILD.bazel @@ -42,15 +42,20 @@ go_test( deps = [ "//api/server/structs:go_default_library", "//beacon-chain/blockchain/testing:go_default_library", + "//beacon-chain/core/helpers:go_default_library", "//beacon-chain/core/light-client:go_default_library", "//beacon-chain/db/kv:go_default_library", "//beacon-chain/rpc/testutil:go_default_library", "//beacon-chain/state:go_default_library", "//config/fieldparams:go_default_library", "//config/params:go_default_library", + "//consensus-types/blocks:go_default_library", + "//consensus-types/interfaces:go_default_library", "//consensus-types/light-client:go_default_library", "//consensus-types/primitives:go_default_library", + "//proto/engine/v1:go_default_library", "//proto/prysm/v1alpha1:go_default_library", + "//runtime/version:go_default_library", "//testing/assert:go_default_library", "//testing/require:go_default_library", "//testing/util:go_default_library", diff --git a/beacon-chain/rpc/eth/light-client/handlers_test.go b/beacon-chain/rpc/eth/light-client/handlers_test.go index bbd269460718..059fc8f25181 100644 --- a/beacon-chain/rpc/eth/light-client/handlers_test.go +++ b/beacon-chain/rpc/eth/light-client/handlers_test.go @@ -4,6 +4,8 @@ import ( "bytes" "context" "encoding/json" + "fmt" + "math/rand" "net/http" "net/http/httptest" "strconv" @@ -12,10 +14,20 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" "github.com/prysmaticlabs/prysm/v5/api/server/structs" mock "github.com/prysmaticlabs/prysm/v5/beacon-chain/blockchain/testing" + "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/helpers" + lightclient "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/light-client" "github.com/prysmaticlabs/prysm/v5/beacon-chain/db/kv" "github.com/prysmaticlabs/prysm/v5/beacon-chain/rpc/testutil" "github.com/prysmaticlabs/prysm/v5/beacon-chain/state" + fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams" + "github.com/prysmaticlabs/prysm/v5/config/params" + "github.com/prysmaticlabs/prysm/v5/consensus-types/blocks" + "github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces" + light_client "github.com/prysmaticlabs/prysm/v5/consensus-types/light-client" "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" + enginev1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1" + pb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" + "github.com/prysmaticlabs/prysm/v5/runtime/version" "github.com/prysmaticlabs/prysm/v5/testing/require" "github.com/prysmaticlabs/prysm/v5/testing/util" ) @@ -146,2312 +158,1733 @@ func TestLightClientHandler_GetLightClientBootstrap_Capella(t *testing.T) { require.NotNil(t, resp.Data.CurrentSyncCommitteeBranch) } -//func TestLightClientHandler_GetLightClientBootstrap_Deneb(t *testing.T) { -// l := util.NewTestLightClient(t).SetupTestDeneb(false) // result is same for true and false -// -// slot := l.State.Slot() -// stateRoot, err := l.State.HashTreeRoot(l.Ctx) -// require.NoError(t, err) -// -// mockBlocker := &testutil.MockBlocker{BlockToReturn: l.Block} -// mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot} -// s := &Server{ -// Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ -// slot: l.State, -// }}, -// Blocker: mockBlocker, -// HeadFetcher: mockChainService, -// } -// request := httptest.NewRequest("GET", "http://foo.com/", nil) -// request.SetPathValue("block_root", hexutil.Encode(stateRoot[:])) -// writer := httptest.NewRecorder() -// writer.Body = &bytes.Buffer{} -// -// s.GetLightClientBootstrap(writer, request) -// require.Equal(t, http.StatusOK, writer.Code) -// var resp structs.LightClientBootstrapResponse -// err = json.Unmarshal(writer.Body.Bytes(), &resp) -// require.NoError(t, err) -// var respHeader structs.LightClientHeader -// err = json.Unmarshal(resp.Data.Header, &respHeader) -// require.NoError(t, err) -// require.Equal(t, "deneb", resp.Version) -// -// blockHeader, err := l.Block.Header() -// require.NoError(t, err) -// require.Equal(t, hexutil.Encode(blockHeader.Header.BodyRoot), respHeader.Beacon.BodyRoot) -// require.Equal(t, strconv.FormatUint(uint64(blockHeader.Header.Slot), 10), respHeader.Beacon.Slot) -// -// require.NotNil(t, resp.Data.CurrentSyncCommittee) -// require.NotNil(t, resp.Data.CurrentSyncCommitteeBranch) -//} - -//func TestLightClientHandler_GetLightClientBootstrap_Electra(t *testing.T) { -// l := util.NewTestLightClient(t).SetupTestElectra(false) // result is same for true and false -// -// slot := l.State.Slot() -// stateRoot, err := l.State.HashTreeRoot(l.Ctx) -// require.NoError(t, err) -// -// mockBlocker := &testutil.MockBlocker{BlockToReturn: l.Block} -// mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot} -// s := &Server{ -// Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ -// slot: l.State, -// }}, -// Blocker: mockBlocker, -// HeadFetcher: mockChainService, -// } -// request := httptest.NewRequest("GET", "http://foo.com/", nil) -// request.SetPathValue("block_root", hexutil.Encode(stateRoot[:])) -// writer := httptest.NewRecorder() -// writer.Body = &bytes.Buffer{} -// -// s.GetLightClientBootstrap(writer, request) -// require.Equal(t, http.StatusOK, writer.Code) -// var resp structs.LightClientBootstrapResponse -// err = json.Unmarshal(writer.Body.Bytes(), &resp) -// require.NoError(t, err) -// var respHeader structs.LightClientHeader -// err = json.Unmarshal(resp.Data.Header, &respHeader) -// require.NoError(t, err) -// require.Equal(t, "electra", resp.Version) -// -// blockHeader, err := l.Block.Header() -// require.NoError(t, err) -// require.Equal(t, hexutil.Encode(blockHeader.Header.BodyRoot), respHeader.Beacon.BodyRoot) -// require.Equal(t, strconv.FormatUint(uint64(blockHeader.Header.Slot), 10), respHeader.Beacon.Slot) -// -// require.NotNil(t, resp.Data.CurrentSyncCommittee) -// require.NotNil(t, resp.Data.CurrentSyncCommitteeBranch) -//} +func TestLightClientHandler_GetLightClientBootstrap_Deneb(t *testing.T) { + l := util.NewTestLightClient(t).SetupTestDeneb(false) // result is same for true and false + + slot := l.State.Slot() + stateRoot, err := l.State.HashTreeRoot(l.Ctx) + require.NoError(t, err) + + mockBlocker := &testutil.MockBlocker{BlockToReturn: l.Block} + mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot} + mockChainInfoFetcher := &mock.ChainService{Slot: &slot} + s := &Server{ + Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ + slot: l.State, + }}, + Blocker: mockBlocker, + HeadFetcher: mockChainService, + ChainInfoFetcher: mockChainInfoFetcher, + } + request := httptest.NewRequest("GET", "http://foo.com/", nil) + request.SetPathValue("block_root", hexutil.Encode(stateRoot[:])) + writer := httptest.NewRecorder() + writer.Body = &bytes.Buffer{} + + s.GetLightClientBootstrap(writer, request) + require.Equal(t, http.StatusOK, writer.Code) + var resp structs.LightClientBootstrapResponse + err = json.Unmarshal(writer.Body.Bytes(), &resp) + require.NoError(t, err) + var respHeader structs.LightClientHeader + err = json.Unmarshal(resp.Data.Header, &respHeader) + require.NoError(t, err) + require.Equal(t, "deneb", resp.Version) + + blockHeader, err := l.Block.Header() + require.NoError(t, err) + require.Equal(t, hexutil.Encode(blockHeader.Header.BodyRoot), respHeader.Beacon.BodyRoot) + require.Equal(t, strconv.FormatUint(uint64(blockHeader.Header.Slot), 10), respHeader.Beacon.Slot) + + require.NotNil(t, resp.Data.CurrentSyncCommittee) + require.NotNil(t, resp.Data.CurrentSyncCommitteeBranch) +} + +func TestLightClientHandler_GetLightClientBootstrap_Electra(t *testing.T) { + l := util.NewTestLightClient(t).SetupTestElectra(false) // result is same for true and false + + slot := l.State.Slot() + stateRoot, err := l.State.HashTreeRoot(l.Ctx) + require.NoError(t, err) + + mockBlocker := &testutil.MockBlocker{BlockToReturn: l.Block} + mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot} + mockChainInfoFetcher := &mock.ChainService{Slot: &slot} + s := &Server{ + Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ + slot: l.State, + }}, + Blocker: mockBlocker, + HeadFetcher: mockChainService, + ChainInfoFetcher: mockChainInfoFetcher, + } + request := httptest.NewRequest("GET", "http://foo.com/", nil) + request.SetPathValue("block_root", hexutil.Encode(stateRoot[:])) + writer := httptest.NewRecorder() + writer.Body = &bytes.Buffer{} + + s.GetLightClientBootstrap(writer, request) + require.Equal(t, http.StatusOK, writer.Code) + var resp structs.LightClientBootstrapResponse + err = json.Unmarshal(writer.Body.Bytes(), &resp) + require.NoError(t, err) + var respHeader structs.LightClientHeader + err = json.Unmarshal(resp.Data.Header, &respHeader) + require.NoError(t, err) + require.Equal(t, "electra", resp.Version) + + blockHeader, err := l.Block.Header() + require.NoError(t, err) + require.Equal(t, hexutil.Encode(blockHeader.Header.BodyRoot), respHeader.Beacon.BodyRoot) + require.Equal(t, strconv.FormatUint(uint64(blockHeader.Header.Slot), 10), respHeader.Beacon.Slot) + + require.NotNil(t, resp.Data.CurrentSyncCommittee) + require.NotNil(t, resp.Data.CurrentSyncCommitteeBranch) +} // GetLightClientByRange tests -//func TestLightClientHandler_GetLightClientUpdatesByRangeAltair(t *testing.T) { -// helpers.ClearCache() -// ctx := context.Background() -// -// params.SetupTestConfigCleanup(t) -// config := params.BeaconConfig() -// config.AltairForkEpoch = 0 -// params.OverrideBeaconConfig(config) -// -// slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) -// -// st, err := util.NewBeaconStateAltair() -// require.NoError(t, err) -// err = st.SetSlot(slot) -// require.NoError(t, err) -// -// db := setupDB(t) -// -// updatePeriod := uint64(slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch))) -// -// updateRaw := &pb.LightClientUpdateAltair{ -// AttestedHeader: &pb.LightClientHeaderAltair{ -// Beacon: &pb.BeaconBlockHeader{ -// Slot: slot.Sub(1), -// ProposerIndex: 1, -// ParentRoot: []byte{1, 1, 1}, -// StateRoot: []byte{1, 1, 1}, -// BodyRoot: []byte{1, 1, 1}, -// }, -// }, -// NextSyncCommittee: &pb.SyncCommittee{ -// Pubkeys: nil, -// AggregatePubkey: nil, -// }, -// NextSyncCommitteeBranch: nil, -// FinalizedHeader: nil, -// FinalityBranch: nil, -// SyncAggregate: &pb.SyncAggregate{ -// SyncCommitteeBits: []byte{1, 1, 1}, -// SyncCommitteeSignature: []byte{1, 1, 1}, -// }, -// SignatureSlot: 7, -// } -// -// update, err := light_client.NewWrappedUpdate(updateRaw) -// require.NoError(t, err) -// err = db.SaveLightClientUpdate(ctx, updatePeriod, update) -// require.NoError(t, err) -// -// mockChainService := &mock.ChainService{State: st} -// s := &Server{ -// HeadFetcher: mockChainService, -// BeaconDB: db, -// } -// startPeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) -// url := fmt.Sprintf("http://foo.com/?count=1&start_period=%d", startPeriod) -// request := httptest.NewRequest("GET", url, nil) -// writer := httptest.NewRecorder() -// writer.Body = &bytes.Buffer{} -// -// s.GetLightClientUpdatesByRange(writer, request) -// -// require.Equal(t, http.StatusOK, writer.Code) -// var resp structs.LightClientUpdatesByRangeResponse -// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) -// require.NoError(t, err) -// require.Equal(t, 1, len(resp.Updates)) -// require.Equal(t, "altair", resp.Updates[0].Version) -// updateJson, err := structs.LightClientUpdateFromConsensus(update) -// require.NoError(t, err) -// require.DeepEqual(t, updateJson, resp.Updates[0].Data) -//} - -// func TestLightClientHandler_GetLightClientUpdatesByRangeCapella(t *testing.T) { -// helpers.ClearCache() -// ctx := context.Background() -// params.SetupTestConfigCleanup(t) -// config := params.BeaconConfig() -// config.AltairForkEpoch = 0 -// config.CapellaForkEpoch = 1 -// params.OverrideBeaconConfig(config) -// slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) -// -// st, err := util.NewBeaconStateCapella() -// require.NoError(t, err) -// err = st.SetSlot(slot) -// require.NoError(t, err) -// -// db := setupDB(t) -// -// updatePeriod := uint64(slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch))) -// -// update := ðpbv2.LightClientUpdate{ -// AttestedHeader: ðpbv2.LightClientHeaderContainer{ -// Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ -// HeaderCapella: ðpbv2.LightClientHeaderCapella{ -// Beacon: ðpbv1.BeaconBlockHeader{ -// Slot: slot.Sub(1), -// ProposerIndex: 1, -// ParentRoot: []byte{1, 1, 1}, -// StateRoot: []byte{1, 1, 1}, -// BodyRoot: []byte{1, 1, 1}, -// }, -// Execution: &enginev1.ExecutionPayloadHeaderCapella{ -// FeeRecipient: []byte{1, 2, 3}, -// }, -// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, -// }, -// }, -// }, -// NextSyncCommittee: ðpbv2.SyncCommittee{ -// Pubkeys: nil, -// AggregatePubkey: nil, -// }, -// NextSyncCommitteeBranch: nil, -// FinalizedHeader: ðpbv2.LightClientHeaderContainer{ -// Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ -// HeaderCapella: ðpbv2.LightClientHeaderCapella{ -// Beacon: ðpbv1.BeaconBlockHeader{ -// Slot: 12, -// ProposerIndex: 1, -// ParentRoot: []byte{1, 1, 1}, -// StateRoot: []byte{1, 1, 1}, -// BodyRoot: []byte{1, 1, 1}, -// }, -// Execution: &enginev1.ExecutionPayloadHeaderCapella{ -// FeeRecipient: []byte{1, 2, 3}, -// }, -// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, -// }, -// }, -// }, -// FinalityBranch: nil, -// SyncAggregate: ðpbv1.SyncAggregate{ -// SyncCommitteeBits: []byte{1, 1, 1}, -// SyncCommitteeSignature: []byte{1, 1, 1}, -// }, -// SignatureSlot: 7, -// } -// -// err = db.SaveLightClientUpdate(ctx, updatePeriod, ðpbv2.LightClientUpdateWithVersion{ -// Version: version.Capella, -// Data: update, -// }) -// require.NoError(t, err) -// -// mockChainService := &mock.ChainService{State: st} -// s := &Server{ -// HeadFetcher: mockChainService, -// BeaconDB: db, -// } -// startPeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) -// url := fmt.Sprintf("http://foo.com/?count=1&start_period=%d", startPeriod) -// request := httptest.NewRequest("GET", url, nil) -// writer := httptest.NewRecorder() -// writer.Body = &bytes.Buffer{} -// -// s.GetLightClientUpdatesByRange(writer, request) -// -// require.Equal(t, http.StatusOK, writer.Code) -// var resp structs.LightClientUpdatesByRangeResponse -// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) -// require.NoError(t, err) -// require.Equal(t, 1, len(resp.Updates)) -// require.Equal(t, "capella", resp.Updates[0].Version) -// updateJson, err := structs.LightClientUpdateFromConsensus(update) -// require.NoError(t, err) -// require.DeepEqual(t, updateJson, resp.Updates[0].Data) -// } -// -// func TestLightClientHandler_GetLightClientUpdatesByRangeDeneb(t *testing.T) { -// helpers.ClearCache() -// ctx := context.Background() -// params.SetupTestConfigCleanup(t) -// config := params.BeaconConfig() -// config.AltairForkEpoch = 0 -// config.DenebForkEpoch = 1 -// params.OverrideBeaconConfig(config) -// slot := primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) -// -// st, err := util.NewBeaconStateDeneb() -// require.NoError(t, err) -// err = st.SetSlot(slot) -// require.NoError(t, err) -// -// db := setupDB(t) -// -// updatePeriod := uint64(slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch))) -// -// update := ðpbv2.LightClientUpdate{ -// AttestedHeader: ðpbv2.LightClientHeaderContainer{ -// Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ -// HeaderCapella: ðpbv2.LightClientHeaderCapella{ -// Beacon: ðpbv1.BeaconBlockHeader{ -// Slot: slot.Sub(1), -// ProposerIndex: 1, -// ParentRoot: []byte{1, 1, 1}, -// StateRoot: []byte{1, 1, 1}, -// BodyRoot: []byte{1, 1, 1}, -// }, -// Execution: &enginev1.ExecutionPayloadHeaderCapella{ -// FeeRecipient: []byte{1, 2, 3}, -// }, -// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, -// }, -// }, -// }, -// NextSyncCommittee: ðpbv2.SyncCommittee{ -// Pubkeys: nil, -// AggregatePubkey: nil, -// }, -// NextSyncCommitteeBranch: nil, -// FinalizedHeader: ðpbv2.LightClientHeaderContainer{ -// Header: ðpbv2.LightClientHeaderContainer_HeaderDeneb{ -// HeaderDeneb: ðpbv2.LightClientHeaderDeneb{ -// Beacon: ðpbv1.BeaconBlockHeader{ -// Slot: 12, -// ProposerIndex: 1, -// ParentRoot: []byte{1, 1, 1}, -// StateRoot: []byte{1, 1, 1}, -// BodyRoot: []byte{1, 1, 1}, -// }, -// Execution: &enginev1.ExecutionPayloadHeaderDeneb{ -// FeeRecipient: []byte{1, 2, 3}, -// }, -// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, -// }, -// }, -// }, -// FinalityBranch: nil, -// SyncAggregate: ðpbv1.SyncAggregate{ -// SyncCommitteeBits: []byte{1, 1, 1}, -// SyncCommitteeSignature: []byte{1, 1, 1}, -// }, -// SignatureSlot: 7, -// } -// -// err = db.SaveLightClientUpdate(ctx, updatePeriod, ðpbv2.LightClientUpdateWithVersion{ -// Version: version.Deneb, -// Data: update, -// }) -// require.NoError(t, err) -// -// mockChainService := &mock.ChainService{State: st} -// s := &Server{ -// HeadFetcher: mockChainService, -// BeaconDB: db, -// } -// startPeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) -// url := fmt.Sprintf("http://foo.com/?count=1&start_period=%d", startPeriod) -// request := httptest.NewRequest("GET", url, nil) -// writer := httptest.NewRecorder() -// writer.Body = &bytes.Buffer{} -// -// s.GetLightClientUpdatesByRange(writer, request) -// -// require.Equal(t, http.StatusOK, writer.Code) -// var resp structs.LightClientUpdatesByRangeResponse -// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) -// require.NoError(t, err) -// require.Equal(t, 1, len(resp.Updates)) -// require.Equal(t, "deneb", resp.Updates[0].Version) -// updateJson, err := structs.LightClientUpdateFromConsensus(update) -// require.NoError(t, err) -// require.DeepEqual(t, updateJson, resp.Updates[0].Data) -// } -// -// func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleAltair(t *testing.T) { -// helpers.ClearCache() -// ctx := context.Background() -// params.SetupTestConfigCleanup(t) -// config := params.BeaconConfig() -// config.AltairForkEpoch = 0 -// config.EpochsPerSyncCommitteePeriod = 1 -// params.OverrideBeaconConfig(config) -// slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) -// -// st, err := util.NewBeaconStateAltair() -// require.NoError(t, err) -// headSlot := slot.Add(33) // 2 periods -// err = st.SetSlot(headSlot) -// require.NoError(t, err) -// -// db := setupDB(t) -// -// updates := make([]*ethpbv2.LightClientUpdate, 2) -// -// updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) -// -// for i := 0; i < 2; i++ { -// newSlot := slot.Add(uint64(i)) -// -// update := ðpbv2.LightClientUpdate{ -// AttestedHeader: ðpbv2.LightClientHeaderContainer{ -// Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ -// HeaderAltair: ðpbv2.LightClientHeader{ -// Beacon: ðpbv1.BeaconBlockHeader{ -// Slot: newSlot, -// ProposerIndex: 1, -// ParentRoot: []byte{1, 1, 1}, -// StateRoot: []byte{1, 1, 1}, -// BodyRoot: []byte{1, 1, 1}, -// }, -// }, -// }, -// }, -// NextSyncCommittee: ðpbv2.SyncCommittee{ -// Pubkeys: nil, -// AggregatePubkey: nil, -// }, -// NextSyncCommitteeBranch: nil, -// FinalizedHeader: nil, -// FinalityBranch: nil, -// SyncAggregate: ðpbv1.SyncAggregate{ -// SyncCommitteeBits: []byte{1, 1, 1}, -// SyncCommitteeSignature: []byte{1, 1, 1}, -// }, -// SignatureSlot: 7, -// } -// -// updates[i] = update -// -// err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ -// Version: version.Altair, -// Data: update, -// }) -// require.NoError(t, err) -// -// updatePeriod++ -// } -// -// mockChainService := &mock.ChainService{State: st} -// s := &Server{ -// HeadFetcher: mockChainService, -// BeaconDB: db, -// } -// startPeriod := slot.Sub(1).Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) -// url := fmt.Sprintf("http://foo.com/?count=100&start_period=%d", startPeriod) -// request := httptest.NewRequest("GET", url, nil) -// writer := httptest.NewRecorder() -// writer.Body = &bytes.Buffer{} -// -// s.GetLightClientUpdatesByRange(writer, request) -// -// require.Equal(t, http.StatusOK, writer.Code) -// var resp structs.LightClientUpdatesByRangeResponse -// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) -// require.NoError(t, err) -// require.Equal(t, 2, len(resp.Updates)) -// for i, update := range updates { -// require.Equal(t, "altair", resp.Updates[i].Version) -// updateJson, err := structs.LightClientUpdateFromConsensus(update) -// require.NoError(t, err) -// require.DeepEqual(t, updateJson, resp.Updates[i].Data) -// } -// } -// -// func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleCapella(t *testing.T) { -// helpers.ClearCache() -// ctx := context.Background() -// params.SetupTestConfigCleanup(t) -// config := params.BeaconConfig() -// config.AltairForkEpoch = 0 -// config.CapellaForkEpoch = 1 -// config.EpochsPerSyncCommitteePeriod = 1 -// params.OverrideBeaconConfig(config) -// slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) -// -// st, err := util.NewBeaconStateAltair() -// require.NoError(t, err) -// headSlot := slot.Add(33) // 2 periods -// err = st.SetSlot(headSlot) -// require.NoError(t, err) -// -// db := setupDB(t) -// -// updates := make([]*ethpbv2.LightClientUpdate, 2) -// -// updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) -// -// for i := 0; i < 2; i++ { -// -// newSlot := slot.Add(uint64(i)) -// -// update := ðpbv2.LightClientUpdate{ -// AttestedHeader: ðpbv2.LightClientHeaderContainer{ -// Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ -// HeaderCapella: ðpbv2.LightClientHeaderCapella{ -// Beacon: ðpbv1.BeaconBlockHeader{ -// Slot: newSlot, -// ProposerIndex: 1, -// ParentRoot: []byte{1, 1, 1}, -// StateRoot: []byte{1, 1, 1}, -// BodyRoot: []byte{1, 1, 1}, -// }, -// Execution: &enginev1.ExecutionPayloadHeaderCapella{ -// FeeRecipient: []byte{1, 2, 3}, -// }, -// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, -// }, -// }, -// }, -// NextSyncCommittee: ðpbv2.SyncCommittee{ -// Pubkeys: nil, -// AggregatePubkey: nil, -// }, -// NextSyncCommitteeBranch: nil, -// FinalizedHeader: ðpbv2.LightClientHeaderContainer{ -// Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ -// HeaderCapella: ðpbv2.LightClientHeaderCapella{ -// Beacon: ðpbv1.BeaconBlockHeader{ -// Slot: 12, -// ProposerIndex: 1, -// ParentRoot: []byte{1, 1, 1}, -// StateRoot: []byte{1, 1, 1}, -// BodyRoot: []byte{1, 1, 1}, -// }, -// Execution: &enginev1.ExecutionPayloadHeaderCapella{ -// FeeRecipient: []byte{1, 2, 3}, -// }, -// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, -// }, -// }, -// }, -// FinalityBranch: nil, -// SyncAggregate: ðpbv1.SyncAggregate{ -// SyncCommitteeBits: []byte{1, 1, 1}, -// SyncCommitteeSignature: []byte{1, 1, 1}, -// }, -// SignatureSlot: 7, -// } -// -// updates[i] = update -// -// err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ -// Version: version.Capella, -// Data: update, -// }) -// require.NoError(t, err) -// -// updatePeriod++ -// } -// -// mockChainService := &mock.ChainService{State: st} -// s := &Server{ -// HeadFetcher: mockChainService, -// BeaconDB: db, -// } -// startPeriod := slot.Sub(1).Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) -// url := fmt.Sprintf("http://foo.com/?count=100&start_period=%d", startPeriod) -// request := httptest.NewRequest("GET", url, nil) -// writer := httptest.NewRecorder() -// writer.Body = &bytes.Buffer{} -// -// s.GetLightClientUpdatesByRange(writer, request) -// -// require.Equal(t, http.StatusOK, writer.Code) -// var resp structs.LightClientUpdatesByRangeResponse -// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) -// require.NoError(t, err) -// require.Equal(t, 2, len(resp.Updates)) -// for i, update := range updates { -// require.Equal(t, "capella", resp.Updates[i].Version) -// updateJson, err := structs.LightClientUpdateFromConsensus(update) -// require.NoError(t, err) -// require.DeepEqual(t, updateJson, resp.Updates[i].Data) -// } -// } -// -// func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleDeneb(t *testing.T) { -// helpers.ClearCache() -// ctx := context.Background() -// params.SetupTestConfigCleanup(t) -// config := params.BeaconConfig() -// config.AltairForkEpoch = 0 -// config.DenebForkEpoch = 1 -// config.EpochsPerSyncCommitteePeriod = 1 -// params.OverrideBeaconConfig(config) -// slot := primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) -// -// st, err := util.NewBeaconStateAltair() -// require.NoError(t, err) -// headSlot := slot.Add(33) -// err = st.SetSlot(headSlot) -// require.NoError(t, err) -// -// db := setupDB(t) -// -// updates := make([]*ethpbv2.LightClientUpdate, 2) -// -// updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) -// -// for i := 0; i < 2; i++ { -// -// newSlot := slot.Add(uint64(i)) -// -// update := ðpbv2.LightClientUpdate{ -// AttestedHeader: ðpbv2.LightClientHeaderContainer{ -// Header: ðpbv2.LightClientHeaderContainer_HeaderDeneb{ -// HeaderDeneb: ðpbv2.LightClientHeaderDeneb{ -// Beacon: ðpbv1.BeaconBlockHeader{ -// Slot: newSlot, -// ProposerIndex: 1, -// ParentRoot: []byte{1, 1, 1}, -// StateRoot: []byte{1, 1, 1}, -// BodyRoot: []byte{1, 1, 1}, -// }, -// Execution: &enginev1.ExecutionPayloadHeaderDeneb{ -// FeeRecipient: []byte{1, 2, 3}, -// }, -// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, -// }, -// }, -// }, -// NextSyncCommittee: ðpbv2.SyncCommittee{ -// Pubkeys: nil, -// AggregatePubkey: nil, -// }, -// NextSyncCommitteeBranch: nil, -// FinalizedHeader: ðpbv2.LightClientHeaderContainer{ -// Header: ðpbv2.LightClientHeaderContainer_HeaderDeneb{ -// HeaderDeneb: ðpbv2.LightClientHeaderDeneb{ -// Beacon: ðpbv1.BeaconBlockHeader{ -// Slot: 12, -// ProposerIndex: 1, -// ParentRoot: []byte{1, 1, 1}, -// StateRoot: []byte{1, 1, 1}, -// BodyRoot: []byte{1, 1, 1}, -// }, -// Execution: &enginev1.ExecutionPayloadHeaderDeneb{ -// FeeRecipient: []byte{1, 2, 3}, -// }, -// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, -// }, -// }, -// }, -// FinalityBranch: nil, -// SyncAggregate: ðpbv1.SyncAggregate{ -// SyncCommitteeBits: []byte{1, 1, 1}, -// SyncCommitteeSignature: []byte{1, 1, 1}, -// }, -// SignatureSlot: 7, -// } -// -// updates[i] = update -// -// err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ -// Version: version.Deneb, -// Data: update, -// }) -// require.NoError(t, err) -// -// updatePeriod++ -// } -// -// mockChainService := &mock.ChainService{State: st} -// s := &Server{ -// HeadFetcher: mockChainService, -// BeaconDB: db, -// } -// startPeriod := slot.Sub(1).Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) -// url := fmt.Sprintf("http://foo.com/?count=100&start_period=%d", startPeriod) -// request := httptest.NewRequest("GET", url, nil) -// writer := httptest.NewRecorder() -// writer.Body = &bytes.Buffer{} -// -// s.GetLightClientUpdatesByRange(writer, request) -// -// require.Equal(t, http.StatusOK, writer.Code) -// var resp structs.LightClientUpdatesByRangeResponse -// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) -// require.NoError(t, err) -// require.Equal(t, 2, len(resp.Updates)) -// for i, update := range updates { -// require.Equal(t, "deneb", resp.Updates[i].Version) -// updateJson, err := structs.LightClientUpdateFromConsensus(update) -// require.NoError(t, err) -// require.DeepEqual(t, updateJson, resp.Updates[i].Data) -// } -// } -// -// func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleForksAltairCapella(t *testing.T) { -// helpers.ClearCache() -// ctx := context.Background() -// params.SetupTestConfigCleanup(t) -// config := params.BeaconConfig() -// config.AltairForkEpoch = 0 -// config.CapellaForkEpoch = 1 -// config.EpochsPerSyncCommitteePeriod = 1 -// params.OverrideBeaconConfig(config) -// slotCapella := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) -// slotAltair := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) -// -// st, err := util.NewBeaconStateAltair() -// require.NoError(t, err) -// headSlot := slotCapella.Add(1) -// err = st.SetSlot(headSlot) -// require.NoError(t, err) -// -// db := setupDB(t) -// -// updates := make([]*ethpbv2.LightClientUpdate, 2) -// -// updatePeriod := slotAltair.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) -// -// update := ðpbv2.LightClientUpdate{ -// AttestedHeader: ðpbv2.LightClientHeaderContainer{ -// Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ -// HeaderAltair: ðpbv2.LightClientHeader{ -// Beacon: ðpbv1.BeaconBlockHeader{ -// Slot: slotAltair, -// ProposerIndex: 1, -// ParentRoot: []byte{1, 1, 1}, -// StateRoot: []byte{1, 1, 1}, -// BodyRoot: []byte{1, 1, 1}, -// }, -// }, -// }, -// }, -// NextSyncCommittee: ðpbv2.SyncCommittee{ -// Pubkeys: nil, -// AggregatePubkey: nil, -// }, -// NextSyncCommitteeBranch: nil, -// FinalizedHeader: ðpbv2.LightClientHeaderContainer{ -// Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ -// HeaderAltair: ðpbv2.LightClientHeader{ -// Beacon: ðpbv1.BeaconBlockHeader{ -// Slot: 12, -// ProposerIndex: 1, -// ParentRoot: []byte{1, 1, 1}, -// StateRoot: []byte{1, 1, 1}, -// BodyRoot: []byte{1, 1, 1}, -// }, -// }, -// }, -// }, -// FinalityBranch: nil, -// SyncAggregate: ðpbv1.SyncAggregate{ -// SyncCommitteeBits: []byte{1, 1, 1}, -// SyncCommitteeSignature: []byte{1, 1, 1}, -// }, -// SignatureSlot: slotAltair, -// } -// -// updates[0] = update -// -// err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ -// Version: version.Altair, -// Data: update, -// }) -// require.NoError(t, err) -// -// updatePeriod = slotCapella.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) -// -// update = ðpbv2.LightClientUpdate{ -// AttestedHeader: ðpbv2.LightClientHeaderContainer{ -// Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ -// HeaderCapella: ðpbv2.LightClientHeaderCapella{ -// Beacon: ðpbv1.BeaconBlockHeader{ -// Slot: slotCapella, -// ProposerIndex: 1, -// ParentRoot: []byte{1, 1, 1}, -// StateRoot: []byte{1, 1, 1}, -// BodyRoot: []byte{1, 1, 1}, -// }, -// Execution: &enginev1.ExecutionPayloadHeaderCapella{ -// FeeRecipient: []byte{1, 2, 3}, -// }, -// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, -// }, -// }, -// }, -// NextSyncCommittee: ðpbv2.SyncCommittee{ -// Pubkeys: nil, -// AggregatePubkey: nil, -// }, -// NextSyncCommitteeBranch: nil, -// FinalizedHeader: ðpbv2.LightClientHeaderContainer{ -// Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ -// HeaderCapella: ðpbv2.LightClientHeaderCapella{ -// Beacon: ðpbv1.BeaconBlockHeader{ -// Slot: 12, -// ProposerIndex: 1, -// ParentRoot: []byte{1, 1, 1}, -// StateRoot: []byte{1, 1, 1}, -// BodyRoot: []byte{1, 1, 1}, -// }, -// Execution: &enginev1.ExecutionPayloadHeaderCapella{ -// FeeRecipient: []byte{1, 2, 3}, -// }, -// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, -// }, -// }, -// }, -// FinalityBranch: nil, -// SyncAggregate: ðpbv1.SyncAggregate{ -// SyncCommitteeBits: []byte{1, 1, 1}, -// SyncCommitteeSignature: []byte{1, 1, 1}, -// }, -// SignatureSlot: slotCapella, -// } -// -// updates[1] = update -// -// err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ -// Version: version.Capella, -// Data: update, -// }) -// require.NoError(t, err) -// -// mockChainService := &mock.ChainService{State: st} -// s := &Server{ -// HeadFetcher: mockChainService, -// BeaconDB: db, -// } -// startPeriod := 0 -// url := fmt.Sprintf("http://foo.com/?count=100&start_period=%d", startPeriod) -// request := httptest.NewRequest("GET", url, nil) -// writer := httptest.NewRecorder() -// writer.Body = &bytes.Buffer{} -// -// s.GetLightClientUpdatesByRange(writer, request) -// -// require.Equal(t, http.StatusOK, writer.Code) -// var resp structs.LightClientUpdatesByRangeResponse -// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) -// require.NoError(t, err) -// require.Equal(t, 2, len(resp.Updates)) -// for i, update := range updates { -// if i < 1 { -// require.Equal(t, "altair", resp.Updates[i].Version) -// } else { -// require.Equal(t, "capella", resp.Updates[i].Version) -// } -// updateJson, err := structs.LightClientUpdateFromConsensus(update) -// require.NoError(t, err) -// require.DeepEqual(t, updateJson, resp.Updates[i].Data) -// } -// } -// -// func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleForksCapellaDeneb(t *testing.T) { -// helpers.ClearCache() -// ctx := context.Background() -// params.SetupTestConfigCleanup(t) -// config := params.BeaconConfig() -// config.AltairForkEpoch = 0 -// config.CapellaForkEpoch = 1 -// config.DenebForkEpoch = 2 -// config.EpochsPerSyncCommitteePeriod = 1 -// params.OverrideBeaconConfig(config) -// slotDeneb := primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) -// slotCapella := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) -// -// st, err := util.NewBeaconStateAltair() -// require.NoError(t, err) -// headSlot := slotDeneb.Add(1) -// err = st.SetSlot(headSlot) -// require.NoError(t, err) -// -// db := setupDB(t) -// -// updates := make([]*ethpbv2.LightClientUpdate, 2) -// -// updatePeriod := slotCapella.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) -// -// update := ðpbv2.LightClientUpdate{ -// AttestedHeader: ðpbv2.LightClientHeaderContainer{ -// Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ -// HeaderCapella: ðpbv2.LightClientHeaderCapella{ -// Beacon: ðpbv1.BeaconBlockHeader{ -// Slot: slotCapella, -// ProposerIndex: 1, -// ParentRoot: []byte{1, 1, 1}, -// StateRoot: []byte{1, 1, 1}, -// BodyRoot: []byte{1, 1, 1}, -// }, -// Execution: &enginev1.ExecutionPayloadHeaderCapella{ -// FeeRecipient: []byte{1, 2, 3}, -// }, -// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, -// }, -// }, -// }, -// NextSyncCommittee: ðpbv2.SyncCommittee{ -// Pubkeys: nil, -// AggregatePubkey: nil, -// }, -// NextSyncCommitteeBranch: nil, -// FinalizedHeader: ðpbv2.LightClientHeaderContainer{ -// Header: ðpbv2.LightClientHeaderContainer_HeaderCapella{ -// HeaderCapella: ðpbv2.LightClientHeaderCapella{ -// Beacon: ðpbv1.BeaconBlockHeader{ -// Slot: 12, -// ProposerIndex: 1, -// ParentRoot: []byte{1, 1, 1}, -// StateRoot: []byte{1, 1, 1}, -// BodyRoot: []byte{1, 1, 1}, -// }, -// Execution: &enginev1.ExecutionPayloadHeaderCapella{ -// FeeRecipient: []byte{1, 2, 3}, -// }, -// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, -// }, -// }, -// }, -// FinalityBranch: nil, -// SyncAggregate: ðpbv1.SyncAggregate{ -// SyncCommitteeBits: []byte{1, 1, 1}, -// SyncCommitteeSignature: []byte{1, 1, 1}, -// }, -// SignatureSlot: slotCapella, -// } -// -// updates[0] = update -// -// err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ -// Version: version.Capella, -// Data: update, -// }) -// require.NoError(t, err) -// -// updatePeriod = slotDeneb.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) -// -// update = ðpbv2.LightClientUpdate{ -// AttestedHeader: ðpbv2.LightClientHeaderContainer{ -// Header: ðpbv2.LightClientHeaderContainer_HeaderDeneb{ -// HeaderDeneb: ðpbv2.LightClientHeaderDeneb{ -// Beacon: ðpbv1.BeaconBlockHeader{ -// Slot: slotDeneb, -// ProposerIndex: 1, -// ParentRoot: []byte{1, 1, 1}, -// StateRoot: []byte{1, 1, 1}, -// BodyRoot: []byte{1, 1, 1}, -// }, -// Execution: &enginev1.ExecutionPayloadHeaderDeneb{ -// FeeRecipient: []byte{1, 2, 3}, -// }, -// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, -// }, -// }, -// }, -// NextSyncCommittee: ðpbv2.SyncCommittee{ -// Pubkeys: nil, -// AggregatePubkey: nil, -// }, -// NextSyncCommitteeBranch: nil, -// FinalizedHeader: ðpbv2.LightClientHeaderContainer{ -// Header: ðpbv2.LightClientHeaderContainer_HeaderDeneb{ -// HeaderDeneb: ðpbv2.LightClientHeaderDeneb{ -// Beacon: ðpbv1.BeaconBlockHeader{ -// Slot: 12, -// ProposerIndex: 1, -// ParentRoot: []byte{1, 1, 1}, -// StateRoot: []byte{1, 1, 1}, -// BodyRoot: []byte{1, 1, 1}, -// }, -// Execution: &enginev1.ExecutionPayloadHeaderDeneb{ -// FeeRecipient: []byte{1, 2, 3}, -// }, -// ExecutionBranch: [][]byte{{1, 2, 3}, {4, 5, 6}}, -// }, -// }, -// }, -// FinalityBranch: nil, -// SyncAggregate: ðpbv1.SyncAggregate{ -// SyncCommitteeBits: []byte{1, 1, 1}, -// SyncCommitteeSignature: []byte{1, 1, 1}, -// }, -// SignatureSlot: slotDeneb, -// } -// -// updates[1] = update -// -// err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ -// Version: version.Deneb, -// Data: update, -// }) -// require.NoError(t, err) -// -// mockChainService := &mock.ChainService{State: st} -// s := &Server{ -// HeadFetcher: mockChainService, -// BeaconDB: db, -// } -// startPeriod := 1 -// url := fmt.Sprintf("http://foo.com/?count=100&start_period=%d", startPeriod) -// request := httptest.NewRequest("GET", url, nil) -// writer := httptest.NewRecorder() -// writer.Body = &bytes.Buffer{} -// -// s.GetLightClientUpdatesByRange(writer, request) -// -// require.Equal(t, http.StatusOK, writer.Code) -// var resp structs.LightClientUpdatesByRangeResponse -// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) -// require.NoError(t, err) -// require.Equal(t, 2, len(resp.Updates)) -// for i, update := range updates { -// if i < 1 { -// require.Equal(t, "capella", resp.Updates[i].Version) -// } else { -// require.Equal(t, "deneb", resp.Updates[i].Version) -// } -// updateJson, err := structs.LightClientUpdateFromConsensus(update) -// require.NoError(t, err) -// require.DeepEqual(t, updateJson, resp.Updates[i].Data) -// } -// } -// -// func TestLightClientHandler_GetLightClientUpdatesByRangeCountBiggerThanLimit(t *testing.T) { -// helpers.ClearCache() -// ctx := context.Background() -// params.SetupTestConfigCleanup(t) -// config := params.BeaconConfig() -// config.AltairForkEpoch = 0 -// config.EpochsPerSyncCommitteePeriod = 1 -// config.MaxRequestLightClientUpdates = 2 -// params.OverrideBeaconConfig(config) -// slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) -// -// st, err := util.NewBeaconStateAltair() -// require.NoError(t, err) -// headSlot := slot.Add(65) -// err = st.SetSlot(headSlot) -// require.NoError(t, err) -// -// db := setupDB(t) -// -// updates := make([]*ethpbv2.LightClientUpdate, 3) -// -// updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) -// -// for i := 0; i < 3; i++ { -// newSlot := slot.Add(uint64(i * 32)) -// -// update := ðpbv2.LightClientUpdate{ -// AttestedHeader: ðpbv2.LightClientHeaderContainer{ -// Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ -// HeaderAltair: ðpbv2.LightClientHeader{ -// Beacon: ðpbv1.BeaconBlockHeader{ -// Slot: newSlot, -// ProposerIndex: 1, -// ParentRoot: []byte{1, 1, 1}, -// StateRoot: []byte{1, 1, 1}, -// BodyRoot: []byte{1, 1, 1}, -// }, -// }, -// }, -// }, -// NextSyncCommittee: ðpbv2.SyncCommittee{ -// Pubkeys: nil, -// AggregatePubkey: nil, -// }, -// NextSyncCommitteeBranch: nil, -// FinalizedHeader: nil, -// FinalityBranch: nil, -// SyncAggregate: ðpbv1.SyncAggregate{ -// SyncCommitteeBits: []byte{1, 1, 1}, -// SyncCommitteeSignature: []byte{1, 1, 1}, -// }, -// SignatureSlot: 7, -// } -// -// updates[i] = update -// -// err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ -// Version: version.Altair, -// Data: update, -// }) -// require.NoError(t, err) -// -// updatePeriod++ -// } -// -// mockChainService := &mock.ChainService{State: st} -// s := &Server{ -// HeadFetcher: mockChainService, -// BeaconDB: db, -// } -// startPeriod := 0 -// url := fmt.Sprintf("http://foo.com/?count=4&start_period=%d", startPeriod) -// request := httptest.NewRequest("GET", url, nil) -// writer := httptest.NewRecorder() -// writer.Body = &bytes.Buffer{} -// -// s.GetLightClientUpdatesByRange(writer, request) -// -// require.Equal(t, http.StatusOK, writer.Code) -// var resp structs.LightClientUpdatesByRangeResponse -// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) -// require.NoError(t, err) -// require.Equal(t, 2, len(resp.Updates)) -// for i, update := range updates { -// if i < 2 { -// require.Equal(t, "altair", resp.Updates[i].Version) -// updateJson, err := structs.LightClientUpdateFromConsensus(update) -// require.NoError(t, err) -// require.DeepEqual(t, updateJson, resp.Updates[i].Data) -// } -// } -// } -// -// func TestLightClientHandler_GetLightClientUpdatesByRangeCountBiggerThanMax(t *testing.T) { -// helpers.ClearCache() -// ctx := context.Background() -// params.SetupTestConfigCleanup(t) -// config := params.BeaconConfig() -// config.AltairForkEpoch = 0 -// config.EpochsPerSyncCommitteePeriod = 1 -// config.MaxRequestLightClientUpdates = 2 -// params.OverrideBeaconConfig(config) -// slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) -// -// st, err := util.NewBeaconStateAltair() -// require.NoError(t, err) -// headSlot := slot.Add(65) -// err = st.SetSlot(headSlot) -// require.NoError(t, err) -// -// db := setupDB(t) -// -// updates := make([]*ethpbv2.LightClientUpdate, 3) -// -// updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) -// -// for i := 0; i < 3; i++ { -// newSlot := slot.Add(uint64(i * 32)) -// -// update := ðpbv2.LightClientUpdate{ -// AttestedHeader: ðpbv2.LightClientHeaderContainer{ -// Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ -// HeaderAltair: ðpbv2.LightClientHeader{ -// Beacon: ðpbv1.BeaconBlockHeader{ -// Slot: newSlot, -// ProposerIndex: 1, -// ParentRoot: []byte{1, 1, 1}, -// StateRoot: []byte{1, 1, 1}, -// BodyRoot: []byte{1, 1, 1}, -// }, -// }, -// }, -// }, -// NextSyncCommittee: ðpbv2.SyncCommittee{ -// Pubkeys: nil, -// AggregatePubkey: nil, -// }, -// NextSyncCommitteeBranch: nil, -// FinalizedHeader: nil, -// FinalityBranch: nil, -// SyncAggregate: ðpbv1.SyncAggregate{ -// SyncCommitteeBits: []byte{1, 1, 1}, -// SyncCommitteeSignature: []byte{1, 1, 1}, -// }, -// SignatureSlot: 7, -// } -// -// updates[i] = update -// err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ -// Version: version.Altair, -// Data: update, -// }) -// require.NoError(t, err) -// -// updatePeriod++ -// } -// -// mockChainService := &mock.ChainService{State: st} -// s := &Server{ -// HeadFetcher: mockChainService, -// BeaconDB: db, -// } -// startPeriod := 0 -// url := fmt.Sprintf("http://foo.com/?count=10&start_period=%d", startPeriod) -// request := httptest.NewRequest("GET", url, nil) -// writer := httptest.NewRecorder() -// writer.Body = &bytes.Buffer{} -// -// s.GetLightClientUpdatesByRange(writer, request) -// -// require.Equal(t, http.StatusOK, writer.Code) -// var resp structs.LightClientUpdatesByRangeResponse -// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) -// require.NoError(t, err) -// require.Equal(t, 2, len(resp.Updates)) -// for i, update := range updates { -// if i < 2 { -// require.Equal(t, "altair", resp.Updates[i].Version) -// updateJson, err := structs.LightClientUpdateFromConsensus(update) -// require.NoError(t, err) -// require.DeepEqual(t, updateJson, resp.Updates[i].Data) -// } -// } -// } -// -// func TestLightClientHandler_GetLightClientUpdatesByRangeStartPeriodBeforeAltair(t *testing.T) { -// helpers.ClearCache() -// ctx := context.Background() -// params.SetupTestConfigCleanup(t) -// config := params.BeaconConfig() -// config.AltairForkEpoch = 1 -// config.EpochsPerSyncCommitteePeriod = 1 -// params.OverrideBeaconConfig(config) -// slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) -// -// st, err := util.NewBeaconStateAltair() -// require.NoError(t, err) -// headSlot := slot.Add(1) -// err = st.SetSlot(headSlot) -// require.NoError(t, err) -// -// db := setupDB(t) -// -// updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) -// -// update := ðpbv2.LightClientUpdate{ -// AttestedHeader: ðpbv2.LightClientHeaderContainer{ -// Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ -// HeaderAltair: ðpbv2.LightClientHeader{ -// Beacon: ðpbv1.BeaconBlockHeader{ -// Slot: slot, -// ProposerIndex: 1, -// ParentRoot: []byte{1, 1, 1}, -// StateRoot: []byte{1, 1, 1}, -// BodyRoot: []byte{1, 1, 1}, -// }, -// }, -// }, -// }, -// NextSyncCommittee: ðpbv2.SyncCommittee{ -// Pubkeys: nil, -// AggregatePubkey: nil, -// }, -// NextSyncCommitteeBranch: nil, -// FinalizedHeader: nil, -// FinalityBranch: nil, -// SyncAggregate: ðpbv1.SyncAggregate{ -// SyncCommitteeBits: []byte{1, 1, 1}, -// SyncCommitteeSignature: []byte{1, 1, 1}, -// }, -// SignatureSlot: 7, -// } -// -// err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ -// Version: version.Altair, -// Data: update, -// }) -// require.NoError(t, err) -// -// mockChainService := &mock.ChainService{State: st} -// s := &Server{ -// HeadFetcher: mockChainService, -// BeaconDB: db, -// } -// startPeriod := 0 -// url := fmt.Sprintf("http://foo.com/?count=2&start_period=%d", startPeriod) -// request := httptest.NewRequest("GET", url, nil) -// writer := httptest.NewRecorder() -// writer.Body = &bytes.Buffer{} -// -// s.GetLightClientUpdatesByRange(writer, request) -// -// require.Equal(t, http.StatusOK, writer.Code) -// var resp structs.LightClientUpdatesByRangeResponse -// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) -// require.NoError(t, err) -// require.Equal(t, 1, len(resp.Updates)) -// -// require.Equal(t, "altair", resp.Updates[0].Version) -// updateJson, err := structs.LightClientUpdateFromConsensus(update) -// require.NoError(t, err) -// require.DeepEqual(t, updateJson, resp.Updates[0].Data) -// -// } -// -// func TestLightClientHandler_GetLightClientUpdatesByRangeMissingUpdates(t *testing.T) { -// helpers.ClearCache() -// ctx := context.Background() -// params.SetupTestConfigCleanup(t) -// config := params.BeaconConfig() -// config.AltairForkEpoch = 0 -// config.EpochsPerSyncCommitteePeriod = 1 -// params.OverrideBeaconConfig(config) -// slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) -// -// st, err := util.NewBeaconStateAltair() -// require.NoError(t, err) -// headSlot := slot.Add(65) -// err = st.SetSlot(headSlot) -// require.NoError(t, err) -// -// t.Run("missing update in the middle", func(t *testing.T) { -// db := setupDB(t) -// -// updates := make([]*ethpbv2.LightClientUpdate, 3) -// -// updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) -// -// for i := 0; i < 3; i++ { -// if i == 1 { // skip this update -// updatePeriod++ -// continue -// } -// newSlot := slot.Add(uint64(i * 32)) -// -// update := ðpbv2.LightClientUpdate{ -// AttestedHeader: ðpbv2.LightClientHeaderContainer{ -// Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ -// HeaderAltair: ðpbv2.LightClientHeader{ -// Beacon: ðpbv1.BeaconBlockHeader{ -// Slot: newSlot, -// ProposerIndex: 1, -// ParentRoot: []byte{1, 1, 1}, -// StateRoot: []byte{1, 1, 1}, -// BodyRoot: []byte{1, 1, 1}, -// }, -// }, -// }, -// }, -// NextSyncCommittee: ðpbv2.SyncCommittee{ -// Pubkeys: nil, -// AggregatePubkey: nil, -// }, -// NextSyncCommitteeBranch: nil, -// FinalizedHeader: nil, -// FinalityBranch: nil, -// SyncAggregate: ðpbv1.SyncAggregate{ -// SyncCommitteeBits: []byte{1, 1, 1}, -// SyncCommitteeSignature: []byte{1, 1, 1}, -// }, -// SignatureSlot: 7, -// } -// -// updates[i] = update -// -// err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ -// Version: version.Altair, -// Data: update, -// }) -// require.NoError(t, err) -// -// updatePeriod++ -// } -// -// mockChainService := &mock.ChainService{State: st} -// s := &Server{ -// HeadFetcher: mockChainService, -// BeaconDB: db, -// } -// startPeriod := 0 -// url := fmt.Sprintf("http://foo.com/?count=10&start_period=%d", startPeriod) -// request := httptest.NewRequest("GET", url, nil) -// writer := httptest.NewRecorder() -// writer.Body = &bytes.Buffer{} -// -// s.GetLightClientUpdatesByRange(writer, request) -// -// require.Equal(t, http.StatusOK, writer.Code) -// var resp structs.LightClientUpdatesByRangeResponse -// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) -// require.NoError(t, err) -// require.Equal(t, 1, len(resp.Updates)) -// require.Equal(t, "altair", resp.Updates[0].Version) -// updateJson, err := structs.LightClientUpdateFromConsensus(updates[0]) -// require.NoError(t, err) -// require.DeepEqual(t, updateJson, resp.Updates[0].Data) -// }) -// -// t.Run("missing update at the beginning", func(t *testing.T) { -// db := setupDB(t) -// -// updates := make([]*ethpbv2.LightClientUpdate, 3) -// -// updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) -// -// for i := 0; i < 3; i++ { -// if i == 0 { // skip this update -// updatePeriod++ -// continue -// } -// newSlot := slot.Add(uint64(i)) -// -// update := ðpbv2.LightClientUpdate{ -// AttestedHeader: ðpbv2.LightClientHeaderContainer{ -// Header: ðpbv2.LightClientHeaderContainer_HeaderAltair{ -// HeaderAltair: ðpbv2.LightClientHeader{ -// Beacon: ðpbv1.BeaconBlockHeader{ -// Slot: newSlot, -// ProposerIndex: 1, -// ParentRoot: []byte{1, 1, 1}, -// StateRoot: []byte{1, 1, 1}, -// BodyRoot: []byte{1, 1, 1}, -// }, -// }, -// }, -// }, -// NextSyncCommittee: ðpbv2.SyncCommittee{ -// Pubkeys: nil, -// AggregatePubkey: nil, -// }, -// NextSyncCommitteeBranch: nil, -// FinalizedHeader: nil, -// FinalityBranch: nil, -// SyncAggregate: ðpbv1.SyncAggregate{ -// SyncCommitteeBits: []byte{1, 1, 1}, -// SyncCommitteeSignature: []byte{1, 1, 1}, -// }, -// SignatureSlot: 7, -// } -// -// updates[i] = update -// -// err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), ðpbv2.LightClientUpdateWithVersion{ -// Version: version.Altair, -// Data: update, -// }) -// require.NoError(t, err) -// -// updatePeriod++ -// } -// -// mockChainService := &mock.ChainService{State: st} -// s := &Server{ -// HeadFetcher: mockChainService, -// BeaconDB: db, -// } -// startPeriod := 0 -// url := fmt.Sprintf("http://foo.com/?count=10&start_period=%d", startPeriod) -// request := httptest.NewRequest("GET", url, nil) -// writer := httptest.NewRecorder() -// writer.Body = &bytes.Buffer{} -// -// s.GetLightClientUpdatesByRange(writer, request) -// -// require.Equal(t, http.StatusOK, writer.Code) -// var resp structs.LightClientUpdatesByRangeResponse -// err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) -// require.NoError(t, err) -// require.Equal(t, 0, len(resp.Updates)) -// }) -// -// } -// -// // TestLightClientHandler_GetLightClientFinalityUpdate tests -// -// func TestLightClientHandler_GetLightClientFinalityUpdateAltair(t *testing.T) { -// helpers.ClearCache() -// ctx := context.Background() -// params.SetupTestConfigCleanup(t) -// config := params.BeaconConfig() -// slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) -// -// attestedState, err := util.NewBeaconStateAltair() -// require.NoError(t, err) -// err = attestedState.SetSlot(slot.Sub(1)) -// require.NoError(t, err) -// -// require.NoError(t, attestedState.SetFinalizedCheckpoint(ðpb.Checkpoint{ -// Epoch: config.AltairForkEpoch - 10, -// Root: make([]byte, 32), -// })) -// -// parent := util.NewBeaconBlockAltair() -// parent.Block.Slot = slot.Sub(1) -// -// signedParent, err := blocks.NewSignedBeaconBlock(parent) -// require.NoError(t, err) -// -// parentHeader, err := signedParent.Header() -// require.NoError(t, err) -// attestedHeader := parentHeader.Header -// -// err = attestedState.SetLatestBlockHeader(attestedHeader) -// require.NoError(t, err) -// attestedStateRoot, err := attestedState.HashTreeRoot(ctx) -// require.NoError(t, err) -// -// // get a new signed block so the root is updated with the new state root -// parent.Block.StateRoot = attestedStateRoot[:] -// signedParent, err = blocks.NewSignedBeaconBlock(parent) -// require.NoError(t, err) -// -// st, err := util.NewBeaconStateAltair() -// require.NoError(t, err) -// err = st.SetSlot(slot) -// require.NoError(t, err) -// -// parentRoot, err := signedParent.Block().HashTreeRoot() -// require.NoError(t, err) -// -// block := util.NewBeaconBlockAltair() -// block.Block.Slot = slot -// block.Block.ParentRoot = parentRoot[:] -// -// for i := uint64(0); i < config.SyncCommitteeSize; i++ { -// block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) -// } -// -// signedBlock, err := blocks.NewSignedBeaconBlock(block) -// require.NoError(t, err) -// -// h, err := signedBlock.Header() -// require.NoError(t, err) -// -// err = st.SetLatestBlockHeader(h.Header) -// require.NoError(t, err) -// stateRoot, err := st.HashTreeRoot(ctx) -// require.NoError(t, err) -// -// // get a new signed block so the root is updated with the new state root -// block.Block.StateRoot = stateRoot[:] -// signedBlock, err = blocks.NewSignedBeaconBlock(block) -// require.NoError(t, err) -// -// root, err := block.Block.HashTreeRoot() -// require.NoError(t, err) -// -// mockBlocker := &testutil.MockBlocker{ -// RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ -// parentRoot: signedParent, -// root: signedBlock, -// }, -// SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ -// slot.Sub(1): signedParent, -// slot: signedBlock, -// }, -// } -// mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st, FinalizedRoots: map[[32]byte]bool{ -// root: true, -// }} -// s := &Server{ -// Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ -// slot.Sub(1): attestedState, -// slot: st, -// }}, -// Blocker: mockBlocker, -// HeadFetcher: mockChainService, -// } -// request := httptest.NewRequest("GET", "http://foo.com", nil) -// writer := httptest.NewRecorder() -// writer.Body = &bytes.Buffer{} -// -// s.GetLightClientFinalityUpdate(writer, request) -// -// require.Equal(t, http.StatusOK, writer.Code) -// var resp *structs.LightClientUpdateResponse -// err = json.Unmarshal(writer.Body.Bytes(), &resp) -// require.NoError(t, err) -// var respHeader structs.LightClientHeader -// err = json.Unmarshal(resp.Data.AttestedHeader, &respHeader) -// require.NoError(t, err) -// require.Equal(t, "altair", resp.Version) -// require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot) -// require.NotNil(t, resp.Data) -// } -// -// func TestLightClientHandler_GetLightClientFinalityUpdateCapella(t *testing.T) { -// helpers.ClearCache() -// ctx := context.Background() -// params.SetupTestConfigCleanup(t) -// config := params.BeaconConfig() -// slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) -// -// attestedState, err := util.NewBeaconStateCapella() -// require.NoError(t, err) -// err = attestedState.SetSlot(slot.Sub(1)) -// require.NoError(t, err) -// -// require.NoError(t, attestedState.SetFinalizedCheckpoint(ðpb.Checkpoint{ -// Epoch: config.AltairForkEpoch - 10, -// Root: make([]byte, 32), -// })) -// -// parent := util.NewBeaconBlockCapella() -// parent.Block.Slot = slot.Sub(1) -// -// signedParent, err := blocks.NewSignedBeaconBlock(parent) -// require.NoError(t, err) -// -// parentHeader, err := signedParent.Header() -// require.NoError(t, err) -// attestedHeader := parentHeader.Header -// -// err = attestedState.SetLatestBlockHeader(attestedHeader) -// require.NoError(t, err) -// attestedStateRoot, err := attestedState.HashTreeRoot(ctx) -// require.NoError(t, err) -// -// // get a new signed block so the root is updated with the new state root -// parent.Block.StateRoot = attestedStateRoot[:] -// signedParent, err = blocks.NewSignedBeaconBlock(parent) -// require.NoError(t, err) -// -// st, err := util.NewBeaconStateCapella() -// require.NoError(t, err) -// err = st.SetSlot(slot) -// require.NoError(t, err) -// -// parentRoot, err := signedParent.Block().HashTreeRoot() -// require.NoError(t, err) -// -// block := util.NewBeaconBlockCapella() -// block.Block.Slot = slot -// block.Block.ParentRoot = parentRoot[:] -// -// for i := uint64(0); i < config.SyncCommitteeSize; i++ { -// block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) -// } -// -// signedBlock, err := blocks.NewSignedBeaconBlock(block) -// require.NoError(t, err) -// -// h, err := signedBlock.Header() -// require.NoError(t, err) -// -// err = st.SetLatestBlockHeader(h.Header) -// require.NoError(t, err) -// stateRoot, err := st.HashTreeRoot(ctx) -// require.NoError(t, err) -// -// // get a new signed block so the root is updated with the new state root -// block.Block.StateRoot = stateRoot[:] -// signedBlock, err = blocks.NewSignedBeaconBlock(block) -// require.NoError(t, err) -// -// root, err := block.Block.HashTreeRoot() -// require.NoError(t, err) -// -// mockBlocker := &testutil.MockBlocker{ -// RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ -// parentRoot: signedParent, -// root: signedBlock, -// }, -// SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ -// slot.Sub(1): signedParent, -// slot: signedBlock, -// }, -// } -// mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st, FinalizedRoots: map[[32]byte]bool{ -// root: true, -// }} -// s := &Server{ -// Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ -// slot.Sub(1): attestedState, -// slot: st, -// }}, -// Blocker: mockBlocker, -// HeadFetcher: mockChainService, -// } -// request := httptest.NewRequest("GET", "http://foo.com", nil) -// writer := httptest.NewRecorder() -// writer.Body = &bytes.Buffer{} -// -// s.GetLightClientFinalityUpdate(writer, request) -// -// require.Equal(t, http.StatusOK, writer.Code) -// var resp *structs.LightClientUpdateResponse -// err = json.Unmarshal(writer.Body.Bytes(), &resp) -// require.NoError(t, err) -// var respHeader structs.LightClientHeader -// err = json.Unmarshal(resp.Data.AttestedHeader, &respHeader) -// require.NoError(t, err) -// require.Equal(t, "capella", resp.Version) -// require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot) -// require.NotNil(t, resp.Data) -// } -// -// func TestLightClientHandler_GetLightClientFinalityUpdateDeneb(t *testing.T) { -// helpers.ClearCache() -// ctx := context.Background() -// params.SetupTestConfigCleanup(t) -// config := params.BeaconConfig() -// slot := primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) -// -// attestedState, err := util.NewBeaconStateDeneb() -// require.NoError(t, err) -// err = attestedState.SetSlot(slot.Sub(1)) -// require.NoError(t, err) -// -// require.NoError(t, attestedState.SetFinalizedCheckpoint(ðpb.Checkpoint{ -// Epoch: config.AltairForkEpoch - 10, -// Root: make([]byte, 32), -// })) -// -// parent := util.NewBeaconBlockDeneb() -// parent.Block.Slot = slot.Sub(1) -// -// signedParent, err := blocks.NewSignedBeaconBlock(parent) -// require.NoError(t, err) -// -// parentHeader, err := signedParent.Header() -// require.NoError(t, err) -// attestedHeader := parentHeader.Header -// -// err = attestedState.SetLatestBlockHeader(attestedHeader) -// require.NoError(t, err) -// attestedStateRoot, err := attestedState.HashTreeRoot(ctx) -// require.NoError(t, err) -// -// // get a new signed block so the root is updated with the new state root -// parent.Block.StateRoot = attestedStateRoot[:] -// signedParent, err = blocks.NewSignedBeaconBlock(parent) -// require.NoError(t, err) -// -// st, err := util.NewBeaconStateDeneb() -// require.NoError(t, err) -// err = st.SetSlot(slot) -// require.NoError(t, err) -// -// parentRoot, err := signedParent.Block().HashTreeRoot() -// require.NoError(t, err) -// -// block := util.NewBeaconBlockDeneb() -// block.Block.Slot = slot -// block.Block.ParentRoot = parentRoot[:] -// -// for i := uint64(0); i < config.SyncCommitteeSize; i++ { -// block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) -// } -// -// signedBlock, err := blocks.NewSignedBeaconBlock(block) -// require.NoError(t, err) -// -// h, err := signedBlock.Header() -// require.NoError(t, err) -// -// err = st.SetLatestBlockHeader(h.Header) -// require.NoError(t, err) -// stateRoot, err := st.HashTreeRoot(ctx) -// require.NoError(t, err) -// -// // get a new signed block so the root is updated with the new state root -// block.Block.StateRoot = stateRoot[:] -// signedBlock, err = blocks.NewSignedBeaconBlock(block) -// require.NoError(t, err) -// -// root, err := block.Block.HashTreeRoot() -// require.NoError(t, err) -// -// mockBlocker := &testutil.MockBlocker{ -// RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ -// parentRoot: signedParent, -// root: signedBlock, -// }, -// SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ -// slot.Sub(1): signedParent, -// slot: signedBlock, -// }, -// } -// mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st, FinalizedRoots: map[[32]byte]bool{ -// root: true, -// }} -// s := &Server{ -// Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ -// slot.Sub(1): attestedState, -// slot: st, -// }}, -// Blocker: mockBlocker, -// HeadFetcher: mockChainService, -// } -// request := httptest.NewRequest("GET", "http://foo.com", nil) -// writer := httptest.NewRecorder() -// writer.Body = &bytes.Buffer{} -// -// s.GetLightClientFinalityUpdate(writer, request) -// -// require.Equal(t, http.StatusOK, writer.Code) -// var resp *structs.LightClientUpdateResponse -// err = json.Unmarshal(writer.Body.Bytes(), &resp) -// require.NoError(t, err) -// var respHeader structs.LightClientHeaderDeneb -// err = json.Unmarshal(resp.Data.AttestedHeader, &respHeader) -// require.NoError(t, err) -// require.Equal(t, "deneb", resp.Version) -// require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot) -// require.NotNil(t, resp.Data) -// } -// -// func TestLightClientHandler_GetLightClientOptimisticUpdateAltair(t *testing.T) { -// helpers.ClearCache() -// ctx := context.Background() -// params.SetupTestConfigCleanup(t) -// config := params.BeaconConfig() -// slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) -// -// attestedState, err := util.NewBeaconStateAltair() -// require.NoError(t, err) -// err = attestedState.SetSlot(slot.Sub(1)) -// require.NoError(t, err) -// -// require.NoError(t, attestedState.SetFinalizedCheckpoint(ðpb.Checkpoint{ -// Epoch: config.AltairForkEpoch - 10, -// Root: make([]byte, 32), -// })) -// -// parent := util.NewBeaconBlockAltair() -// parent.Block.Slot = slot.Sub(1) -// -// signedParent, err := blocks.NewSignedBeaconBlock(parent) -// require.NoError(t, err) -// -// parentHeader, err := signedParent.Header() -// require.NoError(t, err) -// attestedHeader := parentHeader.Header -// -// err = attestedState.SetLatestBlockHeader(attestedHeader) -// require.NoError(t, err) -// attestedStateRoot, err := attestedState.HashTreeRoot(ctx) -// require.NoError(t, err) -// -// // get a new signed block so the root is updated with the new state root -// parent.Block.StateRoot = attestedStateRoot[:] -// signedParent, err = blocks.NewSignedBeaconBlock(parent) -// require.NoError(t, err) -// -// st, err := util.NewBeaconStateAltair() -// require.NoError(t, err) -// err = st.SetSlot(slot) -// require.NoError(t, err) -// -// parentRoot, err := signedParent.Block().HashTreeRoot() -// require.NoError(t, err) -// -// block := util.NewBeaconBlockAltair() -// block.Block.Slot = slot -// block.Block.ParentRoot = parentRoot[:] -// -// for i := uint64(0); i < config.SyncCommitteeSize; i++ { -// block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) -// } -// -// signedBlock, err := blocks.NewSignedBeaconBlock(block) -// require.NoError(t, err) -// -// h, err := signedBlock.Header() -// require.NoError(t, err) -// -// err = st.SetLatestBlockHeader(h.Header) -// require.NoError(t, err) -// stateRoot, err := st.HashTreeRoot(ctx) -// require.NoError(t, err) -// -// // get a new signed block so the root is updated with the new state root -// block.Block.StateRoot = stateRoot[:] -// signedBlock, err = blocks.NewSignedBeaconBlock(block) -// require.NoError(t, err) -// -// root, err := block.Block.HashTreeRoot() -// require.NoError(t, err) -// -// mockBlocker := &testutil.MockBlocker{ -// RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ -// parentRoot: signedParent, -// root: signedBlock, -// }, -// SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ -// slot.Sub(1): signedParent, -// slot: signedBlock, -// }, -// } -// mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st, FinalizedRoots: map[[32]byte]bool{ -// root: true, -// }} -// s := &Server{ -// Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ -// slot.Sub(1): attestedState, -// slot: st, -// }}, -// Blocker: mockBlocker, -// HeadFetcher: mockChainService, -// } -// request := httptest.NewRequest("GET", "http://foo.com", nil) -// writer := httptest.NewRecorder() -// writer.Body = &bytes.Buffer{} -// -// s.GetLightClientOptimisticUpdate(writer, request) -// -// require.Equal(t, http.StatusOK, writer.Code) -// var resp *structs.LightClientUpdateResponse -// err = json.Unmarshal(writer.Body.Bytes(), &resp) -// require.NoError(t, err) -// var respHeader structs.LightClientHeader -// err = json.Unmarshal(resp.Data.AttestedHeader, &respHeader) -// require.NoError(t, err) -// require.Equal(t, "altair", resp.Version) -// require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot) -// require.NotNil(t, resp.Data) -// } -// -// func TestLightClientHandler_GetLightClientOptimisticUpdateCapella(t *testing.T) { -// helpers.ClearCache() -// ctx := context.Background() -// params.SetupTestConfigCleanup(t) -// config := params.BeaconConfig() -// slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) -// -// attestedState, err := util.NewBeaconStateCapella() -// require.NoError(t, err) -// err = attestedState.SetSlot(slot.Sub(1)) -// require.NoError(t, err) -// -// require.NoError(t, attestedState.SetFinalizedCheckpoint(ðpb.Checkpoint{ -// Epoch: config.AltairForkEpoch - 10, -// Root: make([]byte, 32), -// })) -// -// parent := util.NewBeaconBlockCapella() -// parent.Block.Slot = slot.Sub(1) -// -// signedParent, err := blocks.NewSignedBeaconBlock(parent) -// require.NoError(t, err) -// -// parentHeader, err := signedParent.Header() -// require.NoError(t, err) -// attestedHeader := parentHeader.Header -// -// err = attestedState.SetLatestBlockHeader(attestedHeader) -// require.NoError(t, err) -// attestedStateRoot, err := attestedState.HashTreeRoot(ctx) -// require.NoError(t, err) -// -// // get a new signed block so the root is updated with the new state root -// parent.Block.StateRoot = attestedStateRoot[:] -// signedParent, err = blocks.NewSignedBeaconBlock(parent) -// require.NoError(t, err) -// -// st, err := util.NewBeaconStateCapella() -// require.NoError(t, err) -// err = st.SetSlot(slot) -// require.NoError(t, err) -// -// parentRoot, err := signedParent.Block().HashTreeRoot() -// require.NoError(t, err) -// -// block := util.NewBeaconBlockCapella() -// block.Block.Slot = slot -// block.Block.ParentRoot = parentRoot[:] -// -// for i := uint64(0); i < config.SyncCommitteeSize; i++ { -// block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) -// } -// -// signedBlock, err := blocks.NewSignedBeaconBlock(block) -// require.NoError(t, err) -// -// h, err := signedBlock.Header() -// require.NoError(t, err) -// -// err = st.SetLatestBlockHeader(h.Header) -// require.NoError(t, err) -// stateRoot, err := st.HashTreeRoot(ctx) -// require.NoError(t, err) -// -// // get a new signed block so the root is updated with the new state root -// block.Block.StateRoot = stateRoot[:] -// signedBlock, err = blocks.NewSignedBeaconBlock(block) -// require.NoError(t, err) -// -// root, err := block.Block.HashTreeRoot() -// require.NoError(t, err) -// -// mockBlocker := &testutil.MockBlocker{ -// RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ -// parentRoot: signedParent, -// root: signedBlock, -// }, -// SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ -// slot.Sub(1): signedParent, -// slot: signedBlock, -// }, -// } -// mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st, FinalizedRoots: map[[32]byte]bool{ -// root: true, -// }} -// s := &Server{ -// Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ -// slot.Sub(1): attestedState, -// slot: st, -// }}, -// Blocker: mockBlocker, -// HeadFetcher: mockChainService, -// } -// request := httptest.NewRequest("GET", "http://foo.com", nil) -// writer := httptest.NewRecorder() -// writer.Body = &bytes.Buffer{} -// -// s.GetLightClientOptimisticUpdate(writer, request) -// -// require.Equal(t, http.StatusOK, writer.Code) -// var resp *structs.LightClientUpdateResponse -// err = json.Unmarshal(writer.Body.Bytes(), &resp) -// require.NoError(t, err) -// var respHeader structs.LightClientHeaderCapella -// err = json.Unmarshal(resp.Data.AttestedHeader, &respHeader) -// require.NoError(t, err) -// require.Equal(t, "capella", resp.Version) -// require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot) -// require.NotNil(t, resp.Data) -// } -// -// func TestLightClientHandler_GetLightClientOptimisticUpdateDeneb(t *testing.T) { -// helpers.ClearCache() -// ctx := context.Background() -// params.SetupTestConfigCleanup(t) -// config := params.BeaconConfig() -// slot := primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) -// -// attestedState, err := util.NewBeaconStateDeneb() -// require.NoError(t, err) -// err = attestedState.SetSlot(slot.Sub(1)) -// require.NoError(t, err) -// -// require.NoError(t, attestedState.SetFinalizedCheckpoint(ðpb.Checkpoint{ -// Epoch: config.AltairForkEpoch - 10, -// Root: make([]byte, 32), -// })) -// -// parent := util.NewBeaconBlockDeneb() -// parent.Block.Slot = slot.Sub(1) -// -// signedParent, err := blocks.NewSignedBeaconBlock(parent) -// require.NoError(t, err) -// -// parentHeader, err := signedParent.Header() -// require.NoError(t, err) -// attestedHeader := parentHeader.Header -// -// err = attestedState.SetLatestBlockHeader(attestedHeader) -// require.NoError(t, err) -// attestedStateRoot, err := attestedState.HashTreeRoot(ctx) -// require.NoError(t, err) -// -// // get a new signed block so the root is updated with the new state root -// parent.Block.StateRoot = attestedStateRoot[:] -// signedParent, err = blocks.NewSignedBeaconBlock(parent) -// require.NoError(t, err) -// -// st, err := util.NewBeaconStateDeneb() -// require.NoError(t, err) -// err = st.SetSlot(slot) -// require.NoError(t, err) -// -// parentRoot, err := signedParent.Block().HashTreeRoot() -// require.NoError(t, err) -// -// block := util.NewBeaconBlockDeneb() -// block.Block.Slot = slot -// block.Block.ParentRoot = parentRoot[:] -// -// for i := uint64(0); i < config.SyncCommitteeSize; i++ { -// block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) -// } -// -// signedBlock, err := blocks.NewSignedBeaconBlock(block) -// require.NoError(t, err) -// -// h, err := signedBlock.Header() -// require.NoError(t, err) -// -// err = st.SetLatestBlockHeader(h.Header) -// require.NoError(t, err) -// stateRoot, err := st.HashTreeRoot(ctx) -// require.NoError(t, err) -// -// // get a new signed block so the root is updated with the new state root -// block.Block.StateRoot = stateRoot[:] -// signedBlock, err = blocks.NewSignedBeaconBlock(block) -// require.NoError(t, err) -// -// root, err := block.Block.HashTreeRoot() -// require.NoError(t, err) -// -// mockBlocker := &testutil.MockBlocker{ -// RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ -// parentRoot: signedParent, -// root: signedBlock, -// }, -// SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ -// slot.Sub(1): signedParent, -// slot: signedBlock, -// }, -// } -// mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st, FinalizedRoots: map[[32]byte]bool{ -// root: true, -// }} -// s := &Server{ -// Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ -// slot.Sub(1): attestedState, -// slot: st, -// }}, -// Blocker: mockBlocker, -// HeadFetcher: mockChainService, -// } -// request := httptest.NewRequest("GET", "http://foo.com", nil) -// writer := httptest.NewRecorder() -// writer.Body = &bytes.Buffer{} -// -// s.GetLightClientOptimisticUpdate(writer, request) -// -// require.Equal(t, http.StatusOK, writer.Code) -// var resp *structs.LightClientUpdateResponse -// err = json.Unmarshal(writer.Body.Bytes(), &resp) -// require.NoError(t, err) -// var respHeader structs.LightClientHeaderDeneb -// err = json.Unmarshal(resp.Data.AttestedHeader, &respHeader) -// require.NoError(t, err) -// require.Equal(t, "deneb", resp.Version) -// require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot) -// require.NotNil(t, resp.Data) -// } -// -// func TestLightClientHandler_GetLightClientEventBlock(t *testing.T) { -// helpers.ClearCache() -// ctx := context.Background() -// params.SetupTestConfigCleanup(t) -// config := params.BeaconConfig() -// slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) -// -// attestedState, err := util.NewBeaconStateCapella() -// require.NoError(t, err) -// err = attestedState.SetSlot(slot.Sub(1)) -// require.NoError(t, err) -// -// require.NoError(t, attestedState.SetFinalizedCheckpoint(ðpb.Checkpoint{ -// Epoch: config.AltairForkEpoch - 10, -// Root: make([]byte, 32), -// })) -// -// parent := util.NewBeaconBlockCapella() -// parent.Block.Slot = slot.Sub(1) -// -// signedParent, err := blocks.NewSignedBeaconBlock(parent) -// require.NoError(t, err) -// -// parentHeader, err := signedParent.Header() -// require.NoError(t, err) -// attestedHeader := parentHeader.Header -// -// err = attestedState.SetLatestBlockHeader(attestedHeader) -// require.NoError(t, err) -// attestedStateRoot, err := attestedState.HashTreeRoot(ctx) -// require.NoError(t, err) -// -// // get a new signed block so the root is updated with the new state root -// parent.Block.StateRoot = attestedStateRoot[:] -// signedParent, err = blocks.NewSignedBeaconBlock(parent) -// require.NoError(t, err) -// -// st, err := util.NewBeaconStateCapella() -// require.NoError(t, err) -// err = st.SetSlot(slot) -// require.NoError(t, err) -// -// parentRoot, err := signedParent.Block().HashTreeRoot() -// require.NoError(t, err) -// -// block := util.NewBeaconBlockCapella() -// block.Block.Slot = slot -// block.Block.ParentRoot = parentRoot[:] -// -// for i := uint64(0); i < config.SyncCommitteeSize; i++ { -// block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) -// } -// -// signedBlock, err := blocks.NewSignedBeaconBlock(block) -// require.NoError(t, err) -// -// h, err := signedBlock.Header() -// require.NoError(t, err) -// -// err = st.SetLatestBlockHeader(h.Header) -// require.NoError(t, err) -// stateRoot, err := st.HashTreeRoot(ctx) -// require.NoError(t, err) -// -// // get a new signed block so the root is updated with the new state root -// block.Block.StateRoot = stateRoot[:] -// signedBlock, err = blocks.NewSignedBeaconBlock(block) -// require.NoError(t, err) -// -// root, err := block.Block.HashTreeRoot() -// require.NoError(t, err) -// -// mockBlocker := &testutil.MockBlocker{ -// RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ -// parentRoot: signedParent, -// root: signedBlock, -// }, -// SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ -// slot.Sub(1): signedParent, -// slot: signedBlock, -// }, -// } -// mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st, FinalizedRoots: map[[32]byte]bool{ -// root: true, -// }} -// s := &Server{ -// Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ -// slot.Sub(1): attestedState, -// slot: st, -// }}, -// Blocker: mockBlocker, -// HeadFetcher: mockChainService, -// } -// -// minSignaturesRequired := uint64(100) -// eventBlock, err := s.suitableBlock(ctx, minSignaturesRequired) -// -// require.NoError(t, err) -// require.NotNil(t, eventBlock) -// require.Equal(t, slot, eventBlock.Block().Slot()) -// syncAggregate, err := eventBlock.Block().Body().SyncAggregate() -// require.NoError(t, err) -// require.Equal(t, true, syncAggregate.SyncCommitteeBits.Count() >= minSignaturesRequired) -// } -// -// func TestLightClientHandler_GetLightClientEventBlock_NeedFetchParent(t *testing.T) { -// helpers.ClearCache() -// ctx := context.Background() -// params.SetupTestConfigCleanup(t) -// config := params.BeaconConfig() -// slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) -// -// attestedState, err := util.NewBeaconStateCapella() -// require.NoError(t, err) -// err = attestedState.SetSlot(slot.Sub(1)) -// require.NoError(t, err) -// -// require.NoError(t, attestedState.SetFinalizedCheckpoint(ðpb.Checkpoint{ -// Epoch: config.AltairForkEpoch - 10, -// Root: make([]byte, 32), -// })) -// -// parent := util.NewBeaconBlockCapella() -// parent.Block.Slot = slot.Sub(1) -// for i := uint64(0); i < config.SyncCommitteeSize; i++ { -// parent.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) -// } -// -// signedParent, err := blocks.NewSignedBeaconBlock(parent) -// require.NoError(t, err) -// -// parentHeader, err := signedParent.Header() -// require.NoError(t, err) -// attestedHeader := parentHeader.Header -// -// err = attestedState.SetLatestBlockHeader(attestedHeader) -// require.NoError(t, err) -// attestedStateRoot, err := attestedState.HashTreeRoot(ctx) -// require.NoError(t, err) -// -// // get a new signed block so the root is updated with the new state root -// parent.Block.StateRoot = attestedStateRoot[:] -// signedParent, err = blocks.NewSignedBeaconBlock(parent) -// require.NoError(t, err) -// -// st, err := util.NewBeaconStateCapella() -// require.NoError(t, err) -// err = st.SetSlot(slot) -// require.NoError(t, err) -// -// parentRoot, err := signedParent.Block().HashTreeRoot() -// require.NoError(t, err) -// -// block := util.NewBeaconBlockCapella() -// block.Block.Slot = slot -// block.Block.ParentRoot = parentRoot[:] -// -// for i := uint64(0); i < 10; i++ { -// block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) -// } -// -// signedBlock, err := blocks.NewSignedBeaconBlock(block) -// require.NoError(t, err) -// -// h, err := signedBlock.Header() -// require.NoError(t, err) -// -// err = st.SetLatestBlockHeader(h.Header) -// require.NoError(t, err) -// stateRoot, err := st.HashTreeRoot(ctx) -// require.NoError(t, err) -// -// // get a new signed block so the root is updated with the new state root -// block.Block.StateRoot = stateRoot[:] -// signedBlock, err = blocks.NewSignedBeaconBlock(block) -// require.NoError(t, err) -// -// root, err := block.Block.HashTreeRoot() -// require.NoError(t, err) -// -// mockBlocker := &testutil.MockBlocker{ -// RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ -// parentRoot: signedParent, -// root: signedBlock, -// }, -// SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ -// slot.Sub(1): signedParent, -// slot: signedBlock, -// }, -// } -// mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st, FinalizedRoots: map[[32]byte]bool{ -// root: true, -// }} -// s := &Server{ -// Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ -// slot.Sub(1): attestedState, -// slot: st, -// }}, -// Blocker: mockBlocker, -// HeadFetcher: mockChainService, -// } -// -// minSignaturesRequired := uint64(100) -// eventBlock, err := s.suitableBlock(ctx, minSignaturesRequired) -// -// require.NoError(t, err) -// require.NotNil(t, eventBlock) -// syncAggregate, err := eventBlock.Block().Body().SyncAggregate() -// require.NoError(t, err) -// require.Equal(t, true, syncAggregate.SyncCommitteeBits.Count() >= minSignaturesRequired) -// require.Equal(t, slot-1, eventBlock.Block().Slot()) -// } -// +func TestLightClientHandler_GetLightClientUpdatesByRangeAltair(t *testing.T) { + helpers.ClearCache() + ctx := context.Background() + + params.SetupTestConfigCleanup(t) + config := params.BeaconConfig() + config.AltairForkEpoch = 0 + params.OverrideBeaconConfig(config) + + slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) + + st, err := util.NewBeaconStateAltair() + require.NoError(t, err) + err = st.SetSlot(slot) + require.NoError(t, err) + + db := setupDB(t) + + updatePeriod := uint64(slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch))) + + update, err := createUpdate(t, version.Altair) + require.NoError(t, err) + err = db.SaveLightClientUpdate(ctx, updatePeriod, update) + require.NoError(t, err) + + mockChainService := &mock.ChainService{State: st} + s := &Server{ + HeadFetcher: mockChainService, + BeaconDB: db, + } + startPeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) + url := fmt.Sprintf("http://foo.com/?count=1&start_period=%d", startPeriod) + request := httptest.NewRequest("GET", url, nil) + writer := httptest.NewRecorder() + writer.Body = &bytes.Buffer{} + + s.GetLightClientUpdatesByRange(writer, request) + + require.Equal(t, http.StatusOK, writer.Code) + var resp structs.LightClientUpdatesByRangeResponse + err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) + require.NoError(t, err) + require.Equal(t, 1, len(resp.Updates)) + require.Equal(t, "altair", resp.Updates[0].Version) + updateJson, err := structs.LightClientUpdateFromConsensus(update) + require.NoError(t, err) + require.DeepEqual(t, updateJson, resp.Updates[0].Data) +} + +func TestLightClientHandler_GetLightClientUpdatesByRangeCapella(t *testing.T) { + helpers.ClearCache() + ctx := context.Background() + params.SetupTestConfigCleanup(t) + config := params.BeaconConfig() + config.AltairForkEpoch = 0 + config.CapellaForkEpoch = 1 + params.OverrideBeaconConfig(config) + slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) + + st, err := util.NewBeaconStateCapella() + require.NoError(t, err) + err = st.SetSlot(slot) + require.NoError(t, err) + + db := setupDB(t) + + updatePeriod := uint64(slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch))) + + update, err := createUpdate(t, version.Capella) + require.NoError(t, err) + + err = db.SaveLightClientUpdate(ctx, updatePeriod, update) + require.NoError(t, err) + + mockChainService := &mock.ChainService{State: st} + s := &Server{ + HeadFetcher: mockChainService, + BeaconDB: db, + } + startPeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) + url := fmt.Sprintf("http://foo.com/?count=1&start_period=%d", startPeriod) + request := httptest.NewRequest("GET", url, nil) + writer := httptest.NewRecorder() + writer.Body = &bytes.Buffer{} + + s.GetLightClientUpdatesByRange(writer, request) + + require.Equal(t, http.StatusOK, writer.Code) + var resp structs.LightClientUpdatesByRangeResponse + err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) + require.NoError(t, err) + require.Equal(t, 1, len(resp.Updates)) + require.Equal(t, "capella", resp.Updates[0].Version) + updateJson, err := structs.LightClientUpdateFromConsensus(update) + require.NoError(t, err) + require.DeepEqual(t, updateJson, resp.Updates[0].Data) +} + +func TestLightClientHandler_GetLightClientUpdatesByRangeDeneb(t *testing.T) { + helpers.ClearCache() + ctx := context.Background() + params.SetupTestConfigCleanup(t) + config := params.BeaconConfig() + config.AltairForkEpoch = 0 + config.CapellaForkEpoch = 1 + config.DenebForkEpoch = 2 + params.OverrideBeaconConfig(config) + slot := primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) + + st, err := util.NewBeaconStateDeneb() + require.NoError(t, err) + err = st.SetSlot(slot) + require.NoError(t, err) + + db := setupDB(t) + + updatePeriod := uint64(slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch))) + + update, err := createUpdate(t, version.Deneb) + require.NoError(t, err) + err = db.SaveLightClientUpdate(ctx, updatePeriod, update) + require.NoError(t, err) + + mockChainService := &mock.ChainService{State: st} + s := &Server{ + HeadFetcher: mockChainService, + BeaconDB: db, + } + startPeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) + url := fmt.Sprintf("http://foo.com/?count=1&start_period=%d", startPeriod) + request := httptest.NewRequest("GET", url, nil) + writer := httptest.NewRecorder() + writer.Body = &bytes.Buffer{} + + s.GetLightClientUpdatesByRange(writer, request) + + require.Equal(t, http.StatusOK, writer.Code) + var resp structs.LightClientUpdatesByRangeResponse + err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) + require.NoError(t, err) + require.Equal(t, 1, len(resp.Updates)) + require.Equal(t, "deneb", resp.Updates[0].Version) + updateJson, err := structs.LightClientUpdateFromConsensus(update) + require.NoError(t, err) + require.DeepEqual(t, updateJson, resp.Updates[0].Data) +} + +func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleAltair(t *testing.T) { + helpers.ClearCache() + ctx := context.Background() + params.SetupTestConfigCleanup(t) + config := params.BeaconConfig() + config.AltairForkEpoch = 0 + config.EpochsPerSyncCommitteePeriod = 1 + params.OverrideBeaconConfig(config) + slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) + + st, err := util.NewBeaconStateAltair() + require.NoError(t, err) + headSlot := slot.Add(33) // 2 periods + err = st.SetSlot(headSlot) + require.NoError(t, err) + + db := setupDB(t) + + updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) + + updates := make([]interfaces.LightClientUpdate, 0) + for i := 1; i <= 2; i++ { + update, err := createUpdate(t, version.Altair) + require.NoError(t, err) + updates = append(updates, update) + } + + for _, update := range updates { + err := db.SaveLightClientUpdate(ctx, uint64(updatePeriod), update) + require.NoError(t, err) + updatePeriod++ + } + + mockChainService := &mock.ChainService{State: st} + s := &Server{ + HeadFetcher: mockChainService, + BeaconDB: db, + } + startPeriod := slot.Sub(1).Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) + url := fmt.Sprintf("http://foo.com/?count=100&start_period=%d", startPeriod) + request := httptest.NewRequest("GET", url, nil) + writer := httptest.NewRecorder() + writer.Body = &bytes.Buffer{} + + s.GetLightClientUpdatesByRange(writer, request) + + require.Equal(t, http.StatusOK, writer.Code) + var resp structs.LightClientUpdatesByRangeResponse + err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) + require.NoError(t, err) + require.Equal(t, 2, len(resp.Updates)) + for i, update := range updates { + require.Equal(t, "altair", resp.Updates[i].Version) + updateJson, err := structs.LightClientUpdateFromConsensus(update) + require.NoError(t, err) + require.DeepEqual(t, updateJson, resp.Updates[i].Data) + } +} + +func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleCapella(t *testing.T) { + helpers.ClearCache() + ctx := context.Background() + params.SetupTestConfigCleanup(t) + config := params.BeaconConfig() + config.AltairForkEpoch = 0 + config.CapellaForkEpoch = 1 + config.EpochsPerSyncCommitteePeriod = 1 + params.OverrideBeaconConfig(config) + slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) + + st, err := util.NewBeaconStateAltair() + require.NoError(t, err) + headSlot := slot.Add(33) // 2 periods + err = st.SetSlot(headSlot) + require.NoError(t, err) + + db := setupDB(t) + + updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) + + updates := make([]interfaces.LightClientUpdate, 0) + for i := 0; i < 2; i++ { + update, err := createUpdate(t, version.Capella) + require.NoError(t, err) + updates = append(updates, update) + } + + for _, update := range updates { + err := db.SaveLightClientUpdate(ctx, uint64(updatePeriod), update) + require.NoError(t, err) + updatePeriod++ + } + + mockChainService := &mock.ChainService{State: st} + s := &Server{ + HeadFetcher: mockChainService, + BeaconDB: db, + } + startPeriod := slot.Sub(1).Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) + url := fmt.Sprintf("http://foo.com/?count=100&start_period=%d", startPeriod) + request := httptest.NewRequest("GET", url, nil) + writer := httptest.NewRecorder() + writer.Body = &bytes.Buffer{} + + s.GetLightClientUpdatesByRange(writer, request) + + require.Equal(t, http.StatusOK, writer.Code) + var resp structs.LightClientUpdatesByRangeResponse + err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) + require.NoError(t, err) + require.Equal(t, 2, len(resp.Updates)) + for i, update := range updates { + require.Equal(t, "capella", resp.Updates[i].Version) + updateJson, err := structs.LightClientUpdateFromConsensus(update) + require.NoError(t, err) + require.DeepEqual(t, updateJson, resp.Updates[i].Data) + } +} + +func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleDeneb(t *testing.T) { + helpers.ClearCache() + ctx := context.Background() + params.SetupTestConfigCleanup(t) + config := params.BeaconConfig() + config.AltairForkEpoch = 0 + config.CapellaForkEpoch = 1 + config.DenebForkEpoch = 2 + config.EpochsPerSyncCommitteePeriod = 1 + params.OverrideBeaconConfig(config) + slot := primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) + + st, err := util.NewBeaconStateAltair() + require.NoError(t, err) + headSlot := slot.Add(33) + err = st.SetSlot(headSlot) + require.NoError(t, err) + + db := setupDB(t) + + updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) + + updates := make([]interfaces.LightClientUpdate, 0) + for i := 0; i < 2; i++ { + update, err := createUpdate(t, version.Deneb) + require.NoError(t, err) + updates = append(updates, update) + } + + for _, update := range updates { + err := db.SaveLightClientUpdate(ctx, uint64(updatePeriod), update) + require.NoError(t, err) + updatePeriod++ + } + mockChainService := &mock.ChainService{State: st} + s := &Server{ + HeadFetcher: mockChainService, + BeaconDB: db, + } + startPeriod := slot.Sub(1).Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) + url := fmt.Sprintf("http://foo.com/?count=100&start_period=%d", startPeriod) + request := httptest.NewRequest("GET", url, nil) + writer := httptest.NewRecorder() + writer.Body = &bytes.Buffer{} + + s.GetLightClientUpdatesByRange(writer, request) + + require.Equal(t, http.StatusOK, writer.Code) + var resp structs.LightClientUpdatesByRangeResponse + err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) + require.NoError(t, err) + require.Equal(t, 2, len(resp.Updates)) + for i, update := range updates { + require.Equal(t, "deneb", resp.Updates[i].Version) + updateJson, err := structs.LightClientUpdateFromConsensus(update) + require.NoError(t, err) + require.DeepEqual(t, updateJson, resp.Updates[i].Data) + } +} + +func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleForksAltairCapella(t *testing.T) { + helpers.ClearCache() + ctx := context.Background() + params.SetupTestConfigCleanup(t) + config := params.BeaconConfig() + config.AltairForkEpoch = 0 + config.CapellaForkEpoch = 1 + config.EpochsPerSyncCommitteePeriod = 1 + params.OverrideBeaconConfig(config) + slotCapella := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) + slotAltair := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) + + st, err := util.NewBeaconStateAltair() + require.NoError(t, err) + headSlot := slotCapella.Add(1) + err = st.SetSlot(headSlot) + require.NoError(t, err) + + db := setupDB(t) + + updates := make([]interfaces.LightClientUpdate, 2) + + updatePeriod := slotAltair.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) + + updates[0], err = createUpdate(t, version.Altair) + require.NoError(t, err) + + err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), updates[0]) + require.NoError(t, err) + + updatePeriod = slotCapella.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) + + updates[1], err = createUpdate(t, version.Capella) + require.NoError(t, err) + + err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), updates[1]) + require.NoError(t, err) + + mockChainService := &mock.ChainService{State: st} + s := &Server{ + HeadFetcher: mockChainService, + BeaconDB: db, + } + startPeriod := 0 + url := fmt.Sprintf("http://foo.com/?count=100&start_period=%d", startPeriod) + request := httptest.NewRequest("GET", url, nil) + writer := httptest.NewRecorder() + writer.Body = &bytes.Buffer{} + + s.GetLightClientUpdatesByRange(writer, request) + + require.Equal(t, http.StatusOK, writer.Code) + var resp structs.LightClientUpdatesByRangeResponse + err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) + require.NoError(t, err) + require.Equal(t, 2, len(resp.Updates)) + for i, update := range updates { + if i < 1 { + require.Equal(t, "altair", resp.Updates[i].Version) + } else { + require.Equal(t, "capella", resp.Updates[i].Version) + } + updateJson, err := structs.LightClientUpdateFromConsensus(update) + require.NoError(t, err) + require.DeepEqual(t, updateJson, resp.Updates[i].Data) + } +} + +func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleForksCapellaDeneb(t *testing.T) { + helpers.ClearCache() + ctx := context.Background() + params.SetupTestConfigCleanup(t) + config := params.BeaconConfig() + config.AltairForkEpoch = 0 + config.CapellaForkEpoch = 1 + config.DenebForkEpoch = 2 + config.EpochsPerSyncCommitteePeriod = 1 + params.OverrideBeaconConfig(config) + slotDeneb := primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) + slotCapella := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) + + st, err := util.NewBeaconStateAltair() + require.NoError(t, err) + headSlot := slotDeneb.Add(1) + err = st.SetSlot(headSlot) + require.NoError(t, err) + + db := setupDB(t) + + updates := make([]interfaces.LightClientUpdate, 2) + + updatePeriod := slotCapella.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) + + updates[0], err = createUpdate(t, version.Capella) + require.NoError(t, err) + + err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), updates[0]) + require.NoError(t, err) + + updatePeriod = slotDeneb.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) + + updates[1], err = createUpdate(t, version.Deneb) + require.NoError(t, err) + + err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), updates[1]) + require.NoError(t, err) + + mockChainService := &mock.ChainService{State: st} + s := &Server{ + HeadFetcher: mockChainService, + BeaconDB: db, + } + startPeriod := 1 + url := fmt.Sprintf("http://foo.com/?count=100&start_period=%d", startPeriod) + request := httptest.NewRequest("GET", url, nil) + writer := httptest.NewRecorder() + writer.Body = &bytes.Buffer{} + + s.GetLightClientUpdatesByRange(writer, request) + + require.Equal(t, http.StatusOK, writer.Code) + var resp structs.LightClientUpdatesByRangeResponse + err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) + require.NoError(t, err) + require.Equal(t, 2, len(resp.Updates)) + for i, update := range updates { + if i < 1 { + require.Equal(t, "capella", resp.Updates[i].Version) + } else { + require.Equal(t, "deneb", resp.Updates[i].Version) + } + updateJson, err := structs.LightClientUpdateFromConsensus(update) + require.NoError(t, err) + require.DeepEqual(t, updateJson, resp.Updates[i].Data) + } +} + +func TestLightClientHandler_GetLightClientUpdatesByRangeCountBiggerThanLimit(t *testing.T) { + helpers.ClearCache() + ctx := context.Background() + params.SetupTestConfigCleanup(t) + config := params.BeaconConfig() + config.AltairForkEpoch = 0 + config.EpochsPerSyncCommitteePeriod = 1 + config.MaxRequestLightClientUpdates = 2 + params.OverrideBeaconConfig(config) + slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) + + st, err := util.NewBeaconStateAltair() + require.NoError(t, err) + headSlot := slot.Add(65) + err = st.SetSlot(headSlot) + require.NoError(t, err) + + db := setupDB(t) + + updates := make([]interfaces.LightClientUpdate, 3) + + updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) + + for i := 0; i < 3; i++ { + + updates[i], err = createUpdate(t, version.Altair) + require.NoError(t, err) + + err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), updates[i]) + require.NoError(t, err) + + updatePeriod++ + } + + mockChainService := &mock.ChainService{State: st} + s := &Server{ + HeadFetcher: mockChainService, + BeaconDB: db, + } + startPeriod := 0 + url := fmt.Sprintf("http://foo.com/?count=4&start_period=%d", startPeriod) + request := httptest.NewRequest("GET", url, nil) + writer := httptest.NewRecorder() + writer.Body = &bytes.Buffer{} + + s.GetLightClientUpdatesByRange(writer, request) + + require.Equal(t, http.StatusOK, writer.Code) + var resp structs.LightClientUpdatesByRangeResponse + err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) + require.NoError(t, err) + require.Equal(t, 2, len(resp.Updates)) + for i, update := range updates { + if i < 2 { + require.Equal(t, "altair", resp.Updates[i].Version) + updateJson, err := structs.LightClientUpdateFromConsensus(update) + require.NoError(t, err) + require.DeepEqual(t, updateJson, resp.Updates[i].Data) + } + } +} + +func TestLightClientHandler_GetLightClientUpdatesByRangeCountBiggerThanMax(t *testing.T) { + helpers.ClearCache() + ctx := context.Background() + params.SetupTestConfigCleanup(t) + config := params.BeaconConfig() + config.AltairForkEpoch = 0 + config.EpochsPerSyncCommitteePeriod = 1 + config.MaxRequestLightClientUpdates = 2 + params.OverrideBeaconConfig(config) + slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) + + st, err := util.NewBeaconStateAltair() + require.NoError(t, err) + headSlot := slot.Add(65) + err = st.SetSlot(headSlot) + require.NoError(t, err) + + db := setupDB(t) + + updates := make([]interfaces.LightClientUpdate, 3) + + updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) + + for i := 0; i < 3; i++ { + updates[i], err = createUpdate(t, version.Altair) + require.NoError(t, err) + + err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), updates[i]) + require.NoError(t, err) + + updatePeriod++ + } + + mockChainService := &mock.ChainService{State: st} + s := &Server{ + HeadFetcher: mockChainService, + BeaconDB: db, + } + startPeriod := 0 + url := fmt.Sprintf("http://foo.com/?count=10&start_period=%d", startPeriod) + request := httptest.NewRequest("GET", url, nil) + writer := httptest.NewRecorder() + writer.Body = &bytes.Buffer{} + + s.GetLightClientUpdatesByRange(writer, request) + + require.Equal(t, http.StatusOK, writer.Code) + var resp structs.LightClientUpdatesByRangeResponse + err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) + require.NoError(t, err) + require.Equal(t, 2, len(resp.Updates)) + for i, update := range updates { + if i < 2 { + require.Equal(t, "altair", resp.Updates[i].Version) + updateJson, err := structs.LightClientUpdateFromConsensus(update) + require.NoError(t, err) + require.DeepEqual(t, updateJson, resp.Updates[i].Data) + } + } +} + +func TestLightClientHandler_GetLightClientUpdatesByRangeStartPeriodBeforeAltair(t *testing.T) { + helpers.ClearCache() + ctx := context.Background() + params.SetupTestConfigCleanup(t) + config := params.BeaconConfig() + config.AltairForkEpoch = 1 + config.EpochsPerSyncCommitteePeriod = 1 + params.OverrideBeaconConfig(config) + slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) + + st, err := util.NewBeaconStateAltair() + require.NoError(t, err) + headSlot := slot.Add(1) + err = st.SetSlot(headSlot) + require.NoError(t, err) + + db := setupDB(t) + + updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) + + update, err := createUpdate(t, version.Altair) + require.NoError(t, err) + + err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), update) + require.NoError(t, err) + + mockChainService := &mock.ChainService{State: st} + s := &Server{ + HeadFetcher: mockChainService, + BeaconDB: db, + } + startPeriod := 0 + url := fmt.Sprintf("http://foo.com/?count=2&start_period=%d", startPeriod) + request := httptest.NewRequest("GET", url, nil) + writer := httptest.NewRecorder() + writer.Body = &bytes.Buffer{} + + s.GetLightClientUpdatesByRange(writer, request) + + require.Equal(t, http.StatusOK, writer.Code) + var resp structs.LightClientUpdatesByRangeResponse + err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) + require.NoError(t, err) + require.Equal(t, 1, len(resp.Updates)) + + require.Equal(t, "altair", resp.Updates[0].Version) + updateJson, err := structs.LightClientUpdateFromConsensus(update) + require.NoError(t, err) + require.DeepEqual(t, updateJson, resp.Updates[0].Data) + +} + +func TestLightClientHandler_GetLightClientUpdatesByRangeMissingUpdates(t *testing.T) { + helpers.ClearCache() + ctx := context.Background() + params.SetupTestConfigCleanup(t) + config := params.BeaconConfig() + config.AltairForkEpoch = 0 + config.EpochsPerSyncCommitteePeriod = 1 + params.OverrideBeaconConfig(config) + slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) + + st, err := util.NewBeaconStateAltair() + require.NoError(t, err) + headSlot := slot.Add(65) + err = st.SetSlot(headSlot) + require.NoError(t, err) + + t.Run("missing update in the middle", func(t *testing.T) { + db := setupDB(t) + + updates := make([]interfaces.LightClientUpdate, 3) + + updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) + + for i := 0; i < 3; i++ { + if i == 1 { // skip this update + updatePeriod++ + continue + } + + updates[i], err = createUpdate(t, version.Altair) + require.NoError(t, err) + + err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), updates[i]) + require.NoError(t, err) + + updatePeriod++ + } + + mockChainService := &mock.ChainService{State: st} + s := &Server{ + HeadFetcher: mockChainService, + BeaconDB: db, + } + startPeriod := 0 + url := fmt.Sprintf("http://foo.com/?count=10&start_period=%d", startPeriod) + request := httptest.NewRequest("GET", url, nil) + writer := httptest.NewRecorder() + writer.Body = &bytes.Buffer{} + + s.GetLightClientUpdatesByRange(writer, request) + + require.Equal(t, http.StatusOK, writer.Code) + var resp structs.LightClientUpdatesByRangeResponse + err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) + require.NoError(t, err) + require.Equal(t, 1, len(resp.Updates)) + require.Equal(t, "altair", resp.Updates[0].Version) + updateJson, err := structs.LightClientUpdateFromConsensus(updates[0]) + require.NoError(t, err) + require.DeepEqual(t, updateJson, resp.Updates[0].Data) + }) + + t.Run("missing update at the beginning", func(t *testing.T) { + db := setupDB(t) + + updates := make([]interfaces.LightClientUpdate, 3) + + updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) + + for i := 0; i < 3; i++ { + if i == 0 { // skip this update + updatePeriod++ + continue + } + + updates[i], err = createUpdate(t, version.Altair) + require.NoError(t, err) + + err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), updates[i]) + require.NoError(t, err) + + updatePeriod++ + } + + mockChainService := &mock.ChainService{State: st} + s := &Server{ + HeadFetcher: mockChainService, + BeaconDB: db, + } + startPeriod := 0 + url := fmt.Sprintf("http://foo.com/?count=10&start_period=%d", startPeriod) + request := httptest.NewRequest("GET", url, nil) + writer := httptest.NewRecorder() + writer.Body = &bytes.Buffer{} + + s.GetLightClientUpdatesByRange(writer, request) + + require.Equal(t, http.StatusOK, writer.Code) + var resp structs.LightClientUpdatesByRangeResponse + err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates) + require.NoError(t, err) + require.Equal(t, 0, len(resp.Updates)) + }) + +} + +// // TestLightClientHandler_GetLightClientFinalityUpdate tests + +func TestLightClientHandler_GetLightClientFinalityUpdateAltair(t *testing.T) { + helpers.ClearCache() + ctx := context.Background() + params.SetupTestConfigCleanup(t) + config := params.BeaconConfig() + slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) + + attestedState, err := util.NewBeaconStateAltair() + require.NoError(t, err) + err = attestedState.SetSlot(slot.Sub(1)) + require.NoError(t, err) + + require.NoError(t, attestedState.SetFinalizedCheckpoint(&pb.Checkpoint{ + Epoch: config.AltairForkEpoch - 10, + Root: make([]byte, 32), + })) + + parent := util.NewBeaconBlockAltair() + parent.Block.Slot = slot.Sub(1) + + signedParent, err := blocks.NewSignedBeaconBlock(parent) + require.NoError(t, err) + + parentHeader, err := signedParent.Header() + require.NoError(t, err) + attestedHeader := parentHeader.Header + + err = attestedState.SetLatestBlockHeader(attestedHeader) + require.NoError(t, err) + attestedStateRoot, err := attestedState.HashTreeRoot(ctx) + require.NoError(t, err) + + // get a new signed block so the root is updated with the new state root + parent.Block.StateRoot = attestedStateRoot[:] + signedParent, err = blocks.NewSignedBeaconBlock(parent) + require.NoError(t, err) + + st, err := util.NewBeaconStateAltair() + require.NoError(t, err) + err = st.SetSlot(slot) + require.NoError(t, err) + + parentRoot, err := signedParent.Block().HashTreeRoot() + require.NoError(t, err) + + block := util.NewBeaconBlockAltair() + block.Block.Slot = slot + block.Block.ParentRoot = parentRoot[:] + + for i := uint64(0); i < config.SyncCommitteeSize; i++ { + block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) + } + + signedBlock, err := blocks.NewSignedBeaconBlock(block) + require.NoError(t, err) + + h, err := signedBlock.Header() + require.NoError(t, err) + + err = st.SetLatestBlockHeader(h.Header) + require.NoError(t, err) + stateRoot, err := st.HashTreeRoot(ctx) + require.NoError(t, err) + + // get a new signed block so the root is updated with the new state root + block.Block.StateRoot = stateRoot[:] + signedBlock, err = blocks.NewSignedBeaconBlock(block) + require.NoError(t, err) + + root, err := block.Block.HashTreeRoot() + require.NoError(t, err) + + mockBlocker := &testutil.MockBlocker{ + RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ + parentRoot: signedParent, + root: signedBlock, + }, + SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ + slot.Sub(1): signedParent, + slot: signedBlock, + }, + } + mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st, FinalizedRoots: map[[32]byte]bool{ + root: true, + }} + mockChainInfoFetcher := &mock.ChainService{Slot: &slot} + s := &Server{ + Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ + slot.Sub(1): attestedState, + slot: st, + }}, + Blocker: mockBlocker, + HeadFetcher: mockChainService, + ChainInfoFetcher: mockChainInfoFetcher, + } + request := httptest.NewRequest("GET", "http://foo.com", nil) + writer := httptest.NewRecorder() + writer.Body = &bytes.Buffer{} + + s.GetLightClientFinalityUpdate(writer, request) + + require.Equal(t, http.StatusOK, writer.Code) + var resp *structs.LightClientUpdateResponse + err = json.Unmarshal(writer.Body.Bytes(), &resp) + require.NoError(t, err) + var respHeader structs.LightClientHeader + err = json.Unmarshal(resp.Data.AttestedHeader, &respHeader) + require.NoError(t, err) + require.Equal(t, "altair", resp.Version) + require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot) + require.NotNil(t, resp.Data) +} + +func TestLightClientHandler_GetLightClientFinalityUpdateCapella(t *testing.T) { + helpers.ClearCache() + ctx := context.Background() + params.SetupTestConfigCleanup(t) + config := params.BeaconConfig() + slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) + + attestedState, err := util.NewBeaconStateCapella() + require.NoError(t, err) + err = attestedState.SetSlot(slot.Sub(1)) + require.NoError(t, err) + + require.NoError(t, attestedState.SetFinalizedCheckpoint(&pb.Checkpoint{ + Epoch: config.AltairForkEpoch - 10, + Root: make([]byte, 32), + })) + + parent := util.NewBeaconBlockCapella() + parent.Block.Slot = slot.Sub(1) + + signedParent, err := blocks.NewSignedBeaconBlock(parent) + require.NoError(t, err) + + parentHeader, err := signedParent.Header() + require.NoError(t, err) + attestedHeader := parentHeader.Header + + err = attestedState.SetLatestBlockHeader(attestedHeader) + require.NoError(t, err) + attestedStateRoot, err := attestedState.HashTreeRoot(ctx) + require.NoError(t, err) + + // get a new signed block so the root is updated with the new state root + parent.Block.StateRoot = attestedStateRoot[:] + signedParent, err = blocks.NewSignedBeaconBlock(parent) + require.NoError(t, err) + + st, err := util.NewBeaconStateCapella() + require.NoError(t, err) + err = st.SetSlot(slot) + require.NoError(t, err) + + parentRoot, err := signedParent.Block().HashTreeRoot() + require.NoError(t, err) + + block := util.NewBeaconBlockCapella() + block.Block.Slot = slot + block.Block.ParentRoot = parentRoot[:] + + for i := uint64(0); i < config.SyncCommitteeSize; i++ { + block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) + } + + signedBlock, err := blocks.NewSignedBeaconBlock(block) + require.NoError(t, err) + + h, err := signedBlock.Header() + require.NoError(t, err) + + err = st.SetLatestBlockHeader(h.Header) + require.NoError(t, err) + stateRoot, err := st.HashTreeRoot(ctx) + require.NoError(t, err) + + // get a new signed block so the root is updated with the new state root + block.Block.StateRoot = stateRoot[:] + signedBlock, err = blocks.NewSignedBeaconBlock(block) + require.NoError(t, err) + + root, err := block.Block.HashTreeRoot() + require.NoError(t, err) + + mockBlocker := &testutil.MockBlocker{ + RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ + parentRoot: signedParent, + root: signedBlock, + }, + SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ + slot.Sub(1): signedParent, + slot: signedBlock, + }, + } + mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st, FinalizedRoots: map[[32]byte]bool{ + root: true, + }} + mockChainInfoFetcher := &mock.ChainService{Slot: &slot} + s := &Server{ + Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ + slot.Sub(1): attestedState, + slot: st, + }}, + Blocker: mockBlocker, + HeadFetcher: mockChainService, + ChainInfoFetcher: mockChainInfoFetcher, + } + request := httptest.NewRequest("GET", "http://foo.com", nil) + writer := httptest.NewRecorder() + writer.Body = &bytes.Buffer{} + + s.GetLightClientFinalityUpdate(writer, request) + + require.Equal(t, http.StatusOK, writer.Code) + var resp *structs.LightClientUpdateResponse + err = json.Unmarshal(writer.Body.Bytes(), &resp) + require.NoError(t, err) + var respHeader structs.LightClientHeader + err = json.Unmarshal(resp.Data.AttestedHeader, &respHeader) + require.NoError(t, err) + require.Equal(t, "capella", resp.Version) + require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot) + require.NotNil(t, resp.Data) +} + +func TestLightClientHandler_GetLightClientFinalityUpdateDeneb(t *testing.T) { + helpers.ClearCache() + ctx := context.Background() + params.SetupTestConfigCleanup(t) + config := params.BeaconConfig() + slot := primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) + + attestedState, err := util.NewBeaconStateDeneb() + require.NoError(t, err) + err = attestedState.SetSlot(slot.Sub(1)) + require.NoError(t, err) + + require.NoError(t, attestedState.SetFinalizedCheckpoint(&pb.Checkpoint{ + Epoch: config.AltairForkEpoch - 10, + Root: make([]byte, 32), + })) + + parent := util.NewBeaconBlockDeneb() + parent.Block.Slot = slot.Sub(1) + + signedParent, err := blocks.NewSignedBeaconBlock(parent) + require.NoError(t, err) + + parentHeader, err := signedParent.Header() + require.NoError(t, err) + attestedHeader := parentHeader.Header + + err = attestedState.SetLatestBlockHeader(attestedHeader) + require.NoError(t, err) + attestedStateRoot, err := attestedState.HashTreeRoot(ctx) + require.NoError(t, err) + + // get a new signed block so the root is updated with the new state root + parent.Block.StateRoot = attestedStateRoot[:] + signedParent, err = blocks.NewSignedBeaconBlock(parent) + require.NoError(t, err) + + st, err := util.NewBeaconStateDeneb() + require.NoError(t, err) + err = st.SetSlot(slot) + require.NoError(t, err) + + parentRoot, err := signedParent.Block().HashTreeRoot() + require.NoError(t, err) + + block := util.NewBeaconBlockDeneb() + block.Block.Slot = slot + block.Block.ParentRoot = parentRoot[:] + + for i := uint64(0); i < config.SyncCommitteeSize; i++ { + block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) + } + + signedBlock, err := blocks.NewSignedBeaconBlock(block) + require.NoError(t, err) + + h, err := signedBlock.Header() + require.NoError(t, err) + + err = st.SetLatestBlockHeader(h.Header) + require.NoError(t, err) + stateRoot, err := st.HashTreeRoot(ctx) + require.NoError(t, err) + + // get a new signed block so the root is updated with the new state root + block.Block.StateRoot = stateRoot[:] + signedBlock, err = blocks.NewSignedBeaconBlock(block) + require.NoError(t, err) + + root, err := block.Block.HashTreeRoot() + require.NoError(t, err) + + mockBlocker := &testutil.MockBlocker{ + RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ + parentRoot: signedParent, + root: signedBlock, + }, + SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ + slot.Sub(1): signedParent, + slot: signedBlock, + }, + } + mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st, FinalizedRoots: map[[32]byte]bool{ + root: true, + }} + mockChainInfoFetcher := &mock.ChainService{Slot: &slot} + s := &Server{ + Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ + slot.Sub(1): attestedState, + slot: st, + }}, + Blocker: mockBlocker, + HeadFetcher: mockChainService, + ChainInfoFetcher: mockChainInfoFetcher, + } + request := httptest.NewRequest("GET", "http://foo.com", nil) + writer := httptest.NewRecorder() + writer.Body = &bytes.Buffer{} + + s.GetLightClientFinalityUpdate(writer, request) + + require.Equal(t, http.StatusOK, writer.Code) + var resp *structs.LightClientUpdateResponse + err = json.Unmarshal(writer.Body.Bytes(), &resp) + require.NoError(t, err) + var respHeader structs.LightClientHeaderDeneb + err = json.Unmarshal(resp.Data.AttestedHeader, &respHeader) + require.NoError(t, err) + require.Equal(t, "deneb", resp.Version) + require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot) + require.NotNil(t, resp.Data) +} + +func TestLightClientHandler_GetLightClientOptimisticUpdateAltair(t *testing.T) { + helpers.ClearCache() + ctx := context.Background() + params.SetupTestConfigCleanup(t) + config := params.BeaconConfig() + slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) + + attestedState, err := util.NewBeaconStateAltair() + require.NoError(t, err) + err = attestedState.SetSlot(slot.Sub(1)) + require.NoError(t, err) + + require.NoError(t, attestedState.SetFinalizedCheckpoint(&pb.Checkpoint{ + Epoch: config.AltairForkEpoch - 10, + Root: make([]byte, 32), + })) + + parent := util.NewBeaconBlockAltair() + parent.Block.Slot = slot.Sub(1) + + signedParent, err := blocks.NewSignedBeaconBlock(parent) + require.NoError(t, err) + + parentHeader, err := signedParent.Header() + require.NoError(t, err) + attestedHeader := parentHeader.Header + + err = attestedState.SetLatestBlockHeader(attestedHeader) + require.NoError(t, err) + attestedStateRoot, err := attestedState.HashTreeRoot(ctx) + require.NoError(t, err) + + // get a new signed block so the root is updated with the new state root + parent.Block.StateRoot = attestedStateRoot[:] + signedParent, err = blocks.NewSignedBeaconBlock(parent) + require.NoError(t, err) + + st, err := util.NewBeaconStateAltair() + require.NoError(t, err) + err = st.SetSlot(slot) + require.NoError(t, err) + + parentRoot, err := signedParent.Block().HashTreeRoot() + require.NoError(t, err) + + block := util.NewBeaconBlockAltair() + block.Block.Slot = slot + block.Block.ParentRoot = parentRoot[:] + + for i := uint64(0); i < config.SyncCommitteeSize; i++ { + block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) + } + + signedBlock, err := blocks.NewSignedBeaconBlock(block) + require.NoError(t, err) + + h, err := signedBlock.Header() + require.NoError(t, err) + + err = st.SetLatestBlockHeader(h.Header) + require.NoError(t, err) + stateRoot, err := st.HashTreeRoot(ctx) + require.NoError(t, err) + + // get a new signed block so the root is updated with the new state root + block.Block.StateRoot = stateRoot[:] + signedBlock, err = blocks.NewSignedBeaconBlock(block) + require.NoError(t, err) + + root, err := block.Block.HashTreeRoot() + require.NoError(t, err) + + mockBlocker := &testutil.MockBlocker{ + RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ + parentRoot: signedParent, + root: signedBlock, + }, + SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ + slot.Sub(1): signedParent, + slot: signedBlock, + }, + } + mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st, FinalizedRoots: map[[32]byte]bool{ + root: true, + }} + mockChainInfoFetcher := &mock.ChainService{Slot: &slot} + s := &Server{ + Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ + slot.Sub(1): attestedState, + slot: st, + }}, + Blocker: mockBlocker, + HeadFetcher: mockChainService, + ChainInfoFetcher: mockChainInfoFetcher, + } + request := httptest.NewRequest("GET", "http://foo.com", nil) + writer := httptest.NewRecorder() + writer.Body = &bytes.Buffer{} + + s.GetLightClientOptimisticUpdate(writer, request) + + require.Equal(t, http.StatusOK, writer.Code) + var resp *structs.LightClientUpdateResponse + err = json.Unmarshal(writer.Body.Bytes(), &resp) + require.NoError(t, err) + var respHeader structs.LightClientHeader + err = json.Unmarshal(resp.Data.AttestedHeader, &respHeader) + require.NoError(t, err) + require.Equal(t, "altair", resp.Version) + require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot) + require.NotNil(t, resp.Data) +} + +func TestLightClientHandler_GetLightClientOptimisticUpdateCapella(t *testing.T) { + helpers.ClearCache() + ctx := context.Background() + params.SetupTestConfigCleanup(t) + config := params.BeaconConfig() + slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) + + attestedState, err := util.NewBeaconStateCapella() + require.NoError(t, err) + err = attestedState.SetSlot(slot.Sub(1)) + require.NoError(t, err) + + require.NoError(t, attestedState.SetFinalizedCheckpoint(&pb.Checkpoint{ + Epoch: config.AltairForkEpoch - 10, + Root: make([]byte, 32), + })) + + parent := util.NewBeaconBlockCapella() + parent.Block.Slot = slot.Sub(1) + + signedParent, err := blocks.NewSignedBeaconBlock(parent) + require.NoError(t, err) + + parentHeader, err := signedParent.Header() + require.NoError(t, err) + attestedHeader := parentHeader.Header + + err = attestedState.SetLatestBlockHeader(attestedHeader) + require.NoError(t, err) + attestedStateRoot, err := attestedState.HashTreeRoot(ctx) + require.NoError(t, err) + + // get a new signed block so the root is updated with the new state root + parent.Block.StateRoot = attestedStateRoot[:] + signedParent, err = blocks.NewSignedBeaconBlock(parent) + require.NoError(t, err) + + st, err := util.NewBeaconStateCapella() + require.NoError(t, err) + err = st.SetSlot(slot) + require.NoError(t, err) + + parentRoot, err := signedParent.Block().HashTreeRoot() + require.NoError(t, err) + + block := util.NewBeaconBlockCapella() + block.Block.Slot = slot + block.Block.ParentRoot = parentRoot[:] + + for i := uint64(0); i < config.SyncCommitteeSize; i++ { + block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) + } + + signedBlock, err := blocks.NewSignedBeaconBlock(block) + require.NoError(t, err) + + h, err := signedBlock.Header() + require.NoError(t, err) + + err = st.SetLatestBlockHeader(h.Header) + require.NoError(t, err) + stateRoot, err := st.HashTreeRoot(ctx) + require.NoError(t, err) + + // get a new signed block so the root is updated with the new state root + block.Block.StateRoot = stateRoot[:] + signedBlock, err = blocks.NewSignedBeaconBlock(block) + require.NoError(t, err) + + root, err := block.Block.HashTreeRoot() + require.NoError(t, err) + + mockBlocker := &testutil.MockBlocker{ + RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ + parentRoot: signedParent, + root: signedBlock, + }, + SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ + slot.Sub(1): signedParent, + slot: signedBlock, + }, + } + mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st, FinalizedRoots: map[[32]byte]bool{ + root: true, + }} + mockChainInfoFetcher := &mock.ChainService{Slot: &slot} + s := &Server{ + Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ + slot.Sub(1): attestedState, + slot: st, + }}, + Blocker: mockBlocker, + HeadFetcher: mockChainService, + ChainInfoFetcher: mockChainInfoFetcher, + } + request := httptest.NewRequest("GET", "http://foo.com", nil) + writer := httptest.NewRecorder() + writer.Body = &bytes.Buffer{} + + s.GetLightClientOptimisticUpdate(writer, request) + + require.Equal(t, http.StatusOK, writer.Code) + var resp *structs.LightClientUpdateResponse + err = json.Unmarshal(writer.Body.Bytes(), &resp) + require.NoError(t, err) + var respHeader structs.LightClientHeaderCapella + err = json.Unmarshal(resp.Data.AttestedHeader, &respHeader) + require.NoError(t, err) + require.Equal(t, "capella", resp.Version) + require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot) + require.NotNil(t, resp.Data) +} + +func TestLightClientHandler_GetLightClientOptimisticUpdateDeneb(t *testing.T) { + helpers.ClearCache() + ctx := context.Background() + params.SetupTestConfigCleanup(t) + config := params.BeaconConfig() + slot := primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) + + attestedState, err := util.NewBeaconStateDeneb() + require.NoError(t, err) + err = attestedState.SetSlot(slot.Sub(1)) + require.NoError(t, err) + + require.NoError(t, attestedState.SetFinalizedCheckpoint(&pb.Checkpoint{ + Epoch: config.AltairForkEpoch - 10, + Root: make([]byte, 32), + })) + + parent := util.NewBeaconBlockDeneb() + parent.Block.Slot = slot.Sub(1) + + signedParent, err := blocks.NewSignedBeaconBlock(parent) + require.NoError(t, err) + + parentHeader, err := signedParent.Header() + require.NoError(t, err) + attestedHeader := parentHeader.Header + + err = attestedState.SetLatestBlockHeader(attestedHeader) + require.NoError(t, err) + attestedStateRoot, err := attestedState.HashTreeRoot(ctx) + require.NoError(t, err) + + // get a new signed block so the root is updated with the new state root + parent.Block.StateRoot = attestedStateRoot[:] + signedParent, err = blocks.NewSignedBeaconBlock(parent) + require.NoError(t, err) + + st, err := util.NewBeaconStateDeneb() + require.NoError(t, err) + err = st.SetSlot(slot) + require.NoError(t, err) + + parentRoot, err := signedParent.Block().HashTreeRoot() + require.NoError(t, err) + + block := util.NewBeaconBlockDeneb() + block.Block.Slot = slot + block.Block.ParentRoot = parentRoot[:] + + for i := uint64(0); i < config.SyncCommitteeSize; i++ { + block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) + } + + signedBlock, err := blocks.NewSignedBeaconBlock(block) + require.NoError(t, err) + + h, err := signedBlock.Header() + require.NoError(t, err) + + err = st.SetLatestBlockHeader(h.Header) + require.NoError(t, err) + stateRoot, err := st.HashTreeRoot(ctx) + require.NoError(t, err) + + // get a new signed block so the root is updated with the new state root + block.Block.StateRoot = stateRoot[:] + signedBlock, err = blocks.NewSignedBeaconBlock(block) + require.NoError(t, err) + + root, err := block.Block.HashTreeRoot() + require.NoError(t, err) + + mockBlocker := &testutil.MockBlocker{ + RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ + parentRoot: signedParent, + root: signedBlock, + }, + SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ + slot.Sub(1): signedParent, + slot: signedBlock, + }, + } + mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st, FinalizedRoots: map[[32]byte]bool{ + root: true, + }} + mockChainInfoFetcher := &mock.ChainService{Slot: &slot} + s := &Server{ + Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ + slot.Sub(1): attestedState, + slot: st, + }}, + Blocker: mockBlocker, + HeadFetcher: mockChainService, + ChainInfoFetcher: mockChainInfoFetcher, + } + request := httptest.NewRequest("GET", "http://foo.com", nil) + writer := httptest.NewRecorder() + writer.Body = &bytes.Buffer{} + + s.GetLightClientOptimisticUpdate(writer, request) + + require.Equal(t, http.StatusOK, writer.Code) + var resp *structs.LightClientUpdateResponse + err = json.Unmarshal(writer.Body.Bytes(), &resp) + require.NoError(t, err) + var respHeader structs.LightClientHeaderDeneb + err = json.Unmarshal(resp.Data.AttestedHeader, &respHeader) + require.NoError(t, err) + require.Equal(t, "deneb", resp.Version) + require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot) + require.NotNil(t, resp.Data) +} + +func TestLightClientHandler_GetLightClientEventBlock(t *testing.T) { + helpers.ClearCache() + ctx := context.Background() + params.SetupTestConfigCleanup(t) + config := params.BeaconConfig() + slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) + + attestedState, err := util.NewBeaconStateCapella() + require.NoError(t, err) + err = attestedState.SetSlot(slot.Sub(1)) + require.NoError(t, err) + + require.NoError(t, attestedState.SetFinalizedCheckpoint(&pb.Checkpoint{ + Epoch: config.AltairForkEpoch - 10, + Root: make([]byte, 32), + })) + + parent := util.NewBeaconBlockCapella() + parent.Block.Slot = slot.Sub(1) + + signedParent, err := blocks.NewSignedBeaconBlock(parent) + require.NoError(t, err) + + parentHeader, err := signedParent.Header() + require.NoError(t, err) + attestedHeader := parentHeader.Header + + err = attestedState.SetLatestBlockHeader(attestedHeader) + require.NoError(t, err) + attestedStateRoot, err := attestedState.HashTreeRoot(ctx) + require.NoError(t, err) + + // get a new signed block so the root is updated with the new state root + parent.Block.StateRoot = attestedStateRoot[:] + signedParent, err = blocks.NewSignedBeaconBlock(parent) + require.NoError(t, err) + + st, err := util.NewBeaconStateCapella() + require.NoError(t, err) + err = st.SetSlot(slot) + require.NoError(t, err) + + parentRoot, err := signedParent.Block().HashTreeRoot() + require.NoError(t, err) + + block := util.NewBeaconBlockCapella() + block.Block.Slot = slot + block.Block.ParentRoot = parentRoot[:] + + for i := uint64(0); i < config.SyncCommitteeSize; i++ { + block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) + } + + signedBlock, err := blocks.NewSignedBeaconBlock(block) + require.NoError(t, err) + + h, err := signedBlock.Header() + require.NoError(t, err) + + err = st.SetLatestBlockHeader(h.Header) + require.NoError(t, err) + stateRoot, err := st.HashTreeRoot(ctx) + require.NoError(t, err) + + // get a new signed block so the root is updated with the new state root + block.Block.StateRoot = stateRoot[:] + signedBlock, err = blocks.NewSignedBeaconBlock(block) + require.NoError(t, err) + + root, err := block.Block.HashTreeRoot() + require.NoError(t, err) + + mockBlocker := &testutil.MockBlocker{ + RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ + parentRoot: signedParent, + root: signedBlock, + }, + SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ + slot.Sub(1): signedParent, + slot: signedBlock, + }, + } + mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st, FinalizedRoots: map[[32]byte]bool{ + root: true, + }} + mockChainInfoFetcher := &mock.ChainService{Slot: &slot} + s := &Server{ + Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ + slot.Sub(1): attestedState, + slot: st, + }}, + Blocker: mockBlocker, + HeadFetcher: mockChainService, + ChainInfoFetcher: mockChainInfoFetcher, + } + + minSignaturesRequired := uint64(100) + eventBlock, err := s.suitableBlock(ctx, minSignaturesRequired) + + require.NoError(t, err) + require.NotNil(t, eventBlock) + require.Equal(t, slot, eventBlock.Block().Slot()) + syncAggregate, err := eventBlock.Block().Body().SyncAggregate() + require.NoError(t, err) + require.Equal(t, true, syncAggregate.SyncCommitteeBits.Count() >= minSignaturesRequired) +} + +func TestLightClientHandler_GetLightClientEventBlock_NeedFetchParent(t *testing.T) { + helpers.ClearCache() + ctx := context.Background() + params.SetupTestConfigCleanup(t) + config := params.BeaconConfig() + slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) + + attestedState, err := util.NewBeaconStateCapella() + require.NoError(t, err) + err = attestedState.SetSlot(slot.Sub(1)) + require.NoError(t, err) + + require.NoError(t, attestedState.SetFinalizedCheckpoint(&pb.Checkpoint{ + Epoch: config.AltairForkEpoch - 10, + Root: make([]byte, 32), + })) + + parent := util.NewBeaconBlockCapella() + parent.Block.Slot = slot.Sub(1) + for i := uint64(0); i < config.SyncCommitteeSize; i++ { + parent.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) + } + + signedParent, err := blocks.NewSignedBeaconBlock(parent) + require.NoError(t, err) + + parentHeader, err := signedParent.Header() + require.NoError(t, err) + attestedHeader := parentHeader.Header + + err = attestedState.SetLatestBlockHeader(attestedHeader) + require.NoError(t, err) + attestedStateRoot, err := attestedState.HashTreeRoot(ctx) + require.NoError(t, err) + + // get a new signed block so the root is updated with the new state root + parent.Block.StateRoot = attestedStateRoot[:] + signedParent, err = blocks.NewSignedBeaconBlock(parent) + require.NoError(t, err) + + st, err := util.NewBeaconStateCapella() + require.NoError(t, err) + err = st.SetSlot(slot) + require.NoError(t, err) + + parentRoot, err := signedParent.Block().HashTreeRoot() + require.NoError(t, err) + + block := util.NewBeaconBlockCapella() + block.Block.Slot = slot + block.Block.ParentRoot = parentRoot[:] + + for i := uint64(0); i < 10; i++ { + block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) + } + + signedBlock, err := blocks.NewSignedBeaconBlock(block) + require.NoError(t, err) + + h, err := signedBlock.Header() + require.NoError(t, err) + + err = st.SetLatestBlockHeader(h.Header) + require.NoError(t, err) + stateRoot, err := st.HashTreeRoot(ctx) + require.NoError(t, err) + + // get a new signed block so the root is updated with the new state root + block.Block.StateRoot = stateRoot[:] + signedBlock, err = blocks.NewSignedBeaconBlock(block) + require.NoError(t, err) + + root, err := block.Block.HashTreeRoot() + require.NoError(t, err) + + mockBlocker := &testutil.MockBlocker{ + RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{ + parentRoot: signedParent, + root: signedBlock, + }, + SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{ + slot.Sub(1): signedParent, + slot: signedBlock, + }, + } + mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st, FinalizedRoots: map[[32]byte]bool{ + root: true, + }} + mockChainInfoFetcher := &mock.ChainService{Slot: &slot} + s := &Server{ + Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ + slot.Sub(1): attestedState, + slot: st, + }}, + Blocker: mockBlocker, + HeadFetcher: mockChainService, + ChainInfoFetcher: mockChainInfoFetcher, + } + + minSignaturesRequired := uint64(100) + eventBlock, err := s.suitableBlock(ctx, minSignaturesRequired) + + require.NoError(t, err) + require.NotNil(t, eventBlock) + syncAggregate, err := eventBlock.Block().Body().SyncAggregate() + require.NoError(t, err) + require.Equal(t, true, syncAggregate.SyncCommitteeBits.Count() >= minSignaturesRequired) + require.Equal(t, slot-1, eventBlock.Block().Slot()) +} + // setupDB instantiates and returns a Store instance. func setupDB(t testing.TB) *kv.Store { db, err := kv.NewKVStore(context.Background(), t.TempDir()) @@ -2461,3 +1894,111 @@ func setupDB(t testing.TB) *kv.Store { }) return db } + +func createUpdate(t *testing.T, v int) (interfaces.LightClientUpdate, error) { + params.SetupTestConfigCleanup(t) + config := params.BeaconConfig() + var slot primitives.Slot + var header interfaces.LightClientHeader + var err error + + sampleRoot := make([]byte, 32) + for i := 0; i < 32; i++ { + sampleRoot[i] = byte(i) + } + + sampleExecutionBranch := make([][]byte, 4) + for i := 0; i < 4; i++ { + sampleExecutionBranch[i] = make([]byte, 32) + for j := 0; j < 32; j++ { + sampleExecutionBranch[i][j] = byte(i + j) + } + } + + switch v { + case version.Altair: + slot = primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) + header, err = light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{ + Beacon: &pb.BeaconBlockHeader{ + Slot: 1, + ProposerIndex: primitives.ValidatorIndex(rand.Int()), + ParentRoot: sampleRoot, + StateRoot: sampleRoot, + BodyRoot: sampleRoot, + }, + }) + require.NoError(t, err) + case version.Capella: + slot = primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) + header, err = light_client.NewWrappedHeader(&pb.LightClientHeaderCapella{ + Beacon: &pb.BeaconBlockHeader{ + Slot: 1, + ProposerIndex: primitives.ValidatorIndex(rand.Int()), + ParentRoot: sampleRoot, + StateRoot: sampleRoot, + BodyRoot: sampleRoot, + }, + Execution: &enginev1.ExecutionPayloadHeaderCapella{ + ParentHash: make([]byte, fieldparams.RootLength), + FeeRecipient: make([]byte, fieldparams.FeeRecipientLength), + StateRoot: make([]byte, fieldparams.RootLength), + ReceiptsRoot: make([]byte, fieldparams.RootLength), + LogsBloom: make([]byte, fieldparams.LogsBloomLength), + PrevRandao: make([]byte, fieldparams.RootLength), + ExtraData: make([]byte, 0), + BaseFeePerGas: make([]byte, fieldparams.RootLength), + BlockHash: make([]byte, fieldparams.RootLength), + TransactionsRoot: make([]byte, fieldparams.RootLength), + WithdrawalsRoot: make([]byte, fieldparams.RootLength), + }, + ExecutionBranch: sampleExecutionBranch, + }) + require.NoError(t, err) + case version.Deneb: + slot = primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) + header, err = light_client.NewWrappedHeader(&pb.LightClientHeaderDeneb{ + Beacon: &pb.BeaconBlockHeader{ + Slot: 1, + ProposerIndex: primitives.ValidatorIndex(rand.Int()), + ParentRoot: sampleRoot, + StateRoot: sampleRoot, + BodyRoot: sampleRoot, + }, + Execution: &enginev1.ExecutionPayloadHeaderDeneb{ + ParentHash: make([]byte, fieldparams.RootLength), + FeeRecipient: make([]byte, fieldparams.FeeRecipientLength), + StateRoot: make([]byte, fieldparams.RootLength), + ReceiptsRoot: make([]byte, fieldparams.RootLength), + LogsBloom: make([]byte, fieldparams.LogsBloomLength), + PrevRandao: make([]byte, fieldparams.RootLength), + ExtraData: make([]byte, 0), + BaseFeePerGas: make([]byte, fieldparams.RootLength), + BlockHash: make([]byte, fieldparams.RootLength), + TransactionsRoot: make([]byte, fieldparams.RootLength), + WithdrawalsRoot: make([]byte, fieldparams.RootLength), + }, + ExecutionBranch: sampleExecutionBranch, + }) + require.NoError(t, err) + default: + return nil, fmt.Errorf("unsupported version %v", v) + } + + update, err := lightclient.CreateDefaultLightClientUpdate(slot) + require.NoError(t, err) + update.SetSignatureSlot(slot - 1) + syncCommitteeBits := make([]byte, 64) + syncCommitteeSignature := make([]byte, 96) + update.SetSyncAggregate(&pb.SyncAggregate{ + SyncCommitteeBits: syncCommitteeBits, + SyncCommitteeSignature: syncCommitteeSignature, + }) + + require.NoError(t, err) + err = update.SetAttestedHeader(header) + require.NoError(t, err) + err = update.SetFinalizedHeader(header) + require.NoError(t, err) + + return update, nil +} diff --git a/beacon-chain/rpc/eth/light-client/helpers_test.go b/beacon-chain/rpc/eth/light-client/helpers_test.go index ef1a99f5c87e..8d6e22ae429b 100644 --- a/beacon-chain/rpc/eth/light-client/helpers_test.go +++ b/beacon-chain/rpc/eth/light-client/helpers_test.go @@ -125,7 +125,8 @@ func TestIsBetterUpdate(t *testing.T) { }, }) assert.NoError(t, err) - oldUpdate.SetAttestedHeader(oldAttestedHeader) + err = oldUpdate.SetAttestedHeader(oldAttestedHeader) + assert.NoError(t, err) oldUpdate.SetSignatureSlot(9999) newUpdate.SetSyncAggregate(&pb.SyncAggregate{ @@ -137,7 +138,8 @@ func TestIsBetterUpdate(t *testing.T) { }, }) assert.NoError(t, err) - newUpdate.SetAttestedHeader(newAttestedHeader) + err = newUpdate.SetAttestedHeader(newAttestedHeader) + assert.NoError(t, err) err = newUpdate.SetNextSyncCommitteeBranch(createNonEmptySyncCommitteeBranch()) assert.NoError(t, err) newUpdate.SetSignatureSlot(1000000) @@ -162,7 +164,8 @@ func TestIsBetterUpdate(t *testing.T) { }, }) assert.NoError(t, err) - oldUpdate.SetAttestedHeader(oldAttestedHeader) + err = oldUpdate.SetAttestedHeader(oldAttestedHeader) + assert.NoError(t, err) err = oldUpdate.SetNextSyncCommitteeBranch(createNonEmptySyncCommitteeBranch()) assert.NoError(t, err) oldUpdate.SetSignatureSlot(1000000) @@ -176,7 +179,8 @@ func TestIsBetterUpdate(t *testing.T) { }, }) assert.NoError(t, err) - newUpdate.SetAttestedHeader(newAttestedHeader) + err = newUpdate.SetAttestedHeader(newAttestedHeader) + assert.NoError(t, err) newUpdate.SetSignatureSlot(9999) result, err := IsBetterUpdate(newUpdate, oldUpdate) @@ -199,7 +203,8 @@ func TestIsBetterUpdate(t *testing.T) { }, }) assert.NoError(t, err) - oldUpdate.SetAttestedHeader(oldAttestedHeader) + err = oldUpdate.SetAttestedHeader(oldAttestedHeader) + assert.NoError(t, err) err = oldUpdate.SetNextSyncCommitteeBranch(createNonEmptySyncCommitteeBranch()) assert.NoError(t, err) oldUpdate.SetSignatureSlot(9999) @@ -213,7 +218,8 @@ func TestIsBetterUpdate(t *testing.T) { }, }) assert.NoError(t, err) - newUpdate.SetAttestedHeader(newAttestedHeader) + err = newUpdate.SetAttestedHeader(newAttestedHeader) + assert.NoError(t, err) err = newUpdate.SetNextSyncCommitteeBranch(createNonEmptySyncCommitteeBranch()) assert.NoError(t, err) newUpdate.SetSignatureSlot(9999) @@ -240,7 +246,8 @@ func TestIsBetterUpdate(t *testing.T) { }, }) assert.NoError(t, err) - oldUpdate.SetAttestedHeader(oldAttestedHeader) + err = oldUpdate.SetAttestedHeader(oldAttestedHeader) + assert.NoError(t, err) err = oldUpdate.SetNextSyncCommitteeBranch(createNonEmptySyncCommitteeBranch()) assert.NoError(t, err) oldUpdate.SetSignatureSlot(9999) @@ -256,7 +263,8 @@ func TestIsBetterUpdate(t *testing.T) { }, }) assert.NoError(t, err) - newUpdate.SetAttestedHeader(newAttestedHeader) + err = newUpdate.SetAttestedHeader(newAttestedHeader) + assert.NoError(t, err) err = newUpdate.SetNextSyncCommitteeBranch(createNonEmptySyncCommitteeBranch()) assert.NoError(t, err) newUpdate.SetSignatureSlot(9999) @@ -281,7 +289,8 @@ func TestIsBetterUpdate(t *testing.T) { }, }) assert.NoError(t, err) - oldUpdate.SetAttestedHeader(oldAttestedHeader) + err = oldUpdate.SetAttestedHeader(oldAttestedHeader) + assert.NoError(t, err) err = oldUpdate.SetNextSyncCommitteeBranch(createNonEmptySyncCommitteeBranch()) assert.NoError(t, err) err = oldUpdate.SetFinalityBranch(createNonEmptyFinalityBranch()) @@ -293,7 +302,8 @@ func TestIsBetterUpdate(t *testing.T) { }, }) assert.NoError(t, err) - oldUpdate.SetFinalizedHeader(oldFinalizedHeader) + err = oldUpdate.SetFinalizedHeader(oldFinalizedHeader) + assert.NoError(t, err) newUpdate.SetSyncAggregate(&pb.SyncAggregate{ SyncCommitteeBits: []byte{0b01111100, 0b1}, // [0,0,1,1,1,1,1,0] @@ -304,7 +314,8 @@ func TestIsBetterUpdate(t *testing.T) { }, }) assert.NoError(t, err) - newUpdate.SetAttestedHeader(newAttestedHeader) + err = newUpdate.SetAttestedHeader(newAttestedHeader) + assert.NoError(t, err) err = newUpdate.SetNextSyncCommitteeBranch(createNonEmptySyncCommitteeBranch()) assert.NoError(t, err) newUpdate.SetSignatureSlot(999999) @@ -316,7 +327,8 @@ func TestIsBetterUpdate(t *testing.T) { }, }) assert.NoError(t, err) - newUpdate.SetFinalizedHeader(newFinalizedHeader) + err = newUpdate.SetFinalizedHeader(newFinalizedHeader) + assert.NoError(t, err) result, err := IsBetterUpdate(newUpdate, oldUpdate) assert.NoError(t, err) @@ -338,7 +350,8 @@ func TestIsBetterUpdate(t *testing.T) { }, }) assert.NoError(t, err) - oldUpdate.SetAttestedHeader(oldAttestedHeader) + err = oldUpdate.SetAttestedHeader(oldAttestedHeader) + assert.NoError(t, err) err = oldUpdate.SetNextSyncCommitteeBranch(createNonEmptySyncCommitteeBranch()) assert.NoError(t, err) err = oldUpdate.SetFinalityBranch(createNonEmptyFinalityBranch()) @@ -350,7 +363,8 @@ func TestIsBetterUpdate(t *testing.T) { }, }) assert.NoError(t, err) - oldUpdate.SetFinalizedHeader(oldFinalizedHeader) + err = oldUpdate.SetFinalizedHeader(oldFinalizedHeader) + assert.NoError(t, err) newUpdate.SetSyncAggregate(&pb.SyncAggregate{ SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0] @@ -361,7 +375,8 @@ func TestIsBetterUpdate(t *testing.T) { }, }) assert.NoError(t, err) - newUpdate.SetAttestedHeader(newAttestedHeader) + err = newUpdate.SetAttestedHeader(newAttestedHeader) + assert.NoError(t, err) err = newUpdate.SetNextSyncCommitteeBranch(createNonEmptySyncCommitteeBranch()) assert.NoError(t, err) newUpdate.SetSignatureSlot(9999) @@ -373,7 +388,8 @@ func TestIsBetterUpdate(t *testing.T) { }, }) assert.NoError(t, err) - newUpdate.SetFinalizedHeader(newFinalizedHeader) + err = newUpdate.SetFinalizedHeader(newFinalizedHeader) + assert.NoError(t, err) result, err := IsBetterUpdate(newUpdate, oldUpdate) assert.NoError(t, err) @@ -431,7 +447,8 @@ func TestIsBetterUpdate(t *testing.T) { }, }) assert.NoError(t, err) - oldUpdate.SetAttestedHeader(oldAttestedHeader) + err = oldUpdate.SetAttestedHeader(oldAttestedHeader) + assert.NoError(t, err) err = oldUpdate.SetNextSyncCommitteeBranch(createNonEmptySyncCommitteeBranch()) assert.NoError(t, err) err = oldUpdate.SetFinalityBranch(createNonEmptyFinalityBranch()) @@ -443,7 +460,8 @@ func TestIsBetterUpdate(t *testing.T) { }, }) assert.NoError(t, err) - oldUpdate.SetFinalizedHeader(oldFinalizedHeader) + err = oldUpdate.SetFinalizedHeader(oldFinalizedHeader) + assert.NoError(t, err) newUpdate.SetSyncAggregate(&pb.SyncAggregate{ SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0] @@ -454,7 +472,8 @@ func TestIsBetterUpdate(t *testing.T) { }, }) assert.NoError(t, err) - newUpdate.SetAttestedHeader(newAttestedHeader) + err = newUpdate.SetAttestedHeader(newAttestedHeader) + assert.NoError(t, err) err = newUpdate.SetNextSyncCommitteeBranch(createNonEmptySyncCommitteeBranch()) assert.NoError(t, err) newUpdate.SetSignatureSlot(9999) @@ -466,7 +485,8 @@ func TestIsBetterUpdate(t *testing.T) { }, }) assert.NoError(t, err) - newUpdate.SetFinalizedHeader(newFinalizedHeader) + err = newUpdate.SetFinalizedHeader(newFinalizedHeader) + assert.NoError(t, err) result, err := IsBetterUpdate(newUpdate, oldUpdate) assert.NoError(t, err) @@ -488,7 +508,8 @@ func TestIsBetterUpdate(t *testing.T) { }, }) assert.NoError(t, err) - oldUpdate.SetAttestedHeader(oldAttestedHeader) + err = oldUpdate.SetAttestedHeader(oldAttestedHeader) + assert.NoError(t, err) err = oldUpdate.SetNextSyncCommitteeBranch(createNonEmptySyncCommitteeBranch()) assert.NoError(t, err) err = oldUpdate.SetFinalityBranch(createNonEmptyFinalityBranch()) @@ -500,7 +521,8 @@ func TestIsBetterUpdate(t *testing.T) { }, }) assert.NoError(t, err) - oldUpdate.SetFinalizedHeader(oldFinalizedHeader) + err = oldUpdate.SetFinalizedHeader(oldFinalizedHeader) + assert.NoError(t, err) newUpdate.SetSyncAggregate(&pb.SyncAggregate{ SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0] @@ -511,7 +533,8 @@ func TestIsBetterUpdate(t *testing.T) { }, }) assert.NoError(t, err) - newUpdate.SetAttestedHeader(newAttestedHeader) + err = newUpdate.SetAttestedHeader(newAttestedHeader) + assert.NoError(t, err) err = newUpdate.SetNextSyncCommitteeBranch(createNonEmptySyncCommitteeBranch()) assert.NoError(t, err) newUpdate.SetSignatureSlot(9999) @@ -523,7 +546,8 @@ func TestIsBetterUpdate(t *testing.T) { }, }) assert.NoError(t, err) - newUpdate.SetFinalizedHeader(newFinalizedHeader) + err = newUpdate.SetFinalizedHeader(newFinalizedHeader) + assert.NoError(t, err) result, err := IsBetterUpdate(newUpdate, oldUpdate) assert.NoError(t, err) @@ -545,7 +569,8 @@ func TestIsBetterUpdate(t *testing.T) { }, }) assert.NoError(t, err) - oldUpdate.SetAttestedHeader(oldAttestedHeader) + err = oldUpdate.SetAttestedHeader(oldAttestedHeader) + assert.NoError(t, err) err = oldUpdate.SetNextSyncCommitteeBranch(createNonEmptySyncCommitteeBranch()) assert.NoError(t, err) err = oldUpdate.SetFinalityBranch(createNonEmptyFinalityBranch()) @@ -557,7 +582,8 @@ func TestIsBetterUpdate(t *testing.T) { }, }) assert.NoError(t, err) - oldUpdate.SetFinalizedHeader(oldFinalizedHeader) + err = oldUpdate.SetFinalizedHeader(oldFinalizedHeader) + assert.NoError(t, err) newUpdate.SetSyncAggregate(&pb.SyncAggregate{ SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0] @@ -568,7 +594,8 @@ func TestIsBetterUpdate(t *testing.T) { }, }) assert.NoError(t, err) - newUpdate.SetAttestedHeader(newAttestedHeader) + err = newUpdate.SetAttestedHeader(newAttestedHeader) + assert.NoError(t, err) err = newUpdate.SetNextSyncCommitteeBranch(createNonEmptySyncCommitteeBranch()) assert.NoError(t, err) newUpdate.SetSignatureSlot(9998) @@ -580,7 +607,8 @@ func TestIsBetterUpdate(t *testing.T) { }, }) assert.NoError(t, err) - newUpdate.SetFinalizedHeader(newFinalizedHeader) + err = newUpdate.SetFinalizedHeader(newFinalizedHeader) + assert.NoError(t, err) result, err := IsBetterUpdate(newUpdate, oldUpdate) assert.NoError(t, err) @@ -602,7 +630,8 @@ func TestIsBetterUpdate(t *testing.T) { }, }) assert.NoError(t, err) - oldUpdate.SetAttestedHeader(oldAttestedHeader) + err = oldUpdate.SetAttestedHeader(oldAttestedHeader) + assert.NoError(t, err) err = oldUpdate.SetNextSyncCommitteeBranch(createNonEmptySyncCommitteeBranch()) assert.NoError(t, err) err = oldUpdate.SetFinalityBranch(createNonEmptyFinalityBranch()) @@ -614,7 +643,8 @@ func TestIsBetterUpdate(t *testing.T) { }, }) assert.NoError(t, err) - oldUpdate.SetFinalizedHeader(oldFinalizedHeader) + err = oldUpdate.SetFinalizedHeader(oldFinalizedHeader) + assert.NoError(t, err) newUpdate.SetSyncAggregate(&pb.SyncAggregate{ SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0] @@ -625,7 +655,8 @@ func TestIsBetterUpdate(t *testing.T) { }, }) assert.NoError(t, err) - newUpdate.SetAttestedHeader(newAttestedHeader) + err = newUpdate.SetAttestedHeader(newAttestedHeader) + assert.NoError(t, err) err = newUpdate.SetNextSyncCommitteeBranch(createNonEmptySyncCommitteeBranch()) assert.NoError(t, err) newUpdate.SetSignatureSlot(9999) @@ -637,7 +668,8 @@ func TestIsBetterUpdate(t *testing.T) { }, }) assert.NoError(t, err) - newUpdate.SetFinalizedHeader(newFinalizedHeader) + err = newUpdate.SetFinalizedHeader(newFinalizedHeader) + assert.NoError(t, err) result, err := IsBetterUpdate(newUpdate, oldUpdate) assert.NoError(t, err) From 59e9acd80d4b5f97a96170a172a3b0c5aa678b0a Mon Sep 17 00:00:00 2001 From: Inspector-Butters Date: Fri, 25 Oct 2024 22:35:38 +0200 Subject: [PATCH 29/35] remove unused function --- beacon-chain/rpc/eth/light-client/helpers.go | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/beacon-chain/rpc/eth/light-client/helpers.go b/beacon-chain/rpc/eth/light-client/helpers.go index f1f6cbdf7af1..4f6dee400b34 100644 --- a/beacon-chain/rpc/eth/light-client/helpers.go +++ b/beacon-chain/rpc/eth/light-client/helpers.go @@ -99,23 +99,6 @@ func createLightClientBootstrap( return result, nil } -func newLightClientUpdateFromBeaconState( - ctx context.Context, - currentSlot primitives.Slot, - state state.BeaconState, - block interfaces.ReadOnlySignedBeaconBlock, - attestedState state.BeaconState, - attestedBlock interfaces.ReadOnlySignedBeaconBlock, - finalizedBlock interfaces.ReadOnlySignedBeaconBlock, -) (*structs.LightClientUpdate, error) { - result, err := lightclient.NewLightClientUpdateFromBeaconState(ctx, currentSlot, state, block, attestedState, attestedBlock, finalizedBlock) - if err != nil { - return nil, err - } - - return structs.LightClientUpdateFromConsensus(result) -} - func newLightClientFinalityUpdateFromBeaconState( ctx context.Context, currentSlot primitives.Slot, From 03fd48cc4aa7f85fe96fe92624aff15ae09b71b2 Mon Sep 17 00:00:00 2001 From: Inspector-Butters Date: Sat, 26 Oct 2024 00:16:59 +0200 Subject: [PATCH 30/35] fix slice capacity --- beacon-chain/db/kv/lightclient_test.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/beacon-chain/db/kv/lightclient_test.go b/beacon-chain/db/kv/lightclient_test.go index 417d9312f78a..eaa361f4c29c 100644 --- a/beacon-chain/db/kv/lightclient_test.go +++ b/beacon-chain/db/kv/lightclient_test.go @@ -173,7 +173,7 @@ func TestStore_LightClientUpdate_CanSaveRetrieveDeneb(t *testing.T) { func TestStore_LightClientUpdates_canRetrieveRange(t *testing.T) { db := setupDB(t) ctx := context.Background() - updates := make([]interfaces.LightClientUpdate, 0) + updates := make([]interfaces.LightClientUpdate, 0, 3) for i := 1; i <= 3; i++ { update, err := createUpdate(t, version.Altair) require.NoError(t, err) @@ -198,7 +198,7 @@ func TestStore_LightClientUpdates_canRetrieveRange(t *testing.T) { func TestStore_LightClientUpdate_EndPeriodSmallerThanStartPeriod(t *testing.T) { db := setupDB(t) ctx := context.Background() - updates := make([]interfaces.LightClientUpdate, 0) + updates := make([]interfaces.LightClientUpdate, 0, 3) for i := 1; i <= 3; i++ { update, err := createUpdate(t, version.Altair) require.NoError(t, err) @@ -221,7 +221,7 @@ func TestStore_LightClientUpdate_EndPeriodSmallerThanStartPeriod(t *testing.T) { func TestStore_LightClientUpdate_EndPeriodEqualToStartPeriod(t *testing.T) { db := setupDB(t) ctx := context.Background() - updates := make([]interfaces.LightClientUpdate, 0) + updates := make([]interfaces.LightClientUpdate, 0, 3) for i := 1; i <= 3; i++ { update, err := createUpdate(t, version.Altair) require.NoError(t, err) @@ -243,7 +243,7 @@ func TestStore_LightClientUpdate_EndPeriodEqualToStartPeriod(t *testing.T) { func TestStore_LightClientUpdate_StartPeriodBeforeFirstUpdate(t *testing.T) { db := setupDB(t) ctx := context.Background() - updates := make([]interfaces.LightClientUpdate, 0) + updates := make([]interfaces.LightClientUpdate, 0, 3) for i := 1; i <= 3; i++ { update, err := createUpdate(t, version.Altair) require.NoError(t, err) @@ -267,7 +267,7 @@ func TestStore_LightClientUpdate_StartPeriodBeforeFirstUpdate(t *testing.T) { func TestStore_LightClientUpdate_EndPeriodAfterLastUpdate(t *testing.T) { db := setupDB(t) ctx := context.Background() - updates := make([]interfaces.LightClientUpdate, 0) + updates := make([]interfaces.LightClientUpdate, 0, 3) for i := 1; i <= 3; i++ { update, err := createUpdate(t, version.Altair) require.NoError(t, err) @@ -291,7 +291,7 @@ func TestStore_LightClientUpdate_EndPeriodAfterLastUpdate(t *testing.T) { func TestStore_LightClientUpdate_PartialUpdates(t *testing.T) { db := setupDB(t) ctx := context.Background() - updates := make([]interfaces.LightClientUpdate, 0) + updates := make([]interfaces.LightClientUpdate, 0, 3) for i := 1; i <= 3; i++ { update, err := createUpdate(t, version.Altair) require.NoError(t, err) @@ -315,7 +315,7 @@ func TestStore_LightClientUpdate_PartialUpdates(t *testing.T) { func TestStore_LightClientUpdate_MissingPeriods_SimpleData(t *testing.T) { db := setupDB(t) ctx := context.Background() - updates := make([]interfaces.LightClientUpdate, 0) + updates := make([]interfaces.LightClientUpdate, 0, 4) for i := 1; i <= 4; i++ { update, err := createUpdate(t, version.Altair) require.NoError(t, err) @@ -370,7 +370,7 @@ func TestStore_LightClientUpdate_EmptyDB(t *testing.T) { func TestStore_LightClientUpdate_RetrieveMissingPeriodDistributed(t *testing.T) { db := setupDB(t) ctx := context.Background() - updates := make([]interfaces.LightClientUpdate, 0) + updates := make([]interfaces.LightClientUpdate, 0, 5) for i := 1; i <= 5; i++ { update, err := createUpdate(t, version.Altair) require.NoError(t, err) From df616fbb237f622ab77681f332108b60003d2247 Mon Sep 17 00:00:00 2001 From: Inspector-Butters Date: Mon, 28 Oct 2024 12:28:46 +0100 Subject: [PATCH 31/35] address issues --- beacon-chain/core/light-client/lightclient.go | 4 +- beacon-chain/db/kv/lightclient_test.go | 52 ++++++++++++++++--- 2 files changed, 47 insertions(+), 9 deletions(-) diff --git a/beacon-chain/core/light-client/lightclient.go b/beacon-chain/core/light-client/lightclient.go index 4cce693c9ec0..f8df29ba6b6c 100644 --- a/beacon-chain/core/light-client/lightclient.go +++ b/beacon-chain/core/light-client/lightclient.go @@ -278,7 +278,9 @@ func CreateDefaultLightClientUpdate(currentSlot primitives.Slot) (interfaces.Lig var m proto.Message if currentEpoch < params.BeaconConfig().CapellaForkEpoch { m = &pb.LightClientUpdateAltair{ - AttestedHeader: &pb.LightClientHeaderAltair{}, + AttestedHeader: &pb.LightClientHeaderAltair{ + Beacon: &pb.BeaconBlockHeader{}, + }, NextSyncCommittee: nextSyncCommittee, NextSyncCommitteeBranch: nextSyncCommitteeBranch, FinalityBranch: finalityBranch, diff --git a/beacon-chain/db/kv/lightclient_test.go b/beacon-chain/db/kv/lightclient_test.go index eaa361f4c29c..fc20d8c27a01 100644 --- a/beacon-chain/db/kv/lightclient_test.go +++ b/beacon-chain/db/kv/lightclient_test.go @@ -20,7 +20,6 @@ import ( ) func createUpdate(t *testing.T, v int) (interfaces.LightClientUpdate, error) { - params.SetupTestConfigCleanup(t) config := params.BeaconConfig() var slot primitives.Slot var header interfaces.LightClientHeader @@ -31,7 +30,7 @@ func createUpdate(t *testing.T, v int) (interfaces.LightClientUpdate, error) { sampleRoot[i] = byte(i) } - sampleExecutionBranch := make([][]byte, 4) + sampleExecutionBranch := make([][]byte, fieldparams.ExecutionBranchDepth) for i := 0; i < 4; i++ { sampleExecutionBranch[i] = make([]byte, 32) for j := 0; j < 32; j++ { @@ -104,8 +103,34 @@ func createUpdate(t *testing.T, v int) (interfaces.LightClientUpdate, error) { ExecutionBranch: sampleExecutionBranch, }) require.NoError(t, err) + case version.Electra: + slot = primitives.Slot(config.ElectraForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) + header, err = light_client.NewWrappedHeader(&pb.LightClientHeaderDeneb{ + Beacon: &pb.BeaconBlockHeader{ + Slot: 1, + ProposerIndex: primitives.ValidatorIndex(rand.Int()), + ParentRoot: sampleRoot, + StateRoot: sampleRoot, + BodyRoot: sampleRoot, + }, + Execution: &enginev1.ExecutionPayloadHeaderElectra{ + ParentHash: make([]byte, fieldparams.RootLength), + FeeRecipient: make([]byte, fieldparams.FeeRecipientLength), + StateRoot: make([]byte, fieldparams.RootLength), + ReceiptsRoot: make([]byte, fieldparams.RootLength), + LogsBloom: make([]byte, fieldparams.LogsBloomLength), + PrevRandao: make([]byte, fieldparams.RootLength), + ExtraData: make([]byte, 0), + BaseFeePerGas: make([]byte, fieldparams.RootLength), + BlockHash: make([]byte, fieldparams.RootLength), + TransactionsRoot: make([]byte, fieldparams.RootLength), + WithdrawalsRoot: make([]byte, fieldparams.RootLength), + }, + ExecutionBranch: sampleExecutionBranch, + }) + require.NoError(t, err) default: - return nil, fmt.Errorf("unsupported version %v", v) + return nil, fmt.Errorf("unsupported version %s", version.String(v)) } update, err := createDefaultLightClientUpdate(slot) @@ -118,11 +143,8 @@ func createUpdate(t *testing.T, v int) (interfaces.LightClientUpdate, error) { SyncCommitteeSignature: syncCommitteeSignature, }) - require.NoError(t, err) - err = update.SetAttestedHeader(header) - require.NoError(t, err) - err = update.SetFinalizedHeader(header) - require.NoError(t, err) + require.NoError(t, update.SetAttestedHeader(header)) + require.NoError(t, update.SetFinalizedHeader(header)) return update, nil } @@ -170,6 +192,20 @@ func TestStore_LightClientUpdate_CanSaveRetrieveDeneb(t *testing.T) { require.DeepEqual(t, update, retrievedUpdate, "retrieved update does not match saved update") } +func TestStore_LightClientUpdate_CanSaveRetrieveElectra(t *testing.T) { + db := setupDB(t) + ctx := context.Background() + update, err := createUpdate(t, version.Electra) + require.NoError(t, err) + period := uint64(1) + err = db.SaveLightClientUpdate(ctx, period, update) + require.NoError(t, err) + + retrievedUpdate, err := db.LightClientUpdate(ctx, period) + require.NoError(t, err) + require.DeepEqual(t, update, retrievedUpdate, "retrieved update does not match saved update") +} + func TestStore_LightClientUpdates_canRetrieveRange(t *testing.T) { db := setupDB(t) ctx := context.Background() From 70d021b52f5d75b4632b4bb96474bb7fcb978154 Mon Sep 17 00:00:00 2001 From: Inspector-Butters Date: Mon, 28 Oct 2024 12:55:31 +0100 Subject: [PATCH 32/35] address issues --- beacon-chain/rpc/eth/light-client/BUILD.bazel | 2 +- .../rpc/eth/light-client/handlers_test.go | 201 +++--------------- .../rpc/eth/light-client/helpers_test.go | 1 - testing/util/BUILD.bazel | 2 + testing/util/lightclient.go | 134 ++++++++++++ 5 files changed, 172 insertions(+), 168 deletions(-) diff --git a/beacon-chain/rpc/eth/light-client/BUILD.bazel b/beacon-chain/rpc/eth/light-client/BUILD.bazel index 94e29dc6f9d7..f4bf65404a28 100644 --- a/beacon-chain/rpc/eth/light-client/BUILD.bazel +++ b/beacon-chain/rpc/eth/light-client/BUILD.bazel @@ -44,7 +44,7 @@ go_test( "//beacon-chain/blockchain/testing:go_default_library", "//beacon-chain/core/helpers:go_default_library", "//beacon-chain/core/light-client:go_default_library", - "//beacon-chain/db/kv:go_default_library", + "//beacon-chain/db/testing:go_default_library", "//beacon-chain/rpc/testutil:go_default_library", "//beacon-chain/state:go_default_library", "//config/fieldparams:go_default_library", diff --git a/beacon-chain/rpc/eth/light-client/handlers_test.go b/beacon-chain/rpc/eth/light-client/handlers_test.go index 059fc8f25181..4b843e915c2f 100644 --- a/beacon-chain/rpc/eth/light-client/handlers_test.go +++ b/beacon-chain/rpc/eth/light-client/handlers_test.go @@ -5,7 +5,6 @@ import ( "context" "encoding/json" "fmt" - "math/rand" "net/http" "net/http/httptest" "strconv" @@ -15,17 +14,13 @@ import ( "github.com/prysmaticlabs/prysm/v5/api/server/structs" mock "github.com/prysmaticlabs/prysm/v5/beacon-chain/blockchain/testing" "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/helpers" - lightclient "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/light-client" - "github.com/prysmaticlabs/prysm/v5/beacon-chain/db/kv" + dbtesting "github.com/prysmaticlabs/prysm/v5/beacon-chain/db/testing" "github.com/prysmaticlabs/prysm/v5/beacon-chain/rpc/testutil" "github.com/prysmaticlabs/prysm/v5/beacon-chain/state" - fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams" "github.com/prysmaticlabs/prysm/v5/config/params" "github.com/prysmaticlabs/prysm/v5/consensus-types/blocks" "github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces" - light_client "github.com/prysmaticlabs/prysm/v5/consensus-types/light-client" "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" - enginev1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1" pb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" "github.com/prysmaticlabs/prysm/v5/runtime/version" "github.com/prysmaticlabs/prysm/v5/testing/require" @@ -260,11 +255,11 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeAltair(t *testing.T) { err = st.SetSlot(slot) require.NoError(t, err) - db := setupDB(t) + db := dbtesting.SetupDB(t) updatePeriod := uint64(slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch))) - update, err := createUpdate(t, version.Altair) + update, err := util.CreateTestingUpdate(t, version.Altair) require.NoError(t, err) err = db.SaveLightClientUpdate(ctx, updatePeriod, update) require.NoError(t, err) @@ -308,11 +303,11 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeCapella(t *testing.T) { err = st.SetSlot(slot) require.NoError(t, err) - db := setupDB(t) + db := dbtesting.SetupDB(t) updatePeriod := uint64(slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch))) - update, err := createUpdate(t, version.Capella) + update, err := util.CreateTestingUpdate(t, version.Capella) require.NoError(t, err) err = db.SaveLightClientUpdate(ctx, updatePeriod, update) @@ -358,11 +353,11 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeDeneb(t *testing.T) { err = st.SetSlot(slot) require.NoError(t, err) - db := setupDB(t) + db := dbtesting.SetupDB(t) updatePeriod := uint64(slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch))) - update, err := createUpdate(t, version.Deneb) + update, err := util.CreateTestingUpdate(t, version.Deneb) require.NoError(t, err) err = db.SaveLightClientUpdate(ctx, updatePeriod, update) require.NoError(t, err) @@ -403,17 +398,17 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleAltair(t *testin st, err := util.NewBeaconStateAltair() require.NoError(t, err) - headSlot := slot.Add(33) // 2 periods + headSlot := slot.Add(2 * uint64(config.SlotsPerEpoch) * uint64(config.EpochsPerSyncCommitteePeriod)) // 2 periods err = st.SetSlot(headSlot) require.NoError(t, err) - db := setupDB(t) + db := dbtesting.SetupDB(t) updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) updates := make([]interfaces.LightClientUpdate, 0) for i := 1; i <= 2; i++ { - update, err := createUpdate(t, version.Altair) + update, err := util.CreateTestingUpdate(t, version.Altair) require.NoError(t, err) updates = append(updates, update) } @@ -463,17 +458,17 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleCapella(t *testi st, err := util.NewBeaconStateAltair() require.NoError(t, err) - headSlot := slot.Add(33) // 2 periods + headSlot := slot.Add(2 * uint64(config.SlotsPerEpoch) * uint64(config.EpochsPerSyncCommitteePeriod)) // 2 periods err = st.SetSlot(headSlot) require.NoError(t, err) - db := setupDB(t) + db := dbtesting.SetupDB(t) updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) updates := make([]interfaces.LightClientUpdate, 0) for i := 0; i < 2; i++ { - update, err := createUpdate(t, version.Capella) + update, err := util.CreateTestingUpdate(t, version.Capella) require.NoError(t, err) updates = append(updates, update) } @@ -524,17 +519,17 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleDeneb(t *testing st, err := util.NewBeaconStateAltair() require.NoError(t, err) - headSlot := slot.Add(33) + headSlot := slot.Add(2 * uint64(config.SlotsPerEpoch) * uint64(config.EpochsPerSyncCommitteePeriod)) err = st.SetSlot(headSlot) require.NoError(t, err) - db := setupDB(t) + db := dbtesting.SetupDB(t) updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) updates := make([]interfaces.LightClientUpdate, 0) for i := 0; i < 2; i++ { - update, err := createUpdate(t, version.Deneb) + update, err := util.CreateTestingUpdate(t, version.Deneb) require.NoError(t, err) updates = append(updates, update) } @@ -588,13 +583,13 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleForksAltairCapel err = st.SetSlot(headSlot) require.NoError(t, err) - db := setupDB(t) + db := dbtesting.SetupDB(t) updates := make([]interfaces.LightClientUpdate, 2) updatePeriod := slotAltair.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - updates[0], err = createUpdate(t, version.Altair) + updates[0], err = util.CreateTestingUpdate(t, version.Altair) require.NoError(t, err) err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), updates[0]) @@ -602,7 +597,7 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleForksAltairCapel updatePeriod = slotCapella.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - updates[1], err = createUpdate(t, version.Capella) + updates[1], err = util.CreateTestingUpdate(t, version.Capella) require.NoError(t, err) err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), updates[1]) @@ -657,13 +652,13 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleForksCapellaDene err = st.SetSlot(headSlot) require.NoError(t, err) - db := setupDB(t) + db := dbtesting.SetupDB(t) updates := make([]interfaces.LightClientUpdate, 2) updatePeriod := slotCapella.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - updates[0], err = createUpdate(t, version.Capella) + updates[0], err = util.CreateTestingUpdate(t, version.Capella) require.NoError(t, err) err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), updates[0]) @@ -671,7 +666,7 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleForksCapellaDene updatePeriod = slotDeneb.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - updates[1], err = createUpdate(t, version.Deneb) + updates[1], err = util.CreateTestingUpdate(t, version.Deneb) require.NoError(t, err) err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), updates[1]) @@ -720,11 +715,11 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeCountBiggerThanLimit(t * st, err := util.NewBeaconStateAltair() require.NoError(t, err) - headSlot := slot.Add(65) + headSlot := slot.Add(4 * uint64(config.SlotsPerEpoch) * uint64(config.EpochsPerSyncCommitteePeriod)) // 4 periods err = st.SetSlot(headSlot) require.NoError(t, err) - db := setupDB(t) + db := dbtesting.SetupDB(t) updates := make([]interfaces.LightClientUpdate, 3) @@ -732,7 +727,7 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeCountBiggerThanLimit(t * for i := 0; i < 3; i++ { - updates[i], err = createUpdate(t, version.Altair) + updates[i], err = util.CreateTestingUpdate(t, version.Altair) require.NoError(t, err) err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), updates[i]) @@ -782,18 +777,18 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeCountBiggerThanMax(t *te st, err := util.NewBeaconStateAltair() require.NoError(t, err) - headSlot := slot.Add(65) + headSlot := slot.Add(4 * uint64(config.SlotsPerEpoch) * uint64(config.EpochsPerSyncCommitteePeriod)) // 4 periods err = st.SetSlot(headSlot) require.NoError(t, err) - db := setupDB(t) + db := dbtesting.SetupDB(t) updates := make([]interfaces.LightClientUpdate, 3) updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) for i := 0; i < 3; i++ { - updates[i], err = createUpdate(t, version.Altair) + updates[i], err = util.CreateTestingUpdate(t, version.Altair) require.NoError(t, err) err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), updates[i]) @@ -846,11 +841,11 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeStartPeriodBeforeAltair( err = st.SetSlot(headSlot) require.NoError(t, err) - db := setupDB(t) + db := dbtesting.SetupDB(t) updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - update, err := createUpdate(t, version.Altair) + update, err := util.CreateTestingUpdate(t, version.Altair) require.NoError(t, err) err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), update) @@ -894,12 +889,12 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeMissingUpdates(t *testin st, err := util.NewBeaconStateAltair() require.NoError(t, err) - headSlot := slot.Add(65) + headSlot := slot.Add(4 * uint64(config.SlotsPerEpoch) * uint64(config.EpochsPerSyncCommitteePeriod)) // 4 periods err = st.SetSlot(headSlot) require.NoError(t, err) t.Run("missing update in the middle", func(t *testing.T) { - db := setupDB(t) + db := dbtesting.SetupDB(t) updates := make([]interfaces.LightClientUpdate, 3) @@ -911,7 +906,7 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeMissingUpdates(t *testin continue } - updates[i], err = createUpdate(t, version.Altair) + updates[i], err = util.CreateTestingUpdate(t, version.Altair) require.NoError(t, err) err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), updates[i]) @@ -945,7 +940,7 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeMissingUpdates(t *testin }) t.Run("missing update at the beginning", func(t *testing.T) { - db := setupDB(t) + db := dbtesting.SetupDB(t) updates := make([]interfaces.LightClientUpdate, 3) @@ -957,7 +952,7 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeMissingUpdates(t *testin continue } - updates[i], err = createUpdate(t, version.Altair) + updates[i], err = util.CreateTestingUpdate(t, version.Altair) require.NoError(t, err) err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), updates[i]) @@ -993,7 +988,6 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeMissingUpdates(t *testin func TestLightClientHandler_GetLightClientFinalityUpdateAltair(t *testing.T) { helpers.ClearCache() ctx := context.Background() - params.SetupTestConfigCleanup(t) config := params.BeaconConfig() slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) @@ -1106,7 +1100,6 @@ func TestLightClientHandler_GetLightClientFinalityUpdateAltair(t *testing.T) { func TestLightClientHandler_GetLightClientFinalityUpdateCapella(t *testing.T) { helpers.ClearCache() ctx := context.Background() - params.SetupTestConfigCleanup(t) config := params.BeaconConfig() slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) @@ -1219,7 +1212,6 @@ func TestLightClientHandler_GetLightClientFinalityUpdateCapella(t *testing.T) { func TestLightClientHandler_GetLightClientFinalityUpdateDeneb(t *testing.T) { helpers.ClearCache() ctx := context.Background() - params.SetupTestConfigCleanup(t) config := params.BeaconConfig() slot := primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) @@ -1332,7 +1324,6 @@ func TestLightClientHandler_GetLightClientFinalityUpdateDeneb(t *testing.T) { func TestLightClientHandler_GetLightClientOptimisticUpdateAltair(t *testing.T) { helpers.ClearCache() ctx := context.Background() - params.SetupTestConfigCleanup(t) config := params.BeaconConfig() slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) @@ -1445,7 +1436,6 @@ func TestLightClientHandler_GetLightClientOptimisticUpdateAltair(t *testing.T) { func TestLightClientHandler_GetLightClientOptimisticUpdateCapella(t *testing.T) { helpers.ClearCache() ctx := context.Background() - params.SetupTestConfigCleanup(t) config := params.BeaconConfig() slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) @@ -1558,7 +1548,6 @@ func TestLightClientHandler_GetLightClientOptimisticUpdateCapella(t *testing.T) func TestLightClientHandler_GetLightClientOptimisticUpdateDeneb(t *testing.T) { helpers.ClearCache() ctx := context.Background() - params.SetupTestConfigCleanup(t) config := params.BeaconConfig() slot := primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) @@ -1671,7 +1660,6 @@ func TestLightClientHandler_GetLightClientOptimisticUpdateDeneb(t *testing.T) { func TestLightClientHandler_GetLightClientEventBlock(t *testing.T) { helpers.ClearCache() ctx := context.Background() - params.SetupTestConfigCleanup(t) config := params.BeaconConfig() slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) @@ -1778,7 +1766,6 @@ func TestLightClientHandler_GetLightClientEventBlock(t *testing.T) { func TestLightClientHandler_GetLightClientEventBlock_NeedFetchParent(t *testing.T) { helpers.ClearCache() ctx := context.Background() - params.SetupTestConfigCleanup(t) config := params.BeaconConfig() slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) @@ -1884,121 +1871,3 @@ func TestLightClientHandler_GetLightClientEventBlock_NeedFetchParent(t *testing. require.Equal(t, true, syncAggregate.SyncCommitteeBits.Count() >= minSignaturesRequired) require.Equal(t, slot-1, eventBlock.Block().Slot()) } - -// setupDB instantiates and returns a Store instance. -func setupDB(t testing.TB) *kv.Store { - db, err := kv.NewKVStore(context.Background(), t.TempDir()) - require.NoError(t, err, "Failed to instantiate DB") - t.Cleanup(func() { - require.NoError(t, db.Close(), "Failed to close database") - }) - return db -} - -func createUpdate(t *testing.T, v int) (interfaces.LightClientUpdate, error) { - params.SetupTestConfigCleanup(t) - config := params.BeaconConfig() - var slot primitives.Slot - var header interfaces.LightClientHeader - var err error - - sampleRoot := make([]byte, 32) - for i := 0; i < 32; i++ { - sampleRoot[i] = byte(i) - } - - sampleExecutionBranch := make([][]byte, 4) - for i := 0; i < 4; i++ { - sampleExecutionBranch[i] = make([]byte, 32) - for j := 0; j < 32; j++ { - sampleExecutionBranch[i][j] = byte(i + j) - } - } - - switch v { - case version.Altair: - slot = primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) - header, err = light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{ - Beacon: &pb.BeaconBlockHeader{ - Slot: 1, - ProposerIndex: primitives.ValidatorIndex(rand.Int()), - ParentRoot: sampleRoot, - StateRoot: sampleRoot, - BodyRoot: sampleRoot, - }, - }) - require.NoError(t, err) - case version.Capella: - slot = primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) - header, err = light_client.NewWrappedHeader(&pb.LightClientHeaderCapella{ - Beacon: &pb.BeaconBlockHeader{ - Slot: 1, - ProposerIndex: primitives.ValidatorIndex(rand.Int()), - ParentRoot: sampleRoot, - StateRoot: sampleRoot, - BodyRoot: sampleRoot, - }, - Execution: &enginev1.ExecutionPayloadHeaderCapella{ - ParentHash: make([]byte, fieldparams.RootLength), - FeeRecipient: make([]byte, fieldparams.FeeRecipientLength), - StateRoot: make([]byte, fieldparams.RootLength), - ReceiptsRoot: make([]byte, fieldparams.RootLength), - LogsBloom: make([]byte, fieldparams.LogsBloomLength), - PrevRandao: make([]byte, fieldparams.RootLength), - ExtraData: make([]byte, 0), - BaseFeePerGas: make([]byte, fieldparams.RootLength), - BlockHash: make([]byte, fieldparams.RootLength), - TransactionsRoot: make([]byte, fieldparams.RootLength), - WithdrawalsRoot: make([]byte, fieldparams.RootLength), - }, - ExecutionBranch: sampleExecutionBranch, - }) - require.NoError(t, err) - case version.Deneb: - slot = primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) - header, err = light_client.NewWrappedHeader(&pb.LightClientHeaderDeneb{ - Beacon: &pb.BeaconBlockHeader{ - Slot: 1, - ProposerIndex: primitives.ValidatorIndex(rand.Int()), - ParentRoot: sampleRoot, - StateRoot: sampleRoot, - BodyRoot: sampleRoot, - }, - Execution: &enginev1.ExecutionPayloadHeaderDeneb{ - ParentHash: make([]byte, fieldparams.RootLength), - FeeRecipient: make([]byte, fieldparams.FeeRecipientLength), - StateRoot: make([]byte, fieldparams.RootLength), - ReceiptsRoot: make([]byte, fieldparams.RootLength), - LogsBloom: make([]byte, fieldparams.LogsBloomLength), - PrevRandao: make([]byte, fieldparams.RootLength), - ExtraData: make([]byte, 0), - BaseFeePerGas: make([]byte, fieldparams.RootLength), - BlockHash: make([]byte, fieldparams.RootLength), - TransactionsRoot: make([]byte, fieldparams.RootLength), - WithdrawalsRoot: make([]byte, fieldparams.RootLength), - }, - ExecutionBranch: sampleExecutionBranch, - }) - require.NoError(t, err) - default: - return nil, fmt.Errorf("unsupported version %v", v) - } - - update, err := lightclient.CreateDefaultLightClientUpdate(slot) - require.NoError(t, err) - update.SetSignatureSlot(slot - 1) - syncCommitteeBits := make([]byte, 64) - syncCommitteeSignature := make([]byte, 96) - update.SetSyncAggregate(&pb.SyncAggregate{ - SyncCommitteeBits: syncCommitteeBits, - SyncCommitteeSignature: syncCommitteeSignature, - }) - - require.NoError(t, err) - err = update.SetAttestedHeader(header) - require.NoError(t, err) - err = update.SetFinalizedHeader(header) - require.NoError(t, err) - - return update, nil -} diff --git a/beacon-chain/rpc/eth/light-client/helpers_test.go b/beacon-chain/rpc/eth/light-client/helpers_test.go index 8d6e22ae429b..62594af80c3f 100644 --- a/beacon-chain/rpc/eth/light-client/helpers_test.go +++ b/beacon-chain/rpc/eth/light-client/helpers_test.go @@ -35,7 +35,6 @@ func createNonEmptyFinalityBranch() [][]byte { func TestIsBetterUpdate(t *testing.T) { - params.SetupTestConfigCleanup(t) config := params.BeaconConfig() t.Run("new has supermajority but old doesn't", func(t *testing.T) { diff --git a/testing/util/BUILD.bazel b/testing/util/BUILD.bazel index 16154398cf7e..b474d0236027 100644 --- a/testing/util/BUILD.bazel +++ b/testing/util/BUILD.bazel @@ -34,6 +34,7 @@ go_library( "//beacon-chain/core/altair:go_default_library", "//beacon-chain/core/blocks:go_default_library", "//beacon-chain/core/helpers:go_default_library", + "//beacon-chain/core/light-client:go_default_library", "//beacon-chain/core/signing:go_default_library", "//beacon-chain/core/time:go_default_library", "//beacon-chain/core/transition:go_default_library", @@ -47,6 +48,7 @@ go_library( "//consensus-types:go_default_library", "//consensus-types/blocks:go_default_library", "//consensus-types/interfaces:go_default_library", + "//consensus-types/light-client:go_default_library", "//consensus-types/primitives:go_default_library", "//container/trie:go_default_library", "//crypto/bls:go_default_library", diff --git a/testing/util/lightclient.go b/testing/util/lightclient.go index 2edb8390a7aa..261b87d3220c 100644 --- a/testing/util/lightclient.go +++ b/testing/util/lightclient.go @@ -2,15 +2,19 @@ package util import ( "context" + "fmt" + "math/rand" "testing" "github.com/pkg/errors" + lightclientCore "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/light-client" "github.com/prysmaticlabs/prysm/v5/beacon-chain/state" fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams" "github.com/prysmaticlabs/prysm/v5/config/params" consensus_types "github.com/prysmaticlabs/prysm/v5/consensus-types" "github.com/prysmaticlabs/prysm/v5/consensus-types/blocks" "github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces" + light_client "github.com/prysmaticlabs/prysm/v5/consensus-types/light-client" "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" "github.com/prysmaticlabs/prysm/v5/encoding/ssz" v11 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1" @@ -892,3 +896,133 @@ func (l *TestLightClient) CheckSyncAggregate(sa *pb.SyncAggregate) { require.DeepSSZEqual(l.T, syncAggregate.SyncCommitteeBits, sa.SyncCommitteeBits, "SyncAggregate bits is not equal") require.DeepSSZEqual(l.T, syncAggregate.SyncCommitteeSignature, sa.SyncCommitteeSignature, "SyncAggregate signature is not equal") } + +func CreateTestingUpdate(t *testing.T, v int) (interfaces.LightClientUpdate, error) { + config := params.BeaconConfig() + var slot primitives.Slot + var header interfaces.LightClientHeader + var err error + + sampleRoot := make([]byte, 32) + for i := 0; i < 32; i++ { + sampleRoot[i] = byte(i) + } + + sampleExecutionBranch := make([][]byte, fieldparams.ExecutionBranchDepth) + for i := 0; i < 4; i++ { + sampleExecutionBranch[i] = make([]byte, 32) + for j := 0; j < 32; j++ { + sampleExecutionBranch[i][j] = byte(i + j) + } + } + + switch v { + case version.Altair: + slot = primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) + header, err = light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{ + Beacon: &pb.BeaconBlockHeader{ + Slot: 1, + ProposerIndex: primitives.ValidatorIndex(rand.Int()), + ParentRoot: sampleRoot, + StateRoot: sampleRoot, + BodyRoot: sampleRoot, + }, + }) + require.NoError(t, err) + case version.Capella: + slot = primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) + header, err = light_client.NewWrappedHeader(&pb.LightClientHeaderCapella{ + Beacon: &pb.BeaconBlockHeader{ + Slot: 1, + ProposerIndex: primitives.ValidatorIndex(rand.Int()), + ParentRoot: sampleRoot, + StateRoot: sampleRoot, + BodyRoot: sampleRoot, + }, + Execution: &v11.ExecutionPayloadHeaderCapella{ + ParentHash: make([]byte, fieldparams.RootLength), + FeeRecipient: make([]byte, fieldparams.FeeRecipientLength), + StateRoot: make([]byte, fieldparams.RootLength), + ReceiptsRoot: make([]byte, fieldparams.RootLength), + LogsBloom: make([]byte, fieldparams.LogsBloomLength), + PrevRandao: make([]byte, fieldparams.RootLength), + ExtraData: make([]byte, 0), + BaseFeePerGas: make([]byte, fieldparams.RootLength), + BlockHash: make([]byte, fieldparams.RootLength), + TransactionsRoot: make([]byte, fieldparams.RootLength), + WithdrawalsRoot: make([]byte, fieldparams.RootLength), + }, + ExecutionBranch: sampleExecutionBranch, + }) + require.NoError(t, err) + case version.Deneb: + slot = primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) + header, err = light_client.NewWrappedHeader(&pb.LightClientHeaderDeneb{ + Beacon: &pb.BeaconBlockHeader{ + Slot: 1, + ProposerIndex: primitives.ValidatorIndex(rand.Int()), + ParentRoot: sampleRoot, + StateRoot: sampleRoot, + BodyRoot: sampleRoot, + }, + Execution: &v11.ExecutionPayloadHeaderDeneb{ + ParentHash: make([]byte, fieldparams.RootLength), + FeeRecipient: make([]byte, fieldparams.FeeRecipientLength), + StateRoot: make([]byte, fieldparams.RootLength), + ReceiptsRoot: make([]byte, fieldparams.RootLength), + LogsBloom: make([]byte, fieldparams.LogsBloomLength), + PrevRandao: make([]byte, fieldparams.RootLength), + ExtraData: make([]byte, 0), + BaseFeePerGas: make([]byte, fieldparams.RootLength), + BlockHash: make([]byte, fieldparams.RootLength), + TransactionsRoot: make([]byte, fieldparams.RootLength), + WithdrawalsRoot: make([]byte, fieldparams.RootLength), + }, + ExecutionBranch: sampleExecutionBranch, + }) + require.NoError(t, err) + case version.Electra: + slot = primitives.Slot(config.ElectraForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) + header, err = light_client.NewWrappedHeader(&pb.LightClientHeaderDeneb{ + Beacon: &pb.BeaconBlockHeader{ + Slot: 1, + ProposerIndex: primitives.ValidatorIndex(rand.Int()), + ParentRoot: sampleRoot, + StateRoot: sampleRoot, + BodyRoot: sampleRoot, + }, + Execution: &v11.ExecutionPayloadHeaderElectra{ + ParentHash: make([]byte, fieldparams.RootLength), + FeeRecipient: make([]byte, fieldparams.FeeRecipientLength), + StateRoot: make([]byte, fieldparams.RootLength), + ReceiptsRoot: make([]byte, fieldparams.RootLength), + LogsBloom: make([]byte, fieldparams.LogsBloomLength), + PrevRandao: make([]byte, fieldparams.RootLength), + ExtraData: make([]byte, 0), + BaseFeePerGas: make([]byte, fieldparams.RootLength), + BlockHash: make([]byte, fieldparams.RootLength), + TransactionsRoot: make([]byte, fieldparams.RootLength), + WithdrawalsRoot: make([]byte, fieldparams.RootLength), + }, + ExecutionBranch: sampleExecutionBranch, + }) + require.NoError(t, err) + default: + return nil, fmt.Errorf("unsupported version %s", version.String(v)) + } + + update, err := lightclientCore.CreateDefaultLightClientUpdate(slot) + require.NoError(t, err) + update.SetSignatureSlot(slot - 1) + syncCommitteeBits := make([]byte, 64) + syncCommitteeSignature := make([]byte, 96) + update.SetSyncAggregate(&pb.SyncAggregate{ + SyncCommitteeBits: syncCommitteeBits, + SyncCommitteeSignature: syncCommitteeSignature, + }) + + require.NoError(t, update.SetAttestedHeader(header)) + require.NoError(t, update.SetFinalizedHeader(header)) + + return update, nil +} From 04c4d3bc354461dd111f93f1da5e00865c7ec838 Mon Sep 17 00:00:00 2001 From: Inspector-Butters Date: Mon, 28 Oct 2024 13:31:30 +0100 Subject: [PATCH 33/35] fix circular import error --- .../rpc/eth/light-client/handlers_test.go | 165 ++++++++++- testing/util/BUILD.bazel | 2 - testing/util/lightclient.go | 262 +++++++++--------- 3 files changed, 279 insertions(+), 150 deletions(-) diff --git a/beacon-chain/rpc/eth/light-client/handlers_test.go b/beacon-chain/rpc/eth/light-client/handlers_test.go index 4b843e915c2f..449daa20ec96 100644 --- a/beacon-chain/rpc/eth/light-client/handlers_test.go +++ b/beacon-chain/rpc/eth/light-client/handlers_test.go @@ -5,6 +5,7 @@ import ( "context" "encoding/json" "fmt" + "math/rand" "net/http" "net/http/httptest" "strconv" @@ -14,13 +15,17 @@ import ( "github.com/prysmaticlabs/prysm/v5/api/server/structs" mock "github.com/prysmaticlabs/prysm/v5/beacon-chain/blockchain/testing" "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/helpers" + lightclient "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/light-client" dbtesting "github.com/prysmaticlabs/prysm/v5/beacon-chain/db/testing" "github.com/prysmaticlabs/prysm/v5/beacon-chain/rpc/testutil" "github.com/prysmaticlabs/prysm/v5/beacon-chain/state" + fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams" "github.com/prysmaticlabs/prysm/v5/config/params" "github.com/prysmaticlabs/prysm/v5/consensus-types/blocks" "github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces" + light_client "github.com/prysmaticlabs/prysm/v5/consensus-types/light-client" "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" + enginev1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1" pb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" "github.com/prysmaticlabs/prysm/v5/runtime/version" "github.com/prysmaticlabs/prysm/v5/testing/require" @@ -259,7 +264,7 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeAltair(t *testing.T) { updatePeriod := uint64(slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch))) - update, err := util.CreateTestingUpdate(t, version.Altair) + update, err := createUpdate(t, version.Altair) require.NoError(t, err) err = db.SaveLightClientUpdate(ctx, updatePeriod, update) require.NoError(t, err) @@ -307,7 +312,7 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeCapella(t *testing.T) { updatePeriod := uint64(slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch))) - update, err := util.CreateTestingUpdate(t, version.Capella) + update, err := createUpdate(t, version.Capella) require.NoError(t, err) err = db.SaveLightClientUpdate(ctx, updatePeriod, update) @@ -357,7 +362,7 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeDeneb(t *testing.T) { updatePeriod := uint64(slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch))) - update, err := util.CreateTestingUpdate(t, version.Deneb) + update, err := createUpdate(t, version.Deneb) require.NoError(t, err) err = db.SaveLightClientUpdate(ctx, updatePeriod, update) require.NoError(t, err) @@ -408,7 +413,7 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleAltair(t *testin updates := make([]interfaces.LightClientUpdate, 0) for i := 1; i <= 2; i++ { - update, err := util.CreateTestingUpdate(t, version.Altair) + update, err := createUpdate(t, version.Altair) require.NoError(t, err) updates = append(updates, update) } @@ -468,7 +473,7 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleCapella(t *testi updates := make([]interfaces.LightClientUpdate, 0) for i := 0; i < 2; i++ { - update, err := util.CreateTestingUpdate(t, version.Capella) + update, err := createUpdate(t, version.Capella) require.NoError(t, err) updates = append(updates, update) } @@ -529,7 +534,7 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleDeneb(t *testing updates := make([]interfaces.LightClientUpdate, 0) for i := 0; i < 2; i++ { - update, err := util.CreateTestingUpdate(t, version.Deneb) + update, err := createUpdate(t, version.Deneb) require.NoError(t, err) updates = append(updates, update) } @@ -589,7 +594,7 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleForksAltairCapel updatePeriod := slotAltair.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - updates[0], err = util.CreateTestingUpdate(t, version.Altair) + updates[0], err = createUpdate(t, version.Altair) require.NoError(t, err) err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), updates[0]) @@ -597,7 +602,7 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleForksAltairCapel updatePeriod = slotCapella.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - updates[1], err = util.CreateTestingUpdate(t, version.Capella) + updates[1], err = createUpdate(t, version.Capella) require.NoError(t, err) err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), updates[1]) @@ -658,7 +663,7 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleForksCapellaDene updatePeriod := slotCapella.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - updates[0], err = util.CreateTestingUpdate(t, version.Capella) + updates[0], err = createUpdate(t, version.Capella) require.NoError(t, err) err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), updates[0]) @@ -666,7 +671,7 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeMultipleForksCapellaDene updatePeriod = slotDeneb.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - updates[1], err = util.CreateTestingUpdate(t, version.Deneb) + updates[1], err = createUpdate(t, version.Deneb) require.NoError(t, err) err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), updates[1]) @@ -727,7 +732,7 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeCountBiggerThanLimit(t * for i := 0; i < 3; i++ { - updates[i], err = util.CreateTestingUpdate(t, version.Altair) + updates[i], err = createUpdate(t, version.Altair) require.NoError(t, err) err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), updates[i]) @@ -788,7 +793,7 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeCountBiggerThanMax(t *te updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) for i := 0; i < 3; i++ { - updates[i], err = util.CreateTestingUpdate(t, version.Altair) + updates[i], err = createUpdate(t, version.Altair) require.NoError(t, err) err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), updates[i]) @@ -845,7 +850,7 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeStartPeriodBeforeAltair( updatePeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch)) - update, err := util.CreateTestingUpdate(t, version.Altair) + update, err := createUpdate(t, version.Altair) require.NoError(t, err) err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), update) @@ -906,7 +911,7 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeMissingUpdates(t *testin continue } - updates[i], err = util.CreateTestingUpdate(t, version.Altair) + updates[i], err = createUpdate(t, version.Altair) require.NoError(t, err) err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), updates[i]) @@ -952,7 +957,7 @@ func TestLightClientHandler_GetLightClientUpdatesByRangeMissingUpdates(t *testin continue } - updates[i], err = util.CreateTestingUpdate(t, version.Altair) + updates[i], err = createUpdate(t, version.Altair) require.NoError(t, err) err = db.SaveLightClientUpdate(ctx, uint64(updatePeriod), updates[i]) @@ -1871,3 +1876,133 @@ func TestLightClientHandler_GetLightClientEventBlock_NeedFetchParent(t *testing. require.Equal(t, true, syncAggregate.SyncCommitteeBits.Count() >= minSignaturesRequired) require.Equal(t, slot-1, eventBlock.Block().Slot()) } + +func createUpdate(t *testing.T, v int) (interfaces.LightClientUpdate, error) { + config := params.BeaconConfig() + var slot primitives.Slot + var header interfaces.LightClientHeader + var err error + + sampleRoot := make([]byte, 32) + for i := 0; i < 32; i++ { + sampleRoot[i] = byte(i) + } + + sampleExecutionBranch := make([][]byte, fieldparams.ExecutionBranchDepth) + for i := 0; i < 4; i++ { + sampleExecutionBranch[i] = make([]byte, 32) + for j := 0; j < 32; j++ { + sampleExecutionBranch[i][j] = byte(i + j) + } + } + + switch v { + case version.Altair: + slot = primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) + header, err = light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{ + Beacon: &pb.BeaconBlockHeader{ + Slot: 1, + ProposerIndex: primitives.ValidatorIndex(rand.Int()), + ParentRoot: sampleRoot, + StateRoot: sampleRoot, + BodyRoot: sampleRoot, + }, + }) + require.NoError(t, err) + case version.Capella: + slot = primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) + header, err = light_client.NewWrappedHeader(&pb.LightClientHeaderCapella{ + Beacon: &pb.BeaconBlockHeader{ + Slot: 1, + ProposerIndex: primitives.ValidatorIndex(rand.Int()), + ParentRoot: sampleRoot, + StateRoot: sampleRoot, + BodyRoot: sampleRoot, + }, + Execution: &enginev1.ExecutionPayloadHeaderCapella{ + ParentHash: make([]byte, fieldparams.RootLength), + FeeRecipient: make([]byte, fieldparams.FeeRecipientLength), + StateRoot: make([]byte, fieldparams.RootLength), + ReceiptsRoot: make([]byte, fieldparams.RootLength), + LogsBloom: make([]byte, fieldparams.LogsBloomLength), + PrevRandao: make([]byte, fieldparams.RootLength), + ExtraData: make([]byte, 0), + BaseFeePerGas: make([]byte, fieldparams.RootLength), + BlockHash: make([]byte, fieldparams.RootLength), + TransactionsRoot: make([]byte, fieldparams.RootLength), + WithdrawalsRoot: make([]byte, fieldparams.RootLength), + }, + ExecutionBranch: sampleExecutionBranch, + }) + require.NoError(t, err) + case version.Deneb: + slot = primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) + header, err = light_client.NewWrappedHeader(&pb.LightClientHeaderDeneb{ + Beacon: &pb.BeaconBlockHeader{ + Slot: 1, + ProposerIndex: primitives.ValidatorIndex(rand.Int()), + ParentRoot: sampleRoot, + StateRoot: sampleRoot, + BodyRoot: sampleRoot, + }, + Execution: &enginev1.ExecutionPayloadHeaderDeneb{ + ParentHash: make([]byte, fieldparams.RootLength), + FeeRecipient: make([]byte, fieldparams.FeeRecipientLength), + StateRoot: make([]byte, fieldparams.RootLength), + ReceiptsRoot: make([]byte, fieldparams.RootLength), + LogsBloom: make([]byte, fieldparams.LogsBloomLength), + PrevRandao: make([]byte, fieldparams.RootLength), + ExtraData: make([]byte, 0), + BaseFeePerGas: make([]byte, fieldparams.RootLength), + BlockHash: make([]byte, fieldparams.RootLength), + TransactionsRoot: make([]byte, fieldparams.RootLength), + WithdrawalsRoot: make([]byte, fieldparams.RootLength), + }, + ExecutionBranch: sampleExecutionBranch, + }) + require.NoError(t, err) + case version.Electra: + slot = primitives.Slot(config.ElectraForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) + header, err = light_client.NewWrappedHeader(&pb.LightClientHeaderDeneb{ + Beacon: &pb.BeaconBlockHeader{ + Slot: 1, + ProposerIndex: primitives.ValidatorIndex(rand.Int()), + ParentRoot: sampleRoot, + StateRoot: sampleRoot, + BodyRoot: sampleRoot, + }, + Execution: &enginev1.ExecutionPayloadHeaderElectra{ + ParentHash: make([]byte, fieldparams.RootLength), + FeeRecipient: make([]byte, fieldparams.FeeRecipientLength), + StateRoot: make([]byte, fieldparams.RootLength), + ReceiptsRoot: make([]byte, fieldparams.RootLength), + LogsBloom: make([]byte, fieldparams.LogsBloomLength), + PrevRandao: make([]byte, fieldparams.RootLength), + ExtraData: make([]byte, 0), + BaseFeePerGas: make([]byte, fieldparams.RootLength), + BlockHash: make([]byte, fieldparams.RootLength), + TransactionsRoot: make([]byte, fieldparams.RootLength), + WithdrawalsRoot: make([]byte, fieldparams.RootLength), + }, + ExecutionBranch: sampleExecutionBranch, + }) + require.NoError(t, err) + default: + return nil, fmt.Errorf("unsupported version %s", version.String(v)) + } + + update, err := lightclient.CreateDefaultLightClientUpdate(slot) + require.NoError(t, err) + update.SetSignatureSlot(slot - 1) + syncCommitteeBits := make([]byte, 64) + syncCommitteeSignature := make([]byte, 96) + update.SetSyncAggregate(&pb.SyncAggregate{ + SyncCommitteeBits: syncCommitteeBits, + SyncCommitteeSignature: syncCommitteeSignature, + }) + + require.NoError(t, update.SetAttestedHeader(header)) + require.NoError(t, update.SetFinalizedHeader(header)) + + return update, nil +} diff --git a/testing/util/BUILD.bazel b/testing/util/BUILD.bazel index b474d0236027..16154398cf7e 100644 --- a/testing/util/BUILD.bazel +++ b/testing/util/BUILD.bazel @@ -34,7 +34,6 @@ go_library( "//beacon-chain/core/altair:go_default_library", "//beacon-chain/core/blocks:go_default_library", "//beacon-chain/core/helpers:go_default_library", - "//beacon-chain/core/light-client:go_default_library", "//beacon-chain/core/signing:go_default_library", "//beacon-chain/core/time:go_default_library", "//beacon-chain/core/transition:go_default_library", @@ -48,7 +47,6 @@ go_library( "//consensus-types:go_default_library", "//consensus-types/blocks:go_default_library", "//consensus-types/interfaces:go_default_library", - "//consensus-types/light-client:go_default_library", "//consensus-types/primitives:go_default_library", "//container/trie:go_default_library", "//crypto/bls:go_default_library", diff --git a/testing/util/lightclient.go b/testing/util/lightclient.go index 261b87d3220c..bfd29a7618e4 100644 --- a/testing/util/lightclient.go +++ b/testing/util/lightclient.go @@ -2,19 +2,15 @@ package util import ( "context" - "fmt" - "math/rand" "testing" "github.com/pkg/errors" - lightclientCore "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/light-client" "github.com/prysmaticlabs/prysm/v5/beacon-chain/state" fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams" "github.com/prysmaticlabs/prysm/v5/config/params" consensus_types "github.com/prysmaticlabs/prysm/v5/consensus-types" "github.com/prysmaticlabs/prysm/v5/consensus-types/blocks" "github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces" - light_client "github.com/prysmaticlabs/prysm/v5/consensus-types/light-client" "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" "github.com/prysmaticlabs/prysm/v5/encoding/ssz" v11 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1" @@ -897,132 +893,132 @@ func (l *TestLightClient) CheckSyncAggregate(sa *pb.SyncAggregate) { require.DeepSSZEqual(l.T, syncAggregate.SyncCommitteeSignature, sa.SyncCommitteeSignature, "SyncAggregate signature is not equal") } -func CreateTestingUpdate(t *testing.T, v int) (interfaces.LightClientUpdate, error) { - config := params.BeaconConfig() - var slot primitives.Slot - var header interfaces.LightClientHeader - var err error - - sampleRoot := make([]byte, 32) - for i := 0; i < 32; i++ { - sampleRoot[i] = byte(i) - } - - sampleExecutionBranch := make([][]byte, fieldparams.ExecutionBranchDepth) - for i := 0; i < 4; i++ { - sampleExecutionBranch[i] = make([]byte, 32) - for j := 0; j < 32; j++ { - sampleExecutionBranch[i][j] = byte(i + j) - } - } - - switch v { - case version.Altair: - slot = primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) - header, err = light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{ - Beacon: &pb.BeaconBlockHeader{ - Slot: 1, - ProposerIndex: primitives.ValidatorIndex(rand.Int()), - ParentRoot: sampleRoot, - StateRoot: sampleRoot, - BodyRoot: sampleRoot, - }, - }) - require.NoError(t, err) - case version.Capella: - slot = primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) - header, err = light_client.NewWrappedHeader(&pb.LightClientHeaderCapella{ - Beacon: &pb.BeaconBlockHeader{ - Slot: 1, - ProposerIndex: primitives.ValidatorIndex(rand.Int()), - ParentRoot: sampleRoot, - StateRoot: sampleRoot, - BodyRoot: sampleRoot, - }, - Execution: &v11.ExecutionPayloadHeaderCapella{ - ParentHash: make([]byte, fieldparams.RootLength), - FeeRecipient: make([]byte, fieldparams.FeeRecipientLength), - StateRoot: make([]byte, fieldparams.RootLength), - ReceiptsRoot: make([]byte, fieldparams.RootLength), - LogsBloom: make([]byte, fieldparams.LogsBloomLength), - PrevRandao: make([]byte, fieldparams.RootLength), - ExtraData: make([]byte, 0), - BaseFeePerGas: make([]byte, fieldparams.RootLength), - BlockHash: make([]byte, fieldparams.RootLength), - TransactionsRoot: make([]byte, fieldparams.RootLength), - WithdrawalsRoot: make([]byte, fieldparams.RootLength), - }, - ExecutionBranch: sampleExecutionBranch, - }) - require.NoError(t, err) - case version.Deneb: - slot = primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) - header, err = light_client.NewWrappedHeader(&pb.LightClientHeaderDeneb{ - Beacon: &pb.BeaconBlockHeader{ - Slot: 1, - ProposerIndex: primitives.ValidatorIndex(rand.Int()), - ParentRoot: sampleRoot, - StateRoot: sampleRoot, - BodyRoot: sampleRoot, - }, - Execution: &v11.ExecutionPayloadHeaderDeneb{ - ParentHash: make([]byte, fieldparams.RootLength), - FeeRecipient: make([]byte, fieldparams.FeeRecipientLength), - StateRoot: make([]byte, fieldparams.RootLength), - ReceiptsRoot: make([]byte, fieldparams.RootLength), - LogsBloom: make([]byte, fieldparams.LogsBloomLength), - PrevRandao: make([]byte, fieldparams.RootLength), - ExtraData: make([]byte, 0), - BaseFeePerGas: make([]byte, fieldparams.RootLength), - BlockHash: make([]byte, fieldparams.RootLength), - TransactionsRoot: make([]byte, fieldparams.RootLength), - WithdrawalsRoot: make([]byte, fieldparams.RootLength), - }, - ExecutionBranch: sampleExecutionBranch, - }) - require.NoError(t, err) - case version.Electra: - slot = primitives.Slot(config.ElectraForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) - header, err = light_client.NewWrappedHeader(&pb.LightClientHeaderDeneb{ - Beacon: &pb.BeaconBlockHeader{ - Slot: 1, - ProposerIndex: primitives.ValidatorIndex(rand.Int()), - ParentRoot: sampleRoot, - StateRoot: sampleRoot, - BodyRoot: sampleRoot, - }, - Execution: &v11.ExecutionPayloadHeaderElectra{ - ParentHash: make([]byte, fieldparams.RootLength), - FeeRecipient: make([]byte, fieldparams.FeeRecipientLength), - StateRoot: make([]byte, fieldparams.RootLength), - ReceiptsRoot: make([]byte, fieldparams.RootLength), - LogsBloom: make([]byte, fieldparams.LogsBloomLength), - PrevRandao: make([]byte, fieldparams.RootLength), - ExtraData: make([]byte, 0), - BaseFeePerGas: make([]byte, fieldparams.RootLength), - BlockHash: make([]byte, fieldparams.RootLength), - TransactionsRoot: make([]byte, fieldparams.RootLength), - WithdrawalsRoot: make([]byte, fieldparams.RootLength), - }, - ExecutionBranch: sampleExecutionBranch, - }) - require.NoError(t, err) - default: - return nil, fmt.Errorf("unsupported version %s", version.String(v)) - } - - update, err := lightclientCore.CreateDefaultLightClientUpdate(slot) - require.NoError(t, err) - update.SetSignatureSlot(slot - 1) - syncCommitteeBits := make([]byte, 64) - syncCommitteeSignature := make([]byte, 96) - update.SetSyncAggregate(&pb.SyncAggregate{ - SyncCommitteeBits: syncCommitteeBits, - SyncCommitteeSignature: syncCommitteeSignature, - }) - - require.NoError(t, update.SetAttestedHeader(header)) - require.NoError(t, update.SetFinalizedHeader(header)) - - return update, nil -} +//func CreateTestingUpdate(t *testing.T, v int) (interfaces.LightClientUpdate, error) { +// config := params.BeaconConfig() +// var slot primitives.Slot +// var header interfaces.LightClientHeader +// var err error +// +// sampleRoot := make([]byte, 32) +// for i := 0; i < 32; i++ { +// sampleRoot[i] = byte(i) +// } +// +// sampleExecutionBranch := make([][]byte, fieldparams.ExecutionBranchDepth) +// for i := 0; i < 4; i++ { +// sampleExecutionBranch[i] = make([]byte, 32) +// for j := 0; j < 32; j++ { +// sampleExecutionBranch[i][j] = byte(i + j) +// } +// } +// +// switch v { +// case version.Altair: +// slot = primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) +// header, err = light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{ +// Beacon: &pb.BeaconBlockHeader{ +// Slot: 1, +// ProposerIndex: primitives.ValidatorIndex(rand.Int()), +// ParentRoot: sampleRoot, +// StateRoot: sampleRoot, +// BodyRoot: sampleRoot, +// }, +// }) +// require.NoError(t, err) +// case version.Capella: +// slot = primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) +// header, err = light_client.NewWrappedHeader(&pb.LightClientHeaderCapella{ +// Beacon: &pb.BeaconBlockHeader{ +// Slot: 1, +// ProposerIndex: primitives.ValidatorIndex(rand.Int()), +// ParentRoot: sampleRoot, +// StateRoot: sampleRoot, +// BodyRoot: sampleRoot, +// }, +// Execution: &v11.ExecutionPayloadHeaderCapella{ +// ParentHash: make([]byte, fieldparams.RootLength), +// FeeRecipient: make([]byte, fieldparams.FeeRecipientLength), +// StateRoot: make([]byte, fieldparams.RootLength), +// ReceiptsRoot: make([]byte, fieldparams.RootLength), +// LogsBloom: make([]byte, fieldparams.LogsBloomLength), +// PrevRandao: make([]byte, fieldparams.RootLength), +// ExtraData: make([]byte, 0), +// BaseFeePerGas: make([]byte, fieldparams.RootLength), +// BlockHash: make([]byte, fieldparams.RootLength), +// TransactionsRoot: make([]byte, fieldparams.RootLength), +// WithdrawalsRoot: make([]byte, fieldparams.RootLength), +// }, +// ExecutionBranch: sampleExecutionBranch, +// }) +// require.NoError(t, err) +// case version.Deneb: +// slot = primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) +// header, err = light_client.NewWrappedHeader(&pb.LightClientHeaderDeneb{ +// Beacon: &pb.BeaconBlockHeader{ +// Slot: 1, +// ProposerIndex: primitives.ValidatorIndex(rand.Int()), +// ParentRoot: sampleRoot, +// StateRoot: sampleRoot, +// BodyRoot: sampleRoot, +// }, +// Execution: &v11.ExecutionPayloadHeaderDeneb{ +// ParentHash: make([]byte, fieldparams.RootLength), +// FeeRecipient: make([]byte, fieldparams.FeeRecipientLength), +// StateRoot: make([]byte, fieldparams.RootLength), +// ReceiptsRoot: make([]byte, fieldparams.RootLength), +// LogsBloom: make([]byte, fieldparams.LogsBloomLength), +// PrevRandao: make([]byte, fieldparams.RootLength), +// ExtraData: make([]byte, 0), +// BaseFeePerGas: make([]byte, fieldparams.RootLength), +// BlockHash: make([]byte, fieldparams.RootLength), +// TransactionsRoot: make([]byte, fieldparams.RootLength), +// WithdrawalsRoot: make([]byte, fieldparams.RootLength), +// }, +// ExecutionBranch: sampleExecutionBranch, +// }) +// require.NoError(t, err) +// case version.Electra: +// slot = primitives.Slot(config.ElectraForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) +// header, err = light_client.NewWrappedHeader(&pb.LightClientHeaderDeneb{ +// Beacon: &pb.BeaconBlockHeader{ +// Slot: 1, +// ProposerIndex: primitives.ValidatorIndex(rand.Int()), +// ParentRoot: sampleRoot, +// StateRoot: sampleRoot, +// BodyRoot: sampleRoot, +// }, +// Execution: &v11.ExecutionPayloadHeaderElectra{ +// ParentHash: make([]byte, fieldparams.RootLength), +// FeeRecipient: make([]byte, fieldparams.FeeRecipientLength), +// StateRoot: make([]byte, fieldparams.RootLength), +// ReceiptsRoot: make([]byte, fieldparams.RootLength), +// LogsBloom: make([]byte, fieldparams.LogsBloomLength), +// PrevRandao: make([]byte, fieldparams.RootLength), +// ExtraData: make([]byte, 0), +// BaseFeePerGas: make([]byte, fieldparams.RootLength), +// BlockHash: make([]byte, fieldparams.RootLength), +// TransactionsRoot: make([]byte, fieldparams.RootLength), +// WithdrawalsRoot: make([]byte, fieldparams.RootLength), +// }, +// ExecutionBranch: sampleExecutionBranch, +// }) +// require.NoError(t, err) +// default: +// return nil, fmt.Errorf("unsupported version %s", version.String(v)) +// } +// +// update, err := lightclientCore.CreateDefaultLightClientUpdate(slot) +// require.NoError(t, err) +// update.SetSignatureSlot(slot - 1) +// syncCommitteeBits := make([]byte, 64) +// syncCommitteeSignature := make([]byte, 96) +// update.SetSyncAggregate(&pb.SyncAggregate{ +// SyncCommitteeBits: syncCommitteeBits, +// SyncCommitteeSignature: syncCommitteeSignature, +// }) +// +// require.NoError(t, update.SetAttestedHeader(header)) +// require.NoError(t, update.SetFinalizedHeader(header)) +// +// return update, nil +//} From 43919eb73864ad5c6af98fcd81e640891ee89870 Mon Sep 17 00:00:00 2001 From: Inspector-Butters Date: Mon, 28 Oct 2024 13:37:34 +0100 Subject: [PATCH 34/35] remove unused func --- testing/util/lightclient.go | 130 ------------------------------------ 1 file changed, 130 deletions(-) diff --git a/testing/util/lightclient.go b/testing/util/lightclient.go index bfd29a7618e4..2edb8390a7aa 100644 --- a/testing/util/lightclient.go +++ b/testing/util/lightclient.go @@ -892,133 +892,3 @@ func (l *TestLightClient) CheckSyncAggregate(sa *pb.SyncAggregate) { require.DeepSSZEqual(l.T, syncAggregate.SyncCommitteeBits, sa.SyncCommitteeBits, "SyncAggregate bits is not equal") require.DeepSSZEqual(l.T, syncAggregate.SyncCommitteeSignature, sa.SyncCommitteeSignature, "SyncAggregate signature is not equal") } - -//func CreateTestingUpdate(t *testing.T, v int) (interfaces.LightClientUpdate, error) { -// config := params.BeaconConfig() -// var slot primitives.Slot -// var header interfaces.LightClientHeader -// var err error -// -// sampleRoot := make([]byte, 32) -// for i := 0; i < 32; i++ { -// sampleRoot[i] = byte(i) -// } -// -// sampleExecutionBranch := make([][]byte, fieldparams.ExecutionBranchDepth) -// for i := 0; i < 4; i++ { -// sampleExecutionBranch[i] = make([]byte, 32) -// for j := 0; j < 32; j++ { -// sampleExecutionBranch[i][j] = byte(i + j) -// } -// } -// -// switch v { -// case version.Altair: -// slot = primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) -// header, err = light_client.NewWrappedHeader(&pb.LightClientHeaderAltair{ -// Beacon: &pb.BeaconBlockHeader{ -// Slot: 1, -// ProposerIndex: primitives.ValidatorIndex(rand.Int()), -// ParentRoot: sampleRoot, -// StateRoot: sampleRoot, -// BodyRoot: sampleRoot, -// }, -// }) -// require.NoError(t, err) -// case version.Capella: -// slot = primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) -// header, err = light_client.NewWrappedHeader(&pb.LightClientHeaderCapella{ -// Beacon: &pb.BeaconBlockHeader{ -// Slot: 1, -// ProposerIndex: primitives.ValidatorIndex(rand.Int()), -// ParentRoot: sampleRoot, -// StateRoot: sampleRoot, -// BodyRoot: sampleRoot, -// }, -// Execution: &v11.ExecutionPayloadHeaderCapella{ -// ParentHash: make([]byte, fieldparams.RootLength), -// FeeRecipient: make([]byte, fieldparams.FeeRecipientLength), -// StateRoot: make([]byte, fieldparams.RootLength), -// ReceiptsRoot: make([]byte, fieldparams.RootLength), -// LogsBloom: make([]byte, fieldparams.LogsBloomLength), -// PrevRandao: make([]byte, fieldparams.RootLength), -// ExtraData: make([]byte, 0), -// BaseFeePerGas: make([]byte, fieldparams.RootLength), -// BlockHash: make([]byte, fieldparams.RootLength), -// TransactionsRoot: make([]byte, fieldparams.RootLength), -// WithdrawalsRoot: make([]byte, fieldparams.RootLength), -// }, -// ExecutionBranch: sampleExecutionBranch, -// }) -// require.NoError(t, err) -// case version.Deneb: -// slot = primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) -// header, err = light_client.NewWrappedHeader(&pb.LightClientHeaderDeneb{ -// Beacon: &pb.BeaconBlockHeader{ -// Slot: 1, -// ProposerIndex: primitives.ValidatorIndex(rand.Int()), -// ParentRoot: sampleRoot, -// StateRoot: sampleRoot, -// BodyRoot: sampleRoot, -// }, -// Execution: &v11.ExecutionPayloadHeaderDeneb{ -// ParentHash: make([]byte, fieldparams.RootLength), -// FeeRecipient: make([]byte, fieldparams.FeeRecipientLength), -// StateRoot: make([]byte, fieldparams.RootLength), -// ReceiptsRoot: make([]byte, fieldparams.RootLength), -// LogsBloom: make([]byte, fieldparams.LogsBloomLength), -// PrevRandao: make([]byte, fieldparams.RootLength), -// ExtraData: make([]byte, 0), -// BaseFeePerGas: make([]byte, fieldparams.RootLength), -// BlockHash: make([]byte, fieldparams.RootLength), -// TransactionsRoot: make([]byte, fieldparams.RootLength), -// WithdrawalsRoot: make([]byte, fieldparams.RootLength), -// }, -// ExecutionBranch: sampleExecutionBranch, -// }) -// require.NoError(t, err) -// case version.Electra: -// slot = primitives.Slot(config.ElectraForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1) -// header, err = light_client.NewWrappedHeader(&pb.LightClientHeaderDeneb{ -// Beacon: &pb.BeaconBlockHeader{ -// Slot: 1, -// ProposerIndex: primitives.ValidatorIndex(rand.Int()), -// ParentRoot: sampleRoot, -// StateRoot: sampleRoot, -// BodyRoot: sampleRoot, -// }, -// Execution: &v11.ExecutionPayloadHeaderElectra{ -// ParentHash: make([]byte, fieldparams.RootLength), -// FeeRecipient: make([]byte, fieldparams.FeeRecipientLength), -// StateRoot: make([]byte, fieldparams.RootLength), -// ReceiptsRoot: make([]byte, fieldparams.RootLength), -// LogsBloom: make([]byte, fieldparams.LogsBloomLength), -// PrevRandao: make([]byte, fieldparams.RootLength), -// ExtraData: make([]byte, 0), -// BaseFeePerGas: make([]byte, fieldparams.RootLength), -// BlockHash: make([]byte, fieldparams.RootLength), -// TransactionsRoot: make([]byte, fieldparams.RootLength), -// WithdrawalsRoot: make([]byte, fieldparams.RootLength), -// }, -// ExecutionBranch: sampleExecutionBranch, -// }) -// require.NoError(t, err) -// default: -// return nil, fmt.Errorf("unsupported version %s", version.String(v)) -// } -// -// update, err := lightclientCore.CreateDefaultLightClientUpdate(slot) -// require.NoError(t, err) -// update.SetSignatureSlot(slot - 1) -// syncCommitteeBits := make([]byte, 64) -// syncCommitteeSignature := make([]byte, 96) -// update.SetSyncAggregate(&pb.SyncAggregate{ -// SyncCommitteeBits: syncCommitteeBits, -// SyncCommitteeSignature: syncCommitteeSignature, -// }) -// -// require.NoError(t, update.SetAttestedHeader(header)) -// require.NoError(t, update.SetFinalizedHeader(header)) -// -// return update, nil -//} From d402dd1f95918efb19796f0a5ed68b84a1c0d0f9 Mon Sep 17 00:00:00 2001 From: Inspector-Butters Date: Mon, 28 Oct 2024 13:40:42 +0100 Subject: [PATCH 35/35] fix changelog --- CHANGELOG.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e0bbd89d153..71a23c0e4dd4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,7 +24,6 @@ The format is based on Keep a Changelog, and this project adheres to Semantic Ve - Fix `engine_exchangeCapabilities` implementation. - Updated the default `scrape-interval` in `Client-stats` to 2 minutes to accommodate Beaconcha.in API rate limits. - Switch to compounding when consolidating with source==target. -- Changed `GetLightClientUpdatesByRange` API to read from the DB instead of computing. - Revert block db save when saving state fails. - Return false from HasBlock if the block is being synced. - Cleanup forkchoice on failed insertions. @@ -44,9 +43,6 @@ The format is based on Keep a Changelog, and this project adheres to Semantic Ve - Fixed mesh size by appending `gParams.Dhi = gossipSubDhi` - Fix skipping partial withdrawals count. -- recover from panics when writing the event stream [pr](https://github.com/prysmaticlabs/prysm/pull/14545) -- Return the correct light client payload proof. [PR](https://github.com/prysmaticlabs/prysm/pull/14565) -- Set fields of wrapped proto object in light client setters. [PR](https://github.com/prysmaticlabs/prysm/pull/14573) - wait for the async StreamEvent writer to exit before leaving the http handler, avoiding race condition panics [pr](https://github.com/prysmaticlabs/prysm/pull/14557) - Certain deb files were returning a 404 which made building new docker images without an existing cache impossible. This has been fixed with updates to rules_oci and bazel-lib.