@@ -11,7 +11,10 @@ import (
11
11
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
12
12
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
13
13
"github.com/prysmaticlabs/prysm/beacon-chain/core/validators"
14
+ "github.com/prysmaticlabs/prysm/beacon-chain/db/filters"
14
15
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"
15
18
"github.com/prysmaticlabs/prysm/shared/bytesutil"
16
19
"github.com/prysmaticlabs/prysm/shared/cmd"
17
20
"github.com/prysmaticlabs/prysm/shared/featureconfig"
@@ -474,21 +477,24 @@ func (bs *Server) GetValidatorParticipation(
474
477
requestedEpoch ,
475
478
)
476
479
}
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 )
479
484
if err != nil {
480
485
return nil , status .Error (codes .Internal , "Could not get state" )
481
486
}
482
487
488
+ requestedState , err = bs .appendNonFinalizedBlockAttsToState (ctx , requestedState , requestedEpoch )
489
+
483
490
v , b , err := precompute .New (ctx , requestedState )
484
491
if err != nil {
485
492
return nil , status .Error (codes .Internal , "Could not set up pre compute instance" )
486
493
}
487
494
_ , b , err = precompute .ProcessAttestations (ctx , requestedState , v , b )
488
495
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 )
490
497
}
491
-
492
498
headState , err := bs .HeadFetcher .HeadState (ctx )
493
499
if err != nil {
494
500
return nil , status .Error (codes .Internal , "Could not get head state" )
@@ -505,6 +511,45 @@ func (bs *Server) GetValidatorParticipation(
505
511
}, nil
506
512
}
507
513
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
+
508
553
// GetValidatorQueue retrieves the current validator queue information.
509
554
func (bs * Server ) GetValidatorQueue (
510
555
ctx context.Context , _ * ptypes.Empty ,
0 commit comments