{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE ViewPatterns #-}

-- | How to compute the reward update compuation. Also, how to spread the
--     compuation over many blocks, once the chain reaches a stability point.
module Cardano.Ledger.Shelley.RewardUpdate (
  RewardEvent,
  RewardAns (..),
  Pulser,
  RewardUpdate (..),
  emptyRewardUpdate,
  RewardSnapShot (..),
  FreeVars (..),
  rewardStakePoolMember,
  RewardPulser (..),
  clearRecent,
  PulsingRewUpdate (..),
) where

import Cardano.Ledger.BaseTypes (ProtVer (..), ShelleyBase)
import Cardano.Ledger.Binary (
  DecCBOR (..),
  EncCBOR (..),
  decNoShareCBOR,
  decodeRecordNamed,
  encodeListLen,
 )
import Cardano.Ledger.Binary.Coders (
  Decode (..),
  Encode (..),
  decode,
  encode,
  (!>),
  (<!),
 )
import Cardano.Ledger.Coin (Coin (..), CompactForm, DeltaCoin (..))
import Cardano.Ledger.Compactible (Compactible (fromCompact))
import Cardano.Ledger.Core (Reward (..), RewardType (MemberReward))
import Cardano.Ledger.Credential (Credential (..))
import Cardano.Ledger.Crypto (Crypto)
import Cardano.Ledger.Keys (KeyHash, KeyRole (..))
import Cardano.Ledger.Shelley.PoolRank (Likelihood, NonMyopic)
import Cardano.Ledger.Shelley.Rewards (
  PoolRewardInfo (..),
  rewardOnePoolMember,
 )
import Control.DeepSeq (NFData (..))
import Data.Aeson (KeyValue, ToJSON (..), Value (Null), object, pairs, (.=))
import Data.Default.Class (def)
import Data.Group (invert)
import Data.Kind (Type)
import Data.Map.Strict (Map)
import qualified Data.Map.Strict as Map
import Data.Maybe (fromMaybe)
import Data.Pulse (Pulsable (..), completeM)
import Data.Set (Set)
import qualified Data.Set as Set
import Data.Typeable
import Data.VMap as VMap
import GHC.Generics (Generic)
import NoThunks.Class (NoThunks (..), allNoThunks)

-- ===============================================================

type RewardEvent c = Map (Credential 'Staking c) (Set (Reward c))

-- | The result of reward calculation is a pair of aggregate Maps.
--   One for the accumulated answer, and one for the answer since the last pulse
data RewardAns c = RewardAns
  { forall c. RewardAns c -> Map (Credential 'Staking c) (Reward c)
accumRewardAns :: !(Map (Credential 'Staking c) (Reward c))
  , forall c. RewardAns c -> RewardEvent c
recentRewardAns :: !(RewardEvent c)
  }
  deriving (Int -> RewardAns c -> ShowS
forall c. Int -> RewardAns c -> ShowS
forall c. [RewardAns c] -> ShowS
forall c. RewardAns c -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [RewardAns c] -> ShowS
$cshowList :: forall c. [RewardAns c] -> ShowS
show :: RewardAns c -> String
$cshow :: forall c. RewardAns c -> String
showsPrec :: Int -> RewardAns c -> ShowS
$cshowsPrec :: forall c. Int -> RewardAns c -> ShowS
Show, RewardAns c -> RewardAns c -> Bool
forall c. RewardAns c -> RewardAns c -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: RewardAns c -> RewardAns c -> Bool
$c/= :: forall c. RewardAns c -> RewardAns c -> Bool
== :: RewardAns c -> RewardAns c -> Bool
$c== :: forall c. RewardAns c -> RewardAns c -> Bool
Eq, forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall c x. Rep (RewardAns c) x -> RewardAns c
forall c x. RewardAns c -> Rep (RewardAns c) x
$cto :: forall c x. Rep (RewardAns c) x -> RewardAns c
$cfrom :: forall c x. RewardAns c -> Rep (RewardAns c) x
Generic)
  deriving (forall c. RewardAns c -> ()
forall a. (a -> ()) -> NFData a
rnf :: RewardAns c -> ()
$crnf :: forall c. RewardAns c -> ()
NFData)

instance NoThunks (RewardAns c)

instance Crypto c => EncCBOR (RewardAns c) where
  encCBOR :: RewardAns c -> Encoding
encCBOR (RewardAns Map (Credential 'Staking c) (Reward c)
accum RewardEvent c
recent) = Word -> Encoding
encodeListLen Word
2 forall a. Semigroup a => a -> a -> a
<> forall a. EncCBOR a => a -> Encoding
encCBOR Map (Credential 'Staking c) (Reward c)
accum forall a. Semigroup a => a -> a -> a
<> forall a. EncCBOR a => a -> Encoding
encCBOR RewardEvent c
recent

instance Crypto c => DecCBOR (RewardAns c) where
  decCBOR :: forall s. Decoder s (RewardAns c)
decCBOR = forall a s. Text -> (a -> Int) -> Decoder s a -> Decoder s a
decodeRecordNamed Text
"RewardAns" (forall a b. a -> b -> a
const Int
2) (forall c.
Map (Credential 'Staking c) (Reward c)
-> RewardEvent c -> RewardAns c
RewardAns forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a s. DecCBOR a => Decoder s a
decCBOR forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a s. DecCBOR a => Decoder s a
decCBOR)

-- | The type of RewardPulser we pulse on.
type Pulser c = RewardPulser c ShelleyBase (RewardAns c)

-- =====================================

-- | The ultimate goal of a reward update computation.
--     Aggregating rewards for each staking credential.
data RewardUpdate c = RewardUpdate
  { forall c. RewardUpdate c -> DeltaCoin
deltaT :: !DeltaCoin
  , forall c. RewardUpdate c -> DeltaCoin
deltaR :: !DeltaCoin
  , forall c.
RewardUpdate c -> Map (Credential 'Staking c) (Set (Reward c))
rs :: !(Map (Credential 'Staking c) (Set (Reward c)))
  , forall c. RewardUpdate c -> DeltaCoin
deltaF :: !DeltaCoin
  , forall c. RewardUpdate c -> NonMyopic c
nonMyopic :: !(NonMyopic c)
  }
  deriving (Int -> RewardUpdate c -> ShowS
forall c. Int -> RewardUpdate c -> ShowS
forall c. [RewardUpdate c] -> ShowS
forall c. RewardUpdate c -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [RewardUpdate c] -> ShowS
$cshowList :: forall c. [RewardUpdate c] -> ShowS
show :: RewardUpdate c -> String
$cshow :: forall c. RewardUpdate c -> String
showsPrec :: Int -> RewardUpdate c -> ShowS
$cshowsPrec :: forall c. Int -> RewardUpdate c -> ShowS
Show, RewardUpdate c -> RewardUpdate c -> Bool
forall c. RewardUpdate c -> RewardUpdate c -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: RewardUpdate c -> RewardUpdate c -> Bool
$c/= :: forall c. RewardUpdate c -> RewardUpdate c -> Bool
== :: RewardUpdate c -> RewardUpdate c -> Bool
$c== :: forall c. RewardUpdate c -> RewardUpdate c -> Bool
Eq, forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall c x. Rep (RewardUpdate c) x -> RewardUpdate c
forall c x. RewardUpdate c -> Rep (RewardUpdate c) x
$cto :: forall c x. Rep (RewardUpdate c) x -> RewardUpdate c
$cfrom :: forall c x. RewardUpdate c -> Rep (RewardUpdate c) x
Generic)

instance NoThunks (RewardUpdate c)

instance NFData (RewardUpdate c)

instance Crypto c => EncCBOR (RewardUpdate c) where
  encCBOR :: RewardUpdate c -> Encoding
encCBOR (RewardUpdate DeltaCoin
dt DeltaCoin
dr Map (Credential 'Staking c) (Set (Reward c))
rw DeltaCoin
df NonMyopic c
nm) =
    Word -> Encoding
encodeListLen Word
5
      forall a. Semigroup a => a -> a -> a
<> forall a. EncCBOR a => a -> Encoding
encCBOR DeltaCoin
dt
      forall a. Semigroup a => a -> a -> a
<> forall a. EncCBOR a => a -> Encoding
encCBOR (forall m. Group m => m -> m
invert DeltaCoin
dr) -- TODO change Coin serialization to use integers?
      forall a. Semigroup a => a -> a -> a
<> forall a. EncCBOR a => a -> Encoding
encCBOR Map (Credential 'Staking c) (Set (Reward c))
rw
      forall a. Semigroup a => a -> a -> a
<> forall a. EncCBOR a => a -> Encoding
encCBOR (forall m. Group m => m -> m
invert DeltaCoin
df) -- TODO change Coin serialization to use integers?
      forall a. Semigroup a => a -> a -> a
<> forall a. EncCBOR a => a -> Encoding
encCBOR NonMyopic c
nm

instance Crypto c => DecCBOR (RewardUpdate c) where
  decCBOR :: forall s. Decoder s (RewardUpdate c)
decCBOR = do
    forall a s. Text -> (a -> Int) -> Decoder s a -> Decoder s a
decodeRecordNamed Text
"RewardUpdate" (forall a b. a -> b -> a
const Int
5) forall a b. (a -> b) -> a -> b
$ do
      DeltaCoin
dt <- forall a s. DecCBOR a => Decoder s a
decCBOR
      DeltaCoin
dr <- forall a s. DecCBOR a => Decoder s a
decCBOR -- TODO change Coin serialization to use integers?
      Map (Credential 'Staking c) (Set (Reward c))
rw <- forall a s. DecCBOR a => Decoder s a
decCBOR
      DeltaCoin
df <- forall a s. DecCBOR a => Decoder s a
decCBOR -- TODO change Coin serialization to use integers?
      NonMyopic c
nm <- forall a s. DecShareCBOR a => Decoder s a
decNoShareCBOR
      forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall c.
DeltaCoin
-> DeltaCoin
-> Map (Credential 'Staking c) (Set (Reward c))
-> DeltaCoin
-> NonMyopic c
-> RewardUpdate c
RewardUpdate DeltaCoin
dt (forall m. Group m => m -> m
invert DeltaCoin
dr) Map (Credential 'Staking c) (Set (Reward c))
rw (forall m. Group m => m -> m
invert DeltaCoin
df) NonMyopic c
nm

instance Crypto c => ToJSON (RewardUpdate c) where
  toJSON :: RewardUpdate c -> Value
toJSON = [Pair] -> Value
object forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall e a c. (KeyValue e a, Crypto c) => RewardUpdate c -> [a]
toRewardUpdatePair
  toEncoding :: RewardUpdate c -> Encoding
toEncoding = Series -> Encoding
pairs forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Monoid a => [a] -> a
mconcat forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall e a c. (KeyValue e a, Crypto c) => RewardUpdate c -> [a]
toRewardUpdatePair

toRewardUpdatePair :: (KeyValue e a, Crypto c) => RewardUpdate c -> [a]
toRewardUpdatePair :: forall e a c. (KeyValue e a, Crypto c) => RewardUpdate c -> [a]
toRewardUpdatePair ru :: RewardUpdate c
ru@(RewardUpdate DeltaCoin
_ DeltaCoin
_ Map (Credential 'Staking c) (Set (Reward c))
_ DeltaCoin
_ NonMyopic c
_) =
  let RewardUpdate {Map (Credential 'Staking c) (Set (Reward c))
DeltaCoin
NonMyopic c
nonMyopic :: NonMyopic c
deltaF :: DeltaCoin
rs :: Map (Credential 'Staking c) (Set (Reward c))
deltaR :: DeltaCoin
deltaT :: DeltaCoin
nonMyopic :: forall c. RewardUpdate c -> NonMyopic c
deltaF :: forall c. RewardUpdate c -> DeltaCoin
rs :: forall c.
RewardUpdate c -> Map (Credential 'Staking c) (Set (Reward c))
deltaR :: forall c. RewardUpdate c -> DeltaCoin
deltaT :: forall c. RewardUpdate c -> DeltaCoin
..} = RewardUpdate c
ru
   in [ Key
"deltaT" forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= DeltaCoin
deltaT
      , Key
"deltaR" forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= DeltaCoin
deltaR
      , Key
"rs" forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Map (Credential 'Staking c) (Set (Reward c))
rs
      , Key
"deltaF" forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= DeltaCoin
deltaF
      , Key
"nonMyopic" forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= NonMyopic c
nonMyopic
      ]

emptyRewardUpdate :: RewardUpdate c
emptyRewardUpdate :: forall c. RewardUpdate c
emptyRewardUpdate =
  forall c.
DeltaCoin
-> DeltaCoin
-> Map (Credential 'Staking c) (Set (Reward c))
-> DeltaCoin
-> NonMyopic c
-> RewardUpdate c
RewardUpdate (Integer -> DeltaCoin
DeltaCoin Integer
0) (Integer -> DeltaCoin
DeltaCoin Integer
0) forall k a. Map k a
Map.empty (Integer -> DeltaCoin
DeltaCoin Integer
0) forall a. Default a => a
def

-- ===================================================

-- | To complete the reward update, we need a snap shot of the EpochState particular to this computation
data RewardSnapShot c = RewardSnapShot
  { forall c. RewardSnapShot c -> Coin
rewFees :: !Coin
  , forall c. RewardSnapShot c -> ProtVer
rewProtocolVersion :: !ProtVer
  , forall c. RewardSnapShot c -> NonMyopic c
rewNonMyopic :: !(NonMyopic c)
  , forall c. RewardSnapShot c -> Coin
rewDeltaR1 :: !Coin -- deltaR1
  , forall c. RewardSnapShot c -> Coin
rewR :: !Coin -- r
  , forall c. RewardSnapShot c -> Coin
rewDeltaT1 :: !Coin -- deltaT1
  , forall c. RewardSnapShot c -> Map (KeyHash 'StakePool c) Likelihood
rewLikelihoods :: !(Map (KeyHash 'StakePool c) Likelihood)
  , forall c.
RewardSnapShot c -> Map (Credential 'Staking c) (Set (Reward c))
rewLeaders :: !(Map (Credential 'Staking c) (Set (Reward c)))
  }
  deriving (Int -> RewardSnapShot c -> ShowS
forall c. Int -> RewardSnapShot c -> ShowS
forall c. [RewardSnapShot c] -> ShowS
forall c. RewardSnapShot c -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [RewardSnapShot c] -> ShowS
$cshowList :: forall c. [RewardSnapShot c] -> ShowS
show :: RewardSnapShot c -> String
$cshow :: forall c. RewardSnapShot c -> String
showsPrec :: Int -> RewardSnapShot c -> ShowS
$cshowsPrec :: forall c. Int -> RewardSnapShot c -> ShowS
Show, RewardSnapShot c -> RewardSnapShot c -> Bool
forall c. RewardSnapShot c -> RewardSnapShot c -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: RewardSnapShot c -> RewardSnapShot c -> Bool
$c/= :: forall c. RewardSnapShot c -> RewardSnapShot c -> Bool
== :: RewardSnapShot c -> RewardSnapShot c -> Bool
$c== :: forall c. RewardSnapShot c -> RewardSnapShot c -> Bool
Eq, forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall c x. Rep (RewardSnapShot c) x -> RewardSnapShot c
forall c x. RewardSnapShot c -> Rep (RewardSnapShot c) x
$cto :: forall c x. Rep (RewardSnapShot c) x -> RewardSnapShot c
$cfrom :: forall c x. RewardSnapShot c -> Rep (RewardSnapShot c) x
Generic)

instance Typeable c => NoThunks (RewardSnapShot c)

instance NFData (RewardSnapShot c)

instance Crypto c => EncCBOR (RewardSnapShot c) where
  encCBOR :: RewardSnapShot c -> Encoding
encCBOR (RewardSnapShot Coin
fees ProtVer
ver NonMyopic c
nm Coin
dr1 Coin
r Coin
dt1 Map (KeyHash 'StakePool c) Likelihood
lhs Map (Credential 'Staking c) (Set (Reward c))
lrs) =
    forall (w :: Wrapped) t. Encode w t -> Encoding
encode
      ( forall t. t -> Encode ('Closed 'Dense) t
Rec forall c.
Coin
-> ProtVer
-> NonMyopic c
-> Coin
-> Coin
-> Coin
-> Map (KeyHash 'StakePool c) Likelihood
-> Map (Credential 'Staking c) (Set (Reward c))
-> RewardSnapShot c
RewardSnapShot
          forall (w :: Wrapped) a t (r :: Density).
Encode w (a -> t) -> Encode ('Closed r) a -> Encode w t
!> forall t. EncCBOR t => t -> Encode ('Closed 'Dense) t
To Coin
fees
          forall (w :: Wrapped) a t (r :: Density).
Encode w (a -> t) -> Encode ('Closed r) a -> Encode w t
!> forall t. EncCBOR t => t -> Encode ('Closed 'Dense) t
To ProtVer
ver
          forall (w :: Wrapped) a t (r :: Density).
Encode w (a -> t) -> Encode ('Closed r) a -> Encode w t
!> forall t. EncCBOR t => t -> Encode ('Closed 'Dense) t
To NonMyopic c
nm
          forall (w :: Wrapped) a t (r :: Density).
Encode w (a -> t) -> Encode ('Closed r) a -> Encode w t
!> forall t. EncCBOR t => t -> Encode ('Closed 'Dense) t
To Coin
dr1
          forall (w :: Wrapped) a t (r :: Density).
Encode w (a -> t) -> Encode ('Closed r) a -> Encode w t
!> forall t. EncCBOR t => t -> Encode ('Closed 'Dense) t
To Coin
r
          forall (w :: Wrapped) a t (r :: Density).
Encode w (a -> t) -> Encode ('Closed r) a -> Encode w t
!> forall t. EncCBOR t => t -> Encode ('Closed 'Dense) t
To Coin
dt1
          forall (w :: Wrapped) a t (r :: Density).
Encode w (a -> t) -> Encode ('Closed r) a -> Encode w t
!> forall t. EncCBOR t => t -> Encode ('Closed 'Dense) t
To Map (KeyHash 'StakePool c) Likelihood
lhs
          forall (w :: Wrapped) a t (r :: Density).
Encode w (a -> t) -> Encode ('Closed r) a -> Encode w t
!> forall t. EncCBOR t => t -> Encode ('Closed 'Dense) t
To Map (Credential 'Staking c) (Set (Reward c))
lrs
      )

instance Crypto c => DecCBOR (RewardSnapShot c) where
  decCBOR :: forall s. Decoder s (RewardSnapShot c)
decCBOR =
    forall (w :: Wrapped) t s. Decode w t -> Decoder s t
decode
      ( forall t. t -> Decode ('Closed 'Dense) t
RecD forall c.
Coin
-> ProtVer
-> NonMyopic c
-> Coin
-> Coin
-> Coin
-> Map (KeyHash 'StakePool c) Likelihood
-> Map (Credential 'Staking c) (Set (Reward c))
-> RewardSnapShot c
RewardSnapShot
          forall (w1 :: Wrapped) a t (w :: Density).
Decode w1 (a -> t) -> Decode ('Closed w) a -> Decode w1 t
<! forall t (w :: Wrapped). DecCBOR t => Decode w t
From
          forall (w1 :: Wrapped) a t (w :: Density).
Decode w1 (a -> t) -> Decode ('Closed w) a -> Decode w1 t
<! forall t (w :: Wrapped). DecCBOR t => Decode w t
From
          forall (w1 :: Wrapped) a t (w :: Density).
Decode w1 (a -> t) -> Decode ('Closed w) a -> Decode w1 t
<! forall t. (forall s. Decoder s t) -> Decode ('Closed 'Dense) t
D forall a s. DecShareCBOR a => Decoder s a
decNoShareCBOR
          forall (w1 :: Wrapped) a t (w :: Density).
Decode w1 (a -> t) -> Decode ('Closed w) a -> Decode w1 t
<! forall t (w :: Wrapped). DecCBOR t => Decode w t
From
          forall (w1 :: Wrapped) a t (w :: Density).
Decode w1 (a -> t) -> Decode ('Closed w) a -> Decode w1 t
<! forall t (w :: Wrapped). DecCBOR t => Decode w t
From
          forall (w1 :: Wrapped) a t (w :: Density).
Decode w1 (a -> t) -> Decode ('Closed w) a -> Decode w1 t
<! forall t (w :: Wrapped). DecCBOR t => Decode w t
From
          forall (w1 :: Wrapped) a t (w :: Density).
Decode w1 (a -> t) -> Decode ('Closed w) a -> Decode w1 t
<! forall t (w :: Wrapped). DecCBOR t => Decode w t
From
          forall (w1 :: Wrapped) a t (w :: Density).
Decode w1 (a -> t) -> Decode ('Closed w) a -> Decode w1 t
<! forall t (w :: Wrapped). DecCBOR t => Decode w t
From
      )

-- ========================================================
-- FreeVars is the set of variables needed to compute
-- rewardStakePool, so that it can be made into a serializable
-- Pulsable function.

data FreeVars c = FreeVars
  { forall c.
FreeVars c
-> VMap VB VB (Credential 'Staking c) (KeyHash 'StakePool c)
fvDelegs :: !(VMap VB VB (Credential 'Staking c) (KeyHash 'StakePool c))
  , forall c. FreeVars c -> Set (Credential 'Staking c)
fvAddrsRew :: !(Set (Credential 'Staking c))
  , forall c. FreeVars c -> Coin
fvTotalStake :: !Coin
  , forall c. FreeVars c -> ProtVer
fvProtVer :: !ProtVer
  , forall c.
FreeVars c -> Map (KeyHash 'StakePool c) (PoolRewardInfo c)
fvPoolRewardInfo :: !(Map (KeyHash 'StakePool c) (PoolRewardInfo c))
  }
  deriving (FreeVars c -> FreeVars c -> Bool
forall c. FreeVars c -> FreeVars c -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: FreeVars c -> FreeVars c -> Bool
$c/= :: forall c. FreeVars c -> FreeVars c -> Bool
== :: FreeVars c -> FreeVars c -> Bool
$c== :: forall c. FreeVars c -> FreeVars c -> Bool
Eq, Int -> FreeVars c -> ShowS
forall c. Int -> FreeVars c -> ShowS
forall c. [FreeVars c] -> ShowS
forall c. FreeVars c -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [FreeVars c] -> ShowS
$cshowList :: forall c. [FreeVars c] -> ShowS
show :: FreeVars c -> String
$cshow :: forall c. FreeVars c -> String
showsPrec :: Int -> FreeVars c -> ShowS
$cshowsPrec :: forall c. Int -> FreeVars c -> ShowS
Show, forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall c x. Rep (FreeVars c) x -> FreeVars c
forall c x. FreeVars c -> Rep (FreeVars c) x
$cto :: forall c x. Rep (FreeVars c) x -> FreeVars c
$cfrom :: forall c x. FreeVars c -> Rep (FreeVars c) x
Generic)
  deriving (forall c.
Typeable c =>
Context -> FreeVars c -> IO (Maybe ThunkInfo)
forall c. Typeable c => Proxy (FreeVars c) -> String
forall a.
(Context -> a -> IO (Maybe ThunkInfo))
-> (Context -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> String)
-> NoThunks a
showTypeOf :: Proxy (FreeVars c) -> String
$cshowTypeOf :: forall c. Typeable c => Proxy (FreeVars c) -> String
wNoThunks :: Context -> FreeVars c -> IO (Maybe ThunkInfo)
$cwNoThunks :: forall c.
Typeable c =>
Context -> FreeVars c -> IO (Maybe ThunkInfo)
noThunks :: Context -> FreeVars c -> IO (Maybe ThunkInfo)
$cnoThunks :: forall c.
Typeable c =>
Context -> FreeVars c -> IO (Maybe ThunkInfo)
NoThunks)

instance NFData (FreeVars c)

instance Crypto c => EncCBOR (FreeVars c) where
  encCBOR :: FreeVars c -> Encoding
encCBOR
    FreeVars
      { VMap VB VB (Credential 'Staking c) (KeyHash 'StakePool c)
fvDelegs :: VMap VB VB (Credential 'Staking c) (KeyHash 'StakePool c)
fvDelegs :: forall c.
FreeVars c
-> VMap VB VB (Credential 'Staking c) (KeyHash 'StakePool c)
fvDelegs
      , Set (Credential 'Staking c)
fvAddrsRew :: Set (Credential 'Staking c)
fvAddrsRew :: forall c. FreeVars c -> Set (Credential 'Staking c)
fvAddrsRew
      , Coin
fvTotalStake :: Coin
fvTotalStake :: forall c. FreeVars c -> Coin
fvTotalStake
      , ProtVer
fvProtVer :: ProtVer
fvProtVer :: forall c. FreeVars c -> ProtVer
fvProtVer
      , Map (KeyHash 'StakePool c) (PoolRewardInfo c)
fvPoolRewardInfo :: Map (KeyHash 'StakePool c) (PoolRewardInfo c)
fvPoolRewardInfo :: forall c.
FreeVars c -> Map (KeyHash 'StakePool c) (PoolRewardInfo c)
fvPoolRewardInfo
      } =
      forall (w :: Wrapped) t. Encode w t -> Encoding
encode
        ( forall t. t -> Encode ('Closed 'Dense) t
Rec forall c.
VMap VB VB (Credential 'Staking c) (KeyHash 'StakePool c)
-> Set (Credential 'Staking c)
-> Coin
-> ProtVer
-> Map (KeyHash 'StakePool c) (PoolRewardInfo c)
-> FreeVars c
FreeVars
            forall (w :: Wrapped) a t (r :: Density).
Encode w (a -> t) -> Encode ('Closed r) a -> Encode w t
!> forall t. EncCBOR t => t -> Encode ('Closed 'Dense) t
To VMap VB VB (Credential 'Staking c) (KeyHash 'StakePool c)
fvDelegs
            forall (w :: Wrapped) a t (r :: Density).
Encode w (a -> t) -> Encode ('Closed r) a -> Encode w t
!> forall t. EncCBOR t => t -> Encode ('Closed 'Dense) t
To Set (Credential 'Staking c)
fvAddrsRew
            forall (w :: Wrapped) a t (r :: Density).
Encode w (a -> t) -> Encode ('Closed r) a -> Encode w t
!> forall t. EncCBOR t => t -> Encode ('Closed 'Dense) t
To Coin
fvTotalStake
            forall (w :: Wrapped) a t (r :: Density).
Encode w (a -> t) -> Encode ('Closed r) a -> Encode w t
!> forall t. EncCBOR t => t -> Encode ('Closed 'Dense) t
To ProtVer
fvProtVer
            forall (w :: Wrapped) a t (r :: Density).
Encode w (a -> t) -> Encode ('Closed r) a -> Encode w t
!> forall t. EncCBOR t => t -> Encode ('Closed 'Dense) t
To Map (KeyHash 'StakePool c) (PoolRewardInfo c)
fvPoolRewardInfo
        )

instance Crypto c => DecCBOR (FreeVars c) where
  decCBOR :: forall s. Decoder s (FreeVars c)
decCBOR =
    forall (w :: Wrapped) t s. Decode w t -> Decoder s t
decode
      ( forall t. t -> Decode ('Closed 'Dense) t
RecD forall c.
VMap VB VB (Credential 'Staking c) (KeyHash 'StakePool c)
-> Set (Credential 'Staking c)
-> Coin
-> ProtVer
-> Map (KeyHash 'StakePool c) (PoolRewardInfo c)
-> FreeVars c
FreeVars
          forall (w1 :: Wrapped) a t (w :: Density).
Decode w1 (a -> t) -> Decode ('Closed w) a -> Decode w1 t
<! forall t (w :: Wrapped). DecCBOR t => Decode w t
From {- fvDelegs -}
          forall (w1 :: Wrapped) a t (w :: Density).
Decode w1 (a -> t) -> Decode ('Closed w) a -> Decode w1 t
<! forall t (w :: Wrapped). DecCBOR t => Decode w t
From {- fvAddrsRew -}
          forall (w1 :: Wrapped) a t (w :: Density).
Decode w1 (a -> t) -> Decode ('Closed w) a -> Decode w1 t
<! forall t (w :: Wrapped). DecCBOR t => Decode w t
From {- fvTotalStake -}
          forall (w1 :: Wrapped) a t (w :: Density).
Decode w1 (a -> t) -> Decode ('Closed w) a -> Decode w1 t
<! forall t (w :: Wrapped). DecCBOR t => Decode w t
From {- fvProtver -}
          forall (w1 :: Wrapped) a t (w :: Density).
Decode w1 (a -> t) -> Decode ('Closed w) a -> Decode w1 t
<! forall t (w :: Wrapped). DecCBOR t => Decode w t
From {- fvPoolRewardInfo -}
      )

-- =====================================================================

-- | The function to call on each reward update pulse. Called by the pulser.
rewardStakePoolMember ::
  FreeVars c ->
  RewardAns c ->
  Credential 'Staking c ->
  CompactForm Coin ->
  RewardAns c
rewardStakePoolMember :: forall c.
FreeVars c
-> RewardAns c
-> Credential 'Staking c
-> CompactForm Coin
-> RewardAns c
rewardStakePoolMember
  FreeVars
    { VMap VB VB (Credential 'Staking c) (KeyHash 'StakePool c)
fvDelegs :: VMap VB VB (Credential 'Staking c) (KeyHash 'StakePool c)
fvDelegs :: forall c.
FreeVars c
-> VMap VB VB (Credential 'Staking c) (KeyHash 'StakePool c)
fvDelegs
    , Set (Credential 'Staking c)
fvAddrsRew :: Set (Credential 'Staking c)
fvAddrsRew :: forall c. FreeVars c -> Set (Credential 'Staking c)
fvAddrsRew
    , Coin
fvTotalStake :: Coin
fvTotalStake :: forall c. FreeVars c -> Coin
fvTotalStake
    , Map (KeyHash 'StakePool c) (PoolRewardInfo c)
fvPoolRewardInfo :: Map (KeyHash 'StakePool c) (PoolRewardInfo c)
fvPoolRewardInfo :: forall c.
FreeVars c -> Map (KeyHash 'StakePool c) (PoolRewardInfo c)
fvPoolRewardInfo
    , ProtVer
fvProtVer :: ProtVer
fvProtVer :: forall c. FreeVars c -> ProtVer
fvProtVer
    }
  inputanswer :: RewardAns c
inputanswer@(RewardAns Map (Credential 'Staking c) (Reward c)
accum RewardEvent c
recent)
  Credential 'Staking c
cred
  CompactForm Coin
c = forall a. a -> Maybe a -> a
fromMaybe RewardAns c
inputanswer forall a b. (a -> b) -> a -> b
$ do
    KeyHash 'StakePool c
poolID <- forall k (kv :: * -> *) (vv :: * -> *) v.
(Ord k, Vector kv k, Vector vv v) =>
k -> VMap kv vv k v -> Maybe v
VMap.lookup Credential 'Staking c
cred VMap VB VB (Credential 'Staking c) (KeyHash 'StakePool c)
fvDelegs
    PoolRewardInfo c
poolRI <- forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup KeyHash 'StakePool c
poolID Map (KeyHash 'StakePool c) (PoolRewardInfo c)
fvPoolRewardInfo
    Coin
r <- forall c.
ProtVer
-> Coin
-> Set (Credential 'Staking c)
-> PoolRewardInfo c
-> Credential 'Staking c
-> Coin
-> Maybe Coin
rewardOnePoolMember ProtVer
fvProtVer Coin
fvTotalStake Set (Credential 'Staking c)
fvAddrsRew PoolRewardInfo c
poolRI Credential 'Staking c
cred (forall a. Compactible a => CompactForm a -> a
fromCompact CompactForm Coin
c)
    let ans :: Reward c
ans = forall c. RewardType -> KeyHash 'StakePool c -> Coin -> Reward c
Reward RewardType
MemberReward KeyHash 'StakePool c
poolID Coin
r
    -- There is always just 1 member reward, so Set.singleton is appropriate
    forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall c.
Map (Credential 'Staking c) (Reward c)
-> RewardEvent c -> RewardAns c
RewardAns (forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert Credential 'Staking c
cred Reward c
ans Map (Credential 'Staking c) (Reward c)
accum) (forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert Credential 'Staking c
cred (forall a. a -> Set a
Set.singleton Reward c
ans) RewardEvent c
recent)

-- ================================================================

-- | The type of a Pulser which uses 'rewardStakePoolMember' as its underlying function.
--     'rewardStakePool' will be partially applied to the component of type
--     (FreeVars c) when pulsing. Note that we use two type equality (~) constraints
--     to fix both the monad 'm' and the 'ans' type, to the context where we will use
--     the type as a Pulser. The type must have 'm' and 'ans' as its last two
--     parameters so we can make a Pulsable instance.
--     RSLP = Reward Serializable Listbased Pulser
data RewardPulser c (m :: Type -> Type) ans where
  RSLP ::
    (ans ~ RewardAns c, m ~ ShelleyBase) =>
    !Int ->
    !(FreeVars c) ->
    !(VMap.VMap VMap.VB VMap.VP (Credential 'Staking c) (CompactForm Coin)) ->
    !ans ->
    RewardPulser c m ans

-- Because of the constraints on the Constructor RSLP, there is really only one inhabited
-- type:  (RewardPulser c ShelleyBase (RewardAns c))
-- All of the instances are at that type. Though only the CBOR instances need make that explicit.

clearRecent :: RewardAns c -> RewardAns c
clearRecent :: forall c. RewardAns c -> RewardAns c
clearRecent (RewardAns Map (Credential 'Staking c) (Reward c)
accum RewardEvent c
_) = forall c.
Map (Credential 'Staking c) (Reward c)
-> RewardEvent c -> RewardAns c
RewardAns Map (Credential 'Staking c) (Reward c)
accum forall k a. Map k a
Map.empty

instance Pulsable (RewardPulser c) where
  done :: forall (m :: * -> *) ans. RewardPulser c m ans -> Bool
done (RSLP Int
_n FreeVars c
_free VMap VB VP (Credential 'Staking c) (CompactForm Coin)
zs ans
_ans) = forall (vv :: * -> *) v (kv :: * -> *) k.
(Vector vv v, Vector kv k) =>
VMap kv vv k v -> Bool
VMap.null VMap VB VP (Credential 'Staking c) (CompactForm Coin)
zs
  current :: forall (m :: * -> *) ans. RewardPulser c m ans -> ans
current (RSLP Int
_ FreeVars c
_ VMap VB VP (Credential 'Staking c) (CompactForm Coin)
_ ans
ans) = ans
ans
  pulseM :: forall (m :: * -> *) ans.
Monad m =>
RewardPulser c m ans -> m (RewardPulser c m ans)
pulseM p :: RewardPulser c m ans
p@(RSLP Int
n FreeVars c
free VMap VB VP (Credential 'Staking c) (CompactForm Coin)
balance (forall c. RewardAns c -> RewardAns c
clearRecent -> RewardAns c
ans)) =
    if forall (vv :: * -> *) v (kv :: * -> *) k.
(Vector vv v, Vector kv k) =>
VMap kv vv k v -> Bool
VMap.null VMap VB VP (Credential 'Staking c) (CompactForm Coin)
balance
      then forall (f :: * -> *) a. Applicative f => a -> f a
pure RewardPulser c m ans
p
      else do
        let !(VMap VB VP (Credential 'Staking c) (CompactForm Coin)
steps, !VMap VB VP (Credential 'Staking c) (CompactForm Coin)
balance') = forall (vv :: * -> *) v (kv :: * -> *) k.
(Vector vv v, Vector kv k) =>
Int -> VMap kv vv k v -> (VMap kv vv k v, VMap kv vv k v)
VMap.splitAt Int
n VMap VB VP (Credential 'Staking c) (CompactForm Coin)
balance
            ans' :: RewardAns c
ans' = forall (kv :: * -> *) k (vv :: * -> *) v a.
(Vector kv k, Vector vv v) =>
(a -> k -> v -> a) -> a -> VMap kv vv k v -> a
VMap.foldlWithKey (forall c.
FreeVars c
-> RewardAns c
-> Credential 'Staking c
-> CompactForm Coin
-> RewardAns c
rewardStakePoolMember FreeVars c
free) RewardAns c
ans VMap VB VP (Credential 'Staking c) (CompactForm Coin)
steps
        forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$! forall ans c (m :: * -> *).
(ans ~ RewardAns c, m ~ ShelleyBase) =>
Int
-> FreeVars c
-> VMap VB VP (Credential 'Staking c) (CompactForm Coin)
-> ans
-> RewardPulser c m ans
RSLP Int
n FreeVars c
free VMap VB VP (Credential 'Staking c) (CompactForm Coin)
balance' RewardAns c
ans'
  completeM :: forall (m :: * -> *) ans. Monad m => RewardPulser c m ans -> m ans
completeM (RSLP Int
_ FreeVars c
free VMap VB VP (Credential 'Staking c) (CompactForm Coin)
balance (forall c. RewardAns c -> RewardAns c
clearRecent -> RewardAns c
ans)) =
    forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall (kv :: * -> *) k (vv :: * -> *) v a.
(Vector kv k, Vector vv v) =>
(a -> k -> v -> a) -> a -> VMap kv vv k v -> a
VMap.foldlWithKey (forall c.
FreeVars c
-> RewardAns c
-> Credential 'Staking c
-> CompactForm Coin
-> RewardAns c
rewardStakePoolMember FreeVars c
free) RewardAns c
ans VMap VB VP (Credential 'Staking c) (CompactForm Coin)
balance

deriving instance Eq ans => Eq (RewardPulser c m ans)

deriving instance Show ans => Show (RewardPulser c m ans)

instance Typeable c => NoThunks (Pulser c) where
  showTypeOf :: Proxy (Pulser c) -> String
showTypeOf Proxy (Pulser c)
_ = String
"RewardPulser"
  wNoThunks :: Context -> Pulser c -> IO (Maybe ThunkInfo)
wNoThunks Context
ctxt (RSLP Int
n FreeVars c
free VMap VB VP (Credential 'Staking c) (CompactForm Coin)
balance RewardAns c
ans) =
    [IO (Maybe ThunkInfo)] -> IO (Maybe ThunkInfo)
allNoThunks
      [ forall a. NoThunks a => Context -> a -> IO (Maybe ThunkInfo)
noThunks Context
ctxt Int
n
      , forall a. NoThunks a => Context -> a -> IO (Maybe ThunkInfo)
noThunks Context
ctxt FreeVars c
free
      , forall a. NoThunks a => Context -> a -> IO (Maybe ThunkInfo)
noThunks Context
ctxt VMap VB VP (Credential 'Staking c) (CompactForm Coin)
balance
      , forall a. NoThunks a => Context -> a -> IO (Maybe ThunkInfo)
noThunks Context
ctxt RewardAns c
ans
      ]

instance NFData (Pulser c) where
  rnf :: Pulser c -> ()
rnf (RSLP Int
n1 FreeVars c
c1 VMap VB VP (Credential 'Staking c) (CompactForm Coin)
b1 RewardAns c
a1) = seq :: forall a b. a -> b -> b
seq (forall a. NFData a => a -> ()
rnf Int
n1) (seq :: forall a b. a -> b -> b
seq (forall a. NFData a => a -> ()
rnf FreeVars c
c1) (seq :: forall a b. a -> b -> b
seq (forall a. NFData a => a -> ()
rnf VMap VB VP (Credential 'Staking c) (CompactForm Coin)
b1) (forall a. NFData a => a -> ()
rnf RewardAns c
a1)))

instance Crypto c => EncCBOR (Pulser c) where
  encCBOR :: Pulser c -> Encoding
encCBOR (RSLP Int
n FreeVars c
free VMap VB VP (Credential 'Staking c) (CompactForm Coin)
balance RewardAns c
ans) =
    forall (w :: Wrapped) t. Encode w t -> Encoding
encode (forall t. t -> Encode ('Closed 'Dense) t
Rec forall ans c (m :: * -> *).
(ans ~ RewardAns c, m ~ ShelleyBase) =>
Int
-> FreeVars c
-> VMap VB VP (Credential 'Staking c) (CompactForm Coin)
-> ans
-> RewardPulser c m ans
RSLP forall (w :: Wrapped) a t (r :: Density).
Encode w (a -> t) -> Encode ('Closed r) a -> Encode w t
!> forall t. EncCBOR t => t -> Encode ('Closed 'Dense) t
To Int
n forall (w :: Wrapped) a t (r :: Density).
Encode w (a -> t) -> Encode ('Closed r) a -> Encode w t
!> forall t. EncCBOR t => t -> Encode ('Closed 'Dense) t
To FreeVars c
free forall (w :: Wrapped) a t (r :: Density).
Encode w (a -> t) -> Encode ('Closed r) a -> Encode w t
!> forall t. EncCBOR t => t -> Encode ('Closed 'Dense) t
To VMap VB VP (Credential 'Staking c) (CompactForm Coin)
balance forall (w :: Wrapped) a t (r :: Density).
Encode w (a -> t) -> Encode ('Closed r) a -> Encode w t
!> forall t. EncCBOR t => t -> Encode ('Closed 'Dense) t
To RewardAns c
ans)

instance Crypto c => DecCBOR (Pulser c) where
  decCBOR :: forall s. Decoder s (Pulser c)
decCBOR =
    forall (w :: Wrapped) t s. Decode w t -> Decoder s t
decode (forall t. t -> Decode ('Closed 'Dense) t
RecD forall ans c (m :: * -> *).
(ans ~ RewardAns c, m ~ ShelleyBase) =>
Int
-> FreeVars c
-> VMap VB VP (Credential 'Staking c) (CompactForm Coin)
-> ans
-> RewardPulser c m ans
RSLP forall (w1 :: Wrapped) a t (w :: Density).
Decode w1 (a -> t) -> Decode ('Closed w) a -> Decode w1 t
<! forall t (w :: Wrapped). DecCBOR t => Decode w t
From forall (w1 :: Wrapped) a t (w :: Density).
Decode w1 (a -> t) -> Decode ('Closed w) a -> Decode w1 t
<! forall t (w :: Wrapped). DecCBOR t => Decode w t
From forall (w1 :: Wrapped) a t (w :: Density).
Decode w1 (a -> t) -> Decode ('Closed w) a -> Decode w1 t
<! forall t (w :: Wrapped). DecCBOR t => Decode w t
From forall (w1 :: Wrapped) a t (w :: Density).
Decode w1 (a -> t) -> Decode ('Closed w) a -> Decode w1 t
<! forall t (w :: Wrapped). DecCBOR t => Decode w t
From)

-- =========================================================================

-- | The state used in the STS rules
data PulsingRewUpdate c
  = Pulsing !(RewardSnapShot c) !(Pulser c) -- Pulsing work still to do
  | Complete !(RewardUpdate c) -- Pulsing work completed, ultimate goal reached
  deriving (PulsingRewUpdate c -> PulsingRewUpdate c -> Bool
forall c. PulsingRewUpdate c -> PulsingRewUpdate c -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PulsingRewUpdate c -> PulsingRewUpdate c -> Bool
$c/= :: forall c. PulsingRewUpdate c -> PulsingRewUpdate c -> Bool
== :: PulsingRewUpdate c -> PulsingRewUpdate c -> Bool
$c== :: forall c. PulsingRewUpdate c -> PulsingRewUpdate c -> Bool
Eq, Int -> PulsingRewUpdate c -> ShowS
forall c. Int -> PulsingRewUpdate c -> ShowS
forall c. [PulsingRewUpdate c] -> ShowS
forall c. PulsingRewUpdate c -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PulsingRewUpdate c] -> ShowS
$cshowList :: forall c. [PulsingRewUpdate c] -> ShowS
show :: PulsingRewUpdate c -> String
$cshow :: forall c. PulsingRewUpdate c -> String
showsPrec :: Int -> PulsingRewUpdate c -> ShowS
$cshowsPrec :: forall c. Int -> PulsingRewUpdate c -> ShowS
Show, forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall c x. Rep (PulsingRewUpdate c) x -> PulsingRewUpdate c
forall c x. PulsingRewUpdate c -> Rep (PulsingRewUpdate c) x
$cto :: forall c x. Rep (PulsingRewUpdate c) x -> PulsingRewUpdate c
$cfrom :: forall c x. PulsingRewUpdate c -> Rep (PulsingRewUpdate c) x
Generic, forall c.
Typeable c =>
Context -> PulsingRewUpdate c -> IO (Maybe ThunkInfo)
forall c. Typeable c => Proxy (PulsingRewUpdate c) -> String
forall a.
(Context -> a -> IO (Maybe ThunkInfo))
-> (Context -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> String)
-> NoThunks a
showTypeOf :: Proxy (PulsingRewUpdate c) -> String
$cshowTypeOf :: forall c. Typeable c => Proxy (PulsingRewUpdate c) -> String
wNoThunks :: Context -> PulsingRewUpdate c -> IO (Maybe ThunkInfo)
$cwNoThunks :: forall c.
Typeable c =>
Context -> PulsingRewUpdate c -> IO (Maybe ThunkInfo)
noThunks :: Context -> PulsingRewUpdate c -> IO (Maybe ThunkInfo)
$cnoThunks :: forall c.
Typeable c =>
Context -> PulsingRewUpdate c -> IO (Maybe ThunkInfo)
NoThunks)

instance Crypto c => EncCBOR (PulsingRewUpdate c) where
  encCBOR :: PulsingRewUpdate c -> Encoding
encCBOR (Pulsing RewardSnapShot c
s Pulser c
p) = forall (w :: Wrapped) t. Encode w t -> Encoding
encode (forall t. t -> Word -> Encode 'Open t
Sum forall c. RewardSnapShot c -> Pulser c -> PulsingRewUpdate c
Pulsing Word
0 forall (w :: Wrapped) a t (r :: Density).
Encode w (a -> t) -> Encode ('Closed r) a -> Encode w t
!> forall t. EncCBOR t => t -> Encode ('Closed 'Dense) t
To RewardSnapShot c
s forall (w :: Wrapped) a t (r :: Density).
Encode w (a -> t) -> Encode ('Closed r) a -> Encode w t
!> forall t. EncCBOR t => t -> Encode ('Closed 'Dense) t
To Pulser c
p)
  encCBOR (Complete RewardUpdate c
r) = forall (w :: Wrapped) t. Encode w t -> Encoding
encode (forall t. t -> Word -> Encode 'Open t
Sum forall c. RewardUpdate c -> PulsingRewUpdate c
Complete Word
1 forall (w :: Wrapped) a t (r :: Density).
Encode w (a -> t) -> Encode ('Closed r) a -> Encode w t
!> forall t. EncCBOR t => t -> Encode ('Closed 'Dense) t
To RewardUpdate c
r)

instance Crypto c => DecCBOR (PulsingRewUpdate c) where
  decCBOR :: forall s. Decoder s (PulsingRewUpdate c)
decCBOR = forall (w :: Wrapped) t s. Decode w t -> Decoder s t
decode (forall t.
Text -> (Word -> Decode 'Open t) -> Decode ('Closed 'Dense) t
Summands Text
"PulsingRewUpdate" forall {c}. Crypto c => Word -> Decode 'Open (PulsingRewUpdate c)
decPS)
    where
      decPS :: Word -> Decode 'Open (PulsingRewUpdate c)
decPS Word
0 = forall t. t -> Decode 'Open t
SumD forall c. RewardSnapShot c -> Pulser c -> PulsingRewUpdate c
Pulsing forall (w1 :: Wrapped) a t (w :: Density).
Decode w1 (a -> t) -> Decode ('Closed w) a -> Decode w1 t
<! forall t (w :: Wrapped). DecCBOR t => Decode w t
From forall (w1 :: Wrapped) a t (w :: Density).
Decode w1 (a -> t) -> Decode ('Closed w) a -> Decode w1 t
<! forall t (w :: Wrapped). DecCBOR t => Decode w t
From
      decPS Word
1 = forall t. t -> Decode 'Open t
SumD forall c. RewardUpdate c -> PulsingRewUpdate c
Complete forall (w1 :: Wrapped) a t (w :: Density).
Decode w1 (a -> t) -> Decode ('Closed w) a -> Decode w1 t
<! forall t (w :: Wrapped). DecCBOR t => Decode w t
From
      decPS Word
n = forall (w :: Wrapped) t. Word -> Decode w t
Invalid Word
n

instance NFData (PulsingRewUpdate c)

instance Crypto c => ToJSON (PulsingRewUpdate c) where
  toJSON :: PulsingRewUpdate c -> Value
toJSON = \case
    Pulsing RewardSnapShot c
_ Pulser c
_ -> Value
Null
    Complete RewardUpdate c
ru -> forall a. ToJSON a => a -> Value
toJSON RewardUpdate c
ru
  toEncoding :: PulsingRewUpdate c -> Encoding
toEncoding = \case
    Pulsing RewardSnapShot c
_ Pulser c
_ -> forall a. ToJSON a => a -> Encoding
toEncoding Value
Null
    Complete RewardUpdate c
ru -> forall a. ToJSON a => a -> Encoding
toEncoding RewardUpdate c
ru