Skip to content

Commit 0908ade

Browse files
authored
Merge pull request #105 from mlabs-haskell/misha/issue-100-time-conversions
Misha/issue 100 time conversions
2 parents 5c4cb93 + 7cff2e9 commit 0908ade

File tree

12 files changed

+330
-33
lines changed

12 files changed

+330
-33
lines changed

README.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,6 @@ main = do
8484
, pcPort = 9080
8585
, pcProtocolParams = protocolParams
8686
, pcTipPollingInterval = 10_000_000
87-
, -- | Slot configuration of the network, the default value can be used for the mainnet
88-
pcSlotConfig = def
8987
, pcOwnPubKeyHash = "0f45aaf1b2959db6e5ff94dbb1f823bf257680c3c723ac2d49f97546"
9088
, pcOwnStakePubKeyHash = Nothing
9189
, -- Directory name of the script and data files

bot-plutus-interface.cabal

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ library
8787
BotPlutusInterface.Helpers
8888
BotPlutusInterface.QueryNode
8989
BotPlutusInterface.Server
90+
BotPlutusInterface.TimeSlot
9091
BotPlutusInterface.Types
9192
BotPlutusInterface.UtxoParser
9293

@@ -97,6 +98,7 @@ library
9798
, cardano-api
9899
, cardano-crypto
99100
, cardano-ledger-alonzo
101+
, cardano-ledger-core
100102
, cardano-prelude
101103
, cardano-slotting
102104
, containers
@@ -113,6 +115,7 @@ library
113115
, lens
114116
, memory
115117
, mtl
118+
, ouroboros-consensus
116119
, playground-common
117120
, plutus-chain-index
118121
, plutus-chain-index-core
@@ -136,6 +139,7 @@ library
136139
, split
137140
, stm
138141
, text ^>=1.2.4.0
142+
, time
139143
, transformers
140144
, transformers-either
141145
, transformers-except

