Skip to content

Commit 2ee025e

Browse files
Participation: count atts from orphaned blocks (#7117)
* Cound attestations from orphaned blocks * Use next epoch's end slot * Fixed a test * Fixed a test * Nishant's feedback * Typo Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
1 parent 0410b14 commit 2ee025e

File tree

2 files changed

+72
-6
lines changed

2 files changed

+72
-6
lines changed

beacon-chain/rpc/beacon/validators.go

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@ import (
1111
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
1212
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
1313
"github.com/prysmaticlabs/prysm/beacon-chain/core/validators"
14+
"github.com/prysmaticlabs/prysm/beacon-chain/db/filters"
1415
statetrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
16+
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil"
17+
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
1518
"github.com/prysmaticlabs/prysm/shared/bytesutil"
1619
"github.com/prysmaticlabs/prysm/shared/cmd"
1720
"github.com/prysmaticlabs/prysm/shared/featureconfig"
@@ -474,21 +477,24 @@ func (bs *Server) GetValidatorParticipation(
474477
requestedEpoch,
475478
)
476479
}
477-
478-
requestedState, err := bs.StateGen.StateBySlot(ctx, helpers.StartSlot(requestedEpoch+1))
480+
// Calculate the end slot of the next epoch.
481+
// Ex: requested epoch 1, this gets slot 95.
482+
nextEpochEndSlot := helpers.StartSlot(requestedEpoch+2) - 1
483+
requestedState, err := bs.StateGen.StateBySlot(ctx, nextEpochEndSlot)
479484
if err != nil {
480485
return nil, status.Error(codes.Internal, "Could not get state")
481486
}
482487

488+
requestedState, err = bs.appendNonFinalizedBlockAttsToState(ctx, requestedState, requestedEpoch)
489+
483490
v, b, err := precompute.New(ctx, requestedState)
484491
if err != nil {
485492
return nil, status.Error(codes.Internal, "Could not set up pre compute instance")
486493
}
487494
_, b, err = precompute.ProcessAttestations(ctx, requestedState, v, b)
488495
if err != nil {
489-
return nil, status.Error(codes.Internal, "Could not pre compute attestations")
496+
return nil, status.Errorf(codes.Internal, "Could not pre compute attestations: %v", err)
490497
}
491-
492498
headState, err := bs.HeadFetcher.HeadState(ctx)
493499
if err != nil {
494500
return nil, status.Error(codes.Internal, "Could not get head state")
@@ -505,6 +511,45 @@ func (bs *Server) GetValidatorParticipation(
505511
}, nil
506512
}
507513

514+
// This appends non finalized block atts to state. To replay for a state, a node does not replay non canonical
515+
// nor finalized blocks. To count participation, this includes the attestations from the orphaned block to state.
516+
func (bs *Server) appendNonFinalizedBlockAttsToState(ctx context.Context, s *statetrie.BeaconState, e uint64) (*statetrie.BeaconState, error) {
517+
start := helpers.StartSlot(e)
518+
end := helpers.StartSlot(e + 1)
519+
f := filters.NewFilter().SetStartSlot(start).SetEndSlot(end)
520+
blks, err := bs.BeaconDB.Blocks(ctx, f)
521+
if err != nil {
522+
return nil, err
523+
}
524+
525+
nonFinalizedBlks := make([]*ethpb.SignedBeaconBlock, 0, len(blks))
526+
for i := len(blks) - 1; i >= 0; i-- {
527+
r, err := stateutil.BlockRoot(blks[i].Block)
528+
if err != nil {
529+
return nil, err
530+
}
531+
if !bs.BeaconDB.IsFinalizedBlock(ctx, r) {
532+
nonFinalizedBlks = append(nonFinalizedBlks, blks[i])
533+
}
534+
}
535+
for _, b := range nonFinalizedBlks {
536+
for _, a := range b.Block.Body.Attestations {
537+
if a.Data.Target.Epoch == e {
538+
pa := &pb.PendingAttestation{
539+
Data: a.Data,
540+
AggregationBits: a.AggregationBits,
541+
InclusionDelay: params.BeaconConfig().FarFutureEpoch,
542+
}
543+
if err := s.AppendPreviousEpochAttestations(pa); err != nil {
544+
return nil, err
545+
}
546+
}
547+
}
548+
}
549+
550+
return s, nil
551+
}
552+
508553
// GetValidatorQueue retrieves the current validator queue information.
509554
func (bs *Server) GetValidatorQueue(
510555
ctx context.Context, _ *ptypes.Empty,

beacon-chain/rpc/beacon/validators_test.go

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1367,7 +1367,7 @@ func TestServer_GetValidatorParticipation_PrevEpoch(t *testing.T) {
13671367

13681368
atts := []*pbp2p.PendingAttestation{{Data: &ethpb.AttestationData{Target: &ethpb.Checkpoint{}}, InclusionDelay: 1}}
13691369
headState := testutil.NewBeaconState()
1370-
require.NoError(t, headState.SetSlot(params.BeaconConfig().SlotsPerEpoch))
1370+
require.NoError(t, headState.SetSlot(params.BeaconConfig().SlotsPerEpoch*2-1))
13711371
require.NoError(t, headState.SetValidators(validators))
13721372
require.NoError(t, headState.SetBalances(balances))
13731373
require.NoError(t, headState.SetPreviousEpochAttestations(atts))
@@ -1400,7 +1400,7 @@ func TestServer_GetValidatorParticipation_DoesntExist(t *testing.T) {
14001400
ctx := context.Background()
14011401

14021402
headState := testutil.NewBeaconState()
1403-
require.NoError(t, headState.SetSlot(params.BeaconConfig().SlotsPerEpoch))
1403+
require.NoError(t, headState.SetSlot(params.BeaconConfig().SlotsPerEpoch*2-1))
14041404

14051405
b := &ethpb.SignedBeaconBlock{Block: &ethpb.BeaconBlock{Slot: params.BeaconConfig().SlotsPerEpoch}}
14061406
require.NoError(t, db.SaveBlock(ctx, b))
@@ -1860,3 +1860,24 @@ func TestServer_GetIndividualVotes_Working(t *testing.T) {
18601860
}
18611861
assert.DeepEqual(t, wanted, res, "Unexpected response")
18621862
}
1863+
1864+
func TestServer_appendNonFinalizedBlockAttsToState(t *testing.T) {
1865+
db, _ := dbTest.SetupDB(t)
1866+
ctx := context.Background()
1867+
bs := &Server{
1868+
BeaconDB: db,
1869+
}
1870+
e := uint64(1)
1871+
b1 := testutil.NewBeaconBlock()
1872+
b1.Block.Slot = e * params.BeaconConfig().SlotsPerEpoch
1873+
b1.Block.Body.Attestations = []*ethpb.Attestation{{Data: &ethpb.AttestationData{Target: &ethpb.Checkpoint{Epoch: 1}}}}
1874+
b2 := testutil.NewBeaconBlock()
1875+
b2.Block.Slot = e*params.BeaconConfig().SlotsPerEpoch + 1
1876+
b2.Block.Body.Attestations = []*ethpb.Attestation{{Data: &ethpb.AttestationData{Target: &ethpb.Checkpoint{Epoch: 1}}}}
1877+
require.NoError(t, db.SaveBlock(ctx, b1))
1878+
require.NoError(t, db.SaveBlock(ctx, b2))
1879+
s := testutil.NewBeaconState()
1880+
got, err := bs.appendNonFinalizedBlockAttsToState(ctx, s, e)
1881+
require.NoError(t, err)
1882+
require.Equal(t, 2, len(got.PreviousEpochAttestations()))
1883+
}

0 commit comments

Comments
 (0)