Skip to content
This repository was archived by the owner on Nov 6, 2020. It is now read-only.

Commit 708e0e5

Browse files
andresilvaAndronik Ordian
authored andcommitted
ethcore: handle vm exception when estimating gas (#9615)
1 parent b395da9 commit 708e0e5

File tree

1 file changed

+17
-11
lines changed

1 file changed

+17
-11
lines changed

ethcore/src/client/client.rs

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1486,28 +1486,34 @@ impl Call for Client {
14861486
let sender = t.sender();
14871487
let options = || TransactOptions::with_tracing().dont_check_nonce();
14881488

1489-
let cond = |gas| {
1489+
let exec = |gas| {
14901490
let mut tx = t.as_unsigned().clone();
14911491
tx.gas = gas;
14921492
let tx = tx.fake_sign(sender);
14931493

14941494
let mut clone = state.clone();
1495-
Ok(Executive::new(&mut clone, &env_info, self.engine.machine())
1495+
Executive::new(&mut clone, &env_info, self.engine.machine())
14961496
.transact_virtual(&tx, options())
1497+
.ok()
14971498
.map(|r| r.exception.is_none())
1498-
.unwrap_or(false))
14991499
};
15001500

1501-
if !cond(upper)? {
1501+
let cond = |gas| exec(gas).unwrap_or(false);
1502+
1503+
if !cond(upper) {
15021504
upper = max_upper;
1503-
if !cond(upper)? {
1504-
trace!(target: "estimate_gas", "estimate_gas failed with {}", upper);
1505-
let err = ExecutionError::Internal(format!("Requires higher than upper limit of {}", upper));
1506-
return Err(err.into())
1505+
match exec(upper) {
1506+
Some(false) => return Err(CallError::Exceptional),
1507+
None => {
1508+
trace!(target: "estimate_gas", "estimate_gas failed with {}", upper);
1509+
let err = ExecutionError::Internal(format!("Requires higher than upper limit of {}", upper));
1510+
return Err(err.into())
1511+
},
1512+
_ => {},
15071513
}
15081514
}
15091515
let lower = t.gas_required(&self.engine.schedule(env_info.number)).into();
1510-
if cond(lower)? {
1516+
if cond(lower) {
15111517
trace!(target: "estimate_gas", "estimate_gas succeeded with {}", lower);
15121518
return Ok(lower)
15131519
}
@@ -1516,12 +1522,12 @@ impl Call for Client {
15161522
/// Returns the lowest value between `lower` and `upper` for which `cond` returns true.
15171523
/// We assert: `cond(lower) = false`, `cond(upper) = true`
15181524
fn binary_chop<F, E>(mut lower: U256, mut upper: U256, mut cond: F) -> Result<U256, E>
1519-
where F: FnMut(U256) -> Result<bool, E>
1525+
where F: FnMut(U256) -> bool
15201526
{
15211527
while upper - lower > 1.into() {
15221528
let mid = (lower + upper) / 2.into();
15231529
trace!(target: "estimate_gas", "{} .. {} .. {}", lower, mid, upper);
1524-
let c = cond(mid)?;
1530+
let c = cond(mid);
15251531
match c {
15261532
true => upper = mid,
15271533
false => lower = mid,

0 commit comments

Comments
 (0)