{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE UndecidableSuperClasses #-}
{-# LANGUAGE ViewPatterns #-}
{-# OPTIONS_GHC -Wno-orphans #-}

module Cardano.Ledger.Alonzo.TxOut (
  AlonzoEraTxOut (..),
  AlonzoTxOut (.., AlonzoTxOut, TxOutCompact, TxOutCompactDH),
  -- Constructors are not exported for safety:
  Addr28Extra,
  DataHash32,
  getAdaOnly,
  decodeDataHash32,
  encodeDataHash32,
  encodeAddress28,
  decodeAddress28,
  viewCompactTxOut,
  viewTxOut,
  getAlonzoTxOutEitherAddr,
  utxoEntrySize,
  internAlonzoTxOut,
)
where

import Cardano.Crypto.Hash
import Cardano.Ledger.Address (
  Addr (..),
  CompactAddr,
  compactAddr,
  decompactAddr,
  fromCborBothAddr,
 )
import Cardano.Ledger.Alonzo.Era
import Cardano.Ledger.Alonzo.PParams (AlonzoEraPParams, CoinPerWord (..), ppCoinsPerUTxOWordL)
import Cardano.Ledger.Alonzo.Scripts ()
import Cardano.Ledger.BaseTypes (
  Network (..),
  StrictMaybe (..),
  inject,
  strictMaybeToMaybe,
 )
import Cardano.Ledger.Binary (
  DecCBOR (decCBOR),
  DecShareCBOR (Share, decShareCBOR),
  DecoderError (DecoderErrorCustom),
  EncCBOR (encCBOR),
  FromCBOR (..),
  Interns,
  ToCBOR (..),
  cborError,
  decodeBreakOr,
  decodeListLenOrIndef,
  encodeListLen,
  interns,
 )
import Cardano.Ledger.Coin (Coin (..))
import Cardano.Ledger.Compactible
import Cardano.Ledger.Credential (Credential (..), PaymentCredential, StakeReference (..))
import Cardano.Ledger.Hashes (unsafeMakeSafeHash)
import Cardano.Ledger.Plutus.Data (Datum (..), dataHashSize)
import Cardano.Ledger.Shelley.Core
import qualified Cardano.Ledger.Shelley.TxOut as Shelley
import Cardano.Ledger.Val (Val (..))
import Control.DeepSeq (NFData (..), rwhnf)
import Control.Monad (guard, (<$!>))
import Data.Aeson (ToJSON (..), object, (.=))
import qualified Data.Aeson as Aeson (Value (Null, String))
import Data.Bits
import Data.Maybe (fromMaybe)
import Data.Typeable (Proxy (..), (:~:) (Refl))
import Data.Word
import GHC.Generics (Generic)
import GHC.Stack (HasCallStack)
import GHC.TypeLits
import Lens.Micro
import NoThunks.Class (InspectHeapNamed (..), NoThunks)

class (AlonzoEraPParams era, EraTxOut era) => AlonzoEraTxOut era where
  dataHashTxOutL :: Lens' (TxOut era) (StrictMaybe DataHash)

  datumTxOutF :: SimpleGetter (TxOut era) (Datum era)

data Addr28Extra
  = Addr28Extra
      {-# UNPACK #-} !Word64 -- Payment Addr
      {-# UNPACK #-} !Word64 -- Payment Addr
      {-# UNPACK #-} !Word64 -- Payment Addr
      {-# UNPACK #-} !Word64 -- Payment Addr (32bits) + ... +  0/1 for Testnet/Mainnet + 0/1 Script/Pubkey
  deriving (Addr28Extra -> Addr28Extra -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Addr28Extra -> Addr28Extra -> Bool
$c/= :: Addr28Extra -> Addr28Extra -> Bool
== :: Addr28Extra -> Addr28Extra -> Bool
$c== :: Addr28Extra -> Addr28Extra -> Bool
Eq, Int -> Addr28Extra -> ShowS
[Addr28Extra] -> ShowS
Addr28Extra -> [Char]
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
showList :: [Addr28Extra] -> ShowS
$cshowList :: [Addr28Extra] -> ShowS
show :: Addr28Extra -> [Char]
$cshow :: Addr28Extra -> [Char]
showsPrec :: Int -> Addr28Extra -> ShowS
$cshowsPrec :: Int -> Addr28Extra -> ShowS
Show, forall x. Rep Addr28Extra x -> Addr28Extra
forall x. Addr28Extra -> Rep Addr28Extra x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Addr28Extra x -> Addr28Extra
$cfrom :: forall x. Addr28Extra -> Rep Addr28Extra x
Generic, Context -> Addr28Extra -> IO (Maybe ThunkInfo)
Proxy Addr28Extra -> [Char]
forall a.
(Context -> a -> IO (Maybe ThunkInfo))
-> (Context -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> [Char])
-> NoThunks a
showTypeOf :: Proxy Addr28Extra -> [Char]
$cshowTypeOf :: Proxy Addr28Extra -> [Char]
wNoThunks :: Context -> Addr28Extra -> IO (Maybe ThunkInfo)
$cwNoThunks :: Context -> Addr28Extra -> IO (Maybe ThunkInfo)
noThunks :: Context -> Addr28Extra -> IO (Maybe ThunkInfo)
$cnoThunks :: Context -> Addr28Extra -> IO (Maybe ThunkInfo)
NoThunks)

data DataHash32
  = DataHash32
      {-# UNPACK #-} !Word64 -- DataHash
      {-# UNPACK #-} !Word64 -- DataHash
      {-# UNPACK #-} !Word64 -- DataHash
      {-# UNPACK #-} !Word64 -- DataHash
  deriving (DataHash32 -> DataHash32 -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: DataHash32 -> DataHash32 -> Bool
$c/= :: DataHash32 -> DataHash32 -> Bool
== :: DataHash32 -> DataHash32 -> Bool
$c== :: DataHash32 -> DataHash32 -> Bool
Eq, Int -> DataHash32 -> ShowS
[DataHash32] -> ShowS
DataHash32 -> [Char]
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
showList :: [DataHash32] -> ShowS
$cshowList :: [DataHash32] -> ShowS
show :: DataHash32 -> [Char]
$cshow :: DataHash32 -> [Char]
showsPrec :: Int -> DataHash32 -> ShowS
$cshowsPrec :: Int -> DataHash32 -> ShowS
Show, forall x. Rep DataHash32 x -> DataHash32
forall x. DataHash32 -> Rep DataHash32 x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep DataHash32 x -> DataHash32
$cfrom :: forall x. DataHash32 -> Rep DataHash32 x
Generic, Context -> DataHash32 -> IO (Maybe ThunkInfo)
Proxy DataHash32 -> [Char]
forall a.
(Context -> a -> IO (Maybe ThunkInfo))
-> (Context -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> [Char])
-> NoThunks a
showTypeOf :: Proxy DataHash32 -> [Char]
$cshowTypeOf :: Proxy DataHash32 -> [Char]
wNoThunks :: Context -> DataHash32 -> IO (Maybe ThunkInfo)
$cwNoThunks :: Context -> DataHash32 -> IO (Maybe ThunkInfo)
noThunks :: Context -> DataHash32 -> IO (Maybe ThunkInfo)
$cnoThunks :: Context -> DataHash32 -> IO (Maybe ThunkInfo)
NoThunks)

decodeAddress28 ::
  Credential 'Staking ->
  Addr28Extra ->
  Maybe Addr
decodeAddress28 :: Credential 'Staking -> Addr28Extra -> Maybe Addr
decodeAddress28 Credential 'Staking
stakeRef (Addr28Extra Word64
a Word64
b Word64
c Word64
d) = do
  28 :~: 28
Refl <- forall (a :: Nat) (b :: Nat) (proxy1 :: Nat -> *)
       (proxy2 :: Nat -> *).
(KnownNat a, KnownNat b) =>
proxy1 a -> proxy2 b -> Maybe (a :~: b)
sameNat (forall {k} (t :: k). Proxy t
Proxy @(SizeHash ADDRHASH)) (forall {k} (t :: k). Proxy t
Proxy @28)
  let network :: Network
network = if Word64
d forall a. Bits a => a -> Int -> Bool
`testBit` Int
1 then Network
Mainnet else Network
Testnet
      paymentCred :: Credential 'Payment
paymentCred =
        if Word64
d forall a. Bits a => a -> Int -> Bool
`testBit` Int
0
          then forall (kr :: KeyRole). KeyHash kr -> Credential kr
KeyHashObj (forall (r :: KeyRole).
Hash ADDRHASH (VerKeyDSIGN DSIGN) -> KeyHash r
KeyHash forall a. Hash ADDRHASH a
addrHash)
          else forall (kr :: KeyRole). ScriptHash -> Credential kr
ScriptHashObj (Hash ADDRHASH EraIndependentScript -> ScriptHash
ScriptHash forall a. Hash ADDRHASH a
addrHash)
      addrHash :: Hash ADDRHASH a
      addrHash :: forall a. Hash ADDRHASH a
addrHash =
        forall h a. PackedBytes (SizeHash h) -> Hash h a
hashFromPackedBytes forall a b. (a -> b) -> a -> b
$
          Word64 -> Word64 -> Word64 -> Word32 -> PackedBytes 28
PackedBytes28 Word64
a Word64
b Word64
c (forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64
d forall a. Bits a => a -> Int -> a
`shiftR` Int
32))
  forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$! Network -> Credential 'Payment -> StakeReference -> Addr
Addr Network
network Credential 'Payment
paymentCred (Credential 'Staking -> StakeReference
StakeRefBase Credential 'Staking
stakeRef)
{-# INLINE decodeAddress28 #-}

data AlonzoTxOut era
  = TxOutCompact'
      {-# UNPACK #-} !CompactAddr
      !(CompactForm (Value era))
  | TxOutCompactDH'
      {-# UNPACK #-} !CompactAddr
      !(CompactForm (Value era))
      !DataHash
  | TxOut_AddrHash28_AdaOnly
      !(Credential 'Staking)
      {-# UNPACK #-} !Addr28Extra
      {-# UNPACK #-} !(CompactForm Coin) -- Ada value
  | TxOut_AddrHash28_AdaOnly_DataHash32
      !(Credential 'Staking)
      {-# UNPACK #-} !Addr28Extra
      {-# UNPACK #-} !(CompactForm Coin) -- Ada value
      {-# UNPACK #-} !DataHash32

deriving stock instance (Eq (Value era), Compactible (Value era)) => Eq (AlonzoTxOut era)

deriving instance Generic (AlonzoTxOut era)

-- | Already in NF
instance NFData (AlonzoTxOut era) where
  rnf :: AlonzoTxOut era -> ()
rnf = forall a. a -> ()
rwhnf

addressErrorMsg :: String
addressErrorMsg :: [Char]
addressErrorMsg = [Char]
"Impossible: Compacted an address of non-standard size"
{-# NOINLINE addressErrorMsg #-}

decodeDataHash32 ::
  DataHash32 ->
  Maybe DataHash
decodeDataHash32 :: DataHash32 -> Maybe DataHash
decodeDataHash32 (DataHash32 Word64
a Word64
b Word64
c Word64
d) = do
  32 :~: 32
Refl <- forall (a :: Nat) (b :: Nat) (proxy1 :: Nat -> *)
       (proxy2 :: Nat -> *).
(KnownNat a, KnownNat b) =>
proxy1 a -> proxy2 b -> Maybe (a :~: b)
sameNat (forall {k} (t :: k). Proxy t
Proxy @(SizeHash HASH)) (forall {k} (t :: k). Proxy t
Proxy @32)
  forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$! forall i. Hash HASH i -> SafeHash i
unsafeMakeSafeHash forall a b. (a -> b) -> a -> b
$ forall h a. PackedBytes (SizeHash h) -> Hash h a
hashFromPackedBytes forall a b. (a -> b) -> a -> b
$ Word64 -> Word64 -> Word64 -> Word64 -> PackedBytes 32
PackedBytes32 Word64
a Word64
b Word64
c Word64
d

viewCompactTxOut ::
  Val (Value era) =>
  AlonzoTxOut era ->
  (CompactAddr, CompactForm (Value era), StrictMaybe DataHash)
viewCompactTxOut :: forall era.
Val (Value era) =>
AlonzoTxOut era
-> (CompactAddr, CompactForm (Value era), StrictMaybe DataHash)
viewCompactTxOut AlonzoTxOut era
txOut = case AlonzoTxOut era
txOut of
  TxOutCompact' CompactAddr
addr CompactForm (Value era)
val -> (CompactAddr
addr, CompactForm (Value era)
val, forall a. StrictMaybe a
SNothing)
  TxOutCompactDH' CompactAddr
addr CompactForm (Value era)
val DataHash
dh -> (CompactAddr
addr, CompactForm (Value era)
val, forall a. a -> StrictMaybe a
SJust DataHash
dh)
  TxOut_AddrHash28_AdaOnly Credential 'Staking
stakeRef Addr28Extra
addr28Extra CompactForm Coin
adaVal
    | Just Addr
addr <- Credential 'Staking -> Addr28Extra -> Maybe Addr
decodeAddress28 Credential 'Staking
stakeRef Addr28Extra
addr28Extra ->
        (Addr -> CompactAddr
compactAddr Addr
addr, forall t. Val t => CompactForm Coin -> CompactForm t
injectCompact CompactForm Coin
adaVal, forall a. StrictMaybe a
SNothing)
    | Bool
otherwise -> forall a. HasCallStack => [Char] -> a
error [Char]
addressErrorMsg
  TxOut_AddrHash28_AdaOnly_DataHash32 Credential 'Staking
stakeRef Addr28Extra
addr28Extra CompactForm Coin
adaVal DataHash32
dataHash32
    | Just Addr
addr <- Credential 'Staking -> Addr28Extra -> Maybe Addr
decodeAddress28 Credential 'Staking
stakeRef Addr28Extra
addr28Extra
    , Just DataHash
dh <- DataHash32 -> Maybe DataHash
decodeDataHash32 DataHash32
dataHash32 ->
        (Addr -> CompactAddr
compactAddr Addr
addr, forall t. Val t => CompactForm Coin -> CompactForm t
injectCompact CompactForm Coin
adaVal, forall a. a -> StrictMaybe a
SJust DataHash
dh)
    | Bool
otherwise -> forall a. HasCallStack => [Char] -> a
error [Char]
addressErrorMsg

viewTxOut ::
  Val (Value era) =>
  AlonzoTxOut era ->
  (Addr, Value era, StrictMaybe DataHash)
viewTxOut :: forall era.
Val (Value era) =>
AlonzoTxOut era -> (Addr, Value era, StrictMaybe DataHash)
viewTxOut (TxOutCompact' CompactAddr
bs CompactForm (Value era)
c) = (Addr
addr, Value era
val, forall a. StrictMaybe a
SNothing)
  where
    addr :: Addr
addr = HasCallStack => CompactAddr -> Addr
decompactAddr CompactAddr
bs
    val :: Value era
val = forall a. Compactible a => CompactForm a -> a
fromCompact CompactForm (Value era)
c
viewTxOut (TxOutCompactDH' CompactAddr
bs CompactForm (Value era)
c DataHash
dh) = (Addr
addr, Value era
val, forall a. a -> StrictMaybe a
SJust DataHash
dh)
  where
    addr :: Addr
addr = HasCallStack => CompactAddr -> Addr
decompactAddr CompactAddr
bs
    val :: Value era
val = forall a. Compactible a => CompactForm a -> a
fromCompact CompactForm (Value era)
c
viewTxOut (TxOut_AddrHash28_AdaOnly Credential 'Staking
stakeRef Addr28Extra
addr28Extra CompactForm Coin
adaVal)
  | Just Addr
addr <- Credential 'Staking -> Addr28Extra -> Maybe Addr
decodeAddress28 Credential 'Staking
stakeRef Addr28Extra
addr28Extra =
      (Addr
addr, forall t s. Inject t s => t -> s
inject (forall a. Compactible a => CompactForm a -> a
fromCompact CompactForm Coin
adaVal), forall a. StrictMaybe a
SNothing)
viewTxOut (TxOut_AddrHash28_AdaOnly_DataHash32 Credential 'Staking
stakeRef Addr28Extra
addr28Extra CompactForm Coin
adaVal DataHash32
dataHash32)
  | Just Addr
addr <- Credential 'Staking -> Addr28Extra -> Maybe Addr
decodeAddress28 Credential 'Staking
stakeRef Addr28Extra
addr28Extra
  , Just DataHash
dh <- DataHash32 -> Maybe DataHash
decodeDataHash32 DataHash32
dataHash32 =
      (Addr
addr, forall t s. Inject t s => t -> s
inject (forall a. Compactible a => CompactForm a -> a
fromCompact CompactForm Coin
adaVal), forall a. a -> StrictMaybe a
SJust DataHash
dh)
viewTxOut TxOut_AddrHash28_AdaOnly {} = forall a. HasCallStack => [Char] -> a
error [Char]
addressErrorMsg
viewTxOut TxOut_AddrHash28_AdaOnly_DataHash32 {} = forall a. HasCallStack => [Char] -> a
error [Char]
addressErrorMsg

instance (Era era, Val (Value era)) => Show (AlonzoTxOut era) where
  show :: AlonzoTxOut era -> [Char]
show = forall a. Show a => a -> [Char]
show forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall era.
Val (Value era) =>
AlonzoTxOut era -> (Addr, Value era, StrictMaybe DataHash)
viewTxOut -- FIXME: showing tuple is ugly

deriving via InspectHeapNamed "AlonzoTxOut" (AlonzoTxOut era) instance NoThunks (AlonzoTxOut era)

encodeAddress28 ::
  Network ->
  PaymentCredential ->
  Maybe (SizeHash ADDRHASH :~: 28, Addr28Extra)
encodeAddress28 :: Network
-> Credential 'Payment
-> Maybe (SizeHash ADDRHASH :~: 28, Addr28Extra)
encodeAddress28 Network
network Credential 'Payment
paymentCred = do
  let networkBit, payCredTypeBit :: Word64
      networkBit :: Word64
networkBit =
        case Network
network of
          Network
Mainnet -> Word64
0 forall a. Bits a => a -> Int -> a
`setBit` Int
1
          Network
Testnet -> Word64
0
      payCredTypeBit :: Word64
payCredTypeBit =
        case Credential 'Payment
paymentCred of
          KeyHashObj {} -> Word64
0 forall a. Bits a => a -> Int -> a
`setBit` Int
0
          ScriptHashObj {} -> Word64
0
      encodeAddr ::
        Hash ADDRHASH a ->
        Maybe (SizeHash ADDRHASH :~: 28, Addr28Extra)
      encodeAddr :: forall a.
Hash ADDRHASH a -> Maybe (SizeHash ADDRHASH :~: 28, Addr28Extra)
encodeAddr Hash ADDRHASH a
h = do
        refl :: 28 :~: 28
refl@28 :~: 28
Refl <- forall (a :: Nat) (b :: Nat) (proxy1 :: Nat -> *)
       (proxy2 :: Nat -> *).
(KnownNat a, KnownNat b) =>
proxy1 a -> proxy2 b -> Maybe (a :~: b)
sameNat (forall {k} (t :: k). Proxy t
Proxy @(SizeHash ADDRHASH)) (forall {k} (t :: k). Proxy t
Proxy @28)
        case forall h a. Hash h a -> PackedBytes (SizeHash h)
hashToPackedBytes Hash ADDRHASH a
h of
          PackedBytes28 Word64
a Word64
b Word64
c Word32
d ->
            let d' :: Word64
d' = (forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
d forall a. Bits a => a -> Int -> a
`shiftL` Int
32) forall a. Bits a => a -> a -> a
.|. Word64
networkBit forall a. Bits a => a -> a -> a
.|. Word64
payCredTypeBit
             in forall a. a -> Maybe a
Just (28 :~: 28
refl, Word64 -> Word64 -> Word64 -> Word64 -> Addr28Extra
Addr28Extra Word64
a Word64
b Word64
c Word64
d')
          PackedBytes (SizeHash ADDRHASH)
_ -> forall a. Maybe a
Nothing
  case Credential 'Payment
paymentCred of
    KeyHashObj (KeyHash Hash ADDRHASH (VerKeyDSIGN DSIGN)
addrHash) -> forall a.
Hash ADDRHASH a -> Maybe (SizeHash ADDRHASH :~: 28, Addr28Extra)
encodeAddr Hash ADDRHASH (VerKeyDSIGN DSIGN)
addrHash
    ScriptHashObj (ScriptHash Hash ADDRHASH EraIndependentScript
addrHash) -> forall a.
Hash ADDRHASH a -> Maybe (SizeHash ADDRHASH :~: 28, Addr28Extra)
encodeAddr Hash ADDRHASH EraIndependentScript
addrHash

encodeDataHash32 ::
  DataHash ->
  Maybe (SizeHash HASH :~: 32, DataHash32)
encodeDataHash32 :: DataHash -> Maybe (SizeHash HASH :~: 32, DataHash32)
encodeDataHash32 DataHash
dataHash = do
  refl :: 32 :~: 32
refl@32 :~: 32
Refl <- forall (a :: Nat) (b :: Nat) (proxy1 :: Nat -> *)
       (proxy2 :: Nat -> *).
(KnownNat a, KnownNat b) =>
proxy1 a -> proxy2 b -> Maybe (a :~: b)
sameNat (forall {k} (t :: k). Proxy t
Proxy @(SizeHash HASH)) (forall {k} (t :: k). Proxy t
Proxy @32)
  case forall h a. Hash h a -> PackedBytes (SizeHash h)
hashToPackedBytes (forall i. SafeHash i -> Hash HASH i
extractHash DataHash
dataHash) of
    PackedBytes32 Word64
a Word64
b Word64
c Word64
d -> forall a. a -> Maybe a
Just (32 :~: 32
refl, Word64 -> Word64 -> Word64 -> Word64 -> DataHash32
DataHash32 Word64
a Word64
b Word64
c Word64
d)
    PackedBytes (SizeHash HASH)
_ -> forall a. Maybe a
Nothing

getAdaOnly ::
  forall era.
  Val (Value era) =>
  Proxy era ->
  Value era ->
  Maybe (CompactForm Coin)
getAdaOnly :: forall era.
Val (Value era) =>
Proxy era -> Value era -> Maybe (CompactForm Coin)
getAdaOnly Proxy era
_ Value era
v = do
  forall (f :: * -> *). Alternative f => Bool -> f ()
guard forall a b. (a -> b) -> a -> b
$ forall t. Val t => t -> Bool
isAdaOnly Value era
v
  forall a. Compactible a => a -> Maybe (CompactForm a)
toCompact forall a b. (a -> b) -> a -> b
$ forall t. Val t => t -> Coin
coin Value era
v

pattern AlonzoTxOut ::
  forall era.
  (Era era, Val (Value era), HasCallStack) =>
  Addr ->
  Value era ->
  StrictMaybe DataHash ->
  AlonzoTxOut era
pattern $bAlonzoTxOut :: forall era.
(Era era, Val (Value era), HasCallStack) =>
Addr -> Value era -> StrictMaybe DataHash -> AlonzoTxOut era
$mAlonzoTxOut :: forall {r} {era}.
(Era era, Val (Value era), HasCallStack) =>
AlonzoTxOut era
-> (Addr -> Value era -> StrictMaybe DataHash -> r)
-> ((# #) -> r)
-> r
AlonzoTxOut addr vl dh <-
  (viewTxOut -> (addr, vl, dh))
  where
    AlonzoTxOut (Addr Network
network Credential 'Payment
paymentCred StakeReference
stakeRef) Value era
vl StrictMaybe DataHash
SNothing
      | StakeRefBase Credential 'Staking
stakeCred <- StakeReference
stakeRef
      , Just CompactForm Coin
adaCompact <- forall era.
Val (Value era) =>
Proxy era -> Value era -> Maybe (CompactForm Coin)
getAdaOnly (forall {k} (t :: k). Proxy t
Proxy @era) Value era
vl
      , Just (SizeHash ADDRHASH :~: 28
Refl, Addr28Extra
addr28Extra) <- Network
-> Credential 'Payment
-> Maybe (SizeHash ADDRHASH :~: 28, Addr28Extra)
encodeAddress28 Network
network Credential 'Payment
paymentCred =
          forall era.
Credential 'Staking
-> Addr28Extra -> CompactForm Coin -> AlonzoTxOut era
TxOut_AddrHash28_AdaOnly Credential 'Staking
stakeCred Addr28Extra
addr28Extra CompactForm Coin
adaCompact
    AlonzoTxOut (Addr Network
network Credential 'Payment
paymentCred StakeReference
stakeRef) Value era
vl (SJust DataHash
dh)
      | StakeRefBase Credential 'Staking
stakeCred <- StakeReference
stakeRef
      , Just CompactForm Coin
adaCompact <- forall era.
Val (Value era) =>
Proxy era -> Value era -> Maybe (CompactForm Coin)
getAdaOnly (forall {k} (t :: k). Proxy t
Proxy @era) Value era
vl
      , Just (SizeHash ADDRHASH :~: 28
Refl, Addr28Extra
addr28Extra) <- Network
-> Credential 'Payment
-> Maybe (SizeHash ADDRHASH :~: 28, Addr28Extra)
encodeAddress28 Network
network Credential 'Payment
paymentCred
      , Just (SizeHash HASH :~: 32
Refl, DataHash32
dataHash32) <- DataHash -> Maybe (SizeHash HASH :~: 32, DataHash32)
encodeDataHash32 DataHash
dh =
          forall era.
Credential 'Staking
-> Addr28Extra -> CompactForm Coin -> DataHash32 -> AlonzoTxOut era
TxOut_AddrHash28_AdaOnly_DataHash32 Credential 'Staking
stakeCred Addr28Extra
addr28Extra CompactForm Coin
adaCompact DataHash32
dataHash32
    AlonzoTxOut Addr
addr Value era
vl StrictMaybe DataHash
mdh =
      let v :: CompactForm (Value era)
v = forall a. a -> Maybe a -> a
fromMaybe (forall a. HasCallStack => [Char] -> a
error forall a b. (a -> b) -> a -> b
$ [Char]
"Illegal value in TxOut: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Value era
vl) forall a b. (a -> b) -> a -> b
$ forall a. Compactible a => a -> Maybe (CompactForm a)
toCompact Value era
vl
          a :: CompactAddr
a = Addr -> CompactAddr
compactAddr Addr
addr
       in case StrictMaybe DataHash
mdh of
            StrictMaybe DataHash
SNothing -> forall era.
CompactAddr -> CompactForm (Value era) -> AlonzoTxOut era
TxOutCompact' CompactAddr
a CompactForm (Value era)
v
            SJust DataHash
dh -> forall era.
CompactAddr
-> CompactForm (Value era) -> DataHash -> AlonzoTxOut era
TxOutCompactDH' CompactAddr
a CompactForm (Value era)
v DataHash
dh

{-# COMPLETE AlonzoTxOut #-}

instance EraTxOut AlonzoEra where
  type TxOut AlonzoEra = AlonzoTxOut AlonzoEra

  mkBasicTxOut :: HasCallStack => Addr -> Value AlonzoEra -> TxOut AlonzoEra
mkBasicTxOut Addr
addr Value AlonzoEra
vl = forall era.
(Era era, Val (Value era), HasCallStack) =>
Addr -> Value era -> StrictMaybe DataHash -> AlonzoTxOut era
AlonzoTxOut Addr
addr Value AlonzoEra
vl forall a. StrictMaybe a
SNothing

  upgradeTxOut :: EraTxOut (PreviousEra AlonzoEra) =>
TxOut (PreviousEra AlonzoEra) -> TxOut AlonzoEra
upgradeTxOut (Shelley.TxOutCompact CompactAddr
addr CompactForm (Value MaryEra)
value) = forall era.
(Era era, Val (Value era), HasCallStack) =>
CompactAddr -> CompactForm (Value era) -> AlonzoTxOut era
TxOutCompact CompactAddr
addr CompactForm (Value MaryEra)
value

  addrEitherTxOutL :: Lens' (TxOut AlonzoEra) (Either Addr CompactAddr)
addrEitherTxOutL =
    forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens
      forall era. AlonzoTxOut era -> Either Addr CompactAddr
getAlonzoTxOutEitherAddr
      ( \AlonzoTxOut AlonzoEra
txOut Either Addr CompactAddr
eAddr ->
          let cVal :: CompactForm (Value AlonzoEra)
cVal = forall era.
EraTxOut era =>
AlonzoTxOut era -> CompactForm (Value era)
getTxOutCompactValue AlonzoTxOut AlonzoEra
txOut
              (Addr
_, Value AlonzoEra
_, StrictMaybe DataHash
dh) = forall era.
Val (Value era) =>
AlonzoTxOut era -> (Addr, Value era, StrictMaybe DataHash)
viewTxOut AlonzoTxOut AlonzoEra
txOut
           in case Either Addr CompactAddr
eAddr of
                Left Addr
addr -> forall era.
(Era era, HasCallStack, Val (Value era)) =>
Addr
-> CompactAddr
-> CompactForm (Value era)
-> StrictMaybe DataHash
-> AlonzoTxOut era
mkTxOutCompact Addr
addr (Addr -> CompactAddr
compactAddr Addr
addr) CompactForm (Value AlonzoEra)
cVal StrictMaybe DataHash
dh
                Right CompactAddr
cAddr -> forall era.
(Era era, HasCallStack, Val (Value era)) =>
Addr
-> CompactAddr
-> CompactForm (Value era)
-> StrictMaybe DataHash
-> AlonzoTxOut era
mkTxOutCompact (HasCallStack => CompactAddr -> Addr
decompactAddr CompactAddr
cAddr) CompactAddr
cAddr CompactForm (Value AlonzoEra)
cVal StrictMaybe DataHash
dh
      )
  {-# INLINE addrEitherTxOutL #-}

  valueEitherTxOutL :: Lens'
  (TxOut AlonzoEra)
  (Either (Value AlonzoEra) (CompactForm (Value AlonzoEra)))
valueEitherTxOutL =
    forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens
      (forall a b. b -> Either a b
Right forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall era.
EraTxOut era =>
AlonzoTxOut era -> CompactForm (Value era)
getTxOutCompactValue)
      ( \AlonzoTxOut AlonzoEra
txOut Either MaryValue (CompactForm MaryValue)
eVal ->
          case Either MaryValue (CompactForm MaryValue)
eVal of
            Left MaryValue
val ->
              let (Addr
addr, Value AlonzoEra
_, StrictMaybe DataHash
dh) = forall era.
Val (Value era) =>
AlonzoTxOut era -> (Addr, Value era, StrictMaybe DataHash)
viewTxOut AlonzoTxOut AlonzoEra
txOut
               in forall era.
(Era era, Val (Value era), HasCallStack) =>
Addr -> Value era -> StrictMaybe DataHash -> AlonzoTxOut era
AlonzoTxOut Addr
addr MaryValue
val StrictMaybe DataHash
dh
            Right CompactForm MaryValue
cVal ->
              let dh :: StrictMaybe DataHash
dh = forall era. HasCallStack => AlonzoTxOut era -> StrictMaybe DataHash
getAlonzoTxOutDataHash AlonzoTxOut AlonzoEra
txOut
               in case forall era. AlonzoTxOut era -> Either Addr CompactAddr
getAlonzoTxOutEitherAddr AlonzoTxOut AlonzoEra
txOut of
                    Left Addr
addr -> forall era.
(Era era, HasCallStack, Val (Value era)) =>
Addr
-> CompactAddr
-> CompactForm (Value era)
-> StrictMaybe DataHash
-> AlonzoTxOut era
mkTxOutCompact Addr
addr (Addr -> CompactAddr
compactAddr Addr
addr) CompactForm MaryValue
cVal StrictMaybe DataHash
dh
                    Right CompactAddr
cAddr -> forall era.
(Era era, HasCallStack, Val (Value era)) =>
Addr
-> CompactAddr
-> CompactForm (Value era)
-> StrictMaybe DataHash
-> AlonzoTxOut era
mkTxOutCompact (HasCallStack => CompactAddr -> Addr
decompactAddr CompactAddr
cAddr) CompactAddr
cAddr CompactForm MaryValue
cVal StrictMaybe DataHash
dh
      )
  {-# INLINE valueEitherTxOutL #-}

  getMinCoinTxOut :: PParams AlonzoEra -> TxOut AlonzoEra -> Coin
getMinCoinTxOut PParams AlonzoEra
pp TxOut AlonzoEra
txOut =
    case PParams AlonzoEra
pp forall s a. s -> Getting a s a -> a
^. forall era.
(AlonzoEraPParams era, ExactEra AlonzoEra era) =>
Lens' (PParams era) CoinPerWord
ppCoinsPerUTxOWordL of
      CoinPerWord (Coin Integer
cpw) -> Integer -> Coin
Coin forall a b. (a -> b) -> a -> b
$ forall era. AlonzoEraTxOut era => TxOut era -> Integer
utxoEntrySize TxOut AlonzoEra
txOut forall a. Num a => a -> a -> a
* Integer
cpw

instance
  (Era era, Val (Value era)) =>
  EncCBOR (AlonzoTxOut era)
  where
  encCBOR :: AlonzoTxOut era -> Encoding
encCBOR (TxOutCompact CompactAddr
addr CompactForm (Value era)
cv) =
    Word -> Encoding
encodeListLen Word
2
      forall a. Semigroup a => a -> a -> a
<> forall a. EncCBOR a => a -> Encoding
encCBOR CompactAddr
addr
      forall a. Semigroup a => a -> a -> a
<> forall a. EncCBOR a => a -> Encoding
encCBOR CompactForm (Value era)
cv
  encCBOR (TxOutCompactDH CompactAddr
addr CompactForm (Value era)
cv DataHash
dh) =
    Word -> Encoding
encodeListLen Word
3
      forall a. Semigroup a => a -> a -> a
<> forall a. EncCBOR a => a -> Encoding
encCBOR CompactAddr
addr
      forall a. Semigroup a => a -> a -> a
<> forall a. EncCBOR a => a -> Encoding
encCBOR CompactForm (Value era)
cv
      forall a. Semigroup a => a -> a -> a
<> forall a. EncCBOR a => a -> Encoding
encCBOR DataHash
dh

instance (Era era, Val (Value era)) => DecCBOR (AlonzoTxOut era) where
  decCBOR :: forall s. Decoder s (AlonzoTxOut era)
decCBOR = do
    Maybe Int
lenOrIndef <- forall s. Decoder s (Maybe Int)
decodeListLenOrIndef
    case Maybe Int
lenOrIndef of
      Maybe Int
Nothing -> do
        (Addr
a, CompactAddr
ca) <- forall s. Decoder s (Addr, CompactAddr)
fromCborBothAddr
        CompactForm (Value era)
cv <- forall a s. DecCBOR a => Decoder s a
decCBOR
        forall s. Decoder s Bool
decodeBreakOr forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
          Bool
True -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall era.
(Era era, HasCallStack, Val (Value era)) =>
Addr
-> CompactAddr
-> CompactForm (Value era)
-> StrictMaybe DataHash
-> AlonzoTxOut era
mkTxOutCompact Addr
a CompactAddr
ca CompactForm (Value era)
cv forall a. StrictMaybe a
SNothing
          Bool
False -> do
            DataHash
dh <- forall a s. DecCBOR a => Decoder s a
decCBOR
            forall s. Decoder s Bool
decodeBreakOr forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
              Bool
True -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall era.
(Era era, HasCallStack, Val (Value era)) =>
Addr
-> CompactAddr
-> CompactForm (Value era)
-> StrictMaybe DataHash
-> AlonzoTxOut era
mkTxOutCompact Addr
a CompactAddr
ca CompactForm (Value era)
cv (forall a. a -> StrictMaybe a
SJust DataHash
dh)
              Bool
False -> forall (m :: * -> *) e a. (MonadFail m, Buildable e) => e -> m a
cborError forall a b. (a -> b) -> a -> b
$ Text -> Text -> DecoderError
DecoderErrorCustom Text
"txout" Text
"Excess terms in txout"
      Just Int
2 -> do
        (Addr
a, CompactAddr
ca) <- forall s. Decoder s (Addr, CompactAddr)
fromCborBothAddr
        CompactForm (Value era)
cv <- forall a s. DecCBOR a => Decoder s a
decCBOR
        forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall era.
(Era era, HasCallStack, Val (Value era)) =>
Addr
-> CompactAddr
-> CompactForm (Value era)
-> StrictMaybe DataHash
-> AlonzoTxOut era
mkTxOutCompact Addr
a CompactAddr
ca CompactForm (Value era)
cv forall a. StrictMaybe a
SNothing
      Just Int
3 -> do
        (Addr
a, CompactAddr
ca) <- forall s. Decoder s (Addr, CompactAddr)
fromCborBothAddr
        CompactForm (Value era)
cv <- forall a s. DecCBOR a => Decoder s a
decCBOR
        forall era.
(Era era, HasCallStack, Val (Value era)) =>
Addr
-> CompactAddr
-> CompactForm (Value era)
-> StrictMaybe DataHash
-> AlonzoTxOut era
mkTxOutCompact Addr
a CompactAddr
ca CompactForm (Value era)
cv forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> StrictMaybe a
SJust forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a s. DecCBOR a => Decoder s a
decCBOR
      Just Int
_ -> forall (m :: * -> *) e a. (MonadFail m, Buildable e) => e -> m a
cborError forall a b. (a -> b) -> a -> b
$ Text -> Text -> DecoderError
DecoderErrorCustom Text
"txout" Text
"wrong number of terms in txout"
  {-# INLINEABLE decCBOR #-}

instance (Era era, Val (Value era)) => DecShareCBOR (AlonzoTxOut era) where
  type Share (AlonzoTxOut era) = Interns (Credential 'Staking)
  decShareCBOR :: forall s. Share (AlonzoTxOut era) -> Decoder s (AlonzoTxOut era)
decShareCBOR Share (AlonzoTxOut era)
credsInterns = do
    forall era.
(Credential 'Staking -> Credential 'Staking)
-> AlonzoTxOut era -> AlonzoTxOut era
internAlonzoTxOut (forall k. Interns k -> k -> k
interns Share (AlonzoTxOut era)
credsInterns) forall (m :: * -> *) a b. Monad m => (a -> b) -> m a -> m b
<$!> forall a s. DecCBOR a => Decoder s a
decCBOR
  {-# INLINEABLE decShareCBOR #-}

internAlonzoTxOut ::
  (Credential 'Staking -> Credential 'Staking) ->
  AlonzoTxOut era ->
  AlonzoTxOut era
internAlonzoTxOut :: forall era.
(Credential 'Staking -> Credential 'Staking)
-> AlonzoTxOut era -> AlonzoTxOut era
internAlonzoTxOut Credential 'Staking -> Credential 'Staking
internCred = \case
  TxOut_AddrHash28_AdaOnly Credential 'Staking
cred Addr28Extra
addr28Extra CompactForm Coin
ada ->
    forall era.
Credential 'Staking
-> Addr28Extra -> CompactForm Coin -> AlonzoTxOut era
TxOut_AddrHash28_AdaOnly (Credential 'Staking -> Credential 'Staking
internCred Credential 'Staking
cred) Addr28Extra
addr28Extra CompactForm Coin
ada
  TxOut_AddrHash28_AdaOnly_DataHash32 Credential 'Staking
cred Addr28Extra
addr28Extra CompactForm Coin
ada DataHash32
dataHash32 ->
    forall era.
Credential 'Staking
-> Addr28Extra -> CompactForm Coin -> DataHash32 -> AlonzoTxOut era
TxOut_AddrHash28_AdaOnly_DataHash32 (Credential 'Staking -> Credential 'Staking
internCred Credential 'Staking
cred) Addr28Extra
addr28Extra CompactForm Coin
ada DataHash32
dataHash32
  AlonzoTxOut era
txOut -> AlonzoTxOut era
txOut
{-# INLINE internAlonzoTxOut #-}

instance (Era era, Val (Value era)) => ToCBOR (AlonzoTxOut era) where
  toCBOR :: AlonzoTxOut era -> Encoding
toCBOR = forall era t. (Era era, EncCBOR t) => t -> Encoding
toEraCBOR @era
  {-# INLINE toCBOR #-}

instance (Era era, Val (Value era)) => FromCBOR (AlonzoTxOut era) where
  fromCBOR :: forall s. Decoder s (AlonzoTxOut era)
fromCBOR = forall era t s. (Era era, DecCBOR t) => Decoder s t
fromEraCBOR @era
  {-# INLINE fromCBOR #-}

instance (Era era, Val (Value era)) => ToJSON (AlonzoTxOut era) where
  toJSON :: AlonzoTxOut era -> Value
toJSON (AlonzoTxOut Addr
addr Value era
v StrictMaybe DataHash
dataHash) =
    [Pair] -> Value
object
      [ Key
"address" forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= forall a. ToJSON a => a -> Value
toJSON Addr
addr
      , Key
"value" forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= forall a. ToJSON a => a -> Value
toJSON Value era
v
      , Key
"datahash" forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= case forall a. StrictMaybe a -> Maybe a
strictMaybeToMaybe StrictMaybe DataHash
dataHash of
          Maybe DataHash
Nothing -> Value
Aeson.Null
          Just DataHash
dHash ->
            Text -> Value
Aeson.String forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall h a. Hash h a -> Text
hashToTextAsHex forall a b. (a -> b) -> a -> b
$
              forall i. SafeHash i -> Hash HASH i
extractHash DataHash
dHash
      ]

pattern TxOutCompact ::
  (Era era, Val (Value era), HasCallStack) =>
  CompactAddr ->
  CompactForm (Value era) ->
  AlonzoTxOut era
pattern $bTxOutCompact :: forall era.
(Era era, Val (Value era), HasCallStack) =>
CompactAddr -> CompactForm (Value era) -> AlonzoTxOut era
$mTxOutCompact :: forall {r} {era}.
(Era era, Val (Value era), HasCallStack) =>
AlonzoTxOut era
-> (CompactAddr -> CompactForm (Value era) -> r)
-> ((# #) -> r)
-> r
TxOutCompact addr vl <-
  (viewCompactTxOut -> (addr, vl, SNothing))
  where
    TxOutCompact CompactAddr
cAddr CompactForm (Value era)
cVal = forall era.
(Era era, HasCallStack, Val (Value era)) =>
Addr
-> CompactAddr
-> CompactForm (Value era)
-> StrictMaybe DataHash
-> AlonzoTxOut era
mkTxOutCompact (HasCallStack => CompactAddr -> Addr
decompactAddr CompactAddr
cAddr) CompactAddr
cAddr CompactForm (Value era)
cVal forall a. StrictMaybe a
SNothing

pattern TxOutCompactDH ::
  (Era era, Val (Value era), HasCallStack) =>
  CompactAddr ->
  CompactForm (Value era) ->
  DataHash ->
  AlonzoTxOut era
pattern $bTxOutCompactDH :: forall era.
(Era era, Val (Value era), HasCallStack) =>
CompactAddr
-> CompactForm (Value era) -> DataHash -> AlonzoTxOut era
$mTxOutCompactDH :: forall {r} {era}.
(Era era, Val (Value era), HasCallStack) =>
AlonzoTxOut era
-> (CompactAddr -> CompactForm (Value era) -> DataHash -> r)
-> ((# #) -> r)
-> r
TxOutCompactDH addr vl dh <-
  (viewCompactTxOut -> (addr, vl, SJust dh))
  where
    TxOutCompactDH CompactAddr
cAddr CompactForm (Value era)
cVal DataHash
dh = forall era.
(Era era, HasCallStack, Val (Value era)) =>
Addr
-> CompactAddr
-> CompactForm (Value era)
-> StrictMaybe DataHash
-> AlonzoTxOut era
mkTxOutCompact (HasCallStack => CompactAddr -> Addr
decompactAddr CompactAddr
cAddr) CompactAddr
cAddr CompactForm (Value era)
cVal (forall a. a -> StrictMaybe a
SJust DataHash
dh)

{-# COMPLETE TxOutCompact, TxOutCompactDH #-}

mkTxOutCompact ::
  (Era era, HasCallStack, Val (Value era)) =>
  Addr ->
  CompactAddr ->
  CompactForm (Value era) ->
  StrictMaybe DataHash ->
  AlonzoTxOut era
mkTxOutCompact :: forall era.
(Era era, HasCallStack, Val (Value era)) =>
Addr
-> CompactAddr
-> CompactForm (Value era)
-> StrictMaybe DataHash
-> AlonzoTxOut era
mkTxOutCompact Addr
addr CompactAddr
cAddr CompactForm (Value era)
cVal StrictMaybe DataHash
mdh
  | forall t. Val t => CompactForm t -> Bool
isAdaOnlyCompact CompactForm (Value era)
cVal = forall era.
(Era era, Val (Value era), HasCallStack) =>
Addr -> Value era -> StrictMaybe DataHash -> AlonzoTxOut era
AlonzoTxOut Addr
addr (forall a. Compactible a => CompactForm a -> a
fromCompact CompactForm (Value era)
cVal) StrictMaybe DataHash
mdh
  | SJust DataHash
dh <- StrictMaybe DataHash
mdh = forall era.
CompactAddr
-> CompactForm (Value era) -> DataHash -> AlonzoTxOut era
TxOutCompactDH' CompactAddr
cAddr CompactForm (Value era)
cVal DataHash
dh
  | Bool
otherwise = forall era.
CompactAddr -> CompactForm (Value era) -> AlonzoTxOut era
TxOutCompact' CompactAddr
cAddr CompactForm (Value era)
cVal

getAlonzoTxOutDataHash ::
  forall era.
  HasCallStack =>
  AlonzoTxOut era ->
  StrictMaybe DataHash
getAlonzoTxOutDataHash :: forall era. HasCallStack => AlonzoTxOut era -> StrictMaybe DataHash
getAlonzoTxOutDataHash = \case
  TxOutCompactDH' CompactAddr
_ CompactForm (Value era)
_ DataHash
dh -> forall a. a -> StrictMaybe a
SJust DataHash
dh
  TxOut_AddrHash28_AdaOnly_DataHash32 Credential 'Staking
_ Addr28Extra
_ CompactForm Coin
_ DataHash32
dh ->
    case DataHash32 -> Maybe DataHash
decodeDataHash32 DataHash32
dh of
      Maybe DataHash
Nothing -> forall a. HasCallStack => [Char] -> a
error forall a b. (a -> b) -> a -> b
$ [Char]
"Impossible: Compacted a DataHash of non-standard size: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show DataHash32
dh
      Just DataHash
dataHash -> forall a. a -> StrictMaybe a
SJust DataHash
dataHash
  AlonzoTxOut era
_ -> forall a. StrictMaybe a
SNothing

getAlonzoTxOutEitherAddr ::
  AlonzoTxOut era ->
  Either Addr CompactAddr
getAlonzoTxOutEitherAddr :: forall era. AlonzoTxOut era -> Either Addr CompactAddr
getAlonzoTxOutEitherAddr = \case
  TxOutCompact' CompactAddr
cAddr CompactForm (Value era)
_ -> forall a b. b -> Either a b
Right CompactAddr
cAddr
  TxOutCompactDH' CompactAddr
cAddr CompactForm (Value era)
_ DataHash
_ -> forall a b. b -> Either a b
Right CompactAddr
cAddr
  TxOut_AddrHash28_AdaOnly Credential 'Staking
stakeRef Addr28Extra
addr28Extra CompactForm Coin
_
    | Just Addr
addr <- Credential 'Staking -> Addr28Extra -> Maybe Addr
decodeAddress28 Credential 'Staking
stakeRef Addr28Extra
addr28Extra -> forall a b. a -> Either a b
Left Addr
addr
    | Bool
otherwise -> forall a. HasCallStack => [Char] -> a
error [Char]
addressErrorMsg
  TxOut_AddrHash28_AdaOnly_DataHash32 Credential 'Staking
stakeRef Addr28Extra
addr28Extra CompactForm Coin
_ DataHash32
_
    | Just Addr
addr <- Credential 'Staking -> Addr28Extra -> Maybe Addr
decodeAddress28 Credential 'Staking
stakeRef Addr28Extra
addr28Extra -> forall a b. a -> Either a b
Left Addr
addr
    | Bool
otherwise -> forall a. HasCallStack => [Char] -> a
error [Char]
addressErrorMsg

-- | Compute an estimate of the size of storing one UTxO entry.
-- This function implements the UTxO entry size estimate done by scaledMinDeposit in the ShelleyMA era
utxoEntrySize :: AlonzoEraTxOut era => TxOut era -> Integer
utxoEntrySize :: forall era. AlonzoEraTxOut era => TxOut era -> Integer
utxoEntrySize TxOut era
txOut = Integer
utxoEntrySizeWithoutVal forall a. Num a => a -> a -> a
+ forall t. Val t => t -> Integer
size Value era
v forall a. Num a => a -> a -> a
+ StrictMaybe DataHash -> Integer
dataHashSize StrictMaybe DataHash
dh
  where
    v :: Value era
v = TxOut era
txOut forall s a. s -> Getting a s a -> a
^. forall era. EraTxOut era => Lens' (TxOut era) (Value era)
valueTxOutL
    dh :: StrictMaybe DataHash
dh = TxOut era
txOut forall s a. s -> Getting a s a -> a
^. forall era.
AlonzoEraTxOut era =>
Lens' (TxOut era) (StrictMaybe DataHash)
dataHashTxOutL
    -- lengths obtained from tracing on HeapWords of inputs and outputs
    -- obtained experimentally, and number used here
    -- units are Word64s

    -- size of UTxO entry excluding the Value part
    utxoEntrySizeWithoutVal :: Integer
    utxoEntrySizeWithoutVal :: Integer
utxoEntrySizeWithoutVal = Integer
27 -- 6 + txoutLenNoVal [14] + txinLen [7]

instance AlonzoEraTxOut AlonzoEra where
  dataHashTxOutL :: Lens' (TxOut AlonzoEra) (StrictMaybe DataHash)
dataHashTxOutL =
    forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens forall era. HasCallStack => AlonzoTxOut era -> StrictMaybe DataHash
getAlonzoTxOutDataHash (\(AlonzoTxOut Addr
addr Value AlonzoEra
cv StrictMaybe DataHash
_) StrictMaybe DataHash
dh -> forall era.
(Era era, Val (Value era), HasCallStack) =>
Addr -> Value era -> StrictMaybe DataHash -> AlonzoTxOut era
AlonzoTxOut Addr
addr Value AlonzoEra
cv StrictMaybe DataHash
dh)
  {-# INLINEABLE dataHashTxOutL #-}

  datumTxOutF :: SimpleGetter (TxOut AlonzoEra) (Datum AlonzoEra)
datumTxOutF = forall s a. (s -> a) -> SimpleGetter s a
to forall a b. (a -> b) -> a -> b
$ \TxOut AlonzoEra
txOut ->
    case forall era. HasCallStack => AlonzoTxOut era -> StrictMaybe DataHash
getAlonzoTxOutDataHash TxOut AlonzoEra
txOut of
      StrictMaybe DataHash
SNothing -> forall era. Datum era
NoDatum
      SJust DataHash
dh -> forall era. DataHash -> Datum era
DatumHash DataHash
dh
  {-# INLINEABLE datumTxOutF #-}

getTxOutCompactValue :: EraTxOut era => AlonzoTxOut era -> CompactForm (Value era)
getTxOutCompactValue :: forall era.
EraTxOut era =>
AlonzoTxOut era -> CompactForm (Value era)
getTxOutCompactValue =
  \case
    TxOutCompact' CompactAddr
_ CompactForm (Value era)
cv -> CompactForm (Value era)
cv
    TxOutCompactDH' CompactAddr
_ CompactForm (Value era)
cv DataHash
_ -> CompactForm (Value era)
cv
    TxOut_AddrHash28_AdaOnly Credential 'Staking
_ Addr28Extra
_ CompactForm Coin
cc -> forall t. Val t => CompactForm Coin -> CompactForm t
injectCompact CompactForm Coin
cc
    TxOut_AddrHash28_AdaOnly_DataHash32 Credential 'Staking
_ Addr28Extra
_ CompactForm Coin
cc DataHash32
_ -> forall t. Val t => CompactForm Coin -> CompactForm t
injectCompact CompactForm Coin
cc