{-# LANGUAGE BangPatterns #-}
{-# 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 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 (..),
  TokenType (..),
  cborError,
  decodeBreakOr,
  decodeListLenOrIndef,
  decodeMemPack,
  encodeListLen,
  interns,
  peekTokenType,
 )
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.MemPack
import Data.Typeable (Proxy (..))
import Data.Word
import GHC.Generics (Generic)
import GHC.Stack (HasCallStack)
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
(Addr28Extra -> Addr28Extra -> Bool)
-> (Addr28Extra -> Addr28Extra -> Bool) -> Eq Addr28Extra
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Addr28Extra -> Addr28Extra -> Bool
== :: Addr28Extra -> Addr28Extra -> Bool
$c/= :: Addr28Extra -> Addr28Extra -> Bool
/= :: Addr28Extra -> Addr28Extra -> Bool
Eq, Int -> Addr28Extra -> ShowS
[Addr28Extra] -> ShowS
Addr28Extra -> [Char]
(Int -> Addr28Extra -> ShowS)
-> (Addr28Extra -> [Char])
-> ([Addr28Extra] -> ShowS)
-> Show Addr28Extra
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Addr28Extra -> ShowS
showsPrec :: Int -> Addr28Extra -> ShowS
$cshow :: Addr28Extra -> [Char]
show :: Addr28Extra -> [Char]
$cshowList :: [Addr28Extra] -> ShowS
showList :: [Addr28Extra] -> ShowS
Show, (forall x. Addr28Extra -> Rep Addr28Extra x)
-> (forall x. Rep Addr28Extra x -> Addr28Extra)
-> Generic Addr28Extra
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
$cfrom :: forall x. Addr28Extra -> Rep Addr28Extra x
from :: forall x. Addr28Extra -> Rep Addr28Extra x
$cto :: forall x. Rep Addr28Extra x -> Addr28Extra
to :: forall x. Rep Addr28Extra x -> Addr28Extra
Generic, Context -> Addr28Extra -> IO (Maybe ThunkInfo)
Proxy Addr28Extra -> [Char]
(Context -> Addr28Extra -> IO (Maybe ThunkInfo))
-> (Context -> Addr28Extra -> IO (Maybe ThunkInfo))
-> (Proxy Addr28Extra -> [Char])
-> NoThunks Addr28Extra
forall a.
(Context -> a -> IO (Maybe ThunkInfo))
-> (Context -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> [Char])
-> NoThunks a
$cnoThunks :: Context -> Addr28Extra -> IO (Maybe ThunkInfo)
noThunks :: Context -> Addr28Extra -> IO (Maybe ThunkInfo)
$cwNoThunks :: Context -> Addr28Extra -> IO (Maybe ThunkInfo)
wNoThunks :: Context -> Addr28Extra -> IO (Maybe ThunkInfo)
$cshowTypeOf :: Proxy Addr28Extra -> [Char]
showTypeOf :: Proxy Addr28Extra -> [Char]
NoThunks)

instance MemPack Addr28Extra where
  packedByteCount :: Addr28Extra -> Int
packedByteCount Addr28Extra
_ = Int
32
  packM :: forall s. Addr28Extra -> Pack s ()
