mirror of
https://gitlab.com/pulsechaincom/prysm-pulse.git
synced 2024-12-28 14:17:17 +00:00
1fbe05292f
* Fix `SubmitPoolSyncCommitteeSignatures` API endpoint * fix test * fix another test Co-authored-by: Raul Jordan <raul@prysmaticlabs.com> Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
161 lines
5.4 KiB
Go
161 lines
5.4 KiB
Go
package beacon
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/golang/protobuf/ptypes/empty"
|
|
"github.com/pkg/errors"
|
|
types "github.com/prysmaticlabs/eth2-types"
|
|
"github.com/prysmaticlabs/prysm/api/grpc"
|
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/altair"
|
|
"github.com/prysmaticlabs/prysm/beacon-chain/rpc/eth/helpers"
|
|
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
|
"github.com/prysmaticlabs/prysm/config/params"
|
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
|
"github.com/prysmaticlabs/prysm/proto/eth/v2"
|
|
ethpbv2 "github.com/prysmaticlabs/prysm/proto/eth/v2"
|
|
ethpbalpha "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
|
"go.opencensus.io/trace"
|
|
"google.golang.org/grpc/codes"
|
|
"google.golang.org/grpc/status"
|
|
)
|
|
|
|
// ListSyncCommittees retrieves the sync committees for the given epoch.
|
|
// If the epoch is not passed in, then the sync committees for the epoch of the state will be obtained.
|
|
func (bs *Server) ListSyncCommittees(ctx context.Context, req *ethpbv2.StateSyncCommitteesRequest) (*ethpbv2.StateSyncCommitteesResponse, error) {
|
|
ctx, span := trace.StartSpan(ctx, "beacon.ListSyncCommittees")
|
|
defer span.End()
|
|
|
|
st, err := bs.stateFromRequest(ctx, &stateRequest{
|
|
epoch: req.Epoch,
|
|
stateId: req.StateId,
|
|
})
|
|
if err != nil {
|
|
return nil, status.Errorf(codes.Internal, "Could not fetch beacon state using request: %v", err)
|
|
}
|
|
|
|
// Get the current sync committee and sync committee indices from the state.
|
|
committeeIndices, committee, err := currentCommitteeIndicesFromState(st)
|
|
if err != nil {
|
|
return nil, status.Errorf(codes.Internal, "Could not get sync committee indices from state: %v", err)
|
|
}
|
|
subcommittees, err := extractSyncSubcommittees(st, committee)
|
|
if err != nil {
|
|
return nil, status.Errorf(codes.Internal, "Could not extract sync subcommittees: %v", err)
|
|
}
|
|
|
|
return ðpbv2.StateSyncCommitteesResponse{
|
|
Data: ðpbv2.SyncCommitteeValidators{
|
|
Validators: committeeIndices,
|
|
ValidatorAggregates: subcommittees,
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
func currentCommitteeIndicesFromState(st state.BeaconState) ([]types.ValidatorIndex, *ethpbalpha.SyncCommittee, error) {
|
|
committee, err := st.CurrentSyncCommittee()
|
|
if err != nil {
|
|
return nil, nil, fmt.Errorf(
|
|
"could not get sync committee: %v", err,
|
|
)
|
|
}
|
|
|
|
committeeIndices := make([]types.ValidatorIndex, len(committee.Pubkeys))
|
|
for i, key := range committee.Pubkeys {
|
|
index, ok := st.ValidatorIndexByPubkey(bytesutil.ToBytes48(key))
|
|
if !ok {
|
|
return nil, nil, fmt.Errorf(
|
|
"validator index not found for pubkey %#x",
|
|
bytesutil.Trunc(key),
|
|
)
|
|
}
|
|
committeeIndices[i] = index
|
|
}
|
|
return committeeIndices, committee, nil
|
|
}
|
|
|
|
func extractSyncSubcommittees(st state.BeaconState, committee *ethpbalpha.SyncCommittee) ([]*eth.SyncSubcommitteeValidators, error) {
|
|
subcommitteeCount := params.BeaconConfig().SyncCommitteeSubnetCount
|
|
subcommittees := make([]*ethpbv2.SyncSubcommitteeValidators, subcommitteeCount)
|
|
for i := uint64(0); i < subcommitteeCount; i++ {
|
|
pubkeys, err := altair.SyncSubCommitteePubkeys(committee, types.CommitteeIndex(i))
|
|
if err != nil {
|
|
return nil, fmt.Errorf(
|
|
"failed to get subcommittee pubkeys: %v", err,
|
|
)
|
|
}
|
|
subcommittee := ðpbv2.SyncSubcommitteeValidators{Validators: make([]types.ValidatorIndex, len(pubkeys))}
|
|
for j, key := range pubkeys {
|
|
index, ok := st.ValidatorIndexByPubkey(bytesutil.ToBytes48(key))
|
|
if !ok {
|
|
return nil, fmt.Errorf(
|
|
"validator index not found for pubkey %#x",
|
|
bytesutil.Trunc(key),
|
|
)
|
|
}
|
|
subcommittee.Validators[j] = index
|
|
}
|
|
subcommittees[i] = subcommittee
|
|
}
|
|
return subcommittees, nil
|
|
}
|
|
|
|
// SubmitPoolSyncCommitteeSignatures submits sync committee signature objects to the node.
|
|
func (bs *Server) SubmitPoolSyncCommitteeSignatures(ctx context.Context, req *ethpbv2.SubmitPoolSyncCommitteeSignatures) (*empty.Empty, error) {
|
|
ctx, span := trace.StartSpan(ctx, "beacon.SubmitPoolSyncCommitteeSignatures")
|
|
defer span.End()
|
|
|
|
var validMessages []*ethpbalpha.SyncCommitteeMessage
|
|
var msgFailures []*helpers.SingleIndexedVerificationFailure
|
|
for i, msg := range req.Data {
|
|
if err := validateSyncCommitteeMessage(msg); err != nil {
|
|
msgFailures = append(msgFailures, &helpers.SingleIndexedVerificationFailure{
|
|
Index: i,
|
|
Message: err.Error(),
|
|
})
|
|
continue
|
|
}
|
|
|
|
v1alpha1Msg := ðpbalpha.SyncCommitteeMessage{
|
|
Slot: msg.Slot,
|
|
BlockRoot: msg.BeaconBlockRoot,
|
|
ValidatorIndex: msg.ValidatorIndex,
|
|
Signature: msg.Signature,
|
|
}
|
|
validMessages = append(validMessages, v1alpha1Msg)
|
|
}
|
|
|
|
for _, msg := range validMessages {
|
|
_, err := bs.V1Alpha1ValidatorServer.SubmitSyncMessage(ctx, msg)
|
|
if err != nil {
|
|
return nil, status.Errorf(codes.Internal, "Could not submit message: %v", err)
|
|
}
|
|
}
|
|
|
|
if len(msgFailures) > 0 {
|
|
failuresContainer := &helpers.IndexedVerificationFailure{Failures: msgFailures}
|
|
err := grpc.AppendCustomErrorHeader(ctx, failuresContainer)
|
|
if err != nil {
|
|
return nil, status.Errorf(
|
|
codes.InvalidArgument,
|
|
"One or more messages failed validation. Could not prepare detailed failure information: %v",
|
|
err,
|
|
)
|
|
}
|
|
return nil, status.Errorf(codes.InvalidArgument, "One or more messages failed validation")
|
|
}
|
|
|
|
return &empty.Empty{}, nil
|
|
}
|
|
|
|
func validateSyncCommitteeMessage(msg *ethpbv2.SyncCommitteeMessage) error {
|
|
if len(msg.BeaconBlockRoot) != 32 {
|
|
return errors.New("invalid block root length")
|
|
}
|
|
if len(msg.Signature) != 96 {
|
|
return errors.New("invalid signature length")
|
|
}
|
|
return nil
|
|
}
|