Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: read rpc config when using fork cheatcodes #9547

Merged
merged 12 commits into from
Dec 14, 2024
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}")]);
}
Comment on lines +333 to +337
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cool

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
Loading