@@ -100,7 +100,7 @@ fn get_method(f: &ImplItemFn) -> Option<(Signature, EvmMethod, TokenStream)> {
100100 } ,
101101 }
102102 }
103- if signature. convert && signature. args . len ( ) != f. sig . inputs . len ( ) - 1 {
103+ if signature. convert && signature. args . len ( ) != f. sig . inputs . len ( ) - 2 {
104104 signature
105105 . name
106106 . span ( )
@@ -136,9 +136,7 @@ fn generate_method_call(attr: &EvmMethod, sig: &Signature) -> Option<TokenStream
136136 arg_decls. push ( quote ! {
137137 let #temp_name = decoded_args. #field_index. clone( ) ;
138138 if * #temp_name. high( ) != 0 {
139- return Some ( Err ( :: evm:: executor:: stack:: PrecompileFailure :: Error {
140- exit_status: :: evm:: ExitError :: Other ( "integer overflow" . into( ) ) ,
141- } ) ) ;
139+ return Err ( :: evm:: interpreter:: ExitError :: Exception ( :: evm:: interpreter:: ExitException :: Other ( "integer overflow" . into( ) ) ) . into( ) ) ;
142140 }
143141 let #arg_name = #temp_name. as_u128( ) ;
144142 } ) ;
@@ -163,14 +161,12 @@ fn generate_method_call(attr: &EvmMethod, sig: &Signature) -> Option<TokenStream
163161 } ;
164162
165163 Some ( quote ! { {
166- let decoded_args: #decode_type = match :: solabi:: decode( & handle. input( ) [ #SELECTOR_LENGTH ..] ) {
167- Err ( e) => return Some ( Err ( :: evm:: executor:: stack:: PrecompileFailure :: Error {
168- exit_status: :: evm:: ExitError :: Other ( "invalid argument" . into( ) ) ,
169- } ) ) ,
164+ let decoded_args: #decode_type = match :: solabi:: decode( & input[ #SELECTOR_LENGTH ..] ) {
165+ Err ( e) => return Err ( :: evm:: interpreter:: ExitError :: Exception ( :: evm:: interpreter:: ExitException :: Other ( "invalid argument" . into( ) ) ) . into( ) ) ,
170166 Ok ( tokens) => tokens,
171167 } ;
172168 #( #arg_decls) *
173- Some ( Self :: #method_name( handle , #( #call_args) , * ) )
169+ Self :: #method_name( gasometer , handler , #( #call_args) , * )
174170 } } )
175171}
176172
@@ -213,15 +209,27 @@ pub fn derive_evm_contract(input: ItemImpl) -> TokenStream {
213209 } else {
214210 let method_name = sig. name . clone ( ) ;
215211 quote ! {
216- & [ #keccak] => Some ( Self :: #method_name( handle , #SELECTOR_LENGTH ) ) ,
212+ & [ #keccak] => Self :: #method_name( gasometer , handler , #SELECTOR_LENGTH ) ,
217213 }
218214 }
219215 } )
220216 . collect ( ) ;
221217
222- let impl_generics = & input. generics ;
218+ let ( impl_generics, _, _) = input. generics . split_for_impl ( ) ;
219+
220+ // Add custom G and H type parameters for use in the PrecompileSet impl.
221+ let mut extended_generics = input. generics . clone ( ) ;
222+ extended_generics. params . push (
223+ syn:: parse_quote!( G : AsRef <:: evm:: interpreter:: runtime:: RuntimeState > + :: evm:: GasMutState ) ,
224+ ) ;
225+ extended_generics
226+ . params
227+ . push ( syn:: parse_quote!( H : :: evm:: interpreter:: runtime:: RuntimeBackend ) ) ;
228+ let ( impl_generics_gh, _, _) = extended_generics. split_for_impl ( ) ;
229+
223230 let self_ty = input. self_ty . clone ( ) ;
224231 let evm_crate = evm_crate_path ( ) ;
232+
225233 quote ! {
226234 #input
227235
@@ -231,62 +239,48 @@ pub fn derive_evm_contract(input: ItemImpl) -> TokenStream {
231239 Self :: #address_fn( )
232240 }
233241
234- fn dispatch_call(
235- handle: & mut impl :: evm:: executor:: stack:: PrecompileHandle ,
236- ) -> Option <Result <:: evm:: executor:: stack:: PrecompileOutput , :: evm:: executor:: stack:: PrecompileFailure >> {
237- if handle. context( ) . address != handle. code_address( ) {
238- return Some ( Err ( :: evm:: executor:: stack:: PrecompileFailure :: Error {
239- exit_status: :: evm:: ExitError :: Other ( "invalid call" . into( ) ) ,
240- } ) ) ;
241- }
242- let selector = match handle. input( ) . get( ..#SELECTOR_LENGTH ) {
242+ fn dispatch_call<G , H >(
243+ input: & [ u8 ] ,
244+ gasometer: & mut G ,
245+ handler: & mut H ,
246+ ) -> #evm_crate:: precompile:: PrecompileResult
247+ where
248+ G : AsRef <:: evm:: interpreter:: runtime:: RuntimeState > + :: evm:: GasMutState ,
249+ H : :: evm:: interpreter:: runtime:: RuntimeBackend ,
250+ {
251+ let selector = match input. get( ..#SELECTOR_LENGTH ) {
243252 Some ( slice) => slice,
244- None => return Some ( Err ( :: evm:: executor:: stack:: PrecompileFailure :: Revert {
245- exit_status: :: evm:: ExitRevert :: Reverted ,
246- output: vec![ ] ,
247- } ) ) ,
253+ None => return Err ( :: evm:: interpreter:: ExitError :: Reverted . into( ) ) ,
248254 } ;
249255 match selector {
250256 #( #method_arms) *
251- _ => Some ( Err ( :: evm:: executor:: stack:: PrecompileFailure :: Revert {
252- exit_status: :: evm:: ExitRevert :: Reverted ,
253- output: vec![ ] ,
254- } ) ) ,
257+ _ => Err ( :: evm:: interpreter:: ExitError :: Reverted . into( ) ) ,
255258 }
256259 }
257260 }
258261
259262 #[ automatically_derived]
260- impl #impl_generics :: evm:: executor:: stack:: PrecompileSet for #self_ty {
261- fn execute( & self , handle: & mut impl :: evm:: executor:: stack:: PrecompileHandle ) -> Option <Result <:: evm:: executor:: stack:: PrecompileOutput , :: evm:: executor:: stack:: PrecompileFailure >> {
262- match self . is_precompile( handle. code_address( ) , handle. remaining_gas( ) ) {
263- :: evm:: executor:: stack:: IsPrecompileResult :: Answer {
264- is_precompile: true ,
265- extra_cost,
266- } => {
267- if let Err ( e) = handle. record_cost( extra_cost) {
268- return Some ( Err ( e. into( ) ) ) ;
269- }
270- }
271- :: evm:: executor:: stack:: IsPrecompileResult :: OutOfGas => {
272- return Some ( Err ( :: evm:: ExitError :: OutOfGas . into( ) ) ) ;
273- }
274- _ => {
275- return None ;
276- }
263+ impl #impl_generics_gh :: evm:: standard:: PrecompileSet <G , H > for #self_ty {
264+ fn execute(
265+ & self ,
266+ code_address: H160 ,
267+ input: & [ u8 ] ,
268+ gasometer: & mut G ,
269+ handler: & mut H ,
270+ ) -> Option <( :: evm:: interpreter:: ExitResult , Vec <u8 >) > {
271+ if code_address != Self :: address( ) {
272+ return None ;
277273 }
278274
279- <Self as #evm_crate:: precompile:: contract:: StaticContract >:: dispatch_call( handle)
280- }
275+ let result = <Self as #evm_crate:: precompile:: contract:: StaticContract >:: dispatch_call(
276+ input,
277+ gasometer,
278+ handler,
279+ ) ;
281280
282- fn is_precompile(
283- & self ,
284- address: :: primitive_types:: H160 ,
285- _remaining_gas: u64 ,
286- ) -> :: evm:: executor:: stack:: IsPrecompileResult {
287- :: evm:: executor:: stack:: IsPrecompileResult :: Answer {
288- is_precompile: Self :: address( ) == address,
289- extra_cost: 0 ,
281+ match result {
282+ Ok ( success) => Some ( ( success. status. into( ) , success. output) ) ,
283+ Err ( err) => Some ( ( err. error. into( ) , err. output) ) ,
290284 }
291285 }
292286 }
@@ -372,14 +366,26 @@ pub fn derive_evm_event(input: DeriveInput) -> TokenStream {
372366 #[ automatically_derived]
373367 #[ allow( clippy:: cloned_ref_to_slice_refs) ]
374368 impl #evm_crate:: precompile:: contract:: EvmEvent for #event_ty {
375- fn emit<C : #evm_crate:: precompile:: contract:: StaticContract >( & self , handle: & mut impl :: evm:: executor:: stack:: PrecompileHandle ) -> Result <( ) , :: evm:: ExitError > {
369+ fn emit<C , H >(
370+ & self ,
371+ handler: & mut H ,
372+ ) -> Result <( ) , #evm_crate:: precompile:: PrecompileError >
373+ where
374+ C : #evm_crate:: precompile:: contract:: StaticContract ,
375+ H : :: evm:: interpreter:: runtime:: RuntimeBackend ,
376+ {
376377 let address = C :: address( ) ;
377378 let topics = vec![
378379 :: primitive_types:: H256 :: from_slice( & [ #( #signature_tokens , ) * ] ) ,
379380 #( #topics , ) *
380381 ] ;
381382 let data = #data_tokens;
382- handle. log( address, topics, data)
383+ handler. log( :: evm:: interpreter:: runtime:: Log {
384+ address,
385+ topics,
386+ data,
387+ } ) ?;
388+ Ok ( ( ) )
383389 }
384390 }
385391 }
@@ -405,6 +411,8 @@ pub fn derive_evm_error(input: DeriveInput) -> TokenStream {
405411 Err ( e) => return e. write_errors ( ) ,
406412 } ;
407413
414+ let evm_crate = evm_crate_path ( ) ;
415+
408416 let mut variant_encoders: Vec < TokenStream > = Vec :: new ( ) ;
409417 for variant in error. data . as_ref ( ) . take_enum ( ) . unwrap ( ) . iter ( ) {
410418 let ident = & variant. ident ;
@@ -458,21 +466,20 @@ pub fn derive_evm_error(input: DeriveInput) -> TokenStream {
458466 let mut output = Vec :: new( ) ;
459467 output. extend( & [ #( #hash_bytes, ) * ] ) ;
460468 #encode_expr
461- :: evm :: executor :: stack :: PrecompileFailure :: Revert {
462- exit_status : :: evm:: ExitRevert :: Reverted ,
469+ #evm_crate :: precompile :: PrecompileError :: new (
470+ :: evm:: interpreter :: ExitError :: Reverted ,
463471 output,
464- }
472+ )
465473 }
466474 } ) ;
467475 }
468476
469- let evm_crate = evm_crate_path ( ) ;
470477 let error_ty = & error. ident ;
471478
472479 quote ! {
473480 #[ automatically_derived]
474481 impl #evm_crate:: precompile:: contract:: EvmError for #error_ty {
475- fn encode( & self ) -> :: evm :: executor :: stack :: PrecompileFailure {
482+ fn encode( & self ) -> #evm_crate :: precompile :: PrecompileError {
476483 match self {
477484 #( #variant_encoders) *
478485 }
0 commit comments