Calculate gas for deployment transaction (#9840)

* Calculate gas for deployment transaction

* Space fixed

* ethcore: style fix in public_creation_transaction
This commit is contained in:
Anton Gavrilov 2018-11-28 13:14:40 +01:00 committed by Afri Schoedon
parent 5e9dc185a5
commit 7f5e6b3a0a

View File

@ -82,7 +82,8 @@ use ethcore::executed::{Executed};
use transaction::{SignedTransaction, Transaction, Action, UnverifiedTransaction}; use transaction::{SignedTransaction, Transaction, Action, UnverifiedTransaction};
use ethcore::{contract_address as ethcore_contract_address}; use ethcore::{contract_address as ethcore_contract_address};
use ethcore::client::{ use ethcore::client::{
Client, ChainNotify, ChainRoute, ChainMessageType, ClientIoMessage, BlockId, CallContract Client, ChainNotify, ChainRoute, ChainMessageType, ClientIoMessage, BlockId,
CallContract, Call, BlockInfo
}; };
use ethcore::account_provider::AccountProvider; use ethcore::account_provider::AccountProvider;
use ethcore::miner::{self, Miner, MinerService, pool_client::NonceCache}; use ethcore::miner::{self, Miner, MinerService, pool_client::NonceCache};
@ -550,19 +551,34 @@ impl Provider where {
let state = self.client.state_at(block).ok_or(ErrorKind::StatePruned)?; let state = self.client.state_at(block).ok_or(ErrorKind::StatePruned)?;
let nonce = state.nonce(&sender)?; let nonce = state.nonce(&sender)?;
let executed = self.execute_private(source, TransactOptions::with_no_tracing(), block)?; let executed = self.execute_private(source, TransactOptions::with_no_tracing(), block)?;
let gas: u64 = 650000 + let header = self.client.block_header(block)
validators.len() as u64 * 30000 + .ok_or(ErrorKind::StatePruned)
executed.code.as_ref().map_or(0, |c| c.len() as u64) * 8000 + .and_then(|h| h.decode().map_err(|_| ErrorKind::StateIncorrect).into())?;
executed.state.len() as u64 * 8000; let (executed_code, executed_state) = (executed.code.unwrap_or_default(), executed.state);
Ok((Transaction { let tx_data = Self::generate_constructor(validators, executed_code.clone(), executed_state.clone());
let mut tx = Transaction {
nonce: nonce, nonce: nonce,
action: Action::Create, action: Action::Create,
gas: gas.into(), gas: u64::max_value().into(),
gas_price: gas_price, gas_price: gas_price,
value: source.value, value: source.value,
data: Self::generate_constructor(validators, executed.code.unwrap_or_default(), executed.state) data: tx_data,
}, };
executed.contract_address)) tx.gas = match self.client.estimate_gas(&tx.clone().fake_sign(sender), &state, &header) {
Ok(estimated_gas) => estimated_gas,
Err(_) => self.estimate_tx_gas(validators, &executed_code, &executed_state, &[]),
};
Ok((tx, executed.contract_address))
}
fn estimate_tx_gas(&self, validators: &[Address], code: &Bytes, state: &Bytes, signatures: &[Signature]) -> U256 {
let default_gas = 650000 +
validators.len() as u64 * 30000 +
code.len() as u64 * 8000 +
signatures.len() as u64 * 50000 +
state.len() as u64 * 8000;
default_gas.into()
} }
/// Create encrypted public contract deployment transaction. Returns updated encrypted state. /// Create encrypted public contract deployment transaction. Returns updated encrypted state.
@ -576,7 +592,7 @@ impl Provider where {
/// Create encrypted public transaction from private transaction. /// Create encrypted public transaction from private transaction.
pub fn public_transaction(&self, state: Bytes, source: &SignedTransaction, signatures: &[Signature], nonce: U256, gas_price: U256) -> Result<Transaction, Error> { pub fn public_transaction(&self, state: Bytes, source: &SignedTransaction, signatures: &[Signature], nonce: U256, gas_price: U256) -> Result<Transaction, Error> {
let gas: u64 = 650000 + state.len() as u64 * 8000 + signatures.len() as u64 * 50000; let gas = self.estimate_tx_gas(&[], &Vec::new(), &state, signatures);
Ok(Transaction { Ok(Transaction {
nonce: nonce, nonce: nonce,
action: source.action.clone(), action: source.action.clone(),