signet_sim/cache/
state.rs1use alloy::{
2 primitives::{Address, U256},
3 providers::Provider,
4 transports::TransportError,
5};
6use core::future::Future;
7use trevm::revm::database_interface::async_db::DatabaseAsyncRef;
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
14pub struct AcctInfo {
15 pub nonce: u64,
17 pub balance: U256,
19 pub has_code: bool,
21}
22
23pub trait StateSource: Send + Sync {
26 type Error: core::error::Error + Send + 'static;
28
29 fn account_details(
31 &self,
32 address: &Address,
33 ) -> impl Future<Output = Result<AcctInfo, Self::Error>> + Send;
34
35 fn nonce(&self, address: &Address) -> impl Future<Output = Result<u64, Self::Error>> + Send {
38 async { self.account_details(address).await.map(|info| info.nonce) }
39 }
40
41 fn balance(&self, address: &Address) -> impl Future<Output = Result<U256, Self::Error>> + Send {
43 async { self.account_details(address).await.map(|info| info.balance) }
44 }
45
46 fn map<T: Send, F: FnOnce(&AcctInfo) -> T + Send>(
48 &self,
49 address: &Address,
50 f: F,
51 ) -> impl Future<Output = Result<T, Self::Error>> + Send {
52 async { self.account_details(address).await.map(|info| f(&info)) }
53 }
54}
55
56impl<Db> StateSource for Db
57where
58 Db: DatabaseAsyncRef + Send + Sync,
59 Db::Error: Send + 'static,
60{
61 type Error = Db::Error;
62
63 async fn account_details(&self, address: &Address) -> Result<AcctInfo, Self::Error> {
64 let info = self.basic_async_ref(*address).await?.unwrap_or_default();
65 let has_code = info.code_hash() != trevm::revm::primitives::KECCAK_EMPTY;
66 Ok(AcctInfo { nonce: info.nonce, balance: info.balance, has_code })
67 }
68}
69
70#[derive(Debug, Clone)]
77pub struct ProviderStateSource<P>(pub P);
78
79impl<P: Provider> StateSource for ProviderStateSource<P> {
80 type Error = TransportError;
81
82 async fn account_details(&self, address: &Address) -> Result<AcctInfo, Self::Error> {
83 let (nonce, balance, code) = tokio::join!(
84 self.0.get_transaction_count(*address),
85 self.0.get_balance(*address),
86 self.0.get_code_at(*address),
87 );
88 Ok(AcctInfo { nonce: nonce?, balance: balance?, has_code: !code?.is_empty() })
89 }
90}