@@ -4,34 +4,35 @@ use crate::{
4
4
Cheatcode , CheatsCtxt , DatabaseExt , Result , Vm :: * , json:: parse_json_as,
5
5
toml:: toml_to_json_value,
6
6
} ;
7
+ use alloy_chains:: Chain ;
7
8
use alloy_dyn_abi:: { DynSolType , DynSolValue } ;
8
9
use alloy_sol_types:: SolValue ;
9
- use eyre:: OptionExt ;
10
10
use foundry_evm_core:: ContextExt ;
11
+ use std:: borrow:: Cow ;
11
12
12
13
impl Cheatcode for readForkChainIdsCall {
13
14
fn apply ( & self , state : & mut crate :: Cheatcodes ) -> Result {
14
15
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 ( ) )
22
17
}
23
18
}
24
19
25
20
impl Cheatcode for readForkChainsCall {
26
21
fn apply ( & self , state : & mut crate :: Cheatcodes ) -> Result {
27
22
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 ( ) )
29
30
}
30
31
}
31
32
32
33
impl Cheatcode for readForkChainCall {
33
34
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 ( ) )
35
36
}
36
37
}
37
38
@@ -41,42 +42,35 @@ impl Cheatcode for readForkChainIdCall {
41
42
}
42
43
}
43
44
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) {
47
47
let rpc = match config. rpc_endpoint {
48
48
Some ( ref url) => url. clone ( ) . resolve ( ) ,
49
- None => state. config . rpc_endpoint ( name ) ?,
49
+ None => state. config . rpc_endpoint ( & get_chain_name ( & chain ) ) ?,
50
50
} ;
51
51
52
52
return Ok ( rpc. url ( ) ?. abi_encode ( ) ) ;
53
53
}
54
54
55
- bail ! ( "[fork.{name}] subsection not found in [fork] of 'foundry.toml'" )
55
+ bail ! ( "'rpc_endpoint' not found in [fork.{chain}] subsection of 'foundry.toml'" )
56
56
}
57
57
58
58
impl Cheatcode for readForkChainRpcUrlCall {
59
59
fn apply ( & self , state : & mut crate :: Cheatcodes ) -> Result {
60
60
let Self { id } = self ;
61
- let name = get_chain_name ( id. to :: < u64 > ( ) ) ?;
62
- resolve_rpc_url ( name, state)
61
+ resolve_rpc_url ( Chain :: from_id ( id. to :: < u64 > ( ) ) , state)
63
62
}
64
63
}
65
64
66
65
impl Cheatcode for readForkRpcUrlCall {
67
66
fn apply_stateful ( & self , ccx : & mut CheatsCtxt ) -> Result {
68
- let name = get_active_fork_chain_name ( ccx) ?;
69
- resolve_rpc_url ( name, ccx. state )
67
+ resolve_rpc_url ( get_active_fork_chain ( ccx) ?, ccx. state )
70
68
}
71
69
}
72
70
73
71
/// 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 ( ) )
72
+ fn get_chain_name ( chain : & Chain ) -> Cow < ' static , str > {
73
+ chain. named ( ) . map_or ( Cow :: Owned ( chain. id ( ) . to_string ( ) ) , |name| Cow :: Borrowed ( name. as_str ( ) ) )
80
74
}
81
75
82
76
/// Gets the chain id of the active fork. Panics if no fork is selected.
@@ -88,9 +82,9 @@ fn get_active_fork_chain_id(ccx: &mut CheatsCtxt) -> Result<u64> {
88
82
Ok ( env. cfg . chain_id )
89
83
}
90
84
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) ? )
85
+ /// Gets the alloy chain for the active fork. Panics if no fork is selected.
86
+ fn get_active_fork_chain ( ccx : & mut CheatsCtxt ) -> Result < Chain > {
87
+ get_active_fork_chain_id ( ccx) . map ( Chain :: from_id )
94
88
}
95
89
96
90
// Helper macros to generate cheatcode implementations
@@ -99,7 +93,7 @@ macro_rules! impl_get_value_cheatcode {
99
93
impl Cheatcode for $struct {
100
94
fn apply_stateful( & self , ccx: & mut CheatsCtxt ) -> Result {
101
95
let Self { key } = self ;
102
- let chain = get_active_fork_chain_id ( ccx) ?;
96
+ let chain = get_active_fork_chain ( ccx) ?;
103
97
get_value( chain, key, $sol_type, ccx. state)
104
98
}
105
99
}
@@ -108,7 +102,7 @@ macro_rules! impl_get_value_cheatcode {
108
102
impl Cheatcode for $struct {
109
103
fn apply( & self , state: & mut crate :: Cheatcodes ) -> Result {
110
104
let Self { chain, key } = self ;
111
- get_value( chain. to:: <u64 >( ) , key, $sol_type, state)
105
+ get_value( Chain :: from_id ( chain. to:: <u64 >( ) ) , key, $sol_type, state)
112
106
}
113
107
}
114
108
} ;
@@ -119,16 +113,15 @@ macro_rules! impl_get_array_cheatcode {
119
113
impl Cheatcode for $struct {
120
114
fn apply_stateful( & self , ccx: & mut CheatsCtxt ) -> Result {
121
115
let Self { key } = self ;
122
- let chain = get_active_fork_chain_id( ccx) ?;
123
- get_array( chain, key, $sol_type, ccx. state)
116
+ get_array( get_active_fork_chain( ccx) ?, key, $sol_type, ccx. state)
124
117
}
125
118
}
126
119
} ;
127
120
( $struct: ident, $sol_type: expr) => {
128
121
impl Cheatcode for $struct {
129
122
fn apply( & self , state: & mut crate :: Cheatcodes ) -> Result {
130
123
let Self { chain, key } = self ;
131
- get_array( chain. to:: <u64 >( ) , key, $sol_type, state)
124
+ get_array( Chain :: from ( chain. to:: <u64 >( ) ) , key, $sol_type, state)
132
125
}
133
126
}
134
127
} ;
@@ -178,44 +171,46 @@ impl_get_array_cheatcode!(readForkStringArrayCall, &DynSolType::String, stateful
178
171
179
172
/// Generic helper to get any value from the TOML config.
180
173
fn get_toml_value < ' a > (
181
- name : & ' a str ,
174
+ chain : Chain ,
182
175
key : & ' a str ,
183
176
state : & ' a crate :: Cheatcodes ,
184
177
) -> 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'" )
178
+ let config = state. config . forks . get ( & chain) . ok_or_else ( || {
179
+ fmt_err ! ( "[fork.{chain}] subsection not found in [fork] of 'foundry.toml'" )
180
+ } ) ?;
181
+ let value = config. vars . get ( key) . ok_or_else ( || {
182
+ fmt_err ! ( "variable '{key}' not found in '[fork.<chain_id: {chain}>]'" , chain = chain. id( ) )
187
183
} ) ?;
188
- let value = config
189
- . vars
190
- . get ( key)
191
- . ok_or_else ( || fmt_err ! ( "Variable '{key}' not found in [fork.{name}] configuration" ) ) ?;
192
184
193
185
Ok ( value)
194
186
}
195
187
196
188
/// 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) ?;
189
+ fn get_value ( chain : Chain , key : & str , ty : & DynSolType , state : & crate :: Cheatcodes ) -> Result {
190
+ let value = get_toml_value ( chain, key, state) ?;
191
+ let sol_value = parse_toml_element ( value, ty, key, chain) ?;
201
192
Ok ( sol_value. abi_encode ( ) )
202
193
}
203
194
204
195
/// 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
-
196
+ fn get_array (
197
+ chain : Chain ,
198
+ key : & str ,
199
+ element_ty : & DynSolType ,
200
+ state : & crate :: Cheatcodes ,
201
+ ) -> Result {
202
+ let arr = get_toml_value ( chain, key, state) ?. as_array ( ) . ok_or_else ( || {
203
+ fmt_err ! (
204
+ "variable '{key}' in '[fork.<chain_id: {chain}>]' must be an array" ,
205
+ chain = chain. id( )
206
+ )
207
+ } ) ?;
213
208
let result: Result < Vec < _ > > = arr
214
209
. iter ( )
215
210
. enumerate ( )
216
211
. map ( |( i, elem) | {
217
212
let context = format ! ( "{key}[{i}]" ) ;
218
- parse_toml_element ( elem, element_ty, & context, name )
213
+ parse_toml_element ( elem, element_ty, & context, chain )
219
214
} )
220
215
. collect ( ) ;
221
216
@@ -227,9 +222,9 @@ fn parse_toml_element(
227
222
elem : & toml:: Value ,
228
223
element_ty : & DynSolType ,
229
224
context : & str ,
230
- fork_name : & str ,
225
+ chain : Chain ,
231
226
) -> Result < DynSolValue > {
232
227
// Convert TOML value to JSON value and use existing JSON parsing logic
233
228
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}" ) )
229
+ . map_err ( |e| fmt_err ! ( "Failed to parse '{context}' in [fork.{chain }]: {e}" ) )
235
230
}
0 commit comments