@@ -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,38 @@ 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 ! (
56
+ "'rpc_endpoint' not found in '[fork.<chain_id: {chain}>]' subsection of 'foundry.toml'" ,
57
+ chain = chain. id( )
58
+ )
56
59
}
57
60
58
61
impl Cheatcode for readForkChainRpcUrlCall {
59
62
fn apply ( & self , state : & mut crate :: Cheatcodes ) -> Result {
60
63
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)
63
65
}
64
66
}
65
67
66
68
impl Cheatcode for readForkRpcUrlCall {
67
69
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 )
70
71
}
71
72
}
72
73
73
74
/// 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 ( ) ) )
80
77
}
81
78
82
79
/// 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> {
88
85
Ok ( env. cfg . chain_id )
89
86
}
90
87
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 )
94
91
}
95
92
96
93
// Helper macros to generate cheatcode implementations
@@ -99,7 +96,7 @@ macro_rules! impl_get_value_cheatcode {
99
96
impl Cheatcode for $struct {
100
97
fn apply_stateful( & self , ccx: & mut CheatsCtxt ) -> Result {
101
98
let Self { key } = self ;
102
- let chain = get_active_fork_chain_id ( ccx) ?;
99
+ let chain = get_active_fork_chain ( ccx) ?;
103
100
get_value( chain, key, $sol_type, ccx. state)
104
101
}
105
102
}
@@ -108,7 +105,7 @@ macro_rules! impl_get_value_cheatcode {
108
105
impl Cheatcode for $struct {
109
106
fn apply( & self , state: & mut crate :: Cheatcodes ) -> Result {
110
107
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)
112
109
}
113
110
}
114
111
} ;
@@ -119,16 +116,15 @@ macro_rules! impl_get_array_cheatcode {
119
116
impl Cheatcode for $struct {
120
117
fn apply_stateful( & self , ccx: & mut CheatsCtxt ) -> Result {
121
118
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)
124
120
}
125
121
}
126
122
} ;
127
123
( $struct: ident, $sol_type: expr) => {
128
124
impl Cheatcode for $struct {
129
125
fn apply( & self , state: & mut crate :: Cheatcodes ) -> Result {
130
126
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)
132
128
}
133
129
}
134
130
} ;
@@ -178,44 +174,49 @@ impl_get_array_cheatcode!(readForkStringArrayCall, &DynSolType::String, stateful
178
174
179
175
/// Generic helper to get any value from the TOML config.
180
176
fn get_toml_value < ' a > (
181
- name : & ' a str ,
177
+ chain : Chain ,
182
178
key : & ' a str ,
183
179
state : & ' a crate :: Cheatcodes ,
184
180
) -> 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( ) )
187
189
} ) ?;
188
- let value = config
189
- . vars
190
- . get ( key)
191
- . ok_or_else ( || fmt_err ! ( "Variable '{key}' not found in [fork.{name}] configuration" ) ) ?;
192
190
193
191
Ok ( value)
194
192
}
195
193
196
194
/// 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) ?;
201
198
Ok ( sol_value. abi_encode ( ) )
202
199
}
203
200
204
201
/// 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
+ } ) ?;
213
214
let result: Result < Vec < _ > > = arr
214
215
. iter ( )
215
216
. enumerate ( )
216
217
. map ( |( i, elem) | {
217
218
let context = format ! ( "{key}[{i}]" ) ;
218
- parse_toml_element ( elem, element_ty, & context, name )
219
+ parse_toml_element ( elem, element_ty, & context, chain )
219
220
} )
220
221
. collect ( ) ;
221
222
@@ -226,10 +227,11 @@ fn get_array(chain: u64, key: &str, element_ty: &DynSolType, state: &crate::Chea
226
227
fn parse_toml_element (
227
228
elem : & toml:: Value ,
228
229
element_ty : & DynSolType ,
229
- context : & str ,
230
- fork_name : & str ,
230
+ key : & str ,
231
+ chain : Chain ,
231
232
) -> Result < DynSolValue > {
232
233
// 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
+ } )
235
237
}
0 commit comments