{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
{-# OPTIONS_GHC -Wno-orphans #-}
module Cardano.Ledger.Shelley.Rules.Deleg (
ShelleyDELEG,
DelegEnv (..),
PredicateFailure,
ShelleyDelegPredFailure (..),
ShelleyDelegEvent (..),
)
where
import Cardano.Ledger.BaseTypes (
EpochInterval (..),
Globals (..),
Mismatch (..),
Relation (..),
ShelleyBase,
StrictMaybe (..),
addEpochInterval,
epochInfoPure,
invalidKey,
)
import Cardano.Ledger.Binary (
DecCBOR (..),
EncCBOR (..),
decodeRecordSum,
encodeListLen,
)
import Cardano.Ledger.Coin (Coin (..), DeltaCoin (..), addDeltaCoin, toDeltaCoin)
import Cardano.Ledger.Credential (Credential, Ptr)
import Cardano.Ledger.Hashes (GenDelegPair (..), GenDelegs (..))
import Cardano.Ledger.Shelley.Core
import Cardano.Ledger.Shelley.Era (ShelleyDELEG, ShelleyEra)
import Cardano.Ledger.Shelley.HardForks as HardForks (allowMIRTransfer)
import Cardano.Ledger.Shelley.LedgerState (
AccountState (..),
DState (..),
FutureGenDeleg (..),
InstantaneousRewards (..),
availableAfterMIR,
delegations,
dsFutureGenDelegs,
dsGenDelegs,
dsIRewards,
rewards,
)
import Cardano.Ledger.Slot (
Duration (..),
EpochNo (..),
SlotNo,
epochInfoFirst,
(*-),
(+*),
)
import Cardano.Ledger.UMap (RDPair (..), UView (..), compactCoinOrError)
import qualified Cardano.Ledger.UMap as UM
import Control.DeepSeq
import Control.Monad (guard)
import Control.Monad.Trans.Reader (asks)
import Control.SetAlgebra (eval, range, singleton, (∉), (∪), (⨃))
import Control.State.Transition
import Data.Foldable (fold)
import Data.Group (Group (..))
import qualified Data.Map.Strict as Map
import Data.Maybe (isJust)
import qualified Data.Set as Set
import Data.Typeable (Typeable)
import Data.Word (Word8)
import GHC.Generics (Generic)
import Lens.Micro ((^.))
import NoThunks.Class (NoThunks (..))
data DelegEnv era = DelegEnv
{ forall era. DelegEnv era -> SlotNo
slotNo :: !SlotNo
, forall era. DelegEnv era -> EpochNo
deCurEpochNo :: EpochNo
, forall era. DelegEnv era -> Ptr
ptr_ :: !Ptr
, forall era. DelegEnv era -> AccountState
acnt_ :: !AccountState
, forall era. DelegEnv era -> PParams era
ppDE :: !(PParams era)
}
deriving (forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall era x. Rep (DelegEnv era) x -> DelegEnv era
forall era x. DelegEnv era -> Rep (DelegEnv era) x
$cto :: forall era x. Rep (DelegEnv era) x -> DelegEnv era
$cfrom :: forall era x. DelegEnv era -> Rep (DelegEnv era) x
Generic)
deriving instance Show (PParams era) => Show (DelegEnv era)
deriving instance Eq (PParams era) => Eq (DelegEnv era)
instance NFData (PParams era) => NFData (DelegEnv era)
data ShelleyDelegPredFailure era
= StakeKeyAlreadyRegisteredDELEG
!(Credential 'Staking)
| StakeKeyNotRegisteredDELEG
!(Credential 'Staking)
| StakeKeyNonZeroAccountBalanceDELEG
!Coin
| StakeDelegationImpossibleDELEG
!(Credential 'Staking)
| WrongCertificateTypeDELEG
| GenesisKeyNotInMappingDELEG
!(KeyHash 'Genesis)
| DuplicateGenesisDelegateDELEG
!(KeyHash 'GenesisDelegate)
| InsufficientForInstantaneousRewardsDELEG
!MIRPot
!(Mismatch 'RelLTEQ Coin)
| MIRCertificateTooLateinEpochDELEG
!(Mismatch 'RelLT SlotNo)
| DuplicateGenesisVRFDELEG
!(VRFVerKeyHash 'GenDelegVRF)
| MIRTransferNotCurrentlyAllowed
| MIRNegativesNotCurrentlyAllowed
| InsufficientForTransferDELEG
!MIRPot
!(Mismatch 'RelLTEQ Coin)
| MIRProducesNegativeUpdate
| MIRNegativeTransfer
!MIRPot
!Coin
deriving (Int -> ShelleyDelegPredFailure era -> ShowS
forall era. Int -> ShelleyDelegPredFailure era -> ShowS
forall era. [ShelleyDelegPredFailure era] -> ShowS
forall era. ShelleyDelegPredFailure era -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ShelleyDelegPredFailure era] -> ShowS
$cshowList :: forall era. [ShelleyDelegPredFailure era] -> ShowS
show :: ShelleyDelegPredFailure era -> String
$cshow :: forall era. ShelleyDelegPredFailure era -> String
showsPrec :: Int -> ShelleyDelegPredFailure era -> ShowS
$cshowsPrec :: forall era. Int -> ShelleyDelegPredFailure era -> ShowS
Show, ShelleyDelegPredFailure era -> ShelleyDelegPredFailure era -> Bool
forall era.
ShelleyDelegPredFailure era -> ShelleyDelegPredFailure era -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ShelleyDelegPredFailure era -> ShelleyDelegPredFailure era -> Bool
$c/= :: forall era.
ShelleyDelegPredFailure era -> ShelleyDelegPredFailure era -> Bool
== :: ShelleyDelegPredFailure era -> ShelleyDelegPredFailure era -> Bool
$c== :: forall era.
ShelleyDelegPredFailure era -> ShelleyDelegPredFailure era -> Bool
Eq, forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall era x.
Rep (ShelleyDelegPredFailure era) x -> ShelleyDelegPredFailure era
forall era x.
ShelleyDelegPredFailure era -> Rep (ShelleyDelegPredFailure era) x
$cto :: forall era x.
Rep (ShelleyDelegPredFailure era) x -> ShelleyDelegPredFailure era
$cfrom :: forall era x.
ShelleyDelegPredFailure era -> Rep (ShelleyDelegPredFailure era) x
Generic)
type instance EraRuleFailure "DELEG" ShelleyEra = ShelleyDelegPredFailure ShelleyEra
instance InjectRuleFailure "DELEG" ShelleyDelegPredFailure ShelleyEra
newtype ShelleyDelegEvent era = DelegNewEpoch EpochNo
deriving (forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall era x.
Rep (ShelleyDelegEvent era) x -> ShelleyDelegEvent era
forall era x.
ShelleyDelegEvent era -> Rep (ShelleyDelegEvent era) x
$cto :: forall era x.
Rep (ShelleyDelegEvent era) x -> ShelleyDelegEvent era
$cfrom :: forall era x.
ShelleyDelegEvent era -> Rep (ShelleyDelegEvent era) x
Generic, ShelleyDelegEvent era -> ShelleyDelegEvent era -> Bool
forall era. ShelleyDelegEvent era -> ShelleyDelegEvent era -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ShelleyDelegEvent era -> ShelleyDelegEvent era -> Bool
$c/= :: forall era. ShelleyDelegEvent era -> ShelleyDelegEvent era -> Bool
== :: ShelleyDelegEvent era -> ShelleyDelegEvent era -> Bool
$c== :: forall era. ShelleyDelegEvent era -> ShelleyDelegEvent era -> Bool
Eq)
instance NFData (ShelleyDelegEvent era)
instance (EraPParams era, ShelleyEraTxCert era, ProtVerAtMost era 8) => STS (ShelleyDELEG era) where
type State (ShelleyDELEG era) = DState era
type Signal (ShelleyDELEG era) = TxCert era
type Environment (ShelleyDELEG era) = DelegEnv era
type BaseM (ShelleyDELEG era) = ShelleyBase
type PredicateFailure (ShelleyDELEG era) = ShelleyDelegPredFailure era
type Event (ShelleyDELEG era) = ShelleyDelegEvent era
transitionRules :: [TransitionRule (ShelleyDELEG era)]
transitionRules = [forall era.
(ShelleyEraTxCert era, EraPParams era, ProtVerAtMost era 8) =>
TransitionRule (ShelleyDELEG era)
delegationTransition]
instance NoThunks (ShelleyDelegPredFailure era)
instance NFData (ShelleyDelegPredFailure era)
instance
(Era era, Typeable (Script era)) =>
EncCBOR (ShelleyDelegPredFailure era)
where
encCBOR :: ShelleyDelegPredFailure era -> Encoding
encCBOR = \case
StakeKeyAlreadyRegisteredDELEG Credential 'Staking
cred ->
Word -> Encoding
encodeListLen Word
2 forall a. Semigroup a => a -> a -> a
<> forall a. EncCBOR a => a -> Encoding
encCBOR (Word8
0 :: Word8) forall a. Semigroup a => a -> a -> a
<> forall a. EncCBOR a => a -> Encoding
encCBOR Credential 'Staking
cred
StakeKeyNotRegisteredDELEG Credential 'Staking
cred ->
Word -> Encoding
encodeListLen Word
2 forall a. Semigroup a => a -> a -> a
<> forall a. EncCBOR a => a -> Encoding
encCBOR (Word8
1 :: Word8) forall a. Semigroup a => a -> a -> a
<> forall a. EncCBOR a => a -> Encoding
encCBOR Credential 'Staking
cred
StakeKeyNonZeroAccountBalanceDELEG Coin
rewardBalance ->
Word -> Encoding
encodeListLen Word
2 forall a. Semigroup a => a -> a -> a
<> forall a. EncCBOR a => a -> Encoding
encCBOR (Word8
2 :: Word8) forall a. Semigroup a => a -> a -> a
<> forall a. EncCBOR a => a -> Encoding
encCBOR Coin
rewardBalance
StakeDelegationImpossibleDELEG Credential 'Staking
cred ->
Word -> Encoding
encodeListLen Word
2 forall a. Semigroup a => a -> a -> a
<> forall a. EncCBOR a => a -> Encoding
encCBOR (Word8
3 :: Word8) forall a. Semigroup a => a -> a -> a
<> forall a. EncCBOR a => a -> Encoding
encCBOR Credential 'Staking
cred
ShelleyDelegPredFailure era
WrongCertificateTypeDELEG ->
Word -> Encoding
encodeListLen Word
1 forall a. Semigroup a => a -> a -> a
<> forall a. EncCBOR a => a -> Encoding
encCBOR (Word8
4 :: Word8)
GenesisKeyNotInMappingDELEG KeyHash 'Genesis
gkh ->
Word -> Encoding
encodeListLen Word
2 forall a. Semigroup a => a -> a -> a
<> forall a. EncCBOR a => a -> Encoding
encCBOR (Word8
5 :: Word8) forall a. Semigroup a => a -> a -> a
<> forall a. EncCBOR a => a -> Encoding
encCBOR KeyHash 'Genesis
gkh
DuplicateGenesisDelegateDELEG KeyHash 'GenesisDelegate
kh ->
Word -> Encoding
encodeListLen Word
2 forall a. Semigroup a => a -> a -> a
<> forall a. EncCBOR a => a -> Encoding
encCBOR (Word8
6 :: Word8) forall a. Semigroup a => a -> a -> a
<> forall a. EncCBOR a => a -> Encoding
encCBOR KeyHash 'GenesisDelegate
kh
InsufficientForInstantaneousRewardsDELEG MIRPot
pot Mismatch 'RelLTEQ Coin
m ->
Word -> Encoding
encodeListLen Word
3
forall a. Semigroup a => a -> a -> a
<> forall a. EncCBOR a => a -> Encoding
encCBOR (Word8
7 :: Word8)
forall a. Semigroup a => a -> a -> a
<> forall a. EncCBOR a => a -> Encoding
encCBOR MIRPot
pot
forall a. Semigroup a => a -> a -> a
<> forall a. EncCBOR a => a -> Encoding
encCBOR Mismatch 'RelLTEQ Coin
m
MIRCertificateTooLateinEpochDELEG Mismatch 'RelLT SlotNo
m ->
Word -> Encoding
encodeListLen Word
2 forall a. Semigroup a => a -> a -> a
<> forall a. EncCBOR a => a -> Encoding
encCBOR (Word8
8 :: Word8) forall a. Semigroup a => a -> a -> a
<> forall a. EncCBOR a => a -> Encoding
encCBOR Mismatch 'RelLT SlotNo
m
DuplicateGenesisVRFDELEG VRFVerKeyHash 'GenDelegVRF
vrf ->
Word -> Encoding
encodeListLen Word
2 forall a. Semigroup a => a -> a -> a
<> forall a. EncCBOR a => a -> Encoding
encCBOR (Word8
9 :: Word8) forall a. Semigroup a => a -> a -> a
<> forall a. EncCBOR a => a -> Encoding
encCBOR VRFVerKeyHash 'GenDelegVRF
vrf
ShelleyDelegPredFailure era
MIRTransferNotCurrentlyAllowed ->
Word -> Encoding
encodeListLen Word
1 forall a. Semigroup a => a -> a -> a
<> forall a. EncCBOR a => a -> Encoding
encCBOR (Word8
11 :: Word8)
ShelleyDelegPredFailure era
MIRNegativesNotCurrentlyAllowed ->
Word -> Encoding
encodeListLen Word
1 forall a. Semigroup a => a -> a -> a
<> forall a. EncCBOR a => a -> Encoding
encCBOR (Word8
12 :: Word8)
InsufficientForTransferDELEG MIRPot
pot Mismatch 'RelLTEQ Coin
m ->
Word -> Encoding
encodeListLen Word
3
forall a. Semigroup a => a -> a -> a
<> forall a. EncCBOR a => a -> Encoding
encCBOR (Word8
13 :: Word8)
forall a. Semigroup a => a -> a -> a
<> forall a. EncCBOR a => a -> Encoding
encCBOR MIRPot
pot
forall a. Semigroup a => a -> a -> a
<> forall a. EncCBOR a => a -> Encoding
encCBOR Mismatch 'RelLTEQ Coin
m
ShelleyDelegPredFailure era
MIRProducesNegativeUpdate ->
Word -> Encoding
encodeListLen Word
1 forall a. Semigroup a => a -> a -> a
<> forall a. EncCBOR a => a -> Encoding
encCBOR (Word8
14 :: Word8)
MIRNegativeTransfer MIRPot
pot Coin
amt ->
Word -> Encoding
encodeListLen Word
3
forall a. Semigroup a => a -> a -> a
<> forall a. EncCBOR a => a -> Encoding
encCBOR (Word8
15 :: Word8)
forall a. Semigroup a => a -> a -> a
<> forall a. EncCBOR a => a -> Encoding
encCBOR MIRPot
pot
forall a. Semigroup a => a -> a -> a
<> forall a. EncCBOR a => a -> Encoding
encCBOR Coin
amt
instance
(Era era, Typeable (Script era)) =>
DecCBOR (ShelleyDelegPredFailure era)
where
decCBOR :: forall s. Decoder s (ShelleyDelegPredFailure era)
decCBOR = forall s a. Text -> (Word -> Decoder s (Int, a)) -> Decoder s a
decodeRecordSum Text
"ShelleyDelegPredFailure" forall a b. (a -> b) -> a -> b
$
\case
Word
0 -> do
Credential 'Staking
kh <- forall a s. DecCBOR a => Decoder s a
decCBOR
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
2, forall era. Credential 'Staking -> ShelleyDelegPredFailure era
StakeKeyAlreadyRegisteredDELEG Credential 'Staking
kh)
Word
1 -> do
Credential 'Staking
kh <- forall a s. DecCBOR a => Decoder s a
decCBOR
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
2, forall era. Credential 'Staking -> ShelleyDelegPredFailure era
StakeKeyNotRegisteredDELEG Credential 'Staking
kh)
Word
2 -> do
Coin
b <- forall a s. DecCBOR a => Decoder s a
decCBOR
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
2, forall era. Coin -> ShelleyDelegPredFailure era
StakeKeyNonZeroAccountBalanceDELEG Coin
b)
Word
3 -> do
Credential 'Staking
kh <- forall a s. DecCBOR a => Decoder s a
decCBOR
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
2, forall era. Credential 'Staking -> ShelleyDelegPredFailure era
StakeDelegationImpossibleDELEG Credential 'Staking
kh)
Word
4 -> do
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
1, forall era. ShelleyDelegPredFailure era
WrongCertificateTypeDELEG)
Word
5 -> do
KeyHash 'Genesis
gkh <- forall a s. DecCBOR a => Decoder s a
decCBOR
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
2, forall era. KeyHash 'Genesis -> ShelleyDelegPredFailure era
GenesisKeyNotInMappingDELEG KeyHash 'Genesis
gkh)
Word
6 -> do
KeyHash 'GenesisDelegate
kh <- forall a s. DecCBOR a => Decoder s a
decCBOR
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
2, forall era. KeyHash 'GenesisDelegate -> ShelleyDelegPredFailure era
DuplicateGenesisDelegateDELEG KeyHash 'GenesisDelegate
kh)
Word
7 -> do
MIRPot
pot <- forall a s. DecCBOR a => Decoder s a
decCBOR
Mismatch 'RelLTEQ Coin
m <- forall a s. DecCBOR a => Decoder s a
decCBOR
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
3, forall era.
MIRPot -> Mismatch 'RelLTEQ Coin -> ShelleyDelegPredFailure era
InsufficientForInstantaneousRewardsDELEG MIRPot
pot Mismatch 'RelLTEQ Coin
m)
Word
8 -> do
Mismatch 'RelLT SlotNo
m <- forall a s. DecCBOR a => Decoder s a
decCBOR
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
2, forall era. Mismatch 'RelLT SlotNo -> ShelleyDelegPredFailure era
MIRCertificateTooLateinEpochDELEG Mismatch 'RelLT SlotNo
m)
Word
9 -> do
VRFVerKeyHash 'GenDelegVRF
vrf <- forall a s. DecCBOR a => Decoder s a
decCBOR
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
2, forall era.
VRFVerKeyHash 'GenDelegVRF -> ShelleyDelegPredFailure era
DuplicateGenesisVRFDELEG VRFVerKeyHash 'GenDelegVRF
vrf)
Word
11 -> do
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
1, forall era. ShelleyDelegPredFailure era
MIRTransferNotCurrentlyAllowed)
Word
12 -> do
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
1, forall era. ShelleyDelegPredFailure era
MIRNegativesNotCurrentlyAllowed)
Word
13 -> do
MIRPot
pot <- forall a s. DecCBOR a => Decoder s a
decCBOR
Mismatch 'RelLTEQ Coin
m <- forall a s. DecCBOR a => Decoder s a
decCBOR
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
3, forall era.
MIRPot -> Mismatch 'RelLTEQ Coin -> ShelleyDelegPredFailure era
InsufficientForTransferDELEG MIRPot
pot Mismatch 'RelLTEQ Coin
m)
Word
14 -> do
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
1, forall era. ShelleyDelegPredFailure era
MIRProducesNegativeUpdate)
Word
15 -> do
MIRPot
pot <- forall a s. DecCBOR a => Decoder s a
decCBOR
Coin
amt <- forall a s. DecCBOR a => Decoder s a
decCBOR
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
3, forall era. MIRPot -> Coin -> ShelleyDelegPredFailure era
MIRNegativeTransfer MIRPot
pot Coin
amt)
Word
k -> forall (m :: * -> *) a. MonadFail m => Word -> m a
invalidKey Word
k
delegationTransition ::
(ShelleyEraTxCert era, EraPParams era, ProtVerAtMost era 8) =>
TransitionRule (ShelleyDELEG era)
delegationTransition :: forall era.
(ShelleyEraTxCert era, EraPParams era, ProtVerAtMost era 8) =>
TransitionRule (ShelleyDELEG era)
delegationTransition = do
TRC (DelegEnv SlotNo
slot EpochNo
epochNo Ptr
ptr AccountState
acnt PParams era
pp, State (ShelleyDELEG era)
ds, Signal (ShelleyDELEG era)
c) <- forall sts (rtype :: RuleType).
Rule sts rtype (RuleContext rtype sts)
judgmentContext
let pv :: ProtVer
pv = PParams era
pp forall s a. s -> Getting a s a -> a
^. forall era. EraPParams era => Lens' (PParams era) ProtVer
ppProtocolVersionL
case Signal (ShelleyDELEG era)
c of
RegTxCert Credential 'Staking
hk -> do
forall k v. k -> UView k v -> Bool
UM.notMember Credential 'Staking
hk (forall era. DState era -> UView (Credential 'Staking) RDPair
rewards State (ShelleyDELEG era)
ds) forall sts (ctx :: RuleType).
Bool -> PredicateFailure sts -> Rule sts ctx ()
?! forall era. Credential 'Staking -> ShelleyDelegPredFailure era
StakeKeyAlreadyRegisteredDELEG Credential 'Staking
hk
let u1 :: UMap
u1 = forall era. DState era -> UMap
dsUnified State (ShelleyDELEG era)
ds
deposit :: CompactForm Coin
deposit = HasCallStack => Coin -> CompactForm Coin
compactCoinOrError (PParams era
pp forall s a. s -> Getting a s a -> a
^. forall era. EraPParams era => Lens' (PParams era) Coin
ppKeyDepositL)
u2 :: UMap
u2 = UMap -> UView (Credential 'Staking) RDPair
RewDepUView UMap
u1 forall k v. UView k v -> (k, v) -> UMap
UM.∪ (Credential 'Staking
hk, CompactForm Coin -> CompactForm Coin -> RDPair
RDPair (Word64 -> CompactForm Coin
UM.CompactCoin Word64
0) CompactForm Coin
deposit)
u3 :: UMap
u3 = UMap -> UView Ptr (Credential 'Staking)
PtrUView UMap
u2 forall k v. UView k v -> (k, v) -> UMap
UM.∪ (Ptr
ptr, Credential 'Staking
hk)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (State (ShelleyDELEG era)
ds {dsUnified :: UMap
dsUnified = UMap
u3})
UnRegTxCert Credential 'Staking
cred -> do
let (Maybe UMElem
mUMElem, UMap
umap) = Credential 'Staking -> UMap -> (Maybe UMElem, UMap)
UM.extractStakingCredential Credential 'Staking
cred (forall era. DState era -> UMap
dsUnified State (ShelleyDELEG era)
ds)
checkStakeKeyHasZeroRewardBalance :: Maybe Coin
checkStakeKeyHasZeroRewardBalance = do
UM.UMElem (SJust RDPair
rd) Set Ptr
_ StrictMaybe (KeyHash 'StakePool)
_ StrictMaybe DRep
_ <- Maybe UMElem
mUMElem
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (RDPair -> CompactForm Coin
UM.rdReward RDPair
rd forall a. Eq a => a -> a -> Bool
/= forall a. Monoid a => a
mempty)
forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a. Compactible a => CompactForm a -> a
UM.fromCompact (RDPair -> CompactForm Coin
UM.rdReward RDPair
rd)
forall a. Maybe a -> Bool
isJust Maybe UMElem
mUMElem forall sts (ctx :: RuleType).
Bool -> PredicateFailure sts -> Rule sts ctx ()
?! forall era. Credential 'Staking -> ShelleyDelegPredFailure era
StakeKeyNotRegisteredDELEG Credential 'Staking
cred
forall a sts (ctx :: RuleType).
Maybe a -> (a -> PredicateFailure sts) -> Rule sts ctx ()
failOnJust Maybe Coin
checkStakeKeyHasZeroRewardBalance forall era. Coin -> ShelleyDelegPredFailure era
StakeKeyNonZeroAccountBalanceDELEG
forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ State (ShelleyDELEG era)
ds {dsUnified :: UMap
dsUnified = UMap
umap}
DelegStakeTxCert Credential 'Staking
hk KeyHash 'StakePool
dpool -> do
forall k v. k -> UView k v -> Bool
UM.member Credential 'Staking
hk (forall era. DState era -> UView (Credential 'Staking) RDPair
rewards State (ShelleyDELEG era)
ds) forall sts (ctx :: RuleType).
Bool -> PredicateFailure sts -> Rule sts ctx ()
?! forall era. Credential 'Staking -> ShelleyDelegPredFailure era
StakeDelegationImpossibleDELEG Credential 'Staking
hk
forall (f :: * -> *) a. Applicative f => a -> f a
pure (State (ShelleyDELEG era)
ds {dsUnified :: UMap
dsUnified = forall era.
DState era -> UView (Credential 'Staking) (KeyHash 'StakePool)
delegations State (ShelleyDELEG era)
ds forall k v. UView k v -> Map k v -> UMap
UM.⨃ forall k a. k -> a -> Map k a
Map.singleton Credential 'Staking
hk KeyHash 'StakePool
dpool})
GenesisDelegTxCert KeyHash 'Genesis
gkh KeyHash 'GenesisDelegate
vkh VRFVerKeyHash 'GenDelegVRF
vrf -> do
Word64
sp <- forall sts a (ctx :: RuleType).
STS sts =>
BaseM sts a -> Rule sts ctx a
liftSTS forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) r a. Monad m => (r -> a) -> ReaderT r m a
asks Globals -> Word64
stabilityWindow
let s' :: SlotNo
s' = SlotNo
slot SlotNo -> Duration -> SlotNo
+* Word64 -> Duration
Duration Word64
sp
GenDelegs Map (KeyHash 'Genesis) GenDelegPair
genDelegs = forall era. DState era -> GenDelegs
dsGenDelegs State (ShelleyDELEG era)
ds
forall a. Maybe a -> Bool
isJust (forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup KeyHash 'Genesis
gkh Map (KeyHash 'Genesis) GenDelegPair
genDelegs) forall sts (ctx :: RuleType).
Bool -> PredicateFailure sts -> Rule sts ctx ()
?! forall era. KeyHash 'Genesis -> ShelleyDelegPredFailure era
GenesisKeyNotInMappingDELEG KeyHash 'Genesis
gkh
let cod :: Set GenDelegPair
cod = forall (f :: * -> * -> *) v k. (Basic f, Ord v) => f k v -> Set v
range forall a b. (a -> b) -> a -> b
$ forall k a. Ord k => k -> Map k a -> Map k a
Map.delete KeyHash 'Genesis
gkh Map (KeyHash 'Genesis) GenDelegPair
genDelegs
fod :: Set GenDelegPair
fod =
forall (f :: * -> * -> *) v k. (Basic f, Ord v) => f k v -> Set v
range forall a b. (a -> b) -> a -> b
$
forall k a. (k -> a -> Bool) -> Map k a -> Map k a
Map.filterWithKey (\(FutureGenDeleg SlotNo
_ KeyHash 'Genesis
g) GenDelegPair
_ -> KeyHash 'Genesis
g forall a. Eq a => a -> a -> Bool
/= KeyHash 'Genesis
gkh) (forall era. DState era -> Map FutureGenDeleg GenDelegPair
dsFutureGenDelegs State (ShelleyDELEG era)
ds)
currentOtherColdKeyHashes :: Set (KeyHash 'GenesisDelegate)
currentOtherColdKeyHashes = forall b a. Ord b => (a -> b) -> Set a -> Set b
Set.map GenDelegPair -> KeyHash 'GenesisDelegate
genDelegKeyHash Set GenDelegPair
cod
currentOtherVrfKeyHashes :: Set (VRFVerKeyHash 'GenDelegVRF)
currentOtherVrfKeyHashes = forall b a. Ord b => (a -> b) -> Set a -> Set b
Set.map GenDelegPair -> VRFVerKeyHash 'GenDelegVRF
genDelegVrfHash Set GenDelegPair
cod
futureOtherColdKeyHashes :: Set (KeyHash 'GenesisDelegate)
futureOtherColdKeyHashes = forall b a. Ord b => (a -> b) -> Set a -> Set b
Set.map GenDelegPair -> KeyHash 'GenesisDelegate
genDelegKeyHash Set GenDelegPair
fod
futureOtherVrfKeyHashes :: Set (VRFVerKeyHash 'GenDelegVRF)
futureOtherVrfKeyHashes = forall b a. Ord b => (a -> b) -> Set a -> Set b
Set.map GenDelegPair -> VRFVerKeyHash 'GenDelegVRF
genDelegVrfHash Set GenDelegPair
fod
forall s t. Embed s t => Exp t -> s
eval (KeyHash 'GenesisDelegate
vkh forall k (g :: * -> * -> *) s.
(Show k, Ord k, Iter g, HasExp s (g k ())) =>
k -> s -> Exp Bool
∉ (Set (KeyHash 'GenesisDelegate)
currentOtherColdKeyHashes forall k v s1 (f :: * -> * -> *) s2 (g :: * -> * -> *).
(Show k, Show v, Ord k, HasExp s1 (f k v), HasExp s2 (g k v)) =>
s1 -> s2 -> Exp (f k v)
∪ Set (KeyHash 'GenesisDelegate)
futureOtherColdKeyHashes))
forall sts (ctx :: RuleType).
Bool -> PredicateFailure sts -> Rule sts ctx ()
?! forall era. KeyHash 'GenesisDelegate -> ShelleyDelegPredFailure era
DuplicateGenesisDelegateDELEG KeyHash 'GenesisDelegate
vkh
forall s t. Embed s t => Exp t -> s
eval (VRFVerKeyHash 'GenDelegVRF
vrf forall k (g :: * -> * -> *) s.
(Show k, Ord k, Iter g, HasExp s (g k ())) =>
k -> s -> Exp Bool
∉ (Set (VRFVerKeyHash 'GenDelegVRF)
currentOtherVrfKeyHashes forall k v s1 (f :: * -> * -> *) s2 (g :: * -> * -> *).
(Show k, Show v, Ord k, HasExp s1 (f k v), HasExp s2 (g k v)) =>
s1 -> s2 -> Exp (f k v)
∪ Set (VRFVerKeyHash 'GenDelegVRF)
futureOtherVrfKeyHashes))
forall sts (ctx :: RuleType).
Bool -> PredicateFailure sts -> Rule sts ctx ()
?! forall era.
VRFVerKeyHash 'GenDelegVRF -> ShelleyDelegPredFailure era
DuplicateGenesisVRFDELEG VRFVerKeyHash 'GenDelegVRF
vrf
forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$
State (ShelleyDELEG era)
ds
{ dsFutureGenDelegs :: Map FutureGenDeleg GenDelegPair
dsFutureGenDelegs =
forall s t. Embed s t => Exp t -> s
eval (forall era. DState era -> Map FutureGenDeleg GenDelegPair
dsFutureGenDelegs State (ShelleyDELEG era)
ds forall k s1 (f :: * -> * -> *) v s2 (g :: * -> * -> *).
(Ord k, HasExp s1 (f k v), HasExp s2 (g k v)) =>
s1 -> s2 -> Exp (f k v)
⨃ forall k v. Ord k => k -> v -> Exp (Single k v)
singleton (SlotNo -> KeyHash 'Genesis -> FutureGenDeleg
FutureGenDeleg SlotNo
s' KeyHash 'Genesis
gkh) (KeyHash 'GenesisDelegate
-> VRFVerKeyHash 'GenDelegVRF -> GenDelegPair
GenDelegPair KeyHash 'GenesisDelegate
vkh VRFVerKeyHash 'GenDelegVRF
vrf))
}
RegPoolTxCert PoolParams
_ -> do
forall sts (ctx :: RuleType).
PredicateFailure sts -> Rule sts ctx ()
failBecause forall era. ShelleyDelegPredFailure era
WrongCertificateTypeDELEG
forall (f :: * -> *) a. Applicative f => a -> f a
pure State (ShelleyDELEG era)
ds
Signal (ShelleyDELEG era)
_ | Just (MIRCert MIRPot
targetPot MIRTarget
mirTarget) <- forall era.
(ShelleyEraTxCert era, ProtVerAtMost era 8) =>
TxCert era -> Maybe MIRCert
getMirTxCert Signal (ShelleyDELEG era)
c -> do
forall era.
(ShelleyEraTxCert era, EraPParams era, ProtVerAtMost era 8) =>
SlotNo -> EpochNo -> Rule (ShelleyDELEG era) 'Transition ()
checkSlotNotTooLate SlotNo
slot EpochNo
epochNo
case MIRTarget
mirTarget of
StakeAddressesMIR Map (Credential 'Staking) DeltaCoin
credCoinMap -> do
let (Coin
potAmount, DeltaCoin
delta, Map (Credential 'Staking) Coin
instantaneousRewards) =
case MIRPot
targetPot of
MIRPot
ReservesMIR ->
(AccountState -> Coin
asReserves AccountState
acnt, InstantaneousRewards -> DeltaCoin
deltaReserves forall a b. (a -> b) -> a -> b
$ forall era. DState era -> InstantaneousRewards
dsIRewards State (ShelleyDELEG era)
ds, InstantaneousRewards -> Map (Credential 'Staking) Coin
iRReserves forall a b. (a -> b) -> a -> b
$ forall era. DState era -> InstantaneousRewards
dsIRewards State (ShelleyDELEG era)
ds)
MIRPot
TreasuryMIR ->
(AccountState -> Coin
asTreasury AccountState
acnt, InstantaneousRewards -> DeltaCoin
deltaTreasury forall a b. (a -> b) -> a -> b
$ forall era. DState era -> InstantaneousRewards
dsIRewards State (ShelleyDELEG era)
ds, InstantaneousRewards -> Map (Credential 'Staking) Coin
iRTreasury forall a b. (a -> b) -> a -> b
$ forall era. DState era -> InstantaneousRewards
dsIRewards State (ShelleyDELEG era)
ds)
let credCoinMap' :: Map (Credential 'Staking) Coin
credCoinMap' = forall a b k. (a -> b) -> Map k a -> Map k b
Map.map (\(DeltaCoin Integer
x) -> Integer -> Coin
Coin Integer
x) Map (Credential 'Staking) DeltaCoin
credCoinMap
(Map (Credential 'Staking) Coin
combinedMap, Coin
available) <-
if ProtVer -> Bool
HardForks.allowMIRTransfer ProtVer
pv
then do
let cm :: Map (Credential 'Staking) Coin
cm = forall k a. Ord k => (a -> a -> a) -> Map k a -> Map k a -> Map k a
Map.unionWith forall a. Semigroup a => a -> a -> a
(<>) Map (Credential 'Staking) Coin
credCoinMap' Map (Credential 'Staking) Coin
instantaneousRewards
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (forall a. Ord a => a -> a -> Bool
>= forall a. Monoid a => a
mempty) Map (Credential 'Staking) Coin
cm forall sts (ctx :: RuleType).
Bool -> PredicateFailure sts -> Rule sts ctx ()
?! forall era. ShelleyDelegPredFailure era
MIRProducesNegativeUpdate
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Map (Credential 'Staking) Coin
cm, Coin
potAmount Coin -> DeltaCoin -> Coin
`addDeltaCoin` DeltaCoin
delta)
else do
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (forall a. Ord a => a -> a -> Bool
>= forall a. Monoid a => a
mempty) Map (Credential 'Staking) DeltaCoin
credCoinMap forall sts (ctx :: RuleType).
Bool -> PredicateFailure sts -> Rule sts ctx ()
?! forall era. ShelleyDelegPredFailure era
MIRNegativesNotCurrentlyAllowed
forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall k a. Ord k => Map k a -> Map k a -> Map k a
Map.union Map (Credential 'Staking) Coin
credCoinMap' Map (Credential 'Staking) Coin
instantaneousRewards, Coin
potAmount)
forall era.
MIRPot
-> Map (Credential 'Staking) Coin
-> Coin
-> DState era
-> Rule (ShelleyDELEG era) 'Transition (DState era)
updateReservesAndTreasury MIRPot
targetPot Map (Credential 'Staking) Coin
combinedMap Coin
available State (ShelleyDELEG era)
ds
SendToOppositePotMIR Coin
coin ->
if ProtVer -> Bool
HardForks.allowMIRTransfer ProtVer
pv
then do
let available :: Coin
available = MIRPot -> AccountState -> InstantaneousRewards -> Coin
availableAfterMIR MIRPot
targetPot AccountState
acnt (forall era. DState era -> InstantaneousRewards
dsIRewards State (ShelleyDELEG era)
ds)
Coin
coin forall a. Ord a => a -> a -> Bool
>= forall a. Monoid a => a
mempty forall sts (ctx :: RuleType).
Bool -> PredicateFailure sts -> Rule sts ctx ()
?! forall era. MIRPot -> Coin -> ShelleyDelegPredFailure era
MIRNegativeTransfer MIRPot
targetPot Coin
coin
Coin
coin forall a. Ord a => a -> a -> Bool
<= Coin
available forall sts (ctx :: RuleType).
Bool -> PredicateFailure sts -> Rule sts ctx ()
?! forall era.
MIRPot -> Mismatch 'RelLTEQ Coin -> ShelleyDelegPredFailure era
InsufficientForTransferDELEG MIRPot
targetPot (forall (r :: Relation) a. a -> a -> Mismatch r a
Mismatch Coin
coin Coin
available)
let ir :: InstantaneousRewards
ir = forall era. DState era -> InstantaneousRewards
dsIRewards State (ShelleyDELEG era)
ds
dr :: DeltaCoin
dr = InstantaneousRewards -> DeltaCoin
deltaReserves InstantaneousRewards
ir
dt :: DeltaCoin
dt = InstantaneousRewards -> DeltaCoin
deltaTreasury InstantaneousRewards
ir
case MIRPot
targetPot of
MIRPot
ReservesMIR ->
forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$
State (ShelleyDELEG era)
ds
{ dsIRewards :: InstantaneousRewards
dsIRewards =
InstantaneousRewards
ir
{ deltaReserves :: DeltaCoin
deltaReserves = DeltaCoin
dr forall a. Semigroup a => a -> a -> a
<> forall m. Group m => m -> m
invert (Coin -> DeltaCoin
toDeltaCoin Coin
coin)
, deltaTreasury :: DeltaCoin
deltaTreasury = DeltaCoin
dt forall a. Semigroup a => a -> a -> a
<> Coin -> DeltaCoin
toDeltaCoin Coin
coin
}
}
MIRPot
TreasuryMIR ->
forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$
State (ShelleyDELEG era)
ds
{ dsIRewards :: InstantaneousRewards
dsIRewards =
InstantaneousRewards
ir
{ deltaReserves :: DeltaCoin
deltaReserves = DeltaCoin
dr forall a. Semigroup a => a -> a -> a
<> Coin -> DeltaCoin
toDeltaCoin Coin
coin
, deltaTreasury :: DeltaCoin
deltaTreasury = DeltaCoin
dt forall a. Semigroup a => a -> a -> a
<> forall m. Group m => m -> m
invert (Coin -> DeltaCoin
toDeltaCoin Coin
coin)
}
}
else do
forall sts (ctx :: RuleType).
PredicateFailure sts -> Rule sts ctx ()
failBecause forall era. ShelleyDelegPredFailure era
MIRTransferNotCurrentlyAllowed
forall (f :: * -> *) a. Applicative f => a -> f a
pure State (ShelleyDELEG era)
ds
Signal (ShelleyDELEG era)
_ -> do
forall sts (ctx :: RuleType).
PredicateFailure sts -> Rule sts ctx ()
failBecause forall era. ShelleyDelegPredFailure era
WrongCertificateTypeDELEG
forall (f :: * -> *) a. Applicative f => a -> f a
pure State (ShelleyDELEG era)
ds
checkSlotNotTooLate ::
(ShelleyEraTxCert era, EraPParams era, ProtVerAtMost era 8) =>
SlotNo ->
EpochNo ->
Rule (ShelleyDELEG era) 'Transition ()
checkSlotNotTooLate :: forall era.
(ShelleyEraTxCert era, EraPParams era, ProtVerAtMost era 8) =>
SlotNo -> EpochNo -> Rule (ShelleyDELEG era) 'Transition ()
checkSlotNotTooLate SlotNo
slot EpochNo
curEpochNo = do
Word64
sp <- forall sts a (ctx :: RuleType).
STS sts =>
BaseM sts a -> Rule sts ctx a
liftSTS forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) r a. Monad m => (r -> a) -> ReaderT r m a
asks Globals -> Word64
stabilityWindow
EpochInfo Identity
ei <- forall sts a (ctx :: RuleType).
STS sts =>
BaseM sts a -> Rule sts ctx a
liftSTS forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) r a. Monad m => (r -> a) -> ReaderT r m a
asks Globals -> EpochInfo Identity
epochInfoPure
let firstSlot :: SlotNo
firstSlot = HasCallStack => EpochInfo Identity -> EpochNo -> SlotNo
epochInfoFirst EpochInfo Identity
ei EpochNo
newEpoch
tooLate :: SlotNo
tooLate = SlotNo
firstSlot SlotNo -> Duration -> SlotNo
*- Word64 -> Duration
Duration Word64
sp
newEpoch :: EpochNo
newEpoch = EpochNo -> EpochInterval -> EpochNo
addEpochInterval EpochNo
curEpochNo (Word32 -> EpochInterval
EpochInterval Word32
1)
forall sts (ctx :: RuleType). Event sts -> Rule sts ctx ()
tellEvent (forall era. EpochNo -> ShelleyDelegEvent era
DelegNewEpoch EpochNo
newEpoch)
SlotNo
slot forall a. Ord a => a -> a -> Bool
< SlotNo
tooLate forall sts (ctx :: RuleType).
Bool -> PredicateFailure sts -> Rule sts ctx ()
?! forall era. Mismatch 'RelLT SlotNo -> ShelleyDelegPredFailure era
MIRCertificateTooLateinEpochDELEG (forall (r :: Relation) a. a -> a -> Mismatch r a
Mismatch SlotNo
slot SlotNo
tooLate)
updateReservesAndTreasury ::
MIRPot ->
Map.Map (Credential 'Staking) Coin ->
Coin ->
DState era ->
Rule (ShelleyDELEG era) 'Transition (DState era)
updateReservesAndTreasury :: forall era.
MIRPot
-> Map (Credential 'Staking) Coin
-> Coin
-> DState era
-> Rule (ShelleyDELEG era) 'Transition (DState era)
updateReservesAndTreasury MIRPot
targetPot Map (Credential 'Staking) Coin
combinedMap Coin
available DState era
ds = do
let requiredForRewards :: Coin
requiredForRewards = forall (t :: * -> *) m. (Foldable t, Monoid m) => t m -> m
fold Map (Credential 'Staking) Coin
combinedMap
Coin
requiredForRewards
forall a. Ord a => a -> a -> Bool
<= Coin
available
forall sts (ctx :: RuleType).
Bool -> PredicateFailure sts -> Rule sts ctx ()
?! forall era.
MIRPot -> Mismatch 'RelLTEQ Coin -> ShelleyDelegPredFailure era
InsufficientForInstantaneousRewardsDELEG
MIRPot
targetPot
Mismatch
{ mismatchSupplied :: Coin
mismatchSupplied = Coin
requiredForRewards
, mismatchExpected :: Coin
mismatchExpected = Coin
available
}
forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$
case MIRPot
targetPot of
MIRPot
ReservesMIR -> DState era
ds {dsIRewards :: InstantaneousRewards
dsIRewards = (forall era. DState era -> InstantaneousRewards
dsIRewards DState era
ds) {iRReserves :: Map (Credential 'Staking) Coin
iRReserves = Map (Credential 'Staking) Coin
combinedMap}}
MIRPot
TreasuryMIR -> DState era
ds {dsIRewards :: InstantaneousRewards
dsIRewards = (forall era. DState era -> InstantaneousRewards
dsIRewards DState era
ds) {iRTreasury :: Map (Credential 'Staking) Coin
iRTreasury = Map (Credential 'Staking) Coin
combinedMap}}