-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Consensus layer for the Ouroboros blockchain protocol
--   
--   Consensus layer for the Ouroboros blockchain protocol
@package ouroboros-consensus
@version 0.1.0.0


-- | Strict variant of SOP
--   
--   This does not currently attempt to be exhaustive.
module Data.SOP.Strict
data NP :: (k -> Type) -> [k] -> Type
[Nil] :: NP f '[]
[:*] :: !f x -> !NP f xs -> NP f (x : xs)
infixr 5 :*
hd :: NP f (x : xs) -> f x
tl :: NP f (x : xs) -> NP f xs
data NS :: (k -> Type) -> [k] -> Type
[Z] :: !f x -> NS f (x : xs)
[S] :: !NS f xs -> NS f (x : xs)
unZ :: NS f '[x] -> f x
index_NS :: forall f xs. NS f xs -> Int
type Injection (f :: k -> Type) (xs :: [k]) = f -.-> K (NS f xs)
injections :: forall xs f. SListI xs => NP (Injection f xs) xs

-- | <a>Proxy</a> is a type that holds no data, but has a phantom parameter
--   of arbitrary type (or even kind). Its use is to provide type
--   information, even though there is no value available of that type (or
--   it may be too costly to create one).
--   
--   Historically, <tt><a>Proxy</a> :: <a>Proxy</a> a</tt> is a safer
--   alternative to the <tt><a>undefined</a> :: a</tt> idiom.
--   
--   <pre>
--   &gt;&gt;&gt; Proxy :: Proxy (Void, Int -&gt; Int)
--   Proxy
--   </pre>
--   
--   Proxy can even hold types of higher kinds,
--   
--   <pre>
--   &gt;&gt;&gt; Proxy :: Proxy Either
--   Proxy
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; Proxy :: Proxy Functor
--   Proxy
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; Proxy :: Proxy complicatedStructure
--   Proxy
--   </pre>
data Proxy (t :: k)
Proxy :: Proxy (t :: k)

-- | Constrained version of <a>compare_SOP</a>.
ccompare_SOP :: forall k (c :: k -> Constraint) proxy r (f :: k -> Type) (g :: k -> Type) (xss :: [[k]]). All2 c xss => proxy c -> r -> (forall (xs :: [k]). All c xs => NP f xs -> NP g xs -> r) -> r -> SOP f xss -> SOP g xss -> r

-- | Compare two sums of products with respect to the choice in the sum
--   they are making.
--   
--   Only the sum structure is used for comparison. This is a small wrapper
--   around <a>ccompare_NS</a> for a common special case.
compare_SOP :: forall k r (f :: k -> Type) (g :: k -> Type) (xss :: [[k]]). r -> (forall (xs :: [k]). () => NP f xs -> NP g xs -> r) -> r -> SOP f xss -> SOP g xss -> r

-- | Constrained version of <a>compare_NS</a>.
ccompare_NS :: forall k c proxy r f g (xs :: [k]). All c xs => proxy c -> r -> (forall (x :: k). c x => f x -> g x -> r) -> r -> NS f xs -> NS g xs -> r

-- | Compare two sums with respect to the choice they are making.
--   
--   A value that chooses the first option is considered smaller than one
--   that chooses the second option.
--   
--   If the choices are different, then either the first (if the first is
--   smaller than the second) or the third (if the first is larger than the
--   second) argument are called. If both choices are equal, then the
--   second argument is called, which has access to the elements contained
--   in the sums.
compare_NS :: forall k r f g (xs :: [k]). r -> (forall (x :: k). () => f x -> g x -> r) -> r -> NS f xs -> NS g xs -> r

-- | Apply injections to a product of product.
--   
--   This operates on the outer product only. Given a product containing
--   all possible choices (that are products), produce a list of sums (of
--   products) by applying each injection to the appropriate element.
--   
--   <i>Example:</i>
--   
--   <pre>
--   &gt;&gt;&gt; apInjs_POP (POP ((I 'x' :* Nil) :* (I True :* I 2 :* Nil) :* Nil))
--   [SOP (Z (I 'x' :* Nil)),SOP (S (Z (I True :* I 2 :* Nil)))]
--   </pre>
apInjs_POP :: forall k (xss :: [[k]]) (f :: k -> Type). SListI xss => POP f xss -> [SOP f xss]

-- | Apply injections to a product.
--   
--   Given a product containing all possible choices, produce a list of
--   sums by applying each injection to the appropriate element.
--   
--   <i>Example:</i>
--   
--   <pre>
--   &gt;&gt;&gt; apInjs_NP (I 'x' :* I True :* I 2 :* Nil)
--   [Z (I 'x'),S (Z (I True)),S (S (Z (I 2)))]
--   </pre>
apInjs_NP :: forall k (xs :: [k]) (f :: k -> Type). SListI xs => NP f xs -> [NS f xs]

-- | Shift an injection.
--   
--   Given an injection, return an injection into a sum that is one
--   component larger.
shift :: forall a1 (f :: a1 -> Type) (xs :: [a1]) (a2 :: a1) (x :: a1). Injection f xs a2 -> Injection f (x : xs) a2

-- | Unwrap a sum of products.
unSOP :: forall k (f :: k -> Type) (xss :: [[k]]). SOP f xss -> NS (NP f) xss

-- | A sum of products.
--   
--   This is a 'newtype' for an <a>NS</a> of an <a>NP</a>. The elements of
--   the (inner) products are applications of the parameter <tt>f</tt>. The
--   type <a>SOP</a> is indexed by the list of lists that determines the
--   sizes of both the (outer) sum and all the (inner) products, as well as
--   the types of all the elements of the inner products.
--   
--   A <tt><a>SOP</a> <a>I</a></tt> reflects the structure of a normal
--   Haskell datatype. The sum structure represents the choice between the
--   different constructors, the product structure represents the arguments
--   of each constructor.
newtype SOP (f :: k -> Type) (xss :: [[k]])
SOP :: NS (NP f) xss -> SOP (f :: k -> Type) (xss :: [[k]])

-- | Like <a>hcliftA'</a>, but for ternary functions.
hcliftA3' :: forall k (c :: k -> Constraint) (xss :: [[k]]) h proxy f f' f'' f'''. (All2 c xss, Prod h ~ (NP :: ([k] -> Type) -> [[k]] -> Type), HAp h) => proxy c -> (forall (xs :: [k]). All c xs => f xs -> f' xs -> f'' xs -> f''' xs) -> Prod h f xss -> Prod h f' xss -> h f'' xss -> h f''' xss

-- | Like <a>hcliftA'</a>, but for binary functions.
hcliftA2' :: forall k (c :: k -> Constraint) (xss :: [[k]]) h proxy f f' f''. (All2 c xss, Prod h ~ (NP :: ([k] -> Type) -> [[k]] -> Type), HAp h) => proxy c -> (forall (xs :: [k]). All c xs => f xs -> f' xs -> f'' xs) -> Prod h f xss -> h f' xss -> h f'' xss

-- | Lift a constrained function operating on a list-indexed structure to a
--   function on a list-of-list-indexed structure.
--   
--   This is a variant of <a>hcliftA</a>.
--   
--   <i>Specification:</i>
--   
--   <pre>
--   <a>hcliftA'</a> p f xs = <a>hpure</a> (<a>fn_2</a> $ \ <tt>AllDictC</tt> -&gt; f) ` <a>hap</a> ` <tt>allDict_NP</tt> p ` <a>hap</a> ` xs
--   </pre>
--   
--   <i>Instances:</i>
--   
--   <pre>
--   <a>hcliftA'</a> :: <a>All2</a> c xss =&gt; proxy c -&gt; (forall xs. <a>All</a> c xs =&gt; f xs -&gt; f' xs) -&gt; <a>NP</a> f xss -&gt; <a>NP</a> f' xss
--   <a>hcliftA'</a> :: <a>All2</a> c xss =&gt; proxy c -&gt; (forall xs. <a>All</a> c xs =&gt; f xs -&gt; f' xs) -&gt; <a>NS</a> f xss -&gt; <a>NS</a> f' xss
--   </pre>
hcliftA' :: forall k (c :: k -> Constraint) (xss :: [[k]]) h proxy f f'. (All2 c xss, Prod h ~ (NP :: ([k] -> Type) -> [[k]] -> Type), HAp h) => proxy c -> (forall (xs :: [k]). All c xs => f xs -> f' xs) -> h f xss -> h f' xss
shiftProjection :: forall a1 (f :: a1 -> Type) (xs :: [a1]) (a2 :: a1) (x :: a1). Projection f xs a2 -> Projection f (x : xs) a2

-- | Compute all projections from an n-ary product.
--   
--   Each element of the resulting product contains one of the projections.
projections :: forall k (xs :: [k]) (f :: k -> Type). SListI xs => NP (Projection f xs) xs

-- | Construct a homogeneous n-ary product from a normal Haskell list.
--   
--   Returns <a>Nothing</a> if the length of the list does not exactly
--   match the expected size of the product.
fromList :: forall k (xs :: [k]) a. SListI xs => [a] -> Maybe (NP (K a :: k -> Type) xs)

-- | Unwrap a product of products.
unPOP :: forall k (f :: k -> Type) (xss :: [[k]]). POP f xss -> NP (NP f) xss

-- | A product of products.
--   
--   This is a 'newtype' for an <a>NP</a> of an <a>NP</a>. The elements of
--   the inner products are applications of the parameter <tt>f</tt>. The
--   type <a>POP</a> is indexed by the list of lists that determines the
--   lengths of both the outer and all the inner products, as well as the
--   types of all the elements of the inner products.
--   
--   A <a>POP</a> is reminiscent of a two-dimensional table (but the inner
--   lists can all be of different length). In the context of the SOP
--   approach to generic programming, a <a>POP</a> is useful to represent
--   information that is available for all arguments of all constructors of
--   a datatype.
newtype POP (f :: k -> Type) (xss :: [[k]])
POP :: NP (NP f) xss -> POP (f :: k -> Type) (xss :: [[k]])

-- | The type of projections from an n-ary product.
--   
--   A projection is a function from the n-ary product to a single element.
type Projection (f :: k -> Type) (xs :: [k]) = K NP f xs :: k -> Type -.-> f

-- | The length of a type-level list.
lengthSList :: forall k (xs :: [k]) proxy. SListI xs => proxy xs -> Int

-- | The shape of a type-level list.
shape :: forall k (xs :: [k]). SListI xs => Shape xs

-- | Get hold of an explicit singleton (that one can then pattern match on)
--   for a type-level list
sList :: forall k (xs :: [k]). SListI xs => SList xs

-- | Case distinction on a type-level list.
case_SList :: forall k (xs :: [k]) r. SListI xs => r ('[] :: [k]) -> (forall (y :: k) (ys :: [k]). SListI ys => r (y : ys)) -> r xs

-- | Paramorphism for a type-level list.
para_SList :: forall k (xs :: [k]) r. SListI xs => r ('[] :: [k]) -> (forall (y :: k) (ys :: [k]). SListI ys => r ys -> r (y : ys)) -> r xs

-- | Explicit singleton list.
--   
--   A singleton list can be used to reveal the structure of a type-level
--   list argument that the function is quantified over. For every
--   type-level list <tt>xs</tt>, there is one non-bottom value of type
--   <tt><a>SList</a> xs</tt>.
--   
--   Note that these singleton lists are polymorphic in the list elements;
--   we do not require a singleton representation for them.
data SList (a :: [k])
[SNil] :: forall k. SList ('[] :: [k])
[SCons] :: forall k (xs :: [k]) (x :: k). SListI xs => SList (x : xs)

-- | Occasionally it is useful to have an explicit, term-level,
--   representation of type-level lists (esp because of
--   <a>https://ghc.haskell.org/trac/ghc/ticket/9108</a> )
data Shape (a :: [k])
[ShapeNil] :: forall k. Shape ('[] :: [k])
[ShapeCons] :: forall k (xs :: [k]) (x :: k). SListI xs => Shape xs -> Shape (x : xs)

-- | Specialization of <a>hcoerce</a>.
htoI :: forall k1 l1 l2 h1 (f :: k1 -> Type) (xs :: l1) (ys :: l2) h2. (AllZipN (Prod h1) (LiftedCoercible f I) xs ys, HTrans h1 h2) => h1 f xs -> h2 I ys

-- | Specialization of <a>hcoerce</a>.
hfromI :: forall l1 k2 l2 h1 (f :: k2 -> Type) (xs :: l1) (ys :: l2) h2. (AllZipN (Prod h1) (LiftedCoercible I f) xs ys, HTrans h1 h2) => h1 I xs -> h2 f ys

-- | Special case of <a>hsequence'</a> where <tt>g = <a>K</a> a</tt>.
hsequenceK :: forall k l h (xs :: l) f a. (SListIN h xs, SListIN (Prod h) xs, Applicative f, HSequence h) => h (K (f a) :: k -> Type) xs -> f (h (K a :: k -> Type) xs)

-- | Special case of <a>hsequence'</a> where <tt>g = <a>I</a></tt>.
hsequence :: forall l h (xs :: l) f. (SListIN h xs, SListIN (Prod h) xs, HSequence h, Applicative f) => h f xs -> f (h I xs)

-- | Flipped version of <a>hctraverse</a>.
hcfor :: forall l h c (xs :: l) g proxy f. (HSequence h, AllN h c xs, Applicative g) => proxy c -> h f xs -> (forall a. c a => f a -> g a) -> g (h I xs)

-- | Special case of <a>hctraverse'</a> where <tt>f' = <a>I</a></tt>.
hctraverse :: forall l h c (xs :: l) g proxy f. (HSequence h, AllN h c xs, Applicative g) => proxy c -> (forall a. c a => f a -> g a) -> h f xs -> g (h I xs)

-- | Special case of <a>hctraverse_</a>.
hcfoldMap :: forall k l h c (xs :: l) m proxy f. (HTraverse_ h, AllN h c xs, Monoid m) => proxy c -> (forall (a :: k). c a => f a -> m) -> h f xs -> m

-- | Flipped version of <a>hctraverse_</a>.
hcfor_ :: forall k l h c (xs :: l) g proxy f. (HTraverse_ h, AllN h c xs, Applicative g) => proxy c -> h f xs -> (forall (a :: k). c a => f a -> g ()) -> g ()

-- | Another name for <a>hcliftA3</a>.
hczipWith3 :: forall k l h c (xs :: l) proxy f f' f'' f'''. (AllN (Prod h) c xs, HAp h, HAp (Prod h)) => proxy c -> (forall (a :: k). c a => f a -> f' a -> f'' a -> f''' a) -> Prod h f xs -> Prod h f' xs -> h f'' xs -> h f''' xs

-- | Another name for <a>hcliftA2</a>.
hczipWith :: forall k l h c (xs :: l) proxy f f' f''. (AllN (Prod h) c xs, HAp h, HAp (Prod h)) => proxy c -> (forall (a :: k). c a => f a -> f' a -> f'' a) -> Prod h f xs -> h f' xs -> h f'' xs

-- | Another name for <a>hcliftA</a>.
hcmap :: forall k l h c (xs :: l) proxy f f'. (AllN (Prod h) c xs, HAp h) => proxy c -> (forall (a :: k). c a => f a -> f' a) -> h f xs -> h f' xs

-- | Variant of <a>hcliftA3</a> that takes a constrained function.
--   
--   <i>Specification:</i>
--   
--   <pre>
--   <a>hcliftA3</a> p f xs ys zs = <a>hcpure</a> p (<a>fn_3</a> f) ` <a>hap</a> ` xs ` <a>hap</a> ` ys ` <a>hap</a> ` zs
--   </pre>
hcliftA3 :: forall k l h c (xs :: l) proxy f f' f'' f'''. (AllN (Prod h) c xs, HAp h, HAp (Prod h)) => proxy c -> (forall (a :: k). c a => f a -> f' a -> f'' a -> f''' a) -> Prod h f xs -> Prod h f' xs -> h f'' xs -> h f''' xs

-- | Variant of <a>hcliftA2</a> that takes a constrained function.
--   
--   <i>Specification:</i>
--   
--   <pre>
--   <a>hcliftA2</a> p f xs ys = <a>hcpure</a> p (<a>fn_2</a> f) ` <a>hap</a> ` xs ` <a>hap</a> ` ys
--   </pre>
hcliftA2 :: forall k l h c (xs :: l) proxy f f' f''. (AllN (Prod h) c xs, HAp h, HAp (Prod h)) => proxy c -> (forall (a :: k). c a => f a -> f' a -> f'' a) -> Prod h f xs -> h f' xs -> h f'' xs

-- | Variant of <a>hliftA</a> that takes a constrained function.
--   
--   <i>Specification:</i>
--   
--   <pre>
--   <a>hcliftA</a> p f xs = <a>hcpure</a> p (<a>fn</a> f) ` <a>hap</a> ` xs
--   </pre>
hcliftA :: forall k l h c (xs :: l) proxy f f'. (AllN (Prod h) c xs, HAp h) => proxy c -> (forall (a :: k). c a => f a -> f' a) -> h f xs -> h f' xs

-- | Another name for <a>hliftA3</a>.
hzipWith3 :: forall k l h (xs :: l) f f' f'' f'''. (SListIN (Prod h) xs, HAp h, HAp (Prod h)) => (forall (a :: k). () => f a -> f' a -> f'' a -> f''' a) -> Prod h f xs -> Prod h f' xs -> h f'' xs -> h f''' xs

-- | Another name for <a>hliftA2</a>.
hzipWith :: forall k l h (xs :: l) f f' f''. (SListIN (Prod h) xs, HAp h, HAp (Prod h)) => (forall (a :: k). () => f a -> f' a -> f'' a) -> Prod h f xs -> h f' xs -> h f'' xs

-- | Another name for <a>hliftA</a>.
hmap :: forall k l h (xs :: l) f f'. (SListIN (Prod h) xs, HAp h) => (forall (a :: k). () => f a -> f' a) -> h f xs -> h f' xs

-- | A generalized form of <a>liftA3</a>, which in turn is a generalized
--   <a>zipWith3</a>.
--   
--   Takes a lifted ternary function and uses it to combine three
--   structures of equal shape into a single structure.
--   
--   It either takes three product structures to a product structure, or
--   two product structures and one sum structure to a sum structure.
--   
--   <i>Specification:</i>
--   
--   <pre>
--   <a>hliftA3</a> f xs ys zs = <a>hpure</a> (<a>fn_3</a> f) ` <a>hap</a> ` xs ` <a>hap</a> ` ys ` <a>hap</a> ` zs
--   </pre>
--   
--   <i>Instances:</i>
--   
--   <pre>
--   <a>hliftA3</a>, <a>liftA3_NP</a>  :: <a>SListI</a>  xs  =&gt; (forall a. f a -&gt; f' a -&gt; f'' a -&gt; f''' a) -&gt; <a>NP</a>  f xs  -&gt; <a>NP</a>  f' xs  -&gt; <a>NP</a>  f'' xs  -&gt; <a>NP</a>  f''' xs
--   <a>hliftA3</a>, <a>liftA3_NS</a>  :: <a>SListI</a>  xs  =&gt; (forall a. f a -&gt; f' a -&gt; f'' a -&gt; f''' a) -&gt; <a>NP</a>  f xs  -&gt; <a>NP</a>  f' xs  -&gt; <a>NS</a>  f'' xs  -&gt; <a>NS</a>  f''' xs
--   <a>hliftA3</a>, <a>liftA3_POP</a> :: <a>SListI2</a> xss =&gt; (forall a. f a -&gt; f' a -&gt; f'' a -&gt; f''' a) -&gt; <a>POP</a> f xss -&gt; <a>POP</a> f' xss -&gt; <a>POP</a> f'' xss -&gt; <a>POP</a> f''' xs
--   <a>hliftA3</a>, <a>liftA3_SOP</a> :: <a>SListI2</a> xss =&gt; (forall a. f a -&gt; f' a -&gt; f'' a -&gt; f''' a) -&gt; <a>POP</a> f xss -&gt; <a>POP</a> f' xss -&gt; <a>SOP</a> f'' xss -&gt; <a>SOP</a> f''' xs
--   </pre>
hliftA3 :: forall k l h (xs :: l) f f' f'' f'''. (SListIN (Prod h) xs, HAp h, HAp (Prod h)) => (forall (a :: k). () => f a -> f' a -> f'' a -> f''' a) -> Prod h f xs -> Prod h f' xs -> h f'' xs -> h f''' xs

-- | A generalized form of <a>liftA2</a>, which in turn is a generalized
--   <a>zipWith</a>.
--   
--   Takes a lifted binary function and uses it to combine two structures
--   of equal shape into a single structure.
--   
--   It either takes two product structures to a product structure, or one
--   product and one sum structure to a sum structure.
--   
--   <i>Specification:</i>
--   
--   <pre>
--   <a>hliftA2</a> f xs ys = <a>hpure</a> (<a>fn_2</a> f) ` <a>hap</a> ` xs ` <a>hap</a> ` ys
--   </pre>
--   
--   <i>Instances:</i>
--   
--   <pre>
--   <a>hliftA2</a>, <a>liftA2_NP</a>  :: <a>SListI</a>  xs  =&gt; (forall a. f a -&gt; f' a -&gt; f'' a) -&gt; <a>NP</a>  f xs  -&gt; <a>NP</a>  f' xs  -&gt; <a>NP</a>  f'' xs
--   <a>hliftA2</a>, <a>liftA2_NS</a>  :: <a>SListI</a>  xs  =&gt; (forall a. f a -&gt; f' a -&gt; f'' a) -&gt; <a>NP</a>  f xs  -&gt; <a>NS</a>  f' xs  -&gt; <a>NS</a>  f'' xs
--   <a>hliftA2</a>, <a>liftA2_POP</a> :: <a>SListI2</a> xss =&gt; (forall a. f a -&gt; f' a -&gt; f'' a) -&gt; <a>POP</a> f xss -&gt; <a>POP</a> f' xss -&gt; <a>POP</a> f'' xss
--   <a>hliftA2</a>, <a>liftA2_SOP</a> :: <a>SListI2</a> xss =&gt; (forall a. f a -&gt; f' a -&gt; f'' a) -&gt; <a>POP</a> f xss -&gt; <a>SOP</a> f' xss -&gt; <a>SOP</a> f'' xss
--   </pre>
hliftA2 :: forall k l h (xs :: l) f f' f''. (SListIN (Prod h) xs, HAp h, HAp (Prod h)) => (forall (a :: k). () => f a -> f' a -> f'' a) -> Prod h f xs -> h f' xs -> h f'' xs

-- | A generalized form of <a>liftA</a>, which in turn is a generalized
--   <a>map</a>.
--   
--   Takes a lifted function and applies it to every element of a structure
--   while preserving its shape.
--   
--   <i>Specification:</i>
--   
--   <pre>
--   <a>hliftA</a> f xs = <a>hpure</a> (<a>fn</a> f) ` <a>hap</a> ` xs
--   </pre>
--   
--   <i>Instances:</i>
--   
--   <pre>
--   <a>hliftA</a>, <a>liftA_NP</a>  :: <a>SListI</a>  xs  =&gt; (forall a. f a -&gt; f' a) -&gt; <a>NP</a>  f xs  -&gt; <a>NP</a>  f' xs
--   <a>hliftA</a>, <a>liftA_NS</a>  :: <a>SListI</a>  xs  =&gt; (forall a. f a -&gt; f' a) -&gt; <a>NS</a>  f xs  -&gt; <a>NS</a>  f' xs
--   <a>hliftA</a>, <a>liftA_POP</a> :: <a>SListI2</a> xss =&gt; (forall a. f a -&gt; f' a) -&gt; <a>POP</a> f xss -&gt; <a>POP</a> f' xss
--   <a>hliftA</a>, <a>liftA_SOP</a> :: <a>SListI2</a> xss =&gt; (forall a. f a -&gt; f' a) -&gt; <a>SOP</a> f xss -&gt; <a>SOP</a> f' xss
--   </pre>
hliftA :: forall k l h (xs :: l) f f'. (SListIN (Prod h) xs, HAp h) => (forall (a :: k). () => f a -> f' a) -> h f xs -> h f' xs

-- | Construct a quarternary lifted function.
fn_4 :: forall k f (a :: k) f' f'' f''' f''''. (f a -> f' a -> f'' a -> f''' a -> f'''' a) -> (f -.-> (f' -.-> (f'' -.-> (f''' -.-> f'''')))) a

-- | Construct a ternary lifted function.
fn_3 :: forall k f (a :: k) f' f'' f'''. (f a -> f' a -> f'' a -> f''' a) -> (f -.-> (f' -.-> (f'' -.-> f'''))) a

-- | Construct a binary lifted function.
fn_2 :: forall k f (a :: k) f' f''. (f a -> f' a -> f'' a) -> (f -.-> (f' -.-> f'')) a

-- | Construct a lifted function.
--   
--   Same as <a>Fn</a>. Only available for uniformity with the higher-arity
--   versions.
fn :: forall k f (a :: k) f'. (f a -> f' a) -> (f -.-> f') a

-- | A generalization of <a>pure</a> or <a>return</a> to higher kinds.
class HPure (h :: k -> Type -> l -> Type)

-- | Corresponds to <a>pure</a> directly.
--   
--   <i>Instances:</i>
--   
--   <pre>
--   <a>hpure</a>, <a>pure_NP</a>  :: <a>SListI</a>  xs  =&gt; (forall a. f a) -&gt; <a>NP</a>  f xs
--   <a>hpure</a>, <a>pure_POP</a> :: <a>SListI2</a> xss =&gt; (forall a. f a) -&gt; <a>POP</a> f xss
--   </pre>
hpure :: forall (xs :: l) f. (HPure h, SListIN h xs) => (forall (a :: k). () => f a) -> h f xs

-- | A variant of <a>hpure</a> that allows passing in a constrained
--   argument.
--   
--   Calling <tt><a>hcpure</a> f s</tt> where <tt>s :: h f xs</tt> causes
--   <tt>f</tt> to be applied at all the types that are contained in
--   <tt>xs</tt>. Therefore, the constraint <tt>c</tt> has to be satisfied
--   for all elements of <tt>xs</tt>, which is what <tt><a>AllN</a> h c
--   xs</tt> states.
--   
--   <i>Instances:</i>
--   
--   <pre>
--   <a>hcpure</a>, <a>cpure_NP</a>  :: (<a>All</a>  c xs ) =&gt; proxy c -&gt; (forall a. c a =&gt; f a) -&gt; <a>NP</a>  f xs
--   <a>hcpure</a>, <a>cpure_POP</a> :: (<a>All2</a> c xss) =&gt; proxy c -&gt; (forall a. c a =&gt; f a) -&gt; <a>POP</a> f xss
--   </pre>
hcpure :: forall c (xs :: l) proxy f. (HPure h, AllN h c xs) => proxy c -> (forall (a :: k). c a => f a) -> h f xs

-- | Lifted functions.
newtype ( (f :: k -> Type) -.-> (g :: k -> Type) ) (a :: k)
Fn :: (f a -> g a) -> (-.->) (f :: k -> Type) (g :: k -> Type) (a :: k)
[apFn] :: (-.->) (f :: k -> Type) (g :: k -> Type) (a :: k) -> f a -> g a
infixr 1 -.->

-- | Maps a structure containing sums to the corresponding product
--   structure.
type family Prod (h :: k -> Type -> l -> Type) :: k -> Type -> l -> Type

-- | A generalization of <a>&lt;*&gt;</a>.
class (Prod Prod h ~ Prod h, HPure Prod h) => HAp (h :: k -> Type -> l -> Type)

-- | Corresponds to <a>&lt;*&gt;</a>.
--   
--   For products (<a>NP</a>) as well as products of products (<a>POP</a>),
--   the correspondence is rather direct. We combine a structure containing
--   (lifted) functions and a compatible structure containing corresponding
--   arguments into a compatible structure containing results.
--   
--   The same combinator can also be used to combine a product structure of
--   functions with a sum structure of arguments, which then results in
--   another sum structure of results. The sum structure determines which
--   part of the product structure will be used.
--   
--   <i>Instances:</i>
--   
--   <pre>
--   <a>hap</a>, <a>ap_NP</a>  :: <a>NP</a>  (f -.-&gt; g) xs  -&gt; <a>NP</a>  f xs  -&gt; <a>NP</a>  g xs
--   <a>hap</a>, <a>ap_NS</a>  :: <a>NP</a>  (f -.-&gt; g) xs  -&gt; <a>NS</a>  f xs  -&gt; <a>NS</a>  g xs
--   <a>hap</a>, <a>ap_POP</a> :: <a>POP</a> (f -.-&gt; g) xss -&gt; <a>POP</a> f xss -&gt; <a>POP</a> g xss
--   <a>hap</a>, <a>ap_SOP</a> :: <a>POP</a> (f -.-&gt; g) xss -&gt; <a>SOP</a> f xss -&gt; <a>SOP</a> g xss
--   </pre>
hap :: forall (f :: k -> Type) (g :: k -> Type) (xs :: l). HAp h => Prod h (f -.-> g) xs -> h f xs -> h g xs

-- | Maps products to lists, and sums to identities.
type family CollapseTo (h :: k -> Type -> l -> Type) x

-- | A class for collapsing a heterogeneous structure into a homogeneous
--   one.
class HCollapse (h :: k -> Type -> l -> Type)

-- | Collapse a heterogeneous structure with homogeneous elements into a
--   homogeneous structure.
--   
--   If a heterogeneous structure is instantiated to the constant functor
--   <a>K</a>, then it is in fact homogeneous. This function maps such a
--   value to a simpler Haskell datatype reflecting that. An <tt><a>NS</a>
--   (<a>K</a> a)</tt> contains a single <tt>a</tt>, and an <tt><a>NP</a>
--   (<a>K</a> a)</tt> contains a list of <tt>a</tt>s.
--   
--   <i>Instances:</i>
--   
--   <pre>
--   <a>hcollapse</a>, <a>collapse_NP</a>  :: <a>NP</a>  (<a>K</a> a) xs  -&gt;  [a]
--   <a>hcollapse</a>, <a>collapse_NS</a>  :: <a>NS</a>  (<a>K</a> a) xs  -&gt;   a
--   <a>hcollapse</a>, <a>collapse_POP</a> :: <a>POP</a> (<a>K</a> a) xss -&gt; [[a]]
--   <a>hcollapse</a>, <a>collapse_SOP</a> :: <a>SOP</a> (<a>K</a> a) xss -&gt;  [a]
--   </pre>
hcollapse :: forall (xs :: l) a. (HCollapse h, SListIN h xs) => h (K a :: k -> Type) xs -> CollapseTo h a

-- | A generalization of <a>traverse_</a> or <a>foldMap</a>.
class HTraverse_ (h :: k -> Type -> l -> Type)

-- | Corresponds to <a>traverse_</a>.
--   
--   <i>Instances:</i>
--   
--   <pre>
--   <a>hctraverse_</a>, <a>ctraverse__NP</a>  :: (<a>All</a>  c xs , <a>Applicative</a> g) =&gt; proxy c -&gt; (forall a. c a =&gt; f a -&gt; g ()) -&gt; <a>NP</a>  f xs  -&gt; g ()
--   <a>hctraverse_</a>, <a>ctraverse__NS</a>  :: (<a>All2</a> c xs , <a>Applicative</a> g) =&gt; proxy c -&gt; (forall a. c a =&gt; f a -&gt; g ()) -&gt; <a>NS</a>  f xs  -&gt; g ()
--   <a>hctraverse_</a>, <a>ctraverse__POP</a> :: (<a>All</a>  c xss, <a>Applicative</a> g) =&gt; proxy c -&gt; (forall a. c a =&gt; f a -&gt; g ()) -&gt; <a>POP</a> f xss -&gt; g ()
--   <a>hctraverse_</a>, <a>ctraverse__SOP</a> :: (<a>All2</a> c xss, <a>Applicative</a> g) =&gt; proxy c -&gt; (forall a. c a =&gt; f a -&gt; g ()) -&gt; <a>SOP</a> f xss -&gt; g ()
--   </pre>
hctraverse_ :: forall c (xs :: l) g proxy f. (HTraverse_ h, AllN h c xs, Applicative g) => proxy c -> (forall (a :: k). c a => f a -> g ()) -> h f xs -> g ()

-- | Unconstrained version of <a>hctraverse_</a>.
--   
--   <i>Instances:</i>
--   
--   <pre>
--   <tt>traverse_</tt>, <a>traverse__NP</a>  :: (<a>SListI</a>  xs , <a>Applicative</a> g) =&gt; (forall a. f a -&gt; g ()) -&gt; <a>NP</a>  f xs  -&gt; g ()
--   <tt>traverse_</tt>, <a>traverse__NS</a>  :: (<a>SListI</a>  xs , <a>Applicative</a> g) =&gt; (forall a. f a -&gt; g ()) -&gt; <a>NS</a>  f xs  -&gt; g ()
--   <tt>traverse_</tt>, <a>traverse__POP</a> :: (<a>SListI2</a> xss, <a>Applicative</a> g) =&gt; (forall a. f a -&gt; g ()) -&gt; <a>POP</a> f xss -&gt; g ()
--   <tt>traverse_</tt>, <a>traverse__SOP</a> :: (<a>SListI2</a> xss, <a>Applicative</a> g) =&gt; (forall a. f a -&gt; g ()) -&gt; <a>SOP</a> f xss -&gt; g ()
--   </pre>
htraverse_ :: forall (xs :: l) g f. (HTraverse_ h, SListIN h xs, Applicative g) => (forall (a :: k). () => f a -> g ()) -> h f xs -> g ()

-- | A generalization of <a>sequenceA</a>.
class HAp h => HSequence (h :: k -> Type -> l -> Type)

-- | Corresponds to <a>sequenceA</a>.
--   
--   Lifts an applicative functor out of a structure.
--   
--   <i>Instances:</i>
--   
--   <pre>
--   <a>hsequence'</a>, <a>sequence'_NP</a>  :: (<a>SListI</a>  xs , <a>Applicative</a> f) =&gt; <a>NP</a>  (f <a>:.:</a> g) xs  -&gt; f (<a>NP</a>  g xs )
--   <a>hsequence'</a>, <a>sequence'_NS</a>  :: (<a>SListI</a>  xs , <a>Applicative</a> f) =&gt; <a>NS</a>  (f <a>:.:</a> g) xs  -&gt; f (<a>NS</a>  g xs )
--   <a>hsequence'</a>, <a>sequence'_POP</a> :: (<a>SListI2</a> xss, <a>Applicative</a> f) =&gt; <a>POP</a> (f <a>:.:</a> g) xss -&gt; f (<a>POP</a> g xss)
--   <a>hsequence'</a>, <a>sequence'_SOP</a> :: (<a>SListI2</a> xss, <a>Applicative</a> f) =&gt; <a>SOP</a> (f <a>:.:</a> g) xss -&gt; f (<a>SOP</a> g xss)
--   </pre>
hsequence' :: forall (xs :: l) f (g :: k -> Type). (HSequence h, SListIN h xs, Applicative f) => h (f :.: g) xs -> f (h g xs)

-- | Corresponds to <a>traverse</a>.
--   
--   <i>Instances:</i>
--   
--   <pre>
--   <a>hctraverse'</a>, <a>ctraverse'_NP</a>  :: (<a>All</a>  c xs , <a>Applicative</a> g) =&gt; proxy c -&gt; (forall a. c a =&gt; f a -&gt; g (f' a)) -&gt; <a>NP</a>  f xs  -&gt; g (<a>NP</a>  f' xs )
--   <a>hctraverse'</a>, <a>ctraverse'_NS</a>  :: (<a>All2</a> c xs , <a>Applicative</a> g) =&gt; proxy c -&gt; (forall a. c a =&gt; f a -&gt; g (f' a)) -&gt; <a>NS</a>  f xs  -&gt; g (<a>NS</a>  f' xs )
--   <a>hctraverse'</a>, <a>ctraverse'_POP</a> :: (<a>All</a>  c xss, <a>Applicative</a> g) =&gt; proxy c -&gt; (forall a. c a =&gt; f a -&gt; g (f' a)) -&gt; <a>POP</a> f xss -&gt; g (<a>POP</a> f' xss)
--   <a>hctraverse'</a>, <a>ctraverse'_SOP</a> :: (<a>All2</a> c xss, <a>Applicative</a> g) =&gt; proxy c -&gt; (forall a. c a =&gt; f a -&gt; g (f' a)) -&gt; <a>SOP</a> f xss -&gt; g (<a>SOP</a> f' xss)
--   </pre>
hctraverse' :: forall c (xs :: l) g proxy f f'. (HSequence h, AllN h c xs, Applicative g) => proxy c -> (forall (a :: k). c a => f a -> g (f' a)) -> h f xs -> g (h f' xs)

-- | Unconstrained variant of <tt>htraverse</tt>`.
--   
--   <i>Instances:</i>
--   
--   <pre>
--   <a>htraverse'</a>, <a>traverse'_NP</a>  :: (<a>SListI</a>  xs , <a>Applicative</a> g) =&gt; (forall a. c a =&gt; f a -&gt; g (f' a)) -&gt; <a>NP</a>  f xs  -&gt; g (<a>NP</a>  f' xs )
--   <a>htraverse'</a>, <a>traverse'_NS</a>  :: (<a>SListI2</a> xs , <a>Applicative</a> g) =&gt; (forall a. c a =&gt; f a -&gt; g (f' a)) -&gt; <a>NS</a>  f xs  -&gt; g (<a>NS</a>  f' xs )
--   <a>htraverse'</a>, <a>traverse'_POP</a> :: (<a>SListI</a>  xss, <a>Applicative</a> g) =&gt; (forall a. c a =&gt; f a -&gt; g (f' a)) -&gt; <a>POP</a> f xss -&gt; g (<a>POP</a> f' xss)
--   <a>htraverse'</a>, <a>traverse'_SOP</a> :: (<a>SListI2</a> xss, <a>Applicative</a> g) =&gt; (forall a. c a =&gt; f a -&gt; g (f' a)) -&gt; <a>SOP</a> f xss -&gt; g (<a>SOP</a> f' xss)
--   </pre>
htraverse' :: forall (xs :: l) g f f'. (HSequence h, SListIN h xs, Applicative g) => (forall (a :: k). () => f a -> g (f' a)) -> h f xs -> g (h f' xs)

-- | A class for determining which choice in a sum-like structure a value
--   represents.
class HIndex (h :: k -> Type -> l -> Type)

-- | If <tt>h</tt> is a sum-like structure representing a choice between
--   <tt>n</tt> different options, and <tt>x</tt> is a value of type <tt>h
--   f xs</tt>, then <tt><a>hindex</a> x</tt> returns a number between
--   <tt>0</tt> and <tt>n - 1</tt> representing the index of the choice
--   made by <tt>x</tt>.
--   
--   <i>Instances:</i>
--   
--   <pre>
--   <a>hindex</a>, <a>index_NS</a>  :: <a>NS</a>  f xs -&gt; Int
--   <a>hindex</a>, <a>index_SOP</a> :: <a>SOP</a> f xs -&gt; Int
--   </pre>
--   
--   <i>Examples:</i>
--   
--   <pre>
--   &gt;&gt;&gt; hindex (S (S (Z (I False))))
--   2
--   
--   &gt;&gt;&gt; hindex (Z (K ()))
--   0
--   
--   &gt;&gt;&gt; hindex (SOP (S (Z (I True :* I 'x' :* Nil))))
--   1
--   </pre>
hindex :: forall (f :: k -> Type) (xs :: l). HIndex h => h f xs -> Int

-- | Maps a structure containing products to the corresponding sum
--   structure.
type family UnProd (h :: k -> Type -> l -> Type) :: k -> Type -> l -> Type

-- | A class for applying all injections corresponding to a sum-like
--   structure to a table containing suitable arguments.
class UnProd Prod h ~ h => HApInjs (h :: k -> Type -> l -> Type)

-- | For a given table (product-like structure), produce a list where each
--   element corresponds to the application of an injection function into
--   the corresponding sum-like structure.
--   
--   <i>Instances:</i>
--   
--   <pre>
--   <a>hapInjs</a>, <a>apInjs_NP</a>  :: <a>SListI</a>  xs  =&gt; <a>NP</a>  f xs -&gt; [<a>NS</a>  f xs ]
--   <a>hapInjs</a>, <a>apInjs_SOP</a> :: <a>SListI2</a> xss =&gt; <a>POP</a> f xs -&gt; [<a>SOP</a> f xss]
--   </pre>
--   
--   <i>Examples:</i>
--   
--   <pre>
--   &gt;&gt;&gt; hapInjs (I 'x' :* I True :* I 2 :* Nil) :: [NS I '[Char, Bool, Int]]
--   [Z (I 'x'),S (Z (I True)),S (S (Z (I 2)))]
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; hapInjs (POP ((I 'x' :* Nil) :* (I True :* I 2 :* Nil) :* Nil)) :: [SOP I '[ '[Char], '[Bool, Int]]]
--   [SOP (Z (I 'x' :* Nil)),SOP (S (Z (I True :* I 2 :* Nil)))]
--   </pre>
--   
--   Unfortunately the type-signatures are required in GHC-7.10 and older.
hapInjs :: forall (xs :: l) (f :: k -> Type). (HApInjs h, SListIN h xs) => Prod h f xs -> [h f xs]

-- | A class for expanding sum structures into corresponding product
--   structures, filling in the slots not targeted by the sum with default
--   values.
class HExpand (h :: k -> Type -> l -> Type)

-- | Expand a given sum structure into a corresponding product structure by
--   placing the value contained in the sum into the corresponding position
--   in the product, and using the given default value for all other
--   positions.
--   
--   <i>Instances:</i>
--   
--   <pre>
--   <a>hexpand</a>, <a>expand_NS</a>  :: <a>SListI</a> xs   =&gt; (forall x . f x) -&gt; <a>NS</a>  f xs  -&gt; <a>NP</a>  f xs
--   <a>hexpand</a>, <a>expand_SOP</a> :: <a>SListI2</a> xss =&gt; (forall x . f x) -&gt; <a>SOP</a> f xss -&gt; <a>POP</a> f xss
--   </pre>
--   
--   <i>Examples:</i>
--   
--   <pre>
--   &gt;&gt;&gt; hexpand Nothing (S (Z (Just 3))) :: NP Maybe '[Char, Int, Bool]
--   Nothing :* Just 3 :* Nothing :* Nil
--   
--   &gt;&gt;&gt; hexpand [] (SOP (S (Z ([1,2] :* "xyz" :* Nil)))) :: POP [] '[ '[Bool], '[Int, Char] ]
--   POP (([] :* Nil) :* ([1,2] :* "xyz" :* Nil) :* Nil)
--   </pre>
hexpand :: forall (xs :: l) f. (HExpand h, SListIN (Prod h) xs) => (forall (x :: k). () => f x) -> h f xs -> Prod h f xs

-- | Variant of <a>hexpand</a> that allows passing a constrained default.
--   
--   <i>Instances:</i>
--   
--   <pre>
--   <a>hcexpand</a>, <a>cexpand_NS</a>  :: <a>All</a>  c xs  =&gt; proxy c -&gt; (forall x . c x =&gt; f x) -&gt; <a>NS</a>  f xs  -&gt; <a>NP</a>  f xs
--   <a>hcexpand</a>, <a>cexpand_SOP</a> :: <a>All2</a> c xss =&gt; proxy c -&gt; (forall x . c x =&gt; f x) -&gt; <a>SOP</a> f xss -&gt; <a>POP</a> f xss
--   </pre>
--   
--   <i>Examples:</i>
--   
--   <pre>
--   &gt;&gt;&gt; hcexpand (Proxy :: Proxy Bounded) (I minBound) (S (Z (I 20))) :: NP I '[Bool, Int, Ordering]
--   I False :* I 20 :* I LT :* Nil
--   
--   &gt;&gt;&gt; hcexpand (Proxy :: Proxy Num) (I 0) (SOP (S (Z (I 1 :* I 2 :* Nil)))) :: POP I '[ '[Double], '[Int, Int] ]
--   POP ((I 0.0 :* Nil) :* (I 1 :* I 2 :* Nil) :* Nil)
--   </pre>
hcexpand :: forall c (xs :: l) proxy f. (HExpand h, AllN (Prod h) c xs) => proxy c -> (forall (x :: k). c x => f x) -> h f xs -> Prod h f xs

-- | A class for transforming structures into related structures with a
--   different index list, as long as the index lists have the same shape
--   and the elements and interpretation functions are suitably related.
class (Same h1 :: k2 -> Type -> l2 -> Type ~ h2, Same h2 :: k1 -> Type -> l1 -> Type ~ h1) => HTrans (h1 :: k1 -> Type -> l1 -> Type) (h2 :: k2 -> Type -> l2 -> Type)

-- | Transform a structure into a related structure given a conversion
--   function for the elements.
htrans :: forall c (xs :: l1) (ys :: l2) proxy f g. (HTrans h1 h2, AllZipN (Prod h1) c xs ys) => proxy c -> (forall (x :: k1) (y :: k2). c x y => f x -> g y) -> h1 f xs -> h2 g ys

-- | Safely coerce a structure into a representationally equal structure.
--   
--   This is a special case of <a>htrans</a>, but can be implemented more
--   efficiently; for example in terms of <a>unsafeCoerce</a>.
--   
--   <i>Examples:</i>
--   
--   <pre>
--   &gt;&gt;&gt; hcoerce (I (Just LT) :* I (Just 'x') :* I (Just True) :* Nil) :: NP Maybe '[Ordering, Char, Bool]
--   Just LT :* Just 'x' :* Just True :* Nil
--   
--   &gt;&gt;&gt; hcoerce (SOP (Z (K True :* K False :* Nil))) :: SOP I '[ '[Bool, Bool], '[Bool] ]
--   SOP (Z (I True :* I False :* Nil))
--   </pre>
hcoerce :: forall (f :: k1 -> Type) (g :: k2 -> Type) (xs :: l1) (ys :: l2). (HTrans h1 h2, AllZipN (Prod h1) (LiftedCoercible f g) xs ys) => h1 f xs -> h2 g ys

-- | Constrained case distinction on a type-level list.
ccase_SList :: forall k c (xs :: [k]) proxy r. All c xs => proxy c -> r ('[] :: [k]) -> (forall (y :: k) (ys :: [k]). (c y, All c ys) => r (y : ys)) -> r xs

-- | Require a constraint for every element of a list.
--   
--   If you have a datatype that is indexed over a type-level list, then
--   you can use <a>All</a> to indicate that all elements of that
--   type-level list must satisfy a given constraint.
--   
--   <i>Example:</i> The constraint
--   
--   <pre>
--   All Eq '[ Int, Bool, Char ]
--   </pre>
--   
--   is equivalent to the constraint
--   
--   <pre>
--   (Eq Int, Eq Bool, Eq Char)
--   </pre>
--   
--   <i>Example:</i> A type signature such as
--   
--   <pre>
--   f :: All Eq xs =&gt; NP I xs -&gt; ...
--   </pre>
--   
--   means that <tt>f</tt> can assume that all elements of the n-ary
--   product satisfy <a>Eq</a>.
--   
--   Note on superclasses: ghc cannot deduce superclasses from <a>All</a>
--   constraints. You might expect the following to compile
--   
--   <pre>
--   class (Eq a) =&gt; MyClass a
--   
--   foo :: (All Eq xs) =&gt; NP f xs -&gt; z
--   foo = [..]
--   
--   bar :: (All MyClass xs) =&gt; NP f xs -&gt; x
--   bar = foo
--   </pre>
--   
--   but it will fail with an error saying that it was unable to deduce the
--   class constraint <tt><a>AllF</a> <a>Eq</a> xs</tt> (or similar) in the
--   definition of <tt>bar</tt>. In cases like this you can use <a>Dict</a>
--   from <a>Data.SOP.Dict</a> to prove conversions between constraints.
--   See <a>this answer on SO for more details</a>.
class (AllF c xs, SListI xs) => All (c :: k -> Constraint) (xs :: [k])

-- | Constrained paramorphism for a type-level list.
--   
--   The advantage of writing functions in terms of <a>cpara_SList</a> is
--   that they are then typically not recursive, and can be unfolded
--   statically if the type-level list is statically known.
cpara_SList :: All c xs => proxy c -> r ('[] :: [k]) -> (forall (y :: k) (ys :: [k]). (c y, All c ys) => r ys -> r (y : ys)) -> r xs

-- | Require a singleton for every inner list in a list of lists.
type SListI2 = All SListI :: [k] -> Constraint

-- | Implicit singleton list.
--   
--   A singleton list can be used to reveal the structure of a type-level
--   list argument that the function is quantified over.
--   
--   Since 0.4.0.0, this is now defined in terms of <a>All</a>. A singleton
--   list provides a witness for a type-level list where the elements need
--   not satisfy any additional constraints.
type SListI = All Top :: k -> Constraint

-- | Require a constraint for every element of a list of lists.
--   
--   If you have a datatype that is indexed over a type-level list of
--   lists, then you can use <a>All2</a> to indicate that all elements of
--   the inner lists must satisfy a given constraint.
--   
--   <i>Example:</i> The constraint
--   
--   <pre>
--   All2 Eq '[ '[ Int ], '[ Bool, Char ] ]
--   </pre>
--   
--   is equivalent to the constraint
--   
--   <pre>
--   (Eq Int, Eq Bool, Eq Char)
--   </pre>
--   
--   <i>Example:</i> A type signature such as
--   
--   <pre>
--   f :: All2 Eq xss =&gt; SOP I xs -&gt; ...
--   </pre>
--   
--   means that <tt>f</tt> can assume that all elements of the sum of
--   product satisfy <a>Eq</a>.
--   
--   Since 0.4.0.0, this is merely a synonym for 'All (All c)'.
type All2 (c :: k -> Constraint) = All All c

-- | Require a constraint pointwise for every pair of elements from two
--   lists.
--   
--   <i>Example:</i> The constraint
--   
--   <pre>
--   All (~) '[ Int, Bool, Char ] '[ a, b, c ]
--   </pre>
--   
--   is equivalent to the constraint
--   
--   <pre>
--   (Int ~ a, Bool ~ b, Char ~ c)
--   </pre>
class (SListI xs, SListI ys, SameShapeAs xs ys, SameShapeAs ys xs, AllZipF c xs ys) => AllZip (c :: a -> b -> Constraint) (xs :: [a]) (ys :: [b])

-- | Type family that forces a type-level list to be of the same shape as
--   the given type-level list.
--   
--   Since 0.5.0.0, this only tests the top-level structure of the list,
--   and is intended to be used in conjunction with a separate construct
--   (such as the <a>AllZip</a>, <a>AllZipF</a> combination to tie the
--   recursive knot). The reason is that making <a>SameShapeAs</a> directly
--   recursive leads to quadratic compile times.
--   
--   The main use of this constraint is to help type inference to learn
--   something about otherwise unknown type-level lists.
type family SameShapeAs (xs :: [a]) (ys :: [b])

-- | The constraint <tt><a>LiftedCoercible</a> f g x y</tt> is equivalent
--   to <tt><a>Coercible</a> (f x) (g y)</tt>.
class Coercible f x g y => LiftedCoercible (f :: k -> k1) (g :: k2 -> k1) (x :: k) (y :: k2)

-- | Require a constraint pointwise for every pair of elements from two
--   lists of lists.
class (AllZipF AllZip f xss yss, SListI xss, SListI yss, SameShapeAs xss yss, SameShapeAs yss xss) => AllZip2 (f :: a -> b -> Constraint) (xss :: [[a]]) (yss :: [[b]])

-- | Composition of constraints.
--   
--   Note that the result of the composition must be a constraint, and
--   therefore, in <tt><a>Compose</a> f g</tt>, the kind of <tt>f</tt> is
--   <tt>k -&gt; <a>Constraint</a></tt>. The kind of <tt>g</tt>, however,
--   is <tt>l -&gt; k</tt> and can thus be a normal type constructor.
--   
--   A typical use case is in connection with <a>All</a> on an <a>NP</a> or
--   an <a>NS</a>. For example, in order to denote that all elements on an
--   <tt><a>NP</a> f xs</tt> satisfy <a>Show</a>, we can say <tt><a>All</a>
--   (<a>Compose</a> <a>Show</a> f) xs</tt>.
class f g x => Compose (f :: k -> Constraint) (g :: k1 -> k) (x :: k1)
infixr 9 `Compose`

-- | Pairing of constraints.
class (f x, g x) => And (f :: k -> Constraint) (g :: k -> Constraint) (x :: k)
infixl 7 `And`

-- | A constraint that can always be satisfied.
class Top (x :: k)

-- | A generalization of <a>All</a> and <a>All2</a>.
--   
--   The family <a>AllN</a> expands to <a>All</a> or <a>All2</a> depending
--   on whether the argument is indexed by a list or a list of lists.
type family AllN (h :: k -> Type -> l -> Type) (c :: k -> Constraint) :: l -> Constraint

-- | A generalization of <a>AllZip</a> and <a>AllZip2</a>.
--   
--   The family <a>AllZipN</a> expands to <a>AllZip</a> or <a>AllZip2</a>
--   depending on whther the argument is indexed by a list or a list of
--   lists.
type family AllZipN (h :: k -> Type -> l -> Type) (c :: k1 -> k2 -> Constraint) :: l1 -> l2 -> Constraint

-- | Lift the given function.
mapKKK :: forall k1 k2 k3 a b c (d :: k1) (e :: k2) (f :: k3). (a -> b -> c) -> K a d -> K b e -> K c f

-- | Lift the given function.
mapKKI :: forall k1 k2 a b c (d :: k1) (e :: k2). (a -> b -> c) -> K a d -> K b e -> I c

-- | Lift the given function.
mapKIK :: forall k1 k2 a b c (d :: k1) (e :: k2). (a -> b -> c) -> K a d -> I b -> K c e

-- | Lift the given function.
mapKII :: forall k a b c (d :: k). (a -> b -> c) -> K a d -> I b -> I c

-- | Lift the given function.
mapIKK :: forall k1 k2 a b c (d :: k1) (e :: k2). (a -> b -> c) -> I a -> K b d -> K c e

-- | Lift the given function.
mapIKI :: forall k a b c (d :: k). (a -> b -> c) -> I a -> K b d -> I c

-- | Lift the given function.
mapIIK :: forall k a b c (d :: k). (a -> b -> c) -> I a -> I b -> K c d

-- | Lift the given function.
mapIII :: (a -> b -> c) -> I a -> I b -> I c

-- | Lift the given function.
mapKK :: forall k1 k2 a b (c :: k1) (d :: k2). (a -> b) -> K a c -> K b d

-- | Lift the given function.
mapKI :: forall k a b (c :: k). (a -> b) -> K a c -> I b

-- | Lift the given function.
mapIK :: forall k a b (c :: k). (a -> b) -> I a -> K b c

-- | Lift the given function.
mapII :: (a -> b) -> I a -> I b

-- | Extract the contents of a <a>Comp</a> value.
unComp :: forall l k f (g :: k -> l) (p :: k). (f :.: g) p -> f (g p)

-- | Extract the contents of an <a>I</a> value.
unI :: I a -> a

-- | Extract the contents of a <a>K</a> value.
unK :: forall k a (b :: k). K a b -> a

-- | The constant type functor.
--   
--   Like <a>Constant</a>, but kind-polymorphic in its second argument and
--   with a shorter name.
newtype K a (b :: k)
K :: a -> K a (b :: k)

-- | The identity type functor.
--   
--   Like <a>Identity</a>, but with a shorter name.
newtype I a
I :: a -> I a

-- | Composition of functors.
--   
--   Like <a>Compose</a>, but kind-polymorphic and with a shorter name.
newtype ( (f :: l -> Type) :.: (g :: k -> l) ) (p :: k)
Comp :: f (g p) -> (:.:) (f :: l -> Type) (g :: k -> l) (p :: k)
infixr 7 :.:
instance forall k (f :: k -> *) (xs :: [k]). Data.SOP.Constraint.All (Data.SOP.Constraint.Compose GHC.Show.Show f) xs => GHC.Show.Show (Data.SOP.Strict.NS f xs)
instance forall k (f :: k -> *) (xs :: [k]). Data.SOP.Constraint.All (Data.SOP.Constraint.Compose GHC.Classes.Eq f) xs => GHC.Classes.Eq (Data.SOP.Strict.NS f xs)
instance forall k (f :: k -> *) (xs :: [k]). (Data.SOP.Constraint.All (Data.SOP.Constraint.Compose GHC.Classes.Eq f) xs, Data.SOP.Constraint.All (Data.SOP.Constraint.Compose GHC.Classes.Ord f) xs) => GHC.Classes.Ord (Data.SOP.Strict.NS f xs)
instance forall k (f :: k -> *) (xs :: [k]). Data.SOP.Constraint.All (Data.SOP.Constraint.Compose GHC.Classes.Eq f) xs => GHC.Classes.Eq (Data.SOP.Strict.NP f xs)
instance forall k (f :: k -> *) (xs :: [k]). (Data.SOP.Constraint.All (Data.SOP.Constraint.Compose GHC.Classes.Eq f) xs, Data.SOP.Constraint.All (Data.SOP.Constraint.Compose GHC.Classes.Ord f) xs) => GHC.Classes.Ord (Data.SOP.Strict.NP f xs)
instance Data.SOP.Classes.HExpand Data.SOP.Strict.NS
instance Data.SOP.Classes.HAp Data.SOP.Strict.NS
instance Data.SOP.Classes.HCollapse Data.SOP.Strict.NS
instance Data.SOP.Classes.HSequence Data.SOP.Strict.NS
instance Data.SOP.Classes.HTrans Data.SOP.Strict.NS Data.SOP.Strict.NS
instance forall k (f :: k -> *) (xs :: [k]). Data.SOP.Constraint.All (Data.SOP.Constraint.Compose NoThunks.Class.NoThunks f) xs => NoThunks.Class.NoThunks (Data.SOP.Strict.NS f xs)
instance Data.SOP.Classes.HPure Data.SOP.Strict.NP
instance Data.SOP.Classes.HAp Data.SOP.Strict.NP
instance Data.SOP.Classes.HCollapse Data.SOP.Strict.NP
instance Data.SOP.Classes.HSequence Data.SOP.Strict.NP
instance Data.SOP.Classes.HTraverse_ Data.SOP.Strict.NP
instance forall k (f :: k -> *) (xs :: [k]). Data.SOP.Constraint.All (Data.SOP.Constraint.Compose GHC.Show.Show f) xs => GHC.Show.Show (Data.SOP.Strict.NP f xs)
instance forall k (f :: k -> *) (xs :: [k]). Data.SOP.Constraint.All (Data.SOP.Constraint.Compose NoThunks.Class.NoThunks f) xs => NoThunks.Class.NoThunks (Data.SOP.Strict.NP f xs)

module Ouroboros.Consensus.BlockchainTime.WallClock.Types

-- | System start
--   
--   Slots are counted from the system start.
newtype SystemStart
SystemStart :: UTCTime -> SystemStart
[getSystemStart] :: SystemStart -> UTCTime

-- | <a>RelativeTime</a> is time relative to the <a>SystemStart</a>
newtype RelativeTime
RelativeTime :: NominalDiffTime -> RelativeTime
[getRelativeTime] :: RelativeTime -> NominalDiffTime
addRelTime :: NominalDiffTime -> RelativeTime -> RelativeTime
diffRelTime :: RelativeTime -> RelativeTime -> NominalDiffTime
toRelativeTime :: SystemStart -> UTCTime -> RelativeTime
fromRelativeTime :: SystemStart -> RelativeTime -> UTCTime

-- | System time
--   
--   Slots are counted from the system start.
data SystemTime m
SystemTime :: m RelativeTime -> m () -> SystemTime m

-- | Get current time (as a <a>RelativeTime</a>)
--   
--   For real deployment, this will take the current <a>UTCTime</a> and
--   then subtract the <a>SystemStart</a> (see <tt>defaultSystemTime</tt>).
--   Tests don't bother with a <a>UTCTime</a> and just work entirely in
--   <a>RelativeTime</a>.
[systemTimeCurrent] :: SystemTime m -> m RelativeTime

-- | Wait for <a>SystemStart</a>
--   
--   For the real deployment, this waits for the current <a>UTCTime</a> to
--   reach <a>SystemStart</a>. In tests this does nothing.
[systemTimeWait] :: SystemTime m -> m ()

-- | Slot length
data SlotLength
getSlotLength :: SlotLength -> NominalDiffTime

-- | Constructor for <a>SlotLength</a>
mkSlotLength :: NominalDiffTime -> SlotLength
slotLengthFromSec :: Integer -> SlotLength
slotLengthToSec :: SlotLength -> Integer
slotLengthFromMillisec :: Integer -> SlotLength
slotLengthToMillisec :: SlotLength -> Integer
instance GHC.Show.Show Ouroboros.Consensus.BlockchainTime.WallClock.Types.SystemStart
instance NoThunks.Class.NoThunks Ouroboros.Consensus.BlockchainTime.WallClock.Types.SystemStart
instance GHC.Generics.Generic Ouroboros.Consensus.BlockchainTime.WallClock.Types.SystemStart
instance GHC.Classes.Eq Ouroboros.Consensus.BlockchainTime.WallClock.Types.SystemStart
instance GHC.Show.Show Ouroboros.Consensus.BlockchainTime.WallClock.Types.RelativeTime
instance NoThunks.Class.NoThunks Ouroboros.Consensus.BlockchainTime.WallClock.Types.RelativeTime
instance GHC.Generics.Generic Ouroboros.Consensus.BlockchainTime.WallClock.Types.RelativeTime
instance GHC.Classes.Ord Ouroboros.Consensus.BlockchainTime.WallClock.Types.RelativeTime
instance GHC.Classes.Eq Ouroboros.Consensus.BlockchainTime.WallClock.Types.RelativeTime
instance NoThunks.Class.NoThunks (Ouroboros.Consensus.BlockchainTime.WallClock.Types.SystemTime m)
instance GHC.Show.Show Ouroboros.Consensus.BlockchainTime.WallClock.Types.SlotLength
instance NoThunks.Class.NoThunks Ouroboros.Consensus.BlockchainTime.WallClock.Types.SlotLength
instance GHC.Generics.Generic Ouroboros.Consensus.BlockchainTime.WallClock.Types.SlotLength
instance GHC.Classes.Eq Ouroboros.Consensus.BlockchainTime.WallClock.Types.SlotLength
instance Codec.Serialise.Class.Serialise Ouroboros.Consensus.BlockchainTime.WallClock.Types.SlotLength
instance Codec.Serialise.Class.Serialise Ouroboros.Consensus.BlockchainTime.WallClock.Types.RelativeTime

module Ouroboros.Consensus.Config.SecurityParam

-- | Protocol security parameter
--   
--   We interpret this as the number of rollbacks we support.
--   
--   i.e., k == 0: we can't roll back at all k == 1: we can roll back at
--   most one block, etc
--   
--   NOTE: This talks about the number of <i>blocks</i> we can roll back,
--   not the number of <i>slots</i>.
newtype SecurityParam
SecurityParam :: Word64 -> SecurityParam
[maxRollbacks] :: SecurityParam -> Word64
instance GHC.Show.Show Ouroboros.Consensus.Config.SecurityParam.SecurityParam
instance NoThunks.Class.NoThunks Ouroboros.Consensus.Config.SecurityParam.SecurityParam
instance GHC.Generics.Generic Ouroboros.Consensus.Config.SecurityParam.SecurityParam
instance GHC.Classes.Eq Ouroboros.Consensus.Config.SecurityParam.SecurityParam

module Ouroboros.Consensus.HardFork.Combinator.Info

-- | Information about an era (mostly for type errors)
data SingleEraInfo blk
SingleEraInfo :: !Text -> SingleEraInfo blk
[singleEraName] :: SingleEraInfo blk -> !Text

-- | Additional newtype wrapper around <a>SingleEraInfo</a>
--   
--   This is primarily useful for use in error messages: it marks which era
--   info came from the ledger, and which came from a
--   tx<i>block</i>header/etc.
newtype LedgerEraInfo blk
LedgerEraInfo :: SingleEraInfo blk -> LedgerEraInfo blk
[getLedgerEraInfo] :: LedgerEraInfo blk -> SingleEraInfo blk
instance Codec.Serialise.Class.Serialise (Ouroboros.Consensus.HardFork.Combinator.Info.SingleEraInfo blk)
instance NoThunks.Class.NoThunks (Ouroboros.Consensus.HardFork.Combinator.Info.SingleEraInfo blk)
instance GHC.Show.Show (Ouroboros.Consensus.HardFork.Combinator.Info.SingleEraInfo blk)
instance GHC.Classes.Eq (Ouroboros.Consensus.HardFork.Combinator.Info.SingleEraInfo blk)
instance GHC.Generics.Generic (Ouroboros.Consensus.HardFork.Combinator.Info.SingleEraInfo blk)
instance Codec.Serialise.Class.Serialise (Ouroboros.Consensus.HardFork.Combinator.Info.LedgerEraInfo blk)
instance NoThunks.Class.NoThunks (Ouroboros.Consensus.HardFork.Combinator.Info.LedgerEraInfo blk)
instance GHC.Show.Show (Ouroboros.Consensus.HardFork.Combinator.Info.LedgerEraInfo blk)
instance GHC.Classes.Eq (Ouroboros.Consensus.HardFork.Combinator.Info.LedgerEraInfo blk)

module Ouroboros.Consensus.HardFork.Combinator.Util.Tails

-- | For every tail <tt>(x ': xs)</tt> of the list, an <tt>f x y</tt> for
--   every <tt>y</tt> in <tt>xs</tt>
data Tails (f :: k -> k -> Type) (xs :: [k])
[TNil] :: Tails f '[]
[TCons] :: NP (f x) xs -> Tails f xs -> Tails f (x : xs)
mk1 :: Tails f '[x]
mk2 :: f x y -> Tails f '[x, y]
mk3 :: f x y -> f x z -> f y z -> Tails f '[x, y, z]
hmap :: SListI xs => (forall x y. f x y -> g x y) -> Tails f xs -> Tails g xs
hcmap :: forall proxy c f g xs. All c xs => proxy c -> (forall x y. (c x, c y) => f x y -> g x y) -> Tails f xs -> Tails g xs
hpure :: SListI xs => (forall x y. f x y) -> Tails f xs
hcpure :: forall proxy f c xs. All c xs => proxy c -> (forall x y. (c x, c y) => f x y) -> Tails f xs

module Ouroboros.Consensus.Node.NetworkProtocolVersion

-- | Protocol versioning
class (Show (BlockNodeToNodeVersion blk), Show (BlockNodeToClientVersion blk), Eq (BlockNodeToNodeVersion blk), Eq (BlockNodeToClientVersion blk)) => HasNetworkProtocolVersion blk where {
    type family BlockNodeToNodeVersion blk :: Type;
    type family BlockNodeToClientVersion blk :: Type;
    type BlockNodeToNodeVersion blk = ();
    type BlockNodeToClientVersion blk = ();
}
class HasNetworkProtocolVersion blk => SupportedNetworkProtocolVersion blk

-- | Enumerate all supported node-to-node versions
supportedNodeToNodeVersions :: SupportedNetworkProtocolVersion blk => Proxy blk -> Map NodeToNodeVersion (BlockNodeToNodeVersion blk)

-- | Enumerate all supported node-to-client versions
supportedNodeToClientVersions :: SupportedNetworkProtocolVersion blk => Proxy blk -> Map NodeToClientVersion (BlockNodeToClientVersion blk)
data NodeToNodeVersion
NodeToNodeV_1 :: NodeToNodeVersion
NodeToNodeV_2 :: NodeToNodeVersion
NodeToNodeV_3 :: NodeToNodeVersion
NodeToNodeV_4 :: NodeToNodeVersion
data NodeToClientVersion
NodeToClientV_1 :: NodeToClientVersion
NodeToClientV_2 :: NodeToClientVersion
NodeToClientV_3 :: NodeToClientVersion
NodeToClientV_4 :: NodeToClientVersion


-- | Support for protocols that include a signature
module Ouroboros.Consensus.Protocol.Signed

-- | The part of the header that is signed
type family Signed hdr :: Type

-- | Header that contain a signed part
--   
--   This class enforces that signatures are computed over the header only
--   (without the block body). This is important: we must be able to verify
--   the signature in a header without having access to the block (which we
--   download separately). Typically of course the header will contain a
--   hash of the body, so the signature can include the body implicitly.
class SignedHeader hdr

-- | Extract the part of the header that the signature should be computed
--   over
headerSigned :: SignedHeader hdr => hdr -> Signed hdr


-- | This is meant to be used for the implementation of HasFS instances and
--   not directly by client code.
module Ouroboros.Consensus.Storage.FS.Handle

-- | File handlers for the IO instance for HasFS. This is parametric on the
--   os.
--   
--   The <a>FilePath</a> is used to improve error messages. The <a>MVar</a>
--   is used to implement <tt>close</tt>. osHandle is Fd for unix and
--   HANDLE for Windows.
data HandleOS osHandle
HandleOS :: FilePath -> MVar (Maybe osHandle) -> HandleOS osHandle
[filePath] :: HandleOS osHandle -> FilePath
[handle] :: HandleOS osHandle -> MVar (Maybe osHandle)
isOpenHandleOS :: HandleOS osHandle -> IO Bool

-- | This is a no-op when the handle is already closed.
closeHandleOS :: HandleOS osHandle -> (osHandle -> IO ()) -> IO ()

-- | This is meant to be used for the implementation of individual file
--   system commands. Using it for larger scopes woud not be correct, since
--   we would not notice if the handle is closed.
withOpenHandle :: String -> HandleOS osHandle -> (osHandle -> IO a) -> IO a
isHandleClosedException :: IOException -> Bool
instance GHC.Classes.Eq (Ouroboros.Consensus.Storage.FS.Handle.HandleOS a)
instance GHC.Show.Show (Ouroboros.Consensus.Storage.FS.Handle.HandleOS a)

module Ouroboros.Consensus.Storage.LedgerDB.DiskPolicy

-- | On-disk policy
--   
--   We only write ledger states that are older than <tt>k</tt> blocks to
--   disk (that is, snapshots that are guaranteed valid). The on-disk
--   policy determines how often we write to disk and how many checkpoints
--   we keep.
data DiskPolicy
DiskPolicy :: Word -> (Maybe DiffTime -> Word64 -> Bool) -> DiskPolicy

-- | How many snapshots do we want to keep on disk?
--   
--   A higher number of on-disk snapshots is primarily a safe-guard against
--   disk corruption: it trades disk space for reliability.
--   
--   Examples:
--   
--   <ul>
--   <li><tt>0</tt>: Delete the snapshot immediately after writing.
--   Probably not a useful value :-D</li>
--   <li><tt>1</tt>: Delete the previous snapshot immediately after writing
--   the next Dangerous policy: if for some reason the deletion happens
--   before the new snapshot is written entirely to disk (we don't
--   <tt>fsync</tt>), we have no choice but to start at the genesis
--   snapshot on the next startup.</li>
--   <li><tt>2</tt>: Always keep 2 snapshots around. This means that when
--   we write the next snapshot, we delete the oldest one, leaving the
--   middle one available in case of truncation of the write. This is
--   probably a sane value in most circumstances.</li>
--   </ul>
[onDiskNumSnapshots] :: DiskPolicy -> Word

-- | Should we write a snapshot of the ledger state to disk?
--   
--   This function is passed two bits of information:
--   
--   <ul>
--   <li>The time since the last snapshot, or <a>Nothing</a> if none was
--   taken yet. Note that <a>Nothing</a> merely means no snapshot had been
--   taking yet since the node was started; it does not necessarily mean
--   that none exist on disk.</li>
--   <li>The distance in terms of blocks applied to the <i>oldest</i>
--   ledger snapshot in memory. During normal operation, this is the number
--   of blocks written to the ImmutableDB since the last snapshot. On
--   startup, it is computed by counting how many immutable blocks we had
--   to reapply to get to the chain tip. This is useful, as it allows the
--   policy to decide to take a snapshot <i>on node startup</i> if a lot of
--   blocks had to be replayed.</li>
--   </ul>
--   
--   See also <a>defaultDiskPolicy</a>
[onDiskShouldTakeSnapshot] :: DiskPolicy -> Maybe DiffTime -> Word64 -> Bool

-- | Default on-disk policy
--   
--   We want to take a snapshot every 50k blocks or roughly every hour (72
--   minutes actually) when <tt>k = 2160</tt> (for other values of
--   <tt>k</tt> we scale proportionally), but not more rapidly than 10 per
--   hour (which is important for bulk sync).
--   
--   If users never leave their wallet running for long, however, this
--   would mean that we <i>never</i> take snapshots after syncing (until we
--   get to 50k blocks). So, on startup, we take a snapshot as soon as
--   there are <tt>k</tt> blocks replayed. This means that even if users
--   frequently shut down their wallet, we still take a snapshot roughly
--   every <tt>k</tt> blocks. It does mean the possibility of an extra
--   unnecessary snapshot during syncing (if the node is restarted), but
--   that is not a big deal.
defaultDiskPolicy :: SecurityParam -> DiskPolicy
instance NoThunks.Class.NoThunks Ouroboros.Consensus.Storage.LedgerDB.DiskPolicy.DiskPolicy

module Ouroboros.Consensus.Ticked

-- | " Ticked " piece of state (<tt>LedgerState</tt>, <tt>LedgerView</tt>,
--   <tt>ChainIndepState</tt>)
--   
--   Ticking refers to the passage of time (the ticking of the clock). When
--   a piece of state is marked as ticked, it means that time-related
--   changes have been applied to the state (or forecast).
--   
--   Some examples of time related changes:
--   
--   <ul>
--   <li>Scheduled delegations might have been applied in Byron</li>
--   <li>New leader schedule computed for Shelley</li>
--   <li>Transition from Byron to Shelley activated in the hard fork
--   combinator.</li>
--   <li>Nonces switched out at the start of a new epoch.</li>
--   </ul>
data family Ticked st :: Type
instance GHC.Show.Show (Ouroboros.Consensus.Ticked.Ticked ())
instance GHC.Show.Show (Ouroboros.Consensus.Ticked.Ticked a) => GHC.Show.Show (Ouroboros.Consensus.Ticked.Ticked (Data.SOP.BasicFunctors.K a x))
instance GHC.Show.Show (Ouroboros.Consensus.Ticked.Ticked (f a)) => GHC.Show.Show ((Data.SOP.BasicFunctors.:.:) Ouroboros.Consensus.Ticked.Ticked f a)
instance NoThunks.Class.NoThunks (Ouroboros.Consensus.Ticked.Ticked (f a)) => NoThunks.Class.NoThunks ((Data.SOP.BasicFunctors.:.:) Ouroboros.Consensus.Ticked.Ticked f a)


-- | Miscellaneous utilities
module Ouroboros.Consensus.Util
data Dict :: Constraint -> Type
[Dict] :: a => Dict a
class Empty a
data Some (f :: k -> Type)
[Some] :: f a -> Some f

-- | Pair of functors instantiated to the <i>same</i> existential
data SomePair (f :: k -> Type) (g :: k -> Type)
[SomePair] :: f a -> g a -> SomePair f g

-- | Hide the second type argument of some functor
--   
--   <tt>SomeSecond f a</tt> is isomorphic to <tt>Some (f a)</tt>, but is
--   more convenient in partial applications.
data SomeSecond (f :: Type -> Type -> Type) a
[SomeSecond] :: !f a b -> SomeSecond f a
class ShowProxy (p :: k)
showProxy :: ShowProxy p => Proxy p -> String
mustBeRight :: Either Void a -> a
foldlM' :: forall m a b. Monad m => (b -> a -> m b) -> b -> [a] -> m b
repeatedly :: (a -> b -> b) -> [a] -> b -> b
repeatedlyM :: Monad m => (a -> b -> m b) -> [a] -> b -> m b

-- | Apply a function n times. The value of each application is forced.
nTimes :: forall a. (a -> a) -> Word64 -> a -> a

-- | Apply a function n times through a monadic bind. The value of each
--   application is forced.
nTimesM :: forall m a. Monad m => (a -> m a) -> Word64 -> a -> m a
chunks :: Int -> [a] -> [[a]]

-- | All possible ways to pick on element from a list, preserving order
--   
--   <pre>
--   pickOne [1,2,3] = [ ([], 1, [2, 3])
--                     , ([1], 2, [3])
--                     , ([1,2], 3, [])
--                     ]
--   </pre>
pickOne :: [a] -> [([a], a, [a])]

-- | Mark the last element of the list as <a>Right</a>
markLast :: [a] -> [Either a a]

-- | Take the last <tt>n</tt> elements
takeLast :: Word64 -> [a] -> [a]

-- | Drop the last <tt>n</tt> elements
dropLast :: Word64 -> [a] -> [a]
firstJust :: forall a b f. Foldable f => (a -> Maybe b) -> f a -> Maybe b
allEqual :: Eq a => [a] -> Bool

-- | Take items until the condition is true. If the condition is true for
--   an item, include that item as the last item in the returned list. If
--   the condition was never true, the original list is returned.
--   
--   <pre>
--   takeUntil (== 3) [1,2,3,4]
--   </pre>
--   
--   <ul>
--   <li><i>1,2,3</i> &gt; takeUntil (== 2) [0,1,0]</li>
--   <li><i>0,1,0</i> &gt; takeUntil (== 2) [2,2,3]</li>
--   <li><i>2</i></li>
--   </ul>
takeUntil :: (a -> Bool) -> [a] -> [a]

-- | Variation on <tt>groupBy</tt> that records the matched element
--   
--   <pre>
--      groupOn signum [-3..3]
--   == [ (-1, [-3, -2,-1])
--      , ( 0, [0])
--      , ( 1, [1, 2, 3])
--      ]
--   </pre>
groupOn :: forall a b. Eq b => (a -> b) -> [a] -> [(b, [a])]

-- | Generalization of <a>groupOn</a> where we specify both what to compare
--   and what to collect
groupSplit :: forall a b c. Eq b => (a -> (b, c)) -> [a] -> [(b, [c])]

-- | Focus on one element in the list
--   
--   E.g.
--   
--   <pre>
--      splits [1..3]
--   == [ ([]    , 1 , [2,3])
--      , ([1]   , 2 , [3]  )
--      , ([1,2] , 3 , []   )
--      ]
--   </pre>
splits :: [a] -> [([a], a, [a])]
lastMaybe :: [a] -> Maybe a
safeMaximum :: Ord a => [a] -> Maybe a
safeMaximumBy :: (a -> a -> Ordering) -> [a] -> Maybe a
safeMaximumOn :: Ord b => (a -> b) -> [a] -> Maybe a

-- | Calls <a>hashFromBytes</a> and throws an error if the input is of the
--   wrong length.
hashFromBytesE :: forall h a. (HashAlgorithm h, HasCallStack) => ByteString -> Hash h a

-- | Calls <a>hashFromBytesShort</a> and throws an error if the input is of
--   the wrong length.
hashFromBytesShortE :: forall h a. (HashAlgorithm h, HasCallStack) => ShortByteString -> Hash h a
byteStringChunks :: Int -> ByteString -> [ByteString]
lazyByteStringChunks :: Int -> ByteString -> [ByteString]
whenJust :: Applicative f => Maybe a -> (a -> f ()) -> f ()

-- | Assertion
--   
--   Variation on <tt>assert</tt> for use in testing code.
checkThat :: (Show a, Monad m) => String -> (a -> Bool) -> a -> m ()

-- | Check that a bunch of sets are all mutually disjoint
allDisjoint :: forall a. Ord a => [Set a] -> Bool
(.:) :: (y -> z) -> (x0 -> x1 -> y) -> x0 -> x1 -> z
(..:) :: (y -> z) -> (x0 -> x1 -> x2 -> y) -> x0 -> x1 -> x2 -> z
(...:) :: (y -> z) -> (x0 -> x1 -> x2 -> x3 -> y) -> x0 -> x1 -> x2 -> x3 -> z
(....:) :: (y -> z) -> (x0 -> x1 -> x2 -> x3 -> x4 -> y) -> x0 -> x1 -> x2 -> x3 -> x4 -> z
(.....:) :: (y -> z) -> (x0 -> x1 -> x2 -> x3 -> x4 -> x5 -> y) -> x0 -> x1 -> x2 -> x3 -> x4 -> x5 -> z
pairFst :: Product f g a -> f a
pairSnd :: Product f g a -> g a

-- | Fast Fibonacci computation, using Binet's formula
fib :: Word64 -> Word64
eitherToMaybe :: Either a b -> Maybe b
instance forall k (a :: k). Ouroboros.Consensus.Util.Empty a


-- | Utilities for arguments record with defaults
--   
--   Useful for when you want to define a default value of an arguments
--   record consisting of a mix of arguments with/without defaults.
--   
--   The following code example explains it best:
--   
--   <pre>
--   data Args f = Args {
--         hasNoDefault :: HKD f Int
--       , hasDefault   :: Bool
--       }
--   
--   defaultArgs :: Args Defaults
--   defaultArgs = Args {
--         hasNoDefault = NoDefault
--       , hasDefault   = False
--       }
--   
--   theArgs :: Args Identity
--   theArgs = defaultArgs {
--         hasNoDefault = 0
--       }
--   
--   useArgs :: Args Identity -&gt; (Int, Bool)
--   useArgs (Args a b) = (a, b)
--   </pre>
--   
--   Leaving out the <tt>hasNoDefault</tt> field from <tt>theArgs</tt> will
--   result in a type error.
module Ouroboros.Consensus.Util.Args
data Defaults t
NoDefault :: Defaults t
type family HKD f a
class MapHKD f
mapHKD :: MapHKD f => proxy (f b) -> (a -> b) -> HKD f a -> HKD f b

-- | Identity functor and monad. (a non-strict monad)
newtype Identity a
Identity :: a -> Identity a
[runIdentity] :: Identity a -> a
instance GHC.Base.Functor Ouroboros.Consensus.Util.Args.Defaults
instance Ouroboros.Consensus.Util.Args.MapHKD Data.Functor.Identity.Identity
instance Ouroboros.Consensus.Util.Args.MapHKD Ouroboros.Consensus.Util.Args.Defaults


-- | CallStack with a nicer <a>Show</a> instance
--   
--   Use of this module is intended to <i>replace</i> import of
--   <tt>GHC.Stack</tt>
module Ouroboros.Consensus.Util.CallStack

-- | CallStack with <a>Show</a> instance using <a>prettyCallStack</a>
data PrettyCallStack
prettyCallStack :: HasCallStack => PrettyCallStack

-- | Request a CallStack.
--   
--   NOTE: The implicit parameter <tt>?callStack :: CallStack</tt> is an
--   implementation detail and <b>should not</b> be considered part of the
--   <a>CallStack</a> API, we may decide to change the implementation in
--   the future.
type HasCallStack = ?callStack :: CallStack
instance NoThunks.Class.NoThunks Ouroboros.Consensus.Util.CallStack.PrettyCallStack
instance GHC.Show.Show Ouroboros.Consensus.Util.CallStack.PrettyCallStack

module Ouroboros.Consensus.Util.DepPair

-- | Generalization of <a>DepPair</a>
--   
--   This adds an additional functor <tt>g</tt> around the second value in
--   the pair.
data GenDepPair g f
[GenDepPair] :: !f a -> !g a -> GenDepPair g f
pattern DepPair :: f a -> a -> DepPair f

-- | Dependent pair
--   
--   A dependent pair is a pair of values where the type of the value
--   depends on the first value.
type DepPair = GenDepPair I
depPairFirst :: (forall a. f a -> f' a) -> GenDepPair g f -> GenDepPair g f'
class SameDepIndex f
sameDepIndex :: SameDepIndex f => f a -> f b -> Maybe (a :~: b)
sameDepIndex :: (SameDepIndex f, TrivialDependency f) => f a -> f b -> Maybe (a :~: b)

-- | A dependency is trivial if it always maps to the same type <tt>b</tt>
class TrivialDependency f where {
    type family TrivialIndex f :: Type;
}
hasSingleIndex :: TrivialDependency f => f a -> f b -> a :~: b
indexIsTrivial :: TrivialDependency f => f (TrivialIndex f)
fromTrivialDependency :: TrivialDependency f => f a -> a -> TrivialIndex f
toTrivialDependency :: TrivialDependency f => f a -> TrivialIndex f -> a

-- | Propositional equality. If <tt>a :~: b</tt> is inhabited by some
--   terminating value, then the type <tt>a</tt> is the same as the type
--   <tt>b</tt>. To use this equality in practice, pattern-match on the
--   <tt>a :~: b</tt> to get out the <tt>Refl</tt> constructor; in the body
--   of the pattern-match, the compiler knows that <tt>a ~ b</tt>.
data (a :: k) :~: (b :: k)
[Refl] :: forall k (a :: k). a :~: a
infix 4 :~:

-- | <a>Proxy</a> is a type that holds no data, but has a phantom parameter
--   of arbitrary type (or even kind). Its use is to provide type
--   information, even though there is no value available of that type (or
--   it may be too costly to create one).
--   
--   Historically, <tt><a>Proxy</a> :: <a>Proxy</a> a</tt> is a safer
--   alternative to the <tt><a>undefined</a> :: a</tt> idiom.
--   
--   <pre>
--   &gt;&gt;&gt; Proxy :: Proxy (Void, Int -&gt; Int)
--   Proxy
--   </pre>
--   
--   Proxy can even hold types of higher kinds,
--   
--   <pre>
--   &gt;&gt;&gt; Proxy :: Proxy Either
--   Proxy
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; Proxy :: Proxy Functor
--   Proxy
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; Proxy :: Proxy complicatedStructure
--   Proxy
--   </pre>
data Proxy (t :: k)
Proxy :: Proxy (t :: k)

module Ouroboros.Consensus.Block.NestedContent

-- | Nested content inside a block
--   
--   Consider a simplified version of the hard fork combinator, defining
--   
--   <pre>
--   type HardFork a b = Either a b
--   </pre>
--   
--   Then encoding <tt>Hardfork ByronBlock ShelleyBlock</tt> is easy, in
--   the same way that we encode <i>any</i> <tt>Either</tt>. The
--   <i>header</i> of such a block will have type
--   
--   <pre>
--   HardFork (Header ByronBlock) (Header ShelleyBlock)
--   </pre>
--   
--   and encoding those (for example, to send them across the network) is
--   similarly trivial. But now suppose we want to read a header from disk.
--   We do not store headers directly, but instead store the blocks. The DB
--   will know the offset and length (both in bytes) of the header inside
--   the block, but how do we decode such a header? If it's a Byron block,
--   we should use the decoder for <tt>Header ByronBlock</tt>, and
--   similarly for Shelley, but how should we express this more generally?
--   
--   Here is where <a>HasNestedContent</a> comes in. Continuing the
--   example, we can <tt>unnest</tt> a <tt>Header (HardFork ByronBlock
--   ShelleyBlock)</tt> into a pair of values, where the first value (a
--   <tt>NestedCtxt</tt>) tells us what type of block we have, and the
--   second value gives us the actual header. So, if the first value says
--   "this is a Byron block", the second value is a <tt>Header
--   ByronBlock</tt>, and vice versa. In other words, this is a dependent
--   pair.
--   
--   This then solves the serialisation problem: we expect a
--   <i>dependent</i> decoder which, <i>given</i> a <tt>NestedCtxt</tt>
--   identifying the block type, decodes the raw bytes from the block into
--   the type indicated by that <tt>NestedCtxt</tt>.
--   
--   TODO: We could perhaps define this independent of blocks in
--   <a>DepPair</a>.
class (forall a. Show (NestedCtxt_ blk f a), SameDepIndex (NestedCtxt_ blk f)) => HasNestedContent f blk
unnest :: HasNestedContent f blk => f blk -> DepPair (NestedCtxt f blk)
nest :: HasNestedContent f blk => DepPair (NestedCtxt f blk) -> f blk
unnest :: (HasNestedContent f blk, TrivialDependency (NestedCtxt f blk), TrivialIndex (NestedCtxt f blk) ~ f blk) => f blk -> DepPair (NestedCtxt f blk)
nest :: (HasNestedContent f blk, TrivialDependency (NestedCtxt f blk), TrivialIndex (NestedCtxt f blk) ~ f blk) => DepPair (NestedCtxt f blk) -> f blk

-- | Context identifying what kind of block we have
--   
--   In almost all places we will use <a>NestedCtxt</a> rather than
--   <a>NestedCtxt_</a>.
data family NestedCtxt_ blk :: (Type -> Type) -> (Type -> Type)
curriedNest :: HasNestedContent f blk => NestedCtxt f blk a -> a -> f blk

-- | Version of <a>NestedCtxt_</a> with the type arguments swapped
--   
--   <a>NestedCtxt</a> must be indexed on <tt>blk</tt>: it is the block
--   that determines this type. However, we often want to partially apply
--   the second argument (the functor), leaving the block type not yet
--   defined.
newtype NestedCtxt f blk a
NestedCtxt :: NestedCtxt_ blk f a -> NestedCtxt f blk a
[flipNestedCtxt] :: NestedCtxt f blk a -> NestedCtxt_ blk f a
castNestedCtxt :: (NestedCtxt_ blk f a -> NestedCtxt_ blk' f a) -> NestedCtxt f blk a -> NestedCtxt f blk' a
mapNestedCtxt :: (NestedCtxt_ blk f a -> NestedCtxt_ blk' f' a') -> NestedCtxt f blk a -> NestedCtxt f' blk' a'
castSomeNestedCtxt :: (forall a. NestedCtxt_ blk f a -> NestedCtxt_ blk' f a) -> SomeSecond (NestedCtxt f) blk -> SomeSecond (NestedCtxt f) blk'
mapSomeNestedCtxt :: (forall a. NestedCtxt_ blk f a -> NestedCtxt_ blk' f' a) -> SomeSecond (NestedCtxt f) blk -> SomeSecond (NestedCtxt f') blk'

-- | Hide the second type argument of some functor
--   
--   <tt>SomeSecond f a</tt> is isomorphic to <tt>Some (f a)</tt>, but is
--   more convenient in partial applications.
data SomeSecond (f :: Type -> Type -> Type) a
[SomeSecond] :: !f a b -> SomeSecond f a
instance GHC.Show.Show (Ouroboros.Consensus.Block.NestedContent.NestedCtxt_ blk f a) => GHC.Show.Show (Ouroboros.Consensus.Block.NestedContent.NestedCtxt f blk a)
instance (Ouroboros.Consensus.Block.NestedContent.HasNestedContent f blk, forall a. GHC.Show.Show (g a)) => GHC.Show.Show (Ouroboros.Consensus.Util.DepPair.GenDepPair g (Ouroboros.Consensus.Block.NestedContent.NestedCtxt f blk))
instance Ouroboros.Consensus.Block.NestedContent.HasNestedContent f blk => GHC.Show.Show (Ouroboros.Consensus.Util.SomeSecond (Ouroboros.Consensus.Block.NestedContent.NestedCtxt f) blk)
instance (Data.Typeable.Internal.Typeable f, Data.Typeable.Internal.Typeable blk) => NoThunks.Class.NoThunks (Ouroboros.Consensus.Util.SomeSecond (Ouroboros.Consensus.Block.NestedContent.NestedCtxt f) blk)
instance Ouroboros.Consensus.Util.DepPair.SameDepIndex (Ouroboros.Consensus.Block.NestedContent.NestedCtxt_ blk f) => Ouroboros.Consensus.Util.DepPair.SameDepIndex (Ouroboros.Consensus.Block.NestedContent.NestedCtxt f blk)
instance Ouroboros.Consensus.Util.DepPair.TrivialDependency (Ouroboros.Consensus.Block.NestedContent.NestedCtxt_ blk f) => Ouroboros.Consensus.Util.DepPair.TrivialDependency (Ouroboros.Consensus.Block.NestedContent.NestedCtxt f blk)
instance Ouroboros.Consensus.Util.DepPair.SameDepIndex (Ouroboros.Consensus.Block.NestedContent.NestedCtxt_ blk f) => GHC.Classes.Eq (Ouroboros.Consensus.Util.SomeSecond (Ouroboros.Consensus.Block.NestedContent.NestedCtxt f) blk)

module Ouroboros.Consensus.Util.FileLock

-- | Abstraction for file locks
data FileLock m
FileLock :: (FilePath -> m (m ())) -> FileLock m

-- | Obtain an exclusive lock on the given file.
--   
--   Returns the function to unlock the file.
--   
--   Blocks until the lock is available.
--   
--   We don't guarantee the ability to read/write to a locked file, not
--   even when holding the lock.
[lockFile] :: FileLock m -> FilePath -> m (m ())

-- | Implementation of <a>FileLock</a> for <a>IO</a>, using on
--   <a>System.FileLock</a>.
--   
--   Locking the file can block in FFI, so not interruptible.
--   
--   Unlocking the file is not guaranteed to be synchronous. Near
--   instantaneous on Linux, but not synchronous. On Windows, unlocking is
--   even more lazy.
ioFileLock :: FileLock IO


-- | Heterogeneous lists
--   
--   Intended for qualified import
module Ouroboros.Consensus.Util.HList
data HList :: [Type] -> Type
[Nil] :: HList '[]
[:*] :: a -> HList as -> HList (a : as)
infixr 9 :*
type family All c as :: Constraint
foldl :: forall c as b proxy. All c as => proxy c -> (forall a. c a => b -> a -> b) -> b -> HList as -> b
foldlM :: forall c as m b proxy. (All c as, Monad m) => proxy c -> (forall a. c a => b -> a -> m b) -> b -> HList as -> m b
foldr :: forall c as b proxy. All c as => proxy c -> (forall a. c a => a -> b -> b) -> b -> HList as -> b
foldMap :: forall c as b proxy. (All c as, Monoid b) => proxy c -> (forall a. c a => a -> b) -> HList as -> b

-- | Apply function repeatedly for all elements of the list
--   
--   <pre>
--   repeatedly p = flip . foldl p . flip
--   </pre>
repeatedly :: forall c as b proxy. All c as => proxy c -> (forall a. c a => a -> b -> b) -> HList as -> b -> b
repeatedlyM :: forall c as b proxy m. (Monad m, All c as) => proxy c -> (forall a. c a => a -> b -> m b) -> HList as -> b -> m b
collapse :: forall c as b proxy. All c as => proxy c -> (forall a. c a => a -> b) -> HList as -> [b]
data SList :: [Type] -> Type
class IsList (xs :: [Type])
isList :: IsList xs => SList xs
type family Fn as b
applyFn :: Fn as b -> HList as -> b
afterFn :: SList as -> (b -> c) -> Fn as b -> Fn as c
instance (Ouroboros.Consensus.Util.HList.IsList as, Ouroboros.Consensus.Util.HList.All GHC.Classes.Eq as) => GHC.Classes.Eq (Ouroboros.Consensus.Util.HList.HList as)
instance (Ouroboros.Consensus.Util.HList.IsList as, Ouroboros.Consensus.Util.HList.All GHC.Classes.Eq as, Ouroboros.Consensus.Util.HList.All GHC.Classes.Ord as) => GHC.Classes.Ord (Ouroboros.Consensus.Util.HList.HList as)
instance Ouroboros.Consensus.Util.HList.IsList '[]
instance Ouroboros.Consensus.Util.HList.IsList as => Ouroboros.Consensus.Util.HList.IsList (a : as)
instance Ouroboros.Consensus.Util.HList.All GHC.Show.Show as => GHC.Show.Show (Ouroboros.Consensus.Util.HList.HList as)

module Ouroboros.Consensus.Util.Condense

-- | Condensed but human-readable output
class Condense a
condense :: Condense a => a -> String
class Condense1 f
liftCondense :: Condense1 f => (a -> String) -> f a -> String

-- | Lift the standard <a>condense</a> function through the type
--   constructor
condense1 :: (Condense1 f, Condense a) => f a -> String
instance Ouroboros.Consensus.Util.Condense.Condense1 []
instance Ouroboros.Consensus.Util.Condense.Condense1 Data.Set.Internal.Set
instance Ouroboros.Consensus.Util.Condense.Condense Data.Void.Void
instance Ouroboros.Consensus.Util.Condense.Condense Data.Text.Internal.Text
instance Ouroboros.Consensus.Util.Condense.Condense GHC.Types.Bool
instance Ouroboros.Consensus.Util.Condense.Condense GHC.Types.Int
instance Ouroboros.Consensus.Util.Condense.Condense GHC.Int.Int64
instance Ouroboros.Consensus.Util.Condense.Condense GHC.Types.Word
instance Ouroboros.Consensus.Util.Condense.Condense GHC.Word.Word32
instance Ouroboros.Consensus.Util.Condense.Condense GHC.Word.Word64
instance Ouroboros.Consensus.Util.Condense.Condense GHC.Natural.Natural
instance Ouroboros.Consensus.Util.Condense.Condense GHC.Real.Rational
instance Ouroboros.Consensus.Util.Condense.Condense a => Ouroboros.Consensus.Util.Condense.Condense [a]
instance Ouroboros.Consensus.Util.Condense.Condense a => Ouroboros.Consensus.Util.Condense.Condense (GHC.Maybe.Maybe a)
instance Ouroboros.Consensus.Util.Condense.Condense a => Ouroboros.Consensus.Util.Condense.Condense (Data.Set.Internal.Set a)
instance (Ouroboros.Consensus.Util.Condense.Condense a, Ouroboros.Consensus.Util.Condense.Condense b) => Ouroboros.Consensus.Util.Condense.Condense (a, b)
instance (Ouroboros.Consensus.Util.Condense.Condense a, Ouroboros.Consensus.Util.Condense.Condense b, Ouroboros.Consensus.Util.Condense.Condense c) => Ouroboros.Consensus.Util.Condense.Condense (a, b, c)
instance (Ouroboros.Consensus.Util.Condense.Condense a, Ouroboros.Consensus.Util.Condense.Condense b, Ouroboros.Consensus.Util.Condense.Condense c, Ouroboros.Consensus.Util.Condense.Condense d) => Ouroboros.Consensus.Util.Condense.Condense (a, b, c, d)
instance (Ouroboros.Consensus.Util.Condense.Condense a, Ouroboros.Consensus.Util.Condense.Condense b, Ouroboros.Consensus.Util.Condense.Condense c, Ouroboros.Consensus.Util.Condense.Condense d, Ouroboros.Consensus.Util.Condense.Condense e) => Ouroboros.Consensus.Util.Condense.Condense (a, b, c, d, e)
instance (Ouroboros.Consensus.Util.Condense.Condense k, Ouroboros.Consensus.Util.Condense.Condense a) => Ouroboros.Consensus.Util.Condense.Condense (Data.Map.Internal.Map k a)
instance Ouroboros.Consensus.Util.Condense.Condense Data.ByteString.Internal.ByteString
instance Ouroboros.Consensus.Util.Condense.Condense Data.ByteString.Lazy.Internal.ByteString
instance Ouroboros.Consensus.Util.HList.All Ouroboros.Consensus.Util.Condense.Condense as => Ouroboros.Consensus.Util.Condense.Condense (Ouroboros.Consensus.Util.HList.HList as)
instance Ouroboros.Consensus.Util.Condense.Condense Cardano.Slotting.Block.BlockNo
instance Ouroboros.Consensus.Util.Condense.Condense Cardano.Slotting.Slot.SlotNo
instance Ouroboros.Consensus.Util.Condense.Condense Cardano.Slotting.Slot.EpochNo
instance Ouroboros.Consensus.Util.Condense.Condense (Ouroboros.Network.Block.HeaderHash b) => Ouroboros.Consensus.Util.Condense.Condense (Ouroboros.Network.Block.ChainHash b)
instance Ouroboros.Consensus.Util.Condense.Condense (Ouroboros.Network.Block.HeaderHash b) => Ouroboros.Consensus.Util.Condense.Condense (Ouroboros.Network.Block.Tip b)
instance Ouroboros.Consensus.Util.Condense.Condense a => Ouroboros.Consensus.Util.Condense.Condense (Cardano.Slotting.Slot.WithOrigin a)
instance Ouroboros.Consensus.Util.Condense.Condense (Cardano.Crypto.DSIGN.Class.SigDSIGN v) => Ouroboros.Consensus.Util.Condense.Condense (Cardano.Crypto.DSIGN.Class.SignedDSIGN v a)
instance Ouroboros.Consensus.Util.Condense.Condense (Cardano.Crypto.DSIGN.Class.SigDSIGN Cardano.Crypto.DSIGN.Ed25519.Ed25519DSIGN)
instance Ouroboros.Consensus.Util.Condense.Condense (Cardano.Crypto.DSIGN.Class.SigDSIGN Cardano.Crypto.DSIGN.Ed448.Ed448DSIGN)
instance Ouroboros.Consensus.Util.Condense.Condense (Cardano.Crypto.DSIGN.Class.SigDSIGN Cardano.Crypto.DSIGN.Mock.MockDSIGN)
instance Ouroboros.Consensus.Util.Condense.Condense (Cardano.Crypto.KES.Class.SigKES v) => Ouroboros.Consensus.Util.Condense.Condense (Cardano.Crypto.KES.Class.SignedKES v a)
instance Ouroboros.Consensus.Util.Condense.Condense (Cardano.Crypto.KES.Class.SigKES (Cardano.Crypto.KES.Mock.MockKES t))
instance Ouroboros.Consensus.Util.Condense.Condense (Cardano.Crypto.KES.Class.SigKES Cardano.Crypto.KES.NeverUsed.NeverKES)
instance Ouroboros.Consensus.Util.Condense.Condense (Cardano.Crypto.DSIGN.Class.SigDSIGN d) => Ouroboros.Consensus.Util.Condense.Condense (Cardano.Crypto.KES.Class.SigKES (Cardano.Crypto.KES.Simple.SimpleKES d t))
instance Ouroboros.Consensus.Util.Condense.Condense (Cardano.Crypto.KES.Class.SigKES (Cardano.Crypto.KES.Single.SingleKES d))
instance GHC.Show.Show (Cardano.Crypto.DSIGN.Class.VerKeyDSIGN d) => Ouroboros.Consensus.Util.Condense.Condense (Cardano.Crypto.DSIGN.Class.VerKeyDSIGN d)
instance (Ouroboros.Consensus.Util.Condense.Condense (Cardano.Crypto.KES.Class.SigKES d), Ouroboros.Consensus.Util.Condense.Condense (Cardano.Crypto.KES.Class.VerKeyKES d)) => Ouroboros.Consensus.Util.Condense.Condense (Cardano.Crypto.KES.Class.SigKES (Cardano.Crypto.KES.Sum.SumKES h d))
instance Ouroboros.Consensus.Util.Condense.Condense (Cardano.Crypto.KES.Class.VerKeyKES (Cardano.Crypto.KES.Single.SingleKES d))
instance Ouroboros.Consensus.Util.Condense.Condense (Cardano.Crypto.KES.Class.VerKeyKES (Cardano.Crypto.KES.Sum.SumKES h d))
instance Ouroboros.Consensus.Util.Condense.Condense (Cardano.Crypto.Hash.Class.Hash h a)
instance Ouroboros.Consensus.Util.Condense.Condense Control.Monad.Class.MonadTime.Time

module Ouroboros.Consensus.Storage.FS.API.Types

-- | How to <tt>hOpen</tt> a new file.
data OpenMode
ReadMode :: OpenMode
WriteMode :: AllowExisting -> OpenMode
AppendMode :: AllowExisting -> OpenMode
ReadWriteMode :: AllowExisting -> OpenMode

-- | When <tt>hOpen</tt>ing a file:
data AllowExisting

-- | The file may already exist. If it does, it is reopened. If it doesn't,
--   it is created.
AllowExisting :: AllowExisting

-- | The file may not yet exist. If it does, an error
--   (<a>FsResourceAlreadyExist</a>) is thrown.
MustBeNew :: AllowExisting
allowExisting :: OpenMode -> AllowExisting

-- | A mode that determines the effect of <a>hSeek</a> <tt>hdl mode i</tt>.
data SeekMode

-- | the position of <tt>hdl</tt> is set to <tt>i</tt>.
AbsoluteSeek :: SeekMode

-- | the position of <tt>hdl</tt> is set to offset <tt>i</tt> from the
--   current position.
RelativeSeek :: SeekMode

-- | the position of <tt>hdl</tt> is set to offset <tt>i</tt> from the end
--   of the file.
SeekFromEnd :: SeekMode
data FsPath
fsPathToList :: FsPath -> [Text]
fsPathFromList :: [Text] -> FsPath

-- | Split <a>FsPath</a> is essentially <tt>(init fp, last fp)</tt>
--   
--   Like <tt>init</tt> and <tt>last</tt>, <a>Nothing</a> if empty.
fsPathSplit :: FsPath -> Maybe (FsPath, Text)

-- | Drop the final component of the path
--   
--   Undefined if the path is empty.
fsPathInit :: HasCallStack => FsPath -> FsPath

-- | Constructor for <a>FsPath</a> ensures path is in normal form
mkFsPath :: [String] -> FsPath

-- | Mount point
--   
--   <a>FsPath</a>s are not absolute paths, but must be interpreted with
--   respect to a particualar mount point.
newtype MountPoint
MountPoint :: FilePath -> MountPoint
fsToFilePath :: MountPoint -> FsPath -> FilePath
fsFromFilePath :: MountPoint -> FilePath -> Maybe FsPath
data Handle h
Handle :: !h -> !FsPath -> Handle h

-- | The raw underlying handle
[handleRaw] :: Handle h -> !h

-- | The path corresponding to this handle
--   
--   This is primarily useful for error reporting.
[handlePath] :: Handle h -> !FsPath
newtype AbsOffset
AbsOffset :: Word64 -> AbsOffset
[unAbsOffset] :: AbsOffset -> Word64
data FsError
FsError :: FsErrorType -> FsErrorPath -> String -> Maybe Errno -> PrettyCallStack -> Bool -> FsError

-- | Error type
[fsErrorType] :: FsError -> FsErrorType

-- | Path to the file
[fsErrorPath] :: FsError -> FsErrorPath

-- | Human-readable string giving additional information about the error
[fsErrorString] :: FsError -> String

-- | The <a>Errno</a>, if available. This is more precise than the
--   <a>FsErrorType</a>.
[fsErrorNo] :: FsError -> Maybe Errno

-- | Call stack
[fsErrorStack] :: FsError -> PrettyCallStack

-- | Is this error due to a limitation of the mock file system?
--   
--   The mock file system does not all of Posix's features and quirks. This
--   flag will be set for such unsupported IO calls. Real I/O calls would
--   not have thrown an error for these calls.
[fsLimitation] :: FsError -> Bool
data FsErrorType
FsIllegalOperation :: FsErrorType

-- | e.g the user tried to open a directory with hOpen rather than a file.
FsResourceInappropriateType :: FsErrorType
FsResourceAlreadyInUse :: FsErrorType
FsResourceDoesNotExist :: FsErrorType
FsResourceAlreadyExist :: FsErrorType
FsReachedEOF :: FsErrorType
FsDeviceFull :: FsErrorType
FsTooManyOpenFiles :: FsErrorType
FsInsufficientPermissions :: FsErrorType
FsInvalidArgument :: FsErrorType

-- | Used for all other error types
FsOther :: FsErrorType

-- | For better error reporting to the end user, we want to include the
--   mount point of the file. But the mountpoint may not always be
--   available, like when we mock the fs or we simulate fs errors.
data FsErrorPath
FsErrorPath :: Maybe MountPoint -> FsPath -> FsErrorPath

-- | Check if two errors are semantically the same error
--   
--   This ignores the error string, the errno, and the callstack.
sameFsError :: FsError -> FsError -> Bool
isFsErrorType :: FsErrorType -> FsError -> Bool
prettyFsError :: FsError -> String
fsToFsErrorPath :: MountPoint -> FsPath -> FsErrorPath

-- | Like <a>fsToFsErrorPath</a>, but when we don't have a
--   <a>MountPoint</a>
fsToFsErrorPathUnmounted :: FsPath -> FsErrorPath
hasMountPoint :: FsError -> Bool

-- | Translate exceptions thrown by IO functions to <a>FsError</a>
--   
--   We take the <a>FsPath</a> as an argument. We could try to translate
--   back from a <a>FilePath</a> to an <a>FsPath</a> (given a
--   <a>MountPoint</a>), but we know the <a>FsPath</a> at all times anyway
--   and not all IO exceptions actually include a filepath.
ioToFsError :: HasCallStack => FsErrorPath -> IOError -> FsError

-- | Assign an <a>FsErrorType</a> to the given <a>IOError</a>.
--   
--   Note that we don't always use the classification made by
--   <a>errnoToIOError</a> (also see <a>Error</a>) because it combines some
--   errors into one <tt>IOErrorType</tt>, e.g., <tt>EMFILE</tt> (too many
--   open files) and <tt>ENOSPC</tt> (no space left on device) both result
--   in <tt>ResourceExhausted</tt> while we want to keep them separate. For
--   this reason, we do a classification of our own based on the
--   <tt>errno</tt> while sometimes deferring to the existing
--   classification.
--   
--   See the ERRNO(3) man page for the meaning of the different errnos.
ioToFsErrorType :: IOError -> FsErrorType
instance GHC.Show.Show Ouroboros.Consensus.Storage.FS.API.Types.AllowExisting
instance GHC.Classes.Eq Ouroboros.Consensus.Storage.FS.API.Types.AllowExisting
instance GHC.Show.Show Ouroboros.Consensus.Storage.FS.API.Types.OpenMode
instance GHC.Classes.Eq Ouroboros.Consensus.Storage.FS.API.Types.OpenMode
instance NoThunks.Class.NoThunks Ouroboros.Consensus.Storage.FS.API.Types.FsPath
instance GHC.Generics.Generic Ouroboros.Consensus.Storage.FS.API.Types.FsPath
instance GHC.Classes.Ord Ouroboros.Consensus.Storage.FS.API.Types.FsPath
instance GHC.Classes.Eq Ouroboros.Consensus.Storage.FS.API.Types.FsPath
instance NoThunks.Class.NoThunks (Ouroboros.Consensus.Storage.FS.API.Types.Handle h)
instance GHC.Generics.Generic (Ouroboros.Consensus.Storage.FS.API.Types.Handle h)
instance GHC.Show.Show Ouroboros.Consensus.Storage.FS.API.Types.AbsOffset
instance GHC.Num.Num Ouroboros.Consensus.Storage.FS.API.Types.AbsOffset
instance GHC.Enum.Bounded Ouroboros.Consensus.Storage.FS.API.Types.AbsOffset
instance GHC.Enum.Enum Ouroboros.Consensus.Storage.FS.API.Types.AbsOffset
instance GHC.Classes.Ord Ouroboros.Consensus.Storage.FS.API.Types.AbsOffset
instance GHC.Classes.Eq Ouroboros.Consensus.Storage.FS.API.Types.AbsOffset
instance GHC.Classes.Eq Ouroboros.Consensus.Storage.FS.API.Types.FsErrorType
instance GHC.Show.Show Ouroboros.Consensus.Storage.FS.API.Types.FsErrorType
instance GHC.Show.Show Ouroboros.Consensus.Storage.FS.API.Types.FsError
instance GHC.Show.Show Foreign.C.Error.Errno
instance GHC.Exception.Type.Exception Ouroboros.Consensus.Storage.FS.API.Types.FsError
instance GHC.Classes.Eq h => GHC.Classes.Eq (Ouroboros.Consensus.Storage.FS.API.Types.Handle h)
instance GHC.Show.Show (Ouroboros.Consensus.Storage.FS.API.Types.Handle h)
instance Ouroboros.Consensus.Util.Condense.Condense (Ouroboros.Consensus.Storage.FS.API.Types.Handle h)
instance GHC.Show.Show Ouroboros.Consensus.Storage.FS.API.Types.FsErrorPath
instance Ouroboros.Consensus.Util.Condense.Condense Ouroboros.Consensus.Storage.FS.API.Types.FsErrorPath
instance GHC.Classes.Eq Ouroboros.Consensus.Storage.FS.API.Types.FsErrorPath
instance GHC.Show.Show Ouroboros.Consensus.Storage.FS.API.Types.FsPath
instance Ouroboros.Consensus.Util.Condense.Condense Ouroboros.Consensus.Storage.FS.API.Types.FsPath
instance Ouroboros.Consensus.Util.Condense.Condense Ouroboros.Consensus.Storage.FS.API.Types.OpenMode
instance Ouroboros.Consensus.Util.Condense.Condense Ouroboros.Consensus.Storage.FS.API.Types.AllowExisting
instance Ouroboros.Consensus.Util.Condense.Condense GHC.IO.Device.SeekMode

module Ouroboros.Consensus.Storage.IO
type FHandle = HandleOS Fd

-- | Opens a file from disk.
open :: FilePath -> OpenMode -> IO Fd

-- | Truncates the file managed by the input <a>FHandle</a> to the input
--   size.
truncate :: FHandle -> Word64 -> IO ()

-- | Seek within the file.
--   
--   The offset may be negative.
--   
--   We don't return the new offset since the behaviour of lseek is rather
--   odd (e.g., the file pointer may not actually be moved until a
--   subsequent write)
seek :: FHandle -> SeekMode -> Int64 -> IO ()

-- | Reads a given number of bytes from the input <a>FHandle</a>.
read :: FHandle -> Word64 -> IO ByteString
pread :: FHandle -> Word64 -> Word64 -> IO ByteString

-- | Writes the data pointed by the input 'Ptr Word8' into the input
--   <a>FHandle</a>.
write :: FHandle -> Ptr Word8 -> Int64 -> IO Word32

-- | Close handle
--   
--   This is a no-op when the handle is already closed.
close :: FHandle -> IO ()

-- | File size of the given file pointer
--   
--   NOTE: This is not thread safe (changes made to the file in other
--   threads may affect this thread).
getSize :: FHandle -> IO Word64
sameError :: FsError -> FsError -> Bool


-- | An abstract view over the filesystem.
module Ouroboros.Consensus.Storage.FS.API
data HasFS m h
HasFS :: m String -> (HasCallStack => FsPath -> OpenMode -> m (Handle h)) -> (HasCallStack => Handle h -> m ()) -> (HasCallStack => Handle h -> m Bool) -> (HasCallStack => Handle h -> SeekMode -> Int64 -> m ()) -> (HasCallStack => Handle h -> Word64 -> m ByteString) -> (HasCallStack => Handle h -> Word64 -> AbsOffset -> m ByteString) -> (HasCallStack => Handle h -> ByteString -> m Word64) -> (HasCallStack => Handle h -> Word64 -> m ()) -> (HasCallStack => Handle h -> m Word64) -> (HasCallStack => FsPath -> m ()) -> (HasCallStack => Bool -> FsPath -> m ()) -> (HasCallStack => FsPath -> m (Set String)) -> (HasCallStack => FsPath -> m Bool) -> (HasCallStack => FsPath -> m Bool) -> (HasCallStack => FsPath -> m ()) -> (HasCallStack => FsPath -> FsPath -> m ()) -> (FsPath -> FsErrorPath) -> HasFS m h

-- | Debugging: human-readable description of file system state
[dumpState] :: HasFS m h -> m String

-- | Open a file
[hOpen] :: HasFS m h -> HasCallStack => FsPath -> OpenMode -> m (Handle h)

-- | Close a file
[hClose] :: HasFS m h -> HasCallStack => Handle h -> m ()

-- | Is the handle open?
[hIsOpen] :: HasFS m h -> HasCallStack => Handle h -> m Bool

-- | Seek handle
--   
--   The offset is an <a>Int64</a> rather than a <a>Word64</a> because it
--   may be negative (for use in relative positioning).
--   
--   Unlike the Posix <tt>lseek</tt>, <a>hSeek</a> does not return the new
--   seek position because the value returned by Posix is rather strange
--   and unreliable and we don't want to emulate it's behaviour.
[hSeek] :: HasFS m h -> HasCallStack => Handle h -> SeekMode -> Int64 -> m ()

-- | Try to read <tt>n</tt> bytes from a handle
--   
--   When at the end of the file, an empty bytestring will be returned.
--   
--   The returned bytestring will typically have length <tt>n</tt>, but may
--   be shorter in case of a partial read, see #277. However, a partial
--   read will always return at least 1 byte, as returning 0 bytes would
--   mean that we have reached EOF.
--   
--   Postcondition: the length of the returned bytestring <a>@n@ and</a>=
--   0.
[hGetSome] :: HasFS m h -> HasCallStack => Handle h -> Word64 -> m ByteString

-- | Same as <a>hGetSome</a>, but does not affect the file offset. An
--   additional argument is used to specify the offset. This allows it to
--   be called concurrently for the same file handle. However, the actual
--   level of parallelism achieved depends on the implementation and the
--   operating system: generally on Unix it will be "more parallel" than on
--   Windows.
[hGetSomeAt] :: HasFS m h -> HasCallStack => Handle h -> Word64 -> AbsOffset -> m ByteString

-- | Write to a handle
--   
--   The return value indicates the number of bytes written and will
--   typically be equal to <tt>l</tt>, the length of the bytestring, but
--   may be shorter in case of a partial write, see #277.
--   
--   If nothing can be written at all, an exception will be thrown.
--   
--   Postcondition: the return value <a>@l@ and</a> 0, unless the given
--   bytestring is empty, in which case the return value can be 0.
[hPutSome] :: HasFS m h -> HasCallStack => Handle h -> ByteString -> m Word64

-- | Truncate the file to the specified size
--   
--   NOTE: Only supported in append mode.
[hTruncate] :: HasFS m h -> HasCallStack => Handle h -> Word64 -> m ()

-- | Return current file size
--   
--   NOTE: This is not thread safe (changes made to the file in other
--   threads may affect this thread).
[hGetSize] :: HasFS m h -> HasCallStack => Handle h -> m Word64

-- | Create new directory
[createDirectory] :: HasFS m h -> HasCallStack => FsPath -> m ()

-- | Create new directory if it doesn't exist.
--   
--   <tt>createDirectoryIfMissing True</tt> will also try to create all
--   parent dirs.
[createDirectoryIfMissing] :: HasFS m h -> HasCallStack => Bool -> FsPath -> m ()

-- | List contents of a directory
[listDirectory] :: HasFS m h -> HasCallStack => FsPath -> m (Set String)

-- | Check if the path exists and is a directory
[doesDirectoryExist] :: HasFS m h -> HasCallStack => FsPath -> m Bool

-- | Check if the path exists and is a file
[doesFileExist] :: HasFS m h -> HasCallStack => FsPath -> m Bool

-- | Remove the file (which must exist)
[removeFile] :: HasFS m h -> HasCallStack => FsPath -> m ()

-- | Rename the file (which must exist) from the first path to the second
--   path. If there is already a file at the latter path, it is replaced by
--   the new one.
--   
--   NOTE: only works for files within the same folder.
[renameFile] :: HasFS m h -> HasCallStack => FsPath -> FsPath -> m ()

-- | Useful for better error reporting
[mkFsErrorPath] :: HasFS m h -> FsPath -> FsErrorPath
data Handle h
Handle :: !h -> !FsPath -> Handle h

-- | The raw underlying handle
[handleRaw] :: Handle h -> !h

-- | The path corresponding to this handle
--   
--   This is primarily useful for error reporting.
[handlePath] :: Handle h -> !FsPath

-- | Makes sure it reads all requested bytes. If eof is found before all
--   bytes are read, it throws an exception.
hGetExactly :: forall m h. (HasCallStack, MonadThrow m) => HasFS m h -> Handle h -> Word64 -> m ByteString

-- | Like <a>hGetExactly</a>, but is thread safe since it does not change
--   or depend on the file offset. <tt>pread</tt> syscall is used
--   internally.
hGetExactlyAt :: forall m h. (HasCallStack, MonadThrow m) => HasFS m h -> Handle h -> Word64 -> AbsOffset -> m ByteString

-- | Read all the data from the given file handle 64kB at a time.
--   
--   Stops when EOF is reached.
hGetAll :: Monad m => HasFS m h -> Handle h -> m ByteString

-- | Like <a>hGetAll</a>, but is thread safe since it does not change or
--   depend on the file offset. <tt>pread</tt> syscall is used internally.
hGetAllAt :: Monad m => HasFS m h -> Handle h -> AbsOffset -> m ByteString

-- | This function makes sure that the whole <a>Builder</a> is written.
--   
--   The chunk size of the resulting <a>ByteString</a> determines how much
--   memory will be used while writing to the handle.
hPut :: forall m h. (HasCallStack, Monad m) => HasFS m h -> Handle h -> Builder -> m Word64

-- | This function makes sure that the whole <a>ByteString</a> is written.
hPutAll :: forall m h. (HasCallStack, Monad m) => HasFS m h -> Handle h -> ByteString -> m Word64

-- | This function makes sure that the whole <a>ByteString</a> is written.
hPutAllStrict :: forall m h. (HasCallStack, Monad m) => HasFS m h -> Handle h -> ByteString -> m Word64
withFile :: (HasCallStack, MonadThrow m) => HasFS m h -> FsPath -> OpenMode -> (Handle h -> m a) -> m a

-- | Returns <a>True</a> when the handle was still open.
hClose' :: (HasCallStack, Monad m) => HasFS m h -> Handle h -> m Bool

-- | It is often inconvenient to have to parameterise over <tt>h</tt>. One
--   often makes it existential, losing the ability to use derive
--   <tt>Generic</tt> and <a>NoThunks</a>. This data type hides an
--   existential <tt>h</tt> parameter of a <a>HasFS</a> and provides a
--   <a>NoThunks</a> thunks instance.
data SomeHasFS m
[SomeHasFS] :: Eq h => HasFS m h -> SomeHasFS m
instance NoThunks.Class.NoThunks (Ouroboros.Consensus.Storage.FS.API.HasFS m h)
instance NoThunks.Class.NoThunks (Ouroboros.Consensus.Storage.FS.API.SomeHasFS m)


-- | IO implementation of the <a>HasFS</a> class
module Ouroboros.Consensus.Storage.FS.IO

-- | File handlers for the IO instance for HasFS
--   
--   We store the path the handle points to for better error messages
type HandleIO = FHandle
ioHasFS :: MountPoint -> HasFS IO HandleIO


-- | Support for CRC
module Ouroboros.Consensus.Storage.FS.CRC
newtype CRC
CRC :: Word32 -> CRC
[getCRC] :: CRC -> Word32
initCRC :: CRC
updateCRC :: forall a. CRC32 a => a -> CRC -> CRC
computeCRC :: forall a. CRC32 a => a -> CRC

-- | Variation on <a>hPutAll</a> that also computes a CRC
hPutAllCRC :: forall m h. (HasCallStack, Monad m) => HasFS m h -> Handle h -> ByteString -> m (Word64, CRC)

-- | Variation on <a>hGetExactlyAt</a> that also computes a CRC
hGetExactlyAtCRC :: forall m h. (HasCallStack, MonadThrow m) => HasFS m h -> Handle h -> Word64 -> AbsOffset -> m (ByteString, CRC)

-- | Variation on <a>hGetAllAt</a> that also computes a CRC
hGetAllAtCRC :: forall m h. Monad m => HasFS m h -> Handle h -> AbsOffset -> m (ByteString, CRC)
instance Foreign.Storable.Storable Ouroboros.Consensus.Storage.FS.CRC.CRC
instance NoThunks.Class.NoThunks Ouroboros.Consensus.Storage.FS.CRC.CRC
instance GHC.Generics.Generic Ouroboros.Consensus.Storage.FS.CRC.CRC
instance GHC.Show.Show Ouroboros.Consensus.Storage.FS.CRC.CRC
instance GHC.Classes.Eq Ouroboros.Consensus.Storage.FS.CRC.CRC

module Ouroboros.Consensus.Protocol.PBFT.Crypto

-- | Crypto primitives required by BFT
--   
--   Cardano stores a map of stakeholder IDs rather than the verification
--   key directly. We make this family injective for convenience - whilst
--   it's _possible_ that there could be non-injective instances, the
--   chances of there being more than the two instances here are basically
--   non-existent.
class (Typeable c, DSIGNAlgorithm (PBftDSIGN c), Condense (SigDSIGN (PBftDSIGN c)), Show (PBftVerKeyHash c), Ord (PBftVerKeyHash c), Eq (PBftVerKeyHash c), Show (PBftVerKeyHash c), NoThunks (PBftVerKeyHash c), NoThunks (PBftDelegationCert c)) => PBftCrypto c where {
    type family PBftDSIGN c :: Type;
    type family PBftDelegationCert c = (d :: Type) | d -> c;
    type family PBftVerKeyHash c = (d :: Type) | d -> c;
}
dlgCertGenVerKey :: PBftCrypto c => PBftDelegationCert c -> VerKeyDSIGN (PBftDSIGN c)
dlgCertDlgVerKey :: PBftCrypto c => PBftDelegationCert c -> VerKeyDSIGN (PBftDSIGN c)
hashVerKey :: PBftCrypto c => VerKeyDSIGN (PBftDSIGN c) -> PBftVerKeyHash c
data PBftMockCrypto
instance Ouroboros.Consensus.Protocol.PBFT.Crypto.PBftCrypto Ouroboros.Consensus.Protocol.PBFT.Crypto.PBftMockCrypto

module Ouroboros.Consensus.NodeId
data NodeId
CoreId :: !CoreNodeId -> NodeId
RelayId :: !Word64 -> NodeId

-- | Core node ID
newtype CoreNodeId
CoreNodeId :: Word64 -> CoreNodeId
[unCoreNodeId] :: CoreNodeId -> Word64
fromCoreNodeId :: CoreNodeId -> NodeId
instance GHC.Show.Show Ouroboros.Consensus.NodeId.CoreNodeId
instance NoThunks.Class.NoThunks Ouroboros.Consensus.NodeId.CoreNodeId
instance Codec.Serialise.Class.Serialise Ouroboros.Consensus.NodeId.CoreNodeId
instance Ouroboros.Consensus.Util.Condense.Condense Ouroboros.Consensus.NodeId.CoreNodeId
instance GHC.Generics.Generic Ouroboros.Consensus.NodeId.CoreNodeId
instance GHC.Classes.Ord Ouroboros.Consensus.NodeId.CoreNodeId
instance GHC.Classes.Eq Ouroboros.Consensus.NodeId.CoreNodeId
instance NoThunks.Class.NoThunks Ouroboros.Consensus.NodeId.NodeId
instance GHC.Generics.Generic Ouroboros.Consensus.NodeId.NodeId
instance GHC.Show.Show Ouroboros.Consensus.NodeId.NodeId
instance GHC.Classes.Ord Ouroboros.Consensus.NodeId.NodeId
instance GHC.Classes.Eq Ouroboros.Consensus.NodeId.NodeId
instance Ouroboros.Consensus.Util.Condense.Condense Ouroboros.Consensus.NodeId.NodeId
instance Data.Hashable.Class.Hashable Ouroboros.Consensus.NodeId.NodeId
instance Data.Hashable.Class.Hashable Ouroboros.Consensus.NodeId.CoreNodeId


-- | Generic infrastructure for working with EBBs
module Ouroboros.Consensus.Block.EBB

-- | Whether a block is an Epoch Boundary Block (EBB)
--   
--   See <a>Ouroboros.Storage.ImmutableDB.API</a> for a discussion of EBBs.
--   Key idiosyncracies:
--   
--   <ul>
--   <li>An EBB carries no unique information.</li>
--   <li>An EBB has the same <tt>BlockNo</tt> as its predecessor.</li>
--   <li>EBBs are vestigial. As of Shelley, nodes no longer forge EBBs:
--   they are only a legacy/backwards-compatibility concern.</li>
--   </ul>
data IsEBB
IsEBB :: IsEBB
IsNotEBB :: IsEBB
toIsEBB :: Bool -> IsEBB
fromIsEBB :: IsEBB -> Bool
instance NoThunks.Class.NoThunks Ouroboros.Consensus.Block.EBB.IsEBB
instance GHC.Generics.Generic Ouroboros.Consensus.Block.EBB.IsEBB
instance GHC.Show.Show Ouroboros.Consensus.Block.EBB.IsEBB
instance GHC.Classes.Eq Ouroboros.Consensus.Block.EBB.IsEBB
instance Codec.Serialise.Class.Serialise Ouroboros.Consensus.Block.EBB.IsEBB
instance Ouroboros.Consensus.Util.Condense.Condense Ouroboros.Consensus.Block.EBB.IsEBB

module Ouroboros.Consensus.Block.Abstract

-- | Map block to consensus protocol
type family BlockProtocol blk :: Type

-- | Static configuration required to work with this type of blocks
data family BlockConfig blk :: Type

-- | Static configuration required for serialisation and deserialisation of
--   types pertaining to this type of block.
--   
--   Data family instead of type family to get better type inference.
data family CodecConfig blk :: Type

-- | Config needed for the <a>NodeInitStorage</a> class. Defined here to
--   avoid circular dependencies.
data family StorageConfig blk :: Type
class (HasHeader blk, GetHeader blk) => GetPrevHash blk

-- | Get the hash of the predecessor of this block
headerPrevHash :: GetPrevHash blk => Header blk -> ChainHash blk
blockPrevHash :: GetPrevHash blk => blk -> ChainHash blk
data family Header blk :: Type
class HasHeader (Header blk) => GetHeader blk
getHeader :: GetHeader blk => blk -> Header blk

-- | Check whether the header is the header of the block.
--   
--   For example, by checking whether the hash of the body stored in the
--   header matches that of the block.
blockMatchesHeader :: GetHeader blk => Header blk -> blk -> Bool

-- | When the given header is the header of an Epoch Boundary Block,
--   returns its epoch number.
headerIsEBB :: GetHeader blk => Header blk -> Maybe EpochNo

-- | Get the <a>HeaderFields</a> of a block, without requiring 'HasHeader
--   blk'
--   
--   This is primarily useful as a a simple definition of <a>HasHeader</a>
--   for block types:
--   
--   <pre>
--   instance HasHeader SomeBlock where
--     getHeaderFields = getBlockHeaderFields
--   </pre>
--   
--   provided that there is a <a>HasHeader</a> instance for the header.
--   
--   Unfortunately we cannot give a <a>HasHeader</a> instance once and for
--   all; if we mapped from a header to a block instead we could do
--   
--   <pre>
--   instance HasHeader hdr =&gt; HasHeader (Block hdr) where
--    ..
--   </pre>
--   
--   but we can't do that when we do things this way around.
getBlockHeaderFields :: GetHeader blk => blk -> HeaderFields blk
headerHash :: HasHeader (Header blk) => Header blk -> HeaderHash blk
headerPoint :: HasHeader (Header blk) => Header blk -> Point blk
headerToIsEBB :: GetHeader blk => Header blk -> IsEBB
blockIsEBB :: GetHeader blk => blk -> Maybe EpochNo
blockToIsEBB :: GetHeader blk => blk -> IsEBB

-- | Convert a hash from/to raw bytes
--   
--   Variants of <a>toRawHash</a> and <a>fromRawHash</a> for
--   <a>ShortByteString</a> are included. Override the default
--   implementations to avoid an extra step in case the <a>HeaderHash</a>
--   is a <a>ShortByteString</a> under the hood.
class ConvertRawHash blk

-- | Get the raw bytes from a hash
toRawHash :: ConvertRawHash blk => proxy blk -> HeaderHash blk -> ByteString

-- | Construct the hash from a raw hash
--   
--   PRECONDITION: the bytestring's size must match <a>hashSize</a>
fromRawHash :: ConvertRawHash blk => proxy blk -> ByteString -> HeaderHash blk

-- | Variant of <a>toRawHash</a> for <a>ShortByteString</a>
toShortRawHash :: ConvertRawHash blk => proxy blk -> HeaderHash blk -> ShortByteString

-- | Variant of <a>fromRawHash</a> for <a>ShortByteString</a>
fromShortRawHash :: ConvertRawHash blk => proxy blk -> ShortByteString -> HeaderHash blk

-- | The size of the hash in number of bytes
hashSize :: ConvertRawHash blk => proxy blk -> Word32
encodeRawHash :: ConvertRawHash blk => proxy blk -> HeaderHash blk -> Encoding
decodeRawHash :: ConvertRawHash blk => proxy blk -> forall s. Decoder s (HeaderHash blk)

-- | Return the successor of a <a>WithOrigin</a> value. Useful in
--   combination with <a>SlotNo</a> and <a>BlockNo</a>.
succWithOrigin :: (Bounded t, Enum t) => WithOrigin t -> t
blockHash :: HasHeader b => b -> HeaderHash b
blockMeasure :: HasHeader b => b -> BlockMeasure
data BlockMeasure
blockNo :: HasHeader b => b -> BlockNo
blockPoint :: HasHeader block => block -> Point block
blockSlot :: HasHeader b => b -> SlotNo
castHash :: Coercible (HeaderHash b) (HeaderHash b') => ChainHash b -> ChainHash b'
castHeaderFields :: HeaderHash b ~ HeaderHash b' => HeaderFields b -> HeaderFields b'
castPoint :: Coercible (HeaderHash b) (HeaderHash b') => Point b -> Point b'
data ChainHash b
GenesisHash :: ChainHash b
BlockHash :: !HeaderHash b -> ChainHash b
class (StandardHash b, Measured BlockMeasure b, Typeable b) => HasHeader b
getHeaderFields :: HasHeader b => b -> HeaderFields b
data HeaderFields b
HeaderFields :: SlotNo -> BlockNo -> HeaderHash b -> HeaderFields b
[headerFieldSlot] :: HeaderFields b -> SlotNo
[headerFieldBlockNo] :: HeaderFields b -> BlockNo
[headerFieldHash] :: HeaderFields b -> HeaderHash b
type family HeaderHash b
data Point block
pattern GenesisPoint :: Point block
pattern BlockPoint :: SlotNo -> HeaderHash block -> Point block
pointHash :: Point block -> ChainHash block
pointSlot :: Point block -> WithOrigin SlotNo
class (Eq HeaderHash b, Ord HeaderHash b, Show HeaderHash b, Typeable HeaderHash b, NoThunks HeaderHash b) => StandardHash b

-- | The 0-based index of the block in the blockchain. BlockNo is &lt;=
--   SlotNo and is only equal at slot N if there is a block for every slot
--   where N &lt;= SlotNo.
newtype BlockNo
BlockNo :: Word64 -> BlockNo
[unBlockNo] :: BlockNo -> Word64

-- | An epoch, i.e. the number of the epoch.
newtype EpochNo
EpochNo :: Word64 -> EpochNo
[unEpochNo] :: EpochNo -> Word64
newtype EpochSize
EpochSize :: Word64 -> EpochSize
[unEpochSize] :: EpochSize -> Word64
fromWithOrigin :: t -> WithOrigin t -> t

-- | The 0-based index for the Ourboros time slot.
newtype SlotNo
SlotNo :: Word64 -> SlotNo
[unSlotNo] :: SlotNo -> Word64
withOrigin :: b -> (t -> b) -> WithOrigin t -> b
withOriginFromMaybe :: Maybe t -> WithOrigin t
data WithOrigin t
Origin :: WithOrigin t

-- | Custom pattern for <a>WithOrigin</a>
--   
--   This avoids clashing with our (extensive) use of <tt>At</tt> for
--   testing.
pattern NotOrigin :: t -> WithOrigin t
withOriginToMaybe :: WithOrigin t -> Maybe t
instance Ouroboros.Network.Block.HasHeader blk => Ouroboros.Network.Block.StandardHash (Ouroboros.Consensus.Block.Abstract.Header blk)
instance Ouroboros.Network.Block.HasHeader (Ouroboros.Consensus.Block.Abstract.Header blk) => Data.FingerTree.Measured Ouroboros.Network.Block.BlockMeasure (Ouroboros.Consensus.Block.Abstract.Header blk)

module Ouroboros.Consensus.Protocol.Abstract

-- | The (open) universe of Ouroboros protocols
--   
--   This class encodes the part that is independent from any particular
--   block representation.
class (Show (ChainDepState p), Show (ValidationErr p), Show (LedgerView p), Eq (ChainDepState p), Eq (ValidationErr p), NoThunks (ConsensusConfig p), NoThunks (ChainDepState p), NoThunks (ValidationErr p), Typeable p, ChainSelection p) => ConsensusProtocol p where {
    
    -- | Protocol-specific state
    --   
    --   NOTE: This chain is blockchain dependent, i.e., updated when new
    --   blocks come in (more precisely, new <i>headers</i>), and subject to
    --   rollback.
    type family ChainDepState p :: Type;
    
    -- | Evidence that a node <i>is</i> the leader
    type family IsLeader p :: Type;
    
    -- | Evidence that we <i>can</i> be a leader
    type family CanBeLeader p :: Type;
    
    -- | Projection of the ledger state the Ouroboros protocol needs access to
    --   
    --   The <a>LedgerView</a> is a summary of the state of the ledger that the
    --   consensus algorithm requires to do its job. Under certain
    --   circumstances the consensus algorithm may require the
    --   <a>LedgerView</a> for slots in the past (before the current tip of the
    --   chain) or in the (near) future (beyond the tip of the current chain,
    --   without having seen those future blocks yet).
    --   
    --   This puts limitations on what the <a>LedgerView</a> can be. For
    --   example, it cannot be the "current stake distribution", since it is of
    --   course impossible to compute the current stake distibution for a slot
    --   in the future. This means that for a consensus algorithm that requires
    --   the stake distribution such as Praos, the <a>LedgerView</a> for a
    --   particular slot must be the "stake distribution for the purpose of
    --   leader selection". This "relevant" stake distribution <i>can</i> be
    --   computed for slots in the (near) future because it is based on
    --   historical stake, not current.
    --   
    --   A somewhat unfortunate consequence of this is that some decisions that
    --   ought to live in the consensus layer (such as the decision precisely
    --   which historical stake to sample to determine the relevant stake
    --   distribution) instead live in the ledger layer. It is difficult to
    --   disentangle this, because the ledger may indeed <i>depend</i> on those
    --   sampling decisions (for example, reward calculations <i>must</i> be
    --   based on that same stake distribution).
    --   
    --   There are also some <i>advantages</i> to moving these sorts of
    --   decisions to the ledger layer. It means that the consensus algorithm
    --   can continue to function without modifications if we decide that the
    --   stake distribution for leader selection should be based on something
    --   else instead (for example, for some bespoke version of the blockchain
    --   we may wish to use a committee instead of a decentralized blockchain).
    --   Having sampling decisions in the ledger layer rather than the
    --   consensus layer means that these decisions can be made without
    --   modifying the consensus algorithm.
    --   
    --   Note that for the specific case of Praos, whilst the ledger layer
    --   provides the relevant stake distribution, the precise leader election
    --   must still live in the consensus layer since that depends on the
    --   computation (and sampling) of entropy, which is done consensus side,
    --   not ledger side (the reward calculation does not depend on this).
    type family LedgerView p :: Type;
    
    -- | Validation errors
    type family ValidationErr p :: Type;
    
    -- | View on a header required to validate it
    type family ValidateView p :: Type;
}

-- | <a>ConsensusConfig</a> must include the <a>ChainSelConfig</a> p
chainSelConfig :: ConsensusProtocol p => ConsensusConfig p -> ChainSelConfig p

-- | <a>ConsensusConfig</a> must include the <a>ChainSelConfig</a> p
chainSelConfig :: (ConsensusProtocol p, ChainSelConfig p ~ ()) => ConsensusConfig p -> ChainSelConfig p

-- | Check if a node is the leader
checkIsLeader :: (ConsensusProtocol p, HasCallStack) => ConsensusConfig p -> CanBeLeader p -> SlotNo -> Ticked (ChainDepState p) -> Maybe (IsLeader p)

-- | Tick the <a>ChainDepState</a>
--   
--   We pass the ticked <a>LedgerView</a> to <a>tickChainDepState</a>.
--   Functions that <i>take</i> a ticked <a>ChainDepState</a> are not
--   separately passed a ticked ledger view; protocols that require it, can
--   include it in their ticked <a>ChainDepState</a> type.
tickChainDepState :: ConsensusProtocol p => ConsensusConfig p -> Ticked (LedgerView p) -> SlotNo -> ChainDepState p -> Ticked (ChainDepState p)

-- | Apply a header
updateChainDepState :: (ConsensusProtocol p, HasCallStack) => ConsensusConfig p -> ValidateView p -> SlotNo -> Ticked (ChainDepState p) -> Except (ValidationErr p) (ChainDepState p)

-- | Re-apply a header to the same <a>ChainDepState</a> we have been able
--   to successfully apply to before.
--   
--   Since a header can only be applied to a single, specific,
--   <a>ChainDepState</a>, if we apply a previously applied header again it
--   will be applied in the very same <a>ChainDepState</a>, and therefore
--   can't possibly fail.
--   
--   It is worth noting that since we already know that the header is valid
--   w.r.t. the provided <a>ChainDepState</a>, no validation checks should
--   be performed.
reupdateChainDepState :: (ConsensusProtocol p, HasCallStack) => ConsensusConfig p -> ValidateView p -> SlotNo -> Ticked (ChainDepState p) -> ChainDepState p

-- | We require that protocols support a <tt>k</tt> security parameter
protocolSecurityParam :: ConsensusProtocol p => ConsensusConfig p -> SecurityParam

-- | Chain selection
class (NoThunks (ChainSelConfig p), Show (SelectView p), Show (ChainSelConfig p), Eq (ChainSelConfig p)) => ChainSelection p where {
    
    -- | Configuration required for chain selection
    type family ChainSelConfig p :: Type;
    
    -- | View on a header required for chain selection
    type family SelectView p :: Type;
    type ChainSelConfig p = ();
    type SelectView p = BlockNo;
}

-- | Do we prefer the candidate chain over ours?
--   
--   Should return <a>True</a> when we prefer the candidate over our chain.
--   
--   We pass only the tips of the chains; for all consensus protocols we
--   are interested in, this provides sufficient context. (Ouroboros
--   Genesis is the only exception, but we will handle the genesis rule
--   elsewhere.)
--   
--   PRECONDITIONS:
--   
--   <ul>
--   <li>The candidate chain does not extend into the future.</li>
--   <li>The candidate must intersect with our chain within <tt>k</tt>
--   blocks from our tip.</li>
--   </ul>
--   
--   NOTE: An assumption that is quite deeply ingrained in the design of
--   the consensus layer is that if a chain can be extended, it always
--   should (e.g., see the chain database spec in <tt>ChainDB.md</tt>).
--   This means that any chain is always preferred over the empty chain,
--   and <a>preferCandidate</a> does not need (indeed, cannot) be called if
--   our current chain is empty.
preferCandidate :: ChainSelection p => proxy p -> ChainSelConfig p -> SelectView p -> SelectView p -> Bool

-- | Compare two candidates, both of which we prefer to our own chain
--   
--   PRECONDITION: both candidates must be preferred to our own chain
compareCandidates :: ChainSelection p => proxy p -> ChainSelConfig p -> SelectView p -> SelectView p -> Ordering

-- | Compare two candidates, both of which we prefer to our own chain
--   
--   PRECONDITION: both candidates must be preferred to our own chain
compareCandidates :: (ChainSelection p, Ord (SelectView p)) => proxy p -> ChainSelConfig p -> SelectView p -> SelectView p -> Ordering

-- | Static configuration required to run the consensus protocol
--   
--   Every method in the <a>ConsensusProtocol</a> class takes the consensus
--   configuration as a parameter, so having this as a data family rather
--   than a type family resolves most ambiguity.
--   
--   Defined out of the class so that protocols can define this type
--   without having to define the entire protocol at the same time (or
--   indeed in the same module).
data family ConsensusConfig p :: Type

-- | Protocol security parameter
--   
--   We interpret this as the number of rollbacks we support.
--   
--   i.e., k == 0: we can't roll back at all k == 1: we can roll back at
--   most one block, etc
--   
--   NOTE: This talks about the number of <i>blocks</i> we can roll back,
--   not the number of <i>slots</i>.
newtype SecurityParam
SecurityParam :: Word64 -> SecurityParam
[maxRollbacks] :: SecurityParam -> Word64

module Ouroboros.Consensus.Protocol.ModChainSel
data ModChainSel p s

-- | Static configuration required to run the consensus protocol
--   
--   Every method in the <a>ConsensusProtocol</a> class takes the consensus
--   configuration as a parameter, so having this as a data family rather
--   than a type family resolves most ambiguity.
--   
--   Defined out of the class so that protocols can define this type
--   without having to define the entire protocol at the same time (or
--   indeed in the same module).
data family ConsensusConfig p :: Type
instance GHC.Generics.Generic (Ouroboros.Consensus.Protocol.Abstract.ConsensusConfig (Ouroboros.Consensus.Protocol.ModChainSel.ModChainSel p s))
instance Ouroboros.Consensus.Protocol.Abstract.ChainSelection s => Ouroboros.Consensus.Protocol.Abstract.ChainSelection (Ouroboros.Consensus.Protocol.ModChainSel.ModChainSel p s)
instance (Data.Typeable.Internal.Typeable p, Data.Typeable.Internal.Typeable s, Ouroboros.Consensus.Protocol.Abstract.ConsensusProtocol p, Ouroboros.Consensus.Protocol.Abstract.ChainSelection s) => Ouroboros.Consensus.Protocol.Abstract.ConsensusProtocol (Ouroboros.Consensus.Protocol.ModChainSel.ModChainSel p s)
instance (Ouroboros.Consensus.Protocol.Abstract.ConsensusProtocol p, Ouroboros.Consensus.Protocol.Abstract.ChainSelection s) => NoThunks.Class.NoThunks (Ouroboros.Consensus.Protocol.Abstract.ConsensusConfig (Ouroboros.Consensus.Protocol.ModChainSel.ModChainSel p s))

module Ouroboros.Consensus.Protocol.MockChainSel

-- | Chain selection between our chain and list of candidates
--   
--   This is only a <i>model</i> of chain selection: in reality of course
--   we will not work with entire chains in memory. This function is
--   intended as an explanation of how chain selection should work
--   conceptually.
--   
--   The <tt>l</tt> parameter here models the ledger state for each chain,
--   and serves as evidence that the chains we are selecting between have
--   been validated. (It would <i>not</i> be correct to run chain selection
--   on unvalidated chains and then somehow fail if the selected chain
--   turns out to be invalid.)
--   
--   Returns <a>Nothing</a> if we stick with our current chain.
selectChain :: forall proxy p hdr l. ChainSelection p => proxy p -> (hdr -> SelectView p) -> ChainSelConfig p -> Chain hdr -> [(Chain hdr, l)] -> Maybe (Chain hdr, l)

-- | Chain selection on unvalidated chains
selectUnvalidatedChain :: ChainSelection p => proxy p -> (hdr -> SelectView p) -> ChainSelConfig p -> Chain hdr -> [Chain hdr] -> Maybe (Chain hdr)


-- | Definition is <a>IsLedger</a>
--   
--   Normally this is imported from
--   <a>Ouroboros.Consensus.Ledger.Abstract</a>. We pull this out to avoid
--   circular module dependencies.
module Ouroboros.Consensus.Ledger.Basics
class GetTip l

-- | Point of the most recently applied block
--   
--   Should be <tt>genesisPoint</tt> when no blocks have been applied yet
getTip :: GetTip l => l -> Point l
getTipHash :: GetTip l => l -> ChainHash l
getTipSlot :: GetTip l => l -> WithOrigin SlotNo

-- | Static environment required for the ledger
type family LedgerCfg l :: Type
class (Show l, Eq l, NoThunks l, NoThunks (LedgerCfg l), Show (LedgerErr l), Eq (LedgerErr l), NoThunks (LedgerErr l), GetTip l, GetTip (Ticked l)) => IsLedger l where {
    
    -- | Errors that can arise when updating the ledger
    --   
    --   This is defined here rather than in <tt>ApplyBlock</tt>, since the
    --   <i>type</i> of these errors does not depend on the type of the block.
    type family LedgerErr l :: Type;
}

-- | Apply "slot based" state transformations
--   
--   When a block is applied to the ledger state, a number of things happen
--   purely based on the slot number of that block. For example:
--   
--   <ul>
--   <li>In Byron, scheduled updates are applied, and the update system
--   state is updated.</li>
--   <li>In Shelley, delegation state is updated (on epoch
--   boundaries).</li>
--   </ul>
--   
--   The consensus layer must be able to apply such a "chain tick"
--   function, primarily when validating transactions in the mempool
--   (which, conceptually, live in "some block in the future") or when
--   extracting valid transactions from the mempool to insert into a new
--   block to be produced.
--   
--   This is not allowed to throw any errors. After all, if this could
--   fail, it would mean a <i>previous</i> block set up the ledger state in
--   such a way that as soon as a certain slot was reached, <i>any</i>
--   block would be invalid.
--   
--   PRECONDITION: The slot number must be strictly greater than the slot
--   at the tip of the ledger (except for EBBs, obviously..).
--   
--   NOTE: <a>applyChainTick</a> should <i>not</i> change the tip of the
--   underlying ledger state, which should still refer to the most recent
--   applied <i>block</i>. In other words, we should have
--   
--   <pre>
--      ledgerTipPoint (applyChainTick cfg slot st)
--   == ledgerTipPoint st
--   </pre>
applyChainTick :: IsLedger l => LedgerCfg l -> SlotNo -> l -> Ticked l

-- | Ledger state associated with a block
data family LedgerState blk :: Type
type LedgerConfig blk = LedgerCfg (LedgerState blk)
type LedgerError blk = LedgerErr (LedgerState blk)
type TickedLedgerState blk = Ticked (LedgerState blk)


-- | Interface to the ledger layer
module Ouroboros.Consensus.Ledger.Abstract
class (IsLedger l, HeaderHash l ~ HeaderHash blk, HasHeader blk, HasHeader (Header blk)) => ApplyBlock l blk

-- | Apply a block to the ledger state.
--   
--   This is passed the ledger state ticked with the slot of the given
--   block, so <a>applyChainTick</a> has already been called.
applyLedgerBlock :: (ApplyBlock l blk, HasCallStack) => LedgerCfg l -> blk -> Ticked l -> Except (LedgerErr l) l

-- | Re-apply a block to the very same ledger state it was applied in
--   before.
--   
--   Since a block can only be applied to a single, specific, ledger state,
--   if we apply a previously applied block again it will be applied in the
--   very same ledger state, and therefore can't possibly fail.
--   
--   It is worth noting that since we already know that the block is valid
--   in the provided ledger state, the ledger layer should not perform
--   <i>any</i> validation checks.
reapplyLedgerBlock :: (ApplyBlock l blk, HasCallStack) => LedgerCfg l -> blk -> Ticked l -> l

-- | Interaction with the ledger layer
class ApplyBlock (LedgerState blk) blk => UpdateLedger blk
tickThenApply :: ApplyBlock l blk => LedgerCfg l -> blk -> l -> Except (LedgerErr l) l
tickThenReapply :: ApplyBlock l blk => LedgerCfg l -> blk -> l -> l
foldLedger :: ApplyBlock l blk => LedgerCfg l -> [blk] -> l -> Except (LedgerErr l) l
refoldLedger :: ApplyBlock l blk => LedgerCfg l -> [blk] -> l -> l
ledgerTipHash :: forall blk. UpdateLedger blk => LedgerState blk -> ChainHash blk

-- | Wrapper around <a>ledgerTipPoint</a> that uses a proxy to fix
--   <tt>blk</tt>
--   
--   This is occassionally useful to guide type inference
ledgerTipPoint :: UpdateLedger blk => Proxy blk -> LedgerState blk -> Point blk
ledgerTipSlot :: forall blk. UpdateLedger blk => LedgerState blk -> WithOrigin SlotNo

module Ouroboros.Consensus.Ledger.CommonProtocolParams

-- | Ask the ledger for common protocol parameters.
class UpdateLedger blk => CommonProtocolParams blk

-- | The maximum header size in bytes according to the currently adopted
--   protocol parameters of the ledger state.
maxHeaderSize :: CommonProtocolParams blk => LedgerState blk -> Word32

-- | The maximum transaction size in bytes according to the currently
--   adopted protocol parameters of the ledger state.
maxTxSize :: CommonProtocolParams blk => LedgerState blk -> Word32

module Ouroboros.Consensus.Config

-- | The top-level node configuration
data TopLevelConfig blk
TopLevelConfig :: !ConsensusConfig (BlockProtocol blk) -> !LedgerConfig blk -> !BlockConfig blk -> !CodecConfig blk -> !StorageConfig blk -> TopLevelConfig blk
[topLevelConfigProtocol] :: TopLevelConfig blk -> !ConsensusConfig (BlockProtocol blk)
[topLevelConfigLedger] :: TopLevelConfig blk -> !LedgerConfig blk
[topLevelConfigBlock] :: TopLevelConfig blk -> !BlockConfig blk
[topLevelConfigCodec] :: TopLevelConfig blk -> !CodecConfig blk
[topLevelConfigStorage] :: TopLevelConfig blk -> !StorageConfig blk
mkTopLevelConfig :: ConsensusConfig (BlockProtocol blk) -> LedgerConfig blk -> BlockConfig blk -> CodecConfig blk -> StorageConfig blk -> TopLevelConfig blk
castTopLevelConfig :: (Coercible (ConsensusConfig (BlockProtocol blk)) (ConsensusConfig (BlockProtocol blk')), LedgerConfig blk ~ LedgerConfig blk', Coercible (BlockConfig blk) (BlockConfig blk'), Coercible (CodecConfig blk) (CodecConfig blk'), Coercible (StorageConfig blk) (StorageConfig blk')) => TopLevelConfig blk -> TopLevelConfig blk'
configConsensus :: TopLevelConfig blk -> ConsensusConfig (BlockProtocol blk)
configLedger :: TopLevelConfig blk -> LedgerConfig blk
configBlock :: TopLevelConfig blk -> BlockConfig blk
configCodec :: TopLevelConfig blk -> CodecConfig blk
configStorage :: TopLevelConfig blk -> StorageConfig blk
configSecurityParam :: ConsensusProtocol (BlockProtocol blk) => TopLevelConfig blk -> SecurityParam
instance GHC.Generics.Generic (Ouroboros.Consensus.Config.TopLevelConfig blk)
instance (Ouroboros.Consensus.Protocol.Abstract.ConsensusProtocol (Ouroboros.Consensus.Block.Abstract.BlockProtocol blk), NoThunks.Class.NoThunks (Ouroboros.Consensus.Ledger.Basics.LedgerConfig blk), NoThunks.Class.NoThunks (Ouroboros.Consensus.Block.Abstract.BlockConfig blk), NoThunks.Class.NoThunks (Ouroboros.Consensus.Block.Abstract.CodecConfig blk), NoThunks.Class.NoThunks (Ouroboros.Consensus.Block.Abstract.StorageConfig blk)) => NoThunks.Class.NoThunks (Ouroboros.Consensus.Config.TopLevelConfig blk)

module Ouroboros.Consensus.Block.SupportsProtocol

-- | Evidence that a block supports its protocol
class (GetHeader blk, GetPrevHash blk, ConsensusProtocol (BlockProtocol blk), NoThunks (Header blk), NoThunks (BlockConfig blk), NoThunks (CodecConfig blk), NoThunks (StorageConfig blk)) => BlockSupportsProtocol blk
validateView :: BlockSupportsProtocol blk => BlockConfig blk -> Header blk -> ValidateView (BlockProtocol blk)
selectView :: BlockSupportsProtocol blk => BlockConfig blk -> Header blk -> SelectView (BlockProtocol blk)
selectView :: (BlockSupportsProtocol blk, SelectView (BlockProtocol blk) ~ BlockNo) => BlockConfig blk -> Header blk -> SelectView (BlockProtocol blk)

module Ouroboros.Consensus.Block.RealPoint

-- | Point of an actual block (i.e., not genesis)
data RealPoint blk
RealPoint :: !SlotNo -> !HeaderHash blk -> RealPoint blk
encodeRealPoint :: (HeaderHash blk -> Encoding) -> RealPoint blk -> Encoding
decodeRealPoint :: (forall s. Decoder s (HeaderHash blk)) -> forall s. Decoder s (RealPoint blk)
realPointSlot :: RealPoint blk -> SlotNo
realPointHash :: RealPoint blk -> HeaderHash blk
blockRealPoint :: HasHeader blk => blk -> RealPoint blk
headerRealPoint :: HasHeader (Header blk) => Header blk -> RealPoint blk
realPointToPoint :: RealPoint blk -> Point blk
withOriginRealPointToPoint :: WithOrigin (RealPoint blk) -> Point blk
pointToWithOriginRealPoint :: Point blk -> WithOrigin (RealPoint blk)
instance GHC.Generics.Generic (Ouroboros.Consensus.Block.RealPoint.RealPoint blk)
instance Ouroboros.Network.Block.StandardHash blk => GHC.Classes.Eq (Ouroboros.Consensus.Block.RealPoint.RealPoint blk)
instance Ouroboros.Network.Block.StandardHash blk => GHC.Classes.Ord (Ouroboros.Consensus.Block.RealPoint.RealPoint blk)
instance Ouroboros.Network.Block.StandardHash blk => GHC.Show.Show (Ouroboros.Consensus.Block.RealPoint.RealPoint blk)
instance (Ouroboros.Network.Block.StandardHash blk, Data.Typeable.Internal.Typeable blk) => NoThunks.Class.NoThunks (Ouroboros.Consensus.Block.RealPoint.RealPoint blk)
instance Ouroboros.Consensus.Util.Condense.Condense (Ouroboros.Network.Block.HeaderHash blk) => Ouroboros.Consensus.Util.Condense.Condense (Ouroboros.Consensus.Block.RealPoint.RealPoint blk)

module Ouroboros.Consensus.Util.MonadSTM.StrictMVar

-- | Strict MVar (modelled using a lazy <a>TMVar</a> under the hood)
--   
--   The <a>StrictMVar</a> API is slightly stronger than the usual
--   <tt>MVar</tt> one, as we offer a primitive to read the value of the
--   MVar even if it is empty (in which case we will return the oldest
--   known stale one). See <a>readMVarSTM</a>.
--   
--   There is a weaker invariant for a <a>StrictMVar</a> than for a
--   <tt>StrictTVar</tt>: although all functions that modify the
--   <a>StrictMVar</a> check the invariant, we do <i>not</i> guarantee that
--   the value inside the <a>StrictMVar</a> always satisfies the invariant.
--   Instead, we <i>do</i> guarantee that if the <a>StrictMVar</a> is
--   updated with a value that does not satisfy the invariant, an exception
--   is thrown. The reason for this weaker guarantee is that leaving an
--   <tt>MVar</tt> empty can lead to very hard to debug "blocked
--   indefinitely" problems.
--   
--   This is also the reason we do not offer support for an invariant in
--   <tt>StrictTMVar</tt>: if we throw an exception from an STM
--   transaction, the STM transaction is not executed, and so we would not
--   even be able to provide the weaker guarantee that we provide for
--   <a>StrictMVar</a>.
data StrictMVar m a
StrictMVar :: !a -> Maybe String -> !TMVar m a -> !TVar m a -> StrictMVar m a

-- | Invariant checked whenever updating the <a>StrictMVar</a>.
[invariant] :: StrictMVar m a -> !a -> Maybe String

-- | The main TMVar supporting this <a>StrictMVar</a>
[tmvar] :: StrictMVar m a -> !TMVar m a

-- | TVar for supporting <a>readMVarSTM</a>
--   
--   This TVar is always kept up to date with the <a>TMVar</a>, but holds
--   on the old value of the <a>TMVar</a> when it is empty. This is very
--   useful to support single writer/many reader scenarios.
--   
--   NOTE: We should always update the <a>tmvar</a> before the <a>tvar</a>
--   so that if the update to the <a>tmvar</a> fails, the 'tvar is left
--   unchanged.
[tvar] :: StrictMVar m a -> !TVar m a
castStrictMVar :: (TMVar m ~ TMVar n, TVar m ~ TVar n) => StrictMVar m a -> StrictMVar n a
newMVar :: MonadSTM m => a -> m (StrictMVar m a)
newMVarWithInvariant :: (MonadSTM m, HasCallStack) => (a -> Maybe String) -> a -> m (StrictMVar m a)
newEmptyMVar :: MonadSTM m => a -> m (StrictMVar m a)

-- | Create an initially empty <a>StrictMVar</a>
--   
--   NOTE: Since <a>readMVarSTM</a> allows to read the <a>StrictMVar</a>
--   even when it is empty, we need an initial value of <tt>a</tt> even
--   though the <a>StrictMVar</a> starts out empty. However, we are
--   <i>NOT</i> strict in this value, to allow it to be <tt>error</tt>.
newEmptyMVarWithInvariant :: MonadSTM m => (a -> Maybe String) -> a -> m (StrictMVar m a)
takeMVar :: MonadSTM m => StrictMVar m a -> m a
tryTakeMVar :: MonadSTM m => StrictMVar m a -> m (Maybe a)
putMVar :: (MonadSTM m, HasCallStack) => StrictMVar m a -> a -> m ()
tryPutMVar :: (MonadSTM m, HasCallStack) => StrictMVar m a -> a -> m Bool
readMVar :: MonadSTM m => StrictMVar m a -> m a

-- | Read the possibly-stale value of the <tt>MVar</tt>
--   
--   Will return the current value of the <tt>MVar</tt> if it non-empty, or
--   the last known value otherwise.
readMVarSTM :: MonadSTM m => StrictMVar m a -> STM m a
tryReadMVar :: MonadSTM m => StrictMVar m a -> m (Maybe a)

-- | Swap value of a <a>StrictMVar</a>
--   
--   NOTE: Since swapping the value can't leave the <a>StrictMVar</a>
--   empty, we <i>could</i> check the invariant first and only then swap.
--   We nonetheless swap first and check the invariant after to keep the
--   semantics the same with <a>putMVar</a>, otherwise it will be difficult
--   to understand when a <a>StrictMVar</a> is updated and when it is not.
swapMVar :: (MonadSTM m, HasCallStack) => StrictMVar m a -> a -> m a
isEmptyMVar :: MonadSTM m => StrictMVar m a -> m Bool
updateMVar :: (MonadSTM m, HasCallStack) => StrictMVar m a -> (a -> (a, b)) -> m b
updateMVar_ :: (MonadSTM m, HasCallStack) => StrictMVar m a -> (a -> a) -> m ()
modifyMVar :: (MonadSTM m, MonadCatch m, HasCallStack) => StrictMVar m a -> (a -> m (a, b)) -> m b
modifyMVar_ :: (MonadSTM m, MonadCatch m, HasCallStack) => StrictMVar m a -> (a -> m a) -> m ()
instance NoThunks.Class.NoThunks a => NoThunks.Class.NoThunks (Ouroboros.Consensus.Util.MonadSTM.StrictMVar.StrictMVar GHC.Types.IO a)

module Ouroboros.Consensus.Util.MonadSTM.NormalForm

-- | Check invariant (if enabled) before continuing
--   
--   <tt>checkInvariant mErr x</tt> is equal to <tt>x</tt> if <tt>mErr ==
--   Nothing</tt>, and throws an error <tt>err</tt> if <tt>mErr == Just
--   err</tt>.
--   
--   This is exported so that other code that wants to conditionally check
--   invariants can reuse the same logic, rather than having to introduce
--   new per-package flags.
checkInvariant :: HasCallStack => Maybe String -> a -> a
isEmptyTMVar :: forall (m :: Type -> Type) a. MonadSTM m => StrictTMVar m a -> STM m Bool
swapTMVar :: forall (m :: Type -> Type) a. MonadSTM m => StrictTMVar m a -> a -> STM m a
tryReadTMVar :: forall (m :: Type -> Type) a. MonadSTM m => StrictTMVar m a -> STM m (Maybe a)
readTMVar :: forall (m :: Type -> Type) a. MonadSTM m => StrictTMVar m a -> STM m a
tryPutTMVar :: forall (m :: Type -> Type) a. MonadSTM m => StrictTMVar m a -> a -> STM m Bool
putTMVar :: forall (m :: Type -> Type) a. MonadSTM m => StrictTMVar m a -> a -> STM m ()
tryTakeTMVar :: forall (m :: Type -> Type) a. MonadSTM m => StrictTMVar m a -> STM m (Maybe a)
takeTMVar :: forall (m :: Type -> Type) a. MonadSTM m => StrictTMVar m a -> STM m a
newEmptyTMVarM :: MonadSTM m => m (StrictTMVar m a)
newEmptyTMVar :: forall (m :: Type -> Type) a. MonadSTM m => STM m (StrictTMVar m a)
newTMVarM :: MonadSTM m => a -> m (StrictTMVar m a)
castStrictTMVar :: forall (m :: Type -> Type) (n :: Type -> Type) a. LazyTMVar m ~ LazyTMVar n => StrictTMVar m a -> StrictTMVar n a
updateTVar :: forall (m :: Type -> Type) a b. MonadSTM m => StrictTVar m a -> (a -> (a, b)) -> STM m b
stateTVar :: forall (m :: Type -> Type) a b. MonadSTM m => StrictTVar m a -> (a -> (a, b)) -> STM m b
modifyTVar :: forall (m :: Type -> Type) a. MonadSTM m => StrictTVar m a -> (a -> a) -> STM m ()
writeTVar :: forall (m :: Type -> Type) a. (MonadSTM m, HasCallStack) => StrictTVar m a -> a -> STM m ()
readTVar :: forall (m :: Type -> Type) a. MonadSTM m => StrictTVar m a -> STM m a
newTVarWithInvariantM :: (MonadSTM m, HasCallStack) => (a -> Maybe String) -> a -> m (StrictTVar m a)
newTVarM :: MonadSTM m => a -> m (StrictTVar m a)

-- | Get the underlying <tt>TVar</tt>
--   
--   Since we obviously cannot guarantee that updates to this
--   <a>LazyTVar</a> will be strict, this should be used with caution.
toLazyTVar :: forall (m :: Type -> Type) a. StrictTVar m a -> LazyTVar m a
castStrictTVar :: forall (m :: Type -> Type) (n :: Type -> Type) a. LazyTVar m ~ LazyTVar n => StrictTVar m a -> StrictTVar n a
type LazyTVar (m :: Type -> Type) = TVar m
type LazyTMVar (m :: Type -> Type) = TMVar m
data StrictTVar (m :: Type -> Type) a
data StrictTMVar (m :: Type -> Type) a

-- | <a>catch</a> speclialized for an <tt>stm</tt> monad.
catchSTM :: (MonadSTMTx stm, MonadCatch stm, Exception e) => stm a -> (e -> stm a) -> stm a

-- | <a>throwIO</a> specialised to <tt>stm</tt> monad.
throwSTM :: (MonadSTMTx stm, MonadThrow stm, Exception e) => e -> stm a
flushTBQueueDefault :: forall (m :: Type -> Type) a. MonadSTM m => TBQueueDefault m a -> STM m [a]
lengthTBQueueDefault :: forall (m :: Type -> Type) a. MonadSTM m => TBQueueDefault m a -> STM m Natural
isFullTBQueueDefault :: forall (m :: Type -> Type) a. MonadSTM m => TBQueueDefault m a -> STM m Bool
isEmptyTBQueueDefault :: forall (m :: Type -> Type) a. MonadSTM m => TBQueueDefault m a -> STM m Bool
writeTBQueueDefault :: forall (m :: Type -> Type) a. MonadSTM m => TBQueueDefault m a -> a -> STM m ()
tryReadTBQueueDefault :: forall (m :: Type -> Type) a. MonadSTMTx (STM m) => TBQueueDefault m a -> STM m (Maybe a)
readTBQueueDefault :: forall (m :: Type -> Type) a. MonadSTM m => TBQueueDefault m a -> STM m a
newTBQueueDefault :: forall (m :: Type -> Type) a. MonadSTM m => Natural -> STM m (TBQueueDefault m a)
isEmptyTQueueDefault :: forall (m :: Type -> Type) a. MonadSTMTx (STM m) => TQueueDefault m a -> STM m Bool
tryReadTQueueDefault :: forall (m :: Type -> Type) a. MonadSTMTx (STM m) => TQueueDefault m a -> STM m (Maybe a)
readTQueueDefault :: forall (m :: Type -> Type) a. MonadSTM m => TQueueDefault m a -> STM m a
writeTQueueDefault :: forall (m :: Type -> Type) a. MonadSTM m => TQueueDefault m a -> a -> STM m ()
newTQueueDefault :: forall (m :: Type -> Type) a. MonadSTM m => STM m (TQueueDefault m a)
isEmptyTMVarDefault :: forall (m :: Type -> Type) a. MonadSTM m => TMVarDefault m a -> STM m Bool
swapTMVarDefault :: forall (m :: Type -> Type) a. MonadSTM m => TMVarDefault m a -> a -> STM m a
tryReadTMVarDefault :: forall (m :: Type -> Type) a. MonadSTM m => TMVarDefault m a -> STM m (Maybe a)
readTMVarDefault :: forall (m :: Type -> Type) a. MonadSTM m => TMVarDefault m a -> STM m a
tryPutTMVarDefault :: forall (m :: Type -> Type) a. MonadSTM m => TMVarDefault m a -> a -> STM m Bool
putTMVarDefault :: forall (m :: Type -> Type) a. MonadSTM m => TMVarDefault m a -> a -> STM m ()
tryTakeTMVarDefault :: forall (m :: Type -> Type) a. MonadSTM m => TMVarDefault m a -> STM m (Maybe a)
takeTMVarDefault :: forall (m :: Type -> Type) a. MonadSTM m => TMVarDefault m a -> STM m a
newEmptyTMVarMDefault :: MonadSTM m => m (TMVarDefault m a)
newEmptyTMVarIODefault :: MonadSTM m => m (TMVarDefault m a)
newEmptyTMVarDefault :: forall (m :: Type -> Type) a. MonadSTM m => STM m (TMVarDefault m a)
newTMVarMDefault :: MonadSTM m => a -> m (TMVarDefault m a)
newTMVarIODefault :: MonadSTM m => a -> m (TMVarDefault m a)
newTMVarDefault :: forall (m :: Type -> Type) a. MonadSTM m => a -> STM m (TMVarDefault m a)
type family TBQueue_ (stm :: Type -> Type) :: Type -> Type
type family TQueue_ (stm :: Type -> Type) :: Type -> Type
type family TMVar_ (stm :: Type -> Type) :: Type -> Type
type family TVar_ (stm :: Type -> Type) :: Type -> Type
class (Monad stm, Alternative stm, MonadPlus stm) => MonadSTMTx (stm :: Type -> Type) where {
    type family TVar_ (stm :: Type -> Type) :: Type -> Type;
    type family TMVar_ (stm :: Type -> Type) :: Type -> Type;
    type family TQueue_ (stm :: Type -> Type) :: Type -> Type;
    type family TBQueue_ (stm :: Type -> Type) :: Type -> Type;
}
retry :: MonadSTMTx stm => stm a
orElse :: MonadSTMTx stm => stm a -> stm a -> stm a
modifyTVar' :: MonadSTMTx stm => TVar_ stm a -> (a -> a) -> stm ()
check :: MonadSTMTx stm => Bool -> stm ()
newTQueue :: MonadSTMTx stm => stm (TQueue_ stm a)
readTQueue :: MonadSTMTx stm => TQueue_ stm a -> stm a
tryReadTQueue :: MonadSTMTx stm => TQueue_ stm a -> stm (Maybe a)
writeTQueue :: MonadSTMTx stm => TQueue_ stm a -> a -> stm ()
isEmptyTQueue :: MonadSTMTx stm => TQueue_ stm a -> stm Bool
newTBQueue :: MonadSTMTx stm => Natural -> stm (TBQueue_ stm a)
readTBQueue :: MonadSTMTx stm => TBQueue_ stm a -> stm a
tryReadTBQueue :: MonadSTMTx stm => TBQueue_ stm a -> stm (Maybe a)
flushTBQueue :: MonadSTMTx stm => TBQueue_ stm a -> stm [a]
writeTBQueue :: MonadSTMTx stm => TBQueue_ stm a -> a -> stm ()

lengthTBQueue :: MonadSTMTx stm => TBQueue_ stm a -> stm Natural
isEmptyTBQueue :: MonadSTMTx stm => TBQueue_ stm a -> stm Bool
isFullTBQueue :: MonadSTMTx stm => TBQueue_ stm a -> stm Bool
type TQueue (m :: Type -> Type) = TQueue_ STM m
type TBQueue (m :: Type -> Type) = TBQueue_ STM m
type family STM (m :: Type -> Type) :: Type -> Type
class (Monad m, MonadSTMTx STM m) => MonadSTM (m :: Type -> Type) where {
    type family STM (m :: Type -> Type) :: Type -> Type;
}
atomically :: (MonadSTM m, HasCallStack) => STM m a -> m a
newTBQueueIO :: MonadSTM m => Natural -> m (TBQueue m a)
data TMVarDefault (m :: Type -> Type) a
data TQueueDefault (m :: Type -> Type) a
TQueue :: !TVar m [a] -> !TVar m [a] -> TQueueDefault (m :: Type -> Type) a
data TBQueueDefault (m :: Type -> Type) a
TBQueue :: !TVar m Natural -> !TVar m [a] -> !TVar m Natural -> !TVar m [a] -> !Natural -> TBQueueDefault (m :: Type -> Type) a

-- | Strict MVar (modelled using a lazy <a>TMVar</a> under the hood)
--   
--   The <a>StrictMVar</a> API is slightly stronger than the usual
--   <tt>MVar</tt> one, as we offer a primitive to read the value of the
--   MVar even if it is empty (in which case we will return the oldest
--   known stale one). See <a>readMVarSTM</a>.
--   
--   There is a weaker invariant for a <a>StrictMVar</a> than for a
--   <tt>StrictTVar</tt>: although all functions that modify the
--   <a>StrictMVar</a> check the invariant, we do <i>not</i> guarantee that
--   the value inside the <a>StrictMVar</a> always satisfies the invariant.
--   Instead, we <i>do</i> guarantee that if the <a>StrictMVar</a> is
--   updated with a value that does not satisfy the invariant, an exception
--   is thrown. The reason for this weaker guarantee is that leaving an
--   <tt>MVar</tt> empty can lead to very hard to debug "blocked
--   indefinitely" problems.
--   
--   This is also the reason we do not offer support for an invariant in
--   <tt>StrictTMVar</tt>: if we throw an exception from an STM
--   transaction, the STM transaction is not executed, and so we would not
--   even be able to provide the weaker guarantee that we provide for
--   <a>StrictMVar</a>.
data StrictMVar m a
StrictMVar :: !a -> Maybe String -> !TMVar m a -> !TVar m a -> StrictMVar m a

-- | Invariant checked whenever updating the <a>StrictMVar</a>.
[invariant] :: StrictMVar m a -> !a -> Maybe String

-- | The main TMVar supporting this <a>StrictMVar</a>
[tmvar] :: StrictMVar m a -> !TMVar m a

-- | TVar for supporting <a>readMVarSTM</a>
--   
--   This TVar is always kept up to date with the <a>TMVar</a>, but holds
--   on the old value of the <a>TMVar</a> when it is empty. This is very
--   useful to support single writer/many reader scenarios.
--   
--   NOTE: We should always update the <a>tmvar</a> before the <a>tvar</a>
--   so that if the update to the <a>tmvar</a> fails, the 'tvar is left
--   unchanged.
[tvar] :: StrictMVar m a -> !TVar m a
castStrictMVar :: (TMVar m ~ TMVar n, TVar m ~ TVar n) => StrictMVar m a -> StrictMVar n a
takeMVar :: MonadSTM m => StrictMVar m a -> m a
tryTakeMVar :: MonadSTM m => StrictMVar m a -> m (Maybe a)
putMVar :: (MonadSTM m, HasCallStack) => StrictMVar m a -> a -> m ()
tryPutMVar :: (MonadSTM m, HasCallStack) => StrictMVar m a -> a -> m Bool
readMVar :: MonadSTM m => StrictMVar m a -> m a
tryReadMVar :: MonadSTM m => StrictMVar m a -> m (Maybe a)

-- | Read the possibly-stale value of the <tt>MVar</tt>
--   
--   Will return the current value of the <tt>MVar</tt> if it non-empty, or
--   the last known value otherwise.
readMVarSTM :: MonadSTM m => StrictMVar m a -> STM m a

-- | Swap value of a <a>StrictMVar</a>
--   
--   NOTE: Since swapping the value can't leave the <a>StrictMVar</a>
--   empty, we <i>could</i> check the invariant first and only then swap.
--   We nonetheless swap first and check the invariant after to keep the
--   semantics the same with <a>putMVar</a>, otherwise it will be difficult
--   to understand when a <a>StrictMVar</a> is updated and when it is not.
swapMVar :: (MonadSTM m, HasCallStack) => StrictMVar m a -> a -> m a
isEmptyMVar :: MonadSTM m => StrictMVar m a -> m Bool
updateMVar :: (MonadSTM m, HasCallStack) => StrictMVar m a -> (a -> (a, b)) -> m b
updateMVar_ :: (MonadSTM m, HasCallStack) => StrictMVar m a -> (a -> a) -> m ()
modifyMVar :: (MonadSTM m, MonadCatch m, HasCallStack) => StrictMVar m a -> (a -> m (a, b)) -> m b
modifyMVar_ :: (MonadSTM m, MonadCatch m, HasCallStack) => StrictMVar m a -> (a -> m a) -> m ()
newTVarIO :: (MonadSTM m, HasCallStack, NoThunks a) => a -> m (StrictTVar m a)
newMVar :: (MonadSTM m, HasCallStack, NoThunks a) => a -> m (StrictMVar m a)
newEmptyMVar :: (MonadSTM m, NoThunks a) => a -> m (StrictMVar m a)
uncheckedNewTVarM :: MonadSTM m => a -> m (StrictTVar m a)
uncheckedNewMVar :: MonadSTM m => a -> m (StrictMVar m a)
uncheckedNewEmptyMVar :: MonadSTM m => a -> m (StrictMVar m a)

module Ouroboros.Consensus.Util.Orphans
instance NoThunks.Class.NoThunks (Codec.CBOR.Decoding.Decoder s a)
instance NoThunks.Class.NoThunks (Control.Tracer.Tracer m ev)
instance NoThunks.Class.NoThunks Control.Monad.Class.MonadTime.Time
instance NoThunks.Class.NoThunks Data.Void.Void
instance Ouroboros.Consensus.Util.Condense.Condense (Ouroboros.Network.Block.HeaderHash block) => Ouroboros.Consensus.Util.Condense.Condense (Ouroboros.Network.Block.Point block)
instance Ouroboros.Consensus.Util.Condense.Condense block => Ouroboros.Consensus.Util.Condense.Condense (Ouroboros.Network.MockChain.Chain.Chain block)
instance (Ouroboros.Consensus.Util.Condense.Condense block, Ouroboros.Network.Block.HasHeader block, Ouroboros.Consensus.Util.Condense.Condense (Ouroboros.Network.Block.HeaderHash block)) => Ouroboros.Consensus.Util.Condense.Condense (Ouroboros.Network.AnchoredFragment.AnchoredFragment block)
instance Codec.Serialise.Class.Serialise (Cardano.Crypto.Hash.Class.Hash h a)
instance Codec.Serialise.Class.Serialise (Cardano.Crypto.DSIGN.Class.VerKeyDSIGN Cardano.Crypto.DSIGN.Mock.MockDSIGN)
instance NoThunks.Class.NoThunks a => NoThunks.Class.NoThunks (Control.Monad.Class.MonadSTM.Strict.StrictTVar GHC.Types.IO a)
instance (NoThunks.Class.NoThunks k, NoThunks.Class.NoThunks v) => NoThunks.Class.NoThunks (Data.Bimap.Bimap k v)
instance (NoThunks.Class.NoThunks p, NoThunks.Class.NoThunks v, GHC.Classes.Ord p) => NoThunks.Class.NoThunks (Data.IntPSQ.Internal.IntPSQ p v)
instance NoThunks.Class.NoThunks a => NoThunks.Class.NoThunks (Data.SOP.BasicFunctors.K a b)

module Ouroboros.Consensus.Util.IOLike
class (MonadAsync m, MonadEventlog m, MonadFork m, MonadST m, MonadDelay m, MonadThread m, MonadThrow m, MonadCatch m, MonadMask m, MonadMonotonicTime m, MonadEvaluate m, MonadThrow (STM m), forall a. NoThunks (m a), forall a. NoThunks a => NoThunks (StrictTVar m a), forall a. NoThunks a => NoThunks (StrictMVar m a)) => IOLike m

-- | Securely forget a KES signing key.
--   
--   No-op for the IOSim, but <a>forgetSignKeyKES</a> for IO.
forgetSignKeyKES :: (IOLike m, KESAlgorithm v) => SignKeyKES v -> m ()

-- | Throwing exceptions, and resource handling in the presence of
--   exceptions.
--   
--   Does not include the ability to respond to exceptions.
class Monad m => MonadThrow (m :: Type -> Type)
throwIO :: (MonadThrow m, Exception e) => e -> m a
bracket :: MonadThrow m => m a -> (a -> m b) -> (a -> m c) -> m c
bracket_ :: MonadThrow m => m a -> m b -> m c -> m c
finally :: MonadThrow m => m a -> m b -> m a

-- | Catching exceptions.
--   
--   Covers standard utilities to respond to exceptions.
class MonadThrow m => MonadCatch (m :: Type -> Type)
catch :: (MonadCatch m, Exception e) => m a -> (e -> m a) -> m a
catchJust :: (MonadCatch m, Exception e) => (e -> Maybe b) -> m a -> (b -> m a) -> m a
try :: (MonadCatch m, Exception e) => m a -> m (Either e a)
tryJust :: (MonadCatch m, Exception e) => (e -> Maybe b) -> m a -> m (Either b a)
handle :: (MonadCatch m, Exception e) => (e -> m a) -> m a -> m a
handleJust :: (MonadCatch m, Exception e) => (e -> Maybe b) -> (b -> m a) -> m a -> m a
onException :: MonadCatch m => m a -> m b -> m a
bracketOnError :: MonadCatch m => m a -> (a -> m b) -> (a -> m c) -> m c

-- | General form of bracket
--   
--   See
--   <a>http://hackage.haskell.org/package/exceptions-0.10.0/docs/Control-Monad-Catch.html#v:generalBracket</a>
--   for discussion and motivation.
generalBracket :: MonadCatch m => m a -> (a -> ExitCase b -> m c) -> (a -> m b) -> m (b, c)

-- | Support for safely working in the presence of asynchronous exceptions.
--   
--   This is typically not needed directly as the utilities in
--   <a>MonadThrow</a> and <a>MonadCatch</a> cover most use cases.
class MonadCatch m => MonadMask (m :: Type -> Type)
mask :: MonadMask m => ((forall a. () => m a -> m a) -> m b) -> m b
uninterruptibleMask :: MonadMask m => ((forall a. () => m a -> m a) -> m b) -> m b
mask_ :: MonadMask m => m a -> m a
uninterruptibleMask_ :: MonadMask m => m a -> m a

-- | Any type that you wish to throw or catch as an exception must be an
--   instance of the <tt>Exception</tt> class. The simplest case is a new
--   exception type directly below the root:
--   
--   <pre>
--   data MyException = ThisException | ThatException
--       deriving Show
--   
--   instance Exception MyException
--   </pre>
--   
--   The default method definitions in the <tt>Exception</tt> class do what
--   we need in this case. You can now throw and catch
--   <tt>ThisException</tt> and <tt>ThatException</tt> as exceptions:
--   
--   <pre>
--   *Main&gt; throw ThisException `catch` \e -&gt; putStrLn ("Caught " ++ show (e :: MyException))
--   Caught ThisException
--   </pre>
--   
--   In more complicated examples, you may wish to define a whole hierarchy
--   of exceptions:
--   
--   <pre>
--   ---------------------------------------------------------------------
--   -- Make the root exception type for all the exceptions in a compiler
--   
--   data SomeCompilerException = forall e . Exception e =&gt; SomeCompilerException e
--   
--   instance Show SomeCompilerException where
--       show (SomeCompilerException e) = show e
--   
--   instance Exception SomeCompilerException
--   
--   compilerExceptionToException :: Exception e =&gt; e -&gt; SomeException
--   compilerExceptionToException = toException . SomeCompilerException
--   
--   compilerExceptionFromException :: Exception e =&gt; SomeException -&gt; Maybe e
--   compilerExceptionFromException x = do
--       SomeCompilerException a &lt;- fromException x
--       cast a
--   
--   ---------------------------------------------------------------------
--   -- Make a subhierarchy for exceptions in the frontend of the compiler
--   
--   data SomeFrontendException = forall e . Exception e =&gt; SomeFrontendException e
--   
--   instance Show SomeFrontendException where
--       show (SomeFrontendException e) = show e
--   
--   instance Exception SomeFrontendException where
--       toException = compilerExceptionToException
--       fromException = compilerExceptionFromException
--   
--   frontendExceptionToException :: Exception e =&gt; e -&gt; SomeException
--   frontendExceptionToException = toException . SomeFrontendException
--   
--   frontendExceptionFromException :: Exception e =&gt; SomeException -&gt; Maybe e
--   frontendExceptionFromException x = do
--       SomeFrontendException a &lt;- fromException x
--       cast a
--   
--   ---------------------------------------------------------------------
--   -- Make an exception type for a particular frontend compiler exception
--   
--   data MismatchedParentheses = MismatchedParentheses
--       deriving Show
--   
--   instance Exception MismatchedParentheses where
--       toException   = frontendExceptionToException
--       fromException = frontendExceptionFromException
--   </pre>
--   
--   We can now catch a <tt>MismatchedParentheses</tt> exception as
--   <tt>MismatchedParentheses</tt>, <tt>SomeFrontendException</tt> or
--   <tt>SomeCompilerException</tt>, but not other types, e.g.
--   <tt>IOException</tt>:
--   
--   <pre>
--   *Main&gt; throw MismatchedParentheses `catch` \e -&gt; putStrLn ("Caught " ++ show (e :: MismatchedParentheses))
--   Caught MismatchedParentheses
--   *Main&gt; throw MismatchedParentheses `catch` \e -&gt; putStrLn ("Caught " ++ show (e :: SomeFrontendException))
--   Caught MismatchedParentheses
--   *Main&gt; throw MismatchedParentheses `catch` \e -&gt; putStrLn ("Caught " ++ show (e :: SomeCompilerException))
--   Caught MismatchedParentheses
--   *Main&gt; throw MismatchedParentheses `catch` \e -&gt; putStrLn ("Caught " ++ show (e :: IOException))
--   *** Exception: MismatchedParentheses
--   </pre>
class (Typeable e, Show e) => Exception e
toException :: Exception e => e -> SomeException
fromException :: Exception e => SomeException -> Maybe e

-- | Render this exception value in a human-friendly manner.
--   
--   Default implementation: <tt><a>show</a></tt>.
displayException :: Exception e => e -> String

-- | The <tt>SomeException</tt> type is the root of the exception type
--   hierarchy. When an exception of type <tt>e</tt> is thrown, behind the
--   scenes it is encapsulated in a <tt>SomeException</tt>.
data SomeException

-- | Used in <a>generalBracket</a>
--   
--   See <tt>exceptions</tt> package for discussion and motivation.
data ExitCase a
ExitCaseSuccess :: a -> ExitCase a
ExitCaseException :: SomeException -> ExitCase a
ExitCaseAbort :: ExitCase a
class MonadThread m => MonadFork (m :: Type -> Type)
forkIO :: MonadFork m => m () -> m (ThreadId m)
forkIOWithUnmask :: MonadFork m => ((forall a. () => m a -> m a) -> m ()) -> m (ThreadId m)
throwTo :: (MonadFork m, Exception e) => ThreadId m -> e -> m ()
killThread :: MonadFork m => ThreadId m -> m ()

-- | Apply the label to the current thread
labelThisThread :: MonadThread m => String -> m ()
class (Monad m, Eq ThreadId m, Ord ThreadId m, Show ThreadId m) => MonadThread (m :: Type -> Type) where {
    type family ThreadId (m :: Type -> Type);
}
myThreadId :: MonadThread m => m (ThreadId m)
labelThread :: MonadThread m => ThreadId m -> String -> m ()
class (Functor async, MonadSTMTx stm) => MonadAsyncSTM (async :: Type -> Type) (stm :: Type -> Type)
waitSTM :: MonadAsyncSTM async stm => async a -> stm a
pollSTM :: MonadAsyncSTM async stm => async a -> stm (Maybe (Either SomeException a))
waitCatchSTM :: MonadAsyncSTM async stm => async a -> stm (Either SomeException a)
waitAnySTM :: MonadAsyncSTM async stm => [async a] -> stm (async a, a)
waitAnyCatchSTM :: MonadAsyncSTM async stm => [async a] -> stm (async a, Either SomeException a)
waitEitherSTM :: MonadAsyncSTM async stm => async a -> async b -> stm (Either a b)
waitEitherSTM_ :: MonadAsyncSTM async stm => async a -> async b -> stm ()
waitEitherCatchSTM :: MonadAsyncSTM async stm => async a -> async b -> stm (Either (Either SomeException a) (Either SomeException b))
waitBothSTM :: MonadAsyncSTM async stm => async a -> async b -> stm (a, b)
class (MonadSTM m, MonadThread m, MonadAsyncSTM Async m STM m) => MonadAsync (m :: Type -> Type) where {
    
    -- | An asynchronous action
    type family Async (m :: Type -> Type) :: Type -> Type;
}
async :: MonadAsync m => m a -> m (Async m a)
asyncThreadId :: MonadAsync m => Proxy m -> Async m a -> ThreadId m
withAsync :: MonadAsync m => m a -> (Async m a -> m b) -> m b
wait :: MonadAsync m => Async m a -> m a
poll :: MonadAsync m => Async m a -> m (Maybe (Either SomeException a))
waitCatch :: MonadAsync m => Async m a -> m (Either SomeException a)
cancel :: MonadAsync m => Async m a -> m ()
cancelWith :: (MonadAsync m, Exception e) => Async m a -> e -> m ()
uninterruptibleCancel :: MonadAsync m => Async m a -> m ()
waitAny :: MonadAsync m => [Async m a] -> m (Async m a, a)
waitAnyCatch :: MonadAsync m => [Async m a] -> m (Async m a, Either SomeException a)
waitAnyCancel :: MonadAsync m => [Async m a] -> m (Async m a, a)
waitAnyCatchCancel :: MonadAsync m => [Async m a] -> m (Async m a, Either SomeException a)
waitEither :: MonadAsync m => Async m a -> Async m b -> m (Either a b)

-- | Note, IO-based implementations should override the default
--   implementation. See the <tt>async</tt> package implementation and
--   comments.
--   <a>http://hackage.haskell.org/package/async-2.2.1/docs/src/Control.Concurrent.Async.html#waitEitherCatch</a>
waitEitherCatch :: MonadAsync m => Async m a -> Async m b -> m (Either (Either SomeException a) (Either SomeException b))
waitEitherCancel :: MonadAsync m => Async m a -> Async m b -> m (Either a b)
waitEitherCatchCancel :: MonadAsync m => Async m a -> Async m b -> m (Either (Either SomeException a) (Either SomeException b))
waitEither_ :: MonadAsync m => Async m a -> Async m b -> m ()
waitBoth :: MonadAsync m => Async m a -> Async m b -> m (a, b)
race :: MonadAsync m => m a -> m b -> m (Either a b)
race_ :: MonadAsync m => m a -> m b -> m ()
concurrently :: MonadAsync m => m a -> m b -> m (a, b)
concurrently_ :: MonadAsync m => m a -> m b -> m ()
asyncWithUnmask :: MonadAsync m => ((forall b. () => m b -> m b) -> m a) -> m (Async m a)

-- | Exception from child thread re-raised in parent thread
--   
--   We record the thread ID of the child thread as a <a>String</a>. This
--   avoids an <tt>m</tt> parameter in the type, which is important:
--   <a>ExceptionInLinkedThread</a> must be an instance of
--   <a>Exception</a>, requiring it to be <tt>Typeable</tt>; if <tt>m</tt>
--   appeared in the type, we would require <tt>m</tt> to be
--   <tt>Typeable</tt>, which does not work with with the simulator, as it
--   would require a <tt>Typeable</tt> constraint on the <tt>s</tt>
--   parameter of <tt>IOSim</tt>.
data ExceptionInLinkedThread
ExceptionInLinkedThread :: String -> SomeException -> ExceptionInLinkedThread
link :: (MonadAsync m, MonadFork m, MonadMask m) => Async m a -> m ()

-- | Generalizion of <a>link</a> that links an async to an arbitrary
--   thread.
linkTo :: (MonadAsync m, MonadFork m, MonadMask m) => ThreadId m -> Async m a -> m ()

-- | This class is for abstracting over <a>stToIO</a> which allows running
--   <a>ST</a> actions in <a>IO</a>. In this case it is to allow running
--   <a>ST</a> actions within another monad <tt>m</tt>.
--   
--   The type of <a>stToIO</a> is:
--   
--   <pre>
--   stToIO : ST RealWorld a -&gt; IO a
--   </pre>
--   
--   Abstracting over this is tricky because we need to not care about both
--   the <tt>IO</tt>, and also the <tt>RealWorld</tt>.
--   
--   A solution is to write an action that is given the <tt>liftST</tt> as
--   an argument and where that action itself is polymorphic in the
--   <tt>s</tt> parameter. This allows us to instantiate it with
--   <tt>RealWorld</tt> in the <tt>IO</tt> case, and the local <tt>s</tt>
--   in a case where we are embedding into another <tt>ST</tt> action.
class Monad m => MonadST (m :: Type -> Type)
withLiftST :: MonadST m => (forall s. () => (forall a. () => ST s a -> m a) -> b) -> b
class Monad m => MonadMonotonicTime (m :: Type -> Type)

-- | Time in a monotonic clock, with high precision. The epoch for this
--   clock is arbitrary and does not correspond to any wall clock or
--   calendar.
getMonotonicTime :: MonadMonotonicTime m => m Time

-- | A point in time in a monotonic clock.
--   
--   The epoch for this clock is arbitrary and does not correspond to any
--   wall clock or calendar, and is <i>not guaranteed</i> to be the same
--   epoch across program runs. It is represented as the <a>DiffTime</a>
--   from this arbitrary epoch.
newtype Time
Time :: DiffTime -> Time

-- | This is a length of time, as measured by a clock. Conversion functions
--   will treat it as seconds. It has a precision of 10^-12 s.
data DiffTime

-- | Add a duration to a point in time, giving another time.
addTime :: DiffTime -> Time -> Time

-- | The time duration between two points in time (positive or negative).
diffTime :: Time -> Time -> DiffTime
class Monad m => MonadDelay (m :: Type -> Type)
threadDelay :: MonadDelay m => DiffTime -> m ()
class Monad m => MonadEventlog (m :: Type -> Type)

-- | Emits a message to the eventlog, if eventlog profiling is available
--   and enabled at runtime.
traceEventIO :: MonadEventlog m => String -> m ()

-- | Emits a marker to the eventlog, if eventlog profiling is available and
--   enabled at runtime.
--   
--   The <a>String</a> is the name of the marker. The name is just used in
--   the profiling tools to help you keep clear which marker is which.
traceMarkerIO :: MonadEventlog m => String -> m ()

-- | Monads which can <a>evaluate</a>.
class MonadThrow m => MonadEvaluate (m :: Type -> Type)
evaluate :: MonadEvaluate m => a -> m a

-- | Check a value for unexpected thunks
class NoThunks a

-- | Check if the argument does not contain any unexpected thunks
--   
--   For most datatypes, we should have that
--   
--   <pre>
--   noThunks ctxt x == Nothing
--   </pre>
--   
--   if and only if
--   
--   <pre>
--   checkContainsThunks x
--   </pre>
--   
--   For some datatypes however, some thunks are expected. For example, the
--   internal fingertree <a>Sequence</a> might contain thunks (this is
--   important for the asymptotic complexity of this data structure).
--   However, we should still check that the <i>values</i> in the sequence
--   don't contain any unexpected thunks.
--   
--   This means that we need to traverse the sequence, which might force
--   some of the thunks in the tree. In general, it is acceptable for
--   <a>noThunks</a> to force such "expected thunks", as long as it always
--   reports the <i>unexpected</i> thunks.
--   
--   The default implementation of <a>noThunks</a> checks that the argument
--   is in WHNF, and if so, adds the type into the context (using
--   <a>showTypeOf</a>), and calls <a>wNoThunks</a>. See <a>ThunkInfo</a>
--   for a detailed discussion of the type context.
--   
--   See also discussion of caveats listed for <a>checkContainsThunks</a>.
noThunks :: NoThunks a => Context -> a -> IO (Maybe ThunkInfo)

-- | Check that the argument is in normal form, assuming it is in WHNF.
--   
--   The context will already have been extended with the type we're
--   looking at, so all that's left is to look at the thunks <i>inside</i>
--   the type. The default implementation uses GHC Generics to do this.
wNoThunks :: NoThunks a => Context -> a -> IO (Maybe ThunkInfo)

-- | Show type <tt>a</tt> (to add to the context)
--   
--   We try hard to avoid <a>Typeable</a> constraints in this module: there
--   are types with no <a>Typeable</a> instance but with a <a>NoThunks</a>
--   instance (most important example are types such as <tt>ST s</tt> which
--   rely on parametric polymorphism). By default we should therefore only
--   show the "outer layer"; for example, if we have a type
--   
--   <pre>
--   Seq (ST s ())
--   </pre>
--   
--   then <a>showTypeOf</a> should just give <tt>Seq</tt>, leaving it up to
--   the instance for <tt>ST</tt> to decide how to implement
--   <a>showTypeOf</a>; this keeps things compositional. The default
--   implementation does precisely this using the metadata that GHC
--   Generics provides.
--   
--   For convenience, however, some of the <tt>deriving via</tt> newtype
--   wrappers we provide <i>do</i> depend on <tt>Typeable</tt>; see below.
showTypeOf :: NoThunks a => Proxy a -> String
instance Ouroboros.Consensus.Util.IOLike.IOLike GHC.Types.IO


-- | A Read-Append-Write (RAW) lock
--   
--   Intended for qualified import
module Ouroboros.Consensus.Util.MonadSTM.RAWLock

-- | A Read-Append-Write (RAW) lock
--   
--   A RAW lock allows multiple concurrent readers, at most one appender,
--   which is allowed to run concurrently with the readers, and at most one
--   writer, which has exclusive access to the lock.
--   
--   The following table summarises which roles are allowed to concurrently
--   access the RAW lock:
--   
--   <pre>
--            │ Reader │ Appender │ Writer │
--   ─────────┼────────┼──────────┼────────┤
--   Reader   │   V    │     V    │    X   │
--   Appender │░░░░░░░░│     X    │    X   │
--   Writer   │░░░░░░░░│░░░░░░░░░░│    X   │
--   </pre>
--   
--   It is important to realise that a RAW lock is intended to control
--   access to a piece of in-memory state that should remain in sync with
--   some other state that can only be modified using side-effects, e.g.,
--   the file system. If, for example, you're only maintaining a counter
--   shared by threads, then simply use a <tt>TVar</tt> or an
--   <tt>MVar</tt>.
--   
--   <h1>Example use case: log files</h1>
--   
--   A RAW lock is useful, for example, to maintain an in-memory index of
--   log files stored on disk.
--   
--   <ul>
--   <li>To read data from a log file, you need "read" access to the index
--   to find out the file and offset where the requested piece of data is
--   stored. While holding the RAW lock as a reader, you can perform the IO
--   operation to read the data from the right log file. This can safely
--   happen concurrently with other read operations.</li>
--   <li>To append data to the current log file, you need "append" access
--   to the index so you can append an entry to the index and even to add a
--   new log file to the index when necessary. While holding the RAW lock
--   as an appender, you can perform the IO operation to append the piece
--   of data to the current log file and, if necessary start a new log
--   file. Only one append can happen concurrently. However, reads can
--   safely happen concurrently with appends. Note that the in-memory index
--   is only updated <i>after</i> writing to disk.</li>
--   <li>To remove the oldest log files, you need "write" access to the
--   index, so you can remove files from the index. While holding the RAW
--   lock as a writer, you can perform the IO operations to delete the
--   oldest log files. No other operations can run concurrently with this
--   operation: concurrent reads might try to read from deleted files and a
--   concurrent append could try to append to a deleted file.</li>
--   </ul>
--   
--   <h1>Analogy: Chicken coop</h1>
--   
--   Think of readers as chickens, the appender as the rooster, and the
--   writer as the fox. All of them want access to the chicken coop, i.e.,
--   the state protected by the RAW lock.
--   
--   We can allow multiple chickens (readers) together in the chicken coop,
--   they get along (reasonably) fine. We can also let one rooster
--   (appender) in, but not more than one, otherwise he would start
--   fighting with the other rooster (conflict with the other appender). We
--   can only let the fox in when all chickens and the rooster (if present)
--   have left the chicken coop, otherwise the fox would eat them (conflict
--   with the appender and invalidate the results of readers, e.g, closing
--   resources readers try to access).
--   
--   <h1>Usage</h1>
--   
--   To use the lock, use any of the three following operations:
--   
--   <ul>
--   <li><a>withReadAccess</a></li>
--   <li><a>withAppendAccess</a></li>
--   <li><a>withWriteAccess</a></li>
--   </ul>
--   
--   If the standard bracketing the above three operations use doesn't
--   suffice, use the following three acquire-release pairs:
--   
--   <ul>
--   <li><a>unsafeAcquireReadAccess</a> &amp;
--   <a>unsafeReleaseReadAccess</a></li>
--   <li><a>unsafeAcquireAppendAccess</a> &amp;
--   <a>unsafeReleaseAppendAccess</a></li>
--   <li><a>unsafeAcquireWriteAccess</a> &amp;
--   <a>unsafeReleaseWriteAccess</a></li>
--   </ul>
--   
--   NOTE: an acquire <b>must</b> be followed by the corresponding release,
--   otherwise the correctness of the lock is not guaranteed and a
--   dead-lock can happen.
--   
--   NOTE: nested locking of the same lock is not allowed, as you might be
--   blocked on yourself.
--   
--   <h1>Notes</h1>
--   
--   <ul>
--   <li>Only use a RAW lock when it is safe to concurrently read and
--   append.</li>
--   </ul>
--   
--   <ul>
--   <li>We do not guarantee fairness for appenders and writers. They will
--   race for access each time the RAW lock changes.</li>
--   <li>When you have many writers and/or very frequent writes, readers
--   and appenders will starve. You could say we have "unfairness", as
--   writers win over readers and appenders. A RAW lock will not be the
--   best fit in such a scenario.</li>
--   <li>When you have no writers and you only need a read-append lock,
--   consider using a <tt>StrictMVar</tt> instead. The "stale" state can be
--   used by the readers.</li>
--   <li>The state <tt>st</tt> is always evaluated to WHNF and is subject
--   to the <a>NoThunks</a> check when enabled.</li>
--   <li>All public functions are exception-safe.</li>
--   </ul>
data RAWLock m st

-- | Create a new <a>RAWLock</a>
new :: (IOLike m, NoThunks st) => st -> m (RAWLock m st)

-- | Access the state stored in the <a>RAWLock</a> as a reader.
--   
--   Will block when there is a writer or when a writer is waiting to take
--   the lock.
withReadAccess :: forall m st a. IOLike m => RAWLock m st -> (st -> m a) -> m a

-- | Access the state stored in the <a>RAWLock</a> as an appender.
--   
--   NOTE: it must be safe to run the given append action concurrently with
--   readers.
--   
--   Will block when there is another appender, a writer, or when a writer
--   is waiting to take the lock.
withAppendAccess :: forall m st a. IOLike m => RAWLock m st -> (st -> m (st, a)) -> m a

-- | Access the state stored in the <a>RAWLock</a> as a writer.
--   
--   Will block when there is another writer or while there are readers
--   and/or an appender.
withWriteAccess :: forall m st a. IOLike m => RAWLock m st -> (st -> m (st, a)) -> m a

-- | Read the contents of the <a>RAWLock</a> in an STM transaction.
--   
--   Will retry when there is a writer.
--   
--   In contrast to <a>withReadAccess</a>, this transaction will succeed
--   when there is a writer waiting to write, as there is no IO-operation
--   during which the lock must be held.
read :: IOLike m => RAWLock m st -> STM m st

-- | Poison the lock with the given exception. All subsequent access to the
--   lock will result in the given exception being thrown.
--   
--   Unless the lock has already been poisoned, in which case the original
--   exception with which the lock was poisoned will be thrown.
poison :: (IOLike m, Exception e, HasCallStack) => RAWLock m st -> (CallStack -> e) -> m (Maybe st)

-- | Acquire the <a>RAWLock</a> as a reader.
--   
--   Will block when there is a writer or when a writer is waiting to take
--   the lock.
--   
--   Composable with other <a>STM</a> transactions.
--   
--   NOTE: <b>must</b> be followed by a call to
--   <a>unsafeReleaseReadAccess</a>.
unsafeAcquireReadAccess :: IOLike m => RAWLock m st -> STM m st

-- | Release the <a>RAWLock</a> as a reader.
--   
--   Doesn't block.
--   
--   Composable with other <a>STM</a> transactions.
--   
--   NOTE: <b>must</b> be preceded by a call to
--   <a>unsafeAcquireReadAccess</a>.
unsafeReleaseReadAccess :: IOLike m => RAWLock m st -> STM m ()

-- | Access the state stored in the <a>RAWLock</a> as an appender.
--   
--   Will block when there is another appender, a writer, or when a writer
--   is waiting to take the lock.
--   
--   Composable with other <a>STM</a> transactions.
--   
--   NOTE: <b>must</b> be followed by a call to
--   <a>unsafeReleaseAppendAccess</a>.
unsafeAcquireAppendAccess :: IOLike m => RAWLock m st -> STM m st

-- | Release the <a>RAWLock</a> as an appender.
--   
--   Doesn't block.
--   
--   Composable with other <a>STM</a> transactions.
--   
--   NOTE: <b>must</b> be preceded by a call to
--   <a>unsafeAcquireAppendAccess</a>.
unsafeReleaseAppendAccess :: IOLike m => RAWLock m st -> st -> STM m ()

-- | Access the state stored in the <a>RAWLock</a> as a writer.
--   
--   Will block when there is another writer or while there are readers
--   and/or an appender.
--   
--   Does <i>not</i> compose with other <a>STM</a> transactions.
--   
--   NOTE: <b>must</b> be followed by a call to
--   <a>unsafeReleaseWriteAccess</a>.
unsafeAcquireWriteAccess :: IOLike m => RAWLock m st -> m st

-- | Release the <a>RAWLock</a> as a writer.
--   
--   Doesn't block.
--   
--   Does <i>not</i> compose with other <a>STM</a> transactions.
--   
--   NOTE: <b>must</b> be preceded by a call to
--   <a>unsafeAcquireWriteAccess</a>.
unsafeReleaseWriteAccess :: IOLike m => RAWLock m st -> st -> m ()
instance NoThunks.Class.NoThunks Ouroboros.Consensus.Util.MonadSTM.RAWLock.Readers
instance GHC.Num.Num Ouroboros.Consensus.Util.MonadSTM.RAWLock.Readers
instance GHC.Enum.Enum Ouroboros.Consensus.Util.MonadSTM.RAWLock.Readers
instance GHC.Classes.Ord Ouroboros.Consensus.Util.MonadSTM.RAWLock.Readers
instance GHC.Classes.Eq Ouroboros.Consensus.Util.MonadSTM.RAWLock.Readers
instance NoThunks.Class.NoThunks Ouroboros.Consensus.Util.MonadSTM.RAWLock.Appender
instance GHC.Generics.Generic Ouroboros.Consensus.Util.MonadSTM.RAWLock.Appender
instance NoThunks.Class.NoThunks st => NoThunks.Class.NoThunks (Ouroboros.Consensus.Util.MonadSTM.RAWLock.RAWState st)
instance GHC.Generics.Generic (Ouroboros.Consensus.Util.MonadSTM.RAWLock.RAWState st)

module Ouroboros.Consensus.Util.EarlyExit
data WithEarlyExit m a
withEarlyExit :: WithEarlyExit m a -> m (Maybe a)
withEarlyExit_ :: Functor m => WithEarlyExit m () -> m ()
exitEarly :: Applicative m => WithEarlyExit m a

-- | Lift a computation from the argument monad to the constructed monad.
lift :: (MonadTrans t, Monad m) => m a -> t m a
instance GHC.Base.Monad m => GHC.Base.MonadPlus (Ouroboros.Consensus.Util.EarlyExit.WithEarlyExit m)
instance Control.Monad.Trans.Class.MonadTrans Ouroboros.Consensus.Util.EarlyExit.WithEarlyExit
instance GHC.Base.Monad m => GHC.Base.Monad (Ouroboros.Consensus.Util.EarlyExit.WithEarlyExit m)
instance GHC.Base.Monad m => GHC.Base.Alternative (Ouroboros.Consensus.Util.EarlyExit.WithEarlyExit m)
instance GHC.Base.Monad m => GHC.Base.Applicative (Ouroboros.Consensus.Util.EarlyExit.WithEarlyExit m)
instance GHC.Base.Functor m => GHC.Base.Functor (Ouroboros.Consensus.Util.EarlyExit.WithEarlyExit m)
instance (forall a'. NoThunks.Class.NoThunks (m a')) => NoThunks.Class.NoThunks (Ouroboros.Consensus.Util.EarlyExit.WithEarlyExit m a)
instance Control.Monad.Class.MonadSTM.MonadSTMTx stm => Control.Monad.Class.MonadSTM.MonadSTMTx (Ouroboros.Consensus.Util.EarlyExit.WithEarlyExit stm)
instance Control.Monad.Class.MonadSTM.MonadSTM m => Control.Monad.Class.MonadSTM.MonadSTM (Ouroboros.Consensus.Util.EarlyExit.WithEarlyExit m)
instance Control.Monad.Class.MonadThrow.MonadCatch m => Control.Monad.Class.MonadThrow.MonadThrow (Ouroboros.Consensus.Util.EarlyExit.WithEarlyExit m)
instance Control.Monad.Class.MonadThrow.MonadCatch m => Control.Monad.Class.MonadThrow.MonadCatch (Ouroboros.Consensus.Util.EarlyExit.WithEarlyExit m)
instance Control.Monad.Class.MonadThrow.MonadMask m => Control.Monad.Class.MonadThrow.MonadMask (Ouroboros.Consensus.Util.EarlyExit.WithEarlyExit m)
instance Control.Monad.Class.MonadFork.MonadThread m => Control.Monad.Class.MonadFork.MonadThread (Ouroboros.Consensus.Util.EarlyExit.WithEarlyExit m)
instance (Control.Monad.Class.MonadAsync.MonadAsyncSTM async stm, Control.Monad.Class.MonadThrow.MonadCatch stm) => Control.Monad.Class.MonadAsync.MonadAsyncSTM (Ouroboros.Consensus.Util.EarlyExit.WithEarlyExit async) (Ouroboros.Consensus.Util.EarlyExit.WithEarlyExit stm)
instance (Control.Monad.Class.MonadThrow.MonadMask m, Control.Monad.Class.MonadAsync.MonadAsync m, Control.Monad.Class.MonadThrow.MonadCatch (Control.Monad.Class.MonadSTM.STM m)) => Control.Monad.Class.MonadAsync.MonadAsync (Ouroboros.Consensus.Util.EarlyExit.WithEarlyExit m)
instance Control.Monad.Class.MonadFork.MonadFork m => Control.Monad.Class.MonadFork.MonadFork (Ouroboros.Consensus.Util.EarlyExit.WithEarlyExit m)
instance Control.Monad.Class.MonadST.MonadST m => Control.Monad.Class.MonadST.MonadST (Ouroboros.Consensus.Util.EarlyExit.WithEarlyExit m)
instance Control.Monad.Class.MonadTime.MonadMonotonicTime m => Control.Monad.Class.MonadTime.MonadMonotonicTime (Ouroboros.Consensus.Util.EarlyExit.WithEarlyExit m)
instance Control.Monad.Class.MonadTimer.MonadDelay m => Control.Monad.Class.MonadTimer.MonadDelay (Ouroboros.Consensus.Util.EarlyExit.WithEarlyExit m)
instance (Control.Monad.Class.MonadThrow.MonadEvaluate m, Control.Monad.Class.MonadThrow.MonadCatch m) => Control.Monad.Class.MonadThrow.MonadEvaluate (Ouroboros.Consensus.Util.EarlyExit.WithEarlyExit m)
instance Control.Monad.Class.MonadEventlog.MonadEventlog m => Control.Monad.Class.MonadEventlog.MonadEventlog (Ouroboros.Consensus.Util.EarlyExit.WithEarlyExit m)
instance (Ouroboros.Consensus.Util.IOLike.IOLike m, forall a. NoThunks.Class.NoThunks (Control.Monad.Class.MonadSTM.Strict.StrictTVar (Ouroboros.Consensus.Util.EarlyExit.WithEarlyExit m) a), forall a. NoThunks.Class.NoThunks (Ouroboros.Consensus.Util.MonadSTM.StrictMVar.StrictMVar (Ouroboros.Consensus.Util.EarlyExit.WithEarlyExit m) a), Control.Monad.Class.MonadThrow.MonadCatch (Control.Monad.Class.MonadSTM.STM m)) => Ouroboros.Consensus.Util.IOLike.IOLike (Ouroboros.Consensus.Util.EarlyExit.WithEarlyExit m)


-- | Special file we store in the DB dir to avoid unintended deletions
module Ouroboros.Consensus.Node.DbMarker
data DbMarkerError

-- | There was a <a>dbMarkerFile</a> in the database folder, but it
--   contained a different <a>NetworkMagic</a> than the expected one. This
--   indicates that this database folder corresponds to another net.
NetworkMagicMismatch :: FilePath -> NetworkMagic -> NetworkMagic -> DbMarkerError

-- | The full path to the <a>dbMarkerFile</a>
NoDbMarkerAndNotEmpty :: FilePath -> DbMarkerError

-- | The full path to the <a>dbMarkerFile</a>
CorruptDbMarker :: FilePath -> DbMarkerError

-- | Check database marker
--   
--   The database folder will contain folders for the ImmutableDB
--   (<tt>immutable</tt>), the VolatileDB (<tt>volatile</tt>), and the
--   LedgerDB (<tt>ledger</tt>). All three subdatabases can delete files
--   from these folders, e.g., outdated files or files that are deemed
--   invalid.
--   
--   For example, when starting a node that will connect to a testnet with
--   a database folder containing mainnet blocks, these blocks will be
--   deemed invalid and will be deleted. This would throw away a perfectly
--   good chain, possibly consisting of gigabytes of data that will have to
--   be synched again.
--   
--   To protect us from unwanted deletion of valid files, we first check
--   whether we have been given the path to the right database folder. We
--   do this by reading the <a>NetworkMagic</a> of the net from a file
--   stored in the root of the database folder. This file's name is defined
--   in <a>dbMarkerFile</a>.
--   
--   <ul>
--   <li>If the <a>NetworkMagic</a> from the file matches that of the net,
--   we have the right database folder.</li>
--   <li>If not, we are opening the wrong database folder and abort by
--   throwing a <a>DbMarkerError</a>.</li>
--   <li>If there is no such file and the folder is empty, we create it and
--   store the net's <a>NetworkMagic</a> in it.</li>
--   <li>If there is no such file, but the folder is not empty, we throw a
--   <a>DbMarkerError</a>, because we have likely been given the wrong
--   path, maybe to a folder containing user or system files. This includes
--   the case that the <a>dbMarkerFile</a> has been deleted.</li>
--   <li>If there is such a <a>dbMarkerFile</a>, but it could not be read
--   or its contents could not be parsed, we also throw a
--   <a>DbMarkerError</a>.</li>
--   </ul>
--   
--   Note that an <a>FsError</a> can also be thrown.
checkDbMarker :: forall m h. MonadThrow m => HasFS m h -> MountPoint -> NetworkMagic -> m (Either DbMarkerError ())

-- | For legacy reasons it was using <tt>ProtocolMagicId</tt> not
--   <a>NetworkMagic</a> which are really the same thing.
dbMarkerFile :: Text
dbMarkerContents :: NetworkMagic -> ByteString

-- | Parse contents of the DB marker file
--   
--   Must be inverse to <a>dbMarkerContents</a>
dbMarkerParse :: Monad m => FilePath -> ByteString -> ExceptT DbMarkerError m NetworkMagic
instance GHC.Show.Show Ouroboros.Consensus.Node.DbMarker.DbMarkerError
instance GHC.Classes.Eq Ouroboros.Consensus.Node.DbMarker.DbMarkerError
instance GHC.Exception.Type.Exception Ouroboros.Consensus.Node.DbMarker.DbMarkerError

module Ouroboros.Consensus.Node.DbLock
newtype DbLocked
DbLocked :: FilePath -> DbLocked

-- | We use an empty file (<a>dbLockFsPath</a>) as a lock of the database
--   so that the database cannot be opened by more than one process. We
--   wait up to <a>dbLockTimeout</a> to take the lock, before timing out
--   and throwing a <a>DbLocked</a> exception.
withLockDB :: MountPoint -> IO a -> IO a

-- | The default lock file
dbLockFsPath :: FsPath

-- | Default time to wait on the lock
dbLockTimeout :: DiffTime

-- | We use the given <a>FsPath</a> in the <a>MountPoint</a> as a lock of
--   the database so that the database cannot be opened by more than one
--   process. We wait the given <a>DiffTime</a> on the thread taking the
--   lock. In case of a timeout, we throw a <a>DbLocked</a> exception.
--   
--   Some systems may delete the empty file when all its handles are
--   closed. This is not an issue, since the file is created if it doesn't
--   exist.
withLockDB_ :: forall m a. (IOLike m, MonadTimer m) => FileLock m -> MountPoint -> FsPath -> DiffTime -> m a -> m a
instance GHC.Show.Show Ouroboros.Consensus.Node.DbLock.DbLocked
instance GHC.Classes.Eq Ouroboros.Consensus.Node.DbLock.DbLocked
instance GHC.Exception.Type.Exception Ouroboros.Consensus.Node.DbLock.DbLocked

module Ouroboros.Consensus.Ledger.SupportsMempool

-- | Generalized transaction
--   
--   The mempool (and, accordingly, blocks) consist of "generalized
--   transactions"; this could be "proper" transactions (transferring
--   funds) but also other kinds of things such as update proposals,
--   delegations, etc.
data family GenTx blk :: Type

-- | Updating the ledger with a single transaction may result in a
--   different error type as when updating it with a block
type family ApplyTxErr blk :: Type
class (UpdateLedger blk, NoThunks (GenTx blk), NoThunks (Ticked (LedgerState blk)), Show (GenTx blk), Show (ApplyTxErr blk)) => LedgerSupportsMempool blk

-- | Check whether the internal invariants of the transaction hold.
txInvariant :: LedgerSupportsMempool blk => GenTx blk -> Bool

-- | Apply transaction we have not previously seen before
applyTx :: LedgerSupportsMempool blk => LedgerConfig blk -> SlotNo -> GenTx blk -> TickedLedgerState blk -> Except (ApplyTxErr blk) (TickedLedgerState blk)

-- | Re-apply a transaction
--   
--   When we re-apply a transaction to a potentially different ledger state
--   expensive checks such as cryptographic hashes can be skipped, but
--   other checks (such as checking for double spending) must still be
--   done.
reapplyTx :: (LedgerSupportsMempool blk, HasCallStack) => LedgerConfig blk -> SlotNo -> GenTx blk -> TickedLedgerState blk -> Except (ApplyTxErr blk) (TickedLedgerState blk)

-- | The maximum number of bytes worth of transactions that can be put into
--   a block according to the currently adopted protocol parameters of the
--   ledger state.
--   
--   This is (conservatively) computed by subtracting the header size and
--   any other fixed overheads from the maximum block size.
maxTxCapacity :: LedgerSupportsMempool blk => TickedLedgerState blk -> Word32

-- | Return the post-serialisation size in bytes of a <a>GenTx</a> /when it
--   is embedded in a block/. This size might differ from the size of the
--   serialisation used to send and receive the transaction across the
--   network.
--   
--   This size is used to compute how many transaction we can put in a
--   block when forging one.
--   
--   For example, CBOR-in-CBOR could be used when sending the transaction
--   across the network, requiring a few extra bytes compared to the actual
--   in-block serialisation. Another example is the transaction of the
--   hard-fork combinator which will include an envelope indicating its era
--   when sent across the network. However, when embedded in the respective
--   era's block, there is no need for such envelope.
--   
--   Can be implemented by serialising the <a>GenTx</a>, but, ideally, this
--   is implement more efficiently. E.g., by returning the length of the
--   annotation.
txInBlockSize :: LedgerSupportsMempool blk => GenTx blk -> Word32

-- | A generalized transaction, <a>GenTx</a>, identifier.
data family TxId tx :: Type

-- | Transactions with an identifier
--   
--   The mempool will use these to locate transactions, so two different
--   transactions should have different identifiers.
class (Show (TxId tx), Ord (TxId tx), NoThunks (TxId tx)) => HasTxId tx

-- | Return the <a>TxId</a> of a <a>GenTx</a>.
--   
--   NOTE: a <a>TxId</a> must be unique up to ledger rules, i.e., two
--   <a>GenTx</a>s with the same <a>TxId</a> must be the same transaction
--   <i>according to the ledger</i>. However, we do not assume that a
--   <a>TxId</a> uniquely determines a <a>GenTx</a>: two <a>GenTx</a>s with
--   the same <a>TxId</a> can differ in, e.g., witnesses.
--   
--   Should be cheap as this will be called often.
txId :: HasTxId tx => tx -> TxId tx

-- | Shorthand: ID of a generalized transaction
type GenTxId blk = TxId (GenTx blk)

-- | Collect all transactions from a block
--   
--   This is used for tooling only. We don't require it as part of RunNode
--   (and cannot, because we cannot give an instance for the dual ledger).
class HasTxs blk

-- | Return the transactions part of the given block in no particular
--   order.
extractTxs :: HasTxs blk => blk -> [GenTx blk]

module Ouroboros.Consensus.Block.Forging

-- | Information about why we <i>cannot</i> forge a block, although we are
--   a leader
--   
--   This should happen only rarely. An example might be that our hot key
--   does not (yet/anymore) match the delegation state.
type family CannotForge blk :: Type

-- | Returned when a call to <a>updateForgeState</a> succeeded and caused
--   the forge state to change. This info is traced.
type family ForgeStateInfo blk :: Type

-- | Returned when a call <a>updateForgeState</a> failed, e.g., because the
--   KES key is no longer valid. This info is traced.
type family ForgeStateUpdateError blk :: Type

-- | The result of <a>updateForgeState</a>.
--   
--   Note: the forge state itself is implicit and not reflected in the
--   types.
newtype ForgeStateUpdateInfo blk
ForgeStateUpdateInfo :: UpdateInfo (ForgeStateInfo blk) (ForgeStateInfo blk) (ForgeStateUpdateError blk) -> ForgeStateUpdateInfo blk
[getForgeStateUpdateInfo] :: ForgeStateUpdateInfo blk -> UpdateInfo (ForgeStateInfo blk) (ForgeStateInfo blk) (ForgeStateUpdateError blk)
castForgeStateUpdateInfo :: (ForgeStateInfo blk ~ ForgeStateInfo blk', ForgeStateUpdateError blk ~ ForgeStateUpdateError blk') => ForgeStateUpdateInfo blk -> ForgeStateUpdateInfo blk'

-- | Stateful wrapper around block production
--   
--   NOTE: do not refer to the consensus or ledger config in the closure of
--   this record because they might contain an <tt>EpochInfo Identity</tt>,
--   which will be incorrect when used as part of the hard fork combinator.
data BlockForging m blk
BlockForging :: Text -> CanBeLeader (BlockProtocol blk) -> (SlotNo -> m (ForgeStateUpdateInfo blk)) -> (forall p. BlockProtocol blk ~ p => TopLevelConfig blk -> SlotNo -> Ticked (ChainDepState p) -> IsLeader p -> ForgeStateInfo blk -> Either (CannotForge blk) ()) -> (TopLevelConfig blk -> BlockNo -> SlotNo -> TickedLedgerState blk -> [GenTx blk] -> IsLeader (BlockProtocol blk) -> m blk) -> BlockForging m blk

-- | Identifier used in the trace messages produced for this
--   <a>BlockForging</a> record.
--   
--   Useful when the node is running with multiple sets of credentials.
[forgeLabel] :: BlockForging m blk -> Text

-- | Proof that the node can be a leader
--   
--   NOTE: the other fields of this record may refer to this value (or a
--   value derived from it) in their closure, which means one should not
--   override this field independently from the others.
[canBeLeader] :: BlockForging m blk -> CanBeLeader (BlockProtocol blk)

-- | Update the forge state.
--   
--   When the node can be a leader, this will be called at the start of
--   each slot, right before calling <a>checkCanForge</a>.
--   
--   When <a>Updated</a> or <a>Unchanged</a> is returned, we trace the
--   <a>ForgeStateInfo</a>.
--   
--   When <a>UpdateFailed</a> is returned, we trace the
--   <a>ForgeStateUpdateError</a> and don't call <a>checkCanForge</a>.
[updateForgeState] :: BlockForging m blk -> SlotNo -> m (ForgeStateUpdateInfo blk)

-- | After checking that the node indeed is a leader (<a>checkIsLeader</a>
--   returned <a>Just</a>) and successfully updating the forge state
--   (<a>updateForgeState</a> did not return <a>UpdateFailed</a>), do
--   another check to see whether we can actually forge a block.
--   
--   When <a>CannotForge</a> is returned, we don't call <a>forgeBlock</a>.
[checkCanForge] :: BlockForging m blk -> forall p. BlockProtocol blk ~ p => TopLevelConfig blk -> SlotNo -> Ticked (ChainDepState p) -> IsLeader p -> ForgeStateInfo blk -> Either (CannotForge blk) ()

-- | Forge a block
--   
--   The function is passed the contents of the mempool; this is a set of
--   transactions that is guaranteed to be consistent with the ledger state
--   (also provided as an argument) and with each other (when applied in
--   order). In principle <i>all</i> of them could be included in the block
--   (up to maximum block size).
--   
--   NOTE: do not refer to the consensus or ledger config in the closure,
--   because they might contain an <tt>EpochInfo Identity</tt>, which will
--   be incorrect when used as part of the hard fork combinator. Use the
--   given <a>TopLevelConfig</a> instead, as it is guaranteed to be correct
--   even when used as part of the hard fork combinator.
--   
--   PRECONDITION: <a>checkCanForge</a> returned <tt>Right ()</tt>.
[forgeBlock] :: BlockForging m blk -> TopLevelConfig blk -> BlockNo -> SlotNo -> TickedLedgerState blk -> [GenTx blk] -> IsLeader (BlockProtocol blk) -> m blk
data ShouldForge blk

-- | Before check whether we are a leader in this slot, we tried to update
--   our forge state (<a>updateForgeState</a>), but it failed. We will not
--   check whether we are leader and will thus not forge a block either.
--   
--   E.g., we could not evolve our KES key.
ForgeStateUpdateError :: ForgeStateUpdateError blk -> ShouldForge blk

-- | We are a leader in this slot, but we cannot forge for a certain
--   reason.
--   
--   E.g., our KES key is not yet valid in this slot or we are not the
--   current delegate of the genesis key we have a delegation certificate
--   from.
CannotForge :: CannotForge blk -> ShouldForge blk

-- | We are not a leader in this slot
NotLeader :: ShouldForge blk

-- | We are a leader in this slot and we should forge a block.
ShouldForge :: IsLeader (BlockProtocol blk) -> ShouldForge blk
checkShouldForge :: forall m blk. (Monad m, ConsensusProtocol (BlockProtocol blk), HasCallStack) => BlockForging m blk -> Tracer m (ForgeStateInfo blk) -> TopLevelConfig blk -> SlotNo -> Ticked (ChainDepState (BlockProtocol blk)) -> m (ShouldForge blk)

-- | The result of updating something, e.g., the forge state.
data UpdateInfo updated unchanged failed
Updated :: updated -> UpdateInfo updated unchanged failed
Unchanged :: unchanged -> UpdateInfo updated unchanged failed
UpdateFailed :: failed -> UpdateInfo updated unchanged failed
castUpdateInfo :: (updated ~ updated', unchanged ~ unchanged', failed ~ failed') => UpdateInfo updated unchanged failed -> UpdateInfo updated' unchanged' failed'
instance (GHC.Show.Show updated, GHC.Show.Show unchanged, GHC.Show.Show failed) => GHC.Show.Show (Ouroboros.Consensus.Block.Forging.UpdateInfo updated unchanged failed)
instance (GHC.Show.Show (Ouroboros.Consensus.Block.Forging.ForgeStateInfo blk), GHC.Show.Show (Ouroboros.Consensus.Block.Forging.ForgeStateUpdateError blk)) => GHC.Show.Show (Ouroboros.Consensus.Block.Forging.ForgeStateUpdateInfo blk)


-- | The consensus layer's abstract view of blocks
module Ouroboros.Consensus.Block

module Ouroboros.Consensus.Util.CBOR
data IDecodeIO a
Partial :: (Maybe ByteString -> IO (IDecodeIO a)) -> IDecodeIO a
Done :: !ByteString -> !ByteOffset -> a -> IDecodeIO a
Fail :: !ByteString -> !ByteOffset -> DeserialiseFailure -> IDecodeIO a
fromIDecode :: IDecode RealWorld a -> IDecodeIO a
deserialiseIncrementalIO :: (forall s. Decoder s a) -> IO (IDecodeIO a)
data Decoder m
Decoder :: (forall a. (forall s. Decoder s a) -> m a) -> Decoder m

-- | Decode next failure
--   
--   May throw <a>DeserialiseFailure</a>
[decodeNext] :: Decoder m -> forall a. (forall s. Decoder s a) -> m a

-- | Construct incremental decoder given a way to get chunks
--   
--   Resulting decoder is not thread safe.
initDecoderIO :: IO ByteString -> IO (Decoder IO)
decodeAsFlatTerm :: ByteString -> Either DeserialiseFailure FlatTerm
data ReadIncrementalErr

-- | Could not deserialise the data
ReadFailed :: DeserialiseFailure -> ReadIncrementalErr

-- | Deserialisation was successful, but there was additional data
TrailingBytes :: ByteString -> ReadIncrementalErr

-- | Read a file incrementally
--   
--   NOTE: The <a>MonadThrow</a> constraint is only needed for
--   <a>bracket</a>. This function does not actually throw anything.
--   
--   NOTE: This uses a chunk size of roughly 32k. If we use this function
--   to read small things this might not be ideal.
--   
--   NOTE: This currently expects the file to contain precisely one value;
--   see also <a>withStreamIncrementalOffsets</a>.
readIncremental :: forall m a. IOLike m => SomeHasFS m -> (forall s. Decoder s a) -> FsPath -> m (Either ReadIncrementalErr a)

-- | Read multiple <tt>a</tt>s incrementally from a file in a streaming
--   way.
--   
--   Continuation-passing style to ensure proper closure of the file.
--   
--   Reads the offset (<a>Word64</a>) of the start of each <tt>a</tt>, the
--   size (<a>Word64</a>) of each <tt>a</tt>, and each <tt>a</tt> itself.
--   When deserialising fails, it passes all already deserialised
--   <tt>a</tt>s, the error, and the offset after which the failure
--   occurred.
--   
--   NOTE: f we introduce user-facing streaming API also, the fact that we
--   are using <tt>streaming</tt> here should not dictate that we should
--   stick with it later; rather, we should revisit this code at that
--   point.
withStreamIncrementalOffsets :: forall m h a r. (IOLike m, HasCallStack) => HasFS m h -> (forall s. Decoder s (ByteString -> a)) -> FsPath -> (Stream (Of (Word64, (Word64, a))) m (Maybe (ReadIncrementalErr, Word64)) -> m r) -> m r
encodeList :: (a -> Encoding) -> [a] -> Encoding
decodeList :: Decoder s a -> Decoder s [a]
encodeSeq :: (a -> Encoding) -> StrictSeq a -> Encoding
decodeSeq :: Decoder s a -> Decoder s (StrictSeq a)
encodeMaybe :: (a -> Encoding) -> Maybe a -> Encoding
decodeMaybe :: Decoder s a -> Decoder s (Maybe a)
encodeWithOrigin :: (a -> Encoding) -> WithOrigin a -> Encoding
decodeWithOrigin :: Decoder s a -> Decoder s (WithOrigin a)
instance GHC.Show.Show Ouroboros.Consensus.Util.CBOR.ReadIncrementalErr
instance GHC.Classes.Eq Ouroboros.Consensus.Util.CBOR.ReadIncrementalErr


-- | Utility functions on anchored fragments
--   
--   Intended for qualified import &gt; import qualified
--   Ouroboros.Consensus.Util.AnchoredFragment as AF
module Ouroboros.Consensus.Util.AnchoredFragment

-- | Compare the <tt>headBlockNo</tt>, which is a measure of the length of
--   the chain, of two anchored fragments.
--   
--   A fragment with a head is always "greater" than one without. When both
--   fragments have no head (i.e. are empty), they are <a>EQ</a>.
--   
--   Note that an EBB can share its <tt>BlockNo</tt> with another regular
--   block. If such an EBB is the head of one fragment and the regular
--   block with the same <tt>BlockNo</tt> is the head of the other
--   fragment, then this function will say they are <a>EQ</a>, while in
--   fact one fragment should be preferred over the other.
--   
--   This is not a big deal as we won't be seeing new EBBs, so they will
--   not be the head of a fragment very often anyway, only when catching
--   up. As soon as a new block/header is added to the fragment, the right
--   decision will be made again (<a>GT</a> or <a>LT</a>).
compareHeadBlockNo :: HasHeader b => AnchoredFragment b -> AnchoredFragment b -> Ordering
forksAtMostKBlocks :: HasHeader b => Word64 -> AnchoredFragment b -> AnchoredFragment b -> Bool

-- | Lift <a>preferCandidate</a> to <a>AnchoredFragment</a>
--   
--   PRECONDITION: The candidate must intersect with our chain within
--   <tt>k</tt> blocks from our tip.
--   
--   NOTE: In the discussion below we assume that the anchored fragments
--   are <i>suffixes</i> of their chains.
--   
--   A non-empty chain is always preferred over an empty one (see
--   discussion for <a>preferCandidate</a>), but that does not necessarily
--   mean that a non-empty chain <i>fragment</i> is necessary preferred
--   over an empty one. After all, chain fragments are suffixes of chains,
--   and so in principle it's possible that we might prefer the empty
--   suffix of a longer chain over the non-empty suffix of a shorter one.
--   
--   We can distinguish between an empty fragment of a non-empty chain and
--   a (necessarily) empty fragment of an empty chain by looking at the
--   anchor point: if that is the genesis point, the chain must be empty.
--   For emphasis, we will refer to these chains/fragments as "genuinely
--   empty".
--   
--   Our own fragment will be empty in two cases only:
--   
--   <ul>
--   <li>It is genuinely empty. In this case, we prefer the candidate
--   always, unless it too is genuinely empty.</li>
--   <li>We suffered from data loss, to such an extent that the volatile DB
--   does not contain any blocks anymore that fit onto our immutable chain.
--   This case will require more careful consideration.</li>
--   </ul>
--   
--   Unfortunately, the candidate fragment can basically be empty at any
--   point due to the way that a switch-to-fork is implemented in terms of
--   rollback followed by roll forward; after a maximum rollback (and
--   before the roll forward), the candidate fragment is empty. (Note that
--   a genuinely empty fragment is <i>never</i> preferred over our chain.)
--   
--   We therefore have the following cases to consider:
--   
--   <ol>
--   <li>Both fragments are empty.</li>
--   </ol>
--   
--   Since the two fragments must intersect, that intersection point can
--   only be the two anchor points, which must therefore be equal. This
--   means that two fragments represent the same chain: the candidate is
--   not preferred.
--   
--   <ol>
--   <li>Our fragment is non-empty, the candidate fragment is empty.</li>
--   </ol>
--   
--   Since the two fragments must intersect, that intersection can only be
--   the anchor of the candidate. That intersection point can lie anywhere
--   on our fragment.
--   
--   a. If it lies at the tip of our fragment, the two fragments represent
--   the same chain. b. If it lies before the tip of our fragment, the
--   candidate chain is a strict prefix of our chain.
--   
--   In either case the candidate is not preferred.
--   
--   <ol>
--   <li>Our fragment is empty, the candidate fragment is non-empty.</li>
--   </ol>
--   
--   Since the two fragments must intersect, that intersection can only be
--   the anchor of our fragment. Moreover, since we have ruled out the case
--   that our chain is genuinely empty, that anchor must be the tip of the
--   immutable DB. In other words, the tip of the immutable DB must lie
--   somewhere on the candidate chain.
--   
--   a. If that is also the tip of the candidate fragment, the two
--   fragments represent the same chain, and the candidate is not
--   preferred. b. If it is <i>not</i> the tip, the candidate is a strict
--   extension of our chain and is therefore preferred.
--   
--   <ol>
--   <li>Neither fragment is empty. In this case, we can simply call
--   <a>preferCandidate</a> on the two heads.</li>
--   </ol>
--   
--   The case distinction between (3a) and (3b) could be avoided if we can
--   assume that the candidate fragment is anchored at our own anchor point
--   (which is guaranteed by trimming; see the ChainSync.md spec). In this
--   case, case (3a) becomes impossible. We <i>could</i> require this as a
--   stronger precondition, at the cost of potentially requiring the caller
--   to trim every time before calling <a>preferAnchoredCandidate</a>. We
--   choose not to do this: trimming in most cases is unnecessary (it is
--   only required if our own fragment is empty, which will be very rare
--   indeed); moreover, the work we need to do here to distinguish between
--   (3a) and (3b) is the same amount of work that a trimming would need to
--   do (but we only need to do it rarely).
--   
--   It is worth emphasizing that the above means that in the case that our
--   fragment or the candidate fragment is empty, we can decide whether or
--   not the candidate is preferred using only the "always extend" rule: we
--   never need the header that corresponds to the anchor point.
preferAnchoredCandidate :: forall blk. BlockSupportsProtocol blk => TopLevelConfig blk -> AnchoredFragment (Header blk) -> AnchoredFragment (Header blk) -> Bool

-- | Lift <a>compareCandidates</a> to <a>AnchoredFragment</a>
--   
--   PRECONDITION: Both candidates must be preferred to our chain.
--   
--   Implementation note: since the empty fragment is never preferred over
--   our chain, this is trivial. See discussion in
--   <a>preferAnchoredCandidate</a> for details.
compareAnchoredCandidates :: forall blk. (BlockSupportsProtocol blk, HasCallStack) => TopLevelConfig blk -> AnchoredFragment (Header blk) -> AnchoredFragment (Header blk) -> Ordering

module Ouroboros.Consensus.Storage.LedgerDB.InMemory

-- | Internal state of the ledger DB
--   
--   The ledger DB looks like
--   
--   <pre>
--   anchor |&gt; snapshots &lt;| current
--   </pre>
--   
--   where <tt>anchor</tt> records the oldest known snapshot and
--   <tt>current</tt> the most recent. The anchor is the oldest point we
--   can roll back to.
--   
--   We take a snapshot after each block is applied and keep in memory a
--   window of the last <tt>k</tt> snapshots. We have verified empirically
--   (#1936) that the overhead of keeping @k snapshots in memory is small,
--   i.e., about 5% compared to keeping a snapshot every 100 blocks. This
--   is thanks to sharing between consecutive snapshots.
--   
--   As an example, suppose we have <tt>k = 6</tt>. The ledger DB grows as
--   illustrated below, where we indicate the anchor number of blocks, the
--   stored snapshots, and the current ledger.
--   
--   <pre>
--   anchor |&gt; #   [ snapshots ]                   &lt;| tip
--   ---------------------------------------------------------------------------
--   G      |&gt; (0) [ ]                             &lt;| G
--   G      |&gt; (1) [ L1]                           &lt;| L1
--   G      |&gt; (2) [ L1,  L2]                      &lt;| L2
--   G      |&gt; (3) [ L1,  L2,  L3]                 &lt;| L3
--   G      |&gt; (4) [ L1,  L2,  L3,  L4]            &lt;| L4
--   G      |&gt; (5) [ L1,  L2,  L3,  L4,  L5]       &lt;| L5
--   G      |&gt; (6) [ L1,  L2,  L3,  L4,  L5,  L6]  &lt;| L6
--   L1     |&gt; (6) [ L2,  L3,  L4,  L5,  L6,  L7]  &lt;| L7
--   L2     |&gt; (6) [ L3,  L4,  L5,  L6,  L7,  L8]  &lt;| L8
--   L3     |&gt; (6) [ L4,  L5,  L6,  L7,  L8,  L9]  &lt;| L9   (*)
--   L4     |&gt; (6) [ L5,  L6,  L7,  L8,  L9,  L10] &lt;| L10
--   L5     |&gt; (6) [*L6,  L7,  L8,  L9,  L10, L11] &lt;| L11
--   L6     |&gt; (6) [ L7,  L8,  L9,  L10, L11, L12] &lt;| L12
--   L7     |&gt; (6) [ L8,  L9,  L10, L12, L12, L13] &lt;| L13
--   L8     |&gt; (6) [ L9,  L10, L12, L12, L13, L14] &lt;| L14
--   </pre>
--   
--   The ledger DB must guarantee that at all times we are able to roll
--   back <tt>k</tt> blocks. For example, if we are on line (*), and roll
--   back 6 blocks, we get
--   
--   <pre>
--   L3 |&gt; []
--   </pre>
data LedgerDB l r
newtype LedgerDbParams
LedgerDbParams :: SecurityParam -> LedgerDbParams

-- | Security parameter (maximum rollback)
[ledgerDbSecurityParam] :: LedgerDbParams -> SecurityParam

-- | Default parameters
ledgerDbDefaultParams :: SecurityParam -> LedgerDbParams

-- | Ledger DB starting at the specified ledger state
ledgerDbWithAnchor :: LedgerDbParams -> ChainSummary l r -> LedgerDB l r
ledgerDbFromGenesis :: LedgerDbParams -> l -> LedgerDB l r

-- | Summary of the chain at a particular point in time
data ChainSummary l r
ChainSummary :: !WithOrigin r -> !Word64 -> !l -> ChainSummary l r

-- | The tip of the chain
[csTip] :: ChainSummary l r -> !WithOrigin r

-- | Length of the chain
[csLength] :: ChainSummary l r -> !Word64

-- | Ledger state
[csLedger] :: ChainSummary l r -> !l
encodeChainSummary :: (l -> Encoding) -> (r -> Encoding) -> ChainSummary l r -> Encoding
decodeChainSummary :: (forall s. Decoder s l) -> (forall s. Decoder s r) -> forall s. Decoder s (ChainSummary l r)

-- | The ledger state at the tip of the chain
ledgerDbCurrent :: LedgerDB l r -> l

-- | Reference to the block at the tip of the chain
ledgerDbTip :: LedgerDB l r -> WithOrigin r

-- | Information about the state of the ledger <i>before</i>
ledgerDbAnchor :: LedgerDB l r -> ChainSummary l r

-- | Get a past ledger state
--   
--   &lt;math&gt;.
--   
--   When no <a>Checkpoint</a> (or anchor) has the given
--   <tt><a>WithOrigin</a> r</tt>, <a>Nothing</a> is returned.
--   
--   To avoid a linear search on the checkpoints (typically 2160 of them),
--   we do a binary search benefitting from the cheap splits of the
--   underlying <a>StrictSeq</a> &lt;math&gt;.
--   
--   For a binary search, the checkpoints have to be ordered by <tt>r</tt>.
--   In practice, we'll use <a>RealPoint</a> for <tt>r</tt>, which, because
--   of the existence of EBBs, doesn't have a reliable ordering: it orders
--   first on <a>SlotNo</a>, which is correct. But in case of a tie, it
--   will look at the hash, which is not what we need: an EBB has the same
--   slot as the block after it, so we'd want the <a>RealPoint</a> of an
--   EBB to be <i>less</i> than the <a>RealPoint</a> of the regular block
--   in the same slot. But the decision is made based on the hash, so we
--   won't get a reliable answer.
--   
--   Therefore, we take a projection <tt>refOrder :: r -&gt; ro</tt> as an
--   argument. The <tt>ro</tt> type should have a correct ordering, so that
--   the list below is correctly ordered:
--   
--   <pre>
--   map (refOrder . cpBlock) $ Seq.toList (ledgerDbCheckpoints db)
--   </pre>
--   
--   When instantiating <tt>r</tt> to <a>RealPoint</a>, one should use
--   <a>realPointSlot</a> as <tt>refOrder</tt>.
--   
--   Note: we don't use <tt>fingertree</tt> for the checkpoints (with its
--   <tt>search</tt> operation we could use here) because we'd have to
--   impose more constraints on the <tt>r</tt> type. We could do an
--   interpolation search if we assume more about the <tt>ro</tt> parameter
--   (<a>SlotNo</a>), but that would be more complicated.
ledgerDbPast :: forall l r ro. (Ord ro, Eq r) => (r -> ro) -> WithOrigin r -> LedgerDB l r -> Maybe l

-- | Apply the given function to all past ledgers in the <a>LedgerDB</a>,
--   including the one stored at the anchor.
--   
--   &lt;math&gt;
ledgerDbPastLedgers :: (l -> a) -> LedgerDB l r -> (a, StrictSeq a)

-- | <a>Ap</a> is used to pass information about blocks to ledger DB
--   updates
--   
--   The constructors serve two purposes:
--   
--   <ul>
--   <li>Specify the various parameters a. Are we passing the block by
--   value or by reference? b. Are we applying or reapplying the
--   block?</li>
--   <li>Compute the constraint <tt>c</tt> on the monad <tt>m</tt> in order
--   to run the query: a. If we are passing a block by reference, we must
--   be able to resolve it. b. If we are applying rather than reapplying,
--   we might have ledger errors.</li>
--   </ul>
data Ap :: (Type -> Type) -> Type -> Type -> Type -> Constraint -> Type
[ReapplyVal] :: r -> b -> Ap m l r b ()
[ApplyVal] :: r -> b -> Ap m l r b (ThrowsLedgerError l r m)
[ReapplyRef] :: r -> Ap m l r b (ResolvesBlocks r b m)
[ApplyRef] :: r -> Ap m l r b (ResolvesBlocks r b m, ThrowsLedgerError l r m)

-- | <a>Weaken</a> increases the constraint on the monad <tt>m</tt>.
--   
--   This is primarily useful when combining multiple <a>Ap</a>s in a
--   single homogeneous structure.
[Weaken] :: (c' => c) => Ap m l r b c -> Ap m l r b c'

-- | Annotated ledger errors
data AnnLedgerError l r
AnnLedgerError :: LedgerDB l r -> r -> LedgerErr l -> AnnLedgerError l r

-- | The ledger DB just <i>before</i> this block was applied
[annLedgerState] :: AnnLedgerError l r -> LedgerDB l r

-- | Reference to the block that had the error
[annLedgerErrRef] :: AnnLedgerError l r -> r

-- | The ledger error itself
[annLedgerErr] :: AnnLedgerError l r -> LedgerErr l

-- | Resolve a block
--   
--   Resolving a block reference to the actual block lives in <tt>m</tt>
--   because it might need to read the block from disk (and can therefore
--   not be done inside an STM transaction).
--   
--   NOTE: The ledger DB will only ask the <tt>ChainDB</tt> for blocks it
--   knows must exist. If the <tt>ChainDB</tt> is unable to fulfill the
--   request, data corruption must have happened and the <tt>ChainDB</tt>
--   should trigger validation mode.
type ResolveBlock m r b = r -> m b

-- | Monads in which we can resolve blocks
--   
--   To guide type inference, we insist that we must be able to infer the
--   type of the block we are resolving from the type of the monad.
class Monad m => ResolvesBlocks r b m | m -> b
resolveBlock :: ResolvesBlocks r b m => r -> m b
class Monad m => ThrowsLedgerError l r m
throwLedgerError :: ThrowsLedgerError l r m => LedgerDB l r -> r -> LedgerErr l -> m a
defaultThrowLedgerErrors :: ExceptT (AnnLedgerError l r) m a -> m (Either (AnnLedgerError l r) a)
defaultResolveBlocks :: ResolveBlock m r b -> ReaderT (ResolveBlock m r b) m a -> m a
defaultResolveWithErrors :: ResolveBlock m r b -> ExceptT (AnnLedgerError l r) (ReaderT (ResolveBlock m r b) m) a -> m (Either (AnnLedgerError l r) a)

-- | Exceeded maximum rollback supported by the current ledger DB state
--   
--   Under normal circumstances this will not arise. It can really only
--   happen in the presence of data corruption (or when switching to a
--   shorter fork, but that is disallowed by all currently known Ouroboros
--   protocols).
--   
--   Records both the supported and the requested rollback.
data ExceededRollback
ExceededRollback :: Word64 -> Word64 -> ExceededRollback
[rollbackMaximum] :: ExceededRollback -> Word64
[rollbackRequested] :: ExceededRollback -> Word64
ledgerDbPush :: forall m c l r b. (ApplyBlock l b, Monad m, c) => LedgerCfg l -> Ap m l r b c -> LedgerDB l r -> m (LedgerDB l r)

-- | Switch to a fork
ledgerDbSwitch :: (ApplyBlock l b, Monad m, c) => LedgerCfg l -> Word64 -> [Ap m l r b c] -> LedgerDB l r -> m (Either ExceededRollback (LedgerDB l r))

-- | Total length of the chain (in terms of number of blocks)
ledgerDbChainLength :: LedgerDB l r -> Word64

-- | References to blocks and corresponding ledger state (from old to new)
ledgerDbToList :: LedgerDB l r -> [(r, l)]

-- | How many blocks can we currently roll back?
ledgerDbMaxRollback :: LedgerDB l r -> Word64

-- | All snapshots currently stored by the ledger DB (new to old)
--   
--   This also includes the snapshot at the anchor. For each snapshot we
--   also return the distance from the tip.
ledgerDbSnapshots :: forall l r. LedgerDB l r -> [(Word64, l)]

-- | Have we seen at least <tt>k</tt> blocks?
ledgerDbIsSaturated :: LedgerDB l r -> Bool

-- | Internal: count number of checkpoints to prune, given total number of
--   checkpoints
--   
--   This is exposed for the benefit of tests only.
ledgerDbCountToPrune :: LedgerDbParams -> Int -> Int

-- | Get a past ledger state
--   
--   &lt;math&gt;
--   
--   Straightforward implementation of <a>ledgerDbPast</a> using a linear
--   search.
--   
--   Can be used in tests to compare against <a>ledgerDbPast</a>.
ledgerDbPastSpec :: forall l r. Eq r => WithOrigin r -> LedgerDB l r -> Maybe l
ledgerDbPush' :: ApplyBlock l b => LedgerCfg l -> b -> LedgerDB l b -> LedgerDB l b
ledgerDbPushMany' :: ApplyBlock l b => LedgerCfg l -> [b] -> LedgerDB l b -> LedgerDB l b
ledgerDbSwitch' :: forall l b. ApplyBlock l b => LedgerCfg l -> Word64 -> [b] -> LedgerDB l b -> Maybe (LedgerDB l b)
instance NoThunks.Class.NoThunks Ouroboros.Consensus.Storage.LedgerDB.InMemory.LedgerDbParams
instance GHC.Generics.Generic Ouroboros.Consensus.Storage.LedgerDB.InMemory.LedgerDbParams
instance GHC.Classes.Eq Ouroboros.Consensus.Storage.LedgerDB.InMemory.LedgerDbParams
instance GHC.Show.Show Ouroboros.Consensus.Storage.LedgerDB.InMemory.LedgerDbParams
instance (NoThunks.Class.NoThunks r, NoThunks.Class.NoThunks l) => NoThunks.Class.NoThunks (Ouroboros.Consensus.Storage.LedgerDB.InMemory.Checkpoint l r)
instance GHC.Generics.Generic (Ouroboros.Consensus.Storage.LedgerDB.InMemory.Checkpoint l r)
instance (GHC.Classes.Eq r, GHC.Classes.Eq l) => GHC.Classes.Eq (Ouroboros.Consensus.Storage.LedgerDB.InMemory.Checkpoint l r)
instance (GHC.Show.Show r, GHC.Show.Show l) => GHC.Show.Show (Ouroboros.Consensus.Storage.LedgerDB.InMemory.Checkpoint l r)
instance (NoThunks.Class.NoThunks r, NoThunks.Class.NoThunks l) => NoThunks.Class.NoThunks (Ouroboros.Consensus.Storage.LedgerDB.InMemory.ChainSummary l r)
instance GHC.Generics.Generic (Ouroboros.Consensus.Storage.LedgerDB.InMemory.ChainSummary l r)
instance (GHC.Classes.Eq r, GHC.Classes.Eq l) => GHC.Classes.Eq (Ouroboros.Consensus.Storage.LedgerDB.InMemory.ChainSummary l r)
instance (GHC.Show.Show r, GHC.Show.Show l) => GHC.Show.Show (Ouroboros.Consensus.Storage.LedgerDB.InMemory.ChainSummary l r)
instance (NoThunks.Class.NoThunks r, NoThunks.Class.NoThunks l) => NoThunks.Class.NoThunks (Ouroboros.Consensus.Storage.LedgerDB.InMemory.LedgerDB l r)
instance GHC.Generics.Generic (Ouroboros.Consensus.Storage.LedgerDB.InMemory.LedgerDB l r)
instance (GHC.Classes.Eq r, GHC.Classes.Eq l) => GHC.Classes.Eq (Ouroboros.Consensus.Storage.LedgerDB.InMemory.LedgerDB l r)
instance (GHC.Show.Show r, GHC.Show.Show l) => GHC.Show.Show (Ouroboros.Consensus.Storage.LedgerDB.InMemory.LedgerDB l r)
instance GHC.Base.Monad m => Ouroboros.Consensus.Storage.LedgerDB.InMemory.ThrowsLedgerError l r (Control.Monad.Trans.Except.ExceptT (Ouroboros.Consensus.Storage.LedgerDB.InMemory.AnnLedgerError l r) m)
instance GHC.Base.Monad m => Ouroboros.Consensus.Storage.LedgerDB.InMemory.ResolvesBlocks r b (Control.Monad.Trans.Reader.ReaderT (Ouroboros.Consensus.Storage.LedgerDB.InMemory.ResolveBlock m r b) m)
instance GHC.Base.Monad m => Ouroboros.Consensus.Storage.LedgerDB.InMemory.ResolvesBlocks r b (Control.Monad.Trans.Except.ExceptT e (Control.Monad.Trans.Reader.ReaderT (Ouroboros.Consensus.Storage.LedgerDB.InMemory.ResolveBlock m r b) m))
instance Ouroboros.Consensus.Ledger.Basics.IsLedger l => Ouroboros.Consensus.Ledger.Basics.GetTip (Ouroboros.Consensus.Storage.LedgerDB.InMemory.LedgerDB l r)
instance Ouroboros.Consensus.Ledger.Basics.IsLedger l => Ouroboros.Consensus.Ledger.Basics.GetTip (Ouroboros.Consensus.Ticked.Ticked (Ouroboros.Consensus.Storage.LedgerDB.InMemory.LedgerDB l r))
instance (Ouroboros.Consensus.Ledger.Basics.IsLedger l, GHC.Show.Show r, GHC.Classes.Eq r, NoThunks.Class.NoThunks r) => Ouroboros.Consensus.Ledger.Basics.IsLedger (Ouroboros.Consensus.Storage.LedgerDB.InMemory.LedgerDB l r)
instance Ouroboros.Consensus.Ledger.Abstract.ApplyBlock l blk => Ouroboros.Consensus.Ledger.Abstract.ApplyBlock (Ouroboros.Consensus.Storage.LedgerDB.InMemory.LedgerDB l (Ouroboros.Consensus.Block.RealPoint.RealPoint blk)) blk
instance (Codec.Serialise.Class.Serialise l, Codec.Serialise.Class.Serialise r) => Codec.Serialise.Class.Serialise (Ouroboros.Consensus.Storage.LedgerDB.InMemory.ChainSummary l r)

module Ouroboros.Consensus.Storage.Common
tipIsGenesis :: WithOrigin r -> Bool

-- | Number of bytes from the start of a block needed to reconstruct the
--   nested context.
--   
--   See <tt>reconstructPrefixLen</tt>.
newtype PrefixLen
PrefixLen :: Word8 -> PrefixLen
[getPrefixLen] :: PrefixLen -> Word8
addPrefixLen :: Word8 -> PrefixLen -> PrefixLen
takePrefix :: PrefixLen -> ByteString -> ShortByteString

-- | Information about the serialised block.
data BinaryBlockInfo
BinaryBlockInfo :: !Word16 -> !Word16 -> BinaryBlockInfo

-- | The offset within the serialised block at which the header starts.
[headerOffset] :: BinaryBlockInfo -> !Word16

-- | How many bytes the header is long. Extracting the <a>headerSize</a>
--   bytes from serialised block starting from <a>headerOffset</a> should
--   yield the header. Before passing the extracted bytes to the decoder
--   for headers, an envelope can be around using
--   <tt>nodeAddHeaderEnvelope</tt>.
[headerSize] :: BinaryBlockInfo -> !Word16

-- | Extract the header from the given <a>ByteString</a> using the
--   <a>BinaryBlockInfo</a>.
extractHeader :: BinaryBlockInfo -> ByteString -> ByteString

-- | The lower bound for an iterator
--   
--   Hint: use <tt><a>StreamFromExclusive</a> <tt>genesisPoint</tt></tt> to
--   start streaming from Genesis.
data StreamFrom blk
StreamFromInclusive :: !RealPoint blk -> StreamFrom blk
StreamFromExclusive :: !Point blk -> StreamFrom blk
newtype StreamTo blk
StreamToInclusive :: RealPoint blk -> StreamTo blk

-- | Check whether the bounds make sense
--   
--   An example of bounds that don't make sense:
--   
--   <pre>
--   StreamFromExclusive (BlockPoint 3 ..)
--   StreamToInclusive   (RealPoint  3 ..)
--   </pre>
--   
--   This function does not check whether the bounds correspond to existing
--   blocks.
validBounds :: StandardHash blk => StreamFrom blk -> StreamTo blk -> Bool

-- | Which component of the block to read from a database: the whole block,
--   its header, its hash, the block size, ..., or combinations thereof.
--   
--   NOTE: when requesting multiple components, we will not optimise/cache
--   them.
data BlockComponent blk a

-- | Verify the integrity of the block by checking its signature and/or
--   hashes. The interpreter should throw an exception when the block does
--   not pass the check.
[GetVerifiedBlock] :: BlockComponent blk blk
[GetBlock] :: BlockComponent blk blk
[GetRawBlock] :: BlockComponent blk ByteString
[GetHeader] :: BlockComponent blk (Header blk)
[GetRawHeader] :: BlockComponent blk ByteString
[GetHash] :: BlockComponent blk (HeaderHash blk)
[GetSlot] :: BlockComponent blk SlotNo
[GetIsEBB] :: BlockComponent blk IsEBB
[GetBlockSize] :: BlockComponent blk Word32
[GetHeaderSize] :: BlockComponent blk Word16
[GetNestedCtxt] :: BlockComponent blk (SomeSecond (NestedCtxt Header) blk)
[GetPure] :: a -> BlockComponent blk a
[GetApply] :: BlockComponent blk (a -> b) -> BlockComponent blk a -> BlockComponent blk b
type SizeInBytes = Word32
instance NoThunks.Class.NoThunks Ouroboros.Consensus.Storage.Common.PrefixLen
instance GHC.Generics.Generic Ouroboros.Consensus.Storage.Common.PrefixLen
instance GHC.Show.Show Ouroboros.Consensus.Storage.Common.PrefixLen
instance GHC.Classes.Ord Ouroboros.Consensus.Storage.Common.PrefixLen
instance GHC.Classes.Eq Ouroboros.Consensus.Storage.Common.PrefixLen
instance GHC.Generics.Generic Ouroboros.Consensus.Storage.Common.BinaryBlockInfo
instance GHC.Show.Show Ouroboros.Consensus.Storage.Common.BinaryBlockInfo
instance GHC.Classes.Eq Ouroboros.Consensus.Storage.Common.BinaryBlockInfo
instance (Ouroboros.Network.Block.StandardHash blk, Data.Typeable.Internal.Typeable blk) => NoThunks.Class.NoThunks (Ouroboros.Consensus.Storage.Common.StreamFrom blk)
instance GHC.Generics.Generic (Ouroboros.Consensus.Storage.Common.StreamFrom blk)
instance Ouroboros.Network.Block.StandardHash blk => GHC.Classes.Eq (Ouroboros.Consensus.Storage.Common.StreamFrom blk)
instance Ouroboros.Network.Block.StandardHash blk => GHC.Show.Show (Ouroboros.Consensus.Storage.Common.StreamFrom blk)
instance (Ouroboros.Network.Block.StandardHash blk, Data.Typeable.Internal.Typeable blk) => NoThunks.Class.NoThunks (Ouroboros.Consensus.Storage.Common.StreamTo blk)
instance GHC.Generics.Generic (Ouroboros.Consensus.Storage.Common.StreamTo blk)
instance Ouroboros.Network.Block.StandardHash blk => GHC.Classes.Eq (Ouroboros.Consensus.Storage.Common.StreamTo blk)
instance Ouroboros.Network.Block.StandardHash blk => GHC.Show.Show (Ouroboros.Consensus.Storage.Common.StreamTo blk)
instance GHC.Base.Functor (Ouroboros.Consensus.Storage.Common.BlockComponent blk)
instance GHC.Base.Applicative (Ouroboros.Consensus.Storage.Common.BlockComponent blk)

module Ouroboros.Consensus.Storage.VolatileDB.API
data VolatileDB m blk
VolatileDB :: (HasCallStack => m ()) -> (forall b. HasCallStack => BlockComponent blk b -> HeaderHash blk -> m (Maybe b)) -> (HasCallStack => blk -> m ()) -> (HasCallStack => STM m (ChainHash blk -> Set (HeaderHash blk))) -> (HasCallStack => STM m (HeaderHash blk -> Maybe (BlockInfo blk))) -> (HasCallStack => SlotNo -> m ()) -> (HasCallStack => STM m MaxSlotNo) -> VolatileDB m blk

-- | Close the VolatileDB.
--   
--   NOTE: idempotent after a manual closure, but not after an automatic
--   closure in case of an <a>UnexpectedFailure</a>. In that case, closing
--   it again will cause a <a>ClosedDBError</a> wrapping the original
--   <a>UnexpectedFailure</a> to be thrown.
[closeDB] :: VolatileDB m blk -> HasCallStack => m ()

-- | Return the request block component for the block with the given hash.
--   When not in the VolatileDB, <a>Nothing</a> is returned.
[getBlockComponent] :: VolatileDB m blk -> forall b. HasCallStack => BlockComponent blk b -> HeaderHash blk -> m (Maybe b)

-- | Store the given block in the VolatileDB.
--   
--   Returns after the block has been written to disk.
[putBlock] :: VolatileDB m blk -> HasCallStack => blk -> m ()

-- | Return a function that returns the successors of the block with the
--   given hash.
--   
--   This function will return a non-empty set for any block of which a
--   predecessor has been added to the VolatileDB and will return an empty
--   set if no successors for the given block have been added to the
--   VolatileDB (yet).
--   
--   Note that it is not required that the given block has been added to
--   the VolatileDB.
[filterByPredecessor] :: VolatileDB m blk -> HasCallStack => STM m (ChainHash blk -> Set (HeaderHash blk))

-- | Return a function that returns the <a>BlockInfo</a> of the block with
--   the given hash or <a>Nothing</a> if the block is not found in the
--   VolatileDB.
[getBlockInfo] :: VolatileDB m blk -> HasCallStack => STM m (HeaderHash blk -> Maybe (BlockInfo blk))

-- | Try to remove all blocks with a slot number less than the given one.
--   
--   <h1>Context</h1>
--   
--   When the current chain changes, blocks older than <tt>k</tt>, i.e.,
--   blocks that are followed by <tt>k</tt> blocks or more, become
--   <i>immutable</i>. Whenever this happens, we schedule a garbage
--   collection on the VolatileDB that will try to remove blocks older than
--   the most recent immutable block, as such blocks will never be adopted.
--   There's no point in storing them anymore.
--   
--   <h1>Block number vs slot number</h1>
--   
--   While we typically talk in terms of <i>block numbers</i> when
--   discussing immutability, i.e., <i><tt>k</tt> blocks</i>, we use
--   <i>slot number</i> for garbage collection. We schedule a garbage
--   collection for blocks with a /slot number/ less than the slot number
--   of the immutable block, as opposed to the block number. The reason for
--   this is that the VolatileDB is not aware of block numbers, only of
--   slot numbers.
--   
--   By using slot numbers for garbage collection, we might not <i>yet</i>
--   have garbage collected some blocks that could never be adopted again
--   and that we would have garbage collected when using block numbers.
--   This is harmless. The opposite direction is more important and
--   problematic: garbage collecting a block that we might want to adopt
--   after all. Say we have mistakenly garbage collected such a block, in
--   that case the following would be true:
--   
--   <ol>
--   <li>The block has a slot number older than the immutable block's slot
--   number: otherwise we wouldn't have mistakenly garbage collected
--   it.</li>
--   <li>The block has a block number greater than the immutable block's
--   block number: otherwise we wouldn't want to adopt it, as it would have
--   been older than <tt>k</tt>.</li>
--   <li>The block is a part of a fork fitting on the immutable block. As
--   we cannot roll back this block, all forks we could ever adopt would
--   have to go through this block.</li>
--   </ol>
--   
--   As slot numbers grow monotonically within a chain, all forks starting
--   after the immutable block will only contain blocks with slot numbers
--   greater (or equal to in case of EBBs) than the immutable block's slot
--   number. This directly contradicts (1), so we will <i>never</i> garbage
--   collect a block that we might still want to adopt.
--   
--   <h1>Less than vs. less than or equal to</h1>
--   
--   Note that we remove blocks with a slot number <i>less than</i> the
--   given slot number, but not <i>equal to</i> it. In practice, this
--   off-by-one difference will not matter in terms of disk space usage,
--   because as soon as the chain grows again by at least one block, those
--   blocks will be removed anyway. The reason for <tt>&lt;</tt> opposed to
--   <tt>&lt;=</tt> is to avoid issues with <i>EBBs</i>, which have the
--   same slot number as the block after it.
[garbageCollect] :: VolatileDB m blk -> HasCallStack => SlotNo -> m ()

-- | Return the highest slot number ever stored by the VolatileDB.
[getMaxSlotNo] :: VolatileDB m blk -> HasCallStack => STM m MaxSlotNo

-- | The information that the user has to provide for each new block.
data BlockInfo blk
BlockInfo :: !HeaderHash blk -> !SlotNo -> !BlockNo -> !ChainHash blk -> !IsEBB -> !Word16 -> !Word16 -> BlockInfo blk
[biHash] :: BlockInfo blk -> !HeaderHash blk
[biSlotNo] :: BlockInfo blk -> !SlotNo
[biBlockNo] :: BlockInfo blk -> !BlockNo
[biPrevHash] :: BlockInfo blk -> !ChainHash blk
[biIsEBB] :: BlockInfo blk -> !IsEBB
[biHeaderOffset] :: BlockInfo blk -> !Word16
[biHeaderSize] :: BlockInfo blk -> !Word16

-- | Errors which might arise when working with this database.
data VolatileDBError

-- | An error thrown because of incorrect usage of the VolatileDB by the
--   user.
ApiMisuse :: ApiMisuse -> VolatileDBError

-- | An unexpected failure thrown because something went wrong.
UnexpectedFailure :: UnexpectedFailure -> VolatileDBError
data ApiMisuse

-- | The VolatileDB was closed. In case it was automatically closed because
--   an unexpected error was thrown during a read operation or any
--   exception was thrown during a write operation, that exception is
--   embedded.
ClosedDBError :: Maybe SomeException -> ApiMisuse
data UnexpectedFailure
FileSystemError :: FsError -> UnexpectedFailure

-- | A block failed to parse
ParseError :: FsPath -> RealPoint blk -> DeserialiseFailure -> UnexpectedFailure

-- | When parsing a block we got some trailing data
TrailingDataError :: FsPath -> RealPoint blk -> ByteString -> UnexpectedFailure

-- | Block missing
--   
--   This exception gets thrown when a block that we <i>know</i> it should
--   be in the VolatileDB, nonetheless was not found.
--   
--   This exception will be thrown by <tt>getKnownBlockComponent</tt>.
MissingBlockError :: Proxy blk -> HeaderHash blk -> UnexpectedFailure

-- | A (parsed) block did not pass the integrity check.
--   
--   This exception gets thrown when a block doesn't pass the integrity
--   check done for <a>GetVerifiedBlock</a>.
--   
--   NOTE: we do not check the integrity of a block when it is added to the
--   VolatileDB. While this exception typically means the block has been
--   corrupted, it could also mean the block didn't pass the check at the
--   time it was added.
CorruptBlockError :: Proxy blk -> HeaderHash blk -> UnexpectedFailure

-- | Open the database using the given function, perform the given action
--   using the database, and closes the database using its <a>closeDB</a>
--   function, in case of success or when an exception was raised.
withDB :: (HasCallStack, MonadThrow m) => m (VolatileDB m blk) -> (VolatileDB m blk -> m a) -> m a
getIsMember :: Functor (STM m) => VolatileDB m blk -> STM m (HeaderHash blk -> Bool)
getPredecessor :: Functor (STM m) => VolatileDB m blk -> STM m (HeaderHash blk -> Maybe (ChainHash blk))
getKnownBlockComponent :: (MonadThrow m, HasHeader blk) => VolatileDB m blk -> BlockComponent blk b -> HeaderHash blk -> m b
instance (Ouroboros.Network.Block.StandardHash blk, Data.Typeable.Internal.Typeable blk) => NoThunks.Class.NoThunks (Ouroboros.Consensus.Storage.VolatileDB.API.BlockInfo blk)
instance GHC.Generics.Generic (Ouroboros.Consensus.Storage.VolatileDB.API.BlockInfo blk)
instance Ouroboros.Network.Block.StandardHash blk => GHC.Show.Show (Ouroboros.Consensus.Storage.VolatileDB.API.BlockInfo blk)
instance Ouroboros.Network.Block.StandardHash blk => GHC.Classes.Eq (Ouroboros.Consensus.Storage.VolatileDB.API.BlockInfo blk)
instance NoThunks.Class.NoThunks (Ouroboros.Consensus.Storage.VolatileDB.API.VolatileDB m blk)
instance GHC.Show.Show Ouroboros.Consensus.Storage.VolatileDB.API.ApiMisuse
instance GHC.Show.Show Ouroboros.Consensus.Storage.VolatileDB.API.VolatileDBError
instance GHC.Show.Show Ouroboros.Consensus.Storage.VolatileDB.API.UnexpectedFailure
instance GHC.Exception.Type.Exception Ouroboros.Consensus.Storage.VolatileDB.API.VolatileDBError

module Ouroboros.Consensus.Storage.VolatileDB.Impl.Types

-- | The maximum number of blocks to store per file.
data BlocksPerFile
unBlocksPerFile :: BlocksPerFile -> Word32

-- | Create a <a>BlocksPerFile</a>.
--   
--   PRECONDITION: the given number must be greater than 0, if not, this
--   function will throw an <a>error</a>.
mkBlocksPerFile :: Word32 -> BlocksPerFile

-- | When block validation is enabled, the parser checks for each block a
--   number of properties and stops parsing if it finds any invalid blocks.
data BlockValidationPolicy
NoValidation :: BlockValidationPolicy
ValidateAll :: BlockValidationPolicy

-- | Note that we recover from the error, and thus never throw it as an
--   <tt>Exception</tt>.
--   
--   Defined here instead of in the <tt>Parser</tt> module because
--   <a>TraceEvent</a> depends on it.
data ParseError blk

-- | A block could not be parsed.
BlockReadErr :: ReadIncrementalErr -> ParseError blk

-- | A block was corrupted, e.g., checking its signature and/or hash
--   failed.
BlockCorruptedErr :: HeaderHash blk -> ParseError blk

-- | A block with the same hash occurred twice in the VolatileDB files.
--   
--   We include the file in which it occurred first and the file in which
--   it occured the second time. The two files can be the same.
DuplicatedBlock :: HeaderHash blk -> FsPath -> FsPath -> ParseError blk
data TraceEvent blk
DBAlreadyClosed :: TraceEvent blk
DBAlreadyOpen :: TraceEvent blk
BlockAlreadyHere :: HeaderHash blk -> TraceEvent blk
TruncateCurrentFile :: FsPath -> TraceEvent blk
Truncate :: ParseError blk -> FsPath -> BlockOffset -> TraceEvent blk
InvalidFileNames :: [FsPath] -> TraceEvent blk

-- | The <a>FileId</a> is the unique identifier of each file found in the
--   db. For example, the file <tt>blocks-42.dat</tt> has <a>FileId</a>
--   <tt>42</tt>.
type FileId = Int

-- | We map the header hash of each block to the <a>InternalBlockInfo</a>.
type ReverseIndex blk = Map (HeaderHash blk) (InternalBlockInfo blk)

-- | For each block, we store the set of all blocks which have this block
--   as a predecessor (set of successors).
type SuccessorsIndex blk = Map (ChainHash blk) (Set (HeaderHash blk))
newtype BlockSize
BlockSize :: Word32 -> BlockSize
[unBlockSize] :: BlockSize -> Word32

-- | The offset at which a block is stored in a file.
newtype BlockOffset
BlockOffset :: Word64 -> BlockOffset
[unBlockOffset] :: BlockOffset -> Word64

-- | The internal information the db keeps for each block.
data InternalBlockInfo blk
InternalBlockInfo :: !FsPath -> !BlockOffset -> !BlockSize -> !BlockInfo blk -> !SomeSecond (NestedCtxt Header) blk -> InternalBlockInfo blk
[ibiFile] :: InternalBlockInfo blk -> !FsPath
[ibiBlockOffset] :: InternalBlockInfo blk -> !BlockOffset
[ibiBlockSize] :: InternalBlockInfo blk -> !BlockSize
[ibiBlockInfo] :: InternalBlockInfo blk -> !BlockInfo blk
[ibiNestedCtxt] :: InternalBlockInfo blk -> !SomeSecond (NestedCtxt Header) blk
instance GHC.Show.Show Ouroboros.Consensus.Storage.VolatileDB.Impl.Types.BlocksPerFile
instance GHC.Generics.Generic Ouroboros.Consensus.Storage.VolatileDB.Impl.Types.BlocksPerFile
instance GHC.Classes.Eq Ouroboros.Consensus.Storage.VolatileDB.Impl.Types.BlockValidationPolicy
instance NoThunks.Class.NoThunks Ouroboros.Consensus.Storage.VolatileDB.Impl.Types.BlockSize
instance GHC.Generics.Generic Ouroboros.Consensus.Storage.VolatileDB.Impl.Types.BlockSize
instance GHC.Show.Show Ouroboros.Consensus.Storage.VolatileDB.Impl.Types.BlockSize
instance GHC.Classes.Eq Ouroboros.Consensus.Storage.VolatileDB.Impl.Types.BlockSize
instance NoThunks.Class.NoThunks Ouroboros.Consensus.Storage.VolatileDB.Impl.Types.BlockOffset
instance GHC.Generics.Generic Ouroboros.Consensus.Storage.VolatileDB.Impl.Types.BlockOffset
instance GHC.Show.Show Ouroboros.Consensus.Storage.VolatileDB.Impl.Types.BlockOffset
instance GHC.Classes.Eq Ouroboros.Consensus.Storage.VolatileDB.Impl.Types.BlockOffset
instance Ouroboros.Network.Block.StandardHash blk => GHC.Show.Show (Ouroboros.Consensus.Storage.VolatileDB.Impl.Types.TraceEvent blk)
instance GHC.Generics.Generic (Ouroboros.Consensus.Storage.VolatileDB.Impl.Types.TraceEvent blk)
instance Ouroboros.Network.Block.StandardHash blk => GHC.Classes.Eq (Ouroboros.Consensus.Storage.VolatileDB.Impl.Types.TraceEvent blk)
instance (Ouroboros.Network.Block.StandardHash blk, Data.Typeable.Internal.Typeable blk) => NoThunks.Class.NoThunks (Ouroboros.Consensus.Storage.VolatileDB.Impl.Types.InternalBlockInfo blk)
instance GHC.Generics.Generic (Ouroboros.Consensus.Storage.VolatileDB.Impl.Types.InternalBlockInfo blk)
instance Ouroboros.Network.Block.StandardHash blk => GHC.Classes.Eq (Ouroboros.Consensus.Storage.VolatileDB.Impl.Types.ParseError blk)
instance Ouroboros.Network.Block.StandardHash blk => GHC.Show.Show (Ouroboros.Consensus.Storage.VolatileDB.Impl.Types.ParseError blk)

module Ouroboros.Consensus.Storage.VolatileDB.Impl.Util
parseFd :: FsPath -> Maybe FileId

-- | Parses the <a>FileId</a> of each <a>FsPath</a> and zips them together.
--   Returns the results sorted on the <a>FileId</a>.
--   
--   Return separately any <a>FsPath</a> which failed to parse.
parseAllFds :: [FsPath] -> ([(FileId, FsPath)], [FsPath])
filePath :: FileId -> FsPath

-- | This also returns any <a>FsPath</a> which failed to parse.
findLastFd :: [FsPath] -> (Maybe FileId, [FsPath])
wrapFsError :: MonadCatch m => m a -> m a

-- | Execute an action and catch the <a>VolatileDBError</a> and
--   <a>FsError</a> that can be thrown by it, and wrap the <a>FsError</a>
--   in an <a>VolatileDBError</a> using the <a>FileSystemError</a>
--   constructor.
--   
--   This should be used whenever you want to run an action on the
--   VolatileDB and catch the <a>VolatileDBError</a> and the <a>FsError</a>
--   (wrapped in the former) it may thrown.
tryVolatileDB :: forall m a. MonadCatch m => m a -> m (Either VolatileDBError a)
insertMapSet :: forall k v. (Ord k, Ord v) => k -> v -> Map k (Set v) -> Map k (Set v)
deleteMapSet :: forall k v. (Ord k, Ord v) => k -> v -> Map k (Set v) -> Map k (Set v)


-- | Cache blocks in memory
--   
--   Intended for qualified import.
--   
--   <pre>
--   import           Ouroboros.Consensus.Storage.ChainDB.Impl.BlockCache (BlockCache)
--   import qualified Ouroboros.Consensus.Storage.ChainDB.Impl.BlockCache as BlockCache
--   </pre>
module Ouroboros.Consensus.Storage.ChainDB.Impl.BlockCache
data BlockCache blk
empty :: BlockCache blk
singleton :: HasHeader blk => blk -> BlockCache blk
cacheBlock :: HasHeader blk => blk -> BlockCache blk -> BlockCache blk
lookup :: HasHeader blk => HeaderHash blk -> BlockCache blk -> Maybe blk

module Ouroboros.Consensus.Protocol.LeaderSchedule
newtype LeaderSchedule
LeaderSchedule :: Map SlotNo [CoreNodeId] -> LeaderSchedule
[getLeaderSchedule] :: LeaderSchedule -> Map SlotNo [CoreNodeId]

-- | The <tt>Slots</tt> a given node is supposed to lead in
leaderScheduleFor :: CoreNodeId -> LeaderSchedule -> Set SlotNo

-- | Extension of protocol <tt>p</tt> by a static leader schedule.
data WithLeaderSchedule p

-- | Static configuration required to run the consensus protocol
--   
--   Every method in the <a>ConsensusProtocol</a> class takes the consensus
--   configuration as a parameter, so having this as a data family rather
--   than a type family resolves most ambiguity.
--   
--   Defined out of the class so that protocols can define this type
--   without having to define the entire protocol at the same time (or
--   indeed in the same module).
data family ConsensusConfig p :: Type
instance NoThunks.Class.NoThunks Ouroboros.Consensus.Protocol.LeaderSchedule.LeaderSchedule
instance GHC.Generics.Generic Ouroboros.Consensus.Protocol.LeaderSchedule.LeaderSchedule
instance GHC.Classes.Ord Ouroboros.Consensus.Protocol.LeaderSchedule.LeaderSchedule
instance GHC.Classes.Eq Ouroboros.Consensus.Protocol.LeaderSchedule.LeaderSchedule
instance GHC.Show.Show Ouroboros.Consensus.Protocol.LeaderSchedule.LeaderSchedule
instance GHC.Generics.Generic (Ouroboros.Consensus.Protocol.Abstract.ConsensusConfig (Ouroboros.Consensus.Protocol.LeaderSchedule.WithLeaderSchedule p))
instance Ouroboros.Consensus.Protocol.Abstract.ChainSelection p => Ouroboros.Consensus.Protocol.Abstract.ChainSelection (Ouroboros.Consensus.Protocol.LeaderSchedule.WithLeaderSchedule p)
instance Ouroboros.Consensus.Protocol.Abstract.ConsensusProtocol p => Ouroboros.Consensus.Protocol.Abstract.ConsensusProtocol (Ouroboros.Consensus.Protocol.LeaderSchedule.WithLeaderSchedule p)
instance Ouroboros.Consensus.Protocol.Abstract.ConsensusProtocol p => NoThunks.Class.NoThunks (Ouroboros.Consensus.Protocol.Abstract.ConsensusConfig (Ouroboros.Consensus.Protocol.LeaderSchedule.WithLeaderSchedule p))
instance GHC.Base.Semigroup Ouroboros.Consensus.Protocol.LeaderSchedule.LeaderSchedule
instance Ouroboros.Consensus.Util.Condense.Condense Ouroboros.Consensus.Protocol.LeaderSchedule.LeaderSchedule

module Ouroboros.Consensus.Mempool.API

-- | Mempool
--   
--   The mempool is the set of transactions that should be included in the
--   next block. In principle this is a <i>set</i> of all the transactions
--   that we receive from our peers. In order to avoid flooding the network
--   with invalid transactions, however, we only want to keep <i>valid</i>
--   transactions in the mempool. That raises the question: valid with
--   respect to which ledger state?
--   
--   We opt for a very simple answer to this: the mempool will be
--   interpreted as a <i>list</i> of transactions; which are validated
--   strictly in order, starting from the current ledger state. This has a
--   number of advantages:
--   
--   <ul>
--   <li>It's simple to implement and it's efficient. In particular, no
--   search for a valid subset is ever required.</li>
--   <li>When producing a block, we can simply take the longest possible
--   prefix of transactions that fits in a block.</li>
--   <li>It supports wallets that submit dependent transactions (where
--   later transaction depends on outputs from earlier ones).</li>
--   </ul>
data Mempool m blk idx
Mempool :: ([GenTx blk] -> m ([(GenTx blk, MempoolAddTxResult blk)], [GenTx blk])) -> ([GenTxId blk] -> m ()) -> m (MempoolSnapshot blk idx) -> STM m (MempoolSnapshot blk idx) -> (ForgeLedgerState blk -> STM m (MempoolSnapshot blk idx)) -> STM m MempoolCapacityBytes -> (GenTx blk -> TxSizeInBytes) -> idx -> Mempool m blk idx

-- | Add a bunch of transactions (oldest to newest)
--   
--   As long as we keep the mempool entirely in-memory this could live in
--   <tt>STM m</tt>; we keep it in <tt>m</tt> instead to leave open the
--   possibility of persistence.
--   
--   The new transactions provided will be validated, <i>in order</i>,
--   against the ledger state obtained by applying all the transactions
--   already in the Mempool to it. Transactions which are found to be
--   invalid, with respect to the ledger state, are dropped, whereas valid
--   transactions are added to the mempool.
--   
--   Note that transactions that are invalid, with respect to the ledger
--   state, will <i>never</i> be added to the mempool. However, it is
--   possible that, at a given point in time, transactions which were once
--   valid but are now invalid, with respect to the current ledger state,
--   could exist within the mempool until they are revalidated and dropped
--   from the mempool via a call to <a>syncWithLedger</a> or by the
--   background thread that watches the ledger for changes.
--   
--   This function will return two lists
--   
--   <ol>
--   <li>A list containing the following transactions:</li>
--   </ol>
--   
--   <ul>
--   <li>Those transactions provided which were found to be valid, along
--   with <a>MempoolTxAdded</a> for their accompanying
--   <a>MempoolAddTxResult</a> values. These transactions are now in the
--   Mempool.</li>
--   <li>Those transactions provided which were found to be invalid, along
--   with their accompanying validation errors. These transactions are not
--   in the Mempool.</li>
--   </ul>
--   
--   <ol>
--   <li>A list containing the transactions that have not yet been added
--   yet, as the capacity of the Mempool has been reached. I.e., there is
--   no space in the Mempool to add the first transaction in this list.
--   Note that we won't try to add smaller transactions after that first
--   transaction because they might depend on the first transaction.</li>
--   </ol>
--   
--   POSTCONDITION: &gt; (processed, toProcess) &lt;- tryAddTxs txs &gt;
--   map fst processed ++ toProcess == txs
--   
--   Note that previously valid transaction that are now invalid with
--   respect to the current ledger state are dropped from the mempool, but
--   are not part of the first returned list (nor the second).
--   
--   In principle it is possible that validation errors are transient; for
--   example, it is possible that a transaction is rejected because one of
--   its inputs is not <i>yet</i> available in the UTxO (the transaction it
--   depends on is not yet in the chain, nor in the mempool). In practice
--   however it is likely that rejected transactions will still be rejected
--   later, and should just be dropped.
--   
--   It is important to note one important special case of transactions
--   being "invalid": a transaction will <i>also</i> be considered invalid
--   if <i>that very same transaction</i> is already included on the
--   blockchain (after all, by definition that must mean its inputs have
--   been used). Rejected transactions are therefore not necessarily a sign
--   of malicious behaviour. Indeed, we would expect <i>most</i>
--   transactions that are reported as invalid by <a>tryAddTxs</a> to be
--   invalid precisely because they have already been included.
--   Distinguishing between these two cases can be done in theory, but it
--   is expensive unless we have an index of transaction hashes that have
--   been included on the blockchain.
[tryAddTxs] :: Mempool m blk idx -> [GenTx blk] -> m ([(GenTx blk, MempoolAddTxResult blk)], [GenTx blk])

-- | Manually remove the given transactions from the mempool.
[removeTxs] :: Mempool m blk idx -> [GenTxId blk] -> m ()

-- | Sync the transactions in the mempool with the current ledger state of
--   the <tt>ChainDB</tt>.
--   
--   The transactions that exist within the mempool will be revalidated
--   against the current ledger state. Transactions which are found to be
--   invalid with respect to the current ledger state, will be dropped from
--   the mempool, whereas valid transactions will remain.
--   
--   We keep this in <tt>m</tt> instead of <tt>STM m</tt> to leave open the
--   possibility of persistence. Additionally, this makes it possible to
--   trace the removal of invalid transactions.
--   
--   n.b. in our current implementation, when one opens a mempool, we spawn
--   a thread which performs this action whenever the <tt>ChainDB</tt> tip
--   point changes.
[syncWithLedger] :: Mempool m blk idx -> m (MempoolSnapshot blk idx)

-- | Get a snapshot of the current mempool state. This allows for further
--   pure queries on the snapshot.
--   
--   This doesn't look at the ledger state at all.
[getSnapshot] :: Mempool m blk idx -> STM m (MempoolSnapshot blk idx)

-- | Get a snapshot of the mempool state that is valid with respect to the
--   given ledger state
--   
--   This does not update the state of the mempool.
[getSnapshotFor] :: Mempool m blk idx -> ForgeLedgerState blk -> STM m (MempoolSnapshot blk idx)

-- | Get the mempool's capacity in bytes.
--   
--   Note that the capacity of the Mempool, unless it is overridden with
--   <tt>MempoolCapacityBytesOverride</tt>, can dynamically change when the
--   ledger state is updated: it will be set to twice the current ledger's
--   maximum transaction capacity of a block.
--   
--   When the capacity happens to shrink at some point, we <i>do not</i>
--   remove transactions from the Mempool to satisfy this new lower limit.
--   Instead, we treat it the same way as a Mempool which is <i>at</i>
--   capacity, i.e., we won't admit new transactions until some have been
--   removed because they have become invalid.
[getCapacity] :: Mempool m blk idx -> STM m MempoolCapacityBytes

-- | Return the post-serialisation size in bytes of a <a>GenTx</a>.
[getTxSize] :: Mempool m blk idx -> GenTx blk -> TxSizeInBytes

-- | Represents the initial value at which the transaction ticket number
--   counter will start (i.e. the zeroth ticket number).
[zeroIdx] :: Mempool m blk idx -> idx

-- | Wrapper around <tt>implTryAddTxs</tt> that blocks until all
--   transaction have either been added to the Mempool or rejected.
--   
--   This function does not sync the Mempool contents with the ledger state
--   in case the latter changes, it relies on the background thread to do
--   that.
--   
--   POSTCONDITON: &gt; processed &lt;- addTxs mpEnv txs &gt; map fst
--   processed == txs
addTxs :: forall m blk idx. MonadSTM m => Mempool m blk idx -> [GenTx blk] -> m [(GenTx blk, MempoolAddTxResult blk)]

-- | The ledger state wrt to which we should produce a block
--   
--   The transactions in the mempool will be part of the body of a block,
--   but a block consists of a header and a body, and the full validation
--   of a block consists of first processing its header and only then
--   processing the body. This is important, because processing the header
--   may change the state of the ledger: the update system might be
--   updated, scheduled delegations might be applied, etc., and such
--   changes should take effect before we validate any transactions.
data ForgeLedgerState blk

-- | The slot number of the block is known
--   
--   This will only be the case when we realized that we are the slot
--   leader and we are actually producing a block. It is the caller's
--   responsibility to call <a>applyChainTick</a> and produce the ticked
--   ledger state.
ForgeInKnownSlot :: SlotNo -> TickedLedgerState blk -> ForgeLedgerState blk

-- | The slot number of the block is not yet known
--   
--   When we are validating transactions before we know in which block they
--   will end up, we have to make an assumption about which slot number to
--   use for <a>applyChainTick</a> to prepare the ledger state; we will
--   assume that they will end up in the slot after the slot at the tip of
--   the ledger.
ForgeInUnknownSlot :: LedgerState blk -> ForgeLedgerState blk

-- | Represents the maximum number of bytes worth of transactions that a
--   <a>Mempool</a> can contain.
newtype MempoolCapacityBytes
MempoolCapacityBytes :: Word32 -> MempoolCapacityBytes
[getMempoolCapacityBytes] :: MempoolCapacityBytes -> Word32

-- | A pure snapshot of the contents of the mempool. It allows fetching
--   information about transactions in the mempool, and fetching individual
--   transactions.
--   
--   This uses a transaction sequence number type for identifying
--   transactions within the mempool sequence. The sequence number is local
--   to this mempool, unlike the transaction hash. This allows us to ask
--   for all transactions after a known sequence number, to get new
--   transactions. It is also used to look up individual transactions.
--   
--   Note that it is expected that <tt>getTx</tt> will often return
--   <a>Nothing</a> even for tx sequence numbers returned in previous
--   snapshots. This happens when the transaction has been removed from the
--   mempool between snapshots.
data MempoolSnapshot blk idx
MempoolSnapshot :: [(GenTx blk, idx)] -> (idx -> [(GenTx blk, idx)]) -> (Word32 -> [(GenTx blk, idx)]) -> (idx -> Maybe (GenTx blk)) -> (GenTxId blk -> Bool) -> MempoolSize -> SlotNo -> TickedLedgerState blk -> MempoolSnapshot blk idx

-- | Get all transactions (oldest to newest) in the mempool snapshot along
--   with their ticket number.
[snapshotTxs] :: MempoolSnapshot blk idx -> [(GenTx blk, idx)]

-- | Get all transactions (oldest to newest) in the mempool snapshot, along
--   with their ticket number, which are associated with a ticket number
--   greater than the one provided.
[snapshotTxsAfter] :: MempoolSnapshot blk idx -> idx -> [(GenTx blk, idx)]

-- | Get as many transactions (oldest to newest) from the mempool snapshot,
--   along with their ticket number, such that their combined size is &lt;=
--   the given limit (in bytes).
[snapshotTxsForSize] :: MempoolSnapshot blk idx -> Word32 -> [(GenTx blk, idx)]

-- | Get a specific transaction from the mempool snapshot by its ticket
--   number, if it exists.
[snapshotLookupTx] :: MempoolSnapshot blk idx -> idx -> Maybe (GenTx blk)

-- | Determine whether a specific transaction exists within the mempool
--   snapshot.
[snapshotHasTx] :: MempoolSnapshot blk idx -> GenTxId blk -> Bool

-- | Get the size of the mempool snapshot.
[snapshotMempoolSize] :: MempoolSnapshot blk idx -> MempoolSize

-- | The block number of the "virtual block" under construction
[snapshotSlotNo] :: MempoolSnapshot blk idx -> SlotNo

-- | The ledger state after all transactions in the snapshot
[snapshotLedgerState] :: MempoolSnapshot blk idx -> TickedLedgerState blk

-- | The result of attempting to add a transaction to the mempool.
data MempoolAddTxResult blk

-- | The transaction was added to the mempool.
MempoolTxAdded :: MempoolAddTxResult blk

-- | The transaction was rejected and could not be added to the mempool for
--   the specified reason.
MempoolTxRejected :: !ApplyTxErr blk -> MempoolAddTxResult blk
isMempoolTxAdded :: MempoolAddTxResult blk -> Bool
isMempoolTxRejected :: MempoolAddTxResult blk -> Bool

-- | The size of a mempool.
data MempoolSize
MempoolSize :: !Word32 -> !Word32 -> MempoolSize

-- | The number of transactions in the mempool.
[msNumTxs] :: MempoolSize -> !Word32

-- | The summed byte size of all the transactions in the mempool.
[msNumBytes] :: MempoolSize -> !Word32

-- | Events traced by the Mempool.
data TraceEventMempool blk
TraceMempoolAddedTx :: !GenTx blk -> !MempoolSize -> !MempoolSize -> TraceEventMempool blk
TraceMempoolRejectedTx :: !GenTx blk -> !ApplyTxErr blk -> !MempoolSize -> TraceEventMempool blk
TraceMempoolRemoveTxs :: ![GenTx blk] -> !MempoolSize -> TraceEventMempool blk
TraceMempoolManuallyRemovedTxs :: ![GenTxId blk] -> ![GenTx blk] -> !MempoolSize -> TraceEventMempool blk
type TxSizeInBytes = Word32
instance NoThunks.Class.NoThunks Ouroboros.Consensus.Mempool.API.MempoolCapacityBytes
instance GHC.Show.Show Ouroboros.Consensus.Mempool.API.MempoolCapacityBytes
instance GHC.Classes.Eq Ouroboros.Consensus.Mempool.API.MempoolCapacityBytes
instance GHC.Show.Show Ouroboros.Consensus.Mempool.API.MempoolSize
instance GHC.Classes.Eq Ouroboros.Consensus.Mempool.API.MempoolSize
instance GHC.Classes.Eq (Ouroboros.Consensus.Ledger.SupportsMempool.ApplyTxErr blk) => GHC.Classes.Eq (Ouroboros.Consensus.Mempool.API.MempoolAddTxResult blk)
instance GHC.Show.Show (Ouroboros.Consensus.Ledger.SupportsMempool.ApplyTxErr blk) => GHC.Show.Show (Ouroboros.Consensus.Mempool.API.MempoolAddTxResult blk)
instance (GHC.Classes.Eq (Ouroboros.Consensus.Ledger.SupportsMempool.GenTx blk), GHC.Classes.Eq (Ouroboros.Consensus.Ledger.SupportsMempool.GenTxId blk), GHC.Classes.Eq (Ouroboros.Consensus.Ledger.SupportsMempool.ApplyTxErr blk)) => GHC.Classes.Eq (Ouroboros.Consensus.Mempool.API.TraceEventMempool blk)
instance (GHC.Show.Show (Ouroboros.Consensus.Ledger.SupportsMempool.GenTx blk), GHC.Show.Show (Ouroboros.Consensus.Ledger.SupportsMempool.GenTxId blk), GHC.Show.Show (Ouroboros.Consensus.Ledger.SupportsMempool.ApplyTxErr blk)) => GHC.Show.Show (Ouroboros.Consensus.Mempool.API.TraceEventMempool blk)
instance GHC.Base.Semigroup Ouroboros.Consensus.Mempool.API.MempoolSize
instance GHC.Base.Monoid Ouroboros.Consensus.Mempool.API.MempoolSize

module Ouroboros.Consensus.MiniProtocol.LocalTxSubmission.Server

-- | Local transaction submission server, for adding txs to the
--   <a>Mempool</a>
localTxSubmissionServer :: MonadSTM m => Tracer m (TraceLocalTxSubmissionServerEvent blk) -> Mempool m blk idx -> LocalTxSubmissionServer (GenTx blk) (ApplyTxErr blk) m ()
data TraceLocalTxSubmissionServerEvent blk

-- | A transaction was received.
TraceReceivedTx :: GenTx blk -> TraceLocalTxSubmissionServerEvent blk
instance GHC.Classes.Eq (Ouroboros.Consensus.Ledger.SupportsMempool.GenTx blk) => GHC.Classes.Eq (Ouroboros.Consensus.MiniProtocol.LocalTxSubmission.Server.TraceLocalTxSubmissionServerEvent blk)
instance GHC.Show.Show (Ouroboros.Consensus.Ledger.SupportsMempool.GenTx blk) => GHC.Show.Show (Ouroboros.Consensus.MiniProtocol.LocalTxSubmission.Server.TraceLocalTxSubmissionServerEvent blk)


-- | Intended for qualified import.
--   
--   <pre>
--   import           Ouroboros.Consensus.Mempool.TxSeq (TxSeq (..))
--   import qualified Ouroboros.Consensus.Mempool.TxSeq as TxSeq
--   </pre>
module Ouroboros.Consensus.Mempool.TxSeq

-- | We allocate each transaction a (monotonically increasing) ticket
--   number as it enters the mempool.
newtype TicketNo
TicketNo :: Word64 -> TicketNo

-- | We associate transactions in the mempool with their ticket number and
--   size in bytes.
data TxTicket tx
TxTicket :: !tx -> !TicketNo -> !TxSizeInBytes -> TxTicket tx

-- | The transaction associated with this ticket.
[txTicketTx] :: TxTicket tx -> !tx

-- | The ticket number.
[txTicketNo] :: TxTicket tx -> !TicketNo

-- | The byte size of the transaction (<a>txTicketTx</a>) associated with
--   this ticket.
[txTicketTxSizeInBytes] :: TxTicket tx -> !TxSizeInBytes

-- | The mempool is a sequence of transactions with their ticket numbers
--   and size in bytes.
--   
--   Transactions are allocated monotonically increasing ticket numbers as
--   they are appended to the mempool sequence. Transactions can be removed
--   from any position, not just the front.
--   
--   The sequence is thus ordered by the ticket numbers. We can use the
--   ticket numbers as a compact representation for a "reader" location in
--   the sequence. If a reader knows it has seen all txs with a lower
--   ticket number then it is only interested in transactions with higher
--   ticket numbers.
--   
--   The mempool sequence is represented by a fingertree. We use a
--   fingertree measure to allow not just normal sequence operations but
--   also efficient splitting and indexing by the ticket number.
data TxSeq tx

-- | An empty mempool sequence.
pattern Empty :: TxSeq tx

-- | &lt;math&gt;. Access or add a tx at the back of the mempool sequence.
--   
--   New txs are always added at the back.
pattern (:>) :: TxSeq tx -> TxTicket tx -> TxSeq tx

-- | &lt;math&gt;. Access a tx at the front of the mempool sequence.
--   
--   Note that we never add txs at the front. We access txs from front to
--   back when forwarding txs to other peers, or when adding txs to blocks.
pattern (:<) :: TxTicket tx -> TxSeq tx -> TxSeq tx
infixl 5 :>
infixl 5 :<

-- | Given a list of <a>TxTicket</a>s, construct a <a>TxSeq</a>.
fromList :: [TxTicket tx] -> TxSeq tx

-- | Convert a <a>TxSeq</a> to a list of <a>TxTicket</a>s.
toList :: TxSeq tx -> [TxTicket tx]

-- | Convert a <a>TxSeq</a> to a list of pairs of transactions and their
--   associated <a>TicketNo</a>s.
toTuples :: TxSeq tx -> [(tx, TicketNo)]

-- | &lt;math&gt;. Look up a transaction in the sequence by its
--   <a>TicketNo</a>.
lookupByTicketNo :: TxSeq tx -> TicketNo -> Maybe tx

-- | &lt;math&gt;. Split the sequence of transactions into two parts based
--   on the given <a>TicketNo</a>. The first part has transactions with
--   tickets less than or equal to the given ticket, and the second part
--   has transactions with tickets strictly greater than the given ticket.
splitAfterTicketNo :: TxSeq tx -> TicketNo -> (TxSeq tx, TxSeq tx)

-- | &lt;math&gt;. Split the sequence of transactions into two parts based
--   on the given <a>TxSizeInBytes</a>. The first part has transactions
--   whose summed <a>TxSizeInBytes</a> is less than or equal to the given
--   <a>TxSizeInBytes</a>, and the second part has the remaining
--   transactions in the sequence.
splitAfterTxSize :: TxSeq tx -> TxSizeInBytes -> (TxSeq tx, TxSeq tx)

-- | The transaction ticket number from which our counter starts.
zeroTicketNo :: TicketNo

-- | &lt;math&gt;. Return the <a>MempoolSize</a> of the given <a>TxSeq</a>.
toMempoolSize :: TxSeq tx -> MempoolSize

-- | &lt;math&gt;. Specification of <a>splitAfterTxSize</a>.
--   
--   Use <a>splitAfterTxSize</a> as it should be faster.
--   
--   This function is used to verify whether <a>splitAfterTxSize</a>
--   behaves as expected.
splitAfterTxSizeSpec :: TxSeq tx -> TxSizeInBytes -> (TxSeq tx, TxSeq tx)
instance NoThunks.Class.NoThunks Ouroboros.Consensus.Mempool.TxSeq.TicketNo
instance GHC.Enum.Bounded Ouroboros.Consensus.Mempool.TxSeq.TicketNo
instance GHC.Enum.Enum Ouroboros.Consensus.Mempool.TxSeq.TicketNo
instance GHC.Show.Show Ouroboros.Consensus.Mempool.TxSeq.TicketNo
instance GHC.Classes.Ord Ouroboros.Consensus.Mempool.TxSeq.TicketNo
instance GHC.Classes.Eq Ouroboros.Consensus.Mempool.TxSeq.TicketNo
instance NoThunks.Class.NoThunks tx => NoThunks.Class.NoThunks (Ouroboros.Consensus.Mempool.TxSeq.TxTicket tx)
instance GHC.Generics.Generic (Ouroboros.Consensus.Mempool.TxSeq.TxTicket tx)
instance GHC.Show.Show tx => GHC.Show.Show (Ouroboros.Consensus.Mempool.TxSeq.TxTicket tx)
instance GHC.Classes.Eq tx => GHC.Classes.Eq (Ouroboros.Consensus.Mempool.TxSeq.TxTicket tx)
instance GHC.Show.Show Ouroboros.Consensus.Mempool.TxSeq.TxSeqMeasure
instance NoThunks.Class.NoThunks tx => NoThunks.Class.NoThunks (Ouroboros.Consensus.Mempool.TxSeq.TxSeq tx)
instance GHC.Show.Show tx => GHC.Show.Show (Ouroboros.Consensus.Mempool.TxSeq.TxSeq tx)
instance Data.Foldable.Foldable Ouroboros.Consensus.Mempool.TxSeq.TxSeq
instance Data.FingerTree.Measured Ouroboros.Consensus.Mempool.TxSeq.TxSeqMeasure (Ouroboros.Consensus.Mempool.TxSeq.TxTicket tx)
instance GHC.Base.Semigroup Ouroboros.Consensus.Mempool.TxSeq.TxSeqMeasure
instance GHC.Base.Monoid Ouroboros.Consensus.Mempool.TxSeq.TxSeqMeasure

module Ouroboros.Consensus.HardFork.History.Util
addSlots :: Word64 -> SlotNo -> SlotNo
subSlots :: Word64 -> SlotNo -> SlotNo
addEpochs :: Word64 -> EpochNo -> EpochNo

-- | <tt>countSlots to fr</tt> counts the slots from <tt>fr</tt> to
--   <tt>to</tt> (<tt>to &gt;= fr</tt>)
countSlots :: HasCallStack => SlotNo -> SlotNo -> Word64

-- | <tt>countEpochs to fr</tt> counts the epochs from <tt>fr</tt> to
--   <tt>to</tt> (<tt>to &gt;= fr</tt>)
countEpochs :: HasCallStack => EpochNo -> EpochNo -> Word64

module Ouroboros.Consensus.HardFork.History.EraParams

-- | Parameters that can vary across hard forks
data EraParams
EraParams :: !EpochSize -> !SlotLength -> !SafeZone -> EraParams
[eraEpochSize] :: EraParams -> !EpochSize
[eraSlotLength] :: EraParams -> !SlotLength
[eraSafeZone] :: EraParams -> !SafeZone

-- | Zone in which it is guaranteed that no hard fork can take place
data SafeZone

-- | Standard safe zone
--   
--   We record
--   
--   <ul>
--   <li>Number of slots from the tip of the ledger. This should be (at
--   least) the number of slots in which we are guaranteed to have
--   <tt>k</tt> blocks.</li>
--   <li>Optionally, an <a>EpochNo</a> before which no hard fork can take
--   place.</li>
--   </ul>
StandardSafeZone :: !Word64 -> !SafeBeforeEpoch -> SafeZone

-- | Pretend the transition to the next era will not take place.
--   
--   This constructor is marked as unsafe because it effectively extends
--   the safe zone of this era indefinitely into the future. This means
--   that we might reach invalid conclusions when doing
--   
--   <ul>
--   <li>slot to time conversions for blocks that are past the actual safe
--   zone</li>
--   <li>time to slot conversions for the current time, when behind in
--   syncing</li>
--   </ul>
--   
--   This is safe when the code is simply not yet ready to transition to
--   the next era, because in that case, we can be sure that blocks that
--   come in are still from this era. It also means that we can always
--   <i>produce</i> a block, no matter how far ahead of the current ledger
--   we are.
--   
--   If the code is ready for the transition, just awaiting an update
--   proposal, then <a>LowerBound</a> can be used instead.
--   
--   This constructor can be regarded as an " extreme " version of
--   <a>LowerBound</a>, and can be used for similar reasons.
UnsafeIndefiniteSafeZone :: SafeZone

-- | Lower bound on when a transition can take place
data SafeBeforeEpoch

-- | No such lower bound is known
NoLowerBound :: SafeBeforeEpoch

-- | <a>EpochNo</a> before which a transition is guaranteed not to take
--   place
--   
--   Often such a value is available, since a new era is planned only after
--   the current era has already been running for a while. For example, at
--   the time of writing, we know the Byron to Shelley transition cannot
--   happen before epoch 180, since we are currently already in epoch 179.
--   
--   Moreover, for epoch transitions that have <i>already</i> taken place,
--   the exact <a>EpochNo</a> of the transition can be used.
--   
--   Providing this value is strictly an optimization; for example, it will
--   reduce the frequency with which <tt>summaryToEpochInfo</tt> must
--   update its summary of the hard fork history.
LowerBound :: !EpochNo -> SafeBeforeEpoch

-- | The safe zone with given <tt>safeFromTip</tt> and <a>NoLowerBound</a>
noLowerBoundSafeZone :: Word64 -> SafeZone

-- | Default <a>EraParams</a>
--   
--   We set
--   
--   <ul>
--   <li>epoch size to <tt>10k</tt> slots</li>
--   <li>the safe zone to <tt>2k</tt> slots</li>
--   <li>the upper bound to <a>NoLowerBound</a></li>
--   </ul>
--   
--   This is primarily useful for tests.
defaultEraParams :: SecurityParam -> SlotLength -> EraParams

-- | Returns <a>Nothing</a> if the era is unbounded.
safeBeforeEpoch :: SafeZone -> Maybe SafeBeforeEpoch
maxSafeBeforeEpoch :: SafeBeforeEpoch -> EpochNo -> EpochNo
instance NoThunks.Class.NoThunks Ouroboros.Consensus.HardFork.History.EraParams.SafeBeforeEpoch
instance GHC.Generics.Generic Ouroboros.Consensus.HardFork.History.EraParams.SafeBeforeEpoch
instance GHC.Classes.Eq Ouroboros.Consensus.HardFork.History.EraParams.SafeBeforeEpoch
instance GHC.Show.Show Ouroboros.Consensus.HardFork.History.EraParams.SafeBeforeEpoch
instance NoThunks.Class.NoThunks Ouroboros.Consensus.HardFork.History.EraParams.SafeZone
instance GHC.Generics.Generic Ouroboros.Consensus.HardFork.History.EraParams.SafeZone
instance GHC.Classes.Eq Ouroboros.Consensus.HardFork.History.EraParams.SafeZone
instance GHC.Show.Show Ouroboros.Consensus.HardFork.History.EraParams.SafeZone
instance NoThunks.Class.NoThunks Ouroboros.Consensus.HardFork.History.EraParams.EraParams
instance GHC.Generics.Generic Ouroboros.Consensus.HardFork.History.EraParams.EraParams
instance GHC.Classes.Eq Ouroboros.Consensus.HardFork.History.EraParams.EraParams
instance GHC.Show.Show Ouroboros.Consensus.HardFork.History.EraParams.EraParams
instance Codec.Serialise.Class.Serialise Ouroboros.Consensus.HardFork.History.EraParams.EraParams
instance Codec.Serialise.Class.Serialise Ouroboros.Consensus.HardFork.History.EraParams.SafeZone
instance Codec.Serialise.Class.Serialise Ouroboros.Consensus.HardFork.History.EraParams.SafeBeforeEpoch

module Ouroboros.Consensus.HardFork.Combinator.PartialConfig

-- | Partial consensus config
class (ConsensusProtocol p, NoThunks (PartialConsensusConfig p)) => HasPartialConsensusConfig p where {
    type family PartialConsensusConfig p :: Type;
    type PartialConsensusConfig p = ConsensusConfig p;
}

-- | Construct <a>ConsensusConfig</a> from <a>PartialConsensusConfig</a>
--   
--   See comments for <a>completeLedgerConfig</a> for some details about
--   the <a>EpochInfo</a>.
completeConsensusConfig :: HasPartialConsensusConfig p => proxy p -> EpochInfo Identity -> PartialConsensusConfig p -> ConsensusConfig p

-- | Construct <a>ConsensusConfig</a> from <a>PartialConsensusConfig</a>
--   
--   See comments for <a>completeLedgerConfig</a> for some details about
--   the <a>EpochInfo</a>.
completeConsensusConfig :: (HasPartialConsensusConfig p, PartialConsensusConfig p ~ ConsensusConfig p) => proxy p -> EpochInfo Identity -> PartialConsensusConfig p -> ConsensusConfig p

-- | The <a>ChainSelConfig</a> must be derivable from the partial config
partialChainSelConfig :: HasPartialConsensusConfig p => proxy p -> PartialConsensusConfig p -> ChainSelConfig p

-- | The <a>ChainSelConfig</a> must be derivable from the partial config
partialChainSelConfig :: (HasPartialConsensusConfig p, PartialConsensusConfig p ~ ConsensusConfig p) => proxy p -> PartialConsensusConfig p -> ChainSelConfig p

-- | Partial ledger config
class (UpdateLedger blk, NoThunks (PartialLedgerConfig blk)) => HasPartialLedgerConfig blk where {
    type family PartialLedgerConfig blk :: Type;
    type PartialLedgerConfig blk = LedgerConfig blk;
}

-- | Construct <a>LedgerConfig</a> from <tt>PartialLedgerCfg</tt>
--   
--   NOTE: The <a>EpochInfo</a> provided will have limited range, any
--   attempt to look past its horizon will result in a pure
--   <tt>PastHorizonException</tt>. The horizon is determined by the tip of
--   the ledger <i>state</i> (not view) from which the <a>EpochInfo</a> is
--   derived.
--   
--   TODO: This should not be Identity; see
--   <a>https://github.com/input-output-hk/ouroboros-network/issues/2126</a>
completeLedgerConfig :: HasPartialLedgerConfig blk => proxy blk -> EpochInfo Identity -> PartialLedgerConfig blk -> LedgerConfig blk

-- | Construct <a>LedgerConfig</a> from <tt>PartialLedgerCfg</tt>
--   
--   NOTE: The <a>EpochInfo</a> provided will have limited range, any
--   attempt to look past its horizon will result in a pure
--   <tt>PastHorizonException</tt>. The horizon is determined by the tip of
--   the ledger <i>state</i> (not view) from which the <a>EpochInfo</a> is
--   derived.
--   
--   TODO: This should not be Identity; see
--   <a>https://github.com/input-output-hk/ouroboros-network/issues/2126</a>
completeLedgerConfig :: (HasPartialLedgerConfig blk, PartialLedgerConfig blk ~ LedgerConfig blk) => proxy blk -> EpochInfo Identity -> PartialLedgerConfig blk -> LedgerConfig blk
newtype WrapPartialLedgerConfig blk
WrapPartialLedgerConfig :: PartialLedgerConfig blk -> WrapPartialLedgerConfig blk
[unwrapPartialLedgerConfig] :: WrapPartialLedgerConfig blk -> PartialLedgerConfig blk
newtype WrapPartialConsensusConfig blk
WrapPartialConsensusConfig :: PartialConsensusConfig (BlockProtocol blk) -> WrapPartialConsensusConfig blk
[unwrapPartialConsensusConfig] :: WrapPartialConsensusConfig blk -> PartialConsensusConfig (BlockProtocol blk)

-- | Information about epochs
--   
--   Epochs may have different sizes at different times during the lifetime
--   of the blockchain. This information is encapsulated by
--   <a>EpochInfo</a>; it is parameterized over a monad <tt>m</tt> because
--   the information about how long each epoch is may depend on information
--   derived from the blockchain itself, and hence requires access to
--   state.
--   
--   The other functions provide some derived information from epoch sizes.
--   In the default implementation all of these functions query and update
--   an internal cache maintaining cumulative epoch sizes; for that reason,
--   all of these functions live in a monad <tt>m</tt>.
data EpochInfo (m :: Type -> Type)
EpochInfo :: (HasCallStack => EpochNo -> m EpochSize) -> (HasCallStack => EpochNo -> m SlotNo) -> (HasCallStack => SlotNo -> m EpochNo) -> EpochInfo (m :: Type -> Type)

-- | Return the size of the given epoch as a number of slots
--   
--   Note that the number of slots does <i>not</i> bound the number of
--   blocks, since the EBB and a regular block share a slot number.
[epochInfoSize_] :: EpochInfo (m :: Type -> Type) -> HasCallStack => EpochNo -> m EpochSize

-- | First slot in the specified epoch
--   
--   See also <a>epochInfoRange</a>
[epochInfoFirst_] :: EpochInfo (m :: Type -> Type) -> HasCallStack => EpochNo -> m SlotNo

-- | Epoch containing the given slot
--   
--   We should have the property that
--   
--   <pre>
--   s `inRange` epochInfoRange (epochInfoEpoch s)
--   </pre>
[epochInfoEpoch_] :: EpochInfo (m :: Type -> Type) -> HasCallStack => SlotNo -> m EpochNo

-- | Identity functor and monad. (a non-strict monad)
newtype Identity a
Identity :: a -> Identity a
[runIdentity] :: Identity a -> a
instance NoThunks.Class.NoThunks (Ouroboros.Consensus.HardFork.Combinator.PartialConfig.PartialLedgerConfig blk) => NoThunks.Class.NoThunks (Ouroboros.Consensus.HardFork.Combinator.PartialConfig.WrapPartialLedgerConfig blk)
instance NoThunks.Class.NoThunks (Ouroboros.Consensus.HardFork.Combinator.PartialConfig.PartialConsensusConfig (Ouroboros.Consensus.Block.Abstract.BlockProtocol blk)) => NoThunks.Class.NoThunks (Ouroboros.Consensus.HardFork.Combinator.PartialConfig.WrapPartialConsensusConfig blk)


-- | Intended for qualified import
--   
--   <pre>
--   import Ouroboros.Consensus.Fragment.Diff (ChainDiff (..))
--   import qualified Ouroboros.Consensus.Fragment.Diff as Diff
--   </pre>
module Ouroboros.Consensus.Fragment.Diff

-- | A diff of a chain (fragment).
--   
--   Typical instantiations of the type argument <tt>b</tt>: a block type
--   <tt>blk</tt>, <tt>Header blk</tt>, <tt>HeaderFields</tt>, ...,
--   anything that supports <a>HasHeader</a>.
--   
--   Note: we allow the suffix to be shorter than the number of blocks to
--   roll back. In other words, applying a <a>ChainDiff</a> can result in a
--   chain shorter than the chain to which the diff was applied.
data ChainDiff b
ChainDiff :: !Word64 -> !AnchoredFragment b -> ChainDiff b

-- | The number of blocks/headers to roll back the current chain
[getRollback] :: ChainDiff b -> !Word64

-- | The new blocks/headers to add after rolling back the current chain.
[getSuffix] :: ChainDiff b -> !AnchoredFragment b

-- | Return the tip of the new suffix
getTip :: HasHeader b => ChainDiff b -> Point b

-- | Return the anchor point of the new suffix
getAnchorPoint :: ChainDiff b -> Point b

-- | Return <a>True</a> iff applying the <a>ChainDiff</a> to a chain
--   <tt>C</tt> will result in a chain shorter than <tt>C</tt>, i.e., the
--   number of blocks to roll back is greater than the length of the new
--   elements in the suffix to add.
rollbackExceedsSuffix :: HasHeader b => ChainDiff b -> Bool

-- | Make an extension-only (no rollback) <a>ChainDiff</a>.
extend :: AnchoredFragment b -> ChainDiff b

-- | Diff a candidate chain with the current chain.
--   
--   If the candidate fragment is shorter than the current chain,
--   <a>Nothing</a> is returned (this would violate the invariant of
--   <a>ChainDiff</a>).
--   
--   PRECONDITION: the candidate fragment must intersect with the current
--   chain fragment.
diff :: (HasHeader b, HasCallStack) => AnchoredFragment b -> AnchoredFragment b -> ChainDiff b

-- | Apply the <a>ChainDiff</a> on the given chain fragment.
--   
--   The fragment is first rolled back a number of blocks before appending
--   the new suffix.
--   
--   If the <a>ChainDiff</a> doesn't fit (anchor point mismatch),
--   <a>Nothing</a> is returned.
--   
--   The returned fragment will have the same anchor point as the given
--   fragment.
apply :: HasHeader b => AnchoredFragment b -> ChainDiff b -> Maybe (AnchoredFragment b)

-- | Append a <tt>b</tt> to a <a>ChainDiff</a>.
--   
--   PRECONDITION: it must fit onto the end of the suffix.
append :: HasHeader b => ChainDiff b -> b -> ChainDiff b

-- | Truncate the diff by rolling back the new suffix to the given point.
--   
--   PRECONDITION: the given point must correspond to one of the new
--   blocks/headers of the new suffix or its anchor (i.e,
--   <tt><a>withinFragmentBounds</a> pt (getSuffix diff)</tt>).
--   
--   If the length of the truncated suffix is shorter than the rollback,
--   <a>Nothing</a> is returned.
truncate :: (HasHeader b, HasCallStack) => Point b -> ChainDiff b -> ChainDiff b

-- | Return the longest prefix of the suffix matching the given predicate,
--   starting from the left, i.e., the "oldest" blocks.
--   
--   If the new suffix is shorter than the diff's rollback, return
--   <a>Nothing</a>.
takeWhileOldest :: HasHeader b => (b -> Bool) -> ChainDiff b -> ChainDiff b
mapM :: forall a b m. (HasHeader b, HeaderHash a ~ HeaderHash b, Monad m) => (a -> m b) -> ChainDiff a -> m (ChainDiff b)
instance (Ouroboros.Network.Block.StandardHash b, GHC.Classes.Eq b) => GHC.Classes.Eq (Ouroboros.Consensus.Fragment.Diff.ChainDiff b)
instance (Ouroboros.Network.Block.StandardHash b, GHC.Show.Show b) => GHC.Show.Show (Ouroboros.Consensus.Fragment.Diff.ChainDiff b)

module Ouroboros.Consensus.Forecast

-- | Forecast the effect of time ticking
data Forecast a
Forecast :: WithOrigin SlotNo -> (SlotNo -> Except OutsideForecastRange (Ticked a)) -> Forecast a
[forecastAt] :: Forecast a -> WithOrigin SlotNo
[forecastFor] :: Forecast a -> SlotNo -> Except OutsideForecastRange (Ticked a)
mapForecast :: (Ticked a -> Ticked b) -> Forecast a -> Forecast b

-- | Trivial forecast of values of type <tt>()</tt> performed by an
--   instance of <a>GetTip</a>.
--   
--   Specialization of <tt>constantForecast</tt>.
trivialForecast :: GetTip b => b -> Forecast ()

-- | Forecast where the values are never changing
--   
--   This is primarily useful for tests; the forecast range is infinite,
--   but we do still check the precondition, to catch any bugs.
constantForecastOf :: Ticked a -> WithOrigin SlotNo -> Forecast a
data OutsideForecastRange
OutsideForecastRange :: !WithOrigin SlotNo -> !SlotNo -> !SlotNo -> OutsideForecastRange

-- | The slot for which the forecast was obtained
[outsideForecastAt] :: OutsideForecastRange -> !WithOrigin SlotNo

-- | Exclusive upper bound on the range of the forecast
[outsideForecastMaxFor] :: OutsideForecastRange -> !SlotNo

-- | The slot for which we requested a value
[outsideForecastFor] :: OutsideForecastRange -> !SlotNo

-- | Compute the upper bound for a range for a forecast across eras.
--   
--   We have to be very careful here in how we compute the maximum
--   lookahead. As long as we are in a single era, things look like this:
--   
--   <pre>
--                                            /-------------------\
--                                            |                   |
--   chain     ... - block - block - block [block]                |
--                                     |                          v
--   ledger                           TIP                  VIEW
--   </pre>
--   
--   where <tt>TIP</tt> is the current ledger tip and <tt>VIEW</tt> is the
--   last ledger view we can forecast, because the next block
--   <tt>[block]</tt> to arrive will take effect in the next leger state
--   after <tt>VIEW</tt>. Note that if the maximum lookahead is zero, this
--   looks like
--   
--   <pre>
--   chain     ... - block - block - block [block]
--                                     |      |
--   ledger                           TIP
--   </pre>
--   
--   where <tt>[block]</tt> can have immediate changes on the ledger, and
--   so we can't look ahead at all (of course, we always know the
--   <i>current</i> <tt>TIP</tt>).
--   
--   Note that blocks arriving <i>after</i> <tt>[block]</tt> can only take
--   effect <i>later</i> than <tt>[block]</tt>, and so they are not
--   relevant for computing the maximum slot number we can compute a ledger
--   view for.
--   
--   Now, if we are near an era transition, this picture gets a bit more
--   complicated. <i>If</i> the next block is still in this era (that is,
--   unless we are <i>right</i> at the edge), then that imposes <i>one</i>
--   constraint, as before. However, the first block in the <i>next</i> era
--   imposes an <i>additional</i> constraint:
--   
--   <pre>
--                        ~
--                        ~    /------------------\
--                        ~    |                  |
--            /---------- ~ ---|----------\       |
--            |           ~    |          |       |
--   block [block]        ~ [block']      |       |
--     |                  ~               v       v
--    TIP                 ~         VIEW
--                        ~
--   </pre>
--   
--   There are no restrictions on the relative values of these two maximum
--   lookahead values. This means that it's quite possible for the next era
--   to have a <i>smaller</i> lookahead (to re-iterate, since that era has
--   not yet begun, the first block in that era is at the transition, and
--   so the maximum lookahead applies from the transition point):
--   
--   <pre>
--                        ~
--                        ~    /----------\
--                        ~    |          |
--            /---------- ~ ---|----------|-------\
--            |           ~    |          |       |
--   block [block]        ~ [block']      |       |
--     |                  ~               v       v
--    TIP                 ~         VIEW
--                        ~
--   </pre>
--   
--   Indeed, if the next era has zero lookahead, when the first block of
--   the next era comes it, it can make changes immediately, and so we
--   can't even know what the view at the transition point is.
--   
--   Note that if there can be no more blocks in this era, the maximum
--   lookahead of the current era is irrelevant:
--   
--   <pre>
--         ~
--         ~    /----------\
--         ~    |          |
--         ~    |          |
--         ~    |          |
--   block ~ [block']      |
--     |   ~               v
--    TIP  ~         VIEW
--         ~
--   </pre>
--   
--   We can therefore compute the earliest <a>SlotNo</a> the next block in
--   this era (if any) can make changes to the ledger state, as well as the
--   earliest <a>SlotNo</a> the first block in the next era can; their
--   <tt>minimum</tt> will serve as an exclusive upper bound for the
--   forecast range.
crossEraForecastBound :: WithOrigin SlotNo -> SlotNo -> Word64 -> Word64 -> SlotNo
instance GHC.Classes.Eq Ouroboros.Consensus.Forecast.OutsideForecastRange
instance GHC.Show.Show Ouroboros.Consensus.Forecast.OutsideForecastRange
instance GHC.Exception.Type.Exception Ouroboros.Consensus.Forecast.OutsideForecastRange

module Ouroboros.Consensus.Util.RedundantConstraints

-- | Can be used to silence individual "redundant constraint" warnings
--   
--   <pre>
--   foo :: ConstraintUsefulForDebugging =&gt; ...
--   foo =
--       ..
--     where
--       _ = keepRedundantConstraint (Proxy @ConstraintUsefulForDebugging))
--   </pre>
keepRedundantConstraint :: c => proxy c -> ()

-- | <a>Proxy</a> is a type that holds no data, but has a phantom parameter
--   of arbitrary type (or even kind). Its use is to provide type
--   information, even though there is no value available of that type (or
--   it may be too costly to create one).
--   
--   Historically, <tt><a>Proxy</a> :: <a>Proxy</a> a</tt> is a safer
--   alternative to the <tt><a>undefined</a> :: a</tt> idiom.
--   
--   <pre>
--   &gt;&gt;&gt; Proxy :: Proxy (Void, Int -&gt; Int)
--   Proxy
--   </pre>
--   
--   Proxy can even hold types of higher kinds,
--   
--   <pre>
--   &gt;&gt;&gt; Proxy :: Proxy Either
--   Proxy
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; Proxy :: Proxy Functor
--   Proxy
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; Proxy :: Proxy complicatedStructure
--   Proxy
--   </pre>
data Proxy (t :: k)
Proxy :: Proxy (t :: k)

module Ouroboros.Consensus.Util.Assert
assertWithMsg :: HasCallStack => Either String () -> a -> a
assertEqWithMsg :: (Eq b, Show b, HasCallStack) => (b, b) -> a -> a


-- | Header validation
module Ouroboros.Consensus.HeaderValidation

-- | Header validation
--   
--   Header validation (as opposed to block validation) is done by the
--   chain sync client: as we download headers from other network nodes, we
--   validate those headers before deciding whether or not to download the
--   corresponding blocks.
--   
--   Before we <i>adopt</i> any blocks we have downloaded, however, we will
--   do a full block validation. As such, the header validation check can
--   omit some checks (provided that we do those checks when we do the full
--   validation); at worst, this would mean we might download some blocks
--   that we will reject as being invalid where we could have detected that
--   sooner.
--   
--   For this reason, the header validation currently only checks two
--   things:
--   
--   o It verifies the consensus part of the header.
--   
--   For example, for Praos this means checking the VRF proofs.
--   
--   o It verifies the <a>HasHeader</a> part of the header.
--   
--   By default, we verify that
--   
--   x Block numbers are consecutive x The block number of the first block
--   is <tt>firstBlockNo</tt> x Slot numbers are strictly increasing x The
--   slot number of the first block is at least
--   <a>minimumPossibleSlotNo</a> x Hashes line up
--   
--   <i>If</i> a particular ledger wants to verify additional fields in the
--   header, it will get the chance to do so in <tt>applyLedgerBlock</tt>,
--   which is passed the entire block (not just the block body).
validateHeader :: (BlockSupportsProtocol blk, ValidateEnvelope blk) => TopLevelConfig blk -> Ticked (LedgerView (BlockProtocol blk)) -> Header blk -> Ticked (HeaderState blk) -> Except (HeaderError blk) (HeaderState blk)

-- | Header revalidation
--   
--   Same as <a>validateHeader</a> but used when the header has been
--   validated before w.r.t. the same exact <a>HeaderState</a>.
--   
--   Expensive validation checks are skipped (<a>reupdateChainDepState</a>
--   vs. <a>updateChainDepState</a>).
revalidateHeader :: forall blk. (BlockSupportsProtocol blk, ValidateEnvelope blk, HasCallStack) => TopLevelConfig blk -> Ticked (LedgerView (BlockProtocol blk)) -> Header blk -> Ticked (HeaderState blk) -> HeaderState blk

-- | Annotated information about the tip of the chain
--   
--   The annotation is the additional information we need to validate the
--   header envelope. Under normal circumstances no additional information
--   is required, but for instance for Byron we need to know if the
--   previous header was an EBB.
data AnnTip blk
AnnTip :: !SlotNo -> !BlockNo -> !TipInfo blk -> AnnTip blk
[annTipSlotNo] :: AnnTip blk -> !SlotNo
[annTipBlockNo] :: AnnTip blk -> !BlockNo
[annTipInfo] :: AnnTip blk -> !TipInfo blk
annTipHash :: forall blk. HasAnnTip blk => AnnTip blk -> HeaderHash blk
annTipPoint :: forall blk. HasAnnTip blk => AnnTip blk -> Point blk
annTipRealPoint :: forall blk. HasAnnTip blk => AnnTip blk -> RealPoint blk
castAnnTip :: TipInfo blk ~ TipInfo blk' => AnnTip blk -> AnnTip blk'
mapAnnTip :: (TipInfo blk -> TipInfo blk') -> AnnTip blk -> AnnTip blk'
class (StandardHash blk, Show (TipInfo blk), Eq (TipInfo blk), NoThunks (TipInfo blk)) => HasAnnTip blk where {
    type family TipInfo blk :: Type;
    type TipInfo blk = HeaderHash blk;
}

-- | Extract <a>TipInfo</a> from a block header
getTipInfo :: HasAnnTip blk => Header blk -> TipInfo blk

-- | The tip info must at least include the hash
tipInfoHash :: HasAnnTip blk => proxy blk -> TipInfo blk -> HeaderHash blk

-- | The tip info must at least include the hash
tipInfoHash :: (HasAnnTip blk, TipInfo blk ~ HeaderHash blk) => proxy blk -> TipInfo blk -> HeaderHash blk

-- | Extract <a>TipInfo</a> from a block header
getTipInfo :: (HasAnnTip blk, TipInfo blk ~ HeaderHash blk, HasHeader (Header blk)) => Header blk -> TipInfo blk
getAnnTip :: (HasHeader (Header blk), HasAnnTip blk) => Header blk -> AnnTip blk

-- | State required to validate the header
--   
--   See <a>validateHeader</a> for details
data HeaderState blk
HeaderState :: !WithOrigin (AnnTip blk) -> !ChainDepState (BlockProtocol blk) -> HeaderState blk
[headerStateTip] :: HeaderState blk -> !WithOrigin (AnnTip blk)
[headerStateChainDep] :: HeaderState blk -> !ChainDepState (BlockProtocol blk)
castHeaderState :: (Coercible (ChainDepState (BlockProtocol blk)) (ChainDepState (BlockProtocol blk')), TipInfo blk ~ TipInfo blk') => HeaderState blk -> HeaderState blk'

-- | Tick the <a>ChainDepState</a> inside the <a>HeaderState</a>
tickHeaderState :: ConsensusProtocol (BlockProtocol blk) => ConsensusConfig (BlockProtocol blk) -> Ticked (LedgerView (BlockProtocol blk)) -> SlotNo -> HeaderState blk -> Ticked (HeaderState blk)
genesisHeaderState :: ChainDepState (BlockProtocol blk) -> HeaderState blk
headerStatePoint :: HasAnnTip blk => HeaderState blk -> Point blk

-- | Ledger-independent envelope validation (block, slot, hash)
class (HasHeader (Header blk), HasAnnTip blk) => BasicEnvelopeValidation blk

-- | The block number of the first block on the chain
expectedFirstBlockNo :: BasicEnvelopeValidation blk => proxy blk -> BlockNo

-- | Next block number
expectedNextBlockNo :: BasicEnvelopeValidation blk => proxy blk -> TipInfo blk -> TipInfo blk -> BlockNo -> BlockNo

-- | The smallest possible <a>SlotNo</a>
--   
--   NOTE: This does not affect the translation between <a>SlotNo</a> and
--   <a>EpochNo</a>. <a>Ouroboros.Consensus.HardFork.History</a> for
--   details.
minimumPossibleSlotNo :: BasicEnvelopeValidation blk => Proxy blk -> SlotNo

-- | Minimum next slot number
minimumNextSlotNo :: BasicEnvelopeValidation blk => proxy blk -> TipInfo blk -> TipInfo blk -> SlotNo -> SlotNo
data HeaderEnvelopeError blk

-- | Invalid block number
--   
--   We record both the expected and actual block number
UnexpectedBlockNo :: !BlockNo -> !BlockNo -> HeaderEnvelopeError blk

-- | Invalid slot number
--   
--   We record both the expected (minimum) and actual slot number
UnexpectedSlotNo :: !SlotNo -> !SlotNo -> HeaderEnvelopeError blk

-- | Invalid hash (in the reference to the previous block)
--   
--   We record the current tip as well as the prev hash of the new block.
UnexpectedPrevHash :: !WithOrigin (HeaderHash blk) -> !ChainHash blk -> HeaderEnvelopeError blk

-- | Block specific envelope error
OtherHeaderEnvelopeError :: !OtherHeaderEnvelopeError blk -> HeaderEnvelopeError blk
castHeaderEnvelopeError :: (HeaderHash blk ~ HeaderHash blk', OtherHeaderEnvelopeError blk ~ OtherHeaderEnvelopeError blk') => HeaderEnvelopeError blk -> HeaderEnvelopeError blk'

-- | Validate header envelope
class (BasicEnvelopeValidation blk, GetPrevHash blk, Eq (OtherHeaderEnvelopeError blk), Show (OtherHeaderEnvelopeError blk), NoThunks (OtherHeaderEnvelopeError blk)) => ValidateEnvelope blk where {
    
    -- | A block-specific error that <a>validateEnvelope</a> can return.
    type family OtherHeaderEnvelopeError blk :: Type;
    type OtherHeaderEnvelopeError blk = Void;
}

-- | Do additional envelope checks
additionalEnvelopeChecks :: ValidateEnvelope blk => TopLevelConfig blk -> Ticked (LedgerView (BlockProtocol blk)) -> Header blk -> Except (OtherHeaderEnvelopeError blk) ()

-- | Invalid header
data HeaderError blk

-- | Invalid consensus protocol fields
HeaderProtocolError :: !ValidationErr (BlockProtocol blk) -> HeaderError blk

-- | Failed to validate the envelope
HeaderEnvelopeError :: !HeaderEnvelopeError blk -> HeaderError blk
castHeaderError :: (ValidationErr (BlockProtocol blk) ~ ValidationErr (BlockProtocol blk'), HeaderHash blk ~ HeaderHash blk', OtherHeaderEnvelopeError blk ~ OtherHeaderEnvelopeError blk') => HeaderError blk -> HeaderError blk'

-- | Reusable strict data type for <a>TipInfo</a> in case the
--   <a>TipInfo</a> should contain <a>IsEBB</a> in addition to the
--   <a>HeaderHash</a>.
data TipInfoIsEBB blk
TipInfoIsEBB :: !HeaderHash blk -> !IsEBB -> TipInfoIsEBB blk
defaultEncodeAnnTip :: TipInfo blk ~ HeaderHash blk => (HeaderHash blk -> Encoding) -> AnnTip blk -> Encoding
defaultDecodeAnnTip :: TipInfo blk ~ HeaderHash blk => (forall s. Decoder s (HeaderHash blk)) -> forall s. Decoder s (AnnTip blk)
encodeAnnTipIsEBB :: TipInfo blk ~ TipInfoIsEBB blk => (HeaderHash blk -> Encoding) -> AnnTip blk -> Encoding
decodeAnnTipIsEBB :: TipInfo blk ~ TipInfoIsEBB blk => (forall s. Decoder s (HeaderHash blk)) -> forall s. Decoder s (AnnTip blk)
encodeHeaderState :: (ChainDepState (BlockProtocol blk) -> Encoding) -> (AnnTip blk -> Encoding) -> HeaderState blk -> Encoding
decodeHeaderState :: (forall s. Decoder s (ChainDepState (BlockProtocol blk))) -> (forall s. Decoder s (AnnTip blk)) -> forall s. Decoder s (HeaderState blk)

-- | " Ticked " piece of state (<tt>LedgerState</tt>, <tt>LedgerView</tt>,
--   <tt>ChainIndepState</tt>)
--   
--   Ticking refers to the passage of time (the ticking of the clock). When
--   a piece of state is marked as ticked, it means that time-related
--   changes have been applied to the state (or forecast).
--   
--   Some examples of time related changes:
--   
--   <ul>
--   <li>Scheduled delegations might have been applied in Byron</li>
--   <li>New leader schedule computed for Shelley</li>
--   <li>Transition from Byron to Shelley activated in the hard fork
--   combinator.</li>
--   <li>Nonces switched out at the start of a new epoch.</li>
--   </ul>
data family Ticked st :: Type
instance GHC.Generics.Generic (Ouroboros.Consensus.HeaderValidation.AnnTip blk)
instance GHC.Generics.Generic (Ouroboros.Consensus.HeaderValidation.HeaderState blk)
instance GHC.Generics.Generic (Ouroboros.Consensus.HeaderValidation.HeaderEnvelopeError blk)
instance GHC.Generics.Generic (Ouroboros.Consensus.HeaderValidation.HeaderError blk)
instance GHC.Generics.Generic (Ouroboros.Consensus.HeaderValidation.TipInfoIsEBB blk)
instance Ouroboros.Consensus.HeaderValidation.HasAnnTip blk => GHC.Show.Show (Ouroboros.Consensus.HeaderValidation.AnnTip blk)
instance Ouroboros.Consensus.HeaderValidation.HasAnnTip blk => GHC.Classes.Eq (Ouroboros.Consensus.HeaderValidation.AnnTip blk)
instance Ouroboros.Consensus.HeaderValidation.HasAnnTip blk => NoThunks.Class.NoThunks (Ouroboros.Consensus.HeaderValidation.AnnTip blk)
instance (Ouroboros.Consensus.Block.SupportsProtocol.BlockSupportsProtocol blk, Ouroboros.Consensus.HeaderValidation.HasAnnTip blk) => GHC.Classes.Eq (Ouroboros.Consensus.HeaderValidation.HeaderState blk)
instance (Ouroboros.Consensus.Block.SupportsProtocol.BlockSupportsProtocol blk, Ouroboros.Consensus.HeaderValidation.HasAnnTip blk) => GHC.Show.Show (Ouroboros.Consensus.HeaderValidation.HeaderState blk)
instance (Ouroboros.Consensus.Block.SupportsProtocol.BlockSupportsProtocol blk, Ouroboros.Consensus.HeaderValidation.HasAnnTip blk) => NoThunks.Class.NoThunks (Ouroboros.Consensus.HeaderValidation.HeaderState blk)
instance Ouroboros.Consensus.HeaderValidation.ValidateEnvelope blk => GHC.Classes.Eq (Ouroboros.Consensus.HeaderValidation.HeaderEnvelopeError blk)
instance Ouroboros.Consensus.HeaderValidation.ValidateEnvelope blk => GHC.Show.Show (Ouroboros.Consensus.HeaderValidation.HeaderEnvelopeError blk)
instance (Ouroboros.Consensus.HeaderValidation.ValidateEnvelope blk, Data.Typeable.Internal.Typeable blk) => NoThunks.Class.NoThunks (Ouroboros.Consensus.HeaderValidation.HeaderEnvelopeError blk)
instance (Ouroboros.Consensus.Block.SupportsProtocol.BlockSupportsProtocol blk, Ouroboros.Consensus.HeaderValidation.ValidateEnvelope blk) => GHC.Classes.Eq (Ouroboros.Consensus.HeaderValidation.HeaderError blk)
instance (Ouroboros.Consensus.Block.SupportsProtocol.BlockSupportsProtocol blk, Ouroboros.Consensus.HeaderValidation.ValidateEnvelope blk) => GHC.Show.Show (Ouroboros.Consensus.HeaderValidation.HeaderError blk)
instance (Ouroboros.Consensus.Block.SupportsProtocol.BlockSupportsProtocol blk, Ouroboros.Consensus.HeaderValidation.ValidateEnvelope blk, Data.Typeable.Internal.Typeable blk) => NoThunks.Class.NoThunks (Ouroboros.Consensus.HeaderValidation.HeaderError blk)
instance Ouroboros.Network.Block.StandardHash blk => GHC.Classes.Eq (Ouroboros.Consensus.HeaderValidation.TipInfoIsEBB blk)
instance Ouroboros.Network.Block.StandardHash blk => GHC.Show.Show (Ouroboros.Consensus.HeaderValidation.TipInfoIsEBB blk)
instance Ouroboros.Network.Block.StandardHash blk => NoThunks.Class.NoThunks (Ouroboros.Consensus.HeaderValidation.TipInfoIsEBB blk)

module Ouroboros.Consensus.Ledger.SupportsProtocol

-- | Link protocol to ledger
class (BlockSupportsProtocol blk, UpdateLedger blk, ValidateEnvelope blk) => LedgerSupportsProtocol blk

-- | Extract ticked ledger view from ticked ledger state
--   
--   See <a>ledgerViewForecastAt</a> for a discussion and precise
--   definition of the relation between this and forecasting.
protocolLedgerView :: LedgerSupportsProtocol blk => LedgerConfig blk -> Ticked (LedgerState blk) -> Ticked (LedgerView (BlockProtocol blk))

-- | Get a forecast at the given ledger state.
--   
--   This forecast can be used to validate headers of blocks within the
--   range of the forecast. These blocks need to live on a chain that fits
--   on the last applied block of the given ledger.
--   
--   The range of the forecast should allow to validate a sufficient number
--   of headers to validate an alternative chain longer than ours, so that
--   chain selection can decide whether or not we prefer the alternative
--   chain to our current chain. In addition, it would be helpful, though
--   not essential, if we can look further ahead than that, as this would
--   improve sync performance.
--   
--   NOTE (difference between <a>ledgerViewForecastAt</a> and
--   <a>applyChainTick</a>): Both <a>ledgerViewForecastAt</a> and
--   <a>applyChainTick</a> can be used to obtain a protocol ledger view for
--   a future slot. The difference between the two is that
--   <a>applyChainTick</a> assumes no blocks are present between the
--   current ledger tip and the specified <a>SlotNo</a>, whereas
--   <a>ledgerViewForecastAt</a> cannot make such an assumption. Thus,
--   <a>applyChainTick</a> cannot fail, whereas the forecast returned by
--   <a>ledgerViewForecastAt</a> might report an
--   <a>OutsideForecastRange</a> for the same <a>SlotNo</a>. We expect the
--   two functions to produce the same view whenever the <a>SlotNo</a>
--   <i>is</i> in range, however. More precisely:
--   
--   If
--   
--   <pre>
--      forecastFor (ledgerViewForecastAt cfg st) for
--   == Just view
--   </pre>
--   
--   then
--   
--   <pre>
--      protocolLedgerView cfg (applyChainTick cfg for st)
--   == view
--   </pre>
--   
--   See <tt>lemma_ledgerViewForecastAt_applyChainTick</tt>.
ledgerViewForecastAt :: (LedgerSupportsProtocol blk, HasCallStack) => LedgerConfig blk -> LedgerState blk -> Forecast (LedgerView (BlockProtocol blk))

module Ouroboros.Consensus.Ledger.Extended

-- | Extended ledger state
--   
--   This is the combination of the header state and the ledger state
--   proper.
data ExtLedgerState blk
ExtLedgerState :: !LedgerState blk -> !HeaderState blk -> ExtLedgerState blk
[ledgerState] :: ExtLedgerState blk -> !LedgerState blk
[headerState] :: ExtLedgerState blk -> !HeaderState blk
data ExtValidationError blk
ExtValidationErrorLedger :: !LedgerError blk -> ExtValidationError blk
ExtValidationErrorHeader :: !HeaderError blk -> ExtValidationError blk

-- | " Ledger " configuration for the extended ledger
--   
--   Since the extended ledger also does the consensus protocol validation,
--   we also need the consensus config.
newtype ExtLedgerCfg blk
ExtLedgerCfg :: TopLevelConfig blk -> ExtLedgerCfg blk
[getExtLedgerCfg] :: ExtLedgerCfg blk -> TopLevelConfig blk
encodeExtLedgerState :: (LedgerState blk -> Encoding) -> (ChainDepState (BlockProtocol blk) -> Encoding) -> (AnnTip blk -> Encoding) -> ExtLedgerState blk -> Encoding
decodeExtLedgerState :: (forall s. Decoder s (LedgerState blk)) -> (forall s. Decoder s (ChainDepState (BlockProtocol blk))) -> (forall s. Decoder s (AnnTip blk)) -> forall s. Decoder s (ExtLedgerState blk)
castExtLedgerState :: (Coercible (LedgerState blk) (LedgerState blk'), Coercible (ChainDepState (BlockProtocol blk)) (ChainDepState (BlockProtocol blk')), TipInfo blk ~ TipInfo blk') => ExtLedgerState blk -> ExtLedgerState blk'

-- | " Ticked " piece of state (<tt>LedgerState</tt>, <tt>LedgerView</tt>,
--   <tt>ChainIndepState</tt>)
--   
--   Ticking refers to the passage of time (the ticking of the clock). When
--   a piece of state is marked as ticked, it means that time-related
--   changes have been applied to the state (or forecast).
--   
--   Some examples of time related changes:
--   
--   <ul>
--   <li>Scheduled delegations might have been applied in Byron</li>
--   <li>New leader schedule computed for Shelley</li>
--   <li>Transition from Byron to Shelley activated in the hard fork
--   combinator.</li>
--   <li>Nonces switched out at the start of a new epoch.</li>
--   </ul>
data family Ticked st :: Type
instance GHC.Generics.Generic (Ouroboros.Consensus.Ledger.Extended.ExtLedgerState blk)
instance GHC.Generics.Generic (Ouroboros.Consensus.Ledger.Extended.ExtValidationError blk)
instance GHC.Generics.Generic (Ouroboros.Consensus.Ledger.Extended.ExtLedgerCfg blk)
instance Ouroboros.Consensus.Ledger.SupportsProtocol.LedgerSupportsProtocol blk => GHC.Show.Show (Ouroboros.Consensus.Ledger.Extended.ExtLedgerState blk)
instance Ouroboros.Consensus.Ledger.SupportsProtocol.LedgerSupportsProtocol blk => GHC.Show.Show (Ouroboros.Consensus.Ledger.Extended.ExtValidationError blk)
instance Ouroboros.Consensus.Ledger.SupportsProtocol.LedgerSupportsProtocol blk => GHC.Classes.Eq (Ouroboros.Consensus.Ledger.Extended.ExtValidationError blk)
instance (Ouroboros.Consensus.Ledger.SupportsProtocol.LedgerSupportsProtocol blk, GHC.Classes.Eq (Ouroboros.Consensus.Protocol.Abstract.ChainDepState (Ouroboros.Consensus.Block.Abstract.BlockProtocol blk))) => GHC.Classes.Eq (Ouroboros.Consensus.Ledger.Extended.ExtLedgerState blk)
instance (Ouroboros.Consensus.Protocol.Abstract.ConsensusProtocol (Ouroboros.Consensus.Block.Abstract.BlockProtocol blk), NoThunks.Class.NoThunks (Ouroboros.Consensus.Block.Abstract.BlockConfig blk), NoThunks.Class.NoThunks (Ouroboros.Consensus.Block.Abstract.CodecConfig blk), NoThunks.Class.NoThunks (Ouroboros.Consensus.Ledger.Basics.LedgerConfig blk), NoThunks.Class.NoThunks (Ouroboros.Consensus.Block.Abstract.StorageConfig blk)) => NoThunks.Class.NoThunks (Ouroboros.Consensus.Ledger.Extended.ExtLedgerCfg blk)
instance (Ouroboros.Consensus.Ledger.Basics.IsLedger (Ouroboros.Consensus.Ledger.Basics.LedgerState blk), Ouroboros.Consensus.Ledger.SupportsProtocol.LedgerSupportsProtocol blk) => Ouroboros.Consensus.Ledger.Basics.IsLedger (Ouroboros.Consensus.Ledger.Extended.ExtLedgerState blk)
instance Ouroboros.Consensus.Ledger.SupportsProtocol.LedgerSupportsProtocol blk => Ouroboros.Consensus.Ledger.Abstract.ApplyBlock (Ouroboros.Consensus.Ledger.Extended.ExtLedgerState blk) blk
instance Ouroboros.Consensus.Ledger.SupportsProtocol.LedgerSupportsProtocol blk => NoThunks.Class.NoThunks (Ouroboros.Consensus.Ledger.Extended.ExtValidationError blk)
instance Ouroboros.Consensus.Ledger.SupportsProtocol.LedgerSupportsProtocol blk => NoThunks.Class.NoThunks (Ouroboros.Consensus.Ledger.Extended.ExtLedgerState blk)
instance Ouroboros.Consensus.Ledger.Basics.IsLedger (Ouroboros.Consensus.Ledger.Basics.LedgerState blk) => Ouroboros.Consensus.Ledger.Basics.GetTip (Ouroboros.Consensus.Ledger.Extended.ExtLedgerState blk)
instance Ouroboros.Consensus.Ledger.Basics.IsLedger (Ouroboros.Consensus.Ledger.Basics.LedgerState blk) => Ouroboros.Consensus.Ledger.Basics.GetTip (Ouroboros.Consensus.Ticked.Ticked (Ouroboros.Consensus.Ledger.Extended.ExtLedgerState blk))

module Ouroboros.Consensus.Node.ProtocolInfo
newtype NumCoreNodes
NumCoreNodes :: Word64 -> NumCoreNodes
enumCoreNodes :: NumCoreNodes -> [CoreNodeId]

-- | Data required to run the specified protocol.
data ProtocolInfo m b
ProtocolInfo :: TopLevelConfig b -> ExtLedgerState b -> [m (BlockForging m b)] -> ProtocolInfo m b
[pInfoConfig] :: ProtocolInfo m b -> TopLevelConfig b

-- | At genesis
[pInfoInitLedger] :: ProtocolInfo m b -> ExtLedgerState b
[pInfoBlockForging] :: ProtocolInfo m b -> [m (BlockForging m b)]

-- | Data required by clients of a node running the specified protocol.
data ProtocolClientInfo b
ProtocolClientInfo :: CodecConfig b -> ProtocolClientInfo b
[pClientInfoCodecConfig] :: ProtocolClientInfo b -> CodecConfig b
instance NoThunks.Class.NoThunks Ouroboros.Consensus.Node.ProtocolInfo.NumCoreNodes
instance GHC.Show.Show Ouroboros.Consensus.Node.ProtocolInfo.NumCoreNodes

module Ouroboros.Consensus.Protocol.BFT

-- | Basic BFT
--   
--   Basic BFT is very simple:
--   
--   <ul>
--   <li>No support for delegation (and hence has no need for a ledger
--   view)</li>
--   <li>Requires round-robin block signing throughout (and so has no need
--   for any chain state or cryptographic leader proofs).</li>
--   <li>Does not use any stateful crypto (and so has no need for node
--   state)</li>
--   </ul>
data Bft c
data BftFields c toSign
BftFields :: !SignedDSIGN (BftDSIGN c) toSign -> BftFields c toSign
[bftSignature] :: BftFields c toSign -> !SignedDSIGN (BftDSIGN c) toSign

-- | Protocol parameters
data BftParams
BftParams :: !SecurityParam -> !NumCoreNodes -> BftParams

-- | Security parameter
--   
--   Although the protocol proper does not have such a security parameter,
--   we insist on it.
[bftSecurityParam] :: BftParams -> !SecurityParam

-- | Number of core nodes
[bftNumNodes] :: BftParams -> !NumCoreNodes
data BftValidationErr
BftInvalidSignature :: String -> BftValidationErr
forgeBftFields :: (BftCrypto c, Signable (BftDSIGN c) toSign) => ConsensusConfig (Bft c) -> toSign -> BftFields c toSign

-- | Crypto primitives required by BFT
class (Typeable c, DSIGNAlgorithm (BftDSIGN c), Condense (SigDSIGN (BftDSIGN c)), NoThunks (SigDSIGN (BftDSIGN c)), ContextDSIGN (BftDSIGN c) ~ ()) => BftCrypto c where {
    type family BftDSIGN c :: Type;
}
data BftStandardCrypto
data BftMockCrypto
data BftValidateView c
BftValidateView :: BftFields c signed -> signed -> BftValidateView c

-- | Convenience constructor for <a>BftValidateView</a>
bftValidateView :: (SignedHeader hdr, Signable (BftDSIGN c) (Signed hdr)) => (hdr -> BftFields c (Signed hdr)) -> hdr -> BftValidateView c

-- | Static configuration required to run the consensus protocol
--   
--   Every method in the <a>ConsensusProtocol</a> class takes the consensus
--   configuration as a parameter, so having this as a data family rather
--   than a type family resolves most ambiguity.
--   
--   Defined out of the class so that protocols can define this type
--   without having to define the entire protocol at the same time (or
--   indeed in the same module).
data family ConsensusConfig p :: Type
instance NoThunks.Class.NoThunks Ouroboros.Consensus.Protocol.BFT.BftParams
instance GHC.Generics.Generic Ouroboros.Consensus.Protocol.BFT.BftParams
instance NoThunks.Class.NoThunks Ouroboros.Consensus.Protocol.BFT.BftValidationErr
instance GHC.Generics.Generic Ouroboros.Consensus.Protocol.BFT.BftValidationErr
instance GHC.Classes.Eq Ouroboros.Consensus.Protocol.BFT.BftValidationErr
instance GHC.Show.Show Ouroboros.Consensus.Protocol.BFT.BftValidationErr
instance GHC.Generics.Generic (Ouroboros.Consensus.Protocol.Abstract.ConsensusConfig (Ouroboros.Consensus.Protocol.BFT.Bft c))
instance GHC.Generics.Generic (Ouroboros.Consensus.Protocol.BFT.BftFields c toSign)
instance Ouroboros.Consensus.Protocol.BFT.BftCrypto c => GHC.Show.Show (Ouroboros.Consensus.Protocol.BFT.BftFields c toSign)
instance Ouroboros.Consensus.Protocol.BFT.BftCrypto c => GHC.Classes.Eq (Ouroboros.Consensus.Protocol.BFT.BftFields c toSign)
instance Ouroboros.Consensus.Protocol.BFT.BftCrypto Ouroboros.Consensus.Protocol.BFT.BftMockCrypto
instance Ouroboros.Consensus.Protocol.BFT.BftCrypto Ouroboros.Consensus.Protocol.BFT.BftStandardCrypto
instance Ouroboros.Consensus.Protocol.BFT.BftCrypto c => Ouroboros.Consensus.Protocol.Abstract.ConsensusProtocol (Ouroboros.Consensus.Protocol.BFT.Bft c)
instance (Ouroboros.Consensus.Protocol.BFT.BftCrypto c, Data.Typeable.Internal.Typeable toSign) => NoThunks.Class.NoThunks (Ouroboros.Consensus.Protocol.BFT.BftFields c toSign)
instance Ouroboros.Consensus.Protocol.BFT.BftCrypto c => Ouroboros.Consensus.Util.Condense.Condense (Ouroboros.Consensus.Protocol.BFT.BftFields c toSign)
instance Ouroboros.Consensus.Protocol.BFT.BftCrypto c => NoThunks.Class.NoThunks (Ouroboros.Consensus.Protocol.Abstract.ConsensusConfig (Ouroboros.Consensus.Protocol.BFT.Bft c))
instance Ouroboros.Consensus.Protocol.Abstract.ChainSelection (Ouroboros.Consensus.Protocol.BFT.Bft c)

module Ouroboros.Consensus.Ledger.Query

-- | Different queries supported by the ledger, indexed by the result type.
data family Query blk :: Type -> Type

-- | Query the ledger extended state.
--   
--   Used by the LocalStateQuery protocol to allow clients to query the
--   extended ledger state.
class (ShowQuery (Query blk), SameDepIndex (Query blk)) => QueryLedger blk

-- | Answer the given query about the extended ledger state.
answerQuery :: QueryLedger blk => ExtLedgerCfg blk -> Query blk result -> ExtLedgerState blk -> result
class forall result. () => Show query result => ShowQuery (query :: Type -> Type)
showResult :: ShowQuery query => query result -> result -> String
instance (forall result. GHC.Show.Show (Ouroboros.Consensus.Ledger.Query.Query blk result)) => GHC.Show.Show (Ouroboros.Consensus.Util.SomeSecond Ouroboros.Consensus.Ledger.Query.Query blk)
instance Ouroboros.Consensus.Util.DepPair.SameDepIndex (Ouroboros.Consensus.Ledger.Query.Query blk) => GHC.Classes.Eq (Ouroboros.Consensus.Util.SomeSecond Ouroboros.Consensus.Ledger.Query.Query blk)

module Ouroboros.Consensus.MiniProtocol.LocalStateQuery.Server
localStateQueryServer :: forall m blk. (IOLike m, QueryLedger blk) => ExtLedgerCfg blk -> (Point blk -> STM m (Maybe (ExtLedgerState blk))) -> STM m (Point blk) -> LocalStateQueryServer blk (Point blk) (Query blk) m ()


-- | HeaderState history
--   
--   Intended for qualified import
--   
--   <pre>
--   import           Ouroboros.Consensus.HeaderStateHistory (HeaderStateHistory (..))
--   import qualified Ouroboros.Consensus.HeaderStateHistory as HeaderStateHistory
--   </pre>
module Ouroboros.Consensus.HeaderStateHistory

-- | Maintain a history of <a>HeaderState</a>s.
data HeaderStateHistory blk
HeaderStateHistory :: !StrictSeq (HeaderState blk) -> !HeaderState blk -> HeaderStateHistory blk

-- | The last, right-most, element in the sequence contains the current
--   state, see <tt>headerStateHistoryCurrent</tt>.
[headerStateHistorySnapshots] :: HeaderStateHistory blk -> !StrictSeq (HeaderState blk)

-- | Header state <i>before</i> the oldest in
--   <a>headerStateHistorySnapshots</a>. This is the oldest tip we can roll
--   back to.
[headerStateHistoryAnchor] :: HeaderStateHistory blk -> !HeaderState blk
current :: HeaderStateHistory blk -> HeaderState blk

-- | Trim the <a>HeaderStateHistory</a> to the given size, dropping the
--   oldest snapshots. The anchor will be shifted accordingly.
--   
--   Note that we do not include the anchor in the size. For example,
--   trimming to 0 results in no snapshots but still an anchor. Trimming to
--   1 results in 1 snapshot and an anchor.
trim :: Int -> HeaderStateHistory blk -> HeaderStateHistory blk

-- | &lt;math&gt; ). Rewind the header state history
--   
--   NOTE: we don't distinguish headers of regular blocks from headers of
--   EBBs. Whenever we use "header" it can be either. In practice, EBB
--   headers do not affect the <a>ChainDepState</a>, but they <i>do</i>
--   affect the <a>AnnTip</a>.
--   
--   PRECONDITION: the point to rewind to must correspond to a header (or
--   <a>GenesisPoint</a>) that was previously applied to the header state
--   history.
--   
--   Rewinding the header state history is intended to be used when
--   switching to a fork, longer or equally long to the chain to which the
--   current header state corresponds. So each rewinding should be followed
--   by rolling forward (using <tt>headerStateHistoryPush</tt>) at least as
--   many blocks that we have rewound.
--   
--   Note that repeatedly rewinding a header state history does not make it
--   possible to rewind it all the way to genesis (this would mean that the
--   whole historical header state is accumulated or derivable from the
--   current header state history). For example, rewinding a header state
--   by <tt>i</tt> blocks and then rewinding that header state again by
--   <tt>j</tt> where <tt>i + j &gt; k</tt> is not possible and will yield
--   <a>Nothing</a>.
rewind :: forall blk. (BlockSupportsProtocol blk, HasAnnTip blk) => Point blk -> HeaderStateHistory blk -> Maybe (HeaderStateHistory blk)
cast :: (Coercible (ChainDepState (BlockProtocol blk)) (ChainDepState (BlockProtocol blk')), TipInfo blk ~ TipInfo blk') => HeaderStateHistory blk -> HeaderStateHistory blk'

-- | Variation on <a>validateHeader</a> that maintains a
--   <a>HeaderStateHistory</a>.
--   
--   This is used only in the chain sync client for header-only validation.
--   
--   Note: this function does not trim the <a>HeaderStateHistory</a>.
validateHeader :: forall blk. (BlockSupportsProtocol blk, ValidateEnvelope blk) => TopLevelConfig blk -> Ticked (LedgerView (BlockProtocol blk)) -> Header blk -> HeaderStateHistory blk -> Except (HeaderError blk) (HeaderStateHistory blk)

-- | Create a <a>HeaderStateHistory</a> corresponding to the blocks in the
--   given <a>Chain</a>.
--   
--   PRECONDITION: the blocks in the chain are valid.
fromChain :: ApplyBlock (ExtLedgerState blk) blk => TopLevelConfig blk -> ExtLedgerState blk -> Chain blk -> HeaderStateHistory blk
instance GHC.Generics.Generic (Ouroboros.Consensus.HeaderStateHistory.HeaderStateHistory blk)
instance (Ouroboros.Consensus.Block.SupportsProtocol.BlockSupportsProtocol blk, Ouroboros.Consensus.HeaderValidation.HasAnnTip blk) => GHC.Classes.Eq (Ouroboros.Consensus.HeaderStateHistory.HeaderStateHistory blk)
instance (Ouroboros.Consensus.Block.SupportsProtocol.BlockSupportsProtocol blk, Ouroboros.Consensus.HeaderValidation.HasAnnTip blk) => GHC.Show.Show (Ouroboros.Consensus.HeaderStateHistory.HeaderStateHistory blk)
instance (Ouroboros.Consensus.Block.SupportsProtocol.BlockSupportsProtocol blk, Ouroboros.Consensus.HeaderValidation.HasAnnTip blk) => NoThunks.Class.NoThunks (Ouroboros.Consensus.HeaderStateHistory.HeaderStateHistory blk)


-- | Intended for qualified import
--   
--   <pre>
--   import Ouroboros.Consensus.Fragment.Validated (ValidatedFragment)
--   import qualified Ouroboros.Consensus.Fragment.Validated as VF
--   </pre>
module Ouroboros.Consensus.Fragment.Validated

-- | Validated chain fragment along with the ledger state after validation
--   
--   INVARIANT:
--   
--   <pre>
--   AF.headPoint validatedFragment == ledgerTipPoint validatedLedger
--   </pre>
data ValidatedFragment b l
pattern ValidatedFragment :: (IsLedger l, HasHeader b, HeaderHash b ~ HeaderHash l, HasCallStack) => AnchoredFragment b -> l -> ValidatedFragment b l

-- | Chain fragment
validatedFragment :: ValidatedFragment b l -> AnchoredFragment b

-- | Ledger after after validation
validatedLedger :: ValidatedFragment b l -> l
validatedTip :: HasHeader b => ValidatedFragment b l -> Point b
instance GHC.Base.Functor (Ouroboros.Consensus.Fragment.Validated.ValidatedFragment b)


-- | Intended for qualified import
--   
--   <pre>
--   import Ouroboros.Consensus.Fragment.ValidatedDiff (ValidatedChainDiff (..))
--   import qualified Ouroboros.Consensus.Fragment.ValidatedDiff as ValidatedDiff
--   </pre>
module Ouroboros.Consensus.Fragment.ValidatedDiff

-- | A <a>ChainDiff</a> along with the ledger state after validation.
--   
--   INVARIANT:
--   
--   <pre>
--   getTip chainDiff == ledgerTipPoint ledger
--   </pre>
data ValidatedChainDiff b l

-- | Allow for pattern matching on a <a>ValidatedChainDiff</a> without
--   exposing the (unsafe) constructor. Use <a>new</a> to construct a
--   <a>ValidatedChainDiff</a>.
pattern ValidatedChainDiff :: ChainDiff b -> l -> ValidatedChainDiff b l
getChainDiff :: ValidatedChainDiff b l -> ChainDiff b
getLedger :: ValidatedChainDiff b l -> l

-- | Create a <a>ValidatedChainDiff</a>.
--   
--   PRECONDITION:
--   
--   <pre>
--   getTip chainDiff == ledgerTipPoint ledger
--   </pre>
new :: forall b l. (IsLedger l, HasHeader b, HeaderHash l ~ HeaderHash b, HasCallStack) => ChainDiff b -> l -> ValidatedChainDiff b l
toValidatedFragment :: (IsLedger l, HasHeader b, HeaderHash l ~ HeaderHash b, HasCallStack) => ValidatedChainDiff b l -> ValidatedFragment b l
rollbackExceedsSuffix :: HasHeader b => ValidatedChainDiff b l -> Bool

module Ouroboros.Consensus.Storage.ImmutableDB.Chunks.Internal

-- | Size of the chunks of the immutable DB
--   
--   This is the key data structure that drives all layout functions.
--   
--   TODO: Add support for non-uniform <a>ChunkInfo</a>
--   <a>https://github.com/input-output-hk/ouroboros-network/issues/1754</a>
data ChunkInfo

-- | A single, uniform, chunk size
--   
--   If EBBs are present, the chunk size must line up precisely with the
--   epoch size (that is, the number of regular blocks in the chunk must
--   equal the number of regular blocks in an epoch).
UniformChunkSize :: !ChunkSize -> ChunkInfo

-- | Simple chunk config with a single chunk size
--   
--   This intentionally takes <a>EpochSize</a> (number of slots) rather
--   than <a>ChunkSize</a>: the translation from <a>EpochSize</a> to
--   <a>ChunkSize</a> (number of available entries in a chunk) should not
--   be done by client code.
simpleChunkInfo :: EpochSize -> ChunkInfo

-- | <a>ChunkInfo</a> for a single <a>ChunkSize</a>
--   
--   See also <a>simpleChunkInfo</a>.
singleChunkInfo :: ChunkSize -> ChunkInfo

-- | Can we store EBBs in the chunks described by this <a>ChunkInfo</a>?
--   
--   This is only used for tests. This API will need to change (and the
--   tests will become more complicated) once we support non-uniform
--   <a>ChunkInfo</a>.
chunkInfoSupportsEBBs :: ChunkInfo -> Bool

-- | Chunk number
newtype ChunkNo
ChunkNo :: Word64 -> ChunkNo
[unChunkNo] :: ChunkNo -> Word64

-- | First chunk
firstChunkNo :: ChunkNo

-- | Convert <a>ChunkNo</a> to <a>Int</a>
--   
--   This is primarily useful for the immutable DB, which uses an
--   <tt>IntPSQ</tt>.
chunkNoToInt :: ChunkNo -> Int

-- | Convert <a>Int</a> to <a>ChunkNo</a>
--   
--   See <a>chunkNoToInt</a> for motivation.
chunkNoFromInt :: Int -> ChunkNo
nextChunkNo :: ChunkNo -> ChunkNo
prevChunkNo :: ChunkNo -> Maybe ChunkNo

-- | Count number of chunks between two indices
--   
--   <pre>
--   countChunks x              x  == 0
--   countChunks x (nextChunkNo x) == 1
--   </pre>
countChunks :: ChunkNo -> ChunkNo -> Word64

-- | Enumerate all chunks
--   
--   <pre>
--   chunksBetween x              x  == [x]
--   chunksBetween x (nextChunkNo x) == [x, nextChunkNo x]
--   </pre>
chunksBetween :: ChunkNo -> ChunkNo -> [ChunkNo]

-- | Translate <a>EpochNo</a> to <a>ChunkNo</a>
--   
--   This should <i>ONLY</i> be used to translate the <a>EpochNo</a> of an
--   EBB, since the invariant says EBBs can only exist in the first period
--   of the DB, where the chunk size must equal the epoch size. See
--   <a>ChunkInfo</a> for details.
unsafeEpochNoToChunkNo :: EpochNo -> ChunkNo

-- | Translate <a>ChunkNo</a> to <a>EpochNo</a>
--   
--   This should <i>ONLY</i> be used for chunks that contain EBBs. See
--   <a>unsafeEpochNoToChunkNo</a> and <a>ChunkInfo</a> for details.
unsafeChunkNoToEpochNo :: ChunkNo -> EpochNo

-- | Size of a chunk
--   
--   The total number of slots available in a chunk is equal to
--   <a>numRegularBlocks</a> if <tt>not</tt> <a>chunkCanContainEBB</a>, and
--   <a>numRegularBlocks</a> <tt>+ 1</tt> otherwise.
data ChunkSize
ChunkSize :: !Bool -> !Word64 -> ChunkSize

-- | Does this chunk also accomodate an EBB?
[chunkCanContainEBB] :: ChunkSize -> !Bool

-- | The number of regular blocks in this chunk
[numRegularBlocks] :: ChunkSize -> !Word64
getChunkSize :: ChunkInfo -> ChunkNo -> ChunkSize

-- | A <i>relative</i> slot within a chunk
data RelativeSlot
RelativeSlot :: !ChunkNo -> !ChunkSize -> !Word64 -> RelativeSlot

-- | The chunk index of the chunk this slot is in
--   
--   Recorded primarily to be able to define a semi-sensible <a>Ord</a>
--   instance.
[relativeSlotChunkNo] :: RelativeSlot -> !ChunkNo

-- | The size of the chunk that this slot is in
--   
--   We record this for bounds checking as well as to be able to answer
--   questions such as <tt>relativeSlotIsEBB</tt>.
[relativeSlotChunkSize] :: RelativeSlot -> !ChunkSize

-- | The index within the chunk
[relativeSlotIndex] :: RelativeSlot -> !Word64

-- | Maximum relative index within a chunk
maxRelativeIndex :: ChunkSize -> Word64

-- | Smart constructor for <a>RelativeSlot</a>
mkRelativeSlot :: HasCallStack => ChunkInfo -> ChunkNo -> Word64 -> RelativeSlot
assertRelativeSlotInChunk :: HasCallStack => ChunkNo -> RelativeSlot -> Word64

-- | <a>RelativeSlot</a> is partially ordered, not totally ordered
--   
--   It makes no sense to compare <tt>RelativeSlots</tt> from different
--   chunks. Doing so will result in an assertion failure.
compareRelativeSlot :: HasCallStack => RelativeSlot -> RelativeSlot -> Ordering
data ChunkAssertionFailure
assertSameChunk :: HasCallStack => ChunkNo -> ChunkNo -> a -> a
assertWithinBounds :: HasCallStack => Word64 -> ChunkSize -> a -> a
assertChunkCanContainEBB :: HasCallStack => ChunkNo -> ChunkSize -> a -> a
instance NoThunks.Class.NoThunks Ouroboros.Consensus.Storage.ImmutableDB.Chunks.Internal.ChunkSize
instance GHC.Generics.Generic Ouroboros.Consensus.Storage.ImmutableDB.Chunks.Internal.ChunkSize
instance GHC.Show.Show Ouroboros.Consensus.Storage.ImmutableDB.Chunks.Internal.ChunkSize
instance NoThunks.Class.NoThunks Ouroboros.Consensus.Storage.ImmutableDB.Chunks.Internal.ChunkInfo
instance GHC.Generics.Generic Ouroboros.Consensus.Storage.ImmutableDB.Chunks.Internal.ChunkInfo
instance GHC.Show.Show Ouroboros.Consensus.Storage.ImmutableDB.Chunks.Internal.ChunkInfo
instance NoThunks.Class.NoThunks Ouroboros.Consensus.Storage.ImmutableDB.Chunks.Internal.ChunkNo
instance GHC.Show.Show Ouroboros.Consensus.Storage.ImmutableDB.Chunks.Internal.ChunkNo
instance GHC.Generics.Generic Ouroboros.Consensus.Storage.ImmutableDB.Chunks.Internal.ChunkNo
instance GHC.Classes.Ord Ouroboros.Consensus.Storage.ImmutableDB.Chunks.Internal.ChunkNo
instance GHC.Classes.Eq Ouroboros.Consensus.Storage.ImmutableDB.Chunks.Internal.ChunkNo
instance NoThunks.Class.NoThunks Ouroboros.Consensus.Storage.ImmutableDB.Chunks.Internal.RelativeSlot
instance GHC.Generics.Generic Ouroboros.Consensus.Storage.ImmutableDB.Chunks.Internal.RelativeSlot
instance GHC.Show.Show Ouroboros.Consensus.Storage.ImmutableDB.Chunks.Internal.RelativeSlot
instance GHC.Show.Show Ouroboros.Consensus.Storage.ImmutableDB.Chunks.Internal.ChunkAssertionFailure
instance GHC.Exception.Type.Exception Ouroboros.Consensus.Storage.ImmutableDB.Chunks.Internal.ChunkAssertionFailure
instance GHC.Classes.Eq Ouroboros.Consensus.Storage.ImmutableDB.Chunks.Internal.RelativeSlot

module Ouroboros.Consensus.Ledger.Inspect
data LedgerEvent blk
LedgerWarning :: LedgerWarning blk -> LedgerEvent blk
LedgerUpdate :: LedgerUpdate blk -> LedgerEvent blk
castLedgerEvent :: (LedgerWarning blk ~ LedgerWarning blk', LedgerUpdate blk ~ LedgerUpdate blk') => LedgerEvent blk -> LedgerEvent blk'
partitionLedgerEvents :: [LedgerEvent blk] -> ([LedgerWarning blk], [LedgerUpdate blk])
class (Show (LedgerWarning blk), Show (LedgerUpdate blk), Eq (LedgerWarning blk), Eq (LedgerUpdate blk), Condense (LedgerUpdate blk)) => InspectLedger blk where {
    type family LedgerWarning blk :: Type;
    type family LedgerUpdate blk :: Type;
    type LedgerWarning blk = Void;
    type LedgerUpdate blk = Void;
}

-- | Inspect the ledger
--   
--   The point of the inspection is to see if the state of the ledger might
--   indicate a potential misconfiguration of the node.
--   
--   TODO: We might at some point need to generalize this to
--   <tt>ExtLedgerState</tt> instead. That doesn't fit quite so neatly with
--   the HFC at present, so leaving it at this for now.
inspectLedger :: InspectLedger blk => TopLevelConfig blk -> LedgerState blk -> LedgerState blk -> [LedgerEvent blk]

-- | Inspect the ledger
--   
--   The point of the inspection is to see if the state of the ledger might
--   indicate a potential misconfiguration of the node.
--   
--   TODO: We might at some point need to generalize this to
--   <tt>ExtLedgerState</tt> instead. That doesn't fit quite so neatly with
--   the HFC at present, so leaving it at this for now.
inspectLedger :: (InspectLedger blk, LedgerWarning blk ~ Void, LedgerUpdate blk ~ Void) => TopLevelConfig blk -> LedgerState blk -> LedgerState blk -> [LedgerEvent blk]
instance Ouroboros.Consensus.Ledger.Inspect.InspectLedger blk => GHC.Show.Show (Ouroboros.Consensus.Ledger.Inspect.LedgerEvent blk)
instance Ouroboros.Consensus.Ledger.Inspect.InspectLedger blk => GHC.Classes.Eq (Ouroboros.Consensus.Ledger.Inspect.LedgerEvent blk)


-- | Newtypes around type families so that they can be partially applied
module Ouroboros.Consensus.TypeFamilyWrappers
newtype WrapApplyTxErr blk
WrapApplyTxErr :: ApplyTxErr blk -> WrapApplyTxErr blk
[unwrapApplyTxErr] :: WrapApplyTxErr blk -> ApplyTxErr blk
newtype WrapCannotForge blk
WrapCannotForge :: CannotForge blk -> WrapCannotForge blk
[unwrapCannotForge] :: WrapCannotForge blk -> CannotForge blk
newtype WrapEnvelopeErr blk
WrapEnvelopeErr :: OtherHeaderEnvelopeError blk -> WrapEnvelopeErr blk
[unwrapEnvelopeErr] :: WrapEnvelopeErr blk -> OtherHeaderEnvelopeError blk
newtype WrapForgeStateInfo blk
WrapForgeStateInfo :: ForgeStateInfo blk -> WrapForgeStateInfo blk
[unwrapForgeStateInfo] :: WrapForgeStateInfo blk -> ForgeStateInfo blk
newtype WrapForgeStateUpdateError blk
WrapForgeStateUpdateError :: ForgeStateUpdateError blk -> WrapForgeStateUpdateError blk
[unwrapForgeStateUpdateError] :: WrapForgeStateUpdateError blk -> ForgeStateUpdateError blk
newtype WrapGenTxId blk
WrapGenTxId :: GenTxId blk -> WrapGenTxId blk
[unwrapGenTxId] :: WrapGenTxId blk -> GenTxId blk
newtype WrapHeaderHash blk
WrapHeaderHash :: HeaderHash blk -> WrapHeaderHash blk
[unwrapHeaderHash] :: WrapHeaderHash blk -> HeaderHash blk
newtype WrapLedgerConfig blk
WrapLedgerConfig :: LedgerConfig blk -> WrapLedgerConfig blk
[unwrapLedgerConfig] :: WrapLedgerConfig blk -> LedgerConfig blk
newtype WrapLedgerErr blk
WrapLedgerErr :: LedgerError blk -> WrapLedgerErr blk
[unwrapLedgerErr] :: WrapLedgerErr blk -> LedgerError blk
newtype WrapLedgerUpdate blk
WrapLedgerUpdate :: LedgerUpdate blk -> WrapLedgerUpdate blk
[unwrapLedgerUpdate] :: WrapLedgerUpdate blk -> LedgerUpdate blk
newtype WrapLedgerWarning blk
WrapLedgerWarning :: LedgerWarning blk -> WrapLedgerWarning blk
[unwrapLedgerWarning] :: WrapLedgerWarning blk -> LedgerWarning blk
newtype WrapTipInfo blk
WrapTipInfo :: TipInfo blk -> WrapTipInfo blk
[unwrapTipInfo] :: WrapTipInfo blk -> TipInfo blk
newtype WrapCanBeLeader blk
WrapCanBeLeader :: CanBeLeader (BlockProtocol blk) -> WrapCanBeLeader blk
[unwrapCanBeLeader] :: WrapCanBeLeader blk -> CanBeLeader (BlockProtocol blk)
newtype WrapChainDepState blk
WrapChainDepState :: ChainDepState (BlockProtocol blk) -> WrapChainDepState blk
[unwrapChainDepState] :: WrapChainDepState blk -> ChainDepState (BlockProtocol blk)
newtype WrapChainSelConfig blk
WrapChainSelConfig :: ChainSelConfig (BlockProtocol blk) -> WrapChainSelConfig blk
[unwrapChainSelConfig] :: WrapChainSelConfig blk -> ChainSelConfig (BlockProtocol blk)
newtype WrapConsensusConfig blk
WrapConsensusConfig :: ConsensusConfig (BlockProtocol blk) -> WrapConsensusConfig blk
[unwrapConsensusConfig] :: WrapConsensusConfig blk -> ConsensusConfig (BlockProtocol blk)
newtype WrapIsLeader blk
WrapIsLeader :: IsLeader (BlockProtocol blk) -> WrapIsLeader blk
[unwrapIsLeader] :: WrapIsLeader blk -> IsLeader (BlockProtocol blk)
newtype WrapLedgerView blk
WrapLedgerView :: LedgerView (BlockProtocol blk) -> WrapLedgerView blk
[unwrapLedgerView] :: WrapLedgerView blk -> LedgerView (BlockProtocol blk)
newtype WrapSelectView blk
WrapSelectView :: SelectView (BlockProtocol blk) -> WrapSelectView blk
[unwrapSelectView] :: WrapSelectView blk -> SelectView (BlockProtocol blk)
newtype WrapValidateView blk
WrapValidateView :: ValidateView (BlockProtocol blk) -> WrapValidateView blk
[unwrapValidateView] :: WrapValidateView blk -> ValidateView (BlockProtocol blk)
newtype WrapValidationErr blk
WrapValidationErr :: ValidationErr (BlockProtocol blk) -> WrapValidationErr blk
[unwrapValidationErr] :: WrapValidationErr blk -> ValidationErr (BlockProtocol blk)
newtype WrapNodeToNodeVersion blk
WrapNodeToNodeVersion :: BlockNodeToNodeVersion blk -> WrapNodeToNodeVersion blk
[unwrapNodeToNodeVersion] :: WrapNodeToNodeVersion blk -> BlockNodeToNodeVersion blk
newtype WrapNodeToClientVersion blk
WrapNodeToClientVersion :: BlockNodeToClientVersion blk -> WrapNodeToClientVersion blk
[unwrapNodeToClientVersion] :: WrapNodeToClientVersion blk -> BlockNodeToClientVersion blk

-- | " Ticked " piece of state (<tt>LedgerState</tt>, <tt>LedgerView</tt>,
--   <tt>ChainIndepState</tt>)
--   
--   Ticking refers to the passage of time (the ticking of the clock). When
--   a piece of state is marked as ticked, it means that time-related
--   changes have been applied to the state (or forecast).
--   
--   Some examples of time related changes:
--   
--   <ul>
--   <li>Scheduled delegations might have been applied in Byron</li>
--   <li>New leader schedule computed for Shelley</li>
--   <li>Transition from Byron to Shelley activated in the hard fork
--   combinator.</li>
--   <li>Nonces switched out at the start of a new epoch.</li>
--   </ul>
data family Ticked st :: Type
instance GHC.Classes.Eq (Ouroboros.Consensus.Ledger.SupportsMempool.ApplyTxErr blk) => GHC.Classes.Eq (Ouroboros.Consensus.TypeFamilyWrappers.WrapApplyTxErr blk)
instance GHC.Classes.Eq (Ouroboros.Consensus.Ledger.SupportsMempool.GenTxId blk) => GHC.Classes.Eq (Ouroboros.Consensus.TypeFamilyWrappers.WrapGenTxId blk)
instance GHC.Classes.Eq (Ouroboros.Consensus.Ledger.Basics.LedgerError blk) => GHC.Classes.Eq (Ouroboros.Consensus.TypeFamilyWrappers.WrapLedgerErr blk)
instance GHC.Classes.Eq (Ouroboros.Consensus.Ledger.Inspect.LedgerUpdate blk) => GHC.Classes.Eq (Ouroboros.Consensus.TypeFamilyWrappers.WrapLedgerUpdate blk)
instance GHC.Classes.Eq (Ouroboros.Consensus.Ledger.Inspect.LedgerWarning blk) => GHC.Classes.Eq (Ouroboros.Consensus.TypeFamilyWrappers.WrapLedgerWarning blk)
instance GHC.Classes.Eq (Ouroboros.Consensus.HeaderValidation.OtherHeaderEnvelopeError blk) => GHC.Classes.Eq (Ouroboros.Consensus.TypeFamilyWrappers.WrapEnvelopeErr blk)
instance GHC.Classes.Eq (Ouroboros.Consensus.HeaderValidation.TipInfo blk) => GHC.Classes.Eq (Ouroboros.Consensus.TypeFamilyWrappers.WrapTipInfo blk)
instance GHC.Classes.Ord (Ouroboros.Consensus.Ledger.SupportsMempool.GenTxId blk) => GHC.Classes.Ord (Ouroboros.Consensus.TypeFamilyWrappers.WrapGenTxId blk)
instance GHC.Show.Show (Ouroboros.Consensus.Ledger.SupportsMempool.ApplyTxErr blk) => GHC.Show.Show (Ouroboros.Consensus.TypeFamilyWrappers.WrapApplyTxErr blk)
instance GHC.Show.Show (Ouroboros.Consensus.Block.Forging.CannotForge blk) => GHC.Show.Show (Ouroboros.Consensus.TypeFamilyWrappers.WrapCannotForge blk)
instance GHC.Show.Show (Ouroboros.Consensus.Block.Forging.ForgeStateInfo blk) => GHC.Show.Show (Ouroboros.Consensus.TypeFamilyWrappers.WrapForgeStateInfo blk)
instance GHC.Show.Show (Ouroboros.Consensus.Block.Forging.ForgeStateUpdateError blk) => GHC.Show.Show (Ouroboros.Consensus.TypeFamilyWrappers.WrapForgeStateUpdateError blk)
instance GHC.Show.Show (Ouroboros.Consensus.Ledger.SupportsMempool.GenTxId blk) => GHC.Show.Show (Ouroboros.Consensus.TypeFamilyWrappers.WrapGenTxId blk)
instance GHC.Show.Show (Ouroboros.Consensus.Ledger.Basics.LedgerError blk) => GHC.Show.Show (Ouroboros.Consensus.TypeFamilyWrappers.WrapLedgerErr blk)
instance GHC.Show.Show (Ouroboros.Consensus.Ledger.Inspect.LedgerUpdate blk) => GHC.Show.Show (Ouroboros.Consensus.TypeFamilyWrappers.WrapLedgerUpdate blk)
instance GHC.Show.Show (Ouroboros.Consensus.Ledger.Inspect.LedgerWarning blk) => GHC.Show.Show (Ouroboros.Consensus.TypeFamilyWrappers.WrapLedgerWarning blk)
instance GHC.Show.Show (Ouroboros.Consensus.HeaderValidation.OtherHeaderEnvelopeError blk) => GHC.Show.Show (Ouroboros.Consensus.TypeFamilyWrappers.WrapEnvelopeErr blk)
instance GHC.Show.Show (Ouroboros.Consensus.HeaderValidation.TipInfo blk) => GHC.Show.Show (Ouroboros.Consensus.TypeFamilyWrappers.WrapTipInfo blk)
instance NoThunks.Class.NoThunks (Ouroboros.Consensus.Ledger.SupportsMempool.GenTxId blk) => NoThunks.Class.NoThunks (Ouroboros.Consensus.TypeFamilyWrappers.WrapGenTxId blk)
instance NoThunks.Class.NoThunks (Ouroboros.Consensus.Ledger.Basics.LedgerError blk) => NoThunks.Class.NoThunks (Ouroboros.Consensus.TypeFamilyWrappers.WrapLedgerErr blk)
instance NoThunks.Class.NoThunks (Ouroboros.Consensus.HeaderValidation.OtherHeaderEnvelopeError blk) => NoThunks.Class.NoThunks (Ouroboros.Consensus.TypeFamilyWrappers.WrapEnvelopeErr blk)
instance NoThunks.Class.NoThunks (Ouroboros.Consensus.HeaderValidation.TipInfo blk) => NoThunks.Class.NoThunks (Ouroboros.Consensus.TypeFamilyWrappers.WrapTipInfo blk)
instance GHC.Classes.Eq (Ouroboros.Consensus.Protocol.Abstract.ChainDepState (Ouroboros.Consensus.Block.Abstract.BlockProtocol blk)) => GHC.Classes.Eq (Ouroboros.Consensus.TypeFamilyWrappers.WrapChainDepState blk)
instance GHC.Classes.Eq (Ouroboros.Consensus.Protocol.Abstract.ChainSelConfig (Ouroboros.Consensus.Block.Abstract.BlockProtocol blk)) => GHC.Classes.Eq (Ouroboros.Consensus.TypeFamilyWrappers.WrapChainSelConfig blk)
instance GHC.Classes.Eq (Ouroboros.Consensus.Protocol.Abstract.ValidationErr (Ouroboros.Consensus.Block.Abstract.BlockProtocol blk)) => GHC.Classes.Eq (Ouroboros.Consensus.TypeFamilyWrappers.WrapValidationErr blk)
instance GHC.Show.Show (Ouroboros.Consensus.Protocol.Abstract.ChainDepState (Ouroboros.Consensus.Block.Abstract.BlockProtocol blk)) => GHC.Show.Show (Ouroboros.Consensus.TypeFamilyWrappers.WrapChainDepState blk)
instance GHC.Show.Show (Ouroboros.Consensus.Protocol.Abstract.ChainSelConfig (Ouroboros.Consensus.Block.Abstract.BlockProtocol blk)) => GHC.Show.Show (Ouroboros.Consensus.TypeFamilyWrappers.WrapChainSelConfig blk)
instance GHC.Show.Show (Ouroboros.Consensus.Protocol.Abstract.LedgerView (Ouroboros.Consensus.Block.Abstract.BlockProtocol blk)) => GHC.Show.Show (Ouroboros.Consensus.TypeFamilyWrappers.WrapLedgerView blk)
instance GHC.Show.Show (Ouroboros.Consensus.Protocol.Abstract.SelectView (Ouroboros.Consensus.Block.Abstract.BlockProtocol blk)) => GHC.Show.Show (Ouroboros.Consensus.TypeFamilyWrappers.WrapSelectView blk)
instance GHC.Show.Show (Ouroboros.Consensus.Protocol.Abstract.ValidationErr (Ouroboros.Consensus.Block.Abstract.BlockProtocol blk)) => GHC.Show.Show (Ouroboros.Consensus.TypeFamilyWrappers.WrapValidationErr blk)
instance NoThunks.Class.NoThunks (Ouroboros.Consensus.Protocol.Abstract.ChainSelConfig (Ouroboros.Consensus.Block.Abstract.BlockProtocol blk)) => NoThunks.Class.NoThunks (Ouroboros.Consensus.TypeFamilyWrappers.WrapChainSelConfig blk)
instance NoThunks.Class.NoThunks (Ouroboros.Consensus.Protocol.Abstract.ChainDepState (Ouroboros.Consensus.Block.Abstract.BlockProtocol blk)) => NoThunks.Class.NoThunks (Ouroboros.Consensus.TypeFamilyWrappers.WrapChainDepState blk)
instance NoThunks.Class.NoThunks (Ouroboros.Consensus.Protocol.Abstract.ValidationErr (Ouroboros.Consensus.Block.Abstract.BlockProtocol blk)) => NoThunks.Class.NoThunks (Ouroboros.Consensus.TypeFamilyWrappers.WrapValidationErr blk)
instance GHC.Show.Show (Ouroboros.Consensus.Node.NetworkProtocolVersion.BlockNodeToNodeVersion blk) => GHC.Show.Show (Ouroboros.Consensus.TypeFamilyWrappers.WrapNodeToNodeVersion blk)
instance GHC.Show.Show (Ouroboros.Consensus.Node.NetworkProtocolVersion.BlockNodeToClientVersion blk) => GHC.Show.Show (Ouroboros.Consensus.TypeFamilyWrappers.WrapNodeToClientVersion blk)
instance GHC.Classes.Eq (Ouroboros.Consensus.Node.NetworkProtocolVersion.BlockNodeToNodeVersion blk) => GHC.Classes.Eq (Ouroboros.Consensus.TypeFamilyWrappers.WrapNodeToNodeVersion blk)
instance GHC.Classes.Eq (Ouroboros.Consensus.Node.NetworkProtocolVersion.BlockNodeToClientVersion blk) => GHC.Classes.Eq (Ouroboros.Consensus.TypeFamilyWrappers.WrapNodeToClientVersion blk)
instance Codec.Serialise.Class.Serialise (Ouroboros.Consensus.Ledger.SupportsMempool.GenTxId blk) => Codec.Serialise.Class.Serialise (Ouroboros.Consensus.TypeFamilyWrappers.WrapGenTxId blk)
instance Codec.Serialise.Class.Serialise (Ouroboros.Consensus.Protocol.Abstract.ChainDepState (Ouroboros.Consensus.Block.Abstract.BlockProtocol blk)) => Codec.Serialise.Class.Serialise (Ouroboros.Consensus.TypeFamilyWrappers.WrapChainDepState blk)
instance Codec.Serialise.Class.Serialise (Ouroboros.Consensus.HeaderValidation.TipInfo blk) => Codec.Serialise.Class.Serialise (Ouroboros.Consensus.TypeFamilyWrappers.WrapTipInfo blk)


-- | Serialisation for on-disk storage.
--   
--   We have separate classes for on-disk and on-the-wire serialisation,
--   because the encoding formats of the same type may differ, depending on
--   the context.
--   
--   We separate the encoder from the decoder, because sometimes the
--   encoded type will differ from the decoded one. For example, we encode
--   a <tt>blk</tt>, but decode an <tt><a>ByteString</a> -&gt; blk</tt>
--   (when reading something from disk, we have the precise bytestring that
--   we can pass in as the annotation). If we coupled the encoder to the
--   decoder, we wouldn't be able to cleanly model this use case. Moreover,
--   sometimes we only need a single direction.
module Ouroboros.Consensus.Storage.Serialisation

-- | Encode a type <tt>a</tt> so that it can be stored on disk.
--   
--   There is no version negotiation for on disk serialisation. However,
--   instances can still decide to perform versioning internally to
--   maintain compatibility.
class EncodeDisk blk a
encodeDisk :: EncodeDisk blk a => CodecConfig blk -> a -> Encoding
encodeDisk :: (EncodeDisk blk a, Serialise a) => CodecConfig blk -> a -> Encoding

-- | Decode a type <tt>a</tt> read from disk.
--   
--   There is no version negotiation for on disk serialisation. However,
--   instances can still decide to perform versioning internally to
--   maintain compatibility.
class DecodeDisk blk a
decodeDisk :: DecodeDisk blk a => CodecConfig blk -> forall s. Decoder s a
decodeDisk :: (DecodeDisk blk a, Serialise a) => CodecConfig blk -> forall s. Decoder s a

-- | Encode dependent index
class EncodeDiskDepIx f blk
encodeDiskDepIx :: EncodeDiskDepIx f blk => CodecConfig blk -> SomeSecond f blk -> Encoding
encodeDiskDepIx :: (EncodeDiskDepIx f blk, TrivialDependency (f blk)) => CodecConfig blk -> SomeSecond f blk -> Encoding

-- | Encode a dependent value
class EncodeDiskDep f blk
encodeDiskDep :: EncodeDiskDep f blk => CodecConfig blk -> f blk a -> a -> Encoding
encodeDiskDep :: (EncodeDiskDep f blk, TrivialDependency (f blk), EncodeDisk blk (TrivialIndex (f blk))) => CodecConfig blk -> f blk a -> a -> Encoding

-- | Decode dependent index
class DecodeDiskDepIx f blk
decodeDiskDepIx :: DecodeDiskDepIx f blk => CodecConfig blk -> Decoder s (SomeSecond f blk)
decodeDiskDepIx :: (DecodeDiskDepIx f blk, TrivialDependency (f blk)) => CodecConfig blk -> Decoder s (SomeSecond f blk)

-- | Decode a dependent value
--   
--   Typical usage: <tt>f = NestedCtxt Header</tt>.
class DecodeDiskDep f blk
decodeDiskDep :: DecodeDiskDep f blk => CodecConfig blk -> f blk a -> forall s. Decoder s (ByteString -> a)
decodeDiskDep :: (DecodeDiskDep f blk, TrivialDependency (f blk), DecodeDisk blk (ByteString -> TrivialIndex (f blk))) => CodecConfig blk -> f blk a -> forall s. Decoder s (ByteString -> a)

-- | A <a>Serialised</a> header along with context identifying what kind of
--   header it is.
--   
--   The <tt>SerialiseNodeToNodeDep</tt> for <a>Header</a> will decide how
--   to actually encode this.
newtype SerialisedHeader blk
SerialisedHeaderFromDepPair :: GenDepPair Serialised (NestedCtxt Header blk) -> SerialisedHeader blk
[serialisedHeaderToDepPair] :: SerialisedHeader blk -> GenDepPair Serialised (NestedCtxt Header blk)
serialisedHeaderToPair :: SerialisedHeader blk -> (SomeSecond (NestedCtxt Header) blk, ByteString)
serialisedHeaderFromPair :: (SomeSecond (NestedCtxt Header) blk, ByteString) -> SerialisedHeader blk
castSerialisedHeader :: (forall a. NestedCtxt_ blk Header a -> NestedCtxt_ blk' Header a) -> SerialisedHeader blk -> SerialisedHeader blk'

-- | Encode the header without the <a>NestedCtxt</a>
--   
--   Uses CBOR-in-CBOR
encodeTrivialSerialisedHeader :: forall blk. TrivialDependency (NestedCtxt_ blk Header) => SerialisedHeader blk -> Encoding

-- | Inverse to <a>encodeTrivialSerialisedHeader</a>
decodeTrivialSerialisedHeader :: forall blk. TrivialDependency (NestedCtxt_ blk Header) => forall s. Decoder s (SerialisedHeader blk)
class HasNestedContent f blk => ReconstructNestedCtxt f blk

-- | Number of bytes required to reconstruct the nested context.
--   
--   This will be the <i>minimum</i> length of the <a>ShortByteString</a>
--   passed to <a>reconstructNestedCtxt</a>.
reconstructPrefixLen :: ReconstructNestedCtxt f blk => proxy (f blk) -> PrefixLen

-- | Reconstruct the type of nested contents
--   
--   TODO: Allow to fail.
reconstructNestedCtxt :: ReconstructNestedCtxt f blk => proxy (f blk) -> ShortByteString -> SizeInBytes -> SomeSecond (NestedCtxt f) blk

-- | Number of bytes required to reconstruct the nested context.
--   
--   This will be the <i>minimum</i> length of the <a>ShortByteString</a>
--   passed to <a>reconstructNestedCtxt</a>.
reconstructPrefixLen :: (ReconstructNestedCtxt f blk, TrivialDependency (NestedCtxt_ blk f)) => proxy (f blk) -> PrefixLen

-- | Reconstruct the type of nested contents
--   
--   TODO: Allow to fail.
reconstructNestedCtxt :: (ReconstructNestedCtxt f blk, TrivialDependency (NestedCtxt_ blk f)) => proxy (f blk) -> ShortByteString -> SizeInBytes -> SomeSecond (NestedCtxt f) blk

-- | Number of bytes from the start of a block needed to reconstruct the
--   nested context.
--   
--   See <tt>reconstructPrefixLen</tt>.
newtype PrefixLen
PrefixLen :: Word8 -> PrefixLen
[getPrefixLen] :: PrefixLen -> Word8
addPrefixLen :: Word8 -> PrefixLen -> PrefixLen
takePrefix :: PrefixLen -> ByteString -> ShortByteString
class HasBinaryBlockInfo blk

-- | Return information about the serialised block, i.e., how to extract
--   the bytes corresponding to the header from the serialised block.
getBinaryBlockInfo :: HasBinaryBlockInfo blk => blk -> BinaryBlockInfo

-- | Information about the serialised block.
data BinaryBlockInfo
BinaryBlockInfo :: !Word16 -> !Word16 -> BinaryBlockInfo

-- | The offset within the serialised block at which the header starts.
[headerOffset] :: BinaryBlockInfo -> !Word16

-- | How many bytes the header is long. Extracting the <a>headerSize</a>
--   bytes from serialised block starting from <a>headerOffset</a> should
--   yield the header. Before passing the extracted bytes to the decoder
--   for headers, an envelope can be around using
--   <tt>nodeAddHeaderEnvelope</tt>.
[headerSize] :: BinaryBlockInfo -> !Word16
type SizeInBytes = Word32
encodeDepPair :: EncodeDiskDep f blk => CodecConfig blk -> DepPair (f blk) -> GenDepPair Serialised (f blk)
decodeDepPair :: DecodeDiskDep f blk => CodecConfig blk -> GenDepPair Serialised (f blk) -> Decoder s (DepPair (f blk))
instance Ouroboros.Consensus.Block.NestedContent.HasNestedContent Ouroboros.Consensus.Block.Abstract.Header blk => GHC.Show.Show (Ouroboros.Consensus.Storage.Serialisation.SerialisedHeader blk)
instance Ouroboros.Network.Util.ShowProxy.ShowProxy blk => Ouroboros.Network.Util.ShowProxy.ShowProxy (Ouroboros.Consensus.Storage.Serialisation.SerialisedHeader blk)
instance Ouroboros.Network.Block.StandardHash blk => Ouroboros.Network.Block.StandardHash (Ouroboros.Consensus.Storage.Serialisation.SerialisedHeader blk)
instance Ouroboros.Consensus.Storage.Serialisation.EncodeDiskDepIx (Ouroboros.Consensus.Block.NestedContent.NestedCtxt Ouroboros.Consensus.Block.Abstract.Header) blk => Ouroboros.Consensus.Storage.Serialisation.EncodeDisk blk (Ouroboros.Consensus.Storage.Serialisation.SerialisedHeader blk)
instance Ouroboros.Consensus.Storage.Serialisation.DecodeDiskDepIx (Ouroboros.Consensus.Block.NestedContent.NestedCtxt Ouroboros.Consensus.Block.Abstract.Header) blk => Ouroboros.Consensus.Storage.Serialisation.DecodeDisk blk (Ouroboros.Consensus.Storage.Serialisation.SerialisedHeader blk)
instance (Ouroboros.Consensus.Storage.Serialisation.DecodeDiskDepIx f blk, Ouroboros.Consensus.Storage.Serialisation.DecodeDiskDep f blk) => Ouroboros.Consensus.Storage.Serialisation.DecodeDisk blk (Ouroboros.Consensus.Util.DepPair.DepPair (f blk))
instance Ouroboros.Consensus.Storage.Serialisation.DecodeDiskDepIx f blk => Ouroboros.Consensus.Storage.Serialisation.DecodeDisk blk (Ouroboros.Consensus.Util.DepPair.GenDepPair Ouroboros.Network.Block.Serialised (f blk))
instance (Ouroboros.Consensus.Storage.Serialisation.EncodeDiskDepIx f blk, Ouroboros.Consensus.Storage.Serialisation.EncodeDiskDep f blk) => Ouroboros.Consensus.Storage.Serialisation.EncodeDisk blk (Ouroboros.Consensus.Util.DepPair.DepPair (f blk))
instance Ouroboros.Consensus.Storage.Serialisation.EncodeDiskDepIx f blk => Ouroboros.Consensus.Storage.Serialisation.EncodeDisk blk (Ouroboros.Consensus.Util.DepPair.GenDepPair Ouroboros.Network.Block.Serialised (f blk))
instance Ouroboros.Consensus.Storage.Serialisation.DecodeDisk blk (Ouroboros.Consensus.Protocol.Abstract.ChainDepState (Ouroboros.Consensus.Block.Abstract.BlockProtocol blk)) => Ouroboros.Consensus.Storage.Serialisation.DecodeDisk blk (Ouroboros.Consensus.TypeFamilyWrappers.WrapChainDepState blk)
instance Ouroboros.Consensus.Storage.Serialisation.DecodeDisk blk blk => Ouroboros.Consensus.Storage.Serialisation.DecodeDisk blk (Data.SOP.BasicFunctors.I blk)
instance Ouroboros.Consensus.Storage.Serialisation.DecodeDisk blk (a -> f blk) => Ouroboros.Consensus.Storage.Serialisation.DecodeDisk blk ((Data.SOP.BasicFunctors.:.:) ((->) a) f blk)
instance Ouroboros.Consensus.Storage.Serialisation.EncodeDisk blk (Ouroboros.Consensus.Protocol.Abstract.ChainDepState (Ouroboros.Consensus.Block.Abstract.BlockProtocol blk)) => Ouroboros.Consensus.Storage.Serialisation.EncodeDisk blk (Ouroboros.Consensus.TypeFamilyWrappers.WrapChainDepState blk)
instance Ouroboros.Consensus.Storage.Serialisation.EncodeDisk blk blk => Ouroboros.Consensus.Storage.Serialisation.EncodeDisk blk (Data.SOP.BasicFunctors.I blk)

module Ouroboros.Consensus.Storage.VolatileDB.Impl.Parser

-- | Parse the given file containing blocks.
--   
--   Return the <a>ParsedBlockInfo</a> for all the valid blocks in the
--   file. Stop when encountering an error and include the offset to
--   truncate to.
parseBlockFile :: forall m blk h. (IOLike m, GetPrevHash blk, HasBinaryBlockInfo blk, HasNestedContent Header blk, DecodeDisk blk (ByteString -> blk)) => CodecConfig blk -> HasFS m h -> (blk -> Bool) -> BlockValidationPolicy -> FsPath -> m ([ParsedBlockInfo blk], Maybe (ParseError blk, BlockOffset))

-- | Information returned by the parser about a single block.
--   
--   The parser returns for each block, its offset, its size and its
--   <a>BlockInfo</a>
--   
--   The fields of this record are strict to make sure that by evaluating
--   this record to WHNF, we no longer hold on to the entire block.
--   Otherwise, we might accidentally keep all blocks in a single file in
--   memory during parsing.
data ParsedBlockInfo blk
ParsedBlockInfo :: !BlockOffset -> !BlockSize -> !BlockInfo blk -> !SomeSecond (NestedCtxt Header) blk -> ParsedBlockInfo blk
[pbiBlockOffset] :: ParsedBlockInfo blk -> !BlockOffset
[pbiBlockSize] :: ParsedBlockInfo blk -> !BlockSize
[pbiBlockInfo] :: ParsedBlockInfo blk -> !BlockInfo blk
[pbiNestedCtxt] :: ParsedBlockInfo blk -> !SomeSecond (NestedCtxt Header) blk

-- | Note that we recover from the error, and thus never throw it as an
--   <tt>Exception</tt>.
--   
--   Defined here instead of in the <tt>Parser</tt> module because
--   <a>TraceEvent</a> depends on it.
data ParseError blk

-- | A block could not be parsed.
BlockReadErr :: ReadIncrementalErr -> ParseError blk

-- | A block was corrupted, e.g., checking its signature and/or hash
--   failed.
BlockCorruptedErr :: HeaderHash blk -> ParseError blk

-- | A block with the same hash occurred twice in the VolatileDB files.
--   
--   We include the file in which it occurred first and the file in which
--   it occured the second time. The two files can be the same.
DuplicatedBlock :: HeaderHash blk -> FsPath -> FsPath -> ParseError blk
extractBlockInfo :: (GetPrevHash blk, HasBinaryBlockInfo blk) => blk -> BlockInfo blk


-- | Information about the files stored by the volatile DB
--   
--   Intended for qualified import.
module Ouroboros.Consensus.Storage.VolatileDB.Impl.FileInfo

-- | The internal information the VolatileDB keeps for each file.
data FileInfo blk
empty :: FileInfo blk

-- | Adds a block to a <a>FileInfo</a>.
addBlock :: StandardHash blk => SlotNo -> HeaderHash blk -> FileInfo blk -> FileInfo blk

-- | Construct a <a>FileInfo</a> from the parser result.
fromParsedBlockInfos :: forall blk. StandardHash blk => [ParsedBlockInfo blk] -> FileInfo blk
maxSlotNo :: FileInfo blk -> MaxSlotNo
hashes :: FileInfo blk -> Set (HeaderHash blk)

-- | Checks if this file can be GCed.
canGC :: FileInfo blk -> SlotNo -> Bool

-- | Has this file reached its maximum size?
isFull :: BlocksPerFile -> FileInfo blk -> Bool
maxSlotNoInFiles :: [FileInfo blk] -> MaxSlotNo
instance GHC.Generics.Generic (Ouroboros.Consensus.Storage.VolatileDB.Impl.FileInfo.FileInfo blk)
instance Ouroboros.Network.Block.StandardHash blk => GHC.Show.Show (Ouroboros.Consensus.Storage.VolatileDB.Impl.FileInfo.FileInfo blk)
instance Ouroboros.Network.Block.StandardHash blk => NoThunks.Class.NoThunks (Ouroboros.Consensus.Storage.VolatileDB.Impl.FileInfo.FileInfo blk)


-- | VolatileDB Index
--   
--   Intended for qualified import &gt; import qualified
--   Ouroboros.Consensus.Storage.VolatileDB.Impl.Index as Index
module Ouroboros.Consensus.Storage.VolatileDB.Impl.Index

-- | Mapping from <a>FileId</a> to <a>FileInfo</a>
data Index blk
empty :: Index blk
lookup :: FileId -> Index blk -> Maybe (FileInfo blk)
insert :: FileId -> FileInfo blk -> Index blk -> Index blk
delete :: FileId -> Index blk -> Index blk
toAscList :: Index blk -> [(FileId, FileInfo blk)]
elems :: Index blk -> [FileInfo blk]

-- | Return the last, i.e. the <i>highest</i>, <a>FileId</a> and
--   corresponding <a>FileInfo</a> stored in the <a>Index</a>. Return
--   <a>Nothing</a> when empty.
lastFile :: Index blk -> Maybe (FileId, FileInfo blk)
instance Ouroboros.Network.Block.StandardHash blk => NoThunks.Class.NoThunks (Ouroboros.Consensus.Storage.VolatileDB.Impl.Index.Index blk)
instance GHC.Generics.Generic (Ouroboros.Consensus.Storage.VolatileDB.Impl.Index.Index blk)


-- | Serialisation for sending things across the network.
--   
--   We separate <tt>NodeToNode</tt> from <tt>NodeToClient</tt> to be very
--   explicit about what gets sent where.
--   
--   Unlike in <a>Ouroboros.Consensus.Storage.Serialisation</a>, we don't
--   separate the encoder from the decoder, because the reasons don't
--   apply: we always need both directions and we don't have access to the
--   bytestrings that could be used for the annotations (we use
--   CBOR-in-CBOR in those cases).
module Ouroboros.Consensus.Node.Serialisation

-- | Serialise a type <tt>a</tt> so that it can be sent across network via
--   a node-to-node protocol.
class SerialiseNodeToNode blk a
encodeNodeToNode :: SerialiseNodeToNode blk a => CodecConfig blk -> BlockNodeToNodeVersion blk -> a -> Encoding
decodeNodeToNode :: SerialiseNodeToNode blk a => CodecConfig blk -> BlockNodeToNodeVersion blk -> forall s. Decoder s a
encodeNodeToNode :: (SerialiseNodeToNode blk a, Serialise a) => CodecConfig blk -> BlockNodeToNodeVersion blk -> a -> Encoding
decodeNodeToNode :: (SerialiseNodeToNode blk a, Serialise a) => CodecConfig blk -> BlockNodeToNodeVersion blk -> forall s. Decoder s a

-- | Serialise a type <tt>a</tt> so that it can be sent across the network
--   via node-to-client protocol.
class SerialiseNodeToClient blk a
encodeNodeToClient :: SerialiseNodeToClient blk a => CodecConfig blk -> BlockNodeToClientVersion blk -> a -> Encoding
decodeNodeToClient :: SerialiseNodeToClient blk a => CodecConfig blk -> BlockNodeToClientVersion blk -> forall s. Decoder s a
encodeNodeToClient :: (SerialiseNodeToClient blk a, Serialise a) => CodecConfig blk -> BlockNodeToClientVersion blk -> a -> Encoding
decodeNodeToClient :: (SerialiseNodeToClient blk a, Serialise a) => CodecConfig blk -> BlockNodeToClientVersion blk -> forall s. Decoder s a

-- | How to serialise the result of the <tt>result</tt> of a query.
--   
--   The <tt>LocalStateQuery</tt> protocol is a node-to-client protocol,
--   hence the <a>NodeToClientVersion</a> argument.
class SerialiseResult blk query
encodeResult :: forall result. SerialiseResult blk query => CodecConfig blk -> BlockNodeToClientVersion blk -> query result -> result -> Encoding
decodeResult :: forall result. SerialiseResult blk query => CodecConfig blk -> BlockNodeToClientVersion blk -> query result -> forall s. Decoder s result

-- | Uses the <a>Serialise</a> instance, but wraps it in CBOR-in-CBOR.
--   
--   Use this for the <a>SerialiseNodeToNode</a> and/or
--   <a>SerialiseNodeToClient</a> instance of <tt>blk</tt> and/or
--   <tt><a>Header</a> blk</tt>, which require CBOR-in-CBOR to be
--   compatible with the corresponding <tt>Serialised</tt> instance.
defaultEncodeCBORinCBOR :: Serialise a => a -> Encoding

-- | Inverse of <a>defaultEncodeCBORinCBOR</a>
defaultDecodeCBORinCBOR :: Serialise a => Decoder s a
data Some (f :: k -> Type)
[Some] :: forall k (f :: k -> Type) (a :: k). f a -> Some f
instance Ouroboros.Consensus.Node.Serialisation.SerialiseNodeToClient blk blk => Ouroboros.Consensus.Node.Serialisation.SerialiseNodeToClient blk (Data.SOP.BasicFunctors.I blk)
instance Ouroboros.Consensus.Node.Serialisation.SerialiseNodeToClient blk (Ouroboros.Consensus.Ledger.SupportsMempool.ApplyTxErr blk) => Ouroboros.Consensus.Node.Serialisation.SerialiseNodeToClient blk (Ouroboros.Consensus.TypeFamilyWrappers.WrapApplyTxErr blk)
instance Ouroboros.Consensus.Node.Serialisation.SerialiseNodeToNode blk blk => Ouroboros.Consensus.Node.Serialisation.SerialiseNodeToNode blk (Data.SOP.BasicFunctors.I blk)
instance Ouroboros.Consensus.Node.Serialisation.SerialiseNodeToNode blk (Ouroboros.Consensus.Ledger.SupportsMempool.GenTxId blk) => Ouroboros.Consensus.Node.Serialisation.SerialiseNodeToNode blk (Ouroboros.Consensus.TypeFamilyWrappers.WrapGenTxId blk)

module Ouroboros.Consensus.Storage.LedgerDB.OnDisk

-- | Initialize the ledger DB from the most recent snapshot on disk
--   
--   If no such snapshot can be found, use the genesis ledger DB. Returns
--   the initialized DB as well as the block reference corresponding to the
--   snapshot we found on disk (the latter primarily for testing/monitoring
--   purposes).
--   
--   We do <i>not</i> catch any exceptions thrown during streaming; should
--   any be thrown, it is the responsibility of the <tt>ChainDB</tt> to
--   catch these and trigger (further) validation. We only discard
--   snapshots if
--   
--   <ul>
--   <li>We cannot deserialise them, or</li>
--   <li>they are <i>ahead</i> of the chain</li>
--   </ul>
--   
--   It is possible that the Ledger DB will not be able to roll back
--   <tt>k</tt> blocks after initialization if the chain has been truncated
--   (data corruption).
initLedgerDB :: forall m blk. (IOLike m, LedgerSupportsProtocol blk, InspectLedger blk, HasCallStack) => Tracer m (TraceReplayEvent blk ()) -> Tracer m (TraceEvent blk) -> SomeHasFS m -> (forall s. Decoder s (ExtLedgerState blk)) -> (forall s. Decoder s (RealPoint blk)) -> LedgerDbParams -> ExtLedgerCfg blk -> m (ExtLedgerState blk) -> StreamAPI m blk -> m (InitLog blk, LedgerDB' blk, Word64)

-- | Initialization log
--   
--   The initialization log records which snapshots from disk were
--   considered, in which order, and why some snapshots were rejected. It
--   is primarily useful for monitoring purposes.
data InitLog blk

-- | Defaulted to initialization from genesis
--   
--   NOTE: Unless the blockchain is near genesis, we should see this
--   <i>only</i> if data corrupted occurred.
InitFromGenesis :: InitLog blk

-- | Used a snapshot corresponding to the specified tip
InitFromSnapshot :: DiskSnapshot -> Point blk -> InitLog blk

-- | Initialization skipped a snapshot
--   
--   We record the reason why it was skipped.
--   
--   NOTE: We should <i>only</i> see this if data corrupted occurred.
InitFailure :: DiskSnapshot -> InitFailure blk -> InitLog blk -> InitLog blk
data InitFailure blk

-- | We failed to deserialise the snapshot
--   
--   This can happen due to data corruption in the ledger DB.
InitFailureRead :: ReadIncrementalErr -> InitFailure blk

-- | This snapshot is too recent (ahead of the tip of the chain)
InitFailureTooRecent :: Point blk -> InitFailure blk
type LedgerDB' blk = LedgerDB (ExtLedgerState blk) (RealPoint blk)
ledgerDbTip' :: LedgerDB' blk -> Point blk
type ChainSummary' blk = ChainSummary (ExtLedgerState blk) (RealPoint blk)
csTip' :: ChainSummary' blk -> Point blk
type AnnLedgerError' blk = AnnLedgerError (ExtLedgerState blk) (RealPoint blk)

-- | Next block returned during streaming
data NextBlock blk
NoMoreBlocks :: NextBlock blk
NextBlock :: blk -> NextBlock blk

-- | Stream blocks from the immutable DB
--   
--   When we initialize the ledger DB, we try to find a snapshot close to
--   the tip of the immutable DB, and then stream blocks from the immutable
--   DB to its tip to bring the ledger up to date with the tip of the
--   immutable DB.
--   
--   In CPS form to enable the use of <tt>withXYZ</tt> style iterator init
--   functions.
data StreamAPI m blk
StreamAPI :: (forall a. HasCallStack => Point blk -> (Maybe (m (NextBlock blk)) -> m a) -> m a) -> StreamAPI m blk

-- | Start streaming after the specified block
[streamAfter] :: StreamAPI m blk -> forall a. HasCallStack => Point blk -> (Maybe (m (NextBlock blk)) -> m a) -> m a

-- | Take a snapshot of the <i>oldest ledger state</i> in the ledger DB
--   
--   We write the <i>oldest</i> ledger state to disk because the intention
--   is to only write ledger states to disk that we know to be immutable.
--   Primarily for testing purposes, <a>takeSnapshot</a> returns the block
--   reference corresponding to the snapshot that we wrote.
--   
--   NOTE: This is a lower-level API that unconditionally takes a snapshot
--   (i.e., independent from whether this snapshot corresponds to a state
--   that is more than <tt>k</tt> back).
--   
--   TODO: Should we delete the file if an error occurs during writing?
takeSnapshot :: forall m blk. MonadThrow m => Tracer m (TraceEvent blk) -> SomeHasFS m -> (ExtLedgerState blk -> Encoding) -> (RealPoint blk -> Encoding) -> LedgerDB' blk -> m (DiskSnapshot, Point blk)

-- | Trim the number of on disk snapshots so that at most
--   <a>onDiskNumSnapshots</a> snapshots are stored on disk. The oldest
--   snapshots are deleted.
--   
--   The deleted snapshots are returned.
trimSnapshots :: Monad m => Tracer m (TraceEvent r) -> SomeHasFS m -> DiskPolicy -> m [DiskSnapshot]

-- | On disk snapshots are numbered monotonically
data DiskSnapshot

-- | Delete snapshot from disk
deleteSnapshot :: HasCallStack => SomeHasFS m -> DiskSnapshot -> m ()
snapshotToPath :: DiskSnapshot -> FsPath
data TraceEvent blk

-- | An on disk snapshot was skipped because it was invalid.
InvalidSnapshot :: DiskSnapshot -> InitFailure blk -> TraceEvent blk

-- | A snapshot was written to disk.
TookSnapshot :: DiskSnapshot -> Point blk -> TraceEvent blk

-- | An old or invalid on-disk snapshot was deleted
DeletedSnapshot :: DiskSnapshot -> TraceEvent blk

-- | Events traced while replaying blocks against the ledger to bring it up
--   to date w.r.t. the tip of the ImmutableDB during initialisation. As
--   this process takes a while, we trace events to inform higher layers of
--   our progress.
--   
--   The <tt>replayTo</tt> parameter is meant to be filled in by a higher
--   layer, i.e., the ChainDB.
data TraceReplayEvent blk replayTo

-- | There were no LedgerDB snapshots on disk, so we're replaying all
--   blocks starting from Genesis against the initial ledger.
--   
--   The <tt>replayTo</tt> parameter corresponds to the block at the tip of
--   the ImmutableDB, i.e., the last block to replay.
ReplayFromGenesis :: replayTo -> TraceReplayEvent blk replayTo

-- | There was a LedgerDB snapshot on disk corresponding to the given tip.
--   We're replaying more recent blocks against it.
--   
--   The <tt>replayTo</tt> parameter corresponds to the block at the tip of
--   the ImmutableDB, i.e., the last block to replay.
ReplayFromSnapshot :: DiskSnapshot -> Point blk -> replayTo -> TraceReplayEvent blk replayTo

-- | We replayed the given block (reference) on the genesis snapshot during
--   the initialisation of the LedgerDB.
--   
--   The <tt>blockInfo</tt> parameter corresponds replayed block and the
--   <tt>replayTo</tt> parameter corresponds to the block at the tip of the
--   ImmutableDB, i.e., the last block to replay.
ReplayedBlock :: RealPoint blk -> [LedgerEvent blk] -> replayTo -> TraceReplayEvent blk replayTo
instance GHC.Generics.Generic (Ouroboros.Consensus.Storage.LedgerDB.OnDisk.InitFailure blk)
instance Ouroboros.Network.Block.StandardHash blk => GHC.Classes.Eq (Ouroboros.Consensus.Storage.LedgerDB.OnDisk.InitFailure blk)
instance Ouroboros.Network.Block.StandardHash blk => GHC.Show.Show (Ouroboros.Consensus.Storage.LedgerDB.OnDisk.InitFailure blk)
instance GHC.Generics.Generic Ouroboros.Consensus.Storage.LedgerDB.OnDisk.DiskSnapshot
instance GHC.Classes.Ord Ouroboros.Consensus.Storage.LedgerDB.OnDisk.DiskSnapshot
instance GHC.Classes.Eq Ouroboros.Consensus.Storage.LedgerDB.OnDisk.DiskSnapshot
instance GHC.Show.Show Ouroboros.Consensus.Storage.LedgerDB.OnDisk.DiskSnapshot
instance GHC.Generics.Generic (Ouroboros.Consensus.Storage.LedgerDB.OnDisk.InitLog blk)
instance Ouroboros.Network.Block.StandardHash blk => GHC.Classes.Eq (Ouroboros.Consensus.Storage.LedgerDB.OnDisk.InitLog blk)
instance Ouroboros.Network.Block.StandardHash blk => GHC.Show.Show (Ouroboros.Consensus.Storage.LedgerDB.OnDisk.InitLog blk)
instance Ouroboros.Network.Block.StandardHash blk => GHC.Show.Show (Ouroboros.Consensus.Storage.LedgerDB.OnDisk.TraceEvent blk)
instance Ouroboros.Network.Block.StandardHash blk => GHC.Classes.Eq (Ouroboros.Consensus.Storage.LedgerDB.OnDisk.TraceEvent blk)
instance GHC.Generics.Generic (Ouroboros.Consensus.Storage.LedgerDB.OnDisk.TraceEvent blk)
instance Data.Traversable.Traversable (Ouroboros.Consensus.Storage.LedgerDB.OnDisk.TraceReplayEvent blk)
instance Data.Foldable.Foldable (Ouroboros.Consensus.Storage.LedgerDB.OnDisk.TraceReplayEvent blk)
instance GHC.Base.Functor (Ouroboros.Consensus.Storage.LedgerDB.OnDisk.TraceReplayEvent blk)
instance (Ouroboros.Network.Block.StandardHash blk, Ouroboros.Consensus.Ledger.Inspect.InspectLedger blk, GHC.Show.Show replayTo) => GHC.Show.Show (Ouroboros.Consensus.Storage.LedgerDB.OnDisk.TraceReplayEvent blk replayTo)
instance (Ouroboros.Network.Block.StandardHash blk, Ouroboros.Consensus.Ledger.Inspect.InspectLedger blk, GHC.Classes.Eq replayTo) => GHC.Classes.Eq (Ouroboros.Consensus.Storage.LedgerDB.OnDisk.TraceReplayEvent blk replayTo)
instance GHC.Generics.Generic (Ouroboros.Consensus.Storage.LedgerDB.OnDisk.TraceReplayEvent blk replayTo)

module Ouroboros.Consensus.Util.ResourceRegistry

-- | Resource registry
--   
--   Note on terminology: when thread A forks thread B, we will say that
--   thread A is the " parent " and thread B is the " child ". No further
--   relationship between the two threads is implied by this terminology.
--   In particular, note that the child may outlive the parent. We will use
--   "fork" and "spawn" interchangeably.
--   
--   <h1>Motivation</h1>
--   
--   Whenever we allocate resources, we must keep track of them so that we
--   can deallocate them when they are no longer required. The most
--   important tool we have to achieve this is <a>bracket</a>:
--   
--   <pre>
--   bracket allocateResource releaseResource $ \r -&gt;
--     .. use r ..
--   </pre>
--   
--   Often <a>bracket</a> comes in the guise of a with-style combinator
--   
--   <pre>
--   withResource $ \r -&gt;
--     .. use r ..
--   </pre>
--   
--   Where this pattern is applicable, it should be used and there is no
--   need to use the <a>ResourceRegistry</a>. However, <a>bracket</a>
--   introduces strict lexical scoping: the resource is available inside
--   the scope of the bracket, and will be deallocated once we leave that
--   scope. That pattern is sometimes hard to use.
--   
--   For example, suppose we have this interface to an SQL server
--   
--   <pre>
--   query :: Query -&gt; IO QueryHandle
--   close :: QueryHandle -&gt; IO ()
--   next  :: QueryHandle -&gt; IO Row
--   </pre>
--   
--   and suppose furthermore that we are writing a simple webserver that
--   allows a client to send multiple SQL queries, get rows from any open
--   query, and close queries when no longer required:
--   
--   <pre>
--   server :: IO ()
--   server = go Map.empty
--     where
--       go :: Map QueryId QueryHandle -&gt; IO ()
--       go handles = getRequest &gt;&gt;= \case
--           New q -&gt; do
--             h   &lt;- query q                        -- allocate
--             qId &lt;- generateQueryId
--             sendResponse qId
--             go $ Map.insert qId h handles
--           Close qId -&gt; do
--             close (handles ! qId)                 -- release
--             go $ Map.delete qId handles
--           Next qId -&gt; do
--             sendResponse =&lt;&lt; next (handles ! qId)
--             go handles
--   </pre>
--   
--   The server opens and closes query handles in response to client
--   requests. Restructuring this code to use <a>bracket</a> would be
--   awkward, but as it stands this code does not ensure that resources get
--   deallocated; for example, if the server thread is killed
--   (<a>killThread</a>), resources will be leaked.
--   
--   Another, perhaps simpler, example is spawning threads. Threads too
--   should be considered to be resources that we should keep track of and
--   deallocate when they are no longer required, primarily because when we
--   deallocate (terminate) those threads they too will have a chance to
--   deallocate <i>their</i> resources. As for other resources, we have a
--   with-style combinator for this
--   
--   <pre>
--   withAsync $ \thread -&gt; ..
--   </pre>
--   
--   Lexical scoping of threads is often inconvenient, however, more so
--   than for regular resources. The temptation is therefore to simply fork
--   a thread and forget about it, but if we are serious about resource
--   deallocation this is not an acceptable solution.
--   
--   <h1>The resource registry</h1>
--   
--   The resource registry is essentially a piece of state tracking which
--   resources have been allocated. The registry itself is allocated with a
--   with-style combinator <a>withRegistry</a>, and when we leave that
--   scope any resources not yet deallocated will be released at that
--   point. Typically the registry is only used as a fall-back, ensuring
--   that resources will deallocated even in the presence of exceptions.
--   For example, here's how we might rewrite the above server example
--   using a registry:
--   
--   <pre>
--   server' :: IO ()
--   server' =
--       withRegistry $ \registry -&gt; go registry Map.empty
--     where
--       go :: ResourceRegistry IO
--          -&gt; Map QueryId (ResourceKey, QueryHandle)
--          -&gt; IO ()
--       go registry handles = getRequest &gt;&gt;= \case
--           New q -&gt; do
--             (key, h) &lt;- allocate registry (query q) close  -- allocate
--             qId      &lt;- generateQueryId
--             sendResponse qId
--             go registry $ Map.insert qId (key, h) handles
--           Close qId -&gt; do
--             release registry (fst (handles ! qId))         -- release
--             go registry $ Map.delete qId handles
--           Next qId -&gt; do
--             sendResponse =&lt;&lt; next (snd (handles ! qId))
--             go registry handles
--   </pre>
--   
--   We allocate the query with the help of the registry, providing the
--   registry with the means to deallocate the query should that be
--   required. We can /and should/ still manually release resources also:
--   in this particular example, the (lexical) scope of the registry is the
--   entire server thread, so delaying releasing queries until we exit that
--   scope will probably mean we hold on to resources for too long. The
--   registry is only there as a fall-back.
--   
--   <h1>Spawning threads</h1>
--   
--   We already observed in the introduction that insisting on lexical
--   scoping for threads is often inconvenient, and that simply using
--   <tt>fork</tt> is no solution as it means we might leak resources.
--   There is however another problem with <tt>fork</tt>. Consider this
--   snippet:
--   
--   <pre>
--   withRegistry $ \registry -&gt;
--     r &lt;- allocate registry allocateResource releaseResource
--     fork $ .. use r ..
--   </pre>
--   
--   It is easy to see that this code is problematic: we allocate a
--   resource <tt>r</tt>, then spawn a thread that uses <tt>r</tt>, and
--   finally leave the scope of <a>withRegistry</a>, thereby deallocating
--   <tt>r</tt> -- leaving the thread to run with a now deallocated
--   resource.
--   
--   It is <i>only</i> safe for threads to use a given registry, and/or its
--   registered resources, if the lifetime of those threads is tied to the
--   lifetime of the registry. There would be no problem with the example
--   above if the thread would be terminated when we exit the scope of
--   <a>withRegistry</a>.
--   
--   The <a>forkThread</a> combinator provided by the registry therefore
--   does two things: it allocates the thread as a resource in the
--   registry, so that it can kill the thread when releasing all resources
--   in the registry. It also records the thread ID in a set of known
--   threads. Whenever the registry is accessed from a thread <i>not</i> in
--   this set, the registry throws a runtime exception, since such a thread
--   might outlive the registry and hence its contents. The intention is
--   that this guards against dangerous patterns like the one above.
--   
--   <h1>Linking</h1>
--   
--   When thread A spawns thread B using <a>withAsync</a>, the lifetime of
--   B is tied to the lifetime of A:
--   
--   <pre>
--   withAsync .. $ \threadB -&gt; ..
--   </pre>
--   
--   After all, when A exits the scope of the <a>withAsync</a>, thread B
--   will be killed. The reverse is however not true: thread B can
--   terminate before thread A. It is often useful for thread A to be able
--   to declare a dependency on thread B: if B somehow fails, that is,
--   terminates with an exception, we want that exception to be rethrown in
--   thread A as well. A can achieve this by <i>linking</i> to B:
--   
--   <pre>
--   withAsync .. $ \threadB -&gt; do
--     link threadB
--     ..
--   </pre>
--   
--   Linking a parent to a child is however of limited value if the
--   lifetime of the child is not limited by the lifetime of the parent.
--   For example, if A does
--   
--   <pre>
--   threadB &lt;- async $ ..
--   link threadB
--   </pre>
--   
--   and A terminates before B does, any exception thrown by B might be
--   send to a thread that no longer exists. This is particularly
--   problematic when we start chaining threads: if A spawns-and-links-to B
--   which spawns-and-links-to C, and C throws an exception, perhaps the
--   intention is that this gets rethrown to B, and then rethrown to A,
--   terminating all three threads; however, if B has terminated before the
--   exception is thrown, C will throw the exception to a non-existent
--   thread and A is never notified.
--   
--   For this reason, the registry's <a>linkToRegistry</a> combinator does
--   not link the specified to the thread calling <a>linkToRegistry</a>,
--   but rather to the thread that created the registry. After all, the
--   lifetime of threads spawned with <a>forkThread</a> can certainly
--   exceed the lifetime of their parent threads, but the lifetime of
--   <i>all</i> threads spawned using the registry will be limited by the
--   scope of that registry, and hence the lifetime of the thread that
--   created it. So, when we call <a>linkToRegistry</a>, the exception will
--   be thrown the thread that created the registry, which (if not caught)
--   will cause that that to exit the scope of <a>withRegistry</a>, thereby
--   terminating all threads in that registry.
--   
--   # Combining the registry and with-style allocation
--   
--   It is perfectly possible (indeed, advisable) to use <a>bracket</a> and
--   bracket-like allocation functions alongside the registry, but note
--   that the usual caveats with <a>bracket</a> and forking threads still
--   applies. In particular, spawning threads inside the <a>bracket</a>
--   that make use of the bracketed resource is problematic; this is of
--   course true whether or not a registry is used.
--   
--   In principle this also includes <a>withAsync</a>; however, since
--   <a>withAsync</a> results in a thread that is not known to the
--   registry, such a thread will not be able to use the registry (the
--   registry would throw an unknown thread exception, as described above).
--   For this purpose we provide <a>withThread</a>; <a>withThread</a> (as
--   opposed to <a>forkThread</a>) should be used when a parent thread
--   wants to handle exceptions in the child thread; see <a>withThread</a>
--   for detailed discussion.
--   
--   It is <i>also</i> fine to includes nested calls to
--   <a>withRegistry</a>. Since the lifetime of such a registry (and all
--   resources within) is tied to the thread calling <a>withRegistry</a>,
--   which itself is tied to the "parent registry" in which it was created,
--   this creates a hierarchy of registries. It is of course essential for
--   compositionality that we should be able to create local registries,
--   but even if we do have easy access to a parent regisry, creating a
--   local one where possibly is useful as it limits the scope of the
--   resources created within, and hence their maximum lifetimes.
data ResourceRegistry m

-- | Attempt to allocate a resource in a registry which is closed
--   
--   When calling <a>closeRegistry</a> (typically, leaving the scope of
--   <a>withRegistry</a>), all resources in the registry must be released.
--   If a concurrent thread is still allocating resources, we end up with a
--   race between the thread trying to allocate new resources and the
--   registry trying to free them all. To avoid this, before releasing
--   anything, the registry will record itself as closed. Any attempt by a
--   concurrent thread to allocate a new resource will then result in a
--   <a>RegistryClosedException</a>.
--   
--   It is probably not particularly useful for threads to try and catch
--   this exception (apart from in a generic handler that does local
--   resource cleanup). The thread will anyway soon receive a
--   <tt>ThreadKilled</tt> exception.
data RegistryClosedException
RegistryClosedException :: !Context m -> !PrettyCallStack -> !Context m -> RegistryClosedException

-- | The context in which the registry was created
[registryClosedRegistryContext] :: RegistryClosedException -> !Context m

-- | Callstack to the call to <a>close</a>
--   
--   Note that <a>close</a> can only be called from the same thread that
--   created the registry.
[registryClosedCloseCallStack] :: RegistryClosedException -> !PrettyCallStack

-- | Context of the call resulting in the exception
[registryClosedAllocContext] :: RegistryClosedException -> !Context m

-- | Registry used from untracked threads
--   
--   If this exception is raised, it indicates a bug in the caller.
data ResourceRegistryThreadException

-- | Create a new registry
--   
--   See documentation of <a>ResourceRegistry</a> for a detailed
--   discussion.
withRegistry :: (IOLike m, HasCallStack) => (ResourceRegistry m -> m a) -> m a

-- | The thread that created the registry
registryThread :: ResourceRegistry m -> ThreadId m

-- | Resource key
--   
--   Resource keys are tied to a particular registry.
data ResourceKey m

-- | Allocate new resource
--   
--   The allocation function will be run with asynchronous exceptions
--   masked. This means that the resource allocation must either be fast or
--   else interruptible; see "Dealing with Asynchronous Exceptions during
--   Resource Acquisition" <a>http://www.well-typed.com/blog/97/</a> for
--   details.
allocate :: forall m a. (IOLike m, HasCallStack) => ResourceRegistry m -> (ResourceId -> m a) -> (a -> m ()) -> m (ResourceKey m, a)

-- | Generalization of <a>allocate</a> for allocation functions that may
--   fail
allocateEither :: forall m e a. (IOLike m, HasCallStack) => ResourceRegistry m -> (ResourceId -> m (Either e a)) -> (a -> m Bool) -> m (Either e (ResourceKey m, a))

-- | Release resource
--   
--   This deallocates the resource and removes it from the registry. It
--   will be the responsibility of the caller to make sure that the
--   resource is no longer used in any thread.
--   
--   The deallocation function is run with exceptions masked, so that we
--   are guaranteed not to remove the resource from the registry without
--   releasing it.
--   
--   Releasing an already released resource is a no-op.
--   
--   When the resource has not been released before, its context is
--   returned.
release :: (IOLike m, HasCallStack) => ResourceKey m -> m (Maybe (Context m))

-- | Unsafe version of <a>release</a>
--   
--   The only difference between <a>release</a> and <a>unsafeRelease</a> is
--   that the latter does not insist that it is called from a thread that
--   is known to the registry. This is dangerous, because it implies that
--   there is a thread with access to a resource which may be deallocated
--   before that thread is terminated. Of course, we can't detect all such
--   situations (when the thread merely uses a resource but does not
--   allocate or release we can't tell), but normally when we <i>do</i>
--   detect this we throw an exception.
--   
--   This function should only be used if the above situation can be ruled
--   out or handled by other means.
unsafeRelease :: IOLike m => ResourceKey m -> m (Maybe (Context m))

-- | Release all resources in the <a>ResourceRegistry</a> without closing.
--   
--   See <a>closeRegistry</a> for more details.
releaseAll :: (IOLike m, HasCallStack) => ResourceRegistry m -> m ()

-- | This is to <a>releaseAll</a> what <a>unsafeRelease</a> is to
--   <a>release</a>: we do not insist that this funciton is called from a
--   thread that is known to the registry. See <a>unsafeRelease</a> for why
--   this is dangerous.
unsafeReleaseAll :: (IOLike m, HasCallStack) => ResourceRegistry m -> m ()

-- | Thread
--   
--   The internals of this type are not exported.
data Thread m a
threadId :: Thread m a -> ThreadId m

-- | Fork a new thread
forkThread :: forall m a. (IOLike m, HasCallStack) => ResourceRegistry m -> String -> m a -> m (Thread m a)

-- | Cancel a thread
--   
--   This is a synchronous operation: the thread will have terminated when
--   this function returns.
--   
--   Uses <a>uninterruptibleCancel</a> because that's what <a>withAsync</a>
--   does.
cancelThread :: IOLike m => Thread m a -> m ()

-- | Bracketed version of <a>forkThread</a>
--   
--   The analogue of <a>withAsync</a> for the registry.
--   
--   Scoping thread lifetime using <a>withThread</a> is important when a
--   parent thread wants to link to a child thread /and handle any
--   exceptions arising from the link/:
--   
--   <pre>
--   let handleLinkException :: ExceptionInLinkedThread -&gt; m ()
--       handleLinkException = ..
--   in handle handleLinkException $
--        withThread registry codeInChild $ \child -&gt;
--          ..
--   </pre>
--   
--   instead of
--   
--   <pre>
--   handle handleLinkException $ do  -- PROBABLY NOT CORRECT!
--     child &lt;- forkThread registry codeInChild
--     ..
--   </pre>
--   
--   where the parent may exit the scope of the exception handler before
--   the child terminates. If the lifetime of the child cannot be limited
--   to the lifetime of the parent, the child should probably be linked to
--   the registry instead and the thread that spawned the registry should
--   handle any exceptions.
--   
--   Note that in <i>principle</i> there is no problem in using
--   <tt>withAync</tt> alongside a registry. After all, in a pattern like
--   
--   <pre>
--   withRegistry $ \registry -&gt;
--     ..
--     withAsync (.. registry ..) $ \async -&gt;
--       ..
--   </pre>
--   
--   the async will be cancelled when leaving the scope of <a>withAsync</a>
--   and so that reference to the registry, or indeed any of the resources
--   inside the registry, is safe. However, the registry implements a
--   sanity check that the registry is only used from known threads. This
--   is useful: when a thread that is not known to the registry (in other
--   words, whose lifetime is not tied to the lifetime of the registry)
--   spawns a resource in that registry, that resource may well be
--   deallocated before the thread terminates, leading to undefined and
--   hard to debug behaviour (indeed, whether or not this results in
--   problems may well depend on precise timing); an exception that is
--   thrown when <i>allocating</i> the resource is (more) deterministic and
--   easier to debug. Unfortunately, it means that the above pattern is not
--   applicable, as the thread spawned by <a>withAsync</a> is not known to
--   the registry, and so if it were to try to use the registry, the
--   registry would throw an error (even though this pattern is actually
--   safe). This situation is not ideal, but for now we merely provide an
--   alternative to <a>withAsync</a> that <i>does</i> register the thread
--   with the registry.
--   
--   NOTE: Threads that are spawned out of the user's control but that must
--   still make use of the registry can use the unsafe API. This should be
--   used with caution, however.
withThread :: IOLike m => ResourceRegistry m -> String -> m a -> (Thread m a -> m b) -> m b

-- | Wait for thread to terminate and return its result.
--   
--   If the thread throws an exception, this will rethrow that exception.
--   
--   NOTE: If A waits on B, and B is linked to the registry, and B throws
--   an exception, then A might <i>either</i> receive the exception thrown
--   by B <i>or</i> the <tt>ThreadKilled</tt> exception thrown by the
--   registry.
waitThread :: IOLike m => Thread m a -> m a

-- | Lift <a>waitAny</a> to <a>Thread</a>
waitAnyThread :: forall m a. IOLike m => [Thread m a] -> m a

-- | Link specified <a>Thread</a> to the (thread that created) the registry
linkToRegistry :: IOLike m => Thread m a -> m ()

-- | Fork a thread and link to it to the registry.
--   
--   This function is just a convenience.
forkLinkedThread :: (IOLike m, HasCallStack) => ResourceRegistry m -> String -> m a -> m (Thread m a)

-- | An action with a temporary registry in scope, see
--   <a>runWithTempRegistry</a> for more details.
--   
--   The most important function to run in this monad is
--   <a>allocateTemp</a>.
data WithTempRegistry st m a

-- | Run an action with a temporary resource registry.
--   
--   When allocating resources that are meant to end up in some final
--   state, e.g., stored in a <tt>TVar</tt>, after which they are
--   guaranteed to be released correctly, it is possible that an exception
--   is thrown after allocating such a resource, but before it was stored
--   in the final state. In that case, the resource would be leaked.
--   <a>runWithTempRegistry</a> solves that problem.
--   
--   When no exception is thrown before the end of
--   <a>runWithTempRegistry</a>, the user must have transferred all the
--   resources it allocated to their final state. This means that these
--   resources don't have to be released by the temporary registry anymore,
--   the final state is now in charge of releasing them.
--   
--   In case an exception is thrown before the end of
--   <a>runWithTempRegistry</a>, <i>all</i> resources allocated in the
--   temporary registry will be released.
--   
--   Resources must be allocated using <a>allocateTemp</a>.
--   
--   To make sure that the user doesn't forget to transfer a resource to
--   the final state <tt>st</tt>, the user must pass a function to
--   <a>allocateTemp</a> that checks whether a given <tt>st</tt> contains
--   the resource, i.e., whether the resource was successfully transferred
--   to its final destination.
--   
--   When no exception is thrown before the end of
--   <a>runWithTempRegistry</a>, we check whether all allocated resources
--   have been transferred to the final state <tt>st</tt>. If there's a
--   resource that hasn't been transferred to the final state <i>and</i>
--   that hasn't be released or closed before (see the release function
--   passed to <a>allocateTemp</a>), a <a>TempRegistryRemainingResource</a>
--   exception will be thrown.
--   
--   For that reason, <a>WithTempRegistry</a> is parameterised over the
--   final state type <tt>st</tt> and the given <a>WithTempRegistry</a>
--   action must return the final state.
--   
--   NOTE: we explicitly don't let <a>runWithTempRegistry</a> return the
--   final state, because the state <i>must</i> have been stored somewhere
--   safely, transferring the resources, before the temporary registry is
--   closed.
runWithTempRegistry :: (IOLike m, HasCallStack) => WithTempRegistry st m (a, st) -> m a

-- | When <a>runWithTempRegistry</a> exits successfully while there are
--   still resources remaining in the temporary registry that haven't been
--   transferred to the final state.
data TempRegistryException
TempRegistryRemainingResource :: !Context m -> !Context m -> TempRegistryException

-- | The context in which the temporary registry was created.
[tempRegistryContext] :: TempRegistryException -> !Context m

-- | The context in which the resource was allocated that was not
--   transferred to the final state.
[tempRegistryResource] :: TempRegistryException -> !Context m

-- | Allocate a resource in a temporary registry until it has been
--   transferred to the final state <tt>st</tt>. See
--   <a>runWithTempRegistry</a> for more details.
allocateTemp :: (IOLike m, HasCallStack) => m a -> (a -> m Bool) -> (st -> a -> Bool) -> WithTempRegistry st m a

-- | Higher level API on top of <a>runWithTempRegistry</a>: modify the
--   given <tt>st</tt>, allocating resources in the process that will be
--   transferred to the returned <tt>st</tt>.
modifyWithTempRegistry :: forall m st a. IOLike m => m st -> (st -> ExitCase st -> m ()) -> StateT st (WithTempRegistry st m) a -> m a

-- | Create a new registry
--   
--   You are strongly encouraged to use <a>withRegistry</a> instead.
--   Exported primarily for the benefit of tests.
unsafeNewRegistry :: (IOLike m, HasCallStack) => m (ResourceRegistry m)

-- | Close the registry
--   
--   This can only be called from the same thread that created the
--   registry. This is a no-op if the registry is already closed.
--   
--   This entire function runs with exceptions masked, so that we are not
--   interrupted while we release all resources.
--   
--   Resources will be allocated from young to old, so that resources
--   allocated later can safely refer to resources created earlier.
--   
--   The release functions are run in the scope of an exception handler, so
--   that if releasing one resource throws an exception, we still attempt
--   to release the other resources. Should we catch an exception whilst we
--   close the registry, we will rethrow it after having attempted to
--   release all resources. If there is more than one, we will pick a
--   random one to rethrow, though we will prioritize asynchronous
--   exceptions over other exceptions. This may be important for exception
--   handlers that catch all-except-asynchronous exceptions.
closeRegistry :: (IOLike m, HasCallStack) => ResourceRegistry m -> m ()

-- | Number of currently allocated resources
--   
--   Primarily for the benefit of testing.
countResources :: IOLike m => ResourceRegistry m -> m Int
instance NoThunks.Class.NoThunks (Ouroboros.Consensus.Util.ResourceRegistry.KnownThreads m)
instance NoThunks.Class.NoThunks Ouroboros.Consensus.Util.ResourceRegistry.RegistryStatus
instance GHC.Generics.Generic Ouroboros.Consensus.Util.ResourceRegistry.RegistryStatus
instance NoThunks.Class.NoThunks Ouroboros.Consensus.Util.ResourceRegistry.ResourceId
instance GHC.Enum.Enum Ouroboros.Consensus.Util.ResourceRegistry.ResourceId
instance GHC.Classes.Ord Ouroboros.Consensus.Util.ResourceRegistry.ResourceId
instance GHC.Classes.Eq Ouroboros.Consensus.Util.ResourceRegistry.ResourceId
instance GHC.Show.Show Ouroboros.Consensus.Util.ResourceRegistry.ResourceId
instance NoThunks.Class.NoThunks (Ouroboros.Consensus.Util.ResourceRegistry.Release m)
instance NoThunks.Class.NoThunks (Ouroboros.Consensus.Util.ResourceRegistry.TransferredTo st)
instance GHC.Base.Monoid (Ouroboros.Consensus.Util.ResourceRegistry.TransferredTo st)
instance GHC.Base.Semigroup (Ouroboros.Consensus.Util.ResourceRegistry.TransferredTo st)
instance NoThunks.Class.NoThunks (Ouroboros.Consensus.Util.ResourceRegistry.Resource m)
instance GHC.Generics.Generic (Ouroboros.Consensus.Util.ResourceRegistry.Resource m)
instance NoThunks.Class.NoThunks (Ouroboros.Consensus.Util.ResourceRegistry.RegistryState m)
instance GHC.Generics.Generic (Ouroboros.Consensus.Util.ResourceRegistry.RegistryState m)
instance GHC.Generics.Generic (Ouroboros.Consensus.Util.ResourceRegistry.ResourceRegistry m)
instance NoThunks.Class.NoThunks (Ouroboros.Consensus.Util.ResourceRegistry.Thread m a)
instance Control.Monad.Class.MonadSTM.MonadSTM m => Control.Monad.Class.MonadSTM.MonadSTM (Ouroboros.Consensus.Util.ResourceRegistry.WithTempRegistry st m)
instance Control.Monad.Class.MonadThrow.MonadMask m => Control.Monad.Class.MonadThrow.MonadMask (Ouroboros.Consensus.Util.ResourceRegistry.WithTempRegistry st m)
instance Control.Monad.Class.MonadThrow.MonadCatch m => Control.Monad.Class.MonadThrow.MonadCatch (Ouroboros.Consensus.Util.ResourceRegistry.WithTempRegistry st m)
instance Control.Monad.Class.MonadThrow.MonadThrow m => Control.Monad.Class.MonadThrow.MonadThrow (Ouroboros.Consensus.Util.ResourceRegistry.WithTempRegistry st m)
instance GHC.Base.Monad m => GHC.Base.Monad (Ouroboros.Consensus.Util.ResourceRegistry.WithTempRegistry st m)
instance GHC.Base.Applicative m => GHC.Base.Applicative (Ouroboros.Consensus.Util.ResourceRegistry.WithTempRegistry st m)
instance GHC.Base.Functor m => GHC.Base.Functor (Ouroboros.Consensus.Util.ResourceRegistry.WithTempRegistry st m)
instance Ouroboros.Consensus.Util.IOLike.IOLike m => NoThunks.Class.NoThunks (Ouroboros.Consensus.Util.ResourceRegistry.ResourceKey m)
instance GHC.Generics.Generic (Ouroboros.Consensus.Util.ResourceRegistry.ResourceKey m)
instance Ouroboros.Consensus.Util.IOLike.IOLike m => NoThunks.Class.NoThunks (Ouroboros.Consensus.Util.ResourceRegistry.ResourceRegistry m)
instance GHC.Show.Show Ouroboros.Consensus.Util.ResourceRegistry.RegistryClosedException
instance GHC.Show.Show Ouroboros.Consensus.Util.ResourceRegistry.TempRegistryException
instance GHC.Show.Show Ouroboros.Consensus.Util.ResourceRegistry.ResourceRegistryThreadException
instance GHC.Show.Show (Ouroboros.Consensus.Util.ResourceRegistry.Context m)
instance Control.Monad.Trans.Class.MonadTrans (Ouroboros.Consensus.Util.ResourceRegistry.WithTempRegistry st)
instance Control.Monad.State.Class.MonadState s m => Control.Monad.State.Class.MonadState s (Ouroboros.Consensus.Util.ResourceRegistry.WithTempRegistry st m)
instance GHC.Classes.Eq (Ouroboros.Consensus.Util.ResourceRegistry.Thread m a)
instance GHC.Exception.Type.Exception Ouroboros.Consensus.Util.ResourceRegistry.RegistryClosedException
instance GHC.Exception.Type.Exception Ouroboros.Consensus.Util.ResourceRegistry.TempRegistryException
instance GHC.Exception.Type.Exception Ouroboros.Consensus.Util.ResourceRegistry.ResourceRegistryThreadException
instance NoThunks.Class.NoThunks (Ouroboros.Consensus.Util.ResourceRegistry.Context m)
instance GHC.Show.Show (Ouroboros.Consensus.Util.ResourceRegistry.Release m)

module Ouroboros.Consensus.Storage.VolatileDB.Impl.State
data TraceEvent blk
DBAlreadyClosed :: TraceEvent blk
DBAlreadyOpen :: TraceEvent blk
BlockAlreadyHere :: HeaderHash blk -> TraceEvent blk
TruncateCurrentFile :: FsPath -> TraceEvent blk
Truncate :: ParseError blk -> FsPath -> BlockOffset -> TraceEvent blk
InvalidFileNames :: [FsPath] -> TraceEvent blk

-- | The <a>FileId</a> is the unique identifier of each file found in the
--   db. For example, the file <tt>blocks-42.dat</tt> has <a>FileId</a>
--   <tt>42</tt>.
type FileId = Int

-- | We map the header hash of each block to the <a>InternalBlockInfo</a>.
type ReverseIndex blk = Map (HeaderHash blk) (InternalBlockInfo blk)

-- | For each block, we store the set of all blocks which have this block
--   as a predecessor (set of successors).
type SuccessorsIndex blk = Map (ChainHash blk) (Set (HeaderHash blk))
newtype BlockSize
BlockSize :: Word32 -> BlockSize
[unBlockSize] :: BlockSize -> Word32

-- | The offset at which a block is stored in a file.
newtype BlockOffset
BlockOffset :: Word64 -> BlockOffset
[unBlockOffset] :: BlockOffset -> Word64
data VolatileDBEnv m blk
VolatileDBEnv :: !HasFS m h -> !RAWLock m (InternalState blk h) -> !BlocksPerFile -> !blk -> Bool -> !CodecConfig blk -> !Tracer m (TraceEvent blk) -> VolatileDBEnv m blk
[hasFS] :: VolatileDBEnv m blk -> !HasFS m h
[varInternalState] :: VolatileDBEnv m blk -> !RAWLock m (InternalState blk h)
[maxBlocksPerFile] :: VolatileDBEnv m blk -> !BlocksPerFile
[checkIntegrity] :: VolatileDBEnv m blk -> !blk -> Bool
[codecConfig] :: VolatileDBEnv m blk -> !CodecConfig blk
[tracer] :: VolatileDBEnv m blk -> !Tracer m (TraceEvent blk)
data InternalState blk h
DbClosed :: InternalState blk h
DbOpen :: !OpenState blk h -> InternalState blk h
dbIsOpen :: InternalState blk h -> Bool

-- | Internal state when the database is open.
data OpenState blk h
OpenState :: !Handle h -> !FsPath -> !FileId -> !Word64 -> !Index blk -> !ReverseIndex blk -> !SuccessorsIndex blk -> !MaxSlotNo -> OpenState blk h

-- | The only open file we append blocks to.
[currentWriteHandle] :: OpenState blk h -> !Handle h

-- | The path of the file above.
[currentWritePath] :: OpenState blk h -> !FsPath

-- | The <a>FileId</a> of the same file.
[currentWriteId] :: OpenState blk h -> !FileId

-- | The offset of the same file.
[currentWriteOffset] :: OpenState blk h -> !Word64

-- | The contents of each file.
[currentMap] :: OpenState blk h -> !Index blk

-- | Where to find each block based on its slot number.
[currentRevMap] :: OpenState blk h -> !ReverseIndex blk

-- | The successors for each block.
[currentSuccMap] :: OpenState blk h -> !SuccessorsIndex blk

-- | Highest stored SlotNo.
--   
--   INVARIANT: this is the cached value of: &gt; FileInfo.maxSlotNoInFiles
--   (Index.elems (currentMap st))
[currentMaxSlotNo] :: OpenState blk h -> !MaxSlotNo

-- | Shorthand
type ModifyOpenState m blk h = StateT (OpenState blk h) (WithTempRegistry (OpenState blk h) m)

-- | Append to the open state. Reads can happen concurrently with this
--   operation.
--   
--   NOTE: This is safe in terms of throwing FsErrors.
appendOpenState :: forall blk m a. IOLike m => VolatileDBEnv m blk -> (forall h. Eq h => HasFS m h -> ModifyOpenState m blk h a) -> m a

-- | Write to the open state. No reads or appends can concurrently with
--   this operation.
--   
--   NOTE: This is safe in terms of throwing FsErrors.
writeOpenState :: forall blk m a. IOLike m => VolatileDBEnv m blk -> (forall h. Eq h => HasFS m h -> ModifyOpenState m blk h a) -> m a

-- | Perform an action that accesses the internal state of an open
--   database.
--   
--   In case the database is closed, a <a>ClosedDBError</a> is thrown.
--   
--   In case an <a>UnexpectedFailure</a> is thrown while the action is
--   being run, the database is closed to prevent further appending to a
--   database in a potentially inconsistent state. All other exceptions
--   will leave the database open.
withOpenState :: forall blk m r. IOLike m => VolatileDBEnv m blk -> (forall h. HasFS m h -> OpenState blk h -> m r) -> m r
mkOpenState :: forall m blk h. (HasCallStack, IOLike m, GetPrevHash blk, HasBinaryBlockInfo blk, HasNestedContent Header blk, DecodeDisk blk (ByteString -> blk), Eq h) => CodecConfig blk -> HasFS m h -> (blk -> Bool) -> BlockValidationPolicy -> Tracer m (TraceEvent blk) -> BlocksPerFile -> WithTempRegistry (OpenState blk h) m (OpenState blk h)

-- | Close the handles in the <a>OpenState</a>.
--   
--   Idempotent, as closing a handle is idempotent.
--   
--   NOTE: does not wrap <a>FsError</a>s and must be called within
--   <a>wrapFsError</a> or <a>tryVolatileDB</a>.
closeOpenHandles :: HasFS m h -> OpenState blk h -> m ()
instance (Ouroboros.Network.Block.StandardHash blk, Data.Typeable.Internal.Typeable blk) => NoThunks.Class.NoThunks (Ouroboros.Consensus.Storage.VolatileDB.Impl.State.OpenState blk h)
instance GHC.Generics.Generic (Ouroboros.Consensus.Storage.VolatileDB.Impl.State.OpenState blk h)
instance (Ouroboros.Network.Block.StandardHash blk, Data.Typeable.Internal.Typeable blk) => NoThunks.Class.NoThunks (Ouroboros.Consensus.Storage.VolatileDB.Impl.State.InternalState blk h)
instance GHC.Generics.Generic (Ouroboros.Consensus.Storage.VolatileDB.Impl.State.InternalState blk h)


-- | Volatile on-disk database of blocks
--   
--   <h1>Logic</h1>
--   
--   The VolatileDB is a key-value store of blocks indexed by their hashes.
--   It is parameterised by the block type <tt>blk</tt>.
--   
--   The "volatile" in the name refers to the fact that the blocks stored
--   in it make up the <i>volatile</i> part of the chain, i.e., the last
--   <tt>k</tt> blocks of the chain, which can still be rolled back. Not
--   only the last <tt>k</tt> blocks of the current chain are stored in
--   this database, but also blocks of forks which we have switched from or
--   will switch to.
--   
--   The VolatileDB appends new blocks sequentially to a file. When
--   <a>volMaxBlocksPerFile</a> are stored in the current file, a new file
--   is started.
--   
--   The VolatileDB provides four main operations:
--   
--   <ol>
--   <li>Adding blocks with <a>putBlock</a></li>
--   <li>Get blocks or information about them with
--   <a>getBlockComponent</a></li>
--   <li>Accessing the in-memory indices using <a>getBlockInfo</a> and
--   <a>filterByPredecessor</a></li>
--   <li>Garbage collecting blocks older than a given slot using
--   <a>garbageCollect</a></li>
--   </ol>
--   
--   Garbage collection will only delete a file from the VolatileDB when
--   all blocks in it have a slot older than the one passed to
--   <a>garbageCollect</a>.
--   
--   <h1>Errors</h1>
--   
--   When an exception occurs while modifying the VolatileDB, we close the
--   database as a safety measure, e.g., in case a file could not be
--   written to disk, as we can no longer make sure the in-memory indices
--   match what's stored on the file system. When reopening, we validate
--   the blocks stored in the file system and reconstruct the in-memory
--   indices.
--   
--   NOTE: this means that when a thread modifying the VolatileDB is
--   killed, the database will be closed. This is an intentional choice to
--   simplify things.
--   
--   The in-memory indices can always be reconstructed from the file
--   system. This is important, as we must be resilient against unexpected
--   shutdowns, power losses, etc.
--   
--   We achieve this by only performing basic operations on the VolatileDB:
--   * <a>putBlock</a> only appends a new block to a file. Losing an update
--   means we only lose a block, which is not a problem, it can be
--   redownloaded. * <a>garbageCollect</a> only deletes entire files. *
--   There is no operation that modifies a file in-place. This means we do
--   not have to keep any rollback journals to make sure we are safe in
--   case of unexpected shutdowns.
--   
--   We only throw <a>VolatileDBError</a>. File-system errors are caught,
--   wrapped in a <a>VolatileDBError</a>, and rethrown. We make sure that
--   all calls to <a>HasFS</a> functions are properly wrapped. This
--   wrapping is automatically done when inside the scope of
--   <tt>modifyOpenState</tt> and <a>withOpenState</a>. Otherwise, we use
--   <a>wrapFsError</a>.
--   
--   <h1>Concurrency</h1>
--   
--   A single folder should only be used by a single VolatileDB. Naturally,
--   a VolatileDB can be accessed concurrently by multiple threads.
--   
--   <h1>File-system layout:</h1>
--   
--   The on-disk representation is as follows:
--   
--   <pre>
--   dbFolder/
--     blocks-0.dat
--     blocks-1.dat
--     ...
--   </pre>
--   
--   Files not fitting the naming scheme are ignored. The numbering of
--   these files does not correlate to the blocks stored in them.
--   
--   Each file stores a fixed number of blocks, specified by
--   <a>volMaxBlocksPerFile</a>. When opening the VolatileDB, it will start
--   appending to the file with the highest number that is not yet full. If
--   all are full or none exist, a new file will be created.
--   
--   There is an implicit ordering of block files, which is NOT
--   alpharithmetic. For example, <tt>blocks-20.dat</tt> &lt;
--   <tt>blocks-100.dat</tt>.
--   
--   <h1>Recovery</h1>
--   
--   The VolatileDB will always try to recover to a consistent state even
--   if this means deleting all of its contents. In order to achieve this,
--   it truncates the files containing blocks if some blocks fail to parse,
--   are invalid, or are duplicated.
module Ouroboros.Consensus.Storage.VolatileDB.Impl
openDB :: forall m blk. (HasCallStack, IOLike m, HasHeader blk, GetPrevHash blk, VolatileDbSerialiseConstraints blk) => VolatileDbArgs Identity m blk -> m (VolatileDB m blk)
data VolatileDbArgs f m blk
VolatileDbArgs :: HKD f (blk -> Bool) -> HKD f (CodecConfig blk) -> SomeHasFS m -> BlocksPerFile -> Tracer m (TraceEvent blk) -> BlockValidationPolicy -> VolatileDbArgs f m blk
[volCheckIntegrity] :: VolatileDbArgs f m blk -> HKD f (blk -> Bool)
[volCodecConfig] :: VolatileDbArgs f m blk -> HKD f (CodecConfig blk)
[volHasFS] :: VolatileDbArgs f m blk -> SomeHasFS m
[volMaxBlocksPerFile] :: VolatileDbArgs f m blk -> BlocksPerFile
[volTracer] :: VolatileDbArgs f m blk -> Tracer m (TraceEvent blk)
[volValidationPolicy] :: VolatileDbArgs f m blk -> BlockValidationPolicy

-- | Default arguments when using the <a>IO</a> monad
defaultArgs :: FilePath -> VolatileDbArgs Defaults IO blk

-- | <a>EncodeDisk</a> and <a>DecodeDisk</a> constraints needed for the
--   VolatileDB.
type VolatileDbSerialiseConstraints blk = (EncodeDisk blk blk, DecodeDisk blk (ByteString -> blk), DecodeDiskDep (NestedCtxt Header) blk, HasNestedContent Header blk, HasBinaryBlockInfo blk)

-- | The maximum number of blocks to store per file.
data BlocksPerFile

-- | Create a <a>BlocksPerFile</a>.
--   
--   PRECONDITION: the given number must be greater than 0, if not, this
--   function will throw an <a>error</a>.
mkBlocksPerFile :: Word32 -> BlocksPerFile

-- | When block validation is enabled, the parser checks for each block a
--   number of properties and stops parsing if it finds any invalid blocks.
data BlockValidationPolicy
NoValidation :: BlockValidationPolicy
ValidateAll :: BlockValidationPolicy

-- | Note that we recover from the error, and thus never throw it as an
--   <tt>Exception</tt>.
--   
--   Defined here instead of in the <tt>Parser</tt> module because
--   <a>TraceEvent</a> depends on it.
data ParseError blk

-- | A block could not be parsed.
BlockReadErr :: ReadIncrementalErr -> ParseError blk

-- | A block was corrupted, e.g., checking its signature and/or hash
--   failed.
BlockCorruptedErr :: HeaderHash blk -> ParseError blk

-- | A block with the same hash occurred twice in the VolatileDB files.
--   
--   We include the file in which it occurred first and the file in which
--   it occured the second time. The two files can be the same.
DuplicatedBlock :: HeaderHash blk -> FsPath -> FsPath -> ParseError blk
data TraceEvent blk
DBAlreadyClosed :: TraceEvent blk
DBAlreadyOpen :: TraceEvent blk
BlockAlreadyHere :: HeaderHash blk -> TraceEvent blk
TruncateCurrentFile :: FsPath -> TraceEvent blk
Truncate :: ParseError blk -> FsPath -> BlockOffset -> TraceEvent blk
InvalidFileNames :: [FsPath] -> TraceEvent blk
extractBlockInfo :: (GetPrevHash blk, HasBinaryBlockInfo blk) => blk -> BlockInfo blk

module Ouroboros.Consensus.Storage.VolatileDB

module Ouroboros.Consensus.Storage.ImmutableDB.API

-- | API for the <a>ImmutableDB</a>.
--   
--   The <a>ImmutableDB</a> stores blocks in <a>SlotNo</a>s. Nevertheless,
--   lookups use <a>RealPoint</a>, primarily because Epoch Boundary Blocks
--   (EBBs) have the same <a>SlotNo</a> as the regular block after them
--   (unless that slot is empty), so that we have to use the hash of the
--   block to distinguish the two (hence <a>RealPoint</a>). But also to
--   avoid reading the wrong block, i.e., when we expect a block with a
--   different hash.
--   
--   The database is append-only, so you cannot append a block to a slot in
--   the past. You can, however, skip slots, e.g., append to slot 0 and
--   then to slot 5, but afterwards, you can no longer append to slots 1-4.
--   You can only store at most one block in each slot, except for EBBs,
--   which are stored separately, at the start of each epoch/chunk.
--   
--   The block stored in a slot can be queried with
--   <a>getBlockComponent</a>. Block components can also be streamed using
--   <a>Iterator</a>s, see <a>stream</a>.
--   
--   The <a>Tip</a> of the database can be queried with <a>getTip</a>. This
--   tip will always point to a filled slot or an EBB that is present.
--   
--   The database can be explicitly closed, but can also be automatically
--   closed in case of an <a>UnexpectedFailure</a>.
data ImmutableDB m blk
ImmutableDB :: (HasCallStack => m ()) -> (HasCallStack => STM m (WithOrigin (Tip blk))) -> (forall b. HasCallStack => BlockComponent blk b -> RealPoint blk -> m (Either (MissingBlock blk) b)) -> (HasCallStack => blk -> m ()) -> (forall b. HasCallStack => ResourceRegistry m -> BlockComponent blk b -> StreamFrom blk -> StreamTo blk -> m (Either (MissingBlock blk) (Iterator m blk b))) -> ImmutableDB m blk

-- | Close the database.
--   
--   Idempotent.
--   
--   <b>Note</b>: Use <a>withDB</a> instead of this function.
[closeDB_] :: ImmutableDB m blk -> HasCallStack => m ()

-- | Return the tip of the database.
--   
--   The tip of the database will never point to an unfilled slot or
--   missing EBB.
--   
--   Throws a <a>ClosedDBError</a> if the database is closed.
[getTip_] :: ImmutableDB m blk -> HasCallStack => STM m (WithOrigin (Tip blk))

-- | Get the block component of the block with the given <a>Point</a>.
--   
--   The hash of the point is used to distinguish a potential EBB from the
--   regular block in the same slot.
--   
--   Returns a <a>MissingBlockError</a> if no block was stored with the
--   given <a>Point</a>, either because the slot was empty or because the
--   block stored with that slot had a different hash.
--   
--   Throws a <a>ClosedDBError</a> if the database is closed.
[getBlockComponent_] :: ImmutableDB m blk -> forall b. HasCallStack => BlockComponent blk b -> RealPoint blk -> m (Either (MissingBlock blk) b)

-- | Appends a block to the ImmutableDB.
--   
--   Throws an <a>AppendBlockNotNewerThanTipError</a> if the given slot is
--   &lt;= the result of <a>getTip</a>.
--   
--   Throws a <a>ClosedDBError</a> if the database is closed.
[appendBlock_] :: ImmutableDB m blk -> HasCallStack => blk -> m ()

-- | Return an <a>Iterator</a> to efficiently stream blocks from the
--   ImmutableDB.
--   
--   Throws an <a>InvalidIteratorRangeError</a> if the start of the range
--   is greater than the end of the range.
--   
--   NOTE: <a>MissingBlock</a> is returned, but
--   <a>InvalidIteratorRangeError</a> is thrown. This is because the former
--   is expected to occur during normal operation: a node serving blocks
--   might get requests to stream blocks that are not in the database. The
--   latter exception indicates incorrect usage and should not happen
--   during normal operation.
--   
--   Throws a <a>ClosedDBError</a> if the database is closed.
--   
--   The iterator is automatically closed when exhausted, and can be
--   prematurely closed with <a>iteratorClose</a>.
[stream_] :: ImmutableDB m blk -> forall b. HasCallStack => ResourceRegistry m -> BlockComponent blk b -> StreamFrom blk -> StreamTo blk -> m (Either (MissingBlock blk) (Iterator m blk b))

-- | An <a>Iterator</a> is a handle which can be used to efficiently stream
--   block components from the ImmutableDB.
data Iterator m blk b
Iterator :: (HasCallStack => m (IteratorResult b)) -> (HasCallStack => STM m (Maybe (RealPoint blk))) -> (HasCallStack => m ()) -> Iterator m blk b

-- | Steps an <a>Iterator</a> yielding an <a>IteratorResult</a>.
--   
--   After returning the block component as an <a>IteratorResult</a>, the
--   iterator is advanced to the next non-empty slot or non-empty EBB.
--   
--   Throws a <a>ClosedDBError</a> if the database is closed.
--   
--   The iterator is automatically closed when exhausted
--   (<a>IteratorExhausted</a>), and can be prematurely closed with
--   <a>iteratorClose</a>.
[iteratorNext] :: Iterator m blk b -> HasCallStack => m (IteratorResult b)

-- | Return the point of the next block to stream, if there is one. Return
--   <a>Nothing</a> if not.
--   
--   This operation is idempotent.
[iteratorHasNext] :: Iterator m blk b -> HasCallStack => STM m (Maybe (RealPoint blk))

-- | Dispose of the <a>Iterator</a> by closing any open handles.
--   
--   Idempotent operation.
[iteratorClose] :: Iterator m blk b -> HasCallStack => m ()

-- | The result of stepping an <a>Iterator</a>.
data IteratorResult b
IteratorExhausted :: IteratorResult b
IteratorResult :: b -> IteratorResult b

-- | Variant of <a>traverse</a> instantiated to <tt><a>Iterator</a> m blk
--   m</tt> that executes the monadic function when calling
--   <a>iteratorNext</a>.
traverseIterator :: Monad m => (b -> m b') -> Iterator m blk b -> Iterator m blk b'

-- | Consume an <a>Iterator</a> by stepping until it is exhausted. A list
--   of all the <a>IteratorResult</a>s (excluding the final
--   <a>IteratorExhausted</a>) produced by the <a>Iterator</a> is returned.
iteratorToList :: (HasCallStack, Monad m) => Iterator m blk b -> m [b]

-- | Information about the tip of the ImmutableDB.
data Tip blk
Tip :: !SlotNo -> !IsEBB -> !BlockNo -> !HeaderHash blk -> Tip blk
[tipSlotNo] :: Tip blk -> !SlotNo
[tipIsEBB] :: Tip blk -> !IsEBB
[tipBlockNo] :: Tip blk -> !BlockNo
[tipHash] :: Tip blk -> !HeaderHash blk
tipToRealPoint :: Tip blk -> RealPoint blk
tipToPoint :: WithOrigin (Tip blk) -> Point blk
tipToAnchor :: WithOrigin (Tip blk) -> Anchor blk
blockToTip :: (HasHeader blk, GetHeader blk) => blk -> Tip blk

-- | newtype with an <a>Ord</a> instance that only uses <a>tipSlotNo</a>
--   and <a>tipIsEBB</a> and ignores the other fields.
newtype CompareTip blk
CompareTip :: Tip blk -> CompareTip blk
[getCompareTip] :: CompareTip blk -> Tip blk

-- | Errors that might arise when working with this database.
data ImmutableDBError

-- | An error thrown because of incorrect usage of the immutable database
--   by the user.
ApiMisuse :: ApiMisuse -> PrettyCallStack -> ImmutableDBError

-- | An unexpected error thrown because something went wrong on a lower
--   layer.
UnexpectedFailure :: UnexpectedFailure -> ImmutableDBError
data ApiMisuse

-- | When trying to append a new block, it was not newer than the current
--   tip, i.e., the slot was older than or equal to the current tip's slot.
--   
--   The <a>RealPoint</a> corresponds to the new block and the <a>Point</a>
--   to the current tip.
AppendBlockNotNewerThanTipError :: RealPoint blk -> Point blk -> ApiMisuse

-- | When the chosen iterator range was invalid, i.e. the <tt>start</tt>
--   (first parameter) came after the <tt>end</tt> (second parameter).
InvalidIteratorRangeError :: StreamFrom blk -> StreamTo blk -> ApiMisuse

-- | When performing an operation on a closed DB that is only allowed when
--   the database is open.
ClosedDBError :: ApiMisuse

-- | When performing an operation on an open DB that is only allowed when
--   the database is closed.
OpenDBError :: ApiMisuse
throwApiMisuse :: (MonadThrow m, HasCallStack) => ApiMisuse -> m a
data UnexpectedFailure

-- | An IO operation on the file-system threw an error.
FileSystemError :: FsError -> UnexpectedFailure

-- | When loading an epoch or index file, its contents did not pass
--   validation.
InvalidFileError :: FsPath -> String -> PrettyCallStack -> UnexpectedFailure

-- | A missing epoch or index file.
MissingFileError :: FsPath -> PrettyCallStack -> UnexpectedFailure

-- | There was a checksum mismatch when reading the block with the given
--   point. The first <a>CRC</a> is the expected one, the second one the
--   actual one.
ChecksumMismatchError :: RealPoint blk -> CRC -> CRC -> FsPath -> PrettyCallStack -> UnexpectedFailure

-- | A block failed to parse
ParseError :: FsPath -> RealPoint blk -> DeserialiseFailure -> UnexpectedFailure

-- | When parsing a block we got some trailing data
TrailingDataError :: FsPath -> RealPoint blk -> ByteString -> UnexpectedFailure

-- | Block missing
--   
--   This exception gets thrown when a block that we <i>know</i> it should
--   be in the ImmutableDB, nonetheless was not found.
MissingBlockError :: MissingBlock blk -> UnexpectedFailure

-- | A (parsed) block did not pass the integrity check.
--   
--   This exception gets thrown when a block doesn't pass the integrity
--   check done for <a>GetVerifiedBlock</a>.
--   
--   NOTE: we do not check the integrity of a block when it is added to the
--   ImmutableDB. While this exception typically means the block has been
--   corrupted, it could also mean the block didn't pass the check at the
--   time it was added.
CorruptBlockError :: RealPoint blk -> UnexpectedFailure
throwUnexpectedFailure :: MonadThrow m => UnexpectedFailure -> m a

-- | This type can be part of an exception, but also returned as part of an
--   <a>Either</a>, because it can be expected in some cases.
data MissingBlock blk

-- | There is no block in the slot of the given point.
EmptySlot :: RealPoint blk -> MissingBlock blk

-- | The block and/or EBB in the slot of the given point have a different
--   hash.
WrongHash :: RealPoint blk -> NonEmpty (HeaderHash blk) -> MissingBlock blk

-- | The requested point is in the future, i.e., its slot is greater than
--   that of the tip. We record the tip as the second argument.
NewerThanTip :: RealPoint blk -> Point blk -> MissingBlock blk

-- | Return the <a>RealPoint</a> of the block that was missing.
missingBlockPoint :: MissingBlock blk -> RealPoint blk
closeDB :: HasCallStack => ImmutableDB m blk -> m ()
getTip :: HasCallStack => ImmutableDB m blk -> STM m (WithOrigin (Tip blk))
getBlockComponent :: HasCallStack => ImmutableDB m blk -> BlockComponent blk b -> RealPoint blk -> m (Either (MissingBlock blk) b)
appendBlock :: HasCallStack => ImmutableDB m blk -> blk -> m ()
stream :: HasCallStack => ImmutableDB m blk -> ResourceRegistry m -> BlockComponent blk b -> StreamFrom blk -> StreamTo blk -> m (Either (MissingBlock blk) (Iterator m blk b))

-- | Open the database using the given function, perform the given action
--   using the database, and closes the database using its <a>closeDB</a>
--   function, in case of success or when an exception was raised.
withDB :: (HasCallStack, MonadThrow m) => m (ImmutableDB m blk) -> (ImmutableDB m blk -> m a) -> m a
getKnownBlockComponent :: (MonadThrow m, HasHeader blk) => ImmutableDB m blk -> BlockComponent blk b -> RealPoint blk -> m b

-- | Variant of <a>streamAfterPoint</a> that throws a
--   <a>MissingBlockError</a> when the point is not in the ImmutableDB (or
--   genesis).
streamAfterKnownPoint :: (MonadSTM m, MonadThrow m, HasHeader blk, HasCallStack) => ImmutableDB m blk -> ResourceRegistry m -> BlockComponent blk b -> Point blk -> m (Iterator m blk b)

-- | Open an iterator with the given point as lower exclusive bound and the
--   current tip as the inclusive upper bound.
--   
--   Returns a <a>MissingBlock</a> when the point is not in the
--   ImmutableDB.
streamAfterPoint :: (MonadSTM m, HasHeader blk, HasCallStack) => ImmutableDB m blk -> ResourceRegistry m -> BlockComponent blk b -> Point blk -> m (Either (MissingBlock blk) (Iterator m blk b))
streamAll :: (MonadSTM m, MonadThrow m, HasHeader blk, HasCallStack) => ImmutableDB m blk -> ResourceRegistry m -> BlockComponent blk b -> m (Iterator m blk b)
hasBlock :: (MonadSTM m, HasCallStack) => ImmutableDB m blk -> RealPoint blk -> m Bool
getTipPoint :: (MonadSTM m, HasCallStack) => ImmutableDB m blk -> STM m (Point blk)
getTipAnchor :: (MonadSTM m, HasCallStack) => ImmutableDB m blk -> STM m (Anchor blk)
getTipSlot :: (MonadSTM m, HasCallStack) => ImmutableDB m blk -> STM m (WithOrigin SlotNo)
instance Data.Traversable.Traversable Ouroboros.Consensus.Storage.ImmutableDB.API.IteratorResult
instance Data.Foldable.Foldable Ouroboros.Consensus.Storage.ImmutableDB.API.IteratorResult
instance GHC.Base.Functor Ouroboros.Consensus.Storage.ImmutableDB.API.IteratorResult
instance GHC.Generics.Generic (Ouroboros.Consensus.Storage.ImmutableDB.API.IteratorResult b)
instance GHC.Classes.Eq b => GHC.Classes.Eq (Ouroboros.Consensus.Storage.ImmutableDB.API.IteratorResult b)
instance GHC.Show.Show b => GHC.Show.Show (Ouroboros.Consensus.Storage.ImmutableDB.API.IteratorResult b)
instance NoThunks.Class.NoThunks (Ouroboros.Consensus.Storage.ImmutableDB.API.Iterator m blk b)
instance GHC.Base.Functor m => GHC.Base.Functor (Ouroboros.Consensus.Storage.ImmutableDB.API.Iterator m blk)
instance GHC.Generics.Generic (Ouroboros.Consensus.Storage.ImmutableDB.API.Tip blk)
instance GHC.Generics.Generic (Ouroboros.Consensus.Storage.ImmutableDB.API.MissingBlock blk)
instance Ouroboros.Network.Block.StandardHash blk => GHC.Show.Show (Ouroboros.Consensus.Storage.ImmutableDB.API.MissingBlock blk)
instance Ouroboros.Network.Block.StandardHash blk => GHC.Classes.Eq (Ouroboros.Consensus.Storage.ImmutableDB.API.MissingBlock blk)
instance GHC.Show.Show Ouroboros.Consensus.Storage.ImmutableDB.API.ImmutableDBError
instance GHC.Generics.Generic Ouroboros.Consensus.Storage.ImmutableDB.API.ImmutableDBError
instance NoThunks.Class.NoThunks (Ouroboros.Consensus.Storage.ImmutableDB.API.ImmutableDB m blk)
instance Ouroboros.Network.Block.StandardHash blk => GHC.Classes.Eq (Ouroboros.Consensus.Storage.ImmutableDB.API.Tip blk)
instance Ouroboros.Network.Block.StandardHash blk => GHC.Show.Show (Ouroboros.Consensus.Storage.ImmutableDB.API.Tip blk)
instance Ouroboros.Network.Block.StandardHash blk => NoThunks.Class.NoThunks (Ouroboros.Consensus.Storage.ImmutableDB.API.Tip blk)
instance GHC.Show.Show Ouroboros.Consensus.Storage.ImmutableDB.API.ApiMisuse
instance GHC.Show.Show Ouroboros.Consensus.Storage.ImmutableDB.API.UnexpectedFailure
instance GHC.Exception.Type.Exception Ouroboros.Consensus.Storage.ImmutableDB.API.ImmutableDBError
instance GHC.Classes.Eq (Ouroboros.Consensus.Storage.ImmutableDB.API.CompareTip blk)
instance GHC.Classes.Ord (Ouroboros.Consensus.Storage.ImmutableDB.API.CompareTip blk)

module Ouroboros.Consensus.Storage.ImmutableDB.Impl.Util

-- | Useful when you have exactly two values of some type and want to
--   <a>traverse</a> over both of them (which is not possible with a
--   tuple).
data Two a
Two :: a -> a -> Two a

-- | Opposite of <a>parseDBFile</a>.
renderFile :: Text -> ChunkNo -> FsPath
fsPathChunkFile :: ChunkNo -> FsPath
fsPathPrimaryIndexFile :: ChunkNo -> FsPath
fsPathSecondaryIndexFile :: ChunkNo -> FsPath

-- | Rewrap <a>FsError</a> in a <a>ImmutableDBError</a>.
wrapFsError :: MonadCatch m => m a -> m a

-- | Execute an action and catch the <a>ImmutableDBError</a> and
--   <a>FsError</a> that can be thrown by it, and wrap the <a>FsError</a>
--   in an <a>ImmutableDBError</a> using the <a>FileSystemError</a>
--   constructor.
--   
--   This should be used whenever you want to run an action on the
--   ImmutableDB and catch the <a>ImmutableDBError</a> and the
--   <a>FsError</a> (wrapped in the former) it may thrown.
tryImmutableDB :: MonadCatch m => m a -> m (Either ImmutableDBError a)

-- | Parse the prefix and chunk number from the filename of an index or
--   chunk file.
--   
--   <pre>
--   parseDBFile "00001.chunk"
--   </pre>
--   
--   Just ("chunk", 1) &gt; parseDBFile "00012.primary" Just ("primary",
--   12)
parseDBFile :: String -> Maybe (String, ChunkNo)

-- | Go through all files, making three sets: the set of chunk files,
--   primary index files, and secondary index files, discarding all others.
dbFilesOnDisk :: Set String -> (Set ChunkNo, Set ChunkNo, Set ChunkNo)

-- | Remove all chunk and index starting from the given chunk (included).
removeFilesStartingFrom :: (HasCallStack, Monad m) => HasFS m h -> ChunkNo -> m ()

-- | Wrapper around <a>runGetOrFail</a> that throws an
--   <a>InvalidFileError</a> when it failed or when there was unconsumed
--   input.
runGet :: (HasCallStack, MonadThrow m) => FsPath -> Get a -> ByteString -> m a

-- | Same as <a>runGet</a>, but allows unconsumed input and returns it.
runGetWithUnconsumed :: (HasCallStack, MonadThrow m) => FsPath -> Get a -> ByteString -> m (ByteString, a)

-- | Check whether the given checksums match. If not, throw a
--   <a>ChecksumMismatchError</a>.
checkChecksum :: (HasCallStack, HasHeader blk, MonadThrow m) => FsPath -> RealPoint blk -> CRC -> CRC -> m ()
instance Data.Traversable.Traversable Ouroboros.Consensus.Storage.ImmutableDB.Impl.Util.Two
instance Data.Foldable.Foldable Ouroboros.Consensus.Storage.ImmutableDB.Impl.Util.Two
instance GHC.Base.Functor Ouroboros.Consensus.Storage.ImmutableDB.Impl.Util.Two

module Ouroboros.Consensus.Storage.ImmutableDB.Impl.Types
data BlockOrEBB
Block :: !SlotNo -> BlockOrEBB
EBB :: !EpochNo -> BlockOrEBB
isBlockOrEBB :: BlockOrEBB -> IsEBB
data WithBlockSize a
WithBlockSize :: !Word32 -> !a -> WithBlockSize a
[blockSize] :: WithBlockSize a -> !Word32
[withoutBlockSize] :: WithBlockSize a -> !a

-- | The validation policy used when opening an <a>ImmutableDB</a>.
--   
--   The validation policy is used by <a>openDB</a>: the initial opening of
--   the database, either an empty database or a database that was
--   previously closed.
--   
--   The recovery policy dictates which on-disk files should be validated.
data ValidationPolicy

-- | The chunk and index files of the most recent chunk stored on disk will
--   be validated.
--   
--   Prior chunk and index files are ignored, even their presence will not
--   be checked.
--   
--   A <tt>MissingFileError</tt> or an <tt>InvalidFileError</tt> will be
--   thrown in case of a missing or invalid chunk file, or an invalid index
--   file.
--   
--   Because not all files are validated, subsequent operations on the
--   database after opening may result in unexpected errors.
ValidateMostRecentChunk :: ValidationPolicy

-- | The chunk and index files of all chunks starting from the first one up
--   to the last chunk stored on disk will be validated.
--   
--   A <tt>MissingFileError</tt> or an <tt>InvalidFileError</tt> will be
--   thrown in case of a missing or invalid chunk file, or an invalid index
--   file.
ValidateAllChunks :: ValidationPolicy

-- | Defined here instead of in the <tt>Parser</tt> module because
--   <a>TraceEvent</a> depends on it.
data ChunkFileError blk

-- | A block could not be decoded
ChunkErrRead :: ReadIncrementalErr -> ChunkFileError blk

-- | The previous hash of a block did not match the hash of the previous
--   block.
ChunkErrHashMismatch :: HeaderHash blk -> ChainHash blk -> ChunkFileError blk

-- | The integrity verification of the block with the given point returned
--   <a>False</a>, indicating that the block got corrupted.
ChunkErrCorrupt :: Point blk -> ChunkFileError blk
data TraceEvent blk
NoValidLastLocation :: TraceEvent blk
ValidatedLastLocation :: ChunkNo -> Tip blk -> TraceEvent blk
ValidatingChunk :: ChunkNo -> TraceEvent blk
MissingChunkFile :: ChunkNo -> TraceEvent blk
InvalidChunkFile :: ChunkNo -> ChunkFileError blk -> TraceEvent blk

-- | The hash of the last block in the previous epoch doesn't match the
--   previous hash of the first block in the current epoch
ChunkFileDoesntFit :: ChainHash blk -> ChainHash blk -> TraceEvent blk
MissingPrimaryIndex :: ChunkNo -> TraceEvent blk
MissingSecondaryIndex :: ChunkNo -> TraceEvent blk
InvalidPrimaryIndex :: ChunkNo -> TraceEvent blk
InvalidSecondaryIndex :: ChunkNo -> TraceEvent blk
RewritePrimaryIndex :: ChunkNo -> TraceEvent blk
RewriteSecondaryIndex :: ChunkNo -> TraceEvent blk

-- | Performing a migration of the on-disk files
Migrating :: Text -> TraceEvent blk
DeletingAfter :: WithOrigin (Tip blk) -> TraceEvent blk
DBAlreadyClosed :: TraceEvent blk
DBClosed :: TraceEvent blk
TraceCacheEvent :: !TraceCacheEvent -> TraceEvent blk

-- | The argument with type <a>Word32</a> is the number of past chunk
--   currently in the cache.
data TraceCacheEvent
TraceCurrentChunkHit :: ChunkNo -> Word32 -> TraceCacheEvent
TracePastChunkHit :: ChunkNo -> Word32 -> TraceCacheEvent
TracePastChunkMiss :: ChunkNo -> Word32 -> TraceCacheEvent

-- | The least recently used past chunk was evicted because the cache was
--   full.
TracePastChunkEvict :: ChunkNo -> Word32 -> TraceCacheEvent

-- | Past chunks were expired from the cache because they haven't been used
--   for a while.
TracePastChunksExpired :: [ChunkNo] -> Word32 -> TraceCacheEvent
instance NoThunks.Class.NoThunks Ouroboros.Consensus.Storage.ImmutableDB.Impl.Types.BlockOrEBB
instance GHC.Generics.Generic Ouroboros.Consensus.Storage.ImmutableDB.Impl.Types.BlockOrEBB
instance GHC.Show.Show Ouroboros.Consensus.Storage.ImmutableDB.Impl.Types.BlockOrEBB
instance GHC.Classes.Eq Ouroboros.Consensus.Storage.ImmutableDB.Impl.Types.BlockOrEBB
instance Data.Traversable.Traversable Ouroboros.Consensus.Storage.ImmutableDB.Impl.Types.WithBlockSize
instance Data.Foldable.Foldable Ouroboros.Consensus.Storage.ImmutableDB.Impl.Types.WithBlockSize
instance GHC.Base.Functor Ouroboros.Consensus.Storage.ImmutableDB.Impl.Types.WithBlockSize
instance NoThunks.Class.NoThunks a => NoThunks.Class.NoThunks (Ouroboros.Consensus.Storage.ImmutableDB.Impl.Types.WithBlockSize a)
instance GHC.Generics.Generic (Ouroboros.Consensus.Storage.ImmutableDB.Impl.Types.WithBlockSize a)
instance GHC.Show.Show a => GHC.Show.Show (Ouroboros.Consensus.Storage.ImmutableDB.Impl.Types.WithBlockSize a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Ouroboros.Consensus.Storage.ImmutableDB.Impl.Types.WithBlockSize a)
instance GHC.Generics.Generic Ouroboros.Consensus.Storage.ImmutableDB.Impl.Types.ValidationPolicy
instance GHC.Classes.Eq Ouroboros.Consensus.Storage.ImmutableDB.Impl.Types.ValidationPolicy
instance GHC.Show.Show Ouroboros.Consensus.Storage.ImmutableDB.Impl.Types.ValidationPolicy
instance Ouroboros.Network.Block.StandardHash blk => GHC.Show.Show (Ouroboros.Consensus.Storage.ImmutableDB.Impl.Types.ChunkFileError blk)
instance Ouroboros.Network.Block.StandardHash blk => GHC.Classes.Eq (Ouroboros.Consensus.Storage.ImmutableDB.Impl.Types.ChunkFileError blk)
instance GHC.Show.Show Ouroboros.Consensus.Storage.ImmutableDB.Impl.Types.TraceCacheEvent
instance GHC.Generics.Generic Ouroboros.Consensus.Storage.ImmutableDB.Impl.Types.TraceCacheEvent
instance GHC.Classes.Eq Ouroboros.Consensus.Storage.ImmutableDB.Impl.Types.TraceCacheEvent
instance Ouroboros.Network.Block.StandardHash blk => GHC.Show.Show (Ouroboros.Consensus.Storage.ImmutableDB.Impl.Types.TraceEvent blk)
instance GHC.Generics.Generic (Ouroboros.Consensus.Storage.ImmutableDB.Impl.Types.TraceEvent blk)
instance Ouroboros.Network.Block.StandardHash blk => GHC.Classes.Eq (Ouroboros.Consensus.Storage.ImmutableDB.Impl.Types.TraceEvent blk)


-- | Layout of individual chunks on disk
--   
--   This module is not re-exported from the public Chunks API, since it's
--   only relevant internally in the immutable DB.
module Ouroboros.Consensus.Storage.ImmutableDB.Chunks.Layout

-- | A <i>relative</i> slot within a chunk
data RelativeSlot

-- | The last relative slot within a chunk of the given size
maxRelativeSlot :: ChunkInfo -> ChunkNo -> RelativeSlot

-- | Is this relative slot reserved for an EBB?
relativeSlotIsEBB :: RelativeSlot -> IsEBB

-- | The <tt>n</tt>'th relative slot for an arbitrary block
--   
--   NOTE: Offset <tt>0</tt> refers to an EBB only if the <a>ChunkSize</a>
--   supports it.
nthBlockOrEBB :: (HasCallStack, Integral a) => ChunkInfo -> ChunkNo -> a -> RelativeSlot

-- | The first relative slot
--   
--   NOTE: This refers to an EBB only if the <a>ChunkSize</a> supports it.
firstBlockOrEBB :: ChunkInfo -> ChunkNo -> RelativeSlot

-- | Result of <a>nextRelativeSlot</a>
data NextRelativeSlot

-- | There is a next negative slot
NextRelativeSlot :: RelativeSlot -> NextRelativeSlot

-- | We reached the end of the chunk
NoMoreRelativeSlots :: NextRelativeSlot

-- | Next relative slot
nextRelativeSlot :: HasCallStack => RelativeSlot -> NextRelativeSlot

-- | Variation on <a>nextRelativeSlot</a> where the caller <i>knows</i>
--   that there must be a next slot
--   
--   Throws an assertion failure (if assertions are enabled) if there is no
--   next slot.
unsafeNextRelativeSlot :: HasCallStack => RelativeSlot -> RelativeSlot
chunkIndexOfSlot :: ChunkInfo -> SlotNo -> ChunkNo

-- | Uniquely identify a block within the immutable DB
--   
--   Constructor marked as <tt>Unsafe</tt>; construction should normally
--   happen inside this module only (though see the <a>ChunkSlot</a>
--   pattern synonym).
data ChunkSlot
UnsafeChunkSlot :: !ChunkNo -> !RelativeSlot -> ChunkSlot
[chunkIndex] :: ChunkSlot -> !ChunkNo
[chunkRelative] :: ChunkSlot -> !RelativeSlot
pattern ChunkSlot :: ChunkNo -> RelativeSlot -> ChunkSlot

-- | Chunk slot for an unknown block
--   
--   This returns <i>two</i> <a>ChunkSlot</a>s: one in case the block could
--   be an EBB, and one in case the block is a regular block. In addition,
--   it also returns the <a>ChunkNo</a> that both of these
--   <a>ChunkSlot</a>s must necessarily share.
chunkSlotForUnknownBlock :: HasCallStack => ChunkInfo -> SlotNo -> (ChunkNo, Maybe ChunkSlot, ChunkSlot)

-- | Chunk slot for a regular block (i.e., not an EBB)
chunkSlotForRegularBlock :: ChunkInfo -> SlotNo -> ChunkSlot

-- | Chunk slot for EBB
chunkSlotForBoundaryBlock :: HasCallStack => ChunkInfo -> EpochNo -> ChunkSlot

-- | Chunk slot for <a>BlockOrEBB</a>
chunkSlotForBlockOrEBB :: ChunkInfo -> BlockOrEBB -> ChunkSlot

-- | Chunk slot for <a>Tip</a>
chunkSlotForTip :: ChunkInfo -> Tip blk -> ChunkSlot
chunkSlotForRelativeSlot :: ChunkNo -> RelativeSlot -> ChunkSlot

-- | From relative to absolute slot
--   
--   This can be used for EBBs and regular blocks, since they don't share a
--   relative slot.
chunkSlotToSlot :: ChunkInfo -> ChunkSlot -> SlotNo
chunkSlotToBlockOrEBB :: ChunkInfo -> ChunkSlot -> BlockOrEBB
slotNoOfEBB :: HasCallStack => ChunkInfo -> EpochNo -> SlotNo
slotMightBeEBB :: ChunkInfo -> SlotNo -> Maybe EpochNo
slotNoOfBlockOrEBB :: ChunkInfo -> BlockOrEBB -> SlotNo
instance NoThunks.Class.NoThunks Ouroboros.Consensus.Storage.ImmutableDB.Chunks.Layout.ChunkSlot
instance GHC.Generics.Generic Ouroboros.Consensus.Storage.ImmutableDB.Chunks.Layout.ChunkSlot
instance GHC.Classes.Eq Ouroboros.Consensus.Storage.ImmutableDB.Chunks.Layout.ChunkSlot
instance GHC.Classes.Ord Ouroboros.Consensus.Storage.ImmutableDB.Chunks.Layout.ChunkSlot
instance GHC.Show.Show Ouroboros.Consensus.Storage.ImmutableDB.Chunks.Layout.ChunkSlot

module Ouroboros.Consensus.Storage.ImmutableDB.Chunks

-- | A <i>relative</i> slot within a chunk
data RelativeSlot

-- | Chunk number
data ChunkNo

-- | Size of a chunk
--   
--   The total number of slots available in a chunk is equal to
--   <a>numRegularBlocks</a> if <tt>not</tt> <a>chunkCanContainEBB</a>, and
--   <a>numRegularBlocks</a> <tt>+ 1</tt> otherwise.
data ChunkSize
ChunkSize :: !Bool -> !Word64 -> ChunkSize

-- | Does this chunk also accomodate an EBB?
[chunkCanContainEBB] :: ChunkSize -> !Bool

-- | The number of regular blocks in this chunk
[numRegularBlocks] :: ChunkSize -> !Word64

-- | Size of the chunks of the immutable DB
--   
--   This is the key data structure that drives all layout functions.
--   
--   TODO: Add support for non-uniform <a>ChunkInfo</a>
--   <a>https://github.com/input-output-hk/ouroboros-network/issues/1754</a>
data ChunkInfo

-- | A single, uniform, chunk size
--   
--   If EBBs are present, the chunk size must line up precisely with the
--   epoch size (that is, the number of regular blocks in the chunk must
--   equal the number of regular blocks in an epoch).
UniformChunkSize :: !ChunkSize -> ChunkInfo

-- | Simple chunk config with a single chunk size
--   
--   This intentionally takes <a>EpochSize</a> (number of slots) rather
--   than <a>ChunkSize</a>: the translation from <a>EpochSize</a> to
--   <a>ChunkSize</a> (number of available entries in a chunk) should not
--   be done by client code.
simpleChunkInfo :: EpochSize -> ChunkInfo

-- | <a>ChunkInfo</a> for a single <a>ChunkSize</a>
--   
--   See also <a>simpleChunkInfo</a>.
singleChunkInfo :: ChunkSize -> ChunkInfo

-- | Can we store EBBs in the chunks described by this <a>ChunkInfo</a>?
--   
--   This is only used for tests. This API will need to change (and the
--   tests will become more complicated) once we support non-uniform
--   <a>ChunkInfo</a>.
chunkInfoSupportsEBBs :: ChunkInfo -> Bool

-- | First chunk
firstChunkNo :: ChunkNo
nextChunkNo :: ChunkNo -> ChunkNo
prevChunkNo :: ChunkNo -> Maybe ChunkNo

-- | Count number of chunks between two indices
--   
--   <pre>
--   countChunks x              x  == 0
--   countChunks x (nextChunkNo x) == 1
--   </pre>
countChunks :: ChunkNo -> ChunkNo -> Word64

-- | Enumerate all chunks
--   
--   <pre>
--   chunksBetween x              x  == [x]
--   chunksBetween x (nextChunkNo x) == [x, nextChunkNo x]
--   </pre>
chunksBetween :: ChunkNo -> ChunkNo -> [ChunkNo]
getChunkSize :: ChunkInfo -> ChunkNo -> ChunkSize

-- | Smart constructor for <a>RelativeSlot</a>
mkRelativeSlot :: HasCallStack => ChunkInfo -> ChunkNo -> Word64 -> RelativeSlot

-- | <a>RelativeSlot</a> is partially ordered, not totally ordered
--   
--   It makes no sense to compare <tt>RelativeSlots</tt> from different
--   chunks. Doing so will result in an assertion failure.
compareRelativeSlot :: HasCallStack => RelativeSlot -> RelativeSlot -> Ordering

-- | Uniquely identify a block within the immutable DB
--   
--   Constructor marked as <tt>Unsafe</tt>; construction should normally
--   happen inside this module only (though see the <a>ChunkSlot</a>
--   pattern synonym).
data ChunkSlot
UnsafeChunkSlot :: !ChunkNo -> !RelativeSlot -> ChunkSlot
[chunkIndex] :: ChunkSlot -> !ChunkNo
[chunkRelative] :: ChunkSlot -> !RelativeSlot

-- | Result of <a>nextRelativeSlot</a>
data NextRelativeSlot

-- | There is a next negative slot
NextRelativeSlot :: RelativeSlot -> NextRelativeSlot

-- | We reached the end of the chunk
NoMoreRelativeSlots :: NextRelativeSlot
pattern ChunkSlot :: ChunkNo -> RelativeSlot -> ChunkSlot

-- | The last relative slot within a chunk of the given size
maxRelativeSlot :: ChunkInfo -> ChunkNo -> RelativeSlot

-- | Is this relative slot reserved for an EBB?
relativeSlotIsEBB :: RelativeSlot -> IsEBB

-- | The <tt>n</tt>'th relative slot for an arbitrary block
--   
--   NOTE: Offset <tt>0</tt> refers to an EBB only if the <a>ChunkSize</a>
--   supports it.
nthBlockOrEBB :: (HasCallStack, Integral a) => ChunkInfo -> ChunkNo -> a -> RelativeSlot

-- | The first relative slot
--   
--   NOTE: This refers to an EBB only if the <a>ChunkSize</a> supports it.
firstBlockOrEBB :: ChunkInfo -> ChunkNo -> RelativeSlot

-- | Next relative slot
nextRelativeSlot :: HasCallStack => RelativeSlot -> NextRelativeSlot

-- | Variation on <a>nextRelativeSlot</a> where the caller <i>knows</i>
--   that there must be a next slot
--   
--   Throws an assertion failure (if assertions are enabled) if there is no
--   next slot.
unsafeNextRelativeSlot :: HasCallStack => RelativeSlot -> RelativeSlot
chunkIndexOfSlot :: ChunkInfo -> SlotNo -> ChunkNo

-- | Chunk slot for an unknown block
--   
--   This returns <i>two</i> <a>ChunkSlot</a>s: one in case the block could
--   be an EBB, and one in case the block is a regular block. In addition,
--   it also returns the <a>ChunkNo</a> that both of these
--   <a>ChunkSlot</a>s must necessarily share.
chunkSlotForUnknownBlock :: HasCallStack => ChunkInfo -> SlotNo -> (ChunkNo, Maybe ChunkSlot, ChunkSlot)

-- | Chunk slot for a regular block (i.e., not an EBB)
chunkSlotForRegularBlock :: ChunkInfo -> SlotNo -> ChunkSlot

-- | Chunk slot for EBB
chunkSlotForBoundaryBlock :: HasCallStack => ChunkInfo -> EpochNo -> ChunkSlot

-- | Chunk slot for <a>BlockOrEBB</a>
chunkSlotForBlockOrEBB :: ChunkInfo -> BlockOrEBB -> ChunkSlot

-- | Chunk slot for <a>Tip</a>
chunkSlotForTip :: ChunkInfo -> Tip blk -> ChunkSlot
chunkSlotForRelativeSlot :: ChunkNo -> RelativeSlot -> ChunkSlot

-- | From relative to absolute slot
--   
--   This can be used for EBBs and regular blocks, since they don't share a
--   relative slot.
chunkSlotToSlot :: ChunkInfo -> ChunkSlot -> SlotNo
chunkSlotToBlockOrEBB :: ChunkInfo -> ChunkSlot -> BlockOrEBB
slotNoOfEBB :: HasCallStack => ChunkInfo -> EpochNo -> SlotNo
slotMightBeEBB :: ChunkInfo -> SlotNo -> Maybe EpochNo
slotNoOfBlockOrEBB :: ChunkInfo -> BlockOrEBB -> SlotNo


-- | Primary Index
--   
--   Intended for qualified import &gt; import qualified
--   Ouroboros.Consensus.Storage.ImmutableDB.Impl.Index.Primary as
--   PrimaryIndex
module Ouroboros.Consensus.Storage.ImmutableDB.Impl.Index.Primary

-- | An offset in the secondary index file.
--   
--   We need 4 bytes (<a>Word32</a>) because the secondary index file can
--   grow to +1MiB.
type SecondaryOffset = Word32

-- | In-memory representation of the primary index file.
--   
--   The primary index maps relative slots to offsets in the secondary
--   index file. The first offset is always 0, as the first entry in the
--   secondary index file will always start at offset 0. The second offset
--   will be equal to the size of a secondary index entry, unless the slot
--   is empty, in which case it will be 0. In general, an offset will
--   either be a repetition of the offset before it, to indicate the slot
--   is empty, or the offset before it + the fixed size of a secondary
--   index entry, in case the slot is filled.
--   
--   The size of a secondary index entry can be computed by subtracting the
--   offset corresponding to the respective slot from the offset
--   corresponding to the slot after it.
--   
--   For example, if slots 0, 1 and 4 are filled, we'd have the following
--   offsets in the primary index file:
--   
--   <pre>
--   slot:       0   1   2   3   4
--           ┌───┬───┬───┬───┬───┬───┐
--   offset: │ 0 │ x │ y │ y │ y │ z │
--           └───┴───┴───┴───┴───┴───┘
--   </pre>
--   
--   We use <tt>x, y, z</tt> in the example above, but in practice these
--   will be multiples of the (fixed) size of an entry in secondary index.
--   
--   TODO As all entries have the same size, we could use a bitvector
--   instead, see #1234.
--   
--   The serialisation of a primary index file starts with
--   <tt>currentVersionNumber</tt> followed by all its offset.
data PrimaryIndex
MkPrimaryIndex :: !ChunkNo -> !Vector SecondaryOffset -> PrimaryIndex

-- | The <a>ChunkNo</a> of the chunk this index is associated with
[primaryIndexChunkNo] :: PrimaryIndex -> !ChunkNo

-- | The entries in the index proper
[primaryIndexOffsets] :: PrimaryIndex -> !Vector SecondaryOffset

-- | Version number of the index format
currentVersionNumber :: Word8

-- | Count the number of (filled or unfilled) slots currently in the index
slots :: PrimaryIndex -> Word64

-- | The size of each entry in the primary index file, i.e., the size of a
--   <a>SecondaryOffset</a>.
secondaryOffsetSize :: Word64

-- | Read the <a>SecondaryOffset</a> corresponding to the given relative
--   slot in the primary index. Return <a>Nothing</a> when the slot is
--   empty.
readOffset :: forall m h. (HasCallStack, MonadThrow m) => HasFS m h -> ChunkNo -> RelativeSlot -> m (Maybe SecondaryOffset)

-- | Same as <a>readOffset</a>, but for multiple offsets.
--   
--   NOTE: only use this for a few offsets, as we will seek
--   (<tt>pread</tt>) for each offset. Use <a>load</a> if you want to read
--   the whole primary index.
readOffsets :: forall m h t. (HasCallStack, MonadThrow m, Traversable t) => HasFS m h -> ChunkNo -> t RelativeSlot -> m (t (Maybe SecondaryOffset))

-- | Return the first filled slot in the primary index file, or
--   <a>Nothing</a> in case there are no filled slots.
--   
--   PRECONDITION: the index file must exist and contain at least the
--   version number and offset 0.
--   
--   May throw <tt>InvalidPrimaryIndexException</tt>.
readFirstFilledSlot :: forall m h. (HasCallStack, MonadThrow m) => HasFS m h -> ChunkInfo -> ChunkNo -> m (Maybe RelativeSlot)

-- | Load a primary index file in memory.
load :: forall m h. (HasCallStack, MonadThrow m) => HasFS m h -> ChunkNo -> m PrimaryIndex

-- | Write a primary index to a file.
--   
--   Property: for <tt>hasFS</tt>, <tt>err</tt>, <tt>chunk</tt>
--   
--   <pre>
--   'write' hasFS chunk primaryIndex
--   primaryIndex' &lt;- 'load' hasFS err chunk
--   </pre>
--   
--   Then it must be that:
--   
--   <pre>
--   primaryIndex === primaryIndex'
--   </pre>
write :: (HasCallStack, MonadThrow m) => HasFS m h -> ChunkNo -> PrimaryIndex -> m ()

-- | Truncate the primary index so that the given <a>RelativeSlot</a> will
--   be the last slot (filled or not) in the primary index, unless the
--   primary index didn't contain the <a>RelativeSlot</a> in the first
--   place.
truncateToSlot :: ChunkInfo -> RelativeSlot -> PrimaryIndex -> PrimaryIndex

-- | On-disk variant of <a>truncateToSlot</a>. The truncation is done
--   without reading the primary index from disk.
truncateToSlotFS :: (HasCallStack, MonadThrow m) => HasFS m h -> ChunkNo -> RelativeSlot -> m ()

-- | Remove all trailing empty slots that were added during the
--   finalisation/backfilling of the primary index.
--   
--   POSTCONDITION: the last slot of the primary index file will be filled,
--   unless the index itself is empty.
unfinalise :: (HasCallStack, MonadThrow m) => HasFS m h -> ChunkInfo -> ChunkNo -> m ()

-- | Open a primary index file for the given chunk and return a handle to
--   it.
--   
--   The file is opened with the given <a>AllowExisting</a> value. When
--   given <a>MustBeNew</a>, the version number is written to the file.
open :: (HasCallStack, MonadCatch m) => HasFS m h -> ChunkNo -> AllowExisting -> m (Handle h)

-- | Append the given <a>SecondaryOffset</a> to the end of the file (passed
--   as a handle).
appendOffsets :: (Monad m, Foldable f, HasCallStack) => HasFS m h -> Handle h -> f SecondaryOffset -> m ()

-- | Return the last <a>SecondaryOffset</a> in the primary index file.
lastOffset :: PrimaryIndex -> SecondaryOffset

-- | Return the last slot of the primary index (empty or not).
--   
--   Returns <a>Nothing</a> if the index is empty.
getLastSlot :: ChunkInfo -> PrimaryIndex -> Maybe RelativeSlot

-- | Check whether the given slot is within the primary index.
containsSlot :: PrimaryIndex -> RelativeSlot -> Bool

-- | Return the offset for the given slot.
--   
--   Precondition: the given slot must be within the primary index
--   (<a>containsSlot</a>).
offsetOfSlot :: HasCallStack => PrimaryIndex -> RelativeSlot -> SecondaryOffset

-- | Return the size of the given slot according to the primary index.
--   
--   Precondition: the given slot must be within the primary index
--   (<a>containsSlot</a>).
sizeOfSlot :: HasCallStack => PrimaryIndex -> RelativeSlot -> Word32

-- | Return <a>True</a> when the given slot is filled.
--   
--   Precondition: the given slot must be within the primary index
--   (<a>containsSlot</a>).
isFilledSlot :: HasCallStack => PrimaryIndex -> RelativeSlot -> Bool

-- | Find the next filled (length &gt; zero) slot after the given slot in
--   the primary index. If there is none, return <a>Nothing</a>.
--   
--   Precondition: the given slot must be within the primary index
--   (<a>containsSlot</a>).
--   
--   Example: given the primary index below and slot 1:
--   
--   <pre>
--   slot:       0   1   2   3   4
--           ┌───┬───┬───┬───┬───┬───┐
--   offset: │ 0 │ x │ y │ y │ y │ z │
--           └───┴───┴───┴───┴───┴───┘
--   </pre>
--   
--   Return slot 4.
nextFilledSlot :: ChunkInfo -> PrimaryIndex -> RelativeSlot -> Maybe RelativeSlot

-- | Find the first filled (length &gt; zero) slot in the primary index. If
--   there is none, return <a>Nothing</a>.
--   
--   Example: given the primary index below:
--   
--   <pre>
--   slot:       0   1
--           ┌───┬───┬───┐
--   offset: │ 0 │ 0 │ x │
--           └───┴───┴───┘
--   </pre>
--   
--   Return slot 1.
firstFilledSlot :: ChunkInfo -> PrimaryIndex -> Maybe RelativeSlot

-- | Return a list of all the filled (length &gt; zero) slots in the
--   primary index.
filledSlots :: ChunkInfo -> PrimaryIndex -> [RelativeSlot]

-- | Return the last filled slot in the primary index.
lastFilledSlot :: HasCallStack => ChunkInfo -> PrimaryIndex -> Maybe RelativeSlot

-- | Return the slots to backfill the primary index file with.
--   
--   A situation may arise in which we "skip" some relative slots, and we
--   write into the DB, for example, every other relative slot. In this
--   case, we need to backfill the primary index file with offsets for the
--   skipped relative slots. Similarly, before we start a new chunk, we
--   must backfill the primary index file of the current chunk to indicate
--   that the remaining slots in the chunk are empty.
--   
--   For example, say we have written to relative slots 0 and 1. We have
--   the following primary index file:
--   
--   <pre>
--   slot:       0   1
--           ┌───┬───┬───┐
--   offset: │ 0 │ x │ y │
--           └───┴───┴───┘
--   </pre>
--   
--   Now we want to write to relative slot 4, skipping 2 and 3. We first
--   have to backfill the primary index by repeating the last offset for
--   the two missing slots:
--   
--   <pre>
--   slot:       0   1   2   3
--           ┌───┬───┬───┬───┬───┐
--   offset: │ 0 │ x │ y │ y │ y │
--           └───┴───┴───┴───┴───┘
--   </pre>
--   
--   After backfilling (writing the offset <tt>y</tt> twice), we can write
--   the next offset:
--   
--   <pre>
--   slot:       0   1   2   3   4
--           ┌───┬───┬───┬───┬───┬───┐
--   offset: │ 0 │ x │ y │ y │ y │ z │
--           └───┴───┴───┴───┴───┴───┘
--   </pre>
--   
--   For the example above, the output of this function would thus be:
--   <tt>[y, y]</tt>.
--   
--   We use <tt>x, y, z</tt> in the examples above, but in practice these
--   will be multiples of the (fixed) size of an entry in secondary index.
backfill :: RelativeSlot -> RelativeSlot -> SecondaryOffset -> [SecondaryOffset]

-- | Return the slots to backfill the primary index file with when padding
--   it to the chunk size.
--   
--   See <a>backfill</a> for more details.
backfillChunk :: ChunkInfo -> ChunkNo -> NextRelativeSlot -> SecondaryOffset -> [SecondaryOffset]

-- | Smart constructor: checks that the offsets are non-decreasing, there
--   is at least one offset, and that the first offset is 0.
mk :: ChunkNo -> [SecondaryOffset] -> Maybe PrimaryIndex

-- | Return the <a>SecondaryOffset</a>s in the <a>PrimaryIndex</a>.
toSecondaryOffsets :: PrimaryIndex -> [SecondaryOffset]
instance NoThunks.Class.NoThunks Ouroboros.Consensus.Storage.ImmutableDB.Impl.Index.Primary.PrimaryIndex
instance GHC.Generics.Generic Ouroboros.Consensus.Storage.ImmutableDB.Impl.Index.Primary.PrimaryIndex
instance GHC.Show.Show Ouroboros.Consensus.Storage.ImmutableDB.Impl.Index.Primary.PrimaryIndex
instance GHC.Classes.Eq Ouroboros.Consensus.Storage.ImmutableDB.Impl.Index.Primary.PrimaryIndex

module Ouroboros.Consensus.Storage.ImmutableDB.Impl.Index.Secondary
data Entry blk
Entry :: !BlockOffset -> !HeaderOffset -> !HeaderSize -> !CRC -> !HeaderHash blk -> !BlockOrEBB -> Entry blk
[blockOffset] :: Entry blk -> !BlockOffset
[headerOffset] :: Entry blk -> !HeaderOffset
[headerSize] :: Entry blk -> !HeaderSize
[checksum] :: Entry blk -> !CRC
[headerHash] :: Entry blk -> !HeaderHash blk
[blockOrEBB] :: Entry blk -> !BlockOrEBB
entrySize :: ConvertRawHash blk => Proxy blk -> Word32
newtype BlockOffset
BlockOffset :: Word64 -> BlockOffset
[unBlockOffset] :: BlockOffset -> Word64
newtype HeaderOffset
HeaderOffset :: Word16 -> HeaderOffset
[unHeaderOffset] :: HeaderOffset -> Word16
newtype HeaderSize
HeaderSize :: Word16 -> HeaderSize
[unHeaderSize] :: HeaderSize -> Word16
data BlockSize
BlockSize :: Word32 -> BlockSize

-- | In case of the last entry, we don't have any entry and thus block
--   offset after it that we can use to calculate the size of the block.
LastEntry :: BlockSize

-- | Read the entry at the given <a>SecondaryOffset</a>. Interpret it as an
--   EBB depending on the given <a>IsEBB</a>.
readEntry :: forall m blk h. (HasCallStack, ConvertRawHash blk, MonadThrow m) => HasFS m h -> ChunkNo -> IsEBB -> SecondaryOffset -> m (Entry blk, BlockSize)

-- | Same as <a>readEntry</a>, but for multiple entries.
--   
--   NOTE: only use this for a few entries, as we will seek
--   (<tt>pread</tt>) for each entry. Use <a>readAllEntries</a> if you want
--   to read all entries in the secondary index file.
readEntries :: forall m blk h t. (HasCallStack, ConvertRawHash blk, MonadThrow m, Traversable t) => HasFS m h -> ChunkNo -> t (IsEBB, SecondaryOffset) -> m (t (Entry blk, BlockSize))

-- | Read all entries in a secondary index file, starting from the given
--   <a>SecondaryOffset</a> until the stop condition is true or until the
--   end of the file is reached. The entry for which the stop condition is
--   true will be the last in the returned list of entries.
readAllEntries :: forall m blk h. (HasCallStack, ConvertRawHash blk, MonadThrow m) => HasFS m h -> SecondaryOffset -> ChunkNo -> (Entry blk -> Bool) -> Word64 -> IsEBB -> m [WithBlockSize (Entry blk)]
appendEntry :: forall m blk h. (HasCallStack, ConvertRawHash blk, MonadThrow m) => HasFS m h -> Handle h -> Entry blk -> m Word64

-- | Remove all entries after the entry at the given
--   <a>SecondaryOffset</a>. That entry will now be the last entry in the
--   secondary index file.
truncateToEntry :: forall m blk h. (HasCallStack, ConvertRawHash blk, MonadThrow m) => Proxy blk -> HasFS m h -> ChunkNo -> SecondaryOffset -> m ()
writeAllEntries :: forall m blk h. (HasCallStack, ConvertRawHash blk, MonadThrow m) => HasFS m h -> ChunkNo -> [Entry blk] -> m ()
instance NoThunks.Class.NoThunks Ouroboros.Consensus.Storage.ImmutableDB.Impl.Index.Secondary.BlockOffset
instance Foreign.Storable.Storable Ouroboros.Consensus.Storage.ImmutableDB.Impl.Index.Secondary.BlockOffset
instance GHC.Num.Num Ouroboros.Consensus.Storage.ImmutableDB.Impl.Index.Secondary.BlockOffset
instance GHC.Real.Integral Ouroboros.Consensus.Storage.ImmutableDB.Impl.Index.Secondary.BlockOffset
instance GHC.Real.Real Ouroboros.Consensus.Storage.ImmutableDB.Impl.Index.Secondary.BlockOffset
instance GHC.Enum.Enum Ouroboros.Consensus.Storage.ImmutableDB.Impl.Index.Secondary.BlockOffset
instance GHC.Classes.Ord Ouroboros.Consensus.Storage.ImmutableDB.Impl.Index.Secondary.BlockOffset
instance GHC.Classes.Eq Ouroboros.Consensus.Storage.ImmutableDB.Impl.Index.Secondary.BlockOffset
instance GHC.Show.Show Ouroboros.Consensus.Storage.ImmutableDB.Impl.Index.Secondary.BlockOffset
instance NoThunks.Class.NoThunks Ouroboros.Consensus.Storage.ImmutableDB.Impl.Index.Secondary.HeaderOffset
instance Foreign.Storable.Storable Ouroboros.Consensus.Storage.ImmutableDB.Impl.Index.Secondary.HeaderOffset
instance GHC.Classes.Eq Ouroboros.Consensus.Storage.ImmutableDB.Impl.Index.Secondary.HeaderOffset
instance GHC.Show.Show Ouroboros.Consensus.Storage.ImmutableDB.Impl.Index.Secondary.HeaderOffset
instance NoThunks.Class.NoThunks Ouroboros.Consensus.Storage.ImmutableDB.Impl.Index.Secondary.HeaderSize
instance Foreign.Storable.Storable Ouroboros.Consensus.Storage.ImmutableDB.Impl.Index.Secondary.HeaderSize
instance GHC.Classes.Eq Ouroboros.Consensus.Storage.ImmutableDB.Impl.Index.Secondary.HeaderSize
instance GHC.Show.Show Ouroboros.Consensus.Storage.ImmutableDB.Impl.Index.Secondary.HeaderSize
instance GHC.Generics.Generic (Ouroboros.Consensus.Storage.ImmutableDB.Impl.Index.Secondary.Entry blk)
instance NoThunks.Class.NoThunks Ouroboros.Consensus.Storage.ImmutableDB.Impl.Index.Secondary.BlockSize
instance GHC.Generics.Generic Ouroboros.Consensus.Storage.ImmutableDB.Impl.Index.Secondary.BlockSize
instance GHC.Show.Show Ouroboros.Consensus.Storage.ImmutableDB.Impl.Index.Secondary.BlockSize
instance GHC.Classes.Eq Ouroboros.Consensus.Storage.ImmutableDB.Impl.Index.Secondary.BlockSize
instance Ouroboros.Network.Block.StandardHash blk => GHC.Classes.Eq (Ouroboros.Consensus.Storage.ImmutableDB.Impl.Index.Secondary.Entry blk)
instance Ouroboros.Network.Block.StandardHash blk => GHC.Show.Show (Ouroboros.Consensus.Storage.ImmutableDB.Impl.Index.Secondary.Entry blk)
instance Ouroboros.Network.Block.StandardHash blk => NoThunks.Class.NoThunks (Ouroboros.Consensus.Storage.ImmutableDB.Impl.Index.Secondary.Entry blk)
instance Data.Binary.Class.Binary Ouroboros.Consensus.Storage.ImmutableDB.Impl.Index.Secondary.HeaderSize
instance Data.Binary.Class.Binary Ouroboros.Consensus.Storage.ImmutableDB.Impl.Index.Secondary.HeaderOffset
instance Data.Binary.Class.Binary Ouroboros.Consensus.Storage.ImmutableDB.Impl.Index.Secondary.BlockOffset

module Ouroboros.Consensus.Storage.ImmutableDB.Impl.Parser

-- | Parse the contents of a chunk file.
--   
--   <ul>
--   <li>The parser decodes each block in the chunk. When one of them fails
--   to decode, a <a>ChunkErrRead</a> error is returned.</li>
--   <li>Each block's checksum is checked against its given expected
--   checksum (coming from the secondary index). When a checksum doesn't
--   match, a <a>ChunkErrCorrupt</a> error is returned. When the secondary
--   index is missing or corrupt, and there are no or fewer expected
--   checksums, we use the given (more expensive) integrity checking
--   function instead of checksum comparison.</li>
--   <li>We check that each block fits onto the previous one by checking
--   the hashes. If not, we return a <a>ChunkErrHashMismatch</a>
--   error.</li>
--   <li>An error is returned in the form of:</li>
--   </ul>
--   
--   <pre>
--   'Maybe' ('ChunkFileError' blk, 'Word64')
--   </pre>
--   
--   The <a>Word64</a> corresponds to the offset in the file where the last
--   valid entry ends. Truncating to this offset will remove all invalid
--   data from the file and just leave the valid entries before it. Note
--   that we are not using <a>Either</a> because the error might occur
--   after some valid entries have been parsed successfully, in which case
--   we still want these valid entries, but also want to know about the
--   error so we can truncate the file to get rid of the unparseable data.
parseChunkFile :: forall m blk h r. (IOLike m, GetPrevHash blk, HasBinaryBlockInfo blk, DecodeDisk blk (ByteString -> blk)) => CodecConfig blk -> HasFS m h -> (blk -> Bool) -> FsPath -> [CRC] -> (Stream (Of (BlockSummary blk, ChainHash blk)) m (Maybe (ChunkFileError blk, Word64)) -> m r) -> m r

-- | Defined here instead of in the <tt>Parser</tt> module because
--   <a>TraceEvent</a> depends on it.
data ChunkFileError blk

-- | A block could not be decoded
ChunkErrRead :: ReadIncrementalErr -> ChunkFileError blk

-- | The previous hash of a block did not match the hash of the previous
--   block.
ChunkErrHashMismatch :: HeaderHash blk -> ChainHash blk -> ChunkFileError blk

-- | The integrity verification of the block with the given point returned
--   <a>False</a>, indicating that the block got corrupted.
ChunkErrCorrupt :: Point blk -> ChunkFileError blk

-- | Information about a block returned by the parser.
--   
--   The fields of this record are strict to make sure that by evaluating
--   this record to WHNF, we no longer hold on to the entire block.
--   Otherwise, we might accidentally keep all blocks in a single file in
--   memory during parsing.
data BlockSummary blk
BlockSummary :: !Entry blk -> !BlockNo -> !SlotNo -> BlockSummary blk
[summaryEntry] :: BlockSummary blk -> !Entry blk
[summaryBlockNo] :: BlockSummary blk -> !BlockNo
[summarySlotNo] :: BlockSummary blk -> !SlotNo

module Ouroboros.Consensus.Storage.ImmutableDB.Impl.Index.Cache

-- | Environment used by functions operating on the cached index.
data CacheEnv m blk h

-- | Creates a new <a>CacheEnv</a> and launches a background thread that
--   expires unused past chunks (<a>expireUnusedChunks</a>).
--   
--   PRECONDITION: <a>$sel:pastChunksToCache:CacheConfig</a> (in
--   <a>CacheConfig</a>) &gt; 0
newEnv :: (HasCallStack, IOLike m, ConvertRawHash blk, StandardHash blk) => HasFS m h -> ResourceRegistry m -> Tracer m TraceCacheEvent -> CacheConfig -> ChunkInfo -> ChunkNo -> m (CacheEnv m blk h)
data CacheConfig
CacheConfig :: Word32 -> DiffTime -> CacheConfig

-- | Maximum number of past chunks to cache, excluding the current chunk.
--   
--   NOTE: must be &gt; 0
[$sel:pastChunksToCache:CacheConfig] :: CacheConfig -> Word32

-- | Expire past chunks that haven't been used for
--   <a>$sel:expireUnusedAfter:CacheConfig</a> from the cache, regardless
--   the number of past chunks in the cache.
[$sel:expireUnusedAfter:CacheConfig] :: CacheConfig -> DiffTime
checkInvariants :: Word32 -> Cached blk -> Maybe String

-- | Intended to run as a background thread.
--   
--   Will expire past chunks that haven't been used for
--   <a>$sel:expireUnusedAfter:CacheConfig</a> from the cache.
expireUnusedChunks :: (HasCallStack, IOLike m) => CacheEnv m blk h -> m Void

-- | Stops the background expiration thread.
--   
--   This operation is idempotent.
close :: IOLike m => CacheEnv m blk h -> m ()

-- | Restarts the background expiration thread, drops all previously cached
--   information, loads the given chunk.
--   
--   PRECONDITION: the background thread expiring unused past chunks must
--   have been terminated.
restart :: (ConvertRawHash blk, IOLike m) => CacheEnv m blk h -> ChunkNo -> m ()
readOffsets :: (HasCallStack, ConvertRawHash blk, Traversable t, IOLike m) => CacheEnv m blk h -> ChunkNo -> t RelativeSlot -> m (t (Maybe SecondaryOffset))
readFirstFilledSlot :: (HasCallStack, ConvertRawHash blk, IOLike m) => CacheEnv m blk h -> ChunkNo -> m (Maybe RelativeSlot)

-- | This is called when a new chunk is started, which means we need to
--   update <a>Cached</a> to reflect this.
openPrimaryIndex :: (HasCallStack, ConvertRawHash blk, IOLike m) => CacheEnv m blk h -> ChunkNo -> AllowExisting -> m (Handle h)
appendOffsets :: (HasCallStack, Foldable f, IOLike m) => CacheEnv m blk h -> Handle h -> f SecondaryOffset -> m ()
readEntries :: forall m blk h t. (HasCallStack, ConvertRawHash blk, Traversable t, IOLike m) => CacheEnv m blk h -> ChunkNo -> t (IsEBB, SecondaryOffset) -> m (t (Entry blk, BlockSize))
readAllEntries :: forall m blk h. (HasCallStack, ConvertRawHash blk, IOLike m) => CacheEnv m blk h -> SecondaryOffset -> ChunkNo -> (Entry blk -> Bool) -> Word64 -> IsEBB -> m [WithBlockSize (Entry blk)]
appendEntry :: forall m blk h. (HasCallStack, ConvertRawHash blk, IOLike m) => CacheEnv m blk h -> ChunkNo -> Handle h -> Entry blk -> m Word64
instance GHC.Show.Show Ouroboros.Consensus.Storage.ImmutableDB.Impl.Index.Cache.CacheConfig
instance GHC.Classes.Eq Ouroboros.Consensus.Storage.ImmutableDB.Impl.Index.Cache.CacheConfig
instance Ouroboros.Network.Block.StandardHash blk => NoThunks.Class.NoThunks (Ouroboros.Consensus.Storage.ImmutableDB.Impl.Index.Cache.CurrentChunkInfo blk)
instance GHC.Generics.Generic (Ouroboros.Consensus.Storage.ImmutableDB.Impl.Index.Cache.CurrentChunkInfo blk)
instance Ouroboros.Network.Block.StandardHash blk => GHC.Show.Show (Ouroboros.Consensus.Storage.ImmutableDB.Impl.Index.Cache.CurrentChunkInfo blk)
instance Ouroboros.Network.Block.StandardHash blk => NoThunks.Class.NoThunks (Ouroboros.Consensus.Storage.ImmutableDB.Impl.Index.Cache.PastChunkInfo blk)
instance GHC.Generics.Generic (Ouroboros.Consensus.Storage.ImmutableDB.Impl.Index.Cache.PastChunkInfo blk)
instance NoThunks.Class.NoThunks Ouroboros.Consensus.Storage.ImmutableDB.Impl.Index.Cache.LastUsed
instance GHC.Show.Show Ouroboros.Consensus.Storage.ImmutableDB.Impl.Index.Cache.LastUsed
instance GHC.Classes.Ord Ouroboros.Consensus.Storage.ImmutableDB.Impl.Index.Cache.LastUsed
instance GHC.Classes.Eq Ouroboros.Consensus.Storage.ImmutableDB.Impl.Index.Cache.LastUsed
instance Ouroboros.Network.Block.StandardHash blk => NoThunks.Class.NoThunks (Ouroboros.Consensus.Storage.ImmutableDB.Impl.Index.Cache.Cached blk)
instance GHC.Generics.Generic (Ouroboros.Consensus.Storage.ImmutableDB.Impl.Index.Cache.Cached blk)

module Ouroboros.Consensus.Storage.ImmutableDB.Impl.Index

-- | Bundle the operations on the primary and secondary index that touch
--   the files. This allows us to easily introduce an intermediary caching
--   layer.
data Index m blk h
Index :: (forall t. (HasCallStack, Traversable t) => ChunkNo -> t RelativeSlot -> m (t (Maybe SecondaryOffset))) -> (HasCallStack => ChunkNo -> m (Maybe RelativeSlot)) -> (HasCallStack => ChunkNo -> AllowExisting -> m (Handle h)) -> (forall f. (HasCallStack, Foldable f) => Handle h -> f SecondaryOffset -> m ()) -> (forall t. (HasCallStack, Traversable t) => ChunkNo -> t (IsEBB, SecondaryOffset) -> m (t (Entry blk, BlockSize))) -> (HasCallStack => SecondaryOffset -> ChunkNo -> (Entry blk -> Bool) -> Word64 -> IsEBB -> m [WithBlockSize (Entry blk)]) -> (HasCallStack => ChunkNo -> Handle h -> WithBlockSize (Entry blk) -> m Word64) -> (HasCallStack => m ()) -> (HasCallStack => ChunkNo -> m ()) -> Index m blk h

-- | See <a>readOffsets</a>
[readOffsets] :: Index m blk h -> forall t. (HasCallStack, Traversable t) => ChunkNo -> t RelativeSlot -> m (t (Maybe SecondaryOffset))

-- | See <a>readFirstFilledSlot</a>
[readFirstFilledSlot] :: Index m blk h -> HasCallStack => ChunkNo -> m (Maybe RelativeSlot)

-- | See <a>open</a>
[openPrimaryIndex] :: Index m blk h -> HasCallStack => ChunkNo -> AllowExisting -> m (Handle h)

-- | See <a>appendOffsets</a>
[appendOffsets] :: Index m blk h -> forall f. (HasCallStack, Foldable f) => Handle h -> f SecondaryOffset -> m ()

-- | See <a>readEntries</a>
[readEntries] :: Index m blk h -> forall t. (HasCallStack, Traversable t) => ChunkNo -> t (IsEBB, SecondaryOffset) -> m (t (Entry blk, BlockSize))

-- | See <a>readAllEntries</a>
[readAllEntries] :: Index m blk h -> HasCallStack => SecondaryOffset -> ChunkNo -> (Entry blk -> Bool) -> Word64 -> IsEBB -> m [WithBlockSize (Entry blk)]

-- | See <a>appendEntry</a>
[appendEntry] :: Index m blk h -> HasCallStack => ChunkNo -> Handle h -> WithBlockSize (Entry blk) -> m Word64

-- | Close the index and stop any background threads.
--   
--   Should be called when the ImmutableDB is closed.
[close] :: Index m blk h -> HasCallStack => m ()

-- | Restart a closed index using the given chunk as the current chunk,
--   drop all previously cached information.
--   
--   NOTE: this will only used in the testsuite, when we need to truncate.
[restart] :: Index m blk h -> HasCallStack => ChunkNo -> m ()

-- | See <a>readOffset</a>.
readOffset :: Functor m => Index m blk h -> ChunkNo -> RelativeSlot -> m (Maybe SecondaryOffset)

-- | See <a>readEntry</a>.
readEntry :: Functor m => Index m blk h -> ChunkNo -> IsEBB -> SecondaryOffset -> m (Entry blk, BlockSize)
fileBackedIndex :: forall m blk h. (ConvertRawHash blk, MonadCatch m) => HasFS m h -> ChunkInfo -> Index m blk h

-- | Caches the current chunk's indices as well as a number of past chunk's
--   indices.
--   
--   Spawns a background thread to expire past chunks from the cache that
--   haven't been used for a while.
cachedIndex :: forall m blk h. (IOLike m, ConvertRawHash blk, StandardHash blk) => HasFS m h -> ResourceRegistry m -> Tracer m TraceCacheEvent -> CacheConfig -> ChunkInfo -> ChunkNo -> m (Index m blk h)
data CacheConfig
CacheConfig :: Word32 -> DiffTime -> CacheConfig

-- | Maximum number of past chunks to cache, excluding the current chunk.
--   
--   NOTE: must be &gt; 0
[$sel:pastChunksToCache:CacheConfig] :: CacheConfig -> Word32

-- | Expire past chunks that haven't been used for
--   <a>$sel:expireUnusedAfter:CacheConfig</a> from the cache, regardless
--   the number of past chunks in the cache.
[$sel:expireUnusedAfter:CacheConfig] :: CacheConfig -> DiffTime
instance NoThunks.Class.NoThunks (Ouroboros.Consensus.Storage.ImmutableDB.Impl.Index.Index m blk h)

module Ouroboros.Consensus.Storage.ImmutableDB.Impl.State

-- | The environment used by the immutable database.
data ImmutableDBEnv m blk
ImmutableDBEnv :: !HasFS m h -> !StrictMVar m (InternalState m blk h) -> !blk -> Bool -> !ChunkInfo -> !Tracer m (TraceEvent blk) -> !ResourceRegistry m -> !CacheConfig -> !CodecConfig blk -> ImmutableDBEnv m blk
[hasFS] :: ImmutableDBEnv m blk -> !HasFS m h
[varInternalState] :: ImmutableDBEnv m blk -> !StrictMVar m (InternalState m blk h)
[checkIntegrity] :: ImmutableDBEnv m blk -> !blk -> Bool
[chunkInfo] :: ImmutableDBEnv m blk -> !ChunkInfo
[tracer] :: ImmutableDBEnv m blk -> !Tracer m (TraceEvent blk)
[registry] :: ImmutableDBEnv m blk -> !ResourceRegistry m
[cacheConfig] :: ImmutableDBEnv m blk -> !CacheConfig
[codecConfig] :: ImmutableDBEnv m blk -> !CodecConfig blk
data InternalState m blk h
DbClosed :: InternalState m blk h
DbOpen :: !OpenState m blk h -> InternalState m blk h
dbIsOpen :: InternalState m blk h -> Bool

-- | Internal state when the database is open.
data OpenState m blk h
OpenState :: !ChunkNo -> !BlockOffset -> !SecondaryOffset -> !Handle h -> !Handle h -> !Handle h -> !WithOrigin (Tip blk) -> !Index m blk h -> OpenState m blk h

-- | The current <a>ChunkNo</a> the immutable store is writing to.
[currentChunk] :: OpenState m blk h -> !ChunkNo

-- | The offset at which the next block will be written in the current
--   chunk file.
[currentChunkOffset] :: OpenState m blk h -> !BlockOffset

-- | The offset at which the next index entry will be written in the
--   current secondary index.
[currentSecondaryOffset] :: OpenState m blk h -> !SecondaryOffset

-- | The write handle for the current chunk file.
[currentChunkHandle] :: OpenState m blk h -> !Handle h

-- | The write handle for the current primary index file.
[currentPrimaryHandle] :: OpenState m blk h -> !Handle h

-- | The write handle for the current secondary index file.
[currentSecondaryHandle] :: OpenState m blk h -> !Handle h

-- | The current tip of the database.
[currentTip] :: OpenState m blk h -> !WithOrigin (Tip blk)

-- | An abstraction layer on top of the indices to allow for caching.
[currentIndex] :: OpenState m blk h -> !Index m blk h

-- | Create the internal open state for the given chunk.
mkOpenState :: forall m blk h. (HasCallStack, IOLike m, Eq h) => HasFS m h -> Index m blk h -> ChunkNo -> WithOrigin (Tip blk) -> AllowExisting -> WithTempRegistry (OpenState m blk h) m (OpenState m blk h)

-- | Get the <a>OpenState</a> of the given database, throw a
--   <a>ClosedDBError</a> in case it is closed.
--   
--   NOTE: Since the <a>OpenState</a> is parameterized over a type
--   parameter <tt>h</tt> of handles, which is not visible from the type of
--   the <tt>ImmutableDBEnv</tt>, we return a <tt>SomePair</tt> here that
--   returns the open state along with a <a>HasFS</a> instance for the
--   <i>same</i> type parameter <tt>h</tt>. Note that it would be
--   impossible to use an existing <a>HasFS</a> instance already in scope
--   otherwise, since the <tt>h</tt> parameters would not be known to
--   match.
getOpenState :: (HasCallStack, IOLike m) => ImmutableDBEnv m blk -> STM m (SomePair (HasFS m) (OpenState m blk))

-- | Shorthand
type ModifyOpenState m blk h = StateT (OpenState m blk h) (WithTempRegistry (OpenState m blk h) m)

-- | Modify the internal state of an open database.
--   
--   In case the database is closed, a <a>ClosedDBError</a> is thrown.
--   
--   In case an <a>UnexpectedFailure</a> is thrown, the database is closed
--   to prevent further appending to a database in a potentially
--   inconsistent state.
--   
--   The action is run in the <a>ModifyOpenState</a> monad, which is a
--   <a>StateT</a> transformer (of the <a>OpenState</a>) over the
--   <a>WithTempRegistry</a> monad. This monad can be used to allocate
--   resources in that will be transferred to the returned <a>OpenState</a>
--   that is safely stored in the <a>ImmutableDBEnv</a>. This approach
--   makes sure that no resources are leaked when an exception is thrown
--   while running the action modifying the state.
--   
--   <b>Note</b>: This <i>takes</i> the <tt>TMVar</tt>, <i>then</i> runs
--   the action (which might be in <a>IO</a>), and then puts the
--   <tt>TMVar</tt> back, just like <a>modifyMVar</a> does. Consequently,
--   it has the same gotchas that <tt>modifyMVar</tt> does; the effects are
--   observable and it is susceptible to deadlock.
modifyOpenState :: forall m blk a. (HasCallStack, IOLike m) => ImmutableDBEnv m blk -> (forall h. Eq h => HasFS m h -> ModifyOpenState m blk h a) -> m a

-- | Perform an action that accesses the internal state of an open
--   database.
--   
--   In case the database is closed, a <a>ClosedDBError</a> is thrown.
--   
--   In case an <a>UnexpectedFailure</a> is thrown while the action is
--   being run, the database is closed to prevent further appending to a
--   database in a potentially inconsistent state.
withOpenState :: forall m blk r. (HasCallStack, IOLike m) => ImmutableDBEnv m blk -> (forall h. HasFS m h -> OpenState m blk h -> m r) -> m r

-- | Close the handles in the <a>OpenState</a>.
--   
--   Idempotent, as closing a handle is idempotent.
closeOpenHandles :: Monad m => HasFS m h -> OpenState m blk h -> m ()

-- | Clean up the <a>OpenState</a>: <a>closeOpenHandles</a> + close the
--   index (i.e., shut down its background thread)
cleanUp :: Monad m => HasFS m h -> OpenState m blk h -> m ()
instance Ouroboros.Network.Block.StandardHash blk => NoThunks.Class.NoThunks (Ouroboros.Consensus.Storage.ImmutableDB.Impl.State.OpenState m blk h)
instance GHC.Generics.Generic (Ouroboros.Consensus.Storage.ImmutableDB.Impl.State.OpenState m blk h)
instance Ouroboros.Network.Block.StandardHash blk => NoThunks.Class.NoThunks (Ouroboros.Consensus.Storage.ImmutableDB.Impl.State.InternalState m blk h)
instance GHC.Generics.Generic (Ouroboros.Consensus.Storage.ImmutableDB.Impl.State.InternalState m blk h)

module Ouroboros.Consensus.Storage.ImmutableDB.Impl.Validation

-- | Perform validation as per the <a>ValidationPolicy</a> using
--   <a>validate</a> and create an <a>OpenState</a> corresponding to its
--   outcome using <a>mkOpenState</a>.
validateAndReopen :: forall m blk h. (IOLike m, GetPrevHash blk, HasBinaryBlockInfo blk, DecodeDisk blk (ByteString -> blk), ConvertRawHash blk, Eq h, HasCallStack) => ValidateEnv m blk h -> ResourceRegistry m -> ValidationPolicy -> WithTempRegistry (OpenState m blk h) m (OpenState m blk h)

-- | Bundle of arguments used most validation functions.
--   
--   Note that we don't use
--   <a>Ouroboros.Consensus.Storage.ImmutableDB.Impl.Index</a> because we
--   are reading and manipulating index files in different ways, e.g.,
--   truncating them.
data ValidateEnv m blk h
ValidateEnv :: !HasFS m h -> !ChunkInfo -> !Tracer m (TraceEvent blk) -> !CacheConfig -> !CodecConfig blk -> !blk -> Bool -> ValidateEnv m blk h
[hasFS] :: ValidateEnv m blk h -> !HasFS m h
[chunkInfo] :: ValidateEnv m blk h -> !ChunkInfo
[tracer] :: ValidateEnv m blk h -> !Tracer m (TraceEvent blk)
[cacheConfig] :: ValidateEnv m blk h -> !CacheConfig
[codecConfig] :: ValidateEnv m blk h -> !CodecConfig blk
[checkIntegrity] :: ValidateEnv m blk h -> !blk -> Bool

-- | Reconstruct a <a>PrimaryIndex</a> based on a list of <a>Entry</a>s.
reconstructPrimaryIndex :: forall blk. (ConvertRawHash blk, HasCallStack) => Proxy blk -> ChunkInfo -> ShouldBeFinalised -> ChunkNo -> [BlockOrEBB] -> PrimaryIndex

-- | Iff the chunk is the most recent chunk, it should not be finalised.
--   
--   With finalising, we mean: if there are one or more empty slots at the
--   end of the chunk, the primary index should be padded with offsets to
--   indicate that these slots are empty. See <a>backfill</a>.
data ShouldBeFinalised
ShouldBeFinalised :: ShouldBeFinalised
ShouldNotBeFinalised :: ShouldBeFinalised
instance GHC.Show.Show Ouroboros.Consensus.Storage.ImmutableDB.Impl.Validation.ShouldBeFinalised

module Ouroboros.Consensus.Storage.ImmutableDB.Impl.Iterator
streamImpl :: forall m blk b. (IOLike m, HasHeader blk, DecodeDisk blk (ByteString -> blk), DecodeDiskDep (NestedCtxt Header) blk, ReconstructNestedCtxt Header blk, HasCallStack) => ImmutableDBEnv m blk -> ResourceRegistry m -> BlockComponent blk b -> StreamFrom blk -> StreamTo blk -> m (Either (MissingBlock blk) (Iterator m blk b))

-- | Get information about the block or EBB at the given slot with the
--   given hash. If no such block exists, because the slot is empty, it
--   contains a block and/or EBB with a different hash, or it is newer than
--   the current tip, return a <a>MissingBlock</a>.
--   
--   Return the <a>ChunkSlot</a> corresponding to the block or EBB, the
--   corresponding entry (and <a>BlockSize</a>) from the secondary index
--   file, and the <a>SecondaryOffset</a> of that entry.
--   
--   The primary index is read to find out whether the slot is filled and
--   what the <a>SecondaryOffset</a> is for the slot. The secondary index
--   is read to check the hash and to return the <a>Entry</a>.
getSlotInfo :: forall m blk h. (HasCallStack, IOLike m, HasHeader blk) => ChunkInfo -> Index m blk h -> WithOrigin (Tip blk) -> RealPoint blk -> ExceptT (MissingBlock blk) m (ChunkSlot, (Entry blk, BlockSize), SecondaryOffset)

-- | Auxiliary data type that combines the <a>currentChunk</a> and
--   <a>currentChunkOffset</a> fields from <a>OpenState</a>. This is used
--   to avoid passing the whole state around, and moreover, it avoids
--   issues with existential <tt>h</tt> type parameter.
data CurrentChunkInfo
CurrentChunkInfo :: !ChunkNo -> !BlockOffset -> CurrentChunkInfo
extractBlockComponent :: forall m blk b h. (HasHeader blk, ReconstructNestedCtxt Header blk, DecodeDisk blk (ByteString -> blk), DecodeDiskDep (NestedCtxt Header) blk, IOLike m) => HasFS m h -> ChunkInfo -> ChunkNo -> CodecConfig blk -> (blk -> Bool) -> Handle h -> WithBlockSize (Entry blk) -> BlockComponent blk b -> m b
instance GHC.Generics.Generic (Ouroboros.Consensus.Storage.ImmutableDB.Impl.Iterator.IteratorState m blk h)
instance (Ouroboros.Network.Block.StandardHash hash, Ouroboros.Consensus.Util.IOLike.IOLike m) => NoThunks.Class.NoThunks (Ouroboros.Consensus.Storage.ImmutableDB.Impl.Iterator.IteratorStateOrExhausted m hash h)
instance GHC.Generics.Generic (Ouroboros.Consensus.Storage.ImmutableDB.Impl.Iterator.IteratorStateOrExhausted m hash h)
instance (Ouroboros.Network.Block.StandardHash blk, Ouroboros.Consensus.Util.IOLike.IOLike m) => NoThunks.Class.NoThunks (Ouroboros.Consensus.Storage.ImmutableDB.Impl.Iterator.IteratorState m blk h)


-- | Immutable on-disk database of binary blobs
--   
--   <h1>Internal format</h1>
--   
--   The API of the ImmutableDB uses <a>SlotNo</a> to indicate a location
--   in the chain/immutable database. To distinguish EBBs from regular
--   blocks, the hash is used (together they form a <a>RealPoint</a>). The
--   contents of the database are not stored in one big file that is
--   appended to in eternity, but a separate file is created for each
--   <a>ChunkNo</a>.
--   
--   Within each <a>ChunkNo</a>, the entries are numbered by
--   <a>RelativeSlot</a>s. Each <a>SlotNo</a> can be converted to a
--   combination of an <a>ChunkNo</a> and a <a>RelativeSlot</a> (=
--   <a>ChunkSlot</a>) and vice versa. This conversion depends on the size
--   of the chunks: <a>ChunkSize</a>. This size may not be the same for
--   each chunk. When opening the database, the user must give a
--   <a>ChunkInfo</a> that will be used to find out the size of each chunk.
--   
--   For example:
--   
--   <pre>
--   Chunks:         &lt;──────── 0 ────────&gt; &lt;────── 1 ──────&gt;
--   chunk size:               4                   3
--                   ┌───┬───┬───┬───┬───┐ ┌───┬───┬───┬───┐
--                   │   │   │   │   │   │ │   │   │   │   │
--                   └───┴───┴───┴───┴───┘ └───┴───┴───┴───┘
--   'RelativeSlot':   0   1   2   3   4     0   1   2   3
--   'SlotNo':        EBB  0   1   2   3    EBB  4   5   6
--   </pre>
--   
--   Not all chunks can contain EBBs; see <a>ChunkInfo</a> for details.
--   
--   <h1>Errors</h1>
--   
--   Whenever an <a>UnexpectedFailure</a> is thrown during an operation,
--   e.g., <a>appendBlock</a>, the database will be automatically closed
--   because we can not guarantee a consistent state in the face of file
--   system errors.
--   
--   <h1>Opening the database</h1>
--   
--   The database can be closed and opened again. In case the database was
--   closed because of an unexpected error. When the database is opened
--   again, invalid data will be truncated from the database until a valid
--   prefix is recovered.
--   
--   <h1>Concurrency</h1>
--   
--   The same database should not be opened multiple times concurrently.
--   This is ensured by the file lock of the ChainDB.
--   
--   The database can have multiple readers, but should only have one
--   writer.
--   
--   <h1>Layout on disk</h1>
--   
--   The database is structured on disk as follows:
--   
--   <pre>
--   /
--     00000.chunk
--     00000.primary
--     00000.secondary
--     ..
--     00008.chunk
--     00008.primary
--     00008.secondary
--   </pre>
--   
--   For each chunk, there are three files on disk:
--   
--   <ul>
--   <li>A "chunk file" that stores the actual blocks. But nothing more, so
--   nothing is stored for empty slots.</li>
--   <li>A "secondary index file" that stores information about each block:
--   its hash, the slot number or epoch number in case of an EBB, a
--   checksum of the block, the offset of the block in the chunk file, and
--   more. This index is sparse to save space.</li>
--   <li>A "primary index file" that maps slots to offsets in the secondary
--   index file.</li>
--   </ul>
module Ouroboros.Consensus.Storage.ImmutableDB.Impl
openDB :: forall m blk. (IOLike m, GetPrevHash blk, ConvertRawHash blk, ImmutableDbSerialiseConstraints blk, HasCallStack) => ImmutableDbArgs Identity m blk -> m (ImmutableDB m blk)
data ImmutableDbArgs f m blk
ImmutableDbArgs :: CacheConfig -> HKD f (blk -> Bool) -> HKD f ChunkInfo -> HKD f (CodecConfig blk) -> SomeHasFS m -> HKD f (ResourceRegistry m) -> Tracer m (TraceEvent blk) -> ValidationPolicy -> ImmutableDbArgs f m blk
[immCacheConfig] :: ImmutableDbArgs f m blk -> CacheConfig
[immCheckIntegrity] :: ImmutableDbArgs f m blk -> HKD f (blk -> Bool)
[immChunkInfo] :: ImmutableDbArgs f m blk -> HKD f ChunkInfo
[immCodecConfig] :: ImmutableDbArgs f m blk -> HKD f (CodecConfig blk)
[immHasFS] :: ImmutableDbArgs f m blk -> SomeHasFS m
[immRegistry] :: ImmutableDbArgs f m blk -> HKD f (ResourceRegistry m)
[immTracer] :: ImmutableDbArgs f m blk -> Tracer m (TraceEvent blk)
[immValidationPolicy] :: ImmutableDbArgs f m blk -> ValidationPolicy

-- | Default arguments when using the <a>IO</a> monad
defaultArgs :: FilePath -> ImmutableDbArgs Defaults IO blk

-- | <a>EncodeDisk</a> and <a>DecodeDisk</a> constraints needed for the
--   ImmutableDB.
type ImmutableDbSerialiseConstraints blk = (EncodeDisk blk blk, DecodeDisk blk (ByteString -> blk), DecodeDiskDep (NestedCtxt Header) blk, ReconstructNestedCtxt Header blk, HasBinaryBlockInfo blk)

-- | The validation policy used when opening an <a>ImmutableDB</a>.
--   
--   The validation policy is used by <a>openDB</a>: the initial opening of
--   the database, either an empty database or a database that was
--   previously closed.
--   
--   The recovery policy dictates which on-disk files should be validated.
data ValidationPolicy

-- | The chunk and index files of the most recent chunk stored on disk will
--   be validated.
--   
--   Prior chunk and index files are ignored, even their presence will not
--   be checked.
--   
--   A <tt>MissingFileError</tt> or an <tt>InvalidFileError</tt> will be
--   thrown in case of a missing or invalid chunk file, or an invalid index
--   file.
--   
--   Because not all files are validated, subsequent operations on the
--   database after opening may result in unexpected errors.
ValidateMostRecentChunk :: ValidationPolicy

-- | The chunk and index files of all chunks starting from the first one up
--   to the last chunk stored on disk will be validated.
--   
--   A <tt>MissingFileError</tt> or an <tt>InvalidFileError</tt> will be
--   thrown in case of a missing or invalid chunk file, or an invalid index
--   file.
ValidateAllChunks :: ValidationPolicy

-- | Defined here instead of in the <tt>Parser</tt> module because
--   <a>TraceEvent</a> depends on it.
data ChunkFileError blk

-- | A block could not be decoded
ChunkErrRead :: ReadIncrementalErr -> ChunkFileError blk

-- | The previous hash of a block did not match the hash of the previous
--   block.
ChunkErrHashMismatch :: HeaderHash blk -> ChainHash blk -> ChunkFileError blk

-- | The integrity verification of the block with the given point returned
--   <a>False</a>, indicating that the block got corrupted.
ChunkErrCorrupt :: Point blk -> ChunkFileError blk
data TraceEvent blk
NoValidLastLocation :: TraceEvent blk
ValidatedLastLocation :: ChunkNo -> Tip blk -> TraceEvent blk
ValidatingChunk :: ChunkNo -> TraceEvent blk
MissingChunkFile :: ChunkNo -> TraceEvent blk
InvalidChunkFile :: ChunkNo -> ChunkFileError blk -> TraceEvent blk

-- | The hash of the last block in the previous epoch doesn't match the
--   previous hash of the first block in the current epoch
ChunkFileDoesntFit :: ChainHash blk -> ChainHash blk -> TraceEvent blk
MissingPrimaryIndex :: ChunkNo -> TraceEvent blk
MissingSecondaryIndex :: ChunkNo -> TraceEvent blk
InvalidPrimaryIndex :: ChunkNo -> TraceEvent blk
InvalidSecondaryIndex :: ChunkNo -> TraceEvent blk
RewritePrimaryIndex :: ChunkNo -> TraceEvent blk
RewriteSecondaryIndex :: ChunkNo -> TraceEvent blk

-- | Performing a migration of the on-disk files
Migrating :: Text -> TraceEvent blk
DeletingAfter :: WithOrigin (Tip blk) -> TraceEvent blk
DBAlreadyClosed :: TraceEvent blk
DBClosed :: TraceEvent blk
TraceCacheEvent :: !TraceCacheEvent -> TraceEvent blk
data CacheConfig
CacheConfig :: Word32 -> DiffTime -> CacheConfig

-- | Maximum number of past chunks to cache, excluding the current chunk.
--   
--   NOTE: must be &gt; 0
[$sel:pastChunksToCache:CacheConfig] :: CacheConfig -> Word32

-- | Expire past chunks that haven't been used for
--   <a>$sel:expireUnusedAfter:CacheConfig</a> from the cache, regardless
--   the number of past chunks in the cache.
[$sel:expireUnusedAfter:CacheConfig] :: CacheConfig -> DiffTime

-- | For testing purposes: exposes internals via <a>Internal</a>
openDBInternal :: forall m blk. (IOLike m, GetPrevHash blk, ConvertRawHash blk, ImmutableDbSerialiseConstraints blk, HasCallStack) => ImmutableDbArgs Identity m blk -> m (ImmutableDB m blk, Internal m blk)
data Internal m blk
Internal :: (HasCallStack => WithOrigin (Tip blk) -> m ()) -> Internal m blk

-- | Delete everything in the database after the specified tip.
--   
--   PRECONDITION: The tip must correspond to an existing block or genesis.
--   
--   The correctness of open iterators is not guaranteed, they should be
--   closed before calling this operation.
--   
--   Throws a <a>ClosedDBError</a> if the database is closed.
[deleteAfter_] :: Internal m blk -> HasCallStack => WithOrigin (Tip blk) -> m ()

-- | Wrapper around <a>deleteAfter_</a> to ensure <a>HasCallStack</a>
--   constraint
--   
--   See documentation of <a>deleteAfter_</a>.
deleteAfter :: HasCallStack => Internal m blk -> WithOrigin (Tip blk) -> m ()

module Ouroboros.Consensus.Storage.ImmutableDB

module Ouroboros.Consensus.Util.SOP

-- | Version of <tt>sequence_NS</tt> that requires only <a>Functor</a>
--   
--   The version in the library requires <a>Applicative</a>, which is
--   unnecessary.
sequence_NS' :: forall xs f g. Functor f => NS (f :.: g) xs -> f (NS g xs)

-- | Version of <tt>map_NP</tt> that does not require a singleton
map_NP' :: forall f g xs. (forall a. f a -> g a) -> NP f xs -> NP g xs
partition_NS :: forall xs f. SListI xs => [NS f xs] -> NP ([] :.: f) xs

-- | We only allow up to 23 (so counting from 0, 24 elements in
--   <tt>xs</tt>), because CBOR stores a <a>Word8</a> in the range 0-23 as
--   a single byte equal to the value of the <a>Word8</a>. We rely on this
--   in <tt>reconstructNestedCtxt</tt> and other places.
npWithIndices :: SListI xs => NP (K Word8) xs
nsToIndex :: SListI xs => NS f xs -> Word8

-- | We only allow up to 23, see <a>npWithIndices</a>.
nsFromIndex :: SListI xs => Word8 -> Maybe (NS (K ()) xs)

-- | Simple lens to access an element of an n-ary product.
data Lens f xs a
Lens :: (NP f xs -> f a) -> (f a -> NP f xs -> NP f xs) -> Lens f xs a
[getter] :: Lens f xs a -> NP f xs -> f a
[setter] :: Lens f xs a -> f a -> NP f xs -> NP f xs

-- | Generate all lenses to access the element of an n-ary product.
lenses_NP :: forall f xs. SListI xs => NP (Lens f xs) xs

-- | Conjure up an <a>SListI</a> constraint from an <a>NP</a>
npToSListI :: NP a xs -> (SListI xs => r) -> r
allComposeShowK :: (SListI xs, Show a) => Proxy xs -> Proxy a -> Dict (All (Compose Show (K a))) xs
fn_5 :: (f0 a -> f1 a -> f2 a -> f3 a -> f4 a -> f5 a) -> (f0 -.-> (f1 -.-> (f2 -.-> (f3 -.-> (f4 -.-> f5))))) a
class IsNonEmpty xs
isNonEmpty :: IsNonEmpty xs => proxy xs -> ProofNonEmpty xs
data ProofNonEmpty :: [Type] -> Type
[ProofNonEmpty] :: Proxy x -> Proxy xs -> ProofNonEmpty (x : xs)
checkIsNonEmpty :: forall xs. SListI xs => Proxy xs -> Maybe (ProofNonEmpty xs)
instance Ouroboros.Consensus.Util.SOP.IsNonEmpty (x : xs)


-- | Type-level counting
--   
--   Intended for unqualified import.
module Ouroboros.Consensus.Util.Counting
newtype Exactly xs a
Exactly :: NP (K a) xs -> Exactly xs a
[getExactly] :: Exactly xs a -> NP (K a) xs
pattern ExactlyNil :: () => xs ~ '[] => Exactly xs a
pattern ExactlyCons :: () => xs' ~ (x : xs) => a -> Exactly xs a -> Exactly xs' a

-- | At most one value for each type level index
data AtMost :: [Type] -> Type -> Type
[AtMostNil] :: AtMost xs a
[AtMostCons] :: !a -> !AtMost xs a -> AtMost (x : xs) a

-- | Non-empty variation on <a>AtMost</a>
data NonEmpty :: [Type] -> Type -> Type
[NonEmptyOne] :: !a -> NonEmpty (x : xs) a
[NonEmptyCons] :: !a -> !NonEmpty xs a -> NonEmpty (x : xs) a

-- | Singleton
exactlyOne :: a -> Exactly '[x] a

-- | From a pair
exactlyTwo :: a -> a -> Exactly '[x, y] a

-- | Analogue of <a>head</a>
exactlyHead :: Exactly (x : xs) a -> a

-- | Analogue of <a>tail</a>
exactlyTail :: Exactly (x : xs) a -> Exactly xs a

-- | Analogue of <a>zip</a>
exactlyZip :: Exactly xs a -> Exactly xs b -> Exactly xs (a, b)

-- | Analogue of <a>zip</a> where the length of second argument is unknown
exactlyZipFoldable :: Foldable t => Exactly xs a -> t b -> AtMost xs (a, b)
exactlyWeaken :: Exactly xs a -> AtMost xs a
exactlyWeakenNonEmpty :: Exactly (x : xs) a -> NonEmpty (x : xs) a

-- | Analogue of <a>replicate</a>
--   
--   In CPS style because the <tt>xs</tt> type parameter is not statically
--   known.
exactlyReplicate :: forall a r. Word -> a -> (forall xs. Exactly xs a -> r) -> r

-- | Singleton
atMostOne :: a -> AtMost (x : xs) a

-- | Analogue of <a>init</a>
--   
--   For simplicity we don't shrink the type-level index.
atMostInit :: AtMost xs a -> Maybe (AtMost xs a, a)

-- | Analogue of <a>head</a>
atMostHead :: AtMost xs a -> Maybe a

-- | Analogue of <a>last</a>
atMostLast :: AtMost xs a -> Maybe a
atMostZipFoldable :: Foldable t => AtMost xs a -> t b -> AtMost xs (a, b)
atMostNonEmpty :: AtMost (x : xs) a -> Maybe (NonEmpty (x : xs) a)

-- | Analogue of <a>head</a>
nonEmptyHead :: NonEmpty xs a -> a

-- | Analogue of <a>last</a>
nonEmptyLast :: NonEmpty xs a -> a

-- | Analogue of <a>init</a>
nonEmptyInit :: NonEmpty xs a -> (Maybe (NonEmpty xs a), a)

-- | Build a <a>NonEmpty</a> from a list. Returns <a>Nothing</a> when the
--   list is empty or when it's longer than <tt>xs</tt>.
nonEmptyFromList :: forall xs a. SListI xs => [a] -> Maybe (NonEmpty xs a)
nonEmptyWeaken :: NonEmpty xs a -> AtMost xs a

-- | A strict prefixes
--   
--   <pre>
--      nonEmptyStrictPrefixes (fromJust (nonEmptyFromList [1..4]))
--   == [ NonEmptyOne  1
--      , NonEmptyCons 1 $ NonEmptyOne  2
--      , NonEmptyCons 1 $ NonEmptyCons 2 $ NonEmptyOne 3
--      ]
--   </pre>
nonEmptyStrictPrefixes :: NonEmpty xs a -> [NonEmpty xs a]

-- | Apply the specified function to exactly one element
nonEmptyMapOne :: forall m xs a. Alternative m => (a -> m a) -> NonEmpty xs a -> m (NonEmpty xs a)

-- | Variation on <a>nonEmptyMapOne</a> where we try to apply the function
--   to <i>pairs</i> of elements
nonEmptyMapTwo :: forall m xs a. Alternative m => (a -> m a) -> (a -> a -> m (a, a)) -> NonEmpty xs a -> m (NonEmpty xs a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Ouroboros.Consensus.Util.Counting.AtMost xs a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Ouroboros.Consensus.Util.Counting.NonEmpty xs a)
instance GHC.Show.Show a => GHC.Show.Show (Ouroboros.Consensus.Util.Counting.AtMost xs a)
instance GHC.Show.Show a => GHC.Show.Show (Ouroboros.Consensus.Util.Counting.NonEmpty xs a)
instance GHC.Base.Functor (Ouroboros.Consensus.Util.Counting.AtMost xs)
instance Data.Foldable.Foldable (Ouroboros.Consensus.Util.Counting.AtMost xs)
instance Data.Traversable.Traversable (Ouroboros.Consensus.Util.Counting.AtMost xs)
instance GHC.Base.Functor (Ouroboros.Consensus.Util.Counting.NonEmpty xs)
instance Data.Foldable.Foldable (Ouroboros.Consensus.Util.Counting.NonEmpty xs)
instance Data.Traversable.Traversable (Ouroboros.Consensus.Util.Counting.NonEmpty xs)
instance Ouroboros.Consensus.Util.SOP.IsNonEmpty xs => GHC.Base.Applicative (Ouroboros.Consensus.Util.Counting.NonEmpty xs)
instance GHC.Base.Functor (Ouroboros.Consensus.Util.Counting.Exactly xs)
instance Data.Foldable.Foldable (Ouroboros.Consensus.Util.Counting.Exactly xs)
instance Data.Traversable.Traversable (Ouroboros.Consensus.Util.Counting.Exactly xs)
instance GHC.Show.Show a => GHC.Show.Show (Ouroboros.Consensus.Util.Counting.Exactly xs a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Ouroboros.Consensus.Util.Counting.Exactly xs a)

module Ouroboros.Consensus.HardFork.History.Summary

-- | Detailed information about the time bounds of an era
data Bound
Bound :: !RelativeTime -> !SlotNo -> !EpochNo -> Bound
[boundTime] :: Bound -> !RelativeTime
[boundSlot] :: Bound -> !SlotNo
[boundEpoch] :: Bound -> !EpochNo
initBound :: Bound

-- | Compute upper bound given just the epoch number and era parameters
mkUpperBound :: HasCallStack => EraParams -> Bound -> EpochNo -> Bound
slotToEpochBound :: EraParams -> Bound -> SlotNo -> EpochNo

-- | Information about a specific era
--   
--   The <a>eraEnd</a> of the final era in the summary will be determined
--   by the safe zone considerations discussed above.
--   
--   Let the start of the summary be <tt>(t, s, e)</tt> (time, slot epoch),
--   and the end of the summary be <tt>(t', s', e')</tt>. We have one
--   invariant relating epochs and slots:
--   
--   <pre>
--   INV-1a  e' == e + ((s' - s) / epochSize)
--   INV-1b: s' == s + ((e' - e) * epochSize)
--   </pre>
--   
--   And another invariant relating time and slots:
--   
--   <pre>
--   INV-2a: s' == s + ((t' - t) / slotLen)
--   INV-2b: t' == t + ((s' - s) * slotLen)
--   </pre>
--   
--   Note that these aren't really two sets of independent invariants.
--   <tt>INV-1a</tt> follows from <tt>INV-1b</tt>:
--   
--   <pre>
--         s'                   == s + ((e' - e) * epochSize)
--         s' - s               ==     ((e' - e) * epochSize)
--        (s' - s) / epochSize  ==       e' - e
--   e + ((s' - s) / epochSize) ==       e'
--   </pre>
--   
--   Similarly, <tt>INV-2a</tt> follows from <tt>INV-2b</tt>:
--   
--   <pre>
--         t'                 == t + ((s' - s) * slotLen)
--         t' - t             ==     ((s' - s) * slotLen)
--        (t' - t) / slotLen  ==       s' - s
--   s + ((t' - t) / slotLen) ==       s'
--   </pre>
data EraSummary
EraSummary :: !Bound -> !EraEnd -> !EraParams -> EraSummary

-- | Inclusive lower bound
[eraStart] :: EraSummary -> !Bound

-- | Exclusive upper bound
[eraEnd] :: EraSummary -> !EraEnd

-- | Active parameters
[eraParams] :: EraSummary -> !EraParams

-- | Exclusive upper bound on the era
data EraEnd

-- | Bounded era
EraEnd :: !Bound -> EraEnd

-- | Unbounded era
--   
--   This arises from the use of <tt>UnsafeUnbounded</tt>.
EraUnbounded :: EraEnd

-- | Version of <a>mkUpperBound</a> when the upper bound may not be known
--   
--   If passed <a>Nothing</a>, assumes <a>EraUnbounded</a>. This is
--   <i>NOT</i> suitable for eras where the transition is simply unknown.
mkEraEnd :: EraParams -> Bound -> Maybe EpochNo -> EraEnd

-- | Summary of the <i>confirmed</i> part of the ledger
--   
--   The summary zips <a>Shape</a> with <tt>Forks</tt>, and provides
--   detailed information about the start and end of each era.
newtype Summary xs
Summary :: NonEmpty xs EraSummary -> Summary xs
[getSummary] :: Summary xs -> NonEmpty xs EraSummary

-- | Construct <a>Summary</a> with an exact number of <a>EraSummary</a>
--   
--   Primarily useful for tests.
summaryWithExactly :: Exactly (x : xs) EraSummary -> Summary (x : xs)

-- | <a>Summary</a> for a ledger that never forks
neverForksSummary :: EpochSize -> SlotLength -> Summary '[x]

-- | The shape of the chain (old to new)
--   
--   The shape determines how many hard forks we expect as well as the
--   parameters for each era. The type argument is a type-level list
--   containing one entry per era, emphasizing that this information is
--   statically known.
--   
--   The entry indices themselves are not used here, but the idea is that
--   they look something like <tt>'[ByronBlock, ShelleyBlock,
--   GoguenBlock]</tt> and do affect the hard fork combinator. So far this
--   is a list of block types, since most of consensus is indexed by block
--   types.
newtype Shape xs
Shape :: Exactly xs EraParams -> Shape xs
[getShape] :: Shape xs -> Exactly xs EraParams

-- | The exact point of each confirmed hard fork transition (old to new)
--   
--   Unlike the <a>Shape</a> of the chain, which is statically known, the
--   <a>Transitions</a> are derived from the state of the ledger (hard fork
--   transition points only become known after a voting procedure).
--   
--   Any transition listed here must be "certain". How certainty is
--   established is ledger dependent, but it should imply that this is no
--   longer subject to rollback.
data Transitions :: [Type] -> Type

-- | If the indices are, say, <tt>'[Byron, Shelley, Goguen]</tt>, then we
--   can have have at most two transitions: one to Shelley, and one to
--   Goguen. There cannot be a transition <i>to</i> the initial ledger.
[Transitions] :: AtMost xs EpochNo -> Transitions (x : xs)

-- | There is only one era
singletonShape :: EraParams -> Shape '[x]

-- | No known transitions yet
transitionsUnknown :: Transitions (x : xs)

-- | Construct hard fork <a>Summary</a>
--   
--   NOTE (on epoch to slot translation). In order to translate
--   <a>SlotNo</a> to <a>EpochNo</a>, we simply "line up" all slots. For
--   example, suppose we have an initial <a>EpochSize</a> of 10, and then
--   an <a>EpochSize</a> of 20 from <a>EpochNo</a> 3 onwards. We end up
--   with something like
--   
--   <pre>
--   Epoch | 0      | 1        | 2        | 3        | 4        | ..
--   Slot  | 0 .. 9 | 10 .. 19 | 20 .. 29 | 30 .. 49 | 50 .. 69 | ..
--   </pre>
--   
--   We do this translation <i>independent</i> from the
--   <tt>minimumPossibleSlotNo</tt> for a particular ledger. This means
--   that for ledgers where the <tt>minimumPossibleSlotNo</tt> is not zero
--   (e.g., some ledgers might set it to 1), the maximum number of blocks
--   (aka filled slots) in an epoch is just 1 (or more) less than the other
--   epochs.
summarize :: WithOrigin SlotNo -> Shape xs -> Transitions xs -> Summary xs

-- | Check <a>Shape</a> invariants
--   
--   The only part of the <a>Shape</a> that must make sense is the
--   <a>safeBeforeEpoch</a> values (they must be strictly increasing).
--   
--   NOTE: We assume eras cannot be empty. This will be satisfied by any
--   ledger we are interested in since transitions must be voted on (safe
--   zones will be non-empty).
invariantShape :: Shape xs -> Except String ()

-- | Check <a>Summary</a> invariants
invariantSummary :: Summary xs -> Except String ()

-- | Outer bounds of the summary
summaryBounds :: Summary xs -> (Bound, EraEnd)

-- | Analogue of <a>init</a> for <a>Summary</a> (i.e., split off the final
--   era)
--   
--   This is primarily useful for tests.
summaryInit :: Summary xs -> (Maybe (Summary xs), EraSummary)
instance NoThunks.Class.NoThunks Ouroboros.Consensus.HardFork.History.Summary.Bound
instance GHC.Generics.Generic Ouroboros.Consensus.HardFork.History.Summary.Bound
instance GHC.Classes.Eq Ouroboros.Consensus.HardFork.History.Summary.Bound
instance GHC.Show.Show Ouroboros.Consensus.HardFork.History.Summary.Bound
instance NoThunks.Class.NoThunks Ouroboros.Consensus.HardFork.History.Summary.EraEnd
instance GHC.Generics.Generic Ouroboros.Consensus.HardFork.History.Summary.EraEnd
instance GHC.Classes.Eq Ouroboros.Consensus.HardFork.History.Summary.EraEnd
instance GHC.Show.Show Ouroboros.Consensus.HardFork.History.Summary.EraEnd
instance NoThunks.Class.NoThunks Ouroboros.Consensus.HardFork.History.Summary.EraSummary
instance GHC.Generics.Generic Ouroboros.Consensus.HardFork.History.Summary.EraSummary
instance GHC.Classes.Eq Ouroboros.Consensus.HardFork.History.Summary.EraSummary
instance GHC.Show.Show Ouroboros.Consensus.HardFork.History.Summary.EraSummary
instance NoThunks.Class.NoThunks (Ouroboros.Consensus.HardFork.History.Summary.Summary xs)
instance GHC.Show.Show (Ouroboros.Consensus.HardFork.History.Summary.Summary xs)
instance GHC.Classes.Eq (Ouroboros.Consensus.HardFork.History.Summary.Summary xs)
instance NoThunks.Class.NoThunks (Ouroboros.Consensus.HardFork.History.Summary.Shape xs)
instance GHC.Show.Show (Ouroboros.Consensus.HardFork.History.Summary.Shape xs)
instance GHC.Show.Show (Ouroboros.Consensus.HardFork.History.Summary.Transitions xs)
instance Data.SOP.Constraint.SListI xs => Codec.Serialise.Class.Serialise (Ouroboros.Consensus.HardFork.History.Summary.Summary xs)
instance Codec.Serialise.Class.Serialise Ouroboros.Consensus.HardFork.History.Summary.EraSummary
instance Codec.Serialise.Class.Serialise Ouroboros.Consensus.HardFork.History.Summary.EraEnd
instance Codec.Serialise.Class.Serialise Ouroboros.Consensus.HardFork.History.Summary.Bound

module Ouroboros.Consensus.HardFork.History.Qry

-- | Query
--   
--   <a>Qry</a> adds a monadic interface on top of <a>Expr</a>. Although
--   means that <a>Qry</a> itself is not showable, the
--   <a>PastHorizonException</a> can nonetheless show the offending
--   expression alongside the <a>Summary</a> against which it was
--   evaluated.
data Qry :: Type -> Type

-- | Query expressions in PHOAS
data Expr (f :: Type -> Type) :: Type -> Type
[EVar] :: f a -> Expr f a
[ELit] :: Show a => a -> Expr f a
[ELet] :: Expr f a -> (f a -> Expr f b) -> Expr f b
[EPair] :: Expr f a -> Expr f b -> Expr f (a, b)
[EFst] :: Expr f (a, b) -> Expr f a
[ESnd] :: Expr f (a, b) -> Expr f b
[EAbsToRelTime] :: Expr f RelativeTime -> Expr f TimeInEra
[EAbsToRelSlot] :: Expr f SlotNo -> Expr f SlotInEra
[EAbsToRelEpoch] :: Expr f EpochNo -> Expr f EpochInEra
[ERelToAbsTime] :: Expr f TimeInEra -> Expr f RelativeTime
[ERelToAbsSlot] :: Expr f (SlotInEra, TimeInSlot) -> Expr f SlotNo
[ERelToAbsEpoch] :: Expr f (EpochInEra, SlotInEpoch) -> Expr f EpochNo
[ERelTimeToSlot] :: Expr f TimeInEra -> Expr f (SlotInEra, TimeInSlot)
[ERelSlotToTime] :: Expr f SlotInEra -> Expr f TimeInEra
[ERelSlotToEpoch] :: Expr f SlotInEra -> Expr f (EpochInEra, SlotInEpoch)
[ERelEpochToSlot] :: Expr f EpochInEra -> Expr f SlotInEra
[ESlotLength] :: Expr f SlotNo -> Expr f SlotLength
[EEpochSize] :: Expr f EpochNo -> Expr f EpochSize

-- | We tried to convert something that is past the horizon
--   
--   That is, we tried to convert something that is past the point in time
--   beyond which we lack information due to uncertainty about the next
--   hard fork.
data PastHorizonException
PastHorizon :: CallStack -> Some ClosedExpr -> [EraSummary] -> PastHorizonException

-- | Callstack to the call to <a>runQuery</a>
[pastHorizonCallStack] :: PastHorizonException -> CallStack

-- | The <a>Expr</a> we tried to evaluate
[pastHorizonExpression] :: PastHorizonException -> Some ClosedExpr

-- | The <a>EraSummary</a>s that we tried to evaluate the <a>Expr</a>
--   against
[pastHorizonSummary] :: PastHorizonException -> [EraSummary]

-- | Construct a <a>Qry</a> from a closed <a>Expr</a>
qryFromExpr :: (forall f. Expr f a) -> Qry a

-- | Run a query
--   
--   Unlike an <a>Expr</a>, which is evaluated in a single era, a
--   <a>Qry</a> is evaluated against <i>all</i> eras. Only if all
--   <a>Expr</a>s embedded in the <a>Qry</a> can be evaluated in the
--   <i>same</i> era (we don't want to mix properties of different eras in
--   one query) do we return the result. If there is no era in which we can
--   evaluate all <a>Expr</a>s in the <a>Qry</a>, we report a
--   <a>PastHorizonException</a>.
--   
--   NOTE: this means that queries about separate eras have to be run
--   separately, they should not be composed into a single query. How could
--   we know to which era which relative slot/time refers?
runQuery :: forall a xs. HasCallStack => Qry a -> Summary xs -> Either PastHorizonException a
runQueryThrow :: (HasCallStack, MonadThrow m) => Qry a -> Summary xs -> m a
runQueryPure :: HasCallStack => Qry a -> Summary xs -> a

-- | Can be sent across the LocalStateQuery protocol to interpret queries
--   in the wallet.
--   
--   The <a>Summary</a> should be considered internal.
data Interpreter xs
mkInterpreter :: Summary xs -> Interpreter xs
interpretQuery :: HasCallStack => Interpreter xs -> Qry a -> Either PastHorizonException a

-- | Translate <tt>UTCTime</tt> to <a>SlotNo</a>
--   
--   Additionally returns the time spent and time left in this slot.
wallclockToSlot :: RelativeTime -> Qry (SlotNo, NominalDiffTime, NominalDiffTime)

-- | Translate <a>SlotNo</a> to the <tt>UTCTime</tt> at the start of that
--   slot
--   
--   Additionally returns the length of the slot.
slotToWallclock :: SlotNo -> Qry (RelativeTime, SlotLength)

-- | Convert <a>SlotNo</a> to <a>EpochNo</a> and the relative slot within
--   the epoch
slotToEpoch' :: SlotNo -> Qry (EpochNo, Word64)

-- | Translate <a>SlotNo</a> to its corresponding <a>EpochNo</a>
--   
--   Additionally returns the relative slot within this epoch and how many
--   slots are left in this slot.
slotToEpoch :: SlotNo -> Qry (EpochNo, Word64, Word64)
epochToSlot' :: EpochNo -> Qry SlotNo

-- | Translate <a>EpochNo</a> to the <a>SlotNo</a> of the first slot in
--   that epoch
--   
--   Additionally returns the size of the epoch.
epochToSlot :: EpochNo -> Qry (SlotNo, EpochSize)
epochToSize :: EpochNo -> Qry EpochSize
instance GHC.Generics.Generic Ouroboros.Consensus.HardFork.History.Qry.TimeInEra
instance GHC.Generics.Generic Ouroboros.Consensus.HardFork.History.Qry.TimeInSlot
instance GHC.Generics.Generic Ouroboros.Consensus.HardFork.History.Qry.SlotInEra
instance GHC.Generics.Generic Ouroboros.Consensus.HardFork.History.Qry.SlotInEpoch
instance GHC.Generics.Generic Ouroboros.Consensus.HardFork.History.Qry.EpochInEra
instance GHC.Classes.Eq (Ouroboros.Consensus.HardFork.History.Qry.Interpreter xs)
instance GHC.Show.Show (Ouroboros.Consensus.HardFork.History.Qry.Var a)
instance GHC.Show.Show Ouroboros.Consensus.HardFork.History.Qry.TimeInEra
instance GHC.Show.Show Ouroboros.Consensus.HardFork.History.Qry.TimeInSlot
instance GHC.Show.Show Ouroboros.Consensus.HardFork.History.Qry.SlotInEra
instance GHC.Show.Show Ouroboros.Consensus.HardFork.History.Qry.SlotInEpoch
instance GHC.Show.Show Ouroboros.Consensus.HardFork.History.Qry.EpochInEra
instance GHC.Show.Show Ouroboros.Consensus.HardFork.History.Qry.PastHorizonException
instance Data.SOP.Constraint.SListI xs => Codec.Serialise.Class.Serialise (Ouroboros.Consensus.HardFork.History.Qry.Interpreter xs)
instance GHC.Show.Show (Ouroboros.Consensus.Util.Some Ouroboros.Consensus.HardFork.History.Qry.ClosedExpr)
instance GHC.Show.Show (Ouroboros.Consensus.HardFork.History.Qry.ClosedExpr a)
instance GHC.Show.Show (Ouroboros.Consensus.HardFork.History.Qry.Interpreter xs)
instance GHC.Exception.Type.Exception Ouroboros.Consensus.HardFork.History.Qry.PastHorizonException
instance GHC.Base.Functor Ouroboros.Consensus.HardFork.History.Qry.Qry
instance GHC.Base.Applicative Ouroboros.Consensus.HardFork.History.Qry.Qry
instance GHC.Base.Monad Ouroboros.Consensus.HardFork.History.Qry.Qry

module Ouroboros.Consensus.HardFork.History.Caching

-- | Stateful abstraction to execute queries
data RunWithCachedSummary (xs :: [Type]) m
RunWithCachedSummary :: (forall a. Qry a -> STM m (Either PastHorizonException a)) -> RunWithCachedSummary (xs :: [Type]) m

-- | Run the specified query
--   
--   If the query fails with a <a>PastHorizonException</a>, it will update
--   its internal state (compute a new summary) and try again. If that
--   <i>still</i> fails, the <a>PastHorizonException</a> is returned.
--   
--   See also <a>cachedRunQueryThrow</a>.
[cachedRunQuery] :: RunWithCachedSummary (xs :: [Type]) m -> forall a. Qry a -> STM m (Either PastHorizonException a)

-- | Construct <a>RunWithCachedSummary</a> given action that computes the
--   summary
--   
--   Most use cases will probably construct this action from an action that
--   reads the ledger state and then computes the summary from that.
runWithCachedSummary :: forall m xs. MonadSTM m => STM m (Summary xs) -> m (RunWithCachedSummary xs m)

-- | Wrapper around <a>cachedRunQuery</a> which throws the
--   <a>PastHorizonException</a>
--   
--   This is useful for callers who know that their queries should not be
--   past the horizon (and it would be a bug if they were).
cachedRunQueryThrow :: (MonadSTM m, MonadThrow (STM m)) => RunWithCachedSummary xs m -> Qry a -> STM m a


-- | Derive <a>EpochInfo</a>
module Ouroboros.Consensus.HardFork.History.EpochInfo

-- | Construct <a>EpochInfo</a> from a function that returns the hard fork
--   summary
--   
--   When a particular request fails with a <a>PastHorizon</a> error, we
--   ask for an updated summary, in the hope that the ledger state has
--   advanced. If the query <i>still</i> fails with that updated summary,
--   the error is thrown as an exception.
summaryToEpochInfo :: forall m xs. (MonadSTM m, MonadThrow (STM m)) => STM m (Summary xs) -> m (EpochInfo (STM m))

-- | Construct an <a>EpochInfo</a> for a <i>snapshot</i> of the ledger
--   state
--   
--   When a particular request fails with a <a>PastHorizon</a> error, we
--   throw the error as a <i>pure</i> exception. Such an exception would
--   indicate a bug.
snapshotEpochInfo :: forall xs. Summary xs -> EpochInfo Identity

-- | A dummy <a>EpochInfo</a> that always throws an <a>error</a>.
--   
--   To be used as a placeholder before a summary is available.
dummyEpochInfo :: EpochInfo Identity


-- | Intended for qualified import
--   
--   <pre>
--   import qualified Ouroboros.Consensus.HardFork.History as History
--   </pre>
module Ouroboros.Consensus.HardFork.History

module Ouroboros.Consensus.HardFork.Abstract
class HasHardForkHistory blk where {
    
    -- | Type level description of the hard fork shape
    --   
    --   The <tt>Summary</tt> infrastructure does not care what the types in
    --   this list are, it just cares how <i>many</i> eras there are. The hard
    --   fork combinator will instantiate <a>HardForkIndices</a> to the types
    --   of the blocks involved in the hard fork, e.g., we might have something
    --   like
    --   
    --   <pre>
    --   '[ByronBlock, ShelleyBlock, GoguenBlock]
    --   </pre>
    type family HardForkIndices blk :: [Type];
}

-- | Summary of the hard fork state
--   
--   NOTE: <a>HasHardForkHistory</a> is the only abstraction that the
--   consensus layer is aware in relation to potential hard forks, and is
--   needed only for time translations (in block production and in the
--   chain DB). It is independent from the hard fork combinator and can be
--   used for blocks that never fork (in which case the <tt>Summary</tt>
--   will be trivial) or indeed for blocks that do support transitions but
--   do not use the hard fork combinator.
--   
--   It is however useful to consider what this function means in the
--   (typical) case that the hard fork combinator <i>is</i> used. The HFC
--   introduces the concept of a partial ledger config, which is
--   essentially the ledger config minus an <tt>EpochInfo</tt>. Whenever
--   the HFC calls functions on the underlying ledger, it maintains enough
--   state to be able to <i>construct</i> an <tt>EpochInfo</tt> on the fly
--   and then combines that with the <tt>PartialLedgerConfig</tt> to get
--   the full <a>LedgerConfig</a>. The config of the HFC <i>itself</i>
--   however does <i>not</i> require an <tt>EpochInfo</tt>, and so the
--   config that we pass here will not contain that <tt>EpochInfo</tt> (if
--   it did, that would be strange: we'd be computing the <tt>Summary</tt>
--   required to construct an <tt>EpochInfo</tt> while we already have
--   one). Critically, the HFC implements <a>hardForkSummary</a> directly
--   and does not call <a>hardForkSummary</a> in the underlying ledgers.
--   
--   When running ledgers that are normally run using the HFC as standalone
--   ledgers, then the <a>LedgerConfig</a> here must indeed already contain
--   timing information, and so this function becomes little more than a
--   projection (indeed, in this case the <a>LedgerState</a> should be
--   irrelevant).
hardForkSummary :: HasHardForkHistory blk => LedgerConfig blk -> LedgerState blk -> Summary (HardForkIndices blk)

-- | Helper function that can be used to define <a>hardForkSummary</a>
--   
--   This is basically a proof of the claim of the documentation of
--   <a>hardForkSummary</a> that <a>hardForkSummary</a> becomes a mere
--   projection of a block's ledger state when there are no hard forks. It
--   is useful to give blocks such as <tt>ShelleyBlock</tt> their own
--   <a>HasHardForkHistory</a> instance so that we can run them as
--   independent ledgers (in addition to being run with the hard fork
--   combinator).
neverForksHardForkSummary :: (LedgerConfig blk -> EraParams) -> LedgerConfig blk -> LedgerState blk -> Summary '[blk]


-- | Support for defining <tt>BlockchainTime</tt> instances
module Ouroboros.Consensus.BlockchainTime.WallClock.Util

-- | Time related tracing
data TraceBlockchainTimeEvent

-- | The start time of the blockchain time is in the future
--   
--   We have to block (for <a>NominalDiffTime</a>) until that time comes.
TraceStartTimeInTheFuture :: SystemStart -> NominalDiffTime -> TraceBlockchainTimeEvent

-- | Current slot is not yet known
--   
--   This happens when the tip of our current chain is so far in the past
--   that we cannot translate the current wallclock to a slot number,
--   typically during syncing. Until the current slot number is known, we
--   cannot produce blocks. Seeing this message during syncing therefore is
--   normal and to be expected.
--   
--   We record the current time (the time we tried to translate to a
--   <a>SlotNo</a>) as well as the <a>PastHorizonException</a>, which
--   provides detail on the bounds between which we <i>can</i> do
--   conversions. The distance between the current time and the upper bound
--   should rapidly decrease with consecutive
--   <a>TraceCurrentSlotUnknown</a> messages during syncing.
TraceCurrentSlotUnknown :: UTCTime -> PastHorizonException -> TraceBlockchainTimeEvent
data SystemClockMovedBackException

-- | The system clock got moved back so far that the slot number decreased
--   
--   We record the the slot number before and after the change.
SystemClockMovedBack :: SlotNo -> SlotNo -> SystemClockMovedBackException
instance GHC.Show.Show Ouroboros.Consensus.BlockchainTime.WallClock.Util.TraceBlockchainTimeEvent
instance GHC.Show.Show Ouroboros.Consensus.BlockchainTime.WallClock.Util.SystemClockMovedBackException
instance GHC.Exception.Type.Exception Ouroboros.Consensus.BlockchainTime.WallClock.Util.SystemClockMovedBackException


-- | Intended for qualified import
--   
--   <pre>
--   import Ouroboros.Consensus.HardFork.Combinator.Util.InPairs (InPairs(..))
--   import qualified Ouroboros.Consensus.HardFork.Combinator.Util.InPairs as InPairs
--   </pre>
module Ouroboros.Consensus.HardFork.Combinator.Util.InPairs

-- | We have an <tt>f x y</tt> for each pair <tt>(x, y)</tt> of successive
--   list elements
data InPairs (f :: k -> k -> Type) (xs :: [k])
[PNil] :: InPairs f '[x]
[PCons] :: f x y -> InPairs f (y : zs) -> InPairs f (x : (y : zs))
mk1 :: InPairs f '[x]
mk2 :: f x y -> InPairs f '[x, y]
mk3 :: f x y -> f y z -> InPairs f '[x, y, z]
hmap :: SListI xs => (forall x y. f x y -> g x y) -> InPairs f xs -> InPairs g xs
hcmap :: forall proxy c f g xs. All c xs => proxy c -> (forall x y. (c x, c y) => f x y -> g x y) -> InPairs f xs -> InPairs g xs
hpure :: (SListI xs, IsNonEmpty xs) => (forall x y. f x y) -> InPairs f xs
hcpure :: forall proxy c xs f. (All c xs, IsNonEmpty xs) => proxy c -> (forall x y. (c x, c y) => f x y) -> InPairs f xs
data Requiring h f x y
Require :: (h x -> f x y) -> Requiring h f x y
[provide] :: Requiring h f x y -> h x -> f x y
data RequiringBoth h f x y
RequireBoth :: (h x -> h y -> f x y) -> RequiringBoth h f x y
[provideBoth] :: RequiringBoth h f x y -> h x -> h y -> f x y
ignoring :: f x y -> Requiring h f x y
ignoringBoth :: f x y -> RequiringBoth h f x y
requiring :: SListI xs => NP h xs -> InPairs (Requiring h f) xs -> InPairs f xs
requiringBoth :: NP h xs -> InPairs (RequiringBoth h f) xs -> InPairs f xs


-- | Intended for qualified import
--   
--   <pre>
--   import qualified Ouroboros.Consensus.HardFork.Combinator.Util.Telescope as Telescope
--   </pre>
module Ouroboros.Consensus.HardFork.Combinator.Util.Telescope

-- | Telescope
--   
--   A telescope is an extension of an <a>NS</a>, where every time we "go
--   right" in the sum we have an additional value.
--   
--   Blockchain intuition: think of <tt>g</tt> as representing some kind of
--   past state, and <tt>f</tt> some kind of current state. Then depending
--   on how many hard fork transitions we have had, we might either have,
--   say
--   
--   <pre>
--   TZ currentByronState
--   TS pastByronState $ TZ currentShelleyState
--   TS pastByronState $ TS pastShelleyState $ TZ currentGoguenState
--   </pre>
--   
--   The <a>Telescope</a> API mostly follows <tt>sop-core</tt> conventions,
--   supporting functor (<a>hmap</a>, <a>hcmap</a>), applicative
--   (<a>hap</a>, <a>hpure</a>), foldable (<a>hcollapse</a>) and
--   traversable (<a>hsequence'</a>). However, since <a>Telescope</a> is a
--   bi-functor, it cannot reuse the <tt>sop-core</tt> classes. The naming
--   scheme of the functions is adopted from <tt>sop-core</tt> though; for
--   example:
--   
--   <pre>
--   bi h (c) zipWith
--   |  |  |    |
--   |  |  |    \ zipWith: the name from base
--   |  |  |
--   |  |  \ constrained: version of the function with a constraint parameter
--   |  |
--   |  \ higher order: 'Telescope' (like 'NS'/'NP') is a /higher order/ functor
--   |
--   \ bifunctor: 'Telescope' (unlike 'NS'/'NP') is a higher order /bifunctor/
--   </pre>
--   
--   In addition to the standard SOP operators, the new operators that make
--   a <a>Telescope</a> a telescope are <a>extend</a>, <a>retract</a> and
--   <a>align</a>; see their documentation for details.
data Telescope (g :: k -> Type) (f :: k -> Type) (xs :: [k])
[TZ] :: !f x -> Telescope g f (x : xs)
[TS] :: !g x -> !Telescope g f xs -> Telescope g f (x : xs)

-- | Specialization of <a>hsequence'</a> with weaker constraints
--   (<a>Functor</a> rather than <a>Applicative</a>)
sequence :: forall m g f xs. Functor m => Telescope g (m :.: f) xs -> m (Telescope g f xs)
tip :: Telescope g f xs -> NS f xs
fromTip :: NS f xs -> Telescope (K ()) f xs
toAtMost :: Telescope (K a) (K (Maybe a)) xs -> AtMost xs a
fromTZ :: Telescope g f '[x] -> f x

-- | Bifunctor analogue of <a>hap</a>
bihap :: NP (g -.-> g') xs -> NP (f -.-> f') xs -> Telescope g f xs -> Telescope g' f' xs

-- | Bifunctor analogue of <a>hmap</a>
bihmap :: SListI xs => (forall x. g x -> g' x) -> (forall x. f x -> f' x) -> Telescope g f xs -> Telescope g' f' xs

-- | Bifunctor equivalent of <a>hzipWith</a>
bihzipWith :: SListI xs => (forall x. h x -> g x -> g' x) -> (forall x. h x -> f x -> f' x) -> NP h xs -> Telescope g f xs -> Telescope g' f' xs

-- | Bifunctor equivalent of <a>hczipWith</a>
bihczipWith :: All c xs => proxy c -> (forall x. c x => h x -> g x -> g' x) -> (forall x. c x => h x -> f x -> f' x) -> NP h xs -> Telescope g f xs -> Telescope g' f' xs
newtype Extend m g f x y
Extend :: (f x -> m (g x, f y)) -> Extend m g f x y
[extendWith] :: Extend m g f x y -> f x -> m (g x, f y)

-- | Extend the telescope
--   
--   We will not attempt to extend the telescope past its final segment.
--   
--   Blockchain intuition: suppose we have a telescope containing the
--   ledger state. The "how to extend" argument would take, say, the final
--   Byron state to the initial Shelley state; and "where to extend from"
--   argument would indicate when we want to extend: when the current slot
--   number has gone past the end of the Byron era.
extend :: forall m h g f xs. Monad m => InPairs (Requiring h (Extend m g f)) xs -> NP (f -.-> (Maybe :.: h)) xs -> Telescope g f xs -> m (Telescope g f xs)
newtype Retract m g f x y
Retract :: (g x -> f y -> m (f x)) -> Retract m g f x y
[retractWith] :: Retract m g f x y -> g x -> f y -> m (f x)

-- | Retract a telescope
--   
--   Blockchain intuition: suppose we have a telescope containing the
--   consensus state. When we rewind the consensus state, we might cross a
--   hard fork transition point. So we first <i>retract</i> the telescope
--   <i>to</i> the era containing the slot number that we want to rewind
--   to, and only then call <tt>rewindChainDepState</tt> on that era. Of
--   course, retraction may fail (we might not <i>have</i> past consensus
--   state to rewind to anymore); this failure would require a choice for a
--   particular monad <tt>m</tt>.
retract :: forall m h g f xs. Monad m => Tails (Requiring h (Retract m g f)) xs -> NP (g -.-> (Maybe :.: h)) xs -> Telescope g f xs -> m (Telescope g f xs)

-- | Align a telescope with another, then apply a function to the tips
--   
--   Aligning is a combination of extension and retraction, extending or
--   retracting the telescope as required to match up with the other
--   telescope.
--   
--   Blockchain intuition: suppose we have one telescope containing the
--   already-ticked ledger state, and another telescope containing the
--   consensus state. Since the ledger state has already been ticked, it
--   might have been advanced to the next era. If this happens, we should
--   then align the consensus state with the ledger state, moving <i>it</i>
--   also to the next era, before we can do the consensus header validation
--   check. Note that in this particular example, the ledger state will
--   always be ahead of the consensus state, never behind;
--   <a>alignExtend</a> can be used in this case.
align :: forall m g' g f' f f'' xs. Monad m => InPairs (Requiring g' (Extend m g f)) xs -> Tails (Requiring f' (Retract m g f)) xs -> NP (f' -.-> (f -.-> f'')) xs -> Telescope g' f' xs -> Telescope g f xs -> m (Telescope g f'' xs)

-- | Version of <a>extend</a> where the evidence is a simple <a>Bool</a>
extendIf :: Monad m => InPairs (Extend m g f) xs -> NP (f -.-> K Bool) xs -> Telescope g f xs -> m (Telescope g f xs)

-- | Version of <a>retract</a> where the evidence is a simple <a>Bool</a>
retractIf :: Monad m => Tails (Retract m g f) xs -> NP (g -.-> K Bool) xs -> Telescope g f xs -> m (Telescope g f xs)

-- | Version of <a>align</a> that never retracts, only extends
--   
--   PRE: The telescope we are aligning with cannot be behind us.
alignExtend :: (Monad m, HasCallStack) => InPairs (Requiring g' (Extend m g f)) xs -> NP (f' -.-> (f -.-> f'')) xs -> Telescope g' f' xs -> Telescope g f xs -> m (Telescope g f'' xs)

-- | Version of <a>alignExtend</a> that extends with an NS instead
alignExtendNS :: (Monad m, HasCallStack) => InPairs (Extend m g f) xs -> NP (f' -.-> (f -.-> f'')) xs -> NS f' xs -> Telescope g f xs -> m (Telescope g f'' xs)

-- | <a>Telescope</a> with both functors set to the same <tt>f</tt>
newtype SimpleTelescope f xs
SimpleTelescope :: Telescope f f xs -> SimpleTelescope f xs
[getSimpleTelescope] :: SimpleTelescope f xs -> Telescope f f xs
newtype ScanNext h g x y
ScanNext :: (h x -> g x -> h y) -> ScanNext h g x y
[getNext] :: ScanNext h g x y -> h x -> g x -> h y

-- | Telescope analogue of <a>scanl</a> on lists
--   
--   This function is modelled on
--   
--   <pre>
--   scanl :: (b -&gt; a -&gt; b) -&gt; b -&gt; [a] -&gt; [b]
--   </pre>
--   
--   but there are a few differences:
--   
--   <ul>
--   <li>Since every seed has a different type, we must be given a function
--   for each transition.</li>
--   <li>Unlike <a>scanl</a>, we preserve the length of the telescope
--   (<a>scanl</a> prepends the initial seed)</li>
--   <li>Instead of generating a telescope containing only the seeds, we
--   instead pair the seeds with the elements.</li>
--   </ul>
scanl :: InPairs (ScanNext h g) (x : xs) -> h x -> Telescope g f (x : xs) -> Telescope (Product h g) (Product h f) (x : xs)
instance forall k (g :: k -> *) (xs :: [k]) (f :: k -> *). (Data.SOP.Constraint.All (Data.SOP.Constraint.Compose GHC.Classes.Eq g) xs, Data.SOP.Constraint.All (Data.SOP.Constraint.Compose GHC.Classes.Eq f) xs) => GHC.Classes.Eq (Ouroboros.Consensus.HardFork.Combinator.Util.Telescope.Telescope g f xs)
instance forall k (g :: k -> *) (xs :: [k]) (f :: k -> *). (Data.SOP.Constraint.All (Data.SOP.Constraint.Compose GHC.Classes.Eq g) xs, Data.SOP.Constraint.All (Data.SOP.Constraint.Compose GHC.Classes.Ord g) xs, Data.SOP.Constraint.All (Data.SOP.Constraint.Compose GHC.Classes.Eq f) xs, Data.SOP.Constraint.All (Data.SOP.Constraint.Compose GHC.Classes.Ord f) xs) => GHC.Classes.Ord (Ouroboros.Consensus.HardFork.Combinator.Util.Telescope.Telescope g f xs)
instance forall k (g :: k -> *) (xs :: [k]) (f :: k -> *). (Data.SOP.Constraint.All (Data.SOP.Constraint.Compose GHC.Show.Show g) xs, Data.SOP.Constraint.All (Data.SOP.Constraint.Compose GHC.Show.Show f) xs) => GHC.Show.Show (Ouroboros.Consensus.HardFork.Combinator.Util.Telescope.Telescope g f xs)
instance Data.SOP.Classes.HAp Ouroboros.Consensus.HardFork.Combinator.Util.Telescope.SimpleTelescope
instance Data.SOP.Classes.HTraverse_ Ouroboros.Consensus.HardFork.Combinator.Util.Telescope.SimpleTelescope
instance Data.SOP.Classes.HSequence Ouroboros.Consensus.HardFork.Combinator.Util.Telescope.SimpleTelescope
instance Data.SOP.Classes.HCollapse Ouroboros.Consensus.HardFork.Combinator.Util.Telescope.SimpleTelescope
instance forall k (g :: k -> *). Data.SOP.Classes.HAp (Ouroboros.Consensus.HardFork.Combinator.Util.Telescope.Telescope g)
instance forall k (g :: k -> *). Data.SOP.Classes.HTraverse_ (Ouroboros.Consensus.HardFork.Combinator.Util.Telescope.Telescope g)
instance forall k (g :: k -> *). Data.SOP.Classes.HSequence (Ouroboros.Consensus.HardFork.Combinator.Util.Telescope.Telescope g)
instance forall k (g :: k -> *) (xs :: [k]) (f :: k -> *). (Data.SOP.Constraint.All (Data.SOP.Constraint.Compose NoThunks.Class.NoThunks g) xs, Data.SOP.Constraint.All (Data.SOP.Constraint.Compose NoThunks.Class.NoThunks f) xs) => NoThunks.Class.NoThunks (Ouroboros.Consensus.HardFork.Combinator.Util.Telescope.Telescope g f xs)


-- | Intended for qualified import
--   
--   <pre>
--   import Ouroboros.Consensus.HardFork.Combinator.Util.Match (Mismatch(..))
--   import qualified Ouroboros.Consensus.HardFork.Combinator.Util.Match as Match
--   </pre>
module Ouroboros.Consensus.HardFork.Combinator.Util.Match
data Mismatch :: (k -> Type) -> (k -> Type) -> [k] -> Type
[ML] :: f x -> NS g xs -> Mismatch f g (x : xs)
[MR] :: NS f xs -> g x -> Mismatch f g (x : xs)
[MS] :: Mismatch f g xs -> Mismatch f g (x : xs)
matchNS :: NS f xs -> NS g xs -> Either (Mismatch f g xs) (NS (Product f g) xs)
matchTelescope :: NS h xs -> Telescope g f xs -> Either (Mismatch h f xs) (Telescope g (Product h f) xs)
flip :: Mismatch f g xs -> Mismatch g f xs

-- | Project two <a>NS</a> from a <a>Mismatch</a>
--   
--   We should have the property that
--   
--   <pre>
--   uncurry matchNS (mismatchToNS m) == Left m
--   </pre>
mismatchToNS :: Mismatch f g xs -> (NS f xs, NS g xs)

-- | We cannot give a mismatch if we have only one type variable
mismatchOne :: Mismatch f g '[x] -> Void

-- | If we only have two eras, only two possibilities for a mismatch
mismatchTwo :: Mismatch f g '[x, y] -> Either (f x, g y) (f y, g x)
mkMismatchTwo :: Either (f x, g y) (f y, g x) -> Mismatch f g '[x, y]
mismatchNotEmpty :: Mismatch f g xs -> (forall x xs'. xs ~ (x : xs') => Mismatch f g (x : xs') -> a) -> a
mismatchNotFirst :: Mismatch f g (x : xs) -> Either (NS f xs) (NS g xs)

-- | Variant of <a>matchNS</a> for when we know the two <a>NS</a>s must
--   match. Otherwise an error, mentioning the given <a>String</a>, is
--   thrown.
mustMatchNS :: forall f g xs. HasCallStack => String -> NS f xs -> NS g xs -> NS (Product f g) xs
bihap :: NP (f -.-> f') xs -> NP (g -.-> g') xs -> Mismatch f g xs -> Mismatch f' g' xs
bihmap :: SListI xs => (forall x. f x -> f' x) -> (forall x. g x -> g' x) -> Mismatch f g xs -> Mismatch f' g' xs

-- | Bifunctor analogue of <a>hcmap</a>
bihcmap :: All c xs => proxy c -> (forall x. c x => f x -> f' x) -> (forall x. c x => g x -> g' x) -> Mismatch f g xs -> Mismatch f' g' xs
instance forall k (f :: k -> *) (xs :: [k]) (g :: k -> *). (Data.SOP.Constraint.All (Data.SOP.Constraint.Compose GHC.Classes.Eq f) xs, Data.SOP.Constraint.All (Data.SOP.Constraint.Compose GHC.Classes.Eq g) xs) => GHC.Classes.Eq (Ouroboros.Consensus.HardFork.Combinator.Util.Match.Mismatch f g xs)
instance forall k (f :: k -> *) (xs :: [k]) (g :: k -> *). (Data.SOP.Constraint.All (Data.SOP.Constraint.Compose GHC.Classes.Eq f) xs, Data.SOP.Constraint.All (Data.SOP.Constraint.Compose GHC.Classes.Ord f) xs, Data.SOP.Constraint.All (Data.SOP.Constraint.Compose GHC.Classes.Eq g) xs, Data.SOP.Constraint.All (Data.SOP.Constraint.Compose GHC.Classes.Ord g) xs) => GHC.Classes.Ord (Ouroboros.Consensus.HardFork.Combinator.Util.Match.Mismatch f g xs)
instance forall k (f :: k -> *) (xs :: [k]) (g :: k -> *). (Data.SOP.Constraint.All (Data.SOP.Constraint.Compose GHC.Show.Show f) xs, Data.SOP.Constraint.All (Data.SOP.Constraint.Compose GHC.Show.Show g) xs) => GHC.Show.Show (Ouroboros.Consensus.HardFork.Combinator.Util.Match.Mismatch f g xs)
instance forall k (f :: k -> *) (xs :: [k]) (g :: k -> *). (Data.SOP.Constraint.All (Data.SOP.Constraint.Compose NoThunks.Class.NoThunks f) xs, Data.SOP.Constraint.All (Data.SOP.Constraint.Compose NoThunks.Class.NoThunks g) xs) => NoThunks.Class.NoThunks (Ouroboros.Consensus.HardFork.Combinator.Util.Match.Mismatch f g xs)

module Ouroboros.Consensus.HardFork.Combinator.State.Types

-- | Generic hard fork state
--   
--   This is used both for the consensus state and the ledger state.
newtype HardForkState f xs
HardForkState :: Telescope (K Past) (Current f) xs -> HardForkState f xs
[getHardForkState] :: HardForkState f xs -> Telescope (K Past) (Current f) xs

-- | Information about the current era
data Current f blk
Current :: !Bound -> !f blk -> Current f blk
[currentStart] :: Current f blk -> !Bound
[currentState] :: Current f blk -> !f blk

-- | Information about a past era
data Past
Past :: !Bound -> !Bound -> Past
[pastStart] :: Past -> !Bound
[pastEnd] :: Past -> !Bound

-- | Translate <tt>f x</tt> to <tt>f y</tt> across an era transition
--   
--   Typically <tt>f</tt> will be <tt>LedgerState</tt> or
--   <tt>WrapChainDepState</tt>.
newtype Translate f x y
Translate :: (EpochNo -> f x -> f y) -> Translate f x y
[translateWith] :: Translate f x y -> EpochNo -> f x -> f y

-- | Translate (a forecast of) <tt>f x</tt> to (a forecast of) <tt>f y</tt>
--   across an era transition.
--   
--   Typically <tt>f</tt> will be <tt>WrapLedgerView</tt>.
--   
--   In addition to the <a>Bound</a> of the transition, this is also told
--   the <a>SlotNo</a> we're constructing a forecast for. This enables the
--   translation function to take into account any scheduled changes that
--   the final ledger view in the preceding era might have.
newtype TranslateForecast f g x y
TranslateForecast :: (Bound -> SlotNo -> f x -> Except OutsideForecastRange (Ticked (g y))) -> TranslateForecast f g x y
[translateForecastWith] :: TranslateForecast f g x y -> Bound -> SlotNo -> f x -> Except OutsideForecastRange (Ticked (g y))

-- | Knowledge in a particular era of the transition to the next era
data TransitionInfo

-- | No transition is yet known for this era We instead record the ledger
--   tip (which must be in <i>this</i> era)
--   
--   NOTE: If we are forecasting, this will be set to the slot number of
--   the (past) ledger state in which the forecast was created. This means
--   that when we construct an <tt>EpochInfo</tt> using a
--   <tt>HardForkLedgerView</tt>, the range of that <tt>EpochInfo</tt> will
--   extend a safe zone from that <i>past</i> ledger state.
TransitionUnknown :: !WithOrigin SlotNo -> TransitionInfo

-- | Transition to the next era is known to happen at this <a>EpochNo</a>
TransitionKnown :: !EpochNo -> TransitionInfo

-- | The transition is impossible
--   
--   This can be due to one of two reasons:
--   
--   <ul>
--   <li>We are in the final era</li>
--   <li>This era has not actually begun yet (we are forecasting). In this
--   case, we cannot look past the safe zone of this era and hence, by
--   definition, the transition to the <i>next</i> era cannot happen.</li>
--   </ul>
TransitionImpossible :: TransitionInfo
instance GHC.Generics.Generic (Ouroboros.Consensus.HardFork.Combinator.State.Types.Current f blk)
instance NoThunks.Class.NoThunks Ouroboros.Consensus.HardFork.Combinator.State.Types.Past
instance GHC.Generics.Generic Ouroboros.Consensus.HardFork.Combinator.State.Types.Past
instance GHC.Show.Show Ouroboros.Consensus.HardFork.Combinator.State.Types.Past
instance GHC.Classes.Eq Ouroboros.Consensus.HardFork.Combinator.State.Types.Past
instance NoThunks.Class.NoThunks Ouroboros.Consensus.HardFork.Combinator.State.Types.TransitionInfo
instance GHC.Generics.Generic Ouroboros.Consensus.HardFork.Combinator.State.Types.TransitionInfo
instance GHC.Show.Show Ouroboros.Consensus.HardFork.Combinator.State.Types.TransitionInfo


-- | Lifting functions for the various types used in <a>HardForkState</a>
--   
--   NOTE: These are internal and not exported in the toplevel
--   <tt>.State</tt> module.
module Ouroboros.Consensus.HardFork.Combinator.State.Lift
lift :: (f blk -> f' blk) -> Current f blk -> Current f' blk
liftM :: Functor m => (f blk -> m (f' blk)) -> Current f blk -> m (Current f' blk)

module Ouroboros.Consensus.HardFork.Combinator.Translation
data EraTranslation xs
EraTranslation :: InPairs (RequiringBoth WrapLedgerConfig (Translate LedgerState)) xs -> InPairs (RequiringBoth WrapConsensusConfig (Translate WrapChainDepState)) xs -> InPairs (RequiringBoth WrapLedgerConfig (TranslateForecast LedgerState WrapLedgerView)) xs -> EraTranslation xs
[translateLedgerState] :: EraTranslation xs -> InPairs (RequiringBoth WrapLedgerConfig (Translate LedgerState)) xs
[translateChainDepState] :: EraTranslation xs -> InPairs (RequiringBoth WrapConsensusConfig (Translate WrapChainDepState)) xs
[translateLedgerView] :: EraTranslation xs -> InPairs (RequiringBoth WrapLedgerConfig (TranslateForecast LedgerState WrapLedgerView)) xs
trivialEraTranslation :: EraTranslation '[blk]
instance NoThunks.Class.NoThunks (Ouroboros.Consensus.HardFork.Combinator.Translation.EraTranslation xs)

module Ouroboros.Consensus.HardFork.Combinator.InjectTxs
data InjectTx blk blk'
InjectTx :: (GenTx blk -> Maybe (GenTx blk')) -> InjectTx blk blk'
[injectTxWith] :: InjectTx blk blk' -> GenTx blk -> Maybe (GenTx blk')
cannotInjectTx :: InjectTx blk blk'
matchTx :: SListI xs => InPairs InjectTx xs -> NS GenTx xs -> HardForkState f xs -> Either (Mismatch GenTx (Current f) xs) (HardForkState (Product GenTx f) xs)

module Ouroboros.Consensus.Util.STM

-- | Wait until the TVar changed
blockUntilChanged :: forall stm a b. (MonadSTMTx stm, Eq b) => (a -> b) -> b -> stm a -> stm (a, b)

-- | Spawn a new thread that runs an action each time an STM value changes.
--   
--   NOTE: STM does not guarantee that <a>onEachChange</a> will
--   <i>literally</i> be called on <i>every</i> change: when the system is
--   under heavy load, some updates may be missed.
--   
--   The thread will be linked to the registry.
onEachChange :: forall m a b. (IOLike m, Eq b, HasCallStack) => ResourceRegistry m -> String -> (a -> b) -> Maybe b -> STM m a -> (a -> m ()) -> m (Thread m Void)

-- | Spawn a new thread that waits for an STM value to become <a>Just</a>
--   
--   The thread will be linked to the registry.
runWhenJust :: IOLike m => ResourceRegistry m -> String -> STM m (Maybe a) -> (a -> m ()) -> m ()
blockUntilJust :: MonadSTMTx stm => stm (Maybe a) -> stm a
blockUntilAllJust :: MonadSTMTx stm => [stm (Maybe a)] -> stm [a]

-- | Simple type that can be used to indicate something in a <tt>TVar</tt>
--   is changed.
newtype Fingerprint
Fingerprint :: Word64 -> Fingerprint

-- | Store a value together with its fingerprint.
data WithFingerprint a
WithFingerprint :: !a -> !Fingerprint -> WithFingerprint a
[forgetFingerprint] :: WithFingerprint a -> !a
[getFingerprint] :: WithFingerprint a -> !Fingerprint
newtype Sim n m
Sim :: (forall a. n a -> STM m a) -> Sim n m
[runSim] :: Sim n m -> forall a. n a -> STM m a
simId :: Sim (STM m) m
simStateT :: IOLike m => StrictTVar m st -> Sim n m -> Sim (StateT st n) m
instance NoThunks.Class.NoThunks Ouroboros.Consensus.Util.STM.Fingerprint
instance GHC.Enum.Enum Ouroboros.Consensus.Util.STM.Fingerprint
instance GHC.Generics.Generic Ouroboros.Consensus.Util.STM.Fingerprint
instance GHC.Classes.Eq Ouroboros.Consensus.Util.STM.Fingerprint
instance GHC.Show.Show Ouroboros.Consensus.Util.STM.Fingerprint
instance NoThunks.Class.NoThunks a => NoThunks.Class.NoThunks (Ouroboros.Consensus.Util.STM.WithFingerprint a)
instance GHC.Generics.Generic (Ouroboros.Consensus.Util.STM.WithFingerprint a)
instance GHC.Base.Functor Ouroboros.Consensus.Util.STM.WithFingerprint
instance GHC.Classes.Eq a => GHC.Classes.Eq (Ouroboros.Consensus.Util.STM.WithFingerprint a)
instance GHC.Show.Show a => GHC.Show.Show (Ouroboros.Consensus.Util.STM.WithFingerprint a)

module Ouroboros.Consensus.Storage.ChainDB.API

-- | The chain database
--   
--   The chain database provides a unified interface on top of:
--   
--   <ul>
--   <li>The ImmutableDB, storing the part of the chain that can't roll
--   back.</li>
--   <li>The VolatileDB, storing the blocks near the tip of the chain,
--   possibly in multiple competing forks.</li>
--   <li>The LedgerDB, storing snapshots of the ledger state for blocks in
--   the ImmutableDB (and in-memory snapshots for the rest).</li>
--   </ul>
--   
--   In addition to providing a unifying interface on top of these
--   disparate components, the main responsibilities that the ChainDB
--   itself has are:
--   
--   <ul>
--   <li>Chain selection (on initialization and whenever a block is
--   added)</li>
--   <li>Trigger full recovery whenever we detect disk failure in any
--   component</li>
--   <li>Provide iterators across fixed fragments of the current chain</li>
--   <li>Provide readers that track the status of the current chain</li>
--   </ul>
--   
--   The ChainDB instantiates all the various type parameters of these
--   databases to conform to the unified interface we provide here.
data ChainDB m blk
ChainDB :: (blk -> m (AddBlockPromise m blk)) -> STM m (AnchoredFragment (Header blk)) -> STM m (ExtLedgerState blk) -> (Point blk -> STM m (Maybe (ExtLedgerState blk))) -> STM m (HeaderStateHistory blk) -> m (Maybe blk) -> m (Maybe (Header blk)) -> STM m (Point blk) -> (forall b. BlockComponent blk b -> RealPoint blk -> m (Maybe b)) -> STM m (Point blk -> Bool) -> STM m (RealPoint blk -> Maybe Bool) -> STM m MaxSlotNo -> (forall b. ResourceRegistry m -> BlockComponent blk b -> StreamFrom blk -> StreamTo blk -> m (Either (UnknownRange blk) (Iterator m blk b))) -> (forall b. ResourceRegistry m -> BlockComponent blk b -> m (Reader m blk b)) -> STM m (WithFingerprint (HeaderHash blk -> Maybe (InvalidBlockReason blk))) -> m () -> STM m Bool -> ChainDB m blk

-- | Add a block to the heap of blocks
--   
--   We do <i>not</i> assume that the block is valid (under the legder
--   rules); it is the responsibility of the Chain DB itself to only select
--   chains that are valid.
--   
--   Conversely, the caller cannot assume that the new block will be added
--   to the current chain; even if the block is valid, it will not become
--   part of the chain if there are other chains available that are
--   preferred by the consensus algorithm (typically, longer chains).
--   
--   This function typically returns immediately, yielding a
--   <a>AddBlockPromise</a> which can be used to wait for the result. You
--   can use <a>addBlock</a> to add the block synchronously.
--   
--   NOTE: back pressure can be applied when overloaded.
[addBlockAsync] :: ChainDB m blk -> blk -> m (AddBlockPromise m blk)

-- | Get the current chain fragment
--   
--   Suppose the current chain is
--   
--   <pre>
--   a -&gt; b -&gt; c -&gt; d -&gt; e -&gt; ff
--   </pre>
--   
--   and suppose <tt>k = 2</tt>; this means that the most distant fork we
--   can switch to is something like
--   
--   <pre>
--   a -&gt; b -&gt; c -&gt; d -&gt; e' -&gt; f'
--   </pre>
--   
--   The fragment we return will be <tt>[e, f]</tt>, anchored at
--   <tt>d</tt>. In other words, the length of the fragment will under
--   normal circumstances be exactly <tt>k</tt> blocks long. It may be
--   shorter if
--   
--   <ul>
--   <li>We are near genesis The anchor will be the genesis point (which
--   does not correspond to an actual block)</li>
--   <li>The volatile DB suffered some data loss Typically (but not
--   necessarily) the immutable DB will not be empty and the anchor will be
--   pointing to the tip of the immutable DB.</li>
--   </ul>
--   
--   POSTCONDITION: The Chain DB will be able to switch to any fork
--   starting from the anchor of the returned fragment or any subsequent
--   block (provided the new fork is at least of the same length as the
--   old).
--   
--   NOTE: A direct consequence of this guarantee is that the anchor of the
--   fragment will move as the chain grows.
[getCurrentChain] :: ChainDB m blk -> STM m (AnchoredFragment (Header blk))

-- | Get current ledger
[getCurrentLedger] :: ChainDB m blk -> STM m (ExtLedgerState blk)

-- | Get the ledger for the given point.
--   
--   When the given point is not among the last <tt>k</tt> blocks of the
--   current chain (i.e., older than <tt>k</tt> or not on the current
--   chain), <a>Nothing</a> is returned.
[getPastLedger] :: ChainDB m blk -> Point blk -> STM m (Maybe (ExtLedgerState blk))

-- | Get a <a>HeaderStateHistory</a> populated with the
--   <tt>HeaderState</tt>s of the last <tt>k</tt> blocks of the current
--   chain.
[getHeaderStateHistory] :: ChainDB m blk -> STM m (HeaderStateHistory blk)

-- | Get block at the tip of the chain, if one exists
--   
--   Returns <a>Nothing</a> if the database is empty.
[getTipBlock] :: ChainDB m blk -> m (Maybe blk)

-- | Get header at the tip of the chain
--   
--   NOTE: Calling <a>getTipHeader</a> is cheaper than <a>getTipBlock</a>
--   and then extracting the header: most of the time the header at the tip
--   is actually in memory, whereas the block never is.
--   
--   Returns <a>Nothing</a> if the database is empty.
[getTipHeader] :: ChainDB m blk -> m (Maybe (Header blk))

-- | Get point of the tip of the chain
--   
--   Will return <tt>genesisPoint</tt> if the database is empty; if the
--   current chain fragment is empty due to data loss in the volatile DB,
--   <a>getTipPoint</a> will return the tip of the immutable DB.
[getTipPoint] :: ChainDB m blk -> STM m (Point blk)

-- | Get the given component(s) of the block at the specified point. If
--   there is no block at the given point, <a>Nothing</a> is returned.
[getBlockComponent] :: ChainDB m blk -> forall b. BlockComponent blk b -> RealPoint blk -> m (Maybe b)

-- | Return membership check function for recent blocks
--   
--   This check is only reliable for blocks up to <tt>k</tt> away from the
--   tip. For blocks older than that the results should be regarded as
--   non-deterministic.
[getIsFetched] :: ChainDB m blk -> STM m (Point blk -> Bool)

-- | Return a function that tells whether a block is known to be valid or
--   invalid.
--   
--   The function will return:
--   
--   <ul>
--   <li><tt>Just True</tt>: for blocks in the volatile DB that have been
--   validated and were found to be valid. All blocks in the current chain
--   fragment (i.e., <a>getCurrentChain</a>) are valid.</li>
--   <li><tt>Just False</tt>: for blocks in the volatile DB that have been
--   validated and were found to be invalid.</li>
--   <li><tt>Nothing</tt>: for blocks not or no longer in the volatile DB,
--   whether they are valid or not, including blocks in the immutable DB.
--   Also for blocks in the volatile DB that haven't been validated (yet),
--   e.g., because they are disconnected from the current chain or they are
--   part of a shorter fork.</li>
--   </ul>
[getIsValid] :: ChainDB m blk -> STM m (RealPoint blk -> Maybe Bool)

-- | Get the highest slot number stored in the ChainDB.
--   
--   Note that the corresponding block doesn't have to be part of the
--   current chain, it could be part of some fork, or even be a
--   disconnected block.
[getMaxSlotNo] :: ChainDB m blk -> STM m MaxSlotNo

-- | Stream blocks
--   
--   Streaming is not restricted to the current fork, but there must be an
--   unbroken path from the starting point to the end point /at the time of
--   initialization/ of the iterator. Once the iterator has been
--   initialized, it will not be affected by subsequent calls to
--   <a>addBlock</a>. To track the current chain, use a <a>Reader</a>
--   instead.
--   
--   Streaming blocks older than <tt>k</tt> is permitted, but only when
--   they are part of the current fork (at the time of initialization).
--   Streaming a fork that forks off more than <tt>k</tt> blocks in the
--   past is not permitted and an <a>UnknownRange</a> error will be
--   returned in that case.
--   
--   The iterator <i>does</i> have a limited lifetime, however. The chain
--   DB internally partitions the chain into an " immutable " part and a "
--   volatile " part, moving blocks from the volatile DB to the immutable
--   DB when they become more than <tt>k</tt> deep into the chain. When a
--   block with slot number <tt>n</tt> is added to the immutble DB, a time
--   delay <tt>t</tt> kicks in; after that time delay expires, all blocks
--   older than <tt>n</tt> may be removed from the volatile DB, /including
--   any blocks that happen to live on other forks/ (since those forks must
--   now, by definition, be too distant). This time delay <tt>t</tt> also
--   provides a worst-case bound for the lifetime of the iterator: if the
--   iterator traverses a chain that forks off from our current chain at
--   the tip of the immutable DB, then the first block on that fork will
--   become unavailable as soon as another block is pushed to the current
--   chain and the subsequent time delay expires.
--   
--   Note: although blocks are moved from the volatile DB to the immutable
--   DB after they have become <tt>k</tt> deep into the chain, due to data
--   corruption the suffix of the chain in the volatile DB might be shorter
--   than <tt>k</tt>. The immutable DB <i>always</i> determines the maximum
--   rollback, which may therefore be shorter than <tt>k</tt> under such
--   circumstances. In addition, streaming blocks which aren't on the
--   current fork is permitted, but the oldest volatile block must fit on
--   to the tip of the immutable DB.
--   
--   When the given bounds are nonsensical, an <a>InvalidIteratorRange</a>
--   is thrown.
--   
--   When the given bounds are not part of the chain DB, an
--   <a>UnknownRange</a> error is returned.
--   
--   To stream all blocks from the current chain, use <a>streamAll</a>, as
--   it correctly handles an empty ChainDB.
[stream] :: ChainDB m blk -> forall b. ResourceRegistry m -> BlockComponent blk b -> StreamFrom blk -> StreamTo blk -> m (Either (UnknownRange blk) (Iterator m blk b))

-- | Chain reader
--   
--   A chain reader is an iterator that tracks the state of the
--   <i>current</i> chain: calling <tt>next</tt> on the iterator will
--   either give you the next block header, or (if we have switched to a
--   fork) the instruction to rollback.
--   
--   The tracking iterator starts at genesis (see also
--   <tt>trackForward</tt>).
--   
--   This is intended for use by chain consumers to <i>reliably</i> follow
--   a chain, desipite the chain being volatile.
--   
--   Examples of users: * The server side of the chain sync mini-protocol
--   for the node-to-node protocol using headers and the block size. * The
--   server side of the chain sync mini-protocol for the node-to-client
--   protocol using blocks.
[newReader] :: ChainDB m blk -> forall b. ResourceRegistry m -> BlockComponent blk b -> m (Reader m blk b)

-- | Function to check whether a block is known to be invalid.
--   
--   Blocks unknown to the ChainDB will result in <a>False</a>.
--   
--   If the hash corresponds to a block that is known to be invalid, but is
--   now older than <tt>k</tt>, this function may return <a>False</a>.
--   
--   Whenever a new invalid block is added, the <tt>Fingerprint</tt> will
--   be changed. This is useful when "watching" this function in a
--   transaction.
--   
--   Note that when invalid blocks are garbage collected and thus no longer
--   detected by this function, the <tt>Fingerprint</tt> doesn't have to
--   change, since the function will not detect new invalid blocks.
[getIsInvalidBlock] :: ChainDB m blk -> STM m (WithFingerprint (HeaderHash blk -> Maybe (InvalidBlockReason blk)))

-- | Close the ChainDB
--   
--   Idempotent.
--   
--   Should only be called on shutdown.
[closeDB] :: ChainDB m blk -> m ()

-- | Return <a>True</a> when the database is open.
--   
--   <a>False</a> when the database is closed.
[isOpen] :: ChainDB m blk -> STM m Bool
getCurrentTip :: (Monad (STM m), HasHeader (Header blk)) => ChainDB m blk -> STM m (Tip blk)
getTipBlockNo :: (Monad (STM m), HasHeader (Header blk)) => ChainDB m blk -> STM m (WithOrigin BlockNo)
data AddBlockPromise m blk
AddBlockPromise :: STM m Bool -> STM m (Point blk) -> AddBlockPromise m blk

-- | Use this <a>STM</a> transaction to wait until the block has been
--   written to disk.
--   
--   Returns <a>True</a> when the block was written to disk or <a>False</a>
--   when it was ignored, e.g., because it was older than <tt>k</tt>.
--   
--   If the <a>STM</a> transaction has returned <a>True</a> then
--   <a>getIsFetched</a> will return <a>True</a> for the added block.
--   
--   NOTE: Even when the result is <a>False</a>, <a>getIsFetched</a> might
--   still return <a>True</a>, e.g., the block was older than <tt>k</tt>,
--   but it has been downloaded and stored on disk before.
[blockWrittenToDisk] :: AddBlockPromise m blk -> STM m Bool

-- | Use this <a>STM</a> transaction to wait until the block has been
--   processed: the block has been written to disk and chain selection has
--   been performed for the block, <i>unless</i> the block is from the
--   future.
--   
--   The ChainDB's tip after chain selection is returned. When this tip
--   doesn't match the added block, it doesn't necessarily mean the block
--   wasn't adopted. We might have adopted a longer chain of which the
--   added block is a part, but not the tip.
--   
--   NOTE: When the block is from the future, chain selection for the block
--   won't be performed until the block is no longer in the future, which
--   might take some time. For that reason, this transaction will not wait
--   for chain selection of a block from the future. It will return the
--   current tip of the ChainDB after writing the block to disk.
[blockProcessed] :: AddBlockPromise m blk -> STM m (Point blk)

-- | Add a block synchronously: wait until the block has been written to
--   disk (see <a>blockWrittenToDisk</a>).
addBlockWaitWrittenToDisk :: IOLike m => ChainDB m blk -> blk -> m Bool

-- | Add a block synchronously: wait until the block has been processed
--   (see <a>blockProcessed</a>). The new tip of the ChainDB is returned.
addBlock :: IOLike m => ChainDB m blk -> blk -> m (Point blk)

-- | Add a block synchronously. Variant of <a>addBlock</a> that doesn't
--   return the new tip of the ChainDB.
addBlock_ :: IOLike m => ChainDB m blk -> blk -> m ()

-- | A <tt>b</tt> together with its <a>Point</a>.
--   
--   The <a>Point</a> is needed because we often need to know the hash,
--   slot, or point itself of the block or header in question, and we don't
--   want to deserialise the block to obtain it.
data WithPoint blk b
WithPoint :: !b -> !Point blk -> WithPoint blk b
[withoutPoint] :: WithPoint blk b -> !b
[point] :: WithPoint blk b -> !Point blk
getSerialisedBlockWithPoint :: BlockComponent blk (WithPoint blk (Serialised blk))
getSerialisedHeaderWithPoint :: BlockComponent blk (WithPoint blk (SerialisedHeader blk))
getPoint :: BlockComponent blk (Point blk)

-- | Which component of the block to read from a database: the whole block,
--   its header, its hash, the block size, ..., or combinations thereof.
--   
--   NOTE: when requesting multiple components, we will not optimise/cache
--   them.
data BlockComponent blk a

-- | Verify the integrity of the block by checking its signature and/or
--   hashes. The interpreter should throw an exception when the block does
--   not pass the check.
[GetVerifiedBlock] :: BlockComponent blk blk
[GetBlock] :: BlockComponent blk blk
[GetRawBlock] :: BlockComponent blk ByteString
[GetHeader] :: BlockComponent blk (Header blk)
[GetRawHeader] :: BlockComponent blk ByteString
[GetHash] :: BlockComponent blk (HeaderHash blk)
[GetSlot] :: BlockComponent blk SlotNo
[GetIsEBB] :: BlockComponent blk IsEBB
[GetBlockSize] :: BlockComponent blk Word32
[GetHeaderSize] :: BlockComponent blk Word16
[GetNestedCtxt] :: BlockComponent blk (SomeSecond (NestedCtxt Header) blk)
[GetPure] :: a -> BlockComponent blk a
[GetApply] :: BlockComponent blk (a -> b) -> BlockComponent blk a -> BlockComponent blk b
toChain :: forall m blk. (HasCallStack, IOLike m, HasHeader blk) => ChainDB m blk -> m (Chain blk)
fromChain :: forall m blk. IOLike m => m (ChainDB m blk) -> Chain blk -> m (ChainDB m blk)

-- | The lower bound for an iterator
--   
--   Hint: use <tt><a>StreamFromExclusive</a> <tt>genesisPoint</tt></tt> to
--   start streaming from Genesis.
data StreamFrom blk
StreamFromInclusive :: !RealPoint blk -> StreamFrom blk
StreamFromExclusive :: !Point blk -> StreamFrom blk
newtype StreamTo blk
StreamToInclusive :: RealPoint blk -> StreamTo blk
data Iterator m blk b
Iterator :: m (IteratorResult blk b) -> m () -> Iterator m blk b
[iteratorNext] :: Iterator m blk b -> m (IteratorResult blk b)

-- | When <a>fmap</a>-ing or <a>traverse</a>-ing (or using
--   <a>traverseIterator</a>) an <a>Iterator</a>, the resulting iterator
--   will still refer to and use the original one. This means that when
--   either of them is closed, both will be closed in practice.
[iteratorClose] :: Iterator m blk b -> m ()
data IteratorResult blk b
IteratorExhausted :: IteratorResult blk b
IteratorResult :: b -> IteratorResult blk b

-- | The block that was supposed to be streamed was garbage-collected from
--   the VolatileDB, but not added to the ImmutableDB.
--   
--   This will only happen when streaming very old forks very slowly.
IteratorBlockGCed :: RealPoint blk -> IteratorResult blk b

-- | An iterator that is immediately exhausted.
emptyIterator :: Monad m => Iterator m blk b

-- | Variant of <a>traverse</a> instantiated to <tt><a>Iterator</a> m
--   blk</tt> that executes the monadic function when calling
--   <a>iteratorNext</a>.
traverseIterator :: Monad m => (b -> m b') -> Iterator m blk b -> Iterator m blk b'
data UnknownRange blk

-- | The block at the given point was not found in the ChainDB.
MissingBlock :: RealPoint blk -> UnknownRange blk

-- | The requested range forks off too far in the past, i.e. it doesn't fit
--   on the tip of the ImmutableDB.
ForkTooOld :: StreamFrom blk -> UnknownRange blk

-- | Check whether the bounds make sense
--   
--   An example of bounds that don't make sense:
--   
--   <pre>
--   StreamFromExclusive (BlockPoint 3 ..)
--   StreamToInclusive   (RealPoint  3 ..)
--   </pre>
--   
--   This function does not check whether the bounds correspond to existing
--   blocks.
validBounds :: StandardHash blk => StreamFrom blk -> StreamTo blk -> Bool

-- | Stream all blocks from the current chain.
--   
--   To stream all blocks from the current chain from the ChainDB, one
--   would use <tt><a>StreamFromExclusive</a> <tt>genesisPoint</tt></tt> as
--   the lower bound and <tt><a>StreamToInclusive</a> tip</tt> as the upper
--   bound where <tt>tip</tt> is retrieved with <a>getTipPoint</a>.
--   
--   However, when the ChainDB is empty, <tt>tip</tt> will be
--   <tt>genesisPoint</tt> too, in which case the bounds don't make sense.
--   This function correctly handles this case.
--   
--   Note that this is not a <a>Reader</a>, so the stream will not include
--   blocks that are added to the current chain after starting the stream.
streamAll :: (MonadSTM m, HasHeader blk, HasCallStack) => ChainDB m blk -> ResourceRegistry m -> BlockComponent blk b -> m (Iterator m blk b)

-- | The reason why a block is invalid.
data InvalidBlockReason blk

-- | The ledger found the block to be invalid.
ValidationError :: !ExtValidationError blk -> InvalidBlockReason blk

-- | The block's slot is in the future, exceeding the allowed clock skew.
--   
--   Possible causes, order by decreasing likelihood:
--   
--   <ol>
--   <li>Our clock is behind (significantly more likely than the
--   others)</li>
--   <li>Their clock is ahead</li>
--   <li>It's intentional, i.e., an attack</li>
--   </ol>
InFutureExceedsClockSkew :: !RealPoint blk -> InvalidBlockReason blk

-- | Reader
--   
--   See <tt>newHeaderReader</tt> for more info.
--   
--   The type parameter <tt>a</tt> will be instantiated with <tt>blk</tt>
--   or <tt>Header </tt>blk@.
data Reader m blk a
Reader :: m (Maybe (ChainUpdate blk a)) -> m (ChainUpdate blk a) -> ([Point blk] -> m (Maybe (Point blk))) -> m () -> Reader m blk a

-- | The next chain update (if one exists)
--   
--   Not in <tt>STM</tt> because might have to read the blocks or headers
--   from disk.
--   
--   We may roll back more than <tt>k</tt>, but only in case of data loss.
[readerInstruction] :: Reader m blk a -> m (Maybe (ChainUpdate blk a))

-- | Blocking version of <a>readerInstruction</a>
[readerInstructionBlocking] :: Reader m blk a -> m (ChainUpdate blk a)

-- | Move the reader forward
--   
--   Must be given a list of points in order of preference; the iterator
--   will move forward to the first point on the list that is on the
--   current chain. Returns <a>Nothing</a> if the iterator did not move, or
--   the new point otherwise.
--   
--   When successful, the first call to <a>readerInstruction</a> after
--   <a>readerForward</a> will be a <tt>RollBack</tt> to the point returned
--   by <a>readerForward</a>.
--   
--   Cannot live in <tt>STM</tt> because the points specified might live in
--   the immutable DB.
[readerForward] :: Reader m blk a -> [Point blk] -> m (Maybe (Point blk))

-- | Close the reader.
--   
--   Idempotent.
--   
--   After closing, all other operations on the reader will throw
--   <a>ClosedReaderError</a>.
[readerClose] :: Reader m blk a -> m ()

-- | Variant of <a>traverse</a> instantiated to <tt><a>Reader</a> m
--   blk</tt> that executes the monadic function when calling
--   <a>readerInstruction</a> and <a>readerInstructionBlocking</a>.
traverseReader :: Monad m => (b -> m b') -> Reader m blk b -> Reader m blk b'

-- | Database failure
--   
--   This exception wraps any kind of unexpected problem with the on-disk
--   storage of the chain.
--   
--   The various constructors only serve to give more detailed information
--   about what went wrong, in case sysadmins want to investigate the disk
--   failure. The Chain DB itself does not differentiate; all disk failures
--   are treated equal and all trigger the same recovery procedure.
data ChainDbFailure

-- | The ledger DB threw a file-system error
LgrDbFailure :: FsError -> ChainDbFailure

-- | Block missing from the chain DB
--   
--   Thrown when we are not sure in which DB the block <i>should</i> have
--   been.
ChainDbMissingBlock :: RealPoint blk -> ChainDbFailure

-- | Whether a block is an Epoch Boundary Block (EBB)
--   
--   See <a>Ouroboros.Storage.ImmutableDB.API</a> for a discussion of EBBs.
--   Key idiosyncracies:
--   
--   <ul>
--   <li>An EBB carries no unique information.</li>
--   <li>An EBB has the same <tt>BlockNo</tt> as its predecessor.</li>
--   <li>EBBs are vestigial. As of Shelley, nodes no longer forge EBBs:
--   they are only a legacy/backwards-compatibility concern.</li>
--   </ul>
data IsEBB
IsEBB :: IsEBB
IsNotEBB :: IsEBB

-- | Database error
--   
--   Thrown upon incorrect use: invalid input.
data ChainDbError

-- | The ChainDB is closed.
--   
--   This will be thrown when performing any operation on the ChainDB
--   except for <a>isOpen</a> and <a>closeDB</a>. The <tt>CallStack</tt> of
--   the operation on the ChainDB is included in the error.
ClosedDBError :: PrettyCallStack -> ChainDbError

-- | The reader is closed.
--   
--   This will be thrown when performing any operation on a closed readers,
--   except for <a>readerClose</a>.
ClosedReaderError :: ChainDbError

-- | When there is no chain/fork that satisfies the bounds passed to
--   <tt>streamBlocks</tt>.
--   
--   <ul>
--   <li>The lower and upper bound are not on the same chain.</li>
--   <li>The bounds don't make sense, e.g., the lower bound starts after
--   the upper bound, or the lower bound starts from genesis,
--   <i>inclusive</i>.</li>
--   </ul>
InvalidIteratorRange :: StreamFrom blk -> StreamTo blk -> ChainDbError
instance Data.Traversable.Traversable (Ouroboros.Consensus.Storage.ChainDB.API.IteratorResult blk)
instance Data.Foldable.Foldable (Ouroboros.Consensus.Storage.ChainDB.API.IteratorResult blk)
instance GHC.Base.Functor (Ouroboros.Consensus.Storage.ChainDB.API.IteratorResult blk)
instance Data.Traversable.Traversable m => Data.Traversable.Traversable (Ouroboros.Consensus.Storage.ChainDB.API.Iterator m blk)
instance Data.Foldable.Foldable m => Data.Foldable.Foldable (Ouroboros.Consensus.Storage.ChainDB.API.Iterator m blk)
instance GHC.Base.Functor m => GHC.Base.Functor (Ouroboros.Consensus.Storage.ChainDB.API.Iterator m blk)
instance Ouroboros.Network.Block.StandardHash blk => GHC.Show.Show (Ouroboros.Consensus.Storage.ChainDB.API.UnknownRange blk)
instance Ouroboros.Network.Block.StandardHash blk => GHC.Classes.Eq (Ouroboros.Consensus.Storage.ChainDB.API.UnknownRange blk)
instance GHC.Generics.Generic (Ouroboros.Consensus.Storage.ChainDB.API.InvalidBlockReason blk)
instance Ouroboros.Consensus.Ledger.SupportsProtocol.LedgerSupportsProtocol blk => GHC.Show.Show (Ouroboros.Consensus.Storage.ChainDB.API.InvalidBlockReason blk)
instance Ouroboros.Consensus.Ledger.SupportsProtocol.LedgerSupportsProtocol blk => GHC.Classes.Eq (Ouroboros.Consensus.Storage.ChainDB.API.InvalidBlockReason blk)
instance GHC.Base.Functor m => GHC.Base.Functor (Ouroboros.Consensus.Storage.ChainDB.API.Reader m blk)
instance (GHC.Classes.Eq blk, GHC.Classes.Eq b, Ouroboros.Network.Block.StandardHash blk) => GHC.Classes.Eq (Ouroboros.Consensus.Storage.ChainDB.API.IteratorResult blk b)
instance (GHC.Show.Show blk, GHC.Show.Show b, Ouroboros.Network.Block.StandardHash blk) => GHC.Show.Show (Ouroboros.Consensus.Storage.ChainDB.API.IteratorResult blk b)
instance GHC.Show.Show Ouroboros.Consensus.Storage.ChainDB.API.ChainDbFailure
instance GHC.Show.Show Ouroboros.Consensus.Storage.ChainDB.API.ChainDbError
instance GHC.Exception.Type.Exception Ouroboros.Consensus.Storage.ChainDB.API.ChainDbError
instance GHC.Exception.Type.Exception Ouroboros.Consensus.Storage.ChainDB.API.ChainDbFailure
instance Ouroboros.Consensus.Ledger.SupportsProtocol.LedgerSupportsProtocol blk => NoThunks.Class.NoThunks (Ouroboros.Consensus.Storage.ChainDB.API.InvalidBlockReason blk)
instance Ouroboros.Network.Block.StandardHash blk => Ouroboros.Network.Block.StandardHash (Ouroboros.Consensus.Storage.ChainDB.API.WithPoint blk b)


-- | Intended for qualified import
--   
--   <pre>
--   import Ouroboros.Consensus.Storage.ChainDB.Init (InitChainDB)
--   import qualified Ouroboros.Consensus.Storage.ChainDB.Init as InitChainDB
--   </pre>
module Ouroboros.Consensus.Storage.ChainDB.Init

-- | Restricted interface to the <a>ChainDB</a> used on node initialization
newtype InitChainDB m blk
InitChainDB :: (m blk -> m ()) -> InitChainDB m blk

-- | Add a block to the DB when the current chain is empty.
--   
--   The given action is only called when the current chain is empty.
[addBlockIfEmpty] :: InitChainDB m blk -> m blk -> m ()
fromFull :: IOLike m => ChainDB m blk -> InitChainDB m blk
cast :: (Functor m, Coercible blk blk') => InitChainDB m blk -> InitChainDB m blk'
instance GHC.Base.Functor m => Data.Functor.Contravariant.Contravariant (Ouroboros.Consensus.Storage.ChainDB.Init.InitChainDB m)

module Ouroboros.Consensus.Node.InitStorage

-- | Functionality needed to initialise the storage layer of the node.
class NodeInitStorage blk

-- | The <a>ChunkInfo</a> to use for the ImmutableDB, i.e., how many slots
--   to put together in a single chunk file.
--   
--   For example, for Byron, one would use the epoch size.
nodeImmutableDbChunkInfo :: NodeInitStorage blk => StorageConfig blk -> ChunkInfo

-- | Check the integrity of a block, i.e., that it has not been corrupted
--   by a bitflip.
--   
--   Check this by, e.g., verifying whether the block has a valid signature
--   and that the hash of the body matches the body hash stores in the
--   header.
--   
--   This does not check the validity of the contents of the block, e.g.,
--   whether the transactions are valid w.r.t. the ledger, or whether it's
--   sent by a malicious node.
nodeCheckIntegrity :: NodeInitStorage blk => StorageConfig blk -> blk -> Bool

-- | This function is called when starting up the node, right after the
--   ChainDB was opened, and before we connect to other nodes and start
--   block production.
--   
--   This function can be used to, for example, create the genesis EBB in
--   case the chain(DB) is empty.
--   
--   We only provide a limited interface to the chain DB. This is primarily
--   useful for the definition of combinators (which may need to turn a
--   <a>InitChainDB</a> for one type of block into an <a>InitChainDB</a>
--   for a closely related type of block).
nodeInitChainDB :: (NodeInitStorage blk, IOLike m) => StorageConfig blk -> InitChainDB m blk -> m ()

module Ouroboros.Consensus.Storage.ChainDB.Impl.Paths

-- | Return the block info for the block with the given hash. Return
--   <a>Nothing</a> when not in the VolatileDB.
type LookupBlockInfo blk = HeaderHash blk -> Maybe (BlockInfo blk)

-- | Compute all candidates starting at the specified point
--   
--   PRECONDITION: the block to which the given point corresponds is part
--   of the VolatileDB.
--   
--   The first element in each list of hashes is the hash <i>after</i> the
--   specified hash. Thus, when building fragments from these lists of
--   hashes, they fragments must be <i>anchored</i> at the specified hash,
--   but not contain it.
--   
--   NOTE: it is possible that no candidates are found, but don't forget
--   that the chain (fragment) ending with <tt>B</tt> is also a potential
--   candidate.
candidates :: forall blk. (ChainHash blk -> Set (HeaderHash blk)) -> Point blk -> [NonEmpty (HeaderHash blk)]

-- | Extend the <a>ChainDiff</a> with the successors found by
--   <a>candidates</a>.
--   
--   In case no successors were found, the original <a>ChainDiff</a> is
--   returned as a singleton.
--   
--   In case successors <i>were</i> found, the original <a>ChainDiff</a> is
--   <i>not</i> included, only its extensions.
--   
--   Only the longest possible extensions are returned, no intermediary
--   prefixes of extensions.
extendWithSuccessors :: forall blk. HasHeader blk => (ChainHash blk -> Set (HeaderHash blk)) -> LookupBlockInfo blk -> ChainDiff (HeaderFields blk) -> NonEmpty (ChainDiff (HeaderFields blk))

-- | A path through the VolatileDB from a <a>StreamFrom</a> to a
--   <a>StreamTo</a>.
--   
--   Invariant: the <tt>ChainFragment</tt> (oldest first) constructed using
--   the blocks corresponding to the points in the path will be valid,
--   i.e., the blocks will fit onto each other.
data Path blk

-- | The <tt>end</tt> point (<tt><a>StreamToInclusive</a> end</tt>) was not
--   part of the VolatileDB.
NotInVolatileDB :: RealPoint blk -> Path blk

-- | A complete path, from start point to end point was constructed from
--   the VolatileDB. The list contains the points from oldest to newest.
--   
--   <ul>
--   <li>If the lower bound was <tt><a>StreamFromInclusive</a> pt</tt>,
--   then <tt>pt</tt> will be the first element of the list.</li>
--   <li>If the lower bound was <tt><a>StreamFromExclusive</a> pt</tt>,
--   then the first element of the list will correspond to the first block
--   after <tt>pt</tt>.</li>
--   <li>If the upper bound was <tt><a>StreamToInclusive</a> pt</tt>, then
--   <tt>pt</tt> will be the last element of the list.</li>
--   </ul>
CompletelyInVolatileDB :: [RealPoint blk] -> Path blk

-- | Only a partial path could be constructed from the VolatileDB. The
--   missing predecessor could still be in the ImmutableDB. The list
--   contains the points from oldest to newest.
--   
--   <ul>
--   <li>The first element in the list is the point for which no
--   predecessor is available in the VolatileDB. The block corresponding to
--   the point itself, <i>is</i> available in the VolatileDB.</li>
--   <li>The first argument is the hash of predecessor, the block that is
--   not available in the VolatileDB.</li>
--   </ul>
--   
--   Note: if the lower bound is exclusive, the block corresponding to it
--   doesn't have to be part of the VolatileDB, it will result in a
--   <tt>StartToEnd</tt>.
--   
--   The same invariants hold for the upper bound as for
--   <tt>StartToEnd</tt>.
PartiallyInVolatileDB :: HeaderHash blk -> [RealPoint blk] -> Path blk

-- | Construct a path backwards through the VolatileDB.
--   
--   We walk backwards through the VolatileDB, constructing a <a>Path</a>
--   from the <a>StreamTo</a> to the <a>StreamFrom</a>.
--   
--   If the range is invalid, <a>Nothing</a> is returned.
--   
--   See the documentation of <a>Path</a>.
computePath :: forall blk. HasHeader blk => LookupBlockInfo blk -> StreamFrom blk -> StreamTo blk -> Maybe (Path blk)

-- | A reverse path through the VolatileDB starting at a block in the
--   VolatileDB until we reach genesis or leave the VolatileDB.
data ReversePath blk

-- | The path stopped at genesis
StoppedAtGenesis :: ReversePath blk

-- | The path stopped at this hash, which is the hash of the predecessor of
--   the last block in the path (that was still stored in the VolatileDB).
--   
--   The block corresponding to the predecessor is <i>not</i> stored in the
--   VolatileDB. Either because it is missing, or because it is old and has
--   been garbage collected.
--   
--   Since block numbers are consecutive, we subtract 1 from the block
--   number of the last block to obtain the block number corresponding to
--   this hash.
--   
--   EBBs share their block number with their predecessor:
--   
--   <pre>
--   block:         regular block 1 | EBB | regular block 2
--   block number:                X |   X | X + 1
--   </pre>
--   
--   So when the hash refers to regular block 1, we see that the successor
--   block is an EBB and use its block number without subtracting 1.
--   
--   Edge case: if there are two or more consecutive EBBs, we might predict
--   the wrong block number, but there are no consecutive EBBs in practice,
--   they are one epoch apart.
StoppedAt :: HeaderHash blk -> BlockNo -> ReversePath blk

-- | Snoc: the block with the given <a>HeaderFields</a> is in the
--   VolatileDB. We also track whether it is an EBB or not.
--   
--   NOTE: we are intentionally lazy in the spine, as constructing the path
--   requires lookups in the VolatileDB's in-memory indices, which are
--   logarithmic in the size of the index.
(::>) :: ReversePath blk -> (HeaderFields blk, IsEBB) -> ReversePath blk

-- | Lazily compute the <a>ReversePath</a> that starts (i.e., ends) with
--   the given <a>HeaderHash</a>.
computeReversePath :: forall blk. LookupBlockInfo blk -> HeaderHash blk -> Maybe (ReversePath blk)

-- | Try to connect the point <tt>P</tt> to the chain fragment by chasing
--   the predecessors.
--   
--   When successful, return a <a>ChainDiff</a>: the number of blocks to
--   roll back the chain fragment to the intersection point and a fragment
--   anchored at the intersection point containing the <a>HeaderFields</a>
--   corresponding to the blocks needed to connect to <tt>P</tt>. The
--   intersection point will be the most recent intersection point.
--   
--   Returns <a>Nothing</a> when <tt>P</tt> is not in the VolatileDB or
--   when <tt>P</tt> is not connected to the given chain fragment.
--   
--   POSTCONDITION: the returned number of blocks to roll back is less than
--   or equal to the length of the given chain fragment.
--   
--   Note that the number of returned points can be smaller than the number
--   of blocks to roll back. This means <tt>P</tt> is on a fork shorter
--   than the given chain fragment.
--   
--   A <a>ChainDiff</a> is returned iff <tt>P</tt> is on the chain
--   fragment. Moreover, when the number of blocks to roll back is also 0,
--   it must be that <tt>P</tt> is the tip of the chain fragment.
--   
--   When the suffix of the <a>ChainDiff</a> is non-empty, <tt>P</tt> will
--   be the last point in the suffix.
isReachable :: forall blk. (HasHeader blk, GetHeader blk, HasCallStack) => LookupBlockInfo blk -> AnchoredFragment (Header blk) -> RealPoint blk -> Maybe (ChainDiff (HeaderFields blk))
instance Ouroboros.Network.Block.HasHeader blk => GHC.Classes.Eq (Ouroboros.Consensus.Storage.ChainDB.Impl.Paths.Path blk)
instance Ouroboros.Network.Block.HasHeader blk => GHC.Show.Show (Ouroboros.Consensus.Storage.ChainDB.Impl.Paths.Path blk)


-- | Thin wrapper around the LedgerDB
module Ouroboros.Consensus.Storage.ChainDB.Impl.LgrDB

-- | Thin wrapper around the ledger database
data LgrDB m blk
type LedgerDB' blk = LedgerDB (ExtLedgerState blk) (RealPoint blk)

-- | <a>EncodeDisk</a> and <a>DecodeDisk</a> constraints needed for the
--   LgrDB.
type LgrDbSerialiseConstraints blk = (Serialise (HeaderHash blk), EncodeDisk blk (LedgerState blk), DecodeDisk blk (LedgerState blk), EncodeDisk blk (AnnTip blk), DecodeDisk blk (AnnTip blk), EncodeDisk blk (ChainDepState (BlockProtocol blk)), DecodeDisk blk (ChainDepState (BlockProtocol blk)))
data LgrDbArgs f m blk
LgrDbArgs :: HKD f DiskPolicy -> HKD f (m (ExtLedgerState blk)) -> SomeHasFS m -> HKD f LedgerDbParams -> HKD f (TopLevelConfig blk) -> Tracer m (LedgerDB' blk) -> Tracer m (TraceEvent blk) -> LgrDbArgs f m blk
[lgrDiskPolicy] :: LgrDbArgs f m blk -> HKD f DiskPolicy
[lgrGenesis] :: LgrDbArgs f m blk -> HKD f (m (ExtLedgerState blk))
[lgrHasFS] :: LgrDbArgs f m blk -> SomeHasFS m
[lgrParams] :: LgrDbArgs f m blk -> HKD f LedgerDbParams
[lgrTopLevelConfig] :: LgrDbArgs f m blk -> HKD f (TopLevelConfig blk)
[lgrTraceLedger] :: LgrDbArgs f m blk -> Tracer m (LedgerDB' blk)
[lgrTracer] :: LgrDbArgs f m blk -> Tracer m (TraceEvent blk)

-- | Default arguments
defaultArgs :: FilePath -> LgrDbArgs Defaults IO blk

-- | Open the ledger DB
--   
--   In addition to the ledger DB also returns the number of immutable
--   blocks that were replayed.
openDB :: forall m blk. (IOLike m, LedgerSupportsProtocol blk, LgrDbSerialiseConstraints blk, InspectLedger blk, HasCallStack) => LgrDbArgs Identity m blk -> Tracer m (TraceReplayEvent blk ()) -> ImmutableDB m blk -> (RealPoint blk -> m blk) -> m (LgrDB m blk, Word64)

-- | <a>TraceReplayEvent</a> instantiated with additional information.
--   
--   The <tt>replayTo</tt> parameter is instantiated with the <a>Point</a>
--   of the tip of the ImmutableDB.
type TraceLedgerReplayEvent blk = TraceReplayEvent blk (Point blk)

-- | Add the tip of the Immutable DB to the trace event
--   
--   Between the tip of the immutable DB and the point of the starting
--   block, the node could (if it so desired) easily compute a "percentage
--   complete".
decorateReplayTracer :: Point blk -> Tracer m (TraceLedgerReplayEvent blk) -> Tracer m (TraceReplayEvent blk ())
getCurrent :: IOLike m => LgrDB m blk -> STM m (LedgerDB' blk)

-- | PRECONDITION: The new <tt>LedgerDB</tt> must be the result of calling
--   either <a>ledgerDbSwitch</a> or <a>ledgerDbPushMany</a> on the current
--   <tt>LedgerDB</tt>.
setCurrent :: IOLike m => LgrDB m blk -> LedgerDB' blk -> STM m ()
getCurrentState :: IOLike m => LgrDB m blk -> STM m (ExtLedgerState blk)
getPastState :: (IOLike m, HasHeader blk) => LgrDB m blk -> Point blk -> STM m (Maybe (ExtLedgerState blk))
getHeaderStateHistory :: IOLike m => LgrDB m blk -> STM m (HeaderStateHistory blk)
currentPoint :: forall blk. UpdateLedger blk => LedgerDB' blk -> Point blk
takeSnapshot :: forall m blk. (IOLike m, LgrDbSerialiseConstraints blk) => LgrDB m blk -> m (DiskSnapshot, Point blk)
trimSnapshots :: MonadCatch m => LgrDB m blk -> m [DiskSnapshot]
getDiskPolicy :: LgrDB m blk -> DiskPolicy
validate :: forall m blk. (IOLike m, LedgerSupportsProtocol blk, HasCallStack) => LgrDB m blk -> LedgerDB' blk -> BlockCache blk -> Word64 -> [Header blk] -> m (ValidateResult blk)
data ValidateResult blk
ValidateSuccessful :: LedgerDB' blk -> ValidateResult blk
ValidateLedgerError :: AnnLedgerError' blk -> ValidateResult blk
ValidateExceededRollBack :: ExceededRollback -> ValidateResult blk
getPrevApplied :: IOLike m => LgrDB m blk -> STM m (Set (RealPoint blk))

-- | Remove all points with a slot older than the given slot from the set
--   of previously applied points.
garbageCollectPrevApplied :: IOLike m => LgrDB m blk -> SlotNo -> STM m ()

-- | Exceeded maximum rollback supported by the current ledger DB state
--   
--   Under normal circumstances this will not arise. It can really only
--   happen in the presence of data corruption (or when switching to a
--   shorter fork, but that is disallowed by all currently known Ouroboros
--   protocols).
--   
--   Records both the supported and the requested rollback.
data ExceededRollback
ExceededRollback :: Word64 -> Word64 -> ExceededRollback
[rollbackMaximum] :: ExceededRollback -> Word64
[rollbackRequested] :: ExceededRollback -> Word64

-- | Annotated ledger errors
data AnnLedgerError l r
AnnLedgerError :: LedgerDB l r -> r -> LedgerErr l -> AnnLedgerError l r

-- | The ledger DB just <i>before</i> this block was applied
[annLedgerState] :: AnnLedgerError l r -> LedgerDB l r

-- | Reference to the block that had the error
[annLedgerErrRef] :: AnnLedgerError l r -> r

-- | The ledger error itself
[annLedgerErr] :: AnnLedgerError l r -> LedgerErr l
newtype LedgerDbParams
LedgerDbParams :: SecurityParam -> LedgerDbParams

-- | Security parameter (maximum rollback)
[ledgerDbSecurityParam] :: LedgerDbParams -> SecurityParam

-- | On-disk policy
--   
--   We only write ledger states that are older than <tt>k</tt> blocks to
--   disk (that is, snapshots that are guaranteed valid). The on-disk
--   policy determines how often we write to disk and how many checkpoints
--   we keep.
data DiskPolicy
DiskPolicy :: Word -> (Maybe DiffTime -> Word64 -> Bool) -> DiskPolicy

-- | How many snapshots do we want to keep on disk?
--   
--   A higher number of on-disk snapshots is primarily a safe-guard against
--   disk corruption: it trades disk space for reliability.
--   
--   Examples:
--   
--   <ul>
--   <li><tt>0</tt>: Delete the snapshot immediately after writing.
--   Probably not a useful value :-D</li>
--   <li><tt>1</tt>: Delete the previous snapshot immediately after writing
--   the next Dangerous policy: if for some reason the deletion happens
--   before the new snapshot is written entirely to disk (we don't
--   <tt>fsync</tt>), we have no choice but to start at the genesis
--   snapshot on the next startup.</li>
--   <li><tt>2</tt>: Always keep 2 snapshots around. This means that when
--   we write the next snapshot, we delete the oldest one, leaving the
--   middle one available in case of truncation of the write. This is
--   probably a sane value in most circumstances.</li>
--   </ul>
[onDiskNumSnapshots] :: DiskPolicy -> Word

-- | Should we write a snapshot of the ledger state to disk?
--   
--   This function is passed two bits of information:
--   
--   <ul>
--   <li>The time since the last snapshot, or <a>Nothing</a> if none was
--   taken yet. Note that <a>Nothing</a> merely means no snapshot had been
--   taking yet since the node was started; it does not necessarily mean
--   that none exist on disk.</li>
--   <li>The distance in terms of blocks applied to the <i>oldest</i>
--   ledger snapshot in memory. During normal operation, this is the number
--   of blocks written to the ImmutableDB since the last snapshot. On
--   startup, it is computed by counting how many immutable blocks we had
--   to reapply to get to the chain tip. This is useful, as it allows the
--   policy to decide to take a snapshot <i>on node startup</i> if a lot of
--   blocks had to be replayed.</li>
--   </ul>
--   
--   See also <a>defaultDiskPolicy</a>
[onDiskShouldTakeSnapshot] :: DiskPolicy -> Maybe DiffTime -> Word64 -> Bool

-- | On disk snapshots are numbered monotonically
data DiskSnapshot
data TraceEvent blk

-- | An on disk snapshot was skipped because it was invalid.
InvalidSnapshot :: DiskSnapshot -> InitFailure blk -> TraceEvent blk

-- | A snapshot was written to disk.
TookSnapshot :: DiskSnapshot -> Point blk -> TraceEvent blk

-- | An old or invalid on-disk snapshot was deleted
DeletedSnapshot :: DiskSnapshot -> TraceEvent blk

-- | Events traced while replaying blocks against the ledger to bring it up
--   to date w.r.t. the tip of the ImmutableDB during initialisation. As
--   this process takes a while, we trace events to inform higher layers of
--   our progress.
--   
--   The <tt>replayTo</tt> parameter is meant to be filled in by a higher
--   layer, i.e., the ChainDB.
data TraceReplayEvent blk replayTo

-- | There were no LedgerDB snapshots on disk, so we're replaying all
--   blocks starting from Genesis against the initial ledger.
--   
--   The <tt>replayTo</tt> parameter corresponds to the block at the tip of
--   the ImmutableDB, i.e., the last block to replay.
ReplayFromGenesis :: replayTo -> TraceReplayEvent blk replayTo

-- | There was a LedgerDB snapshot on disk corresponding to the given tip.
--   We're replaying more recent blocks against it.
--   
--   The <tt>replayTo</tt> parameter corresponds to the block at the tip of
--   the ImmutableDB, i.e., the last block to replay.
ReplayFromSnapshot :: DiskSnapshot -> Point blk -> replayTo -> TraceReplayEvent blk replayTo

-- | We replayed the given block (reference) on the genesis snapshot during
--   the initialisation of the LedgerDB.
--   
--   The <tt>blockInfo</tt> parameter corresponds replayed block and the
--   <tt>replayTo</tt> parameter corresponds to the block at the tip of the
--   ImmutableDB, i.e., the last block to replay.
ReplayedBlock :: RealPoint blk -> [LedgerEvent blk] -> replayTo -> TraceReplayEvent blk replayTo

-- | The ledger state at the tip of the chain
ledgerDbCurrent :: LedgerDB l r -> l

-- | For testing purposes
mkLgrDB :: StrictTVar m (LedgerDB' blk) -> StrictTVar m (Set (RealPoint blk)) -> (RealPoint blk -> m blk) -> LgrDbArgs Identity m blk -> LgrDB m blk
instance GHC.Generics.Generic (Ouroboros.Consensus.Storage.ChainDB.Impl.LgrDB.LgrDB m blk)
instance (Ouroboros.Consensus.Util.IOLike.IOLike m, Ouroboros.Consensus.Ledger.SupportsProtocol.LedgerSupportsProtocol blk) => NoThunks.Class.NoThunks (Ouroboros.Consensus.Storage.ChainDB.Impl.LgrDB.LgrDB m blk)

module Ouroboros.Consensus.Node.Exit

-- | The exit code to return when terminating with an exception.
--   
--   To be used in the <tt>ExitFailure</tt> constructor of <a>ExitCode</a>.
--   
--   Note that a node will never turn shut down itself, it is meant to run
--   forever, so it will always terminate with an <a>ExitFailure</a>.
type ExitFailure = Int

-- | Convert an <a>ExitReason</a> to an <a>ExitFailure</a>.
exitReasontoExitFailure :: ExitReason -> ExitFailure

-- | The reason of shutting down
data ExitReason

-- | The node process was killed, by the <tt>kill</tt> command,
--   <tt>CTRL-C</tt> or some other means. This is normal way for a user to
--   terminate the node process. The node can simply be restarted.
Killed :: ExitReason

-- | Something is wrong with the node configuration, the user should check
--   it.
--   
--   For example, for PBFT, it could be that the block signing key and the
--   delegation certificate do not match.
ConfigurationError :: ExitReason

-- | We were unable to open the database, probably the user is using the
--   wrong directory. See <a>DbMarkerError</a> for details.
WrongDatabase :: ExitReason

-- | The disk is full, make some space before restarting the node.
DiskFull :: ExitReason

-- | The database folder doesn't have the right permissions.
InsufficientPermissions :: ExitReason

-- | There is a problem with the network connection, the user should
--   investigate.
--   
--   TODO We're not yet returning this.
NoNetwork :: ExitReason

-- | Something went wrong with the database, restart the node with recovery
--   enabled.
DatabaseCorruption :: ExitReason

-- | Some exception was thrown. The node should just be restarted.
Other :: ExitReason

-- | Return the <a>ExitReason</a> for the given <a>SomeException</a>.
--   Defaults to <a>Other</a>.
toExitReason :: SomeException -> ExitReason

module Ouroboros.Consensus.Node.Recovery

-- | When the given action terminates with a <i>clean</i> exception, create
--   the <i>clean shutdown marker file</i>.
--   
--   NOTE: we assume the action (i.e., the node itself) never terminates
--   without an exception.
--   
--   A <i>clean</i> exception is an exception for
--   <a>exceptionRequiresRecovery</a> returns <a>False</a>.
createMarkerOnCleanShutdown :: IOLike m => HasFS m h -> m a -> m a

-- | Return <a>True</a> when <a>cleanShutdownMarkerFile</a> exists.
hasCleanShutdownMarker :: HasFS m h -> m Bool

-- | Create the <a>cleanShutdownMarkerFile</a>.
--   
--   Idempotent.
createCleanShutdownMarker :: IOLike m => HasFS m h -> m ()

-- | Remove <a>cleanShutdownMarkerFile</a>.
--   
--   Will throw an <tt>FsResourceDoesNotExist</tt> error when it does not
--   exist.
removeCleanShutdownMarker :: HasFS m h -> m ()

module Ouroboros.Consensus.MiniProtocol.ChainSync.Server

-- | Chain Sync Server for block headers for a given a <a>ChainDB</a>.
--   
--   The node-to-node protocol uses the chain sync mini-protocol with chain
--   headers (and fetches blocks separately with the block fetch
--   mini-protocol).
chainSyncHeadersServer :: forall m blk. (IOLike m, HasHeader (Header blk)) => Tracer m (TraceChainSyncServerEvent blk) -> ChainDB m blk -> NodeToNodeVersion -> ResourceRegistry m -> ChainSyncServer (SerialisedHeader blk) (Point blk) (Tip blk) m ()

-- | Chain Sync Server for blocks for a given a <a>ChainDB</a>.
--   
--   The local node-to-client protocol uses the chain sync mini-protocol
--   with chains of full blocks (rather than a header / body split).
chainSyncBlocksServer :: forall m blk. (IOLike m, HasHeader (Header blk)) => Tracer m (TraceChainSyncServerEvent blk) -> ChainDB m blk -> ResourceRegistry m -> ChainSyncServer (Serialised blk) (Point blk) (Tip blk) m ()
data Tip b

-- | Events traced by the Chain Sync Server.
--   
--   The whole headers/blocks in the traced <a>ChainUpdate</a> are
--   substituted with their corresponding <a>Point</a>.
data TraceChainSyncServerEvent blk
TraceChainSyncServerRead :: Tip blk -> ChainUpdate blk (Point blk) -> TraceChainSyncServerEvent blk
TraceChainSyncServerReadBlocked :: Tip blk -> ChainUpdate blk (Point blk) -> TraceChainSyncServerEvent blk
instance Ouroboros.Network.Block.StandardHash blk => GHC.Show.Show (Ouroboros.Consensus.MiniProtocol.ChainSync.Server.TraceChainSyncServerEvent blk)
instance Ouroboros.Network.Block.StandardHash blk => GHC.Classes.Eq (Ouroboros.Consensus.MiniProtocol.ChainSync.Server.TraceChainSyncServerEvent blk)

module Ouroboros.Consensus.BlockchainTime.API

-- | Blockchain time
--   
--   When we run the blockchain, there is a single, global time. We
--   abstract over this here to allow to query this time (in terms of the
--   current slot), and execute an action each time we advance a slot.
data BlockchainTime m
BlockchainTime :: STM m CurrentSlot -> BlockchainTime m

-- | Get current slot
[getCurrentSlot] :: BlockchainTime m -> STM m CurrentSlot
data CurrentSlot

-- | The current slot is known
CurrentSlot :: !SlotNo -> CurrentSlot

-- | The current slot is not yet known
--   
--   This only happens when the tip of the ledger is so far behind that we
--   lack the information necessary to translate the current
--   <tt>UTCTime</tt> into a <a>SlotNo</a>. This should only be the case
--   during syncing.
CurrentSlotUnknown :: CurrentSlot

-- | Spawn a thread to run an action each time the slot changes
--   
--   The action will not be called until the current slot becomes known (if
--   the tip of our ledger is too far away from the current wallclock time,
--   we may not know what the current <tt>SlotId</tt> is).
--   
--   Returns a handle to kill the thread.
onKnownSlotChange :: forall m. (IOLike m, HasCallStack) => ResourceRegistry m -> BlockchainTime m -> String -> (SlotNo -> m ()) -> m (m ())
instance NoThunks.Class.NoThunks Ouroboros.Consensus.BlockchainTime.API.CurrentSlot
instance GHC.Show.Show Ouroboros.Consensus.BlockchainTime.API.CurrentSlot
instance GHC.Generics.Generic Ouroboros.Consensus.BlockchainTime.API.CurrentSlot
instance NoThunks.Class.NoThunks (Ouroboros.Consensus.BlockchainTime.API.BlockchainTime m)


-- | Singletons
--   
--   This provides the core of the <tt>singletons</tt> package, using the
--   same name, but without pulling in all the dependencies and craziness.
module Ouroboros.Consensus.Util.Singletons

-- | Data family of singletons
data family Sing (a :: k)
class SingI (a :: k)
sing :: SingI a => Sing a
data SomeSing k
[SomeSing] :: Sing (a :: k) -> SomeSing k
withSomeSing :: forall k r. SingKind k => Demote k -> (forall (a :: k). Sing a -> r) -> r
class SingKind k where {
    type family Demote k = (r :: Type) | r -> k;
}
fromSing :: SingKind k => Sing (a :: k) -> Demote k
toSing :: SingKind k => Demote k -> SomeSing k
instance Ouroboros.Consensus.Util.Singletons.SingI '[]
instance forall a (xs :: [a]) (x :: a). Ouroboros.Consensus.Util.Singletons.SingI xs => Ouroboros.Consensus.Util.Singletons.SingI (x : xs)

module Ouroboros.Consensus.Util.Time
nominalDelay :: NominalDiffTime -> DiffTime
secondsToNominalDiffTime :: Double -> NominalDiffTime

module Ouroboros.Consensus.BlockchainTime.WallClock.Simple

-- | Real blockchain time
--   
--   WARNING: if the start time is in the future,
--   <a>simpleBlockchainTime</a> will block until the start time has come.
simpleBlockchainTime :: forall m. IOLike m => ResourceRegistry m -> SystemTime m -> SlotLength -> m (BlockchainTime m)

-- | Get current slot and time spent in that slot
getWallClockSlot :: IOLike m => SystemTime m -> SlotLength -> m (SlotNo, NominalDiffTime)

-- | Wait until the next slot
--   
--   Takes the current slot number to guard against system clock changes.
--   Any clock changes that would result in the slot number to
--   <i>decrease</i> will result in a fatal
--   <a>SystemClockMovedBackException</a>. When this exception is thrown,
--   the node will shut down, and should be restarted with (full?)
--   validation enabled: it is conceivable that blocks got moved to the
--   immutable DB that, due to the clock change, should not be considered
--   immutable anymore.
waitUntilNextSlot :: IOLike m => SystemTime m -> SlotLength -> SlotNo -> m SlotNo

module Ouroboros.Consensus.BlockchainTime.WallClock.HardFork

-- | A backoff delay
--   
--   If the <tt>horizon</tt> is very far away, the current tip is very far
--   away from the wallclock. However, that probably does not mean we have
--   to wait <tt>now - horizon</tt> time: we are probably just syncing, and
--   so the tip of the ledger will rapidly move forward. So at most <tt>now
--   - horizon</tt> could be used as a heuristic for how long to wait. For
--   now we just trace it.
--   
--   Instead, we just return a fixed delay of <tt>backoffDelay</tt>. There
--   is a trade-off between trying to often, incurring computational
--   overhead, and missing the opportunity to produce a block. For mainnet,
--   we anticipate a 60 second delay will keep both the computational
--   overhead and the number of slots we might miss reasonably small. We
--   anyway can't guarantee the speed of syncing, so delaying it by a
--   further 60 seconds as needed does not change anything fundamentally.
--   
--   (NOTE: We could reduce this delay but Edsko doesn't think it would
--   change very much, and it would increase the frequency of the trace
--   messages and incur computational overhead.)
newtype BackoffDelay
BackoffDelay :: NominalDiffTime -> BackoffDelay

-- | <a>BlockchainTime</a> instance with support for the hard fork history
hardForkBlockchainTime :: forall m blk. (IOLike m, HasHardForkHistory blk, HasCallStack) => ResourceRegistry m -> Tracer m (RelativeTime, PastHorizonException) -> SystemTime m -> LedgerConfig blk -> m BackoffDelay -> STM m (LedgerState blk) -> m (BlockchainTime m)

module Ouroboros.Consensus.BlockchainTime.WallClock.Default
defaultSystemTime :: (MonadTime m, MonadDelay m) => SystemStart -> Tracer m TraceBlockchainTimeEvent -> SystemTime m

module Ouroboros.Consensus.BlockchainTime


-- | Intended for qualified import
--   
--   <pre>
--   import Ouroboros.Consensus.Fragment.InFuture (CheckInFuture(..), ClockSkew(..))
--   import qualified Ouroboros.Consensus.Fragment.InFuture as InFuture
--   </pre>
module Ouroboros.Consensus.Fragment.InFuture
data CheckInFuture m blk
CheckInFuture :: (ValidatedFragment (Header blk) (LedgerState blk) -> m (AnchoredFragment (Header blk), [InFuture blk])) -> CheckInFuture m blk

-- | POSTCONDITION: &gt; checkInFuture vf &gt;&gt;= (af, fut) -&gt; &gt;
--   validatedFragment vf == af <a>=</a> null fut
[checkInFuture] :: CheckInFuture m blk -> ValidatedFragment (Header blk) (LedgerState blk) -> m (AnchoredFragment (Header blk), [InFuture blk])

-- | Header of block that we found to be in the future
data InFuture blk
InFuture :: Header blk -> Bool -> InFuture blk

-- | The header itself
[inFutureHeader] :: InFuture blk -> Header blk

-- | Whether or not this header exceeded the allowed clock skew
--   
--   Headers that do exceed the clock skew should be considered invalid.
[inFutureExceedsClockSkew] :: InFuture blk -> Bool
reference :: forall m blk. (Monad m, UpdateLedger blk, HasHardForkHistory blk) => LedgerConfig blk -> ClockSkew -> SystemTime m -> CheckInFuture m blk

-- | Maximum permissible clock skew
--   
--   When running NTP, systems clocks will never be perfectly synchronized.
--   The maximum clock skew records how much of a difference we consider
--   acceptable.
--   
--   For example. Suppose
--   
--   <ul>
--   <li>Two nodes A and B</li>
--   <li>A's clock is 0.5 ahead of B's</li>
--   <li>A produces a block and sends it to B</li>
--   <li>When B translates the <a>SlotNo</a> of that block to a time, it
--   may find that it is 0.5 seconds ahead of its current clock (worst
--   case).</li>
--   </ul>
--   
--   The maximum permissible clock skew decides if B will consider this
--   block to be valid (even if it will not yet consider it for chain
--   seleciton) or as invalid (and disconnect from A, since A is sending it
--   invalid blocks).
--   
--   Use <a>defaultClockSkew</a> when unsure.
data ClockSkew

-- | Specify maximum clock skew in seconds
clockSkewInSeconds :: Double -> ClockSkew

-- | Default maximum permissible clock skew
--   
--   See <a>ClockSkew</a> for details. We allow for 5 seconds skew by
--   default.
defaultClockSkew :: ClockSkew

-- | Trivial <a>InFuture</a> check that doesn't do any check at all
--   
--   This is useful for testing and tools such as the DB converter.
dontCheck :: Monad m => CheckInFuture m blk

-- | If by some miracle we have a function that can always tell us what the
--   correct slot is, implementing <a>CheckInFuture</a> is easy
--   
--   NOTE: Use of <a>miracle</a> in tests means that none of the hard fork
--   infrastructure for converting slots to time is tested.
miracle :: forall m blk. (MonadSTM m, HasHeader (Header blk)) => STM m SlotNo -> Word64 -> CheckInFuture m blk
instance NoThunks.Class.NoThunks (Ouroboros.Consensus.Fragment.InFuture.CheckInFuture m blk)
instance GHC.Classes.Ord Ouroboros.Consensus.Fragment.InFuture.ClockSkew
instance GHC.Classes.Eq Ouroboros.Consensus.Fragment.InFuture.ClockSkew
instance GHC.Show.Show Ouroboros.Consensus.Fragment.InFuture.ClockSkew


-- | Types used throughout the implementation: handle, state, environment,
--   types, trace types, etc.
module Ouroboros.Consensus.Storage.ChainDB.Impl.Types

-- | All the serialisation related constraints needed by the ChainDB.
class (ImmutableDbSerialiseConstraints blk, LgrDbSerialiseConstraints blk, VolatileDbSerialiseConstraints blk, EncodeDiskDep (NestedCtxt Header) blk) => SerialiseDiskConstraints blk

-- | A handle to the internal ChainDB state
newtype ChainDbHandle m blk
CDBHandle :: StrictTVar m (ChainDbState m blk) -> ChainDbHandle m blk

-- | Check if the ChainDB is open, if so, executing the given function on
--   the <a>ChainDbEnv</a>, otherwise, throw a <tt>CloseDBError</tt>.
getEnv :: forall m blk r. (IOLike m, HasCallStack) => ChainDbHandle m blk -> (ChainDbEnv m blk -> m r) -> m r

-- | Variant 'of <a>getEnv</a> for functions taking one argument.
getEnv1 :: (IOLike m, HasCallStack) => ChainDbHandle m blk -> (ChainDbEnv m blk -> a -> m r) -> a -> m r

-- | Variant 'of <a>getEnv</a> for functions taking two arguments.
getEnv2 :: (IOLike m, HasCallStack) => ChainDbHandle m blk -> (ChainDbEnv m blk -> a -> b -> m r) -> a -> b -> m r

-- | Variant of <a>getEnv</a> that works in <a>STM</a>.
getEnvSTM :: forall m blk r. (IOLike m, HasCallStack) => ChainDbHandle m blk -> (ChainDbEnv m blk -> STM m r) -> STM m r

-- | Variant of <a>getEnv1</a> that works in <a>STM</a>.
getEnvSTM1 :: (IOLike m, HasCallStack) => ChainDbHandle m blk -> (ChainDbEnv m blk -> a -> STM m r) -> a -> STM m r
data ChainDbState m blk
ChainDbOpen :: !ChainDbEnv m blk -> ChainDbState m blk
ChainDbClosed :: ChainDbState m blk
data ChainDbEnv m blk
CDB :: !ImmutableDB m blk -> !VolatileDB m blk -> !LgrDB m blk -> !StrictTVar m (AnchoredFragment (Header blk)) -> !StrictTVar m (Map IteratorKey (m ())) -> !StrictTVar m (Map ReaderKey (ReaderHandle m blk)) -> !TopLevelConfig blk -> !StrictTVar m (WithFingerprint (InvalidBlocks blk)) -> !StrictTVar m IteratorKey -> !StrictTVar m ReaderKey -> !StrictMVar m () -> !Tracer m (TraceEvent blk) -> !Tracer m (LedgerDB' blk) -> !ResourceRegistry m -> !DiffTime -> !DiffTime -> !StrictTVar m (m ()) -> !ChunkInfo -> !blk -> Bool -> !CheckInFuture m blk -> !BlocksToAdd m blk -> !StrictTVar m (FutureBlocks blk) -> ChainDbEnv m blk
[cdbImmutableDB] :: ChainDbEnv m blk -> !ImmutableDB m blk
[cdbVolatileDB] :: ChainDbEnv m blk -> !VolatileDB m blk
[cdbLgrDB] :: ChainDbEnv m blk -> !LgrDB m blk

-- | Contains the current chain fragment.
--   
--   INVARIANT: the anchor point of this fragment is the tip of the
--   ImmutableDB. This implies that this fragment never contains any blocks
--   that are stored in the immutable DB.
--   
--   Note that this fragment might be shorter than <tt>k</tt> headers when
--   the whole chain is shorter than <tt>k</tt> or in case of corruption of
--   the VolatileDB.
--   
--   Note that this fragment might also be <i>longer</i> than <tt>k</tt>
--   headers, because the oldest blocks from the fragment might not yet
--   have been copied from the VolatileDB to the ImmutableDB.
--   
--   The anchor point of this chain should be the most recent "immutable"
--   block according to the protocol, i.e., a block that cannot be rolled
--   back.
--   
--   Note that the "immutable" block isn't necessarily at the tip of the
--   ImmutableDB, but could temporarily still be on the in-memory chain
--   fragment. When the background thread that copies blocks to the
--   ImmutableDB has caught up, the "immutable" block will be at the tip of
--   the ImmutableDB again.
--   
--   Note that the "immutable" block might be less than <tt>k</tt> blocks
--   from our tip in case the whole chain is shorter than <tt>k</tt> or in
--   case of corruption of the VolatileDB.
--   
--   Note that the "immutable" block will <i>never</i> be <i>more</i> than
--   <tt>k</tt> blocks back, as opposed to the anchor point of
--   <a>cdbChain</a>.
[cdbChain] :: ChainDbEnv m blk -> !StrictTVar m (AnchoredFragment (Header blk))

-- | The iterators.
--   
--   This maps the <a>IteratorKey</a>s of each open <tt>Iterator</tt> to a
--   function that, when called, closes the iterator. This is used when
--   closing the ChainDB: the open file handles used by iterators can be
--   closed, and the iterators themselves are closed so that it is
--   impossible to use an iterator after closing the ChainDB itself.
[cdbIterators] :: ChainDbEnv m blk -> !StrictTVar m (Map IteratorKey (m ()))

-- | The readers.
--   
--   A reader is open iff its <a>ReaderKey</a> is this <a>Map</a>.
--   
--   INVARIANT: the <tt>readerPoint</tt> of each reader is
--   <tt>withinFragmentBounds</tt> of the current chain fragment (retrieved
--   <tt>cdbGetCurrentChain</tt>, not by reading <a>cdbChain</a> directly).
[cdbReaders] :: ChainDbEnv m blk -> !StrictTVar m (Map ReaderKey (ReaderHandle m blk))
[cdbTopLevelConfig] :: ChainDbEnv m blk -> !TopLevelConfig blk

-- | See the docstring of <a>InvalidBlocks</a>.
--   
--   The <tt>Fingerprint</tt> changes every time a hash is added to the
--   map, but not when hashes are garbage-collected from the map.
[cdbInvalid] :: ChainDbEnv m blk -> !StrictTVar m (WithFingerprint (InvalidBlocks blk))
[cdbNextIteratorKey] :: ChainDbEnv m blk -> !StrictTVar m IteratorKey
[cdbNextReaderKey] :: ChainDbEnv m blk -> !StrictTVar m ReaderKey

-- | Lock used to ensure that <tt>copyToImmutableDB</tt> is not executed
--   more than once concurrently.
--   
--   Note that <tt>copyToImmutableDB</tt> can still be executed
--   concurrently with all others functions, just not with itself.
[cdbCopyLock] :: ChainDbEnv m blk -> !StrictMVar m ()
[cdbTracer] :: ChainDbEnv m blk -> !Tracer m (TraceEvent blk)
[cdbTraceLedger] :: ChainDbEnv m blk -> !Tracer m (LedgerDB' blk)

-- | Resource registry that will be used to (re)start the background
--   threads, see <tt>cdbBgThreads</tt>.
[cdbRegistry] :: ChainDbEnv m blk -> !ResourceRegistry m

-- | How long to wait between copying a block from the VolatileDB to
--   ImmutableDB and garbage collecting it from the VolatileDB
[cdbGcDelay] :: ChainDbEnv m blk -> !DiffTime

-- | Minimum time between two garbage collections. Is used to batch garbage
--   collections.
[cdbGcInterval] :: ChainDbEnv m blk -> !DiffTime

-- | A handle to kill the background threads.
[cdbKillBgThreads] :: ChainDbEnv m blk -> !StrictTVar m (m ())
[cdbChunkInfo] :: ChainDbEnv m blk -> !ChunkInfo
[cdbCheckIntegrity] :: ChainDbEnv m blk -> !blk -> Bool
[cdbCheckInFuture] :: ChainDbEnv m blk -> !CheckInFuture m blk

-- | Queue of blocks that still have to be added.
[cdbBlocksToAdd] :: ChainDbEnv m blk -> !BlocksToAdd m blk

-- | Blocks from the future
--   
--   Blocks that were added to the ChainDB but that were from the future
--   according to <a>CheckInFuture</a>, without exceeding the clock skew
--   (<tt>inFutureExceedsClockSkew</tt>). Blocks exceeding the clock skew
--   are considered to be invalid (<tt>InFutureExceedsClockSkew</tt>) and
--   will be added <a>cdbInvalid</a>.
--   
--   Whenever a block is added to the ChainDB, we first trigger chain
--   selection for all the blocks in this map so that blocks no longer from
--   the future can get adopted. Note that when no blocks are added to the
--   ChainDB, we will <i>not</i> actively trigger chain selection for the
--   blocks in this map.
--   
--   The number of blocks from the future is bounded by the number of
--   upstream peers multiplied by the max clock skew divided by the slot
--   length.
[cdbFutureBlocks] :: ChainDbEnv m blk -> !StrictTVar m (FutureBlocks blk)
data Internal m blk
Internal :: m (WithOrigin SlotNo) -> (SlotNo -> m ()) -> m () -> m Void -> StrictTVar m (m ()) -> Internal m blk

-- | Copy the blocks older than <tt>k</tt> from to the VolatileDB to the
--   ImmutableDB and update the in-memory chain fragment correspondingly.
--   
--   The <a>SlotNo</a> of the tip of the ImmutableDB after copying the
--   blocks is returned. This can be used for a garbage collection on the
--   VolatileDB.
[intCopyToImmutableDB] :: Internal m blk -> m (WithOrigin SlotNo)

-- | Perform garbage collection for blocks &lt;= the given <a>SlotNo</a>.
[intGarbageCollect] :: Internal m blk -> SlotNo -> m ()

-- | Write a new LedgerDB snapshot to disk and remove the oldest one(s).
[intUpdateLedgerSnapshots] :: Internal m blk -> m ()

-- | Start the loop that adds blocks to the ChainDB retrieved from the
--   queue populated by <a>addBlock</a>. Execute this loop in a separate
--   thread.
[intAddBlockRunner] :: Internal m blk -> m Void

-- | A handle to kill the background threads.
[intKillBgThreads] :: Internal m blk -> StrictTVar m (m ())

-- | We use this internally to track iterators in a map
--   (<a>cdbIterators</a>) in the ChainDB state so that we can remove them
--   from the map when the iterator is closed.
--   
--   We store them in the map so that the ChainDB can close all open
--   iterators when it is closed itself.
newtype IteratorKey
IteratorKey :: Word -> IteratorKey

-- | We use this internally to track reader in a map (<a>cdbReaders</a>) in
--   the ChainDB state so that we can remove them from the map when the
--   reader is closed.
--   
--   We store them in the map so that the ChainDB can close all open
--   readers when it is closed itself and to update the readers in case we
--   switch to a different chain.
newtype ReaderKey
ReaderKey :: Word -> ReaderKey

-- | Internal handle to a <tt>Reader</tt> without an explicit <tt>b</tt>
--   (<tt>blk</tt>, <tt><a>Header</a> blk</tt>, etc.) parameter so
--   <tt>Reader</tt>s with different' <tt>b</tt>s can be stored together in
--   <a>cdbReaders</a>.
data ReaderHandle m blk
ReaderHandle :: (Point blk -> AnchoredFragment (Header blk) -> STM m ()) -> m () -> ReaderHandle m blk

-- | When we have switched to a fork, all open <tt>Reader</tt>s must be
--   notified.
[rhSwitchFork] :: ReaderHandle m blk -> Point blk -> AnchoredFragment (Header blk) -> STM m ()

-- | When closing the ChainDB, we must also close all open
--   <tt>Reader</tt>s, as they might be holding on to resources.
--   
--   Call <a>rhClose</a> will release the resources used by the
--   <tt>Reader</tt>.
--   
--   NOTE the <tt>Reader</tt> is not removed from <a>cdbReaders</a>. (That
--   is done by <tt>closeAllReaders</tt>).
[rhClose] :: ReaderHandle m blk -> m ()

-- | <tt>b</tt> corresponds to the <tt>BlockComponent</tt> that is being
--   read.
data ReaderState m blk b

-- | The <tt>Reader</tt> is in its initial state. Its
--   <a>ReaderRollState</a> is <tt><a>RollBackTo</a>
--   <tt>genesisPoint</tt></tt>.
--   
--   This is equivalent to having a <a>ReaderInImmutableDB</a> with the
--   same <a>ReaderRollState</a> and an iterator streaming after genesis.
--   Opening such an iterator has a cost (index files will have to be
--   read). However, in most cases, right after opening a Reader, the user
--   of the Reader will try to move it forward, moving it from genesis to a
--   more recent point on the chain. So we incur the cost of opening the
--   iterator while not even using it.
--   
--   Therefore, we have this extra initial state, that avoids this cost.
--   When the user doesn't move the Reader forward, an iterator is opened.
ReaderInit :: ReaderState m blk b

-- | The <tt>Reader</tt> is reading from the ImmutableDB.
--   
--   Note that the iterator includes 'Point blk' in addition to <tt>b</tt>,
--   as it is needed to keep track of where the iterator is.
--   
--   INVARIANT: for all <tt>ReaderInImmutableDB rollState immIt</tt>: the
--   predecessor of the next block streamed by <tt>immIt</tt> must be the
--   block identified by <tt>readerRollStatePoint rollState</tt>. In other
--   words: the iterator is positioned <i>on</i> <tt>readerRollStatePoint
--   rollState</tt>.
ReaderInImmutableDB :: !ReaderRollState blk -> !Iterator m blk (Point blk, b) -> ReaderState m blk b

-- | The <tt>Reader</tt> is reading from the in-memory current chain
--   fragment.
ReaderInMem :: !ReaderRollState blk -> ReaderState m blk b

-- | Similar to <a>ReaderState</a>.
data ReaderRollState blk

-- | We don't know at which point the user is, but the next message we'll
--   send is to roll back to this point.
RollBackTo :: !Point blk -> ReaderRollState blk

-- | We know that the reader is at this point and the next message we'll
--   send is to roll forward to the point <i>after</i> this point on our
--   chain.
RollForwardFrom :: !Point blk -> ReaderRollState blk

-- | Get the point the <a>ReaderRollState</a> should roll back to or roll
--   forward from.
readerRollStatePoint :: ReaderRollState blk -> Point blk

-- | Hashes corresponding to invalid blocks. This is used to ignore these
--   blocks during chain selection.
type InvalidBlocks blk = Map (HeaderHash blk) (InvalidBlockInfo blk)

-- | In addition to the reason why a block is invalid, the slot number of
--   the block is stored, so that whenever a garbage collection is
--   performed on the VolatileDB for some slot <tt>s</tt>, the hashes older
--   or equal to <tt>s</tt> can be removed from this map.
data InvalidBlockInfo blk
InvalidBlockInfo :: !InvalidBlockReason blk -> !SlotNo -> InvalidBlockInfo blk
[invalidBlockReason] :: InvalidBlockInfo blk -> !InvalidBlockReason blk
[invalidBlockSlotNo] :: InvalidBlockInfo blk -> !SlotNo

-- | Blocks from the future for which we still need to trigger chain
--   selection.
--   
--   See <a>cdbFutureBlocks</a> for more info.
type FutureBlocks blk = Map (HeaderHash blk) (Header blk)

-- | FIFO queue used to add blocks asynchronously to the ChainDB. Blocks
--   are read from this queue by a background thread, which processes the
--   blocks synchronously.
data BlocksToAdd m blk

-- | Entry in the <a>BlocksToAdd</a> queue: a block together with the
--   <tt>TMVar</tt>s used to implement <a>AddBlockPromise</a>.
data BlockToAdd m blk
BlockToAdd :: !blk -> !StrictTMVar m Bool -> !StrictTMVar m (Point blk) -> BlockToAdd m blk
[blockToAdd] :: BlockToAdd m blk -> !blk

-- | Used for the <a>blockWrittenToDisk</a> field of
--   <a>AddBlockPromise</a>.
[varBlockWrittenToDisk] :: BlockToAdd m blk -> !StrictTMVar m Bool

-- | Used for the <a>blockProcessed</a> field of <a>AddBlockPromise</a>.
[varBlockProcessed] :: BlockToAdd m blk -> !StrictTMVar m (Point blk)

-- | Create a new <a>BlocksToAdd</a> with the given size.
newBlocksToAdd :: IOLike m => Word -> m (BlocksToAdd m blk)

-- | Add a block to the <a>BlocksToAdd</a> queue. Can block when the queue
--   is full.
addBlockToAdd :: (IOLike m, HasHeader blk) => Tracer m (TraceAddBlockEvent blk) -> BlocksToAdd m blk -> blk -> m (AddBlockPromise m blk)

-- | Get the oldest block from the <a>BlocksToAdd</a> queue. Can block when
--   the queue is empty.
getBlockToAdd :: IOLike m => BlocksToAdd m blk -> m (BlockToAdd m blk)

-- | Trace type for the various events of the ChainDB.
data TraceEvent blk
TraceAddBlockEvent :: TraceAddBlockEvent blk -> TraceEvent blk
TraceReaderEvent :: TraceReaderEvent blk -> TraceEvent blk
TraceCopyToImmutableDBEvent :: TraceCopyToImmutableDBEvent blk -> TraceEvent blk
TraceGCEvent :: TraceGCEvent blk -> TraceEvent blk
TraceInitChainSelEvent :: TraceInitChainSelEvent blk -> TraceEvent blk
TraceOpenEvent :: TraceOpenEvent blk -> TraceEvent blk
TraceIteratorEvent :: TraceIteratorEvent blk -> TraceEvent blk
TraceLedgerEvent :: TraceEvent blk -> TraceEvent blk
TraceLedgerReplayEvent :: TraceLedgerReplayEvent blk -> TraceEvent blk
TraceImmutableDBEvent :: TraceEvent blk -> TraceEvent blk
TraceVolatileDBEvent :: TraceEvent blk -> TraceEvent blk

-- | Information about the new tip of the current chain.
--   
--   NOTE: the fields of this record are intentionally lazy to prevent the
--   forcing of this information in case it doesn't have to be traced.
--   However, this means that the tracer processing this message <i>must
--   not</i> hold on to it, otherwise it leaks memory.
data NewTipInfo blk
NewTipInfo :: RealPoint blk -> EpochNo -> Word64 -> RealPoint blk -> NewTipInfo blk

-- | The new tip of the current chain.
[newTipPoint] :: NewTipInfo blk -> RealPoint blk

-- | The epoch of the new tip.
[newTipEpoch] :: NewTipInfo blk -> EpochNo

-- | The slot in the epoch, i.e., the relative slot number, of the new tip.
[newTipSlotInEpoch] :: NewTipInfo blk -> Word64

-- | The new tip of the current chain (<a>newTipPoint</a>) is the result of
--   performing chain selection for a <i>trigger</i> block
--   (<a>newTipTrigger</a>). In most cases, we add a new block to the tip
--   of the current chain, in which case the new tip <i>is</i> the trigger
--   block.
--   
--   However, this is not always the case. For example, with our current
--   chain being A and having a disconnected C lying around, adding B will
--   result in A -&gt; B -&gt; C as the new chain. The trigger B /= the new
--   tip C.
[newTipTrigger] :: NewTipInfo blk -> RealPoint blk

-- | Trace type for the various events that occur when adding a block.
data TraceAddBlockEvent blk

-- | A block with a <a>BlockNo</a> more than <tt>k</tt> back than the
--   current tip was ignored.
IgnoreBlockOlderThanK :: RealPoint blk -> TraceAddBlockEvent blk

-- | A block that is already in the Volatile DB was ignored.
IgnoreBlockAlreadyInVolatileDB :: RealPoint blk -> TraceAddBlockEvent blk

-- | A block that is know to be invalid was ignored.
IgnoreInvalidBlock :: RealPoint blk -> InvalidBlockReason blk -> TraceAddBlockEvent blk

-- | The block was added to the queue and will be added to the ChainDB by
--   the background thread. The size of the queue is included.
AddedBlockToQueue :: RealPoint blk -> Word -> TraceAddBlockEvent blk

-- | The block is from the future, i.e., its slot number is greater than
--   the current slot (the second argument).
BlockInTheFuture :: RealPoint blk -> SlotNo -> TraceAddBlockEvent blk

-- | A block was added to the Volatile DB
AddedBlockToVolatileDB :: RealPoint blk -> BlockNo -> IsEBB -> TraceAddBlockEvent blk

-- | The block fits onto the current chain, we'll try to use it to extend
--   our chain.
TryAddToCurrentChain :: RealPoint blk -> TraceAddBlockEvent blk

-- | The block fits onto some fork, we'll try to switch to that fork (if it
--   is preferable to our chain).
TrySwitchToAFork :: RealPoint blk -> ChainDiff (HeaderFields blk) -> TraceAddBlockEvent blk

-- | The block doesn't fit onto any other block, so we store it and ignore
--   it.
StoreButDontChange :: RealPoint blk -> TraceAddBlockEvent blk

-- | The new block fits onto the current chain (first fragment) and we have
--   successfully used it to extend our (new) current chain (second
--   fragment).
AddedToCurrentChain :: [LedgerEvent blk] -> NewTipInfo blk -> AnchoredFragment (Header blk) -> AnchoredFragment (Header blk) -> TraceAddBlockEvent blk

-- | The new block fits onto some fork and we have switched to that fork
--   (second fragment), as it is preferable to our (previous) current chain
--   (first fragment).
SwitchedToAFork :: [LedgerEvent blk] -> NewTipInfo blk -> AnchoredFragment (Header blk) -> AnchoredFragment (Header blk) -> TraceAddBlockEvent blk

-- | An event traced during validating performed while adding a block.
AddBlockValidation :: TraceValidationEvent blk -> TraceAddBlockEvent blk

-- | Run chain selection for a block that was previously from the future.
--   This is done for all blocks from the future each time a new block is
--   added.
ChainSelectionForFutureBlock :: RealPoint blk -> TraceAddBlockEvent blk
data TraceReaderEvent blk

-- | A new reader was created.
NewReader :: TraceReaderEvent blk

-- | The reader was in the <a>ReaderInMem</a> state but its point is no
--   longer on the in-memory chain fragment, so it has to switch to the
--   <a>ReaderInImmutableDB</a> state.
ReaderNoLongerInMem :: ReaderRollState blk -> TraceReaderEvent blk

-- | The reader was in the <a>ReaderInImmutableDB</a> state and is switched
--   to the <a>ReaderInMem</a> state.
ReaderSwitchToMem :: Point blk -> WithOrigin SlotNo -> TraceReaderEvent blk

-- | The reader is in the <a>ReaderInImmutableDB</a> state but the iterator
--   is exhausted while the ImmutableDB has grown, so we open a new
--   iterator to stream these blocks too.
ReaderNewImmIterator :: Point blk -> WithOrigin SlotNo -> TraceReaderEvent blk
data TraceCopyToImmutableDBEvent blk

-- | A block was successfully copied to the ImmutableDB.
CopiedBlockToImmutableDB :: Point blk -> TraceCopyToImmutableDBEvent blk

-- | There are no block to copy to the ImmutableDB.
NoBlocksToCopyToImmutableDB :: TraceCopyToImmutableDBEvent blk
data TraceGCEvent blk

-- | A garbage collection for the given <a>SlotNo</a> was scheduled to
--   happen at the given time.
ScheduledGC :: SlotNo -> Time -> TraceGCEvent blk

-- | A garbage collection for the given <a>SlotNo</a> was performed.
PerformedGC :: SlotNo -> TraceGCEvent blk
data TraceValidationEvent blk

-- | A point was found to be invalid.
InvalidBlock :: ExtValidationError blk -> RealPoint blk -> TraceValidationEvent blk

-- | A candidate chain was invalid.
InvalidCandidate :: AnchoredFragment (Header blk) -> TraceValidationEvent blk

-- | A candidate chain was valid.
ValidCandidate :: AnchoredFragment (Header blk) -> TraceValidationEvent blk

-- | Candidate contains headers from the future which do no exceed the
--   clock skew.
CandidateContainsFutureBlocks :: AnchoredFragment (Header blk) -> [Header blk] -> TraceValidationEvent blk

-- | Candidate contains headers from the future which exceed the clock
--   skew, making them invalid.
CandidateContainsFutureBlocksExceedingClockSkew :: AnchoredFragment (Header blk) -> [Header blk] -> TraceValidationEvent blk
data TraceInitChainSelEvent blk

-- | An event traced during validation performed while performing initial
--   chain selection.
InitChainSelValidation :: TraceValidationEvent blk -> TraceInitChainSelEvent blk
data TraceOpenEvent blk

-- | The ChainDB was opened.
OpenedDB :: Point blk -> Point blk -> TraceOpenEvent blk

-- | The ChainDB was closed.
ClosedDB :: Point blk -> Point blk -> TraceOpenEvent blk

-- | The ImmutableDB was opened.
OpenedImmutableDB :: Point blk -> ChunkNo -> TraceOpenEvent blk

-- | The VolatileDB was opened.
OpenedVolatileDB :: TraceOpenEvent blk

-- | The LedgerDB was opened.
OpenedLgrDB :: TraceOpenEvent blk
data TraceIteratorEvent blk

-- | An unknown range was requested, see <a>UnknownRange</a>.
UnknownRangeRequested :: UnknownRange blk -> TraceIteratorEvent blk

-- | Stream only from the VolatileDB.
StreamFromVolatileDB :: StreamFrom blk -> StreamTo blk -> [RealPoint blk] -> TraceIteratorEvent blk

-- | Stream only from the ImmutableDB.
StreamFromImmutableDB :: StreamFrom blk -> StreamTo blk -> TraceIteratorEvent blk

-- | Stream from both the VolatileDB and the ImmutableDB.
StreamFromBoth :: StreamFrom blk -> StreamTo blk -> [RealPoint blk] -> TraceIteratorEvent blk

-- | A block is no longer in the VolatileDB because it has been garbage
--   collected. It might now be in the ImmutableDB if it was part of the
--   current chain.
BlockMissingFromVolatileDB :: RealPoint blk -> TraceIteratorEvent blk

-- | A block that has been garbage collected from the VolatileDB is now
--   found and streamed from the ImmutableDB.
BlockWasCopiedToImmutableDB :: RealPoint blk -> TraceIteratorEvent blk

-- | A block is no longer in the VolatileDB and isn't in the ImmutableDB
--   either; it wasn't part of the current chain.
BlockGCedFromVolatileDB :: RealPoint blk -> TraceIteratorEvent blk

-- | We have streamed one or more blocks from the ImmutableDB that were
--   part of the VolatileDB when initialising the iterator. Now, we have to
--   look back in the VolatileDB again because the ImmutableDB doesn't have
--   the next block we're looking for.
SwitchBackToVolatileDB :: TraceIteratorEvent blk
instance NoThunks.Class.NoThunks Ouroboros.Consensus.Storage.ChainDB.Impl.Types.IteratorKey
instance GHC.Enum.Enum Ouroboros.Consensus.Storage.ChainDB.Impl.Types.IteratorKey
instance GHC.Classes.Ord Ouroboros.Consensus.Storage.ChainDB.Impl.Types.IteratorKey
instance GHC.Classes.Eq Ouroboros.Consensus.Storage.ChainDB.Impl.Types.IteratorKey
instance GHC.Show.Show Ouroboros.Consensus.Storage.ChainDB.Impl.Types.IteratorKey
instance NoThunks.Class.NoThunks Ouroboros.Consensus.Storage.ChainDB.Impl.Types.ReaderKey
instance GHC.Enum.Enum Ouroboros.Consensus.Storage.ChainDB.Impl.Types.ReaderKey
instance GHC.Classes.Ord Ouroboros.Consensus.Storage.ChainDB.Impl.Types.ReaderKey
instance GHC.Classes.Eq Ouroboros.Consensus.Storage.ChainDB.Impl.Types.ReaderKey
instance GHC.Show.Show Ouroboros.Consensus.Storage.ChainDB.Impl.Types.ReaderKey
instance NoThunks.Class.NoThunks (Ouroboros.Consensus.Storage.ChainDB.Impl.Types.ReaderHandle m blk)
instance Ouroboros.Network.Block.StandardHash blk => NoThunks.Class.NoThunks (Ouroboros.Consensus.Storage.ChainDB.Impl.Types.ReaderRollState blk)
instance GHC.Generics.Generic (Ouroboros.Consensus.Storage.ChainDB.Impl.Types.ReaderRollState blk)
instance Ouroboros.Network.Block.StandardHash blk => GHC.Show.Show (Ouroboros.Consensus.Storage.ChainDB.Impl.Types.ReaderRollState blk)
instance Ouroboros.Network.Block.StandardHash blk => GHC.Classes.Eq (Ouroboros.Consensus.Storage.ChainDB.Impl.Types.ReaderRollState blk)
instance Ouroboros.Network.Block.StandardHash blk => NoThunks.Class.NoThunks (Ouroboros.Consensus.Storage.ChainDB.Impl.Types.ReaderState m blk b)
instance GHC.Generics.Generic (Ouroboros.Consensus.Storage.ChainDB.Impl.Types.ReaderState m blk b)
instance Ouroboros.Consensus.Ledger.SupportsProtocol.LedgerSupportsProtocol blk => NoThunks.Class.NoThunks (Ouroboros.Consensus.Storage.ChainDB.Impl.Types.InvalidBlockInfo blk)
instance GHC.Generics.Generic (Ouroboros.Consensus.Storage.ChainDB.Impl.Types.InvalidBlockInfo blk)
instance Ouroboros.Consensus.Ledger.SupportsProtocol.LedgerSupportsProtocol blk => GHC.Show.Show (Ouroboros.Consensus.Storage.ChainDB.Impl.Types.InvalidBlockInfo blk)
instance Ouroboros.Consensus.Ledger.SupportsProtocol.LedgerSupportsProtocol blk => GHC.Classes.Eq (Ouroboros.Consensus.Storage.ChainDB.Impl.Types.InvalidBlockInfo blk)
instance NoThunks.Class.NoThunks (Ouroboros.Consensus.Storage.ChainDB.Impl.Types.BlocksToAdd m blk)
instance Ouroboros.Network.Block.StandardHash blk => GHC.Show.Show (Ouroboros.Consensus.Storage.ChainDB.Impl.Types.TraceOpenEvent blk)
instance Ouroboros.Network.Block.StandardHash blk => GHC.Classes.Eq (Ouroboros.Consensus.Storage.ChainDB.Impl.Types.TraceOpenEvent blk)
instance GHC.Generics.Generic (Ouroboros.Consensus.Storage.ChainDB.Impl.Types.TraceOpenEvent blk)
instance GHC.Generics.Generic (Ouroboros.Consensus.Storage.ChainDB.Impl.Types.NewTipInfo blk)
instance Ouroboros.Network.Block.StandardHash blk => GHC.Show.Show (Ouroboros.Consensus.Storage.ChainDB.Impl.Types.NewTipInfo blk)
instance Ouroboros.Network.Block.StandardHash blk => GHC.Classes.Eq (Ouroboros.Consensus.Storage.ChainDB.Impl.Types.NewTipInfo blk)
instance GHC.Generics.Generic (Ouroboros.Consensus.Storage.ChainDB.Impl.Types.TraceValidationEvent blk)
instance GHC.Generics.Generic (Ouroboros.Consensus.Storage.ChainDB.Impl.Types.TraceAddBlockEvent blk)
instance GHC.Generics.Generic (Ouroboros.Consensus.Storage.ChainDB.Impl.Types.TraceInitChainSelEvent blk)
instance Ouroboros.Network.Block.StandardHash blk => GHC.Show.Show (Ouroboros.Consensus.Storage.ChainDB.Impl.Types.TraceReaderEvent blk)
instance Ouroboros.Network.Block.StandardHash blk => GHC.Classes.Eq (Ouroboros.Consensus.Storage.ChainDB.Impl.Types.TraceReaderEvent blk)
instance GHC.Generics.Generic (Ouroboros.Consensus.Storage.ChainDB.Impl.Types.TraceReaderEvent blk)
instance Ouroboros.Network.Block.StandardHash blk => GHC.Show.Show (Ouroboros.Consensus.Storage.ChainDB.Impl.Types.TraceCopyToImmutableDBEvent blk)
instance Ouroboros.Network.Block.StandardHash blk => GHC.Classes.Eq (Ouroboros.Consensus.Storage.ChainDB.Impl.Types.TraceCopyToImmutableDBEvent blk)
instance GHC.Generics.Generic (Ouroboros.Consensus.Storage.ChainDB.Impl.Types.TraceCopyToImmutableDBEvent blk)
instance GHC.Show.Show (Ouroboros.Consensus.Storage.ChainDB.Impl.Types.TraceGCEvent blk)
instance GHC.Classes.Eq (Ouroboros.Consensus.Storage.ChainDB.Impl.Types.TraceGCEvent blk)
instance GHC.Generics.Generic (Ouroboros.Consensus.Storage.ChainDB.Impl.Types.TraceGCEvent blk)
instance Ouroboros.Network.Block.StandardHash blk => GHC.Show.Show (Ouroboros.Consensus.Storage.ChainDB.Impl.Types.TraceIteratorEvent blk)
instance Ouroboros.Network.Block.StandardHash blk => GHC.Classes.Eq (Ouroboros.Consensus.Storage.ChainDB.Impl.Types.TraceIteratorEvent blk)
instance GHC.Generics.Generic (Ouroboros.Consensus.Storage.ChainDB.Impl.Types.TraceIteratorEvent blk)
instance GHC.Generics.Generic (Ouroboros.Consensus.Storage.ChainDB.Impl.Types.TraceEvent blk)
instance GHC.Generics.Generic (Ouroboros.Consensus.Storage.ChainDB.Impl.Types.ChainDbEnv m blk)
instance (Ouroboros.Consensus.Util.IOLike.IOLike m, Ouroboros.Consensus.Ledger.SupportsProtocol.LedgerSupportsProtocol blk) => NoThunks.Class.NoThunks (Ouroboros.Consensus.Storage.ChainDB.Impl.Types.ChainDbState m blk)
instance GHC.Generics.Generic (Ouroboros.Consensus.Storage.ChainDB.Impl.Types.ChainDbState m blk)
instance (Ouroboros.Network.Block.HasHeader blk, GHC.Classes.Eq (Ouroboros.Consensus.Block.Abstract.Header blk), Ouroboros.Consensus.Ledger.SupportsProtocol.LedgerSupportsProtocol blk, Ouroboros.Consensus.Ledger.Inspect.InspectLedger blk) => GHC.Classes.Eq (Ouroboros.Consensus.Storage.ChainDB.Impl.Types.TraceEvent blk)
instance (Ouroboros.Network.Block.HasHeader blk, GHC.Show.Show (Ouroboros.Consensus.Block.Abstract.Header blk), Ouroboros.Consensus.Ledger.SupportsProtocol.LedgerSupportsProtocol blk, Ouroboros.Consensus.Ledger.Inspect.InspectLedger blk) => GHC.Show.Show (Ouroboros.Consensus.Storage.ChainDB.Impl.Types.TraceEvent blk)
instance (Ouroboros.Network.Block.HasHeader blk, GHC.Classes.Eq (Ouroboros.Consensus.Block.Abstract.Header blk), Ouroboros.Consensus.Ledger.SupportsProtocol.LedgerSupportsProtocol blk, Ouroboros.Consensus.Ledger.Inspect.InspectLedger blk) => GHC.Classes.Eq (Ouroboros.Consensus.Storage.ChainDB.Impl.Types.TraceAddBlockEvent blk)
instance (Ouroboros.Network.Block.HasHeader blk, GHC.Show.Show (Ouroboros.Consensus.Block.Abstract.Header blk), Ouroboros.Consensus.Ledger.SupportsProtocol.LedgerSupportsProtocol blk, Ouroboros.Consensus.Ledger.Inspect.InspectLedger blk) => GHC.Show.Show (Ouroboros.Consensus.Storage.ChainDB.Impl.Types.TraceAddBlockEvent blk)
instance (Ouroboros.Network.Block.HasHeader blk, GHC.Classes.Eq (Ouroboros.Consensus.Block.Abstract.Header blk), Ouroboros.Consensus.Ledger.SupportsProtocol.LedgerSupportsProtocol blk) => GHC.Classes.Eq (Ouroboros.Consensus.Storage.ChainDB.Impl.Types.TraceValidationEvent blk)
instance (GHC.Show.Show (Ouroboros.Consensus.Block.Abstract.Header blk), Ouroboros.Consensus.Ledger.SupportsProtocol.LedgerSupportsProtocol blk) => GHC.Show.Show (Ouroboros.Consensus.Storage.ChainDB.Impl.Types.TraceValidationEvent blk)
instance (Ouroboros.Network.Block.HasHeader blk, GHC.Classes.Eq (Ouroboros.Consensus.Block.Abstract.Header blk), Ouroboros.Consensus.Ledger.SupportsProtocol.LedgerSupportsProtocol blk) => GHC.Classes.Eq (Ouroboros.Consensus.Storage.ChainDB.Impl.Types.TraceInitChainSelEvent blk)
instance (GHC.Show.Show (Ouroboros.Consensus.Block.Abstract.Header blk), Ouroboros.Consensus.Ledger.SupportsProtocol.LedgerSupportsProtocol blk) => GHC.Show.Show (Ouroboros.Consensus.Storage.ChainDB.Impl.Types.TraceInitChainSelEvent blk)
instance (Ouroboros.Consensus.Util.IOLike.IOLike m, Ouroboros.Consensus.Ledger.SupportsProtocol.LedgerSupportsProtocol blk) => NoThunks.Class.NoThunks (Ouroboros.Consensus.Storage.ChainDB.Impl.Types.ChainDbEnv m blk)


-- | Queries
module Ouroboros.Consensus.Storage.ChainDB.Impl.Query

-- | Return the last <tt>k</tt> headers.
--   
--   While the in-memory fragment (<a>cdbChain</a>) might temporarily be
--   longer than <tt>k</tt> (until the background thread has copied those
--   blocks to the ImmutableDB), this function will never return a fragment
--   longer than <tt>k</tt>.
--   
--   The anchor point of the returned fragment will be the most recent
--   "immutable" block, i.e. a block that cannot be rolled back. In
--   ChainDB.md, we call this block <tt>i</tt>.
--   
--   Note that the returned fragment may be shorter than <tt>k</tt> in case
--   the whole chain itself is shorter than <tt>k</tt> or in case the
--   VolatileDB was corrupted. In the latter case, we don't take blocks
--   already in the ImmutableDB into account, as we know they <i>must</i>
--   have been "immutable" at some point, and, therefore, <i>must</i> still
--   be "immutable".
getCurrentChain :: forall m blk. (IOLike m, HasHeader (Header blk), ConsensusProtocol (BlockProtocol blk)) => ChainDbEnv m blk -> STM m (AnchoredFragment (Header blk))
getCurrentLedger :: IOLike m => ChainDbEnv m blk -> STM m (ExtLedgerState blk)
getPastLedger :: (HasHeader blk, IOLike m) => ChainDbEnv m blk -> Point blk -> STM m (Maybe (ExtLedgerState blk))
getHeaderStateHistory :: IOLike m => ChainDbEnv m blk -> STM m (HeaderStateHistory blk)
getTipBlock :: forall m blk. (IOLike m, HasHeader blk, HasHeader (Header blk)) => ChainDbEnv m blk -> m (Maybe blk)
getTipHeader :: forall m blk. (IOLike m, HasHeader blk, HasHeader (Header blk)) => ChainDbEnv m blk -> m (Maybe (Header blk))
getTipPoint :: forall m blk. (IOLike m, HasHeader (Header blk)) => ChainDbEnv m blk -> STM m (Point blk)
getBlockComponent :: forall m blk b. IOLike m => ChainDbEnv m blk -> BlockComponent blk b -> RealPoint blk -> m (Maybe b)
getIsFetched :: forall m blk. IOLike m => ChainDbEnv m blk -> STM m (Point blk -> Bool)
getIsValid :: forall m blk. (IOLike m, HasHeader blk) => ChainDbEnv m blk -> STM m (RealPoint blk -> Maybe Bool)
getIsInvalidBlock :: forall m blk. (IOLike m, HasHeader blk) => ChainDbEnv m blk -> STM m (WithFingerprint (HeaderHash blk -> Maybe (InvalidBlockReason blk)))
getMaxSlotNo :: forall m blk. (IOLike m, HasHeader (Header blk)) => ChainDbEnv m blk -> STM m MaxSlotNo

-- | Variant of <a>getAnyBlockComponent</a> instantiated with
--   <a>GetBlock</a>.
getAnyKnownBlock :: forall m blk. (IOLike m, HasHeader blk) => ImmutableDB m blk -> VolatileDB m blk -> RealPoint blk -> m blk

-- | Wrapper around <a>getAnyBlockComponent</a> for blocks we know should
--   exist.
--   
--   If the block does not exist, this indicates disk failure.
getAnyKnownBlockComponent :: forall m blk b. (IOLike m, HasHeader blk) => ImmutableDB m blk -> VolatileDB m blk -> BlockComponent blk b -> RealPoint blk -> m b

-- | Get a block component from either the immutable DB or volatile DB.
--   
--   Returns <a>Nothing</a> if the <a>Point</a> is unknown. Throws
--   <tt>NoGenesisBlockException</tt> if the <a>Point</a> refers to the
--   genesis block.
getAnyBlockComponent :: forall m blk b. IOLike m => ImmutableDB m blk -> VolatileDB m blk -> BlockComponent blk b -> RealPoint blk -> m (Maybe b)


-- | Readers
module Ouroboros.Consensus.Storage.ChainDB.Impl.Reader
newReader :: forall m blk b. (IOLike m, HasHeader blk, GetHeader blk, HasNestedContent Header blk, EncodeDiskDep (NestedCtxt Header) blk) => ChainDbHandle m blk -> ResourceRegistry m -> BlockComponent blk b -> m (Reader m blk b)

-- | Update the given <a>ReaderState</a> to account for switching the
--   current chain to the given fork (which might just be an extension of
--   the current chain).
--   
--   PRECONDITION: the intersection point must be within the fragment
--   bounds of the new chain
switchFork :: forall m blk b. (HasHeader blk, HasHeader (Header blk)) => Point blk -> AnchoredFragment (Header blk) -> ReaderState m blk b -> ReaderState m blk b

-- | Close all open block and header <a>Reader</a>s.
closeAllReaders :: IOLike m => ChainDbEnv m blk -> m ()


-- | Iterators
module Ouroboros.Consensus.Storage.ChainDB.Impl.Iterator

-- | Stream blocks
--   
--   <h1>Start &amp; end point</h1>
--   
--   The start point can either be in the ImmutableDB (on our chain) or in
--   the VolatileDB (on our chain or on a recent fork). We first check
--   whether it is in the VolatileDB, if not, we check if it is in the
--   ImmutableDB (see "Garbage collection" for why this order is
--   important). Similarly for the end point.
--   
--   If a bound can't be found in the ChainDB, an <a>UnknownRange</a> error
--   is returned.
--   
--   When the bounds are nonsensical, e.g., &gt; StreamFromExclusive (Point
--   (SlotNo 3) _) &gt; StreamToInclusive (RealPoint (SlotNo 3) _) An
--   <a>InvalidIteratorRange</a> exception is thrown.
--   
--   <h1>Paths of blocks</h1>
--   
--   To stream blocks from the ImmutableDB we can simply use the iterators
--   offered by the ImmutableDB.
--   
--   To stream blocks from the VolatileDB we have to construct a path of
--   points backwards through the VolatileDB, starting from the end point
--   using <tt>getPredecessor</tt> until we get to the start point,
--   genesis, or we get to a block that is not in the VolatileDB. Then, for
--   each point in the path, we can ask the VolatileDB for the
--   corresponding block.
--   
--   If the path through the VolatileDB is incomplete, we will first have
--   to stream blocks from the ImmutableDB and then switch to the path
--   through the VolatileDB. We only allow the tip of the ImmutableDB to be
--   the switchover point between the two DBs. In other words, the
--   incomplete path through the VolatileDB must fit onto the tip of the
--   ImmutableDB. This must be true at the time of initialising the
--   iterator, but does not have to hold during the whole lifetime of the
--   iterator. If it doesn't fit on it, it means the path forked off more
--   than <tt>k</tt> blocks in the past and blocks belonging to it are more
--   likely to go missing because of garbage-collection (see the next
--   paragraph). In that case, we return <a>ForkTooOld</a>.
--   
--   <h1>Garbage collection</h1>
--   
--   We have to be careful about the following: as our chain grows, blocks
--   from our chain will be copied to the ImmutableDB in the background.
--   After a while, old blocks will be garbage-collected from the
--   VolatileDB. Blocks that were part of the current chain will be in the
--   ImmutableDB, but blocks that only lived on forks will be gone forever.
--   
--   This means that blocks that were part of the VolatileDB when the
--   iterator was initialised might no longer be part of the VolatileDB
--   when we come to the point that the iterator will try to read them.
--   When this is noticed, we will try to open an iterator from the
--   ImmutableDB to obtain the blocks that have moved over. However, this
--   will only work if they were and are part of the current chain,
--   otherwise they will have been deleted from the VolatileDB without
--   being copied to the ImmutableDB.
--   
--   This iterator is opened with an open upper bound and will be used to
--   stream blocks until the path has been fully streamed, the iterator is
--   exhausted, or a block doesn't match the expected point. In the latter
--   two cases, we switch back to the VolatileDB. If the block is missing
--   from the VolatileDB, we will switch back to streaming from the
--   ImmutableDB. If that fails, we switch back to the VolatileDB. To avoid
--   eternally switching between the two DBs, we only switch back to the
--   VolatileDB if the stream from the ImmutableDB has made progress, i.e.
--   streamed at least one block with the expected point. If no block was
--   streamed from the ImmutableDB, not even the first one, we know for
--   sure that that block isn't part of the VolatileDB (the reason we
--   switch to the ImmutableDB) and isn't part of the ImmutableDB (no block
--   was streamed). In that case, we return <a>IteratorBlockGCed</a> and
--   stop the stream.
--   
--   Note that the open upper bound doesn't allow us to include blocks in
--   the stream that are copied to the ImmutableDB after opening this
--   iterator, as the bound of the iterator is fixed upon initialisation.
--   These newly added blocks will be included in the stream because we
--   will repeatedly open new ImmutableDB iterators (as long as we make
--   progress).
--   
--   <h1>Bounds checking</h1>
--   
--   The VolatileDB is hash-based instead of point-based. While the bounds
--   of a stream are <i>point</i>s, we can simply check whether the hashes
--   of the bounds match the hashes stored in the points.
--   
--   The ImmutableDB is slot-based instead of point-based, which means that
--   before we know whether a block in the ImmutableDB matches a given
--   point, we must first read the block's hash corresponding to the
--   point's slot from the (cached) on-disk indices, after which we can
--   then verify whether it matches the hash of the point. This is
--   important for the start and end bounds (both points) of a stream in
--   case they are in the ImmutableDB (i.e., their slots are &lt;= the tip
--   of the ImmutableDB): we must first read the hashes corresponding to
--   the bounds from the (cached) on-disk indices to be sure the range is
--   valid. Note that these reads happen before the first call to
--   <a>iteratorNext</a>.
--   
--   Note that when streaming to an <i>exclusive</i> bound, the block
--   corresponding to that bound (<a>Point</a>) must exist in the ChainDB.
--   
--   The ImmutableDB will keep the on-disk indices of a chunk of blocks in
--   memory after the first read so that the next lookup doesn't have to
--   read from disk. When both bounds are in the same chunk, which will
--   typically be the case, only checking the first bound will require disk
--   reads, the second will be cached.
--   
--   <h1>Costs</h1>
--   
--   Opening an iterator has some costs:
--   
--   <ul>
--   <li>When blocks have to be streamed from the ImmutableDB: as discussed
--   in "Bounds checking", the hashes corresponding to the bounds have to
--   be read from the (cached) on-disk indices.</li>
--   <li>When blocks have to be streamed both from the ImmutableDB and the
--   VolatileDB, only the hash of the block corresponding to the lower
--   bound will have to be read from the ImmutableDB upfront, as described
--   in the previous bullet point. Note that the hash of the block
--   corresponding to the upper bound does not have to be read from disk,
--   since it will be in the VolatileDB, which means that we know its hash
--   already from the in-memory index.</li>
--   </ul>
--   
--   In summary:
--   
--   <ul>
--   <li>Only streaming from the VolatileDB: 0 (cached) reads from disk
--   upfront.</li>
--   <li>Only streaming from the ImmutableDB: 2 (cached) reads from disk
--   upfront.</li>
--   <li>Streaming from both the ImmutableDB and the VolatileDB: 1 (cached)
--   read from disk upfront.</li>
--   </ul>
--   
--   Additionally, when we notice during streaming that a block is no
--   longer in the VolatileDB, we try to see whether it can be streamed
--   from the ImmutableDB instead. Opening such an iterator costs 2
--   (cached) reads from disk upfront. This can happen multiple times.
stream :: forall m blk b. (IOLike m, HasHeader blk, HasCallStack) => ChainDbHandle m blk -> ResourceRegistry m -> BlockComponent blk b -> StreamFrom blk -> StreamTo blk -> m (Either (UnknownRange blk) (Iterator m blk b))

-- | Close all open <a>Iterator</a>s.
--   
--   This <i>can</i> be called when the ChainDB is already closed.
closeAllIterators :: IOLike m => ChainDbEnv m blk -> m ()

-- | Environment containing everything needed to implement iterators.
--   
--   The main purpose of bundling these things in a separate record is to
--   make it easier to test this code: no need to set up a whole ChainDB,
--   just provide this record.
data IteratorEnv m blk
IteratorEnv :: ImmutableDB m blk -> VolatileDB m blk -> StrictTVar m (Map IteratorKey (m ())) -> StrictTVar m IteratorKey -> Tracer m (TraceIteratorEvent blk) -> IteratorEnv m blk
[itImmutableDB] :: IteratorEnv m blk -> ImmutableDB m blk
[itVolatileDB] :: IteratorEnv m blk -> VolatileDB m blk
[itIterators] :: IteratorEnv m blk -> StrictTVar m (Map IteratorKey (m ()))
[itNextIteratorKey] :: IteratorEnv m blk -> StrictTVar m IteratorKey
[itTracer] :: IteratorEnv m blk -> Tracer m (TraceIteratorEvent blk)

-- | See <a>stream</a>.
newIterator :: forall m blk b. (IOLike m, HasHeader blk, HasCallStack) => IteratorEnv m blk -> (forall r. (IteratorEnv m blk -> m r) -> m r) -> ResourceRegistry m -> BlockComponent blk b -> StreamFrom blk -> StreamTo blk -> m (Either (UnknownRange blk) (Iterator m blk b))
instance (Ouroboros.Network.Block.StandardHash blk, Data.Typeable.Internal.Typeable blk) => NoThunks.Class.NoThunks (Ouroboros.Consensus.Storage.ChainDB.Impl.Iterator.InImmutableDBEnd blk)
instance GHC.Generics.Generic (Ouroboros.Consensus.Storage.ChainDB.Impl.Iterator.InImmutableDBEnd blk)
instance GHC.Generics.Generic (Ouroboros.Consensus.Storage.ChainDB.Impl.Iterator.IteratorState m blk b)
instance (Data.Typeable.Internal.Typeable blk, Ouroboros.Network.Block.StandardHash blk) => NoThunks.Class.NoThunks (Ouroboros.Consensus.Storage.ChainDB.Impl.Iterator.IteratorState m blk b)


-- | Operations involving chain selection: the initial chain selection and
--   adding a block.
module Ouroboros.Consensus.Storage.ChainDB.Impl.ChainSel

-- | Perform the initial chain selection based on the tip of the
--   ImmutableDB and the contents of the VolatileDB.
--   
--   Returns the chosen validated chain and corresponding ledger.
--   
--   See "## Initialization" in ChainDB.md.
initialChainSelection :: forall m blk. (IOLike m, LedgerSupportsProtocol blk) => ImmutableDB m blk -> VolatileDB m blk -> LgrDB m blk -> Tracer m (TraceEvent blk) -> TopLevelConfig blk -> StrictTVar m (WithFingerprint (InvalidBlocks blk)) -> StrictTVar m (FutureBlocks blk) -> CheckInFuture m blk -> m (ChainAndLedger blk)

-- | Add a block to the ChainDB, <i>asynchronously</i>.
--   
--   This adds a <a>BlockToAdd</a> corresponding to the given block to the
--   <a>cdbBlocksToAdd</a> queue. The entries in that queue are processed
--   using <a>addBlockSync</a>, see that function for more information.
--   
--   When the queue is full, this function will still block.
--   
--   An important advantage of this asynchronous approach over a
--   synchronous approach is that it doesn't have the following
--   disadvantage: when a thread adding a block to the ChainDB is killed,
--   which can happen when disconnecting from the corresponding node, we
--   might have written the block to disk, but not updated the
--   corresponding in-memory state (e.g., that of the VolatileDB), leaving
--   both out of sync.
--   
--   With this asynchronous approach, threads adding blocks asynchronously
--   can be killed without worries, the background thread processing the
--   blocks synchronously won't be killed. Only when the whole ChainDB
--   shuts down will that background thread get killed. But since there
--   will be no more in-memory state, it can't get out of sync with the
--   file system state. On the next startup, a correct in-memory state will
--   be reconstructed from the file system state.
addBlockAsync :: forall m blk. (IOLike m, HasHeader blk) => ChainDbEnv m blk -> blk -> m (AddBlockPromise m blk)

-- | Add a block to the ChainDB, <i>synchronously</i>.
--   
--   This is the only operation that actually changes the ChainDB. It will
--   store the block on disk and trigger chain selection, possibly
--   switching to a fork.
--   
--   When the slot of the block is &gt; the current slot, a chain selection
--   will be scheduled in the slot of the block.
addBlockSync :: forall m blk. (IOLike m, GetPrevHash blk, LedgerSupportsProtocol blk, InspectLedger blk, HasHardForkHistory blk, HasCallStack) => ChainDbEnv m blk -> BlockToAdd m blk -> m ()

-- | Trigger chain selection for the given block.
--   
--   PRECONDITION: the block is in the VolatileDB.
--   
--   PRECONDITION: the slot of the block &lt;= the current (wall) slot
--   
--   The new tip of the current chain is returned.
--   
--   <h1>Constructing candidate fragments</h1>
--   
--   The VolatileDB keeps a "successors" map in memory, telling us the
--   hashes of the known successors of any block, but it does not keep
--   <i>headers</i> in memory, which are needed to construct candidate
--   fargments. We try to reuse the headers from the current chain fragment
--   where possible, but it will not contain all needed headers. This means
--   that we will need to read some blocks from disk and extract their
--   headers. Under normal circumstances this does not matter too much;
--   although this will be done every time we add a block, the expected
--   number of headers to read from disk is very small:
--   
--   <ul>
--   <li>None if we stay on the current chain and this is just the next
--   block</li>
--   <li>A handful if we stay on the current chain and the block we just
--   received was a missing block and we already received some of its
--   successors</li>
--   <li>A handful if we switch to a short fork</li>
--   </ul>
--   
--   This is expensive only
--   
--   <ul>
--   <li>on startup: in this case we need to read at least <tt>k</tt>
--   blocks from the VolatileDB, and possibly more if there are some other
--   chains in the VolatileDB starting from the tip of the ImmutableDB</li>
--   <li>when we switch to a distant fork</li>
--   </ul>
--   
--   This cost is currently deemed acceptable.
chainSelectionForBlock :: forall m blk. (IOLike m, HasHeader blk, LedgerSupportsProtocol blk, InspectLedger blk, HasHardForkHistory blk, HasCallStack) => ChainDbEnv m blk -> BlockCache blk -> Header blk -> m (Point blk)

-- | Return <a>True</a> when the given header should be ignored when adding
--   it because it is too old, i.e., we wouldn't be able to switch to a
--   chain containing the corresponding block because its block number is
--   more than <tt>k</tt> blocks or exactly <tt>k</tt> blocks back.
--   
--   Special case: the header corresponds to an EBB which has the same
--   block number as the block <tt>k</tt> blocks back (the most recent
--   "immutable" block). As EBBs share their block number with the block
--   before them, the EBB is not too old in that case and can be adopted as
--   part of our chain.
--   
--   This special case can occur, for example, when the VolatileDB is empty
--   (because of corruption). The "immutable" block is then also the tip of
--   the chain. If we then try to add the EBB after it, it will have the
--   same block number, so we must allow it.
olderThanK :: HasHeader (Header blk) => Header blk -> IsEBB -> WithOrigin BlockNo -> Bool


-- | Background tasks:
--   
--   <ul>
--   <li>Copying blocks from the VolatileDB to the ImmutableDB</li>
--   <li>Performing and scheduling garbage collections on the
--   VolatileDB</li>
--   <li>Writing snapshots of the LedgerDB to disk and deleting old
--   ones</li>
--   <li>Executing scheduled chain selections</li>
--   </ul>
module Ouroboros.Consensus.Storage.ChainDB.Impl.Background
launchBgTasks :: forall m blk. (IOLike m, LedgerSupportsProtocol blk, InspectLedger blk, HasHardForkHistory blk, LgrDbSerialiseConstraints blk) => ChainDbEnv m blk -> Word64 -> m ()

-- | Copy the blocks older than <tt>k</tt> from the VolatileDB to the
--   ImmutableDB.
--   
--   These headers of these blocks can be retrieved by dropping the
--   <tt>k</tt> most recent blocks from the fragment stored in
--   <a>cdbChain</a>.
--   
--   The copied blocks are removed from the fragment stored in
--   <a>cdbChain</a>.
--   
--   This function does not remove blocks from the VolatileDB.
--   
--   The <a>SlotNo</a> of the tip of the ImmutableDB after copying the
--   blocks is returned. This can be used for a garbage collection on the
--   VolatileDB.
--   
--   NOTE: this function would not be safe when called multiple times
--   concurrently. To enforce thread-safety, a lock is obtained at the
--   start of this function and released at the end. So in practice, this
--   function can be called multiple times concurrently, but the calls will
--   be serialised.
--   
--   NOTE: this function <i>can</i> run concurrently with all other
--   functions, just not with itself.
copyToImmutableDB :: forall m blk. (IOLike m, ConsensusProtocol (BlockProtocol blk), HasHeader blk, GetHeader blk, HasCallStack) => ChainDbEnv m blk -> m (WithOrigin SlotNo)

-- | Copy blocks from the VolatileDB to ImmutableDB and take snapshots of
--   the LgrDB
--   
--   We watch the chain for changes. Whenever the chain is longer than
--   <tt>k</tt>, then the headers older than <tt>k</tt> are copied from the
--   VolatileDB to the ImmutableDB (using <a>copyToImmutableDB</a>). Once
--   that is complete,
--   
--   <ul>
--   <li>We periodically take a snapshot of the LgrDB (depending on its
--   config). When enough blocks (depending on its config) have been
--   replayed during startup, a snapshot of the replayed LgrDB will be
--   written to disk at the start of this function. NOTE: After this
--   initial snapshot we do not take a snapshot of the LgrDB until the
--   chain has changed again, irrespective of the LgrDB policy.</li>
--   <li>Schedule GC of the VolatileDB (<a>scheduleGC</a>) for the
--   <a>SlotNo</a> of the most recent block that was copied.</li>
--   </ul>
--   
--   It is important that we only take LgrDB snapshots when are are
--   <i>sure</i> they have been copied to the ImmutableDB, since the LgrDB
--   assumes that all snapshots correspond to immutable blocks. (Of course,
--   data corruption can occur and we can handle it by reverting to an
--   older LgrDB snapshot, but we should need this only in exceptional
--   circumstances.)
--   
--   We do not store any state of the VolatileDB GC. If the node shuts down
--   before GC can happen, when we restart the node and schedule the
--   <i>next</i> GC, it will <i>imply</i> any previously scheduled GC,
--   since GC is driven by slot number ("garbage collect anything older
--   than <tt>x</tt>").
copyAndSnapshotRunner :: forall m blk. (IOLike m, ConsensusProtocol (BlockProtocol blk), HasHeader blk, GetHeader blk, LgrDbSerialiseConstraints blk) => ChainDbEnv m blk -> GcSchedule m -> Word64 -> m Void

-- | Write a snapshot of the LedgerDB to disk and remove old snapshots
--   (typically one) so that only <tt>onDiskNumSnapshots</tt> snapshots are
--   on disk.
updateLedgerSnapshots :: (IOLike m, LgrDbSerialiseConstraints blk) => ChainDbEnv m blk -> m ()

-- | Trigger a garbage collection for blocks older than the given
--   <a>SlotNo</a> on the VolatileDB.
--   
--   Also removes the corresponding cached "previously applied points" from
--   the LedgerDB.
--   
--   This is thread-safe as the VolatileDB locks itself while performing a
--   GC.
--   
--   TODO will a long GC be a bottleneck? It will block any other calls to
--   <tt>putBlock</tt> and <tt>getBlock</tt>.
garbageCollect :: forall m blk. IOLike m => ChainDbEnv m blk -> SlotNo -> m ()

-- | Scheduled garbage collections
--   
--   When a block has been copied to the ImmutableDB, we schedule a
--   VolatileDB garbage collection for the slot corresponding to the block
--   in the future. How far in the future is determined by the
--   <a>gcDelay</a> parameter. The goal is to allow some overlap so that
--   the write to the ImmutableDB will have been flushed to disk before the
--   block is removed from the VolatileDB.
--   
--   We store scheduled garbage collections in a LIFO queue. Since the
--   queue will be very short (see further down for why) and entries are
--   more often added (at the block sync speed by a single thread) than
--   removed (once every <a>gcInterval</a>), we simply use a
--   <a>StrictSeq</a> stored in a <tt>TVar</tt> to make reasoning and
--   testing easier. Entries are enqueued at the end (right) and dequeued
--   from the head (left).
--   
--   The <a>Time</a>s in the queue will be monotonically increasing. A
--   fictional example (with hh:mm:ss):
--   
--   <pre>
--   [(16:01:12, SlotNo 1012), (16:04:38, SlotNo 1045), ..]
--   </pre>
--   
--   Scheduling a garbage collection with <a>scheduleGC</a> will add an
--   entry to the end of the queue for the given slot at the time equal to
--   now (<a>getMonotonicTime</a>) + the <tt>gcDelay</tt> rounded to
--   <tt>gcInterval</tt>. Unless the last entry in the queue was scheduled
--   for the same rounded time, in that case the new entry replaces the
--   existing entry. The goal of this is to batch garbage collections so
--   that, when possible, at most one garbage collection happens every
--   <tt>gcInterval</tt>.
--   
--   For example, starting with an empty queue and <tt>gcDelay = 5min</tt>
--   and <tt>gcInterval = 10s</tt>:
--   
--   At 8:43:22, we schedule a GC for slot 10:
--   
--   <pre>
--   [(8:48:30, SlotNo 10)]
--   </pre>
--   
--   The scheduled time is rounded up to the next interval. Next, at
--   8:43:24, we schedule a GC for slot 11:
--   
--   <pre>
--   [(8:48:30, SlotNo 11)]
--   </pre>
--   
--   Note that the existing entry is replaced with the new one, as they map
--   to the same <tt>gcInterval</tt>. Instead of two GCs 2 seconds apart,
--   we will only schedule one GC.
--   
--   Next, at 8:44:02, we schedule a GC for slot 12:
--   
--   <pre>
--   [(8:48:30, SlotNo 11), (8:49:10, SlotNo 12)]
--   </pre>
--   
--   Now, a new entry was appended to the queue, as it doesn't map to the
--   same <tt>gcInterval</tt> as the last one.
--   
--   In other words, everything scheduled in the first 10s will be done
--   after 20s. The bounds are the open-closed interval:
--   
--   <pre>
--   (now + gcDelay, now + gcDelay + gcInterval]
--   </pre>
--   
--   Whether we're syncing at high speed or downloading blocks as they are
--   produced, the length of the queue will be at most <tt>⌈gcDelay /
--   gcInterval⌉ + 1</tt>, e.g., 5min / 10s = 31 entries. The <tt>+ 1</tt>
--   is needed because we might be somewhere in the middle of a
--   <tt>gcInterval</tt>.
--   
--   The background thread will look at head of the queue and wait until
--   that has <a>Time</a> passed. After the wait, it will pop off the head
--   of the queue and perform a garbage collection for the <a>SlotNo</a> in
--   the head. Note that the <a>SlotNo</a> before the wait can be different
--   from the one after the wait, precisely because of batching.
data GcSchedule m
data GcParams
GcParams :: !DiffTime -> !DiffTime -> GcParams

-- | How long to wait until performing the GC. See <tt>cdbsGcDelay</tt>.
[gcDelay] :: GcParams -> !DiffTime

-- | The GC interval: the minimum time between two GCs. See
--   <tt>cdbsGcInterval</tt>.
[gcInterval] :: GcParams -> !DiffTime
newGcSchedule :: IOLike m => m (GcSchedule m)
scheduleGC :: forall m blk. IOLike m => Tracer m (TraceGCEvent blk) -> SlotNo -> GcParams -> GcSchedule m -> m ()
computeTimeForGC :: GcParams -> Time -> Time
gcScheduleRunner :: forall m. IOLike m => GcSchedule m -> (SlotNo -> m ()) -> m Void
data ScheduledGc
ScheduledGc :: !Time -> !SlotNo -> ScheduledGc

-- | Time at which to run the garbage collection
[scheduledGcTime] :: ScheduledGc -> !Time

-- | For which slot to run the garbage collection
[scheduledGcSlot] :: ScheduledGc -> !SlotNo

-- | Return the current contents of the <a>GcSchedule</a> queue without
--   modifying it.
--   
--   For testing purposes.
dumpGcSchedule :: IOLike m => GcSchedule m -> STM m [ScheduledGc]

-- | Read blocks from <a>cdbBlocksToAdd</a> and add them synchronously to
--   the ChainDB.
addBlockRunner :: (IOLike m, LedgerSupportsProtocol blk, InspectLedger blk, HasHardForkHistory blk, HasCallStack) => ChainDbEnv m blk -> m Void
instance NoThunks.Class.NoThunks Ouroboros.Consensus.Storage.ChainDB.Impl.Background.ScheduledGc
instance GHC.Generics.Generic Ouroboros.Consensus.Storage.ChainDB.Impl.Background.ScheduledGc
instance GHC.Show.Show Ouroboros.Consensus.Storage.ChainDB.Impl.Background.ScheduledGc
instance GHC.Classes.Eq Ouroboros.Consensus.Storage.ChainDB.Impl.Background.ScheduledGc
instance GHC.Show.Show Ouroboros.Consensus.Storage.ChainDB.Impl.Background.GcParams
instance Ouroboros.Consensus.Util.Condense.Condense Ouroboros.Consensus.Storage.ChainDB.Impl.Background.ScheduledGc

module Ouroboros.Consensus.Storage.ChainDB.Impl.Args
data ChainDbArgs f m blk
ChainDbArgs :: SomeHasFS m -> SomeHasFS m -> SomeHasFS m -> ValidationPolicy -> BlockValidationPolicy -> BlocksPerFile -> HKD f LedgerDbParams -> HKD f DiskPolicy -> HKD f (TopLevelConfig blk) -> HKD f ChunkInfo -> HKD f (blk -> Bool) -> HKD f (m (ExtLedgerState blk)) -> HKD f (CheckInFuture m blk) -> CacheConfig -> Tracer m (TraceEvent blk) -> Tracer m (LedgerDB' blk) -> HKD f (ResourceRegistry m) -> DiffTime -> DiffTime -> Word -> ChainDbArgs f m blk
[cdbHasFSImmutableDB] :: ChainDbArgs f m blk -> SomeHasFS m
[cdbHasFSVolatileDB] :: ChainDbArgs f m blk -> SomeHasFS m
[cdbHasFSLgrDB] :: ChainDbArgs f m blk -> SomeHasFS m
[cdbImmutableDbValidation] :: ChainDbArgs f m blk -> ValidationPolicy
[cdbVolatileDbValidation] :: ChainDbArgs f m blk -> BlockValidationPolicy
[cdbMaxBlocksPerFile] :: ChainDbArgs f m blk -> BlocksPerFile
[cdbParamsLgrDB] :: ChainDbArgs f m blk -> HKD f LedgerDbParams
[cdbDiskPolicy] :: ChainDbArgs f m blk -> HKD f DiskPolicy
[cdbTopLevelConfig] :: ChainDbArgs f m blk -> HKD f (TopLevelConfig blk)
[cdbChunkInfo] :: ChainDbArgs f m blk -> HKD f ChunkInfo
[cdbCheckIntegrity] :: ChainDbArgs f m blk -> HKD f (blk -> Bool)
[cdbGenesis] :: ChainDbArgs f m blk -> HKD f (m (ExtLedgerState blk))
[cdbCheckInFuture] :: ChainDbArgs f m blk -> HKD f (CheckInFuture m blk)
[cdbImmutableDbCacheConfig] :: ChainDbArgs f m blk -> CacheConfig
[cdbTracer] :: ChainDbArgs f m blk -> Tracer m (TraceEvent blk)
[cdbTraceLedger] :: ChainDbArgs f m blk -> Tracer m (LedgerDB' blk)
[cdbRegistry] :: ChainDbArgs f m blk -> HKD f (ResourceRegistry m)
[cdbGcDelay] :: ChainDbArgs f m blk -> DiffTime
[cdbGcInterval] :: ChainDbArgs f m blk -> DiffTime

-- | Size of the queue used to store asynchronously added blocks. This is
--   the maximum number of blocks that could be kept in memory at the same
--   time when the background thread processing the blocks can't keep up.
[cdbBlocksToAddSize] :: ChainDbArgs f m blk -> Word

-- | Arguments specific to the ChainDB, not to the ImmutableDB, VolatileDB,
--   or LedgerDB.
data ChainDbSpecificArgs f m blk
ChainDbSpecificArgs :: Word -> HKD f (CheckInFuture m blk) -> DiffTime -> DiffTime -> HKD f (ResourceRegistry m) -> Tracer m (TraceEvent blk) -> ChainDbSpecificArgs f m blk
[cdbsBlocksToAddSize] :: ChainDbSpecificArgs f m blk -> Word
[cdbsCheckInFuture] :: ChainDbSpecificArgs f m blk -> HKD f (CheckInFuture m blk)

-- | Delay between copying a block to the ImmutableDB and triggering a
--   garbage collection for the corresponding slot on the VolatileDB.
--   
--   The goal of the delay is to ensure that the write to the ImmutableDB
--   has been flushed to disk before deleting the block from the
--   VolatileDB, so that a crash won't result in the loss of the block.
[cdbsGcDelay] :: ChainDbSpecificArgs f m blk -> DiffTime

-- | Batch all scheduled GCs so that at most one GC happens every
--   <a>cdbsGcInterval</a>.
[cdbsGcInterval] :: ChainDbSpecificArgs f m blk -> DiffTime

-- | TODO: the ImmutableDB takes a <a>ResourceRegistry</a> too, but we're
--   using it for ChainDB-specific things. Revisit these arguments.
[cdbsRegistry] :: ChainDbSpecificArgs f m blk -> HKD f (ResourceRegistry m)
[cdbsTracer] :: ChainDbSpecificArgs f m blk -> Tracer m (TraceEvent blk)

-- | Default arguments for use within IO
--   
--   See <a>defaultArgs</a>, <a>defaultArgs</a>, <a>defaultArgs</a>, and
--   <a>defaultSpecificArgs</a> for a list of which fields are not given a
--   default and must therefore be set explicitly.
defaultArgs :: FilePath -> ChainDbArgs Defaults IO blk

-- | Internal: split <a>ChainDbArgs</a> into <tt>ImmutableDbArgs</tt>,
--   'VolatileDbArgs, <tt>LgrDbArgs</tt>, and <a>ChainDbSpecificArgs</a>.
fromChainDbArgs :: forall m blk f. MapHKD f => ChainDbArgs f m blk -> (ImmutableDbArgs f m blk, VolatileDbArgs f m blk, LgrDbArgs f m blk, ChainDbSpecificArgs f m blk)

module Ouroboros.Consensus.Storage.ChainDB.Impl
data ChainDbArgs f m blk
ChainDbArgs :: SomeHasFS m -> SomeHasFS m -> SomeHasFS m -> ValidationPolicy -> BlockValidationPolicy -> BlocksPerFile -> HKD f LedgerDbParams -> HKD f DiskPolicy -> HKD f (TopLevelConfig blk) -> HKD f ChunkInfo -> HKD f (blk -> Bool) -> HKD f (m (ExtLedgerState blk)) -> HKD f (CheckInFuture m blk) -> CacheConfig -> Tracer m (TraceEvent blk) -> Tracer m (LedgerDB' blk) -> HKD f (ResourceRegistry m) -> DiffTime -> DiffTime -> Word -> ChainDbArgs f m blk
[cdbHasFSImmutableDB] :: ChainDbArgs f m blk -> SomeHasFS m
[cdbHasFSVolatileDB] :: ChainDbArgs f m blk -> SomeHasFS m
[cdbHasFSLgrDB] :: ChainDbArgs f m blk -> SomeHasFS m
[cdbImmutableDbValidation] :: ChainDbArgs f m blk -> ValidationPolicy
[cdbVolatileDbValidation] :: ChainDbArgs f m blk -> BlockValidationPolicy
[cdbMaxBlocksPerFile] :: ChainDbArgs f m blk -> BlocksPerFile
[cdbParamsLgrDB] :: ChainDbArgs f m blk -> HKD f LedgerDbParams
[cdbDiskPolicy] :: ChainDbArgs f m blk -> HKD f DiskPolicy
[cdbTopLevelConfig] :: ChainDbArgs f m blk -> HKD f (TopLevelConfig blk)
[cdbChunkInfo] :: ChainDbArgs f m blk -> HKD f ChunkInfo
[cdbCheckIntegrity] :: ChainDbArgs f m blk -> HKD f (blk -> Bool)
[cdbGenesis] :: ChainDbArgs f m blk -> HKD f (m (ExtLedgerState blk))
[cdbCheckInFuture] :: ChainDbArgs f m blk -> HKD f (CheckInFuture m blk)
[cdbImmutableDbCacheConfig] :: ChainDbArgs f m blk -> CacheConfig
[cdbTracer] :: ChainDbArgs f m blk -> Tracer m (TraceEvent blk)
[cdbTraceLedger] :: ChainDbArgs f m blk -> Tracer m (LedgerDB' blk)
[cdbRegistry] :: ChainDbArgs f m blk -> HKD f (ResourceRegistry m)
[cdbGcDelay] :: ChainDbArgs f m blk -> DiffTime
[cdbGcInterval] :: ChainDbArgs f m blk -> DiffTime

-- | Size of the queue used to store asynchronously added blocks. This is
--   the maximum number of blocks that could be kept in memory at the same
--   time when the background thread processing the blocks can't keep up.
[cdbBlocksToAddSize] :: ChainDbArgs f m blk -> Word

-- | Default arguments for use within IO
--   
--   See <a>defaultArgs</a>, <a>defaultArgs</a>, <a>defaultArgs</a>, and
--   <a>defaultSpecificArgs</a> for a list of which fields are not given a
--   default and must therefore be set explicitly.
defaultArgs :: FilePath -> ChainDbArgs Defaults IO blk

-- | All the serialisation related constraints needed by the ChainDB.
class (ImmutableDbSerialiseConstraints blk, LgrDbSerialiseConstraints blk, VolatileDbSerialiseConstraints blk, EncodeDiskDep (NestedCtxt Header) blk) => SerialiseDiskConstraints blk
withDB :: forall m blk a. (IOLike m, LedgerSupportsProtocol blk, InspectLedger blk, HasHardForkHistory blk, ConvertRawHash blk, SerialiseDiskConstraints blk) => ChainDbArgs Identity m blk -> (ChainDB m blk -> m a) -> m a
openDB :: forall m blk. (IOLike m, LedgerSupportsProtocol blk, InspectLedger blk, HasHardForkHistory blk, ConvertRawHash blk, SerialiseDiskConstraints blk) => ChainDbArgs Identity m blk -> m (ChainDB m blk)

-- | Trace type for the various events of the ChainDB.
data TraceEvent blk
TraceAddBlockEvent :: TraceAddBlockEvent blk -> TraceEvent blk
TraceReaderEvent :: TraceReaderEvent blk -> TraceEvent blk
TraceCopyToImmutableDBEvent :: TraceCopyToImmutableDBEvent blk -> TraceEvent blk
TraceGCEvent :: TraceGCEvent blk -> TraceEvent blk
TraceInitChainSelEvent :: TraceInitChainSelEvent blk -> TraceEvent blk
TraceOpenEvent :: TraceOpenEvent blk -> TraceEvent blk
TraceIteratorEvent :: TraceIteratorEvent blk -> TraceEvent blk
TraceLedgerEvent :: TraceEvent blk -> TraceEvent blk
TraceLedgerReplayEvent :: TraceLedgerReplayEvent blk -> TraceEvent blk
TraceImmutableDBEvent :: TraceEvent blk -> TraceEvent blk
TraceVolatileDBEvent :: TraceEvent blk -> TraceEvent blk

-- | Information about the new tip of the current chain.
--   
--   NOTE: the fields of this record are intentionally lazy to prevent the
--   forcing of this information in case it doesn't have to be traced.
--   However, this means that the tracer processing this message <i>must
--   not</i> hold on to it, otherwise it leaks memory.
data NewTipInfo blk
NewTipInfo :: RealPoint blk -> EpochNo -> Word64 -> RealPoint blk -> NewTipInfo blk

-- | The new tip of the current chain.
[newTipPoint] :: NewTipInfo blk -> RealPoint blk

-- | The epoch of the new tip.
[newTipEpoch] :: NewTipInfo blk -> EpochNo

-- | The slot in the epoch, i.e., the relative slot number, of the new tip.
[newTipSlotInEpoch] :: NewTipInfo blk -> Word64

-- | The new tip of the current chain (<a>newTipPoint</a>) is the result of
--   performing chain selection for a <i>trigger</i> block
--   (<a>newTipTrigger</a>). In most cases, we add a new block to the tip
--   of the current chain, in which case the new tip <i>is</i> the trigger
--   block.
--   
--   However, this is not always the case. For example, with our current
--   chain being A and having a disconnected C lying around, adding B will
--   result in A -&gt; B -&gt; C as the new chain. The trigger B /= the new
--   tip C.
[newTipTrigger] :: NewTipInfo blk -> RealPoint blk

-- | Trace type for the various events that occur when adding a block.
data TraceAddBlockEvent blk

-- | A block with a <a>BlockNo</a> more than <tt>k</tt> back than the
--   current tip was ignored.
IgnoreBlockOlderThanK :: RealPoint blk -> TraceAddBlockEvent blk

-- | A block that is already in the Volatile DB was ignored.
IgnoreBlockAlreadyInVolatileDB :: RealPoint blk -> TraceAddBlockEvent blk

-- | A block that is know to be invalid was ignored.
IgnoreInvalidBlock :: RealPoint blk -> InvalidBlockReason blk -> TraceAddBlockEvent blk

-- | The block was added to the queue and will be added to the ChainDB by
--   the background thread. The size of the queue is included.
AddedBlockToQueue :: RealPoint blk -> Word -> TraceAddBlockEvent blk

-- | The block is from the future, i.e., its slot number is greater than
--   the current slot (the second argument).
BlockInTheFuture :: RealPoint blk -> SlotNo -> TraceAddBlockEvent blk

-- | A block was added to the Volatile DB
AddedBlockToVolatileDB :: RealPoint blk -> BlockNo -> IsEBB -> TraceAddBlockEvent blk

-- | The block fits onto the current chain, we'll try to use it to extend
--   our chain.
TryAddToCurrentChain :: RealPoint blk -> TraceAddBlockEvent blk

-- | The block fits onto some fork, we'll try to switch to that fork (if it
--   is preferable to our chain).
TrySwitchToAFork :: RealPoint blk -> ChainDiff (HeaderFields blk) -> TraceAddBlockEvent blk

-- | The block doesn't fit onto any other block, so we store it and ignore
--   it.
StoreButDontChange :: RealPoint blk -> TraceAddBlockEvent blk

-- | The new block fits onto the current chain (first fragment) and we have
--   successfully used it to extend our (new) current chain (second
--   fragment).
AddedToCurrentChain :: [LedgerEvent blk] -> NewTipInfo blk -> AnchoredFragment (Header blk) -> AnchoredFragment (Header blk) -> TraceAddBlockEvent blk

-- | The new block fits onto some fork and we have switched to that fork
--   (second fragment), as it is preferable to our (previous) current chain
--   (first fragment).
SwitchedToAFork :: [LedgerEvent blk] -> NewTipInfo blk -> AnchoredFragment (Header blk) -> AnchoredFragment (Header blk) -> TraceAddBlockEvent blk

-- | An event traced during validating performed while adding a block.
AddBlockValidation :: TraceValidationEvent blk -> TraceAddBlockEvent blk

-- | Run chain selection for a block that was previously from the future.
--   This is done for all blocks from the future each time a new block is
--   added.
ChainSelectionForFutureBlock :: RealPoint blk -> TraceAddBlockEvent blk
data TraceReaderEvent blk

-- | A new reader was created.
NewReader :: TraceReaderEvent blk

-- | The reader was in the <a>ReaderInMem</a> state but its point is no
--   longer on the in-memory chain fragment, so it has to switch to the
--   <a>ReaderInImmutableDB</a> state.
ReaderNoLongerInMem :: ReaderRollState blk -> TraceReaderEvent blk

-- | The reader was in the <a>ReaderInImmutableDB</a> state and is switched
--   to the <a>ReaderInMem</a> state.
ReaderSwitchToMem :: Point blk -> WithOrigin SlotNo -> TraceReaderEvent blk

-- | The reader is in the <a>ReaderInImmutableDB</a> state but the iterator
--   is exhausted while the ImmutableDB has grown, so we open a new
--   iterator to stream these blocks too.
ReaderNewImmIterator :: Point blk -> WithOrigin SlotNo -> TraceReaderEvent blk
data TraceCopyToImmutableDBEvent blk

-- | A block was successfully copied to the ImmutableDB.
CopiedBlockToImmutableDB :: Point blk -> TraceCopyToImmutableDBEvent blk

-- | There are no block to copy to the ImmutableDB.
NoBlocksToCopyToImmutableDB :: TraceCopyToImmutableDBEvent blk
data TraceGCEvent blk

-- | A garbage collection for the given <a>SlotNo</a> was scheduled to
--   happen at the given time.
ScheduledGC :: SlotNo -> Time -> TraceGCEvent blk

-- | A garbage collection for the given <a>SlotNo</a> was performed.
PerformedGC :: SlotNo -> TraceGCEvent blk
data TraceValidationEvent blk

-- | A point was found to be invalid.
InvalidBlock :: ExtValidationError blk -> RealPoint blk -> TraceValidationEvent blk

-- | A candidate chain was invalid.
InvalidCandidate :: AnchoredFragment (Header blk) -> TraceValidationEvent blk

-- | A candidate chain was valid.
ValidCandidate :: AnchoredFragment (Header blk) -> TraceValidationEvent blk

-- | Candidate contains headers from the future which do no exceed the
--   clock skew.
CandidateContainsFutureBlocks :: AnchoredFragment (Header blk) -> [Header blk] -> TraceValidationEvent blk

-- | Candidate contains headers from the future which exceed the clock
--   skew, making them invalid.
CandidateContainsFutureBlocksExceedingClockSkew :: AnchoredFragment (Header blk) -> [Header blk] -> TraceValidationEvent blk
data TraceInitChainSelEvent blk

-- | An event traced during validation performed while performing initial
--   chain selection.
InitChainSelValidation :: TraceValidationEvent blk -> TraceInitChainSelEvent blk
data TraceOpenEvent blk

-- | The ChainDB was opened.
OpenedDB :: Point blk -> Point blk -> TraceOpenEvent blk

-- | The ChainDB was closed.
ClosedDB :: Point blk -> Point blk -> TraceOpenEvent blk

-- | The ImmutableDB was opened.
OpenedImmutableDB :: Point blk -> ChunkNo -> TraceOpenEvent blk

-- | The VolatileDB was opened.
OpenedVolatileDB :: TraceOpenEvent blk

-- | The LedgerDB was opened.
OpenedLgrDB :: TraceOpenEvent blk
data TraceIteratorEvent blk

-- | An unknown range was requested, see <a>UnknownRange</a>.
UnknownRangeRequested :: UnknownRange blk -> TraceIteratorEvent blk

-- | Stream only from the VolatileDB.
StreamFromVolatileDB :: StreamFrom blk -> StreamTo blk -> [RealPoint blk] -> TraceIteratorEvent blk

-- | Stream only from the ImmutableDB.
StreamFromImmutableDB :: StreamFrom blk -> StreamTo blk -> TraceIteratorEvent blk

-- | Stream from both the VolatileDB and the ImmutableDB.
StreamFromBoth :: StreamFrom blk -> StreamTo blk -> [RealPoint blk] -> TraceIteratorEvent blk

-- | A block is no longer in the VolatileDB because it has been garbage
--   collected. It might now be in the ImmutableDB if it was part of the
--   current chain.
BlockMissingFromVolatileDB :: RealPoint blk -> TraceIteratorEvent blk

-- | A block that has been garbage collected from the VolatileDB is now
--   found and streamed from the ImmutableDB.
BlockWasCopiedToImmutableDB :: RealPoint blk -> TraceIteratorEvent blk

-- | A block is no longer in the VolatileDB and isn't in the ImmutableDB
--   either; it wasn't part of the current chain.
BlockGCedFromVolatileDB :: RealPoint blk -> TraceIteratorEvent blk

-- | We have streamed one or more blocks from the ImmutableDB that were
--   part of the VolatileDB when initialising the iterator. Now, we have to
--   look back in the VolatileDB again because the ImmutableDB doesn't have
--   the next block we're looking for.
SwitchBackToVolatileDB :: TraceIteratorEvent blk

-- | <a>TraceReplayEvent</a> instantiated with additional information.
--   
--   The <tt>replayTo</tt> parameter is instantiated with the <a>Point</a>
--   of the tip of the ImmutableDB.
type TraceLedgerReplayEvent blk = TraceReplayEvent blk (Point blk)

-- | <a>EncodeDisk</a> and <a>DecodeDisk</a> constraints needed for the
--   ImmutableDB.
type ImmutableDbSerialiseConstraints blk = (EncodeDisk blk blk, DecodeDisk blk (ByteString -> blk), DecodeDiskDep (NestedCtxt Header) blk, ReconstructNestedCtxt Header blk, HasBinaryBlockInfo blk)

-- | <a>EncodeDisk</a> and <a>DecodeDisk</a> constraints needed for the
--   LgrDB.
type LgrDbSerialiseConstraints blk = (Serialise (HeaderHash blk), EncodeDisk blk (LedgerState blk), DecodeDisk blk (LedgerState blk), EncodeDisk blk (AnnTip blk), DecodeDisk blk (AnnTip blk), EncodeDisk blk (ChainDepState (BlockProtocol blk)), DecodeDisk blk (ChainDepState (BlockProtocol blk)))

-- | <a>EncodeDisk</a> and <a>DecodeDisk</a> constraints needed for the
--   VolatileDB.
type VolatileDbSerialiseConstraints blk = (EncodeDisk blk blk, DecodeDisk blk (ByteString -> blk), DecodeDiskDep (NestedCtxt Header) blk, HasNestedContent Header blk, HasBinaryBlockInfo blk)
openDBInternal :: forall m blk. (IOLike m, LedgerSupportsProtocol blk, InspectLedger blk, HasHardForkHistory blk, ConvertRawHash blk, SerialiseDiskConstraints blk) => ChainDbArgs Identity m blk -> Bool -> m (ChainDB m blk, Internal m blk)
data Internal m blk
Internal :: m (WithOrigin SlotNo) -> (SlotNo -> m ()) -> m () -> m Void -> StrictTVar m (m ()) -> Internal m blk

-- | Copy the blocks older than <tt>k</tt> from to the VolatileDB to the
--   ImmutableDB and update the in-memory chain fragment correspondingly.
--   
--   The <a>SlotNo</a> of the tip of the ImmutableDB after copying the
--   blocks is returned. This can be used for a garbage collection on the
--   VolatileDB.
[intCopyToImmutableDB] :: Internal m blk -> m (WithOrigin SlotNo)

-- | Perform garbage collection for blocks &lt;= the given <a>SlotNo</a>.
[intGarbageCollect] :: Internal m blk -> SlotNo -> m ()

-- | Write a new LedgerDB snapshot to disk and remove the oldest one(s).
[intUpdateLedgerSnapshots] :: Internal m blk -> m ()

-- | Start the loop that adds blocks to the ChainDB retrieved from the
--   queue populated by <a>addBlock</a>. Execute this loop in a separate
--   thread.
[intAddBlockRunner] :: Internal m blk -> m Void

-- | A handle to kill the background threads.
[intKillBgThreads] :: Internal m blk -> StrictTVar m (m ())

module Ouroboros.Consensus.Storage.ChainDB

module Ouroboros.Consensus.MiniProtocol.ChainSync.Client
type Consensus (client :: Type -> Type -> Type -> (Type -> Type) -> Type -> Type) blk m = client (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult

-- | Chain sync client
--   
--   This never terminates. In case of a failure, a
--   <a>ChainSyncClientException</a> is thrown. The network layer
--   classifies exception such that the corresponding peer will never be
--   chosen again.
chainSyncClient :: forall m blk. (IOLike m, LedgerSupportsProtocol blk) => MkPipelineDecision -> Tracer m (TraceChainSyncClientEvent blk) -> TopLevelConfig blk -> ChainDbView m blk -> NodeToNodeVersion -> ControlMessageSTM m -> StrictTVar m (AnchoredFragment (Header blk)) -> Consensus ChainSyncClientPipelined blk m
bracketChainSyncClient :: (IOLike m, Ord peer, BlockSupportsProtocol blk, LedgerSupportsProtocol blk) => Tracer m (TraceChainSyncClientEvent blk) -> ChainDbView m blk -> StrictTVar m (Map peer (StrictTVar m (AnchoredFragment (Header blk)))) -> peer -> (StrictTVar m (AnchoredFragment (Header blk)) -> m a) -> m a

-- | The Chain sync client only _gracefully_ terminates when the upstream
--   node's chain is not interesting (e.g., forked off too far in the
--   past). By gracefully terminating, the network layer can keep the other
--   mini-protocols connect to the same upstream node running.
--   
--   For example, a relay node will often receive connections from nodes
--   syncing from scratch or an old chain. Since these nodes have a chain
--   that is shorter than the relay node's chain, it's useless for the
--   relay node to run the client-side of the chain sync protocol. However,
--   the other direction of the protocol, and, e.g., the transaction
--   submission protocol, should keep running.
data ChainSyncClientResult

-- | The server we're connecting to forked more than <tt>k</tt> blocks ago.
ForkTooDeep :: Point blk -> Our (Tip blk) -> Their (Tip blk) -> ChainSyncClientResult

-- | Our chain changed such that it no longer intersects with the
--   candidate's fragment, and asking for a new intersection did not yield
--   one.
NoMoreIntersection :: Our (Tip blk) -> Their (Tip blk) -> ChainSyncClientResult

-- | We were asked to roll back past the anchor point of the candidate's
--   fragment. This means the candidate chain no longer forks off within
--   <tt>k</tt>, making it impossible to switch to.
RolledBackPastIntersection :: Point blk -> Our (Tip blk) -> Their (Tip blk) -> ChainSyncClientResult

-- | We were asked to terminate via the <a>ControlMessageSTM</a>
AskedToTerminate :: ChainSyncClientResult

-- | When the upstream node violates the protocol or exhibits malicious
--   behaviour, e.g., serving an invalid header or a header corresponding
--   to a known invalid block, we throw an exception to disconnect. This
--   will bring down all miniprotocols in both directions with that node.
data ChainSyncClientException

-- | Header validation threw an error.
HeaderError :: Point blk -> HeaderError blk -> Our (Tip blk) -> Their (Tip blk) -> ChainSyncClientException

-- | We send the upstream node a bunch of points from a chain fragment and
--   the upstream node responded with an intersection point that is not on
--   our chain fragment, and thus not among the points we sent.
--   
--   We store the intersection point the upstream node sent us.
InvalidIntersection :: Point blk -> Our (Tip blk) -> Their (Tip blk) -> ChainSyncClientException

-- | The received header to roll forward doesn't fit onto the previous one.
--   
--   The first <a>ChainHash</a> is the previous hash of the received header
--   and the second <a>ChainHash</a> is that of the previous one.
DoesntFit :: ChainHash blk -> ChainHash blk -> Our (Tip blk) -> Their (Tip blk) -> ChainSyncClientException

-- | The upstream node's chain contained a block that we know is invalid.
InvalidBlock :: Point blk -> InvalidBlockReason blk -> ChainSyncClientException

-- | Abstract over the ChainDB
data ChainDbView m blk
ChainDbView :: STM m (AnchoredFragment (Header blk)) -> STM m (HeaderStateHistory blk) -> (Point blk -> STM m (Maybe (ExtLedgerState blk))) -> STM m (WithFingerprint (HeaderHash blk -> Maybe (InvalidBlockReason blk))) -> ChainDbView m blk
[$sel:getCurrentChain:ChainDbView] :: ChainDbView m blk -> STM m (AnchoredFragment (Header blk))
[$sel:getHeaderStateHistory:ChainDbView] :: ChainDbView m blk -> STM m (HeaderStateHistory blk)
[$sel:getPastLedger:ChainDbView] :: ChainDbView m blk -> Point blk -> STM m (Maybe (ExtLedgerState blk))
[$sel:getIsInvalidBlock:ChainDbView] :: ChainDbView m blk -> STM m (WithFingerprint (HeaderHash blk -> Maybe (InvalidBlockReason blk)))
defaultChainDbView :: ChainDB m blk -> ChainDbView m blk
newtype Our a
Our :: a -> Our a
[$sel:unOur:Our] :: Our a -> a
newtype Their a
Their :: a -> Their a
[$sel:unTheir:Their] :: Their a -> a

-- | Events traced by the Chain Sync Client.
data TraceChainSyncClientEvent blk

-- | While following a candidate chain, we rolled forward by downloading a
--   header.
TraceDownloadedHeader :: Header blk -> TraceChainSyncClientEvent blk

-- | While following a candidate chain, we rolled back to the given point.
TraceRolledBack :: Point blk -> TraceChainSyncClientEvent blk

-- | We found an intersection between our chain fragment and the
--   candidate's chain.
TraceFoundIntersection :: Point blk -> Our (Tip blk) -> Their (Tip blk) -> TraceChainSyncClientEvent blk

-- | An exception was thrown by the Chain Sync Client.
TraceException :: ChainSyncClientException -> TraceChainSyncClientEvent blk

-- | The reason why a block is invalid.
data InvalidBlockReason blk
instance NoThunks.Class.NoThunks a => NoThunks.Class.NoThunks (Ouroboros.Consensus.MiniProtocol.ChainSync.Client.Their a)
instance GHC.Show.Show a => GHC.Show.Show (Ouroboros.Consensus.MiniProtocol.ChainSync.Client.Their a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Ouroboros.Consensus.MiniProtocol.ChainSync.Client.Their a)
instance NoThunks.Class.NoThunks a => NoThunks.Class.NoThunks (Ouroboros.Consensus.MiniProtocol.ChainSync.Client.Our a)
instance GHC.Show.Show a => GHC.Show.Show (Ouroboros.Consensus.MiniProtocol.ChainSync.Client.Our a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Ouroboros.Consensus.MiniProtocol.ChainSync.Client.Our a)
instance GHC.Generics.Generic (Ouroboros.Consensus.MiniProtocol.ChainSync.Client.UnknownIntersectionState blk)
instance GHC.Generics.Generic (Ouroboros.Consensus.MiniProtocol.ChainSync.Client.KnownIntersectionState blk)
instance GHC.Show.Show Ouroboros.Consensus.MiniProtocol.ChainSync.Client.ChainSyncClientResult
instance GHC.Show.Show Ouroboros.Consensus.MiniProtocol.ChainSync.Client.ChainSyncClientException
instance (Ouroboros.Consensus.Block.SupportsProtocol.BlockSupportsProtocol blk, GHC.Classes.Eq (Ouroboros.Consensus.Protocol.Abstract.ValidationErr (Ouroboros.Consensus.Block.Abstract.BlockProtocol blk)), GHC.Classes.Eq (Ouroboros.Consensus.Block.Abstract.Header blk)) => GHC.Classes.Eq (Ouroboros.Consensus.MiniProtocol.ChainSync.Client.TraceChainSyncClientEvent blk)
instance (Ouroboros.Consensus.Block.SupportsProtocol.BlockSupportsProtocol blk, GHC.Show.Show (Ouroboros.Consensus.Block.Abstract.Header blk)) => GHC.Show.Show (Ouroboros.Consensus.MiniProtocol.ChainSync.Client.TraceChainSyncClientEvent blk)
instance GHC.Classes.Eq Ouroboros.Consensus.MiniProtocol.ChainSync.Client.ChainSyncClientException
instance GHC.Exception.Type.Exception Ouroboros.Consensus.MiniProtocol.ChainSync.Client.ChainSyncClientException
instance GHC.Classes.Eq Ouroboros.Consensus.MiniProtocol.ChainSync.Client.ChainSyncClientResult
instance Ouroboros.Consensus.Ledger.SupportsProtocol.LedgerSupportsProtocol blk => NoThunks.Class.NoThunks (Ouroboros.Consensus.MiniProtocol.ChainSync.Client.KnownIntersectionState blk)
instance Ouroboros.Consensus.Ledger.SupportsProtocol.LedgerSupportsProtocol blk => NoThunks.Class.NoThunks (Ouroboros.Consensus.MiniProtocol.ChainSync.Client.UnknownIntersectionState blk)

module Ouroboros.Consensus.MiniProtocol.BlockFetch.Server

-- | Block fetch server based on <a>mockBlockFetchServer1</a>, but using
--   the <a>ChainDB</a>.
blockFetchServer :: forall m blk. (IOLike m, StandardHash blk, Typeable blk) => Tracer m (TraceBlockFetchServerEvent blk) -> ChainDB m blk -> NodeToNodeVersion -> ResourceRegistry m -> BlockFetchServer (Serialised blk) (Point blk) m ()

-- | Events traced by the Block Fetch Server.
data TraceBlockFetchServerEvent blk
data BlockFetchServerException
instance GHC.Show.Show (Ouroboros.Consensus.MiniProtocol.BlockFetch.Server.TraceBlockFetchServerEvent blk)
instance GHC.Classes.Eq (Ouroboros.Consensus.MiniProtocol.BlockFetch.Server.TraceBlockFetchServerEvent blk)
instance GHC.Show.Show Ouroboros.Consensus.MiniProtocol.BlockFetch.Server.BlockFetchServerException
instance GHC.Exception.Type.Exception Ouroboros.Consensus.MiniProtocol.BlockFetch.Server.BlockFetchServerException

module Ouroboros.Consensus.Node.Tracers
data Tracers' remotePeer localPeer blk f
Tracers :: f (TraceChainSyncClientEvent blk) -> f (TraceChainSyncServerEvent blk) -> f (TraceChainSyncServerEvent blk) -> f [TraceLabelPeer remotePeer (FetchDecision [Point (Header blk)])] -> f (TraceLabelPeer remotePeer (TraceFetchClientState (Header blk))) -> f (TraceBlockFetchServerEvent blk) -> f (TraceLabelPeer remotePeer (TraceTxSubmissionInbound (GenTxId blk) (GenTx blk))) -> f (TraceLabelPeer remotePeer (TraceTxSubmissionOutbound (GenTxId blk) (GenTx blk))) -> f (TraceLocalTxSubmissionServerEvent blk) -> f (TraceEventMempool blk) -> f (TraceLabelCreds (TraceForgeEvent blk)) -> f TraceBlockchainTimeEvent -> f (TraceLabelCreds (ForgeStateInfo blk)) -> f (TraceKeepAliveClient remotePeer) -> Tracers' remotePeer localPeer blk f
[chainSyncClientTracer] :: Tracers' remotePeer localPeer blk f -> f (TraceChainSyncClientEvent blk)
[chainSyncServerHeaderTracer] :: Tracers' remotePeer localPeer blk f -> f (TraceChainSyncServerEvent blk)
[chainSyncServerBlockTracer] :: Tracers' remotePeer localPeer blk f -> f (TraceChainSyncServerEvent blk)
[blockFetchDecisionTracer] :: Tracers' remotePeer localPeer blk f -> f [TraceLabelPeer remotePeer (FetchDecision [Point (Header blk)])]
[blockFetchClientTracer] :: Tracers' remotePeer localPeer blk f -> f (TraceLabelPeer remotePeer (TraceFetchClientState (Header blk)))
[blockFetchServerTracer] :: Tracers' remotePeer localPeer blk f -> f (TraceBlockFetchServerEvent blk)
[txInboundTracer] :: Tracers' remotePeer localPeer blk f -> f (TraceLabelPeer remotePeer (TraceTxSubmissionInbound (GenTxId blk) (GenTx blk)))
[txOutboundTracer] :: Tracers' remotePeer localPeer blk f -> f (TraceLabelPeer remotePeer (TraceTxSubmissionOutbound (GenTxId blk) (GenTx blk)))
[localTxSubmissionServerTracer] :: Tracers' remotePeer localPeer blk f -> f (TraceLocalTxSubmissionServerEvent blk)
[mempoolTracer] :: Tracers' remotePeer localPeer blk f -> f (TraceEventMempool blk)
[forgeTracer] :: Tracers' remotePeer localPeer blk f -> f (TraceLabelCreds (TraceForgeEvent blk))
[blockchainTimeTracer] :: Tracers' remotePeer localPeer blk f -> f TraceBlockchainTimeEvent
[forgeStateInfoTracer] :: Tracers' remotePeer localPeer blk f -> f (TraceLabelCreds (ForgeStateInfo blk))
[keepAliveClientTracer] :: Tracers' remotePeer localPeer blk f -> f (TraceKeepAliveClient remotePeer)

-- | A record of <a>Tracer</a>s for the node.
type Tracers m remotePeer localPeer blk = Tracers' remotePeer localPeer blk (Tracer m)

-- | Use a <a>nullTracer</a> for each of the <a>Tracer</a>s in
--   <a>Tracers</a>
nullTracers :: Monad m => Tracers m remotePeer localPeer blk
showTracers :: (Show blk, Show (GenTx blk), Show (GenTxId blk), Show (ApplyTxErr blk), Show (Header blk), Show (ForgeStateInfo blk), Show (ForgeStateUpdateError blk), Show (CannotForge blk), Show remotePeer, LedgerSupportsProtocol blk) => Tracer m String -> Tracers m remotePeer localPeer blk

-- | Trace the forging of a block as a slot leader.
--   
--   The flow of trace events here can be visualized as follows:
--   
--   <pre>
--   TraceStartLeadershipCheck
--            |
--            +--- TraceSlotIsImmutable (leadership check failed)
--            |
--            +--- TraceBlockFromFuture (leadership check failed)
--            |
--    TraceBlockContext
--            |
--            +--- TraceNoLedgerState (leadership check failed)
--            |
--     TraceLedgerState
--            |
--            +--- TraceNoLedgerView (leadership check failed)
--            |
--     TraceLedgerView
--            |
--            +--- TraceForgeStateUpdateError (leadership check failed)
--            |
--            +--- TraceNodeCannotForge (leadership check failed)
--            |
--            +--- TraceNodeNotLeader
--            |
--     TraceNodeIsLeader
--            |
--      TraceForgedBlock
--            |
--            +--- TraceDidntAdoptBlock
--            |
--            +--- TraceForgedInvalidBlock
--            |
--    TraceAdoptedBlock
--   </pre>
data TraceForgeEvent blk

-- | Start of the leadership check
--   
--   We record the current slot number.
TraceStartLeadershipCheck :: SlotNo -> TraceForgeEvent blk

-- | Leadership check failed: the tip of the ImmutableDB inhabits the
--   current slot
--   
--   This might happen in two cases.
--   
--   <ol>
--   <li>the clock moved backwards, on restart we ignored everything from
--   the VolatileDB since it's all in the future, and now the tip of the
--   ImmutableDB points to a block produced in the same slot we're trying
--   to produce a block in</li>
--   <li>k = 0 and we already adopted a block from another leader of the
--   same slot.</li>
--   </ol>
--   
--   We record both the current slot number as well as the tip of the
--   ImmutableDB.
--   
--   See also
--   <a>https://github.com/input-output-hk/ouroboros-network/issues/1462</a>
TraceSlotIsImmutable :: SlotNo -> Point blk -> BlockNo -> TraceForgeEvent blk

-- | Leadership check failed: the current chain contains a block from a
--   slot <i>after</i> the current slot
--   
--   This can only happen if the system is under heavy load.
--   
--   We record both the current slot number as well as the slot number of
--   the block at the tip of the chain.
--   
--   See also
--   <a>https://github.com/input-output-hk/ouroboros-network/issues/1462</a>
TraceBlockFromFuture :: SlotNo -> SlotNo -> TraceForgeEvent blk

-- | We found out to which block we are going to connect the block we are
--   about to forge.
--   
--   We record the current slot number, the block number of the block to
--   connect to and its point.
--   
--   Note that block number of the block we will try to forge is one more
--   than the recorded block number.
TraceBlockContext :: SlotNo -> BlockNo -> Point blk -> TraceForgeEvent blk

-- | Leadership check failed: we were unable to get the ledger state for
--   the point of the block we want to connect to
--   
--   This can happen if after choosing which block to connect to the node
--   switched to a different fork. We expect this to happen only rather
--   rarely, so this certainly merits a warning; if it happens a lot, that
--   merits an investigation.
--   
--   We record both the current slot number as well as the point of the
--   block we attempt to connect the new block to (that we requested the
--   ledger state for).
TraceNoLedgerState :: SlotNo -> Point blk -> TraceForgeEvent blk

-- | We obtained a ledger state for the point of the block we want to
--   connect to
--   
--   We record both the current slot number as well as the point of the
--   block we attempt to connect the new block to (that we requested the
--   ledger state for).
TraceLedgerState :: SlotNo -> Point blk -> TraceForgeEvent blk

-- | Leadership check failed: we were unable to get the ledger view for the
--   current slot number
--   
--   This will only happen if there are many missing blocks between the tip
--   of our chain and the current slot.
--   
--   We record also the failure returned by <tt>forecastFor</tt>.
TraceNoLedgerView :: SlotNo -> OutsideForecastRange -> TraceForgeEvent blk

-- | We obtained a ledger view for the current slot number
--   
--   We record the current slot number.
TraceLedgerView :: SlotNo -> TraceForgeEvent blk

-- | Updating the forge state failed.
--   
--   For example, the KES key could not be evolved anymore.
--   
--   We record the error returned by <a>updateForgeState</a>.
TraceForgeStateUpdateError :: SlotNo -> ForgeStateUpdateError blk -> TraceForgeEvent blk

-- | We did the leadership check and concluded that we should lead and
--   forge a block, but cannot.
--   
--   This should only happen rarely and should be logged with warning
--   severity.
--   
--   Records why we cannot forge a block.
TraceNodeCannotForge :: SlotNo -> CannotForge blk -> TraceForgeEvent blk

-- | We did the leadership check and concluded we are not the leader
--   
--   We record the current slot number
TraceNodeNotLeader :: SlotNo -> TraceForgeEvent blk

-- | We did the leadership check and concluded we <i>are</i> the leader
--   
--   The node will soon forge; it is about to read its transactions from
--   the Mempool. This will be followed by TraceForgedBlock.
TraceNodeIsLeader :: SlotNo -> TraceForgeEvent blk

-- | We forged a block
--   
--   We record the current slot number, the point of the predecessor, the
--   block itself, and the total size of the mempool snapshot at the time
--   we produced the block (which may be significantly larger than the
--   block, due to maximum block size)
--   
--   This will be followed by one of three messages:
--   
--   <ul>
--   <li>TraceAdoptedBlock (normally)</li>
--   <li>TraceDidntAdoptBlock (rarely)</li>
--   <li>TraceForgedInvalidBlock (hopefully never -- this would indicate a
--   bug)</li>
--   </ul>
TraceForgedBlock :: SlotNo -> Point blk -> blk -> MempoolSize -> TraceForgeEvent blk

-- | We did not adopt the block we produced, but the block was valid. We
--   must have adopted a block that another leader of the same slot
--   produced before we got the chance of adopting our own block. This is
--   very rare, this warrants a warning.
TraceDidntAdoptBlock :: SlotNo -> blk -> TraceForgeEvent blk

-- | We forged a block that is invalid according to the ledger in the
--   ChainDB. This means there is an inconsistency between the mempool
--   validation and the ledger validation. This is a serious error!
TraceForgedInvalidBlock :: SlotNo -> blk -> InvalidBlockReason blk -> TraceForgeEvent blk

-- | We adopted the block we produced, we also trace the transactions that
--   were adopted.
TraceAdoptedBlock :: SlotNo -> blk -> [GenTx blk] -> TraceForgeEvent blk

-- | Label a forge-related trace event with the label associated with its
--   credentials.
--   
--   This is useful when a node is running with multiple sets of
--   credentials.
data TraceLabelCreds a
TraceLabelCreds :: Text -> a -> TraceLabelCreds a
instance GHC.Base.Functor Ouroboros.Consensus.Node.Tracers.TraceLabelCreds
instance GHC.Show.Show a => GHC.Show.Show (Ouroboros.Consensus.Node.Tracers.TraceLabelCreds a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Ouroboros.Consensus.Node.Tracers.TraceLabelCreds a)
instance (Ouroboros.Consensus.Ledger.SupportsProtocol.LedgerSupportsProtocol blk, GHC.Classes.Eq blk, GHC.Classes.Eq (Ouroboros.Consensus.Ledger.SupportsMempool.GenTx blk), GHC.Classes.Eq (Ouroboros.Consensus.Block.Forging.ForgeStateUpdateError blk), GHC.Classes.Eq (Ouroboros.Consensus.Block.Forging.CannotForge blk)) => GHC.Classes.Eq (Ouroboros.Consensus.Node.Tracers.TraceForgeEvent blk)
instance (Ouroboros.Consensus.Ledger.SupportsProtocol.LedgerSupportsProtocol blk, GHC.Show.Show blk, GHC.Show.Show (Ouroboros.Consensus.Ledger.SupportsMempool.GenTx blk), GHC.Show.Show (Ouroboros.Consensus.Block.Forging.ForgeStateUpdateError blk), GHC.Show.Show (Ouroboros.Consensus.Block.Forging.CannotForge blk)) => GHC.Show.Show (Ouroboros.Consensus.Node.Tracers.TraceForgeEvent blk)
instance (forall a. GHC.Base.Semigroup (f a)) => GHC.Base.Semigroup (Ouroboros.Consensus.Node.Tracers.Tracers' remotePeer localPeer blk f)

module Ouroboros.Consensus.Node.ErrorPolicy
consensusErrorPolicy :: ErrorPolicies

module Ouroboros.Consensus.Mempool.Impl
openMempool :: (IOLike m, LedgerSupportsMempool blk, HasTxId (GenTx blk), ValidateEnvelope blk) => ResourceRegistry m -> LedgerInterface m blk -> LedgerConfig blk -> MempoolCapacityBytesOverride -> Tracer m (TraceEventMempool blk) -> (GenTx blk -> TxSizeInBytes) -> m (Mempool m blk TicketNo)

-- | An override for the default <a>MempoolCapacityBytes</a> which is 2x
--   the maximum transaction capacity (see <tt>MaxTxCapacityOverride</tt>)
data MempoolCapacityBytesOverride

-- | Use 2x the maximum transaction capacity of a block. This will change
--   dynamically with the protocol parameters adopted in the current
--   ledger.
NoMempoolCapacityBytesOverride :: MempoolCapacityBytesOverride

-- | Use the following <a>MempoolCapacityBytes</a>.
MempoolCapacityBytesOverride :: !MempoolCapacityBytes -> MempoolCapacityBytesOverride

-- | Abstract interface needed to run a Mempool.
data LedgerInterface m blk
LedgerInterface :: STM m (LedgerState blk) -> LedgerInterface m blk
[getCurrentLedgerState] :: LedgerInterface m blk -> STM m (LedgerState blk)

-- | Create a <a>LedgerInterface</a> from a <a>ChainDB</a>.
chainDBLedgerInterface :: IOLike m => ChainDB m blk -> LedgerInterface m blk

-- | We allocate each transaction a (monotonically increasing) ticket
--   number as it enters the mempool.
data TicketNo

-- | Unlike <a>openMempool</a>, this function does not fork a background
--   thread that synchronises with the ledger state whenever the later
--   changes.
--   
--   Intended for testing purposes.
openMempoolWithoutSyncThread :: (IOLike m, LedgerSupportsMempool blk, HasTxId (GenTx blk), ValidateEnvelope blk) => LedgerInterface m blk -> LedgerConfig blk -> MempoolCapacityBytesOverride -> Tracer m (TraceEventMempool blk) -> (GenTx blk -> TxSizeInBytes) -> m (Mempool m blk TicketNo)
instance GHC.Show.Show Ouroboros.Consensus.Mempool.Impl.MempoolCapacityBytesOverride
instance GHC.Classes.Eq Ouroboros.Consensus.Mempool.Impl.MempoolCapacityBytesOverride
instance GHC.Generics.Generic (Ouroboros.Consensus.Mempool.Impl.InternalState blk)
instance (NoThunks.Class.NoThunks (Ouroboros.Consensus.Ledger.SupportsMempool.GenTx blk), NoThunks.Class.NoThunks (Ouroboros.Consensus.Ledger.SupportsMempool.GenTxId blk), NoThunks.Class.NoThunks (Ouroboros.Consensus.Ticked.Ticked (Ouroboros.Consensus.Ledger.Basics.LedgerState blk)), Ouroboros.Network.Block.StandardHash blk, Data.Typeable.Internal.Typeable blk) => NoThunks.Class.NoThunks (Ouroboros.Consensus.Mempool.Impl.InternalState blk)

module Ouroboros.Consensus.Mempool

module Ouroboros.Consensus.Config.SupportsNode

-- | The <a>BlockConfig</a> needs to contain some information in order to
--   support running a node.
class ConfigSupportsNode blk
getSystemStart :: ConfigSupportsNode blk => BlockConfig blk -> SystemStart
getNetworkMagic :: ConfigSupportsNode blk => BlockConfig blk -> NetworkMagic


-- | Infrastructure required to run a node
--   
--   The definitions in this module are independent from any specific
--   protocol.
module Ouroboros.Consensus.Node.Run

-- | All the serialisation related constraints needed by the ChainDB.
class (ImmutableDbSerialiseConstraints blk, LgrDbSerialiseConstraints blk, VolatileDbSerialiseConstraints blk, EncodeDiskDep (NestedCtxt Header) blk) => SerialiseDiskConstraints blk

-- | <a>EncodeDisk</a> and <a>DecodeDisk</a> constraints needed for the
--   ImmutableDB.
type ImmutableDbSerialiseConstraints blk = (EncodeDisk blk blk, DecodeDisk blk (ByteString -> blk), DecodeDiskDep (NestedCtxt Header) blk, ReconstructNestedCtxt Header blk, HasBinaryBlockInfo blk)

-- | <a>EncodeDisk</a> and <a>DecodeDisk</a> constraints needed for the
--   LgrDB.
type LgrDbSerialiseConstraints blk = (Serialise (HeaderHash blk), EncodeDisk blk (LedgerState blk), DecodeDisk blk (LedgerState blk), EncodeDisk blk (AnnTip blk), DecodeDisk blk (AnnTip blk), EncodeDisk blk (ChainDepState (BlockProtocol blk)), DecodeDisk blk (ChainDepState (BlockProtocol blk)))

-- | <a>EncodeDisk</a> and <a>DecodeDisk</a> constraints needed for the
--   VolatileDB.
type VolatileDbSerialiseConstraints blk = (EncodeDisk blk blk, DecodeDisk blk (ByteString -> blk), DecodeDiskDep (NestedCtxt Header) blk, HasNestedContent Header blk, HasBinaryBlockInfo blk)

-- | Serialisation constraints needed by the node-to-node protocols
class (ConvertRawHash blk, SerialiseNodeToNode blk blk, SerialiseNodeToNode blk (Header blk), SerialiseNodeToNode blk (Serialised blk), SerialiseNodeToNode blk (SerialisedHeader blk), SerialiseNodeToNode blk (GenTx blk), SerialiseNodeToNode blk (GenTxId blk)) => SerialiseNodeToNodeConstraints blk

-- | An upper bound on the size in bytes of the block corresponding to the
--   header. This can be an overestimate, but not an underestimate.
--   
--   The block fetch client uses this to estimate how bytes will be in
--   flight. This is also used to limit the number of bytes accepted when
--   downloading a block.
--   
--   This is part of this class as it depends on the node-to-node
--   serialisation format used for blocks.
estimateBlockSize :: SerialiseNodeToNodeConstraints blk => Header blk -> SizeInBytes

-- | Serialisation constraints needed by the node-to-client protocols
class (ConvertRawHash blk, SerialiseNodeToClient blk blk, SerialiseNodeToClient blk (Serialised blk), SerialiseNodeToClient blk (GenTx blk), SerialiseNodeToClient blk (ApplyTxErr blk), SerialiseNodeToClient blk (SomeSecond Query blk), SerialiseResult blk (Query blk)) => SerialiseNodeToClientConstraints blk
class (LedgerSupportsProtocol blk, InspectLedger blk, HasHardForkHistory blk, LedgerSupportsMempool blk, HasTxId (GenTx blk), QueryLedger blk, SupportedNetworkProtocolVersion blk, ConfigSupportsNode blk, ConvertRawHash blk, CommonProtocolParams blk, HasBinaryBlockInfo blk, SerialiseDiskConstraints blk, SerialiseNodeToNodeConstraints blk, SerialiseNodeToClientConstraints blk, NodeInitStorage blk, Show (CannotForge blk), Show (ForgeStateInfo blk), Show (ForgeStateUpdateError blk), ShowProxy blk, ShowProxy (ApplyTxErr blk), ShowProxy (GenTx blk), ShowProxy (Header blk), ShowProxy (Query blk), ShowProxy (TxId (GenTx blk))) => RunNode blk

module Ouroboros.Consensus.NodeKernel

-- | Interface against running relay node
data NodeKernel m remotePeer localPeer blk
NodeKernel :: ChainDB m blk -> Mempool m blk TicketNo -> TopLevelConfig blk -> FetchClientRegistry remotePeer (Header blk) blk m -> StrictTVar m (Map remotePeer (StrictTVar m (AnchoredFragment (Header blk)))) -> Tracers m remotePeer localPeer blk -> NodeKernel m remotePeer localPeer blk

-- | The <a>ChainDB</a> of the node
[$sel:getChainDB:NodeKernel] :: NodeKernel m remotePeer localPeer blk -> ChainDB m blk

-- | The node's mempool
[$sel:getMempool:NodeKernel] :: NodeKernel m remotePeer localPeer blk -> Mempool m blk TicketNo

-- | The node's top-level static configuration
[$sel:getTopLevelConfig:NodeKernel] :: NodeKernel m remotePeer localPeer blk -> TopLevelConfig blk

-- | The fetch client registry, used for the block fetch clients.
[$sel:getFetchClientRegistry:NodeKernel] :: NodeKernel m remotePeer localPeer blk -> FetchClientRegistry remotePeer (Header blk) blk m

-- | Read the current candidates
[$sel:getNodeCandidates:NodeKernel] :: NodeKernel m remotePeer localPeer blk -> StrictTVar m (Map remotePeer (StrictTVar m (AnchoredFragment (Header blk))))

-- | The node's tracers
[$sel:getTracers:NodeKernel] :: NodeKernel m remotePeer localPeer blk -> Tracers m remotePeer localPeer blk

-- | The maximum transaction capacity of a block is computed by taking the
--   max block size from the protocol parameters in the current ledger
--   state and subtracting the size of the header.
--   
--   It is possible to override this maximum transaction capacity with a
--   lower value. We ignore higher values than the ledger state's max block
--   size. Such blocks would be rejected by the ledger anyway.
data MaxTxCapacityOverride

-- | Don't override the maximum transaction capacity as computed from the
--   current ledger state.
NoMaxTxCapacityOverride :: MaxTxCapacityOverride

-- | Use the following maximum size in bytes for the transaction capacity
--   of a block.
MaxTxCapacityOverride :: !Word32 -> MaxTxCapacityOverride

-- | An override for the default <a>MempoolCapacityBytes</a> which is 2x
--   the maximum transaction capacity (see <tt>MaxTxCapacityOverride</tt>)
data MempoolCapacityBytesOverride

-- | Use 2x the maximum transaction capacity of a block. This will change
--   dynamically with the protocol parameters adopted in the current
--   ledger.
NoMempoolCapacityBytesOverride :: MempoolCapacityBytesOverride

-- | Use the following <a>MempoolCapacityBytes</a>.
MempoolCapacityBytesOverride :: !MempoolCapacityBytes -> MempoolCapacityBytesOverride

-- | Arguments required when initializing a node
data NodeArgs m remotePeer localPeer blk
NodeArgs :: Tracers m remotePeer localPeer blk -> ResourceRegistry m -> TopLevelConfig blk -> BlockchainTime m -> ChainDB m blk -> (StorageConfig blk -> InitChainDB m blk -> m ()) -> (Header blk -> SizeInBytes) -> [BlockForging m blk] -> MaxTxCapacityOverride -> MempoolCapacityBytesOverride -> MiniProtocolParameters -> BlockFetchConfiguration -> StdGen -> NodeArgs m remotePeer localPeer blk
[$sel:tracers:NodeArgs] :: NodeArgs m remotePeer localPeer blk -> Tracers m remotePeer localPeer blk
[$sel:registry:NodeArgs] :: NodeArgs m remotePeer localPeer blk -> ResourceRegistry m
[$sel:cfg:NodeArgs] :: NodeArgs m remotePeer localPeer blk -> TopLevelConfig blk
[$sel:btime:NodeArgs] :: NodeArgs m remotePeer localPeer blk -> BlockchainTime m
[$sel:chainDB:NodeArgs] :: NodeArgs m remotePeer localPeer blk -> ChainDB m blk
[$sel:initChainDB:NodeArgs] :: NodeArgs m remotePeer localPeer blk -> StorageConfig blk -> InitChainDB m blk -> m ()
[$sel:blockFetchSize:NodeArgs] :: NodeArgs m remotePeer localPeer blk -> Header blk -> SizeInBytes
[$sel:blockForging:NodeArgs] :: NodeArgs m remotePeer localPeer blk -> [BlockForging m blk]
[$sel:maxTxCapacityOverride:NodeArgs] :: NodeArgs m remotePeer localPeer blk -> MaxTxCapacityOverride
[$sel:mempoolCapacityOverride:NodeArgs] :: NodeArgs m remotePeer localPeer blk -> MempoolCapacityBytesOverride
[$sel:miniProtocolParameters:NodeArgs] :: NodeArgs m remotePeer localPeer blk -> MiniProtocolParameters
[$sel:blockFetchConfiguration:NodeArgs] :: NodeArgs m remotePeer localPeer blk -> BlockFetchConfiguration
[$sel:keepAliveRng:NodeArgs] :: NodeArgs m remotePeer localPeer blk -> StdGen

-- | Trace the forging of a block as a slot leader.
--   
--   The flow of trace events here can be visualized as follows:
--   
--   <pre>
--   TraceStartLeadershipCheck
--            |
--            +--- TraceSlotIsImmutable (leadership check failed)
--            |
--            +--- TraceBlockFromFuture (leadership check failed)
--            |
--    TraceBlockContext
--            |
--            +--- TraceNoLedgerState (leadership check failed)
--            |
--     TraceLedgerState
--            |
--            +--- TraceNoLedgerView (leadership check failed)
--            |
--     TraceLedgerView
--            |
--            +--- TraceForgeStateUpdateError (leadership check failed)
--            |
--            +--- TraceNodeCannotForge (leadership check failed)
--            |
--            +--- TraceNodeNotLeader
--            |
--     TraceNodeIsLeader
--            |
--      TraceForgedBlock
--            |
--            +--- TraceDidntAdoptBlock
--            |
--            +--- TraceForgedInvalidBlock
--            |
--    TraceAdoptedBlock
--   </pre>
data TraceForgeEvent blk

-- | Start of the leadership check
--   
--   We record the current slot number.
TraceStartLeadershipCheck :: SlotNo -> TraceForgeEvent blk

-- | Leadership check failed: the tip of the ImmutableDB inhabits the
--   current slot
--   
--   This might happen in two cases.
--   
--   <ol>
--   <li>the clock moved backwards, on restart we ignored everything from
--   the VolatileDB since it's all in the future, and now the tip of the
--   ImmutableDB points to a block produced in the same slot we're trying
--   to produce a block in</li>
--   <li>k = 0 and we already adopted a block from another leader of the
--   same slot.</li>
--   </ol>
--   
--   We record both the current slot number as well as the tip of the
--   ImmutableDB.
--   
--   See also
--   <a>https://github.com/input-output-hk/ouroboros-network/issues/1462</a>
TraceSlotIsImmutable :: SlotNo -> Point blk -> BlockNo -> TraceForgeEvent blk

-- | Leadership check failed: the current chain contains a block from a
--   slot <i>after</i> the current slot
--   
--   This can only happen if the system is under heavy load.
--   
--   We record both the current slot number as well as the slot number of
--   the block at the tip of the chain.
--   
--   See also
--   <a>https://github.com/input-output-hk/ouroboros-network/issues/1462</a>
TraceBlockFromFuture :: SlotNo -> SlotNo -> TraceForgeEvent blk

-- | We found out to which block we are going to connect the block we are
--   about to forge.
--   
--   We record the current slot number, the block number of the block to
--   connect to and its point.
--   
--   Note that block number of the block we will try to forge is one more
--   than the recorded block number.
TraceBlockContext :: SlotNo -> BlockNo -> Point blk -> TraceForgeEvent blk

-- | Leadership check failed: we were unable to get the ledger state for
--   the point of the block we want to connect to
--   
--   This can happen if after choosing which block to connect to the node
--   switched to a different fork. We expect this to happen only rather
--   rarely, so this certainly merits a warning; if it happens a lot, that
--   merits an investigation.
--   
--   We record both the current slot number as well as the point of the
--   block we attempt to connect the new block to (that we requested the
--   ledger state for).
TraceNoLedgerState :: SlotNo -> Point blk -> TraceForgeEvent blk

-- | We obtained a ledger state for the point of the block we want to
--   connect to
--   
--   We record both the current slot number as well as the point of the
--   block we attempt to connect the new block to (that we requested the
--   ledger state for).
TraceLedgerState :: SlotNo -> Point blk -> TraceForgeEvent blk

-- | Leadership check failed: we were unable to get the ledger view for the
--   current slot number
--   
--   This will only happen if there are many missing blocks between the tip
--   of our chain and the current slot.
--   
--   We record also the failure returned by <tt>forecastFor</tt>.
TraceNoLedgerView :: SlotNo -> OutsideForecastRange -> TraceForgeEvent blk

-- | We obtained a ledger view for the current slot number
--   
--   We record the current slot number.
TraceLedgerView :: SlotNo -> TraceForgeEvent blk

-- | Updating the forge state failed.
--   
--   For example, the KES key could not be evolved anymore.
--   
--   We record the error returned by <a>updateForgeState</a>.
TraceForgeStateUpdateError :: SlotNo -> ForgeStateUpdateError blk -> TraceForgeEvent blk

-- | We did the leadership check and concluded that we should lead and
--   forge a block, but cannot.
--   
--   This should only happen rarely and should be logged with warning
--   severity.
--   
--   Records why we cannot forge a block.
TraceNodeCannotForge :: SlotNo -> CannotForge blk -> TraceForgeEvent blk

-- | We did the leadership check and concluded we are not the leader
--   
--   We record the current slot number
TraceNodeNotLeader :: SlotNo -> TraceForgeEvent blk

-- | We did the leadership check and concluded we <i>are</i> the leader
--   
--   The node will soon forge; it is about to read its transactions from
--   the Mempool. This will be followed by TraceForgedBlock.
TraceNodeIsLeader :: SlotNo -> TraceForgeEvent blk

-- | We forged a block
--   
--   We record the current slot number, the point of the predecessor, the
--   block itself, and the total size of the mempool snapshot at the time
--   we produced the block (which may be significantly larger than the
--   block, due to maximum block size)
--   
--   This will be followed by one of three messages:
--   
--   <ul>
--   <li>TraceAdoptedBlock (normally)</li>
--   <li>TraceDidntAdoptBlock (rarely)</li>
--   <li>TraceForgedInvalidBlock (hopefully never -- this would indicate a
--   bug)</li>
--   </ul>
TraceForgedBlock :: SlotNo -> Point blk -> blk -> MempoolSize -> TraceForgeEvent blk

-- | We did not adopt the block we produced, but the block was valid. We
--   must have adopted a block that another leader of the same slot
--   produced before we got the chance of adopting our own block. This is
--   very rare, this warrants a warning.
TraceDidntAdoptBlock :: SlotNo -> blk -> TraceForgeEvent blk

-- | We forged a block that is invalid according to the ledger in the
--   ChainDB. This means there is an inconsistency between the mempool
--   validation and the ledger validation. This is a serious error!
TraceForgedInvalidBlock :: SlotNo -> blk -> InvalidBlockReason blk -> TraceForgeEvent blk

-- | We adopted the block we produced, we also trace the transactions that
--   were adopted.
TraceAdoptedBlock :: SlotNo -> blk -> [GenTx blk] -> TraceForgeEvent blk
initNodeKernel :: forall m remotePeer localPeer blk. (IOLike m, RunNode blk, NoThunks remotePeer, Ord remotePeer, Hashable remotePeer) => NodeArgs m remotePeer localPeer blk -> m (NodeKernel m remotePeer localPeer blk)
getMempoolReader :: forall m blk. (IOLike m, HasTxId (GenTx blk)) => Mempool m blk TicketNo -> TxSubmissionMempoolReader (GenTxId blk) (GenTx blk) TicketNo m
getMempoolWriter :: (IOLike m, HasTxId (GenTx blk)) => Mempool m blk TicketNo -> TxSubmissionMempoolWriter (GenTxId blk) (GenTx blk) TicketNo m


-- | Intended for qualified import
module Ouroboros.Consensus.Network.NodeToNode

-- | Protocol handlers for node-to-node (remote) communication
data Handlers m peer blk
Handlers :: (NodeToNodeVersion -> ControlMessageSTM m -> StrictTVar m (AnchoredFragment (Header blk)) -> ChainSyncClientPipelined (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult) -> (NodeToNodeVersion -> ResourceRegistry m -> ChainSyncServer (SerialisedHeader blk) (Point blk) (Tip blk) m ()) -> (NodeToNodeVersion -> ControlMessageSTM m -> BlockFetchClient (Header blk) blk m ()) -> (NodeToNodeVersion -> ResourceRegistry m -> BlockFetchServer (Serialised blk) (Point blk) m ()) -> (NodeToNodeVersion -> ControlMessageSTM m -> peer -> TxSubmissionClient (GenTxId blk) (GenTx blk) m ()) -> (NodeToNodeVersion -> peer -> TxSubmissionServerPipelined (GenTxId blk) (GenTx blk) m ()) -> (NodeToNodeVersion -> ControlMessageSTM m -> peer -> StrictTVar m (Map peer PeerGSV) -> KeepAliveInterval -> KeepAliveClient m ()) -> (NodeToNodeVersion -> peer -> KeepAliveServer m ()) -> Handlers m peer blk
[hChainSyncClient] :: Handlers m peer blk -> NodeToNodeVersion -> ControlMessageSTM m -> StrictTVar m (AnchoredFragment (Header blk)) -> ChainSyncClientPipelined (Header blk) (Point blk) (Tip blk) m ChainSyncClientResult
[hChainSyncServer] :: Handlers m peer blk -> NodeToNodeVersion -> ResourceRegistry m -> ChainSyncServer (SerialisedHeader blk) (Point blk) (Tip blk) m ()
[hBlockFetchClient] :: Handlers m peer blk -> NodeToNodeVersion -> ControlMessageSTM m -> BlockFetchClient (Header blk) blk m ()
[hBlockFetchServer] :: Handlers m peer blk -> NodeToNodeVersion -> ResourceRegistry m -> BlockFetchServer (Serialised blk) (Point blk) m ()
[hTxSubmissionClient] :: Handlers m peer blk -> NodeToNodeVersion -> ControlMessageSTM m -> peer -> TxSubmissionClient (GenTxId blk) (GenTx blk) m ()
[hTxSubmissionServer] :: Handlers m peer blk -> NodeToNodeVersion -> peer -> TxSubmissionServerPipelined (GenTxId blk) (GenTx blk) m ()
[hKeepAliveClient] :: Handlers m peer blk -> NodeToNodeVersion -> ControlMessageSTM m -> peer -> StrictTVar m (Map peer PeerGSV) -> KeepAliveInterval -> KeepAliveClient m ()
[hKeepAliveServer] :: Handlers m peer blk -> NodeToNodeVersion -> peer -> KeepAliveServer m ()
mkHandlers :: forall m blk remotePeer localPeer. (IOLike m, MonadTimer m, LedgerSupportsMempool blk, HasTxId (GenTx blk), LedgerSupportsProtocol blk, Ord remotePeer) => NodeArgs m remotePeer localPeer blk -> NodeKernel m remotePeer localPeer blk -> Handlers m remotePeer blk

-- | Node-to-node protocol codecs needed to run <a>Handlers</a>.
data Codecs blk e m bCS bSCS bBF bSBF bTX bKA
Codecs :: Codec (ChainSync (Header blk) (Point blk) (Tip blk)) e m bCS -> Codec (ChainSync (SerialisedHeader blk) (Point blk) (Tip blk)) e m bSCS -> Codec (BlockFetch blk (Point blk)) e m bBF -> Codec (BlockFetch (Serialised blk) (Point blk)) e m bSBF -> Codec (TxSubmission (GenTxId blk) (GenTx blk)) e m bTX -> Codec KeepAlive e m bKA -> Codecs blk e m bCS bSCS bBF bSBF bTX bKA
[cChainSyncCodec] :: Codecs blk e m bCS bSCS bBF bSBF bTX bKA -> Codec (ChainSync (Header blk) (Point blk) (Tip blk)) e m bCS
[cChainSyncCodecSerialised] :: Codecs blk e m bCS bSCS bBF bSBF bTX bKA -> Codec (ChainSync (SerialisedHeader blk) (Point blk) (Tip blk)) e m bSCS
[cBlockFetchCodec] :: Codecs blk e m bCS bSCS bBF bSBF bTX bKA -> Codec (BlockFetch blk (Point blk)) e m bBF
[cBlockFetchCodecSerialised] :: Codecs blk e m bCS bSCS bBF bSBF bTX bKA -> Codec (BlockFetch (Serialised blk) (Point blk)) e m bSBF
[cTxSubmissionCodec] :: Codecs blk e m bCS bSCS bBF bSBF bTX bKA -> Codec (TxSubmission (GenTxId blk) (GenTx blk)) e m bTX
[cKeepAliveCodec] :: Codecs blk e m bCS bSCS bBF bSBF bTX bKA -> Codec KeepAlive e m bKA

-- | Protocol codecs for the node-to-node protocols
defaultCodecs :: forall m blk. (IOLike m, SerialiseNodeToNodeConstraints blk) => CodecConfig blk -> BlockNodeToNodeVersion blk -> Codecs blk DeserialiseFailure m ByteString ByteString ByteString ByteString ByteString ByteString

-- | Identity codecs used in tests.
identityCodecs :: Monad m => Codecs blk CodecFailure m (AnyMessage (ChainSync (Header blk) (Point blk) (Tip blk))) (AnyMessage (ChainSync (SerialisedHeader blk) (Point blk) (Tip blk))) (AnyMessage (BlockFetch blk (Point blk))) (AnyMessage (BlockFetch (Serialised blk) (Point blk))) (AnyMessage (TxSubmission (GenTxId blk) (GenTx blk))) (AnyMessage KeepAlive)

-- | A record of <a>Tracer</a>s for the different protocols.
type Tracers m peer blk e = Tracers' peer blk e (Tracer m)
data Tracers' peer blk e f
Tracers :: f (TraceLabelPeer peer (TraceSendRecv (ChainSync (Header blk) (Point blk) (Tip blk)))) -> f (TraceLabelPeer peer (TraceSendRecv (ChainSync (SerialisedHeader blk) (Point blk) (Tip blk)))) -> f (TraceLabelPeer peer (TraceSendRecv (BlockFetch blk (Point blk)))) -> f (TraceLabelPeer peer (TraceSendRecv (BlockFetch (Serialised blk) (Point blk)))) -> f (TraceLabelPeer peer (TraceSendRecv (TxSubmission (GenTxId blk) (GenTx blk)))) -> Tracers' peer blk e f
[tChainSyncTracer] :: Tracers' peer blk e f -> f (TraceLabelPeer peer (TraceSendRecv (ChainSync (Header blk) (Point blk) (Tip blk))))
[tChainSyncSerialisedTracer] :: Tracers' peer blk e f -> f (TraceLabelPeer peer (TraceSendRecv (ChainSync (SerialisedHeader blk) (Point blk) (Tip blk))))
[tBlockFetchTracer] :: Tracers' peer blk e f -> f (TraceLabelPeer peer (TraceSendRecv (BlockFetch blk (Point blk))))
[tBlockFetchSerialisedTracer] :: Tracers' peer blk e f -> f (TraceLabelPeer peer (TraceSendRecv (BlockFetch (Serialised blk) (Point blk))))
[tTxSubmissionTracer] :: Tracers' peer blk e f -> f (TraceLabelPeer peer (TraceSendRecv (TxSubmission (GenTxId blk) (GenTx blk))))

-- | Use a <a>nullTracer</a> for each protocol.
nullTracers :: Monad m => Tracers m peer blk e
showTracers :: (Show blk, Show peer, Show (Header blk), Show (GenTx blk), Show (GenTxId blk), HasHeader blk, HasNestedContent Header blk) => Tracer m String -> Tracers m peer blk e

-- | A node-to-node application
type ClientApp m peer bytes a = NodeToNodeVersion -> ControlMessageSTM m -> peer -> Channel m bytes -> m (a, Maybe bytes)
type ServerApp m peer bytes a = NodeToNodeVersion -> peer -> Channel m bytes -> m (a, Maybe bytes)

-- | Applications for the node-to-node protocols
--   
--   See <a>MuxApplication</a>
data Apps m peer bCS bBF bTX bKA a
Apps :: ClientApp m peer bCS a -> ServerApp m peer bCS a -> ClientApp m peer bBF a -> ServerApp m peer bBF a -> ClientApp m peer bTX a -> ServerApp m peer bTX a -> ClientApp m peer bKA a -> ServerApp m peer bKA a -> Apps m peer bCS bBF bTX bKA a

-- | Start a chain sync client that communicates with the given upstream
--   node.
[aChainSyncClient] :: Apps m peer bCS bBF bTX bKA a -> ClientApp m peer bCS a

-- | Start a chain sync server.
[aChainSyncServer] :: Apps m peer bCS bBF bTX bKA a -> ServerApp m peer bCS a

-- | Start a block fetch client that communicates with the given upstream
--   node.
[aBlockFetchClient] :: Apps m peer bCS bBF bTX bKA a -> ClientApp m peer bBF a

-- | Start a block fetch server.
[aBlockFetchServer] :: Apps m peer bCS bBF bTX bKA a -> ServerApp m peer bBF a

-- | Start a transaction submission client that communicates with the given
--   upstream node.
[aTxSubmissionClient] :: Apps m peer bCS bBF bTX bKA a -> ClientApp m peer bTX a

-- | Start a transaction submission server.
[aTxSubmissionServer] :: Apps m peer bCS bBF bTX bKA a -> ServerApp m peer bTX a

-- | Start a keep-alive client.
[aKeepAliveClient] :: Apps m peer bCS bBF bTX bKA a -> ClientApp m peer bKA a

-- | Start a keep-alive server.
[aKeepAliveServer] :: Apps m peer bCS bBF bTX bKA a -> ServerApp m peer bKA a

-- | Construct the <tt>NetworkApplication</tt> for the node-to-node
--   protocols
mkApps :: forall m remotePeer localPeer blk e bCS bBF bTX bKA. (IOLike m, MonadTimer m, Ord remotePeer, Exception e, LedgerSupportsProtocol blk, ShowProxy blk, ShowProxy (Header blk), ShowProxy (TxId (GenTx blk)), ShowProxy (GenTx blk)) => NodeKernel m remotePeer localPeer blk -> Tracers m remotePeer blk e -> Codecs blk e m bCS bCS bBF bBF bTX bKA -> m ChainSyncTimeout -> Handlers m remotePeer blk -> Apps m remotePeer bCS bBF bTX bKA ()

-- | A projection from <tt>NetworkApplication</tt> to a client-side
--   <a>OuroborosApplication</a> for the node-to-node protocols.
--   
--   Implementation note: network currently doesn't enable protocols
--   conditional on the protocol version, but it eventually may; this is
--   why <tt>_version</tt> is currently unused.
initiator :: MiniProtocolParameters -> NodeToNodeVersion -> Apps m (ConnectionId peer) b b b b a -> OuroborosApplication 'InitiatorMode peer b m a Void

-- | A projection from <tt>NetworkApplication</tt> to a server-side
--   <a>OuroborosApplication</a> for the node-to-node protocols.
--   
--   See <tt>initiatorNetworkApplication</tt> for rationale for the
--   <tt>_version</tt> arg.
responder :: MiniProtocolParameters -> NodeToNodeVersion -> Apps m (ConnectionId peer) b b b b a -> OuroborosApplication 'ResponderMode peer b m Void a
data ChainSyncTimeout
ChainSyncTimeout :: Maybe DiffTime -> Maybe DiffTime -> ChainSyncTimeout
[canAwaitTimeout] :: ChainSyncTimeout -> Maybe DiffTime
[mustReplyTimeout] :: ChainSyncTimeout -> Maybe DiffTime
instance (forall a. GHC.Base.Semigroup (f a)) => GHC.Base.Semigroup (Ouroboros.Consensus.Network.NodeToNode.Tracers' peer blk e f)


-- | Intended for qualified import
module Ouroboros.Consensus.Network.NodeToClient

-- | Protocol handlers for node-to-client (local) communication
data Handlers m peer blk
Handlers :: (ResourceRegistry m -> ChainSyncServer (Serialised blk) (Point blk) (Tip blk) m ()) -> LocalTxSubmissionServer (GenTx blk) (ApplyTxErr blk) m () -> LocalStateQueryServer blk (Point blk) (Query blk) m () -> Handlers m peer blk
[hChainSyncServer] :: Handlers m peer blk -> ResourceRegistry m -> ChainSyncServer (Serialised blk) (Point blk) (Tip blk) m ()
[hTxSubmissionServer] :: Handlers m peer blk -> LocalTxSubmissionServer (GenTx blk) (ApplyTxErr blk) m ()
[hStateQueryServer] :: Handlers m peer blk -> LocalStateQueryServer blk (Point blk) (Query blk) m ()
mkHandlers :: forall m blk remotePeer localPeer. (IOLike m, LedgerSupportsMempool blk, QueryLedger blk) => NodeArgs m remotePeer localPeer blk -> NodeKernel m remotePeer localPeer blk -> Handlers m localPeer blk

-- | Node-to-client protocol codecs needed to run <a>Handlers</a>.
data Codecs' blk serialisedBlk e m bCS bTX bSQ
Codecs :: Codec (ChainSync serialisedBlk (Point blk) (Tip blk)) e m bCS -> Codec (LocalTxSubmission (GenTx blk) (ApplyTxErr blk)) e m bTX -> Codec (LocalStateQuery blk (Point blk) (Query blk)) e m bSQ -> Codecs' blk serialisedBlk e m bCS bTX bSQ
[cChainSyncCodec] :: Codecs' blk serialisedBlk e m bCS bTX bSQ -> Codec (ChainSync serialisedBlk (Point blk) (Tip blk)) e m bCS
[cTxSubmissionCodec] :: Codecs' blk serialisedBlk e m bCS bTX bSQ -> Codec (LocalTxSubmission (GenTx blk) (ApplyTxErr blk)) e m bTX
[cStateQueryCodec] :: Codecs' blk serialisedBlk e m bCS bTX bSQ -> Codec (LocalStateQuery blk (Point blk) (Query blk)) e m bSQ
type Codecs blk e m bCS bTX bSQ = Codecs' blk (Serialised blk) e m bCS bTX bSQ
type DefaultCodecs blk m = Codecs' blk (Serialised blk) DeserialiseFailure m ByteString ByteString ByteString
type ClientCodecs blk m = Codecs' blk blk DeserialiseFailure m ByteString ByteString ByteString

-- | Protocol codecs for the node-to-client protocols
--   
--   We pass the <a>BlockConfig</a> here, even though it is currently
--   unused. If at any point we want to introduce local protocols that for
--   example send Byron blocks or headers across, we will need to have the
--   epoch size, which comes from the Byron config. Unlike the full
--   <tt>TopLevelConfig</tt>, it should not be difficult for a wallet to
--   construct the <a>BlockConfig</a>.
--   
--   NOTE: Somewhat confusingly, <tt>pcChainSyncCodec</tt> currently
--   <i>does</i> send Byron blocks across, but it does not deserialize them
--   (the user of the codec is itself responsible for doing that), which is
--   why it currently does not need the config.
--   
--   Implementation mode: currently none of the consensus encoders/decoders
--   do anything different based on the version, so <tt>_version</tt> is
--   unused; it's just that not all codecs are used, depending on the
--   version number.
defaultCodecs :: forall m blk. (MonadST m, SerialiseNodeToClientConstraints blk, ShowQuery (Query blk)) => CodecConfig blk -> BlockNodeToClientVersion blk -> DefaultCodecs blk m

-- | Protocol codecs for the node-to-client protocols which serialise <i>
--   deserialise blocks in </i>chain-sync/ protocol.
clientCodecs :: forall m blk. (MonadST m, SerialiseNodeToClientConstraints blk, ShowQuery (Query blk)) => CodecConfig blk -> BlockNodeToClientVersion blk -> ClientCodecs blk m

-- | Identity codecs used in tests.
identityCodecs :: (Monad m, QueryLedger blk) => Codecs blk CodecFailure m (AnyMessage (ChainSync (Serialised blk) (Point blk) (Tip blk))) (AnyMessage (LocalTxSubmission (GenTx blk) (ApplyTxErr blk))) (AnyMessage (LocalStateQuery blk (Point blk) (Query blk)))

-- | A record of <a>Tracer</a>s for the different protocols.
type Tracers m peer blk e = Tracers' peer blk e (Tracer m)
data Tracers' peer blk e f
Tracers :: f (TraceLabelPeer peer (TraceSendRecv (ChainSync (Serialised blk) (Point blk) (Tip blk)))) -> f (TraceLabelPeer peer (TraceSendRecv (LocalTxSubmission (GenTx blk) (ApplyTxErr blk)))) -> f (TraceLabelPeer peer (TraceSendRecv (LocalStateQuery blk (Point blk) (Query blk)))) -> Tracers' peer blk e f
[tChainSyncTracer] :: Tracers' peer blk e f -> f (TraceLabelPeer peer (TraceSendRecv (ChainSync (Serialised blk) (Point blk) (Tip blk))))
[tTxSubmissionTracer] :: Tracers' peer blk e f -> f (TraceLabelPeer peer (TraceSendRecv (LocalTxSubmission (GenTx blk) (ApplyTxErr blk))))
[tStateQueryTracer] :: Tracers' peer blk e f -> f (TraceLabelPeer peer (TraceSendRecv (LocalStateQuery blk (Point blk) (Query blk))))

-- | Use a <a>nullTracer</a> for each protocol.
nullTracers :: Monad m => Tracers m peer blk e
showTracers :: (Show peer, Show (GenTx blk), Show (ApplyTxErr blk), ShowQuery (Query blk), HasHeader blk) => Tracer m String -> Tracers m peer blk e

-- | A node-to-client application
type App m peer bytes a = peer -> Channel m bytes -> m (a, Maybe bytes)

-- | Applications for the node-to-client (i.e., local) protocols
--   
--   See <a>MuxApplication</a>
data Apps m peer bCS bTX bSQ a
Apps :: App m peer bCS a -> App m peer bTX a -> App m peer bSQ a -> Apps m peer bCS bTX bSQ a

-- | Start a local chain sync server.
[aChainSyncServer] :: Apps m peer bCS bTX bSQ a -> App m peer bCS a

-- | Start a local transaction submission server.
[aTxSubmissionServer] :: Apps m peer bCS bTX bSQ a -> App m peer bTX a

-- | Start a local state query server.
[aStateQueryServer] :: Apps m peer bCS bTX bSQ a -> App m peer bSQ a

-- | Construct the <tt>NetworkApplication</tt> for the node-to-client
--   protocols
mkApps :: forall m peer blk e bCS bTX bSQ. (IOLike m, Exception e, ShowProxy blk, ShowProxy (ApplyTxErr blk), ShowProxy (Query blk), ShowProxy (GenTx blk), ShowQuery (Query blk)) => Tracers m peer blk e -> Codecs blk e m bCS bTX bSQ -> Handlers m peer blk -> Apps m peer bCS bTX bSQ ()

-- | A projection from <tt>NetworkApplication</tt> to a server-side
--   <a>OuroborosApplication</a> for the node-to-client protocols.
responder :: NodeToClientVersion -> Apps m (ConnectionId peer) b b b a -> OuroborosApplication 'ResponderMode peer b m Void a
instance (forall a. GHC.Base.Semigroup (f a)) => GHC.Base.Semigroup (Ouroboros.Consensus.Network.NodeToClient.Tracers' peer blk e f)


-- | Run the whole Node
--   
--   Intended for qualified import.
module Ouroboros.Consensus.Node
data DiffusionTracers
DiffusionTracers :: Tracer IO (WithIPList (SubscriptionTrace SockAddr)) -> Tracer IO (WithDomainName (SubscriptionTrace SockAddr)) -> Tracer IO (WithDomainName DnsTrace) -> Tracer IO (WithMuxBearer (ConnectionId SockAddr) MuxTrace) -> Tracer IO (WithMuxBearer (ConnectionId LocalAddress) MuxTrace) -> Tracer IO HandshakeTr -> Tracer IO HandshakeTr -> Tracer IO (WithAddr SockAddr ErrorPolicyTrace) -> Tracer IO (WithAddr LocalAddress ErrorPolicyTrace) -> Tracer IO AcceptConnectionsPolicyTrace -> DiffusionTracers
[dtIpSubscriptionTracer] :: DiffusionTracers -> Tracer IO (WithIPList (SubscriptionTrace SockAddr))
[dtDnsSubscriptionTracer] :: DiffusionTracers -> Tracer IO (WithDomainName (SubscriptionTrace SockAddr))
[dtDnsResolverTracer] :: DiffusionTracers -> Tracer IO (WithDomainName DnsTrace)
[dtMuxTracer] :: DiffusionTracers -> Tracer IO (WithMuxBearer (ConnectionId SockAddr) MuxTrace)
[dtMuxLocalTracer] :: DiffusionTracers -> Tracer IO (WithMuxBearer (ConnectionId LocalAddress) MuxTrace)
[dtHandshakeTracer] :: DiffusionTracers -> Tracer IO HandshakeTr
[dtHandshakeLocalTracer] :: DiffusionTracers -> Tracer IO HandshakeTr
[dtErrorPolicyTracer] :: DiffusionTracers -> Tracer IO (WithAddr SockAddr ErrorPolicyTrace)
[dtLocalErrorPolicyTracer] :: DiffusionTracers -> Tracer IO (WithAddr LocalAddress ErrorPolicyTrace)
[dtAcceptPolicyTracer] :: DiffusionTracers -> Tracer IO AcceptConnectionsPolicyTrace
data DiffusionArguments
DiffusionArguments :: Maybe (Either Socket AddrInfo) -> Maybe (Either Socket AddrInfo) -> Either Socket FilePath -> IPSubscriptionTarget -> [DnsSubscriptionTarget] -> AcceptedConnectionsLimit -> DiffusionMode -> DiffusionArguments
[daIPv4Address] :: DiffusionArguments -> Maybe (Either Socket AddrInfo)
[daIPv6Address] :: DiffusionArguments -> Maybe (Either Socket AddrInfo)
[daLocalAddress] :: DiffusionArguments -> Either Socket FilePath
[daIpProducers] :: DiffusionArguments -> IPSubscriptionTarget
[daDnsProducers] :: DiffusionArguments -> [DnsSubscriptionTarget]
[daAcceptedConnectionsLimit] :: DiffusionArguments -> AcceptedConnectionsLimit
[daDiffusionMode] :: DiffusionArguments -> DiffusionMode

-- | Start a node.
--   
--   This opens the <a>ChainDB</a>, sets up the <a>NodeKernel</a> and
--   initialises the network layer.
--   
--   This function runs forever unless an exception is thrown.
run :: forall blk. RunNode blk => RunNodeArgs blk -> IO ()

-- | Arguments required by <tt>runNode</tt>
data RunNodeArgs blk
RunNodeArgs :: Tracers IO RemoteConnectionId LocalConnectionId blk -> Tracers IO RemoteConnectionId blk DeserialiseFailure -> Tracers IO LocalConnectionId blk DeserialiseFailure -> Tracer IO (TraceEvent blk) -> DiffusionTracers -> DiffusionArguments -> NetworkMagic -> FilePath -> ProtocolInfo IO blk -> (ChainDbArgs Identity IO blk -> ChainDbArgs Identity IO blk) -> (NodeArgs IO RemoteConnectionId LocalConnectionId blk -> NodeArgs IO RemoteConnectionId LocalConnectionId blk) -> Map NodeToNodeVersion (BlockNodeToNodeVersion blk) -> Map NodeToClientVersion (BlockNodeToClientVersion blk) -> (ResourceRegistry IO -> NodeKernel IO RemoteConnectionId LocalConnectionId blk -> IO ()) -> ClockSkew -> RunNodeArgs blk

-- | Consensus tracers
[rnTraceConsensus] :: RunNodeArgs blk -> Tracers IO RemoteConnectionId LocalConnectionId blk

-- | Protocol tracers for node-to-node communication
[rnTraceNTN] :: RunNodeArgs blk -> Tracers IO RemoteConnectionId blk DeserialiseFailure

-- | Protocol tracers for node-to-client communication
[rnTraceNTC] :: RunNodeArgs blk -> Tracers IO LocalConnectionId blk DeserialiseFailure

-- | ChainDB tracer
[rnTraceDB] :: RunNodeArgs blk -> Tracer IO (TraceEvent blk)

-- | Diffusion tracers
[rnTraceDiffusion] :: RunNodeArgs blk -> DiffusionTracers

-- | Diffusion arguments
[rnDiffusionArguments] :: RunNodeArgs blk -> DiffusionArguments

-- | Network magic
[rnNetworkMagic] :: RunNodeArgs blk -> NetworkMagic

-- | Database path
[rnDatabasePath] :: RunNodeArgs blk -> FilePath

-- | Protocol info
[rnProtocolInfo] :: RunNodeArgs blk -> ProtocolInfo IO blk

-- | Customise the <a>ChainDbArgs</a>
[rnCustomiseChainDbArgs] :: RunNodeArgs blk -> ChainDbArgs Identity IO blk -> ChainDbArgs Identity IO blk

-- | Customise the <a>NodeArgs</a>
[rnCustomiseNodeArgs] :: RunNodeArgs blk -> NodeArgs IO RemoteConnectionId LocalConnectionId blk -> NodeArgs IO RemoteConnectionId LocalConnectionId blk

-- | node-to-node protocol versions to run.
[rnNodeToNodeVersions] :: RunNodeArgs blk -> Map NodeToNodeVersion (BlockNodeToNodeVersion blk)

-- | node-to-client protocol versions to run.
[rnNodeToClientVersions] :: RunNodeArgs blk -> Map NodeToClientVersion (BlockNodeToClientVersion blk)

-- | Hook called after the initialisation of the <a>NodeKernel</a>
--   
--   Called on the <a>NodeKernel</a> after creating it, but before the
--   network layer is initialised.
[rnNodeKernelHook] :: RunNodeArgs blk -> ResourceRegistry IO -> NodeKernel IO RemoteConnectionId LocalConnectionId blk -> IO ()

-- | Maximum clock skew.
--   
--   Use <tt>defaultClockSkew</tt> when unsure.
[rnMaxClockSkew] :: RunNodeArgs blk -> ClockSkew
class (LedgerSupportsProtocol blk, InspectLedger blk, HasHardForkHistory blk, LedgerSupportsMempool blk, HasTxId (GenTx blk), QueryLedger blk, SupportedNetworkProtocolVersion blk, ConfigSupportsNode blk, ConvertRawHash blk, CommonProtocolParams blk, HasBinaryBlockInfo blk, SerialiseDiskConstraints blk, SerialiseNodeToNodeConstraints blk, SerialiseNodeToClientConstraints blk, NodeInitStorage blk, Show (CannotForge blk), Show (ForgeStateInfo blk), Show (ForgeStateUpdateError blk), ShowProxy blk, ShowProxy (ApplyTxErr blk), ShowProxy (GenTx blk), ShowProxy (Header blk), ShowProxy (Query blk), ShowProxy (TxId (GenTx blk))) => RunNode blk

-- | A record of <a>Tracer</a>s for the node.
type Tracers m remotePeer localPeer blk = Tracers' remotePeer localPeer blk (Tracer m)
data Tracers' remotePeer localPeer blk f
Tracers :: f (TraceChainSyncClientEvent blk) -> f (TraceChainSyncServerEvent blk) -> f (TraceChainSyncServerEvent blk) -> f [TraceLabelPeer remotePeer (FetchDecision [Point (Header blk)])] -> f (TraceLabelPeer remotePeer (TraceFetchClientState (Header blk))) -> f (TraceBlockFetchServerEvent blk) -> f (TraceLabelPeer remotePeer (TraceTxSubmissionInbound (GenTxId blk) (GenTx blk))) -> f (TraceLabelPeer remotePeer (TraceTxSubmissionOutbound (GenTxId blk) (GenTx blk))) -> f (TraceLocalTxSubmissionServerEvent blk) -> f (TraceEventMempool blk) -> f (TraceLabelCreds (TraceForgeEvent blk)) -> f TraceBlockchainTimeEvent -> f (TraceLabelCreds (ForgeStateInfo blk)) -> f (TraceKeepAliveClient remotePeer) -> Tracers' remotePeer localPeer blk f
[chainSyncClientTracer] :: Tracers' remotePeer localPeer blk f -> f (TraceChainSyncClientEvent blk)
[chainSyncServerHeaderTracer] :: Tracers' remotePeer localPeer blk f -> f (TraceChainSyncServerEvent blk)
[chainSyncServerBlockTracer] :: Tracers' remotePeer localPeer blk f -> f (TraceChainSyncServerEvent blk)
[blockFetchDecisionTracer] :: Tracers' remotePeer localPeer blk f -> f [TraceLabelPeer remotePeer (FetchDecision [Point (Header blk)])]
[blockFetchClientTracer] :: Tracers' remotePeer localPeer blk f -> f (TraceLabelPeer remotePeer (TraceFetchClientState (Header blk)))
[blockFetchServerTracer] :: Tracers' remotePeer localPeer blk f -> f (TraceBlockFetchServerEvent blk)
[txInboundTracer] :: Tracers' remotePeer localPeer blk f -> f (TraceLabelPeer remotePeer (TraceTxSubmissionInbound (GenTxId blk) (GenTx blk)))
[txOutboundTracer] :: Tracers' remotePeer localPeer blk f -> f (TraceLabelPeer remotePeer (TraceTxSubmissionOutbound (GenTxId blk) (GenTx blk)))
[localTxSubmissionServerTracer] :: Tracers' remotePeer localPeer blk f -> f (TraceLocalTxSubmissionServerEvent blk)
[mempoolTracer] :: Tracers' remotePeer localPeer blk f -> f (TraceEventMempool blk)
[forgeTracer] :: Tracers' remotePeer localPeer blk f -> f (TraceLabelCreds (TraceForgeEvent blk))
[blockchainTimeTracer] :: Tracers' remotePeer localPeer blk f -> f TraceBlockchainTimeEvent
[forgeStateInfoTracer] :: Tracers' remotePeer localPeer blk f -> f (TraceLabelCreds (ForgeStateInfo blk))
[keepAliveClientTracer] :: Tracers' remotePeer localPeer blk f -> f (TraceKeepAliveClient remotePeer)

-- | Trace type for the various events of the ChainDB.
data TraceEvent blk
TraceAddBlockEvent :: TraceAddBlockEvent blk -> TraceEvent blk
TraceReaderEvent :: TraceReaderEvent blk -> TraceEvent blk
TraceCopyToImmutableDBEvent :: TraceCopyToImmutableDBEvent blk -> TraceEvent blk
TraceGCEvent :: TraceGCEvent blk -> TraceEvent blk
TraceInitChainSelEvent :: TraceInitChainSelEvent blk -> TraceEvent blk
TraceOpenEvent :: TraceOpenEvent blk -> TraceEvent blk
TraceIteratorEvent :: TraceIteratorEvent blk -> TraceEvent blk
TraceLedgerEvent :: TraceEvent blk -> TraceEvent blk
TraceLedgerReplayEvent :: TraceLedgerReplayEvent blk -> TraceEvent blk
TraceImmutableDBEvent :: TraceEvent blk -> TraceEvent blk
TraceVolatileDBEvent :: TraceEvent blk -> TraceEvent blk

-- | Data required to run the specified protocol.
data ProtocolInfo m b
ProtocolInfo :: TopLevelConfig b -> ExtLedgerState b -> [m (BlockForging m b)] -> ProtocolInfo m b
[pInfoConfig] :: ProtocolInfo m b -> TopLevelConfig b

-- | At genesis
[pInfoInitLedger] :: ProtocolInfo m b -> ExtLedgerState b
[pInfoBlockForging] :: ProtocolInfo m b -> [m (BlockForging m b)]
data ChainDbArgs f m blk
ChainDbArgs :: SomeHasFS m -> SomeHasFS m -> SomeHasFS m -> ValidationPolicy -> BlockValidationPolicy -> BlocksPerFile -> HKD f LedgerDbParams -> HKD f DiskPolicy -> HKD f (TopLevelConfig blk) -> HKD f ChunkInfo -> HKD f (blk -> Bool) -> HKD f (m (ExtLedgerState blk)) -> HKD f (CheckInFuture m blk) -> CacheConfig -> Tracer m (TraceEvent blk) -> Tracer m (LedgerDB' blk) -> HKD f (ResourceRegistry m) -> DiffTime -> DiffTime -> Word -> ChainDbArgs f m blk
[cdbHasFSImmutableDB] :: ChainDbArgs f m blk -> SomeHasFS m
[cdbHasFSVolatileDB] :: ChainDbArgs f m blk -> SomeHasFS m
[cdbHasFSLgrDB] :: ChainDbArgs f m blk -> SomeHasFS m
[cdbImmutableDbValidation] :: ChainDbArgs f m blk -> ValidationPolicy
[cdbVolatileDbValidation] :: ChainDbArgs f m blk -> BlockValidationPolicy
[cdbMaxBlocksPerFile] :: ChainDbArgs f m blk -> BlocksPerFile
[cdbParamsLgrDB] :: ChainDbArgs f m blk -> HKD f LedgerDbParams
[cdbDiskPolicy] :: ChainDbArgs f m blk -> HKD f DiskPolicy
[cdbTopLevelConfig] :: ChainDbArgs f m blk -> HKD f (TopLevelConfig blk)
[cdbChunkInfo] :: ChainDbArgs f m blk -> HKD f ChunkInfo
[cdbCheckIntegrity] :: ChainDbArgs f m blk -> HKD f (blk -> Bool)
[cdbGenesis] :: ChainDbArgs f m blk -> HKD f (m (ExtLedgerState blk))
[cdbCheckInFuture] :: ChainDbArgs f m blk -> HKD f (CheckInFuture m blk)
[cdbImmutableDbCacheConfig] :: ChainDbArgs f m blk -> CacheConfig
[cdbTracer] :: ChainDbArgs f m blk -> Tracer m (TraceEvent blk)
[cdbTraceLedger] :: ChainDbArgs f m blk -> Tracer m (LedgerDB' blk)
[cdbRegistry] :: ChainDbArgs f m blk -> HKD f (ResourceRegistry m)
[cdbGcDelay] :: ChainDbArgs f m blk -> DiffTime
[cdbGcInterval] :: ChainDbArgs f m blk -> DiffTime

-- | Size of the queue used to store asynchronously added blocks. This is
--   the maximum number of blocks that could be kept in memory at the same
--   time when the background thread processing the blocks can't keep up.
[cdbBlocksToAddSize] :: ChainDbArgs f m blk -> Word

-- | Arguments required when initializing a node
data NodeArgs m remotePeer localPeer blk
NodeArgs :: Tracers m remotePeer localPeer blk -> ResourceRegistry m -> TopLevelConfig blk -> BlockchainTime m -> ChainDB m blk -> (StorageConfig blk -> InitChainDB m blk -> m ()) -> (Header blk -> SizeInBytes) -> [BlockForging m blk] -> MaxTxCapacityOverride -> MempoolCapacityBytesOverride -> MiniProtocolParameters -> BlockFetchConfiguration -> StdGen -> NodeArgs m remotePeer localPeer blk
[$sel:tracers:NodeArgs] :: NodeArgs m remotePeer localPeer blk -> Tracers m remotePeer localPeer blk
[$sel:registry:NodeArgs] :: NodeArgs m remotePeer localPeer blk -> ResourceRegistry m
[$sel:cfg:NodeArgs] :: NodeArgs m remotePeer localPeer blk -> TopLevelConfig blk
[$sel:btime:NodeArgs] :: NodeArgs m remotePeer localPeer blk -> BlockchainTime m
[$sel:chainDB:NodeArgs] :: NodeArgs m remotePeer localPeer blk -> ChainDB m blk
[$sel:initChainDB:NodeArgs] :: NodeArgs m remotePeer localPeer blk -> StorageConfig blk -> InitChainDB m blk -> m ()
[$sel:blockFetchSize:NodeArgs] :: NodeArgs m remotePeer localPeer blk -> Header blk -> SizeInBytes
[$sel:blockForging:NodeArgs] :: NodeArgs m remotePeer localPeer blk -> [BlockForging m blk]
[$sel:maxTxCapacityOverride:NodeArgs] :: NodeArgs m remotePeer localPeer blk -> MaxTxCapacityOverride
[$sel:mempoolCapacityOverride:NodeArgs] :: NodeArgs m remotePeer localPeer blk -> MempoolCapacityBytesOverride
[$sel:miniProtocolParameters:NodeArgs] :: NodeArgs m remotePeer localPeer blk -> MiniProtocolParameters
[$sel:blockFetchConfiguration:NodeArgs] :: NodeArgs m remotePeer localPeer blk -> BlockFetchConfiguration
[$sel:keepAliveRng:NodeArgs] :: NodeArgs m remotePeer localPeer blk -> StdGen

-- | Interface against running relay node
data NodeKernel m remotePeer localPeer blk
NodeKernel :: ChainDB m blk -> Mempool m blk TicketNo -> TopLevelConfig blk -> FetchClientRegistry remotePeer (Header blk) blk m -> StrictTVar m (Map remotePeer (StrictTVar m (AnchoredFragment (Header blk)))) -> Tracers m remotePeer localPeer blk -> NodeKernel m remotePeer localPeer blk

-- | The <a>ChainDB</a> of the node
[$sel:getChainDB:NodeKernel] :: NodeKernel m remotePeer localPeer blk -> ChainDB m blk

-- | The node's mempool
[$sel:getMempool:NodeKernel] :: NodeKernel m remotePeer localPeer blk -> Mempool m blk TicketNo

-- | The node's top-level static configuration
[$sel:getTopLevelConfig:NodeKernel] :: NodeKernel m remotePeer localPeer blk -> TopLevelConfig blk

-- | The fetch client registry, used for the block fetch clients.
[$sel:getFetchClientRegistry:NodeKernel] :: NodeKernel m remotePeer localPeer blk -> FetchClientRegistry remotePeer (Header blk) blk m

-- | Read the current candidates
[$sel:getNodeCandidates:NodeKernel] :: NodeKernel m remotePeer localPeer blk -> StrictTVar m (Map remotePeer (StrictTVar m (AnchoredFragment (Header blk))))

-- | The node's tracers
[$sel:getTracers:NodeKernel] :: NodeKernel m remotePeer localPeer blk -> Tracers m remotePeer localPeer blk

-- | The maximum transaction capacity of a block is computed by taking the
--   max block size from the protocol parameters in the current ledger
--   state and subtracting the size of the header.
--   
--   It is possible to override this maximum transaction capacity with a
--   lower value. We ignore higher values than the ledger state's max block
--   size. Such blocks would be rejected by the ledger anyway.
data MaxTxCapacityOverride

-- | Don't override the maximum transaction capacity as computed from the
--   current ledger state.
NoMaxTxCapacityOverride :: MaxTxCapacityOverride

-- | Use the following maximum size in bytes for the transaction capacity
--   of a block.
MaxTxCapacityOverride :: !Word32 -> MaxTxCapacityOverride

-- | An override for the default <a>MempoolCapacityBytes</a> which is 2x
--   the maximum transaction capacity (see <tt>MaxTxCapacityOverride</tt>)
data MempoolCapacityBytesOverride

-- | Use 2x the maximum transaction capacity of a block. This will change
--   dynamically with the protocol parameters adopted in the current
--   ledger.
NoMempoolCapacityBytesOverride :: MempoolCapacityBytesOverride

-- | Use the following <a>MempoolCapacityBytes</a>.
MempoolCapacityBytesOverride :: !MempoolCapacityBytes -> MempoolCapacityBytesOverride
data IPSubscriptionTarget
IPSubscriptionTarget :: ![SockAddr] -> !Int -> IPSubscriptionTarget

-- | List of destinations to possibly connect to
[ispIps] :: IPSubscriptionTarget -> ![SockAddr]

-- | Number of parallel connections to keep actice.
[ispValency] :: IPSubscriptionTarget -> !Int
data DnsSubscriptionTarget
DnsSubscriptionTarget :: !Domain -> !PortNumber -> !Int -> DnsSubscriptionTarget
[dstDomain] :: DnsSubscriptionTarget -> !Domain
[dstPort] :: DnsSubscriptionTarget -> !PortNumber
[dstValency] :: DnsSubscriptionTarget -> !Int

-- | Connection is identified by local and remote address.
--   
--   TODO: the type variable which this data type fills in is called
--   <tt>peerid</tt>. We should renamed to <tt>connectionId</tt>.
data ConnectionId addr
ConnectionId :: !addr -> !addr -> ConnectionId addr
[localAddress] :: ConnectionId addr -> !addr
[remoteAddress] :: ConnectionId addr -> !addr
type RemoteConnectionId = ConnectionId SockAddr
openChainDB :: forall blk. RunNode blk => Tracer IO (TraceEvent blk) -> ResourceRegistry IO -> CheckInFuture IO blk -> FilePath -> TopLevelConfig blk -> ExtLedgerState blk -> (ChainDbArgs Identity IO blk -> ChainDbArgs Identity IO blk) -> IO (ChainDB IO blk)
mkChainDbArgs :: forall blk. RunNode blk => Tracer IO (TraceEvent blk) -> ResourceRegistry IO -> CheckInFuture IO blk -> FilePath -> TopLevelConfig blk -> ExtLedgerState blk -> ChunkInfo -> ChainDbArgs Identity IO blk
mkNodeArgs :: forall blk. RunNode blk => ResourceRegistry IO -> TopLevelConfig blk -> [IO (BlockForging IO blk)] -> Tracers IO RemoteConnectionId LocalConnectionId blk -> BlockchainTime IO -> ChainDB IO blk -> IO (NodeArgs IO RemoteConnectionId LocalConnectionId blk)

-- | We allow the user running the node to customise the <a>NodeArgs</a>
--   through <a>rnCustomiseNodeArgs</a>, but there are some limits to some
--   values. This function makes sure we don't exceed those limits and that
--   the values are consistent.
nodeArgsEnforceInvariants :: NodeArgs m RemoteConnectionId LocalConnectionId blk -> NodeArgs m RemoteConnectionId LocalConnectionId blk

module Ouroboros.Consensus.Ledger.Dual

-- | Bridge the two ledgers
class (HasHeader m, GetHeader m, HasHeader (Header m), LedgerSupportsProtocol m, HasHardForkHistory m, LedgerSupportsMempool m, CommonProtocolParams m, HasTxId (GenTx m), Show (ApplyTxErr m), Typeable a, UpdateLedger a, LedgerSupportsMempool a, Show (ApplyTxErr a), NoThunks (LedgerConfig a), NoThunks (CodecConfig a), NoThunks (StorageConfig a), Show (BridgeLedger m a), Eq (BridgeLedger m a), Serialise (BridgeLedger m a), Serialise (BridgeBlock m a), Serialise (BridgeTx m a), Show (BridgeTx m a)) => Bridge m a where {
    
    -- | Additional information relating both ledgers
    type family BridgeLedger m a :: Type;
    
    -- | Information required to update the bridge when applying a block
    type family BridgeBlock m a :: Type;
    
    -- | Information required to update the bridge when applying a transaction
    type family BridgeTx m a :: Type;
}
updateBridgeWithBlock :: Bridge m a => DualBlock m a -> BridgeLedger m a -> BridgeLedger m a
updateBridgeWithTx :: Bridge m a => GenTx (DualBlock m a) -> BridgeLedger m a -> BridgeLedger m a

-- | Dual block
--   
--   The dual block is used to instantiate the consensus with a dual
--   ledger, consisting of two ledger states associated with two types of
--   blocks. The (consensus) chain state will still be updated based on one
--   block type only, which is therefore designed as the <i>main</i> block,
--   while the other block is designated as the <i>auxiliary</i> block.
--   
--   The auxiliary block is optional; this can be used if some " main "
--   blocks should have no effect on the auxiliary ledger state at all. The
--   motivating example is EBBs: if the main blocks are real Byron blocks,
--   and the auxiliary blocks are Byron spec blocks, then regular Byron
--   blocks correspond to Byron spec blocks, but EBBs don't correspond to a
--   spec block at all and should leave the Byron spec ledger state
--   unchanged.
--   
--   NOTE: The dual ledger is used for testing purposes only; we do not do
--   any meaningful <a>NoThunks</a> checks here.
data DualBlock m a
DualBlock :: m -> Maybe a -> BridgeBlock m a -> DualBlock m a
[dualBlockMain] :: DualBlock m a -> m
[dualBlockAux] :: DualBlock m a -> Maybe a
[dualBlockBridge] :: DualBlock m a -> BridgeBlock m a
type DualHeader m a = Header (DualBlock m a)
data DualLedgerConfig m a
DualLedgerConfig :: LedgerConfig m -> LedgerConfig a -> DualLedgerConfig m a
[dualLedgerConfigMain] :: DualLedgerConfig m a -> LedgerConfig m
[dualLedgerConfigAux] :: DualLedgerConfig m a -> LedgerConfig a

-- | Both ledger rules threw an error
--   
--   We do not verify that the errors agree, merely that they both report
--   <i>some</i> error.
--   
--   If only <i>one</i> of the two semantics reports an error, we fail with
--   an <a>error</a> (see <a>agreeOnError</a>), rather than a regular chain
--   failure; if this happens, it indicates a bug, and the node should fail
--   (rather than just, for example, reject a block).
data DualLedgerError m a
DualLedgerError :: LedgerError m -> LedgerError a -> DualLedgerError m a
[dualLedgerErrorMain] :: DualLedgerError m a -> LedgerError m
[dualLedgerErrorAux] :: DualLedgerError m a -> LedgerError a
data DualGenTxErr m a
DualGenTxErr :: ApplyTxErr m -> ApplyTxErr a -> DualGenTxErr m a
[dualGenTxErrMain] :: DualGenTxErr m a -> ApplyTxErr m
[dualGenTxErrAux] :: DualGenTxErr m a -> ApplyTxErr a
dualExtValidationErrorMain :: ExtValidationError (DualBlock m a) -> ExtValidationError m

-- | This is only used for block production
dualTopLevelConfigMain :: TopLevelConfig (DualBlock m a) -> TopLevelConfig m
ctxtDualMain :: NestedCtxt_ (DualBlock m a) f x -> NestedCtxt_ m f x
data family Header blk :: Type

-- | Static configuration required to work with this type of blocks
data family BlockConfig blk :: Type

-- | Static configuration required for serialisation and deserialisation of
--   types pertaining to this type of block.
--   
--   Data family instead of type family to get better type inference.
data family CodecConfig blk :: Type

-- | Config needed for the <a>NodeInitStorage</a> class. Defined here to
--   avoid circular dependencies.
data family StorageConfig blk :: Type

-- | Ledger state associated with a block
data family LedgerState blk :: Type

-- | Generalized transaction
--   
--   The mempool (and, accordingly, blocks) consist of "generalized
--   transactions"; this could be "proper" transactions (transferring
--   funds) but also other kinds of things such as update proposals,
--   delegations, etc.
data family GenTx blk :: Type

-- | A generalized transaction, <a>GenTx</a>, identifier.
data family TxId tx :: Type

-- | Context identifying what kind of block we have
--   
--   In almost all places we will use <a>NestedCtxt</a> rather than
--   <a>NestedCtxt_</a>.
data family NestedCtxt_ blk :: (Type -> Type) -> (Type -> Type)

-- | " Ticked " piece of state (<tt>LedgerState</tt>, <tt>LedgerView</tt>,
--   <tt>ChainIndepState</tt>)
--   
--   Ticking refers to the passage of time (the ticking of the clock). When
--   a piece of state is marked as ticked, it means that time-related
--   changes have been applied to the state (or forecast).
--   
--   Some examples of time related changes:
--   
--   <ul>
--   <li>Scheduled delegations might have been applied in Byron</li>
--   <li>New leader schedule computed for Shelley</li>
--   <li>Transition from Byron to Shelley activated in the hard fork
--   combinator.</li>
--   <li>Nonces switched out at the start of a new epoch.</li>
--   </ul>
data family Ticked st :: Type
encodeDualBlock :: (Bridge m a, Serialise a) => (m -> Encoding) -> DualBlock m a -> Encoding
decodeDualBlock :: (Bridge m a, Serialise a) => Decoder s (ByteString -> m) -> Decoder s (ByteString -> DualBlock m a)
encodeDualHeader :: (Header m -> Encoding) -> Header (DualBlock m a) -> Encoding
decodeDualHeader :: Decoder s (ByteString -> Header m) -> Decoder s (ByteString -> Header (DualBlock m a))
encodeDualGenTx :: (Bridge m a, Serialise (GenTx a)) => (GenTx m -> Encoding) -> GenTx (DualBlock m a) -> Encoding
decodeDualGenTx :: (Bridge m a, Serialise (GenTx a)) => Decoder s (GenTx m) -> Decoder s (GenTx (DualBlock m a))
encodeDualGenTxId :: (GenTxId m -> Encoding) -> GenTxId (DualBlock m a) -> Encoding
decodeDualGenTxId :: Decoder s (GenTxId m) -> Decoder s (GenTxId (DualBlock m a))
encodeDualGenTxErr :: Serialise (ApplyTxErr a) => (ApplyTxErr m -> Encoding) -> ApplyTxErr (DualBlock m a) -> Encoding
decodeDualGenTxErr :: Serialise (ApplyTxErr a) => Decoder s (ApplyTxErr m) -> Decoder s (ApplyTxErr (DualBlock m a))
encodeDualLedgerState :: (Bridge m a, Serialise (LedgerState a)) => (LedgerState m -> Encoding) -> LedgerState (DualBlock m a) -> Encoding
decodeDualLedgerState :: (Bridge m a, Serialise (LedgerState a)) => Decoder s (LedgerState m) -> Decoder s (LedgerState (DualBlock m a))
instance NoThunks.Class.NoThunks (Ouroboros.Consensus.Block.Abstract.Header (Ouroboros.Consensus.Ledger.Dual.DualBlock m a))
instance NoThunks.Class.NoThunks (Ouroboros.Consensus.Block.Abstract.BlockConfig (Ouroboros.Consensus.Ledger.Dual.DualBlock m a))
instance GHC.Generics.Generic (Ouroboros.Consensus.Block.Abstract.CodecConfig (Ouroboros.Consensus.Ledger.Dual.DualBlock m a))
instance GHC.Generics.Generic (Ouroboros.Consensus.Block.Abstract.StorageConfig (Ouroboros.Consensus.Ledger.Dual.DualBlock m a))
instance NoThunks.Class.NoThunks (Ouroboros.Consensus.Ticked.Ticked (Ouroboros.Consensus.Ledger.Basics.LedgerState (Ouroboros.Consensus.Ledger.Dual.DualBlock m a)))
instance NoThunks.Class.NoThunks (Ouroboros.Consensus.Ledger.Basics.LedgerState (Ouroboros.Consensus.Ledger.Dual.DualBlock m a))
instance GHC.Show.Show (Ouroboros.Consensus.Ledger.Query.Query (Ouroboros.Consensus.Ledger.Dual.DualBlock m a) result)
instance NoThunks.Class.NoThunks (Ouroboros.Consensus.Ledger.SupportsMempool.GenTx (Ouroboros.Consensus.Ledger.Dual.DualBlock m a))
instance NoThunks.Class.NoThunks (Ouroboros.Consensus.Ledger.SupportsMempool.TxId (Ouroboros.Consensus.Ledger.SupportsMempool.GenTx (Ouroboros.Consensus.Ledger.Dual.DualBlock m a)))
instance NoThunks.Class.NoThunks (Ouroboros.Consensus.Ledger.Dual.DualLedgerError m a)
instance NoThunks.Class.NoThunks (Ouroboros.Consensus.Ledger.Dual.DualLedgerConfig m a)
instance (GHC.Show.Show m, GHC.Show.Show a, GHC.Show.Show (Ouroboros.Consensus.Ledger.Dual.BridgeBlock m a)) => GHC.Show.Show (Ouroboros.Consensus.Ledger.Dual.DualBlock m a)
instance (GHC.Classes.Eq m, GHC.Classes.Eq a, GHC.Classes.Eq (Ouroboros.Consensus.Ledger.Dual.BridgeBlock m a)) => GHC.Classes.Eq (Ouroboros.Consensus.Ledger.Dual.DualBlock m a)
instance GHC.Show.Show (Ouroboros.Consensus.Block.Abstract.Header m) => GHC.Show.Show (Ouroboros.Consensus.Ledger.Dual.DualHeader m a)
instance (GHC.Show.Show (Ouroboros.Consensus.Ledger.Basics.LedgerError m), GHC.Show.Show (Ouroboros.Consensus.Ledger.Basics.LedgerError a)) => GHC.Show.Show (Ouroboros.Consensus.Ledger.Dual.DualLedgerError m a)
instance (GHC.Classes.Eq (Ouroboros.Consensus.Ledger.Basics.LedgerError m), GHC.Classes.Eq (Ouroboros.Consensus.Ledger.Basics.LedgerError a)) => GHC.Classes.Eq (Ouroboros.Consensus.Ledger.Dual.DualLedgerError m a)
instance (GHC.Show.Show (Ouroboros.Consensus.Ledger.Basics.LedgerState m), GHC.Show.Show (Ouroboros.Consensus.Ledger.Basics.LedgerState a), Ouroboros.Consensus.Ledger.Dual.Bridge m a) => GHC.Show.Show (Ouroboros.Consensus.Ledger.Basics.LedgerState (Ouroboros.Consensus.Ledger.Dual.DualBlock m a))
instance (GHC.Classes.Eq (Ouroboros.Consensus.Ledger.Basics.LedgerState m), GHC.Classes.Eq (Ouroboros.Consensus.Ledger.Basics.LedgerState a), Ouroboros.Consensus.Ledger.Dual.Bridge m a) => GHC.Classes.Eq (Ouroboros.Consensus.Ledger.Basics.LedgerState (Ouroboros.Consensus.Ledger.Dual.DualBlock m a))
instance Ouroboros.Consensus.Ledger.Dual.Bridge m a => GHC.Show.Show (Ouroboros.Consensus.Ledger.SupportsMempool.GenTx (Ouroboros.Consensus.Ledger.Dual.DualBlock m a))
instance Ouroboros.Consensus.Ledger.Dual.Bridge m a => GHC.Show.Show (Ouroboros.Consensus.Ledger.Dual.DualGenTxErr m a)
instance GHC.Show.Show (Ouroboros.Consensus.Ledger.SupportsMempool.GenTxId m) => GHC.Show.Show (Ouroboros.Consensus.Ledger.SupportsMempool.TxId (Ouroboros.Consensus.Ledger.SupportsMempool.GenTx (Ouroboros.Consensus.Ledger.Dual.DualBlock m a)))
instance GHC.Classes.Eq (Ouroboros.Consensus.Ledger.SupportsMempool.GenTxId m) => GHC.Classes.Eq (Ouroboros.Consensus.Ledger.SupportsMempool.TxId (Ouroboros.Consensus.Ledger.SupportsMempool.GenTx (Ouroboros.Consensus.Ledger.Dual.DualBlock m a)))
instance GHC.Classes.Ord (Ouroboros.Consensus.Ledger.SupportsMempool.GenTxId m) => GHC.Classes.Ord (Ouroboros.Consensus.Ledger.SupportsMempool.TxId (Ouroboros.Consensus.Ledger.SupportsMempool.GenTx (Ouroboros.Consensus.Ledger.Dual.DualBlock m a)))
instance GHC.Show.Show (Ouroboros.Consensus.Block.NestedContent.NestedCtxt_ m f x) => GHC.Show.Show (Ouroboros.Consensus.Block.NestedContent.NestedCtxt_ (Ouroboros.Consensus.Ledger.Dual.DualBlock m a) f x)
instance (Data.Typeable.Internal.Typeable m, Data.Typeable.Internal.Typeable a) => Ouroboros.Network.Util.ShowProxy.ShowProxy (Ouroboros.Consensus.Ledger.Dual.DualGenTxErr m a)
instance Ouroboros.Consensus.Ledger.Dual.Bridge m a => Ouroboros.Consensus.Ledger.SupportsMempool.LedgerSupportsMempool (Ouroboros.Consensus.Ledger.Dual.DualBlock m a)
instance Ouroboros.Consensus.Ledger.Dual.Bridge m a => Ouroboros.Consensus.Ledger.Basics.IsLedger (Ouroboros.Consensus.Ledger.Basics.LedgerState (Ouroboros.Consensus.Ledger.Dual.DualBlock m a))
instance Ouroboros.Consensus.Ledger.Dual.Bridge m a => Ouroboros.Consensus.Ledger.Abstract.ApplyBlock (Ouroboros.Consensus.Ledger.Basics.LedgerState (Ouroboros.Consensus.Ledger.Dual.DualBlock m a)) (Ouroboros.Consensus.Ledger.Dual.DualBlock m a)
instance Ouroboros.Consensus.Ledger.Dual.Bridge m a => Ouroboros.Consensus.Ledger.SupportsProtocol.LedgerSupportsProtocol (Ouroboros.Consensus.Ledger.Dual.DualBlock m a)
instance Ouroboros.Consensus.Ledger.Dual.Bridge m a => Ouroboros.Consensus.HardFork.Abstract.HasHardForkHistory (Ouroboros.Consensus.Ledger.Dual.DualBlock m a)
instance (Data.Typeable.Internal.Typeable m, Data.Typeable.Internal.Typeable a) => Ouroboros.Network.Util.ShowProxy.ShowProxy (Ouroboros.Consensus.Ledger.Dual.DualHeader m a)
instance Ouroboros.Consensus.Ledger.Dual.Bridge m a => Ouroboros.Network.Block.HasHeader (Ouroboros.Consensus.Ledger.Dual.DualHeader m a)
instance (Data.Typeable.Internal.Typeable m, Data.Typeable.Internal.Typeable a) => Ouroboros.Network.Util.ShowProxy.ShowProxy (Ouroboros.Consensus.Ledger.Dual.DualBlock m a)
instance Ouroboros.Consensus.Util.Condense.Condense m => Ouroboros.Consensus.Util.Condense.Condense (Ouroboros.Consensus.Ledger.Dual.DualBlock m a)
instance Ouroboros.Network.Block.StandardHash m => Ouroboros.Network.Block.StandardHash (Ouroboros.Consensus.Ledger.Dual.DualBlock m a)
instance Ouroboros.Consensus.Block.Abstract.ConvertRawHash m => Ouroboros.Consensus.Block.Abstract.ConvertRawHash (Ouroboros.Consensus.Ledger.Dual.DualBlock m a)
instance Ouroboros.Consensus.Ledger.Dual.Bridge m a => Ouroboros.Consensus.Block.Abstract.GetHeader (Ouroboros.Consensus.Ledger.Dual.DualBlock m a)
instance Ouroboros.Consensus.Config.SupportsNode.ConfigSupportsNode m => Ouroboros.Consensus.Config.SupportsNode.ConfigSupportsNode (Ouroboros.Consensus.Ledger.Dual.DualBlock m a)
instance (NoThunks.Class.NoThunks (Ouroboros.Consensus.Block.Abstract.CodecConfig m), NoThunks.Class.NoThunks (Ouroboros.Consensus.Block.Abstract.CodecConfig a)) => NoThunks.Class.NoThunks (Ouroboros.Consensus.Block.Abstract.CodecConfig (Ouroboros.Consensus.Ledger.Dual.DualBlock m a))
instance (NoThunks.Class.NoThunks (Ouroboros.Consensus.Block.Abstract.StorageConfig m), NoThunks.Class.NoThunks (Ouroboros.Consensus.Block.Abstract.StorageConfig a)) => NoThunks.Class.NoThunks (Ouroboros.Consensus.Block.Abstract.StorageConfig (Ouroboros.Consensus.Ledger.Dual.DualBlock m a))
instance Ouroboros.Consensus.Ledger.Dual.Bridge m a => Data.FingerTree.Measured Ouroboros.Network.Block.BlockMeasure (Ouroboros.Consensus.Ledger.Dual.DualBlock m a)
instance Ouroboros.Consensus.Ledger.Dual.Bridge m a => Ouroboros.Network.Block.HasHeader (Ouroboros.Consensus.Ledger.Dual.DualBlock m a)
instance Ouroboros.Consensus.Ledger.Dual.Bridge m a => Ouroboros.Consensus.Block.Abstract.GetPrevHash (Ouroboros.Consensus.Ledger.Dual.DualBlock m a)
instance Ouroboros.Consensus.Ledger.Dual.Bridge m a => Ouroboros.Consensus.Block.SupportsProtocol.BlockSupportsProtocol (Ouroboros.Consensus.Ledger.Dual.DualBlock m a)
instance Ouroboros.Consensus.Ledger.Dual.Bridge m a => Ouroboros.Consensus.Ledger.Basics.GetTip (Ouroboros.Consensus.Ledger.Basics.LedgerState (Ouroboros.Consensus.Ledger.Dual.DualBlock m a))
instance Ouroboros.Consensus.Ledger.Dual.Bridge m a => Ouroboros.Consensus.Ledger.Basics.GetTip (Ouroboros.Consensus.Ticked.Ticked (Ouroboros.Consensus.Ledger.Basics.LedgerState (Ouroboros.Consensus.Ledger.Dual.DualBlock m a)))
instance Ouroboros.Consensus.Ledger.Dual.Bridge m a => Ouroboros.Consensus.Ledger.Abstract.UpdateLedger (Ouroboros.Consensus.Ledger.Dual.DualBlock m a)
instance Ouroboros.Consensus.Ledger.Dual.Bridge m a => Ouroboros.Consensus.HeaderValidation.HasAnnTip (Ouroboros.Consensus.Ledger.Dual.DualBlock m a)
instance Ouroboros.Consensus.Ledger.Dual.Bridge m a => Ouroboros.Consensus.HeaderValidation.BasicEnvelopeValidation (Ouroboros.Consensus.Ledger.Dual.DualBlock m a)
instance Ouroboros.Consensus.Ledger.Dual.Bridge m a => Ouroboros.Consensus.HeaderValidation.ValidateEnvelope (Ouroboros.Consensus.Ledger.Dual.DualBlock m a)
instance (Data.Typeable.Internal.Typeable m, Data.Typeable.Internal.Typeable a) => Ouroboros.Network.Util.ShowProxy.ShowProxy (Ouroboros.Consensus.Ledger.Query.Query (Ouroboros.Consensus.Ledger.Dual.DualBlock m a))
instance Ouroboros.Consensus.Ledger.Dual.Bridge m a => Ouroboros.Consensus.Ledger.Query.QueryLedger (Ouroboros.Consensus.Ledger.Dual.DualBlock m a)
instance Ouroboros.Consensus.Util.DepPair.SameDepIndex (Ouroboros.Consensus.Ledger.Query.Query (Ouroboros.Consensus.Ledger.Dual.DualBlock m a))
instance Ouroboros.Network.Protocol.LocalStateQuery.Type.ShowQuery (Ouroboros.Consensus.Ledger.Query.Query (Ouroboros.Consensus.Ledger.Dual.DualBlock m a))
instance Ouroboros.Consensus.Ledger.Dual.Bridge m a => Ouroboros.Consensus.Ledger.CommonProtocolParams.CommonProtocolParams (Ouroboros.Consensus.Ledger.Dual.DualBlock m a)
instance (Data.Typeable.Internal.Typeable m, Data.Typeable.Internal.Typeable a) => Ouroboros.Network.Util.ShowProxy.ShowProxy (Ouroboros.Consensus.Ledger.SupportsMempool.GenTx (Ouroboros.Consensus.Ledger.Dual.DualBlock m a))
instance (Data.Typeable.Internal.Typeable m, Data.Typeable.Internal.Typeable a) => Ouroboros.Network.Util.ShowProxy.ShowProxy (Ouroboros.Consensus.Ledger.SupportsMempool.TxId (Ouroboros.Consensus.Ledger.SupportsMempool.GenTx (Ouroboros.Consensus.Ledger.Dual.DualBlock m a)))
instance Ouroboros.Consensus.Ledger.Dual.Bridge m a => Ouroboros.Consensus.Ledger.SupportsMempool.HasTxId (Ouroboros.Consensus.Ledger.SupportsMempool.GenTx (Ouroboros.Consensus.Ledger.Dual.DualBlock m a))
instance Ouroboros.Consensus.Util.DepPair.SameDepIndex (Ouroboros.Consensus.Block.NestedContent.NestedCtxt_ m f) => Ouroboros.Consensus.Util.DepPair.SameDepIndex (Ouroboros.Consensus.Block.NestedContent.NestedCtxt_ (Ouroboros.Consensus.Ledger.Dual.DualBlock m a) f)
instance Ouroboros.Consensus.Block.NestedContent.HasNestedContent Ouroboros.Consensus.Block.Abstract.Header m => Ouroboros.Consensus.Block.NestedContent.HasNestedContent Ouroboros.Consensus.Block.Abstract.Header (Ouroboros.Consensus.Ledger.Dual.DualBlock m a)
instance Ouroboros.Consensus.Storage.Serialisation.ReconstructNestedCtxt Ouroboros.Consensus.Block.Abstract.Header m => Ouroboros.Consensus.Storage.Serialisation.ReconstructNestedCtxt Ouroboros.Consensus.Block.Abstract.Header (Ouroboros.Consensus.Ledger.Dual.DualBlock m a)
instance Ouroboros.Consensus.Storage.Serialisation.EncodeDiskDepIx (Ouroboros.Consensus.Block.NestedContent.NestedCtxt Ouroboros.Consensus.Block.Abstract.Header) m => Ouroboros.Consensus.Storage.Serialisation.EncodeDiskDepIx (Ouroboros.Consensus.Block.NestedContent.NestedCtxt Ouroboros.Consensus.Block.Abstract.Header) (Ouroboros.Consensus.Ledger.Dual.DualBlock m a)
instance Ouroboros.Consensus.Storage.Serialisation.EncodeDiskDep (Ouroboros.Consensus.Block.NestedContent.NestedCtxt Ouroboros.Consensus.Block.Abstract.Header) m => Ouroboros.Consensus.Storage.Serialisation.EncodeDiskDep (Ouroboros.Consensus.Block.NestedContent.NestedCtxt Ouroboros.Consensus.Block.Abstract.Header) (Ouroboros.Consensus.Ledger.Dual.DualBlock m a)
instance Ouroboros.Consensus.Storage.Serialisation.HasBinaryBlockInfo m => Ouroboros.Consensus.Storage.Serialisation.HasBinaryBlockInfo (Ouroboros.Consensus.Ledger.Dual.DualBlock m a)
instance Ouroboros.Consensus.Ledger.Inspect.InspectLedger m => Ouroboros.Consensus.Ledger.Inspect.InspectLedger (Ouroboros.Consensus.Ledger.Dual.DualBlock m a)

module Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock

-- | Blocks from which we can assemble a hard fork
class (LedgerSupportsProtocol blk, InspectLedger blk, LedgerSupportsMempool blk, HasTxId (GenTx blk), QueryLedger blk, HasPartialConsensusConfig (BlockProtocol blk), HasPartialLedgerConfig blk, ConvertRawHash blk, ReconstructNestedCtxt Header blk, CommonProtocolParams blk, ConfigSupportsNode blk, NodeInitStorage blk, Eq (GenTx blk), Eq (ApplyTxErr blk), Show blk, Show (Header blk), Show (CannotForge blk), Show (ForgeStateInfo blk), Show (ForgeStateUpdateError blk)) => SingleEraBlock blk

-- | Era transition
--   
--   This should only report the transition point once it is stable
--   (rollback cannot affect it anymore).
--   
--   Since we need this to construct the <tt>HardForkSummary</tt> (and
--   hence the <a>EpochInfo</a>), this takes the <i>partial</i> config, not
--   the full config (or we'd end up with a catch-22).
singleEraTransition :: SingleEraBlock blk => PartialLedgerConfig blk -> EraParams -> Bound -> LedgerState blk -> Maybe EpochNo

-- | Era information (for use in error messages)
singleEraInfo :: SingleEraBlock blk => proxy blk -> SingleEraInfo blk
singleEraTransition' :: SingleEraBlock blk => WrapPartialLedgerConfig blk -> EraParams -> Bound -> LedgerState blk -> Maybe EpochNo
proxySingle :: Proxy SingleEraBlock
newtype EraIndex xs
EraIndex :: NS (K ()) xs -> EraIndex xs
[getEraIndex] :: EraIndex xs -> NS (K ()) xs
eraIndexEmpty :: EraIndex '[] -> Void
eraIndexFromNS :: SListI xs => NS f xs -> EraIndex xs
eraIndexZero :: EraIndex (x : xs)
eraIndexSucc :: EraIndex xs -> EraIndex (x : xs)
eraIndexToInt :: EraIndex xs -> Int
instance GHC.Classes.Eq (Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.EraIndex xs)
instance Data.SOP.Constraint.All Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock xs => GHC.Show.Show (Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.EraIndex xs)
instance Data.SOP.Constraint.All Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock xs => Ouroboros.Consensus.Util.Condense.Condense (Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.EraIndex xs)
instance Data.SOP.Constraint.SListI xs => Codec.Serialise.Class.Serialise (Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.EraIndex xs)

module Ouroboros.Consensus.HardFork.Combinator.State.Infra
initHardForkState :: f x -> HardForkState f (x : xs)
tip :: SListI xs => HardForkState f xs -> NS f xs
match :: SListI xs => NS h xs -> HardForkState f xs -> Either (Mismatch h (Current f) xs) (HardForkState (Product h f) xs)
sequence :: forall f m xs. (SListI xs, Functor m) => HardForkState (m :.: f) xs -> m (HardForkState f xs)
fromTZ :: HardForkState f '[blk] -> f blk

-- | A <tt>h</tt> situated in time
data Situated h f xs
[SituatedCurrent] :: Current f x -> h x -> Situated h f (x : xs)
[SituatedNext] :: Current f x -> h y -> Situated h f (x : (y : xs))
[SituatedFuture] :: Current f x -> NS h xs -> Situated h f (x : (y : xs))
[SituatedPast] :: K Past x -> h x -> Situated h f (x : xs)
[SituatedShift] :: Situated h f xs -> Situated h f (x : xs)
situate :: NS h xs -> HardForkState f xs -> Situated h f xs
align :: forall xs f f' f''. All SingleEraBlock xs => InPairs (Translate f) xs -> NP (f' -.-> (f -.-> f'')) xs -> HardForkState f' xs -> HardForkState f xs -> HardForkState f'' xs
reconstructSummary :: Shape xs -> TransitionInfo -> HardForkState f xs -> Summary xs


-- | Infrastructure for doing chain selection across eras
module Ouroboros.Consensus.HardFork.Combinator.Protocol.ChainSel
data AcrossEraSelection :: Type -> Type -> Type

-- | Just compare block numbers
--   
--   This is a useful default when two eras run totally different consensus
--   protocols, and we just want to choose the longer chain.
[CompareBlockNo] :: AcrossEraSelection x y

-- | Two eras running the same protocol
--   
--   In this case, we can just call <tt>compareCandidates</tt> even across
--   eras. (The <a>ChainSelConfig</a> must also be the same in both eras:
--   we assert this at the value level.)
--   
--   NOTE: We require that the eras have the same <i>protocol</i>, not
--   merely the same <a>SelectView</a>, because if we have two eras with
--   different protocols that happen to use the same <a>SelectView</a> but
--   a different way to compare chains, it's not clear how to do cross-era
--   selection.
[SelectSameProtocol] :: BlockProtocol x ~ BlockProtocol y => AcrossEraSelection x y

-- | Custom chain selection
--   
--   This is the most general form, and allows to override chain selection
--   for the specific combination of two eras with a custom comparison
--   function.
[CustomChainSel] :: (ChainSelConfig (BlockProtocol x) -> ChainSelConfig (BlockProtocol y) -> SelectView (BlockProtocol x) -> SelectView (BlockProtocol y) -> Ordering) -> AcrossEraSelection x y
acrossEraSelection :: All SingleEraBlock xs => NP WrapChainSelConfig xs -> Tails AcrossEraSelection xs -> WithBlockNo (NS WrapSelectView) xs -> WithBlockNo (NS WrapSelectView) xs -> Ordering
data WithBlockNo (f :: k -> Type) (a :: k)
WithBlockNo :: BlockNo -> f a -> WithBlockNo (f :: k -> Type) (a :: k)
[getBlockNo] :: WithBlockNo (f :: k -> Type) (a :: k) -> BlockNo
[dropBlockNo] :: WithBlockNo (f :: k -> Type) (a :: k) -> f a
mapWithBlockNo :: (f x -> g y) -> WithBlockNo f x -> WithBlockNo g y
instance forall k (f :: k -> *) (a :: k). GHC.Show.Show (f a) => GHC.Show.Show (Ouroboros.Consensus.HardFork.Combinator.Protocol.ChainSel.WithBlockNo f a)

module Ouroboros.Consensus.HardFork.Combinator.Abstract.NoHardForks
class SingleEraBlock blk => NoHardForks blk

-- | Extract <a>EraParams</a> from the top-level config
--   
--   The HFC itself does not care about this, as it must be given the full
--   shape across <i>all</i> eras.
getEraParams :: NoHardForks blk => TopLevelConfig blk -> EraParams

-- | Construct partial consensus config from full consensus config
--   
--   NOTE: This is basically just losing <a>EpochInfo</a>, but that is
--   constant anyway when we are dealing with a single era.
toPartialConsensusConfig :: NoHardForks blk => proxy blk -> ConsensusConfig (BlockProtocol blk) -> PartialConsensusConfig (BlockProtocol blk)

-- | Construct partial ledger config from full ledger config
--   
--   See also <a>toPartialConsensusConfig</a>
toPartialLedgerConfig :: NoHardForks blk => proxy blk -> LedgerConfig blk -> PartialLedgerConfig blk
noHardForksEpochInfo :: NoHardForks blk => TopLevelConfig blk -> EpochInfo Identity

module Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork
class (All SingleEraBlock xs, Typeable xs, IsNonEmpty xs) => CanHardFork xs
hardForkEraTranslation :: CanHardFork xs => EraTranslation xs
hardForkChainSel :: CanHardFork xs => Tails AcrossEraSelection xs
hardForkInjectTxs :: CanHardFork xs => InPairs (RequiringBoth WrapLedgerConfig InjectTx) xs
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock blk => Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork '[blk]

module Ouroboros.Consensus.HardFork.Combinator.Abstract
class IsNonEmpty xs
isNonEmpty :: IsNonEmpty xs => proxy xs -> ProofNonEmpty xs
data ProofNonEmpty :: [Type] -> Type
[ProofNonEmpty] :: Proxy x -> Proxy xs -> ProofNonEmpty (x : xs)

module Ouroboros.Consensus.HardFork.Combinator.Util.DerivingVia
newtype LiftNS f xs
LiftNS :: NS f xs -> LiftNS f xs
newtype LiftNP f xs
LiftNP :: NP f xs -> LiftNP f xs
newtype LiftTelescope g f xs
LiftTelescope :: Telescope g f xs -> LiftTelescope g f xs
newtype LiftMismatch f g xs
LiftMismatch :: Mismatch f g xs -> LiftMismatch f g xs
newtype LiftNamedNS (name :: Symbol) f xs
LiftNamedNS :: NS f xs -> LiftNamedNS (name :: Symbol) f xs
newtype LiftNamedNP (name :: Symbol) f xs
LiftNamedNP :: NP f xs -> LiftNamedNP (name :: Symbol) f xs
newtype LiftNamedTelescope (name :: Symbol) f g xs
LiftNamedTelescope :: Telescope f g xs -> LiftNamedTelescope (name :: Symbol) f g xs
newtype LiftNamedMismatch (name :: Symbol) f g xs
LiftNamedMismatch :: Mismatch f g xs -> LiftNamedMismatch (name :: Symbol) f g xs
instance (Data.SOP.Constraint.All Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock xs, forall x. Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock x => NoThunks.Class.NoThunks (f x), forall x. Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock x => NoThunks.Class.NoThunks (g x), GHC.TypeLits.KnownSymbol name) => NoThunks.Class.NoThunks (Ouroboros.Consensus.HardFork.Combinator.Util.DerivingVia.LiftNamedMismatch name f g xs)
instance (Data.SOP.Constraint.All Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock xs, forall x. Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock x => NoThunks.Class.NoThunks (f x), forall x. Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock x => NoThunks.Class.NoThunks (g x), GHC.TypeLits.KnownSymbol name) => NoThunks.Class.NoThunks (Ouroboros.Consensus.HardFork.Combinator.Util.DerivingVia.LiftNamedTelescope name f g xs)
instance (Data.SOP.Constraint.All Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock xs, forall x. Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock x => NoThunks.Class.NoThunks (f x), GHC.TypeLits.KnownSymbol name) => NoThunks.Class.NoThunks (Ouroboros.Consensus.HardFork.Combinator.Util.DerivingVia.LiftNamedNP name f xs)
instance (Data.SOP.Constraint.All Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock xs, forall x. Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock x => NoThunks.Class.NoThunks (f x), GHC.TypeLits.KnownSymbol name) => NoThunks.Class.NoThunks (Ouroboros.Consensus.HardFork.Combinator.Util.DerivingVia.LiftNamedNS name f xs)
instance (Data.SOP.Constraint.All Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock xs, forall x. Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock x => GHC.Classes.Eq (f x), forall x. Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock x => GHC.Classes.Eq (g x)) => GHC.Classes.Eq (Ouroboros.Consensus.HardFork.Combinator.Util.DerivingVia.LiftMismatch f g xs)
instance (Data.SOP.Constraint.All Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock xs, forall x. Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock x => GHC.Classes.Ord (f x), forall x. Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock x => GHC.Classes.Ord (g x)) => GHC.Classes.Ord (Ouroboros.Consensus.HardFork.Combinator.Util.DerivingVia.LiftMismatch f g xs)
instance (Data.SOP.Constraint.All Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock xs, forall x. Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock x => GHC.Show.Show (f x), forall x. Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock x => GHC.Show.Show (g x)) => GHC.Show.Show (Ouroboros.Consensus.HardFork.Combinator.Util.DerivingVia.LiftMismatch f g xs)
instance (Data.SOP.Constraint.All Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock xs, forall x. Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock x => GHC.Classes.Eq (g x), forall x. Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock x => GHC.Classes.Eq (f x)) => GHC.Classes.Eq (Ouroboros.Consensus.HardFork.Combinator.Util.DerivingVia.LiftTelescope g f xs)
instance (Data.SOP.Constraint.All Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock xs, forall x. Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock x => GHC.Classes.Ord (f x), forall x. Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock x => GHC.Classes.Ord (g x)) => GHC.Classes.Ord (Ouroboros.Consensus.HardFork.Combinator.Util.DerivingVia.LiftTelescope g f xs)
instance (Data.SOP.Constraint.All Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock xs, forall x. Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock x => GHC.Show.Show (g x), forall x. Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock x => GHC.Show.Show (f x)) => GHC.Show.Show (Ouroboros.Consensus.HardFork.Combinator.Util.DerivingVia.LiftTelescope g f xs)
instance (Data.SOP.Constraint.All Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock xs, forall x. Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock x => GHC.Classes.Eq (f x)) => GHC.Classes.Eq (Ouroboros.Consensus.HardFork.Combinator.Util.DerivingVia.LiftNP f xs)
instance (Data.SOP.Constraint.All Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock xs, forall x. Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock x => GHC.Classes.Ord (f x)) => GHC.Classes.Ord (Ouroboros.Consensus.HardFork.Combinator.Util.DerivingVia.LiftNP f xs)
instance (Data.SOP.Constraint.All Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock xs, forall x. Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock x => GHC.Show.Show (f x)) => GHC.Show.Show (Ouroboros.Consensus.HardFork.Combinator.Util.DerivingVia.LiftNP f xs)
instance (Data.SOP.Constraint.All Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock xs, forall x. Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock x => GHC.Classes.Eq (f x)) => GHC.Classes.Eq (Ouroboros.Consensus.HardFork.Combinator.Util.DerivingVia.LiftNS f xs)
instance (Data.SOP.Constraint.All Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock xs, forall x. Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock x => GHC.Classes.Ord (f x)) => GHC.Classes.Ord (Ouroboros.Consensus.HardFork.Combinator.Util.DerivingVia.LiftNS f xs)
instance (Data.SOP.Constraint.All Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock xs, forall x. Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock x => GHC.Show.Show (f x)) => GHC.Show.Show (Ouroboros.Consensus.HardFork.Combinator.Util.DerivingVia.LiftNS f xs)

module Ouroboros.Consensus.HardFork.Combinator.State.Instances
encodeCurrent :: (f blk -> Encoding) -> Current f blk -> Encoding
decodeCurrent :: Decoder s (f blk) -> Decoder s (Current f blk)
encodePast :: Past -> Encoding
decodePast :: Decoder s Past
instance GHC.Classes.Eq (f blk) => GHC.Classes.Eq (Ouroboros.Consensus.HardFork.Combinator.State.Types.Current f blk)
instance GHC.Show.Show (f blk) => GHC.Show.Show (Ouroboros.Consensus.HardFork.Combinator.State.Types.Current f blk)
instance NoThunks.Class.NoThunks (f blk) => NoThunks.Class.NoThunks (Ouroboros.Consensus.HardFork.Combinator.State.Types.Current f blk)
instance (Data.SOP.Constraint.All Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock xs, forall blk. Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock blk => GHC.Show.Show (f blk)) => GHC.Show.Show (Ouroboros.Consensus.HardFork.Combinator.State.Types.HardForkState f xs)
instance (Data.SOP.Constraint.All Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock xs, forall blk. Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock blk => GHC.Classes.Eq (f blk)) => GHC.Classes.Eq (Ouroboros.Consensus.HardFork.Combinator.State.Types.HardForkState f xs)
instance (Data.SOP.Constraint.All Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock xs, forall blk. Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock blk => NoThunks.Class.NoThunks (f blk)) => NoThunks.Class.NoThunks (Ouroboros.Consensus.HardFork.Combinator.State.Types.HardForkState f xs)
instance Data.SOP.Classes.HAp Ouroboros.Consensus.HardFork.Combinator.State.Types.HardForkState
instance Data.SOP.Classes.HSequence Ouroboros.Consensus.HardFork.Combinator.State.Types.HardForkState
instance Data.SOP.Classes.HCollapse Ouroboros.Consensus.HardFork.Combinator.State.Types.HardForkState
instance Codec.Serialise.Class.Serialise (f blk) => Codec.Serialise.Class.Serialise (Ouroboros.Consensus.HardFork.Combinator.State.Types.Current f blk)
instance Codec.Serialise.Class.Serialise Ouroboros.Consensus.HardFork.Combinator.State.Types.Past

module Ouroboros.Consensus.HardFork.Combinator.Protocol.LedgerView
data HardForkLedgerView_ f xs
HardForkLedgerView :: !TransitionInfo -> !HardForkState f xs -> HardForkLedgerView_ f xs

-- | Information about the transition to the next era, if known
[hardForkLedgerViewTransition] :: HardForkLedgerView_ f xs -> !TransitionInfo

-- | The underlying ledger view
[hardForkLedgerViewPerEra] :: HardForkLedgerView_ f xs -> !HardForkState f xs
type HardForkLedgerView = HardForkLedgerView_ WrapLedgerView

-- | " Ticked " piece of state (<tt>LedgerState</tt>, <tt>LedgerView</tt>,
--   <tt>ChainIndepState</tt>)
--   
--   Ticking refers to the passage of time (the ticking of the clock). When
--   a piece of state is marked as ticked, it means that time-related
--   changes have been applied to the state (or forecast).
--   
--   Some examples of time related changes:
--   
--   <ul>
--   <li>Scheduled delegations might have been applied in Byron</li>
--   <li>New leader schedule computed for Shelley</li>
--   <li>Transition from Byron to Shelley activated in the hard fork
--   combinator.</li>
--   <li>Nonces switched out at the start of a new epoch.</li>
--   </ul>
data family Ticked st :: Type
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => GHC.Show.Show (Ouroboros.Consensus.HardFork.Combinator.Protocol.LedgerView.HardForkLedgerView_ Ouroboros.Consensus.TypeFamilyWrappers.WrapLedgerView xs)
instance (Data.SOP.Constraint.SListI xs, GHC.Show.Show a) => GHC.Show.Show (Ouroboros.Consensus.HardFork.Combinator.Protocol.LedgerView.HardForkLedgerView_ (Data.SOP.BasicFunctors.K a) xs)
instance (Data.SOP.Constraint.SListI xs, GHC.Show.Show (Ouroboros.Consensus.Ticked.Ticked a)) => GHC.Show.Show (Ouroboros.Consensus.Ticked.Ticked (Ouroboros.Consensus.HardFork.Combinator.Protocol.LedgerView.HardForkLedgerView_ (Data.SOP.BasicFunctors.K a) xs))

module Ouroboros.Consensus.HardFork.Combinator.AcrossEras
newtype PerEraConsensusConfig xs
PerEraConsensusConfig :: NP WrapPartialConsensusConfig xs -> PerEraConsensusConfig xs
[getPerEraConsensusConfig] :: PerEraConsensusConfig xs -> NP WrapPartialConsensusConfig xs
newtype PerEraBlockConfig xs
PerEraBlockConfig :: NP BlockConfig xs -> PerEraBlockConfig xs
[getPerEraBlockConfig] :: PerEraBlockConfig xs -> NP BlockConfig xs
newtype PerEraChainSelConfig xs
PerEraChainSelConfig :: NP WrapChainSelConfig xs -> PerEraChainSelConfig xs
[getPerEraChainSelConfig] :: PerEraChainSelConfig xs -> NP WrapChainSelConfig xs
newtype PerEraCodecConfig xs
PerEraCodecConfig :: NP CodecConfig xs -> PerEraCodecConfig xs
[getPerEraCodecConfig] :: PerEraCodecConfig xs -> NP CodecConfig xs
newtype PerEraLedgerConfig xs
PerEraLedgerConfig :: NP WrapPartialLedgerConfig xs -> PerEraLedgerConfig xs
[getPerEraLedgerConfig] :: PerEraLedgerConfig xs -> NP WrapPartialLedgerConfig xs
newtype PerEraStorageConfig xs
PerEraStorageConfig :: NP StorageConfig xs -> PerEraStorageConfig xs
[getPerEraStorageConfig] :: PerEraStorageConfig xs -> NP StorageConfig xs
newtype OneEraApplyTxErr xs
OneEraApplyTxErr :: NS WrapApplyTxErr xs -> OneEraApplyTxErr xs
[getOneEraApplyTxErr] :: OneEraApplyTxErr xs -> NS WrapApplyTxErr xs
newtype OneEraBlock xs
OneEraBlock :: NS I xs -> OneEraBlock xs
[getOneEraBlock] :: OneEraBlock xs -> NS I xs
newtype OneEraCanBeLeader xs
OneEraCanBeLeader :: NS WrapCanBeLeader xs -> OneEraCanBeLeader xs
[getOneEraCanBeLeader] :: OneEraCanBeLeader xs -> NS WrapCanBeLeader xs
newtype OneEraCannotForge xs
OneEraCannotForge :: NS WrapCannotForge xs -> OneEraCannotForge xs
[getOneEraCannotForge] :: OneEraCannotForge xs -> NS WrapCannotForge xs
newtype OneEraEnvelopeErr xs
OneEraEnvelopeErr :: NS WrapEnvelopeErr xs -> OneEraEnvelopeErr xs
[getOneEraEnvelopeErr] :: OneEraEnvelopeErr xs -> NS WrapEnvelopeErr xs
newtype OneEraForgeStateInfo xs
OneEraForgeStateInfo :: NS WrapForgeStateInfo xs -> OneEraForgeStateInfo xs
[getOneEraForgeStateInfo] :: OneEraForgeStateInfo xs -> NS WrapForgeStateInfo xs
newtype OneEraForgeStateUpdateError xs
OneEraForgeStateUpdateError :: NS WrapForgeStateUpdateError xs -> OneEraForgeStateUpdateError xs
[getOneEraForgeStateUpdateError] :: OneEraForgeStateUpdateError xs -> NS WrapForgeStateUpdateError xs
newtype OneEraGenTx xs
OneEraGenTx :: NS GenTx xs -> OneEraGenTx xs
[getOneEraGenTx] :: OneEraGenTx xs -> NS GenTx xs
newtype OneEraGenTxId xs
OneEraGenTxId :: NS WrapGenTxId xs -> OneEraGenTxId xs
[getOneEraGenTxId] :: OneEraGenTxId xs -> NS WrapGenTxId xs

-- | The hash for an era
--   
--   This type is special: we don't use an NS here, because the hash by
--   itself should not allow us to differentiate between eras. If it did,
--   the <i>size</i> of the hash would necessarily have to increase, and
--   that leads to trouble. So, the type parameter <tt>xs</tt> here is
--   merely a phantom one, and we just store the underlying raw hash.
newtype OneEraHash (xs :: [k])
OneEraHash :: ShortByteString -> OneEraHash (xs :: [k])
[getOneEraHash] :: OneEraHash (xs :: [k]) -> ShortByteString
newtype OneEraHeader xs
OneEraHeader :: NS Header xs -> OneEraHeader xs
[getOneEraHeader] :: OneEraHeader xs -> NS Header xs
newtype OneEraIsLeader xs
OneEraIsLeader :: NS WrapIsLeader xs -> OneEraIsLeader xs
[getOneEraIsLeader] :: OneEraIsLeader xs -> NS WrapIsLeader xs
newtype OneEraLedgerError xs
OneEraLedgerError :: NS WrapLedgerErr xs -> OneEraLedgerError xs
[getOneEraLedgerError] :: OneEraLedgerError xs -> NS WrapLedgerErr xs
newtype OneEraLedgerUpdate xs
OneEraLedgerUpdate :: NS WrapLedgerUpdate xs -> OneEraLedgerUpdate xs
[getOneEraLedgerUpdate] :: OneEraLedgerUpdate xs -> NS WrapLedgerUpdate xs
newtype OneEraLedgerWarning xs
OneEraLedgerWarning :: NS WrapLedgerWarning xs -> OneEraLedgerWarning xs
[getOneEraLedgerWarning] :: OneEraLedgerWarning xs -> NS WrapLedgerWarning xs
newtype OneEraSelectView xs
OneEraSelectView :: NS WrapSelectView xs -> OneEraSelectView xs
[getOneEraSelectView] :: OneEraSelectView xs -> NS WrapSelectView xs
newtype OneEraTipInfo xs
OneEraTipInfo :: NS WrapTipInfo xs -> OneEraTipInfo xs
[getOneEraTipInfo] :: OneEraTipInfo xs -> NS WrapTipInfo xs
newtype OneEraValidateView xs
OneEraValidateView :: NS WrapValidateView xs -> OneEraValidateView xs
[getOneEraValidateView] :: OneEraValidateView xs -> NS WrapValidateView xs
newtype OneEraValidationErr xs
OneEraValidationErr :: NS WrapValidationErr xs -> OneEraValidationErr xs
[getOneEraValidationErr] :: OneEraValidationErr xs -> NS WrapValidationErr xs
newtype MismatchEraInfo xs
MismatchEraInfo :: Mismatch SingleEraInfo LedgerEraInfo xs -> MismatchEraInfo xs

-- | Era mismatch
--   
--   We have an era mismatch between the era of a
--   block<i>header</i>tx/query and the era of the current ledger.
[getMismatchEraInfo] :: MismatchEraInfo xs -> Mismatch SingleEraInfo LedgerEraInfo xs
mismatchOneEra :: MismatchEraInfo '[b] -> Void

-- | A mismatch _must_ involve a future era
mismatchFutureEra :: SListI xs => MismatchEraInfo (x : xs) -> NS SingleEraInfo xs

-- | Extra info for errors caused by applying a block, header, transaction,
--   or query from one era to a ledger from a different era.
data EraMismatch
EraMismatch :: !Text -> !Text -> EraMismatch

-- | Name of the era of the ledger (<a>Byron</a> or <a>Shelley</a>).
[ledgerEraName] :: EraMismatch -> !Text

-- | Era of the block, header, transaction, or query.
[otherEraName] :: EraMismatch -> !Text

-- | When a transaction or block from a certain era was applied to a ledger
--   from another era, we get a <a>MismatchEraInfo</a>.
--   
--   Given such a <a>MismatchEraInfo</a>, return the name of the era of the
--   transaction/block and the name of the era of the ledger.
mkEraMismatch :: SListI xs => MismatchEraInfo xs -> EraMismatch
oneEraBlockHeader :: CanHardFork xs => OneEraBlock xs -> OneEraHeader xs
getSameValue :: forall xs a. (IsNonEmpty xs, Eq a, SListI xs, HasCallStack) => NP (K a) xs -> a
instance forall k (xs :: [k]). Codec.Serialise.Class.Serialise (Ouroboros.Consensus.HardFork.Combinator.AcrossEras.OneEraHash xs)
instance forall k (xs :: [k]). NoThunks.Class.NoThunks (Ouroboros.Consensus.HardFork.Combinator.AcrossEras.OneEraHash xs)
instance forall k (xs :: [k]). GHC.Classes.Ord (Ouroboros.Consensus.HardFork.Combinator.AcrossEras.OneEraHash xs)
instance forall k (xs :: [k]). GHC.Classes.Eq (Ouroboros.Consensus.HardFork.Combinator.AcrossEras.OneEraHash xs)
instance GHC.Generics.Generic Ouroboros.Consensus.HardFork.Combinator.AcrossEras.EraMismatch
instance GHC.Show.Show Ouroboros.Consensus.HardFork.Combinator.AcrossEras.EraMismatch
instance GHC.Classes.Eq Ouroboros.Consensus.HardFork.Combinator.AcrossEras.EraMismatch
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => NoThunks.Class.NoThunks (Ouroboros.Consensus.HardFork.Combinator.AcrossEras.PerEraBlockConfig xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => NoThunks.Class.NoThunks (Ouroboros.Consensus.HardFork.Combinator.AcrossEras.PerEraChainSelConfig xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => NoThunks.Class.NoThunks (Ouroboros.Consensus.HardFork.Combinator.AcrossEras.PerEraCodecConfig xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => NoThunks.Class.NoThunks (Ouroboros.Consensus.HardFork.Combinator.AcrossEras.PerEraConsensusConfig xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => NoThunks.Class.NoThunks (Ouroboros.Consensus.HardFork.Combinator.AcrossEras.PerEraLedgerConfig xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => NoThunks.Class.NoThunks (Ouroboros.Consensus.HardFork.Combinator.AcrossEras.PerEraStorageConfig xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => NoThunks.Class.NoThunks (Ouroboros.Consensus.HardFork.Combinator.AcrossEras.OneEraEnvelopeErr xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => NoThunks.Class.NoThunks (Ouroboros.Consensus.HardFork.Combinator.AcrossEras.OneEraGenTx xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => NoThunks.Class.NoThunks (Ouroboros.Consensus.HardFork.Combinator.AcrossEras.OneEraGenTxId xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => NoThunks.Class.NoThunks (Ouroboros.Consensus.HardFork.Combinator.AcrossEras.OneEraHeader xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => NoThunks.Class.NoThunks (Ouroboros.Consensus.HardFork.Combinator.AcrossEras.OneEraLedgerError xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => NoThunks.Class.NoThunks (Ouroboros.Consensus.HardFork.Combinator.AcrossEras.OneEraTipInfo xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => NoThunks.Class.NoThunks (Ouroboros.Consensus.HardFork.Combinator.AcrossEras.OneEraValidationErr xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => NoThunks.Class.NoThunks (Ouroboros.Consensus.HardFork.Combinator.AcrossEras.MismatchEraInfo xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => GHC.Classes.Eq (Ouroboros.Consensus.HardFork.Combinator.AcrossEras.PerEraChainSelConfig xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => GHC.Classes.Eq (Ouroboros.Consensus.HardFork.Combinator.AcrossEras.OneEraApplyTxErr xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => GHC.Classes.Eq (Ouroboros.Consensus.HardFork.Combinator.AcrossEras.OneEraEnvelopeErr xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => GHC.Classes.Eq (Ouroboros.Consensus.HardFork.Combinator.AcrossEras.OneEraGenTx xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => GHC.Classes.Eq (Ouroboros.Consensus.HardFork.Combinator.AcrossEras.OneEraGenTxId xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => GHC.Classes.Eq (Ouroboros.Consensus.HardFork.Combinator.AcrossEras.OneEraLedgerError xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => GHC.Classes.Eq (Ouroboros.Consensus.HardFork.Combinator.AcrossEras.OneEraLedgerUpdate xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => GHC.Classes.Eq (Ouroboros.Consensus.HardFork.Combinator.AcrossEras.OneEraLedgerWarning xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => GHC.Classes.Eq (Ouroboros.Consensus.HardFork.Combinator.AcrossEras.OneEraTipInfo xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => GHC.Classes.Eq (Ouroboros.Consensus.HardFork.Combinator.AcrossEras.OneEraValidationErr xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => GHC.Classes.Ord (Ouroboros.Consensus.HardFork.Combinator.AcrossEras.OneEraGenTxId xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => GHC.Show.Show (Ouroboros.Consensus.HardFork.Combinator.AcrossEras.PerEraChainSelConfig xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => GHC.Show.Show (Ouroboros.Consensus.HardFork.Combinator.AcrossEras.OneEraEnvelopeErr xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => GHC.Show.Show (Ouroboros.Consensus.HardFork.Combinator.AcrossEras.OneEraForgeStateInfo xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => GHC.Show.Show (Ouroboros.Consensus.HardFork.Combinator.AcrossEras.OneEraForgeStateUpdateError xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => GHC.Show.Show (Ouroboros.Consensus.HardFork.Combinator.AcrossEras.OneEraLedgerError xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => GHC.Show.Show (Ouroboros.Consensus.HardFork.Combinator.AcrossEras.OneEraLedgerUpdate xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => GHC.Show.Show (Ouroboros.Consensus.HardFork.Combinator.AcrossEras.OneEraLedgerWarning xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => GHC.Show.Show (Ouroboros.Consensus.HardFork.Combinator.AcrossEras.OneEraTipInfo xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => GHC.Show.Show (Ouroboros.Consensus.HardFork.Combinator.AcrossEras.OneEraValidationErr xs)
instance Data.SOP.Constraint.All Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock xs => GHC.Classes.Eq (Ouroboros.Consensus.HardFork.Combinator.AcrossEras.MismatchEraInfo xs)
instance Data.SOP.Constraint.All Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock xs => GHC.Show.Show (Ouroboros.Consensus.HardFork.Combinator.AcrossEras.MismatchEraInfo xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => GHC.Show.Show (Ouroboros.Consensus.HardFork.Combinator.AcrossEras.OneEraApplyTxErr xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => GHC.Show.Show (Ouroboros.Consensus.HardFork.Combinator.AcrossEras.OneEraBlock xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => GHC.Show.Show (Ouroboros.Consensus.HardFork.Combinator.AcrossEras.OneEraCannotForge xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => GHC.Show.Show (Ouroboros.Consensus.HardFork.Combinator.AcrossEras.OneEraGenTx xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => GHC.Show.Show (Ouroboros.Consensus.HardFork.Combinator.AcrossEras.OneEraGenTxId xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => GHC.Show.Show (Ouroboros.Consensus.HardFork.Combinator.AcrossEras.OneEraHeader xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => GHC.Show.Show (Ouroboros.Consensus.HardFork.Combinator.AcrossEras.OneEraSelectView xs)
instance forall k (xs :: [k]). GHC.Show.Show (Ouroboros.Consensus.HardFork.Combinator.AcrossEras.OneEraHash xs)
instance forall k (xs :: [k]). Ouroboros.Consensus.Util.Condense.Condense (Ouroboros.Consensus.HardFork.Combinator.AcrossEras.OneEraHash xs)

module Ouroboros.Consensus.HardFork.Combinator.Basics
data HardForkProtocol (xs :: [Type])
newtype HardForkBlock xs
HardForkBlock :: OneEraBlock xs -> HardForkBlock xs
[getHardForkBlock] :: HardForkBlock xs -> OneEraBlock xs

-- | Ledger state associated with a block
data family LedgerState blk :: Type

-- | Static configuration required to run the consensus protocol
--   
--   Every method in the <a>ConsensusProtocol</a> class takes the consensus
--   configuration as a parameter, so having this as a data family rather
--   than a type family resolves most ambiguity.
--   
--   Defined out of the class so that protocols can define this type
--   without having to define the entire protocol at the same time (or
--   indeed in the same module).
data family ConsensusConfig p :: Type

-- | Static configuration required to work with this type of blocks
data family BlockConfig blk :: Type

-- | Static configuration required for serialisation and deserialisation of
--   types pertaining to this type of block.
--   
--   Data family instead of type family to get better type inference.
data family CodecConfig blk :: Type

-- | Config needed for the <a>NodeInitStorage</a> class. Defined here to
--   avoid circular dependencies.
data family StorageConfig blk :: Type
data HardForkLedgerConfig xs
HardForkLedgerConfig :: !Shape xs -> !PerEraLedgerConfig xs -> HardForkLedgerConfig xs
[hardForkLedgerConfigShape] :: HardForkLedgerConfig xs -> !Shape xs
[hardForkLedgerConfigPerEra] :: HardForkLedgerConfig xs -> !PerEraLedgerConfig xs
completeLedgerConfig' :: forall blk. HasPartialLedgerConfig blk => EpochInfo Identity -> WrapPartialLedgerConfig blk -> LedgerConfig blk
completeLedgerConfig'' :: forall blk. HasPartialLedgerConfig blk => EpochInfo Identity -> WrapPartialLedgerConfig blk -> WrapLedgerConfig blk
completeConsensusConfig' :: forall blk. HasPartialConsensusConfig (BlockProtocol blk) => EpochInfo Identity -> WrapPartialConsensusConfig blk -> ConsensusConfig (BlockProtocol blk)
completeConsensusConfig'' :: forall blk. HasPartialConsensusConfig (BlockProtocol blk) => EpochInfo Identity -> WrapPartialConsensusConfig blk -> WrapConsensusConfig blk
distribLedgerConfig :: CanHardFork xs => EpochInfo Identity -> LedgerConfig (HardForkBlock xs) -> NP WrapLedgerConfig xs
distribTopLevelConfig :: All SingleEraBlock xs => EpochInfo Identity -> TopLevelConfig (HardForkBlock xs) -> NP TopLevelConfig xs

-- | Information about epochs
--   
--   Epochs may have different sizes at different times during the lifetime
--   of the blockchain. This information is encapsulated by
--   <a>EpochInfo</a>; it is parameterized over a monad <tt>m</tt> because
--   the information about how long each epoch is may depend on information
--   derived from the blockchain itself, and hence requires access to
--   state.
--   
--   The other functions provide some derived information from epoch sizes.
--   In the default implementation all of these functions query and update
--   an internal cache maintaining cumulative epoch sizes; for that reason,
--   all of these functions live in a monad <tt>m</tt>.
data EpochInfo (m :: Type -> Type)

-- | Identity functor and monad. (a non-strict monad)
data Identity a
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => NoThunks.Class.NoThunks (Ouroboros.Consensus.Protocol.Abstract.ConsensusConfig (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkProtocol xs))
instance GHC.Generics.Generic (Ouroboros.Consensus.Protocol.Abstract.ConsensusConfig (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkProtocol xs))
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => GHC.Show.Show (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => NoThunks.Class.NoThunks (Ouroboros.Consensus.Block.Abstract.BlockConfig (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs))
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => NoThunks.Class.NoThunks (Ouroboros.Consensus.Block.Abstract.CodecConfig (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs))
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => NoThunks.Class.NoThunks (Ouroboros.Consensus.Block.Abstract.StorageConfig (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs))
instance GHC.Generics.Generic (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkLedgerConfig xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => GHC.Show.Show (Ouroboros.Consensus.Ledger.Basics.LedgerState (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs))
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => GHC.Classes.Eq (Ouroboros.Consensus.Ledger.Basics.LedgerState (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs))
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => NoThunks.Class.NoThunks (Ouroboros.Consensus.Ledger.Basics.LedgerState (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs))
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => NoThunks.Class.NoThunks (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkLedgerConfig xs)
instance Data.Typeable.Internal.Typeable xs => Ouroboros.Network.Util.ShowProxy.ShowProxy (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs)


-- | Intended for qualified import
--   
--   <pre>
--   import Ouroboros.Consensus.HardFork.Combinator.State (HardForkState(..))
--   import qualified Ouroboros.Consensus.HardFork.Combinator.State as State
--   </pre>
module Ouroboros.Consensus.HardFork.Combinator.State

-- | Knowledge in a particular era of the transition to the next era
data TransitionInfo

-- | No transition is yet known for this era We instead record the ledger
--   tip (which must be in <i>this</i> era)
--   
--   NOTE: If we are forecasting, this will be set to the slot number of
--   the (past) ledger state in which the forecast was created. This means
--   that when we construct an <tt>EpochInfo</tt> using a
--   <tt>HardForkLedgerView</tt>, the range of that <tt>EpochInfo</tt> will
--   extend a safe zone from that <i>past</i> ledger state.
TransitionUnknown :: !WithOrigin SlotNo -> TransitionInfo

-- | Transition to the next era is known to happen at this <a>EpochNo</a>
TransitionKnown :: !EpochNo -> TransitionInfo

-- | The transition is impossible
--   
--   This can be due to one of two reasons:
--   
--   <ul>
--   <li>We are in the final era</li>
--   <li>This era has not actually begun yet (we are forecasting). In this
--   case, we cannot look past the safe zone of this era and hence, by
--   definition, the transition to the <i>next</i> era cannot happen.</li>
--   </ul>
TransitionImpossible :: TransitionInfo

-- | Translate (a forecast of) <tt>f x</tt> to (a forecast of) <tt>f y</tt>
--   across an era transition.
--   
--   Typically <tt>f</tt> will be <tt>WrapLedgerView</tt>.
--   
--   In addition to the <a>Bound</a> of the transition, this is also told
--   the <a>SlotNo</a> we're constructing a forecast for. This enables the
--   translation function to take into account any scheduled changes that
--   the final ledger view in the preceding era might have.
newtype TranslateForecast f g x y
TranslateForecast :: (Bound -> SlotNo -> f x -> Except OutsideForecastRange (Ticked (g y))) -> TranslateForecast f g x y
[translateForecastWith] :: TranslateForecast f g x y -> Bound -> SlotNo -> f x -> Except OutsideForecastRange (Ticked (g y))

-- | Translate <tt>f x</tt> to <tt>f y</tt> across an era transition
--   
--   Typically <tt>f</tt> will be <tt>LedgerState</tt> or
--   <tt>WrapChainDepState</tt>.
newtype Translate f x y
Translate :: (EpochNo -> f x -> f y) -> Translate f x y
[translateWith] :: Translate f x y -> EpochNo -> f x -> f y

-- | Information about a past era
data Past
Past :: !Bound -> !Bound -> Past
[pastStart] :: Past -> !Bound
[pastEnd] :: Past -> !Bound

-- | Information about the current era
data Current f blk
Current :: !Bound -> !f blk -> Current f blk
[currentStart] :: Current f blk -> !Bound
[currentState] :: Current f blk -> !f blk

-- | Generic hard fork state
--   
--   This is used both for the consensus state and the ledger state.
newtype HardForkState f xs
HardForkState :: Telescope (K Past) (Current f) xs -> HardForkState f xs
[getHardForkState] :: HardForkState f xs -> Telescope (K Past) (Current f) xs

-- | A <tt>h</tt> situated in time
data Situated h f xs
[SituatedCurrent] :: Current f x -> h x -> Situated h f (x : xs)
[SituatedNext] :: Current f x -> h y -> Situated h f (x : (y : xs))
[SituatedFuture] :: Current f x -> NS h xs -> Situated h f (x : (y : xs))
[SituatedPast] :: K Past x -> h x -> Situated h f (x : xs)
[SituatedShift] :: Situated h f xs -> Situated h f (x : xs)
initHardForkState :: f x -> HardForkState f (x : xs)
tip :: SListI xs => HardForkState f xs -> NS f xs
match :: SListI xs => NS h xs -> HardForkState f xs -> Either (Mismatch h (Current f) xs) (HardForkState (Product h f) xs)
sequence :: forall f m xs. (SListI xs, Functor m) => HardForkState (m :.: f) xs -> m (HardForkState f xs)
fromTZ :: HardForkState f '[blk] -> f blk
situate :: NS h xs -> HardForkState f xs -> Situated h f xs
align :: forall xs f f' f''. All SingleEraBlock xs => InPairs (Translate f) xs -> NP (f' -.-> (f -.-> f'')) xs -> HardForkState f' xs -> HardForkState f xs -> HardForkState f'' xs
reconstructSummary :: Shape xs -> TransitionInfo -> HardForkState f xs -> Summary xs
getTip :: forall f xs. CanHardFork xs => (forall blk. SingleEraBlock blk => f blk -> Point blk) -> HardForkState f xs -> Point (HardForkBlock xs)

-- | Recover <a>HardForkState</a> from partial information
--   
--   The primary goal of this is to make sure that for the <i>current</i>
--   state we really only need to store the underlying <tt>f</tt>. It is
--   not strictly essential that this is possible but it helps with the
--   unary hardfork case, and it may in general help with binary
--   compatibility.
recover :: forall f xs. CanHardFork xs => Telescope (K Past) f xs -> HardForkState f xs
mostRecentTransitionInfo :: All SingleEraBlock xs => HardForkLedgerConfig xs -> HardForkState LedgerState xs -> TransitionInfo
reconstructSummaryLedger :: All SingleEraBlock xs => HardForkLedgerConfig xs -> HardForkState LedgerState xs -> Summary xs

-- | Construct <a>EpochInfo</a> from the ledger state
--   
--   NOTE: The resulting <a>EpochInfo</a> is a snapshot only, with a
--   limited range. It should not be stored.
epochInfoLedger :: All SingleEraBlock xs => HardForkLedgerConfig xs -> HardForkState LedgerState xs -> EpochInfo Identity

-- | Construct <a>EpochInfo</a> given precomputed <a>TransitionInfo</a>
epochInfoPrecomputedTransitionInfo :: Shape xs -> TransitionInfo -> HardForkState f xs -> EpochInfo Identity

-- | Extend the telescope until the specified slot is within the era at the
--   tip
extendToSlot :: forall xs. CanHardFork xs => HardForkLedgerConfig xs -> SlotNo -> HardForkState LedgerState xs -> HardForkState LedgerState xs

module Ouroboros.Consensus.HardFork.Combinator.Node.InitStorage
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => Ouroboros.Consensus.Node.InitStorage.NodeInitStorage (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs)

module Ouroboros.Consensus.HardFork.Combinator.Block
data family Header blk :: Type

-- | Context identifying what kind of block we have
--   
--   In almost all places we will use <a>NestedCtxt</a> rather than
--   <a>NestedCtxt_</a>.
data family NestedCtxt_ blk :: (Type -> Type) -> (Type -> Type)
distribAnnTip :: SListI xs => AnnTip (HardForkBlock xs) -> NS AnnTip xs
undistribAnnTip :: SListI xs => NS AnnTip xs -> AnnTip (HardForkBlock xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => NoThunks.Class.NoThunks (Ouroboros.Consensus.Block.Abstract.Header (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs))
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => GHC.Show.Show (Ouroboros.Consensus.Block.Abstract.Header (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs))
instance Data.SOP.Constraint.All Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock xs => GHC.Show.Show (Ouroboros.Consensus.Block.NestedContent.NestedCtxt_ (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs) Ouroboros.Consensus.Block.Abstract.Header a)
instance Data.Typeable.Internal.Typeable xs => Ouroboros.Network.Util.ShowProxy.ShowProxy (Ouroboros.Consensus.Block.Abstract.Header (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs))
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => Ouroboros.Consensus.Block.Abstract.GetHeader (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => Ouroboros.Network.Block.StandardHash (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => Data.FingerTree.Measured Ouroboros.Network.Block.BlockMeasure (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => Ouroboros.Network.Block.HasHeader (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => Ouroboros.Network.Block.HasHeader (Ouroboros.Consensus.Block.Abstract.Header (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs))
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => Ouroboros.Consensus.Block.Abstract.GetPrevHash (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => Ouroboros.Consensus.Util.DepPair.SameDepIndex (Ouroboros.Consensus.Block.NestedContent.NestedCtxt_ (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs) Ouroboros.Consensus.Block.Abstract.Header)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => Ouroboros.Consensus.Block.NestedContent.HasNestedContent Ouroboros.Consensus.Block.Abstract.Header (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => Ouroboros.Consensus.Block.Abstract.ConvertRawHash (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => Ouroboros.Consensus.HeaderValidation.HasAnnTip (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => Ouroboros.Consensus.HeaderValidation.BasicEnvelopeValidation (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs)
instance Data.SOP.Constraint.All GHC.Classes.Eq xs => GHC.Classes.Eq (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs)
instance Data.SOP.Constraint.All (Data.SOP.Constraint.Compose GHC.Classes.Eq Ouroboros.Consensus.Block.Abstract.Header) xs => GHC.Classes.Eq (Ouroboros.Consensus.Block.Abstract.Header (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs))

module Ouroboros.Consensus.HardFork.Combinator.Protocol
type HardForkChainDepState xs = HardForkState WrapChainDepState xs

-- | We are a leader if we have a proof from one of the eras
type HardForkIsLeader xs = OneEraIsLeader xs

-- | We have one or more <a>BlockForging</a>s, and thus <a>CanBeLeader</a>
--   proofs, for each era in which we can forge blocks.
type HardForkCanBeLeader xs = OneEraCanBeLeader xs
data HardForkValidationErr xs

-- | Validation error from one of the eras
HardForkValidationErrFromEra :: OneEraValidationErr xs -> HardForkValidationErr xs

-- | We tried to apply a block from the wrong era
HardForkValidationErrWrongEra :: MismatchEraInfo xs -> HardForkValidationErr xs
data HardForkLedgerView_ f xs
HardForkLedgerView :: !TransitionInfo -> !HardForkState f xs -> HardForkLedgerView_ f xs

-- | Information about the transition to the next era, if known
[hardForkLedgerViewTransition] :: HardForkLedgerView_ f xs -> !TransitionInfo

-- | The underlying ledger view
[hardForkLedgerViewPerEra] :: HardForkLedgerView_ f xs -> !HardForkState f xs
type HardForkLedgerView = HardForkLedgerView_ WrapLedgerView

-- | " Ticked " piece of state (<tt>LedgerState</tt>, <tt>LedgerView</tt>,
--   <tt>ChainIndepState</tt>)
--   
--   Ticking refers to the passage of time (the ticking of the clock). When
--   a piece of state is marked as ticked, it means that time-related
--   changes have been applied to the state (or forecast).
--   
--   Some examples of time related changes:
--   
--   <ul>
--   <li>Scheduled delegations might have been applied in Byron</li>
--   <li>New leader schedule computed for Shelley</li>
--   <li>Transition from Byron to Shelley activated in the hard fork
--   combinator.</li>
--   <li>Nonces switched out at the start of a new epoch.</li>
--   </ul>
data family Ticked st :: Type
instance GHC.Generics.Generic (Ouroboros.Consensus.HardFork.Combinator.Protocol.HardForkValidationErr xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => GHC.Classes.Eq (Ouroboros.Consensus.HardFork.Combinator.Protocol.HardForkValidationErr xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => GHC.Show.Show (Ouroboros.Consensus.HardFork.Combinator.Protocol.HardForkValidationErr xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => NoThunks.Class.NoThunks (Ouroboros.Consensus.HardFork.Combinator.Protocol.HardForkValidationErr xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => Ouroboros.Consensus.Protocol.Abstract.ConsensusProtocol (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkProtocol xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => Ouroboros.Consensus.Protocol.Abstract.ChainSelection (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkProtocol xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => Ouroboros.Consensus.Block.SupportsProtocol.BlockSupportsProtocol (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs)

module Ouroboros.Consensus.HardFork.Combinator.Ledger
data HardForkLedgerError xs

-- | Validation error from one of the eras
HardForkLedgerErrorFromEra :: OneEraLedgerError xs -> HardForkLedgerError xs

-- | We tried to apply a block from the wrong era
HardForkLedgerErrorWrongEra :: MismatchEraInfo xs -> HardForkLedgerError xs
data HardForkLedgerWarning xs

-- | Warning from the underlying era
HardForkWarningInEra :: OneEraLedgerWarning xs -> HardForkLedgerWarning xs

-- | The transition to the next era does not match the <a>EraParams</a>
--   
--   The <a>EraParams</a> can specify a lower bound on when the transition
--   to the next era will happen. If the actual transition, when confirmed,
--   is <i>before</i> this lower bound, the node is misconfigured and will
--   likely not work correctly. This should be taken care of as soon as
--   possible (before the transition happens).
HardForkWarningTransitionMismatch :: EraIndex xs -> EraParams -> EpochNo -> HardForkLedgerWarning xs

-- | Transition in the final era
--   
--   The final era should never confirm any transitions. For clarity, we
--   also record the index of that final era.
HardForkWarningTransitionInFinalEra :: EraIndex xs -> EpochNo -> HardForkLedgerWarning xs

-- | An already-confirmed transition got un-confirmed
HardForkWarningTransitionUnconfirmed :: EraIndex xs -> HardForkLedgerWarning xs

-- | An already-confirmed transition got changed
--   
--   We record the indices of the era we are transitioning from and to, as
--   well as the old and new <a>EpochNo</a> of that transition, in that
--   order.
HardForkWarningTransitionReconfirmed :: EraIndex xs -> EraIndex xs -> EpochNo -> EpochNo -> HardForkLedgerWarning xs
data HardForkLedgerUpdate xs
HardForkUpdateInEra :: OneEraLedgerUpdate xs -> HardForkLedgerUpdate xs

-- | Hard fork transition got confirmed
HardForkUpdateTransitionConfirmed :: EraIndex xs -> EraIndex xs -> EpochNo -> HardForkLedgerUpdate xs

-- | Hard fork transition happened
--   
--   We record the <a>EpochNo</a> at the start of the era after the
--   transition
HardForkUpdateTransitionDone :: EraIndex xs -> EraIndex xs -> EpochNo -> HardForkLedgerUpdate xs

-- | The hard fork transition rolled back
HardForkUpdateTransitionRolledBack :: EraIndex xs -> EraIndex xs -> HardForkLedgerUpdate xs
data HardForkEnvelopeErr xs

-- | Validation error from one of the eras
HardForkEnvelopeErrFromEra :: OneEraEnvelopeErr xs -> HardForkEnvelopeErr xs

-- | We tried to apply a block from the wrong era
HardForkEnvelopeErrWrongEra :: MismatchEraInfo xs -> HardForkEnvelopeErr xs

-- | " Ticked " piece of state (<tt>LedgerState</tt>, <tt>LedgerView</tt>,
--   <tt>ChainIndepState</tt>)
--   
--   Ticking refers to the passage of time (the ticking of the clock). When
--   a piece of state is marked as ticked, it means that time-related
--   changes have been applied to the state (or forecast).
--   
--   Some examples of time related changes:
--   
--   <ul>
--   <li>Scheduled delegations might have been applied in Byron</li>
--   <li>New leader schedule computed for Shelley</li>
--   <li>Transition from Byron to Shelley activated in the hard fork
--   combinator.</li>
--   <li>Nonces switched out at the start of a new epoch.</li>
--   </ul>
data family Ticked st :: Type

-- | Forecast annotated with details about the ledger it was derived from
data AnnForecast state view blk
AnnForecast :: Forecast (view blk) -> state blk -> WithOrigin SlotNo -> Maybe Bound -> AnnForecast state view blk
[annForecast] :: AnnForecast state view blk -> Forecast (view blk)
[annForecastState] :: AnnForecast state view blk -> state blk
[annForecastTip] :: AnnForecast state view blk -> WithOrigin SlotNo
[annForecastEnd] :: AnnForecast state view blk -> Maybe Bound

-- | Change a telescope of a forecast into a forecast of a telescope
mkHardForkForecast :: forall state view xs. SListI xs => InPairs (TranslateForecast state view) xs -> HardForkState (AnnForecast state view) xs -> Forecast (HardForkLedgerView_ view xs)
instance GHC.Generics.Generic (Ouroboros.Consensus.Ticked.Ticked (Ouroboros.Consensus.Ledger.Basics.LedgerState (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs)))
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => NoThunks.Class.NoThunks (Ouroboros.Consensus.HardFork.Combinator.Ledger.HardForkLedgerError xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => GHC.Classes.Eq (Ouroboros.Consensus.HardFork.Combinator.Ledger.HardForkLedgerError xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => GHC.Show.Show (Ouroboros.Consensus.HardFork.Combinator.Ledger.HardForkLedgerError xs)
instance GHC.Generics.Generic (Ouroboros.Consensus.HardFork.Combinator.Ledger.HardForkLedgerError xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => NoThunks.Class.NoThunks (Ouroboros.Consensus.HardFork.Combinator.Ledger.HardForkEnvelopeErr xs)
instance GHC.Generics.Generic (Ouroboros.Consensus.HardFork.Combinator.Ledger.HardForkEnvelopeErr xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => GHC.Show.Show (Ouroboros.Consensus.HardFork.Combinator.Ledger.HardForkEnvelopeErr xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => GHC.Classes.Eq (Ouroboros.Consensus.HardFork.Combinator.Ledger.HardForkEnvelopeErr xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => NoThunks.Class.NoThunks (Ouroboros.Consensus.Ticked.Ticked (Ouroboros.Consensus.Ledger.Basics.LedgerState (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs)))
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => GHC.Show.Show (Ouroboros.Consensus.HardFork.Combinator.Ledger.HardForkLedgerWarning xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => GHC.Classes.Eq (Ouroboros.Consensus.HardFork.Combinator.Ledger.HardForkLedgerWarning xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => GHC.Show.Show (Ouroboros.Consensus.HardFork.Combinator.Ledger.HardForkLedgerUpdate xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => GHC.Classes.Eq (Ouroboros.Consensus.HardFork.Combinator.Ledger.HardForkLedgerUpdate xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => Ouroboros.Consensus.Util.Condense.Condense (Ouroboros.Consensus.HardFork.Combinator.Ledger.HardForkLedgerUpdate xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => Ouroboros.Consensus.Ledger.Inspect.InspectLedger (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => Ouroboros.Consensus.Ledger.SupportsProtocol.LedgerSupportsProtocol (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => Ouroboros.Consensus.HeaderValidation.ValidateEnvelope (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => Ouroboros.Consensus.Ledger.Basics.IsLedger (Ouroboros.Consensus.Ledger.Basics.LedgerState (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs))
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => Ouroboros.Consensus.Ledger.Abstract.ApplyBlock (Ouroboros.Consensus.Ledger.Basics.LedgerState (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs)) (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => Ouroboros.Consensus.Ledger.Basics.GetTip (Ouroboros.Consensus.Ledger.Basics.LedgerState (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs))
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => Ouroboros.Consensus.Ledger.Basics.GetTip (Ouroboros.Consensus.Ticked.Ticked (Ouroboros.Consensus.Ledger.Basics.LedgerState (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs)))
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => Ouroboros.Consensus.Ledger.Abstract.UpdateLedger (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs)
instance Data.SOP.Constraint.All Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock xs => Ouroboros.Consensus.HardFork.Abstract.HasHardForkHistory (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs)

module Ouroboros.Consensus.HardFork.Combinator.Mempool
data HardForkApplyTxErr xs

-- | Validation error from one of the eras
HardForkApplyTxErrFromEra :: !OneEraApplyTxErr xs -> HardForkApplyTxErr xs

-- | We tried to apply a block from the wrong era
HardForkApplyTxErrWrongEra :: !MismatchEraInfo xs -> HardForkApplyTxErr xs
hardForkApplyTxErrToEither :: HardForkApplyTxErr xs -> Either (MismatchEraInfo xs) (OneEraApplyTxErr xs)
hardForkApplyTxErrFromEither :: Either (MismatchEraInfo xs) (OneEraApplyTxErr xs) -> HardForkApplyTxErr xs

-- | Generalized transaction
--   
--   The mempool (and, accordingly, blocks) consist of "generalized
--   transactions"; this could be "proper" transactions (transferring
--   funds) but also other kinds of things such as update proposals,
--   delegations, etc.
data family GenTx blk :: Type

-- | A generalized transaction, <a>GenTx</a>, identifier.
data family TxId tx :: Type
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => NoThunks.Class.NoThunks (Ouroboros.Consensus.Ledger.SupportsMempool.GenTx (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs))
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => GHC.Show.Show (Ouroboros.Consensus.Ledger.SupportsMempool.GenTx (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs))
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => GHC.Classes.Eq (Ouroboros.Consensus.Ledger.SupportsMempool.GenTx (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs))
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => NoThunks.Class.NoThunks (Ouroboros.Consensus.Ledger.SupportsMempool.TxId (Ouroboros.Consensus.Ledger.SupportsMempool.GenTx (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs)))
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => GHC.Classes.Ord (Ouroboros.Consensus.Ledger.SupportsMempool.TxId (Ouroboros.Consensus.Ledger.SupportsMempool.GenTx (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs)))
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => GHC.Classes.Eq (Ouroboros.Consensus.Ledger.SupportsMempool.TxId (Ouroboros.Consensus.Ledger.SupportsMempool.GenTx (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs)))
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => GHC.Show.Show (Ouroboros.Consensus.Ledger.SupportsMempool.TxId (Ouroboros.Consensus.Ledger.SupportsMempool.GenTx (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs)))
instance GHC.Generics.Generic (Ouroboros.Consensus.HardFork.Combinator.Mempool.HardForkApplyTxErr xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => GHC.Show.Show (Ouroboros.Consensus.HardFork.Combinator.Mempool.HardForkApplyTxErr xs)
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => GHC.Classes.Eq (Ouroboros.Consensus.HardFork.Combinator.Mempool.HardForkApplyTxErr xs)
instance Data.Typeable.Internal.Typeable xs => Ouroboros.Network.Util.ShowProxy.ShowProxy (Ouroboros.Consensus.HardFork.Combinator.Mempool.HardForkApplyTxErr xs)
instance Data.Typeable.Internal.Typeable xs => Ouroboros.Network.Util.ShowProxy.ShowProxy (Ouroboros.Consensus.Ledger.SupportsMempool.GenTx (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs))
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => Ouroboros.Consensus.Ledger.SupportsMempool.LedgerSupportsMempool (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs)
instance Data.Typeable.Internal.Typeable xs => Ouroboros.Network.Util.ShowProxy.ShowProxy (Ouroboros.Consensus.Ledger.SupportsMempool.TxId (Ouroboros.Consensus.Ledger.SupportsMempool.GenTx (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs)))
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => Ouroboros.Consensus.Ledger.SupportsMempool.HasTxId (Ouroboros.Consensus.Ledger.SupportsMempool.GenTx (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs))
instance Data.SOP.Constraint.All Ouroboros.Consensus.Ledger.SupportsMempool.HasTxs xs => Ouroboros.Consensus.Ledger.SupportsMempool.HasTxs (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs)

module Ouroboros.Consensus.HardFork.Combinator.Ledger.Query

-- | Different queries supported by the ledger, indexed by the result type.
data family Query blk :: Type -> Type
data QueryIfCurrent :: [Type] -> Type -> Type
[QZ] :: Query x result -> QueryIfCurrent (x : xs) result
[QS] :: QueryIfCurrent xs result -> QueryIfCurrent (x : xs) result
type HardForkQueryResult xs = Either (MismatchEraInfo xs)
data QueryAnytime result
[GetEraStart] :: QueryAnytime (Maybe Bound)
data QueryHardFork xs result
[GetInterpreter] :: QueryHardFork xs (Interpreter xs)
[GetCurrentEra] :: QueryHardFork xs (EraIndex xs)
getHardForkQuery :: Query (HardForkBlock xs) result -> (forall result'. (result :~: HardForkQueryResult xs result') -> QueryIfCurrent xs result' -> r) -> (forall x' xs'. (xs :~: (x' : xs')) -> ProofNonEmpty xs' -> QueryAnytime result -> EraIndex xs -> r) -> (forall x' xs'. (xs :~: (x' : xs')) -> ProofNonEmpty xs' -> QueryHardFork xs result -> r) -> r
hardForkQueryInfo :: All SingleEraBlock xs => QueryIfCurrent xs result -> NS SingleEraInfo xs
encodeQueryAnytimeResult :: QueryAnytime result -> result -> Encoding
decodeQueryAnytimeResult :: QueryAnytime result -> forall s. Decoder s result
encodeQueryHardForkResult :: SListI xs => QueryHardFork xs result -> result -> Encoding
decodeQueryHardForkResult :: SListI xs => QueryHardFork xs result -> forall s. Decoder s result
instance Data.SOP.Constraint.All Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock xs => GHC.Show.Show (Ouroboros.Consensus.Ledger.Query.Query (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs) result)
instance Data.SOP.Constraint.All Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock xs => GHC.Show.Show (Ouroboros.Consensus.HardFork.Combinator.Ledger.Query.QueryIfCurrent xs result)
instance GHC.Show.Show (Ouroboros.Consensus.HardFork.Combinator.Ledger.Query.QueryAnytime result)
instance GHC.Show.Show (Ouroboros.Consensus.HardFork.Combinator.Ledger.Query.QueryHardFork xs result)
instance Data.SOP.Constraint.All Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock xs => Ouroboros.Network.Protocol.LocalStateQuery.Type.ShowQuery (Ouroboros.Consensus.HardFork.Combinator.Ledger.Query.QueryHardFork xs)
instance Ouroboros.Consensus.Util.DepPair.SameDepIndex (Ouroboros.Consensus.HardFork.Combinator.Ledger.Query.QueryHardFork xs)
instance Ouroboros.Network.Protocol.LocalStateQuery.Type.ShowQuery Ouroboros.Consensus.HardFork.Combinator.Ledger.Query.QueryAnytime
instance Ouroboros.Consensus.Util.DepPair.SameDepIndex Ouroboros.Consensus.HardFork.Combinator.Ledger.Query.QueryAnytime
instance Codec.Serialise.Class.Serialise (Ouroboros.Network.Protocol.LocalStateQuery.Codec.Some Ouroboros.Consensus.HardFork.Combinator.Ledger.Query.QueryAnytime)
instance Data.SOP.Constraint.All Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock xs => Ouroboros.Network.Protocol.LocalStateQuery.Type.ShowQuery (Ouroboros.Consensus.HardFork.Combinator.Ledger.Query.QueryIfCurrent xs)
instance Data.SOP.Constraint.All Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock xs => Ouroboros.Consensus.Util.DepPair.SameDepIndex (Ouroboros.Consensus.HardFork.Combinator.Ledger.Query.QueryIfCurrent xs)
instance Data.Typeable.Internal.Typeable xs => Ouroboros.Network.Util.ShowProxy.ShowProxy (Ouroboros.Consensus.Ledger.Query.Query (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs))
instance Data.SOP.Constraint.All Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock xs => Ouroboros.Network.Protocol.LocalStateQuery.Type.ShowQuery (Ouroboros.Consensus.Ledger.Query.Query (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs))
instance Data.SOP.Constraint.All Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock xs => Ouroboros.Consensus.Ledger.Query.QueryLedger (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs)
instance Data.SOP.Constraint.All Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock.SingleEraBlock xs => Ouroboros.Consensus.Util.DepPair.SameDepIndex (Ouroboros.Consensus.Ledger.Query.Query (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs))

module Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common

-- | Conditions required by the HFC to provide serialisation
--   
--   NOTE: Compatibility between HFC enabled and disabled:
--   
--   <ol>
--   <li>Node-to-node and node-to-client communication is versioned. When
--   the HFC is disabled, we default to the instances for the first era,
--   and so compatibility is preserved by construction.</li>
--   <li>On-disk storage is <i>not</i> versioned, and here we make no
--   attempt to be compatible between non-HFC and HFC deployments,
--   <i>except</i> for blocks: we define two methods
--   <a>encodeDiskHfcBlock</a> and <a>decodeDiskHfcBlock</a> which are used
--   for on-disk serialisation of blocks. These methods have defaults which
--   can and probably should be used for deployments that use the HFC from
--   the get-go, but for deployments that only later change to use the HFC
--   these functions can be overriden to provide an on-disk storage format
--   for HFC blocks that is compatible with the on-disk storage of blocks
--   from the first era.</li>
--   <li>The converse is NOT supported. Deployments that use the HFC from
--   the start should not use <a>HardForkNodeToNodeDisabled</a> and/or
--   <a>HardForkNodeToClientDisabled</a>. Doing so would result in opposite
--   compatibility problems: the on-disk block would include the HFC tag,
--   but sending blocks with the HFC disabled suggests that that tag is
--   unexpected. This would then lead to problems with binary streaming,
--   and we do not currently provide any provisions to resolve these.</li>
--   </ol>
class (CanHardFork xs, All SerialiseConstraintsHFC xs, All (Compose Show EraNodeToNodeVersion) xs, All (Compose Eq EraNodeToNodeVersion) xs, All (Compose Show EraNodeToClientVersion) xs, All (Compose Eq EraNodeToClientVersion) xs, All (EncodeDiskDepIx (NestedCtxt Header)) xs, All (DecodeDiskDepIx (NestedCtxt Header)) xs, All HasBinaryBlockInfo xs) => SerialiseHFC xs
encodeDiskHfcBlock :: SerialiseHFC xs => CodecConfig (HardForkBlock xs) -> HardForkBlock xs -> Encoding
decodeDiskHfcBlock :: SerialiseHFC xs => CodecConfig (HardForkBlock xs) -> forall s. Decoder s (ByteString -> HardForkBlock xs)

-- | Used as the implementation of <a>reconstructPrefixLen</a> for
--   <a>HardForkBlock</a>.
reconstructHfcPrefixLen :: SerialiseHFC xs => proxy (Header (HardForkBlock xs)) -> PrefixLen

-- | Used as the implementation of <a>reconstructNestedCtxt</a> for
--   <a>HardForkBlock</a>.
reconstructHfcNestedCtxt :: SerialiseHFC xs => proxy (Header (HardForkBlock xs)) -> ShortByteString -> SizeInBytes -> SomeSecond (NestedCtxt Header) (HardForkBlock xs)

-- | Used as the implementation of <a>getBinaryBlockInfo</a> for
--   <a>HardForkBlock</a>.
getHfcBinaryBlockInfo :: SerialiseHFC xs => HardForkBlock xs -> BinaryBlockInfo

-- | Used as the implementation of <a>estimateBlockSize</a> for
--   <a>HardForkBlock</a>.
estimateHfcBlockSize :: SerialiseHFC xs => Header (HardForkBlock xs) -> SizeInBytes
class (SingleEraBlock blk, SerialiseDiskConstraints blk, SerialiseNodeToNodeConstraints blk, SerialiseNodeToClientConstraints blk, HasNetworkProtocolVersion blk) => SerialiseConstraintsHFC blk
pSHFC :: Proxy SerialiseConstraintsHFC

-- | Exception thrown in the HFC encoders
data HardForkEncoderException

-- | HFC disabled, but we saw a value from an era other than the first
[HardForkEncoderFutureEra] :: SingleEraInfo blk -> HardForkEncoderException

-- | HFC enabled, but we saw a value from a disabled era
[HardForkEncoderDisabledEra] :: SingleEraInfo blk -> HardForkEncoderException

-- | HFC disabled, but we saw a query that is only supported by the HFC
[HardForkEncoderQueryHfcDisabled] :: HardForkEncoderException

-- | HFC enabled, but we saw a HFC query that is not supported by the
--   HFC-specific version used
[HardForkEncoderQueryWrongVersion] :: HardForkEncoderException
futureEraException :: SListI xs => NS SingleEraInfo xs -> HardForkEncoderException
disabledEraException :: forall blk. SingleEraBlock blk => Proxy blk -> HardForkEncoderException
type family FirstEra (xs :: [Type])
type family LaterEra (xs :: [Type])
isFirstEra :: forall f xs. All SingleEraBlock xs => NS f xs -> Either (NS SingleEraInfo (LaterEra xs)) (f (FirstEra xs))

-- | Used to construct <tt>FutureEraException</tt>
notFirstEra :: All SingleEraBlock xs => NS f xs -> NS SingleEraInfo xs

-- | Versioning of the specific additions made by the HFC to the
--   <tt>NodeToNode</tt> protocols, e.g., the era tag.
data HardForkSpecificNodeToNodeVersion
HardForkSpecificNodeToNodeVersion1 :: HardForkSpecificNodeToNodeVersion

-- | Versioning of the specific additions made by the HFC to the
--   <tt>NodeToClient</tt> protocols, e.g., the era tag or the hard-fork
--   specific queries.
data HardForkSpecificNodeToClientVersion
HardForkSpecificNodeToClientVersion1 :: HardForkSpecificNodeToClientVersion

-- | Enable the <a>GetCurrentEra</a> query in <a>QueryHardFork</a>.
HardForkSpecificNodeToClientVersion2 :: HardForkSpecificNodeToClientVersion
data HardForkNodeToNodeVersion xs

-- | Disable the HFC
--   
--   This means that only the first era (<tt>x</tt>) is supported, and
--   moreover, is compatible with serialisation used if the HFC would not
--   be present at all.
[HardForkNodeToNodeDisabled] :: BlockNodeToNodeVersion x -> HardForkNodeToNodeVersion (x : xs)

-- | Enable the HFC
--   
--   Each era can be enabled or disabled individually by passing
--   <a>EraNodeToNodeDisabled</a> as its configuration, but serialised
--   values will always include tags inserted by the HFC to distinguish one
--   era from another. We also version the hard-fork specific parts with
--   <a>HardForkSpecificNodeToNodeVersion</a>.
[HardForkNodeToNodeEnabled] :: HardForkSpecificNodeToNodeVersion -> NP EraNodeToNodeVersion xs -> HardForkNodeToNodeVersion xs
data HardForkNodeToClientVersion xs

-- | Disable the HFC
--   
--   See <a>HardForkNodeToNodeDisabled</a>
[HardForkNodeToClientDisabled] :: BlockNodeToClientVersion x -> HardForkNodeToClientVersion (x : xs)

-- | Enable the HFC
--   
--   See <a>HardForkNodeToNodeEnabled</a>
[HardForkNodeToClientEnabled] :: HardForkSpecificNodeToClientVersion -> NP EraNodeToClientVersion xs -> HardForkNodeToClientVersion xs
data EraNodeToNodeVersion blk
EraNodeToNodeEnabled :: !BlockNodeToNodeVersion blk -> EraNodeToNodeVersion blk
EraNodeToNodeDisabled :: EraNodeToNodeVersion blk
data EraNodeToClientVersion blk
EraNodeToClientEnabled :: !BlockNodeToClientVersion blk -> EraNodeToClientVersion blk
EraNodeToClientDisabled :: EraNodeToClientVersion blk
isHardForkNodeToNodeEnabled :: HardForkNodeToNodeVersion xs -> Bool
isHardForkNodeToClientEnabled :: HardForkNodeToClientVersion xs -> Bool
data AnnDecoder f blk
AnnDecoder :: (forall s. Decoder s (ByteString -> f blk)) -> AnnDecoder f blk
[annDecoder] :: AnnDecoder f blk -> forall s. Decoder s (ByteString -> f blk)
encodeTelescope :: SListI xs => NP (f -.-> K Encoding) xs -> HardForkState f xs -> Encoding
decodeTelescope :: NP (Decoder s :.: f) xs -> Decoder s (HardForkState f xs)
encodeNS :: SListI xs => NP (f -.-> K Encoding) xs -> NS f xs -> Encoding
decodeNS :: SListI xs => NP (Decoder s :.: f) xs -> Decoder s (NS f xs)
decodeAnnNS :: SListI xs => NP (AnnDecoder f) xs -> forall s. Decoder s (ByteString -> NS f xs)
encodeNestedCtxt :: All (EncodeDiskDepIx (NestedCtxt f)) xs => CodecConfig (HardForkBlock xs) -> SomeSecond (NestedCtxt f) (HardForkBlock xs) -> Encoding
decodeNestedCtxt :: All (DecodeDiskDepIx (NestedCtxt f)) xs => CodecConfig (HardForkBlock xs) -> forall s. Decoder s (SomeSecond (NestedCtxt f) (HardForkBlock xs))
encodeNested :: All (EncodeDiskDep (NestedCtxt f)) xs => CodecConfig (HardForkBlock xs) -> NestedCtxt f (HardForkBlock xs) a -> a -> Encoding
decodeNested :: All (DecodeDiskDep (NestedCtxt f)) xs => CodecConfig (HardForkBlock xs) -> NestedCtxt f (HardForkBlock xs) a -> forall s. Decoder s (ByteString -> a)
encodeEitherMismatch :: forall xs a. SListI xs => BlockNodeToClientVersion (HardForkBlock xs) -> (a -> Encoding) -> Either (MismatchEraInfo xs) a -> Encoding
decodeEitherMismatch :: SListI xs => BlockNodeToClientVersion (HardForkBlock xs) -> Decoder s a -> Decoder s (Either (MismatchEraInfo xs) a)
distribAnnTip :: SListI xs => AnnTip (HardForkBlock xs) -> NS AnnTip xs
undistribAnnTip :: SListI xs => NS AnnTip xs -> AnnTip (HardForkBlock xs)
distribSerialisedHeader :: SerialisedHeader (HardForkBlock xs) -> NS SerialisedHeader xs
undistribSerialisedHeader :: NS SerialisedHeader xs -> SerialisedHeader (HardForkBlock xs)
distribQueryIfCurrent :: Some (QueryIfCurrent xs) -> NS (SomeSecond Query) xs
undistribQueryIfCurrent :: NS (SomeSecond Query) xs -> Some (QueryIfCurrent xs)

-- | Used for deriving via
--   
--   Example
--   
--   <pre>
--   deriving via SerialiseNS Header SomeEras
--            instance Serialise (Header SomeSecond)
--   </pre>
newtype SerialiseNS f xs
SerialiseNS :: NS f xs -> SerialiseNS f xs
[getSerialiseNS] :: SerialiseNS f xs -> NS f xs
instance GHC.Enum.Bounded Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common.HardForkSpecificNodeToNodeVersion
instance GHC.Enum.Enum Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common.HardForkSpecificNodeToNodeVersion
instance GHC.Show.Show Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common.HardForkSpecificNodeToNodeVersion
instance GHC.Classes.Ord Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common.HardForkSpecificNodeToNodeVersion
instance GHC.Classes.Eq Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common.HardForkSpecificNodeToNodeVersion
instance GHC.Enum.Bounded Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common.HardForkSpecificNodeToClientVersion
instance GHC.Enum.Enum Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common.HardForkSpecificNodeToClientVersion
instance GHC.Show.Show Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common.HardForkSpecificNodeToClientVersion
instance GHC.Classes.Ord Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common.HardForkSpecificNodeToClientVersion
instance GHC.Classes.Eq Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common.HardForkSpecificNodeToClientVersion
instance GHC.Show.Show (Ouroboros.Consensus.Node.NetworkProtocolVersion.BlockNodeToNodeVersion blk) => GHC.Show.Show (Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common.EraNodeToNodeVersion blk)
instance GHC.Show.Show (Ouroboros.Consensus.Node.NetworkProtocolVersion.BlockNodeToClientVersion blk) => GHC.Show.Show (Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common.EraNodeToClientVersion blk)
instance GHC.Classes.Eq (Ouroboros.Consensus.Node.NetworkProtocolVersion.BlockNodeToNodeVersion blk) => GHC.Classes.Eq (Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common.EraNodeToNodeVersion blk)
instance GHC.Classes.Eq (Ouroboros.Consensus.Node.NetworkProtocolVersion.BlockNodeToClientVersion blk) => GHC.Classes.Eq (Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common.EraNodeToClientVersion blk)
instance Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common.SerialiseHFC xs => GHC.Show.Show (Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common.HardForkNodeToNodeVersion xs)
instance Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common.SerialiseHFC xs => GHC.Show.Show (Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common.HardForkNodeToClientVersion xs)
instance Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common.SerialiseHFC xs => GHC.Classes.Eq (Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common.HardForkNodeToNodeVersion xs)
instance Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common.SerialiseHFC xs => GHC.Classes.Eq (Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common.HardForkNodeToClientVersion xs)
instance GHC.Show.Show Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common.HardForkEncoderException
instance Data.SOP.Constraint.All (Data.SOP.Constraint.Compose Codec.Serialise.Class.Serialise f) xs => Codec.Serialise.Class.Serialise (Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common.SerialiseNS f xs)
instance Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common.SerialiseHFC xs => Ouroboros.Consensus.Node.NetworkProtocolVersion.HasNetworkProtocolVersion (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs)
instance GHC.Exception.Type.Exception Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common.HardForkEncoderException

module Ouroboros.Consensus.HardFork.Combinator.Serialisation.SerialiseDisk
instance Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common.SerialiseHFC xs => Ouroboros.Consensus.Storage.ChainDB.Impl.Types.SerialiseDiskConstraints (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs)
instance Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common.SerialiseHFC xs => Ouroboros.Consensus.Storage.Serialisation.ReconstructNestedCtxt Ouroboros.Consensus.Block.Abstract.Header (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs)
instance Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common.SerialiseHFC xs => Ouroboros.Consensus.Storage.Serialisation.HasBinaryBlockInfo (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs)
instance Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common.SerialiseHFC xs => Ouroboros.Consensus.Storage.Serialisation.EncodeDisk (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs) (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs)
instance Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common.SerialiseHFC xs => Ouroboros.Consensus.Storage.Serialisation.DecodeDisk (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs) (Data.ByteString.Lazy.Internal.ByteString -> Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs)
instance Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common.SerialiseHFC xs => Ouroboros.Consensus.Storage.Serialisation.EncodeDiskDepIx (Ouroboros.Consensus.Block.NestedContent.NestedCtxt Ouroboros.Consensus.Block.Abstract.Header) (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs)
instance Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common.SerialiseHFC xs => Ouroboros.Consensus.Storage.Serialisation.DecodeDiskDepIx (Ouroboros.Consensus.Block.NestedContent.NestedCtxt Ouroboros.Consensus.Block.Abstract.Header) (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs)
instance Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common.SerialiseHFC xs => Ouroboros.Consensus.Storage.Serialisation.EncodeDiskDep (Ouroboros.Consensus.Block.NestedContent.NestedCtxt Ouroboros.Consensus.Block.Abstract.Header) (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs)
instance Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common.SerialiseHFC xs => Ouroboros.Consensus.Storage.Serialisation.DecodeDiskDep (Ouroboros.Consensus.Block.NestedContent.NestedCtxt Ouroboros.Consensus.Block.Abstract.Header) (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs)
instance Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common.SerialiseHFC xs => Ouroboros.Consensus.Storage.Serialisation.EncodeDisk (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs) (Ouroboros.Consensus.HeaderValidation.AnnTip (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs))
instance Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common.SerialiseHFC xs => Ouroboros.Consensus.Storage.Serialisation.DecodeDisk (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs) (Ouroboros.Consensus.HeaderValidation.AnnTip (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs))
instance Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common.SerialiseHFC xs => Ouroboros.Consensus.Storage.Serialisation.EncodeDisk (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs) (Ouroboros.Consensus.HardFork.Combinator.Protocol.HardForkChainDepState xs)
instance Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common.SerialiseHFC xs => Ouroboros.Consensus.Storage.Serialisation.DecodeDisk (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs) (Ouroboros.Consensus.HardFork.Combinator.Protocol.HardForkChainDepState xs)
instance Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common.SerialiseHFC xs => Ouroboros.Consensus.Storage.Serialisation.EncodeDisk (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs) (Ouroboros.Consensus.Ledger.Basics.LedgerState (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs))
instance Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common.SerialiseHFC xs => Ouroboros.Consensus.Storage.Serialisation.DecodeDisk (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs) (Ouroboros.Consensus.Ledger.Basics.LedgerState (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs))

module Ouroboros.Consensus.HardFork.Combinator.Serialisation.SerialiseNodeToNode
instance Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common.SerialiseHFC xs => Ouroboros.Consensus.Node.Run.SerialiseNodeToNodeConstraints (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs)
instance Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common.SerialiseHFC xs => Ouroboros.Consensus.Node.Serialisation.SerialiseNodeToNode (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs) (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs)
instance Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common.SerialiseHFC xs => Ouroboros.Consensus.Node.Serialisation.SerialiseNodeToNode (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs) (Ouroboros.Consensus.Block.Abstract.Header (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs))
instance Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common.SerialiseHFC xs => Ouroboros.Consensus.Node.Serialisation.SerialiseNodeToNode (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs) (Ouroboros.Network.Block.Serialised (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs))
instance Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common.SerialiseHFC xs => Ouroboros.Consensus.Node.Serialisation.SerialiseNodeToNode (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs) (Ouroboros.Consensus.Storage.Serialisation.SerialisedHeader (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs))
instance Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common.SerialiseHFC xs => Ouroboros.Consensus.Node.Serialisation.SerialiseNodeToNode (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs) (Ouroboros.Consensus.Ledger.SupportsMempool.GenTx (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs))
instance Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common.SerialiseHFC xs => Ouroboros.Consensus.Node.Serialisation.SerialiseNodeToNode (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs) (Ouroboros.Consensus.Ledger.SupportsMempool.GenTxId (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs))

module Ouroboros.Consensus.HardFork.Combinator.Serialisation.SerialiseNodeToClient
instance Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common.SerialiseHFC xs => Ouroboros.Consensus.Node.Run.SerialiseNodeToClientConstraints (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs)
instance Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common.SerialiseHFC xs => Ouroboros.Consensus.Node.Serialisation.SerialiseNodeToClient (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs) (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs)
instance Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common.SerialiseHFC xs => Ouroboros.Consensus.Node.Serialisation.SerialiseNodeToClient (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs) (Ouroboros.Network.Block.Serialised (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs))
instance Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common.SerialiseHFC xs => Ouroboros.Consensus.Node.Serialisation.SerialiseNodeToClient (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs) (Ouroboros.Consensus.Ledger.SupportsMempool.GenTx (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs))
instance Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common.SerialiseHFC xs => Ouroboros.Consensus.Node.Serialisation.SerialiseNodeToClient (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs) (Ouroboros.Consensus.HardFork.Combinator.Mempool.HardForkApplyTxErr xs)
instance Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common.SerialiseHFC xs => Ouroboros.Consensus.Node.Serialisation.SerialiseNodeToClient (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs) (Ouroboros.Consensus.Util.SomeSecond Ouroboros.Consensus.Ledger.Query.Query (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs))
instance Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common.SerialiseHFC xs => Ouroboros.Consensus.Node.Serialisation.SerialiseResult (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs) (Ouroboros.Consensus.Ledger.Query.Query (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs))


-- | Serialisation support for the HFC
module Ouroboros.Consensus.HardFork.Combinator.Serialisation

-- | Conditions required by the HFC to provide serialisation
--   
--   NOTE: Compatibility between HFC enabled and disabled:
--   
--   <ol>
--   <li>Node-to-node and node-to-client communication is versioned. When
--   the HFC is disabled, we default to the instances for the first era,
--   and so compatibility is preserved by construction.</li>
--   <li>On-disk storage is <i>not</i> versioned, and here we make no
--   attempt to be compatible between non-HFC and HFC deployments,
--   <i>except</i> for blocks: we define two methods
--   <a>encodeDiskHfcBlock</a> and <a>decodeDiskHfcBlock</a> which are used
--   for on-disk serialisation of blocks. These methods have defaults which
--   can and probably should be used for deployments that use the HFC from
--   the get-go, but for deployments that only later change to use the HFC
--   these functions can be overriden to provide an on-disk storage format
--   for HFC blocks that is compatible with the on-disk storage of blocks
--   from the first era.</li>
--   <li>The converse is NOT supported. Deployments that use the HFC from
--   the start should not use <a>HardForkNodeToNodeDisabled</a> and/or
--   <a>HardForkNodeToClientDisabled</a>. Doing so would result in opposite
--   compatibility problems: the on-disk block would include the HFC tag,
--   but sending blocks with the HFC disabled suggests that that tag is
--   unexpected. This would then lead to problems with binary streaming,
--   and we do not currently provide any provisions to resolve these.</li>
--   </ol>
class (CanHardFork xs, All SerialiseConstraintsHFC xs, All (Compose Show EraNodeToNodeVersion) xs, All (Compose Eq EraNodeToNodeVersion) xs, All (Compose Show EraNodeToClientVersion) xs, All (Compose Eq EraNodeToClientVersion) xs, All (EncodeDiskDepIx (NestedCtxt Header)) xs, All (DecodeDiskDepIx (NestedCtxt Header)) xs, All HasBinaryBlockInfo xs) => SerialiseHFC xs
encodeDiskHfcBlock :: SerialiseHFC xs => CodecConfig (HardForkBlock xs) -> HardForkBlock xs -> Encoding
decodeDiskHfcBlock :: SerialiseHFC xs => CodecConfig (HardForkBlock xs) -> forall s. Decoder s (ByteString -> HardForkBlock xs)

-- | Used as the implementation of <a>reconstructPrefixLen</a> for
--   <a>HardForkBlock</a>.
reconstructHfcPrefixLen :: SerialiseHFC xs => proxy (Header (HardForkBlock xs)) -> PrefixLen

-- | Used as the implementation of <a>reconstructNestedCtxt</a> for
--   <a>HardForkBlock</a>.
reconstructHfcNestedCtxt :: SerialiseHFC xs => proxy (Header (HardForkBlock xs)) -> ShortByteString -> SizeInBytes -> SomeSecond (NestedCtxt Header) (HardForkBlock xs)

-- | Used as the implementation of <a>getBinaryBlockInfo</a> for
--   <a>HardForkBlock</a>.
getHfcBinaryBlockInfo :: SerialiseHFC xs => HardForkBlock xs -> BinaryBlockInfo

-- | Used as the implementation of <a>estimateBlockSize</a> for
--   <a>HardForkBlock</a>.
estimateHfcBlockSize :: SerialiseHFC xs => Header (HardForkBlock xs) -> SizeInBytes
class (SingleEraBlock blk, SerialiseDiskConstraints blk, SerialiseNodeToNodeConstraints blk, SerialiseNodeToClientConstraints blk, HasNetworkProtocolVersion blk) => SerialiseConstraintsHFC blk
data EraNodeToClientVersion blk
EraNodeToClientEnabled :: !BlockNodeToClientVersion blk -> EraNodeToClientVersion blk
EraNodeToClientDisabled :: EraNodeToClientVersion blk
data EraNodeToNodeVersion blk
EraNodeToNodeEnabled :: !BlockNodeToNodeVersion blk -> EraNodeToNodeVersion blk
EraNodeToNodeDisabled :: EraNodeToNodeVersion blk
data HardForkNodeToClientVersion xs

-- | Disable the HFC
--   
--   See <a>HardForkNodeToNodeDisabled</a>
[HardForkNodeToClientDisabled] :: BlockNodeToClientVersion x -> HardForkNodeToClientVersion (x : xs)

-- | Enable the HFC
--   
--   See <a>HardForkNodeToNodeEnabled</a>
[HardForkNodeToClientEnabled] :: HardForkSpecificNodeToClientVersion -> NP EraNodeToClientVersion xs -> HardForkNodeToClientVersion xs
data HardForkNodeToNodeVersion xs

-- | Disable the HFC
--   
--   This means that only the first era (<tt>x</tt>) is supported, and
--   moreover, is compatible with serialisation used if the HFC would not
--   be present at all.
[HardForkNodeToNodeDisabled] :: BlockNodeToNodeVersion x -> HardForkNodeToNodeVersion (x : xs)

-- | Enable the HFC
--   
--   Each era can be enabled or disabled individually by passing
--   <a>EraNodeToNodeDisabled</a> as its configuration, but serialised
--   values will always include tags inserted by the HFC to distinguish one
--   era from another. We also version the hard-fork specific parts with
--   <a>HardForkSpecificNodeToNodeVersion</a>.
[HardForkNodeToNodeEnabled] :: HardForkSpecificNodeToNodeVersion -> NP EraNodeToNodeVersion xs -> HardForkNodeToNodeVersion xs

-- | Versioning of the specific additions made by the HFC to the
--   <tt>NodeToClient</tt> protocols, e.g., the era tag or the hard-fork
--   specific queries.
data HardForkSpecificNodeToClientVersion
HardForkSpecificNodeToClientVersion1 :: HardForkSpecificNodeToClientVersion

-- | Enable the <a>GetCurrentEra</a> query in <a>QueryHardFork</a>.
HardForkSpecificNodeToClientVersion2 :: HardForkSpecificNodeToClientVersion

-- | Versioning of the specific additions made by the HFC to the
--   <tt>NodeToNode</tt> protocols, e.g., the era tag.
data HardForkSpecificNodeToNodeVersion
HardForkSpecificNodeToNodeVersion1 :: HardForkSpecificNodeToNodeVersion
isHardForkNodeToNodeEnabled :: HardForkNodeToNodeVersion xs -> Bool
isHardForkNodeToClientEnabled :: HardForkNodeToClientVersion xs -> Bool

module Ouroboros.Consensus.HardFork.Combinator.Compat

-- | Version of <tt>Query (HardForkBlock xs)</tt> without the restriction
--   to have at least two eras
data HardForkCompatQuery blk :: Type -> Type
[CompatIfCurrent] :: Query blk result -> HardForkCompatQuery blk result
[CompatAnytime] :: QueryAnytime result -> EraIndex (HardForkIndices blk) -> HardForkCompatQuery blk result
[CompatHardFork] :: QueryHardFork (HardForkIndices blk) result -> HardForkCompatQuery blk result

-- | Submit query to underlying ledger
compatIfCurrent :: Query blk result -> HardForkCompatQuery blk result

-- | Get the start of the specified era, if known
compatGetEraStart :: EraIndex (HardForkIndices blk) -> HardForkCompatQuery blk (Maybe Bound)

-- | Get an interpreter for history queries
--   
--   I.e., this can be used for slot<i>epoch</i>time conversions.
compatGetInterpreter :: HardForkCompatQuery blk (Interpreter (HardForkIndices blk))

-- | Wrapper used when connecting to a server that's running the HFC with
--   at least two eras
forwardCompatQuery :: forall m x xs. IsNonEmpty xs => (forall result. Query (HardForkBlock (x : xs)) result -> m result) -> forall result. HardForkCompatQuery (HardForkBlock (x : xs)) result -> m result

-- | Wrapper used when connecting to a server that's not using the HFC, or
--   is using the HFC but with a single era only.
singleEraCompatQuery :: forall m blk era. (Monad m, HardForkIndices blk ~ '[era]) => EpochSize -> SlotLength -> (forall result. Query blk result -> m result) -> forall result. HardForkCompatQuery blk result -> m result

module Ouroboros.Consensus.HardFork.Combinator.Ledger.CommonProtocolParams
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => Ouroboros.Consensus.Ledger.CommonProtocolParams.CommonProtocolParams (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs)

module Ouroboros.Consensus.HardFork.Combinator.Forging

-- | If we cannot forge, it's because the current era could not forge
type HardForkCannotForge xs = OneEraCannotForge xs
hardForkBlockForging :: forall m xs. (CanHardFork xs, Monad m) => NS (BlockForging m) xs -> BlockForging m (HardForkBlock xs)

-- | For each era in which we want to forge blocks, we have a
--   <a>BlockForging</a>, and thus <a>ForgeStateInfo</a>.
type HardForkForgeStateInfo xs = OneEraForgeStateInfo xs

-- | For each era in which we want to forge blocks, we have a
--   <a>BlockForging</a>, and thus <a>ForgeStateUpdateError</a>.
type HardForkForgeStateUpdateError xs = OneEraForgeStateUpdateError xs


-- | Witness isomorphism between <tt>b</tt> and <tt>HardForkBlock '[b]</tt>
module Ouroboros.Consensus.HardFork.Combinator.Unary
class Isomorphic f
project :: (Isomorphic f, NoHardForks blk) => f (HardForkBlock '[blk]) -> f blk
inject :: (Isomorphic f, NoHardForks blk) => f blk -> f (HardForkBlock '[blk])
project' :: forall proxy f x y blk. (Isomorphic f, NoHardForks blk, Coercible x (f (HardForkBlock '[blk])), Coercible y (f blk)) => proxy (f blk) -> x -> y
inject' :: forall proxy f x y blk. (Isomorphic f, NoHardForks blk, Coercible x (f blk), Coercible y (f (HardForkBlock '[blk]))) => proxy (f blk) -> x -> y

-- | Project <a>Query</a>
--   
--   Not an instance of <a>Isomorphic</a> because the types change.
projQuery :: Query (HardForkBlock '[b]) result -> (forall result'. (result :~: HardForkQueryResult '[b] result') -> Query b result' -> a) -> a
projQuery' :: Query (HardForkBlock '[b]) result -> ProjHardForkQuery b result
data ProjHardForkQuery b :: Type -> Type
[ProjHardForkQuery] :: Query b result' -> ProjHardForkQuery b (HardForkQueryResult '[b] result')

-- | Inject <a>Query</a>
--   
--   Not an instance of <a>Isomorphic</a> because the types change.
injQuery :: Query b result -> Query (HardForkBlock '[b]) (HardForkQueryResult '[b] result)
projQueryResult :: HardForkQueryResult '[b] result -> result
injQueryResult :: result -> HardForkQueryResult '[b] result
projNestedCtxt :: NestedCtxt f (HardForkBlock '[blk]) a -> NestedCtxt f blk a
injNestedCtxt :: NestedCtxt f blk a -> NestedCtxt f (HardForkBlock '[blk]) a

-- | <a>Proxy</a> is a type that holds no data, but has a phantom parameter
--   of arbitrary type (or even kind). Its use is to provide type
--   information, even though there is no value available of that type (or
--   it may be too costly to create one).
--   
--   Historically, <tt><a>Proxy</a> :: <a>Proxy</a> a</tt> is a safer
--   alternative to the <tt><a>undefined</a> :: a</tt> idiom.
--   
--   <pre>
--   &gt;&gt;&gt; Proxy :: Proxy (Void, Int -&gt; Int)
--   Proxy
--   </pre>
--   
--   Proxy can even hold types of higher kinds,
--   
--   <pre>
--   &gt;&gt;&gt; Proxy :: Proxy Either
--   Proxy
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; Proxy :: Proxy Functor
--   Proxy
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; Proxy :: Proxy complicatedStructure
--   Proxy
--   </pre>
data Proxy (t :: k)
Proxy :: Proxy (t :: k)

-- | The identity type functor.
--   
--   Like <a>Identity</a>, but with a shorter name.
newtype I a
I :: a -> I a
instance Ouroboros.Consensus.HardFork.Combinator.Unary.Isomorphic ((->) a)
instance Ouroboros.Consensus.HardFork.Combinator.Unary.Isomorphic Ouroboros.Consensus.TypeFamilyWrappers.WrapIsLeader
instance Ouroboros.Consensus.HardFork.Combinator.Unary.Isomorphic Ouroboros.Consensus.TypeFamilyWrappers.WrapGenTxId
instance Ouroboros.Consensus.HardFork.Combinator.Unary.Isomorphic Data.SOP.BasicFunctors.I
instance Ouroboros.Consensus.HardFork.Combinator.Unary.Isomorphic Ouroboros.Consensus.Ledger.SupportsMempool.GenTx
instance Ouroboros.Consensus.HardFork.Combinator.Unary.Isomorphic Ouroboros.Consensus.Block.Abstract.Header
instance Ouroboros.Consensus.HardFork.Combinator.Unary.Isomorphic Ouroboros.Consensus.Block.Abstract.BlockConfig
instance Ouroboros.Consensus.HardFork.Combinator.Unary.Isomorphic Ouroboros.Consensus.Block.Abstract.CodecConfig
instance Ouroboros.Consensus.HardFork.Combinator.Unary.Isomorphic Ouroboros.Consensus.Block.Abstract.StorageConfig
instance Ouroboros.Consensus.HardFork.Combinator.Unary.Isomorphic Ouroboros.Consensus.Ledger.Basics.LedgerState
instance Ouroboros.Consensus.HardFork.Combinator.Unary.Isomorphic Ouroboros.Consensus.TypeFamilyWrappers.WrapCanBeLeader
instance Ouroboros.Consensus.HardFork.Combinator.Unary.Isomorphic Ouroboros.Consensus.TypeFamilyWrappers.WrapCannotForge
instance Ouroboros.Consensus.HardFork.Combinator.Unary.Isomorphic Ouroboros.Consensus.TypeFamilyWrappers.WrapChainDepState
instance Ouroboros.Consensus.HardFork.Combinator.Unary.Isomorphic Ouroboros.Consensus.TypeFamilyWrappers.WrapForgeStateInfo
instance Ouroboros.Consensus.HardFork.Combinator.Unary.Isomorphic Ouroboros.Consensus.TypeFamilyWrappers.WrapForgeStateUpdateError
instance Ouroboros.Consensus.HardFork.Combinator.Unary.Isomorphic Ouroboros.Consensus.TypeFamilyWrappers.WrapTipInfo
instance Ouroboros.Consensus.HardFork.Combinator.Unary.Isomorphic Ouroboros.Consensus.TypeFamilyWrappers.WrapHeaderHash
instance Ouroboros.Consensus.HardFork.Combinator.Unary.Isomorphic Ouroboros.Network.Block.ChainHash
instance Ouroboros.Consensus.HardFork.Combinator.Unary.Isomorphic Ouroboros.Consensus.Config.TopLevelConfig
instance Ouroboros.Consensus.HardFork.Combinator.Unary.Isomorphic Ouroboros.Consensus.HeaderValidation.HeaderState
instance Ouroboros.Consensus.HardFork.Combinator.Unary.Isomorphic (Ouroboros.Consensus.Ticked.Ticked Data.SOP.BasicFunctors.:.: Ouroboros.Consensus.Ledger.Basics.LedgerState)
instance Ouroboros.Consensus.HardFork.Combinator.Unary.Isomorphic Ouroboros.Consensus.Ledger.Extended.ExtLedgerState
instance Ouroboros.Consensus.HardFork.Combinator.Unary.Isomorphic Ouroboros.Consensus.HeaderValidation.AnnTip
instance GHC.Base.Functor m => Ouroboros.Consensus.HardFork.Combinator.Unary.Isomorphic (Ouroboros.Consensus.Storage.ChainDB.Init.InitChainDB m)
instance Ouroboros.Consensus.HardFork.Combinator.Unary.Isomorphic Ouroboros.Consensus.Node.ProtocolInfo.ProtocolClientInfo
instance Ouroboros.Consensus.HardFork.Combinator.Unary.Isomorphic Ouroboros.Consensus.Block.Forging.ForgeStateUpdateInfo
instance GHC.Base.Functor m => Ouroboros.Consensus.HardFork.Combinator.Unary.Isomorphic (Ouroboros.Consensus.Block.Forging.BlockForging m)
instance GHC.Base.Functor m => Ouroboros.Consensus.HardFork.Combinator.Unary.Isomorphic (Ouroboros.Consensus.Node.ProtocolInfo.ProtocolInfo m)
instance Ouroboros.Consensus.HardFork.Combinator.Unary.Isomorphic Ouroboros.Consensus.TypeFamilyWrappers.WrapApplyTxErr
instance Ouroboros.Consensus.HardFork.Combinator.Unary.Isomorphic Ouroboros.Consensus.TypeFamilyWrappers.WrapEnvelopeErr
instance Ouroboros.Consensus.HardFork.Combinator.Unary.Isomorphic Ouroboros.Consensus.TypeFamilyWrappers.WrapLedgerView
instance Ouroboros.Consensus.HardFork.Combinator.Unary.Isomorphic (Ouroboros.Consensus.Util.SomeSecond (Ouroboros.Consensus.Block.NestedContent.NestedCtxt f))
instance Ouroboros.Consensus.HardFork.Combinator.Unary.Isomorphic Ouroboros.Consensus.TypeFamilyWrappers.WrapLedgerErr
instance Ouroboros.Consensus.HardFork.Combinator.Unary.Isomorphic Ouroboros.Consensus.Storage.Serialisation.SerialisedHeader

module Ouroboros.Consensus.HardFork.Combinator.Node
instance Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs => Ouroboros.Consensus.Config.SupportsNode.ConfigSupportsNode (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs)
instance (Ouroboros.Consensus.HardFork.Combinator.Abstract.CanHardFork.CanHardFork xs, Ouroboros.Consensus.Node.NetworkProtocolVersion.SupportedNetworkProtocolVersion (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs), Ouroboros.Consensus.HardFork.Combinator.Serialisation.Common.SerialiseHFC xs) => Ouroboros.Consensus.Node.Run.RunNode (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs)

module Ouroboros.Consensus.HardFork.Combinator.Degenerate
data HardForkBlock xs
pattern DegenBlock :: forall b. NoHardForks b => b -> HardForkBlock '[b]
data family Header blk :: Type
pattern DegenHeader :: NoHardForks b => Header b -> Header (HardForkBlock '[b])

-- | Generalized transaction
--   
--   The mempool (and, accordingly, blocks) consist of "generalized
--   transactions"; this could be "proper" transactions (transferring
--   funds) but also other kinds of things such as update proposals,
--   delegations, etc.
data family GenTx blk :: Type
pattern DegenGenTx :: NoHardForks b => GenTx b -> GenTx (HardForkBlock '[b])

-- | A generalized transaction, <a>GenTx</a>, identifier.
data family TxId tx :: Type
pattern DegenGenTxId :: forall b. NoHardForks b => GenTxId b -> GenTxId (HardForkBlock '[b])
data HardForkApplyTxErr xs
pattern DegenApplyTxErr :: forall b. NoHardForks b => ApplyTxErr b -> HardForkApplyTxErr '[b]
data HardForkLedgerError xs
pattern DegenLedgerError :: forall b. NoHardForks b => LedgerError b -> HardForkLedgerError '[b]
data HardForkEnvelopeErr xs
pattern DegenOtherHeaderEnvelopeError :: forall b. NoHardForks b => OtherHeaderEnvelopeError b -> HardForkEnvelopeErr '[b]
data OneEraTipInfo xs
pattern DegenTipInfo :: forall b. NoHardForks b => TipInfo b -> OneEraTipInfo '[b]

-- | Different queries supported by the ledger, indexed by the result type.
data family Query blk :: Type -> Type
pattern DegenQuery :: () => HardForkQueryResult '[b] result ~ a => Query b result -> Query (HardForkBlock '[b]) a

-- | The <a>Either</a> type represents values with two possibilities: a
--   value of type <tt><a>Either</a> a b</tt> is either <tt><a>Left</a>
--   a</tt> or <tt><a>Right</a> b</tt>.
--   
--   The <a>Either</a> type is sometimes used to represent a value which is
--   either correct or an error; by convention, the <a>Left</a> constructor
--   is used to hold an error value and the <a>Right</a> constructor is
--   used to hold a correct value (mnemonic: "right" also means "correct").
--   
--   <h4><b>Examples</b></h4>
--   
--   The type <tt><a>Either</a> <a>String</a> <a>Int</a></tt> is the type
--   of values which can be either a <a>String</a> or an <a>Int</a>. The
--   <a>Left</a> constructor can be used only on <a>String</a>s, and the
--   <a>Right</a> constructor can be used only on <a>Int</a>s:
--   
--   <pre>
--   &gt;&gt;&gt; let s = Left "foo" :: Either String Int
--   
--   &gt;&gt;&gt; s
--   Left "foo"
--   
--   &gt;&gt;&gt; let n = Right 3 :: Either String Int
--   
--   &gt;&gt;&gt; n
--   Right 3
--   
--   &gt;&gt;&gt; :type s
--   s :: Either String Int
--   
--   &gt;&gt;&gt; :type n
--   n :: Either String Int
--   </pre>
--   
--   The <a>fmap</a> from our <a>Functor</a> instance will ignore
--   <a>Left</a> values, but will apply the supplied function to values
--   contained in a <a>Right</a>:
--   
--   <pre>
--   &gt;&gt;&gt; let s = Left "foo" :: Either String Int
--   
--   &gt;&gt;&gt; let n = Right 3 :: Either String Int
--   
--   &gt;&gt;&gt; fmap (*2) s
--   Left "foo"
--   
--   &gt;&gt;&gt; fmap (*2) n
--   Right 6
--   </pre>
--   
--   The <a>Monad</a> instance for <a>Either</a> allows us to chain
--   together multiple actions which may fail, and fail overall if any of
--   the individual steps failed. First we'll write a function that can
--   either parse an <a>Int</a> from a <a>Char</a>, or fail.
--   
--   <pre>
--   &gt;&gt;&gt; import Data.Char ( digitToInt, isDigit )
--   
--   &gt;&gt;&gt; :{
--       let parseEither :: Char -&gt; Either String Int
--           parseEither c
--             | isDigit c = Right (digitToInt c)
--             | otherwise = Left "parse error"
--   
--   &gt;&gt;&gt; :}
--   </pre>
--   
--   The following should work, since both <tt>'1'</tt> and <tt>'2'</tt>
--   can be parsed as <a>Int</a>s.
--   
--   <pre>
--   &gt;&gt;&gt; :{
--       let parseMultiple :: Either String Int
--           parseMultiple = do
--             x &lt;- parseEither '1'
--             y &lt;- parseEither '2'
--             return (x + y)
--   
--   &gt;&gt;&gt; :}
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; parseMultiple
--   Right 3
--   </pre>
--   
--   But the following should fail overall, since the first operation where
--   we attempt to parse <tt>'m'</tt> as an <a>Int</a> will fail:
--   
--   <pre>
--   &gt;&gt;&gt; :{
--       let parseMultiple :: Either String Int
--           parseMultiple = do
--             x &lt;- parseEither 'm'
--             y &lt;- parseEither '2'
--             return (x + y)
--   
--   &gt;&gt;&gt; :}
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; parseMultiple
--   Left "parse error"
--   </pre>
data Either a b
pattern DegenQueryResult :: result -> HardForkQueryResult '[b] result

-- | Static configuration required for serialisation and deserialisation of
--   types pertaining to this type of block.
--   
--   Data family instead of type family to get better type inference.
data family CodecConfig blk :: Type
pattern DegenCodecConfig :: NoHardForks b => CodecConfig b -> CodecConfig (HardForkBlock '[b])

-- | Static configuration required to work with this type of blocks
data family BlockConfig blk :: Type
pattern DegenBlockConfig :: NoHardForks b => BlockConfig b -> BlockConfig (HardForkBlock '[b])

-- | Static configuration required to run the consensus protocol
--   
--   Every method in the <a>ConsensusProtocol</a> class takes the consensus
--   configuration as a parameter, so having this as a data family rather
--   than a type family resolves most ambiguity.
--   
--   Defined out of the class so that protocols can define this type
--   without having to define the entire protocol at the same time (or
--   indeed in the same module).
data family ConsensusConfig p :: Type
pattern DegenConsensusConfig :: PartialConsensusConfig (BlockProtocol b) -> ConsensusConfig (BlockProtocol (HardForkBlock '[b]))
data HardForkLedgerConfig xs
pattern DegenLedgerConfig :: PartialLedgerConfig b -> HardForkLedgerConfig '[b]

-- | The top-level node configuration
data TopLevelConfig blk
pattern DegenTopLevelConfig :: NoHardForks b => TopLevelConfig b -> TopLevelConfig (HardForkBlock '[b])

-- | Ledger state associated with a block
data family LedgerState blk :: Type
pattern DegenLedgerState :: NoHardForks b => LedgerState b -> LedgerState (HardForkBlock '[b])


-- | The hard fork combinator
--   
--   Intended for unqualified import
module Ouroboros.Consensus.HardFork.Combinator

-- | Identity functor and monad. (a non-strict monad)
newtype Identity a
Identity :: a -> Identity a
[runIdentity] :: Identity a -> a

-- | Information about epochs
--   
--   Epochs may have different sizes at different times during the lifetime
--   of the blockchain. This information is encapsulated by
--   <a>EpochInfo</a>; it is parameterized over a monad <tt>m</tt> because
--   the information about how long each epoch is may depend on information
--   derived from the blockchain itself, and hence requires access to
--   state.
--   
--   The other functions provide some derived information from epoch sizes.
--   In the default implementation all of these functions query and update
--   an internal cache maintaining cumulative epoch sizes; for that reason,
--   all of these functions live in a monad <tt>m</tt>.
data EpochInfo (m :: Type -> Type)
EpochInfo :: (HasCallStack => EpochNo -> m EpochSize) -> (HasCallStack => EpochNo -> m SlotNo) -> (HasCallStack => SlotNo -> m EpochNo) -> EpochInfo (m :: Type -> Type)

-- | Return the size of the given epoch as a number of slots
--   
--   Note that the number of slots does <i>not</i> bound the number of
--   blocks, since the EBB and a regular block share a slot number.
[epochInfoSize_] :: EpochInfo (m :: Type -> Type) -> HasCallStack => EpochNo -> m EpochSize

-- | First slot in the specified epoch
--   
--   See also <a>epochInfoRange</a>
[epochInfoFirst_] :: EpochInfo (m :: Type -> Type) -> HasCallStack => EpochNo -> m SlotNo

-- | Epoch containing the given slot
--   
--   We should have the property that
--   
--   <pre>
--   s `inRange` epochInfoRange (epochInfoEpoch s)
--   </pre>
[epochInfoEpoch_] :: EpochInfo (m :: Type -> Type) -> HasCallStack => SlotNo -> m EpochNo

-- | Additional newtype wrapper around <a>SingleEraInfo</a>
--   
--   This is primarily useful for use in error messages: it marks which era
--   info came from the ledger, and which came from a
--   tx<i>block</i>header/etc.
newtype LedgerEraInfo blk
LedgerEraInfo :: SingleEraInfo blk -> LedgerEraInfo blk
[getLedgerEraInfo] :: LedgerEraInfo blk -> SingleEraInfo blk

-- | Information about an era (mostly for type errors)
data SingleEraInfo blk
SingleEraInfo :: !Text -> SingleEraInfo blk
[singleEraName] :: SingleEraInfo blk -> !Text

-- | " Ticked " piece of state (<tt>LedgerState</tt>, <tt>LedgerView</tt>,
--   <tt>ChainIndepState</tt>)
--   
--   Ticking refers to the passage of time (the ticking of the clock). When
--   a piece of state is marked as ticked, it means that time-related
--   changes have been applied to the state (or forecast).
--   
--   Some examples of time related changes:
--   
--   <ul>
--   <li>Scheduled delegations might have been applied in Byron</li>
--   <li>New leader schedule computed for Shelley</li>
--   <li>Transition from Byron to Shelley activated in the hard fork
--   combinator.</li>
--   <li>Nonces switched out at the start of a new epoch.</li>
--   </ul>
data family Ticked st :: Type

-- | Context identifying what kind of block we have
--   
--   In almost all places we will use <a>NestedCtxt</a> rather than
--   <a>NestedCtxt_</a>.
data family NestedCtxt_ blk :: (Type -> Type) -> (Type -> Type)
data family Header blk :: Type

-- | Config needed for the <a>NodeInitStorage</a> class. Defined here to
--   avoid circular dependencies.
data family StorageConfig blk :: Type

-- | Static configuration required for serialisation and deserialisation of
--   types pertaining to this type of block.
--   
--   Data family instead of type family to get better type inference.
data family CodecConfig blk :: Type

-- | Static configuration required to work with this type of blocks
data family BlockConfig blk :: Type

-- | Static configuration required to run the consensus protocol
--   
--   Every method in the <a>ConsensusProtocol</a> class takes the consensus
--   configuration as a parameter, so having this as a data family rather
--   than a type family resolves most ambiguity.
--   
--   Defined out of the class so that protocols can define this type
--   without having to define the entire protocol at the same time (or
--   indeed in the same module).
data family ConsensusConfig p :: Type

-- | Ledger state associated with a block
data family LedgerState blk :: Type

-- | A generalized transaction, <a>GenTx</a>, identifier.
data family TxId tx :: Type

-- | Generalized transaction
--   
--   The mempool (and, accordingly, blocks) consist of "generalized
--   transactions"; this could be "proper" transactions (transferring
--   funds) but also other kinds of things such as update proposals,
--   delegations, etc.
data family GenTx blk :: Type
newtype WrapPartialConsensusConfig blk
WrapPartialConsensusConfig :: PartialConsensusConfig (BlockProtocol blk) -> WrapPartialConsensusConfig blk
[unwrapPartialConsensusConfig] :: WrapPartialConsensusConfig blk -> PartialConsensusConfig (BlockProtocol blk)
newtype WrapPartialLedgerConfig blk
WrapPartialLedgerConfig :: PartialLedgerConfig blk -> WrapPartialLedgerConfig blk
[unwrapPartialLedgerConfig] :: WrapPartialLedgerConfig blk -> PartialLedgerConfig blk

-- | Partial ledger config
class (UpdateLedger blk, NoThunks (PartialLedgerConfig blk)) => HasPartialLedgerConfig blk where {
    type family PartialLedgerConfig blk :: Type;
    type PartialLedgerConfig blk = LedgerConfig blk;
}

-- | Construct <a>LedgerConfig</a> from <tt>PartialLedgerCfg</tt>
--   
--   NOTE: The <a>EpochInfo</a> provided will have limited range, any
--   attempt to look past its horizon will result in a pure
--   <tt>PastHorizonException</tt>. The horizon is determined by the tip of
--   the ledger <i>state</i> (not view) from which the <a>EpochInfo</a> is
--   derived.
--   
--   TODO: This should not be Identity; see
--   <a>https://github.com/input-output-hk/ouroboros-network/issues/2126</a>
completeLedgerConfig :: HasPartialLedgerConfig blk => proxy blk -> EpochInfo Identity -> PartialLedgerConfig blk -> LedgerConfig blk

-- | Construct <a>LedgerConfig</a> from <tt>PartialLedgerCfg</tt>
--   
--   NOTE: The <a>EpochInfo</a> provided will have limited range, any
--   attempt to look past its horizon will result in a pure
--   <tt>PastHorizonException</tt>. The horizon is determined by the tip of
--   the ledger <i>state</i> (not view) from which the <a>EpochInfo</a> is
--   derived.
--   
--   TODO: This should not be Identity; see
--   <a>https://github.com/input-output-hk/ouroboros-network/issues/2126</a>
completeLedgerConfig :: (HasPartialLedgerConfig blk, PartialLedgerConfig blk ~ LedgerConfig blk) => proxy blk -> EpochInfo Identity -> PartialLedgerConfig blk -> LedgerConfig blk

-- | Partial consensus config
class (ConsensusProtocol p, NoThunks (PartialConsensusConfig p)) => HasPartialConsensusConfig p where {
    type family PartialConsensusConfig p :: Type;
    type PartialConsensusConfig p = ConsensusConfig p;
}

-- | Construct <a>ConsensusConfig</a> from <a>PartialConsensusConfig</a>
--   
--   See comments for <a>completeLedgerConfig</a> for some details about
--   the <a>EpochInfo</a>.
completeConsensusConfig :: HasPartialConsensusConfig p => proxy p -> EpochInfo Identity -> PartialConsensusConfig p -> ConsensusConfig p

-- | Construct <a>ConsensusConfig</a> from <a>PartialConsensusConfig</a>
--   
--   See comments for <a>completeLedgerConfig</a> for some details about
--   the <a>EpochInfo</a>.
completeConsensusConfig :: (HasPartialConsensusConfig p, PartialConsensusConfig p ~ ConsensusConfig p) => proxy p -> EpochInfo Identity -> PartialConsensusConfig p -> ConsensusConfig p

-- | The <a>ChainSelConfig</a> must be derivable from the partial config
partialChainSelConfig :: HasPartialConsensusConfig p => proxy p -> PartialConsensusConfig p -> ChainSelConfig p

-- | The <a>ChainSelConfig</a> must be derivable from the partial config
partialChainSelConfig :: (HasPartialConsensusConfig p, PartialConsensusConfig p ~ ConsensusConfig p) => proxy p -> PartialConsensusConfig p -> ChainSelConfig p

-- | Different queries supported by the ledger, indexed by the result type.
data family Query blk :: Type -> Type
class IsNonEmpty xs
isNonEmpty :: IsNonEmpty xs => proxy xs -> ProofNonEmpty xs
data ProofNonEmpty :: [Type] -> Type
[ProofNonEmpty] :: Proxy x -> Proxy xs -> ProofNonEmpty (x : xs)

-- | We have an <tt>f x y</tt> for each pair <tt>(x, y)</tt> of successive
--   list elements
data InPairs (f :: k -> k -> Type) (xs :: [k])
[PNil] :: InPairs f '[x]
[PCons] :: f x y -> InPairs f (y : zs) -> InPairs f (x : (y : zs))

-- | Telescope
--   
--   A telescope is an extension of an <a>NS</a>, where every time we "go
--   right" in the sum we have an additional value.
--   
--   Blockchain intuition: think of <tt>g</tt> as representing some kind of
--   past state, and <tt>f</tt> some kind of current state. Then depending
--   on how many hard fork transitions we have had, we might either have,
--   say
--   
--   <pre>
--   TZ currentByronState
--   TS pastByronState $ TZ currentShelleyState
--   TS pastByronState $ TS pastShelleyState $ TZ currentGoguenState
--   </pre>
--   
--   The <a>Telescope</a> API mostly follows <tt>sop-core</tt> conventions,
--   supporting functor (<a>hmap</a>, <a>hcmap</a>), applicative
--   (<a>hap</a>, <a>hpure</a>), foldable (<a>hcollapse</a>) and
--   traversable (<a>hsequence'</a>). However, since <a>Telescope</a> is a
--   bi-functor, it cannot reuse the <tt>sop-core</tt> classes. The naming
--   scheme of the functions is adopted from <tt>sop-core</tt> though; for
--   example:
--   
--   <pre>
--   bi h (c) zipWith
--   |  |  |    |
--   |  |  |    \ zipWith: the name from base
--   |  |  |
--   |  |  \ constrained: version of the function with a constraint parameter
--   |  |
--   |  \ higher order: 'Telescope' (like 'NS'/'NP') is a /higher order/ functor
--   |
--   \ bifunctor: 'Telescope' (unlike 'NS'/'NP') is a higher order /bifunctor/
--   </pre>
--   
--   In addition to the standard SOP operators, the new operators that make
--   a <a>Telescope</a> a telescope are <a>extend</a>, <a>retract</a> and
--   <a>align</a>; see their documentation for details.
data Telescope (g :: k -> Type) (f :: k -> Type) (xs :: [k])
[TZ] :: !f x -> Telescope g f (x : xs)
[TS] :: !g x -> !Telescope g f xs -> Telescope g f (x : xs)
data Mismatch :: (k -> Type) -> (k -> Type) -> [k] -> Type
[ML] :: f x -> NS g xs -> Mismatch f g (x : xs)
[MR] :: NS f xs -> g x -> Mismatch f g (x : xs)
[MS] :: Mismatch f g xs -> Mismatch f g (x : xs)

-- | Generic hard fork state
--   
--   This is used both for the consensus state and the ledger state.
newtype HardForkState f xs
HardForkState :: Telescope (K Past) (Current f) xs -> HardForkState f xs
[getHardForkState] :: HardForkState f xs -> Telescope (K Past) (Current f) xs
data EraTranslation xs
EraTranslation :: InPairs (RequiringBoth WrapLedgerConfig (Translate LedgerState)) xs -> InPairs (RequiringBoth WrapConsensusConfig (Translate WrapChainDepState)) xs -> InPairs (RequiringBoth WrapLedgerConfig (TranslateForecast LedgerState WrapLedgerView)) xs -> EraTranslation xs
[translateLedgerState] :: EraTranslation xs -> InPairs (RequiringBoth WrapLedgerConfig (Translate LedgerState)) xs
[translateChainDepState] :: EraTranslation xs -> InPairs (RequiringBoth WrapConsensusConfig (Translate WrapChainDepState)) xs
[translateLedgerView] :: EraTranslation xs -> InPairs (RequiringBoth WrapLedgerConfig (TranslateForecast LedgerState WrapLedgerView)) xs
trivialEraTranslation :: EraTranslation '[blk]
data InjectTx blk blk'
InjectTx :: (GenTx blk -> Maybe (GenTx blk')) -> InjectTx blk blk'
[injectTxWith] :: InjectTx blk blk' -> GenTx blk -> Maybe (GenTx blk')
cannotInjectTx :: InjectTx blk blk'
newtype EraIndex xs
EraIndex :: NS (K ()) xs -> EraIndex xs
[getEraIndex] :: EraIndex xs -> NS (K ()) xs

-- | Blocks from which we can assemble a hard fork
class (LedgerSupportsProtocol blk, InspectLedger blk, LedgerSupportsMempool blk, HasTxId (GenTx blk), QueryLedger blk, HasPartialConsensusConfig (BlockProtocol blk), HasPartialLedgerConfig blk, ConvertRawHash blk, ReconstructNestedCtxt Header blk, CommonProtocolParams blk, ConfigSupportsNode blk, NodeInitStorage blk, Eq (GenTx blk), Eq (ApplyTxErr blk), Show blk, Show (Header blk), Show (CannotForge blk), Show (ForgeStateInfo blk), Show (ForgeStateUpdateError blk)) => SingleEraBlock blk

-- | Era transition
--   
--   This should only report the transition point once it is stable
--   (rollback cannot affect it anymore).
--   
--   Since we need this to construct the <tt>HardForkSummary</tt> (and
--   hence the <a>EpochInfo</a>), this takes the <i>partial</i> config, not
--   the full config (or we'd end up with a catch-22).
singleEraTransition :: SingleEraBlock blk => PartialLedgerConfig blk -> EraParams -> Bound -> LedgerState blk -> Maybe EpochNo

-- | Era information (for use in error messages)
singleEraInfo :: SingleEraBlock blk => proxy blk -> SingleEraInfo blk
proxySingle :: Proxy SingleEraBlock
singleEraTransition' :: SingleEraBlock blk => WrapPartialLedgerConfig blk -> EraParams -> Bound -> LedgerState blk -> Maybe EpochNo
eraIndexEmpty :: EraIndex '[] -> Void
eraIndexFromNS :: SListI xs => NS f xs -> EraIndex xs
eraIndexZero :: EraIndex (x : xs)
eraIndexSucc :: EraIndex xs -> EraIndex (x : xs)
eraIndexToInt :: EraIndex xs -> Int
initHardForkState :: f x -> HardForkState f (x : xs)
data WithBlockNo (f :: k -> Type) (a :: k)
WithBlockNo :: BlockNo -> f a -> WithBlockNo (f :: k -> Type) (a :: k)
[getBlockNo] :: WithBlockNo (f :: k -> Type) (a :: k) -> BlockNo
[dropBlockNo] :: WithBlockNo (f :: k -> Type) (a :: k) -> f a
data AcrossEraSelection :: Type -> Type -> Type

-- | Just compare block numbers
--   
--   This is a useful default when two eras run totally different consensus
--   protocols, and we just want to choose the longer chain.
[CompareBlockNo] :: AcrossEraSelection x y

-- | Two eras running the same protocol
--   
--   In this case, we can just call <tt>compareCandidates</tt> even across
--   eras. (The <a>ChainSelConfig</a> must also be the same in both eras:
--   we assert this at the value level.)
--   
--   NOTE: We require that the eras have the same <i>protocol</i>, not
--   merely the same <a>SelectView</a>, because if we have two eras with
--   different protocols that happen to use the same <a>SelectView</a> but
--   a different way to compare chains, it's not clear how to do cross-era
--   selection.
[SelectSameProtocol] :: BlockProtocol x ~ BlockProtocol y => AcrossEraSelection x y

-- | Custom chain selection
--   
--   This is the most general form, and allows to override chain selection
--   for the specific combination of two eras with a custom comparison
--   function.
[CustomChainSel] :: (ChainSelConfig (BlockProtocol x) -> ChainSelConfig (BlockProtocol y) -> SelectView (BlockProtocol x) -> SelectView (BlockProtocol y) -> Ordering) -> AcrossEraSelection x y
acrossEraSelection :: All SingleEraBlock xs => NP WrapChainSelConfig xs -> Tails AcrossEraSelection xs -> WithBlockNo (NS WrapSelectView) xs -> WithBlockNo (NS WrapSelectView) xs -> Ordering
mapWithBlockNo :: (f x -> g y) -> WithBlockNo f x -> WithBlockNo g y
class SingleEraBlock blk => NoHardForks blk

-- | Extract <a>EraParams</a> from the top-level config
--   
--   The HFC itself does not care about this, as it must be given the full
--   shape across <i>all</i> eras.
getEraParams :: NoHardForks blk => TopLevelConfig blk -> EraParams

-- | Construct partial consensus config from full consensus config
--   
--   NOTE: This is basically just losing <a>EpochInfo</a>, but that is
--   constant anyway when we are dealing with a single era.
toPartialConsensusConfig :: NoHardForks blk => proxy blk -> ConsensusConfig (BlockProtocol blk) -> PartialConsensusConfig (BlockProtocol blk)

-- | Construct partial ledger config from full ledger config
--   
--   See also <a>toPartialConsensusConfig</a>
toPartialLedgerConfig :: NoHardForks blk => proxy blk -> LedgerConfig blk -> PartialLedgerConfig blk
noHardForksEpochInfo :: NoHardForks blk => TopLevelConfig blk -> EpochInfo Identity
class (All SingleEraBlock xs, Typeable xs, IsNonEmpty xs) => CanHardFork xs
hardForkEraTranslation :: CanHardFork xs => EraTranslation xs
hardForkChainSel :: CanHardFork xs => Tails AcrossEraSelection xs
hardForkInjectTxs :: CanHardFork xs => InPairs (RequiringBoth WrapLedgerConfig InjectTx) xs
type HardForkLedgerView = HardForkLedgerView_ WrapLedgerView
data HardForkLedgerView_ f xs
HardForkLedgerView :: !TransitionInfo -> !HardForkState f xs -> HardForkLedgerView_ f xs

-- | Information about the transition to the next era, if known
[hardForkLedgerViewTransition] :: HardForkLedgerView_ f xs -> !TransitionInfo

-- | The underlying ledger view
[hardForkLedgerViewPerEra] :: HardForkLedgerView_ f xs -> !HardForkState f xs
newtype MismatchEraInfo xs
MismatchEraInfo :: Mismatch SingleEraInfo LedgerEraInfo xs -> MismatchEraInfo xs

-- | Era mismatch
--   
--   We have an era mismatch between the era of a
--   block<i>header</i>tx/query and the era of the current ledger.
[getMismatchEraInfo] :: MismatchEraInfo xs -> Mismatch SingleEraInfo LedgerEraInfo xs

-- | The hash for an era
--   
--   This type is special: we don't use an NS here, because the hash by
--   itself should not allow us to differentiate between eras. If it did,
--   the <i>size</i> of the hash would necessarily have to increase, and
--   that leads to trouble. So, the type parameter <tt>xs</tt> here is
--   merely a phantom one, and we just store the underlying raw hash.
newtype OneEraHash (xs :: [k])
OneEraHash :: ShortByteString -> OneEraHash (xs :: [k])
[getOneEraHash] :: OneEraHash (xs :: [k]) -> ShortByteString
newtype OneEraTipInfo xs
OneEraTipInfo :: NS WrapTipInfo xs -> OneEraTipInfo xs
[getOneEraTipInfo] :: OneEraTipInfo xs -> NS WrapTipInfo xs
newtype OneEraHeader xs
OneEraHeader :: NS Header xs -> OneEraHeader xs
[getOneEraHeader] :: OneEraHeader xs -> NS Header xs
newtype OneEraGenTxId xs
OneEraGenTxId :: NS WrapGenTxId xs -> OneEraGenTxId xs
[getOneEraGenTxId] :: OneEraGenTxId xs -> NS WrapGenTxId xs
newtype OneEraGenTx xs
OneEraGenTx :: NS GenTx xs -> OneEraGenTx xs
[getOneEraGenTx] :: OneEraGenTx xs -> NS GenTx xs
newtype OneEraBlock xs
OneEraBlock :: NS I xs -> OneEraBlock xs
[getOneEraBlock] :: OneEraBlock xs -> NS I xs
newtype OneEraApplyTxErr xs
OneEraApplyTxErr :: NS WrapApplyTxErr xs -> OneEraApplyTxErr xs
[getOneEraApplyTxErr] :: OneEraApplyTxErr xs -> NS WrapApplyTxErr xs
newtype PerEraStorageConfig xs
PerEraStorageConfig :: NP StorageConfig xs -> PerEraStorageConfig xs
[getPerEraStorageConfig] :: PerEraStorageConfig xs -> NP StorageConfig xs
newtype PerEraLedgerConfig xs
PerEraLedgerConfig :: NP WrapPartialLedgerConfig xs -> PerEraLedgerConfig xs
[getPerEraLedgerConfig] :: PerEraLedgerConfig xs -> NP WrapPartialLedgerConfig xs
newtype PerEraConsensusConfig xs
PerEraConsensusConfig :: NP WrapPartialConsensusConfig xs -> PerEraConsensusConfig xs
[getPerEraConsensusConfig] :: PerEraConsensusConfig xs -> NP WrapPartialConsensusConfig xs
newtype PerEraCodecConfig xs
PerEraCodecConfig :: NP CodecConfig xs -> PerEraCodecConfig xs
[getPerEraCodecConfig] :: PerEraCodecConfig xs -> NP CodecConfig xs
newtype PerEraBlockConfig xs
PerEraBlockConfig :: NP BlockConfig xs -> PerEraBlockConfig xs
[getPerEraBlockConfig] :: PerEraBlockConfig xs -> NP BlockConfig xs
data HardForkLedgerConfig xs
HardForkLedgerConfig :: !Shape xs -> !PerEraLedgerConfig xs -> HardForkLedgerConfig xs
[hardForkLedgerConfigShape] :: HardForkLedgerConfig xs -> !Shape xs
[hardForkLedgerConfigPerEra] :: HardForkLedgerConfig xs -> !PerEraLedgerConfig xs
newtype HardForkBlock xs
HardForkBlock :: OneEraBlock xs -> HardForkBlock xs
[getHardForkBlock] :: HardForkBlock xs -> OneEraBlock xs
data HardForkProtocol (xs :: [Type])
completeLedgerConfig' :: forall blk. HasPartialLedgerConfig blk => EpochInfo Identity -> WrapPartialLedgerConfig blk -> LedgerConfig blk
completeLedgerConfig'' :: forall blk. HasPartialLedgerConfig blk => EpochInfo Identity -> WrapPartialLedgerConfig blk -> WrapLedgerConfig blk
completeConsensusConfig' :: forall blk. HasPartialConsensusConfig (BlockProtocol blk) => EpochInfo Identity -> WrapPartialConsensusConfig blk -> ConsensusConfig (BlockProtocol blk)
completeConsensusConfig'' :: forall blk. HasPartialConsensusConfig (BlockProtocol blk) => EpochInfo Identity -> WrapPartialConsensusConfig blk -> WrapConsensusConfig blk
distribLedgerConfig :: CanHardFork xs => EpochInfo Identity -> LedgerConfig (HardForkBlock xs) -> NP WrapLedgerConfig xs
distribTopLevelConfig :: All SingleEraBlock xs => EpochInfo Identity -> TopLevelConfig (HardForkBlock xs) -> NP TopLevelConfig xs
distribAnnTip :: SListI xs => AnnTip (HardForkBlock xs) -> NS AnnTip xs
undistribAnnTip :: SListI xs => NS AnnTip xs -> AnnTip (HardForkBlock xs)
data HardForkValidationErr xs

-- | Validation error from one of the eras
HardForkValidationErrFromEra :: OneEraValidationErr xs -> HardForkValidationErr xs

-- | We tried to apply a block from the wrong era
HardForkValidationErrWrongEra :: MismatchEraInfo xs -> HardForkValidationErr xs

-- | We have one or more <a>BlockForging</a>s, and thus <a>CanBeLeader</a>
--   proofs, for each era in which we can forge blocks.
type HardForkCanBeLeader xs = OneEraCanBeLeader xs

-- | We are a leader if we have a proof from one of the eras
type HardForkIsLeader xs = OneEraIsLeader xs
type HardForkChainDepState xs = HardForkState WrapChainDepState xs
data HardForkLedgerUpdate xs
HardForkUpdateInEra :: OneEraLedgerUpdate xs -> HardForkLedgerUpdate xs

-- | Hard fork transition got confirmed
HardForkUpdateTransitionConfirmed :: EraIndex xs -> EraIndex xs -> EpochNo -> HardForkLedgerUpdate xs

-- | Hard fork transition happened
--   
--   We record the <a>EpochNo</a> at the start of the era after the
--   transition
HardForkUpdateTransitionDone :: EraIndex xs -> EraIndex xs -> EpochNo -> HardForkLedgerUpdate xs

-- | The hard fork transition rolled back
HardForkUpdateTransitionRolledBack :: EraIndex xs -> EraIndex xs -> HardForkLedgerUpdate xs
data HardForkLedgerWarning xs

-- | Warning from the underlying era
HardForkWarningInEra :: OneEraLedgerWarning xs -> HardForkLedgerWarning xs

-- | The transition to the next era does not match the <a>EraParams</a>
--   
--   The <a>EraParams</a> can specify a lower bound on when the transition
--   to the next era will happen. If the actual transition, when confirmed,
--   is <i>before</i> this lower bound, the node is misconfigured and will
--   likely not work correctly. This should be taken care of as soon as
--   possible (before the transition happens).
HardForkWarningTransitionMismatch :: EraIndex xs -> EraParams -> EpochNo -> HardForkLedgerWarning xs

-- | Transition in the final era
--   
--   The final era should never confirm any transitions. For clarity, we
--   also record the index of that final era.
HardForkWarningTransitionInFinalEra :: EraIndex xs -> EpochNo -> HardForkLedgerWarning xs

-- | An already-confirmed transition got un-confirmed
HardForkWarningTransitionUnconfirmed :: EraIndex xs -> HardForkLedgerWarning xs

-- | An already-confirmed transition got changed
--   
--   We record the indices of the era we are transitioning from and to, as
--   well as the old and new <a>EpochNo</a> of that transition, in that
--   order.
HardForkWarningTransitionReconfirmed :: EraIndex xs -> EraIndex xs -> EpochNo -> EpochNo -> HardForkLedgerWarning xs

-- | Forecast annotated with details about the ledger it was derived from
data AnnForecast state view blk
AnnForecast :: Forecast (view blk) -> state blk -> WithOrigin SlotNo -> Maybe Bound -> AnnForecast state view blk
[annForecast] :: AnnForecast state view blk -> Forecast (view blk)
[annForecastState] :: AnnForecast state view blk -> state blk
[annForecastTip] :: AnnForecast state view blk -> WithOrigin SlotNo
[annForecastEnd] :: AnnForecast state view blk -> Maybe Bound
data HardForkEnvelopeErr xs

-- | Validation error from one of the eras
HardForkEnvelopeErrFromEra :: OneEraEnvelopeErr xs -> HardForkEnvelopeErr xs

-- | We tried to apply a block from the wrong era
HardForkEnvelopeErrWrongEra :: MismatchEraInfo xs -> HardForkEnvelopeErr xs
data HardForkLedgerError xs

-- | Validation error from one of the eras
HardForkLedgerErrorFromEra :: OneEraLedgerError xs -> HardForkLedgerError xs

-- | We tried to apply a block from the wrong era
HardForkLedgerErrorWrongEra :: MismatchEraInfo xs -> HardForkLedgerError xs

-- | Change a telescope of a forecast into a forecast of a telescope
mkHardForkForecast :: forall state view xs. SListI xs => InPairs (TranslateForecast state view) xs -> HardForkState (AnnForecast state view) xs -> Forecast (HardForkLedgerView_ view xs)
data HardForkApplyTxErr xs

-- | Validation error from one of the eras
HardForkApplyTxErrFromEra :: !OneEraApplyTxErr xs -> HardForkApplyTxErr xs

-- | We tried to apply a block from the wrong era
HardForkApplyTxErrWrongEra :: !MismatchEraInfo xs -> HardForkApplyTxErr xs
hardForkApplyTxErrToEither :: HardForkApplyTxErr xs -> Either (MismatchEraInfo xs) (OneEraApplyTxErr xs)
hardForkApplyTxErrFromEither :: Either (MismatchEraInfo xs) (OneEraApplyTxErr xs) -> HardForkApplyTxErr xs
data QueryHardFork xs result
[GetInterpreter] :: QueryHardFork xs (Interpreter xs)
[GetCurrentEra] :: QueryHardFork xs (EraIndex xs)
data QueryAnytime result
[GetEraStart] :: QueryAnytime (Maybe Bound)
data QueryIfCurrent :: [Type] -> Type -> Type
[QZ] :: Query x result -> QueryIfCurrent (x : xs) result
[QS] :: QueryIfCurrent xs result -> QueryIfCurrent (x : xs) result
type HardForkQueryResult xs = Either (MismatchEraInfo xs)
getHardForkQuery :: Query (HardForkBlock xs) result -> (forall result'. (result :~: HardForkQueryResult xs result') -> QueryIfCurrent xs result' -> r) -> (forall x' xs'. (xs :~: (x' : xs')) -> ProofNonEmpty xs' -> QueryAnytime result -> EraIndex xs -> r) -> (forall x' xs'. (xs :~: (x' : xs')) -> ProofNonEmpty xs' -> QueryHardFork xs result -> r) -> r
encodeQueryAnytimeResult :: QueryAnytime result -> result -> Encoding
decodeQueryAnytimeResult :: QueryAnytime result -> forall s. Decoder s result
encodeQueryHardForkResult :: SListI xs => QueryHardFork xs result -> result -> Encoding
decodeQueryHardForkResult :: SListI xs => QueryHardFork xs result -> forall s. Decoder s result
hardForkQueryInfo :: All SingleEraBlock xs => QueryIfCurrent xs result -> NS SingleEraInfo xs

-- | For each era in which we want to forge blocks, we have a
--   <a>BlockForging</a>, and thus <a>ForgeStateInfo</a>.
type HardForkForgeStateInfo xs = OneEraForgeStateInfo xs
hardForkBlockForging :: forall m xs. (CanHardFork xs, Monad m) => NS (BlockForging m) xs -> BlockForging m (HardForkBlock xs)


-- | Condense instances
--   
--   These are for the benefit of integration and tests. We do not rely on
--   them within consensus.
--   
--   NOTE: No guarantees are made about what these condense instances look
--   like.
module Ouroboros.Consensus.HardFork.Combinator.Condense
class (Condense blk, Condense (Header blk), Condense (GenTx blk), Condense (GenTxId blk)) => CondenseConstraints blk
instance Data.SOP.Constraint.All Ouroboros.Consensus.HardFork.Combinator.Condense.CondenseConstraints xs => Ouroboros.Consensus.Util.Condense.Condense (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs)
instance Data.SOP.Constraint.All Ouroboros.Consensus.HardFork.Combinator.Condense.CondenseConstraints xs => Ouroboros.Consensus.Util.Condense.Condense (Ouroboros.Consensus.Block.Abstract.Header (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs))
instance Data.SOP.Constraint.All Ouroboros.Consensus.HardFork.Combinator.Condense.CondenseConstraints xs => Ouroboros.Consensus.Util.Condense.Condense (Ouroboros.Consensus.Ledger.SupportsMempool.GenTx (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs))
instance Data.SOP.Constraint.All Ouroboros.Consensus.HardFork.Combinator.Condense.CondenseConstraints xs => Ouroboros.Consensus.Util.Condense.Condense (Ouroboros.Consensus.Ledger.SupportsMempool.TxId (Ouroboros.Consensus.Ledger.SupportsMempool.GenTx (Ouroboros.Consensus.HardFork.Combinator.Basics.HardForkBlock xs)))
instance Ouroboros.Consensus.Util.Condense.Condense a => Ouroboros.Consensus.Util.Condense.Condense (Data.SOP.BasicFunctors.I a)
instance Ouroboros.Consensus.Util.Condense.Condense (Ouroboros.Consensus.Ledger.SupportsMempool.GenTxId blk) => Ouroboros.Consensus.Util.Condense.Condense (Ouroboros.Consensus.TypeFamilyWrappers.WrapGenTxId blk)

module Ouroboros.Consensus.Util.TraceSize

-- | Generic helper to trace a value and its size
traceSize :: MonadIO m => Tracer m (a, Either CountFailure Word64) -> Tracer m a
data LedgerDbSize blk
LedgerDbSize :: Point blk -> Either CountFailure Word64 -> Either CountFailure Word64 -> LedgerDbSize blk

-- | The tip of the ledger DB
[ledgerDbTip] :: LedgerDbSize blk -> Point blk

-- | Size of the ledger at the tip of the DB
[ledgerDbSizeTip] :: LedgerDbSize blk -> Either CountFailure Word64

-- | Size of the entire (in-memory) ledger DB
[ledgerDbSizeTotal] :: LedgerDbSize blk -> Either CountFailure Word64

-- | Trace the size of the ledger
--   
--   Only traces slots for which the predicate results true (genesis will
--   be considered to be slot 0).
traceLedgerDbSize :: MonadIO m => (Word64 -> Bool) -> Tracer m (LedgerDbSize blk) -> Tracer m (LedgerDB l (RealPoint blk))
instance Ouroboros.Network.Block.StandardHash blk => GHC.Show.Show (Ouroboros.Consensus.Util.TraceSize.LedgerDbSize blk)

module Ouroboros.Consensus.Util.Versioned
data Versioned a
Versioned :: !VersionNumber -> !a -> Versioned a
[versionNumber] :: Versioned a -> !VersionNumber
[versioned] :: Versioned a -> !a
data VersionNumber
data VersionError

-- | We cannot deserialise the version of the data with the given
--   <a>VersionNumber</a> because its data format is incompatible.
--   
--   For example, the given format lacks data that was added in later
--   version that cannot be reconstructed from scratch.
IncompatibleVersion :: VersionNumber -> String -> VersionError

-- | The given <a>VersionNumber</a> is unknown and thus not supported.
UnknownVersion :: VersionNumber -> VersionError

-- | A migration from the given <a>VersionNumber</a> failed. See
--   <a>Migrate</a>.
MigrationFailed :: VersionNumber -> String -> VersionError

-- | How to decode a version of a format.
data VersionDecoder a

-- | This version is incompatible, fail with <a>IncompatibleVersion</a> and
--   the given message.
[Incompatible] :: String -> VersionDecoder a

-- | Decode the version using the given <a>Decoder</a>.
[Decode] :: (forall s. Decoder s a) -> VersionDecoder a

-- | Decode an other format (<tt>from</tt>) and migrate from that. When
--   migration fails, the version decoder will fail with
--   <tt>MigrationFailed</tt>.
[Migrate] :: VersionDecoder from -> (from -> Either String to) -> VersionDecoder to
encodeVersioned :: (a -> Encoding) -> Versioned a -> Encoding

-- | Given a <a>VersionNumber</a> and the encoding of an <tt>a</tt>, encode
--   the corresponding <tt><a>Versioned</a> a</tt>. Use
--   <a>decodeVersion</a> to decode it.
encodeVersion :: VersionNumber -> Encoding -> Encoding
decodeVersioned :: [(VersionNumber, VersionDecoder a)] -> forall s. Decoder s (Versioned a)

-- | Decode a <i>versioned</i> <tt>a</tt> (encoded using
--   <a>encodeVersion</a> or <a>encodeVersioned</a>).
--   
--   The corresponding <a>VersionDecoder</a> for the deserialised
--   <a>VersionNumber</a> is looked up in the given list. The first match
--   is used (using the semantics of <a>lookup</a>). When no match is
--   found, a decoder that fails with <a>UnknownVersion</a> is returned.
decodeVersion :: [(VersionNumber, VersionDecoder a)] -> forall s. Decoder s a
instance GHC.Show.Show Ouroboros.Consensus.Util.Versioned.VersionNumber
instance GHC.Num.Num Ouroboros.Consensus.Util.Versioned.VersionNumber
instance GHC.Classes.Ord Ouroboros.Consensus.Util.Versioned.VersionNumber
instance GHC.Classes.Eq Ouroboros.Consensus.Util.Versioned.VersionNumber
instance GHC.Show.Show a => GHC.Show.Show (Ouroboros.Consensus.Util.Versioned.Versioned a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Ouroboros.Consensus.Util.Versioned.Versioned a)
instance GHC.Exception.Type.Exception Ouroboros.Consensus.Util.Versioned.VersionError
instance GHC.Show.Show Ouroboros.Consensus.Util.Versioned.VersionError
instance Codec.Serialise.Class.Serialise Ouroboros.Consensus.Util.Versioned.VersionNumber


-- | PBFT chain state
--   
--   Intended for qualified import.
module Ouroboros.Consensus.Protocol.PBFT.State

-- | PBFT state
--   
--   For a window size of <tt>n</tt>, the PBFT chain state is a sequence of
--   signatures over the last <tt>n</tt> slots
--   
--   <pre>
--   +-------------------------------------------+
--   |                signatures                 |
--   +-------------------------------------------+
--   
--   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
--                    window of n
--   </pre>
--   
--   We need the last <tt>n</tt> signatures to verify that no single key
--   has signed more than a certain threshold percentage of the slots.
--   
--   When near genesis, we will have less than <tt>n</tt> signatures in the
--   history.
--   
--   The window size itself is pretty much arbitrary and will be fixed by a
--   particular blockchain specification (e.g., Byron).
data PBftState c
PBftState :: !StrictSeq (PBftSigner c) -> !Map (PBftVerKeyHash c) Word64 -> PBftState c

-- | Signatures in the window
--   
--   We should have precisely <tt>n</tt> signatures in the window, unless
--   we are near genesis.
--   
--   INVARIANT Empty if and only if we are exactly at genesis.
[inWindow] :: PBftState c -> !StrictSeq (PBftSigner c)

-- | Cached counts of the signatures in the window
[counts] :: PBftState c -> !Map (PBftVerKeyHash c) Word64

-- | " Ticked " piece of state (<tt>LedgerState</tt>, <tt>LedgerView</tt>,
--   <tt>ChainIndepState</tt>)
--   
--   Ticking refers to the passage of time (the ticking of the clock). When
--   a piece of state is marked as ticked, it means that time-related
--   changes have been applied to the state (or forecast).
--   
--   Some examples of time related changes:
--   
--   <ul>
--   <li>Scheduled delegations might have been applied in Byron</li>
--   <li>New leader schedule computed for Shelley</li>
--   <li>Transition from Byron to Shelley activated in the hard fork
--   combinator.</li>
--   <li>Nonces switched out at the start of a new epoch.</li>
--   </ul>
data family Ticked st :: Type

-- | Window size
--   
--   See <a>PBftState</a> itself for a detailed discussion on the window
--   size versus the number of signatures.
newtype WindowSize
WindowSize :: Word64 -> WindowSize
[getWindowSize] :: WindowSize -> Word64

-- | Slot and corresponding genesis key
data PBftSigner c
PBftSigner :: !SlotNo -> !PBftVerKeyHash c -> PBftSigner c
[pbftSignerSlotNo] :: PBftSigner c -> !SlotNo
[pbftSignerGenesisKey] :: PBftSigner c -> !PBftVerKeyHash c

-- | Empty PBFT chain state
--   
--   In other words, the PBFT chain state corresponding to genesis.
empty :: PBftState c

-- | Append new signature
--   
--   Drops the oldest signature, provided we have reached the required
--   number.
append :: forall c. PBftCrypto c => WindowSize -> PBftSigner c -> PBftState c -> PBftState c

-- | Number of signatures in the window
--   
--   This will be equal to the specified window size, unless near genesis
countSignatures :: PBftState c -> Word64

-- | The number of blocks signed by the specified genesis key
--   
--   This only considers the signatures within the window, not in the
--   pre-window; see <a>PBftState</a> for detailed discussion.
countSignedBy :: PBftCrypto c => PBftState c -> PBftVerKeyHash c -> Word64

-- | The last (most recent) signed slot in the window
--   
--   Returns <a>Origin</a> if there are no signatures in the window (this
--   will happen exactly at genesis only).
--   
--   Unaffected by EBBs, since they're not signed.
lastSignedSlot :: PBftState c -> WithOrigin SlotNo
toList :: PBftState c -> [PBftSigner c]

-- | Note: we are not checking the invariants because we don't want to
--   require the <a>WindowSize</a> to be in the context, see #2383. When
--   assertions are enabled, we would notice the invariant violation as
--   soon as we <a>append</a>.
--   
--   PRECONDITION: the slots of the signers are in ascending order.
fromList :: PBftCrypto c => [PBftSigner c] -> PBftState c
encodePBftState :: (PBftCrypto c, Serialise (PBftVerKeyHash c)) => PBftState c -> Encoding
decodePBftState :: forall c. (PBftCrypto c, Serialise (PBftVerKeyHash c)) => forall s. Decoder s (PBftState c)
instance GHC.Generics.Generic (Ouroboros.Consensus.Protocol.PBFT.State.PBftSigner c)
instance GHC.Generics.Generic (Ouroboros.Consensus.Protocol.PBFT.State.PBftState c)
instance GHC.Real.Integral Ouroboros.Consensus.Protocol.PBFT.State.WindowSize
instance GHC.Real.Real Ouroboros.Consensus.Protocol.PBFT.State.WindowSize
instance GHC.Num.Num Ouroboros.Consensus.Protocol.PBFT.State.WindowSize
instance GHC.Enum.Enum Ouroboros.Consensus.Protocol.PBFT.State.WindowSize
instance GHC.Classes.Ord Ouroboros.Consensus.Protocol.PBFT.State.WindowSize
instance GHC.Classes.Eq Ouroboros.Consensus.Protocol.PBFT.State.WindowSize
instance GHC.Show.Show Ouroboros.Consensus.Protocol.PBFT.State.WindowSize
instance Ouroboros.Consensus.Protocol.PBFT.Crypto.PBftCrypto c => GHC.Show.Show (Ouroboros.Consensus.Protocol.PBFT.State.PBftState c)
instance Ouroboros.Consensus.Protocol.PBFT.Crypto.PBftCrypto c => GHC.Classes.Eq (Ouroboros.Consensus.Protocol.PBFT.State.PBftState c)
instance Ouroboros.Consensus.Protocol.PBFT.Crypto.PBftCrypto c => NoThunks.Class.NoThunks (Ouroboros.Consensus.Protocol.PBFT.State.PBftState c)
instance Ouroboros.Consensus.Protocol.PBFT.Crypto.PBftCrypto c => GHC.Show.Show (Ouroboros.Consensus.Protocol.PBFT.State.PBftSigner c)
instance Ouroboros.Consensus.Protocol.PBFT.Crypto.PBftCrypto c => GHC.Classes.Eq (Ouroboros.Consensus.Protocol.PBFT.State.PBftSigner c)
instance Ouroboros.Consensus.Protocol.PBFT.Crypto.PBftCrypto c => NoThunks.Class.NoThunks (Ouroboros.Consensus.Protocol.PBFT.State.PBftSigner c)
instance Codec.Serialise.Class.Serialise (Ouroboros.Consensus.Protocol.PBFT.Crypto.PBftVerKeyHash c) => Codec.Serialise.Class.Serialise (Ouroboros.Consensus.Protocol.PBFT.State.PBftSigner c)

module Ouroboros.Consensus.Protocol.PBFT

-- | Permissive BFT
--   
--   As defined in
--   <a>https://hydra.iohk.io/job/Cardano/cardano-ledger-specs/byronChainSpec/latest/download-by-type/doc-pdf/blockchain-spec</a>
data PBft c

-- | Signature threshold. This represents the proportion of blocks in a
--   <tt>pbftSignatureWindow</tt>-sized window which may be signed by any
--   single key.
newtype PBftSignatureThreshold
PBftSignatureThreshold :: Double -> PBftSignatureThreshold
[getPBftSignatureThreshold] :: PBftSignatureThreshold -> Double
data PBftLedgerView c
PBftLedgerView :: !Bimap (PBftVerKeyHash c) (PBftVerKeyHash c) -> PBftLedgerView c

-- | ProtocolParameters: map from genesis to delegate keys.
[pbftDelegates] :: PBftLedgerView c -> !Bimap (PBftVerKeyHash c) (PBftVerKeyHash c)
data PBftFields c toSign
PBftFields :: VerKeyDSIGN (PBftDSIGN c) -> VerKeyDSIGN (PBftDSIGN c) -> SignedDSIGN (PBftDSIGN c) toSign -> PBftFields c toSign

-- | The actual issuer of a block
[pbftIssuer] :: PBftFields c toSign -> VerKeyDSIGN (PBftDSIGN c)

-- | The stakeholder on whose behalf the block is being issued
[pbftGenKey] :: PBftFields c toSign -> VerKeyDSIGN (PBftDSIGN c)
[pbftSignature] :: PBftFields c toSign -> SignedDSIGN (PBftDSIGN c) toSign

-- | Protocol parameters
data PBftParams
PBftParams :: !SecurityParam -> !NumCoreNodes -> !PBftSignatureThreshold -> PBftParams

-- | Security parameter
--   
--   Although the protocol proper does not have such a security parameter,
--   we insist on it.
[pbftSecurityParam] :: PBftParams -> !SecurityParam

-- | Number of core nodes
[pbftNumNodes] :: PBftParams -> !NumCoreNodes

-- | Signature threshold
--   
--   This bounds the proportion of the latest <a>pbftSecurityParam</a>-many
--   blocks which is allowed to be signed by any single key. The protocol
--   proper is parameterized over the size of this window of recent blocks,
--   but this implementation follows the specification by fixing that
--   parameter to the ambient security parameter <tt>k</tt>.
[pbftSignatureThreshold] :: PBftParams -> !PBftSignatureThreshold

-- | If we are a core node (i.e. a block producing node) we know which core
--   node we are, and we have the operational key pair and delegation
--   certificate.
data PBftCanBeLeader c
PBftCanBeLeader :: !CoreNodeId -> !SignKeyDSIGN (PBftDSIGN c) -> !PBftDelegationCert c -> PBftCanBeLeader c
[pbftCanBeLeaderCoreNodeId] :: PBftCanBeLeader c -> !CoreNodeId
[pbftCanBeLeaderSignKey] :: PBftCanBeLeader c -> !SignKeyDSIGN (PBftDSIGN c)
[pbftCanBeLeaderDlgCert] :: PBftCanBeLeader c -> !PBftDelegationCert c

-- | Information required to produce a block.
data PBftIsLeader c
PBftIsLeader :: !SignKeyDSIGN (PBftDSIGN c) -> !PBftDelegationCert c -> PBftIsLeader c
[pbftIsLeaderSignKey] :: PBftIsLeader c -> !SignKeyDSIGN (PBftDSIGN c)
[pbftIsLeaderDlgCert] :: PBftIsLeader c -> !PBftDelegationCert c

-- | Window size used by PBFT
--   
--   We set the window size to be equal to k.
pbftWindowSize :: SecurityParam -> WindowSize

-- | Does the number of blocks signed by this key exceed the threshold?
--   
--   Returns <tt>Just</tt> the number of blocks signed if exceeded.
pbftWindowExceedsThreshold :: PBftCrypto c => PBftWindowParams -> PBftState c -> PBftVerKeyHash c -> Either Word64 ()
forgePBftFields :: forall c toSign. (PBftCrypto c, Signable (PBftDSIGN c) toSign) => (VerKeyDSIGN (PBftDSIGN c) -> ContextDSIGN (PBftDSIGN c)) -> IsLeader (PBft c) -> toSign -> PBftFields c toSign

-- | Crypto primitives required by BFT
--   
--   Cardano stores a map of stakeholder IDs rather than the verification
--   key directly. We make this family injective for convenience - whilst
--   it's _possible_ that there could be non-injective instances, the
--   chances of there being more than the two instances here are basically
--   non-existent.
class (Typeable c, DSIGNAlgorithm (PBftDSIGN c), Condense (SigDSIGN (PBftDSIGN c)), Show (PBftVerKeyHash c), Ord (PBftVerKeyHash c), Eq (PBftVerKeyHash c), Show (PBftVerKeyHash c), NoThunks (PBftVerKeyHash c), NoThunks (PBftDelegationCert c)) => PBftCrypto c where {
    type family PBftDSIGN c :: Type;
    type family PBftDelegationCert c = (d :: Type) | d -> c;
    type family PBftVerKeyHash c = (d :: Type) | d -> c;
}
dlgCertGenVerKey :: PBftCrypto c => PBftDelegationCert c -> VerKeyDSIGN (PBftDSIGN c)
dlgCertDlgVerKey :: PBftCrypto c => PBftDelegationCert c -> VerKeyDSIGN (PBftDSIGN c)
hashVerKey :: PBftCrypto c => VerKeyDSIGN (PBftDSIGN c) -> PBftVerKeyHash c
data PBftMockCrypto

-- | Part of the header that we validate
data PBftValidateView c

-- | Regular block
--   
--   Regular blocks are signed, and so we need to validate them. We also
--   need to know the slot number of the block
PBftValidateRegular :: PBftFields c signed -> signed -> ContextDSIGN (PBftDSIGN c) -> PBftValidateView c

-- | Boundary block (EBB)
--   
--   EBBs are not signed and they do not affect the consensus state.
PBftValidateBoundary :: PBftValidateView c

-- | Convenience constructor for <a>PBftValidateView</a> for regular blocks
pbftValidateRegular :: (SignedHeader hdr, Signable (PBftDSIGN c) (Signed hdr)) => ContextDSIGN (PBftDSIGN c) -> (hdr -> PBftFields c (Signed hdr)) -> hdr -> PBftValidateView c

-- | Convenience constructor for <a>PBftValidateView</a> for boundary
--   blocks
pbftValidateBoundary :: hdr -> PBftValidateView c

-- | Expresses that, whilst we believe ourselves to be a leader for this
--   slot, we are nonetheless unable to forge a block.
data PBftCannotForge c

-- | We cannot forge a block because we are not the current delegate of the
--   genesis key we have a delegation certificate from.
PBftCannotForgeInvalidDelegation :: !PBftVerKeyHash c -> PBftCannotForge c

-- | We cannot lead because delegates of the genesis key we have a
--   delegation from have already forged the maximum number of blocks in
--   this signing window.
PBftCannotForgeThresholdExceeded :: !Word64 -> PBftCannotForge c
pbftCheckCanForge :: forall c. PBftCrypto c => ConsensusConfig (PBft c) -> PBftCanBeLeader c -> SlotNo -> Ticked (PBftState c) -> Either (PBftCannotForge c) ()

-- | Static configuration required to run the consensus protocol
--   
--   Every method in the <a>ConsensusProtocol</a> class takes the consensus
--   configuration as a parameter, so having this as a data family rather
--   than a type family resolves most ambiguity.
--   
--   Defined out of the class so that protocols can define this type
--   without having to define the entire protocol at the same time (or
--   indeed in the same module).
data family ConsensusConfig p :: Type

-- | " Ticked " piece of state (<tt>LedgerState</tt>, <tt>LedgerView</tt>,
--   <tt>ChainIndepState</tt>)
--   
--   Ticking refers to the passage of time (the ticking of the clock). When
--   a piece of state is marked as ticked, it means that time-related
--   changes have been applied to the state (or forecast).
--   
--   Some examples of time related changes:
--   
--   <ul>
--   <li>Scheduled delegations might have been applied in Byron</li>
--   <li>New leader schedule computed for Shelley</li>
--   <li>Transition from Byron to Shelley activated in the hard fork
--   combinator.</li>
--   <li>Nonces switched out at the start of a new epoch.</li>
--   </ul>
data family Ticked st :: Type

-- | NOTE: this type is stored in the state, so it must be in normal form
--   to avoid space leaks.
data PBftValidationErr c
PBftInvalidSignature :: !Text -> PBftValidationErr c
PBftNotGenesisDelegate :: !PBftVerKeyHash c -> !PBftLedgerView c -> PBftValidationErr c

-- | We record how many slots this key signed
PBftExceededSignThreshold :: !PBftVerKeyHash c -> !Word64 -> PBftValidationErr c
PBftInvalidSlot :: PBftValidationErr c
instance GHC.Generics.Generic (Ouroboros.Consensus.Protocol.PBFT.PBftFields c toSign)
instance GHC.Generics.Generic (Ouroboros.Consensus.Protocol.PBFT.PBftLedgerView c)
instance NoThunks.Class.NoThunks Ouroboros.Consensus.Protocol.PBFT.PBftSignatureThreshold
instance GHC.Generics.Generic Ouroboros.Consensus.Protocol.PBFT.PBftSignatureThreshold
instance GHC.Show.Show Ouroboros.Consensus.Protocol.PBFT.PBftSignatureThreshold
instance GHC.Classes.Eq Ouroboros.Consensus.Protocol.PBFT.PBftSignatureThreshold
instance GHC.Show.Show Ouroboros.Consensus.Protocol.PBFT.PBftParams
instance NoThunks.Class.NoThunks Ouroboros.Consensus.Protocol.PBFT.PBftParams
instance GHC.Generics.Generic Ouroboros.Consensus.Protocol.PBFT.PBftParams
instance NoThunks.Class.NoThunks (Ouroboros.Consensus.Protocol.Abstract.ConsensusConfig (Ouroboros.Consensus.Protocol.PBFT.PBft c))
instance GHC.Generics.Generic (Ouroboros.Consensus.Protocol.Abstract.ConsensusConfig (Ouroboros.Consensus.Protocol.PBFT.PBft c))
instance GHC.Generics.Generic (Ouroboros.Consensus.Protocol.PBFT.PBftCanBeLeader c)
instance GHC.Generics.Generic (Ouroboros.Consensus.Protocol.PBFT.PBftIsLeader c)
instance Ouroboros.Consensus.Protocol.PBFT.Crypto.PBftCrypto c => NoThunks.Class.NoThunks (Ouroboros.Consensus.Protocol.PBFT.PBftValidationErr c)
instance GHC.Generics.Generic (Ouroboros.Consensus.Protocol.PBFT.PBftValidationErr c)
instance GHC.Generics.Generic (Ouroboros.Consensus.Protocol.PBFT.PBftCannotForge c)
instance Ouroboros.Consensus.Protocol.PBFT.Crypto.PBftCrypto c => GHC.Show.Show (Ouroboros.Consensus.Protocol.PBFT.PBftFields c toSign)
instance Ouroboros.Consensus.Protocol.PBFT.Crypto.PBftCrypto c => GHC.Classes.Eq (Ouroboros.Consensus.Protocol.PBFT.PBftFields c toSign)
instance Ouroboros.Consensus.Protocol.PBFT.Crypto.PBftCrypto c => NoThunks.Class.NoThunks (Ouroboros.Consensus.Protocol.PBFT.PBftLedgerView c)
instance GHC.Classes.Eq (Ouroboros.Consensus.Protocol.PBFT.Crypto.PBftVerKeyHash c) => GHC.Classes.Eq (Ouroboros.Consensus.Protocol.PBFT.PBftLedgerView c)
instance GHC.Show.Show (Ouroboros.Consensus.Protocol.PBFT.Crypto.PBftVerKeyHash c) => GHC.Show.Show (Ouroboros.Consensus.Protocol.PBFT.PBftLedgerView c)
instance Ouroboros.Consensus.Protocol.PBFT.Crypto.PBftCrypto c => GHC.Show.Show (Ouroboros.Consensus.Protocol.PBFT.PBftValidationErr c)
instance Ouroboros.Consensus.Protocol.PBFT.Crypto.PBftCrypto c => GHC.Classes.Eq (Ouroboros.Consensus.Protocol.PBFT.PBftValidationErr c)
instance Ouroboros.Consensus.Protocol.PBFT.Crypto.PBftCrypto c => GHC.Show.Show (Ouroboros.Consensus.Protocol.PBFT.PBftCannotForge c)
instance Ouroboros.Consensus.Protocol.PBFT.Crypto.PBftCrypto c => NoThunks.Class.NoThunks (Ouroboros.Consensus.Protocol.PBFT.PBftCannotForge c)
instance Ouroboros.Consensus.Protocol.PBFT.Crypto.PBftCrypto c => Ouroboros.Consensus.Protocol.Abstract.ConsensusProtocol (Ouroboros.Consensus.Protocol.PBFT.PBft c)
instance Ouroboros.Consensus.Protocol.PBFT.Crypto.PBftCrypto c => NoThunks.Class.NoThunks (Ouroboros.Consensus.Protocol.PBFT.PBftIsLeader c)
instance Ouroboros.Consensus.Protocol.PBFT.Crypto.PBftCrypto c => NoThunks.Class.NoThunks (Ouroboros.Consensus.Protocol.PBFT.PBftCanBeLeader c)
instance Ouroboros.Consensus.Protocol.PBFT.Crypto.PBftCrypto c => Ouroboros.Consensus.Protocol.Abstract.ChainSelection (Ouroboros.Consensus.Protocol.PBFT.PBft c)
instance (Codec.Serialise.Class.Serialise (Ouroboros.Consensus.Protocol.PBFT.Crypto.PBftVerKeyHash c), GHC.Classes.Ord (Ouroboros.Consensus.Protocol.PBFT.Crypto.PBftVerKeyHash c)) => Codec.Serialise.Class.Serialise (Ouroboros.Consensus.Protocol.PBFT.PBftLedgerView c)
instance (Ouroboros.Consensus.Protocol.PBFT.Crypto.PBftCrypto c, Data.Typeable.Internal.Typeable toSign) => NoThunks.Class.NoThunks (Ouroboros.Consensus.Protocol.PBFT.PBftFields c toSign)
instance Ouroboros.Consensus.Protocol.PBFT.Crypto.PBftCrypto c => Ouroboros.Consensus.Util.Condense.Condense (Ouroboros.Consensus.Protocol.PBFT.PBftFields c toSign)
