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

Native Blocks Ep. 1 - New types and functions #10837

Merged
merged 15 commits into from
Jun 9, 2022

Conversation

rkapka
Copy link
Contributor

@rkapka rkapka commented Jun 7, 2022

What type of PR is this?

Feature

What does this PR do? Why is it needed?

This PR introduces all types, methods and functions necessary to migrate towards native blocks. It accomplishes the following tasks from https://www.notion.so/prysmaticlabs/Native-Beacon-Block-c862730f431545b6a57333eaa50025d2:

  • Create a new /consensus-types/blocks package
  • Create new consensus types: SignedBeaconBlock, BeaconBlock, BeaconBlockBody. Fields of these types will be existing protobuf objects e.g. eth1Data: *eth.Eth1Data. Having protobuf fields greatly reduces the amount of refactoring needed and does not harm our main goal of making it easier to work with blocks. Each type will contain fields for all versions of the object. An additional version field will be responsible for determining the actual version.
  • Create init[1]FromProto[2] functions where [1] is the name of the object that we want to create, e.g. SignedBeaconBlock and [2] is the version e.g. Altair, and use these initialization functions when creating an interface object from a protobuf object.

Other notes for review

Code extracted from #10799, tests added in this PR.

@rkapka rkapka requested a review from a team as a code owner June 7, 2022 12:33
// BeaconBlockIsNil checks if any composite field of input signed beacon block is nil.
// Access to these nil fields will result in run time panic,
// it is recommended to run these checks as first line of defense.
func BeaconBlockIsNil(b interfaces.SignedBeaconBlock) error {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This function does not have tests at the moment. This is because it takes an interface parameter and new types don't implement interfaces properly just yet. This will come in the next PR.

func (b *SignedBeaconBlock) SizeSSZ() int {
pb, err := b.Proto()
if err != nil {
panic(err)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

All panics will be converted to errors once we update fastssz to generate SizeSSZ (int, error)

Copy link
Member

Choose a reason for hiding this comment

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

b.Proto() can return an error if the inner block type is malformed for any reason. When do you expect the fast-ssz fix to be merged in ?

// BuildSignedBeaconBlock assembles a block.SignedBeaconBlock interface compatible struct from a
// given beacon block and the appropriate signature. This method may be used to easily create a
// signed beacon block.
func BuildSignedBeaconBlock(blk interfaces.BeaconBlock, signature []byte) (*SignedBeaconBlock, error) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Same comment as #10837 (comment)


// Header converts the underlying protobuf object from blinded block to header format.
func (b *SignedBeaconBlock) Header() (*eth.SignedBeaconBlockHeader, error) {
root, err := b.block.body.HashTreeRoot()
Copy link
Member

Choose a reason for hiding this comment

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

should do a nil check here before calling HTR

StateRoot: b.block.stateRoot,
BodyRoot: root[:],
},
Signature: b.Signature(),
Copy link
Member

Choose a reason for hiding this comment

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

no need to call the getter method if you already have access to the block struct

func (b *SignedBeaconBlock) SizeSSZ() int {
pb, err := b.Proto()
if err != nil {
panic(err)
Copy link
Member

Choose a reason for hiding this comment

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

b.Proto() can return an error if the inner block type is malformed for any reason. When do you expect the fast-ssz fix to be merged in ?


// ExecutionPayload returns the execution payload of the block body.
func (b *BeaconBlockBody) ExecutionPayload() (*enginev1.ExecutionPayload, error) {
if b.version == version.Phase0 || b.version == version.Altair || b.version == version.BellatrixBlind {
Copy link
Member

Choose a reason for hiding this comment

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

might be simpler to check for a negative ( version != Bellatrix)


// ExecutionPayloadHeader returns the execution payload header of the block body.
func (b *BeaconBlockBody) ExecutionPayloadHeader() (*eth.ExecutionPayloadHeader, error) {
if b.version == version.Phase0 || b.version == version.Altair || b.version == version.Bellatrix {
Copy link
Member

Choose a reason for hiding this comment

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

same concept here

return nil, errNilBlock
}

pb, ok := proto.Clone(pb).(*eth.SignedBeaconBlock)
Copy link
Member

Choose a reason for hiding this comment

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

what is the reason for doing a clone here, this is going to make unmarshalling blocks expensive on memory and cpu

return nil, errNilBlock
}

pb, ok := proto.Clone(pb).(*eth.SignedBeaconBlockBellatrix)
Copy link
Member

Choose a reason for hiding this comment

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

same here

return nil, errNilBlock
}

pb, ok := proto.Clone(pb).(*eth.BeaconBlock)
Copy link
Member

Choose a reason for hiding this comment

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

same principle here on cloning blocks


// Header converts the underlying protobuf object from blinded block to header format.
func (b *SignedBeaconBlock) Header() (*eth.SignedBeaconBlockHeader, error) {
if b.IsNil() || b.block.IsNil() {
Copy link
Member

Choose a reason for hiding this comment

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

lets add one more check for the body, since we are doing a htr of it below.

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 don't know why I changed the implementation of SignedBeaconBlock.IsNil. I reverted it back to what's in the current block code, which basically checks everything for nilness: signed block, block and block body.

@prylabs-bulldozer prylabs-bulldozer bot merged commit fce9e68 into develop Jun 9, 2022
@delete-merged-branch delete-merged-branch bot deleted the native-blocks-types branch June 9, 2022 13:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants