Skip to content

Commit

Permalink
fix(content): update Blocks and Tipsets section (#1169)
Browse files Browse the repository at this point in the history
Co-authored-by: Hugo Dias <hugomrdias@gmail.com>
  • Loading branch information
yiannisbot and hugomrdias authored Sep 25, 2020
1 parent 0bc5162 commit d2f3a5b
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 54 deletions.
16 changes: 7 additions & 9 deletions content/systems/filecoin_blockchain/_index.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
---
title: "Blockchain"
title: Blockchain
bookCollapseSection: true
weight: 4
dashboardWeight: 2
dashboardState: wip
dashboardState: reliable
dashboardAudit: missing
dashboardTests: 0
---
Expand All @@ -12,20 +12,18 @@ dashboardTests: 0

The Filecoin Blockchain is a distributed virtual machine that achieves consensus, processes messages, accounts for storage, and maintains security in the Filecoin Protocol. It is the main interface linking various actors in the Filecoin system.

It includes:
The Filecoin blockchain system includes:

- A [Message Pool](message_pool) subsystem that nodes use to track and propagate messages related to the storage market throughout a gossip network.
- A [Message Pool](message_pool) subsystem that nodes use to track and propagate messages that miners have declared they want to include in the blockchain.
- A [Virtual Machine](systems/filecoin_vm) subsystem used to interpret and execute messages in order to update system state.
- A [State Tree](state_tree) subsystem which manages the creation and maintenance of state trees (the system state) deterministically generated by the vm from a given subchain.
- A [Chain Synchronisation (ChainSync)](chainsync) susbystem that tracks and propagates validated message blocks, maintaining sets of candidate chains on which the miner may mine and running syntactic validation on incoming blocks.
- A [Storage Power Consensus](storage_power_consensus) subsystem which tracks storage state (i.e., [Storage Subystem](storage_mining)) for a given chain and helps the blockchain system choose subchains to extend and blocks to include in them.

And also:
The blockchain system also includes:

- A [Chain Manager](chain_manager) -- which maintains a given chain's state, providing facilities to other blockchain subsystems which will query state about the latest chain in order to run, and ensuring incoming blocks are semantically validated before inclusion into the chain.
- A [Block Producer](block_producer) -- which is called in the event of a successful leader election in order to produce a new block that will extend the current heaviest chain before forwarding it to the syncer for propagation.
- A [Chain Manager](chain_manager), which maintains a given chain's state, providing facilities to other blockchain subsystems which will query state about the latest chain in order to run, and ensuring incoming blocks are semantically validated before inclusion into the chain.
- A [Block Producer](block_producer) which is called in the event of a successful leader election in order to produce a new block that will extend the current heaviest chain before forwarding it to the syncer for propagation.

At a high-level, the Filecoin blockchain grows through successive rounds of leader election in which a number of miners are elected to generate a block, whose inclusion in the chain will earn them block rewards.
Filecoin's blockchain runs on storage power. That is, its consensus algorithm by which miners agree on which subchain to mine is predicated on the amount of storage backing that subchain. At a high-level, the [Storage Power Consensus](storage_power_consensus) subsystem maintains a _Power Table_ that tracks the amount of storage that [storage miner actors](storage_mining) have contributed to the network through _Sector commitments_ and _Proofs of Spacetime_.

Most of the functions of the Filecoin blockchain system are detailed in the code below.
4 changes: 2 additions & 2 deletions content/systems/filecoin_blockchain/struct/_index.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
---
title: "Blocks"
title: Blocks
bookCollapseSection: true
weight: 1
dashboardWeight: 1.5
dashboardState: incorrect
dashboardState: wip
dashboardAudit: missing
dashboardTests: 0
---
Expand Down
150 changes: 109 additions & 41 deletions content/systems/filecoin_blockchain/struct/block/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,67 @@
title: Block
weight: 1
dashboardWeight: 1.5
dashboardState: incorrect
dashboardState: reliable
dashboardAudit: missing
dashboardTests: 0
---

# Block

A block header contains information relevant to a particular point in time over which the network may achieve consensus.
The Block is the main unit of the Filecoin blockchain.

> **Note:** A block is functionally the same as a block header in the Filecoin protocol. While a block header contains Merkle links to the full system state, messages, and message receipts, a block can be thought of as the full set of this information (not just the Merkle roots, but rather the full data of the state tree, message tree, receipts tree, etc.). Because a full block is quite large, our chain consists of block headers rather than full blocks. We often use the terms `block` and `block header` interchangeably.
The Block structure in the Filecoin blockchain is composed of: i) the Block Header, ii) the list of messages inside the block, and iii) the signed messages. This is represented inside the `FullBlock` abstraction. The messages indicate the required set of changes to apply in order to arrive at a deterministic state of the chain.

