Skip to content

Commit 7e39ee5

Browse files
committed
Add structured logs interface and script fees recording
Also updates CLB dep
1 parent beadd21 commit 7e39ee5

File tree

9 files changed

+139
-31
lines changed

9 files changed

+139
-31
lines changed

cabal.project

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@ tests: true
1919
source-repository-package
2020
type: git
2121
location: https://github.com/mlabs-haskell/clb
22-
tag: 925f80a9755d2292edf4589afb50dc1146b36ac2
22+
tag: d5b0e7ce07258482d53704ce19383013b1fa6610
2323
--sha256: 6+Os/mQDzBOU+TkTD+n/T1MFcI+Mn0/tcBMJhLRfqyA=
2424

25-
-- Cannot use new commit, because it requires `plutus-ledger-api==1.29`
25+
-- FIXME: Cannot use new commit, because it requires `plutus-ledger-api==1.29`
2626
source-repository-package
2727
type: git
2828
location: https://github.com/Plutonomicon/plutarch-plutus

src/Cardano/CEM/Monads.hs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,34 @@ data BlockchainParams = MkBlockchainParams
6060
}
6161
deriving stock (Show)
6262

63+
data Fees = MkFees
64+
{ fee :: Coin
65+
, usedMemory :: Natural
66+
, usedCpu :: Natural
67+
}
68+
deriving stock (Show)
69+
70+
data BlockchainMonadEvent
71+
= SubmittedTxSpec TxSpec (Either TxResolutionError TxId)
72+
| UserSpentFee
73+
{ txId :: TxId
74+
, txSigner :: SigningKey PaymentKey
75+
, fees :: Fees
76+
}
77+
| AwaitedTx TxId
78+
deriving stock (Show)
79+
6380
{- | This monad gives access to all information about Cardano params,
64-
| which is various kind of Ledger params and ValidityBound/Slots semantics
81+
which is various kind of Ledger params and ValidityBound/Slots semantics
82+
83+
Also contains common structured log support.
6584
-}
6685
class (MonadFail m) => MonadBlockchainParams m where
6786
askNetworkId :: m NetworkId
6887
queryCurrentSlot :: m SlotNo
6988
queryBlockchainParams :: m BlockchainParams
89+
logEvent :: BlockchainMonadEvent -> m ()
90+
eventList :: m [BlockchainMonadEvent]
7091

7192
-- MonadQuery
7293

src/Cardano/CEM/Monads/CLB.hs

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ module Cardano.CEM.Monads.CLB where
44

55
import Prelude
66

7+
import Control.Concurrent.MVar (MVar, modifyMVar_, newMVar, readMVar)
78
import Control.Monad.State (StateT (..), gets)
89
import Data.Map qualified as Map
910
import Data.Set qualified as Set
@@ -34,12 +35,23 @@ import Clb.TimeSlot (posixTimeToUTCTime)
3435
import Cardano.CEM.Monads
3536
import Cardano.CEM.Monads.L1Commons
3637
import Cardano.CEM.OffChain (fromPlutusAddressInMonad)
38+
import Control.Monad.Reader (MonadReader (..), ReaderT (..))
3739

38-
instance (MonadFail m) => MonadBlockchainParams (ClbT m) where
39-
askNetworkId :: ClbT m NetworkId
40+
instance (MonadReader r m) => MonadReader r (ClbT m) where
41+
ask = lift ask
42+
local f action = ClbT $ local f $ unwrapClbT action
43+
44+
type ClbRunner = ClbT (ReaderT (MVar [BlockchainMonadEvent]) IO)
45+
46+
instance
47+
( MonadFail m
48+
, MonadIO m
49+
, MonadReader (MVar [BlockchainMonadEvent]) m
50+
) =>
51+
MonadBlockchainParams (ClbT m)
52+
where
4053
askNetworkId = gets (mockConfigNetworkId . mockConfig)
4154

