Skip to content

Commit

Permalink
fix: read rpc config when using fork cheatcodes (foundry-rs#9547)
Browse files Browse the repository at this point in the history
* read rpc config when using fork cheatcodes

* attempt to resolve failed environment variables again

* nit: refactor

* nit: refactor

* fix clippy errors

* fix rustfmt errors

* run cargofmt

* set auth header for fork

* remove redundant clone()

* Update crates/cheatcodes/src/config.rs

---------

Co-authored-by: Matthias Seitz <[email protected]>
  • Loading branch information
anukul and mattsse authored Dec 14, 2024
1 parent dabacec commit 233bff2
Show file tree
Hide file tree
Showing 10 changed files with 246 additions and 162 deletions.
37 changes: 16 additions & 21 deletions crates/cheatcodes/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use foundry_common::{fs::normalize_path, ContractsByArtifact};
use foundry_compilers::{utils::canonicalize, ProjectPathsConfig};
use foundry_config::{
cache::StorageCachingConfig, fs_permissions::FsAccessKind, Config, FsPermissions,
ResolvedRpcEndpoints,
ResolvedRpcEndpoint, ResolvedRpcEndpoints, RpcEndpoint, RpcEndpointUrl,
};
use foundry_evm_core::opts::EvmOpts;
use semver::Version;
Expand Down Expand Up @@ -185,33 +185,28 @@ impl CheatsConfig {
/// - Returns an error if `url_or_alias` is a known alias but references an unresolved env var.
/// - Returns an error if `url_or_alias` is not an alias but does not start with a `http` or
/// `ws` `scheme` and is not a path to an existing file
pub fn rpc_url(&self, url_or_alias: &str) -> Result<String> {
match self.rpc_endpoints.get(url_or_alias) {
Some(Ok(url)) => Ok(url.clone()),
Some(Err(err)) => {
// try resolve again, by checking if env vars are now set
err.try_resolve().map_err(Into::into)
}
None => {
// check if it's a URL or a path to an existing file to an ipc socket
if url_or_alias.starts_with("http") ||
url_or_alias.starts_with("ws") ||
// check for existing ipc file
Path::new(url_or_alias).exists()
{
Ok(url_or_alias.into())
} else {
Err(fmt_err!("invalid rpc url: {url_or_alias}"))
}
pub fn rpc_endpoint(&self, url_or_alias: &str) -> Result<ResolvedRpcEndpoint> {
if let Some(endpoint) = self.rpc_endpoints.get(url_or_alias) {
Ok(endpoint.clone().try_resolve())
} else {
// check if it's a URL or a path to an existing file to an ipc socket
if url_or_alias.starts_with("http") ||
url_or_alias.starts_with("ws") ||
// check for existing ipc file
Path::new(url_or_alias).exists()
{
let url = RpcEndpointUrl::Env(url_or_alias.to_string());
Ok(RpcEndpoint::new(url).resolve())
} else {
Err(fmt_err!("invalid rpc url: {url_or_alias}"))
}
}
}

/// Returns all the RPC urls and their alias.
pub fn rpc_urls(&self) -> Result<Vec<Rpc>> {
let mut urls = Vec::with_capacity(self.rpc_endpoints.len());
for alias in self.rpc_endpoints.keys() {
let url = self.rpc_url(alias)?;
let url = self.rpc_endpoint(alias)?.url()?;
urls.push(Rpc { key: alias.clone(), url });
}
Ok(urls)
Expand Down
10 changes: 8 additions & 2 deletions crates/cheatcodes/src/evm/fork.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ impl Cheatcode for rpc_0Call {
impl Cheatcode for rpc_1Call {
fn apply(&self, state: &mut Cheatcodes) -> Result {
let Self { urlOrAlias, method, params } = self;
let url = state.config.rpc_url(urlOrAlias)?;
let url = state.config.rpc_endpoint(urlOrAlias)?.url()?;
rpc_call(&url, method, params)
}
}
Expand Down Expand Up @@ -326,9 +326,15 @@ fn create_fork_request(
) -> Result<CreateFork> {
persist_caller(ccx);

let url = ccx.state.config.rpc_url(url_or_alias)?;
let rpc_endpoint = ccx.state.config.rpc_endpoint(url_or_alias)?;
let url = rpc_endpoint.url()?;
let mut evm_opts = ccx.state.config.evm_opts.clone();
evm_opts.fork_block_number = block;
evm_opts.fork_retries = rpc_endpoint.config.retries;
evm_opts.fork_retry_backoff = rpc_endpoint.config.retry_backoff;
if let Some(Ok(auth)) = rpc_endpoint.auth {
evm_opts.fork_headers = Some(vec![format!("Authorization: {auth}")]);
}
let fork = CreateFork {
enable_caching: !ccx.state.config.no_storage_caching &&
ccx.state.config.rpc_storage_caching.enable_for_endpoint(&url),
Expand Down
3 changes: 2 additions & 1 deletion crates/cheatcodes/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ impl Cheatcode for getFoundryVersionCall {
impl Cheatcode for rpcUrlCall {
fn apply(&self, state: &mut Cheatcodes) -> Result {
let Self { rpcAlias } = self;
state.config.rpc_url(rpcAlias).map(|url| url.abi_encode())
let url = state.config.rpc_endpoint(rpcAlias)?.url()?.abi_encode();
Ok(url)
}
}

Expand Down
6 changes: 3 additions & 3 deletions crates/chisel/src/dispatcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::{
use alloy_json_abi::{InternalType, JsonAbi};
use alloy_primitives::{hex, Address};
use forge_fmt::FormatterConfig;
use foundry_config::{Config, RpcEndpoint};
use foundry_config::{Config, RpcEndpointUrl};
use foundry_evm::{
decode::decode_console_logs,
traces::{
Expand Down Expand Up @@ -357,9 +357,9 @@ impl ChiselDispatcher {
{
endpoint.clone()
} else {
RpcEndpoint::Env(arg.to_string()).into()
RpcEndpointUrl::Env(arg.to_string()).into()
};
let fork_url = match endpoint.resolve() {
let fork_url = match endpoint.resolve().url() {
Ok(fork_url) => fork_url,
Err(e) => {
return DispatchResult::CommandFailed(Self::make_error(format!(
Expand Down
6 changes: 6 additions & 0 deletions crates/common/src/provider/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,12 @@ impl ProviderBuilder {
self
}

/// Sets http headers. If `None`, defaults to the already-set value.
pub fn maybe_headers(mut self, headers: Option<Vec<String>>) -> Self {
self.headers = headers.unwrap_or(self.headers);
self
}

/// Constructs the `RetryProvider` taking all configs into account.
pub fn build(self) -> Result<RetryProvider> {
let Self {
Expand Down
Loading

0 comments on commit 233bff2

Please sign in to comment.