{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE PartialTypeSignatures #-}
{-# LANGUAGE RecordWildCards #-}
{-# OPTIONS_GHC -fno-warn-partial-type-signatures #-}

module Cardano.Wallet.Primitive.Types.Tx.Gen
    ( coarbitraryTxIn
    , genTx
    , genTxHash
    , genTxIndex
    , genTxIn
    , genTxInFunction
    , genTxInLargeRange
    , genTxOut
    , genTxOutCoin
    , genTxOutTokenBundle
    , genTxScriptValidity
    , shrinkTx
    , shrinkTxHash
    , shrinkTxIndex
    , shrinkTxIn
    , shrinkTxOut
    , shrinkTxOutCoin
    , shrinkTxScriptValidity
    )
    where

import Prelude

import Cardano.Wallet.Gen
    ( genNestedTxMetadata, shrinkTxMetadata )
import Cardano.Wallet.Primitive.Types.Address.Gen
    ( genAddress, shrinkAddress )
import Cardano.Wallet.Primitive.Types.Coin
    ( Coin (..) )
import Cardano.Wallet.Primitive.Types.Coin.Gen
    ( genCoinPositive, shrinkCoinPositive )
import Cardano.Wallet.Primitive.Types.Hash
    ( Hash (..), mockHash )
import Cardano.Wallet.Primitive.Types.RewardAccount
    ( RewardAccount (..) )
import Cardano.Wallet.Primitive.Types.RewardAccount.Gen
    ( genRewardAccount, shrinkRewardAccount )
import Cardano.Wallet.Primitive.Types.TokenBundle
    ( TokenBundle )
import Cardano.Wallet.Primitive.Types.TokenBundle.Gen
    ( genTokenBundleSmallRange, shrinkTokenBundleSmallRange )
import Cardano.Wallet.Primitive.Types.TokenMap.Gen
    ( genAssetIdLargeRange )
import Cardano.Wallet.Primitive.Types.TokenQuantity
    ( TokenQuantity (..) )
import Cardano.Wallet.Primitive.Types.Tx
    ( Tx (..)
    , TxIn (..)
    , TxMetadata (..)
    , TxOut (..)
    , TxScriptValidity (..)
    , coinIsValidForTxOut
    , txOutMaxCoin
    , txOutMaxTokenQuantity
    , txOutMinCoin
    , txOutMinTokenQuantity
    )
import Control.Monad
    ( replicateM )
import Data.Either
    ( fromRight )
import Data.Map.Strict
    ( Map )
import Data.Text.Class
    ( FromText (..) )
import Data.Word
    ( Word16, Word32 )
import Generics.SOP
    ( NP (..) )
import GHC.Generics
    ( Generic )
import Test.QuickCheck
    ( Gen
    , arbitrary
    , choose
    , coarbitrary
    , elements
    , frequency
    , liftArbitrary
    , liftArbitrary2
    , liftShrink
    , liftShrink2
    , listOf
    , listOf1
    , oneof
    , shrinkList
    , shrinkMapBy
    , sized
    , suchThat
    )
import Test.QuickCheck.Arbitrary.Generic
    ( genericArbitrary, genericShrink )
import Test.QuickCheck.Extra
    ( chooseNatural
    , genFunction
    , genMapWith
    , genSized2With
    , genericRoundRobinShrink
    , shrinkInterleaved
    , shrinkMapWith
    , shrinkNatural
    , (<:>)
    , (<@>)
    )

import qualified Cardano.Wallet.Primitive.Types.Coin as Coin
import qualified Cardano.Wallet.Primitive.Types.TokenBundle as TokenBundle
import qualified Data.ByteString.Char8 as B8
import qualified Data.List as L
import qualified Data.Text as T

--------------------------------------------------------------------------------
-- Transactions generated according to the size parameter
--------------------------------------------------------------------------------

genTx :: Gen Tx
genTx :: Gen Tx
genTx = TxWithoutId -> Tx
txWithoutIdToTx (TxWithoutId -> Tx) -> Gen TxWithoutId -> Gen Tx
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen TxWithoutId
genTxWithoutId

shrinkTx :: Tx -> [Tx]
shrinkTx :: Tx -> [Tx]
shrinkTx = (TxWithoutId -> Tx)
-> (Tx -> TxWithoutId)
-> (TxWithoutId -> [TxWithoutId])
-> Tx
-> [Tx]
forall a b. (a -> b) -> (b -> a) -> (a -> [a]) -> b -> [b]
shrinkMapBy TxWithoutId -> Tx
txWithoutIdToTx Tx -> TxWithoutId
txToTxWithoutId TxWithoutId -> [TxWithoutId]
shrinkTxWithoutId

data TxWithoutId = TxWithoutId
    { TxWithoutId -> Maybe Coin
fee :: !(Maybe Coin)
    , TxWithoutId -> [(TxIn, Coin)]
resolvedInputs :: ![(TxIn, Coin)]
    , TxWithoutId -> [(TxIn, Coin)]
resolvedCollateralInputs :: ![(TxIn, Coin)]
    , TxWithoutId -> [TxOut]
outputs :: ![TxOut]
    , TxWithoutId -> Maybe TxOut
collateralOutput :: !(Maybe TxOut)
    , TxWithoutId -> Maybe TxMetadata
metadata :: !(Maybe TxMetadata)
    , TxWithoutId -> Map RewardAccount Coin
withdrawals :: !(Map RewardAccount Coin)
    , TxWithoutId -> Maybe TxScriptValidity
scriptValidity :: !(Maybe TxScriptValidity)
    }
    deriving (TxWithoutId -> TxWithoutId -> Bool
(TxWithoutId -> TxWithoutId -> Bool)
-> (TxWithoutId -> TxWithoutId -> Bool) -> Eq TxWithoutId
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: TxWithoutId -> TxWithoutId -> Bool
$c/= :: TxWithoutId -> TxWithoutId -> Bool
== :: TxWithoutId -> TxWithoutId -> Bool
$c== :: TxWithoutId -> TxWithoutId -> Bool
Eq, (forall x. TxWithoutId -> Rep TxWithoutId x)
-> (forall x. Rep TxWithoutId x -> TxWithoutId)
-> Generic TxWithoutId
forall x. Rep TxWithoutId x -> TxWithoutId
forall x. TxWithoutId -> Rep TxWithoutId x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep TxWithoutId x -> TxWithoutId
$cfrom :: forall x. TxWithoutId -> Rep TxWithoutId x
Generic, Eq TxWithoutId
Eq TxWithoutId
-> (TxWithoutId -> TxWithoutId -> Ordering)
-> (TxWithoutId -> TxWithoutId -> Bool)
-> (TxWithoutId -> TxWithoutId -> Bool)
-> (TxWithoutId -> TxWithoutId -> Bool)
-> (TxWithoutId -> TxWithoutId -> Bool)
-> (TxWithoutId -> TxWithoutId -> TxWithoutId)
-> (TxWithoutId -> TxWithoutId -> TxWithoutId)
-> Ord TxWithoutId
TxWithoutId -> TxWithoutId -> Bool
TxWithoutId -> TxWithoutId -> Ordering
TxWithoutId -> TxWithoutId -> TxWithoutId
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: TxWithoutId -> TxWithoutId -> TxWithoutId
$cmin :: TxWithoutId -> TxWithoutId -> TxWithoutId
max :: TxWithoutId -> TxWithoutId -> TxWithoutId
$cmax :: TxWithoutId -> TxWithoutId -> TxWithoutId
>= :: TxWithoutId -> TxWithoutId -> Bool
$c>= :: TxWithoutId -> TxWithoutId -> Bool
> :: TxWithoutId -> TxWithoutId -> Bool
$c> :: TxWithoutId -> TxWithoutId -> Bool
<= :: TxWithoutId -> TxWithoutId -> Bool
$c<= :: TxWithoutId -> TxWithoutId -> Bool
< :: TxWithoutId -> TxWithoutId -> Bool
$c< :: TxWithoutId -> TxWithoutId -> Bool
compare :: TxWithoutId -> TxWithoutId -> Ordering
$ccompare :: TxWithoutId -> TxWithoutId -> Ordering
$cp1Ord :: Eq TxWithoutId
Ord, Int -> TxWithoutId -> ShowS
[TxWithoutId] -> ShowS
TxWithoutId -> String
(Int -> TxWithoutId -> ShowS)
-> (TxWithoutId -> String)
-> ([TxWithoutId] -> ShowS)
-> Show TxWithoutId
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [TxWithoutId] -> ShowS
$cshowList :: [TxWithoutId] -> ShowS
show :: TxWithoutId -> String
$cshow :: TxWithoutId -> String
showsPrec :: Int -> TxWithoutId -> ShowS
$cshowsPrec :: Int -> TxWithoutId -> ShowS
Show)

genTxWithoutId :: Gen TxWithoutId
genTxWithoutId :: Gen TxWithoutId
genTxWithoutId = Maybe Coin
-> [(TxIn, Coin)]
-> [(TxIn, Coin)]
-> [TxOut]
-> Maybe TxOut
-> Maybe TxMetadata
-> Map RewardAccount Coin
-> Maybe TxScriptValidity
-> TxWithoutId
TxWithoutId
    (Maybe Coin
 -> [(TxIn, Coin)]
 -> [(TxIn, Coin)]
 -> [TxOut]
 -> Maybe TxOut
 -> Maybe TxMetadata
 -> Map RewardAccount Coin
 -> Maybe TxScriptValidity
 -> TxWithoutId)
-> Gen (Maybe Coin)
-> Gen
     ([(TxIn, Coin)]
      -> [(TxIn, Coin)]
      -> [TxOut]
      -> Maybe TxOut
      -> Maybe TxMetadata
      -> Map RewardAccount Coin
      -> Maybe TxScriptValidity
      -> TxWithoutId)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen Coin -> Gen (Maybe Coin)
forall (f :: * -> *) a. Arbitrary1 f => Gen a -> Gen (f a)
liftArbitrary Gen Coin
genCoinPositive
    Gen
  ([(TxIn, Coin)]
   -> [(TxIn, Coin)]
   -> [TxOut]
   -> Maybe TxOut
   -> Maybe TxMetadata
   -> Map RewardAccount Coin
   -> Maybe TxScriptValidity
   -> TxWithoutId)
-> Gen [(TxIn, Coin)]
-> Gen
     ([(TxIn, Coin)]
      -> [TxOut]
      -> Maybe TxOut
      -> Maybe TxMetadata
      -> Map RewardAccount Coin
      -> Maybe TxScriptValidity
      -> TxWithoutId)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen (TxIn, Coin) -> Gen [(TxIn, Coin)]
forall a. Gen a -> Gen [a]
listOf1 (Gen TxIn -> Gen Coin -> Gen (TxIn, Coin)
forall (f :: * -> * -> *) a b.
Arbitrary2 f =>
Gen a -> Gen b -> Gen (f a b)
liftArbitrary2 Gen TxIn
genTxIn Gen Coin
genCoinPositive)
    Gen
  ([(TxIn, Coin)]
   -> [TxOut]
   -> Maybe TxOut
   -> Maybe TxMetadata
   -> Map RewardAccount Coin
   -> Maybe TxScriptValidity
   -> TxWithoutId)
-> Gen [(TxIn, Coin)]
-> Gen
     ([TxOut]
      -> Maybe TxOut
      -> Maybe TxMetadata
      -> Map RewardAccount Coin
      -> Maybe TxScriptValidity
      -> TxWithoutId)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen (TxIn, Coin) -> Gen [(TxIn, Coin)]
forall a. Gen a -> Gen [a]
listOf1 (Gen TxIn -> Gen Coin -> Gen (TxIn, Coin)
forall (f :: * -> * -> *) a b.
Arbitrary2 f =>
Gen a -> Gen b -> Gen (f a b)
liftArbitrary2 Gen TxIn
genTxIn Gen Coin
genCoinPositive)
    Gen
  ([TxOut]
   -> Maybe TxOut
   -> Maybe TxMetadata
   -> Map RewardAccount Coin
   -> Maybe TxScriptValidity
   -> TxWithoutId)
-> Gen [TxOut]
-> Gen
     (Maybe TxOut
      -> Maybe TxMetadata
      -> Map RewardAccount Coin
      -> Maybe TxScriptValidity
      -> TxWithoutId)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen TxOut -> Gen [TxOut]
forall a. Gen a -> Gen [a]
listOf Gen TxOut
genTxOut
    Gen
  (Maybe TxOut
   -> Maybe TxMetadata
   -> Map RewardAccount Coin
   -> Maybe TxScriptValidity
   -> TxWithoutId)
-> Gen (Maybe TxOut)
-> Gen
     (Maybe TxMetadata
      -> Map RewardAccount Coin -> Maybe TxScriptValidity -> TxWithoutId)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen TxOut -> Gen (Maybe TxOut)
forall (f :: * -> *) a. Arbitrary1 f => Gen a -> Gen (f a)
liftArbitrary Gen TxOut
genTxOut
    Gen
  (Maybe TxMetadata
   -> Map RewardAccount Coin -> Maybe TxScriptValidity -> TxWithoutId)
-> Gen (Maybe TxMetadata)
-> Gen
     (Map RewardAccount Coin -> Maybe TxScriptValidity -> TxWithoutId)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen TxMetadata -> Gen (Maybe TxMetadata)
forall (f :: * -> *) a. Arbitrary1 f => Gen a -> Gen (f a)
liftArbitrary Gen TxMetadata
genNestedTxMetadata
    Gen
  (Map RewardAccount Coin -> Maybe TxScriptValidity -> TxWithoutId)
-> Gen (Map RewardAccount Coin)
-> Gen (Maybe TxScriptValidity -> TxWithoutId)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen RewardAccount -> Gen Coin -> Gen (Map RewardAccount Coin)
forall k v. Ord k => Gen k -> Gen v -> Gen (Map k v)
genMapWith Gen RewardAccount
genRewardAccount Gen Coin
genCoinPositive
    Gen (Maybe TxScriptValidity -> TxWithoutId)
-> Gen (Maybe TxScriptValidity) -> Gen TxWithoutId
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen TxScriptValidity -> Gen (Maybe TxScriptValidity)
forall (f :: * -> *) a. Arbitrary1 f => Gen a -> Gen (f a)
liftArbitrary Gen TxScriptValidity
genTxScriptValidity

shrinkTxWithoutId :: TxWithoutId -> [TxWithoutId]
shrinkTxWithoutId :: TxWithoutId -> [TxWithoutId]
shrinkTxWithoutId = NP
  (I -.-> [])
  '[Maybe Coin, [(TxIn, Coin)], [(TxIn, Coin)], [TxOut], Maybe TxOut,
    Maybe TxMetadata, Map RewardAccount Coin, Maybe TxScriptValidity]
-> TxWithoutId -> [TxWithoutId]
forall a (xs :: [*]).
(Generic a, GFrom a, GTo a, GCode a ~ '[xs]) =>
NP (I -.-> []) xs -> a -> [a]
genericRoundRobinShrink
    (NP
   (I -.-> [])
   '[Maybe Coin, [(TxIn, Coin)], [(TxIn, Coin)], [TxOut], Maybe TxOut,
     Maybe TxMetadata, Map RewardAccount Coin, Maybe TxScriptValidity]
 -> TxWithoutId -> [TxWithoutId])
-> NP
     (I -.-> [])
     '[Maybe Coin, [(TxIn, Coin)], [(TxIn, Coin)], [TxOut], Maybe TxOut,
       Maybe TxMetadata, Map RewardAccount Coin, Maybe TxScriptValidity]
-> TxWithoutId
-> [TxWithoutId]
forall a b. (a -> b) -> a -> b
<@> (Coin -> [Coin]) -> Maybe Coin -> [Maybe Coin]
forall (f :: * -> *) a. Arbitrary1 f => (a -> [a]) -> f a -> [f a]
liftShrink Coin -> [Coin]
shrinkCoinPositive
    (Maybe Coin -> [Maybe Coin])
-> NP
     (I -.-> [])
     '[[(TxIn, Coin)], [(TxIn, Coin)], [TxOut], Maybe TxOut,
       Maybe TxMetadata, Map RewardAccount Coin, Maybe TxScriptValidity]
