diff --git a/api_v3.go b/api_v3.go index 02146fba7..4d9335ff0 100644 --- a/api_v3.go +++ b/api_v3.go @@ -264,7 +264,7 @@ func (v *v3api) Decode(b []byte, obj interface{}, opts ...serix.Option) (int, er func V3API(protoParams ProtocolParameters) API { api := CommonSerixAPI() - timeProvider := NewTimeProvider(protoParams.GenesisUnixTimestamp(), int64(protoParams.SlotDurationInSeconds()), protoParams.SlotsPerEpochExponent()) + timeProvider := NewTimeProvider(0, protoParams.GenesisUnixTimestamp(), int64(protoParams.SlotDurationInSeconds()), protoParams.SlotsPerEpochExponent()) maxBlockWork, err := protoParams.WorkScoreParameters().MaxBlockWork() must(err) diff --git a/builder/output_builder_test.go b/builder/output_builder_test.go index efdea8d61..8dc43042c 100644 --- a/builder/output_builder_test.go +++ b/builder/output_builder_test.go @@ -19,7 +19,7 @@ func TestBasicOutputBuilder(t *testing.T) { nativeTokenFeature = tpkg.RandNativeTokenFeature() expirationTarget = tpkg.RandEd25519Address() metadata = []byte("123456") - slotTimeProvider = iotago.NewTimeProvider(time.Now().Unix(), 10, 10) + slotTimeProvider = iotago.NewTimeProvider(0, time.Now().Unix(), 10, 10) ) timelock := slotTimeProvider.SlotFromTime(time.Now().Add(5 * time.Minute)) expiration := slotTimeProvider.SlotFromTime(time.Now().Add(10 * time.Minute)) diff --git a/mana_decay_provider_test.go b/mana_decay_provider_test.go index 93afafe8a..16398ba35 100644 --- a/mana_decay_provider_test.go +++ b/mana_decay_provider_test.go @@ -39,7 +39,7 @@ func TestMain(m *testing.M) { testManaDecayFactors = tpkg.ManaDecayFactors(betaPerYear, 1<> t.slotsPerEpochExponent) + if slot <= t.genesisSlot { + return 0 + } + + return EpochIndex((slot - t.genesisSlot) >> t.slotsPerEpochExponent) } // EpochStart calculates the start slot of the given epoch. func (t *TimeProvider) EpochStart(epoch EpochIndex) SlotIndex { - return SlotIndex(epoch << t.slotsPerEpochExponent) + return t.genesisSlot + SlotIndex(epoch< 0 { + t.Run(fmt.Sprintf("Test Below Genesis %d", genesisSlot), func(t *testing.T) { + firstEpoch := iotago.EpochIndex(0) + belowGenesisTime := genesisTime.Add(-time.Nanosecond) + + require.EqualValues(t, genesisSlot, tp.SlotFromTime(belowGenesisTime)) + + require.EqualValues(t, belowGenesisTime, tp.SlotStartTime(genesisSlot-1)) + require.EqualValues(t, belowGenesisTime, tp.SlotStartTime(0)) + + require.EqualValues(t, belowGenesisTime, tp.SlotEndTime(genesisSlot-1)) + require.EqualValues(t, belowGenesisTime, tp.SlotEndTime(0)) + + require.EqualValues(t, firstEpoch, tp.EpochFromSlot(genesisSlot-1)) + require.EqualValues(t, firstEpoch, tp.EpochFromSlot(0)) + + require.EqualValues(t, 0, tp.SlotsBeforeNextEpoch(genesisSlot-1)) + require.EqualValues(t, 0, tp.SlotsBeforeNextEpoch(0)) + + require.EqualValues(t, 0, tp.SlotsSinceEpochStart(genesisSlot-1)) + require.EqualValues(t, 0, tp.SlotsSinceEpochStart(0)) + }) + } + + t.Run(fmt.Sprintf("Test SlotFromTime %d", genesisSlot), func(t *testing.T) { slot0StartTime := genesisTime.Add(-time.Nanosecond) - require.EqualValues(t, 0, tp.SlotFromTime(slot0StartTime)) + require.EqualValues(t, genesisSlot, tp.SlotFromTime(slot0StartTime)) slot1StartTime := genesisTime - require.EqualValues(t, 1, tp.SlotFromTime(slot1StartTime)) + require.EqualValues(t, genesisSlot+1, tp.SlotFromTime(slot1StartTime)) slot2StartTime := genesisTime.Add(time.Duration(slotDurationSeconds) * time.Second) - require.EqualValues(t, 2, tp.SlotFromTime(slot2StartTime)) + require.EqualValues(t, genesisSlot+2, tp.SlotFromTime(slot2StartTime)) arbitraryTime := genesisTime.Add(time.Duration(slotDurationSeconds*3)*time.Second + 5*time.Second + 300*time.Millisecond) - require.EqualValues(t, 4, tp.SlotFromTime(arbitraryTime)) + require.EqualValues(t, genesisSlot+4, tp.SlotFromTime(arbitraryTime)) }) - t.Run("Test SlotStartTime", func(t *testing.T) { + t.Run(fmt.Sprintf("Test SlotStartTime %d", genesisSlot), func(t *testing.T) { slot0StartTime := genesisTime.Add(-time.Nanosecond) - require.EqualValues(t, slot0StartTime, tp.SlotStartTime(0)) + require.EqualValues(t, slot0StartTime, tp.SlotStartTime(genesisSlot)) slot1StartTime := genesisTime - require.EqualValues(t, slot1StartTime, tp.SlotStartTime(1)) + require.EqualValues(t, slot1StartTime, tp.SlotStartTime(genesisSlot+1)) slot2StartTime := genesisTime.Add(time.Duration(slotDurationSeconds) * time.Second) - require.EqualValues(t, slot2StartTime, tp.SlotStartTime(2)) + require.EqualValues(t, slot2StartTime, tp.SlotStartTime(genesisSlot+2)) slot4000StartTime := genesisTime.Add(time.Duration(slotDurationSeconds*3999) * time.Second) - require.EqualValues(t, slot4000StartTime, tp.SlotStartTime(4000)) + require.EqualValues(t, slot4000StartTime, tp.SlotStartTime(genesisSlot+4000)) }) - t.Run("Test SlotEndTime", func(t *testing.T) { + t.Run(fmt.Sprintf("Test SlotEndTime %d", genesisSlot), func(t *testing.T) { slot0EndTime := genesisTime.Add(-time.Nanosecond) - require.EqualValues(t, slot0EndTime, tp.SlotEndTime(0)) + require.EqualValues(t, slot0EndTime, tp.SlotEndTime(genesisSlot)) slot1EndTime := genesisTime.Add(time.Duration(slotDurationSeconds) * time.Second).Add(-time.Nanosecond) - require.EqualValues(t, slot1EndTime, tp.SlotEndTime(1)) + require.EqualValues(t, slot1EndTime, tp.SlotEndTime(genesisSlot+1)) slot2EndTime := genesisTime.Add(time.Duration(slotDurationSeconds*2) * time.Second).Add(-time.Nanosecond) - require.EqualValues(t, slot2EndTime, tp.SlotEndTime(2)) + require.EqualValues(t, slot2EndTime, tp.SlotEndTime(genesisSlot+2)) slot4000EndTime := genesisTime.Add(time.Duration(slotDurationSeconds*4000) * time.Second).Add(-time.Nanosecond) - require.EqualValues(t, slot4000EndTime, tp.SlotEndTime(4000)) + require.EqualValues(t, slot4000EndTime, tp.SlotEndTime(genesisSlot+4000)) }) - t.Run("Test EpochFromSlot", func(t *testing.T) { - require.EqualValues(t, 0, tp.EpochFromSlot(0)) - require.EqualValues(t, 0, tp.EpochFromSlot(7)) - require.EqualValues(t, 1, tp.EpochFromSlot(8)) - require.EqualValues(t, 1, tp.EpochFromSlot(15)) - require.EqualValues(t, 4000, tp.EpochFromSlot(32000)) - require.EqualValues(t, 4000, tp.EpochFromSlot(32007)) + t.Run(fmt.Sprintf("Test EpochFromSlot %d", genesisSlot), func(t *testing.T) { + require.EqualValues(t, 0, tp.EpochFromSlot(genesisSlot)) + require.EqualValues(t, 0, tp.EpochFromSlot(genesisSlot+7)) + require.EqualValues(t, 1, tp.EpochFromSlot(genesisSlot+8)) + require.EqualValues(t, 1, tp.EpochFromSlot(genesisSlot+15)) + require.EqualValues(t, 4000, tp.EpochFromSlot(genesisSlot+32000)) + require.EqualValues(t, 4000, tp.EpochFromSlot(genesisSlot+32007)) }) - t.Run("Test EpochStart", func(t *testing.T) { - require.EqualValues(t, 0, tp.EpochStart(0)) - require.EqualValues(t, 8, tp.EpochStart(1)) - require.EqualValues(t, 16, tp.EpochStart(2)) - require.EqualValues(t, 32000, tp.EpochStart(4000)) + t.Run(fmt.Sprintf("Test EpochStart %d", genesisSlot), func(t *testing.T) { + require.EqualValues(t, genesisSlot, tp.EpochStart(0)) + require.EqualValues(t, genesisSlot+8, tp.EpochStart(1)) + require.EqualValues(t, genesisSlot+16, tp.EpochStart(2)) + require.EqualValues(t, genesisSlot+32000, tp.EpochStart(4000)) }) - t.Run("Test EpochEnd", func(t *testing.T) { - require.EqualValues(t, 7, tp.EpochEnd(0)) - require.EqualValues(t, 15, tp.EpochEnd(1)) - require.EqualValues(t, 23, tp.EpochEnd(2)) - require.EqualValues(t, 32007, tp.EpochEnd(4000)) + t.Run(fmt.Sprintf("Test EpochEnd %d", genesisSlot), func(t *testing.T) { + require.EqualValues(t, genesisSlot+7, tp.EpochEnd(0)) + require.EqualValues(t, genesisSlot+15, tp.EpochEnd(1)) + require.EqualValues(t, genesisSlot+23, tp.EpochEnd(2)) + require.EqualValues(t, genesisSlot+32007, tp.EpochEnd(4000)) }) - t.Run("Test SlotsBeforeNextEpoch", func(t *testing.T) { - require.EqualValues(t, 8, tp.SlotsBeforeNextEpoch(0)) - require.EqualValues(t, 1, tp.SlotsBeforeNextEpoch(7)) - require.EqualValues(t, 1, tp.SlotsBeforeNextEpoch(15)) - require.EqualValues(t, 8, tp.SlotsBeforeNextEpoch(32000)) - require.EqualValues(t, 1, tp.SlotsBeforeNextEpoch(32007)) + t.Run(fmt.Sprintf("Test SlotsBeforeNextEpoch %d", genesisSlot), func(t *testing.T) { + require.EqualValues(t, genesisSlot+8, tp.SlotsBeforeNextEpoch(genesisSlot)) + require.EqualValues(t, genesisSlot+1, tp.SlotsBeforeNextEpoch(genesisSlot+7)) + require.EqualValues(t, genesisSlot+1, tp.SlotsBeforeNextEpoch(genesisSlot+15)) + require.EqualValues(t, genesisSlot+8, tp.SlotsBeforeNextEpoch(genesisSlot+32000)) + require.EqualValues(t, genesisSlot+1, tp.SlotsBeforeNextEpoch(genesisSlot+32007)) }) - t.Run("Test SlotsSinceEpochStart", func(t *testing.T) { - require.EqualValues(t, 0, tp.SlotsSinceEpochStart(0)) - require.EqualValues(t, 7, tp.SlotsSinceEpochStart(7)) - require.EqualValues(t, 0, tp.SlotsSinceEpochStart(8)) - require.EqualValues(t, 7, tp.SlotsSinceEpochStart(15)) - require.EqualValues(t, 0, tp.SlotsSinceEpochStart(32000)) - require.EqualValues(t, 7, tp.SlotsSinceEpochStart(32007)) + t.Run(fmt.Sprintf("Test SlotsSinceEpochStart %d", genesisSlot), func(t *testing.T) { + require.EqualValues(t, genesisSlot, tp.SlotsSinceEpochStart(genesisSlot)) + require.EqualValues(t, genesisSlot+7, tp.SlotsSinceEpochStart(genesisSlot+7)) + require.EqualValues(t, genesisSlot, tp.SlotsSinceEpochStart(genesisSlot+8)) + require.EqualValues(t, genesisSlot+7, tp.SlotsSinceEpochStart(genesisSlot+15)) + require.EqualValues(t, genesisSlot+0, tp.SlotsSinceEpochStart(genesisSlot+32000)) + require.EqualValues(t, genesisSlot+7, tp.SlotsSinceEpochStart(genesisSlot+32007)) }) }