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

Add block setters for consensus type #11751

Merged
merged 13 commits into from
Dec 13, 2022
1 change: 1 addition & 0 deletions consensus-types/blocks/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ go_library(
"factory.go",
"getters.go",
"proto.go",
"setters.go",
"types.go",
],
importpath = "github.com/prysmaticlabs/prysm/v3/consensus-types/blocks",
Expand Down
40 changes: 40 additions & 0 deletions consensus-types/blocks/execution.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,16 @@ func (e executionPayload) WithdrawalsRoot() ([]byte, error) {
return nil, ErrUnsupportedGetter
}

// PbV1 --
func (e executionPayload) PbV1() (*enginev1.ExecutionPayload, error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

All these PbVx from the different targets are not tested.

Copy link
Contributor

@rkapka rkapka Dec 12, 2022

Choose a reason for hiding this comment

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

Do we really want to name things PbV1/PbV2 instead of Pb/PbCapella or PbBellatrix/PbCapella? It might be misleading because all protobufs are under the enginev1 package. I understand this convention comes from the builder API?

return e.p, nil
}

// PbV2 --
func (executionPayload) PbV2() (*enginev1.ExecutionPayloadCapella, error) {
return nil, ErrUnsupportedGetter
}

// executionPayloadHeader is a convenience wrapper around a blinded beacon block body's execution header data structure
// This wrapper allows us to conform to a common interface so that beacon
// blocks for future forks can also be applied across Prysm without issues.
Expand Down Expand Up @@ -296,6 +306,16 @@ func (e executionPayloadHeader) WithdrawalsRoot() ([]byte, error) {
return nil, ErrUnsupportedGetter
}

// PbV2 --
func (executionPayloadHeader) PbV2() (*enginev1.ExecutionPayloadCapella, error) {
return nil, ErrUnsupportedGetter
}

// PbV1 --
func (executionPayloadHeader) PbV1() (*enginev1.ExecutionPayload, error) {
return nil, ErrUnsupportedGetter
}

