Skip to content

Commit

Permalink
merge
Browse files Browse the repository at this point in the history
  • Loading branch information
ratankaliani committed Aug 30, 2023
2 parents e5c9a93 + 4018306 commit 6c1deb9
Show file tree
Hide file tree
Showing 8 changed files with 256 additions and 78 deletions.
3 changes: 2 additions & 1 deletion plonky2x/src/backend/circuit/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ use plonky2::util::serialization::{Buffer, IoResult, WitnessGeneratorSerializer}

use crate::frontend::eth::storage::generators::block::EthBlockGenerator;
use crate::frontend::eth::storage::generators::storage::{
EthAccountProofGenerator, EthStorageKeyGenerator, EthStorageProofGenerator,
EthAccountProofGenerator, EthStorageKeyGenerator, EthStorageProofGenerator, EthLogGenerator
};
use crate::frontend::hash::keccak::keccak256::Keccack256Generator;

Expand Down Expand Up @@ -146,6 +146,7 @@ where
EthStorageProofGenerator<F, D>, "EthStorageProofGenerator",
EthAccountProofGenerator<F, D>, "EthAccountProofGenerator",
EthStorageKeyGenerator<F, D>, "EthStorageKeyGenerator",
EthLogGenerator<F, D>, "EthLogGenerator",
EthBlockGenerator<F, D>, "EthBlockGenerator",
Keccack256Generator<F, D>, "Keccak256Generator"
}
Expand Down
2 changes: 1 addition & 1 deletion plonky2x/src/frontend/ecc/ed25519/gadgets/eddsa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use core::fmt::Debug;
use curta::chip::ec::edwards::ed25519::Ed25519 as CurtaEd25519;
use curta::chip::ec::edwards::scalar_mul::generator::ScalarMulEd25519Gadget;
use curta::chip::ec::edwards::EdwardsParameters;
use curta::math::extension::CubicParameters;
use curta::math::extension::cubic::parameters::CubicParameters;
use plonky2::field::extension::Extendable;
use plonky2::hash::hash_types::RichField;
use plonky2::iop::target::{BoolTarget, Target};
Expand Down
91 changes: 80 additions & 11 deletions plonky2x/src/frontend/eth/storage/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use plonky2::hash::hash_types::RichField;
use super::generators::block::EthBlockGenerator;
use super::generators::storage::{
EthAccountProofGenerator, EthStorageKeyGenerator, EthStorageProofGenerator,
EthLogGenerator,
};
use super::vars::{EthAccountVariable, EthHeaderVariable, EthLogVariable};
use crate::frontend::builder::CircuitBuilder;
Expand All @@ -25,11 +26,11 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
#[allow(non_snake_case)]
pub fn eth_get_storage_at(
&mut self,
block_hash: Bytes32Variable,
address: AddressVariable,
storage_key: Bytes32Variable,
block_hash: Bytes32Variable,
) -> Bytes32Variable {
let generator = EthStorageProofGenerator::new(self, address, storage_key, block_hash);
let generator = EthStorageProofGenerator::new(self, block_hash, address, storage_key);
self.add_simple_generator(&generator);
generator.value
}
Expand All @@ -53,13 +54,15 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
}

#[allow(non_snake_case)]
pub fn eth_get_transaction_receipt(
pub fn eth_get_transaction_log(
&mut self,
_transaction_hash: Bytes32Variable,
_block_hash: Bytes32Variable,
_log_index: usize,
transaction_hash: Bytes32Variable,
block_hash: Bytes32Variable,
log_index: u64,
) -> EthLogVariable {
todo!()
let generator = EthLogGenerator::new(self, transaction_hash, block_hash, log_index);
self.add_simple_generator(&generator);
generator.value
}
}

Expand All @@ -68,12 +71,12 @@ mod tests {
use std::env;

use ethers::providers::{Http, Provider};
use ethers::types::U256;
use ethers::types::{U256, U64};
use plonky2::plonk::config::PoseidonGoldilocksConfig;

use super::*;
use crate::frontend::eth::storage::utils::get_map_storage_location;
use crate::frontend::eth::storage::vars::{EthAccount, EthHeader};
use crate::frontend::eth::storage::vars::{EthAccount, EthHeader, EthLog};
use crate::prelude::CircuitBuilderX;
use crate::utils::{address, bytes32};

Expand All @@ -91,7 +94,7 @@ mod tests {
let block_hash = builder.evm_read::<Bytes32Variable>();
let address = builder.evm_read::<AddressVariable>();
let location = builder.evm_read::<Bytes32Variable>();
let value = builder.eth_get_storage_at(address, location, block_hash);
let value = builder.eth_get_storage_at(block_hash, address, location);
builder.evm_write(value);

// Build your circuit.
Expand All @@ -100,10 +103,13 @@ mod tests {
// Write to the circuit input.
// These values are taken from Ethereum block https://etherscan.io/block/17880427
let mut input = circuit.input();
// block hash
input.evm_write::<Bytes32Variable>(bytes32!(
"0x281dc31bb78779a1ede7bf0f4d2bc5f07ddebc9f9d1155e413d8804384604bbe"
));
// address
input.evm_write::<AddressVariable>(address!("0x55032650b14df07b85bF18A3a3eC8E0Af2e028d5"));
// location
input.evm_write::<Bytes32Variable>(bytes32!(
"0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5"
));
Expand Down Expand Up @@ -284,7 +290,70 @@ mod tests {
"0x8fa46ad6b448faefbfc010736a3d39595ca68eb8bdd4e6b4ab30513bab688068"
),
difficulty: U256::from("0x0"),
number: U256::from("0x110d56b"),
number: U64::from("0x110d56b"),
gas_limit: U256::from("0x1c9c380"),
gas_used: U256::from("0x16041f6"),
time: U256::from("0x64d41817"),
}
);

let _ = circuit.serialize().unwrap();
}

