Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
sandybradley committed Oct 6, 2024
1 parent 9d37796 commit 2434d82
Show file tree
Hide file tree
Showing 326 changed files with 82,824 additions and 42 deletions.
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export ETH_RPC="https://eth.llamarpc.com"
export BEACON_RPC="https://beacon-nd-422-757-666.p2pify.com/0a9d79d93fb2f4a4b1e04695da2b77a7"
1 change: 1 addition & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ on:

env:
FOUNDRY_PROFILE: ci
RPC: "https://eth.llamarpc.com"

jobs:
check:
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,5 @@ docs/

# Dotenv file
.env

*.ssz
169 changes: 169 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,172 @@
# Consensus Layer Verifier

The `ConsensusLayerVerifier` smart contract is designed to verify data from the Ethereum Beacon chain by using Merkle hashing techniques. It reconstructs the beacon block root, which can be queried on-chain via the Beacon Roots contract (EIP-4788).

This repository consists of three main components:
1. **Solidity Contract (`ConsensusLayerVerifier.sol`)**: Implements the logic to verify Beacon block headers, state roots, and validator data using Merkle proofs.
2. **Bash Script**: A shell script to interact with the Beacon node API and retrieve the latest Beacon chain state.
3. **Python Script**: Generates Merkle proofs required for verifying the Beacon state and validator information.

