Move Consensus Type Wrappers Into Consensus Types Package (#10598)

* builds

* move block to consensus-types

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
This commit is contained in:
Raul Jordan
2022-05-02 15:43:40 +00:00
committed by GitHub
parent f9113dfd06
commit 16bbf5602f
287 changed files with 379 additions and 378 deletions

View File

@@ -0,0 +1,52 @@
load("@prysm//tools/go:def.bzl", "go_library", "go_test")
go_library(
name = "go_default_library",
srcs = [
"beacon_block.go",
"beacon_block_altair.go",
"beacon_block_bellatrix.go",
"beacon_block_phase0.go",
"blinded_beacon_block_bellatrix.go",
"metadata.go",
"mutator.go",
],
importpath = "github.com/prysmaticlabs/prysm/consensus-types/wrapper",
visibility = ["//visibility:public"],
deps = [
"//consensus-types/block:go_default_library",
"//consensus-types/primitives:go_default_library",
"//proto/engine/v1:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
"//proto/prysm/v1alpha1/metadata:go_default_library",
"//proto/prysm/v1alpha1/validator-client:go_default_library",
"//runtime/version:go_default_library",
"@com_github_ferranbt_fastssz//:go_default_library",
"@com_github_pkg_errors//:go_default_library",
"@com_github_prysmaticlabs_go_bitfield//:go_default_library",
"@org_golang_google_protobuf//proto:go_default_library",
],
)
go_test(
name = "go_default_test",
srcs = [
"beacon_block_altair_test.go",
"beacon_block_bellatrix_test.go",
"beacon_block_phase0_test.go",
"beacon_block_test.go",
"blinded_beacon_block_bellatrix_test.go",
],
deps = [
":go_default_library",
"//consensus-types/primitives:go_default_library",
"//encoding/bytesutil:go_default_library",
"//proto/engine/v1:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
"//proto/prysm/v1alpha1/validator-client:go_default_library",
"//runtime/version:go_default_library",
"//testing/assert:go_default_library",
"//testing/require:go_default_library",
"//testing/util:go_default_library",
],
)

View File

@@ -0,0 +1,137 @@
package wrapper
import (
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/consensus-types/block"
eth "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
)
var (
// ErrUnsupportedField is returned when a field is not supported by a specific beacon block type.
// This allows us to create a generic beacon block interface that is implemented by different
// fork versions of beacon blocks.
ErrUnsupportedField = errors.New("unsupported field for block type")
// ErrUnsupportedSignedBeaconBlock is returned when the struct type is not a supported signed
// beacon block type.
ErrUnsupportedSignedBeaconBlock = errors.New("unsupported signed beacon block")
// ErrUnsupportedBeaconBlock is returned when the struct type is not a supported beacon block
// type.
ErrUnsupportedBeaconBlock = errors.New("unsupported beacon block")
// ErrUnsupportedPhase0Block is returned when accessing a phase0 block from a non-phase0 wrapped
// block.
ErrUnsupportedPhase0Block = errors.New("unsupported phase0 block")
// ErrUnsupportedAltairBlock is returned when accessing an altair block from non-altair wrapped
// block.
ErrUnsupportedAltairBlock = errors.New("unsupported altair block")
// ErrUnsupportedBellatrixBlock is returned when accessing a bellatrix block from a non-bellatrix wrapped
// block.
ErrUnsupportedBellatrixBlock = errors.New("unsupported bellatrix block")
// ErrUnsupportedBlindedBellatrixBlock is returned when accessing a blinded bellatrix block from unsupported method.
ErrUnsupportedBlindedBellatrixBlock = errors.New("unsupported blinded bellatrix block")
// ErrNilObjectWrapped is returned in a constructor when the underlying object is nil.
ErrNilObjectWrapped = errors.New("attempted to wrap nil object")
)
// WrappedSignedBeaconBlock will wrap a signed beacon block to conform to the
// signed beacon block interface.
func WrappedSignedBeaconBlock(i interface{}) (block.SignedBeaconBlock, error) {
switch b := i.(type) {
case *eth.GenericSignedBeaconBlock_Phase0:
return wrappedPhase0SignedBeaconBlock(b.Phase0), nil
case *eth.SignedBeaconBlock:
return wrappedPhase0SignedBeaconBlock(b), nil
case *eth.GenericSignedBeaconBlock_Altair:
return wrappedAltairSignedBeaconBlock(b.Altair)
case *eth.SignedBeaconBlockAltair:
return wrappedAltairSignedBeaconBlock(b)
case *eth.GenericSignedBeaconBlock_Bellatrix:
return wrappedBellatrixSignedBeaconBlock(b.Bellatrix)
case *eth.SignedBeaconBlockBellatrix:
return wrappedBellatrixSignedBeaconBlock(b)
case *eth.GenericSignedBeaconBlock_BlindedBellatrix:
return wrappedBellatrixSignedBlindedBeaconBlock(b.BlindedBellatrix)
case *eth.SignedBlindedBeaconBlockBellatrix:
return wrappedBellatrixSignedBlindedBeaconBlock(b)
case nil:
return nil, ErrNilObjectWrapped
default:
return nil, errors.Wrapf(ErrUnsupportedSignedBeaconBlock, "unable to wrap block of type %T", i)
}
}
// WrappedBeaconBlock will wrap a signed beacon block to conform to the
// signed beacon block interface.
func WrappedBeaconBlock(i interface{}) (block.BeaconBlock, error) {
switch b := i.(type) {
case *eth.GenericBeaconBlock_Phase0:
return WrappedPhase0BeaconBlock(b.Phase0), nil
case *eth.BeaconBlock:
return WrappedPhase0BeaconBlock(b), nil
case *eth.GenericBeaconBlock_Altair:
return WrappedAltairBeaconBlock(b.Altair)
case *eth.BeaconBlockAltair:
return WrappedAltairBeaconBlock(b)
case *eth.GenericBeaconBlock_Bellatrix:
return WrappedBellatrixBeaconBlock(b.Bellatrix)
case *eth.BeaconBlockBellatrix:
return WrappedBellatrixBeaconBlock(b)
case *eth.GenericBeaconBlock_BlindedBellatrix:
return WrappedBellatrixBlindedBeaconBlock(b.BlindedBellatrix)
case *eth.BlindedBeaconBlockBellatrix:
return WrappedBellatrixBlindedBeaconBlock(b)
default:
return nil, errors.Wrapf(ErrUnsupportedBeaconBlock, "unable to wrap block of type %T", i)
}
}
// BuildSignedBeaconBlock assembles a block.SignedBeaconBlock interface compatible struct from a
// given beacon block an the appropriate signature. This method may be used to easily create a
// signed beacon block.
func BuildSignedBeaconBlock(blk block.BeaconBlock, signature []byte) (block.SignedBeaconBlock, error) {
switch b := blk.(type) {
case Phase0BeaconBlock:
pb, ok := b.Proto().(*eth.BeaconBlock)
if !ok {
return nil, errors.New("unable to access inner phase0 proto")
}
return WrappedSignedBeaconBlock(&eth.SignedBeaconBlock{Block: pb, Signature: signature})
case altairBeaconBlock:
pb, ok := b.Proto().(*eth.BeaconBlockAltair)
if !ok {
return nil, errors.New("unable to access inner altair proto")
}
return WrappedSignedBeaconBlock(&eth.SignedBeaconBlockAltair{Block: pb, Signature: signature})
case bellatrixBeaconBlock:
pb, ok := b.Proto().(*eth.BeaconBlockBellatrix)
if !ok {
return nil, errors.New("unable to access inner bellatrix proto")
}
return WrappedSignedBeaconBlock(&eth.SignedBeaconBlockBellatrix{Block: pb, Signature: signature})
case blindedBeaconBlockBellatrix:
pb, ok := b.Proto().(*eth.BlindedBeaconBlockBellatrix)
if !ok {
return nil, errors.New("unable to access inner bellatrix proto")
}
return WrappedSignedBeaconBlock(&eth.SignedBlindedBeaconBlockBellatrix{Block: pb, Signature: signature})
default:
return nil, errors.Wrapf(ErrUnsupportedBeaconBlock, "unable to wrap block of type %T", b)
}
}
func UnwrapGenericSignedBeaconBlock(gb *eth.GenericSignedBeaconBlock) (block.SignedBeaconBlock, error) {
if gb == nil {
return nil, ErrNilObjectWrapped
}
switch bb := gb.Block.(type) {
case *eth.GenericSignedBeaconBlock_Phase0:
return WrappedSignedBeaconBlock(bb.Phase0)
case *eth.GenericSignedBeaconBlock_Altair:
return WrappedSignedBeaconBlock(bb.Altair)
case *eth.GenericSignedBeaconBlock_Bellatrix:
return WrappedSignedBeaconBlock(bb.Bellatrix)
case *eth.GenericSignedBeaconBlock_BlindedBellatrix:
return WrappedSignedBeaconBlock(bb.BlindedBellatrix)
default:
return nil, errors.Wrapf(ErrUnsupportedSignedBeaconBlock, "unable to wrap block of type %T", gb)
}
}

View File

@@ -0,0 +1,326 @@
package wrapper
import (
ssz "github.com/ferranbt/fastssz"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/consensus-types/block"
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
enginev1 "github.com/prysmaticlabs/prysm/proto/engine/v1"
eth "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
validatorpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/validator-client"
"github.com/prysmaticlabs/prysm/runtime/version"
"google.golang.org/protobuf/proto"
)
var (
_ = block.SignedBeaconBlock(&altairSignedBeaconBlock{})
_ = block.BeaconBlock(&altairBeaconBlock{})
_ = block.BeaconBlockBody(&altairBeaconBlockBody{})
)
// altairSignedBeaconBlock is a convenience wrapper around a altair beacon block
// object. 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.
type altairSignedBeaconBlock struct {
b *eth.SignedBeaconBlockAltair
}
// wrappedAltairSignedBeaconBlock is constructor which wraps a protobuf altair block
// with the block wrapper.
func wrappedAltairSignedBeaconBlock(b *eth.SignedBeaconBlockAltair) (block.SignedBeaconBlock, error) {
w := altairSignedBeaconBlock{b: b}
if w.IsNil() {
return nil, ErrNilObjectWrapped
}
return w, nil
}
// Signature returns the respective block signature.
func (w altairSignedBeaconBlock) Signature() []byte {
return w.b.Signature
}
// Block returns the underlying beacon block object.
func (w altairSignedBeaconBlock) Block() block.BeaconBlock {
return altairBeaconBlock{b: w.b.Block}
}
// IsNil checks if the underlying beacon block is
// nil.
func (w altairSignedBeaconBlock) IsNil() bool {
return w.b == nil || w.b.Block == nil
}
// Copy performs a deep copy of the signed beacon block
// object.
func (w altairSignedBeaconBlock) Copy() block.SignedBeaconBlock {
return altairSignedBeaconBlock{b: eth.CopySignedBeaconBlockAltair(w.b)}
}
// MarshalSSZ marshals the signed beacon block to its relevant ssz
// form.
func (w altairSignedBeaconBlock) MarshalSSZ() ([]byte, error) {
return w.b.MarshalSSZ()
}
// MarshalSSZTo marshals the signed beacon block's ssz
// form to the provided byte buffer.
func (w altairSignedBeaconBlock) MarshalSSZTo(dst []byte) ([]byte, error) {
return w.b.MarshalSSZTo(dst)
}
// SizeSSZ returns the size of the serialized signed block
func (w altairSignedBeaconBlock) SizeSSZ() int {
return w.b.SizeSSZ()
}
// UnmarshalSSZ unmarshals the signed beacon block from its relevant ssz
// form.
func (w altairSignedBeaconBlock) UnmarshalSSZ(buf []byte) error {
return w.b.UnmarshalSSZ(buf)
}
// Proto returns the block in its underlying protobuf
// interface.
func (w altairSignedBeaconBlock) Proto() proto.Message {
return w.b
}
// PbGenericBlock returns a generic signed beacon block.
func (w altairSignedBeaconBlock) PbGenericBlock() (*eth.GenericSignedBeaconBlock, error) {
return &eth.GenericSignedBeaconBlock{
Block: &eth.GenericSignedBeaconBlock_Altair{Altair: w.b},
}, nil
}
// PbAltairBlock returns the underlying protobuf object.
func (w altairSignedBeaconBlock) PbAltairBlock() (*eth.SignedBeaconBlockAltair, error) {
return w.b, nil
}
// PbPhase0Block is a stub.
func (altairSignedBeaconBlock) PbPhase0Block() (*eth.SignedBeaconBlock, error) {
return nil, ErrUnsupportedPhase0Block
}
// PbBellatrixBlock is a stub.
func (altairSignedBeaconBlock) PbBellatrixBlock() (*eth.SignedBeaconBlockBellatrix, error) {
return nil, ErrUnsupportedBellatrixBlock
}
// PbBlindedBellatrixBlock is a stub.
func (altairSignedBeaconBlock) PbBlindedBellatrixBlock() (*eth.SignedBlindedBeaconBlockBellatrix, error) {
return nil, ErrUnsupportedBlindedBellatrixBlock
}
// Version of the underlying protobuf object.
func (altairSignedBeaconBlock) Version() int {
return version.Altair
}
func (w altairSignedBeaconBlock) Header() (*eth.SignedBeaconBlockHeader, error) {
root, err := w.b.Block.Body.HashTreeRoot()
if err != nil {
return nil, errors.Wrapf(err, "could not hash block")
}
return &eth.SignedBeaconBlockHeader{
Header: &eth.BeaconBlockHeader{
Slot: w.b.Block.Slot,
ProposerIndex: w.b.Block.ProposerIndex,
ParentRoot: w.b.Block.ParentRoot,
StateRoot: w.b.Block.StateRoot,
BodyRoot: root[:],
},
Signature: w.Signature(),
}, nil
}
// altairBeaconBlock is the wrapper for the actual block.
type altairBeaconBlock struct {
b *eth.BeaconBlockAltair
}
// WrappedAltairBeaconBlock is constructor which wraps a protobuf altair object
// with the block wrapper.
//
// Deprecated: Use WrappedBeaconBlock.
func WrappedAltairBeaconBlock(b *eth.BeaconBlockAltair) (block.BeaconBlock, error) {
w := altairBeaconBlock{b: b}
if w.IsNil() {
return nil, ErrNilObjectWrapped
}
return w, nil
}
// Slot returns the respective slot of the block.
func (w altairBeaconBlock) Slot() types.Slot {
return w.b.Slot
}
// ProposerIndex returns the proposer index of the beacon block.
func (w altairBeaconBlock) ProposerIndex() types.ValidatorIndex {
return w.b.ProposerIndex
}
// ParentRoot returns the parent root of beacon block.
func (w altairBeaconBlock) ParentRoot() []byte {
return w.b.ParentRoot
}
// StateRoot returns the state root of the beacon block.
func (w altairBeaconBlock) StateRoot() []byte {
return w.b.StateRoot
}
// Body returns the underlying block body.
func (w altairBeaconBlock) Body() block.BeaconBlockBody {
return altairBeaconBlockBody{b: w.b.Body}
}
// IsNil checks if the beacon block is nil.
func (w altairBeaconBlock) IsNil() bool {
return w.b == nil
}
// IsBlinded checks if the beacon block is a blinded block.
func (altairBeaconBlock) IsBlinded() bool {
return false
}
// HashTreeRoot returns the ssz root of the block.
func (w altairBeaconBlock) HashTreeRoot() ([32]byte, error) {
return w.b.HashTreeRoot()
}
// HashTreeRootWith ssz hashes the BeaconBlock object with a hasher.
func (w altairBeaconBlock) HashTreeRootWith(hh *ssz.Hasher) error {
return w.b.HashTreeRootWith(hh)
}
// MarshalSSZ marshals the block into its respective
// ssz form.
func (w altairBeaconBlock) MarshalSSZ() ([]byte, error) {
return w.b.MarshalSSZ()
}
// MarshalSSZTo marshals the beacon block's ssz
// form to the provided byte buffer.
func (w altairBeaconBlock) MarshalSSZTo(dst []byte) ([]byte, error) {
return w.b.MarshalSSZTo(dst)
}
// SizeSSZ returns the size of the serialized block.
func (w altairBeaconBlock) SizeSSZ() int {
return w.b.SizeSSZ()
}
// UnmarshalSSZ unmarshals the beacon block from its relevant ssz
// form.
func (w altairBeaconBlock) UnmarshalSSZ(buf []byte) error {
return w.b.UnmarshalSSZ(buf)
}
// Proto returns the underlying block object in its
// proto form.
func (w altairBeaconBlock) Proto() proto.Message {
return w.b
}
// Version of the underlying protobuf object.
func (altairBeaconBlock) Version() int {
return version.Altair
}
// AsSignRequestObject returns the underlying sign request object.
func (w altairBeaconBlock) AsSignRequestObject() validatorpb.SignRequestObject {
return &validatorpb.SignRequest_BlockV2{
BlockV2: w.b,
}
}
// altairBeaconBlockBody is a wrapper of a beacon block body.
type altairBeaconBlockBody struct {
b *eth.BeaconBlockBodyAltair
}
// WrappedAltairBeaconBlockBody is constructor which wraps a protobuf altair object
// with the block wrapper.
func WrappedAltairBeaconBlockBody(b *eth.BeaconBlockBodyAltair) (block.BeaconBlockBody, error) {
w := altairBeaconBlockBody{b: b}
if w.IsNil() {
return nil, ErrNilObjectWrapped
}
return w, nil
}
// RandaoReveal returns the randao reveal from the block body.
func (w altairBeaconBlockBody) RandaoReveal() []byte {
return w.b.RandaoReveal
}
// Eth1Data returns the eth1 data in the block.
func (w altairBeaconBlockBody) Eth1Data() *eth.Eth1Data {
return w.b.Eth1Data
}
// Graffiti returns the graffiti in the block.
func (w altairBeaconBlockBody) Graffiti() []byte {
return w.b.Graffiti
}
// ProposerSlashings returns the proposer slashings in the block.
func (w altairBeaconBlockBody) ProposerSlashings() []*eth.ProposerSlashing {
return w.b.ProposerSlashings
}
// AttesterSlashings returns the attester slashings in the block.
func (w altairBeaconBlockBody) AttesterSlashings() []*eth.AttesterSlashing {
return w.b.AttesterSlashings
}
// Attestations returns the stored attestations in the block.
func (w altairBeaconBlockBody) Attestations() []*eth.Attestation {
return w.b.Attestations
}
// Deposits returns the stored deposits in the block.
func (w altairBeaconBlockBody) Deposits() []*eth.Deposit {
return w.b.Deposits
}
// VoluntaryExits returns the voluntary exits in the block.
func (w altairBeaconBlockBody) VoluntaryExits() []*eth.SignedVoluntaryExit {
return w.b.VoluntaryExits
}
// SyncAggregate returns the sync aggregate in the block.
func (w altairBeaconBlockBody) SyncAggregate() (*eth.SyncAggregate, error) {
return w.b.SyncAggregate, nil
}
// IsNil checks if the block body is nil.
func (w altairBeaconBlockBody) IsNil() bool {
return w.b == nil
}
// HashTreeRoot returns the ssz root of the block body.
func (w altairBeaconBlockBody) HashTreeRoot() ([32]byte, error) {
return w.b.HashTreeRoot()
}
// Proto returns the underlying proto form of the block
// body.
func (w altairBeaconBlockBody) Proto() proto.Message {
return w.b
}
// ExecutionPayload is a stub.
func (w altairBeaconBlockBody) ExecutionPayload() (*enginev1.ExecutionPayload, error) {
return nil, errors.Wrapf(ErrUnsupportedField, "ExecutionPayload for %T", w)
}
// ExecutionPayloadHeader is a stub.
func (w altairBeaconBlockBody) ExecutionPayloadHeader() (*eth.ExecutionPayloadHeader, error) {
return nil, errors.Wrapf(ErrUnsupportedField, "ExecutionPayloadHeader for %T", w)
}

View File

@@ -0,0 +1,356 @@
package wrapper_test
import (
"bytes"
"testing"
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
"github.com/prysmaticlabs/prysm/consensus-types/wrapper"
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
validatorpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/validator-client"
"github.com/prysmaticlabs/prysm/runtime/version"
"github.com/prysmaticlabs/prysm/testing/assert"
"github.com/prysmaticlabs/prysm/testing/require"
"github.com/prysmaticlabs/prysm/testing/util"
)
func TestAltairSignedBeaconBlock_Signature(t *testing.T) {
sig := []byte{0x11, 0x22}
wsb, err := wrapper.WrappedSignedBeaconBlock(&ethpb.SignedBeaconBlockAltair{Block: &ethpb.BeaconBlockAltair{}, Signature: sig})
require.NoError(t, err)
if !bytes.Equal(sig, wsb.Signature()) {
t.Error("Wrong signature returned")
}
}
func TestAltairSignedBeaconBlock_Block(t *testing.T) {
blk := &ethpb.BeaconBlockAltair{Slot: 54}
wsb, err := wrapper.WrappedSignedBeaconBlock(&ethpb.SignedBeaconBlockAltair{Block: blk})
require.NoError(t, err)
assert.DeepEqual(t, blk, wsb.Block().Proto())
}
func TestAltairSignedBeaconBlock_IsNil(t *testing.T) {
_, err := wrapper.WrappedSignedBeaconBlock(nil)
require.Equal(t, wrapper.ErrNilObjectWrapped, err)
wsb, err := wrapper.WrappedSignedBeaconBlock(&ethpb.SignedBeaconBlockAltair{Block: &ethpb.BeaconBlockAltair{}})
require.NoError(t, err)
assert.Equal(t, false, wsb.IsNil())
}
func TestAltairSignedBeaconBlock_Copy(t *testing.T) {
t.Skip("TODO: Missing mutation evaluation helpers")
}
func TestAltairSignedBeaconBlock_Proto(t *testing.T) {
sb := &ethpb.SignedBeaconBlockAltair{
Block: &ethpb.BeaconBlockAltair{Slot: 66},
Signature: []byte{0x11, 0x22},
}
wsb, err := wrapper.WrappedSignedBeaconBlock(sb)
require.NoError(t, err)
assert.Equal(t, sb, wsb.Proto())
}
func TestAltairSignedBeaconBlock_PbPhase0Block(t *testing.T) {
wsb, err := wrapper.WrappedSignedBeaconBlock(&ethpb.SignedBeaconBlockAltair{Block: &ethpb.BeaconBlockAltair{}})
require.NoError(t, err)
if _, err := wsb.PbPhase0Block(); err != wrapper.ErrUnsupportedPhase0Block {
t.Errorf("Wrong error returned. Want %v got %v", wrapper.ErrUnsupportedPhase0Block, err)
}
}
func TestAltairSignedBeaconBlock_PbAltairBlock(t *testing.T) {
sb := &ethpb.SignedBeaconBlockAltair{
Block: &ethpb.BeaconBlockAltair{Slot: 66},
Signature: []byte{0x11, 0x22},
}
wsb, err := wrapper.WrappedSignedBeaconBlock(sb)
require.NoError(t, err)
got, err := wsb.PbAltairBlock()
assert.NoError(t, err)
assert.Equal(t, sb, got)
}
func TestAltairSignedBeaconBlock_MarshalSSZTo(t *testing.T) {
wsb, err := wrapper.WrappedSignedBeaconBlock(util.HydrateSignedBeaconBlockAltair(&ethpb.SignedBeaconBlockAltair{}))
assert.NoError(t, err)
var b []byte
b, err = wsb.MarshalSSZTo(b)
assert.NoError(t, err)
assert.NotEqual(t, 0, len(b))
}
func TestAltairSignedBeaconBlock_SSZ(t *testing.T) {
wsb, err := wrapper.WrappedSignedBeaconBlock(util.HydrateSignedBeaconBlockAltair(&ethpb.SignedBeaconBlockAltair{}))
assert.NoError(t, err)
b, err := wsb.MarshalSSZ()
assert.NoError(t, err)
assert.NotEqual(t, 0, len(b))
assert.NotEqual(t, 0, wsb.SizeSSZ())
assert.NoError(t, wsb.UnmarshalSSZ(b))
}
func TestAltairSignedBeaconBlock_Version(t *testing.T) {
wsb, err := wrapper.WrappedSignedBeaconBlock(&ethpb.SignedBeaconBlockAltair{Block: &ethpb.BeaconBlockAltair{}})
require.NoError(t, err)
assert.Equal(t, version.Altair, wsb.Version())
}
func TestAltairBeaconBlock_Slot(t *testing.T) {
slot := types.Slot(546)
wb, err := wrapper.WrappedAltairBeaconBlock(&ethpb.BeaconBlockAltair{Slot: slot})
require.NoError(t, err)
assert.Equal(t, slot, wb.Slot())
}
func TestAltairBeaconBlock_ProposerIndex(t *testing.T) {
pi := types.ValidatorIndex(555)
wb, err := wrapper.WrappedAltairBeaconBlock(&ethpb.BeaconBlockAltair{ProposerIndex: pi})
require.NoError(t, err)
assert.Equal(t, pi, wb.ProposerIndex())
}
func TestAltairBeaconBlock_ParentRoot(t *testing.T) {
root := []byte{0xAA, 0xBF, 0x33, 0x01}
wb, err := wrapper.WrappedAltairBeaconBlock(&ethpb.BeaconBlockAltair{ParentRoot: root})
require.NoError(t, err)
assert.DeepEqual(t, root, wb.ParentRoot())
}
func TestAltairBeaconBlock_StateRoot(t *testing.T) {
root := []byte{0xAA, 0xBF, 0x33, 0x01}
wb, err := wrapper.WrappedAltairBeaconBlock(&ethpb.BeaconBlockAltair{StateRoot: root})
require.NoError(t, err)
assert.DeepEqual(t, root, wb.StateRoot())
}
func TestAltairBeaconBlock_Body(t *testing.T) {
body := &ethpb.BeaconBlockBodyAltair{Graffiti: []byte{0x44}}
wb, err := wrapper.WrappedAltairBeaconBlock(&ethpb.BeaconBlockAltair{Body: body})
require.NoError(t, err)
assert.Equal(t, body, wb.Body().Proto())
}
func TestAltairBeaconBlock_IsNil(t *testing.T) {
_, err := wrapper.WrappedAltairBeaconBlock(nil)
require.Equal(t, wrapper.ErrNilObjectWrapped, err)
wb, err := wrapper.WrappedAltairBeaconBlock(&ethpb.BeaconBlockAltair{})
require.NoError(t, err)
assert.Equal(t, false, wb.IsNil())
}
func TestAltairBeaconBlock_IsBlinded(t *testing.T) {
wsb, err := wrapper.WrappedBeaconBlock(&ethpb.BeaconBlockAltair{})
require.NoError(t, err)
require.Equal(t, false, wsb.IsNil())
}
func TestAltairBeaconBlock_HashTreeRoot(t *testing.T) {
wb, err := wrapper.WrappedAltairBeaconBlock(util.HydrateBeaconBlockAltair(&ethpb.BeaconBlockAltair{}))
require.NoError(t, err)
rt, err := wb.HashTreeRoot()
assert.NoError(t, err)
assert.NotEmpty(t, rt)
}
func TestAltairBeaconBlock_Proto(t *testing.T) {
blk := &ethpb.BeaconBlockAltair{ProposerIndex: 234}
wb, err := wrapper.WrappedAltairBeaconBlock(blk)
require.NoError(t, err)
assert.Equal(t, blk, wb.Proto())
}
func TestAltairBeaconBlock_SSZ(t *testing.T) {
wb, err := wrapper.WrappedAltairBeaconBlock(util.HydrateBeaconBlockAltair(&ethpb.BeaconBlockAltair{}))
assert.NoError(t, err)
b, err := wb.MarshalSSZ()
assert.NoError(t, err)
assert.NotEqual(t, 0, len(b))
assert.NotEqual(t, 0, wb.SizeSSZ())
assert.NoError(t, wb.UnmarshalSSZ(b))
}
func TestAltairBeaconBlock_Version(t *testing.T) {
wb, err := wrapper.WrappedAltairBeaconBlock(&ethpb.BeaconBlockAltair{})
require.NoError(t, err)
assert.Equal(t, version.Altair, wb.Version())
}
func TestAltairBeaconBlockBody_RandaoReveal(t *testing.T) {
root := []byte{0xAA, 0xBF, 0x33, 0x01}
wbb, err := wrapper.WrappedAltairBeaconBlockBody(&ethpb.BeaconBlockBodyAltair{RandaoReveal: root})
require.NoError(t, err)
assert.DeepEqual(t, root, wbb.RandaoReveal())
}
func TestAltairBeaconBlockBody_Eth1Data(t *testing.T) {
data := &ethpb.Eth1Data{}
body := &ethpb.BeaconBlockBodyAltair{
Eth1Data: data,
}
wbb, err := wrapper.WrappedAltairBeaconBlockBody(body)
require.NoError(t, err)
assert.Equal(t, data, wbb.Eth1Data())
}
func TestAltairBeaconBlockBody_Graffiti(t *testing.T) {
graffiti := []byte{0x66, 0xAA}
body := &ethpb.BeaconBlockBodyAltair{Graffiti: graffiti}
wbb, err := wrapper.WrappedAltairBeaconBlockBody(body)
require.NoError(t, err)
assert.DeepEqual(t, graffiti, wbb.Graffiti())
}
func TestAltairBeaconBlockBody_ProposerSlashings(t *testing.T) {
ps := []*ethpb.ProposerSlashing{
{Header_1: &ethpb.SignedBeaconBlockHeader{
Signature: []byte{0x11, 0x20},
}},
}
body := &ethpb.BeaconBlockBodyAltair{ProposerSlashings: ps}
wbb, err := wrapper.WrappedAltairBeaconBlockBody(body)
require.NoError(t, err)
assert.DeepEqual(t, ps, wbb.ProposerSlashings())
}
func TestAltairBeaconBlockBody_AttesterSlashings(t *testing.T) {
as := []*ethpb.AttesterSlashing{
{Attestation_1: &ethpb.IndexedAttestation{Signature: []byte{0x11}}},
}
body := &ethpb.BeaconBlockBodyAltair{AttesterSlashings: as}
wbb, err := wrapper.WrappedAltairBeaconBlockBody(body)
require.NoError(t, err)
assert.DeepEqual(t, as, wbb.AttesterSlashings())
}
func TestAltairBeaconBlockBody_Attestations(t *testing.T) {
atts := []*ethpb.Attestation{{Signature: []byte{0x88}}}
body := &ethpb.BeaconBlockBodyAltair{Attestations: atts}
wbb, err := wrapper.WrappedAltairBeaconBlockBody(body)
require.NoError(t, err)
assert.DeepEqual(t, atts, wbb.Attestations())
}
func TestAltairBeaconBlockBody_Deposits(t *testing.T) {
deposits := []*ethpb.Deposit{
{Proof: [][]byte{{0x54, 0x10}}},
}
body := &ethpb.BeaconBlockBodyAltair{Deposits: deposits}
wbb, err := wrapper.WrappedAltairBeaconBlockBody(body)
require.NoError(t, err)
assert.DeepEqual(t, deposits, wbb.Deposits())
}
func TestAltairBeaconBlockBody_VoluntaryExits(t *testing.T) {
exits := []*ethpb.SignedVoluntaryExit{
{Exit: &ethpb.VoluntaryExit{Epoch: 54}},
}
body := &ethpb.BeaconBlockBodyAltair{VoluntaryExits: exits}
wbb, err := wrapper.WrappedAltairBeaconBlockBody(body)
require.NoError(t, err)
assert.DeepEqual(t, exits, wbb.VoluntaryExits())
}
func TestAltairBeaconBlockBody_IsNil(t *testing.T) {
_, err := wrapper.WrappedAltairBeaconBlockBody(nil)
require.Equal(t, wrapper.ErrNilObjectWrapped, err)
wbb, err := wrapper.WrappedAltairBeaconBlockBody(&ethpb.BeaconBlockBodyAltair{})
require.NoError(t, err)
assert.Equal(t, false, wbb.IsNil())
}
func TestAltairBeaconBlockBody_HashTreeRoot(t *testing.T) {
wb, err := wrapper.WrappedAltairBeaconBlockBody(util.HydrateBeaconBlockBodyAltair(&ethpb.BeaconBlockBodyAltair{}))
assert.NoError(t, err)
rt, err := wb.HashTreeRoot()
assert.NoError(t, err)
assert.NotEmpty(t, rt)
}
func TestAltairBeaconBlockBody_Proto(t *testing.T) {
body := &ethpb.BeaconBlockBodyAltair{Graffiti: []byte{0x66, 0xAA}}
wbb, err := wrapper.WrappedAltairBeaconBlockBody(body)
require.NoError(t, err)
assert.Equal(t, body, wbb.Proto())
}
func TestAltairBeaconBlock_PbGenericBlock(t *testing.T) {
abb := &ethpb.SignedBeaconBlockAltair{
Block: util.HydrateBeaconBlockAltair(&ethpb.BeaconBlockAltair{}),
}
wsb, err := wrapper.WrappedSignedBeaconBlock(abb)
require.NoError(t, err)
got, err := wsb.PbGenericBlock()
require.NoError(t, err)
assert.Equal(t, abb, got.GetAltair())
}
func TestAltairBeaconBlock_AsSignRequestObject(t *testing.T) {
abb := util.HydrateBeaconBlockAltair(&ethpb.BeaconBlockAltair{})
wsb, err := wrapper.WrappedBeaconBlock(abb)
require.NoError(t, err)
sro := wsb.AsSignRequestObject()
got, ok := sro.(*validatorpb.SignRequest_BlockV2)
require.Equal(t, true, ok, "Not a SignRequest_BlockV2")
assert.Equal(t, abb, got.BlockV2)
}
func TestAltairBeaconBlock_PbBlindedBellatrixBlock(t *testing.T) {
sb := &ethpb.SignedBeaconBlockAltair{
Block: &ethpb.BeaconBlockAltair{Slot: 66},
}
wsb, err := wrapper.WrappedSignedBeaconBlock(sb)
require.NoError(t, err)
_, err = wsb.PbBlindedBellatrixBlock()
require.ErrorContains(t, "unsupported blinded bellatrix block", err)
}
func TestAltairBeaconBlock_ExecutionPayloadHeader(t *testing.T) {
sb := &ethpb.SignedBeaconBlockAltair{
Block: &ethpb.BeaconBlockAltair{Slot: 66},
}
wsb, err := wrapper.WrappedSignedBeaconBlock(sb)
require.NoError(t, err)
_, err = wsb.Block().Body().ExecutionPayloadHeader()
require.ErrorContains(t, "unsupported field for block type", err)
}

View File

@@ -0,0 +1,321 @@
package wrapper
import (
ssz "github.com/ferranbt/fastssz"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/consensus-types/block"
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
enginev1 "github.com/prysmaticlabs/prysm/proto/engine/v1"
eth "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
validatorpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/validator-client"
"github.com/prysmaticlabs/prysm/runtime/version"
"google.golang.org/protobuf/proto"
)
var (
_ = block.SignedBeaconBlock(&bellatrixSignedBeaconBlock{})
_ = block.BeaconBlock(&bellatrixBeaconBlock{})
_ = block.BeaconBlockBody(&bellatrixBeaconBlockBody{})
)
// bellatrixSignedBeaconBlock is a convenience wrapper around a Bellatrix blinded beacon block
// object. 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.
type bellatrixSignedBeaconBlock struct {
b *eth.SignedBeaconBlockBellatrix
}
// wrappedBellatrixSignedBeaconBlock is a constructor which wraps a protobuf Bellatrix block with the block wrapper.
func wrappedBellatrixSignedBeaconBlock(b *eth.SignedBeaconBlockBellatrix) (block.SignedBeaconBlock, error) {
w := bellatrixSignedBeaconBlock{b: b}
if w.IsNil() {
return nil, ErrNilObjectWrapped
}
return w, nil
}
// Signature returns the respective block signature.
func (w bellatrixSignedBeaconBlock) Signature() []byte {
return w.b.Signature
}
// Block returns the underlying beacon block object.
func (w bellatrixSignedBeaconBlock) Block() block.BeaconBlock {
return bellatrixBeaconBlock{b: w.b.Block}
}
// IsNil checks if the underlying beacon block is nil.
func (w bellatrixSignedBeaconBlock) IsNil() bool {
return w.b == nil || w.b.Block == nil
}
// Copy performs a deep copy of the signed beacon block object.
func (w bellatrixSignedBeaconBlock) Copy() block.SignedBeaconBlock {
return bellatrixSignedBeaconBlock{b: eth.CopySignedBeaconBlockBellatrix(w.b)}
}
// MarshalSSZ marshals the signed beacon block to its relevant ssz form.
func (w bellatrixSignedBeaconBlock) MarshalSSZ() ([]byte, error) {
return w.b.MarshalSSZ()
}
// MarshalSSZTo marshals the signed beacon block's ssz
// form to the provided byte buffer.
func (w bellatrixSignedBeaconBlock) MarshalSSZTo(dst []byte) ([]byte, error) {
return w.b.MarshalSSZTo(dst)
}
// SizeSSZ returns the size of the serialized signed block
func (w bellatrixSignedBeaconBlock) SizeSSZ() int {
return w.b.SizeSSZ()
}
// UnmarshalSSZ unmarshals the signed beacon block from its relevant ssz
// form.
func (w bellatrixSignedBeaconBlock) UnmarshalSSZ(buf []byte) error {
return w.b.UnmarshalSSZ(buf)
}
// Proto returns the block in its underlying protobuf interface.
func (w bellatrixSignedBeaconBlock) Proto() proto.Message {
return w.b
}
// PbGenericBlock returns a generic signed beacon block.
func (w bellatrixSignedBeaconBlock) PbGenericBlock() (*eth.GenericSignedBeaconBlock, error) {
return &eth.GenericSignedBeaconBlock{
Block: &eth.GenericSignedBeaconBlock_Bellatrix{Bellatrix: w.b},
}, nil
}
// PbBellatrixBlock returns the underlying protobuf object.
func (w bellatrixSignedBeaconBlock) PbBellatrixBlock() (*eth.SignedBeaconBlockBellatrix, error) {
return w.b, nil
}
// PbBlindedBellatrixBlock is a stub.
func (bellatrixSignedBeaconBlock) PbBlindedBellatrixBlock() (*eth.SignedBlindedBeaconBlockBellatrix, error) {
return nil, ErrUnsupportedBlindedBellatrixBlock
}
// PbPhase0Block is a stub.
func (bellatrixSignedBeaconBlock) PbPhase0Block() (*eth.SignedBeaconBlock, error) {
return nil, ErrUnsupportedPhase0Block
}
// PbAltairBlock returns the underlying protobuf object.
func (bellatrixSignedBeaconBlock) PbAltairBlock() (*eth.SignedBeaconBlockAltair, error) {
return nil, ErrUnsupportedAltairBlock
}
// Version of the underlying protobuf object.
func (bellatrixSignedBeaconBlock) Version() int {
return version.Bellatrix
}
func (w bellatrixSignedBeaconBlock) Header() (*eth.SignedBeaconBlockHeader, error) {
root, err := w.b.Block.Body.HashTreeRoot()
if err != nil {
return nil, errors.Wrapf(err, "could not hash block")
}
return &eth.SignedBeaconBlockHeader{
Header: &eth.BeaconBlockHeader{
Slot: w.b.Block.Slot,
ProposerIndex: w.b.Block.ProposerIndex,
ParentRoot: w.b.Block.ParentRoot,
StateRoot: w.b.Block.StateRoot,
BodyRoot: root[:],
},
Signature: w.Signature(),
}, nil
}
// bellatrixBeaconBlock is the wrapper for the actual block.
type bellatrixBeaconBlock struct {
b *eth.BeaconBlockBellatrix
}
// WrappedBellatrixBeaconBlock is a constructor which wraps a protobuf Bellatrix object
// with the block wrapper.
//
// Deprecated: Use WrappedBeaconBlock.
func WrappedBellatrixBeaconBlock(b *eth.BeaconBlockBellatrix) (block.BeaconBlock, error) {
w := bellatrixBeaconBlock{b: b}
if w.IsNil() {
return nil, ErrNilObjectWrapped
}
return w, nil
}
// Slot returns the respective slot of the block.
func (w bellatrixBeaconBlock) Slot() types.Slot {
return w.b.Slot
}
// ProposerIndex returns the proposer index of the beacon block.
func (w bellatrixBeaconBlock) ProposerIndex() types.ValidatorIndex {
return w.b.ProposerIndex
}
// ParentRoot returns the parent root of beacon block.
func (w bellatrixBeaconBlock) ParentRoot() []byte {
return w.b.ParentRoot
}
// StateRoot returns the state root of the beacon block.
func (w bellatrixBeaconBlock) StateRoot() []byte {
return w.b.StateRoot
}
// Body returns the underlying block body.
func (w bellatrixBeaconBlock) Body() block.BeaconBlockBody {
return bellatrixBeaconBlockBody{b: w.b.Body}
}
// IsNil checks if the beacon block is nil.
func (w bellatrixBeaconBlock) IsNil() bool {
return w.b == nil
}
// IsBlinded checks if the beacon block is a blinded block.
func (bellatrixBeaconBlock) IsBlinded() bool {
return false
}
// HashTreeRoot returns the ssz root of the block.
func (w bellatrixBeaconBlock) HashTreeRoot() ([32]byte, error) {
return w.b.HashTreeRoot()
}
// HashTreeRootWith ssz hashes the BeaconBlock object with a hasher.
func (w bellatrixBeaconBlock) HashTreeRootWith(hh *ssz.Hasher) error {
return w.b.HashTreeRootWith(hh)
}
// MarshalSSZ marshals the block into its respective
// ssz form.
func (w bellatrixBeaconBlock) MarshalSSZ() ([]byte, error) {
return w.b.MarshalSSZ()
}
// MarshalSSZTo marshals the beacon block's ssz
// form to the provided byte buffer.
func (w bellatrixBeaconBlock) MarshalSSZTo(dst []byte) ([]byte, error) {
return w.b.MarshalSSZTo(dst)
}
// SizeSSZ returns the size of the serialized block.
func (w bellatrixBeaconBlock) SizeSSZ() int {
return w.b.SizeSSZ()
}
// UnmarshalSSZ unmarshals the beacon block from its relevant ssz
// form.
func (w bellatrixBeaconBlock) UnmarshalSSZ(buf []byte) error {
return w.b.UnmarshalSSZ(buf)
}
// Proto returns the underlying block object in its
// proto form.
func (w bellatrixBeaconBlock) Proto() proto.Message {
return w.b
}
// Version of the underlying protobuf object.
func (bellatrixBeaconBlock) Version() int {
return version.Bellatrix
}
// AsSignRequestObject returns the underlying sign request object.
func (w bellatrixBeaconBlock) AsSignRequestObject() validatorpb.SignRequestObject {
return &validatorpb.SignRequest_BlockV3{
BlockV3: w.b,
}
}
// bellatrixBeaconBlockBody is a wrapper of a beacon block body.
type bellatrixBeaconBlockBody struct {
b *eth.BeaconBlockBodyBellatrix
}
// WrappedBellatrixBeaconBlockBody is a constructor which wraps a protobuf bellatrix object
// with the block wrapper.
func WrappedBellatrixBeaconBlockBody(b *eth.BeaconBlockBodyBellatrix) (block.BeaconBlockBody, error) {
w := bellatrixBeaconBlockBody{b: b}
if w.IsNil() {
return nil, ErrNilObjectWrapped
}
return w, nil
}
// RandaoReveal returns the randao reveal from the block body.
func (w bellatrixBeaconBlockBody) RandaoReveal() []byte {
return w.b.RandaoReveal
}
// Eth1Data returns the eth1 data in the block.
func (w bellatrixBeaconBlockBody) Eth1Data() *eth.Eth1Data {
return w.b.Eth1Data
}
// Graffiti returns the graffiti in the block.
func (w bellatrixBeaconBlockBody) Graffiti() []byte {
return w.b.Graffiti
}
// ProposerSlashings returns the proposer slashings in the block.
func (w bellatrixBeaconBlockBody) ProposerSlashings() []*eth.ProposerSlashing {
return w.b.ProposerSlashings
}
// AttesterSlashings returns the attester slashings in the block.
func (w bellatrixBeaconBlockBody) AttesterSlashings() []*eth.AttesterSlashing {
return w.b.AttesterSlashings
}
// Attestations returns the stored attestations in the block.
func (w bellatrixBeaconBlockBody) Attestations() []*eth.Attestation {
return w.b.Attestations
}
// Deposits returns the stored deposits in the block.
func (w bellatrixBeaconBlockBody) Deposits() []*eth.Deposit {
return w.b.Deposits
}
// VoluntaryExits returns the voluntary exits in the block.
func (w bellatrixBeaconBlockBody) VoluntaryExits() []*eth.SignedVoluntaryExit {
return w.b.VoluntaryExits
}
// SyncAggregate returns the sync aggregate in the block.
func (w bellatrixBeaconBlockBody) SyncAggregate() (*eth.SyncAggregate, error) {
return w.b.SyncAggregate, nil
}
// IsNil checks if the block body is nil.
func (w bellatrixBeaconBlockBody) IsNil() bool {
return w.b == nil
}
// HashTreeRoot returns the ssz root of the block body.
func (w bellatrixBeaconBlockBody) HashTreeRoot() ([32]byte, error) {
return w.b.HashTreeRoot()
}
// Proto returns the underlying proto form of the block
// body.
func (w bellatrixBeaconBlockBody) Proto() proto.Message {
return w.b
}
// ExecutionPayload returns the Execution payload of the block body.
func (w bellatrixBeaconBlockBody) ExecutionPayload() (*enginev1.ExecutionPayload, error) {
return w.b.ExecutionPayload, nil
}
// ExecutionPayloadHeader is a stub.
func (w bellatrixBeaconBlockBody) ExecutionPayloadHeader() (*eth.ExecutionPayloadHeader, error) {
return nil, errors.Wrapf(ErrUnsupportedField, "ExecutionPayloadHeader for %T", w)
}

View File

@@ -0,0 +1,401 @@
package wrapper_test
import (
"bytes"
"testing"
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
"github.com/prysmaticlabs/prysm/consensus-types/wrapper"
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
enginev1 "github.com/prysmaticlabs/prysm/proto/engine/v1"
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
validatorpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/validator-client"
"github.com/prysmaticlabs/prysm/runtime/version"
"github.com/prysmaticlabs/prysm/testing/assert"
"github.com/prysmaticlabs/prysm/testing/require"
"github.com/prysmaticlabs/prysm/testing/util"
)
func TestBellatrixSignedBeaconBlock_Header(t *testing.T) {
root := bytesutil.PadTo([]byte("root"), 32)
signature := bytesutil.PadTo([]byte("sig"), 96)
body := &ethpb.BeaconBlockBodyBellatrix{}
body = util.HydrateBeaconBlockBodyBellatrix(body)
bodyRoot, err := body.HashTreeRoot()
require.NoError(t, err)
block := &ethpb.SignedBeaconBlockBellatrix{
Block: &ethpb.BeaconBlockBellatrix{
Slot: 1,
ProposerIndex: 1,
ParentRoot: root,
StateRoot: root,
Body: body,
},
Signature: signature,
}
wrapped, err := wrapper.WrappedSignedBeaconBlock(block)
require.NoError(t, err)
header, err := wrapped.Header()
require.NoError(t, err)
assert.Equal(t, types.ValidatorIndex(1), header.Header.ProposerIndex)
assert.Equal(t, types.Slot(1), header.Header.Slot)
assert.DeepEqual(t, bodyRoot[:], header.Header.BodyRoot)
assert.DeepEqual(t, root, header.Header.StateRoot)
assert.DeepEqual(t, root, header.Header.ParentRoot)
assert.DeepEqual(t, signature, header.Signature)
}
func TestBellatrixSignedBeaconBlock_Signature(t *testing.T) {
sig := []byte{0x11, 0x22}
wsb, err := wrapper.WrappedSignedBeaconBlock(&ethpb.SignedBeaconBlockBellatrix{Block: &ethpb.BeaconBlockBellatrix{}, Signature: sig})
require.NoError(t, err)
if !bytes.Equal(sig, wsb.Signature()) {
t.Error("Wrong signature returned")
}
}
func TestBellatrixSignedBeaconBlock_Block(t *testing.T) {
blk := &ethpb.BeaconBlockBellatrix{Slot: 54}
wsb, err := wrapper.WrappedSignedBeaconBlock(&ethpb.SignedBeaconBlockBellatrix{Block: blk})
require.NoError(t, err)
assert.DeepEqual(t, blk, wsb.Block().Proto())
}
func TestBellatrixSignedBeaconBlock_IsNil(t *testing.T) {
_, err := wrapper.WrappedSignedBeaconBlock(nil)
require.Equal(t, wrapper.ErrNilObjectWrapped, err)
wsb, err := wrapper.WrappedSignedBeaconBlock(&ethpb.SignedBeaconBlockBellatrix{Block: &ethpb.BeaconBlockBellatrix{}})
require.NoError(t, err)
assert.Equal(t, false, wsb.IsNil())
}
func TestBellatrixSignedBeaconBlock_Copy(t *testing.T) {
t.Skip("TODO: Missing mutation evaluation helpers")
}
func TestBellatrixSignedBeaconBlock_Proto(t *testing.T) {
sb := &ethpb.SignedBeaconBlockBellatrix{
Block: &ethpb.BeaconBlockBellatrix{Slot: 66},
Signature: []byte{0x11, 0x22},
}
wsb, err := wrapper.WrappedSignedBeaconBlock(sb)
require.NoError(t, err)
assert.Equal(t, sb, wsb.Proto())
}
func TestBellatrixSignedBeaconBlock_PbPhase0Block(t *testing.T) {
wsb, err := wrapper.WrappedSignedBeaconBlock(&ethpb.SignedBeaconBlockBellatrix{Block: &ethpb.BeaconBlockBellatrix{}})
require.NoError(t, err)
if _, err := wsb.PbPhase0Block(); err != wrapper.ErrUnsupportedPhase0Block {
t.Errorf("Wrong error returned. Want %v got %v", wrapper.ErrUnsupportedPhase0Block, err)
}
}
func TestBellatrixSignedBeaconBlock_PbBellatrixBlock(t *testing.T) {
sb := &ethpb.SignedBeaconBlockBellatrix{
Block: &ethpb.BeaconBlockBellatrix{Slot: 66},
Signature: []byte{0x11, 0x22},
}
wsb, err := wrapper.WrappedSignedBeaconBlock(sb)
require.NoError(t, err)
got, err := wsb.PbBellatrixBlock()
assert.NoError(t, err)
assert.Equal(t, sb, got)
}
func TestBellatrixSignedBeaconBlock_MarshalSSZTo(t *testing.T) {
wsb, err := wrapper.WrappedSignedBeaconBlock(util.HydrateSignedBeaconBlockBellatrix(&ethpb.SignedBeaconBlockBellatrix{}))
assert.NoError(t, err)
var b []byte
b, err = wsb.MarshalSSZTo(b)
assert.NoError(t, err)
assert.NotEqual(t, 0, len(b))
}
func TestBellatrixSignedBeaconBlock_SSZ(t *testing.T) {
wsb, err := wrapper.WrappedSignedBeaconBlock(util.HydrateSignedBeaconBlockBellatrix(&ethpb.SignedBeaconBlockBellatrix{}))
assert.NoError(t, err)
b, err := wsb.MarshalSSZ()
assert.NoError(t, err)
assert.NotEqual(t, 0, len(b))
assert.NotEqual(t, 0, wsb.SizeSSZ())
assert.NoError(t, wsb.UnmarshalSSZ(b))
}
func TestBellatrixSignedBeaconBlock_Version(t *testing.T) {
wsb, err := wrapper.WrappedSignedBeaconBlock(&ethpb.SignedBeaconBlockBellatrix{Block: &ethpb.BeaconBlockBellatrix{}})
require.NoError(t, err)
assert.Equal(t, version.Bellatrix, wsb.Version())
}
func TestBellatrixBeaconBlock_Slot(t *testing.T) {
slot := types.Slot(546)
wb, err := wrapper.WrappedBellatrixBeaconBlock(&ethpb.BeaconBlockBellatrix{Slot: slot})
require.NoError(t, err)
assert.Equal(t, slot, wb.Slot())
}
func TestBellatrixBeaconBlock_ProposerIndex(t *testing.T) {
pi := types.ValidatorIndex(555)
wb, err := wrapper.WrappedBellatrixBeaconBlock(&ethpb.BeaconBlockBellatrix{ProposerIndex: pi})
require.NoError(t, err)
assert.Equal(t, pi, wb.ProposerIndex())
}
func TestBellatrixBeaconBlock_ParentRoot(t *testing.T) {
root := []byte{0xAA, 0xBF, 0x33, 0x01}
wb, err := wrapper.WrappedBellatrixBeaconBlock(&ethpb.BeaconBlockBellatrix{ParentRoot: root})
require.NoError(t, err)
assert.DeepEqual(t, root, wb.ParentRoot())
}
func TestBellatrixBeaconBlock_StateRoot(t *testing.T) {
root := []byte{0xAA, 0xBF, 0x33, 0x01}
wb, err := wrapper.WrappedBellatrixBeaconBlock(&ethpb.BeaconBlockBellatrix{StateRoot: root})
require.NoError(t, err)
assert.DeepEqual(t, root, wb.StateRoot())
}
func TestBellatrixBeaconBlock_Body(t *testing.T) {
body := &ethpb.BeaconBlockBodyBellatrix{Graffiti: []byte{0x44}}
wb, err := wrapper.WrappedBellatrixBeaconBlock(&ethpb.BeaconBlockBellatrix{Body: body})
require.NoError(t, err)
assert.Equal(t, body, wb.Body().Proto())
}
func TestBellatrixBeaconBlock_IsNil(t *testing.T) {
_, err := wrapper.WrappedBellatrixBeaconBlock(nil)
require.Equal(t, wrapper.ErrNilObjectWrapped, err)
wb, err := wrapper.WrappedBellatrixBeaconBlock(&ethpb.BeaconBlockBellatrix{})
require.NoError(t, err)
assert.Equal(t, false, wb.IsNil())
}
func TesTBellatrixBeaconBlock_IsBlinded(t *testing.T) {
wsb, err := wrapper.WrappedBeaconBlock(&ethpb.BeaconBlockBellatrix{})
require.NoError(t, err)
require.Equal(t, false, wsb.IsNil())
}
func TestBellatrixBeaconBlock_HashTreeRoot(t *testing.T) {
wb, err := wrapper.WrappedBellatrixBeaconBlock(util.HydrateBeaconBlockBellatrix(&ethpb.BeaconBlockBellatrix{}))
require.NoError(t, err)
rt, err := wb.HashTreeRoot()
assert.NoError(t, err)
assert.NotEmpty(t, rt)
}
func TestBellatrixBeaconBlock_Proto(t *testing.T) {
blk := &ethpb.BeaconBlockBellatrix{ProposerIndex: 234}
wb, err := wrapper.WrappedBellatrixBeaconBlock(blk)
require.NoError(t, err)
assert.Equal(t, blk, wb.Proto())
}
func TestBellatrixBeaconBlock_SSZ(t *testing.T) {
wb, err := wrapper.WrappedBellatrixBeaconBlock(util.HydrateBeaconBlockBellatrix(&ethpb.BeaconBlockBellatrix{}))
assert.NoError(t, err)
b, err := wb.MarshalSSZ()
assert.NoError(t, err)
assert.NotEqual(t, 0, len(b))
assert.NotEqual(t, 0, wb.SizeSSZ())
assert.NoError(t, wb.UnmarshalSSZ(b))
}
func TestBellatrixBeaconBlock_Version(t *testing.T) {
wb, err := wrapper.WrappedBellatrixBeaconBlock(&ethpb.BeaconBlockBellatrix{})
require.NoError(t, err)
assert.Equal(t, version.Bellatrix, wb.Version())
}
func TestBellatrixBeaconBlockBody_RandaoReveal(t *testing.T) {
root := []byte{0xAA, 0xBF, 0x33, 0x01}
wbb, err := wrapper.WrappedBellatrixBeaconBlockBody(&ethpb.BeaconBlockBodyBellatrix{RandaoReveal: root})
require.NoError(t, err)
assert.DeepEqual(t, root, wbb.RandaoReveal())
}
func TestBellatrixBeaconBlockBody_Eth1Data(t *testing.T) {
data := &ethpb.Eth1Data{}
body := &ethpb.BeaconBlockBodyBellatrix{
Eth1Data: data,
}
wbb, err := wrapper.WrappedBellatrixBeaconBlockBody(body)
require.NoError(t, err)
assert.Equal(t, data, wbb.Eth1Data())
}
func TestBellatrixBeaconBlockBody_Graffiti(t *testing.T) {
graffiti := []byte{0x66, 0xAA}
body := &ethpb.BeaconBlockBodyBellatrix{Graffiti: graffiti}
wbb, err := wrapper.WrappedBellatrixBeaconBlockBody(body)
require.NoError(t, err)
assert.DeepEqual(t, graffiti, wbb.Graffiti())
}
func TestBellatrixBeaconBlockBody_ProposerSlashings(t *testing.T) {
ps := []*ethpb.ProposerSlashing{
{Header_1: &ethpb.SignedBeaconBlockHeader{
Signature: []byte{0x11, 0x20},
}},
}
body := &ethpb.BeaconBlockBodyBellatrix{ProposerSlashings: ps}
wbb, err := wrapper.WrappedBellatrixBeaconBlockBody(body)
require.NoError(t, err)
assert.DeepEqual(t, ps, wbb.ProposerSlashings())
}
func TestBellatrixBeaconBlockBody_AttesterSlashings(t *testing.T) {
as := []*ethpb.AttesterSlashing{
{Attestation_1: &ethpb.IndexedAttestation{Signature: []byte{0x11}}},
}
body := &ethpb.BeaconBlockBodyBellatrix{AttesterSlashings: as}
wbb, err := wrapper.WrappedBellatrixBeaconBlockBody(body)
require.NoError(t, err)
assert.DeepEqual(t, as, wbb.AttesterSlashings())
}
func TestBellatrixBeaconBlockBody_Attestations(t *testing.T) {
atts := []*ethpb.Attestation{{Signature: []byte{0x88}}}
body := &ethpb.BeaconBlockBodyBellatrix{Attestations: atts}
wbb, err := wrapper.WrappedBellatrixBeaconBlockBody(body)
require.NoError(t, err)
assert.DeepEqual(t, atts, wbb.Attestations())
}
func TestBellatrixBeaconBlockBody_Deposits(t *testing.T) {
deposits := []*ethpb.Deposit{
{Proof: [][]byte{{0x54, 0x10}}},
}
body := &ethpb.BeaconBlockBodyBellatrix{Deposits: deposits}
wbb, err := wrapper.WrappedBellatrixBeaconBlockBody(body)
require.NoError(t, err)
assert.DeepEqual(t, deposits, wbb.Deposits())
}
func TestBellatrixBeaconBlockBody_VoluntaryExits(t *testing.T) {
exits := []*ethpb.SignedVoluntaryExit{
{Exit: &ethpb.VoluntaryExit{Epoch: 54}},
}
body := &ethpb.BeaconBlockBodyBellatrix{VoluntaryExits: exits}
wbb, err := wrapper.WrappedBellatrixBeaconBlockBody(body)
require.NoError(t, err)
assert.DeepEqual(t, exits, wbb.VoluntaryExits())
}
func TestBellatrixBeaconBlockBody_IsNil(t *testing.T) {
_, err := wrapper.WrappedBellatrixBeaconBlockBody(nil)
require.Equal(t, wrapper.ErrNilObjectWrapped, err)
wbb, err := wrapper.WrappedBellatrixBeaconBlockBody(&ethpb.BeaconBlockBodyBellatrix{})
require.NoError(t, err)
assert.Equal(t, false, wbb.IsNil())
}
func TestBellatrixBeaconBlockBody_HashTreeRoot(t *testing.T) {
wb, err := wrapper.WrappedBellatrixBeaconBlockBody(util.HydrateBeaconBlockBodyBellatrix(&ethpb.BeaconBlockBodyBellatrix{}))
assert.NoError(t, err)
rt, err := wb.HashTreeRoot()
assert.NoError(t, err)
assert.NotEmpty(t, rt)
}
func TestBellatrixBeaconBlockBody_Proto(t *testing.T) {
body := &ethpb.BeaconBlockBodyBellatrix{Graffiti: []byte{0x66, 0xAA}}
wbb, err := wrapper.WrappedBellatrixBeaconBlockBody(body)
require.NoError(t, err)
assert.Equal(t, body, wbb.Proto())
}
func TestBellatrixBeaconBlockBody_ExecutionPayload(t *testing.T) {
payloads := &enginev1.ExecutionPayload{
BlockNumber: 100,
}
body := &ethpb.BeaconBlockBodyBellatrix{ExecutionPayload: payloads}
wbb, err := wrapper.WrappedBellatrixBeaconBlockBody(body)
require.NoError(t, err)
got, err := wbb.ExecutionPayload()
require.NoError(t, err)
assert.DeepEqual(t, payloads, got)
}
func TestBellatrixBeaconBlock_PbGenericBlock(t *testing.T) {
abb := &ethpb.SignedBeaconBlockBellatrix{
Block: util.HydrateBeaconBlockBellatrix(&ethpb.BeaconBlockBellatrix{}),
}
wsb, err := wrapper.WrappedSignedBeaconBlock(abb)
require.NoError(t, err)
got, err := wsb.PbGenericBlock()
require.NoError(t, err)
assert.Equal(t, abb, got.GetBellatrix())
}
func TestBellatrixBeaconBlock_AsSignRequestObject(t *testing.T) {
abb := util.HydrateBeaconBlockBellatrix(&ethpb.BeaconBlockBellatrix{})
wsb, err := wrapper.WrappedBeaconBlock(abb)
require.NoError(t, err)
sro := wsb.AsSignRequestObject()
got, ok := sro.(*validatorpb.SignRequest_BlockV3)
require.Equal(t, true, ok, "Not a SignRequest_BlockV3")
assert.Equal(t, abb, got.BlockV3)
}
func TestBellatrixBeaconBlock_PbBlindedBellatrixBlock(t *testing.T) {
sb := &ethpb.SignedBeaconBlockBellatrix{
Block: &ethpb.BeaconBlockBellatrix{Slot: 66},
}
wsb, err := wrapper.WrappedSignedBeaconBlock(sb)
require.NoError(t, err)
_, err = wsb.PbBlindedBellatrixBlock()
require.ErrorContains(t, "unsupported blinded bellatrix block", err)
}
func TestBellatrixBeaconBlock_ExecutionPayloadHeader(t *testing.T) {
sb := &ethpb.SignedBeaconBlockBellatrix{
Block: &ethpb.BeaconBlockBellatrix{Slot: 66},
}
wsb, err := wrapper.WrappedSignedBeaconBlock(sb)
require.NoError(t, err)
_, err = wsb.Block().Body().ExecutionPayloadHeader()
require.ErrorContains(t, "unsupported field for block type", err)
}

View File

@@ -0,0 +1,314 @@
package wrapper
import (
ssz "github.com/ferranbt/fastssz"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/consensus-types/block"
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
enginev1 "github.com/prysmaticlabs/prysm/proto/engine/v1"
eth "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
validatorpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/validator-client"
"github.com/prysmaticlabs/prysm/runtime/version"
"google.golang.org/protobuf/proto"
)
var (
_ = block.SignedBeaconBlock(&Phase0SignedBeaconBlock{})
_ = block.BeaconBlock(&Phase0BeaconBlock{})
_ = block.BeaconBlockBody(&Phase0BeaconBlockBody{})
)
// Phase0SignedBeaconBlock is a convenience wrapper around a phase 0 beacon block
// object. 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.
type Phase0SignedBeaconBlock struct {
b *eth.SignedBeaconBlock
}
// wrappedPhase0SignedBeaconBlock is constructor which wraps a protobuf phase 0 block
// with the block wrapper.
func wrappedPhase0SignedBeaconBlock(b *eth.SignedBeaconBlock) block.SignedBeaconBlock {
return Phase0SignedBeaconBlock{b: b}
}
// Signature returns the respective block signature.
func (w Phase0SignedBeaconBlock) Signature() []byte {
return w.b.Signature
}
// Block returns the underlying beacon block object.
func (w Phase0SignedBeaconBlock) Block() block.BeaconBlock {
return WrappedPhase0BeaconBlock(w.b.Block)
}
// IsNil checks if the underlying beacon block is
// nil.
func (w Phase0SignedBeaconBlock) IsNil() bool {
return w.b == nil || w.Block().IsNil()
}
// Copy performs a deep copy of the signed beacon block
// object.
func (w Phase0SignedBeaconBlock) Copy() block.SignedBeaconBlock {
return wrappedPhase0SignedBeaconBlock(eth.CopySignedBeaconBlock(w.b))
}
// MarshalSSZ marshals the signed beacon block to its relevant ssz
// form.
func (w Phase0SignedBeaconBlock) MarshalSSZ() ([]byte, error) {
return w.b.MarshalSSZ()
}
// MarshalSSZTo marshals the signed beacon block's ssz
// form to the provided byte buffer.
func (w Phase0SignedBeaconBlock) MarshalSSZTo(dst []byte) ([]byte, error) {
return w.b.MarshalSSZTo(dst)
}
// SizeSSZ returns the size of the serialized signed block
func (w Phase0SignedBeaconBlock) SizeSSZ() int {
return w.b.SizeSSZ()
}
// UnmarshalSSZ unmarshals the signed beacon block from its relevant ssz
// form.
func (w Phase0SignedBeaconBlock) UnmarshalSSZ(buf []byte) error {
return w.b.UnmarshalSSZ(buf)
}
// Proto returns the block in its underlying protobuf
// interface.
func (w Phase0SignedBeaconBlock) Proto() proto.Message {
return w.b
}
// PbGenericBlock returns a generic signed beacon block.
func (w Phase0SignedBeaconBlock) PbGenericBlock() (*eth.GenericSignedBeaconBlock, error) {
return &eth.GenericSignedBeaconBlock{
Block: &eth.GenericSignedBeaconBlock_Phase0{Phase0: w.b},
}, nil
}
// PbPhase0Block returns the underlying protobuf object.
func (w Phase0SignedBeaconBlock) PbPhase0Block() (*eth.SignedBeaconBlock, error) {
return w.b, nil
}
// PbAltairBlock is a stub.
func (Phase0SignedBeaconBlock) PbAltairBlock() (*eth.SignedBeaconBlockAltair, error) {
return nil, ErrUnsupportedAltairBlock
}
// PbBellatrixBlock is a stub.
func (Phase0SignedBeaconBlock) PbBellatrixBlock() (*eth.SignedBeaconBlockBellatrix, error) {
return nil, ErrUnsupportedBellatrixBlock
}
// PbBlindedBellatrixBlock is a stub.
func (Phase0SignedBeaconBlock) PbBlindedBellatrixBlock() (*eth.SignedBlindedBeaconBlockBellatrix, error) {
return nil, ErrUnsupportedBlindedBellatrixBlock
}
// Version of the underlying protobuf object.
func (Phase0SignedBeaconBlock) Version() int {
return version.Phase0
}
func (w Phase0SignedBeaconBlock) Header() (*eth.SignedBeaconBlockHeader, error) {
root, err := w.b.Block.Body.HashTreeRoot()
if err != nil {
return nil, errors.Wrapf(err, "could not hash block")
}
return &eth.SignedBeaconBlockHeader{
Header: &eth.BeaconBlockHeader{
Slot: w.b.Block.Slot,
ProposerIndex: w.b.Block.ProposerIndex,
ParentRoot: w.b.Block.ParentRoot,
StateRoot: w.b.Block.StateRoot,
BodyRoot: root[:],
},
Signature: w.Signature(),
}, nil
}
// Phase0BeaconBlock is the wrapper for the actual block.
type Phase0BeaconBlock struct {
b *eth.BeaconBlock
}
// WrappedPhase0BeaconBlock is constructor which wraps a protobuf phase 0 object
// with the block wrapper.
//
// Deprecated: Use WrappedBeaconBlock.
func WrappedPhase0BeaconBlock(b *eth.BeaconBlock) block.BeaconBlock {
return Phase0BeaconBlock{b: b}
}
// Slot returns the respective slot of the block.
func (w Phase0BeaconBlock) Slot() types.Slot {
return w.b.Slot
}
// ProposerIndex returns the proposer index of the beacon block.
func (w Phase0BeaconBlock) ProposerIndex() types.ValidatorIndex {
return w.b.ProposerIndex
}
// ParentRoot returns the parent root of beacon block.
func (w Phase0BeaconBlock) ParentRoot() []byte {
return w.b.ParentRoot
}
// StateRoot returns the state root of the beacon block.
func (w Phase0BeaconBlock) StateRoot() []byte {
return w.b.StateRoot
}
// Body returns the underlying block body.
func (w Phase0BeaconBlock) Body() block.BeaconBlockBody {
return WrappedPhase0BeaconBlockBody(w.b.Body)
}
// IsNil checks if the beacon block is nil.
func (w Phase0BeaconBlock) IsNil() bool {
return w.b == nil || w.Body().IsNil()
}
// IsBlinded checks if the beacon block is a blinded block.
func (Phase0BeaconBlock) IsBlinded() bool {
return false
}
// HashTreeRoot returns the ssz root of the block.
func (w Phase0BeaconBlock) HashTreeRoot() ([32]byte, error) {
return w.b.HashTreeRoot()
}
// HashTreeRootWith ssz hashes the BeaconBlock object with a hasher.
func (w Phase0BeaconBlock) HashTreeRootWith(hh *ssz.Hasher) error {
return w.b.HashTreeRootWith(hh)
}
// MarshalSSZ marshals the block into its respective
// ssz form.
func (w Phase0BeaconBlock) MarshalSSZ() ([]byte, error) {
return w.b.MarshalSSZ()
}
// MarshalSSZTo marshals the beacon block's ssz
// form to the provided byte buffer.
func (w Phase0BeaconBlock) MarshalSSZTo(dst []byte) ([]byte, error) {
return w.b.MarshalSSZTo(dst)
}
// SizeSSZ returns the size of the serialized block.
func (w Phase0BeaconBlock) SizeSSZ() int {
return w.b.SizeSSZ()
}
// UnmarshalSSZ unmarshals the beacon block from its relevant ssz
// form.
func (w Phase0BeaconBlock) UnmarshalSSZ(buf []byte) error {
return w.b.UnmarshalSSZ(buf)
}
// Proto returns the underlying block object in its
// proto form.
func (w Phase0BeaconBlock) Proto() proto.Message {
return w.b
}
// Version of the underlying protobuf object.
func (Phase0BeaconBlock) Version() int {
return version.Phase0
}
// AsSignRequestObject returns the underlying sign request object.
func (w Phase0BeaconBlock) AsSignRequestObject() validatorpb.SignRequestObject {
return &validatorpb.SignRequest_Block{
Block: w.b,
}
}
// Phase0BeaconBlockBody is a wrapper of a beacon block body.
type Phase0BeaconBlockBody struct {
b *eth.BeaconBlockBody
}
// WrappedPhase0BeaconBlockBody is constructor which wraps a protobuf phase 0 object
// with the block wrapper.
func WrappedPhase0BeaconBlockBody(b *eth.BeaconBlockBody) block.BeaconBlockBody {
return Phase0BeaconBlockBody{b: b}
}
// RandaoReveal returns the randao reveal from the block body.
func (w Phase0BeaconBlockBody) RandaoReveal() []byte {
return w.b.RandaoReveal
}
// Eth1Data returns the eth1 data in the block.
func (w Phase0BeaconBlockBody) Eth1Data() *eth.Eth1Data {
return w.b.Eth1Data
}
// Graffiti returns the graffiti in the block.
func (w Phase0BeaconBlockBody) Graffiti() []byte {
return w.b.Graffiti
}
// ProposerSlashings returns the proposer slashings in the block.
func (w Phase0BeaconBlockBody) ProposerSlashings() []*eth.ProposerSlashing {
return w.b.ProposerSlashings
}
// AttesterSlashings returns the attester slashings in the block.
func (w Phase0BeaconBlockBody) AttesterSlashings() []*eth.AttesterSlashing {
return w.b.AttesterSlashings
}
// Attestations returns the stored attestations in the block.
func (w Phase0BeaconBlockBody) Attestations() []*eth.Attestation {
return w.b.Attestations
}
// Deposits returns the stored deposits in the block.
func (w Phase0BeaconBlockBody) Deposits() []*eth.Deposit {
return w.b.Deposits
}
// VoluntaryExits returns the voluntary exits in the block.
func (w Phase0BeaconBlockBody) VoluntaryExits() []*eth.SignedVoluntaryExit {
return w.b.VoluntaryExits
}
// SyncAggregate returns the sync aggregate in the block.
func (Phase0BeaconBlockBody) SyncAggregate() (*eth.SyncAggregate, error) {
return nil, errors.New("Sync aggregate is not supported in phase 0 block")
}
// IsNil checks if the block body is nil.
func (w Phase0BeaconBlockBody) IsNil() bool {
return w.b == nil
}
// HashTreeRoot returns the ssz root of the block body.
func (w Phase0BeaconBlockBody) HashTreeRoot() ([32]byte, error) {
return w.b.HashTreeRoot()
}
// Proto returns the underlying proto form of the block
// body.
func (w Phase0BeaconBlockBody) Proto() proto.Message {
return w.b
}
// ExecutionPayload is a stub.
func (w Phase0BeaconBlockBody) ExecutionPayload() (*enginev1.ExecutionPayload, error) {
return nil, errors.Wrapf(ErrUnsupportedField, "ExecutionPayload for %T", w)
}
// ExecutionPayloadHeader is a stub.
func (w Phase0BeaconBlockBody) ExecutionPayloadHeader() (*eth.ExecutionPayloadHeader, error) {
return nil, errors.Wrapf(ErrUnsupportedField, "ExecutionPayloadHeader for %T", w)
}

View File

@@ -0,0 +1,87 @@
package wrapper_test
import (
"testing"
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
"github.com/prysmaticlabs/prysm/consensus-types/wrapper"
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
validatorpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/validator-client"
"github.com/prysmaticlabs/prysm/testing/assert"
"github.com/prysmaticlabs/prysm/testing/require"
"github.com/prysmaticlabs/prysm/testing/util"
)
func TestPhase0SignedBeaconBlock_Header(t *testing.T) {
root := bytesutil.PadTo([]byte("root"), 32)
signature := bytesutil.PadTo([]byte("sig"), 96)
body := &ethpb.BeaconBlockBody{}
body = util.HydrateBeaconBlockBody(body)
bodyRoot, err := body.HashTreeRoot()
require.NoError(t, err)
block := &ethpb.SignedBeaconBlock{
Block: &ethpb.BeaconBlock{
Slot: 1,
ProposerIndex: 1,
ParentRoot: root,
StateRoot: root,
Body: body,
},
Signature: signature,
}
wrapped, err := wrapper.WrappedSignedBeaconBlock(block)
require.NoError(t, err)
header, err := wrapped.Header()
require.NoError(t, err)
assert.Equal(t, types.ValidatorIndex(1), header.Header.ProposerIndex)
assert.Equal(t, types.Slot(1), header.Header.Slot)
assert.DeepEqual(t, bodyRoot[:], header.Header.BodyRoot)
assert.DeepEqual(t, root, header.Header.StateRoot)
assert.DeepEqual(t, root, header.Header.ParentRoot)
assert.DeepEqual(t, signature, header.Signature)
}
func TestBeaconBlock_PbGenericBlock(t *testing.T) {
abb := &ethpb.SignedBeaconBlock{
Block: util.HydrateBeaconBlock(&ethpb.BeaconBlock{}),
}
wsb, err := wrapper.WrappedSignedBeaconBlock(abb)
require.NoError(t, err)
got, err := wsb.PbGenericBlock()
require.NoError(t, err)
assert.Equal(t, abb, got.GetPhase0())
}
func TestBeaconBlock_AsSignRequestObject(t *testing.T) {
abb := util.HydrateBeaconBlock(&ethpb.BeaconBlock{})
wsb, err := wrapper.WrappedBeaconBlock(abb)
require.NoError(t, err)
sro := wsb.AsSignRequestObject()
got, ok := sro.(*validatorpb.SignRequest_Block)
require.Equal(t, true, ok, "Not a SignRequest_Block")
assert.Equal(t, abb, got.Block)
}
func TestPhase0BeaconBlock_PbBlindedBellatrixBlock(t *testing.T) {
sb := &ethpb.SignedBeaconBlock{
Block: &ethpb.BeaconBlock{Slot: 66},
}
wsb, err := wrapper.WrappedSignedBeaconBlock(sb)
require.NoError(t, err)
_, err = wsb.PbBlindedBellatrixBlock()
require.ErrorContains(t, "unsupported blinded bellatrix block", err)
}
func TestPhase0BeaconBlock_ExecutionPayloadHeader(t *testing.T) {
sb := &ethpb.SignedBeaconBlock{
Block: &ethpb.BeaconBlock{Slot: 66},
}
wsb, err := wrapper.WrappedSignedBeaconBlock(sb)
require.NoError(t, err)
_, err = wsb.Block().Body().ExecutionPayloadHeader()
require.ErrorContains(t, "unsupported field for block type", err)
}

View File

@@ -0,0 +1,45 @@
package wrapper_test
import (
"testing"
"github.com/prysmaticlabs/prysm/consensus-types/wrapper"
"github.com/prysmaticlabs/prysm/testing/require"
"github.com/prysmaticlabs/prysm/testing/util"
)
func TestWrappedSignedBeaconBlock(t *testing.T) {
tests := []struct {
name string
blk interface{}
wantErr bool
}{
{
name: "unsupported type",
blk: "not a beacon block",
wantErr: true,
},
{
name: "phase0",
blk: util.NewBeaconBlock(),
},
{
name: "altair",
blk: util.NewBeaconBlockAltair(),
},
{
name: "bellatrix",
blk: util.NewBeaconBlockBellatrix(),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
_, err := wrapper.WrappedSignedBeaconBlock(tt.blk)
if tt.wantErr {
require.ErrorIs(t, err, wrapper.ErrUnsupportedSignedBeaconBlock)
} else {
require.NoError(t, err)
}
})
}
}