-> NP
     (I -.-> [])
     '[Maybe Coin, [(TxIn, Coin)], [(TxIn, Coin)], [TxOut], Maybe TxOut,
       Maybe TxMetadata, Map RewardAccount Coin, Maybe TxScriptValidity]
forall x (xs :: [*]).
(x -> [x]) -> NP (I -.-> []) xs -> NP (I -.-> []) (x : xs)
<:> ((TxIn, Coin) -> [(TxIn, Coin)])
-> [(TxIn, Coin)] -> [[(TxIn, Coin)]]
forall a. (a -> [a]) -> [a] -> [[a]]
shrinkList ((TxIn -> [TxIn])
-> (Coin -> [Coin]) -> (TxIn, Coin) -> [(TxIn, Coin)]
forall (f :: * -> * -> *) a b.
Arbitrary2 f =>
(a -> [a]) -> (b -> [b]) -> f a b -> [f a b]
liftShrink2 TxIn -> [TxIn]
shrinkTxIn Coin -> [Coin]
shrinkCoinPositive)
    ([(TxIn, Coin)] -> [[(TxIn, Coin)]])
-> NP
     (I -.-> [])
     '[[(TxIn, Coin)], [TxOut], Maybe TxOut, Maybe TxMetadata,
       Map RewardAccount Coin, Maybe TxScriptValidity]
