Skip to content

Commit 22b310c

Browse files
rach-idadlerjohnevan-forbes
authored
docs: add inclusion proofs documentation (#160)
<!-- Please read and fill out this form before submitting your PR. Please make sure you have reviewed our contributors guide before submitting your first PR. --> ## Overview Closes #143 and #193 ## Checklist <!-- Please complete the checklist to ensure that the PR is ready to be reviewed. IMPORTANT: PRs should be left in Draft until the below checklist is completed. --> - [ ] New and updated code has appropriate documentation - [ ] New and updated code has new and/or updated testing - [ ] Required CI checks are passing - [ ] Visual proof for any user facing features like CLI or documentation updates - [ ] Linked issues closed with keywords --------- Co-authored-by: John Adler <adlerjohn@users.noreply.github.com> Co-authored-by: Evan Forbes <42654277+evan-forbes@users.noreply.github.com>
1 parent aa54699 commit 22b310c

File tree

2 files changed

+651
-0
lines changed

2 files changed

+651
-0
lines changed

docs/inclusion-proofs.md

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
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

Comments
 (0)