Skip to main content

cast/cmd/
da_estimate.rs

1//! Estimates the data availability size of a block for opstack.
2
3use alloy_consensus::BlockHeader;
4use alloy_network::{AnyNetwork, BlockResponse, Ethereum, Network, eip2718::Encodable2718};
5use alloy_provider::Provider;
6use alloy_rpc_types::BlockId;
7use clap::Parser;
8use eyre::Result;
9use foundry_cli::{
10    opts::{NetworkVariant, RpcOpts},
11    utils::LoadConfig,
12};
13use foundry_common::provider::ProviderBuilder;
14use foundry_config::Config;
15use op_alloy_network::Optimism;
16
17/// CLI arguments for `cast da-estimate`.
18#[derive(Debug, Parser)]
19pub struct DAEstimateArgs {
20    /// The block to estimate the data availability size for.
21    pub block: BlockId,
22    #[command(flatten)]
23    pub rpc: RpcOpts,
24    /// Specify the Network for correct encoding.
25    #[arg(long, short, num_args = 1, value_name = "NETWORK")]
26    network: Option<NetworkVariant>,
27}
28
29impl DAEstimateArgs {
30    /// Load the RPC URL from the config file.
31    pub async fn run(self) -> Result<()> {
32        let Self { block, rpc, network } = self;
33        let config = rpc.load_config()?;
34        let network = match network {
35            Some(n) => n,
36            None => {
37                let provider = ProviderBuilder::<AnyNetwork>::from_config(&config)?.build()?;
38                provider.get_chain_id().await?.into()
39            }
40        };
41        match network {
42            NetworkVariant::Optimism => da_estimate::<Optimism>(&config, block).await,
43            NetworkVariant::Ethereum => da_estimate::<Ethereum>(&config, block).await,
44            NetworkVariant::Tempo => Err(eyre::eyre!(
45                "DA estimation is not supported for Tempo: EIP-4844 blob transactions are not available on this network"
46            )),
47        }
48    }
49}
50
51pub async fn da_estimate<N: Network>(config: &Config, block_id: BlockId) -> Result<()> {
52    let provider = ProviderBuilder::<N>::from_config(config)?.build()?;
53    let block =
54        provider.get_block(block_id).full().await?.ok_or_else(|| eyre::eyre!("Block not found"))?;
55
56    let block_number = block.header().number();
57    let tx_count = block.transactions().len();
58    let mut da_estimate = 0;
59    for tx in block.transactions().txns() {
60        da_estimate += op_alloy_flz::tx_estimated_size_fjord(&tx.as_ref().encoded_2718());
61    }
62    sh_println!(
63        "Estimated data availability size for block {block_number} with {tx_count} transactions: {da_estimate}"
64    )?;
65    Ok(())
66}