-> NP
     (I -.-> [])
     '[[(TxIn, Coin)], [(TxIn, Coin)], [TxOut], Maybe TxOut,
       Maybe TxMetadata, Map RewardAccount Coin, Maybe TxScriptValidity]
forall x (xs :: [*]).
(x -> [x]) -> NP (I -.-> []) xs -> NP (I -.-> []) (x : xs)
<:> ((TxIn, Coin) -> [(TxIn, Coin)])
-> [(TxIn, Coin)] -> [[(TxIn, Coin)]]
forall a. (a -> [a]) -> [a] -> [[a]]
shrinkList ((TxIn -> [TxIn])
-> (Coin -> [Coin]) -> (TxIn, Coin) -> [(TxIn, Coin)]
forall (f :: * -> * -> *) a b.
Arbitrary2 f =>
(a -> [a]) -> (b -> [b]) -> f a b -> [f a b]
liftShrink2 TxIn -> [TxIn]
shrinkTxIn Coin -> [Coin]
shrinkCoinPositive)
    ([(TxIn, Coin)] -> [[(TxIn, Coin)]])
-> NP
     (I -.-> [])
     '[[TxOut], Maybe TxOut, Maybe TxMetadata, Map RewardAccount Coin,
       Maybe TxScriptValidity]
-> NP
     (I -.-> [])
     '[[(TxIn, Coin)], [TxOut], Maybe TxOut, Maybe TxMetadata,
       Map RewardAccount Coin, Maybe TxScriptValidity]
