Skip to content

Commit

Permalink
SlotToTime helper (#5710)
Browse files Browse the repository at this point in the history
* SlotToTime helper
* gofmt
* gaz
* overflow
* Merge refs/heads/master into better-time
* Fix tests, move overflow
* Merge branch 'better-time' of github.com:prysmaticlabs/prysm into better-time
* smaller diff
  • Loading branch information
prestonvanloon authored May 1, 2020
1 parent 125d022 commit 37f2a04
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 8 deletions.
4 changes: 2 additions & 2 deletions beacon-chain/blockchain/process_block_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,10 @@ func TestStore_OnBlock(t *testing.T) {
wantErrString: "provided block root does not have block saved in the db",
},
{
name: "block is from the feature",
name: "block is from the future",
blk: &ethpb.BeaconBlock{ParentRoot: randomParentRoot[:], Slot: params.BeaconConfig().FarFutureEpoch},
s: st.Copy(),
wantErrString: "could not process slot from the future",
wantErrString: "far distant future",
},
{
name: "could not get finalized block",
Expand Down
1 change: 1 addition & 0 deletions beacon-chain/core/helpers/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ go_test(
"//shared/featureconfig:go_default_library",
"//shared/hashutil:go_default_library",
"//shared/params:go_default_library",
"//shared/roughtime:go_default_library",
"//shared/sliceutil:go_default_library",
"//shared/testutil:go_default_library",
"@com_github_google_gofuzz//:go_default_library",
Expand Down
25 changes: 19 additions & 6 deletions beacon-chain/core/helpers/slot_epoch.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package helpers

import (
"fmt"
"math"
"time"

stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
Expand Down Expand Up @@ -94,16 +95,28 @@ const TimeShiftTolerance = 500 * time.Millisecond // ms

// VerifySlotTime validates the input slot is not from the future.
func VerifySlotTime(genesisTime uint64, slot uint64, timeTolerance time.Duration) error {
// denominate everything in milliseconds
slotTime := 1000 * (genesisTime + slot*params.BeaconConfig().SecondsPerSlot)
currentTime := 1000 * uint64(roughtime.Now().Unix())
tolerance := uint64(timeTolerance.Milliseconds())
if slotTime > currentTime+tolerance {
return fmt.Errorf("could not process slot from the future, slot time(ms) %d > current time(ms) %d", slotTime, currentTime)
slotTime, err := SlotToTime(genesisTime, slot)
if err != nil {
return err
}
currentTime := roughtime.Now()
diff := slotTime.Sub(currentTime)

if diff > timeTolerance {
return fmt.Errorf("could not process slot from the future, slot time %s > current time %s", slotTime, currentTime)
}
return nil
}

// SlotToTime takes the given slot and genesis time to determine the start time of the slot.
func SlotToTime(genesisTimeSec uint64, slot uint64) (time.Time, error) {
if slot >= math.MaxInt64 {
return time.Unix(0, 0), fmt.Errorf("slot (%d) is in the far distant future", slot)
}
timeSinceGenesis := slot * params.BeaconConfig().SecondsPerSlot
return time.Unix(int64(genesisTimeSec+timeSinceGenesis), 0), nil
}

// SlotsSince computes the number of time slots that have occurred since the given timestamp.
func SlotsSince(time time.Time) uint64 {
return uint64(roughtime.Since(time).Seconds()) / params.BeaconConfig().SecondsPerSlot
Expand Down
105 changes: 105 additions & 0 deletions beacon-chain/core/helpers/slot_epoch_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package helpers

import (
"github.com/prysmaticlabs/prysm/shared/roughtime"
"math"
"reflect"
"testing"
"time"

beaconstate "github.com/prysmaticlabs/prysm/beacon-chain/state"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
Expand Down Expand Up @@ -200,3 +204,104 @@ func TestRoundUpToNearestEpoch_OK(t *testing.T) {
}
}
}

func TestSlotToTime(t *testing.T) {
type args struct {
genesisTimeSec uint64
slot uint64
}
tests := []struct {
name string
args args
want time.Time
wantErr bool
}{
{
name: "slot_0",
args: args{
genesisTimeSec: 0,
slot: 0,
},
want: time.Unix(0, 0),
wantErr: false,
},
{
name: "slot_1",
args: args{
genesisTimeSec: 0,
slot: 1,
},
want: time.Unix(int64(1*params.BeaconConfig().SecondsPerSlot), 0),
wantErr: false,
},
{
name: "slot_12",
args: args{
genesisTimeSec: 500,
slot: 12,
},
want: time.Unix(500+int64(12*params.BeaconConfig().SecondsPerSlot), 0),
wantErr: false,
},
{
name: "overflow",
args: args{
genesisTimeSec: 500,
slot: math.MaxUint64,
},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got, err := SlotToTime(tt.args.genesisTimeSec, tt.args.slot); (err != nil ) != tt.wantErr && !reflect.DeepEqual(got, tt.want) {
t.Errorf("SlotToTime() = %v, want %v", got, tt.want)
}
})
}
}

func TestVerifySlotTime(t *testing.T) {
type args struct {
genesisTime int64
slot uint64
timeTolerance time.Duration
}
tests := []struct {
name string
args args
wantErr bool
}{
{
name: "Past slot",
args: args{
genesisTime: roughtime.Now().Add(-1 * 5 * time.Duration(params.BeaconConfig().SecondsPerSlot) * time.Second).Unix(),
slot: 3,
},
wantErr: false,
},
{
name: "within tolerance",
args: args{
genesisTime: roughtime.Now().Add(-1 * 5 * time.Duration(params.BeaconConfig().SecondsPerSlot) * time.Second).Add(20 * time.Millisecond).Unix(),
slot: 5,
},
wantErr: false,
},
{
name: "future slot",
args: args{
genesisTime: roughtime.Now().Add(-1 * 5 * time.Duration(params.BeaconConfig().SecondsPerSlot) * time.Second).Unix(),
slot: 6,
},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := VerifySlotTime(uint64(tt.args.genesisTime), tt.args.slot, tt.args.timeTolerance); (err != nil) != tt.wantErr {
t.Errorf("VerifySlotTime() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}

0 comments on commit 37f2a04

Please sign in to comment.