Skip to content

Commit

Permalink
separating data and functions
Browse files Browse the repository at this point in the history
  • Loading branch information
polinavino committed Sep 16, 2020
1 parent e9e3123 commit 5ff1255
Show file tree
Hide file tree
Showing 35 changed files with 5,943 additions and 1,253 deletions.
17 changes: 13 additions & 4 deletions shelley/chain-and-ledger/executable-spec/shelley-spec-ledger.cabal
Expand Up @@ -22,32 +22,41 @@ library
Cardano.Ledger.Era
Cardano.Ledger.Shelley
Shelley.Spec.Ledger.Address
Shelley.Spec.Ledger.Data.AddressData
Shelley.Spec.Ledger.Data.BaseTypesData
Shelley.Spec.Ledger.Address.Bootstrap
Shelley.Spec.Ledger.API
Shelley.Spec.Ledger.API.Protocol
Shelley.Spec.Ledger.API.Validation
Shelley.Spec.Ledger.BaseTypes
Shelley.Spec.Ledger.BlockChain
Shelley.Spec.Ledger.ByronTranslation
Shelley.Spec.Ledger.Coin
Shelley.Spec.Ledger.Credential
Shelley.Spec.Ledger.Data.CoinData
Shelley.Spec.Ledger.Data.CredentialData
Shelley.Spec.Ledger.Delegation.Certificates
Shelley.Spec.Ledger.Delegation.PoolParams
Shelley.Spec.Ledger.DeserializeShort
Shelley.Spec.Ledger.EpochBoundary
Shelley.Spec.Ledger.Genesis
Shelley.Spec.Ledger.Hashing
Shelley.Spec.Ledger.Data.HashingData
Shelley.Spec.Ledger.Keys
Shelley.Spec.Ledger.Data.KeysData
Shelley.Spec.Ledger.LedgerState
Shelley.Spec.Ledger.Data.MetaDataData
Shelley.Spec.Ledger.MetaData
Shelley.Spec.Ledger.OCert
Shelley.Spec.Ledger.Orphans
Shelley.Spec.Ledger.Data.OCertData
Shelley.Spec.Ledger.Data.OrphansData
Shelley.Spec.Ledger.OverlaySchedule
Shelley.Spec.Ledger.Data.OverlayScheduleData
Shelley.Spec.Ledger.PParams
Shelley.Spec.Ledger.Data.PParamsData
Shelley.Spec.Ledger.Rewards
Shelley.Spec.Ledger.Scripts
Shelley.Spec.Ledger.Data.ScriptsData
Shelley.Spec.Ledger.Serialization
Shelley.Spec.Ledger.Slot
Shelley.Spec.Ledger.Data.SlotData
Shelley.Spec.Ledger.StabilityWindow
Shelley.Spec.Ledger.STS.Bbody
Shelley.Spec.Ledger.STS.Chain
Expand Down
Expand Up @@ -12,7 +12,8 @@
{-# LANGUAGE TypeApplications #-}

module Shelley.Spec.Ledger.Address
( mkVKeyRwdAcnt,
( module Shelley.Spec.Ledger.Data.AddressData,
mkVKeyRwdAcnt,
mkRwdAcnt,
scriptsToAddr,
scriptToCred,
Expand All @@ -21,11 +22,8 @@ module Shelley.Spec.Ledger.Address
serialiseAddr,
deserialiseAddr,
deserialiseAddrStakeRef,
Addr (..),
BootstrapAddress (..),
bootstrapAddressAttrsSize,
getNetwork,
RewardAcnt (..),
serialiseRewardAcnt,
deserialiseRewardAcnt,
-- Bits
Expand All @@ -50,11 +48,11 @@ module Shelley.Spec.Ledger.Address
-- TODO: these should live somewhere else
natToWord7s,
word7sToNat,
Word7 (..),
toWord7,
)
where

import Shelley.Spec.Ledger.Data.AddressData
import Cardano.Binary
( Decoder,
DecoderError (..),
Expand Down Expand Up @@ -89,8 +87,8 @@ import qualified Data.Text.Encoding as Text
import GHC.Generics (Generic)
import Numeric.Natural (Natural)
import Quiet
import Shelley.Spec.Ledger.BaseTypes (Network (..), networkToWord8, word8ToNetwork)
import Shelley.Spec.Ledger.Credential
import Shelley.Spec.Ledger.Data.BaseTypesData (Network (..), networkToWord8, word8ToNetwork)
import Shelley.Spec.Ledger.Data.CredentialData
( Credential (..),
PaymentCredential,
Ptr (..),
Expand Down Expand Up @@ -173,68 +171,13 @@ deserialiseRewardAcnt bs = case B.runGetOrFail getRewardAcnt (BSL.fromStrict bs)
Left (_remaining, _offset, _message) -> Nothing
Right (_remaining, _offset, result) -> Just result

-- | An address for UTxO.
data Addr era
= Addr !Network !(PaymentCredential era) !(StakeReference era)
| AddrBootstrap !(BootstrapAddress era)
deriving (Show, Eq, Generic, NFData, Ord)

getNetwork :: Addr era -> Network
getNetwork (Addr n _ _) = n
getNetwork (AddrBootstrap (BootstrapAddress byronAddr)) =
case Byron.aaNetworkMagic . Byron.attrData . Byron.addrAttributes $ byronAddr of
Byron.NetworkMainOrStage -> Mainnet
Byron.NetworkTestnet _ -> Testnet

instance NoUnexpectedThunks (Addr era)

-- | An account based address for rewards
data RewardAcnt era = RewardAcnt
{ getRwdNetwork :: !Network,
getRwdCred :: !(Credential 'Staking era)
}
deriving (Show, Eq, Generic, Ord, NFData, ToJSONKey, FromJSONKey)

instance Era era => ToJSON (RewardAcnt era) where
toJSON ra =
Aeson.object
[ "network" .= getRwdNetwork ra,
"credential" .= getRwdCred ra
]

instance Era era => FromJSON (RewardAcnt era) where
parseJSON =
Aeson.withObject "RewardAcnt" $ \obj ->
RewardAcnt
<$> obj .: "network"
<*> obj .: "credential"

instance NoUnexpectedThunks (RewardAcnt era)

instance Era era => ToJSONKey (Addr era) where
toJSONKey = Aeson.ToJSONKeyText addrToText (Aeson.text . addrToText)

instance Era era => FromJSONKey (Addr era) where
fromJSONKey = Aeson.FromJSONKeyTextParser parseAddr

instance Era era => ToJSON (Addr era) where
toJSON = toJSON . addrToText

instance Era era => FromJSON (Addr era) where
parseJSON = Aeson.withText "address" parseAddr

addrToText :: Addr era -> Text
addrToText =
Text.decodeLatin1 . Base16.encode . serialiseAddr

parseAddr :: Era era => Text -> Aeson.Parser (Addr era)
parseAddr t = do
bytes <- either badHex return (parseBase16 t)
maybe badFormat return (deserialiseAddr bytes)
where
badHex h = fail $ "Addresses are expected in hex encoding for now: " ++ show h
badFormat = fail "Address is not in the right format"

byron :: Int
byron = 7

Expand Down Expand Up @@ -402,9 +345,6 @@ getPtr =
<*> getVariableLengthNat
<*> getVariableLengthNat

newtype Word7 = Word7 Word8
deriving (Eq, Show)

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

Expand Down Expand Up @@ -458,14 +398,29 @@ instance Era era => ToCBOR (RewardAcnt era) where
instance Era era => FromCBOR (RewardAcnt era) where
fromCBOR = decoderFromGet "RewardAcnt" getRewardAcnt

newtype BootstrapAddress era = BootstrapAddress
{ unBootstrapAddress :: Byron.Address
}
deriving (Eq, Generic)
deriving newtype (NFData, Ord)
deriving (Show) via Quiet (BootstrapAddress era)
instance Era era => ToJSONKey (Addr era) where
toJSONKey = Aeson.ToJSONKeyText addrToText (Aeson.text . addrToText)

instance Era era => FromJSONKey (Addr era) where
fromJSONKey = Aeson.FromJSONKeyTextParser parseAddr

instance Era era => ToJSON (Addr era) where
toJSON = toJSON . addrToText

instance Era era => FromJSON (Addr era) where
parseJSON = Aeson.withText "address" parseAddr

instance NoUnexpectedThunks (BootstrapAddress era)
addrToText :: Addr era -> Text
addrToText =
Text.decodeLatin1 . Base16.encode . serialiseAddr

parseAddr :: Era era => Text -> Aeson.Parser (Addr era)
parseAddr t = do
bytes <- either badHex return (parseBase16 t)
maybe badFormat return (deserialiseAddr bytes)
where
badHex h = fail $ "Addresses are expected in hex encoding for now: " ++ show h
badFormat = fail "Address is not in the right format"

bootstrapKeyHash ::
forall era.
Expand Down
Expand Up @@ -4,39 +4,15 @@
{-# LANGUAGE OverloadedStrings #-}

module Shelley.Spec.Ledger.Coin
( Coin (..),
( module Shelley.Spec.Ledger.Data.CoinData,
word64ToCoin,
coinToRational,
rationalToCoinViaFloor,
)
where

import Cardano.Binary (DecoderError (..), FromCBOR (..), ToCBOR (..))
import Cardano.Prelude (NFData, NoUnexpectedThunks (..), cborError)
import Data.Aeson (FromJSON, ToJSON)
import Data.Group (Abelian, Group (..))
import Data.Monoid (Sum (..))
import Data.PartialOrd (PartialOrd)
import Data.Text (pack)
import Shelley.Spec.Ledger.Data.CoinData
import Data.Word (Word64)
import GHC.Generics (Generic)
import Quiet

-- | The amount of value held by a transaction output.
newtype Coin = Coin {unCoin :: Integer}
deriving
( Eq,
Ord,
Enum,
NoUnexpectedThunks,
Generic,
ToJSON,
FromJSON,
NFData
)
deriving (Show) via Quiet Coin
deriving (Semigroup, Monoid, Group, Abelian) via Sum Integer
deriving newtype (PartialOrd)

word64ToCoin :: Word64 -> Coin
word64ToCoin w = Coin $ fromIntegral w
Expand All @@ -46,19 +22,3 @@ coinToRational (Coin c) = fromIntegral c

rationalToCoinViaFloor :: Rational -> Coin
rationalToCoinViaFloor r = Coin . floor $ r

isValidCoinValue :: Integer -> Bool
isValidCoinValue c = 0 <= c && c <= (fromIntegral (maxBound :: Word64))

instance ToCBOR Coin where
toCBOR (Coin c) =
if isValidCoinValue c
then toCBOR (fromInteger c :: Word64)
else toCBOR c

instance FromCBOR Coin where
fromCBOR = do
c <- fromCBOR
if isValidCoinValue c
then pure (Coin c)
else cborError $ DecoderErrorCustom "Invalid Coin Value" (pack $ show c)
@@ -0,0 +1,81 @@
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}

module Shelley.Spec.Ledger.Data.AddressData
( Addr (..),
BootstrapAddress (..),
RewardAcnt (..),
Word7 (..),
)
where

import qualified Cardano.Chain.Common as Byron
import Cardano.Ledger.Era
import Cardano.Prelude (NFData, NoUnexpectedThunks)
import Data.Aeson (FromJSON (..), FromJSONKey (..), ToJSON (..), ToJSONKey (..), (.:), (.=))
import qualified Data.Aeson as Aeson
import Data.Binary (Word8)
import GHC.Generics (Generic)
import Quiet
import Shelley.Spec.Ledger.Data.BaseTypesData (Network (..))
import Shelley.Spec.Ledger.Data.CredentialData
( Credential (..),
PaymentCredential,
StakeReference (..),
)
import Shelley.Spec.Ledger.Data.KeysData
( KeyRole (..),
)

-- | An address for UTxO.
data Addr era
= Addr !Network !(PaymentCredential era) !(StakeReference era)
| AddrBootstrap !(BootstrapAddress era)
deriving (Show, Eq, Generic, NFData, Ord)

instance NoUnexpectedThunks (Addr era)

-- | An account based address for rewards
data RewardAcnt era = RewardAcnt
{ getRwdNetwork :: !Network,
getRwdCred :: !(Credential 'Staking era)
}
deriving (Show, Eq, Generic, Ord, NFData, ToJSONKey, FromJSONKey)

instance Era era => ToJSON (RewardAcnt era) where
toJSON ra =
Aeson.object
[ "network" .= getRwdNetwork ra,
"credential" .= getRwdCred ra
]

instance Era era => FromJSON (RewardAcnt era) where
parseJSON =
Aeson.withObject "RewardAcnt" $ \obj ->
RewardAcnt
<$> obj .: "network"
<*> obj .: "credential"

instance NoUnexpectedThunks (RewardAcnt era)

newtype Word7 = Word7 Word8
deriving (Eq, Show)

newtype BootstrapAddress era = BootstrapAddress
{ unBootstrapAddress :: Byron.Address
}
deriving (Eq, Generic)
deriving newtype (NFData, Ord)
deriving (Show) via Quiet (BootstrapAddress era)

instance NoUnexpectedThunks (BootstrapAddress era)
Expand Up @@ -11,7 +11,7 @@
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE ViewPatterns #-}

module Shelley.Spec.Ledger.BaseTypes
module Shelley.Spec.Ledger.Data.BaseTypesData
( FixedPoint,
(==>),
(⭒),
Expand Down

0 comments on commit 5ff1255

Please sign in to comment.