Skip to content

Commit 44ff0b1

Browse files
rupam-04Inspector-Buttersrkapka
authored
add missing Electra tests for light client (#14783)
* add Electra tests for finality update * override beacon config * add Electra tests to * fix setupTestElectra * changelog * cleanup test config * Update beacon-chain/core/light-client/lightclient_test.go Co-authored-by: Radosław Kapka <radoslaw.kapka@gmail.com> * changelog * move config to top --------- Co-authored-by: Bastin <bastin.m@proton.me> Co-authored-by: Bastin <43618253+Inspector-Butters@users.noreply.github.com> Co-authored-by: Radosław Kapka <radoslaw.kapka@gmail.com> Co-authored-by: Radosław Kapka <rkapka@wp.pl>
1 parent 91cdd31 commit 44ff0b1

File tree

3 files changed

+302
-3
lines changed

3 files changed

+302
-3
lines changed

beacon-chain/core/light-client/lightclient_test.go

+182
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,15 @@ import (
2222
)
2323

2424
func TestLightClient_NewLightClientOptimisticUpdateFromBeaconState(t *testing.T) {
25+
params.SetupTestConfigCleanup(t)
26+
cfg := params.BeaconConfig()
27+
cfg.AltairForkEpoch = 1
28+
cfg.BellatrixForkEpoch = 2
29+
cfg.CapellaForkEpoch = 3
30+
cfg.DenebForkEpoch = 4
31+
cfg.ElectraForkEpoch = 5
32+
params.OverrideBeaconConfig(cfg)
33+
2534
t.Run("Altair", func(t *testing.T) {
2635
l := util.NewTestLightClient(t).SetupTestAltair()
2736

@@ -59,9 +68,31 @@ func TestLightClient_NewLightClientOptimisticUpdateFromBeaconState(t *testing.T)
5968
l.CheckSyncAggregate(update.SyncAggregate())
6069
l.CheckAttestedHeader(update.AttestedHeader())
6170
})
71+
72+
t.Run("Electra", func(t *testing.T) {
73+
l := util.NewTestLightClient(t).SetupTestElectra(false)
74+
75+
update, err := lightClient.NewLightClientOptimisticUpdateFromBeaconState(l.Ctx, l.State.Slot(), l.State, l.Block, l.AttestedState, l.AttestedBlock)
76+
require.NoError(t, err)
77+
require.NotNil(t, update, "update is nil")
78+
79+
require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot(), "Signature slot is not equal")
80+
81+
l.CheckSyncAggregate(update.SyncAggregate())
82+
l.CheckAttestedHeader(update.AttestedHeader())
83+
})
6284
}
6385

