Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use headblock for prunePostBlockOperationPools, remove duplicate markInclusionBLStoExecutionChange calls #12085

Merged
merged 24 commits into from
Mar 14, 2023
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
27c8bc7
removing duplicate function
james-prysm Mar 6, 2023
0e04895
Merge branch 'develop' into duplicate-changes-removal
james-prysm Mar 6, 2023
8d08dce
moved markInclusion for bls to use headblock instead of processed block
james-prysm Mar 6, 2023
34b9b61
Merge branch 'develop' into duplicate-changes-removal
james-prysm Mar 6, 2023
c20c641
Merge branch 'develop' into duplicate-changes-removal
james-prysm Mar 7, 2023
63f95cc
Merge branch 'develop' into duplicate-changes-removal
james-prysm Mar 8, 2023
90bf88e
updating based on internal feedback
james-prysm Mar 8, 2023
5b5823e
addressing some comments
james-prysm Mar 8, 2023
3235997
addressing feedback from slack
james-prysm Mar 8, 2023
ab353ca
Merge branch 'develop' into duplicate-changes-removal
james-prysm Mar 8, 2023
362f353
fixing conflict
james-prysm Mar 8, 2023
10058a3
Merge branch 'develop' into duplicate-changes-removal
james-prysm Mar 9, 2023
2d2545c
Merge branch 'develop' into duplicate-changes-removal
james-prysm Mar 9, 2023
f838b31
making changes based on suggestions on slack
james-prysm Mar 9, 2023
30cf37c
reverting a change
james-prysm Mar 9, 2023
904944b
Merge branch 'develop' into duplicate-changes-removal
james-prysm Mar 10, 2023
4cbb316
Merge branch 'develop' into duplicate-changes-removal
james-prysm Mar 13, 2023
ad05c42
making chases based on potuz's comments
james-prysm Mar 14, 2023
1ac08f8
Merge branch 'develop' into duplicate-changes-removal
james-prysm Mar 14, 2023
ef5da67
removing one additional block copy
james-prysm Mar 14, 2023
7a5818a
Merge branch 'develop' into duplicate-changes-removal
james-prysm Mar 14, 2023
38ecfee
Merge branch 'develop' into duplicate-changes-removal
james-prysm Mar 14, 2023
52cb064
Merge branch 'develop' into duplicate-changes-removal
james-prysm Mar 14, 2023
7c7b7ef
clarifying comments
james-prysm Mar 14, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions beacon-chain/blockchain/process_block.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,6 @@ func (s *Service) onBlock(ctx context.Context, signed interfaces.ReadOnlySignedB
if err := s.handleBlockAttestations(ctx, signed.Block(), postState); err != nil {
return errors.Wrap(err, "could not handle block's attestations")
}
if err := s.handleBlockBLSToExecChanges(signed.Block()); err != nil {
return errors.Wrap(err, "could not handle block's BLSToExecutionChanges")
}

s.InsertSlashingsToForkChoiceStore(ctx, signed.Block().Body().AttesterSlashings())
if isValidPayload {
Expand Down Expand Up @@ -214,6 +211,8 @@ func (s *Service) onBlock(ctx context.Context, signed interfaces.ReadOnlySignedB
}
newBlockHeadElapsedTime.Observe(float64(time.Since(start).Milliseconds()))

// verify conditions for FCU, notifies FCU, and saves the new head.
// This function also prunes attestations, other similar operations happen in prunePostBlockOperationPools.
if err := s.forkchoiceUpdateWithExecution(ctx, headRoot, s.CurrentSlot()+1); err != nil {
return err
}
Expand Down Expand Up @@ -597,8 +596,8 @@ func (s *Service) savePostStateInfo(ctx context.Context, r [32]byte, b interface
}

// This removes the attestations in block `b` from the attestation mem pool.
func (s *Service) pruneAttsFromPool(b interfaces.ReadOnlySignedBeaconBlock) error {
atts := b.Block().Body().Attestations()
func (s *Service) pruneAttsFromPool(headBlock interfaces.ReadOnlySignedBeaconBlock) error {
atts := headBlock.Block().Body().Attestations()
for _, att := range atts {
if helpers.IsAggregated(att) {
if err := s.cfg.AttPool.DeleteAggregatedAttestation(att); err != nil {
Expand Down
39 changes: 29 additions & 10 deletions beacon-chain/blockchain/receive_block.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package blockchain

import (
"bytes"
"context"

"github.com/pkg/errors"
Expand Down Expand Up @@ -48,6 +49,9 @@ func (s *Service) ReceiveBlock(ctx context.Context, block interfaces.ReadOnlySig

s.cfg.ForkChoiceStore.Lock()
defer s.cfg.ForkChoiceStore.Unlock()
// Checks if the current blockRoot ( which is also the head root) is new.
// This check must come before forkchoiceUpdateWithExecution because it saves the new head.
isNewHead := s.isNewHead(blockRoot)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do this here versus next to the usage?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to get is New Head before forkchoiceUpdateWithExecution saves the head which happens inside the onblock. otherwise it's not new anymore.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't work either: an incoming block will always have isNewHead==true here. You need to save the headroot here and then after the call to onBlock check the the new head.


// Apply state transition on the new block.
if err := s.onBlock(ctx, blockCopy, blockRoot); err != nil {
Expand All @@ -56,9 +60,11 @@ func (s *Service) ReceiveBlock(ctx context.Context, block interfaces.ReadOnlySig
return err
}

// Handle post block operations such as attestations and exits.
if err := s.handlePostBlockOperations(blockCopy.Block()); err != nil {
return err
if isNewHead {
// Handle post block operations such as pruning exits and bls messages.
if err := s.prunePostBlockOperationPools(ctx, blockRoot); err != nil {
log.WithError(err).Error("Could not prune canonical objects from pool ")
}
}

// Have we been finalizing? Should we start saving hot states to db?
Expand Down Expand Up @@ -157,29 +163,42 @@ func (s *Service) ReceiveAttesterSlashing(ctx context.Context, slashing *ethpb.A
s.InsertSlashingsToForkChoiceStore(ctx, []*ethpb.AttesterSlashing{slashing})
}

func (s *Service) handlePostBlockOperations(b interfaces.ReadOnlyBeaconBlock) error {
// prunePostBlockOperationPools only runs on new head otherwise should return a nil.
func (s *Service) prunePostBlockOperationPools(ctx context.Context, root [32]byte) error {
headRoot, err := s.HeadRoot(ctx)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there will be a dead lock. HeadRoot requires a read lock

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought what potuz mentioned here #12085 (comment) was to use this lock instead.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HeadRoot does not require a read lock, the function takes one.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah ok. HeadRoot uses headLock from Blockchain pkg not ForkchoiceLock. Confusing how there are two different locks

if err != nil {
return err
}
if !bytes.Equal(headRoot, root[:]) {
return nil
}
// uses the newly saved block from forkchoiceUpdateWithExecution
headBlock, err := s.HeadBlock(ctx)
if err != nil {
return err
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just pass the block as part of the argument? We can save a block copy

}
// Mark block exits as seen so we don't include same ones in future blocks.
for _, e := range b.Body().VoluntaryExits() {
for _, e := range headBlock.Block().Body().VoluntaryExits() {
s.cfg.ExitPool.MarkIncluded(e)
}

// Mark block BLS changes as seen so we don't include same ones in future blocks.
if err := s.handleBlockBLSToExecChanges(b); err != nil {
if err := s.markIncludedBlockBLSToExecChanges(headBlock.Block()); err != nil {
return errors.Wrap(err, "could not process BLSToExecutionChanges")
}

// Mark attester slashings as seen so we don't include same ones in future blocks.
for _, as := range b.Body().AttesterSlashings() {
for _, as := range headBlock.Block().Body().AttesterSlashings() {
s.cfg.SlashingPool.MarkIncludedAttesterSlashing(as)
}
return nil
}

func (s *Service) handleBlockBLSToExecChanges(blk interfaces.ReadOnlyBeaconBlock) error {
if blk.Version() < version.Capella {
func (s *Service) markIncludedBlockBLSToExecChanges(headBlock interfaces.ReadOnlyBeaconBlock) error {
if headBlock.Version() < version.Capella {
return nil
}
changes, err := blk.Body().BLSToExecutionChanges()
changes, err := headBlock.Body().BLSToExecutionChanges()
if err != nil {
return errors.Wrap(err, "could not get BLSToExecutionChanges")
}
Expand Down
6 changes: 3 additions & 3 deletions beacon-chain/blockchain/receive_block_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,7 @@ func TestHandleBlockBLSToExecutionChanges(t *testing.T) {
}
blk, err := blocks.NewBeaconBlock(pbb)
require.NoError(t, err)
require.NoError(t, service.handleBlockBLSToExecChanges(blk))
require.NoError(t, service.markIncludedBlockBLSToExecChanges(blk))
})

t.Run("Post Capella no changes", func(t *testing.T) {
Expand All @@ -367,7 +367,7 @@ func TestHandleBlockBLSToExecutionChanges(t *testing.T) {
}
blk, err := blocks.NewBeaconBlock(pbb)
require.NoError(t, err)
require.NoError(t, service.handleBlockBLSToExecChanges(blk))
require.NoError(t, service.markIncludedBlockBLSToExecChanges(blk))
})

t.Run("Post Capella some changes", func(t *testing.T) {
Expand All @@ -389,7 +389,7 @@ func TestHandleBlockBLSToExecutionChanges(t *testing.T) {

pool.InsertBLSToExecChange(signedChange)
require.Equal(t, true, pool.ValidatorExists(idx))
require.NoError(t, service.handleBlockBLSToExecChanges(blk))
require.NoError(t, service.markIncludedBlockBLSToExecChanges(blk))
require.Equal(t, false, pool.ValidatorExists(idx))
})
}