mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-09 15:37:56 -05:00
Add payload attribute type (#11710)
* Add payload attribute type * Gazelle * Fix test Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
This commit is contained in:
@@ -117,7 +117,7 @@ func (b *SignedBeaconBlock) PbGenericBlock() (*eth.GenericSignedBeaconBlock, err
|
||||
// PbPhase0Block returns the underlying protobuf object.
|
||||
func (b *SignedBeaconBlock) PbPhase0Block() (*eth.SignedBeaconBlock, error) {
|
||||
if b.version != version.Phase0 {
|
||||
return nil, errNotSupported("PbPhase0Block", b.version)
|
||||
return nil, ErrNotSupported("PbPhase0Block", b.version)
|
||||
}
|
||||
pb, err := b.Proto()
|
||||
if err != nil {
|
||||
@@ -129,7 +129,7 @@ func (b *SignedBeaconBlock) PbPhase0Block() (*eth.SignedBeaconBlock, error) {
|
||||
// PbAltairBlock returns the underlying protobuf object.
|
||||
func (b *SignedBeaconBlock) PbAltairBlock() (*eth.SignedBeaconBlockAltair, error) {
|
||||
if b.version != version.Altair {
|
||||
return nil, errNotSupported("PbAltairBlock", b.version)
|
||||
return nil, ErrNotSupported("PbAltairBlock", b.version)
|
||||
}
|
||||
pb, err := b.Proto()
|
||||
if err != nil {
|
||||
@@ -141,7 +141,7 @@ func (b *SignedBeaconBlock) PbAltairBlock() (*eth.SignedBeaconBlockAltair, error
|
||||
// PbBellatrixBlock returns the underlying protobuf object.
|
||||
func (b *SignedBeaconBlock) PbBellatrixBlock() (*eth.SignedBeaconBlockBellatrix, error) {
|
||||
if b.version != version.Bellatrix || b.IsBlinded() {
|
||||
return nil, errNotSupported("PbBellatrixBlock", b.version)
|
||||
return nil, ErrNotSupported("PbBellatrixBlock", b.version)
|
||||
}
|
||||
pb, err := b.Proto()
|
||||
if err != nil {
|
||||
@@ -153,7 +153,7 @@ func (b *SignedBeaconBlock) PbBellatrixBlock() (*eth.SignedBeaconBlockBellatrix,
|
||||
// PbBlindedBellatrixBlock returns the underlying protobuf object.
|
||||
func (b *SignedBeaconBlock) PbBlindedBellatrixBlock() (*eth.SignedBlindedBeaconBlockBellatrix, error) {
|
||||
if b.version != version.Bellatrix || !b.IsBlinded() {
|
||||
return nil, errNotSupported("PbBlindedBellatrixBlock", b.version)
|
||||
return nil, ErrNotSupported("PbBlindedBellatrixBlock", b.version)
|
||||
}
|
||||
pb, err := b.Proto()
|
||||
if err != nil {
|
||||
@@ -165,7 +165,7 @@ func (b *SignedBeaconBlock) PbBlindedBellatrixBlock() (*eth.SignedBlindedBeaconB
|
||||
// PbCapellaBlock returns the underlying protobuf object.
|
||||
func (b *SignedBeaconBlock) PbCapellaBlock() (*eth.SignedBeaconBlockCapella, error) {
|
||||
if b.version != version.Capella || b.IsBlinded() {
|
||||
return nil, errNotSupported("PbCapellaBlock", b.version)
|
||||
return nil, ErrNotSupported("PbCapellaBlock", b.version)
|
||||
}
|
||||
pb, err := b.Proto()
|
||||
if err != nil {
|
||||
@@ -177,7 +177,7 @@ func (b *SignedBeaconBlock) PbCapellaBlock() (*eth.SignedBeaconBlockCapella, err
|
||||
// PbBlindedCapellaBlock returns the underlying protobuf object.
|
||||
func (b *SignedBeaconBlock) PbBlindedCapellaBlock() (*eth.SignedBlindedBeaconBlockCapella, error) {
|
||||
if b.version != version.Capella || !b.IsBlinded() {
|
||||
return nil, errNotSupported("PbBlindedCapellaBlock", b.version)
|
||||
return nil, ErrNotSupported("PbBlindedCapellaBlock", b.version)
|
||||
}
|
||||
pb, err := b.Proto()
|
||||
if err != nil {
|
||||
@@ -779,7 +779,7 @@ func (b *BeaconBlockBody) VoluntaryExits() []*eth.SignedVoluntaryExit {
|
||||
// SyncAggregate returns the sync aggregate in the block.
|
||||
func (b *BeaconBlockBody) SyncAggregate() (*eth.SyncAggregate, error) {
|
||||
if b.version == version.Phase0 {
|
||||
return nil, errNotSupported("SyncAggregate", b.version)
|
||||
return nil, ErrNotSupported("SyncAggregate", b.version)
|
||||
}
|
||||
return b.syncAggregate, nil
|
||||
}
|
||||
@@ -788,7 +788,7 @@ func (b *BeaconBlockBody) SyncAggregate() (*eth.SyncAggregate, error) {
|
||||
func (b *BeaconBlockBody) Execution() (interfaces.ExecutionData, error) {
|
||||
switch b.version {
|
||||
case version.Phase0, version.Altair:
|
||||
return nil, errNotSupported("Execution", b.version)
|
||||
return nil, ErrNotSupported("Execution", b.version)
|
||||
case version.Bellatrix:
|
||||
if b.isBlinded {
|
||||
var ph *enginev1.ExecutionPayloadHeader
|
||||
@@ -838,7 +838,7 @@ func (b *BeaconBlockBody) Execution() (interfaces.ExecutionData, error) {
|
||||
|
||||
func (b *BeaconBlockBody) BLSToExecutionChanges() ([]*eth.SignedBLSToExecutionChange, error) {
|
||||
if b.version < version.Capella {
|
||||
return nil, errNotSupported("BLSToExecutionChanges", b.version)
|
||||
return nil, ErrNotSupported("BLSToExecutionChanges", b.version)
|
||||
}
|
||||
return b.blsToExecutionChanges, nil
|
||||
}
|
||||
|
||||
@@ -75,6 +75,6 @@ type SignedBeaconBlock struct {
|
||||
signature [field_params.BLSSignatureLength]byte
|
||||
}
|
||||
|
||||
func errNotSupported(funcName string, ver int) error {
|
||||
func ErrNotSupported(funcName string, ver int) error {
|
||||
return errors.Wrap(ErrUnsupportedGetter, fmt.Sprintf("%s is not supported for %s", funcName, version.String(ver)))
|
||||
}
|
||||
|
||||
29
consensus-types/payload-attribute/BUILD.bazel
Normal file
29
consensus-types/payload-attribute/BUILD.bazel
Normal file
@@ -0,0 +1,29 @@
|
||||
load("@prysm//tools/go:def.bzl", "go_library", "go_test")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"getters.go",
|
||||
"interface.go",
|
||||
"types.go",
|
||||
],
|
||||
importpath = "github.com/prysmaticlabs/prysm/v3/consensus-types/payload-attribute",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//consensus-types/blocks:go_default_library",
|
||||
"//proto/engine/v1:go_default_library",
|
||||
"//runtime/version:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["getters_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//proto/engine/v1:go_default_library",
|
||||
"//runtime/version:go_default_library",
|
||||
"//testing/require:go_default_library",
|
||||
],
|
||||
)
|
||||
76
consensus-types/payload-attribute/getters.go
Normal file
76
consensus-types/payload-attribute/getters.go
Normal file
@@ -0,0 +1,76 @@
|
||||
package payloadattribute
|
||||
|
||||
import (
|
||||
"github.com/prysmaticlabs/prysm/v3/consensus-types/blocks"
|
||||
enginev1 "github.com/prysmaticlabs/prysm/v3/proto/engine/v1"
|
||||
"github.com/prysmaticlabs/prysm/v3/runtime/version"
|
||||
)
|
||||
|
||||
// Version returns the version of the payload attribute.
|
||||
func (a *data) Version() int {
|
||||
return a.version
|
||||
}
|
||||
|
||||
// PrevRandao returns the previous randao value of the payload attribute.
|
||||
func (a *data) PrevRandao() []byte {
|
||||
return a.prevRandao
|
||||
}
|
||||
|
||||
// Timestamps returns the timestamp of the payload attribute.
|
||||
func (a *data) Timestamps() uint64 {
|
||||
return a.timeStamp
|
||||
}
|
||||
|
||||
// SuggestedFeeRecipient returns the suggested fee recipient of the payload attribute.
|
||||
func (a *data) SuggestedFeeRecipient() []byte {
|
||||
return a.suggestedFeeRecipient
|
||||
}
|
||||
|
||||
// Withdrawals returns the withdrawals of the payload attribute.
|
||||
// Support for withdrawals was added in version 2 of the payload attribute.
|
||||
func (a *data) Withdrawals() ([]*enginev1.Withdrawal, error) {
|
||||
if a == nil {
|
||||
return nil, errNilPayloadAttribute
|
||||
}
|
||||
if a.version < version.Capella {
|
||||
return nil, blocks.ErrNotSupported("Withdrawals", a.version)
|
||||
}
|
||||
return a.withdrawals, nil
|
||||
}
|
||||
|
||||
// PbV1 returns the payload attribute in version 1.
|
||||
func (a *data) PbV1() (*enginev1.PayloadAttributes, error) {
|
||||
if a == nil {
|
||||
return nil, errNilPayloadAttribute
|
||||
}
|
||||
if a.version != version.Bellatrix {
|
||||
return nil, blocks.ErrNotSupported("PayloadAttributePbV1", a.version)
|
||||
}
|
||||
if a.timeStamp == 0 && len(a.prevRandao) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
return &enginev1.PayloadAttributes{
|
||||
Timestamp: a.timeStamp,
|
||||
PrevRandao: a.prevRandao,
|
||||
SuggestedFeeRecipient: a.suggestedFeeRecipient,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// PbV2 returns the payload attribute in version 2.
|
||||
func (a *data) PbV2() (*enginev1.PayloadAttributesV2, error) {
|
||||
if a == nil {
|
||||
return nil, errNilPayloadAttribute
|
||||
}
|
||||
if a.version != version.Capella {
|
||||
return nil, blocks.ErrNotSupported("PayloadAttributePbV2", a.version)
|
||||
}
|
||||
if a.timeStamp == 0 && len(a.prevRandao) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
return &enginev1.PayloadAttributesV2{
|
||||
Timestamp: a.timeStamp,
|
||||
PrevRandao: a.prevRandao,
|
||||
SuggestedFeeRecipient: a.suggestedFeeRecipient,
|
||||
Withdrawals: a.withdrawals,
|
||||
}, nil
|
||||
}
|
||||
143
consensus-types/payload-attribute/getters_test.go
Normal file
143
consensus-types/payload-attribute/getters_test.go
Normal file
@@ -0,0 +1,143 @@
|
||||
package payloadattribute
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
enginev1 "github.com/prysmaticlabs/prysm/v3/proto/engine/v1"
|
||||
"github.com/prysmaticlabs/prysm/v3/runtime/version"
|
||||
"github.com/prysmaticlabs/prysm/v3/testing/require"
|
||||
)
|
||||
|
||||
func TestPayloadAttributeGetters(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
tc func(t *testing.T)
|
||||
}{
|
||||
{
|
||||
name: "Get version",
|
||||
tc: func(t *testing.T) {
|
||||
a := EmptyWithVersion(version.Capella)
|
||||
require.Equal(t, version.Capella, a.Version())
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Get prev randao",
|
||||
tc: func(t *testing.T) {
|
||||
r := []byte{1, 2, 3}
|
||||
a, err := New(&enginev1.PayloadAttributes{PrevRandao: r})
|
||||
require.NoError(t, err)
|
||||
require.DeepEqual(t, r, a.PrevRandao())
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Get suggested fee recipient",
|
||||
tc: func(t *testing.T) {
|
||||
r := []byte{4, 5, 6}
|
||||
a, err := New(&enginev1.PayloadAttributes{SuggestedFeeRecipient: r})
|
||||
require.NoError(t, err)
|
||||
require.DeepEqual(t, r, a.SuggestedFeeRecipient())
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Get timestamp",
|
||||
tc: func(t *testing.T) {
|
||||
r := uint64(123)
|
||||
a, err := New(&enginev1.PayloadAttributes{Timestamp: r})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, r, a.Timestamps())
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Get withdrawals (bellatrix)",
|
||||
tc: func(t *testing.T) {
|
||||
a := EmptyWithVersion(version.Bellatrix)
|
||||
_, err := a.Withdrawals()
|
||||
require.ErrorContains(t, "Withdrawals is not supported for bellatrix: unsupported getter", err)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Get withdrawals (capella)",
|
||||
tc: func(t *testing.T) {
|
||||
wd := []*enginev1.Withdrawal{{WithdrawalIndex: 1}, {WithdrawalIndex: 2}, {WithdrawalIndex: 3}}
|
||||
a, err := New(&enginev1.PayloadAttributesV2{Withdrawals: wd})
|
||||
require.NoError(t, err)
|
||||
got, err := a.Withdrawals()
|
||||
require.NoError(t, err)
|
||||
require.DeepEqual(t, wd, got)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Get PbV1 (bad version)",
|
||||
tc: func(t *testing.T) {
|
||||
a, err := New(&enginev1.PayloadAttributes{})
|
||||
require.NoError(t, err)
|
||||
_, err = a.PbV2()
|
||||
require.ErrorContains(t, "PayloadAttributePbV2 is not supported for bellatrix: unsupported getter", err)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Get PbV2 (bad version)",
|
||||
tc: func(t *testing.T) {
|
||||
a, err := New(&enginev1.PayloadAttributesV2{})
|
||||
require.NoError(t, err)
|
||||
_, err = a.PbV1()
|
||||
require.ErrorContains(t, "PayloadAttributePbV1 is not supported for capella: unsupported getter", err)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Get PbV1 (nil)",
|
||||
tc: func(t *testing.T) {
|
||||
a, err := New(&enginev1.PayloadAttributes{})
|
||||
require.NoError(t, err)
|
||||
got, err := a.PbV1()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, (*enginev1.PayloadAttributes)(nil), got)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Get PbV2 (nil)",
|
||||
tc: func(t *testing.T) {
|
||||
a, err := New(&enginev1.PayloadAttributesV2{})
|
||||
require.NoError(t, err)
|
||||
got, err := a.PbV2()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, (*enginev1.PayloadAttributesV2)(nil), got)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Get PbV1",
|
||||
tc: func(t *testing.T) {
|
||||
p := &enginev1.PayloadAttributes{
|
||||
Timestamp: 1,
|
||||
PrevRandao: []byte{1, 2, 3},
|
||||
SuggestedFeeRecipient: []byte{4, 5, 6},
|
||||
}
|
||||
a, err := New(p)
|
||||
require.NoError(t, err)
|
||||
got, err := a.PbV1()
|
||||
require.NoError(t, err)
|
||||
require.DeepEqual(t, p, got)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Get PbV2",
|
||||
tc: func(t *testing.T) {
|
||||
p := &enginev1.PayloadAttributesV2{
|
||||
Timestamp: 1,
|
||||
PrevRandao: []byte{1, 2, 3},
|
||||
SuggestedFeeRecipient: []byte{4, 5, 6},
|
||||
Withdrawals: []*enginev1.Withdrawal{{WithdrawalIndex: 1}, {WithdrawalIndex: 2}, {WithdrawalIndex: 3}},
|
||||
}
|
||||
a, err := New(p)
|
||||
require.NoError(t, err)
|
||||
got, err := a.PbV2()
|
||||
require.NoError(t, err)
|
||||
require.DeepEqual(t, p, got)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, test.tc)
|
||||
}
|
||||
}
|
||||
15
consensus-types/payload-attribute/interface.go
Normal file
15
consensus-types/payload-attribute/interface.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package payloadattribute
|
||||
|
||||
import (
|
||||
enginev1 "github.com/prysmaticlabs/prysm/v3/proto/engine/v1"
|
||||
)
|
||||
|
||||
type Attributer interface {
|
||||
Version() int
|
||||
PrevRandao() []byte
|
||||
Timestamps() uint64
|
||||
SuggestedFeeRecipient() []byte
|
||||
Withdrawals() ([]*enginev1.Withdrawal, error)
|
||||
PbV1() (*enginev1.PayloadAttributes, error)
|
||||
PbV2() (*enginev1.PayloadAttributesV2, error)
|
||||
}
|
||||
73
consensus-types/payload-attribute/types.go
Normal file
73
consensus-types/payload-attribute/types.go
Normal file
@@ -0,0 +1,73 @@
|
||||
package payloadattribute
|
||||
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v3/consensus-types/blocks"
|
||||
enginev1 "github.com/prysmaticlabs/prysm/v3/proto/engine/v1"
|
||||
"github.com/prysmaticlabs/prysm/v3/runtime/version"
|
||||
)
|
||||
|
||||
var (
|
||||
_ = Attributer(&data{})
|
||||
)
|
||||
|
||||
type data struct {
|
||||
version int
|
||||
timeStamp uint64
|
||||
prevRandao []byte
|
||||
suggestedFeeRecipient []byte
|
||||
withdrawals []*enginev1.Withdrawal
|
||||
}
|
||||
|
||||
var (
|
||||
errNilPayloadAttribute = errors.New("received nil payload attribute")
|
||||
errUnsupportedPayloadAttribute = errors.New("unsupported payload attribute")
|
||||
)
|
||||
|
||||
// New returns a new payload attribute with the given input object.
|
||||
func New(i interface{}) (Attributer, error) {
|
||||
switch a := i.(type) {
|
||||
case nil:
|
||||
return nil, blocks.ErrNilObject
|
||||
case *enginev1.PayloadAttributes:
|
||||
return initPayloadAttributeFromV1(a)
|
||||
case *enginev1.PayloadAttributesV2:
|
||||
return initPayloadAttributeFromV2(a)
|
||||
default:
|
||||
return nil, errors.Wrapf(errUnsupportedPayloadAttribute, "unable to create payload attribute from type %T", i)
|
||||
}
|
||||
}
|
||||
|
||||
// EmptyWithVersion returns an empty payload attribute with the given version.
|
||||
func EmptyWithVersion(version int) Attributer {
|
||||
return &data{
|
||||
version: version,
|
||||
}
|
||||
}
|
||||
|
||||
func initPayloadAttributeFromV1(a *enginev1.PayloadAttributes) (Attributer, error) {
|
||||
if a == nil {
|
||||
return nil, errNilPayloadAttribute
|
||||
}
|
||||
|
||||
return &data{
|
||||
version: version.Bellatrix,
|
||||
prevRandao: a.PrevRandao,
|
||||
timeStamp: a.Timestamp,
|
||||
suggestedFeeRecipient: a.SuggestedFeeRecipient,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func initPayloadAttributeFromV2(a *enginev1.PayloadAttributesV2) (Attributer, error) {
|
||||
if a == nil {
|
||||
return nil, errNilPayloadAttribute
|
||||
}
|
||||
|
||||
return &data{
|
||||
version: version.Capella,
|
||||
prevRandao: a.PrevRandao,
|
||||
timeStamp: a.Timestamp,
|
||||
suggestedFeeRecipient: a.SuggestedFeeRecipient,
|
||||
withdrawals: a.Withdrawals,
|
||||
}, nil
|
||||
}
|
||||
Reference in New Issue
Block a user