mirror of
https://gitlab.com/pulsechaincom/prysm-pulse.git
synced 2025-01-10 19:51:20 +00:00
b0423a94af
* fork state endpoint * removing generated files * fixing linting * fixing tests using old type * moving the response object to a new file under shared * fixing test * gaz * fixing generated code * gaz * fixing linting * rolling back some changes * reverting generated changes * fixing spacing * linting * updating protos after develop merged * addressing radek's comments * addressing more radek comments
519 lines
17 KiB
Go
519 lines
17 KiB
Go
package shared
|
|
|
|
import (
|
|
"fmt"
|
|
"strconv"
|
|
|
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
|
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
|
|
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
|
|
"github.com/prysmaticlabs/prysm/v4/consensus-types/validator"
|
|
eth "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
|
)
|
|
|
|
type Attestation struct {
|
|
AggregationBits string `json:"aggregation_bits" validate:"required,hexadecimal"`
|
|
Data *AttestationData `json:"data" validate:"required"`
|
|
Signature string `json:"signature" validate:"required,hexadecimal"`
|
|
}
|
|
|
|
type AttestationData struct {
|
|
Slot string `json:"slot" validate:"required,number,gte=0"`
|
|
CommitteeIndex string `json:"index" validate:"required,number,gte=0"`
|
|
BeaconBlockRoot string `json:"beacon_block_root" validate:"required,hexadecimal"`
|
|
Source *Checkpoint `json:"source" validate:"required"`
|
|
Target *Checkpoint `json:"target" validate:"required"`
|
|
}
|
|
|
|
type Checkpoint struct {
|
|
Epoch string `json:"epoch" validate:"required,number,gte=0"`
|
|
Root string `json:"root" validate:"required,hexadecimal"`
|
|
}
|
|
|
|
type SignedContributionAndProof struct {
|
|
Message *ContributionAndProof `json:"message" validate:"required"`
|
|
Signature string `json:"signature" validate:"required,hexadecimal"`
|
|
}
|
|
|
|
type ContributionAndProof struct {
|
|
AggregatorIndex string `json:"aggregator_index" validate:"required,number,gte=0"`
|
|
Contribution *SyncCommitteeContribution `json:"contribution" validate:"required"`
|
|
SelectionProof string `json:"selection_proof" validate:"required,hexadecimal"`
|
|
}
|
|
|
|
type SyncCommitteeContribution struct {
|
|
Slot string `json:"slot" validate:"required,number,gte=0"`
|
|
BeaconBlockRoot string `json:"beacon_block_root" hex:"true" validate:"required,hexadecimal"`
|
|
SubcommitteeIndex string `json:"subcommittee_index" validate:"required,number,gte=0"`
|
|
AggregationBits string `json:"aggregation_bits" hex:"true" validate:"required,hexadecimal"`
|
|
Signature string `json:"signature" hex:"true" validate:"required,hexadecimal"`
|
|
}
|
|
|
|
type SignedAggregateAttestationAndProof struct {
|
|
Message *AggregateAttestationAndProof `json:"message" validate:"required"`
|
|
Signature string `json:"signature" validate:"required,hexadecimal"`
|
|
}
|
|
|
|
type AggregateAttestationAndProof struct {
|
|
AggregatorIndex string `json:"aggregator_index" validate:"required,number,gte=0"`
|
|
Aggregate *Attestation `json:"aggregate" validate:"required"`
|
|
SelectionProof string `json:"selection_proof" validate:"required,hexadecimal"`
|
|
}
|
|
|
|
type SyncCommitteeSubscription struct {
|
|
ValidatorIndex string `json:"validator_index" validate:"required,number,gte=0"`
|
|
SyncCommitteeIndices []string `json:"sync_committee_indices" validate:"required,dive,number,gte=0"`
|
|
UntilEpoch string `json:"until_epoch" validate:"required,number,gte=0"`
|
|
}
|
|
|
|
type BeaconCommitteeSubscription struct {
|
|
ValidatorIndex string `json:"validator_index" validate:"required,number,gte=0"`
|
|
CommitteeIndex string `json:"committee_index" validate:"required,number,gte=0"`
|
|
CommitteesAtSlot string `json:"committees_at_slot" validate:"required,number,gte=0"`
|
|
Slot string `json:"slot" validate:"required,number,gte=0"`
|
|
IsAggregator bool `json:"is_aggregator"`
|
|
}
|
|
|
|
type ValidatorRegistration struct {
|
|
FeeRecipient string `json:"fee_recipient" validate:"required,hexadecimal"`
|
|
GasLimit string `json:"gas_limit" validate:"required,number,gte=0"`
|
|
Timestamp string `json:"timestamp" validate:"required,number,gte=0"`
|
|
Pubkey string `json:"pubkey" validate:"required,hexadecimal"`
|
|
}
|
|
|
|
type SignedValidatorRegistration struct {
|
|
Message *ValidatorRegistration `json:"message" validate:"required"`
|
|
Signature string `json:"signature" validate:"required,hexadecimal"`
|
|
}
|
|
|
|
type FeeRecipient struct {
|
|
ValidatorIndex string `json:"validator_index"`
|
|
FeeRecipient string `json:"fee_recipient"`
|
|
}
|
|
|
|
type SignedVoluntaryExit struct {
|
|
Message *VoluntaryExit `json:"message" validate:"required"`
|
|
Signature string `json:"signature" validate:"required,hexadecimal"`
|
|
}
|
|
|
|
type VoluntaryExit struct {
|
|
Epoch string `json:"epoch" validate:"required,number,gte=0"`
|
|
ValidatorIndex string `json:"validator_index" validate:"required,number,gte=0"`
|
|
}
|
|
|
|
type Fork struct {
|
|
PreviousVersion string `json:"previous_version"`
|
|
CurrentVersion string `json:"current_version"`
|
|
Epoch string `json:"epoch"`
|
|
}
|
|
|
|
func (s *Fork) ToConsensus() (*eth.Fork, error) {
|
|
previousVersion, err := hexutil.Decode(s.PreviousVersion)
|
|
if err != nil {
|
|
return nil, NewDecodeError(err, "PreviousVersion")
|
|
}
|
|
currentVersion, err := hexutil.Decode(s.CurrentVersion)
|
|
if err != nil {
|
|
return nil, NewDecodeError(err, "CurrentVersion")
|
|
}
|
|
epoch, err := strconv.ParseUint(s.Epoch, 10, 64)
|
|
if err != nil {
|
|
return nil, NewDecodeError(err, "Epoch")
|
|
}
|
|
return ð.Fork{
|
|
PreviousVersion: previousVersion,
|
|
CurrentVersion: currentVersion,
|
|
Epoch: primitives.Epoch(epoch),
|
|
}, nil
|
|
}
|
|
|
|
type SyncCommitteeMessage struct {
|
|
Slot string `json:"slot" validate:"required,number,gte=0"`
|
|
BeaconBlockRoot string `json:"beacon_block_root" validate:"required,hexadecimal"`
|
|
ValidatorIndex string `json:"validator_index" validate:"required,number,gte=0"`
|
|
Signature string `json:"signature" validate:"required,hexadecimal"`
|
|
}
|
|
|
|
func (s *SignedValidatorRegistration) ToConsensus() (*eth.SignedValidatorRegistrationV1, error) {
|
|
msg, err := s.Message.ToConsensus()
|
|
if err != nil {
|
|
return nil, NewDecodeError(err, "Message")
|
|
}
|
|
sig, err := hexutil.Decode(s.Signature)
|
|
if err != nil {
|
|
return nil, NewDecodeError(err, "Signature")
|
|
}
|
|
if len(sig) != fieldparams.BLSSignatureLength {
|
|
return nil, fmt.Errorf("Signature length was %d when expecting length %d", len(sig), fieldparams.BLSSignatureLength)
|
|
}
|
|
return ð.SignedValidatorRegistrationV1{
|
|
Message: msg,
|
|
Signature: sig,
|
|
}, nil
|
|
}
|
|
|
|
func (s *ValidatorRegistration) ToConsensus() (*eth.ValidatorRegistrationV1, error) {
|
|
feeRecipient, err := hexutil.Decode(s.FeeRecipient)
|
|
if err != nil {
|
|
return nil, NewDecodeError(err, "FeeRecipient")
|
|
}
|
|
if len(feeRecipient) != fieldparams.FeeRecipientLength {
|
|
return nil, fmt.Errorf("feeRecipient length was %d when expecting length %d", len(feeRecipient), fieldparams.FeeRecipientLength)
|
|
}
|
|
pubKey, err := hexutil.Decode(s.Pubkey)
|
|
if err != nil {
|
|
return nil, NewDecodeError(err, "FeeRecipient")
|
|
}
|
|
if len(pubKey) != fieldparams.BLSPubkeyLength {
|
|
return nil, fmt.Errorf("FeeRecipient length was %d when expecting length %d", len(pubKey), fieldparams.BLSPubkeyLength)
|
|
}
|
|
gasLimit, err := strconv.ParseUint(s.GasLimit, 10, 64)
|
|
if err != nil {
|
|
return nil, NewDecodeError(err, "GasLimit")
|
|
}
|
|
timestamp, err := strconv.ParseUint(s.Timestamp, 10, 64)
|
|
if err != nil {
|
|
return nil, NewDecodeError(err, "Timestamp")
|
|
}
|
|
return ð.ValidatorRegistrationV1{
|
|
FeeRecipient: feeRecipient,
|
|
GasLimit: gasLimit,
|
|
Timestamp: timestamp,
|
|
Pubkey: pubKey,
|
|
}, nil
|
|
}
|
|
|
|
func (s *SignedContributionAndProof) ToConsensus() (*eth.SignedContributionAndProof, error) {
|
|
msg, err := s.Message.ToConsensus()
|
|
if err != nil {
|
|
return nil, NewDecodeError(err, "Message")
|
|
}
|
|
sig, err := hexutil.Decode(s.Signature)
|
|
if err != nil {
|
|
return nil, NewDecodeError(err, "Signature")
|
|
}
|
|
|
|
return ð.SignedContributionAndProof{
|
|
Message: msg,
|
|
Signature: sig,
|
|
}, nil
|
|
}
|
|
|
|
func (c *ContributionAndProof) ToConsensus() (*eth.ContributionAndProof, error) {
|
|
contribution, err := c.Contribution.ToConsensus()
|
|
if err != nil {
|
|
return nil, NewDecodeError(err, "Contribution")
|
|
}
|
|
aggregatorIndex, err := strconv.ParseUint(c.AggregatorIndex, 10, 64)
|
|
if err != nil {
|
|
return nil, NewDecodeError(err, "AggregatorIndex")
|
|
}
|
|
selectionProof, err := hexutil.Decode(c.SelectionProof)
|
|
if err != nil {
|
|
return nil, NewDecodeError(err, "SelectionProof")
|
|
}
|
|
|
|
return ð.ContributionAndProof{
|
|
AggregatorIndex: primitives.ValidatorIndex(aggregatorIndex),
|
|
Contribution: contribution,
|
|
SelectionProof: selectionProof,
|
|
}, nil
|
|
}
|
|
|
|
func (s *SyncCommitteeContribution) ToConsensus() (*eth.SyncCommitteeContribution, error) {
|
|
slot, err := strconv.ParseUint(s.Slot, 10, 64)
|
|
if err != nil {
|
|
return nil, NewDecodeError(err, "Slot")
|
|
}
|
|
bbRoot, err := hexutil.Decode(s.BeaconBlockRoot)
|
|
if err != nil {
|
|
return nil, NewDecodeError(err, "BeaconBlockRoot")
|
|
}
|
|
subcommitteeIndex, err := strconv.ParseUint(s.SubcommitteeIndex, 10, 64)
|
|
if err != nil {
|
|
return nil, NewDecodeError(err, "SubcommitteeIndex")
|
|
}
|
|
aggBits, err := hexutil.Decode(s.AggregationBits)
|
|
if err != nil {
|
|
return nil, NewDecodeError(err, "AggregationBits")
|
|
}
|
|
sig, err := hexutil.Decode(s.Signature)
|
|
if err != nil {
|
|
return nil, NewDecodeError(err, "Signature")
|
|
}
|
|
|
|
return ð.SyncCommitteeContribution{
|
|
Slot: primitives.Slot(slot),
|
|
BlockRoot: bbRoot,
|
|
SubcommitteeIndex: subcommitteeIndex,
|
|
AggregationBits: aggBits,
|
|
Signature: sig,
|
|
}, nil
|
|
}
|
|
|
|
func (s *SignedAggregateAttestationAndProof) ToConsensus() (*eth.SignedAggregateAttestationAndProof, error) {
|
|
msg, err := s.Message.ToConsensus()
|
|
if err != nil {
|
|
return nil, NewDecodeError(err, "Message")
|
|
}
|
|
sig, err := hexutil.Decode(s.Signature)
|
|
if err != nil {
|
|
return nil, NewDecodeError(err, "Signature")
|
|
}
|
|
|
|
return ð.SignedAggregateAttestationAndProof{
|
|
Message: msg,
|
|
Signature: sig,
|
|
}, nil
|
|
}
|
|
|
|
func (a *AggregateAttestationAndProof) ToConsensus() (*eth.AggregateAttestationAndProof, error) {
|
|
aggIndex, err := strconv.ParseUint(a.AggregatorIndex, 10, 64)
|
|
if err != nil {
|
|
return nil, NewDecodeError(err, "AggregatorIndex")
|
|
}
|
|
agg, err := a.Aggregate.ToConsensus()
|
|
if err != nil {
|
|
return nil, NewDecodeError(err, "Aggregate")
|
|
}
|
|
proof, err := hexutil.Decode(a.SelectionProof)
|
|
if err != nil {
|
|
return nil, NewDecodeError(err, "SelectionProof")
|
|
}
|
|
return ð.AggregateAttestationAndProof{
|
|
AggregatorIndex: primitives.ValidatorIndex(aggIndex),
|
|
Aggregate: agg,
|
|
SelectionProof: proof,
|
|
}, nil
|
|
}
|
|
|
|
func (a *Attestation) ToConsensus() (*eth.Attestation, error) {
|
|
aggBits, err := hexutil.Decode(a.AggregationBits)
|
|
if err != nil {
|
|
return nil, NewDecodeError(err, "AggregationBits")
|
|
}
|
|
data, err := a.Data.ToConsensus()
|
|
if err != nil {
|
|
return nil, NewDecodeError(err, "Data")
|
|
}
|
|
sig, err := hexutil.Decode(a.Signature)
|
|
if err != nil {
|
|
return nil, NewDecodeError(err, "Signature")
|
|
}
|
|
|
|
return ð.Attestation{
|
|
AggregationBits: aggBits,
|
|
Data: data,
|
|
Signature: sig,
|
|
}, nil
|
|
}
|
|
|
|
func AttestationFromConsensus(a *eth.Attestation) *Attestation {
|
|
return &Attestation{
|
|
AggregationBits: hexutil.Encode(a.AggregationBits),
|
|
Data: AttestationDataFromConsensus(a.Data),
|
|
Signature: hexutil.Encode(a.Signature),
|
|
}
|
|
}
|
|
|
|
func (a *AttestationData) ToConsensus() (*eth.AttestationData, error) {
|
|
slot, err := strconv.ParseUint(a.Slot, 10, 64)
|
|
if err != nil {
|
|
return nil, NewDecodeError(err, "Slot")
|
|
}
|
|
committeeIndex, err := strconv.ParseUint(a.CommitteeIndex, 10, 64)
|
|
if err != nil {
|
|
return nil, NewDecodeError(err, "CommitteeIndex")
|
|
}
|
|
bbRoot, err := hexutil.Decode(a.BeaconBlockRoot)
|
|
if err != nil {
|
|
return nil, NewDecodeError(err, "BeaconBlockRoot")
|
|
}
|
|
source, err := a.Source.ToConsensus()
|
|
if err != nil {
|
|
return nil, NewDecodeError(err, "Source")
|
|
}
|
|
target, err := a.Target.ToConsensus()
|
|
if err != nil {
|
|
return nil, NewDecodeError(err, "Target")
|
|
}
|
|
|
|
return ð.AttestationData{
|
|
Slot: primitives.Slot(slot),
|
|
CommitteeIndex: primitives.CommitteeIndex(committeeIndex),
|
|
BeaconBlockRoot: bbRoot,
|
|
Source: source,
|
|
Target: target,
|
|
}, nil
|
|
}
|
|
|
|
func AttestationDataFromConsensus(a *eth.AttestationData) *AttestationData {
|
|
return &AttestationData{
|
|
Slot: strconv.FormatUint(uint64(a.Slot), 10),
|
|
CommitteeIndex: strconv.FormatUint(uint64(a.CommitteeIndex), 10),
|
|
BeaconBlockRoot: hexutil.Encode(a.BeaconBlockRoot),
|
|
Source: CheckpointFromConsensus(a.Source),
|
|
Target: CheckpointFromConsensus(a.Target),
|
|
}
|
|
}
|
|
|
|
func (c *Checkpoint) ToConsensus() (*eth.Checkpoint, error) {
|
|
epoch, err := strconv.ParseUint(c.Epoch, 10, 64)
|
|
if err != nil {
|
|
return nil, NewDecodeError(err, "Epoch")
|
|
}
|
|
root, err := hexutil.Decode(c.Root)
|
|
if err != nil {
|
|
return nil, NewDecodeError(err, "Root")
|
|
}
|
|
|
|
return ð.Checkpoint{
|
|
Epoch: primitives.Epoch(epoch),
|
|
Root: root,
|
|
}, nil
|
|
}
|
|
|
|
func CheckpointFromConsensus(c *eth.Checkpoint) *Checkpoint {
|
|
return &Checkpoint{
|
|
Epoch: strconv.FormatUint(uint64(c.Epoch), 10),
|
|
Root: hexutil.Encode(c.Root),
|
|
}
|
|
}
|
|
|
|
func (s *SyncCommitteeSubscription) ToConsensus() (*validator.SyncCommitteeSubscription, error) {
|
|
index, err := strconv.ParseUint(s.ValidatorIndex, 10, 64)
|
|
if err != nil {
|
|
return nil, NewDecodeError(err, "ValidatorIndex")
|
|
}
|
|
scIndices := make([]uint64, len(s.SyncCommitteeIndices))
|
|
for i, ix := range s.SyncCommitteeIndices {
|
|
scIndices[i], err = strconv.ParseUint(ix, 10, 64)
|
|
if err != nil {
|
|
return nil, NewDecodeError(err, fmt.Sprintf("SyncCommitteeIndices[%d]", i))
|
|
}
|
|
}
|
|
epoch, err := strconv.ParseUint(s.UntilEpoch, 10, 64)
|
|
if err != nil {
|
|
return nil, NewDecodeError(err, "UntilEpoch")
|
|
}
|
|
|
|
return &validator.SyncCommitteeSubscription{
|
|
ValidatorIndex: primitives.ValidatorIndex(index),
|
|
SyncCommitteeIndices: scIndices,
|
|
UntilEpoch: primitives.Epoch(epoch),
|
|
}, nil
|
|
}
|
|
|
|
func (b *BeaconCommitteeSubscription) ToConsensus() (*validator.BeaconCommitteeSubscription, error) {
|
|
valIndex, err := strconv.ParseUint(b.ValidatorIndex, 10, 64)
|
|
if err != nil {
|
|
return nil, NewDecodeError(err, "ValidatorIndex")
|
|
}
|
|
committeeIndex, err := strconv.ParseUint(b.CommitteeIndex, 10, 64)
|
|
if err != nil {
|
|
return nil, NewDecodeError(err, "CommitteeIndex")
|
|
}
|
|
committeesAtSlot, err := strconv.ParseUint(b.CommitteesAtSlot, 10, 64)
|
|
if err != nil {
|
|
return nil, NewDecodeError(err, "CommitteesAtSlot")
|
|
}
|
|
slot, err := strconv.ParseUint(b.Slot, 10, 64)
|
|
if err != nil {
|
|
return nil, NewDecodeError(err, "Slot")
|
|
}
|
|
|
|
return &validator.BeaconCommitteeSubscription{
|
|
ValidatorIndex: primitives.ValidatorIndex(valIndex),
|
|
CommitteeIndex: primitives.CommitteeIndex(committeeIndex),
|
|
CommitteesAtSlot: committeesAtSlot,
|
|
Slot: primitives.Slot(slot),
|
|
IsAggregator: b.IsAggregator,
|
|
}, nil
|
|
}
|
|
|
|
func (e *SignedVoluntaryExit) ToConsensus() (*eth.SignedVoluntaryExit, error) {
|
|
sig, err := hexutil.Decode(e.Signature)
|
|
if err != nil {
|
|
return nil, NewDecodeError(err, "Signature")
|
|
}
|
|
exit, err := e.Message.ToConsensus()
|
|
if err != nil {
|
|
return nil, NewDecodeError(err, "Message")
|
|
}
|
|
|
|
return ð.SignedVoluntaryExit{
|
|
Exit: exit,
|
|
Signature: sig,
|
|
}, nil
|
|
}
|
|
|
|
func SignedVoluntaryExitFromConsensus(e *eth.SignedVoluntaryExit) *SignedVoluntaryExit {
|
|
return &SignedVoluntaryExit{
|
|
Message: VoluntaryExitFromConsensus(e.Exit),
|
|
Signature: hexutil.Encode(e.Signature),
|
|
}
|
|
}
|
|
|
|
func (e *VoluntaryExit) ToConsensus() (*eth.VoluntaryExit, error) {
|
|
epoch, err := strconv.ParseUint(e.Epoch, 10, 64)
|
|
if err != nil {
|
|
return nil, NewDecodeError(err, "Epoch")
|
|
}
|
|
valIndex, err := strconv.ParseUint(e.ValidatorIndex, 10, 64)
|
|
if err != nil {
|
|
return nil, NewDecodeError(err, "ValidatorIndex")
|
|
}
|
|
|
|
return ð.VoluntaryExit{
|
|
Epoch: primitives.Epoch(epoch),
|
|
ValidatorIndex: primitives.ValidatorIndex(valIndex),
|
|
}, nil
|
|
}
|
|
|
|
func VoluntaryExitFromConsensus(e *eth.VoluntaryExit) *VoluntaryExit {
|
|
return &VoluntaryExit{
|
|
Epoch: strconv.FormatUint(uint64(e.Epoch), 10),
|
|
ValidatorIndex: strconv.FormatUint(uint64(e.ValidatorIndex), 10),
|
|
}
|
|
}
|
|
|
|
func (m *SyncCommitteeMessage) ToConsensus() (*eth.SyncCommitteeMessage, error) {
|
|
slot, err := strconv.ParseUint(m.Slot, 10, 64)
|
|
if err != nil {
|
|
return nil, NewDecodeError(err, "Slot")
|
|
}
|
|
root, err := DecodeHexWithLength(m.BeaconBlockRoot, fieldparams.RootLength)
|
|
if err != nil {
|
|
return nil, NewDecodeError(err, "BeaconBlockRoot")
|
|
}
|
|
valIndex, err := strconv.ParseUint(m.ValidatorIndex, 10, 64)
|
|
if err != nil {
|
|
return nil, NewDecodeError(err, "ValidatorIndex")
|
|
}
|
|
sig, err := DecodeHexWithLength(m.Signature, fieldparams.BLSSignatureLength)
|
|
if err != nil {
|
|
return nil, NewDecodeError(err, "Signature")
|
|
}
|
|
|
|
return ð.SyncCommitteeMessage{
|
|
Slot: primitives.Slot(slot),
|
|
BlockRoot: root,
|
|
ValidatorIndex: primitives.ValidatorIndex(valIndex),
|
|
Signature: sig,
|
|
}, nil
|
|
}
|
|
|
|
// SyncDetails contains information about node sync status.
|
|
type SyncDetails struct {
|
|
HeadSlot string `json:"head_slot"`
|
|
SyncDistance string `json:"sync_distance"`
|
|
IsSyncing bool `json:"is_syncing"`
|
|
IsOptimistic bool `json:"is_optimistic"`
|
|
ElOffline bool `json:"el_offline"`
|
|
}
|
|
|
|
// SyncDetailsContainer is a wrapper for Data.
|
|
type SyncDetailsContainer struct {
|
|
Data *SyncDetails `json:"data"`
|
|
}
|