Skip to content

Commit 535f703

Browse files
committed
Optimise query stake-snapshot command
1 parent 45b0c58 commit 535f703

File tree

6 files changed

+92
-54
lines changed

6 files changed

+92
-54
lines changed

cabal.project

+2-2
Original file line numberDiff line numberDiff line change
@@ -263,8 +263,8 @@ source-repository-package
263263
source-repository-package
264264
type: git
265265
location: https://github.com/input-output-hk/ouroboros-network
266-
tag: c764553561bed8978d2c6753d1608dc65449617a
267-
--sha256: 0hdh7xdrvxw943r6qr0xr4kwszindh5mnsn1lww6qdnxnmn7wcsc
266+
tag: a06a2472827df073493f64307ef0d854679aaa77
267+
--sha256: 0fchrb4cba2j2jxcc8dk9sn3hnrhc1x56pjy37q7rq9hv1lcx5y2
268268
subdir:
269269
monoidal-synchronisation
270270
network-mux

cardano-api/src/Cardano/Api/KeysShelley.hs

+3-1
Original file line numberDiff line numberDiff line change
@@ -1184,7 +1184,9 @@ instance SerialiseAsBech32 (SigningKey StakePoolKey) where
11841184
bech32PrefixesPermitted _ = ["pool_sk"]
11851185

11861186
newtype instance Hash StakePoolKey =
1187-
StakePoolKeyHash (Shelley.KeyHash Shelley.StakePool StandardCrypto)
1187+
StakePoolKeyHash
1188+
{ unStakePoolKeyHash :: Shelley.KeyHash Shelley.StakePool StandardCrypto
1189+
}
11881190
deriving stock (Eq, Ord)
11891191
deriving (Show, IsString) via UsingRawBytesHex (Hash StakePoolKey)
11901192
deriving (ToCBOR, FromCBOR) via UsingRawBytes (Hash StakePoolKey)

cardano-api/src/Cardano/Api/Orphans.hs

