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:
Preston Van Loon
2025-07-14 16:04:50 -05:00
committed by GitHub
parent 56e8881bc1
commit 499d27b6ae
143 changed files with 659 additions and 595 deletions

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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) {