prysm-pulse/validator/client/beacon-api/submit_aggregate_selection_proof.go
Radosław Kapka b692722ddf
Optimize SubmitAggregateSelectionProof VC action (#13711)
* Optimize `SubscribeCommitteeSubnets` VC action

* test fixes

* remove newline

* Optimize `SubmitAggregateSelectionProof`

* mock

* bzl gzl

* test fixes
2024-03-19 14:09:07 +00:00

86 lines
2.8 KiB
Go

package beacon_api
import (
"context"
"net/url"
"strconv"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/v5/api/server/structs"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
)
func (c *beaconApiValidatorClient) submitAggregateSelectionProof(
ctx context.Context,
in *ethpb.AggregateSelectionRequest,
index primitives.ValidatorIndex,
committeeLength uint64,
) (*ethpb.AggregateSelectionResponse, error) {
isOptimistic, err := c.isOptimistic(ctx)
if err != nil {
return nil, err
}
// An optimistic validator MUST NOT participate in attestation. (i.e., sign across the DOMAIN_BEACON_ATTESTER, DOMAIN_SELECTION_PROOF or DOMAIN_AGGREGATE_AND_PROOF domains).
if isOptimistic {
return nil, errors.New("the node is currently optimistic and cannot serve validators")
}
isAggregator, err := helpers.IsAggregator(committeeLength, in.SlotSignature)
if err != nil {
return nil, errors.Wrap(err, "failed to get aggregator status")
}
if !isAggregator {
return nil, errors.New("validator is not an aggregator")
}
attestationData, err := c.getAttestationData(ctx, in.Slot, in.CommitteeIndex)
if err != nil {
return nil, errors.Wrapf(err, "failed to get attestation data for slot=%d and committee_index=%d", in.Slot, in.CommitteeIndex)
}
attestationDataRoot, err := attestationData.HashTreeRoot()
if err != nil {
return nil, errors.Wrap(err, "failed to calculate attestation data root")
}
aggregateAttestationResponse, err := c.getAggregateAttestation(ctx, in.Slot, attestationDataRoot[:])
if err != nil {
return nil, err
}
aggregatedAttestation, err := convertAttestationToProto(aggregateAttestationResponse.Data)
if err != nil {
return nil, errors.Wrap(err, "failed to convert aggregate attestation json to proto")
}
return &ethpb.AggregateSelectionResponse{
AggregateAndProof: &ethpb.AggregateAttestationAndProof{
AggregatorIndex: index,
Aggregate: aggregatedAttestation,
SelectionProof: in.SlotSignature,
},
}, nil
}
func (c *beaconApiValidatorClient) getAggregateAttestation(
ctx context.Context,
slot primitives.Slot,
attestationDataRoot []byte,
) (*structs.AggregateAttestationResponse, error) {
params := url.Values{}
params.Add("slot", strconv.FormatUint(uint64(slot), 10))
params.Add("attestation_data_root", hexutil.Encode(attestationDataRoot))
endpoint := buildURL("/eth/v1/validator/aggregate_attestation", params)
var aggregateAttestationResponse structs.AggregateAttestationResponse
if err := c.jsonRestHandler.Get(ctx, endpoint, &aggregateAttestationResponse); err != nil {
return nil, err
}
return &aggregateAttestationResponse, nil
}