Skip to content

Commit

Permalink
feat: add Bellatrix tests for light clients (prysmaticlabs#14520)
Browse files Browse the repository at this point in the history
* add tests for Bellatrix

* update `CHANGELOG.md`

* Update CHANGELOG.md

Co-authored-by: Radosław Kapka <radoslaw.kapka@gmail.com>

---------

Co-authored-by: Radosław Kapka <radoslaw.kapka@gmail.com>
  • Loading branch information
rupam-04 and rkapka authored Oct 9, 2024
1 parent 3fa6d3b commit e40d2cb
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,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

Expand Down
20 changes: 20 additions & 0 deletions beacon-chain/core/light-client/lightclient_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
39 changes: 39 additions & 0 deletions beacon-chain/rpc/eth/light-client/handlers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
85 changes: 85 additions & 0 deletions testing/util/lightclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -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(&ethpb.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()

Expand Down

0 comments on commit e40d2cb

Please sign in to comment.