From 0bb11f6769a7fcf5f71fe4c0adf8e732ef68f256 Mon Sep 17 00:00:00 2001 From: John Ky Date: Mon, 12 Dec 2022 15:20:03 +1100 Subject: [PATCH 1/2] Optimise query stake-snapshot command --- cardano-api/src/Cardano/Api/Keys/Shelley.hs | 2 +- cardano-api/src/Cardano/Api/Orphans.hs | 38 +++++++++++- cardano-api/src/Cardano/Api/Query.hs | 35 +++++++++-- cardano-api/src/Cardano/Api/Shelley.hs | 7 +++ .../src/Cardano/CLI/Shelley/Run/Query.hs | 60 +++++-------------- 5 files changed, 89 insertions(+), 53 deletions(-) diff --git a/cardano-api/src/Cardano/Api/Keys/Shelley.hs b/cardano-api/src/Cardano/Api/Keys/Shelley.hs index ddda7a39651..5008487169d 100644 --- a/cardano-api/src/Cardano/Api/Keys/Shelley.hs +++ b/cardano-api/src/Cardano/Api/Keys/Shelley.hs @@ -1218,7 +1218,7 @@ instance SerialiseAsBech32 (SigningKey StakePoolKey) where bech32PrefixesPermitted _ = ["pool_sk"] newtype instance Hash StakePoolKey = - StakePoolKeyHash (Shelley.KeyHash Shelley.StakePool StandardCrypto) + StakePoolKeyHash { unStakePoolKeyHash :: Shelley.KeyHash Shelley.StakePool StandardCrypto } deriving stock (Eq, Ord) deriving (Show, IsString) via UsingRawBytesHex (Hash StakePoolKey) deriving (ToCBOR, FromCBOR) via UsingRawBytes (Hash StakePoolKey) diff --git a/cardano-api/src/Cardano/Api/Orphans.hs b/cardano-api/src/Cardano/Api/Orphans.hs index 4ce8ab5e42a..e769ab39bcb 100644 --- a/cardano-api/src/Cardano/Api/Orphans.hs +++ b/cardano-api/src/Cardano/Api/Orphans.hs @@ -6,6 +6,7 @@ {-# LANGUAGE GADTs #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE LambdaCase #-} +{-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE StandaloneDeriving #-} @@ -18,7 +19,7 @@ module Cardano.Api.Orphans () where import Prelude -import Data.Aeson (FromJSON (..), ToJSON (..), object, (.=)) +import Data.Aeson (FromJSON (..), ToJSON (..), object, pairs, (.=)) import qualified Data.Aeson as Aeson import Data.Aeson.Types (ToJSONKey (..), toJSONKeyText) import Data.BiMap (BiMap (..), Bimap) @@ -69,6 +70,7 @@ import qualified Cardano.Ledger.Shelley.Rewards as Shelley import qualified Cardano.Ledger.Shelley.RewardUpdate as Shelley import Cardano.Ledger.Val (Val) import qualified Ouroboros.Consensus.Shelley.Eras as Consensus +import qualified Ouroboros.Consensus.Shelley.Ledger.Query as Consensus -- Orphan instances involved in the JSON output of the API queries. -- We will remove/replace these as we provide more API wrapper types @@ -686,3 +688,37 @@ instance Crypto.Crypto crypto => ToJSON (VMap VB VB (Shelley.KeyHash 'Shelley instance Crypto.Crypto crypto => ToJSON (VMap VB VP (Shelley.Credential 'Shelley.Staking crypto) (Shelley.CompactForm Shelley.Coin)) where toJSON = toJSON . fmap fromCompact . VMap.toMap toEncoding = toEncoding . fmap fromCompact . VMap.toMap + +----- + +instance ToJSON (Consensus.StakeSnapshots crypto) where + toJSON = object . stakeSnapshotsToPair + toEncoding = pairs . mconcat . stakeSnapshotsToPair + +stakeSnapshotsToPair :: Aeson.KeyValue a => Consensus.StakeSnapshots crypto -> [a] +stakeSnapshotsToPair Consensus.StakeSnapshots + { Consensus.ssStakeSnapshots + , Consensus.ssMarkTotal + , Consensus.ssSetTotal + , Consensus.ssGoTotal + } = mconcat + -- Only output the first pool in order to preserve backwards compatibility of the output + -- format. The output format will have to change to support multiple pools when that + -- functionality is added. + [ take 1 (Map.elems ssStakeSnapshots) >>= stakeSnapshotToPair + , [ "activeStakeMark" .= ssMarkTotal + , "activeStakeSet" .= ssSetTotal + , "activeStakeGo" .= ssGoTotal + ] + ] + +stakeSnapshotToPair :: Aeson.KeyValue a => Consensus.StakeSnapshot crypto -> [a] +stakeSnapshotToPair Consensus.StakeSnapshot + { Consensus.ssMarkPool + , Consensus.ssSetPool + , Consensus.ssGoPool + } = + [ "poolStakeMark" .= ssMarkPool + , "poolStakeSet" .= ssSetPool + , "poolStakeGo" .= ssGoPool + ] diff --git a/cardano-api/src/Cardano/Api/Query.hs b/cardano-api/src/Cardano/Api/Query.hs index 131127e7116..1ebd5108063 100644 --- a/cardano-api/src/Cardano/Api/Query.hs +++ b/cardano-api/src/Cardano/Api/Query.hs @@ -52,6 +52,10 @@ module Cardano.Api.Query ( PoolDistribution(..), decodePoolDistribution, + SerialisedStakeSnapshots(..), + StakeSnapshot(..), + decodeStakeSnapshot, + EraHistory(..), SystemStart(..), @@ -255,6 +259,10 @@ data QueryInShelleyBasedEra era result where :: Maybe (Set PoolId) -> QueryInShelleyBasedEra era (SerialisedPoolDistribution era) + QueryStakeSnapshot + :: PoolId + -> QueryInShelleyBasedEra era (SerialisedStakeSnapshots era) + deriving instance Show (QueryInShelleyBasedEra era result) @@ -429,6 +437,18 @@ decodePoolDistribution -> Either DecoderError (PoolDistribution era) decodePoolDistribution (SerialisedPoolDistribution (Serialised ls)) = PoolDistribution <$> decodeFull ls +newtype SerialisedStakeSnapshots era + = SerialisedStakeSnapshots (Serialised (Consensus.StakeSnapshots (Ledger.Crypto (ShelleyLedgerEra era)))) + +newtype StakeSnapshot era = StakeSnapshot (Consensus.StakeSnapshots (Ledger.Crypto (ShelleyLedgerEra era))) + +decodeStakeSnapshot + :: forall era. () + => FromCBOR (Consensus.StakeSnapshots (Ledger.Crypto (ShelleyLedgerEra era))) + => SerialisedStakeSnapshots era + -> Either DecoderError (StakeSnapshot era) +decodeStakeSnapshot (SerialisedStakeSnapshots (Serialised ls)) = StakeSnapshot <$> decodeFull ls + toShelleyAddrSet :: CardanoEra era -> Set AddressAny -> Set (Shelley.Addr Consensus.StandardCrypto) @@ -597,7 +617,7 @@ toConsensusQueryShelleyBased erainmode (QueryStakePoolParameters poolids) = Some (consensusQueryInEraInMode erainmode (Consensus.GetStakePoolParams poolids')) where poolids' :: Set (Shelley.KeyHash Shelley.StakePool Consensus.StandardCrypto) - poolids' = Set.map (\(StakePoolKeyHash kh) -> kh) poolids + poolids' = Set.map unStakePoolKeyHash poolids toConsensusQueryShelleyBased erainmode QueryDebugLedgerState = Some (consensusQueryInEraInMode erainmode (Consensus.GetCBOR Consensus.DebugNewEpochState)) @@ -609,10 +629,10 @@ toConsensusQueryShelleyBased erainmode QueryCurrentEpochState = Some (consensusQueryInEraInMode erainmode (Consensus.GetCBOR Consensus.DebugEpochState)) toConsensusQueryShelleyBased erainmode (QueryPoolState poolIds) = - Some (consensusQueryInEraInMode erainmode (Consensus.GetCBOR (Consensus.GetPoolState (getPoolIds <$> poolIds)))) - where - getPoolIds :: Set PoolId -> Set (Shelley.KeyHash Shelley.StakePool Consensus.StandardCrypto) - getPoolIds = Set.map (\(StakePoolKeyHash kh) -> kh) + Some (consensusQueryInEraInMode erainmode (Consensus.GetCBOR (Consensus.GetPoolState (Set.map unStakePoolKeyHash <$> poolIds)))) + +toConsensusQueryShelleyBased erainmode (QueryStakeSnapshot poolId) = + Some (consensusQueryInEraInMode erainmode (Consensus.GetCBOR (Consensus.GetStakeSnapshots (Just (Set.singleton (unStakePoolKeyHash poolId)))))) toConsensusQueryShelleyBased erainmode (QueryPoolDistribution poolIds) = Some (consensusQueryInEraInMode erainmode (Consensus.GetCBOR (Consensus.GetPoolDistr (getPoolIds <$> poolIds)))) @@ -860,6 +880,11 @@ fromConsensusQueryResultShelleyBased _ QueryPoolDistribution{} q' r' = Consensus.GetCBOR Consensus.GetPoolDistr {} -> SerialisedPoolDistribution r' _ -> fromConsensusQueryResultMismatch +fromConsensusQueryResultShelleyBased _ QueryStakeSnapshot{} q' r' = + case q' of + Consensus.GetCBOR Consensus.GetStakeSnapshots {} -> SerialisedStakeSnapshots r' + _ -> fromConsensusQueryResultMismatch + -- | This should /only/ happen if we messed up the mapping in 'toConsensusQuery' -- and 'fromConsensusQueryResult' so they are inconsistent with each other. -- diff --git a/cardano-api/src/Cardano/Api/Shelley.hs b/cardano-api/src/Cardano/Api/Shelley.hs index 52ae219f7e4..776fcd5bce6 100644 --- a/cardano-api/src/Cardano/Api/Shelley.hs +++ b/cardano-api/src/Cardano/Api/Shelley.hs @@ -207,12 +207,19 @@ module Cardano.Api.Shelley CurrentEpochState(..), SerialisedCurrentEpochState(..), decodeCurrentEpochState, + PoolState(..), SerialisedPoolState(..), decodePoolState, + PoolDistribution(..), SerialisedPoolDistribution(..), decodePoolDistribution, + + StakeSnapshot(..), + SerialisedStakeSnapshots(..), + decodeStakeSnapshot, + UTxO(..), AcquiringFailure(..), SystemStart(..), diff --git a/cardano-cli/src/Cardano/CLI/Shelley/Run/Query.hs b/cardano-cli/src/Cardano/CLI/Shelley/Run/Query.hs index 3eb7f76c25e..5cbce4b15f3 100644 --- a/cardano-cli/src/Cardano/CLI/Shelley/Run/Query.hs +++ b/cardano-cli/src/Cardano/CLI/Shelley/Run/Query.hs @@ -53,7 +53,6 @@ import qualified Data.Text.IO as Text import Data.Text.Lazy.Builder (toLazyText) import Data.Time.Clock import qualified Data.Vector as Vector -import qualified Data.VMap as VMap import Formatting.Buildable (build) import Numeric (showEFloat) import qualified System.IO as IO @@ -74,8 +73,6 @@ import qualified Cardano.Crypto.Hash.Blake2b as Blake2b import qualified Cardano.Crypto.VRF as Crypto import qualified Cardano.Ledger.Alonzo.PParams as Alonzo import Cardano.Ledger.BaseTypes (Seed, UnitInterval) -import Cardano.Ledger.Coin -import Cardano.Ledger.Compactible import qualified Cardano.Ledger.Core as Core import qualified Cardano.Ledger.Credential as Ledger import qualified Cardano.Ledger.Crypto as Crypto @@ -83,9 +80,7 @@ import qualified Cardano.Ledger.Era as Era import qualified Cardano.Ledger.Era as Ledger import Cardano.Ledger.Keys (KeyHash (..), KeyRole (..)) import Cardano.Ledger.SafeHash (HashAnnotated) -import Cardano.Ledger.Shelley.EpochBoundary -import Cardano.Ledger.Shelley.LedgerState (EpochState (esSnapshots), - NewEpochState (nesEs), PState (_fPParams, _pParams, _retiring)) +import Cardano.Ledger.Shelley.LedgerState (PState (_fPParams, _pParams, _retiring)) import qualified Cardano.Ledger.Shelley.LedgerState as SL import qualified Cardano.Ledger.Shelley.PParams as Shelley import Cardano.Ledger.Shelley.Scripts () @@ -133,6 +128,7 @@ data ShelleyQueryCmdError FilePath -- ^ Operational certificate of the unknown stake pool. | ShelleyQueryCmdPoolStateDecodeError DecoderError + | ShelleyQueryCmdStakeSnapshotDecodeError DecoderError deriving Show @@ -170,6 +166,8 @@ renderShelleyQueryCmdError err = "in the current epoch, you must wait until the following epoch for the registration to take place." ShelleyQueryCmdPoolStateDecodeError decoderError -> "Failed to decode PoolState. Error: " <> Text.pack (show decoderError) + ShelleyQueryCmdStakeSnapshotDecodeError decoderError -> + "Failed to decode StakeSnapshot. Error: " <> Text.pack (show decoderError) runQueryCmd :: QueryCmd -> ExceptT ShelleyQueryCmdError IO () runQueryCmd cmd = @@ -674,9 +672,8 @@ runQueryStakeSnapshot -> NetworkId -> Hash StakePoolKey -> ExceptT ShelleyQueryCmdError IO () -runQueryStakeSnapshot (AnyConsensusModeParams cModeParams) network poolid = do - SocketPath sockPath <- firstExceptT ShelleyQueryCmdEnvVarSocketErr - $ newExceptT readEnvSocketPath +runQueryStakeSnapshot (AnyConsensusModeParams cModeParams) network poolId = do + SocketPath sockPath <- firstExceptT ShelleyQueryCmdEnvVarSocketErr $ newExceptT readEnvSocketPath let localNodeConnInfo = LocalNodeConnectInfo cModeParams network sockPath anyE@(AnyCardanoEra era) <- @@ -689,9 +686,9 @@ runQueryStakeSnapshot (AnyConsensusModeParams cModeParams) network poolid = do eInMode <- toEraInMode era cMode & hoistMaybe (ShelleyQueryCmdEraConsensusModeMismatch (AnyConsensusMode cMode) anyE) - let qInMode = QueryInEra eInMode . QueryInShelleyBasedEra sbe $ QueryDebugLedgerState + let qInMode = QueryInEra eInMode . QueryInShelleyBasedEra sbe $ QueryStakeSnapshot poolId result <- executeQuery era cModeParams localNodeConnInfo qInMode - obtainLedgerEraClassConstraints sbe (writeStakeSnapshot poolid) result + obtainLedgerEraClassConstraints sbe writeStakeSnapshot result runQueryLedgerState @@ -855,44 +852,15 @@ writeLedgerState mOutFile qState@(SerialisedDebugLedgerState serLedgerState) = writeStakeSnapshot :: forall era ledgerera. () => ShelleyLedgerEra era ~ ledgerera => Era.Crypto ledgerera ~ StandardCrypto - => FromCBOR (DebugLedgerState era) - => PoolId - -> SerialisedDebugLedgerState era + => SerialisedStakeSnapshots era -> ExceptT ShelleyQueryCmdError IO () -writeStakeSnapshot (StakePoolKeyHash hk) qState = - case decodeDebugLedgerState qState of - -- In the event of decode failure print the CBOR instead - Left bs -> firstExceptT ShelleyQueryCmdHelpersError $ pPrintCBOR bs - - Right ledgerState -> do - -- Ledger State - let (DebugLedgerState snapshot) = ledgerState - - -- The three stake snapshots, obtained from the ledger state - let (SnapShots markS setS goS _) = esSnapshots $ nesEs snapshot +writeStakeSnapshot qState = + case decodeStakeSnapshot qState of + Left err -> left (ShelleyQueryCmdStakeSnapshotDecodeError err) + Right (StakeSnapshot snapshot) -> do -- Calculate the three pool and active stake values for the given pool - liftIO . LBS.putStrLn $ encodePretty $ Stakes - { markPool = getPoolStake hk markS - , setPool = getPoolStake hk setS - , goPool = getPoolStake hk goS - , markTotal = getAllStake markS - , setTotal = getAllStake setS - , goTotal = getAllStake goS - } - --- | Sum all the stake that is held by the pool -getPoolStake :: KeyHash Cardano.Ledger.Keys.StakePool crypto -> SnapShot crypto -> Integer -getPoolStake hash ss = pStake - where - Coin pStake = fold (Map.map fromCompact $ VMap.toMap s) - Stake s = poolStake hash (_delegations ss) (_stake ss) - --- | Sum the active stake from a snapshot -getAllStake :: SnapShot crypto -> Integer -getAllStake (SnapShot stake _ _) = activeStake - where - Coin activeStake = fold (fmap fromCompact (VMap.toMap (unStake stake))) + liftIO . LBS.putStrLn $ encodePretty snapshot -- | This function obtains the pool parameters, equivalent to the following jq query on the output of query ledger-state -- .nesEs.esLState._delegationState._pstate._pParams. From 8cd88e50305d3f64ede395e6cce610465963fdb3 Mon Sep 17 00:00:00 2001 From: John Ky Date: Sat, 7 Jan 2023 01:48:52 +1100 Subject: [PATCH 2/2] stuff --- cardano-api/src/Cardano/Api/Orphans.hs | 37 +----------------- .../src/Cardano/CLI/Shelley/Run/Query.hs | 17 ++++++++- cardano-cli/src/Cardano/CLI/Types.hs | 38 ------------------- 3 files changed, 16 insertions(+), 76 deletions(-) diff --git a/cardano-api/src/Cardano/Api/Orphans.hs b/cardano-api/src/Cardano/Api/Orphans.hs index e769ab39bcb..b31b43d6330 100644 --- a/cardano-api/src/Cardano/Api/Orphans.hs +++ b/cardano-api/src/Cardano/Api/Orphans.hs @@ -19,7 +19,7 @@ module Cardano.Api.Orphans () where import Prelude -import Data.Aeson (FromJSON (..), ToJSON (..), object, pairs, (.=)) +import Data.Aeson (FromJSON (..), ToJSON (..), object, (.=)) import qualified Data.Aeson as Aeson import Data.Aeson.Types (ToJSONKey (..), toJSONKeyText) import Data.BiMap (BiMap (..), Bimap) @@ -70,7 +70,6 @@ import qualified Cardano.Ledger.Shelley.Rewards as Shelley import qualified Cardano.Ledger.Shelley.RewardUpdate as Shelley import Cardano.Ledger.Val (Val) import qualified Ouroboros.Consensus.Shelley.Eras as Consensus -import qualified Ouroboros.Consensus.Shelley.Ledger.Query as Consensus -- Orphan instances involved in the JSON output of the API queries. -- We will remove/replace these as we provide more API wrapper types @@ -688,37 +687,3 @@ instance Crypto.Crypto crypto => ToJSON (VMap VB VB (Shelley.KeyHash 'Shelley instance Crypto.Crypto crypto => ToJSON (VMap VB VP (Shelley.Credential 'Shelley.Staking crypto) (Shelley.CompactForm Shelley.Coin)) where toJSON = toJSON . fmap fromCompact . VMap.toMap toEncoding = toEncoding . fmap fromCompact . VMap.toMap - ------ - -instance ToJSON (Consensus.StakeSnapshots crypto) where - toJSON = object . stakeSnapshotsToPair - toEncoding = pairs . mconcat . stakeSnapshotsToPair - -stakeSnapshotsToPair :: Aeson.KeyValue a => Consensus.StakeSnapshots crypto -> [a] -stakeSnapshotsToPair Consensus.StakeSnapshots - { Consensus.ssStakeSnapshots - , Consensus.ssMarkTotal - , Consensus.ssSetTotal - , Consensus.ssGoTotal - } = mconcat - -- Only output the first pool in order to preserve backwards compatibility of the output - -- format. The output format will have to change to support multiple pools when that - -- functionality is added. - [ take 1 (Map.elems ssStakeSnapshots) >>= stakeSnapshotToPair - , [ "activeStakeMark" .= ssMarkTotal - , "activeStakeSet" .= ssSetTotal - , "activeStakeGo" .= ssGoTotal - ] - ] - -stakeSnapshotToPair :: Aeson.KeyValue a => Consensus.StakeSnapshot crypto -> [a] -stakeSnapshotToPair Consensus.StakeSnapshot - { Consensus.ssMarkPool - , Consensus.ssSetPool - , Consensus.ssGoPool - } = - [ "poolStakeMark" .= ssMarkPool - , "poolStakeSet" .= ssSetPool - , "poolStakeGo" .= ssGoPool - ] diff --git a/cardano-cli/src/Cardano/CLI/Shelley/Run/Query.hs b/cardano-cli/src/Cardano/CLI/Shelley/Run/Query.hs index 5cbce4b15f3..5f1372def8f 100644 --- a/cardano-cli/src/Cardano/CLI/Shelley/Run/Query.hs +++ b/cardano-cli/src/Cardano/CLI/Shelley/Run/Query.hs @@ -89,12 +89,13 @@ import Cardano.Slotting.EpochInfo (EpochInfo (..), epochInfoSlotToUTCT import Ouroboros.Consensus.BlockchainTime.WallClock.Types (RelativeTime (..), toRelativeTime) import Ouroboros.Consensus.Cardano.Block as Consensus (EraMismatch (..)) -import Ouroboros.Consensus.Protocol.TPraos +import Ouroboros.Consensus.Protocol.TPraos ( StandardCrypto ) import Ouroboros.Network.Block (Serialised (..)) import qualified Ouroboros.Consensus.HardFork.History as Consensus import qualified Ouroboros.Consensus.Protocol.Abstract as Consensus import qualified Ouroboros.Consensus.Protocol.Praos.Common as Consensus +import qualified Ouroboros.Consensus.Shelley.Ledger.Query as Consensus import qualified Ouroboros.Consensus.HardFork.History.Qry as Qry import qualified Ouroboros.Network.Protocol.LocalStateQuery.Type as LocalStateQuery @@ -860,7 +861,19 @@ writeStakeSnapshot qState = Right (StakeSnapshot snapshot) -> do -- Calculate the three pool and active stake values for the given pool - liftIO . LBS.putStrLn $ encodePretty snapshot + liftIO . LBS.putStrLn $ encodePretty $ Aeson.object $ + [ "activeStakeMark" .= Consensus.ssMarkTotal snapshot + , "activeStakeSet" .= Consensus.ssSetTotal snapshot + , "activeStakeGo" .= Consensus.ssGoTotal snapshot + ] <> poolFields snapshot + where poolFields :: Consensus.StakeSnapshots (Ledger.Crypto (ShelleyLedgerEra era)) -> [Aeson.Pair] + poolFields snapshot = case Map.elems (Consensus.ssStakeSnapshots snapshot) of + [pool] -> + [ "poolStakeMark" .= Consensus.ssMarkPool pool + , "poolStakeSet" .= Consensus.ssSetPool pool + , "poolStakeGo" .= Consensus.ssGoPool pool + ] + _ -> [] -- | This function obtains the pool parameters, equivalent to the following jq query on the output of query ledger-state -- .nesEs.esLState._delegationState._pstate._pParams. diff --git a/cardano-cli/src/Cardano/CLI/Types.hs b/cardano-cli/src/Cardano/CLI/Types.hs index d468d884401..6435df874e6 100644 --- a/cardano-cli/src/Cardano/CLI/Types.hs +++ b/cardano-cli/src/Cardano/CLI/Types.hs @@ -36,7 +36,6 @@ module Cardano.CLI.Types , TxMempoolQuery (..) , UpdateProposalFile (..) , VerificationKeyFile (..) - , Stakes (..) , Params (..) , RequiredSigner (..) ) where @@ -182,43 +181,6 @@ data OutputFormat | OutputFormatBech32 deriving (Eq, Show) - --- | This data structure is used to allow nicely formatted output within the query stake-snapshot command. --- --- "markPool", "setPool", "goPool" are the three ledger state stake snapshots (from most recent to least recent) --- go is the snapshot that is used for the current epoch, set will be used in the next epoch, --- mark for the epoch after that. "markTotal", "setTotal", "goTotal" record the total active stake for each snapshot. --- --- This information can be used by community tools to calculate upcoming leader schedules. -data Stakes = Stakes - { markPool :: Integer - , setPool :: Integer - , goPool :: Integer - , markTotal :: Integer - , setTotal :: Integer - , goTotal :: Integer - } deriving Show - --- | Pretty printing for stake information -instance ToJSON Stakes where - toJSON (Stakes m s g mt st gt) = object - [ "poolStakeMark" .= m - , "poolStakeSet" .= s - , "poolStakeGo" .= g - , "activeStakeMark" .= mt - , "activeStakeSet" .= st - , "activeStakeGo" .= gt - ] - - toEncoding (Stakes m s g mt st gt) = pairs $ mconcat - [ "poolStakeMark" .= m - , "poolStakeSet" .= s - , "poolStakeGo" .= g - , "activeStakeMark" .= mt - , "activeStakeSet" .= st - , "activeStakeGo" .= gt - ] - -- | This data structure is used to allow nicely formatted output in the query pool-params command. -- params are the current pool parameter settings, futureparams are new parameters, retiringEpoch is the -- epoch that has been set for pool retirement. Any of these may be Nothing.