Compare commits

..

14 Commits

Author SHA1 Message Date
terence tsao
d9affb927b Init map 2023-04-05 14:41:58 -07:00
Kasey Kirkham
b3d509a5a1 fixing several initial-sync blob bugs 2023-04-05 16:13:45 -05:00
Kasey Kirkham
a8d154f75e 🤦 2023-04-05 14:39:01 -05:00
Kasey Kirkham
8bd5a265dd unblinded blocks had serious commitment issues 2023-04-05 14:30:04 -05:00
Kasey Kirkham
8dc84411b2 bug fixes and chatty logs 2023-04-04 16:50:52 -05:00
Kasey Kirkham
0d0147b0cb deneb changes for exec engine api
Unblinding blocks without these changes resulted in mtuating the block
type, transforming deneb blocks into capella blocks.
note debug logs in beacon-chain/sync/rpc_chunked_response.go
2023-04-04 15:45:07 -05:00
Kasey Kirkham
60ab9f22c1 simplify batch block logic 2023-04-03 14:34:56 -05:00
Kasey Kirkham
eede6ec2c4 WIP debugging 2023-04-03 13:38:46 -05:00
Kasey Kirkham
bea41af396 fixes 2023-03-31 09:42:23 -05:00
Kasey Kirkham
8a0ef4a85c janky initial-sync blob downloading 2023-03-30 20:39:53 -05:00
terence tsao
7c9bb47f99 Implement send blob by range request 2023-03-30 13:39:54 -05:00
Radosław Kapka
d5dadc75e4 Block rewards API endpoint (#12020)
Co-authored-by: terencechain <terence@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2023-03-30 13:50:33 +02:00
kasey
12d0a4ceeb Separate EE blob type (#12203)
* BlobSidecar.Blob should be a byte slice

* remove engine Blob type from db

---------

Co-authored-by: Kasey Kirkham <kasey@users.noreply.github.com>
2023-03-28 20:12:44 -05:00
terencechain
18743ec30f Blob by root fixes (#12202) 2023-03-28 16:39:30 -07:00
80 changed files with 2222 additions and 2915 deletions

View File

@@ -70,15 +70,16 @@ type Gateway struct {
func New(ctx context.Context, opts ...Option) (*Gateway, error) {
g := &Gateway{
ctx: ctx,
cfg: &config{
router: mux.NewRouter(),
},
cfg: &config{},
}
for _, opt := range opts {
if err := opt(g); err != nil {
return nil, err
}
}
if g.cfg.router == nil {
g.cfg.router = mux.NewRouter()
}
return g, nil
}

View File

@@ -10,11 +10,6 @@ import (
type Option func(g *Gateway) error
func (g *Gateway) SetRouter(r *mux.Router) *Gateway {
g.cfg.router = r
return g
}
func WithPbHandlers(handlers []*PbMux) Option {
return func(g *Gateway) error {
g.cfg.pbHandlers = handlers

View File

@@ -109,7 +109,6 @@ go_test(
"//consensus-types/interfaces:go_default_library",
"//consensus-types/primitives:go_default_library",
"//encoding/bytesutil:go_default_library",
"//proto/engine/v1:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
"//proto/testing:go_default_library",
"//testing/assert:go_default_library",

View File

@@ -11,7 +11,6 @@ import (
"github.com/prysmaticlabs/prysm/v4/config/params"
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
enginev1 "github.com/prysmaticlabs/prysm/v4/proto/engine/v1"
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v4/testing/assertions"
"github.com/prysmaticlabs/prysm/v4/testing/require"
@@ -213,12 +212,9 @@ func generateBlobSidecar(t *testing.T, index uint64) *ethpb.BlobSidecar {
proposerIndex := make([]byte, 8)
_, err = rand.Read(proposerIndex)
require.NoError(t, err)
blobData := make([]byte, 131072)
_, err = rand.Read(blobData)
blob := make([]byte, 131072)
_, err = rand.Read(blob)
require.NoError(t, err)
blob := &enginev1.Blob{
Data: blobData,
}
kzgCommitment := make([]byte, 48)
_, err = rand.Read(kzgCommitment)
require.NoError(t, err)

View File

@@ -141,7 +141,7 @@ func (s *Service) NewPayload(ctx context.Context, payload interfaces.ExecutionDa
return nil, handleRPCError(err)
}
default:
return nil, errors.New("unknown execution data type")
return nil, ErrUnknownExecutionDataType
}
switch result.Status {
@@ -673,7 +673,8 @@ func fullPayloadFromExecutionBlock(
txs[i] = txBin
}
if block.Version == version.Bellatrix {
switch block.Version {
case version.Bellatrix:
return blocks.WrappedExecutionPayload(&pb.ExecutionPayload{
ParentHash: header.ParentHash(),
FeeRecipient: header.FeeRecipient(),
@@ -690,24 +691,51 @@ func fullPayloadFromExecutionBlock(
BlockHash: blockHash[:],
Transactions: txs,
})
case version.Capella:
return blocks.WrappedExecutionPayloadCapella(&pb.ExecutionPayloadCapella{
ParentHash: header.ParentHash(),
FeeRecipient: header.FeeRecipient(),
StateRoot: header.StateRoot(),
ReceiptsRoot: header.ReceiptsRoot(),
LogsBloom: header.LogsBloom(),
PrevRandao: header.PrevRandao(),
BlockNumber: header.BlockNumber(),
GasLimit: header.GasLimit(),
GasUsed: header.GasUsed(),
Timestamp: header.Timestamp(),
ExtraData: header.ExtraData(),
BaseFeePerGas: header.BaseFeePerGas(),
BlockHash: blockHash[:],
Transactions: txs,
Withdrawals: block.Withdrawals,
}, big.NewInt(0)) // We can't get the block value and don't care about the block value for this instance
case version.Deneb:
edg, err := header.ExcessDataGas()
if err != nil {
return nil, errors.Wrap(err, "unable to extract ExcessDataGas attribute from excution payload header")
}
return blocks.WrappedExecutionPayloadDeneb(
&pb.ExecutionPayloadDeneb{
ParentHash: header.ParentHash(),
FeeRecipient: header.FeeRecipient(),
StateRoot: header.StateRoot(),
ReceiptsRoot: header.ReceiptsRoot(),
LogsBloom: header.LogsBloom(),
PrevRandao: header.PrevRandao(),
BlockNumber: header.BlockNumber(),
GasLimit: header.GasLimit(),
GasUsed: header.GasUsed(),
Timestamp: header.Timestamp(),
ExtraData: header.ExtraData(),
BaseFeePerGas: header.BaseFeePerGas(),
BlockHash: blockHash[:],
Transactions: txs,
Withdrawals: block.Withdrawals,
ExcessDataGas: edg,
}, big.NewInt(0))
default:
return nil, errors.Wrapf(ErrUnknownExecutionDataType, "block.version=%d", block.Version)
}
return blocks.WrappedExecutionPayloadCapella(&pb.ExecutionPayloadCapella{
ParentHash: header.ParentHash(),
FeeRecipient: header.FeeRecipient(),
StateRoot: header.StateRoot(),
ReceiptsRoot: header.ReceiptsRoot(),
LogsBloom: header.LogsBloom(),
PrevRandao: header.PrevRandao(),
BlockNumber: header.BlockNumber(),
GasLimit: header.GasLimit(),
GasUsed: header.GasUsed(),
Timestamp: header.Timestamp(),
ExtraData: header.ExtraData(),
BaseFeePerGas: header.BaseFeePerGas(),
BlockHash: blockHash[:],
Transactions: txs,
Withdrawals: block.Withdrawals,
}, big.NewInt(0)) // We can't get the block value and don't care about the block value for this instance
}
// Handles errors received from the RPC server according to the specification.

View File

@@ -36,4 +36,7 @@ var (
ErrNilResponse = errors.New("nil response")
// ErrRequestTooLarge when the request is too large
ErrRequestTooLarge = errors.New("request too large")
// ErrUnknownExecutionDataType is an internal error when an execution payload type is unrecognized,
// making type conversions impossible to do correctly.
ErrUnknownExecutionDataType = errors.New("unknown execution data type")
)

View File

@@ -61,6 +61,7 @@ go_library(
"//runtime/prereqs:go_default_library",
"//runtime/version:go_default_library",
"@com_github_ethereum_go_ethereum//common:go_default_library",
"@com_github_gorilla_mux//:go_default_library",
"@com_github_pkg_errors//:go_default_library",
"@com_github_prometheus_client_golang//prometheus:go_default_library",
"@com_github_prysmaticlabs_fastssz//:go_default_library",

View File

@@ -15,6 +15,7 @@ import (
"syscall"
"github.com/ethereum/go-ethereum/common"
"github.com/gorilla/mux"
"github.com/pkg/errors"
apigateway "github.com/prysmaticlabs/prysm/v4/api/gateway"
"github.com/prysmaticlabs/prysm/v4/async/event"
@@ -253,12 +254,13 @@ func New(cliCtx *cli.Context, opts ...Option) (*BeaconNode, error) {
}
log.Debugln("Registering RPC Service")
if err := beacon.registerRPCService(); err != nil {
router := mux.NewRouter()
if err := beacon.registerRPCService(router); err != nil {
return nil, err
}
log.Debugln("Registering GRPC Gateway Service")
if err := beacon.registerGRPCGateway(); err != nil {
if err := beacon.registerGRPCGateway(router); err != nil {
return nil, err
}
@@ -734,7 +736,7 @@ func (b *BeaconNode) registerSlasherService() error {
return b.services.RegisterService(slasherSrv)
}
func (b *BeaconNode) registerRPCService() error {
func (b *BeaconNode) registerRPCService(router *mux.Router) error {
var chainService *blockchain.Service
if err := b.services.FetchService(&chainService); err != nil {
return err
@@ -830,6 +832,7 @@ func (b *BeaconNode) registerRPCService() error {
MaxMsgSize: maxMsgSize,
ProposerIdsCache: b.proposerIdsCache,
BlockBuilder: b.fetchBuilderService(),
Router: router,
})
return b.services.RegisterService(rpcService)
@@ -858,7 +861,7 @@ func (b *BeaconNode) registerPrometheusService(_ *cli.Context) error {
return b.services.RegisterService(service)
}
func (b *BeaconNode) registerGRPCGateway() error {
func (b *BeaconNode) registerGRPCGateway(router *mux.Router) error {
if b.cliCtx.Bool(flags.DisableGRPCGateway.Name) {
return nil
}
@@ -884,6 +887,7 @@ func (b *BeaconNode) registerGRPCGateway() error {
}
opts := []apigateway.Option{
apigateway.WithRouter(router),
apigateway.WithGatewayAddr(gatewayAddress),
apigateway.WithRemoteAddr(selfAddress),
apigateway.WithPbHandlers(muxs),

View File

@@ -28,12 +28,13 @@ go_library(
"//beacon-chain/rpc/eth/debug:go_default_library",
"//beacon-chain/rpc/eth/events:go_default_library",
"//beacon-chain/rpc/eth/node:go_default_library",
"//beacon-chain/rpc/eth/rewards:go_default_library",
"//beacon-chain/rpc/eth/validator:go_default_library",
"//beacon-chain/rpc/lookup:go_default_library",
"//beacon-chain/rpc/prysm/v1alpha1/beacon:go_default_library",
"//beacon-chain/rpc/prysm/v1alpha1/debug:go_default_library",
"//beacon-chain/rpc/prysm/v1alpha1/node:go_default_library",
"//beacon-chain/rpc/prysm/v1alpha1/validator:go_default_library",
"//beacon-chain/rpc/statefetcher:go_default_library",
"//beacon-chain/slasher:go_default_library",
"//beacon-chain/state/stategen:go_default_library",
"//beacon-chain/sync:go_default_library",
@@ -43,6 +44,7 @@ go_library(
"//monitoring/tracing:go_default_library",
"//proto/eth/service:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
"@com_github_gorilla_mux//:go_default_library",
"@com_github_grpc_ecosystem_go_grpc_middleware//:go_default_library",
"@com_github_grpc_ecosystem_go_grpc_middleware//recovery:go_default_library",
"@com_github_grpc_ecosystem_go_grpc_middleware//tracing/opentracing:go_default_library",
@@ -68,6 +70,7 @@ go_test(
"//beacon-chain/sync/initial-sync/testing:go_default_library",
"//testing/assert:go_default_library",
"//testing/require:go_default_library",
"@com_github_gorilla_mux//:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",
"@com_github_sirupsen_logrus//hooks/test:go_default_library",
],

View File

@@ -34,8 +34,8 @@ go_library(
"//beacon-chain/operations/voluntaryexits:go_default_library",
"//beacon-chain/p2p:go_default_library",
"//beacon-chain/rpc/eth/helpers:go_default_library",
"//beacon-chain/rpc/lookup:go_default_library",
"//beacon-chain/rpc/prysm/v1alpha1/validator:go_default_library",
"//beacon-chain/rpc/statefetcher:go_default_library",
"//beacon-chain/state:go_default_library",
"//beacon-chain/state/state-native:go_default_library",
"//beacon-chain/state/stategen:go_default_library",
@@ -92,7 +92,6 @@ go_test(
"//beacon-chain/core/transition:go_default_library",
"//beacon-chain/db:go_default_library",
"//beacon-chain/db/testing:go_default_library",
"//beacon-chain/execution/testing:go_default_library",
"//beacon-chain/operations/attestations:go_default_library",
"//beacon-chain/operations/blstoexec:go_default_library",
"//beacon-chain/operations/blstoexec/mock:go_default_library",
@@ -101,12 +100,11 @@ go_test(
"//beacon-chain/operations/voluntaryexits/mock:go_default_library",
"//beacon-chain/p2p/testing:go_default_library",
"//beacon-chain/rpc/eth/helpers:go_default_library",
"//beacon-chain/rpc/lookup:go_default_library",
"//beacon-chain/rpc/prysm/v1alpha1/validator:go_default_library",
"//beacon-chain/rpc/statefetcher:go_default_library",
"//beacon-chain/rpc/testutil:go_default_library",
"//beacon-chain/state:go_default_library",
"//beacon-chain/state/state-native:go_default_library",
"//config/features:go_default_library",
"//config/params:go_default_library",
"//consensus-types/blocks:go_default_library",
"//consensus-types/interfaces:go_default_library",

View File

@@ -25,7 +25,7 @@ func (bs *Server) GetBlindedBlock(ctx context.Context, req *ethpbv1.BlockRequest
ctx, span := trace.StartSpan(ctx, "beacon.GetBlindedBlock")
defer span.End()
blk, err := bs.blockFromBlockID(ctx, req.BlockId)
blk, err := bs.Blocker.Block(ctx, req.BlockId)
err = handleGetBlockError(blk, err)
if err != nil {
return nil, err
@@ -80,7 +80,7 @@ func (bs *Server) GetBlindedBlockSSZ(ctx context.Context, req *ethpbv1.BlockRequ
ctx, span := trace.StartSpan(ctx, "beacon.GetBlindedBlockSSZ")
defer span.End()
blk, err := bs.blockFromBlockID(ctx, req.BlockId)
blk, err := bs.Blocker.Block(ctx, req.BlockId)
err = handleGetBlockError(blk, err)
if err != nil {
return nil, err

View File

@@ -2,17 +2,15 @@ package beacon
import (
"context"
"fmt"
"reflect"
"testing"
mock "github.com/prysmaticlabs/prysm/v4/beacon-chain/blockchain/testing"
builderTest "github.com/prysmaticlabs/prysm/v4/beacon-chain/builder/testing"
dbTest "github.com/prysmaticlabs/prysm/v4/beacon-chain/db/testing"
executionTest "github.com/prysmaticlabs/prysm/v4/beacon-chain/execution/testing"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/operations/synccommittee"
mockp2p "github.com/prysmaticlabs/prysm/v4/beacon-chain/p2p/testing"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/prysm/v1alpha1/validator"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/testutil"
"github.com/prysmaticlabs/prysm/v4/config/params"
"github.com/prysmaticlabs/prysm/v4/consensus-types/blocks"
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
@@ -21,7 +19,6 @@ import (
ethpbv1 "github.com/prysmaticlabs/prysm/v4/proto/eth/v1"
ethpbv2 "github.com/prysmaticlabs/prysm/v4/proto/eth/v2"
"github.com/prysmaticlabs/prysm/v4/proto/migration"
ethpbalpha "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v4/testing/assert"
"github.com/prysmaticlabs/prysm/v4/testing/require"
"github.com/prysmaticlabs/prysm/v4/testing/util"
@@ -29,774 +26,284 @@ import (
)
func TestServer_GetBlindedBlock(t *testing.T) {
ctx := context.Background()
t.Run("Phase 0", func(t *testing.T) {
beaconDB := dbTest.SetupDB(t)
ctx := context.Background()
genBlk, blkContainers := fillDBTestBlocks(ctx, t, beaconDB)
canonicalRoots := make(map[[32]byte]bool)
for _, bContr := range blkContainers {
canonicalRoots[bytesutil.ToBytes32(bContr.BlockRoot)] = true
}
headBlock := blkContainers[len(blkContainers)-1]
nextSlot := headBlock.GetPhase0Block().Block.Slot + 1
wsb, err := blocks.NewSignedBeaconBlock(headBlock.Block.(*ethpbalpha.BeaconBlockContainer_Phase0Block).Phase0Block)
b := util.NewBeaconBlock()
blk, err := blocks.NewSignedBeaconBlock(b)
require.NoError(t, err)
mockChainService := &mock.ChainService{
DB: beaconDB,
Block: wsb,
Root: headBlock.BlockRoot,
FinalizedCheckPoint: &ethpbalpha.Checkpoint{Root: blkContainers[64].BlockRoot},
CanonicalRoots: canonicalRoots,
FinalizedRoots: map[[32]byte]bool{},
}
bs := &Server{
BeaconDB: beaconDB,
ChainInfoFetcher: mockChainService,
HeadFetcher: mockChainService,
OptimisticModeFetcher: mockChainService,
FinalizationFetcher: mockChainService,
FinalizationFetcher: &mock.ChainService{},
Blocker: &testutil.MockBlocker{BlockToReturn: blk},
}
root, err := genBlk.Block.HashTreeRoot()
expected, err := migration.V1Alpha1ToV1SignedBlock(b)
require.NoError(t, err)
tests := []struct {
name string
blockID []byte
want *ethpbalpha.SignedBeaconBlock
wantErr bool
}{
{
name: "slot",
blockID: []byte("30"),
want: blkContainers[30].Block.(*ethpbalpha.BeaconBlockContainer_Phase0Block).Phase0Block,
},
{
name: "bad formatting",
blockID: []byte("3bad0"),
wantErr: true,
},
{
name: "canonical",
blockID: []byte("30"),
want: blkContainers[30].Block.(*ethpbalpha.BeaconBlockContainer_Phase0Block).Phase0Block,
},
{
name: "non canonical",
blockID: []byte(fmt.Sprintf("%d", nextSlot)),
wantErr: true,
},
{
name: "head",
blockID: []byte("head"),
want: headBlock.Block.(*ethpbalpha.BeaconBlockContainer_Phase0Block).Phase0Block,
},
{
name: "finalized",
blockID: []byte("finalized"),
want: blkContainers[64].Block.(*ethpbalpha.BeaconBlockContainer_Phase0Block).Phase0Block,
},
{
name: "genesis",
blockID: []byte("genesis"),
want: genBlk,
},
{
name: "genesis root",
blockID: root[:],
want: genBlk,
},
{
name: "root",
blockID: blkContainers[20].BlockRoot,
want: blkContainers[20].Block.(*ethpbalpha.BeaconBlockContainer_Phase0Block).Phase0Block,
},
{
name: "non-existent root",
blockID: bytesutil.PadTo([]byte("hi there"), 32),
wantErr: true,
},
{
name: "no block",
blockID: []byte("105"),
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
blk, err := bs.GetBlindedBlock(ctx, &ethpbv1.BlockRequest{
BlockId: tt.blockID,
})
if tt.wantErr {
require.NotEqual(t, err, nil)
return
}
require.NoError(t, err)
v1Block, err := migration.V1Alpha1ToV1SignedBlock(tt.want)
require.NoError(t, err)
phase0Block, ok := blk.Data.Message.(*ethpbv2.SignedBlindedBeaconBlockContainer_Phase0Block)
require.Equal(t, true, ok)
if !reflect.DeepEqual(phase0Block.Phase0Block, v1Block.Block) {
t.Error("Expected blocks to equal")
}
assert.Equal(t, ethpbv2.Version_PHASE0, blk.Version)
})
}
resp, err := bs.GetBlindedBlock(ctx, &ethpbv1.BlockRequest{})
require.NoError(t, err)
phase0Block, ok := resp.Data.Message.(*ethpbv2.SignedBlindedBeaconBlockContainer_Phase0Block)
require.Equal(t, true, ok)
assert.DeepEqual(t, expected.Block, phase0Block.Phase0Block)
assert.Equal(t, ethpbv2.Version_PHASE0, resp.Version)
})
t.Run("Altair", func(t *testing.T) {
beaconDB := dbTest.SetupDB(t)
ctx := context.Background()
genBlk, blkContainers := fillDBTestBlocksAltair(ctx, t, beaconDB)
canonicalRoots := make(map[[32]byte]bool)
for _, bContr := range blkContainers {
canonicalRoots[bytesutil.ToBytes32(bContr.BlockRoot)] = true
}
headBlock := blkContainers[len(blkContainers)-1]
nextSlot := headBlock.GetAltairBlock().Block.Slot + 1
chainBlk, err := blocks.NewSignedBeaconBlock(headBlock.GetAltairBlock())
b := util.NewBeaconBlockAltair()
blk, err := blocks.NewSignedBeaconBlock(b)
require.NoError(t, err)
mockChainService := &mock.ChainService{
DB: beaconDB,
Block: chainBlk,
Root: headBlock.BlockRoot,
FinalizedCheckPoint: &ethpbalpha.Checkpoint{Root: blkContainers[64].BlockRoot},
CanonicalRoots: canonicalRoots,
FinalizedRoots: map[[32]byte]bool{},
}
bs := &Server{
BeaconDB: beaconDB,
ChainInfoFetcher: mockChainService,
HeadFetcher: mockChainService,
OptimisticModeFetcher: mockChainService,
FinalizationFetcher: mockChainService,
FinalizationFetcher: &mock.ChainService{},
Blocker: &testutil.MockBlocker{BlockToReturn: blk},
}
root, err := genBlk.Block.HashTreeRoot()
expected, err := migration.V1Alpha1BeaconBlockAltairToV2(b.Block)
require.NoError(t, err)
tests := []struct {
name string
blockID []byte
want *ethpbalpha.SignedBeaconBlockAltair
wantErr bool
}{
{
name: "slot",
blockID: []byte("30"),
want: blkContainers[30].GetAltairBlock(),
},
{
name: "bad formatting",
blockID: []byte("3bad0"),
wantErr: true,
},
{
name: "canonical",
blockID: []byte("30"),
want: blkContainers[30].GetAltairBlock(),
},
{
name: "non canonical",
blockID: []byte(fmt.Sprintf("%d", nextSlot)),
wantErr: true,
},
{
name: "head",
blockID: []byte("head"),
want: headBlock.GetAltairBlock(),
},
{
name: "finalized",
blockID: []byte("finalized"),
want: blkContainers[64].GetAltairBlock(),
},
{
name: "genesis",
blockID: []byte("genesis"),
want: genBlk,
},
{
name: "genesis root",
blockID: root[:],
want: genBlk,
},
{
name: "root",
blockID: blkContainers[20].BlockRoot,
want: blkContainers[20].GetAltairBlock(),
},
{
name: "non-existent root",
blockID: bytesutil.PadTo([]byte("hi there"), 32),
wantErr: true,
},
{
name: "no block",
blockID: []byte("105"),
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
blk, err := bs.GetBlindedBlock(ctx, &ethpbv1.BlockRequest{
BlockId: tt.blockID,
})
if tt.wantErr {
require.NotEqual(t, err, nil)
return
}
require.NoError(t, err)
v2Block, err := migration.V1Alpha1BeaconBlockAltairToV2(tt.want.Block)
require.NoError(t, err)
altairBlock, ok := blk.Data.Message.(*ethpbv2.SignedBlindedBeaconBlockContainer_AltairBlock)
require.Equal(t, true, ok)
if !reflect.DeepEqual(altairBlock.AltairBlock, v2Block) {
t.Error("Expected blocks to equal")
}
assert.Equal(t, ethpbv2.Version_ALTAIR, blk.Version)
})
}
resp, err := bs.GetBlindedBlock(ctx, &ethpbv1.BlockRequest{})
require.NoError(t, err)
altairBlock, ok := resp.Data.Message.(*ethpbv2.SignedBlindedBeaconBlockContainer_AltairBlock)
require.Equal(t, true, ok)
assert.DeepEqual(t, expected, altairBlock.AltairBlock)
assert.Equal(t, ethpbv2.Version_ALTAIR, resp.Version)
})
t.Run("Bellatrix", func(t *testing.T) {
beaconDB := dbTest.SetupDB(t)
ctx := context.Background()
genBlk, blkContainers := fillDBTestBlocksBellatrixBlinded(ctx, t, beaconDB)
canonicalRoots := make(map[[32]byte]bool)
for _, bContr := range blkContainers {
canonicalRoots[bytesutil.ToBytes32(bContr.BlockRoot)] = true
}
headBlock := blkContainers[len(blkContainers)-1]
nextSlot := headBlock.GetBlindedBellatrixBlock().Block.Slot + 1
chainBlk, err := blocks.NewSignedBeaconBlock(headBlock.GetBlindedBellatrixBlock())
b := util.NewBlindedBeaconBlockBellatrix()
blk, err := blocks.NewSignedBeaconBlock(b)
require.NoError(t, err)
mockChainService := &mock.ChainService{
DB: beaconDB,
Block: chainBlk,
Root: headBlock.BlockRoot,
FinalizedCheckPoint: &ethpbalpha.Checkpoint{Root: blkContainers[64].BlockRoot},
CanonicalRoots: canonicalRoots,
FinalizedRoots: map[[32]byte]bool{},
}
mockChainService := &mock.ChainService{}
bs := &Server{
BeaconDB: beaconDB,
ChainInfoFetcher: mockChainService,
HeadFetcher: mockChainService,
FinalizationFetcher: mockChainService,
Blocker: &testutil.MockBlocker{BlockToReturn: blk},
OptimisticModeFetcher: mockChainService,
ExecutionPayloadReconstructor: &executionTest.EngineClient{
ExecutionPayloadByBlockHash: map[[32]byte]*enginev1.ExecutionPayload{},
},
FinalizationFetcher: mockChainService,
}
root, err := genBlk.Block.HashTreeRoot()
expected, err := migration.V1Alpha1BeaconBlockBlindedBellatrixToV2Blinded(b.Block)
require.NoError(t, err)
tests := []struct {
name string
blockID []byte
want *ethpbalpha.SignedBlindedBeaconBlockBellatrix
wantErr bool
}{
{
name: "slot",
blockID: []byte("30"),
want: blkContainers[30].GetBlindedBellatrixBlock(),
},
{
name: "bad formatting",
blockID: []byte("3bad0"),
wantErr: true,
},
{
name: "canonical",
blockID: []byte("30"),
want: blkContainers[30].GetBlindedBellatrixBlock(),
},
{
name: "non canonical",
blockID: []byte(fmt.Sprintf("%d", nextSlot)),
wantErr: true,
},
{
name: "head",
blockID: []byte("head"),
want: headBlock.GetBlindedBellatrixBlock(),
},
{
name: "finalized",
blockID: []byte("finalized"),
want: blkContainers[64].GetBlindedBellatrixBlock(),
},
{
name: "genesis",
blockID: []byte("genesis"),
want: genBlk,
},
{
name: "genesis root",
blockID: root[:],
want: genBlk,
},
{
name: "root",
blockID: blkContainers[20].BlockRoot,
want: blkContainers[20].GetBlindedBellatrixBlock(),
},
{
name: "non-existent root",
blockID: bytesutil.PadTo([]byte("hi there"), 32),
wantErr: true,
},
{
name: "no block",
blockID: []byte("105"),
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
blk, err := bs.GetBlindedBlock(ctx, &ethpbv1.BlockRequest{
BlockId: tt.blockID,
})
if tt.wantErr {
require.NotEqual(t, err, nil)
return
}
require.NoError(t, err)
v2Block, err := migration.V1Alpha1BeaconBlockBlindedBellatrixToV2Blinded(tt.want.Block)
require.NoError(t, err)
b, ok := blk.Data.Message.(*ethpbv2.SignedBlindedBeaconBlockContainer_BellatrixBlock)
require.Equal(t, true, ok)
if !reflect.DeepEqual(b.BellatrixBlock, v2Block) {
t.Error("Expected blocks to equal")
}
assert.Equal(t, ethpbv2.Version_BELLATRIX, blk.Version)
})
}
resp, err := bs.GetBlindedBlock(ctx, &ethpbv1.BlockRequest{})
require.NoError(t, err)
bellatrixBlock, ok := resp.Data.Message.(*ethpbv2.SignedBlindedBeaconBlockContainer_BellatrixBlock)
require.Equal(t, true, ok)
assert.DeepEqual(t, expected, bellatrixBlock.BellatrixBlock)
assert.Equal(t, ethpbv2.Version_BELLATRIX, resp.Version)
})
t.Run("Capella", func(t *testing.T) {
beaconDB := dbTest.SetupDB(t)
ctx := context.Background()
genBlk, blkContainers := fillDBTestBlocksCapellaBlinded(ctx, t, beaconDB)
canonicalRoots := make(map[[32]byte]bool)
for _, bContr := range blkContainers {
canonicalRoots[bytesutil.ToBytes32(bContr.BlockRoot)] = true
}
headBlock := blkContainers[len(blkContainers)-1]
nextSlot := headBlock.GetBlindedCapellaBlock().Block.Slot + 1
chainBlk, err := blocks.NewSignedBeaconBlock(headBlock.GetBlindedCapellaBlock())
b := util.NewBlindedBeaconBlockCapella()
blk, err := blocks.NewSignedBeaconBlock(b)
require.NoError(t, err)
mockChainService := &mock.ChainService{
DB: beaconDB,
Block: chainBlk,
Root: headBlock.BlockRoot,
FinalizedCheckPoint: &ethpbalpha.Checkpoint{Root: blkContainers[64].BlockRoot},
CanonicalRoots: canonicalRoots,
FinalizedRoots: map[[32]byte]bool{},
}
mockChainService := &mock.ChainService{}
bs := &Server{
BeaconDB: beaconDB,
ChainInfoFetcher: mockChainService,
HeadFetcher: mockChainService,
FinalizationFetcher: mockChainService,
Blocker: &testutil.MockBlocker{BlockToReturn: blk},
OptimisticModeFetcher: mockChainService,
ExecutionPayloadReconstructor: &executionTest.EngineClient{
ExecutionPayloadByBlockHash: map[[32]byte]*enginev1.ExecutionPayload{},
},
FinalizationFetcher: mockChainService,
}
root, err := genBlk.Block.HashTreeRoot()
expected, err := migration.V1Alpha1BeaconBlockBlindedCapellaToV2Blinded(b.Block)
require.NoError(t, err)
tests := []struct {
name string
blockID []byte
want *ethpbalpha.SignedBlindedBeaconBlockCapella
wantErr bool
}{
{
name: "slot",
blockID: []byte("30"),
want: blkContainers[30].GetBlindedCapellaBlock(),
},
{
name: "bad formatting",
blockID: []byte("3bad0"),
wantErr: true,
},
{
name: "canonical",
blockID: []byte("30"),
want: blkContainers[30].GetBlindedCapellaBlock(),
},
{
name: "non canonical",
blockID: []byte(fmt.Sprintf("%d", nextSlot)),
wantErr: true,
},
{
name: "head",
blockID: []byte("head"),
want: headBlock.GetBlindedCapellaBlock(),
},
{
name: "finalized",
blockID: []byte("finalized"),
want: blkContainers[64].GetBlindedCapellaBlock(),
},
{
name: "genesis",
blockID: []byte("genesis"),
want: genBlk,
},
{
name: "genesis root",
blockID: root[:],
want: genBlk,
},
{
name: "root",
blockID: blkContainers[20].BlockRoot,
want: blkContainers[20].GetBlindedCapellaBlock(),
},
{
name: "non-existent root",
blockID: bytesutil.PadTo([]byte("hi there"), 32),
wantErr: true,
},
{
name: "no block",
blockID: []byte("105"),
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
blk, err := bs.GetBlindedBlock(ctx, &ethpbv1.BlockRequest{
BlockId: tt.blockID,
})
if tt.wantErr {
require.NotEqual(t, err, nil)
return
}
require.NoError(t, err)
v2Block, err := migration.V1Alpha1BeaconBlockBlindedCapellaToV2Blinded(tt.want.Block)
require.NoError(t, err)
b, ok := blk.Data.Message.(*ethpbv2.SignedBlindedBeaconBlockContainer_CapellaBlock)
require.Equal(t, true, ok)
if !reflect.DeepEqual(b.CapellaBlock, v2Block) {
t.Error("Expected blocks to equal")
}
assert.Equal(t, ethpbv2.Version_CAPELLA, blk.Version)
})
}
resp, err := bs.GetBlindedBlock(ctx, &ethpbv1.BlockRequest{})
require.NoError(t, err)
capellaBlock, ok := resp.Data.Message.(*ethpbv2.SignedBlindedBeaconBlockContainer_CapellaBlock)
require.Equal(t, true, ok)
assert.DeepEqual(t, expected, capellaBlock.CapellaBlock)
assert.Equal(t, ethpbv2.Version_CAPELLA, resp.Version)
})
t.Run("execution optimistic", func(t *testing.T) {
beaconDB := dbTest.SetupDB(t)
ctx := context.Background()
_, blkContainers := fillDBTestBlocksBellatrix(ctx, t, beaconDB)
headBlock := blkContainers[len(blkContainers)-1]
chainBlk, err := blocks.NewSignedBeaconBlock(headBlock.GetBellatrixBlock())
b := util.NewBlindedBeaconBlockBellatrix()
blk, err := blocks.NewSignedBeaconBlock(b)
require.NoError(t, err)
r, err := blk.Block().HashTreeRoot()
require.NoError(t, err)
mockChainService := &mock.ChainService{
DB: beaconDB,
Block: chainBlk,
Root: headBlock.BlockRoot,
FinalizedCheckPoint: &ethpbalpha.Checkpoint{Root: blkContainers[64].BlockRoot},
FinalizedRoots: map[[32]byte]bool{},
OptimisticRoots: map[[32]byte]bool{
bytesutil.ToBytes32(headBlock.BlockRoot): true,
},
OptimisticRoots: map[[32]byte]bool{r: true},
}
bs := &Server{
BeaconDB: beaconDB,
ChainInfoFetcher: mockChainService,
HeadFetcher: mockChainService,
OptimisticModeFetcher: mockChainService,
FinalizationFetcher: mockChainService,
Blocker: &testutil.MockBlocker{BlockToReturn: blk},
OptimisticModeFetcher: mockChainService,
}
blk, err := bs.GetBlindedBlock(ctx, &ethpbv1.BlockRequest{
BlockId: []byte("head"),
})
resp, err := bs.GetBlindedBlock(ctx, &ethpbv1.BlockRequest{})
require.NoError(t, err)
assert.Equal(t, true, blk.ExecutionOptimistic)
assert.Equal(t, true, resp.ExecutionOptimistic)
})
t.Run("finalized", func(t *testing.T) {
beaconDB := dbTest.SetupDB(t)
ctx := context.Background()
_, blkContainers := fillDBTestBlocks(ctx, t, beaconDB)
headBlock := blkContainers[len(blkContainers)-1]
chainBlk, err := blocks.NewSignedBeaconBlock(headBlock.GetPhase0Block())
b := util.NewBeaconBlock()
blk, err := blocks.NewSignedBeaconBlock(b)
require.NoError(t, err)
root, err := blk.Block().HashTreeRoot()
require.NoError(t, err)
mockChainService := &mock.ChainService{
DB: beaconDB,
Block: chainBlk,
Root: headBlock.BlockRoot,
FinalizedCheckPoint: &ethpbalpha.Checkpoint{Root: blkContainers[64].BlockRoot},
Optimistic: true,
FinalizedRoots: map[[32]byte]bool{
bytesutil.ToBytes32(blkContainers[32].BlockRoot): true,
bytesutil.ToBytes32(blkContainers[64].BlockRoot): false,
},
FinalizedRoots: map[[32]byte]bool{root: true},
}
bs := &Server{
BeaconDB: beaconDB,
ChainInfoFetcher: mockChainService,
HeadFetcher: mockChainService,
OptimisticModeFetcher: mockChainService,
FinalizationFetcher: mockChainService,
FinalizationFetcher: mockChainService,
Blocker: &testutil.MockBlocker{BlockToReturn: blk},
}
t.Run("true", func(t *testing.T) {
blk, err := bs.GetBlindedBlock(ctx, &ethpbv1.BlockRequest{
BlockId: []byte("32"),
})
require.NoError(t, err)
assert.Equal(t, true, blk.Finalized)
})
t.Run("false", func(t *testing.T) {
blk, err := bs.GetBlindedBlock(ctx, &ethpbv1.BlockRequest{
BlockId: []byte("64"),
})
require.NoError(t, err)
assert.Equal(t, false, blk.Finalized)
})
resp, err := bs.GetBlindedBlock(ctx, &ethpbv1.BlockRequest{BlockId: root[:]})
require.NoError(t, err)
assert.Equal(t, true, resp.Finalized)
})
t.Run("not finalized", func(t *testing.T) {
b := util.NewBeaconBlock()
blk, err := blocks.NewSignedBeaconBlock(b)
require.NoError(t, err)
root, err := blk.Block().HashTreeRoot()
require.NoError(t, err)
mockChainService := &mock.ChainService{
FinalizedRoots: map[[32]byte]bool{root: false},
}
bs := &Server{
FinalizationFetcher: mockChainService,
Blocker: &testutil.MockBlocker{BlockToReturn: blk},
}
resp, err := bs.GetBlindedBlock(ctx, &ethpbv1.BlockRequest{BlockId: root[:]})
require.NoError(t, err)
assert.Equal(t, false, resp.Finalized)
})
}
func TestServer_GetBlindedBlockSSZ(t *testing.T) {
ctx := context.Background()
t.Run("Phase 0", func(t *testing.T) {
beaconDB := dbTest.SetupDB(t)
ctx := context.Background()
_, blkContainers := fillDBTestBlocks(ctx, t, beaconDB)
headBlock := blkContainers[len(blkContainers)-1]
wsb, err := blocks.NewSignedBeaconBlock(headBlock.Block.(*ethpbalpha.BeaconBlockContainer_Phase0Block).Phase0Block)
b := util.NewBeaconBlock()
blk, err := blocks.NewSignedBeaconBlock(b)
require.NoError(t, err)
mockChainService := &mock.ChainService{
DB: beaconDB,
Block: wsb,
Root: headBlock.BlockRoot,
FinalizedCheckPoint: &ethpbalpha.Checkpoint{Root: blkContainers[64].BlockRoot},
FinalizedRoots: map[[32]byte]bool{},
}
bs := &Server{
BeaconDB: beaconDB,
ChainInfoFetcher: mockChainService,
FinalizationFetcher: mockChainService,
FinalizationFetcher: &mock.ChainService{},
Blocker: &testutil.MockBlocker{BlockToReturn: blk},
}
blks, err := beaconDB.BlocksBySlot(ctx, 30)
require.Equal(t, true, len(blks) > 0)
expected, err := blk.MarshalSSZ()
require.NoError(t, err)
sszBlock, err := blks[0].MarshalSSZ()
require.NoError(t, err)
resp, err := bs.GetBlindedBlockSSZ(ctx, &ethpbv1.BlockRequest{BlockId: []byte("30")})
resp, err := bs.GetBlindedBlockSSZ(ctx, &ethpbv1.BlockRequest{})
require.NoError(t, err)
assert.NotNil(t, resp)
assert.DeepEqual(t, sszBlock, resp.Data)
assert.DeepEqual(t, expected, resp.Data)
assert.Equal(t, ethpbv2.Version_PHASE0, resp.Version)
})
t.Run("Altair", func(t *testing.T) {
beaconDB := dbTest.SetupDB(t)
ctx := context.Background()
_, blkContainers := fillDBTestBlocksAltair(ctx, t, beaconDB)
headBlock := blkContainers[len(blkContainers)-1]
chainBlk, err := blocks.NewSignedBeaconBlock(headBlock.GetAltairBlock())
b := util.NewBeaconBlockAltair()
blk, err := blocks.NewSignedBeaconBlock(b)
require.NoError(t, err)
mockChainService := &mock.ChainService{
DB: beaconDB,
Block: chainBlk,
Root: headBlock.BlockRoot,
FinalizedCheckPoint: &ethpbalpha.Checkpoint{Root: blkContainers[64].BlockRoot},
FinalizedRoots: map[[32]byte]bool{},
}
bs := &Server{
BeaconDB: beaconDB,
ChainInfoFetcher: mockChainService,
FinalizationFetcher: mockChainService,
FinalizationFetcher: &mock.ChainService{},
Blocker: &testutil.MockBlocker{BlockToReturn: blk},
}
blks, err := beaconDB.BlocksBySlot(ctx, 30)
require.Equal(t, true, len(blks) > 0)
expected, err := blk.MarshalSSZ()
require.NoError(t, err)
sszBlock, err := blks[0].MarshalSSZ()
require.NoError(t, err)
resp, err := bs.GetBlindedBlockSSZ(ctx, &ethpbv1.BlockRequest{BlockId: []byte("30")})
resp, err := bs.GetBlindedBlockSSZ(ctx, &ethpbv1.BlockRequest{})
require.NoError(t, err)
assert.NotNil(t, resp)
assert.DeepEqual(t, sszBlock, resp.Data)
assert.DeepEqual(t, expected, resp.Data)
assert.Equal(t, ethpbv2.Version_ALTAIR, resp.Version)
})
t.Run("Bellatrix", func(t *testing.T) {
beaconDB := dbTest.SetupDB(t)
ctx := context.Background()
_, blkContainers := fillDBTestBlocksBellatrixBlinded(ctx, t, beaconDB)
headBlock := blkContainers[len(blkContainers)-1]
chainBlk, err := blocks.NewSignedBeaconBlock(headBlock.GetBlindedBellatrixBlock())
b := util.NewBlindedBeaconBlockBellatrix()
blk, err := blocks.NewSignedBeaconBlock(b)
require.NoError(t, err)
mockChainService := &mock.ChainService{
DB: beaconDB,
Block: chainBlk,
Root: headBlock.BlockRoot,
FinalizedCheckPoint: &ethpbalpha.Checkpoint{Root: blkContainers[64].BlockRoot},
FinalizedRoots: map[[32]byte]bool{},
}
mockChainService := &mock.ChainService{}
bs := &Server{
BeaconDB: beaconDB,
ChainInfoFetcher: mockChainService,
OptimisticModeFetcher: mockChainService,
FinalizationFetcher: mockChainService,
Blocker: &testutil.MockBlocker{BlockToReturn: blk},
OptimisticModeFetcher: mockChainService,
}
blks, err := beaconDB.BlocksBySlot(ctx, 30)
require.Equal(t, true, len(blks) > 0)
expected, err := blk.MarshalSSZ()
require.NoError(t, err)
sszBlock, err := blks[0].MarshalSSZ()
require.NoError(t, err)
resp, err := bs.GetBlindedBlockSSZ(ctx, &ethpbv1.BlockRequest{BlockId: []byte("30")})
resp, err := bs.GetBlindedBlockSSZ(ctx, &ethpbv1.BlockRequest{})
require.NoError(t, err)
assert.NotNil(t, resp)
assert.DeepEqual(t, sszBlock, resp.Data)
assert.DeepEqual(t, expected, resp.Data)
assert.Equal(t, ethpbv2.Version_BELLATRIX, resp.Version)
})
t.Run("Capella", func(t *testing.T) {
beaconDB := dbTest.SetupDB(t)
ctx := context.Background()
_, blkContainers := fillDBTestBlocksCapellaBlinded(ctx, t, beaconDB)
headBlock := blkContainers[len(blkContainers)-1]
chainBlk, err := blocks.NewSignedBeaconBlock(headBlock.GetBlindedCapellaBlock())
b := util.NewBlindedBeaconBlockCapella()
blk, err := blocks.NewSignedBeaconBlock(b)
require.NoError(t, err)
mockChainService := &mock.ChainService{
DB: beaconDB,
Block: chainBlk,
Root: headBlock.BlockRoot,
FinalizedCheckPoint: &ethpbalpha.Checkpoint{Root: blkContainers[64].BlockRoot},
FinalizedRoots: map[[32]byte]bool{},
}
mockChainService := &mock.ChainService{}
bs := &Server{
BeaconDB: beaconDB,
ChainInfoFetcher: mockChainService,
OptimisticModeFetcher: mockChainService,
FinalizationFetcher: mockChainService,
Blocker: &testutil.MockBlocker{BlockToReturn: blk},
OptimisticModeFetcher: mockChainService,
}
blks, err := beaconDB.BlocksBySlot(ctx, 30)
require.Equal(t, true, len(blks) > 0)
expected, err := blk.MarshalSSZ()
require.NoError(t, err)
sszBlock, err := blks[0].MarshalSSZ()
require.NoError(t, err)
resp, err := bs.GetBlindedBlockSSZ(ctx, &ethpbv1.BlockRequest{BlockId: []byte("30")})
resp, err := bs.GetBlindedBlockSSZ(ctx, &ethpbv1.BlockRequest{})
require.NoError(t, err)
assert.NotNil(t, resp)
assert.DeepEqual(t, sszBlock, resp.Data)
assert.DeepEqual(t, expected, resp.Data)
assert.Equal(t, ethpbv2.Version_CAPELLA, resp.Version)
})
t.Run("execution optimistic", func(t *testing.T) {
beaconDB := dbTest.SetupDB(t)
ctx := context.Background()
_, blkContainers := fillDBTestBlocksBellatrix(ctx, t, beaconDB)
headBlock := blkContainers[len(blkContainers)-1]
chainBlk, err := blocks.NewSignedBeaconBlock(headBlock.GetBellatrixBlock())
b := util.NewBlindedBeaconBlockBellatrix()
blk, err := blocks.NewSignedBeaconBlock(b)
require.NoError(t, err)
r, err := blk.Block().HashTreeRoot()
require.NoError(t, err)
mockChainService := &mock.ChainService{
DB: beaconDB,
Block: chainBlk,
Root: headBlock.BlockRoot,
FinalizedCheckPoint: &ethpbalpha.Checkpoint{Root: blkContainers[64].BlockRoot},
FinalizedRoots: map[[32]byte]bool{},
OptimisticRoots: map[[32]byte]bool{
bytesutil.ToBytes32(headBlock.BlockRoot): true,
},
OptimisticRoots: map[[32]byte]bool{r: true},
}
bs := &Server{
BeaconDB: beaconDB,
ChainInfoFetcher: mockChainService,
HeadFetcher: mockChainService,
OptimisticModeFetcher: mockChainService,
FinalizationFetcher: mockChainService,
Blocker: &testutil.MockBlocker{BlockToReturn: blk},
OptimisticModeFetcher: mockChainService,
}
blk, err := bs.GetBlindedBlockSSZ(ctx, &ethpbv1.BlockRequest{
BlockId: []byte("head"),
})
resp, err := bs.GetBlindedBlockSSZ(ctx, &ethpbv1.BlockRequest{})
require.NoError(t, err)
assert.Equal(t, true, blk.ExecutionOptimistic)
assert.Equal(t, true, resp.ExecutionOptimistic)
})
t.Run("finalized", func(t *testing.T) {
beaconDB := dbTest.SetupDB(t)
ctx := context.Background()
_, blkContainers := fillDBTestBlocks(ctx, t, beaconDB)
headBlock := blkContainers[len(blkContainers)-1]
chainBlk, err := blocks.NewSignedBeaconBlock(headBlock.GetPhase0Block())
b := util.NewBeaconBlock()
blk, err := blocks.NewSignedBeaconBlock(b)
require.NoError(t, err)
root, err := blk.Block().HashTreeRoot()
require.NoError(t, err)
mockChainService := &mock.ChainService{
DB: beaconDB,
Block: chainBlk,
Root: headBlock.BlockRoot,
FinalizedCheckPoint: &ethpbalpha.Checkpoint{Root: blkContainers[64].BlockRoot},
Optimistic: true,
FinalizedRoots: map[[32]byte]bool{
bytesutil.ToBytes32(blkContainers[32].BlockRoot): true,
bytesutil.ToBytes32(blkContainers[64].BlockRoot): false,
},
FinalizedRoots: map[[32]byte]bool{root: true},
}
bs := &Server{
BeaconDB: beaconDB,
ChainInfoFetcher: mockChainService,
HeadFetcher: mockChainService,
OptimisticModeFetcher: mockChainService,
FinalizationFetcher: mockChainService,
FinalizationFetcher: mockChainService,
Blocker: &testutil.MockBlocker{BlockToReturn: blk},
}
t.Run("true", func(t *testing.T) {
blk, err := bs.GetBlindedBlockSSZ(ctx, &ethpbv1.BlockRequest{
BlockId: []byte("32"),
})
require.NoError(t, err)
assert.Equal(t, true, blk.Finalized)
})
t.Run("false", func(t *testing.T) {
blk, err := bs.GetBlindedBlockSSZ(ctx, &ethpbv1.BlockRequest{
BlockId: []byte("64"),
})
require.NoError(t, err)
assert.Equal(t, false, blk.Finalized)
})
resp, err := bs.GetBlindedBlockSSZ(ctx, &ethpbv1.BlockRequest{BlockId: root[:]})
require.NoError(t, err)
assert.Equal(t, true, resp.Finalized)
})
t.Run("not finalized", func(t *testing.T) {
b := util.NewBeaconBlock()
blk, err := blocks.NewSignedBeaconBlock(b)
require.NoError(t, err)
root, err := blk.Block().HashTreeRoot()
require.NoError(t, err)
mockChainService := &mock.ChainService{
FinalizedRoots: map[[32]byte]bool{root: false},
}
bs := &Server{
FinalizationFetcher: mockChainService,
Blocker: &testutil.MockBlocker{BlockToReturn: blk},
}
resp, err := bs.GetBlindedBlockSSZ(ctx, &ethpbv1.BlockRequest{BlockId: root[:]})
require.NoError(t, err)
assert.Equal(t, false, resp.Finalized)
})
}

View File

@@ -12,6 +12,7 @@ import (
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/db/filters"
rpchelpers "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/helpers"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/lookup"
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
"github.com/prysmaticlabs/prysm/v4/config/params"
"github.com/prysmaticlabs/prysm/v4/consensus-types/blocks"
@@ -37,23 +38,6 @@ var (
errNilBlock = errors.New("nil block")
)
// blockIdParseError represents an error scenario where a block ID could not be parsed.
type blockIdParseError struct {
message string
}
// newBlockIdParseError creates a new error instance.
func newBlockIdParseError(reason error) blockIdParseError {
return blockIdParseError{
message: errors.Wrapf(reason, "could not parse block ID").Error(),
}
}
// Error returns the underlying error message.
func (e *blockIdParseError) Error() string {
return e.message
}
// GetWeakSubjectivity computes the starting epoch of the current weak subjectivity period, and then also
// determines the best block root and state root to use for a Checkpoint Sync starting from that point.
// DEPRECATED: GetWeakSubjectivity endpoint will no longer be supported
@@ -101,7 +85,7 @@ func (bs *Server) GetBlockHeader(ctx context.Context, req *ethpbv1.BlockRequest)
ctx, span := trace.StartSpan(ctx, "beacon.GetBlockHeader")
defer span.End()
blk, err := bs.blockFromBlockID(ctx, req.BlockId)
blk, err := bs.Blocker.Block(ctx, req.BlockId)
err = handleGetBlockError(blk, err)
if err != nil {
return nil, err
@@ -290,7 +274,7 @@ func (bs *Server) GetBlock(ctx context.Context, req *ethpbv1.BlockRequest) (*eth
ctx, span := trace.StartSpan(ctx, "beacon.GetBlock")
defer span.End()
blk, err := bs.blockFromBlockID(ctx, req.BlockId)
blk, err := bs.Blocker.Block(ctx, req.BlockId)
err = handleGetBlockError(blk, err)
if err != nil {
return nil, err
@@ -314,7 +298,7 @@ func (bs *Server) GetBlockSSZ(ctx context.Context, req *ethpbv1.BlockRequest) (*
ctx, span := trace.StartSpan(ctx, "beacon.GetBlockSSZ")
defer span.End()
blk, err := bs.blockFromBlockID(ctx, req.BlockId)
blk, err := bs.Blocker.Block(ctx, req.BlockId)
err = handleGetBlockError(blk, err)
if err != nil {
return nil, err
@@ -336,7 +320,7 @@ func (bs *Server) GetBlockV2(ctx context.Context, req *ethpbv2.BlockRequestV2) (
ctx, span := trace.StartSpan(ctx, "beacon.GetBlockV2")
defer span.End()
blk, err := bs.blockFromBlockID(ctx, req.BlockId)
blk, err := bs.Blocker.Block(ctx, req.BlockId)
err = handleGetBlockError(blk, err)
if err != nil {
return nil, err
@@ -398,7 +382,7 @@ func (bs *Server) GetBlockSSZV2(ctx context.Context, req *ethpbv2.BlockRequestV2
ctx, span := trace.StartSpan(ctx, "beacon.GetBlockSSZV2")
defer span.End()
blk, err := bs.blockFromBlockID(ctx, req.BlockId)
blk, err := bs.Blocker.Block(ctx, req.BlockId)
err = handleGetBlockError(blk, err)
if err != nil {
return nil, err
@@ -548,7 +532,7 @@ func (bs *Server) ListBlockAttestations(ctx context.Context, req *ethpbv1.BlockR
ctx, span := trace.StartSpan(ctx, "beacon.ListBlockAttestations")
defer span.End()
blk, err := bs.blockFromBlockID(ctx, req.BlockId)
blk, err := bs.Blocker.Block(ctx, req.BlockId)
err = handleGetBlockError(blk, err)
if err != nil {
return nil, err
@@ -575,68 +559,8 @@ func (bs *Server) ListBlockAttestations(ctx context.Context, req *ethpbv1.BlockR
}, nil
}
func (bs *Server) blockFromBlockID(ctx context.Context, blockId []byte) (interfaces.ReadOnlySignedBeaconBlock, error) {
var err error
var blk interfaces.ReadOnlySignedBeaconBlock
switch string(blockId) {
case "head":
blk, err = bs.ChainInfoFetcher.HeadBlock(ctx)
if err != nil {
return nil, errors.Wrap(err, "could not retrieve head block")
}
case "finalized":
finalized := bs.ChainInfoFetcher.FinalizedCheckpt()
finalizedRoot := bytesutil.ToBytes32(finalized.Root)
blk, err = bs.BeaconDB.Block(ctx, finalizedRoot)
if err != nil {
return nil, errors.New("could not get finalized block from db")
}
case "genesis":
blk, err = bs.BeaconDB.GenesisBlock(ctx)
if err != nil {
return nil, errors.Wrap(err, "could not retrieve blocks for genesis slot")
}
default:
if len(blockId) == 32 {
blk, err = bs.BeaconDB.Block(ctx, bytesutil.ToBytes32(blockId))
if err != nil {
return nil, errors.Wrap(err, "could not retrieve block")
}
} else {
slot, err := strconv.ParseUint(string(blockId), 10, 64)
if err != nil {
e := newBlockIdParseError(err)
return nil, &e
}
blks, err := bs.BeaconDB.BlocksBySlot(ctx, primitives.Slot(slot))
if err != nil {
return nil, errors.Wrapf(err, "could not retrieve blocks for slot %d", slot)
}
_, roots, err := bs.BeaconDB.BlockRootsBySlot(ctx, primitives.Slot(slot))
if err != nil {
return nil, errors.Wrapf(err, "could not retrieve block roots for slot %d", slot)
}
numBlks := len(blks)
if numBlks == 0 {
return nil, nil
}
for i, b := range blks {
canonical, err := bs.ChainInfoFetcher.IsCanonical(ctx, roots[i])
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not determine if block root is canonical: %v", err)
}
if canonical {
blk = b
break
}
}
}
}
return blk, nil
}
func handleGetBlockError(blk interfaces.ReadOnlySignedBeaconBlock, err error) error {
if invalidBlockIdErr, ok := err.(*blockIdParseError); ok {
if invalidBlockIdErr, ok := err.(*lookup.BlockIdParseError); ok {
return status.Errorf(codes.InvalidArgument, "Invalid block ID: %v", invalidBlockIdErr)
}
if err != nil {

File diff suppressed because it is too large Load Diff

View File

@@ -14,8 +14,8 @@ import (
"github.com/prysmaticlabs/prysm/v4/beacon-chain/operations/slashings"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/operations/voluntaryexits"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/p2p"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/lookup"
v1alpha1validator "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/prysm/v1alpha1/validator"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/statefetcher"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state/stategen"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/sync"
)
@@ -34,7 +34,8 @@ type Server struct {
SlashingsPool slashings.PoolManager
VoluntaryExitsPool voluntaryexits.PoolManager
StateGenService stategen.StateManager
StateFetcher statefetcher.Fetcher
Stater lookup.Stater
Blocker lookup.Blocker
HeadFetcher blockchain.HeadFetcher
OptimisticModeFetcher blockchain.OptimisticModeFetcher
V1Alpha1ValidatorServer *v1alpha1validator.Server

View File

@@ -6,7 +6,7 @@ import (
"strconv"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/helpers"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/statefetcher"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/lookup"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state"
"github.com/prysmaticlabs/prysm/v4/config/params"
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
@@ -58,20 +58,20 @@ func (bs *Server) GetStateRoot(ctx context.Context, req *ethpb.StateRequest) (*e
ctx, span := trace.StartSpan(ctx, "beacon.GetStateRoot")
defer span.End()
stateRoot, err := bs.StateFetcher.StateRoot(ctx, req.StateId)
stateRoot, err := bs.Stater.StateRoot(ctx, req.StateId)
if err != nil {
if rootNotFoundErr, ok := err.(*statefetcher.StateRootNotFoundError); ok {
if rootNotFoundErr, ok := err.(*lookup.StateRootNotFoundError); ok {
return nil, status.Errorf(codes.NotFound, "State root not found: %v", rootNotFoundErr)
} else if parseErr, ok := err.(*statefetcher.StateIdParseError); ok {
} else if parseErr, ok := err.(*lookup.StateIdParseError); ok {
return nil, status.Errorf(codes.InvalidArgument, "Invalid state ID: %v", parseErr)
}
return nil, status.Errorf(codes.Internal, "Could not get state root: %v", err)
}
st, err := bs.StateFetcher.State(ctx, req.StateId)
st, err := bs.Stater.State(ctx, req.StateId)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not get state: %v", err)
}
isOptimistic, err := helpers.IsOptimistic(ctx, req.StateId, bs.OptimisticModeFetcher, bs.StateFetcher, bs.ChainInfoFetcher, bs.BeaconDB)
isOptimistic, err := helpers.IsOptimistic(ctx, req.StateId, bs.OptimisticModeFetcher, bs.Stater, bs.ChainInfoFetcher, bs.BeaconDB)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not check if slot's block is optimistic: %v", err)
}
@@ -95,12 +95,12 @@ func (bs *Server) GetStateFork(ctx context.Context, req *ethpb.StateRequest) (*e
ctx, span := trace.StartSpan(ctx, "beacon.GetStateFork")
defer span.End()
st, err := bs.StateFetcher.State(ctx, req.StateId)
st, err := bs.Stater.State(ctx, req.StateId)
if err != nil {
return nil, helpers.PrepareStateFetchGRPCError(err)
}
fork := st.Fork()
isOptimistic, err := helpers.IsOptimistic(ctx, req.StateId, bs.OptimisticModeFetcher, bs.StateFetcher, bs.ChainInfoFetcher, bs.BeaconDB)
isOptimistic, err := helpers.IsOptimistic(ctx, req.StateId, bs.OptimisticModeFetcher, bs.Stater, bs.ChainInfoFetcher, bs.BeaconDB)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not check if slot's block is optimistic: %v", err)
}
@@ -127,11 +127,11 @@ func (bs *Server) GetFinalityCheckpoints(ctx context.Context, req *ethpb.StateRe
ctx, span := trace.StartSpan(ctx, "beacon.GetFinalityCheckpoints")
defer span.End()
st, err := bs.StateFetcher.State(ctx, req.StateId)
st, err := bs.Stater.State(ctx, req.StateId)
if err != nil {
return nil, helpers.PrepareStateFetchGRPCError(err)
}
isOptimistic, err := helpers.IsOptimistic(ctx, req.StateId, bs.OptimisticModeFetcher, bs.StateFetcher, bs.ChainInfoFetcher, bs.BeaconDB)
isOptimistic, err := helpers.IsOptimistic(ctx, req.StateId, bs.OptimisticModeFetcher, bs.Stater, bs.ChainInfoFetcher, bs.BeaconDB)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not check if slot's block is optimistic: %v", err)
}
@@ -160,7 +160,7 @@ func (bs *Server) GetRandao(ctx context.Context, req *eth2.RandaoRequest) (*eth2
ctx, span := trace.StartSpan(ctx, "beacon.GetRandao")
defer span.End()
st, err := bs.StateFetcher.State(ctx, req.StateId)
st, err := bs.Stater.State(ctx, req.StateId)
if err != nil {
return nil, helpers.PrepareStateFetchGRPCError(err)
}
@@ -186,7 +186,7 @@ func (bs *Server) GetRandao(ctx context.Context, req *eth2.RandaoRequest) (*eth2
return nil, status.Errorf(codes.Internal, "Could not get randao mix at index %d", idx)
}
isOptimistic, err := helpers.IsOptimistic(ctx, req.StateId, bs.OptimisticModeFetcher, bs.StateFetcher, bs.ChainInfoFetcher, bs.BeaconDB)
isOptimistic, err := helpers.IsOptimistic(ctx, req.StateId, bs.OptimisticModeFetcher, bs.Stater, bs.ChainInfoFetcher, bs.BeaconDB)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not check if slot's block is optimistic: %v", err)
}
@@ -215,14 +215,14 @@ func (bs *Server) stateFromRequest(ctx context.Context, req *stateRequest) (stat
err,
)
}
st, err := bs.StateFetcher.State(ctx, []byte(strconv.FormatUint(uint64(slot), 10)))
st, err := bs.Stater.State(ctx, []byte(strconv.FormatUint(uint64(slot), 10)))
if err != nil {
return nil, helpers.PrepareStateFetchGRPCError(err)
}
return st, nil
}
var err error
st, err := bs.StateFetcher.State(ctx, req.stateId)
st, err := bs.Stater.State(ctx, req.stateId)
if err != nil {
return nil, helpers.PrepareStateFetchGRPCError(err)
}

View File

@@ -83,7 +83,7 @@ func TestGetStateRoot(t *testing.T) {
chainService := &chainMock.ChainService{}
server := &Server{
StateFetcher: &testutil.MockFetcher{
Stater: &testutil.MockStater{
BeaconStateRoot: stateRoot[:],
BeaconState: fakeState,
},
@@ -111,7 +111,7 @@ func TestGetStateRoot(t *testing.T) {
chainService := &chainMock.ChainService{Optimistic: true}
server := &Server{
StateFetcher: &testutil.MockFetcher{
Stater: &testutil.MockStater{
BeaconStateRoot: stateRoot[:],
BeaconState: fakeState,
},
@@ -145,7 +145,7 @@ func TestGetStateRoot(t *testing.T) {
},
}
server := &Server{
StateFetcher: &testutil.MockFetcher{
Stater: &testutil.MockStater{
BeaconStateRoot: stateRoot[:],
BeaconState: fakeState,
},
@@ -179,7 +179,7 @@ func TestGetStateFork(t *testing.T) {
chainService := &chainMock.ChainService{}
server := &Server{
StateFetcher: &testutil.MockFetcher{
Stater: &testutil.MockStater{
BeaconState: fakeState,
},
HeadFetcher: chainService,
@@ -209,7 +209,7 @@ func TestGetStateFork(t *testing.T) {
chainService := &chainMock.ChainService{Optimistic: true}
server := &Server{
StateFetcher: &testutil.MockFetcher{
Stater: &testutil.MockStater{
BeaconState: fakeState,
},
HeadFetcher: chainService,
@@ -242,7 +242,7 @@ func TestGetStateFork(t *testing.T) {
},
}
server := &Server{
StateFetcher: &testutil.MockFetcher{
Stater: &testutil.MockStater{
BeaconState: fakeState,
},
HeadFetcher: chainService,
@@ -282,7 +282,7 @@ func TestGetFinalityCheckpoints(t *testing.T) {
chainService := &chainMock.ChainService{}
server := &Server{
StateFetcher: &testutil.MockFetcher{
Stater: &testutil.MockStater{
BeaconState: fakeState,
},
HeadFetcher: chainService,
@@ -314,7 +314,7 @@ func TestGetFinalityCheckpoints(t *testing.T) {
chainService := &chainMock.ChainService{Optimistic: true}
server := &Server{
StateFetcher: &testutil.MockFetcher{
Stater: &testutil.MockStater{
BeaconState: fakeState,
},
HeadFetcher: chainService,
@@ -347,7 +347,7 @@ func TestGetFinalityCheckpoints(t *testing.T) {
},
}
server := &Server{
StateFetcher: &testutil.MockFetcher{
Stater: &testutil.MockStater{
BeaconState: fakeState,
},
HeadFetcher: chainService,
@@ -388,7 +388,7 @@ func TestGetRandao(t *testing.T) {
db := dbTest.SetupDB(t)
chainService := &chainMock.ChainService{}
server := &Server{
StateFetcher: &testutil.MockFetcher{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
@@ -413,7 +413,7 @@ func TestGetRandao(t *testing.T) {
assert.DeepEqual(t, mixOld, resp.Data.Randao)
})
t.Run("head state below `EpochsPerHistoricalVector`", func(t *testing.T) {
server.StateFetcher = &testutil.MockFetcher{
server.Stater = &testutil.MockStater{
BeaconState: headSt,
}
resp, err := server.GetRandao(ctx, &eth2.RandaoRequest{StateId: []byte("head")})
@@ -441,7 +441,7 @@ func TestGetRandao(t *testing.T) {
chainService := &chainMock.ChainService{Optimistic: true}
server := &Server{
StateFetcher: &testutil.MockFetcher{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
@@ -473,7 +473,7 @@ func TestGetRandao(t *testing.T) {
},
}
server := &Server{
StateFetcher: &testutil.MockFetcher{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,

View File

@@ -91,7 +91,7 @@ func (bs *Server) ListSyncCommittees(ctx context.Context, req *ethpbv2.StateSync
return nil, status.Errorf(codes.Internal, "Could not extract sync subcommittees: %v", err)
}
isOptimistic, err := helpers.IsOptimistic(ctx, req.StateId, bs.OptimisticModeFetcher, bs.StateFetcher, bs.ChainInfoFetcher, bs.BeaconDB)
isOptimistic, err := helpers.IsOptimistic(ctx, req.StateId, bs.OptimisticModeFetcher, bs.Stater, bs.ChainInfoFetcher, bs.BeaconDB)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not check if slot's block is optimistic: %v", err)
}

View File

@@ -167,7 +167,7 @@ func TestListSyncCommittees(t *testing.T) {
GenesisTimeFetcher: &testutil.MockGenesisTimeFetcher{
Genesis: time.Now(),
},
StateFetcher: &testutil.MockFetcher{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
@@ -213,7 +213,7 @@ func TestListSyncCommittees(t *testing.T) {
GenesisTimeFetcher: &testutil.MockGenesisTimeFetcher{
Genesis: time.Now(),
},
StateFetcher: &testutil.MockFetcher{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
@@ -249,7 +249,7 @@ func TestListSyncCommittees(t *testing.T) {
GenesisTimeFetcher: &testutil.MockGenesisTimeFetcher{
Genesis: time.Now(),
},
StateFetcher: &testutil.MockFetcher{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
@@ -309,7 +309,7 @@ func TestListSyncCommitteesFuture(t *testing.T) {
GenesisTimeFetcher: &testutil.MockGenesisTimeFetcher{
Genesis: time.Now(),
},
StateFetcher: &futureSyncMockFetcher{
Stater: &futureSyncMockFetcher{
BeaconState: st,
},
HeadFetcher: chainService,

View File

@@ -42,7 +42,7 @@ func (bs *Server) GetValidator(ctx context.Context, req *ethpb.StateValidatorReq
ctx, span := trace.StartSpan(ctx, "beacon.GetValidator")
defer span.End()
st, err := bs.StateFetcher.State(ctx, req.StateId)
st, err := bs.Stater.State(ctx, req.StateId)
if err != nil {
return nil, helpers.PrepareStateFetchGRPCError(err)
}
@@ -57,7 +57,7 @@ func (bs *Server) GetValidator(ctx context.Context, req *ethpb.StateValidatorReq
return nil, status.Error(codes.NotFound, "Could not find validator")
}
isOptimistic, err := helpers.IsOptimistic(ctx, req.StateId, bs.OptimisticModeFetcher, bs.StateFetcher, bs.ChainInfoFetcher, bs.BeaconDB)
isOptimistic, err := helpers.IsOptimistic(ctx, req.StateId, bs.OptimisticModeFetcher, bs.Stater, bs.ChainInfoFetcher, bs.BeaconDB)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not check if slot's block is optimistic: %v", err)
}
@@ -76,7 +76,7 @@ func (bs *Server) ListValidators(ctx context.Context, req *ethpb.StateValidators
ctx, span := trace.StartSpan(ctx, "beacon.ListValidators")
defer span.End()
st, err := bs.StateFetcher.State(ctx, req.StateId)
st, err := bs.Stater.State(ctx, req.StateId)
if err != nil {
return nil, helpers.PrepareStateFetchGRPCError(err)
}
@@ -86,7 +86,7 @@ func (bs *Server) ListValidators(ctx context.Context, req *ethpb.StateValidators
return nil, handleValContainerErr(err)
}
isOptimistic, err := helpers.IsOptimistic(ctx, req.StateId, bs.OptimisticModeFetcher, bs.StateFetcher, bs.ChainInfoFetcher, bs.BeaconDB)
isOptimistic, err := helpers.IsOptimistic(ctx, req.StateId, bs.OptimisticModeFetcher, bs.Stater, bs.ChainInfoFetcher, bs.BeaconDB)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not check if slot's block is optimistic: %v", err)
}
@@ -138,7 +138,7 @@ func (bs *Server) ListValidatorBalances(ctx context.Context, req *ethpb.Validato
ctx, span := trace.StartSpan(ctx, "beacon.ListValidatorBalances")
defer span.End()
st, err := bs.StateFetcher.State(ctx, req.StateId)
st, err := bs.Stater.State(ctx, req.StateId)
if err != nil {
return nil, helpers.PrepareStateFetchGRPCError(err)
}
@@ -155,7 +155,7 @@ func (bs *Server) ListValidatorBalances(ctx context.Context, req *ethpb.Validato
}
}
isOptimistic, err := helpers.IsOptimistic(ctx, req.StateId, bs.OptimisticModeFetcher, bs.StateFetcher, bs.ChainInfoFetcher, bs.BeaconDB)
isOptimistic, err := helpers.IsOptimistic(ctx, req.StateId, bs.OptimisticModeFetcher, bs.Stater, bs.ChainInfoFetcher, bs.BeaconDB)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not check if slot's block is optimistic: %v", err)
}
@@ -175,7 +175,7 @@ func (bs *Server) ListCommittees(ctx context.Context, req *ethpb.StateCommittees
ctx, span := trace.StartSpan(ctx, "beacon.ListCommittees")
defer span.End()
st, err := bs.StateFetcher.State(ctx, req.StateId)
st, err := bs.Stater.State(ctx, req.StateId)
if err != nil {
return nil, helpers.PrepareStateFetchGRPCError(err)
}
@@ -220,7 +220,7 @@ func (bs *Server) ListCommittees(ctx context.Context, req *ethpb.StateCommittees
}
}
isOptimistic, err := helpers.IsOptimistic(ctx, req.StateId, bs.OptimisticModeFetcher, bs.StateFetcher, bs.ChainInfoFetcher, bs.BeaconDB)
isOptimistic, err := helpers.IsOptimistic(ctx, req.StateId, bs.OptimisticModeFetcher, bs.Stater, bs.ChainInfoFetcher, bs.BeaconDB)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not check if slot's block is optimistic: %v", err)
}

View File

@@ -9,7 +9,7 @@ import (
chainMock "github.com/prysmaticlabs/prysm/v4/beacon-chain/blockchain/testing"
dbTest "github.com/prysmaticlabs/prysm/v4/beacon-chain/db/testing"
rpchelpers "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/helpers"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/statefetcher"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/lookup"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/testutil"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state"
state_native "github.com/prysmaticlabs/prysm/v4/beacon-chain/state/state-native"
@@ -34,7 +34,7 @@ func TestGetValidator(t *testing.T) {
t.Run("Head Get Validator by index", func(t *testing.T) {
chainService := &chainMock.ChainService{}
s := Server{
StateFetcher: &testutil.MockFetcher{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
@@ -54,7 +54,7 @@ func TestGetValidator(t *testing.T) {
t.Run("Head Get Validator by pubkey", func(t *testing.T) {
chainService := &chainMock.ChainService{}
s := Server{
StateFetcher: &testutil.MockFetcher{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
@@ -75,7 +75,7 @@ func TestGetValidator(t *testing.T) {
t.Run("Validator ID required", func(t *testing.T) {
s := Server{
StateFetcher: &testutil.MockFetcher{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: &chainMock.ChainService{},
@@ -98,7 +98,7 @@ func TestGetValidator(t *testing.T) {
chainService := &chainMock.ChainService{Optimistic: true}
s := Server{
StateFetcher: &testutil.MockFetcher{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
@@ -131,7 +131,7 @@ func TestGetValidator(t *testing.T) {
},
}
s := Server{
StateFetcher: &testutil.MockFetcher{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
@@ -157,7 +157,7 @@ func TestListValidators(t *testing.T) {
t.Run("Head List All Validators", func(t *testing.T) {
chainService := &chainMock.ChainService{}
s := Server{
StateFetcher: &testutil.MockFetcher{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
@@ -179,7 +179,7 @@ func TestListValidators(t *testing.T) {
t.Run("Head List Validators by index", func(t *testing.T) {
chainService := &chainMock.ChainService{}
s := Server{
StateFetcher: &testutil.MockFetcher{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
@@ -204,7 +204,7 @@ func TestListValidators(t *testing.T) {
t.Run("Head List Validators by pubkey", func(t *testing.T) {
chainService := &chainMock.ChainService{}
s := Server{
StateFetcher: &testutil.MockFetcher{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
@@ -233,7 +233,7 @@ func TestListValidators(t *testing.T) {
t.Run("Head List Validators by both index and pubkey", func(t *testing.T) {
chainService := &chainMock.ChainService{}
s := Server{
StateFetcher: &testutil.MockFetcher{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
@@ -264,7 +264,7 @@ func TestListValidators(t *testing.T) {
t.Run("Unknown public key is ignored", func(t *testing.T) {
chainService := &chainMock.ChainService{}
s := Server{
StateFetcher: &testutil.MockFetcher{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
@@ -287,7 +287,7 @@ func TestListValidators(t *testing.T) {
t.Run("Unknown index is ignored", func(t *testing.T) {
chainService := &chainMock.ChainService{}
s := Server{
StateFetcher: &testutil.MockFetcher{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
@@ -317,7 +317,7 @@ func TestListValidators(t *testing.T) {
chainService := &chainMock.ChainService{Optimistic: true}
s := Server{
StateFetcher: &testutil.MockFetcher{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
@@ -349,7 +349,7 @@ func TestListValidators(t *testing.T) {
},
}
s := Server{
StateFetcher: &testutil.MockFetcher{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
@@ -440,7 +440,7 @@ func TestListValidators_Status(t *testing.T) {
t.Run("Head List All ACTIVE Validators", func(t *testing.T) {
chainService := &chainMock.ChainService{}
s := Server{
StateFetcher: &statefetcher.StateProvider{
Stater: &lookup.BeaconDbStater{
ChainInfoFetcher: &chainMock.ChainService{State: st},
},
HeadFetcher: chainService,
@@ -478,7 +478,7 @@ func TestListValidators_Status(t *testing.T) {
t.Run("Head List All ACTIVE_ONGOING Validators", func(t *testing.T) {
chainService := &chainMock.ChainService{}
s := Server{
StateFetcher: &statefetcher.StateProvider{
Stater: &lookup.BeaconDbStater{
ChainInfoFetcher: &chainMock.ChainService{State: st},
},
HeadFetcher: chainService,
@@ -515,7 +515,7 @@ func TestListValidators_Status(t *testing.T) {
t.Run("Head List All EXITED Validators", func(t *testing.T) {
chainService := &chainMock.ChainService{}
s := Server{
StateFetcher: &statefetcher.StateProvider{
Stater: &lookup.BeaconDbStater{
ChainInfoFetcher: &chainMock.ChainService{State: st},
},
HeadFetcher: chainService,
@@ -551,7 +551,7 @@ func TestListValidators_Status(t *testing.T) {
t.Run("Head List All PENDING_INITIALIZED and EXITED_UNSLASHED Validators", func(t *testing.T) {
chainService := &chainMock.ChainService{}
s := Server{
StateFetcher: &statefetcher.StateProvider{
Stater: &lookup.BeaconDbStater{
ChainInfoFetcher: &chainMock.ChainService{State: st},
},
HeadFetcher: chainService,
@@ -587,7 +587,7 @@ func TestListValidators_Status(t *testing.T) {
t.Run("Head List All PENDING and EXITED Validators", func(t *testing.T) {
chainService := &chainMock.ChainService{}
s := Server{
StateFetcher: &statefetcher.StateProvider{
Stater: &lookup.BeaconDbStater{
ChainInfoFetcher: &chainMock.ChainService{State: st},
},
HeadFetcher: chainService,
@@ -638,7 +638,7 @@ func TestListValidatorBalances(t *testing.T) {
t.Run("Head List Validators Balance by index", func(t *testing.T) {
chainService := &chainMock.ChainService{}
s := Server{
StateFetcher: &testutil.MockFetcher{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
@@ -663,7 +663,7 @@ func TestListValidatorBalances(t *testing.T) {
t.Run("Head List Validators Balance by pubkey", func(t *testing.T) {
chainService := &chainMock.ChainService{}
s := Server{
StateFetcher: &testutil.MockFetcher{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
@@ -691,7 +691,7 @@ func TestListValidatorBalances(t *testing.T) {
t.Run("Head List Validators Balance by both index and pubkey", func(t *testing.T) {
chainService := &chainMock.ChainService{}
s := Server{
StateFetcher: &testutil.MockFetcher{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
@@ -726,7 +726,7 @@ func TestListValidatorBalances(t *testing.T) {
chainService := &chainMock.ChainService{Optimistic: true}
s := Server{
StateFetcher: &testutil.MockFetcher{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
@@ -761,7 +761,7 @@ func TestListValidatorBalances(t *testing.T) {
},
}
s := Server{
StateFetcher: &testutil.MockFetcher{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
@@ -791,7 +791,7 @@ func TestListCommittees(t *testing.T) {
t.Run("Head All Committees", func(t *testing.T) {
chainService := &chainMock.ChainService{}
s := Server{
StateFetcher: &testutil.MockFetcher{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
@@ -814,7 +814,7 @@ func TestListCommittees(t *testing.T) {
t.Run("Head All Committees of Epoch 10", func(t *testing.T) {
chainService := &chainMock.ChainService{}
s := Server{
StateFetcher: &testutil.MockFetcher{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
@@ -836,7 +836,7 @@ func TestListCommittees(t *testing.T) {
t.Run("Head All Committees of Slot 4", func(t *testing.T) {
chainService := &chainMock.ChainService{}
s := Server{
StateFetcher: &testutil.MockFetcher{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
@@ -864,7 +864,7 @@ func TestListCommittees(t *testing.T) {
t.Run("Head All Committees of Index 1", func(t *testing.T) {
chainService := &chainMock.ChainService{}
s := Server{
StateFetcher: &testutil.MockFetcher{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
@@ -892,7 +892,7 @@ func TestListCommittees(t *testing.T) {
t.Run("Head All Committees of Slot 2, Index 1", func(t *testing.T) {
chainService := &chainMock.ChainService{}
s := Server{
StateFetcher: &testutil.MockFetcher{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
@@ -928,7 +928,7 @@ func TestListCommittees(t *testing.T) {
chainService := &chainMock.ChainService{Optimistic: true}
s := Server{
StateFetcher: &testutil.MockFetcher{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,
@@ -961,7 +961,7 @@ func TestListCommittees(t *testing.T) {
},
}
s := Server{
StateFetcher: &testutil.MockFetcher{
Stater: &testutil.MockStater{
BeaconState: st,
},
HeadFetcher: chainService,

View File

@@ -12,7 +12,7 @@ go_library(
"//beacon-chain/blockchain:go_default_library",
"//beacon-chain/db:go_default_library",
"//beacon-chain/rpc/eth/helpers:go_default_library",
"//beacon-chain/rpc/statefetcher:go_default_library",
"//beacon-chain/rpc/lookup:go_default_library",
"//proto/eth/v1:go_default_library",
"//proto/eth/v2:go_default_library",
"//proto/migration:go_default_library",

View File

@@ -19,7 +19,7 @@ func (ds *Server) GetBeaconStateSSZ(ctx context.Context, req *ethpbv1.StateReque
ctx, span := trace.StartSpan(ctx, "debug.GetBeaconStateSSZ")
defer span.End()
state, err := ds.StateFetcher.State(ctx, req.StateId)
state, err := ds.Stater.State(ctx, req.StateId)
if err != nil {
return nil, helpers.PrepareStateFetchGRPCError(err)
}
@@ -37,11 +37,11 @@ func (ds *Server) GetBeaconStateV2(ctx context.Context, req *ethpbv2.BeaconState
ctx, span := trace.StartSpan(ctx, "debug.GetBeaconStateV2")
defer span.End()
beaconSt, err := ds.StateFetcher.State(ctx, req.StateId)
beaconSt, err := ds.Stater.State(ctx, req.StateId)
if err != nil {
return nil, helpers.PrepareStateFetchGRPCError(err)
}
isOptimistic, err := helpers.IsOptimistic(ctx, req.StateId, ds.OptimisticModeFetcher, ds.StateFetcher, ds.ChainInfoFetcher, ds.BeaconDB)
isOptimistic, err := helpers.IsOptimistic(ctx, req.StateId, ds.OptimisticModeFetcher, ds.Stater, ds.ChainInfoFetcher, ds.BeaconDB)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not check if slot's block is optimistic: %v", err)
}
@@ -127,7 +127,7 @@ func (ds *Server) GetBeaconStateSSZV2(ctx context.Context, req *ethpbv2.BeaconSt
ctx, span := trace.StartSpan(ctx, "debug.GetBeaconStateSSZV2")
defer span.End()
st, err := ds.StateFetcher.State(ctx, req.StateId)
st, err := ds.Stater.State(ctx, req.StateId)
if err != nil {
return nil, helpers.PrepareStateFetchGRPCError(err)
}

View File

@@ -28,7 +28,7 @@ func TestGetBeaconStateV2(t *testing.T) {
fakeState, err := util.NewBeaconState()
require.NoError(t, err)
server := &Server{
StateFetcher: &testutil.MockFetcher{
Stater: &testutil.MockStater{
BeaconState: fakeState,
},
HeadFetcher: &blockchainmock.ChainService{},
@@ -46,7 +46,7 @@ func TestGetBeaconStateV2(t *testing.T) {
t.Run("Altair", func(t *testing.T) {
fakeState, _ := util.DeterministicGenesisStateAltair(t, 1)
server := &Server{
StateFetcher: &testutil.MockFetcher{
Stater: &testutil.MockStater{
BeaconState: fakeState,
},
HeadFetcher: &blockchainmock.ChainService{},
@@ -64,7 +64,7 @@ func TestGetBeaconStateV2(t *testing.T) {
t.Run("Bellatrix", func(t *testing.T) {
fakeState, _ := util.DeterministicGenesisStateBellatrix(t, 1)
server := &Server{
StateFetcher: &testutil.MockFetcher{
Stater: &testutil.MockStater{
BeaconState: fakeState,
},
HeadFetcher: &blockchainmock.ChainService{},
@@ -82,7 +82,7 @@ func TestGetBeaconStateV2(t *testing.T) {
t.Run("Capella", func(t *testing.T) {
fakeState, _ := util.DeterministicGenesisStateCapella(t, 1)
server := &Server{
StateFetcher: &testutil.MockFetcher{
Stater: &testutil.MockStater{
BeaconState: fakeState,
},
HeadFetcher: &blockchainmock.ChainService{},
@@ -108,7 +108,7 @@ func TestGetBeaconStateV2(t *testing.T) {
fakeState, _ := util.DeterministicGenesisStateBellatrix(t, 1)
server := &Server{
StateFetcher: &testutil.MockFetcher{
Stater: &testutil.MockStater{
BeaconState: fakeState,
},
HeadFetcher: &blockchainmock.ChainService{},
@@ -141,7 +141,7 @@ func TestGetBeaconStateV2(t *testing.T) {
},
}
server := &Server{
StateFetcher: &testutil.MockFetcher{
Stater: &testutil.MockStater{
BeaconState: fakeState,
},
HeadFetcher: chainService,
@@ -165,7 +165,7 @@ func TestGetBeaconStateSSZ(t *testing.T) {
require.NoError(t, err)
server := &Server{
StateFetcher: &testutil.MockFetcher{
Stater: &testutil.MockStater{
BeaconState: fakeState,
},
}
@@ -186,7 +186,7 @@ func TestGetBeaconStateSSZV2(t *testing.T) {
require.NoError(t, err)
server := &Server{
StateFetcher: &testutil.MockFetcher{
Stater: &testutil.MockStater{
BeaconState: fakeState,
},
}
@@ -205,7 +205,7 @@ func TestGetBeaconStateSSZV2(t *testing.T) {
require.NoError(t, err)
server := &Server{
StateFetcher: &testutil.MockFetcher{
Stater: &testutil.MockStater{
BeaconState: fakeState,
},
}
@@ -224,7 +224,7 @@ func TestGetBeaconStateSSZV2(t *testing.T) {
require.NoError(t, err)
server := &Server{
StateFetcher: &testutil.MockFetcher{
Stater: &testutil.MockStater{
BeaconState: fakeState,
},
}
@@ -243,7 +243,7 @@ func TestGetBeaconStateSSZV2(t *testing.T) {
require.NoError(t, err)
server := &Server{
StateFetcher: &testutil.MockFetcher{
Stater: &testutil.MockStater{
BeaconState: fakeState,
},
}

View File

@@ -6,7 +6,7 @@ package debug
import (
"github.com/prysmaticlabs/prysm/v4/beacon-chain/blockchain"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/db"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/statefetcher"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/lookup"
)
// Server defines a server implementation of the gRPC Beacon Chain service,
@@ -14,7 +14,7 @@ import (
type Server struct {
BeaconDB db.ReadOnlyDatabase
HeadFetcher blockchain.HeadFetcher
StateFetcher statefetcher.Fetcher
Stater lookup.Stater
OptimisticModeFetcher blockchain.OptimisticModeFetcher
ForkFetcher blockchain.ForkFetcher
ForkchoiceFetcher blockchain.ForkchoiceFetcher

View File

@@ -13,7 +13,7 @@ go_library(
"//api/grpc:go_default_library",
"//beacon-chain/blockchain:go_default_library",
"//beacon-chain/db:go_default_library",
"//beacon-chain/rpc/statefetcher:go_default_library",
"//beacon-chain/rpc/lookup:go_default_library",
"//beacon-chain/state:go_default_library",
"//beacon-chain/state/stategen:go_default_library",
"//beacon-chain/sync:go_default_library",

View File

@@ -3,7 +3,7 @@ package helpers
import (
"errors"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/statefetcher"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/lookup"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state/stategen"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
@@ -15,10 +15,10 @@ func PrepareStateFetchGRPCError(err error) error {
if errors.Is(err, stategen.ErrNoDataForSlot) {
return status.Errorf(codes.NotFound, "lacking historical data needed to fulfill request")
}
if stateNotFoundErr, ok := err.(*statefetcher.StateNotFoundError); ok {
if stateNotFoundErr, ok := err.(*lookup.StateNotFoundError); ok {
return status.Errorf(codes.NotFound, "State not found: %v", stateNotFoundErr)
}
if parseErr, ok := err.(*statefetcher.StateIdParseError); ok {
if parseErr, ok := err.(*lookup.StateIdParseError); ok {
return status.Errorf(codes.InvalidArgument, "Invalid state ID: %v", parseErr)
}
return status.Errorf(codes.Internal, "Invalid state ID: %v", err)

View File

@@ -9,7 +9,7 @@ import (
"github.com/prysmaticlabs/prysm/v4/api/grpc"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/blockchain"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/db"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/statefetcher"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/lookup"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/sync"
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
@@ -61,7 +61,7 @@ func IsOptimistic(
ctx context.Context,
stateId []byte,
optimisticModeFetcher blockchain.OptimisticModeFetcher,
stateFetcher statefetcher.Fetcher,
stateFetcher lookup.Stater,
chainInfo blockchain.ChainInfoFetcher,
database db.ReadOnlyDatabase,
) (bool, error) {
@@ -97,7 +97,7 @@ func IsOptimistic(
slotNumber, parseErr := strconv.ParseUint(stateIdString, 10, 64)
if parseErr != nil {
// ID format does not match any valid options.
e := statefetcher.NewStateIdParseError(parseErr)
e := lookup.NewStateIdParseError(parseErr)
return true, &e
}
fcp := chainInfo.FinalizedCheckpt()
@@ -146,7 +146,7 @@ func isStateRootOptimistic(
ctx context.Context,
stateId []byte,
optimisticModeFetcher blockchain.OptimisticModeFetcher,
stateFetcher statefetcher.Fetcher,
stateFetcher lookup.Stater,
chainInfo blockchain.ChainInfoFetcher,
database db.ReadOnlyDatabase,
) (bool, error) {

View File

@@ -97,7 +97,7 @@ func TestIsOptimistic(t *testing.T) {
st, err := util.NewBeaconState()
require.NoError(t, err)
cs := &chainmock.ChainService{Optimistic: true, FinalizedCheckPoint: &eth.Checkpoint{}, OptimisticRoots: map[[32]byte]bool{[32]byte{}: true}}
mf := &testutil.MockFetcher{BeaconState: st}
mf := &testutil.MockStater{BeaconState: st}
o, err := IsOptimistic(ctx, []byte("finalized"), cs, mf, cs, nil)
require.NoError(t, err)
assert.Equal(t, true, o)
@@ -106,7 +106,7 @@ func TestIsOptimistic(t *testing.T) {
st, err := util.NewBeaconState()
require.NoError(t, err)
cs := &chainmock.ChainService{Optimistic: true, FinalizedCheckPoint: &eth.Checkpoint{}}
mf := &testutil.MockFetcher{BeaconState: st}
mf := &testutil.MockStater{BeaconState: st}
o, err := IsOptimistic(ctx, []byte("finalized"), cs, mf, cs, nil)
require.NoError(t, err)
assert.Equal(t, false, o)
@@ -117,7 +117,7 @@ func TestIsOptimistic(t *testing.T) {
st, err := util.NewBeaconState()
require.NoError(t, err)
cs := &chainmock.ChainService{Optimistic: true, CurrentJustifiedCheckPoint: &eth.Checkpoint{}, OptimisticRoots: map[[32]byte]bool{[32]byte{}: true}}
mf := &testutil.MockFetcher{BeaconState: st}
mf := &testutil.MockStater{BeaconState: st}
o, err := IsOptimistic(ctx, []byte("justified"), cs, mf, cs, nil)
require.NoError(t, err)
assert.Equal(t, true, o)
@@ -126,7 +126,7 @@ func TestIsOptimistic(t *testing.T) {
st, err := util.NewBeaconState()
require.NoError(t, err)
cs := &chainmock.ChainService{Optimistic: true, CurrentJustifiedCheckPoint: &eth.Checkpoint{}}
mf := &testutil.MockFetcher{BeaconState: st}
mf := &testutil.MockStater{BeaconState: st}
o, err := IsOptimistic(ctx, []byte("justified"), cs, mf, cs, nil)
require.NoError(t, err)
assert.Equal(t, false, o)
@@ -137,7 +137,7 @@ func TestIsOptimistic(t *testing.T) {
st, err := util.NewBeaconState()
require.NoError(t, err)
cs := &chainmock.ChainService{Optimistic: true}
mf := &testutil.MockFetcher{BeaconState: st}
mf := &testutil.MockStater{BeaconState: st}
o, err := IsOptimistic(ctx, bytesutil.PadTo([]byte("root"), 32), cs, mf, cs, nil)
require.NoError(t, err)
assert.Equal(t, true, o)
@@ -146,7 +146,7 @@ func TestIsOptimistic(t *testing.T) {
st, err := util.NewBeaconState()
require.NoError(t, err)
cs := &chainmock.ChainService{Optimistic: false}
mf := &testutil.MockFetcher{BeaconState: st}
mf := &testutil.MockStater{BeaconState: st}
o, err := IsOptimistic(ctx, bytesutil.PadTo([]byte("root"), 32), cs, mf, cs, nil)
require.NoError(t, err)
assert.Equal(t, false, o)
@@ -165,7 +165,7 @@ func TestIsOptimistic(t *testing.T) {
bRoot, err := b.Block().HashTreeRoot()
require.NoError(t, err)
cs := &chainmock.ChainService{State: chainSt, OptimisticRoots: map[[32]byte]bool{bRoot: true}}
mf := &testutil.MockFetcher{BeaconState: fetcherSt}
mf := &testutil.MockStater{BeaconState: fetcherSt}
o, err := IsOptimistic(ctx, bytesutil.PadTo([]byte("root"), 32), cs, mf, cs, db)
require.NoError(t, err)
assert.Equal(t, true, o)
@@ -182,7 +182,7 @@ func TestIsOptimistic(t *testing.T) {
require.NoError(t, err)
require.NoError(t, chainSt.SetSlot(fieldparams.SlotsPerEpoch))
cs := &chainmock.ChainService{State: chainSt}
mf := &testutil.MockFetcher{BeaconState: fetcherSt}
mf := &testutil.MockStater{BeaconState: fetcherSt}
o, err := IsOptimistic(ctx, bytesutil.PadTo([]byte("root"), 32), cs, mf, cs, db)
require.NoError(t, err)
assert.Equal(t, false, o)
@@ -198,7 +198,7 @@ func TestIsOptimistic(t *testing.T) {
require.NoError(t, err)
require.NoError(t, chainSt.SetSlot(fieldparams.SlotsPerEpoch))
cs := &chainmock.ChainService{Optimistic: false, State: chainSt, CanonicalRoots: map[[32]byte]bool{}}
mf := &testutil.MockFetcher{BeaconState: fetcherSt}
mf := &testutil.MockStater{BeaconState: fetcherSt}
o, err := IsOptimistic(ctx, bytesutil.PadTo([]byte("root"), 32), nil, mf, cs, db)
require.NoError(t, err)
assert.Equal(t, true, o)
@@ -248,7 +248,7 @@ func TestIsOptimistic(t *testing.T) {
require.NoError(t, err)
require.NoError(t, chainSt.SetSlot(fieldparams.SlotsPerEpoch*2))
cs := &chainmock.ChainService{Optimistic: true, State: chainSt, FinalizedCheckPoint: &eth.Checkpoint{Epoch: 0}}
mf := &testutil.MockFetcher{BeaconState: fetcherSt}
mf := &testutil.MockStater{BeaconState: fetcherSt}
o, err := IsOptimistic(ctx, []byte(strconv.Itoa(fieldparams.SlotsPerEpoch*2)), cs, mf, cs, db)
require.NoError(t, err)
assert.Equal(t, true, o)
@@ -268,7 +268,7 @@ func TestIsOptimistic(t *testing.T) {
require.NoError(t, err)
require.NoError(t, fcs.InsertNode(ctx, st, root))
cs := &chainmock.ChainService{Root: headRoot[:], Optimistic: true, ForkChoiceStore: fcs, OptimisticRoots: map[[32]byte]bool{r: true}, FinalizedCheckPoint: finalizedCheckpt}
mf := &testutil.MockFetcher{BeaconState: st}
mf := &testutil.MockStater{BeaconState: st}
o, err := IsOptimistic(ctx, []byte(strconv.Itoa(fieldparams.SlotsPerEpoch*2)), cs, mf, cs, db)
require.NoError(t, err)
assert.Equal(t, true, o)
@@ -288,7 +288,7 @@ func TestIsOptimistic(t *testing.T) {
require.NoError(t, err)
require.NoError(t, fcs.InsertNode(ctx, st, root))
cs := &chainmock.ChainService{Root: headRoot[:], Optimistic: true, ForkChoiceStore: fcs, OptimisticRoots: map[[32]byte]bool{r: false}, FinalizedCheckPoint: finalizedCheckpt}
mf := &testutil.MockFetcher{BeaconState: st}
mf := &testutil.MockStater{BeaconState: st}
o, err := IsOptimistic(ctx, []byte(strconv.Itoa(fieldparams.SlotsPerEpoch*2)), cs, mf, cs, db)
require.NoError(t, err)
assert.Equal(t, false, o)

View File

@@ -0,0 +1,52 @@
load("@prysm//tools/go:def.bzl", "go_library", "go_test")
go_library(
name = "go_default_library",
srcs = [
"handlers.go",
"server.go",
"structs.go",
],
importpath = "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/rewards",
visibility = ["//visibility:public"],
deps = [
"//beacon-chain/blockchain:go_default_library",
"//beacon-chain/core/altair:go_default_library",
"//beacon-chain/core/blocks:go_default_library",
"//beacon-chain/core/validators:go_default_library",
"//beacon-chain/rpc/lookup:go_default_library",
"//beacon-chain/state/stategen:go_default_library",
"//consensus-types/blocks:go_default_library",
"//consensus-types/interfaces:go_default_library",
"//network:go_default_library",
"//runtime/version:go_default_library",
"@com_github_pkg_errors//:go_default_library",
],
)
go_test(
name = "go_default_test",
srcs = ["handlers_test.go"],
embed = [":go_default_library"],
deps = [
"//beacon-chain/blockchain/testing:go_default_library",
"//beacon-chain/core/altair:go_default_library",
"//beacon-chain/core/signing:go_default_library",
"//beacon-chain/rpc/testutil:go_default_library",
"//beacon-chain/state/stategen/mock:go_default_library",
"//config/fieldparams:go_default_library",
"//config/params:go_default_library",
"//consensus-types/blocks:go_default_library",
"//consensus-types/interfaces:go_default_library",
"//consensus-types/primitives:go_default_library",
"//crypto/bls:go_default_library",
"//crypto/bls/blst:go_default_library",
"//encoding/bytesutil:go_default_library",
"//network:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
"//testing/assert:go_default_library",
"//testing/require:go_default_library",
"//testing/util:go_default_library",
"@com_github_prysmaticlabs_go_bitfield//:go_default_library",
],
)

View File

@@ -0,0 +1,189 @@
package rewards
import (
"net/http"
"strconv"
"strings"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/altair"
coreblocks "github.com/prysmaticlabs/prysm/v4/beacon-chain/core/blocks"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/validators"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/lookup"
"github.com/prysmaticlabs/prysm/v4/consensus-types/blocks"
"github.com/prysmaticlabs/prysm/v4/consensus-types/interfaces"
"github.com/prysmaticlabs/prysm/v4/network"
"github.com/prysmaticlabs/prysm/v4/runtime/version"
)
// BlockRewards is an HTTP handler for Beacon API getBlockRewards.
func (s *Server) BlockRewards(w http.ResponseWriter, r *http.Request) {
segments := strings.Split(r.URL.Path, "/")
blockId := segments[len(segments)-1]
blk, err := s.Blocker.Block(r.Context(), []byte(blockId))
if errJson := handleGetBlockError(blk, err); errJson != nil {
network.WriteError(w, errJson)
return
}
if blk.Version() == version.Phase0 {
errJson := &network.DefaultErrorJson{
Message: "block rewards are not supported for Phase 0 blocks",
Code: http.StatusBadRequest,
}
network.WriteError(w, errJson)
return
}
// We want to run several block processing functions that update the proposer's balance.
// This will allow us to calculate proposer rewards for each operation (atts, slashings etc).
// To do this, we replay the state up to the block's slot, but before processing the block.
st, err := s.ReplayerBuilder.ReplayerForSlot(blk.Block().Slot()-1).ReplayToSlot(r.Context(), blk.Block().Slot())
if err != nil {
errJson := &network.DefaultErrorJson{
Message: errors.Wrapf(err, "could not get state").Error(),
Code: http.StatusInternalServerError,
}
network.WriteError(w, errJson)
return
}
proposerIndex := blk.Block().ProposerIndex()
initBalance, err := st.BalanceAtIndex(proposerIndex)
if err != nil {
errJson := &network.DefaultErrorJson{
Message: errors.Wrapf(err, "could not get proposer's balance").Error(),
Code: http.StatusInternalServerError,
}
network.WriteError(w, errJson)
return
}
st, err = altair.ProcessAttestationsNoVerifySignature(r.Context(), st, blk)
if err != nil {
errJson := &network.DefaultErrorJson{
Message: errors.Wrapf(err, "could not get attestation rewards").Error(),
Code: http.StatusInternalServerError,
}
network.WriteError(w, errJson)
return
}
attBalance, err := st.BalanceAtIndex(proposerIndex)
if err != nil {
errJson := &network.DefaultErrorJson{
Message: errors.Wrapf(err, "could not get proposer's balance").Error(),
Code: http.StatusInternalServerError,
}
network.WriteError(w, errJson)
return
}
st, err = coreblocks.ProcessAttesterSlashings(r.Context(), st, blk.Block().Body().AttesterSlashings(), validators.SlashValidator)
if err != nil {
errJson := &network.DefaultErrorJson{
Message: errors.Wrapf(err, "could not get attester slashing rewards").Error(),
Code: http.StatusInternalServerError,
}
network.WriteError(w, errJson)
return
}
attSlashingsBalance, err := st.BalanceAtIndex(proposerIndex)
if err != nil {
errJson := &network.DefaultErrorJson{
Message: errors.Wrapf(err, "could not get proposer's balance").Error(),
Code: http.StatusInternalServerError,
}
network.WriteError(w, errJson)
return
}
st, err = coreblocks.ProcessProposerSlashings(r.Context(), st, blk.Block().Body().ProposerSlashings(), validators.SlashValidator)
if err != nil {
errJson := &network.DefaultErrorJson{
Message: errors.Wrapf(err, "could not get proposer slashing rewards").Error(),
Code: http.StatusInternalServerError,
}
network.WriteError(w, errJson)
return
}
proposerSlashingsBalance, err := st.BalanceAtIndex(proposerIndex)
if err != nil {
errJson := &network.DefaultErrorJson{
Message: errors.Wrapf(err, "could not get proposer's balance").Error(),
Code: http.StatusInternalServerError,
}
network.WriteError(w, errJson)
return
}
sa, err := blk.Block().Body().SyncAggregate()
if err != nil {
errJson := &network.DefaultErrorJson{
Message: errors.Wrapf(err, "could not get sync aggregate").Error(),
Code: http.StatusInternalServerError,
}
network.WriteError(w, errJson)
return
}
var syncCommitteeReward uint64
_, syncCommitteeReward, err = altair.ProcessSyncAggregate(r.Context(), st, sa)
if err != nil {
errJson := &network.DefaultErrorJson{
Message: errors.Wrapf(err, "could not get sync aggregate rewards").Error(),
Code: http.StatusInternalServerError,
}
network.WriteError(w, errJson)
return
}
optimistic, err := s.OptimisticModeFetcher.IsOptimistic(r.Context())
if err != nil {
errJson := &network.DefaultErrorJson{
Message: errors.Wrapf(err, "could not get optimistic mode info").Error(),
Code: http.StatusInternalServerError,
}
network.WriteError(w, errJson)
return
}
blkRoot, err := blk.Block().HashTreeRoot()
if err != nil {
errJson := &network.DefaultErrorJson{
Message: errors.Wrapf(err, "could not get block root").Error(),
Code: http.StatusInternalServerError,
}
network.WriteError(w, errJson)
return
}
response := &BlockRewardsResponse{
Data: &BlockRewards{
ProposerIndex: strconv.FormatUint(uint64(proposerIndex), 10),
Total: strconv.FormatUint(proposerSlashingsBalance-initBalance+syncCommitteeReward, 10),
Attestations: strconv.FormatUint(attBalance-initBalance, 10),
SyncAggregate: strconv.FormatUint(syncCommitteeReward, 10),
ProposerSlashings: strconv.FormatUint(proposerSlashingsBalance-attSlashingsBalance, 10),
AttesterSlashings: strconv.FormatUint(attSlashingsBalance-attBalance, 10),
},
ExecutionOptimistic: optimistic,
Finalized: s.FinalizationFetcher.IsFinalized(r.Context(), blkRoot),
}
network.WriteJson(w, response)
}
func handleGetBlockError(blk interfaces.ReadOnlySignedBeaconBlock, err error) *network.DefaultErrorJson {
if errors.Is(err, lookup.BlockIdParseError{}) {
return &network.DefaultErrorJson{
Message: errors.Wrapf(err, "invalid block ID").Error(),
Code: http.StatusBadRequest,
}
}
if err != nil {
return &network.DefaultErrorJson{
Message: errors.Wrapf(err, "could not get block from block ID").Error(),
Code: http.StatusInternalServerError,
}
}
if err := blocks.BeaconBlockIsNil(blk); err != nil {
return &network.DefaultErrorJson{
Message: errors.Wrapf(err, "could not find requested block").Error(),
Code: http.StatusNotFound,
}
}
return nil
}

View File

@@ -0,0 +1,198 @@
package rewards
import (
"bytes"
"context"
"encoding/json"
"net/http"
"net/http/httptest"
"testing"
"github.com/prysmaticlabs/go-bitfield"
mock "github.com/prysmaticlabs/prysm/v4/beacon-chain/blockchain/testing"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/altair"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/signing"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/testutil"
mockstategen "github.com/prysmaticlabs/prysm/v4/beacon-chain/state/stategen/mock"
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
"github.com/prysmaticlabs/prysm/v4/config/params"
"github.com/prysmaticlabs/prysm/v4/consensus-types/blocks"
"github.com/prysmaticlabs/prysm/v4/consensus-types/interfaces"
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
"github.com/prysmaticlabs/prysm/v4/crypto/bls"
"github.com/prysmaticlabs/prysm/v4/crypto/bls/blst"
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
"github.com/prysmaticlabs/prysm/v4/network"
eth "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v4/testing/assert"
"github.com/prysmaticlabs/prysm/v4/testing/require"
"github.com/prysmaticlabs/prysm/v4/testing/util"
)
func TestBlockRewards(t *testing.T) {
valCount := 64
st, err := util.NewBeaconStateAltair()
require.NoError(t, st.SetSlot(1))
require.NoError(t, err)
validators := make([]*eth.Validator, 0, valCount)
balances := make([]uint64, 0, valCount)
secretKeys := make([]bls.SecretKey, 0, valCount)
for i := 0; i < valCount; i++ {
blsKey, err := bls.RandKey()
require.NoError(t, err)
secretKeys = append(secretKeys, blsKey)
validators = append(validators, &eth.Validator{
PublicKey: blsKey.PublicKey().Marshal(),
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
WithdrawableEpoch: params.BeaconConfig().FarFutureEpoch,
EffectiveBalance: params.BeaconConfig().MaxEffectiveBalance,
})
balances = append(balances, params.BeaconConfig().MaxEffectiveBalance)
}
require.NoError(t, st.SetValidators(validators))
require.NoError(t, st.SetBalances(balances))
require.NoError(t, st.SetCurrentParticipationBits(make([]byte, valCount)))
syncCommittee, err := altair.NextSyncCommittee(context.Background(), st)
require.NoError(t, err)
require.NoError(t, st.SetCurrentSyncCommittee(syncCommittee))
slot0bRoot := bytesutil.PadTo([]byte("slot0root"), 32)
bRoots := make([][]byte, fieldparams.BlockRootsLength)
bRoots[0] = slot0bRoot
require.NoError(t, st.SetBlockRoots(bRoots))
b := util.HydrateSignedBeaconBlockAltair(util.NewBeaconBlockAltair())
b.Block.Slot = 2
// we have to set the proposer index to the value that will be randomly chosen (fortunately it's deterministic)
b.Block.ProposerIndex = 12
b.Block.Body.Attestations = []*eth.Attestation{
{
AggregationBits: bitfield.Bitlist{0b00000111},
Data: util.HydrateAttestationData(&eth.AttestationData{}),
Signature: make([]byte, fieldparams.BLSSignatureLength),
},
{
AggregationBits: bitfield.Bitlist{0b00000111},
Data: util.HydrateAttestationData(&eth.AttestationData{}),
Signature: make([]byte, fieldparams.BLSSignatureLength),
},
}
attData1 := util.HydrateAttestationData(&eth.AttestationData{BeaconBlockRoot: bytesutil.PadTo([]byte("root1"), 32)})
attData2 := util.HydrateAttestationData(&eth.AttestationData{BeaconBlockRoot: bytesutil.PadTo([]byte("root2"), 32)})
domain, err := signing.Domain(st.Fork(), 0, params.BeaconConfig().DomainBeaconAttester, st.GenesisValidatorsRoot())
require.NoError(t, err)
sigRoot1, err := signing.ComputeSigningRoot(attData1, domain)
require.NoError(t, err)
sigRoot2, err := signing.ComputeSigningRoot(attData2, domain)
require.NoError(t, err)
b.Block.Body.AttesterSlashings = []*eth.AttesterSlashing{
{
Attestation_1: &eth.IndexedAttestation{
AttestingIndices: []uint64{0},
Data: attData1,
Signature: secretKeys[0].Sign(sigRoot1[:]).Marshal(),
},
Attestation_2: &eth.IndexedAttestation{
AttestingIndices: []uint64{0},
Data: attData2,
Signature: secretKeys[0].Sign(sigRoot2[:]).Marshal(),
},
},
}
header1 := &eth.BeaconBlockHeader{
Slot: 0,
ProposerIndex: 1,
ParentRoot: bytesutil.PadTo([]byte("root1"), 32),
StateRoot: bytesutil.PadTo([]byte("root1"), 32),
BodyRoot: bytesutil.PadTo([]byte("root1"), 32),
}
header2 := &eth.BeaconBlockHeader{
Slot: 0,
ProposerIndex: 1,
ParentRoot: bytesutil.PadTo([]byte("root2"), 32),
StateRoot: bytesutil.PadTo([]byte("root2"), 32),
BodyRoot: bytesutil.PadTo([]byte("root2"), 32),
}
domain, err = signing.Domain(st.Fork(), 0, params.BeaconConfig().DomainBeaconProposer, st.GenesisValidatorsRoot())
require.NoError(t, err)
sigRoot1, err = signing.ComputeSigningRoot(header1, domain)
require.NoError(t, err)
sigRoot2, err = signing.ComputeSigningRoot(header2, domain)
require.NoError(t, err)
b.Block.Body.ProposerSlashings = []*eth.ProposerSlashing{
{
Header_1: &eth.SignedBeaconBlockHeader{
Header: header1,
Signature: secretKeys[1].Sign(sigRoot1[:]).Marshal(),
},
Header_2: &eth.SignedBeaconBlockHeader{
Header: header2,
Signature: secretKeys[1].Sign(sigRoot2[:]).Marshal(),
},
},
}
scBits := bitfield.NewBitvector512()
scBits.SetBitAt(10, true)
scBits.SetBitAt(100, true)
domain, err = signing.Domain(st.Fork(), 0, params.BeaconConfig().DomainSyncCommittee, st.GenesisValidatorsRoot())
require.NoError(t, err)
sszBytes := primitives.SSZBytes(slot0bRoot)
r, err := signing.ComputeSigningRoot(&sszBytes, domain)
require.NoError(t, err)
// Bits set in sync committee bits determine which validators will be treated as participating in sync committee.
// These validators have to sign the message.
sig1, err := blst.SignatureFromBytes(secretKeys[47].Sign(r[:]).Marshal())
require.NoError(t, err)
sig2, err := blst.SignatureFromBytes(secretKeys[19].Sign(r[:]).Marshal())
require.NoError(t, err)
aggSig := bls.AggregateSignatures([]bls.Signature{sig1, sig2}).Marshal()
b.Block.Body.SyncAggregate = &eth.SyncAggregate{SyncCommitteeBits: scBits, SyncCommitteeSignature: aggSig}
sbb, err := blocks.NewSignedBeaconBlock(b)
require.NoError(t, err)
phase0block, err := blocks.NewSignedBeaconBlock(util.NewBeaconBlock())
require.NoError(t, err)
mockChainService := &mock.ChainService{Optimistic: true}
s := &Server{
Blocker: &testutil.MockBlocker{SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{
0: phase0block,
2: sbb,
}},
OptimisticModeFetcher: mockChainService,
FinalizationFetcher: mockChainService,
ReplayerBuilder: mockstategen.NewMockReplayerBuilder(mockstategen.WithMockState(st)),
}
t.Run("ok", func(t *testing.T) {
url := "http://only.the.slot.number.at.the.end.is.important/2"
request := httptest.NewRequest("GET", url, nil)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.BlockRewards(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
resp := &BlockRewardsResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
assert.Equal(t, "12", resp.Data.ProposerIndex)
assert.Equal(t, "125089490", resp.Data.Total)
assert.Equal(t, "89442", resp.Data.Attestations)
assert.Equal(t, "48", resp.Data.SyncAggregate)
assert.Equal(t, "62500000", resp.Data.AttesterSlashings)
assert.Equal(t, "62500000", resp.Data.ProposerSlashings)
assert.Equal(t, true, resp.ExecutionOptimistic)
assert.Equal(t, false, resp.Finalized)
})
t.Run("phase 0", func(t *testing.T) {
url := "http://only.the.slot.number.at.the.end.is.important/0"
request := httptest.NewRequest("GET", url, nil)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.BlockRewards(writer, request)
assert.Equal(t, http.StatusBadRequest, writer.Code)
e := &network.DefaultErrorJson{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), e))
assert.Equal(t, http.StatusBadRequest, e.Code)
assert.Equal(t, "block rewards are not supported for Phase 0 blocks", e.Message)
})
}

View File

@@ -0,0 +1,14 @@
package rewards
import (
"github.com/prysmaticlabs/prysm/v4/beacon-chain/blockchain"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/lookup"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state/stategen"
)
type Server struct {
Blocker lookup.Blocker
OptimisticModeFetcher blockchain.OptimisticModeFetcher
FinalizationFetcher blockchain.FinalizationFetcher
ReplayerBuilder stategen.ReplayerBuilder
}

View File

@@ -0,0 +1,16 @@
package rewards
type BlockRewardsResponse struct {
Data *BlockRewards `json:"data"`
ExecutionOptimistic bool `json:"execution_optimistic"`
Finalized bool `json:"finalized"`
}
type BlockRewards struct {
ProposerIndex string `json:"proposer_index"`
Total string `json:"total"`
Attestations string `json:"attestations"`
SyncAggregate string `json:"sync_aggregate"`
ProposerSlashings string `json:"proposer_slashings"`
AttesterSlashings string `json:"attester_slashings"`
}

View File

@@ -20,8 +20,8 @@ go_library(
"//beacon-chain/operations/synccommittee:go_default_library",
"//beacon-chain/p2p:go_default_library",
"//beacon-chain/rpc/eth/helpers:go_default_library",
"//beacon-chain/rpc/lookup:go_default_library",
"//beacon-chain/rpc/prysm/v1alpha1/validator:go_default_library",
"//beacon-chain/rpc/statefetcher:go_default_library",
"//beacon-chain/state:go_default_library",
"//beacon-chain/state/state-native:go_default_library",
"//beacon-chain/sync:go_default_library",

View File

@@ -8,8 +8,8 @@ import (
"github.com/prysmaticlabs/prysm/v4/beacon-chain/operations/blstoexec"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/operations/synccommittee"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/p2p"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/lookup"
v1alpha1validator "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/prysm/v1alpha1/validator"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/statefetcher"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/sync"
)
@@ -22,7 +22,7 @@ type Server struct {
AttestationsPool attestations.Pool
PeerManager p2p.PeerManager
Broadcaster p2p.Broadcaster
StateFetcher statefetcher.Fetcher
Stater lookup.Stater
OptimisticModeFetcher blockchain.OptimisticModeFetcher
SyncCommitteePool synccommittee.Pool
BLSChangesPool blstoexec.PoolManager

View File

@@ -70,7 +70,7 @@ func (vs *Server) GetAttesterDuties(ctx context.Context, req *ethpbv1.AttesterDu
return nil, status.Errorf(codes.Internal, "Could not get start slot from epoch %d: %v", req.Epoch, err)
}
s, err := vs.StateFetcher.StateBySlot(ctx, startSlot)
s, err := vs.Stater.StateBySlot(ctx, startSlot)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not get state: %v", err)
}
@@ -159,7 +159,7 @@ func (vs *Server) GetProposerDuties(ctx context.Context, req *ethpbv1.ProposerDu
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not get start slot from epoch %d: %v", req.Epoch, err)
}
s, err := vs.StateFetcher.StateBySlot(ctx, startSlot)
s, err := vs.Stater.StateBySlot(ctx, startSlot)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not get state: %v", err)
}
@@ -243,7 +243,7 @@ func (vs *Server) GetSyncCommitteeDuties(ctx context.Context, req *ethpbv2.SyncC
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not get sync committee slot: %v", err)
}
st, err := vs.StateFetcher.State(ctx, []byte(strconv.FormatUint(uint64(slot), 10)))
st, err := vs.Stater.State(ctx, []byte(strconv.FormatUint(uint64(slot), 10)))
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not get sync committee state: %v", err)
}
@@ -282,7 +282,7 @@ func (vs *Server) GetSyncCommitteeDuties(ctx context.Context, req *ethpbv2.SyncC
ctx,
[]byte(strconv.FormatUint(uint64(slot), 10)),
vs.OptimisticModeFetcher,
vs.StateFetcher,
vs.Stater,
vs.ChainInfoFetcher,
vs.BeaconDB,
)
@@ -1081,7 +1081,7 @@ func (vs *Server) GetLiveness(ctx context.Context, req *ethpbv2.GetLivenessReque
if err != nil {
return nil, status.Error(codes.Internal, "Could not get requested epoch's end slot")
}
st, err = vs.StateFetcher.StateBySlot(ctx, epochEnd)
st, err = vs.Stater.StateBySlot(ctx, epochEnd)
if err != nil {
return nil, status.Error(codes.Internal, "Could not get slot for requested epoch")
}

View File

@@ -93,7 +93,7 @@ func TestGetAttesterDuties(t *testing.T) {
State: bs, Root: genesisRoot[:], Slot: &chainSlot,
}
vs := &Server{
StateFetcher: &testutil.MockFetcher{
Stater: &testutil.MockStater{
StatesBySlot: map[primitives.Slot]state.BeaconState{
0: bs,
params.BeaconConfig().SlotsPerEpoch: nextEpochState,
@@ -198,7 +198,7 @@ func TestGetAttesterDuties(t *testing.T) {
State: bs, Root: genesisRoot[:], Slot: &chainSlot, Optimistic: true,
}
vs := &Server{
StateFetcher: &testutil.MockFetcher{StatesBySlot: map[primitives.Slot]state.BeaconState{0: bs}},
Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{0: bs}},
TimeFetcher: chain,
OptimisticModeFetcher: chain,
SyncChecker: &mockSync.Sync{IsSyncing: false},
@@ -258,7 +258,7 @@ func TestGetProposerDuties(t *testing.T) {
State: bs, Root: genesisRoot[:], Slot: &chainSlot,
}
vs := &Server{
StateFetcher: &testutil.MockFetcher{StatesBySlot: map[primitives.Slot]state.BeaconState{0: bs}},
Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{0: bs}},
HeadFetcher: chain,
TimeFetcher: chain,
OptimisticModeFetcher: chain,
@@ -297,7 +297,7 @@ func TestGetProposerDuties(t *testing.T) {
State: bs, Root: genesisRoot[:], Slot: &chainSlot,
}
vs := &Server{
StateFetcher: &testutil.MockFetcher{StatesBySlot: map[primitives.Slot]state.BeaconState{0: bs}},
Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{0: bs}},
HeadFetcher: chain,
TimeFetcher: chain,
OptimisticModeFetcher: chain,
@@ -337,7 +337,7 @@ func TestGetProposerDuties(t *testing.T) {
State: bs, Root: genesisRoot[:], Slot: &chainSlot,
}
vs := &Server{
StateFetcher: &testutil.MockFetcher{StatesBySlot: map[primitives.Slot]state.BeaconState{params.BeaconConfig().SlotsPerEpoch: bs}},
Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{params.BeaconConfig().SlotsPerEpoch: bs}},
HeadFetcher: chain,
TimeFetcher: chain,
OptimisticModeFetcher: chain,
@@ -377,7 +377,7 @@ func TestGetProposerDuties(t *testing.T) {
State: bs, Root: genesisRoot[:], Slot: &chainSlot,
}
vs := &Server{
StateFetcher: &testutil.MockFetcher{StatesBySlot: map[primitives.Slot]state.BeaconState{0: bs}},
Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{0: bs}},
HeadFetcher: chain,
TimeFetcher: chain,
OptimisticModeFetcher: chain,
@@ -414,7 +414,7 @@ func TestGetProposerDuties(t *testing.T) {
State: bs, Root: genesisRoot[:], Slot: &chainSlot, Optimistic: true,
}
vs := &Server{
StateFetcher: &testutil.MockFetcher{StatesBySlot: map[primitives.Slot]state.BeaconState{0: bs}},
Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{0: bs}},
HeadFetcher: chain,
TimeFetcher: chain,
OptimisticModeFetcher: chain,
@@ -469,7 +469,7 @@ func TestGetSyncCommitteeDuties(t *testing.T) {
mockChainService := &mockChain.ChainService{Genesis: genesisTime}
vs := &Server{
StateFetcher: &testutil.MockFetcher{BeaconState: st},
Stater: &testutil.MockStater{BeaconState: st},
SyncChecker: &mockSync.Sync{IsSyncing: false},
TimeFetcher: mockChainService,
HeadFetcher: mockChainService,
@@ -611,7 +611,7 @@ func TestGetSyncCommitteeDuties(t *testing.T) {
}
mockChainService := &mockChain.ChainService{Genesis: genesisTime, Slot: &newSyncPeriodStartSlot}
vs := &Server{
StateFetcher: &testutil.MockFetcher{BeaconState: stateFetchFn(newSyncPeriodStartSlot)},
Stater: &testutil.MockStater{BeaconState: stateFetchFn(newSyncPeriodStartSlot)},
SyncChecker: &mockSync.Sync{IsSyncing: false},
TimeFetcher: mockChainService,
HeadFetcher: mockChainService,
@@ -665,7 +665,7 @@ func TestGetSyncCommitteeDuties(t *testing.T) {
State: state,
}
vs := &Server{
StateFetcher: &testutil.MockFetcher{BeaconState: st},
Stater: &testutil.MockStater{BeaconState: st},
SyncChecker: &mockSync.Sync{IsSyncing: false},
TimeFetcher: mockChainService,
HeadFetcher: mockChainService,
@@ -5021,7 +5021,7 @@ func TestGetLiveness(t *testing.T) {
server := &Server{
HeadFetcher: &mockChain.ChainService{State: headSt},
StateFetcher: &testutil.MockFetcher{
Stater: &testutil.MockStater{
// We configure states for last slots of an epoch
StatesBySlot: map[primitives.Slot]state.BeaconState{
params.BeaconConfig().SlotsPerEpoch - 1: oldSt,

View File

@@ -2,9 +2,12 @@ load("@prysm//tools/go:def.bzl", "go_library", "go_test")
go_library(
name = "go_default_library",
srcs = ["fetcher.go"],
importpath = "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/statefetcher",
visibility = ["//beacon-chain:__subpackages__"],
srcs = [
"blocker.go",
"stater.go",
],
importpath = "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/lookup",
visibility = ["//visibility:public"],
deps = [
"//beacon-chain/blockchain:go_default_library",
"//beacon-chain/db:go_default_library",
@@ -12,6 +15,7 @@ go_library(
"//beacon-chain/state/stategen:go_default_library",
"//config/params:go_default_library",
"//consensus-types/blocks:go_default_library",
"//consensus-types/interfaces:go_default_library",
"//consensus-types/primitives:go_default_library",
"//encoding/bytesutil:go_default_library",
"//time/slots:go_default_library",
@@ -22,11 +26,15 @@ go_library(
go_test(
name = "go_default_test",
srcs = ["fetcher_test.go"],
srcs = [
"blocker_test.go",
"stater_test.go",
],
embed = [":go_default_library"],
deps = [
"//beacon-chain/blockchain/testing:go_default_library",
"//beacon-chain/db/testing:go_default_library",
"//beacon-chain/rpc/testutil:go_default_library",
"//beacon-chain/state/state-native:go_default_library",
"//beacon-chain/state/stategen:go_default_library",
"//beacon-chain/state/stategen/mock:go_default_library",

View File

@@ -0,0 +1,108 @@
package lookup
import (
"context"
"strconv"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/blockchain"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/db"
"github.com/prysmaticlabs/prysm/v4/consensus-types/interfaces"
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
)
// BlockIdParseError represents an error scenario where a block ID could not be parsed.
type BlockIdParseError struct {
message string
}
// NewBlockIdParseError creates a new error instance.
func NewBlockIdParseError(reason error) BlockIdParseError {
return BlockIdParseError{
message: errors.Wrapf(reason, "could not parse block ID").Error(),
}
}
// Error returns the underlying error message.
func (e BlockIdParseError) Error() string {
return e.message
}
// Blocker is responsible for retrieving blocks.
type Blocker interface {
Block(ctx context.Context, id []byte) (interfaces.ReadOnlySignedBeaconBlock, error)
}
// BeaconDbBlocker is an implementation of Blocker. It retrieves blocks from the beacon chain database.
type BeaconDbBlocker struct {
BeaconDB db.ReadOnlyDatabase
ChainInfoFetcher blockchain.ChainInfoFetcher
}
// Block returns the beacon block for a given identifier. The identifier can be one of:
// - "head" (canonical head in node's view)
// - "genesis"
// - "finalized"
// - "justified"
// - <slot>
// - <hex encoded block root with '0x' prefix>
func (p *BeaconDbBlocker) Block(ctx context.Context, id []byte) (interfaces.ReadOnlySignedBeaconBlock, error) {
var err error
var blk interfaces.ReadOnlySignedBeaconBlock
switch string(id) {
case "head":
blk, err = p.ChainInfoFetcher.HeadBlock(ctx)
if err != nil {
return nil, errors.Wrap(err, "could not retrieve head block")
}
case "finalized":
finalized := p.ChainInfoFetcher.FinalizedCheckpt()
finalizedRoot := bytesutil.ToBytes32(finalized.Root)
blk, err = p.BeaconDB.Block(ctx, finalizedRoot)
if err != nil {
return nil, errors.New("could not get finalized block from db")
}
case "genesis":
blk, err = p.BeaconDB.GenesisBlock(ctx)
if err != nil {
return nil, errors.Wrap(err, "could not retrieve genesis block")
}
default:
if len(id) == 32 {
blk, err = p.BeaconDB.Block(ctx, bytesutil.ToBytes32(id))
if err != nil {
return nil, errors.Wrap(err, "could not retrieve block")
}
} else {
slot, err := strconv.ParseUint(string(id), 10, 64)
if err != nil {
e := NewBlockIdParseError(err)
return nil, &e
}
blks, err := p.BeaconDB.BlocksBySlot(ctx, primitives.Slot(slot))
if err != nil {
return nil, errors.Wrapf(err, "could not retrieve blocks for slot %d", slot)
}
_, roots, err := p.BeaconDB.BlockRootsBySlot(ctx, primitives.Slot(slot))
if err != nil {
return nil, errors.Wrapf(err, "could not retrieve block roots for slot %d", slot)
}
numBlks := len(blks)
if numBlks == 0 {
return nil, nil
}
for i, b := range blks {
canonical, err := p.ChainInfoFetcher.IsCanonical(ctx, roots[i])
if err != nil {
return nil, errors.Wrapf(err, "could not determine if block root is canonical")
}
if canonical {
blk = b
break
}
}
}
}
return blk, nil
}

View File

@@ -0,0 +1,144 @@
package lookup
import (
"context"
"fmt"
"reflect"
"testing"
mock "github.com/prysmaticlabs/prysm/v4/beacon-chain/blockchain/testing"
dbtesting "github.com/prysmaticlabs/prysm/v4/beacon-chain/db/testing"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/testutil"
"github.com/prysmaticlabs/prysm/v4/consensus-types/blocks"
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
ethpbalpha "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v4/testing/assert"
"github.com/prysmaticlabs/prysm/v4/testing/require"
"github.com/prysmaticlabs/prysm/v4/testing/util"
)
func TestGetBlock(t *testing.T) {
beaconDB := dbtesting.SetupDB(t)
ctx := context.Background()
genBlk, blkContainers := testutil.FillDBWithBlocks(ctx, t, beaconDB)
canonicalRoots := make(map[[32]byte]bool)
for _, bContr := range blkContainers {
canonicalRoots[bytesutil.ToBytes32(bContr.BlockRoot)] = true
}
headBlock := blkContainers[len(blkContainers)-1]
nextSlot := headBlock.GetPhase0Block().Block.Slot + 1
b2 := util.NewBeaconBlock()
b2.Block.Slot = 30
b2.Block.ParentRoot = bytesutil.PadTo([]byte{1}, 32)
util.SaveBlock(t, ctx, beaconDB, b2)
b3 := util.NewBeaconBlock()
b3.Block.Slot = 30
b3.Block.ParentRoot = bytesutil.PadTo([]byte{4}, 32)
util.SaveBlock(t, ctx, beaconDB, b3)
b4 := util.NewBeaconBlock()
b4.Block.Slot = nextSlot
b4.Block.ParentRoot = bytesutil.PadTo([]byte{8}, 32)
util.SaveBlock(t, ctx, beaconDB, b4)
wsb, err := blocks.NewSignedBeaconBlock(headBlock.Block.(*ethpbalpha.BeaconBlockContainer_Phase0Block).Phase0Block)
require.NoError(t, err)
fetcher := &BeaconDbBlocker{
BeaconDB: beaconDB,
ChainInfoFetcher: &mock.ChainService{
DB: beaconDB,
Block: wsb,
Root: headBlock.BlockRoot,
FinalizedCheckPoint: &ethpbalpha.Checkpoint{Root: blkContainers[64].BlockRoot},
CanonicalRoots: canonicalRoots,
},
}
root, err := genBlk.Block.HashTreeRoot()
require.NoError(t, err)
tests := []struct {
name string
blockID []byte
want *ethpbalpha.SignedBeaconBlock
wantErr bool
}{
{
name: "slot",
blockID: []byte("30"),
want: blkContainers[30].Block.(*ethpbalpha.BeaconBlockContainer_Phase0Block).Phase0Block,
},
{
name: "bad formatting",
blockID: []byte("3bad0"),
wantErr: true,
},
{
name: "canonical",
blockID: []byte("30"),
want: blkContainers[30].Block.(*ethpbalpha.BeaconBlockContainer_Phase0Block).Phase0Block,
},
{
name: "non canonical",
blockID: []byte(fmt.Sprintf("%d", nextSlot)),
want: nil,
},
{
name: "head",
blockID: []byte("head"),
want: headBlock.Block.(*ethpbalpha.BeaconBlockContainer_Phase0Block).Phase0Block,
},
{
name: "finalized",
blockID: []byte("finalized"),
want: blkContainers[64].Block.(*ethpbalpha.BeaconBlockContainer_Phase0Block).Phase0Block,
},
{
name: "genesis",
blockID: []byte("genesis"),
want: genBlk,
},
{
name: "genesis root",
blockID: root[:],
want: genBlk,
},
{
name: "root",
blockID: blkContainers[20].BlockRoot,
want: blkContainers[20].Block.(*ethpbalpha.BeaconBlockContainer_Phase0Block).Phase0Block,
},
{
name: "non-existent root",
blockID: bytesutil.PadTo([]byte("hi there"), 32),
want: nil,
},
{
name: "no block",
blockID: []byte("105"),
want: nil,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result, err := fetcher.Block(ctx, tt.blockID)
if tt.wantErr {
assert.NotEqual(t, err, nil, "no error has been returned")
return
}
if tt.want == nil {
assert.Equal(t, nil, result)
return
}
require.NoError(t, err)
pbBlock, err := result.PbPhase0Block()
require.NoError(t, err)
if !reflect.DeepEqual(pbBlock, tt.want) {
t.Error("Expected blocks to equal")
}
})
}
}

View File

@@ -1,4 +1,4 @@
package statefetcher
package lookup
import (
"bytes"
@@ -71,15 +71,15 @@ func (e *StateRootNotFoundError) Error() string {
return e.message
}
// Fetcher is responsible for retrieving info related with the beacon chain.
type Fetcher interface {
State(ctx context.Context, stateId []byte) (state.BeaconState, error)
StateRoot(ctx context.Context, stateId []byte) ([]byte, error)
// Stater is responsible for retrieving states.
type Stater interface {
State(ctx context.Context, id []byte) (state.BeaconState, error)
StateRoot(ctx context.Context, id []byte) ([]byte, error)
StateBySlot(ctx context.Context, slot primitives.Slot) (state.BeaconState, error)
}
// StateProvider is a real implementation of Fetcher.
type StateProvider struct {
// BeaconDbStater is an implementation of Stater. It retrieves states from the beacon chain database.
type BeaconDbStater struct {
BeaconDB db.ReadOnlyDatabase
ChainInfoFetcher blockchain.ChainInfoFetcher
GenesisTimeFetcher blockchain.TimeFetcher
@@ -94,7 +94,7 @@ type StateProvider struct {
// - "justified"
// - <slot>
// - <hex encoded state root with '0x' prefix>
func (p *StateProvider) State(ctx context.Context, stateId []byte) (state.BeaconState, error) {
func (p *BeaconDbStater) State(ctx context.Context, stateId []byte) (state.BeaconState, error) {
var (
s state.BeaconState
err error
@@ -164,7 +164,7 @@ func (p *StateProvider) State(ctx context.Context, stateId []byte) (state.Beacon
// - "justified"
// - <slot>
// - <hex encoded state root with '0x' prefix>
func (p *StateProvider) StateRoot(ctx context.Context, stateId []byte) (root []byte, err error) {
func (p *BeaconDbStater) StateRoot(ctx context.Context, stateId []byte) (root []byte, err error) {
stateIdString := strings.ToLower(string(stateId))
switch stateIdString {
case "head":
@@ -192,7 +192,7 @@ func (p *StateProvider) StateRoot(ctx context.Context, stateId []byte) (root []b
return root, err
}
func (p *StateProvider) stateByRoot(ctx context.Context, stateRoot []byte) (state.BeaconState, error) {
func (p *BeaconDbStater) stateByRoot(ctx context.Context, stateRoot []byte) (state.BeaconState, error) {
headState, err := p.ChainInfoFetcher.HeadStateReadOnly(ctx)
if err != nil {
return nil, errors.Wrap(err, "could not get head state")
@@ -213,7 +213,7 @@ func (p *StateProvider) stateByRoot(ctx context.Context, stateRoot []byte) (stat
// between the found state's slot and the target slot.
// process_blocks is applied for all canonical blocks, and process_slots is called for any skipped
// slots, or slots following the most recent canonical block up to and including the target slot.
func (p *StateProvider) StateBySlot(ctx context.Context, target primitives.Slot) (state.BeaconState, error) {
func (p *BeaconDbStater) StateBySlot(ctx context.Context, target primitives.Slot) (state.BeaconState, error) {
ctx, span := trace.StartSpan(ctx, "statefetcher.StateBySlot")
defer span.End()
@@ -229,7 +229,7 @@ func (p *StateProvider) StateBySlot(ctx context.Context, target primitives.Slot)
return st, nil
}
func (p *StateProvider) headStateRoot(ctx context.Context) ([]byte, error) {
func (p *BeaconDbStater) headStateRoot(ctx context.Context) ([]byte, error) {
b, err := p.ChainInfoFetcher.HeadBlock(ctx)
if err != nil {
return nil, errors.Wrap(err, "could not get head block")
@@ -241,7 +241,7 @@ func (p *StateProvider) headStateRoot(ctx context.Context) ([]byte, error) {
return stateRoot[:], nil
}
func (p *StateProvider) genesisStateRoot(ctx context.Context) ([]byte, error) {
func (p *BeaconDbStater) genesisStateRoot(ctx context.Context) ([]byte, error) {
b, err := p.BeaconDB.GenesisBlock(ctx)
if err != nil {
return nil, errors.Wrap(err, "could not get genesis block")
@@ -253,7 +253,7 @@ func (p *StateProvider) genesisStateRoot(ctx context.Context) ([]byte, error) {
return stateRoot[:], nil
}
func (p *StateProvider) finalizedStateRoot(ctx context.Context) ([]byte, error) {
func (p *BeaconDbStater) finalizedStateRoot(ctx context.Context) ([]byte, error) {
cp, err := p.BeaconDB.FinalizedCheckpoint(ctx)
if err != nil {
return nil, errors.Wrap(err, "could not get finalized checkpoint")
@@ -269,7 +269,7 @@ func (p *StateProvider) finalizedStateRoot(ctx context.Context) ([]byte, error)
return stateRoot[:], nil
}
func (p *StateProvider) justifiedStateRoot(ctx context.Context) ([]byte, error) {
func (p *BeaconDbStater) justifiedStateRoot(ctx context.Context) ([]byte, error) {
cp, err := p.BeaconDB.JustifiedCheckpoint(ctx)
if err != nil {
return nil, errors.Wrap(err, "could not get justified checkpoint")
@@ -285,7 +285,7 @@ func (p *StateProvider) justifiedStateRoot(ctx context.Context) ([]byte, error)
return stateRoot[:], nil
}
func (p *StateProvider) stateRootByRoot(ctx context.Context, stateRoot []byte) ([]byte, error) {
func (p *BeaconDbStater) stateRootByRoot(ctx context.Context, stateRoot []byte) ([]byte, error) {
var r [32]byte
copy(r[:], stateRoot)
headState, err := p.ChainInfoFetcher.HeadStateReadOnly(ctx)
@@ -302,7 +302,7 @@ func (p *StateProvider) stateRootByRoot(ctx context.Context, stateRoot []byte) (
return nil, &rootNotFoundErr
}
func (p *StateProvider) stateRootBySlot(ctx context.Context, slot primitives.Slot) ([]byte, error) {
func (p *BeaconDbStater) stateRootBySlot(ctx context.Context, slot primitives.Slot) ([]byte, error) {
currentSlot := p.GenesisTimeFetcher.CurrentSlot()
if slot > currentSlot {
return nil, errors.New("slot cannot be in the future")

View File

@@ -1,4 +1,4 @@
package statefetcher
package lookup
import (
"context"
@@ -38,7 +38,7 @@ func TestGetState(t *testing.T) {
require.NoError(t, err)
t.Run("head", func(t *testing.T) {
p := StateProvider{
p := BeaconDbStater{
ChainInfoFetcher: &chainMock.ChainService{State: newBeaconState},
}
@@ -78,7 +78,7 @@ func TestGetState(t *testing.T) {
cs := &mockstategen.MockCurrentSlotter{Slot: bs.Slot() + 1}
ch := stategen.NewCanonicalHistory(db, cc, cs)
currentSlot := primitives.Slot(0)
p := StateProvider{
p := BeaconDbStater{
BeaconDB: db,
ReplayerBuilder: ch,
GenesisTimeFetcher: &chainMock.ChainService{Slot: &currentSlot},
@@ -98,7 +98,7 @@ func TestGetState(t *testing.T) {
replayer.SetMockStateForSlot(newBeaconState, params.BeaconConfig().SlotsPerEpoch*10)
stateGen.StatesByRoot[stateRoot] = newBeaconState
p := StateProvider{
p := BeaconDbStater{
ChainInfoFetcher: &chainMock.ChainService{
FinalizedCheckPoint: &ethpb.Checkpoint{
Root: stateRoot[:],
@@ -122,7 +122,7 @@ func TestGetState(t *testing.T) {
replayer.SetMockStateForSlot(newBeaconState, params.BeaconConfig().SlotsPerEpoch*10)
stateGen.StatesByRoot[stateRoot] = newBeaconState
p := StateProvider{
p := BeaconDbStater{
ChainInfoFetcher: &chainMock.ChainService{
CurrentJustifiedCheckPoint: &ethpb.Checkpoint{
Root: stateRoot[:],
@@ -146,7 +146,7 @@ func TestGetState(t *testing.T) {
stateGen := mockstategen.NewMockService()
stateGen.StatesByRoot[bytesutil.ToBytes32(stateId)] = newBeaconState
p := StateProvider{
p := BeaconDbStater{
ChainInfoFetcher: &chainMock.ChainService{State: newBeaconState},
StateGenService: stateGen,
}
@@ -159,7 +159,7 @@ func TestGetState(t *testing.T) {
})
t.Run("hex_root_not_found", func(t *testing.T) {
p := StateProvider{
p := BeaconDbStater{
ChainInfoFetcher: &chainMock.ChainService{State: newBeaconState},
}
stateId, err := hexutil.Decode("0x" + strings.Repeat("f", 64))
@@ -169,7 +169,7 @@ func TestGetState(t *testing.T) {
})
t.Run("slot", func(t *testing.T) {
p := StateProvider{
p := BeaconDbStater{
GenesisTimeFetcher: &chainMock.ChainService{Slot: &headSlot},
ChainInfoFetcher: &chainMock.ChainService{
CanonicalRoots: map[[32]byte]bool{
@@ -188,7 +188,7 @@ func TestGetState(t *testing.T) {
})
t.Run("invalid_state", func(t *testing.T) {
p := StateProvider{}
p := BeaconDbStater{}
_, err := p.State(ctx, []byte("foo"))
require.ErrorContains(t, "could not parse state ID", err)
})
@@ -212,7 +212,7 @@ func TestGetStateRoot(t *testing.T) {
b.Block.StateRoot = stateRoot[:]
wsb, err := blocks.NewSignedBeaconBlock(b)
require.NoError(t, err)
p := StateProvider{
p := BeaconDbStater{
ChainInfoFetcher: &chainMock.ChainService{
State: newBeaconState,
Block: wsb,
@@ -241,7 +241,7 @@ func TestGetStateRoot(t *testing.T) {
require.NoError(t, db.SaveGenesisBlockRoot(ctx, r))
require.NoError(t, db.SaveState(ctx, bs, r))
p := StateProvider{
p := BeaconDbStater{
BeaconDB: db,
}
@@ -275,7 +275,7 @@ func TestGetStateRoot(t *testing.T) {
require.NoError(t, db.SaveState(ctx, st, root))
require.NoError(t, db.SaveFinalizedCheckpoint(ctx, cp))
p := StateProvider{
p := BeaconDbStater{
BeaconDB: db,
}
@@ -306,7 +306,7 @@ func TestGetStateRoot(t *testing.T) {
require.NoError(t, db.SaveState(ctx, st, root))
require.NoError(t, db.SaveJustifiedCheckpoint(ctx, cp))
p := StateProvider{
p := BeaconDbStater{
BeaconDB: db,
}
@@ -319,7 +319,7 @@ func TestGetStateRoot(t *testing.T) {
stateId, err := hexutil.Decode("0x" + strings.Repeat("0", 63) + "1")
require.NoError(t, err)
p := StateProvider{
p := BeaconDbStater{
ChainInfoFetcher: &chainMock.ChainService{State: newBeaconState},
}
@@ -329,7 +329,7 @@ func TestGetStateRoot(t *testing.T) {
})
t.Run("hex_root_not_found", func(t *testing.T) {
p := StateProvider{
p := BeaconDbStater{
ChainInfoFetcher: &chainMock.ChainService{State: newBeaconState},
}
stateId, err := hexutil.Decode("0x" + strings.Repeat("f", 64))
@@ -355,7 +355,7 @@ func TestGetStateRoot(t *testing.T) {
require.NoError(t, db.SaveState(ctx, st, root))
slot := primitives.Slot(40)
p := StateProvider{
p := BeaconDbStater{
GenesisTimeFetcher: &chainMock.ChainService{Slot: &slot},
BeaconDB: db,
}
@@ -366,7 +366,7 @@ func TestGetStateRoot(t *testing.T) {
})
t.Run("slot_too_big", func(t *testing.T) {
p := StateProvider{
p := BeaconDbStater{
GenesisTimeFetcher: &chainMock.ChainService{
Genesis: time.Now(),
},
@@ -376,7 +376,7 @@ func TestGetStateRoot(t *testing.T) {
})
t.Run("invalid_state", func(t *testing.T) {
p := StateProvider{}
p := BeaconDbStater{}
_, err := p.StateRoot(ctx, []byte("foo"))
require.ErrorContains(t, "could not parse state ID", err)
})
@@ -389,7 +389,7 @@ func TestNewStateNotFoundError(t *testing.T) {
func TestStateBySlot_FutureSlot(t *testing.T) {
slot := primitives.Slot(100)
p := StateProvider{GenesisTimeFetcher: &chainMock.ChainService{Slot: &slot}}
p := BeaconDbStater{GenesisTimeFetcher: &chainMock.ChainService{Slot: &slot}}
_, err := p.StateBySlot(context.Background(), 101)
assert.ErrorContains(t, "requested slot is in the future", err)
}
@@ -403,7 +403,7 @@ func TestStateBySlot_AfterHeadSlot(t *testing.T) {
mock := &chainMock.ChainService{State: headSt, Slot: &currentSlot}
mockReplayer := mockstategen.NewMockReplayerBuilder()
mockReplayer.SetMockStateForSlot(slotSt, 101)
p := StateProvider{ChainInfoFetcher: mock, GenesisTimeFetcher: mock, ReplayerBuilder: mockReplayer}
p := BeaconDbStater{ChainInfoFetcher: mock, GenesisTimeFetcher: mock, ReplayerBuilder: mockReplayer}
st, err := p.StateBySlot(context.Background(), 101)
require.NoError(t, err)
assert.Equal(t, primitives.Slot(101), st.Slot())

View File

@@ -171,7 +171,7 @@ func (vs *Server) GetBeaconBlock(ctx context.Context, req *ethpb.BlockRequest) (
Slot: blk.Slot,
BlockParentRoot: blk.ParentRoot,
ProposerIndex: blk.ProposerIndex,
Blob: b,
Blob: b.Data,
KzgCommitment: commitments[i][:],
KzgProof: proofs[i][:],
}
@@ -338,10 +338,6 @@ func (vs *Server) proposeGenericBeaconBlock(ctx context.Context, req *ethpb.Gene
scs := make([]*ethpb.BlobSidecar, len(b.Deneb.Blobs))
for i, sidecar := range b.Deneb.Blobs {
scs[i] = sidecar.Message
// Hehehe skip index 1 and let peers handle it.
if sidecar.Message.Index == 1 {
continue
}
if err := vs.P2P.BroadcastBlob(ctx, sidecar.Message.Index, sidecar); err != nil {
return nil, errors.Wrap(err, "could not broadcast blob sidecar")
}

View File

@@ -8,6 +8,7 @@ import (
"net"
"sync"
"github.com/gorilla/mux"
middleware "github.com/grpc-ecosystem/go-grpc-middleware"
recovery "github.com/grpc-ecosystem/go-grpc-middleware/recovery"
grpcopentracing "github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing"
@@ -32,12 +33,13 @@ import (
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/debug"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/events"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/node"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/rewards"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/validator"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/lookup"
beaconv1alpha1 "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/prysm/v1alpha1/beacon"
debugv1alpha1 "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/prysm/v1alpha1/debug"
nodev1alpha1 "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/prysm/v1alpha1/node"
validatorv1alpha1 "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/prysm/v1alpha1/validator"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/statefetcher"
slasherservice "github.com/prysmaticlabs/prysm/v4/beacon-chain/slasher"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state/stategen"
chainSync "github.com/prysmaticlabs/prysm/v4/beacon-chain/sync"
@@ -117,6 +119,7 @@ type Config struct {
ProposerIdsCache *cache.ProposerPayloadIDsCache
OptimisticModeFetcher blockchain.OptimisticModeFetcher
BlockBuilder builder.BlockBuilder
Router *mux.Router
}
// NewService instantiates a new RPC service instance that will
@@ -189,6 +192,25 @@ func (s *Service) Start() {
}
withCache := stategen.WithCache(stateCache)
ch := stategen.NewCanonicalHistory(s.cfg.BeaconDB, s.cfg.ChainInfoFetcher, s.cfg.ChainInfoFetcher, withCache)
stater := &lookup.BeaconDbStater{
BeaconDB: s.cfg.BeaconDB,
ChainInfoFetcher: s.cfg.ChainInfoFetcher,
GenesisTimeFetcher: s.cfg.GenesisTimeFetcher,
StateGenService: s.cfg.StateGen,
ReplayerBuilder: ch,
}
blocker := &lookup.BeaconDbBlocker{
BeaconDB: s.cfg.BeaconDB,
ChainInfoFetcher: s.cfg.ChainInfoFetcher,
}
rewardsServer := &rewards.Server{
Blocker: blocker,
OptimisticModeFetcher: s.cfg.OptimisticModeFetcher,
FinalizationFetcher: s.cfg.FinalizationFetcher,
ReplayerBuilder: ch,
}
s.cfg.Router.HandleFunc("/eth/v1/beacon/rewards/blocks/{block_id}", rewardsServer.BlockRewards)
validatorServer := &validatorv1alpha1.Server{
Ctx: s.ctx,
@@ -226,21 +248,15 @@ func (s *Service) Start() {
BLSChangesPool: s.cfg.BLSChangesPool,
}
validatorServerV1 := &validator.Server{
HeadFetcher: s.cfg.HeadFetcher,
TimeFetcher: s.cfg.GenesisTimeFetcher,
SyncChecker: s.cfg.SyncService,
OptimisticModeFetcher: s.cfg.OptimisticModeFetcher,
AttestationsPool: s.cfg.AttestationsPool,
PeerManager: s.cfg.PeerManager,
Broadcaster: s.cfg.Broadcaster,
V1Alpha1Server: validatorServer,
StateFetcher: &statefetcher.StateProvider{
BeaconDB: s.cfg.BeaconDB,
ChainInfoFetcher: s.cfg.ChainInfoFetcher,
GenesisTimeFetcher: s.cfg.GenesisTimeFetcher,
StateGenService: s.cfg.StateGen,
ReplayerBuilder: ch,
},
HeadFetcher: s.cfg.HeadFetcher,
TimeFetcher: s.cfg.GenesisTimeFetcher,
SyncChecker: s.cfg.SyncService,
OptimisticModeFetcher: s.cfg.OptimisticModeFetcher,
AttestationsPool: s.cfg.AttestationsPool,
PeerManager: s.cfg.PeerManager,
Broadcaster: s.cfg.Broadcaster,
V1Alpha1Server: validatorServer,
Stater: stater,
SyncCommitteePool: s.cfg.SyncCommitteeObjectPool,
ProposerSlotIndexCache: s.cfg.ProposerIdsCache,
ChainInfoFetcher: s.cfg.ChainInfoFetcher,
@@ -298,24 +314,19 @@ func (s *Service) Start() {
ReplayerBuilder: ch,
}
beaconChainServerV1 := &beacon.Server{
CanonicalHistory: ch,
BeaconDB: s.cfg.BeaconDB,
AttestationsPool: s.cfg.AttestationsPool,
SlashingsPool: s.cfg.SlashingsPool,
ChainInfoFetcher: s.cfg.ChainInfoFetcher,
GenesisTimeFetcher: s.cfg.GenesisTimeFetcher,
BlockNotifier: s.cfg.BlockNotifier,
OperationNotifier: s.cfg.OperationNotifier,
Broadcaster: s.cfg.Broadcaster,
BlockReceiver: s.cfg.BlockReceiver,
StateGenService: s.cfg.StateGen,
StateFetcher: &statefetcher.StateProvider{
BeaconDB: s.cfg.BeaconDB,
ChainInfoFetcher: s.cfg.ChainInfoFetcher,
GenesisTimeFetcher: s.cfg.GenesisTimeFetcher,
StateGenService: s.cfg.StateGen,
ReplayerBuilder: ch,
},
CanonicalHistory: ch,
BeaconDB: s.cfg.BeaconDB,
AttestationsPool: s.cfg.AttestationsPool,
SlashingsPool: s.cfg.SlashingsPool,
ChainInfoFetcher: s.cfg.ChainInfoFetcher,
GenesisTimeFetcher: s.cfg.GenesisTimeFetcher,
BlockNotifier: s.cfg.BlockNotifier,
OperationNotifier: s.cfg.OperationNotifier,
Broadcaster: s.cfg.Broadcaster,
BlockReceiver: s.cfg.BlockReceiver,
StateGenService: s.cfg.StateGen,
Stater: stater,
Blocker: blocker,
OptimisticModeFetcher: s.cfg.OptimisticModeFetcher,
HeadFetcher: s.cfg.HeadFetcher,
VoluntaryExitsPool: s.cfg.ExitPool,
@@ -350,15 +361,9 @@ func (s *Service) Start() {
ReplayerBuilder: ch,
}
debugServerV1 := &debug.Server{
BeaconDB: s.cfg.BeaconDB,
HeadFetcher: s.cfg.HeadFetcher,
StateFetcher: &statefetcher.StateProvider{
BeaconDB: s.cfg.BeaconDB,
ChainInfoFetcher: s.cfg.ChainInfoFetcher,
GenesisTimeFetcher: s.cfg.GenesisTimeFetcher,
StateGenService: s.cfg.StateGen,
ReplayerBuilder: ch,
},
BeaconDB: s.cfg.BeaconDB,
HeadFetcher: s.cfg.HeadFetcher,
Stater: stater,
OptimisticModeFetcher: s.cfg.OptimisticModeFetcher,
ForkFetcher: s.cfg.ForkFetcher,
ForkchoiceFetcher: s.cfg.ForkchoiceFetcher,

View File

@@ -7,6 +7,7 @@ import (
"testing"
"time"
"github.com/gorilla/mux"
mock "github.com/prysmaticlabs/prysm/v4/beacon-chain/blockchain/testing"
mockExecution "github.com/prysmaticlabs/prysm/v4/beacon-chain/execution/testing"
mockSync "github.com/prysmaticlabs/prysm/v4/beacon-chain/sync/initial-sync/testing"
@@ -35,6 +36,7 @@ func TestLifecycle_OK(t *testing.T) {
GenesisTimeFetcher: chainService,
ExecutionChainService: &mockExecution.Chain{},
StateNotifier: chainService.StateNotifier(),
Router: mux.NewRouter(),
})
rpcService.Start()
@@ -75,6 +77,7 @@ func TestRPC_InsecureEndpoint(t *testing.T) {
HeadFetcher: chainService,
ExecutionChainService: &mockExecution.Chain{},
StateNotifier: chainService.StateNotifier(),
Router: mux.NewRouter(),
})
rpcService.Start()

View File

@@ -4,15 +4,24 @@ go_library(
name = "go_default_library",
testonly = True,
srcs = [
"db.go",
"mock_blocker.go",
"mock_exec_chain_info_fetcher.go",
"mock_genesis_timefetcher.go",
"mock_state_fetcher.go",
"mock_stater.go",
],
importpath = "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/testutil",
visibility = ["//beacon-chain:__subpackages__"],
deps = [
"//beacon-chain/db:go_default_library",
"//beacon-chain/state:go_default_library",
"//config/params:go_default_library",
"//consensus-types/blocks:go_default_library",
"//consensus-types/interfaces:go_default_library",
"//consensus-types/primitives:go_default_library",
"//encoding/bytesutil:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
"//testing/require:go_default_library",
"//testing/util:go_default_library",
],
)

View File

@@ -0,0 +1,51 @@
package testutil
import (
"context"
"testing"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/db"
"github.com/prysmaticlabs/prysm/v4/consensus-types/blocks"
"github.com/prysmaticlabs/prysm/v4/consensus-types/interfaces"
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
ethpbalpha "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v4/testing/require"
"github.com/prysmaticlabs/prysm/v4/testing/util"
)
func FillDBWithBlocks(ctx context.Context, t *testing.T, beaconDB db.Database) (*ethpbalpha.SignedBeaconBlock, []*ethpbalpha.BeaconBlockContainer) {
parentRoot := [32]byte{1, 2, 3}
genBlk := util.NewBeaconBlock()
genBlk.Block.ParentRoot = parentRoot[:]
root, err := genBlk.Block.HashTreeRoot()
require.NoError(t, err)
util.SaveBlock(t, ctx, beaconDB, genBlk)
require.NoError(t, beaconDB.SaveGenesisBlockRoot(ctx, root))
count := primitives.Slot(100)
blks := make([]interfaces.ReadOnlySignedBeaconBlock, count)
blkContainers := make([]*ethpbalpha.BeaconBlockContainer, count)
for i := primitives.Slot(0); i < count; i++ {
b := util.NewBeaconBlock()
b.Block.Slot = i
b.Block.ParentRoot = bytesutil.PadTo([]byte{uint8(i)}, 32)
root, err := b.Block.HashTreeRoot()
require.NoError(t, err)
blks[i], err = blocks.NewSignedBeaconBlock(b)
require.NoError(t, err)
blkContainers[i] = &ethpbalpha.BeaconBlockContainer{
Block: &ethpbalpha.BeaconBlockContainer_Phase0Block{Phase0Block: b},
BlockRoot: root[:],
}
}
require.NoError(t, beaconDB.SaveBlocks(ctx, blks))
headRoot := bytesutil.ToBytes32(blkContainers[len(blks)-1].BlockRoot)
summary := &ethpbalpha.StateSummary{
Root: headRoot[:],
Slot: blkContainers[len(blks)-1].Block.(*ethpbalpha.BeaconBlockContainer_Phase0Block).Phase0Block.Block.Slot,
}
require.NoError(t, beaconDB.SaveStateSummary(ctx, summary))
require.NoError(t, beaconDB.SaveHeadBlockRoot(ctx, headRoot))
return genBlk, blkContainers
}

View File

@@ -0,0 +1,28 @@
package testutil
import (
"context"
"strconv"
"github.com/prysmaticlabs/prysm/v4/consensus-types/interfaces"
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
)
// MockBlocker is a fake implementation of lookup.Blocker.
type MockBlocker struct {
BlockToReturn interfaces.ReadOnlySignedBeaconBlock
ErrorToReturn error
SlotBlockMap map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock
}
// Block --
func (m *MockBlocker) Block(_ context.Context, b []byte) (interfaces.ReadOnlySignedBeaconBlock, error) {
if m.ErrorToReturn != nil {
return nil, m.ErrorToReturn
}
slotNumber, parseErr := strconv.ParseUint(string(b), 10, 64)
if parseErr != nil {
return m.BlockToReturn, nil
}
return m.SlotBlockMap[primitives.Slot(slotNumber)], nil
}

View File

@@ -7,23 +7,24 @@ import (
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
)
// MockFetcher is a fake implementation of statefetcher.Fetcher.
type MockFetcher struct {
// MockStater is a fake implementation of lookup.Stater.
type MockStater struct {
BeaconState state.BeaconState
BeaconStateRoot []byte
StatesBySlot map[primitives.Slot]state.BeaconState
}
// State --
func (m *MockFetcher) State(context.Context, []byte) (state.BeaconState, error) {
func (m *MockStater) State(context.Context, []byte) (state.BeaconState, error) {
return m.BeaconState, nil
}
// StateRoot --
func (m *MockFetcher) StateRoot(context.Context, []byte) ([]byte, error) {
func (m *MockStater) StateRoot(context.Context, []byte) ([]byte, error) {
return m.BeaconStateRoot, nil
}
func (m *MockFetcher) StateBySlot(_ context.Context, s primitives.Slot) (state.BeaconState, error) {
// StateBySlot --
func (m *MockStater) StateBySlot(_ context.Context, s primitives.Slot) (state.BeaconState, error) {
return m.StatesBySlot[s], nil
}

View File

@@ -45,6 +45,7 @@ func main() {
log.SetLevel(logrus.DebugLevel)
}
r := mux.NewRouter()
gatewayConfig := beaconGateway.DefaultConfig(*enableDebugRPCEndpoints, *httpModules)
muxs := make([]*gateway.PbMux, 0)
if gatewayConfig.V1AlphaPbMux != nil {
@@ -54,6 +55,7 @@ func main() {
muxs = append(muxs, gatewayConfig.EthPbMux)
}
opts := []gateway.Option{
gateway.WithRouter(r),
gateway.WithPbHandlers(muxs),
gateway.WithMuxHandler(gatewayConfig.Handler),
gateway.WithRemoteAddr(*beaconRPC),
@@ -71,10 +73,8 @@ func main() {
log.Fatal(err)
}
r := mux.NewRouter()
r.HandleFunc("/swagger/", gateway.SwaggerServer())
r.HandleFunc("/healthz", healthzServer(gw))
gw.SetRouter(r)
gw.Start()

View File

@@ -108,10 +108,8 @@ func generateTestBlockWithSidecars(t *testing.T, parent [32]byte, slot types.Slo
}
func generateTestSidecar(root [32]byte, block *ethpb.SignedBeaconBlockDeneb, index int, commitment []byte) *ethpb.BlobSidecar {
blob := &enginev1.Blob{
Data: make([]byte, fieldparams.BlobSize),
}
binary.LittleEndian.PutUint64(blob.Data, uint64(index))
blob := make([]byte, fieldparams.BlobSize)
binary.LittleEndian.PutUint64(blob, uint64(index))
sc := &ethpb.BlobSidecar{
BlockRoot: root[:],
Index: uint64(index),

View File

@@ -1,7 +1,6 @@
package sync
import (
"context"
"sync"
"github.com/ethereum/go-ethereum/params"
@@ -135,28 +134,3 @@ func (q *blockAndBlocksQueue) canImport(r [32]byte) (bool, error) {
return len(commitments) == len(bnb.blobs), nil
}
func (q *blockAndBlocksQueue) missingRootAndIndex(ctx context.Context) (map[[32]byte][]uint64, error) {
q.lock.RLock()
defer q.lock.RUnlock()
m := make(map[[32]byte][]uint64)
for r, b := range q.queue {
kzgs, err := b.blk.Block().Body().BlobKzgCommitments()
if err != nil {
return nil, err
}
has := make(map[uint64]bool)
for _, blob := range b.blobs {
has[blob.Index] = true
}
for i := range kzgs {
if has[uint64(i)] {
continue
}
m[r] = append(m[r], uint64(i))
}
}
return m, nil
}

View File

@@ -1,7 +1,6 @@
package sync
import (
"context"
"testing"
"github.com/prysmaticlabs/prysm/v4/consensus-types/blocks"
@@ -107,16 +106,3 @@ func Test_blockAndBlocksQueue(t *testing.T) {
require.Equal(t, false, canImport)
})
}
func Test_blockAndBlocksQueue_missingRootAndIndex(t *testing.T) {
q := newBlockAndBlobs()
sb, err := blocks.NewSignedBeaconBlock(util.HydrateSignedBeaconBlockDeneb(&eth.SignedBeaconBlockDeneb{Block: &eth.BeaconBlockDeneb{}}))
require.NoError(t, err)
b := bytesutil.PadTo([]byte("kzg"), 48)
require.NoError(t, sb.SetBlobKzgCommitments([][]byte{b, b, b}))
require.NoError(t, err)
require.NoError(t, q.addBlock(sb))
m, err := q.missingRootAndIndex(context.Background())
require.NoError(t, err)
t.Log(m)
}

View File

@@ -51,6 +51,9 @@ func filterCanonical(ctx context.Context, blks []blocks.ROBlock, prevRoot *[32]b
func sortedUniqueBlocks(blks []blocks.ROBlock) []blocks.ROBlock {
// Remove duplicate blocks received
sort.Sort(blocks.ROBlockSlice(blks))
if len(blks) < 2 {
return blks
}
u := 0
for i := 1; i < len(blks); i++ {
if blks[i].Root() != blks[u].Root() {
@@ -156,21 +159,21 @@ func (bb *blockRangeBatcher) Next(ctx context.Context, stream libp2pcore.Stream)
return blockBatch{err: errors.Wrap(err, "Could not retrieve blocks")}, false
}
log.WithField("nb.start", nb.start).WithField("nb.end", nb.end).Warn("block batch received")
// make slice with extra +1 capacity in case we want to grow it to also hold the genesis block
rob := make([]blocks.ROBlock, len(blks), len(blks)+1)
goff := 0 // offset for genesis value
rob := make([]blocks.ROBlock, 0)
if nb.start == 0 {
gb, err := bb.genesisBlock(ctx)
if err != nil {
return blockBatch{err: errors.Wrap(err, "could not retrieve genesis block")}, false
}
rob = append(rob, blocks.ROBlock{}) // grow the slice to its capacity to hold the genesis block
rob[0] = gb
goff = 1
rob = append(rob, gb)
}
for i := 0; i < len(blks); i++ {
rob[goff+i] = blocks.NewROBlock(blks[i], roots[i])
rob = append(rob, blocks.NewROBlock(blks[i], roots[i]))
}
// Filter and sort our retrieved blocks, so that
// we only return valid sets of blocks.
rob = sortedUniqueBlocks(rob)

View File

@@ -29,10 +29,12 @@ go_library(
"//beacon-chain/sync:go_default_library",
"//cmd/beacon-chain/flags:go_default_library",
"//config/params:go_default_library",
"//consensus-types/blocks:go_default_library",
"//consensus-types/interfaces:go_default_library",
"//consensus-types/primitives:go_default_library",
"//container/leaky-bucket:go_default_library",
"//crypto/rand:go_default_library",
"//encoding/bytesutil:go_default_library",
"//math:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
"//runtime:go_default_library",

View File

@@ -14,10 +14,12 @@ import (
prysmsync "github.com/prysmaticlabs/prysm/v4/beacon-chain/sync"
"github.com/prysmaticlabs/prysm/v4/cmd/beacon-chain/flags"
"github.com/prysmaticlabs/prysm/v4/config/params"
btypes "github.com/prysmaticlabs/prysm/v4/consensus-types/blocks"
"github.com/prysmaticlabs/prysm/v4/consensus-types/interfaces"
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
leakybucket "github.com/prysmaticlabs/prysm/v4/container/leaky-bucket"
"github.com/prysmaticlabs/prysm/v4/crypto/rand"
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
"github.com/prysmaticlabs/prysm/v4/math"
p2ppb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
"github.com/sirupsen/logrus"
@@ -104,11 +106,13 @@ type fetchRequestParams struct {
// fetchRequestResponse is a combined type to hold results of both successful executions and errors.
// Valid usage pattern will be to check whether result's `err` is nil, before using `blocks`.
type fetchRequestResponse struct {
pid peer.ID
start primitives.Slot
count uint64
blocks []interfaces.ReadOnlySignedBeaconBlock
err error
pid peer.ID
start primitives.Slot
count uint64
blocks []interfaces.ReadOnlySignedBeaconBlock
blobMap map[[32]byte][]*p2ppb.BlobSidecar
blobsPid peer.ID
err error
}
// newBlocksFetcher creates ready to use fetcher.
@@ -274,6 +278,11 @@ func (f *blocksFetcher) handleRequest(ctx context.Context, start primitives.Slot
}
response.blocks, response.pid, response.err = f.fetchBlocksFromPeer(ctx, start, count, peers)
if response.err == nil {
if err := f.fetchBlobsForResponse(ctx, response, peers); err != nil {
response.err = err
}
}
return response
}
@@ -293,45 +302,92 @@ func (f *blocksFetcher) fetchBlocksFromPeer(
Step: 1,
}
for i := 0; i < len(peers); i++ {
blocks, err := f.requestBlocks(ctx, req, peers[i])
if err == nil {
f.p2p.Peers().Scorers().BlockProviderScorer().Touch(peers[i])
return blocks, peers[i], err
} else {
log.WithError(err).Debug("Could not request blocks by range")
p := peers[i]
blocks, err := f.requestBlocks(ctx, req, p)
if err != nil {
log.WithField("peer", p).WithError(err).Debug("Could not request blocks by range from peer")
continue
}
f.p2p.Peers().Scorers().BlockProviderScorer().Touch(p)
return blocks, p, err
}
return nil, "", errNoPeersAvailable
}
// TODO: need to fix the blobs by range rpc to bring this back
/*
func blobRequestsForBlocks(blocks []interfaces.ReadOnlySignedBeaconBlock) (*p2ppb.BlobSidecarsByRangeRequest, error) {
log.WithField("block-len", len(blocks)).Warn("blobRequestsForBlocks 1")
if len(blocks) == 0 {
return nil, nil
}
req := &p2ppb.BlobSidecarsByRangeRequest{
StartSlot: 0,
Count: 0,
}
// Loop through the blocks, looking for the earliest deneb block in the slice.
for i, bl := range blocks {
commits, err := bl.Block().Body().BlobKzgCommitments()
if err != nil {
if errors.Is(err, btypes.ErrUnsupportedGetter) {
continue
}
return nil, err
}
if len(commits) == 0 {
continue
}
if req.Count == 0 {
req.StartSlot = bl.Block().Slot()
}
req.Count = uint64(len(blocks) - i)
break
}
if req.Count == 0 {
return nil, nil
}
return req, nil
}
// fetchBlobsFromPeer fetches blocks from a single randomly selected peer.
func (f *blocksFetcher) fetchBlobsFromPeer(
ctx context.Context,
start primitives.Slot, count uint64,
peers []peer.ID,
) ([]*p2ppb.BlobSidecar, peer.ID, error) {
func (f *blocksFetcher) fetchBlobsForResponse(ctx context.Context, resp *fetchRequestResponse, peers []peer.ID) error {
ctx, span := trace.StartSpan(ctx, "initialsync.fetchBlobsFromPeer")
defer span.End()
peers = f.filterPeers(ctx, peers, peersPercentagePerRequest)
req := &p2ppb.BlobSidecarsByRangeRequest{
StartSlot: start,
Count: count,
req, err := blobRequestsForBlocks(resp.blocks)
if err != nil || req == nil {
return err
}
for i := 0; i < len(peers); i++ {
blobs, err := f.requestBlobs(ctx, req, peers[i])
if err == nil {
f.p2p.Peers().Scorers().BlockProviderScorer().Touch(peers[i])
return blobs, peers[i], err
} else {
log.WithError(err).Debug("Could not request blobs by range")
peers = f.filterPeers(ctx, peers, peersPercentagePerRequest)
// prioritize the peer we got the block slice from, since they are required to have the blobs
for i := range peers {
if peers[i] == resp.pid {
if i == 0 {
break
}
// if the peer we got the blocks from isn't first on the list, swap it to the front
peers[0], peers[i] = peers[i], peers[0]
}
}
return nil, "", errNoPeersAvailable
for i := 0; i < len(peers); i++ {
pid := peers[i]
blobs, err := f.requestBlobs(ctx, req, pid)
if err != nil {
log.WithError(err).Debug("Could not request blobs by range")
continue
}
f.p2p.Peers().Scorers().BlockProviderScorer().Touch(pid)
if resp.blobMap == nil {
resp.blobMap = make(map[[32]byte][]*p2ppb.BlobSidecar)
}
for _, b := range blobs {
resp.blobMap[bytesutil.ToBytes32(b.BlockRoot)] = append(resp.blobMap[bytesutil.ToBytes32(b.BlockRoot)], b)
}
resp.blobsPid = pid
return nil
}
return errNoPeersAvailable
}
*/
// requestBlocks is a wrapper for handling BeaconBlocksByRangeRequest requests/streams.
func (f *blocksFetcher) requestBlocks(
@@ -363,7 +419,6 @@ func (f *blocksFetcher) requestBlocks(
return prysmsync.SendBeaconBlocksByRangeRequest(ctx, f.chain, f.p2p, pid, req, nil)
}
/*
func (f *blocksFetcher) requestBlobs(ctx context.Context, req *p2ppb.BlobSidecarsByRangeRequest, pid peer.ID) ([]*p2ppb.BlobSidecar, error) {
if ctx.Err() != nil {
return nil, ctx.Err()
@@ -385,9 +440,8 @@ func (f *blocksFetcher) requestBlobs(ctx context.Context, req *p2ppb.BlobSidecar
}
f.rateLimiter.Add(pid.String(), int64(req.Count))
l.Unlock()
return prysmsync.SendBlobsSidecarsByRangeRequest(ctx, f.chain, f.p2p, pid, req, nil)
return prysmsync.SendBlobsByRangeRequest(ctx, f.chain, f.p2p, pid, req)
}
*/
// requestBlocksByRoot is a wrapper for handling BeaconBlockByRootsReq requests/streams.
func (f *blocksFetcher) requestBlocksByRoot(

View File

@@ -11,6 +11,7 @@ import (
beaconsync "github.com/prysmaticlabs/prysm/v4/beacon-chain/sync"
"github.com/prysmaticlabs/prysm/v4/consensus-types/interfaces"
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
eth "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v4/time/slots"
"github.com/sirupsen/logrus"
)
@@ -88,8 +89,10 @@ type blocksQueue struct {
// blocksQueueFetchedData is a data container that is returned from a queue on each step.
type blocksQueueFetchedData struct {
pid peer.ID
blocks []interfaces.ReadOnlySignedBeaconBlock
pid peer.ID
blocks []interfaces.ReadOnlySignedBeaconBlock
blobsPid peer.ID
blobMap map[[32]byte][]*eth.BlobSidecar
}
// newBlocksQueue creates initialized priority queue.
@@ -333,6 +336,8 @@ func (q *blocksQueue) onDataReceivedEvent(ctx context.Context) eventHandlerFn {
}
m.pid = response.pid
m.blocks = response.blocks
m.blobMap = response.blobMap
m.blobsPid = response.blobsPid
return stateDataParsed, nil
}
}
@@ -353,8 +358,10 @@ func (q *blocksQueue) onReadyToSendEvent(ctx context.Context) eventHandlerFn {
send := func() (stateID, error) {
data := &blocksQueueFetchedData{
pid: m.pid,
blocks: m.blocks,
pid: m.pid,
blocks: m.blocks,
blobMap: m.blobMap,
blobsPid: m.blobsPid,
}
select {
case <-ctx.Done():

View File

@@ -9,6 +9,7 @@ import (
"github.com/libp2p/go-libp2p/core/peer"
"github.com/prysmaticlabs/prysm/v4/consensus-types/interfaces"
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
prysmTime "github.com/prysmaticlabs/prysm/v4/time"
"github.com/prysmaticlabs/prysm/v4/time/slots"
)
@@ -42,12 +43,14 @@ type stateMachineManager struct {
// stateMachine holds a state of a single block processing FSM.
// Each FSM allows deterministic state transitions: State(S) x Event(E) -> Actions (A), State(S').
type stateMachine struct {
smm *stateMachineManager
start primitives.Slot
state stateID
pid peer.ID
blocks []interfaces.ReadOnlySignedBeaconBlock
updated time.Time
smm *stateMachineManager
start primitives.Slot
state stateID
pid peer.ID
blocks []interfaces.ReadOnlySignedBeaconBlock
blobMap map[[32]byte][]*ethpb.BlobSidecar
blobsPid peer.ID
updated time.Time
}
// eventHandlerFn is an event handler function's signature.

View File

@@ -3,15 +3,18 @@ package initialsync
import (
"context"
"encoding/hex"
"errors"
"fmt"
"time"
"github.com/libp2p/go-libp2p/core/peer"
"github.com/paulbellamy/ratecounter"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/transition"
"github.com/prysmaticlabs/prysm/v4/consensus-types/blocks"
"github.com/prysmaticlabs/prysm/v4/consensus-types/interfaces"
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v4/time/slots"
"github.com/sirupsen/logrus"
)
@@ -131,7 +134,7 @@ func (s *Service) processFetchedData(
defer s.updatePeerScorerStats(data.pid, startSlot)
// Use Batch Block Verify to process and verify batches directly.
if err := s.processBatchedBlocks(ctx, genesis, data.blocks, s.cfg.Chain.ReceiveBlockBatch); err != nil {
if err := s.processBatchedBlocks(ctx, genesis, data.blocks, s.cfg.Chain.ReceiveBlockBatch, data.blobMap); err != nil {
log.WithError(err).Warn("Skip processing batched blocks")
}
}
@@ -247,48 +250,96 @@ func (s *Service) processBlock(
return blockReceiver(ctx, blk, blkRoot)
}
var ErrMissingBlobsForBlockCommitments = errors.New("blobs unavailable for processing block with kzg commitments")
var ErrMisalignedIndices = errors.New("unexpected ordering of blobs for block")
var ErrBlobCommitmentMismatch = errors.New("kzg_commitment in blob does not match block")
func (s *Service) processBatchedBlocks(ctx context.Context, genesis time.Time,
blks []interfaces.ReadOnlySignedBeaconBlock, bFunc batchBlockReceiverFn) error {
blks []interfaces.ReadOnlySignedBeaconBlock, bFunc batchBlockReceiverFn, blobs map[[32]byte][]*ethpb.BlobSidecar) error {
if len(blks) == 0 {
return errors.New("0 blocks provided into method")
}
firstBlock := blks[0]
blkRoot, err := firstBlock.Block().HashTreeRoot()
if err != nil {
blockRoots := make([][32]byte, 0)
unprocessed := make([]interfaces.ReadOnlySignedBeaconBlock, 0)
for i := range blks {
b := blks[i]
root, err := b.Block().HashTreeRoot()
if err != nil {
return err
}
if s.isProcessedBlock(ctx, b, root) {
continue
}
if len(blockRoots) > 0 {
max := len(blockRoots) - 1
proot := blockRoots[max]
if proot != b.Block().ParentRoot() {
pblock := unprocessed[max]
return fmt.Errorf("expected linear block list with parent root of %#x (slot %d) but received %#x (slot %d)",
proot, pblock.Block().Slot(), b.Block().ParentRoot(), b.Block().Slot())
}
}
blockRoots = append(blockRoots, root)
unprocessed = append(unprocessed, b)
// TODO: This blob processing should be moved down into blocks_fetcher.go so that we can
// try other peers if we get blobs that don't match the block commitments.
denebB, err := b.PbDenebBlock()
if err != nil {
if errors.Is(err, blocks.ErrUnsupportedGetter) {
// expected for pre-deneb blocks
continue
}
return errors.Wrapf(err, "unexpected error when checking if block root=%#x is post-deneb", root)
}
kcs := denebB.GetBlock().GetBody().BlobKzgCommitments
if len(kcs) == 0 {
continue
}
bblobs := blobs[root]
if len(bblobs) != len(kcs) {
return errors.Wrapf(ErrMissingBlobsForBlockCommitments, "block root %#x, %d commitments, %d blobs", root, len(kcs), len(bblobs))
}
// make sure commitments match
for ci, kc := range kcs {
blobi := bblobs[ci]
if blobi.Index != uint64(ci) {
return errors.Wrapf(ErrMisalignedIndices, "block root %#x, block commitment %#x, offset %d, blob commitment %#x, Index=%d",
root, kc, ci, blobi.KzgCommitment, blobi.Index)
}
if bytesutil.ToBytes48(kc) != bytesutil.ToBytes48(blobi.KzgCommitment) {
return errors.Wrapf(ErrBlobCommitmentMismatch, "block root %#x, Index %d, block commitment=%#x, blob commitment=%#x",
root, ci, kc, blobi.KzgCommitment)
}
}
}
if len(unprocessed) == 0 {
maxIncoming := blks[len(blks)-1]
maxRoot, err := maxIncoming.Block().HashTreeRoot()
if err != nil {
log.Errorf("TODO: use ROBlock so this kind of silly error handling isn't needed")
}
headSlot := s.cfg.Chain.HeadSlot()
return fmt.Errorf("headSlot:%d, blockSlot:%d , root %#x:%w", headSlot, maxIncoming.Block().Slot(), maxRoot, errBlockAlreadyProcessed)
}
if !s.cfg.Chain.HasBlock(ctx, unprocessed[0].Block().ParentRoot()) {
return fmt.Errorf("%w: %#x (in processBatchedBlocks, slot=%d)", errParentDoesNotExist, unprocessed[0].Block().ParentRoot(), unprocessed[0].Block().Slot())
}
s.logBatchSyncStatus(genesis, unprocessed, blockRoots[0])
for _, root := range blockRoots {
scs, has := blobs[root]
if !has {
continue
}
if err := s.cfg.DB.SaveBlobSidecar(ctx, scs); err != nil {
return errors.Wrapf(err, "failed to save blobs for block %#x", root)
}
}
if err := bFunc(ctx, unprocessed, blockRoots); err != nil {
return err
}
headSlot := s.cfg.Chain.HeadSlot()
for headSlot >= firstBlock.Block().Slot() && s.isProcessedBlock(ctx, firstBlock, blkRoot) {
if len(blks) == 1 {
return fmt.Errorf("headSlot:%d, blockSlot:%d , root %#x:%w", headSlot, firstBlock.Block().Slot(), blkRoot, errBlockAlreadyProcessed)
}
blks = blks[1:]
firstBlock = blks[0]
blkRoot, err = firstBlock.Block().HashTreeRoot()
if err != nil {
return err
}
}
s.logBatchSyncStatus(genesis, blks, blkRoot)
parentRoot := firstBlock.Block().ParentRoot()
if !s.cfg.Chain.HasBlock(ctx, parentRoot) {
return fmt.Errorf("%w: %#x (in processBatchedBlocks, slot=%d)", errParentDoesNotExist, firstBlock.Block().ParentRoot(), firstBlock.Block().Slot())
}
blockRoots := make([][32]byte, len(blks))
blockRoots[0] = blkRoot
for i := 1; i < len(blks); i++ {
b := blks[i]
if b.Block().ParentRoot() != blockRoots[i-1] {
return fmt.Errorf("expected linear block list with parent root of %#x but received %#x",
blockRoots[i-1][:], b.Block().ParentRoot())
}
blkRoot, err := b.Block().HashTreeRoot()
if err != nil {
return err
}
blockRoots[i] = blkRoot
}
return bFunc(ctx, blks, blockRoots)
return nil
}
// updatePeerScorerStats adjusts monitored metrics for a peer.

View File

@@ -449,19 +449,20 @@ func TestService_processBlockBatch(t *testing.T) {
currBlockRoot = blk1Root
}
// Process block normally.
err = s.processBatchedBlocks(ctx, genesis, batch, func(
ctx context.Context, blks []interfaces.ReadOnlySignedBeaconBlock, blockRoots [][32]byte) error {
cbnormal := func(ctx context.Context, blks []interfaces.ReadOnlySignedBeaconBlock, blockRoots [][32]byte) error {
assert.NoError(t, s.cfg.Chain.ReceiveBlockBatch(ctx, blks, blockRoots))
return nil
})
}
// Process block normally.
err = s.processBatchedBlocks(ctx, genesis, batch, cbnormal, nil)
assert.NoError(t, err)
// Duplicate processing should trigger error.
err = s.processBatchedBlocks(ctx, genesis, batch, func(
ctx context.Context, blocks []interfaces.ReadOnlySignedBeaconBlock, blockRoots [][32]byte) error {
cbnil := func(ctx context.Context, blocks []interfaces.ReadOnlySignedBeaconBlock, blockRoots [][32]byte) error {
return nil
})
}
// Duplicate processing should trigger error.
err = s.processBatchedBlocks(ctx, genesis, batch, cbnil, nil)
assert.ErrorContains(t, "block is already processed", err)
var badBatch2 []interfaces.ReadOnlySignedBeaconBlock
@@ -474,19 +475,12 @@ func TestService_processBlockBatch(t *testing.T) {
}
// Bad batch should fail because it is non linear
err = s.processBatchedBlocks(ctx, genesis, badBatch2, func(
ctx context.Context, blks []interfaces.ReadOnlySignedBeaconBlock, blockRoots [][32]byte) error {
return nil
})
err = s.processBatchedBlocks(ctx, genesis, badBatch2, cbnil, nil)
expectedSubErr := "expected linear block list"
assert.ErrorContains(t, expectedSubErr, err)
// Continue normal processing, should proceed w/o errors.
err = s.processBatchedBlocks(ctx, genesis, batch2, func(
ctx context.Context, blks []interfaces.ReadOnlySignedBeaconBlock, blockRoots [][32]byte) error {
assert.NoError(t, s.cfg.Chain.ReceiveBlockBatch(ctx, blks, blockRoots))
return nil
})
err = s.processBatchedBlocks(ctx, genesis, batch2, cbnormal, nil)
assert.NoError(t, err)
assert.Equal(t, primitives.Slot(19), s.cfg.Chain.HeadSlot(), "Unexpected head slot")
})

View File

@@ -2,6 +2,7 @@ package sync
import (
"context"
"fmt"
"time"
libp2pcore "github.com/libp2p/go-libp2p/core"
@@ -64,6 +65,13 @@ func (s *Service) beaconBlocksByRangeRPCHandler(ctx context.Context, msg interfa
ticker: ticker,
}
log.WithField("start-slot", m.StartSlot).WithField("count", m.Count).Warn("BeaconBlocksByRangeRequest")
log.
WithField("start", batcher.start).
WithField("end", batcher.end).
WithField("size", batcher.size).
Warn("batcher")
// prevRoot is used to ensure that returned chains are strictly linear for singular steps
// by comparing the previous root of the block in the list with the current block's parent.
var batch blockBatch
@@ -128,10 +136,18 @@ func (s *Service) writeBlockBatchToStream(ctx context.Context, batch blockBatch,
if err := blocks.BeaconBlockIsNil(b); err != nil {
continue
}
checkr, err := b.Block().HashTreeRoot()
if err != nil {
return err
}
if b.Root() != checkr {
return fmt.Errorf("ROBlock has the wrong root for block at slot %d", b.Block().Slot())
}
if b.IsBlinded() {
blinded = append(blinded, b.ReadOnlySignedBeaconBlock)
continue
}
log.WithField("derp", "preb").WithField("slot", b.Block().Slot()).Warn("writing pre-bellatrix block")
if chunkErr := s.chunkBlockWriter(stream, b); chunkErr != nil {
log.WithError(chunkErr).Debug("Could not send a chunked response")
return chunkErr
@@ -153,6 +169,7 @@ func (s *Service) writeBlockBatchToStream(ctx context.Context, batch blockBatch,
if b.IsBlinded() {
continue
}
log.WithField("derp", "postb").WithField("slot", b.Block().Slot()).Warn("writing blinded block")
if chunkErr := s.chunkBlockWriter(stream, b); chunkErr != nil {
log.WithError(chunkErr).Debug("Could not send a chunked response")
return chunkErr

View File

@@ -21,7 +21,7 @@ func (s *Service) sendRecentBeaconBlocksAndBlobsRequest(ctx context.Context, blo
ctx, cancel := context.WithTimeout(ctx, respTimeout)
defer cancel()
var requestBlobs map[[32]byte]int
requestBlobs := make(map[[32]byte]int)
_, err := SendBeaconBlocksByRootRequest(ctx, s.cfg.chain, s.cfg.p2p, id, blockRoots, func(blk interfaces.ReadOnlySignedBeaconBlock) error {
blkRoot, err := blk.Block().HashTreeRoot()
if err != nil {

View File

@@ -35,7 +35,6 @@ func blobMinReqEpoch(finalized, current primitives.Epoch) primitives.Epoch {
// blobSidecarByRootRPCHandler handles the /eth2/beacon_chain/req/blob_sidecars_by_root/1/ RPC request.
// spec: https://github.com/ethereum/consensus-specs/blob/a7e45db9ac2b60a33e144444969ad3ac0aae3d4c/specs/deneb/p2p-interface.md#blobsidecarsbyroot-v1
func (s *Service) blobSidecarByRootRPCHandler(ctx context.Context, msg interface{}, stream libp2pcore.Stream) error {
log.Warn("Received blob sidecar by root request")
ctx, span := trace.StartSpan(ctx, "sync.blobSidecarByRootRPCHandler")
defer span.End()
ctx, cancel := context.WithTimeout(ctx, ttfbTimeout)
@@ -49,7 +48,6 @@ func (s *Service) blobSidecarByRootRPCHandler(ctx context.Context, msg interface
minReqEpoch := blobMinReqEpoch(s.cfg.chain.FinalizedCheckpt().Epoch, slots.ToEpoch(s.cfg.chain.CurrentSlot()))
blobIdents := *ref
for i := range blobIdents {
log.Warnf("Received blob sidecar request for block %#x, index %d", blobIdents[i].BlockRoot, blobIdents[i].Index)
root, idx := bytesutil.ToBytes32(blobIdents[i].BlockRoot), blobIdents[i].Index
scs, err := s.cfg.beaconDB.BlobSidecarsByRoot(ctx, root)
if err != nil {

View File

@@ -1,6 +1,8 @@
package sync
import (
"fmt"
libp2pcore "github.com/libp2p/go-libp2p/core"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/blockchain"
@@ -71,6 +73,10 @@ func WriteBlockChunk(stream libp2pcore.Stream, chain blockchain.ChainInfoFetcher
obtainedCtx = digest[:]
}
log.
WithField("version", blk.Version()).
WithField("ctx", fmt.Sprintf("%#x", obtainedCtx)).
Warn("writing block to stream")
if err := writeContextToStream(obtainedCtx, stream, chain); err != nil {
return err
}
@@ -151,6 +157,11 @@ func readResponseChunk(stream libp2pcore.Stream, chain blockchain.ForkFetcher, p
return nil, err
}
err = p2p.Encoding().DecodeWithMaxLength(stream, blk)
log.
WithField("slot", blk.Block().Slot()).
WithField("rpc-ctx", fmt.Sprintf("%#x", rpcCtx)).
WithField("version", blk.Version()).
Warn("reading response chunk")
return blk, err
}

View File

@@ -187,3 +187,18 @@ func readChunkEncodedBlobs(stream network.Stream, ff blockchain.ForkFetcher, enc
}
return sidecars, nil
}
func SendBlobsByRangeRequest(ctx context.Context, ci blockchain.ForkFetcher, p2pApi p2p.SenderEncoder, pid peer.ID, req *pb.BlobSidecarsByRangeRequest) ([]*pb.BlobSidecar, error) {
topic, err := p2p.TopicFromMessage(p2p.BlobSidecarsByRangeName, slots.ToEpoch(ci.CurrentSlot()))
if err != nil {
return nil, err
}
log.WithField("topic", topic).Debug("Sending blob by range request")
stream, err := p2pApi.Send(ctx, req, topic, pid)
if err != nil {
return nil, err
}
defer closeStream(stream, log)
return readChunkEncodedBlobs(stream, ci, p2pApi.Encoding())
}

View File

@@ -186,7 +186,6 @@ func (s *Service) Start() {
s.processPendingAttsQueue()
s.maintainPeerStatuses()
s.resyncIfBehind()
s.requestMissingBlobsRoutine(s.ctx)
// Update sync metrics.
async.RunEvery(s.ctx, syncMetricsInterval, s.updateMetrics)

View File

@@ -3,17 +3,12 @@ package sync
import (
"context"
"fmt"
"time"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/blockchain"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/p2p/types"
"github.com/prysmaticlabs/prysm/v4/config/params"
"github.com/prysmaticlabs/prysm/v4/consensus-types/blocks"
"github.com/prysmaticlabs/prysm/v4/consensus-types/interfaces"
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
eth "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v4/runtime/version"
"github.com/prysmaticlabs/prysm/v4/time/slots"
"github.com/sirupsen/logrus"
"google.golang.org/protobuf/proto"
)
@@ -114,62 +109,3 @@ func (s *Service) receiveBlock(ctx context.Context, signed interfaces.ReadOnlySi
}
return nil
}
func (s *Service) requestMissingBlobsRoutine(ctx context.Context) {
time.Sleep(5 * time.Second)
ticker := slots.NewSlotTickerWithOffset(s.cfg.chain.GenesisTime(), time.Second, params.BeaconConfig().SecondsPerSlot)
go func() {
for {
select {
case <-ticker.C():
cp := s.cfg.chain.FinalizedCheckpt()
_, bestPeers := s.cfg.p2p.Peers().BestFinalized(maxPeerRequest, cp.Epoch)
if len(bestPeers) == 0 {
log.Warn("No peers to request missing blobs")
continue
}
var reqs []*eth.BlobIdentifier
m, err := s.blockAndBlobs.missingRootAndIndex(ctx)
if err != nil {
log.WithError(err).Error("Failed to get missing root and index")
continue
}
if len(m) == 0 {
continue
}
for r, indices := range m {
for _, i := range indices {
reqs = append(reqs, &eth.BlobIdentifier{
BlockRoot: r[:],
Index: i,
})
}
}
req := types.BlobSidecarsByRootReq(reqs)
scs, err := SendBlobSidecarByRoot(ctx, s.cfg.chain, s.cfg.p2p, bestPeers[0], &req)
if err != nil {
log.WithError(err).Error("Failed to send blob sidecar by root")
continue
}
for _, sc := range scs {
if err := s.blockAndBlobs.addBlob(sc); err != nil {
log.WithError(err).Error("Failed to add blob")
continue
}
if err := s.importBlockAndBlobs(ctx, bytesutil.ToBytes32(sc.BlockRoot)); err != nil {
log.WithError(err).Error("Failed to import block and blobs")
continue
}
}
case <-ctx.Done():
log.Debug("Context closed, exiting routine")
return
}
}
}()
}

View File

@@ -302,6 +302,6 @@ func FillTestVersions(c *BeaconChainConfig, b byte) {
c.GenesisForkVersion[0] = 0
c.AltairForkVersion[0] = 1
c.BellatrixForkVersion[0] = 2
c.DenebForkVersion[0] = 3
c.CapellaForkVersion[0] = 3
c.DenebForkVersion[0] = 4
}

View File

@@ -160,8 +160,8 @@ func (e executionPayload) WithdrawalsRoot() ([]byte, error) {
return nil, ErrUnsupportedGetter
}
// ExcessiveDataGas --
func (e executionPayload) ExcessiveDataGas() ([]byte, error) {
// ExcessDataGas --
func (e executionPayload) ExcessDataGas() ([]byte, error) {
return nil, ErrUnsupportedGetter
}
@@ -326,8 +326,8 @@ func (e executionPayloadHeader) WithdrawalsRoot() ([]byte, error) {
return nil, ErrUnsupportedGetter
}
// ExcessiveDataGas --
func (e executionPayloadHeader) ExcessiveDataGas() ([]byte, error) {
// ExcessDataGas --
func (e executionPayloadHeader) ExcessDataGas() ([]byte, error) {
return nil, ErrUnsupportedGetter
}
@@ -521,7 +521,7 @@ func (e executionPayloadCapella) WithdrawalsRoot() ([]byte, error) {
return nil, ErrUnsupportedGetter
}
func (e executionPayloadCapella) ExcessiveDataGas() ([]byte, error) {
func (e executionPayloadCapella) ExcessDataGas() ([]byte, error) {
return nil, ErrUnsupportedGetter
}
@@ -687,7 +687,7 @@ func (e executionPayloadHeaderCapella) WithdrawalsRoot() ([]byte, error) {
return e.p.WithdrawalsRoot, nil
}
func (e executionPayloadHeaderCapella) ExcessiveDataGas() ([]byte, error) {
func (e executionPayloadHeaderCapella) ExcessDataGas() ([]byte, error) {
return nil, ErrUnsupportedGetter
}
@@ -762,7 +762,7 @@ func PayloadToHeaderDeneb(payload interfaces.ExecutionData) (*enginev1.Execution
if err != nil {
return nil, err
}
excessDataGas, err := payload.ExcessiveDataGas()
excessDataGas, err := payload.ExcessDataGas()
if err != nil {
return nil, err
}
@@ -986,7 +986,7 @@ func (e executionPayloadHeaderDeneb) WithdrawalsRoot() ([]byte, error) {
return e.p.WithdrawalsRoot, nil
}
func (e executionPayloadHeaderDeneb) ExcessiveDataGas() ([]byte, error) {
func (e executionPayloadHeaderDeneb) ExcessDataGas() ([]byte, error) {
return e.p.ExcessDataGas, nil
}
@@ -1151,7 +1151,7 @@ func (e executionPayloadDeneb) WithdrawalsRoot() ([]byte, error) {
return nil, ErrUnsupportedGetter
}
func (e executionPayloadDeneb) ExcessiveDataGas() ([]byte, error) {
func (e executionPayloadDeneb) ExcessDataGas() ([]byte, error) {
return e.p.ExcessDataGas, nil
}

View File

@@ -228,6 +228,8 @@ func BuildSignedBeaconBlockFromExecutionPayload(
wrappedPayload, wrapErr = WrappedExecutionPayload(p)
case *enginev1.ExecutionPayloadCapella:
wrappedPayload, wrapErr = WrappedExecutionPayloadCapella(p, big.NewInt(0))
case *enginev1.ExecutionPayloadDeneb:
wrappedPayload, wrapErr = WrappedExecutionPayloadDeneb(p, big.NewInt(0))
default:
return nil, fmt.Errorf("%T is not a type of execution payload", p)
}
@@ -316,6 +318,38 @@ func BuildSignedBeaconBlockFromExecutionPayload(
},
Signature: sig[:],
}
case *enginev1.ExecutionPayloadDeneb:
blsToExecutionChanges, err := b.Body().BLSToExecutionChanges()
if err != nil {
return nil, err
}
commitments, err := b.Body().BlobKzgCommitments()
if err != nil {
return nil, err
}
fullBlock = &eth.SignedBeaconBlockDeneb{
Block: &eth.BeaconBlockDeneb{
Slot: b.Slot(),
ProposerIndex: b.ProposerIndex(),
ParentRoot: parentRoot[:],
StateRoot: stateRoot[:],
Body: &eth.BeaconBlockBodyDeneb{
RandaoReveal: randaoReveal[:],
Eth1Data: b.Body().Eth1Data(),
Graffiti: graffiti[:],
ProposerSlashings: b.Body().ProposerSlashings(),
AttesterSlashings: b.Body().AttesterSlashings(),
Attestations: b.Body().Attestations(),
Deposits: b.Body().Deposits(),
VoluntaryExits: b.Body().VoluntaryExits(),
SyncAggregate: syncAgg,
ExecutionPayload: p,
BlsToExecutionChanges: blsToExecutionChanges,
BlobKzgCommitments: commitments,
},
},
Signature: sig[:],
}
default:
return nil, fmt.Errorf("%T is not a type of execution payload", p)
}

View File

@@ -122,7 +122,7 @@ type ExecutionData interface {
Timestamp() uint64
ExtraData() []byte
BaseFeePerGas() []byte
ExcessiveDataGas() ([]byte, error)
ExcessDataGas() ([]byte, error)
BlockHash() []byte
Transactions() ([][]byte, error)
TransactionsRoot() ([]byte, error)

View File

@@ -6,6 +6,7 @@ go_library(
"auth.go",
"endpoint.go",
"external_ip.go",
"writer.go",
],
importpath = "github.com/prysmaticlabs/prysm/v4/network",
visibility = ["//visibility:public"],
@@ -13,6 +14,7 @@ go_library(
"//network/authorization:go_default_library",
"@com_github_golang_jwt_jwt_v4//:go_default_library",
"@com_github_pkg_errors//:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",
],
)

41
network/writer.go Normal file
View File

@@ -0,0 +1,41 @@
package network
import (
"bytes"
"encoding/json"
"io"
"net/http"
"strconv"
log "github.com/sirupsen/logrus"
)
// DefaultErrorJson is a JSON representation of a simple error value, containing only a message and an error code.
type DefaultErrorJson struct {
Message string `json:"message"`
Code int `json:"code"`
}
// WriteJson writes the response message in JSON format.
func WriteJson(w http.ResponseWriter, v any) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
if err := json.NewEncoder(w).Encode(v); err != nil {
log.WithError(err).Error("Could not write response message")
}
}
// WriteError writes the error by manipulating headers and the body of the final response.
func WriteError(w http.ResponseWriter, errJson *DefaultErrorJson) {
j, err := json.Marshal(errJson)
if err != nil {
log.WithError(err).Error("Could not marshal error message")
return
}
w.Header().Set("Content-Length", strconv.Itoa(len(j)))
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(errJson.Code)
if _, err := io.Copy(w, io.NopCloser(bytes.NewReader(j))); err != nil {
log.WithError(err).Error("Could not write error message")
}
}

View File

@@ -36,6 +36,7 @@ type ExecutionBlock struct {
Transactions []*gethtypes.Transaction `json:"transactions"`
TotalDifficulty string `json:"totalDifficulty"`
Withdrawals []*Withdrawal `json:"withdrawals"`
ExcessDataGas []byte `json:"excessDataGas"`
}
func (e *ExecutionBlock) MarshalJSON() ([]byte, error) {
@@ -87,11 +88,10 @@ func (e *ExecutionBlock) UnmarshalJSON(enc []byte) error {
return errors.New("expected `totalDifficulty` field in JSON response")
}
rawWithdrawals, ok := decoded["withdrawals"]
if !ok || rawWithdrawals == nil {
rawWithdrawals, hasW := decoded["withdrawals"]
if !hasW || rawWithdrawals == nil {
e.Version = version.Bellatrix
} else {
e.Version = version.Capella
j := &withdrawalsJson{}
if err := json.Unmarshal(enc, j); err != nil {
return err
@@ -104,6 +104,14 @@ func (e *ExecutionBlock) UnmarshalJSON(enc []byte) error {
}
}
e.Withdrawals = ws
exDG, hasExDG := decoded["excessDataGas"]
if hasExDG && exDG != nil {
e.ExcessDataGas, err = hexutil.Decode(exDG.(string))
e.Version = version.Deneb
} else {
e.Version = version.Capella
}
}
rawTxList, ok := decoded["transactions"]

View File

@@ -11,7 +11,6 @@ import (
sync "sync"
github_com_prysmaticlabs_prysm_v4_consensus_types_primitives "github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
v1 "github.com/prysmaticlabs/prysm/v4/proto/engine/v1"
_ "github.com/prysmaticlabs/prysm/v4/proto/eth/ext"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
@@ -81,7 +80,7 @@ type BlobSidecar struct {
Slot github_com_prysmaticlabs_prysm_v4_consensus_types_primitives.Slot `protobuf:"varint,3,opt,name=slot,proto3" json:"slot,omitempty" cast-type:"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives.Slot"`
BlockParentRoot []byte `protobuf:"bytes,4,opt,name=block_parent_root,json=blockParentRoot,proto3" json:"block_parent_root,omitempty" ssz-size:"32"`
ProposerIndex github_com_prysmaticlabs_prysm_v4_consensus_types_primitives.ValidatorIndex `protobuf:"varint,5,opt,name=proposer_index,json=proposerIndex,proto3" json:"proposer_index,omitempty" cast-type:"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives.ValidatorIndex"`
Blob *v1.Blob `protobuf:"bytes,6,opt,name=blob,proto3" json:"blob,omitempty"`
Blob []byte `protobuf:"bytes,6,opt,name=blob,proto3" json:"blob,omitempty" ssz-size:"131072"`
KzgCommitment []byte `protobuf:"bytes,7,opt,name=kzg_commitment,json=kzgCommitment,proto3" json:"kzg_commitment,omitempty" ssz-size:"48"`
KzgProof []byte `protobuf:"bytes,8,opt,name=kzg_proof,json=kzgProof,proto3" json:"kzg_proof,omitempty" ssz-size:"48"`
}
@@ -153,7 +152,7 @@ func (x *BlobSidecar) GetProposerIndex() github_com_prysmaticlabs_prysm_v4_conse
return github_com_prysmaticlabs_prysm_v4_consensus_types_primitives.ValidatorIndex(0)
}
func (x *BlobSidecar) GetBlob() *v1.Blob {
func (x *BlobSidecar) GetBlob() []byte {
if x != nil {
return x.Blob
}
@@ -292,66 +291,63 @@ var file_proto_prysm_v1alpha1_blobs_proto_rawDesc = []byte{
0x74, 0x6f, 0x12, 0x15, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68,
0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x1a, 0x1b, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x2f, 0x65, 0x74, 0x68, 0x2f, 0x65, 0x78, 0x74, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x26, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x65, 0x6e,
0x67, 0x69, 0x6e, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f,
0x6e, 0x5f, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x4e,
0x0a, 0x0c, 0x42, 0x6c, 0x6f, 0x62, 0x53, 0x69, 0x64, 0x65, 0x63, 0x61, 0x72, 0x73, 0x12, 0x3e,
0x0a, 0x08, 0x73, 0x69, 0x64, 0x65, 0x63, 0x61, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b,
0x32, 0x22, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e,
0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x42, 0x6c, 0x6f, 0x62, 0x53, 0x69, 0x64,
0x65, 0x63, 0x61, 0x72, 0x52, 0x08, 0x73, 0x69, 0x64, 0x65, 0x63, 0x61, 0x72, 0x73, 0x22, 0xd3,
0x03, 0x0a, 0x0b, 0x42, 0x6c, 0x6f, 0x62, 0x53, 0x69, 0x64, 0x65, 0x63, 0x61, 0x72, 0x12, 0x25,
0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x01, 0x20, 0x01,
0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x33, 0x32, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63,
0x6b, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x02,
0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x59, 0x0a, 0x04, 0x73,
0x6c, 0x6f, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x42, 0x45, 0x82, 0xb5, 0x18, 0x41, 0x67,
0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x61,
0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x34,
0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x73,
0x2f, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x2e, 0x53, 0x6c, 0x6f, 0x74,
0x52, 0x04, 0x73, 0x6c, 0x6f, 0x74, 0x12, 0x32, 0x0a, 0x11, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f,
0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28,
0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x33, 0x32, 0x52, 0x0f, 0x62, 0x6c, 0x6f, 0x63, 0x6b,
0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x76, 0x0a, 0x0e, 0x70, 0x72,
0x6f, 0x70, 0x6f, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x05, 0x20, 0x01,
0x28, 0x04, 0x42, 0x4f, 0x82, 0xb5, 0x18, 0x4b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63,
0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73,
0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x34, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e,
0x73, 0x75, 0x73, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74,
0x69, 0x76, 0x65, 0x73, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x6e,
0x64, 0x65, 0x78, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x64,
0x65, 0x78, 0x12, 0x2c, 0x0a, 0x04, 0x62, 0x6c, 0x6f, 0x62, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x18, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x6e, 0x67, 0x69,
0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x6c, 0x6f, 0x62, 0x52, 0x04, 0x62, 0x6c, 0x6f, 0x62,
0x12, 0x2d, 0x0a, 0x0e, 0x6b, 0x7a, 0x67, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65,
0x6e, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x34, 0x38,
0x52, 0x0d, 0x6b, 0x7a, 0x67, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x12,
0x23, 0x0a, 0x09, 0x6b, 0x7a, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x18, 0x08, 0x20, 0x01,
0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x34, 0x38, 0x52, 0x08, 0x6b, 0x7a, 0x67, 0x50,
0x72, 0x6f, 0x6f, 0x66, 0x22, 0x77, 0x0a, 0x11, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x42, 0x6c,
0x6f, 0x62, 0x53, 0x69, 0x64, 0x65, 0x63, 0x61, 0x72, 0x12, 0x3c, 0x0a, 0x07, 0x6d, 0x65, 0x73,
0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x65, 0x74, 0x68,
0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68,
0x61, 0x31, 0x2e, 0x42, 0x6c, 0x6f, 0x62, 0x53, 0x69, 0x64, 0x65, 0x63, 0x61, 0x72, 0x52, 0x07,
0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x24, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61,
0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02,
0x39, 0x36, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x4d, 0x0a,
0x0e, 0x42, 0x6c, 0x6f, 0x62, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12,
0x25, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x01, 0x20,
0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x33, 0x32, 0x52, 0x09, 0x62, 0x6c, 0x6f,
0x63, 0x6b, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18,
0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x42, 0x95, 0x01, 0x0a,
0x19, 0x6f, 0x72, 0x67, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74,
0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x42, 0x0a, 0x42, 0x6c, 0x6f, 0x62,
0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61,
0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x34, 0x2f, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31,
0x3b, 0x65, 0x74, 0x68, 0xaa, 0x02, 0x15, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e,
0x45, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xca, 0x02, 0x15, 0x45,
0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x5c, 0x45, 0x74, 0x68, 0x5c, 0x76, 0x31, 0x61, 0x6c,
0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x4e, 0x0a, 0x0c, 0x42, 0x6c, 0x6f, 0x62, 0x53, 0x69,
0x64, 0x65, 0x63, 0x61, 0x72, 0x73, 0x12, 0x3e, 0x0a, 0x08, 0x73, 0x69, 0x64, 0x65, 0x63, 0x61,
0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72,
0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31,
0x2e, 0x42, 0x6c, 0x6f, 0x62, 0x53, 0x69, 0x64, 0x65, 0x63, 0x61, 0x72, 0x52, 0x08, 0x73, 0x69,
0x64, 0x65, 0x63, 0x61, 0x72, 0x73, 0x22, 0xc5, 0x03, 0x0a, 0x0b, 0x42, 0x6c, 0x6f, 0x62, 0x53,
0x69, 0x64, 0x65, 0x63, 0x61, 0x72, 0x12, 0x25, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f,
0x72, 0x6f, 0x6f, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02,
0x33, 0x32, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x14, 0x0a,
0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x69, 0x6e,
0x64, 0x65, 0x78, 0x12, 0x59, 0x0a, 0x04, 0x73, 0x6c, 0x6f, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28,
0x04, 0x42, 0x45, 0x82, 0xb5, 0x18, 0x41, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f,
0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f,
0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x34, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73,
0x75, 0x73, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69,
0x76, 0x65, 0x73, 0x2e, 0x53, 0x6c, 0x6f, 0x74, 0x52, 0x04, 0x73, 0x6c, 0x6f, 0x74, 0x12, 0x32,
0x0a, 0x11, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x72,
0x6f, 0x6f, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x33,
0x32, 0x52, 0x0f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x52, 0x6f,
0x6f, 0x74, 0x12, 0x76, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x72, 0x5f, 0x69,
0x6e, 0x64, 0x65, 0x78, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x42, 0x4f, 0x82, 0xb5, 0x18, 0x4b,
0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d,
0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76,
0x34, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2d, 0x74, 0x79, 0x70, 0x65,
0x73, 0x2f, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x2e, 0x56, 0x61, 0x6c,
0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x0d, 0x70, 0x72, 0x6f,
0x70, 0x6f, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x1e, 0x0a, 0x04, 0x62, 0x6c,
0x6f, 0x62, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x0a, 0x8a, 0xb5, 0x18, 0x06, 0x31, 0x33,
0x31, 0x30, 0x37, 0x32, 0x52, 0x04, 0x62, 0x6c, 0x6f, 0x62, 0x12, 0x2d, 0x0a, 0x0e, 0x6b, 0x7a,
0x67, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x07, 0x20, 0x01,
0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x34, 0x38, 0x52, 0x0d, 0x6b, 0x7a, 0x67, 0x43,
0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x23, 0x0a, 0x09, 0x6b, 0x7a, 0x67,
0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5,
0x18, 0x02, 0x34, 0x38, 0x52, 0x08, 0x6b, 0x7a, 0x67, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x22, 0x77,
0x0a, 0x11, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x42, 0x6c, 0x6f, 0x62, 0x53, 0x69, 0x64, 0x65,
0x63, 0x61, 0x72, 0x12, 0x3c, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e,
0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x42, 0x6c, 0x6f,
0x62, 0x53, 0x69, 0x64, 0x65, 0x63, 0x61, 0x72, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67,
0x65, 0x12, 0x24, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02,
0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x39, 0x36, 0x52, 0x09, 0x73, 0x69,
0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x4d, 0x0a, 0x0e, 0x42, 0x6c, 0x6f, 0x62, 0x49,
0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x25, 0x0a, 0x0a, 0x62, 0x6c, 0x6f,
0x63, 0x6b, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a,
0xb5, 0x18, 0x02, 0x33, 0x32, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x6f, 0x6f, 0x74,
0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52,
0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x42, 0x95, 0x01, 0x0a, 0x19, 0x6f, 0x72, 0x67, 0x2e, 0x65,
0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c,
0x70, 0x68, 0x61, 0x31, 0x42, 0x0a, 0x42, 0x6c, 0x6f, 0x62, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f,
0x50, 0x01, 0x5a, 0x3a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70,
0x72, 0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79,
0x73, 0x6d, 0x2f, 0x76, 0x34, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x79, 0x73,
0x6d, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x65, 0x74, 0x68, 0xaa, 0x02,
0x15, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x45, 0x74, 0x68, 0x2e, 0x76, 0x31,
0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xca, 0x02, 0x15, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75,
0x6d, 0x5c, 0x45, 0x74, 0x68, 0x5c, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -372,17 +368,15 @@ var file_proto_prysm_v1alpha1_blobs_proto_goTypes = []interface{}{
(*BlobSidecar)(nil), // 1: ethereum.eth.v1alpha1.BlobSidecar
(*SignedBlobSidecar)(nil), // 2: ethereum.eth.v1alpha1.SignedBlobSidecar
(*BlobIdentifier)(nil), // 3: ethereum.eth.v1alpha1.BlobIdentifier
(*v1.Blob)(nil), // 4: ethereum.engine.v1.Blob
}
var file_proto_prysm_v1alpha1_blobs_proto_depIdxs = []int32{
1, // 0: ethereum.eth.v1alpha1.BlobSidecars.sidecars:type_name -> ethereum.eth.v1alpha1.BlobSidecar
4, // 1: ethereum.eth.v1alpha1.BlobSidecar.blob:type_name -> ethereum.engine.v1.Blob
1, // 2: ethereum.eth.v1alpha1.SignedBlobSidecar.message:type_name -> ethereum.eth.v1alpha1.BlobSidecar
3, // [3:3] is the sub-list for method output_type
3, // [3:3] is the sub-list for method input_type
3, // [3:3] is the sub-list for extension type_name
3, // [3:3] is the sub-list for extension extendee
0, // [0:3] is the sub-list for field type_name
1, // 1: ethereum.eth.v1alpha1.SignedBlobSidecar.message:type_name -> ethereum.eth.v1alpha1.BlobSidecar
2, // [2:2] is the sub-list for method output_type
2, // [2:2] is the sub-list for method input_type
2, // [2:2] is the sub-list for extension type_name
2, // [2:2] is the sub-list for extension extendee
0, // [0:2] is the sub-list for field type_name
}
func init() { file_proto_prysm_v1alpha1_blobs_proto_init() }

View File

@@ -16,7 +16,6 @@ syntax = "proto3";
package ethereum.eth.v1alpha1;
import "proto/eth/ext/options.proto";
import "proto/engine/v1/execution_engine.proto";
option csharp_namespace = "Ethereum.Eth.v1alpha1";
option go_package = "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1;eth";
@@ -35,7 +34,7 @@ message BlobSidecar {
uint64 slot = 3 [(ethereum.eth.ext.cast_type) = "github.com/prysmaticlabs/prysm/v4/consensus-types/primitives.Slot"];
bytes block_parent_root = 4 [(ethereum.eth.ext.ssz_size) = "32"];
uint64 proposer_index = 5 [(ethereum.eth.ext.cast_type) = "github.com/prysmaticlabs/prysm/v4/consensus-types/primitives.ValidatorIndex"];
ethereum.engine.v1.Blob blob = 6;
bytes blob = 6 [(ethereum.eth.ext.ssz_size) = "blob.size"];
bytes kzg_commitment = 7 [(ethereum.eth.ext.ssz_size) = "48"];
bytes kzg_proof = 8 [(ethereum.eth.ext.ssz_size) = "48"];
}

View File

@@ -1,5 +1,5 @@
// Code generated by fastssz. DO NOT EDIT.
// Hash: c2adba54004d58a4eb854a7d5e967d92e57d2a845afd4c42cf626bf495553f6a
// Hash: 3f1afdc89f43f99597725dbe7961031f9cfdca4bba74699e747982e8ed2f64c7
package eth
import (
@@ -14435,12 +14435,11 @@ func (b *BlobSidecar) MarshalSSZTo(buf []byte) (dst []byte, err error) {
dst = ssz.MarshalUint64(dst, uint64(b.ProposerIndex))
// Field (5) 'Blob'
if b.Blob == nil {
b.Blob = new(v1.Blob)
}
if dst, err = b.Blob.MarshalSSZTo(dst); err != nil {
if size := len(b.Blob); size != 131072 {
err = ssz.ErrBytesLengthFn("--.Blob", size, 131072)
return
}
dst = append(dst, b.Blob...)
// Field (6) 'KzgCommitment'
if size := len(b.KzgCommitment); size != 48 {
@@ -14489,12 +14488,10 @@ func (b *BlobSidecar) UnmarshalSSZ(buf []byte) error {
b.ProposerIndex = github_com_prysmaticlabs_prysm_v4_consensus_types_primitives.ValidatorIndex(ssz.UnmarshallUint64(buf[80:88]))
// Field (5) 'Blob'
if b.Blob == nil {
b.Blob = new(v1.Blob)
}
if err = b.Blob.UnmarshalSSZ(buf[88:131160]); err != nil {
return err
if cap(b.Blob) == 0 {
b.Blob = make([]byte, 0, len(buf[88:131160]))
}
b.Blob = append(b.Blob, buf[88:131160]...)
// Field (6) 'KzgCommitment'
if cap(b.KzgCommitment) == 0 {
@@ -14550,9 +14547,11 @@ func (b *BlobSidecar) HashTreeRootWith(hh *ssz.Hasher) (err error) {
hh.PutUint64(uint64(b.ProposerIndex))
// Field (5) 'Blob'
if err = b.Blob.HashTreeRootWith(hh); err != nil {
if size := len(b.Blob); size != 131072 {
err = ssz.ErrBytesLengthFn("--.Blob", size, 131072)
return
}
hh.PutBytes(b.Blob)
// Field (6) 'KzgCommitment'
if size := len(b.KzgCommitment); size != 48 {

View File

@@ -69,6 +69,7 @@ go_library(
"//validator/web:go_default_library",
"@com_github_ethereum_go_ethereum//common:go_default_library",
"@com_github_ethereum_go_ethereum//common/hexutil:go_default_library",
"@com_github_gorilla_mux//:go_default_library",
"@com_github_grpc_ecosystem_grpc_gateway_v2//runtime:go_default_library",
"@com_github_pkg_errors//:go_default_library",
"@com_github_prysmaticlabs_fastssz//:go_default_library",

View File

@@ -22,6 +22,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/gorilla/mux"
gwruntime "github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
"github.com/pkg/errors"
fastssz "github.com/prysmaticlabs/fastssz"
@@ -764,6 +765,7 @@ func (c *ValidatorClient) registerRPCGatewayService(cliCtx *cli.Context) error {
Mux: gwmux,
}
opts := []gateway.Option{
gateway.WithRouter(mux.NewRouter()),
gateway.WithRemoteAddr(rpcAddr),
gateway.WithGatewayAddr(gatewayAddress),
gateway.WithMaxCallRecvMsgSize(maxCallSize),