Skip to content

Commit

Permalink
Merge pull request #2540 from input-output-hk/lehins/snapshots-with-a…
Browse files Browse the repository at this point in the history
…rrays

Snapshots with array base map
  • Loading branch information
lehins committed Nov 10, 2021
2 parents 0411c3e + a2186a3 commit d3d6d07
Show file tree
Hide file tree
Showing 33 changed files with 1,339 additions and 265 deletions.
6 changes: 6 additions & 0 deletions cabal.project
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,12 @@ source-repository-package
tag: ee59880f47ab835dbd73bea0847dab7869fc20d8
--sha256: 1lrzknw765pz2j97nvv9ip3l1mcpf2zr4n56hwlz0rk7wq7ls4cm

source-repository-package
type: git
location: https://github.com/fpco/weigh.git
tag: bfcf4415144d7d2817dfcb91b6f9a6dfd7236de7
--sha256: 01fy4nbq6kaqi73ydn6w7rd1izkg5p217q5znyp2icybf41sl1b6

allow-newer:
monoidal-containers:aeson,
size-based:template-haskell,
Expand Down
3 changes: 2 additions & 1 deletion eras/shelley/impl/cardano-ledger-shelley.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ library
cardano-protocol-tpraos,
cardano-slotting,
cborg,
compact-map,
constraints,
containers,
data-default-class,
Expand All @@ -124,4 +125,4 @@ library
strict-containers,
text,
time,
transformers
transformers,
74 changes: 27 additions & 47 deletions eras/shelley/impl/src/Cardano/Ledger/Shelley/API/Wallet.hs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ import Cardano.Ledger.BaseTypes
epochInfo,
)
import Cardano.Ledger.Coin (Coin (..))
import Cardano.Ledger.Compactible (fromCompact)
import qualified Cardano.Ledger.Core as Core
import Cardano.Ledger.Credential (Credential (..))
import Cardano.Ledger.Crypto (DSIGN, VRF)
Expand Down Expand Up @@ -104,7 +105,7 @@ import Cardano.Ledger.Shelley.Rewards
( NonMyopic (..),
PerformanceEstimate (..),
StakeShare (..),
getTopRankedPools,
getTopRankedPoolsVMap,
nonMyopicMemberRew,
percentile',
)
Expand All @@ -130,12 +131,12 @@ import Data.Coders
(!>),
(<!),
)
import qualified Data.Compact.VMap as VMap
import Data.Default.Class (Default (..))
import Data.Either (fromRight)
import Data.Foldable (fold)
import Data.Foldable (fold, foldMap')
import Data.Map.Strict (Map)
import qualified Data.Map.Strict as Map
import Data.Maybe (fromMaybe)
import Data.Proxy (Proxy (..))
import Data.Ratio ((%))
import Data.Sequence.Strict (StrictSeq)
Expand Down Expand Up @@ -225,7 +226,7 @@ poolsByTotalStakeFraction globals ss =
where
snap@(EB.SnapShot stake _ _) = currentSnapshot ss
Coin totalStake = getTotalStake globals ss
Coin activeStake = fold . EB.unStake $ stake
Coin activeStake = VMap.foldMap fromCompact $ EB.unStake stake
stakeRatio = activeStake % totalStake
PoolDistr poolsByActiveStake = calculatePoolDistr snap
poolsByTotalStake = Map.map toTotalStakeFrac poolsByActiveStake
Expand Down Expand Up @@ -261,39 +262,31 @@ getNonMyopicMemberRewards ::
(Either Coin (Credential 'Staking (Crypto era)))
(Map (KeyHash 'StakePool (Crypto era)) Coin)
getNonMyopicMemberRewards globals ss creds =
Map.fromList $
fmap
(\cred -> (cred, Map.map (mkNMMRewards $ memShare cred) poolData))
(Set.toList creds)
Map.fromSet (\cred -> Map.map (mkNMMRewards $ memShare cred) poolData) creds
where
maxSupply = Coin . fromIntegral $ maxLovelaceSupply globals
Coin totalStake = circulation es maxSupply
toShare (Coin x) = StakeShare (x % totalStake)
memShare (Right cred) =
toShare $
Map.findWithDefault (Coin 0) cred (EB.unStake stake)
toShare $ maybe mempty fromCompact $ VMap.lookup cred (EB.unStake stake)
memShare (Left coin) = toShare coin
es = nesEs ss
pp = esPp es
NonMyopic
{ likelihoodsNM = ls,
rewardPotNM = rPot
} = esNonMyopic es
NonMyopic {likelihoodsNM = ls, rewardPotNM = rPot} = esNonMyopic es
EB.SnapShot stake delegs poolParams = currentSnapshot ss
poolData =
Map.mapWithKey
( \k p ->
Map.fromDistinctAscList
[ ( k,
( percentile' (histLookup k),
p,
toShare . fold
. EB.unStake
$ EB.poolStake k delegs stake
toShare . VMap.foldMap fromCompact . EB.unStake $ EB.poolStake k delegs stake
)
)
poolParams
histLookup k = fromMaybe mempty (Map.lookup k ls)
)
| (k, p) <- VMap.toAscList poolParams
]
histLookup k = Map.findWithDefault mempty k ls
topPools =
getTopRankedPools
getTopRankedPoolsVMap
rPot
(Coin totalStake)
pp
Expand All @@ -306,19 +299,15 @@ getNonMyopicMemberRewards globals ss creds =
where
s = (toShare . _poolPledge) poolp
checkPledge pool =
let ostake =
Set.foldl'
( \c o ->
c
<> fromMaybe
mempty
( Map.lookup (KeyHashObj o) (EB.unStake stake)
)
)
mempty
(_poolOwners pool)
let ostake = sumPoolOwnersStake pool stake
in _poolPledge poolp <= ostake

sumPoolOwnersStake :: PoolParams crypto -> EB.Stake crypto -> Coin
sumPoolOwnersStake pool stake =
let getStakeFor o =
maybe mempty fromCompact $ VMap.lookup (KeyHashObj o) (EB.unStake stake)
in foldMap' getStakeFor (_poolOwners pool)

-- | Create a current snapshot of the ledger state.
--
-- When ranking pools, and reporting their saturation level, in the wallet, we
Expand Down Expand Up @@ -405,15 +394,15 @@ getRewardInfoPools ::
NewEpochState era ->
(RewardParams, Map (KeyHash 'StakePool (Crypto era)) RewardInfoPool)
getRewardInfoPools globals ss =
(mkRewardParams, Map.mapWithKey mkRewardInfoPool poolParams)
(mkRewardParams, VMap.toMap (VMap.mapWithKey mkRewardInfoPool poolParams))
where
es = nesEs ss
pp = esPp es
NonMyopic
{ likelihoodsNM = ls,
rewardPotNM = rPot
} = esNonMyopic es
histLookup key = fromMaybe mempty (Map.lookup key ls)
histLookup key = Map.findWithDefault mempty key ls

EB.SnapShot stakes delegs poolParams = currentSnapshot ss

Expand All @@ -435,17 +424,8 @@ getRewardInfoPools globals ss =
unPerformanceEstimate $ percentile' $ histLookup key
}
where
pstake = fold . EB.unStake $ EB.poolStake key delegs stakes
ostake =
Set.foldl'
( \c o ->
c
<> fromMaybe
mempty
(Map.lookup (KeyHashObj o) (EB.unStake stakes))
)
mempty
(_poolOwners poolp)
pstake = VMap.foldMap fromCompact . EB.unStake $ EB.poolStake key delegs stakes
ostake = sumPoolOwnersStake poolp stakes

{-# DEPRECATED getRewardInfo "Use 'getRewardProvenance' instead." #-}
getRewardInfo ::
Expand Down
23 changes: 14 additions & 9 deletions eras/shelley/impl/src/Cardano/Ledger/Shelley/EpochBoundary.hs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import Cardano.Ledger.Coin
coinToRational,
rationalToCoinViaFloor,
)
import Cardano.Ledger.Compactible
import qualified Cardano.Ledger.Core as Core
import Cardano.Ledger.Credential (Credential, Ptr, StakeReference (..))
import qualified Cardano.Ledger.Crypto as CC (Crypto)
Expand All @@ -55,20 +56,24 @@ import Cardano.Ledger.Val ((<+>), (<×>))
import qualified Cardano.Ledger.Val as Val
import Control.DeepSeq (NFData)
import Control.SetAlgebra (dom, eval, setSingleton, (▷), (◁))
import Data.Compact.VMap as VMap
import Data.Default.Class (Default, def)
import Data.Map.Strict (Map)
import qualified Data.Map.Strict as Map
import Data.Ratio ((%))
import Data.Typeable
import GHC.Generics (Generic)
import GHC.Records (HasField, getField)
import NoThunks.Class (NoThunks (..))
import Numeric.Natural (Natural)

-- | Type of stake as map from hash key to coins associated.
newtype Stake crypto = Stake
{ unStake :: Map (Credential 'Staking crypto) Coin
{ unStake :: VMap VB VP (Credential 'Staking crypto) (CompactForm Coin)
}
deriving (Show, Eq, Ord, NoThunks, NFData)
deriving (Show, Eq, NFData, Generic)

deriving newtype instance Typeable crypto => NoThunks (Stake crypto)

deriving newtype instance
CC.Crypto crypto => ToCBOR (Stake crypto)
Expand Down Expand Up @@ -113,11 +118,11 @@ aggregateUtxoCoinByCredential ptrs (UTxO u) initial =
-- | Get stake of one pool
poolStake ::
KeyHash 'StakePool crypto ->
Map (Credential 'Staking crypto) (KeyHash 'StakePool crypto) ->
VMap VB VB (Credential 'Staking crypto) (KeyHash 'StakePool crypto) ->
Stake crypto ->
Stake crypto
poolStake hk delegs (Stake stake) =
Stake $ eval (dom (delegs setSingleton hk) stake)
Stake $ fromMap (eval (dom (toMap delegs setSingleton hk) toMap stake))

-- | Calculate total possible refunds.
obligation ::
Expand Down Expand Up @@ -165,12 +170,12 @@ maxPool pc r sigma pR = maxPool' a0 nOpt r sigma pR
-- | Snapshot of the stake distribution.
data SnapShot crypto = SnapShot
{ _stake :: !(Stake crypto),
_delegations :: !(Map (Credential 'Staking crypto) (KeyHash 'StakePool crypto)),
_poolParams :: !(Map (KeyHash 'StakePool crypto) (PoolParams crypto))
_delegations :: !(VMap VB VB (Credential 'Staking crypto) (KeyHash 'StakePool crypto)),
_poolParams :: !(VMap VB VB (KeyHash 'StakePool crypto) (PoolParams crypto))
}
deriving (Show, Eq, Generic)

instance NoThunks (SnapShot crypto)
instance Typeable crypto => NoThunks (SnapShot crypto)

instance NFData (SnapShot crypto)

Expand Down Expand Up @@ -203,7 +208,7 @@ data SnapShots crypto = SnapShots
}
deriving (Show, Eq, Generic)

instance NoThunks (SnapShots crypto)
instance Typeable crypto => NoThunks (SnapShots crypto)

instance NFData (SnapShots crypto)

Expand Down Expand Up @@ -234,7 +239,7 @@ instance Default (SnapShots crypto) where
def = emptySnapShots

emptySnapShot :: SnapShot crypto
emptySnapShot = SnapShot (Stake Map.empty) Map.empty Map.empty
emptySnapShot = SnapShot (Stake VMap.empty) VMap.empty VMap.empty

emptySnapShots :: SnapShots crypto
emptySnapShots = SnapShots emptySnapShot emptySnapShot emptySnapShot (Coin 0)
Expand Down
19 changes: 12 additions & 7 deletions eras/shelley/impl/src/Cardano/Ledger/Shelley/LedgerState.hs
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ import Data.Coders
decodeRecordNamed,
(<!),
)
import qualified Data.Compact.VMap as VMap
import Data.Constraint (Constraint)
import Data.Default.Class (Default, def)
import Data.Foldable (fold, toList)
Expand Down Expand Up @@ -999,16 +1000,20 @@ stakeDistr ::
SnapShot (Crypto era)
stakeDistr u ds ps =
SnapShot
(Stake $ eval (dom activeDelegs stakeRelation))
delegs
poolParams
(Stake $ VMap.fromMap (compactCoinOrError <$> eval (dom activeDelegs stakeRelation)))
(VMap.fromMap delegs)
(VMap.fromMap poolParams)
where
DState rewards' delegs ptrs' _ _ _ = ds
PState poolParams _ _ = ps
stakeRelation :: Map (Credential 'Staking (Crypto era)) Coin
stakeRelation = aggregateUtxoCoinByCredential (forwards ptrs') u rewards'
activeDelegs :: Map (Credential 'Staking (Crypto era)) (KeyHash 'StakePool (Crypto era))
activeDelegs = eval ((dom rewards' delegs) dom poolParams)
compactCoinOrError c =
case toCompact c of
Nothing -> error $ "Invalid ADA value in staking: " <> show c
Just compactCoin -> compactCoin

-- | Apply a reward update
applyRUpd ::
Expand Down Expand Up @@ -1115,7 +1120,7 @@ startStep ::
startStep slotsPerEpoch b@(BlocksMade b') es@(EpochState acnt ss ls pr _ nm) maxSupply asc secparam =
let SnapShot stake' delegs' poolParams = _pstakeGo ss
f, numPools, k :: Rational
numPools = fromIntegral (Map.size poolParams)
numPools = fromIntegral (VMap.size poolParams)
k = fromIntegral secparam
f = unboundRational (activeSlotVal asc)

Expand Down Expand Up @@ -1168,7 +1173,7 @@ startStep slotsPerEpoch b@(BlocksMade b') es@(EpochState acnt ss ls pr _ nm) max
rewTotalStake = totalStake,
rewRPot = Coin rPot
}
activestake = fold . unStake $ stake'
activestake = VMap.foldMap fromCompact $ unStake stake'
free =
FreeVars
(unBlocksMade b)
Expand All @@ -1190,7 +1195,7 @@ startStep slotsPerEpoch b@(BlocksMade b') es@(EpochState acnt ss ls pr _ nm) max
RSLP
pulseSize
free
(StrictSeq.fromList $ Map.elems poolParams)
(StrictSeq.fromList $ VMap.elems poolParams)
(RewardAns Map.empty Map.empty)
provenance =
def
Expand Down Expand Up @@ -1277,7 +1282,7 @@ completeRupd
key
( Desirability
{ hitRateEstimate = unPerformanceEstimate estimate,
desirabilityScore = case Map.lookup key poolParams of
desirabilityScore = case VMap.lookup key poolParams of
Just ppx -> desirability (a0, nOpt) rpot ppx estimate totalstake
Nothing -> 0
}
Expand Down
Loading

0 comments on commit d3d6d07

Please sign in to comment.