// PayloadToHeader converts `payload` into execution payload header format.
func PayloadToHeader(payload interfaces.ExecutionData) (*enginev1.ExecutionPayloadHeader, error) {
txs, err := payload.Transactions()
Expand Down Expand Up @@ -465,6 +485,16 @@ func (e executionPayloadCapella) WithdrawalsRoot() ([]byte, error) {
return nil, ErrUnsupportedGetter
}

// PbV2 --
func (e executionPayloadCapella) PbV2() (*enginev1.ExecutionPayloadCapella, error) {
return e.p, nil
}

// PbV1 --
func (executionPayloadCapella) PbV1() (*enginev1.ExecutionPayload, error) {
return nil, ErrUnsupportedGetter
}

// executionPayloadHeaderCapella is a convenience wrapper around a blinded beacon block body's execution header data structure
// This wrapper allows us to conform to a common interface so that beacon
// blocks for future forks can also be applied across Prysm without issues.
Expand Down Expand Up @@ -606,6 +636,16 @@ func (e executionPayloadHeaderCapella) WithdrawalsRoot() ([]byte, error) {
return e.p.WithdrawalsRoot, nil
}

// PbV2 --
func (executionPayloadHeaderCapella) PbV2() (*enginev1.ExecutionPayloadCapella, error) {
return nil, ErrUnsupportedGetter
}

// PbV1 --
func (executionPayloadHeaderCapella) PbV1() (*enginev1.ExecutionPayload, error) {
return nil, ErrUnsupportedGetter
}

// PayloadToHeaderCapella converts `payload` into execution payload header format.
func PayloadToHeaderCapella(payload interfaces.ExecutionData) (*enginev1.ExecutionPayloadHeaderCapella, error) {
txs, err := payload.Transactions()
Expand Down
12 changes: 6 additions & 6 deletions consensus-types/blocks/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ var (
// ErrNilObject is returned in a constructor when the underlying object is nil.
ErrNilObject = errors.New("received nil object")
// ErrNilSignedBeaconBlock is returned when a nil signed beacon block is received.
ErrNilSignedBeaconBlock = errors.New("signed beacon block can't be nil")
ErrNilSignedBeaconBlock = errors.New("signed beacon block can't be nil")
errNonBlindedSignedBeaconBlock = errors.New("can only build signed beacon block from blinded format")
)

// NewSignedBeaconBlock creates a signed beacon block from a protobuf signed beacon block.
Expand Down Expand Up @@ -177,14 +178,13 @@ func BuildSignedBeaconBlockFromExecutionPayload(
if err := BeaconBlockIsNil(blk); err != nil {
return nil, err
}
if !blk.IsBlinded() {
return nil, errNonBlindedSignedBeaconBlock
}
b := blk.Block()
payloadHeader, err := b.Body().Execution()
switch {
case errors.Is(err, ErrUnsupportedGetter):
return nil, errors.Wrap(err, "can only build signed beacon block from blinded format")
case err != nil:
if err != nil {
return nil, errors.Wrap(err, "could not get execution payload header")
default:
}

var wrappedPayload interfaces.ExecutionData
Expand Down
4 changes: 2 additions & 2 deletions consensus-types/blocks/factory_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -332,14 +332,14 @@ func TestBuildSignedBeaconBlockFromExecutionPayload(t *testing.T) {
_, err := BuildSignedBeaconBlockFromExecutionPayload(nil, nil)
require.ErrorIs(t, ErrNilSignedBeaconBlock, err)
})
t.Run("unsupported field payload header", func(t *testing.T) {
t.Run("not blinded payload", func(t *testing.T) {
altairBlock := &eth.SignedBeaconBlockAltair{
Block: &eth.BeaconBlockAltair{
Body: &eth.BeaconBlockBodyAltair{}}}
blk, err := NewSignedBeaconBlock(altairBlock)
require.NoError(t, err)
_, err = BuildSignedBeaconBlockFromExecutionPayload(blk, nil)
require.Equal(t, true, errors.Is(err, ErrUnsupportedGetter))
require.Equal(t, true, errors.Is(err, errNonBlindedSignedBeaconBlock))
})
t.Run("payload header root and payload root mismatch", func(t *testing.T) {
blockHash := bytesutil.Bytes32(1)
Expand Down
40 changes: 40 additions & 0 deletions consensus-types/blocks/getters.go
Original file line number Diff line number Diff line change
Expand Up @@ -731,6 +731,41 @@ func (b *BeaconBlock) AsSignRequestObject() (validatorpb.SignRequestObject, erro
}
}

func (b *BeaconBlock) Copy() (interfaces.BeaconBlock, error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This is not tested

if b == nil {
return nil, nil
}

pb, err := b.Proto()
if err != nil {
return nil, err
}
switch b.version {
case version.Phase0:
cp := eth.CopyBeaconBlock(pb.(*eth.BeaconBlock))
return initBlockFromProtoPhase0(cp)
case version.Altair:
cp := eth.CopyBeaconBlockAltair(pb.(*eth.BeaconBlockAltair))
return initBlockFromProtoAltair(cp)
case version.Bellatrix:
if b.IsBlinded() {
cp := eth.CopyBlindedBeaconBlockBellatrix(pb.(*eth.BlindedBeaconBlockBellatrix))
return initBlindedBlockFromProtoBellatrix(cp)
}
cp := eth.CopyBeaconBlockBellatrix(pb.(*eth.BeaconBlockBellatrix))
return initBlockFromProtoBellatrix(cp)
case version.Capella:
if b.IsBlinded() {
cp := eth.CopyBlindedBeaconBlockCapella(pb.(*eth.BlindedBeaconBlockCapella))
return initBlindedBlockFromProtoCapella(cp)
}
cp := eth.CopyBeaconBlockCapella(pb.(*eth.BeaconBlockCapella))
return initBlockFromProtoCapella(cp)
default:
return nil, errIncorrectBlockVersion
}
}

// IsNil checks if the block body is nil.
func (b *BeaconBlockBody) IsNil() bool {
return b == nil
Expand All @@ -751,6 +786,11 @@ func (b *BeaconBlockBody) Graffiti() [field_params.RootLength]byte {
return b.graffiti
}

// SetGraffiti sets the graffiti in the block.
func (b *BeaconBlockBody) SetGraffiti(g []byte) {
Copy link
Member

Choose a reason for hiding this comment

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

this isnt a getter

copy(b.graffiti[:], g)
}

// ProposerSlashings returns the proposer slashings in the block.
func (b *BeaconBlockBody) ProposerSlashings() []*eth.ProposerSlashing {
return b.proposerSlashings
Expand Down
108 changes: 87 additions & 21 deletions consensus-types/blocks/getters_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,33 @@ import (
"github.com/prysmaticlabs/prysm/v3/consensus-types/interfaces"
types "github.com/prysmaticlabs/prysm/v3/consensus-types/primitives"
"github.com/prysmaticlabs/prysm/v3/encoding/bytesutil"
pb "github.com/prysmaticlabs/prysm/v3/proto/engine/v1"
eth "github.com/prysmaticlabs/prysm/v3/proto/prysm/v1alpha1"
validatorpb "github.com/prysmaticlabs/prysm/v3/proto/prysm/v1alpha1/validator-client"
"github.com/prysmaticlabs/prysm/v3/runtime/version"
"github.com/prysmaticlabs/prysm/v3/testing/assert"
"github.com/prysmaticlabs/prysm/v3/testing/require"
)

func Test_SignedBeaconBlock_SetBlock(t *testing.T) {
b := &eth.BeaconBlockCapella{Slot: 1, Body: &eth.BeaconBlockBodyCapella{ExecutionPayload: &pb.ExecutionPayloadCapella{}}}
wb, err := NewBeaconBlock(b)
require.NoError(t, err)
wsb, err := NewSignedBeaconBlock(&eth.SignedBeaconBlockCapella{
Block: &eth.BeaconBlockCapella{StateRoot: bytesutil.PadTo([]byte("stateroot"), 32),
ParentRoot: bytesutil.PadTo([]byte("parent"), 32),
Body: &eth.BeaconBlockBodyCapella{
RandaoReveal: make([]byte, fieldparams.BLSSignatureLength),
Graffiti: make([]byte, fieldparams.RootLength),
ExecutionPayload: &pb.ExecutionPayloadCapella{},
}},
Signature: make([]byte, fieldparams.BLSSignatureLength),
})
require.NoError(t, err)
require.NoError(t, wsb.SetBlock(wb))
require.DeepEqual(t, wsb.Block(), wb)
}

func Test_BeaconBlockIsNil(t *testing.T) {
t.Run("not nil", func(t *testing.T) {
assert.NoError(t, BeaconBlockIsNil(&SignedBeaconBlock{block: &BeaconBlock{body: &BeaconBlockBody{}}}))
Expand All @@ -41,7 +61,8 @@ func Test_BeaconBlockIsNil(t *testing.T) {
}

func Test_SignedBeaconBlock_Signature(t *testing.T) {
sb := &SignedBeaconBlock{signature: bytesutil.ToBytes96([]byte("signature"))}
sb := &SignedBeaconBlock{}
sb.SetSignature([]byte("signature"))
assert.DeepEqual(t, bytesutil.ToBytes96([]byte("signature")), sb.Signature())
}

Expand Down Expand Up @@ -138,22 +159,26 @@ func Test_SignedBeaconBlock_UnmarshalSSZ(t *testing.T) {
}

func Test_BeaconBlock_Slot(t *testing.T) {
b := &BeaconBlock{slot: 128}
b := &BeaconBlock{}
b.SetSlot(128)
assert.Equal(t, types.Slot(128), b.Slot())
}

func Test_BeaconBlock_ProposerIndex(t *testing.T) {
b := &BeaconBlock{proposerIndex: 128}
b := &BeaconBlock{}
b.SetProposerIndex(128)
assert.Equal(t, types.ValidatorIndex(128), b.ProposerIndex())
}

func Test_BeaconBlock_ParentRoot(t *testing.T) {
b := &BeaconBlock{parentRoot: bytesutil.ToBytes32([]byte("parentroot"))}
b := &BeaconBlock{}
b.SetParentRoot([]byte("parentroot"))
assert.DeepEqual(t, bytesutil.ToBytes32([]byte("parentroot")), b.ParentRoot())
}

func Test_BeaconBlock_StateRoot(t *testing.T) {
b := &BeaconBlock{stateRoot: bytesutil.ToBytes32([]byte("stateroot"))}
b := &BeaconBlock{}
b.SetStateRoot([]byte("stateroot"))
assert.DeepEqual(t, bytesutil.ToBytes32([]byte("stateroot")), b.StateRoot())
}

Expand All @@ -179,8 +204,10 @@ func Test_BeaconBlock_IsNil(t *testing.T) {
}

func Test_BeaconBlock_IsBlinded(t *testing.T) {
assert.Equal(t, false, (&BeaconBlock{body: &BeaconBlockBody{isBlinded: false}}).IsBlinded())
assert.Equal(t, true, (&BeaconBlock{body: &BeaconBlockBody{isBlinded: true}}).IsBlinded())
b := &BeaconBlock{body: &BeaconBlockBody{}}
assert.Equal(t, false, b.IsBlinded())
b.SetBlinded(true)
assert.Equal(t, true, b.IsBlinded())
}

func Test_BeaconBlock_Version(t *testing.T) {
Expand Down Expand Up @@ -256,67 +283,106 @@ func Test_BeaconBlockBody_IsNil(t *testing.T) {
}

func Test_BeaconBlockBody_RandaoReveal(t *testing.T) {
bb := &BeaconBlockBody{randaoReveal: bytesutil.ToBytes96([]byte("randaoreveal"))}
bb := &BeaconBlockBody{}
bb.SetRandaoReveal([]byte("randaoreveal"))
assert.DeepEqual(t, bytesutil.ToBytes96([]byte("randaoreveal")), bb.RandaoReveal())
}

func Test_BeaconBlockBody_Eth1Data(t *testing.T) {
e := &eth.Eth1Data{}
bb := &BeaconBlockBody{eth1Data: e}
assert.Equal(t, e, bb.Eth1Data())
e := &eth.Eth1Data{DepositRoot: []byte("depositroot")}
bb := &BeaconBlockBody{}
bb.SetEth1Data(e)
assert.DeepEqual(t, e, bb.Eth1Data())
}

func Test_BeaconBlockBody_Graffiti(t *testing.T) {
bb := &BeaconBlockBody{graffiti: bytesutil.ToBytes32([]byte("graffiti"))}
bb := &BeaconBlockBody{}
bb.SetGraffiti([]byte("graffiti"))
assert.DeepEqual(t, bytesutil.ToBytes32([]byte("graffiti")), bb.Graffiti())
}

func Test_BeaconBlockBody_ProposerSlashings(t *testing.T) {
ps := make([]*eth.ProposerSlashing, 0)
bb := &BeaconBlockBody{proposerSlashings: ps}
bb := &BeaconBlockBody{}
bb.SetProposerSlashings(ps)
assert.DeepSSZEqual(t, ps, bb.ProposerSlashings())
}

func Test_BeaconBlockBody_AttesterSlashings(t *testing.T) {
as := make([]*eth.AttesterSlashing, 0)
bb := &BeaconBlockBody{attesterSlashings: as}
bb := &BeaconBlockBody{}
bb.SetAttesterSlashings(as)
assert.DeepSSZEqual(t, as, bb.AttesterSlashings())
}

func Test_BeaconBlockBody_Attestations(t *testing.T) {
a := make([]*eth.Attestation, 0)
bb := &BeaconBlockBody{attestations: a}
bb := &BeaconBlockBody{}
bb.SetAttestations(a)
assert.DeepSSZEqual(t, a, bb.Attestations())
}

func Test_BeaconBlockBody_Deposits(t *testing.T) {
d := make([]*eth.Deposit, 0)
bb := &BeaconBlockBody{deposits: d}
bb := &BeaconBlockBody{}
bb.SetDeposits(d)
assert.DeepSSZEqual(t, d, bb.Deposits())
}

func Test_BeaconBlockBody_VoluntaryExits(t *testing.T) {
ve := make([]*eth.SignedVoluntaryExit, 0)
bb := &BeaconBlockBody{voluntaryExits: ve}
bb := &BeaconBlockBody{}
bb.SetVoluntaryExits(ve)
assert.DeepSSZEqual(t, ve, bb.VoluntaryExits())
}

func Test_BeaconBlockBody_SyncAggregate(t *testing.T) {
sa := &eth.SyncAggregate{}
bb := &BeaconBlockBody{version: version.Altair, syncAggregate: sa}
bb := &BeaconBlockBody{version: version.Altair}
require.NoError(t, bb.SetSyncAggregate(sa))
result, err := bb.SyncAggregate()
require.NoError(t, err)
assert.Equal(t, result, sa)
assert.DeepEqual(t, result, sa)
}

func Test_BeaconBlockBody_BLSToExecutionChanges(t *testing.T) {
changes := []*eth.SignedBLSToExecutionChange{{}}
bb := &BeaconBlockBody{version: version.Capella, blsToExecutionChanges: changes}
changes := []*eth.SignedBLSToExecutionChange{{Message: &eth.BLSToExecutionChange{ToExecutionAddress: []byte("address")}}}
bb := &BeaconBlockBody{version: version.Capella}
require.NoError(t, bb.SetBLSToExecutionChanges(changes))
result, err := bb.BLSToExecutionChanges()
require.NoError(t, err)
assert.DeepSSZEqual(t, result, changes)
}

func Test_BeaconBlockBody_Execution(t *testing.T) {
execution := &pb.ExecutionPayload{BlockNumber: 1}
e, err := WrappedExecutionPayload(execution)
require.NoError(t, err)
bb := &BeaconBlockBody{version: version.Bellatrix}
require.NoError(t, bb.SetExecution(e))
result, err := bb.Execution()
require.NoError(t, err)
assert.DeepEqual(t, result, e)

executionCapella := &pb.ExecutionPayloadCapella{BlockNumber: 1}
eCapella, err := WrappedExecutionPayloadCapella(executionCapella)
require.NoError(t, err)
bb = &BeaconBlockBody{version: version.Capella}
require.NoError(t, bb.SetExecution(eCapella))
result, err = bb.Execution()
require.NoError(t, err)
assert.DeepEqual(t, result, eCapella)

executionCapellaHeader := &pb.ExecutionPayloadHeaderCapella{BlockNumber: 1}
eCapellaHeader, err := WrappedExecutionPayloadHeaderCapella(executionCapellaHeader)
require.NoError(t, err)
bb = &BeaconBlockBody{version: version.Capella, isBlinded: true}
require.NoError(t, bb.SetExecution(eCapellaHeader))
result, err = bb.Execution()
require.NoError(t, err)
assert.DeepEqual(t, result, eCapellaHeader)
}

func Test_BeaconBlockBody_HashTreeRoot(t *testing.T) {
pb := hydrateBeaconBlockBody()
expectedHTR, err := pb.HashTreeRoot()
Expand Down
Loading