Another minor estimation fix (#4133)
* Return 0 instead of error with out of gas on estimate_gas * Fix stuff up. * Another estimate gas fix. * Alter balance to maximum possible rather than GP=0. * Only increase to amount strictly necessary.
This commit is contained in:
parent
8d3d76c107
commit
56c546f465
@ -874,6 +874,7 @@ impl BlockChainClient for Client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn estimate_gas(&self, t: &SignedTransaction, block: BlockId) -> Result<U256, CallError> {
|
fn estimate_gas(&self, t: &SignedTransaction, block: BlockId) -> Result<U256, CallError> {
|
||||||
|
const UPPER_CEILING: u64 = 1_000_000_000_000u64;
|
||||||
let header = self.block_header(block).ok_or(CallError::StatePruned)?;
|
let header = self.block_header(block).ok_or(CallError::StatePruned)?;
|
||||||
let last_hashes = self.build_last_hashes(header.parent_hash());
|
let last_hashes = self.build_last_hashes(header.parent_hash());
|
||||||
let env_info = EnvInfo {
|
let env_info = EnvInfo {
|
||||||
@ -883,37 +884,38 @@ impl BlockChainClient for Client {
|
|||||||
difficulty: header.difficulty(),
|
difficulty: header.difficulty(),
|
||||||
last_hashes: last_hashes,
|
last_hashes: last_hashes,
|
||||||
gas_used: U256::zero(),
|
gas_used: U256::zero(),
|
||||||
gas_limit: U256::max_value(),
|
gas_limit: UPPER_CEILING.into(),
|
||||||
};
|
};
|
||||||
// that's just a copy of the state.
|
// that's just a copy of the state.
|
||||||
let mut original_state = self.state_at(block).ok_or(CallError::StatePruned)?;
|
let original_state = self.state_at(block).ok_or(CallError::StatePruned)?;
|
||||||
let sender = t.sender().map_err(|e| {
|
let sender = t.sender().map_err(|e| {
|
||||||
let message = format!("Transaction malformed: {:?}", e);
|
let message = format!("Transaction malformed: {:?}", e);
|
||||||
ExecutionError::TransactionMalformed(message)
|
ExecutionError::TransactionMalformed(message)
|
||||||
})?;
|
})?;
|
||||||
let balance = original_state.balance(&sender);
|
let balance = original_state.balance(&sender);
|
||||||
let needed_balance = t.value + t.gas * t.gas_price;
|
|
||||||
if balance < needed_balance {
|
|
||||||
// give the sender a sufficient balance
|
|
||||||
original_state.add_balance(&sender, &(needed_balance - balance), CleanupMode::NoEmpty);
|
|
||||||
}
|
|
||||||
let options = TransactOptions { tracing: true, vm_tracing: false, check_nonce: false };
|
let options = TransactOptions { tracing: true, vm_tracing: false, check_nonce: false };
|
||||||
let mut tx = t.clone();
|
let mut tx = t.clone();
|
||||||
|
|
||||||
let mut cond = |gas| {
|
let mut cond = |gas| {
|
||||||
let mut state = original_state.clone();
|
|
||||||
tx.gas = gas;
|
tx.gas = gas;
|
||||||
|
|
||||||
|
let mut state = original_state.clone();
|
||||||
|
let needed_balance = tx.value + tx.gas * tx.gas_price;
|
||||||
|
if balance < needed_balance {
|
||||||
|
// give the sender a sufficient balance
|
||||||
|
state.add_balance(&sender, &(needed_balance - balance), CleanupMode::NoEmpty);
|
||||||
|
}
|
||||||
|
|
||||||
Executive::new(&mut state, &env_info, &*self.engine, &self.factories.vm)
|
Executive::new(&mut state, &env_info, &*self.engine, &self.factories.vm)
|
||||||
.transact(&tx, options.clone())
|
.transact(&tx, options.clone())
|
||||||
.map(|r| r.trace[0].result.succeeded())
|
.map(|r| r.trace[0].result.succeeded())
|
||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut upper = env_info.gas_limit;
|
let mut upper = header.gas_limit();
|
||||||
if !cond(upper) {
|
if !cond(upper) {
|
||||||
// impossible at block gas limit - try `UPPER_CEILING` instead.
|
// impossible at block gas limit - try `UPPER_CEILING` instead.
|
||||||
// TODO: consider raising limit by powers of two.
|
// TODO: consider raising limit by powers of two.
|
||||||
const UPPER_CEILING: u64 = 1_000_000_000_000u64;
|
|
||||||
upper = UPPER_CEILING.into();
|
upper = UPPER_CEILING.into();
|
||||||
if !cond(upper) {
|
if !cond(upper) {
|
||||||
trace!(target: "estimate_gas", "estimate_gas failed with {}", upper);
|
trace!(target: "estimate_gas", "estimate_gas failed with {}", upper);
|
||||||
|
@ -660,7 +660,6 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM> Eth for EthClient<C, SN, S, M, EM> where
|
|||||||
num => take_weak!(self.client).call(&signed, num.into(), Default::default()),
|
num => take_weak!(self.client).call(&signed, num.into(), Default::default()),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
result
|
result
|
||||||
.map(|b| b.output.into())
|
.map(|b| b.output.into())
|
||||||
.map_err(errors::from_call_error)
|
.map_err(errors::from_call_error)
|
||||||
|
Loading…
Reference in New Issue
Block a user