42-
queryCurrentSlot :: ClbT m SlotNo
4355
queryCurrentSlot = getCurrentSlot
4456

4557
queryBlockchainParams = do
@@ -56,8 +68,14 @@ instance (MonadFail m) => MonadBlockchainParams (ClbT m) where
5668
, -- Staking is not supported
5769
stakePools = Set.empty
5870
}
71+
logEvent e = do
72+
logVar <- ask
73+
liftIO $ modifyMVar_ logVar (return . (:) e)
74+
eventList = do
75+
events <- ask
76+
liftIO $ readMVar events
5977

60-
instance (MonadFail m) => MonadQueryUtxo (ClbT m) where
78+
instance (Monad m, MonadBlockchainParams (ClbT m)) => MonadQueryUtxo (ClbT m) where
6179
queryUtxo query = do
6280
utxos <- fromLedgerUTxO shelleyBasedEra <$> gets getUtxosAtState
6381
predicate <- mkPredicate
@@ -69,7 +87,7 @@ instance (MonadFail m) => MonadQueryUtxo (ClbT m) where
6987
return $ \_ (TxOut a _ _ _) -> a `elem` cardanoAddresses
7088
ByTxIns txIns -> return $ \txIn _ -> txIn `elem` txIns
7189

72-
instance (MonadFail m) => MonadSubmitTx (ClbT m) where
90+
instance (Monad m, MonadBlockchainParams (ClbT m)) => MonadSubmitTx (ClbT m) where
7391
submitResolvedTx :: ResolvedTx -> ClbT m (Either TxSubmittingError TxId)
7492
submitResolvedTx tx = do
7593
cardanoTxBodyFromResolvedTx tx >>= \case
@@ -82,16 +100,20 @@ instance (MonadFail m) => MonadSubmitTx (ClbT m) where
82100
Right (_, _) -> fail "Unsupported tx format"
83101
Left e -> return $ Left $ UnhandledAutobalanceError e
84102

85-
instance (MonadFail m) => MonadTest (ClbT m) where
103+
instance (Monad m, MonadBlockchainParams (ClbT m)) => MonadTest (ClbT m) where
86104
getTestWalletSks = return $ map intToCardanoSk [1 .. 10]
87105

88106
genesisClbState :: Value -> ClbState
89107
genesisClbState genesisValue =
90108
initClb defaultBabbage genesisValue genesisValue
91109

92-
execOnIsolatedClb :: Value -> ClbT IO a -> IO a
93-
execOnIsolatedClb genesisValue action =
110+
execOnIsolatedClb :: Value -> ClbRunner a -> IO a
111+
execOnIsolatedClb genesisValue action = do
112+
emptyLog <- newMVar []
94113
fst
95-
<$> runStateT
96-
(unwrapClbT action)
97-
(genesisClbState genesisValue)
114+
<$> runReaderT
115+
( runStateT
116+
(unwrapClbT action)
117+
(genesisClbState genesisValue)
118+
)
119+
emptyLog

src/Cardano/CEM/Monads/L1.hs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ instance MonadBlockchainParams L1Runner where
6363
<*> (toLedgerEpochInfo <$> queryCardanoNode QueryEraHistory)
6464
<*> queryCardanoNodeWrapping QueryStakePools
6565

66+
-- FIXME
67+
logEvent _ = return ()
68+
eventList = return []
69+
6670
queryCardanoNodeWrapping :: QueryInShelleyBasedEra Era b -> L1Runner b
6771
queryCardanoNodeWrapping query =
6872
handleEitherEra =<< queryCardanoNode wrapped

src/Cardano/CEM/Monads/L1Commons.hs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import Cardano.Api.Shelley (LedgerProtocolParameters (..))
1616
import Cardano.CEM.Monads
1717
import Cardano.CEM.OffChain
1818
import Cardano.Extras
19+
import Data.Maybe (mapMaybe)
1920

