Skip to content

Commit c577fbd

Browse files
rkapkaterencechain
andauthored
Move attestation's source checkpoint validation to VerifyAttestationNoVerifySignature (#8598)
* Move attestation's source checkpoint validation to VerifyAttestationNoVerifySignature * change parameter type to ReadOnlyBeaconState Co-authored-by: terence tsao <terence@prysmaticlabs.com>
1 parent dc6dee3 commit c577fbd

File tree

4 files changed

+65
-24
lines changed

4 files changed

+65
-24
lines changed

beacon-chain/core/blocks/attestation.go

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -103,43 +103,54 @@ func ProcessAttestationsNoVerifySignature(
103103
// used before processing attestation with the beacon state.
104104
func VerifyAttestationNoVerifySignature(
105105
ctx context.Context,
106-
beaconState iface.BeaconState,
106+
beaconState iface.ReadOnlyBeaconState,
107107
att *ethpb.Attestation,
108-
) (iface.BeaconState, error) {
108+
) error {
109109
ctx, span := trace.StartSpan(ctx, "core.VerifyAttestationNoVerifySignature")
110110
defer span.End()
111111

112112
if err := helpers.ValidateNilAttestation(att); err != nil {
113-
return nil, err
113+
return err
114114
}
115115
currEpoch := helpers.CurrentEpoch(beaconState)
116116
prevEpoch := helpers.PrevEpoch(beaconState)
117117
data := att.Data
118118
if data.Target.Epoch != prevEpoch && data.Target.Epoch != currEpoch {
119-
return nil, fmt.Errorf(
119+
return fmt.Errorf(
120120
"expected target epoch (%d) to be the previous epoch (%d) or the current epoch (%d)",
121121
data.Target.Epoch,
122122
prevEpoch,
123123
currEpoch,
124124
)
125125
}
126+
127+
if data.Target.Epoch == currEpoch {
128+
if !beaconState.MatchCurrentJustifiedCheckpoint(data.Source) {
129+
return errors.New("source check point not equal to current justified checkpoint")
130+
}
131+
} else {
132+
if !beaconState.MatchPreviousJustifiedCheckpoint(data.Source) {
133+
return errors.New("source check point not equal to previous justified checkpoint")
134+
}
135+
}
136+
126137
if err := helpers.ValidateSlotTargetEpoch(att.Data); err != nil {
127-
return nil, err
138+
return err
128139
}
129140

130141
s := att.Data.Slot
131142
minInclusionCheck := s+params.BeaconConfig().MinAttestationInclusionDelay <= beaconState.Slot()
132143
epochInclusionCheck := beaconState.Slot() <= s+params.BeaconConfig().SlotsPerEpoch
133144
if !minInclusionCheck {
134-
return nil, fmt.Errorf(
145+
return fmt.Errorf(
135146
"attestation slot %d + inclusion delay %d > state slot %d",
136147
s,
137148
params.BeaconConfig().MinAttestationInclusionDelay,
138149
beaconState.Slot(),
139150
)
140151
}
141152
if !epochInclusionCheck {
142-
return nil, fmt.Errorf(
153+
return fmt.Errorf(
143154
"state slot %d > attestation slot %d + SLOTS_PER_EPOCH %d",
144155
beaconState.Slot(),
145156
s,
@@ -148,28 +159,28 @@ func VerifyAttestationNoVerifySignature(
148159
}
149160
activeValidatorCount, err := helpers.ActiveValidatorCount(beaconState, att.Data.Target.Epoch)
150161
if err != nil {
151-
return nil, err
162+
return err
152163
}
153164
c := helpers.SlotCommitteeCount(activeValidatorCount)
154165
if uint64(att.Data.CommitteeIndex) >= c {
155-
return nil, fmt.Errorf("committee index %d >= committee count %d", att.Data.CommitteeIndex, c)
166+
return fmt.Errorf("committee index %d >= committee count %d", att.Data.CommitteeIndex, c)
156167
}
157168

158169
if err := helpers.VerifyAttestationBitfieldLengths(beaconState, att); err != nil {
159-
return nil, errors.Wrap(err, "could not verify attestation bitfields")
170+
return errors.Wrap(err, "could not verify attestation bitfields")
160171
}
161172

162173
// Verify attesting indices are correct.
163174
committee, err := helpers.BeaconCommitteeFromState(beaconState, att.Data.Slot, att.Data.CommitteeIndex)
164175
if err != nil {
165-
return nil, err
176+
return err
166177
}
167178
indexedAtt, err := attestationutil.ConvertToIndexed(ctx, att, committee)
168179
if err != nil {
169-
return nil, err
180+
return err
170181
}
171182

172-
return nil, attestationutil.IsValidAttestationIndices(ctx, indexedAtt)
183+
return attestationutil.IsValidAttestationIndices(ctx, indexedAtt)
173184
}
174185

175186
// ProcessAttestationNoVerifySignature processes the attestation without verifying the attestation signature. This
@@ -182,7 +193,7 @@ func ProcessAttestationNoVerifySignature(
182193
ctx, span := trace.StartSpan(ctx, "core.ProcessAttestationNoVerifySignature")
183194
defer span.End()
184195

185-
if _, err := VerifyAttestationNoVerifySignature(ctx, beaconState, att); err != nil {
196+
if err := VerifyAttestationNoVerifySignature(ctx, beaconState, att); err != nil {
186197
return nil, err
187198
}
188199

@@ -201,16 +212,10 @@ func ProcessAttestationNoVerifySignature(
201212
}
202213

203214
if data.Target.Epoch == currEpoch {
204-
if !beaconState.MatchCurrentJustifiedCheckpoint(data.Source) {
205-
return nil, errors.New("source check point not equal to current justified checkpoint")
206-
}
207215
if err := beaconState.AppendCurrentEpochAttestations(pendingAtt); err != nil {
208216
return nil, err
209217
}
210218
} else {
211-
if !beaconState.MatchPreviousJustifiedCheckpoint(data.Source) {
212-
return nil, errors.New("source check point not equal to previous justified checkpoint")
213-
}
214219
if err := beaconState.AppendPreviousEpochAttestations(pendingAtt); err != nil {
215220
return nil, err
216221
}

beacon-chain/core/blocks/attestation_regression_test.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,13 @@ import (
66
"testing"
77

88
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
9+
"github.com/prysmaticlabs/go-bitfield"
910
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
1011
"github.com/prysmaticlabs/prysm/beacon-chain/state"
1112
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
13+
"github.com/prysmaticlabs/prysm/shared/params"
14+
"github.com/prysmaticlabs/prysm/shared/testutil"
15+
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
1216
"github.com/prysmaticlabs/prysm/shared/testutil/require"
1317
)
1418

@@ -42,3 +46,35 @@ func TestProcessAttestationNoVerifySignature_BeaconFuzzIssue78(t *testing.T) {
4246
_, err = blocks.ProcessAttestationNoVerifySignature(ctx, st, att)
4347
require.ErrorContains(t, "committee index 1 >= committee count 1", err)
4448
}
49+
50+
// Regression introduced in https://github.com/prysmaticlabs/prysm/pull/8566.
51+
func TestVerifyAttestationNoVerifySignature_IncorrectSourceEpoch(t *testing.T) {
52+
// Attestation with an empty signature
53+
54+
beaconState, _ := testutil.DeterministicGenesisState(t, 100)
55+
56+
aggBits := bitfield.NewBitlist(3)
57+
aggBits.SetBitAt(1, true)
58+
var mockRoot [32]byte
59+
copy(mockRoot[:], "hello-world")
60+
att := &ethpb.Attestation{
61+
Data: &ethpb.AttestationData{
62+
Source: &ethpb.Checkpoint{Epoch: 99, Root: mockRoot[:]},
63+
Target: &ethpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)},
64+
},
65+
AggregationBits: aggBits,
66+
}
67+
68+
zeroSig := [96]byte{}
69+
att.Signature = zeroSig[:]
70+
71+
err := beaconState.SetSlot(beaconState.Slot() + params.BeaconConfig().MinAttestationInclusionDelay)
72+
require.NoError(t, err)
73+
ckp := beaconState.CurrentJustifiedCheckpoint()
74+
copy(ckp.Root, "hello-world")
75+
require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(ckp))
76+
require.NoError(t, beaconState.SetCurrentEpochAttestations([]*pb.PendingAttestation{}))
77+
78+
err = blocks.VerifyAttestationNoVerifySignature(context.TODO(), beaconState, att)
79+
assert.NotEqual(t, nil, err)
80+
}

beacon-chain/core/blocks/attestation_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,7 @@ func TestVerifyAttestationNoVerifySignature_IncorrectSlotTargetEpoch(t *testing.
366366
},
367367
})
368368
wanted := "slot 32 does not match target epoch 0"
369-
_, err := blocks.VerifyAttestationNoVerifySignature(context.TODO(), beaconState, att)
369+
err := blocks.VerifyAttestationNoVerifySignature(context.TODO(), beaconState, att)
370370
assert.ErrorContains(t, wanted, err)
371371
}
372372

@@ -428,7 +428,7 @@ func TestVerifyAttestationNoVerifySignature_OK(t *testing.T) {
428428
require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(ckp))
429429
require.NoError(t, beaconState.SetCurrentEpochAttestations([]*pb.PendingAttestation{}))
430430

431-
_, err = blocks.VerifyAttestationNoVerifySignature(context.TODO(), beaconState, att)
431+
err = blocks.VerifyAttestationNoVerifySignature(context.TODO(), beaconState, att)
432432
assert.NoError(t, err)
433433
}
434434

@@ -453,7 +453,7 @@ func TestVerifyAttestationNoVerifySignature_BadAttIdx(t *testing.T) {
453453
copy(ckp.Root, "hello-world")
454454
require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(ckp))
455455
require.NoError(t, beaconState.SetCurrentEpochAttestations([]*pb.PendingAttestation{}))
456-
_, err := blocks.VerifyAttestationNoVerifySignature(context.TODO(), beaconState, att)
456+
err := blocks.VerifyAttestationNoVerifySignature(context.TODO(), beaconState, att)
457457
require.ErrorContains(t, "committee index 100 >= committee count 1", err)
458458
}
459459

beacon-chain/rpc/beaconv1/pool.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ func (bs *Server) SubmitAttestations(ctx context.Context, req *ethpb.SubmitAttes
3535
var validAttestations []*ethpb_alpha.Attestation
3636
for _, sourceAtt := range req.Data {
3737
att := migration.V1AttToV1Alpha1(sourceAtt)
38-
_, err = blocks.VerifyAttestationNoVerifySignature(ctx, headState, att)
38+
err = blocks.VerifyAttestationNoVerifySignature(ctx, headState, att)
3939
if err != nil {
4040
continue
4141
}

0 commit comments

Comments
 (0)