Skip to content

Commit bfdf534

Browse files
authored
simulation: Restrict available Time API (#114)
1 parent 45d1111 commit bfdf534

File tree

5 files changed

+45
-64
lines changed

5 files changed

+45
-64
lines changed

.hlint.yaml

+3
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,11 @@
2828
- modules:
2929
# Ensure that MonadDelay is imported from TimeCompat
3030
- name:
31+
- "Data.Time.**"
3132
- "Control.Monad.Class.MonadTime"
3233
- "Control.Monad.Class.MonadTime.SI"
34+
- "Control.Monad.Class.MonadTimer"
35+
- "Control.Monad.Class.MonadTimer.SI"
3336
within: "TimeCompat"
3437
message: "Use TimeCompat instead"
3538
# Ensure that MonadSTM is imported from STMCompat

simulation/src/LeiosProtocol/Short/SimP2P.hs

+6-7
Original file line numberDiff line numberDiff line change
@@ -6,28 +6,27 @@
66

77
module LeiosProtocol.Short.SimP2P where
88

9+
import ChanMux (newConnectionBundleTCP)
10+
import ChanTCP
11+
import Control.Monad (forever)
12+
import Control.Monad.Class.MonadFork (MonadFork (forkIO))
913
import Control.Monad.IOSim as IOSim (IOSim, runSimTrace)
1014
import Control.Tracer as Tracer (
1115
Contravariant (contramap),
1216
Tracer,
1317
traceWith,
1418
)
1519
import Data.List (unfoldr)
16-
import qualified Data.Map.Strict as Map
17-
import System.Random (StdGen, split)
18-
19-
import ChanMux (newConnectionBundleTCP)
20-
import ChanTCP
21-
import Control.Monad (forever)
22-
import Control.Monad.Class.MonadFork (MonadFork (forkIO))
2320
import qualified Data.Map.Strict as M
21+
import qualified Data.Map.Strict as Map
2422
import LeiosProtocol.Common
2523
import LeiosProtocol.Short
2624
import LeiosProtocol.Short.Node
2725
import LeiosProtocol.Short.Sim
2826
import P2P (P2PTopography (..))
2927
import SimTCPLinks (labelDirToLabelLink, mkTcpConnProps, selectTimedEvents, simTracer)
3028
import SimTypes
29+
import System.Random (StdGen, split)
3130

3231
traceLeiosP2P ::
3332
StdGen ->

simulation/src/PraosProtocol/Common/ConcreteBlock.hs

-30
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,6 @@ module PraosProtocol.Common.ConcreteBlock (
3131
hashBody,
3232
IsBody,
3333

34-
-- * Converting slots to times
35-
convertSlotToTimeForTestsAssumingNoHardFork,
36-
3734
-- * Creating sample chains
3835
mkChain,
3936
mkChainSimple,
@@ -62,8 +59,6 @@ import Data.ByteString (ByteString)
6259
import Data.Function (fix)
6360
import Data.Hashable (Hashable (hash))
6461
import Data.String (IsString)
65-
import Data.Time.Calendar (fromGregorian)
66-
import Data.Time.Clock (UTCTime (..), addUTCTime, secondsToNominalDiffTime)
6762
import Data.Typeable (Typeable)
6863
import GHC.Generics (Generic)
6964
import NoThunks.Class (NoThunks)
@@ -373,28 +368,3 @@ instance Serialise BlockBody where
373368
encode (BlockBody b) = encodeBytes b
374369

375370
decode = BlockBody <$> decodeBytes
376-
377-
{-------------------------------------------------------------------------------
378-
Simple static time conversions, since no HardFork
379-
-------------------------------------------------------------------------------}
380-
381-
-- | Arbitrarily but consistently converts slots UTCTimes.
382-
--
383-
-- It is only intended for use in tests. Notably it assumes a fixed system
384-
-- start time, slot length, and the absence of a hard fork (ie no
385-
-- HardForkCombinator). This is how it's available as a pure function.
386-
convertSlotToTimeForTestsAssumingNoHardFork :: SlotNo -> UTCTime
387-
convertSlotToTimeForTestsAssumingNoHardFork sl =
388-
flip addUTCTime startTime $
389-
-- ^^^ arbitrary start time for testing
390-
secondsToNominalDiffTime $
391-
fromIntegral $
392-
unSlotNo sl * 10
393-
where
394-
-- ^^^ arbitrary slot length for testing
395-
396-
startTime =
397-
UTCTime
398-
{ utctDay = fromGregorian 2000 1 1
399-
, utctDayTime = 0
400-
}

simulation/src/TimeCompat.hs

+34-24
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,41 @@
1-
{-# LANGUAGE DerivingStrategies #-}
2-
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
3-
{-# LANGUAGE NumericUnderscores #-}
4-
51
module TimeCompat (
6-
-- Legacy interfact
7-
module Control.Monad.Class.MonadTime.SI,
8-
threadDelayNDT,
2+
DiffTime,
3+
MonadTime (getCurrentTime),
4+
MonadDelay (threadDelay),
5+
MonadMonotonicTime (getMonotonicTime),
6+
Time (Time),
7+
UTCTime,
8+
NominalDiffTime,
9+
diffTimeToSeconds,
10+
addTime,
11+
addUTCTime,
12+
diffTime,
13+
diffUTCTime,
914
threadDelaySI,
10-
MonadDelay,
11-
-- Int-as-Micros API
12-
Microseconds (..),
13-
threadDelayMS,
14-
) where
15+
threadDelayNDT,
16+
)
17+
where
1518

16-
import Control.Monad.Class.MonadTime.SI
17-
import Control.Monad.Class.MonadTimer (MonadDelay (..))
19+
import Control.Monad.Class.MonadTime.SI (
20+
DiffTime,
21+
MonadMonotonicTime (getMonotonicTime),
22+
MonadTime (getCurrentTime),
23+
NominalDiffTime,
24+
Time (..),
25+
UTCTime,
26+
addTime,
27+
addUTCTime,
28+
diffTime,
29+
diffUTCTime,
30+
)
31+
import Control.Monad.Class.MonadTimer (MonadDelay (threadDelay))
32+
import Data.Time.Clock (diffTimeToPicoseconds)
1833

19-
newtype Microseconds = Microseconds {getMicroseconds :: Int}
20-
deriving newtype (Eq, Ord, Show, Enum, Num, Real, Integral)
34+
diffTimeToSeconds :: DiffTime -> Double
35+
diffTimeToSeconds = (* 1e-12) . fromIntegral . diffTimeToPicoseconds
2136

22-
threadDelayMS :: MonadDelay m => Microseconds -> m ()
23-
threadDelayMS micros = threadDelay (getMicroseconds micros)
37+
threadDelaySI :: MonadDelay m => DiffTime -> m ()
38+
threadDelaySI = threadDelay . round . (* 1e6)
2439

25-
-- | Suspends the current thread for a given amount of time.
2640
threadDelayNDT :: MonadDelay m => NominalDiffTime -> m ()
27-
threadDelayNDT = threadDelay . round . (1_000_000 *)
28-
29-
-- | Suspends the current thread for a given amount of time.
30-
threadDelaySI :: MonadDelay m => DiffTime -> m ()
31-
threadDelaySI = threadDelay . round . (1_000_000 *)
41+
threadDelayNDT = threadDelay . round . (* 1e6)

simulation/src/Viz.hs

+2-3
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,14 @@ import Data.Functor.Contravariant (Contravariant (contramap))
1414
import Data.IORef (newIORef, readIORef, writeIORef)
1515
import Data.List (foldl1', mapAccumL, zip4)
1616
import Data.Ratio ((%))
17-
import qualified Data.Time as Time
1817
import Data.Tree as Tree (Tree (..))
1918
import qualified Graphics.Rendering.Cairo as Cairo
2019
import qualified Graphics.Rendering.Pango.Cairo as Pango
2120
import qualified Graphics.Rendering.Pango.Font as Pango
2221
import qualified Graphics.Rendering.Pango.Layout as Pango
2322
import Graphics.UI.Gtk (AttrOp ((:=)))
2423
import qualified Graphics.UI.Gtk as Gtk
24+
import Text.Printf (printf)
2525
import TimeCompat
2626

2727
------------------------------------------------------------------------------
@@ -710,8 +710,7 @@ layoutLabelTime =
710710
Cairo.moveTo 5 20
711711
Cairo.setFontSize 20
712712
Cairo.setSourceRGB 0 0 0
713-
Cairo.showText $
714-
Time.formatTime Time.defaultTimeLocale "Time (sec): %-2Es" t
713+
Cairo.showText (printf "Time (sec): %.4fs" (diffTimeToSeconds t) :: String)
715714

716715
layoutLabel :: Int -> String -> Layout (VizRender model)
717716
layoutLabel size label =

0 commit comments

Comments
 (0)