{{< embed src="block.id" lang="go" >}}
The Lotus implementation of the block has the following `struct`:

{{<embed src="https://github.com/filecoin-project/lotus/blob/master/chain/types/fullblock.go" lang="go" symbol="FullBlock">}}

> **Note:** A block is functionally the same as a block header in the Filecoin protocol. While a block header contains Merkle links to the full system state, messages, and message receipts, a block can be thought of as the full set of this information (not just the Merkle roots, but rather the full data of the state tree, message tree, receipts tree, etc.). Because a full block is large in size, the Filecoin blockchain consists of block headers rather than full blocks. We often use the terms `block` and `block header` interchangeably.
A `BlockHeader` is a canonical representation of a block. BlockHeaders are propagated between miner nodes. From the blockcheader message, a miner has all the required information to apply the associated `FullBlock`'s state and update the chain. In order to be able to do this, the minimum set of information items that need to be included in the `BlockHeader` are shown below and include among others: the miner's address, the Ticket, the [Proof of SpaceTime](post), the CID of the parents where this block evolved from in the IPLD DAG, as well as the messages' own CIDs.

The Lotus implementation of the block header has the following `struct`s:

{{<embed src="https://github.com/filecoin-project/lotus/blob/master/chain/types/blockheader.go" lang="go" symbol="BlockHeader">}}

{{<embed src="https://github.com/filecoin-project/lotus/blob/master/chain/types/blockheader.go" lang="go" symbol="Ticket">}}

{{<embed src="https://github.com/filecoin-project/lotus/blob/master/chain/types/electionproof.go" lang="go" symbol="ElectionProof">}}

{{<embed src="https://github.com/filecoin-project/lotus/blob/master/chain/types/blockheader.go" lang="go" symbol="BeaconEntry">}}

The `BlockHeader` structure has to refer to the TicketWinner of the current round which ensures the correct winner is passed to [ChainSync](chainsync).

```go
func IsTicketWinner(vrfTicket []byte, mypow BigInt, totpow BigInt) bool
```

The `Message` structure has to include the source (`From`) and destination (`To`) addresses, a `Nonce` and the `GasPrice`.

The Lotus implementation of the message has the following structure:

{{<embed src="https://github.com/filecoin-project/lotus/blob/master/chain/types/message.go" lang="go" symbol="Message">}}


The message is also validated before it is passed to the [chain synchronization logic](chainsync):

{{<embed src="https://github.com/filecoin-project/lotus/blob/master/chain/types/message.go" lang="go" symbol="ValidForBlockInclusion">}}

{{< embed src="election.id" lang="go" >}}

## Block syntax validation

Syntax validation refers to validation that may be performed on a block and its messages
without reference to outside information such as the parent state tree.
Syntax validation refers to validation that should be performed on a block and its messages _without_ reference to outside information such as the parent state tree. This type of validation is sometimes called _static validation_.

An invalid block must not be transmitted or referenced as a parent.

A syntactically valid block header must decode into fields matching the type definition below.

A syntactically valid header must have:
A syntactically valid block header must decode into fields matching the definitions below, must be a valid CBOR PubSub `BlockMsg` message and must have:

- between 1 and `5*ec.ExpectedLeaders` `Parents` CIDs if `Epoch` is greater than zero (else empty `Parents`),
- a non-negative `ParentWeight`,
- a `Miner` address which is an ID-address,
- less than or equal to `BlockMessageLimit` number of messages,
- aggregate message CIDs, encapsulated in the `MsgMeta` structure, serialized to the `Messages` CID in the block header,
- a `Miner` address which is an ID-address. The Miner `Address` in the block header should be present and correspond to a public-key address in the current chain state.
- Block signature (`BlockSig`) that belongs to the public-key address retrieved for the Miner
- a non-negative `Epoch`,
- a positive `Timestamp`,
- a `Ticket` with non-empty `VRFResult`,
Expand All @@ -47,48 +79,84 @@ A syntactically valid full block must have:
- the sum of the serialized sizes of the block header and included messages is no greater than `block.BlockMaxSize`,
- the sum of the gas limit of all explicit messages is no greater than `block.BlockGasLimit`.


