mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-08 21:08:10 -05:00
Use time.Time instead of uint64 for genesis time (#15419)
* Convert genesis times from seconds to time.Time * Fixing failed forkchoice tests in a new commit so it doesn't get worse Fixing failed spectest tests in a new commit so it doesn't get worse Fixing forkchoice tests, then spectests * Fixing forkchoice tests, then spectests. Now asking for help... * Fix TestForkChoice_GetProposerHead * Fix broken build * Resolve TODO(preston) items * Changelog fragment * Resolve TODO(preston) items again * Resolve lint issues * Use consistant field names for sinceSlotStart (no spaces) * Manu's feedback * Renamed StartTime -> UnsafeStartTime, marked as deprecated because it doesn't handle overflow scenarios. Renamed SlotTime -> StartTime Renamed SlotAt -> At Handled the error in cases where StartTime was used. @james-prysm feedback * Revert beacon-chain/blockchain/receive_block_test.go from 1b7844de * Fixing issues after rebase * Accepted suggestions from @potuz * Remove CanonicalHeadSlot from merge conflicts --------- Co-authored-by: potuz <potuz@prysmaticlabs.com>
This commit is contained in:
@@ -153,10 +153,10 @@ func (s *SlotIntervalTicker) startWithIntervals(
|
||||
after func(time.Duration) <-chan time.Time,
|
||||
intervals []time.Duration) {
|
||||
go func() {
|
||||
slot := Since(genesisTime)
|
||||
slot := CurrentSlot(genesisTime)
|
||||
slot++
|
||||
interval := 0
|
||||
nextTickTime := startFromTime(genesisTime, slot).Add(intervals[0])
|
||||
nextTickTime := UnsafeStartTime(genesisTime, slot).Add(intervals[0])
|
||||
|
||||
for {
|
||||
waitTime := until(nextTickTime)
|
||||
@@ -168,7 +168,7 @@ func (s *SlotIntervalTicker) startWithIntervals(
|
||||
interval = 0
|
||||
slot++
|
||||
}
|
||||
nextTickTime = startFromTime(genesisTime, slot).Add(intervals[interval])
|
||||
nextTickTime = UnsafeStartTime(genesisTime, slot).Add(intervals[interval])
|
||||
case <-s.done:
|
||||
return
|
||||
}
|
||||
|
||||
@@ -18,32 +18,21 @@ import (
|
||||
// incoming objects. (24 mins with mainnet spec)
|
||||
const MaxSlotBuffer = uint64(1 << 7)
|
||||
|
||||
// startFromTime returns the slot start in terms of genesis time.Time
|
||||
func startFromTime(genesis time.Time, slot primitives.Slot) time.Time {
|
||||
duration := time.Second * time.Duration(slot.Mul(params.BeaconConfig().SecondsPerSlot))
|
||||
return genesis.Add(duration) // lint:ignore uintcast -- Genesis timestamp will not exceed int64 in your lifetime.
|
||||
}
|
||||
|
||||
// StartTime returns the start time in terms of its unix epoch
|
||||
// value.
|
||||
func StartTime(genesis uint64, slot primitives.Slot) time.Time {
|
||||
genesisTime := time.Unix(int64(genesis), 0) // lint:ignore uintcast -- Genesis timestamp will not exceed int64 in your lifetime.
|
||||
return startFromTime(genesisTime, slot)
|
||||
}
|
||||
|
||||
// SinceGenesis returns the number of slots since
|
||||
// the provided genesis time.
|
||||
func SinceGenesis(genesis time.Time) primitives.Slot {
|
||||
if genesis.After(prysmTime.Now()) { // Genesis has not occurred yet.
|
||||
return 0
|
||||
// UnsafeStartTime returns the start time in terms of its unix epoch
|
||||
// value. This method could panic if the product of slot duration * slot overflows uint64.
|
||||
// Deprecated: Use StartTime and handle the error.
|
||||
func UnsafeStartTime(genesis time.Time, slot primitives.Slot) time.Time {
|
||||
tm, err := StartTime(genesis, slot)
|
||||
if err != nil {
|
||||
panic(err) // lint:nopanic -- The panic risk is communicated in the godoc commentary.
|
||||
}
|
||||
return primitives.Slot(uint64(prysmTime.Since(genesis).Seconds()) / params.BeaconConfig().SecondsPerSlot)
|
||||
return tm
|
||||
}
|
||||
|
||||
// EpochsSinceGenesis returns the number of epochs since
|
||||
// the provided genesis time.
|
||||
func EpochsSinceGenesis(genesis time.Time) primitives.Epoch {
|
||||
return primitives.Epoch(SinceGenesis(genesis) / params.BeaconConfig().SlotsPerEpoch)
|
||||
return primitives.Epoch(CurrentSlot(genesis) / params.BeaconConfig().SlotsPerEpoch)
|
||||
}
|
||||
|
||||
// DivideSlotBy divides the SECONDS_PER_SLOT configuration
|
||||
@@ -162,15 +151,15 @@ func SinceEpochStarts(slot primitives.Slot) primitives.Slot {
|
||||
}
|
||||
|
||||
// VerifyTime validates the input slot is not from the future.
|
||||
func VerifyTime(genesisTime uint64, slot primitives.Slot, timeTolerance time.Duration) error {
|
||||
slotTime, err := ToTime(genesisTime, slot)
|
||||
func VerifyTime(genesis time.Time, slot primitives.Slot, timeTolerance time.Duration) error {
|
||||
slotTime, err := StartTime(genesis, slot)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Defensive check to ensure unreasonable slots are rejected
|
||||
// straight away.
|
||||
if err := ValidateClock(slot, genesisTime); err != nil {
|
||||
if err := ValidateClock(slot, genesis); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -183,38 +172,29 @@ func VerifyTime(genesisTime uint64, slot primitives.Slot, timeTolerance time.Dur
|
||||
return nil
|
||||
}
|
||||
|
||||
// ToTime takes the given slot and genesis time to determine the start time of the slot.
|
||||
func ToTime(genesisTimeSec uint64, slot primitives.Slot) (time.Time, error) {
|
||||
timeSinceGenesis, err := slot.SafeMul(params.BeaconConfig().SecondsPerSlot)
|
||||
// StartTime takes the given slot and genesis time to determine the start time of the slot.
|
||||
// This method returns an error if the product of the slot duration * slot overflows int64.
|
||||
func StartTime(genesis time.Time, slot primitives.Slot) (time.Time, error) {
|
||||
_, err := slot.SafeMul(params.BeaconConfig().SecondsPerSlot)
|
||||
if err != nil {
|
||||
return time.Unix(0, 0), fmt.Errorf("slot (%d) is in the far distant future: %w", slot, err)
|
||||
}
|
||||
sTime, err := timeSinceGenesis.SafeAdd(genesisTimeSec)
|
||||
if err != nil {
|
||||
return time.Unix(0, 0), fmt.Errorf("slot (%d) is in the far distant future: %w", slot, err)
|
||||
}
|
||||
return time.Unix(int64(sTime), 0), nil // lint:ignore uintcast -- A timestamp will not exceed int64 in your lifetime.
|
||||
}
|
||||
|
||||
// BeginsAt computes the timestamp where the given slot begins, relative to the genesis timestamp.
|
||||
func BeginsAt(slot primitives.Slot, genesis time.Time) time.Time {
|
||||
sd := time.Second * time.Duration(params.BeaconConfig().SecondsPerSlot) * time.Duration(slot)
|
||||
return genesis.Add(sd)
|
||||
}
|
||||
|
||||
// Since computes the number of time slots that have occurred since the given timestamp.
|
||||
func Since(time time.Time) primitives.Slot {
|
||||
return CurrentSlot(uint64(time.Unix()))
|
||||
return genesis.Add(sd), nil
|
||||
}
|
||||
|
||||
// CurrentSlot returns the current slot as determined by the local clock and
|
||||
// provided genesis time.
|
||||
func CurrentSlot(genesisTimeSec uint64) primitives.Slot {
|
||||
now := uint64(prysmTime.Now().Unix())
|
||||
if now < genesisTimeSec {
|
||||
func CurrentSlot(genesis time.Time) primitives.Slot {
|
||||
return At(genesis, time.Now())
|
||||
}
|
||||
|
||||
// At returns the slot at the given time.
|
||||
func At(genesis, tm time.Time) primitives.Slot {
|
||||
if tm.Before(genesis) {
|
||||
return 0
|
||||
}
|
||||
return primitives.Slot((now - genesisTimeSec) / params.BeaconConfig().SecondsPerSlot)
|
||||
return primitives.Slot(tm.Sub(genesis) / time.Second / time.Duration(params.BeaconConfig().SecondsPerSlot))
|
||||
}
|
||||
|
||||
// Duration computes the span of time between two instants, represented as Slots.
|
||||
@@ -228,8 +208,8 @@ func Duration(start, end time.Time) primitives.Slot {
|
||||
// ValidateClock validates a provided slot against the local
|
||||
// clock to ensure slots that are unreasonable are returned with
|
||||
// an error.
|
||||
func ValidateClock(slot primitives.Slot, genesisTimeSec uint64) error {
|
||||
maxPossibleSlot := CurrentSlot(genesisTimeSec).Add(MaxSlotBuffer)
|
||||
func ValidateClock(slot primitives.Slot, genesis time.Time) error {
|
||||
maxPossibleSlot := CurrentSlot(genesis).Add(MaxSlotBuffer)
|
||||
// Defensive check to ensure that we only process slots up to a hard limit
|
||||
// from our local clock.
|
||||
if slot > maxPossibleSlot {
|
||||
@@ -283,27 +263,22 @@ func SyncCommitteePeriodStartEpoch(e primitives.Epoch) (primitives.Epoch, error)
|
||||
return primitives.Epoch(startEpoch), nil
|
||||
}
|
||||
|
||||
// SecondsSinceSlotStart returns the number of seconds elapsed since the
|
||||
// given slot start time
|
||||
func SecondsSinceSlotStart(s primitives.Slot, genesisTime, timeStamp uint64) (uint64, error) {
|
||||
limit := genesisTime + uint64(s)*params.BeaconConfig().SecondsPerSlot
|
||||
if timeStamp < limit {
|
||||
return 0, fmt.Errorf("could not compute seconds since slot %d start: invalid timestamp, got %d < want %d", s, timeStamp, limit)
|
||||
// SinceSlotStart returns the amount of time elapsed since the
|
||||
// given slot start time. This method returns an error if the timestamp happens
|
||||
// before the given slot start time.
|
||||
func SinceSlotStart(s primitives.Slot, genesis time.Time, timestamp time.Time) (time.Duration, error) {
|
||||
limit := genesis.Add(time.Duration(uint64(s)*params.BeaconConfig().SecondsPerSlot) * time.Second)
|
||||
if timestamp.Before(limit) {
|
||||
return 0, fmt.Errorf("could not compute seconds since slot %d start: invalid timestamp, got %s < want %s", s, timestamp, limit)
|
||||
}
|
||||
return timeStamp - genesisTime - uint64(s)*params.BeaconConfig().SecondsPerSlot, nil
|
||||
}
|
||||
|
||||
// TimeIntoSlot returns the time duration elapsed between the current time and
|
||||
// the start of the current slot
|
||||
func TimeIntoSlot(genesisTime uint64) time.Duration {
|
||||
return time.Since(StartTime(genesisTime, CurrentSlot(genesisTime)))
|
||||
return timestamp.Sub(limit), nil
|
||||
}
|
||||
|
||||
// WithinVotingWindow returns whether the current time is within the voting window
|
||||
// (eg. 4 seconds on mainnet) of the current slot.
|
||||
func WithinVotingWindow(genesisTime uint64, slot primitives.Slot) bool {
|
||||
func WithinVotingWindow(genesis time.Time, slot primitives.Slot) bool {
|
||||
votingWindow := params.BeaconConfig().SecondsPerSlot / params.BeaconConfig().IntervalsPerSlot
|
||||
return time.Since(StartTime(genesisTime, slot)) < time.Duration(votingWindow)*time.Second
|
||||
return time.Since(UnsafeStartTime(genesis, slot)) < time.Duration(votingWindow)*time.Second
|
||||
}
|
||||
|
||||
// MaxSafeEpoch gives the largest epoch value that can be safely converted to a slot.
|
||||
@@ -312,13 +287,13 @@ func MaxSafeEpoch() primitives.Epoch {
|
||||
}
|
||||
|
||||
// SecondsUntilNextEpochStart returns how many seconds until the next Epoch start from the current time and slot
|
||||
func SecondsUntilNextEpochStart(genesisTimeSec uint64) (uint64, error) {
|
||||
currentSlot := CurrentSlot(genesisTimeSec)
|
||||
func SecondsUntilNextEpochStart(genesis time.Time) (uint64, error) {
|
||||
currentSlot := CurrentSlot(genesis)
|
||||
firstSlotOfNextEpoch, err := EpochStart(ToEpoch(currentSlot) + 1)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
nextEpochStartTime, err := ToTime(genesisTimeSec, firstSlotOfNextEpoch)
|
||||
nextEpochStartTime, err := StartTime(genesis, firstSlotOfNextEpoch)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
@@ -14,39 +14,6 @@ import (
|
||||
prysmTime "github.com/OffchainLabs/prysm/v6/time"
|
||||
)
|
||||
|
||||
func TestSlotsSinceGenesis(t *testing.T) {
|
||||
type args struct {
|
||||
genesis time.Time
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want primitives.Slot
|
||||
}{
|
||||
{
|
||||
name: "pre-genesis",
|
||||
args: args{
|
||||
genesis: prysmTime.Now().Add(1 * time.Hour), // 1 hour in the future
|
||||
},
|
||||
want: 0,
|
||||
},
|
||||
{
|
||||
name: "post-genesis",
|
||||
args: args{
|
||||
genesis: prysmTime.Now().Add(-5 * time.Duration(params.BeaconConfig().SecondsPerSlot) * time.Second),
|
||||
},
|
||||
want: 5,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := SinceGenesis(tt.args.genesis); got != tt.want {
|
||||
t.Errorf("SinceGenesis() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAbsoluteValueSlotDifference(t *testing.T) {
|
||||
type args struct {
|
||||
x primitives.Slot
|
||||
@@ -155,37 +122,6 @@ func TestEpochStartSlot_OK(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestBeginsAtOK(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
genesis int64
|
||||
slot primitives.Slot
|
||||
slotTime time.Time
|
||||
}{
|
||||
{
|
||||
name: "genesis",
|
||||
slotTime: time.Unix(0, 0),
|
||||
},
|
||||
{
|
||||
name: "slot 1",
|
||||
slot: 1,
|
||||
slotTime: time.Unix(int64(params.BeaconConfig().SecondsPerSlot), 0),
|
||||
},
|
||||
{
|
||||
name: "slot 1",
|
||||
slot: 32,
|
||||
slotTime: time.Unix(int64(params.BeaconConfig().SecondsPerSlot)*32, 0),
|
||||
},
|
||||
}
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
genesis := time.Unix(c.genesis, 0)
|
||||
st := BeginsAt(c.slot, genesis)
|
||||
require.Equal(t, c.slotTime, st)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestEpochEndSlot_OK(t *testing.T) {
|
||||
tests := []struct {
|
||||
epoch primitives.Epoch
|
||||
@@ -298,8 +234,8 @@ func TestRoundUpToNearestEpoch_OK(t *testing.T) {
|
||||
|
||||
func TestSlotToTime(t *testing.T) {
|
||||
type args struct {
|
||||
genesisTimeSec uint64
|
||||
slot primitives.Slot
|
||||
genesis time.Time
|
||||
slot primitives.Slot
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
@@ -310,39 +246,39 @@ func TestSlotToTime(t *testing.T) {
|
||||
{
|
||||
name: "slot_0",
|
||||
args: args{
|
||||
genesisTimeSec: 0,
|
||||
slot: 0,
|
||||
genesis: time.Unix(0, 0),
|
||||
slot: 0,
|
||||
},
|
||||
want: time.Unix(0, 0),
|
||||
},
|
||||
{
|
||||
name: "slot_1",
|
||||
args: args{
|
||||
genesisTimeSec: 0,
|
||||
slot: 1,
|
||||
genesis: time.Unix(0, 0),
|
||||
slot: 1,
|
||||
},
|
||||
want: time.Unix(int64(1*params.BeaconConfig().SecondsPerSlot), 0),
|
||||
},
|
||||
{
|
||||
name: "slot_12",
|
||||
args: args{
|
||||
genesisTimeSec: 500,
|
||||
slot: 12,
|
||||
genesis: time.Unix(500, 0),
|
||||
slot: 12,
|
||||
},
|
||||
want: time.Unix(500+int64(12*params.BeaconConfig().SecondsPerSlot), 0),
|
||||
},
|
||||
{
|
||||
name: "overflow",
|
||||
args: args{
|
||||
genesisTimeSec: 500,
|
||||
slot: math.MaxUint64,
|
||||
genesis: time.Unix(500, 0),
|
||||
slot: math.MaxUint64,
|
||||
},
|
||||
wantedErr: "is in the far distant future",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := ToTime(tt.args.genesisTimeSec, tt.args.slot)
|
||||
got, err := StartTime(tt.args.genesis, tt.args.slot)
|
||||
if tt.wantedErr != "" {
|
||||
assert.ErrorContains(t, tt.wantedErr, err)
|
||||
} else {
|
||||
@@ -355,7 +291,7 @@ func TestSlotToTime(t *testing.T) {
|
||||
|
||||
func TestVerifySlotTime(t *testing.T) {
|
||||
type args struct {
|
||||
genesisTime int64
|
||||
genesisTime time.Time
|
||||
slot primitives.Slot
|
||||
timeTolerance time.Duration
|
||||
}
|
||||
@@ -367,21 +303,22 @@ func TestVerifySlotTime(t *testing.T) {
|
||||
{
|
||||
name: "Past slot",
|
||||
args: args{
|
||||
genesisTime: prysmTime.Now().Add(-1 * 5 * time.Duration(params.BeaconConfig().SecondsPerSlot) * time.Second).Unix(),
|
||||
genesisTime: prysmTime.Now().Add(-1 * 5 * time.Duration(params.BeaconConfig().SecondsPerSlot) * time.Second),
|
||||
slot: 3,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "within tolerance",
|
||||
args: args{
|
||||
genesisTime: prysmTime.Now().Add(-1 * 5 * time.Duration(params.BeaconConfig().SecondsPerSlot) * time.Second).Add(20 * time.Millisecond).Unix(),
|
||||
slot: 5,
|
||||
genesisTime: prysmTime.Now().Add(-1 * 5 * time.Duration(params.BeaconConfig().SecondsPerSlot) * time.Second).Add(20 * time.Millisecond),
|
||||
slot: 5,
|
||||
timeTolerance: 20 * time.Millisecond,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "future slot",
|
||||
args: args{
|
||||
genesisTime: prysmTime.Now().Add(-1 * 5 * time.Duration(params.BeaconConfig().SecondsPerSlot) * time.Second).Unix(),
|
||||
genesisTime: prysmTime.Now().Add(-1 * 5 * time.Duration(params.BeaconConfig().SecondsPerSlot) * time.Second),
|
||||
slot: 6,
|
||||
},
|
||||
wantedErr: "could not process slot from the future",
|
||||
@@ -389,7 +326,7 @@ func TestVerifySlotTime(t *testing.T) {
|
||||
{
|
||||
name: "future slot but ok given 2s tolerance",
|
||||
args: args{
|
||||
genesisTime: prysmTime.Now().Add(-1*time.Duration(params.BeaconConfig().SecondsPerSlot) - 10*time.Second).Unix(),
|
||||
genesisTime: prysmTime.Now().Add(-1*time.Duration(params.BeaconConfig().SecondsPerSlot) - 10*time.Second),
|
||||
slot: 1,
|
||||
timeTolerance: 2 * time.Second,
|
||||
},
|
||||
@@ -397,7 +334,7 @@ func TestVerifySlotTime(t *testing.T) {
|
||||
{
|
||||
name: "max future slot",
|
||||
args: args{
|
||||
genesisTime: prysmTime.Now().Add(-1 * 5 * time.Duration(params.BeaconConfig().SecondsPerSlot) * time.Second).Unix(),
|
||||
genesisTime: prysmTime.Now().Add(-1 * 5 * time.Duration(params.BeaconConfig().SecondsPerSlot) * time.Second),
|
||||
slot: primitives.Slot(MaxSlotBuffer + 6),
|
||||
},
|
||||
wantedErr: "exceeds max allowed value relative to the local clock",
|
||||
@@ -405,7 +342,7 @@ func TestVerifySlotTime(t *testing.T) {
|
||||
{
|
||||
name: "evil future slot",
|
||||
args: args{
|
||||
genesisTime: prysmTime.Now().Add(-1 * 24 * time.Duration(params.BeaconConfig().SecondsPerSlot) * time.Second).Unix(), // 24 slots in the past
|
||||
genesisTime: prysmTime.Now().Add(-1 * 24 * time.Duration(params.BeaconConfig().SecondsPerSlot) * time.Second), // 24 slots in the past
|
||||
// Gets multiplied with slot duration, and results in an overflow. Wraps around to a valid time.
|
||||
// Lower than max signed int. And chosen specifically to wrap to a valid slot 24
|
||||
slot: primitives.Slot((^uint64(0))/params.BeaconConfig().SecondsPerSlot) + 24,
|
||||
@@ -415,7 +352,7 @@ func TestVerifySlotTime(t *testing.T) {
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
err := VerifyTime(uint64(tt.args.genesisTime), tt.args.slot, tt.args.timeTolerance)
|
||||
err := VerifyTime(tt.args.genesisTime, tt.args.slot, tt.args.timeTolerance)
|
||||
if tt.wantedErr != "" {
|
||||
assert.ErrorContains(t, tt.wantedErr, err)
|
||||
} else {
|
||||
@@ -426,12 +363,12 @@ func TestVerifySlotTime(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestValidateSlotClock_HandlesBadSlot(t *testing.T) {
|
||||
genTime := prysmTime.Now().Add(-1 * time.Duration(MaxSlotBuffer) * time.Duration(params.BeaconConfig().SecondsPerSlot) * time.Second).Unix()
|
||||
genTime := prysmTime.Now().Add(-1 * time.Duration(MaxSlotBuffer) * time.Duration(params.BeaconConfig().SecondsPerSlot) * time.Second)
|
||||
|
||||
assert.NoError(t, ValidateClock(primitives.Slot(MaxSlotBuffer), uint64(genTime)), "unexpected error validating slot")
|
||||
assert.NoError(t, ValidateClock(primitives.Slot(2*MaxSlotBuffer), uint64(genTime)), "unexpected error validating slot")
|
||||
assert.ErrorContains(t, "which exceeds max allowed value relative to the local clock", ValidateClock(primitives.Slot(2*MaxSlotBuffer+1), uint64(genTime)), "no error from bad slot")
|
||||
assert.ErrorContains(t, "which exceeds max allowed value relative to the local clock", ValidateClock(1<<63, uint64(genTime)), "no error from bad slot")
|
||||
assert.NoError(t, ValidateClock(primitives.Slot(MaxSlotBuffer), genTime), "unexpected error validating slot")
|
||||
assert.NoError(t, ValidateClock(primitives.Slot(2*MaxSlotBuffer), genTime), "unexpected error validating slot")
|
||||
assert.ErrorContains(t, "which exceeds max allowed value relative to the local clock", ValidateClock(primitives.Slot(2*MaxSlotBuffer+1), genTime), "no error from bad slot")
|
||||
assert.ErrorContains(t, "which exceeds max allowed value relative to the local clock", ValidateClock(1<<63, genTime), "no error from bad slot")
|
||||
}
|
||||
|
||||
func TestPrevSlot(t *testing.T) {
|
||||
@@ -502,24 +439,24 @@ func TestSyncCommitteePeriodStartEpoch(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestSecondsSinceSlotStart(t *testing.T) {
|
||||
func TestSinceSlotStart(t *testing.T) {
|
||||
now := time.Now()
|
||||
tests := []struct {
|
||||
slot primitives.Slot
|
||||
genesisTime uint64
|
||||
timeStamp uint64
|
||||
wanted uint64
|
||||
wantedErr bool
|
||||
slot primitives.Slot
|
||||
timeStamp time.Time
|
||||
wanted time.Duration
|
||||
wantedErr bool
|
||||
}{
|
||||
{},
|
||||
{slot: 1, timeStamp: 1, wantedErr: true},
|
||||
{slot: 1, timeStamp: params.BeaconConfig().SecondsPerSlot + 2, wanted: 2},
|
||||
{slot: 1, timeStamp: now.Add(-1 * time.Hour), wantedErr: true},
|
||||
{slot: 1, timeStamp: now.Add(2 * time.Second).Add(time.Duration(params.BeaconConfig().SecondsPerSlot) * time.Second), wanted: 2 * time.Second},
|
||||
}
|
||||
for _, test := range tests {
|
||||
w, err := SecondsSinceSlotStart(test.slot, test.genesisTime, test.timeStamp)
|
||||
for i, test := range tests {
|
||||
t.Logf("testing scenario %d", i)
|
||||
w, err := SinceSlotStart(test.slot, now, test.timeStamp)
|
||||
if err != nil {
|
||||
require.Equal(t, true, test.wantedErr)
|
||||
require.Equal(t, true, test.wantedErr, "wanted no error, but got %v", err)
|
||||
} else {
|
||||
require.Equal(t, false, test.wantedErr)
|
||||
require.Equal(t, false, test.wantedErr, "wanted an error, but got %v", err)
|
||||
require.Equal(t, w, test.wanted)
|
||||
}
|
||||
}
|
||||
@@ -597,42 +534,79 @@ func TestDuration(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestTimeIntoSlot(t *testing.T) {
|
||||
genesisTime := uint64(time.Now().Add(-37 * time.Second).Unix())
|
||||
require.Equal(t, true, TimeIntoSlot(genesisTime) > 900*time.Millisecond)
|
||||
require.Equal(t, true, TimeIntoSlot(genesisTime) < 3000*time.Millisecond)
|
||||
}
|
||||
|
||||
func TestWithinVotingWindow(t *testing.T) {
|
||||
genesisTime := uint64(time.Now().Add(-37 * time.Second).Unix())
|
||||
genesisTime := time.Now().Add(-37 * time.Second)
|
||||
require.Equal(t, true, WithinVotingWindow(genesisTime, 3))
|
||||
genesisTime = uint64(time.Now().Add(-40 * time.Second).Unix())
|
||||
genesisTime = time.Now().Add(-40 * time.Second)
|
||||
require.Equal(t, false, WithinVotingWindow(genesisTime, 3))
|
||||
}
|
||||
|
||||
func TestSecondsUntilNextEpochStart(t *testing.T) {
|
||||
secondsInEpoch := uint64(params.BeaconConfig().SlotsPerEpoch) * params.BeaconConfig().SecondsPerSlot
|
||||
// try slot 3
|
||||
genesisTime := uint64(time.Now().Add(-39 * time.Second).Unix())
|
||||
genesisTime := time.Now().Add(-39 * time.Second)
|
||||
waitTime, err := SecondsUntilNextEpochStart(genesisTime)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, secondsInEpoch-(params.BeaconConfig().SecondsPerSlot*3)-3, waitTime)
|
||||
// try slot 34
|
||||
genesisTime = uint64(time.Now().Add(time.Duration(-1*int(secondsInEpoch)-int(params.BeaconConfig().SecondsPerSlot*2)-5) * time.Second).Unix())
|
||||
genesisTime = time.Now().Add(time.Duration(-1*int(secondsInEpoch)-int(params.BeaconConfig().SecondsPerSlot*2)-5) * time.Second)
|
||||
waitTime, err = SecondsUntilNextEpochStart(genesisTime)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, secondsInEpoch-(params.BeaconConfig().SecondsPerSlot*2)-5, waitTime)
|
||||
|
||||
// check if waitTime is correctly EpochStart
|
||||
n := time.Now().Add(-39 * time.Second)
|
||||
genesisTime = uint64(n.Unix())
|
||||
genesisTime = n
|
||||
waitTime, err = SecondsUntilNextEpochStart(genesisTime)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, secondsInEpoch-39, waitTime)
|
||||
newGenesisTime := uint64(n.Add(time.Duration(-1*int(waitTime)) * time.Second).Unix())
|
||||
newGenesisTime := n.Add(time.Duration(-1*int(waitTime)) * time.Second)
|
||||
currentSlot := CurrentSlot(newGenesisTime)
|
||||
require.Equal(t, true, IsEpochStart(currentSlot))
|
||||
}
|
||||
|
||||
func TestCurrentSlot(t *testing.T) {
|
||||
type args struct {
|
||||
genesis time.Time
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want primitives.Slot
|
||||
}{
|
||||
{
|
||||
name: "pre-genesis",
|
||||
args: args{
|
||||
genesis: prysmTime.Now().Add(1 * time.Hour), // 1 hour in the future
|
||||
},
|
||||
want: 0,
|
||||
},
|
||||
{
|
||||
name: "post-genesis",
|
||||
args: args{
|
||||
genesis: prysmTime.Now().Add(-5 * time.Duration(params.BeaconConfig().SecondsPerSlot) * time.Second),
|
||||
},
|
||||
want: 5,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := CurrentSlot(tt.args.genesis); got != tt.want {
|
||||
t.Errorf("CurrentSlot() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
func TestCurrentSlot_iterative(t *testing.T) {
|
||||
for i := primitives.Slot(0); i < 1<<20; i++ {
|
||||
testCurrentSlot(t, i)
|
||||
}
|
||||
}
|
||||
|
||||
func testCurrentSlot(t testing.TB, slot primitives.Slot) {
|
||||
genesis := time.Now().Add(-1 * time.Duration(slot) * time.Duration(params.BeaconConfig().SecondsPerSlot) * time.Second)
|
||||
cs := CurrentSlot(genesis)
|
||||
require.Equal(t, slot, cs)
|
||||
}
|
||||
|
||||
func TestToForkVersion(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user