feat: EIP7045 increase max att inclusion slot (#12565)

This commit is contained in:
terencechain 2023-07-22 00:37:27 -07:00 committed by Preston Van Loon
parent 30ccff4465
commit 2bc91d20f9
6 changed files with 145 additions and 15 deletions

View File

@ -289,13 +289,13 @@ func AttestationParticipationFlagIndices(beaconState state.BeaconState, data *et
sourceFlagIndex := cfg.TimelySourceFlagIndex
targetFlagIndex := cfg.TimelyTargetFlagIndex
headFlagIndex := cfg.TimelyHeadFlagIndex
slotsPerEpoch := cfg.SlotsPerEpoch
sqtRootSlots := cfg.SqrRootSlotsPerEpoch
if matchedSrc && delay <= sqtRootSlots {
participatedFlags[sourceFlagIndex] = true
}
matchedSrcTgt := matchedSrc && matchedTgt
if matchedSrcTgt && delay <= slotsPerEpoch {
// Before Deneb no attestation should pass validation without having delay <= slotsPerEpoch.
if matchedSrcTgt {
participatedFlags[targetFlagIndex] = true
}
matchedSrcTgtHead := matchedHead && matchedSrcTgt

View File

@ -630,6 +630,9 @@ func TestAttestationParticipationFlagIndices(t *testing.T) {
targetFlagIndex := cfg.TimelyTargetFlagIndex
headFlagIndex := cfg.TimelyHeadFlagIndex
denebState, _ := util.DeterministicGenesisStateDeneb(t, params.BeaconConfig().MaxValidatorsPerCommittee)
require.NoError(t, denebState.SetSlot(1))
tests := []struct {
name string
inputState state.BeaconState
@ -678,6 +681,34 @@ func TestAttestationParticipationFlagIndices(t *testing.T) {
targetFlagIndex: true,
},
},
{
name: "participated source and target with delay",
inputState: func() state.BeaconState {
return beaconState
}(),
inputData: &ethpb.AttestationData{
Source: &ethpb.Checkpoint{Root: params.BeaconConfig().ZeroHash[:]},
Target: &ethpb.Checkpoint{Root: params.BeaconConfig().ZeroHash[:]},
},
inputDelay: params.BeaconConfig().SlotsPerEpoch + 1,
participationIndices: map[uint8]bool{
targetFlagIndex: true,
},
},
{
name: "participated source and target with delay in deneb",
inputState: func() state.BeaconState {
return denebState
}(),
inputData: &ethpb.AttestationData{
Source: &ethpb.Checkpoint{Root: params.BeaconConfig().ZeroHash[:]},
Target: &ethpb.Checkpoint{Root: params.BeaconConfig().ZeroHash[:]},
},
inputDelay: params.BeaconConfig().SlotsPerEpoch + 1,
participationIndices: map[uint8]bool{
targetFlagIndex: true,
},
},
{
name: "participated source and target and head",
inputState: func() state.BeaconState {
@ -696,7 +727,6 @@ func TestAttestationParticipationFlagIndices(t *testing.T) {
},
},
}
for _, test := range tests {
flagIndices, err := altair.AttestationParticipationFlagIndices(test.inputState, test.inputData, test.inputDelay)
require.NoError(t, err)

View File

@ -16,6 +16,7 @@ import (
"github.com/prysmaticlabs/prysm/v4/crypto/bls"
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1/attestation"
"github.com/prysmaticlabs/prysm/v4/runtime/version"
"go.opencensus.io/trace"
)
@ -81,7 +82,6 @@ func VerifyAttestationNoVerifySignature(
s := att.Data.Slot
minInclusionCheck := s+params.BeaconConfig().MinAttestationInclusionDelay <= beaconState.Slot()
epochInclusionCheck := beaconState.Slot() <= s+params.BeaconConfig().SlotsPerEpoch
if !minInclusionCheck {
return fmt.Errorf(
"attestation slot %d + inclusion delay %d > state slot %d",
@ -90,13 +90,17 @@ func VerifyAttestationNoVerifySignature(
beaconState.Slot(),
)
}
if !epochInclusionCheck {
return fmt.Errorf(
"state slot %d > attestation slot %d + SLOTS_PER_EPOCH %d",
beaconState.Slot(),
s,
params.BeaconConfig().SlotsPerEpoch,
)
if beaconState.Version() < version.Deneb {
epochInclusionCheck := beaconState.Slot() <= s+params.BeaconConfig().SlotsPerEpoch
if !epochInclusionCheck {
return fmt.Errorf(
"state slot %d > attestation slot %d + SLOTS_PER_EPOCH %d",
beaconState.Slot(),
s,
params.BeaconConfig().SlotsPerEpoch,
)
}
}
activeValidatorCount, err := helpers.ActiveValidatorCount(ctx, beaconState, att.Data.Target.Epoch)
if err != nil {

View File

@ -127,6 +127,44 @@ func TestProcessAttestationsNoVerify_OK(t *testing.T) {
assert.NoError(t, err)
}
func TestProcessAttestationsNoVerify_OlderThanSlotsPerEpoch(t *testing.T) {
aggBits := bitfield.NewBitlist(3)
aggBits.SetBitAt(1, true)
att := &ethpb.Attestation{
Data: &ethpb.AttestationData{
Source: &ethpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)},
Target: &ethpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)},
},
AggregationBits: aggBits,
}
ctx := context.Background()
t.Run("attestation older than slots per epoch", func(t *testing.T) {
beaconState, _ := util.DeterministicGenesisState(t, 100)
err := beaconState.SetSlot(beaconState.Slot() + params.BeaconConfig().SlotsPerEpoch + 1)
require.NoError(t, err)
ckp := beaconState.CurrentJustifiedCheckpoint()
copy(ckp.Root, "hello-world")
require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(ckp))
require.NoError(t, beaconState.AppendCurrentEpochAttestations(&ethpb.PendingAttestation{}))
require.ErrorContains(t, "state slot 33 > attestation slot 0 + SLOTS_PER_EPOCH 32", blocks.VerifyAttestationNoVerifySignature(ctx, beaconState, att))
})
t.Run("attestation older than slots per epoch in deneb", func(t *testing.T) {
beaconState, _ := util.DeterministicGenesisStateDeneb(t, 100)
err := beaconState.SetSlot(beaconState.Slot() + params.BeaconConfig().SlotsPerEpoch + 1)
require.NoError(t, err)
ckp := beaconState.CurrentJustifiedCheckpoint()
copy(ckp.Root, "hello-world")
require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(ckp))
require.NoError(t, blocks.VerifyAttestationNoVerifySignature(ctx, beaconState, att))
})
}
func TestVerifyAttestationNoVerifySignature_OK(t *testing.T) {
// Attestation with an empty signature

View File

@ -12,6 +12,7 @@ import (
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
prysmTime "github.com/prysmaticlabs/prysm/v4/time"
"github.com/prysmaticlabs/prysm/v4/time/slots"
log "github.com/sirupsen/logrus"
)
var (
@ -166,14 +167,33 @@ func ValidateAttestationTime(attSlot primitives.Slot, genesisTime time.Time, clo
lowerBoundsSlot,
currentSlot,
)
if attTime.Before(lowerBounds) {
attReceivedTooLateCount.Inc()
return errors.Join(ErrTooLate, attError)
}
if attTime.After(upperBounds) {
attReceivedTooEarlyCount.Inc()
return attError
}
attEpoch := slots.ToEpoch(attSlot)
if attEpoch < params.BeaconConfig().DenebForkEpoch {
if attTime.Before(lowerBounds) {
attReceivedTooLateCount.Inc()
return errors.Join(ErrTooLate, attError)
}
return nil
}
// EIP-7045: Starting in Deneb, allow any attestations from the current or previous epoch.
currentEpoch := slots.ToEpoch(currentSlot)
prevEpoch, err := currentEpoch.SafeSub(1)
if err != nil {
log.WithError(err).Debug("Ignoring underflow for a deneb attestation inclusion check in epoch 0")
prevEpoch = 0
}
attSlotEpoch := slots.ToEpoch(attSlot)
if attSlotEpoch != currentEpoch && attSlotEpoch != prevEpoch {
return fmt.Errorf("attestation slot %d not within current epoch %d or previous epoch %d", attSlot, currentEpoch, prevEpoch)
}
return nil
}

View File

@ -85,6 +85,11 @@ func TestAttestation_ComputeSubnetForAttestation(t *testing.T) {
}
func Test_ValidateAttestationTime(t *testing.T) {
cfg := params.BeaconConfig().Copy()
cfg.DenebForkEpoch = 5
params.OverrideBeaconConfig(cfg)
params.SetupTestConfigCleanup(t)
if params.BeaconNetworkConfig().MaximumGossipClockDisparity < 200*time.Millisecond {
t.Fatal("This test expects the maximum clock disparity to be at least 200ms")
}
@ -155,6 +160,39 @@ func Test_ValidateAttestationTime(t *testing.T) {
).Add(200 * time.Millisecond),
},
},
{
name: "attestation.slot < current_slot-ATTESTATION_PROPAGATION_SLOT_RANGE in deneb",
args: args{
attSlot: 300 - params.BeaconNetworkConfig().AttestationPropagationSlotRange - 1,
genesisTime: prysmTime.Now().Add(-300 * time.Duration(params.BeaconConfig().SecondsPerSlot) * time.Second),
},
},
{
name: "attestation.slot = current_slot-ATTESTATION_PROPAGATION_SLOT_RANGE in deneb",
args: args{
attSlot: 300 - params.BeaconNetworkConfig().AttestationPropagationSlotRange,
genesisTime: prysmTime.Now().Add(-300 * time.Duration(params.BeaconConfig().SecondsPerSlot) * time.Second),
},
},
{
name: "attestation.slot = current_slot-ATTESTATION_PROPAGATION_SLOT_RANGE, received 200ms late in deneb",
args: args{
attSlot: 300 - params.BeaconNetworkConfig().AttestationPropagationSlotRange,
genesisTime: prysmTime.Now().Add(
-300 * time.Duration(params.BeaconConfig().SecondsPerSlot) * time.Second,
).Add(200 * time.Millisecond),
},
},
{
name: "attestation.slot != current epoch or previous epoch in deneb",
args: args{
attSlot: 300 - params.BeaconNetworkConfig().AttestationPropagationSlotRange,
genesisTime: prysmTime.Now().Add(
-500 * time.Duration(params.BeaconConfig().SecondsPerSlot) * time.Second,
).Add(200 * time.Millisecond),
},
wantedErr: "attestation slot 268 not within current epoch 15 or previous epoch 14",
},
{
name: "attestation.slot is well beyond current slot",
args: args{