Compare commits

...

6 Commits

Author SHA1 Message Date
Kasey Kirkham
fdab4ef997 refactor ssz api resp handlers to avoid typed pbs 2024-04-30 14:10:26 -05:00
Kasey Kirkham
e18b767ebb removing typed pb accessors 2024-04-30 14:10:00 -05:00
Kasey Kirkham
da5ff38d81 fork-specific interface for electra 2024-04-29 13:08:50 -05:00
Preston Van Loon
c13e5089b3 gocognit exclusion 2024-04-26 15:14:38 -05:00
Preston Van Loon
84ab470c12 Electra: consensus types 2024-04-26 14:00:44 -05:00
Preston Van Loon
eee47fea84 Electra: add electra version 2024-04-26 13:51:14 -05:00
22 changed files with 1195 additions and 402 deletions

View File

@@ -671,5 +671,5 @@ func ValidatorMaxEffectiveBalance(val *ethpb.Validator) uint64 {
if HasCompoundingWithdrawalCredential(val) {
return params.BeaconConfig().MaxEffectiveBalanceElectra
}
return params.BeaconConfig().MinActivationBalance // TODO: Add test that MinActivationBalance == (old) MaxEffectiveBalance
return params.BeaconConfig().MinActivationBalance
}

View File

@@ -59,6 +59,7 @@ go_library(
"@com_github_ethereum_go_ethereum//common/hexutil:go_default_library",
"@com_github_gorilla_mux//:go_default_library",
"@com_github_pkg_errors//:go_default_library",
"@com_github_prysmaticlabs_fastssz//:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",
"@io_opencensus_go//trace:go_default_library",
],

View File