View File

@@ -0,0 +1,322 @@
package wrapper
import (
ssz "github.com/ferranbt/fastssz"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/consensus-types/block"
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
enginev1 "github.com/prysmaticlabs/prysm/proto/engine/v1"
eth "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
validatorpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/validator-client"
"github.com/prysmaticlabs/prysm/runtime/version"
"google.golang.org/protobuf/proto"
)
var (
_ = block.SignedBeaconBlock(&signedBlindedBeaconBlockBellatrix{})
_ = block.BeaconBlock(&blindedBeaconBlockBellatrix{})
_ = block.BeaconBlockBody(&blindedBeaconBlockBodyBellatrix{})
)
// signedBlindedBeaconBlockBellatrix is a convenience wrapper around a Bellatrix blinded beacon block
// object. 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.
type signedBlindedBeaconBlockBellatrix struct {
b *eth.SignedBlindedBeaconBlockBellatrix
}
// wrappedBellatrixSignedBlindedBeaconBlock is a constructor which wraps a protobuf Bellatrix blinded block with the block wrapper.
func wrappedBellatrixSignedBlindedBeaconBlock(b *eth.SignedBlindedBeaconBlockBellatrix) (block.SignedBeaconBlock, error) {
w := signedBlindedBeaconBlockBellatrix{b: b}
if w.IsNil() {
return nil, ErrNilObjectWrapped
}
return w, nil
}
// Signature returns the respective block signature.
func (w signedBlindedBeaconBlockBellatrix) Signature() []byte {
return w.b.Signature
}
// Block returns the underlying beacon block object.
func (w signedBlindedBeaconBlockBellatrix) Block() block.BeaconBlock {
return blindedBeaconBlockBellatrix{b: w.b.Block}
}
// IsNil checks if the underlying beacon block is nil.
func (w signedBlindedBeaconBlockBellatrix) IsNil() bool {
return w.b == nil || w.b.Block == nil
}
// Copy performs a deep copy of the signed beacon block object.
func (w signedBlindedBeaconBlockBellatrix) Copy() block.SignedBeaconBlock {
return signedBlindedBeaconBlockBellatrix{b: eth.CopySignedBlindedBeaconBlockBellatrix(w.b)}
}
// MarshalSSZ marshals the signed beacon block to its relevant ssz form.
func (w signedBlindedBeaconBlockBellatrix) MarshalSSZ() ([]byte, error) {
return w.b.MarshalSSZ()
}
// MarshalSSZTo marshals the signed beacon block's ssz
// form to the provided byte buffer.
func (w signedBlindedBeaconBlockBellatrix) MarshalSSZTo(dst []byte) ([]byte, error) {
return w.b.MarshalSSZTo(dst)
}
// SizeSSZ returns the size of the serialized signed block
func (w signedBlindedBeaconBlockBellatrix) SizeSSZ() int {
return w.b.SizeSSZ()
}
// UnmarshalSSZ unmarshals the signed beacon block from its relevant ssz
// form.
func (w signedBlindedBeaconBlockBellatrix) UnmarshalSSZ(buf []byte) error {
return w.b.UnmarshalSSZ(buf)
}
// Proto returns the block in its underlying protobuf interface.
func (w signedBlindedBeaconBlockBellatrix) Proto() proto.Message {
return w.b
}
// PbGenericBlock returns a generic signed beacon block.
func (w signedBlindedBeaconBlockBellatrix) PbGenericBlock() (*eth.GenericSignedBeaconBlock, error) {
return &eth.GenericSignedBeaconBlock{
Block: &eth.GenericSignedBeaconBlock_BlindedBellatrix{BlindedBellatrix: w.b},
}, nil
}
// PbBellatrixBlock returns the underlying protobuf object.
func (signedBlindedBeaconBlockBellatrix) PbBellatrixBlock() (*eth.SignedBeaconBlockBellatrix, error) {
return nil, ErrUnsupportedBellatrixBlock
}
// PbBlindedBellatrixBlock returns the underlying protobuf object.
func (w signedBlindedBeaconBlockBellatrix) PbBlindedBellatrixBlock() (*eth.SignedBlindedBeaconBlockBellatrix, error) {
return w.b, nil
}
// PbPhase0Block returns the underlying protobuf object.
func (signedBlindedBeaconBlockBellatrix) PbPhase0Block() (*eth.SignedBeaconBlock, error) {
return nil, ErrUnsupportedPhase0Block
}
// PbAltairBlock returns the underlying protobuf object.
func (signedBlindedBeaconBlockBellatrix) PbAltairBlock() (*eth.SignedBeaconBlockAltair, error) {
return nil, ErrUnsupportedAltairBlock
}
// Version of the underlying protobuf object.
func (signedBlindedBeaconBlockBellatrix) Version() int {
return version.Bellatrix
}
// Header converts the underlying protobuf object from blinded block to header format.
func (w signedBlindedBeaconBlockBellatrix) Header() (*eth.SignedBeaconBlockHeader, error) {
root, err := w.b.Block.Body.HashTreeRoot()
if err != nil {
return nil, errors.Wrapf(err, "could not hash block")
}
return &eth.SignedBeaconBlockHeader{
Header: &eth.BeaconBlockHeader{
Slot: w.b.Block.Slot,
ProposerIndex: w.b.Block.ProposerIndex,
ParentRoot: w.b.Block.ParentRoot,
StateRoot: w.b.Block.StateRoot,
BodyRoot: root[:],
},
Signature: w.Signature(),
}, nil
}
// blindedBeaconBlockBellatrix is the wrapper for the actual block.
type blindedBeaconBlockBellatrix struct {
b *eth.BlindedBeaconBlockBellatrix
}
// WrappedBellatrixBlindedBeaconBlock is a constructor which wraps a protobuf Bellatrix object
// with the block wrapper.
//
// Deprecated: Use WrappedBeaconBlock.
func WrappedBellatrixBlindedBeaconBlock(b *eth.BlindedBeaconBlockBellatrix) (block.BeaconBlock, error) {
w := blindedBeaconBlockBellatrix{b: b}
if w.IsNil() {
return nil, ErrNilObjectWrapped
}
return w, nil
}
// Slot returns the respective slot of the block.
func (w blindedBeaconBlockBellatrix) Slot() types.Slot {
return w.b.Slot
}
// ProposerIndex returns the proposer index of the beacon block.
func (w blindedBeaconBlockBellatrix) ProposerIndex() types.ValidatorIndex {
return w.b.ProposerIndex
}
// ParentRoot returns the parent root of beacon block.
func (w blindedBeaconBlockBellatrix) ParentRoot() []byte {
return w.b.ParentRoot
}
// StateRoot returns the state root of the beacon block.
func (w blindedBeaconBlockBellatrix) StateRoot() []byte {
return w.b.StateRoot
}
// Body returns the underlying block body.
func (w blindedBeaconBlockBellatrix) Body() block.BeaconBlockBody {
return blindedBeaconBlockBodyBellatrix{b: w.b.Body}
}
// IsNil checks if the beacon block is nil.
func (w blindedBeaconBlockBellatrix) IsNil() bool {
return w.b == nil
}
// IsBlinded checks if the beacon block is a blinded block.
func (blindedBeaconBlockBellatrix) IsBlinded() bool {
return true
}
// HashTreeRoot returns the ssz root of the block.
func (w blindedBeaconBlockBellatrix) HashTreeRoot() ([32]byte, error) {
return w.b.HashTreeRoot()
}
// HashTreeRootWith ssz hashes the BeaconBlock object with a hasher.
func (w blindedBeaconBlockBellatrix) HashTreeRootWith(hh *ssz.Hasher) error {
return w.b.HashTreeRootWith(hh)
}
// MarshalSSZ marshals the block into its respective
// ssz form.
func (w blindedBeaconBlockBellatrix) MarshalSSZ() ([]byte, error) {
return w.b.MarshalSSZ()
}
// MarshalSSZTo marshals the beacon block's ssz
// form to the provided byte buffer.
func (w blindedBeaconBlockBellatrix) MarshalSSZTo(dst []byte) ([]byte, error) {
return w.b.MarshalSSZTo(dst)
}
// SizeSSZ returns the size of the serialized block.
func (w blindedBeaconBlockBellatrix) SizeSSZ() int {
return w.b.SizeSSZ()
}
// UnmarshalSSZ unmarshals the beacon block from its relevant ssz
// form.
func (w blindedBeaconBlockBellatrix) UnmarshalSSZ(buf []byte) error {
return w.b.UnmarshalSSZ(buf)
}
// Proto returns the underlying block object in its
// proto form.
func (w blindedBeaconBlockBellatrix) Proto() proto.Message {
return w.b
}
// Version of the underlying protobuf object.
func (blindedBeaconBlockBellatrix) Version() int {
return version.Bellatrix
}
// AsSignRequestObject returns the underlying sign request object.
func (w blindedBeaconBlockBellatrix) AsSignRequestObject() validatorpb.SignRequestObject {
return &validatorpb.SignRequest_BlindedBlockV3{
BlindedBlockV3: w.b,
}
}
// blindedBeaconBlockBodyBellatrix is a wrapper of a beacon block body.
type blindedBeaconBlockBodyBellatrix struct {
b *eth.BlindedBeaconBlockBodyBellatrix
}
// WrappedBellatrixBlindedBeaconBlockBody is a constructor which wraps a protobuf bellatrix object
// with the block wrapper.
func WrappedBellatrixBlindedBeaconBlockBody(b *eth.BlindedBeaconBlockBodyBellatrix) (block.BeaconBlockBody, error) {
w := blindedBeaconBlockBodyBellatrix{b: b}
if w.IsNil() {
return nil, ErrNilObjectWrapped
}
return w, nil
}
// RandaoReveal returns the randao reveal from the block body.
func (w blindedBeaconBlockBodyBellatrix) RandaoReveal() []byte {
return w.b.RandaoReveal
}
// Eth1Data returns the eth1 data in the block.
func (w blindedBeaconBlockBodyBellatrix) Eth1Data() *eth.Eth1Data {
return w.b.Eth1Data
}
// Graffiti returns the graffiti in the block.
func (w blindedBeaconBlockBodyBellatrix) Graffiti() []byte {
return w.b.Graffiti
}
// ProposerSlashings returns the proposer slashings in the block.
func (w blindedBeaconBlockBodyBellatrix) ProposerSlashings() []*eth.ProposerSlashing {
return w.b.ProposerSlashings
}
// AttesterSlashings returns the attester slashings in the block.
func (w blindedBeaconBlockBodyBellatrix) AttesterSlashings() []*eth.AttesterSlashing {
return w.b.AttesterSlashings
}
// Attestations returns the stored attestations in the block.
func (w blindedBeaconBlockBodyBellatrix) Attestations() []*eth.Attestation {
return w.b.Attestations
}
// Deposits returns the stored deposits in the block.
func (w blindedBeaconBlockBodyBellatrix) Deposits() []*eth.Deposit {
return w.b.Deposits
}
// VoluntaryExits returns the voluntary exits in the block.
func (w blindedBeaconBlockBodyBellatrix) VoluntaryExits() []*eth.SignedVoluntaryExit {
return w.b.VoluntaryExits
}
// SyncAggregate returns the sync aggregate in the block.
func (w blindedBeaconBlockBodyBellatrix) SyncAggregate() (*eth.SyncAggregate, error) {
return w.b.SyncAggregate, nil
}
// IsNil checks if the block body is nil.
func (w blindedBeaconBlockBodyBellatrix) IsNil() bool {
return w.b == nil
}
// HashTreeRoot returns the ssz root of the block body.
func (w blindedBeaconBlockBodyBellatrix) HashTreeRoot() ([32]byte, error) {
return w.b.HashTreeRoot()
}
// Proto returns the underlying proto form of the block
// body.
func (w blindedBeaconBlockBodyBellatrix) Proto() proto.Message {
return w.b
}
// ExecutionPayload returns the execution payload of the block body.
func (w blindedBeaconBlockBodyBellatrix) ExecutionPayload() (*enginev1.ExecutionPayload, error) {
return nil, errors.Wrapf(ErrUnsupportedField, "ExecutionPayload for %T", w)
}
// ExecutionPayloadHeader returns the execution payload header of the block body.
func (w blindedBeaconBlockBodyBellatrix) ExecutionPayloadHeader() (*eth.ExecutionPayloadHeader, error) {
return w.b.ExecutionPayloadHeader, nil
}