packM (Addr28Extra Word64
w0 Word64
w1 Word64
w2 Word64
w3) = Word64 -> Pack s ()
forall s. Word64 -> Pack s ()
forall a s. MemPack a => a -> Pack s ()
packM Word64
w0 Pack s () -> Pack s () -> Pack s ()
forall a b. Pack s a -> Pack s b -> Pack s b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Word64 -> Pack s ()
forall s. Word64 -> Pack s ()
forall a s. MemPack a => a -> Pack s ()
packM Word64
w1 Pack s () -> Pack s () -> Pack s ()
forall a b. Pack s a -> Pack s b -> Pack s b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Word64 -> Pack s ()
forall s. Word64 -> Pack s ()
forall a s. MemPack a => a -> Pack s ()
packM Word64
w2 Pack s () -> Pack s () -> Pack s ()
forall a b. Pack s a -> Pack s b -> Pack s b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Word64 -> Pack s ()
forall s. Word64 -> Pack s ()
forall a s. MemPack a => a -> Pack s ()
packM Word64
w3
  {-# INLINE packM #-}
  unpackM :: forall b. Buffer b => Unpack b Addr28Extra
unpackM = Word64 -> Word64 -> Word64 -> Word64 -> Addr28Extra
Addr28Extra (Word64 -> Word64 -> Word64 -> Word64 -> Addr28Extra)
-> Unpack b Word64
-> Unpack b (Word64 -> Word64 -> Word64 -> Addr28Extra)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Unpack b Word64
forall a b. (MemPack a, Buffer b) => Unpack b a
forall b. Buffer b => Unpack b Word64
unpackM Unpack b (Word64 -> Word64 -> Word64 -> Addr28Extra)
-> Unpack b Word64 -> Unpack b (Word64 -> Word64 -> Addr28Extra)
forall a b. Unpack b (a -> b) -> Unpack b a -> Unpack b b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Unpack b Word64
forall a b. (MemPack a, Buffer b) => Unpack b a
forall b. Buffer b => Unpack b Word64
unpackM Unpack b (Word64 -> Word64 -> Addr28Extra)
-> Unpack b Word64 -> Unpack b (Word64 -> Addr28Extra)
forall a b. Unpack b (a -> b) -> Unpack b a -> Unpack b b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Unpack b Word64
forall a b. (MemPack a, Buffer b) => Unpack b a
forall b. Buffer b => Unpack b Word64
unpackM Unpack b (Word64 -> Addr28Extra)
-> Unpack b Word64 -> Unpack b Addr28Extra
forall a b. Unpack b (a -> b) -> Unpack b a -> Unpack b b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Unpack b Word64
forall a b. (MemPack a, Buffer b) => Unpack b a
forall b. Buffer b => Unpack b Word64
unpackM
  {-# INLINE unpackM #-}

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

instance MemPack DataHash32 where
  packedByteCount :: DataHash32 -> Int
packedByteCount DataHash32
_ = Int
32
  packM :: forall s. DataHash32 -> Pack s ()
packM (DataHash32 Word64
w0 Word64
w1 Word64
w2 Word64
w3) = Word64 -> Pack s ()
forall s. Word64 -> Pack s ()
forall a s. MemPack a => a -> Pack s ()
packM Word64
w0 Pack s () -> Pack s () -> Pack s ()
forall a b. Pack s a -> Pack s b -> Pack s b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Word64 -> Pack s ()
forall s. Word64 -> Pack s ()
forall a s. MemPack a => a -> Pack s ()
packM Word64
w1 Pack s () -> Pack s () -> Pack s ()
forall a b. Pack s a -> Pack s b -> Pack s b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Word64 -> Pack s ()
forall s. Word64 -> Pack s ()
forall a s. MemPack a => a -> Pack s ()
packM Word64
w2 Pack s () -> Pack s () -> Pack s ()
forall a b. Pack s a -> Pack s b -> Pack s b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Word64 -> Pack s ()
forall s. Word64 -> Pack s ()
forall a s. MemPack a => a -> Pack s ()
packM Word64
w3
  {-# INLINE packM #-}
  unpackM :: forall b. Buffer b => Unpack b DataHash32
unpackM = Word64 -> Word64 -> Word64 -> Word64 -> DataHash32
DataHash32 (Word64 -> Word64 -> Word64 -> Word64 -> DataHash32)
-> Unpack b Word64
-> Unpack b (Word64 -> Word64 -> Word64 -> DataHash32)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Unpack b Word64
forall a b. (MemPack a, Buffer b) => Unpack b a
forall b. Buffer b => Unpack b Word64
unpackM Unpack b (Word64 -> Word64 -> Word64 -> DataHash32)
-> Unpack b Word64 -> Unpack b (Word64 -> Word64 -> DataHash32)
forall a b. Unpack b (a -> b) -> Unpack b a -> Unpack b b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Unpack b Word64
forall a b. (MemPack a, Buffer b) => Unpack b a
forall b. Buffer b => Unpack b Word64
unpackM Unpack b (Word64 -> Word64 -> DataHash32)
-> Unpack b Word64 -> Unpack b (Word64 -> DataHash32)
forall a b. Unpack b (a -> b) -> Unpack b a -> Unpack b b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Unpack b Word64
forall a b. (MemPack a, Buffer b) => Unpack b a
forall b. Buffer b => Unpack b Word64
unpackM Unpack b (Word64 -> DataHash32)
-> Unpack b Word64 -> Unpack b DataHash32
forall a b. Unpack b (a -> b) -> Unpack b a -> Unpack b b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Unpack b Word64
forall a b. (MemPack a, Buffer b) => Unpack b a
forall b. Buffer b => Unpack b Word64
unpackM
  {-# INLINE unpackM #-}

decodeAddress28 ::
  Credential 'Staking ->
  Addr28Extra ->
  Addr
decodeAddress28 :: Credential 'Staking -> Addr28Extra -> Addr
decodeAddress28 Credential 'Staking
stakeRef (Addr28Extra Word64
a Word64
b Word64
c Word64
d) =
  let network :: Network
network = if Word64
d Word64 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
`testBit` Int
1 then Network
Mainnet else Network
Testnet
      paymentCred :: Credential 'Payment
paymentCred =
        if Word64
d Word64 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
`testBit` Int
0
          then KeyHash 'Payment -> Credential 'Payment
forall (kr :: KeyRole). KeyHash kr -> Credential kr
KeyHashObj (Hash ADDRHASH (VerKeyDSIGN DSIGN) -> KeyHash 'Payment
forall (r :: KeyRole).
Hash ADDRHASH (VerKeyDSIGN DSIGN) -> KeyHash r
KeyHash Hash ADDRHASH (VerKeyDSIGN DSIGN)
forall a. Hash ADDRHASH a
addrHash)
          else ScriptHash -> Credential 'Payment
forall (kr :: KeyRole). ScriptHash -> Credential kr
ScriptHashObj (Hash ADDRHASH EraIndependentScript -> ScriptHash
ScriptHash Hash ADDRHASH EraIndependentScript
forall a. Hash ADDRHASH a
addrHash)
      addrHash :: Hash ADDRHASH a
      addrHash :: forall a. Hash ADDRHASH a
addrHash =
        PackedBytes (SizeHash ADDRHASH) -> Hash ADDRHASH a
forall h a. PackedBytes (SizeHash h) -> Hash h a
hashFromPackedBytes (PackedBytes (SizeHash ADDRHASH) -> Hash ADDRHASH a)
-> PackedBytes (SizeHash ADDRHASH) -> Hash ADDRHASH a
forall a b. (a -> b) -> a -> b
$
          Word64 -> Word64 -> Word64 -> Word32 -> PackedBytes 28
PackedBytes28 Word64
a Word64
b Word64
c (Word64 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64
d Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftR` Int
32))
   in 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

-- | This instance is backwards compatible in binary representation with TxOut instances for all
-- previous era
instance (Era era, MemPack (CompactForm (Value era))) => MemPack (AlonzoTxOut era) where
  packedByteCount :: AlonzoTxOut era -> Int
packedByteCount = \case
    TxOutCompact' CompactAddr
cAddr CompactForm (Value era)
cValue ->
      Int
packedTagByteCount Int -> Int -> Int
forall a. Num a => a -> a -> a
+ CompactAddr -> Int
forall a. MemPack a => a -> Int
packedByteCount CompactAddr
cAddr Int -> Int -> Int
forall a. Num a => a -> a -> a
+ CompactForm (Value era) -> Int
forall a. MemPack a => a -> Int
packedByteCount CompactForm (Value era)
cValue
    TxOutCompactDH' CompactAddr
cAddr CompactForm (Value era)
cValue DataHash
dataHash ->
      Int
packedTagByteCount Int -> Int -> Int
forall a. Num a => a -> a -> a
+ CompactAddr -> Int
forall a. MemPack a => a -> Int
packedByteCount CompactAddr
cAddr Int -> Int -> Int
forall a. Num a => a -> a -> a
+ CompactForm (Value era) -> Int
forall a. MemPack a => a -> Int
packedByteCount CompactForm (Value era)
cValue Int -> Int -> Int
forall a. Num a => a -> a -> a
+ DataHash -> Int
forall a. MemPack a => a -> Int
packedByteCount DataHash
dataHash
    TxOut_AddrHash28_AdaOnly Credential 'Staking
cred Addr28Extra
addr28 CompactForm Coin
cCoin ->
      Int
packedTagByteCount Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Credential 'Staking -> Int
forall a. MemPack a => a -> Int
packedByteCount Credential 'Staking
cred Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Addr28Extra -> Int
forall a. MemPack a => a -> Int
packedByteCount Addr28Extra
addr28 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ CompactForm Coin -> Int
forall a. MemPack a => a -> Int
packedByteCount CompactForm Coin
cCoin
    TxOut_AddrHash28_AdaOnly_DataHash32 Credential 'Staking
cred Addr28Extra
addr28 CompactForm Coin
cCoin DataHash32
dataHash32 ->
      Int
packedTagByteCount
        Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Credential 'Staking -> Int
forall a. MemPack a => a -> Int
packedByteCount Credential 'Staking
cred
        Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Addr28Extra -> Int
forall a. MemPack a => a -> Int
packedByteCount Addr28Extra
addr28
        Int -> Int -> Int
forall a. Num a => a -> a -> a
+ CompactForm Coin -> Int
forall a. MemPack a => a -> Int
packedByteCount CompactForm Coin
cCoin
        Int -> Int -> Int
forall a. Num a => a -> a -> a
+ DataHash32 -> Int
forall a. MemPack a => a -> Int
packedByteCount DataHash32
dataHash32
  {-# INLINE packedByteCount #-}
  packM :: forall s. AlonzoTxOut era -> Pack s ()
packM = \case
    TxOutCompact' CompactAddr
cAddr CompactForm (Value era)
cValue ->
      Tag -> Pack s ()
forall s. Tag -> Pack s ()
packTagM Tag
0 Pack s () -> Pack s () -> Pack s ()
forall a b. Pack s a -> Pack s b -> Pack s b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> CompactAddr -> Pack s ()
forall a s. MemPack a => a -> Pack s ()
forall s. CompactAddr -> Pack s ()
packM CompactAddr
cAddr Pack s () -> Pack s () -> Pack s ()
forall a b. Pack s a -> Pack s b -> Pack s b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> CompactForm (Value era) -> Pack s ()
forall a s. MemPack a => a -> Pack s ()
forall s. CompactForm (Value era) -> Pack s ()
packM CompactForm (Value era)
cValue
    TxOutCompactDH' CompactAddr
cAddr CompactForm (Value era)
cValue DataHash
dataHash ->
      Tag -> Pack s ()
forall s. Tag -> Pack s ()
packTagM Tag
1 Pack s () -> Pack s () -> Pack s ()
forall a b. Pack s a -> Pack s b -> Pack s b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> CompactAddr -> Pack s ()
forall a s. MemPack a => a -> Pack s ()
forall s. CompactAddr -> Pack s ()
packM CompactAddr
cAddr Pack s () -> Pack s () -> Pack s ()
forall a b. Pack s a -> Pack s b -> Pack s b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> CompactForm (Value era) -> Pack s ()
forall a s. MemPack a => a -> Pack s ()
forall s. CompactForm (Value era) -> Pack s ()
packM CompactForm (Value era)
cValue Pack s () -> Pack s () -> Pack s ()
forall a b. Pack s a -> Pack s b -> Pack s b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> DataHash -> Pack s ()
forall s. DataHash -> Pack s ()
forall a s. MemPack a => a -> Pack s ()
packM DataHash
dataHash
    TxOut_AddrHash28_AdaOnly Credential 'Staking
cred Addr28Extra
addr28 CompactForm Coin
cCoin ->
      Tag -> Pack s ()
forall s. Tag -> Pack s ()
packTagM Tag
2 Pack s () -> Pack s () -> Pack s ()
forall a b. Pack s a -> Pack s b -> Pack s b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Credential 'Staking -> Pack s ()
forall a s. MemPack a => a -> Pack s ()
forall s. Credential 'Staking -> Pack s ()
packM Credential 'Staking
cred Pack s () -> Pack s () -> Pack s ()
forall a b. Pack s a -> Pack s b -> Pack s b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Addr28Extra -> Pack s ()
forall a s. MemPack a => a -> Pack s ()
forall s. Addr28Extra -> Pack s ()
packM Addr28Extra
addr28 Pack s () -> Pack s () -> Pack s ()
forall a b. Pack s a -> Pack s b -> Pack s b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> CompactForm Coin -> Pack s ()
forall a s. MemPack a => a -> Pack s ()
forall s. CompactForm Coin -> Pack s ()
packM CompactForm Coin
cCoin
    TxOut_AddrHash28_AdaOnly_DataHash32 Credential 'Staking
cred Addr28Extra
addr28 CompactForm Coin
cCoin DataHash32
dataHash32 ->
      Tag -> Pack s ()
forall s. Tag -> Pack s ()
packTagM Tag
3 Pack s () -> Pack s () -> Pack s ()
forall a b. Pack s a -> Pack s b -> Pack s b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Credential 'Staking -> Pack s ()
forall a s. MemPack a => a -> Pack s ()
forall s. Credential 'Staking -> Pack s ()
packM Credential 'Staking
cred Pack s () -> Pack s () -> Pack s ()
forall a b. Pack s a -> Pack s b -> Pack s b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Addr28Extra -> Pack s ()
forall a s. MemPack a => a -> Pack s ()
forall s. Addr28Extra -> Pack s ()
packM Addr28Extra
addr28 Pack s () -> Pack s () -> Pack s ()
forall a b. Pack s a -> Pack s b -> Pack s b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> CompactForm Coin -> Pack s ()
forall a s. MemPack a => a -> Pack s ()
forall s. CompactForm Coin -> Pack s ()
packM CompactForm Coin
cCoin Pack s () -> Pack s () -> Pack s ()
forall a b. Pack s a -> Pack s b -> Pack s b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> DataHash32 -> Pack s ()
forall a s. MemPack a => a -> Pack s ()
forall s. DataHash32 -> Pack s ()
packM DataHash32
dataHash32
  {-# INLINE packM #-}
  unpackM :: forall b. Buffer b => Unpack b (AlonzoTxOut era)
unpackM =
    Unpack b Tag
forall b. Buffer b => Unpack b Tag
unpackTagM Unpack b Tag
-> (Tag -> Unpack b (AlonzoTxOut era))
-> Unpack b (AlonzoTxOut era)
forall a b. Unpack b a -> (a -> Unpack b b) -> Unpack b b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
      Tag
0 -> CompactAddr -> CompactForm (Value era) -> AlonzoTxOut era
forall era.
CompactAddr -> CompactForm (Value era) -> AlonzoTxOut era
TxOutCompact' (CompactAddr -> CompactForm (Value era) -> AlonzoTxOut era)
-> Unpack b CompactAddr
-> Unpack b (CompactForm (Value era) -> AlonzoTxOut era)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Unpack b CompactAddr
forall a b. (MemPack a, Buffer b) => Unpack b a
forall b. Buffer b => Unpack b CompactAddr
unpackM Unpack b (CompactForm (Value era) -> AlonzoTxOut era)
-> Unpack b (CompactForm (Value era)) -> Unpack b (AlonzoTxOut era)
forall a b. Unpack b (a -> b) -> Unpack b a -> Unpack b b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Unpack b (CompactForm (Value era))
forall a b. (MemPack a, Buffer b) => Unpack b a
forall b. Buffer b => Unpack b (CompactForm (Value era))
unpackM
      Tag
1 -> CompactAddr
-> CompactForm (Value era) -> DataHash -> AlonzoTxOut era
forall era.
CompactAddr
-> CompactForm (Value era) -> DataHash -> AlonzoTxOut era
TxOutCompactDH' (CompactAddr
 -> CompactForm (Value era) -> DataHash -> AlonzoTxOut era)
-> Unpack b CompactAddr
-> Unpack
     b (CompactForm (Value era) -> DataHash -> AlonzoTxOut era)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Unpack b CompactAddr
forall a b. (MemPack a, Buffer b) => Unpack b a
forall b. Buffer b => Unpack b CompactAddr
unpackM Unpack b (CompactForm (Value era) -> DataHash -> AlonzoTxOut era)
-> Unpack b (CompactForm (Value era))
-> Unpack b (DataHash -> AlonzoTxOut era)
forall a b. Unpack b (a -> b) -> Unpack b a -> Unpack b b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Unpack b (CompactForm (Value era))
forall a b. (MemPack a, Buffer b) => Unpack b a
forall b. Buffer b => Unpack b (CompactForm (Value era))
unpackM Unpack b (DataHash -> AlonzoTxOut era)
-> Unpack b DataHash -> Unpack b (AlonzoTxOut era)
forall a b. Unpack b (a -> b) -> Unpack b a -> Unpack b b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Unpack b DataHash
forall a b. (MemPack a, Buffer b) => Unpack b a
forall b. Buffer b => Unpack b DataHash
unpackM
      Tag
2 -> Credential 'Staking
-> Addr28Extra -> CompactForm Coin -> AlonzoTxOut era
forall era.
Credential 'Staking
-> Addr28Extra -> CompactForm Coin -> AlonzoTxOut era
TxOut_AddrHash28_AdaOnly (Credential 'Staking
 -> Addr28Extra -> CompactForm Coin -> AlonzoTxOut era)
-> Unpack b (Credential 'Staking)
-> Unpack b (Addr28Extra -> CompactForm Coin -> AlonzoTxOut era)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Unpack b (Credential 'Staking)
forall a b. (MemPack a, Buffer b) => Unpack b a
forall b. Buffer b => Unpack b (Credential 'Staking)
unpackM Unpack b (Addr28Extra -> CompactForm Coin -> AlonzoTxOut era)
-> Unpack b Addr28Extra
-> Unpack b (CompactForm Coin -> AlonzoTxOut era)
forall a b. Unpack b (a -> b) -> Unpack b a -> Unpack b b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Unpack b Addr28Extra
forall a b. (MemPack a, Buffer b) => Unpack b a
forall b. Buffer b => Unpack b Addr28Extra
unpackM Unpack b (CompactForm Coin -> AlonzoTxOut era)
-> Unpack b (CompactForm Coin) -> Unpack b (AlonzoTxOut era)
forall a b. Unpack b (a -> b) -> Unpack b a -> Unpack b b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Unpack b (CompactForm Coin)
forall a b. (MemPack a, Buffer b) => Unpack b a
forall b. Buffer b => Unpack b (CompactForm Coin)
unpackM
      Tag
3 -> Credential 'Staking
-> Addr28Extra -> CompactForm Coin -> DataHash32 -> AlonzoTxOut era
forall era.
Credential 'Staking
-> Addr28Extra -> CompactForm Coin -> DataHash32 -> AlonzoTxOut era
TxOut_AddrHash28_AdaOnly_DataHash32 (Credential 'Staking
 -> Addr28Extra
 -> CompactForm Coin
 -> DataHash32
 -> AlonzoTxOut era)
-> Unpack b (Credential 'Staking)
-> Unpack
     b
     (Addr28Extra -> CompactForm Coin -> DataHash32 -> AlonzoTxOut era)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Unpack b (Credential 'Staking)
forall a b. (MemPack a, Buffer b) => Unpack b a
forall b. Buffer b => Unpack b (Credential 'Staking)
unpackM Unpack
  b
  (Addr28Extra -> CompactForm Coin -> DataHash32 -> AlonzoTxOut era)
-> Unpack b Addr28Extra
-> Unpack b (CompactForm Coin -> DataHash32 -> AlonzoTxOut era)
forall a b. Unpack b (a -> b) -> Unpack b a -> Unpack b b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Unpack b Addr28Extra
forall a b. (MemPack a, Buffer b) => Unpack b a
forall b. Buffer b => Unpack b Addr28Extra
unpackM Unpack b (CompactForm Coin -> DataHash32 -> AlonzoTxOut era)
-> Unpack b (CompactForm Coin)
-> Unpack b (DataHash32 -> AlonzoTxOut era)
forall a b. Unpack b (a -> b) -> Unpack b a -> Unpack b b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Unpack b (CompactForm Coin)
forall a b. (MemPack a, Buffer b) => Unpack b a
forall b. Buffer b => Unpack b (CompactForm Coin)
unpackM Unpack b (DataHash32 -> AlonzoTxOut era)
-> Unpack b DataHash32 -> Unpack b (AlonzoTxOut era)
forall a b. Unpack b (a -> b) -> Unpack b a -> Unpack b b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Unpack b DataHash32
forall a b. (MemPack a, Buffer b) => Unpack b a
forall b. Buffer b => Unpack b DataHash32
unpackM
      Tag
n -> forall a (m :: * -> *) b. (MemPack a, MonadFail m) => Tag -> m b
unknownTagM @(AlonzoTxOut era) Tag
n
  {-# INLINE unpackM #-}

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 = AlonzoTxOut era -> ()
forall a. a -> ()
rwhnf

decodeDataHash32 ::
  DataHash32 ->
  DataHash
decodeDataHash32 :: DataHash32 -> DataHash
decodeDataHash32 (DataHash32 Word64
a Word64
b Word64
c Word64
d) = do
  Hash HASH EraIndependentData -> DataHash
forall i. Hash HASH i -> SafeHash i
unsafeMakeSafeHash (Hash HASH EraIndependentData -> DataHash)
-> Hash HASH EraIndependentData -> DataHash
forall a b. (a -> b) -> a -> b
$ PackedBytes (SizeHash HASH) -> Hash HASH EraIndependentData
forall h a. PackedBytes (SizeHash h) -> Hash h a
hashFromPackedBytes (PackedBytes (SizeHash HASH) -> Hash HASH EraIndependentData)
-> PackedBytes (SizeHash HASH) -> Hash HASH EraIndependentData
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, StrictMaybe DataHash
forall a. StrictMaybe a
SNothing)
  TxOutCompactDH' CompactAddr
addr CompactForm (Value era)
val DataHash
dh -> (CompactAddr
addr, CompactForm (Value era)
val, DataHash -> StrictMaybe DataHash
forall a. a -> StrictMaybe a
SJust DataHash
dh)
  TxOut_AddrHash28_AdaOnly Credential 'Staking
stakeRef Addr28Extra
addr28Extra CompactForm Coin
adaVal ->
    let
      addr :: Addr
addr = Credential 'Staking -> Addr28Extra -> Addr
decodeAddress28 Credential 'Staking
stakeRef Addr28Extra
addr28Extra
     in
      (Addr -> CompactAddr
compactAddr Addr
addr, CompactForm Coin -> CompactForm (Value era)
forall t. Val t => CompactForm Coin -> CompactForm t
injectCompact CompactForm Coin
adaVal, StrictMaybe DataHash
forall a. StrictMaybe a
SNothing)
  TxOut_AddrHash28_AdaOnly_DataHash32 Credential 'Staking
stakeRef Addr28Extra
addr28Extra CompactForm Coin
adaVal DataHash32
dataHash32 ->
    let
      addr :: Addr
addr = Credential 'Staking -> Addr28Extra -> Addr
decodeAddress28 Credential 'Staking
stakeRef Addr28Extra
addr28Extra
      dh :: DataHash
dh = DataHash32 -> DataHash
decodeDataHash32 DataHash32
dataHash32
     in
      (Addr -> CompactAddr
compactAddr Addr
addr, CompactForm Coin -> CompactForm (Value era)
forall t. Val t => CompactForm Coin -> CompactForm t
injectCompact CompactForm Coin
adaVal, DataHash -> StrictMaybe DataHash
forall a. a -> StrictMaybe a
SJust DataHash
dh)

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, StrictMaybe DataHash
forall a. StrictMaybe a
SNothing)
  where
    addr :: Addr
addr = HasCallStack => CompactAddr -> Addr
CompactAddr -> Addr
decompactAddr CompactAddr
bs
    val :: Value era
val = CompactForm (Value era) -> Value era
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, DataHash -> StrictMaybe DataHash
forall a. a -> StrictMaybe a
SJust DataHash
dh)
  where
    addr :: Addr
addr = HasCallStack => CompactAddr -> Addr
CompactAddr -> Addr
decompactAddr CompactAddr
bs
    val :: Value era
val = CompactForm (Value era) -> Value era
forall a. Compactible a => CompactForm a -> a
fromCompact CompactForm (Value era)
c
viewTxOut (TxOut_AddrHash28_AdaOnly Credential 'Staking
stakeRef Addr28Extra
addr28Extra CompactForm Coin
adaVal) =
  let addr :: Addr
addr = Credential 'Staking -> Addr28Extra -> Addr
decodeAddress28 Credential 'Staking
stakeRef Addr28Extra
addr28Extra
   in (Addr
addr, Coin -> Value era
forall t s. Inject t s => t -> s
inject (CompactForm Coin -> Coin
forall a. Compactible a => CompactForm a -> a
fromCompact CompactForm Coin
adaVal), StrictMaybe DataHash
forall a. StrictMaybe a
SNothing)
viewTxOut (TxOut_AddrHash28_AdaOnly_DataHash32 Credential 'Staking
stakeRef Addr28Extra
addr28Extra CompactForm Coin
adaVal DataHash32
dataHash32) =
  let
    addr :: Addr
addr = Credential 'Staking -> Addr28Extra -> Addr
decodeAddress28 Credential 'Staking
stakeRef Addr28Extra
addr28Extra
    dh :: DataHash
dh = DataHash32 -> DataHash
decodeDataHash32 DataHash32
dataHash32
   in
    (Addr
addr, Coin -> Value era
forall t s. Inject t s => t -> s
inject (CompactForm Coin -> Coin
forall a. Compactible a => CompactForm a -> a
fromCompact CompactForm Coin
adaVal), DataHash -> StrictMaybe DataHash
forall a. a -> StrictMaybe a
SJust DataHash
dh)

instance (Era era, Val (Value era)) => Show (AlonzoTxOut era) where
  show :: AlonzoTxOut era -> [Char]
show = (Addr, Value era, StrictMaybe DataHash) -> [Char]
forall a. Show a => a -> [Char]
show ((Addr, Value era, StrictMaybe DataHash) -> [Char])
-> (AlonzoTxOut era -> (Addr, Value era, StrictMaybe DataHash))
-> AlonzoTxOut era
-> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AlonzoTxOut era -> (Addr, Value era, StrictMaybe DataHash)
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 ->
  Addr28Extra
encodeAddress28 :: Network -> Credential 'Payment -> Addr28Extra
encodeAddress28 Network
network Credential 'Payment
paymentCred = do
  let networkBit, payCredTypeBit :: Word64
      networkBit :: Word64
networkBit =
        case Network
network of
          Network
Mainnet -> Word64
0 Word64 -> Int -> Word64
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 Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`setBit` Int
0
          ScriptHashObj {} -> Word64
0
      encodeAddr ::
        Hash ADDRHASH a ->
        Addr28Extra
      encodeAddr :: forall a. Hash ADDRHASH a -> Addr28Extra
encodeAddr Hash ADDRHASH a
h = do
        case Hash ADDRHASH a -> PackedBytes (SizeHash ADDRHASH)
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' = (Word32 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
d Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftL` Int
32) Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. Word64
networkBit Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. Word64
payCredTypeBit
             in Word64 -> Word64 -> Word64 -> Word64 -> Addr28Extra
Addr28Extra Word64
a Word64
b Word64
c Word64
d'
          PackedBytes (SizeHash ADDRHASH)
_ -> [Char] -> Addr28Extra
forall a. HasCallStack => [Char] -> a
error [Char]
"Incorrectly constructed PackedBytes"
  case Credential 'Payment
paymentCred of
    KeyHashObj (KeyHash Hash ADDRHASH (VerKeyDSIGN DSIGN)
addrHash) -> Hash ADDRHASH (VerKeyDSIGN DSIGN) -> Addr28Extra
forall a. Hash ADDRHASH a -> Addr28Extra
encodeAddr Hash ADDRHASH (VerKeyDSIGN DSIGN)
addrHash
    ScriptHashObj (ScriptHash Hash ADDRHASH EraIndependentScript
addrHash) -> Hash ADDRHASH EraIndependentScript -> Addr28Extra
forall a. Hash ADDRHASH a -> Addr28Extra
encodeAddr Hash ADDRHASH EraIndependentScript
addrHash

encodeDataHash32 ::
  DataHash ->
  DataHash32
encodeDataHash32 :: DataHash -> DataHash32
encodeDataHash32 DataHash
dataHash = do
  case Hash HASH EraIndependentData -> PackedBytes (SizeHash HASH)
forall h a. Hash h a -> PackedBytes (SizeHash h)
hashToPackedBytes (DataHash -> Hash HASH EraIndependentData
forall i. SafeHash i -> Hash HASH i
extractHash DataHash
dataHash) of
    PackedBytes32 Word64
a Word64
b Word64
c Word64
d -> Word64 -> Word64 -> Word64 -> Word64 -> DataHash32
DataHash32 Word64
a Word64
b Word64
c Word64
d
    PackedBytes (SizeHash HASH)
_ -> [Char] -> DataHash32
forall a. HasCallStack => [Char] -> a
error [Char]
"Incorrectly constructed PackedBytes"

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
  Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> Maybe ()) -> Bool -> Maybe ()
forall a b. (a -> b) -> a -> b
$ Value era -> Bool
forall t. Val t => t -> Bool
isAdaOnly Value era
v
  Coin -> Maybe (CompactForm Coin)
forall a. Compactible a => a -> Maybe (CompactForm a)
toCompact (Coin -> Maybe (CompactForm Coin))
-> Coin -> Maybe (CompactForm Coin)
forall a b. (a -> b) -> a -> b
$ Value era -> Coin
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 $mAlonzoTxOut :: forall {r} {era}.
(Era era, Val (Value era), HasCallStack) =>
AlonzoTxOut era
-> (Addr -> Value era -> StrictMaybe DataHash -> r)
-> ((# #) -> r)
-> r
$bAlonzoTxOut :: forall era.
(Era era, Val (Value era), HasCallStack) =>
Addr -> Value era -> StrictMaybe DataHash -> AlonzoTxOut era
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 <- Proxy era -> Value era -> Maybe (CompactForm Coin)
forall era.
Val (Value era) =>
Proxy era -> Value era -> Maybe (CompactForm Coin)
getAdaOnly (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @era) Value era
vl =
          let addr28Extra :: Addr28Extra
addr28Extra = Network -> Credential 'Payment -> Addr28Extra
encodeAddress28 Network
network Credential 'Payment
paymentCred
           in Credential 'Staking
-> Addr28Extra -> CompactForm Coin -> AlonzoTxOut era
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 <- Proxy era -> Value era -> Maybe (CompactForm Coin)
forall era.
Val (Value era) =>
Proxy era -> Value era -> Maybe (CompactForm Coin)
getAdaOnly (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @era) Value era
vl =
          let
            addr28Extra :: Addr28Extra
addr28Extra = Network -> Credential 'Payment -> Addr28Extra
encodeAddress28 Network
network Credential 'Payment
paymentCred
            dataHash32 :: DataHash32
dataHash32 = DataHash -> DataHash32
encodeDataHash32 DataHash
dh
           in
            Credential 'Staking
-> Addr28Extra -> CompactForm Coin -> DataHash32 -> AlonzoTxOut era
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 = CompactForm (Value era)
-> Maybe (CompactForm (Value era)) -> CompactForm (Value era)
forall a. a -> Maybe a -> a
fromMaybe ([Char] -> CompactForm (Value era)
forall a. HasCallStack => [Char] -> a
error ([Char] -> CompactForm (Value era))
-> [Char] -> CompactForm (Value era)
forall a b. (a -> b) -> a -> b
$ [Char]
"Illegal value in TxOut: " [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ Value era -> [Char]
forall a. Show a => a -> [Char]
show Value era
vl) (Maybe (CompactForm (Value era)) -> CompactForm (Value era))
-> Maybe (CompactForm (Value era)) -> CompactForm (Value era)
forall a b. (a -> b) -> a -> b
$ Value era -> Maybe (CompactForm (Value era))
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 -> CompactAddr -> CompactForm (Value era) -> AlonzoTxOut era
forall era.
CompactAddr -> CompactForm (Value era) -> AlonzoTxOut era
TxOutCompact' CompactAddr
a CompactForm (Value era)
v
            SJust DataHash
dh -> CompactAddr
-> CompactForm (Value era) -> DataHash -> AlonzoTxOut era
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 = Addr
-> Value AlonzoEra -> StrictMaybe DataHash -> AlonzoTxOut AlonzoEra
forall era.
(Era era, Val (Value era), HasCallStack) =>
Addr -> Value era -> StrictMaybe DataHash -> AlonzoTxOut era
AlonzoTxOut Addr
addr Value AlonzoEra
vl StrictMaybe DataHash
forall a. StrictMaybe a
SNothing

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

  addrEitherTxOutL :: Lens' (TxOut AlonzoEra) (Either Addr CompactAddr)
addrEitherTxOutL =
    (AlonzoTxOut AlonzoEra -> Either Addr CompactAddr)
-> (AlonzoTxOut AlonzoEra
    -> Either Addr CompactAddr -> AlonzoTxOut AlonzoEra)
-> Lens
     (AlonzoTxOut AlonzoEra)
     (AlonzoTxOut AlonzoEra)
     (Either Addr CompactAddr)
     (Either Addr CompactAddr)
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens
      AlonzoTxOut AlonzoEra -> Either Addr CompactAddr
forall era. AlonzoTxOut era -> Either Addr CompactAddr
getAlonzoTxOutEitherAddr
      ( \AlonzoTxOut AlonzoEra
txOut Either Addr CompactAddr
eAddr ->
          let cVal :: CompactForm (Value AlonzoEra)
cVal = AlonzoTxOut AlonzoEra -> CompactForm (Value AlonzoEra)
forall era.
EraTxOut era =>
AlonzoTxOut era -> CompactForm (Value era)
getTxOutCompactValue AlonzoTxOut AlonzoEra
txOut
              (Addr
_, Value AlonzoEra
_, StrictMaybe DataHash
dh) = AlonzoTxOut AlonzoEra
-> (Addr, Value AlonzoEra, StrictMaybe DataHash)
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 -> Addr
-> CompactAddr
-> CompactForm (Value AlonzoEra)
-> StrictMaybe DataHash
-> AlonzoTxOut AlonzoEra
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 -> Addr
-> CompactAddr
-> CompactForm (Value AlonzoEra)
-> StrictMaybe DataHash
-> AlonzoTxOut AlonzoEra
forall era.
(Era era, HasCallStack, Val (Value era)) =>
Addr
-> CompactAddr
-> CompactForm (Value era)
-> StrictMaybe DataHash
-> AlonzoTxOut era
mkTxOutCompact (HasCallStack => CompactAddr -> Addr
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 =
    (AlonzoTxOut AlonzoEra -> Either MaryValue (CompactForm MaryValue))
-> (AlonzoTxOut AlonzoEra
    -> Either MaryValue (CompactForm MaryValue)
    -> AlonzoTxOut AlonzoEra)
-> Lens
     (AlonzoTxOut AlonzoEra)
     (AlonzoTxOut AlonzoEra)
     (Either MaryValue (CompactForm MaryValue))
     (Either MaryValue (CompactForm MaryValue))
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens
      (CompactForm MaryValue -> Either MaryValue (CompactForm MaryValue)
forall a b. b -> Either a b
Right (CompactForm MaryValue -> Either MaryValue (CompactForm MaryValue))
-> (AlonzoTxOut AlonzoEra -> CompactForm MaryValue)
-> AlonzoTxOut AlonzoEra
-> Either MaryValue (CompactForm MaryValue)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AlonzoTxOut AlonzoEra -> CompactForm (Value AlonzoEra)
AlonzoTxOut AlonzoEra -> CompactForm MaryValue
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) = AlonzoTxOut AlonzoEra
-> (Addr, Value AlonzoEra, StrictMaybe DataHash)
forall era.
Val (Value era) =>
AlonzoTxOut era -> (Addr, Value era, StrictMaybe DataHash)
viewTxOut AlonzoTxOut AlonzoEra
txOut
               in Addr
-> Value AlonzoEra -> StrictMaybe DataHash -> AlonzoTxOut AlonzoEra
forall era.
(Era era, Val (Value era), HasCallStack) =>
Addr -> Value era -> StrictMaybe DataHash -> AlonzoTxOut era
AlonzoTxOut Addr
addr Value AlonzoEra
MaryValue
val StrictMaybe DataHash
dh
            Right CompactForm MaryValue
cVal ->
              let dh :: StrictMaybe DataHash
dh = AlonzoTxOut AlonzoEra -> StrictMaybe DataHash
forall era. AlonzoTxOut era -> StrictMaybe DataHash
getAlonzoTxOutDataHash AlonzoTxOut AlonzoEra
txOut
               in case AlonzoTxOut AlonzoEra -> Either Addr CompactAddr
forall era. AlonzoTxOut era -> Either Addr CompactAddr
getAlonzoTxOutEitherAddr AlonzoTxOut AlonzoEra
txOut of
                    Left Addr
addr -> Addr
-> CompactAddr
-> CompactForm (Value AlonzoEra)
-> StrictMaybe DataHash
-> AlonzoTxOut AlonzoEra
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)
CompactForm MaryValue
cVal StrictMaybe DataHash
dh
                    Right CompactAddr
cAddr -> Addr
-> CompactAddr
-> CompactForm (Value AlonzoEra)
-> StrictMaybe DataHash
-> AlonzoTxOut AlonzoEra
forall era.
(Era era, HasCallStack, Val (Value era)) =>
Addr
-> CompactAddr
-> CompactForm (Value era)
-> StrictMaybe DataHash
-> AlonzoTxOut era
mkTxOutCompact (HasCallStack => CompactAddr -> Addr
CompactAddr -> Addr
decompactAddr CompactAddr
cAddr) CompactAddr
cAddr CompactForm (Value AlonzoEra)
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 PParams AlonzoEra
-> Getting CoinPerWord (PParams AlonzoEra) CoinPerWord
-> CoinPerWord
forall s a. s -> Getting a s a -> a
^. Getting CoinPerWord (PParams AlonzoEra) CoinPerWord
forall era.
(AlonzoEraPParams era, ExactEra AlonzoEra era) =>
Lens' (PParams era) CoinPerWord
Lens' (PParams AlonzoEra) CoinPerWord
ppCoinsPerUTxOWordL of
      CoinPerWord (Coin Integer
cpw) -> Integer -> Coin
Coin (Integer -> Coin) -> Integer -> Coin
forall a b. (a -> b) -> a -> b
$ TxOut AlonzoEra -> Integer
forall era. AlonzoEraTxOut era => TxOut era -> Integer
utxoEntrySize TxOut AlonzoEra
txOut Integer -> Integer -> Integer
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
      Encoding -> Encoding -> Encoding
forall a. Semigroup a => a -> a -> a
<> CompactAddr -> Encoding
forall a. EncCBOR a => a -> Encoding
encCBOR CompactAddr
addr
      Encoding -> Encoding -> Encoding
forall a. Semigroup a => a -> a -> a
<> CompactForm (Value era) -> Encoding
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
      Encoding -> Encoding -> Encoding
forall a. Semigroup a => a -> a -> a
<> CompactAddr -> Encoding
forall a. EncCBOR a => a -> Encoding
encCBOR CompactAddr
addr
      Encoding -> Encoding -> Encoding
forall a. Semigroup a => a -> a -> a
<> CompactForm (Value era) -> Encoding
forall a. EncCBOR a => a -> Encoding
encCBOR CompactForm (Value era)
cv
      Encoding -> Encoding -> Encoding
forall a. Semigroup a => a -> a -> a
<> DataHash -> Encoding
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 <- Decoder s (Maybe Int)
forall s. Decoder s (Maybe Int)
decodeListLenOrIndef
    case Maybe Int
lenOrIndef of
      Maybe Int
Nothing -> do
        (Addr
a, CompactAddr
ca) <- Decoder s (Addr, CompactAddr)
forall s. Decoder s (Addr, CompactAddr)
fromCborBothAddr
        CompactForm (Value era)
cv <- Decoder s (CompactForm (Value era))
forall s. Decoder s (CompactForm (Value era))
forall a s. DecCBOR a => Decoder s a
decCBOR
        Decoder s Bool
forall s. Decoder s Bool
decodeBreakOr Decoder s Bool
-> (Bool -> Decoder s (AlonzoTxOut era))
-> Decoder s (AlonzoTxOut era)
forall a b. Decoder s a -> (a -> Decoder s b) -> Decoder s b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
          Bool
True -> AlonzoTxOut era -> Decoder s (AlonzoTxOut era)
forall a. a -> Decoder s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (AlonzoTxOut era -> Decoder s (AlonzoTxOut era))
-> AlonzoTxOut era -> Decoder s (AlonzoTxOut era)
forall a b. (a -> b) -> a -> b
$ Addr
-> CompactAddr
-> CompactForm (Value era)
-> StrictMaybe DataHash
-> AlonzoTxOut era
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 StrictMaybe DataHash
forall a. StrictMaybe a
SNothing
          Bool
False -> do
            DataHash
dh <- Decoder s DataHash
forall s. Decoder s DataHash
forall a s. DecCBOR a => Decoder s a
decCBOR
            Decoder s Bool
forall s. Decoder s Bool
decodeBreakOr Decoder s Bool
-> (Bool -> Decoder s (AlonzoTxOut era))
-> Decoder s (AlonzoTxOut era)
forall a b. Decoder s a -> (a -> Decoder s b) -> Decoder s b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
              Bool
True -> AlonzoTxOut era -> Decoder s (AlonzoTxOut era)
forall a. a -> Decoder s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (AlonzoTxOut era -> Decoder s (AlonzoTxOut era))
-> AlonzoTxOut era -> Decoder s (AlonzoTxOut era)
forall a b. (a -> b) -> a -> b
$ Addr
-> CompactAddr
-> CompactForm (Value era)
-> StrictMaybe DataHash
-> AlonzoTxOut era
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 (DataHash -> StrictMaybe DataHash
forall a. a -> StrictMaybe a
SJust DataHash
dh)
              Bool
False -> DecoderError -> Decoder s (AlonzoTxOut era)
forall (m :: * -> *) e a. (MonadFail m, Buildable e) => e -> m a
cborError (DecoderError -> Decoder s (AlonzoTxOut era))
-> DecoderError -> Decoder s (AlonzoTxOut era)
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) <- Decoder s (Addr, CompactAddr)
forall s. Decoder s (Addr, CompactAddr)
fromCborBothAddr
        CompactForm (Value era)
cv <- Decoder s (CompactForm (Value era))
forall s. Decoder s (CompactForm (Value era))
forall a s. DecCBOR a => Decoder s a
decCBOR
        AlonzoTxOut era -> Decoder s (AlonzoTxOut era)
forall a. a -> Decoder s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (AlonzoTxOut era -> Decoder s (AlonzoTxOut era))
-> AlonzoTxOut era -> Decoder s (AlonzoTxOut era)
forall a b. (a -> b) -> a -> b
$ Addr
-> CompactAddr
-> CompactForm (Value era)
-> StrictMaybe DataHash
-> AlonzoTxOut era
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 StrictMaybe DataHash
forall a. StrictMaybe a
SNothing
      Just Int
3 -> do
        (Addr
a, CompactAddr
ca) <- Decoder s (Addr, CompactAddr)
forall s. Decoder s (Addr, CompactAddr)
fromCborBothAddr
        CompactForm (Value era)
cv <- Decoder s (CompactForm (Value era))
forall s. Decoder s (CompactForm (Value era))
forall a s. DecCBOR a => Decoder s a
decCBOR
        Addr
-> CompactAddr
-> CompactForm (Value era)
-> StrictMaybe DataHash
-> AlonzoTxOut era
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 (StrictMaybe DataHash -> AlonzoTxOut era)
-> (DataHash -> StrictMaybe DataHash)
-> DataHash
-> AlonzoTxOut era
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DataHash -> StrictMaybe DataHash
forall a. a -> StrictMaybe a
SJust (DataHash -> AlonzoTxOut era)
-> Decoder s DataHash -> Decoder s (AlonzoTxOut era)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Decoder s DataHash
forall s. Decoder s DataHash
forall a s. DecCBOR a => Decoder s a
decCBOR
      Just Int
_ -> DecoderError -> Decoder s (AlonzoTxOut era)
forall (m :: * -> *) e a. (MonadFail m, Buildable e) => e -> m a
cborError (DecoderError -> Decoder s (AlonzoTxOut era))
-> DecoderError -> Decoder s (AlonzoTxOut era)
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), MemPack (CompactForm (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
    AlonzoTxOut era
txOut <-
      Decoder s TokenType
forall s. Decoder s TokenType
peekTokenType Decoder s TokenType
-> (TokenType -> Decoder s (AlonzoTxOut era))
-> Decoder s (AlonzoTxOut era)
forall a b. Decoder s a -> (a -> Decoder s b) -> Decoder s b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
        TokenType
TypeBytes -> Decoder s (AlonzoTxOut era)
forall a s. MemPack a => Decoder s a
decodeMemPack
        TokenType
TypeBytesIndef -> Decoder s (AlonzoTxOut era)
forall a s. MemPack a => Decoder s a
decodeMemPack
        TokenType
_ -> Decoder s (AlonzoTxOut era)
forall s. Decoder s (AlonzoTxOut era)
forall a s. DecCBOR a => Decoder s a
decCBOR
    AlonzoTxOut era -> Decoder s (AlonzoTxOut era)
forall a. a -> Decoder s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (AlonzoTxOut era -> Decoder s (AlonzoTxOut era))
-> AlonzoTxOut era -> Decoder s (AlonzoTxOut era)
forall a b. (a -> b) -> a -> b
$! (Credential 'Staking -> Credential 'Staking)
-> AlonzoTxOut era -> AlonzoTxOut era
forall era.
(Credential 'Staking -> Credential 'Staking)
-> AlonzoTxOut era -> AlonzoTxOut era
internAlonzoTxOut (Interns (Credential 'Staking)
-> Credential 'Staking -> Credential 'Staking
forall k. Interns k -> k -> k
interns Share (AlonzoTxOut era)
Interns (Credential 'Staking)
credsInterns) AlonzoTxOut era
txOut
  {-# 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 ->
    Credential 'Staking
-> Addr28Extra -> CompactForm Coin -> AlonzoTxOut era
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 ->
    Credential 'Staking
-> Addr28Extra -> CompactForm Coin -> DataHash32 -> AlonzoTxOut era
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" Key -> Value -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Addr -> Value
forall a. ToJSON a => a -> Value
toJSON Addr
addr
      , Key
"value" Key -> Value -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Value era -> Value
forall a. ToJSON a => a -> Value
toJSON Value era
v
      , Key
"datahash" Key -> Value -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= case StrictMaybe DataHash -> Maybe DataHash
forall a. StrictMaybe a -> Maybe a
strictMaybeToMaybe StrictMaybe DataHash
dataHash of
          Maybe DataHash
Nothing -> Value
Aeson.Null
          Just DataHash
dHash ->
            Text -> Value
Aeson.String (Text -> Value)
-> (Hash HASH EraIndependentData -> Text)
-> Hash HASH EraIndependentData
-> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Hash HASH EraIndependentData -> Text
forall h a. Hash h a -> Text
hashToTextAsHex (Hash HASH EraIndependentData -> Value)
-> Hash HASH EraIndependentData -> Value
forall a b. (a -> b) -> a -> b
$
              DataHash -> Hash HASH EraIndependentData
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 $mTxOutCompact :: forall {r} {era}.
(Era era, Val (Value era), HasCallStack) =>
AlonzoTxOut era
-> (CompactAddr -> CompactForm (Value era) -> r)
-> ((# #) -> r)
-> r
$bTxOutCompact :: forall era.
(Era era, Val (Value era), HasCallStack) =>
CompactAddr -> CompactForm (Value era) -> AlonzoTxOut era
TxOutCompact addr vl <-
  (viewCompactTxOut -> (addr, vl, SNothing))
  where
    TxOutCompact CompactAddr
cAddr CompactForm (Value era)
cVal = Addr
-> CompactAddr
-> CompactForm (Value era)
-> StrictMaybe DataHash
-> AlonzoTxOut era
forall era.
(Era era, HasCallStack, Val (Value era)) =>
Addr
-> CompactAddr
-> CompactForm (Value era)
-> StrictMaybe DataHash
-> AlonzoTxOut era
mkTxOutCompact (HasCallStack => CompactAddr -> Addr
CompactAddr -> Addr
decompactAddr CompactAddr
cAddr) CompactAddr
cAddr CompactForm (Value era)
cVal StrictMaybe DataHash
forall a. StrictMaybe a
SNothing

pattern TxOutCompactDH ::
  (Era era, Val (Value era), HasCallStack) =>
  CompactAddr ->
  CompactForm (Value era) ->
  DataHash ->
  AlonzoTxOut era
pattern $mTxOutCompactDH :: forall {r} {era}.
(Era era, Val (Value era), HasCallStack) =>
AlonzoTxOut era
-> (CompactAddr -> CompactForm (Value era) -> DataHash -> r)
-> ((# #) -> r)
-> r
$bTxOutCompactDH :: forall era.
(Era era, Val (Value era), HasCallStack) =>
CompactAddr
-> CompactForm (Value era) -> DataHash -> AlonzoTxOut era
TxOutCompactDH addr vl dh <-
  (viewCompactTxOut -> (addr, vl, SJust dh))
  where
    TxOutCompactDH CompactAddr
cAddr CompactForm (Value era)
cVal DataHash
dh = Addr
-> CompactAddr
-> CompactForm (Value era)
-> StrictMaybe DataHash
-> AlonzoTxOut era
forall era.
(Era era, HasCallStack, Val (Value era)) =>
Addr
-> CompactAddr
-> CompactForm (Value era)
-> StrictMaybe DataHash
-> AlonzoTxOut era
mkTxOutCompact (HasCallStack => CompactAddr -> Addr
CompactAddr -> Addr
decompactAddr CompactAddr
cAddr) CompactAddr
cAddr CompactForm (Value era)
cVal (DataHash -> StrictMaybe DataHash
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
  | CompactForm (Value era) -> Bool
forall t. Val t => CompactForm t -> Bool
isAdaOnlyCompact CompactForm (Value era)
cVal = Addr -> Value era -> StrictMaybe DataHash -> AlonzoTxOut era
forall era.
(Era era, Val (Value era), HasCallStack) =>
Addr -> Value era -> StrictMaybe DataHash -> AlonzoTxOut era
AlonzoTxOut Addr
addr (CompactForm (Value era) -> Value era
forall a. Compactible a => CompactForm a -> a
fromCompact CompactForm (Value era)
cVal) StrictMaybe DataHash
mdh
  | SJust DataHash
dh <- StrictMaybe DataHash
mdh = CompactAddr
-> CompactForm (Value era) -> DataHash -> AlonzoTxOut era
forall era.
CompactAddr
-> CompactForm (Value era) -> DataHash -> AlonzoTxOut era
TxOutCompactDH' CompactAddr
cAddr CompactForm (Value era)
cVal DataHash
dh
  | Bool
otherwise = CompactAddr -> CompactForm (Value era) -> AlonzoTxOut era
forall era.
CompactAddr -> CompactForm (Value era) -> AlonzoTxOut era
TxOutCompact' CompactAddr
cAddr CompactForm (Value era)
cVal

getAlonzoTxOutDataHash ::
  forall era.
  AlonzoTxOut era ->
  StrictMaybe DataHash
getAlonzoTxOutDataHash :: forall era. AlonzoTxOut era -> StrictMaybe DataHash
getAlonzoTxOutDataHash = \case
  TxOutCompactDH' CompactAddr
_ CompactForm (Value era)
_ DataHash
dh -> DataHash -> StrictMaybe DataHash
forall a. a -> StrictMaybe a
SJust DataHash
dh
  TxOut_AddrHash28_AdaOnly_DataHash32 Credential 'Staking
_ Addr28Extra
_ CompactForm Coin
_ DataHash32
dh ->
    DataHash -> StrictMaybe DataHash
forall a. a -> StrictMaybe a
SJust (DataHash -> StrictMaybe DataHash)
-> DataHash -> StrictMaybe DataHash
forall a b. (a -> b) -> a -> b
$ DataHash32 -> DataHash
decodeDataHash32 DataHash32
dh
  AlonzoTxOut era
_ -> StrictMaybe DataHash
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)
_ -> CompactAddr -> Either Addr CompactAddr
forall a b. b -> Either a b
Right CompactAddr
cAddr
  TxOutCompactDH' CompactAddr
cAddr CompactForm (Value era)
_ DataHash
_ -> CompactAddr -> Either Addr CompactAddr
forall a b. b -> Either a b
Right CompactAddr
cAddr
  TxOut_AddrHash28_AdaOnly Credential 'Staking
stakeRef Addr28Extra
addr28Extra CompactForm Coin
_ ->
    Addr -> Either Addr CompactAddr
forall a b. a -> Either a b
Left (Addr -> Either Addr CompactAddr)
-> Addr -> Either Addr CompactAddr
forall a b. (a -> b) -> a -> b
$ Credential 'Staking -> Addr28Extra -> Addr
decodeAddress28 Credential 'Staking
stakeRef Addr28Extra
addr28Extra
  TxOut_AddrHash28_AdaOnly_DataHash32 Credential 'Staking
stakeRef Addr28Extra
addr28Extra CompactForm Coin
_ DataHash32
_ ->
    Addr -> Either Addr CompactAddr
forall a b. a -> Either a b
Left (Addr -> Either Addr CompactAddr)
-> Addr -> Either Addr CompactAddr
forall a b. (a -> b) -> a -> b
$ Credential 'Staking -> Addr28Extra -> Addr
decodeAddress28 Credential 'Staking
stakeRef Addr28Extra
addr28Extra

-- | 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 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Value era -> Integer
forall t. Val t => t -> Integer
size Value era
v Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ StrictMaybe DataHash -> Integer
dataHashSize StrictMaybe DataHash
dh
  where
    v :: Value era
v = TxOut era
txOut 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
    dh :: StrictMaybe DataHash
dh = TxOut era
txOut TxOut era
-> Getting
     (StrictMaybe DataHash) (TxOut era) (StrictMaybe DataHash)
-> StrictMaybe DataHash
forall s a. s -> Getting a s a -> a
^. Getting (StrictMaybe DataHash) (TxOut era) (StrictMaybe DataHash)
forall era.
AlonzoEraTxOut era =>
Lens' (TxOut era) (StrictMaybe DataHash)
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 =
    (AlonzoTxOut AlonzoEra -> StrictMaybe DataHash)
-> (AlonzoTxOut AlonzoEra
    -> StrictMaybe DataHash -> AlonzoTxOut AlonzoEra)
-> Lens
     (AlonzoTxOut AlonzoEra)
     (AlonzoTxOut AlonzoEra)
     (StrictMaybe DataHash)
     (StrictMaybe DataHash)
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens AlonzoTxOut AlonzoEra -> StrictMaybe DataHash
forall era. AlonzoTxOut era -> StrictMaybe DataHash
getAlonzoTxOutDataHash (\(AlonzoTxOut Addr
addr Value AlonzoEra
cv StrictMaybe DataHash
_) StrictMaybe DataHash
dh -> Addr
-> Value AlonzoEra -> StrictMaybe DataHash -> AlonzoTxOut AlonzoEra
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 = (TxOut AlonzoEra -> Datum AlonzoEra)
-> SimpleGetter (TxOut AlonzoEra) (Datum AlonzoEra)
forall s a. (s -> a) -> SimpleGetter s a
to ((TxOut AlonzoEra -> Datum AlonzoEra)
 -> SimpleGetter (TxOut AlonzoEra) (Datum AlonzoEra))
-> (TxOut AlonzoEra -> Datum AlonzoEra)
-> SimpleGetter (TxOut AlonzoEra) (Datum AlonzoEra)
forall a b. (a -> b) -> a -> b
$ \TxOut AlonzoEra
txOut ->
    case AlonzoTxOut AlonzoEra -> StrictMaybe DataHash
forall era. AlonzoTxOut era -> StrictMaybe DataHash
getAlonzoTxOutDataHash TxOut AlonzoEra
AlonzoTxOut AlonzoEra
txOut of
      StrictMaybe DataHash
SNothing -> Datum AlonzoEra
forall era. Datum era
NoDatum
      SJust DataHash
dh -> DataHash -> Datum AlonzoEra
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 -> CompactForm Coin -> CompactForm (Value era)
forall t. Val t => CompactForm Coin -> CompactForm t
injectCompact CompactForm Coin
cc
    TxOut_AddrHash28_AdaOnly_DataHash32 Credential 'Staking
_ Addr28Extra
_ CompactForm Coin
cc DataHash32
_ -> CompactForm Coin -> CompactForm (Value era)
forall t. Val t => CompactForm Coin -> CompactForm t
injectCompact CompactForm Coin
cc