Skip to content

Commit 5c059ef

Browse files
committed
Handle need for separate UTxO query with cardano-node 10.4
1 parent d8d3d08 commit 5c059ef

File tree

4 files changed

+55
-26
lines changed

4 files changed

+55
-26
lines changed

libs/ledger-state/README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,15 @@ $ cardano-node run \
5151
--port 3001 &
5252
```
5353

54-
Dump the ledger state:
54+
Dump the ledger state and utxo:
5555

5656
```shell
5757
$ cardano-cli query ledger-state --mainnet \
5858
--socket-path "${CARDANO_NODE_SOCKET_PATH}" \
5959
--out-file "${CARDANO_DATA}/new-epoch-state.bin"
60+
$ cardano-cli query utxo --mainnet --whole-utxo --output-cbor \
61+
--socket-path "${CARDANO_NODE_SOCKET_PATH}" \
62+
--out-file "${CARDANO_DATA}/utxo.hex"
6063
```
6164

6265
Bring the node back into the foreground and use Ctrl-C to stop it:
@@ -103,6 +106,7 @@ menu, therefore paths to those files must be supplied as environment variables.
103106
```shell
104107
$ export BENCH_GENESIS_PATH=${CARDANO_DATA}/shelley-genesis.json
105108
$ export BENCH_LEDGER_STATE_PATH=${CARDANO_DATA}/new-epoch-state.bin
109+
$ export BENCH_UTXO_PATH=${CARDANO_DATA}/utxo.hex
106110
$ cabal bench ledger-state:performance --benchmark-option=--csv=ledger-state:performance.csv
107111
```
108112

libs/ledger-state/bench/Performance.hs

Lines changed: 32 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import Cardano.Ledger.Shelley.Genesis (
2121
)
2222
import Cardano.Ledger.Shelley.LedgerState
2323
import Cardano.Ledger.State
24-
import Cardano.Ledger.State.UTxO (CurrentEra, readNewEpochState)
24+
import Cardano.Ledger.State.UTxO (CurrentEra, readHexUTxO, readNewEpochState)
2525
import Cardano.Ledger.UMap
2626
import Cardano.Ledger.Val
2727
import Cardano.Slotting.EpochInfo (fixedEpochInfo)
@@ -40,7 +40,7 @@ import Data.MapExtras (extractKeys, extractKeysSmallSet)
4040
import Data.Set (Set)
4141
import qualified Data.Set as Set
4242
import GHC.Stack (HasCallStack)
43-
import Lens.Micro ((^.))
43+
import Lens.Micro ((&), (.~), (^.))
4444
import System.Environment (getEnv)
4545
import System.Exit (die)
4646
import System.Random.Stateful
@@ -49,11 +49,27 @@ import Test.Cardano.Ledger.Core.Arbitrary (uniformSubSet)
4949

5050
main :: IO ()
5151
main = do
52-
let ledgerVarName = "BENCH_LEDGER_STATE_PATH"
53-
genesisVarName = "BENCH_GENESIS_PATH"
54-
ledgerStateFilePath <- getEnv ledgerVarName
52+
let genesisVarName = "BENCH_GENESIS_PATH"
53+
utxoVarName = "BENCH_UTXO_PATH"
54+
ledgerStateVarName = "BENCH_LEDGER_STATE_PATH"
5555
genesisFilePath <- getEnv genesisVarName
56+
utxoFilePath <- getEnv utxoVarName
57+
ledgerStateFilePath <- getEnv ledgerStateVarName
58+
5659
genesis <- either error id <$> eitherDecodeFileStrict' genesisFilePath
60+
putStrLn $ "Importing UTxO from: " ++ show utxoFilePath
61+
utxo <- readHexUTxO utxoFilePath
62+
putStrLn "Done importing UTxO"
63+
putStrLn $ "Importing NewEpochState from: " ++ show ledgerStateFilePath
64+
es' <- readNewEpochState ledgerStateFilePath
65+
putStrLn "Done importing NewEpochState"
66+
67+
let nesUTxOL = nesEsL . esLStateL . lsUTxOStateL . utxoL
68+
es = es' & nesUTxOL .~ utxo
69+
utxoMap = unUTxO utxo
70+
utxoSize = Map.size utxoMap
71+
largeKeysNum = 100000
72+
stdGen = mkStdGen 2022
5773

5874
let toMempoolState :: NewEpochState CurrentEra -> MempoolState CurrentEra
5975
toMempoolState NewEpochState {nesEs = EpochState {esLState}} = esLState
@@ -62,20 +78,15 @@ main = do
6278
applyTx' mempoolEnv mempoolState =
6379
either (error . show) seqTuple
6480
. applyTx globals mempoolEnv mempoolState
65-
reapplyTx' mempoolEnv mempoolState tx =
66-
case reapplyTx globals mempoolEnv mempoolState tx of
67-
Left err -> error (show err)
68-
Right st -> st
69-
putStrLn $ "Importing NewEpochState from: " ++ show ledgerStateFilePath
70-
es <- readNewEpochState ledgerStateFilePath
71-
putStrLn "Done importing NewEpochState"
72-
let utxoMap = unUTxO $ getUTxO es
73-
utxoSize = Map.size utxoMap
74-
largeKeysNum = 100000
75-
stdGen = mkStdGen 2022
81+
reapplyTx' mempoolEnv mempoolState =
82+
either (error . show) id
83+
. reapplyTx globals mempoolEnv mempoolState
84+
7685
when (utxoSize < largeKeysNum) $
77-
die $ "UTxO size is too small (" <> show utxoSize <> " < " <> show largeKeysNum <> ")"
86+
die $
87+
"UTxO size is too small (" <> show utxoSize <> " < " <> show largeKeysNum <> ")"
7888
largeKeys <- selectRandomMapKeys 100000 stdGen utxoMap
89+
7990
defaultMain
8091
[ env (pure (mkMempoolEnv es slotNo, toMempoolState es)) $ \ ~(mempoolEnv, mempoolState) ->
8192
bgroup
@@ -103,15 +114,15 @@ main = do
103114
(pure [validatedTx1, validatedTx2, validatedTx3])
104115
$ bench "Tx1+Tx2+Tx3" . whnf (F.foldl' (\ms -> fst . applyTx' mempoolEnv ms . extractTx) mempoolState)
105116
]
106-
, env (pure (getUTxO es)) $ \utxo ->
117+
, env (pure utxo) $ \utxo' ->
107118
bgroup
108119
"UTxO"
109-
[ bench "balance" $ nf balance utxo
110-
, bench "coinBalance" $ nf coinBalance utxo
120+
[ bench "balance" $ nf balance utxo'
121+
, bench "coinBalance" $ nf coinBalance utxo'
111122
, -- We need to filter out all multi-assets to prevent `areAllAdaOnly`
112123
-- from short circuiting and producing results that are way better
113124
-- than the worst case
114-
env (pure $ Map.filter (\txOut -> isAdaOnly (txOut ^. valueTxOutL)) $ unUTxO utxo) $
125+
env (pure $ Map.filter (\txOut -> isAdaOnly (txOut ^. valueTxOutL)) $ unUTxO utxo') $
115126
bench "areAllAdaOnly" . nf areAllAdaOnly
116127
]
117128
, env (pure es) $ \newEpochState ->

libs/ledger-state/ledger-state.cabal

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ library
3636

3737
build-depends:
3838
base >=4.14 && <5,
39+
base16-bytestring,
3940
bytestring,
4041
cardano-crypto-class,
4142
cardano-ledger-alonzo,

libs/ledger-state/src/Cardano/Ledger/State/UTxO.hs

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,16 @@ import qualified Cardano.Ledger.UMap as UM (ptrMap)
3232
import Conduit
3333
import Control.Exception (throwIO)
3434
import Control.Foldl (Fold (..))
35+
import Control.Monad ((<=<))
3536
import Control.SetAlgebra (range)
37+
import Data.Bifunctor (first)
38+
import qualified Data.ByteString.Base16.Lazy as Base16
3639
import qualified Data.ByteString.Lazy as LBS
3740
import Data.Foldable as F
3841
import qualified Data.IntMap.Strict as IntMap
3942
import qualified Data.Map.Strict as Map
4043
import qualified Data.Set as Set
44+
import qualified Data.Text as T
4145
import Data.Typeable
4246
import qualified Data.VMap as VMap
4347
import Lens.Micro
@@ -57,11 +61,20 @@ readEpochState ::
5761
IO (EpochState CurrentEra)
5862
readEpochState = readDecCBOR
5963

64+
readHexUTxO ::
65+
FilePath ->
66+
IO (UTxO CurrentEra)
67+
readHexUTxO = readDecCBORHex
68+
6069
readDecCBOR :: FromCBOR a => FilePath -> IO a
61-
readDecCBOR fp =
62-
LBS.readFile fp <&> Plain.decodeFull >>= \case
63-
Left exc -> throwIO exc
64-
Right res -> pure res
70+
readDecCBOR = either throwIO pure . Plain.decodeFull <=< LBS.readFile
71+
72+
readDecCBORHex :: FromCBOR a => FilePath -> IO a
73+
readDecCBORHex = either throwIO pure . decodeFullHex <=< LBS.readFile
74+
where
75+
decodeFullHex =
76+
Plain.decodeFull
77+
<=< first (DecoderErrorCustom "Invalid Hex encoding:" . T.pack) . Base16.decode
6578

6679
writeEpochState :: FilePath -> EpochState CurrentEra -> IO ()
6780
writeEpochState fp = LBS.writeFile fp . Plain.serialize

0 commit comments

Comments
 (0)