{-# 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 , InjectRuleFailure "LEDGER" ShelleyUtxoPredFailure era ) => SpecWith (ImpInit (LedgerSpec era)) spec :: forall era. (ShelleyEraImp era, InjectRuleFailure "LEDGER" ShelleyUtxoPredFailure 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 Addr addr1 <- ImpM (LedgerSpec era) Addr forall s (m :: * -> *) g. (HasKeyPairs s, MonadState s m, HasStatefulGen g m, MonadGen m) => m Addr freshKeyAddr_ let txAmount :: Coin txAmount = Integer -> Coin Coin Integer 2000000 TxIn txIn <- Addr -> Coin -> ImpTestM era TxIn forall era. (ShelleyEraImp era, HasCallStack) => Addr -> Coin -> ImpTestM era TxIn sendCoinTo Addr addr1 Coin txAmount Addr addr2 <- ImpM (LedgerSpec era) Addr forall s (m :: * -> *) g. (HasKeyPairs s, MonadState s m, HasStatefulGen g m, MonadGen m) => m Addr freshKeyAddr_ (TxIn _, TxOut era rootTxOut) <- ImpTestM era (TxIn, TxOut era) forall era. ImpTestM era (TxIn, TxOut era) getImpRootTxOut let extra :: Coin extra = Integer -> Coin Coin Integer 3 rootTxOutValue :: Value era 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 era txBody = TxBody era forall era. EraTxBody era => TxBody era mkBasicTxBody TxBody era -> (TxBody era -> TxBody era) -> TxBody era forall a b. a -> (a -> b) -> b & (Set TxIn -> Identity (Set TxIn)) -> TxBody era -> Identity (TxBody era) forall era. EraTxBody era => Lens' (TxBody era) (Set TxIn) Lens' (TxBody era) (Set TxIn) inputsTxBodyL ((Set TxIn -> Identity (Set TxIn)) -> TxBody era -> Identity (TxBody era)) -> Set TxIn -> TxBody era -> TxBody era forall s t a b. ASetter s t a b -> b -> s -> t .~ [Item (Set TxIn) TxIn txIn] TxBody era -> (TxBody era -> TxBody era) -> TxBody era forall a b. a -> (a -> b) -> b & (StrictSeq (TxOut era) -> Identity (StrictSeq (TxOut era))) -> TxBody era -> Identity (TxBody era) forall era. EraTxBody era => Lens' (TxBody era) (StrictSeq (TxOut era)) Lens' (TxBody era) (StrictSeq (TxOut era)) outputsTxBodyL ((StrictSeq (TxOut era) -> Identity (StrictSeq (TxOut era))) -> TxBody era -> Identity (TxBody era)) -> StrictSeq (TxOut era) -> TxBody era -> TxBody 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 :: StrictSeq (TxOut era) -> StrictSeq (TxOut era) 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 era -> Tx era adjustFirstTxOut Tx era tx = Tx era tx Tx era -> (Tx era -> Tx era) -> Tx era forall a b. a -> (a -> b) -> b & (TxBody era -> Identity (TxBody era)) -> Tx era -> Identity (Tx era) forall era. EraTx era => Lens' (Tx era) (TxBody era) Lens' (Tx era) (TxBody era) bodyTxL ((TxBody era -> Identity (TxBody era)) -> Tx era -> Identity (Tx era)) -> ((StrictSeq (TxOut era) -> Identity (StrictSeq (TxOut era))) -> TxBody era -> Identity (TxBody era)) -> (StrictSeq (TxOut era) -> Identity (StrictSeq (TxOut era))) -> Tx era -> Identity (Tx era) forall b c a. (b -> c) -> (a -> b) -> a -> c . (StrictSeq (TxOut era) -> Identity (StrictSeq (TxOut era))) -> TxBody era -> Identity (TxBody era) forall era. EraTxBody era => Lens' (TxBody era) (StrictSeq (TxOut era)) Lens' (TxBody era) (StrictSeq (TxOut era)) outputsTxBodyL ((StrictSeq (TxOut era) -> Identity (StrictSeq (TxOut era))) -> Tx era -> Identity (Tx era)) -> (StrictSeq (TxOut era) -> StrictSeq (TxOut era)) -> Tx era -> Tx era forall s t a b. ASetter s t a b -> (a -> b) -> s -> t %~ StrictSeq (TxOut era) -> StrictSeq (TxOut era) adjustTxOut Tx era -> (Tx era -> Tx era) -> Tx era forall a b. a -> (a -> b) -> b & (TxWits era -> Identity (TxWits era)) -> Tx era -> Identity (Tx era) forall era. EraTx era => Lens' (Tx era) (TxWits era) Lens' (Tx era) (TxWits era) witsTxL ((TxWits era -> Identity (TxWits era)) -> Tx era -> Identity (Tx era)) -> TxWits era -> Tx era -> Tx era forall s t a b. ASetter s t a b -> b -> s -> t .~ TxWits era forall era. EraTxWits era => TxWits era mkBasicTxWits (Tx era -> ImpTestM era (Tx era)) -> ImpM (LedgerSpec era) () -> ImpM (LedgerSpec era) () forall era a. (Tx era -> ImpTestM era (Tx era)) -> ImpTestM era a -> ImpTestM era a withPostFixup (Tx era -> ImpTestM era (Tx era) forall era. (HasCallStack, ShelleyEraImp era) => Tx era -> ImpTestM era (Tx era) updateAddrTxWits (Tx era -> ImpTestM era (Tx era)) -> (Tx era -> Tx era) -> Tx era -> ImpTestM era (Tx era) forall b c a. (b -> c) -> (a -> b) -> a -> c . Tx era -> Tx era adjustFirstTxOut) (ImpM (LedgerSpec era) () -> ImpM (LedgerSpec era) ()) -> ImpM (LedgerSpec era) () -> ImpM (LedgerSpec era) () forall a b. (a -> b) -> a -> b $ Tx era -> NonEmpty (PredicateFailure (EraRule "LEDGER" era)) -> ImpM (LedgerSpec era) () forall era. (HasCallStack, ShelleyEraImp era) => Tx era -> NonEmpty (PredicateFailure (EraRule "LEDGER" era)) -> ImpTestM era () submitFailingTx (TxBody era -> Tx era forall era. EraTx era => TxBody era -> Tx era mkBasicTx TxBody era txBody) [ ShelleyUtxoPredFailure era -> EraRuleFailure "LEDGER" era forall (rule :: Symbol) (t :: * -> *) era. InjectRuleFailure rule t era => t era -> EraRuleFailure rule era injectFailure (ShelleyUtxoPredFailure era -> EraRuleFailure "LEDGER" era) -> ShelleyUtxoPredFailure era -> EraRuleFailure "LEDGER" era forall a b. (a -> b) -> a -> b $ Mismatch 'RelEQ (Value era) -> ShelleyUtxoPredFailure era forall era. Mismatch 'RelEQ (Value era) -> ShelleyUtxoPredFailure era ValueNotConservedUTxO (Mismatch 'RelEQ (Value era) -> ShelleyUtxoPredFailure era) -> Mismatch 'RelEQ (Value era) -> ShelleyUtxoPredFailure era forall a b. (a -> b) -> a -> b $ Value era -> Value era -> Mismatch 'RelEQ (Value era) forall (r :: Relation) a. a -> a -> Mismatch r a Mismatch (Value era rootTxOutValue Value era -> Value era -> Value era forall a. Semigroup a => a -> a -> a <> Coin -> Value era forall t s. Inject t s => t -> s inject Coin txAmount) (Value era rootTxOutValue Value era -> Value era -> Value era forall a. Semigroup a => a -> a -> a <> Coin -> Value era forall t s. Inject t s => t -> s inject (Coin txAmount Coin -> Coin -> Coin forall a. Semigroup a => a -> a -> a <> Coin extra)) ]