alloy-rs / alloy

Transports, Middleware, and Networks for the Alloy project
https://alloy.rs
Apache License 2.0
652 stars 234 forks source link

[Feature] Alloy `ThrottleLayer` #1636

Open 0xKitsune opened 1 week ago

0xKitsune commented 1 week ago

Component

rpc, transports

Describe the feature you would like

In some instances, it would be useful to have a ThrottleLayer to not flood the node with requests all at once. While the RetryLayer works perfectly for retrying requests that exceed RPC provider limits, the ThrottleLayer could throttle outbound requests before they are sent.

The following snippet shows an example that fetches 100k blocks concurrently. In this example a ThrottleLayer would be helpful to limit n requests per second.


#[tokio::main]
async fn main() -> eyre::Result<()> {

   // --snip--

   // Init the provider
    let client = ClientBuilder::default()
        .layer(RetryBackoffLayer::new(10, 300, 330))
        .http(rpc_endpoint.parse()?);
    let provider = ProviderBuilder::new().on_client(client);

    let futures_unordered = FuturesUnordered::new();

    // Get 100_000 blocks
    let block_number = provider.get_block_number().await?;
    for i in block_number - 100_000..block_number {
        let provider = provider.clone();
        futures_unordered.push(async move {
            provider
                .get_block(i.into(), BlockTransactionsKind::Hashes)
                .await
        });
    }

    // Await the results
    let res = futures_unordered.collect::<Vec<_>>().await;

    Ok(())
}

We currently have a working version of a ThrottleLayer built and I would be happy to open a draft PR with this if you think it would be useful to add to alloy.

Additional context

No response

zerosnacks commented 10 hours ago

Hi @0xKitsune thanks for your suggestion

I think this could be useful addition, would be added to https://github.com/alloy-rs/alloy/tree/main/crates/transport/src/layers

cc @yash-atreya / @mattsse

zerosnacks commented 10 hours ago

Would be great if https://github.com/alloy-rs/alloy/issues/1147 is also considered as part of this scope / tested with wasm32-unknown-none