Skip to content

Commit

Permalink
async storage proof hint
Browse files Browse the repository at this point in the history
  • Loading branch information
tamirhemo committed Sep 20, 2023
1 parent baa4f9e commit 7e41da3
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 17 deletions.
32 changes: 19 additions & 13 deletions plonky2x/src/frontend/eth/storage/builder.rs
Original file line number Diff line number Diff line change
@@ -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<L: PlonkParameters<D>, const D: usize> CircuitBuilder<L, D> {
pub fn get_storage_key_at(
Expand All @@ -29,10 +30,15 @@ impl<L: PlonkParameters<D>, const D: usize> CircuitBuilder<L, D> {
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::<Bytes32Variable>(self)
}

#[allow(non_snake_case)]
Expand Down Expand Up @@ -133,14 +139,14 @@ mod tests {
bytes32!("0x0000000000000000000000dd4bc51496dc93a0c47008e820e0d80745476f2201"),
);

// initialize serializers
let gate_serializer = GateRegistry::<L, D>::new();
let generator_serializer = WitnessGeneratorRegistry::<L, D>::new();
// // initialize serializers
// let gate_serializer = GateRegistry::<L, D>::new();
// let generator_serializer = WitnessGeneratorRegistry::<L, D>::new();

// test serialization
let _ = circuit
.serialize(&gate_serializer, &generator_serializer)
.unwrap();
// // test serialization
// let _ = circuit
// .serialize(&gate_serializer, &generator_serializer)
// .unwrap();
}

#[test]
Expand Down
4 changes: 3 additions & 1 deletion plonky2x/src/frontend/eth/storage/generators/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};
42 changes: 41 additions & 1 deletion plonky2x/src/frontend/eth/storage/generators/storage.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
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};
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;

Expand All @@ -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)]
Expand All @@ -31,6 +34,43 @@ pub struct EthStorageProofGenerator<L: PlonkParameters<D>, const D: usize> {
_phantom: PhantomData<L>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EthStorageProofHint<L: PlonkParameters<D>, const D: usize> {
chain_id: u64,
_phantom: PhantomData<L>,
}

impl<L: PlonkParameters<D>, const D: usize> EthStorageProofHint<L, D> {
pub fn new(builder: &CircuitBuilder<L, D>) -> EthStorageProofHint<L, D> {
let chain_id = builder.get_chain_id();
EthStorageProofHint {
chain_id,
_phantom: PhantomData::<L>,
}
}
}

#[async_trait]
impl<L: PlonkParameters<D>, const D: usize> AsyncHint<L, D> for EthStorageProofHint<L, D> {
async fn hint(
&self,
input_stream: &mut ValueStream<L, D>,
output_stream: &mut ValueStream<L, D>,
) {
let block_hash = input_stream.read_value::<Bytes32Variable>();
let address = input_stream.read_value::<AddressVariable>();
let location = input_stream.read_value::<Bytes32Variable>();

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::<Bytes32Variable>(value);
}
}

impl<L: PlonkParameters<D>, const D: usize> EthStorageProofGenerator<L, D> {
pub fn new(
builder: &mut CircuitBuilder<L, D>,
Expand Down
4 changes: 2 additions & 2 deletions plonky2x/src/frontend/generator/asynchronous/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ impl<L: PlonkParameters<D>, const D: usize> HintHandler<L, D> {
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(())
Expand Down

0 comments on commit 7e41da3

Please sign in to comment.