-
Notifications
You must be signed in to change notification settings - Fork 170
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
Adding ChainSync to spec (WIP) #568
Changes from all commits
723e7f8
448f846
8259ffa
c43d509
a304f04
87c9a62
ae5b6d8
1f98527
899f8fc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
This file was deleted.
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
package chainsync |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
import ipld "github.com/filecoin-project/specs/libraries/ipld" | ||
import block "github.com/filecoin-project/specs/systems/filecoin_blockchain/struct/block" | ||
|
||
type ChainSync struct { | ||
// LastTrustedCheckpoint is the most recent TrustedCheckpoint | ||
// ChainSync is aware of. This is used as the starting point from | ||
// which to synchronize the chain. (See block/checkpoints) | ||
LastTrustedCheckpoint block.TrustedCheckpoint | ||
|
||
// VGraph is the ValidationGraph ChainSync uses to track all | ||
// Blocks and decide which blocks to validate, when. | ||
VGraph ValidationGraph | ||
} | ||
|
||
type ValidationGraph struct { | ||
// ChainStore is the ipld Datastore through which to load and store | ||
// all Chain datastructures (Blocks, Messages, StateTrees, etc.) | ||
ChainStore ipld.Store | ||
|
||
// CacheChainStore is the ipld Datastore through which to load and store | ||
// chain datastructures that may be temporary and may be garbage collected. | ||
CacheChainStore ipld.Store | ||
|
||
// Graph is a datastructure that provides efficient access to all | ||
// nodes needed for validation, and keeps both forward and back links. | ||
// Graph graph.BlockGraph | ||
|
||
// FinalityTipset contains the latest finalized tipset -- this is the | ||
// local node's notion of finality. It will not automatically unwind | ||
// history before this point. All automatic ChainSync is forward from | ||
// this tipset. | ||
// | ||
// This is what we use to check state against for users/clients of the | ||
// blockchain subsystem. If users request FinalityEpoch, it corresponds | ||
// to FinalityTipset. | ||
FinalityTipset PartialGraph | ||
|
||
// ValidG contains all the blocks we have validated, but are not | ||
// yet declared Final. This means all the blocks connected into the | ||
// main blockchain, but not yet past finality (ie after FinalityTipset) | ||
ValidG PartialGraph | ||
|
||
// FetchedG is the set of unvalidated Blocks fully connected | ||
// to the validated graph. These are ready to be validated, all the | ||
// data is local, and are ordered by total ChainWeight. | ||
FetchedG PartialGraph | ||
|
||
// ConnectedG is the set of connected Blocks (BlockHeaders) fully connected | ||
// to the ToValidateG graph. These are close to ready to be validated. | ||
// Data may or not may not be local. Ordered by total ChainWeight. | ||
ConnectedG PartialGraph | ||
|
||
// UnconnectedG is the set of connected Blocks (BlockHeaders), which | ||
// may or may not connect back to the growing blockchain. This set | ||
// could contain the heaviest chain, and could contain attackers' | ||
// blocks. | ||
UnconnectedG PartialGraph | ||
|
||
// TargetHeads is a list of candidate blocks sorted by likelihood of being the | ||
// best chain. (eg sorted by block.ChainWeight, even if not validated yet) | ||
// TargetHeads SHOULD be a small set (<10) | ||
// | ||
// Obviously bad heads SHOULD be pruned out: | ||
// - Clearly invalid ChainWeight (lower than BestHead or too high) | ||
// - Heads that are not advancing in BlockPubsub | ||
TargetHeads [block.BlockCID] | ||
|
||
// BestTargetHead is the single best candidate head | ||
// BestTargetHead == TargetHeads[0] | ||
BestTargetHead block.BlockCID | ||
} | ||
|
||
// PartialGraph is a datastructure used to track a set of blocks, and | ||
// provide efficient access to the Roots/Heads and Leaves/Tails of the | ||
// subgraph. | ||
type PartialGraph struct { | ||
// fullGraph provides acess to all nodes | ||
fullGraph BlockGraph | ||
|
||
// Blocks is the set of all blocks in this PartialGraph | ||
Blocks {block.BlockCID: struct {}} | ||
|
||
// Heads is the set of root/head blocks | ||
Heads [block.BlockCID] | ||
|
||
// Tails is the set of leaf/tail blocks | ||
Tails [block.BlockCID] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm confused. Does head refer to the newest thing, as in the "head of the chain" being the latest state? The use of "root" is confusing if so, since one might usually identify that with the genesis. Similarly "leaf" also sounds like the expanding fringe. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
||
// Add adds given BlockCID to the PartialGraph, updating Blocks, | ||
// Roots, and Leaves as needed. | ||
Add(c block.BlockCID) | ||
|
||
// Remove deletes given BlockCID from the PartialGraph, updating | ||
// Blocks, Roots, and Leaves as needed. | ||
Remove(c block.BlockCID) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is a graph necessarily connected, or is this just a bag of blocks, with each disconnected subgraph being reported in heads/tails? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
} | ||
|
||
type BlockGraph struct {// TODO | ||
Parents(b block.BlockCID) block.Tipset | ||
Children(b block.BlockCID) [block.Block] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
digraph sector { | ||
compound=true; | ||
// splines=curved; | ||
edge [style=solid] | ||
|
||
{ // states | ||
node [shape=box, fontname="monospace", style=filled, color=gray84] | ||
INIT | ||
BOOTSTRAP | ||
SYNC_CHECKPOINT | ||
CHAIN_CATCHUP | ||
CHAIN_FOLLOW [color=seagreen3] | ||
} | ||
|
||
{ // transitions | ||
node [shape=none] | ||
init2boot [label=< <i>prepare and verify<br/>all internal state</i> >] | ||
boot2check [label=< <i>done bootstrapping.<br/><b>DO NOT</b> have state for<br/><u>LastTrustedCheckpoint</u></i> >] | ||
boot2catch [label=< <i>done bootstrapping.<br/><b>DO</b> have state for<br/><u>LastTrustedCheckpoint</u></i> >] | ||
check2catch [label=< <i>done getting state for<br/><u>LastTrustedCheckpoint</u></i> >] | ||
catch2follow [label=< <i>done validating<br/>up to <u>BestTargetHead</u></i> >] | ||
{ | ||
follow2catch [label=< <i>new unvalidated gap between<br/><u>ValidG</u> and <u>BestTargetHead</u></i> >, constraint=false, color=red, fontcolor=red] | ||
follow2init [label=< <i>on shut down node</i> >, constraint=false, color=red, fontcolor=red, pos="6,3!"] | ||
} | ||
} | ||
|
||
{ // transition 1 | ||
edge [arrowhead=none] | ||
INIT -> init2boot | ||
BOOTSTRAP -> boot2check | ||
BOOTSTRAP -> boot2catch | ||
SYNC_CHECKPOINT -> check2catch | ||
CHAIN_CATCHUP -> catch2follow | ||
} | ||
|
||
{ // transition 2 | ||
init2boot -> BOOTSTRAP | ||
boot2check -> SYNC_CHECKPOINT | ||
boot2catch -> CHAIN_CATCHUP | ||
check2catch -> CHAIN_CATCHUP | ||
catch2follow -> CHAIN_FOLLOW | ||
} | ||
|
||
{ // transition backs (reversed) | ||
{ | ||
edge [dir=back] | ||
CHAIN_CATCHUP -> follow2catch [color=red] | ||
INIT -> follow2init [color=red] | ||
} | ||
|
||
{ | ||
edge [dir=none] | ||
follow2catch -> CHAIN_FOLLOW [constraint=false, color=red] | ||
// follow2init -> CHAIN_FOLLOW [color=red] | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have assumed all the way through here that "head" is a tipset, not a single block. This and
BestTargetHead
contradict that. I think we might need a new word to refer to blocks that area at the fringe (have no children), distinct from tipsets that can be composed from those blocks.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TargetBlocks
andBestTargetBlock
Tipset
, but thinking/dealing with them as tipsets is a bit trickier (combinatorics...)HeadBlock
vsHeadTipset
? hmmm open to other suggestionsThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm ok with most of this sync spec being phrased in terms of blocks. It does simplify a few things. But "head" in particular is ambiguous, so qualifying it always would help.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok will do
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
addressed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(for now keeping word Head but clearly noting it is a block. may still switch it before PR lands.