#[test]
#[cfg_attr(feature = "ci", ignore)]
#[allow(non_snake_case)]
fn test_eth_get_transaction_log() {
dotenv::dotenv().ok();
let rpc_url = env::var("RPC_1").unwrap();
let provider = Provider::<Http>::try_from(rpc_url).unwrap();

// This is the circuit definition
let mut builder = CircuitBuilderX::new();
builder.set_execution_client(provider);
let transaction_hash = builder.read::<Bytes32Variable>();
let block_hash = builder.read::<Bytes32Variable>();
let log_index = 0u64;

let value = builder.eth_get_transaction_log(transaction_hash, block_hash, log_index);
builder.write(value);

// Build your circuit.
let circuit = builder.build::<PoseidonGoldilocksConfig>();

// Write to the circuit input.
// These values are taken from Ethereum block https://etherscan.io/block/17880427
let mut input = circuit.input();
// transaction hash
input.write::<Bytes32Variable>(bytes32!(
"0xead2251970404128e6f9bdff0133badb7338c5fa7ea4eec24e88af85a6d03cf2"
));
// block hash
input.write::<Bytes32Variable>(bytes32!(
"0x281dc31bb78779a1ede7bf0f4d2bc5f07ddebc9f9d1155e413d8804384604bbe"
));

// Generate a proof.
let (proof, output) = circuit.prove(&input);

// Verify proof.
circuit.verify(&proof, &input, &output);

// Read output.
let circuit_value = output.read::<EthLogVariable>();
println!("{:?}", circuit_value);
assert_eq!(
circuit_value,
EthLog {
address: address!("0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"),
topics: [
bytes32!("0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"),
bytes32!("0x00000000000000000000000059b4bb1f5d943cf71a10df63f6b743ee4a4489ee"),
bytes32!("0x000000000000000000000000def1c0ded9bec7f1a1670819833240f027b25eff")
],
data_hash: bytes32!(
"0x5cdda96947975d4afbc971c9aa8bb2cc684e158d10a0d878b3a5b8b0f895262c"
)
}
);

Expand Down
19 changes: 4 additions & 15 deletions plonky2x/src/frontend/eth/storage/generators/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,17 +67,6 @@ impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D>
})
.expect("No matching block found");

// Copy u64 into U256
let mut bytes = [0u8; 8];
result
.number
.expect("No block number")
.to_big_endian(&mut bytes);
// Append 24 zero bytes to the beginning of the number
let mut total_bytes = [0u8; 32];
total_bytes[24..].copy_from_slice(&bytes);

let number = ethers::types::U256::from_big_endian(&total_bytes);
let value = EthHeader {
parent_hash: result.parent_hash,
uncle_hash: result.uncles_hash,
Expand All @@ -88,10 +77,10 @@ impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D>
// bloom: H256::from_slice(&result.logs_bloom.expect("No bloom").0),
difficulty: result.difficulty,
// TODO: Convert to U64Variable
number,
// gas_limit: result.gas_limit,
// gas_used: result.gas_used,
// time: result.timestamp,
number: result.number.expect("No block number"),
gas_limit: result.gas_limit,
gas_used: result.gas_used,
time: result.timestamp,
// extra: result.extra_data,
};
self.value.set(buffer, value);
Expand Down
122 changes: 117 additions & 5 deletions plonky2x/src/frontend/eth/storage/generators/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,20 @@ use core::fmt::Debug;
use core::marker::PhantomData;

use ethers::providers::Middleware;
use ethers::types::EIP1186ProofResponse;
use ethers::types::{EIP1186ProofResponse, TransactionReceipt};
use plonky2::field::extension::Extendable;
use plonky2::hash::hash_types::RichField;
use plonky2::iop::generator::{GeneratedValues, SimpleGenerator};
use plonky2::iop::target::Target;
use plonky2::iop::witness::PartitionWitness;
use plonky2::plonk::circuit_data::CommonCircuitData;
use plonky2::util::serialization::{Buffer, IoResult, Read, Write};
use sha2::Digest;
use tokio::runtime::Runtime;

use crate::frontend::builder::CircuitBuilder;
use crate::frontend::eth::storage::utils::get_map_storage_location;
use crate::frontend::eth::storage::vars::{EthAccount, EthAccountVariable};
use crate::frontend::eth::storage::vars::{EthAccount, EthAccountVariable, EthLog, EthLogVariable};
use crate::frontend::eth::utils::u256_to_h256_be;
use crate::frontend::eth::vars::AddressVariable;
use crate::frontend::uint::uint256::U256Variable;
Expand All @@ -23,9 +24,9 @@ use crate::utils::eth::get_provider;

