Skip to content

Commit

Permalink
[ADP-3350] Add Read.ChainPoint (#4539)
Browse files Browse the repository at this point in the history
This pull request adds a data type `ChainPoint` to the
`Cardano.Wallet.Read` hierarchy.

In order to add this type, we also need to

* Add functions related to hashing. The `Cardano.Crypto.Hash.Class`
provides a very thoughtful API, we re-export it.
* Add a type `RawHeaderHash` that is an era-independent string of bytes
representing a `HeaderHash`.

### Comments

* This `ChainPoint` type is meant to be consistent with the other types
in the `Cardano.Wallet.Read` hierarchy, which are in turn meant to be
consistent with the ledger specification.
* The ledger specification stipulates that `SlotNo ~ Natural`. We stick
to this type.
* The goal is to eventually remove the old `primitive` types.

### Issue Number

ADP-3350
  • Loading branch information
HeinrichApfelmus committed Apr 16, 2024
2 parents ea95825 + b9e22b6 commit 9f71904
Show file tree
Hide file tree
Showing 6 changed files with 161 additions and 5 deletions.
2 changes: 2 additions & 0 deletions lib/read/cardano-wallet-read.cabal
Expand Up @@ -56,10 +56,12 @@ library
Cardano.Wallet.Read.Block.HeaderHash
Cardano.Wallet.Read.Block.SlotNo
Cardano.Wallet.Read.Block.Txs
Cardano.Wallet.Read.Chain
Cardano.Wallet.Read.Eras
Cardano.Wallet.Read.Eras.EraFun
Cardano.Wallet.Read.Eras.EraValue
Cardano.Wallet.Read.Eras.KnownEras
Cardano.Wallet.Read.Hash
Cardano.Wallet.Read.Tx
Cardano.Wallet.Read.Tx.Cardano
Cardano.Wallet.Read.Tx.CBOR
Expand Down
2 changes: 2 additions & 0 deletions lib/read/lib/Cardano/Wallet/Read.hs
Expand Up @@ -14,10 +14,12 @@ import qualified Cardano.Wallet.Read as Read
-}
module Cardano.Wallet.Read
( module Cardano.Wallet.Read.Block
, module Cardano.Wallet.Read.Chain
, module Cardano.Wallet.Read.Eras
, module Cardano.Wallet.Read.Tx
) where

