Attempt to clarify bank forks
This commit is contained in:
		
							
								
								
									
										11
									
								
								book/art/forks-pruned2.bob
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								book/art/forks-pruned2.bob
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
|  1 | ||||
|  | | ||||
|  3 | ||||
|  |\ | ||||
|  | \ | ||||
|  |  | | ||||
|  |  | | ||||
|  |  | | ||||
|  6  | | ||||
|     | | ||||
|     7 | ||||
| @@ -1,4 +1,4 @@ | ||||
| # Bank Fork | ||||
| # Bank Forks | ||||
|  | ||||
| This design describes a way to checkpoint the bank state such that it can track | ||||
| multiple forks without duplicating data.  It addresses the following | ||||
| @@ -11,8 +11,9 @@ challenges: | ||||
|  | ||||
| ## 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. | ||||
| The basic design idea is to maintain a DAG of Banks checkpointed at different | ||||
| slot heights. The DAG is initialized with a *root* slot height.  Each | ||||
| subsequent fork must descend from the root. | ||||
|  | ||||
| ## Active Forks | ||||
|  | ||||
| @@ -25,35 +26,35 @@ For example: | ||||
|  | ||||
| The following *active forks* are in the forks DAG | ||||
|  | ||||
| * 4,2,1 | ||||
| * 5,2,1 | ||||
| * 6,1 | ||||
| * 7,1 | ||||
| * {4, 2, 1} | ||||
| * {5, 2, 1} | ||||
| * {6, 3, 1} | ||||
| * {7, 3, 1} | ||||
|  | ||||
| ## Merging into root | ||||
| ## Squashing | ||||
|  | ||||
| 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 | ||||
| A validator votes for a frozen fork.  The active fork connecting the fork to | ||||
| the root is *squashed*.  If the active fork is longer than | ||||
| `Forks::ROLLBACK_DEPTH` the oldest two forks are squashed.  The oldest fork in | ||||
| the active fork is the current root, so the second oldest is a direct | ||||
| descendant of the root fork.  Once squashed, 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: | ||||
| Starting from the example above, consider a vote on 5 versus a vote on 6: | ||||
|  | ||||
| <img alt="Forks" src="img/forks.svg" class="center"/> | ||||
|  | ||||
| * ROLLBACK\_DEPTH=2, vote=5, *active fork*={5,2,1} | ||||
| * 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} | ||||
| * ROLLBACK\_DEPTH=2, vote=6, *active fork*={6, 3, 1} | ||||
|  | ||||
| <img alt="Forks" src="img/forks.svg" class="center"/> | ||||
| <img alt="Forks" src="img/forks-pruned2.svg" class="center"/> | ||||
|  | ||||
| The tree remains with `root=1`, since the *active fork* starting at 6 is only 2 | ||||
| The tree remains with `root=1`, since the active fork starting at 6 is only 2 | ||||
| forks long. | ||||
|   | ||||
		Reference in New Issue
	
	Block a user