Note that validation of the block signature requires access to the miner worker address and
public key from the parent tipset state, so signature validation forms part of semantic validation.
Similarly, message signature validation requires lookup of the public key associated with
each message's `From` account actor in the block's parent state.
Note that validation of the block signature requires access to the miner worker address and public key from the parent tipset state, so signature validation forms part of semantic validation. Similarly, message signature validation requires lookup of the public key associated with each message's `From` account actor in the block's parent state.

## Block semantic validation

Semantic validation refers to validation that requires reference to information outside the block
header and messages themselves, in particular the parent tipset and state on which the block is built.
Semantic validation refers to validation that requires reference to information outside the block header and messages themselves. Semantic validation relates to the parent tipset and state on which the block is built.

In order to proceed to semantic validation the `FullBlock` must be assembled from the received block header retrieving its Filecoin messages. Block message CIDs can be retrieved from the network and be decoded into valid CBOR `Message`/`SignedMessage`.

In the Lotus implementation the semantic validation of a block is carried out by the `Syncer` module:

A semantically valid block must have:
{{<embed src="https://github.com/filecoin-project/lotus/blob/master/chain/sync.go" lang="go" symbol="ValidateBlock">}}

- `Parents` listed in lexicographic order of their header's `Ticket`,
- `Parents` all reference valid blocks and form a valid [Tipset](tipset),
- `ParentState` matching the state tree produced by executing the parent tipset's messages (as defined by the VM interpreter) against that tipset's parent state,
- `ParentMessageReceipts` identifying the receipt list produced by parent tipset execution, with one receipt for each unique message from the parent tipset,
- `ParentWeight` matching the weight of the chain up to and including the parent tipset,
- `Epoch` greater than that of its parents, and

