Skip to content

Commit

Permalink
Bounce attack tests (#3993)
Browse files Browse the repository at this point in the history
* New store values

* Update process block

* Update process attestation

* Update tests

* Helper

* Fixed blockchain package tests

* Slots since epoch starts tests

* Update justified checkpt tests

* Conflict

* Fixed logic

* Update process_block.go

* Use helper
  • Loading branch information
terencechain authored Nov 14, 2019
1 parent dee290c commit 8cfc3dc
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 1 deletion.
3 changes: 2 additions & 1 deletion beacon-chain/blockchain/forkchoice/process_block.go
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,8 @@ func (s *Store) currentSlot() uint64 {

// updates justified check point in store if a better check point is known
func (s *Store) updateJustifiedCheckpoint() {
if helpers.SlotsSinceEpochStarts(s.currentSlot()) == 0 {
// Update at epoch boundary slot only
if !helpers.IsEpochStart(s.currentSlot()) {
return
}
if s.bestJustifiedCheckpt.Epoch > s.justifiedCheckpt.Epoch {
Expand Down
114 changes: 114 additions & 0 deletions beacon-chain/blockchain/forkchoice/process_block_test.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package forkchoice

import (
"bytes"
"context"
"reflect"
"strings"
"testing"
"time"

"github.com/prysmaticlabs/go-bitfield"
"github.com/prysmaticlabs/go-ssz"
Expand Down Expand Up @@ -334,3 +336,115 @@ func TestRemoveStateSinceLastFinalized(t *testing.T) {
}
}
}

func TestShouldUpdateJustified_ReturnTrue(t *testing.T) {
ctx := context.Background()
db := testDB.SetupDB(t)
defer testDB.TeardownDB(t, db)
params.UseMinimalConfig()
defer params.UseMainnetConfig()

store := NewForkChoiceService(ctx, db)
store.genesisTime = uint64(time.Now().Unix())

update, err := store.shouldUpdateJustified(ctx, &ethpb.Checkpoint{})
if err != nil {
t.Fatal(err)
}
if !update {
t.Error("Should be able to update justified, received false")
}

lastJustifiedBlk := &ethpb.BeaconBlock{ParentRoot: []byte{'G'}}
lastJustifiedRoot, _ := ssz.SigningRoot(lastJustifiedBlk)
newJustifiedBlk := &ethpb.BeaconBlock{Slot: 1, ParentRoot: lastJustifiedRoot[:]}
newJustifiedRoot, _ := ssz.SigningRoot(newJustifiedBlk)
if err := store.db.SaveBlock(ctx, newJustifiedBlk); err != nil {
t.Fatal(err)
}
if err := store.db.SaveBlock(ctx, lastJustifiedBlk); err != nil {
t.Fatal(err)
}

diff := (params.BeaconConfig().SlotsPerEpoch - 1) * params.BeaconConfig().SecondsPerSlot
store.genesisTime = uint64(time.Now().Unix()) - diff
store.justifiedCheckpt = &ethpb.Checkpoint{Root: lastJustifiedRoot[:]}
update, err = store.shouldUpdateJustified(ctx, &ethpb.Checkpoint{Root: newJustifiedRoot[:]})
if err != nil {
t.Fatal(err)
}
if !update {
t.Error("Should be able to update justified, received false")
}
}

func TestShouldUpdateJustified_ReturnFalse(t *testing.T) {
ctx := context.Background()
db := testDB.SetupDB(t)
defer testDB.TeardownDB(t, db)
params.UseMinimalConfig()
defer params.UseMainnetConfig()

store := NewForkChoiceService(ctx, db)

lastJustifiedBlk := &ethpb.BeaconBlock{ParentRoot: []byte{'G'}}
lastJustifiedRoot, _ := ssz.SigningRoot(lastJustifiedBlk)
newJustifiedBlk := &ethpb.BeaconBlock{ParentRoot: lastJustifiedRoot[:]}
newJustifiedRoot, _ := ssz.SigningRoot(newJustifiedBlk)
if err := store.db.SaveBlock(ctx, newJustifiedBlk); err != nil {
t.Fatal(err)
}
if err := store.db.SaveBlock(ctx, lastJustifiedBlk); err != nil {
t.Fatal(err)
}

diff := (params.BeaconConfig().SlotsPerEpoch - 1) * params.BeaconConfig().SecondsPerSlot
store.genesisTime = uint64(time.Now().Unix()) - diff
store.justifiedCheckpt = &ethpb.Checkpoint{Root: lastJustifiedRoot[:]}

update, err := store.shouldUpdateJustified(ctx, &ethpb.Checkpoint{Root: newJustifiedRoot[:]})
if err != nil {
t.Fatal(err)
}
if update {
t.Error("Should not be able to update justified, received true")
}
}

func TestUpdateJustifiedCheckpoint_Update(t *testing.T) {
ctx := context.Background()
db := testDB.SetupDB(t)
defer testDB.TeardownDB(t, db)
params.UseMinimalConfig()
defer params.UseMainnetConfig()

store := NewForkChoiceService(ctx, db)
store.genesisTime = uint64(time.Now().Unix())

store.justifiedCheckpt = &ethpb.Checkpoint{Root: []byte{'A'}}
store.bestJustifiedCheckpt = &ethpb.Checkpoint{Epoch: 1, Root: []byte{'B'}}
store.updateJustifiedCheckpoint()

if !bytes.Equal(store.justifiedCheckpt.Root, []byte{'B'}) {
t.Error("Justified check point root did not update")
}
}

func TestUpdateJustifiedCheckpoint_NoUpdate(t *testing.T) {
ctx := context.Background()
db := testDB.SetupDB(t)
defer testDB.TeardownDB(t, db)
params.UseMinimalConfig()
defer params.UseMainnetConfig()

store := NewForkChoiceService(ctx, db)
store.genesisTime = uint64(time.Now().Unix()) - params.BeaconConfig().SecondsPerSlot

store.justifiedCheckpt = &ethpb.Checkpoint{Root: []byte{'A'}}
store.bestJustifiedCheckpt = &ethpb.Checkpoint{Epoch: 1, Root: []byte{'B'}}
store.updateJustifiedCheckpoint()

if bytes.Equal(store.justifiedCheckpt.Root, []byte{'B'}) {
t.Error("Justified check point root was not suppose to update")
}
}
18 changes: 18 additions & 0 deletions beacon-chain/core/helpers/slot_epoch_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,3 +156,21 @@ func TestIsEpochEnd(t *testing.T) {
}
}
}

func TestSlotsSinceEpochStarts(t *testing.T) {
tests := []struct {
slots uint64
wantedSlots uint64
}{
{slots: 0, wantedSlots: 0},
{slots: 1, wantedSlots: 1},
{slots: params.BeaconConfig().SlotsPerEpoch - 1, wantedSlots: params.BeaconConfig().SlotsPerEpoch - 1},
{slots: params.BeaconConfig().SlotsPerEpoch + 1, wantedSlots: 1},
{slots: 10*params.BeaconConfig().SlotsPerEpoch + 2, wantedSlots: 2},
}
for _, tt := range tests {
if got := SlotsSinceEpochStarts(tt.slots); got != tt.wantedSlots {
t.Errorf("SlotsSinceEpochStarts() = %v, want %v", got, tt.wantedSlots)
}
}
}

0 comments on commit 8cfc3dc

Please sign in to comment.