revm_database_interface/
async_db.rs1use core::future::Future;
2
3use crate::{DBErrorMarker, Database, DatabaseRef};
4use core::error::Error;
5use primitives::{Address, B256, U256};
6use state::{AccountInfo, Bytecode};
7use tokio::runtime::{Handle, Runtime};
8
9pub trait DatabaseAsync {
15 type Error: Send + DBErrorMarker + Error;
17
18 fn basic_async(
20 &mut self,
21 address: Address,
22 ) -> impl Future<Output = Result<Option<AccountInfo>, Self::Error>> + Send;
23
24 fn code_by_hash_async(
26 &mut self,
27 code_hash: B256,
28 ) -> impl Future<Output = Result<Bytecode, Self::Error>> + Send;
29
30 fn storage_async(
32 &mut self,
33 address: Address,
34 index: U256,
35 ) -> impl Future<Output = Result<U256, Self::Error>> + Send;
36
37 fn block_hash_async(
39 &mut self,
40 number: u64,
41 ) -> impl Future<Output = Result<B256, Self::Error>> + Send;
42}
43
44pub trait DatabaseAsyncRef {
50 type Error: Send + DBErrorMarker + Error;
52
53 fn basic_async_ref(
55 &self,
56 address: Address,
57 ) -> impl Future<Output = Result<Option<AccountInfo>, Self::Error>> + Send;
58
59 fn code_by_hash_async_ref(
61 &self,
62 code_hash: B256,
63 ) -> impl Future<Output = Result<Bytecode, Self::Error>> + Send;
64
65 fn storage_async_ref(
67 &self,
68 address: Address,
69 index: U256,
70 ) -> impl Future<Output = Result<U256, Self::Error>> + Send;
71
72 fn block_hash_async_ref(
74 &self,
75 number: u64,
76 ) -> impl Future<Output = Result<B256, Self::Error>> + Send;
77}
78
79#[derive(Debug)]
81pub struct WrapDatabaseAsync<T> {
82 db: T,
83 rt: HandleOrRuntime,
84}
85
86impl<T> WrapDatabaseAsync<T> {
87 pub fn new(db: T) -> Option<Self> {
91 let rt = match Handle::try_current() {
92 Ok(handle) => match handle.runtime_flavor() {
93 tokio::runtime::RuntimeFlavor::CurrentThread => return None,
94 _ => HandleOrRuntime::Handle(handle),
95 },
96 Err(_) => return None,
97 };
98 Some(Self { db, rt })
99 }
100
101 pub fn with_runtime(db: T, runtime: Runtime) -> Self {
107 let rt = HandleOrRuntime::Runtime(runtime);
108 Self { db, rt }
109 }
110
111 pub fn with_handle(db: T, handle: Handle) -> Self {
118 let rt = HandleOrRuntime::Handle(handle);
119 Self { db, rt }
120 }
121}
122
123impl<T: DatabaseAsync> Database for WrapDatabaseAsync<T> {
124 type Error = T::Error;
125
126 #[inline]
127 fn basic(&mut self, address: Address) -> Result<Option<AccountInfo>, Self::Error> {
128 self.rt.block_on(self.db.basic_async(address))
129 }
130
131 #[inline]
132 fn code_by_hash(&mut self, code_hash: B256) -> Result<Bytecode, Self::Error> {
133 self.rt.block_on(self.db.code_by_hash_async(code_hash))
134 }
135
136 #[inline]
137 fn storage(&mut self, address: Address, index: U256) -> Result<U256, Self::Error> {
138 self.rt.block_on(self.db.storage_async(address, index))
139 }
140
141 #[inline]
142 fn block_hash(&mut self, number: u64) -> Result<B256, Self::Error> {
143 self.rt.block_on(self.db.block_hash_async(number))
144 }
145}
146
147impl<T: DatabaseAsyncRef> DatabaseRef for WrapDatabaseAsync<T> {
148 type Error = T::Error;
149
150 #[inline]
151 fn basic_ref(&self, address: Address) -> Result<Option<AccountInfo>, Self::Error> {
152 self.rt.block_on(self.db.basic_async_ref(address))
153 }
154
155 #[inline]
156 fn code_by_hash_ref(&self, code_hash: B256) -> Result<Bytecode, Self::Error> {
157 self.rt.block_on(self.db.code_by_hash_async_ref(code_hash))
158 }
159
160 #[inline]
161 fn storage_ref(&self, address: Address, index: U256) -> Result<U256, Self::Error> {
162 self.rt.block_on(self.db.storage_async_ref(address, index))
163 }
164
165 #[inline]
166 fn block_hash_ref(&self, number: u64) -> Result<B256, Self::Error> {
167 self.rt.block_on(self.db.block_hash_async_ref(number))
168 }
169}
170
171#[derive(Debug)]
173enum HandleOrRuntime {
174 Handle(Handle),
175 Runtime(Runtime),
176}
177
178impl HandleOrRuntime {
179 #[inline]
180 fn block_on<F>(&self, f: F) -> F::Output
181 where
182 F: Future + Send,
183 F::Output: Send,
184 {
185 match self {
186 Self::Handle(handle) => tokio::task::block_in_place(move || handle.block_on(f)),
187 Self::Runtime(rt) => rt.block_on(f),
188 }
189 }
190}