forall x (xs :: [*]).
(x -> [x]) -> NP (I -.-> []) xs -> NP (I -.-> []) (x : xs)
<:> (TxOut -> [TxOut]) -> [TxOut] -> [[TxOut]]
forall a. (a -> [a]) -> [a] -> [[a]]
shrinkList TxOut -> [TxOut]
shrinkTxOut
    ([TxOut] -> [[TxOut]])
-> NP
     (I -.-> [])
     '[Maybe TxOut, Maybe TxMetadata, Map RewardAccount Coin,
       Maybe TxScriptValidity]
-> NP
     (I -.-> [])
     '[[TxOut], Maybe TxOut, Maybe TxMetadata, Map RewardAccount Coin,
       Maybe TxScriptValidity]
forall x (xs :: [*]).
(x -> [x]) -> NP (I -.-> []) xs -> NP (I -.-> []) (x : xs)
<:> (TxOut -> [TxOut]) -> Maybe TxOut -> [Maybe TxOut]
forall (f :: * -> *) a. Arbitrary1 f => (a -> [a]) -> f a -> [f a]
liftShrink TxOut -> [TxOut]
shrinkTxOut
    (Maybe TxOut -> [Maybe TxOut])
-> NP
     (I -.-> [])
     '[Maybe TxMetadata, Map RewardAccount Coin, Maybe TxScriptValidity]
-> NP
     (I -.-> [])
     '[Maybe TxOut, Maybe TxMetadata, Map RewardAccount Coin,
       Maybe TxScriptValidity]
forall x (xs :: [*]).
(x -> [x]) -> NP (I -.-> []) xs -> NP (I -.-> []) (x : xs)
<:> (TxMetadata -> [TxMetadata])
-> Maybe TxMetadata -> [Maybe TxMetadata]
forall (f :: * -> *) a. Arbitrary1 f => (a -> [a]) -> f a -> [f a]
liftShrink TxMetadata -> [TxMetadata]
shrinkTxMetadata
    (Maybe TxMetadata -> [Maybe TxMetadata])
-> NP (I -.-> []) '[Map RewardAccount Coin, Maybe TxScriptValidity]
-> NP
     (I -.-> [])
     '[Maybe TxMetadata, Map RewardAccount Coin, Maybe TxScriptValidity]
forall x (xs :: [*]).
(x -> [x]) -> NP (I -.-> []) xs -> NP (I -.-> []) (x : xs)
<:> (RewardAccount -> [RewardAccount])
-> (Coin -> [Coin])
-> Map RewardAccount Coin
-> [Map RewardAccount Coin]
forall k v.
Ord k =>
(k -> [k]) -> (v -> [v]) -> Map k v -> [Map k v]
shrinkMapWith RewardAccount -> [RewardAccount]
shrinkRewardAccount Coin -> [Coin]
shrinkCoinPositive
    (Map RewardAccount Coin -> [Map RewardAccount Coin])
-> NP (I -.-> []) '[Maybe TxScriptValidity]
-> NP (I -.-> []) '[Map RewardAccount Coin, Maybe TxScriptValidity]
forall x (xs :: [*]).
(x -> [x]) -> NP (I -.-> []) xs -> NP (I -.-> []) (x : xs)
<:> (TxScriptValidity -> [TxScriptValidity])
-> Maybe TxScriptValidity -> [Maybe TxScriptValidity]
forall (f :: * -> *) a. Arbitrary1 f => (a -> [a]) -> f a -> [f a]
liftShrink TxScriptValidity -> [TxScriptValidity]
shrinkTxScriptValidity
    (Maybe TxScriptValidity -> [Maybe TxScriptValidity])
-> NP (I -.-> []) '[] -> NP (I -.-> []) '[Maybe TxScriptValidity]
forall x (xs :: [*]).
(x -> [x]) -> NP (I -.-> []) xs -> NP (I -.-> []) (x : xs)
<:> NP (I -.-> []) '[]
forall k (a :: k -> *). NP a '[]
Nil

