{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}

-- | This module contains previous implementations for Addr and CoompactAddr
-- deserialization. This is used as an alternative implementation for testing and as a
-- perforance reference for benchmarking.
module Test.Cardano.Ledger.Core.Address (
  deserialiseAddrOld,
  deserialiseRewardAccountOld,
  decompactAddrOld,
  decompactAddrOldLazy,
) where

import qualified Cardano.Crypto.Hash.Class as Hash
import Cardano.Ledger.Address (
  Addr (..),
  BootstrapAddress (BootstrapAddress),
  CompactAddr,
  RewardAccount (..),
  Word7 (..),
  toWord7,
  unCompactAddr,
 )
import Cardano.Ledger.BaseTypes (CertIx (..), TxIx (..), word8ToNetwork)
import Cardano.Ledger.Binary (byronProtVer, decodeFull, decodeFull')
import Cardano.Ledger.Core
import Cardano.Ledger.Credential (
  Credential (..),
  PaymentCredential,
  Ptr (..),
  SlotNo32 (..),
  StakeReference (..),
 )
import Control.Monad (ap)
import qualified Control.Monad.Fail
import Data.Binary (Get)
import qualified Data.Binary.Get as B
import Data.Bits
import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as BSL
import Data.ByteString.Short as SBS (ShortByteString, fromShort, index, length)
import Data.ByteString.Short.Internal as SBS (ShortByteString (SBS))
import Data.Foldable as F (foldl')
import Data.Maybe (fromMaybe)
import qualified Data.Primitive.ByteArray as BA
import Data.String (fromString)
import Data.Text (Text, unpack)
import Data.Word (Word64, Word8)

------------------------------------------------------------------------------------------
-- Old Address Deserializer --------------------------------------------------------------
------------------------------------------------------------------------------------------

-- | Deserialise an address from the external format. This will fail if the
-- input data is not in the right format (or if there is trailing data).
deserialiseAddrOld :: MonadFail m => BS.ByteString -> m Addr
deserialiseAddrOld :: forall (m :: * -> *). MonadFail m => ByteString -> m Addr
deserialiseAddrOld ByteString
bs = case Get Addr
-> ByteString
-> Either
     (ByteString, ByteOffset, [Char]) (ByteString, ByteOffset, Addr)
forall a.
Get a
-> ByteString
-> Either
     (ByteString, ByteOffset, [Char]) (ByteString, ByteOffset, a)
B.runGetOrFail Get Addr
getAddr (ByteString -> ByteString
BSL.fromStrict ByteString
bs) of
  Left (ByteString
_remaining, ByteOffset
_offset, [Char]
message) ->
    [Char] -> m Addr
forall a. [Char] -> m a
forall (m :: * -> *) a. MonadFail m => [Char] -> m a
fail ([Char] -> m Addr) -> [Char] -> m Addr
forall a b. (a -> b) -> a -> b
$ [Char]
"Old Addr decoder failed: " [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [Char] -> [Char]
forall a. IsString a => [Char] -> a
fromString [Char]
message
  Right (ByteString
remaining, ByteOffset
_offset, Addr
result) ->
    if ByteString -> Bool
BSL.null ByteString
remaining
      then Addr -> m Addr
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Addr
result
      else [Char] -> m Addr
forall a. [Char] -> m a
forall (m :: * -> *) a. MonadFail m => [Char] -> m a
fail ([Char] -> m Addr) -> [Char] -> m Addr
forall a b. (a -> b) -> a -> b
$ [Char]
"Old Addr decoder did not consume all input"

-- | Deserialise an 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).
deserialiseRewardAccountOld :: MonadFail m => BS.ByteString -> m RewardAccount
deserialiseRewardAccountOld :: forall (m :: * -> *). MonadFail m => ByteString -> m RewardAccount
deserialiseRewardAccountOld ByteString
bs = case Get RewardAccount
-> ByteString
-> Either
     (ByteString, ByteOffset, [Char])
     (ByteString, ByteOffset, RewardAccount)
forall a.
Get a
-> ByteString
-> Either
     (ByteString, ByteOffset, [Char]) (ByteString, ByteOffset, a)
B.runGetOrFail Get RewardAccount
getRewardAccount (ByteString -> ByteString
BSL.fromStrict ByteString
bs) of
  Left (ByteString
_remaining, ByteOffset
_offset, [Char]
message) ->
    [Char] -> m RewardAccount
forall a. [Char] -> m a
forall (m :: * -> *) a. MonadFail m => [Char] -> m a
fail ([Char] -> m RewardAccount) -> [Char] -> m RewardAccount
forall a b. (a -> b) -> a -> b
$ [Char]
"Old RewardAccount decoder failed: " [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [Char] -> [Char]
forall a. IsString a => [Char] -> a
fromString [Char]
message
  Right (ByteString
remaining, ByteOffset
_offset, RewardAccount
result) ->
    if ByteString -> Bool
BSL.null ByteString
remaining
      then RewardAccount -> m RewardAccount
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure RewardAccount
result
      else [Char] -> m RewardAccount
forall a. [Char] -> m a
forall (m :: * -> *) a. MonadFail m => [Char] -> m a
fail ([Char] -> m RewardAccount) -> [Char] -> m RewardAccount
forall a b. (a -> b) -> a -> b
$ [Char]
"Old RewardAccount decoder did not consume all input"

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

rewardCredIsScript :: Int
rewardCredIsScript :: Int
rewardCredIsScript = Int
4

getAddr :: Get Addr
getAddr :: Get Addr
getAddr = do
  Word8
header <- Get Word8 -> Get Word8
forall a. Get a -> Get a
B.lookAhead Get Word8
B.getWord8
  if Word8 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Word8
header Int
byron
    then Get Addr
getByron
    else do
      Word8
_ <- Get Word8
B.getWord8 -- read past the header byte
      let addrNetId :: Word8
addrNetId = Word8
header Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.&. Word8
0x0F -- 0b00001111 is the mask for the network id
      case Word8 -> Maybe Network
word8ToNetwork Word8
addrNetId of
        Just Network
n -> Network -> PaymentCredential -> StakeReference -> Addr
Addr Network
n (PaymentCredential -> StakeReference -> Addr)
-> Get PaymentCredential -> Get (StakeReference -> Addr)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Word8 -> Get PaymentCredential
getPayCred Word8
header Get (StakeReference -> Addr) -> Get StakeReference -> Get Addr
forall a b. Get (a -> b) -> Get a -> Get b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Word8 -> Get StakeReference
getStakeReference Word8
header
        Maybe Network
Nothing ->
          [Char] -> Get Addr
forall a. [Char] -> Get a
forall (m :: * -> *) a. MonadFail m => [Char] -> m a
fail ([Char] -> Get Addr) -> [Char] -> Get Addr
forall a b. (a -> b) -> a -> b
$
            [[Char]] -> [Char]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
              [[Char]
"Address with unknown network Id. (", Word8 -> [Char]
forall a. Show a => a -> [Char]
show Word8
addrNetId, [Char]
")"]

getRewardAccount :: Get RewardAccount
getRewardAccount :: Get RewardAccount
getRewardAccount = do
  Word8
header <- Get Word8
B.getWord8
  let rewardAccountPrefix :: Word8
rewardAccountPrefix = Word8
0xE0 -- 0b11100000 are always set for reward accounts
      isRewardAccount :: Bool
isRewardAccount = (Word8
header Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.&. Word8
rewardAccountPrefix) Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
rewardAccountPrefix
      netId :: Word8
netId = Word8
header Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.&. Word8
0x0F -- 0b00001111 is the mask for the network id
  case (Word8 -> Maybe Network
word8ToNetwork Word8
netId, Bool
isRewardAccount) of
    (Maybe Network
Nothing, Bool
_) ->
      [Char] -> Get RewardAccount
forall a. [Char] -> Get a
forall (m :: * -> *) a. MonadFail m => [Char] -> m a
fail ([Char] -> Get RewardAccount) -> [Char] -> Get RewardAccount
forall a b. (a -> b) -> a -> b
$ [[Char]] -> [Char]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[Char]
"Reward account with unknown network Id. (", Word8 -> [Char]
forall a. Show a => a -> [Char]
show Word8
netId, [Char]
")"]
    (Maybe Network
_, Bool
False) ->
      [Char] -> Get RewardAccount
forall a. [Char] -> Get a
forall (m :: * -> *) a. MonadFail m => [Char] -> m a
fail ([Char] -> Get RewardAccount) -> [Char] -> Get RewardAccount
forall a b. (a -> b) -> a -> b
$ [[Char]] -> [Char]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[Char]
"Expected reward account. Got account with header: ", Word8 -> [Char]
forall a. Show a => a -> [Char]
show Word8
header]
    (Just Network
network, Bool
True) -> do
      Credential 'Staking
cred <- case Word8 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Word8
header Int
rewardCredIsScript of
        Bool
True -> Get (Credential 'Staking)
forall (kr :: KeyRole). Get (Credential kr)
getScriptHash
        Bool
False -> Get (Credential 'Staking)
forall (kr :: KeyRole). Get (Credential kr)
getKeyHash
      RewardAccount -> Get RewardAccount
forall a. a -> Get a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (RewardAccount -> Get RewardAccount)
-> RewardAccount -> Get RewardAccount
forall a b. (a -> b) -> a -> b
$ Network -> Credential 'Staking -> RewardAccount
RewardAccount Network
network Credential 'Staking
cred

getHash :: forall h a. Hash.HashAlgorithm h => Get (Hash.Hash h a)
getHash :: forall h a. HashAlgorithm h => Get (Hash h a)
getHash = do
  ByteString
bytes <- Int -> Get ByteString
B.getByteString (Int -> Get ByteString) -> (Word -> Int) -> Word -> Get ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word -> Get ByteString) -> Word -> Get ByteString
forall a b. (a -> b) -> a -> b
$ [h] -> Word
forall h (proxy :: * -> *). HashAlgorithm h => proxy h -> Word
Hash.sizeHash ([] @h)
  case ByteString -> Maybe (Hash h a)
forall h a. HashAlgorithm h => ByteString -> Maybe (Hash h a)
Hash.hashFromBytes ByteString
bytes of
    Maybe (Hash h a)
Nothing -> [Char] -> Get (Hash h a)
forall a. [Char] -> Get a
forall (m :: * -> *) a. MonadFail m => [Char] -> m a
fail [Char]
"getHash: implausible hash length mismatch"
    Just !Hash h a
h -> Hash h a -> Get (Hash h a)
forall a. a -> Get a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Hash h a
h

getPayCred :: Word8 -> Get PaymentCredential
getPayCred :: Word8 -> Get PaymentCredential
getPayCred Word8
header = case Word8 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Word8
header Int
payCredIsScript of
  Bool
True -> Get PaymentCredential
forall (kr :: KeyRole). Get (Credential kr)
getScriptHash
  Bool
False -> Get PaymentCredential
forall (kr :: KeyRole). Get (Credential kr)
getKeyHash

getScriptHash :: Get (Credential kr)
getScriptHash :: forall (kr :: KeyRole). Get (Credential kr)
getScriptHash = ScriptHash -> Credential kr
forall (kr :: KeyRole). ScriptHash -> Credential kr
ScriptHashObj (ScriptHash -> Credential kr)
-> (Hash ADDRHASH EraIndependentScript -> ScriptHash)
-> Hash ADDRHASH EraIndependentScript
-> Credential kr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Hash ADDRHASH EraIndependentScript -> ScriptHash
ScriptHash (Hash ADDRHASH EraIndependentScript -> Credential kr)
-> Get (Hash ADDRHASH EraIndependentScript) -> Get (Credential kr)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get (Hash ADDRHASH EraIndependentScript)
forall h a. HashAlgorithm h => Get (Hash h a)
getHash

getKeyHash :: Get (Credential kr)
getKeyHash :: forall (kr :: KeyRole). Get (Credential kr)
getKeyHash = KeyHash kr -> Credential kr
forall (kr :: KeyRole). KeyHash kr -> Credential kr
KeyHashObj (KeyHash kr -> Credential kr)
-> (Hash ADDRHASH (VerKeyDSIGN DSIGN) -> KeyHash kr)
-> Hash ADDRHASH (VerKeyDSIGN DSIGN)
-> Credential kr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Hash ADDRHASH (VerKeyDSIGN DSIGN) -> KeyHash kr
forall (r :: KeyRole).
Hash ADDRHASH (VerKeyDSIGN DSIGN) -> KeyHash r
KeyHash (Hash ADDRHASH (VerKeyDSIGN DSIGN) -> Credential kr)
-> Get (Hash ADDRHASH (VerKeyDSIGN DSIGN)) -> Get (Credential kr)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get (Hash ADDRHASH (VerKeyDSIGN DSIGN))
forall h a. HashAlgorithm h => Get (Hash h a)
getHash

getStakeReference :: Word8 -> Get StakeReference
getStakeReference :: Word8 -> Get StakeReference
getStakeReference Word8
header = case Word8 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Word8
header Int
notBaseAddr of
  Bool
True -> case Word8 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Word8
header Int
isEnterpriseAddr of
    Bool
True -> StakeReference -> Get StakeReference
forall a. a -> Get a
forall (f :: * -> *) a. Applicative f => a -> f a
pure StakeReference
StakeRefNull
    Bool
False -> Ptr -> StakeReference
StakeRefPtr (Ptr -> StakeReference) -> Get Ptr -> Get StakeReference
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Ptr
getPtr
  Bool
False -> case Word8 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Word8
header Int
stakeCredIsScript of
    Bool
True -> Credential 'Staking -> StakeReference
StakeRefBase (Credential 'Staking -> StakeReference)
-> Get (Credential 'Staking) -> Get StakeReference
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get (Credential 'Staking)
forall (kr :: KeyRole). Get (Credential kr)
getScriptHash
    Bool
False -> Credential 'Staking -> StakeReference
StakeRefBase (Credential 'Staking -> StakeReference)
-> Get (Credential 'Staking) -> Get StakeReference
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get (Credential 'Staking)
forall (kr :: KeyRole). Get (Credential kr)
getKeyHash

getByron :: Get Addr
getByron :: Get Addr
getByron =
  Version -> ByteString -> Either DecoderError Address
forall a.
DecCBOR a =>
Version -> ByteString -> Either DecoderError a
decodeFull Version
byronProtVer (ByteString -> Either DecoderError Address)
-> Get ByteString -> Get (Either DecoderError Address)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get ByteString
B.getRemainingLazyByteString Get (Either DecoderError Address)
-> (Either DecoderError Address -> Get Addr) -> Get Addr
forall a b. Get a -> (a -> Get b) -> Get b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
    Left DecoderError
e -> [Char] -> Get Addr
forall a. [Char] -> Get a
forall (m :: * -> *) a. MonadFail m => [Char] -> m a
fail (DecoderError -> [Char]
forall a. Show a => a -> [Char]
show DecoderError
e)
    Right Address
r -> Addr -> Get Addr
forall a. a -> Get a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Addr -> Get Addr) -> Addr -> Get Addr
forall a b. (a -> b) -> a -> b
$ BootstrapAddress -> Addr
AddrBootstrap (BootstrapAddress -> Addr) -> BootstrapAddress -> Addr
forall a b. (a -> b) -> a -> b
$ Address -> BootstrapAddress
BootstrapAddress Address
r

getPtr :: Get Ptr
getPtr :: Get Ptr
getPtr =
  SlotNo32 -> TxIx -> CertIx -> Ptr
Ptr
    (SlotNo32 -> TxIx -> CertIx -> Ptr)
-> Get SlotNo32 -> Get (TxIx -> CertIx -> Ptr)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Word32 -> SlotNo32
SlotNo32 (Word32 -> SlotNo32) -> (Word64 -> Word32) -> Word64 -> SlotNo32
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64 -> SlotNo32) -> Get Word64 -> Get SlotNo32
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Word64
getVariableLengthWord64)
    Get (TxIx -> CertIx -> Ptr) -> Get TxIx -> Get (CertIx -> Ptr)
forall a b. Get (a -> b) -> Get a -> Get b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Word16 -> TxIx
TxIx (Word16 -> TxIx) -> (Word64 -> Word16) -> Word64 -> TxIx
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64 -> TxIx) -> Get Word64 -> Get TxIx
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Word64
getVariableLengthWord64)
    Get (CertIx -> Ptr) -> Get CertIx -> Get Ptr
forall a b. Get (a -> b) -> Get a -> Get b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Word16 -> CertIx
CertIx (Word16 -> CertIx) -> (Word64 -> Word16) -> Word64 -> CertIx
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64 -> CertIx) -> Get Word64 -> Get CertIx
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Word64
getVariableLengthWord64)

getWord7s :: Get [Word7]
getWord7s :: Get [Word7]
getWord7s = do
  Word8
next <- Get Word8
B.getWord8
  -- is the high bit set?
  if Word8 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Word8
next Int
7
    then -- if so, grab more words
      (:) (Word8 -> Word7
toWord7 Word8
next) ([Word7] -> [Word7]) -> Get [Word7] -> Get [Word7]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get [Word7]
getWord7s
    else -- otherwise, this is the last one
      [Word7] -> Get [Word7]
forall a. a -> Get a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [Word8 -> Word7
Word7 Word8
next]

-- invariant: length [Word7] < 8
word7sToWord64 :: [Word7] -> Word64
word7sToWord64 :: [Word7] -> Word64
word7sToWord64 = (Word64 -> Word7 -> Word64) -> Word64 -> [Word7] -> Word64
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
F.foldl' Word64 -> Word7 -> Word64
forall {a}. (Bits a, Num a) => a -> Word7 -> a
f Word64
0
  where
    f :: a -> Word7 -> a
f a
n (Word7 Word8
r) = a -> Int -> a
forall a. Bits a => a -> Int -> a
shiftL a
n 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
r

getVariableLengthWord64 :: Get Word64
getVariableLengthWord64 :: Get Word64
getVariableLengthWord64 = [Word7] -> Word64
word7sToWord64 ([Word7] -> Word64) -> Get [Word7] -> Get Word64
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get [Word7]
getWord7s

------------------------------------------------------------------------------------------
-- Old Compact Address Deserializer ------------------------------------------------------
------------------------------------------------------------------------------------------

newtype GetShort a = GetShort {forall a. GetShort a -> Int -> ShortByteString -> Maybe (Int, a)
runGetShort :: Int -> ShortByteString -> Maybe (Int, a)}
  deriving ((forall a b. (a -> b) -> GetShort a -> GetShort b)
-> (forall a b. a -> GetShort b -> GetShort a) -> Functor GetShort
forall a b. a -> GetShort b -> GetShort a
forall a b. (a -> b) -> GetShort a -> GetShort b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall a b. (a -> b) -> GetShort a -> GetShort b
fmap :: forall a b. (a -> b) -> GetShort a -> GetShort b
$c<$ :: forall a b. a -> GetShort b -> GetShort a
<$ :: forall a b. a -> GetShort b -> GetShort a
Functor)

instance Applicative GetShort where
  pure :: forall a. a -> GetShort a
pure a
a = (Int -> ShortByteString -> Maybe (Int, a)) -> GetShort a
forall a. (Int -> ShortByteString -> Maybe (Int, a)) -> GetShort a
GetShort ((Int -> ShortByteString -> Maybe (Int, a)) -> GetShort a)
-> (Int -> ShortByteString -> Maybe (Int, a)) -> GetShort a
forall a b. (a -> b) -> a -> b
$ \Int
i ShortByteString
_sbs -> (Int, a) -> Maybe (Int, a)
forall a. a -> Maybe a
Just (Int
i, a
a)
  <*> :: forall a b. GetShort (a -> b) -> GetShort a -> GetShort b
(<*>) = GetShort (a -> b) -> GetShort a -> GetShort b
forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
ap

instance Monad GetShort where
  (GetShort Int -> ShortByteString -> Maybe (Int, a)
g) >>= :: forall a b. GetShort a -> (a -> GetShort b) -> GetShort b
>>= a -> GetShort b
f = (Int -> ShortByteString -> Maybe (Int, b)) -> GetShort b
forall a. (Int -> ShortByteString -> Maybe (Int, a)) -> GetShort a
GetShort ((Int -> ShortByteString -> Maybe (Int, b)) -> GetShort b)
-> (Int -> ShortByteString -> Maybe (Int, b)) -> GetShort b
forall a b. (a -> b) -> a -> b
$ \Int
i ShortByteString
sbs ->
    case Int -> ShortByteString -> Maybe (Int, a)
g Int
i ShortByteString
sbs of
      Maybe (Int, a)
Nothing -> Maybe (Int, b)
forall a. Maybe a
Nothing
      Just (Int
i', a
x) -> GetShort b -> Int -> ShortByteString -> Maybe (Int, b)
forall a. GetShort a -> Int -> ShortByteString -> Maybe (Int, a)
runGetShort (a -> GetShort b
f a
x) Int
i' ShortByteString
sbs

instance Control.Monad.Fail.MonadFail GetShort where
  fail :: forall a. [Char] -> GetShort a
fail [Char]
_ = (Int -> ShortByteString -> Maybe (Int, a)) -> GetShort a
forall a. (Int -> ShortByteString -> Maybe (Int, a)) -> GetShort a
GetShort ((Int -> ShortByteString -> Maybe (Int, a)) -> GetShort a)
-> (Int -> ShortByteString -> Maybe (Int, a)) -> GetShort a
forall a b. (a -> b) -> a -> b
$ \Int
_ ShortByteString
_ -> Maybe (Int, a)
forall a. Maybe a
Nothing

getShortBootstrapAddress :: GetShort BootstrapAddress
getShortBootstrapAddress :: GetShort BootstrapAddress
getShortBootstrapAddress = do
  ByteString
bs <- GetShort ByteString
getShortRemainingAsByteString
  case Version -> ByteString -> Either DecoderError Address
forall a.
DecCBOR a =>
Version -> ByteString -> Either DecoderError a
decodeFull' Version
byronProtVer ByteString
bs of
    Left DecoderError
e -> [Char] -> GetShort BootstrapAddress
forall a. [Char] -> GetShort a
forall (m :: * -> *) a. MonadFail m => [Char] -> m a
fail ([Char] -> GetShort BootstrapAddress)
-> [Char] -> GetShort BootstrapAddress
forall a b. (a -> b) -> a -> b
$ DecoderError -> [Char]
forall a. Show a => a -> [Char]
show DecoderError
e
    Right Address
r -> BootstrapAddress -> GetShort BootstrapAddress
forall a. a -> GetShort a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (BootstrapAddress -> GetShort BootstrapAddress)
-> BootstrapAddress -> GetShort BootstrapAddress
forall a b. (a -> b) -> a -> b
$ Address -> BootstrapAddress
BootstrapAddress Address
r

getShortWord :: GetShort Word8
getShortWord :: GetShort Word8
getShortWord = (Int -> ShortByteString -> Maybe (Int, Word8)) -> GetShort Word8
forall a. (Int -> ShortByteString -> Maybe (Int, a)) -> GetShort a
GetShort ((Int -> ShortByteString -> Maybe (Int, Word8)) -> GetShort Word8)
-> (Int -> ShortByteString -> Maybe (Int, Word8)) -> GetShort Word8
forall a b. (a -> b) -> a -> b
$ \Int
i ShortByteString
sbs ->
  if Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< ShortByteString -> Int
SBS.length ShortByteString
sbs
    then (Int, Word8) -> Maybe (Int, Word8)
forall a. a -> Maybe a
Just (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1, HasCallStack => ShortByteString -> Int -> Word8
ShortByteString -> Int -> Word8
SBS.index ShortByteString
sbs Int
i)
    else Maybe (Int, Word8)
forall a. Maybe a
Nothing

peekWord8 :: GetShort Word8
peekWord8 :: GetShort Word8
peekWord8 = (Int -> ShortByteString -> Maybe (Int, Word8)) -> GetShort Word8
forall a. (Int -> ShortByteString -> Maybe (Int, a)) -> GetShort a
GetShort Int -> ShortByteString -> Maybe (Int, Word8)
peek
  where
    peek :: Int -> ShortByteString -> Maybe (Int, Word8)
peek Int
i ShortByteString
sbs = if Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< ShortByteString -> Int
SBS.length ShortByteString
sbs then (Int, Word8) -> Maybe (Int, Word8)
forall a. a -> Maybe a
Just (Int
i, HasCallStack => ShortByteString -> Int -> Word8
ShortByteString -> Int -> Word8
SBS.index ShortByteString
sbs Int
i) else Maybe (Int, Word8)
forall a. Maybe a
Nothing

getShortRemainingAsByteString :: GetShort BS.ByteString
getShortRemainingAsByteString :: GetShort ByteString
getShortRemainingAsByteString = (Int -> ShortByteString -> Maybe (Int, ByteString))
-> GetShort ByteString
forall a. (Int -> ShortByteString -> Maybe (Int, a)) -> GetShort a
GetShort ((Int -> ShortByteString -> Maybe (Int, ByteString))
 -> GetShort ByteString)
-> (Int -> ShortByteString -> Maybe (Int, ByteString))
-> GetShort ByteString
forall a b. (a -> b) -> a -> b
$ \Int
i ShortByteString
sbs ->
  let l :: Int
l = ShortByteString -> Int
SBS.length ShortByteString
sbs
   in if Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
l
        then (Int, ByteString) -> Maybe (Int, ByteString)
forall a. a -> Maybe a
Just (Int
l, ShortByteString -> ByteString
SBS.fromShort (ShortByteString -> ByteString) -> ShortByteString -> ByteString
forall a b. (a -> b) -> a -> b
$ ShortByteString -> Int -> Int -> ShortByteString
substring ShortByteString
sbs Int
i Int
l)
        else Maybe (Int, ByteString)
forall a. Maybe a
Nothing

getShortHash :: forall a h. Hash.HashAlgorithm h => GetShort (Hash.Hash h a)
getShortHash :: forall a h. HashAlgorithm h => GetShort (Hash h a)
getShortHash = (Int -> ShortByteString -> Maybe (Int, Hash h a))
-> GetShort (Hash h a)
forall a. (Int -> ShortByteString -> Maybe (Int, a)) -> GetShort a
GetShort ((Int -> ShortByteString -> Maybe (Int, Hash h a))
 -> GetShort (Hash h a))
-> (Int -> ShortByteString -> Maybe (Int, Hash h a))
-> GetShort (Hash h a)
forall a b. (a -> b) -> a -> b
$ \Int
i ShortByteString
sbs ->
  let hashLen :: Word
hashLen = [h] -> Word
forall h (proxy :: * -> *). HashAlgorithm h => proxy h -> Word
Hash.sizeHash ([] @h)
      offsetStop :: Int
offsetStop = Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Word -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word
hashLen
   in if Int
offsetStop Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= ShortByteString -> Int
SBS.length ShortByteString
sbs
        then do
          Hash h a
hash <- ShortByteString -> Maybe (Hash h a)
forall h a. HashAlgorithm h => ShortByteString -> Maybe (Hash h a)
Hash.hashFromBytesShort (ShortByteString -> Maybe (Hash h a))
-> ShortByteString -> Maybe (Hash h a)
forall a b. (a -> b) -> a -> b
$ ShortByteString -> Int -> Int -> ShortByteString
substring ShortByteString
sbs Int
i Int
offsetStop
          (Int, Hash h a) -> Maybe (Int, Hash h a)
forall a. a -> Maybe a
Just (Int
offsetStop, Hash h a
hash)
        else Maybe (Int, Hash h a)
forall a. Maybe a
Nothing

-- start is the first index copied
-- stop is the index after the last index copied
substring :: ShortByteString -> Int -> Int -> ShortByteString
substring :: ShortByteString -> Int -> Int -> ShortByteString
substring (SBS ByteArray#
ba) Int
start Int
stop =
  case ByteArray -> Int -> Int -> ByteArray
BA.cloneByteArray (ByteArray# -> ByteArray
BA.ByteArray ByteArray#
ba) Int
start (Int
stop Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
start) of
    BA.ByteArray ByteArray#
ba' -> ByteArray# -> ShortByteString
SBS ByteArray#
ba'

getShortWord7s :: GetShort [Word7]
getShortWord7s :: GetShort [Word7]
getShortWord7s = do
  Word8
next <- GetShort Word8
getShortWord
  -- is the high bit set?
  if Word8 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Word8
next Int
7
    then -- if so, grab more words
      (:) (Word8 -> Word7
toWord7 Word8
next) ([Word7] -> [Word7]) -> GetShort [Word7] -> GetShort [Word7]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> GetShort [Word7]
getShortWord7s
    else -- otherwise, this is the last one
      [Word7] -> GetShort [Word7]
forall a. a -> GetShort a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [Word8 -> Word7
Word7 Word8
next]

getShortVariableLengthWord64 :: GetShort Word64
getShortVariableLengthWord64 :: GetShort Word64
getShortVariableLengthWord64 = [Word7] -> Word64
word7sToWord64 ([Word7] -> Word64) -> GetShort [Word7] -> GetShort Word64
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> GetShort [Word7]
getShortWord7s

getShortPtr :: GetShort Ptr
getShortPtr :: GetShort Ptr
getShortPtr =
  SlotNo32 -> TxIx -> CertIx -> Ptr
Ptr
    (SlotNo32 -> TxIx -> CertIx -> Ptr)
-> GetShort SlotNo32 -> GetShort (TxIx -> CertIx -> Ptr)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Word32 -> SlotNo32
SlotNo32 (Word32 -> SlotNo32) -> (Word64 -> Word32) -> Word64 -> SlotNo32
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64 -> SlotNo32) -> GetShort Word64 -> GetShort SlotNo32
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> GetShort Word64
getShortVariableLengthWord64)
    GetShort (TxIx -> CertIx -> Ptr)