6486
func TestLightClient_NewLightClientFinalityUpdateFromBeaconState(t *testing.T) {
87+
params.SetupTestConfigCleanup(t)
88+
cfg := params.BeaconConfig()
89+
cfg.AltairForkEpoch = 1
90+
cfg.BellatrixForkEpoch = 2
91+
cfg.CapellaForkEpoch = 3
92+
cfg.DenebForkEpoch = 4
93+
cfg.ElectraForkEpoch = 5
94+
params.OverrideBeaconConfig(cfg)
95+
6596
t.Run("Altair", func(t *testing.T) {
6697
l := util.NewTestLightClient(t).SetupTestAltair()
6798

@@ -356,6 +387,157 @@ func TestLightClient_NewLightClientFinalityUpdateFromBeaconState(t *testing.T) {
356387
require.DeepSSZEqual(t, execution, updateExecution.Proto(), "Finalized Block Execution is not equal")
357388
})
358389
})
390+
391+
t.Run("Electra", func(t *testing.T) {
392+
t.Run("FinalizedBlock Not Nil", func(t *testing.T) {
393+
l := util.NewTestLightClient(t).SetupTestElectra(false)
394+
395+
update, err := lightClient.NewLightClientFinalityUpdateFromBeaconState(l.Ctx, l.State.Slot(), l.State, l.Block, l.AttestedState, l.AttestedBlock, l.FinalizedBlock)
396+
require.NoError(t, err)
397+
require.NotNil(t, update, "update is nil")
398+
399+
require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot(), "Signature slot is not equal")
400+
401+
l.CheckSyncAggregate(update.SyncAggregate())
402+
l.CheckAttestedHeader(update.AttestedHeader())
403+
404+
//zeroHash := params.BeaconConfig().ZeroHash[:]
405+
finalizedBlockHeader, err := l.FinalizedBlock.Header()
406+
require.NoError(t, err)
407+
require.NotNil(t, update.FinalizedHeader(), "Finalized header is nil")
408+
updateFinalizedHeaderBeacon := update.FinalizedHeader().Beacon()
409+
require.Equal(t, finalizedBlockHeader.Header.Slot, updateFinalizedHeaderBeacon.Slot, "Finalized header slot is not equal")
410+
require.Equal(t, finalizedBlockHeader.Header.ProposerIndex, updateFinalizedHeaderBeacon.ProposerIndex, "Finalized header proposer index is not equal")
411+
require.DeepSSZEqual(t, finalizedBlockHeader.Header.ParentRoot, updateFinalizedHeaderBeacon.ParentRoot, "Finalized header parent root is not equal")
412+
require.DeepSSZEqual(t, finalizedBlockHeader.Header.StateRoot, updateFinalizedHeaderBeacon.StateRoot, "Finalized header state root is not equal")
413+
require.DeepSSZEqual(t, finalizedBlockHeader.Header.BodyRoot, updateFinalizedHeaderBeacon.BodyRoot, "Finalized header body root is not equal")
414+
fb, err := update.FinalityBranchElectra()
415+
require.NoError(t, err)
416+
proof, err := l.AttestedState.FinalizedRootProof(l.Ctx)
417+
require.NoError(t, err)
418+
for i, leaf := range fb {
419+
require.DeepSSZEqual(t, proof[i], leaf[:], "Leaf is not equal")
420+
}
421+
422+
// Check Execution BlockHash
423+
payloadInterface, err := l.FinalizedBlock.Block().Body().Execution()
424+
require.NoError(t, err)
425+
transactionsRoot, err := payloadInterface.TransactionsRoot()
426+
if errors.Is(err, consensustypes.ErrUnsupportedField) {
427+
transactions, err := payloadInterface.Transactions()
428+
require.NoError(t, err)
429+
transactionsRootArray, err := ssz.TransactionsRoot(transactions)
430+
require.NoError(t, err)
431+
transactionsRoot = transactionsRootArray[:]
432+
} else {
433+
require.NoError(t, err)
434+
}
435+
withdrawalsRoot, err := payloadInterface.WithdrawalsRoot()
436+
if errors.Is(err, consensustypes.ErrUnsupportedField) {
437+
withdrawals, err := payloadInterface.Withdrawals()
438+
require.NoError(t, err)
439+
withdrawalsRootArray, err := ssz.WithdrawalSliceRoot(withdrawals, fieldparams.MaxWithdrawalsPerPayload)
440+
require.NoError(t, err)
441+
withdrawalsRoot = withdrawalsRootArray[:]
442+
} else {
443+
require.NoError(t, err)
444+
}
445+
execution := &v11.ExecutionPayloadHeaderDeneb{
446+
ParentHash: payloadInterface.ParentHash(),
447+
FeeRecipient: payloadInterface.FeeRecipient(),
448+
StateRoot: payloadInterface.StateRoot(),
449+
ReceiptsRoot: payloadInterface.ReceiptsRoot(),
450+
LogsBloom: payloadInterface.LogsBloom(),
451+
PrevRandao: payloadInterface.PrevRandao(),
452+
BlockNumber: payloadInterface.BlockNumber(),
453+
GasLimit: payloadInterface.GasLimit(),
454+
GasUsed: payloadInterface.GasUsed(),
455+
Timestamp: payloadInterface.Timestamp(),
456+
ExtraData: payloadInterface.ExtraData(),
457+
BaseFeePerGas: payloadInterface.BaseFeePerGas(),
458+
BlockHash: payloadInterface.BlockHash(),
459+
TransactionsRoot: transactionsRoot,
460+
WithdrawalsRoot: withdrawalsRoot,
461+
}
462+
updateExecution, err := update.FinalizedHeader().Execution()
463+
require.NoError(t, err)
464+
require.DeepSSZEqual(t, execution, updateExecution.Proto(), "Finalized Block Execution is not equal")
465+
})
466+
467+
t.Run("FinalizedBlock In Previous Fork", func(t *testing.T) {
468+
l := util.NewTestLightClient(t).SetupTestElectraFinalizedBlockDeneb(false)
469+
470+
update, err := lightClient.NewLightClientFinalityUpdateFromBeaconState(l.Ctx, l.State.Slot(), l.State, l.Block, l.AttestedState, l.AttestedBlock, l.FinalizedBlock)
471+
require.NoError(t, err)
472+
require.NotNil(t, update, "update is nil")
473+
474+
require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot(), "Signature slot is not equal")
475+
476+
l.CheckSyncAggregate(update.SyncAggregate())
477+
l.CheckAttestedHeader(update.AttestedHeader())
478+
479+
finalizedBlockHeader, err := l.FinalizedBlock.Header()
480+
require.NoError(t, err)
481+
require.NotNil(t, update.FinalizedHeader(), "Finalized header is nil")
482+
updateFinalizedHeaderBeacon := update.FinalizedHeader().Beacon()
483+
require.Equal(t, finalizedBlockHeader.Header.Slot, updateFinalizedHeaderBeacon.Slot, "Finalized header slot is not equal")
484+
require.Equal(t, finalizedBlockHeader.Header.ProposerIndex, updateFinalizedHeaderBeacon.ProposerIndex, "Finalized header proposer index is not equal")
485+
require.DeepSSZEqual(t, finalizedBlockHeader.Header.ParentRoot, updateFinalizedHeaderBeacon.ParentRoot, "Finalized header parent root is not equal")
486+
require.DeepSSZEqual(t, finalizedBlockHeader.Header.StateRoot, updateFinalizedHeaderBeacon.StateRoot, "Finalized header state root is not equal")
487+
require.DeepSSZEqual(t, finalizedBlockHeader.Header.BodyRoot, updateFinalizedHeaderBeacon.BodyRoot, "Finalized header body root is not equal")
488+
fb, err := update.FinalityBranchElectra()
489+
require.NoError(t, err)
490+
proof, err := l.AttestedState.FinalizedRootProof(l.Ctx)
491+
require.NoError(t, err)
492+
for i, leaf := range fb {
493+
require.DeepSSZEqual(t, proof[i], leaf[:], "Leaf is not equal")
494+
}
495+
496+
// Check Execution BlockHash
497+
payloadInterface, err := l.FinalizedBlock.Block().Body().Execution()
498+
require.NoError(t, err)
499+
transactionsRoot, err := payloadInterface.TransactionsRoot()
500+
if errors.Is(err, consensustypes.ErrUnsupportedField) {
501+
transactions, err := payloadInterface.Transactions()
502+
require.NoError(t, err)
503+
transactionsRootArray, err := ssz.TransactionsRoot(transactions)
504+
require.NoError(t, err)
505+
transactionsRoot = transactionsRootArray[:]
506+
} else {
507+
require.NoError(t, err)
508+
}
509+
withdrawalsRoot, err := payloadInterface.WithdrawalsRoot()
510+
if errors.Is(err, consensustypes.ErrUnsupportedField) {
511+
withdrawals, err := payloadInterface.Withdrawals()
512+
require.NoError(t, err)
513+
withdrawalsRootArray, err := ssz.WithdrawalSliceRoot(withdrawals, fieldparams.MaxWithdrawalsPerPayload)
514+
require.NoError(t, err)
515+
withdrawalsRoot = withdrawalsRootArray[:]
516+
} else {
517+
require.NoError(t, err)
518+
}
519+
execution := &v11.ExecutionPayloadHeaderDeneb{
520+
ParentHash: payloadInterface.ParentHash(),
521+
FeeRecipient: payloadInterface.FeeRecipient(),
522+
StateRoot: payloadInterface.StateRoot(),
523+
ReceiptsRoot: payloadInterface.ReceiptsRoot(),
524+
LogsBloom: payloadInterface.LogsBloom(),
525+
PrevRandao: payloadInterface.PrevRandao(),
526+
BlockNumber: payloadInterface.BlockNumber(),
527+
GasLimit: payloadInterface.GasLimit(),
528+
GasUsed: payloadInterface.GasUsed(),
529+
Timestamp: payloadInterface.Timestamp(),
530+
ExtraData: payloadInterface.ExtraData(),
531+
BaseFeePerGas: payloadInterface.BaseFeePerGas(),
532+
BlockHash: payloadInterface.BlockHash(),
533+
TransactionsRoot: transactionsRoot,
534+
WithdrawalsRoot: withdrawalsRoot,
535+
}
536+
updateExecution, err := update.FinalizedHeader().Execution()
537+
require.NoError(t, err)
538+
require.DeepSSZEqual(t, execution, updateExecution.Proto(), "Finalized Block Execution is not equal")
539+
})
540+
})
359541
}
360542

