Skip to content
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

docs: Add a section describing how transfers work #63

Merged
merged 5 commits into from
Dec 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
83 changes: 61 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@

This repo exists to showcase transferring tokens to and from a Cosmos SDK chain (representing Celestia) and a ZK proveable EVM using the [IBC-Eureka solidity contracts](https://github.com/cosmos/solidity-ibc-eureka/blob/main/README.md). The diagram below is meant to detail the components involved and, at a high level, how they interact with one another.

![mvp-zk-accounts](./mvp-zk-accounts.png)
![mvp-zk-accounts](./docs/images/mvp-zk-accounts.png)

For more information refer to the [architecture document](./ARCHITECTURE.md). Note that the design is subject to change.

## Local Development
## Usage

### Prerequisites

Expand All @@ -18,7 +18,7 @@ For more information refer to the [architecture document](./ARCHITECTURE.md). No
1. Install [Foundry](https://book.getfoundry.sh/getting-started/installation)
1. Install [Bun](https://bun.sh/)
1. Install [Just](https://just.systems/man/en/)
1. Install [SP1](https://docs.succinct.xyz/docs/getting-started/install) (for end-to-end tests)
1. Install [SP1](https://docs.succinct.xyz/docs/getting-started/install)

### Steps

Expand All @@ -45,39 +45,64 @@ For more information refer to the [architecture document](./ARCHITECTURE.md). No
1. Set up IBC clients and channels:

- Generate the `contracts/script/genesis.json` file which contains the initialization parameters for the `SP1ICS07Tendermint` light client contract.
- Initialize Groth16 light client on simapp.
- Create a channel on simapp.
- Initialize Groth16 light client on SimApp.
- Create a channel on SimApp.
- Deploy IBC contracts on the Reth node.
- Create a channel on the Reth node.
- Create a counterparty on the Reth node which points to the groth16 client ID on simapp.
- Create a counterparty on the simapp which points to the tendermint client ID on Reth.
- Create a counterparty on the Reth node which points to the groth16 client ID on SimApp.
- Create a counterparty on the SimApp which points to the tendermint client ID on Reth.

```shell
make setup
```

1. Transfer tokens from simapp to the EVM roll-up.
1. Transfer tokens from SimApp to the EVM roll-up.

```shell
make transfer
```

### Helpful commands
1. To stop and teardown the test environment (when you're finished)

```shell
# See the running containers
docker ps
```shell
make stop
```

# You can view the logs from a running container via Docker UI or:
docker logs beacond
docker logs celestia-network-bridge
docker logs celestia-network-validator
docker logs simapp-validator
docker logs reth
## A Breakdown of an IBC Transfer

# State is persisted in the .tmp directory. Remove .tmp to start fresh:
rm -rf .tmp
```
This section takes the diagram from above and breaks down each step during `make transfer` to help aid your understanding.

![mvp-zk-accounts](./docs/images/mvp-zk-accounts-step-1.png)

1a -> The user submits a transfer message. This is a `ICS20LibFungibleTokenPacketData` wrapped in a `SendPacket` message. As well as who it's sending the tokens to and how much it also specifies where this packet is going to and lets the eventual receiver know where the packet came from.

1b -> The SimApp chain (mimicking Celestia) executes the transaction, checking the user's balance and then moving the funds to a locked acount. It stores a commitment to this execution in state. This is kind of like a verifiable receipt.

![mvp-zk-accounts](./docs/images/mvp-zk-accounts-step-2.png)

2a -> Now the relayer kicks in. It listens to events that SimApp has emitted that there are pending packets ready to be sent to other chains. It queries the chain for the receipt based on a predetermined location.

2b -> The relayer needs to prove to the EVM rollup that SimApp has actually successfully executed the first part of the transfer: locking up the tokens. Proving this requires two steps: First the relayer queries a state transition proof from the prover process. This will prove the latest state root from the last trusted state root stored in the state of the ICS07 Tendermint smart contract on the EVM. Now the EVM has an up to date record of SimApp's current state (which includes the receipt). Second, the relayer asks the prover for a proof that the receipt is a merkle leaf of the state root i.e. it's part of state

2c -> The prover has a zk circuit for generating both proofs. One takes tendermint headers and uses the `SkippingVerification` algorithm to assert the latest header. The other takes IAVL merkle proofs and proves some leaf key as part of the root. These are both STARK proofs which can be processed by the smart contracts on the EVM.

2d -> The last step of the relayer is to combine these proofs and packets and submit a `MsgUpdateClient` and `MsgRecvPacket` to the EVM rollup.

![mvp-zk-accounts](./docs/images/mvp-zk-accounts-step-3.png)

Step 3 mirrors step 2 in many ways but now in the opposite direction

3a -> The EVM executes both messages. It verifies the STARK proofs and updates it's local record of SimApp's state. It then uses the updated state to verify that the receipt that the packet refers is indeed present in SimApp's state. Once all the verification checks are passed. It mints the tokens and adds them to the account of the recipient as specified in the packet. The rollup then writes it's own respective receipt that it processed the corresponding message.

3b -> Similarly, the relayer listens for events emitted from the EVM rollup for any packets awaiting to be sent back. Upon receiving the packet to be returned, an acknowledgement of the transfer to be sent back to SimApp, it talks to the prover service to prepare the relevant proofs. While they are of different state machines and different state trees, the requests are universal: a proof of the state transition and a proof of membership. The EVM Prover Service here futher compresses the STARK proofs into groth16 proofs for SimApp's groth16 IBC Client.

3c -> The relayer then sends a `MsgUpdateClient` with the state transition proof to update SimApp's record of the Rollup's state after the point that it processed the transfer packet and wrote the receipt. The relayer also sends a `MsgAcknowledgement` which contains the membership proof of the commitment, a.k.a. the receipt alongside the details of the receipt i.e. for what transfer message are we acknowledging.

3d -> SimApp processes these two messages. It validates the proofs and if everything is in order, it removes the transfer receipt and keeps one final receipt of the acknowledgement (to prevent a later timeout message).

In the case that the EVM decided these messages were not valid it would not write the acknowledgement receipt. The relayer, tracking the time when the transfer message was sent would submit a `MsgTimeout` instead of the acknowledgement with an absence proof. This is a proof that no acknowledgement was written where the predermined path says it should be written. When SimApp receives this timeout and the corresponding absence proof, it reverses the transfer, releaseing the locked funds and returning them to the sender. This process is atomic - funds can not be unlocked if they are minted on the other chain.

If someone were to send tokens from the EVM rollup back to SimApp, the source chain of those tokens, the process would be very similar, however the actions wouldn't be to lock and mint but rather the EVM rollup would burn tokens and SimApp would unlock them.

## Contributing

Expand All @@ -86,6 +111,20 @@ rm -rf .tmp
This repo uses protobuf to define the interfaces between several services. To help with this, this
repo relies on [buf](https://buf.build). If you modify the protos you can regenerate them using:

```
make proto-gen
```

### Helpful commands

```shell
buf generate
# See the running containers
docker ps

# You can view the logs from a running container via Docker UI or:
docker logs beacond
docker logs celestia-network-bridge
docker logs celestia-network-validator
docker logs simapp-validator
docker logs reth
```
4 changes: 2 additions & 2 deletions ARCHITECTURE.md → docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

To provide some context on what we’re trying to achieve, we’re going to start with describing the user flow for transferring TIA to a ZK EVM (Based of the current flow)

![zkevm-ibc-transfer-flow](./zkevm-ibc-transfer-flow.png)
![zkevm-ibc-transfer-flow](./images/zkevm-ibc-transfer-flow.png)

1. A user submits a `MsgTransfer` to the Celestia chain. Celestia performs some validation checks on the message, then transfers the user’s funds to a module account, effectively locking the funds. The chain then creates a `Commitment` , a receipt of the successful execution of that message as well as an event emitted containing a `Packet` with information to send to the EVM rollup
2. A relayer listens for the event. It queries a Celestia consensus node for the `Commitment` in the state tree along with the merkle proof, proving the inclusion of that data. The relayer submits the packet along with the inclusion proofs to the rollups namespace.
Expand All @@ -26,7 +26,7 @@ The architecture involves several different logical components:
- Prover: proves the computation to go from one state to the next. Publishes these proofs to the state namespace. An example of this for EVMs is RSP (Reth Succinct Prover) which is a circuit for proving the computation of a single block.
- Relayer: listens for events from both the EVM rollup full node and the Celestia consensus full node. It queries for commitments and proofs and submits them to the DA layer under the appropriate namespaces. We expect it to often run on the same machine as the sequencer.

![zkevm-ibc-architecture](./zkevm-ibc-architecture.png)
![zkevm-ibc-architecture](./images/zkevm-ibc-architecture.png)

## Proving System

Expand Down
Binary file added docs/images/mvp-zk-accounts-step-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/mvp-zk-accounts-step-2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/mvp-zk-accounts-step-3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/mvp-zk-accounts.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes
File renamed without changes
Binary file removed mvp-zk-accounts.png
Binary file not shown.
Loading