[Feature] Use of Provider Layers in the `PendingTransactionBuilder`
- Vorherrschende Sprache
- Rust
- Sterne
- 1.3k
- Forks
- 668
- Ø Merge
- 2 T. 2 Std.
- Gemergte PRs (30 T.)
- 29
Beschreibung
### Component
provider, pubsub
### Describe the feature you would like
I'm currently working with a number of RPCs where getting the transactions receipt can possibly fail even after the transaction has been confirmed. Geth is one of them where sometimes getting the receipt fails with `-32000: transaction indexing is in progress` even after the transaction has been confirmed.
To combat this I wrote a provider layer that would attempt to get the receipt for a given duration and timeout if we fail to get the receipt in that duration. The layer's primary code looks like the following:
```rust
impl Provider for ReceiptRetryProvider
where
P: Provider,
N: Network,
{
#[inline(always)]
fn root(&self) -> &RootProvider {
self.inner.root()
}
fn get_transaction_receipt(
&self,
hash: TxHash,
) -> ProviderCall<(TxHash,), Option<::ReceiptResponse>> {
tracing::info!("Inside the retry layer");
let client = self.inner.weak_client();
let polling_duration = self.polling_duration;
let polling_interval = self.polling_interval;
ProviderCall::BoxedFuture(Box::pin(async move {
let client = client
.upgrade()
.ok_or_else(|| TransportErrorKind::custom_str("RPC client dropped"))?;
let receipt = timeout(polling_duration, async move {
let mut interval = interval(polling_interval);
loop {
let result = client
.request::<(TxHash,), Option<::ReceiptResponse>>(
"eth_getTransactionReceipt",
(hash,),
)
.await;
if let Ok(Some(receipt)) = result {
return receipt;
}
interval.tick().await;
}
})
.await
.map_err(|_| {
RpcError::local_usage_str("Timeout when waiting for transaction receipt")
})?;
Ok(Some(receipt))
}))
}
}
```
In simple terms, attempt to get the receipt over a given duration and interval and throw a timeout error if we fail to get the receipt back within the allowed timeout.
The main problem that I have is that my added layer means that I can no longer make use of the `PendingTransactionBuilder` and the elegant API that it provides since it uses the `RootProvider` and not a generic `P: Provider` which means that all of the layers that I add to my provider are not used.
https://github.com/alloy-rs/alloy/blob/14835b09066edb36ccca778fc0d22bcdf2488145/crates/provider/src/heart.rs#L93-L96
I thought about pushing this layer further down the stack and into the client layers, but it would then mean that I need to JSON deserialize all (or most) my requests and responses in this layer which would be considerable overhead for the requests.
So, to make my feature request clear: Could the `PendingTransactionBuilder` have a generic `P` over any `Provider` to allow the requests made by the `PendingTransactionBuilder` to go through the layers I added to my provider?
### Additional context
_No response_
Beitragsleitfaden
Bewertung
Dieses Issue wurde noch nicht bewertet.