## Table of Contents
- [Contract Overview](#contract-overview)
- [Functions](#functions)
- [Merkle Root Calculation](#merkle-root-calculation)
- [Beacon Block Header Verification](#beacon-block-header-verification)
- [Validator Verification](#validator-verification)
- [External Components](#external-components)
- [Bash Script](#bash-script)
- [Python Script](#python-script)
- [Getting Started](#getting-started)
- [Installation](#installation)
- [Usage](#usage)
- [Foundry](#foundry)

## Contract Overview

The `ConsensusLayerVerifier` contract provides functionalities for verifying various components of the Beacon chain, including:
- **Beacon Block Header**: Verifies the Merkle root of the Beacon block header.
- **State Root**: Verifies the Merkle proof of a state root within the Beacon block.
- **Validator**: Verifies validator information (e.g., balance, withdrawal credentials) by computing the Merkle root and checking it against the Beacon state.

### External Libraries
- **MerkleTree**: A library for Merkle tree calculations.
- **EndianHelper**: A library for handling endian-specific operations.

## Functions

### Merkle Root Calculation
The contract contains functions to calculate and verify Merkle roots for Beacon block headers and validator data.

- **`calculateBeaconHeaderMerkleRoot`**: Computes the Merkle root of a Beacon block header.
- **`verifyBeaconHeaderMerkleRoot`**: Verifies the Merkle root of a given block header against a stored Beacon root.
- **`calculateValidatorMerkleRoot`**: Calculates the Merkle root of a given validator.

### Beacon Block Header Verification
The contract verifies the integrity of a Beacon block header by checking it against the Beacon Roots contract (`EIP-4788`).

- **`getParentBeaconBlockRoot`**: Fetches the Beacon block root at a given timestamp.
- **`verifyBeaconHeaderMerkleRoot`**: Validates that the Merkleized header matches the Beacon block root on-chain.

### Validator Verification
Validator data (such as balance, withdrawal address, and slashing status) can be verified against the Beacon state root.

- **`verifyValidator`**: Verifies a validator's data using a Merkle proof.
- **`verifyValidatorWithdrawalAddress`**: Confirms the withdrawal address of a validator.
- **`verifyValidatorActive`**: Checks if a validator is active and not slashed.

## External Components

### Bash Scripts

The repository includes bash scripts that retrieve the latest Beacon chain state from a Beacon node API. This data can be used to fetch block roots and other state information necessary for verification.

**Get latest beacon block header**:
```bash
./script/get_beacon_block.sh
```

**Get latest beacon state (warning: ~700 MB download)**:
```bash
./script/get_latest_beacon_state.sh
```

### Python Script
The Python script in this repository is used to generate Merkle proofs required for verifying various data (e.g., state roots, validator information) against the Beacon block root.

**Generate merkle proof for a validator**:
```bash
cd py
python run merkle_proof_generator/main.py
```

This script is essential for creating the Merkle proofs that are input into the smart contract for verification.

**Merkle Tree Proof of Verification**

To prove that a specific field in a validator's record (e.g., `withdrawal_credentials`) is part of the BeaconState Merkle tree, we traverse the tree and collect witness nodes (sibling hashes) along the path from the leaf node to the root.

The Merkle witness nodes are used to recompute the Merkle root and verify that the value is included in the tree.

```plaintext
ROOT
┌──────┴──────┐
│ │
Hash0 Hash1
│ │
┌───┴───┐ ┌───┴───┐
│ │ │ │
Leaf0 Leaf1 Leaf2 Leaf3
```
**Example Path and Witness**

Suppose we're interested in verifying the value of a field (e.g., withdrawal_credentials) at Leaf2. The verification process involves:

- Locate Leaf2: The target value in the Merkle tree.
- Collect Witness Nodes: Gather sibling hashes along the path from Leaf2 to the root. These sibling hashes (known as the Merkle witness) are:
- Hash of Leaf3 (sibling of Leaf2).
- Hash of Hash0 (sibling of Hash1).
- Compute Root: Using the Leaf2 value and the collected witness nodes, we compute the Merkle root and compare it with the known root of the tree. If they match, the value is verified.

```plaintext
Root (Verified)
Witness: Hash0 ──┘
┌───────────┴───────────┐
│ │
Leaf2 (value) Witness: Leaf3
```
Witness Nodes Explanation

- Leaf2: This is the value we want to verify.
- Leaf3: The sibling of Leaf2, used to compute Hash1.
- Hash0: The sibling of Hash1, used to compute the Merkle root.

By traversing up the tree, the verification process ensures that the target value is part of the overall BeaconState structure.

## Getting Started
### Installation

1. Clone the repository:
```bash
git clone https://github.com/your-repo/consensus-layer-verifier.git
cd consensus-layer-verifier
```
2. Set environment variables
e.g.
```bash
export ETH_RPC="https://eth.llamarpc.com"
export BEACON_RPC="https://beacon-nd-422-757-666.p2pify.com/0a9d79d93fb2f4a4b1e04695da2b77a7"
```
3. Get latest beacon header and or beacon state
```bash
./script/get_beacon_block.sh
```
4. Run tests
```bash
forge test -vvv
```

### Usage
1. **Deploy the contract:** Deploy the `ConsensusLayerVerifier.sol` contract on your local or test network.
2. **Use the Bash script:** Fetch the latest Beacon chain state from your node:
```bash
./script/get_latest_beacon_state.sh
```
3. **Generate Merkle proofs:** Use the Python script to generate proofs for specific block headers or validators:
```bash
cd py
python run generate_merkle_proof/main.py --validator-index <index>
```
4. **Verify data on-chain:** Call the contract functions to verify headers, state roots, and validator data.

## Credits

https://github.com/Layr-Labs/eigenlayer-contracts/blob/dev/src/contracts/libraries/BeaconChainProofs.sol

## Foundry

**Foundry is a blazing fast, portable and modular toolkit for Ethereum application development written in Rust.**
Expand Down
7 changes: 7 additions & 0 deletions data/beacon_block_header.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"slot": "10103527",
"proposer_index": "1494303",
"parent_root": "0xd2b163c97779f3cd4c22b2b59a8e940806832b5b0857c49c862051581ed5555d",
"state_root": "0xc3c0e26f64feb8793e3fe8e9eab6b187b9dca0672e96df5de92746cad170803c",
"body_root": "0x9d9cdbce0d5c9b6db91eafd16b1cb015429ec3087037307b2e70dbafc1074fa1"
}
53 changes: 53 additions & 0 deletions data/proof.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
{
"gindex": 94557999988859,
"root": "c3c0e26f64feb8793e3fe8e9eab6b187b9dca0672e96df5de92746cad170803c",
"witness": [
"0x313e2f50681f60754d6b4110d25fbac671bb1055bed37f3b4618bbae55d0f68a",
"0xb472d296cf13a5cdfde766f205a8ff1e686998db12727b4ab10ceff22a4e91ea",
"0xf49ad75e4cc62afaa3820fc67e3f4b7a2ca00acb2c50b54a9e0fd2e3c7ce4e5c",
"0x729b44824ffb8c1f6b0927c9e40197e87aa42c52ba74f10b0ef8678a1826cb7a",
"0x11091a0000000000000000000000000000000000000000000000000000000000",
"0x9478180000000000000000000000000000000000000000000000000000000000",
"0xad21b516cbc645ffe34ab5de1c8aef8cd4e7f8d2b51e8e1456adc7563cda206f",
"0xf7210d4f8e7e1039790e7bf4efa207555a10a6db1dd4b95da313aaa88b88fe76",
"0x55d8fb3687ba3ba49f342c77f5a1f89bec83d811446e1a467139213d640b6a74",
"0xbfb909fdb236ad2411b4e4883810a074b840464689986c3f8a8091827e17c327",
"0x328921deb59612076801e8cd61592107b5c67c79b846595cc6320c395b46362c",
"0x2f075ae229646b6f6aed19a5e372cf295081401eb893ff599b3f9acc0c0d3e7d",
"0x1c9a7e5ff1cf48b4ad1582d3f4e4a1004f3b20d8c5a2b71387a4254ad933ebc5",
"0xc6f67e02e6e4e1bdefb994c6098953f34636ba2b6ca20a4721d2b26a886722ff",
"0x985e929f70af28d0bdd1a90a808f977f597c7c778c489e98d3bd8910d31ac0f7",
"0xb5fe28e79f1b850f8658246ce9b6a1e7b49fc06db7143e8fe0b4f2b0c5523a5c",
"0x8869ff2c22b28cc10510d9853292803328be4fb0e80495e8bb8d271f5b889636",
"0x848930bd7ba8cac54661072113fb278869e07bb8587f91392933374d017bcbe1",
"0x7cdd2986268250628d0c10e385c58c6191e6fbe05191bcc04f133f2cea72c1c4",
"0x619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a46765",
"0x21352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544",
"0x31206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc0",
"0xe71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d7",
"0xfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167",
"0x8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9c",
"0x23f7e474f5a91765075f531aca6487534d8836c99b7d3218d14c65466cc37d1f",
"0x414ff4a97cd82f1614f22a3e8623e3e6411427f40d51d7930b13d37c120151de",
"0x7ab228602a1e276cffaa0e400233051829cf606ae8d00ef751d3e9f35b2ac19b",
"0x7cd0706d8d9d0645302bcaa8a548509e29442e0b65a8bfaea93698a2d43c07c8",
"0x374cb84d496aa4202c8ffce61a9c4bdb0ba97ae07d05b0e163cfa099fd42606c",
"0x98e3489e0e4777ec6bcf00cf6185469d66169b6e73d19ef5b129e04ff6a8db46",
"0xc96203409fd687e25e38327ac5c27345d3e43e332a6603b9389e1f445ed52365",
"0x22abfc8a417b5285b41e1c0144c00b7555f60dce1f754bba1c2499155232cd05",
"0xf5d1874be28a97f94284ecb065d42fb999ca9688496113fa211908201b5e46c6",
"0x943c81ad801c8544a471382b63254d42a72c0c8548ff9bdccf2a2a866d3bf7ee",
"0xb4241dba754626f3eefb9b3a718aa4db3f2e00e3cb46a2fdfd82c7e1da9c6e92",
"0xa67960b8dd96c69a132cef9e8dcbd090768144205cb7518a42504e70dca7b49b",
"0xb1683411fd6e1e23aa8f18040ae3eb6fa8cbfa5a42a666506b4ca6dc68a78ea3",
"0x091404ec40a1be67bb036bec4b9a43a387ea6d1412be0c6e7c2a21360c30166a",
"0x7c824bca5a87ce106828987599478086ad26b02aa06d9d89eca15844bb690000",
"0x54afbea9b8e8dd917afbdde20fb7d93a789942f87f01a7e1de94e322b2babcba",
"0x50c55c8515d9316fa80dd32c628274e49f64d4b76d48ddf71b5c6c9013716289",
"0xc07f892b6a5fca17dea150650fa76f62d4692b8a7d186399fd457b8a514fb94f",
"0x174335688edc57ca5205af5427d54847ca7ac52925349c4d7345e72de029ba0e",
"0x44a8c099e35316e5420026a35932dbcfdf67ad0e135802a183b695ad392f2356",
"0x57225802a1a0a65872c7ca5b694ebafa4c7c41010a26472f66ddfb7bc016e8f3"
],
"value": "6c507b28277e65fef9adb5d8f75937a4a5cca9a77ff7c04ce3504c42049e6493"
}
2 changes: 2 additions & 0 deletions foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,7 @@
src = "src"
out = "out"
libs = ["lib"]
evm_version = 'cancun'
fs_permissions = [{ access = "read", path = "./" }]

# See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options
10 changes: 10 additions & 0 deletions lib/solady/.github/issue_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<!-- Emoji Table: -->
<!-- readme/docs 📝 -->
<!-- new feature ✨ -->
<!-- refactor/cleanup ♻️ -->
<!-- nit 🥢 -->
<!-- security fix 🔒 -->
<!-- optimization ⚡️ -->
<!-- configuration 👷‍♂️ -->
<!-- events 🔊 -->
<!-- bug fix 🐞 -->
23 changes: 23 additions & 0 deletions lib/solady/.github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
## Description

Describe the changes made in your pull request here.

## Checklist

Ensure you completed **all of the steps** below before submitting your pull request:

- [ ] Ran `forge fmt`?
- [ ] Ran `forge test`?

_Pull requests with an incomplete checklist will be thrown out._

<!-- Emoji Table: -->
<!-- readme/docs 📝 -->
<!-- new feature ✨ -->
<!-- refactor/cleanup ♻️ -->
<!-- nit 🥢 -->
<!-- security fix 🔒 -->
<!-- optimization ⚡️ -->
<!-- configuration 👷‍♂️ -->
<!-- events 🔊 -->
<!-- bug fix 🐞 -->
59 changes: 59 additions & 0 deletions lib/solady/.github/workflows/ci-all-via-ir.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
name: ci-all-via-ir

on:
workflow_dispatch:

jobs:
tests:
name: Forge Testing all via-ir
runs-on: ubuntu-latest

strategy:
matrix:
profile: [via-ir-0,via-ir-1,via-ir-2,via-ir-3]

steps:
- uses: actions/checkout@v4

- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
with:
version: nightly

- name: Install Dependencies
run: forge install

- name: Run Tests with ${{ matrix.profile }}
run: >
( [ "${{ matrix.profile }}" = "via-ir-0" ] &&
forge test --use 0.8.4 --via-ir &&
forge test --use 0.8.5 --via-ir &&
forge test --use 0.8.6 --via-ir &&
forge test --use 0.8.7 --via-ir &&
forge test --use 0.8.8 --via-ir &&
forge test --use 0.8.9 --via-ir
) ||
( [ "${{ matrix.profile }}" = "via-ir-1" ] &&
forge test --use 0.8.13 --via-ir &&
forge test --use 0.8.12 --via-ir &&
forge test --use 0.8.11 --via-ir &&
forge test --use 0.8.10 --via-ir
) ||
( [ "${{ matrix.profile }}" = "via-ir-2" ] &&
forge test --use 0.8.14 --via-ir &&
forge test --use 0.8.15 --via-ir &&
forge test --use 0.8.16 --via-ir &&
forge test --use 0.8.17 --via-ir
) ||
( [ "${{ matrix.profile }}" = "via-ir-3" ] &&
forge test --use 0.8.27 --via-ir &&
forge test --use 0.8.26 --via-ir &&
forge test --use 0.8.25 --via-ir &&
forge test --use 0.8.24 --via-ir &&
forge test --use 0.8.23 --via-ir &&
forge test --use 0.8.22 --via-ir &&
forge test --use 0.8.21 --via-ir &&
forge test --use 0.8.20 --via-ir &&
forge test --use 0.8.19 --via-ir &&
forge test --use 0.8.18 --via-ir
)
27 changes: 27 additions & 0 deletions lib/solady/.github/workflows/ci-invariant-intense.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: ci-invariant-intense

on:
workflow_dispatch:

jobs:
tests:
name: Forge Testing invariant intense
runs-on: ubuntu-latest

strategy:
matrix:
profile: [invariant-intense-0,invariant-intense-1,invariant-intense-2,invariant-intense-3]

steps:
- uses: actions/checkout@v4

- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
with:
version: nightly

- name: Install Dependencies
run: forge install

- name: Run Tests with ${{ matrix.profile }}
run: FOUNDRY_INVARIANT_RUNS=500 FOUNDRY_INVARIANT_DEPTH=500 forge test
Loading

0 comments on commit 2434d82

Please sign in to comment.