55
66module Main (main ) where
77
8- import qualified Data.Aeson as JSON
9- import Cardano.Crypto.Init (cryptoInit )
10- import Cardano.Slotting.Slot (SlotNo (.. ))
8+ import Cardano.Crypto.Init (cryptoInit )
9+ import Cardano.Slotting.Slot (SlotNo (.. ))
1110import qualified Cardano.Tools.DBAnalyser.Block.Cardano as Cardano
1211import Cardano.Tools.DBAnalyser.HasAnalysis (mkProtocolInfo )
1312import qualified Cardano.Tools.ImmDBServer.Diffusion as ImmDBServer
14- import Data.Time.Clock (DiffTime )
13+ import qualified Data.Aeson as JSON
14+ import Data.Time.Clock (DiffTime )
1515import qualified Data.Time.Clock.POSIX as POSIX
16- import Data.Void (absurd )
17- import Main.Utf8 (withStdTerminalHandles )
18- import Network.Socket (AddrInfo (addrFlags , addrSocketType ))
16+ import Data.Void (absurd )
17+ import Main.Utf8 (withStdTerminalHandles )
18+ import Network.Socket (AddrInfo (addrFlags , addrSocketType ))
1919import qualified Network.Socket as Socket
20- import Options.Applicative (ParserInfo , execParser , fullDesc , help ,
21- helper , info , long , metavar , progDesc , showDefault ,
22- strOption , value , auto , option )
23- import Ouroboros.Consensus.Node.ProtocolInfo (ProtocolInfo (.. ))
24- import System.Exit (die )
20+ import Options.Applicative
21+ ( ParserInfo
22+ , auto
23+ , execParser
24+ , fullDesc
25+ , help
26+ , helper
27+ , info
28+ , long
29+ , metavar
30+ , option
31+ , progDesc
32+ , showDefault
33+ , strOption
34+ , value
35+ )
36+ import Ouroboros.Consensus.Node.ProtocolInfo (ProtocolInfo (.. ))
37+ import System.Exit (die )
2538import qualified System.IO as SIO
2639
2740main :: IO ()
2841main = withStdTerminalHandles $ do
29- SIO. hSetBuffering SIO. stdout SIO. LineBuffering
30- cryptoInit
31- Opts {immDBDir, port, address, configFile, refSlotNr, refTimeForRefSlot, leiosDbFile, leiosScheduleFile} <- execParser optsParser
32- let hints = Socket. defaultHints { addrFlags = [Socket. AI_NUMERICHOST ], addrSocketType = Socket. Stream }
33- addrInfo <- do
34- addrInfos <- Socket. getAddrInfo (Just hints) (Just address) (Just port)
35- case addrInfos of
36- [] -> error " Invalid address or port"
37- addrInfo: _ -> return addrInfo
42+ SIO. hSetBuffering SIO. stdout SIO. LineBuffering
43+ cryptoInit
44+ Opts
45+ { immDBDir
46+ , port
47+ , address
48+ , configFile
49+ , refSlotNr
50+ , refTimeForRefSlot
51+ , leiosDbFile
52+ , leiosScheduleFile
53+ } <-
54+ execParser optsParser
55+ let hints = Socket. defaultHints{addrFlags = [Socket. AI_NUMERICHOST ], addrSocketType = Socket. Stream }
56+ addrInfo <- do
57+ addrInfos <- Socket. getAddrInfo (Just hints) (Just address) (Just port)
58+ case addrInfos of
59+ [] -> error " Invalid address or port"
60+ addrInfo : _ -> return addrInfo
3861
39- let args = Cardano. CardanoBlockArgs configFile Nothing
40- ProtocolInfo {pInfoConfig} <- mkProtocolInfo args
62+ let args = Cardano. CardanoBlockArgs configFile Nothing
63+ ProtocolInfo {pInfoConfig} <- mkProtocolInfo args
4164
42- leiosSchedule <- JSON. eitherDecodeFileStrict leiosScheduleFile >>= \ case
43- Left err -> die $ " Failed to decode LeiosSchedule: " ++ err
44- Right x -> pure x
65+ leiosSchedule <-
66+ JSON. eitherDecodeFileStrict leiosScheduleFile >>= \ case
67+ Left err -> die $ " Failed to decode LeiosSchedule: " ++ err
68+ Right x -> pure x
4569
46- absurd <$> ImmDBServer. run immDBDir
47- (Socket. addrAddress addrInfo)
48- pInfoConfig
49- (mkGetSlotDelay refSlotNr refTimeForRefSlot)
50- leiosDbFile
51- (leiosSchedule :: ImmDBServer. LeiosSchedule )
52- where
53- -- NB we assume for now the slot duration is 1 second.
54- --
55- -- If we want to this in the actual chain we will need to access
56- -- the information from the configuration file to run the
57- -- Qry.slotToWallclock query.
58- mkGetSlotDelay :: SlotNo -> POSIX. POSIXTime -> Double -> IO DiffTime
59- mkGetSlotDelay refSlotNr refTimeForRefSlot =
60- -- If slot < refSlotNr, we need to subtract to
61- -- refTimeForRefSlot.
62- let slotToPosix :: Double -> POSIX. POSIXTime
63- slotToPosix = realToFrac -- TODO: here is where we assume the slot duration of 1 second.
64- in \ slotDbl -> do
65- let slotTime = refTimeForRefSlot + (slotToPosix slotDbl - slotToPosix (fromIntegral $ unSlotNo refSlotNr))
66- currentTime <- POSIX. getPOSIXTime
67- pure $ if currentTime < slotTime
68- then realToFrac $ slotTime - currentTime
69- else 0
70+ absurd
71+ <$> ImmDBServer. run
72+ immDBDir
73+ (Socket. addrAddress addrInfo)
74+ pInfoConfig
75+ (mkGetSlotDelay refSlotNr refTimeForRefSlot)
76+ leiosDbFile
77+ (leiosSchedule :: ImmDBServer. LeiosSchedule )
78+ where
79+ -- NB we assume for now the slot duration is 1 second.
80+ --
81+ -- If we want to this in the actual chain we will need to access
82+ -- the information from the configuration file to run the
83+ -- Qry.slotToWallclock query.
84+ mkGetSlotDelay :: SlotNo -> POSIX. POSIXTime -> Double -> IO DiffTime
85+ mkGetSlotDelay refSlotNr refTimeForRefSlot =
86+ -- If slot < refSlotNr, we need to subtract to
87+ -- refTimeForRefSlot.
88+ let slotToPosix :: Double -> POSIX. POSIXTime
89+ slotToPosix = realToFrac -- TODO: here is where we assume the slot duration of 1 second.
90+ in \ slotDbl -> do
91+ let slotTime = refTimeForRefSlot + (slotToPosix slotDbl - slotToPosix (fromIntegral $ unSlotNo refSlotNr))
92+ currentTime <- POSIX. getPOSIXTime
93+ pure $
94+ if currentTime < slotTime
95+ then realToFrac $ slotTime - currentTime
96+ else 0
7097
71- data Opts = Opts {
72- immDBDir :: FilePath
73- , port :: String
74- , address :: String
98+ data Opts = Opts
99+ { immDBDir :: FilePath
100+ , port :: String
101+ , address :: String
75102 , configFile :: FilePath
76103 , refSlotNr :: SlotNo
77104 -- ^ Reference slot number. This, in combination with the reference
78105 -- time will be used to convert between slot number and wallclock time.
79106 -- N.B.: for now we assume the slot duration to be 1 second.
80- , refTimeForRefSlot :: POSIX. POSIXTime
107+ , refTimeForRefSlot :: POSIX. POSIXTime
81108 -- ^ Reference slot onset. Wallclock time that corresponds to the
82109 -- reference slot.
83110 , leiosDbFile :: FilePath
@@ -92,47 +119,76 @@ optsParser =
92119 where
93120 desc = " Serve an ImmutableDB via ChainSync and BlockFetch"
94121
95- parse = do
96- immDBDir <- strOption $ mconcat
97- [ long " db"
98- , help " Path to the ImmutableDB"
99- , metavar " PATH"
100- ]
101- port <- strOption $ mconcat
102- [ long " port"
103- , help " Port to serve on"
104- , value " 3001"
105- , showDefault
106- ]
107- address <- strOption $ mconcat
108- [ long " address"
109- , help " Address to serve on"
110- , value " 127.0.0.1"
111- , showDefault
112- ]
113- configFile <- strOption $ mconcat
114- [ long " config"
115- , help " Path to config file, in the same format as for the node or db-analyser"
116- , metavar " PATH"
117- ]
118- refSlotNr <- fmap SlotNo $ option auto $ mconcat
119- [ long " initial-slot"
120- , help " Reference slot number (SlotNo). This, together with the initial-time will be used for time translations."
121- , metavar " SLOT_NO"
122- ]
123- refTimeForRefSlot <- fmap (fromInteger @ POSIX. POSIXTime ) $ option auto $ mconcat
124- [ long " initial-time"
125- , help " UTC time for the reference slot, provided as POSIX seconds (Unix timestamp)"
126- , metavar " POSIX_SECONDS"
127- ]
128- leiosDbFile <- strOption $ mconcat
129- [ long " leios-db"
130- , help " Path to the Leios database"
131- , metavar " PATH"
132- ]
133- leiosScheduleFile <- strOption $ mconcat
134- [ long " leios-schedule"
135- , help " Path to json file specifying when to send Leios offers"
136- , metavar " PATH"
137- ]
138- pure Opts {immDBDir, port, address, configFile, refSlotNr, refTimeForRefSlot, leiosDbFile, leiosScheduleFile}
122+ parse = do
123+ immDBDir <-
124+ strOption $
125+ mconcat
126+ [ long " db"
127+ , help " Path to the ImmutableDB"
128+ , metavar " PATH"
129+ ]
130+ port <-
131+ strOption $
132+ mconcat
133+ [ long " port"
134+ , help " Port to serve on"
135+ , value " 3001"
136+ , showDefault
137+ ]
138+ address <-
139+ strOption $
140+ mconcat
141+ [ long " address"
142+ , help " Address to serve on"
143+ , value " 127.0.0.1"
144+ , showDefault
145+ ]
146+ configFile <-
147+ strOption $
148+ mconcat
149+ [ long " config"
150+ , help " Path to config file, in the same format as for the node or db-analyser"
151+ , metavar " PATH"
152+ ]
153+ refSlotNr <-
154+ fmap SlotNo $
155+ option auto $
156+ mconcat
157+ [ long " initial-slot"
158+ , help
159+ " Reference slot number (SlotNo). This, together with the initial-time will be used for time translations."
160+ , metavar " SLOT_NO"
161+ ]
162+ refTimeForRefSlot <-
163+ fmap (fromInteger @ POSIX. POSIXTime ) $
164+ option auto $
165+ mconcat
166+ [ long " initial-time"
167+ , help " UTC time for the reference slot, provided as POSIX seconds (Unix timestamp)"
168+ , metavar " POSIX_SECONDS"
169+ ]
170+ leiosDbFile <-
171+ strOption $
172+ mconcat
173+ [ long " leios-db"
174+ , help " Path to the Leios database"
175+ , metavar " PATH"
176+ ]
177+ leiosScheduleFile <-
178+ strOption $
179+ mconcat
180+ [ long " leios-schedule"
181+ , help " Path to json file specifying when to send Leios offers"
182+ , metavar " PATH"
183+ ]
184+ pure
185+ Opts
186+ { immDBDir
187+ , port
188+ , address
189+ , configFile
190+ , refSlotNr
191+ , refTimeForRefSlot
192+ , leiosDbFile
193+ , leiosScheduleFile
194+ }
0 commit comments