Skip to content

Commit fc58b46

Browse files
authored
fix: estimation min set to gas_used - 1 rather than to estimate - 1 (#112)
* fix: estimation min set to gas_used - 1 rather than to estimate - 1 * chore: version bump * fix: rename to limit
1 parent f9f5dd1 commit fc58b46

File tree

4 files changed

+44
-32
lines changed

4 files changed

+44
-32
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "trevm"
3-
version = "0.23.6"
3+
version = "0.23.7"
44
rust-version = "1.83.0"
55
edition = "2021"
66
authors = ["init4"]

src/est.rs

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,8 @@ impl SearchRange {
9595
pub enum EstimationResult {
9696
/// The estimation was successful, the result is the gas estimation.
9797
Success {
98-
/// The gas estimation.
99-
estimation: u64,
98+
/// The input estimation limit.
99+
limit: u64,
100100
/// The amount of gas that was refunded to the caller as unused.
101101
refund: u64,
102102
/// The amount of gas used in the execution.
@@ -106,13 +106,17 @@ pub enum EstimationResult {
106106
},
107107
/// Estimation failed due to contract revert.
108108
Revert {
109+
/// The input estimation limit.
110+
limit: u64,
109111
/// The revert reason.
110112
reason: Bytes,
111113
/// The amount of gas used in the execution.
112114
gas_used: u64,
113115
},
114116
/// The estimation failed due to EVM halt.
115117
Halt {
118+
/// The input estimation limit.
119+
limit: u64,
116120
/// The halt reason.
117121
reason: HaltReason,
118122
/// The amount of gas used in the execution
@@ -123,18 +127,17 @@ pub enum EstimationResult {
123127
impl core::fmt::Display for EstimationResult {
124128
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
125129
match self {
126-
Self::Success { estimation, refund, gas_used, .. } => {
130+
Self::Success { limit, refund, gas_used, .. } => {
127131
write!(
128132
f,
129-
"Success {{ estimation: {}, refund: {}, gas_used: {}, .. }}",
130-
estimation, refund, gas_used
133+
"Success {{ gas_limit: {limit}, refund: {refund}, gas_used: {gas_used}, .. }}",
131134
)
132135
}
133-
Self::Revert { gas_used, .. } => {
134-
write!(f, "Revert {{ gas_used: {}, .. }}", gas_used)
136+
Self::Revert { limit, gas_used, .. } => {
137+
write!(f, "Revert {{ gas_limit: {limit}, gas_used: {gas_used}, .. }}")
135138
}
136-
Self::Halt { reason, gas_used } => {
137-
write!(f, "Halt {{ reason: {:?}, gas_used: {} }}", reason, gas_used)
139+
Self::Halt { limit, reason, gas_used } => {
140+
write!(f, "Halt {{ gas_limit: {limit}, reason: {reason:?}, gas_used: {gas_used} }}")
138141
}
139142
}
140143
}
@@ -146,24 +149,24 @@ impl EstimationResult {
146149
pub fn from_limit_and_execution_result(limit: u64, value: &ExecutionResult) -> Self {
147150
match value {
148151
ExecutionResult::Success { gas_used, output, gas_refunded, .. } => Self::Success {
149-
estimation: limit,
152+
limit,
150153
refund: *gas_refunded,
151154
gas_used: *gas_used,
152155
output: output.clone(),
153156
},
154157
ExecutionResult::Revert { output, gas_used } => {
155-
Self::Revert { reason: output.clone(), gas_used: *gas_used }
158+
Self::Revert { limit, reason: output.clone(), gas_used: *gas_used }
156159
}
157160
ExecutionResult::Halt { reason, gas_used } => {
158-
Self::Halt { reason: *reason, gas_used: *gas_used }
161+
Self::Halt { limit, reason: *reason, gas_used: *gas_used }
159162
}
160163
}
161164
}
162165

163166
/// Create a successful estimation result with a gas estimation of 21000.
164167
pub const fn basic_transfer_success(estimation: u64) -> Self {
165168
Self::Success {
166-
estimation,
169+
limit: estimation,
167170
refund: 0,
168171
gas_used: estimation,
169172
output: Output::Call(Bytes::new()),
@@ -180,11 +183,13 @@ impl EstimationResult {
180183
!self.is_success()
181184
}
182185

183-
/// Get the gas estimation, if the execution was successful.
184-
pub const fn gas_estimation(&self) -> Option<u64> {
186+
/// Get the gas limit that was set in the EVM when the estimation was
187+
/// produced.
188+
pub const fn limit(&self) -> u64 {
185189
match self {
186-
Self::Success { estimation, .. } => Some(*estimation),
187-
_ => None,
190+
Self::Success { limit, .. } => *limit,
191+
Self::Revert { limit, .. } => *limit,
192+
Self::Halt { limit, .. } => *limit,
188193
}
189194
}
190195

@@ -242,13 +247,12 @@ impl EstimationResult {
242247
/// Adjust the binary search range based on the estimation outcome.
243248
pub(crate) const fn adjust_binary_search_range(
244249
&self,
245-
limit: u64,
246250
range: &mut SearchRange,
247251
) -> Result<(), Self> {
248252
match self {
249-
Self::Success { .. } => range.set_max(limit),
250-
Self::Revert { .. } => range.set_min(limit),
251-
Self::Halt { reason, gas_used } => {
253+
Self::Success { limit, .. } => range.set_max(*limit),
254+
Self::Revert { limit, .. } => range.set_min(*limit),
255+
Self::Halt { limit, reason, gas_used } => {
252256
// Both `OutOfGas` and `InvalidEFOpcode` can occur dynamically
253257
// if the gas left is too low. Treat this as an out of gas
254258
// condition, knowing that the call succeeds with a
@@ -257,9 +261,9 @@ impl EstimationResult {
257261
// Common usage of invalid opcode in OpenZeppelin:
258262
// <https://github.com/OpenZeppelin/openzeppelin-contracts/blob/94697be8a3f0dfcd95dfb13ffbd39b5973f5c65d/contracts/metatx/ERC2771Forwarder.sol#L360-L367>
259263
if matches!(reason, HaltReason::OutOfGas(_) | HaltReason::InvalidFEOpcode) {
260-
range.set_min(limit);
264+
range.set_min(*limit);
261265
} else {
262-
return Err(Self::Halt { reason: *reason, gas_used: *gas_used });
266+
return Err(Self::Halt { limit: *limit, reason: *reason, gas_used: *gas_used });
263267
}
264268
}
265269
}

src/evm.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1799,7 +1799,7 @@ where
17991799
/// [`MIN_TRANSACTION_GAS`]: crate::MIN_TRANSACTION_GAS
18001800
#[cfg(feature = "estimate_gas")]
18011801
pub fn estimate_gas(mut self) -> Result<(crate::EstimationResult, Self), EvmErrored<Db, Insp>> {
1802-
use tracing::{debug, enabled};
1802+
use tracing::{debug, enabled, trace};
18031803

18041804
if let Some(est) = trevm_try!(self.estimate_gas_simple_transfer(), self) {
18051805
return Ok((crate::EstimationResult::basic_transfer_success(est), self));
@@ -1814,13 +1814,15 @@ where
18141814
crate::est::SearchRange::new(crate::MIN_TRANSACTION_GAS, initial_limit);
18151815

18161816
let span = tracing::debug_span!(
1817-
"estimate_gas",
1817+
"Trevm::estimate_gas",
18181818
start_min = search_range.min(),
18191819
start_max = search_range.max(),
1820-
tx = "omitted",
18211820
);
18221821
if enabled!(tracing::Level::TRACE) {
18231822
span.record("tx", format!("{:?}", &self.tx()));
1823+
span.record("block", format!("{:?}", &self.block()));
1824+
} else {
1825+
span.record("tx", "omitted. Use TRACE for details");
18241826
}
18251827
let _e = span.enter();
18261828

@@ -1834,7 +1836,7 @@ where
18341836
// Run an estimate with the max gas limit.
18351837
// NB: we declare these mut as we re-use the binding throughout the
18361838
// function.
1837-
debug!(gas_limit = search_range.max(), "running optimistic estimate");
1839+
debug!(gas_limit = self.gas_limit(), "running optimistic estimate");
18381840
let (mut estimate, mut trevm) = self.run_estimate(&search_range.max().into())?;
18391841

18401842
// If it failed, no amount of gas is likely to work, so we shortcut
@@ -1843,10 +1845,11 @@ where
18431845
debug!(%estimate, "optimistic estimate failed");
18441846
return Ok((estimate, trevm));
18451847
}
1848+
trace!(%estimate, "optimistic estimate succeeded");
18461849

18471850
// Now we know that it succeeds at _some_ gas limit. We can now binary
18481851
// search.
1849-
let mut gas_used = estimate.gas_estimation().expect("checked is_failure");
1852+
let mut gas_used = estimate.gas_used();
18501853
let gas_refunded = estimate.gas_refunded().expect("checked is_failure");
18511854

18521855
// NB: if we've made it this far it's very unlikely that `gas_used` is
@@ -1862,6 +1865,7 @@ where
18621865
// frame can forward only 63/64 of the gas it has when it makes a new
18631866
// frame.
18641867
let mut needle = gas_used + gas_refunded + revm::interpreter::gas::CALL_STIPEND * 64 / 63;
1868+
18651869
// If the first search is outside the range, we don't need to try it.
18661870
if search_range.contains(needle) {
18671871
estimate_and_adjust!(estimate, trevm, needle, search_range);

src/macros.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,17 @@ macro_rules! estimate_and_adjust {
4545
($est:ident, $trevm:ident, $gas_limit:ident, $range:ident) => {
4646
::tracing::trace!(
4747
estimate = %$est,
48-
gas_limit = $gas_limit,
49-
range = %$range,
48+
max = %$range.max(),
49+
min = %$range.min(),
5050
"running gas estimate call"
5151
);
5252

5353
($est, $trevm) = $trevm.run_estimate(&$gas_limit.into())?;
54-
if let Err(e) = $est.adjust_binary_search_range($gas_limit, &mut $range) {
54+
if let Err(e) = $est.adjust_binary_search_range(&mut $range) {
55+
::tracing::trace!(
56+
%e,
57+
"error adjusting binary search range"
58+
);
5559
return Ok((e, $trevm));
5660
}
5761
};

0 commit comments

Comments
 (0)