diff --git a/src/as_execution/common.rs b/src/as_execution/common.rs index dd48c62d..0d25da2a 100644 --- a/src/as_execution/common.rs +++ b/src/as_execution/common.rs @@ -38,6 +38,8 @@ pub(crate) fn call_module( ))) })?; + interface.increment_recursion_counter()?; + let resp = crate::execution::run_function( &*interface, module, @@ -50,6 +52,8 @@ pub(crate) fn call_module( if cfg!(not(feature = "gas_calibration")) { set_remaining_points(&env, ctx, resp.remaining_gas)?; } + + interface.decrement_recursion_counter()?; env.get_interface().finish_call()?; Ok(resp) } @@ -73,6 +77,8 @@ pub(crate) fn local_call( interface.get_module(bytecode, remaining_gas)? }; + interface.increment_recursion_counter()?; + let resp = crate::execution::run_function( &*interface, module, @@ -82,6 +88,9 @@ pub(crate) fn local_call( gas_costs, env.get_condom_limits(), )?; + + interface.decrement_recursion_counter()?; + if cfg!(not(feature = "gas_calibration")) { set_remaining_points(&env, ctx, resp.remaining_gas)?; } diff --git a/src/tests/mod.rs b/src/tests/mod.rs index 8d7f4a7e..33b588d0 100644 --- a/src/tests/mod.rs +++ b/src/tests/mod.rs @@ -18,6 +18,16 @@ impl InterfaceClone for TestInterface { } impl Interface for TestInterface { + fn increment_recursion_counter(&self) -> Result<()> { + println!("Increment recursion counter"); + Ok(()) + } + + fn decrement_recursion_counter(&self) -> Result<()> { + println!("Decrement recursion counter"); + Ok(()) + } + fn init_call(&self, address: &str, raw_coins: u64) -> Result> { println!("Init call to {}, with {} coins", address, raw_coins); Ok(vec![]) diff --git a/src/types.rs b/src/types.rs index f9e60505..42da156a 100644 --- a/src/types.rs +++ b/src/types.rs @@ -452,6 +452,10 @@ impl Default for GasCosts { #[allow(unused_variables)] pub trait Interface: Send + Sync + InterfaceClone { + fn increment_recursion_counter(&self) -> Result<()>; + + fn decrement_recursion_counter(&self) -> Result<()>; + fn get_interface_version(&self) -> Result; /// Prepare the execution of a module at the given address and transfer a diff --git a/src/wasmv1_execution/abi/abis.rs b/src/wasmv1_execution/abi/abis.rs index 996aeb8c..bae9951e 100644 --- a/src/wasmv1_execution/abi/abis.rs +++ b/src/wasmv1_execution/abi/abis.rs @@ -152,6 +152,9 @@ fn abi_call(store_env: FunctionEnvMut, arg_offset: i32) -> Result, arg_offset: i32) -> Result, arg_offset: i32) -> Result< let remaining_gas = handler.get_remaining_gas(); let interface = handler.exec_env.get_interface(); let module = helper_get_module(interface, bytecode.clone(), remaining_gas)?; - + interface.increment_recursion_counter().map_err(|e| { + WasmV1Error::RuntimeError(format!("Could not increment recursion counter: {}", e)) + })?; let response = crate::execution::run_function( interface, module, @@ -213,6 +221,9 @@ fn abi_local_call(store_env: FunctionEnvMut, arg_offset: i32) -> Result< handler.get_condom_limits().clone(), ) .map_err(|err| WasmV1Error::RuntimeError(format!("Could not run function: {}", err)))?; + interface.decrement_recursion_counter().map_err(|e| { + WasmV1Error::RuntimeError(format!("Could not decrement recursion counter: {}", e)) + })?; handler.set_remaining_gas(response.remaining_gas); #[cfg(feature = "execution-trace")] @@ -1024,6 +1035,9 @@ fn abi_local_execution( let module = helper_get_tmp_module(handler, req.bytecode.clone(), remaining_gas)?; let interface = handler.exec_env.get_interface(); + interface.increment_recursion_counter().map_err(|e| { + WasmV1Error::RuntimeError(format!("Could not increment recursion counter: {}", e)) + })?; match crate::execution::run_function( interface, module, @@ -1034,6 +1048,12 @@ fn abi_local_execution( handler.get_condom_limits().clone(), ) { Ok(response) => { + interface.decrement_recursion_counter().map_err(|e| { + WasmV1Error::RuntimeError(format!( + "Could not decrement recursion counter: {}", + e + )) + })?; handler.set_remaining_gas(response.remaining_gas); #[cfg(feature = "execution-trace")]