|
| 1 | +# QGB Fraud Proofs |
| 2 | + |
| 3 | +## Celestiums Intro |
| 4 | + |
| 5 | +A Celestium is a blockchain that uses Celestia for data availability but settles on any EVM chain. The QGB operates by having the Celestia validator set periodically sign over batched data commitments and validator set updates, which are relayed an EVM smart contract. The data commitments are stored in the EVM chain's state, and can be used to prove inclusion of any data historically posted to Celestia. |
| 6 | + |
| 7 | +## Fraud Proofs |
| 8 | + |
| 9 | +Fraud proofs can be used to inform light clients (including on-chain smart contract light clients) in the case of an invalid rollup state transition or unavailable rollup block data—specifically rollup block data that is claimed to be on Celestia but is not. They rely on rollup full nodes getting the data that was published to Celestia, and executing all the state transitions to verify the rollup state. If they discover an invalid state transition or unavailable rollup block, they emit a fraud proof with the necessary information to convince light clients that fraud happened. This allows for trust-minimized light clients, as the network only needs one honest full node to create the fraud proof and propagate it. |
| 10 | + |
| 11 | +## Rollup Header |
| 12 | + |
| 13 | +Rollups can adopt many approaches to prove that fraud occurred. One of which could be having the following fields in the rollup header: |
| 14 | + |
| 15 | +- Rollup block state root |
| 16 | +- A sequence of spans in Celestia: which references where the rollup data was published in the Celestia chain. |
| 17 | + |
| 18 | +> [!NOTE] |
| 19 | +> The sequence of spans can be defined using the following: `height`, `start index`, and `length` in the Celestia block, in the case of a single Celestia block. However, it could be generalized to span over multiple blocks. |
| 20 | +
|
| 21 | +For the rest of the document, we will suppose that the sequence of spans only references one Celestia block. |
| 22 | + |
| 23 | +## Proving Unavailable Data |
| 24 | + |
| 25 | +By construction, the rollup block data **is the sequence of spans defined in the header**. Thus to prove that the rollup data is unavailable, it is necessary and sufficient to show that the sequence of spans doesn't belong to the Celestia block, i.e. the span is out of bounds. |
| 26 | + |
| 27 | +We could prove that via creating a binary [Merkle proof](https://github.com/celestiaorg/celestia-core/blob/c3ab251659f6fe0f36d10e0dbd14c29a78a85352/crypto/merkle/proof.go#L19-L31) of any row/column to the Celestia data root. This proof will provide the `total` which is the number of rows/columns in the extended data square. This can be used to calculate the square size. |
| 28 | + |
| 29 | +Then, we will use that information to check if the provided transaction index, in the header, is out of the square size bounds. |
| 30 | + |
| 31 | +For the data root, we will use a binary Merkle proof to prove its inclusion in a data root tuple root that was committed to by the QGB smart contract. More on this in [here](#1-data-root-inclusion-proof). |
| 32 | + |
| 33 | +## Proving an Invalid State Transition |
| 34 | + |
| 35 | +In order to prove an invalid transaction in the rollup, we need to prove the following: |
| 36 | + |
| 37 | +- Prove that the transaction was posted to Celestia, and |
| 38 | +- Prove that the transaction is invalid. This is left to the rollup to define. |
| 39 | + |
| 40 | +The first part, proving that the transaction was posted to Celestia, can be done in three steps: |
| 41 | + |
| 42 | +1. Prove that the data root tuple is committed to by the QGB smart contract |
| 43 | +2. Verify inclusion proof of the transaction to Celestia data root |
| 44 | +3. Prove that the transaction is in the rollup sequence spans |
| 45 | + |
| 46 | +### 1. Data root inclusion proof |
| 47 | + |
| 48 | +To prove the data root is committed to by the QGB smart contract, we will need to provide a Merkle proof of the data root tuple to a data root tuple root. This can be created using the [`data_root_inclusion_proof`](https://github.com/celestiaorg/celestia-core/blob/c3ab251659f6fe0f36d10e0dbd14c29a78a85352/rpc/client/http/http.go#L492-L511) query. |
| 49 | + |
| 50 | +### 2. Transaction inclusion proof |
| 51 | + |
| 52 | +To prove that a rollup transaction is part of the data root, we will need to provide two proofs: a namespace Merkle proof of the transaction to a row root. This could be done via proving the shares that contain the transaction to the row root using a namespace Merkle proof. And, a binary Merkle proof of the row root to the data root. |
| 53 | + |
| 54 | +These proofs can be generated using the [`ProveShares`](https://github.com/celestiaorg/celestia-core/blob/c3ab251659f6fe0f36d10e0dbd14c29a78a85352/rpc/client/http/http.go#L526-L543) query. |
| 55 | + |
| 56 | +### 3. Transaction part of the rollup sequence |
| 57 | + |
| 58 | +To prove that a transaction is part of the rollup sequence of spans, we take the authenticated share proof and use the shares begin/end key to define the share position in the row. |
| 59 | + |
| 60 | +Then, we use the row proof to get the row index in the extended Celestia square and get the index of the share in row major order: |
| 61 | + |
| 62 | +```solidity |
| 63 | +uint256 shareIndexInRow = shareProof.shareProofs[0].beginKey; |
| 64 | +uint256 shareIndexInRowMajorOrder = shareIndexInRow + shareProof.rowProofs[0].numLeaves * shareProof.rowProofs[0].key; |
| 65 | +``` |
| 66 | + |
| 67 | +Finally, we can compare the computed index with the rollup header sequence of spans, and be sure that the share/transaction is part of the rollup data. |
| 68 | + |
| 69 | +Check the `RollupInclusionProofs.t.sol` for an example. |
0 commit comments