examples/plutus-game/app/Main.hs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import Cardano.PlutusExample.Game (
2222
import Data.Aeson qualified as JSON
2323
import Data.Aeson.TH (defaultOptions, deriveJSON)
2424
import Data.ByteString.Lazy qualified as LazyByteString
25-
import Data.Default (def)
2625
import Data.Maybe (fromMaybe)
2726
import Playground.Types (FunctionSchema)
2827
import Schema (FormSchema)
@@ -59,7 +58,6 @@ main = do
5958
, pcPort = 9080
6059
, pcProtocolParams = protocolParams
6160
, pcTipPollingInterval = 10_000_000
62-
, pcSlotConfig = def
6361
, pcOwnPubKeyHash = "0f45aaf1b2959db6e5ff94dbb1f823bf257680c3c723ac2d49f97546"
6462
, pcOwnStakePubKeyHash = Nothing
6563
, pcScriptFileDir = "./scripts"

examples/plutus-nft/app/Main.hs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import Cardano.PlutusExample.NFT
1717
import Data.Aeson qualified as JSON
1818
import Data.Aeson.TH (defaultOptions, deriveJSON)
1919
import Data.ByteString.Lazy qualified as LazyByteString
20-
import Data.Default (def)
2120
import Data.Maybe (fromMaybe)
2221
import Playground.Types (FunctionSchema)
2322
import Schema (FormSchema)
@@ -55,7 +54,6 @@ main = do
5554
, pcPort = 9080
5655
, pcProtocolParams = protocolParams
5756
, pcTipPollingInterval = 10_000_000
58-
, pcSlotConfig = def
5957
, pcOwnPubKeyHash = "0f45aaf1b2959db6e5ff94dbb1f823bf257680c3c723ac2d49f97546"
6058
, pcOwnStakePubKeyHash = Nothing
6159
, pcScriptFileDir = "./scripts"

examples/plutus-transfer/app/Main.hs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import Cardano.PlutusExample.Transfer (
2121
import Data.Aeson qualified as JSON
2222
import Data.Aeson.TH (defaultOptions, deriveJSON)
2323
import Data.ByteString.Lazy qualified as LazyByteString
24-
import Data.Default (def)
2524
import Data.Maybe (fromMaybe)
2625
import Playground.Types (FunctionSchema)
2726
import Schema (FormSchema)
@@ -58,7 +57,6 @@ main = do
5857
, pcPort = 9080
5958
, pcProtocolParams = protocolParams
6059
, pcTipPollingInterval = 10_000_000
61-
, pcSlotConfig = def
6260
, pcOwnPubKeyHash = "0f45aaf1b2959db6e5ff94dbb1f823bf257680c3c723ac2d49f97546"
6361
, pcOwnStakePubKeyHash = Nothing
6462
, pcScriptFileDir = "./scripts"

src/BotPlutusInterface/Balance.hs

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,12 @@ module BotPlutusInterface.Balance (
88
) where
99

1010
import BotPlutusInterface.CardanoCLI qualified as CardanoCLI
11-
import BotPlutusInterface.Effects (PABEffect, createDirectoryIfMissingCLI, printBpiLog)
11+
import BotPlutusInterface.Effects (
12+
PABEffect,
13+
createDirectoryIfMissingCLI,
14+
posixTimeRangeToContainedSlotRange,
15+
printBpiLog,
16+
)
1217
import BotPlutusInterface.Files (DummyPrivKey, unDummyPrivateKey)
1318
import BotPlutusInterface.Files qualified as Files
1419
import BotPlutusInterface.Types (LogLevel (Debug), PABConfig)
@@ -43,7 +48,6 @@ import Ledger.Interval (
4348
)
4449
import Ledger.Scripts (Datum, DatumHash)
4550
import Ledger.Time (POSIXTimeRange)
46-
import Ledger.TimeSlot (posixTimeRangeToContainedSlotRange)
4751
import Ledger.Tx (
4852
Tx (..),
4953
TxIn (..),
@@ -61,6 +65,7 @@ import Plutus.V1.Ledger.Api (
6165
)
6266

6367
import BotPlutusInterface.BodyBuilder qualified as BodyBuilder
68+
import Data.Bifunctor (bimap)
6469
import Prettyprinter (pretty, viaShow, (<+>))
6570
import Prelude
6671

@@ -81,10 +86,10 @@ balanceTxIO pabConf ownPkh unbalancedTx =
8186
privKeys <- newEitherT $ Files.readPrivateKeys @w pabConf
8287
let utxoIndex = fmap Tx.toTxOut utxos <> unBalancedTxUtxoIndex unbalancedTx
8388
requiredSigs = map Ledger.unPaymentPubKeyHash $ Map.keys (unBalancedTxRequiredSignatories unbalancedTx)
89+
8490
tx <-
85-
hoistEither $
86-
addValidRange
87-
pabConf
91+
newEitherT $
92+
addValidRange @w
8893
(unBalancedTxValidityTimeRange unbalancedTx)
8994
(unBalancedTxTx unbalancedTx)
9095

@@ -361,11 +366,20 @@ addSignatories ownPkh privKeys pkhs tx =
361366
tx
362367
(ownPkh : pkhs)
363368

364-
addValidRange :: PABConfig -> POSIXTimeRange -> Tx -> Either Text Tx
365-
addValidRange pabConf timeRange tx =
369+
addValidRange ::
370+
forall (w :: Type) (effs :: [Type -> Type]).
371+
Member (PABEffect w) effs =>
372+
POSIXTimeRange ->
373+
Tx ->
374+
Eff effs (Either Text Tx)
375+
addValidRange timeRange tx =
366376
if validateRange timeRange
367-
then Right $ tx {txValidRange = posixTimeRangeToContainedSlotRange pabConf.pcSlotConfig timeRange}
368-
else Left "Invalid validity interval."
377+
then
378+
bimap (Text.pack . show) (setRange tx)
379+
<$> posixTimeRangeToContainedSlotRange @w timeRange
380+
else pure $ Left "Invalid validity interval."
381+
where
382+
setRange tx' range = tx' {txValidRange = range}
369383

370384
validateRange :: forall (a :: Type). Ord a => Interval a -> Bool
371385
validateRange (Interval (LowerBound PosInf _) _) = False

src/BotPlutusInterface/Contract.hs

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,13 @@ import BotPlutusInterface.Effects (
1616
handleContractLog,
1717
handlePABEffect,
1818
logToContract,
19+
posixTimeRangeToContainedSlotRange,
20+
posixTimeToSlot,
1921
printBpiLog,
2022
queryChainIndex,
2123
readFileTextEnvelope,
2224
saveBudget,
25+
slotToPOSIXTime,
2326
threadDelay,
2427
uploadDir,
2528
)
@@ -55,7 +58,6 @@ import Ledger qualified
5558
import Ledger.Address (PaymentPubKeyHash (PaymentPubKeyHash))
5659
import Ledger.Constraints.OffChain (UnbalancedTx (..))
5760
import Ledger.Slot (Slot (Slot))
58-
import Ledger.TimeSlot (posixTimeRangeToContainedSlotRange, posixTimeToEnclosingSlot, slotToEndPOSIXTime)
5961
import Ledger.Tx (CardanoTx)
6062
import Ledger.Tx qualified as Tx
6163
import Plutus.ChainIndex.TxIdState (fromTx, transactionStatus)
@@ -184,10 +186,8 @@ handlePABReq contractEnv req = do
184186
CurrentSlotReq -> CurrentSlotResp <$> currentSlot @w contractEnv
185187
CurrentTimeReq -> CurrentTimeResp <$> currentTime @w contractEnv
186188
PosixTimeRangeToContainedSlotRangeReq posixTimeRange ->
187-
pure $
188-
PosixTimeRangeToContainedSlotRangeResp $
189-
Right $
190-
posixTimeRangeToContainedSlotRange contractEnv.cePABConfig.pcSlotConfig posixTimeRange
189+
either (error . show) (PosixTimeRangeToContainedSlotRangeResp . Right)
190+
<$> posixTimeRangeToContainedSlotRange @w posixTimeRange
191191
AwaitTxStatusChangeReq txId -> AwaitTxStatusChangeResp txId <$> awaitTxStatusChange @w contractEnv txId
192192
------------------------
193193
-- Unhandled requests --
@@ -384,10 +384,12 @@ awaitTime ::
384384
ContractEnvironment w ->
385385
POSIXTime ->
386386
Eff effs POSIXTime
387-
awaitTime ce = fmap fromSlot . awaitSlot ce . toSlot
387+
awaitTime ce pTime = do
388+
slotFromTime <- rightOrErr <$> posixTimeToSlot @w pTime
389+
slot' <- awaitSlot ce slotFromTime
390+
rightOrErr <$> slotToPOSIXTime @w slot'
388391
where
389-
toSlot = posixTimeToEnclosingSlot ce.cePABConfig.pcSlotConfig
390-
fromSlot = slotToEndPOSIXTime ce.cePABConfig.pcSlotConfig
392+
rightOrErr = either (error . show) id
391393

392394
currentSlot ::
393395
forall (w :: Type) (effs :: [Type -> Type]).
@@ -411,4 +413,6 @@ currentTime ::
411413
ContractEnvironment w ->
412414
Eff effs POSIXTime
413415
currentTime contractEnv =
414-
slotToEndPOSIXTime contractEnv.cePABConfig.pcSlotConfig <$> currentSlot @w contractEnv
416+
currentSlot @w contractEnv
417+
>>= slotToPOSIXTime @w
418+
>>= either (error . show) return

src/BotPlutusInterface/Effects.hs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,14 @@ module BotPlutusInterface.Effects (
2424
callCommand,
2525
estimateBudget,
2626
saveBudget,
27+
slotToPOSIXTime,
28+
posixTimeToSlot,
29+
posixTimeRangeToContainedSlotRange,
2730
) where
2831

2932
import BotPlutusInterface.ChainIndex (handleChainIndexReq)
3033
import BotPlutusInterface.ExBudget qualified as ExBudget
34+
import BotPlutusInterface.TimeSlot qualified as TimeSlot
3135
import BotPlutusInterface.Types (
3236
BudgetEstimationError,
3337
CLILocation (..),
@@ -106,6 +110,13 @@ data PABEffect (w :: Type) (r :: Type) where
106110
QueryChainIndex :: ChainIndexQuery -> PABEffect w ChainIndexResponse
107111
EstimateBudget :: TxFile -> PABEffect w (Either BudgetEstimationError TxBudget)
108112
SaveBudget :: Ledger.TxId -> TxBudget -> PABEffect w ()
113+
SlotToPOSIXTime ::
114+
Ledger.Slot ->
115+
PABEffect w (Either TimeSlot.TimeSlotConversionError Ledger.POSIXTime)
116+
POSIXTimeToSlot :: Ledger.POSIXTime -> PABEffect w (Either TimeSlot.TimeSlotConversionError Ledger.Slot)
117+
POSIXTimeRangeToSlotRange ::
118+
Ledger.POSIXTimeRange ->
119+
PABEffect w (Either TimeSlot.TimeSlotConversionError Ledger.SlotRange)
109120

110121
handlePABEffect ::
111122
forall (w :: Type) (effs :: [Type -> Type]).
@@ -155,6 +166,12 @@ handlePABEffect contractEnv =
155166
EstimateBudget txPath ->
156167
ExBudget.estimateBudget contractEnv.cePABConfig txPath
157168
SaveBudget txId exBudget -> saveBudgetImpl contractEnv txId exBudget
169+
SlotToPOSIXTime slot ->
170+
TimeSlot.slotToPOSIXTimeIO contractEnv.cePABConfig slot
171+
POSIXTimeToSlot pTime ->
172+
TimeSlot.posixTimeToSlotIO contractEnv.cePABConfig pTime
173+
POSIXTimeRangeToSlotRange pTimeRange ->
174+
TimeSlot.posixTimeRangeToContainedSlotRangeIO contractEnv.cePABConfig pTimeRange
158175
)
159176

160177
printLog' :: LogLevel -> LogContext -> LogLevel -> PP.Doc () -> IO ()
@@ -345,3 +362,24 @@ saveBudget ::
345362
TxBudget ->
346363
Eff effs ()
347364
saveBudget txId budget = send @(PABEffect w) $ SaveBudget txId budget
365+
366+
slotToPOSIXTime ::
367+
forall (w :: Type) (effs :: [Type -> Type]).
368+
Member (PABEffect w) effs =>
369+
Ledger.Slot ->
370+
Eff effs (Either TimeSlot.TimeSlotConversionError Ledger.POSIXTime)
371+
slotToPOSIXTime = send @(PABEffect w) . SlotToPOSIXTime
372+
373+
posixTimeToSlot ::
374+
forall (w :: Type) (effs :: [Type -> Type]).
375+
Member (PABEffect w) effs =>
376+
Ledger.POSIXTime ->
377+
Eff effs (Either TimeSlot.TimeSlotConversionError Ledger.Slot)
378+
posixTimeToSlot = send @(PABEffect w) . POSIXTimeToSlot
379+
380+
posixTimeRangeToContainedSlotRange ::
381+
forall (w :: Type) (effs :: [Type -> Type]).
382+
Member (PABEffect w) effs =>
383+
Ledger.POSIXTimeRange ->
384+
Eff effs (Either TimeSlot.TimeSlotConversionError Ledger.SlotRange)
385+
posixTimeRangeToContainedSlotRange = send @(PABEffect w) . POSIXTimeRangeToSlotRange

src/BotPlutusInterface/ExBudget.hs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@ import Prelude
3030
minting to `MintingPolicyHash`'es
3131
-}
3232
estimateBudget :: PABConfig -> TxFile -> IO (Either BudgetEstimationError TxBudget)
33-
estimateBudget bapConf txFile = do
33+
estimateBudget pabConf txFile = do
3434
sock <- getEnv "CARDANO_NODE_SOCKET_PATH"
35-
let debugNodeInf = NodeInfo (pcNetwork bapConf) sock
35+
let debugNodeInf = NodeInfo (pcNetwork pabConf) sock
3636
txBody <- case txFile of
3737
Raw rp -> deserialiseRaw rp
3838
Signed sp -> fmap CAPI.getTxBody <$> deserialiseSigned sp
@@ -151,7 +151,7 @@ mkBudgetMaps exUnitsMap txBody = do
151151
CAPI.TxMintValue _ value _ ->
152152
{- The minting policies are indexed in policy id order in the value
153153
reference:
154-
https://github.com/input-output-hk/cardano-node/blob/e31455eaeca98530ce561b79687a8e465ebb3fdd/cardano-api/src/Cardano/Api/TxBody.hs#L2851
154+
https://github.com/input-output-hk/cardano-node/blob/e31455eaeca98530ce561b79687a8e465ebb3fdd/cardano-api/src/Cardano/Api/TxBody.hs#L2881
155155
-}
156156
let CAPI.ValueNestedRep bundle = CAPI.valueToNestedRep value
157157
in Map.fromList

0 commit comments

Comments
 (0)