-> GetShort TxIx -> GetShort (CertIx -> Ptr)
forall a b. GetShort (a -> b) -> GetShort a -> GetShort b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Word16 -> TxIx
TxIx (Word16 -> TxIx) -> (Word64 -> Word16) -> Word64 -> TxIx
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64 -> TxIx) -> GetShort Word64 -> GetShort TxIx
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> GetShort Word64
getShortVariableLengthWord64)
    GetShort (CertIx -> Ptr) -> GetShort CertIx -> GetShort Ptr
forall a b. GetShort (a -> b) -> GetShort a -> GetShort b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Word16 -> CertIx
CertIx (Word16 -> CertIx) -> (Word64 -> Word16) -> Word64 -> CertIx
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64 -> CertIx) -> GetShort Word64 -> GetShort CertIx
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> GetShort Word64
getShortVariableLengthWord64)

getShortKeyHash :: GetShort (Credential kr)
getShortKeyHash :: forall (kr :: KeyRole). GetShort (Credential kr)
getShortKeyHash = KeyHash kr -> Credential kr
forall (kr :: KeyRole). KeyHash kr -> Credential kr
KeyHashObj (KeyHash kr -> Credential kr)
-> (Hash ADDRHASH (VerKeyDSIGN DSIGN) -> KeyHash kr)
-> Hash ADDRHASH (VerKeyDSIGN DSIGN)
-> Credential kr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Hash ADDRHASH (VerKeyDSIGN DSIGN) -> KeyHash kr
forall (r :: KeyRole).
Hash ADDRHASH (VerKeyDSIGN DSIGN) -> KeyHash r
KeyHash (Hash ADDRHASH (VerKeyDSIGN DSIGN) -> Credential kr)
-> GetShort (Hash ADDRHASH (VerKeyDSIGN DSIGN))
-> GetShort (Credential kr)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> GetShort (Hash ADDRHASH (VerKeyDSIGN DSIGN))
forall a h. HashAlgorithm h => GetShort (Hash h a)
getShortHash

