mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-08 21:08:10 -05:00
Deneb produce blockv3 (#12708)
Co-authored-by: Radosław Kapka <rkapka@wp.pl>
This commit is contained in:
@@ -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",
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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"
|
||||
)
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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 := ðpbv2.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 := ðpbv2.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 := ðpbv1.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 := ðpbv2.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 := ðpbv2.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 := ðpbv2.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 := ðpbv1.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
@@ -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",
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
444
beacon-chain/rpc/eth/shared/structs_blocks.go
Normal file
444
beacon-chain/rpc/eth/shared/structs_blocks.go
Normal 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"`
|
||||
}
|
||||
3100
beacon-chain/rpc/eth/shared/structs_blocks_conversions.go
Normal file
3100
beacon-chain/rpc/eth/shared/structs_blocks_conversions.go
Normal file
File diff suppressed because it is too large
Load Diff
10
beacon-chain/rpc/eth/shared/testing/BUILD.bazel
Normal file
10
beacon-chain/rpc/eth/shared/testing/BUILD.bazel
Normal 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"],
|
||||
)
|
||||
1487
beacon-chain/rpc/eth/shared/testing/json.go
Normal file
1487
beacon-chain/rpc/eth/shared/testing/json.go
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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",
|
||||
|
||||
426
beacon-chain/rpc/eth/validator/handlers_block.go
Normal file
426
beacon-chain/rpc/eth/validator/handlers_block.go
Normal 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, ð.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,
|
||||
})
|
||||
}
|
||||
587
beacon-chain/rpc/eth/validator/handlers_block_test.go
Normal file
587
beacon-chain/rpc/eth/validator/handlers_block_test.go
Normal 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)
|
||||
})
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -204,32 +204,32 @@ func (vs *Server) GetBeaconBlock(ctx context.Context, req *ethpb.BlockRequest) (
|
||||
Block: pb.(*ethpb.BlindedBeaconBlockDeneb),
|
||||
Blobs: blindBlobs,
|
||||
}
|
||||
return ðpb.GenericBeaconBlock{Block: ðpb.GenericBeaconBlock_BlindedDeneb{BlindedDeneb: blockAndBlobs}}, nil
|
||||
return ðpb.GenericBeaconBlock{Block: ðpb.GenericBeaconBlock_BlindedDeneb{BlindedDeneb: blockAndBlobs}, IsBlinded: true, PayloadValue: sBlk.ValueInGwei()}, nil
|
||||
}
|
||||
|
||||
blockAndBlobs := ðpb.BeaconBlockAndBlobsDeneb{
|
||||
Block: pb.(*ethpb.BeaconBlockDeneb),
|
||||
Blobs: fullBlobs,
|
||||
}
|
||||
return ðpb.GenericBeaconBlock{Block: ðpb.GenericBeaconBlock_Deneb{Deneb: blockAndBlobs}}, nil
|
||||
return ðpb.GenericBeaconBlock{Block: ðpb.GenericBeaconBlock_Deneb{Deneb: blockAndBlobs}, IsBlinded: false, PayloadValue: sBlk.ValueInGwei()}, nil
|
||||
}
|
||||
|
||||
if slots.ToEpoch(req.Slot) >= params.BeaconConfig().CapellaForkEpoch {
|
||||
if sBlk.IsBlinded() {
|
||||
return ðpb.GenericBeaconBlock{Block: ðpb.GenericBeaconBlock_BlindedCapella{BlindedCapella: pb.(*ethpb.BlindedBeaconBlockCapella)}}, nil
|
||||
return ðpb.GenericBeaconBlock{Block: ðpb.GenericBeaconBlock_BlindedCapella{BlindedCapella: pb.(*ethpb.BlindedBeaconBlockCapella)}, IsBlinded: true, PayloadValue: sBlk.ValueInGwei()}, nil
|
||||
}
|
||||
return ðpb.GenericBeaconBlock{Block: ðpb.GenericBeaconBlock_Capella{Capella: pb.(*ethpb.BeaconBlockCapella)}}, nil
|
||||
return ðpb.GenericBeaconBlock{Block: ðpb.GenericBeaconBlock_Capella{Capella: pb.(*ethpb.BeaconBlockCapella)}, IsBlinded: false, PayloadValue: sBlk.ValueInGwei()}, nil
|
||||
}
|
||||
if slots.ToEpoch(req.Slot) >= params.BeaconConfig().BellatrixForkEpoch {
|
||||
if sBlk.IsBlinded() {
|
||||
return ðpb.GenericBeaconBlock{Block: ðpb.GenericBeaconBlock_BlindedBellatrix{BlindedBellatrix: pb.(*ethpb.BlindedBeaconBlockBellatrix)}}, nil
|
||||
return ðpb.GenericBeaconBlock{Block: ðpb.GenericBeaconBlock_BlindedBellatrix{BlindedBellatrix: pb.(*ethpb.BlindedBeaconBlockBellatrix)}, IsBlinded: true, PayloadValue: sBlk.ValueInGwei()}, nil
|
||||
}
|
||||
return ðpb.GenericBeaconBlock{Block: ðpb.GenericBeaconBlock_Bellatrix{Bellatrix: pb.(*ethpb.BeaconBlockBellatrix)}}, nil
|
||||
return ðpb.GenericBeaconBlock{Block: ðpb.GenericBeaconBlock_Bellatrix{Bellatrix: pb.(*ethpb.BeaconBlockBellatrix)}, IsBlinded: false, PayloadValue: sBlk.ValueInGwei()}, nil
|
||||
}
|
||||
if slots.ToEpoch(req.Slot) >= params.BeaconConfig().AltairForkEpoch {
|
||||
return ðpb.GenericBeaconBlock{Block: ðpb.GenericBeaconBlock_Altair{Altair: pb.(*ethpb.BeaconBlockAltair)}}, nil
|
||||
return ðpb.GenericBeaconBlock{Block: ðpb.GenericBeaconBlock_Altair{Altair: pb.(*ethpb.BeaconBlockAltair)}, IsBlinded: false, PayloadValue: 0}, nil
|
||||
}
|
||||
return ðpb.GenericBeaconBlock{Block: ðpb.GenericBeaconBlock_Phase0{Phase0: pb.(*ethpb.BeaconBlock)}}, nil
|
||||
return ðpb.GenericBeaconBlock{Block: ðpb.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) {
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -32,6 +32,7 @@ type ReadOnlySignedBeaconBlock interface {
|
||||
ssz.Unmarshaler
|
||||
Version() int
|
||||
IsBlinded() bool
|
||||
ValueInGwei() uint64
|
||||
Header() (*ethpb.SignedBeaconBlockHeader, error)
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -6,6 +6,7 @@ go_library(
|
||||
"committee_index.go",
|
||||
"domain.go",
|
||||
"epoch.go",
|
||||
"randao.go",
|
||||
"slot.go",
|
||||
"sszbytes.go",
|
||||
"sszuint64.go",
|
||||
|
||||
3
consensus-types/primitives/randao.go
Normal file
3
consensus-types/primitives/randao.go
Normal file
@@ -0,0 +1,3 @@
|
||||
package primitives
|
||||
|
||||
var PointAtInfinity = append([]byte{0xC0}, make([]byte, 95)...)
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Code generated by fastssz. DO NOT EDIT.
|
||||
// Hash: 4140c14176015ace6edb7d8611bd16207ad64fe872f3ea0170279fbde82b5303
|
||||
// Hash: 86494c66845c0e5ec7b1a6c6f0e34a770ce57f86114b161b5e0d8c7b04219b77
|
||||
package enginev1
|
||||
|
||||
import (
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Code generated by fastssz. DO NOT EDIT.
|
||||
// Hash: e48b579f1c4ced0b36ba1329204c668ac6db966ce37b7bda314aabddbd5f1662
|
||||
// Hash: 07349f3ccd696e6980796cf0b8dc149b14d1791dce8dbc553e506af598c11ebb
|
||||
package v1
|
||||
|
||||
import (
|
||||
|
||||
@@ -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"];
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Code generated by fastssz. DO NOT EDIT.
|
||||
// Hash: d835aa3a6a3cf037dfb4ffca7686e527835b94bb660983f23017bdb8a972f81d
|
||||
// Hash: eaf49253855a8c44a53cb851548885777d203c0cdcd3249906ea5f9a7b6e93c6
|
||||
package eth
|
||||
|
||||
import (
|
||||
|
||||
@@ -76,8 +76,12 @@ ssz_gen_marshal(
|
||||
"BlindedBeaconBlockCapella",
|
||||
"BlindedBeaconBlockBodyCapella",
|
||||
"SignedBlindedBeaconBlockDeneb",
|
||||
"BeaconBlockAndBlobsDeneb",
|
||||
"SignedBeaconBlockAndBlobsDeneb",
|
||||
"BlindedBeaconBlockDeneb",
|
||||
"BlindedBeaconBlockBodyDeneb",
|
||||
"SignedBlindedBeaconBlockAndBlobsDeneb",
|
||||
"BlindedBeaconBlockAndBlobsDeneb",
|
||||
"SyncAggregate",
|
||||
"SyncCommitteeMessage",
|
||||
"SyncCommitteeContribution",
|
||||
|
||||
1850
proto/prysm/v1alpha1/beacon_block.pb.go
generated
1850
proto/prysm/v1alpha1/beacon_block.pb.go
generated
File diff suppressed because it is too large
Load Diff
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user