{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}

-- |
-- Module      : Test.Cardano.Ledger.Shelley.Examples.Mir
-- Description : MIR Example
--
-- Example demonstrating the Move Instantaneous Rewards mechanism
module Test.Cardano.Ledger.Shelley.Examples.Mir (
  mirExample,
) where

import Cardano.Ledger.BaseTypes (Mismatch (..), Nonce, StrictMaybe (..), mkCertIxPartial)
import Cardano.Ledger.Block (Block, bheader)
import Cardano.Ledger.Coin (Coin (..), toDeltaCoin)
import Cardano.Ledger.Credential (Ptr (..), SlotNo32 (..))
import Cardano.Ledger.Keys (asWitness)
import Cardano.Ledger.Shelley (ShelleyEra, TxBody (..))
import Cardano.Ledger.Shelley.Core
import Cardano.Ledger.Shelley.LedgerState (
  EpochState (..),
  NewEpochState (..),
  PulsingRewUpdate,
  emptyRewardUpdate,
 )
import Cardano.Ledger.Shelley.Rules (
  ShelleyDelegPredFailure (..),
  ShelleyUtxowPredFailure (..),
 )
import Cardano.Ledger.Shelley.State
import Cardano.Ledger.Shelley.Tx (ShelleyTx (..))
import Cardano.Ledger.Shelley.TxCert (ShelleyTxCert (..))
import Cardano.Ledger.Shelley.TxOut (ShelleyTxOut (..))
import Cardano.Ledger.Shelley.TxWits (addrWits)
import Cardano.Ledger.Slot (BlockNo (..), SlotNo (..))
import Cardano.Ledger.TxIn (TxIn (..))
import Cardano.Ledger.Val ((<+>), (<->))
import qualified Cardano.Ledger.Val as Val
import Cardano.Protocol.TPraos.BHeader (BHeader, bhHash)
import Cardano.Protocol.TPraos.OCert (KESPeriod (..))
import qualified Data.Map.Strict as Map
import qualified Data.Sequence.Strict as StrictSeq
import qualified Data.Set as Set
import Test.Cardano.Ledger.Core.KeyPair (KeyPair (..), mkWitnessesVKey)
import Test.Cardano.Ledger.Shelley.ConcreteCryptoTypes (MockCrypto)
import Test.Cardano.Ledger.Shelley.Examples (CHAINExample (..), testCHAINExample)
import qualified Test.Cardano.Ledger.Shelley.Examples.Cast as Cast
import qualified Test.Cardano.Ledger.Shelley.Examples.Combinators as C
import Test.Cardano.Ledger.Shelley.Examples.Federation (
  coreNodeIssuerKeys,
  coreNodeKeysBySchedule,
 )
import Test.Cardano.Ledger.Shelley.Examples.Init (
  initSt,
  lastByronHeaderHash,
  nonce0,
  ppEx,
 )