#[derive(Debug, Clone)]
pub struct EthStorageProofGenerator<F: RichField + Extendable<D>, const D: usize> {
block_hash: Bytes32Variable,
address: AddressVariable,
storage_key: Bytes32Variable,
block_hash: Bytes32Variable,
pub value: Bytes32Variable,
chain_id: u64,
_phantom: PhantomData<F>,
Expand All @@ -34,16 +35,16 @@ pub struct EthStorageProofGenerator<F: RichField + Extendable<D>, const D: usize
impl<F: RichField + Extendable<D>, const D: usize> EthStorageProofGenerator<F, D> {
pub fn new(
builder: &mut CircuitBuilder<F, D>,
block_hash: Bytes32Variable,
address: AddressVariable,
storage_key: Bytes32Variable,
block_hash: Bytes32Variable,
) -> EthStorageProofGenerator<F, D> {
let chain_id = builder.get_chain_id();
let value = builder.init::<Bytes32Variable>();
EthStorageProofGenerator {
block_hash,
address,
storage_key,
block_hash,
value,
chain_id,
_phantom: PhantomData::<F>,
Expand Down Expand Up @@ -304,3 +305,114 @@ impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D>
})
}
}

#[derive(Debug, Clone)]
pub struct EthLogGenerator<F: RichField + Extendable<D>, const D: usize> {
transaction_hash: Bytes32Variable,
block_hash: Bytes32Variable,
log_index: u64,
pub value: EthLogVariable,
chain_id: u64,
_phantom: PhantomData<F>,
}

impl<F: RichField + Extendable<D>, const D: usize> EthLogGenerator<F, D> {
pub fn new(
builder: &mut CircuitBuilder<F, D>,
transaction_hash: Bytes32Variable,
block_hash: Bytes32Variable,
log_index: u64,
) -> EthLogGenerator<F, D> {
let chain_id = builder.get_chain_id();
let value = builder.init::<EthLogVariable>();
EthLogGenerator {
transaction_hash,
block_hash,
log_index,
value,
chain_id,
_phantom: PhantomData::<F>,
}
}
}

impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D> for EthLogGenerator<F, D> {
fn id(&self) -> String {
"EthLogGenerator".to_string()
}

fn dependencies(&self) -> Vec<Target> {
let mut targets = Vec::new();
targets.extend(self.transaction_hash.targets());
targets.extend(self.block_hash.targets());
targets
}

fn run_once(&self, witness: &PartitionWitness<F>, buffer: &mut GeneratedValues<F>) {
let transaction_hash = self.transaction_hash.get(witness);
// block_hash is unused
let _block_hash = self.block_hash.get(witness);

let provider = get_provider(self.chain_id);
let rt = Runtime::new().expect("failed to create tokio runtime");
let result: TransactionReceipt = rt
.block_on(async {
provider
.get_transaction_receipt(transaction_hash)
.await
.expect("Failed to call get_transaction_receipt")
})
.expect("No transaction receipt found");

let log = &result.logs[self.log_index as usize];
let value = EthLog {
address: log.address,
topics: [log.topics[0], log.topics[1], log.topics[2]],
data_hash: ethers::types::H256::from_slice(sha2::Sha256::digest(&log.data).as_ref()),
};
self.value.set(buffer, value);
}

#[allow(unused_variables)]
fn serialize(&self, dst: &mut Vec<u8>, common_data: &CommonCircuitData<F, D>) -> IoResult<()> {
let chain_id_bytes = self.chain_id.to_be_bytes();
dst.write_all(&chain_id_bytes)?;

dst.write_target_vec(&self.transaction_hash.targets())?;
dst.write_target_vec(&self.block_hash.targets())?;

let log_index_bytes = self.log_index.to_be_bytes();
dst.write_all(&log_index_bytes)?;

dst.write_target_vec(&self.value.targets())
}

#[allow(unused_variables)]
fn deserialize(src: &mut Buffer, common_data: &CommonCircuitData<F, D>) -> IoResult<Self> {
let mut chain_id_bytes = [0u8; 8];
src.read_exact(&mut chain_id_bytes)?;
let chain_id = u64::from_be_bytes(chain_id_bytes);

let transaction_hash_targets = src.read_target_vec()?;
let transaction_hash = Bytes32Variable::from_targets(&transaction_hash_targets);

let block_hash_targets = src.read_target_vec()?;
let block_hash = Bytes32Variable::from_targets(&block_hash_targets);

let mut log_index_bytes = [0u8; 8];
src.read_exact(&mut log_index_bytes)?;
let log_index = u64::from_be_bytes(log_index_bytes);

let value_targets = src.read_target_vec()?;
let value = EthLogVariable::from_targets(&value_targets);

Ok(Self {
block_hash,
transaction_hash,
log_index,
value,
chain_id,
_phantom: PhantomData::<F>,
})
}
}
Loading

0 comments on commit 6c1deb9

Please sign in to comment.