fix: init guard in noncemanager (#2227)

This commit is contained in:
James Prestwich 2023-03-04 17:37:50 -08:00 committed by GitHub
parent 1c90e1b76a
commit e54666b467
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 29 additions and 14 deletions

View File

@ -9,6 +9,7 @@ use thiserror::Error;
/// consecutive transactions without waiting for them to hit the mempool /// consecutive transactions without waiting for them to hit the mempool
pub struct NonceManagerMiddleware<M> { pub struct NonceManagerMiddleware<M> {
inner: M, inner: M,
init_guard: futures_locks::Mutex<()>,
initialized: AtomicBool, initialized: AtomicBool,
nonce: AtomicU64, nonce: AtomicU64,
address: Address, address: Address,
@ -21,7 +22,13 @@ where
/// Instantiates the nonce manager with a 0 nonce. The `address` should be the /// Instantiates the nonce manager with a 0 nonce. The `address` should be the
/// address which you'll be sending transactions from /// address which you'll be sending transactions from
pub fn new(inner: M, address: Address) -> Self { pub fn new(inner: M, address: Address) -> Self {
Self { initialized: false.into(), nonce: 0.into(), inner, address } Self {
inner,
init_guard: Default::default(),
initialized: Default::default(),
nonce: Default::default(),
address,
}
} }
/// Returns the next nonce to be used /// Returns the next nonce to be used
@ -34,8 +41,20 @@ where
&self, &self,
block: Option<BlockId>, block: Option<BlockId>,
) -> Result<U256, NonceManagerError<M>> { ) -> Result<U256, NonceManagerError<M>> {
if self.initialized.load(Ordering::SeqCst) {
// return current nonce
return Ok(self.nonce.load(Ordering::SeqCst).into())
}
let _guard = self.init_guard.lock().await;
// do this again in case multiple tasks enter this codepath
if self.initialized.load(Ordering::SeqCst) {
// return current nonce
return Ok(self.nonce.load(Ordering::SeqCst).into())
}
// initialize the nonce the first time the manager is called // initialize the nonce the first time the manager is called
if !self.initialized.load(Ordering::SeqCst) {
let nonce = self let nonce = self
.inner .inner
.get_transaction_count(self.address, block) .get_transaction_count(self.address, block)
@ -44,11 +63,7 @@ where
self.nonce.store(nonce.as_u64(), Ordering::SeqCst); self.nonce.store(nonce.as_u64(), Ordering::SeqCst);
self.initialized.store(true, Ordering::SeqCst); self.initialized.store(true, Ordering::SeqCst);
Ok(nonce) Ok(nonce)
} else { } // guard dropped here
// return current nonce
Ok(self.nonce.load(Ordering::SeqCst).into())
}
}
async fn get_transaction_count_with_manager( async fn get_transaction_count_with_manager(
&self, &self,