Messages are retrieved through the `Syncer`. There are the following two steps followed by the `Syncer`:
1) Assemble a `FullTipSet` populated with the single block received earlier. The Block's `ParentWeight` is greater than the one from the (first block of the) heaviest tipset.
2) Retrieve all tipsets from the received Block down to our chain. Validation is expanded to every block inside these tipsets. The validation should ensure that:
- Beacon entires are ordered by their round number.
- The Tipset `Parents` CIDs match the fetched parent tipset through BlockSync.
A semantically valid block must meet all of the following requirements.
**`Parents`-Related**
- `Parents` listed in lexicographic order of their header's `Ticket`.
- `ParentStateRoot` CID of the block matches the state CID computed from the parent [Tipset](tipset).
- `ParentState` matches the state tree produced by executing the parent tipset's messages (as defined by the VM interpreter) against that tipset's parent state.
- `ParentMessageReceipts` identifying the receipt list produced by parent tipset execution, with one receipt for each unique message from the parent tipset. In other words, the Block's `ParentMessageReceipts` CID matches the receipts CID computed from the parent tipset.
- `ParentWeight` matches the weight of the chain up to and including the parent tipset.
**Time-Related**
- `Epoch` is greater than that of its `Parents`, and
- not in the future according to the node's local clock reading of the current epoch,
- blocks with future epochs should not be rejected, but should not be evaluated (validated or included in a tipset) until the appropriate epoch
- not farther in the past than the soft finality as defined by SPC [Finality](expected_consensus#finality-in-ec),
- this rule only applied when receiving new gossip blocks (i.e. from the current chain head), not when syncing to the chain for the first time (e.g.)
- `Miner` that is active in the storage power table in the parent tipset state,
- A valid `BeaconEntry` array (can be empty)
- a `Ticket` derived from the minimum ticket from the parent tipset's block headers,
- this rule only applies when receiving new gossip blocks (i.e. from the current chain head), not when syncing to the chain for the first time.
- The `Timestamp` included is in seconds that:
- must not be bigger than current time plus `ΑllowableClockDriftSecs`
- must not be smaller than previous block's `Timestamp` plus `BlockDelay` (including null blocks)
- is of the precise value implied by the genesis block's timestamp, the network's Βlock time and the Βlock's `Epoch`.

**`Miner`-Related**
- The `Miner` is active in the storage power table in the parent tipset state. The Miner's address is registered in the `Claims` HAMT of the Power Actor
- The `TipSetState` should be included for each tipset being validated.
- Every Block in the tipset should belong to different a miner.
- The Actor associated with the message's `From` address exists, is an account actor and its Nonce matches the message Nonce.
- Valid proofs that the Miner proved access to sealed versions of the sectors it was challenged for are included. In order to achieve that:
- draw randomness for current epoch with `WinningPoSt` domain separation tag.
- get list of sectors challanged in this epoch for this miner, based on the randomness drawn.
- Miner is not slashed in `StoragePowerActor`.


**`Beacon`- & `Ticket`-Related**
- Valid `BeaconEntries` should be included:
- Check that every one of the `BeaconEntries` is a signature of a message: `previousSignature || round` signed using DRAND's public key.
- All entries between `MaxBeaconRoundForEpoch` down to `prevEntry` (from previous tipset) should be included.
- A `Ticket` derived from the minimum ticket from the parent tipset's block headers,
- `Ticket.VRFResult` validly signed by the `Miner` actor's worker account public key,
- `ElectionPoStOutput` yielding winning partial tickets that were generated validly,
- `ElectionPoSt.Randomness` is well formed and appropriately drawn from a past tipset according to the PoStLookback,
- `ElectionPoSt.Proof` is a valid proof verifying the generation of the `ElectionPoSt.Candidates` from the `Miner`'s eligible sectors,
- `ElectionPoSt.Candidates` contains well formed `PoStCandidate`s each of which has a `PartialTicket` yielding a winning `ChallengeTicket` in Expected Consensus.
- a `Timestamp` in seconds that must be
- not in the future at time of reception
- of the precise value implied implied by the genesis block's timestamp, the network's block time and the block's `Epoch`,
- all SECP messages correctly signed by their sending actor's worker account key,
- a `BLSAggregate` signature that signs the array of CIDs of the BLS messages referenced by the block
with their sending actor's key.
- a valid `Signature` over the block header's fields from the block's `Miner` actor's worker account public key.
- `ElectionProof Ticket` is computed correctly by checking BLS signature using miner's key. The `ElectionProof` ticket should be a winning ticket.

**Message- & Signature-Related**
- `secp256k1` messages are correctly signed by their sending actor's (`From`) worker account key,
- A `BLSAggregate` signature is included that signs the array of CIDs of all the BLS messages referenced by the block with their sending actor's key.
- A valid `Signature` over the block header's fields from the block's `Miner` actor's worker account public key is included.
- For each message in `ValidForBlockInclusion()` the following hold:
- Message fields `Version`, `To`, `From`, `Value`, `GasPrice`, and `GasLimit` are correctly defined.
- Message `GasLimit` is under the message minimum gas cost (derived from chain height and message length).
- For each message in `ApplyMessage` (that is before a message is executed), the following hold:
- Basic gas and value checks in `checkMessage()`:
- The Message `GasLimit` is bigger than zero.
- The Message `GasPrice` and `Value` are set.
- The Message's storage gas cost is under the message's `GasLimit`.
- The Message's `Nonce` matches the nonce in the Actor retrieved from the message's `From` address.
- The Message's maximum gas cost (derived from its `GasLimit`, `GasPrice`, and `Value`) is under the balance of the Actor retrieved from message's `From` address.
- The Message's transfer `Value` is under the balance of the Actor retrieved from message's `From` address.
There is no semantic validation of the messages included in a block beyond validation of their signatures.
If all messages included in a block are syntactically valid then they may be executed and produce a receipt.
A chain sync system may perform syntactic and semantic validation in stages in order to minimize unnecessary resource expenditure.

If all of the above tests are successful, the block is marked as validated. Ultimately, an invalid block must not be propagated further or validated as a parent node.
Loading

0 comments on commit d2f3a5b

Please sign in to comment.