Skip to content

Commit

Permalink
Use Lighthouse Types instead of maintaining our own (#77)
Browse files Browse the repository at this point in the history
* update circuits and witnesses, still need to update tests

* fix preprocessor

* fixed tests

* tests for preprocessor work

* in progress: tixing test-utils

* fixed test-utils

* prover wip

* lint

* switch to lighthouse unstable branch

* Add fork version to RPC request

* Everything builds

* remove prints

* merkle proof asserts

* fix preprocessor asserts

* pull from finalized not head

* Update Lighthouse version to tagged release from unstable branch

* Move Lighthoust EthSpec as associated type in Spec

* Pin compiler nightly-2024-04-01

* remove comment

* Remove comments

* remove comments

* No unwrap

* Fix cargo toml

* Clippy

* cargo udeps

* update contracts submodule

* fix cargo toml

* lighouse legacy arith

* remove unnecessary generic bounds

* remove blob params from Spec
  • Loading branch information
ec2 authored Apr 4, 2024
1 parent 7eacce0 commit 8902f51
Show file tree
Hide file tree
Showing 26 changed files with 585 additions and 740 deletions.
9 changes: 5 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,11 @@ snark-verifier-sdk = { git = "https://github.com/axiom-crypto/snark-verifier.git
] }

# ethereum types
ethereum-consensus-types = { git = "https://github.com/ChainSafe/ethereum-consensus-types", branch = "capella" }
beacon-api-client = { git = "https://github.com/ralexstokes/ethereum-consensus.git", rev = "f3bff52e9c43866f231ec40c8ab0e34125a8957f" }
ssz_rs = "0.9"
ethereum-types = { package = "types", git = "https://github.com/sigp/lighthouse/", tag = "v5.1.3", default-features = false, features = ["legacy-arith"] }
tree_hash = { version = "0.5" }
eth2 = { package = "eth2", git = "https://github.com/sigp/lighthouse/", tag = "v5.1.3" }
merkle_proof = { package = "merkle_proof", git = "https://github.com/sigp/lighthouse/", tag = "v5.1.3" }
ethereum_ssz = "0.5.3"

# crypto
group = "0.13"
Expand All @@ -90,7 +92,6 @@ ark-std = { version = "0.4.0", features = ["print-trace"] }


[patch.crates-io]
ssz_rs = { git = "https://github.com/ralexstokes/ssz-rs", rev = "5f1ec833718efa07bbbff427ab28a1eeaa706164" }
halo2-base = { git = "https://github.com/nulltea/halo2-lib", branch = "feat/bls12-381-hash2curve" }
halo2-ecc = { git = "https://github.com/nulltea/halo2-lib", branch = "feat/bls12-381-hash2curve" }
zkevm-hashes = { git = "https://github.com/nulltea/halo2-lib", branch = "feat/bls12-381-hash2curve" }
Expand Down
3 changes: 2 additions & 1 deletion contract-tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ itertools = "0.11.0"
test-utils = { workspace = true }
halo2curves = { workspace = true }
eth-types = { workspace = true }
ssz_rs = { workspace = true }
halo2-base = { workspace = true }
snark-verifier-sdk = { workspace = true }
contracts = { workspace = true }

tree_hash.workspace = true
16 changes: 4 additions & 12 deletions contract-tests/tests/step_input_encoding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// Code: https://github.com/ChainSafe/Spectre
// SPDX-License-Identifier: LGPL-3.0-only

use std::ops::Deref;
use std::path::PathBuf;

use contract_tests::make_client;
Expand All @@ -11,8 +10,8 @@ use ethers::contract::abigen;
use lightclient_circuits::halo2_proofs::halo2curves::bn256;
use lightclient_circuits::witness::SyncStepArgs;
use rstest::rstest;
use ssz_rs::Merkleized;
use test_utils::read_test_files_and_gen_witness;
use tree_hash::TreeHash;

