{-# LANGUAGE DataKinds #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE OverloadedLists #-} {-# LANGUAGE ScopedTypeVariables #-} module Test.Cardano.Ledger.Shelley.Imp.UtxoSpec (spec) where import Cardano.Ledger.BaseTypes (Mismatch (..)) import Cardano.Ledger.Coin (Coin (..)) import Cardano.Ledger.Core import Cardano.Ledger.Shelley.Rules (ShelleyUtxoPredFailure (..)) import Cardano.Ledger.Val (inject) import Data.Sequence.Strict (StrictSeq (..)) import Lens.Micro import Test.Cardano.Ledger.Imp.Common import Test.Cardano.Ledger.Shelley.ImpTest spec :: ShelleyEraImp era => SpecWith (ImpInit (LedgerSpec era)) spec :: forall era. ShelleyEraImp era => SpecWith (ImpInit (LedgerSpec era)) spec = String -> SpecWith (ImpInit (LedgerSpec era)) -> SpecWith (ImpInit (LedgerSpec era)) forall a. HasCallStack => String -> SpecWith a -> SpecWith a describe String "UTXO" (SpecWith (ImpInit (LedgerSpec era)) -> SpecWith (ImpInit (LedgerSpec era))) -> SpecWith (ImpInit (LedgerSpec era)) -> SpecWith (ImpInit (LedgerSpec era)) forall a b. (a -> b) -> a -> b $ do String -> SpecWith (ImpInit (LedgerSpec era)) -> SpecWith (ImpInit (LedgerSpec era)) forall a. HasCallStack => String -> SpecWith a -> SpecWith a describe String "ShelleyUtxoPredFailure" (SpecWith (ImpInit (LedgerSpec era)) -> SpecWith (ImpInit (LedgerSpec era))) -> SpecWith (ImpInit (LedgerSpec era)) -> SpecWith (ImpInit (LedgerSpec era)) forall a b. (a -> b) -> a -> b $ do String -> ImpM (LedgerSpec era) () -> SpecWith (Arg (ImpM (LedgerSpec era) ())) forall a. (HasCallStack, Example a) => String -> a -> SpecWith (Arg a) it String "ValueNotConservedUTxO" (ImpM (LedgerSpec era) () -> SpecWith (Arg (ImpM (LedgerSpec era) ()))) -> ImpM (LedgerSpec era) () -> SpecWith (Arg (ImpM (LedgerSpec era) ())) forall a b. (a -> b) -> a -> b $ do addr1 <- ImpM (LedgerSpec era) Addr forall s (m :: * -> *) g. (HasKeyPairs s, MonadState s m, HasStatefulGen g m, MonadGen m) => m Addr freshKeyAddr_ let txAmount = Integer -> Coin Coin Integer 2000000 txIn <- sendCoinTo addr1 txAmount addr2 <- freshKeyAddr_ (_, rootTxOut) <- getImpRootTxOut let extra = Integer -> Coin Coin Integer 3 rootTxOutValue = TxOut era rootTxOut TxOut era -> Getting (Value era) (TxOut era) (Value era) -> Value era forall s a. s -> Getting a s a -> a ^. Getting (Value era) (TxOut era) (Value era) forall era. EraTxOut era => Lens' (TxOut era) (Value era) Lens' (TxOut era) (Value era) valueTxOutL txBody = TxBody TopTx era forall era (l :: TxLevel). (EraTxBody era, Typeable l) => TxBody l era forall (l :: TxLevel). Typeable l => TxBody l era mkBasicTxBody TxBody TopTx era -> (TxBody TopTx era -> TxBody TopTx era) -> TxBody TopTx era forall a b. a -> (a -> b) -> b & (Set TxIn -> Identity (Set TxIn)) -> TxBody TopTx era -> Identity (TxBody TopTx era) forall era (l :: TxLevel). EraTxBody era => Lens' (TxBody l era) (Set TxIn) forall (l :: TxLevel). Lens' (TxBody l era) (Set TxIn) inputsTxBodyL ((Set TxIn -> Identity (Set TxIn)) -> TxBody TopTx era -> Identity (TxBody TopTx era)) -> Set TxIn -> TxBody TopTx era -> TxBody TopTx era forall s t a b. ASetter s t a b -> b -> s -> t .~ [Item (Set TxIn) TxIn txIn] TxBody TopTx era -> (TxBody TopTx era -> TxBody TopTx era) -> TxBody TopTx era forall a b. a -> (a -> b) -> b & (StrictSeq (TxOut era) -> Identity (StrictSeq (TxOut era))) -> TxBody TopTx era -> Identity (TxBody TopTx era) forall era (l :: TxLevel). EraTxBody era => Lens' (TxBody l era) (StrictSeq (TxOut era)) forall (l :: TxLevel). Lens' (TxBody l era) (StrictSeq (TxOut era)) outputsTxBodyL ((StrictSeq (TxOut era) -> Identity (StrictSeq (TxOut era))) -> TxBody TopTx era -> Identity (TxBody TopTx era)) -> StrictSeq (TxOut era) -> TxBody TopTx era -> TxBody TopTx era forall s t a b. ASetter s t a b -> b -> s -> t .~ [Addr -> Value era -> TxOut era forall era. (EraTxOut era, HasCallStack) => Addr -> Value era -> TxOut era mkBasicTxOut Addr addr2 Value era forall a. Monoid a => a mempty] adjustTxOut = \case StrictSeq (TxOut era) Empty -> String -> StrictSeq (TxOut era) forall a. HasCallStack => String -> a error String "Unexpected empty sequence of outputs" TxOut era txOut :<| StrictSeq (TxOut era) outs -> (TxOut era txOut TxOut era -> (TxOut era -> TxOut era) -> TxOut era forall a b. a -> (a -> b) -> b & (Coin -> Identity Coin) -> TxOut era -> Identity (TxOut era) forall era. (HasCallStack, EraTxOut era) => Lens' (TxOut era) Coin Lens' (TxOut era) Coin coinTxOutL ((Coin -> Identity Coin) -> TxOut era -> Identity (TxOut era)) -> (Coin -> Coin) -> TxOut era -> TxOut era forall s t a b. ASetter s t a b -> (a -> b) -> s -> t %~ (Coin -> Coin -> Coin forall a. Semigroup a => a -> a -> a <> Coin extra)) TxOut era -> StrictSeq (TxOut era) -> StrictSeq (TxOut era) forall a. a -> StrictSeq a -> StrictSeq a :<| StrictSeq (TxOut era) outs adjustFirstTxOut Tx l era tx = Tx l era tx Tx l era -> (Tx l era -> Tx l era) -> Tx l era forall a b. a -> (a -> b) -> b & (TxBody l era -> Identity (TxBody l era)) -> Tx l era -> Identity (Tx l era) forall era (l :: TxLevel). EraTx era => Lens' (Tx l era) (TxBody l era) forall (l :: TxLevel). Lens' (Tx l era) (TxBody l era) bodyTxL ((TxBody l era -> Identity (TxBody l era)) -> Tx l era -> Identity (Tx l era)) -> ((StrictSeq (TxOut era) -> Identity (StrictSeq (TxOut era))) -> TxBody l era -> Identity (TxBody l era)) -> (StrictSeq (TxOut era) -> Identity (StrictSeq (TxOut era))) -> Tx l era -> Identity (Tx l era) forall b c a. (b -> c) -> (a -> b) -> a -> c . (StrictSeq (TxOut era) -> Identity (StrictSeq (TxOut era))) -> TxBody l era -> Identity (TxBody l era) forall era (l :: TxLevel). EraTxBody era => Lens' (TxBody l era) (StrictSeq (TxOut era)) forall (l :: TxLevel). Lens' (TxBody l era) (StrictSeq (TxOut era)) outputsTxBodyL ((StrictSeq (TxOut era) -> Identity (StrictSeq (TxOut era))) -> Tx l era -> Identity (Tx l era)) -> (StrictSeq (TxOut era) -> StrictSeq (TxOut era)) -> Tx l era -> Tx l era forall s t a b. ASetter s t a b -> (a -> b) -> s -> t %~ StrictSeq (TxOut era) -> StrictSeq (TxOut era) adjustTxOut Tx l era -> (Tx l era -> Tx l era) -> Tx l era forall a b. a -> (a -> b) -> b & (TxWits era -> Identity (TxWits era)) -> Tx l era -> Identity (Tx l era) forall era (l :: TxLevel). EraTx era => Lens' (Tx l era) (TxWits era) forall (l :: TxLevel). Lens' (Tx l era) (TxWits era) witsTxL ((TxWits era -> Identity (TxWits era)) -> Tx l era -> Identity (Tx l era)) -> TxWits era -> Tx l era -> Tx l era forall s t a b. ASetter s t a b -> b -> s -> t .~ TxWits era forall era. EraTxWits era => TxWits era mkBasicTxWits withPostFixup (updateAddrTxWits . adjustFirstTxOut) $ submitFailingTx (mkBasicTx txBody) [ injectFailure $ ValueNotConservedUTxO $ Mismatch (rootTxOutValue <> inject txAmount) (rootTxOutValue <> inject (txAmount <> extra)) ]