diff --git a/client/rpc/src/eth.rs b/client/rpc/src/eth.rs index 20a094256b..10f40862a5 100644 --- a/client/rpc/src/eth.rs +++ b/client/rpc/src/eth.rs @@ -1524,9 +1524,21 @@ where used_gas: U256, } - // Create a helper to check if a gas allowance results in an executable transaction + // Create a helper to check if a gas allowance results in an executable transaction. + // + // A new ApiRef instance needs to be used per execution to avoid the overlayed state to affect + // the estimation result of subsequent calls. + // + // Note that this would have a performance penalty if we introduce gas estimation for past + // blocks - and thus, past runtime versions. Substrate has a default `runtime_cache_size` of + // 2 slots LRU-style, meaning if users were to access multiple runtime versions in a short period + // of time, the RPC response time would degrade a lot, as the VersionedRuntime needs to be compiled. + // + // To solve that, and if we introduce historical gas estimation, we'd need to increase that default. #[rustfmt::skip] - let executable = move |request, gas_limit, api_version, estimate_mode| -> Result { + let executable = move | + request, gas_limit, api_version, api: sp_api::ApiRef<'_, C::Api>, estimate_mode + | -> Result { let CallRequest { from, to, @@ -1689,7 +1701,13 @@ where data, exit_reason, used_gas, - } = executable(request.clone(), highest, api_version, estimate_mode)?; + } = executable( + request.clone(), + highest, + api_version, + client.runtime_api(), + estimate_mode, + )?; match exit_reason { ExitReason::Succeed(_) => (), ExitReason::Error(ExitError::OutOfGas) => { @@ -1714,6 +1732,7 @@ where request.clone(), get_current_block_gas_limit().await?, api_version, + client.runtime_api(), estimate_mode, )?; match exit_reason { @@ -1755,7 +1774,13 @@ where data, exit_reason, used_gas: _, - } = executable(request.clone(), mid, api_version, estimate_mode)?; + } = executable( + request.clone(), + mid, + api_version, + client.runtime_api(), + estimate_mode, + )?; match exit_reason { ExitReason::Succeed(_) => { highest = mid;