abigen!(
StepExternal,
Expand All @@ -28,20 +27,13 @@ impl<Spec: eth_types::Spec> From<SyncStepArgs<Spec>> for StepInput {
.map(|v| *v as u64)
.sum::<u64>();

let finalized_header_root: [u8; 32] = args
.finalized_header
.clone()
.hash_tree_root()
.unwrap()
.deref()
.try_into()
.unwrap();
let finalized_header_root: [u8; 32] = args.finalized_header.clone().tree_hash_root().0;

let execution_payload_root: [u8; 32] = args.execution_payload_root.try_into().unwrap();

StepInput {
attested_slot: args.attested_header.slot,
finalized_slot: args.finalized_header.slot,
attested_slot: args.attested_header.slot.into(),
finalized_slot: args.finalized_header.slot.into(),
participation,
finalized_header_root,
execution_payload_root,
Expand Down
4 changes: 1 addition & 3 deletions eth-types/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,13 @@ pasta_curves.workspace = true
uint.workspace = true
hex.workspace = true
halo2-base.workspace = true
halo2-ecc.workspace = true
serde.workspace = true
serde_json.workspace = true
itertools.workspace = true
halo2curves.workspace = true
ethereum-types.workspace = true
regex = "1.5.4"
lazy_static = "1.4"
subtle = "2.4"
num = "0.4"
num-bigint.workspace = true
strum_macros = "0.24"
strum = "0.24"
21 changes: 9 additions & 12 deletions eth-types/src/spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
// SPDX-License-Identifier: LGPL-3.0-only

use core::fmt::Debug;

use ethereum_types::{EthSpec, MainnetEthSpec, MinimalEthSpec};
/// Beacon chain specification.
pub trait Spec: 'static + Sized + Copy + Default + Debug {
type EthSpec: EthSpec;

const NAME: &'static str;
const SYNC_COMMITTEE_SIZE: usize;
const SYNC_COMMITTEE_ROOT_INDEX: usize;
Expand All @@ -18,14 +20,14 @@ pub trait Spec: 'static + Sized + Copy + Default + Debug {
const EXECUTION_STATE_ROOT_DEPTH: usize;
const FINALIZED_HEADER_INDEX: usize;
const FINALIZED_HEADER_DEPTH: usize;
const BYTES_PER_LOGS_BLOOM: usize = 256;
const MAX_EXTRA_DATA_BYTES: usize = 32;
}

#[derive(Copy, Clone, PartialEq, Eq, Debug, Default)]
pub struct Minimal;

impl Spec for Minimal {
type EthSpec = MinimalEthSpec;

const NAME: &'static str = "minimal";
const SYNC_COMMITTEE_SIZE: usize = 32;
const SYNC_COMMITTEE_DEPTH: usize = 5;
Expand All @@ -38,15 +40,14 @@ impl Spec for Minimal {
const EXECUTION_STATE_ROOT_DEPTH: usize = 4;
const FINALIZED_HEADER_INDEX: usize = 105;
const FINALIZED_HEADER_DEPTH: usize = 6;

const BYTES_PER_LOGS_BLOOM: usize = 256;
const MAX_EXTRA_DATA_BYTES: usize = 32;
}

#[derive(Copy, Clone, PartialEq, Eq, Debug, Default)]
pub struct Testnet;

impl Spec for Testnet {
type EthSpec = MainnetEthSpec;

const NAME: &'static str = "testnet";
const SYNC_COMMITTEE_SIZE: usize = 512;
const SYNC_COMMITTEE_DEPTH: usize = 5;
Expand All @@ -58,15 +59,14 @@ impl Spec for Testnet {
const EXECUTION_STATE_ROOT_DEPTH: usize = 4;
const FINALIZED_HEADER_INDEX: usize = 105;
const FINALIZED_HEADER_DEPTH: usize = 6;

const BYTES_PER_LOGS_BLOOM: usize = 256;
const MAX_EXTRA_DATA_BYTES: usize = 32;
}

#[derive(Copy, Clone, PartialEq, Eq, Debug, Default)]
pub struct Mainnet;

impl Spec for Mainnet {
type EthSpec = MainnetEthSpec;

const NAME: &'static str = "mainnet";
const SYNC_COMMITTEE_SIZE: usize = 512;
const SYNC_COMMITTEE_DEPTH: usize = 5;
Expand All @@ -78,7 +78,4 @@ impl Spec for Mainnet {
const EXECUTION_STATE_ROOT_DEPTH: usize = 4;
const FINALIZED_HEADER_INDEX: usize = 105;
const FINALIZED_HEADER_DEPTH: usize = 6;

const BYTES_PER_LOGS_BLOOM: usize = 256;
const MAX_EXTRA_DATA_BYTES: usize = 32;
}
8 changes: 3 additions & 5 deletions lightclient-circuits/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,29 +25,27 @@ sha2.workspace = true
pse-poseidon = { git = "https://github.com/axiom-crypto/pse-poseidon.git" }

# ethereum
ssz_rs = { workspace = true, features = ["serde"] }
ethereum-consensus-types ={ workspace = true, features = ["serde"] }
ethereum-types = {workspace = true, default-features = false }
tree_hash.workspace = true

# local
eth-types.workspace = true

# misc
ark-std.workspace = true
serde.workspace = true
serde_json.workspace = true
itertools.workspace = true
log.workspace = true
hex.workspace = true
rayon = "1.7.0"
array-init = "2.0.0"
strum = "0.25"
strum_macros = "0.25"
rand = "0.8"
lazy_static = "1.4"
getset = "0.1.2"
rand_chacha = "0.3.0"

[dev-dependencies]
ark-std.workspace = true
rstest = "0.18.2"
test-utils = { workspace = true }

Expand Down
18 changes: 5 additions & 13 deletions lightclient-circuits/src/committee_update_circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ use halo2_ecc::{
fields::FieldChip,
};
use itertools::Itertools;
use ssz_rs::Merkleized;
use std::{env::var, iter, marker::PhantomData, vec};
use tree_hash::TreeHash;

/// `CommitteeUpdateCircuit` maps next sync committee SSZ root in the finalized state root to the corresponding Poseidon commitment to the public keys.
///
Expand Down Expand Up @@ -90,7 +90,7 @@ impl<S: Spec, F: Field> CommitteeUpdateCircuit<S, F> {
builder,
&sha256_chip,
[
args.finalized_header.slot.into_witness(),
args.finalized_header.slot.as_u64().into_witness(),
args.finalized_header.proposer_index.into_witness(),
args.finalized_header.parent_root.as_ref().into_witness(),
finalized_state_root.clone().into(),
Expand Down Expand Up @@ -198,14 +198,11 @@ impl<S: Spec, F: Field> CommitteeUpdateCircuit<S, F> {
pub fn get_instances(
args: &witness::CommitteeUpdateArgs<S>,
limb_bits: usize,
) -> Vec<Vec<bn256::Fr>>
where
[(); S::SYNC_COMMITTEE_SIZE]:,
{
) -> Vec<Vec<bn256::Fr>> {
let poseidon_commitment =
poseidon_committee_commitment_from_compressed(&args.pubkeys_compressed, limb_bits);

let finalized_header_root = args.finalized_header.clone().hash_tree_root().unwrap();
let finalized_header_root = args.finalized_header.tree_hash_root();

let finalized_header_root_hilo = {
let bytes = finalized_header_root.as_ref();
Expand Down Expand Up @@ -279,12 +276,7 @@ mod tests {
use ark_std::{end_timer, start_timer};
use eth_types::Testnet;
use halo2_base::{
halo2_proofs::{
dev::MockProver,
halo2curves::bn256::Fr,
plonk::ProvingKey,
poly::{commitment::Params, kzg::commitment::ParamsKZG},
},
halo2_proofs::{dev::MockProver, halo2curves::bn256::Fr, plonk::ProvingKey},
utils::fs::gen_srs,
};
use snark_verifier_sdk::evm::{evm_verify, gen_evm_proof_shplonk};
Expand Down
21 changes: 9 additions & 12 deletions lightclient-circuits/src/sync_step_circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ use halo2_ecc::{
use halo2curves::bls12_381::{G1Affine, G2Affine};
use itertools::Itertools;
use num_bigint::BigUint;
use ssz_rs::Merkleized;
use std::{env::var, marker::PhantomData, vec};
use tree_hash::TreeHash;

/// `StepCircuit` verifies that Beacon chain block header is attested by a lightclient sync committee via aggregated signature,
/// and the execution (Eth1) payload via Merkle proof against the finalized block header.
Expand Down Expand Up @@ -110,7 +110,8 @@ impl<S: Spec, F: Field> StepCircuit<S, F> {
)?;

// Compute attested header root
let attested_slot_bytes: HashInputChunk<_> = args.attested_header.slot.into_witness();
let attested_slot_bytes: HashInputChunk<_> =
args.attested_header.slot.as_u64().into_witness();
let attested_header_state_root = args
.attested_header
.state_root
Expand Down Expand Up @@ -138,7 +139,8 @@ impl<S: Spec, F: Field> StepCircuit<S, F> {
.iter()
.map(|&b| builder.main().load_witness(F::from(b as u64)))
.collect_vec();
let finalized_slot_bytes: HashInputChunk<_> = args.finalized_header.slot.into_witness();
let finalized_slot_bytes: HashInputChunk<_> =
args.finalized_header.slot.as_u64().into_witness();
let finalized_header_root = ssz_merkleize_chunks(
builder,
&sha256_chip,
Expand Down Expand Up @@ -230,11 +232,11 @@ impl<S: Spec, F: Field> StepCircuit<S, F> {
const INPUT_SIZE: usize = 8 * 3 + 32 * 2;
let mut input = [0; INPUT_SIZE];

let mut attested_slot_le = args.attested_header.slot.to_le_bytes().to_vec();
let mut attested_slot_le = args.attested_header.slot.as_u64().to_le_bytes().to_vec();
attested_slot_le.resize(8, 0);
input[..8].copy_from_slice(&attested_slot_le);

let mut finalized_slot_le = args.finalized_header.slot.to_le_bytes().to_vec();
let mut finalized_slot_le = args.finalized_header.slot.as_u64().to_le_bytes().to_vec();
finalized_slot_le.resize(8, 0);
input[8..16].copy_from_slice(&finalized_slot_le);

Expand All @@ -250,9 +252,7 @@ impl<S: Spec, F: Field> StepCircuit<S, F> {

let finalized_header_root: [u8; 32] = args
.finalized_header
.clone()
.hash_tree_root()
.unwrap()
.tree_hash_root()
.as_ref()
.try_into()
.unwrap();
Expand Down Expand Up @@ -435,10 +435,7 @@ impl<S: Spec> AppCircuit for StepCircuit<S, bn256::Fr> {
mod tests {
use std::fs;

use crate::{
aggregation_circuit::AggregationConfigPinning, util::Halo2ConfigPinning,
witness::SyncStepArgs,
};
use crate::{aggregation_circuit::AggregationConfigPinning, util::Halo2ConfigPinning};

use super::*;
use ark_std::{end_timer, start_timer};
Expand Down
21 changes: 12 additions & 9 deletions lightclient-circuits/src/witness/multiproof.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// TODO: A lot if not all/most of this code is copy pasta from: https://github.com/ralexstokes/ssz-rs/pull/118 which is mostly implemented w.r.t. the spec
// TODO: Remove this once the above PR lands in ssz-rs

use ethereum_types::Hash256;
use sha2::{Digest, Sha256};
use ssz_rs::Node;
use std::collections::{HashMap, HashSet};

pub type GeneralizedIndex = usize;
Expand Down Expand Up @@ -93,7 +93,7 @@ pub fn get_helper_indices(indices: &[GeneralizedIndex]) -> Vec<GeneralizedIndex>
all_branch_indices
}

pub fn calculate_merkle_root(leaf: Node, proof: &[Node], index: GeneralizedIndex) -> Node {
pub fn calculate_merkle_root(leaf: Hash256, proof: &[Hash256], index: GeneralizedIndex) -> Hash256 {
debug_assert_eq!(proof.len(), get_path_length(index));
let mut result = leaf;

Expand All @@ -114,15 +114,15 @@ pub fn calculate_merkle_root(leaf: Node, proof: &[Node], index: GeneralizedIndex
/// Calculate the Merkle root of a set of leaves and their corresponding proofs.
/// Note: `indices` and `leaves` must be in the same order as they correspond to each other.
pub fn calculate_multi_merkle_root(
leaves: &[Node],
proof: &[Node],
leaves: &[Hash256],
proof: &[Hash256],
indices: &[GeneralizedIndex],
) -> Node {
) -> Hash256 {
assert_eq!(leaves.len(), indices.len());
let helper_indices = get_helper_indices(indices);
assert_eq!(proof.len(), helper_indices.len());

let mut objects: HashMap<usize, Node> = indices
let mut objects: HashMap<usize, Hash256> = indices
.iter()
.chain(helper_indices.iter())
.copied()
Expand Down Expand Up @@ -163,9 +163,9 @@ pub fn calculate_multi_merkle_root(
/// Return an array representing the tree nodes by generalized index:
/// [0, 1, 2, 3, 4, 5, 6, 7], where each layer is a power of 2. The 0 index is ignored. The 1 index is the root.
/// The result will be twice the size as the padded bottom layer for the input leaves.
pub fn merkle_tree(leaves: &[Node]) -> Vec<Node> {
pub fn merkle_tree(leaves: &[Hash256]) -> Vec<Hash256> {
let bottom_length = get_power_of_two_ceil(leaves.len());
let mut o = vec![Node::default(); bottom_length * 2];
let mut o = vec![Hash256::default(); bottom_length * 2];
o[bottom_length..bottom_length + leaves.len()].copy_from_slice(leaves);
for i in (1..bottom_length).rev() {
let left = o[i * 2].as_ref();
Expand All @@ -178,7 +178,10 @@ pub fn merkle_tree(leaves: &[Node]) -> Vec<Node> {
o
}

pub fn create_multiproof(merkle_tree: &[Node], indices_to_prove: &[GeneralizedIndex]) -> Vec<Node> {
pub fn create_multiproof(
merkle_tree: &[Hash256],
indices_to_prove: &[GeneralizedIndex],
) -> Vec<Hash256> {
get_helper_indices(indices_to_prove)
.into_iter()
.map(|i| merkle_tree[i])
Expand Down
Loading

0 comments on commit 8902f51

Please sign in to comment.