diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index b8541470b..577829d45 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -25,6 +25,7 @@ use blockchain::{BlockReceipts, BlockChain, BlockChainDB, BlockProvider, TreeRou use bytes::Bytes; use call_contract::{CallContract, RegistryInfo}; use ethcore_miner::pool::VerifiedTransaction; +use ethcore_miner::service_transaction_checker::ServiceTransactionChecker; use ethereum_types::{H256, Address, U256}; use evm::Schedule; use hash::keccak; @@ -2156,11 +2157,16 @@ impl BlockChainClient for Client { fn transact_contract(&self, address: Address, data: Bytes) -> Result<(), transaction::Error> { let authoring_params = self.importer.miner.authoring_params(); + let service_transaction_checker = ServiceTransactionChecker::default(); + let gas_price = match service_transaction_checker.check_address(self, authoring_params.author) { + Ok(true) => U256::zero(), + _ => self.importer.miner.sensible_gas_price(), + }; let transaction = transaction::Transaction { nonce: self.latest_nonce(&authoring_params.author), action: Action::Call(address), gas: self.importer.miner.sensible_gas_limit(), - gas_price: self.importer.miner.sensible_gas_price(), + gas_price, value: U256::zero(), data: data, }; diff --git a/miner/src/service_transaction_checker.rs b/miner/src/service_transaction_checker.rs index 17776f156..c9b3b4b23 100644 --- a/miner/src/service_transaction_checker.rs +++ b/miner/src/service_transaction_checker.rs @@ -20,6 +20,7 @@ use call_contract::{CallContract, RegistryInfo}; use types::ids::BlockId; use types::transaction::SignedTransaction; use ethabi::FunctionOutputDecoder; +use ethereum_types::Address; use_contract!(service_transaction, "res/contracts/service_transaction.json"); @@ -30,23 +31,24 @@ const SERVICE_TRANSACTION_CONTRACT_REGISTRY_NAME: &'static str = "service_transa pub struct ServiceTransactionChecker; impl ServiceTransactionChecker { - /// Checks if given address is whitelisted to send service transactions. + /// Checks if given address in tx is whitelisted to send service transactions. pub fn check(&self, client: &C, tx: &SignedTransaction) -> Result { let sender = tx.sender(); - let hash = tx.hash(); - // Skip checking the contract if the transaction does not have zero gas price if !tx.gas_price.is_zero() { return Ok(false) } - let address = client.registry_address(SERVICE_TRANSACTION_CONTRACT_REGISTRY_NAME.to_owned(), BlockId::Latest) + self.check_address(client, sender) + } + + /// Checks if given address is whitelisted to send service transactions. + pub fn check_address(&self, client: &C, sender: Address) -> Result { + let contract_address = client.registry_address(SERVICE_TRANSACTION_CONTRACT_REGISTRY_NAME.to_owned(), BlockId::Latest) .ok_or_else(|| "contract is not configured")?; - - trace!(target: "txqueue", "[{:?}] Checking service transaction checker contract from {}", hash, sender); - + trace!(target: "txqueue", "Checking service transaction checker contract from {}", sender); let (data, decoder) = service_transaction::functions::certified::call(sender); - let value = client.call_contract(BlockId::Latest, address, data)?; + let value = client.call_contract(BlockId::Latest, contract_address, data)?; decoder.decode(&value).map_err(|e| e.to_string()) } } diff --git a/rpc/src/v1/impls/personal.rs b/rpc/src/v1/impls/personal.rs index 35a304df6..3bae576c0 100644 --- a/rpc/src/v1/impls/personal.rs +++ b/rpc/src/v1/impls/personal.rs @@ -20,8 +20,8 @@ use std::time::Duration; use bytes::Bytes; use ethcore::account_provider::AccountProvider; -use types::transaction::PendingTransaction; -use types::transaction::SignedTransaction; + +use types::transaction::{PendingTransaction, SignedTransaction}; use ethereum_types::{H520, U128, Address}; use ethkey::{public_to_address, recover, Signature};