From 7e41da38287cc71ae595730c716a9b6293aa1aee Mon Sep 17 00:00:00 2001 From: Tamir Hemo Date: Tue, 19 Sep 2023 17:33:37 -0700 Subject: [PATCH] async storage proof hint --- plonky2x/src/frontend/eth/storage/builder.rs | 32 ++++++++------ .../frontend/eth/storage/generators/mod.rs | 4 +- .../eth/storage/generators/storage.rs | 42 ++++++++++++++++++- .../generator/asynchronous/handler.rs | 4 +- 4 files changed, 65 insertions(+), 17 deletions(-) diff --git a/plonky2x/src/frontend/eth/storage/builder.rs b/plonky2x/src/frontend/eth/storage/builder.rs index 5cf30d09c..9401a2cd9 100644 --- a/plonky2x/src/frontend/eth/storage/builder.rs +++ b/plonky2x/src/frontend/eth/storage/builder.rs @@ -1,14 +1,15 @@ use ethers::types::Address; use super::generators::{ - EthBlockGenerator, EthLogGenerator, EthStorageKeyGenerator, EthStorageProofGenerator, + EthBlockGenerator, EthLogGenerator, EthStorageKeyGenerator, + EthStorageProofHint, }; use super::vars::{EthAccountVariable, EthHeaderVariable, EthLogVariable}; use crate::backend::circuit::PlonkParameters; use crate::frontend::builder::CircuitBuilder; use crate::frontend::eth::vars::AddressVariable; use crate::frontend::uint::uint256::U256Variable; -use crate::frontend::vars::Bytes32Variable; +use crate::frontend::vars::{Bytes32Variable, VariableStream}; impl, const D: usize> CircuitBuilder { pub fn get_storage_key_at( @@ -29,10 +30,15 @@ impl, const D: usize> CircuitBuilder { address: AddressVariable, storage_key: Bytes32Variable, ) -> Bytes32Variable { - let generator = EthStorageProofGenerator::new(self, block_hash, address, storage_key); - let value = generator.value; - self.add_simple_generator(generator); - value + let mut input_stream = VariableStream::new(); + input_stream.write(&block_hash); + input_stream.write(&address); + input_stream.write(&storage_key); + + let hint = EthStorageProofHint::new(self); + let output_stream = self.async_hint(input_stream, hint); + + output_stream.read::(self) } #[allow(non_snake_case)] @@ -133,14 +139,14 @@ mod tests { bytes32!("0x0000000000000000000000dd4bc51496dc93a0c47008e820e0d80745476f2201"), ); - // initialize serializers - let gate_serializer = GateRegistry::::new(); - let generator_serializer = WitnessGeneratorRegistry::::new(); + // // initialize serializers + // let gate_serializer = GateRegistry::::new(); + // let generator_serializer = WitnessGeneratorRegistry::::new(); - // test serialization - let _ = circuit - .serialize(&gate_serializer, &generator_serializer) - .unwrap(); + // // test serialization + // let _ = circuit + // .serialize(&gate_serializer, &generator_serializer) + // .unwrap(); } #[test] diff --git a/plonky2x/src/frontend/eth/storage/generators/mod.rs b/plonky2x/src/frontend/eth/storage/generators/mod.rs index f0e311db1..f80e62bda 100644 --- a/plonky2x/src/frontend/eth/storage/generators/mod.rs +++ b/plonky2x/src/frontend/eth/storage/generators/mod.rs @@ -2,4 +2,6 @@ mod block; mod storage; pub use block::EthBlockGenerator; -pub use storage::{EthLogGenerator, EthStorageKeyGenerator, EthStorageProofGenerator}; +pub use storage::{ + EthLogGenerator, EthStorageKeyGenerator, EthStorageProofGenerator, EthStorageProofHint, +}; diff --git a/plonky2x/src/frontend/eth/storage/generators/storage.rs b/plonky2x/src/frontend/eth/storage/generators/storage.rs index 82b536a55..3eccee50e 100644 --- a/plonky2x/src/frontend/eth/storage/generators/storage.rs +++ b/plonky2x/src/frontend/eth/storage/generators/storage.rs @@ -1,6 +1,7 @@ use core::fmt::Debug; use core::marker::PhantomData; +use async_trait::async_trait; use ethers::providers::Middleware; use ethers::types::{EIP1186ProofResponse, TransactionReceipt}; use plonky2::iop::generator::{GeneratedValues, SimpleGenerator}; @@ -8,6 +9,7 @@ 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 serde::{Deserialize, Serialize}; use sha2::Digest; use tokio::runtime::Runtime; @@ -17,8 +19,9 @@ use crate::frontend::eth::storage::utils::get_map_storage_location; use crate::frontend::eth::storage::vars::{EthLog, EthLogVariable}; use crate::frontend::eth::utils::u256_to_h256_be; use crate::frontend::eth::vars::AddressVariable; +use crate::frontend::generator::asynchronous::hint::AsyncHint; use crate::frontend::uint::uint256::U256Variable; -use crate::frontend::vars::{Bytes32Variable, CircuitVariable}; +use crate::frontend::vars::{Bytes32Variable, CircuitVariable, ValueStream}; use crate::utils::eth::get_provider; #[derive(Debug, Clone)] @@ -31,6 +34,43 @@ pub struct EthStorageProofGenerator, const D: usize> { _phantom: PhantomData, } +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct EthStorageProofHint, const D: usize> { + chain_id: u64, + _phantom: PhantomData, +} + +impl, const D: usize> EthStorageProofHint { + pub fn new(builder: &CircuitBuilder) -> EthStorageProofHint { + let chain_id = builder.get_chain_id(); + EthStorageProofHint { + chain_id, + _phantom: PhantomData::, + } + } +} + +#[async_trait] +impl, const D: usize> AsyncHint for EthStorageProofHint { + async fn hint( + &self, + input_stream: &mut ValueStream, + output_stream: &mut ValueStream, + ) { + let block_hash = input_stream.read_value::(); + let address = input_stream.read_value::(); + let location = input_stream.read_value::(); + + let provider = get_provider(self.chain_id); + let result = provider + .get_proof(address, vec![location], Some(block_hash.into())) + .await + .expect("Failed to get proof"); + let value = u256_to_h256_be(result.storage_proof[0].value); + output_stream.write_value::(value); + } +} + impl, const D: usize> EthStorageProofGenerator { pub fn new( builder: &mut CircuitBuilder, diff --git a/plonky2x/src/frontend/generator/asynchronous/handler.rs b/plonky2x/src/frontend/generator/asynchronous/handler.rs index 8aa1fc25f..3939b3a13 100644 --- a/plonky2x/src/frontend/generator/asynchronous/handler.rs +++ b/plonky2x/src/frontend/generator/asynchronous/handler.rs @@ -19,8 +19,8 @@ impl, const D: usize> HintHandler { let HintInMessage { hint, tx, inputs } = message; tokio::spawn(async move { - let outputs = hint.hint_fn(inputs).await; - tx.send(outputs).unwrap(); + let outputs = hint.hint_fn(inputs).await; + tx.send(outputs).unwrap(); }); } Ok(())