361543
func TestLightClient_BlockToLightClientHeader(t *testing.T) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
### Added
2+
3+
- Added Electra tests for `TestLightClient_NewLightClientOptimisticUpdateFromBeaconState` and `TestLightClient_NewLightClientFinalityUpdateFromBeaconState`

testing/util/lightclient.go

+117-3
Original file line numberDiff line numberDiff line change
@@ -551,22 +551,23 @@ func (l *TestLightClient) SetupTestElectra(blinded bool) *TestLightClient {
551551
ctx := context.Background()
552552

553553
slot := primitives.Slot(params.BeaconConfig().ElectraForkEpoch * primitives.Epoch(params.BeaconConfig().SlotsPerEpoch)).Add(1)
554+
finalizedBlockSlot := primitives.Slot(params.BeaconConfig().ElectraForkEpoch * primitives.Epoch(params.BeaconConfig().SlotsPerEpoch))
554555

555556
attestedState, err := NewBeaconStateElectra()
556557
require.NoError(l.T, err)
557558
err = attestedState.SetSlot(slot)
558559
require.NoError(l.T, err)
559560

560-
finalizedBlock, err := blocks.NewSignedBeaconBlock(NewBeaconBlockElectra())
561+
finalizedBlock, err := blocks.NewSignedBeaconBlock(NewBeaconBlockDeneb())
561562
require.NoError(l.T, err)
562-
finalizedBlock.SetSlot(1)
563+
finalizedBlock.SetSlot(finalizedBlockSlot)
563564
finalizedHeader, err := finalizedBlock.Header()
564565
require.NoError(l.T, err)
565566
finalizedRoot, err := finalizedHeader.Header.HashTreeRoot()
566567
require.NoError(l.T, err)
567568

568569
require.NoError(l.T, attestedState.SetFinalizedCheckpoint(&ethpb.Checkpoint{
569-
Epoch: params.BeaconConfig().ElectraForkEpoch - 10,
570+
Epoch: params.BeaconConfig().ElectraForkEpoch,
570571
Root: finalizedRoot[:],
571572
}))
572573

@@ -883,6 +884,119 @@ func (l *TestLightClient) SetupTestDenebFinalizedBlockCapella(blinded bool) *Tes
883884
return l
884885
}
885886

