-
Notifications
You must be signed in to change notification settings - Fork 1.2k
[DO NOT MERGE]: Apply consensus and equivocation check before broadcast #12335
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
Changes from all commits
3f9bddb
85ef50e
8a08899
29dd025
8b50411
8e5a192
12990b8
b87294d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,6 +10,7 @@ import ( | |
| "github.com/prysmaticlabs/prysm/v4/beacon-chain/core/feed" | ||
| blockfeed "github.com/prysmaticlabs/prysm/v4/beacon-chain/core/feed/block" | ||
| "github.com/prysmaticlabs/prysm/v4/beacon-chain/core/helpers" | ||
| "github.com/prysmaticlabs/prysm/v4/beacon-chain/core/transition" | ||
| "github.com/prysmaticlabs/prysm/v4/beacon-chain/db/filters" | ||
| rpchelpers "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/helpers" | ||
| "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/lookup" | ||
|
|
@@ -198,10 +199,9 @@ func (bs *Server) ListBlockHeaders(ctx context.Context, req *ethpbv1.BlockHeader | |
| } | ||
|
|
||
| // SubmitBlock instructs the beacon node to broadcast a newly signed beacon block to the beacon network, to be | ||
| // included in the beacon chain. The beacon node is not required to validate the signed ReadOnlyBeaconBlock, and a successful | ||
| // response (20X) only indicates that the broadcast has been successful. The beacon node is expected to integrate the | ||
| // new block into its state, and therefore validate the block internally, however blocks which fail the validation are | ||
| // still broadcast but a different status code is returned (202). | ||
| // included in the beacon chain. The beacon node will validate the signed ReadOnlyBeaconBlock, and a successful | ||
| // response (20X) only indicates that the broadcast has been successful. The beacon node is not expected to integrate the | ||
| // new block into its state. | ||
| func (bs *Server) SubmitBlock(ctx context.Context, req *ethpbv2.SignedBeaconBlockContainer) (*emptypb.Empty, error) { | ||
| ctx, span := trace.StartSpan(ctx, "beacon.SubmitBlock") | ||
| defer span.End() | ||
|
|
@@ -231,10 +231,9 @@ func (bs *Server) SubmitBlock(ctx context.Context, req *ethpbv2.SignedBeaconBloc | |
| } | ||
|
|
||
| // SubmitBlockSSZ instructs the beacon node to broadcast a newly signed beacon block to the beacon network, to be | ||
| // included in the beacon chain. The beacon node is not required to validate the signed ReadOnlyBeaconBlock, and a successful | ||
| // response (20X) only indicates that the broadcast has been successful. The beacon node is expected to integrate the | ||
| // new block into its state, and therefore validate the block internally, however blocks which fail the validation are | ||
| // still broadcast but a different status code is returned (202). | ||
| // included in the beacon chain. The beacon node will validate the signed ReadOnlyBeaconBlock, and a successful | ||
| // response (20X) only indicates that the broadcast has been successful. The beacon node is not expected to integrate the | ||
| // new block into its state. | ||
| // | ||
| // The provided block must be SSZ-serialized. | ||
| func (bs *Server) SubmitBlockSSZ(ctx context.Context, req *ethpbv2.SSZContainer) (*emptypb.Empty, error) { | ||
|
|
@@ -1019,6 +1018,24 @@ func (bs *Server) submitBlock(ctx context.Context, blockRoot [fieldparams.RootLe | |
| }) | ||
| }() | ||
|
|
||
| if block == nil || block.IsNil() { | ||
| return errors.New("nil block") | ||
| } | ||
|
Comment on lines
+1021
to
+1023
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you do this before the defer function? |
||
|
|
||
| b := block.Block() | ||
| parentState, err := bs.StateGenService.StateByRoot(ctx, b.ParentRoot()) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In our usual block processing pipeline we verify the block time disparity at this stage. Do we need to do it here? |
||
| if err != nil { | ||
| return errors.Wrap(err, "could not get parent state") | ||
| } | ||
| _, err = transition.ExecuteStateTransition(ctx, parentState, block) | ||
| if err != nil { | ||
| return errors.Wrap(err, "could not execute state transition") | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Better change the Godoc for |
||
| } | ||
|
|
||
| if bs.EquivocationChecker.SeenProposerIndex(b.Slot(), b.ProposerIndex()) { | ||
| return fmt.Errorf("block exists in sync service, slot: %d, proposer index: %d", b.Slot(), b.ProposerIndex()) | ||
| } | ||
|
|
||
| // Broadcast the new block to the network. | ||
| blockPb, err := block.Proto() | ||
| if err != nil { | ||
|
|
@@ -1028,9 +1045,5 @@ func (bs *Server) submitBlock(ctx context.Context, blockRoot [fieldparams.RootLe | |
| return status.Errorf(codes.Internal, "Could not broadcast block: %v", err) | ||
| } | ||
|
|
||
| if err := bs.BlockReceiver.ReceiveBlock(ctx, block, blockRoot); err != nil { | ||
| return status.Errorf(codes.Internal, "Could not process beacon block: %v", err) | ||
| } | ||
|
|
||
| return nil | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -69,6 +69,10 @@ func (s *Service) validateBeaconBlockPubSub(ctx context.Context, pid peer.ID, ms | |
| return pubsub.ValidationReject, errors.New("block.Block is nil") | ||
| } | ||
|
|
||
| if err := s.verifySignatureAndInsertProposerIndex(ctx, blk); err != nil { | ||
| log.WithError(err).Error("could not verify sig and insert proposer index") | ||
| } | ||
|
|
||
| // Broadcast the block on a feed to notify other services in the beacon node | ||
| // of a received block (even if it does not process correctly through a state transition). | ||
| s.cfg.blockNotifier.BlockFeed().Send(&feed.Event{ | ||
|
|
@@ -384,3 +388,49 @@ func getBlockFields(b interfaces.ReadOnlySignedBeaconBlock) logrus.Fields { | |
| "version": b.Block().Version(), | ||
| } | ||
| } | ||
|
|
||
| func (s *Service) verifySignatureAndInsertProposerIndex(ctx context.Context, blk interfaces.ReadOnlySignedBeaconBlock) error { | ||
| headState, err := s.cfg.chain.HeadStateReadOnly(ctx) | ||
| if err != nil { | ||
| return err | ||
| } | ||
| if err = blocks.VerifyBlockSignatureUsingCurrentFork(headState, blk); err != nil { | ||
| return err | ||
| } | ||
|
|
||
| s.insertProposerIndexCache(blk.Block().Slot(), blk.Block().ProposerIndex()) | ||
| return nil | ||
| } | ||
|
|
||
| func (s *Service) insertProposerIndexCache(slot primitives.Slot, proposerIdx primitives.ValidatorIndex) { | ||
| if s.seenProposerIndexCache == nil { | ||
| return | ||
| } | ||
| if s.cfg.chain.CurrentSlot() != slot { | ||
| return | ||
| } | ||
|
|
||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nilcheck for |
||
| switch { | ||
| case uint64(s.seenProposerIndexCache[0]) == uint64(slot): | ||
| s.seenProposerIndexCache = append(s.seenProposerIndexCache, proposerIdx) | ||
| case uint64(slot) > uint64(s.seenProposerIndexCache[0]): | ||
| // Overwrite slot in proposer index cache if it's higher. | ||
| s.seenProposerIndexCache = []primitives.ValidatorIndex{primitives.ValidatorIndex(slot), proposerIdx} | ||
| } | ||
| } | ||
|
|
||
| func (s *Service) SeenProposerIndex(slot primitives.Slot, proposerIdx primitives.ValidatorIndex) bool { | ||
| if s.seenProposerIndexCache == nil { | ||
| return false | ||
| } | ||
|
|
||
| if s.seenProposerIndexCache[0] != primitives.ValidatorIndex(slot) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nilcheck for |
||
| return false | ||
| } | ||
| for _, i := range s.seenProposerIndexCache[1:] { | ||
| if i == proposerIdx { | ||
| return true | ||
| } | ||
| } | ||
| return false | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.