[Bug] Nonce Conflict with Cloned Provider in CachedNonceManager
- Vorherrschende Sprache
- Rust
- Sterne
- 1.3k
- Forks
- 668
- Ø Merge
- 2 T. 2 Std.
- Gemergte PRs (30 T.)
- 29
Beschreibung
### Component
rpc, other, contract
### What version of Alloy are you on?
1.7.3
### Operating System
macOS (Apple Silicon)
### Describe the bug
We observed this error in our production log:
```
error=Alloy contract, error: server returned an error response: error code 3: nonce too low: next nonce 87, tx nonce 86
```
**Cause:**
We were using `CachedNonceManager` and cloning the provider in two places, which caused nonce conflicts. Switching to `Arc` before cloning mitigated the issue.
**Observation:**
I could not reproduce the issue in my test. Even when sending multiple transactions sequentially with the same provider clone, the nonces were correctly handled:
* Test setup uses `ProviderType::from_signer_ws` and clones the provider twice.
* Approve transactions (`tx_1` → `tx_4`) all succeeded.
* Expected `tx_3` to fail due to a nonce conflict, but it passed.
**Test code snippet:**
```rust
let provider = ProviderType::from_signer_ws(&signer, ws.clone()).await?;
let provider_1 = provider.clone();
let provider_2 = provider.clone();
let approve_one = Address::from_str("0x0000000000000000000000000000000000000001")?;
let approve_two = Address::from_str("0x0000000000000000000000000000000000000002")?;
let contract_one = IERC20Instance::new(WBTC_OFT_ADDRESS, &provider_1);
let contract_two = IERC20Instance::new(BASE_USDC_ADDRESS, &provider_2);
let tx_1 = contract_one.approve(addr1, U256::ONE).send().await?.get_receipt().await?; # `CachedNonceManager->get_next_nonce` should internally call `get_transaction_count`
let tx_2 = contract_two.approve(addr2, U256::ONE).send().await?.get_receipt().await?; # `CachedNonceManager->get_next_nonce` should internally call `get_transaction_count`
let tx_3 = contract_one.approve(addr1, U256::ONE).send().await?.get_receipt().await?; # `CachedNonceManager->get_next_nonce` should now use the nonce of tx_2 and should have failed.
let tx_4 = contract_two.approve(addr2, U256::ONE).send().await?.get_receipt().await?;
```
**Question:**
Why doesn’t the nonce conflict reproduce in testing even with cloned providers?
**Note:**
- We’re using a single dedicated account for this code, so no nonce conflicts can occur from transactions sent elsewhere.
Beitragsleitfaden
Bewertung
Dieses Issue wurde noch nicht bewertet.