1+ use  crate :: helpers:: Ctx ; 
12use  revm:: { 
3+     context_interface:: context:: ContextError , 
24    interpreter:: { 
3-         CallInputs ,  CallOutcome ,  CreateInputs ,  CreateOutcome ,  EOFCreateInputs ,  Gas , 
4-         InstructionResult ,   Interpreter ,   InterpreterResult ,   InterpreterTypes , 
5+         CallInputs ,  CallOutcome ,  CreateInputs ,  CreateOutcome ,  EOFCreateInputs ,  Interpreter , 
6+         InterpreterTypes , 
57    } , 
6-     primitives:: Bytes , 
7-     Inspector , 
8+     Database ,  Inspector , 
89} ; 
910use  std:: time:: { Duration ,  Instant } ; 
1011
11- const  CALL_TIMEOUT :  CallOutcome  = CallOutcome  { 
12-     result :  InterpreterResult  { 
13-         result :  InstructionResult :: CallTooDeep , 
14-         output :  Bytes :: new ( ) , 
15-         gas :  Gas :: new_spent ( 0 ) , 
16-     } , 
17-     memory_offset :  0 ..0 , 
18- } ; 
19- 
20- const  CREATE_TIMEOUT :  CreateOutcome  = CreateOutcome  { 
21-     result :  InterpreterResult  { 
22-         result :  InstructionResult :: CallTooDeep , 
23-         output :  Bytes :: new ( ) , 
24-         gas :  Gas :: new_spent ( 0 ) , 
25-     } , 
26-     address :  None , 
27- } ; 
28- 
2912/// A revm [`Inspector`] that limits wallclock time spent on execution. 
3013/// 
3114/// This inspector will stop execution at the beginning and end of each 
@@ -41,14 +24,8 @@ const CREATE_TIMEOUT: CreateOutcome = CreateOutcome {
4124///     - any invalid opcode 
4225/// 
4326/// When execution is terminated by the timer, it will result in a 
44- /// [`InstructionResult::CallTooDeep`]. This is somewhat unintutive. `revm` 
45- /// uses the [`InstructionResult`] enum to represent possible outcomes of a 
46- /// opcode. It requires that the inspector's outcome is a valid 
47- /// [`InstructionResult`], but does not provide a way to represent a custom 
48- /// outcome. This means that the inspector must overload an existing outcome. 
49- /// `CallTooDeep` is used here because it is effectively unreachable in normal 
50- /// `evm` execution due to [EIP-150] call gas forwarding rules, and therefore 
51- /// overloading it is unlikely to cause issues. 
27+ /// [`ContextError::Custom`], which will be propagated as an 
28+ /// [`EVMError::Custom`] to the caller of the EVM interpreter. 
5229/// 
5330/// ## Usage Note 
5431/// 
@@ -63,6 +40,7 @@ const CREATE_TIMEOUT: CreateOutcome = CreateOutcome {
6340/// discarded. 
6441/// 
6542/// [EIP-150]: https://eips.ethereum.org/EIPS/eip-150 
43+ /// [`EVMError::Custom`]: revm::context::result::EVMError::Custom 
6644#[ derive( Debug ,  Clone ,  Copy ) ]  
6745pub  struct  TimeLimit  { 
6846    duration :  Duration , 
@@ -93,63 +71,60 @@ impl TimeLimit {
9371    } 
9472} 
9573
96- impl < Ctx ,  Int :  InterpreterTypes >  Inspector < Ctx ,  Int >  for  TimeLimit  { 
97-     fn  initialize_interp ( & mut  self ,  _interp :  & mut  Interpreter < Int > ,  _context :  & mut  Ctx )  { 
74+ macro_rules!  check_timeout { 
75+     ( $self: ident,  $ctx: ident)  => { 
76+         if  $self. has_elapsed( )  { 
77+             $ctx. error = Err ( ContextError :: Custom ( "timeout during evm execution" . to_string( ) ) ) ; 
78+         } 
79+     } ; 
80+ } 
81+ 
82+ impl < Db :  Database ,  Int :  InterpreterTypes >  Inspector < Ctx < Db > ,  Int >  for  TimeLimit  { 
83+     fn  initialize_interp ( & mut  self ,  _interp :  & mut  Interpreter < Int > ,  _ctx :  & mut  Ctx < Db > )  { 
9884        self . reset ( ) ; 
9985    } 
10086
101-     fn  call ( & mut  self ,  _context :  & mut  Ctx ,  _inputs :  & mut  CallInputs )  -> Option < CallOutcome >  { 
102-         if  self . has_elapsed ( )  { 
103-             return  Some ( CALL_TIMEOUT ) ; 
104-         } 
87+     fn  call ( & mut  self ,  ctx :  & mut  Ctx < Db > ,  _inputs :  & mut  CallInputs )  -> Option < CallOutcome >  { 
88+         check_timeout ! ( self ,  ctx) ; 
10589
10690        None 
10791    } 
10892
109-     fn  call_end ( & mut  self ,  _context :  & mut  Ctx ,  _inputs :  & CallInputs ,  outcome :  & mut  CallOutcome )  { 
110-         if  self . has_elapsed ( )  { 
111-             * outcome = CALL_TIMEOUT ; 
112-         } 
93+     fn  call_end ( & mut  self ,  ctx :  & mut  Ctx < Db > ,  _inputs :  & CallInputs ,  _outcome :  & mut  CallOutcome )  { 
94+         check_timeout ! ( self ,  ctx) ; 
11395    } 
11496
115-     fn  create ( & mut  self ,  _context :  & mut  Ctx ,  _inputs :  & mut  CreateInputs )  -> Option < CreateOutcome >  { 
116-         if  self . has_elapsed ( )  { 
117-             return  Some ( CREATE_TIMEOUT ) ; 
118-         } 
97+     fn  create ( & mut  self ,  ctx :  & mut  Ctx < Db > ,  _inputs :  & mut  CreateInputs )  -> Option < CreateOutcome >  { 
98+         check_timeout ! ( self ,  ctx) ; 
99+ 
119100        None 
120101    } 
121102
122103    fn  create_end ( 
123104        & mut  self , 
124-         _context :  & mut  Ctx , 
105+         ctx :  & mut  Ctx < Db > , 
125106        _inputs :  & CreateInputs , 
126-         outcome :  & mut  CreateOutcome , 
107+         _outcome :  & mut  CreateOutcome , 
127108    )  { 
128-         if  self . has_elapsed ( )  { 
129-             * outcome = CREATE_TIMEOUT ; 
130-         } 
109+         check_timeout ! ( self ,  ctx) ; 
131110    } 
132111
133112    fn  eofcreate ( 
134113        & mut  self , 
135-         _context :  & mut  Ctx , 
114+         ctx :  & mut  Ctx < Db > , 
136115        _inputs :  & mut  EOFCreateInputs , 
137116    )  -> Option < CreateOutcome >  { 
138-         if  self . has_elapsed ( )  { 
139-             return  Some ( CREATE_TIMEOUT ) ; 
140-         } 
117+         check_timeout ! ( self ,  ctx) ; 
141118
142119        None 
143120    } 
144121
145122    fn  eofcreate_end ( 
146123        & mut  self , 
147-         _context :  & mut  Ctx , 
124+         ctx :  & mut  Ctx < Db > , 
148125        _inputs :  & EOFCreateInputs , 
149-         outcome :  & mut  CreateOutcome , 
126+         _outcome :  & mut  CreateOutcome , 
150127    )  { 
151-         if  self . has_elapsed ( )  { 
152-             * outcome = CREATE_TIMEOUT ; 
153-         } 
128+         check_timeout ! ( self ,  ctx) ; 
154129    } 
155130} 
0 commit comments