2023-02-14 11:25:21 +00:00
package beacon_api
import (
"context"
"net/url"
"strconv"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/pkg/errors"
2024-02-15 05:46:47 +00:00
"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"
2023-02-14 11:25:21 +00:00
)
2024-03-19 14:09:07 +00:00
func ( c * beaconApiValidatorClient ) submitAggregateSelectionProof (
ctx context . Context ,
in * ethpb . AggregateSelectionRequest ,
index primitives . ValidatorIndex ,
committeeLength uint64 ,
) ( * ethpb . AggregateSelectionResponse , error ) {
2023-02-14 11:25:21 +00:00
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" )
}
2024-03-19 14:09:07 +00:00
isAggregator , err := helpers . IsAggregator ( committeeLength , in . SlotSignature )
2023-02-14 11:25:21 +00:00
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 {
2024-03-19 14:09:07 +00:00
AggregatorIndex : index ,
2023-02-14 11:25:21 +00:00
Aggregate : aggregatedAttestation ,
SelectionProof : in . SlotSignature ,
} ,
} , nil
}
2023-12-04 11:55:21 +00:00
func ( c * beaconApiValidatorClient ) getAggregateAttestation (
ctx context . Context ,
slot primitives . Slot ,
attestationDataRoot [ ] byte ,
2024-02-03 11:57:01 +00:00
) ( * structs . AggregateAttestationResponse , error ) {
2023-02-14 11:25:21 +00:00
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 )
2024-02-03 11:57:01 +00:00
var aggregateAttestationResponse structs . AggregateAttestationResponse
2023-12-22 22:39:20 +00:00
if err := c . jsonRestHandler . Get ( ctx , endpoint , & aggregateAttestationResponse ) ; err != nil {
return nil , err
2023-02-14 11:25:21 +00:00
}
return & aggregateAttestationResponse , nil
}