{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE BinaryLiterals #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeSynonymInstances #-}

module Cardano.Ledger.Address (
  serialiseAddr,
  Addr (..),
  addrPtrNormalize,
  BootstrapAddress (..),
  bootstrapAddressAttrsSize,
  isBootstrapRedeemer,
  getNetwork,
  RewardAccount (..),
  rewardAccountCredentialL,
  rewardAccountNetworkL,
  serialiseRewardAccount,
  deserialiseRewardAccount,
  bootstrapKeyHash,
  -- internals exported for testing
  putAddr,
  putCredential,
  putPtr,
  putRewardAccount,
  putVariableLengthWord64,
  Word7 (..),
  toWord7,

  -- * Compact Address
  fromBoostrapCompactAddress,
  compactAddr,
  decompactAddr,
  CompactAddr,
  unCompactAddr,
  isPayCredScriptCompactAddr,
  isBootstrapCompactAddr,
  decodeAddr,
  decodeAddrEither,
  decodeAddrStateT,
  decodeAddrStateLenientT,
  fromCborAddr,
  fromCborBothAddr,
  fromCborCompactAddr,
  fromCborRigorousBothAddr,
  fromCborBackwardsBothAddr,
  decodeRewardAccount,
  fromCborRewardAccount,
  Withdrawals (..),
) where

import qualified Cardano.Chain.Common as Byron
import qualified Cardano.Crypto.Hash.Class as Hash
import qualified Cardano.Crypto.Hashing as Byron
import Cardano.Ledger.BaseTypes (
  CertIx (..),
  Network (..),
  TxIx (..),
  byronProtVer,
  natVersion,
  networkToWord8,
 )
import Cardano.Ledger.Binary (
  DecCBOR (..),
  Decoder,
  EncCBOR (..),
  decodeFull',
  ifDecoderVersionAtLeast,
  serialize,
 )
import Cardano.Ledger.Coin (Coin)
import Cardano.Ledger.Credential (
  Credential (..),
  PaymentCredential,
  Ptr (..),
  SlotNo32 (..),
  StakeReference (..),
  mkPtrNormalized,
 )
import Cardano.Ledger.Hashes (ScriptHash (..))
import Cardano.Ledger.Keys (KeyHash (..), KeyRole (..))
import Control.DeepSeq (NFData)
import Control.Monad (guard, unless, when)
import Control.Monad.Trans.Fail (FailT (..), runFail)
import Control.Monad.Trans.State.Strict (StateT (..), evalStateT, get, modify', state)
import Data.Aeson (FromJSON (..), FromJSONKey (..), ToJSON (..), ToJSONKey (..), (.:), (.=))
import qualified Data.Aeson as Aeson
import qualified Data.Aeson.Encoding as Aeson
import qualified Data.Aeson.Key as Aeson (fromText)
import qualified Data.Aeson.Types as Aeson
import Data.Binary (Put)
import qualified Data.Binary as B
import qualified Data.Binary.Put as B
import Data.Bits (Bits (clearBit, setBit, shiftL, shiftR, testBit, (.&.), (.|.)))
import Data.ByteString (ByteString)
import qualified Data.ByteString as BS
import qualified Data.ByteString.Base16 as B16
import qualified Data.ByteString.Lazy as BSL
import Data.ByteString.Short as SBS (ShortByteString, fromShort, index, length, toShort)
import Data.ByteString.Short.Internal as SBS (unsafeIndex)
import qualified Data.ByteString.Unsafe as BS (unsafeDrop, unsafeIndex, unsafeTake)
import Data.Default (Default (..))
import Data.Function (fix)
import Data.Map.Strict (Map)
import Data.Maybe (fromMaybe)
import Data.MemPack (MemPack, Unpack (..))
import Data.Proxy (Proxy (..))
import Data.Text (Text)
import qualified Data.Text.Encoding as Text
import Data.Word (Word16, Word32, Word64, Word8)
import GHC.Generics (Generic)
import GHC.Show (intToDigit)
import GHC.Stack (HasCallStack)
import Lens.Micro
import NoThunks.Class (NoThunks (..))
import Numeric (showIntAtBase)
import Quiet (Quiet (Quiet))

-- | Serialise an address to the external format.
serialiseAddr :: Addr -> ByteString
serialiseAddr :: Addr -> ByteString
serialiseAddr = ByteString -> ByteString
BSL.toStrict (ByteString -> ByteString)
-> (Addr -> ByteString) -> Addr -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Put -> ByteString
B.runPut (Put -> ByteString) -> (Addr -> Put) -> Addr -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Addr -> Put
putAddr
{-# INLINE serialiseAddr #-}

-- | Serialise a reward account to the external format.
serialiseRewardAccount :: RewardAccount -> ByteString
serialiseRewardAccount :: RewardAccount -> ByteString
serialiseRewardAccount = ByteString -> ByteString
BSL.toStrict (ByteString -> ByteString)
-> (RewardAccount -> ByteString) -> RewardAccount -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Put -> ByteString
B.runPut (Put -> ByteString)
-> (RewardAccount -> Put) -> RewardAccount -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RewardAccount -> Put
putRewardAccount

-- | Deserialise a reward account from the external format. This will fail if the
-- input data is not in the right format (or if there is trailing data).
deserialiseRewardAccount :: ByteString -> Maybe RewardAccount
deserialiseRewardAccount :: ByteString -> Maybe RewardAccount
deserialiseRewardAccount = ByteString -> Maybe RewardAccount
forall b (m :: * -> *).
(AddressBuffer b, MonadFail m) =>
b -> m RewardAccount
decodeRewardAccount

-- | An address for UTxO.
--
-- Contents of Addr data type are intentionally left as lazy, otherwise
-- operating on compact form of an address will result in redundant work.
data Addr
  = Addr Network PaymentCredential StakeReference
  | AddrBootstrap BootstrapAddress
  deriving (Int -> Addr -> ShowS
[Addr] -> ShowS
Addr -> String
(Int -> Addr -> ShowS)
-> (Addr -> String) -> ([Addr] -> ShowS) -> Show Addr
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Addr -> ShowS
showsPrec :: Int -> Addr -> ShowS
$cshow :: Addr -> String
show :: Addr -> String
$cshowList :: [Addr] -> ShowS
showList :: [Addr] -> ShowS
Show, Addr -> Addr -> Bool
(Addr -> Addr -> Bool) -> (Addr -> Addr -> Bool) -> Eq Addr
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Addr -> Addr -> Bool
== :: Addr -> Addr -> Bool
$c/= :: Addr -> Addr -> Bool
/= :: Addr -> Addr -> Bool
Eq, (forall x. Addr -> Rep Addr x)
-> (forall x. Rep Addr x -> Addr) -> Generic Addr
forall x. Rep Addr x -> Addr
forall x. Addr -> Rep Addr x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Addr -> Rep Addr x
from :: forall x. Addr -> Rep Addr x
$cto :: forall x. Rep Addr x -> Addr
to :: forall x. Rep Addr x -> Addr
Generic, Addr -> ()
(Addr -> ()) -> NFData Addr
forall a. (a -> ()) -> NFData a
$crnf :: Addr -> ()
rnf :: Addr -> ()
NFData, Eq Addr
Eq Addr =>
(Addr -> Addr -> Ordering)
-> (Addr -> Addr -> Bool)
-> (Addr -> Addr -> Bool)
-> (Addr -> Addr -> Bool)
-> (Addr -> Addr -> Bool)
-> (Addr -> Addr -> Addr)
-> (Addr -> Addr -> Addr)
-> Ord Addr
Addr -> Addr -> Bool
Addr -> Addr -> Ordering
Addr -> Addr -> Addr
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Addr -> Addr -> Ordering
compare :: Addr -> Addr -> Ordering
$c< :: Addr -> Addr -> Bool
< :: Addr -> Addr -> Bool
$c<= :: Addr -> Addr -> Bool
<= :: Addr -> Addr -> Bool
$c> :: Addr -> Addr -> Bool
> :: Addr -> Addr -> Bool
$c>= :: Addr -> Addr -> Bool
>= :: Addr -> Addr -> Bool
$cmax :: Addr -> Addr -> Addr
max :: Addr -> Addr -> Addr
$cmin :: Addr -> Addr -> Addr
min :: Addr -> Addr -> Addr
Ord)

-- | Lookup a Network Id for an Address
getNetwork :: Addr -> Network
getNetwork :: Addr -> Network
getNetwork (Addr Network
n PaymentCredential
_ StakeReference
_) = Network
n
getNetwork (AddrBootstrap (BootstrapAddress Address
byronAddr)) =
  case AddrAttributes -> NetworkMagic
Byron.aaNetworkMagic (AddrAttributes -> NetworkMagic)
-> (Address -> AddrAttributes) -> Address -> NetworkMagic
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Attributes AddrAttributes -> AddrAttributes
forall h. Attributes h -> h
Byron.attrData (Attributes AddrAttributes -> AddrAttributes)
-> (Address -> Attributes AddrAttributes)
-> Address
-> AddrAttributes
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Address -> Attributes AddrAttributes
Byron.addrAttributes (Address -> NetworkMagic) -> Address -> NetworkMagic
forall a b. (a -> b) -> a -> b
$ Address
byronAddr of
    NetworkMagic
Byron.NetworkMainOrStage -> Network
Mainnet
    Byron.NetworkTestnet Word32
_ -> Network
Testnet

instance NoThunks Addr

-- | This function is implemented solely for the purpose of translating garbage pointers
-- into knowingly invalid ones. Any pointer that contains a SlotNo, TxIx or CertIx that
-- is too large to fit into Word32, Word16 and Word16 respectively, will have all of its
-- values set to 0 using `normalizePtr`.
--
-- There are two reasons why we can safely do that at the Babbage/Conway era boundary:
--
-- * Invalid pointers are no longer allowed in transactions starting with Babbage era
--
-- * There are only a handful of `Ptr`s on mainnet that are invalid.
--
-- Once the transition is complete and we are officially in Conway era, this translation
-- logic can be removed in favor of a fixed deserializer that does the same thing for all
-- eras prior to Babbage.
addrPtrNormalize :: Addr -> Addr
addrPtrNormalize :: Addr -> Addr
addrPtrNormalize = Addr -> Addr
forall a. a -> a
id
{-# DEPRECATED addrPtrNormalize "Pointers are now all normalized and this logic has been moved to the decoder" #-}

-- | An account based address for rewards
data RewardAccount = RewardAccount
  { RewardAccount -> Network
raNetwork :: !Network
  , RewardAccount -> Credential 'Staking
raCredential :: !(Credential 'Staking)
  }
  deriving (Int -> RewardAccount -> ShowS
[RewardAccount] -> ShowS
RewardAccount -> String
(Int -> RewardAccount -> ShowS)
-> (RewardAccount -> String)
-> ([RewardAccount] -> ShowS)
-> Show RewardAccount
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> RewardAccount -> ShowS
showsPrec :: Int -> RewardAccount -> ShowS
$cshow :: RewardAccount -> String
show :: RewardAccount -> String
$cshowList :: [RewardAccount] -> ShowS
showList :: [RewardAccount] -> ShowS
Show, RewardAccount -> RewardAccount -> Bool
(RewardAccount -> RewardAccount -> Bool)
-> (RewardAccount -> RewardAccount -> Bool) -> Eq RewardAccount
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: RewardAccount -> RewardAccount -> Bool
== :: RewardAccount -> RewardAccount -> Bool
$c/= :: RewardAccount -> RewardAccount -> Bool
/= :: RewardAccount -> RewardAccount -> Bool
Eq, (forall x. RewardAccount -> Rep RewardAccount x)
-> (forall x. Rep RewardAccount x -> RewardAccount)
-> Generic RewardAccount
forall x. Rep RewardAccount x -> RewardAccount
forall x. RewardAccount -> Rep RewardAccount x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. RewardAccount -> Rep RewardAccount x
from :: forall x. RewardAccount -> Rep RewardAccount x
$cto :: forall x. Rep RewardAccount x -> RewardAccount
to :: forall x. Rep RewardAccount x -> RewardAccount
Generic, Eq RewardAccount
Eq RewardAccount =>
(RewardAccount -> RewardAccount -> Ordering)
-> (RewardAccount -> RewardAccount -> Bool)
-> (RewardAccount -> RewardAccount -> Bool)
-> (RewardAccount -> RewardAccount -> Bool)
-> (RewardAccount -> RewardAccount -> Bool)
-> (RewardAccount -> RewardAccount -> RewardAccount)
-> (RewardAccount -> RewardAccount -> RewardAccount)
-> Ord RewardAccount
RewardAccount -> RewardAccount -> Bool
RewardAccount -> RewardAccount -> Ordering
RewardAccount -> RewardAccount -> RewardAccount
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: RewardAccount -> RewardAccount -> Ordering
compare :: RewardAccount -> RewardAccount -> Ordering
$c< :: RewardAccount -> RewardAccount -> Bool
< :: RewardAccount -> RewardAccount -> Bool
$c<= :: RewardAccount -> RewardAccount -> Bool
<= :: RewardAccount -> RewardAccount -> Bool
$c> :: RewardAccount -> RewardAccount -> Bool
> :: RewardAccount -> RewardAccount -> Bool
$c>= :: RewardAccount -> RewardAccount -> Bool
>= :: RewardAccount -> RewardAccount -> Bool
$cmax :: RewardAccount -> RewardAccount -> RewardAccount
max :: RewardAccount -> RewardAccount -> RewardAccount
$cmin :: RewardAccount -> RewardAccount -> RewardAccount
min :: RewardAccount -> RewardAccount -> RewardAccount
Ord, RewardAccount -> ()
(RewardAccount -> ()) -> NFData RewardAccount
forall a. (a -> ()) -> NFData a
$crnf :: RewardAccount -> ()
rnf :: RewardAccount -> ()
NFData, ToJSONKeyFunction [RewardAccount]
ToJSONKeyFunction RewardAccount
ToJSONKeyFunction RewardAccount
-> ToJSONKeyFunction [RewardAccount] -> ToJSONKey RewardAccount
forall a.
ToJSONKeyFunction a -> ToJSONKeyFunction [a] -> ToJSONKey a
$ctoJSONKey :: ToJSONKeyFunction RewardAccount
toJSONKey :: ToJSONKeyFunction RewardAccount
$ctoJSONKeyList :: ToJSONKeyFunction [RewardAccount]
toJSONKeyList :: ToJSONKeyFunction [RewardAccount]
ToJSONKey, FromJSONKeyFunction [RewardAccount]
FromJSONKeyFunction RewardAccount
FromJSONKeyFunction RewardAccount
-> FromJSONKeyFunction [RewardAccount] -> FromJSONKey RewardAccount
forall a.
FromJSONKeyFunction a -> FromJSONKeyFunction [a] -> FromJSONKey a
$cfromJSONKey :: FromJSONKeyFunction RewardAccount
fromJSONKey :: FromJSONKeyFunction RewardAccount
$cfromJSONKeyList :: FromJSONKeyFunction [RewardAccount]
fromJSONKeyList :: FromJSONKeyFunction [RewardAccount]
FromJSONKey)

rewardAccountCredentialL :: Lens' RewardAccount (Credential 'Staking)
rewardAccountCredentialL :: Lens' RewardAccount (Credential 'Staking)
rewardAccountCredentialL = (RewardAccount -> Credential 'Staking)
-> (RewardAccount -> Credential 'Staking -> RewardAccount)
-> Lens' RewardAccount (Credential 'Staking)
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens RewardAccount -> Credential 'Staking
raCredential ((RewardAccount -> Credential 'Staking -> RewardAccount)
 -> Lens' RewardAccount (Credential 'Staking))
-> (RewardAccount -> Credential 'Staking -> RewardAccount)
-> Lens' RewardAccount (Credential 'Staking)
forall a b. (a -> b) -> a -> b
$ \RewardAccount
x Credential 'Staking
y -> RewardAccount
x {raCredential = y}

rewardAccountNetworkL :: Lens' RewardAccount Network
rewardAccountNetworkL :: Lens' RewardAccount Network
rewardAccountNetworkL = (RewardAccount -> Network)
-> (RewardAccount -> Network -> RewardAccount)
-> Lens' RewardAccount Network
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens RewardAccount -> Network
raNetwork ((RewardAccount -> Network -> RewardAccount)
 -> Lens' RewardAccount Network)
-> (RewardAccount -> Network -> RewardAccount)
-> Lens' RewardAccount Network
forall a b. (a -> b) -> a -> b
$ \RewardAccount
x Network
y -> RewardAccount
x {raNetwork = y}

instance Default RewardAccount where
  def :: RewardAccount
def = Network -> Credential 'Staking -> RewardAccount
RewardAccount Network
forall a. Default a => a
def Credential 'Staking
forall a. Default a => a
def

instance ToJSON RewardAccount where
  toJSON :: RewardAccount -> Value
toJSON RewardAccount
ra =
    [Pair] -> Value
Aeson.object
      [ Key
"network" Key -> Network -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= RewardAccount -> Network
raNetwork RewardAccount
ra
      , Key
"credential" Key -> Credential 'Staking -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= RewardAccount -> Credential 'Staking
raCredential RewardAccount
ra
      ]

instance FromJSON RewardAccount where
  parseJSON :: Value -> Parser RewardAccount
parseJSON =
    String
-> (Object -> Parser RewardAccount)
-> Value
-> Parser RewardAccount
forall a. String -> (Object -> Parser a) -> Value -> Parser a
Aeson.withObject String
"RewardAccount" ((Object -> Parser RewardAccount) -> Value -> Parser RewardAccount)
-> (Object -> Parser RewardAccount)
-> Value
-> Parser RewardAccount
forall a b. (a -> b) -> a -> b
$ \Object
obj ->
      Network -> Credential 'Staking -> RewardAccount
RewardAccount
        (Network -> Credential 'Staking -> RewardAccount)
-> Parser Network -> Parser (Credential 'Staking -> RewardAccount)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
obj
          Object -> Key -> Parser Network
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"network"
        Parser (Credential 'Staking -> RewardAccount)
-> Parser (Credential 'Staking) -> Parser RewardAccount
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
obj
          Object -> Key -> Parser (Credential 'Staking)
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"credential"

instance NoThunks RewardAccount

instance ToJSONKey Addr where
  toJSONKey :: ToJSONKeyFunction Addr
toJSONKey = (Addr -> Key) -> (Addr -> Encoding' Key) -> ToJSONKeyFunction Addr
forall a. (a -> Key) -> (a -> Encoding' Key) -> ToJSONKeyFunction a
Aeson.ToJSONKeyText (Text -> Key
Aeson.fromText (Text -> Key) -> (Addr -> Text) -> Addr -> Key
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Addr -> Text
addrToText) (Text -> Encoding' Key
forall a. Text -> Encoding' a
Aeson.text (Text -> Encoding' Key) -> (Addr -> Text) -> Addr -> Encoding' Key
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Addr -> Text
addrToText)

instance FromJSONKey Addr where
  fromJSONKey :: FromJSONKeyFunction Addr
fromJSONKey = (Text -> Parser Addr) -> FromJSONKeyFunction Addr
forall a. (Text -> Parser a) -> FromJSONKeyFunction a
Aeson.FromJSONKeyTextParser Text -> Parser Addr
parseAddr

instance ToJSON Addr where
  toJSON :: Addr -> Value
toJSON = Text -> Value
forall a. ToJSON a => a -> Value
toJSON (Text -> Value) -> (Addr -> Text) -> Addr -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Addr -> Text
addrToText

instance FromJSON Addr where
  parseJSON :: Value -> Parser Addr
parseJSON = String -> (Text -> Parser Addr) -> Value -> Parser Addr
forall a. String -> (Text -> Parser a) -> Value -> Parser a
Aeson.withText String
"address" Text -> Parser Addr
parseAddr

addrToText :: Addr -> Text
addrToText :: Addr -> Text
addrToText = ByteString -> Text
Text.decodeLatin1 (ByteString -> Text) -> (Addr -> ByteString) -> Addr -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ByteString
B16.encode (ByteString -> ByteString)
-> (Addr -> ByteString) -> Addr -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Addr -> ByteString
serialiseAddr

parseAddr :: Text -> Aeson.Parser Addr
parseAddr :: Text -> Parser Addr
parseAddr Text
t = do
  ByteString
bytes <- (String -> Parser ByteString)
-> (ByteString -> Parser ByteString)
-> Either String ByteString
-> Parser ByteString
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either String -> Parser ByteString
forall {m :: * -> *} {a} {a}. (MonadFail m, Show a) => a -> m a
badHex ByteString -> Parser ByteString
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return (ByteString -> Either String ByteString
B16.decode (Text -> ByteString
Text.encodeUtf8 Text
t))
  ByteString -> Parser Addr
forall (m :: * -> *). MonadFail m => ByteString -> m Addr
decodeAddr ByteString
bytes
  where
    badHex :: a -> m a
badHex a
h = String -> m a
forall a. String -> m a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> m a) -> String -> m a
forall a b. (a -> b) -> a -> b
$ String
"Addresses are expected in hex encoding for now: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ a -> String
forall a. Show a => a -> String
show a
h

byron :: Int
byron :: Int
byron = Int
7

notBaseAddr :: Int
notBaseAddr :: Int
notBaseAddr = Int
6

isEnterpriseAddr :: Int
isEnterpriseAddr :: Int
isEnterpriseAddr = Int
5

stakeCredIsScript :: Int
stakeCredIsScript :: Int
stakeCredIsScript = Int
5

payCredIsScript :: Int
payCredIsScript :: Int
payCredIsScript = Int
4

putAddr :: Addr -> Put
putAddr :: Addr -> Put
putAddr (AddrBootstrap (BootstrapAddress Address
byronAddr)) =
  ByteString -> Put
B.putLazyByteString (Version -> Address -> ByteString
forall a. EncCBOR a => Version -> a -> ByteString
serialize Version
byronProtVer Address
byronAddr)
putAddr (Addr Network
network PaymentCredential
pc StakeReference
sr) =
  let setPayCredBit :: Word8 -> Word8
setPayCredBit = case PaymentCredential
pc of
        ScriptHashObj ScriptHash
_ -> (Word8 -> Int -> Word8) -> Int -> Word8 -> Word8
forall a b c. (a -> b -> c) -> b -> a -> c
flip Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
setBit Int
payCredIsScript
        KeyHashObj KeyHash 'Payment
_ -> Word8 -> Word8
forall a. a -> a
id
      netId :: Word8
netId = Network -> Word8
networkToWord8 Network
network
   in case StakeReference
sr of
        StakeRefBase Credential 'Staking
sc -> do
          let setStakeCredBit :: Word8 -> Word8
setStakeCredBit = case Credential 'Staking
sc of
                ScriptHashObj ScriptHash
_ -> (Word8 -> Int -> Word8) -> Int -> Word8 -> Word8
forall a b c. (a -> b -> c) -> b -> a -> c
flip Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
setBit Int
stakeCredIsScript
                KeyHashObj KeyHash 'Staking
_ -> Word8 -> Word8
forall a. a -> a
id
              header :: Word8
header = Word8 -> Word8
setStakeCredBit (Word8 -> Word8) -> (Word8 -> Word8) -> Word8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Word8
setPayCredBit (Word8 -> Word8) -> Word8 -> Word8
forall a b. (a -> b) -> a -> b
$ Word8
netId
          Word8 -> Put
B.putWord8 Word8
header
          PaymentCredential -> Put
forall (kr :: KeyRole). Credential kr -> Put
putCredential PaymentCredential
pc
          Credential 'Staking -> Put
forall (kr :: KeyRole). Credential kr -> Put
putCredential Credential 'Staking
sc
        StakeRefPtr Ptr
ptr -> do
          let header :: Word8
header = Word8 -> Word8
setPayCredBit (Word8 -> Word8) -> Word8 -> Word8
forall a b. (a -> b) -> a -> b
$ Word8
netId Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
`setBit` Int
notBaseAddr
          Word8 -> Put
B.putWord8 Word8
header
          PaymentCredential -> Put
forall (kr :: KeyRole). Credential kr -> Put
putCredential PaymentCredential
pc
          Ptr -> Put
putPtr Ptr
ptr
        StakeReference
StakeRefNull -> do
          let header :: Word8
header = Word8 -> Word8
setPayCredBit (Word8 -> Word8) -> Word8 -> Word8
forall a b. (a -> b) -> a -> b
$ Word8
netId Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
`setBit` Int
isEnterpriseAddr Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
`setBit` Int
notBaseAddr
          Word8 -> Put
B.putWord8 Word8
header
          PaymentCredential -> Put
forall (kr :: KeyRole). Credential kr -> Put
putCredential PaymentCredential
pc
{-# INLINE putAddr #-}

putRewardAccount :: RewardAccount -> Put
putRewardAccount :: RewardAccount -> Put
putRewardAccount (RewardAccount Network
network Credential 'Staking
cred) = do
  let setPayCredBit :: Word8 -> Word8
setPayCredBit = case Credential 'Staking
cred of
        ScriptHashObj ScriptHash
_ -> (Word8 -> Int -> Word8) -> Int -> Word8 -> Word8
forall a b c. (a -> b -> c) -> b -> a -> c
flip Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
setBit Int
payCredIsScript
        KeyHashObj KeyHash 'Staking
_ -> Word8 -> Word8
forall a. a -> a
id
      netId :: Word8
netId = Network -> Word8
networkToWord8 Network
network
      rewardAccountPrefix :: Word8
rewardAccountPrefix = Word8
0xE0 -- 0b11100000 are always set for reward accounts
      header :: Word8
header = Word8 -> Word8
setPayCredBit (Word8
netId Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.|. Word8
rewardAccountPrefix)
  Word8 -> Put
B.putWord8 Word8
header
  Credential 'Staking -> Put
forall (kr :: KeyRole). Credential kr -> Put
putCredential Credential 'Staking
cred
{-# INLINE putRewardAccount #-}

putHash :: Hash.Hash h a -> Put
putHash :: forall h a. Hash h a -> Put
putHash = ByteString -> Put
B.putByteString (ByteString -> Put) -> (Hash h a -> ByteString) -> Hash h a -> Put
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Hash h a -> ByteString
forall h a. Hash h a -> ByteString
Hash.hashToBytes
{-# INLINE putHash #-}

putCredential :: Credential kr -> Put
putCredential :: forall (kr :: KeyRole). Credential kr -> Put
putCredential (ScriptHashObj (ScriptHash Hash ADDRHASH EraIndependentScript
h)) = Hash ADDRHASH EraIndependentScript -> Put
forall h a. Hash h a -> Put
putHash Hash ADDRHASH EraIndependentScript
h
putCredential (KeyHashObj (KeyHash Hash ADDRHASH (VerKeyDSIGN DSIGN)
h)) = Hash ADDRHASH (VerKeyDSIGN DSIGN) -> Put
forall h a. Hash h a -> Put
putHash Hash ADDRHASH (VerKeyDSIGN DSIGN)
h
{-# INLINE putCredential #-}

-- | The size of the extra attributes in a bootstrap (ie Byron) address. Used
-- to help enforce that people do not post huge ones on the chain.
bootstrapAddressAttrsSize :: BootstrapAddress -> Int
bootstrapAddressAttrsSize :: BootstrapAddress -> Int
bootstrapAddressAttrsSize (BootstrapAddress Address
addr) =
  Int -> (HDAddressPayload -> Int) -> Maybe HDAddressPayload -> Int
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Int
0 HDAddressPayload -> Int
payloadLen Maybe HDAddressPayload
derivationPath Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Attributes AddrAttributes -> Int
forall a. Attributes a -> Int
Byron.unknownAttributesLength Attributes AddrAttributes
attrs
  where
    payloadLen :: HDAddressPayload -> Int
payloadLen = ByteString -> Int
BS.length (ByteString -> Int)
-> (HDAddressPayload -> ByteString) -> HDAddressPayload -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HDAddressPayload -> ByteString
Byron.getHDAddressPayload
    derivationPath :: Maybe HDAddressPayload
derivationPath = AddrAttributes -> Maybe HDAddressPayload
Byron.aaVKDerivationPath (Attributes AddrAttributes -> AddrAttributes
forall h. Attributes h -> h
Byron.attrData Attributes AddrAttributes
attrs)
    attrs :: Attributes AddrAttributes
attrs = Address -> Attributes AddrAttributes
Byron.addrAttributes Address
addr

-- | Return True if a given address is a redeemer address from the Byron Era
isBootstrapRedeemer :: BootstrapAddress -> Bool
isBootstrapRedeemer :: BootstrapAddress -> Bool
isBootstrapRedeemer (BootstrapAddress (Byron.Address AddressHash Address'
_ Attributes AddrAttributes
_ AddrType
Byron.ATRedeem)) = Bool
True
isBootstrapRedeemer BootstrapAddress
_ = Bool
False

putPtr :: Ptr -> Put
putPtr :: Ptr -> Put
putPtr (Ptr (SlotNo32 Word32
slot) (TxIx Word16
txIx) (CertIx Word16
certIx)) = do
  Word64 -> Put
putVariableLengthWord64 (Word32 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
slot)
  Word64 -> Put
putVariableLengthWord64 (Word16 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word16
txIx) -- TODO: switch to using MemPack for compacting Address at which point
  Word64 -> Put
putVariableLengthWord64 (Word16 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word16
certIx) --     this conversion from Word16 to Word64 will no longer be necessary

newtype Word7 = Word7 Word8
  deriving (Word7 -> Word7 -> Bool
(Word7 -> Word7 -> Bool) -> (Word7 -> Word7 -> Bool) -> Eq Word7
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Word7 -> Word7 -> Bool
== :: Word7 -> Word7 -> Bool
$c/= :: Word7 -> Word7 -> Bool
/= :: Word7 -> Word7 -> Bool
Eq, Int -> Word7 -> ShowS
[Word7] -> ShowS
Word7 -> String
(Int -> Word7 -> ShowS)
-> (Word7 -> String) -> ([Word7] -> ShowS) -> Show Word7
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Word7 -> ShowS
showsPrec :: Int -> Word7 -> ShowS
$cshow :: Word7 -> String
show :: Word7 -> String
$cshowList :: [Word7] -> ShowS
showList :: [Word7] -> ShowS
Show)

toWord7 :: Word8 -> Word7
toWord7 :: Word8 -> Word7
toWord7 Word8
x = Word8 -> Word7
Word7 (Word8
x Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.&. Word8
0x7F) -- 0x7F = 0b01111111

putWord7s :: [Word7] -> Put
putWord7s :: [Word7] -> Put
putWord7s [] = () -> Put
forall a. a -> PutM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
putWord7s [Word7 Word8
x] = Word8 -> Put
B.putWord8 Word8
x
putWord7s (Word7 Word8
x : [Word7]
xs) = Word8 -> Put
B.putWord8 (Word8
x Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.|. Word8
0x80) Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> [Word7] -> Put
putWord7s [Word7]
xs

word64ToWord7s :: Word64 -> [Word7]
word64ToWord7s :: Word64 -> [Word7]
word64ToWord7s = [Word7] -> [Word7]
forall a. [a] -> [a]
reverse ([Word7] -> [Word7]) -> (Word64 -> [Word7]) -> Word64 -> [Word7]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> [Word7]
go
  where
    go :: Word64 -> [Word7]
    go :: Word64 -> [Word7]
go Word64
n
      | Word64
n Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
> Word64
0x7F = (Word8 -> Word7
toWord7 (Word8 -> Word7) -> (Word64 -> Word8) -> Word64 -> Word7
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral) Word64
n Word7 -> [Word7] -> [Word7]
forall a. a -> [a] -> [a]
: Word64 -> [Word7]
go (Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
shiftR Word64
n Int
7)
      | Bool
otherwise = [Word8 -> Word7
Word7 (Word8 -> Word7) -> (Word64 -> Word8) -> Word64 -> Word7
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64 -> Word7) -> Word64 -> Word7
forall a b. (a -> b) -> a -> b
$ Word64
n]

putVariableLengthWord64 :: Word64 -> Put
putVariableLengthWord64 :: Word64 -> Put
putVariableLengthWord64 = [Word7] -> Put
putWord7s ([Word7] -> Put) -> (Word64 -> [Word7]) -> Word64 -> Put
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> [Word7]
word64ToWord7s

instance EncCBOR Addr where
  encCBOR :: Addr -> Encoding
encCBOR = ByteString -> Encoding
forall a. EncCBOR a => a -> Encoding
encCBOR (ByteString -> Encoding)
-> (Addr -> ByteString) -> Addr -> Encoding
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Put -> ByteString
B.runPut (Put -> ByteString) -> (Addr -> Put) -> Addr -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Addr -> Put
putAddr
  {-# INLINE encCBOR #-}

instance DecCBOR Addr where
  decCBOR :: forall s. Decoder s Addr
decCBOR = Decoder s Addr
forall s. Decoder s Addr
fromCborAddr
  {-# INLINE decCBOR #-}

instance EncCBOR RewardAccount where
  encCBOR :: RewardAccount -> Encoding
encCBOR = ByteString -> Encoding
forall a. EncCBOR a => a -> Encoding
encCBOR (ByteString -> Encoding)
-> (RewardAccount -> ByteString) -> RewardAccount -> Encoding
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Put -> ByteString
B.runPut (Put -> ByteString)
-> (RewardAccount -> Put) -> RewardAccount -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RewardAccount -> Put
putRewardAccount
  {-# INLINE encCBOR #-}

instance DecCBOR RewardAccount where
  decCBOR :: forall s. Decoder s RewardAccount
decCBOR = Decoder s RewardAccount
forall s. Decoder s RewardAccount
fromCborRewardAccount
  {-# INLINE decCBOR #-}

newtype BootstrapAddress = BootstrapAddress
  { BootstrapAddress -> Address
unBootstrapAddress :: Byron.Address
  }
  deriving (BootstrapAddress -> BootstrapAddress -> Bool
(BootstrapAddress -> BootstrapAddress -> Bool)
-> (BootstrapAddress -> BootstrapAddress -> Bool)
-> Eq BootstrapAddress
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: BootstrapAddress -> BootstrapAddress -> Bool
== :: BootstrapAddress -> BootstrapAddress -> Bool
$c/= :: BootstrapAddress -> BootstrapAddress -> Bool
/= :: BootstrapAddress -> BootstrapAddress -> Bool
Eq, (forall x. BootstrapAddress -> Rep BootstrapAddress x)
-> (forall x. Rep BootstrapAddress x -> BootstrapAddress)
-> Generic BootstrapAddress
forall x. Rep BootstrapAddress x -> BootstrapAddress
forall x. BootstrapAddress -> Rep BootstrapAddress x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. BootstrapAddress -> Rep BootstrapAddress x
from :: forall x. BootstrapAddress -> Rep BootstrapAddress x
$cto :: forall x. Rep BootstrapAddress x -> BootstrapAddress
to :: forall x. Rep BootstrapAddress x -> BootstrapAddress
Generic)
  deriving newtype (BootstrapAddress -> ()
(BootstrapAddress -> ()) -> NFData BootstrapAddress
forall a. (a -> ()) -> NFData a
$crnf :: BootstrapAddress -> ()
rnf :: BootstrapAddress -> ()
NFData, Eq BootstrapAddress
Eq BootstrapAddress =>
(BootstrapAddress -> BootstrapAddress -> Ordering)
-> (BootstrapAddress -> BootstrapAddress -> Bool)
-> (BootstrapAddress -> BootstrapAddress -> Bool)
-> (BootstrapAddress -> BootstrapAddress -> Bool)
-> (BootstrapAddress -> BootstrapAddress -> Bool)
-> (BootstrapAddress -> BootstrapAddress -> BootstrapAddress)
-> (BootstrapAddress -> BootstrapAddress -> BootstrapAddress)
-> Ord BootstrapAddress
BootstrapAddress -> BootstrapAddress -> Bool
BootstrapAddress -> BootstrapAddress -> Ordering
BootstrapAddress -> BootstrapAddress -> BootstrapAddress
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: BootstrapAddress -> BootstrapAddress -> Ordering
compare :: BootstrapAddress -> BootstrapAddress -> Ordering
$c< :: BootstrapAddress -> BootstrapAddress -> Bool
< :: BootstrapAddress -> BootstrapAddress -> Bool
$c<= :: BootstrapAddress -> BootstrapAddress -> Bool
<= :: BootstrapAddress -> BootstrapAddress -> Bool
$c> :: BootstrapAddress -> BootstrapAddress -> Bool
> :: BootstrapAddress -> BootstrapAddress -> Bool
$c>= :: BootstrapAddress -> BootstrapAddress -> Bool
>= :: BootstrapAddress -> BootstrapAddress -> Bool
$cmax :: BootstrapAddress -> BootstrapAddress -> BootstrapAddress
max :: BootstrapAddress -> BootstrapAddress -> BootstrapAddress
$cmin :: BootstrapAddress -> BootstrapAddress -> BootstrapAddress
min :: BootstrapAddress -> BootstrapAddress -> BootstrapAddress
Ord)
  deriving (Int -> BootstrapAddress -> ShowS
[BootstrapAddress] -> ShowS
BootstrapAddress -> String
(Int -> BootstrapAddress -> ShowS)
-> (BootstrapAddress -> String)
-> ([BootstrapAddress] -> ShowS)
-> Show BootstrapAddress
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> BootstrapAddress -> ShowS
showsPrec :: Int -> BootstrapAddress -> ShowS
$cshow :: BootstrapAddress -> String
show :: BootstrapAddress -> String
$cshowList :: [BootstrapAddress] -> ShowS
showList :: [BootstrapAddress] -> ShowS
Show) via Quiet BootstrapAddress

instance NoThunks BootstrapAddress

bootstrapKeyHash ::
  BootstrapAddress ->
  KeyHash 'Payment
bootstrapKeyHash :: BootstrapAddress -> KeyHash 'Payment
bootstrapKeyHash (BootstrapAddress Address
byronAddress) =
  let root :: AddressHash Address'
root = Address -> AddressHash Address'
Byron.addrRoot Address
byronAddress
      bytes :: ByteString
bytes = AddressHash Address' -> ByteString
forall algo a. AbstractHash algo a -> ByteString
Byron.abstractHashToBytes AddressHash Address'
root
      !hash :: Hash ADDRHASH (VerKeyDSIGN DSIGN)
hash =
        Hash ADDRHASH (VerKeyDSIGN DSIGN)
-> Maybe (Hash ADDRHASH (VerKeyDSIGN DSIGN))
-> Hash ADDRHASH (VerKeyDSIGN DSIGN)
forall a. a -> Maybe a -> a
fromMaybe (String -> Hash ADDRHASH (VerKeyDSIGN DSIGN)
forall a. HasCallStack => String -> a
error String
"bootstrapKeyHash: incorrect hash length") (Maybe (Hash ADDRHASH (VerKeyDSIGN DSIGN))
 -> Hash ADDRHASH (VerKeyDSIGN DSIGN))
-> Maybe (Hash ADDRHASH (VerKeyDSIGN DSIGN))
-> Hash ADDRHASH (VerKeyDSIGN DSIGN)
forall a b. (a -> b) -> a -> b
$
          ByteString -> Maybe (Hash ADDRHASH (VerKeyDSIGN DSIGN))
forall h a. HashAlgorithm h => ByteString -> Maybe (Hash h a)
Hash.hashFromBytes ByteString
bytes
   in Hash ADDRHASH (VerKeyDSIGN DSIGN) -> KeyHash 'Payment
forall (r :: KeyRole).
Hash ADDRHASH (VerKeyDSIGN DSIGN) -> KeyHash r
KeyHash Hash ADDRHASH (VerKeyDSIGN DSIGN)
hash

------------------------------------------------------------------------------------------
-- Compact Address -----------------------------------------------------------------------
------------------------------------------------------------------------------------------

newtype CompactAddr = UnsafeCompactAddr ShortByteString
  deriving stock (CompactAddr -> CompactAddr -> Bool
(CompactAddr -> CompactAddr -> Bool)
-> (CompactAddr -> CompactAddr -> Bool) -> Eq CompactAddr
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: CompactAddr -> CompactAddr -> Bool
== :: CompactAddr -> CompactAddr -> Bool
$c/= :: CompactAddr -> CompactAddr -> Bool
/= :: CompactAddr -> CompactAddr -> Bool
Eq, (forall x. CompactAddr -> Rep CompactAddr x)
-> (forall x. Rep CompactAddr x -> CompactAddr)
-> Generic CompactAddr
forall x. Rep CompactAddr x -> CompactAddr
forall x. CompactAddr -> Rep CompactAddr x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. CompactAddr -> Rep CompactAddr x
from :: forall x. CompactAddr -> Rep CompactAddr x
$cto :: forall x. Rep CompactAddr x -> CompactAddr
to :: forall x. Rep CompactAddr x -> CompactAddr
Generic, Eq CompactAddr
Eq CompactAddr =>
(CompactAddr -> CompactAddr -> Ordering)
-> (CompactAddr -> CompactAddr -> Bool)
-> (CompactAddr -> CompactAddr -> Bool)
-> (CompactAddr -> CompactAddr -> Bool)
-> (CompactAddr -> CompactAddr -> Bool)
-> (CompactAddr -> CompactAddr -> CompactAddr)
-> (CompactAddr -> CompactAddr -> CompactAddr)
-> Ord CompactAddr
CompactAddr -> CompactAddr -> Bool
CompactAddr -> CompactAddr -> Ordering
CompactAddr -> CompactAddr -> CompactAddr
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: CompactAddr -> CompactAddr -> Ordering
compare :: CompactAddr -> CompactAddr -> Ordering
$c< :: CompactAddr -> CompactAddr -> Bool
< :: CompactAddr -> CompactAddr -> Bool
$c<= :: CompactAddr -> CompactAddr -> Bool
<= :: CompactAddr -> CompactAddr -> Bool
$c> :: CompactAddr -> CompactAddr -> Bool
> :: CompactAddr -> CompactAddr -> Bool
$c>= :: CompactAddr -> CompactAddr -> Bool
>= :: CompactAddr -> CompactAddr -> Bool
$cmax :: CompactAddr -> CompactAddr -> CompactAddr
max :: CompactAddr -> CompactAddr -> CompactAddr
$cmin :: CompactAddr -> CompactAddr -> CompactAddr
min :: CompactAddr -> CompactAddr -> CompactAddr
Ord)
  deriving newtype (Context -> CompactAddr -> IO (Maybe ThunkInfo)
Proxy CompactAddr -> String
(Context -> CompactAddr -> IO (Maybe ThunkInfo))
-> (Context -> CompactAddr -> IO (Maybe ThunkInfo))
-> (Proxy CompactAddr -> String)
-> NoThunks CompactAddr
forall a.
(Context -> a -> IO (Maybe ThunkInfo))
-> (Context -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> String)
-> NoThunks a
$cnoThunks :: Context -> CompactAddr -> IO (Maybe ThunkInfo)
noThunks :: Context -> CompactAddr -> IO (Maybe ThunkInfo)
$cwNoThunks :: Context -> CompactAddr -> IO (Maybe ThunkInfo)
wNoThunks :: Context -> CompactAddr -> IO (Maybe ThunkInfo)
$cshowTypeOf :: Proxy CompactAddr -> String
showTypeOf :: Proxy CompactAddr -> String
NoThunks, CompactAddr -> ()
(CompactAddr -> ()) -> NFData CompactAddr
forall a. (a -> ()) -> NFData a
$crnf :: CompactAddr -> ()
rnf :: CompactAddr -> ()
NFData, String
String
-> (CompactAddr -> Int)
-> (forall s. CompactAddr -> Pack s ())
-> (forall b. Buffer b => Unpack b CompactAddr)
-> MemPack CompactAddr
CompactAddr -> Int
forall a.
String
-> (a -> Int)
-> (forall s. a -> Pack s ())
-> (forall b. Buffer b => Unpack b a)
-> MemPack a
forall b. Buffer b => Unpack b CompactAddr
forall s. CompactAddr -> Pack s ()
$ctypeName :: String
typeName :: String
$cpackedByteCount :: CompactAddr -> Int
packedByteCount :: CompactAddr -> Int
$cpackM :: forall s. CompactAddr -> Pack s ()
packM :: forall s. CompactAddr -> Pack s ()
$cunpackM :: forall b. Buffer b => Unpack b CompactAddr
unpackM :: forall b. Buffer b => Unpack b CompactAddr
MemPack)

instance Show CompactAddr where
  show :: CompactAddr -> String
show CompactAddr
c = Addr -> String
forall a. Show a => a -> String
show (HasCallStack => CompactAddr -> Addr
CompactAddr -> Addr
decompactAddr CompactAddr
c)

-- | Unwrap the compact address and get to the address' binary representation.
unCompactAddr :: CompactAddr -> ShortByteString
unCompactAddr :: CompactAddr -> ShortByteString
unCompactAddr (UnsafeCompactAddr ShortByteString
sbs) = ShortByteString
sbs
{-# INLINE unCompactAddr #-}

compactAddr :: Addr -> CompactAddr
compactAddr :: Addr -> CompactAddr
compactAddr = ShortByteString -> CompactAddr
UnsafeCompactAddr (ShortByteString -> CompactAddr)
-> (Addr -> ShortByteString) -> Addr -> CompactAddr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ShortByteString
SBS.toShort (ByteString -> ShortByteString)
-> (Addr -> ByteString) -> Addr -> ShortByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Addr -> ByteString
serialiseAddr
{-# INLINE compactAddr #-}

decompactAddr :: HasCallStack => CompactAddr -> Addr
decompactAddr :: HasCallStack => CompactAddr -> Addr
decompactAddr (UnsafeCompactAddr ShortByteString
sbs) =
  case Fail String Addr -> Either String Addr
forall e a. (IsString e, Semigroup e) => Fail e a -> Either e a
runFail (Fail String Addr -> Either String Addr)
-> Fail String Addr -> Either String Addr
forall a b. (a -> b) -> a -> b
$ StateT Int (FailT String Identity) Addr -> Int -> Fail String Addr
forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m a
evalStateT (Bool
-> Bool
-> ShortByteString
-> StateT Int (FailT String Identity) Addr
forall (m :: * -> *) b.
(MonadFail m, AddressBuffer b) =>
Bool -> Bool -> b -> StateT Int m Addr
decodeAddrStateLenientT Bool
True Bool
True ShortByteString
sbs) Int
0 of
    Right Addr
addr -> Addr
addr
    Left String
err ->
      String -> Addr
forall a. HasCallStack => String -> a
error (String -> Addr) -> String -> Addr
forall a b. (a -> b) -> a -> b
$
        String
"Impossible: Malformed CompactAddr was allowed into the system. "
          String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" Decoder error: "
          String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
err
{-# INLINE decompactAddr #-}

------------------------------------------------------------------------------------------
-- Address Serializer --------------------------------------------------------------------
------------------------------------------------------------------------------------------

-- | Decoder for an `Addr`. Works in all eras
fromCborAddr :: Decoder s Addr
fromCborAddr :: forall s. Decoder s Addr
fromCborAddr = (Addr, CompactAddr) -> Addr
forall a b. (a, b) -> a
fst ((Addr, CompactAddr) -> Addr)
-> Decoder s (Addr, CompactAddr) -> Decoder s Addr
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Decoder s (Addr, CompactAddr)
forall s. Decoder s (Addr, CompactAddr)
fromCborBothAddr
{-# INLINE fromCborAddr #-}

-- | Returns the actual bytes that represent an addres, while ensuring that they can
-- be decoded in any era as an `Addr` when need be.
fromCborCompactAddr :: Decoder s CompactAddr
fromCborCompactAddr :: forall s. Decoder s CompactAddr
fromCborCompactAddr = (Addr, CompactAddr) -> CompactAddr
forall a b. (a, b) -> b
snd ((Addr, CompactAddr) -> CompactAddr)
-> Decoder s (Addr, CompactAddr) -> Decoder s CompactAddr
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Decoder s (Addr, CompactAddr)
forall s. Decoder s (Addr, CompactAddr)
fromCborBothAddr
{-# INLINE fromCborCompactAddr #-}

-- | This is the decoder for an address that returns both the actual `Addr` and the bytes,
-- that it was encoded as.
fromCborBothAddr :: Decoder s (Addr, CompactAddr)
fromCborBothAddr :: forall s. Decoder s (Addr, CompactAddr)
fromCborBothAddr = do
  Version
-> Decoder s (Addr, CompactAddr)
-> Decoder s (Addr, CompactAddr)
-> Decoder s (Addr, CompactAddr)
forall s a. Version -> Decoder s a -> Decoder s a -> Decoder s a
ifDecoderVersionAtLeast
    (forall (v :: Natural).
(KnownNat v, MinVersion <= v, v <= MaxVersion) =>
Version
natVersion @7)
    ( Version
-> Decoder s (Addr, CompactAddr)
-> Decoder s (Addr, CompactAddr)
-> Decoder s (Addr, CompactAddr)
forall s a. Version -> Decoder s a -> Decoder s a -> Decoder s a
ifDecoderVersionAtLeast
        (forall (v :: Natural).
(KnownNat v, MinVersion <= v, v <= MaxVersion) =>
Version
natVersion @9)
        (Bool -> Decoder s (Addr, CompactAddr)
forall s. Bool -> Decoder s (Addr, CompactAddr)
fromCborRigorousBothAddr Bool
False)
        (Bool -> Decoder s (Addr, CompactAddr)
forall s. Bool -> Decoder s (Addr, CompactAddr)
fromCborRigorousBothAddr Bool
True)
    )
    Decoder s (Addr, CompactAddr)
forall s. Decoder s (Addr, CompactAddr)
fromCborBackwardsBothAddr
{-# INLINE fromCborBothAddr #-}

-- | Starting with Babbage we no longer allow addresses with garbage in them.
fromCborRigorousBothAddr ::
  -- | Should there be a hard failure for garbage pointers (`False`) or should they be normalized instead (`True`)
  Bool ->
  Decoder s (Addr, CompactAddr)
fromCborRigorousBothAddr :: forall s. Bool -> Decoder s (Addr, CompactAddr)
fromCborRigorousBothAddr Bool
isPtrLenient = do
  ShortByteString
sbs <- Decoder s ShortByteString
forall s. Decoder s ShortByteString
forall a s. DecCBOR a => Decoder s a
decCBOR
  (StateT Int (Decoder s) (Addr, CompactAddr)
 -> Int -> Decoder s (Addr, CompactAddr))
-> Int
-> StateT Int (Decoder s) (Addr, CompactAddr)
-> Decoder s (Addr, CompactAddr)
forall a b c. (a -> b -> c) -> b -> a -> c
flip StateT Int (Decoder s) (Addr, CompactAddr)
-> Int -> Decoder s (Addr, CompactAddr)
forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m a
evalStateT Int
0 (StateT Int (Decoder s) (Addr, CompactAddr)
 -> Decoder s (Addr, CompactAddr))
-> StateT Int (Decoder s) (Addr, CompactAddr)
-> Decoder s (Addr, CompactAddr)
forall a b. (a -> b) -> a -> b
$ do
    Addr
addr <- Bool -> Bool -> ShortByteString -> StateT Int (Decoder s) Addr
forall (m :: * -> *) b.
(MonadFail m, AddressBuffer b) =>
Bool -> Bool -> b -> StateT Int m Addr
decodeAddrStateLenientT Bool
isPtrLenient Bool
False ShortByteString
sbs
    (Addr, CompactAddr) -> StateT Int (Decoder s) (Addr, CompactAddr)
forall a. a -> StateT Int (Decoder s) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Addr
addr, ShortByteString -> CompactAddr
UnsafeCompactAddr ShortByteString
sbs)
{-# INLINE fromCborRigorousBothAddr #-}

-- | Prior to Babbage era we did not check if a binary blob representing an address was
-- fully consumed, so unfortunately we must preserve this behavior. However, we do not
-- need to preserve the unconsumed bytes in memory, therefore we can drop the
-- garbage after we successfully decoded the malformed address. We also need to allow
-- bogus pointer address to be deserializeable prior to Babbage era.
fromCborBackwardsBothAddr :: Decoder s (Addr, CompactAddr)
fromCborBackwardsBothAddr :: forall s. Decoder s (Addr, CompactAddr)
fromCborBackwardsBothAddr = do
  ShortByteString
sbs <- Decoder s ShortByteString
forall s. Decoder s ShortByteString
forall a s. DecCBOR a => Decoder s a
decCBOR
  (StateT Int (Decoder s) (Addr, CompactAddr)
 -> Int -> Decoder s (Addr, CompactAddr))
-> Int
-> StateT Int (Decoder s) (Addr, CompactAddr)
-> Decoder s (Addr, CompactAddr)
forall a b c. (a -> b -> c) -> b -> a -> c
flip StateT Int (Decoder s) (Addr, CompactAddr)
-> Int -> Decoder s (Addr, CompactAddr)
forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m a
evalStateT Int
0 (StateT Int (Decoder s) (Addr, CompactAddr)
 -> Decoder s (Addr, CompactAddr))
-> StateT Int (Decoder s) (Addr, CompactAddr)
-> Decoder s (Addr, CompactAddr)
forall a b. (a -> b) -> a -> b
$ do
    Addr
addr <- Bool -> Bool -> ShortByteString -> StateT Int (Decoder s) Addr
forall (m :: * -> *) b.
(MonadFail m, AddressBuffer b) =>
Bool -> Bool -> b -> StateT Int m Addr
decodeAddrStateLenientT Bool
True Bool
True ShortByteString
sbs
    Int
bytesConsumed <- StateT Int (Decoder s) Int
forall (m :: * -> *) s. Monad m => StateT s m s
get
    let sbsCropped :: ShortByteString
sbsCropped = ByteString -> ShortByteString
SBS.toShort (ByteString -> ShortByteString) -> ByteString -> ShortByteString
forall a b. (a -> b) -> a -> b
$ Int -> ByteString -> ByteString
BS.take Int
bytesConsumed (ByteString -> ByteString) -> ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$ ShortByteString -> ByteString
SBS.fromShort ShortByteString
sbs
    (Addr, CompactAddr) -> StateT Int (Decoder s) (Addr, CompactAddr)
forall a. a -> StateT Int (Decoder s) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Addr
addr, ShortByteString -> CompactAddr
UnsafeCompactAddr ShortByteString
sbsCropped)
{-# INLINE fromCborBackwardsBothAddr #-}

class AddressBuffer b where
  bufLength :: b -> Int

  bufUnsafeIndex :: b -> Int -> Word8

  bufToByteString :: b -> BS.ByteString

  bufGetHash :: Hash.HashAlgorithm h => b -> Int -> Maybe (Hash.Hash h a)

instance AddressBuffer ShortByteString where
  bufLength :: ShortByteString -> Int
bufLength = ShortByteString -> Int
SBS.length
  {-# INLINE bufLength #-}
  bufUnsafeIndex :: ShortByteString -> Int -> Word8
bufUnsafeIndex = ShortByteString -> Int -> Word8
SBS.unsafeIndex
  {-# INLINE bufUnsafeIndex #-}
  bufToByteString :: ShortByteString -> ByteString
bufToByteString = ShortByteString -> ByteString
SBS.fromShort
  {-# INLINE bufToByteString #-}
  bufGetHash :: forall h a.
HashAlgorithm h =>
ShortByteString -> Int -> Maybe (Hash h a)
bufGetHash = ShortByteString -> Int -> Maybe (Hash h a)
forall h a.
HashAlgorithm h =>
ShortByteString -> Int -> Maybe (Hash h a)
Hash.hashFromOffsetBytesShort
  {-# INLINE bufGetHash #-}

instance AddressBuffer BS.ByteString where
  bufLength :: ByteString -> Int
bufLength = ByteString -> Int
BS.length
  {-# INLINE bufLength #-}
  bufUnsafeIndex :: ByteString -> Int -> Word8
bufUnsafeIndex = ByteString -> Int -> Word8
BS.unsafeIndex
  {-# INLINE bufUnsafeIndex #-}
  bufToByteString :: ByteString -> ByteString
bufToByteString = ByteString -> ByteString
forall a. a -> a
id
  {-# INLINE bufToByteString #-}
  bufGetHash :: forall h a. Hash.HashAlgorithm h => BS.ByteString -> Int -> Maybe (Hash.Hash h a)
  bufGetHash :: forall h a.
HashAlgorithm h =>
ByteString -> Int -> Maybe (Hash h a)
bufGetHash ByteString
bs Int
offset = do
    let size :: Int
size = Word -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Proxy h -> Word
forall h (proxy :: * -> *). HashAlgorithm h => proxy h -> Word
Hash.sizeHash (Proxy h
forall {k} (t :: k). Proxy t
Proxy :: Proxy h))
    Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Int
offset Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
offset Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
size Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= ByteString -> Int
BS.length ByteString
bs)
    ByteString -> Maybe (Hash h a)
forall h a. HashAlgorithm h => ByteString -> Maybe (Hash h a)
Hash.hashFromBytes (Int -> ByteString -> ByteString
BS.unsafeTake Int
size (Int -> ByteString -> ByteString
BS.unsafeDrop Int
offset ByteString
bs))
  {-# INLINE bufGetHash #-}

-- | Address header byte truth table:
newtype Header = Header Word8
  deriving newtype (Header -> Header -> Bool
(Header -> Header -> Bool)
-> (Header -> Header -> Bool) -> Eq Header
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Header -> Header -> Bool
== :: Header -> Header -> Bool
$c/= :: Header -> Header -> Bool
/= :: Header -> Header -> Bool
Eq, Eq Header
Eq Header =>
(Header -> Header -> Ordering)
-> (Header -> Header -> Bool)
-> (Header -> Header -> Bool)
-> (Header -> Header -> Bool)
-> (Header -> Header -> Bool)
-> (Header -> Header -> Header)
-> (Header -> Header -> Header)
-> Ord Header
Header -> Header -> Bool
Header -> Header -> Ordering
Header -> Header -> Header
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Header -> Header -> Ordering
compare :: Header -> Header -> Ordering
$c< :: Header -> Header -> Bool
< :: Header -> Header -> Bool
$c<= :: Header -> Header -> Bool
<= :: Header -> Header -> Bool
$c> :: Header -> Header -> Bool
> :: Header -> Header -> Bool
$c>= :: Header -> Header -> Bool
>= :: Header -> Header -> Bool
$cmax :: Header -> Header -> Header
max :: Header -> Header -> Header
$cmin :: Header -> Header -> Header
min :: Header -> Header -> Header
Ord, Eq Header
Header
Eq Header =>
(Header -> Header -> Header)
-> (Header -> Header -> Header)
-> (Header -> Header -> Header)
-> (Header -> Header)
-> (Header -> Int -> Header)
-> (Header -> Int -> Header)
-> Header
-> (Int -> Header)
-> (Header -> Int -> Header)
-> (Header -> Int -> Header)
-> (Header -> Int -> Header)
-> (Header -> Int -> Bool)
-> (Header -> Maybe Int)
-> (Header -> Int)
-> (Header -> Bool)
-> (Header -> Int -> Header)
-> (Header -> Int -> Header)
-> (Header -> Int -> Header)
-> (Header -> Int -> Header)
-> (Header -> Int -> Header)
-> (Header -> Int -> Header)
-> (Header -> Int)
-> Bits Header
Int -> Header
Header -> Bool
Header -> Int
Header -> Maybe Int
Header -> Header
Header -> Int -> Bool
Header -> Int -> Header
Header -> Header -> Header
forall a.
Eq a =>
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> a
-> (Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> Bool)
-> (a -> Maybe Int)
-> (a -> Int)
-> (a -> Bool)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int)
-> Bits a
$c.&. :: Header -> Header -> Header
.&. :: Header -> Header -> Header
$c.|. :: Header -> Header -> Header
.|. :: Header -> Header -> Header
$cxor :: Header -> Header -> Header
xor :: Header -> Header -> Header
$ccomplement :: Header -> Header
complement :: Header -> Header
$cshift :: Header -> Int -> Header
shift :: Header -> Int -> Header
$crotate :: Header -> Int -> Header
rotate :: Header -> Int -> Header
$czeroBits :: Header
zeroBits :: Header
$cbit :: Int -> Header
bit :: Int -> Header
$csetBit :: Header -> Int -> Header
setBit :: Header -> Int -> Header
$cclearBit :: Header -> Int -> Header
clearBit :: Header -> Int -> Header
$ccomplementBit :: Header -> Int -> Header
complementBit :: Header -> Int -> Header
$ctestBit :: Header -> Int -> Bool
testBit :: Header -> Int -> Bool
$cbitSizeMaybe :: Header -> Maybe Int
bitSizeMaybe :: Header -> Maybe Int
$cbitSize :: Header -> Int
bitSize :: Header -> Int
$cisSigned :: Header -> Bool
isSigned :: Header -> Bool
$cshiftL :: Header -> Int -> Header
shiftL :: Header -> Int -> Header
$cunsafeShiftL :: Header -> Int -> Header
unsafeShiftL :: Header -> Int -> Header
$cshiftR :: Header -> Int -> Header
shiftR :: Header -> Int -> Header
$cunsafeShiftR :: Header -> Int -> Header
unsafeShiftR :: Header -> Int -> Header
$crotateL :: Header -> Int -> Header
rotateL :: Header -> Int -> Header
$crotateR :: Header -> Int -> Header
rotateR :: Header -> Int -> Header
$cpopCount :: Header -> Int
popCount :: Header -> Int
Bits, Integer -> Header
Header -> Header
Header -> Header -> Header
(Header -> Header -> Header)
-> (Header -> Header -> Header)
-> (Header -> Header -> Header)
-> (Header -> Header)
-> (Header -> Header)
-> (Header -> Header)
-> (Integer -> Header)
-> Num Header
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
$c+ :: Header -> Header -> Header
+ :: Header -> Header -> Header
$c- :: Header -> Header -> Header
- :: Header -> Header -> Header
$c* :: Header -> Header -> Header
* :: Header -> Header -> Header
$cnegate :: Header -> Header
negate :: Header -> Header
$cabs :: Header -> Header
abs :: Header -> Header
$csignum :: Header -> Header
signum :: Header -> Header
$cfromInteger :: Integer -> Header
fromInteger :: Integer -> Header
Num)

instance Show Header where
  show :: Header -> String
show (Header Word8
header) = (String
"0b" String -> ShowS
forall a. [a] -> [a] -> [a]
++) ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> (Int -> Char) -> Word8 -> ShowS
forall a. Integral a => a -> (Int -> Char) -> a -> ShowS
showIntAtBase Word8
2 Int -> Char
intToDigit Word8
header ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ String
""

-- | Every Byron address starts with @[TkListLen 2]@, which encodes as 130 (or 0x80)
headerByron :: Header
headerByron :: Header
headerByron = Header
0b10000010 -- 0x80

isByronAddress :: Header -> Bool
isByronAddress :: Header -> Bool
isByronAddress = (Header -> Header -> Bool
forall a. Eq a => a -> a -> Bool
== Header
headerByron)
{-# INLINE isByronAddress #-}

headerNonShelleyBits :: Header
headerNonShelleyBits :: Header
headerNonShelleyBits = Header
headerByron Header -> Header -> Header
forall a. Bits a => a -> a -> a
.|. Header
0b00001100

headerNetworkId :: Header -> Network
headerNetworkId :: Header -> Network
headerNetworkId Header
header
  | Header
header Header -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
`testBit` Int
0 = Network
Mainnet
  | Bool
otherwise = Network
Testnet
{-# INLINE headerNetworkId #-}

headerIsPaymentScript :: Header -> Bool
headerIsPaymentScript :: Header -> Bool
headerIsPaymentScript = (Header -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
`testBit` Int
4)
{-# INLINE headerIsPaymentScript #-}

headerIsEnterpriseAddr :: Header -> Bool
headerIsEnterpriseAddr :: Header -> Bool
headerIsEnterpriseAddr = (Header -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
`testBit` Int
5)
{-# INLINE headerIsEnterpriseAddr #-}

headerIsStakingScript :: Header -> Bool
headerIsStakingScript :: Header -> Bool
headerIsStakingScript = (Header -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
`testBit` Int
5)
{-# INLINE headerIsStakingScript #-}

headerIsBaseAddress :: Header -> Bool
headerIsBaseAddress :: Header -> Bool
headerIsBaseAddress = Bool -> Bool
not (Bool -> Bool) -> (Header -> Bool) -> Header -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Header -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
`testBit` Int
6)
{-# INLINE headerIsBaseAddress #-}

-- | Same as `decodeAddr`, but produces an `Either` result
decodeAddrEither ::
  BS.ByteString ->
  Either String Addr
decodeAddrEither :: ByteString -> Either String Addr
decodeAddrEither ByteString
bs = Fail String Addr -> Either String Addr
forall e a. (IsString e, Semigroup e) => Fail e a -> Either e a
runFail (Fail String Addr -> Either String Addr)
-> Fail String Addr -> Either String Addr
forall a b. (a -> b) -> a -> b
$ StateT Int (FailT String Identity) Addr -> Int -> Fail String Addr
forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m a
evalStateT (ByteString -> StateT Int (FailT String Identity) Addr
forall (m :: * -> *) b.
(MonadFail m, AddressBuffer b) =>
b -> StateT Int m Addr
decodeAddrStateT ByteString
bs) Int
0
{-# INLINE decodeAddrEither #-}

-- | Strict decoder for an address from a `ByteString`. This will not let you decode some
-- of the buggy addresses that have been placed on chain. This decoder is intended for
-- addresses that are to be placed on chian today.
decodeAddr ::
  forall m.
  MonadFail m =>
  BS.ByteString ->
  m Addr
decodeAddr :: forall (m :: * -> *). MonadFail m => ByteString -> m Addr
decodeAddr ByteString
bs = StateT Int m Addr -> Int -> m Addr
forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m a
evalStateT (ByteString -> StateT Int m Addr
forall (m :: * -> *) b.
(MonadFail m, AddressBuffer b) =>
b -> StateT Int m Addr
decodeAddrStateT ByteString
bs) Int
0
{-# INLINE decodeAddr #-}

-- | Just like `decodeAddrStateLenientT`, but enforces the address to be well-formed.
decodeAddrStateT ::
  (MonadFail m, AddressBuffer b) =>
  b ->
  StateT Int m Addr
decodeAddrStateT :: forall (m :: * -> *) b.
(MonadFail m, AddressBuffer b) =>
b -> StateT Int m Addr
decodeAddrStateT = Bool -> Bool -> b -> StateT Int m Addr
forall (m :: * -> *) b.
(MonadFail m, AddressBuffer b) =>
Bool -> Bool -> b -> StateT Int m Addr
decodeAddrStateLenientT Bool
False Bool
False
{-# INLINE decodeAddrStateT #-}

-- | This is the most general decoder for a Cardano address. This function is not meant to
-- be used directly, but it is exported for convenice. `decodeAddr` and other should be
-- used instead.
--
-- While decoding an Addr the header (the first byte in the buffer) is expected to be in a
-- certain format. Here are the meaning of all the bits:
--
-- @@@
--
-- ┏━━━━━━━━━━━━━━━━┳━┯━┯━┯━┯━┯━┯━┯━┓
-- ┃  Byron Address ┃1┊0┊0┊0┊0┊0┊1┊0┃
-- ┣━━━━━━━━━━━━━━━━╋━┿━┿━┿━┿━┿━┿━┿━┫
-- ┃Shelley Address ┃0┊x┊x┊x┊0┊0┊0┊x┃
-- ┗━━━━━━━━━━━━━━━━╋━┿━┿━┿━┿━┿━┿━┿━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
--                  ┃0┊0┊0┊0┊0┊0┊0┊0┃ Testnet PaymentKey    StakingKey    ┃
--                  ┃0┊0┊0┊0┊0┊0┊0┊1┃ Mainnet PaymentKey    StakingKey    ┃
--                  ┃0┊0┊0┊1┊0┊0┊0┊0┃ Testnet PaymentScript StakingKey    ┃
--                  ┃0┊0┊0┊1┊0┊0┊0┊1┃ Mainnet PaymentScript StakingKey    ┃
--                  ┃0┊0┊1┊0┊0┊0┊0┊0┃ Testnet PaymentKey    StakingScript ┃
--                  ┃0┊0┊1┊0┊0┊0┊0┊1┃ Mainnet PaymentKey    StakingScript ┃
--                  ┃0┊0┊1┊1┊0┊0┊0┊0┃ Testnet PaymentScript StakingScript ┃
--                  ┃0┊0┊1┊1┊0┊0┊0┊1┃ Mainnet PaymentScript StakingScript ┃
--                  ┃0┊1┊0┊0┊0┊0┊0┊0┃ Testnet PaymentKey    StakingPtr    ┃
--                  ┃0┊1┊0┊0┊0┊0┊0┊1┃ Mainnet PaymentKey    StakingPtr    ┃
--                  ┃0┊1┊0┊1┊0┊0┊0┊0┃ Testnet PaymentScript StakingPtr    ┃
--                  ┃0┊1┊0┊1┊0┊0┊0┊1┃ Mainnet PaymentScript StakingPtr    ┃
--                  ┃0┊1┊1┊0┊0┊0┊0┊0┃ Testnet PaymentKey    StakingNull   ┃
--                  ┃0┊1┊1┊0┊0┊0┊0┊1┃ Mainnet PaymentKey    StakingNull   ┃
--                  ┃0┊1┊1┊1┊0┊0┊0┊0┃ Testnet PaymentScript StakingNull   ┃
--                  ┃0┊1┊1┊1┊0┊0┊0┊1┃ Mainnet PaymentScript StakingNull   ┃
--                  ┗━┷━┷━┷━┷━┷━┷━┷━┻━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
--                      \ \ \       \
--                       \ \ \       `Is Mainnet Address
--                        \ \ `Payment Credential is a Script
--                         \ `Staking Credential is a Script / No Staking Credential
--                          `Not a Base Address
-- @@@
decodeAddrStateLenientT ::
  (MonadFail m, AddressBuffer b) =>
  -- | Enable lenient decoding for Ptrs, i.e. indicate whether junk can follow a Ptr. This
  -- is necessary for backwards compatibility only.  Setting this argument to True is only
  -- needed for backwards compatibility.
  Bool ->
  -- | Indicate whether decoder should not enforce the full input to be consumed or not,
  -- i.e. allow garbage at the end or not. Setting this argument to True is only needed
  -- for backwards compatibility.
  Bool ->
  b ->
  StateT Int m Addr
decodeAddrStateLenientT :: forall (m :: * -> *) b.
(MonadFail m, AddressBuffer b) =>
Bool -> Bool -> b -> StateT Int m Addr
decodeAddrStateLenientT Bool
isPtrLenient Bool
isLenient b
buf = do
  String -> Int -> b -> StateT Int m ()
forall (m :: * -> *) b.
(MonadFail m, AddressBuffer b) =>
String -> Int -> b -> StateT Int m ()
guardLength String
"Header" Int
1 b
buf
  let header :: Header
header = Word8 -> Header
Header (Word8 -> Header) -> Word8 -> Header
forall a b. (a -> b) -> a -> b
$ b -> Int -> Word8
forall b. AddressBuffer b => b -> Int -> Word8
bufUnsafeIndex b
buf Int
0
  Addr
addr <-
    if Header -> Bool
isByronAddress Header
header
      then BootstrapAddress -> Addr
AddrBootstrap (BootstrapAddress -> Addr)
-> StateT Int m BootstrapAddress -> StateT Int m Addr
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> b -> StateT Int m BootstrapAddress
forall (m :: * -> *) b.
(MonadFail m, AddressBuffer b) =>
b -> StateT Int m BootstrapAddress
decodeBootstrapAddress b
buf
      else do
        -- Ensure there are no unexpected bytes in the header
        Bool -> StateT Int m () -> StateT Int m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Header
header Header -> Header -> Header
forall a. Bits a => a -> a -> a
.&. Header
headerNonShelleyBits Header -> Header -> Bool
forall a. Eq a => a -> a -> Bool
== Header
0)
          (StateT Int m () -> StateT Int m ())
-> StateT Int m () -> StateT Int m ()
forall a b. (a -> b) -> a -> b
$ String -> String -> StateT Int m ()
forall (m :: * -> *) a. MonadFail m => String -> String -> m a
failDecoding
            String
"Shelley Address"
          (String -> StateT Int m ()) -> String -> StateT Int m ()
forall a b. (a -> b) -> a -> b
$ String
"Invalid header. Unused bits are not suppose to be set: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Header -> String
forall a. Show a => a -> String
show Header
header
        -- Advance one byte for the consumed header
        (Int -> Int) -> StateT Int m ()
forall (m :: * -> *) s. Monad m => (s -> s) -> StateT s m ()
modify' (Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
        PaymentCredential
payment <- Header -> b -> StateT Int m PaymentCredential
forall (m :: * -> *) b.
(MonadFail m, AddressBuffer b) =>
Header -> b -> StateT Int m PaymentCredential
decodePaymentCredential Header
header b
buf
        StakeReference
staking <- Bool -> Header -> b -> StateT Int m StakeReference
forall (m :: * -> *) b.
(MonadFail m, AddressBuffer b) =>
Bool -> Header -> b -> StateT Int m StakeReference
decodeStakeReference Bool
isPtrLenient Header
header b
buf
        Addr -> StateT Int m Addr
forall a. a -> StateT Int m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Addr -> StateT Int m Addr) -> Addr -> StateT Int m Addr
forall a b. (a -> b) -> a -> b
$ Network -> PaymentCredential -> StakeReference -> Addr
Addr (Header -> Network
headerNetworkId Header
header) PaymentCredential
payment StakeReference
staking
  Bool -> StateT Int m () -> StateT Int m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
isLenient (StateT Int m () -> StateT Int m ())
-> StateT Int m () -> StateT Int m ()
forall a b. (a -> b) -> a -> b
$
    String -> b -> StateT Int m ()
forall (m :: * -> *) b.
(MonadFail m, AddressBuffer b) =>
String -> b -> StateT Int m ()
ensureBufIsConsumed String
"Addr" b
buf
  Addr -> StateT Int m Addr
forall a. a -> StateT Int m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Addr
addr
{-# INLINE decodeAddrStateLenientT #-}

-- | Checks that the current offset is exactly at the end of the buffer.
ensureBufIsConsumed ::
  forall m b.
  (MonadFail m, AddressBuffer b) =>
  -- | Name for error reporting
  String ->
  -- | Buffer that should have been consumed.
  b ->
  StateT Int m ()
ensureBufIsConsumed :: forall (m :: * -> *) b.
(MonadFail m, AddressBuffer b) =>
String -> b -> StateT Int m ()
ensureBufIsConsumed String
name b
buf = do
  Int
lastOffset <- StateT Int m Int
forall (m :: * -> *) s. Monad m => StateT s m s
get
  let len :: Int
len = b -> Int
forall b. AddressBuffer b => b -> Int
bufLength b
buf
  Bool -> StateT Int m () -> StateT Int m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Int
lastOffset Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
len) (StateT Int m () -> StateT Int m ())
-> StateT Int m () -> StateT Int m ()
forall a b. (a -> b) -> a -> b
$
    String -> String -> StateT Int m ()
forall (m :: * -> *) a. MonadFail m => String -> String -> m a
failDecoding String
name (String -> StateT Int m ()) -> String -> StateT Int m ()
forall a b. (a -> b) -> a -> b
$
      String
"Left over bytes: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show (Int
len Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
lastOffset)
{-# INLINE ensureBufIsConsumed #-}

-- | This decoder assumes the whole `ShortByteString` is occupied by the `BootstrapAddress`
decodeBootstrapAddress ::
  forall m b.
  (MonadFail m, AddressBuffer b) =>
  b ->
  StateT Int m BootstrapAddress
decodeBootstrapAddress :: forall (m :: * -> *) b.
(MonadFail m, AddressBuffer b) =>
b -> StateT Int m BootstrapAddress
decodeBootstrapAddress b
buf =
  case Version -> ByteString -> Either DecoderError Address
forall a.
DecCBOR a =>
Version -> ByteString -> Either DecoderError a
decodeFull' Version
byronProtVer (ByteString -> Either DecoderError Address)
-> ByteString -> Either DecoderError Address
forall a b. (a -> b) -> a -> b
$ b -> ByteString
forall b. AddressBuffer b => b -> ByteString
bufToByteString b
buf of
    Left DecoderError
e -> String -> StateT Int m BootstrapAddress
forall a. String -> StateT Int m a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> StateT Int m BootstrapAddress)
-> String -> StateT Int m BootstrapAddress
forall a b. (a -> b) -> a -> b
$ DecoderError -> String
forall a. Show a => a -> String
show DecoderError
e
    Right Address
addr -> Address -> BootstrapAddress
BootstrapAddress Address
addr BootstrapAddress
-> StateT Int m () -> StateT Int m BootstrapAddress
forall a b. a -> StateT Int m b -> StateT Int m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ (Int -> Int) -> StateT Int m ()
forall (m :: * -> *) s. Monad m => (s -> s) -> StateT s m ()
modify' (Int -> Int -> Int
forall a. Num a => a -> a -> a
+ b -> Int
forall b. AddressBuffer b => b -> Int
bufLength b
buf)
{-# INLINE decodeBootstrapAddress #-}

decodePaymentCredential ::
  (MonadFail m, AddressBuffer b) =>
  Header ->
  b ->
  StateT Int m PaymentCredential
decodePaymentCredential :: forall (m :: * -> *) b.
(MonadFail m, AddressBuffer b) =>
Header -> b -> StateT Int m PaymentCredential
decodePaymentCredential Header
header b
buf
  | Header -> Bool
headerIsPaymentScript Header
header = ScriptHash -> PaymentCredential
forall (kr :: KeyRole). ScriptHash -> Credential kr
ScriptHashObj (ScriptHash -> PaymentCredential)
-> StateT Int m ScriptHash -> StateT Int m PaymentCredential
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> b -> StateT Int m ScriptHash
forall (m :: * -> *) b.
(MonadFail m, AddressBuffer b) =>
b -> StateT Int m ScriptHash
decodeScriptHash b
buf
  | Bool
otherwise = KeyHash 'Payment -> PaymentCredential
forall (kr :: KeyRole). KeyHash kr -> Credential kr
KeyHashObj (KeyHash 'Payment -> PaymentCredential)
-> StateT Int m (KeyHash 'Payment)
-> StateT Int m PaymentCredential
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> b -> StateT Int m (KeyHash 'Payment)
forall (m :: * -> *) b (kr :: KeyRole).
(MonadFail m, AddressBuffer b) =>
b -> StateT Int m (KeyHash kr)
decodeKeyHash b
buf
{-# INLINE decodePaymentCredential #-}

decodeStakeReference ::
  (MonadFail m, AddressBuffer b) =>
  Bool ->
  Header ->
  b ->
  StateT Int m StakeReference
decodeStakeReference :: forall (m :: * -> *) b.
(MonadFail m, AddressBuffer b) =>
Bool -> Header -> b -> StateT Int m StakeReference
decodeStakeReference Bool
isLenientPtrDecoder Header
header b
buf
  | Header -> Bool
headerIsBaseAddress Header
header =
      if Header -> Bool
headerIsStakingScript Header
header
        then Credential 'Staking -> StakeReference
StakeRefBase (Credential 'Staking -> StakeReference)
-> (ScriptHash -> Credential 'Staking)
-> ScriptHash
-> StakeReference
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ScriptHash -> Credential 'Staking
forall (kr :: KeyRole). ScriptHash -> Credential kr
ScriptHashObj (ScriptHash -> StakeReference)
-> StateT Int m ScriptHash -> StateT Int m StakeReference
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> b -> StateT Int m ScriptHash
forall (m :: * -> *) b.
(MonadFail m, AddressBuffer b) =>
b -> StateT Int m ScriptHash
decodeScriptHash b
buf
        else Credential 'Staking -> StakeReference
StakeRefBase (Credential 'Staking -> StakeReference)
-> (KeyHash 'Staking -> Credential 'Staking)
-> KeyHash 'Staking
-> StakeReference
forall b c a. (b -> c) -> (a -> b) -> a -> c
. KeyHash 'Staking -> Credential 'Staking
forall (kr :: KeyRole). KeyHash kr -> Credential kr
KeyHashObj (KeyHash 'Staking -> StakeReference)
-> StateT Int m (KeyHash 'Staking) -> StateT Int m StakeReference
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> b -> StateT Int m (KeyHash 'Staking)
forall (m :: * -> *) b (kr :: KeyRole).
(MonadFail m, AddressBuffer b) =>
b -> StateT Int m (KeyHash kr)
decodeKeyHash b
buf
  | Bool
otherwise =
      if Header -> Bool
headerIsEnterpriseAddr Header
header
        then StakeReference -> StateT Int m StakeReference
forall a. a -> StateT Int m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure StakeReference
StakeRefNull
        else Ptr -> StakeReference
StakeRefPtr (Ptr -> StakeReference)
-> StateT Int m Ptr -> StateT Int m StakeReference
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> if Bool
isLenientPtrDecoder then b -> StateT Int m Ptr
forall (m :: * -> *) b.
(MonadFail m, AddressBuffer b) =>
b -> StateT Int m Ptr
decodePtrLenient b
buf else b -> StateT Int m Ptr
forall (m :: * -> *) b.
(MonadFail m, AddressBuffer b) =>
b -> StateT Int m Ptr
decodePtr b
buf
{-# INLINE decodeStakeReference #-}

decodeKeyHash ::
  (MonadFail m, AddressBuffer b) =>
  b ->
  StateT Int m (KeyHash kr)
decodeKeyHash :: forall (m :: * -> *) b (kr :: KeyRole).
(MonadFail m, AddressBuffer b) =>
b -> StateT Int m (KeyHash kr)
decodeKeyHash b
buf = Hash ADDRHASH (VerKeyDSIGN DSIGN) -> KeyHash kr
forall (r :: KeyRole).
Hash ADDRHASH (VerKeyDSIGN DSIGN) -> KeyHash r
KeyHash (Hash ADDRHASH (VerKeyDSIGN DSIGN) -> KeyHash kr)
-> StateT Int m (Hash ADDRHASH (VerKeyDSIGN DSIGN))
-> StateT Int m (KeyHash kr)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> b -> StateT Int m (Hash ADDRHASH (VerKeyDSIGN DSIGN))
forall a h (m :: * -> *) b.
(HashAlgorithm h, MonadFail m, AddressBuffer b) =>
b -> StateT Int m (Hash h a)
decodeHash b
buf
{-# INLINE decodeKeyHash #-}

decodeScriptHash ::
  (MonadFail m, AddressBuffer b) =>
  b ->
  StateT Int m ScriptHash
decodeScriptHash :: forall (m :: * -> *) b.
(MonadFail m, AddressBuffer b) =>
b -> StateT Int m ScriptHash
decodeScriptHash b
buf = Hash ADDRHASH EraIndependentScript -> ScriptHash
ScriptHash (Hash ADDRHASH EraIndependentScript -> ScriptHash)
-> StateT Int m (Hash ADDRHASH EraIndependentScript)
-> StateT Int m ScriptHash
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> b -> StateT Int m (Hash ADDRHASH EraIndependentScript)
forall a h (m :: * -> *) b.
(HashAlgorithm h, MonadFail m, AddressBuffer b) =>
b -> StateT Int m (Hash h a)
decodeHash b
buf
{-# INLINE decodeScriptHash #-}

decodeHash ::
  forall a h m b.
  (Hash.HashAlgorithm h, MonadFail m, AddressBuffer b) =>
  b ->
  StateT Int m (Hash.Hash h a)
decodeHash :: forall a h (m :: * -> *) b.
(HashAlgorithm h, MonadFail m, AddressBuffer b) =>
b -> StateT Int m (Hash h a)
decodeHash b
buf = do
  Int
offset <- StateT Int m Int
forall (m :: * -> *) s. Monad m => StateT s m s
get
  case b -> Int -> Maybe (Hash h a)
forall b h a.
(AddressBuffer b, HashAlgorithm h) =>
b -> Int -> Maybe (Hash h a)
forall h a. HashAlgorithm h => b -> Int -> Maybe (Hash h a)
bufGetHash b
buf Int
offset of
    Just Hash h a
h -> Hash h a
h Hash h a -> StateT Int m () -> StateT Int m (Hash h a)
forall a b. a -> StateT Int m b -> StateT Int m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ (Int -> Int) -> StateT Int m ()
forall (m :: * -> *) s. Monad m => (s -> s) -> StateT s m ()
modify' (Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
hashLen)
    Maybe (Hash h a)
Nothing
      | Int
offset Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 ->
          String -> String -> StateT Int m (Hash h a)
forall (m :: * -> *) a. MonadFail m => String -> String -> m a
failDecoding String
"Hash" (String -> StateT Int m (Hash h a))
-> String -> StateT Int m (Hash h a)
forall a b. (a -> b) -> a -> b
$
            String
"Not enough bytes supplied: "
              String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show (b -> Int
forall b. AddressBuffer b => b -> Int
bufLength b
buf Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
offset)
              String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
". Expected: "
              String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
hashLen
    Maybe (Hash h a)
Nothing -> String -> StateT Int m (Hash h a)
forall a. String -> StateT Int m a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Impossible: Negative offset"
  where
    hashLen :: Int
    hashLen :: Int
hashLen = Word -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Proxy h -> Word
forall h (proxy :: * -> *). HashAlgorithm h => proxy h -> Word
Hash.sizeHash (Proxy h
forall {k} (t :: k). Proxy t
Proxy :: Proxy h))
{-# INLINE decodeHash #-}

decodePtr ::
  (MonadFail m, AddressBuffer b) =>
  b ->
  StateT Int m Ptr
decodePtr :: forall (m :: * -> *) b.
(MonadFail m, AddressBuffer b) =>
b -> StateT Int m Ptr
decodePtr b
buf =
  SlotNo32 -> TxIx -> CertIx -> Ptr
Ptr
    (SlotNo32 -> TxIx -> CertIx -> Ptr)
-> StateT Int m SlotNo32 -> StateT Int m (TxIx -> CertIx -> Ptr)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Word32 -> SlotNo32
SlotNo32 (Word32 -> SlotNo32)
-> StateT Int m Word32 -> StateT Int m SlotNo32
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> b -> StateT Int m Word32
forall (m :: * -> *) b.
(MonadFail m, AddressBuffer b) =>
String -> b -> StateT Int m Word32
decodeVariableLengthWord32 String
"SlotNo" b
buf)
    StateT Int m (TxIx -> CertIx -> Ptr)
-> StateT Int m TxIx -> StateT Int m (CertIx -> Ptr)
forall a b.
StateT Int m (a -> b) -> StateT Int m a -> StateT Int m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Word16 -> TxIx
TxIx (Word16 -> TxIx) -> StateT Int m Word16 -> StateT Int m TxIx
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> b -> StateT Int m Word16
forall (m :: * -> *) b.
(MonadFail m, AddressBuffer b) =>
String -> b -> StateT Int m Word16
decodeVariableLengthWord16 String
"TxIx" b
buf)
    StateT Int m (CertIx -> Ptr)
-> StateT Int m CertIx -> StateT Int m Ptr
forall a b.
StateT Int m (a -> b) -> StateT Int m a -> StateT Int m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Word16 -> CertIx
CertIx (Word16 -> CertIx) -> StateT Int m Word16 -> StateT Int m CertIx
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> b -> StateT Int m Word16
forall (m :: * -> *) b.
(MonadFail m, AddressBuffer b) =>
String -> b -> StateT Int m Word16
decodeVariableLengthWord16 String
"CertIx" b
buf)
{-# INLINE decodePtr #-}

decodePtrLenient ::
  (MonadFail m, AddressBuffer b) =>
  b ->
  StateT Int m Ptr
decodePtrLenient :: forall (m :: * -> *) b.
(MonadFail m, AddressBuffer b) =>
b -> StateT Int m Ptr
decodePtrLenient b
buf =
  Word64 -> Word64 -> Word64 -> Ptr
mkPtrNormalized
    (Word64 -> Word64 -> Word64 -> Ptr)
-> StateT Int m Word64 -> StateT Int m (Word64 -> Word64 -> Ptr)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> b -> StateT Int m Word64
forall (m :: * -> *) b.
(MonadFail m, AddressBuffer b) =>
String -> b -> StateT Int m Word64
decodeVariableLengthWord64 String
"SlotNo" b
buf
    StateT Int m (Word64 -> Word64 -> Ptr)
-> StateT Int m Word64 -> StateT Int m (Word64 -> Ptr)
forall a b.
StateT Int m (a -> b) -> StateT Int m a -> StateT Int m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String -> b -> StateT Int m Word64
forall (m :: * -> *) b.
(MonadFail m, AddressBuffer b) =>
String -> b -> StateT Int m Word64
decodeVariableLengthWord64 String
"TxIx" b
buf
    StateT Int m (Word64 -> Ptr)
-> StateT Int m Word64 -> StateT Int m Ptr
forall a b.
StateT Int m (a -> b) -> StateT Int m a -> StateT Int m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String -> b -> StateT Int m Word64
forall (m :: * -> *) b.
(MonadFail m, AddressBuffer b) =>
String -> b -> StateT Int m Word64
decodeVariableLengthWord64 String
"CertIx" b
buf
{-# INLINE decodePtrLenient #-}

guardLength ::
  (MonadFail m, AddressBuffer b) =>
  -- | Name for what is being decoded for the error message
  String ->
  Int ->
  b ->
  StateT Int m ()
guardLength :: forall (m :: * -> *) b.
(MonadFail m, AddressBuffer b) =>
String -> Int -> b -> StateT Int m ()
guardLength String
name Int
expectedLength b
buf = do
  Int
offset <- StateT Int m Int
forall (m :: * -> *) s. Monad m => StateT s m s
get
  Bool -> StateT Int m () -> StateT Int m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
offset Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> b -> Int
forall b. AddressBuffer b => b -> Int
bufLength b
buf Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
expectedLength) (StateT Int m () -> StateT Int m ())
-> StateT Int m () -> StateT Int m ()
forall a b. (a -> b) -> a -> b
$
    String -> String -> StateT Int m ()
forall (m :: * -> *) a. MonadFail m => String -> String -> m a
failDecoding String
name String
"Not enough bytes for decoding"
{-# INLINE guardLength #-}

-- | Decode a variable length integral value that is encoded with 7 bits of data
-- and the most significant bit (MSB), the 8th bit is set whenever there are
-- more bits following. Continuation style allows us to avoid
-- rucursion. Removing loops is good for performance.
decode7BitVarLength ::
  (Num a, Bits a, AddressBuffer b, MonadFail m) =>
  -- | Name of what is being decoded for error reporting
  String ->
  -- | Buffer that contains encoded number
  b ->
  -- | Continuation that will be invoked if MSB is set
  (a -> StateT Int m a) ->
  -- | Accumulator
  a ->
  StateT Int m a
decode7BitVarLength :: forall a b (m :: * -> *).
(Num a, Bits a, AddressBuffer b, MonadFail m) =>
String -> b -> (a -> StateT Int m a) -> a -> StateT Int m a
decode7BitVarLength String
name b
buf a -> StateT Int m a
cont !a
acc = do
  String -> Int -> b -> StateT Int m ()
forall (m :: * -> *) b.
(MonadFail m, AddressBuffer b) =>
String -> Int -> b -> StateT Int m ()
guardLength String
name Int
1 b
buf
  Int
offset <- (Int -> (Int, Int)) -> StateT Int m Int
forall (m :: * -> *) s a. Monad m => (s -> (a, s)) -> StateT s m a
state (\Int
off -> (Int
off, Int
off Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1))
  let b8 :: Word8
b8 = b -> Int -> Word8
forall b. AddressBuffer b => b -> Int -> Word8
bufUnsafeIndex b
buf Int
offset
  if Word8
b8 Word8 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
`testBit` Int
7
    then a -> StateT Int m a
cont (a
acc a -> Int -> a
forall a. Bits a => a -> Int -> a
`shiftL` Int
7 a -> a -> a
forall a. Bits a => a -> a -> a
.|. Word8 -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8
b8 Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
`clearBit` Int
7))
    else a -> StateT Int m a
forall a. a -> StateT Int m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (a
acc a -> Int -> a
forall a. Bits a => a -> Int -> a
`shiftL` Int
7 a -> a -> a
forall a. Bits a => a -> a -> a
.|. Word8 -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
b8)
{-# INLINE decode7BitVarLength #-}

failDecoding :: MonadFail m => String -> String -> m a
failDecoding :: forall (m :: * -> *) a. MonadFail m => String -> String -> m a
failDecoding String
name String
msg = String -> m a
forall a. String -> m a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> m a) -> String -> m a
forall a b. (a -> b) -> a -> b
$ String
"Decoding " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
name String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
": " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
msg
{-# NOINLINE failDecoding #-}

decodeVariableLengthWord16 ::
  forall m b.
  (MonadFail m, AddressBuffer b) =>
  String ->
  b ->
  StateT Int m Word16
decodeVariableLengthWord16 :: forall (m :: * -> *) b.
(MonadFail m, AddressBuffer b) =>
String -> b -> StateT Int m Word16
decodeVariableLengthWord16 String
name b
buf = do
  Int
off0 <- StateT Int m Int
forall (m :: * -> *) s. Monad m => StateT s m s
get
  let d7 :: (Word16 -> StateT Int m Word16) -> Word16 -> StateT Int m Word16
d7 = String
-> b
-> (Word16 -> StateT Int m Word16)
-> Word16
-> StateT Int m Word16
forall a b (m :: * -> *).
(Num a, Bits a, AddressBuffer b, MonadFail m) =>
String -> b -> (a -> StateT Int m a) -> a -> StateT Int m a
decode7BitVarLength String
name b
buf
      d7last :: Word16 -> StateT Int m Word16
      d7last :: Word16 -> StateT Int m Word16
d7last Word16
acc = do
        Word16
res <- String
-> b
-> (Word16 -> StateT Int m Word16)
-> Word16
-> StateT Int m Word16
forall a b (m :: * -> *).
(Num a, Bits a, AddressBuffer b, MonadFail m) =>
String -> b -> (a -> StateT Int m a) -> a -> StateT Int m a
decode7BitVarLength String
name b
buf (\Word16
_ -> String -> String -> StateT Int m Word16
forall (m :: * -> *) a. MonadFail m => String -> String -> m a
failDecoding String
name String
"too many bytes.") Word16
acc
        -- Only while decoding the last 7bits we check if there was too many
        -- bits supplied at the beginning.
        Bool -> StateT Int m () -> StateT Int m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (b -> Int -> Word8
forall b. AddressBuffer b => b -> Int -> Word8
bufUnsafeIndex b
buf Int
off0 Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.&. Word8
0b11111100 Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
0b10000000) (StateT Int m () -> StateT Int m ())
-> StateT Int m () -> StateT Int m ()
forall a b. (a -> b) -> a -> b
$
          String -> String -> StateT Int m ()
forall (m :: * -> *) a. MonadFail m => String -> String -> m a
failDecoding String
name String
"More than 16bits was supplied"
        Word16 -> StateT Int m Word16
forall a. a -> StateT Int m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Word16
res
  (Word16 -> StateT Int m Word16) -> Word16 -> StateT Int m Word16
d7 ((Word16 -> StateT Int m Word16) -> Word16 -> StateT Int m Word16
d7 Word16 -> StateT Int m Word16
d7last) Word16
0
{-# INLINE decodeVariableLengthWord16 #-}

decodeVariableLengthWord32 ::
  forall m b.
  (MonadFail m, AddressBuffer b) =>
  String ->
  b ->
  StateT Int m Word32
decodeVariableLengthWord32 :: forall (m :: * -> *) b.
(MonadFail m, AddressBuffer b) =>
String -> b -> StateT Int m Word32
decodeVariableLengthWord32 String
name b
buf = do
  Int
off0 <- StateT Int m Int
forall (m :: * -> *) s. Monad m => StateT s m s
get
  let d7 :: (Word32 -> StateT Int m Word32) -> Word32 -> StateT Int m Word32
d7 = String
-> b
-> (Word32 -> StateT Int m Word32)
-> Word32
-> StateT Int m Word32
forall a b (m :: * -> *).
(Num a, Bits a, AddressBuffer b, MonadFail m) =>
String -> b -> (a -> StateT Int m a) -> a -> StateT Int m a
decode7BitVarLength String
name b
buf
      {-# INLINE d7 #-}
      d7last :: Word32 -> StateT Int m Word32
      d7last :: Word32 -> StateT Int m Word32
d7last Word32
acc = do
        Word32
res <- String
-> b
-> (Word32 -> StateT Int m Word32)
-> Word32
-> StateT Int m Word32
forall a b (m :: * -> *).
(Num a, Bits a, AddressBuffer b, MonadFail m) =>
String -> b -> (a -> StateT Int m a) -> a -> StateT Int m a
decode7BitVarLength String
name b
buf (\Word32
_ -> String -> String -> StateT Int m Word32
forall (m :: * -> *) a. MonadFail m => String -> String -> m a
failDecoding String
name String
"too many bytes.") Word32
acc
        -- Only while decoding the last 7bits we check if there was too many
        -- bits supplied at the beginning.
        Bool -> StateT Int m () -> StateT Int m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (b -> Int -> Word8
forall b. AddressBuffer b => b -> Int -> Word8
bufUnsafeIndex b
buf Int
off0 Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.&. Word8
0b11110000 Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
0b10000000) (StateT Int m () -> StateT Int m ())
-> StateT Int m () -> StateT Int m ()
forall a b. (a -> b) -> a -> b
$
          String -> String -> StateT Int m ()
forall (m :: * -> *) a. MonadFail m => String -> String -> m a
failDecoding String
name String
"More than 32bits was supplied"
        Word32 -> StateT Int m Word32
forall a. a -> StateT Int m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Word32
res
      {-# INLINE d7last #-}
  (Word32 -> StateT Int m Word32) -> Word32 -> StateT Int m Word32
d7 ((Word32 -> StateT Int m Word32) -> Word32 -> StateT Int m Word32
d7 ((Word32 -> StateT Int m Word32) -> Word32 -> StateT Int m Word32
d7 ((Word32 -> StateT Int m Word32) -> Word32 -> StateT Int m Word32
d7 Word32 -> StateT Int m Word32
d7last))) Word32
0
{-# INLINE decodeVariableLengthWord32 #-}

-- | This decoder is here only with the purpose of preserving old buggy behavior. Should
-- not be used for anything else.
decodeVariableLengthWord64 ::
  forall m b.
  (MonadFail m, AddressBuffer b) =>
  String ->
  b ->
  StateT Int m Word64
decodeVariableLengthWord64 :: forall (m :: * -> *) b.
(MonadFail m, AddressBuffer b) =>
String -> b -> StateT Int m Word64
decodeVariableLengthWord64 String
name b
buf = ((Word64 -> StateT Int m Word64) -> Word64 -> StateT Int m Word64)
-> Word64 -> StateT Int m Word64
forall a. (a -> a) -> a
fix (String
-> b
-> (Word64 -> StateT Int m Word64)
-> Word64
-> StateT Int m Word64
forall a b (m :: * -> *).
(Num a, Bits a, AddressBuffer b, MonadFail m) =>
String -> b -> (a -> StateT Int m a) -> a -> StateT Int m a
decode7BitVarLength String
name b
buf) Word64
0
{-# INLINE decodeVariableLengthWord64 #-}

------------------------------------------------------------------------------------------
-- Reward Account Deserializer -----------------------------------------------------------
------------------------------------------------------------------------------------------

decodeRewardAccount ::
  forall b m.
  (AddressBuffer b, MonadFail m) =>
  b ->
  m RewardAccount
decodeRewardAccount :: forall b (m :: * -> *).
(AddressBuffer b, MonadFail m) =>
b -> m RewardAccount
decodeRewardAccount b
buf = StateT Int m RewardAccount -> Int -> m RewardAccount
forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m a
evalStateT (b -> StateT Int m RewardAccount
forall (m :: * -> *) b.
(MonadFail m, AddressBuffer b) =>
b -> StateT Int m RewardAccount
decodeRewardAccountT b
buf) Int
0

fromCborRewardAccount :: Decoder s RewardAccount
fromCborRewardAccount :: forall s. Decoder s RewardAccount
fromCborRewardAccount = do
  ShortByteString
sbs :: ShortByteString <- Decoder s ShortByteString
forall s. Decoder s ShortByteString
forall a s. DecCBOR a => Decoder s a
decCBOR
  ShortByteString -> Decoder s RewardAccount
forall b (m :: * -> *).
(AddressBuffer b, MonadFail m) =>
b -> m RewardAccount
decodeRewardAccount ShortByteString
sbs

headerIsRewardAccount :: Header -> Bool
headerIsRewardAccount :: Header -> Bool
headerIsRewardAccount Header
header = Header
header Header -> Header -> Header
forall a. Bits a => a -> a -> a
.&. Header
0b11101110 Header -> Header -> Bool
forall a. Eq a => a -> a -> Bool
== Header
0b11100000
{-# INLINE headerIsRewardAccount #-}

headerRewardAccountIsScript :: Header -> Bool
headerRewardAccountIsScript :: Header -> Bool
headerRewardAccountIsScript = (Header -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
`testBit` Int
4)
{-# INLINE headerRewardAccountIsScript #-}

-- | Reward Account Header.
--
-- @@@
--
-- ┏━━━━━━━━━━━━━━━━┳━┯━┯━┯━┯━┯━┯━┯━┓
-- ┃ Reward Account ┃1┊1┊1┊x┊0┊0┊0┊x┃
-- ┗━━━━━━━━━━━━━━━━╋━┿━┿━┿━┿━┿━┿━┿━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
--                  ┃1┊1┊1┊0┊0┊0┊0┊0┃ Testnet PaymentKey    StakingKey    ┃
--                  ┃1┊1┊1┊0┊0┊0┊0┊1┃ Mainnet PaymentKey    StakingKey    ┃
--                  ┃1┊1┊1┊1┊0┊0┊0┊0┃ Testnet PaymentScript StakingKey    ┃
--                  ┃1┊1┊1┊1┊0┊0┊0┊1┃ Mainnet PaymentScript StakingKey    ┃
--                  ┗━┷━┷━┷━┷━┷━┷━┷━┻━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
--                          \       \
--                           \       `Is Mainnet Address
--                            `Account Credential is a Script
-- @@@
decodeRewardAccountT ::
  (MonadFail m, AddressBuffer b) =>
  b ->
  StateT Int m RewardAccount
decodeRewardAccountT :: forall (m :: * -> *) b.
(MonadFail m, AddressBuffer b) =>
b -> StateT Int m RewardAccount
decodeRewardAccountT b
buf = do
  String -> Int -> b -> StateT Int m ()
forall (m :: * -> *) b.
(MonadFail m, AddressBuffer b) =>
String -> Int -> b -> StateT Int m ()
guardLength String
"Header" Int
1 b
buf
  (Int -> Int) -> StateT Int m ()
forall (m :: * -> *) s. Monad m => (s -> s) -> StateT s m ()
modify' (Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
  let header :: Header
header = Word8 -> Header
Header (Word8 -> Header) -> Word8 -> Header
forall a b. (a -> b) -> a -> b
$ b -> Int -> Word8
forall b. AddressBuffer b => b -> Int -> Word8
bufUnsafeIndex b
buf Int
0
  Bool -> StateT Int m () -> StateT Int m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Header -> Bool
headerIsRewardAccount Header
header) (StateT Int m () -> StateT Int m ())
-> StateT Int m () -> StateT Int m ()
forall a b. (a -> b) -> a -> b
$
    String -> StateT Int m ()
forall a. String -> StateT Int m a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> StateT Int m ()) -> String -> StateT Int m ()
forall a b. (a -> b) -> a -> b
$
      String
"Invalid header for the reward account: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Header -> String
forall a. Show a => a -> String
show Header
header
  Credential 'Staking
account <-
    if Header -> Bool
headerRewardAccountIsScript Header
header
      then ScriptHash -> Credential 'Staking
forall (kr :: KeyRole). ScriptHash -> Credential kr
ScriptHashObj (ScriptHash -> Credential 'Staking)
-> StateT Int m ScriptHash -> StateT Int m (Credential 'Staking)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> b -> StateT Int m ScriptHash
forall (m :: * -> *) b.
(MonadFail m, AddressBuffer b) =>
b -> StateT Int m ScriptHash
decodeScriptHash b
buf
      else KeyHash 'Staking -> Credential 'Staking
forall (kr :: KeyRole). KeyHash kr -> Credential kr
KeyHashObj (KeyHash 'Staking -> Credential 'Staking)
-> StateT Int m (KeyHash 'Staking)
-> StateT Int m (Credential 'Staking)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> b -> StateT Int m (KeyHash 'Staking)
forall (m :: * -> *) b (kr :: KeyRole).
(MonadFail m, AddressBuffer b) =>
b -> StateT Int m (KeyHash kr)
decodeKeyHash b
buf
  String -> b -> StateT Int m ()
forall (m :: * -> *) b.
(MonadFail m, AddressBuffer b) =>
String -> b -> StateT Int m ()
ensureBufIsConsumed String
"RewardsAcnt" b
buf
  RewardAccount -> StateT Int m RewardAccount
forall a. a -> StateT Int m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (RewardAccount -> StateT Int m RewardAccount)
-> RewardAccount -> StateT Int m RewardAccount
forall a b. (a -> b) -> a -> b
$! Network -> Credential 'Staking -> RewardAccount
RewardAccount (Header -> Network
headerNetworkId Header
header) Credential 'Staking
account
{-# INLINE decodeRewardAccountT #-}

instance EncCBOR CompactAddr where
  encCBOR :: CompactAddr -> Encoding
encCBOR (UnsafeCompactAddr ShortByteString
bytes) = ShortByteString -> Encoding
forall a. EncCBOR a => a -> Encoding
encCBOR ShortByteString
bytes
  {-# INLINE encCBOR #-}

instance DecCBOR CompactAddr where
  decCBOR :: forall s. Decoder s CompactAddr
decCBOR = Decoder s CompactAddr
forall s. Decoder s CompactAddr
fromCborCompactAddr
  {-# INLINE decCBOR #-}

-- | Efficiently check whether compacted adddress is an address with a credential
-- that is a payment script.
isPayCredScriptCompactAddr :: CompactAddr -> Bool
isPayCredScriptCompactAddr :: CompactAddr -> Bool
isPayCredScriptCompactAddr (UnsafeCompactAddr ShortByteString
bytes) =
  Word8 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit (HasCallStack => ShortByteString -> Int -> Word8
ShortByteString -> Int -> Word8
SBS.index ShortByteString
bytes Int
0) Int
payCredIsScript

-- | Efficiently check whether compated adddress is a Byron address.
isBootstrapCompactAddr :: CompactAddr -> Bool
isBootstrapCompactAddr :: CompactAddr -> Bool
isBootstrapCompactAddr (UnsafeCompactAddr ShortByteString
bytes) = Word8 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit (HasCallStack => ShortByteString -> Int -> Word8
ShortByteString -> Int -> Word8
SBS.index ShortByteString
bytes Int
0) Int
byron

-- | Convert Byron's comapct address into `CompactAddr`. This is just an efficient type cast.
fromBoostrapCompactAddress :: Byron.CompactAddress -> CompactAddr
fromBoostrapCompactAddress :: CompactAddress -> CompactAddr
fromBoostrapCompactAddress = ShortByteString -> CompactAddr
UnsafeCompactAddr (ShortByteString -> CompactAddr)
-> (CompactAddress -> ShortByteString)
-> CompactAddress
-> CompactAddr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CompactAddress -> ShortByteString
Byron.unsafeGetCompactAddress

-- | This is called @wdrl@ in the spec.
newtype Withdrawals = Withdrawals {Withdrawals -> Map RewardAccount Coin
unWithdrawals :: Map RewardAccount Coin}
  deriving (Int -> Withdrawals -> ShowS
[Withdrawals] -> ShowS
Withdrawals -> String
(Int -> Withdrawals -> ShowS)
-> (Withdrawals -> String)
-> ([Withdrawals] -> ShowS)
-> Show Withdrawals
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Withdrawals -> ShowS
showsPrec :: Int -> Withdrawals -> ShowS
$cshow :: Withdrawals -> String
show :: Withdrawals -> String
$cshowList :: [Withdrawals] -> ShowS
showList :: [Withdrawals] -> ShowS
Show, Withdrawals -> Withdrawals -> Bool
(Withdrawals -> Withdrawals -> Bool)
-> (Withdrawals -> Withdrawals -> Bool) -> Eq Withdrawals
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Withdrawals -> Withdrawals -> Bool
== :: Withdrawals -> Withdrawals -> Bool
$c/= :: Withdrawals -> Withdrawals -> Bool
/= :: Withdrawals -> Withdrawals -> Bool
Eq, (forall x. Withdrawals -> Rep Withdrawals x)
-> (forall x. Rep Withdrawals x -> Withdrawals)
-> Generic Withdrawals
forall x. Rep Withdrawals x -> Withdrawals
forall x. Withdrawals -> Rep Withdrawals x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Withdrawals -> Rep Withdrawals x
from :: forall x. Withdrawals -> Rep Withdrawals x
$cto :: forall x. Rep Withdrawals x -> Withdrawals
to :: forall x. Rep Withdrawals x -> Withdrawals
Generic)
  deriving newtype (Context -> Withdrawals -> IO (Maybe ThunkInfo)
Proxy Withdrawals -> String
(Context -> Withdrawals -> IO (Maybe ThunkInfo))
-> (Context -> Withdrawals -> IO (Maybe ThunkInfo))
-> (Proxy Withdrawals -> String)
-> NoThunks Withdrawals
forall a.
(Context -> a -> IO (Maybe ThunkInfo))
-> (Context -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> String)
-> NoThunks a
$cnoThunks :: Context -> Withdrawals -> IO (Maybe ThunkInfo)
noThunks :: Context -> Withdrawals -> IO (Maybe ThunkInfo)
$cwNoThunks :: Context -> Withdrawals -> IO (Maybe ThunkInfo)
wNoThunks :: Context -> Withdrawals -> IO (Maybe ThunkInfo)
$cshowTypeOf :: Proxy Withdrawals -> String
showTypeOf :: Proxy Withdrawals -> String
NoThunks, Withdrawals -> ()
(Withdrawals -> ()) -> NFData Withdrawals
forall a. (a -> ()) -> NFData a
$crnf :: Withdrawals -> ()
rnf :: Withdrawals -> ()
NFData, Typeable Withdrawals
Typeable Withdrawals =>
(Withdrawals -> Encoding)
-> ((forall t. EncCBOR t => Proxy t -> Size)
    -> Proxy Withdrawals -> Size)
-> ((forall t. EncCBOR t => Proxy t -> Size)
    -> Proxy [Withdrawals] -> Size)
-> EncCBOR Withdrawals
Withdrawals -> Encoding
(forall t. EncCBOR t => Proxy t -> Size)
-> Proxy [Withdrawals] -> Size
(forall t. EncCBOR t => Proxy t -> Size)
-> Proxy Withdrawals -> Size
forall a.
Typeable a =>
(a -> Encoding)
-> ((forall t. EncCBOR t => Proxy t -> Size) -> Proxy a -> Size)
-> ((forall t. EncCBOR t => Proxy t -> Size) -> Proxy [a] -> Size)
-> EncCBOR a
$cencCBOR :: Withdrawals -> Encoding
encCBOR :: Withdrawals -> Encoding
$cencodedSizeExpr :: (forall t. EncCBOR t => Proxy t -> Size)
-> Proxy Withdrawals -> Size
encodedSizeExpr :: (forall t. EncCBOR t => Proxy t -> Size)
-> Proxy Withdrawals -> Size
$cencodedListSizeExpr :: (forall t. EncCBOR t => Proxy t -> Size)
-> Proxy [Withdrawals] -> Size
encodedListSizeExpr :: (forall t. EncCBOR t => Proxy t -> Size)
-> Proxy [Withdrawals] -> Size
EncCBOR, Typeable Withdrawals
Typeable Withdrawals =>
(forall s. Decoder s Withdrawals)
-> (forall s. Proxy Withdrawals -> Decoder s ())
-> (Proxy Withdrawals -> Text)
-> DecCBOR Withdrawals
Proxy Withdrawals -> Text
forall s. Decoder s Withdrawals
forall a.
Typeable a =>
(forall s. Decoder s a)
-> (forall s. Proxy a -> Decoder s ())
-> (Proxy a -> Text)
-> DecCBOR a
forall s. Proxy Withdrawals -> Decoder s ()
$cdecCBOR :: forall s. Decoder s Withdrawals
decCBOR :: forall s. Decoder s Withdrawals
$cdropCBOR :: forall s. Proxy Withdrawals -> Decoder s ()
dropCBOR :: forall s. Proxy Withdrawals -> Decoder s ()
$clabel :: Proxy Withdrawals -> Text
label :: Proxy Withdrawals -> Text
DecCBOR)