import Test.Cardano.Ledger.Shelley.Examples.PoolLifetime (makePulser')
import Test.Cardano.Ledger.Shelley.Generator.Core (
  AllIssuerKeys (..),
  NatNonce (..),
  genesisCoins,
  mkBlockFakeVRF,
  mkOCert,
 )
import Test.Cardano.Ledger.Shelley.Generator.EraGen (genesisId)
import Test.Cardano.Ledger.Shelley.Generator.ShelleyEraGen ()
import Test.Cardano.Ledger.Shelley.Rules.Chain (ChainState (..), TestChainPredicateFailure (..))
import Test.Cardano.Ledger.Shelley.Utils (getBlockNonce)
import Test.Tasty (TestTree, testGroup)
import Test.Tasty.HUnit (testCase)

initUTxO :: UTxO ShelleyEra
initUTxO :: UTxO ShelleyEra
initUTxO =
  TxId -> [TxOut ShelleyEra] -> UTxO ShelleyEra
forall era. TxId -> [TxOut era] -> UTxO era
genesisCoins
    TxId
genesisId
    [ Addr -> Value ShelleyEra -> ShelleyTxOut ShelleyEra
forall era.
(HasCallStack, Era era, Val (Value era)) =>
Addr -> Value era -> ShelleyTxOut era
ShelleyTxOut Addr
Cast.aliceAddr Value ShelleyEra
Coin
aliceInitCoin
    , Addr -> Value ShelleyEra -> ShelleyTxOut ShelleyEra
forall era.
(HasCallStack, Era era, Val (Value era)) =>
Addr -> Value era -> ShelleyTxOut era
ShelleyTxOut Addr
Cast.bobAddr Value ShelleyEra
Coin
bobInitCoin
    ]
  where
    aliceInitCoin :: Coin
aliceInitCoin = Coin -> Coin
forall t s. Inject t s => t -> s
Val.inject (Coin -> Coin) -> Coin -> Coin
forall a b. (a -> b) -> a -> b
$ Integer -> Coin
Coin (Integer -> Coin) -> Integer -> Coin
forall a b. (a -> b) -> a -> b
$ Integer
10 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
1000 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
1000 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
1000 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
1000 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
1000
    bobInitCoin :: Coin
bobInitCoin = Coin -> Coin
forall t s. Inject t s => t -> s
Val.inject (Coin -> Coin) -> Coin -> Coin
forall a b. (a -> b) -> a -> b
$ Integer -> Coin
Coin (Integer -> Coin) -> Integer -> Coin
forall a b. (a -> b) -> a -> b
$ Integer
1 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
1000 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
1000 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
1000 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
1000 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
1000

initStMIR :: Coin -> ChainState ShelleyEra
initStMIR :: Coin -> ChainState ShelleyEra
initStMIR Coin
treasury = ChainState ShelleyEra
cs {chainNes = (chainNes cs) {nesEs = es'}}
  where
    cs :: ChainState ShelleyEra
cs = forall era.
(EraTxOut era, EraGov era, EraStake era, EraCertState era,
 ProtVerAtMost era 4, ProtVerAtMost era 6,
 Default (StashedAVVMAddresses era)) =>
UTxO era -> ChainState era
initSt @ShelleyEra UTxO ShelleyEra
initUTxO
    chainAccountState :: ChainAccountState
chainAccountState = EpochState ShelleyEra -> ChainAccountState
forall era. EpochState era -> ChainAccountState
esChainAccountState (EpochState ShelleyEra -> ChainAccountState)
-> (NewEpochState ShelleyEra -> EpochState ShelleyEra)
-> NewEpochState ShelleyEra
-> ChainAccountState
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NewEpochState ShelleyEra -> EpochState ShelleyEra
forall era. NewEpochState era -> EpochState era
nesEs (NewEpochState ShelleyEra -> ChainAccountState)
-> NewEpochState ShelleyEra -> ChainAccountState
forall a b. (a -> b) -> a -> b
$ ChainState ShelleyEra -> NewEpochState ShelleyEra
forall era. ChainState era -> NewEpochState era
chainNes ChainState ShelleyEra
cs
    chainAccountState' :: ChainAccountState
chainAccountState' =
      ChainAccountState
        { casTreasury :: Coin
casTreasury = ChainAccountState -> Coin
casTreasury ChainAccountState
chainAccountState Coin -> Coin -> Coin
forall t. Val t => t -> t -> t
<+> Coin
treasury
        , casReserves :: Coin
casReserves = ChainAccountState -> Coin
casReserves ChainAccountState
chainAccountState Coin -> Coin -> Coin
forall t. Val t => t -> t -> t
<-> Coin
treasury
        }
    es' :: EpochState ShelleyEra
es' = (NewEpochState ShelleyEra -> EpochState ShelleyEra
forall era. NewEpochState era -> EpochState era
nesEs (NewEpochState ShelleyEra -> EpochState ShelleyEra)
-> NewEpochState ShelleyEra -> EpochState ShelleyEra
forall a b. (a -> b) -> a -> b
$ ChainState ShelleyEra -> NewEpochState ShelleyEra
forall era. ChainState era -> NewEpochState era
chainNes ChainState ShelleyEra
cs) {esChainAccountState = chainAccountState'}

--
-- Block 1, Slot 10, Epoch 0
--

aliceMIRCoin :: Coin
aliceMIRCoin :: Coin
aliceMIRCoin = Integer -> Coin
Coin Integer
100

ir :: MIRTarget
ir :: MIRTarget
ir = Map (Credential 'Staking) DeltaCoin -> MIRTarget
StakeAddressesMIR (Map (Credential 'Staking) DeltaCoin -> MIRTarget)
-> Map (Credential 'Staking) DeltaCoin -> MIRTarget
forall a b. (a -> b) -> a -> b
$ [(Credential 'Staking, DeltaCoin)]
-> Map (Credential 'Staking) DeltaCoin
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList [(Credential 'Staking
Cast.aliceSHK, Coin -> DeltaCoin
toDeltaCoin Coin
aliceMIRCoin)]

feeTx1 :: Coin
feeTx1 :: Coin
feeTx1 = Integer -> Coin
Coin Integer
1

txbodyEx1 :: MIRPot -> TxBody ShelleyEra
txbodyEx1 :: MIRPot -> TxBody ShelleyEra
txbodyEx1 MIRPot
pot =
  Set TxIn
-> StrictSeq (TxOut ShelleyEra)
-> StrictSeq (TxCert ShelleyEra)
-> Withdrawals
-> Coin
-> SlotNo
-> StrictMaybe (Update ShelleyEra)
-> StrictMaybe TxAuxDataHash
-> TxBody ShelleyEra
ShelleyTxBody
    ([TxIn] -> Set TxIn
forall a. Ord a => [a] -> Set a
Set.fromList [TxId -> TxIx -> TxIn
TxIn TxId
genesisId TxIx
forall a. Bounded a => a
minBound])
    (TxOut ShelleyEra -> StrictSeq (TxOut ShelleyEra)
forall a. a -> StrictSeq a
StrictSeq.singleton (TxOut ShelleyEra -> StrictSeq (TxOut ShelleyEra))
-> TxOut ShelleyEra -> StrictSeq (TxOut ShelleyEra)
forall a b. (a -> b) -> a -> b
$ Addr -> Value ShelleyEra -> ShelleyTxOut ShelleyEra
forall era.
(HasCallStack, Era era, Val (Value era)) =>
Addr -> Value era -> ShelleyTxOut era
ShelleyTxOut Addr
Cast.aliceAddr Value ShelleyEra
Coin
aliceCoinEx1)
    ( [ShelleyTxCert ShelleyEra] -> StrictSeq (ShelleyTxCert ShelleyEra)
forall a. [a] -> StrictSeq a
StrictSeq.fromList
        [ MIRCert -> ShelleyTxCert ShelleyEra
forall era. MIRCert -> ShelleyTxCert era
ShelleyTxCertMir (MIRPot -> MIRTarget -> MIRCert
MIRCert MIRPot
pot MIRTarget
ir)
        , Credential 'Staking -> TxCert ShelleyEra
forall era.
ShelleyEraTxCert era =>
Credential 'Staking -> TxCert era
RegTxCert Credential 'Staking
Cast.aliceSHK
        ]
    )
    (Map RewardAccount Coin -> Withdrawals
Withdrawals Map RewardAccount Coin
forall k a. Map k a
Map.empty)
    (Integer -> Coin
Coin Integer
1)
    (Word64 -> SlotNo
SlotNo Word64
10)
    StrictMaybe (Update ShelleyEra)
forall a. StrictMaybe a
SNothing
    StrictMaybe TxAuxDataHash
forall a. StrictMaybe a
SNothing
  where
    aliceInitCoin :: Coin
aliceInitCoin = Coin -> Coin
forall t s. Inject t s => t -> s
Val.inject (Coin -> Coin) -> Coin -> Coin
forall a b. (a -> b) -> a -> b
$ Integer -> Coin
Coin (Integer -> Coin) -> Integer -> Coin
forall a b. (a -> b) -> a -> b
$ Integer
10 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
1000 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
1000 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
1000 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
1000 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
1000
    aliceCoinEx1 :: Coin
aliceCoinEx1 = Coin
aliceInitCoin Coin -> Coin -> Coin
forall t. Val t => t -> t -> t
<-> Coin -> Coin
forall t s. Inject t s => t -> s
Val.inject (Coin
feeTx1 Coin -> Coin -> Coin
forall t. Val t => t -> t -> t
<+> Integer -> Coin
Coin Integer
7)

mirWits :: [Int] -> [KeyPair 'Witness]
mirWits :: [Int] -> [KeyPair 'Witness]
mirWits = (Int -> KeyPair 'Witness) -> [Int] -> [KeyPair 'Witness]
forall a b. (a -> b) -> [a] -> [b]
map (KeyPair 'GenesisDelegate -> KeyPair 'Witness
forall (a :: KeyRole -> *) (r :: KeyRole).
HasKeyRole a =>
a r -> a 'Witness
asWitness (KeyPair 'GenesisDelegate -> KeyPair 'Witness)
-> (Int -> KeyPair 'GenesisDelegate) -> Int -> KeyPair 'Witness
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AllIssuerKeys MockCrypto 'GenesisDelegate
-> KeyPair 'GenesisDelegate
forall c (r :: KeyRole). AllIssuerKeys c r -> KeyPair r
aikCold (AllIssuerKeys MockCrypto 'GenesisDelegate
 -> KeyPair 'GenesisDelegate)
-> (Int -> AllIssuerKeys MockCrypto 'GenesisDelegate)
-> Int
-> KeyPair 'GenesisDelegate
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> AllIssuerKeys MockCrypto 'GenesisDelegate
coreNodeIssuerKeys)

sufficientMIRWits :: [KeyPair 'Witness]
sufficientMIRWits :: [KeyPair 'Witness]
sufficientMIRWits = [Int] -> [KeyPair 'Witness]
mirWits [Int
0 .. Int
4]

insufficientMIRWits :: [KeyPair 'Witness]
insufficientMIRWits :: [KeyPair 'Witness]
insufficientMIRWits = [Int] -> [KeyPair 'Witness]
mirWits [Int
0 .. Int
3]

txEx1 :: [KeyPair 'Witness] -> MIRPot -> ShelleyTx ShelleyEra
txEx1 :: [KeyPair 'Witness] -> MIRPot -> ShelleyTx ShelleyEra
txEx1 [KeyPair 'Witness]
txwits MIRPot
pot =
  TxBody ShelleyEra
-> TxWits ShelleyEra
-> StrictMaybe (TxAuxData ShelleyEra)
-> ShelleyTx ShelleyEra
forall era.
EraTx era =>
TxBody era
-> TxWits era -> StrictMaybe (TxAuxData era) -> ShelleyTx era
ShelleyTx
    (MIRPot -> TxBody ShelleyEra
txbodyEx1 MIRPot
pot)
    ShelleyTxWits ShelleyEra
forall a. Monoid a => a
mempty
      { addrWits =
          mkWitnessesVKey
            (hashAnnotated $ txbodyEx1 pot)
            ([asWitness Cast.alicePay] <> txwits)
      }
    StrictMaybe (TxAuxData ShelleyEra)
StrictMaybe (ShelleyTxAuxData ShelleyEra)
forall a. StrictMaybe a
SNothing

blockEx1' :: [KeyPair 'Witness] -> MIRPot -> Block (BHeader MockCrypto) ShelleyEra
blockEx1' :: [KeyPair 'Witness]
-> MIRPot -> Block (BHeader MockCrypto) ShelleyEra
blockEx1' [KeyPair 'Witness]
txwits MIRPot
pot =
  HashHeader
-> AllIssuerKeys MockCrypto 'GenesisDelegate
-> [Tx ShelleyEra]
-> SlotNo
-> BlockNo
-> Nonce
-> NatNonce
-> UnitInterval
-> Word
-> Word
-> OCert MockCrypto
-> Block (BHeader MockCrypto) ShelleyEra
forall era (r :: KeyRole) c.
(Crypto c, EraSegWits era, Signable (VRF c) (WithResult Seed),
 Signable (KES c) (BHBody c)) =>
HashHeader
-> AllIssuerKeys c r
-> [Tx era]
-> SlotNo
-> BlockNo
-> Nonce
-> NatNonce
-> UnitInterval
-> Word
-> Word
-> OCert c
-> Block (BHeader c) era
mkBlockFakeVRF
    HashHeader
lastByronHeaderHash
    (forall era.
(HasCallStack, EraPParams era) =>
PParams era -> Word64 -> AllIssuerKeys MockCrypto 'GenesisDelegate
coreNodeKeysBySchedule @ShelleyEra PParams ShelleyEra
forall era.
(EraPParams era, ProtVerAtMost era 4, ProtVerAtMost era 6) =>
PParams era
ppEx Word64
10)
    [[KeyPair 'Witness] -> MIRPot -> ShelleyTx ShelleyEra
txEx1 [KeyPair 'Witness]
txwits MIRPot
pot]
    (Word64 -> SlotNo
SlotNo Word64
10)
    (Word64 -> BlockNo
BlockNo Word64
1)
    Nonce
nonce0
    (Natural -> NatNonce
NatNonce Natural
1)
    UnitInterval
forall a. Bounded a => a
minBound
    Word
0
    Word
0
    (AllIssuerKeys MockCrypto 'GenesisDelegate
-> Word64 -> KESPeriod -> OCert MockCrypto
forall c (r :: KeyRole).
Crypto c =>
AllIssuerKeys c r -> Word64 -> KESPeriod -> OCert c
mkOCert (forall era.
(HasCallStack, EraPParams era) =>
PParams era -> Word64 -> AllIssuerKeys MockCrypto 'GenesisDelegate
coreNodeKeysBySchedule @ShelleyEra PParams ShelleyEra
forall era.
(EraPParams era, ProtVerAtMost era 4, ProtVerAtMost era 6) =>
PParams era
ppEx Word64
10) Word64
0 (Word -> KESPeriod
KESPeriod Word
0))

blockEx1 :: MIRPot -> Block (BHeader MockCrypto) ShelleyEra
blockEx1 :: MIRPot -> Block (BHeader MockCrypto) ShelleyEra
blockEx1 = [KeyPair 'Witness]
-> MIRPot -> Block (BHeader MockCrypto) ShelleyEra
blockEx1' [KeyPair 'Witness]
sufficientMIRWits

expectedStEx1' :: [KeyPair 'Witness] -> MIRPot -> ChainState ShelleyEra
expectedStEx1' :: [KeyPair 'Witness] -> MIRPot -> ChainState ShelleyEra
expectedStEx1' [KeyPair 'Witness]
txwits MIRPot
pot =
  Nonce -> ChainState ShelleyEra -> ChainState ShelleyEra
forall era. Nonce -> ChainState era -> ChainState era
C.evolveNonceUnfrozen (Block (BHeader MockCrypto) ShelleyEra -> Nonce
forall era. Block (BHeader MockCrypto) era -> Nonce
getBlockNonce ([KeyPair 'Witness]
-> MIRPot -> Block (BHeader MockCrypto) ShelleyEra
blockEx1' [KeyPair 'Witness]
txwits MIRPot
pot))
    (ChainState ShelleyEra -> ChainState ShelleyEra)
-> (ChainState ShelleyEra -> ChainState ShelleyEra)
-> ChainState ShelleyEra
-> ChainState ShelleyEra
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Block (BHeader MockCrypto) ShelleyEra
-> ChainState ShelleyEra -> ChainState ShelleyEra
forall era.
Block (BHeader MockCrypto) era -> ChainState era -> ChainState era
C.newLab ([KeyPair 'Witness]
-> MIRPot -> Block (BHeader MockCrypto) ShelleyEra
blockEx1' [KeyPair 'Witness]
txwits MIRPot
pot)
    (ChainState ShelleyEra -> ChainState ShelleyEra)
-> (ChainState ShelleyEra -> ChainState ShelleyEra)
-> ChainState ShelleyEra
-> ChainState ShelleyEra
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PParams ShelleyEra
-> Coin
-> [Credential 'Staking]
-> [PoolParams]
-> ChainState ShelleyEra
-> ChainState ShelleyEra
forall era.
(EraPParams era, EraCertState era) =>
PParams era
-> Coin
-> [Credential 'Staking]
-> [PoolParams]
-> ChainState era
-> ChainState era
C.feesAndDeposits PParams ShelleyEra
forall era.
(EraPParams era, ProtVerAtMost era 4, ProtVerAtMost era 6) =>
PParams era
ppEx Coin
feeTx1 [Credential 'Staking
Cast.aliceSHK] []
    (ChainState ShelleyEra -> ChainState ShelleyEra)
-> (ChainState ShelleyEra -> ChainState ShelleyEra)
-> ChainState ShelleyEra
-> ChainState ShelleyEra
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TxBody ShelleyEra -> ChainState ShelleyEra -> ChainState ShelleyEra
forall era.
(EraTx era, EraStake era) =>
TxBody era -> ChainState era -> ChainState era
C.newUTxO (MIRPot -> TxBody ShelleyEra
txbodyEx1 MIRPot
pot)
    (ChainState ShelleyEra -> ChainState ShelleyEra)
-> (ChainState ShelleyEra -> ChainState ShelleyEra)
-> ChainState ShelleyEra
-> ChainState ShelleyEra
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Credential 'Staking
-> Ptr -> ChainState ShelleyEra -> ChainState ShelleyEra
forall era.
EraCertState era =>
Credential 'Staking -> Ptr -> ChainState era -> ChainState era
C.newStakeCred Credential 'Staking
Cast.aliceSHK (SlotNo32 -> TxIx -> CertIx -> Ptr
Ptr (Word32 -> SlotNo32
SlotNo32 Word32
10) TxIx
forall a. Bounded a => a
minBound (HasCallStack => Integer -> CertIx
Integer -> CertIx
mkCertIxPartial Integer
1))
    (ChainState ShelleyEra -> ChainState ShelleyEra)
-> (ChainState ShelleyEra -> ChainState ShelleyEra)
-> ChainState ShelleyEra
-> ChainState ShelleyEra
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Credential 'Staking
-> MIRPot -> Coin -> ChainState ShelleyEra -> ChainState ShelleyEra
forall era.
EraCertState era =>
Credential 'Staking
-> MIRPot -> Coin -> ChainState era -> ChainState era
C.mir Credential 'Staking
Cast.aliceSHK MIRPot
pot Coin
aliceMIRCoin
    (ChainState ShelleyEra -> ChainState ShelleyEra)
-> ChainState ShelleyEra -> ChainState ShelleyEra
forall a b. (a -> b) -> a -> b
$ Coin -> ChainState ShelleyEra
initStMIR (Integer -> Coin
Coin Integer
1000)

expectedStEx1 :: MIRPot -> ChainState ShelleyEra
expectedStEx1 :: MIRPot -> ChainState ShelleyEra
expectedStEx1 = [KeyPair 'Witness] -> MIRPot -> ChainState ShelleyEra
expectedStEx1' [KeyPair 'Witness]
sufficientMIRWits

-- === Block 1, Slot 10, Epoch 0, Successful MIR Reserves Example
--
-- In the first block, submit a MIR cert drawing from the reserves.
mir1 :: MIRPot -> CHAINExample ShelleyEra
mir1 :: MIRPot -> CHAINExample ShelleyEra
mir1 MIRPot
pot =
  ChainState ShelleyEra
-> Block (BHeader MockCrypto) ShelleyEra
-> Either
     (NonEmpty (PredicateFailure (CHAIN ShelleyEra)))
     (ChainState ShelleyEra)
-> CHAINExample ShelleyEra
forall era.
ChainState era
-> Block (BHeader MockCrypto) era
-> Either
     (NonEmpty (PredicateFailure (CHAIN era))) (ChainState era)
-> CHAINExample era
CHAINExample
    (Coin -> ChainState ShelleyEra
initStMIR (Integer -> Coin
Coin Integer
1000))
    (MIRPot -> Block (BHeader MockCrypto) ShelleyEra
blockEx1 MIRPot
pot)
    (ChainState ShelleyEra
-> Either
     (NonEmpty (PredicateFailure (CHAIN ShelleyEra)))
     (ChainState ShelleyEra)
forall a b. b -> Either a b
Right (ChainState ShelleyEra
 -> Either
      (NonEmpty (PredicateFailure (CHAIN ShelleyEra)))
      (ChainState ShelleyEra))
-> ChainState ShelleyEra
-> Either
     (NonEmpty (PredicateFailure (CHAIN ShelleyEra)))
     (ChainState ShelleyEra)
forall a b. (a -> b) -> a -> b
$ MIRPot -> ChainState ShelleyEra
expectedStEx1 MIRPot
pot)

-- === Block 1, Slot 10, Epoch 0, Insufficient MIR Wits, Reserves Example
--
-- In the first block, submit a MIR cert drawing from the reserves.
mirFailWits :: MIRPot -> CHAINExample ShelleyEra
mirFailWits :: MIRPot -> CHAINExample ShelleyEra
mirFailWits MIRPot
pot =
  ChainState ShelleyEra
-> Block (BHeader MockCrypto) ShelleyEra
-> Either
     (NonEmpty (PredicateFailure (CHAIN ShelleyEra)))
     (ChainState ShelleyEra)
-> CHAINExample ShelleyEra
forall era.
ChainState era
-> Block (BHeader MockCrypto) era
-> Either
     (NonEmpty (PredicateFailure (CHAIN era))) (ChainState era)
-> CHAINExample era
CHAINExample
    (Coin -> ChainState ShelleyEra
initStMIR (Integer -> Coin
Coin Integer
1000))
    ([KeyPair 'Witness]
-> MIRPot -> Block (BHeader MockCrypto) ShelleyEra
blockEx1' [KeyPair 'Witness]
insufficientMIRWits MIRPot
pot)
    ( NonEmpty (TestChainPredicateFailure ShelleyEra)
-> Either
     (NonEmpty (PredicateFailure (CHAIN ShelleyEra)))
     (ChainState ShelleyEra)
NonEmpty (TestChainPredicateFailure ShelleyEra)
-> Either
     (NonEmpty (TestChainPredicateFailure ShelleyEra))
     (ChainState ShelleyEra)
forall a b. a -> Either a b
Left
        (NonEmpty (TestChainPredicateFailure ShelleyEra)
 -> Either
      (NonEmpty (PredicateFailure (CHAIN ShelleyEra)))
      (ChainState ShelleyEra))
-> (ShelleyUtxowPredFailure ShelleyEra
    -> NonEmpty (TestChainPredicateFailure ShelleyEra))
-> ShelleyUtxowPredFailure ShelleyEra
-> Either
     (NonEmpty (PredicateFailure (CHAIN ShelleyEra)))
     (ChainState ShelleyEra)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TestChainPredicateFailure ShelleyEra
-> NonEmpty (TestChainPredicateFailure ShelleyEra)
forall a. a -> NonEmpty a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
        (TestChainPredicateFailure ShelleyEra
 -> NonEmpty (TestChainPredicateFailure ShelleyEra))
-> (ShelleyUtxowPredFailure ShelleyEra
    -> TestChainPredicateFailure ShelleyEra)
-> ShelleyUtxowPredFailure ShelleyEra
-> NonEmpty (TestChainPredicateFailure ShelleyEra)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PredicateFailure (EraRule "BBODY" ShelleyEra)
-> TestChainPredicateFailure ShelleyEra
ShelleyBbodyPredFailure ShelleyEra
-> TestChainPredicateFailure ShelleyEra
forall era.
PredicateFailure (EraRule "BBODY" era)
-> TestChainPredicateFailure era
BbodyFailure
        (ShelleyBbodyPredFailure ShelleyEra
 -> TestChainPredicateFailure ShelleyEra)
-> (ShelleyUtxowPredFailure ShelleyEra
    -> ShelleyBbodyPredFailure ShelleyEra)
-> ShelleyUtxowPredFailure ShelleyEra
-> TestChainPredicateFailure ShelleyEra
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShelleyUtxowPredFailure ShelleyEra
-> EraRuleFailure "BBODY" ShelleyEra
ShelleyUtxowPredFailure ShelleyEra
-> ShelleyBbodyPredFailure ShelleyEra
forall (rule :: Symbol) (t :: * -> *) era.
InjectRuleFailure rule t era =>
t era -> EraRuleFailure rule era
injectFailure
        (ShelleyUtxowPredFailure ShelleyEra
 -> Either
      (NonEmpty (PredicateFailure (CHAIN ShelleyEra)))
      (ChainState ShelleyEra))
-> ShelleyUtxowPredFailure ShelleyEra
-> Either
     (NonEmpty (PredicateFailure (CHAIN ShelleyEra)))
     (ChainState ShelleyEra)
forall a b. (a -> b) -> a -> b
$ Set (KeyHash 'Witness) -> ShelleyUtxowPredFailure ShelleyEra
forall era. Set (KeyHash 'Witness) -> ShelleyUtxowPredFailure era
MIRInsufficientGenesisSigsUTXOW Set (KeyHash 'Witness)
ws
    )
  where
    ws :: Set (KeyHash 'Witness)
ws = [KeyHash 'Witness] -> Set (KeyHash 'Witness)
forall a. Ord a => [a] -> Set a
Set.fromList ([KeyHash 'Witness] -> Set (KeyHash 'Witness))
-> [KeyHash 'Witness] -> Set (KeyHash 'Witness)
forall a b. (a -> b) -> a -> b
$ (Int -> KeyHash 'Witness) -> [Int] -> [KeyHash 'Witness]
forall a b. (a -> b) -> [a] -> [b]
map (KeyHash 'GenesisDelegate -> KeyHash 'Witness
forall (a :: KeyRole -> *) (r :: KeyRole).
HasKeyRole a =>
a r -> a 'Witness
asWitness (KeyHash 'GenesisDelegate -> KeyHash 'Witness)
-> (Int -> KeyHash 'GenesisDelegate) -> Int -> KeyHash 'Witness
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AllIssuerKeys MockCrypto 'GenesisDelegate
-> KeyHash 'GenesisDelegate
forall c (r :: KeyRole). AllIssuerKeys c r -> KeyHash r
aikColdKeyHash (AllIssuerKeys MockCrypto 'GenesisDelegate
 -> KeyHash 'GenesisDelegate)
-> (Int -> AllIssuerKeys MockCrypto 'GenesisDelegate)
-> Int
-> KeyHash 'GenesisDelegate
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> AllIssuerKeys MockCrypto 'GenesisDelegate
coreNodeIssuerKeys) [Int
0 .. Int
3]

-- === Block 1, Slot 10, Epoch 0, Insufficient MIR funds, Reserves Example
--
-- In the first block, submit a MIR cert drawing from the reserves.
mirFailFunds ::
  MIRPot ->
  Coin ->
  Coin ->
  Coin ->
  CHAINExample ShelleyEra
mirFailFunds :: MIRPot -> Coin -> Coin -> Coin -> CHAINExample ShelleyEra
mirFailFunds MIRPot
pot Coin
treasury Coin
llNeeded Coin
llReceived =
  ChainState ShelleyEra
-> Block (BHeader MockCrypto) ShelleyEra
-> Either
     (NonEmpty (PredicateFailure (CHAIN ShelleyEra)))
     (ChainState ShelleyEra)
-> CHAINExample ShelleyEra
forall era.
ChainState era
-> Block (BHeader MockCrypto) era
-> Either
     (NonEmpty (PredicateFailure (CHAIN era))) (ChainState era)
-> CHAINExample era
CHAINExample
    (Coin -> ChainState ShelleyEra
initStMIR Coin
treasury)
    ([KeyPair 'Witness]
-> MIRPot -> Block (BHeader MockCrypto) ShelleyEra
blockEx1' [KeyPair 'Witness]
sufficientMIRWits MIRPot
pot)
    ( NonEmpty (TestChainPredicateFailure ShelleyEra)
-> Either
     (NonEmpty (PredicateFailure (CHAIN ShelleyEra)))
     (ChainState ShelleyEra)
NonEmpty (TestChainPredicateFailure ShelleyEra)
-> Either
     (NonEmpty (TestChainPredicateFailure ShelleyEra))
     (ChainState ShelleyEra)
forall a b. a -> Either a b
Left
        (NonEmpty (TestChainPredicateFailure ShelleyEra)
 -> Either
      (NonEmpty (PredicateFailure (CHAIN ShelleyEra)))
      (ChainState ShelleyEra))
-> (ShelleyDelegPredFailure ShelleyEra
    -> NonEmpty (TestChainPredicateFailure ShelleyEra))
-> ShelleyDelegPredFailure ShelleyEra
-> Either
     (NonEmpty (PredicateFailure (CHAIN ShelleyEra)))
     (ChainState ShelleyEra)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TestChainPredicateFailure ShelleyEra
-> NonEmpty (TestChainPredicateFailure ShelleyEra)
forall a. a -> NonEmpty a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
        (TestChainPredicateFailure ShelleyEra
 -> NonEmpty (TestChainPredicateFailure ShelleyEra))
-> (ShelleyDelegPredFailure ShelleyEra
    -> TestChainPredicateFailure ShelleyEra)
-> ShelleyDelegPredFailure ShelleyEra
-> NonEmpty (TestChainPredicateFailure ShelleyEra)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PredicateFailure (EraRule "BBODY" ShelleyEra)
-> TestChainPredicateFailure ShelleyEra
ShelleyBbodyPredFailure ShelleyEra
-> TestChainPredicateFailure ShelleyEra
forall era.
PredicateFailure (EraRule "BBODY" era)
-> TestChainPredicateFailure era
BbodyFailure
        (ShelleyBbodyPredFailure ShelleyEra
 -> TestChainPredicateFailure ShelleyEra)
-> (ShelleyDelegPredFailure ShelleyEra
    -> ShelleyBbodyPredFailure ShelleyEra)
-> ShelleyDelegPredFailure ShelleyEra
-> TestChainPredicateFailure ShelleyEra
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShelleyDelegPredFailure ShelleyEra
-> EraRuleFailure "BBODY" ShelleyEra
ShelleyDelegPredFailure ShelleyEra
-> ShelleyBbodyPredFailure ShelleyEra
forall (rule :: Symbol) (t :: * -> *) era.
InjectRuleFailure rule t era =>
t era -> EraRuleFailure rule era
injectFailure
        (ShelleyDelegPredFailure ShelleyEra
 -> Either
      (NonEmpty (PredicateFailure (CHAIN ShelleyEra)))
      (ChainState ShelleyEra))
-> ShelleyDelegPredFailure ShelleyEra
-> Either
     (NonEmpty (PredicateFailure (CHAIN ShelleyEra)))
     (ChainState ShelleyEra)
forall a b. (a -> b) -> a -> b
$ MIRPot
-> Mismatch 'RelLTEQ Coin -> ShelleyDelegPredFailure ShelleyEra
forall era.
MIRPot -> Mismatch 'RelLTEQ Coin -> ShelleyDelegPredFailure era
InsufficientForInstantaneousRewardsDELEG MIRPot
pot
        (Mismatch 'RelLTEQ Coin -> ShelleyDelegPredFailure ShelleyEra)
-> Mismatch 'RelLTEQ Coin -> ShelleyDelegPredFailure ShelleyEra
forall a b. (a -> b) -> a -> b
$ Coin -> Coin -> Mismatch 'RelLTEQ Coin
forall (r :: Relation) a. a -> a -> Mismatch r a
Mismatch Coin
llNeeded Coin
llReceived
    )

--
-- Block 2, Slot 50, Epoch 0
--

blockEx2 :: MIRPot -> Block (BHeader MockCrypto) ShelleyEra
blockEx2 :: MIRPot -> Block (BHeader MockCrypto) ShelleyEra
blockEx2 MIRPot
pot =
  HashHeader
-> AllIssuerKeys MockCrypto 'GenesisDelegate
-> [Tx ShelleyEra]
-> SlotNo
-> BlockNo
-> Nonce
-> NatNonce
-> UnitInterval
-> Word
-> Word
-> OCert MockCrypto
-> Block (BHeader MockCrypto) ShelleyEra
forall era (r :: KeyRole) c.
(Crypto c, EraSegWits era, Signable (VRF c) (WithResult Seed),
 Signable (KES c) (BHBody c)) =>
HashHeader
-> AllIssuerKeys c r
-> [Tx era]
-> SlotNo
-> BlockNo
-> Nonce
-> NatNonce
-> UnitInterval
-> Word
-> Word
-> OCert c
-> Block (BHeader c) era
mkBlockFakeVRF
    (BHeader MockCrypto -> HashHeader
forall c. BHeader c -> HashHeader
bhHash (BHeader MockCrypto -> HashHeader)
-> BHeader MockCrypto -> HashHeader
forall a b. (a -> b) -> a -> b
$ Block (BHeader MockCrypto) ShelleyEra -> BHeader MockCrypto
forall h era. Block h era -> h
bheader (MIRPot -> Block (BHeader MockCrypto) ShelleyEra
blockEx1 MIRPot
pot))
    (forall era.
(HasCallStack, EraPParams era) =>
PParams era -> Word64 -> AllIssuerKeys MockCrypto 'GenesisDelegate
coreNodeKeysBySchedule @ShelleyEra PParams ShelleyEra
forall era.
(EraPParams era, ProtVerAtMost era 4, ProtVerAtMost era 6) =>
PParams era
ppEx Word64
50)
    []
    (Word64 -> SlotNo
SlotNo Word64
50)
    (Word64 -> BlockNo
BlockNo Word64
2)
    Nonce
nonce0
    (Natural -> NatNonce
NatNonce Natural
2)
    UnitInterval
forall a. Bounded a => a
minBound
    Word
2
    Word
0
    (AllIssuerKeys MockCrypto 'GenesisDelegate
-> Word64 -> KESPeriod -> OCert MockCrypto
forall c (r :: KeyRole).
Crypto c =>
AllIssuerKeys c r -> Word64 -> KESPeriod -> OCert c
mkOCert (forall era.
(HasCallStack, EraPParams era) =>
PParams era -> Word64 -> AllIssuerKeys MockCrypto 'GenesisDelegate
coreNodeKeysBySchedule @ShelleyEra PParams ShelleyEra
forall era.
(EraPParams era, ProtVerAtMost era 4, ProtVerAtMost era 6) =>
PParams era
ppEx Word64
50) Word64
0 (Word -> KESPeriod
KESPeriod Word
0))

pulserEx2 :: MIRPot -> PulsingRewUpdate
pulserEx2 :: MIRPot -> PulsingRewUpdate
pulserEx2 MIRPot
pot = ChainState ShelleyEra -> PulsingRewUpdate
forall era.
(EraGov era, EraCertState era) =>
ChainState era -> PulsingRewUpdate
makePulser' (MIRPot -> ChainState ShelleyEra
expectedStEx1 MIRPot
pot)

expectedStEx2 :: MIRPot -> ChainState ShelleyEra
expectedStEx2 :: MIRPot -> ChainState ShelleyEra
expectedStEx2 MIRPot
pot =
  Nonce -> ChainState ShelleyEra -> ChainState ShelleyEra
forall era. Nonce -> ChainState era -> ChainState era
C.evolveNonceUnfrozen (Block (BHeader MockCrypto) ShelleyEra -> Nonce
forall era. Block (BHeader MockCrypto) era -> Nonce
getBlockNonce (MIRPot -> Block (BHeader MockCrypto) ShelleyEra
blockEx2 MIRPot
pot))
    (ChainState ShelleyEra -> ChainState ShelleyEra)
-> (ChainState ShelleyEra -> ChainState ShelleyEra)
-> ChainState ShelleyEra
-> ChainState ShelleyEra
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Block (BHeader MockCrypto) ShelleyEra
-> ChainState ShelleyEra -> ChainState ShelleyEra
forall era.
Block (BHeader MockCrypto) era -> ChainState era -> ChainState era
C.newLab (MIRPot -> Block (BHeader MockCrypto) ShelleyEra
blockEx2 MIRPot
pot)
    (ChainState ShelleyEra -> ChainState ShelleyEra)
-> (ChainState ShelleyEra -> ChainState ShelleyEra)
-> ChainState ShelleyEra
-> ChainState ShelleyEra
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PulsingRewUpdate -> ChainState ShelleyEra -> ChainState ShelleyEra
forall era. PulsingRewUpdate -> ChainState era -> ChainState era
C.pulserUpdate (MIRPot -> PulsingRewUpdate
pulserEx2 MIRPot
pot)
    (ChainState ShelleyEra -> ChainState ShelleyEra)
-> ChainState ShelleyEra -> ChainState ShelleyEra
forall a b. (a -> b) -> a -> b
$ MIRPot -> ChainState ShelleyEra
expectedStEx1 MIRPot
pot

-- === Block 2, Slot 50, Epoch 0
--
-- Submit an empty block to create an empty reward update.
mir2 :: MIRPot -> CHAINExample ShelleyEra
mir2 :: MIRPot -> CHAINExample ShelleyEra
mir2 MIRPot
pot =
  ChainState ShelleyEra
-> Block (BHeader MockCrypto) ShelleyEra
-> Either
     (NonEmpty (PredicateFailure (CHAIN ShelleyEra)))
     (ChainState ShelleyEra)
-> CHAINExample ShelleyEra
forall era.
ChainState era
-> Block (BHeader MockCrypto) era
-> Either
     (NonEmpty (PredicateFailure (CHAIN era))) (ChainState era)
-> CHAINExample era
CHAINExample
    (MIRPot -> ChainState ShelleyEra
expectedStEx1 MIRPot
pot)
    (MIRPot -> Block (BHeader MockCrypto) ShelleyEra
blockEx2 MIRPot
pot)
    (ChainState ShelleyEra
-> Either
     (NonEmpty (PredicateFailure (CHAIN ShelleyEra)))
     (ChainState ShelleyEra)
forall a b. b -> Either a b
Right (ChainState ShelleyEra
 -> Either
      (NonEmpty (PredicateFailure (CHAIN ShelleyEra)))
      (ChainState ShelleyEra))
-> ChainState ShelleyEra
-> Either
     (NonEmpty (PredicateFailure (CHAIN ShelleyEra)))
     (ChainState ShelleyEra)
forall a b. (a -> b) -> a -> b
$ ChainState ShelleyEra -> ChainState ShelleyEra
forall era. EraGov era => ChainState era -> ChainState era
C.solidifyProposals (MIRPot -> ChainState ShelleyEra
expectedStEx2 MIRPot
pot))

--
-- Block 3, Slot 110, Epoch 1
--

epoch1Nonce :: MIRPot -> Nonce
epoch1Nonce :: MIRPot -> Nonce
epoch1Nonce MIRPot
pot = ChainState ShelleyEra -> Nonce
forall era. ChainState era -> Nonce
chainCandidateNonce (MIRPot -> ChainState ShelleyEra
expectedStEx2 MIRPot
pot)

blockEx3 :: MIRPot -> Block (BHeader MockCrypto) ShelleyEra
blockEx3 :: MIRPot -> Block (BHeader MockCrypto) ShelleyEra
blockEx3 MIRPot
pot =
  HashHeader
-> AllIssuerKeys MockCrypto 'GenesisDelegate
-> [Tx ShelleyEra]
-> SlotNo
-> BlockNo
-> Nonce
-> NatNonce
-> UnitInterval
-> Word
-> Word
-> OCert MockCrypto
-> Block (BHeader MockCrypto) ShelleyEra
forall era (r :: KeyRole) c.
(Crypto c, EraSegWits era, Signable (VRF c) (WithResult Seed),
 Signable (KES c) (BHBody c)) =>
HashHeader
-> AllIssuerKeys c r
-> [Tx era]
-> SlotNo
-> BlockNo
-> Nonce
-> NatNonce
-> UnitInterval
-> Word
-> Word
-> OCert c
-> Block (BHeader c) era
mkBlockFakeVRF
    (BHeader MockCrypto -> HashHeader
forall c. BHeader c -> HashHeader
bhHash (BHeader MockCrypto -> HashHeader)
-> BHeader MockCrypto -> HashHeader
forall a b. (a -> b) -> a -> b
$ Block (BHeader MockCrypto) ShelleyEra -> BHeader MockCrypto
forall h era. Block h era -> h
bheader (MIRPot -> Block (BHeader MockCrypto) ShelleyEra
blockEx2 MIRPot
pot))
    (forall era.
(HasCallStack, EraPParams era) =>
PParams era -> Word64 -> AllIssuerKeys MockCrypto 'GenesisDelegate
coreNodeKeysBySchedule @ShelleyEra PParams ShelleyEra
forall era.
(EraPParams era, ProtVerAtMost era 4, ProtVerAtMost era 6) =>
PParams era
ppEx Word64
110)
    []
    (Word64 -> SlotNo
SlotNo Word64
110)
    (Word64 -> BlockNo
BlockNo Word64
3)
    (MIRPot -> Nonce
epoch1Nonce MIRPot
pot)
    (Natural -> NatNonce
NatNonce Natural
3)
    UnitInterval
forall a. Bounded a => a
minBound
    Word
5
    Word
0
    (AllIssuerKeys MockCrypto 'GenesisDelegate
-> Word64 -> KESPeriod -> OCert MockCrypto
forall c (r :: KeyRole).
Crypto c =>
AllIssuerKeys c r -> Word64 -> KESPeriod -> OCert c
mkOCert (forall era.
(HasCallStack, EraPParams era) =>
PParams era -> Word64 -> AllIssuerKeys MockCrypto 'GenesisDelegate
coreNodeKeysBySchedule @ShelleyEra PParams ShelleyEra
forall era.
(EraPParams era, ProtVerAtMost era 4, ProtVerAtMost era 6) =>
PParams era
ppEx Word64
110) Word64
0 (Word -> KESPeriod
KESPeriod Word
0))

expectedStEx3 :: MIRPot -> ChainState ShelleyEra
expectedStEx3 :: MIRPot -> ChainState ShelleyEra
expectedStEx3 MIRPot
pot =
  Block (BHeader MockCrypto) ShelleyEra
-> ChainState ShelleyEra -> ChainState ShelleyEra
forall era.
(ProtVerAtMost era 6, EraGov era) =>
Block (BHeader MockCrypto) era -> ChainState era -> ChainState era
C.newEpoch (MIRPot -> Block (BHeader MockCrypto) ShelleyEra
blockEx3 MIRPot
pot)
    (ChainState ShelleyEra -> ChainState ShelleyEra)
-> (ChainState ShelleyEra -> ChainState ShelleyEra)
-> ChainState ShelleyEra
-> ChainState ShelleyEra
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SnapShot -> Coin -> ChainState ShelleyEra -> ChainState ShelleyEra
forall era. SnapShot -> Coin -> ChainState era -> ChainState era
C.newSnapshot SnapShot
emptySnapShot Coin
feeTx1
    (ChainState ShelleyEra -> ChainState ShelleyEra)
-> (ChainState ShelleyEra -> ChainState ShelleyEra)
-> ChainState ShelleyEra
-> ChainState ShelleyEra
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RewardUpdate -> ChainState ShelleyEra -> ChainState ShelleyEra
forall era.
(EraGov era, EraCertState era) =>
RewardUpdate -> ChainState era -> ChainState era
C.applyRewardUpdate RewardUpdate
emptyRewardUpdate
    (ChainState ShelleyEra -> ChainState ShelleyEra)
-> (ChainState ShelleyEra -> ChainState ShelleyEra)
-> ChainState ShelleyEra
-> ChainState ShelleyEra
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MIRPot
-> Map (Credential 'Staking) Coin
-> ChainState ShelleyEra
-> ChainState ShelleyEra
forall era.
EraCertState era =>
MIRPot
-> Map (Credential 'Staking) Coin
-> ChainState era
-> ChainState era
C.applyMIR MIRPot
pot (Credential 'Staking -> Coin -> Map (Credential 'Staking) Coin
forall k a. k -> a -> Map k a
Map.singleton Credential 'Staking
Cast.aliceSHK Coin
aliceMIRCoin)
    (ChainState ShelleyEra -> ChainState ShelleyEra)
-> ChainState ShelleyEra -> ChainState ShelleyEra
forall a b. (a -> b) -> a -> b
$ MIRPot -> ChainState ShelleyEra
expectedStEx2 MIRPot
pot

-- === Block 3, Slot 110, Epoch 1
--
-- Submit an empty block in the next epoch to apply the MIR rewards.
mir3 :: MIRPot -> CHAINExample ShelleyEra
mir3 :: MIRPot -> CHAINExample ShelleyEra
mir3 MIRPot
pot = ChainState ShelleyEra
-> Block (BHeader MockCrypto) ShelleyEra
-> Either
     (NonEmpty (PredicateFailure (CHAIN ShelleyEra)))
     (ChainState ShelleyEra)
-> CHAINExample ShelleyEra
forall era.
ChainState era
-> Block (BHeader MockCrypto) era
-> Either
     (NonEmpty (PredicateFailure (CHAIN era))) (ChainState era)
-> CHAINExample era
CHAINExample (MIRPot -> ChainState ShelleyEra
expectedStEx2 MIRPot
pot) (MIRPot -> Block (BHeader MockCrypto) ShelleyEra
blockEx3 MIRPot
pot) (ChainState ShelleyEra
-> Either
     (NonEmpty (PredicateFailure (CHAIN ShelleyEra)))
     (ChainState ShelleyEra)
forall a b. b -> Either a b
Right (ChainState ShelleyEra
 -> Either
      (NonEmpty (PredicateFailure (CHAIN ShelleyEra)))
      (ChainState ShelleyEra))
-> ChainState ShelleyEra
-> Either
     (NonEmpty (PredicateFailure (CHAIN ShelleyEra)))
     (ChainState ShelleyEra)
forall a b. (a -> b) -> a -> b
$ MIRPot -> ChainState ShelleyEra
expectedStEx3 MIRPot
pot)

--
-- MIR Test Group
--

mirExample :: TestTree
mirExample :: TestTree
mirExample =
  TestName -> [TestTree] -> TestTree
testGroup
    TestName
"move inst rewards"
    [ TestName -> Assertion -> TestTree
testCase TestName
"create MIR cert - reserves" (Assertion -> TestTree) -> Assertion -> TestTree
forall a b. (a -> b) -> a -> b
$ HasCallStack => CHAINExample ShelleyEra -> Assertion
CHAINExample ShelleyEra -> Assertion
testCHAINExample (MIRPot -> CHAINExample ShelleyEra
mir1 MIRPot
ReservesMIR)
    , TestName -> Assertion -> TestTree
testCase TestName
"create MIR cert - treasury" (Assertion -> TestTree) -> Assertion -> TestTree
forall a b. (a -> b) -> a -> b
$ HasCallStack => CHAINExample ShelleyEra -> Assertion
CHAINExample ShelleyEra -> Assertion
testCHAINExample (MIRPot -> CHAINExample ShelleyEra
mir1 MIRPot
TreasuryMIR)
    , TestName -> Assertion -> TestTree
testCase TestName
"insufficient MIR witnesses, reserves" (Assertion -> TestTree) -> Assertion -> TestTree
forall a b. (a -> b) -> a -> b
$
        HasCallStack => CHAINExample ShelleyEra -> Assertion
CHAINExample ShelleyEra -> Assertion
testCHAINExample (MIRPot -> CHAINExample ShelleyEra
mirFailWits MIRPot
ReservesMIR)
    , TestName -> Assertion -> TestTree
testCase TestName
"insufficient MIR witnesses, treasury" (Assertion -> TestTree) -> Assertion -> TestTree
forall a b. (a -> b) -> a -> b
$
        HasCallStack => CHAINExample ShelleyEra -> Assertion
CHAINExample ShelleyEra -> Assertion
testCHAINExample (MIRPot -> CHAINExample ShelleyEra
mirFailWits MIRPot
TreasuryMIR)
    , TestName -> Assertion -> TestTree
testCase TestName
"insufficient MIR funds, reserves" (Assertion -> TestTree) -> Assertion -> TestTree
forall a b. (a -> b) -> a -> b
$
        HasCallStack => CHAINExample ShelleyEra -> Assertion
CHAINExample ShelleyEra -> Assertion
testCHAINExample (MIRPot -> Coin -> Coin -> Coin -> CHAINExample ShelleyEra
mirFailFunds MIRPot
ReservesMIR (Integer -> Coin
Coin Integer
34000000000000000) (Integer -> Coin
Coin Integer
100) (Integer -> Coin
Coin Integer
0))
    , TestName -> Assertion -> TestTree
testCase TestName
"insufficient MIR funds, treasury" (Assertion -> TestTree) -> Assertion -> TestTree
forall a b. (a -> b) -> a -> b
$
        HasCallStack => CHAINExample ShelleyEra -> Assertion
CHAINExample ShelleyEra -> Assertion
testCHAINExample (MIRPot -> Coin -> Coin -> Coin -> CHAINExample ShelleyEra
mirFailFunds MIRPot
TreasuryMIR (Integer -> Coin
Coin Integer
99) (Integer -> Coin
Coin Integer
100) (Integer -> Coin
Coin Integer
99))
    , TestName -> Assertion -> TestTree
testCase TestName
"end of epoch after MIR - reserves" (Assertion -> TestTree) -> Assertion -> TestTree
forall a b. (a -> b) -> a -> b
$
        HasCallStack => CHAINExample ShelleyEra -> Assertion
CHAINExample ShelleyEra -> Assertion
testCHAINExample (MIRPot -> CHAINExample ShelleyEra
mir2 MIRPot
ReservesMIR)
    , TestName -> Assertion -> TestTree
testCase TestName
"end of epoch after MIR - treasury" (Assertion -> TestTree) -> Assertion -> TestTree
forall a b. (a -> b) -> a -> b
$
        HasCallStack => CHAINExample ShelleyEra -> Assertion
CHAINExample ShelleyEra -> Assertion
testCHAINExample (MIRPot -> CHAINExample ShelleyEra
mir2 MIRPot
TreasuryMIR)
    , TestName -> Assertion -> TestTree
testCase TestName
"apply MIR - reserves" (Assertion -> TestTree) -> Assertion -> TestTree
forall a b. (a -> b) -> a -> b
$ HasCallStack => CHAINExample ShelleyEra -> Assertion
CHAINExample ShelleyEra -> Assertion
testCHAINExample (MIRPot -> CHAINExample ShelleyEra
mir3 MIRPot
ReservesMIR)
    , TestName -> Assertion -> TestTree
testCase TestName
"apply MIR - treasury" (Assertion -> TestTree) -> Assertion -> TestTree
forall a b. (a -> b) -> a -> b
$ HasCallStack => CHAINExample ShelleyEra -> Assertion
CHAINExample ShelleyEra -> Assertion
testCHAINExample (MIRPot -> CHAINExample ShelleyEra
mir3 MIRPot
TreasuryMIR)
    ]