Skip to content

docs: add inclusion proofs documentation #160

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 37 commits into from
Sep 25, 2023
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
583d0ba
docs: add fraud proofs documentation
rach-id Jul 26, 2023
d18e7f1
chore: fix links
rach-id Jul 26, 2023
98146f9
Update docs/fraud-proofs.md
rach-id Jul 28, 2023
db8cebc
Update docs/fraud-proofs.md
rach-id Jul 28, 2023
0bb7331
Update docs/fraud-proofs.md
rach-id Jul 28, 2023
deb892d
Update docs/fraud-proofs.md
rach-id Jul 28, 2023
9613782
Update docs/fraud-proofs.md
rach-id Jul 28, 2023
4cd1b15
Update docs/fraud-proofs.md
rach-id Jul 28, 2023
143a8ed
Update docs/fraud-proofs.md
rach-id Jul 28, 2023
a1f1f93
Update docs/fraud-proofs.md
rach-id Jul 28, 2023
a744e5f
Update docs/fraud-proofs.md
rach-id Jul 28, 2023
a162e36
Merge branch 'master' into fraud_proofs_docs
rach-id Jul 28, 2023
1532c35
Merge branch 'master' into fraud_proofs_docs
rach-id Sep 11, 2023
d8afca4
feat: add rollup fraud proof test
rach-id Sep 12, 2023
318f355
Update docs/fraud-proofs.md
rach-id Sep 12, 2023
7087ccf
Update docs/fraud-proofs.md
rach-id Sep 12, 2023
2376626
Update docs/fraud-proofs.md
rach-id Sep 12, 2023
28ffbdd
Update docs/fraud-proofs.md
rach-id Sep 12, 2023
cdcdf90
feat: add share inside spans sequence verification
rach-id Sep 13, 2023
4fcd55e
feat: better details on position of the share in the matrix
rach-id Sep 13, 2023
4c0a688
chore: fmt
rach-id Sep 13, 2023
28b05c1
Update docs/fraud-proofs.md
rach-id Sep 16, 2023
feeba92
Update docs/fraud-proofs.md
rach-id Sep 16, 2023
40ac2b4
Update docs/fraud-proofs.md
rach-id Sep 16, 2023
eafab55
Update docs/fraud-proofs.md
rach-id Sep 16, 2023
079a7a2
Update docs/fraud-proofs.md
rach-id Sep 16, 2023
b60d942
Update docs/fraud-proofs.md
rach-id Sep 16, 2023
a2c7e43
Update docs/fraud-proofs.md
rach-id Sep 16, 2023
eaca8b1
Update docs/fraud-proofs.md
rach-id Sep 16, 2023
ea4ae1f
Update docs/fraud-proofs.md
rach-id Sep 16, 2023
820280c
Update docs/fraud-proofs.md
rach-id Sep 16, 2023
5e615eb
Update docs/fraud-proofs.md
rach-id Sep 16, 2023
68b1a02
Update docs/fraud-proofs.md
rach-id Sep 16, 2023
0a32cf9
Update docs/fraud-proofs.md
rach-id Sep 16, 2023
630e9d8
chore: revert da verifier fix
rach-id Sep 18, 2023
e059edc
Merge branch 'master' into fraud_proofs_docs
rach-id Sep 19, 2023
1caee0c
chore: lint
rach-id Sep 19, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions docs/fraud-proofs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# QGB Fraud Proofs

## Celestiums Intro

A Celestium is a rollup that uses Celestia for data availability but settles on any EVM chain. This works by the Celestia validator set periodically signing over batched data commitments and validator set updates, which are relayed to the QGB smart contract. The data commitments are stored in the EVM chain's state, and can be used to prove inclusion of any data posted to Celestia.

# Fraud Proofs

Fraud proofs is the mechanism used to inform light clients in the case of an invalid rollup state transition or unavailable rollup block data. 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 data, 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.

If the Celestium is settlement smart contract based, then the contract would only need to receive a fraud proof to decide whether data was published correctly or not.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are there types of celestiums that aren't smart contract based?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess they all are smart contract based, but light clients also can verify the proofs before the settlement smart contract executes them.


## Rollup header

Rollups can adopt many approaches to prove that fraud occurred. One of which could be having the following fields in the rollup header:

- Rollup block state root
- A sequence of spans in Celestia: which references where the rollup data was published in the Celestia chain.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A sequence of spans

what is a span?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


> [!NOTE]
> 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.

For the rest of the document, we will suppose that the sequence of spans only references one Celestia block.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sequence of spans

sequence of data?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what occurs when the celestium needs to prove inclusion to multiple chunks of data?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That depends on how they want to separate their data. Generally, they would have multiple references to data in Celestia blocks and they would prove inclusion to one of them


## Proving unavailable data

By construction, the rollup block data **is the sequence of spans defined in the header**. Thus, proving that the data is unavailable goes back to proving that the sequence of spans doesn't belong to the Celestia block, i.e. the span is out of bounds.

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. And, we can use that to calculate the square size.

Then, we will use that information to check if the provided transaction index, in the header, is out of the square size bounds.

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).

## Proving an invalid state transition

In order to prove an invalid transaction in the rollup, we need to prove the following:

- Prove that that transaction was posted to Celestia
- Prove that the transaction is invalid: left to the rollup to define.

The first part, proving that the transaction was posted to Celestia, can be done in three steps:

1. Prove that the data root is committed to by the QGB smart contract
2. Inclusion proof of the transaction to Celestia data root
3. Prove that that transaction is in the rollup sequence spans

### 1. Data root inclusion proof

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.

### 2. Transaction inclusion proof

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.

These proofs can be generated using the [`ProveShares`](https://github.com/celestiaorg/celestia-core/blob/c3ab251659f6fe0f36d10e0dbd14c29a78a85352/rpc/client/http/http.go#L526-L543) query.

### 3. Transaction part of the rollup sequence

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.

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:

```solidity
uint256 shareIndexInRow = shareProof.shareProofs[0].beginKey;
uint256 shareIndexInRowMajorOrder = shareIndexInRow + shareProof.rowProofs[0].numLeaves * shareProof.rowProofs[0].key;
```

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.

Check the `RollupInclusionProofs.t.sol` for an example.
4 changes: 1 addition & 3 deletions src/lib/verifier/DAVerifier.sol
Original file line number Diff line number Diff line change
Expand Up @@ -107,11 +107,9 @@ library DAVerifier {
uint256 cursor = 0;
for (uint256 i = 0; i < _sharesProof.shareProofs.length; i++) {
uint256 sharesUsed = _sharesProof.shareProofs[i].endKey - _sharesProof.shareProofs[i].beginKey;
NamespaceNode memory rowRoot =
NamespaceNode(_sharesProof.namespace, _sharesProof.namespace, _sharesProof.rowRoots[i].digest);
if (
!NamespaceMerkleTree.verifyMulti(
rowRoot,
_sharesProof.rowRoots[i],
_sharesProof.shareProofs[i],
_sharesProof.namespace,
slice(_sharesProof.data, cursor, cursor + sharesUsed)
Expand Down
Loading