Skip to content

Commit

Permalink
fix evm equivalence tests
Browse files Browse the repository at this point in the history
  • Loading branch information
nulltea committed Dec 11, 2023
1 parent 59b88f3 commit bb8386a
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 169 deletions.
124 changes: 69 additions & 55 deletions contract-tests/tests/rotation_input_encoding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,20 @@ where
[(); Spec::SYNC_COMMITTEE_SIZE]:,
{
fn from(args: CommitteeRotationArgs<Spec>) -> Self {
let poseidon_commitment_le = poseidon_committee_commitment_from_compressed(
let poseidon_commitment_be = poseidon_committee_commitment_from_compressed(
&args.pubkeys_compressed.iter().cloned().collect_vec(),
)
.unwrap()
.into_iter()
.rev() // need to reverse to match the endianness of the solidity encoding
.collect_vec()
.try_into()
.unwrap();

// Endianess here is super confusing
// This should be solved by having `committee_poseidong` only be `uint256`
// See https://github.com/ChainSafe/Spectre/pull/42

let mut pk_vector: Vector<Vector<u8, 48>, { Spec::SYNC_COMMITTEE_SIZE }> = args
.pubkeys_compressed
.iter()
Expand All @@ -52,66 +61,71 @@ where

RotateInput {
sync_committee_ssz,
sync_committee_poseidon: poseidon_commitment_le,
sync_committee_poseidon: poseidon_commitment_be,
}
}
}

#[rstest]
#[tokio::test]
async fn test_rotate_public_input_evm_equivalence(
#[files("../consensus-spec-tests/tests/minimal/capella/light_client/sync/pyspec_tests/**")]
#[exclude("deneb*")]
path: PathBuf,
) -> anyhow::Result<()> {
let (_, witness) = read_test_files_and_gen_witness(&path);
let accumulator = [bn256::Fr::zero(); 12]; // this can be anything.. The test is just checking it gets correctly concatenated to the start of the encoded input

let instance = CommitteeUpdateCircuit::<Minimal, bn256::Fr>::instance(&witness, LIMB_BITS);
let finalized_block_root = witness
.finalized_header
.clone()
.hash_tree_root()
.unwrap()
.deref()
.try_into()
.unwrap();
#[cfg(test)]
mod tests {
use super::*;

let (_anvil_instance, ethclient) = make_client();
let contract = RotateExternal::deploy(ethclient, ())?.send().await?;
/// Convert a slice of field elements into an array of U256 ready to pass to a soliditiy call via ethers
fn solidity_encode_fr_array<const N: usize>(frs: &[bn256::Fr]) -> [ethers::types::U256; N] {
frs.iter()
.map(|v| ethers::types::U256::from_little_endian(&v.to_bytes()))
.collect_vec()
.try_into()
.expect("incompatible input slice length with return type")
}

let result = contract
.to_public_inputs(
RotateInput::from(witness),
finalized_block_root,
solidity_encode_fr_array(&accumulator),
)
.call()
.await?;

let result_decoded = decode_solidity_u256_array(&result);
// The expected result is the concatenation of the accumulator and the instance
let expected: Vec<_> = accumulator.iter().chain(instance[0].iter()).collect();
assert_eq!(result_decoded.iter().collect::<Vec<_>>(), expected);
Ok(())
}
fn decode_solidity_u256_array(uints: &[ethers::types::U256]) -> Vec<bn256::Fr> {
uints
.iter()
.map(|v| {
let mut b = [0_u8; 32];
v.to_little_endian(&mut b);
bn256::Fr::from_bytes(&b).expect("bad bn256::Fr encoding")
})
.collect()
}

/// Convert a slice of field elements into an array of U256 ready to pass to a soliditiy call via ethers
fn solidity_encode_fr_array<const N: usize>(frs: &[bn256::Fr]) -> [ethers::types::U256; N] {
frs.iter()
.map(|v| ethers::types::U256::from_little_endian(&v.to_bytes()))
.collect_vec()
.try_into()
.expect("incompatible input slice length with return type")
}
#[rstest]
#[tokio::test]
async fn test_rotate_public_input_evm_equivalence(
#[files("../consensus-spec-tests/tests/minimal/capella/light_client/sync/pyspec_tests/**")]
#[exclude("deneb*")]
path: PathBuf,
) -> anyhow::Result<()> {
let (_, witness) = read_test_files_and_gen_witness(&path);
let accumulator = [bn256::Fr::zero(); 12]; // this can be anything.. The test is just checking it gets correctly concatenated to the start of the encoded input

fn decode_solidity_u256_array(uints: &[ethers::types::U256]) -> Vec<bn256::Fr> {
uints
.iter()
.map(|v| {
let mut b = [0_u8; 32];
v.to_little_endian(&mut b);
bn256::Fr::from_bytes(&b).expect("bad bn256::Fr encoding")
})
.collect()
let instance = CommitteeUpdateCircuit::<Minimal, bn256::Fr>::instance(&witness, LIMB_BITS);
let finalized_block_root = witness
.finalized_header
.clone()
.hash_tree_root()
.unwrap()
.deref()
.try_into()
.unwrap();

let (_anvil_instance, ethclient) = make_client();
let contract = RotateExternal::deploy(ethclient, ())?.send().await?;

let result = contract
.to_public_inputs(
RotateInput::from(witness),
finalized_block_root,
solidity_encode_fr_array(&accumulator),
)
.call()
.await?;

let result_decoded = decode_solidity_u256_array(&result);
// The expected result is the concatenation of the accumulator and the instance
let expected: Vec<_> = accumulator.iter().chain(instance[0].iter()).collect();
assert_eq!(result_decoded.iter().collect::<Vec<_>>(), expected);
Ok(())
}
}
114 changes: 0 additions & 114 deletions prover/tests/rpc_step.rs

This file was deleted.

0 comments on commit bb8386a

Please sign in to comment.