-
Notifications
You must be signed in to change notification settings - Fork 730
/
Copy pathQuery.hs
163 lines (140 loc) · 6.33 KB
/
Query.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
-- | Convenience query functions
--
module Cardano.Api.Convenience.Query (
QueryConvenienceError(..),
determineEra,
-- * Simplest query related
executeQueryCardanoMode,
queryStateForBalancedTx,
renderQueryConvenienceError,
) where
import Prelude
import Control.Monad.Trans.Except (ExceptT (..), except, runExceptT)
import Control.Monad.Trans.Except.Extra (firstExceptT, hoistMaybe)
import Data.Bifunctor (first)
import Data.Function ((&))
import Data.Set (Set)
import qualified Data.Set as Set
import Data.Text (Text)
import Ouroboros.Consensus.HardFork.Combinator.AcrossEras (EraMismatch (..))
import Cardano.Api.Certificate
import Cardano.Api.Convenience.Constraints
import Cardano.Api.Environment
import Cardano.Api.Eras
import Cardano.Api.IPC
import Cardano.Api.Modes
import Cardano.Api.NetworkId
import Cardano.Api.ProtocolParameters
import Cardano.Api.Query
import Cardano.Api.TxBody
import Cardano.Api.Utils
data QueryConvenienceError
= AcqFailure AcquiringFailure
| SockErr EnvSocketError
| QueryEraMismatch EraMismatch
| ByronEraNotSupported
| EraConsensusModeMismatch !AnyConsensusMode !AnyCardanoEra
renderQueryConvenienceError :: QueryConvenienceError -> Text
renderQueryConvenienceError (AcqFailure e) =
"Acquiring failure: " <> textShow e
renderQueryConvenienceError (SockErr e) =
renderEnvSocketError e
renderQueryConvenienceError (QueryEraMismatch (EraMismatch ledgerEraName' otherEraName')) =
"The era of the node and the tx do not match. " <>
"The node is running in the " <> ledgerEraName' <>
" era, but the transaction is for the " <> otherEraName' <> " era."
renderQueryConvenienceError ByronEraNotSupported =
"Byron era not supported"
renderQueryConvenienceError (EraConsensusModeMismatch cMode anyCEra) =
"Consensus mode and era mismatch. Consensus mode: " <> textShow cMode <>
" Era: " <> textShow anyCEra
-- | A convenience function to query the relevant information, from
-- the local node, for Cardano.Api.Convenience.Construction.constructBalancedTx
queryStateForBalancedTx
:: CardanoEra era
-> NetworkId
-> [TxIn]
-> IO (Either QueryConvenienceError (UTxO era, ProtocolParameters, EraHistory CardanoMode, SystemStart, Set PoolId))
queryStateForBalancedTx era networkId allTxIns = runExceptT $ do
SocketPath sockPath <- ExceptT $ first SockErr <$> readEnvSocketPath
let cModeParams = CardanoModeParams $ EpochSlots 21600
localNodeConnInfo = LocalNodeConnectInfo
cModeParams
networkId
sockPath
qSbe <- except $ getSbe $ cardanoEraStyle era
qeInMode <- toEraInMode era CardanoMode
& hoistMaybe (EraConsensusModeMismatch (AnyConsensusMode CardanoMode) (getIsCardanoEraConstraint era $ AnyCardanoEra era))
-- Queries
let utxoQuery = QueryInEra qeInMode $ QueryInShelleyBasedEra qSbe
$ QueryUTxO (QueryUTxOByTxIn (Set.fromList allTxIns))
pparamsQuery = QueryInEra qeInMode
$ QueryInShelleyBasedEra qSbe QueryProtocolParameters
eraHistoryQuery = QueryEraHistory CardanoModeIsMultiEra
systemStartQuery = QuerySystemStart
stakePoolsQuery = QueryInEra qeInMode . QueryInShelleyBasedEra qSbe $ QueryStakePools
-- Query execution
utxo <- ExceptT $ executeQueryCardanoMode era networkId utxoQuery
pparams <- ExceptT $ executeQueryCardanoMode era networkId pparamsQuery
eraHistory <- firstExceptT AcqFailure $ ExceptT $ queryNodeLocalState localNodeConnInfo Nothing eraHistoryQuery
systemStart <- firstExceptT AcqFailure $ ExceptT $ queryNodeLocalState localNodeConnInfo Nothing systemStartQuery
stakePools <- ExceptT $ executeQueryCardanoMode era networkId stakePoolsQuery
return (utxo, pparams, eraHistory, systemStart, stakePools)
-- | Query the node to determine which era it is in.
determineEra
:: ConsensusModeParams mode
-> LocalNodeConnectInfo mode
-> IO (Either AcquiringFailure AnyCardanoEra)
determineEra cModeParams localNodeConnInfo =
case consensusModeOnly cModeParams of
ByronMode -> return . Right $ AnyCardanoEra ByronEra
ShelleyMode -> return . Right $ AnyCardanoEra ShelleyEra
CardanoMode ->
queryNodeLocalState localNodeConnInfo Nothing
$ QueryCurrentEra CardanoModeIsMultiEra
getSbe :: CardanoEraStyle era -> Either QueryConvenienceError (ShelleyBasedEra era)
getSbe LegacyByronEra = Left ByronEraNotSupported
getSbe (ShelleyBasedEra sbe) = return sbe
-- | Execute a query against the local node. The local
-- node must be in CardanoMode.
executeQueryCardanoMode
:: CardanoEra era
-> NetworkId
-> QueryInMode CardanoMode (Either EraMismatch result)
-> IO (Either QueryConvenienceError result)
executeQueryCardanoMode era nid q = runExceptT $ do
SocketPath sockPath <- firstExceptT SockErr . ExceptT $ readEnvSocketPath
let localConnectInfo =
LocalNodeConnectInfo
{ localConsensusModeParams = CardanoModeParams (EpochSlots 21600)
, localNodeNetworkId = nid
, localNodeSocketPath = sockPath
}
ExceptT $ executeQueryAnyMode era localConnectInfo q
-- | Execute a query against the local node in any mode.
executeQueryAnyMode
:: forall result era mode. CardanoEra era
-> LocalNodeConnectInfo mode
-> QueryInMode mode (Either EraMismatch result)
-> IO (Either QueryConvenienceError result)
executeQueryAnyMode era localNodeConnInfo q = do
let cMode = consensusModeOnly $ localConsensusModeParams localNodeConnInfo
case toEraInMode era cMode of
Just eraInMode ->
case eraInMode of
ByronEraInByronMode -> return $ Left ByronEraNotSupported
_ -> execQuery
Nothing -> return $ Left $ EraConsensusModeMismatch
(AnyConsensusMode CardanoMode)
(getIsCardanoEraConstraint era $ AnyCardanoEra era)
where
execQuery :: IO (Either QueryConvenienceError result)
execQuery = collapse <$> queryNodeLocalState localNodeConnInfo Nothing q
collapse
:: Either AcquiringFailure (Either EraMismatch a)
-> Either QueryConvenienceError a
collapse res = do
innerRes <- first AcqFailure res
first QueryEraMismatch innerRes