From 5b979287639568f07458563d268c48bc0904b73f Mon Sep 17 00:00:00 2001 From: adaki2004 Date: Tue, 5 Sep 2023 14:30:23 +0200 Subject: [PATCH 1/4] Add off-chain proof market explanation --- .../website/pages/docs/concepts/overview.mdx | 49 ++++++------------- 1 file changed, 14 insertions(+), 35 deletions(-) diff --git a/packages/website/pages/docs/concepts/overview.mdx b/packages/website/pages/docs/concepts/overview.mdx index 4c6904b80a..35a7146038 100644 --- a/packages/website/pages/docs/concepts/overview.mdx +++ b/packages/website/pages/docs/concepts/overview.mdx @@ -54,7 +54,7 @@ the same mechanism is used on Ethereum it allows Taiko to be Ethereum equivalent (with some small implementation detail changes) even for this part of its network, which is not obviously the case for L2s. -## EIP-1559 powered prover fees +## Off-chain proof market Proving blocks requires significant compute power to calculate the proof to submit and verify the proof on Ethereum. Provers need @@ -71,40 +71,19 @@ to pay for a proof is not obvious however: 4. The proof generation cost depends on how fast a proof needs to be generated. -Because the proving cost impacts the transaction fees -paid by the users, the goal is to pay only as much as -required for the network to function well. This means not -underpaying provers because blocks may remain unproven, -but certainly also not overpaying provers so that it doesn’t -make sense to incur very high costs to try and generate -proofs as quickly as absolutely possible. A good balance is -key to a well working solution that takes into account the -needs of the different network participants. -It’s clear that a fixed proving fee does not work. The -protocol should also not be dependent on a single prover -for a block because this will put too much power in the -hands of a single entity that can impact the stable progress -of the chain. - -The network, somehow, has to find the correct price between -two resources where the demand/supply is ever changing. -We can model this problem as a market between the proving -fee (per gas) per proof delay (per time unit), striking -a dynamic balance between proving cost and proof delay. -An additional complication is that the protocol expects -the block proposer to pay the proving fee at block proposal -time. As such, the baseFee of this model is used to charge -the proposer of a block using the total gas used in the block. -This is only an estimate of the actual cost because the -actual cost is only known when the proof is submitted. If -the estimated cost was too high the difference is returned -to the block proposer and the baseFee is decreased. If -the estimated cost was too low extra Taiko tokens are -minted to make up the difference and the baseFee is -increased. To lower the chance that the estimated cost is too -low and extra Taiko tokens need to be minted, a slightly -higher baseFee can be charged to the proposer than the -one predicted by the model. +In the pursuit of optimizing network efficiency and balancing costs, the ecosystem introduces a robust off-chain proof market. Proposers, on a per-block basis, actively seek potential proof service providers through this dynamic marketplace. A pivotal component of this setup is the publicly exposed API, providing proposers with the means to query and engage with available proof providers off-chain. + +When an agreement is reached concerning the proving fee for a specific block, the chosen proof service provider is then tasked with granting a cryptographic signature to the proposer. This signature serves as a binding commitment, signifying the prover's dedication to delivering the proof within the agreed-upon timeframe. + +Provers within this off-chain proof market come in two primary forms: Externally Owned Accounts (EOA) and contracts, often referred to as Prover pools. To qualify as a Prover pool, a contract must adhere to specific criteria, implementing either the IProver interface, as previously defined by Taiko, or the IERC1271 (isValidSignature) interface. + +Upon a proposer's submission of a block, the signature granted by the chosen provider is subjected to verification. Any deviations result in a reverted transaction. + +As an additional incentive for proposers, the system incorporates the issuance of TKO tokens. This serves as an extra motivator, as proposing blocks alone may not always prove profitable, especially when considering Ethereum's on-chain fees plus the proving fee. The issuance of TKO tokens operates on a dynamic 'emission rate per second,' comparing each block proposal to the last. + +The reward depends on the proof service provider (and the agreement). For EOAs and Prover pools that implement the IERC1271 interface, the reward is disbursed in ETH. However, in cases where providers implement the IProver interface, the prover fee can be ETH, any other ERC20 tokens, or even NFTs, based on the negotiated terms. + +To add a layer of security and commitment to the process, provers must provide a substantial amount of TKO tokens per block, effectively serving as insurance. In the unfortunate event of a failure to deliver the proof within the given time, a portion, specifically 1/4, is directed to the actual prover, while the remaining 3/4 are permanently burnt. Conversely, successful and timely proof delivery ensures the return of these tokens to the Prover. ## EIP-4844 scaling via blob data From 1641919e8ae199dfb0d00e65b49e8a6267af2e96 Mon Sep 17 00:00:00 2001 From: adaki2004 Date: Tue, 5 Sep 2023 18:08:50 +0200 Subject: [PATCH 2/4] Simplify explanation --- .../website/pages/docs/concepts/proposing.mdx | 90 ++++--------------- .../website/pages/docs/concepts/proving.mdx | 6 +- 2 files changed, 17 insertions(+), 79 deletions(-) diff --git a/packages/website/pages/docs/concepts/proposing.mdx b/packages/website/pages/docs/concepts/proposing.mdx index 1135d8dbcf..8c898ffed5 100644 --- a/packages/website/pages/docs/concepts/proposing.mdx +++ b/packages/website/pages/docs/concepts/proposing.mdx @@ -8,71 +8,20 @@ On Taiko, the next L2 state is known immediately and deterministically at the ti - 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](./proposing#anchor-transaction) to create a Taiko L2 block. - IF any transaction in the list is invalid, an empty block (with only the anchor tx) is created on L2. -## Intrinsic validity functions +## Building the blocks -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 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. The high level overview of creating L2 blocks as follows: -- 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 map the txList to an L2 block on Taiko. If a block passes the proposed block validity function but later fails the transaction list validity function, an empty block will be created. - -### Proposed block intrinsic validity function - -The formal specification of the proposed block intrinsic can be found in the [whitepaper](https://taikoxyz.github.io/taiko-mono/taiko-whitepaper.pdf), 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 $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, an empty block will be created on L2 (with only the anchor tx). +1. The system starts by creating a new L2 block with an anchor transaction. This anchor transaction is always the first transaction in the block even if the block is empty. (More about anchor transactions in the next section.) +2. There are validity checks which are performed on node (or sometimes on protocol) level as well: +2.1 Asserts that the length of the transaction list does not exceed a predefined maximum (MAX_TX_LIST_BYTES), ensuring that the list is within the limits. +2.2 The transaction list is (RLP) decoded into a list of transactions (txList). If the bytes are not decodeable it will result in an empty block. +2.3 The amount of gas required to include transactions are available. (If a transaction cannot fit into a block, it is simply excluded from it, but the block is still valid with other transactions.) +2.4 The transaction signature is valid. +2.5 The transaction nonce is valid. +2.6 The sender account has no contract code deployed (EIP-3607). +2.7 The transaction's gas limit is no smaller than the intrinsic gas. +2.8. The sender has enought balance to cover the transaction (gasLimit * gasPrice + tx.value). ## Anchor transaction @@ -80,14 +29,7 @@ The anchor transaction is a way for the protocol to make use of the programmabil 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$, `l1Hash` $C_h$, `l1SignalRoot`, and `parentGasUsed` (data inherited from L1) to the storage trie. These values can be used by bridges to validate cross-chain messages. -2. Comparing $ρ_{i−1}$, 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](https://taikoxyz.github.io/taiko-mono/taiko-whitepaper.pdf)) can be simplified to: - $$ - \begin{aligned} - B &≡ (H, T, U) \\ - &≡ M(δ, θ, B, \dot{B}) \\ - &≡ M(δ, θ, C, L) - \end{aligned} - $$ +1. Persisting `l1Height`, `l1Hash`, `l1SignalRoot`, and `parentGasUsed` (data inherited from L1) to the storage trie. These values can be used by bridges to validate cross-chain messages. +2. Comparing the public input hash stored by the previous block, with the hash of the previous 255 block hashes. 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 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. Calculating the EIP-1559 `basefee` which will be used on L2. \ No newline at end of file diff --git a/packages/website/pages/docs/concepts/proving.mdx b/packages/website/pages/docs/concepts/proving.mdx index 263f5e1540..25be8258bb 100644 --- a/packages/website/pages/docs/concepts/proving.mdx +++ b/packages/website/pages/docs/concepts/proving.mdx @@ -3,7 +3,7 @@ import { Callout } from "nextra-theme-docs"; # Proving Taiko blocks -The purpose of proving blocks is to give certainty to bridges about the execution that happened in the rollup. To rely on some state that happened inside of the rollup, a bridge will want a proof that everything was done correctly. On Taiko you can run a node as a prover and prove blocks, permissionlessly. This means that you can examine the proposed blocks on the TaikoL1 contract, and generate proofs for them. Currently, any prover can create proofs for proposed blocks. This means that the number of "state transitions" has no upper bound, because we don't know what is the correct state transition yet. Only first prover with a valid proof of the correct state transition (state transition) will receive the reward of TTKO. +The purpose of proving blocks is to give certainty to bridges about the execution that happened in the rollup. To rely on some state that happened inside of the rollup, a bridge will want a proof that everything was done correctly. On Taiko you can run a node as a prover and prove blocks, permissionlessly. This means that you can examine the proposed blocks on the TaikoL1 contract, and generate proofs for them. Currently, any prover can create proofs for proposed blocks. This means that the number of "state transitions" has no upper bound, because we don't know what is the correct state transition yet. Only first prover with a valid proof of the correct state transition will receive the reward of `ETH` (and possibly any `ERC20` or even NFTs if the Prover pool implementation favors it). ## Verified blocks and parallel proving @@ -58,10 +58,6 @@ Currently, you only need a single proof from any prover to verify a block. The oracle prover is a prover from a unique address (our own address) that is able to override the community prover. This is a safety mechanism we have in place while the ZK-EVM is still in development and in case an invalid block was marked as verified from a community proof. -### Oracle prover - -A oracle prover generates a fake proof to mark a block as verified. We only require a real proof to be generated every N blocks. Otherwise, we accept a fake, oracle proof, and mark the block as verified. This is a temporary testnet feature to reduce the cost for community provers. - ### The proof cooldown period We have a proof cooldown period which is an interval of time we set after fully verifying a block. The reason we do that is to allow for a fault proof to come in, once we have a multi-prover system set in place. From 02f82009e091ca22044454676c58dcbf252f9008 Mon Sep 17 00:00:00 2001 From: adaki2004 Date: Wed, 6 Sep 2023 12:46:15 +0200 Subject: [PATCH 3/4] Adjusted based on recommendations --- packages/website/pages/docs/concepts/overview.mdx | 2 +- packages/website/pages/docs/concepts/proposing.mdx | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/website/pages/docs/concepts/overview.mdx b/packages/website/pages/docs/concepts/overview.mdx index 35a7146038..6c3d096259 100644 --- a/packages/website/pages/docs/concepts/overview.mdx +++ b/packages/website/pages/docs/concepts/overview.mdx @@ -81,7 +81,7 @@ Upon a proposer's submission of a block, the signature granted by the chosen pro As an additional incentive for proposers, the system incorporates the issuance of TKO tokens. This serves as an extra motivator, as proposing blocks alone may not always prove profitable, especially when considering Ethereum's on-chain fees plus the proving fee. The issuance of TKO tokens operates on a dynamic 'emission rate per second,' comparing each block proposal to the last. -The reward depends on the proof service provider (and the agreement). For EOAs and Prover pools that implement the IERC1271 interface, the reward is disbursed in ETH. However, in cases where providers implement the IProver interface, the prover fee can be ETH, any other ERC20 tokens, or even NFTs, based on the negotiated terms. +The reward depends on the proof service provider and the agreement. For EOAs and Prover pools that implement the IERC1271 interface, the reward is disbursed in ETH. However, in cases where providers implement the IProver interface, the prover fee can be ETH, any other ERC20 tokens, or even NFTs, based on the negotiated terms. To add a layer of security and commitment to the process, provers must provide a substantial amount of TKO tokens per block, effectively serving as insurance. In the unfortunate event of a failure to deliver the proof within the given time, a portion, specifically 1/4, is directed to the actual prover, while the remaining 3/4 are permanently burnt. Conversely, successful and timely proof delivery ensures the return of these tokens to the Prover. diff --git a/packages/website/pages/docs/concepts/proposing.mdx b/packages/website/pages/docs/concepts/proposing.mdx index 8c898ffed5..2609f322b8 100644 --- a/packages/website/pages/docs/concepts/proposing.mdx +++ b/packages/website/pages/docs/concepts/proposing.mdx @@ -10,18 +10,18 @@ On Taiko, the next L2 state is known immediately and deterministically at the ti ## Building the blocks -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. The high level overview of creating L2 blocks as follows: +The Ethereum yellow paper has well-defined rules to compute the state transition. We use these same rules to take a proposed block, and compute the post-block state on Taiko. The high level overview of creating L2 blocks as follows: 1. The system starts by creating a new L2 block with an anchor transaction. This anchor transaction is always the first transaction in the block even if the block is empty. (More about anchor transactions in the next section.) -2. There are validity checks which are performed on node (or sometimes on protocol) level as well: +2. There are validity checks performed at the node (or sometimes protocol) level as well: 2.1 Asserts that the length of the transaction list does not exceed a predefined maximum (MAX_TX_LIST_BYTES), ensuring that the list is within the limits. 2.2 The transaction list is (RLP) decoded into a list of transactions (txList). If the bytes are not decodeable it will result in an empty block. -2.3 The amount of gas required to include transactions are available. (If a transaction cannot fit into a block, it is simply excluded from it, but the block is still valid with other transactions.) +2.3 The amount of gas required to include transactions is available. (If a transaction cannot fit into a block, it is simply excluded from it, but the block is still valid with other transactions.) 2.4 The transaction signature is valid. 2.5 The transaction nonce is valid. 2.6 The sender account has no contract code deployed (EIP-3607). 2.7 The transaction's gas limit is no smaller than the intrinsic gas. -2.8. The sender has enought balance to cover the transaction (gasLimit * gasPrice + tx.value). +2.8. The sender has enough balance to cover the transaction (gasLimit * gasPrice + tx.value). ## Anchor transaction From 36cbf1c3a9be317b03653ca9fb99e8f1ac102df8 Mon Sep 17 00:00:00 2001 From: adaki2004 Date: Wed, 6 Sep 2023 16:17:03 +0200 Subject: [PATCH 4/4] Brecht comments --- packages/website/pages/docs/concepts/proposing.mdx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/website/pages/docs/concepts/proposing.mdx b/packages/website/pages/docs/concepts/proposing.mdx index 2609f322b8..0dc11f8137 100644 --- a/packages/website/pages/docs/concepts/proposing.mdx +++ b/packages/website/pages/docs/concepts/proposing.mdx @@ -29,7 +29,6 @@ The anchor transaction is a way for the protocol to make use of the programmabil 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`, `l1Hash`, `l1SignalRoot`, and `parentGasUsed` (data inherited from L1) to the storage trie. These values can be used by bridges to validate cross-chain messages. -2. Comparing the public input hash stored by the previous block, with the hash of the previous 255 block hashes. 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 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. Calculating the EIP-1559 `basefee` which will be used on L2. \ No newline at end of file +1. Persisting `l1Height`, `l1Hash` and `l1SignalRoot` to the storage trie. These values can be used by bridges to validate cross-chain messages. +2. Ensuring that the previous 256 block hashes that are exposed to the EVM are correct. +3. Calculating the EIP-1559 `basefee` which will be used on L2. \ No newline at end of file