txWithoutIdToTx :: TxWithoutId -> Tx
txWithoutIdToTx :: TxWithoutId -> Tx
txWithoutIdToTx tx :: TxWithoutId
tx@TxWithoutId {[(TxIn, Coin)]
[TxOut]
Maybe TxMetadata
Maybe Coin
Maybe TxScriptValidity
Maybe TxOut
Map RewardAccount Coin
scriptValidity :: Maybe TxScriptValidity
withdrawals :: Map RewardAccount Coin
metadata :: Maybe TxMetadata
collateralOutput :: Maybe TxOut
outputs :: [TxOut]
resolvedCollateralInputs :: [(TxIn, Coin)]
resolvedInputs :: [(TxIn, Coin)]
fee :: Maybe Coin
$sel:scriptValidity:TxWithoutId :: TxWithoutId -> Maybe TxScriptValidity
$sel:withdrawals:TxWithoutId :: TxWithoutId -> Map RewardAccount Coin
$sel:metadata:TxWithoutId :: TxWithoutId -> Maybe TxMetadata
$sel:collateralOutput:TxWithoutId :: TxWithoutId -> Maybe TxOut
$sel:outputs:TxWithoutId :: TxWithoutId -> [TxOut]
$sel:resolvedCollateralInputs:TxWithoutId :: TxWithoutId -> [(TxIn, Coin)]
$sel:resolvedInputs:TxWithoutId :: TxWithoutId -> [(TxIn, Coin)]
$sel:fee:TxWithoutId :: TxWithoutId -> Maybe Coin
..} = Tx :: Hash "Tx"
-> Maybe Coin
-> [(TxIn, Coin)]
-> [(TxIn, Coin)]
-> [TxOut]
-> Maybe TxOut
-> Map RewardAccount Coin
-> Maybe TxMetadata
-> Maybe TxScriptValidity
-> Tx
Tx {$sel:txId:Tx :: Hash "Tx"
txId = TxWithoutId -> Hash "Tx"
forall a (whatever :: Symbol). Show a => a -> Hash whatever
mockHash TxWithoutId
tx, [(TxIn, Coin)]
[TxOut]
Maybe TxMetadata
Maybe Coin
Maybe TxScriptValidity
Maybe TxOut
Map RewardAccount Coin
$sel:scriptValidity:Tx :: Maybe TxScriptValidity
$sel:metadata:Tx :: Maybe TxMetadata
$sel:withdrawals:Tx :: Map RewardAccount Coin
$sel:collateralOutput:Tx :: Maybe TxOut
$sel:outputs:Tx :: [TxOut]
$sel:resolvedCollateralInputs:Tx :: [(TxIn, Coin)]
$sel:resolvedInputs:Tx :: [(TxIn, Coin)]
$sel:fee:Tx :: Maybe Coin
scriptValidity :: Maybe TxScriptValidity
withdrawals :: Map RewardAccount Coin
metadata :: Maybe TxMetadata
collateralOutput :: Maybe TxOut
outputs :: [TxOut]
resolvedCollateralInputs :: [(TxIn, Coin)]
resolvedInputs :: [(TxIn, Coin)]
fee :: Maybe Coin
..}

txToTxWithoutId :: Tx -> TxWithoutId
txToTxWithoutId :: Tx -> TxWithoutId
txToTxWithoutId Tx {[(TxIn, Coin)]
[TxOut]
Maybe TxMetadata
Maybe Coin
Maybe TxScriptValidity
Maybe TxOut
Map RewardAccount Coin
Hash "Tx"
scriptValidity :: Maybe TxScriptValidity
metadata :: Maybe TxMetadata
withdrawals :: Map RewardAccount Coin
collateralOutput :: Maybe TxOut
outputs :: [TxOut]
resolvedCollateralInputs :: [(TxIn, Coin)]
resolvedInputs :: [(TxIn, Coin)]
fee :: Maybe Coin
txId :: Hash "Tx"
$sel:scriptValidity:Tx :: Tx -> Maybe TxScriptValidity
$sel:metadata:Tx :: Tx -> Maybe TxMetadata
$sel:withdrawals:Tx :: Tx -> Map RewardAccount Coin
$sel:collateralOutput:Tx :: Tx -> Maybe TxOut
$sel:outputs:Tx :: Tx -> [TxOut]
$sel:resolvedCollateralInputs:Tx :: Tx -> [(TxIn, Coin)]
$sel:resolvedInputs:Tx :: Tx -> [(TxIn, Coin)]
$sel:fee:Tx :: Tx -> Maybe Coin
$sel:txId:Tx :: Tx -> Hash "Tx"
..} = TxWithoutId :: Maybe Coin
-> [(TxIn, Coin)]
-> [(TxIn, Coin)]
-> [TxOut]
-> Maybe TxOut
-> Maybe TxMetadata
-> Map RewardAccount Coin
-> Maybe TxScriptValidity
-> TxWithoutId
TxWithoutId {[(TxIn, Coin)]
[TxOut]
Maybe TxMetadata
Maybe Coin
Maybe TxScriptValidity
Maybe TxOut
Map RewardAccount Coin
scriptValidity :: Maybe TxScriptValidity
metadata :: Maybe TxMetadata
withdrawals :: Map RewardAccount Coin
collateralOutput :: Maybe TxOut
outputs :: [TxOut]
resolvedCollateralInputs :: [(TxIn, Coin)]
resolvedInputs :: [(TxIn, Coin)]
fee :: Maybe Coin
$sel:scriptValidity:TxWithoutId :: Maybe TxScriptValidity
$sel:withdrawals:TxWithoutId :: Map RewardAccount Coin
$sel:metadata:TxWithoutId :: Maybe TxMetadata
$sel:collateralOutput:TxWithoutId :: Maybe TxOut
$sel:outputs:TxWithoutId :: [TxOut]
$sel:resolvedCollateralInputs:TxWithoutId :: [(TxIn, Coin)]
$sel:resolvedInputs:TxWithoutId :: [(TxIn, Coin)]
$sel:fee:TxWithoutId :: Maybe Coin
..}

genTxScriptValidity :: Gen TxScriptValidity
genTxScriptValidity :: Gen TxScriptValidity
genTxScriptValidity = Gen TxScriptValidity
forall a (ga :: * -> *) (some :: Bool).
(Generic a, GArbitrary a ga some, ga ~ Rep a) =>
Gen a
genericArbitrary