import Cardano.Wallet.Read.Block
import Cardano.Wallet.Read.Chain
import Cardano.Wallet.Read.Eras
import Cardano.Wallet.Read.Tx
5 changes: 4 additions & 1 deletion lib/read/lib/Cardano/Wallet/Read/Block.hs
Expand Up @@ -24,12 +24,15 @@ import Cardano.Wallet.Read.Block.BlockNo
, getEraBlockNo
)
import Cardano.Wallet.Read.Block.HeaderHash
( HeaderHash (..)
( BHeader
, HeaderHash (..)
, HeaderHashT
, PrevHeaderHash (..)
, PrevHeaderHashT
, RawHeaderHash
, getEraHeaderHash
, getEraPrevHeaderHash
, getRawHeaderHash
)
import Cardano.Wallet.Read.Block.SlotNo
( SlotNo (..)
Expand Down
55 changes: 51 additions & 4 deletions lib/read/lib/Cardano/Wallet/Read/Block/HeaderHash.hs
Expand Up @@ -5,9 +5,14 @@
{-# LANGUAGE TypeOperators #-}

module Cardano.Wallet.Read.Block.HeaderHash
( getEraHeaderHash
, HeaderHash (..)
( HeaderHash (..)
, HeaderHashT
, getEraHeaderHash

, BHeader
, RawHeaderHash
, getRawHeaderHash

, PrevHeaderHash (..)
, PrevHeaderHashT
, getEraPrevHeaderHash
Expand Down Expand Up @@ -46,15 +51,24 @@ import Cardano.Wallet.Read.Eras.KnownEras
( Era (..)
, IsEra (..)
)
import Cardano.Wallet.Read.Hash
( Blake2b_256
, Hash
, castHash
, hashFromBytesShort
)
import Data.Maybe
( fromJust
)
import Ouroboros.Consensus.Block.Abstract
( headerPrevHash
)
import Ouroboros.Consensus.Byron.Ledger
( ByronBlock
, ByronHash
, ByronHash (unByronHash)
)
import Ouroboros.Consensus.Shelley.Ledger
( ShelleyHash
( ShelleyHash (unShelleyHash)
)
import Ouroboros.Consensus.Shelley.Protocol.Abstract
( ProtoCrypto
Expand All @@ -64,12 +78,17 @@ import Ouroboros.Consensus.Shelley.Protocol.Praos
import Ouroboros.Consensus.Shelley.Protocol.TPraos
()

import qualified Cardano.Crypto.Hashing as Byron
import qualified Cardano.Ledger.Api as L
import qualified Cardano.Ledger.Shelley.API as Shelley
import qualified Ouroboros.Consensus.Shelley.Ledger.Block as O
import qualified Ouroboros.Consensus.Shelley.Protocol.Abstract as Shelley
import qualified Ouroboros.Network.Block as O

{-----------------------------------------------------------------------------
HeaderHash
------------------------------------------------------------------------------}

-- | Era-specific header hash type from the ledger
type family HeaderHashT era where
HeaderHashT Byron = ByronHash
Expand Down Expand Up @@ -106,6 +125,34 @@ getHeaderHashShelley
getHeaderHashShelley
(O.ShelleyBlock (Shelley.Block header _) _) = Shelley.pHeaderHash header

-- | Tag representing a block header.
data BHeader

-- | Raw hash digest for a block header.
type RawHeaderHash = Hash Blake2b_256 BHeader

{-# INLINABLE getRawHeaderHash #-}
getRawHeaderHash :: forall era. IsEra era => HeaderHash era -> RawHeaderHash
getRawHeaderHash = case theEra @era of
Byron -> \(HeaderHash h) -> fromByron h
Shelley -> \(HeaderHash h) -> castHash $ unShelleyHash h
Allegra -> \(HeaderHash h) -> castHash $ unShelleyHash h
Mary -> \(HeaderHash h) -> castHash $ unShelleyHash h
Alonzo -> \(HeaderHash h) -> castHash $ unShelleyHash h
Babbage -> \(HeaderHash h) -> castHash $ unShelleyHash h
Conway -> \(HeaderHash h) -> castHash $ unShelleyHash h
where
fromByron :: ByronHash -> Hash Blake2b_256 BHeader
fromByron =
fromJust
. hashFromBytesShort
. Byron.abstractHashToShort
. unByronHash

{-----------------------------------------------------------------------------
PrevHeaderHash
------------------------------------------------------------------------------}

-- | Era-specific previous header hash type from the ledger
type family PrevHeaderHashT era where
PrevHeaderHashT Byron = O.ChainHash ByronBlock
Expand Down
64 changes: 64 additions & 0 deletions lib/read/lib/Cardano/Wallet/Read/Chain.hs
@@ -0,0 +1,64 @@
{-# LANGUAGE DeriveGeneric #-}
{- |
Copyright: © 2024 Cardano Foundation
License: Apache-2.0
Data types relating to the consensus about the blockchain.
-}
module Cardano.Wallet.Read.Chain
( ChainPoint (GenesisPoint, BlockPoint)
, getChainPoint
, prettyChainPoint
) where

import Prelude

import Cardano.Wallet.Read.Block
( Block
, RawHeaderHash
, SlotNo (..)
, getEraHeaderHash
, getEraSlotNo
, getRawHeaderHash
)
import Cardano.Wallet.Read.Eras
( IsEra
)
import GHC.Generics
( Generic
)
import NoThunks.Class
( NoThunks (..)
)

import qualified Cardano.Wallet.Read.Hash as Hash
import qualified Data.Text as T

{-----------------------------------------------------------------------------
ChainPoint
------------------------------------------------------------------------------}

-- | A point (block) on the Cardano blockchain.
data ChainPoint
= GenesisPoint
| BlockPoint !SlotNo !RawHeaderHash
deriving (Eq, Ord, Show, Generic)

instance NoThunks ChainPoint

{-# INLINABLE getChainPoint #-}
getChainPoint :: IsEra era => Block era -> ChainPoint
getChainPoint block =
BlockPoint
(getEraSlotNo block)
(getRawHeaderHash $ getEraHeaderHash block)

-- | Short printed representation of a 'ChainPoint'.
prettyChainPoint :: ChainPoint -> T.Text
prettyChainPoint GenesisPoint =
"[point genesis]"
prettyChainPoint (BlockPoint slot hash) =
"[point " <> hashF hash <> " at slot " <> slotF slot <> "]"
where
hashF = T.take 8 . Hash.hashToTextAsHex
slotF (SlotNo n) = T.pack (show n)
38 changes: 38 additions & 0 deletions lib/read/lib/Cardano/Wallet/Read/Hash.hs
@@ -0,0 +1,38 @@
{- |
Copyright: © 2024 Cardano Foundation
License: Apache-2.0
Abstract and specific Hash functionality.
-}
module Cardano.Wallet.Read.Hash
( -- * Core operations
H.Hash
, H.HashAlgorithm (H.digest, H.hashAlgorithmName)
, H.sizeHash
, H.hashWith

-- * Conversions
, H.castHash
, H.hashToBytes
, H.hashFromBytes
, H.hashToBytesShort
, H.hashFromBytesShort

-- * Rendering and parsing
, H.hashToBytesAsHex
, H.hashFromBytesAsHex
, H.hashToTextAsHex
, H.hashFromTextAsHex
, H.hashToStringAsHex
, H.hashFromStringAsHex

-- * Specific Hash algorithms
, Blake2b_224
, Blake2b_256
) where

import Cardano.Crypto.Hash.Blake2b
( Blake2b_224
, Blake2b_256
)
import qualified Cardano.Crypto.Hash.Class as H

0 comments on commit 9f71904

Please sign in to comment.