@@ -324,18 +324,19 @@ where
324324 guard. take ( ) . expect ( "exec state empty" )
325325 }
326326
327- /// Take the execution state, update it, put it back, return the output.
328- async fn modify_exec_state < T , F , R > ( & self , f : F ) -> Result < T >
327+ /// Update the execution state using the provided closure.
328+ ///
329+ /// Note: Deals with panics in the user provided closure as well.
330+ async fn modify_exec_state < T , G , F > ( & self , generator : G ) -> Result < T >
329331 where
330- F : FnOnce ( FvmExecState < BS > ) -> R ,
331- R : Future < Output = Result < ( FvmExecState < BS > , T ) > > ,
332+ G : for < ' s > FnOnce ( & ' s mut FvmExecState < BS > ) -> F ,
333+ F : Future < Output = Result < T > > ,
334+ T : ' static ,
332335 {
333336 let mut guard = self . exec_state . lock ( ) . await ;
334- let state = guard. take ( ) . expect ( "exec state empty" ) ;
335-
336- let ( state, ret) = f ( state) . await ?;
337-
338- * guard = Some ( state) ;
337+ let maybe_state = guard. as_mut ( ) ;
338+ let state = maybe_state. expect ( "exec state empty" ) ;
339+ let ret = generator ( state) . await ?;
339340
340341 Ok ( ret)
341342 }
@@ -418,10 +419,18 @@ where
418419 async fn refresh_validators_cache ( & self ) -> Result < ( ) > {
419420 // TODO: This should be read only state, but we can't use the read-only view here
420421 // because it hasn't been committed to state store yet.
421- self . modify_exec_state ( |mut s| async {
422- let mut cache = self . validators_cache . lock ( ) . await ;
423- * cache = Some ( ValidatorCache :: new_from_state ( & mut s) ?) ;
424- Ok ( ( s, ( ) ) )
422+ let mut cache = self . validators_cache . lock ( ) . await ;
423+ self . modify_exec_state ( |s| {
424+ // we need to leave this outside the closure
425+ // otherwise `s`' lifetime would be captured by the
426+ // closure causing unresolvable liftetime conflicts
427+ // this is fine since we execute the future directly
428+ // after calling the generator closure.
429+ let x = ValidatorCache :: new_from_state ( s) ;
430+ async {
431+ * cache = Some ( x?) ;
432+ Ok ( ( ) )
433+ }
425434 } )
426435 . await ?;
427436
0 commit comments