shrinkTxScriptValidity :: TxScriptValidity -> [TxScriptValidity]
shrinkTxScriptValidity :: TxScriptValidity -> [TxScriptValidity]
shrinkTxScriptValidity = TxScriptValidity -> [TxScriptValidity]
forall a.
(Generic a, RecursivelyShrink (Rep a), GSubterms (Rep a) a) =>
a -> [a]
genericShrink

--------------------------------------------------------------------------------
-- Transaction hashes generated according to the size parameter
--------------------------------------------------------------------------------

genTxHash :: Gen (Hash "Tx")
genTxHash :: Gen (Hash "Tx")
genTxHash = (Int -> Gen (Hash "Tx")) -> Gen (Hash "Tx")
forall a. (Int -> Gen a) -> Gen a
sized ((Int -> Gen (Hash "Tx")) -> Gen (Hash "Tx"))
-> (Int -> Gen (Hash "Tx")) -> Gen (Hash "Tx")
forall a b. (a -> b) -> a -> b
$ \Int
size -> [Hash "Tx"] -> Gen (Hash "Tx")
forall a. [a] -> Gen a
elements ([Hash "Tx"] -> Gen (Hash "Tx")) -> [Hash "Tx"] -> Gen (Hash "Tx")
forall a b. (a -> b) -> a -> b
$ Int -> [Hash "Tx"] -> [Hash "Tx"]
forall a. Int -> [a] -> [a]
take (Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
1 Int
size) [Hash "Tx"]
txHashes

shrinkTxHash :: Hash "Tx" -> [Hash "Tx"]
shrinkTxHash :: Hash "Tx" -> [Hash "Tx"]
shrinkTxHash Hash "Tx"
x
    | Hash "Tx"
x Hash "Tx" -> Hash "Tx" -> Bool
forall a. Eq a => a -> a -> Bool
== Hash "Tx"
simplest = []
    | Bool
otherwise = [Hash "Tx"
simplest]
  where
    simplest :: Hash "Tx"
simplest = [Hash "Tx"] -> Hash "Tx"
forall a. [a] -> a
head [Hash "Tx"]
txHashes

txHashes :: [Hash "Tx"]
txHashes :: [Hash "Tx"]
txHashes = Char -> Hash "Tx"
mkTxHash (Char -> Hash "Tx") -> String -> [Hash "Tx"]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Char
'0' .. Char
'9'] String -> ShowS
forall a. Semigroup a => a -> a -> a
<> [Char
'A' .. Char
'F']

--------------------------------------------------------------------------------
-- Transaction hashes chosen from a large range (to minimize collisions)
--------------------------------------------------------------------------------

genTxHashLargeRange :: Gen (Hash "Tx")
genTxHashLargeRange :: Gen (Hash "Tx")
genTxHashLargeRange = ByteString -> Hash "Tx"
forall (tag :: Symbol). ByteString -> Hash tag
Hash (ByteString -> Hash "Tx")
-> (String -> ByteString) -> String -> Hash "Tx"
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ByteString
B8.pack (String -> Hash "Tx") -> Gen String -> Gen (Hash "Tx")
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Gen Char -> Gen String
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
32 Gen Char
forall a. Arbitrary a => Gen a
arbitrary

--------------------------------------------------------------------------------
-- Transaction indices generated according to the size parameter
--------------------------------------------------------------------------------

genTxIndex :: Gen Word32
genTxIndex :: Gen Word32
genTxIndex = (Int -> Gen Word32) -> Gen Word32
forall a. (Int -> Gen a) -> Gen a
sized ((Int -> Gen Word32) -> Gen Word32)
-> (Int -> Gen Word32) -> Gen Word32
forall a b. (a -> b) -> a -> b
$ \Int
size -> [Word32] -> Gen Word32
forall a. [a] -> Gen a
elements ([Word32] -> Gen Word32) -> [Word32] -> Gen Word32
forall a b. (a -> b) -> a -> b
$ Int -> [Word32] -> [Word32]
forall a. Int -> [a] -> [a]
take (Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
1 Int
size) [Word32]
txIndices

shrinkTxIndex :: Word32 -> [Word32]
shrinkTxIndex :: Word32 -> [Word32]
shrinkTxIndex Word32
0 = []
shrinkTxIndex Word32
_ = [Word32
0]

txIndices :: [Word32]
txIndices :: [Word32]
txIndices =
    let w16range :: [Word16]
w16range = [Word16
0 ..] :: [Word16]
    in Word16 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word16 -> Word32) -> [Word16] -> [Word32]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Word16]
w16range

--------------------------------------------------------------------------------
-- Transaction inputs generated according to the size parameter
--------------------------------------------------------------------------------

genTxIn :: Gen TxIn
genTxIn :: Gen TxIn
genTxIn = (Hash "Tx" -> Word32 -> TxIn)
-> Gen (Hash "Tx") -> Gen Word32 -> Gen TxIn
forall a b c. (a -> b -> c) -> Gen a -> Gen b -> Gen c
genSized2With Hash "Tx" -> Word32 -> TxIn
TxIn Gen (Hash "Tx")
genTxHash Gen Word32
genTxIndex

shrinkTxIn :: TxIn -> [TxIn]
shrinkTxIn :: TxIn -> [TxIn]
shrinkTxIn (TxIn Hash "Tx"
h Word32
i) = (Hash "Tx" -> Word32 -> TxIn) -> (Hash "Tx", Word32) -> TxIn
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Hash "Tx" -> Word32 -> TxIn
TxIn ((Hash "Tx", Word32) -> TxIn) -> [(Hash "Tx", Word32)] -> [TxIn]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Hash "Tx", Hash "Tx" -> [Hash "Tx"])
-> (Word32, Word32 -> [Word32]) -> [(Hash "Tx", Word32)]
forall a b. (a, a -> [a]) -> (b, b -> [b]) -> [(a, b)]
shrinkInterleaved
    (Hash "Tx"
h, Hash "Tx" -> [Hash "Tx"]
shrinkTxHash)
    (Word32
i, Word32 -> [Word32]
shrinkTxIndex)

