From 09dc41e1f0dcfa93ef4587bbd212b8b16b9a2814 Mon Sep 17 00:00:00 2001 From: Anton Gavrilov Date: Wed, 31 Oct 2018 13:01:36 +0100 Subject: [PATCH 1/3] Calculate gas for deployment transaction --- ethcore/private-tx/src/lib.rs | 38 ++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/ethcore/private-tx/src/lib.rs b/ethcore/private-tx/src/lib.rs index 7b8b24c7cc4..668b42e7a6c 100644 --- a/ethcore/private-tx/src/lib.rs +++ b/ethcore/private-tx/src/lib.rs @@ -82,7 +82,8 @@ use ethcore::executed::{Executed}; use transaction::{SignedTransaction, Transaction, Action, UnverifiedTransaction}; use ethcore::{contract_address as ethcore_contract_address}; 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::miner::{self, Miner, MinerService, pool_client::NonceCache}; @@ -550,21 +551,44 @@ impl Provider where { let state = self.client.state_at(block).ok_or(ErrorKind::StatePruned)?; let nonce = state.nonce(&sender)?; let executed = self.execute_private(source, TransactOptions::with_no_tracing(), block)?; - let gas: u64 = 650000 + - validators.len() as u64 * 30000 + - executed.code.as_ref().map_or(0, |c| c.len() as u64) * 8000 + - executed.state.len() as u64 * 8000; + let header = self.client.block_header(block) + .ok_or(ErrorKind::StatePruned) + .and_then(|h| h.decode().map_err(|_| ErrorKind::StateIncorrect).into())?; + let (executed_code, executed_state) = (executed.code.unwrap_or_default(), executed.state); + let tx_data = Self::generate_constructor(validators, executed_code.clone(), executed_state.clone()); + let gas = match self.client.estimate_gas(&Transaction{ + nonce: nonce, + action: Action::Create, + gas: u64::max_value().into(), + gas_price: gas_price, + value: source.value, + data: tx_data.clone(), + }.fake_sign(sender), + &state, + &header) { + Ok(estimated_gas) => estimated_gas, + Err(_) => self.estimate_tx_gas(validators, &executed_code, &executed_state, &[]), + }; Ok((Transaction { nonce: nonce, action: Action::Create, gas: gas.into(), gas_price: gas_price, value: source.value, - data: Self::generate_constructor(validators, executed.code.unwrap_or_default(), executed.state) + data: tx_data, }, 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. pub fn execute_private_transaction(&self, block: BlockId, source: &SignedTransaction) -> Result { if let Action::Create = source.action { @@ -576,7 +600,7 @@ impl Provider where { /// Create encrypted public transaction from private transaction. pub fn public_transaction(&self, state: Bytes, source: &SignedTransaction, signatures: &[Signature], nonce: U256, gas_price: U256) -> Result { - 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 { nonce: nonce, action: source.action.clone(), From b5e755799e6d046df065dff8245861fc139974d7 Mon Sep 17 00:00:00 2001 From: Anton Gavrilov Date: Wed, 31 Oct 2018 13:32:20 +0100 Subject: [PATCH 2/3] Space fixed --- ethcore/private-tx/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ethcore/private-tx/src/lib.rs b/ethcore/private-tx/src/lib.rs index 668b42e7a6c..e27a2afe213 100644 --- a/ethcore/private-tx/src/lib.rs +++ b/ethcore/private-tx/src/lib.rs @@ -556,7 +556,7 @@ impl Provider where { .and_then(|h| h.decode().map_err(|_| ErrorKind::StateIncorrect).into())?; let (executed_code, executed_state) = (executed.code.unwrap_or_default(), executed.state); let tx_data = Self::generate_constructor(validators, executed_code.clone(), executed_state.clone()); - let gas = match self.client.estimate_gas(&Transaction{ + let gas = match self.client.estimate_gas(&Transaction { nonce: nonce, action: Action::Create, gas: u64::max_value().into(), From d24e31200c8d1cd8efa2baf755facb8d04dbc4d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Tue, 27 Nov 2018 18:35:22 +0000 Subject: [PATCH 3/3] ethcore: style fix in public_creation_transaction --- ethcore/private-tx/src/lib.rs | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/ethcore/private-tx/src/lib.rs b/ethcore/private-tx/src/lib.rs index e27a2afe213..c623504be5b 100644 --- a/ethcore/private-tx/src/lib.rs +++ b/ethcore/private-tx/src/lib.rs @@ -556,28 +556,20 @@ impl Provider where { .and_then(|h| h.decode().map_err(|_| ErrorKind::StateIncorrect).into())?; let (executed_code, executed_state) = (executed.code.unwrap_or_default(), executed.state); let tx_data = Self::generate_constructor(validators, executed_code.clone(), executed_state.clone()); - let gas = match self.client.estimate_gas(&Transaction { + let mut tx = Transaction { nonce: nonce, action: Action::Create, gas: u64::max_value().into(), gas_price: gas_price, value: source.value, - data: tx_data.clone(), - }.fake_sign(sender), - &state, - &header) { + data: tx_data, + }; + 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((Transaction { - nonce: nonce, - action: Action::Create, - gas: gas.into(), - gas_price: gas_price, - value: source.value, - data: tx_data, - }, - executed.contract_address)) + + Ok((tx, executed.contract_address)) } fn estimate_tx_gas(&self, validators: &[Address], code: &Bytes, state: &Bytes, signatures: &[Signature]) -> U256 {