From 7d0e607f96b8ae774ff34eebe9ed8c5ab5e7e3ad Mon Sep 17 00:00:00 2001 From: Chris Berry Date: Mon, 27 Jan 2025 10:01:36 +0000 Subject: [PATCH] Update to use electra version of go-eth2-client --- .gitignore | 6 ++ CHANGELOG.md | 3 + cmd/attester/inclusion/output.go | 3 +- cmd/attester/inclusion/process.go | 35 +++++++++--- cmd/block/analyze/process.go | 95 +++++++++++++++++++------------ cmd/epoch/summary/process.go | 30 ++++++---- cmd/validator/summary/process.go | 20 +++++-- go.mod | 2 +- go.sum | 2 + testing/mock/eth2client.go | 4 +- util/attestations.go | 38 +++++++++---- 11 files changed, 163 insertions(+), 75 deletions(-) diff --git a/.gitignore b/.gitignore index 616fdea..02023e9 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,12 @@ coverage.html # Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736 .glide/ +# Intellij +.idea/ + +# Makefile +Makefile + # Vim *.sw? diff --git a/CHANGELOG.md b/CHANGELOG.md index 9278187..914d84f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +electra: + - update to handle versioned attestations from go-eth2-client electra branch + 1.36.2: - avoid crash when signing and verifing signatures using keys rather than accounts diff --git a/cmd/attester/inclusion/output.go b/cmd/attester/inclusion/output.go index c81aa76..37dc902 100644 --- a/cmd/attester/inclusion/output.go +++ b/cmd/attester/inclusion/output.go @@ -19,6 +19,7 @@ import ( "strconv" "strings" + "github.com/attestantio/go-eth2-client/spec" "github.com/attestantio/go-eth2-client/spec/phase0" "github.com/pkg/errors" ) @@ -27,7 +28,7 @@ type dataOut struct { debug bool quiet bool verbose bool - attestation *phase0.Attestation + attestation *spec.VersionedAttestation slot phase0.Slot attestationIndex uint64 inclusionDelay phase0.Slot diff --git a/cmd/attester/inclusion/process.go b/cmd/attester/inclusion/process.go index 9701334..b7b5813 100644 --- a/cmd/attester/inclusion/process.go +++ b/cmd/attester/inclusion/process.go @@ -22,6 +22,7 @@ import ( eth2client "github.com/attestantio/go-eth2-client" "github.com/attestantio/go-eth2-client/api" apiv1 "github.com/attestantio/go-eth2-client/api/v1" + "github.com/attestantio/go-eth2-client/spec" "github.com/attestantio/go-eth2-client/spec/phase0" "github.com/pkg/errors" standardchaintime "github.com/wealdtech/ethdo/services/chaintime/standard" @@ -93,9 +94,17 @@ func process(ctx context.Context, data *dataIn) (*dataOut, error) { return nil, errors.Wrap(err, "failed to obtain block attestations") } for i, attestation := range attestations { - if attestation.Data.Slot == duty.Slot && - attestation.Data.Index == duty.CommitteeIndex && - attestation.AggregationBits.BitAt(duty.ValidatorCommitteeIndex) { + attestationData, err := attestation.Data() + if err != nil { + return nil, errors.Wrap(err, "failed to obtain attestation data") + } + aggregationBits, err := attestation.AggregationBits() + if err != nil { + return nil, errors.Wrap(err, "failed to obtain aggregation bits") + } + if attestationData.Slot == duty.Slot && + attestationData.Index == duty.CommitteeIndex && + aggregationBits.BitAt(duty.ValidatorCommitteeIndex) { headCorrect := false targetCorrect := false if data.verbose { @@ -128,8 +137,12 @@ func process(ctx context.Context, data *dataIn) (*dataOut, error) { return results, nil } -func calcHeadCorrect(ctx context.Context, data *dataIn, attestation *phase0.Attestation) (bool, error) { - slot := attestation.Data.Slot +func calcHeadCorrect(ctx context.Context, data *dataIn, attestation *spec.VersionedAttestation) (bool, error) { + attestationData, err := attestation.Data() + if err != nil { + return false, errors.Wrap(err, "failed to obtain attestation data") + } + slot := attestationData.Slot for { response, err := data.eth2Client.(eth2client.BeaconBlockHeadersProvider).BeaconBlockHeader(ctx, &api.BeaconBlockHeaderOpts{ Block: fmt.Sprintf("%d", slot), @@ -149,13 +162,17 @@ func calcHeadCorrect(ctx context.Context, data *dataIn, attestation *phase0.Atte slot-- continue } - return bytes.Equal(response.Data.Root[:], attestation.Data.BeaconBlockRoot[:]), nil + return bytes.Equal(response.Data.Root[:], attestationData.BeaconBlockRoot[:]), nil } } -func calcTargetCorrect(ctx context.Context, data *dataIn, attestation *phase0.Attestation) (bool, error) { +func calcTargetCorrect(ctx context.Context, data *dataIn, attestation *spec.VersionedAttestation) (bool, error) { + attestationData, err := attestation.Data() + if err != nil { + return false, errors.Wrap(err, "failed to obtain attestation data") + } // Start with first slot of the target epoch. - slot := data.chainTime.FirstSlotOfEpoch(attestation.Data.Target.Epoch) + slot := data.chainTime.FirstSlotOfEpoch(attestationData.Target.Epoch) for { response, err := data.eth2Client.(eth2client.BeaconBlockHeadersProvider).BeaconBlockHeader(ctx, &api.BeaconBlockHeaderOpts{ Block: fmt.Sprintf("%d", slot), @@ -175,7 +192,7 @@ func calcTargetCorrect(ctx context.Context, data *dataIn, attestation *phase0.At slot-- continue } - return bytes.Equal(response.Data.Root[:], attestation.Data.Target.Root[:]), nil + return bytes.Equal(response.Data.Root[:], attestationData.Target.Root[:]), nil } } diff --git a/cmd/block/analyze/process.go b/cmd/block/analyze/process.go index 66b3ef2..7e7524a 100644 --- a/cmd/block/analyze/process.go +++ b/cmd/block/analyze/process.go @@ -63,8 +63,12 @@ func (c *command) process(ctx context.Context) error { // Calculate how many parents we need to fetch. minSlot := slot for _, attestation := range attestations { - if attestation.Data.Slot < minSlot { - minSlot = attestation.Data.Slot + attestData, err := attestation.Data() + if err != nil { + return errors.Wrap(err, "failed to obtain attestation data") + } + if attestData.Slot < minSlot { + minSlot = attestData.Slot } } if c.debug { @@ -103,10 +107,14 @@ func (c *command) analyzeAttestations(ctx context.Context, block *spec.Versioned if c.debug { fmt.Printf("Processing attestation %d\n", i) } + attestData, err := attestation.Data() + if err != nil { + return errors.Wrap(err, "failed to obtain attestation data") + } analysis := &attestationAnalysis{ - Head: attestation.Data.BeaconBlockRoot, - Target: attestation.Data.Target.Root, - Distance: int(slot - attestation.Data.Slot), + Head: attestData.BeaconBlockRoot, + Target: attestData.Target.Root, + Distance: int(slot - attestData.Slot), } root, err := attestation.HashTreeRoot() @@ -116,45 +124,47 @@ func (c *command) analyzeAttestations(ctx context.Context, block *spec.Versioned if info, exists := c.priorAttestations[fmt.Sprintf("%#x", root)]; exists { analysis.Duplicate = info } else { - data := attestation.Data - _, exists := blockVotes[data.Slot] - if !exists { - blockVotes[data.Slot] = make(map[phase0.CommitteeIndex]bitfield.Bitlist) + aggregationBits, err := attestation.AggregationBits() + if err != nil { + return err } - _, exists = blockVotes[data.Slot][data.Index] + _, exists := blockVotes[attestData.Slot] if !exists { - blockVotes[data.Slot][data.Index] = bitfield.NewBitlist(attestation.AggregationBits.Len()) + blockVotes[attestData.Slot] = make(map[phase0.CommitteeIndex]bitfield.Bitlist) + } + _, exists = blockVotes[attestData.Slot][attestData.Index] + if !exists { + blockVotes[attestData.Slot][attestData.Index] = bitfield.NewBitlist(aggregationBits.Len()) } // Count new votes. - analysis.PossibleVotes = int(attestation.AggregationBits.Len()) - for j := range attestation.AggregationBits.Len() { - if attestation.AggregationBits.BitAt(j) { + analysis.PossibleVotes = int(aggregationBits.Len()) + for j := range aggregationBits.Len() { + if aggregationBits.BitAt(j) { analysis.Votes++ - if blockVotes[data.Slot][data.Index].BitAt(j) { + if blockVotes[attestData.Slot][attestData.Index].BitAt(j) { // Already attested to in this block; skip. continue } - if c.votes[data.Slot][data.Index].BitAt(j) { + if c.votes[attestData.Slot][attestData.Index].BitAt(j) { // Already attested to in a previous block; skip. continue } analysis.NewVotes++ - blockVotes[data.Slot][data.Index].SetBitAt(j, true) + blockVotes[attestData.Slot][attestData.Index].SetBitAt(j, true) } } // Calculate head correct. - var err error analysis.HeadCorrect, err = c.calcHeadCorrect(ctx, attestation) if err != nil { return err } // Calculate head timely. - analysis.HeadTimely = analysis.HeadCorrect && attestation.Data.Slot == slot-1 + analysis.HeadTimely = analysis.HeadCorrect && attestData.Slot == slot-1 // Calculate source timely. - analysis.SourceTimely = attestation.Data.Slot >= slot-5 + analysis.SourceTimely = attestData.Slot >= slot-5 // Calculate target correct. analysis.TargetCorrect, err = c.calcTargetCorrect(ctx, attestation) @@ -164,7 +174,7 @@ func (c *command) analyzeAttestations(ctx context.Context, block *spec.Versioned // Calculate target timely. if block.Version < spec.DataVersionDeneb { - analysis.TargetTimely = attestation.Data.Slot >= slot-32 + analysis.TargetTimely = attestData.Slot >= slot-32 } else { analysis.TargetTimely = true } @@ -260,17 +270,24 @@ func (c *command) processParentBlock(_ context.Context, block *spec.VersionedSig Index: i, } - data := attestation.Data + data, err := attestation.Data() + if err != nil { + return err + } _, exists := c.votes[data.Slot] if !exists { c.votes[data.Slot] = make(map[phase0.CommitteeIndex]bitfield.Bitlist) } _, exists = c.votes[data.Slot][data.Index] - if !exists { - c.votes[data.Slot][data.Index] = bitfield.NewBitlist(attestation.AggregationBits.Len()) + aggregationBits, err := attestation.AggregationBits() + if err != nil { + return err } - for j := range attestation.AggregationBits.Len() { - if attestation.AggregationBits.BitAt(j) { + if !exists { + c.votes[data.Slot][data.Index] = bitfield.NewBitlist(aggregationBits.Len()) + } + for j := range aggregationBits.Len() { + if aggregationBits.BitAt(j) { c.votes[data.Slot][data.Index].SetBitAt(j, true) } } @@ -385,8 +402,12 @@ func (c *command) setup(ctx context.Context) error { return nil } -func (c *command) calcHeadCorrect(ctx context.Context, attestation *phase0.Attestation) (bool, error) { - slot := attestation.Data.Slot +func (c *command) calcHeadCorrect(ctx context.Context, attestation *spec.VersionedAttestation) (bool, error) { + attestData, err := attestation.Data() + if err != nil { + return false, errors.Wrap(err, "failed to obtain attestation data") + } + slot := attestData.Slot root, exists := c.headRoots[slot] if !exists { for { @@ -413,20 +434,24 @@ func (c *command) calcHeadCorrect(ctx context.Context, attestation *phase0.Attes slot-- continue } - c.headRoots[attestation.Data.Slot] = response.Data.Root + c.headRoots[attestData.Slot] = response.Data.Root root = response.Data.Root break } } - return bytes.Equal(root[:], attestation.Data.BeaconBlockRoot[:]), nil + return bytes.Equal(root[:], attestData.BeaconBlockRoot[:]), nil } -func (c *command) calcTargetCorrect(ctx context.Context, attestation *phase0.Attestation) (bool, error) { - root, exists := c.targetRoots[attestation.Data.Slot] +func (c *command) calcTargetCorrect(ctx context.Context, attestation *spec.VersionedAttestation) (bool, error) { + attestData, err := attestation.Data() + if err != nil { + return false, errors.Wrap(err, "failed to obtain attestation data") + } + root, exists := c.targetRoots[attestData.Slot] if !exists { // Start with first slot of the target epoch. - slot := c.chainTime.FirstSlotOfEpoch(attestation.Data.Target.Epoch) + slot := c.chainTime.FirstSlotOfEpoch(attestData.Target.Epoch) for { response, err := c.blockHeadersProvider.BeaconBlockHeader(ctx, &api.BeaconBlockHeaderOpts{ Block: fmt.Sprintf("%d", slot), @@ -450,12 +475,12 @@ func (c *command) calcTargetCorrect(ctx context.Context, attestation *phase0.Att slot-- continue } - c.targetRoots[attestation.Data.Slot] = response.Data.Root + c.targetRoots[attestData.Slot] = response.Data.Root root = response.Data.Root break } } - return bytes.Equal(root[:], attestation.Data.Target.Root[:]), nil + return bytes.Equal(root[:], attestData.Target.Root[:]), nil } func (c *command) analyzeSyncCommittees(_ context.Context, block *spec.VersionedSignedBeaconBlock) error { diff --git a/cmd/epoch/summary/process.go b/cmd/epoch/summary/process.go index 93759f1..aecc49a 100644 --- a/cmd/epoch/summary/process.go +++ b/cmd/epoch/summary/process.go @@ -239,17 +239,21 @@ func (c *command) processSlots(ctx context.Context, return nil, nil, nil, nil, nil, nil, nil, err } for _, attestation := range attestations { - if attestation.Data.Slot < c.chainTime.FirstSlotOfEpoch(c.summary.Epoch) || attestation.Data.Slot >= c.chainTime.FirstSlotOfEpoch(c.summary.Epoch+1) { + attestationData, err := attestation.Data() + if err != nil { + return nil, nil, nil, nil, nil, nil, nil, errors.Wrap(err, "failed to obtain attestation data") + } + if attestationData.Slot < c.chainTime.FirstSlotOfEpoch(c.summary.Epoch) || attestationData.Slot >= c.chainTime.FirstSlotOfEpoch(c.summary.Epoch+1) { // Outside of this epoch's range. continue } - slotCommittees, exists := allCommittees[attestation.Data.Slot] + slotCommittees, exists := allCommittees[attestationData.Slot] if !exists { response, err := c.beaconCommitteesProvider.BeaconCommittees(ctx, &api.BeaconCommitteesOpts{ - State: fmt.Sprintf("%d", attestation.Data.Slot), + State: fmt.Sprintf("%d", attestationData.Slot), }) if err != nil { - return nil, nil, nil, nil, nil, nil, nil, errors.Wrap(err, fmt.Sprintf("failed to obtain committees for slot %d", attestation.Data.Slot)) + return nil, nil, nil, nil, nil, nil, nil, errors.Wrap(err, fmt.Sprintf("failed to obtain committees for slot %d", attestationData.Slot)) } for _, beaconCommittee := range response.Data { if _, exists := allCommittees[beaconCommittee.Slot]; !exists { @@ -275,11 +279,11 @@ func (c *command) processSlots(ctx context.Context, } } } - slotCommittees = allCommittees[attestation.Data.Slot] + slotCommittees = allCommittees[attestationData.Slot] } - committee := slotCommittees[attestation.Data.Index] + committee := slotCommittees[attestationData.Index] - inclusionDistance := slot - attestation.Data.Slot + inclusionDistance := slot - attestationData.Slot head, err := util.AttestationHead(ctx, headersCache, attestation) if err != nil { @@ -298,8 +302,12 @@ func (c *command) processSlots(ctx context.Context, return nil, nil, nil, nil, nil, nil, nil, err } - for i := range attestation.AggregationBits.Len() { - if attestation.AggregationBits.BitAt(i) { + aggregationBits, err := attestation.AggregationBits() + if err != nil { + return nil, nil, nil, nil, nil, nil, nil, errors.Wrap(err, "failed to obtain aggregation bits") + } + for i := range aggregationBits.Len() { + if aggregationBits.BitAt(i) { validatorIndex := committee[int(i)] if len(c.validators) > 0 { if _, exists := c.validators[validatorIndex]; !exists { @@ -310,9 +318,9 @@ func (c *command) processSlots(ctx context.Context, // Only set the information from the first attestation we find for this validator. if participations[validatorIndex].InclusionSlot == 0 { - participations[validatorIndex].HeadVote = &attestation.Data.BeaconBlockRoot + participations[validatorIndex].HeadVote = &attestationData.BeaconBlockRoot participations[validatorIndex].Head = &head - participations[validatorIndex].TargetVote = &attestation.Data.Target.Root + participations[validatorIndex].TargetVote = &attestationData.Target.Root participations[validatorIndex].Target = &target participations[validatorIndex].InclusionSlot = slot } diff --git a/cmd/validator/summary/process.go b/cmd/validator/summary/process.go index e9166d0..c74c6f4 100644 --- a/cmd/validator/summary/process.go +++ b/cmd/validator/summary/process.go @@ -243,16 +243,24 @@ func (c *command) processAttesterDutiesSlot(ctx context.Context, return err } for _, attestation := range attestations { - if _, exists := dutiesBySlot[attestation.Data.Slot]; !exists { + attestationData, err := attestation.Data() + if err != nil { + return errors.Wrap(err, "failed to obtain attestation data") + } + if _, exists := dutiesBySlot[attestationData.Slot]; !exists { // We do not have any attestations for this slot. continue } - if _, exists := dutiesBySlot[attestation.Data.Slot][attestation.Data.Index]; !exists { + if _, exists := dutiesBySlot[attestationData.Slot][attestationData.Index]; !exists { // We do not have any attestations for this committee. continue } - for _, duty := range dutiesBySlot[attestation.Data.Slot][attestation.Data.Index] { - if attestation.AggregationBits.BitAt(duty.ValidatorCommitteeIndex) { + for _, duty := range dutiesBySlot[attestationData.Slot][attestationData.Index] { + aggregationBits, err := attestation.AggregationBits() + if err != nil { + return errors.Wrap(err, "failed to obtain aggregation bits") + } + if aggregationBits.BitAt(duty.ValidatorCommitteeIndex) { // Found it. if _, exists := votes[duty.ValidatorIndex]; exists { // Duplicate; ignore. @@ -261,13 +269,13 @@ func (c *command) processAttesterDutiesSlot(ctx context.Context, votes[duty.ValidatorIndex] = struct{}{} // Update the metrics for the attestation. - index := int(attestation.Data.Slot - c.chainTime.FirstSlotOfEpoch(c.summary.Epoch)) + index := int(attestationData.Slot - c.chainTime.FirstSlotOfEpoch(c.summary.Epoch)) c.summary.Slots[index].Attestations.Included++ inclusionDelay := slot - duty.Slot fault := &validatorFault{ Validator: duty.ValidatorIndex, - AttestationData: attestation.Data, + AttestationData: attestationData, InclusionDistance: int(inclusionDelay), } diff --git a/go.mod b/go.mod index 02a7c5e..c38bb07 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.22.7 toolchain go1.23.2 require ( - github.com/attestantio/go-eth2-client v0.22.0 + github.com/attestantio/go-eth2-client v0.23.1-0.20250127091537-251e60f042d4 github.com/ferranbt/fastssz v0.1.4 github.com/gofrs/uuid v4.4.0+incompatible github.com/google/uuid v1.6.0 diff --git a/go.sum b/go.sum index 6f57784..7836a12 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,7 @@ github.com/attestantio/go-eth2-client v0.22.0 h1:KmF9kPNNWWGfE7l1BP7pXps4EOXgKnYeFGR0/WbyFhY= github.com/attestantio/go-eth2-client v0.22.0/go.mod h1:d7ZPNrMX8jLfIgML5u7QZxFo2AukLM+5m08iMaLdqb8= +github.com/attestantio/go-eth2-client v0.23.1-0.20250127091537-251e60f042d4 h1:ePstQwO3RoDX2am93bvtUNLsMtxlikx9kPJDdzr9sk8= +github.com/attestantio/go-eth2-client v0.23.1-0.20250127091537-251e60f042d4/go.mod h1:vy5jU/uDZ2+RcVzq5BfnG+bQ3/6uu9DGwCrGsPtjJ1A= github.com/aws/aws-sdk-go v1.55.5 h1:KKUZBfBoyqy5d3swXyiC7Q76ic40rYcbqH7qjh59kzU= github.com/aws/aws-sdk-go v1.55.5/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= diff --git a/testing/mock/eth2client.go b/testing/mock/eth2client.go index 7896d41..fa257fa 100644 --- a/testing/mock/eth2client.go +++ b/testing/mock/eth2client.go @@ -119,7 +119,7 @@ func NewAttestationSubmitter() eth2client.AttestationsSubmitter { } // SubmitAttestations is a mock. -func (m *AttestationsSubmitter) SubmitAttestations(_ context.Context, _ []*phase0.Attestation) error { +func (m *AttestationsSubmitter) SubmitAttestations(_ context.Context, _ *api.SubmitAttestationsOpts) error { return nil } @@ -145,7 +145,7 @@ func NewAggregateAttestationsSubmitter() eth2client.AggregateAttestationsSubmitt } // SubmitAggregateAttestations is a mock. -func (m *AggregateAttestationsSubmitter) SubmitAggregateAttestations(_ context.Context, _ []*phase0.SignedAggregateAndProof) error { +func (m *AggregateAttestationsSubmitter) SubmitAggregateAttestations(_ context.Context, _ *api.SubmitAggregateAttestationsOpts) error { return nil } diff --git a/util/attestations.go b/util/attestations.go index 0a812a3..7624c23 100644 --- a/util/attestations.go +++ b/util/attestations.go @@ -17,19 +17,25 @@ import ( "bytes" "context" + "github.com/attestantio/go-eth2-client/spec" "github.com/attestantio/go-eth2-client/spec/phase0" + "github.com/pkg/errors" "github.com/wealdtech/ethdo/services/chaintime" ) // AttestationHead returns the head for which the attestation should have voted. func AttestationHead(ctx context.Context, headersCache *BeaconBlockHeaderCache, - attestation *phase0.Attestation, + attestation *spec.VersionedAttestation, ) ( phase0.Root, error, ) { - slot := attestation.Data.Slot + attestationData, err := attestation.Data() + if err != nil { + return phase0.Root{}, errors.Wrap(err, "failed to obtain attestation data") + } + slot := attestationData.Slot for { header, err := headersCache.Fetch(ctx, slot) if err != nil { @@ -53,12 +59,16 @@ func AttestationHead(ctx context.Context, // AttestationHeadCorrect returns true if the given attestation had the correct head. func AttestationHeadCorrect(ctx context.Context, headersCache *BeaconBlockHeaderCache, - attestation *phase0.Attestation, + attestation *spec.VersionedAttestation, ) ( bool, error, ) { - slot := attestation.Data.Slot + attestationData, err := attestation.Data() + if err != nil { + return false, errors.Wrap(err, "failed to obtain attestation data") + } + slot := attestationData.Slot for { header, err := headersCache.Fetch(ctx, slot) if err != nil { @@ -74,7 +84,7 @@ func AttestationHeadCorrect(ctx context.Context, slot-- continue } - return bytes.Equal(header.Root[:], attestation.Data.BeaconBlockRoot[:]), nil + return bytes.Equal(header.Root[:], attestationData.BeaconBlockRoot[:]), nil } } @@ -82,13 +92,17 @@ func AttestationHeadCorrect(ctx context.Context, func AttestationTarget(ctx context.Context, headersCache *BeaconBlockHeaderCache, chainTime chaintime.Service, - attestation *phase0.Attestation, + attestation *spec.VersionedAttestation, ) ( phase0.Root, error, ) { + attestationData, err := attestation.Data() + if err != nil { + return phase0.Root{}, errors.Wrap(err, "failed to obtain attestation data") + } // Start with first slot of the target epoch. - slot := chainTime.FirstSlotOfEpoch(attestation.Data.Target.Epoch) + slot := chainTime.FirstSlotOfEpoch(attestationData.Target.Epoch) for { header, err := headersCache.Fetch(ctx, slot) if err != nil { @@ -113,13 +127,17 @@ func AttestationTarget(ctx context.Context, func AttestationTargetCorrect(ctx context.Context, headersCache *BeaconBlockHeaderCache, chainTime chaintime.Service, - attestation *phase0.Attestation, + attestation *spec.VersionedAttestation, ) ( bool, error, ) { + attestationData, err := attestation.Data() + if err != nil { + return false, errors.Wrap(err, "failed to obtain attestation data") + } // Start with first slot of the target epoch. - slot := chainTime.FirstSlotOfEpoch(attestation.Data.Target.Epoch) + slot := chainTime.FirstSlotOfEpoch(attestationData.Target.Epoch) for { header, err := headersCache.Fetch(ctx, slot) if err != nil { @@ -135,6 +153,6 @@ func AttestationTargetCorrect(ctx context.Context, slot-- continue } - return bytes.Equal(header.Root[:], attestation.Data.Target.Root[:]), nil + return bytes.Equal(header.Root[:], attestationData.Target.Root[:]), nil } }