View File

@@ -0,0 +1,392 @@
package wrapper_test
import (
"bytes"
"testing"
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
"github.com/prysmaticlabs/prysm/consensus-types/wrapper"
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
validatorpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/validator-client"
"github.com/prysmaticlabs/prysm/runtime/version"
"github.com/prysmaticlabs/prysm/testing/assert"
"github.com/prysmaticlabs/prysm/testing/require"
"github.com/prysmaticlabs/prysm/testing/util"
)
func TestBellatrixSignedBlindedBeaconBlock_Header(t *testing.T) {
root := bytesutil.PadTo([]byte("root"), 32)
signature := bytesutil.PadTo([]byte("sig"), 96)
body := &ethpb.BlindedBeaconBlockBodyBellatrix{}
body = util.HydrateBlindedBeaconBlockBodyBellatrix(body)
bodyRoot, err := body.HashTreeRoot()
require.NoError(t, err)
block := &ethpb.SignedBlindedBeaconBlockBellatrix{
Block: &ethpb.BlindedBeaconBlockBellatrix{
Slot: 1,
ProposerIndex: 1,
ParentRoot: root,
StateRoot: root,
Body: body,
},
Signature: signature,
}
wrapped, err := wrapper.WrappedSignedBeaconBlock(block)
require.NoError(t, err)
header, err := wrapped.Header()
require.NoError(t, err)
assert.Equal(t, types.ValidatorIndex(1), header.Header.ProposerIndex)
assert.Equal(t, types.Slot(1), header.Header.Slot)
assert.DeepEqual(t, bodyRoot[:], header.Header.BodyRoot)
assert.DeepEqual(t, root, header.Header.StateRoot)
assert.DeepEqual(t, root, header.Header.ParentRoot)
assert.DeepEqual(t, signature, header.Signature)
}
func TestBellatrixSignedBlindedBeaconBlock_Signature(t *testing.T) {
sig := []byte{0x11, 0x22}
wsb, err := wrapper.WrappedSignedBeaconBlock(&ethpb.SignedBlindedBeaconBlockBellatrix{Block: &ethpb.BlindedBeaconBlockBellatrix{}, Signature: sig})
require.NoError(t, err)
if !bytes.Equal(sig, wsb.Signature()) {
t.Error("Wrong signature returned")
}
}
func TestBellatrixSignedBlindedBeaconBlock_Block(t *testing.T) {
blk := &ethpb.BlindedBeaconBlockBellatrix{Slot: 54}
wsb, err := wrapper.WrappedSignedBeaconBlock(&ethpb.SignedBlindedBeaconBlockBellatrix{Block: blk})
require.NoError(t, err)
assert.DeepEqual(t, blk, wsb.Block().Proto())
}
func TestBellatrixSignedBlindedBeaconBlock_IsNil(t *testing.T) {
_, err := wrapper.WrappedSignedBeaconBlock(nil)
require.Equal(t, wrapper.ErrNilObjectWrapped, err)
wsb, err := wrapper.WrappedSignedBeaconBlock(&ethpb.SignedBlindedBeaconBlockBellatrix{Block: &ethpb.BlindedBeaconBlockBellatrix{}})
require.NoError(t, err)
assert.Equal(t, false, wsb.IsNil())
}
func TestBellatrixSignedBlindedBeaconBlock_Copy(t *testing.T) {
t.Skip("TODO: Missing mutation evaluation helpers")
}
func TestBellatrixSignedBlindedBeaconBlock_Proto(t *testing.T) {
sb := &ethpb.SignedBlindedBeaconBlockBellatrix{
Block: &ethpb.BlindedBeaconBlockBellatrix{Slot: 66},
Signature: []byte{0x11, 0x22},
}
wsb, err := wrapper.WrappedSignedBeaconBlock(sb)
require.NoError(t, err)
assert.Equal(t, sb, wsb.Proto())
}
func TestBellatrixSignedBlindedBeaconBlock_PbPhase0Block(t *testing.T) {
wsb, err := wrapper.WrappedSignedBeaconBlock(&ethpb.SignedBlindedBeaconBlockBellatrix{Block: &ethpb.BlindedBeaconBlockBellatrix{}})
require.NoError(t, err)
if _, err := wsb.PbPhase0Block(); err != wrapper.ErrUnsupportedPhase0Block {
t.Errorf("Wrong error returned. Want %v got %v", wrapper.ErrUnsupportedPhase0Block, err)
}
}
func TestBellatrixSignedBlindedBeaconBlock_PbBellatrixBlock(t *testing.T) {
sb := &ethpb.SignedBlindedBeaconBlockBellatrix{
Block: &ethpb.BlindedBeaconBlockBellatrix{Slot: 66},
Signature: []byte{0x11, 0x22},
}
wsb, err := wrapper.WrappedSignedBeaconBlock(sb)
require.NoError(t, err)
_, err = wsb.PbBellatrixBlock()
require.ErrorContains(t, "unsupported bellatrix block", err)
}
func TestBellatrixSignedBlindedBeaconBlock_PbBlindedBellatrixBlock(t *testing.T) {
sb := &ethpb.SignedBlindedBeaconBlockBellatrix{
Block: &ethpb.BlindedBeaconBlockBellatrix{Slot: 66},
Signature: []byte{0x11, 0x22},
}
wsb, err := wrapper.WrappedSignedBeaconBlock(sb)
require.NoError(t, err)
got, err := wsb.PbBlindedBellatrixBlock()
assert.NoError(t, err)
assert.Equal(t, sb, got)
}
func TestBellatrixSignedBlindedBeaconBlock_MarshalSSZTo(t *testing.T) {
wsb, err := wrapper.WrappedSignedBeaconBlock(util.HydrateSignedBlindedBeaconBlockBellatrix(&ethpb.SignedBlindedBeaconBlockBellatrix{}))
assert.NoError(t, err)
var b []byte
b, err = wsb.MarshalSSZTo(b)
assert.NoError(t, err)
assert.NotEqual(t, 0, len(b))
}
func TestBellatrixSignedBlindedBeaconBlock_SSZ(t *testing.T) {
wsb, err := wrapper.WrappedSignedBeaconBlock(util.HydrateSignedBlindedBeaconBlockBellatrix(&ethpb.SignedBlindedBeaconBlockBellatrix{}))
assert.NoError(t, err)
b, err := wsb.MarshalSSZ()
assert.NoError(t, err)
assert.NotEqual(t, 0, len(b))
assert.NotEqual(t, 0, wsb.SizeSSZ())
assert.NoError(t, wsb.UnmarshalSSZ(b))
}
func TestBellatrixSignedBlindedBeaconBlock_Version(t *testing.T) {
wsb, err := wrapper.WrappedSignedBeaconBlock(&ethpb.SignedBlindedBeaconBlockBellatrix{Block: &ethpb.BlindedBeaconBlockBellatrix{}})
require.NoError(t, err)
assert.Equal(t, version.Bellatrix, wsb.Version())
}
func TestBellatrixBlindedBeaconBlock_Slot(t *testing.T) {
slot := types.Slot(546)
wb, err := wrapper.WrappedBeaconBlock(&ethpb.BlindedBeaconBlockBellatrix{Slot: slot})
require.NoError(t, err)
assert.Equal(t, slot, wb.Slot())
}
func TestBellatrixBlindedBeaconBlock_ProposerIndex(t *testing.T) {
pi := types.ValidatorIndex(555)
wb, err := wrapper.WrappedBeaconBlock(&ethpb.BlindedBeaconBlockBellatrix{ProposerIndex: pi})
require.NoError(t, err)
assert.Equal(t, pi, wb.ProposerIndex())
}
func TestBellatrixBlindedBeaconBlock_ParentRoot(t *testing.T) {
root := []byte{0xAA, 0xBF, 0x33, 0x01}
wb, err := wrapper.WrappedBeaconBlock(&ethpb.BlindedBeaconBlockBellatrix{ParentRoot: root})
require.NoError(t, err)
assert.DeepEqual(t, root, wb.ParentRoot())
}
func TestBellatrixBlindedBeaconBlock_StateRoot(t *testing.T) {
root := []byte{0xAA, 0xBF, 0x33, 0x01}
wb, err := wrapper.WrappedBeaconBlock(&ethpb.BlindedBeaconBlockBellatrix{StateRoot: root})
require.NoError(t, err)
assert.DeepEqual(t, root, wb.StateRoot())
}
func TestBellatrixBlindedBeaconBlock_Body(t *testing.T) {
body := &ethpb.BlindedBeaconBlockBodyBellatrix{Graffiti: []byte{0x44}}
wb, err := wrapper.WrappedBeaconBlock(&ethpb.BlindedBeaconBlockBellatrix{Body: body})
require.NoError(t, err)
assert.Equal(t, body, wb.Body().Proto())
}
func TestBellatrixBlindedBeaconBlock_IsNil(t *testing.T) {
_, err := wrapper.WrappedBellatrixBlindedBeaconBlockBody(nil)
require.Equal(t, wrapper.ErrNilObjectWrapped, err)
wb, err := wrapper.WrappedBeaconBlock(&ethpb.BlindedBeaconBlockBellatrix{})
require.NoError(t, err)
assert.Equal(t, false, wb.IsNil())
}
func TestBellatrixBlindedBeaconBlock_IsBlinded(t *testing.T) {
wb, err := wrapper.WrappedBeaconBlock(&ethpb.BlindedBeaconBlockBellatrix{})
require.NoError(t, err)
assert.Equal(t, true, wb.IsBlinded())
}
func TestBellatrixBlindedBeaconBlock_HashTreeRoot(t *testing.T) {
wb, err := wrapper.WrappedBeaconBlock(util.HydrateBlindedBeaconBlockBellatrix(&ethpb.BlindedBeaconBlockBellatrix{}))
require.NoError(t, err)
rt, err := wb.HashTreeRoot()
assert.NoError(t, err)
assert.NotEmpty(t, rt)
}
func TestBellatrixBlindedBeaconBlock_Proto(t *testing.T) {
blk := &ethpb.BlindedBeaconBlockBellatrix{ProposerIndex: 234}
wb, err := wrapper.WrappedBeaconBlock(blk)
require.NoError(t, err)
assert.Equal(t, blk, wb.Proto())
}
func TestBellatrixBlindedBeaconBlock_SSZ(t *testing.T) {
wb, err := wrapper.WrappedBeaconBlock(util.HydrateBlindedBeaconBlockBellatrix(&ethpb.BlindedBeaconBlockBellatrix{}))
assert.NoError(t, err)
b, err := wb.MarshalSSZ()
assert.NoError(t, err)
assert.NotEqual(t, 0, len(b))
assert.NotEqual(t, 0, wb.SizeSSZ())
assert.NoError(t, wb.UnmarshalSSZ(b))
}
func TestBellatrixBlindedBeaconBlock_Version(t *testing.T) {
wb, err := wrapper.WrappedBeaconBlock(&ethpb.BlindedBeaconBlockBellatrix{})
require.NoError(t, err)
assert.Equal(t, version.Bellatrix, wb.Version())
}
func TestBellatrixBlindedBeaconBlockBody_RandaoReveal(t *testing.T) {
root := []byte{0xAA, 0xBF, 0x33, 0x01}
wbb, err := wrapper.WrappedBellatrixBlindedBeaconBlockBody(&ethpb.BlindedBeaconBlockBodyBellatrix{RandaoReveal: root})
require.NoError(t, err)
assert.DeepEqual(t, root, wbb.RandaoReveal())
}
func TestBellatrixBlindedBeaconBlockBody_Eth1Data(t *testing.T) {
data := &ethpb.Eth1Data{}
body := &ethpb.BlindedBeaconBlockBodyBellatrix{
Eth1Data: data,
}
wbb, err := wrapper.WrappedBellatrixBlindedBeaconBlockBody(body)
require.NoError(t, err)
assert.Equal(t, data, wbb.Eth1Data())
}
func TestBellatrixBlindedBeaconBlockBody_Graffiti(t *testing.T) {
graffiti := []byte{0x66, 0xAA}
body := &ethpb.BlindedBeaconBlockBodyBellatrix{Graffiti: graffiti}
wbb, err := wrapper.WrappedBellatrixBlindedBeaconBlockBody(body)
require.NoError(t, err)
assert.DeepEqual(t, graffiti, wbb.Graffiti())
}
func TestBellatrixBlindedBeaconBlockBody_ProposerSlashings(t *testing.T) {
ps := []*ethpb.ProposerSlashing{
{Header_1: &ethpb.SignedBeaconBlockHeader{
Signature: []byte{0x11, 0x20},
}},
}
body := &ethpb.BlindedBeaconBlockBodyBellatrix{ProposerSlashings: ps}
wbb, err := wrapper.WrappedBellatrixBlindedBeaconBlockBody(body)
require.NoError(t, err)
assert.DeepEqual(t, ps, wbb.ProposerSlashings())
}
func TestBellatrixBlindedBeaconBlockBody_AttesterSlashings(t *testing.T) {
as := []*ethpb.AttesterSlashing{
{Attestation_1: &ethpb.IndexedAttestation{Signature: []byte{0x11}}},
}
body := &ethpb.BlindedBeaconBlockBodyBellatrix{AttesterSlashings: as}
wbb, err := wrapper.WrappedBellatrixBlindedBeaconBlockBody(body)
require.NoError(t, err)
assert.DeepEqual(t, as, wbb.AttesterSlashings())
}
func TestBellatrixBlindedBeaconBlockBody_Attestations(t *testing.T) {
atts := []*ethpb.Attestation{{Signature: []byte{0x88}}}
body := &ethpb.BlindedBeaconBlockBodyBellatrix{Attestations: atts}
wbb, err := wrapper.WrappedBellatrixBlindedBeaconBlockBody(body)
require.NoError(t, err)
assert.DeepEqual(t, atts, wbb.Attestations())
}
func TestBellatrixBlindedBeaconBlockBody_Deposits(t *testing.T) {
deposits := []*ethpb.Deposit{
{Proof: [][]byte{{0x54, 0x10}}},
}
body := &ethpb.BlindedBeaconBlockBodyBellatrix{Deposits: deposits}
wbb, err := wrapper.WrappedBellatrixBlindedBeaconBlockBody(body)
require.NoError(t, err)
assert.DeepEqual(t, deposits, wbb.Deposits())
}
func TestBellatrixBlindedBeaconBlockBody_VoluntaryExits(t *testing.T) {
exits := []*ethpb.SignedVoluntaryExit{
{Exit: &ethpb.VoluntaryExit{Epoch: 54}},
}
body := &ethpb.BlindedBeaconBlockBodyBellatrix{VoluntaryExits: exits}
wbb, err := wrapper.WrappedBellatrixBlindedBeaconBlockBody(body)
require.NoError(t, err)
assert.DeepEqual(t, exits, wbb.VoluntaryExits())
}
func TestBellatrixBlindedBeaconBlockBody_IsNil(t *testing.T) {
_, err := wrapper.WrappedBellatrixBlindedBeaconBlockBody(nil)
require.Equal(t, wrapper.ErrNilObjectWrapped, err)
wbb, err := wrapper.WrappedBellatrixBlindedBeaconBlockBody(&ethpb.BlindedBeaconBlockBodyBellatrix{})
require.NoError(t, err)
assert.Equal(t, false, wbb.IsNil())
}
func TestBellatrixBlindedBeaconBlockBody_HashTreeRoot(t *testing.T) {
wb, err := wrapper.WrappedBellatrixBlindedBeaconBlockBody(util.HydrateBlindedBeaconBlockBodyBellatrix(&ethpb.BlindedBeaconBlockBodyBellatrix{}))
assert.NoError(t, err)
rt, err := wb.HashTreeRoot()
assert.NoError(t, err)
assert.NotEmpty(t, rt)
}
func TestBellatrixBlindedBeaconBlockBody_Proto(t *testing.T) {
body := &ethpb.BlindedBeaconBlockBodyBellatrix{Graffiti: []byte{0x66, 0xAA}}
wbb, err := wrapper.WrappedBellatrixBlindedBeaconBlockBody(body)
require.NoError(t, err)
assert.Equal(t, body, wbb.Proto())
}
func TestBellatrixBlindedBeaconBlockBody_ExecutionPayloadHeader(t *testing.T) {
payloads := &ethpb.ExecutionPayloadHeader{
BlockNumber: 100,
}
body := &ethpb.BlindedBeaconBlockBodyBellatrix{ExecutionPayloadHeader: payloads}
wbb, err := wrapper.WrappedBellatrixBlindedBeaconBlockBody(body)
require.NoError(t, err)
_, err = wbb.ExecutionPayload()
require.ErrorContains(t, wrapper.ErrUnsupportedField.Error(), err)
}
func TestBellatrixBlindedBeaconBlock_PbGenericBlock(t *testing.T) {
abb := &ethpb.SignedBlindedBeaconBlockBellatrix{
Block: util.HydrateBlindedBeaconBlockBellatrix(&ethpb.BlindedBeaconBlockBellatrix{}),
}
wsb, err := wrapper.WrappedSignedBeaconBlock(abb)
require.NoError(t, err)
got, err := wsb.PbGenericBlock()
require.NoError(t, err)
assert.Equal(t, abb, got.GetBlindedBellatrix())
}
func TestBellatrixBlindedBeaconBlock_AsSignRequestObject(t *testing.T) {
abb := util.HydrateBlindedBeaconBlockBellatrix(&ethpb.BlindedBeaconBlockBellatrix{})
wsb, err := wrapper.WrappedBeaconBlock(abb)
require.NoError(t, err)
sro := wsb.AsSignRequestObject()
got, ok := sro.(*validatorpb.SignRequest_BlindedBlockV3)
require.Equal(t, true, ok, "Not a SignRequest_BlockV3")
assert.Equal(t, abb, got.BlindedBlockV3)
}