887+
func (l *TestLightClient) SetupTestElectraFinalizedBlockDeneb(blinded bool) *TestLightClient {
888+
ctx := context.Background()
889+
890+
slot := primitives.Slot(params.BeaconConfig().ElectraForkEpoch * primitives.Epoch(params.BeaconConfig().SlotsPerEpoch)).Add(1)
891+
finalizedBlockSlot := primitives.Slot(params.BeaconConfig().DenebForkEpoch * primitives.Epoch(params.BeaconConfig().SlotsPerEpoch))
892+
893+
attestedState, err := NewBeaconStateElectra()
894+
require.NoError(l.T, err)
895+
err = attestedState.SetSlot(slot)
896+
require.NoError(l.T, err)
897+
898+
finalizedBlock, err := blocks.NewSignedBeaconBlock(NewBeaconBlockDeneb())
899+
require.NoError(l.T, err)
900+
finalizedBlock.SetSlot(finalizedBlockSlot)
901+
finalizedHeader, err := finalizedBlock.Header()
902+
require.NoError(l.T, err)
903+
finalizedRoot, err := finalizedHeader.Header.HashTreeRoot()
904+
require.NoError(l.T, err)
905+
906+
require.NoError(l.T, attestedState.SetFinalizedCheckpoint(&ethpb.Checkpoint{
907+
Epoch: params.BeaconConfig().DenebForkEpoch,
908+
Root: finalizedRoot[:],
909+
}))
910+
911+
parent := NewBeaconBlockElectra()
912+
parent.Block.Slot = slot
913+
914+
signedParent, err := blocks.NewSignedBeaconBlock(parent)
915+
require.NoError(l.T, err)
916+
917+
parentHeader, err := signedParent.Header()
918+
require.NoError(l.T, err)
919+
attestedHeader := parentHeader.Header
920+
921+
err = attestedState.SetLatestBlockHeader(attestedHeader)
922+
require.NoError(l.T, err)
923+
attestedStateRoot, err := attestedState.HashTreeRoot(ctx)
924+
require.NoError(l.T, err)
925+
926+
// get a new signed block so the root is updated with the new state root
927+
parent.Block.StateRoot = attestedStateRoot[:]
928+
signedParent, err = blocks.NewSignedBeaconBlock(parent)
929+
require.NoError(l.T, err)
930+
931+
state, err := NewBeaconStateElectra()
932+
require.NoError(l.T, err)
933+
err = state.SetSlot(slot)
934+
require.NoError(l.T, err)
935+
936+
parentRoot, err := signedParent.Block().HashTreeRoot()
937+
require.NoError(l.T, err)
938+
939+
var signedBlock interfaces.SignedBeaconBlock
940+
if blinded {
941+
block := NewBlindedBeaconBlockElectra()
942+
block.Message.Slot = slot
943+
block.Message.ParentRoot = parentRoot[:]
944+
945+
for i := uint64(0); i < params.BeaconConfig().MinSyncCommitteeParticipants; i++ {
946+
block.Message.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true)
947+
}
948+
949+
signedBlock, err = blocks.NewSignedBeaconBlock(block)
950+
require.NoError(l.T, err)
951+
952+
h, err := signedBlock.Header()
953+
require.NoError(l.T, err)
954+
955+
err = state.SetLatestBlockHeader(h.Header)
956+
require.NoError(l.T, err)
957+
stateRoot, err := state.HashTreeRoot(ctx)
958+
require.NoError(l.T, err)
959+
960+
// get a new signed block so the root is updated with the new state root
961+
block.Message.StateRoot = stateRoot[:]
962+
signedBlock, err = blocks.NewSignedBeaconBlock(block)
963+
require.NoError(l.T, err)
964+
} else {
965+
block := NewBeaconBlockElectra()
966+
block.Block.Slot = slot
967+
block.Block.ParentRoot = parentRoot[:]
968+
969+
for i := uint64(0); i < params.BeaconConfig().MinSyncCommitteeParticipants; i++ {
970+
block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true)
971+
}
972+
973+
signedBlock, err = blocks.NewSignedBeaconBlock(block)
974+
require.NoError(l.T, err)
975+
976+
h, err := signedBlock.Header()
977+
require.NoError(l.T, err)
978+
979+
err = state.SetLatestBlockHeader(h.Header)
980+
require.NoError(l.T, err)
981+
stateRoot, err := state.HashTreeRoot(ctx)
982+
require.NoError(l.T, err)
983+
984+
// get a new signed block so the root is updated with the new state root
985+
block.Block.StateRoot = stateRoot[:]
986+
signedBlock, err = blocks.NewSignedBeaconBlock(block)
987+
require.NoError(l.T, err)
988+
}
989+
990+
l.State = state
991+
l.AttestedState = attestedState
992+
l.AttestedBlock = signedParent
993+
l.Block = signedBlock
994+
l.Ctx = ctx
995+
l.FinalizedBlock = finalizedBlock
996+
997+
return l
998+
}
999+
8861000
func (l *TestLightClient) CheckAttestedHeader(header interfaces.LightClientHeader) {
8871001
updateAttestedHeaderBeacon := header.Beacon()
8881002
testAttestedHeader, err := l.AttestedBlock.Header()

0 commit comments

Comments
 (0)