--------------------------------------------------------------------------------
-- Transaction input functions
--------------------------------------------------------------------------------

coarbitraryTxIn :: TxIn -> Gen a -> Gen a
coarbitraryTxIn :: TxIn -> Gen a -> Gen a
coarbitraryTxIn = String -> Gen a -> Gen a
forall a b. CoArbitrary a => a -> Gen b -> Gen b
coarbitrary (String -> Gen a -> Gen a)
-> (TxIn -> String) -> TxIn -> Gen a -> Gen a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TxIn -> String
forall a. Show a => a -> String
show

genTxInFunction :: Gen a -> Gen (TxIn -> a)
genTxInFunction :: Gen a -> Gen (TxIn -> a)
genTxInFunction = (TxIn -> Gen a -> Gen a) -> Gen a -> Gen (TxIn -> a)
forall a b. (a -> Gen b -> Gen b) -> Gen b -> Gen (a -> b)
genFunction TxIn -> Gen a -> Gen a
forall a. TxIn -> Gen a -> Gen a
coarbitraryTxIn

--------------------------------------------------------------------------------
-- Transaction inputs chosen from a large range (to minimize collisions)
--------------------------------------------------------------------------------

genTxInLargeRange :: Gen TxIn
genTxInLargeRange :: Gen TxIn
genTxInLargeRange = Hash "Tx" -> Word32 -> TxIn
TxIn
    (Hash "Tx" -> Word32 -> TxIn)
-> Gen (Hash "Tx") -> Gen (Word32 -> TxIn)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen (Hash "Tx")
genTxHashLargeRange
    -- Note that we don't need to choose indices from a large range, as hashes
    -- are already chosen from a large range:
    Gen (Word32 -> TxIn) -> Gen Word32 -> Gen TxIn
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen Word32
genTxIndex

--------------------------------------------------------------------------------
-- Transaction outputs generated according to the size parameter
--------------------------------------------------------------------------------

genTxOut :: Gen TxOut
genTxOut :: Gen TxOut
genTxOut = Address -> TokenBundle -> TxOut
TxOut
    (Address -> TokenBundle -> TxOut)
-> Gen Address -> Gen (TokenBundle -> TxOut)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen Address
genAddress
    Gen (TokenBundle -> TxOut) -> Gen TokenBundle -> Gen TxOut
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen TokenBundle
genTokenBundleSmallRange Gen TokenBundle -> (TokenBundle -> Bool) -> Gen TokenBundle
forall a. Gen a -> (a -> Bool) -> Gen a
`suchThat` TokenBundle -> Bool
tokenBundleHasNonZeroCoin

shrinkTxOut :: TxOut -> [TxOut]
shrinkTxOut :: TxOut -> [TxOut]
shrinkTxOut (TxOut Address
a TokenBundle
b) = (Address -> TokenBundle -> TxOut)
-> (Address, TokenBundle) -> TxOut
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Address -> TokenBundle -> TxOut
TxOut ((Address, TokenBundle) -> TxOut)
-> [(Address, TokenBundle)] -> [TxOut]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Address, Address -> [Address])
-> (TokenBundle, TokenBundle -> [TokenBundle])
-> [(Address, TokenBundle)]
forall a b. (a, a -> [a]) -> (b, b -> [b]) -> [(a, b)]
shrinkInterleaved
    (Address
a, Address -> [Address]
shrinkAddress)
    (TokenBundle
b, (TokenBundle -> Bool) -> [TokenBundle] -> [TokenBundle]
forall a. (a -> Bool) -> [a] -> [a]
filter TokenBundle -> Bool
tokenBundleHasNonZeroCoin ([TokenBundle] -> [TokenBundle])
-> (TokenBundle -> [TokenBundle]) -> TokenBundle -> [TokenBundle]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TokenBundle -> [TokenBundle]
shrinkTokenBundleSmallRange)

tokenBundleHasNonZeroCoin :: TokenBundle -> Bool
tokenBundleHasNonZeroCoin :: TokenBundle -> Bool
tokenBundleHasNonZeroCoin TokenBundle
b = TokenBundle -> Coin
TokenBundle.getCoin TokenBundle
b Coin -> Coin -> Bool
forall a. Eq a => a -> a -> Bool
/= Natural -> Coin
Coin Natural
0

--------------------------------------------------------------------------------
-- Coins chosen from the full range allowed in a transaction output
--------------------------------------------------------------------------------

-- | Generates coins across the full range allowed in a transaction output.
--
-- This generator has a slight bias towards the limits of the range, but
-- otherwise generates values uniformly across the whole range.
--
-- This can be useful when testing roundtrip conversions between different
-- types.
--
genTxOutCoin :: Gen Coin
genTxOutCoin :: Gen Coin
genTxOutCoin = [(Int, Gen Coin)] -> Gen Coin
forall a. [(Int, Gen a)] -> Gen a
frequency
    [ (Int
1, Coin -> Gen Coin
forall (f :: * -> *) a. Applicative f => a -> f a
pure Coin
txOutMinCoin)
    , (Int
1, Coin -> Gen Coin
forall (f :: * -> *) a. Applicative f => a -> f a
pure Coin
txOutMaxCoin)
    , (Int
8, Natural -> Coin
Coin.fromNatural (Natural -> Coin) -> Gen Natural -> Gen Coin
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Natural, Natural) -> Gen Natural
chooseNatural
        ( Coin -> Natural
Coin.toNatural Coin
txOutMinCoin Natural -> Natural -> Natural
forall a. Num a => a -> a -> a
+ Natural
1
        , Coin -> Natural
Coin.toNatural Coin
txOutMaxCoin Natural -> Natural -> Natural
forall a. Num a => a -> a -> a
- Natural
1
        )
      )
    ]

