Removes fork-specific concrete type getters (#13941)

* removing typed pb accessors

* refactor ssz api resp handlers to avoid typed pbs

* json get block handler refactor

* SubmitBlindedBlock to use generic json handling

* update SubmitBlindedBlock

* clear out more usages of PbForkname methods

* remove fork-specific getters from block interface

* remove usages of payload pb methods

* remove pb helpers from execution payload interface

* Update beacon-chain/rpc/eth/beacon/handlers.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Update beacon-chain/rpc/eth/beacon/handlers.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Update api/client/builder/client.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Update api/client/builder/client.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Update api/client/builder/client.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Update api/client/builder/client.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Update api/client/builder/client.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Radek review

* fix error message

* deal with wonky builder responses

* ✂️

* gaz

* lint

* tweaks for deep source

---------

Co-authored-by: Kasey Kirkham <kasey@users.noreply.github.com>
Co-authored-by: Radosław Kapka <rkapka@wp.pl>
This commit is contained in:
kasey
2024-05-02 15:52:27 -05:00
committed by GitHub
parent 625818d556
commit c312a88aa3
26 changed files with 553 additions and 1442 deletions

View File

@@ -11,6 +11,7 @@ go_library(
importpath = "github.com/prysmaticlabs/prysm/v5/api/client/builder",
visibility = ["//visibility:public"],
deps = [
"//api:go_default_library",
"//api/server/structs:go_default_library",
"//config/fieldparams:go_default_library",
"//consensus-types:go_default_library",
@@ -28,6 +29,7 @@ go_library(
"@com_github_prysmaticlabs_fastssz//:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",
"@io_opencensus_go//trace:go_default_library",
"@org_golang_google_protobuf//proto:go_default_library",
],
)
@@ -49,6 +51,7 @@ go_test(
"//math:go_default_library",
"//proto/engine/v1: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_ethereum_go_ethereum//common/hexutil:go_default_library",

View File

@@ -6,7 +6,6 @@ import (
"encoding/json"
"fmt"
"io"
"math/big"
"net"
"net/http"
"net/url"
@@ -14,11 +13,11 @@ import (
"text/template"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/v5/api"
"github.com/prysmaticlabs/prysm/v5/api/server/structs"
"github.com/prysmaticlabs/prysm/v5/consensus-types/blocks"
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
"github.com/prysmaticlabs/prysm/v5/monitoring/tracing"
v1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1"
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
@@ -282,133 +281,68 @@ func (c *Client) RegisterValidator(ctx context.Context, svr []*ethpb.SignedValid
return err
}
var errResponseVersionMismatch = errors.New("builder API response uses a different version than requested in " + api.VersionHeader + " header")
// SubmitBlindedBlock calls the builder API endpoint that binds the validator to the builder and submits the block.
// The response is the full execution payload used to create the blinded block.
func (c *Client) SubmitBlindedBlock(ctx context.Context, sb interfaces.ReadOnlySignedBeaconBlock) (interfaces.ExecutionData, *v1.BlobsBundle, error) {
if !sb.IsBlinded() {
return nil, nil, errNotBlinded
}
switch sb.Version() {
case version.Bellatrix:
psb, err := sb.PbBlindedBellatrixBlock()
if err != nil {
return nil, nil, errors.Wrapf(err, "could not get protobuf block")
}
b, err := structs.SignedBlindedBeaconBlockBellatrixFromConsensus(&ethpb.SignedBlindedBeaconBlockBellatrix{Block: psb.Block, Signature: bytesutil.SafeCopyBytes(psb.Signature)})
if err != nil {
return nil, nil, errors.Wrapf(err, "could not convert SignedBlindedBeaconBlockBellatrix to json marshalable type")
}
body, err := json.Marshal(b)
if err != nil {
return nil, nil, errors.Wrap(err, "error encoding the SignedBlindedBeaconBlockBellatrix value body in SubmitBlindedBlock")
}
versionOpt := func(r *http.Request) {
r.Header.Add("Eth-Consensus-Version", version.String(version.Bellatrix))
r.Header.Set("Content-Type", "application/json")
r.Header.Set("Accept", "application/json")
}
rb, err := c.do(ctx, http.MethodPost, postBlindedBeaconBlockPath, bytes.NewBuffer(body), versionOpt)
if err != nil {
return nil, nil, errors.Wrap(err, "error posting the SignedBlindedBeaconBlockBellatrix to the builder api")
}
ep := &ExecPayloadResponse{}
if err := json.Unmarshal(rb, ep); err != nil {
return nil, nil, errors.Wrap(err, "error unmarshaling the builder SubmitBlindedBlock response")
}
if strings.ToLower(ep.Version) != version.String(version.Bellatrix) {
return nil, nil, errors.New("not a bellatrix payload")
}
p, err := ep.ToProto()
if err != nil {
return nil, nil, errors.Wrapf(err, "could not extract proto message from payload")
}
payload, err := blocks.WrappedExecutionPayload(p)
if err != nil {
return nil, nil, errors.Wrapf(err, "could not wrap execution payload in interface")
}
return payload, nil, nil
case version.Capella:
psb, err := sb.PbBlindedCapellaBlock()
if err != nil {
return nil, nil, errors.Wrapf(err, "could not get protobuf block")
}
b, err := structs.SignedBlindedBeaconBlockCapellaFromConsensus(&ethpb.SignedBlindedBeaconBlockCapella{Block: psb.Block, Signature: bytesutil.SafeCopyBytes(psb.Signature)})
if err != nil {
return nil, nil, errors.Wrapf(err, "could not convert SignedBlindedBeaconBlockCapella to json marshalable type")
}
body, err := json.Marshal(b)
if err != nil {
return nil, nil, errors.Wrap(err, "error encoding the SignedBlindedBeaconBlockCapella value body in SubmitBlindedBlockCapella")
}
versionOpt := func(r *http.Request) {
r.Header.Add("Eth-Consensus-Version", version.String(version.Capella))
r.Header.Set("Content-Type", "application/json")
r.Header.Set("Accept", "application/json")
}
rb, err := c.do(ctx, http.MethodPost, postBlindedBeaconBlockPath, bytes.NewBuffer(body), versionOpt)
if err != nil {
return nil, nil, errors.Wrap(err, "error posting the SignedBlindedBeaconBlockCapella to the builder api")
}
ep := &ExecPayloadResponseCapella{}
if err := json.Unmarshal(rb, ep); err != nil {
return nil, nil, errors.Wrap(err, "error unmarshaling the builder SubmitBlindedBlockCapella response")
}
if strings.ToLower(ep.Version) != version.String(version.Capella) {
return nil, nil, errors.New("not a capella payload")
}
p, err := ep.ToProto()
if err != nil {
return nil, nil, errors.Wrapf(err, "could not extract proto message from payload")
}
payload, err := blocks.WrappedExecutionPayloadCapella(p, big.NewInt(0))
if err != nil {
return nil, nil, errors.Wrapf(err, "could not wrap execution payload in interface")
}
return payload, nil, nil
case version.Deneb:
psb, err := sb.PbBlindedDenebBlock()
if err != nil {
return nil, nil, errors.Wrapf(err, "could not get protobuf block")
}
b, err := structs.SignedBlindedBeaconBlockDenebFromConsensus(&ethpb.SignedBlindedBeaconBlockDeneb{Message: psb.Message, Signature: bytesutil.SafeCopyBytes(psb.Signature)})
if err != nil {
return nil, nil, errors.Wrapf(err, "could not convert SignedBlindedBeaconBlockDeneb to json marshalable type")
}
body, err := json.Marshal(b)
if err != nil {
return nil, nil, errors.Wrap(err, "error encoding the SignedBlindedBeaconBlockDeneb value body in SubmitBlindedBlockDeneb")
}
versionOpt := func(r *http.Request) {
r.Header.Add("Eth-Consensus-Version", version.String(version.Deneb))
r.Header.Set("Content-Type", "application/json")
r.Header.Set("Accept", "application/json")
}
rb, err := c.do(ctx, http.MethodPost, postBlindedBeaconBlockPath, bytes.NewBuffer(body), versionOpt)
if err != nil {
return nil, nil, errors.Wrap(err, "error posting the SignedBlindedBeaconBlockDeneb to the builder api")
}
ep := &ExecPayloadResponseDeneb{}
if err := json.Unmarshal(rb, ep); err != nil {
return nil, nil, errors.Wrap(err, "error unmarshaling the builder SubmitBlindedBlockDeneb response")
}
if strings.ToLower(ep.Version) != version.String(version.Deneb) {
return nil, nil, errors.New("not a deneb payload")
}
p, blobBundle, err := ep.ToProto()
if err != nil {
return nil, nil, errors.Wrapf(err, "could not extract proto message from payload")
}
payload, err := blocks.WrappedExecutionPayloadDeneb(p, big.NewInt(0))
if err != nil {
return nil, nil, errors.Wrapf(err, "could not wrap execution payload in interface")
}
return payload, blobBundle, nil
default:
return nil, nil, fmt.Errorf("unsupported block version %s", version.String(sb.Version()))
// massage the proto struct type data into the api response type.
mj, err := structs.SignedBeaconBlockMessageJsoner(sb)
if err != nil {
return nil, nil, errors.Wrap(err, "error generating blinded beacon block post request")
}
body, err := json.Marshal(mj)
if err != nil {
return nil, nil, errors.Wrap(err, "error marshaling blinded block post request to json")
}
postOpts := func(r *http.Request) {
r.Header.Add("Eth-Consensus-Version", version.String(sb.Version()))
r.Header.Set("Content-Type", api.JsonMediaType)
r.Header.Set("Accept", api.JsonMediaType)
}
// post the blinded block - the execution payload response should contain the unblinded payload, along with the
// blobs bundle if it is post deneb.
rb, err := c.do(ctx, http.MethodPost, postBlindedBeaconBlockPath, bytes.NewBuffer(body), postOpts)
if err != nil {
return nil, nil, errors.Wrap(err, "error posting the blinded block to the builder api")
}
// ExecutionPayloadResponse parses just the outer container and the Value key, enabling it to use the .Value
// key to determine which underlying data type to use to finish the unmarshaling.
ep := &ExecutionPayloadResponse{}
if err := json.Unmarshal(rb, ep); err != nil {
return nil, nil, errors.Wrap(err, "error unmarshaling the builder ExecutionPayloadResponse")
}
if strings.ToLower(ep.Version) != version.String(sb.Version()) {
return nil, nil, errors.Wrapf(errResponseVersionMismatch, "req=%s, recv=%s", strings.ToLower(ep.Version), version.String(sb.Version()))
}
// This parses the rest of the response and returns the inner data field.
pp, err := ep.ParsePayload()
if err != nil {
return nil, nil, errors.Wrapf(err, "failed to parse execution payload from builder with version=%s", ep.Version)
}
// Get the payload as a proto.Message so it can be wrapped as an execution payload interface.
pb, err := pp.PayloadProto()
if err != nil {
return nil, nil, err
}
ed, err := blocks.NewWrappedExecutionData(pb, nil)
if err != nil {
return nil, nil, err
}
bb, ok := pp.(BlobBundler)
if ok {
bbpb, err := bb.BundleProto()
if err != nil {
return nil, nil, errors.Wrapf(err, "failed to extract blobs bundle from builder response with version=%s", ep.Version)
}
return ed, bbpb, nil
}
return ed, nil, nil
}
// Status asks the remote builder server for a health check. A response of 200 with an empty body is the success/healthy

View File

@@ -432,7 +432,7 @@ func TestSubmitBlindedBlock(t *testing.T) {
sbbb, err := blocks.NewSignedBeaconBlock(testSignedBlindedBeaconBlockBellatrix(t))
require.NoError(t, err)
_, _, err = c.SubmitBlindedBlock(ctx, sbbb)
require.ErrorContains(t, "not a bellatrix payload", err)
require.ErrorIs(t, err, errResponseVersionMismatch)
})
t.Run("not blinded", func(t *testing.T) {
sbb, err := blocks.NewSignedBeaconBlock(&eth.SignedBeaconBlockBellatrix{Block: &eth.BeaconBlockBellatrix{Body: &eth.BeaconBlockBodyBellatrix{ExecutionPayload: &v1.ExecutionPayload{}}}})

View File

@@ -9,11 +9,15 @@ import (
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/pkg/errors"
fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams"
consensusblocks "github.com/prysmaticlabs/prysm/v5/consensus-types/blocks"
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
types "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
"github.com/prysmaticlabs/prysm/v5/math"
v1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1"
eth "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v5/runtime/version"
"google.golang.org/protobuf/proto"
)
var errInvalidUint256 = errors.New("invalid Uint256")
@@ -44,6 +48,9 @@ func sszBytesToUint256(b []byte) (Uint256, error) {
// SSZBytes creates an ssz-style (little-endian byte slice) representation of the Uint256.
func (s Uint256) SSZBytes() []byte {
if s.Int == nil {
s.Int = big.NewInt(0)
}
if !math.IsValidUint256(s.Int) {
return []byte{}
}
@@ -91,6 +98,9 @@ func (s Uint256) MarshalJSON() ([]byte, error) {
// MarshalText returns a text byte representation of Uint256.
func (s Uint256) MarshalText() ([]byte, error) {
if s.Int == nil {
s.Int = big.NewInt(0)
}
if !math.IsValidUint256(s.Int) {
return nil, errors.Wrapf(errInvalidUint256, "value=%s", s.Int)
}
@@ -265,6 +275,11 @@ func (r *ExecPayloadResponse) ToProto() (*v1.ExecutionPayload, error) {
return r.Data.ToProto()
}
func (r *ExecutionPayload) PayloadProto() (proto.Message, error) {
pb, err := r.ToProto()
return pb, err
}
// ToProto returns a ExecutionPayload Proto
func (p *ExecutionPayload) ToProto() (*v1.ExecutionPayload, error) {
txs := make([][]byte, len(p.Transactions))
@@ -396,6 +411,51 @@ func FromProtoDeneb(payload *v1.ExecutionPayloadDeneb) (ExecutionPayloadDeneb, e
}, nil
}
var errInvalidTypeConversion = errors.New("unable to translate between api and foreign type")
// ExecutionPayloadResponseFromData converts an ExecutionData interface value to a payload response.
// This involves serializing the execution payload value so that the abstract payload envelope can be used.
func ExecutionPayloadResponseFromData(ed interfaces.ExecutionData, bundle *v1.BlobsBundle) (*ExecutionPayloadResponse, error) {
pb := ed.Proto()
var data interface{}
var err error
var ver string
switch pbStruct := pb.(type) {
case *v1.ExecutionPayload:
ver = version.String(version.Bellatrix)
data, err = FromProto(pbStruct)
if err != nil {
return nil, errors.Wrap(err, "failed to convert a Bellatrix ExecutionPayload to an API response")
}
case *v1.ExecutionPayloadCapella:
ver = version.String(version.Capella)
data, err = FromProtoCapella(pbStruct)
if err != nil {
return nil, errors.Wrap(err, "failed to convert a Capella ExecutionPayload to an API response")
}
case *v1.ExecutionPayloadDeneb:
ver = version.String(version.Deneb)
payloadStruct, err := FromProtoDeneb(pbStruct)
if err != nil {
return nil, errors.Wrap(err, "failed to convert a Deneb ExecutionPayload to an API response")
}
data = &ExecutionPayloadDenebAndBlobsBundle{
ExecutionPayload: &payloadStruct,
BlobsBundle: FromBundleProto(bundle),
}
default:
return nil, errInvalidTypeConversion
}
encoded, err := json.Marshal(data)
if err != nil {
return nil, errors.Wrapf(err, "failed to marshal execution payload version=%s", ver)
}
return &ExecutionPayloadResponse{
Version: ver,
Data: encoded,
}, nil
}
// ExecHeaderResponseCapella is the response of builder API /eth/v1/builder/header/{slot}/{parent_hash}/{pubkey} for Capella.
type ExecHeaderResponseCapella struct {
Data struct {
@@ -523,6 +583,42 @@ type ExecPayloadResponseCapella struct {
Data ExecutionPayloadCapella `json:"data"`
}
// ExecutionPayloadResponse allows for unmarshaling just the Version field of the payload.
// This allows it to return different ExecutionPayload types based on the version field.
type ExecutionPayloadResponse struct {
Version string `json:"version"`
Data json.RawMessage `json:"data"`
}
// ParsedPayload can retrieve the underlying protobuf message for the given execution payload response.
type ParsedPayload interface {
PayloadProto() (proto.Message, error)
}
// BlobBundler can retrieve the underlying blob bundle protobuf message for the given execution payload response.
type BlobBundler interface {
BundleProto() (*v1.BlobsBundle, error)
}
func (r *ExecutionPayloadResponse) ParsePayload() (ParsedPayload, error) {
var toProto ParsedPayload
switch r.Version {
case version.String(version.Bellatrix):
toProto = &ExecutionPayload{}
case version.String(version.Capella):
toProto = &ExecutionPayloadCapella{}
case version.String(version.Deneb):
toProto = &ExecutionPayloadDenebAndBlobsBundle{}
default:
return nil, consensusblocks.ErrUnsupportedVersion
}
if err := json.Unmarshal(r.Data, toProto); err != nil {
return nil, errors.Wrap(err, "failed to unmarshal the response .Data field with the stated version schema")
}
return toProto, nil
}
// ExecutionPayloadCapella is a field of ExecPayloadResponseCapella.
type ExecutionPayloadCapella struct {
ParentHash hexutil.Bytes `json:"parent_hash"`
@@ -547,6 +643,11 @@ func (r *ExecPayloadResponseCapella) ToProto() (*v1.ExecutionPayloadCapella, err
return r.Data.ToProto()
}
func (p *ExecutionPayloadCapella) PayloadProto() (proto.Message, error) {
pb, err := p.ToProto()
return pb, err
}
// ToProto returns a ExecutionPayloadCapella Proto.
func (p *ExecutionPayloadCapella) ToProto() (*v1.ExecutionPayloadCapella, error) {
txs := make([][]byte, len(p.Transactions))
@@ -1128,6 +1229,12 @@ func (r *ExecPayloadResponseDeneb) ToProto() (*v1.ExecutionPayloadDeneb, *v1.Blo
if r.Data == nil {
return nil, nil, errors.New("data field in response is empty")
}
if r.Data.ExecutionPayload == nil {
return nil, nil, errors.Wrap(consensusblocks.ErrNilObject, "nil execution payload")
}
if r.Data.BlobsBundle == nil {
return nil, nil, errors.Wrap(consensusblocks.ErrNilObject, "nil blobs bundle")
}
payload, err := r.Data.ExecutionPayload.ToProto()
if err != nil {
return nil, nil, err
@@ -1139,8 +1246,26 @@ func (r *ExecPayloadResponseDeneb) ToProto() (*v1.ExecutionPayloadDeneb, *v1.Blo
return payload, bundle, nil
}
func (r *ExecutionPayloadDenebAndBlobsBundle) PayloadProto() (proto.Message, error) {
if r.ExecutionPayload == nil {
return nil, errors.Wrap(consensusblocks.ErrNilObject, "nil execution payload in combined deneb payload")
}
pb, err := r.ExecutionPayload.ToProto()
return pb, err
}
func (r *ExecutionPayloadDenebAndBlobsBundle) BundleProto() (*v1.BlobsBundle, error) {
if r.BlobsBundle == nil {
return nil, errors.Wrap(consensusblocks.ErrNilObject, "nil blobs bundle")
}
return r.BlobsBundle.ToProto()
}
// ToProto returns the ExecutionPayloadDeneb Proto.
func (p *ExecutionPayloadDeneb) ToProto() (*v1.ExecutionPayloadDeneb, error) {
if p == nil {
return nil, errors.Wrap(consensusblocks.ErrNilObject, "nil execution payload")
}
txs := make([][]byte, len(p.Transactions))
for i := range p.Transactions {
txs[i] = bytesutil.SafeCopyBytes(p.Transactions[i])

View File

@@ -15,9 +15,11 @@ import (
"github.com/prysmaticlabs/go-bitfield"
"github.com/prysmaticlabs/prysm/v5/api/server/structs"
fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams"
consensusblocks "github.com/prysmaticlabs/prysm/v5/consensus-types/blocks"
"github.com/prysmaticlabs/prysm/v5/math"
v1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1"
eth "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v5/runtime/version"
"github.com/prysmaticlabs/prysm/v5/testing/assert"
"github.com/prysmaticlabs/prysm/v5/testing/require"
)
@@ -1600,7 +1602,6 @@ func TestBuilderBidUnmarshalUint256(t *testing.T) {
require.NoError(t, expectedValue.UnmarshalText([]byte(base10)))
r := &ExecHeaderResponse{}
require.NoError(t, json.Unmarshal([]byte(testBuilderBid), r))
//require.Equal(t, expectedValue, r.Data.Message.Value)
marshaled := r.Data.Message.Value.String()
require.Equal(t, base10, marshaled)
require.Equal(t, 0, expectedValue.Cmp(r.Data.Message.Value.Int))
@@ -1907,3 +1908,40 @@ func TestErrorMessage_non200Err(t *testing.T) {
})
}
}
func TestEmptyResponseBody(t *testing.T) {
t.Run("empty buffer", func(t *testing.T) {
var b []byte
r := &ExecutionPayloadResponse{}
err := json.Unmarshal(b, r)
_, ok := err.(*json.SyntaxError)
require.Equal(t, true, ok)
})
t.Run("empty object", func(t *testing.T) {
empty := []byte("{}")
emptyResponse := &ExecutionPayloadResponse{}
require.NoError(t, json.Unmarshal(empty, emptyResponse))
_, err := emptyResponse.ParsePayload()
require.ErrorIs(t, err, consensusblocks.ErrUnsupportedVersion)
})
versions := []int{version.Bellatrix, version.Capella, version.Deneb}
for i := range versions {
vstr := version.String(versions[i])
t.Run("populated version without payload"+vstr, func(t *testing.T) {
in := &ExecutionPayloadResponse{Version: vstr}
encoded, err := json.Marshal(in)
require.NoError(t, err)
epr := &ExecutionPayloadResponse{}
require.NoError(t, json.Unmarshal(encoded, epr))
pp, err := epr.ParsePayload()
require.NoError(t, err)
pb, err := pp.PayloadProto()
if err == nil {
require.NoError(t, err)
require.Equal(t, false, pb == nil)
} else {
require.ErrorIs(t, err, consensusblocks.ErrNilObject)
}
})
}
}

View File

@@ -26,6 +26,7 @@ go_library(
"//api/server:go_default_library",
"//beacon-chain/state:go_default_library",
"//config/fieldparams:go_default_library",
"//consensus-types/interfaces:go_default_library",
"//consensus-types/primitives:go_default_library",
"//consensus-types/validator:go_default_library",
"//container/slice:go_default_library",

View File

@@ -1,10 +1,34 @@
package structs
import "encoding/json"
// MessageJsoner describes a signed consensus type wrapper that can return the `.Message` field in a json envelope
// encoded as a []byte, for use as a json.RawMessage value when encoding the outer envelope.
type MessageJsoner interface {
MessageRawJson() ([]byte, error)
}
// SignedMessageJsoner embeds MessageJsoner and adds a method to also retrieve the Signature field as a string.
type SignedMessageJsoner interface {
MessageJsoner
SigString() string
}
type SignedBeaconBlock struct {
Message *BeaconBlock `json:"message"`
Signature string `json:"signature"`
}
var _ SignedMessageJsoner = &SignedBeaconBlock{}
func (s *SignedBeaconBlock) MessageRawJson() ([]byte, error) {
return json.Marshal(s.Message)
}
func (s *SignedBeaconBlock) SigString() string {
return s.Signature
}
type BeaconBlock struct {
Slot string `json:"slot"`
ProposerIndex string `json:"proposer_index"`
@@ -29,6 +53,16 @@ type SignedBeaconBlockAltair struct {
Signature string `json:"signature"`
}
var _ SignedMessageJsoner = &SignedBeaconBlockAltair{}
func (s *SignedBeaconBlockAltair) MessageRawJson() ([]byte, error) {
return json.Marshal(s.Message)
}
func (s *SignedBeaconBlockAltair) SigString() string {
return s.Signature
}
type BeaconBlockAltair struct {
Slot string `json:"slot"`
ProposerIndex string `json:"proposer_index"`
@@ -54,6 +88,16 @@ type SignedBeaconBlockBellatrix struct {
Signature string `json:"signature"`
}
var _ SignedMessageJsoner = &SignedBeaconBlockBellatrix{}
func (s *SignedBeaconBlockBellatrix) MessageRawJson() ([]byte, error) {
return json.Marshal(s.Message)
}
func (s *SignedBeaconBlockBellatrix) SigString() string {
return s.Signature
}
type BeaconBlockBellatrix struct {
Slot string `json:"slot"`
ProposerIndex string `json:"proposer_index"`
@@ -80,6 +124,16 @@ type SignedBlindedBeaconBlockBellatrix struct {
Signature string `json:"signature"`
}
var _ SignedMessageJsoner = &SignedBlindedBeaconBlockBellatrix{}
func (s *SignedBlindedBeaconBlockBellatrix) MessageRawJson() ([]byte, error) {
return json.Marshal(s.Message)
}
func (s *SignedBlindedBeaconBlockBellatrix) SigString() string {
return s.Signature
}
type BlindedBeaconBlockBellatrix struct {
Slot string `json:"slot"`
ProposerIndex string `json:"proposer_index"`
@@ -106,6 +160,16 @@ type SignedBeaconBlockCapella struct {
Signature string `json:"signature"`
}
var _ SignedMessageJsoner = &SignedBeaconBlockCapella{}
func (s *SignedBeaconBlockCapella) MessageRawJson() ([]byte, error) {
return json.Marshal(s.Message)
}
func (s *SignedBeaconBlockCapella) SigString() string {
return s.Signature
}
type BeaconBlockCapella struct {
Slot string `json:"slot"`
ProposerIndex string `json:"proposer_index"`
@@ -133,6 +197,16 @@ type SignedBlindedBeaconBlockCapella struct {
Signature string `json:"signature"`
}
var _ SignedMessageJsoner = &SignedBlindedBeaconBlockCapella{}
func (s *SignedBlindedBeaconBlockCapella) MessageRawJson() ([]byte, error) {
return json.Marshal(s.Message)
}
func (s *SignedBlindedBeaconBlockCapella) SigString() string {
return s.Signature
}
type BlindedBeaconBlockCapella struct {
Slot string `json:"slot"`
ProposerIndex string `json:"proposer_index"`
@@ -172,6 +246,16 @@ type SignedBeaconBlockDeneb struct {
Signature string `json:"signature"`
}
var _ SignedMessageJsoner = &SignedBeaconBlockDeneb{}
func (s *SignedBeaconBlockDeneb) MessageRawJson() ([]byte, error) {
return json.Marshal(s.Message)
}
func (s *SignedBeaconBlockDeneb) SigString() string {
return s.Signature
}
type BeaconBlockDeneb struct {
Slot string `json:"slot"`
ProposerIndex string `json:"proposer_index"`
@@ -208,6 +292,16 @@ type SignedBlindedBeaconBlockDeneb struct {
Signature string `json:"signature"`
}
var _ SignedMessageJsoner = &SignedBlindedBeaconBlockDeneb{}
func (s *SignedBlindedBeaconBlockDeneb) MessageRawJson() ([]byte, error) {
return json.Marshal(s.Message)
}
func (s *SignedBlindedBeaconBlockDeneb) SigString() string {
return s.Signature
}
type BlindedBeaconBlockBodyDeneb struct {
RandaoReveal string `json:"randao_reveal"`
Eth1Data *Eth1Data `json:"eth1_data"`

View File

@@ -6,8 +6,10 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/v5/api/server"
fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams"
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
"github.com/prysmaticlabs/prysm/v5/container/slice"
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
@@ -15,6 +17,8 @@ import (
eth "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
)
var ErrUnsupportedConversion = errors.New("Could not determine api struct type to use for value")
func (h *SignedBeaconBlockHeader) ToConsensus() (*eth.SignedBeaconBlockHeader, error) {
msg, err := h.Message.ToConsensus()
if err != nil {
@@ -1852,7 +1856,34 @@ func BeaconBlockFromConsensus(b *eth.BeaconBlock) *BeaconBlock {
}
}
func SignedBeaconBlockFromConsensus(b *eth.SignedBeaconBlock) *SignedBeaconBlock {
func SignedBeaconBlockMessageJsoner(block interfaces.ReadOnlySignedBeaconBlock) (SignedMessageJsoner, error) {
pb, err := block.Proto()
if err != nil {
return nil, err
}
switch pbStruct := pb.(type) {
case *eth.SignedBeaconBlock:
return SignedBeaconBlockPhase0FromConsensus(pbStruct), nil
case *eth.SignedBeaconBlockAltair:
return SignedBeaconBlockAltairFromConsensus(pbStruct), nil
case *eth.SignedBlindedBeaconBlockBellatrix:
return SignedBlindedBeaconBlockBellatrixFromConsensus(pbStruct)
case *eth.SignedBeaconBlockBellatrix:
return SignedBeaconBlockBellatrixFromConsensus(pbStruct)
case *eth.SignedBlindedBeaconBlockCapella:
return SignedBlindedBeaconBlockCapellaFromConsensus(pbStruct)
case *eth.SignedBeaconBlockCapella:
return SignedBeaconBlockCapellaFromConsensus(pbStruct)
case *eth.SignedBlindedBeaconBlockDeneb:
return SignedBlindedBeaconBlockDenebFromConsensus(pbStruct)
case *eth.SignedBeaconBlockDeneb:
return SignedBeaconBlockDenebFromConsensus(pbStruct)
default:
return nil, ErrUnsupportedConversion
}
}
func SignedBeaconBlockPhase0FromConsensus(b *eth.SignedBeaconBlock) *SignedBeaconBlock {
return &SignedBeaconBlock{
Message: BeaconBlockFromConsensus(b.Block),
Signature: hexutil.Encode(b.Signature),

View File

@@ -115,6 +115,7 @@ go_test(
"//proto/engine/v1:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
"//proto/testing: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

@@ -14,6 +14,7 @@ import (
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
"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/testing/assert"
"github.com/prysmaticlabs/prysm/v5/testing/require"
"github.com/prysmaticlabs/prysm/v5/testing/util"
@@ -180,7 +181,7 @@ func TestStore_BlocksCRUD(t *testing.T) {
retrievedBlock, err = db.Block(ctx, blockRoot)
require.NoError(t, err)
wanted := retrievedBlock
if _, err := retrievedBlock.PbBellatrixBlock(); err == nil {
if retrievedBlock.Version() >= version.Bellatrix {
wanted, err = retrievedBlock.ToBlinded()
require.NoError(t, err)
}
@@ -368,15 +369,7 @@ func TestStore_BlocksCRUD_NoCache(t *testing.T) {
require.NoError(t, err)
wanted := blk
if _, err := blk.PbBellatrixBlock(); err == nil {
wanted, err = blk.ToBlinded()
require.NoError(t, err)
}
if _, err := blk.PbCapellaBlock(); err == nil {
wanted, err = blk.ToBlinded()
require.NoError(t, err)
}
if _, err := blk.PbDenebBlock(); err == nil {
if blk.Version() >= version.Bellatrix {
wanted, err = blk.ToBlinded()
require.NoError(t, err)
}
@@ -595,15 +588,7 @@ func TestStore_SaveBlock_CanGetHighestAt(t *testing.T) {
b, err := db.Block(ctx, root)
require.NoError(t, err)
wanted := block1
if _, err := block1.PbBellatrixBlock(); err == nil {
wanted, err = wanted.ToBlinded()
require.NoError(t, err)
}
if _, err := block1.PbCapellaBlock(); err == nil {
wanted, err = wanted.ToBlinded()
require.NoError(t, err)
}
if _, err := block1.PbDenebBlock(); err == nil {
if block1.Version() >= version.Bellatrix {
wanted, err = wanted.ToBlinded()
require.NoError(t, err)
}
@@ -621,15 +606,7 @@ func TestStore_SaveBlock_CanGetHighestAt(t *testing.T) {
b, err = db.Block(ctx, root)
require.NoError(t, err)
wanted2 := block2
if _, err := block2.PbBellatrixBlock(); err == nil {
wanted2, err = block2.ToBlinded()
require.NoError(t, err)
}
if _, err := block2.PbCapellaBlock(); err == nil {
wanted2, err = block2.ToBlinded()
require.NoError(t, err)
}
if _, err := block2.PbDenebBlock(); err == nil {
if block2.Version() >= version.Bellatrix {
wanted2, err = block2.ToBlinded()
require.NoError(t, err)
}
@@ -647,15 +624,7 @@ func TestStore_SaveBlock_CanGetHighestAt(t *testing.T) {
b, err = db.Block(ctx, root)
require.NoError(t, err)
wanted = block3
if _, err := block3.PbBellatrixBlock(); err == nil {
wanted, err = wanted.ToBlinded()
require.NoError(t, err)
}
if _, err := block3.PbCapellaBlock(); err == nil {
wanted, err = wanted.ToBlinded()
require.NoError(t, err)
}
if _, err := block3.PbDenebBlock(); err == nil {
if block3.Version() >= version.Bellatrix {
wanted, err = wanted.ToBlinded()
require.NoError(t, err)
}
@@ -691,15 +660,7 @@ func TestStore_GenesisBlock_CanGetHighestAt(t *testing.T) {
b, err := db.Block(ctx, root)
require.NoError(t, err)
wanted := block1
if _, err := block1.PbBellatrixBlock(); err == nil {
wanted, err = block1.ToBlinded()
require.NoError(t, err)
}
if _, err := block1.PbCapellaBlock(); err == nil {
wanted, err = block1.ToBlinded()
require.NoError(t, err)
}
if _, err := block1.PbDenebBlock(); err == nil {
if block1.Version() >= version.Bellatrix {
wanted, err = block1.ToBlinded()
require.NoError(t, err)
}
@@ -716,15 +677,7 @@ func TestStore_GenesisBlock_CanGetHighestAt(t *testing.T) {
b, err = db.Block(ctx, root)
require.NoError(t, err)
wanted = genesisBlock
if _, err := genesisBlock.PbBellatrixBlock(); err == nil {
wanted, err = genesisBlock.ToBlinded()
require.NoError(t, err)
}
if _, err := genesisBlock.PbCapellaBlock(); err == nil {
wanted, err = genesisBlock.ToBlinded()
require.NoError(t, err)
}
if _, err := genesisBlock.PbDenebBlock(); err == nil {
if genesisBlock.Version() >= version.Bellatrix {
wanted, err = genesisBlock.ToBlinded()
require.NoError(t, err)
}
@@ -741,15 +694,7 @@ func TestStore_GenesisBlock_CanGetHighestAt(t *testing.T) {
b, err = db.Block(ctx, root)
require.NoError(t, err)
wanted = genesisBlock
if _, err := genesisBlock.PbBellatrixBlock(); err == nil {
wanted, err = genesisBlock.ToBlinded()
require.NoError(t, err)
}
if _, err := genesisBlock.PbCapellaBlock(); err == nil {
wanted, err = genesisBlock.ToBlinded()
require.NoError(t, err)
}
if _, err := genesisBlock.PbDenebBlock(); err == nil {
if genesisBlock.Version() >= version.Bellatrix {
wanted, err = genesisBlock.ToBlinded()
require.NoError(t, err)
}
@@ -845,15 +790,7 @@ func TestStore_BlocksBySlot_BlockRootsBySlot(t *testing.T) {
require.NoError(t, err)
wanted := b1
if _, err := b1.PbBellatrixBlock(); err == nil {
wanted, err = b1.ToBlinded()
require.NoError(t, err)
}
if _, err := b1.PbCapellaBlock(); err == nil {
wanted, err = b1.ToBlinded()
require.NoError(t, err)
}
if _, err := b1.PbDenebBlock(); err == nil {
if b1.Version() >= version.Bellatrix {
wanted, err = b1.ToBlinded()
require.NoError(t, err)
}
@@ -869,15 +806,7 @@ func TestStore_BlocksBySlot_BlockRootsBySlot(t *testing.T) {
t.Fatalf("Expected 2 blocks, received %d blocks", len(retrievedBlocks))
}
wanted = b2
if _, err := b2.PbBellatrixBlock(); err == nil {
wanted, err = b2.ToBlinded()
require.NoError(t, err)
}
if _, err := b2.PbCapellaBlock(); err == nil {
wanted, err = b2.ToBlinded()
require.NoError(t, err)
}
if _, err := b2.PbDenebBlock(); err == nil {
if b2.Version() >= version.Bellatrix {
wanted, err = b2.ToBlinded()
require.NoError(t, err)
}
@@ -887,15 +816,7 @@ func TestStore_BlocksBySlot_BlockRootsBySlot(t *testing.T) {
require.NoError(t, err)
assert.Equal(t, true, proto.Equal(wantedPb, retrieved0Pb), "Wanted: %v, received: %v", retrievedBlocks[0], wanted)
wanted = b3
if _, err := b3.PbBellatrixBlock(); err == nil {
wanted, err = b3.ToBlinded()
require.NoError(t, err)
}
if _, err := b3.PbCapellaBlock(); err == nil {
wanted, err = b3.ToBlinded()
require.NoError(t, err)
}
if _, err := b3.PbDenebBlock(); err == nil {
if b3.Version() >= version.Bellatrix {
wanted, err = b3.ToBlinded()
require.NoError(t, err)
}

View File

@@ -16,7 +16,6 @@ import (
"github.com/ethereum/go-ethereum/common/hexutil"
gethtypes "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/rpc"
gethRPC "github.com/ethereum/go-ethereum/rpc"
"github.com/holiman/uint256"
"github.com/pkg/errors"
mocks "github.com/prysmaticlabs/prysm/v5/beacon-chain/execution/testing"
@@ -45,7 +44,7 @@ type RPCClientBad struct {
}
func (RPCClientBad) Close() {}
func (RPCClientBad) BatchCall([]gethRPC.BatchElem) error {
func (RPCClientBad) BatchCall([]rpc.BatchElem) error {
return errors.New("rpc client is not initialized")
}
@@ -76,7 +75,9 @@ func TestClient_IPC(t *testing.T) {
resp, _, override, err := srv.GetPayload(ctx, payloadId, 1)
require.NoError(t, err)
require.Equal(t, false, override)
resPb, err := resp.PbBellatrix()
pbs := resp.Proto()
resPb, ok := pbs.(*pb.ExecutionPayload)
require.Equal(t, true, ok)
require.NoError(t, err)
require.DeepEqual(t, want, resPb)
})
@@ -87,8 +88,9 @@ func TestClient_IPC(t *testing.T) {
resp, _, override, err := srv.GetPayload(ctx, payloadId, params.BeaconConfig().SlotsPerEpoch)
require.NoError(t, err)
require.Equal(t, false, override)
resPb, err := resp.PbCapella()
require.NoError(t, err)
pbs := resp.Proto()
resPb, ok := pbs.(*pb.ExecutionPayloadCapella)
require.Equal(t, true, ok)
require.DeepEqual(t, want, resPb)
})
t.Run(ForkchoiceUpdatedMethod, func(t *testing.T) {
@@ -201,9 +203,10 @@ func TestClient_HTTP(t *testing.T) {
resp, _, override, err := client.GetPayload(ctx, payloadId, 1)
require.NoError(t, err)
require.Equal(t, false, override)
pb, err := resp.PbBellatrix()
require.NoError(t, err)
require.DeepEqual(t, want, pb)
pbs := resp.Proto()
pbStruct, ok := pbs.(*pb.ExecutionPayload)
require.Equal(t, true, ok)
require.DeepEqual(t, want, pbStruct)
})
t.Run(GetPayloadMethodV2, func(t *testing.T) {
payloadId := [8]byte{1}
@@ -246,14 +249,15 @@ func TestClient_HTTP(t *testing.T) {
resp, _, override, err := client.GetPayload(ctx, payloadId, params.BeaconConfig().SlotsPerEpoch)
require.NoError(t, err)
require.Equal(t, false, override)
pb, err := resp.PbCapella()
require.NoError(t, err)
require.DeepEqual(t, want.ExecutionPayload.BlockHash.Bytes(), pb.BlockHash)
require.DeepEqual(t, want.ExecutionPayload.StateRoot.Bytes(), pb.StateRoot)
require.DeepEqual(t, want.ExecutionPayload.ParentHash.Bytes(), pb.ParentHash)
require.DeepEqual(t, want.ExecutionPayload.FeeRecipient.Bytes(), pb.FeeRecipient)
require.DeepEqual(t, want.ExecutionPayload.PrevRandao.Bytes(), pb.PrevRandao)
require.DeepEqual(t, want.ExecutionPayload.ParentHash.Bytes(), pb.ParentHash)
pbs := resp.Proto()
ep, ok := pbs.(*pb.ExecutionPayloadCapella)
require.Equal(t, true, ok)
require.DeepEqual(t, want.ExecutionPayload.BlockHash.Bytes(), ep.BlockHash)
require.DeepEqual(t, want.ExecutionPayload.StateRoot.Bytes(), ep.StateRoot)
require.DeepEqual(t, want.ExecutionPayload.ParentHash.Bytes(), ep.ParentHash)
require.DeepEqual(t, want.ExecutionPayload.FeeRecipient.Bytes(), ep.FeeRecipient)
require.DeepEqual(t, want.ExecutionPayload.PrevRandao.Bytes(), ep.PrevRandao)
require.DeepEqual(t, want.ExecutionPayload.ParentHash.Bytes(), ep.ParentHash)
v, err := resp.ValueInGwei()
require.NoError(t, err)

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"
@@ -24,7 +25,6 @@ import (
"github.com/prysmaticlabs/prysm/v5/beacon-chain/rpc/prysm/v1alpha1/validator"
fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams"
"github.com/prysmaticlabs/prysm/v5/config/params"
consensus_types "github.com/prysmaticlabs/prysm/v5/consensus-types"
"github.com/prysmaticlabs/prysm/v5/consensus-types/blocks"
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
@@ -46,10 +46,9 @@ 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
// GetBlockV2 retrieves block details for given block ID.
func (s *Server) GetBlockV2(w http.ResponseWriter, r *http.Request) {
ctx, span := trace.StartSpan(r.Context(), "beacon.GetBlockV2")
@@ -61,95 +60,27 @@ func (s *Server) GetBlockV2(w http.ResponseWriter, r *http.Request) {
return
}
blk, err := s.Blocker.Block(ctx, []byte(blockId))
if !shared.WriteBlockFetchError(w, blk, err) {
if err != nil {
shared.WriteBlockFetchError(w, blk, err)
return
}
// Deal with block unblinding.
if blk.Version() >= version.Bellatrix && blk.IsBlinded() {
blk, err = s.ExecutionPayloadReconstructor.ReconstructFullBlock(ctx, blk)
if err != nil {
shared.WriteBlockFetchError(w, blk, errors.Wrapf(err, "could not reconstruct full execution payload to create signed beacon block"))
return
}
}
if httputil.RespondWithSsz(r) {
s.getBlockSSZV2(ctx, w, blk)
s.getBlockV2Ssz(w, blk)
} else {
s.getBlockV2(ctx, w, blk)
s.getBlockV2Json(ctx, w, blk)
}
}
// getBlockV2 returns the JSON-serialized version of the beacon block for given block ID.
func (s *Server) getBlockV2(ctx context.Context, w http.ResponseWriter, blk interfaces.ReadOnlySignedBeaconBlock) {
blkRoot, err := blk.Block().HashTreeRoot()
if err != nil {
httputil.HandleError(w, "Could not get block root "+err.Error(), http.StatusInternalServerError)
return
}
finalized := s.FinalizationFetcher.IsFinalized(ctx, blkRoot)
getBlockHandler := func(get func(ctx context.Context, block interfaces.ReadOnlySignedBeaconBlock) (*structs.GetBlockV2Response, error)) handled {
result, err := get(ctx, blk)
if result != nil {
result.Finalized = finalized
w.Header().Set(api.VersionHeader, result.Version)
httputil.WriteJson(w, result)
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.getBlockDeneb) {
return
}
if getBlockHandler(s.getBlockCapella) {
return
}
if getBlockHandler(s.getBlockBellatrix) {
return
}
if getBlockHandler(s.getBlockAltair) {
return
}
if getBlockHandler(s.getBlockPhase0) {
return
}
httputil.HandleError(w, fmt.Sprintf("Unknown block type %T", blk), http.StatusInternalServerError)
}
// 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
}
if getBlockHandler(s.getBlockDenebSSZ, version.String(version.Deneb)) {
return
}
if getBlockHandler(s.getBlockCapellaSSZ, version.String(version.Capella)) {
return
}
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)
}
// GetBlindedBlock retrieves blinded block for given block id.
func (s *Server) GetBlindedBlock(w http.ResponseWriter, r *http.Request) {
ctx, span := trace.StartSpan(r.Context(), "beacon.GetBlindedBlock")
@@ -165,701 +96,100 @@ func (s *Server) GetBlindedBlock(w http.ResponseWriter, r *http.Request) {
return
}
// Convert to blinded block (if it's not already).
if blk.Version() >= version.Bellatrix && !blk.IsBlinded() {
blk, err = blk.ToBlinded()
if err != nil {
shared.WriteBlockFetchError(w, blk, errors.Wrapf(err, "could not convert block to blinded block"))
return
}
}
if httputil.RespondWithSsz(r) {
s.getBlindedBlockSSZ(ctx, w, blk)
s.getBlockV2Ssz(w, blk)
} else {
s.getBlindedBlock(ctx, w, blk)
s.getBlockV2Json(ctx, w, blk)
}
}
// getBlindedBlock returns the JSON-serialized version of the blinded beacon block for given block id.
func (s *Server) getBlindedBlock(ctx context.Context, w http.ResponseWriter, blk interfaces.ReadOnlySignedBeaconBlock) {
// getBlockV2Ssz returns the SSZ-serialized version of the beacon block for given block ID.
func (s *Server) getBlockV2Ssz(w http.ResponseWriter, blk interfaces.ReadOnlySignedBeaconBlock) {
result, err := s.getBlockResponseBodySsz(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")
}
func (*Server) getBlockResponseBodySsz(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
}
marshaler, ok := pb.(ssz.Marshaler)
if !ok {
return nil, errMarshalSSZ
}
sszData, err := marshaler.MarshalSSZ()
if err != nil {
return nil, errors.Wrapf(err, "could not marshal block into SSZ")
}
return sszData, nil
}
// getBlockV2Json returns the JSON-serialized version of the beacon block for given block ID.
func (s *Server) getBlockV2Json(ctx context.Context, w http.ResponseWriter, blk interfaces.ReadOnlySignedBeaconBlock) {
result, err := s.getBlockResponseBodyJson(ctx, blk)
if err != nil {
httputil.HandleError(w, "Error processing request: "+err.Error(), http.StatusInternalServerError)
}
w.Header().Set(api.VersionHeader, result.Version)
httputil.WriteJson(w, result)
}
func (s *Server) getBlockResponseBodyJson(ctx context.Context, blk interfaces.ReadOnlySignedBeaconBlock) (*structs.GetBlockV2Response, error) {
if err := blocks.BeaconBlockIsNil(blk); err != nil {
return nil, err
}
blkRoot, err := blk.Block().HashTreeRoot()
if err != nil {
httputil.HandleError(w, "Could not get block root "+err.Error(), http.StatusInternalServerError)
return
return nil, errors.Wrap(err, "could not get block root")
}
finalized := s.FinalizationFetcher.IsFinalized(ctx, blkRoot)
getBlockHandler := func(get func(ctx context.Context, block interfaces.ReadOnlySignedBeaconBlock) (*structs.GetBlockV2Response, error)) handled {
result, err := get(ctx, blk)
if result != nil {
result.Finalized = finalized
w.Header().Set(api.VersionHeader, result.Version)
httputil.WriteJson(w, result)
return true
isOptimistic := false
if blk.Version() >= version.Bellatrix {
isOptimistic, err = s.OptimisticModeFetcher.IsOptimisticForRoot(ctx, blkRoot)
if err != nil {
return nil, errors.Wrap(err, "could not check if block is optimistic")
}
// 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.getBlockPhase0) {
return
}
if getBlockHandler(s.getBlockAltair) {
return
}
if getBlockHandler(s.getBlindedBlockBellatrix) {
return
}
if getBlockHandler(s.getBlindedBlockCapella) {
return
}
if getBlockHandler(s.getBlindedBlockDeneb) {
return
}
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()
mj, err := structs.SignedBeaconBlockMessageJsoner(blk)
if err != nil {
return nil, err
}
if consensusBlk == nil {
return nil, errNilBlock
}
respBlk := structs.SignedBeaconBlockFromConsensus(consensusBlk)
jsonBytes, err := json.Marshal(respBlk.Message)
jb, err := mj.MessageRawJson()
if err != nil {
return nil, err
}
return &structs.GetBlockV2Response{
Version: version.String(version.Phase0),
ExecutionOptimistic: false,
Data: &structs.SignedBlock{
Message: jsonBytes,
Signature: respBlk.Signature,
},
}, nil
}
func (*Server) getBlockAltair(_ context.Context, blk interfaces.ReadOnlySignedBeaconBlock) (*structs.GetBlockV2Response, error) {
consensusBlk, err := blk.PbAltairBlock()
if err != nil {
return nil, err
}
if consensusBlk == nil {
return nil, errNilBlock
}
respBlk := structs.SignedBeaconBlockAltairFromConsensus(consensusBlk)
jsonBytes, err := json.Marshal(respBlk.Message)
if err != nil {
return nil, err
}
return &structs.GetBlockV2Response{
Version: version.String(version.Altair),
ExecutionOptimistic: false,
Data: &structs.SignedBlock{
Message: jsonBytes,
Signature: respBlk.Signature,
},
}, nil
}
func (s *Server) getBlockBellatrix(ctx context.Context, blk interfaces.ReadOnlySignedBeaconBlock) (*structs.GetBlockV2Response, 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
}
root, err := blk.Block().HashTreeRoot()
if err != nil {
return nil, errors.Wrapf(err, "could not get block root")
}
isOptimistic, err := s.OptimisticModeFetcher.IsOptimisticForRoot(ctx, root)
if err != nil {
return nil, errors.Wrapf(err, "could not check if block is optimistic")
}
respBlk, err := structs.SignedBeaconBlockBellatrixFromConsensus(consensusBlk)
if err != nil {
return nil, err
}
jsonBytes, err := json.Marshal(respBlk.Message)
if err != nil {
return nil, err
}
return &structs.GetBlockV2Response{
Version: version.String(version.Bellatrix),
Finalized: finalized,
ExecutionOptimistic: isOptimistic,
Version: version.String(blk.Version()),
Data: &structs.SignedBlock{
Message: jsonBytes,
Signature: respBlk.Signature,
Message: jb,
Signature: mj.SigString(),
},
}, nil
}
func (s *Server) getBlockCapella(ctx context.Context, blk interfaces.ReadOnlySignedBeaconBlock) (*structs.GetBlockV2Response, 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
}
root, err := blk.Block().HashTreeRoot()
if err != nil {
return nil, errors.Wrapf(err, "could not get block root")
}
isOptimistic, err := s.OptimisticModeFetcher.IsOptimisticForRoot(ctx, root)
if err != nil {
return nil, errors.Wrapf(err, "could not check if block is optimistic")
}
respBlk, err := structs.SignedBeaconBlockCapellaFromConsensus(consensusBlk)
if err != nil {
return nil, err
}
jsonBytes, err := json.Marshal(respBlk.Message)
if err != nil {
return nil, err
}
return &structs.GetBlockV2Response{
Version: version.String(version.Capella),
ExecutionOptimistic: isOptimistic,
Data: &structs.SignedBlock{
Message: jsonBytes,
Signature: respBlk.Signature,
},
}, nil
}
func (s *Server) getBlockDeneb(ctx context.Context, blk interfaces.ReadOnlySignedBeaconBlock) (*structs.GetBlockV2Response, 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
}
root, err := blk.Block().HashTreeRoot()
if err != nil {
return nil, errors.Wrapf(err, "could not get block root")
}
isOptimistic, err := s.OptimisticModeFetcher.IsOptimisticForRoot(ctx, root)
if err != nil {
return nil, errors.Wrapf(err, "could not check if block is optimistic")
}
respBlk, err := structs.SignedBeaconBlockDenebFromConsensus(consensusBlk)
if err != nil {
return nil, err
}
jsonBytes, err := json.Marshal(respBlk.Message)
if err != nil {
return nil, err
}
return &structs.GetBlockV2Response{
Version: version.String(version.Deneb),
ExecutionOptimistic: isOptimistic,
Data: &structs.SignedBlock{
Message: jsonBytes,
Signature: respBlk.Signature,
},
}, nil
}
func (*Server) getBlockPhase0SSZ(_ context.Context, blk interfaces.ReadOnlySignedBeaconBlock) ([]byte, error) {
consensusBlk, err := blk.PbPhase0Block()
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 (*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()
if err != nil {
return nil, errors.Wrapf(err, "could not marshal block into SSZ")
}
return sszData, nil
}
func (s *Server) getBlindedBlockBellatrix(ctx context.Context, blk interfaces.ReadOnlySignedBeaconBlock) (*structs.GetBlockV2Response, 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
}
root, err := blk.Block().HashTreeRoot()
if err != nil {
return nil, errors.Wrapf(err, "could not get block root")
}
isOptimistic, err := s.OptimisticModeFetcher.IsOptimisticForRoot(ctx, root)
if err != nil {
return nil, errors.Wrapf(err, "could not check if block is optimistic")
}
respBlk, err := structs.SignedBlindedBeaconBlockBellatrixFromConsensus(blindedConsensusBlk)
if err != nil {
return nil, err
}
jsonBytes, err := json.Marshal(respBlk.Message)
if err != nil {
return nil, err
}
return &structs.GetBlockV2Response{
Version: version.String(version.Bellatrix),
ExecutionOptimistic: isOptimistic,
Data: &structs.SignedBlock{
Message: jsonBytes,
Signature: respBlk.Signature,
},
}, nil
}
func (s *Server) getBlindedBlockCapella(ctx context.Context, blk interfaces.ReadOnlySignedBeaconBlock) (*structs.GetBlockV2Response, 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
}
root, err := blk.Block().HashTreeRoot()
if err != nil {
return nil, errors.Wrapf(err, "could not get block root")
}
isOptimistic, err := s.OptimisticModeFetcher.IsOptimisticForRoot(ctx, root)
if err != nil {
return nil, errors.Wrapf(err, "could not check if block is optimistic")
}
respBlk, err := structs.SignedBlindedBeaconBlockCapellaFromConsensus(blindedConsensusBlk)
if err != nil {
return nil, err
}
jsonBytes, err := json.Marshal(respBlk.Message)
if err != nil {
return nil, err
}
return &structs.GetBlockV2Response{
Version: version.String(version.Capella),
ExecutionOptimistic: isOptimistic,
Data: &structs.SignedBlock{
Message: jsonBytes,
Signature: respBlk.Signature,
},
}, nil
}
func (s *Server) getBlindedBlockDeneb(ctx context.Context, blk interfaces.ReadOnlySignedBeaconBlock) (*structs.GetBlockV2Response, 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
}
root, err := blk.Block().HashTreeRoot()
if err != nil {
return nil, errors.Wrapf(err, "could not get block root")
}
isOptimistic, err := s.OptimisticModeFetcher.IsOptimisticForRoot(ctx, root)
if err != nil {
return nil, errors.Wrapf(err, "could not check if block is optimistic")
}
respBlk, err := structs.SignedBlindedBeaconBlockDenebFromConsensus(blindedConsensusBlk)
if err != nil {
return nil, err
}
jsonBytes, err := json.Marshal(respBlk.Message)
if err != nil {
return nil, err
}
return &structs.GetBlockV2Response{
Version: version.String(version.Deneb),
ExecutionOptimistic: isOptimistic,
Data: &structs.SignedBlock{
Message: jsonBytes,
Signature: respBlk.Signature,
},
}, 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

@@ -265,8 +265,10 @@ func TestServer_ListBeaconBlocks_Genesis(t *testing.T) {
assert.NoError(t, err)
blinded, err := wrapped.ToBlinded()
assert.NoError(t, err)
blindedProto, err := blinded.PbBlindedBellatrixBlock()
pb, err := blinded.Proto()
assert.NoError(t, err)
blindedProto, ok := pb.(*ethpb.SignedBlindedBeaconBlockBellatrix)
require.Equal(t, true, ok)
blkContainer := &ethpb.BeaconBlockContainer{
Block: &ethpb.BeaconBlockContainer_BlindedBellatrixBlock{BlindedBellatrixBlock: blindedProto}}
runListBlocksGenesis(t, wrapped, blkContainer)
@@ -279,7 +281,10 @@ func TestServer_ListBeaconBlocks_Genesis(t *testing.T) {
assert.NoError(t, err)
blinded, err := wrapped.ToBlinded()
assert.NoError(t, err)
blindedProto, err := blinded.PbBlindedCapellaBlock()
pb, err := blinded.Proto()
assert.NoError(t, err)
blindedProto, ok := pb.(*ethpb.SignedBlindedBeaconBlockCapella)
require.Equal(t, true, ok)
assert.NoError(t, err)
blkContainer := &ethpb.BeaconBlockContainer{
Block: &ethpb.BeaconBlockContainer_BlindedCapellaBlock{BlindedCapellaBlock: blindedProto}}

View File

@@ -61,11 +61,11 @@ func BuildBlobSidecars(blk interfaces.SignedBeaconBlock, blobs [][]byte, kzgProo
if blk.Version() < version.Deneb {
return nil, nil // No blobs before deneb.
}
denebBlk, err := blk.PbDenebBlock()
commits, err := blk.Block().Body().BlobKzgCommitments()
if err != nil {
return nil, err
}
cLen := len(denebBlk.Block.Body.BlobKzgCommitments)
cLen := len(commits)
if cLen != len(blobs) || cLen != len(kzgProofs) {
return nil, errors.New("blob KZG commitments don't match number of blobs or KZG proofs")
}
@@ -83,7 +83,7 @@ func BuildBlobSidecars(blk interfaces.SignedBeaconBlock, blobs [][]byte, kzgProo
blobSidecars[i] = &ethpb.BlobSidecar{
Index: uint64(i),
Blob: blobs[i],
KzgCommitment: denebBlk.Block.Body.BlobKzgCommitments[i],
KzgCommitment: commits[i],
KzgProof: kzgProofs[i],
SignedBlockHeader: header,
CommitmentInclusionProof: proof,

View File

@@ -23,6 +23,23 @@ type executionPayload struct {
p *enginev1.ExecutionPayload
}
// NewWrappedExecutionData creates an appropriate execution payload wrapper based on the incoming type.
func NewWrappedExecutionData(v proto.Message, weiValue math.Wei) (interfaces.ExecutionData, error) {
if weiValue == nil {
weiValue = new(big.Int).SetInt64(0)
}
switch pbStruct := v.(type) {
case *enginev1.ExecutionPayload:
return WrappedExecutionPayload(pbStruct)
case *enginev1.ExecutionPayloadCapella:
return WrappedExecutionPayloadCapella(pbStruct, weiValue)
case *enginev1.ExecutionPayloadDeneb:
return WrappedExecutionPayloadDeneb(pbStruct, weiValue)
default:
return nil, ErrUnsupportedVersion
}
}
// 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}
@@ -172,26 +189,6 @@ func (e executionPayload) ExcessBlobGas() (uint64, error) {
return 0, consensus_types.ErrUnsupportedField
}
// PbBellatrix --
func (e executionPayload) PbBellatrix() (*enginev1.ExecutionPayload, error) {
return e.p, nil
}
// PbCapella --
func (executionPayload) PbCapella() (*enginev1.ExecutionPayloadCapella, error) {
return nil, consensus_types.ErrUnsupportedField
}
// PbDeneb --
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
@@ -368,26 +365,6 @@ 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
}
// PbCapella --
func (executionPayloadHeader) PbCapella() (*enginev1.ExecutionPayloadCapella, error) {
return nil, consensus_types.ErrUnsupportedField
}
// PbBellatrix --
func (executionPayloadHeader) PbBellatrix() (*enginev1.ExecutionPayload, error) {
return nil, consensus_types.ErrUnsupportedField
}
// ValueInWei --
func (executionPayloadHeader) ValueInWei() (math.Wei, error) {
return nil, consensus_types.ErrUnsupportedField
@@ -594,26 +571,6 @@ 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
}
// PbCapella --
func (e executionPayloadCapella) PbCapella() (*enginev1.ExecutionPayloadCapella, error) {
return e.p, nil
}
// PbBellatrix --
func (executionPayloadCapella) PbBellatrix() (*enginev1.ExecutionPayload, error) {
return nil, consensus_types.ErrUnsupportedField
}
// ValueInWei --
func (e executionPayloadCapella) ValueInWei() (math.Wei, error) {
return e.weiValue, nil
@@ -792,26 +749,6 @@ 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
}
// PbCapella --
func (executionPayloadHeaderCapella) PbCapella() (*enginev1.ExecutionPayloadCapella, error) {
return nil, consensus_types.ErrUnsupportedField
}
// PbBellatrix --
func (executionPayloadHeaderCapella) PbBellatrix() (*enginev1.ExecutionPayload, error) {
return nil, consensus_types.ErrUnsupportedField
}
// ValueInWei --
func (e executionPayloadHeaderCapella) ValueInWei() (math.Wei, error) {
return e.weiValue, nil
@@ -1221,26 +1158,6 @@ 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
}
// PbBellatrix --
func (executionPayloadHeaderDeneb) PbBellatrix() (*enginev1.ExecutionPayload, error) {
return nil, consensus_types.ErrUnsupportedField
}
// PbCapella --
func (executionPayloadHeaderDeneb) PbCapella() (*enginev1.ExecutionPayloadCapella, error) {
return nil, consensus_types.ErrUnsupportedField
}
// ValueInWei --
func (e executionPayloadHeaderDeneb) ValueInWei() (math.Wei, error) {
return e.weiValue, nil
@@ -1417,26 +1334,6 @@ func (e executionPayloadDeneb) ExcessBlobGas() (uint64, error) {
return e.p.ExcessBlobGas, nil
}
// PbBellatrix --
func (e executionPayloadDeneb) PbBellatrix() (*enginev1.ExecutionPayload, error) {
return nil, consensus_types.ErrUnsupportedField
}
// PbCapella --
func (e executionPayloadDeneb) PbCapella() (*enginev1.ExecutionPayloadCapella, error) {
return nil, consensus_types.ErrUnsupportedField
}
// PbDeneb --
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

View File

@@ -211,44 +211,6 @@ func TestWrapExecutionPayloadHeaderCapella_SSZ(t *testing.T) {
assert.NoError(t, payload.UnmarshalSSZ(encoded))
}
func Test_executionPayload_Pb(t *testing.T) {
payload := createWrappedPayload(t)
pb, err := payload.PbBellatrix()
require.NoError(t, err)
assert.DeepEqual(t, payload.Proto(), pb)
_, err = payload.PbCapella()
require.ErrorIs(t, err, consensus_types.ErrUnsupportedField)
}
func Test_executionPayloadHeader_Pb(t *testing.T) {
payload := createWrappedPayloadHeader(t)
_, err := payload.PbBellatrix()
require.ErrorIs(t, err, consensus_types.ErrUnsupportedField)
_, err = payload.PbCapella()
require.ErrorIs(t, err, consensus_types.ErrUnsupportedField)
}
func Test_executionPayloadCapella_Pb(t *testing.T) {
payload := createWrappedPayloadCapella(t)
pb, err := payload.PbCapella()
require.NoError(t, err)
assert.DeepEqual(t, payload.Proto(), pb)
_, err = payload.PbBellatrix()
require.ErrorIs(t, err, consensus_types.ErrUnsupportedField)
}
func Test_executionPayloadHeaderCapella_Pb(t *testing.T) {
payload := createWrappedPayloadHeaderCapella(t)
_, err := payload.PbBellatrix()
require.ErrorIs(t, err, consensus_types.ErrUnsupportedField)
_, err = payload.PbCapella()
require.ErrorIs(t, err, consensus_types.ErrUnsupportedField)
}
func TestWrapExecutionPayloadDeneb(t *testing.T) {
data := &enginev1.ExecutionPayloadDeneb{
ParentHash: []byte("parenthash"),

View File

@@ -150,102 +150,6 @@ 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, consensus_types.ErrNotSupported("PbPhase0Block", b.version)
}
pb, err := b.Proto()
if err != nil {
return nil, err
}
return pb.(*eth.SignedBeaconBlock), nil
}
// PbAltairBlock returns the underlying protobuf object.
func (b *SignedBeaconBlock) PbAltairBlock() (*eth.SignedBeaconBlockAltair, error) {
if b.version != version.Altair {
return nil, consensus_types.ErrNotSupported("PbAltairBlock", b.version)
}
pb, err := b.Proto()
if err != nil {
return nil, err
}
return pb.(*eth.SignedBeaconBlockAltair), nil
}
// PbBellatrixBlock returns the underlying protobuf object.
func (b *SignedBeaconBlock) PbBellatrixBlock() (*eth.SignedBeaconBlockBellatrix, error) {
if b.version != version.Bellatrix || b.IsBlinded() {
return nil, consensus_types.ErrNotSupported("PbBellatrixBlock", b.version)
}
pb, err := b.Proto()
if err != nil {
return nil, err
}
return pb.(*eth.SignedBeaconBlockBellatrix), nil
}
// PbBlindedBellatrixBlock returns the underlying protobuf object.
func (b *SignedBeaconBlock) PbBlindedBellatrixBlock() (*eth.SignedBlindedBeaconBlockBellatrix, error) {
if b.version != version.Bellatrix || !b.IsBlinded() {
return nil, consensus_types.ErrNotSupported("PbBlindedBellatrixBlock", b.version)
}
pb, err := b.Proto()
if err != nil {
return nil, err
}
return pb.(*eth.SignedBlindedBeaconBlockBellatrix), nil
}
// PbCapellaBlock returns the underlying protobuf object.
func (b *SignedBeaconBlock) PbCapellaBlock() (*eth.SignedBeaconBlockCapella, error) {
if b.version != version.Capella || b.IsBlinded() {
return nil, consensus_types.ErrNotSupported("PbCapellaBlock", b.version)
}
pb, err := b.Proto()
if err != nil {
return nil, err
}
return pb.(*eth.SignedBeaconBlockCapella), nil
}
// PbBlindedCapellaBlock returns the underlying protobuf object.
func (b *SignedBeaconBlock) PbBlindedCapellaBlock() (*eth.SignedBlindedBeaconBlockCapella, error) {
if b.version != version.Capella || !b.IsBlinded() {
return nil, consensus_types.ErrNotSupported("PbBlindedCapellaBlock", b.version)
}
pb, err := b.Proto()
if err != nil {
return nil, err
}
return pb.(*eth.SignedBlindedBeaconBlockCapella), nil
}
// PbDenebBlock returns the underlying protobuf object.
func (b *SignedBeaconBlock) PbDenebBlock() (*eth.SignedBeaconBlockDeneb, error) {
if b.version != version.Deneb || b.IsBlinded() {
return nil, consensus_types.ErrNotSupported("PbDenebBlock", b.version)
}
pb, err := b.Proto()
if err != nil {
return nil, err
}
return pb.(*eth.SignedBeaconBlockDeneb), nil
}
// PbBlindedDenebBlock returns the underlying protobuf object.
func (b *SignedBeaconBlock) PbBlindedDenebBlock() (*eth.SignedBlindedBeaconBlockDeneb, error) {
if b.version != version.Deneb || !b.IsBlinded() {
return nil, consensus_types.ErrNotSupported("PbBlindedDenebBlock", b.version)
}
pb, err := b.Proto()
if err != nil {
return nil, err
}
return pb.(*eth.SignedBlindedBeaconBlockDeneb), nil
}
// ToBlinded converts a non-blinded block to its blinded equivalent.
func (b *SignedBeaconBlock) ToBlinded() (interfaces.ReadOnlySignedBeaconBlock, error) {
if b.version < version.Bellatrix {

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

@@ -21,15 +21,7 @@ type ReadOnlySignedBeaconBlock interface {
Copy() (SignedBeaconBlock, error)
Proto() (proto.Message, error)
PbGenericBlock() (*ethpb.GenericSignedBeaconBlock, error)
PbPhase0Block() (*ethpb.SignedBeaconBlock, error)
PbAltairBlock() (*ethpb.SignedBeaconBlockAltair, error)
ToBlinded() (ReadOnlySignedBeaconBlock, error)
PbBellatrixBlock() (*ethpb.SignedBeaconBlockBellatrix, error)
PbBlindedBellatrixBlock() (*ethpb.SignedBlindedBeaconBlockBellatrix, error)
PbCapellaBlock() (*ethpb.SignedBeaconBlockCapella, error)
PbDenebBlock() (*ethpb.SignedBeaconBlockDeneb, error)
PbBlindedCapellaBlock() (*ethpb.SignedBlindedBeaconBlockCapella, error)
PbBlindedDenebBlock() (*ethpb.SignedBlindedBeaconBlockDeneb, error)
ssz.Marshaler
ssz.Unmarshaler
Version() int
@@ -131,10 +123,6 @@ type ExecutionData interface {
TransactionsRoot() ([]byte, error)
Withdrawals() ([]*enginev1.Withdrawal, error)
WithdrawalsRoot() ([]byte, error)
PbCapella() (*enginev1.ExecutionPayloadCapella, error)
PbBellatrix() (*enginev1.ExecutionPayload, error)
PbDeneb() (*enginev1.ExecutionPayloadDeneb, error)
PbElectra() (*enginev1.ExecutionPayloadElectra, error)
ValueInWei() (math.Wei, error)
ValueInGwei() (uint64, error)
DepositReceipts() ([]*enginev1.DepositReceipt, error)

View File

@@ -43,38 +43,6 @@ func (SignedBeaconBlock) Proto() (proto.Message, error) {
panic("implement me")
}
func (SignedBeaconBlock) PbPhase0Block() (*eth.SignedBeaconBlock, error) {
panic("implement me")
}
func (SignedBeaconBlock) PbAltairBlock() (*eth.SignedBeaconBlockAltair, error) {
panic("implement me")
}
func (SignedBeaconBlock) PbBellatrixBlock() (*eth.SignedBeaconBlockBellatrix, error) {
panic("implement me")
}
func (SignedBeaconBlock) PbBlindedBellatrixBlock() (*eth.SignedBlindedBeaconBlockBellatrix, error) {
panic("implement me")
}
func (SignedBeaconBlock) PbCapellaBlock() (*eth.SignedBeaconBlockCapella, error) {
panic("implement me")
}
func (SignedBeaconBlock) PbBlindedCapellaBlock() (*eth.SignedBlindedBeaconBlockCapella, error) {
panic("implement me")
}
func (SignedBeaconBlock) PbDenebBlock() (*eth.SignedBeaconBlockDeneb, error) {
panic("implement me")
}
func (SignedBeaconBlock) PbBlindedDenebBlock() (*eth.SignedBlindedBeaconBlockDeneb, error) {
panic("implement me")
}
func (SignedBeaconBlock) MarshalSSZTo(_ []byte) ([]byte, error) {
panic("implement me")
}

View File

@@ -7,7 +7,6 @@ import (
"errors"
"fmt"
"io"
"io/ioutil"
"math/big"
"net"
"net/http"
@@ -152,7 +151,7 @@ func New(opts ...Option) (*Builder, error) {
router.HandleFunc(registerPath, p.registerValidators)
router.HandleFunc(headerPath, p.handleHeaderRequest)
router.HandleFunc(blindedPath, p.handleBlindedBlock)
addr := fmt.Sprintf("%s:%d", p.cfg.builderHost, p.cfg.builderPort)
addr := net.JoinHostPort(p.cfg.builderHost, strconv.Itoa(p.cfg.builderPort))
srv := &http.Server{
Handler: mux,
Addr: addr,
@@ -268,7 +267,7 @@ func (p *Builder) handleEngineCalls(req, resp []byte) {
}
payloadID := [8]byte{}
status := ""
lastValHash := []byte{}
var lastValHash []byte
if result.Result.PayloadId != nil {
payloadID = *result.Result.PayloadId
}
@@ -280,7 +279,7 @@ func (p *Builder) handleEngineCalls(req, resp []byte) {
}
}
func (p *Builder) isBuilderCall(req *http.Request) bool {
func (*Builder) isBuilderCall(req *http.Request) bool {
return strings.Contains(req.URL.Path, "/eth/v1/builder/")
}
@@ -523,7 +522,7 @@ func (p *Builder) handleHeaderRequestDeneb(w http.ResponseWriter) {
return
}
val := builderAPI.Uint256{Int: v}
commitments := []hexutil.Bytes{}
var commitments []hexutil.Bytes
for _, c := range b.BlobsBundle.KzgCommitments {
copiedC := c
commitments = append(commitments, copiedC)
@@ -592,66 +591,14 @@ func (p *Builder) handleBlindedBlock(w http.ResponseWriter, req *http.Request) {
http.Error(w, "payload not found", http.StatusInternalServerError)
return
}
if payload, err := p.currPayload.PbDeneb(); err == nil {
convertedPayload, err := builderAPI.FromProtoDeneb(payload)
if err != nil {
p.cfg.logger.WithError(err).Error("Could not convert the payload")
http.Error(w, "payload not found", http.StatusInternalServerError)
return
}
execResp := &builderAPI.ExecPayloadResponseDeneb{
Version: "deneb",
Data: &builderAPI.ExecutionPayloadDenebAndBlobsBundle{
ExecutionPayload: &convertedPayload,
BlobsBundle: builderAPI.FromBundleProto(p.blobBundle),
},
}
err = json.NewEncoder(w).Encode(execResp)
if err != nil {
p.cfg.logger.WithError(err).Error("Could not encode full payload response")
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusOK)
return
}
if payload, err := p.currPayload.PbCapella(); err == nil {
convertedPayload, err := builderAPI.FromProtoCapella(payload)
if err != nil {
p.cfg.logger.WithError(err).Error("Could not convert the payload")
http.Error(w, "payload not found", http.StatusInternalServerError)
return
}
execResp := &builderAPI.ExecPayloadResponseCapella{
Version: "capella",
Data: convertedPayload,
}
err = json.NewEncoder(w).Encode(execResp)
if err != nil {
p.cfg.logger.WithError(err).Error("Could not encode full payload response")
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusOK)
return
}
bellPayload, err := p.currPayload.PbBellatrix()
if err != nil {
p.cfg.logger.WithError(err).Error("Could not retrieve the payload")
http.Error(w, "payload not found", http.StatusInternalServerError)
return
}
convertedPayload, err := builderAPI.FromProto(bellPayload)
resp, err := builderAPI.ExecutionPayloadResponseFromData(p.currPayload, p.blobBundle)
if err != nil {
p.cfg.logger.WithError(err).Error("Could not convert the payload")
http.Error(w, "payload not found", http.StatusInternalServerError)
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
execResp := &builderAPI.ExecPayloadResponse{
Version: "bellatrix",
Data: convertedPayload,
}
err = json.NewEncoder(w).Encode(execResp)
err = json.NewEncoder(w).Encode(resp)
if err != nil {
p.cfg.logger.WithError(err).Error("Could not encode full payload response")
http.Error(w, err.Error(), http.StatusInternalServerError)
@@ -747,7 +694,7 @@ func (p *Builder) sendHttpRequest(req *http.Request, requestBytes []byte) (*http
}
// Set the modified request as the proxy request body.
proxyReq.Body = ioutil.NopCloser(bytes.NewBuffer(requestBytes))
proxyReq.Body = io.NopCloser(bytes.NewBuffer(requestBytes))
// Required proxy headers for forwarding JSON-RPC requests to the execution client.
proxyReq.Header.Set("Host", req.Host)
@@ -768,14 +715,14 @@ func (p *Builder) sendHttpRequest(req *http.Request, requestBytes []byte) (*http
// Peek into the bytes of an HTTP request's body.
func parseRequestBytes(req *http.Request) ([]byte, error) {
requestBytes, err := ioutil.ReadAll(req.Body)
requestBytes, err := io.ReadAll(req.Body)
if err != nil {
return nil, err
}
if err = req.Body.Close(); err != nil {
return nil, err
}
req.Body = ioutil.NopCloser(bytes.NewBuffer(requestBytes))
req.Body = io.NopCloser(bytes.NewBuffer(requestBytes))
return requestBytes, nil
}

View File

@@ -128,11 +128,16 @@ func (v *validator) ProposeBlock(ctx context.Context, slot primitives.Slot, pubK
var genericSignedBlock *ethpb.GenericSignedBeaconBlock
if blk.Version() >= version.Deneb && !blk.IsBlinded() {
denebBlock, err := blk.PbDenebBlock()
pb, err := blk.Proto()
if err != nil {
log.WithError(err).Error("Failed to get deneb block")
return
}
denebBlock, ok := pb.(*ethpb.SignedBeaconBlockDeneb)
if !ok {
log.WithError(err).Error("Failed to get deneb block - assertion failure")
return
}
genericSignedBlock = &ethpb.GenericSignedBeaconBlock{
Block: &ethpb.GenericSignedBeaconBlock_Deneb{
Deneb: &ethpb.SignedBeaconBlockContentsDeneb{