Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell2010 |
In cardano-ledger, hashing a type X
is based upon the serialization of X
. Serialization is
based upon the EncCBOR
and DecCBOR type classes, and the values produced by EncCBOR
instances for a
particular type, are not necessarily unique. For this reason, when an X
object comes
over the network in serialized form, we must preserve the original bytes that arrived over
the network, otherwise when the system hashes that object, the hash in the ledger, and the hash of
that object from the other side of the network may not agree. The module SafeHash
introduces the SafeToHash
type class that ensures that types with a (SafeToHash X)
instance store the
original bytes that arrived over the network for the value of X
. The recommended way to store the
original bytes is to use the type MemoBytes
, although there are
a few types that store their original bytes in other ways. In order to encourage the use of MemoBytes
newtypes defined as a MemoBytes
get the to derive SafeToHash
instances for free.
Synopsis
- data SafeHash c index
- class SafeToHash t where
- originalBytes ∷ t → ByteString
- originalBytesSize ∷ t → Int
- makeHashWithExplicitProxys ∷ HashAlgorithm (HASH c) ⇒ Proxy c → Proxy index → t → SafeHash c index
- class SafeToHash x ⇒ HashAnnotated x index c | x → index c
- hashAnnotated ∷ (HashAnnotated x index c, HashAlgorithm (HASH c)) ⇒ x → SafeHash c index
- class SafeToHash x ⇒ HashWithCrypto x index | x → index where
- hashWithCrypto ∷ ∀ c. HashAlgorithm (HASH c) ⇒ Proxy c → x → SafeHash c index
- unsafeMakeSafeHash ∷ Hash (HASH c) index → SafeHash c index
- castSafeHash ∷ ∀ i j c. SafeHash c i → SafeHash c j
- extractHash ∷ SafeHash c i → Hash (HASH c) i
- indexProxy ∷ HashAnnotated x index c ⇒ x → Proxy index
SafeHash and SafeToHash
data SafeHash c index Source #
A SafeHash
is a hash of something that is safe to hash. Such types store
their own serialisation bytes. The prime example is (
, but other
examples are things that consist of only ByteStrings (i.e. they are their own serialization)
or for some other reason store their original bytes.MemoBytes
t)
We do NOT export the constructor SafeHash
, but instead export other functions
such as 'hashWithCrypto, hashAnnotated
and extractHash
which have constraints
that limit their application to types which preserve their original serialization
bytes.
Instances
class SafeToHash t where Source #
Only Types that preserve their serialisation bytes are members of the
class SafeToHash
. There are only a limited number of primitive direct
instances of SafeToHash
, all but two of them are present in this file. Instead
of making explicit instances, we almost always use a newtype (around a type S
)
where their is already an instance (SafeToHash S)
. In that case the newtype
has its SafeToHash instance derived using newtype deriving. The prime example of s
is MemoBytes
.
The only exceptions are the legacy Shelley types: Metadata
and ShelleyTx
, that
preserve their serialization bytes
using a different mechanism than the use of MemoBytes
. SafeToHash
is a superclass
requirement of the classes HashAnnotated
and HashWithCrypto
(below) which
provide more convenient ways to construct SafeHashes than using makeHashWithExplicitProxys
.
originalBytes ∷ t → ByteString Source #
Extract the original bytes from t
originalBytesSize ∷ t → Int Source #
makeHashWithExplicitProxys ∷ HashAlgorithm (HASH c) ⇒ Proxy c → Proxy index → t → SafeHash c index Source #
Instances
Creating SafeHash
class SafeToHash x ⇒ HashAnnotated x index c | x → index c Source #
Types that are SafeToHash
, AND have both of the following two invariants,
are made members of the HashAnnotated class. The preconditions are:
- The type uniquely determines the
index
type tag of (SafeHash crypto index) - The type uniquely determines the
crypto
type of (SafeHash crytop index)
The SafeToHash
and the HashAnnotated
classes are designed so that their
instances can be easily derived (because their methods have default methods
when the type is a newtype around a type that is SafeToHash
). For example,
newtype T era = T S deriving Eq deriving newtype SafeToHash -- Uses {-# LANGUAGE DerivingStrategies #-} instance HashAnnotated (T era) Index (Crypto era)
After these declarations. One specialization of hashAnnotated
is
(hashAnnotated :: Era e => T e -> SafeHash (Crypto e) Index)
Instances
EraCrypto era ~ c ⇒ HashAnnotated (BinaryData era) EraIndependentData c Source # | |
Defined in Cardano.Ledger.Plutus.Data indexProxy ∷ BinaryData era → Proxy EraIndependentData Source # hashAnnotated ∷ BinaryData era → SafeHash c EraIndependentData Source # | |
EraCrypto era ~ c ⇒ HashAnnotated (Data era) EraIndependentData c Source # | |
Defined in Cardano.Ledger.Plutus.Data indexProxy ∷ Data era → Proxy EraIndependentData Source # hashAnnotated ∷ Data era → SafeHash c EraIndependentData Source # |
hashAnnotated ∷ (HashAnnotated x index c, HashAlgorithm (HASH c)) ⇒ x → SafeHash c index Source #
Create a (
,
given SafeHash
i crypto)(Hash.HashAlgorithm (HASH crypto))
and (HashAnnotated x i crypto)
instances.
class SafeToHash x ⇒ HashWithCrypto x index | x → index where Source #
Create (
values, used when the type being hashed:
SafeHash
index crypto)x
determines the index
tag but not the crypto
tag of x
Nothing
hashWithCrypto ∷ ∀ c. HashAlgorithm (HASH c) ⇒ Proxy c → x → SafeHash c index Source #
Create a (
value from SafeHash
index crypto)x
, the proxy
determines the crypto.
Instances
HashWithCrypto AnchorData AnchorData Source # | |
Defined in Cardano.Ledger.BaseTypes hashWithCrypto ∷ HashAlgorithm (HASH c) ⇒ Proxy c → AnchorData → SafeHash c AnchorData Source # |
unsafeMakeSafeHash ∷ Hash (HASH c) index → SafeHash c index Source #
Don't use this except in Testing to make Arbitrary instances, etc. Defined here, only because the Constructor is in scope here.
Other operations
castSafeHash ∷ ∀ i j c. SafeHash c i → SafeHash c j Source #
To change the index parameter of SafeHash (which is a phantom type) use castSafeHash
indexProxy ∷ HashAnnotated x index c ⇒ x → Proxy index Source #