View File

@@ -0,0 +1,159 @@
package wrapper
import (
"github.com/prysmaticlabs/go-bitfield"
pb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/metadata"
"github.com/prysmaticlabs/prysm/runtime/version"
"google.golang.org/protobuf/proto"
)
// MetadataV0 is a convenience wrapper around our metadata protobuf object.
type MetadataV0 struct {
md *pb.MetaDataV0
}
// WrappedMetadataV0 wrappers around the provided protobuf object.
func WrappedMetadataV0(md *pb.MetaDataV0) MetadataV0 {
return MetadataV0{md: md}
}
// SequenceNumber returns the sequence number from the metadata.
func (m MetadataV0) SequenceNumber() uint64 {
return m.md.SeqNumber
}
// AttnetsBitfield retruns the bitfield stored in the metadata.
func (m MetadataV0) AttnetsBitfield() bitfield.Bitvector64 {
return m.md.Attnets
}
// InnerObject returns the underlying metadata protobuf structure.
func (m MetadataV0) InnerObject() interface{} {
return m.md
}
// IsNil checks for the nilness of the underlying object.
func (m MetadataV0) IsNil() bool {
return m.md == nil
}
// Copy performs a full copy of the underlying metadata object.
func (m MetadataV0) Copy() metadata.Metadata {
return WrappedMetadataV0(proto.Clone(m.md).(*pb.MetaDataV0))
}
// MarshalSSZ marshals the underlying metadata object
// into its serialized form.
func (m MetadataV0) MarshalSSZ() ([]byte, error) {
return m.md.MarshalSSZ()
}
// MarshalSSZTo marshals the underlying metadata object
// into its serialized form into the provided byte buffer.
func (m MetadataV0) MarshalSSZTo(dst []byte) ([]byte, error) {
return m.md.MarshalSSZTo(dst)
}
// SizeSSZ returns the serialized size of the metadata object.
func (m MetadataV0) SizeSSZ() int {
return m.md.SizeSSZ()
}
// UnmarshalSSZ unmarshals the provided byte buffer into
// the underlying metadata object.
func (m MetadataV0) UnmarshalSSZ(buf []byte) error {
return m.md.UnmarshalSSZ(buf)
}
// MetadataObjV0 returns the inner metadata object in its type
// specified form. If it doesn't exist then we return nothing.
func (m MetadataV0) MetadataObjV0() *pb.MetaDataV0 {
return m.md
}
// MetadataObjV1 returns the inner metatdata object in its type
// specified form. If it doesn't exist then we return nothing.
func (_ MetadataV0) MetadataObjV1() *pb.MetaDataV1 {
return nil
}
// Version returns the fork version of the underlying object.
func (_ MetadataV0) Version() int {
return version.Phase0
}
// MetadataV1 is a convenience wrapper around our metadata v2 protobuf object.
type MetadataV1 struct {
md *pb.MetaDataV1
}
// WrappedMetadataV1 wrappers around the provided protobuf object.
func WrappedMetadataV1(md *pb.MetaDataV1) MetadataV1 {
return MetadataV1{md: md}
}
// SequenceNumber returns the sequence number from the metadata.
func (m MetadataV1) SequenceNumber() uint64 {
return m.md.SeqNumber
}
// AttnetsBitfield retruns the bitfield stored in the metadata.
func (m MetadataV1) AttnetsBitfield() bitfield.Bitvector64 {
return m.md.Attnets
}
// InnerObject returns the underlying metadata protobuf structure.
func (m MetadataV1) InnerObject() interface{} {
return m.md
}
// IsNil checks for the nilness of the underlying object.
func (m MetadataV1) IsNil() bool {
return m.md == nil
}
// Copy performs a full copy of the underlying metadata object.
func (m MetadataV1) Copy() metadata.Metadata {
return WrappedMetadataV1(proto.Clone(m.md).(*pb.MetaDataV1))
}
// MarshalSSZ marshals the underlying metadata object
// into its serialized form.
func (m MetadataV1) MarshalSSZ() ([]byte, error) {
return m.md.MarshalSSZ()
}
// MarshalSSZTo marshals the underlying metadata object
// into its serialized form into the provided byte buffer.
func (m MetadataV1) MarshalSSZTo(dst []byte) ([]byte, error) {
return m.md.MarshalSSZTo(dst)
}
// SizeSSZ returns the serialized size of the metadata object.
func (m MetadataV1) SizeSSZ() int {
return m.md.SizeSSZ()
}
// UnmarshalSSZ unmarshals the provided byte buffer into
// the underlying metadata object.
func (m MetadataV1) UnmarshalSSZ(buf []byte) error {
return m.md.UnmarshalSSZ(buf)
}
// MetadataObjV0 returns the inner metadata object in its type
// specified form. If it doesn't exist then we return nothing.
func (_ MetadataV1) MetadataObjV0() *pb.MetaDataV0 {
return nil
}
// MetadataObjV1 returns the inner metatdata object in its type
// specified form. If it doesn't exist then we return nothing.
func (m MetadataV1) MetadataObjV1() *pb.MetaDataV1 {
return m.md
}
// Version returns the fork version of the underlying object.
func (_ MetadataV1) Version() int {
return version.Altair
}