2021
-- Main function
2122

@@ -89,7 +90,43 @@ cardanoTxBodyFromResolvedTx (MkResolvedTx {..}) = do
8990
let
9091
tx = makeSignedTransactionWithKeys [signer] body
9192
txInMode = TxInMode ShelleyBasedEraBabbage tx
93+
94+
lift $ recordFee txInsUtxo body
95+
9296
return (body, txInMode)
97+
where
98+
recordFee txInsUtxo body@(TxBody content) = do
99+
case txFee content of
100+
TxFeeExplicit era coin -> do
101+
MkBlockchainParams {protocolParameters, systemStart, eraHistory} <-
102+
queryBlockchainParams
103+
Right report <-
104+
return $
105+
evaluateTransactionExecutionUnits
106+
(shelleyBasedToCardanoEra era)
107+
systemStart
108+
eraHistory
109+
(LedgerProtocolParameters protocolParameters)
110+
txInsUtxo
111+
body
112+
let
113+
rights = mapMaybe $ \case
114+
Right x -> Just x
115+
Left _ -> Nothing
116+
budgets = rights $ map snd $ Map.toList report
117+
usedMemory = sum $ executionMemory <$> budgets
118+
usedCpu = sum $ executionSteps <$> budgets
119+
logEvent $
120+
UserSpentFee
121+
{ fees =
122+
MkFees
123+
{ fee = coin
124+
, usedMemory
125+
, usedCpu
126+
}
127+
, txId = getTxId body
128+
, txSigner = signer
129+
}
93130

94131
-- Utils
95132

src/Cardano/CEM/OffChain.hs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ awaitTx txId = do
5656
exists <- checkTxIdExists txId
5757
liftIO $ threadDelay 1_000_000
5858
if exists
59-
then return ()
59+
then logEvent $ AwaitedTx txId
6060
else go $ n - 1
6161

6262
failLeft :: (MonadFail m, Show s) => Either s a -> m a
@@ -221,7 +221,10 @@ resolveTxAndSubmit ::
221221
(MonadQueryUtxo m, MonadSubmitTx m, MonadIO m) =>
222222
TxSpec ->
223223
m (Either TxResolutionError TxId)
224-
resolveTxAndSubmit spec = runExceptT $ do
225-
resolved <- ExceptT $ resolveTx spec
226-
let result = submitResolvedTx resolved
227-
ExceptT $ first UnhandledSubmittingError <$> result
224+
resolveTxAndSubmit spec = do
225+
result <- runExceptT $ do
226+
resolved <- ExceptT $ resolveTx spec
227+
let result = submitResolvedTx resolved
228+
ExceptT $ first UnhandledSubmittingError <$> result
229+
logEvent $ SubmittedTxSpec spec result
230+
return result

src/Cardano/CEM/Testing/StateMachine.hs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ import Text.Show.Pretty (ppShow)
4040

4141
import Cardano.CEM (CEMParams (..))
4242
import Cardano.CEM hiding (scriptParams)
43-
import Cardano.CEM.Monads (MonadSubmitTx (..), ResolvedTx (..))
44-
import Cardano.CEM.Monads.CLB (execOnIsolatedClb)
43+
import Cardano.CEM.Monads (CEMAction (..), MonadSubmitTx (..), ResolvedTx (..), SomeCEMAction (..), TxSpec (..))
44+
import Cardano.CEM.Monads.CLB (ClbRunner, execOnIsolatedClb)
4545
import Cardano.CEM.OffChain
4646
import Cardano.CEM.OnChain (CEMScriptCompiled)
4747
import Cardano.Extras (signingKeyToPKH)
@@ -329,14 +329,14 @@ instance
329329

