Add `deforestBlockTree`
An important in-progress task is to make more test code
block-polymorphic; right now it is largely hardcoded to use test blocks
but this will not work for running conformance tests against live
implementations of the protocol.
We do not know the exact motivation behind making these tests monomorphic;
regardless it seems the only thing the tests require is the ability to
compute where a block is on the block tree.
Here we add a helper function to make generalize this by constructing a map
from each block hash in the tree to the `AnchoredFragment` from it to the
anchor. That fragment is a prefix of the trunk if and only if the block
is on the trunk.
The deforested block tree is used to check for block membership, and
to prevent its unnecessary regeneration many thousands of times per test,
it is implemented by adding a `DeforestedBlockTree` field to `BlockTree` to
cache it and a smart constructor that populates it correctly at definition time
and makes it possible to deconstruct a block tree into its trunk and branches
without giving access to the cached deforestation.
GHC's pattern match checker [assumes that any case expression involving
a pattern synonym is
incomplete](https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/pragmas.html#complete-pragmas);
with either `-Wincomplete-patterns` or `-Wall`, GHC will report usage of
such patterns an incomplete pattern match like this:
```
Pattern match(es) are non-exhaustive
In an equation for ‘mkProperty’:
Patterns of type ‘GenesisTestFull blk’,
‘StateView blk’ not matched:
(GenesisTest _ _ _ _ (Test.Consensus.BlockTree.RawBlockTree _ _ _)
_ _ _ _ _ _ _)
_
```
For this reason we add a `COMPLETE` pragma to let GHC know that `BlockTree` is
in fact a complete set of patterns for deconstructing a block tree.