Skip to content

Commit

Permalink
Hash-oracle-node Integration (#30)
Browse files Browse the repository at this point in the history
* RPC as a lib

* Add new RPC endpoints to allow for proof gen with witnesses already supplied

* Witness <> Arg conversion. Needs Cleanup

* Some cleanup

* Change state id to head

* Remove sync commitee rs lib

* Update SSZ and ethereum consensus crates

* fix test compilation

* clippy

* More clippy

* reexport jsonrpc_v2 lib

* fix prover

* clippy

* break up rotation args gen

* lightcleint update to args

* Remove all beacon fetching out of the prover node

* simplify generic

* verifier contract gen fixes

* add rpc endpoint for calculating poseidon committment

* clippy
  • Loading branch information
ec2 authored Nov 23, 2023
1 parent 356324c commit 6902971
Show file tree
Hide file tree
Showing 31 changed files with 1,104 additions and 377 deletions.
40 changes: 8 additions & 32 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,29 +24,14 @@ incremental = true
[workspace.dependencies]
lightclient-circuits = { path = "lightclient-circuits" }
test-utils = { path = "test-utils" }
ethereum-consensus-types = { git = "ssh://[email protected]/sygmaprotocol/Zipline.git", rev = "27e8a01" }
ethereum-consensus-types = { git = "ssh://[email protected]/sygmaprotocol/Zipline.git", rev = "5ecf28d24690862814a7ebc5385c7e5c2eeb6e3d" }
eth-types = { path = "eth-types" }
contracts = { path = "contracts" }
preprocessor = { path = "preprocessor" }
ssz-rs = { git = "https://github.com/ralexstokes/ssz-rs", rev = "adf1a0b14cef90b9536f28ef89da1fab316465e1" }
zipline-test-utils = { package = "test-utils", git = "ssh://[email protected]/sygmaprotocol/Zipline.git", rev = "27e8a01" }
light-client-verifier = { git = "ssh://[email protected]/sygmaprotocol/Zipline.git", rev = "27e8a01" }
sync-committee-primitives = { git = "https://github.com/polytope-labs/sync-committee-rs", version = "0.1.0" }
halo2curves = { git = "https://github.com/privacy-scaling-explorations/halo2curves", tag = "0.3.1" }
halo2-base = { git = "https://github.com/axiom-crypto/halo2-lib", branch = "community-edition", default-features = false, features = [
"halo2-pse",
"display",
] }
snark-verifier-sdk = { git = "https://github.com/axiom-crypto/snark-verifier.git", branch = "community-edition", default-features = false, features = [
"display",
"loader_halo2",
"loader_evm",
"halo2-pse",
] }

[patch."https://github.com/privacy-scaling-explorations/halo2curves"]
halo2curves = { git = "https://github.com/sygmaprotocol/halo2curves", branch = "dev/bls12_381" }
# halo2curves = { path = "../halo2curves" }
zipline-test-utils = { package = "test-utils", git = "ssh://[email protected]/sygmaprotocol/Zipline.git", rev = "5ecf28d24690862814a7ebc5385c7e5c2eeb6e3d" }
zipline-cryptography = { package = "cryptography", git = "ssh://[email protected]/sygmaprotocol/Zipline.git", rev = "5ecf28d24690862814a7ebc5385c7e5c2eeb6e3d" }
light-client-verifier = { git = "ssh://[email protected]/sygmaprotocol/Zipline.git", rev = "5ecf28d24690862814a7ebc5385c7e5c2eeb6e3d" }
beacon-api-client = { git = "https://github.com/ralexstokes/ethereum-consensus.git", rev = "f3bff52e9c43866f231ec40c8ab0e34125a8957f" }

# halo2
halo2_proofs = { git = "https://github.com/privacy-scaling-explorations/halo2.git", tag = "v2023_02_02", features = [
Expand Down Expand Up @@ -75,12 +60,7 @@ snark-verifier-sdk = { git = "https://github.com/axiom-crypto/snark-verifier.git
] }
halo2_solidity_verifier = { git = "https://github.com/privacy-scaling-explorations/halo2-solidity-verifier", branch = "ac/initial-verifier-PR" }

# ethereum types
sync-committee-primitives = { git = "https://github.com/polytope-labs/sync-committee-rs", version = "0.1.0" }
sync-committee-prover = { git = "https://github.com/polytope-labs/sync-committee-rs", version = "0.1.0", features = [
"testnet",
] }
ssz-rs = { git = "https://github.com/ralexstokes/ssz-rs", rev = "adf1a0b14cef90b9536f28ef89da1fab316465e1" }
ssz_rs = "0.9"

# crypto
group = "0.12"
Expand Down Expand Up @@ -111,9 +91,5 @@ poseidon = { git = "https://github.com/timoftime/halo2-lib", rev = "95bf9a5ce6b6
snark-verifier = { git = "https://github.com/timoftime/snark-verifier", branch = "timoftime/bump-revm" }
snark-verifier-sdk = { git = "https://github.com/timoftime/snark-verifier", branch = "timoftime/bump-revm" }

[patch."https://github.com/ralexstokes/ssz-rs"]
ssz-rs = { git = "https://github.com/polytope-labs/ssz-rs", branch = "main" }

[patch."https://github.com/polytope-labs/sync-committee-rs"]
sync-committee-prover = { git = "https://github.com/timoftime/sync-committee-rs", branch = "dev/accept-ssz" }
sync-committee-primitives = { git = "https://github.com/timoftime/sync-committee-rs", branch = "dev/accept-ssz" }
[patch.crates-io]
ssz_rs = { git = "https://github.com/ralexstokes/ssz-rs", rev = "5f1ec833718efa07bbbff427ab28a1eeaa706164" }
2 changes: 1 addition & 1 deletion contract-tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ lightclient-circuits = { workspace = true }
test-utils = { workspace = true }
halo2curves = { workspace = true }
eth-types = { workspace = true }
ssz-rs = { workspace = true }
ssz_rs = { workspace = true }
halo2-base = { workspace = true }
snark-verifier-sdk = { workspace = true }
contracts = { workspace = true }
8 changes: 5 additions & 3 deletions contract-tests/tests/rotation_input_encoding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@ use ethers::contract::abigen;
use halo2curves::bn256::{self, Fr};
use itertools::Itertools;
use lightclient_circuits::committee_update_circuit::CommitteeUpdateCircuit;
use lightclient_circuits::poseidon::poseidon_committee_commitment_from_compressed;
use lightclient_circuits::witness::CommitteeRotationArgs;
use rstest::rstest;
use ssz_rs::prelude::*;
use ssz_rs::Merkleized;
use test_utils::{poseidon_committee_commitment_from_compressed, read_test_files_and_gen_witness};
use std::ops::Deref;
use test_utils::read_test_files_and_gen_witness;

abigen!(
RotateExternal,
Expand All @@ -33,7 +35,7 @@ async fn test_rotate_public_input_evm_equivalence(
.clone()
.hash_tree_root()
.unwrap()
.as_bytes()
.deref()
.try_into()
.unwrap();

Expand Down Expand Up @@ -91,7 +93,7 @@ where
let sync_committee_ssz = pk_vector
.hash_tree_root()
.unwrap()
.as_bytes()
.deref()
.try_into()
.unwrap();

Expand Down
10 changes: 5 additions & 5 deletions contract-tests/tests/step_input_encoding.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
use std::ops::Deref;
use std::path::PathBuf;

use contract_tests::make_client;
use eth_types::Minimal;
use ethers::contract::abigen;
use halo2curves::bn256;
use lightclient_circuits::poseidon::poseidon_committee_commitment_from_uncompressed;
use lightclient_circuits::sync_step_circuit::SyncStepCircuit;
use lightclient_circuits::witness::SyncStepArgs;
use rstest::rstest;
use ssz_rs::Merkleized;
use test_utils::{
poseidon_committee_commitment_from_uncompressed, read_test_files_and_gen_witness,
};
use test_utils::read_test_files_and_gen_witness;

abigen!(
SyncStepExternal,
Expand Down Expand Up @@ -57,7 +57,7 @@ impl<Spec: eth_types::Spec> From<SyncStepArgs<Spec>> for SyncStepInput {
.clone()
.hash_tree_root()
.unwrap()
.as_bytes()
.deref()
.try_into()
.unwrap();

Expand All @@ -66,7 +66,7 @@ impl<Spec: eth_types::Spec> From<SyncStepArgs<Spec>> for SyncStepInput {
SyncStepInput {
attested_slot: args.attested_header.slot,
finalized_slot: args.finalized_header.slot,
participation: participation,
participation,
finalized_header_root,
execution_payload_root,
}
Expand Down
6 changes: 6 additions & 0 deletions contracts/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,9 @@ path = "rust-abi/lib.rs"

[dependencies]
ethers = "2.0.10"
lightclient-circuits.workspace = true
eth-types.workspace = true
ssz_rs.workspace = true
halo2curves = { workspace = true }
itertools = { workspace = true }
halo2-base = { workspace = true }
117 changes: 103 additions & 14 deletions contracts/rust-abi/lib.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,109 @@
use ethers::contract::abigen;

abigen!(Spectre, "./out/Spectre.sol/Spectre.json");

abigen!(StepVerifier, "./out/sync_step.sol/Verifier.json");
#![feature(generic_const_exprs)]
use std::ops::Deref;

use ethers::contract::abigen;
use halo2_base::utils::ScalarField;
use halo2curves::bls12_381::{self};
use halo2curves::bn256::Fr;
use itertools::Itertools;
use lightclient_circuits::{
poseidon::fq_array_poseidon_native,
witness::{CommitteeRotationArgs, SyncStepArgs},
};
use ssz_rs::{Merkleized, Vector};
abigen!(
Spectre,
"./out/Spectre.sol/Spectre.json";
StepVerifier,
"./out/sync_step.sol/Verifier.json";
CommitteeUpdateVerifier,
"./out/committee_update_aggregated.sol/Verifier.json"
);

abigen!(
"./out/committee_update_aggregated.sol/Verifier.json";
StepMockVerifier,
"./out/SyncStepMockVerifier.sol/SyncStepMockVerifier.json"
);

abigen!(
"./out/SyncStepMockVerifier.sol/SyncStepMockVerifier.json";
CommitteeUpdateMockVerifier,
"./out/CommitteeUpdateMockVerifier.sol/CommitteeUpdateMockVerifier.json"
"./out/CommitteeUpdateMockVerifier.sol/CommitteeUpdateMockVerifier.json";
RotateExternal,
"./out/RotateExternal.sol/RotateExternal.json";
SyncStepExternal,
"./out/SyncStepExternal.sol/SyncStepExternal.json";
);

// SyncStepInput type produced by abigen macro matches the solidity struct type
impl<Spec: eth_types::Spec> From<SyncStepArgs<Spec>> for SyncStepInput {
fn from(args: SyncStepArgs<Spec>) -> Self {
let participation = args
.pariticipation_bits
.iter()
.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 execution_payload_root: [u8; 32] = args.execution_payload_root.try_into().unwrap();

SyncStepInput {
attested_slot: args.attested_header.slot,
finalized_slot: args.finalized_header.slot,
participation,
finalized_header_root,
execution_payload_root,
}
}
}

// CommitteeRotationArgs type produced by abigen macro matches the solidity struct type
impl<Spec: eth_types::Spec> From<CommitteeRotationArgs<Spec, Fr>> for RotateInput
where
[(); Spec::SYNC_COMMITTEE_SIZE]:,
{
fn from(args: CommitteeRotationArgs<Spec, Fr>) -> Self {
let poseidon_commitment_le = poseidon_committee_commitment_from_compressed(
&args
.pubkeys_compressed
.iter()
.cloned()
.map(|mut b| {
b.reverse();
b
})
.collect_vec(),
);

let mut pk_vector: Vector<Vector<u8, 48>, { Spec::SYNC_COMMITTEE_SIZE }> = args
.pubkeys_compressed
.iter()
.cloned()
.map(|v| v.try_into().unwrap())
.collect_vec()
.try_into()
.unwrap();

let sync_committee_ssz = pk_vector
.hash_tree_root()
.unwrap()
.deref()
.try_into()
.unwrap();

RotateInput {
sync_committee_ssz,
sync_committee_poseidon: poseidon_commitment_le,
}
}
}

pub fn poseidon_committee_commitment_from_compressed(pubkeys_compressed: &[Vec<u8>]) -> [u8; 32] {
let pubkeys_x = pubkeys_compressed.iter().cloned().map(|mut bytes| {
bytes[47] &= 0b00011111;
bls12_381::Fq::from_bytes_le(&bytes)
});
let poseidon_commitment = fq_array_poseidon_native::<Fr>(pubkeys_x).unwrap();
poseidon_commitment.to_bytes_le().try_into().unwrap()
}
2 changes: 1 addition & 1 deletion contracts/snark-verifiers/sync_step.sol

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions eth-types/src/spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ 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)]
Expand Down
10 changes: 5 additions & 5 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,19 @@ lint: fmt
cargo clippy --all-targets --all-features --workspace

setup-step-circuit:
cargo run -r -- sync-step -c ./lightclient-circuits/config/sync_step.json -o artifacts -k 22
cargo run -r -- circuit sync-step -c ./lightclient-circuits/config/sync_step.json -o artifacts -k 22

setup-rotation-circuit:
cargo run -r -- committee-update -c ./lightclient-circuits/config/committee_update.json -o artifacts -k 18
cargo run -r -- circuit committee-update -c ./lightclient-circuits/config/committee_update.json -o artifacts -k 18
# TODO: generate committee-update snark
cargo run -r -- aggregation -c ./lightclient-circuits/config/aggregation.json --app-pk-path \
cargo run -r -- circuit aggregation -c ./lightclient-circuits/config/aggregation.json --app-pk-path \
./build/committee_update.pkey --app-config-path ./lightclient-circuits/config/committee_update.json -i ./rotation -o artifacts -k 22

gen-step-evm-verifier:
cargo run -r -- sync-step -c ./lightclient-circuits/config/sync_step.json -o evm-verifier ./contracts/snark-verifiers/sync_step.yul
cargo run -r -- circuit sync-step -c ./lightclient-circuits/config/sync_step.json -o evm-verifier ./contracts/snark-verifiers/sync_step.yul

gen-rotation-evm-verifier:
cargo run -r -- aggregation -c ./lightclient-circuits/config/aggregation.json --app-pk-path ./build/committee_update.pkey --app-config-path ./lightclient-circuits/config/committee_update.json -i ./rotation -o evm-verifier ./contracts/snark-verifiers/committee_update_aggregated.yul
cargo run -r -- circuit aggregation -c ./lightclient-circuits/config/aggregation.json --app-pk-path ./build/committee_update.pkey --app-config-path ./lightclient-circuits/config/committee_update.json -i ./rotation -o evm-verifier ./contracts/snark-verifiers/committee_update_aggregated.yul

build-contracts:
cd contracts && forge build
Expand Down
4 changes: 2 additions & 2 deletions lightclient-circuits/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ pasta_curves.workspace = true
ff.workspace = true
sha2.workspace = true
# ethereum
sync-committee-primitives.workspace = true
ssz-rs.workspace = true
ssz_rs = { workspace = true, features = ["serde"] }
ethereum-consensus-types ={ workspace = true, features = ["serde"] }

# local
eth-types.workspace = true
Expand Down
19 changes: 12 additions & 7 deletions lightclient-circuits/src/committee_update_circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ use pasta_curves::group::{ff, GroupEncoding};
use poseidon::PoseidonChip;
use snark_verifier_sdk::CircuitExt;
use ssz_rs::{Merkleized, Vector};
use sync_committee_primitives::consensus_types::BeaconBlockHeader;

#[allow(type_alias_bounds)]
#[derive(Clone, Debug, Default)]
Expand Down Expand Up @@ -162,8 +161,13 @@ impl<S: Spec, F: Field> CommitteeUpdateCircuit<S, F> {
let finalized_header_root = args.finalized_header.clone().hash_tree_root().unwrap();

let instance_vec = iter::once(poseidon_commitment)
.chain(ssz_root.0.map(|b| bn256::Fr::from(b as u64)))
.chain(finalized_header_root.0.map(|b| bn256::Fr::from(b as u64)))
.chain(ssz_root.as_ref().iter().map(|b| bn256::Fr::from(*b as u64)))
.chain(
finalized_header_root
.as_ref()
.iter()
.map(|b| bn256::Fr::from(*b as u64)),
)
.collect();

vec![instance_vec]
Expand Down Expand Up @@ -277,6 +281,7 @@ mod tests {
use super::*;
use ark_std::{end_timer, start_timer};
use eth_types::Testnet;
use ethereum_consensus_types::BeaconBlockHeader;
use halo2_base::{
gates::{
builder::{CircuitBuilderStage, FlexGateConfigParams},
Expand Down Expand Up @@ -325,7 +330,7 @@ mod tests {
pubkeys_compressed,
randomness: constant_randomness(),
_spec: PhantomData,
finalized_header: finalized_header,
finalized_header,
sync_committee_branch: committee_root_branch,
}
}
Expand Down Expand Up @@ -432,7 +437,7 @@ mod tests {
let agg_circuit = AggregationCircuit::create_circuit(
CircuitBuilderStage::Prover,
Some(agg_config),
&vec![snark.clone()],
&vec![snark],
AGG_K,
)
.unwrap();
Expand Down Expand Up @@ -551,7 +556,7 @@ mod tests {
Some(pinning.break_points),
lookup_bits,
&p1,
iter::once(l0_snark.clone()),
iter::once(l0_snark),
);
circuit.expose_previous_instances(false);

Expand Down Expand Up @@ -584,7 +589,7 @@ mod tests {
);
let mut circuit = AggregationCircuit::prover::<SHPLONK>(
&p2,
iter::once(l1_snark.clone()),
iter::once(l1_snark),
pinning.break_points,
);
circuit.expose_previous_instances(true);
Expand Down
Loading

0 comments on commit 6902971

Please sign in to comment.