Skip to content

Commit

Permalink
Use ShortByteString for OneEraHash
Browse files Browse the repository at this point in the history
This avoids the memory overhead that a regular strict `ByteString` has.
According to the [Haddocks of `ShortByteString`][SBS], using a
`ByteString` (unshared) for a 32 byte hash (which is the case for Byron and
Shelley) requires 72 + 32 bytes, but a `ShortByteString` requires only 32 + 32
bytes. This can make a noticeable difference in memory usage as we're keeping
lots of hashes in memory:

* O (k) in the in-memory indices of the VolatileDB (hash and prev hash)
* O(cached epochs * epoch size) in the secondary index caches of the
  ImmutableDB
* ...

[SBS]: http://hackage.haskell.org/package/bytestring-0.10.10.0/docs/Data-ByteString-Short.html#g:2
  • Loading branch information
mrBliss committed Jun 15, 2020
1 parent eee2afc commit f5950f3
Show file tree
Hide file tree
Showing 5 changed files with 14 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,8 @@ instance Arbitrary (ConsensusState (BlockProtocol blk))
-- require all hashes to have the same length.
instance Crypto sc => Arbitrary (OneEraHash (CardanoEras sc)) where
arbitrary = OneEraHash <$> oneof
[ toRawHash (Proxy @ByronBlock) <$> arbitrary
, toRawHash (Proxy @(ShelleyBlock sc)) <$> arbitrary
[ toShortRawHash (Proxy @ByronBlock) <$> arbitrary
, toShortRawHash (Proxy @(ShelleyBlock sc)) <$> arbitrary
]

instance Arbitrary (AnnTip (CardanoBlock TPraosMockCrypto)) where
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ module Ouroboros.Consensus.HardFork.Combinator.AcrossEras (

import Codec.Serialise (Serialise (..))
import Control.Monad.Except (throwError)
import qualified Data.ByteString as Strict
import Data.ByteString.Short (ShortByteString)
import Data.FingerTree.Strict (Measured (..))
import Data.SOP.Strict hiding (shift)
import Data.Text (Text)
Expand Down Expand Up @@ -119,7 +119,7 @@ newtype OneEraApplyTxErr xs = OneEraApplyTxErr { getOneEraApplyTxErr ::
-- of the hash would necessarily have to increase, and that leads to trouble.
-- So, the type parameter @xs@ here is merely a phantom one, and we just store
-- the underlying raw hash.
newtype OneEraHash (xs :: [k]) = OneEraHash { getOneEraHash :: Strict.ByteString }
newtype OneEraHash (xs :: [k]) = OneEraHash { getOneEraHash :: ShortByteString }
deriving newtype (Eq, Ord, Show, NoUnexpectedThunks, Serialise)

{-------------------------------------------------------------------------------
Expand Down Expand Up @@ -229,7 +229,7 @@ instance CanHardFork xs => HasHeader (OneEraHeader xs) where
where
getOneHash :: forall blk. SingleEraBlock blk
=> Header blk -> OneEraHash xs
getOneHash = OneEraHash . toRawHash (Proxy @blk) . blockHash
getOneHash = OneEraHash . toShortRawHash (Proxy @blk) . blockHash

blockPrevHash = hcollapse
. hcmap proxySingle (K . getOnePrev)
Expand All @@ -240,7 +240,7 @@ instance CanHardFork xs => HasHeader (OneEraHeader xs) where
getOnePrev hdr =
case blockPrevHash hdr of
GenesisHash -> GenesisHash
BlockHash h -> BlockHash (OneEraHash $ toRawHash (Proxy @blk) h)
BlockHash h -> BlockHash (OneEraHash $ toShortRawHash (Proxy @blk) h)

blockSlot = hcollapse . hcmap proxySingle (K . blockSlot) . getOneEraHeader
blockNo = hcollapse . hcmap proxySingle (K . blockNo) . getOneEraHeader
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,9 +161,9 @@ instance CanHardFork xs => HasNestedContent Header (HardForkBlock xs) where
-------------------------------------------------------------------------------}

instance CanHardFork xs => ConvertRawHash (HardForkBlock xs) where
toRawHash _ = getOneEraHash
fromRawHash _ = OneEraHash
hashSize _ = getSameValue hashSizes
toShortRawHash _ = getOneEraHash
fromShortRawHash _ = OneEraHash
hashSize _ = getSameValue hashSizes
where
hashSizes :: NP (K Word32) xs
hashSizes = hcpure proxySingle hashSizeOne
Expand Down Expand Up @@ -192,8 +192,8 @@ instance CanHardFork xs => HasAnnTip (HardForkBlock xs) where
tipInfoOne :: forall blk. SingleEraBlock blk
=> WrapTipInfo blk -> OneEraHash xs
tipInfoOne = OneEraHash
. toRawHash (Proxy @blk)
. tipInfoHash (Proxy @blk)
. toShortRawHash (Proxy @blk)
. tipInfoHash (Proxy @blk)
. unwrapTipInfo

{-------------------------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ instance CanHardFork xs
=> Point blk -> Point (HardForkBlock xs)
injPoint GenesisPoint = GenesisPoint
injPoint (BlockPoint s h) = BlockPoint s $ OneEraHash $
toRawHash (Proxy @blk) h
toShortRawHash (Proxy @blk) h

apply :: SingleEraBlock blk
=> EpochInfo Identity
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -218,14 +218,14 @@ instance Isomorphic WrapHeaderHash where
=> WrapHeaderHash (HardForkBlock '[blk]) -> WrapHeaderHash blk
project =
WrapHeaderHash
. fromRawHash (Proxy @blk) . getOneEraHash
. fromShortRawHash (Proxy @blk) . getOneEraHash
. unwrapHeaderHash

inject :: forall blk. ConvertRawHash blk
=> WrapHeaderHash blk -> WrapHeaderHash (HardForkBlock '[blk])
inject =
WrapHeaderHash
. OneEraHash . toRawHash (Proxy @blk)
. OneEraHash . toShortRawHash (Proxy @blk)
. unwrapHeaderHash

instance Isomorphic ChainHash where
Expand Down

0 comments on commit f5950f3

Please sign in to comment.