Skip to content

Commit

Permalink
Merge branch 'main' of github.com:commonprefix/axelar-light-client
Browse files Browse the repository at this point in the history
  • Loading branch information
themicp committed Feb 6, 2024
2 parents 779cf36 + a2bd796 commit 9e0c3c5
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 10 deletions.
21 changes: 11 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,14 @@ Sync Committee protocol of Ethereum to bridge events from Ethereum to Axelar.
More on the [Light Client Architecture](https://commonprefix.notion.site/Light-Client-Architecture-Draft-8fe5486c958e479ab41cdfc36a3d59ed?pvs=4)

This repo is a collection of modules that work together to implement a light client.
- **Light Client**: The core source of the verifier.
- **Contracts** The module that packages the light client verifier in an on-chain CosmWasm contract.
- **Feeder**: Off-chain component that will feed the light client with Update
messages to keep up with the latest sync-committee.
- **Types**: Common types used across the different modules.
- **Relayer**: The core off-chain component, responsible for consuming the
events from the queue, generating the the necessary proofs, and providing them
to the verifier along with the event.
- **Eth** An auxiliary package for querying the Ethereum beacon and execution APIs.
- **[Relayer/Feeder](https://github.com/commonprefix/axelar-light-client/tree/main/relayer)**: The core off-chain component, responsible for consuming
the events from the queue, generating the the necessary proofs, and providing
them to the verifier along with the event. It also includes an off-chain
component that will feed the light client with Update messages to keep up with
the latest sync-committee.
- **[Light Client](https://github.com/commonprefix/axelar-light-client/tree/main/contracts/light-client)**: The core source of the verifier.
- **[Types](https://github.com/commonprefix/axelar-light-client/tree/main/types)**: Common types used across the different modules.
- **[Eth](https://github.com/commonprefix/axelar-light-client/tree/main/eth)** An auxiliary package for querying the Ethereum beacon and execution APIs.

More details about the packages are in their corresponding READMEs.

Expand All @@ -31,6 +30,8 @@ Wasm URL.
- Go to the `relayer` package and follow the instructions mentioned there for
running both the feeder and the relayer.

## Documentation
Along with the README files, code documentation is also available using the `cargo doc --open` command.

## Acknowledgments
This project uses open-source code from the following projects. We are deeply
Expand All @@ -43,4 +44,4 @@ verification/processing.
- [ethers.rs](https://github.com/gakonst/ethers-rs) and
[alloy.rs](https://github.com/alloy-rs/core) for communicating with Ethereum and
for encoding/decoding execution messages.
- [ssz_rs](https://github.com/polytope-labs/ssz-rs) for SSZ serialization/deserialization.
- [ssz_rs](https://github.com/polytope-labs/ssz-rs) for SSZ serialization/deserialization.
85 changes: 85 additions & 0 deletions contracts/light-client/README.md
Original file line number Diff line number Diff line change
@@ -1 +1,86 @@
# LightClient

Implementation of an Ethereum LightClient as a CosmWasm contract.

The main responsibility of this contract is to store the current sync committee and use it to verify Merkle proofs.
The LightClient learns about the sync committee by parsing [LightClientUpdate](https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/light-client/sync-protocol.md#lightclientupdate) messages, provided from an off-chain component, in our case the [Feeder](https://github.com/commonprefix/axelar-light-client/tree/main/relayer).

From another entrypoint, it receives messages along with their respective proofs, to verify their authenticity. More information about this process can be found in the [Architecture Document](https://www.notion.so/commonprefix/Light-Client-Architecture-8fe5486c958e479ab41cdfc36a3d59ed?pvs=4#545d0c2e0b2247d79a88e3b5a7ebdc11):

The LightClient is initialized with an instantiate message, which contains a [LightClientBootstrap](https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/light-client/sync-protocol.md#lightclientbootstrap) message, along with a few options specific to the source chain (Mainnet, Sepolia, Goerli, etc.).

### Build

It is suggested to use an optimizer to build the smart contract. The LightClient has been tested with both the [CosmWasm rust-optimizer](https://github.com/CosmWasm/rust-optimizer) and [cw-optimizoor](https://github.com/mandrean/cw-optimizoor), but cw-optimizoor was much faster with similar results. In the root of the project, run: `cargo cw-optimizoor`.

**Note 1**: For the current Axelar Devnet, build the contract using Rust version 1.69.0

**Note 2**: The default setting is to build for Ethereum Mainnet. If you want to build for Goerli or Sepolia, you need to update `types/Cargo.toml` and update the **features** of the **sync-committee-rs** package from **mainnet** to the target chain.

### Deploy

This process is similar to uploading any other contract on a Cosmos chain. We will use [axelard](https://github.com/axelarnetwork/axelar-core) for the deployment:
```
axelard tx wasm store <path to .wasm artifact> --from <wallet> -y --node http://devnet.rpc.axelar.dev:26657 --chain-id devnet-wasm
```

You might also have to provide extra options for gas calculations, adjust the command accordingly.

### Instantiate

Sample instantiation messages are provided for mainnet, Goerli and Sepolia deployments in `contracts/light-client/testdata/instantiate-{mainnet,goerli,sepolia}.json`. You can modify those accordingly for each new deployment.
While you can use those messages as-is, some fields that might need to be changed for each deployment are the **gateway_address**, which refers to the Axelar Gateway on the Ethereum side, and the **finalization** type, choosing between **Optimistic** and **Finality**. Refer [here](https://www.notion.so/commonprefix/Light-Client-Architecture-8fe5486c958e479ab41cdfc36a3d59ed?pvs=4#98d96718b2c34168841019297896a935) for more information on the finalization types.

The configuration of the LightClient can also be updated after the instantiation, using the **UpdateConfig** entrypoint.

### Governance

The default owner of the contract is the address that instantiated the contract. To change the owner, the current owner can use the **UpdateOwnership** entrypoint and propose a new owner. The proposed new owner then has to use the same entrypoint to accept the ownership transfer.

## Entrypoints

The entrypoints of the contract are separated between query (or view) entrypoints and execution entrypoints. The query entrypoints are free and just request some information from the contract's state, while the execution entrypoints can also modify that state and also incur some cost.

### Execution Entrypoints

#### LightClientUpdate(update: Update) -> void

It receives a LightClientUpdate message, as defined by Ethereum's Consensus Specification, verifies it with the current sync committee stored in the contract state, and then applies it to modify the current state. This entrypoint essentially update the current and next sync committees stored in the contract's state.

#### UpdateConfig(config: Config) -> void

It updates the contract's config which contains information about the chain's genesis and forks, the Axelar Gateway address and the finalization type.

#### BatchVerificationData(payload: BatchVerificationData) -> VerificationResult

This entrypoint receives all the messages to be verified, along with their proofs, and returns the verification result for each message. If a message is successfully verified, it is stored in the contract's state for later lookups.

#### UpdateOwnership(action: Action) -> void

Propose, accept and reject ownership transfers.

#### VerifyMessages( { messages: _ } ) -> void

This entrypoint is no-op and is here only to conform with the Axelar Amplifier's API interfaces.

### Query Entrypoints

#### LightClientState() -> LightClientState

It returns the state for the LightClient, which contains the last LightClientUpdate's slot, the current and the next sync committee.

#### Config() -> Config

Returns the current config.

#### IsVerified( { messages: Message[] } ) -> (Message, bool)[]

Given a vector of Messages, it returns the verification status for each.

#### IsWorkerSetVerified( { message: WorkerSetMessage } -> bool

Given a WorkerSetMessage, which describes an update of the Worker Set, it returns whether that message has been verified or not.

#### Ownership() -> Address

Returns the address of the current contract owner.

0 comments on commit 9e0c3c5

Please sign in to comment.