EIP-7549 gRPC (part 1) (#14055)

* interfaces move

* build fix

* remove annoying warning

* more build fixes

* review

* core code

* tests part 1

* tests part 2

* TranslateParticipation doesn't need Electra

* remove unused function

* pending atts don't need Electra

* tests part 3

* build fixes

* review

* EIP-7549 gRPC part 1
This commit is contained in:
Radosław Kapka
2024-06-01 02:24:06 +09:00
committed by GitHub
parent de04ce8329
commit 968e82b02d
9 changed files with 2579 additions and 1233 deletions

View File

@@ -9,6 +9,8 @@ import (
"github.com/prysmaticlabs/prysm/v5/api/pagination"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/db/filters"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/operations/attestations"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state/stategen"
"github.com/prysmaticlabs/prysm/v5/cmd"
"github.com/prysmaticlabs/prysm/v5/config/params"
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
@@ -67,6 +69,13 @@ func (bs *Server) ListAttestations(
return nil, status.Errorf(codes.Internal, "Could not fetch attestations: %v", err)
}
case *ethpb.ListAttestationsRequest_Epoch:
if q.Epoch >= params.BeaconConfig().ElectraForkEpoch {
return &ethpb.ListAttestationsResponse{
Attestations: make([]*ethpb.Attestation, 0),
TotalSize: int32(0),
NextPageToken: strconv.Itoa(0),
}, nil
}
blocks, _, err = bs.BeaconDB.Blocks(ctx, filters.NewFilter().SetStartEpoch(q.Epoch).SetEndEpoch(q.Epoch))
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not fetch attestations: %v", err)
@@ -74,17 +83,15 @@ func (bs *Server) ListAttestations(
default:
return nil, status.Error(codes.InvalidArgument, "Must specify a filter criteria for fetching attestations")
}
atts := make([]ethpb.Att, 0, params.BeaconConfig().MaxAttestations*uint64(len(blocks)))
for _, blk := range blocks {
atts = append(atts, blk.Block().Body().Attestations()...)
atts, err := blockAttestations[*ethpb.Attestation](blocks)
if err != nil {
return nil, err
}
// We sort attestations according to the Sortable interface.
sort.Sort(sortableAttestations(atts))
numAttestations := len(atts)
// If there are no attestations, we simply return a response specifying this.
// Otherwise, attempting to paginate 0 attestations below would result in an error.
if numAttestations == 0 {
if len(atts) == 0 {
return &ethpb.ListAttestationsResponse{
Attestations: make([]*ethpb.Attestation, 0),
TotalSize: int32(0),
@@ -92,20 +99,77 @@ func (bs *Server) ListAttestations(
}, nil
}
start, end, nextPageToken, err := pagination.StartAndEndPage(req.PageToken, int(req.PageSize), numAttestations)
start, end, nextPageToken, err := pagination.StartAndEndPage(req.PageToken, int(req.PageSize), len(atts))
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not paginate attestations: %v", err)
}
attestations := make([]*ethpb.Attestation, 0, len(atts))
for _, att := range atts {
a, ok := att.(*ethpb.Attestation)
if ok {
attestations = append(attestations, a)
}
}
return &ethpb.ListAttestationsResponse{
Attestations: attestations[start:end],
TotalSize: int32(numAttestations),
Attestations: atts[start:end],
TotalSize: int32(len(atts)),
NextPageToken: nextPageToken,
}, nil
}
// ListAttestationsElectra retrieves attestations by block root, slot, or epoch.
// Attestations are sorted by data slot by default.
//
// The server may return an empty list when no attestations match the given
// filter criteria. This RPC should not return NOT_FOUND. Only one filter
// criteria should be used.
func (bs *Server) ListAttestationsElectra(ctx context.Context, req *ethpb.ListAttestationsRequest) (*ethpb.ListAttestationsElectraResponse, error) {
if int(req.PageSize) > cmd.Get().MaxRPCPageSize {
return nil, status.Errorf(codes.InvalidArgument, "Requested page size %d can not be greater than max size %d",
req.PageSize, cmd.Get().MaxRPCPageSize)
}
var blocks []interfaces.ReadOnlySignedBeaconBlock
var err error
switch q := req.QueryFilter.(type) {
case *ethpb.ListAttestationsRequest_GenesisEpoch:
return &ethpb.ListAttestationsElectraResponse{
Attestations: make([]*ethpb.AttestationElectra, 0),
TotalSize: int32(0),
NextPageToken: strconv.Itoa(0),
}, nil
case *ethpb.ListAttestationsRequest_Epoch:
if q.Epoch < params.BeaconConfig().ElectraForkEpoch {
return &ethpb.ListAttestationsElectraResponse{
Attestations: make([]*ethpb.AttestationElectra, 0),
TotalSize: int32(0),
NextPageToken: strconv.Itoa(0),
}, nil
}
blocks, _, err = bs.BeaconDB.Blocks(ctx, filters.NewFilter().SetStartEpoch(q.Epoch).SetEndEpoch(q.Epoch))
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not fetch attestations: %v", err)
}
default:
return nil, status.Error(codes.InvalidArgument, "Must specify a filter criteria for fetching attestations")
}
atts, err := blockAttestations[*ethpb.AttestationElectra](blocks)
if err != nil {
return nil, err
}
// If there are no attestations, we simply return a response specifying this.
// Otherwise, attempting to paginate 0 attestations below would result in an error.
if len(atts) == 0 {
return &ethpb.ListAttestationsElectraResponse{
Attestations: make([]*ethpb.AttestationElectra, 0),
TotalSize: int32(0),
NextPageToken: strconv.Itoa(0),
}, nil
}
start, end, nextPageToken, err := pagination.StartAndEndPage(req.PageToken, int(req.PageSize), len(atts))
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not paginate attestations: %v", err)
}
return &ethpb.ListAttestationsElectraResponse{
Attestations: atts[start:end],
TotalSize: int32(len(atts)),
NextPageToken: nextPageToken,
}, nil
}
@@ -128,6 +192,13 @@ func (bs *Server) ListIndexedAttestations(
return nil, status.Errorf(codes.Internal, "Could not fetch attestations: %v", err)
}
case *ethpb.ListIndexedAttestationsRequest_Epoch:
if q.Epoch >= params.BeaconConfig().ElectraForkEpoch {
return &ethpb.ListIndexedAttestationsResponse{
IndexedAttestations: make([]*ethpb.IndexedAttestation, 0),
TotalSize: int32(0),
NextPageToken: strconv.Itoa(0),
}, nil
}
blocks, _, err = bs.BeaconDB.Blocks(ctx, filters.NewFilter().SetStartEpoch(q.Epoch).SetEndEpoch(q.Epoch))
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not fetch attestations: %v", err)
@@ -136,29 +207,205 @@ func (bs *Server) ListIndexedAttestations(
return nil, status.Error(codes.InvalidArgument, "Must specify a filter criteria for fetching attestations")
}
attsArray := make([]ethpb.Att, 0, params.BeaconConfig().MaxAttestations*uint64(len(blocks)))
for _, b := range blocks {
attsArray = append(attsArray, b.Block().Body().Attestations()...)
indexedAtts, err := blockIndexedAttestations[*ethpb.IndexedAttestation](ctx, blocks, bs.StateGen)
if err != nil {
return nil, err
}
// We sort attestations according to the Sortable interface.
sort.Sort(sortableAttestations(attsArray))
numAttestations := len(attsArray)
// If there are no attestations, we simply return a response specifying this.
// Otherwise, attempting to paginate 0 attestations below would result in an error.
if numAttestations == 0 {
if len(indexedAtts) == 0 {
return &ethpb.ListIndexedAttestationsResponse{
IndexedAttestations: make([]*ethpb.IndexedAttestation, 0),
TotalSize: int32(0),
NextPageToken: strconv.Itoa(0),
}, nil
}
start, end, nextPageToken, err := pagination.StartAndEndPage(req.PageToken, int(req.PageSize), len(indexedAtts))
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not paginate attestations: %v", err)
}
return &ethpb.ListIndexedAttestationsResponse{
IndexedAttestations: indexedAtts[start:end],
TotalSize: int32(len(indexedAtts)),
NextPageToken: nextPageToken,
}, nil
}
// ListIndexedAttestationsElectra retrieves indexed attestations by block root.
// IndexedAttestationsForEpoch are sorted by data slot by default. Start-end epoch
// filter is used to retrieve blocks with.
//
// The server may return an empty list when no attestations match the given
// filter criteria. This RPC should not return NOT_FOUND.
func (bs *Server) ListIndexedAttestationsElectra(
ctx context.Context,
req *ethpb.ListIndexedAttestationsRequest,
) (*ethpb.ListIndexedAttestationsElectraResponse, error) {
var blocks []interfaces.ReadOnlySignedBeaconBlock
var err error
switch q := req.QueryFilter.(type) {
case *ethpb.ListIndexedAttestationsRequest_GenesisEpoch:
return &ethpb.ListIndexedAttestationsElectraResponse{
IndexedAttestations: make([]*ethpb.IndexedAttestationElectra, 0),
TotalSize: int32(0),
NextPageToken: strconv.Itoa(0),
}, nil
case *ethpb.ListIndexedAttestationsRequest_Epoch:
if q.Epoch < params.BeaconConfig().ElectraForkEpoch {
return &ethpb.ListIndexedAttestationsElectraResponse{
IndexedAttestations: make([]*ethpb.IndexedAttestationElectra, 0),
TotalSize: int32(0),
NextPageToken: strconv.Itoa(0),
}, nil
}
blocks, _, err = bs.BeaconDB.Blocks(ctx, filters.NewFilter().SetStartEpoch(q.Epoch).SetEndEpoch(q.Epoch))
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not fetch attestations: %v", err)
}
default:
return nil, status.Error(codes.InvalidArgument, "Must specify a filter criteria for fetching attestations")
}
indexedAtts, err := blockIndexedAttestations[*ethpb.IndexedAttestationElectra](ctx, blocks, bs.StateGen)
if err != nil {
return nil, err
}
// If there are no attestations, we simply return a response specifying this.
// Otherwise, attempting to paginate 0 attestations below would result in an error.
if len(indexedAtts) == 0 {
return &ethpb.ListIndexedAttestationsElectraResponse{
IndexedAttestations: make([]*ethpb.IndexedAttestationElectra, 0),
TotalSize: int32(0),
NextPageToken: strconv.Itoa(0),
}, nil
}
start, end, nextPageToken, err := pagination.StartAndEndPage(req.PageToken, int(req.PageSize), len(indexedAtts))
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not paginate attestations: %v", err)
}
return &ethpb.ListIndexedAttestationsElectraResponse{
IndexedAttestations: indexedAtts[start:end],
TotalSize: int32(len(indexedAtts)),
NextPageToken: nextPageToken,
}, nil
}
// AttestationPool retrieves pending attestations.
//
// The server returns a list of attestations that have been seen but not
// yet processed. Pool attestations eventually expire as the slot
// advances, so an attestation missing from this request does not imply
// that it was included in a block. The attestation may have expired.
// Refer to the ethereum consensus specification for more details on how
// attestations are processed and when they are no longer valid.
// https://github.com/ethereum/consensus-specs/blob/dev/specs/core/0_beacon-chain.md#attestations
func (bs *Server) AttestationPool(_ context.Context, req *ethpb.AttestationPoolRequest) (*ethpb.AttestationPoolResponse, error) {
atts, err := attestationsFromPool[*ethpb.Attestation](req.PageSize, bs.AttestationsPool)
if err != nil {
return nil, err
}
// If there are no attestations, we simply return a response specifying this.
// Otherwise, attempting to paginate 0 attestations below would result in an error.
if len(atts) == 0 {
return &ethpb.AttestationPoolResponse{
Attestations: make([]*ethpb.Attestation, 0),
TotalSize: int32(0),
NextPageToken: strconv.Itoa(0),
}, nil
}
start, end, nextPageToken, err := pagination.StartAndEndPage(req.PageToken, int(req.PageSize), len(atts))
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not paginate attestations: %v", err)
}
return &ethpb.AttestationPoolResponse{
Attestations: atts[start:end],
TotalSize: int32(len(atts)),
NextPageToken: nextPageToken,
}, nil
}
func (bs *Server) AttestationPoolElectra(_ context.Context, req *ethpb.AttestationPoolRequest) (*ethpb.AttestationPoolElectraResponse, error) {
atts, err := attestationsFromPool[*ethpb.AttestationElectra](req.PageSize, bs.AttestationsPool)
if err != nil {
return nil, err
}
// If there are no attestations, we simply return a response specifying this.
// Otherwise, attempting to paginate 0 attestations below would result in an error.
if len(atts) == 0 {
return &ethpb.AttestationPoolElectraResponse{
Attestations: make([]*ethpb.AttestationElectra, 0),
TotalSize: int32(0),
NextPageToken: strconv.Itoa(0),
}, nil
}
start, end, nextPageToken, err := pagination.StartAndEndPage(req.PageToken, int(req.PageSize), len(atts))
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not paginate attestations: %v", err)
}
return &ethpb.AttestationPoolElectraResponse{
Attestations: atts[start:end],
TotalSize: int32(len(atts)),
NextPageToken: nextPageToken,
}, nil
}
func blockAttestations[T ethpb.Att](blocks []interfaces.ReadOnlySignedBeaconBlock) ([]T, error) {
blockAtts := make([]ethpb.Att, 0, params.BeaconConfig().MaxAttestations*uint64(len(blocks)))
for _, blk := range blocks {
blockAtts = append(blockAtts, blk.Block().Body().Attestations()...)
}
// We sort attestations according to the Sortable interface.
sort.Sort(sortableAttestations(blockAtts))
numAttestations := len(blockAtts)
if numAttestations == 0 {
return []T{}, nil
}
atts := make([]T, 0, len(blockAtts))
for _, att := range blockAtts {
a, ok := att.(T)
if !ok {
var expected T
return nil, status.Errorf(codes.Internal, "Attestation is of the wrong type (expected %T, got %T)", expected, att)
}
atts = append(atts, a)
}
return atts, nil
}
func blockIndexedAttestations[T ethpb.IndexedAtt](
ctx context.Context,
blocks []interfaces.ReadOnlySignedBeaconBlock,
stateGen stategen.StateManager,
) ([]T, error) {
attsArray := make([]ethpb.Att, 0, params.BeaconConfig().MaxAttestations*uint64(len(blocks)))
for _, b := range blocks {
attsArray = append(attsArray, b.Block().Body().Attestations()...)
}
// We sort attestations according to the Sortable interface.
sort.Sort(sortableAttestations(attsArray))
numAttestations := len(attsArray)
if numAttestations == 0 {
return []T{}, nil
}
// We use the retrieved committees for the b root to convert all attestations
// into indexed form effectively.
mappedAttestations := mapAttestationsByTargetRoot(attsArray)
indexedAtts := make([]*ethpb.IndexedAttestation, 0, numAttestations)
indexed := make([]T, 0, numAttestations)
for targetRoot, atts := range mappedAttestations {
attState, err := bs.StateGen.StateByRoot(ctx, targetRoot)
attState, err := stateGen.StateByRoot(ctx, targetRoot)
if err != nil && strings.Contains(err.Error(), "unknown state summary") {
// We shouldn't stop the request if we encounter an attestation we don't have the state for.
log.Debugf("Could not get state for attestation target root %#x", targetRoot)
@@ -185,67 +432,36 @@ func (bs *Server) ListIndexedAttestations(
if err != nil {
return nil, err
}
a, ok := idxAtt.(*ethpb.IndexedAttestation)
if ok {
indexedAtts = append(indexedAtts, a)
a, ok := idxAtt.(T)
if !ok {
var expected T
return nil, status.Errorf(codes.Internal, "Indexed attestation is of the wrong type (expected %T, got %T)", expected, idxAtt)
}
indexed = append(indexed, a)
}
}
start, end, nextPageToken, err := pagination.StartAndEndPage(req.PageToken, int(req.PageSize), len(indexedAtts))
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not paginate attestations: %v", err)
}
return &ethpb.ListIndexedAttestationsResponse{
IndexedAttestations: indexedAtts[start:end],
TotalSize: int32(len(indexedAtts)),
NextPageToken: nextPageToken,
}, nil
return indexed, nil
}
// AttestationPool retrieves pending attestations.
//
// The server returns a list of attestations that have been seen but not
// yet processed. Pool attestations eventually expire as the slot
// advances, so an attestation missing from this request does not imply
// that it was included in a block. The attestation may have expired.
// Refer to the ethereum consensus specification for more details on how
// attestations are processed and when they are no longer valid.
// https://github.com/ethereum/consensus-specs/blob/dev/specs/core/0_beacon-chain.md#attestations
func (bs *Server) AttestationPool(
_ context.Context, req *ethpb.AttestationPoolRequest,
) (*ethpb.AttestationPoolResponse, error) {
if int(req.PageSize) > cmd.Get().MaxRPCPageSize {
func attestationsFromPool[T ethpb.Att](pageSize int32, pool attestations.Pool) ([]T, error) {
if int(pageSize) > cmd.Get().MaxRPCPageSize {
return nil, status.Errorf(
codes.InvalidArgument,
"Requested page size %d can not be greater than max size %d",
req.PageSize,
pageSize,
cmd.Get().MaxRPCPageSize,
)
}
atts := bs.AttestationsPool.AggregatedAttestations()
numAtts := len(atts)
if numAtts == 0 {
return &ethpb.AttestationPoolResponse{
Attestations: make([]*ethpb.Attestation, 0),
TotalSize: int32(0),
NextPageToken: strconv.Itoa(0),
}, nil
}
start, end, nextPageToken, err := pagination.StartAndEndPage(req.PageToken, int(req.PageSize), numAtts)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not paginate attestations: %v", err)
}
attestations := make([]*ethpb.Attestation, 0, len(atts))
for _, att := range atts {
a, ok := att.(*ethpb.Attestation)
if ok {
attestations = append(attestations, a)
poolAtts := pool.AggregatedAttestations()
atts := make([]T, 0, len(poolAtts))
for _, att := range poolAtts {
a, ok := att.(T)
if !ok {
var expected T
return nil, status.Errorf(codes.Internal, "Attestation is of the wrong type (expected %T, got %T)", expected, att)
}
atts = append(atts, a)
}
return &ethpb.AttestationPoolResponse{
Attestations: attestations[start:end],
TotalSize: int32(numAtts),
NextPageToken: nextPageToken,
}, nil
return atts, nil
}

View File

@@ -462,6 +462,59 @@ func TestServer_ListAttestations_Pagination_DefaultPageSize(t *testing.T) {
assert.DeepEqual(t, atts[i:j], res.Attestations, "Incorrect attestations response")
}
func TestServer_ListAttestationsElectra(t *testing.T) {
params.SetupTestConfigCleanup(t)
cfg := params.BeaconConfig()
cfg.ElectraForkEpoch = 0
params.OverrideBeaconConfig(cfg)
db := dbTest.SetupDB(t)
ctx := context.Background()
st, err := state_native.InitializeFromProtoElectra(&ethpb.BeaconStateElectra{
Slot: 0,
})
require.NoError(t, err)
bs := &Server{
BeaconDB: db,
HeadFetcher: &chainMock.ChainService{
State: st,
},
}
cb := primitives.NewAttestationCommitteeBits()
cb.SetBitAt(2, true)
att := util.HydrateAttestationElectra(&ethpb.AttestationElectra{
AggregationBits: bitfield.NewBitlist(0),
Data: &ethpb.AttestationData{
Slot: 2,
},
CommitteeBits: cb,
})
parentRoot := [32]byte{1, 2, 3}
signedBlock := util.NewBeaconBlockElectra()
signedBlock.Block.ParentRoot = bytesutil.PadTo(parentRoot[:], 32)
signedBlock.Block.Body.Attestations = []*ethpb.AttestationElectra{att}
root, err := signedBlock.Block.HashTreeRoot()
require.NoError(t, err)
util.SaveBlock(t, ctx, db, signedBlock)
require.NoError(t, db.SaveGenesisBlockRoot(ctx, root))
wanted := &ethpb.ListAttestationsElectraResponse{
Attestations: []*ethpb.AttestationElectra{att},
NextPageToken: "",
TotalSize: 1,
}
res, err := bs.ListAttestationsElectra(ctx, &ethpb.ListAttestationsRequest{
QueryFilter: &ethpb.ListAttestationsRequest_Epoch{
Epoch: params.BeaconConfig().ElectraForkEpoch,
},
})
require.NoError(t, err)
require.DeepSSZEqual(t, wanted, res)
}
func TestServer_mapAttestationToTargetRoot(t *testing.T) {
count := primitives.Slot(100)
atts := make([]ethpb.Att, count)
@@ -494,8 +547,6 @@ func TestServer_mapAttestationToTargetRoot(t *testing.T) {
}
func TestServer_ListIndexedAttestations_GenesisEpoch(t *testing.T) {
params.SetupTestConfigCleanup(t)
params.OverrideBeaconConfig(params.BeaconConfig())
db := dbTest.SetupDB(t)
helpers.ClearCache()
ctx := context.Background()
@@ -606,8 +657,6 @@ func TestServer_ListIndexedAttestations_GenesisEpoch(t *testing.T) {
}
func TestServer_ListIndexedAttestations_OldEpoch(t *testing.T) {
params.SetupTestConfigCleanup(t)
params.OverrideBeaconConfig(params.BeaconConfig())
db := dbTest.SetupDB(t)
helpers.ClearCache()
ctx := context.Background()
@@ -690,6 +739,123 @@ func TestServer_ListIndexedAttestations_OldEpoch(t *testing.T) {
require.DeepEqual(t, indexedAtts, res.IndexedAttestations, "Incorrect list indexed attestations response")
}
func TestServer_ListIndexedAttestationsElectra(t *testing.T) {
params.SetupTestConfigCleanup(t)
cfg := params.BeaconConfig()
cfg.ElectraForkEpoch = 0
params.OverrideBeaconConfig(cfg)
db := dbTest.SetupDB(t)
helpers.ClearCache()
ctx := context.Background()
targetRoot1 := bytesutil.ToBytes32([]byte("root"))
targetRoot2 := bytesutil.ToBytes32([]byte("root2"))
count := params.BeaconConfig().SlotsPerEpoch
atts := make([]*ethpb.AttestationElectra, 0, count)
atts2 := make([]*ethpb.AttestationElectra, 0, count)
for i := primitives.Slot(0); i < count; i++ {
var targetRoot [32]byte
if i%2 == 0 {
targetRoot = targetRoot1
} else {
targetRoot = targetRoot2
}
cb := primitives.NewAttestationCommitteeBits()
cb.SetBitAt(0, true)
blockExample := util.NewBeaconBlockElectra()
blockExample.Block.Body.Attestations = []*ethpb.AttestationElectra{
{
Signature: make([]byte, fieldparams.BLSSignatureLength),
Data: &ethpb.AttestationData{
BeaconBlockRoot: make([]byte, fieldparams.RootLength),
Target: &ethpb.Checkpoint{
Root: targetRoot[:],
},
Source: &ethpb.Checkpoint{
Root: make([]byte, fieldparams.RootLength),
},
Slot: i,
},
AggregationBits: bitfield.NewBitlist(128 / uint64(params.BeaconConfig().SlotsPerEpoch)),
CommitteeBits: cb,
},
}
util.SaveBlock(t, ctx, db, blockExample)
if i%2 == 0 {
atts = append(atts, blockExample.Block.Body.Attestations...)
} else {
atts2 = append(atts2, blockExample.Block.Body.Attestations...)
}
}
// We setup 512 validators so that committee size matches the length of attestations' aggregation bits.
numValidators := uint64(512)
state, _ := util.DeterministicGenesisStateElectra(t, numValidators)
// Next up we convert the test attestations to indexed form:
indexedAtts := make([]*ethpb.IndexedAttestationElectra, len(atts)+len(atts2))
for i := 0; i < len(atts); i++ {
att := atts[i]
committee, err := helpers.BeaconCommitteeFromState(context.Background(), state, att.Data.Slot, 0)
require.NoError(t, err)
idxAtt, err := attestation.ConvertToIndexed(ctx, atts[i], committee)
require.NoError(t, err, "Could not convert attestation to indexed")
a, ok := idxAtt.(*ethpb.IndexedAttestationElectra)
require.Equal(t, true, ok, "unexpected type of indexed attestation")
indexedAtts[i] = a
}
for i := 0; i < len(atts2); i++ {
att := atts2[i]
committee, err := helpers.BeaconCommitteeFromState(context.Background(), state, att.Data.Slot, 0)
require.NoError(t, err)
idxAtt, err := attestation.ConvertToIndexed(ctx, atts2[i], committee)
require.NoError(t, err, "Could not convert attestation to indexed")
a, ok := idxAtt.(*ethpb.IndexedAttestationElectra)
require.Equal(t, true, ok, "unexpected type of indexed attestation")
indexedAtts[i+len(atts)] = a
}
bs := &Server{
BeaconDB: db,
GenesisTimeFetcher: &chainMock.ChainService{State: state},
HeadFetcher: &chainMock.ChainService{State: state},
StateGen: stategen.New(db, doublylinkedtree.New()),
}
err := db.SaveStateSummary(ctx, &ethpb.StateSummary{
Root: targetRoot1[:],
Slot: 1,
})
require.NoError(t, err)
err = db.SaveStateSummary(ctx, &ethpb.StateSummary{
Root: targetRoot2[:],
Slot: 2,
})
require.NoError(t, err)
require.NoError(t, db.SaveState(ctx, state, bytesutil.ToBytes32(targetRoot1[:])))
require.NoError(t, state.SetSlot(state.Slot()+1))
require.NoError(t, db.SaveState(ctx, state, bytesutil.ToBytes32(targetRoot2[:])))
res, err := bs.ListIndexedAttestationsElectra(ctx, &ethpb.ListIndexedAttestationsRequest{
QueryFilter: &ethpb.ListIndexedAttestationsRequest_Epoch{
Epoch: 0,
},
})
require.NoError(t, err)
assert.Equal(t, len(indexedAtts), len(res.IndexedAttestations), "Incorrect indexted attestations length")
sort.Slice(indexedAtts, func(i, j int) bool {
return indexedAtts[i].GetData().Slot < indexedAtts[j].GetData().Slot
})
sort.Slice(res.IndexedAttestations, func(i, j int) bool {
return res.IndexedAttestations[i].Data.Slot < res.IndexedAttestations[j].Data.Slot
})
assert.DeepEqual(t, indexedAtts, res.IndexedAttestations, "Incorrect list indexed attestations response")
}
func TestServer_AttestationPool_Pagination_ExceedsMaxPageSize(t *testing.T) {
ctx := context.Background()
bs := &Server{}
@@ -827,3 +993,24 @@ func TestServer_AttestationPool_Pagination_CustomPageSize(t *testing.T) {
assert.Equal(t, tt.res.NextPageToken, res.NextPageToken, "Unexpected next page token")
}
}
func TestServer_AttestationPoolElectra(t *testing.T) {
ctx := context.Background()
bs := &Server{
AttestationsPool: attestations.NewPool(),
}
atts := make([]ethpb.Att, params.BeaconConfig().DefaultPageSize+1)
for i := 0; i < len(atts); i++ {
att := util.NewAttestationElectra()
att.Data.Slot = primitives.Slot(i)
atts[i] = att
}
require.NoError(t, bs.AttestationsPool.SaveAggregatedAttestations(atts))
req := &ethpb.AttestationPoolRequest{}
res, err := bs.AttestationPoolElectra(ctx, req)
require.NoError(t, err)
assert.Equal(t, params.BeaconConfig().DefaultPageSize, len(res.Attestations), "Unexpected number of attestations")
assert.Equal(t, params.BeaconConfig().DefaultPageSize+1, int(res.TotalSize), "Unexpected total size")
}

View File

@@ -36,26 +36,31 @@ func (bs *Server) SubmitProposerSlashing(
}, nil
}
// SubmitAttesterSlashing receives an attester slashing object via
func (bs *Server) SubmitAttesterSlashing(ctx context.Context, req *ethpb.AttesterSlashing) (*ethpb.SubmitSlashingResponse, error) {
return bs.submitAttesterSlashing(ctx, req)
}
// SubmitAttesterSlashingElectra receives an attester slashing object via
// RPC and injects it into the beacon node's operations pool.
// Submission into this pool does not guarantee inclusion into a beacon block.
func (bs *Server) SubmitAttesterSlashing(
ctx context.Context,
req *ethpb.AttesterSlashing,
) (*ethpb.SubmitSlashingResponse, error) {
func (bs *Server) SubmitAttesterSlashingElectra(ctx context.Context, req *ethpb.AttesterSlashingElectra) (*ethpb.SubmitSlashingResponse, error) {
return bs.submitAttesterSlashing(ctx, req)
}
func (bs *Server) submitAttesterSlashing(ctx context.Context, slashing ethpb.AttSlashing) (*ethpb.SubmitSlashingResponse, error) {
beaconState, err := bs.HeadFetcher.HeadStateReadOnly(ctx)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not retrieve head state: %v", err)
}
if err := bs.SlashingsPool.InsertAttesterSlashing(ctx, beaconState, req); err != nil {
if err := bs.SlashingsPool.InsertAttesterSlashing(ctx, beaconState, slashing); err != nil {
return nil, status.Errorf(codes.Internal, "Could not insert attester slashing into pool: %v", err)
}
if !features.Get().DisableBroadcastSlashings {
if err := bs.Broadcaster.Broadcast(ctx, req); err != nil {
if err := bs.Broadcaster.Broadcast(ctx, slashing); err != nil {
return nil, status.Errorf(codes.Internal, "Could not broadcast slashing object: %v", err)
}
}
indices := slice.IntersectionUint64(req.Attestation_1.AttestingIndices, req.Attestation_2.AttestingIndices)
indices := slice.IntersectionUint64(slashing.FirstAttestation().GetAttestingIndices(), slashing.SecondAttestation().GetAttestingIndices())
slashedIndices := make([]primitives.ValidatorIndex, len(indices))
for i, index := range indices {
slashedIndices[i] = primitives.ValidatorIndex(index)

View File

@@ -167,3 +167,28 @@ func TestServer_SubmitAttesterSlashing_DontBroadcast(t *testing.T) {
_, err = bs.SubmitAttesterSlashing(ctx, generatedSlashing.(*ethpb.AttesterSlashing))
assert.NotNil(t, err, "Expected including a attester slashing for an already slashed validator to fail")
}
func TestServer_SubmitAttesterSlashingElectra(t *testing.T) {
ctx := context.Background()
st, privs := util.DeterministicGenesisStateElectra(t, 64)
slashedVal, err := st.ValidatorAtIndex(5)
require.NoError(t, err)
slashedVal.Slashed = true
require.NoError(t, st.UpdateValidatorAtIndex(5, slashedVal))
mb := &mockp2p.MockBroadcaster{}
bs := &Server{
HeadFetcher: &mock.ChainService{
State: st,
},
SlashingsPool: slashings.NewPool(),
Broadcaster: mb,
}
generatedSlashing, err := util.GenerateAttesterSlashingForValidator(st, privs[2], primitives.ValidatorIndex(2))
require.NoError(t, err)
_, err = bs.SubmitAttesterSlashingElectra(ctx, generatedSlashing.(*ethpb.AttesterSlashingElectra))
require.NoError(t, err)
assert.Equal(t, true, mb.BroadcastCalled.Load(), "Expected broadcast to be called when flag is set")
}

View File

@@ -48,12 +48,19 @@ func ConvertToIndexed(ctx context.Context, attestation ethpb.Att, committees ...
sort.Slice(attIndices, func(i, j int) bool {
return attIndices[i] < attIndices[j]
})
inAtt := &ethpb.IndexedAttestation{
if attestation.Version() >= version.Electra {
return &ethpb.IndexedAttestationElectra{
Data: attestation.GetData(),
Signature: attestation.GetSignature(),
AttestingIndices: attIndices,
}, nil
}
return &ethpb.IndexedAttestation{
Data: attestation.GetData(),
Signature: attestation.GetSignature(),
AttestingIndices: attIndices,
}
return inAtt, err
}, nil
}
// AttestingIndices returns the attesting participants indices from the attestation data.

File diff suppressed because it is too large Load Diff

View File

@@ -71,6 +71,42 @@ func local_request_BeaconChain_ListAttestations_0(ctx context.Context, marshaler
}
var (
filter_BeaconChain_ListAttestationsElectra_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
)
func request_BeaconChain_ListAttestationsElectra_0(ctx context.Context, marshaler runtime.Marshaler, client BeaconChainClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq ListAttestationsRequest
var metadata runtime.ServerMetadata
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_BeaconChain_ListAttestationsElectra_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := client.ListAttestationsElectra(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_BeaconChain_ListAttestationsElectra_0(ctx context.Context, marshaler runtime.Marshaler, server BeaconChainServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq ListAttestationsRequest
var metadata runtime.ServerMetadata
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_BeaconChain_ListAttestationsElectra_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.ListAttestationsElectra(ctx, &protoReq)
return msg, metadata, err
}
var (
filter_BeaconChain_ListIndexedAttestations_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
)
@@ -107,6 +143,42 @@ func local_request_BeaconChain_ListIndexedAttestations_0(ctx context.Context, ma
}
var (
filter_BeaconChain_ListIndexedAttestationsElectra_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
)
func request_BeaconChain_ListIndexedAttestationsElectra_0(ctx context.Context, marshaler runtime.Marshaler, client BeaconChainClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq ListIndexedAttestationsRequest
var metadata runtime.ServerMetadata
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_BeaconChain_ListIndexedAttestationsElectra_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := client.ListIndexedAttestationsElectra(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_BeaconChain_ListIndexedAttestationsElectra_0(ctx context.Context, marshaler runtime.Marshaler, server BeaconChainServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq ListIndexedAttestationsRequest
var metadata runtime.ServerMetadata
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_BeaconChain_ListIndexedAttestationsElectra_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.ListIndexedAttestationsElectra(ctx, &protoReq)
return msg, metadata, err
}
var (
filter_BeaconChain_AttestationPool_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
)
@@ -143,6 +215,42 @@ func local_request_BeaconChain_AttestationPool_0(ctx context.Context, marshaler
}
var (
filter_BeaconChain_AttestationPoolElectra_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
)
func request_BeaconChain_AttestationPoolElectra_0(ctx context.Context, marshaler runtime.Marshaler, client BeaconChainClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq AttestationPoolRequest
var metadata runtime.ServerMetadata
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_BeaconChain_AttestationPoolElectra_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := client.AttestationPoolElectra(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_BeaconChain_AttestationPoolElectra_0(ctx context.Context, marshaler runtime.Marshaler, server BeaconChainServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq AttestationPoolRequest
var metadata runtime.ServerMetadata
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_BeaconChain_AttestationPoolElectra_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.AttestationPoolElectra(ctx, &protoReq)
return msg, metadata, err
}
var (
filter_BeaconChain_ListBeaconBlocks_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
)
@@ -557,6 +665,42 @@ func local_request_BeaconChain_SubmitAttesterSlashing_0(ctx context.Context, mar
}
var (
filter_BeaconChain_SubmitAttesterSlashingElectra_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
)
func request_BeaconChain_SubmitAttesterSlashingElectra_0(ctx context.Context, marshaler runtime.Marshaler, client BeaconChainClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq AttesterSlashingElectra
var metadata runtime.ServerMetadata
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_BeaconChain_SubmitAttesterSlashingElectra_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := client.SubmitAttesterSlashingElectra(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_BeaconChain_SubmitAttesterSlashingElectra_0(ctx context.Context, marshaler runtime.Marshaler, server BeaconChainServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq AttesterSlashingElectra
var metadata runtime.ServerMetadata
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_BeaconChain_SubmitAttesterSlashingElectra_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.SubmitAttesterSlashingElectra(ctx, &protoReq)
return msg, metadata, err
}
var (
filter_BeaconChain_SubmitProposerSlashing_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
)
@@ -658,6 +802,29 @@ func RegisterBeaconChainHandlerServer(ctx context.Context, mux *runtime.ServeMux
})
mux.Handle("GET", pattern_BeaconChain_ListAttestationsElectra_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ethereum.eth.v1alpha1.BeaconChain/ListAttestationsElectra")
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_BeaconChain_ListAttestationsElectra_0(rctx, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_BeaconChain_ListAttestationsElectra_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_BeaconChain_ListIndexedAttestations_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
@@ -681,6 +848,29 @@ func RegisterBeaconChainHandlerServer(ctx context.Context, mux *runtime.ServeMux
})
mux.Handle("GET", pattern_BeaconChain_ListIndexedAttestationsElectra_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ethereum.eth.v1alpha1.BeaconChain/ListIndexedAttestationsElectra")
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_BeaconChain_ListIndexedAttestationsElectra_0(rctx, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_BeaconChain_ListIndexedAttestationsElectra_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_BeaconChain_AttestationPool_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
@@ -704,6 +894,29 @@ func RegisterBeaconChainHandlerServer(ctx context.Context, mux *runtime.ServeMux
})
mux.Handle("GET", pattern_BeaconChain_AttestationPoolElectra_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ethereum.eth.v1alpha1.BeaconChain/AttestationPoolElectra")
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_BeaconChain_AttestationPoolElectra_0(rctx, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_BeaconChain_AttestationPoolElectra_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_BeaconChain_ListBeaconBlocks_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
@@ -1003,6 +1216,29 @@ func RegisterBeaconChainHandlerServer(ctx context.Context, mux *runtime.ServeMux
})
mux.Handle("GET", pattern_BeaconChain_SubmitAttesterSlashingElectra_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ethereum.eth.v1alpha1.BeaconChain/SubmitAttesterSlashingElectra")
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_BeaconChain_SubmitAttesterSlashingElectra_0(rctx, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_BeaconChain_SubmitAttesterSlashingElectra_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_BeaconChain_SubmitProposerSlashing_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
@@ -1110,6 +1346,26 @@ func RegisterBeaconChainHandlerClient(ctx context.Context, mux *runtime.ServeMux
})
mux.Handle("GET", pattern_BeaconChain_ListAttestationsElectra_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/ethereum.eth.v1alpha1.BeaconChain/ListAttestationsElectra")
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_BeaconChain_ListAttestationsElectra_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_BeaconChain_ListAttestationsElectra_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_BeaconChain_ListIndexedAttestations_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
@@ -1130,6 +1386,26 @@ func RegisterBeaconChainHandlerClient(ctx context.Context, mux *runtime.ServeMux
})
mux.Handle("GET", pattern_BeaconChain_ListIndexedAttestationsElectra_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/ethereum.eth.v1alpha1.BeaconChain/ListIndexedAttestationsElectra")
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_BeaconChain_ListIndexedAttestationsElectra_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_BeaconChain_ListIndexedAttestationsElectra_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_BeaconChain_AttestationPool_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
@@ -1150,6 +1426,26 @@ func RegisterBeaconChainHandlerClient(ctx context.Context, mux *runtime.ServeMux
})
mux.Handle("GET", pattern_BeaconChain_AttestationPoolElectra_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/ethereum.eth.v1alpha1.BeaconChain/AttestationPoolElectra")
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_BeaconChain_AttestationPoolElectra_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_BeaconChain_AttestationPoolElectra_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_BeaconChain_ListBeaconBlocks_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
@@ -1410,6 +1706,26 @@ func RegisterBeaconChainHandlerClient(ctx context.Context, mux *runtime.ServeMux
})
mux.Handle("GET", pattern_BeaconChain_SubmitAttesterSlashingElectra_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/ethereum.eth.v1alpha1.BeaconChain/SubmitAttesterSlashingElectra")
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_BeaconChain_SubmitAttesterSlashingElectra_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_BeaconChain_SubmitAttesterSlashingElectra_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_BeaconChain_SubmitProposerSlashing_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
@@ -1456,10 +1772,16 @@ func RegisterBeaconChainHandlerClient(ctx context.Context, mux *runtime.ServeMux
var (
pattern_BeaconChain_ListAttestations_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"eth", "v1alpha1", "beacon", "attestations"}, ""))
pattern_BeaconChain_ListAttestationsElectra_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"eth", "v1alpha1", "beacon", "attestations_electra"}, ""))
pattern_BeaconChain_ListIndexedAttestations_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"eth", "v1alpha1", "beacon", "attestations", "indexed"}, ""))
pattern_BeaconChain_ListIndexedAttestationsElectra_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"eth", "v1alpha1", "beacon", "attestations", "indexed_electra"}, ""))
pattern_BeaconChain_AttestationPool_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"eth", "v1alpha1", "beacon", "attestations", "pool"}, ""))
pattern_BeaconChain_AttestationPoolElectra_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"eth", "v1alpha1", "beacon", "attestations", "pool_electra"}, ""))
pattern_BeaconChain_ListBeaconBlocks_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"eth", "v1alpha2", "beacon", "blocks"}, ""))
pattern_BeaconChain_GetChainHead_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"eth", "v1alpha1", "beacon", "chainhead"}, ""))
@@ -1486,6 +1808,8 @@ var (
pattern_BeaconChain_SubmitAttesterSlashing_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 2, 5}, []string{"eth", "v1alpha1", "beacon", "slashings", "attester", "submit"}, ""))
pattern_BeaconChain_SubmitAttesterSlashingElectra_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 2, 5}, []string{"eth", "v1alpha1", "beacon", "slashings", "attester", "submit_electra"}, ""))
pattern_BeaconChain_SubmitProposerSlashing_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 2, 5}, []string{"eth", "v1alpha1", "beacon", "slashings", "proposer", "submit"}, ""))
pattern_BeaconChain_GetIndividualVotes_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"eth", "v1alpha1", "beacon", "individual_votes"}, ""))
@@ -1494,10 +1818,16 @@ var (
var (
forward_BeaconChain_ListAttestations_0 = runtime.ForwardResponseMessage
forward_BeaconChain_ListAttestationsElectra_0 = runtime.ForwardResponseMessage
forward_BeaconChain_ListIndexedAttestations_0 = runtime.ForwardResponseMessage
forward_BeaconChain_ListIndexedAttestationsElectra_0 = runtime.ForwardResponseMessage
forward_BeaconChain_AttestationPool_0 = runtime.ForwardResponseMessage
forward_BeaconChain_AttestationPoolElectra_0 = runtime.ForwardResponseMessage
forward_BeaconChain_ListBeaconBlocks_0 = runtime.ForwardResponseMessage
forward_BeaconChain_GetChainHead_0 = runtime.ForwardResponseMessage
@@ -1524,6 +1854,8 @@ var (
forward_BeaconChain_SubmitAttesterSlashing_0 = runtime.ForwardResponseMessage
forward_BeaconChain_SubmitAttesterSlashingElectra_0 = runtime.ForwardResponseMessage
forward_BeaconChain_SubmitProposerSlashing_0 = runtime.ForwardResponseMessage
forward_BeaconChain_GetIndividualVotes_0 = runtime.ForwardResponseMessage

View File

@@ -47,6 +47,18 @@ service BeaconChain {
};
}
// Retrieve attestations by block root, slot, or epoch.
//
// The server may return an empty list when no attestations match the given
// filter criteria. This RPC should not return NOT_FOUND. Only one filter
// criteria should be used. This endpoint allows for retrieval of genesis
// information via a boolean query filter.
rpc ListAttestationsElectra(ListAttestationsRequest) returns (ListAttestationsElectraResponse) {
option (google.api.http) = {
get: "/eth/v1alpha1/beacon/attestations_electra"
};
}
// Retrieve indexed attestations by block root, slot, or epoch.
//
// The server may return an empty list when no indexed attestations match the given
@@ -59,6 +71,18 @@ service BeaconChain {
};
}
// Retrieve indexed attestations by block root, slot, or epoch.
//
// The server may return an empty list when no indexed attestations match the given
// filter criteria. This RPC should not return NOT_FOUND. Only one filter
// criteria should be used. This endpoint allows for retrieval of genesis
// information via a boolean query filter.
rpc ListIndexedAttestationsElectra(ListIndexedAttestationsRequest) returns (ListIndexedAttestationsElectraResponse) {
option (google.api.http) = {
get: "/eth/v1alpha1/beacon/attestations/indexed_electra"
};
}
// Retrieve attestations from pool.
//
// The server returns a list of attestations that have been seen but not
@@ -74,6 +98,21 @@ service BeaconChain {
};
}
// Retrieve attestations from pool.
//
// The server returns a list of attestations that have been seen but not
// yet processed. Pool attestations eventually expire as the slot
// advances, so an attestation missing from this request does not imply
// that it was included in a block. The attestation may have expired.
// Refer to the Ethereum Beacon Chain specification for more details on how
// attestations are processed and when they are no longer valid.
// https://github.com/ethereum/consensus-specs/blob/dev/specs/core/0_beacon-chain.md#attestations
rpc AttestationPoolElectra(AttestationPoolRequest) returns (AttestationPoolElectraResponse) {
option (google.api.http) = {
get: "/eth/v1alpha1/beacon/attestations/pool_electra"
};
}
// Retrieve blocks by root, slot, or epoch.
//
// The server may return multiple blocks in the case that a slot or epoch is
@@ -205,6 +244,13 @@ service BeaconChain {
};
}
// Submit an attester slashing object to the beacon node.
rpc SubmitAttesterSlashingElectra(AttesterSlashingElectra) returns (SubmitSlashingResponse) {
option (google.api.http) = {
get: "/eth/v1alpha1/beacon/slashings/attester/submit_electra"
};
}
// Submit a proposer slashing object to the beacon node.
rpc SubmitProposerSlashing(ProposerSlashing) returns (SubmitSlashingResponse) {
option (google.api.http) = {
@@ -274,6 +320,18 @@ message ListAttestationsResponse {
int32 total_size = 3;
}
message ListAttestationsElectraResponse {
repeated AttestationElectra attestations = 1;
// A pagination token returned from a previous call to `ListAttestations`
// that indicates from where listing should continue.
// This field is optional.
string next_page_token = 2;
// Total count of Attestations matching the request filter.
int32 total_size = 3;
}
message ListIndexedAttestationsResponse {
repeated IndexedAttestation indexed_attestations = 1;
@@ -286,6 +344,18 @@ message ListIndexedAttestationsResponse {
int32 total_size = 3;
}
message ListIndexedAttestationsElectraResponse {
repeated IndexedAttestationElectra indexed_attestations = 1;
// A pagination token returned from a previous call to `ListIndexedAttestations`
// that indicates from where listing should continue.
// This field is optional.
string next_page_token = 2;
// Total count of Attestations matching the request filter.
int32 total_size = 3;
}
message ListBlocksRequest {
oneof query_filter {
// Block root filter to return a single block.
@@ -780,6 +850,19 @@ message AttestationPoolResponse {
int32 total_size = 3;
}
message AttestationPoolElectraResponse {
// List of attestations currently in the pool of the beacon chain.
repeated AttestationElectra attestations = 1;
// A pagination token returned from a previous call
// that indicates where this listing should continue from.
// This field is optional.
string next_page_token = 2;
// Total count of objects matching the request filter.
int32 total_size = 3;
}
// Information about the configuration parameters of the beacon node, such
// as the slots per epoch, slots per eth1 voting period, and more.
message BeaconConfig {

View File

@@ -23,7 +23,7 @@ import (
log "github.com/sirupsen/logrus"
)
// NewAttestation creates an attestation block with minimum marshalable fields.
// NewAttestation creates a block attestation with minimum marshalable fields.
func NewAttestation() *ethpb.Attestation {
return &ethpb.Attestation{
AggregationBits: bitfield.Bitlist{0b1101},
@@ -40,6 +40,26 @@ func NewAttestation() *ethpb.Attestation {
}
}
// NewAttestationElectra creates a block attestation with minimum marshalable fields.
func NewAttestationElectra() *ethpb.AttestationElectra {
cb := primitives.NewAttestationCommitteeBits()
cb.SetBitAt(0, true)
return &ethpb.AttestationElectra{
AggregationBits: bitfield.Bitlist{0b1101},
CommitteeBits: cb,
Data: &ethpb.AttestationData{
BeaconBlockRoot: make([]byte, fieldparams.RootLength),
Source: &ethpb.Checkpoint{
Root: make([]byte, fieldparams.RootLength),
},
Target: &ethpb.Checkpoint{
Root: make([]byte, fieldparams.RootLength),
},
},
Signature: make([]byte, 96),
}
}
// GenerateAttestations creates attestations that are entirely valid, for all
// the committees of the current state slot. This function expects attestations
// requested to be cleanly divisible by committees per slot. If there is 1 committee