shrinkTxOutCoin :: Coin -> [Coin]
shrinkTxOutCoin :: Coin -> [Coin]
shrinkTxOutCoin
    = (Coin -> Bool) -> [Coin] -> [Coin]
forall a. (a -> Bool) -> [a] -> [a]
L.filter Coin -> Bool
coinIsValidForTxOut
    ([Coin] -> [Coin]) -> (Coin -> [Coin]) -> Coin -> [Coin]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Natural -> Coin)
-> (Coin -> Natural) -> (Natural -> [Natural]) -> Coin -> [Coin]
forall a b. (a -> b) -> (b -> a) -> (a -> [a]) -> b -> [b]
shrinkMapBy Natural -> Coin
Coin.fromNatural Coin -> Natural
Coin.toNatural Natural -> [Natural]
shrinkNatural

--------------------------------------------------------------------------------
-- Token bundles with fixed numbers of assets.
--
-- Values are chosen from across the full range of values permitted within
-- transaction outputs.
--
-- Policy identifiers, asset names, token quantities are all allowed to vary.
--------------------------------------------------------------------------------

genTxOutTokenBundle :: Int -> Gen TokenBundle
genTxOutTokenBundle :: Int -> Gen TokenBundle
genTxOutTokenBundle Int
fixedAssetCount
    = Coin -> [(AssetId, TokenQuantity)] -> TokenBundle
TokenBundle.fromFlatList
        (Coin -> [(AssetId, TokenQuantity)] -> TokenBundle)
-> Gen Coin -> Gen ([(AssetId, TokenQuantity)] -> TokenBundle)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen Coin
genTxOutCoin
        Gen ([(AssetId, TokenQuantity)] -> TokenBundle)
-> Gen [(AssetId, TokenQuantity)] -> Gen TokenBundle
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Int
-> Gen (AssetId, TokenQuantity) -> Gen [(AssetId, TokenQuantity)]
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
fixedAssetCount Gen (AssetId, TokenQuantity)
genAssetQuantity
  where
    genAssetQuantity :: Gen (AssetId, TokenQuantity)
genAssetQuantity = (,)
        (AssetId -> TokenQuantity -> (AssetId, TokenQuantity))
-> Gen AssetId -> Gen (TokenQuantity -> (AssetId, TokenQuantity))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen AssetId
genAssetIdLargeRange
        Gen (TokenQuantity -> (AssetId, TokenQuantity))
-> Gen TokenQuantity -> Gen (AssetId, TokenQuantity)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen TokenQuantity
genTokenQuantity
    genTokenQuantity :: Gen TokenQuantity
genTokenQuantity = Integer -> TokenQuantity
integerToTokenQuantity (Integer -> TokenQuantity) -> Gen Integer -> Gen TokenQuantity
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Gen Integer] -> Gen Integer
forall a. [Gen a] -> Gen a
oneof
        [ Integer -> Gen Integer
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Integer -> Gen Integer) -> Integer -> Gen Integer
forall a b. (a -> b) -> a -> b
$ TokenQuantity -> Integer
tokenQuantityToInteger TokenQuantity
txOutMinTokenQuantity
        , Integer -> Gen Integer
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Integer -> Gen Integer) -> Integer -> Gen Integer
forall a b. (a -> b) -> a -> b
$ TokenQuantity -> Integer
tokenQuantityToInteger TokenQuantity
txOutMaxTokenQuantity
        , (Integer, Integer) -> Gen Integer
forall a. Random a => (a, a) -> Gen a
choose
            ( TokenQuantity -> Integer
tokenQuantityToInteger TokenQuantity
txOutMinTokenQuantity Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
1
            , TokenQuantity -> Integer
tokenQuantityToInteger TokenQuantity
txOutMaxTokenQuantity Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
1
            )
        ]
      where
        tokenQuantityToInteger :: TokenQuantity -> Integer
        tokenQuantityToInteger :: TokenQuantity -> Integer
tokenQuantityToInteger = Natural -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Natural -> Integer)
-> (TokenQuantity -> Natural) -> TokenQuantity -> Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TokenQuantity -> Natural
unTokenQuantity

        integerToTokenQuantity :: Integer -> TokenQuantity
        integerToTokenQuantity :: Integer -> TokenQuantity
integerToTokenQuantity = Natural -> TokenQuantity
TokenQuantity (Natural -> TokenQuantity)
-> (Integer -> Natural) -> Integer -> TokenQuantity
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Natural
forall a b. (Integral a, Num b) => a -> b
fromIntegral

--------------------------------------------------------------------------------
-- Internal utilities
--------------------------------------------------------------------------------

-- The input must be a character in the range [0-9] or [A-F].
--
mkTxHash :: Char -> Hash "Tx"
mkTxHash :: Char -> Hash "Tx"
mkTxHash Char
c
    = Hash "Tx" -> Either TextDecodingError (Hash "Tx") -> Hash "Tx"
forall b a. b -> Either a b -> b
fromRight Hash "Tx"
forall a. a
reportError
    (Either TextDecodingError (Hash "Tx") -> Hash "Tx")
-> Either TextDecodingError (Hash "Tx") -> Hash "Tx"
forall a b. (a -> b) -> a -> b
$ Text -> Either TextDecodingError (Hash "Tx")
forall a. FromText a => Text -> Either TextDecodingError a
fromText
    (Text -> Either TextDecodingError (Hash "Tx"))
-> Text -> Either TextDecodingError (Hash "Tx")
forall a b. (a -> b) -> a -> b
$ String -> Text
T.pack
    (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ Int -> Char -> String
forall a. Int -> a -> [a]
replicate Int
txHashHexStringLength Char
c
  where
    reportError :: a
reportError = String -> a
forall a. HasCallStack => String -> a
error (String -> a) -> String -> a
forall a b. (a -> b) -> a -> b
$
        String
"Unable to generate transaction hash from character: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Char -> String
forall a. Show a => a -> String
show Char
c

txHashHexStringLength :: Int
txHashHexStringLength :: Int
txHashHexStringLength = Int
64