From e5d1eb885dacc5fe7b2157d08d94cff8e36ec627 Mon Sep 17 00:00:00 2001 From: Potuz Date: Wed, 2 Aug 2023 02:59:09 -0300 Subject: [PATCH] Update caches blocking (#12679) * update NSC together with epoch boundary caches * block when updating caches * reviews * removal of very useful helper because the reviewers requested it :) * use IsEpochEnd --- beacon-chain/blockchain/process_block.go | 39 +++++++++++++----------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/beacon-chain/blockchain/process_block.go b/beacon-chain/blockchain/process_block.go index 72a385e99..089ff4399 100644 --- a/beacon-chain/blockchain/process_block.go +++ b/beacon-chain/blockchain/process_block.go @@ -86,18 +86,6 @@ func (s *Service) postBlockProcess(ctx context.Context, signed interfaces.ReadOn "headRoot": fmt.Sprintf("%#x", headRoot), "headWeight": headWeight, }).Debug("Head block is not the received block") - } else { - // Updating next slot state cache can happen in the background. It shouldn't block rest of the process. - go func() { - // Use a custom deadline here, since this method runs asynchronously. - // We ignore the parent method's context and instead create a new one - // with a custom deadline, therefore using the background context instead. - slotCtx, cancel := context.WithTimeout(context.Background(), slotDeadline) - defer cancel() - if err := transition.UpdateNextSlotCache(slotCtx, blockRoot[:], postState); err != nil { - log.WithError(err).Debug("could not update next slot state cache") - } - }() } newBlockHeadElapsedTime.Observe(float64(time.Since(start).Milliseconds())) @@ -126,11 +114,28 @@ func (s *Service) postBlockProcess(ctx context.Context, signed interfaces.ReadOn }) defer reportAttestationInclusion(b) - //only handle epoch boundary if the incoming block is canonical, - //otherwise this will be handled by lateBlockTasks. if headRoot == blockRoot { - if err := s.handleEpochBoundary(ctx, postState.Slot(), postState, blockRoot[:]); err != nil { - return errors.Wrap(err, "could not handle epoch boundary") + // Updating next slot state cache can happen in the background + // except in the epoch boundary in which case we lock to handle + // the shuffling and proposer caches updates. + // We handle these caches only on canonical + // blocks, otherwise this will be handled by lateBlockTasks + slot := postState.Slot() + if slots.IsEpochEnd(slot) { + if err := transition.UpdateNextSlotCache(ctx, blockRoot[:], postState); err != nil { + return errors.Wrap(err, "could not update next slot state cache") + } + if err := s.handleEpochBoundary(ctx, slot, postState, blockRoot[:]); err != nil { + return errors.Wrap(err, "could not handle epoch boundary") + } + } else { + go func() { + slotCtx, cancel := context.WithTimeout(context.Background(), slotDeadline) + defer cancel() + if err := transition.UpdateNextSlotCache(slotCtx, blockRoot[:], postState); err != nil { + log.WithError(err).Error("could not update next slot state cache") + } + }() } } onBlockProcessingTime.Observe(float64(time.Since(startTime).Milliseconds())) @@ -360,7 +365,7 @@ func (s *Service) handleEpochBoundary(ctx context.Context, slot primitives.Slot, if slot < headState.Slot() { return nil } - if (slot+1)%params.BeaconConfig().SlotsPerEpoch != 0 { + if !slots.IsEpochEnd(slot) { return nil } copied := headState.Copy()