Skip to content

Commit

Permalink
feat: rpc_headers in cast and config (foundry-rs#9429)
Browse files Browse the repository at this point in the history
* feat: specify `rpc_headers` in cast and config

* test
  • Loading branch information
yash-atreya authored and rplusq committed Nov 29, 2024
1 parent fa910fe commit f61e961
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 5 deletions.
18 changes: 18 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ alloy-transport = { version = "0.6.4", default-features = false }
alloy-transport-http = { version = "0.6.4", default-features = false }
alloy-transport-ipc = { version = "0.6.4", default-features = false }
alloy-transport-ws = { version = "0.6.4", default-features = false }
alloy-node-bindings = { version = "0.6.4", default-features = false }

## alloy-core
alloy-dyn-abi = "0.8.11"
Expand Down
1 change: 1 addition & 0 deletions crates/cast/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ tikv-jemallocator = { workspace = true, optional = true }
[dev-dependencies]
anvil.workspace = true
foundry-test-utils.workspace = true
alloy-node-bindings.workspace = true

async-trait.workspace = true
divan.workspace = true
Expand Down
8 changes: 3 additions & 5 deletions crates/cast/bin/cmd/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,11 +107,9 @@ impl RunArgs {
let compute_units_per_second =
if self.no_rate_limit { Some(u64::MAX) } else { self.compute_units_per_second };

let provider = foundry_common::provider::ProviderBuilder::new(
&config.get_rpc_url_or_localhost_http()?,
)
.compute_units_per_second_opt(compute_units_per_second)
.build()?;
let provider = foundry_cli::utils::get_provider_builder(&config)?
.compute_units_per_second_opt(compute_units_per_second)
.build()?;

let tx_hash = self.tx_hash.parse().wrap_err("invalid tx hash")?;
let tx = provider
Expand Down
7 changes: 7 additions & 0 deletions crates/cli/src/opts/ethereum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ pub struct RpcOpts {
/// Default value: 45
#[arg(long, env = "ETH_RPC_TIMEOUT")]
pub rpc_timeout: Option<u64>,

/// Specify custom headers for RPC requests.
#[arg(long, alias = "headers", env = "ETH_RPC_HEADERS", value_delimiter(','))]
pub rpc_headers: Option<Vec<String>>,
}

impl_figment_convert_cast!(RpcOpts);
Expand Down Expand Up @@ -95,6 +99,9 @@ impl RpcOpts {
if let Some(rpc_timeout) = self.rpc_timeout {
dict.insert("eth_rpc_timeout".into(), rpc_timeout.into());
}
if let Some(headers) = &self.rpc_headers {
dict.insert("eth_rpc_headers".into(), headers.clone().into());
}
dict
}
}
Expand Down
10 changes: 10 additions & 0 deletions crates/cli/src/utils/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ pub const STATIC_FUZZ_SEED: [u8; 32] = [
0x5d, 0x64, 0x0b, 0x19, 0xad, 0xf0, 0xe3, 0x57, 0xb8, 0xd4, 0xbe, 0x7d, 0x49, 0xee, 0x70, 0xe6,
];

const DEFAULT_USER_AGENT: &str = concat!("foundry/", env!("CARGO_PKG_VERSION"));

/// Useful extensions to [`std::path::Path`].
pub trait FoundryPathExt {
/// Returns true if the [`Path`] ends with `.t.sol`
Expand Down Expand Up @@ -110,6 +112,14 @@ pub fn get_provider_builder(config: &Config) -> Result<ProviderBuilder> {
builder = builder.timeout(Duration::from_secs(rpc_timeout));
}

if let Some(mut rpc_headers) = config.eth_rpc_headers.clone() {
if !rpc_headers.iter().any(|h| h.starts_with("User-Agent:")) {
rpc_headers.push(format!("User-Agent:{DEFAULT_USER_AGENT}"));
}

builder = builder.headers(rpc_headers);
}

Ok(builder)
}

Expand Down
10 changes: 10 additions & 0 deletions crates/config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,15 @@ pub struct Config {
pub eth_rpc_jwt: Option<String>,
/// Timeout that should be used for any rpc calls
pub eth_rpc_timeout: Option<u64>,
/// Headers that should be used for any rpc calls
///
/// # Example
///
/// rpc_headers = ["x-custom-header:value", "x-another-header:another-value"]
///
/// You can also the ETH_RPC_HEADERS env variable like so:
/// `ETH_RPC_HEADERS="x-custom-header:value x-another-header:another-value"`
pub eth_rpc_headers: Option<Vec<String>>,
/// etherscan API key, or alias for an `EtherscanConfig` in `etherscan` table
pub etherscan_api_key: Option<String>,
/// Multiple etherscan api configs and their aliases
Expand Down Expand Up @@ -2347,6 +2356,7 @@ impl Default for Config {
eth_rpc_url: None,
eth_rpc_jwt: None,
eth_rpc_timeout: None,
eth_rpc_headers: None,
etherscan_api_key: None,
verbosity: 0,
remappings: vec![],
Expand Down
1 change: 1 addition & 0 deletions crates/forge/tests/cli/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ forgetest!(can_extract_config_values, |prj, cmd| {
eth_rpc_url: Some("localhost".to_string()),
eth_rpc_jwt: None,
eth_rpc_timeout: None,
eth_rpc_headers: None,
etherscan_api_key: None,
etherscan: Default::default(),
verbosity: 4,
Expand Down

0 comments on commit f61e961

Please sign in to comment.