getShortScriptHash :: GetShort (Credential kr)
getShortScriptHash :: forall (kr :: KeyRole). GetShort (Credential kr)
getShortScriptHash = ScriptHash -> Credential kr
forall (kr :: KeyRole). ScriptHash -> Credential kr
ScriptHashObj (ScriptHash -> Credential kr)
-> (Hash ADDRHASH EraIndependentScript -> ScriptHash)
-> Hash ADDRHASH EraIndependentScript
-> Credential kr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Hash ADDRHASH EraIndependentScript -> ScriptHash
ScriptHash (Hash ADDRHASH EraIndependentScript -> Credential kr)
-> GetShort (Hash ADDRHASH EraIndependentScript)
-> GetShort (Credential kr)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> GetShort (Hash ADDRHASH EraIndependentScript)
forall a h. HashAlgorithm h => GetShort (Hash h a)
getShortHash

getShortStakeReference :: Word8 -> GetShort StakeReference
getShortStakeReference :: Word8 -> GetShort StakeReference
getShortStakeReference Word8
header = case Word8 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Word8
header Int
notBaseAddr of
  Bool
True -> case Word8 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Word8
header Int
isEnterpriseAddr of
    Bool
True -> StakeReference -> GetShort StakeReference
forall a. a -> GetShort a
forall (f :: * -> *) a. Applicative f => a -> f a
pure StakeReference
StakeRefNull
    Bool