+37-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
{-# LANGUAGE GADTs #-}
77
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
88
{-# LANGUAGE LambdaCase #-}
9+
{-# LANGUAGE NamedFieldPuns #-}
910
{-# LANGUAGE RankNTypes #-}
1011
{-# LANGUAGE ScopedTypeVariables #-}
1112
{-# LANGUAGE StandaloneDeriving #-}
@@ -18,7 +19,7 @@ module Cardano.Api.Orphans () where
1819

1920
import Prelude
2021

21-
import Data.Aeson (FromJSON (..), ToJSON (..), object, (.=))
22+
import Data.Aeson (FromJSON (..), ToJSON (..), object, pairs, (.=))
2223
import qualified Data.Aeson as Aeson
2324
import Data.Aeson.Types (ToJSONKey (..), toJSONKeyText)
2425
import Data.BiMap (BiMap (..), Bimap)
@@ -63,6 +64,7 @@ import Cardano.Ledger.Shelley.PParams (PParamsUpdate)
6364
import qualified Cardano.Ledger.Shelley.Rewards as Shelley
6465
import qualified Cardano.Ledger.Shelley.RewardUpdate as Shelley
6566
import qualified Ouroboros.Consensus.Shelley.Eras as Consensus
67+
import qualified Ouroboros.Consensus.Shelley.Ledger.Query as Consensus
6668

6769
import Cardano.Api.Script
6870

@@ -681,3 +683,37 @@ instance Crypto.Crypto crypto => ToJSON (VMap VB VB (Shelley.KeyHash 'Shelley
681683
instance Crypto.Crypto crypto => ToJSON (VMap VB VP (Shelley.Credential 'Shelley.Staking crypto) (Shelley.CompactForm Shelley.Coin)) where
682684
toJSON = toJSON . fmap fromCompact . VMap.toMap
683685
toEncoding = toEncoding . fmap fromCompact . VMap.toMap
686+
687+
-----
688+
689+
instance ToJSON (Consensus.StakeSnapshots crypto) where
690+
toJSON = object . stakeSnapshotsToPair
691+
toEncoding = pairs . mconcat . stakeSnapshotsToPair
692+
693+
stakeSnapshotsToPair :: Aeson.KeyValue a => Consensus.StakeSnapshots crypto -> [a]
694+
stakeSnapshotsToPair Consensus.StakeSnapshots
695+
{ Consensus.ssStakeSnapshots
696+
, Consensus.ssMarkTotal
697+
, Consensus.ssSetTotal
698+
, Consensus.ssGoTotal
699+
} = mconcat
700+
-- Only output the first pool in order to preserve backwards compatibility of the output
701+
-- format. The output format will have to change to support multiple pools when that
702+
-- functionality is added.
703+
[ take 1 (Map.elems ssStakeSnapshots) >>= stakeSnapshotToPair
704+
, [ "activeStakeMark" .= ssMarkTotal
705+
, "activeStakeSet" .= ssSetTotal
706+
, "activeStakeGo" .= ssGoTotal
707+
]
708+
]
709+
710+
stakeSnapshotToPair :: Aeson.KeyValue a => Consensus.StakeSnapshot crypto -> [a]
711+
stakeSnapshotToPair Consensus.StakeSnapshot
712+
{ Consensus.ssMarkPool
713+
, Consensus.ssSetPool
714+
, Consensus.ssGoPool
715+
} =
716+
[ "poolStakeMark" .= ssMarkPool
717+
, "poolStakeSet" .= ssSetPool
718+
, "poolStakeGo" .= ssGoPool
719+
]

cardano-api/src/Cardano/Api/Query.hs

+30-5
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ module Cardano.Api.Query (
4848
PoolState(..),
4949
decodePoolState,
5050

51+
SerialisedStakeSnapshots(..),
52+
StakeSnapshot(..),
53+
decodeStakeSnapshot,
54+
5155
EraHistory(..),
5256
SystemStart(..),
5357

@@ -245,6 +249,10 @@ data QueryInShelleyBasedEra era result where
245249
:: Maybe (Set PoolId)
246250
-> QueryInShelleyBasedEra era (SerialisedPoolState era)
247251

252+
QueryStakeSnapshot
253+
:: PoolId
254+
-> QueryInShelleyBasedEra era (SerialisedStakeSnapshots era)
255+
248256
deriving instance Show (QueryInShelleyBasedEra era result)
249257

250258

@@ -403,6 +411,18 @@ decodePoolState
403411
-> Either DecoderError (PoolState era)
404412
decodePoolState (SerialisedPoolState (Serialised ls)) = PoolState <$> decodeFull ls
405413

414+
newtype SerialisedStakeSnapshots era
415+
= SerialisedStakeSnapshots (Serialised (Consensus.StakeSnapshots (Ledger.Crypto (ShelleyLedgerEra era))))
416+
417+
newtype StakeSnapshot era = StakeSnapshot (Consensus.StakeSnapshots (Ledger.Crypto (ShelleyLedgerEra era)))
418+
419+
decodeStakeSnapshot
420+
:: forall era. ()
421+
=> FromCBOR (Consensus.StakeSnapshots (Ledger.Crypto (ShelleyLedgerEra era)))
422+
=> SerialisedStakeSnapshots era
423+
-> Either DecoderError (StakeSnapshot era)
424+
decodeStakeSnapshot (SerialisedStakeSnapshots (Serialised ls)) = StakeSnapshot <$> decodeFull ls
425+
406426
toShelleyAddrSet :: CardanoEra era
407427
-> Set AddressAny
408428
-> Set (Shelley.Addr Consensus.StandardCrypto)
@@ -571,7 +591,7 @@ toConsensusQueryShelleyBased erainmode (QueryStakePoolParameters poolids) =
571591
Some (consensusQueryInEraInMode erainmode (Consensus.GetStakePoolParams poolids'))
572592
where
573593
poolids' :: Set (Shelley.KeyHash Shelley.StakePool Consensus.StandardCrypto)
574-
poolids' = Set.map (\(StakePoolKeyHash kh) -> kh) poolids
594+
poolids' = Set.map unStakePoolKeyHash poolids
575595

576596
toConsensusQueryShelleyBased erainmode QueryDebugLedgerState =
577597
Some (consensusQueryInEraInMode erainmode (Consensus.GetCBOR Consensus.DebugNewEpochState))
@@ -583,10 +603,10 @@ toConsensusQueryShelleyBased erainmode QueryCurrentEpochState =
583603
Some (consensusQueryInEraInMode erainmode (Consensus.GetCBOR Consensus.DebugEpochState))
584604

585605
toConsensusQueryShelleyBased erainmode (QueryPoolState poolIds) =
586-
Some (consensusQueryInEraInMode erainmode (Consensus.GetCBOR (Consensus.GetPoolState (getPoolIds <$> poolIds))))
587-
where
588-
getPoolIds :: Set PoolId -> Set (Shelley.KeyHash Shelley.StakePool Consensus.StandardCrypto)
589-
getPoolIds = Set.map (\(StakePoolKeyHash kh) -> kh)
606+
Some (consensusQueryInEraInMode erainmode (Consensus.GetCBOR (Consensus.GetPoolState (Set.map unStakePoolKeyHash <$> poolIds))))
607+
608+
toConsensusQueryShelleyBased erainmode (QueryStakeSnapshot poolId) =
609+
Some (consensusQueryInEraInMode erainmode (Consensus.GetCBOR (Consensus.GetStakeSnapshots (Just (Set.singleton (unStakePoolKeyHash poolId))))))
590610

591611
consensusQueryInEraInMode
592612
:: forall era mode erablock modeblock result result' xs.
@@ -823,6 +843,11 @@ fromConsensusQueryResultShelleyBased _ QueryPoolState{} q' r' =
823843
Consensus.GetCBOR Consensus.GetPoolState {} -> SerialisedPoolState r'
824844
_ -> fromConsensusQueryResultMismatch
825845

846+
fromConsensusQueryResultShelleyBased _ QueryStakeSnapshot{} q' r' =
847+
case q' of
848+
Consensus.GetCBOR Consensus.GetStakeSnapshots {} -> SerialisedStakeSnapshots r'
849+
_ -> fromConsensusQueryResultMismatch
850+
826851
-- | This should /only/ happen if we messed up the mapping in 'toConsensusQuery'
827852
-- and 'fromConsensusQueryResult' so they are inconsistent with each other.
828853
--

cardano-api/src/Cardano/Api/Shelley.hs

+7-1
Original file line numberDiff line numberDiff line change
@@ -207,9 +207,15 @@ module Cardano.Api.Shelley
207207
CurrentEpochState(..),
208208
SerialisedCurrentEpochState(..),
209209
decodeCurrentEpochState,
210+
210211
PoolState(..),
211212
SerialisedPoolState(..),
212213
decodePoolState,
214+
215+
StakeSnapshot(..),
216+
SerialisedStakeSnapshots(..),
217+
decodeStakeSnapshot,
218+
213219
UTxO(..),
214220
AcquireFailure(..),
215221
SystemStart(..),
@@ -235,8 +241,8 @@ import Cardano.Api.Address
235241
import Cardano.Api.Block
236242
import Cardano.Api.Certificate
237243
import Cardano.Api.Eras
238-
import Cardano.Api.IPC
239244
import Cardano.Api.InMode
245+
import Cardano.Api.IPC
240246
import Cardano.Api.KeysByron
241247
import Cardano.Api.KeysPraos
242248
import Cardano.Api.KeysShelley

cardano-cli/src/Cardano/CLI/Shelley/Run/Query.hs

+13-44
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ import qualified Data.Text.IO as Text
5353
import Data.Text.Lazy.Builder (toLazyText)
5454
import Data.Time.Clock
5555
import qualified Data.Vector as Vector
56-
import qualified Data.VMap as VMap
5756
import Formatting.Buildable (build)
5857
import Numeric (showEFloat)
5958
import qualified System.IO as IO
@@ -75,18 +74,14 @@ import qualified Cardano.Crypto.Hash.Blake2b as Blake2b
7574
import qualified Cardano.Crypto.VRF as Crypto
7675
import qualified Cardano.Ledger.Alonzo.PParams as Alonzo
7776
import Cardano.Ledger.BaseTypes (Seed, UnitInterval)
78-
import Cardano.Ledger.Coin
79-
import Cardano.Ledger.Compactible
8077
import qualified Cardano.Ledger.Core as Core
8178
import qualified Cardano.Ledger.Credential as Ledger
8279
import qualified Cardano.Ledger.Crypto as Crypto
8380
import qualified Cardano.Ledger.Era as Era
8481
import qualified Cardano.Ledger.Era as Ledger
8582
import Cardano.Ledger.Keys (KeyHash (..), KeyRole (..))
8683
import Cardano.Ledger.Shelley.Constraints
87-
import Cardano.Ledger.Shelley.EpochBoundary
88-
import Cardano.Ledger.Shelley.LedgerState (EpochState (esSnapshots),
89-
NewEpochState (nesEs), PState (_fPParams, _pParams, _retiring))
84+
import Cardano.Ledger.Shelley.LedgerState (PState (_fPParams, _pParams, _retiring))
9085
import qualified Cardano.Ledger.Shelley.LedgerState as SL
9186
import qualified Cardano.Ledger.Shelley.PParams as Shelley
9287
import Cardano.Ledger.Shelley.Scripts ()
@@ -134,6 +129,7 @@ data ShelleyQueryCmdError
134129
FilePath
135130
-- ^ Operational certificate of the unknown stake pool.
136131
| ShelleyQueryCmdPoolStateDecodeError DecoderError
132+
| ShelleyQueryCmdStakeSnapshotDecodeError DecoderError
137133

138134
deriving Show
139135

@@ -171,6 +167,8 @@ renderShelleyQueryCmdError err =
171167
"in the current epoch, you must wait until the following epoch for the registration to take place."
172168
ShelleyQueryCmdPoolStateDecodeError decoderError ->
173169
"Failed to decode PoolState. Error: " <> Text.pack (show decoderError)
170+
ShelleyQueryCmdStakeSnapshotDecodeError decoderError ->
171+
"Failed to decode StakeSnapshot. Error: " <> Text.pack (show decoderError)
174172

175173
runQueryCmd :: QueryCmd -> ExceptT ShelleyQueryCmdError IO ()
176174
runQueryCmd cmd =
@@ -629,7 +627,7 @@ runQueryStakeSnapshot
629627
-> NetworkId
630628
-> Hash StakePoolKey
631629
-> ExceptT ShelleyQueryCmdError IO ()
632-
runQueryStakeSnapshot (AnyConsensusModeParams cModeParams) network poolid = do
630+
runQueryStakeSnapshot (AnyConsensusModeParams cModeParams) network poolId = do
633631
SocketPath sockPath <- firstExceptT ShelleyQueryCmdEnvVarSocketErr readEnvSocketPath
634632
let localNodeConnInfo = LocalNodeConnectInfo cModeParams network sockPath
635633

@@ -640,9 +638,9 @@ runQueryStakeSnapshot (AnyConsensusModeParams cModeParams) network poolid = do
640638
eInMode <- toEraInMode era cMode
641639
& hoistMaybe (ShelleyQueryCmdEraConsensusModeMismatch (AnyConsensusMode cMode) anyE)
642640

643-
let qInMode = QueryInEra eInMode . QueryInShelleyBasedEra sbe $ QueryDebugLedgerState
641+
let qInMode = QueryInEra eInMode . QueryInShelleyBasedEra sbe $ QueryStakeSnapshot poolId
644642
result <- executeQuery era cModeParams localNodeConnInfo qInMode
645-
obtainLedgerEraClassConstraints sbe (writeStakeSnapshot poolid) result
643+
obtainLedgerEraClassConstraints sbe writeStakeSnapshot result
646644

647645

648646
runQueryLedgerState
@@ -794,44 +792,15 @@ writeLedgerState mOutFile qState@(SerialisedDebugLedgerState serLedgerState) =
794792
writeStakeSnapshot :: forall era ledgerera. ()
795793
=> ShelleyLedgerEra era ~ ledgerera
796794
=> Era.Crypto ledgerera ~ StandardCrypto
797-
=> FromCBOR (DebugLedgerState era)
798-
=> PoolId
799-
-> SerialisedDebugLedgerState era
795+
=> SerialisedStakeSnapshots era
800796
-> ExceptT ShelleyQueryCmdError IO ()
801-
writeStakeSnapshot (StakePoolKeyHash hk) qState =
802-
case decodeDebugLedgerState qState of
803-
-- In the event of decode failure print the CBOR instead
804-
Left bs -> firstExceptT ShelleyQueryCmdHelpersError $ pPrintCBOR bs
805-
806-
Right ledgerState -> do
807-
-- Ledger State
808-
let (DebugLedgerState snapshot) = ledgerState
809-
810-
-- The three stake snapshots, obtained from the ledger state
811-
let (SnapShots markS setS goS _) = esSnapshots $ nesEs snapshot
797+
writeStakeSnapshot qState =
798+
case decodeStakeSnapshot qState of
799+
Left err -> left (ShelleyQueryCmdStakeSnapshotDecodeError err)
812800

801+
Right (StakeSnapshot snapshot) -> do
813802
-- Calculate the three pool and active stake values for the given pool
814-
liftIO . LBS.putStrLn $ encodePretty $ Stakes
815-
{ markPool = getPoolStake hk markS
816-
, setPool = getPoolStake hk setS
817-
, goPool = getPoolStake hk goS
818-
, markTotal = getAllStake markS
819-
, setTotal = getAllStake setS
820-
, goTotal = getAllStake goS
821-
}
822-
823-
-- | Sum all the stake that is held by the pool
824-
getPoolStake :: KeyHash Cardano.Ledger.Keys.StakePool crypto -> SnapShot crypto -> Integer
825-
getPoolStake hash ss = pStake
826-
where
827-
Coin pStake = fold (Map.map fromCompact $ VMap.toMap s)
828-
Stake s = poolStake hash (_delegations ss) (_stake ss)
829-
830-
-- | Sum the active stake from a snapshot
831-
getAllStake :: SnapShot crypto -> Integer
832-
getAllStake (SnapShot stake _ _) = activeStake
833-
where
834-
Coin activeStake = fold (fmap fromCompact (VMap.toMap (unStake stake)))
803+
liftIO . LBS.putStrLn $ encodePretty snapshot
835804

836805
-- | This function obtains the pool parameters, equivalent to the following jq query on the output of query ledger-state
837806
-- .nesEs.esLState._delegationState._pstate._pParams.<pool_id>

0 commit comments

Comments
 (0)