package blockchain import ( "context" "testing" "github.com/pkg/errors" testDB "github.com/prysmaticlabs/prysm/v4/beacon-chain/db/testing" doublylinkedtree "github.com/prysmaticlabs/prysm/v4/beacon-chain/forkchoice/doubly-linked-tree" forkchoicetypes "github.com/prysmaticlabs/prysm/v4/beacon-chain/forkchoice/types" fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams" "github.com/prysmaticlabs/prysm/v4/consensus-types/primitives" "github.com/prysmaticlabs/prysm/v4/encoding/bytesutil" ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1" "github.com/prysmaticlabs/prysm/v4/testing/require" "github.com/prysmaticlabs/prysm/v4/testing/util" "github.com/prysmaticlabs/prysm/v4/time/slots" ) func TestService_VerifyWeakSubjectivityRoot(t *testing.T) { beaconDB := testDB.SetupDB(t) b := util.NewBeaconBlock() b.Block.Slot = 1792480 util.SaveBlock(t, context.Background(), beaconDB, b) r, err := b.Block.HashTreeRoot() require.NoError(t, err) blockEpoch := slots.ToEpoch(b.Block.Slot) tests := []struct { wsVerified bool disabled bool wantErr error checkpt *ethpb.Checkpoint finalizedEpoch primitives.Epoch name string }{ { name: "nil root and epoch", disabled: true, }, { name: "not yet to verify, ws epoch higher than finalized epoch", checkpt: ðpb.Checkpoint{Root: bytesutil.PadTo([]byte{'a'}, 32), Epoch: blockEpoch}, finalizedEpoch: blockEpoch - 1, }, { name: "can't find the block in DB", checkpt: ðpb.Checkpoint{Root: bytesutil.PadTo([]byte{'a'}, fieldparams.RootLength), Epoch: 1}, finalizedEpoch: blockEpoch + 1, wantErr: errWSBlockNotFound, }, { name: "can't find the block corresponds to ws epoch in DB", checkpt: ðpb.Checkpoint{Root: r[:], Epoch: blockEpoch - 2}, // Root belongs in epoch 1. finalizedEpoch: blockEpoch - 1, wantErr: errWSBlockNotFoundInEpoch, }, { name: "can verify and pass", checkpt: ðpb.Checkpoint{Root: r[:], Epoch: blockEpoch}, finalizedEpoch: blockEpoch + 1, }, { name: "equal epoch", checkpt: ðpb.Checkpoint{Root: r[:], Epoch: blockEpoch}, finalizedEpoch: blockEpoch, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { wv, err := NewWeakSubjectivityVerifier(tt.checkpt, beaconDB) require.Equal(t, !tt.disabled, wv.enabled) require.NoError(t, err) fcs := doublylinkedtree.New() s := &Service{ cfg: &config{BeaconDB: beaconDB, WeakSubjectivityCheckpt: tt.checkpt, ForkChoiceStore: fcs}, wsVerifier: wv, } require.NoError(t, fcs.UpdateFinalizedCheckpoint(&forkchoicetypes.Checkpoint{Epoch: tt.finalizedEpoch})) cp := s.cfg.ForkChoiceStore.FinalizedCheckpoint() err = s.wsVerifier.VerifyWeakSubjectivity(context.Background(), cp.Epoch) if tt.wantErr == nil { require.NoError(t, err) } else { require.Equal(t, true, errors.Is(err, tt.wantErr)) } }) } }