From c5b4cf7f7dfd1c5bed5d6a082a421f4d5293d698 Mon Sep 17 00:00:00 2001 From: terence tsao Date: Sun, 15 Sep 2019 13:54:55 -0700 Subject: [PATCH] Fixed attesting indices set (#3469) * Fixed attesting indices set * Typo * Regression test * Comment * Validator count for tests --- beacon-chain/core/epoch/epoch_processing.go | 9 ++-- .../core/epoch/epoch_processing_test.go | 49 +++++++++++++++++-- 2 files changed, 49 insertions(+), 9 deletions(-) diff --git a/beacon-chain/core/epoch/epoch_processing.go b/beacon-chain/core/epoch/epoch_processing.go index 5af26278b..60035b436 100644 --- a/beacon-chain/core/epoch/epoch_processing.go +++ b/beacon-chain/core/epoch/epoch_processing.go @@ -570,13 +570,14 @@ func unslashedAttestingIndices(state *pb.BeaconState, atts []*pb.PendingAttestat return nil, errors.Wrap(err, "could not get attester indices") } // Create a set for attesting indices - for i, index := range attestingIndices { - if seen[index] { // Remove duplicate - attestingIndices = append(attestingIndices[:i], attestingIndices[i+1:]...) + set := make([]uint64, 0, len(attestingIndices)) + for _, index := range attestingIndices { + if !seen[index] { + set = append(set, index) } seen[index] = true } - setIndices = append(setIndices, attestingIndices...) + setIndices = append(setIndices, set...) } // Sort the attesting set indices by increasing order. sort.Slice(setIndices, func(i, j int) bool { return setIndices[i] < setIndices[j] }) diff --git a/beacon-chain/core/epoch/epoch_processing_test.go b/beacon-chain/core/epoch/epoch_processing_test.go index 7578108e4..4016b6904 100644 --- a/beacon-chain/core/epoch/epoch_processing_test.go +++ b/beacon-chain/core/epoch/epoch_processing_test.go @@ -35,19 +35,19 @@ func TestUnslashedAttestingIndices_CanSortAndFilter(t *testing.T) { Shard: uint64(i), }, }, - AggregationBits: bitfield.Bitlist{0xC0, 0xC0, 0x01}, + AggregationBits: bitfield.Bitlist{0xFF, 0xFF, 0xFF}, } } // Generate validators and state for the 2 attestations. - validators := make([]*ethpb.Validator, params.BeaconConfig().MinGenesisActiveValidatorCount/16) + validatorCount := 1000 + validators := make([]*ethpb.Validator, validatorCount) for i := 0; i < len(validators); i++ { validators[i] = ðpb.Validator{ ExitEpoch: params.BeaconConfig().FarFutureEpoch, } } state := &pb.BeaconState{ - Slot: 0, Validators: validators, RandaoMixes: make([][]byte, params.BeaconConfig().EpochsPerHistoricalVector), ActiveIndexRoots: make([][]byte, params.BeaconConfig().EpochsPerHistoricalVector), @@ -58,8 +58,8 @@ func TestUnslashedAttestingIndices_CanSortAndFilter(t *testing.T) { t.Fatal(err) } for i := 0; i < len(indices)-1; i++ { - if indices[i] > indices[i+1] { - t.Error("sorted indices not sorted") + if indices[i] >= indices[i+1] { + t.Error("sorted indices not sorted or duplicated") } } @@ -77,6 +77,45 @@ func TestUnslashedAttestingIndices_CanSortAndFilter(t *testing.T) { } } +func TestUnslashedAttestingIndices_DuplicatedAttestations(t *testing.T) { + // Generate 5 of the same attestations. + atts := make([]*pb.PendingAttestation, 5) + for i := 0; i < len(atts); i++ { + atts[i] = &pb.PendingAttestation{ + Data: ðpb.AttestationData{Source: ðpb.Checkpoint{}, + Target: ðpb.Checkpoint{Epoch: 0}, + Crosslink: ðpb.Crosslink{}, + }, + AggregationBits: bitfield.Bitlist{0xFF, 0xFF, 0xFF}, + } + } + + // Generate validators and state for the 5 attestations. + validatorCount := 1000 + validators := make([]*ethpb.Validator, validatorCount) + for i := 0; i < len(validators); i++ { + validators[i] = ðpb.Validator{ + ExitEpoch: params.BeaconConfig().FarFutureEpoch, + } + } + state := &pb.BeaconState{ + Validators: validators, + RandaoMixes: make([][]byte, params.BeaconConfig().EpochsPerHistoricalVector), + ActiveIndexRoots: make([][]byte, params.BeaconConfig().EpochsPerHistoricalVector), + } + + indices, err := unslashedAttestingIndices(state, atts) + if err != nil { + t.Fatal(err) + } + + for i := 0; i < len(indices)-1; i++ { + if indices[i] >= indices[i+1] { + t.Error("sorted indices not sorted or duplicated") + } + } +} + func TestAttestingBalance_CorrectBalance(t *testing.T) { helpers.ClearAllCaches()