diff --git a/CHANGELOG.md b/CHANGELOG.md index e87b89e8f938..92905e4318e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ The format is based on Keep a Changelog, and this project adheres to Semantic Ve - Add Electra support and tests for light client functions - fastssz version bump (better error messages). - SSE implementation that sheds stuck clients. [pr](https://github.com/prysmaticlabs/prysm/pull/14413) +- Add Bellatrix tests for light client functions ### Changed @@ -82,6 +83,7 @@ The format is based on Keep a Changelog, and this project adheres to Semantic Ve - Light client support: fix light client attested header execution fields' wrong version bug. - Testing: added custom matcher for better push settings testing. - Registered `GetDepositSnapshot` Beacon API endpoint. +- Fixed mesh size by appending `gParams.Dhi = gossipSubDhi` ### Security diff --git a/beacon-chain/core/light-client/lightclient_test.go b/beacon-chain/core/light-client/lightclient_test.go index bbfafa6a583d..eb6ab4417083 100644 --- a/beacon-chain/core/light-client/lightclient_test.go +++ b/beacon-chain/core/light-client/lightclient_test.go @@ -364,6 +364,26 @@ func TestLightClient_BlockToLightClientHeader(t *testing.T) { 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) diff --git a/beacon-chain/p2p/pubsub.go b/beacon-chain/p2p/pubsub.go index 3549841c9034..5a1f229313ce 100644 --- a/beacon-chain/p2p/pubsub.go +++ b/beacon-chain/p2p/pubsub.go @@ -182,6 +182,7 @@ func pubsubGossipParam() pubsub.GossipSubParams { gParams := pubsub.DefaultGossipSubParams() gParams.Dlo = gossipSubDlo gParams.D = gossipSubD + gParams.Dhi = gossipSubDhi gParams.HeartbeatInterval = gossipSubHeartbeatInterval gParams.HistoryLength = gossipSubMcacheLen gParams.HistoryGossip = gossipSubMcacheGossip diff --git a/beacon-chain/rpc/eth/light-client/handlers_test.go b/beacon-chain/rpc/eth/light-client/handlers_test.go index 774997d336ee..342ea679ee3c 100644 --- a/beacon-chain/rpc/eth/light-client/handlers_test.go +++ b/beacon-chain/rpc/eth/light-client/handlers_test.go @@ -63,7 +63,46 @@ func TestLightClientHandler_GetLightClientBootstrap_Altair(t *testing.T) { 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) { diff --git a/testing/util/lightclient.go b/testing/util/lightclient.go index 8e6a768ae413..a79e7f8f72d9 100644 --- a/testing/util/lightclient.go +++ b/testing/util/lightclient.go @@ -344,6 +344,91 @@ func (l *TestLightClient) SetupTestAltair() *TestLightClient { return l } +func (l *TestLightClient) SetupTestBellatrix() *TestLightClient { + ctx := context.Background() + + slot := primitives.Slot(params.BeaconConfig().BellatrixForkEpoch * primitives.Epoch(params.BeaconConfig().SlotsPerEpoch)).Add(1) + + attestedState, err := NewBeaconStateBellatrix() + require.NoError(l.T, err) + err = attestedState.SetSlot(slot) + require.NoError(l.T, err) + + finalizedBlock, err := blocks.NewSignedBeaconBlock(NewBeaconBlockBellatrix()) + require.NoError(l.T, err) + finalizedBlock.SetSlot(1) + 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().BellatrixForkEpoch - 10, + Root: finalizedRoot[:], + })) + + parent := NewBeaconBlockBellatrix() + parent.Block.Slot = slot + + signedParent, err := blocks.NewSignedBeaconBlock(parent) + require.NoError(l.T, err) + + parentHeader, err := signedParent.Header() + require.NoError(l.T, err) + attestedHeader := parentHeader.Header + + err = attestedState.SetLatestBlockHeader(attestedHeader) + require.NoError(l.T, err) + attestedStateRoot, err := attestedState.HashTreeRoot(ctx) + require.NoError(l.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(l.T, err) + + state, err := NewBeaconStateBellatrix() + require.NoError(l.T, err) + err = state.SetSlot(slot) + require.NoError(l.T, err) + + parentRoot, err := signedParent.Block().HashTreeRoot() + require.NoError(l.T, err) + + block := NewBeaconBlockBellatrix() + block.Block.Slot = slot + block.Block.ParentRoot = parentRoot[:] + + for i := uint64(0); i < params.BeaconConfig().MinSyncCommitteeParticipants; i++ { + block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true) + } + + signedBlock, err := blocks.NewSignedBeaconBlock(block) + require.NoError(l.T, err) + + h, err := signedBlock.Header() + require.NoError(l.T, err) + + err = state.SetLatestBlockHeader(h.Header) + require.NoError(l.T, err) + stateRoot, err := state.HashTreeRoot(ctx) + require.NoError(l.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(l.T, err) + + l.State = state + l.AttestedState = attestedState + l.Block = signedBlock + l.Ctx = ctx + l.FinalizedBlock = finalizedBlock + l.AttestedBlock = signedParent + + return l +} + func (l *TestLightClient) SetupTestDeneb(blinded bool) *TestLightClient { ctx := context.Background()