Fix balance increase.

This commit is contained in:
Tomasz Drwięga 2017-08-15 10:07:00 +02:00
parent 60f6a3fed3
commit a34bea1dad
No known key found for this signature in database
GPG Key ID: D066F497E62CAF66
3 changed files with 5 additions and 15 deletions

View File

@ -1112,20 +1112,9 @@ impl Client {
}.fake_sign(from) }.fake_sign(from)
} }
fn do_call(&self, env_info: &EnvInfo, state: &mut State<StateDB>, increase_balance: bool, t: &SignedTransaction, analytics: CallAnalytics) -> Result<Executed, CallError> { fn do_call(&self, env_info: &EnvInfo, state: &mut State<StateDB>, t: &SignedTransaction, analytics: CallAnalytics) -> Result<Executed, CallError> {
let original_state = if analytics.state_diffing { Some(state.clone()) } else { None }; let original_state = if analytics.state_diffing { Some(state.clone()) } else { None };
// give the sender a sufficient balance (if calling in pending block)
if increase_balance {
let sender = t.sender();
let balance = state.balance(&sender).map_err(ExecutionError::from)?;
let needed_balance = t.value + t.gas * t.gas_price;
if balance < needed_balance {
state.add_balance(&sender, &(needed_balance - balance), state::CleanupMode::NoEmpty)
.map_err(ExecutionError::from)?;
}
}
let options = TransactOptions { tracing: analytics.transaction_tracing, vm_tracing: analytics.vm_tracing, check_nonce: false }; let options = TransactOptions { tracing: analytics.transaction_tracing, vm_tracing: analytics.vm_tracing, check_nonce: false };
let mut ret = Executive::new(state, env_info, &*self.engine).transact_virtual(t, options)?; let mut ret = Executive::new(state, env_info, &*self.engine).transact_virtual(t, options)?;
@ -1167,7 +1156,7 @@ impl BlockChainClient for Client {
// that's just a copy of the state. // that's just a copy of the state.
let mut state = self.state_at(block).ok_or(CallError::StatePruned)?; let mut state = self.state_at(block).ok_or(CallError::StatePruned)?;
self.do_call(&env_info, &mut state, block == BlockId::Pending, transaction, analytics) self.do_call(&env_info, &mut state, transaction, analytics)
} }
fn call_many(&self, transactions: &[(SignedTransaction, CallAnalytics)], block: BlockId) -> Result<Vec<Executed>, CallError> { fn call_many(&self, transactions: &[(SignedTransaction, CallAnalytics)], block: BlockId) -> Result<Vec<Executed>, CallError> {
@ -1179,7 +1168,7 @@ impl BlockChainClient for Client {
let mut results = Vec::with_capacity(transactions.len()); let mut results = Vec::with_capacity(transactions.len());
for &(ref t, analytics) in transactions { for &(ref t, analytics) in transactions {
let ret = self.do_call(&env_info, &mut state, block == BlockId::Pending, t, analytics)?; let ret = self.do_call(&env_info, &mut state, t, analytics)?;
env_info.gas_used = ret.cumulative_gas_used; env_info.gas_used = ret.cumulative_gas_used;
results.push(ret); results.push(ret);
} }

View File

@ -157,7 +157,7 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> {
pub fn transact_virtual(&'a mut self, t: &SignedTransaction, options: TransactOptions) -> Result<Executed, ExecutionError> { pub fn transact_virtual(&'a mut self, t: &SignedTransaction, options: TransactOptions) -> Result<Executed, ExecutionError> {
let sender = t.sender(); let sender = t.sender();
let balance = self.state.balance(&sender)?; let balance = self.state.balance(&sender)?;
let needed_balance = t.value + t.gas * t.gas_price; let needed_balance = t.value.saturating_add(t.gas.saturating_mul(t.gas_price));
if balance < needed_balance { if balance < needed_balance {
// give the sender a sufficient balance // give the sender a sufficient balance
self.state.add_balance(&sender, &(needed_balance - balance), CleanupMode::NoEmpty)?; self.state.add_balance(&sender, &(needed_balance - balance), CleanupMode::NoEmpty)?;

View File

@ -34,6 +34,7 @@ pub fn sign_call<B: MiningBlockChainClient, M: MinerService>(
Ok(Transaction { Ok(Transaction {
nonce: request.nonce.unwrap_or_else(|| client.latest_nonce(&from)), nonce: request.nonce.unwrap_or_else(|| client.latest_nonce(&from)),
action: request.to.map_or(Action::Create, Action::Call), action: request.to.map_or(Action::Create, Action::Call),
// gas: request.gas.unwrap_or(U256::one() << 100),
gas: request.gas.unwrap_or(U256::max_value()), gas: request.gas.unwrap_or(U256::max_value()),
gas_price: request.gas_price.unwrap_or_else(|| default_gas_price(&**client, &**miner)), gas_price: request.gas_price.unwrap_or_else(|| default_gas_price(&**client, &**miner)),
value: request.value.unwrap_or(0.into()), value: request.value.unwrap_or(0.into()),