Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add design for the forking bank #2646

Merged
merged 7 commits into from
Feb 7, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions book/art/forks-pruned.bob
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
2
/|
/ |
4 |
5
9 changes: 9 additions & 0 deletions book/art/forks.bob
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
1
/ \
2 \
/| |
/ | |
4 | |
5 /\
6 \
7
1 change: 1 addition & 0 deletions book/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
- [Blocktree](blocktree.md)
- [Data Plane Fanout](data-plane-fanout.md)
- [Reliable Vote Transmission](reliable-vote-transmission.md)
- [Bank Forks](bank-forks.md)
- [Cluster Economics](ed_overview.md)
- [Validation-client Economics](ed_validation_client_economics.md)
- [State-validation Protocol-based Rewards](ed_vce_state_validation_protocol_based_rewards.md)
Expand Down
59 changes: 59 additions & 0 deletions book/src/bank-forks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Bank Fork

This design describes a way to checkpoint the bank state such that it can track
multiple forks without duplicating data. It addresses the following
challenges:

* Forks are potentially created at every slot boundary.
* Forks can be based on any previously produced block.
* Forks are eventually finalized such that rollback is impossible.
* Unreachable forks need to be pruned.

## Architecture

The basic design idea is to maintain a DAG of forks. The DAG is initialized with
a *root*. Each subsequent fork must descend from the root.

## Active Forks

An *active fork* is a direct list of connected forks that descend from the
current root to a specific fork without any descendants.

For example:

<img alt="Forks" src="img/forks.svg" class="center"/>

The following *active forks* are in the forks DAG

* 4,2,1
* 5,2,1
* 6,1
* 7,1

## Merging into root

A validator votes for a frozen fork. The *active fork* connecting the fork
to the root is merged. If the *active fork* is longer than
`Forks::ROLLBACK_DEPTH` the oldest two forks are merged. The oldest fork in
the *active fork* is the current root, so the second oldest is a direct
descendant of the root fork. Once merged, the current root is updated to the
root descendant. Any forks that are not descendants from the new root are
pruned since they are no longer reachable.

For example:

<img alt="Forks" src="img/forks.svg" class="center"/>

* ROLLBACK\_DEPTH=2, vote=5, *active fork*={5,2,1}

<img alt="Forks after pruning" src="img/forks-pruned.svg" class="center"/>

The new root is 2, and any active forks that are not descendants from 2 are
pruned.

* ROLLBACK\_DEPTH=2, vote=6, *active fork*={6,1}

<img alt="Forks" src="img/forks.svg" class="center"/>

The tree remains with `root=1`, since the *active fork* starting at 6 is only 2
forks long.