Skip to content

Commit

Permalink
docs(website): add more docs (#13316)
Browse files Browse the repository at this point in the history
Co-authored-by: David <[email protected]>
  • Loading branch information
dionysuzx and davidtaikocha authored Mar 18, 2023
1 parent 5f99653 commit 4cabf1b
Show file tree
Hide file tree
Showing 17 changed files with 714 additions and 251 deletions.
409 changes: 409 additions & 0 deletions packages/website/excalidraw/taiko-nodes.excalidraw

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions packages/website/next.config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const withNextra = require("nextra")({
defaultShowCopyCode: true,
latex: true,
theme: "nextra-theme-docs",
themeConfig: "./theme.config.tsx",
});
Expand Down
10 changes: 8 additions & 2 deletions packages/website/pages/docs/concepts/_meta.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
{
"block-proposal-and-verification": {
"title": "Block proposal & verification"
"overview": {
"title": "Overview"
},
"creating-l2-blocks": {
"title": "Creating L2 blocks"
},
"bridging": {
"title": "Bridging"
},
"taiko-nodes": {
"title": "Taiko nodes"
}
}
11 changes: 11 additions & 0 deletions packages/website/pages/docs/concepts/creating-l2-blocks/_meta.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"creating-l2-blocks": {
"title": "Creating L2 blocks"
},
"intrinsic-validity-functions": {
"title": "Intrinsic validity functions"
},
"anchor-transaction": {
"title": "Anchor transaction"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
The anchor transaction is a way for the protocol to make use of the programmability of the EVM (which we already need to be able to proof) to enforce certain protocol behavior. We can add additional tasks to anchor transactions to enrich Taiko’s functionalities by writing standard smart contract code (instead of requiring more complicated changes to Taiko’s ZK-EVM and node subsystems).

The anchor transaction is required to be the first transaction in a Taiko block (which is important to make the block deterministic). The anchor transaction is currently used as follows:
1. Persisting `l1Height` $C_a$ and `l1Hash` $C_h$, data inherited from L1, to the storage trie. These values can be used by bridges to validate cross-chain messages.
2. Comparing $ρ_{i1}$, the public input hash stored by the previous block, with `KEC(i − 1, d, h[2..256])`. The anchor transaction will throw an exception if such comparison fails. The protocol requires the anchor transaction to execute successfully and will not accept a proof for a block that fails to do so. Note that the genesis block has $ρ_0$ ≡ `KEC(0, d, [0, ..., 0])`.
3. Persisting a new public input hash $ρ_i$ ≡ `KEC(i, d, h[1..255])` to the storage trie for the next block to use. This allows transactions, in the current and all following blocks, to access these public input data with confidence as their values are now covered by ZK-EVM’s storage proof.
4. With anchoring, the block mapping function `M` (defined in the [whitepaper](/docs/resources/whitepaper)) can be simplified to:
$$$
\begin{aligned}
B &≡ (H, T, U) \\
&≡ M(δ, θ, B, \dot{B}) \\
&≡ M(δ, θ, C, L)
\end{aligned}
$$$
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
On Taiko, the next L2 state is known immediately and deterministically at the time a block is proposed to the TaikoL1 contract. After a block is proposed, a series of checks are done to compute this post-L2 state:

1. Block is proposed by any proposer (permissionlessly).
2. Block level properties are checked validity by TaikoL1 contract ([proposed block intrinsic validity function](./intrinsic-validity-functions#proposed-block-intrinsic-validity-function)).
3. Proposed block is downloaded by a Taiko node, and the transaction list is parsed over and checked for validity ([transaction list intrinsic validity function](./intrinsic-validity-functions#transaction-list-intrinsic-validity-function)).
- IF every transaction in the list is valid, an ordered subset of the list is created by skipping over transactions which have an invalid nonce or the sender has too little Ether balance to pay for the transaction. This ordered subset is used along with the [anchor transaction](./anchor-transaction) to create a Taiko L2 block.
- IF any transaction in the list is invalid, the block is proven to be invalid.
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
The Ethereum yellow paper has a well defined set of rules to compute the state transition. We use these same rules to take a proposed block, and compute the post-block state on Taiko. A proposed block on Taiko has two parts:

- The block metadata
- A list of transactions (stored in a blob, and the block metadata stores the hash to this blob)

We divide the yellow paper validity checks into two parts:

- **Proposed block** intrinsic validity function
- **Transaction list** intrinsic validity function

A proposed block must pass these two checks in order to construct an L2 block on Taiko. If a block passes the proposed block validity function but later fails the transaction list validity function, it will be proven as invalid.

## Proposed block intrinsic validity function

The formal specification of the proposed block intrinsic can be found in the [whitepaper](/docs/resources/whitepaper), but on a high level, the proposed block intrinsic validity function checks that the block is valid except for transaction list validity checks. This is separated because on TaikoL1, the transaction list is not known and stored as a data blob. It would also be too expensive to do these checks on L1.

| Name | Symbol | Meaning |
| ----------------------- | ----------------- | -------------------------------------------------------------------------------------------------------- |
| **Block Metadata** | $C$ | The block metadata. |
| **id** | $C_i$ | A value equal to the number of proposed blocks. The genesis block has an id of zero. |
| **beneficiary** | $C_c$ | The 20-byte address to which all transaction fees in the block will be transferred. |
| **timestamp** | $C_s$ | The timestamp used in the block, set to the enclosing L1 timestamp. |
| **mixHash** | $C_m$ | The mixHash value used in the block, set to the enclosing L1 mixHash. |
| **txListHash** | $C_t$ | The Keccak-256 hash of this block’s txList (KZG commitment after EIP-4844). |
| **l1Height** | $C_a$ | The enclosing L1 block’s parent block number. |
| **l1Hash** | $C_h$ | The enclosing L1 block’s parent block hash. |
| **TaikoL1** | $R$ | The TaikoL1 contract. |
| **numProposedBlocks** | $R_i$ | The current number of proposed blocks (the `id` for the next proposed block is `numProposedBlocks + 1`). |
| **lastVerifiedBlockId** | $R_f$ | The last verified block id. |
| **txList** | $L$ | The list of transactions in a proposed block. |
| **txListSizeInBytes** | $\lVert L \rVert$ | The transaction list size in bytes. |

The proposed block intrinsic validity function checks that all these conditions are met:

1. $R_i \le R_f + K_{MaxNumBlocks}$ (the block id is not too far ahead)
2. $\lVert L \rVert \gt 0$ (transaction list is not empty)
3. $\lVert L \rVert \le K_{MaxTxListSizeInBytes}$ (transaction list does not exceed the maximum size)
4. $C_c \ne 0$ (beneficiary is not zero)
5. $C_i = R_i$ (block id is correct)
6. $C_s = \text{TIMESTAMP}$ (timestamp is correct)
7. $C_m = \text{DIFFICULTY}$ (mixHash is correct)
8. $C_t \ne 0$ (txListHash is not zero)
9. $C_a = \text{NUMBER} - 1$ (l1Height is correct)
10. $C_h = \text{BLOCKHASH}(C_a)$ (l1Hash is correct)

## Transaction list intrinsic validity function

The transaction list intrinsic validity function checks that the transaction list is valid and each transaction in the list is valid.

A transaction list is valid if and only if:

1. The transaction list is well-formed RLP, with no additional trailing bytes (rule #1 in Ethereum yellow paper).
2. The transaction list is no larger than than $K_{TxListMaxBytes}$.
3. The sum of all transactions' gas limit is no larger than the protocol constant $K_{BlockMaxGasLimit}$.
4. The total number of transactions is no larger than the protocol constant $K_{BlockMaxTxs}$.

A transaction is valid if and only if:

1. The transaction is well-formed RLP, with no additional trailing bytes (rule #1 in the Ethereum yellow paper).
2. The transaction's signature is valid (rule #2 in Ethereum yellow paper).
3. The transaction's gas limit is no smaller than the intrinsic gas $K_{TxMinGasLimit}$ (rule #5 in the Ethereum yellow paper).

If any of these fails, a throwaway block will instead be created on L2 whose first transaction is `invalidateBlock`, and this will prove the proposed block as invalid on TaikoL1.
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
# Block proposal & verification

Taiko aims to build a secure, decentralized, and permissionless rollup on Ethereum. These requirements dictate the following properties:

1. All block data required to reconstruct the post-block state needs to be put on Ethereum so it is publicly available. If this would not be the case, Taiko would not only fail to be a rollup but would also fail to be fully decentralized. This data is required so that anyone can know the latest chain state and so that useful new blocks can be appended to the chain. For the decentralization of the proof generation Taiko requires an even stronger requirement: all block data needed to be able to re-execute all work in a block in a step-by-step fashion needs to be made public. This makes it possible for provers to generate a proof for a block using only publicly known data.
2. Creating and proposing blocks should be a fast and efficient process. Anyone should be able to add blocks to the chain on a level playing field, having access to the same chain data at all times. Proposers, of course, should be able to compete on e.g. transaction fees and [Maximal Extractable Value (MEV)](https://ethereum.org/en/developers/docs/mev/).

We achieve this by splitting the block submission process in two parts:

### Block proposal
## Block proposal

When a block gets proposed the block data is published on Ethereum and the block is appended to the proposed blocks list stored in the [TaikoL1](/docs/reference/contract-documentation/L1/TaikoL1) contract. Once registered, the protocol ensures that _all_ block properties are immutable. This makes the block execution _deterministic_: the post-block state can now be calculated by anyone. As such, the block is immediately _verified_. This also ensures that no one knows more about the latest state than anyone else, as that would create an unfair advantage.

### Block verification
## Block verification

Because the block should already be verified once proposed, it should _not_ be possible for the prover to have any impact on how the block is executed and what the post-block state is. All relevant inputs for the proof generation are verified on L1 directly or indirectly to achieve deterministic block transitions. As all proposed blocks are deterministic, they can be proven in parallel, because all intermediate states between blocks are known and unique. Once a proof is submitted for the block and its parent block, we call the block _on-chain verified_.
99 changes: 99 additions & 0 deletions packages/website/pages/docs/concepts/taiko-nodes.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# Overview
There are two parts to a Taiko node, which are connected over the engine API:
- `taiko-geth`
- `taiko-client`

![taiko nodes diagram](/images/diagrams/taiko-nodes.png)

## Taiko geth

The [taiko-geth](https://github.com/taikoxyz/taiko-geth) repo is a fork of [go-ethereum](https://github.com/ethereum/go-ethereum) with some changes according to Taiko protocol, it serves as a L2 execution engine, which needs to be coupled to a consensus client (in Taiko network, this will be the taiko client's driver software), like L1 ethereum execution engines, it will listen to new L2 transactions broadcasted in the L2 network, executes them in EVM, and holds the latest state and database of all current L2 data.

## Taiko client

The compiled binary `bin/taiko-client` is the main entrypoint which includes three sub-commands:

- `driver`: keep the L2 execution engine's chain in sync with the `TaikoL1` contract, by directing the L2 [execution engine](https://ethereum.org/en/glossary/#execution-client).
- `proposer`: propose new transactions from the L2 execution engine's transaction pool to the `TaikoL1` contract.
- `prover`: request ZK proofs from the zkEVM, and send transactions to prove the proposed blocks are valid or invalid.

### Driver

Taiko client's driver software serves as an L2 consensus client. It will listen for new L2 blocks from the Taiko layer 1 protocol contract, then direct the connected L2 execution engine to insert them into its local chain through the Engine API.

#### Engine API

Driver directs a L2 execution engine to insert new blocks or reorg the local chain through the [Engine API](https://github.com/ethereum/execution-apis/blob/main/src/engine/specification.md).

#### Chain synchronization process

> NOTE: The Taiko protocol allows a block's timestamp to be equal to its parent block's timestamp, which differs from the original Ethereum protocol. So it's fine that there are two `TaikoL1.proposeBlock` transactions included in one L1 block.
Driver will inform the L2 execution engine Taiko protocol contract's latest verified L2 head, and try to let it catch up the latest verified L2 block through P2P at first. Driver will monitor the execution engine's sync progress, if it is not able to make any new sync progress in a period of time, driver will switch to insert the verified blocks to its local chain through the Engine API one by one.

After the L2 execution engine catches up the latest verified L2 head, driver will subscribe to `TaikoL1.BlockProposed` events, and when a new pending block is proposed:

1. Get the corresponding `TaikoL1.proposeBlock` L1 transaction.
2. Decode the txList and block metadata from the transaction's calldata.
3. Check whether the txList is valid based on the rules defined in Taiko protocol.

If the txList is **valid**:

4. Assemble a deterministic `TaikoL2.anchor` transaction based on the rules defined in the protocol, and put it as the first transaction in the proposed txList.
5. Use this txList and the decoded block metadata to assemble a deterministic L2 block.
6. Direct L2 execution engine to insert this assembled block and set it as the current canonical chain's head via the Engine API.

If the txList is **invalid**:

4. Create a `TaikoL2.invalidateBlock` transaction and then assemble a L2 block only including this transaction.
5. Direct the L2 execution engine to insert this block, but does not set it as the chain's head via the Engine API.

> NOTE: For more detailed information about: block metadata, please see `5.2.2 Block Metadata` in the white paper.
> NOTE: For more detailed information about txList validation rules, please see `5.3.1 Validation` in the white paper.
> NOTE: For more detailed information about the `TaikoL2.anchor` transaction and proposed block's determination, please see `5.4.1 Construction of Anchor Transactions` in the white paper.
### Proposer

Taiko client's proposer software will fetch pending transactions in a L2 execution engine's mempool intervally, then try to propose them to the Taiko layer 1 protocol contract.

#### Proposing strategy

Since tokenomics have not been fully implemented in the Taiko protocol, the current proposing strategy is simply based on time interval.

#### Proposing process

Proposing a block involves a few steps:

1. Fetch the pending transactions from the L2 execution engine through the `txpool_content` RPC method.
2. If there are too many pending transactions in the L2 execution engine, split them into several smaller txLists. This is because the Taiko protocol restricts the max size of each proposed txList.
3. Commit hashes of the txLists by sending `TaikoL1.commitBlock` transactions to L1.
4. Wait for `TaikoData.Config.commitConfirmations` (currently `0`) L1 blocks confirmations.
5. Propose all splitted txLists by sending `TaikoL1.proposeBlock` transactions.

### Prover

#### Proving strategy

Since tokenomics have not been fully implemented in the Taiko protocol, the prover software currently proves all proposed blocks.

#### Proving process

When a new block is proposed:

1. Get the `TaikoL1.proposeBlock` L1 transaction calldata, decode it, and validate the txList. Just like what the `driver` software does.
2. Wait until the corresponding block is inserted by the L2 execution engine's `driver` software.
3. Generate a ZK proof for that block asynchronously.

If the proposed block has a valid txList:

4. Generate the merkel proof of the block's `TaikoL2.anchor` transaction to prove its existence in the `block.txRoot`'s [MPT](https://ethereum.org/en/developers/docs/data-structures-and-encoding/patricia-merkle-trie/), and also this transaction receipt's merkel proof in the `block.receiptRoot`'s MPT from the L2 execution engine.
5. Submit the `TaikoL2.anchor` transaction's RLP encoded bytes, its receipt's RLP encoded bytes, generated merkel proofs, and ZK proof to prove this block **valid**, by sending a `TaikoL1.proveBlock` transaction.

If the proposed block has an invalid txList:

4. Generate the merkel proof of the block's `TaikoL2.invalidateBlock` transaction receipt to prove its existence in the `block.receiptRoot`'s MPT from the L2 execution engine.
5. Submit the `TaikoL2.invalidateBlock` transaction receipt's RLP encoded bytes, generated merkel proof, and ZK proof to prove this block **invalid**, by sending a `TaikoL1.proveBlockInvalid` transaction.

> NOTE: For more information about why we need these merkel proofs when proving, please see `5.5 Proving Blocks` in the white paper.
2 changes: 0 additions & 2 deletions packages/website/pages/docs/guides/configure-wallet.mdx
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import AddEthereumChainButton from "../../../components/AddEthereumChainButton";

## Summary

These steps will help you connect your wallet to the Taiko A1 testnet. There are two networks to configure your wallet with: **Ethereum A1** and **Taiko A1**.

## Prerequisites
Expand Down
2 changes: 0 additions & 2 deletions packages/website/pages/docs/guides/deploy-a-contract.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
## Summary

These steps will show you how to deploy a smart contract to Taiko A1 using Foundry. Read the [Foundry Book](https://book.getfoundry.sh/getting-started/first-steps) for the latest docs on Foundry.

## Prerequisites
Expand Down
2 changes: 0 additions & 2 deletions packages/website/pages/docs/guides/request-from-faucet.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
## Summary

These steps will help you receive testnet tokens from the faucet.

## Prerequisites
Expand Down
Loading

0 comments on commit 4cabf1b

Please sign in to comment.