arbiter_core/middleware/
nonce_middleware.rs1use std::sync::atomic::{AtomicBool, AtomicU64, Ordering};
11
12use ethers::providers::MiddlewareError;
13use thiserror::Error;
14
15use super::*;
16
17#[derive(Debug)]
18pub struct NonceManagerMiddleware<M> {
21 inner: M,
22 init_guard: futures_locks::Mutex<()>,
23 initialized: AtomicBool,
24 nonce: AtomicU64,
25 address: eAddress,
26}
27
28impl<M> NonceManagerMiddleware<M>
29where
30 M: Middleware,
31{
32 pub fn new(inner: M, address: eAddress) -> Self {
35 Self {
36 inner,
37 init_guard: Default::default(),
38 initialized: Default::default(),
39 nonce: Default::default(),
40 address,
41 }
42 }
43
44 pub fn next(&self) -> eU256 {
46 let nonce = self.nonce.fetch_add(1, Ordering::SeqCst);
47 nonce.into()
48 }
49 pub async fn initialize_nonce(
70 &self,
71 block: Option<BlockId>,
72 ) -> Result<eU256, NonceManagerError<M>> {
73 if self.initialized.load(Ordering::SeqCst) {
74 return Ok(self.nonce.load(Ordering::SeqCst).into());
76 }
77
78 let _guard = self.init_guard.lock().await;
79
80 if self.initialized.load(Ordering::SeqCst) {
82 return Ok(self.nonce.load(Ordering::SeqCst).into());
84 }
85
86 let nonce = self
89 .inner
90 .get_transaction_count(self.address, block)
91 .await
92 .map_err(MiddlewareError::from_err)?;
93 self.nonce.store(nonce.as_u64(), Ordering::SeqCst);
94 self.initialized.store(true, Ordering::SeqCst);
95 trace!("Nonce initialized for address: {:?}", self.address);
96 Ok(nonce)
97 } async fn get_transaction_count_with_manager(
100 &self,
101 block: Option<BlockId>,
102 ) -> Result<eU256, NonceManagerError<M>> {
103 if !self.initialized.load(Ordering::SeqCst) {
105 let nonce = self
106 .inner
107 .get_transaction_count(self.address, block)
108 .await
109 .map_err(MiddlewareError::from_err)?;
110 self.nonce.store(nonce.as_u64(), Ordering::SeqCst);
111 self.initialized.store(true, Ordering::SeqCst);
112 }
113
114 Ok(self.next())
115 }
116}
117
118#[derive(Error, Debug)]
119pub enum NonceManagerError<M: Middleware> {
121 #[error(transparent)]
123 MiddlewareError(M::Error),
124}
125
126impl<M: Middleware> MiddlewareError for NonceManagerError<M> {
127 type Inner = M::Error;
128
129 fn from_err(src: M::Error) -> Self {
130 NonceManagerError::MiddlewareError(src)
131 }
132
133 fn as_inner(&self) -> Option<&Self::Inner> {
134 match self {
135 NonceManagerError::MiddlewareError(e) => Some(e),
136 }
137 }
138}
139
140#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
141#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
142impl<M> Middleware for NonceManagerMiddleware<M>
143where
144 M: Middleware,
145{
146 type Error = NonceManagerError<M>;
147 type Provider = M::Provider;
148 type Inner = M;
149
150 fn inner(&self) -> &M {
151 &self.inner
152 }
153
154 async fn fill_transaction(
155 &self,
156 tx: &mut TypedTransaction,
157 block: Option<BlockId>,
158 ) -> Result<(), Self::Error> {
159 if tx.nonce().is_none() {
160 tx.set_nonce(self.get_transaction_count_with_manager(block).await?);
161 }
162
163 Ok(self
164 .inner()
165 .fill_transaction(tx, block)
166 .await
167 .map_err(MiddlewareError::from_err)?)
168 }
169
170 async fn send_transaction<T: Into<TypedTransaction> + Send + Sync>(
174 &self,
175 tx: T,
176 block: Option<BlockId>,
177 ) -> Result<PendingTransaction<'_, Self::Provider>, Self::Error> {
178 let mut tx = tx.into();
179
180 if tx.nonce().is_none() {
181 tx.set_nonce(self.get_transaction_count_with_manager(block).await?);
182 }
183
184 match self.inner.send_transaction(tx.clone(), block).await {
185 Ok(tx_hash) => Ok(tx_hash),
186 Err(err) => {
187 let nonce = self.get_transaction_count(self.address, block).await?;
188 if nonce != self.nonce.load(Ordering::SeqCst).into() {
189 self.nonce.store(nonce.as_u64(), Ordering::SeqCst);
192 tx.set_nonce(nonce);
193 trace!("Nonce incremented for address: {:?}", self.address);
194 self.inner
195 .send_transaction(tx, block)
196 .await
197 .map_err(MiddlewareError::from_err)
198 } else {
199 Err(MiddlewareError::from_err(err))
201 }
202 }
203 }
204 }
205}