44//! concurrently active pairs at once.
55
66use super :: CreateFork ;
7+ use crate :: FoundryBlock ;
78use alloy_evm:: EvmEnv ;
89use alloy_network:: Network ;
910use alloy_primitives:: { U256 , map:: HashMap } ;
1011use foundry_config:: Config ;
11- use foundry_fork_db:: { BackendHandler , BlockchainDb , SharedBackend , cache:: BlockchainDbMeta } ;
12+ use foundry_fork_db:: {
13+ BackendHandler , BlockchainDb , ForkBlockEnv , SharedBackend , cache:: BlockchainDbMeta ,
14+ } ;
1215use futures:: {
1316 FutureExt , StreamExt ,
1417 channel:: mpsc:: { Receiver , Sender , channel} ,
1518 stream:: Fuse ,
1619 task:: { Context , Poll } ,
1720} ;
18- use revm:: { context :: BlockEnv , primitives:: hardfork:: SpecId } ;
21+ use revm:: primitives:: hardfork:: SpecId ;
1922use std:: {
2023 fmt:: { self , Write } ,
2124 pin:: Pin ,
@@ -66,15 +69,18 @@ impl<T: Into<String>> From<T> for ForkId {
6669/// Can send requests to the `MultiForkHandler` to create forks.
6770#[ derive( Clone , Debug ) ]
6871#[ must_use]
69- pub struct MultiFork < N : Network , SPEC , BLOCK = BlockEnv > {
72+ pub struct MultiFork < N : Network , SPEC , BLOCK : ForkBlockEnv > {
7073 /// Channel to send `Request`s to the handler.
7174 handler : Sender < Request < N , SPEC , BLOCK > > ,
7275 /// Ensures that all rpc resources get flushed properly.
7376 _shutdown : Arc < ShutDownMultiFork < N , SPEC , BLOCK > > ,
7477}
7578
76- impl < N : Network , SPEC : Into < SpecId > + Default + Copy + Clone + Unpin + Send + ' static >
77- MultiFork < N , SPEC >
79+ impl <
80+ N : Network ,
81+ SPEC : Into < SpecId > + Default + Copy + Clone + Unpin + Send + ' static ,
82+ BLOCK : FoundryBlock + ForkBlockEnv + Default + Unpin ,
83+ > MultiFork < N , SPEC , BLOCK >
7884{
7985 /// Creates a new pair and spawns the `MultiForkHandler` on a background thread.
8086 pub fn spawn ( ) -> Self {
@@ -117,7 +123,7 @@ impl<N: Network, SPEC: Into<SpecId> + Default + Copy + Clone + Unpin + Send + 's
117123 ///
118124 /// Use [`spawn`](Self::spawn) instead.
119125 #[ doc( hidden) ]
120- pub fn new ( ) -> ( Self , MultiForkHandler < N , SPEC > ) {
126+ pub fn new ( ) -> ( Self , MultiForkHandler < N , SPEC , BLOCK > ) {
121127 let ( handler, handler_rx) = channel ( 1 ) ;
122128 let _shutdown = Arc :: new ( ShutDownMultiFork { handler : Some ( handler. clone ( ) ) } ) ;
123129 ( Self { handler, _shutdown } , MultiForkHandler :: new ( handler_rx) )
@@ -126,10 +132,11 @@ impl<N: Network, SPEC: Into<SpecId> + Default + Copy + Clone + Unpin + Send + 's
126132 /// Returns a fork backend.
127133 ///
128134 /// If no matching fork backend exists it will be created.
135+ #[ allow( clippy:: type_complexity) ]
129136 pub fn create_fork (
130137 & self ,
131138 fork : CreateFork ,
132- ) -> eyre:: Result < ( ForkId , SharedBackend < N > , EvmEnv < SPEC > ) > {
139+ ) -> eyre:: Result < ( ForkId , SharedBackend < N , BLOCK > , EvmEnv < SPEC , BLOCK > ) > {
133140 trace ! ( "Creating new fork, url={}, block={:?}" , fork. url, fork. evm_opts. fork_block_number) ;
134141 let ( sender, rx) = oneshot_channel ( ) ;
135142 let req = Request :: CreateFork ( Box :: new ( fork) , sender) ;
@@ -140,11 +147,12 @@ impl<N: Network, SPEC: Into<SpecId> + Default + Copy + Clone + Unpin + Send + 's
140147 /// Rolls the block of the fork.
141148 ///
142149 /// If no matching fork backend exists it will be created.
150+ #[ allow( clippy:: type_complexity) ]
143151 pub fn roll_fork (
144152 & self ,
145153 fork : ForkId ,
146154 block : u64 ,
147- ) -> eyre:: Result < ( ForkId , SharedBackend < N > , EvmEnv < SPEC > ) > {
155+ ) -> eyre:: Result < ( ForkId , SharedBackend < N , BLOCK > , EvmEnv < SPEC , BLOCK > ) > {
148156 trace ! ( ?fork, ?block, "rolling fork" ) ;
149157 let ( sender, rx) = oneshot_channel ( ) ;
150158 let req = Request :: RollFork ( fork, block, sender) ;
@@ -153,7 +161,7 @@ impl<N: Network, SPEC: Into<SpecId> + Default + Copy + Clone + Unpin + Send + 's
153161 }
154162
155163 /// Returns the `EvmEnv` of the given fork, if any.
156- pub fn get_evm_env ( & self , fork : ForkId ) -> eyre:: Result < Option < EvmEnv < SPEC > > > {
164+ pub fn get_evm_env ( & self , fork : ForkId ) -> eyre:: Result < Option < EvmEnv < SPEC , BLOCK > > > {
157165 trace ! ( ?fork, "getting env config" ) ;
158166 let ( sender, rx) = oneshot_channel ( ) ;
159167 let req = Request :: GetEvmEnv ( fork, sender) ;
@@ -174,7 +182,10 @@ impl<N: Network, SPEC: Into<SpecId> + Default + Copy + Clone + Unpin + Send + 's
174182 ///
175183 /// This is required for tx level forking where we need to fork off the `block - 1` state but
176184 /// still need use env settings for `env`.
177- pub fn update_block_env ( & self , fork : ForkId , env : BlockEnv ) -> eyre:: Result < ( ) > {
185+ pub fn update_block_env ( & self , fork : ForkId , env : BLOCK ) -> eyre:: Result < ( ) >
186+ where
187+ BLOCK : fmt:: Debug ,
188+ {
178189 trace ! ( ?fork, ?env, "update fork block" ) ;
179190 self . handler
180191 . clone ( )
@@ -185,7 +196,7 @@ impl<N: Network, SPEC: Into<SpecId> + Default + Copy + Clone + Unpin + Send + 's
185196 /// Returns the corresponding fork if it exists.
186197 ///
187198 /// Returns `None` if no matching fork backend is available.
188- pub fn get_fork ( & self , id : impl Into < ForkId > ) -> eyre:: Result < Option < SharedBackend < N > > > {
199+ pub fn get_fork ( & self , id : impl Into < ForkId > ) -> eyre:: Result < Option < SharedBackend < N , BLOCK > > > {
189200 let id = id. into ( ) ;
190201 trace ! ( ?id, "get fork backend" ) ;
191202 let ( sender, rx) = oneshot_channel ( ) ;
@@ -207,21 +218,26 @@ impl<N: Network, SPEC: Into<SpecId> + Default + Copy + Clone + Unpin + Send + 's
207218
208219type CreateFuture < N , SPEC , BLOCK > = Pin <
209220 Box <
210- dyn Future < Output = eyre:: Result < ( ForkId , CreatedFork < N , SPEC , BLOCK > , BackendHandler < N > ) > >
211- + Send ,
221+ dyn Future <
222+ Output = eyre:: Result < (
223+ ForkId ,
224+ CreatedFork < N , SPEC , BLOCK > ,
225+ BackendHandler < N , BLOCK > ,
226+ ) > ,
227+ > + Send ,
212228 > ,
213229> ;
214230type CreateSender < N , SPEC , BLOCK > =
215- OneshotSender < eyre:: Result < ( ForkId , SharedBackend < N > , EvmEnv < SPEC , BLOCK > ) > > ;
231+ OneshotSender < eyre:: Result < ( ForkId , SharedBackend < N , BLOCK > , EvmEnv < SPEC , BLOCK > ) > > ;
216232type GetEvmEnvSender < SPEC , BLOCK > = OneshotSender < Option < EvmEnv < SPEC , BLOCK > > > ;
217233
218234/// Request that's send to the handler.
219235#[ derive( Debug ) ]
220- enum Request < N : Network , SPEC , BLOCK = BlockEnv > {
236+ enum Request < N : Network , SPEC , BLOCK : ForkBlockEnv > {
221237 /// Creates a new ForkBackend.
222238 CreateFork ( Box < CreateFork > , CreateSender < N , SPEC , BLOCK > ) ,
223239 /// Returns the Fork backend for the `ForkId` if it exists.
224- GetFork ( ForkId , OneshotSender < Option < SharedBackend < N > > > ) ,
240+ GetFork ( ForkId , OneshotSender < Option < SharedBackend < N , BLOCK > > > ) ,
225241 /// Adjusts the block that's being forked, by creating a new fork at the new block.
226242 RollFork ( ForkId , u64 , CreateSender < N , SPEC , BLOCK > ) ,
227243 /// Returns the environment of the fork.
@@ -236,7 +252,7 @@ enum Request<N: Network, SPEC, BLOCK = BlockEnv> {
236252 GetForkUrl ( ForkId , OneshotSender < Option < String > > ) ,
237253}
238254
239- enum ForkTask < N : Network , SPEC , BLOCK = BlockEnv > {
255+ enum ForkTask < N : Network , SPEC , BLOCK : ForkBlockEnv > {
240256 /// Contains the future that will establish a new fork.
241257 Create (
242258 CreateFuture < N , SPEC , BLOCK > ,
@@ -248,14 +264,14 @@ enum ForkTask<N: Network, SPEC, BLOCK = BlockEnv> {
248264
249265/// The type that manages connections in the background.
250266#[ must_use = "futures do nothing unless polled" ]
251- pub struct MultiForkHandler < N : Network , SPEC , BLOCK = BlockEnv > {
267+ pub struct MultiForkHandler < N : Network , SPEC , BLOCK : ForkBlockEnv > {
252268 /// Incoming requests from the `MultiFork`.
253269 incoming : Fuse < Receiver < Request < N , SPEC , BLOCK > > > ,
254270
255271 /// All active handlers.
256272 ///
257273 /// It's expected that this list will be rather small (<10).
258- handlers : Vec < ( ForkId , BackendHandler < N > ) > ,
274+ handlers : Vec < ( ForkId , BackendHandler < N , BLOCK > ) > ,
259275
260276 // tasks currently in progress
261277 pending_tasks : Vec < ForkTask < N , SPEC , BLOCK > > ,
@@ -270,8 +286,13 @@ pub struct MultiForkHandler<N: Network, SPEC, BLOCK = BlockEnv> {
270286 flush_cache_interval : Option < tokio:: time:: Interval > ,
271287}
272288
273- impl < N : Network , SPEC : Into < SpecId > + Default + Copy + Clone + ' static > MultiForkHandler < N , SPEC > {
274- fn new ( incoming : Receiver < Request < N , SPEC > > ) -> Self {
289+ impl <
290+ N : Network ,
291+ SPEC : Into < SpecId > + Default + Copy + Clone + ' static ,
292+ BLOCK : FoundryBlock + ForkBlockEnv + Default ,
293+ > MultiForkHandler < N , SPEC , BLOCK >
294+ {
295+ fn new ( incoming : Receiver < Request < N , SPEC , BLOCK > > ) -> Self {
275296 Self {
276297 incoming : incoming. fuse ( ) ,
277298 handlers : Default :: default ( ) ,
@@ -292,7 +313,7 @@ impl<N: Network, SPEC: Into<SpecId> + Default + Copy + Clone + 'static> MultiFor
292313 fn find_in_progress_task (
293314 & mut self ,
294315 id : & ForkId ,
295- ) -> Option < & mut Vec < CreateSender < N , SPEC , BlockEnv > > > {
316+ ) -> Option < & mut Vec < CreateSender < N , SPEC , BLOCK > > > {
296317 for ForkTask :: Create ( _, in_progress, _, additional) in & mut self . pending_tasks {
297318 if in_progress == id {
298319 return Some ( additional) ;
@@ -301,7 +322,7 @@ impl<N: Network, SPEC: Into<SpecId> + Default + Copy + Clone + 'static> MultiFor
301322 None
302323 }
303324
304- fn create_fork ( & mut self , fork : CreateFork , sender : CreateSender < N , SPEC , BlockEnv > ) {
325+ fn create_fork ( & mut self , fork : CreateFork , sender : CreateSender < N , SPEC , BLOCK > ) {
305326 let fork_id = ForkId :: new ( & fork. url , fork. evm_opts . fork_block_number ) ;
306327 trace ! ( ?fork_id, "created new forkId" ) ;
307328
@@ -319,9 +340,9 @@ impl<N: Network, SPEC: Into<SpecId> + Default + Copy + Clone + 'static> MultiFor
319340 fn insert_new_fork (
320341 & mut self ,
321342 fork_id : ForkId ,
322- fork : CreatedFork < N , SPEC > ,
323- sender : CreateSender < N , SPEC , BlockEnv > ,
324- additional_senders : Vec < CreateSender < N , SPEC , BlockEnv > > ,
343+ fork : CreatedFork < N , SPEC , BLOCK > ,
344+ sender : CreateSender < N , SPEC , BLOCK > ,
345+ additional_senders : Vec < CreateSender < N , SPEC , BLOCK > > ,
325346 ) {
326347 self . forks . insert ( fork_id. clone ( ) , fork. clone ( ) ) ;
327348 let _ = sender. send ( Ok ( ( fork_id. clone ( ) , fork. backend . clone ( ) , fork. evm_env . clone ( ) ) ) ) ;
@@ -335,7 +356,7 @@ impl<N: Network, SPEC: Into<SpecId> + Default + Copy + Clone + 'static> MultiFor
335356 }
336357
337358 /// Update the fork's block entire env
338- fn update_env ( & mut self , fork_id : ForkId , env : BlockEnv ) {
359+ fn update_env ( & mut self , fork_id : ForkId , env : BLOCK ) {
339360 if let Some ( fork) = self . forks . get_mut ( & fork_id) {
340361 fork. evm_env . block_env = env;
341362 }
@@ -344,12 +365,12 @@ impl<N: Network, SPEC: Into<SpecId> + Default + Copy + Clone + 'static> MultiFor
344365 /// cheatcodes when new fork selected.
345366 fn update_block ( & mut self , fork_id : ForkId , block_number : U256 , block_timestamp : U256 ) {
346367 if let Some ( fork) = self . forks . get_mut ( & fork_id) {
347- fork. evm_env . block_env . number = block_number;
348- fork. evm_env . block_env . timestamp = block_timestamp;
368+ fork. evm_env . block_env . set_number ( block_number) ;
369+ fork. evm_env . block_env . set_timestamp ( block_timestamp) ;
349370 }
350371 }
351372
352- fn on_request ( & mut self , req : Request < N , SPEC > ) {
373+ fn on_request ( & mut self , req : Request < N , SPEC , BLOCK > ) {
353374 match req {
354375 Request :: CreateFork ( fork, sender) => self . create_fork ( * fork, sender) ,
355376 Request :: GetFork ( fork_id, sender) => {
@@ -393,8 +414,11 @@ impl<N: Network, SPEC: Into<SpecId> + Default + Copy + Clone + 'static> MultiFor
393414
394415// Drives all handler to completion.
395416// This future will finish once all underlying BackendHandler are completed.
396- impl < N : Network , SPEC : Into < SpecId > + Default + Copy + Clone + Unpin + ' static > Future
397- for MultiForkHandler < N , SPEC >
417+ impl <
418+ N : Network ,
419+ SPEC : Into < SpecId > + Default + Copy + Clone + Unpin + ' static ,
420+ BLOCK : FoundryBlock + ForkBlockEnv + Default + Unpin ,
421+ > Future for MultiForkHandler < N , SPEC , BLOCK >
398422{
399423 type Output = ( ) ;
400424
@@ -496,20 +520,24 @@ impl<N: Network, SPEC: Into<SpecId> + Default + Copy + Clone + Unpin + 'static>
496520
497521/// Tracks the created Fork
498522#[ derive( Debug , Clone ) ]
499- struct CreatedFork < N : Network , SPEC , BLOCK = BlockEnv > {
523+ struct CreatedFork < N : Network , SPEC , BLOCK : ForkBlockEnv > {
500524 /// How the fork was initially created.
501525 opts : CreateFork ,
502526 /// The resolved EVM environment (fetched from the provider).
503527 evm_env : EvmEnv < SPEC , BLOCK > ,
504528 /// Copy of the sender.
505- backend : SharedBackend < N > ,
529+ backend : SharedBackend < N , BLOCK > ,
506530 /// How many consumers there are, since a `SharedBacked` can be used by multiple
507531 /// consumers.
508532 num_senders : Arc < AtomicUsize > ,
509533}
510534
511- impl < N : Network , SPEC > CreatedFork < N , SPEC > {
512- pub fn new ( opts : CreateFork , evm_env : EvmEnv < SPEC > , backend : SharedBackend < N > ) -> Self {
535+ impl < N : Network , SPEC , BLOCK : ForkBlockEnv > CreatedFork < N , SPEC , BLOCK > {
536+ pub fn new (
537+ opts : CreateFork ,
538+ evm_env : EvmEnv < SPEC , BLOCK > ,
539+ backend : SharedBackend < N , BLOCK > ,
540+ ) -> Self {
513541 Self { opts, evm_env, backend, num_senders : Arc :: new ( AtomicUsize :: new ( 1 ) ) }
514542 }
515543
@@ -531,11 +559,11 @@ impl<N: Network, SPEC> CreatedFork<N, SPEC> {
531559/// This type intentionally does not implement `Clone` since it's intended that there's only once
532560/// instance.
533561#[ derive( Debug ) ]
534- struct ShutDownMultiFork < N : Network , SPEC , BLOCK = BlockEnv > {
562+ struct ShutDownMultiFork < N : Network , SPEC , BLOCK : ForkBlockEnv > {
535563 handler : Option < Sender < Request < N , SPEC , BLOCK > > > ,
536564}
537565
538- impl < N : Network , SPEC , BLOCK > Drop for ShutDownMultiFork < N , SPEC , BLOCK > {
566+ impl < N : Network , SPEC , BLOCK : ForkBlockEnv > Drop for ShutDownMultiFork < N , SPEC , BLOCK > {
539567 fn drop ( & mut self ) {
540568 trace ! ( target: "fork::multi" , "initiating shutdown" ) ;
541569 let ( sender, rx) = oneshot_channel ( ) ;
@@ -552,17 +580,21 @@ impl<N: Network, SPEC, BLOCK> Drop for ShutDownMultiFork<N, SPEC, BLOCK> {
552580/// Creates a new fork.
553581///
554582/// This will establish a new `Provider` to the endpoint and return the Fork Backend.
555- async fn create_fork < N : Network , SPEC : Into < SpecId > + Default + Copy > (
583+ async fn create_fork <
584+ N : Network ,
585+ SPEC : Into < SpecId > + Default + Copy ,
586+ BLOCK : FoundryBlock + ForkBlockEnv + Default ,
587+ > (
556588 mut fork : CreateFork ,
557- ) -> eyre:: Result < ( ForkId , CreatedFork < N , SPEC > , BackendHandler < N > ) > {
589+ ) -> eyre:: Result < ( ForkId , CreatedFork < N , SPEC , BLOCK > , BackendHandler < N , BLOCK > ) > {
558590 // Ensure evm_opts reflects the fork URL (may differ from the resolved CreateFork url when
559591 // created via cheatcodes, where evm_opts is cloned from the base config).
560592 fork. evm_opts . fork_url = Some ( fork. url . clone ( ) ) ;
561593
562594 let provider = fork. evm_opts . fork_provider_with_url :: < N > ( & fork. url ) ?;
563595
564596 // Initialise the fork environment.
565- let ( evm_env, number) = fork. evm_opts . fork_evm_env :: < _ , BlockEnv , _ , _ > ( & provider) . await ?;
597+ let ( evm_env, number) = fork. evm_opts . fork_evm_env :: < _ , BLOCK , _ , _ > ( & provider) . await ?;
566598 let meta = BlockchainDbMeta :: new ( evm_env. block_env . clone ( ) , fork. url . clone ( ) ) ;
567599
568600 // Determine the cache path if caching is enabled.
0 commit comments