-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Update ProposeBeaconBlock Prysm RPC for Deneb (Non builder)
#12495
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
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 |
|---|---|---|
|
|
@@ -19,12 +19,14 @@ import ( | |
| "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/kv" | ||
| fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams" | ||
| "github.com/prysmaticlabs/prysm/v4/config/params" | ||
| "github.com/prysmaticlabs/prysm/v4/consensus-types/blocks" | ||
| "github.com/prysmaticlabs/prysm/v4/consensus-types/interfaces" | ||
| "github.com/prysmaticlabs/prysm/v4/consensus-types/primitives" | ||
| "github.com/prysmaticlabs/prysm/v4/encoding/bytesutil" | ||
| ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1" | ||
| "github.com/prysmaticlabs/prysm/v4/runtime/version" | ||
| "github.com/prysmaticlabs/prysm/v4/time/slots" | ||
| "github.com/sirupsen/logrus" | ||
| "go.opencensus.io/trace" | ||
|
|
@@ -215,11 +217,77 @@ func (vs *Server) GetBeaconBlock(ctx context.Context, req *ethpb.BlockRequest) ( | |
| func (vs *Server) ProposeBeaconBlock(ctx context.Context, req *ethpb.GenericSignedBeaconBlock) (*ethpb.ProposeResponse, error) { | ||
| ctx, span := trace.StartSpan(ctx, "ProposerServer.ProposeBeaconBlock") | ||
| defer span.End() | ||
|
|
||
| blk, err := blocks.NewSignedBeaconBlock(req.Block) | ||
| if err != nil { | ||
| return nil, status.Errorf(codes.InvalidArgument, "%s: %v", CouldNotDecodeBlock, err) | ||
| } | ||
| return vs.proposeGenericBeaconBlock(ctx, blk) | ||
|
|
||
| unblinder, err := newUnblinder(blk, vs.BlockBuilder) | ||
| if err != nil { | ||
| return nil, errors.Wrap(err, "could not create unblinder") | ||
| } | ||
| blk, err = unblinder.unblindBuilderBlock(ctx) | ||
| if err != nil { | ||
| return nil, errors.Wrap(err, "could not unblind builder block") | ||
| } | ||
|
|
||
| // Broadcast the new block to the network. | ||
| blkPb, err := blk.Proto() | ||
| if err != nil { | ||
| return nil, errors.Wrap(err, "could not get protobuf block") | ||
| } | ||
| if err := vs.P2P.Broadcast(ctx, blkPb); err != nil { | ||
| return nil, fmt.Errorf("could not broadcast block: %v", err) | ||
| } | ||
|
|
||
| root, err := blk.Block().HashTreeRoot() | ||
| if err != nil { | ||
| return nil, fmt.Errorf("could not tree hash block: %v", err) | ||
| } | ||
| log.WithFields(logrus.Fields{ | ||
| "blockRoot": hex.EncodeToString(root[:]), | ||
| }).Debug("Broadcasting block") | ||
|
|
||
| if blk.Version() >= version.Deneb { | ||
| b, ok := req.GetBlock().(*ethpb.GenericSignedBeaconBlock_Deneb) | ||
|
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. This could still be blinded right? , it was unblinded above but the request block would still be possibly blinded. that being said if it was blinded the blobs would also need to be unblinded below.
Collaborator
Author
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. Right, I'm not handling the blinded logic in this PR. I'll clarify this in the title |
||
| if !ok { | ||
| return nil, status.Error(codes.Internal, "Could not cast block to Deneb") | ||
| } | ||
| if len(b.Deneb.Blobs) > fieldparams.MaxBlobsPerBlock { | ||
| return nil, status.Errorf(codes.InvalidArgument, "Too many blobs in block: %d", len(b.Deneb.Blobs)) | ||
| } | ||
| scs := make([]*ethpb.BlobSidecar, len(b.Deneb.Blobs)) | ||
|
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. does this need a validation check on len for blobs, or does receiving handle that
Collaborator
Author
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. I think that's a good check to have, I'll add it in
Collaborator
Author
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. |
||
| for i, blob := range b.Deneb.Blobs { | ||
| if err := vs.P2P.BroadcastBlob(ctx, blob.Message.Index, blob); err != nil { | ||
| log.WithError(err).Errorf("Could not broadcast blob index %d / %d", i, len(b.Deneb.Blobs)) | ||
| } | ||
| scs[i] = blob.Message | ||
| } | ||
| if len(scs) > 0 { | ||
| if err := vs.BeaconDB.SaveBlobSidecar(ctx, scs); err != nil { | ||
| return nil, err | ||
| } | ||
| } | ||
| } | ||
|
|
||
| // Do not block proposal critical path with debug logging or block feed updates. | ||
| defer func() { | ||
| log.WithField("blockRoot", fmt.Sprintf("%#x", bytesutil.Trunc(root[:]))).Debugf( | ||
| "Block proposal received via RPC") | ||
| vs.BlockNotifier.BlockFeed().Send(&feed.Event{ | ||
| Type: blockfeed.ReceivedBlock, | ||
| Data: &blockfeed.ReceivedBlockData{SignedBlock: blk}, | ||
| }) | ||
| }() | ||
|
|
||
| if err := vs.BlockReceiver.ReceiveBlock(ctx, blk, root); err != nil { | ||
| return nil, fmt.Errorf("could not process beacon block: %v", err) | ||
| } | ||
|
|
||
| return ðpb.ProposeResponse{ | ||
| BlockRoot: root[:], | ||
| }, nil | ||
| } | ||
|
|
||
| // PrepareBeaconProposer caches and updates the fee recipient for the given proposer. | ||
|
|
@@ -301,54 +369,6 @@ func (vs *Server) GetFeeRecipientByPubKey(ctx context.Context, request *ethpb.Fe | |
| }, nil | ||
| } | ||
|
|
||
| func (vs *Server) proposeGenericBeaconBlock(ctx context.Context, blk interfaces.SignedBeaconBlock) (*ethpb.ProposeResponse, error) { | ||
| ctx, span := trace.StartSpan(ctx, "ProposerServer.proposeGenericBeaconBlock") | ||
| defer span.End() | ||
| root, err := blk.Block().HashTreeRoot() | ||
| if err != nil { | ||
| return nil, fmt.Errorf("could not tree hash block: %v", err) | ||
| } | ||
|
|
||
| unblinder, err := newUnblinder(blk, vs.BlockBuilder) | ||
| if err != nil { | ||
| return nil, errors.Wrap(err, "could not create unblinder") | ||
| } | ||
| blk, err = unblinder.unblindBuilderBlock(ctx) | ||
| if err != nil { | ||
| return nil, errors.Wrap(err, "could not unblind builder block") | ||
| } | ||
|
|
||
| // Do not block proposal critical path with debug logging or block feed updates. | ||
| defer func() { | ||
| log.WithField("blockRoot", fmt.Sprintf("%#x", bytesutil.Trunc(root[:]))).Debugf( | ||
| "Block proposal received via RPC") | ||
| vs.BlockNotifier.BlockFeed().Send(&feed.Event{ | ||
| Type: blockfeed.ReceivedBlock, | ||
| Data: &blockfeed.ReceivedBlockData{SignedBlock: blk}, | ||
| }) | ||
| }() | ||
|
|
||
| // Broadcast the new block to the network. | ||
| blkPb, err := blk.Proto() | ||
| if err != nil { | ||
| return nil, errors.Wrap(err, "could not get protobuf block") | ||
| } | ||
| if err := vs.P2P.Broadcast(ctx, blkPb); err != nil { | ||
| return nil, fmt.Errorf("could not broadcast block: %v", err) | ||
| } | ||
| log.WithFields(logrus.Fields{ | ||
| "blockRoot": hex.EncodeToString(root[:]), | ||
| }).Debug("Broadcasting block") | ||
|
|
||
| if err := vs.BlockReceiver.ReceiveBlock(ctx, blk, root); err != nil { | ||
| return nil, fmt.Errorf("could not process beacon block: %v", err) | ||
| } | ||
|
|
||
| return ðpb.ProposeResponse{ | ||
| BlockRoot: root[:], | ||
| }, nil | ||
| } | ||
|
|
||
| // computeStateRoot computes the state root after a block has been processed through a state transition and | ||
| // returns it to the validator client. | ||
| func (vs *Server) computeStateRoot(ctx context.Context, block interfaces.ReadOnlySignedBeaconBlock) ([]byte, error) { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is this check after the broadcast?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not really a check, it calculates the root for logging, and we can remove the log. But it's also later used in
ReceiveBlockanyway. Moving it after the broadcast to reduce latency before the gossip