From f4ff0c07b8dcc85ad31916ae4c1e66ce576d4f53 Mon Sep 17 00:00:00 2001 From: terencechain Date: Tue, 13 Dec 2022 08:03:36 +0800 Subject: [PATCH] Add block setters for consensus type (#11751) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add block getters * Rm changes * Rm changes * Revert "Rm changes" This reverts commit 1ae5db79da2bd735b9a871c0768991c7ef7bac26. * Fix tests * Set graffiti right place * Potuz feedback * Update consensus-types/blocks/setters.go Co-authored-by: RadosÅ‚aw Kapka * Radek feedback * Fix comments Co-authored-by: RadosÅ‚aw Kapka --- consensus-types/blocks/BUILD.bazel | 1 + consensus-types/blocks/execution.go | 42 ++++- consensus-types/blocks/execution_test.go | 38 ++++ consensus-types/blocks/factory.go | 12 +- consensus-types/blocks/factory_test.go | 4 +- consensus-types/blocks/getters.go | 35 ++++ consensus-types/blocks/getters_test.go | 153 +++++++++++++--- consensus-types/blocks/setters.go | 173 ++++++++++++++++++ consensus-types/interfaces/beacon_block.go | 21 +++ consensus-types/mock/block.go | 72 ++++++++ .../payload-attribute/getters_test.go | 12 +- 11 files changed, 527 insertions(+), 36 deletions(-) create mode 100644 consensus-types/blocks/setters.go diff --git a/consensus-types/blocks/BUILD.bazel b/consensus-types/blocks/BUILD.bazel index 65eb34564cb0..15d3e9e1ffae 100644 --- a/consensus-types/blocks/BUILD.bazel +++ b/consensus-types/blocks/BUILD.bazel @@ -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", diff --git a/consensus-types/blocks/execution.go b/consensus-types/blocks/execution.go index 1a2731c756fe..84b5c6465387 100644 --- a/consensus-types/blocks/execution.go +++ b/consensus-types/blocks/execution.go @@ -155,6 +155,16 @@ func (e executionPayload) WithdrawalsRoot() ([]byte, error) { return nil, ErrUnsupportedGetter } +// PbBellatrix -- +func (e executionPayload) PbBellatrix() (*enginev1.ExecutionPayload, error) { + return e.p, nil +} + +// PbCapella -- +func (executionPayload) PbCapella() (*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. @@ -296,6 +306,16 @@ func (e executionPayloadHeader) WithdrawalsRoot() ([]byte, error) { return nil, ErrUnsupportedGetter } +// PbCapella -- +func (executionPayloadHeader) PbCapella() (*enginev1.ExecutionPayloadCapella, error) { + return nil, ErrUnsupportedGetter +} + +// PbBellatrix -- +func (executionPayloadHeader) PbBellatrix() (*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() @@ -465,6 +485,16 @@ func (e executionPayloadCapella) WithdrawalsRoot() ([]byte, error) { return nil, ErrUnsupportedGetter } +// PbCapella -- +func (e executionPayloadCapella) PbCapella() (*enginev1.ExecutionPayloadCapella, error) { + return e.p, nil +} + +// PbBellatrix -- +func (executionPayloadCapella) PbBellatrix() (*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. @@ -601,11 +631,21 @@ func (e executionPayloadHeaderCapella) Withdrawals() ([]*enginev1.Withdrawal, er return nil, ErrUnsupportedGetter } -// WitdrawalsRoot -- +// WithdrawalsRoot -- func (e executionPayloadHeaderCapella) WithdrawalsRoot() ([]byte, error) { return e.p.WithdrawalsRoot, nil } +// PbCapella -- +func (executionPayloadHeaderCapella) PbCapella() (*enginev1.ExecutionPayloadCapella, error) { + return nil, ErrUnsupportedGetter +} + +// PbBellatrix -- +func (executionPayloadHeaderCapella) PbBellatrix() (*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() diff --git a/consensus-types/blocks/execution_test.go b/consensus-types/blocks/execution_test.go index 0e1e6cf7d50b..1b09ff59927d 100644 --- a/consensus-types/blocks/execution_test.go +++ b/consensus-types/blocks/execution_test.go @@ -196,6 +196,44 @@ func TestWrapExecutionPayloadHeaderCapella_SSZ(t *testing.T) { assert.NoError(t, payload.UnmarshalSSZ(encoded)) } +func Test_executionPayload_Pb(t *testing.T) { + payload := createWrappedPayload(t) + pb, err := payload.PbBellatrix() + require.NoError(t, err) + assert.DeepEqual(t, payload.Proto(), pb) + + _, err = payload.PbCapella() + require.ErrorIs(t, err, blocks.ErrUnsupportedGetter) +} + +func Test_executionPayloadHeader_Pb(t *testing.T) { + payload := createWrappedPayloadHeader(t) + _, err := payload.PbBellatrix() + require.ErrorIs(t, err, blocks.ErrUnsupportedGetter) + + _, err = payload.PbCapella() + require.ErrorIs(t, err, blocks.ErrUnsupportedGetter) +} + +func Test_executionPayloadCapella_Pb(t *testing.T) { + payload := createWrappedPayloadCapella(t) + pb, err := payload.PbCapella() + require.NoError(t, err) + assert.DeepEqual(t, payload.Proto(), pb) + + _, err = payload.PbBellatrix() + require.ErrorIs(t, err, blocks.ErrUnsupportedGetter) +} + +func Test_executionPayloadHeaderCapella_Pb(t *testing.T) { + payload := createWrappedPayloadHeaderCapella(t) + _, err := payload.PbBellatrix() + require.ErrorIs(t, err, blocks.ErrUnsupportedGetter) + + _, err = payload.PbCapella() + require.ErrorIs(t, err, blocks.ErrUnsupportedGetter) +} + func createWrappedPayload(t testing.TB) interfaces.ExecutionData { wsb, err := blocks.WrappedExecutionPayload(&enginev1.ExecutionPayload{ ParentHash: make([]byte, fieldparams.RootLength), diff --git a/consensus-types/blocks/factory.go b/consensus-types/blocks/factory.go index eb595ea0e30f..346e5f0c6f56 100644 --- a/consensus-types/blocks/factory.go +++ b/consensus-types/blocks/factory.go @@ -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. @@ -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 diff --git a/consensus-types/blocks/factory_test.go b/consensus-types/blocks/factory_test.go index 8d80d2ff32c7..ca9eaf424878 100644 --- a/consensus-types/blocks/factory_test.go +++ b/consensus-types/blocks/factory_test.go @@ -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 := ð.SignedBeaconBlockAltair{ Block: ð.BeaconBlockAltair{ Body: ð.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) diff --git a/consensus-types/blocks/getters.go b/consensus-types/blocks/getters.go index ab0fa9b3e94b..6804a4499a82 100644 --- a/consensus-types/blocks/getters.go +++ b/consensus-types/blocks/getters.go @@ -731,6 +731,41 @@ func (b *BeaconBlock) AsSignRequestObject() (validatorpb.SignRequestObject, erro } } +func (b *BeaconBlock) Copy() (interfaces.BeaconBlock, error) { + 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 diff --git a/consensus-types/blocks/getters_test.go b/consensus-types/blocks/getters_test.go index edcb83ea1c68..0c12883afcb2 100644 --- a/consensus-types/blocks/getters_test.go +++ b/consensus-types/blocks/getters_test.go @@ -8,6 +8,7 @@ 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" @@ -15,6 +16,25 @@ import ( "github.com/prysmaticlabs/prysm/v3/testing/require" ) +func Test_SignedBeaconBlock_SetBlock(t *testing.T) { + b := ð.BeaconBlockCapella{Slot: 1, Body: ð.BeaconBlockBodyCapella{ExecutionPayload: &pb.ExecutionPayloadCapella{}}} + wb, err := NewBeaconBlock(b) + require.NoError(t, err) + wsb, err := NewSignedBeaconBlock(ð.SignedBeaconBlockCapella{ + Block: ð.BeaconBlockCapella{StateRoot: bytesutil.PadTo([]byte("stateroot"), 32), + ParentRoot: bytesutil.PadTo([]byte("parent"), 32), + Body: ð.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{}}})) @@ -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()) } @@ -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()) } @@ -163,6 +188,51 @@ func Test_BeaconBlock_Body(t *testing.T) { assert.Equal(t, bb, b.Body()) } +func Test_BeaconBlock_Copy(t *testing.T) { + bb := &BeaconBlockBody{randaoReveal: bytesutil.ToBytes96([]byte{246}), graffiti: bytesutil.ToBytes32([]byte("graffiti"))} + b := &BeaconBlock{body: bb, slot: 123, proposerIndex: 456, parentRoot: bytesutil.ToBytes32([]byte("parentroot")), stateRoot: bytesutil.ToBytes32([]byte("stateroot"))} + cp, err := b.Copy() + require.NoError(t, err) + assert.NotEqual(t, cp, b) + assert.NotEqual(t, cp.Body(), bb) + + b.version = version.Altair + b.body.version = b.version + cp, err = b.Copy() + require.NoError(t, err) + assert.NotEqual(t, cp, b) + assert.NotEqual(t, cp.Body(), bb) + + b.version = version.Bellatrix + b.body.version = b.version + cp, err = b.Copy() + require.NoError(t, err) + assert.NotEqual(t, cp, b) + assert.NotEqual(t, cp.Body(), bb) + + b.version = version.Capella + b.body.version = b.version + cp, err = b.Copy() + require.NoError(t, err) + assert.NotEqual(t, cp, b) + assert.NotEqual(t, cp.Body(), bb) + + b.version = version.Bellatrix + b.body.version = b.version + b.body.isBlinded = true + cp, err = b.Copy() + require.NoError(t, err) + assert.NotEqual(t, cp, b) + assert.NotEqual(t, cp.Body(), bb) + + b.version = version.Capella + b.body.version = b.version + cp, err = b.Copy() + require.NoError(t, err) + assert.NotEqual(t, cp, b) + assert.NotEqual(t, cp.Body(), bb) +} + func Test_BeaconBlock_IsNil(t *testing.T) { t.Run("nil block", func(t *testing.T) { var b *BeaconBlock @@ -179,8 +249,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) { @@ -256,67 +328,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 := ð.Eth1Data{} - bb := &BeaconBlockBody{eth1Data: e} - assert.Equal(t, e, bb.Eth1Data()) + e := ð.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 := ð.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: ð.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() diff --git a/consensus-types/blocks/setters.go b/consensus-types/blocks/setters.go new file mode 100644 index 000000000000..800af9f5d936 --- /dev/null +++ b/consensus-types/blocks/setters.go @@ -0,0 +1,173 @@ +package blocks + +import ( + "github.com/prysmaticlabs/prysm/v3/consensus-types/interfaces" + types "github.com/prysmaticlabs/prysm/v3/consensus-types/primitives" + eth "github.com/prysmaticlabs/prysm/v3/proto/prysm/v1alpha1" + "github.com/prysmaticlabs/prysm/v3/runtime/version" +) + +// SetSignature sets the signature of the signed beacon block. +// This function is not thread safe, it is only used during block creation. +func (b *SignedBeaconBlock) SetSignature(sig []byte) { + copy(b.signature[:], sig) +} + +// SetBlock sets the underlying beacon block object. +// This function is not thread safe, it is only used during block creation. +func (b *SignedBeaconBlock) SetBlock(blk interfaces.BeaconBlock) error { + copied, err := blk.Copy() + if err != nil { + return err + } + b.block.slot = copied.Slot() + b.block.parentRoot = copied.ParentRoot() + b.block.stateRoot = copied.StateRoot() + b.block.proposerIndex = copied.ProposerIndex() + b.block.body.randaoReveal = copied.Body().RandaoReveal() + b.block.body.eth1Data = copied.Body().Eth1Data() + b.block.body.graffiti = copied.Body().Graffiti() + b.block.body.proposerSlashings = copied.Body().ProposerSlashings() + b.block.body.attesterSlashings = copied.Body().AttesterSlashings() + b.block.body.attestations = copied.Body().Attestations() + b.block.body.deposits = copied.Body().Deposits() + b.block.body.voluntaryExits = copied.Body().VoluntaryExits() + if b.version >= version.Altair { + syncAggregate, err := copied.Body().SyncAggregate() + if err != nil { + return err + } + b.block.body.syncAggregate = syncAggregate + } + if b.version >= version.Bellatrix { + executionData, err := copied.Body().Execution() + if err != nil { + return err + } + if b.block.body.isBlinded { + b.block.body.executionPayloadHeader = executionData + } else { + b.block.body.executionPayload = executionData + } + } + if b.version >= version.Capella { + changes, err := copied.Body().BLSToExecutionChanges() + if err != nil { + return err + } + b.block.body.blsToExecutionChanges = changes + } + return nil +} + +// SetSlot sets the respective slot of the block. +// This function is not thread safe, it is only used during block creation. +func (b *BeaconBlock) SetSlot(slot types.Slot) { + b.slot = slot +} + +// SetProposerIndex sets the proposer index of the beacon block. +// This function is not thread safe, it is only used during block creation. +func (b *BeaconBlock) SetProposerIndex(proposerIndex types.ValidatorIndex) { + b.proposerIndex = proposerIndex +} + +// SetParentRoot sets the parent root of beacon block. +// This function is not thread safe, it is only used during block creation. +func (b *BeaconBlock) SetParentRoot(parentRoot []byte) { + copy(b.parentRoot[:], parentRoot) +} + +// SetStateRoot sets the state root of the underlying beacon block +// This function is not thread safe, it is only used during block creation. +func (b *BeaconBlock) SetStateRoot(root []byte) { + copy(b.stateRoot[:], root) +} + +// SetBlinded sets the blinded flag of the beacon block. +// This function is not thread safe, it is only used during block creation. +func (b *BeaconBlock) SetBlinded(blinded bool) { + b.body.isBlinded = blinded +} + +// SetRandaoReveal sets the randao reveal in the block body. +// This function is not thread safe, it is only used during block creation. +func (b *BeaconBlockBody) SetRandaoReveal(r []byte) { + copy(b.randaoReveal[:], r) +} + +// SetGraffiti sets the graffiti in the block. +// This function is not thread safe, it is only used during block creation. +func (b *BeaconBlockBody) SetGraffiti(g []byte) { + copy(b.graffiti[:], g) +} + +// SetEth1Data sets the eth1 data in the block. +// This function is not thread safe, it is only used during block creation. +func (b *BeaconBlockBody) SetEth1Data(e *eth.Eth1Data) { + b.eth1Data = eth.CopyETH1Data(e) +} + +// SetProposerSlashings sets the proposer slashings in the block. +// This function is not thread safe, it is only used during block creation. +func (b *BeaconBlockBody) SetProposerSlashings(p []*eth.ProposerSlashing) { + b.proposerSlashings = eth.CopyProposerSlashings(p) +} + +// SetAttesterSlashings sets the attester slashings in the block. +// This function is not thread safe, it is only used during block creation. +func (b *BeaconBlockBody) SetAttesterSlashings(a []*eth.AttesterSlashing) { + b.attesterSlashings = eth.CopyAttesterSlashings(a) +} + +// SetAttestations sets the attestations in the block. +// This function is not thread safe, it is only used during block creation. +func (b *BeaconBlockBody) SetAttestations(a []*eth.Attestation) { + b.attestations = eth.CopyAttestations(a) +} + +// SetDeposits sets the deposits in the block. +// This function is not thread safe, it is only used during block creation. +func (b *BeaconBlockBody) SetDeposits(d []*eth.Deposit) { + b.deposits = eth.CopyDeposits(d) +} + +// SetVoluntaryExits sets the voluntary exits in the block. +// This function is not thread safe, it is only used during block creation. +func (b *BeaconBlockBody) SetVoluntaryExits(v []*eth.SignedVoluntaryExit) { + b.voluntaryExits = eth.CopySignedVoluntaryExits(v) +} + +// SetSyncAggregate sets the sync aggregate in the block. +// This function is not thread safe, it is only used during block creation. +func (b *BeaconBlockBody) SetSyncAggregate(s *eth.SyncAggregate) error { + if b.version == version.Phase0 { + return ErrNotSupported("SyncAggregate", b.version) + } + b.syncAggregate = eth.CopySyncAggregate(s) + return nil +} + +// SetExecution sets the execution payload of the block body. +// This function is not thread safe, it is only used during block creation. +func (b *BeaconBlockBody) SetExecution(e interfaces.ExecutionData) error { + if b.version == version.Phase0 || b.version == version.Altair { + return ErrNotSupported("Execution", b.version) + } + if b.isBlinded { + b.executionPayloadHeader = e + return nil + } + b.executionPayload = e + return nil +} + +// SetBLSToExecutionChanges sets the BLS to execution changes in the block. +// This function is not thread safe, it is only used during block creation. +func (b *BeaconBlockBody) SetBLSToExecutionChanges(blsToExecutionChanges []*eth.SignedBLSToExecutionChange) error { + if b.version < version.Capella { + return ErrNotSupported("BLSToExecutionChanges", b.version) + } + b.blsToExecutionChanges = eth.CopyBLSToExecutionChanges(blsToExecutionChanges) + return nil +} diff --git a/consensus-types/interfaces/beacon_block.go b/consensus-types/interfaces/beacon_block.go index 85d934fd0f01..09413beea70e 100644 --- a/consensus-types/interfaces/beacon_block.go +++ b/consensus-types/interfaces/beacon_block.go @@ -14,7 +14,9 @@ import ( // a signed beacon block. type SignedBeaconBlock interface { Block() BeaconBlock + SetBlock(BeaconBlock) error Signature() [field_params.BLSSignatureLength]byte + SetSignature(sig []byte) IsNil() bool Copy() (SignedBeaconBlock, error) Proto() (proto.Message, error) @@ -37,12 +39,17 @@ type SignedBeaconBlock interface { // employed by an object that is a beacon block. type BeaconBlock interface { Slot() types.Slot + SetSlot(slot types.Slot) ProposerIndex() types.ValidatorIndex + SetProposerIndex(idx types.ValidatorIndex) ParentRoot() [field_params.RootLength]byte + SetParentRoot([]byte) StateRoot() [field_params.RootLength]byte + SetStateRoot([]byte) Body() BeaconBlockBody IsNil() bool IsBlinded() bool + SetBlinded(bool) HashTreeRoot() ([field_params.RootLength]byte, error) Proto() (proto.Message, error) ssz.Marshaler @@ -50,25 +57,37 @@ type BeaconBlock interface { ssz.HashRoot Version() int AsSignRequestObject() (validatorpb.SignRequestObject, error) + Copy() (BeaconBlock, error) } // BeaconBlockBody describes the method set employed by an object // that is a beacon block body. type BeaconBlockBody interface { RandaoReveal() [field_params.BLSSignatureLength]byte + SetRandaoReveal([]byte) Eth1Data() *ethpb.Eth1Data + SetEth1Data(*ethpb.Eth1Data) Graffiti() [field_params.RootLength]byte + SetGraffiti([]byte) ProposerSlashings() []*ethpb.ProposerSlashing + SetProposerSlashings([]*ethpb.ProposerSlashing) AttesterSlashings() []*ethpb.AttesterSlashing + SetAttesterSlashings([]*ethpb.AttesterSlashing) Attestations() []*ethpb.Attestation + SetAttestations([]*ethpb.Attestation) Deposits() []*ethpb.Deposit + SetDeposits([]*ethpb.Deposit) VoluntaryExits() []*ethpb.SignedVoluntaryExit + SetVoluntaryExits([]*ethpb.SignedVoluntaryExit) SyncAggregate() (*ethpb.SyncAggregate, error) + SetSyncAggregate(*ethpb.SyncAggregate) error IsNil() bool HashTreeRoot() ([field_params.RootLength]byte, error) Proto() (proto.Message, error) Execution() (ExecutionData, error) + SetExecution(ExecutionData) error BLSToExecutionChanges() ([]*ethpb.SignedBLSToExecutionChange, error) + SetBLSToExecutionChanges([]*ethpb.SignedBLSToExecutionChange) error } // ExecutionData represents execution layer information that is contained @@ -96,4 +115,6 @@ type ExecutionData interface { TransactionsRoot() ([]byte, error) Withdrawals() ([]*enginev1.Withdrawal, error) WithdrawalsRoot() ([]byte, error) + PbCapella() (*enginev1.ExecutionPayloadCapella, error) + PbBellatrix() (*enginev1.ExecutionPayload, error) } diff --git a/consensus-types/mock/block.go b/consensus-types/mock/block.go index 2761ac22372e..9162c599f24d 100644 --- a/consensus-types/mock/block.go +++ b/consensus-types/mock/block.go @@ -22,10 +22,18 @@ func (m SignedBeaconBlock) Block() interfaces.BeaconBlock { return m.BeaconBlock } +func (SignedBeaconBlock) SetBlock(interfaces.BeaconBlock) error { + panic("implement me") +} + func (SignedBeaconBlock) Signature() [field_params.BLSSignatureLength]byte { panic("implement me") } +func (SignedBeaconBlock) SetSignature([]byte) { + panic("implement me") +} + func (m SignedBeaconBlock) IsNil() bool { return m.BeaconBlock == nil || m.Block().IsNil() } @@ -105,6 +113,22 @@ func (BeaconBlock) AsSignRequestObject() (validatorpb.SignRequestObject, error) panic("implement me") } +func (BeaconBlock) Copy() (interfaces.BeaconBlock, error) { + panic("implement me") +} + +func (BeaconBlock) SetSlot(types.Slot) { + panic("implement me") +} + +func (BeaconBlock) SetProposerIndex(types.ValidatorIndex) { + panic("implement me") +} + +func (BeaconBlock) SetParentRoot([]byte) { + panic("implement me") +} + func (m BeaconBlock) HashTreeRoot() ([field_params.RootLength]byte, error) { return m.Htr, m.HtrErr } @@ -137,6 +161,10 @@ func (BeaconBlock) IsBlinded() bool { return false } +func (BeaconBlock) SetBlinded(bool) { + panic("implement me") +} + func (BeaconBlock) Proto() (proto.Message, error) { panic("implement me") } @@ -171,38 +199,74 @@ func (BeaconBlockBody) RandaoReveal() [field_params.BLSSignatureLength]byte { panic("implement me") } +func (BeaconBlockBody) SetRandaoReveal([]byte) { + panic("implement me") +} + func (BeaconBlockBody) Eth1Data() *eth.Eth1Data { panic("implement me") } +func (BeaconBlockBody) SetEth1Data(*eth.Eth1Data) { + panic("implement me") +} + func (BeaconBlockBody) Graffiti() [field_params.RootLength]byte { panic("implement me") } +func (BeaconBlockBody) SetGraffiti([]byte) { + panic("implement me") +} + func (BeaconBlockBody) ProposerSlashings() []*eth.ProposerSlashing { panic("implement me") } +func (BeaconBlockBody) SetProposerSlashings([]*eth.ProposerSlashing) { + panic("implement me") +} + func (BeaconBlockBody) AttesterSlashings() []*eth.AttesterSlashing { panic("implement me") } +func (BeaconBlockBody) SetAttesterSlashings([]*eth.AttesterSlashing) { + panic("implement me") +} + func (BeaconBlockBody) Attestations() []*eth.Attestation { panic("implement me") } +func (BeaconBlockBody) SetAttestations([]*eth.Attestation) { + panic("implement me") +} + func (BeaconBlockBody) Deposits() []*eth.Deposit { panic("implement me") } +func (BeaconBlockBody) SetDeposits([]*eth.Deposit) { + panic("implement me") +} + func (BeaconBlockBody) VoluntaryExits() []*eth.SignedVoluntaryExit { panic("implement me") } +func (BeaconBlockBody) SetVoluntaryExits([]*eth.SignedVoluntaryExit) { + panic("implement me") +} + func (BeaconBlockBody) SyncAggregate() (*eth.SyncAggregate, error) { panic("implement me") } +func (BeaconBlockBody) SetSyncAggregate(*eth.SyncAggregate) error { + panic("implement me") +} + func (BeaconBlockBody) IsNil() bool { return false } @@ -219,10 +283,18 @@ func (BeaconBlockBody) Execution() (interfaces.ExecutionData, error) { panic("implement me") } +func (BeaconBlockBody) SetExecution(interfaces.ExecutionData) error { + panic("implement me") +} + func (BeaconBlockBody) BLSToExecutionChanges() ([]*eth.SignedBLSToExecutionChange, error) { panic("implement me") } +func (BeaconBlockBody) SetBLSToExecutionChanges([]*eth.SignedBLSToExecutionChange) error { + panic("implement me") +} + func (b *BeaconBlock) SetStateRoot(root []byte) { panic("implement me") } diff --git a/consensus-types/payload-attribute/getters_test.go b/consensus-types/payload-attribute/getters_test.go index 09e08597b382..ea5ece102393 100644 --- a/consensus-types/payload-attribute/getters_test.go +++ b/consensus-types/payload-attribute/getters_test.go @@ -67,7 +67,7 @@ func TestPayloadAttributeGetters(t *testing.T) { }, }, { - name: "Get PbV1 (bad version)", + name: "Get PbBellatrix (bad version)", tc: func(t *testing.T) { a, err := New(&enginev1.PayloadAttributes{}) require.NoError(t, err) @@ -76,7 +76,7 @@ func TestPayloadAttributeGetters(t *testing.T) { }, }, { - name: "Get PbV2 (bad version)", + name: "Get PbCapella (bad version)", tc: func(t *testing.T) { a, err := New(&enginev1.PayloadAttributesV2{}) require.NoError(t, err) @@ -85,7 +85,7 @@ func TestPayloadAttributeGetters(t *testing.T) { }, }, { - name: "Get PbV1 (nil)", + name: "Get PbBellatrix (nil)", tc: func(t *testing.T) { a, err := New(&enginev1.PayloadAttributes{}) require.NoError(t, err) @@ -95,7 +95,7 @@ func TestPayloadAttributeGetters(t *testing.T) { }, }, { - name: "Get PbV2 (nil)", + name: "Get PbCapella (nil)", tc: func(t *testing.T) { a, err := New(&enginev1.PayloadAttributesV2{}) require.NoError(t, err) @@ -105,7 +105,7 @@ func TestPayloadAttributeGetters(t *testing.T) { }, }, { - name: "Get PbV1", + name: "Get PbBellatrix", tc: func(t *testing.T) { p := &enginev1.PayloadAttributes{ Timestamp: 1, @@ -120,7 +120,7 @@ func TestPayloadAttributeGetters(t *testing.T) { }, }, { - name: "Get PbV2", + name: "Get PbCapella", tc: func(t *testing.T) { p := &enginev1.PayloadAttributesV2{ Timestamp: 1,