View File

@@ -0,0 +1,77 @@
package wrapper
import (
"fmt"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/consensus-types/block"
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
eth "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/runtime/version"
)
type BlockMutator struct {
Phase0 func(beaconBlock *eth.SignedBeaconBlock)
Altair func(beaconBlock *eth.SignedBeaconBlockAltair)
Bellatrix func(beaconBlock *eth.SignedBeaconBlockBellatrix)
}
func (m BlockMutator) Apply(b block.SignedBeaconBlock) error {
switch b.Version() {
case version.Phase0:
bb, err := b.PbPhase0Block()
if err != nil {
return err
}
m.Phase0(bb)
return nil
case version.Altair:
bb, err := b.PbAltairBlock()
if err != nil {
return err
}
m.Altair(bb)
return nil
case version.Bellatrix:
bb, err := b.PbBellatrixBlock()
if err != nil {
return err
}
m.Bellatrix(bb)
return nil
}
msg := fmt.Sprintf("version %d = %s", b.Version(), version.String(b.Version()))
return errors.Wrap(ErrUnsupportedSignedBeaconBlock, msg)
}
func SetBlockStateRoot(b block.SignedBeaconBlock, sr [32]byte) error {
return BlockMutator{
Phase0: func(bb *eth.SignedBeaconBlock) { bb.Block.StateRoot = sr[:] },
Altair: func(bb *eth.SignedBeaconBlockAltair) { bb.Block.StateRoot = sr[:] },
Bellatrix: func(bb *eth.SignedBeaconBlockBellatrix) { bb.Block.StateRoot = sr[:] },
}.Apply(b)
}
func SetBlockParentRoot(b block.SignedBeaconBlock, pr [32]byte) error {
return BlockMutator{
Phase0: func(bb *eth.SignedBeaconBlock) { bb.Block.ParentRoot = pr[:] },
Altair: func(bb *eth.SignedBeaconBlockAltair) { bb.Block.ParentRoot = pr[:] },
Bellatrix: func(bb *eth.SignedBeaconBlockBellatrix) { bb.Block.ParentRoot = pr[:] },
}.Apply(b)
}
func SetBlockSlot(b block.SignedBeaconBlock, s types.Slot) error {
return BlockMutator{
Phase0: func(bb *eth.SignedBeaconBlock) { bb.Block.Slot = s },
Altair: func(bb *eth.SignedBeaconBlockAltair) { bb.Block.Slot = s },
Bellatrix: func(bb *eth.SignedBeaconBlockBellatrix) { bb.Block.Slot = s },
}.Apply(b)
}
func SetProposerIndex(b block.SignedBeaconBlock, idx types.ValidatorIndex) error {
return BlockMutator{
Phase0: func(bb *eth.SignedBeaconBlock) { bb.Block.ProposerIndex = idx },
Altair: func(bb *eth.SignedBeaconBlockAltair) { bb.Block.ProposerIndex = idx },
Bellatrix: func(bb *eth.SignedBeaconBlockBellatrix) { bb.Block.ProposerIndex = idx },
}.Apply(b)
}