@@ -434,9 +434,15 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
434
434
/// Execute the fork choice algorithm and enthrone the result as the canonical head.
435
435
///
436
436
/// This method replaces the old `BeaconChain::fork_choice` method.
437
- pub async fn recompute_head_at_current_slot ( self : & Arc < Self > ) -> Result < ( ) , Error > {
438
- let current_slot = self . slot ( ) ?;
439
- self . recompute_head_at_slot ( current_slot) . await
437
+ pub async fn recompute_head_at_current_slot ( self : & Arc < Self > ) {
438
+ match self . slot ( ) {
439
+ Ok ( current_slot) => self . recompute_head_at_slot ( current_slot) . await ,
440
+ Err ( e) => error ! (
441
+ self . log,
442
+ "No slot when recomputing head" ;
443
+ "error" => ?e
444
+ ) ,
445
+ }
440
446
}
441
447
442
448
/// Execute the fork choice algorithm and enthrone the result as the canonical head.
@@ -445,7 +451,13 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
445
451
/// different slot to the wall-clock can be useful for pushing fork choice into the next slot
446
452
/// *just* before the start of the slot. This ensures that block production can use the correct
447
453
/// head value without being delayed.
448
- pub async fn recompute_head_at_slot ( self : & Arc < Self > , current_slot : Slot ) -> Result < ( ) , Error > {
454
+ ///
455
+ /// This function purposefully does *not* return a `Result`. It's possible for fork choice to
456
+ /// fail to update if there is only one viable head and it has an invalid execution payload. In
457
+ /// such a case it's critical that the `BeaconChain` keeps importing blocks so that the
458
+ /// situation can be rectified. We avoid returning an error here so that calling functions
459
+ /// can't abort block import because an error is returned here.
460
+ pub async fn recompute_head_at_slot ( self : & Arc < Self > , current_slot : Slot ) {
449
461
metrics:: inc_counter ( & metrics:: FORK_CHOICE_REQUESTS ) ;
450
462
let _timer = metrics:: start_timer ( & metrics:: FORK_CHOICE_TIMES ) ;
451
463
@@ -455,23 +467,22 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
455
467
move || chain. recompute_head_at_slot_internal ( current_slot) ,
456
468
"recompute_head_internal" ,
457
469
)
458
- . await ?
470
+ . await
459
471
{
460
472
// Fork choice returned successfully and did not need to update the EL.
461
- Ok ( None ) => Ok ( ( ) ) ,
473
+ Ok ( Ok ( None ) ) => ( ) ,
462
474
// Fork choice returned successfully and needed to update the EL. It has returned a
463
475
// join-handle from when it spawned some async tasks. We should await those tasks.
464
- Ok ( Some ( join_handle) ) => match join_handle. await {
476
+ Ok ( Ok ( Some ( join_handle) ) ) => match join_handle. await {
465
477
// The async task completed successfully.
466
- Ok ( Some ( ( ) ) ) => Ok ( ( ) ) ,
478
+ Ok ( Some ( ( ) ) ) => ( ) ,
467
479
// The async task did not complete successfully since the runtime is shutting down.
468
480
Ok ( None ) => {
469
481
debug ! (
470
482
self . log,
471
483
"Did not update EL fork choice" ;
472
484
"info" => "shutting down"
473
485
) ;
474
- Err ( Error :: RuntimeShutdown )
475
486
}
476
487
// The async task did not complete successfully, tokio returned an error.
477
488
Err ( e) => {
@@ -480,13 +491,24 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
480
491
"Did not update EL fork choice" ;
481
492
"error" => ?e
482
493
) ;
483
- Err ( Error :: TokioJoin ( e) )
484
494
}
485
495
} ,
486
496
// There was an error recomputing the head.
487
- Err ( e) => {
497
+ Ok ( Err ( e) ) => {
488
498
metrics:: inc_counter ( & metrics:: FORK_CHOICE_ERRORS ) ;
489
- Err ( e)
499
+ error ! (
500
+ self . log,
501
+ "Error whist recomputing head" ;
502
+ "error" => ?e
503
+ ) ;
504
+ }
505
+ // There was an error spawning the task.
506
+ Err ( e) => {
507
+ error ! (
508
+ self . log,
509
+ "Failed to spawn recompute head task" ;
510
+ "error" => ?e
511
+ ) ;
490
512
}
491
513
}
492
514
}
0 commit comments