axiom_circuit/subquery/
storage.rs

1use anyhow::Result;
2use axiom_codec::types::native::{AnySubquery, StorageSubquery};
3use axiom_query::axiom_eth::{halo2_base::AssignedValue, Field};
4use ethers::{
5    providers::{JsonRpcClient, Middleware, Provider},
6    types::{BigEndianHash, BlockId, H256},
7};
8use tokio::runtime::Runtime;
9
10use super::{caller::FetchSubquery, types::AssignedStorageSubquery};
11
12pub async fn get_storage_field_value<P: JsonRpcClient>(
13    provider: &Provider<P>,
14    query: StorageSubquery,
15) -> Result<H256> {
16    let block_id = BlockId::from(query.block_number as u64);
17    let val = provider
18        .get_storage_at(query.addr, H256::from_uint(&query.slot), Some(block_id))
19        .await?;
20
21    Ok(val)
22}
23
24impl<F: Field> FetchSubquery<F> for AssignedStorageSubquery<F> {
25    fn fetch<P: JsonRpcClient>(&self, p: &Provider<P>) -> Result<H256> {
26        let rt = Runtime::new()?;
27        let val = rt.block_on(get_storage_field_value(p, (*self).into()))?;
28        Ok(val)
29    }
30
31    fn any_subquery(&self) -> AnySubquery {
32        AnySubquery::Storage((*self).into())
33    }
34
35    fn flatten(&self) -> Vec<AssignedValue<F>> {
36        vec![self.block_number, self.addr, self.slot.hi(), self.slot.lo()]
37    }
38}