Add and use SignedBeaconBlockWriteOnly (#11968)

This commit is contained in:
terencechain
2023-02-08 08:39:14 -08:00
committed by GitHub
parent 0d6e8718fd
commit e1f7c52e6b
19 changed files with 173 additions and 150 deletions

View File

@@ -28,7 +28,7 @@ var (
)
// NewSignedBeaconBlock creates a signed beacon block from a protobuf signed beacon block.
func NewSignedBeaconBlock(i interface{}) (interfaces.SignedBeaconBlock, error) {
func NewSignedBeaconBlock(i interface{}) (interfaces.SignedBeaconBlockWriteable, error) {
switch b := i.(type) {
case nil:
return nil, ErrNilObject
@@ -120,7 +120,7 @@ func NewBeaconBlockBody(i interface{}) (interfaces.BeaconBlockBody, error) {
// 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) (interfaces.SignedBeaconBlock, error) {
func BuildSignedBeaconBlock(blk interfaces.BeaconBlock, signature []byte) (interfaces.SignedBeaconBlockWriteable, error) {
pb, err := blk.Proto()
if err != nil {
return nil, err
@@ -174,7 +174,7 @@ func BuildSignedBeaconBlock(blk interfaces.BeaconBlock, signature []byte) (inter
// a full, signed beacon block by specifying an execution payload.
func BuildSignedBeaconBlockFromExecutionPayload(
blk interfaces.SignedBeaconBlock, payload interface{},
) (interfaces.SignedBeaconBlock, error) {
) (interfaces.SignedBeaconBlockWriteable, error) {
if err := BeaconBlockIsNil(blk); err != nil {
return nil, err
}

View File

@@ -140,27 +140,27 @@ func Test_SignedBeaconBlock_UnmarshalSSZ(t *testing.T) {
}
func Test_BeaconBlock_Slot(t *testing.T) {
b := &BeaconBlock{}
b := &SignedBeaconBlock{block: &BeaconBlock{}}
b.SetSlot(128)
assert.Equal(t, primitives.Slot(128), b.Slot())
assert.Equal(t, primitives.Slot(128), b.Block().Slot())
}
func Test_BeaconBlock_ProposerIndex(t *testing.T) {
b := &BeaconBlock{}
b := &SignedBeaconBlock{block: &BeaconBlock{}}
b.SetProposerIndex(128)
assert.Equal(t, primitives.ValidatorIndex(128), b.ProposerIndex())
assert.Equal(t, primitives.ValidatorIndex(128), b.Block().ProposerIndex())
}
func Test_BeaconBlock_ParentRoot(t *testing.T) {
b := &BeaconBlock{}
b := &SignedBeaconBlock{block: &BeaconBlock{}}
b.SetParentRoot([]byte("parentroot"))
assert.DeepEqual(t, bytesutil.ToBytes32([]byte("parentroot")), b.ParentRoot())
assert.DeepEqual(t, bytesutil.ToBytes32([]byte("parentroot")), b.Block().ParentRoot())
}
func Test_BeaconBlock_StateRoot(t *testing.T) {
b := &BeaconBlock{}
b := &SignedBeaconBlock{block: &BeaconBlock{}}
b.SetStateRoot([]byte("stateroot"))
assert.DeepEqual(t, bytesutil.ToBytes32([]byte("stateroot")), b.StateRoot())
assert.DeepEqual(t, bytesutil.ToBytes32([]byte("stateroot")), b.Block().StateRoot())
}
func Test_BeaconBlock_Body(t *testing.T) {
@@ -230,7 +230,7 @@ func Test_BeaconBlock_IsNil(t *testing.T) {
}
func Test_BeaconBlock_IsBlinded(t *testing.T) {
b := &BeaconBlock{body: &BeaconBlockBody{}}
b := &SignedBeaconBlock{block: &BeaconBlock{body: &BeaconBlockBody{}}}
assert.Equal(t, false, b.IsBlinded())
b.SetBlinded(true)
assert.Equal(t, true, b.IsBlinded())
@@ -309,73 +309,73 @@ func Test_BeaconBlockBody_IsNil(t *testing.T) {
}
func Test_BeaconBlockBody_RandaoReveal(t *testing.T) {
bb := &BeaconBlockBody{}
bb := &SignedBeaconBlock{block: &BeaconBlock{body: &BeaconBlockBody{}}}
bb.SetRandaoReveal([]byte("randaoreveal"))
assert.DeepEqual(t, bytesutil.ToBytes96([]byte("randaoreveal")), bb.RandaoReveal())
assert.DeepEqual(t, bytesutil.ToBytes96([]byte("randaoreveal")), bb.Block().Body().RandaoReveal())
}
func Test_BeaconBlockBody_Eth1Data(t *testing.T) {
e := &eth.Eth1Data{DepositRoot: []byte("depositroot")}
bb := &BeaconBlockBody{}
bb := &SignedBeaconBlock{block: &BeaconBlock{body: &BeaconBlockBody{}}}
bb.SetEth1Data(e)
assert.DeepEqual(t, e, bb.Eth1Data())
assert.DeepEqual(t, e, bb.Block().Body().Eth1Data())
}
func Test_BeaconBlockBody_Graffiti(t *testing.T) {
bb := &BeaconBlockBody{}
bb := &SignedBeaconBlock{block: &BeaconBlock{body: &BeaconBlockBody{}}}
bb.SetGraffiti([]byte("graffiti"))
assert.DeepEqual(t, bytesutil.ToBytes32([]byte("graffiti")), bb.Graffiti())
assert.DeepEqual(t, bytesutil.ToBytes32([]byte("graffiti")), bb.Block().Body().Graffiti())
}
func Test_BeaconBlockBody_ProposerSlashings(t *testing.T) {
ps := make([]*eth.ProposerSlashing, 0)
bb := &BeaconBlockBody{}
bb := &SignedBeaconBlock{block: &BeaconBlock{body: &BeaconBlockBody{}}}
bb.SetProposerSlashings(ps)
assert.DeepSSZEqual(t, ps, bb.ProposerSlashings())
assert.DeepSSZEqual(t, ps, bb.Block().Body().ProposerSlashings())
}
func Test_BeaconBlockBody_AttesterSlashings(t *testing.T) {
as := make([]*eth.AttesterSlashing, 0)
bb := &BeaconBlockBody{}
bb := &SignedBeaconBlock{block: &BeaconBlock{body: &BeaconBlockBody{}}}
bb.SetAttesterSlashings(as)
assert.DeepSSZEqual(t, as, bb.AttesterSlashings())
assert.DeepSSZEqual(t, as, bb.Block().Body().AttesterSlashings())
}
func Test_BeaconBlockBody_Attestations(t *testing.T) {
a := make([]*eth.Attestation, 0)
bb := &BeaconBlockBody{}
bb := &SignedBeaconBlock{block: &BeaconBlock{body: &BeaconBlockBody{}}}
bb.SetAttestations(a)
assert.DeepSSZEqual(t, a, bb.Attestations())
assert.DeepSSZEqual(t, a, bb.Block().Body().Attestations())
}
func Test_BeaconBlockBody_Deposits(t *testing.T) {
d := make([]*eth.Deposit, 0)
bb := &BeaconBlockBody{}
bb := &SignedBeaconBlock{block: &BeaconBlock{body: &BeaconBlockBody{}}}
bb.SetDeposits(d)
assert.DeepSSZEqual(t, d, bb.Deposits())
assert.DeepSSZEqual(t, d, bb.Block().Body().Deposits())
}
func Test_BeaconBlockBody_VoluntaryExits(t *testing.T) {
ve := make([]*eth.SignedVoluntaryExit, 0)
bb := &BeaconBlockBody{}
bb := &SignedBeaconBlock{block: &BeaconBlock{body: &BeaconBlockBody{}}}
bb.SetVoluntaryExits(ve)
assert.DeepSSZEqual(t, ve, bb.VoluntaryExits())
assert.DeepSSZEqual(t, ve, bb.Block().Body().VoluntaryExits())
}
func Test_BeaconBlockBody_SyncAggregate(t *testing.T) {
sa := &eth.SyncAggregate{}
bb := &BeaconBlockBody{version: version.Altair}
bb := &SignedBeaconBlock{version: version.Altair, block: &BeaconBlock{version: version.Altair, body: &BeaconBlockBody{version: version.Altair}}}
require.NoError(t, bb.SetSyncAggregate(sa))
result, err := bb.SyncAggregate()
result, err := bb.Block().Body().SyncAggregate()
require.NoError(t, err)
assert.DeepEqual(t, result, sa)
}
func Test_BeaconBlockBody_BLSToExecutionChanges(t *testing.T) {
changes := []*eth.SignedBLSToExecutionChange{{Message: &eth.BLSToExecutionChange{ToExecutionAddress: []byte("address")}}}
bb := &BeaconBlockBody{version: version.Capella}
bb := &SignedBeaconBlock{version: version.Capella, block: &BeaconBlock{body: &BeaconBlockBody{version: version.Capella}}}
require.NoError(t, bb.SetBLSToExecutionChanges(changes))
result, err := bb.BLSToExecutionChanges()
result, err := bb.Block().Body().BLSToExecutionChanges()
require.NoError(t, err)
assert.DeepSSZEqual(t, result, changes)
}
@@ -384,27 +384,27 @@ 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}
bb := &SignedBeaconBlock{version: version.Bellatrix, block: &BeaconBlock{body: &BeaconBlockBody{version: version.Bellatrix}}}
require.NoError(t, bb.SetExecution(e))
result, err := bb.Execution()
result, err := bb.Block().Body().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}
bb = &SignedBeaconBlock{version: version.Capella, block: &BeaconBlock{body: &BeaconBlockBody{version: version.Capella}}}
require.NoError(t, bb.SetExecution(eCapella))
result, err = bb.Execution()
result, err = bb.Block().Body().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}
bb = &SignedBeaconBlock{version: version.Capella, block: &BeaconBlock{version: version.Capella, body: &BeaconBlockBody{version: version.Capella, isBlinded: true}}}
require.NoError(t, bb.SetExecution(eCapellaHeader))
result, err = bb.Execution()
result, err = bb.Block().Body().Execution()
require.NoError(t, err)
assert.DeepEqual(t, result, eCapellaHeader)
}

View File

@@ -15,112 +15,112 @@ func (b *SignedBeaconBlock) SetSignature(sig []byte) {
// 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 primitives.Slot) {
b.slot = slot
func (b *SignedBeaconBlock) SetSlot(slot primitives.Slot) {
b.block.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 primitives.ValidatorIndex) {
b.proposerIndex = proposerIndex
func (b *SignedBeaconBlock) SetProposerIndex(proposerIndex primitives.ValidatorIndex) {
b.block.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)
func (b *SignedBeaconBlock) SetParentRoot(parentRoot []byte) {
copy(b.block.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)
func (b *SignedBeaconBlock) SetStateRoot(root []byte) {
copy(b.block.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
func (b *SignedBeaconBlock) SetBlinded(blinded bool) {
b.block.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)
func (b *SignedBeaconBlock) SetRandaoReveal(r []byte) {
copy(b.block.body.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)
func (b *SignedBeaconBlock) SetGraffiti(g []byte) {
copy(b.block.body.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 = e
func (b *SignedBeaconBlock) SetEth1Data(e *eth.Eth1Data) {
b.block.body.eth1Data = 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 = p
func (b *SignedBeaconBlock) SetProposerSlashings(p []*eth.ProposerSlashing) {
b.block.body.proposerSlashings = 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 = a
func (b *SignedBeaconBlock) SetAttesterSlashings(a []*eth.AttesterSlashing) {
b.block.body.attesterSlashings = 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 = a
func (b *SignedBeaconBlock) SetAttestations(a []*eth.Attestation) {
b.block.body.attestations = 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 = d
func (b *SignedBeaconBlock) SetDeposits(d []*eth.Deposit) {
b.block.body.deposits = 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 = v
func (b *SignedBeaconBlock) SetVoluntaryExits(v []*eth.SignedVoluntaryExit) {
b.block.body.voluntaryExits = 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 {
func (b *SignedBeaconBlock) SetSyncAggregate(s *eth.SyncAggregate) error {
if b.version == version.Phase0 {
return ErrNotSupported("SyncAggregate", b.version)
}
b.syncAggregate = s
b.block.body.syncAggregate = 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 {
func (b *SignedBeaconBlock) 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
if b.block.body.isBlinded {
b.block.body.executionPayloadHeader = e
return nil
}
b.executionPayload = e
b.block.body.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 {
func (b *SignedBeaconBlock) SetBLSToExecutionChanges(blsToExecutionChanges []*eth.SignedBLSToExecutionChange) error {
if b.version < version.Capella {
return ErrNotSupported("BLSToExecutionChanges", b.version)
}
b.blsToExecutionChanges = blsToExecutionChanges
b.block.body.blsToExecutionChanges = blsToExecutionChanges
return nil
}

View File

@@ -15,7 +15,7 @@ type blockMutator struct {
Capella func(beaconBlock *eth.SignedBeaconBlockCapella)
}
func (m blockMutator) apply(b interfaces.SignedBeaconBlock) (interfaces.SignedBeaconBlock, error) {
func (m blockMutator) apply(b interfaces.SignedBeaconBlockWriteable) (interfaces.SignedBeaconBlockWriteable, error) {
switch b.Version() {
case version.Phase0:
bb, err := b.PbPhase0Block()
@@ -51,7 +51,7 @@ func (m blockMutator) apply(b interfaces.SignedBeaconBlock) (interfaces.SignedBe
}
// SetBlockStateRoot modifies the block's state root.
func SetBlockStateRoot(b interfaces.SignedBeaconBlock, sr [32]byte) (interfaces.SignedBeaconBlock, error) {
func SetBlockStateRoot(b interfaces.SignedBeaconBlockWriteable, sr [32]byte) (interfaces.SignedBeaconBlockWriteable, error) {
return blockMutator{
Phase0: func(bb *eth.SignedBeaconBlock) { bb.Block.StateRoot = sr[:] },
Altair: func(bb *eth.SignedBeaconBlockAltair) { bb.Block.StateRoot = sr[:] },
@@ -61,7 +61,7 @@ func SetBlockStateRoot(b interfaces.SignedBeaconBlock, sr [32]byte) (interfaces.
}
// SetBlockParentRoot modifies the block's parent root.
func SetBlockParentRoot(b interfaces.SignedBeaconBlock, pr [32]byte) (interfaces.SignedBeaconBlock, error) {
func SetBlockParentRoot(b interfaces.SignedBeaconBlockWriteable, pr [32]byte) (interfaces.SignedBeaconBlockWriteable, error) {
return blockMutator{
Phase0: func(bb *eth.SignedBeaconBlock) { bb.Block.ParentRoot = pr[:] },
Altair: func(bb *eth.SignedBeaconBlockAltair) { bb.Block.ParentRoot = pr[:] },
@@ -71,7 +71,7 @@ func SetBlockParentRoot(b interfaces.SignedBeaconBlock, pr [32]byte) (interfaces
}
// SetBlockSlot modifies the block's slot.
func SetBlockSlot(b interfaces.SignedBeaconBlock, s primitives.Slot) (interfaces.SignedBeaconBlock, error) {
func SetBlockSlot(b interfaces.SignedBeaconBlockWriteable, s primitives.Slot) (interfaces.SignedBeaconBlockWriteable, error) {
return blockMutator{
Phase0: func(bb *eth.SignedBeaconBlock) { bb.Block.Slot = s },
Altair: func(bb *eth.SignedBeaconBlockAltair) { bb.Block.Slot = s },
@@ -81,7 +81,7 @@ func SetBlockSlot(b interfaces.SignedBeaconBlock, s primitives.Slot) (interfaces
}
// SetProposerIndex modifies the block's proposer index.
func SetProposerIndex(b interfaces.SignedBeaconBlock, idx primitives.ValidatorIndex) (interfaces.SignedBeaconBlock, error) {
func SetProposerIndex(b interfaces.SignedBeaconBlockWriteable, idx primitives.ValidatorIndex) (interfaces.SignedBeaconBlockWriteable, error) {
return blockMutator{
Phase0: func(bb *eth.SignedBeaconBlock) { bb.Block.ProposerIndex = idx },
Altair: func(bb *eth.SignedBeaconBlockAltair) { bb.Block.ProposerIndex = idx },

View File

@@ -15,7 +15,6 @@ import (
type SignedBeaconBlock interface {
Block() BeaconBlock
Signature() [field_params.BLSSignatureLength]byte
SetSignature(sig []byte)
IsNil() bool
Copy() (SignedBeaconBlock, error)
Proto() (proto.Message, error)
@@ -38,17 +37,12 @@ type SignedBeaconBlock interface {
// employed by an object that is a beacon block.
type BeaconBlock interface {
Slot() primitives.Slot
SetSlot(slot primitives.Slot)
ProposerIndex() primitives.ValidatorIndex
SetProposerIndex(idx primitives.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
@@ -63,30 +57,40 @@ type BeaconBlock interface {
// 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)
}
type SignedBeaconBlockWriteable interface {
SignedBeaconBlock
SetExecution(ExecutionData) error
SetBLSToExecutionChanges([]*ethpb.SignedBLSToExecutionChange) error
SetSyncAggregate(*ethpb.SyncAggregate) error
SetVoluntaryExits([]*ethpb.SignedVoluntaryExit)
SetDeposits([]*ethpb.Deposit)
SetAttestations([]*ethpb.Attestation)
SetAttesterSlashings([]*ethpb.AttesterSlashing)
SetProposerSlashings([]*ethpb.ProposerSlashing)
SetGraffiti([]byte)
SetEth1Data(*ethpb.Eth1Data)
SetRandaoReveal([]byte)
SetBlinded(bool)
SetStateRoot([]byte)
SetParentRoot([]byte)
SetProposerIndex(idx primitives.ValidatorIndex)
SetSlot(slot primitives.Slot)
SetSignature(sig []byte)
}
// ExecutionData represents execution layer information that is contained