False -> Ptr -> StakeReference
StakeRefPtr (Ptr -> StakeReference) -> GetShort Ptr -> GetShort StakeReference
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> GetShort Ptr
getShortPtr
  Bool
False -> case Word8 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Word8
header Int
stakeCredIsScript of
    Bool
True -> Credential 'Staking -> StakeReference
StakeRefBase (Credential 'Staking -> StakeReference)
-> GetShort (Credential 'Staking) -> GetShort StakeReference
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> GetShort (Credential 'Staking)
forall (kr :: KeyRole). GetShort (Credential kr)
getShortScriptHash
    Bool
False -> Credential 'Staking -> StakeReference
StakeRefBase (Credential 'Staking -> StakeReference)
-> GetShort (Credential 'Staking) -> GetShort StakeReference
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> GetShort (Credential 'Staking)
forall (kr :: KeyRole). GetShort (Credential kr)
getShortKeyHash

getShortPayCred :: Word8 -> GetShort PaymentCredential
getShortPayCred :: Word8 -> GetShort PaymentCredential
getShortPayCred Word8
header = case Word8 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Word8
header Int
payCredIsScript of
  Bool
True -> GetShort PaymentCredential
forall (kr :: KeyRole). GetShort (Credential kr)
getShortScriptHash
  Bool
False -> GetShort PaymentCredential
forall (kr :: KeyRole). GetShort (Credential kr)
getShortKeyHash

getShortShortAddr :: GetShort Addr
getShortShortAddr :: GetShort Addr
getShortShortAddr = do
  Word8
header <- GetShort Word8
peekWord8
  if Word8 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Word8
header Int
byron
    then BootstrapAddress -> Addr
AddrBootstrap (BootstrapAddress -> Addr)
-> GetShort BootstrapAddress -> GetShort Addr
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> GetShort BootstrapAddress
getShortBootstrapAddress
    else do
      Word8
_ <- GetShort Word8
getShortWord -- read past the header byte
      let addrNetId :: Word8
addrNetId = Word8
header Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.&. Word8
0x0F -- 0b00001111 is the mask for the network id
      case Word8 -> Maybe Network
word8ToNetwork Word8
addrNetId of
        Just Network
n -> do
          PaymentCredential
c <- Word8 -> GetShort PaymentCredential
getShortPayCred Word8
header
          StakeReference
h <- Word8 -> GetShort StakeReference
getShortStakeReference Word8
header
          Addr -> GetShort Addr
forall a. a -> GetShort a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Network -> PaymentCredential -> StakeReference -> Addr
Addr Network
n PaymentCredential
c StakeReference
h)
        Maybe Network
Nothing ->
          [Char] -> GetShort Addr
forall a. [Char] -> GetShort a
forall (m :: * -> *) a. MonadFail m => [Char] -> m a
fail ([Char] -> GetShort Addr) -> [Char] -> GetShort Addr
forall a b. (a -> b) -> a -> b
$
            [[Char]] -> [Char]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
              [[Char]
"Address with unknown network Id. (", Word8 -> [Char]
forall a. Show a => a -> [Char]
show Word8
addrNetId, [Char]
")"]

-- | This is an old decompacter that didn't guard against random junk at the end.
decompactAddrOld :: CompactAddr -> Addr
decompactAddrOld :: CompactAddr -> Addr
decompactAddrOld CompactAddr
cAddr =
  (Int, Addr) -> Addr
forall a b. (a, b) -> b
snd ((Int, Addr) -> Addr)
-> (Maybe (Int, Addr) -> (Int, Addr)) -> Maybe (Int, Addr) -> Addr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Maybe (Int, Addr) -> (Int, Addr)
forall a. Text -> Maybe a -> a
unwrap Text
"CompactAddr" (Maybe (Int, Addr) -> Addr) -> Maybe (Int, Addr) -> Addr
forall a b. (a -> b) -> a -> b
$ GetShort Addr -> Int -> ShortByteString -> Maybe (Int, Addr)
forall a. GetShort a -> Int -> ShortByteString -> Maybe (Int, a)
runGetShort GetShort Addr
getShortShortAddr Int
0 (CompactAddr -> ShortByteString
unCompactAddr CompactAddr
cAddr)
  where
    -- The reason failure is impossible here is that the only way to call this code
    -- is using a CompactAddr, which can only be constructed using compactAddr.
    -- compactAddr serializes an Addr, so this is guaranteed to work.
    unwrap :: forall a. Text -> Maybe a -> a
    unwrap :: forall a. Text -> Maybe a -> a
unwrap Text
name = a -> Maybe a -> a
forall a. a -> Maybe a -> a
fromMaybe ([Char] -> a
forall a. HasCallStack => [Char] -> a
error ([Char] -> a) -> [Char] -> a
forall a b. (a -> b) -> a -> b
$ Text -> [Char]
unpack (Text -> [Char]) -> Text -> [Char]
forall a b. (a -> b) -> a -> b
$ Text
"Impossible failure when decoding " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
name)

-- | This lazy deserializer is kept around purely for benchmarking, so we can
-- verify that new deserializer `decodeAddrStateT` is doing the work lazily.
decompactAddrOldLazy :: CompactAddr -> Addr
decompactAddrOldLazy :: CompactAddr -> Addr
decompactAddrOldLazy CompactAddr
cAddr =
  if Word8 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Word8
header Int
byron
    then BootstrapAddress -> Addr
AddrBootstrap (BootstrapAddress -> Addr) -> BootstrapAddress -> Addr
forall a b. (a -> b) -> a -> b
$ Text
-> Int
-> ShortByteString
-> GetShort BootstrapAddress
-> BootstrapAddress
forall a. Text -> Int -> ShortByteString -> GetShort a -> a
run Text
"byron address" Int
0 ShortByteString
bytes GetShort BootstrapAddress
getShortBootstrapAddress
    else Network -> PaymentCredential -> StakeReference -> Addr
Addr Network
addrNetId PaymentCredential
paycred StakeReference
stakecred
  where
    bytes :: ShortByteString
bytes = CompactAddr -> ShortByteString
unCompactAddr CompactAddr
cAddr
    run :: forall a. Text -> Int -> ShortByteString -> GetShort a -> a
    run :: forall a. Text -> Int -> ShortByteString -> GetShort a -> a
run Text
name Int
i ShortByteString
sbs GetShort a
g = (Int, a) -> a
forall a b. (a, b) -> b
snd ((Int, a) -> a)
-> (Maybe (Int, a) -> (Int, a)) -> Maybe (Int, a) -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Maybe (Int, a) -> (Int, a)
forall a. Text -> Maybe a -> a
unwrap Text
name (Maybe (Int, a) -> a) -> Maybe (Int, a) -> a
forall a b. (a -> b) -> a -> b
$ GetShort a -> Int -> ShortByteString -> Maybe (Int, a)
forall a. GetShort a -> Int -> ShortByteString -> Maybe (Int, a)
runGetShort GetShort a
g Int
i ShortByteString
sbs
    -- The reason failure is impossible here is that the only way to call this code
    -- is using a CompactAddr, which can only be constructed using compactAddr.
    -- compactAddr serializes an Addr, so this is guaranteed to work.
    unwrap :: forall a. Text -> Maybe a -> a
    unwrap :: forall a. Text -> Maybe a -> a
unwrap Text
name = a -> Maybe a -> a
forall a. a -> Maybe a -> a
fromMaybe ([Char] -> a
forall a. HasCallStack => [Char] -> a
error ([Char] -> a) -> [Char] -> a
forall a b. (a -> b) -> a -> b
$ Text -> [Char]
unpack (Text -> [Char]) -> Text -> [Char]
forall a b. (a -> b) -> a -> b
$ Text
"Impossible failure when decoding " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
name)
    header :: Word8
header = Text -> Int -> ShortByteString -> GetShort Word8 -> Word8
forall a. Text -> Int -> ShortByteString -> GetShort a -> a
run Text
"address header" Int
0 ShortByteString
bytes GetShort Word8
getShortWord
    addrNetId :: Network
addrNetId =
      Text -> Maybe Network -> Network
forall a. Text -> Maybe a -> a
unwrap Text
"address network id" (Maybe Network -> Network) -> Maybe Network -> Network
forall a b. (a -> b) -> a -> b
$
        Word8 -> Maybe Network
word8ToNetwork (Word8 -> Maybe Network) -> Word8 -> Maybe Network
forall a b. (a -> b) -> a -> b
$
          Word8
header Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.&. Word8
0x0F -- 0b00001111 is the mask for the network id
          -- The address format is
          -- header | pay cred | stake cred
          -- where the header is 1 byte
          -- the pay cred is (sizeHash (ADDRHASH crypto)) bytes
          -- and the stake cred can vary
    paycred :: PaymentCredential
paycred = Text
-> Int
-> ShortByteString
-> GetShort PaymentCredential
-> PaymentCredential
forall a. Text -> Int -> ShortByteString -> GetShort a -> a
run Text
"payment credential" Int
1 ShortByteString
bytes (Word8 -> GetShort PaymentCredential
getShortPayCred Word8
header)
    stakecred :: StakeReference
stakecred = Text
-> Int
-> ShortByteString
-> GetShort StakeReference
-> StakeReference
forall a. Text -> Int -> ShortByteString -> GetShort a -> a
run Text
"staking credential" Int
1 ShortByteString
bytes (GetShort StakeReference -> StakeReference)
-> GetShort StakeReference -> StakeReference
forall a b. (a -> b) -> a -> b
$ do
      [ADDRHASH] -> GetShort ()
forall (proxy :: * -> *) h.
HashAlgorithm h =>
proxy h -> GetShort ()
skipHash ([] @ADDRHASH)
      Word8 -> GetShort StakeReference
getShortStakeReference Word8
header
    skipHash :: forall proxy h. Hash.HashAlgorithm h => proxy h -> GetShort ()
    skipHash :: forall (proxy :: * -> *) h.
HashAlgorithm h =>
proxy h -> GetShort ()
skipHash proxy h
p = Int -> GetShort ()
skip (Int -> GetShort ()) -> (Word -> Int) -> Word -> GetShort ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word -> GetShort ()) -> Word -> GetShort ()
forall a b. (a -> b) -> a -> b
$ proxy h -> Word
forall h (proxy :: * -> *). HashAlgorithm h => proxy h -> Word
Hash.sizeHash proxy h
p
    skip :: Int -> GetShort ()
    skip :: Int -> GetShort ()
skip Int
n = (Int -> ShortByteString -> Maybe (Int, ())) -> GetShort ()
forall a. (Int -> ShortByteString -> Maybe (Int, a)) -> GetShort a
GetShort ((Int -> ShortByteString -> Maybe (Int, ())) -> GetShort ())
-> (Int -> ShortByteString -> Maybe (Int, ())) -> GetShort ()
forall a b. (a -> b) -> a -> b
$ \Int
i ShortByteString
sbs ->
      let offsetStop :: Int
offsetStop = Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
n
       in if Int
offsetStop Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= ShortByteString -> Int
SBS.length ShortByteString
sbs
            then (Int, ()) -> Maybe (Int, ())
forall a. a -> Maybe a
Just (Int
offsetStop, ())
            else Maybe (Int, ())
forall a. Maybe a
Nothing
{-# INLINE decompactAddrOldLazy #-}