diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 9680c19dfc6..54b2a3aa207 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -1570,22 +1570,27 @@ impl Call for Client { let schedule = machine.schedule(env_info.number); Executive::new(&mut clone, &env_info, &machine, &schedule) .transact_virtual(&tx, options()) - .ok() - .map(|r| r.exception.is_none()) }; - let cond = |gas| exec(gas).unwrap_or(false); + let cond = |gas| { + exec(gas) + .ok() + .map_or(false, |r| r.exception.is_none()) + }; if !cond(upper) { upper = max_upper; match exec(upper) { - Some(false) => return Err(CallError::Exceptional), - None => { + Ok(v) => { + if let Some(exception) = v.exception { + return Err(CallError::Exceptional(exception)) + } + }, + Err(_e) => { trace!(target: "estimate_gas", "estimate_gas failed with {}", upper); let err = ExecutionError::Internal(format!("Requires higher than upper limit of {}", upper)); return Err(err.into()) - }, - _ => {}, + } } } let lower = t.gas_required(&self.engine.schedule(env_info.number)).into(); diff --git a/ethcore/src/executed.rs b/ethcore/src/executed.rs index 0f46ee1decd..10e06fd05e2 100644 --- a/ethcore/src/executed.rs +++ b/ethcore/src/executed.rs @@ -167,7 +167,7 @@ pub enum CallError { /// Couldn't find requested block's state in the chain. StatePruned, /// Couldn't find an amount of gas that didn't result in an exception. - Exceptional, + Exceptional(vm::Error), /// Corrupt state. StateCorrupt, /// Error executing. @@ -187,7 +187,7 @@ impl fmt::Display for CallError { let msg = match *self { TransactionNotFound => "Transaction couldn't be found in the chain".into(), StatePruned => "Couldn't find the transaction block's state in the chain".into(), - Exceptional => "An exception happened in the execution".into(), + Exceptional(ref e) => format!("An exception ({}) happened in the execution", e), StateCorrupt => "Stored state found to be corrupted.".into(), Execution(ref e) => format!("{}", e), }; diff --git a/rpc/src/v1/helpers/errors.rs b/rpc/src/v1/helpers/errors.rs index 1ff40f979b7..c04374d6562 100644 --- a/rpc/src/v1/helpers/errors.rs +++ b/rpc/src/v1/helpers/errors.rs @@ -173,11 +173,11 @@ pub fn state_corrupt() -> Error { internal("State corrupt", "") } -pub fn exceptional() -> Error { +pub fn exceptional(data: T) -> Error { Error { code: ErrorCode::ServerError(codes::EXCEPTION_ERROR), message: "The execution failed due to an exception.".into(), - data: None, + data: Some(Value::String(data.to_string())), } } @@ -467,7 +467,7 @@ pub fn call(error: CallError) -> Error { match error { CallError::StatePruned => state_pruned(), CallError::StateCorrupt => state_corrupt(), - CallError::Exceptional => exceptional(), + CallError::Exceptional(e) => exceptional(e), CallError::Execution(e) => execution(e), CallError::TransactionNotFound => internal("{}, this should not be the case with eth_call, most likely a bug.", CallError::TransactionNotFound), }