@@ -13,6 +13,7 @@ import (
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/gorilla/mux"
"github.com/pkg/errors"
ssz "github.com/prysmaticlabs/fastssz"
"github.com/prysmaticlabs/prysm/v5/api"
"github.com/prysmaticlabs/prysm/v5/api/server/structs"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/cache/depositsnapshot"
@@ -46,6 +47,7 @@ const (
var (
errNilBlock = errors.New("nil block")
errEquivocatedBlock = errors.New("block is equivocated")
errMarshalSSZ = errors.New("could not marshal block into SSZ")
)
type handled bool
@@ -117,37 +119,28 @@ func (s *Server) getBlockV2(ctx context.Context, w http.ResponseWriter, blk inte
// getBlockSSZV2 returns the SSZ-serialized version of the beacon block for given block ID.
func (s *Server) getBlockSSZV2(ctx context.Context, w http.ResponseWriter, blk interfaces.ReadOnlySignedBeaconBlock) {
getBlockHandler := func(get func(ctx context.Context, block interfaces.ReadOnlySignedBeaconBlock) ([]byte, error), ver string) handled {
result, err := get(ctx, blk)
if result != nil {
w.Header().Set(api.VersionHeader, ver)
httputil.WriteSsz(w, result, "beacon_block.ssz")
return true
}
// ErrUnsupportedField means that we have another block type
if !errors.Is(err, consensus_types.ErrUnsupportedField) {
httputil.HandleError(w, "Could not get signed beacon block: "+err.Error(), http.StatusInternalServerError)
return true
}
return false
result, err := s.getUnblindedBlockRespSSZ(ctx, blk)
if err != nil {
httputil.HandleError(w, "Could not get signed beacon block: "+err.Error(), http.StatusInternalServerError)
}
if result == nil {
httputil.HandleError(w, fmt.Sprintf("Unknown block type %T", blk), http.StatusInternalServerError)
}
w.Header().Set(api.VersionHeader, version.String(blk.Version()))
httputil.WriteSsz(w, result, "beacon_block.ssz")
}
if getBlockHandler(s.getBlockDenebSSZ, version.String(version.Deneb)) {
return
// getBlindedBlockSSZ returns the SSZ-serialized version of the blinded beacon block for given block id.
func (s *Server) getBlindedBlockSSZ(w http.ResponseWriter, blk interfaces.ReadOnlySignedBeaconBlock) {
result, err := s.getBlindedBlockRespSSZ(blk)
if err != nil {
httputil.HandleError(w, "Could not get signed beacon block: "+err.Error(), http.StatusInternalServerError)
}
if getBlockHandler(s.getBlockCapellaSSZ, version.String(version.Capella)) {
return
if result == nil {
httputil.HandleError(w, fmt.Sprintf("Unknown block type %T", blk), http.StatusInternalServerError)
}
if getBlockHandler(s.getBlockBellatrixSSZ, version.String(version.Bellatrix)) {
return
}
if getBlockHandler(s.getBlockAltairSSZ, version.String(version.Altair)) {
return
}
if getBlockHandler(s.getBlockPhase0SSZ, version.String(version.Phase0)) {
return
}
httputil.HandleError(w, fmt.Sprintf("Unknown block type %T", blk), http.StatusInternalServerError)
w.Header().Set(api.VersionHeader, version.String(blk.Version()))
httputil.WriteSsz(w, result, "beacon_block.ssz")
}
// GetBlindedBlock retrieves blinded block for given block id.
@@ -166,7 +159,7 @@ func (s *Server) GetBlindedBlock(w http.ResponseWriter, r *http.Request) {
}
if httputil.RespondWithSsz(r) {
s.getBlindedBlockSSZ(ctx, w, blk)
s.getBlindedBlockSSZ(w, blk)
} else {
s.getBlindedBlock(ctx, w, blk)
}
@@ -215,41 +208,6 @@ func (s *Server) getBlindedBlock(ctx context.Context, w http.ResponseWriter, blk
httputil.HandleError(w, fmt.Sprintf("Unknown block type %T", blk), http.StatusInternalServerError)
}
// getBlindedBlockSSZ returns the SSZ-serialized version of the blinded beacon block for given block id.
func (s *Server) getBlindedBlockSSZ(ctx context.Context, w http.ResponseWriter, blk interfaces.ReadOnlySignedBeaconBlock) {
getBlockHandler := func(get func(ctx context.Context, block interfaces.ReadOnlySignedBeaconBlock) ([]byte, error), ver string) handled {
result, err := get(ctx, blk)
if result != nil {
w.Header().Set(api.VersionHeader, ver)
httputil.WriteSsz(w, result, "beacon_block.ssz")
return true
}
// ErrUnsupportedField means that we have another block type
if !errors.Is(err, consensus_types.ErrUnsupportedField) {
httputil.HandleError(w, "Could not get signed beacon block: "+err.Error(), http.StatusInternalServerError)
return true
}
return false
}
if getBlockHandler(s.getBlockPhase0SSZ, version.String(version.Phase0)) {
return
}
if getBlockHandler(s.getBlockAltairSSZ, version.String(version.Altair)) {
return
}
if getBlockHandler(s.getBlindedBlockBellatrixSSZ, version.String(version.Bellatrix)) {
return
}
if getBlockHandler(s.getBlindedBlockCapellaSSZ, version.String(version.Capella)) {
return
}
if getBlockHandler(s.getBlindedBlockDenebSSZ, version.String(version.Deneb)) {
return
}
httputil.HandleError(w, fmt.Sprintf("Unknown block type %T", blk), http.StatusInternalServerError)
}
func (*Server) getBlockPhase0(_ context.Context, blk interfaces.ReadOnlySignedBeaconBlock) (*structs.GetBlockV2Response, error) {
consensusBlk, err := blk.PbPhase0Block()
if err != nil {
@@ -458,135 +416,50 @@ func (s *Server) getBlockDeneb(ctx context.Context, blk interfaces.ReadOnlySigne
}, nil
}
func (*Server) getBlockPhase0SSZ(_ context.Context, blk interfaces.ReadOnlySignedBeaconBlock) ([]byte, error) {
consensusBlk, err := blk.PbPhase0Block()
// getUnblindedBlockRespSSZ attempts to reconstruct the full block before calling getBlockRespSSZ to finish the job.
func (s *Server) getUnblindedBlockRespSSZ(ctx context.Context, blk interfaces.ReadOnlySignedBeaconBlock) ([]byte, error) {
err := blocks.BeaconBlockIsNil(blk)
if err != nil {
return nil, errNilBlock
}
if blk.Version() >= version.Bellatrix && blk.IsBlinded() {
blk, err = s.ExecutionPayloadReconstructor.ReconstructFullBlock(ctx, blk)
if err != nil {
return nil, errors.Wrapf(err, "could not reconstruct full execution payload to create signed beacon block")
}
}
return s.getBlockRespSSZ(blk)
}
// getUnblindedBlockRespSSZ attempts to reconstruct the full block before calling getBlockRespSSZ to finish the job.
func (s *Server) getBlindedBlockRespSSZ(blk interfaces.ReadOnlySignedBeaconBlock) ([]byte, error) {
err := blocks.BeaconBlockIsNil(blk)
if err != nil {
return nil, errNilBlock
}
if blk.Version() >= version.Bellatrix && !blk.IsBlinded() {
blk, err = blk.ToBlinded()
if err != nil {
return nil, errors.Wrapf(err, "could not convert block to blinded block")
}
}
return s.getBlockRespSSZ(blk)
}
func (s *Server) getBlockRespSSZ(blk interfaces.ReadOnlySignedBeaconBlock) ([]byte, error) {
err := blocks.BeaconBlockIsNil(blk)
if err != nil {
return nil, errNilBlock
}
pb, err := blk.Proto()
if err != nil {
return nil, err
}
if consensusBlk == nil {
return nil, errNilBlock
marshaler, ok := pb.(ssz.Marshaler)
if !ok {
return nil, errMarshalSSZ
}
sszData, err := consensusBlk.MarshalSSZ()
if err != nil {
return nil, errors.Wrapf(err, "could not marshal block into SSZ")
}
return sszData, nil
}
func (*Server) getBlockAltairSSZ(_ context.Context, blk interfaces.ReadOnlySignedBeaconBlock) ([]byte, error) {
consensusBlk, err := blk.PbAltairBlock()
if err != nil {
return nil, err
}
if consensusBlk == nil {
return nil, errNilBlock
}
sszData, err := consensusBlk.MarshalSSZ()
if err != nil {
return nil, errors.Wrapf(err, "could not marshal block into SSZ")
}
return sszData, nil
}
func (s *Server) getBlockBellatrixSSZ(ctx context.Context, blk interfaces.ReadOnlySignedBeaconBlock) ([]byte, error) {
consensusBlk, err := blk.PbBellatrixBlock()
if err != nil {
// ErrUnsupportedField means that we have another block type
if errors.Is(err, consensus_types.ErrUnsupportedField) {
blindedConsensusBlk, err := blk.PbBlindedBellatrixBlock()
if err != nil {
return nil, err
}
if blindedConsensusBlk == nil {
return nil, errNilBlock
}
fullBlk, err := s.ExecutionPayloadReconstructor.ReconstructFullBlock(ctx, blk)
if err != nil {
return nil, errors.Wrapf(err, "could not reconstruct full execution payload to create signed beacon block")
}
consensusBlk, err = fullBlk.PbBellatrixBlock()
if err != nil {
return nil, errors.Wrapf(err, "could not get signed beacon block")
}
} else {
return nil, err
}
}
if consensusBlk == nil {
return nil, errNilBlock
}
sszData, err := consensusBlk.MarshalSSZ()
if err != nil {
return nil, errors.Wrapf(err, "could not marshal block into SSZ")
}
return sszData, nil
}
func (s *Server) getBlockCapellaSSZ(ctx context.Context, blk interfaces.ReadOnlySignedBeaconBlock) ([]byte, error) {
consensusBlk, err := blk.PbCapellaBlock()
if err != nil {
// ErrUnsupportedField means that we have another block type
if errors.Is(err, consensus_types.ErrUnsupportedField) {
blindedConsensusBlk, err := blk.PbBlindedCapellaBlock()
if err != nil {
return nil, err
}
if blindedConsensusBlk == nil {
return nil, errNilBlock
}
fullBlk, err := s.ExecutionPayloadReconstructor.ReconstructFullBlock(ctx, blk)
if err != nil {
return nil, errors.Wrapf(err, "could not reconstruct full execution payload to create signed beacon block")
}
consensusBlk, err = fullBlk.PbCapellaBlock()
if err != nil {
return nil, errors.Wrapf(err, "could not get signed beacon block")
}
} else {
return nil, err
}
}
if consensusBlk == nil {
return nil, errNilBlock
}
sszData, err := consensusBlk.MarshalSSZ()
if err != nil {
return nil, errors.Wrapf(err, "could not marshal block into SSZ")
}
return sszData, nil
}
func (s *Server) getBlockDenebSSZ(ctx context.Context, blk interfaces.ReadOnlySignedBeaconBlock) ([]byte, error) {
consensusBlk, err := blk.PbDenebBlock()
if err != nil {
// ErrUnsupportedGetter means that we have another block type
if errors.Is(err, consensus_types.ErrUnsupportedField) {
blindedConsensusBlk, err := blk.PbBlindedDenebBlock()
if err != nil {
return nil, err
}
if blindedConsensusBlk == nil {
return nil, errNilBlock
}
fullBlk, err := s.ExecutionPayloadReconstructor.ReconstructFullBlock(ctx, blk)
if err != nil {
return nil, errors.Wrapf(err, "could not reconstruct full execution payload to create signed beacon block")
}
consensusBlk, err = fullBlk.PbDenebBlock()
if err != nil {
return nil, errors.Wrapf(err, "could not get signed beacon block")
}
} else {
return nil, err
}
}
if consensusBlk == nil {
return nil, errNilBlock
}
sszData, err := consensusBlk.MarshalSSZ()
sszData, err := marshaler.MarshalSSZ()
if err != nil {
return nil, errors.Wrapf(err, "could not marshal block into SSZ")
}
@@ -755,111 +628,6 @@ func (s *Server) getBlindedBlockDeneb(ctx context.Context, blk interfaces.ReadOn
}, nil
}
func (*Server) getBlindedBlockBellatrixSSZ(_ context.Context, blk interfaces.ReadOnlySignedBeaconBlock) ([]byte, error) {
blindedConsensusBlk, err := blk.PbBlindedBellatrixBlock()
if err != nil {
// ErrUnsupportedField means that we have another block type
if errors.Is(err, consensus_types.ErrUnsupportedField) {
consensusBlk, err := blk.PbBellatrixBlock()
if err != nil {
return nil, err
}
if consensusBlk == nil {
return nil, errNilBlock
}
blkInterface, err := blk.ToBlinded()
if err != nil {
return nil, errors.Wrapf(err, "could not convert block to blinded block")
}
blindedConsensusBlk, err = blkInterface.PbBlindedBellatrixBlock()
if err != nil {
return nil, errors.Wrapf(err, "could not get signed beacon block")
}
} else {
return nil, err
}
}
if blindedConsensusBlk == nil {
return nil, errNilBlock
}
sszData, err := blindedConsensusBlk.MarshalSSZ()
if err != nil {
return nil, errors.Wrapf(err, "could not marshal block into SSZ")
}
return sszData, nil
}
func (*Server) getBlindedBlockCapellaSSZ(_ context.Context, blk interfaces.ReadOnlySignedBeaconBlock) ([]byte, error) {
blindedConsensusBlk, err := blk.PbBlindedCapellaBlock()
if err != nil {
// ErrUnsupportedField means that we have another block type
if errors.Is(err, consensus_types.ErrUnsupportedField) {
consensusBlk, err := blk.PbCapellaBlock()
if err != nil {
return nil, err
}
if consensusBlk == nil {
return nil, errNilBlock
}
blkInterface, err := blk.ToBlinded()
if err != nil {
return nil, errors.Wrapf(err, "could not convert block to blinded block")
}
blindedConsensusBlk, err = blkInterface.PbBlindedCapellaBlock()
if err != nil {
return nil, errors.Wrapf(err, "could not get signed beacon block")
}
} else {
return nil, err
}
}
if blindedConsensusBlk == nil {
return nil, errNilBlock
}
sszData, err := blindedConsensusBlk.MarshalSSZ()
if err != nil {
return nil, errors.Wrapf(err, "could not marshal block into SSZ")
}
return sszData, nil
}
func (*Server) getBlindedBlockDenebSSZ(_ context.Context, blk interfaces.ReadOnlySignedBeaconBlock) ([]byte, error) {
blindedConsensusBlk, err := blk.PbBlindedDenebBlock()
if err != nil {
// ErrUnsupportedGetter means that we have another block type
if errors.Is(err, consensus_types.ErrUnsupportedField) {
consensusBlk, err := blk.PbDenebBlock()
if err != nil {
return nil, err
}
if consensusBlk == nil {
return nil, errNilBlock
}
blkInterface, err := blk.ToBlinded()
if err != nil {
return nil, errors.Wrapf(err, "could not convert block to blinded block")
}
blindedConsensusBlk, err = blkInterface.PbBlindedDenebBlock()
if err != nil {
return nil, errors.Wrapf(err, "could not get signed beacon block")
}
} else {
return nil, err
}
}
if blindedConsensusBlk == nil {
return nil, errNilBlock
}
sszData, err := blindedConsensusBlk.MarshalSSZ()
if err != nil {
return nil, errors.Wrapf(err, "could not marshal block into SSZ")
}
return sszData, nil
}
// GetBlockAttestations retrieves attestation included in requested block.
func (s *Server) GetBlockAttestations(w http.ResponseWriter, r *http.Request) {
ctx, span := trace.StartSpan(r.Context(), "beacon.GetBlockAttestations")

View File

@@ -146,8 +146,10 @@ func TestGetBlock(t *testing.T) {
return
}
require.NoError(t, err)
pbBlock, err := result.PbPhase0Block()
pb, err := result.Proto()
require.NoError(t, err)
pbBlock, ok := pb.(*ethpbalpha.SignedBeaconBlock)
require.Equal(t, true, ok)
if !reflect.DeepEqual(pbBlock, tt.want) {
t.Error("Expected blocks to equal")
}

View File

@@ -13,7 +13,6 @@ import (
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v5/runtime/version"
"github.com/prysmaticlabs/prysm/v5/time/slots"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
@@ -90,64 +89,32 @@ func convertToBlockContainer(blk interfaces.ReadOnlySignedBeaconBlock, root [32]
Canonical: isCanonical,
}
switch blk.Version() {
case version.Phase0:
rBlk, err := blk.PbPhase0Block()
if err != nil {
return nil, err
}
ctr.Block = &ethpb.BeaconBlockContainer_Phase0Block{Phase0Block: rBlk}
case version.Altair:
rBlk, err := blk.PbAltairBlock()
if err != nil {
return nil, err
}
ctr.Block = &ethpb.BeaconBlockContainer_AltairBlock{AltairBlock: rBlk}
case version.Bellatrix:
if blk.IsBlinded() {
rBlk, err := blk.PbBlindedBellatrixBlock()
if err != nil {
return nil, err
}
ctr.Block = &ethpb.BeaconBlockContainer_BlindedBellatrixBlock{BlindedBellatrixBlock: rBlk}
} else {
rBlk, err := blk.PbBellatrixBlock()
if err != nil {
return nil, err
}
ctr.Block = &ethpb.BeaconBlockContainer_BellatrixBlock{BellatrixBlock: rBlk}
}
case version.Capella:
if blk.IsBlinded() {
rBlk, err := blk.PbBlindedCapellaBlock()
if err != nil {
return nil, err
}
ctr.Block = &ethpb.BeaconBlockContainer_BlindedCapellaBlock{BlindedCapellaBlock: rBlk}
} else {
rBlk, err := blk.PbCapellaBlock()
if err != nil {
return nil, err
}
ctr.Block = &ethpb.BeaconBlockContainer_CapellaBlock{CapellaBlock: rBlk}
}
case version.Deneb:
if blk.IsBlinded() {
rBlk, err := blk.PbBlindedDenebBlock()
if err != nil {
return nil, err
}
ctr.Block = &ethpb.BeaconBlockContainer_BlindedDenebBlock{BlindedDenebBlock: rBlk}
} else {
rBlk, err := blk.PbDenebBlock()
if err != nil {
return nil, err
}
ctr.Block = &ethpb.BeaconBlockContainer_DenebBlock{DenebBlock: rBlk}
}
pb, err := blk.Proto()
if err != nil {
return nil, err
}
switch pbStruct := pb.(type) {
case *ethpb.SignedBeaconBlock:
ctr.Block = &ethpb.BeaconBlockContainer_Phase0Block{Phase0Block: pbStruct}
case *ethpb.SignedBeaconBlockAltair:
ctr.Block = &ethpb.BeaconBlockContainer_AltairBlock{AltairBlock: pbStruct}
case *ethpb.SignedBlindedBeaconBlockBellatrix:
ctr.Block = &ethpb.BeaconBlockContainer_BlindedBellatrixBlock{BlindedBellatrixBlock: pbStruct}
case *ethpb.SignedBeaconBlockBellatrix:
ctr.Block = &ethpb.BeaconBlockContainer_BellatrixBlock{BellatrixBlock: pbStruct}
case *ethpb.SignedBlindedBeaconBlockCapella:
ctr.Block = &ethpb.BeaconBlockContainer_BlindedCapellaBlock{BlindedCapellaBlock: pbStruct}
case *ethpb.SignedBeaconBlockCapella:
ctr.Block = &ethpb.BeaconBlockContainer_CapellaBlock{CapellaBlock: pbStruct}
case *ethpb.SignedBlindedBeaconBlockDeneb:
ctr.Block = &ethpb.BeaconBlockContainer_BlindedDenebBlock{BlindedDenebBlock: pbStruct}
case *ethpb.SignedBeaconBlockDeneb:
ctr.Block = &ethpb.BeaconBlockContainer_DenebBlock{DenebBlock: pbStruct}
default:
return nil, errors.Errorf("block type is not recognized: %d", blk.Version())
}
return ctr, nil
}

View File

@@ -23,6 +23,8 @@ type executionPayload struct {
p *enginev1.ExecutionPayload
}
var _ interfaces.ExecutionData = &executionPayload{}
// WrappedExecutionPayload is a constructor which wraps a protobuf execution payload into an interface.
func WrappedExecutionPayload(p *enginev1.ExecutionPayload) (interfaces.ExecutionData, error) {
w := executionPayload{p: p}
@@ -187,6 +189,11 @@ func (executionPayload) PbDeneb() (*enginev1.ExecutionPayloadDeneb, error) {
return nil, consensus_types.ErrUnsupportedField
}
// PbElectra --
func (executionPayload) PbElectra() (*enginev1.ExecutionPayloadElectra, error) {
return nil, consensus_types.ErrUnsupportedField
}
// ValueInWei --
func (executionPayload) ValueInWei() (math.Wei, error) {
return nil, consensus_types.ErrUnsupportedField
@@ -204,6 +211,8 @@ type executionPayloadHeader struct {
p *enginev1.ExecutionPayloadHeader
}
var _ interfaces.ExecutionData = &executionPayloadHeader{}
// WrappedExecutionPayloadHeader is a constructor which wraps a protobuf execution header into an interface.
func WrappedExecutionPayloadHeader(p *enginev1.ExecutionPayloadHeader) (interfaces.ExecutionData, error) {
w := executionPayloadHeader{p: p}
@@ -353,6 +362,11 @@ func (e executionPayloadHeader) ExcessBlobGas() (uint64, error) {
return 0, consensus_types.ErrUnsupportedField
}
// PbElectra --
func (e executionPayloadHeader) PbElectra() (*enginev1.ExecutionPayloadElectra, error) {
return nil, consensus_types.ErrUnsupportedField
}
// PbDeneb --
func (executionPayloadHeader) PbDeneb() (*enginev1.ExecutionPayloadDeneb, error) {
return nil, consensus_types.ErrUnsupportedField
@@ -415,6 +429,8 @@ type executionPayloadCapella struct {
gweiValue uint64
}
var _ interfaces.ExecutionData = &executionPayloadCapella{}
// WrappedExecutionPayloadCapella is a constructor which wraps a protobuf execution payload into an interface.
func WrappedExecutionPayloadCapella(p *enginev1.ExecutionPayloadCapella, value math.Wei) (interfaces.ExecutionData, error) {
w := executionPayloadCapella{p: p, weiValue: value, gweiValue: uint64(math.WeiToGwei(value))}
@@ -564,6 +580,11 @@ func (e executionPayloadCapella) ExcessBlobGas() (uint64, error) {
return 0, consensus_types.ErrUnsupportedField
}
// PbElectra --
func (executionPayloadCapella) PbElectra() (*enginev1.ExecutionPayloadElectra, error) {
return nil, consensus_types.ErrUnsupportedField
}
// PbDeneb --
func (executionPayloadCapella) PbDeneb() (*enginev1.ExecutionPayloadDeneb, error) {
return nil, consensus_types.ErrUnsupportedField
@@ -598,6 +619,8 @@ type executionPayloadHeaderCapella struct {
gweiValue uint64
}
var _ interfaces.ExecutionData = &executionPayloadHeaderCapella{}
// WrappedExecutionPayloadHeaderCapella is a constructor which wraps a protobuf execution header into an interface.
func WrappedExecutionPayloadHeaderCapella(p *enginev1.ExecutionPayloadHeaderCapella, value math.Wei) (interfaces.ExecutionData, error) {
w := executionPayloadHeaderCapella{p: p, weiValue: value, gweiValue: uint64(math.WeiToGwei(value))}
@@ -747,6 +770,11 @@ func (e executionPayloadHeaderCapella) ExcessBlobGas() (uint64, error) {
return 0, consensus_types.ErrUnsupportedField
}
// PbElectra --
func (executionPayloadHeaderCapella) PbElectra() (*enginev1.ExecutionPayloadElectra, error) {
return nil, consensus_types.ErrUnsupportedField
}
// PbDeneb --
func (executionPayloadHeaderCapella) PbDeneb() (*enginev1.ExecutionPayloadDeneb, error) {
return nil, consensus_types.ErrUnsupportedField
@@ -858,6 +886,68 @@ func PayloadToHeaderDeneb(payload interfaces.ExecutionData) (*enginev1.Execution
}, nil
}
// PayloadToHeaderElectra converts `payload` into execution payload header format.
func PayloadToHeaderElectra(payload interfaces.ExecutionDataElectra) (*enginev1.ExecutionPayloadHeaderElectra, error) {
txs, err := payload.Transactions()
if err != nil {
return nil, err
}
txRoot, err := ssz.TransactionsRoot(txs)
if err != nil {
return nil, err
}
withdrawals, err := payload.Withdrawals()
if err != nil {
return nil, err
}
withdrawalsRoot, err := ssz.WithdrawalSliceRoot(withdrawals, fieldparams.MaxWithdrawalsPerPayload)
if err != nil {
return nil, err
}
blobGasUsed, err := payload.BlobGasUsed()
if err != nil {
return nil, err
}
excessBlobGas, err := payload.ExcessBlobGas()
if err != nil {
return nil, err
}
depositReceipts := payload.DepositReceipts()
depositReceiptsRoot, err := ssz.DepositReceiptSliceRoot(depositReceipts, fieldparams.MaxDepositReceiptsPerPayload)
if err != nil {
return nil, err
}
withdrawalRequests := payload.WithdrawalRequests()
withdrawalRequestsRoot, err := ssz.WithdrawalRequestSliceRoot(withdrawalRequests, fieldparams.MaxWithdrawalRequestsPerPayload)
if err != nil {
return nil, err
}
return &enginev1.ExecutionPayloadHeaderElectra{
ParentHash: bytesutil.SafeCopyBytes(payload.ParentHash()),
FeeRecipient: bytesutil.SafeCopyBytes(payload.FeeRecipient()),
StateRoot: bytesutil.SafeCopyBytes(payload.StateRoot()),
ReceiptsRoot: bytesutil.SafeCopyBytes(payload.ReceiptsRoot()),
LogsBloom: bytesutil.SafeCopyBytes(payload.LogsBloom()),
PrevRandao: bytesutil.SafeCopyBytes(payload.PrevRandao()),
BlockNumber: payload.BlockNumber(),
GasLimit: payload.GasLimit(),
GasUsed: payload.GasUsed(),
Timestamp: payload.Timestamp(),
ExtraData: bytesutil.SafeCopyBytes(payload.ExtraData()),
BaseFeePerGas: bytesutil.SafeCopyBytes(payload.BaseFeePerGas()),
BlockHash: bytesutil.SafeCopyBytes(payload.BlockHash()),
TransactionsRoot: txRoot[:],
WithdrawalsRoot: withdrawalsRoot[:],
BlobGasUsed: blobGasUsed,
ExcessBlobGas: excessBlobGas,
DepositReceiptsRoot: depositReceiptsRoot[:],
WithdrawalRequestsRoot: withdrawalRequestsRoot[:],
}, nil
}
// IsEmptyExecutionData checks if an execution data is empty underneath. If a single field has
// a non-zero value, this function will return false.
func IsEmptyExecutionData(data interfaces.ExecutionData) (bool, error) {
@@ -915,6 +1005,20 @@ func IsEmptyExecutionData(data interfaces.ExecutionData) (bool, error) {
if data.Timestamp() != 0 {
return false, nil
}
epe, postElectra := data.(interfaces.ExecutionDataElectra)
if postElectra {
drs := epe.DepositReceipts()
if len(drs) != 0 {
return false, nil
}
wrs := epe.WithdrawalRequests()
if len(wrs) != 0 {
return false, nil
}
}
return true, nil
}
@@ -927,6 +1031,8 @@ type executionPayloadHeaderDeneb struct {
gweiValue uint64
}
var _ interfaces.ExecutionData = &executionPayloadHeaderDeneb{}
// WrappedExecutionPayloadHeaderDeneb is a constructor which wraps a protobuf execution header into an interface.
func WrappedExecutionPayloadHeaderDeneb(p *enginev1.ExecutionPayloadHeaderDeneb, value math.Wei) (interfaces.ExecutionData, error) {
w := executionPayloadHeaderDeneb{p: p, weiValue: value, gweiValue: uint64(math.WeiToGwei(value))}
@@ -1071,6 +1177,11 @@ func (e executionPayloadHeaderDeneb) ExcessBlobGas() (uint64, error) {
return e.p.ExcessBlobGas, nil
}
// PbElectra --
func (executionPayloadHeaderDeneb) PbElectra() (*enginev1.ExecutionPayloadElectra, error) {
return nil, consensus_types.ErrUnsupportedField
}
// PbDeneb --
func (executionPayloadHeaderDeneb) PbDeneb() (*enginev1.ExecutionPayloadDeneb, error) {
return nil, consensus_types.ErrUnsupportedField
@@ -1110,6 +1221,8 @@ type executionPayloadDeneb struct {
gweiValue uint64
}
var _ interfaces.ExecutionData = &executionPayloadDeneb{}
// WrappedExecutionPayloadDeneb is a constructor which wraps a protobuf execution payload into an interface.
func WrappedExecutionPayloadDeneb(p *enginev1.ExecutionPayloadDeneb, value math.Wei) (interfaces.ExecutionData, error) {
w := executionPayloadDeneb{p: p, weiValue: value, gweiValue: uint64(math.WeiToGwei(value))}
@@ -1267,6 +1380,11 @@ func (e executionPayloadDeneb) PbDeneb() (*enginev1.ExecutionPayloadDeneb, error
return e.p, nil
}
// PbElectra --
func (e executionPayloadDeneb) PbElectra() (*enginev1.ExecutionPayloadElectra, error) {
return nil, consensus_types.ErrUnsupportedField
}
// ValueInWei --
func (e executionPayloadDeneb) ValueInWei() (math.Wei, error) {
return e.weiValue, nil
@@ -1282,6 +1400,406 @@ func (e executionPayloadDeneb) IsBlinded() bool {
return false
}
// executionPayloadHeaderElectra is a convenience wrapper around a blinded beacon block body's execution header data structure.
// This wrapper allows us to conform to a common interface so that beacon
// blocks for future forks can also be applied across Prysm without issues.
type executionPayloadHeaderElectra struct {
p *enginev1.ExecutionPayloadHeaderElectra
weiValue math.Wei
gweiValue uint64
}
var _ interfaces.ExecutionData = &executionPayloadElectra{}
var _ interfaces.ExecutionDataElectra = &executionPayloadElectra{}
// WrappedExecutionPayloadHeaderElectra is a constructor which wraps a protobuf execution header into an interface.
func WrappedExecutionPayloadHeaderElectra(p *enginev1.ExecutionPayloadHeaderElectra, value math.Wei) (interfaces.ExecutionData, error) {
w := executionPayloadHeaderElectra{p: p, weiValue: value, gweiValue: uint64(math.WeiToGwei(value))}
if w.IsNil() {
return nil, consensus_types.ErrNilObjectWrapped
}
return w, nil
}
// IsNil checks if the underlying data is nil.
func (e executionPayloadHeaderElectra) IsNil() bool {
return e.p == nil
}
// MarshalSSZ --
func (e executionPayloadHeaderElectra) MarshalSSZ() ([]byte, error) {
return e.p.MarshalSSZ()
}
// MarshalSSZTo --
func (e executionPayloadHeaderElectra) MarshalSSZTo(dst []byte) ([]byte, error) {
return e.p.MarshalSSZTo(dst)
}
// SizeSSZ --
func (e executionPayloadHeaderElectra) SizeSSZ() int {
return e.p.SizeSSZ()
}
// UnmarshalSSZ --
func (e executionPayloadHeaderElectra) UnmarshalSSZ(buf []byte) error {
return e.p.UnmarshalSSZ(buf)
}
// HashTreeRoot --
func (e executionPayloadHeaderElectra) HashTreeRoot() ([32]byte, error) {
return e.p.HashTreeRoot()
}
// HashTreeRootWith --
func (e executionPayloadHeaderElectra) HashTreeRootWith(hh *fastssz.Hasher) error {
return e.p.HashTreeRootWith(hh)
}
// Proto --
func (e executionPayloadHeaderElectra) Proto() proto.Message {
return e.p
}
// ParentHash --
func (e executionPayloadHeaderElectra) ParentHash() []byte {
return e.p.ParentHash
}
// FeeRecipient --
func (e executionPayloadHeaderElectra) FeeRecipient() []byte {
return e.p.FeeRecipient
}
// StateRoot --
func (e executionPayloadHeaderElectra) StateRoot() []byte {
return e.p.StateRoot
}
// ReceiptsRoot --
func (e executionPayloadHeaderElectra) ReceiptsRoot() []byte {
return e.p.ReceiptsRoot
}
// LogsBloom --
func (e executionPayloadHeaderElectra) LogsBloom() []byte {
return e.p.LogsBloom
}
// PrevRandao --
func (e executionPayloadHeaderElectra) PrevRandao() []byte {
return e.p.PrevRandao
}
// BlockNumber --
func (e executionPayloadHeaderElectra) BlockNumber() uint64 {
return e.p.BlockNumber
}
// GasLimit --
func (e executionPayloadHeaderElectra) GasLimit() uint64 {
return e.p.GasLimit
}
// GasUsed --
func (e executionPayloadHeaderElectra) GasUsed() uint64 {
return e.p.GasUsed
}
// Timestamp --
func (e executionPayloadHeaderElectra) Timestamp() uint64 {
return e.p.Timestamp
}
// ExtraData --
func (e executionPayloadHeaderElectra) ExtraData() []byte {
return e.p.ExtraData
}
// BaseFeePerGas --
func (e executionPayloadHeaderElectra) BaseFeePerGas() []byte {
return e.p.BaseFeePerGas
}
// BlockHash --
func (e executionPayloadHeaderElectra) BlockHash() []byte {
return e.p.BlockHash
}
// Transactions --
func (executionPayloadHeaderElectra) Transactions() ([][]byte, error) {
return nil, consensus_types.ErrUnsupportedField
}
// TransactionsRoot --
func (e executionPayloadHeaderElectra) TransactionsRoot() ([]byte, error) {
return e.p.TransactionsRoot, nil
}
// Withdrawals --
func (e executionPayloadHeaderElectra) Withdrawals() ([]*enginev1.Withdrawal, error) {
return nil, consensus_types.ErrUnsupportedField
}
// WithdrawalsRoot --
func (e executionPayloadHeaderElectra) WithdrawalsRoot() ([]byte, error) {
return e.p.WithdrawalsRoot, nil
}
// BlobGasUsed --
func (e executionPayloadHeaderElectra) BlobGasUsed() (uint64, error) {
return e.p.BlobGasUsed, nil
}
// ExcessBlobGas --
func (e executionPayloadHeaderElectra) ExcessBlobGas() (uint64, error) {
return e.p.ExcessBlobGas, nil
}
// PbElectra --
func (e executionPayloadHeaderElectra) PbElectra() (*enginev1.ExecutionPayloadElectra, error) {
return nil, consensus_types.ErrUnsupportedField
}
// PbDeneb --
func (executionPayloadHeaderElectra) PbDeneb() (*enginev1.ExecutionPayloadDeneb, error) {
return nil, consensus_types.ErrUnsupportedField
}
// PbBellatrix --
func (executionPayloadHeaderElectra) PbBellatrix() (*enginev1.ExecutionPayload, error) {
return nil, consensus_types.ErrUnsupportedField
}
// PbCapella --
func (executionPayloadHeaderElectra) PbCapella() (*enginev1.ExecutionPayloadCapella, error) {
return nil, consensus_types.ErrUnsupportedField
}
// ValueInWei --
func (e executionPayloadHeaderElectra) ValueInWei() (math.Wei, error) {
return e.weiValue, nil
}
// ValueInGwei --
func (e executionPayloadHeaderElectra) ValueInGwei() (uint64, error) {
return e.gweiValue, nil
}
// DepositReceipts --
func (e executionPayloadHeaderElectra) DepositReceipts() ([]*enginev1.DepositReceipt, error) {
return nil, consensus_types.ErrUnsupportedField
}
// WithdrawalRequests --
func (e executionPayloadHeaderElectra) WithdrawalRequests() ([]*enginev1.ExecutionLayerWithdrawalRequest, error) {
return nil, consensus_types.ErrUnsupportedField
}
// IsBlinded returns true if the underlying data is blinded.
func (e executionPayloadHeaderElectra) IsBlinded() bool {
return true
}
// executionPayloadElectra is a convenience wrapper around a beacon block body's execution payload data structure
// This wrapper allows us to conform to a common interface so that beacon
// blocks for future forks can also be applied across Prysm without issues.
type executionPayloadElectra struct {
p *enginev1.ExecutionPayloadElectra
weiValue math.Wei
gweiValue uint64
}
// WrappedExecutionPayloadElectra is a constructor which wraps a protobuf execution payload into an interface.
func WrappedExecutionPayloadElectra(p *enginev1.ExecutionPayloadElectra, value math.Wei) (interfaces.ExecutionData, error) {
w := executionPayloadElectra{p: p, weiValue: value, gweiValue: uint64(math.WeiToGwei(value))}
if w.IsNil() {
return nil, consensus_types.ErrNilObjectWrapped
}
return w, nil
}
var _ interfaces.ExecutionData = &executionPayloadElectra{}
var _ interfaces.ExecutionDataElectra = &executionPayloadElectra{}
// IsNil checks if the underlying data is nil.
func (e executionPayloadElectra) IsNil() bool {
return e.p == nil
}
// MarshalSSZ --
func (e executionPayloadElectra) MarshalSSZ() ([]byte, error) {
return e.p.MarshalSSZ()
}
// MarshalSSZTo --
func (e executionPayloadElectra) MarshalSSZTo(dst []byte) ([]byte, error) {
return e.p.MarshalSSZTo(dst)
}
// SizeSSZ --
func (e executionPayloadElectra) SizeSSZ() int {
return e.p.SizeSSZ()
}
// UnmarshalSSZ --
func (e executionPayloadElectra) UnmarshalSSZ(buf []byte) error {
return e.p.UnmarshalSSZ(buf)
}
// HashTreeRoot --
func (e executionPayloadElectra) HashTreeRoot() ([32]byte, error) {
return e.p.HashTreeRoot()
}
// HashTreeRootWith --
func (e executionPayloadElectra) HashTreeRootWith(hh *fastssz.Hasher) error {
return e.p.HashTreeRootWith(hh)
}
// Proto --
func (e executionPayloadElectra) Proto() proto.Message {
return e.p
}
// ParentHash --
func (e executionPayloadElectra) ParentHash() []byte {
return e.p.ParentHash
}
// FeeRecipient --
func (e executionPayloadElectra) FeeRecipient() []byte {
return e.p.FeeRecipient
}
// StateRoot --
func (e executionPayloadElectra) StateRoot() []byte {
return e.p.StateRoot
}
// ReceiptsRoot --
func (e executionPayloadElectra) ReceiptsRoot() []byte {
return e.p.ReceiptsRoot
}
// LogsBloom --
func (e executionPayloadElectra) LogsBloom() []byte {
return e.p.LogsBloom
}
// PrevRandao --
func (e executionPayloadElectra) PrevRandao() []byte {
return e.p.PrevRandao
}
// BlockNumber --
func (e executionPayloadElectra) BlockNumber() uint64 {
return e.p.BlockNumber
}
// GasLimit --
func (e executionPayloadElectra) GasLimit() uint64 {
return e.p.GasLimit
}
// GasUsed --
func (e executionPayloadElectra) GasUsed() uint64 {
return e.p.GasUsed
}
// Timestamp --
func (e executionPayloadElectra) Timestamp() uint64 {
return e.p.Timestamp
}
// ExtraData --
func (e executionPayloadElectra) ExtraData() []byte {
return e.p.ExtraData
}
// BaseFeePerGas --
func (e executionPayloadElectra) BaseFeePerGas() []byte {
return e.p.BaseFeePerGas
}
// BlockHash --
func (e executionPayloadElectra) BlockHash() []byte {
return e.p.BlockHash
}
// Transactions --
func (e executionPayloadElectra) Transactions() ([][]byte, error) {
return e.p.Transactions, nil
}
// TransactionsRoot --
func (e executionPayloadElectra) TransactionsRoot() ([]byte, error) {
return nil, consensus_types.ErrUnsupportedField
}
// Withdrawals --
func (e executionPayloadElectra) Withdrawals() ([]*enginev1.Withdrawal, error) {
return e.p.Withdrawals, nil
}
// WithdrawalsRoot --
func (e executionPayloadElectra) WithdrawalsRoot() ([]byte, error) {
return nil, consensus_types.ErrUnsupportedField
}
func (e executionPayloadElectra) BlobGasUsed() (uint64, error) {
return e.p.BlobGasUsed, nil
}
func (e executionPayloadElectra) ExcessBlobGas() (uint64, error) {
return e.p.ExcessBlobGas, nil
}
// PbBellatrix --
func (e executionPayloadElectra) PbBellatrix() (*enginev1.ExecutionPayload, error) {
return nil, consensus_types.ErrUnsupportedField
}
// PbCapella --
func (e executionPayloadElectra) PbCapella() (*enginev1.ExecutionPayloadCapella, error) {
return nil, consensus_types.ErrUnsupportedField
}
// PbDeneb --
func (e executionPayloadElectra) PbDeneb() (*enginev1.ExecutionPayloadDeneb, error) {
return nil, consensus_types.ErrUnsupportedField
}
// PbElectra --
func (e executionPayloadElectra) PbElectra() (*enginev1.ExecutionPayloadElectra, error) {
return e.p, nil
}
// ValueInWei --
func (e executionPayloadElectra) ValueInWei() (math.Wei, error) {
return e.weiValue, nil
}
// ValueInGwei --
func (e executionPayloadElectra) ValueInGwei() (uint64, error) {
return e.gweiValue, nil
}
// DepositReceipts --
func (e executionPayloadElectra) DepositReceipts() []*enginev1.DepositReceipt {
return e.p.DepositReceipts
}
// WithdrawalRequests --
func (e executionPayloadElectra) WithdrawalRequests() []*enginev1.ExecutionLayerWithdrawalRequest {
return e.p.WithdrawalRequests
}
// IsBlinded returns true if the underlying data is blinded.
func (e executionPayloadElectra) IsBlinded() bool {
return false
}
// PayloadValueToWei returns a Wei value given the payload's value
func PayloadValueToWei(value []byte) math.Wei {
// We have to convert big endian to little endian because the value is coming from the execution layer.

View File

@@ -67,6 +67,14 @@ func NewSignedBeaconBlock(i interface{}) (interfaces.SignedBeaconBlock, error) {
return initBlindedSignedBlockFromProtoDeneb(b)
case *eth.GenericSignedBeaconBlock_BlindedDeneb:
return initBlindedSignedBlockFromProtoDeneb(b.BlindedDeneb)
case *eth.GenericSignedBeaconBlock_Electra:
return initSignedBlockFromProtoElectra(b.Electra.Block)
case *eth.SignedBeaconBlockElectra:
return initSignedBlockFromProtoElectra(b)
case *eth.SignedBlindedBeaconBlockElectra:
return initBlindedSignedBlockFromProtoElectra(b)
case *eth.GenericSignedBeaconBlock_BlindedElectra:
return initBlindedSignedBlockFromProtoElectra(b.BlindedElectra)
default:
return nil, errors.Wrapf(ErrUnsupportedSignedBeaconBlock, "unable to create block from type %T", i)
}
@@ -109,6 +117,14 @@ func NewBeaconBlock(i interface{}) (interfaces.ReadOnlyBeaconBlock, error) {
return initBlindedBlockFromProtoDeneb(b)
case *eth.GenericBeaconBlock_BlindedDeneb:
return initBlindedBlockFromProtoDeneb(b.BlindedDeneb)
case *eth.GenericBeaconBlock_Electra:
return initBlockFromProtoElectra(b.Electra.Block)
case *eth.BeaconBlockElectra:
return initBlockFromProtoElectra(b)
case *eth.BlindedBeaconBlockElectra:
return initBlindedBlockFromProtoElectra(b)
case *eth.GenericBeaconBlock_BlindedElectra:
return initBlindedBlockFromProtoElectra(b.BlindedElectra)
default:
return nil, errors.Wrapf(errUnsupportedBeaconBlock, "unable to create block from type %T", i)
}
@@ -135,6 +151,10 @@ func NewBeaconBlockBody(i interface{}) (interfaces.ReadOnlyBeaconBlockBody, erro
return initBlockBodyFromProtoDeneb(b)
case *eth.BlindedBeaconBlockBodyDeneb:
return initBlindedBlockBodyFromProtoDeneb(b)
case *eth.BeaconBlockBodyElectra:
return initBlockBodyFromProtoElectra(b)
case *eth.BlindedBeaconBlockBodyElectra:
return initBlindedBlockBodyFromProtoElectra(b)
default:
return nil, errors.Wrapf(errUnsupportedBeaconBlockBody, "unable to create block body from type %T", i)
}
@@ -201,6 +221,19 @@ func BuildSignedBeaconBlock(blk interfaces.ReadOnlyBeaconBlock, signature []byte
return nil, errIncorrectBlockVersion
}
return NewSignedBeaconBlock(&eth.SignedBeaconBlockDeneb{Block: pb, Signature: signature})
case version.Electra:
if blk.IsBlinded() {
pb, ok := pb.(*eth.BlindedBeaconBlockElectra)
if !ok {
return nil, errIncorrectBlockVersion
}
return NewSignedBeaconBlock(&eth.SignedBlindedBeaconBlockElectra{Message: pb, Signature: signature})
}
pb, ok := pb.(*eth.BeaconBlockElectra)
if !ok {
return nil, errIncorrectBlockVersion
}
return NewSignedBeaconBlock(&eth.SignedBeaconBlockElectra{Block: pb, Signature: signature})
default:
return nil, errUnsupportedBeaconBlock
}

View File

@@ -7,6 +7,7 @@ import (
"testing"
fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams"
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
enginev1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1"
eth "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
@@ -537,3 +538,26 @@ func TestBuildSignedBeaconBlockFromExecutionPayload(t *testing.T) {
require.DeepEqual(t, uint64(321), payload.BlobGasUsed)
})
}
func TestElectraBlockBodyCast(t *testing.T) {
t.Run("deneb cast fails", func(t *testing.T) {
pb := &eth.BeaconBlockBodyDeneb{}
i, err := NewBeaconBlockBody(pb)
require.NoError(t, err)
b, ok := i.(*BeaconBlockBody)
require.Equal(t, true, ok)
assert.Equal(t, version.Deneb, b.version)
_, err = interfaces.AsROBlockBodyElectra(b)
require.ErrorIs(t, err, interfaces.ErrInvalidCast)
})
t.Run("electra cast succeeds", func(t *testing.T) {
pb := &eth.BeaconBlockBodyElectra{}
i, err := NewBeaconBlockBody(pb)
require.NoError(t, err)
b, ok := i.(*BeaconBlockBody)
require.Equal(t, true, ok)
assert.Equal(t, version.Electra, b.version)
_, err = interfaces.AsROBlockBodyElectra(b)
require.NoError(t, err)
})
}

View File

@@ -81,6 +81,14 @@ func (b *SignedBeaconBlock) Copy() (interfaces.SignedBeaconBlock, error) {
}
cp := eth.CopySignedBeaconBlockDeneb(pb.(*eth.SignedBeaconBlockDeneb))
return initSignedBlockFromProtoDeneb(cp)
case version.Electra:
if b.IsBlinded() {
cp := eth.CopySignedBlindedBeaconBlockElectra(pb.(*eth.SignedBlindedBeaconBlockElectra))
return initBlindedSignedBlockFromProtoElectra(cp)
}
cp := eth.CopySignedBeaconBlockElectra(pb.(*eth.SignedBeaconBlockElectra))
return initSignedBlockFromProtoElectra(cp)
default:
return nil, errIncorrectBlockVersion
}
@@ -128,6 +136,15 @@ func (b *SignedBeaconBlock) PbGenericBlock() (*eth.GenericSignedBeaconBlock, err
return &eth.GenericSignedBeaconBlock{
Block: &eth.GenericSignedBeaconBlock_Deneb{Deneb: pb.(*eth.SignedBeaconBlockContentsDeneb)},
}, nil
case version.Electra:
if b.IsBlinded() {
return &eth.GenericSignedBeaconBlock{
Block: &eth.GenericSignedBeaconBlock_BlindedElectra{BlindedElectra: pb.(*eth.SignedBlindedBeaconBlockElectra)},
}, nil
}
return &eth.GenericSignedBeaconBlock{
Block: &eth.GenericSignedBeaconBlock_Electra{Electra: pb.(*eth.SignedBeaconBlockContentsElectra)},
}, nil
default:
return nil, errIncorrectBlockVersion
}
@@ -330,6 +347,40 @@ func (b *SignedBeaconBlock) ToBlinded() (interfaces.ReadOnlySignedBeaconBlock, e
},
Signature: b.signature[:],
})
case *enginev1.ExecutionPayloadElectra:
pe, ok := payload.(interfaces.ExecutionDataElectra)
if !ok {
return nil, interfaces.ErrIncompatibleFork
}
header, err := PayloadToHeaderElectra(pe)
if err != nil {
return nil, err
}
return initBlindedSignedBlockFromProtoElectra(
&eth.SignedBlindedBeaconBlockElectra{
Message: &eth.BlindedBeaconBlockElectra{
Slot: b.block.slot,
ProposerIndex: b.block.proposerIndex,
ParentRoot: b.block.parentRoot[:],
StateRoot: b.block.stateRoot[:],
Body: &eth.BlindedBeaconBlockBodyElectra{
RandaoReveal: b.block.body.randaoReveal[:],
Eth1Data: b.block.body.eth1Data,
Graffiti: b.block.body.graffiti[:],
ProposerSlashings: b.block.body.proposerSlashings,
AttesterSlashings: b.block.body.attesterSlashingsElectra,
Attestations: b.block.body.attestationsElectra,
Deposits: b.block.body.deposits,
VoluntaryExits: b.block.body.voluntaryExits,
SyncAggregate: b.block.body.syncAggregate,
ExecutionPayloadHeader: header,
BlsToExecutionChanges: b.block.body.blsToExecutionChanges,
BlobKzgCommitments: b.block.body.blobKzgCommitments,
Consolidations: b.block.body.signedConsolidations,
},
},
Signature: b.signature[:],
})
default:
return nil, fmt.Errorf("%T is not an execution payload header", p)
}
@@ -459,6 +510,11 @@ func (b *SignedBeaconBlock) MarshalSSZ() ([]byte, error) {
return pb.(*eth.SignedBlindedBeaconBlockDeneb).MarshalSSZ()
}
return pb.(*eth.SignedBeaconBlockDeneb).MarshalSSZ()
case version.Electra:
if b.IsBlinded() {
return pb.(*eth.SignedBlindedBeaconBlockElectra).MarshalSSZ()
}
return pb.(*eth.SignedBeaconBlockElectra).MarshalSSZ()
default:
return []byte{}, errIncorrectBlockVersion
}
@@ -491,6 +547,11 @@ func (b *SignedBeaconBlock) MarshalSSZTo(dst []byte) ([]byte, error) {
return pb.(*eth.SignedBlindedBeaconBlockDeneb).MarshalSSZTo(dst)
}
return pb.(*eth.SignedBeaconBlockDeneb).MarshalSSZTo(dst)
case version.Electra:
if b.IsBlinded() {
return pb.(*eth.SignedBlindedBeaconBlockElectra).MarshalSSZTo(dst)
}
return pb.(*eth.SignedBeaconBlockElectra).MarshalSSZTo(dst)
default:
return []byte{}, errIncorrectBlockVersion
}
@@ -527,6 +588,11 @@ func (b *SignedBeaconBlock) SizeSSZ() int {
return pb.(*eth.SignedBlindedBeaconBlockDeneb).SizeSSZ()
}
return pb.(*eth.SignedBeaconBlockDeneb).SizeSSZ()
case version.Electra:
if b.IsBlinded() {
return pb.(*eth.SignedBlindedBeaconBlockElectra).SizeSSZ()
}
return pb.(*eth.SignedBeaconBlockElectra).SizeSSZ()
default:
panic(incorrectBlockVersion)
}
@@ -622,6 +688,28 @@ func (b *SignedBeaconBlock) UnmarshalSSZ(buf []byte) error {
return err
}
}
case version.Electra:
if b.IsBlinded() {
pb := &eth.SignedBlindedBeaconBlockElectra{}
if err := pb.UnmarshalSSZ(buf); err != nil {
return err
}
var err error
newBlock, err = initBlindedSignedBlockFromProtoElectra(pb)
if err != nil {
return err
}
} else {
pb := &eth.SignedBeaconBlockElectra{}
if err := pb.UnmarshalSSZ(buf); err != nil {
return err
}
var err error
newBlock, err = initSignedBlockFromProtoElectra(pb)
if err != nil {
return err
}
}
default:
return errIncorrectBlockVersion
}
@@ -695,6 +783,11 @@ func (b *BeaconBlock) HashTreeRoot() ([field_params.RootLength]byte, error) {
return pb.(*eth.BlindedBeaconBlockDeneb).HashTreeRoot()
}
return pb.(*eth.BeaconBlockDeneb).HashTreeRoot()
case version.Electra:
if b.IsBlinded() {
return pb.(*eth.BlindedBeaconBlockElectra).HashTreeRoot()
}
return pb.(*eth.BeaconBlockElectra).HashTreeRoot()
default:
return [field_params.RootLength]byte{}, errIncorrectBlockVersion
}
@@ -726,6 +819,11 @@ func (b *BeaconBlock) HashTreeRootWith(h *ssz.Hasher) error {
return pb.(*eth.BlindedBeaconBlockDeneb).HashTreeRootWith(h)
}
return pb.(*eth.BeaconBlockDeneb).HashTreeRootWith(h)
case version.Electra:
if b.IsBlinded() {
return pb.(*eth.BlindedBeaconBlockElectra).HashTreeRootWith(h)
}
return pb.(*eth.BeaconBlockElectra).HashTreeRootWith(h)
default:
return errIncorrectBlockVersion
}
@@ -758,6 +856,11 @@ func (b *BeaconBlock) MarshalSSZ() ([]byte, error) {
return pb.(*eth.BlindedBeaconBlockDeneb).MarshalSSZ()
}
return pb.(*eth.BeaconBlockDeneb).MarshalSSZ()
case version.Electra:
if b.IsBlinded() {
return pb.(*eth.BlindedBeaconBlockElectra).MarshalSSZ()
}
return pb.(*eth.BeaconBlockElectra).MarshalSSZ()
default:
return []byte{}, errIncorrectBlockVersion
}
@@ -790,6 +893,11 @@ func (b *BeaconBlock) MarshalSSZTo(dst []byte) ([]byte, error) {
return pb.(*eth.BlindedBeaconBlockDeneb).MarshalSSZTo(dst)
}
return pb.(*eth.BeaconBlockDeneb).MarshalSSZTo(dst)
case version.Electra:
if b.IsBlinded() {
return pb.(*eth.BlindedBeaconBlockElectra).MarshalSSZTo(dst)
}
return pb.(*eth.BeaconBlockElectra).MarshalSSZTo(dst)
default:
return []byte{}, errIncorrectBlockVersion
}
@@ -826,6 +934,11 @@ func (b *BeaconBlock) SizeSSZ() int {
return pb.(*eth.BlindedBeaconBlockDeneb).SizeSSZ()
}
return pb.(*eth.BeaconBlockDeneb).SizeSSZ()
case version.Electra:
if b.IsBlinded() {
return pb.(*eth.BlindedBeaconBlockElectra).SizeSSZ()
}
return pb.(*eth.BeaconBlockElectra).SizeSSZ()
default:
panic(incorrectBodyVersion)
}
@@ -921,6 +1034,28 @@ func (b *BeaconBlock) UnmarshalSSZ(buf []byte) error {
return err
}
}
case version.Electra:
if b.IsBlinded() {
pb := &eth.BlindedBeaconBlockElectra{}
if err := pb.UnmarshalSSZ(buf); err != nil {
return err
}
var err error
newBlock, err = initBlindedBlockFromProtoElectra(pb)
if err != nil {
return err
}
} else {
pb := &eth.BeaconBlockElectra{}
if err := pb.UnmarshalSSZ(buf); err != nil {
return err
}
var err error
newBlock, err = initBlockFromProtoElectra(pb)
if err != nil {
return err
}
}
default:
return errIncorrectBlockVersion
}
@@ -954,6 +1089,11 @@ func (b *BeaconBlock) AsSignRequestObject() (validatorpb.SignRequestObject, erro
return &validatorpb.SignRequest_BlindedBlockDeneb{BlindedBlockDeneb: pb.(*eth.BlindedBeaconBlockDeneb)}, nil
}
return &validatorpb.SignRequest_BlockDeneb{BlockDeneb: pb.(*eth.BeaconBlockDeneb)}, nil
case version.Electra:
if b.IsBlinded() {
return &validatorpb.SignRequest_BlindedBlockElectra{BlindedBlockElectra: pb.(*eth.BlindedBeaconBlockElectra)}, nil
}
return &validatorpb.SignRequest_BlockElectra{BlockElectra: pb.(*eth.BeaconBlockElectra)}, nil
default:
return nil, errIncorrectBlockVersion
}
@@ -996,6 +1136,13 @@ func (b *BeaconBlock) Copy() (interfaces.ReadOnlyBeaconBlock, error) {
}
cp := eth.CopyBeaconBlockDeneb(pb.(*eth.BeaconBlockDeneb))
return initBlockFromProtoDeneb(cp)
case version.Electra:
if b.IsBlinded() {
cp := eth.CopyBlindedBeaconBlockElectra(pb.(*eth.BlindedBeaconBlockElectra))
return initBlindedBlockFromProtoElectra(cp)
}
cp := eth.CopyBeaconBlockElectra(pb.(*eth.BeaconBlockElectra))
return initBlockFromProtoElectra(cp)
default:
return nil, errIncorrectBlockVersion
}
@@ -1079,13 +1226,17 @@ func (b *BeaconBlockBody) BlobKzgCommitments() ([][]byte, error) {
switch b.version {
case version.Phase0, version.Altair, version.Bellatrix, version.Capella:
return nil, consensus_types.ErrNotSupported("BlobKzgCommitments", b.version)
case version.Deneb:
case version.Deneb, version.Electra:
return b.blobKzgCommitments, nil
default:
return nil, errIncorrectBlockVersion
}
}
func (b *BeaconBlockBody) Consolidations() []*eth.SignedConsolidation {
return b.signedConsolidations
}
// Version returns the version of the beacon block body
func (b *BeaconBlockBody) Version() int {
return b.version
@@ -1117,6 +1268,11 @@ func (b *BeaconBlockBody) HashTreeRoot() ([field_params.RootLength]byte, error)
return pb.(*eth.BlindedBeaconBlockBodyDeneb).HashTreeRoot()
}
return pb.(*eth.BeaconBlockBodyDeneb).HashTreeRoot()
case version.Electra:
if b.IsBlinded() {
return pb.(*eth.BlindedBeaconBlockBodyElectra).HashTreeRoot()
}
return pb.(*eth.BeaconBlockBodyElectra).HashTreeRoot()
default:
return [field_params.RootLength]byte{}, errIncorrectBodyVersion
}

View File

@@ -490,3 +490,9 @@ func hydrateBeaconBlockBody() *eth.BeaconBlockBody {
},
}
}
func TestPreElectraFailsInterfaceAssertion(t *testing.T) {
var epd interfaces.ExecutionData = &executionPayloadDeneb{}
_, ok := epd.(interfaces.ExecutionDataElectra)
require.Equal(t, false, ok)
}

View File

@@ -13,7 +13,7 @@ import (
)
// Proto converts the signed beacon block to a protobuf object.
func (b *SignedBeaconBlock) Proto() (proto.Message, error) {
func (b *SignedBeaconBlock) Proto() (proto.Message, error) { // nolint:gocognit
if b == nil {
return nil, errNilBlock
}
@@ -131,13 +131,40 @@ func (b *SignedBeaconBlock) Proto() (proto.Message, error) {
Block: block,
Signature: b.signature[:],
}, nil
case version.Electra:
if b.IsBlinded() {
var block *eth.BlindedBeaconBlockElectra
if blockMessage != nil {
var ok bool
block, ok = blockMessage.(*eth.BlindedBeaconBlockElectra)
if !ok {
return nil, errIncorrectBlockVersion
}
}
return &eth.SignedBlindedBeaconBlockElectra{
Message: block,
Signature: b.signature[:],
}, nil
}
var block *eth.BeaconBlockElectra
if blockMessage != nil {
var ok bool
block, ok = blockMessage.(*eth.BeaconBlockElectra)
if !ok {
return nil, errIncorrectBlockVersion
}
}
return &eth.SignedBeaconBlockElectra{
Block: block,
Signature: b.signature[:],
}, nil
default:
return nil, errors.New("unsupported signed beacon block version")
}
}
// Proto converts the beacon block to a protobuf object.
func (b *BeaconBlock) Proto() (proto.Message, error) {
func (b *BeaconBlock) Proto() (proto.Message, error) { // nolint:gocognit
if b == nil {
return nil, nil
}
@@ -279,6 +306,40 @@ func (b *BeaconBlock) Proto() (proto.Message, error) {
StateRoot: b.stateRoot[:],
Body: body,
}, nil
case version.Electra:
if b.IsBlinded() {
var body *eth.BlindedBeaconBlockBodyElectra
if bodyMessage != nil {
var ok bool
body, ok = bodyMessage.(*eth.BlindedBeaconBlockBodyElectra)
if !ok {
return nil, errIncorrectBodyVersion
}
}
return &eth.BlindedBeaconBlockElectra{
Slot: b.slot,
ProposerIndex: b.proposerIndex,
ParentRoot: b.parentRoot[:],
StateRoot: b.stateRoot[:],
Body: body,
}, nil
}
var body *eth.BeaconBlockBodyElectra
if bodyMessage != nil {
var ok bool
body, ok = bodyMessage.(*eth.BeaconBlockBodyElectra)
if !ok {
return nil, errIncorrectBodyVersion
}
}
return &eth.BeaconBlockElectra{
Slot: b.slot,
ProposerIndex: b.proposerIndex,
ParentRoot: b.parentRoot[:],
StateRoot: b.stateRoot[:],
Body: body,
}, nil
default:
return nil, errors.New("unsupported beacon block version")
}
@@ -449,6 +510,56 @@ func (b *BeaconBlockBody) Proto() (proto.Message, error) {
BlsToExecutionChanges: b.blsToExecutionChanges,
BlobKzgCommitments: b.blobKzgCommitments,
}, nil
case version.Electra:
if b.IsBlinded() {
var ph *enginev1.ExecutionPayloadHeaderElectra
var ok bool
if b.executionPayloadHeader != nil {
ph, ok = b.executionPayloadHeader.Proto().(*enginev1.ExecutionPayloadHeaderElectra)
if !ok {
return nil, errPayloadHeaderWrongType
}
}
return &eth.BlindedBeaconBlockBodyElectra{
RandaoReveal: b.randaoReveal[:],
Eth1Data: b.eth1Data,
Graffiti: b.graffiti[:],
ProposerSlashings: b.proposerSlashings,
AttesterSlashings: b.attesterSlashingsElectra,
Attestations: b.attestationsElectra,
Deposits: b.deposits,
VoluntaryExits: b.voluntaryExits,
SyncAggregate: b.syncAggregate,
ExecutionPayloadHeader: ph,
BlsToExecutionChanges: b.blsToExecutionChanges,
BlobKzgCommitments: b.blobKzgCommitments,
Consolidations: b.signedConsolidations,
}, nil
}
var p *enginev1.ExecutionPayloadElectra
var ok bool
if b.executionPayload != nil {
p, ok = b.executionPayload.Proto().(*enginev1.ExecutionPayloadElectra)
if !ok {
return nil, errPayloadWrongType
}
}
return &eth.BeaconBlockBodyElectra{
RandaoReveal: b.randaoReveal[:],
Eth1Data: b.eth1Data,
Graffiti: b.graffiti[:],
ProposerSlashings: b.proposerSlashings,
AttesterSlashings: b.attesterSlashingsElectra,
Attestations: b.attestationsElectra,
Deposits: b.deposits,
VoluntaryExits: b.voluntaryExits,
SyncAggregate: b.syncAggregate,
ExecutionPayload: p,
BlsToExecutionChanges: b.blsToExecutionChanges,
BlobKzgCommitments: b.blobKzgCommitments,
Consolidations: b.signedConsolidations,
}, nil
default:
return nil, errors.New("unsupported beacon block body version")
}
@@ -539,6 +650,23 @@ func initSignedBlockFromProtoDeneb(pb *eth.SignedBeaconBlockDeneb) (*SignedBeaco
return b, nil
}
func initSignedBlockFromProtoElectra(pb *eth.SignedBeaconBlockElectra) (*SignedBeaconBlock, error) {
if pb == nil {
return nil, errNilBlock
}
block, err := initBlockFromProtoElectra(pb.Block)
if err != nil {
return nil, err
}
b := &SignedBeaconBlock{
version: version.Electra,
block: block,
signature: bytesutil.ToBytes96(pb.Signature),
}
return b, nil
}
func initBlindedSignedBlockFromProtoBellatrix(pb *eth.SignedBlindedBeaconBlockBellatrix) (*SignedBeaconBlock, error) {
if pb == nil {
return nil, errNilBlock
@@ -590,6 +718,23 @@ func initBlindedSignedBlockFromProtoDeneb(pb *eth.SignedBlindedBeaconBlockDeneb)
return b, nil
}
func initBlindedSignedBlockFromProtoElectra(pb *eth.SignedBlindedBeaconBlockElectra) (*SignedBeaconBlock, error) {
if pb == nil {
return nil, errNilBlock
}
block, err := initBlindedBlockFromProtoElectra(pb.Message)
if err != nil {
return nil, err
}
b := &SignedBeaconBlock{
version: version.Electra,
block: block,
signature: bytesutil.ToBytes96(pb.Signature),
}
return b, nil
}
func initBlockFromProtoPhase0(pb *eth.BeaconBlock) (*BeaconBlock, error) {
if pb == nil {
return nil, errNilBlock
@@ -710,6 +855,26 @@ func initBlockFromProtoDeneb(pb *eth.BeaconBlockDeneb) (*BeaconBlock, error) {
return b, nil
}
func initBlockFromProtoElectra(pb *eth.BeaconBlockElectra) (*BeaconBlock, error) {
if pb == nil {
return nil, errNilBlock
}
body, err := initBlockBodyFromProtoElectra(pb.Body)
if err != nil {
return nil, err
}
b := &BeaconBlock{
version: version.Electra,
slot: pb.Slot,
proposerIndex: pb.ProposerIndex,
parentRoot: bytesutil.ToBytes32(pb.ParentRoot),
stateRoot: bytesutil.ToBytes32(pb.StateRoot),
body: body,
}
return b, nil
}
func initBlindedBlockFromProtoCapella(pb *eth.BlindedBeaconBlockCapella) (*BeaconBlock, error) {
if pb == nil {
return nil, errNilBlock
@@ -750,6 +915,26 @@ func initBlindedBlockFromProtoDeneb(pb *eth.BlindedBeaconBlockDeneb) (*BeaconBlo
return b, nil
}
func initBlindedBlockFromProtoElectra(pb *eth.BlindedBeaconBlockElectra) (*BeaconBlock, error) {
if pb == nil {
return nil, errNilBlock
}
body, err := initBlindedBlockBodyFromProtoElectra(pb.Body)
if err != nil {
return nil, err
}
b := &BeaconBlock{
version: version.Electra,
slot: pb.Slot,
proposerIndex: pb.ProposerIndex,
parentRoot: bytesutil.ToBytes32(pb.ParentRoot),
stateRoot: bytesutil.ToBytes32(pb.StateRoot),
body: body,
}
return b, nil
}
func initBlockBodyFromProtoPhase0(pb *eth.BeaconBlockBody) (*BeaconBlockBody, error) {
if pb == nil {
return nil, errNilBlockBody
@@ -923,6 +1108,35 @@ func initBlockBodyFromProtoDeneb(pb *eth.BeaconBlockBodyDeneb) (*BeaconBlockBody
return b, nil
}
func initBlockBodyFromProtoElectra(pb *eth.BeaconBlockBodyElectra) (*BeaconBlockBody, error) {
if pb == nil {
return nil, errNilBlockBody
}
p, err := WrappedExecutionPayloadElectra(pb.ExecutionPayload, big.NewInt(0))
// We allow the payload to be nil
if err != nil && err != consensus_types.ErrNilObjectWrapped {
return nil, err
}
b := &BeaconBlockBody{
version: version.Electra,
randaoReveal: bytesutil.ToBytes96(pb.RandaoReveal),
eth1Data: pb.Eth1Data,
graffiti: bytesutil.ToBytes32(pb.Graffiti),
proposerSlashings: pb.ProposerSlashings,
attesterSlashingsElectra: pb.AttesterSlashings,
attestationsElectra: pb.Attestations,
deposits: pb.Deposits,
voluntaryExits: pb.VoluntaryExits,
syncAggregate: pb.SyncAggregate,
executionPayload: p,
blsToExecutionChanges: pb.BlsToExecutionChanges,
blobKzgCommitments: pb.BlobKzgCommitments,
signedConsolidations: pb.Consolidations,
}
return b, nil
}
func initBlindedBlockBodyFromProtoDeneb(pb *eth.BlindedBeaconBlockBodyDeneb) (*BeaconBlockBody, error) {
if pb == nil {
return nil, errNilBlockBody
@@ -950,3 +1164,32 @@ func initBlindedBlockBodyFromProtoDeneb(pb *eth.BlindedBeaconBlockBodyDeneb) (*B
}
return b, nil
}
func initBlindedBlockBodyFromProtoElectra(pb *eth.BlindedBeaconBlockBodyElectra) (*BeaconBlockBody, error) {
if pb == nil {
return nil, errNilBlockBody
}
ph, err := WrappedExecutionPayloadHeaderElectra(pb.ExecutionPayloadHeader, big.NewInt(0))
// We allow the payload to be nil
if err != nil && err != consensus_types.ErrNilObjectWrapped {
return nil, err
}
b := &BeaconBlockBody{
version: version.Electra,
randaoReveal: bytesutil.ToBytes96(pb.RandaoReveal),
eth1Data: pb.Eth1Data,
graffiti: bytesutil.ToBytes32(pb.Graffiti),
proposerSlashings: pb.ProposerSlashings,
attesterSlashingsElectra: pb.AttesterSlashings,
attestationsElectra: pb.Attestations,
deposits: pb.Deposits,
voluntaryExits: pb.VoluntaryExits,
syncAggregate: pb.SyncAggregate,
executionPayloadHeader: ph,
blsToExecutionChanges: pb.BlsToExecutionChanges,
blobKzgCommitments: pb.BlobKzgCommitments,
signedConsolidations: pb.Consolidations,
}
return b, nil
}

View File

@@ -125,7 +125,7 @@ func (b *SignedBeaconBlock) SetBlobKzgCommitments(c [][]byte) error {
switch b.version {
case version.Phase0, version.Altair, version.Bellatrix, version.Capella:
return consensus_types.ErrNotSupported("SetBlobKzgCommitments", b.version)
case version.Deneb:
case version.Deneb, version.Electra:
b.block.body.blobKzgCommitments = c
return nil
default:

View File

@@ -14,7 +14,6 @@ go_library(
"//consensus-types/interfaces:go_default_library",
"//consensus-types/primitives:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
"//runtime/version:go_default_library",
"@com_github_pkg_errors//:go_default_library",
],
)

View File

@@ -5,7 +5,6 @@ import (
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
eth "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v5/runtime/version"
)
type blockMutator struct {
@@ -16,38 +15,23 @@ type blockMutator struct {
}
func (m blockMutator) apply(b interfaces.SignedBeaconBlock) (interfaces.SignedBeaconBlock, error) {
switch b.Version() {
case version.Phase0:
bb, err := b.PbPhase0Block()
if err != nil {
return nil, err
}
m.Phase0(bb)
return blocks.NewSignedBeaconBlock(bb)
case version.Altair:
bb, err := b.PbAltairBlock()
if err != nil {
return nil, err
}
m.Altair(bb)
return blocks.NewSignedBeaconBlock(bb)
case version.Bellatrix:
bb, err := b.PbBellatrixBlock()
if err != nil {
return nil, err
}
m.Bellatrix(bb)
return blocks.NewSignedBeaconBlock(bb)
case version.Capella:
bb, err := b.PbCapellaBlock()
if err != nil {
return nil, err
}
m.Capella(bb)
return blocks.NewSignedBeaconBlock(bb)
pb, err := b.Proto()
if err != nil {
return nil, err
}
switch pbStruct := pb.(type) {
case *eth.SignedBeaconBlock:
m.Phase0(pbStruct)
case *eth.SignedBeaconBlockAltair:
m.Altair(pbStruct)
case *eth.SignedBeaconBlockBellatrix:
m.Bellatrix(pbStruct)
case *eth.SignedBeaconBlockCapella:
m.Capella(pbStruct)
default:
return nil, blocks.ErrUnsupportedSignedBeaconBlock
}
return blocks.NewSignedBeaconBlock(pb)
}
// SetBlockStateRoot modifies the block's state root.

View File

@@ -38,22 +38,28 @@ var (
// BeaconBlockBody is the main beacon block body structure. It can represent any block type.
type BeaconBlockBody struct {
version int
randaoReveal [field_params.BLSSignatureLength]byte
eth1Data *eth.Eth1Data
graffiti [field_params.RootLength]byte
proposerSlashings []*eth.ProposerSlashing
attesterSlashings []*eth.AttesterSlashing
attestations []*eth.Attestation
deposits []*eth.Deposit
voluntaryExits []*eth.SignedVoluntaryExit
syncAggregate *eth.SyncAggregate
executionPayload interfaces.ExecutionData
executionPayloadHeader interfaces.ExecutionData
blsToExecutionChanges []*eth.SignedBLSToExecutionChange
blobKzgCommitments [][]byte
version int
randaoReveal [field_params.BLSSignatureLength]byte
eth1Data *eth.Eth1Data
graffiti [field_params.RootLength]byte
proposerSlashings []*eth.ProposerSlashing
attesterSlashings []*eth.AttesterSlashing
attesterSlashingsElectra []*eth.AttesterSlashingElectra
attestations []*eth.Attestation
attestationsElectra []*eth.AttestationElectra
deposits []*eth.Deposit
voluntaryExits []*eth.SignedVoluntaryExit
syncAggregate *eth.SyncAggregate
executionPayload interfaces.ExecutionData
executionPayloadHeader interfaces.ExecutionData
blsToExecutionChanges []*eth.SignedBLSToExecutionChange
blobKzgCommitments [][]byte
signedConsolidations []*eth.SignedConsolidation
}
var _ interfaces.ReadOnlyBeaconBlockBody = &BeaconBlockBody{}
var _ interfaces.ROBlockBodyElectra = &BeaconBlockBody{}
// BeaconBlock is the main beacon block structure. It can represent any block type.
type BeaconBlock struct {
version int

View File

@@ -4,6 +4,8 @@ go_library(
name = "go_default_library",
srcs = [
"beacon_block.go",
"cast.go",
"error.go",
"utils.go",
],
importpath = "github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces",
@@ -15,6 +17,7 @@ go_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",
"@com_github_pkg_errors//:go_default_library",
"@com_github_prysmaticlabs_fastssz//:go_default_library",
"@org_golang_google_protobuf//proto:go_default_library",
@@ -23,14 +26,19 @@ go_library(
go_test(
name = "go_default_test",
srcs = ["utils_test.go"],
srcs = [
"error_test.go",
"utils_test.go",
],
embed = [":go_default_library"],
deps = [
":go_default_library",
"//config/fieldparams:go_default_library",
"//consensus-types/blocks:go_default_library",
"//encoding/bytesutil:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
"//runtime/version:go_default_library",
"//testing/assert:go_default_library",
"//testing/require:go_default_library",
"@com_github_pkg_errors//:go_default_library",
],
)

View File

@@ -1,6 +1,7 @@
package interfaces
import (
"github.com/pkg/errors"
ssz "github.com/prysmaticlabs/fastssz"
field_params "github.com/prysmaticlabs/prysm/v5/config/fieldparams"
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
@@ -11,6 +12,8 @@ import (
"google.golang.org/protobuf/proto"
)
var ErrIncompatibleFork = errors.New("Can't convert to fork-specific interface")
// ReadOnlySignedBeaconBlock is an interface describing the method set of
// a signed beacon block.
type ReadOnlySignedBeaconBlock interface {
@@ -79,6 +82,11 @@ type ReadOnlyBeaconBlockBody interface {
BlobKzgCommitments() ([][]byte, error)
}
type ROBlockBodyElectra interface {
ReadOnlyBeaconBlockBody
Consolidations() []*ethpb.SignedConsolidation
}
type SignedBeaconBlock interface {
ReadOnlySignedBeaconBlock
SetExecution(ExecutionData) error
@@ -132,6 +140,13 @@ type ExecutionData interface {
PbCapella() (*enginev1.ExecutionPayloadCapella, error)
PbBellatrix() (*enginev1.ExecutionPayload, error)
PbDeneb() (*enginev1.ExecutionPayloadDeneb, error)
PbElectra() (*enginev1.ExecutionPayloadElectra, error)
ValueInWei() (math.Wei, error)
ValueInGwei() (uint64, error)
}
type ExecutionDataElectra interface {
ExecutionData
DepositReceipts() []*enginev1.DepositReceipt
WithdrawalRequests() []*enginev1.ExecutionLayerWithdrawalRequest
}

View File

@@ -0,0 +1,15 @@
package interfaces
import "github.com/prysmaticlabs/prysm/v5/runtime/version"
// AsROBlockBodyElectra safely asserts the ReadOnlyBeaconBlockBody to a ROBlockBodyElectra.
// This allows the caller to access methods on the block body which are only available on values after
// the Electra hard fork. If the value is for an earlier fork (based on comparing its Version() to the electra version)
// an error will be returned. Callers that want to conditionally process electra data can check for this condition
// and safely ignore it like `if err != nil && errors.Is(interfaces.ErrInvalidCast) {`
func AsROBlockBodyElectra(in ReadOnlyBeaconBlockBody) (ROBlockBodyElectra, error) {
if in.Version() >= version.Electra {
return in.(ROBlockBodyElectra), nil
}
return nil, NewInvalidCastError(in.Version(), version.Electra)
}

View File

@@ -0,0 +1,27 @@
package interfaces
import (
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/v5/runtime/version"
)
var ErrInvalidCast = errors.New("unable to cast between types")
type InvalidCastError struct {
from int
to int
}
func (e *InvalidCastError) Error() string {
return errors.Wrapf(ErrInvalidCast,
"from=%s(%d), to=%s(%d)", version.String(e.from), e.from, version.String(e.to), e.to).
Error()
}
func (e *InvalidCastError) Is(err error) bool {
return errors.Is(err, ErrInvalidCast)
}
func NewInvalidCastError(from, to int) *InvalidCastError {
return &InvalidCastError{from: from, to: to}
}

View File

@@ -0,0 +1,14 @@
package interfaces
import (
"testing"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/v5/runtime/version"
"github.com/prysmaticlabs/prysm/v5/testing/require"
)
func TestNewInvalidCastError(t *testing.T) {
err := NewInvalidCastError(version.Phase0, version.Electra)
require.Equal(t, true, errors.Is(err, ErrInvalidCast))
}

View File

@@ -313,6 +313,10 @@ func (b *BeaconBlockBody) BlobKzgCommitments() ([][]byte, error) {
panic("implement me")
}
func (b *BeaconBlockBody) Consolidations() []*eth.SignedConsolidation {
panic("implement me")
}
func (b *BeaconBlockBody) Attestations() []*eth.Attestation {
panic("implement me")
}
@@ -324,3 +328,4 @@ func (b *BeaconBlockBody) Version() int {
var _ interfaces.ReadOnlySignedBeaconBlock = &SignedBeaconBlock{}
var _ interfaces.ReadOnlyBeaconBlock = &BeaconBlock{}
var _ interfaces.ReadOnlyBeaconBlockBody = &BeaconBlockBody{}
var _ interfaces.ROBlockBodyElectra = &BeaconBlockBody{}

View File

@@ -8,6 +8,7 @@ const (
Bellatrix
Capella
Deneb
Electra
)
var versionToString = map[int]string{
@@ -16,6 +17,7 @@ var versionToString = map[int]string{
Bellatrix: "bellatrix",
Capella: "capella",
Deneb: "deneb",
Electra: "electra",
}
// stringToVersion and allVersions are populated in init()