diff --git a/README.md b/README.md index f0ace6c..29a042e 100644 --- a/README.md +++ b/README.md @@ -44,11 +44,15 @@ var epochStartTime = converters.epoch().beginningOfEpochToUTCTime(445); var utcTime = converters.slot().slotToTime(109090938L); var epochNo = converters.time().utcTimeToEpochNo(LocalDateTime.of(2023, 11, 22, 9, 48, 58)); var lastAlonzoAbsoluteSlot = converters.epoch().endingOfEpochToAbsoluteSlot(364); +var firstRealAbsoluteSlotBabbage = converters.era().firstRealSlot(EraType.Babbage); +var firstRealTimeBabbage = converters.era().firstRealEraTime(EraType.Babbage); System.out.println(epochStartTime); // LocalDateTime.of(2023, 10, 27, 21, 44, 51) System.out.println(utcTime); // LocalDateTime.of(2023, 11, 22, 12, 47, 9) System.out.println(epochNo); // 450 System.out.println(lastAlonzoAbsoluteSlot); // 72316799L +System.out.println(firstRealAbsoluteSlotBabbage); // 72316896L +System.out.println(firstRealTimeBabbage); // LocalDateTime.of(2022, 9, 22, 21, 46, 27) ``` ## Additional Docs diff --git a/src/main/java/org/cardanofoundation/conversions/CardanoConverters.java b/src/main/java/org/cardanofoundation/conversions/CardanoConverters.java index 89e2fc0..32aaf89 100644 --- a/src/main/java/org/cardanofoundation/conversions/CardanoConverters.java +++ b/src/main/java/org/cardanofoundation/conversions/CardanoConverters.java @@ -1,12 +1,14 @@ package org.cardanofoundation.conversions; import org.cardanofoundation.conversions.converters.EpochConversions; +import org.cardanofoundation.conversions.converters.EraConversions; import org.cardanofoundation.conversions.converters.SlotConversions; import org.cardanofoundation.conversions.converters.TimeConversions; public record CardanoConverters( - ConversionsConfig conversionsConfig, - GenesisConfig genesisConfig, - EpochConversions epoch, - SlotConversions slot, - TimeConversions time) {} + ConversionsConfig conversionsConfig, + GenesisConfig genesisConfig, + EpochConversions epoch, + SlotConversions slot, + TimeConversions time, + EraConversions era) {} diff --git a/src/main/java/org/cardanofoundation/conversions/ClasspathConversionsFactory.java b/src/main/java/org/cardanofoundation/conversions/ClasspathConversionsFactory.java index 097771c..fb64037 100644 --- a/src/main/java/org/cardanofoundation/conversions/ClasspathConversionsFactory.java +++ b/src/main/java/org/cardanofoundation/conversions/ClasspathConversionsFactory.java @@ -5,6 +5,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import org.cardanofoundation.conversions.converters.EpochConversions; +import org.cardanofoundation.conversions.converters.EraConversions; import org.cardanofoundation.conversions.converters.SlotConversions; import org.cardanofoundation.conversions.converters.TimeConversions; import org.cardanofoundation.conversions.domain.EraType; @@ -45,9 +46,16 @@ public static CardanoConverters createConverters( var slotConversions = new SlotConversions(genesisConfig); var epochConversions = new EpochConversions(genesisConfig, slotConversions); var timeConversions = new TimeConversions(genesisConfig, slotConversions); + var eraConversions = new EraConversions(genesisConfig, slotConversions); return new CardanoConverters( - conversionsConfig, genesisConfig, epochConversions, slotConversions, timeConversions); + conversionsConfig, + genesisConfig, + epochConversions, + slotConversions, + timeConversions, + eraConversions + ); } private static String getGenesisEraClasspathLink(EraType era, NetworkType networkType) { diff --git a/src/main/java/org/cardanofoundation/conversions/converters/EraConversions.java b/src/main/java/org/cardanofoundation/conversions/converters/EraConversions.java new file mode 100644 index 0000000..6208cf3 --- /dev/null +++ b/src/main/java/org/cardanofoundation/conversions/converters/EraConversions.java @@ -0,0 +1,53 @@ +package org.cardanofoundation.conversions.converters; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.cardanofoundation.conversions.ConversionRuntimeException; +import org.cardanofoundation.conversions.GenesisConfig; +import org.cardanofoundation.conversions.domain.EraHistoryItem; +import org.cardanofoundation.conversions.domain.EraType; + +import java.time.LocalDateTime; +import java.util.Optional; + +@Slf4j +@RequiredArgsConstructor +public class EraConversions { + + private final GenesisConfig genesisConfig; + private final SlotConversions slotConversions; + + public long firstRealSlot(EraType eraType) { + return getEraHistoryItem(eraType).firstRealSlotNo(); + } + + public long firstTheoreticalSlot(EraType eraType) { + return getEraHistoryItem(eraType).firstTheoreticalSlotNo(); + } + + public Optional lastTheoreticalSlot(EraType eraType) { + return getEraHistoryItem(eraType).lastTheoreticalSlotNo(); + } + + public Optional lastRealSlot(EraType eraType) { + return getEraHistoryItem(eraType).lastRealSlotNo(); + } + + public LocalDateTime firstRealEraTime(EraType eraType) { + var absoluteSlot = firstRealSlot(eraType); + + return slotConversions.slotToTime(absoluteSlot); + } + + public Optional lastRealEraTime(EraType eraType) { + return lastRealSlot(eraType) + .map(slotConversions::slotToTime); + } + + private EraHistoryItem getEraHistoryItem(EraType eraType) { + return genesisConfig.getEraHistory() + .findFirstByEra(eraType) + .orElseThrow(() -> new ConversionRuntimeException("Era details not found!, era: " + eraType)); + } + +} diff --git a/src/test/java/org/cardanofoundation/conversions/converters/EpochConversionsMainNetTest.java b/src/test/java/org/cardanofoundation/conversions/converters/EpochConversionsMainNetTest.java index ee5e838..8e904af 100644 --- a/src/test/java/org/cardanofoundation/conversions/converters/EpochConversionsMainNetTest.java +++ b/src/test/java/org/cardanofoundation/conversions/converters/EpochConversionsMainNetTest.java @@ -10,6 +10,7 @@ import lombok.extern.slf4j.Slf4j; import org.cardanofoundation.conversions.ClasspathConversionsFactory; import org.cardanofoundation.conversions.GenesisConfig; +import org.cardanofoundation.conversions.domain.EraType; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -34,7 +35,8 @@ public void testIntraByronFork() { assertThat(epochConversions.epochToAbsoluteSlot(176, START)).isEqualTo(slot); } - @Test + + @Test public void testConvertByronEpochToSlot() { assertThat(epochConversions.epochToAbsoluteSlot(207, START)).isEqualTo(4471200); assertThat(epochConversions.epochToAbsoluteSlot(207, END)).isEqualTo(4492799L); diff --git a/src/test/java/org/cardanofoundation/conversions/converters/EraConversionsMainNetTest.java b/src/test/java/org/cardanofoundation/conversions/converters/EraConversionsMainNetTest.java new file mode 100644 index 0000000..4595b7f --- /dev/null +++ b/src/test/java/org/cardanofoundation/conversions/converters/EraConversionsMainNetTest.java @@ -0,0 +1,81 @@ +package org.cardanofoundation.conversions.converters; + +import org.cardanofoundation.conversions.ClasspathConversionsFactory; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.time.LocalDateTime; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.cardanofoundation.conversions.domain.EraType.Babbage; +import static org.cardanofoundation.conversions.domain.EraType.Shelley; +import static org.cardanofoundation.conversions.domain.NetworkType.MAINNET; + +class EraConversionsMainNetTest { + private EraConversions eraConversions; + + @BeforeEach + public void setup() { + var converters = ClasspathConversionsFactory.createConverters(MAINNET); + eraConversions = converters.era(); + } + + @Test + void firstRealSlotShelley() { + var absoluteSlot = eraConversions.firstRealSlot(Shelley); + assertThat(absoluteSlot).isEqualTo(4492800L); + } + + @Test + void firstRealSlotBabbage() { + var absoluteSlot = eraConversions.firstRealSlot(Babbage); + assertThat(absoluteSlot).isEqualTo(72316896L); + } + + @Test + void firstTheoreticalSlotShelley() { + var absoluteSlot = eraConversions.firstTheoreticalSlot(Shelley); + assertThat(absoluteSlot).isEqualTo(4492800L); + } + + @Test + void firstTheoreticalSlotBabbage() { + var absoluteSlot = eraConversions.firstTheoreticalSlot(Babbage); + assertThat(absoluteSlot).isEqualTo(72316800L); + } + + @Test + void lastRealSlotBabbage() { + assertThat(eraConversions.lastRealEraTime(Babbage)).isEmpty(); + } + + @Test + void lastTheoreticalSlotShelley() { + var absoluteSlot = eraConversions.lastTheoreticalSlot(Shelley).orElseThrow(); + assertThat(absoluteSlot).isEqualTo(16588799L); + } + + @Test + void firstRealEraTimeShelley() { + var time = eraConversions.firstRealEraTime(Shelley); + assertThat(time).isEqualTo(LocalDateTime.of(2020, 7, 29, 21, 44, 51)); + } + + @Test + void lastRealEraTimeShelley() { + var time = eraConversions.lastRealEraTime(Shelley).orElseThrow(); + assertThat(time).isEqualTo(LocalDateTime.of(2020, 12, 16, 21, 43, 48)); + } + + @Test + void firstRealEraTimeBabbage() { + var time = eraConversions.firstRealEraTime(Babbage); + assertThat(time).isEqualTo(LocalDateTime.of(2022, 9, 22, 21, 46, 27)); + } + + @Test + void lastRealEraTimeBabbage() { + assertThat(eraConversions.lastRealEraTime(Babbage)).isEmpty(); + } + +} \ No newline at end of file diff --git a/src/test/java/org/cardanofoundation/conversions/converters/EraConversionsPreProdTest.java b/src/test/java/org/cardanofoundation/conversions/converters/EraConversionsPreProdTest.java new file mode 100644 index 0000000..4258241 --- /dev/null +++ b/src/test/java/org/cardanofoundation/conversions/converters/EraConversionsPreProdTest.java @@ -0,0 +1,35 @@ +package org.cardanofoundation.conversions.converters; + +import org.cardanofoundation.conversions.ClasspathConversionsFactory; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.time.LocalDateTime; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.cardanofoundation.conversions.domain.EraType.Shelley; +import static org.cardanofoundation.conversions.domain.NetworkType.MAINNET; +import static org.cardanofoundation.conversions.domain.NetworkType.PREPROD; + +class EraConversionsPreProdTest { + private EraConversions eraConversions; + + @BeforeEach + public void setup() { + var converters = ClasspathConversionsFactory.createConverters(PREPROD); + eraConversions = converters.era(); + } + + @Test + void firstTheoreticalSlot() { + var shelleySlot = eraConversions.firstTheoreticalSlot(Shelley); + assertThat(shelleySlot).isEqualTo(86400L); + } + + @Test + void lastTheoreticalSlot() { + var shelleySlot = eraConversions.lastTheoreticalSlot(Shelley).orElseThrow(); + assertThat(shelleySlot).isEqualTo(518399L); + } + +} \ No newline at end of file