330330
runActionsInClb ::
331331
forall state.
332-
(StateModel (ScriptState state), RunModel (ScriptState state) (ClbT IO)) =>
332+
(StateModel (ScriptState state), RunModel (ScriptState state) ClbRunner) =>
333333
Value ->
334334
Actions (ScriptState state) ->
335335
Property
336336
runActionsInClb genesisValue actions =
337337
monadic (ioProperty . execOnIsolatedClb genesisValue) $
338338
void $
339-
runActions @(ScriptState state) @(ClbT IO) actions
339+
runActions @(ScriptState state) @(ClbRunner) actions
340340

341341
-- Orphans
342342

test/Utils.hs

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ module Utils where
33
import Prelude
44

55
import Data.Map (keys)
6+
import Data.Map qualified as Map
7+
import Data.Maybe (mapMaybe)
68

79
import PlutusLedgerApi.V1.Interval (always)
810
import PlutusLedgerApi.V1.Value (assetClassValue)
@@ -17,28 +19,31 @@ import Cardano.Api.Shelley (
1719
import Test.Hspec (shouldSatisfy)
1820
import Text.Show.Pretty (ppShow)
1921

20-
import Clb (ClbT)
21-
2222
import Cardano.CEM.Monads (
23+
BlockchainMonadEvent (..),
24+
CEMAction (..),
25+
Fees (..),
26+
MonadBlockchainParams (..),
2327
MonadQueryUtxo (..),
2428
MonadSubmitTx (..),
2529
ResolvedTx (..),
30+
SomeCEMAction (..),
31+
TxSpec (..),
2632
UtxoQuery (..),
33+
submitResolvedTx,
2734
)
28-
import Cardano.CEM.Monads.CLB (execOnIsolatedClb)
35+
import Cardano.CEM.Monads.CLB (ClbRunner, execOnIsolatedClb)
2936
import Cardano.CEM.OffChain (
30-
CEMAction (..),
31-
SomeCEMAction (..),
32-
TxSpec (..),
3337
awaitTx,
3438
fromPlutusAddressInMonad,
3539
resolveTxAndSubmit,
3640
)
3741
import Cardano.Extras
42+
import Data.Spine (HasSpine (..))
3843

3944
import TestNFT
4045

41-
execClb :: ClbT IO a -> IO a
46+
execClb :: ClbRunner a -> IO a
4247
execClb = execOnIsolatedClb $ lovelaceToValue $ fromInteger 300_000_000
4348

4449
mintTestTokens ::
@@ -108,3 +113,19 @@ submitAndCheck spec = do
108113
MkSomeCEMAction (MkCEMAction _ transition) ->
109114
liftIO $ putStrLn $ "Doing " <> show transition
110115
awaitEitherTx =<< resolveTxAndSubmit spec
116+
117+
perTransitionStats :: (MonadBlockchainParams m) => m (Map.Map String Fees)
118+
perTransitionStats = do
119+
events <- eventList
120+
let feesByTxId = Map.fromList $ mapMaybe txIdFeePair events
121+
return $ Map.fromList $ mapMaybe (transitionFeePair feesByTxId) events
122+
where
123+
txIdFeePair (UserSpentFee {fees, txId}) = Just (txId, fees)
124+
txIdFeePair _ = Nothing
125+
transitionFeePair feesByTxId event = case event of
126+
( SubmittedTxSpec
127+
(MkTxSpec [MkSomeCEMAction (MkCEMAction _ transition)] _)
128+
(Right txId)
129+
) ->
130+
Just (show (getSpine transition), feesByTxId Map.! txId)
131+
_ -> Nothing

test/Voting.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import Test.Hspec (describe, shouldBe)
99
import Cardano.CEM
1010
import Cardano.CEM.Examples.Compilation ()
1111
import Cardano.CEM.Examples.Voting
12-
import Cardano.CEM.Monads (MonadTest (..))
12+
import Cardano.CEM.Monads
1313
import Cardano.CEM.OffChain
1414
import Cardano.CEM.Stages
1515
import Cardano.Extras (signingKeyToPKH)

0 commit comments

Comments
 (0)