This is a major refactoring that gets rid of a significant wart
in the design of the `bridgetree::Frontier` type that has existed
since the the project's inception.
The `Leaf` type incorrectly treated the siblings of leaves at
odd positions as special, whereas they should have been simply
treated as ordinary entries in the frontier's ommers list. Correcting
this allows for the code to be significantly simplified in a number
of places.
Prior to this change, each position being tracked would
require an entry in the `auth_fragments` map for each
bridge in a BridgeTree. However, very frequently, these
entries would duplicate storage of nodes higher up in the
tree, wherever a single node in the was an ancestor of
a leaf being tracked.
This commit restructures the tracking of auth data to
avoid this duplication of data, as well as the redundant
work that was required to produce each copy of the duplicated
nodes.
This requires a user of this API to specify a root of the tree
that identifies the state of the tree at which the user wishes
to construct an authentication path. This must be equal to either
the current root of the tree, or to the root of the tree at a
previous checkpoint.
* `witnessed_positions` returns the set of positions that have been
witnessed in the tree.
* `garbage_collect` makes the garbage collection operation of
`bridgetree::BridgeTree` publicly accessible. It is always safe to
implement this method as a no-op.
This modifies the `Tree::authentication_path` and `Tree::remove_witness`
methods to only operate in terms of the tree position, rather than both
the position and the hash that is expected to be the leaf at that
position.
Positions in the tree are always unique, and the tree already contains
the leaf information corresponding to each position, so the existing API
previously required the storage of redundant information. This change
streamlines the API without loss of power.
This also adds additional consistency checks to the property tests.
This was just entirely wrong; it will often be the case that we've
observed several altitudes but have an empty list of values within
a particular fragment.