Skip to content

feat: reduce default gas limit to ~1B #8274

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions crates/config/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,10 @@ initial_balance = '0xffffffffffffffffffffffff'
block_number = 0
fork_block_number = 0
chain_id = 1
# NOTE due to a toml-rs limitation, this value needs to be a string if the desired gas limit exceeds `i64::MAX` (9223372036854775807)
# `gas_limit = "Max"` is equivalent to `gas_limit = "18446744073709551615"`
gas_limit = 9223372036854775807
# NOTE due to a toml-rs limitation, this value needs to be a string if the desired gas limit exceeds 2**63-1 (9223372036854775807).
# `gas_limit = "max"` is equivalent to `gas_limit = "18446744073709551615"`. This is not recommended
# as it will make infinite loops effectively hang during execution.
gas_limit = 1073741824
gas_price = 0
block_base_fee_per_gas = 0
block_coinbase = '0x0000000000000000000000000000000000000000'
Expand Down
55 changes: 8 additions & 47 deletions crates/config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ use inflector::Inflector;
use regex::Regex;
use revm_primitives::{FixedBytes, SpecId};
use semver::Version;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use serde::{Deserialize, Serialize, Serializer};
use std::{
borrow::Cow,
collections::HashMap,
Expand Down Expand Up @@ -2075,11 +2075,11 @@ impl Default for Config {
prompt_timeout: 120,
sender: Self::DEFAULT_SENDER,
tx_origin: Self::DEFAULT_SENDER,
initial_balance: U256::from(0xffffffffffffffffffffffffu128),
initial_balance: U256::from((1u128 << 96) - 1),
block_number: 1,
fork_block_number: None,
chain: None,
gas_limit: i64::MAX.into(),
gas_limit: (1u64 << 30).into(), // ~1B
code_size_limit: None,
gas_price: None,
block_base_fee_per_gas: 0,
Expand Down Expand Up @@ -2138,29 +2138,14 @@ impl Default for Config {
///
/// Due to this limitation this type will be serialized/deserialized as String if it's larger than
/// `i64`
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct GasLimit(pub u64);
#[derive(Clone, Copy, Debug, PartialEq, Eq, Deserialize)]
pub struct GasLimit(#[serde(deserialize_with = "crate::deserialize_u64_or_max")] pub u64);

impl From<u64> for GasLimit {
fn from(gas: u64) -> Self {
Self(gas)
}
}
impl From<i64> for GasLimit {
fn from(gas: i64) -> Self {
Self(gas as u64)
}
}
impl From<i32> for GasLimit {
fn from(gas: i32) -> Self {
Self(gas as u64)
}
}
impl From<u32> for GasLimit {
fn from(gas: u32) -> Self {
Self(gas as u64)
}
}

impl From<GasLimit> for u64 {
fn from(gas: GasLimit) -> Self {
Expand All @@ -2173,40 +2158,16 @@ impl Serialize for GasLimit {
where
S: Serializer,
{
if self.0 > i64::MAX as u64 {
if self.0 == u64::MAX {
serializer.serialize_str("max")
} else if self.0 > i64::MAX as u64 {
serializer.serialize_str(&self.0.to_string())
} else {
serializer.serialize_u64(self.0)
}
}
}

impl<'de> Deserialize<'de> for GasLimit {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
use serde::de::Error;

#[derive(Deserialize)]
#[serde(untagged)]
enum Gas {
Number(u64),
Text(String),
}

let gas = match Gas::deserialize(deserializer)? {
Gas::Number(num) => Self(num),
Gas::Text(s) => match s.as_str() {
"max" | "MAX" | "Max" | "u64::MAX" | "u64::Max" => Self(u64::MAX),
s => Self(s.parse().map_err(D::Error::custom)?),
},
};

Ok(gas)
}
}

/// Variants for selecting the [`Solc`] instance
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(untagged)]
Expand Down
34 changes: 17 additions & 17 deletions crates/config/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,31 +236,31 @@ where
}
}

/// Deserialize an usize or
pub(crate) fn deserialize_usize_or_max<'de, D>(deserializer: D) -> Result<usize, D::Error>
/// Deserialize a `u64` or "max" for `u64::MAX`.
pub(crate) fn deserialize_u64_or_max<'de, D>(deserializer: D) -> Result<u64, D::Error>
where
D: Deserializer<'de>,
{
#[derive(Deserialize)]
#[serde(untagged)]
enum Val {
Number(usize),
Text(String),
Number(u64),
String(String),
}

let num = match Val::deserialize(deserializer)? {
Val::Number(num) => num,
Val::Text(s) => {
match s.as_str() {
"max" | "MAX" | "Max" => {
// toml limitation
i64::MAX as usize
}
s => s.parse::<usize>().map_err(D::Error::custom).unwrap(),
}
}
};
Ok(num)
match Val::deserialize(deserializer)? {
Val::Number(num) => Ok(num),
Val::String(s) if s.eq_ignore_ascii_case("max") => Ok(u64::MAX),
Val::String(s) => s.parse::<u64>().map_err(D::Error::custom),
}
}

/// Deserialize a `usize` or "max" for `usize::MAX`.
pub(crate) fn deserialize_usize_or_max<'de, D>(deserializer: D) -> Result<usize, D::Error>
where
D: Deserializer<'de>,
{
deserialize_u64_or_max(deserializer)?.try_into().map_err(D::Error::custom)
}

/// Helper type to parse both `u64` and `U256`
Expand Down
18 changes: 10 additions & 8 deletions crates/evm/evm/src/inspectors/stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -926,6 +926,16 @@ impl<'a, DB: DatabaseExt> InspectorExt<DB> for InspectorStackRefMut<'a> {
}

impl<DB: DatabaseExt> Inspector<DB> for InspectorStack {
#[inline]
fn step(&mut self, interpreter: &mut Interpreter, ecx: &mut EvmContext<DB>) {
self.as_mut().step(interpreter, ecx)
}

#[inline]
fn step_end(&mut self, interpreter: &mut Interpreter, ecx: &mut EvmContext<DB>) {
self.as_mut().step_end(interpreter, ecx)
}

fn call(
&mut self,
context: &mut EvmContext<DB>,
Expand Down Expand Up @@ -971,14 +981,6 @@ impl<DB: DatabaseExt> Inspector<DB> for InspectorStack {
fn selfdestruct(&mut self, contract: Address, target: Address, value: U256) {
Inspector::<DB>::selfdestruct(&mut self.as_mut(), contract, target, value)
}

fn step(&mut self, interpreter: &mut Interpreter, ecx: &mut EvmContext<DB>) {
self.as_mut().step(interpreter, ecx)
}

fn step_end(&mut self, interpreter: &mut Interpreter, ecx: &mut EvmContext<DB>) {
self.as_mut().step_end(interpreter, ecx)
}
}

impl<DB: DatabaseExt> InspectorExt<DB> for InspectorStack {
Expand Down
16 changes: 10 additions & 6 deletions crates/forge/tests/cli/ext_integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@ fn forge_std() {

#[test]
fn solmate() {
let tester =
let mut tester =
ExtTester::new("transmissions11", "solmate", "c892309933b25c03d32b1b0d674df7ae292ba925");

#[cfg(feature = "isolate-by-default")]
let tester = tester.args(["--nmc", "ReentrancyGuardTest"]);
if cfg!(feature = "isolate-by-default") {
tester = tester.args(["--nmc", "ReentrancyGuardTest"]);
}

tester.run();
}
Expand Down Expand Up @@ -42,10 +43,12 @@ fn prb_proxy() {
#[test]
#[cfg_attr(windows, ignore = "Windows cannot find installed programs")]
fn sablier_v2() {
let tester =
let mut tester =
ExtTester::new("sablier-labs", "v2-core", "84758a40077bf3ccb1c8f7bb8d00278e672fbfef")
// Skip fork tests.
.args(["--nmc", "Fork"])
// Increase the gas limit: https://github.com/sablier-labs/v2-core/issues/956
.args(["--gas-limit", u64::MAX.to_string().as_str()])
// Run tests without optimizations.
.env("FOUNDRY_PROFILE", "lite")
.install_command(&["bun", "install", "--prefer-offline"])
Expand All @@ -54,8 +57,9 @@ fn sablier_v2() {

// This test reverts due to memory limit without isolation. This revert is not reached with
// isolation because memory is divided between separate EVMs created by inner calls.
#[cfg(feature = "isolate-by-default")]
let tester = tester.args(["--nmt", "test_RevertWhen_LoopCalculationOverflowsBlockGasLimit"]);
if cfg!(feature = "isolate-by-default") {
tester = tester.args(["--nmt", "test_RevertWhen_LoopCalculationOverflowsBlockGasLimit"]);
}

tester.run();
}
Expand Down
Loading