Skip to content

Commit 9058812

Browse files
authored
feat(cheatcodes): add rpc with url overload (#8316)
1 parent bd72b05 commit 9058812

File tree

5 files changed

+86
-39
lines changed

5 files changed

+86
-39
lines changed

crates/cheatcodes/assets/cheatcodes.json

Lines changed: 40 additions & 20 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/cheatcodes/spec/src/vm.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -611,6 +611,12 @@ interface Vm {
611611
#[cheatcode(group = Evm, safety = Safe)]
612612
function rpc(string calldata method, string calldata params) external returns (bytes memory data);
613613

614+
/// Performs an Ethereum JSON-RPC request to the given endpoint.
615+
#[cheatcode(group = Evm, safety = Safe)]
616+
function rpc(string calldata urlOrAlias, string calldata method, string calldata params)
617+
external
618+
returns (bytes memory data);
619+
614620
/// Gets all the logs according to specified filter.
615621
#[cheatcode(group = Evm, safety = Safe)]
616622
function eth_getLogs(uint256 fromBlock, uint256 toBlock, address target, bytes32[] memory topics)

crates/cheatcodes/src/evm/fork.rs

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -233,29 +233,20 @@ impl Cheatcode for isPersistentCall {
233233
}
234234
}
235235

236-
impl Cheatcode for rpcCall {
236+
impl Cheatcode for rpc_0Call {
237237
fn apply_stateful<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
238238
let Self { method, params } = self;
239239
let url =
240240
ccx.ecx.db.active_fork_url().ok_or_else(|| fmt_err!("no active fork URL found"))?;
241-
let provider = ProviderBuilder::new(&url).build()?;
242-
let params_json: serde_json::Value = serde_json::from_str(params)?;
243-
let result =
244-
foundry_common::block_on(provider.raw_request(method.clone().into(), params_json))
245-
.map_err(|err| fmt_err!("{method:?}: {err}"))?;
246-
247-
let result_as_tokens = match crate::json::json_value_to_token(&result)
248-
.map_err(|err| fmt_err!("failed to parse result: {err}"))?
249-
{
250-
DynSolValue::FixedBytes(bytes, size) => {
251-
// converted fixed bytes to bytes to prevent evm encoding issues: <https://github.com/foundry-rs/foundry/issues/8287>
252-
DynSolValue::Bytes(bytes.as_slice()[..size].to_vec())
253-
}
254-
DynSolValue::Address(addr) => DynSolValue::Bytes(addr.to_vec()),
255-
val => val,
256-
};
241+
rpc_call(&url, method, params)
242+
}
243+
}
257244

258-
Ok(result_as_tokens.abi_encode())
245+
impl Cheatcode for rpc_1Call {
246+
fn apply(&self, state: &mut Cheatcodes) -> Result {
247+
let Self { urlOrAlias, method, params } = self;
248+
let url = state.config.rpc_url(urlOrAlias)?;
249+
rpc_call(&url, method, params)
259250
}
260251
}
261252

@@ -392,3 +383,26 @@ fn check_broadcast(state: &Cheatcodes) -> Result<()> {
392383
fn persist_caller<DB: DatabaseExt>(ccx: &mut CheatsCtxt<DB>) {
393384
ccx.ecx.db.add_persistent_account(ccx.caller);
394385
}
386+
387+
/// Performs an Ethereum JSON-RPC request to the given endpoint.
388+
fn rpc_call(url: &str, method: &str, params: &str) -> Result {
389+
let provider = ProviderBuilder::new(url).build()?;
390+
let params_json: serde_json::Value = serde_json::from_str(params)?;
391+
let result =
392+
foundry_common::block_on(provider.raw_request(method.to_string().into(), params_json))
393+
.map_err(|err| fmt_err!("{method:?}: {err}"))?;
394+
395+
let result_as_tokens = match crate::json::json_value_to_token(&result)
396+
.map_err(|err| fmt_err!("failed to parse result: {err}"))?
397+
{
398+
// Convert fixed bytes to bytes to prevent encoding issues.
399+
// See: <https://github.com/foundry-rs/foundry/issues/8287>
400+
DynSolValue::FixedBytes(bytes, size) => {
401+
DynSolValue::Bytes(bytes.as_slice()[..size].to_vec())
402+
}
403+
DynSolValue::Address(addr) => DynSolValue::Bytes(addr.to_vec()),
404+
val => val,
405+
};
406+
407+
Ok(result_as_tokens.abi_encode())
408+
}

testdata/cheats/Vm.sol

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

testdata/default/cheats/Fork2.t.sol

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,12 @@ contract ForkTest is DSTest {
228228
bytes memory result = vm.rpc("eth_getBalance", file);
229229
assertEq(hex"10b7c11bcb51e6", result);
230230
}
231+
232+
function testRpcWithUrl() public {
233+
bytes memory result = vm.rpc("rpcAlias", "eth_blockNumber", "[]");
234+
uint256 decodedResult = vm.parseUint(vm.toString(result));
235+
assertGt(decodedResult, 20_000_000);
236+
}
231237
}
232238

233239
contract DummyContract {

0 commit comments

Comments
 (0)