Deneb produce blockv3 (#12708)

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
This commit is contained in:
james-prysm
2023-09-01 05:51:27 -05:00
committed by GitHub
parent 3a8be9fcf8
commit 9a7393a2e3
34 changed files with 8182 additions and 2520 deletions

View File

@@ -17,6 +17,7 @@ go_library(
"//consensus-types/interfaces:go_default_library",
"//consensus-types/primitives:go_default_library",
"//encoding/bytesutil:go_default_library",
"//math:go_default_library",
"//monitoring/tracing:go_default_library",
"//network:go_default_library",
"//network/authorization:go_default_library",
@@ -45,6 +46,7 @@ go_test(
"//consensus-types/blocks:go_default_library",
"//consensus-types/primitives:go_default_library",
"//encoding/bytesutil:go_default_library",
"//math:go_default_library",
"//proto/engine/v1:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
"//testing/assert:go_default_library",

View File

@@ -11,6 +11,7 @@ import (
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
types "github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
"github.com/prysmaticlabs/prysm/v4/math"
v1 "github.com/prysmaticlabs/prysm/v4/proto/engine/v1"
eth "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
)
@@ -104,14 +105,10 @@ type Uint256 struct {
*big.Int
}
func isValidUint256(bi *big.Int) bool {
return bi.Cmp(big.NewInt(0)) >= 0 && bi.BitLen() <= 256
}
func stringToUint256(s string) (Uint256, error) {
bi := new(big.Int)
_, ok := bi.SetString(s, 10)
if !ok || !isValidUint256(bi) {
if !ok || !math.IsValidUint256(bi) {
return Uint256{}, errors.Wrapf(errDecodeUint256, "value=%s", s)
}
return Uint256{Int: bi}, nil
@@ -120,7 +117,7 @@ func stringToUint256(s string) (Uint256, error) {
// sszBytesToUint256 creates a Uint256 from a ssz-style (little-endian byte slice) representation.
func sszBytesToUint256(b []byte) (Uint256, error) {
bi := bytesutil.LittleEndianBytesToBigInt(b)
if !isValidUint256(bi) {
if !math.IsValidUint256(bi) {
return Uint256{}, errors.Wrapf(errDecodeUint256, "value=%s", b)
}
return Uint256{Int: bi}, nil
@@ -128,7 +125,7 @@ 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 !isValidUint256(s.Int) {
if !math.IsValidUint256(s.Int) {
return []byte{}
}
return bytesutil.PadTo(bytesutil.ReverseByteOrder(s.Int.Bytes()), 32)
@@ -155,7 +152,7 @@ func (s *Uint256) UnmarshalText(t []byte) error {
if !ok {
return errors.Wrapf(errDecodeUint256, "value=%s", t)
}
if !isValidUint256(z) {
if !math.IsValidUint256(z) {
return errors.Wrapf(errDecodeUint256, "value=%s", t)
}
s.Int = z
@@ -175,7 +172,7 @@ func (s Uint256) MarshalJSON() ([]byte, error) {
// MarshalText returns a text byte representation of Uint256.
func (s Uint256) MarshalText() ([]byte, error) {
if !isValidUint256(s.Int) {
if !math.IsValidUint256(s.Int) {
return nil, errors.Wrapf(errInvalidUint256, "value=%s", s.Int)
}
return []byte(s.String()), nil

View File

@@ -15,6 +15,7 @@ import (
"github.com/golang/protobuf/proto"
"github.com/prysmaticlabs/go-bitfield"
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
"github.com/prysmaticlabs/prysm/v4/math"
v1 "github.com/prysmaticlabs/prysm/v4/proto/engine/v1"
eth "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v4/testing/assert"
@@ -1405,40 +1406,40 @@ func TestIsValidUint256(t *testing.T) {
_, ok = value.SetString("-10000000000000000000000000000000000000000000000000000000000000000", 16)
require.Equal(t, true, ok)
require.Equal(t, 257, value.BitLen())
require.Equal(t, false, isValidUint256(value))
require.Equal(t, false, math.IsValidUint256(value))
// negative uint256.max
_, ok = value.SetString("-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16)
require.Equal(t, true, ok)
require.Equal(t, 256, value.BitLen())
require.Equal(t, false, isValidUint256(value))
require.Equal(t, false, math.IsValidUint256(value))
// negative number
_, ok = value.SetString("-1", 16)
require.Equal(t, true, ok)
require.Equal(t, false, isValidUint256(value))
require.Equal(t, false, math.IsValidUint256(value))
// uint256.min
_, ok = value.SetString("0", 16)
require.Equal(t, true, ok)
require.Equal(t, true, isValidUint256(value))
require.Equal(t, true, math.IsValidUint256(value))
// positive number
_, ok = value.SetString("1", 16)
require.Equal(t, true, ok)
require.Equal(t, true, isValidUint256(value))
require.Equal(t, true, math.IsValidUint256(value))
// uint256.max
_, ok = value.SetString("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16)
require.Equal(t, true, ok)
require.Equal(t, 256, value.BitLen())
require.Equal(t, true, isValidUint256(value))
require.Equal(t, true, math.IsValidUint256(value))
// uint256.max + 1
_, ok = value.SetString("10000000000000000000000000000000000000000000000000000000000000000", 16)
require.Equal(t, true, ok)
require.Equal(t, 257, value.BitLen())
require.Equal(t, false, isValidUint256(value))
require.Equal(t, false, math.IsValidUint256(value))
}
func TestUint256Unmarshal(t *testing.T) {

View File

@@ -1,7 +1,9 @@
package api
const (
VersionHeader = "Eth-Consensus-Version"
JsonMediaType = "application/json"
OctetStreamMediaType = "application/octet-stream"
VersionHeader = "Eth-Consensus-Version"
ExecutionPayloadBlindedHeader = "Eth-Execution-Payload-Blinded"
ExecutionPayloadValueHeader = "Eth-Execution-Payload-Value"
JsonMediaType = "application/json"
OctetStreamMediaType = "application/octet-stream"
)

View File

@@ -117,6 +117,8 @@ go_test(
"//beacon-chain/p2p/testing:go_default_library",
"//beacon-chain/rpc/apimiddleware:go_default_library",
"//beacon-chain/rpc/eth/helpers:go_default_library",
"//beacon-chain/rpc/eth/shared:go_default_library",
"//beacon-chain/rpc/eth/shared/testing:go_default_library",
"//beacon-chain/rpc/lookup:go_default_library",
"//beacon-chain/rpc/prysm/v1alpha1/validator:go_default_library",
"//beacon-chain/rpc/testutil:go_default_library",

View File

@@ -46,18 +46,20 @@ const (
// a `SignedBeaconBlock`. The broadcast behaviour may be adjusted via the `broadcast_validation`
// query parameter.
func (bs *Server) PublishBlindedBlockV2(w http.ResponseWriter, r *http.Request) {
ctx, span := trace.StartSpan(r.Context(), "beacon.PublishBlindedBlockV2")
defer span.End()
if shared.IsSyncing(r.Context(), w, bs.SyncChecker, bs.HeadFetcher, bs.TimeFetcher, bs.OptimisticModeFetcher) {
return
}
isSSZ, err := http2.SszRequested(r)
if isSSZ && err == nil {
publishBlindedBlockV2SSZ(bs, w, r)
publishBlindedBlockV2SSZ(ctx, bs, w, r)
} else {
publishBlindedBlockV2(bs, w, r)
publishBlindedBlockV2(ctx, bs, w, r)
}
}
func publishBlindedBlockV2SSZ(bs *Server, w http.ResponseWriter, r *http.Request) {
func publishBlindedBlockV2SSZ(ctx context.Context, bs *Server, w http.ResponseWriter, r *http.Request) {
body, err := io.ReadAll(r.Body)
if err != nil {
errJson := &http2.DefaultErrorJson{
@@ -83,7 +85,7 @@ func publishBlindedBlockV2SSZ(bs *Server, w http.ResponseWriter, r *http.Request
BlindedDeneb: v1block,
},
}
if err = bs.validateBroadcast(r, genericBlock); err != nil {
if err = bs.validateBroadcast(ctx, r, genericBlock); err != nil {
errJson := &http2.DefaultErrorJson{
Message: err.Error(),
Code: http.StatusBadRequest,
@@ -91,7 +93,7 @@ func publishBlindedBlockV2SSZ(bs *Server, w http.ResponseWriter, r *http.Request
http2.WriteError(w, errJson)
return
}
bs.proposeBlock(r.Context(), w, genericBlock)
bs.proposeBlock(ctx, w, genericBlock)
return
}
capellaBlock := &ethpbv2.SignedBlindedBeaconBlockCapella{}
@@ -110,7 +112,7 @@ func publishBlindedBlockV2SSZ(bs *Server, w http.ResponseWriter, r *http.Request
BlindedCapella: v1block,
},
}
if err = bs.validateBroadcast(r, genericBlock); err != nil {
if err = bs.validateBroadcast(ctx, r, genericBlock); err != nil {
errJson := &http2.DefaultErrorJson{
Message: err.Error(),
Code: http.StatusBadRequest,
@@ -118,7 +120,7 @@ func publishBlindedBlockV2SSZ(bs *Server, w http.ResponseWriter, r *http.Request
http2.WriteError(w, errJson)
return
}
bs.proposeBlock(r.Context(), w, genericBlock)
bs.proposeBlock(ctx, w, genericBlock)
return
}
bellatrixBlock := &ethpbv2.SignedBlindedBeaconBlockBellatrix{}
@@ -137,7 +139,7 @@ func publishBlindedBlockV2SSZ(bs *Server, w http.ResponseWriter, r *http.Request
BlindedBellatrix: v1block,
},
}
if err = bs.validateBroadcast(r, genericBlock); err != nil {
if err = bs.validateBroadcast(ctx, r, genericBlock); err != nil {
errJson := &http2.DefaultErrorJson{
Message: err.Error(),
Code: http.StatusBadRequest,
@@ -145,7 +147,7 @@ func publishBlindedBlockV2SSZ(bs *Server, w http.ResponseWriter, r *http.Request
http2.WriteError(w, errJson)
return
}
bs.proposeBlock(r.Context(), w, genericBlock)
bs.proposeBlock(ctx, w, genericBlock)
return
}
@@ -166,7 +168,7 @@ func publishBlindedBlockV2SSZ(bs *Server, w http.ResponseWriter, r *http.Request
Altair: v1block,
},
}
if err = bs.validateBroadcast(r, genericBlock); err != nil {
if err = bs.validateBroadcast(ctx, r, genericBlock); err != nil {
errJson := &http2.DefaultErrorJson{
Message: err.Error(),
Code: http.StatusBadRequest,
@@ -174,7 +176,7 @@ func publishBlindedBlockV2SSZ(bs *Server, w http.ResponseWriter, r *http.Request
http2.WriteError(w, errJson)
return
}
bs.proposeBlock(r.Context(), w, genericBlock)
bs.proposeBlock(ctx, w, genericBlock)
return
}
phase0Block := &ethpbv1.SignedBeaconBlock{}
@@ -193,7 +195,7 @@ func publishBlindedBlockV2SSZ(bs *Server, w http.ResponseWriter, r *http.Request
Phase0: v1block,
},
}
if err = bs.validateBroadcast(r, genericBlock); err != nil {
if err = bs.validateBroadcast(ctx, r, genericBlock); err != nil {
errJson := &http2.DefaultErrorJson{
Message: err.Error(),
Code: http.StatusBadRequest,
@@ -201,7 +203,7 @@ func publishBlindedBlockV2SSZ(bs *Server, w http.ResponseWriter, r *http.Request
http2.WriteError(w, errJson)
return
}
bs.proposeBlock(r.Context(), w, genericBlock)
bs.proposeBlock(ctx, w, genericBlock)
return
}
errJson := &http2.DefaultErrorJson{
@@ -211,7 +213,7 @@ func publishBlindedBlockV2SSZ(bs *Server, w http.ResponseWriter, r *http.Request
http2.WriteError(w, errJson)
}
func publishBlindedBlockV2(bs *Server, w http.ResponseWriter, r *http.Request) {
func publishBlindedBlockV2(ctx context.Context, bs *Server, w http.ResponseWriter, r *http.Request) {
validate := validator.New()
body, err := io.ReadAll(r.Body)
if err != nil {
@@ -222,7 +224,7 @@ func publishBlindedBlockV2(bs *Server, w http.ResponseWriter, r *http.Request) {
http2.WriteError(w, errJson)
return
}
var denebBlockContents *SignedBlindedBeaconBlockContentsDeneb
var denebBlockContents *shared.SignedBlindedBeaconBlockContentsDeneb
if err = unmarshalStrict(body, &denebBlockContents); err == nil {
if err = validate.Struct(denebBlockContents); err == nil {
consensusBlock, err := denebBlockContents.ToGeneric()
@@ -234,7 +236,7 @@ func publishBlindedBlockV2(bs *Server, w http.ResponseWriter, r *http.Request) {
http2.WriteError(w, errJson)
return
}
if err = bs.validateBroadcast(r, consensusBlock); err != nil {
if err = bs.validateBroadcast(ctx, r, consensusBlock); err != nil {
errJson := &http2.DefaultErrorJson{
Message: err.Error(),
Code: http.StatusBadRequest,
@@ -242,12 +244,12 @@ func publishBlindedBlockV2(bs *Server, w http.ResponseWriter, r *http.Request) {
http2.WriteError(w, errJson)
return
}
bs.proposeBlock(r.Context(), w, consensusBlock)
bs.proposeBlock(ctx, w, consensusBlock)
return
}
}
var capellaBlock *SignedBlindedBeaconBlockCapella
var capellaBlock *shared.SignedBlindedBeaconBlockCapella
if err = unmarshalStrict(body, &capellaBlock); err == nil {
if err = validate.Struct(capellaBlock); err == nil {
consensusBlock, err := capellaBlock.ToGeneric()
@@ -259,7 +261,7 @@ func publishBlindedBlockV2(bs *Server, w http.ResponseWriter, r *http.Request) {
http2.WriteError(w, errJson)
return
}
if err = bs.validateBroadcast(r, consensusBlock); err != nil {
if err = bs.validateBroadcast(ctx, r, consensusBlock); err != nil {
errJson := &http2.DefaultErrorJson{
Message: err.Error(),
Code: http.StatusBadRequest,
@@ -267,12 +269,12 @@ func publishBlindedBlockV2(bs *Server, w http.ResponseWriter, r *http.Request) {
http2.WriteError(w, errJson)
return
}
bs.proposeBlock(r.Context(), w, consensusBlock)
bs.proposeBlock(ctx, w, consensusBlock)
return
}
}
var bellatrixBlock *SignedBlindedBeaconBlockBellatrix
var bellatrixBlock *shared.SignedBlindedBeaconBlockBellatrix
if err = unmarshalStrict(body, &bellatrixBlock); err == nil {
if err = validate.Struct(bellatrixBlock); err == nil {
consensusBlock, err := bellatrixBlock.ToGeneric()
@@ -284,7 +286,7 @@ func publishBlindedBlockV2(bs *Server, w http.ResponseWriter, r *http.Request) {
http2.WriteError(w, errJson)
return
}
if err = bs.validateBroadcast(r, consensusBlock); err != nil {
if err = bs.validateBroadcast(ctx, r, consensusBlock); err != nil {
errJson := &http2.DefaultErrorJson{
Message: err.Error(),
Code: http.StatusBadRequest,
@@ -292,11 +294,11 @@ func publishBlindedBlockV2(bs *Server, w http.ResponseWriter, r *http.Request) {
http2.WriteError(w, errJson)
return
}
bs.proposeBlock(r.Context(), w, consensusBlock)
bs.proposeBlock(ctx, w, consensusBlock)
return
}
}
var altairBlock *SignedBeaconBlockAltair
var altairBlock *shared.SignedBeaconBlockAltair
if err = unmarshalStrict(body, &altairBlock); err == nil {
if err = validate.Struct(altairBlock); err == nil {
consensusBlock, err := altairBlock.ToGeneric()
@@ -308,7 +310,7 @@ func publishBlindedBlockV2(bs *Server, w http.ResponseWriter, r *http.Request) {
http2.WriteError(w, errJson)
return
}
if err = bs.validateBroadcast(r, consensusBlock); err != nil {
if err = bs.validateBroadcast(ctx, r, consensusBlock); err != nil {
errJson := &http2.DefaultErrorJson{
Message: err.Error(),
Code: http.StatusBadRequest,
@@ -316,11 +318,11 @@ func publishBlindedBlockV2(bs *Server, w http.ResponseWriter, r *http.Request) {
http2.WriteError(w, errJson)
return
}
bs.proposeBlock(r.Context(), w, consensusBlock)
bs.proposeBlock(ctx, w, consensusBlock)
return
}
}
var phase0Block *SignedBeaconBlock
var phase0Block *shared.SignedBeaconBlock
if err = unmarshalStrict(body, &phase0Block); err == nil {
if err = validate.Struct(phase0Block); err == nil {
consensusBlock, err := phase0Block.ToGeneric()
@@ -332,7 +334,7 @@ func publishBlindedBlockV2(bs *Server, w http.ResponseWriter, r *http.Request) {
http2.WriteError(w, errJson)
return
}
if err = bs.validateBroadcast(r, consensusBlock); err != nil {
if err = bs.validateBroadcast(ctx, r, consensusBlock); err != nil {
errJson := &http2.DefaultErrorJson{
Message: err.Error(),
Code: http.StatusBadRequest,
@@ -340,7 +342,7 @@ func publishBlindedBlockV2(bs *Server, w http.ResponseWriter, r *http.Request) {
http2.WriteError(w, errJson)
return
}
bs.proposeBlock(r.Context(), w, consensusBlock)
bs.proposeBlock(ctx, w, consensusBlock)
return
}
}
@@ -361,18 +363,20 @@ func publishBlindedBlockV2(bs *Server, w http.ResponseWriter, r *http.Request) {
// successfully broadcast but failed integration. The broadcast behaviour may be adjusted via the
// `broadcast_validation` query parameter.
func (bs *Server) PublishBlockV2(w http.ResponseWriter, r *http.Request) {
ctx, span := trace.StartSpan(r.Context(), "beacon.PublishBlockV2")
defer span.End()
if shared.IsSyncing(r.Context(), w, bs.SyncChecker, bs.HeadFetcher, bs.TimeFetcher, bs.OptimisticModeFetcher) {
return
}
isSSZ, err := http2.SszRequested(r)
if isSSZ && err == nil {
publishBlockV2SSZ(bs, w, r)
publishBlockV2SSZ(ctx, bs, w, r)
} else {
publishBlockV2(bs, w, r)
publishBlockV2(ctx, bs, w, r)
}
}
func publishBlockV2SSZ(bs *Server, w http.ResponseWriter, r *http.Request) {
func publishBlockV2SSZ(ctx context.Context, bs *Server, w http.ResponseWriter, r *http.Request) {
body, err := io.ReadAll(r.Body)
if err != nil {
errJson := &http2.DefaultErrorJson{
@@ -398,7 +402,7 @@ func publishBlockV2SSZ(bs *Server, w http.ResponseWriter, r *http.Request) {
Deneb: v1BlockContents,
},
}
if err = bs.validateBroadcast(r, genericBlock); err != nil {
if err = bs.validateBroadcast(ctx, r, genericBlock); err != nil {
errJson := &http2.DefaultErrorJson{
Message: err.Error(),
Code: http.StatusBadRequest,
@@ -406,7 +410,7 @@ func publishBlockV2SSZ(bs *Server, w http.ResponseWriter, r *http.Request) {
http2.WriteError(w, errJson)
return
}
bs.proposeBlock(r.Context(), w, genericBlock)
bs.proposeBlock(ctx, w, genericBlock)
return
}
capellaBlock := &ethpbv2.SignedBeaconBlockCapella{}
@@ -425,7 +429,7 @@ func publishBlockV2SSZ(bs *Server, w http.ResponseWriter, r *http.Request) {
Capella: v1block,
},
}
if err = bs.validateBroadcast(r, genericBlock); err != nil {
if err = bs.validateBroadcast(ctx, r, genericBlock); err != nil {
errJson := &http2.DefaultErrorJson{
Message: err.Error(),
Code: http.StatusBadRequest,
@@ -433,7 +437,7 @@ func publishBlockV2SSZ(bs *Server, w http.ResponseWriter, r *http.Request) {
http2.WriteError(w, errJson)
return
}
bs.proposeBlock(r.Context(), w, genericBlock)
bs.proposeBlock(ctx, w, genericBlock)
return
}
bellatrixBlock := &ethpbv2.SignedBeaconBlockBellatrix{}
@@ -452,7 +456,7 @@ func publishBlockV2SSZ(bs *Server, w http.ResponseWriter, r *http.Request) {
Bellatrix: v1block,
},
}
if err = bs.validateBroadcast(r, genericBlock); err != nil {
if err = bs.validateBroadcast(ctx, r, genericBlock); err != nil {
errJson := &http2.DefaultErrorJson{
Message: err.Error(),
Code: http.StatusBadRequest,
@@ -460,7 +464,7 @@ func publishBlockV2SSZ(bs *Server, w http.ResponseWriter, r *http.Request) {
http2.WriteError(w, errJson)
return
}
bs.proposeBlock(r.Context(), w, genericBlock)
bs.proposeBlock(ctx, w, genericBlock)
return
}
altairBlock := &ethpbv2.SignedBeaconBlockAltair{}
@@ -479,7 +483,7 @@ func publishBlockV2SSZ(bs *Server, w http.ResponseWriter, r *http.Request) {
Altair: v1block,
},
}
if err = bs.validateBroadcast(r, genericBlock); err != nil {
if err = bs.validateBroadcast(ctx, r, genericBlock); err != nil {
errJson := &http2.DefaultErrorJson{
Message: err.Error(),
Code: http.StatusBadRequest,
@@ -487,7 +491,7 @@ func publishBlockV2SSZ(bs *Server, w http.ResponseWriter, r *http.Request) {
http2.WriteError(w, errJson)
return
}
bs.proposeBlock(r.Context(), w, genericBlock)
bs.proposeBlock(ctx, w, genericBlock)
return
}
phase0Block := &ethpbv1.SignedBeaconBlock{}
@@ -506,7 +510,7 @@ func publishBlockV2SSZ(bs *Server, w http.ResponseWriter, r *http.Request) {
Phase0: v1block,
},
}
if err = bs.validateBroadcast(r, genericBlock); err != nil {
if err = bs.validateBroadcast(ctx, r, genericBlock); err != nil {
errJson := &http2.DefaultErrorJson{
Message: err.Error(),
Code: http.StatusBadRequest,
@@ -514,7 +518,7 @@ func publishBlockV2SSZ(bs *Server, w http.ResponseWriter, r *http.Request) {
http2.WriteError(w, errJson)
return
}
bs.proposeBlock(r.Context(), w, genericBlock)
bs.proposeBlock(ctx, w, genericBlock)
return
}
errJson := &http2.DefaultErrorJson{
@@ -524,7 +528,7 @@ func publishBlockV2SSZ(bs *Server, w http.ResponseWriter, r *http.Request) {
http2.WriteError(w, errJson)
}
func publishBlockV2(bs *Server, w http.ResponseWriter, r *http.Request) {
func publishBlockV2(ctx context.Context, bs *Server, w http.ResponseWriter, r *http.Request) {
validate := validator.New()
body, err := io.ReadAll(r.Body)
if err != nil {
@@ -535,7 +539,7 @@ func publishBlockV2(bs *Server, w http.ResponseWriter, r *http.Request) {
http2.WriteError(w, errJson)
return
}
var denebBlockContents *SignedBeaconBlockContentsDeneb
var denebBlockContents *shared.SignedBeaconBlockContentsDeneb
if err = unmarshalStrict(body, &denebBlockContents); err == nil {
if err = validate.Struct(denebBlockContents); err == nil {
consensusBlock, err := denebBlockContents.ToGeneric()
@@ -547,7 +551,7 @@ func publishBlockV2(bs *Server, w http.ResponseWriter, r *http.Request) {
http2.WriteError(w, errJson)
return
}
if err = bs.validateBroadcast(r, consensusBlock); err != nil {
if err = bs.validateBroadcast(ctx, r, consensusBlock); err != nil {
errJson := &http2.DefaultErrorJson{
Message: err.Error(),
Code: http.StatusBadRequest,
@@ -555,11 +559,11 @@ func publishBlockV2(bs *Server, w http.ResponseWriter, r *http.Request) {
http2.WriteError(w, errJson)
return
}
bs.proposeBlock(r.Context(), w, consensusBlock)
bs.proposeBlock(ctx, w, consensusBlock)
return
}
}
var capellaBlock *SignedBeaconBlockCapella
var capellaBlock *shared.SignedBeaconBlockCapella
if err = unmarshalStrict(body, &capellaBlock); err == nil {
if err = validate.Struct(capellaBlock); err == nil {
consensusBlock, err := capellaBlock.ToGeneric()
@@ -571,7 +575,7 @@ func publishBlockV2(bs *Server, w http.ResponseWriter, r *http.Request) {
http2.WriteError(w, errJson)
return
}
if err = bs.validateBroadcast(r, consensusBlock); err != nil {
if err = bs.validateBroadcast(ctx, r, consensusBlock); err != nil {
errJson := &http2.DefaultErrorJson{
Message: err.Error(),
Code: http.StatusBadRequest,
@@ -579,11 +583,11 @@ func publishBlockV2(bs *Server, w http.ResponseWriter, r *http.Request) {
http2.WriteError(w, errJson)
return
}
bs.proposeBlock(r.Context(), w, consensusBlock)
bs.proposeBlock(ctx, w, consensusBlock)
return
}
}
var bellatrixBlock *SignedBeaconBlockBellatrix
var bellatrixBlock *shared.SignedBeaconBlockBellatrix
if err = unmarshalStrict(body, &bellatrixBlock); err == nil {
if err = validate.Struct(bellatrixBlock); err == nil {
consensusBlock, err := bellatrixBlock.ToGeneric()
@@ -595,7 +599,7 @@ func publishBlockV2(bs *Server, w http.ResponseWriter, r *http.Request) {
http2.WriteError(w, errJson)
return
}
if err = bs.validateBroadcast(r, consensusBlock); err != nil {
if err = bs.validateBroadcast(ctx, r, consensusBlock); err != nil {
errJson := &http2.DefaultErrorJson{
Message: err.Error(),
Code: http.StatusBadRequest,
@@ -603,11 +607,11 @@ func publishBlockV2(bs *Server, w http.ResponseWriter, r *http.Request) {
http2.WriteError(w, errJson)
return
}
bs.proposeBlock(r.Context(), w, consensusBlock)
bs.proposeBlock(ctx, w, consensusBlock)
return
}
}
var altairBlock *SignedBeaconBlockAltair
var altairBlock *shared.SignedBeaconBlockAltair
if err = unmarshalStrict(body, &altairBlock); err == nil {
if err = validate.Struct(altairBlock); err == nil {
consensusBlock, err := altairBlock.ToGeneric()
@@ -619,7 +623,7 @@ func publishBlockV2(bs *Server, w http.ResponseWriter, r *http.Request) {
http2.WriteError(w, errJson)
return
}
if err = bs.validateBroadcast(r, consensusBlock); err != nil {
if err = bs.validateBroadcast(ctx, r, consensusBlock); err != nil {
errJson := &http2.DefaultErrorJson{
Message: err.Error(),
Code: http.StatusBadRequest,
@@ -627,11 +631,11 @@ func publishBlockV2(bs *Server, w http.ResponseWriter, r *http.Request) {
http2.WriteError(w, errJson)
return
}
bs.proposeBlock(r.Context(), w, consensusBlock)
bs.proposeBlock(ctx, w, consensusBlock)
return
}
}
var phase0Block *SignedBeaconBlock
var phase0Block *shared.SignedBeaconBlock
if err = unmarshalStrict(body, &phase0Block); err == nil {
if err = validate.Struct(phase0Block); err == nil {
consensusBlock, err := phase0Block.ToGeneric()
@@ -643,7 +647,7 @@ func publishBlockV2(bs *Server, w http.ResponseWriter, r *http.Request) {
http2.WriteError(w, errJson)
return
}
if err = bs.validateBroadcast(r, consensusBlock); err != nil {
if err = bs.validateBroadcast(ctx, r, consensusBlock); err != nil {
errJson := &http2.DefaultErrorJson{
Message: err.Error(),
Code: http.StatusBadRequest,
@@ -651,7 +655,7 @@ func publishBlockV2(bs *Server, w http.ResponseWriter, r *http.Request) {
http2.WriteError(w, errJson)
return
}
bs.proposeBlock(r.Context(), w, consensusBlock)
bs.proposeBlock(ctx, w, consensusBlock)
return
}
}
@@ -681,14 +685,14 @@ func unmarshalStrict(data []byte, v interface{}) error {
return dec.Decode(v)
}
func (bs *Server) validateBroadcast(r *http.Request, blk *eth.GenericSignedBeaconBlock) error {
func (bs *Server) validateBroadcast(ctx context.Context, r *http.Request, blk *eth.GenericSignedBeaconBlock) error {
switch r.URL.Query().Get(broadcastValidationQueryParam) {
case broadcastValidationConsensus:
b, err := blocks.NewSignedBeaconBlock(blk.Block)
if err != nil {
return errors.Wrapf(err, "could not create signed beacon block")
}
if err = bs.validateConsensus(r.Context(), b); err != nil {
if err = bs.validateConsensus(ctx, b); err != nil {
return errors.Wrap(err, "consensus validation failed")
}
case broadcastValidationConsensusAndEquivocation:

File diff suppressed because it is too large Load Diff

View File

@@ -6,6 +6,8 @@ go_library(
"errors.go",
"request.go",
"structs.go",
"structs_blocks.go",
"structs_blocks_conversions.go",
],
importpath = "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/shared",
visibility = ["//visibility:public"],
@@ -15,9 +17,14 @@ go_library(
"//config/fieldparams:go_default_library",
"//consensus-types/primitives:go_default_library",
"//consensus-types/validator:go_default_library",
"//encoding/bytesutil:go_default_library",
"//math:go_default_library",
"//network/http:go_default_library",
"//proto/engine/v1:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
"@com_github_ethereum_go_ethereum//common:go_default_library",
"@com_github_ethereum_go_ethereum//common/hexutil:go_default_library",
"@com_github_pkg_errors//:go_default_library",
],
)

View File

@@ -8,6 +8,8 @@ import (
"strconv"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/blockchain"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/sync"
http2 "github.com/prysmaticlabs/prysm/v4/network/http"
@@ -140,3 +142,39 @@ func IsOptimistic(
http2.WriteError(w, errJson)
return true, nil
}
// DecodeHexWithLength takes a string and a length in bytes,
// and validates whether the string is a hex and has the correct length.
func DecodeHexWithLength(s string, length int) ([]byte, error) {
bytes, err := hexutil.Decode(s)
if err != nil {
return nil, errors.Wrap(err, fmt.Sprintf("%s is not a valid hex", s))
}
if len(bytes) != length {
return nil, fmt.Errorf("%s is not length %d bytes", s, length)
}
return bytes, nil
}
// DecodeHexWithMaxLength takes a string and a length in bytes,
// and validates whether the string is a hex and has the correct length.
func DecodeHexWithMaxLength(s string, maxLength int) ([]byte, error) {
bytes, err := hexutil.Decode(s)
if err != nil {
return nil, errors.Wrap(err, fmt.Sprintf("%s is not a valid hex", s))
}
err = VerifyMaxLength(bytes, maxLength)
if err != nil {
return nil, errors.Wrap(err, fmt.Sprintf("length of %s exceeds max of %d bytes", s, maxLength))
}
return bytes, nil
}
// VerifyMaxLength takes a slice and a maximum length and validates the length.
func VerifyMaxLength[T any](v []T, max int) error {
l := len(v)
if l > max {
return fmt.Errorf("length of %d exceeds max of %d", l, max)
}
return nil
}

View File

@@ -0,0 +1,444 @@
package shared
type SignedBeaconBlock struct {
Message *BeaconBlock `json:"message" validate:"required"`
Signature string `json:"signature" validate:"required"`
}
type BeaconBlock struct {
Slot string `json:"slot" validate:"required"`
ProposerIndex string `json:"proposer_index" validate:"required"`
ParentRoot string `json:"parent_root" validate:"required"`
StateRoot string `json:"state_root" validate:"required"`
Body *BeaconBlockBody `json:"body" validate:"required"`
}
type BeaconBlockBody struct {
RandaoReveal string `json:"randao_reveal" validate:"required"`
Eth1Data *Eth1Data `json:"eth1_data" validate:"required"`
Graffiti string `json:"graffiti" validate:"required"`
ProposerSlashings []*ProposerSlashing `json:"proposer_slashings" validate:"required"`
AttesterSlashings []*AttesterSlashing `json:"attester_slashings" validate:"required"`
Attestations []*Attestation `json:"attestations" validate:"required"`
Deposits []*Deposit `json:"deposits" validate:"required"`
VoluntaryExits []*SignedVoluntaryExit `json:"voluntary_exits" validate:"required"`
}
type SignedBeaconBlockAltair struct {
Message *BeaconBlockAltair `json:"message" validate:"required"`
Signature string `json:"signature" validate:"required"`
}
type BeaconBlockAltair struct {
Slot string `json:"slot" validate:"required"`
ProposerIndex string `json:"proposer_index" validate:"required"`
ParentRoot string `json:"parent_root" validate:"required"`
StateRoot string `json:"state_root" validate:"required"`
Body *BeaconBlockBodyAltair `json:"body" validate:"required"`
}
type BeaconBlockBodyAltair struct {
RandaoReveal string `json:"randao_reveal" validate:"required"`
Eth1Data *Eth1Data `json:"eth1_data" validate:"required"`
Graffiti string `json:"graffiti" validate:"required"`
ProposerSlashings []*ProposerSlashing `json:"proposer_slashings" validate:"required,dive"`
AttesterSlashings []*AttesterSlashing `json:"attester_slashings" validate:"required,dive"`
Attestations []*Attestation `json:"attestations" validate:"required,dive"`
Deposits []*Deposit `json:"deposits" validate:"required,dive"`
VoluntaryExits []*SignedVoluntaryExit `json:"voluntary_exits" validate:"required,dive"`
SyncAggregate *SyncAggregate `json:"sync_aggregate" validate:"required"`
}
type SignedBeaconBlockBellatrix struct {
Message *BeaconBlockBellatrix `json:"message" validate:"required"`
Signature string `json:"signature" validate:"required"`
}
type BeaconBlockBellatrix struct {
Slot string `json:"slot" validate:"required"`
ProposerIndex string `json:"proposer_index" validate:"required"`
ParentRoot string `json:"parent_root" validate:"required"`
StateRoot string `json:"state_root" validate:"required"`
Body *BeaconBlockBodyBellatrix `json:"body" validate:"required"`
}
type BeaconBlockBodyBellatrix struct {
RandaoReveal string `json:"randao_reveal" validate:"required"`
Eth1Data *Eth1Data `json:"eth1_data" validate:"required"`
Graffiti string `json:"graffiti" validate:"required"`
ProposerSlashings []*ProposerSlashing `json:"proposer_slashings" validate:"required,dive"`
AttesterSlashings []*AttesterSlashing `json:"attester_slashings" validate:"required,dive"`
Attestations []*Attestation `json:"attestations" validate:"required,dive"`
Deposits []*Deposit `json:"deposits" validate:"required,dive"`
VoluntaryExits []*SignedVoluntaryExit `json:"voluntary_exits" validate:"required,dive"`
SyncAggregate *SyncAggregate `json:"sync_aggregate" validate:"required"`
ExecutionPayload *ExecutionPayload `json:"execution_payload" validate:"required"`
}
type SignedBlindedBeaconBlockBellatrix struct {
Message *BlindedBeaconBlockBellatrix `json:"message" validate:"required"`
Signature string `json:"signature" validate:"required"`
}
type BlindedBeaconBlockBellatrix struct {
Slot string `json:"slot" validate:"required"`
ProposerIndex string `json:"proposer_index" validate:"required"`
ParentRoot string `json:"parent_root" validate:"required"`
StateRoot string `json:"state_root" validate:"required"`
Body *BlindedBeaconBlockBodyBellatrix `json:"body" validate:"required"`
}
type BlindedBeaconBlockBodyBellatrix struct {
RandaoReveal string `json:"randao_reveal" validate:"required"`
Eth1Data *Eth1Data `json:"eth1_data" validate:"required"`
Graffiti string `json:"graffiti" validate:"required"`
ProposerSlashings []*ProposerSlashing `json:"proposer_slashings" validate:"required,dive"`
AttesterSlashings []*AttesterSlashing `json:"attester_slashings" validate:"required,dive"`
Attestations []*Attestation `json:"attestations" validate:"required,dive"`
Deposits []*Deposit `json:"deposits" validate:"required,dive"`
VoluntaryExits []*SignedVoluntaryExit `json:"voluntary_exits" validate:"required,dive"`
SyncAggregate *SyncAggregate `json:"sync_aggregate" validate:"required"`
ExecutionPayloadHeader *ExecutionPayloadHeader `json:"execution_payload_header" validate:"required"`
}
type SignedBeaconBlockCapella struct {
Message *BeaconBlockCapella `json:"message" validate:"required"`
Signature string `json:"signature" validate:"required"`
}
type BeaconBlockCapella struct {
Slot string `json:"slot" validate:"required"`
ProposerIndex string `json:"proposer_index" validate:"required"`
ParentRoot string `json:"parent_root" validate:"required"`
StateRoot string `json:"state_root" validate:"required"`
Body *BeaconBlockBodyCapella `json:"body" validate:"required"`
}
type BeaconBlockBodyCapella struct {
RandaoReveal string `json:"randao_reveal" validate:"required"`
Eth1Data *Eth1Data `json:"eth1_data" validate:"required"`
Graffiti string `json:"graffiti" validate:"required"`
ProposerSlashings []*ProposerSlashing `json:"proposer_slashings" validate:"required,dive"`
AttesterSlashings []*AttesterSlashing `json:"attester_slashings" validate:"required,dive"`
Attestations []*Attestation `json:"attestations" validate:"required,dive"`
Deposits []*Deposit `json:"deposits" validate:"required,dive"`
VoluntaryExits []*SignedVoluntaryExit `json:"voluntary_exits" validate:"required,dive"`
SyncAggregate *SyncAggregate `json:"sync_aggregate" validate:"required"`
ExecutionPayload *ExecutionPayloadCapella `json:"execution_payload" validate:"required"`
BlsToExecutionChanges []*SignedBlsToExecutionChange `json:"bls_to_execution_changes" validate:"required,dive"`
}
type SignedBlindedBeaconBlockCapella struct {
Message *BlindedBeaconBlockCapella `json:"message" validate:"required"`
Signature string `json:"signature" validate:"required"`
}
type BlindedBeaconBlockCapella struct {
Slot string `json:"slot" validate:"required"`
ProposerIndex string `json:"proposer_index" validate:"required"`
ParentRoot string `json:"parent_root" validate:"required"`
StateRoot string `json:"state_root" validate:"required"`
Body *BlindedBeaconBlockBodyCapella `json:"body" validate:"required"`
}
type BlindedBeaconBlockBodyCapella struct {
RandaoReveal string `json:"randao_reveal" validate:"required"`
Eth1Data *Eth1Data `json:"eth1_data" validate:"required"`
Graffiti string `json:"graffiti" validate:"required"`
ProposerSlashings []*ProposerSlashing `json:"proposer_slashings" validate:"required,dive"`
AttesterSlashings []*AttesterSlashing `json:"attester_slashings" validate:"required,dive"`
Attestations []*Attestation `json:"attestations" validate:"required,dive"`
Deposits []*Deposit `json:"deposits" validate:"required,dive"`
VoluntaryExits []*SignedVoluntaryExit `json:"voluntary_exits" validate:"required,dive"`
SyncAggregate *SyncAggregate `json:"sync_aggregate" validate:"required"`
ExecutionPayloadHeader *ExecutionPayloadHeaderCapella `json:"execution_payload_header" validate:"required"`
BlsToExecutionChanges []*SignedBlsToExecutionChange `json:"bls_to_execution_changes" validate:"required,dive"`
}
type SignedBeaconBlockContentsDeneb struct {
SignedBlock *SignedBeaconBlockDeneb `json:"signed_block" validate:"required"`
SignedBlobSidecars []*SignedBlobSidecar `json:"signed_blob_sidecars" validate:"dive"`
}
type BeaconBlockContentsDeneb struct {
Block *BeaconBlockDeneb `json:"block" validate:"required"`
BlobSidecars []*BlobSidecar `json:"blob_sidecars" validate:"dive"`
}
type SignedBeaconBlockDeneb struct {
Message *BeaconBlockDeneb `json:"message" validate:"required"`
Signature string `json:"signature" validate:"required"`
}
type BeaconBlockDeneb struct {
Slot string `json:"slot" validate:"required"`
ProposerIndex string `json:"proposer_index" validate:"required"`
ParentRoot string `json:"parent_root" validate:"required"`
StateRoot string `json:"state_root" validate:"required"`
Body *BeaconBlockBodyDeneb `json:"body" validate:"required"`
}
type BeaconBlockBodyDeneb struct {
RandaoReveal string `json:"randao_reveal" validate:"required"`
Eth1Data *Eth1Data `json:"eth1_data" validate:"required"`
Graffiti string `json:"graffiti" validate:"required"`
ProposerSlashings []*ProposerSlashing `json:"proposer_slashings" validate:"required,dive"`
AttesterSlashings []*AttesterSlashing `json:"attester_slashings" validate:"required,dive"`
Attestations []*Attestation `json:"attestations" validate:"required,dive"`
Deposits []*Deposit `json:"deposits" validate:"required,dive"`
VoluntaryExits []*SignedVoluntaryExit `json:"voluntary_exits" validate:"required,dive"`
SyncAggregate *SyncAggregate `json:"sync_aggregate" validate:"required"`
ExecutionPayload *ExecutionPayloadDeneb `json:"execution_payload" validate:"required"`
BlsToExecutionChanges []*SignedBlsToExecutionChange `json:"bls_to_execution_changes" validate:"required,dive"`
BlobKzgCommitments []string `json:"blob_kzg_commitments" validate:"required,dive"`
}
type ExecutionPayloadDeneb struct {
ParentHash string `json:"parent_hash" validate:"required"`
FeeRecipient string `json:"fee_recipient" validate:"required"`
StateRoot string `json:"state_root" validate:"required"`
ReceiptsRoot string `json:"receipts_root" validate:"required"`
LogsBloom string `json:"logs_bloom" validate:"required"`
PrevRandao string `json:"prev_randao" validate:"required"`
BlockNumber string `json:"block_number" validate:"required"`
GasLimit string `json:"gas_limit" validate:"required"`
GasUsed string `json:"gas_used" validate:"required"`
Timestamp string `json:"timestamp" validate:"required"`
ExtraData string `json:"extra_data" validate:"required"`
BaseFeePerGas string `json:"base_fee_per_gas" validate:"required"`
BlobGasUsed string `json:"blob_gas_used" validate:"required"` // new in deneb
ExcessBlobGas string `json:"excess_blob_gas" validate:"required"` // new in deneb
BlockHash string `json:"block_hash" validate:"required"`
Transactions []string `json:"transactions" validate:"required,dive,hexadecimal"`
Withdrawals []*Withdrawal `json:"withdrawals" validate:"required,dive"`
}
type SignedBlindedBeaconBlockContentsDeneb struct {
SignedBlindedBlock *SignedBlindedBeaconBlockDeneb `json:"signed_blinded_block" validate:"required"`
SignedBlindedBlobSidecars []*SignedBlindedBlobSidecar `json:"signed_blinded_blob_sidecars" validate:"dive"`
}
type BlindedBeaconBlockContentsDeneb struct {
BlindedBlock *BlindedBeaconBlockDeneb `json:"blinded_block" validate:"required"`
BlindedBlobSidecars []*BlindedBlobSidecar `json:"blinded_blob_sidecars" validate:"dive"`
}
type BlindedBeaconBlockDeneb struct {
Slot string `json:"slot" validate:"required"`
ProposerIndex string `json:"proposer_index" validate:"required"`
ParentRoot string `json:"parent_root" validate:"required"`
StateRoot string `json:"state_root" validate:"required"`
Body *BlindedBeaconBlockBodyDeneb `json:"body" validate:"required"`
}
type SignedBlindedBeaconBlockDeneb struct {
Message *BlindedBeaconBlockDeneb `json:"message" validate:"required"`
Signature string `json:"signature" validate:"required"`
}
type BlindedBeaconBlockBodyDeneb struct {
RandaoReveal string `json:"randao_reveal" validate:"required"`
Eth1Data *Eth1Data `json:"eth1_data" validate:"required"`
Graffiti string `json:"graffiti" validate:"required"`
ProposerSlashings []*ProposerSlashing `json:"proposer_slashings" validate:"required,dive"`
AttesterSlashings []*AttesterSlashing `json:"attester_slashings" validate:"required,dive"`
Attestations []*Attestation `json:"attestations" validate:"required,dive"`
Deposits []*Deposit `json:"deposits" validate:"required,dive"`
VoluntaryExits []*SignedVoluntaryExit `json:"voluntary_exits" validate:"required,dive"`
SyncAggregate *SyncAggregate `json:"sync_aggregate" validate:"required"`
ExecutionPayloadHeader *ExecutionPayloadHeaderDeneb `json:"execution_payload_header" validate:"required"`
BlsToExecutionChanges []*SignedBlsToExecutionChange `json:"bls_to_execution_changes" validate:"required,dive"`
BlobKzgCommitments []string `json:"blob_kzg_commitments" validate:"required,dive,hexadecimal"`
}
type SignedBlindedBlobSidecar struct {
Message *BlindedBlobSidecar `json:"message" validate:"required"`
Signature string `json:"signature" validate:"required"`
}
type SignedBlobSidecar struct {
Message *BlobSidecar `json:"message" validate:"required"`
Signature string `json:"signature" validate:"required"`
}
type BlindedBlobSidecar struct {
BlockRoot string `json:"block_root" validate:"required"`
Index string `json:"index" validate:"required"`
Slot string `json:"slot" validate:"required"`
BlockParentRoot string `json:"block_parent_root" validate:"required"`
ProposerIndex string `json:"proposer_index" validate:"required"`
BlobRoot string `json:"blob_root" validate:"required"`
KzgCommitment string `json:"kzg_commitment" validate:"required"` // pattern: "^0x[a-fA-F0-9]{96}$" ssz-size:"48"
KzgProof string `json:"kzg_proof" validate:"required"` // pattern: "^0x[a-fA-F0-9]{96}$" ssz-size:"48"
}
type BlobSidecar struct {
BlockRoot string `json:"block_root" validate:"required"`
Index string `json:"index" validate:"required"`
Slot string `json:"slot" validate:"required"`
BlockParentRoot string `json:"block_parent_root" validate:"required"`
ProposerIndex string `json:"proposer_index" validate:"required"`
Blob string `json:"blob" validate:"required"` // pattern: "^0x[a-fA-F0-9]{262144}$"
KzgCommitment string `json:"kzg_commitment" validate:"required"` // pattern: "^0x[a-fA-F0-9]{96}$" ssz-size:"48"
KzgProof string `json:"kzg_proof" validate:"required"` // pattern: "^0x[a-fA-F0-9]{96}$" ssz-size:"48"
}
type Eth1Data struct {
DepositRoot string `json:"deposit_root" validate:"required"`
DepositCount string `json:"deposit_count" validate:"required"`
BlockHash string `json:"block_hash" validate:"required"`
}
type ProposerSlashing struct {
SignedHeader1 *SignedBeaconBlockHeader `json:"signed_header_1" validate:"required"`
SignedHeader2 *SignedBeaconBlockHeader `json:"signed_header_2" validate:"required"`
}
type AttesterSlashing struct {
Attestation1 *IndexedAttestation `json:"attestation_1" validate:"required"`
Attestation2 *IndexedAttestation `json:"attestation_2" validate:"required"`
}
type Deposit struct {
Proof []string `json:"proof" validate:"required,dive,hexadecimal"`
Data *DepositData `json:"data" validate:"required"`
}
type DepositData struct {
Pubkey string `json:"pubkey" validate:"required"`
WithdrawalCredentials string `json:"withdrawal_credentials" validate:"required"`
Amount string `json:"amount" validate:"required"`
Signature string `json:"signature" validate:"required"`
}
type SignedBeaconBlockHeader struct {
Message *BeaconBlockHeader `json:"message" validate:"required"`
Signature string `json:"signature" validate:"required"`
}
type BeaconBlockHeader struct {
Slot string `json:"slot" validate:"required"`
ProposerIndex string `json:"proposer_index" validate:"required"`
ParentRoot string `json:"parent_root" validate:"required"`
StateRoot string `json:"state_root" validate:"required"`
BodyRoot string `json:"body_root" validate:"required"`
}
type IndexedAttestation struct {
AttestingIndices []string `json:"attesting_indices" validate:"required,dive"`
Data *AttestationData `json:"data" validate:"required"`
Signature string `json:"signature" validate:"required"`
}
type SyncAggregate struct {
SyncCommitteeBits string `json:"sync_committee_bits" validate:"required"`
SyncCommitteeSignature string `json:"sync_committee_signature" validate:"required"`
}
type ExecutionPayload struct {
ParentHash string `json:"parent_hash" validate:"required"`
FeeRecipient string `json:"fee_recipient" validate:"required"`
StateRoot string `json:"state_root" validate:"required"`
ReceiptsRoot string `json:"receipts_root" validate:"required"`
LogsBloom string `json:"logs_bloom" validate:"required"`
PrevRandao string `json:"prev_randao" validate:"required"`
BlockNumber string `json:"block_number" validate:"required"`
GasLimit string `json:"gas_limit" validate:"required"`
GasUsed string `json:"gas_used" validate:"required"`
Timestamp string `json:"timestamp" validate:"required"`
ExtraData string `json:"extra_data" validate:"required"`
BaseFeePerGas string `json:"base_fee_per_gas" validate:"required"`
BlockHash string `json:"block_hash" validate:"required"`
Transactions []string `json:"transactions" validate:"required,dive,hexadecimal"`
}
type ExecutionPayloadHeader struct {
ParentHash string `json:"parent_hash" validate:"required"`
FeeRecipient string `json:"fee_recipient" validate:"required"`
StateRoot string `json:"state_root" validate:"required"`
ReceiptsRoot string `json:"receipts_root" validate:"required"`
LogsBloom string `json:"logs_bloom" validate:"required"`
PrevRandao string `json:"prev_randao" validate:"required"`
BlockNumber string `json:"block_number" validate:"required"`
GasLimit string `json:"gas_limit" validate:"required"`
GasUsed string `json:"gas_used" validate:"required"`
Timestamp string `json:"timestamp" validate:"required"`
ExtraData string `json:"extra_data" validate:"required"`
BaseFeePerGas string `json:"base_fee_per_gas" validate:"required"`
BlockHash string `json:"block_hash" validate:"required"`
TransactionsRoot string `json:"transactions_root" validate:"required"`
}
type ExecutionPayloadCapella struct {
ParentHash string `json:"parent_hash" validate:"required"`
FeeRecipient string `json:"fee_recipient" validate:"required"`
StateRoot string `json:"state_root" validate:"required"`
ReceiptsRoot string `json:"receipts_root" validate:"required"`
LogsBloom string `json:"logs_bloom" validate:"required"`
PrevRandao string `json:"prev_randao" validate:"required"`
BlockNumber string `json:"block_number" validate:"required"`
GasLimit string `json:"gas_limit" validate:"required"`
GasUsed string `json:"gas_used" validate:"required"`
Timestamp string `json:"timestamp" validate:"required"`
ExtraData string `json:"extra_data" validate:"required"`
BaseFeePerGas string `json:"base_fee_per_gas" validate:"required"`
BlockHash string `json:"block_hash" validate:"required"`
Transactions []string `json:"transactions" validate:"required,dive"`
Withdrawals []*Withdrawal `json:"withdrawals" validate:"required,dive"`
}
type ExecutionPayloadHeaderCapella struct {
ParentHash string `json:"parent_hash" validate:"required"`
FeeRecipient string `json:"fee_recipient" validate:"required"`
StateRoot string `json:"state_root" validate:"required"`
ReceiptsRoot string `json:"receipts_root" validate:"required"`
LogsBloom string `json:"logs_bloom" validate:"required"`
PrevRandao string `json:"prev_randao" validate:"required"`
BlockNumber string `json:"block_number" validate:"required"`
GasLimit string `json:"gas_limit" validate:"required"`
GasUsed string `json:"gas_used" validate:"required"`
Timestamp string `json:"timestamp" validate:"required"`
ExtraData string `json:"extra_data" validate:"required"`
BaseFeePerGas string `json:"base_fee_per_gas" validate:"required"`
BlockHash string `json:"block_hash" validate:"required"`
TransactionsRoot string `json:"transactions_root" validate:"required"`
WithdrawalsRoot string `json:"withdrawals_root" validate:"required"`
}
type ExecutionPayloadHeaderDeneb struct {
ParentHash string `json:"parent_hash" validate:"required"`
FeeRecipient string `json:"fee_recipient" validate:"required"`
StateRoot string `json:"state_root" validate:"required"`
ReceiptsRoot string `json:"receipts_root" validate:"required"`
LogsBloom string `json:"logs_bloom" validate:"required"`
PrevRandao string `json:"prev_randao" validate:"required"`
BlockNumber string `json:"block_number" validate:"required"`
GasLimit string `json:"gas_limit" validate:"required"`
GasUsed string `json:"gas_used" validate:"required"`
Timestamp string `json:"timestamp" validate:"required"`
ExtraData string `json:"extra_data" validate:"required"`
BaseFeePerGas string `json:"base_fee_per_gas" validate:"required"`
BlobGasUsed string `json:"blob_gas_used" validate:"required"` // new in deneb
ExcessBlobGas string `json:"excess_blob_gas" validate:"required"` // new in deneb
BlockHash string `json:"block_hash" validate:"required"`
TransactionsRoot string `json:"transactions_root" validate:"required"`
WithdrawalsRoot string `json:"withdrawals_root" validate:"required"`
}
type Withdrawal struct {
WithdrawalIndex string `json:"index" validate:"required"`
ValidatorIndex string `json:"validator_index" validate:"required"`
ExecutionAddress string `json:"address" validate:"required"`
Amount string `json:"amount" validate:"required"`
}
type SignedBlsToExecutionChange struct {
Message *BlsToExecutionChange `json:"message" validate:"required"`
Signature string `json:"signature" validate:"required"`
}
type BlsToExecutionChange struct {
ValidatorIndex string `json:"validator_index" validate:"required"`
FromBlsPubkey string `json:"from_bls_pubkey" validate:"required"`
ToExecutionAddress string `json:"to_execution_address" validate:"required"`
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,10 @@
load("@prysm//tools/go:def.bzl", "go_library")
go_library(
name = "go_default_library",
testonly = True,
srcs = ["json.go"],
importpath = "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/shared/testing",
visibility = ["//visibility:public"],
deps = ["@com_github_ethereum_go_ethereum//common/hexutil:go_default_library"],
)

File diff suppressed because it is too large Load Diff

View File

@@ -4,6 +4,7 @@ go_library(
name = "go_default_library",
srcs = [
"handlers.go",
"handlers_block.go",
"server.go",
"structs.go",
"validator.go",
@@ -11,6 +12,7 @@ go_library(
importpath = "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/validator",
visibility = ["//visibility:public"],
deps = [
"//api:go_default_library",
"//beacon-chain/blockchain:go_default_library",
"//beacon-chain/builder:go_default_library",
"//beacon-chain/cache:go_default_library",
@@ -38,6 +40,7 @@ go_library(
"//proto/eth/v2:go_default_library",
"//proto/migration:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
"//runtime/version:go_default_library",
"//time/slots:go_default_library",
"@com_github_ethereum_go_ethereum//common:go_default_library",
"@com_github_ethereum_go_ethereum//common/hexutil:go_default_library",
@@ -53,11 +56,13 @@ go_library(
go_test(
name = "go_default_test",
srcs = [
"handlers_block_test.go",
"handlers_test.go",
"validator_test.go",
],
embed = [":go_default_library"],
deps = [
"//api:go_default_library",
"//beacon-chain/blockchain/testing:go_default_library",
"//beacon-chain/builder/testing:go_default_library",
"//beacon-chain/cache:go_default_library",
@@ -70,6 +75,7 @@ go_test(
"//beacon-chain/p2p/testing:go_default_library",
"//beacon-chain/rpc/core:go_default_library",
"//beacon-chain/rpc/eth/shared:go_default_library",
"//beacon-chain/rpc/eth/shared/testing:go_default_library",
"//beacon-chain/rpc/testutil:go_default_library",
"//beacon-chain/state:go_default_library",
"//beacon-chain/state/state-native:go_default_library",

View File

@@ -0,0 +1,426 @@
package validator
import (
"context"
"encoding/json"
"fmt"
"net/http"
"strings"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/v4/api"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/shared"
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
http2 "github.com/prysmaticlabs/prysm/v4/network/http"
eth "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v4/runtime/version"
log "github.com/sirupsen/logrus"
"go.opencensus.io/trace"
)
// ProduceBlockV3 Requests a beacon node to produce a valid block, which can then be signed by a validator. The
// returned block may be blinded or unblinded, depending on the current state of the network as
// decided by the execution and beacon nodes.
// The beacon node must return an unblinded block if it obtains the execution payload from its
// paired execution node. It must only return a blinded block if it obtains the execution payload
// header from an MEV relay.
// Metadata in the response indicates the type of block produced, and the supported types of block
// will be added to as forks progress.
func (s *Server) ProduceBlockV3(w http.ResponseWriter, r *http.Request) {
ctx, span := trace.StartSpan(r.Context(), "validator.ProduceBlockV3")
defer span.End()
if shared.IsSyncing(r.Context(), w, s.SyncChecker, s.HeadFetcher, s.TimeFetcher, s.OptimisticModeFetcher) {
return
}
segments := strings.Split(r.URL.Path, "/")
rawSlot := segments[len(segments)-1]
rawRandaoReveal := r.URL.Query().Get("randao_reveal")
rawGraffiti := r.URL.Query().Get("graffiti")
rawSkipRandaoVerification := r.URL.Query().Get("skip_randao_verification")
slot, valid := shared.ValidateUint(w, "slot", rawSlot)
if !valid {
return
}
var randaoReveal []byte
if rawSkipRandaoVerification == "true" {
randaoReveal = primitives.PointAtInfinity
} else {
rr, err := shared.DecodeHexWithLength(rawRandaoReveal, fieldparams.BLSSignatureLength)
if err != nil {
http2.HandleError(w, errors.Wrap(err, "unable to decode randao reveal").Error(), http.StatusBadRequest)
return
}
randaoReveal = rr
}
var graffiti []byte
if rawGraffiti != "" {
g, err := shared.DecodeHexWithLength(rawGraffiti, 32)
if err != nil {
http2.HandleError(w, errors.Wrap(err, "unable to decode graffiti").Error(), http.StatusBadRequest)
return
}
graffiti = g
}
s.produceBlockV3(ctx, w, r, &eth.BlockRequest{
Slot: primitives.Slot(slot),
RandaoReveal: randaoReveal,
Graffiti: graffiti,
SkipMevBoost: false,
})
}
func (s *Server) produceBlockV3(ctx context.Context, w http.ResponseWriter, r *http.Request, v1alpha1req *eth.BlockRequest) {
isSSZ, err := http2.SszRequested(r)
if err != nil {
log.WithError(err).Error("Checking for SSZ failed, defaulting to JSON")
isSSZ = false
}
v1alpha1resp, err := s.V1Alpha1Server.GetBeaconBlock(ctx, v1alpha1req)
if err != nil {
http2.HandleError(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set(api.ExecutionPayloadBlindedHeader, fmt.Sprintf("%v", v1alpha1resp.IsBlinded))
w.Header().Set(api.ExecutionPayloadValueHeader, fmt.Sprintf("%d", v1alpha1resp.PayloadValue))
phase0Block, ok := v1alpha1resp.Block.(*eth.GenericBeaconBlock_Phase0)
if ok {
handleProducePhase0V3(ctx, w, isSSZ, phase0Block, v1alpha1resp.PayloadValue)
return
}
altairBlock, ok := v1alpha1resp.Block.(*eth.GenericBeaconBlock_Altair)
if ok {
handleProduceAltairV3(ctx, w, isSSZ, altairBlock, v1alpha1resp.PayloadValue)
return
}
optimistic, err := s.OptimisticModeFetcher.IsOptimistic(ctx)
if err != nil {
http2.HandleError(w, errors.Wrap(err, "Could not determine if the node is a optimistic node").Error(), http.StatusInternalServerError)
return
}
if optimistic {
http2.HandleError(w, "The node is currently optimistic and cannot serve validators", http.StatusServiceUnavailable)
return
}
blindedBellatrixBlock, ok := v1alpha1resp.Block.(*eth.GenericBeaconBlock_BlindedBellatrix)
if ok {
handleProduceBlindedBellatrixV3(ctx, w, isSSZ, blindedBellatrixBlock, v1alpha1resp.PayloadValue)
return
}
bellatrixBlock, ok := v1alpha1resp.Block.(*eth.GenericBeaconBlock_Bellatrix)
if ok {
handleProduceBellatrixV3(ctx, w, isSSZ, bellatrixBlock, v1alpha1resp.PayloadValue)
return
}
blindedCapellaBlock, ok := v1alpha1resp.Block.(*eth.GenericBeaconBlock_BlindedCapella)
if ok {
handleProduceBlindedCapellaV3(ctx, w, isSSZ, blindedCapellaBlock, v1alpha1resp.PayloadValue)
return
}
capellaBlock, ok := v1alpha1resp.Block.(*eth.GenericBeaconBlock_Capella)
if ok {
handleProduceCapellaV3(ctx, w, isSSZ, capellaBlock, v1alpha1resp.PayloadValue)
return
}
blindedDenebBlockContents, ok := v1alpha1resp.Block.(*eth.GenericBeaconBlock_BlindedDeneb)
if ok {
handleProduceBlindedDenebV3(ctx, w, isSSZ, blindedDenebBlockContents, v1alpha1resp.PayloadValue)
return
}
denebBlockContents, ok := v1alpha1resp.Block.(*eth.GenericBeaconBlock_Deneb)
if ok {
handleProduceDenebV3(ctx, w, isSSZ, denebBlockContents, v1alpha1resp.PayloadValue)
return
}
}
func handleProducePhase0V3(
ctx context.Context,
w http.ResponseWriter,
isSSZ bool,
blk *eth.GenericBeaconBlock_Phase0,
payloadValue uint64,
) {
_, span := trace.StartSpan(ctx, "validator.ProduceBlockV3.internal.handleProducePhase0V3")
defer span.End()
if isSSZ {
sszResp, err := blk.Phase0.MarshalSSZ()
if err != nil {
http2.HandleError(w, err.Error(), http.StatusInternalServerError)
return
}
http2.WriteSsz(w, sszResp, "phase0Block.ssz")
return
}
block, err := shared.BeaconBlockFromConsensus(blk.Phase0)
if err != nil {
http2.HandleError(w, err.Error(), http.StatusInternalServerError)
return
}
jsonBytes, err := json.Marshal(block)
if err != nil {
http2.HandleError(w, err.Error(), http.StatusInternalServerError)
return
}
http2.WriteJson(w, &ProduceBlockV3Response{
Version: version.String(version.Phase0),
ExecutionPayloadBlinded: false,
ExecutionPayloadValue: fmt.Sprintf("%d", payloadValue), // mev not available at this point
Data: jsonBytes,
})
}
func handleProduceAltairV3(
ctx context.Context,
w http.ResponseWriter,
isSSZ bool,
blk *eth.GenericBeaconBlock_Altair,
payloadValue uint64,
) {
_, span := trace.StartSpan(ctx, "validator.ProduceBlockV3.internal.handleProduceAltairV3")
defer span.End()
if isSSZ {
sszResp, err := blk.Altair.MarshalSSZ()
if err != nil {
http2.HandleError(w, err.Error(), http.StatusInternalServerError)
return
}
http2.WriteSsz(w, sszResp, "altairBlock.ssz")
return
}
block, err := shared.BeaconBlockAltairFromConsensus(blk.Altair)
if err != nil {
http2.HandleError(w, err.Error(), http.StatusInternalServerError)
return
}
jsonBytes, err := json.Marshal(block)
if err != nil {
http2.HandleError(w, err.Error(), http.StatusInternalServerError)
return
}
http2.WriteJson(w, &ProduceBlockV3Response{
Version: version.String(version.Altair),
ExecutionPayloadBlinded: false,
ExecutionPayloadValue: fmt.Sprintf("%d", payloadValue), // mev not available at this point
Data: jsonBytes,
})
}
func handleProduceBellatrixV3(
ctx context.Context,
w http.ResponseWriter,
isSSZ bool,
blk *eth.GenericBeaconBlock_Bellatrix,
payloadValue uint64,
) {
_, span := trace.StartSpan(ctx, "validator.ProduceBlockV3.internal.handleProduceBellatrixV3")
defer span.End()
if isSSZ {
sszResp, err := blk.Bellatrix.MarshalSSZ()
if err != nil {
http2.HandleError(w, err.Error(), http.StatusInternalServerError)
return
}
http2.WriteSsz(w, sszResp, "bellatrixBlock.ssz")
return
}
block, err := shared.BeaconBlockBellatrixFromConsensus(blk.Bellatrix)
if err != nil {
http2.HandleError(w, err.Error(), http.StatusInternalServerError)
return
}
jsonBytes, err := json.Marshal(block)
if err != nil {
http2.HandleError(w, err.Error(), http.StatusInternalServerError)
return
}
http2.WriteJson(w, &ProduceBlockV3Response{
Version: version.String(version.Bellatrix),
ExecutionPayloadBlinded: false,
ExecutionPayloadValue: fmt.Sprintf("%d", payloadValue), // mev not available at this point
Data: jsonBytes,
})
}
func handleProduceBlindedBellatrixV3(
ctx context.Context,
w http.ResponseWriter,
isSSZ bool,
blk *eth.GenericBeaconBlock_BlindedBellatrix,
payloadValue uint64,
) {
_, span := trace.StartSpan(ctx, "validator.ProduceBlockV3.internal.handleProduceBlindedBellatrixV3")
defer span.End()
if isSSZ {
sszResp, err := blk.BlindedBellatrix.MarshalSSZ()
if err != nil {
http2.HandleError(w, err.Error(), http.StatusInternalServerError)
return
}
http2.WriteSsz(w, sszResp, "blindedBellatrixBlock.ssz")
return
}
block, err := shared.BlindedBeaconBlockBellatrixFromConsensus(blk.BlindedBellatrix)
if err != nil {
http2.HandleError(w, err.Error(), http.StatusInternalServerError)
return
}
jsonBytes, err := json.Marshal(block)
if err != nil {
http2.HandleError(w, err.Error(), http.StatusInternalServerError)
return
}
http2.WriteJson(w, &ProduceBlockV3Response{
Version: version.String(version.Bellatrix),
ExecutionPayloadBlinded: true,
ExecutionPayloadValue: fmt.Sprintf("%d", payloadValue),
Data: jsonBytes,
})
}
func handleProduceBlindedCapellaV3(
ctx context.Context,
w http.ResponseWriter,
isSSZ bool,
blk *eth.GenericBeaconBlock_BlindedCapella,
payloadValue uint64,
) {
_, span := trace.StartSpan(ctx, "validator.ProduceBlockV3.internal.handleProduceBlindedCapellaV3")
defer span.End()
if isSSZ {
sszResp, err := blk.BlindedCapella.MarshalSSZ()
if err != nil {
http2.HandleError(w, err.Error(), http.StatusInternalServerError)
return
}
http2.WriteSsz(w, sszResp, "blindedCapellaBlock.ssz")
return
}
block, err := shared.BlindedBeaconBlockCapellaFromConsensus(blk.BlindedCapella)
if err != nil {
http2.HandleError(w, err.Error(), http.StatusInternalServerError)
return
}
jsonBytes, err := json.Marshal(block)
if err != nil {
http2.HandleError(w, err.Error(), http.StatusInternalServerError)
return
}
http2.WriteJson(w, &ProduceBlockV3Response{
Version: version.String(version.Capella),
ExecutionPayloadBlinded: true,
ExecutionPayloadValue: fmt.Sprintf("%d", payloadValue),
Data: jsonBytes,
})
}
func handleProduceCapellaV3(
ctx context.Context,
w http.ResponseWriter,
isSSZ bool,
blk *eth.GenericBeaconBlock_Capella,
payloadValue uint64,
) {
_, span := trace.StartSpan(ctx, "validator.ProduceBlockV3.internal.handleProduceCapellaV3")
defer span.End()
if isSSZ {
sszResp, err := blk.Capella.MarshalSSZ()
if err != nil {
http2.HandleError(w, err.Error(), http.StatusInternalServerError)
return
}
http2.WriteSsz(w, sszResp, "capellaBlock.ssz")
return
}
block, err := shared.BeaconBlockCapellaFromConsensus(blk.Capella)
if err != nil {
http2.HandleError(w, err.Error(), http.StatusInternalServerError)
return
}
jsonBytes, err := json.Marshal(block)
if err != nil {
http2.HandleError(w, err.Error(), http.StatusInternalServerError)
return
}
http2.WriteJson(w, &ProduceBlockV3Response{
Version: version.String(version.Capella),
ExecutionPayloadBlinded: false,
ExecutionPayloadValue: fmt.Sprintf("%d", payloadValue), // mev not available at this point
Data: jsonBytes,
})
}
func handleProduceBlindedDenebV3(
ctx context.Context,
w http.ResponseWriter,
isSSZ bool,
blk *eth.GenericBeaconBlock_BlindedDeneb,
payloadValue uint64,
) {
_, span := trace.StartSpan(ctx, "validator.ProduceBlockV3.internal.handleProduceBlindedDenebV3")
defer span.End()
if isSSZ {
sszResp, err := blk.BlindedDeneb.MarshalSSZ()
if err != nil {
http2.HandleError(w, err.Error(), http.StatusInternalServerError)
return
}
http2.WriteSsz(w, sszResp, "blindedDenebBlockContents.ssz")
return
}
blockContents, err := shared.BlindedBeaconBlockContentsDenebFromConsensus(blk.BlindedDeneb)
if err != nil {
http2.HandleError(w, err.Error(), http.StatusInternalServerError)
return
}
jsonBytes, err := json.Marshal(blockContents)
if err != nil {
http2.HandleError(w, err.Error(), http.StatusInternalServerError)
return
}
http2.WriteJson(w, &ProduceBlockV3Response{
Version: version.String(version.Deneb),
ExecutionPayloadBlinded: true,
ExecutionPayloadValue: fmt.Sprintf("%d", payloadValue),
Data: jsonBytes,
})
}
func handleProduceDenebV3(
ctx context.Context,
w http.ResponseWriter,
isSSZ bool,
blk *eth.GenericBeaconBlock_Deneb,
payloadValue uint64,
) {
_, span := trace.StartSpan(ctx, "validator.ProduceBlockV3.internal.handleProduceDenebV3")
defer span.End()
if isSSZ {
sszResp, err := blk.Deneb.MarshalSSZ()
if err != nil {
http2.HandleError(w, err.Error(), http.StatusInternalServerError)
return
}
http2.WriteSsz(w, sszResp, "denebBlockContents.ssz")
return
}
blockContents, err := shared.BeaconBlockContentsDenebFromConsensus(blk.Deneb)
if err != nil {
http2.HandleError(w, err.Error(), http.StatusInternalServerError)
return
}
jsonBytes, err := json.Marshal(blockContents)
if err != nil {
http2.HandleError(w, err.Error(), http.StatusInternalServerError)
return
}
http2.WriteJson(w, &ProduceBlockV3Response{
Version: version.String(version.Deneb),
ExecutionPayloadBlinded: false,
ExecutionPayloadValue: fmt.Sprintf("%d", payloadValue), // mev not available at this point
Data: jsonBytes,
})
}

View File

@@ -0,0 +1,587 @@
package validator
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"net/http/httptest"
"strings"
"testing"
"github.com/golang/mock/gomock"
"github.com/prysmaticlabs/prysm/v4/api"
blockchainTesting "github.com/prysmaticlabs/prysm/v4/beacon-chain/blockchain/testing"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/shared"
rpctesting "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/shared/testing"
mockSync "github.com/prysmaticlabs/prysm/v4/beacon-chain/sync/initial-sync/testing"
eth "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v4/testing/assert"
mock2 "github.com/prysmaticlabs/prysm/v4/testing/mock"
"github.com/prysmaticlabs/prysm/v4/testing/require"
)
func TestProduceBlockV3(t *testing.T) {
ctrl := gomock.NewController(t)
t.Run("Phase 0", func(t *testing.T) {
var block *shared.SignedBeaconBlock
err := json.Unmarshal([]byte(rpctesting.Phase0Block), &block)
require.NoError(t, err)
jsonBytes, err := json.Marshal(block.Message)
require.NoError(t, err)
v1alpha1Server := mock2.NewMockBeaconNodeValidatorServer(ctrl)
v1alpha1Server.EXPECT().GetBeaconBlock(gomock.Any(), gomock.Any()).Return(
func() (*eth.GenericBeaconBlock, error) {
return block.Message.ToGeneric()
}())
server := &Server{
V1Alpha1Server: v1alpha1Server,
SyncChecker: &mockSync.Sync{IsSyncing: false},
}
rr := "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" +
"&graffiti=0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"
request := httptest.NewRequest(http.MethodGet, fmt.Sprintf("http://foo.example/eth/v3/validator/blocks/1?randao_reveal=%s", rr), nil)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
server.ProduceBlockV3(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
want := fmt.Sprintf(`{"version":"phase0","execution_payload_blinded":false,"execution_payload_value":"0","data":%s}`, string(jsonBytes))
body := strings.ReplaceAll(writer.Body.String(), "\n", "")
require.Equal(t, want, body)
require.Equal(t, writer.Header().Get(api.ExecutionPayloadBlindedHeader) == "false", true)
require.Equal(t, writer.Header().Get(api.ExecutionPayloadValueHeader) == "0", true)
})
t.Run("Altair", func(t *testing.T) {
var block *shared.SignedBeaconBlockAltair
err := json.Unmarshal([]byte(rpctesting.AltairBlock), &block)
require.NoError(t, err)
jsonBytes, err := json.Marshal(block.Message)
require.NoError(t, err)
v1alpha1Server := mock2.NewMockBeaconNodeValidatorServer(ctrl)
v1alpha1Server.EXPECT().GetBeaconBlock(gomock.Any(), gomock.Any()).Return(
func() (*eth.GenericBeaconBlock, error) {
return block.Message.ToGeneric()
}())
server := &Server{
V1Alpha1Server: v1alpha1Server,
SyncChecker: &mockSync.Sync{IsSyncing: false},
}
rr := "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" +
"&graffiti=0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"
request := httptest.NewRequest(http.MethodGet, fmt.Sprintf("http://foo.example/eth/v3/validator/blocks/1?randao_reveal=%s", rr), nil)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
server.ProduceBlockV3(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
want := fmt.Sprintf(`{"version":"altair","execution_payload_blinded":false,"execution_payload_value":"0","data":%s}`, string(jsonBytes))
body := strings.ReplaceAll(writer.Body.String(), "\n", "")
require.Equal(t, want, body)
require.Equal(t, writer.Header().Get(api.ExecutionPayloadBlindedHeader) == "false", true)
require.Equal(t, writer.Header().Get(api.ExecutionPayloadValueHeader) == "0", true)
})
t.Run("Bellatrix", func(t *testing.T) {
var block *shared.SignedBeaconBlockBellatrix
err := json.Unmarshal([]byte(rpctesting.BellatrixBlock), &block)
require.NoError(t, err)
jsonBytes, err := json.Marshal(block.Message)
require.NoError(t, err)
v1alpha1Server := mock2.NewMockBeaconNodeValidatorServer(ctrl)
v1alpha1Server.EXPECT().GetBeaconBlock(gomock.Any(), gomock.Any()).Return(
func() (*eth.GenericBeaconBlock, error) {
return block.Message.ToGeneric()
}())
mockChainService := &blockchainTesting.ChainService{}
server := &Server{
V1Alpha1Server: v1alpha1Server,
SyncChecker: &mockSync.Sync{IsSyncing: false},
OptimisticModeFetcher: mockChainService,
}
rr := "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" +
"&graffiti=0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"
request := httptest.NewRequest(http.MethodGet, fmt.Sprintf("http://foo.example/eth/v3/validator/blocks/1?randao_reveal=%s", rr), nil)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
server.ProduceBlockV3(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
want := fmt.Sprintf(`{"version":"bellatrix","execution_payload_blinded":false,"execution_payload_value":"0","data":%s}`, string(jsonBytes))
body := strings.ReplaceAll(writer.Body.String(), "\n", "")
require.Equal(t, want, body)
require.Equal(t, writer.Header().Get(api.ExecutionPayloadBlindedHeader) == "false", true)
require.Equal(t, writer.Header().Get(api.ExecutionPayloadValueHeader) == "0", true)
})
t.Run("BlindedBellatrix", func(t *testing.T) {
var block *shared.SignedBlindedBeaconBlockBellatrix
err := json.Unmarshal([]byte(rpctesting.BlindedBellatrixBlock), &block)
require.NoError(t, err)
jsonBytes, err := json.Marshal(block.Message)
require.NoError(t, err)
v1alpha1Server := mock2.NewMockBeaconNodeValidatorServer(ctrl)
v1alpha1Server.EXPECT().GetBeaconBlock(gomock.Any(), gomock.Any()).Return(
func() (*eth.GenericBeaconBlock, error) {
return block.Message.ToGeneric()
}())
mockChainService := &blockchainTesting.ChainService{}
server := &Server{
V1Alpha1Server: v1alpha1Server,
SyncChecker: &mockSync.Sync{IsSyncing: false},
OptimisticModeFetcher: mockChainService,
}
rr := "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" +
"&graffiti=0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"
request := httptest.NewRequest(http.MethodGet, fmt.Sprintf("http://foo.example/eth/v3/validator/blocks/1?randao_reveal=%s", rr), nil)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
server.ProduceBlockV3(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
want := fmt.Sprintf(`{"version":"bellatrix","execution_payload_blinded":true,"execution_payload_value":"0","data":%s}`, string(jsonBytes))
body := strings.ReplaceAll(writer.Body.String(), "\n", "")
require.Equal(t, want, body)
require.Equal(t, writer.Header().Get(api.ExecutionPayloadBlindedHeader) == "true", true)
require.Equal(t, writer.Header().Get(api.ExecutionPayloadValueHeader) == "0", true)
})
t.Run("Capella", func(t *testing.T) {
var block *shared.SignedBeaconBlockCapella
err := json.Unmarshal([]byte(rpctesting.CapellaBlock), &block)
require.NoError(t, err)
jsonBytes, err := json.Marshal(block.Message)
require.NoError(t, err)
v1alpha1Server := mock2.NewMockBeaconNodeValidatorServer(ctrl)
v1alpha1Server.EXPECT().GetBeaconBlock(gomock.Any(), gomock.Any()).Return(
func() (*eth.GenericBeaconBlock, error) {
return block.Message.ToGeneric()
}())
mockChainService := &blockchainTesting.ChainService{}
server := &Server{
V1Alpha1Server: v1alpha1Server,
SyncChecker: &mockSync.Sync{IsSyncing: false},
OptimisticModeFetcher: mockChainService,
}
rr := "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" +
"&graffiti=0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"
request := httptest.NewRequest(http.MethodGet, fmt.Sprintf("http://foo.example/eth/v3/validator/blocks/1?randao_reveal=%s", rr), nil)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
server.ProduceBlockV3(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
want := fmt.Sprintf(`{"version":"capella","execution_payload_blinded":false,"execution_payload_value":"0","data":%s}`, string(jsonBytes))
body := strings.ReplaceAll(writer.Body.String(), "\n", "")
require.Equal(t, want, body)
require.Equal(t, writer.Header().Get(api.ExecutionPayloadBlindedHeader) == "false", true)
require.Equal(t, writer.Header().Get(api.ExecutionPayloadValueHeader) == "0", true)
})
t.Run("Blinded Capella", func(t *testing.T) {
var block *shared.SignedBlindedBeaconBlockCapella
err := json.Unmarshal([]byte(rpctesting.BlindedCapellaBlock), &block)
require.NoError(t, err)
jsonBytes, err := json.Marshal(block.Message)
require.NoError(t, err)
v1alpha1Server := mock2.NewMockBeaconNodeValidatorServer(ctrl)
v1alpha1Server.EXPECT().GetBeaconBlock(gomock.Any(), gomock.Any()).Return(
func() (*eth.GenericBeaconBlock, error) {
g, err := block.Message.ToGeneric()
require.NoError(t, err)
g.PayloadValue = 2000 //some fake value
return g, err
}())
mockChainService := &blockchainTesting.ChainService{}
server := &Server{
V1Alpha1Server: v1alpha1Server,
SyncChecker: &mockSync.Sync{IsSyncing: false},
OptimisticModeFetcher: mockChainService,
}
rr := "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" +
"&graffiti=0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"
request := httptest.NewRequest(http.MethodGet, fmt.Sprintf("http://foo.example/eth/v3/validator/blocks/1?randao_reveal=%s", rr), nil)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
server.ProduceBlockV3(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
want := fmt.Sprintf(`{"version":"capella","execution_payload_blinded":true,"execution_payload_value":"2000","data":%s}`, string(jsonBytes))
body := strings.ReplaceAll(writer.Body.String(), "\n", "")
require.Equal(t, want, body)
require.Equal(t, writer.Header().Get(api.ExecutionPayloadBlindedHeader) == "true", true)
require.Equal(t, writer.Header().Get(api.ExecutionPayloadValueHeader) == "2000", true)
})
t.Run("Deneb", func(t *testing.T) {
var block *shared.SignedBeaconBlockContentsDeneb
err := json.Unmarshal([]byte(rpctesting.DenebBlockContents), &block)
require.NoError(t, err)
jsonBytes, err := json.Marshal(block.ToUnsigned())
require.NoError(t, err)
v1alpha1Server := mock2.NewMockBeaconNodeValidatorServer(ctrl)
v1alpha1Server.EXPECT().GetBeaconBlock(gomock.Any(), gomock.Any()).Return(
func() (*eth.GenericBeaconBlock, error) {
return block.ToUnsigned().ToGeneric()
}())
mockChainService := &blockchainTesting.ChainService{}
server := &Server{
V1Alpha1Server: v1alpha1Server,
SyncChecker: &mockSync.Sync{IsSyncing: false},
OptimisticModeFetcher: mockChainService,
}
rr := "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" +
"&graffiti=0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"
request := httptest.NewRequest(http.MethodGet, fmt.Sprintf("http://foo.example/eth/v3/validator/blocks/1?randao_reveal=%s", rr), nil)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
server.ProduceBlockV3(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
want := fmt.Sprintf(`{"version":"deneb","execution_payload_blinded":false,"execution_payload_value":"0","data":%s}`, string(jsonBytes))
body := strings.ReplaceAll(writer.Body.String(), "\n", "")
require.Equal(t, want, body)
require.Equal(t, writer.Header().Get(api.ExecutionPayloadBlindedHeader) == "false", true)
require.Equal(t, writer.Header().Get(api.ExecutionPayloadValueHeader) == "0", true)
})
t.Run("Blinded Deneb", func(t *testing.T) {
var block *shared.SignedBlindedBeaconBlockContentsDeneb
err := json.Unmarshal([]byte(rpctesting.BlindedDenebBlockContents), &block)
require.NoError(t, err)
jsonBytes, err := json.Marshal(block.ToUnsigned())
require.NoError(t, err)
v1alpha1Server := mock2.NewMockBeaconNodeValidatorServer(ctrl)
v1alpha1Server.EXPECT().GetBeaconBlock(gomock.Any(), gomock.Any()).Return(
func() (*eth.GenericBeaconBlock, error) {
return block.ToUnsigned().ToGeneric()
}())
mockChainService := &blockchainTesting.ChainService{}
server := &Server{
V1Alpha1Server: v1alpha1Server,
SyncChecker: &mockSync.Sync{IsSyncing: false},
OptimisticModeFetcher: mockChainService,
}
rr := "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" +
"&graffiti=0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"
request := httptest.NewRequest(http.MethodGet, fmt.Sprintf("http://foo.example/eth/v3/validator/blocks/1?randao_reveal=%s", rr), nil)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
server.ProduceBlockV3(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
want := fmt.Sprintf(`{"version":"deneb","execution_payload_blinded":true,"execution_payload_value":"0","data":%s}`, string(jsonBytes))
body := strings.ReplaceAll(writer.Body.String(), "\n", "")
require.Equal(t, want, body)
require.Equal(t, writer.Header().Get(api.ExecutionPayloadBlindedHeader) == "true", true)
require.Equal(t, writer.Header().Get(api.ExecutionPayloadValueHeader) == "0", true)
})
t.Run("invalid query parameter slot empty", func(t *testing.T) {
v1alpha1Server := mock2.NewMockBeaconNodeValidatorServer(ctrl)
server := &Server{
V1Alpha1Server: v1alpha1Server,
SyncChecker: &mockSync.Sync{IsSyncing: false},
}
request := httptest.NewRequest(http.MethodGet, "http://foo.example/eth/v3/validator/blocks/", nil)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
server.ProduceBlockV3(writer, request)
assert.Equal(t, http.StatusBadRequest, writer.Code)
assert.Equal(t, true, strings.Contains(writer.Body.String(), "slot is required"))
})
t.Run("invalid query parameter slot invalid", func(t *testing.T) {
v1alpha1Server := mock2.NewMockBeaconNodeValidatorServer(ctrl)
server := &Server{
V1Alpha1Server: v1alpha1Server,
SyncChecker: &mockSync.Sync{IsSyncing: false},
}
request := httptest.NewRequest(http.MethodGet, "http://foo.example/eth/v3/validator/blocks/asdfsad", nil)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
server.ProduceBlockV3(writer, request)
assert.Equal(t, http.StatusBadRequest, writer.Code)
assert.Equal(t, true, strings.Contains(writer.Body.String(), "slot is invalid"))
})
t.Run("invalid query parameter randao_reveal invalid", func(t *testing.T) {
v1alpha1Server := mock2.NewMockBeaconNodeValidatorServer(ctrl)
server := &Server{
V1Alpha1Server: v1alpha1Server,
SyncChecker: &mockSync.Sync{IsSyncing: false},
}
request := httptest.NewRequest(http.MethodGet, "http://foo.example/eth/v3/validator/blocks/1?randao_reveal=0x213123", nil)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
server.ProduceBlockV3(writer, request)
assert.Equal(t, http.StatusBadRequest, writer.Code)
})
t.Run("syncing", func(t *testing.T) {
chainService := &blockchainTesting.ChainService{}
server := &Server{
SyncChecker: &mockSync.Sync{IsSyncing: true},
HeadFetcher: chainService,
TimeFetcher: chainService,
OptimisticModeFetcher: chainService,
}
request := httptest.NewRequest(http.MethodPost, "http://foo.example", bytes.NewReader([]byte("foo")))
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
server.ProduceBlockV3(writer, request)
assert.Equal(t, http.StatusServiceUnavailable, writer.Code)
assert.Equal(t, true, strings.Contains(writer.Body.String(), "Beacon node is currently syncing and not serving request on that endpoint"))
})
}
func TestProduceBlockV3SSZ(t *testing.T) {
ctrl := gomock.NewController(t)
t.Run("Phase 0", func(t *testing.T) {
var block *shared.SignedBeaconBlock
err := json.Unmarshal([]byte(rpctesting.Phase0Block), &block)
require.NoError(t, err)
v1alpha1Server := mock2.NewMockBeaconNodeValidatorServer(ctrl)
v1alpha1Server.EXPECT().GetBeaconBlock(gomock.Any(), gomock.Any()).Return(
func() (*eth.GenericBeaconBlock, error) {
return block.Message.ToGeneric()
}())
server := &Server{
V1Alpha1Server: v1alpha1Server,
SyncChecker: &mockSync.Sync{IsSyncing: false},
}
rr := "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" +
"&graffiti=0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"
request := httptest.NewRequest(http.MethodGet, fmt.Sprintf("http://foo.example/eth/v3/validator/blocks/1?randao_reveal=%s", rr), nil)
request.Header.Set("Accept", "application/octet-stream")
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
server.ProduceBlockV3(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
g, err := block.ToGeneric()
require.NoError(t, err)
bl, ok := g.Block.(*eth.GenericSignedBeaconBlock_Phase0)
require.Equal(t, true, ok)
ssz, err := bl.Phase0.Block.MarshalSSZ()
require.NoError(t, err)
require.Equal(t, string(ssz), writer.Body.String())
require.Equal(t, writer.Header().Get(api.ExecutionPayloadBlindedHeader) == "false", true)
require.Equal(t, writer.Header().Get(api.ExecutionPayloadValueHeader) == "0", true)
})
t.Run("Altair", func(t *testing.T) {
var block *shared.SignedBeaconBlockAltair
err := json.Unmarshal([]byte(rpctesting.AltairBlock), &block)
require.NoError(t, err)
v1alpha1Server := mock2.NewMockBeaconNodeValidatorServer(ctrl)
v1alpha1Server.EXPECT().GetBeaconBlock(gomock.Any(), gomock.Any()).Return(
func() (*eth.GenericBeaconBlock, error) {
return block.Message.ToGeneric()
}())
server := &Server{
V1Alpha1Server: v1alpha1Server,
SyncChecker: &mockSync.Sync{IsSyncing: false},
}
rr := "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" +
"&graffiti=0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"
request := httptest.NewRequest(http.MethodGet, fmt.Sprintf("http://foo.example/eth/v3/validator/blocks/1?randao_reveal=%s", rr), nil)
request.Header.Set("Accept", "application/octet-stream")
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
server.ProduceBlockV3(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
g, err := block.ToGeneric()
require.NoError(t, err)
bl, ok := g.Block.(*eth.GenericSignedBeaconBlock_Altair)
require.Equal(t, true, ok)
ssz, err := bl.Altair.Block.MarshalSSZ()
require.NoError(t, err)
require.Equal(t, string(ssz), writer.Body.String())
require.Equal(t, writer.Header().Get(api.ExecutionPayloadBlindedHeader) == "false", true)
require.Equal(t, writer.Header().Get(api.ExecutionPayloadValueHeader) == "0", true)
})
t.Run("Bellatrix", func(t *testing.T) {
var block *shared.SignedBeaconBlockBellatrix
err := json.Unmarshal([]byte(rpctesting.BellatrixBlock), &block)
require.NoError(t, err)
v1alpha1Server := mock2.NewMockBeaconNodeValidatorServer(ctrl)
v1alpha1Server.EXPECT().GetBeaconBlock(gomock.Any(), gomock.Any()).Return(
func() (*eth.GenericBeaconBlock, error) {
return block.Message.ToGeneric()
}())
mockChainService := &blockchainTesting.ChainService{}
server := &Server{
V1Alpha1Server: v1alpha1Server,
SyncChecker: &mockSync.Sync{IsSyncing: false},
OptimisticModeFetcher: mockChainService,
}
rr := "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" +
"&graffiti=0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"
request := httptest.NewRequest(http.MethodGet, fmt.Sprintf("http://foo.example/eth/v3/validator/blocks/1?randao_reveal=%s", rr), nil)
request.Header.Set("Accept", "application/octet-stream")
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
server.ProduceBlockV3(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
g, err := block.ToGeneric()
require.NoError(t, err)
bl, ok := g.Block.(*eth.GenericSignedBeaconBlock_Bellatrix)
require.Equal(t, true, ok)
ssz, err := bl.Bellatrix.Block.MarshalSSZ()
require.NoError(t, err)
require.Equal(t, string(ssz), writer.Body.String())
require.Equal(t, writer.Header().Get(api.ExecutionPayloadBlindedHeader) == "false", true)
require.Equal(t, writer.Header().Get(api.ExecutionPayloadValueHeader) == "0", true)
})
t.Run("BlindedBellatrix", func(t *testing.T) {
var block *shared.SignedBlindedBeaconBlockBellatrix
err := json.Unmarshal([]byte(rpctesting.BlindedBellatrixBlock), &block)
require.NoError(t, err)
v1alpha1Server := mock2.NewMockBeaconNodeValidatorServer(ctrl)
v1alpha1Server.EXPECT().GetBeaconBlock(gomock.Any(), gomock.Any()).Return(
func() (*eth.GenericBeaconBlock, error) {
return block.Message.ToGeneric()
}())
mockChainService := &blockchainTesting.ChainService{}
server := &Server{
V1Alpha1Server: v1alpha1Server,
SyncChecker: &mockSync.Sync{IsSyncing: false},
OptimisticModeFetcher: mockChainService,
}
rr := "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" +
"&graffiti=0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"
request := httptest.NewRequest(http.MethodGet, fmt.Sprintf("http://foo.example/eth/v3/validator/blocks/1?randao_reveal=%s", rr), nil)
request.Header.Set("Accept", "application/octet-stream")
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
server.ProduceBlockV3(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
g, err := block.ToGeneric()
require.NoError(t, err)
bl, ok := g.Block.(*eth.GenericSignedBeaconBlock_BlindedBellatrix)
require.Equal(t, true, ok)
ssz, err := bl.BlindedBellatrix.Block.MarshalSSZ()
require.NoError(t, err)
require.Equal(t, string(ssz), writer.Body.String())
require.Equal(t, writer.Header().Get(api.ExecutionPayloadBlindedHeader) == "true", true)
require.Equal(t, writer.Header().Get(api.ExecutionPayloadValueHeader) == "0", true)
})
t.Run("Capella", func(t *testing.T) {
var block *shared.SignedBeaconBlockCapella
err := json.Unmarshal([]byte(rpctesting.CapellaBlock), &block)
require.NoError(t, err)
v1alpha1Server := mock2.NewMockBeaconNodeValidatorServer(ctrl)
v1alpha1Server.EXPECT().GetBeaconBlock(gomock.Any(), gomock.Any()).Return(
func() (*eth.GenericBeaconBlock, error) {
return block.Message.ToGeneric()
}())
mockChainService := &blockchainTesting.ChainService{}
server := &Server{
V1Alpha1Server: v1alpha1Server,
SyncChecker: &mockSync.Sync{IsSyncing: false},
OptimisticModeFetcher: mockChainService,
}
rr := "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" +
"&graffiti=0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"
request := httptest.NewRequest(http.MethodGet, fmt.Sprintf("http://foo.example/eth/v3/validator/blocks/1?randao_reveal=%s", rr), nil)
request.Header.Set("Accept", "application/octet-stream")
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
server.ProduceBlockV3(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
g, err := block.ToGeneric()
require.NoError(t, err)
bl, ok := g.Block.(*eth.GenericSignedBeaconBlock_Capella)
require.Equal(t, true, ok)
ssz, err := bl.Capella.Block.MarshalSSZ()
require.NoError(t, err)
require.Equal(t, string(ssz), writer.Body.String())
require.Equal(t, writer.Header().Get(api.ExecutionPayloadBlindedHeader) == "false", true)
require.Equal(t, writer.Header().Get(api.ExecutionPayloadValueHeader) == "0", true)
})
t.Run("Blinded Capella", func(t *testing.T) {
var block *shared.SignedBlindedBeaconBlockCapella
err := json.Unmarshal([]byte(rpctesting.BlindedCapellaBlock), &block)
require.NoError(t, err)
v1alpha1Server := mock2.NewMockBeaconNodeValidatorServer(ctrl)
v1alpha1Server.EXPECT().GetBeaconBlock(gomock.Any(), gomock.Any()).Return(
func() (*eth.GenericBeaconBlock, error) {
g, err := block.Message.ToGeneric()
require.NoError(t, err)
g.PayloadValue = 2000 //some fake value
return g, err
}())
mockChainService := &blockchainTesting.ChainService{}
server := &Server{
V1Alpha1Server: v1alpha1Server,
SyncChecker: &mockSync.Sync{IsSyncing: false},
OptimisticModeFetcher: mockChainService,
}
rr := "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" +
"&graffiti=0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"
request := httptest.NewRequest(http.MethodGet, fmt.Sprintf("http://foo.example/eth/v3/validator/blocks/1?randao_reveal=%s", rr), nil)
request.Header.Set("Accept", "application/octet-stream")
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
server.ProduceBlockV3(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
g, err := block.ToGeneric()
require.NoError(t, err)
bl, ok := g.Block.(*eth.GenericSignedBeaconBlock_BlindedCapella)
require.Equal(t, true, ok)
ssz, err := bl.BlindedCapella.Block.MarshalSSZ()
require.NoError(t, err)
require.Equal(t, string(ssz), writer.Body.String())
require.Equal(t, writer.Header().Get(api.ExecutionPayloadBlindedHeader) == "true", true)
require.Equal(t, writer.Header().Get(api.ExecutionPayloadValueHeader) == "2000", true)
})
t.Run("Deneb", func(t *testing.T) {
var block *shared.SignedBeaconBlockContentsDeneb
err := json.Unmarshal([]byte(rpctesting.DenebBlockContents), &block)
require.NoError(t, err)
v1alpha1Server := mock2.NewMockBeaconNodeValidatorServer(ctrl)
v1alpha1Server.EXPECT().GetBeaconBlock(gomock.Any(), gomock.Any()).Return(
func() (*eth.GenericBeaconBlock, error) {
return block.ToUnsigned().ToGeneric()
}())
mockChainService := &blockchainTesting.ChainService{}
server := &Server{
V1Alpha1Server: v1alpha1Server,
SyncChecker: &mockSync.Sync{IsSyncing: false},
OptimisticModeFetcher: mockChainService,
}
rr := "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" +
"&graffiti=0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"
request := httptest.NewRequest(http.MethodGet, fmt.Sprintf("http://foo.example/eth/v3/validator/blocks/1?randao_reveal=%s", rr), nil)
request.Header.Set("Accept", "application/octet-stream")
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
server.ProduceBlockV3(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
g, err := block.ToUnsigned().ToGeneric()
require.NoError(t, err)
bl, ok := g.Block.(*eth.GenericBeaconBlock_Deneb)
require.Equal(t, true, ok)
ssz, err := bl.Deneb.MarshalSSZ()
require.NoError(t, err)
require.Equal(t, string(ssz), writer.Body.String())
require.Equal(t, writer.Header().Get(api.ExecutionPayloadBlindedHeader) == "false", true)
require.Equal(t, writer.Header().Get(api.ExecutionPayloadValueHeader) == "0", true)
})
t.Run("Blinded Deneb", func(t *testing.T) {
var block *shared.SignedBlindedBeaconBlockContentsDeneb
err := json.Unmarshal([]byte(rpctesting.BlindedDenebBlockContents), &block)
require.NoError(t, err)
v1alpha1Server := mock2.NewMockBeaconNodeValidatorServer(ctrl)
v1alpha1Server.EXPECT().GetBeaconBlock(gomock.Any(), gomock.Any()).Return(
func() (*eth.GenericBeaconBlock, error) {
return block.ToUnsigned().ToGeneric()
}())
mockChainService := &blockchainTesting.ChainService{}
server := &Server{
V1Alpha1Server: v1alpha1Server,
SyncChecker: &mockSync.Sync{IsSyncing: false},
OptimisticModeFetcher: mockChainService,
}
rr := "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" +
"&graffiti=0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"
request := httptest.NewRequest(http.MethodGet, fmt.Sprintf("http://foo.example/eth/v3/validator/blocks/1?randao_reveal=%s", rr), nil)
request.Header.Set("Accept", "application/octet-stream")
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
server.ProduceBlockV3(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
g, err := block.ToUnsigned().ToGeneric()
require.NoError(t, err)
bl, ok := g.Block.(*eth.GenericBeaconBlock_BlindedDeneb)
require.Equal(t, true, ok)
ssz, err := bl.BlindedDeneb.MarshalSSZ()
require.NoError(t, err)
require.Equal(t, string(ssz), writer.Body.String())
require.Equal(t, writer.Header().Get(api.ExecutionPayloadBlindedHeader) == "true", true)
require.Equal(t, writer.Header().Get(api.ExecutionPayloadValueHeader) == "0", true)
})
}

View File

@@ -1,6 +1,10 @@
package validator
import "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/shared"
import (
"encoding/json"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/shared"
)
type AggregateAttestationResponse struct {
Data *shared.Attestation `json:"data"`
@@ -29,3 +33,11 @@ type GetAttestationDataResponse struct {
type ProduceSyncCommitteeContributionResponse struct {
Data *shared.SyncCommitteeContribution `json:"data"`
}
// ProduceBlockV3Response is a wrapper json object for the returned block from the ProduceBlockV3 endpoint
type ProduceBlockV3Response struct {
Version string `json:"version"`
ExecutionPayloadBlinded bool `json:"execution_payload_blinded"`
ExecutionPayloadValue string `json:"execution_payload_value"`
Data json.RawMessage `json:"data"` // represents the block values based on the version
}

View File

@@ -204,32 +204,32 @@ func (vs *Server) GetBeaconBlock(ctx context.Context, req *ethpb.BlockRequest) (
Block: pb.(*ethpb.BlindedBeaconBlockDeneb),
Blobs: blindBlobs,
}
return &ethpb.GenericBeaconBlock{Block: &ethpb.GenericBeaconBlock_BlindedDeneb{BlindedDeneb: blockAndBlobs}}, nil
return &ethpb.GenericBeaconBlock{Block: &ethpb.GenericBeaconBlock_BlindedDeneb{BlindedDeneb: blockAndBlobs}, IsBlinded: true, PayloadValue: sBlk.ValueInGwei()}, nil
}
blockAndBlobs := &ethpb.BeaconBlockAndBlobsDeneb{
Block: pb.(*ethpb.BeaconBlockDeneb),
Blobs: fullBlobs,
}
return &ethpb.GenericBeaconBlock{Block: &ethpb.GenericBeaconBlock_Deneb{Deneb: blockAndBlobs}}, nil
return &ethpb.GenericBeaconBlock{Block: &ethpb.GenericBeaconBlock_Deneb{Deneb: blockAndBlobs}, IsBlinded: false, PayloadValue: sBlk.ValueInGwei()}, nil
}
if slots.ToEpoch(req.Slot) >= params.BeaconConfig().CapellaForkEpoch {
if sBlk.IsBlinded() {
return &ethpb.GenericBeaconBlock{Block: &ethpb.GenericBeaconBlock_BlindedCapella{BlindedCapella: pb.(*ethpb.BlindedBeaconBlockCapella)}}, nil
return &ethpb.GenericBeaconBlock{Block: &ethpb.GenericBeaconBlock_BlindedCapella{BlindedCapella: pb.(*ethpb.BlindedBeaconBlockCapella)}, IsBlinded: true, PayloadValue: sBlk.ValueInGwei()}, nil
}
return &ethpb.GenericBeaconBlock{Block: &ethpb.GenericBeaconBlock_Capella{Capella: pb.(*ethpb.BeaconBlockCapella)}}, nil
return &ethpb.GenericBeaconBlock{Block: &ethpb.GenericBeaconBlock_Capella{Capella: pb.(*ethpb.BeaconBlockCapella)}, IsBlinded: false, PayloadValue: sBlk.ValueInGwei()}, nil
}
if slots.ToEpoch(req.Slot) >= params.BeaconConfig().BellatrixForkEpoch {
if sBlk.IsBlinded() {
return &ethpb.GenericBeaconBlock{Block: &ethpb.GenericBeaconBlock_BlindedBellatrix{BlindedBellatrix: pb.(*ethpb.BlindedBeaconBlockBellatrix)}}, nil
return &ethpb.GenericBeaconBlock{Block: &ethpb.GenericBeaconBlock_BlindedBellatrix{BlindedBellatrix: pb.(*ethpb.BlindedBeaconBlockBellatrix)}, IsBlinded: true, PayloadValue: sBlk.ValueInGwei()}, nil
}
return &ethpb.GenericBeaconBlock{Block: &ethpb.GenericBeaconBlock_Bellatrix{Bellatrix: pb.(*ethpb.BeaconBlockBellatrix)}}, nil
return &ethpb.GenericBeaconBlock{Block: &ethpb.GenericBeaconBlock_Bellatrix{Bellatrix: pb.(*ethpb.BeaconBlockBellatrix)}, IsBlinded: false, PayloadValue: sBlk.ValueInGwei()}, nil
}
if slots.ToEpoch(req.Slot) >= params.BeaconConfig().AltairForkEpoch {
return &ethpb.GenericBeaconBlock{Block: &ethpb.GenericBeaconBlock_Altair{Altair: pb.(*ethpb.BeaconBlockAltair)}}, nil
return &ethpb.GenericBeaconBlock{Block: &ethpb.GenericBeaconBlock_Altair{Altair: pb.(*ethpb.BeaconBlockAltair)}, IsBlinded: false, PayloadValue: 0}, nil
}
return &ethpb.GenericBeaconBlock{Block: &ethpb.GenericBeaconBlock_Phase0{Phase0: pb.(*ethpb.BeaconBlock)}}, nil
return &ethpb.GenericBeaconBlock{Block: &ethpb.GenericBeaconBlock_Phase0{Phase0: pb.(*ethpb.BeaconBlock)}, IsBlinded: false, PayloadValue: 0}, nil
}
func (vs *Server) BuildBlockParallel(ctx context.Context, sBlk interfaces.SignedBeaconBlock, head state.BeaconState) ([]*ethpb.BlindedBlobSidecar, []*ethpb.BlobSidecar, error) {

View File

@@ -315,6 +315,8 @@ func (s *Service) Start() {
s.cfg.Router.HandleFunc("/eth/v1/validator/register_validator", validatorServerV1.RegisterValidator).Methods(http.MethodPost)
s.cfg.Router.HandleFunc("/eth/v1/validator/prepare_beacon_proposer", validatorServerV1.PrepareBeaconProposer).Methods(http.MethodPost)
s.cfg.Router.HandleFunc("/eth/v3/validator/blocks/{slot}", validatorServerV1.ProduceBlockV3).Methods(http.MethodGet)
nodeServer := &nodev1alpha1.Server{
LogsStreamer: logs.NewStreamServer(),
StreamLogsBufferSize: 1000, // Enough to handle bursts of beacon node logs for gRPC streaming.

View File

@@ -27,6 +27,7 @@ go_library(
"//runtime/version:go_default_library",
"@com_github_pkg_errors//:go_default_library",
"@com_github_prysmaticlabs_fastssz//:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",
"@org_golang_google_protobuf//proto:go_default_library",
],
)

View File

@@ -13,6 +13,7 @@ import (
eth "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
validatorpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1/validator-client"
"github.com/prysmaticlabs/prysm/v4/runtime/version"
log "github.com/sirupsen/logrus"
)
// BeaconBlockIsNil checks if any composite field of input signed beacon block is nil.
@@ -341,10 +342,26 @@ func (b *SignedBeaconBlock) Version() int {
return b.version
}
// IsBlinded metadata on whether a block is blinded
func (b *SignedBeaconBlock) IsBlinded() bool {
return b.block.body.isBlinded
}
// ValueInGwei metadata on the payload value returned by the builder. Value is 0 by default if local.
func (b *SignedBeaconBlock) ValueInGwei() uint64 {
exec, err := b.block.body.Execution()
if err != nil {
log.WithError(err).Warn("failed to retrieve execution payload")
return 0
}
val, err := exec.ValueInGwei()
if err != nil {
log.WithError(err).Warn("failed to retrieve value in gwei")
return 0
}
return val
}
// Header converts the underlying protobuf object from blinded block to header format.
func (b *SignedBeaconBlock) Header() (*eth.SignedBeaconBlockHeader, error) {
if b.IsNil() {

View File

@@ -32,6 +32,7 @@ type ReadOnlySignedBeaconBlock interface {
ssz.Unmarshaler
Version() int
IsBlinded() bool
ValueInGwei() uint64
Header() (*ethpb.SignedBeaconBlockHeader, error)
}

View File

@@ -106,6 +106,10 @@ func (SignedBeaconBlock) Header() (*eth.SignedBeaconBlockHeader, error) {
panic("implement me")
}
func (SignedBeaconBlock) ValueInGwei() uint64 {
panic("implement me")
}
type BeaconBlock struct {
Htr [field_params.RootLength]byte
HtrErr error

View File

@@ -6,6 +6,7 @@ go_library(
"committee_index.go",
"domain.go",
"epoch.go",
"randao.go",
"slot.go",
"sszbytes.go",
"sszuint64.go",

View File

@@ -0,0 +1,3 @@
package primitives
var PointAtInfinity = append([]byte{0xC0}, make([]byte, 95)...)

View File

@@ -230,3 +230,8 @@ func WeiToGwei(v Wei) Gwei {
copied.Div(copied, gweiPerEth)
return Gwei(copied.Uint64())
}
// IsValidUint256 given a bigint checks if the value is a valid Uint256
func IsValidUint256(bi *big.Int) bool {
return bi.Cmp(big.NewInt(0)) >= 0 && bi.BitLen() <= 256
}

View File

@@ -1,5 +1,5 @@
// Code generated by fastssz. DO NOT EDIT.
// Hash: 4140c14176015ace6edb7d8611bd16207ad64fe872f3ea0170279fbde82b5303
// Hash: 86494c66845c0e5ec7b1a6c6f0e34a770ce57f86114b161b5e0d8c7b04219b77
package enginev1
import (

View File

@@ -1,5 +1,5 @@
// Code generated by fastssz. DO NOT EDIT.
// Hash: e48b579f1c4ced0b36ba1329204c668ac6db966ce37b7bda314aabddbd5f1662
// Hash: 07349f3ccd696e6980796cf0b8dc149b14d1791dce8dbc553e506af598c11ebb
package v1
import (

View File

@@ -519,7 +519,7 @@ message BeaconBlockBodyDeneb {
bytes graffiti = 3 [(ethereum.eth.ext.ssz_size) = "32"];
// Block operations
// Refer to spec constants at https://github.com/ethereum/consensus-specs/blob/dev/specs/core/0_beacon-chain.md#max-operations-per-block
// Refer to spec constants at https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#max-operations-per-block
// At most MAX_PROPOSER_SLASHINGS.
repeated v1.ProposerSlashing proposer_slashings = 4 [(ethereum.eth.ext.ssz_max) = "16"];

View File

@@ -1,5 +1,5 @@
// Code generated by fastssz. DO NOT EDIT.
// Hash: d835aa3a6a3cf037dfb4ffca7686e527835b94bb660983f23017bdb8a972f81d
// Hash: eaf49253855a8c44a53cb851548885777d203c0cdcd3249906ea5f9a7b6e93c6
package eth
import (

View File

@@ -76,8 +76,12 @@ ssz_gen_marshal(
"BlindedBeaconBlockCapella",
"BlindedBeaconBlockBodyCapella",
"SignedBlindedBeaconBlockDeneb",
"BeaconBlockAndBlobsDeneb",
"SignedBeaconBlockAndBlobsDeneb",
"BlindedBeaconBlockDeneb",
"BlindedBeaconBlockBodyDeneb",
"SignedBlindedBeaconBlockAndBlobsDeneb",
"BlindedBeaconBlockAndBlobsDeneb",
"SyncAggregate",
"SyncCommitteeMessage",
"SyncCommitteeContribution",

File diff suppressed because it is too large Load Diff

View File

@@ -54,6 +54,8 @@ message GenericSignedBeaconBlock {
// Representing a signed, post-Deneb fork blinded beacon block content.
SignedBlindedBeaconBlockAndBlobsDeneb blinded_deneb = 8;
}
bool is_blinded = 100;
uint64 payload_value = 101;
}
message GenericBeaconBlock {
@@ -82,6 +84,8 @@ message GenericBeaconBlock {
// Representing a signed, post-Deneb fork blinded beacon block content.
BlindedBeaconBlockAndBlobsDeneb blinded_deneb = 8;
}
bool is_blinded = 100;
uint64 payload_value = 101;
}
// The Ethereum consensus beacon block. The message does not contain a validator signature.

View File

@@ -1,5 +1,5 @@
// Code generated by fastssz. DO NOT EDIT.
// Hash: a4cef4276bc2874bce7cd893bfee3da13f3b3f3183686029b2ce9c6ef4a32817
// Hash: 2a9c193ab6b4d9257fe266b49ce98b5cfecc990e6757a8aabb9dd0931a797f1c
package eth
import (
@@ -4613,6 +4613,160 @@ func (b *BlindedBeaconBlockBodyBellatrix) HashTreeRootWith(hh *ssz.Hasher) (err
return
}
// MarshalSSZ ssz marshals the SignedBeaconBlockAndBlobsDeneb object
func (s *SignedBeaconBlockAndBlobsDeneb) MarshalSSZ() ([]byte, error) {
return ssz.MarshalSSZ(s)
}
// MarshalSSZTo ssz marshals the SignedBeaconBlockAndBlobsDeneb object to a target array
func (s *SignedBeaconBlockAndBlobsDeneb) MarshalSSZTo(buf []byte) (dst []byte, err error) {
dst = buf
offset := int(8)
// Offset (0) 'Block'
dst = ssz.WriteOffset(dst, offset)
if s.Block == nil {
s.Block = new(SignedBeaconBlockDeneb)
}
offset += s.Block.SizeSSZ()
// Offset (1) 'Blobs'
dst = ssz.WriteOffset(dst, offset)
offset += len(s.Blobs) * 131352
// Field (0) 'Block'
if dst, err = s.Block.MarshalSSZTo(dst); err != nil {
return
}
// Field (1) 'Blobs'
if size := len(s.Blobs); size > 6 {
err = ssz.ErrListTooBigFn("--.Blobs", size, 6)
return
}
for ii := 0; ii < len(s.Blobs); ii++ {
if dst, err = s.Blobs[ii].MarshalSSZTo(dst); err != nil {
return
}
}
return
}
// UnmarshalSSZ ssz unmarshals the SignedBeaconBlockAndBlobsDeneb object
func (s *SignedBeaconBlockAndBlobsDeneb) UnmarshalSSZ(buf []byte) error {
var err error
size := uint64(len(buf))
if size < 8 {
return ssz.ErrSize
}
tail := buf
var o0, o1 uint64
// Offset (0) 'Block'
if o0 = ssz.ReadOffset(buf[0:4]); o0 > size {
return ssz.ErrOffset
}
if o0 < 8 {
return ssz.ErrInvalidVariableOffset
}
// Offset (1) 'Blobs'
if o1 = ssz.ReadOffset(buf[4:8]); o1 > size || o0 > o1 {
return ssz.ErrOffset
}
// Field (0) 'Block'
{
buf = tail[o0:o1]
if s.Block == nil {
s.Block = new(SignedBeaconBlockDeneb)
}
if err = s.Block.UnmarshalSSZ(buf); err != nil {
return err
}
}
// Field (1) 'Blobs'
{
buf = tail[o1:]
num, err := ssz.DivideInt2(len(buf), 131352, 6)
if err != nil {
return err
}
s.Blobs = make([]*SignedBlobSidecar, num)
for ii := 0; ii < num; ii++ {
if s.Blobs[ii] == nil {
s.Blobs[ii] = new(SignedBlobSidecar)
}
if err = s.Blobs[ii].UnmarshalSSZ(buf[ii*131352 : (ii+1)*131352]); err != nil {
return err
}
}
}
return err
}
// SizeSSZ returns the ssz encoded size in bytes for the SignedBeaconBlockAndBlobsDeneb object
func (s *SignedBeaconBlockAndBlobsDeneb) SizeSSZ() (size int) {
size = 8
// Field (0) 'Block'
if s.Block == nil {
s.Block = new(SignedBeaconBlockDeneb)
}
size += s.Block.SizeSSZ()
// Field (1) 'Blobs'
size += len(s.Blobs) * 131352
return
}
// HashTreeRoot ssz hashes the SignedBeaconBlockAndBlobsDeneb object
func (s *SignedBeaconBlockAndBlobsDeneb) HashTreeRoot() ([32]byte, error) {
return ssz.HashWithDefaultHasher(s)
}
// HashTreeRootWith ssz hashes the SignedBeaconBlockAndBlobsDeneb object with a hasher
func (s *SignedBeaconBlockAndBlobsDeneb) HashTreeRootWith(hh *ssz.Hasher) (err error) {
indx := hh.Index()
// Field (0) 'Block'
if err = s.Block.HashTreeRootWith(hh); err != nil {
return
}
// Field (1) 'Blobs'
{
subIndx := hh.Index()
num := uint64(len(s.Blobs))
if num > 6 {
err = ssz.ErrIncorrectListSize
return
}
for _, elem := range s.Blobs {
if err = elem.HashTreeRootWith(hh); err != nil {
return
}
}
if ssz.EnableVectorizedHTR {
hh.MerkleizeWithMixinVectorizedHTR(subIndx, num, 6)
} else {
hh.MerkleizeWithMixin(subIndx, num, 6)
}
}
if ssz.EnableVectorizedHTR {
hh.MerkleizeVectorizedHTR(indx)
} else {
hh.Merkleize(indx)
}
return
}
// MarshalSSZ ssz marshals the SignedBeaconBlockDeneb object
func (s *SignedBeaconBlockDeneb) MarshalSSZ() ([]byte, error) {
return ssz.MarshalSSZ(s)
@@ -4726,6 +4880,160 @@ func (s *SignedBeaconBlockDeneb) HashTreeRootWith(hh *ssz.Hasher) (err error) {
return
}
// MarshalSSZ ssz marshals the BeaconBlockAndBlobsDeneb object
func (b *BeaconBlockAndBlobsDeneb) MarshalSSZ() ([]byte, error) {
return ssz.MarshalSSZ(b)
}
// MarshalSSZTo ssz marshals the BeaconBlockAndBlobsDeneb object to a target array
func (b *BeaconBlockAndBlobsDeneb) MarshalSSZTo(buf []byte) (dst []byte, err error) {
dst = buf
offset := int(8)
// Offset (0) 'Block'
dst = ssz.WriteOffset(dst, offset)
if b.Block == nil {
b.Block = new(BeaconBlockDeneb)
}
offset += b.Block.SizeSSZ()
// Offset (1) 'Blobs'
dst = ssz.WriteOffset(dst, offset)
offset += len(b.Blobs) * 131256
// Field (0) 'Block'
if dst, err = b.Block.MarshalSSZTo(dst); err != nil {
return
}
// Field (1) 'Blobs'
if size := len(b.Blobs); size > 6 {
err = ssz.ErrListTooBigFn("--.Blobs", size, 6)
return
}
for ii := 0; ii < len(b.Blobs); ii++ {
if dst, err = b.Blobs[ii].MarshalSSZTo(dst); err != nil {
return
}
}
return
}
// UnmarshalSSZ ssz unmarshals the BeaconBlockAndBlobsDeneb object
func (b *BeaconBlockAndBlobsDeneb) UnmarshalSSZ(buf []byte) error {
var err error
size := uint64(len(buf))
if size < 8 {
return ssz.ErrSize
}
tail := buf
var o0, o1 uint64
// Offset (0) 'Block'
if o0 = ssz.ReadOffset(buf[0:4]); o0 > size {
return ssz.ErrOffset
}
if o0 < 8 {
return ssz.ErrInvalidVariableOffset
}
// Offset (1) 'Blobs'
if o1 = ssz.ReadOffset(buf[4:8]); o1 > size || o0 > o1 {
return ssz.ErrOffset
}
// Field (0) 'Block'
{
buf = tail[o0:o1]
if b.Block == nil {
b.Block = new(BeaconBlockDeneb)
}
if err = b.Block.UnmarshalSSZ(buf); err != nil {
return err
}
}
// Field (1) 'Blobs'
{
buf = tail[o1:]
num, err := ssz.DivideInt2(len(buf), 131256, 6)
if err != nil {
return err
}
b.Blobs = make([]*BlobSidecar, num)
for ii := 0; ii < num; ii++ {
if b.Blobs[ii] == nil {
b.Blobs[ii] = new(BlobSidecar)
}
if err = b.Blobs[ii].UnmarshalSSZ(buf[ii*131256 : (ii+1)*131256]); err != nil {
return err
}
}
}
return err
}
// SizeSSZ returns the ssz encoded size in bytes for the BeaconBlockAndBlobsDeneb object
func (b *BeaconBlockAndBlobsDeneb) SizeSSZ() (size int) {
size = 8
// Field (0) 'Block'
if b.Block == nil {
b.Block = new(BeaconBlockDeneb)
}
size += b.Block.SizeSSZ()
// Field (1) 'Blobs'
size += len(b.Blobs) * 131256
return
}
// HashTreeRoot ssz hashes the BeaconBlockAndBlobsDeneb object
func (b *BeaconBlockAndBlobsDeneb) HashTreeRoot() ([32]byte, error) {
return ssz.HashWithDefaultHasher(b)
}
// HashTreeRootWith ssz hashes the BeaconBlockAndBlobsDeneb object with a hasher
func (b *BeaconBlockAndBlobsDeneb) HashTreeRootWith(hh *ssz.Hasher) (err error) {
indx := hh.Index()
// Field (0) 'Block'
if err = b.Block.HashTreeRootWith(hh); err != nil {
return
}
// Field (1) 'Blobs'
{
subIndx := hh.Index()
num := uint64(len(b.Blobs))
if num > 6 {
err = ssz.ErrIncorrectListSize
return
}
for _, elem := range b.Blobs {
if err = elem.HashTreeRootWith(hh); err != nil {
return
}
}
if ssz.EnableVectorizedHTR {
hh.MerkleizeWithMixinVectorizedHTR(subIndx, num, 6)
} else {
hh.MerkleizeWithMixin(subIndx, num, 6)
}
}
if ssz.EnableVectorizedHTR {
hh.MerkleizeVectorizedHTR(indx)
} else {
hh.Merkleize(indx)
}
return
}
// MarshalSSZ ssz marshals the BeaconBlockDeneb object
func (b *BeaconBlockDeneb) MarshalSSZ() ([]byte, error) {
return ssz.MarshalSSZ(b)
@@ -7194,6 +7502,314 @@ func (b *BlindedBeaconBlockBodyCapella) HashTreeRootWith(hh *ssz.Hasher) (err er
return
}
// MarshalSSZ ssz marshals the SignedBlindedBeaconBlockAndBlobsDeneb object
func (s *SignedBlindedBeaconBlockAndBlobsDeneb) MarshalSSZ() ([]byte, error) {
return ssz.MarshalSSZ(s)
}
// MarshalSSZTo ssz marshals the SignedBlindedBeaconBlockAndBlobsDeneb object to a target array
func (s *SignedBlindedBeaconBlockAndBlobsDeneb) MarshalSSZTo(buf []byte) (dst []byte, err error) {
dst = buf
offset := int(8)
// Offset (0) 'Block'
dst = ssz.WriteOffset(dst, offset)
if s.Block == nil {
s.Block = new(SignedBlindedBeaconBlockDeneb)
}
offset += s.Block.SizeSSZ()
// Offset (1) 'Blobs'
dst = ssz.WriteOffset(dst, offset)
offset += len(s.Blobs) * 312
// Field (0) 'Block'
if dst, err = s.Block.MarshalSSZTo(dst); err != nil {
return
}
// Field (1) 'Blobs'
if size := len(s.Blobs); size > 6 {
err = ssz.ErrListTooBigFn("--.Blobs", size, 6)
return
}
for ii := 0; ii < len(s.Blobs); ii++ {
if dst, err = s.Blobs[ii].MarshalSSZTo(dst); err != nil {
return
}
}
return
}
// UnmarshalSSZ ssz unmarshals the SignedBlindedBeaconBlockAndBlobsDeneb object
func (s *SignedBlindedBeaconBlockAndBlobsDeneb) UnmarshalSSZ(buf []byte) error {
var err error
size := uint64(len(buf))
if size < 8 {
return ssz.ErrSize
}
tail := buf
var o0, o1 uint64
// Offset (0) 'Block'
if o0 = ssz.ReadOffset(buf[0:4]); o0 > size {
return ssz.ErrOffset
}
if o0 < 8 {
return ssz.ErrInvalidVariableOffset
}
// Offset (1) 'Blobs'
if o1 = ssz.ReadOffset(buf[4:8]); o1 > size || o0 > o1 {
return ssz.ErrOffset
}
// Field (0) 'Block'
{
buf = tail[o0:o1]
if s.Block == nil {
s.Block = new(SignedBlindedBeaconBlockDeneb)
}
if err = s.Block.UnmarshalSSZ(buf); err != nil {
return err
}
}
// Field (1) 'Blobs'
{
buf = tail[o1:]
num, err := ssz.DivideInt2(len(buf), 312, 6)
if err != nil {
return err
}
s.Blobs = make([]*SignedBlindedBlobSidecar, num)
for ii := 0; ii < num; ii++ {
if s.Blobs[ii] == nil {
s.Blobs[ii] = new(SignedBlindedBlobSidecar)
}
if err = s.Blobs[ii].UnmarshalSSZ(buf[ii*312 : (ii+1)*312]); err != nil {
return err
}
}
}
return err
}
// SizeSSZ returns the ssz encoded size in bytes for the SignedBlindedBeaconBlockAndBlobsDeneb object
func (s *SignedBlindedBeaconBlockAndBlobsDeneb) SizeSSZ() (size int) {
size = 8
// Field (0) 'Block'
if s.Block == nil {
s.Block = new(SignedBlindedBeaconBlockDeneb)
}
size += s.Block.SizeSSZ()
// Field (1) 'Blobs'
size += len(s.Blobs) * 312
return
}
// HashTreeRoot ssz hashes the SignedBlindedBeaconBlockAndBlobsDeneb object
func (s *SignedBlindedBeaconBlockAndBlobsDeneb) HashTreeRoot() ([32]byte, error) {
return ssz.HashWithDefaultHasher(s)
}
// HashTreeRootWith ssz hashes the SignedBlindedBeaconBlockAndBlobsDeneb object with a hasher
func (s *SignedBlindedBeaconBlockAndBlobsDeneb) HashTreeRootWith(hh *ssz.Hasher) (err error) {
indx := hh.Index()
// Field (0) 'Block'
if err = s.Block.HashTreeRootWith(hh); err != nil {
return
}
// Field (1) 'Blobs'
{
subIndx := hh.Index()
num := uint64(len(s.Blobs))
if num > 6 {
err = ssz.ErrIncorrectListSize
return
}
for _, elem := range s.Blobs {
if err = elem.HashTreeRootWith(hh); err != nil {
return
}
}
if ssz.EnableVectorizedHTR {
hh.MerkleizeWithMixinVectorizedHTR(subIndx, num, 6)
} else {
hh.MerkleizeWithMixin(subIndx, num, 6)
}
}
if ssz.EnableVectorizedHTR {
hh.MerkleizeVectorizedHTR(indx)
} else {
hh.Merkleize(indx)
}
return
}
// MarshalSSZ ssz marshals the BlindedBeaconBlockAndBlobsDeneb object
func (b *BlindedBeaconBlockAndBlobsDeneb) MarshalSSZ() ([]byte, error) {
return ssz.MarshalSSZ(b)
}
// MarshalSSZTo ssz marshals the BlindedBeaconBlockAndBlobsDeneb object to a target array
func (b *BlindedBeaconBlockAndBlobsDeneb) MarshalSSZTo(buf []byte) (dst []byte, err error) {
dst = buf
offset := int(8)
// Offset (0) 'Block'
dst = ssz.WriteOffset(dst, offset)
if b.Block == nil {
b.Block = new(BlindedBeaconBlockDeneb)
}
offset += b.Block.SizeSSZ()
// Offset (1) 'Blobs'
dst = ssz.WriteOffset(dst, offset)
offset += len(b.Blobs) * 216
// Field (0) 'Block'
if dst, err = b.Block.MarshalSSZTo(dst); err != nil {
return
}
// Field (1) 'Blobs'
if size := len(b.Blobs); size > 6 {
err = ssz.ErrListTooBigFn("--.Blobs", size, 6)
return
}
for ii := 0; ii < len(b.Blobs); ii++ {
if dst, err = b.Blobs[ii].MarshalSSZTo(dst); err != nil {
return
}
}
return
}
// UnmarshalSSZ ssz unmarshals the BlindedBeaconBlockAndBlobsDeneb object
func (b *BlindedBeaconBlockAndBlobsDeneb) UnmarshalSSZ(buf []byte) error {
var err error
size := uint64(len(buf))
if size < 8 {
return ssz.ErrSize
}
tail := buf
var o0, o1 uint64
// Offset (0) 'Block'
if o0 = ssz.ReadOffset(buf[0:4]); o0 > size {
return ssz.ErrOffset
}
if o0 < 8 {
return ssz.ErrInvalidVariableOffset
}
// Offset (1) 'Blobs'
if o1 = ssz.ReadOffset(buf[4:8]); o1 > size || o0 > o1 {
return ssz.ErrOffset
}
// Field (0) 'Block'
{
buf = tail[o0:o1]
if b.Block == nil {
b.Block = new(BlindedBeaconBlockDeneb)
}
if err = b.Block.UnmarshalSSZ(buf); err != nil {
return err
}
}
// Field (1) 'Blobs'
{
buf = tail[o1:]
num, err := ssz.DivideInt2(len(buf), 216, 6)
if err != nil {
return err
}
b.Blobs = make([]*BlindedBlobSidecar, num)
for ii := 0; ii < num; ii++ {
if b.Blobs[ii] == nil {
b.Blobs[ii] = new(BlindedBlobSidecar)
}
if err = b.Blobs[ii].UnmarshalSSZ(buf[ii*216 : (ii+1)*216]); err != nil {
return err
}
}
}
return err
}
// SizeSSZ returns the ssz encoded size in bytes for the BlindedBeaconBlockAndBlobsDeneb object
func (b *BlindedBeaconBlockAndBlobsDeneb) SizeSSZ() (size int) {
size = 8
// Field (0) 'Block'
if b.Block == nil {
b.Block = new(BlindedBeaconBlockDeneb)
}
size += b.Block.SizeSSZ()
// Field (1) 'Blobs'
size += len(b.Blobs) * 216
return
}
// HashTreeRoot ssz hashes the BlindedBeaconBlockAndBlobsDeneb object
func (b *BlindedBeaconBlockAndBlobsDeneb) HashTreeRoot() ([32]byte, error) {
return ssz.HashWithDefaultHasher(b)
}
// HashTreeRootWith ssz hashes the BlindedBeaconBlockAndBlobsDeneb object with a hasher
func (b *BlindedBeaconBlockAndBlobsDeneb) HashTreeRootWith(hh *ssz.Hasher) (err error) {
indx := hh.Index()
// Field (0) 'Block'
if err = b.Block.HashTreeRootWith(hh); err != nil {
return
}
// Field (1) 'Blobs'
{
subIndx := hh.Index()
num := uint64(len(b.Blobs))
if num > 6 {
err = ssz.ErrIncorrectListSize
return
}
for _, elem := range b.Blobs {
if err = elem.HashTreeRootWith(hh); err != nil {
return
}
}
if ssz.EnableVectorizedHTR {
hh.MerkleizeWithMixinVectorizedHTR(subIndx, num, 6)
} else {
hh.MerkleizeWithMixin(subIndx, num, 6)
}
}
if ssz.EnableVectorizedHTR {
hh.MerkleizeVectorizedHTR(indx)
} else {
hh.Merkleize(indx)
}
return
}
// MarshalSSZ ssz marshals the SignedBlindedBeaconBlockDeneb object
func (s *SignedBlindedBeaconBlockDeneb) MarshalSSZ() ([]byte, error) {
return ssz.MarshalSSZ(s)
@@ -14545,6 +15161,266 @@ func (s *SignedBlobSidecar) HashTreeRootWith(hh *ssz.Hasher) (err error) {
return
}
// MarshalSSZ ssz marshals the BlindedBlobSidecar object
func (b *BlindedBlobSidecar) MarshalSSZ() ([]byte, error) {
return ssz.MarshalSSZ(b)
}
// MarshalSSZTo ssz marshals the BlindedBlobSidecar object to a target array
func (b *BlindedBlobSidecar) MarshalSSZTo(buf []byte) (dst []byte, err error) {
dst = buf
// Field (0) 'BlockRoot'
if size := len(b.BlockRoot); size != 32 {
err = ssz.ErrBytesLengthFn("--.BlockRoot", size, 32)
return
}
dst = append(dst, b.BlockRoot...)
// Field (1) 'Index'
dst = ssz.MarshalUint64(dst, b.Index)
// Field (2) 'Slot'
dst = ssz.MarshalUint64(dst, uint64(b.Slot))
// Field (3) 'BlockParentRoot'
if size := len(b.BlockParentRoot); size != 32 {
err = ssz.ErrBytesLengthFn("--.BlockParentRoot", size, 32)
return
}
dst = append(dst, b.BlockParentRoot...)
// Field (4) 'ProposerIndex'
dst = ssz.MarshalUint64(dst, uint64(b.ProposerIndex))
// Field (5) 'BlobRoot'
if size := len(b.BlobRoot); size != 32 {
err = ssz.ErrBytesLengthFn("--.BlobRoot", size, 32)
return
}
dst = append(dst, b.BlobRoot...)
// Field (6) 'KzgCommitment'
if size := len(b.KzgCommitment); size != 48 {
err = ssz.ErrBytesLengthFn("--.KzgCommitment", size, 48)
return
}
dst = append(dst, b.KzgCommitment...)
// Field (7) 'KzgProof'
if size := len(b.KzgProof); size != 48 {
err = ssz.ErrBytesLengthFn("--.KzgProof", size, 48)
return
}
dst = append(dst, b.KzgProof...)
return
}
// UnmarshalSSZ ssz unmarshals the BlindedBlobSidecar object
func (b *BlindedBlobSidecar) UnmarshalSSZ(buf []byte) error {
var err error
size := uint64(len(buf))
if size != 216 {
return ssz.ErrSize
}
// Field (0) 'BlockRoot'
if cap(b.BlockRoot) == 0 {
b.BlockRoot = make([]byte, 0, len(buf[0:32]))
}
b.BlockRoot = append(b.BlockRoot, buf[0:32]...)
// Field (1) 'Index'
b.Index = ssz.UnmarshallUint64(buf[32:40])
// Field (2) 'Slot'
b.Slot = github_com_prysmaticlabs_prysm_v4_consensus_types_primitives.Slot(ssz.UnmarshallUint64(buf[40:48]))
// Field (3) 'BlockParentRoot'
if cap(b.BlockParentRoot) == 0 {
b.BlockParentRoot = make([]byte, 0, len(buf[48:80]))
}
b.BlockParentRoot = append(b.BlockParentRoot, buf[48:80]...)
// Field (4) 'ProposerIndex'
b.ProposerIndex = github_com_prysmaticlabs_prysm_v4_consensus_types_primitives.ValidatorIndex(ssz.UnmarshallUint64(buf[80:88]))
// Field (5) 'BlobRoot'
if cap(b.BlobRoot) == 0 {
b.BlobRoot = make([]byte, 0, len(buf[88:120]))
}
b.BlobRoot = append(b.BlobRoot, buf[88:120]...)
// Field (6) 'KzgCommitment'
if cap(b.KzgCommitment) == 0 {
b.KzgCommitment = make([]byte, 0, len(buf[120:168]))
}
b.KzgCommitment = append(b.KzgCommitment, buf[120:168]...)
// Field (7) 'KzgProof'
if cap(b.KzgProof) == 0 {
b.KzgProof = make([]byte, 0, len(buf[168:216]))
}
b.KzgProof = append(b.KzgProof, buf[168:216]...)
return err
}
// SizeSSZ returns the ssz encoded size in bytes for the BlindedBlobSidecar object
func (b *BlindedBlobSidecar) SizeSSZ() (size int) {
size = 216
return
}
// HashTreeRoot ssz hashes the BlindedBlobSidecar object
func (b *BlindedBlobSidecar) HashTreeRoot() ([32]byte, error) {
return ssz.HashWithDefaultHasher(b)
}
// HashTreeRootWith ssz hashes the BlindedBlobSidecar object with a hasher
func (b *BlindedBlobSidecar) HashTreeRootWith(hh *ssz.Hasher) (err error) {
indx := hh.Index()
// Field (0) 'BlockRoot'
if size := len(b.BlockRoot); size != 32 {
err = ssz.ErrBytesLengthFn("--.BlockRoot", size, 32)
return
}
hh.PutBytes(b.BlockRoot)
// Field (1) 'Index'
hh.PutUint64(b.Index)
// Field (2) 'Slot'
hh.PutUint64(uint64(b.Slot))
// Field (3) 'BlockParentRoot'
if size := len(b.BlockParentRoot); size != 32 {
err = ssz.ErrBytesLengthFn("--.BlockParentRoot", size, 32)
return
}
hh.PutBytes(b.BlockParentRoot)
// Field (4) 'ProposerIndex'
hh.PutUint64(uint64(b.ProposerIndex))
// Field (5) 'BlobRoot'
if size := len(b.BlobRoot); size != 32 {
err = ssz.ErrBytesLengthFn("--.BlobRoot", size, 32)
return
}
hh.PutBytes(b.BlobRoot)
// Field (6) 'KzgCommitment'
if size := len(b.KzgCommitment); size != 48 {
err = ssz.ErrBytesLengthFn("--.KzgCommitment", size, 48)
return
}
hh.PutBytes(b.KzgCommitment)
// Field (7) 'KzgProof'
if size := len(b.KzgProof); size != 48 {
err = ssz.ErrBytesLengthFn("--.KzgProof", size, 48)
return
}
hh.PutBytes(b.KzgProof)
if ssz.EnableVectorizedHTR {
hh.MerkleizeVectorizedHTR(indx)
} else {
hh.Merkleize(indx)
}
return
}
// MarshalSSZ ssz marshals the SignedBlindedBlobSidecar object
func (s *SignedBlindedBlobSidecar) MarshalSSZ() ([]byte, error) {
return ssz.MarshalSSZ(s)
}
// MarshalSSZTo ssz marshals the SignedBlindedBlobSidecar object to a target array
func (s *SignedBlindedBlobSidecar) MarshalSSZTo(buf []byte) (dst []byte, err error) {
dst = buf
// Field (0) 'Message'
if s.Message == nil {
s.Message = new(BlindedBlobSidecar)
}
if dst, err = s.Message.MarshalSSZTo(dst); err != nil {
return
}
// Field (1) 'Signature'
if size := len(s.Signature); size != 96 {
err = ssz.ErrBytesLengthFn("--.Signature", size, 96)
return
}
dst = append(dst, s.Signature...)
return
}
// UnmarshalSSZ ssz unmarshals the SignedBlindedBlobSidecar object
func (s *SignedBlindedBlobSidecar) UnmarshalSSZ(buf []byte) error {
var err error
size := uint64(len(buf))
if size != 312 {
return ssz.ErrSize
}
// Field (0) 'Message'
if s.Message == nil {
s.Message = new(BlindedBlobSidecar)
}
if err = s.Message.UnmarshalSSZ(buf[0:216]); err != nil {
return err
}
// Field (1) 'Signature'
if cap(s.Signature) == 0 {
s.Signature = make([]byte, 0, len(buf[216:312]))
}
s.Signature = append(s.Signature, buf[216:312]...)
return err
}
// SizeSSZ returns the ssz encoded size in bytes for the SignedBlindedBlobSidecar object
func (s *SignedBlindedBlobSidecar) SizeSSZ() (size int) {
size = 312
return
}
// HashTreeRoot ssz hashes the SignedBlindedBlobSidecar object
func (s *SignedBlindedBlobSidecar) HashTreeRoot() ([32]byte, error) {
return ssz.HashWithDefaultHasher(s)
}
// HashTreeRootWith ssz hashes the SignedBlindedBlobSidecar object with a hasher
func (s *SignedBlindedBlobSidecar) HashTreeRootWith(hh *ssz.Hasher) (err error) {
indx := hh.Index()
// Field (0) 'Message'
if err = s.Message.HashTreeRootWith(hh); err != nil {
return
}
// Field (1) 'Signature'
if size := len(s.Signature); size != 96 {
err = ssz.ErrBytesLengthFn("--.Signature", size, 96)
return
}
hh.PutBytes(s.Signature)
if ssz.EnableVectorizedHTR {
hh.MerkleizeVectorizedHTR(indx)
} else {
hh.Merkleize(indx)
}
return
}
// MarshalSSZ ssz marshals the BlobIdentifier object
func (b *BlobIdentifier) MarshalSSZ() ([]byte, error) {
return ssz.MarshalSSZ(b)