You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat: use positions based on a forest with 63 rows
When we compute the position of a node, for any node not in the 0th row,
their position depends on how many leaves there are. This happens because
the 0th row's size is allocated to the nearest power of two that can
fit that many leaves. Therefore, in a forest with 6 leaves, the bottom row
goes from zero through 7, the row 1 from 8 through 11 (the size of each row
halves as you move up). If you add three extra UTXOs, growing the forest to
nine leaves, adding the 9th will require allocating 16 0-row leaves, row 1
therefore goes from 16 to 23 and so on.
If leaves always stay at the bottom, that fine. Nothing at the bottom ever
needs to care about this, because there's no row before it to grow and shift
their positions. However, leaves **do** move up during deletions. For that
reason, whenever the forest grow, all targets that aren't at the bottom needs
to be updated.
Now imagine that we want to keep a leaf map that maps leaf_hash -> position
within the forest: this works fine, we know where a node must go when deleting,
by calling [`parent`] with their current position and `num_leaves`. But now
imagine the forest has to grow: we need to go through the map and update
all non-row 0 leaves. This could potentially involve going through millions of
UTXOs and update one-by-one. Note that we can find the next position, it's not super
efficient but works (see [`crate::proof::Proof::maybe_remap`] for more details),
but doing this for every UTXO that isn't at the bottom is too expensive, even
though it happens exponentially less frequently, when it happens, it's going to
take an absurd amount of time and potentially stall the Utreexo network for hours.
For that reason, we communicate positions as if the forest is always filled with
the maximum amount of leaves we can possibly have, which is 63. Therefore, those
positions never need to be remapped. Internally, we still use the dynamic size,
and use this function to translate between the two.
0 commit comments