@@ -4,34 +4,35 @@ use crate::{
44 Cheatcode , CheatsCtxt , DatabaseExt , Result , Vm :: * , json:: parse_json_as,
55 toml:: toml_to_json_value,
66} ;
7+ use alloy_chains:: Chain ;
78use alloy_dyn_abi:: { DynSolType , DynSolValue } ;
89use alloy_sol_types:: SolValue ;
9- use eyre:: OptionExt ;
1010use foundry_evm_core:: ContextExt ;
11+ use std:: borrow:: Cow ;
1112
1213impl Cheatcode for readForkChainIdsCall {
1314 fn apply ( & self , state : & mut crate :: Cheatcodes ) -> Result {
1415 let Self { } = self ;
15- Ok ( state
16- . config
17- . forks
18- . keys ( )
19- . map ( |name| alloy_chains:: Chain :: from_named ( name. parse ( ) . unwrap ( ) ) . id ( ) )
20- . collect :: < Vec < _ > > ( )
21- . abi_encode ( ) )
16+ Ok ( state. config . forks . keys ( ) . map ( |chain| chain. id ( ) ) . collect :: < Vec < _ > > ( ) . abi_encode ( ) )
2217 }
2318}
2419
2520impl Cheatcode for readForkChainsCall {
2621 fn apply ( & self , state : & mut crate :: Cheatcodes ) -> Result {
2722 let Self { } = self ;
28- Ok ( state. config . forks . keys ( ) . collect :: < Vec < _ > > ( ) . abi_encode ( ) )
23+ Ok ( state
24+ . config
25+ . forks
26+ . keys ( )
27+ . map ( |chain| get_chain_name ( chain) . to_string ( ) )
28+ . collect :: < Vec < _ > > ( )
29+ . abi_encode ( ) )
2930 }
3031}
3132
3233impl Cheatcode for readForkChainCall {
3334 fn apply_stateful ( & self , ccx : & mut CheatsCtxt ) -> Result {
34- Ok ( get_active_fork_chain_name ( ccx) ?. abi_encode ( ) )
35+ Ok ( get_chain_name ( & get_active_fork_chain ( ccx) ?) . to_string ( ) . abi_encode ( ) )
3536 }
3637}
3738
@@ -41,42 +42,38 @@ impl Cheatcode for readForkChainIdCall {
4142 }
4243}
4344
44- fn resolve_rpc_url ( name : & ' static str , state : & mut crate :: Cheatcodes ) -> Result {
45- // Get the chain ID from the chain_configs
46- if let Some ( config) = state. config . forks . get ( name) {
45+ fn resolve_rpc_url ( chain : Chain , state : & mut crate :: Cheatcodes ) -> Result {
46+ if let Some ( config) = state. config . forks . get ( & chain) {
4747 let rpc = match config. rpc_endpoint {
4848 Some ( ref url) => url. clone ( ) . resolve ( ) ,
49- None => state. config . rpc_endpoint ( name ) ?,
49+ None => state. config . rpc_endpoint ( & get_chain_name ( & chain ) ) ?,
5050 } ;
5151
5252 return Ok ( rpc. url ( ) ?. abi_encode ( ) ) ;
5353 }
5454
55- bail ! ( "[fork.{name}] subsection not found in [fork] of 'foundry.toml'" )
55+ bail ! (
56+ "'rpc_endpoint' not found in '[fork.<chain_id: {chain}>]' subsection of 'foundry.toml'" ,
57+ chain = chain. id( )
58+ )
5659}
5760
5861impl Cheatcode for readForkChainRpcUrlCall {
5962 fn apply ( & self , state : & mut crate :: Cheatcodes ) -> Result {
6063 let Self { id } = self ;
61- let name = get_chain_name ( id. to :: < u64 > ( ) ) ?;
62- resolve_rpc_url ( name, state)
64+ resolve_rpc_url ( Chain :: from_id ( id. to :: < u64 > ( ) ) , state)
6365 }
6466}
6567
6668impl Cheatcode for readForkRpcUrlCall {
6769 fn apply_stateful ( & self , ccx : & mut CheatsCtxt ) -> Result {
68- let name = get_active_fork_chain_name ( ccx) ?;
69- resolve_rpc_url ( name, ccx. state )
70+ resolve_rpc_url ( get_active_fork_chain ( ccx) ?, ccx. state )
7071 }
7172}
7273
7374/// Gets the alloy chain name for a given chain id.
74- fn get_chain_name ( id : u64 ) -> Result < & ' static str > {
75- let chain = alloy_chains:: Chain :: from_id ( id)
76- . named ( )
77- . ok_or_eyre ( "unknown name for active forked chain" ) ?;
78-
79- Ok ( chain. as_str ( ) )
75+ fn get_chain_name ( chain : & Chain ) -> Cow < ' static , str > {
76+ chain. named ( ) . map_or ( Cow :: Owned ( chain. id ( ) . to_string ( ) ) , |name| Cow :: Borrowed ( name. as_str ( ) ) )
8077}
8178
8279/// Gets the chain id of the active fork. Panics if no fork is selected.
@@ -88,9 +85,9 @@ fn get_active_fork_chain_id(ccx: &mut CheatsCtxt) -> Result<u64> {
8885 Ok ( env. cfg . chain_id )
8986}
9087
91- /// Gets the alloy chain name for the active fork. Panics if no fork is selected.
92- fn get_active_fork_chain_name ( ccx : & mut CheatsCtxt ) -> Result < & ' static str > {
93- get_chain_name ( get_active_fork_chain_id ( ccx) ? )
88+ /// Gets the alloy chain for the active fork. Panics if no fork is selected.
89+ fn get_active_fork_chain ( ccx : & mut CheatsCtxt ) -> Result < Chain > {
90+ get_active_fork_chain_id ( ccx) . map ( Chain :: from_id )
9491}
9592
9693// Helper macros to generate cheatcode implementations
@@ -99,7 +96,7 @@ macro_rules! impl_get_value_cheatcode {
9996 impl Cheatcode for $struct {
10097 fn apply_stateful( & self , ccx: & mut CheatsCtxt ) -> Result {
10198 let Self { key } = self ;
102- let chain = get_active_fork_chain_id ( ccx) ?;
99+ let chain = get_active_fork_chain ( ccx) ?;
103100 get_value( chain, key, $sol_type, ccx. state)
104101 }
105102 }
@@ -108,7 +105,7 @@ macro_rules! impl_get_value_cheatcode {
108105 impl Cheatcode for $struct {
109106 fn apply( & self , state: & mut crate :: Cheatcodes ) -> Result {
110107 let Self { chain, key } = self ;
111- get_value( chain. to:: <u64 >( ) , key, $sol_type, state)
108+ get_value( Chain :: from_id ( chain. to:: <u64 >( ) ) , key, $sol_type, state)
112109 }
113110 }
114111 } ;
@@ -119,16 +116,15 @@ macro_rules! impl_get_array_cheatcode {
119116 impl Cheatcode for $struct {
120117 fn apply_stateful( & self , ccx: & mut CheatsCtxt ) -> Result {
121118 let Self { key } = self ;
122- let chain = get_active_fork_chain_id( ccx) ?;
123- get_array( chain, key, $sol_type, ccx. state)
119+ get_array( get_active_fork_chain( ccx) ?, key, $sol_type, ccx. state)
124120 }
125121 }
126122 } ;
127123 ( $struct: ident, $sol_type: expr) => {
128124 impl Cheatcode for $struct {
129125 fn apply( & self , state: & mut crate :: Cheatcodes ) -> Result {
130126 let Self { chain, key } = self ;
131- get_array( chain. to:: <u64 >( ) , key, $sol_type, state)
127+ get_array( Chain :: from ( chain. to:: <u64 >( ) ) , key, $sol_type, state)
132128 }
133129 }
134130 } ;
@@ -178,44 +174,49 @@ impl_get_array_cheatcode!(readForkStringArrayCall, &DynSolType::String, stateful
178174
179175/// Generic helper to get any value from the TOML config.
180176fn get_toml_value < ' a > (
181- name : & ' a str ,
177+ chain : Chain ,
182178 key : & ' a str ,
183179 state : & ' a crate :: Cheatcodes ,
184180) -> Result < & ' a toml:: Value > {
185- let config = state. config . forks . get ( name) . ok_or_else ( || {
186- fmt_err ! ( "[fork.{name}] subsection not found in [fork] of 'foundry.toml'" )
181+ let config = state. config . forks . get ( & chain) . ok_or_else ( || {
182+ fmt_err ! (
183+ "'[fork.<chain_id: {chain}>]' subsection not found in 'foundry.toml'" ,
184+ chain = chain. id( )
185+ )
186+ } ) ?;
187+ let value = config. vars . get ( key) . ok_or_else ( || {
188+ fmt_err ! ( "variable '{key}' not found in '[fork.<chain_id: {chain}>]'" , chain = chain. id( ) )
187189 } ) ?;
188- let value = config
189- . vars
190- . get ( key)
191- . ok_or_else ( || fmt_err ! ( "Variable '{key}' not found in [fork.{name}] configuration" ) ) ?;
192190
193191 Ok ( value)
194192}
195193
196194/// Generic helper to get any single value from the TOML config.
197- fn get_value ( chain : u64 , key : & str , ty : & DynSolType , state : & crate :: Cheatcodes ) -> Result {
198- let name = get_chain_name ( chain) ?;
199- let value = get_toml_value ( name, key, state) ?;
200- let sol_value = parse_toml_element ( value, ty, key, name) ?;
195+ fn get_value ( chain : Chain , key : & str , ty : & DynSolType , state : & crate :: Cheatcodes ) -> Result {
196+ let value = get_toml_value ( chain, key, state) ?;
197+ let sol_value = parse_toml_element ( value, ty, key, chain) ?;
201198 Ok ( sol_value. abi_encode ( ) )
202199}
203200
204201/// Generic helper to get an array of values from the TOML config.
205- fn get_array ( chain : u64 , key : & str , element_ty : & DynSolType , state : & crate :: Cheatcodes ) -> Result {
206- let name = get_chain_name ( chain) ?;
207- let value = get_toml_value ( name, key, state) ?;
208-
209- let arr = value
210- . as_array ( )
211- . ok_or_else ( || fmt_err ! ( "Variable '{key}' in [fork.{name}] must be an array" ) ) ?;
212-
202+ fn get_array (
203+ chain : Chain ,
204+ key : & str ,
205+ element_ty : & DynSolType ,
206+ state : & crate :: Cheatcodes ,
207+ ) -> Result {
208+ let arr = get_toml_value ( chain, key, state) ?. as_array ( ) . ok_or_else ( || {
209+ fmt_err ! (
210+ "variable '{key}' in '[fork.<chain_id: {chain}>]' must be an array" ,
211+ chain = chain. id( )
212+ )
213+ } ) ?;
213214 let result: Result < Vec < _ > > = arr
214215 . iter ( )
215216 . enumerate ( )
216217 . map ( |( i, elem) | {
217218 let context = format ! ( "{key}[{i}]" ) ;
218- parse_toml_element ( elem, element_ty, & context, name )
219+ parse_toml_element ( elem, element_ty, & context, chain )
219220 } )
220221 . collect ( ) ;
221222
@@ -226,10 +227,11 @@ fn get_array(chain: u64, key: &str, element_ty: &DynSolType, state: &crate::Chea
226227fn parse_toml_element (
227228 elem : & toml:: Value ,
228229 element_ty : & DynSolType ,
229- context : & str ,
230- fork_name : & str ,
230+ key : & str ,
231+ chain : Chain ,
231232) -> Result < DynSolValue > {
232233 // Convert TOML value to JSON value and use existing JSON parsing logic
233- parse_json_as ( & toml_to_json_value ( elem. to_owned ( ) ) , element_ty)
234- . map_err ( |e| fmt_err ! ( "Failed to parse '{context}' in [fork.{fork_name}]: {e}" ) )
234+ parse_json_as ( & toml_to_json_value ( elem. to_owned ( ) ) , element_ty) . map_err ( |e| {
235+ fmt_err ! ( "failed to parse '{key}' in '[fork.<chain_id: {chain}>]': {e}" , chain = chain. id( ) )
236+ } )
235237}
0 commit comments