allow optional casting of engine client to full client
This commit is contained in:
parent
ad39446e87
commit
7d1c7a0474
@ -19,9 +19,9 @@
|
|||||||
use std::sync::{Weak, Arc};
|
use std::sync::{Weak, Arc};
|
||||||
|
|
||||||
use ethcore::block_status::BlockStatus;
|
use ethcore::block_status::BlockStatus;
|
||||||
use ethcore::client::{TransactionImportResult, ClientReport, EnvInfo};
|
use ethcore::client::{ClientReport, EnvInfo};
|
||||||
use ethcore::engines::{epoch, Engine, EpochChange, EpochTransition, Proof, Unsure};
|
use ethcore::engines::{epoch, Engine, EpochChange, EpochTransition, Proof, Unsure};
|
||||||
use ethcore::error::{TransactionError, BlockImportError, Error as EthcoreError};
|
use ethcore::error::BlockImportError;
|
||||||
use ethcore::ids::BlockId;
|
use ethcore::ids::BlockId;
|
||||||
use ethcore::header::{BlockNumber, Header};
|
use ethcore::header::{BlockNumber, Header};
|
||||||
use ethcore::verification::queue::{self, HeaderQueue};
|
use ethcore::verification::queue::{self, HeaderQueue};
|
||||||
@ -35,7 +35,6 @@ use bigint::prelude::U256;
|
|||||||
use bigint::hash::H256;
|
use bigint::hash::H256;
|
||||||
use futures::{IntoFuture, Future};
|
use futures::{IntoFuture, Future};
|
||||||
|
|
||||||
use util::Address;
|
|
||||||
use util::kvdb::{KeyValueDB, CompactionProfile};
|
use util::kvdb::{KeyValueDB, CompactionProfile};
|
||||||
|
|
||||||
use self::fetch::ChainDataFetcher;
|
use self::fetch::ChainDataFetcher;
|
||||||
@ -619,17 +618,8 @@ impl<T: ChainDataFetcher> ::ethcore::client::EngineClient for Client<T> {
|
|||||||
Client::chain_info(self)
|
Client::chain_info(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call_contract(&self, _id: BlockId, _address: Address, _data: Vec<u8>) -> Result<Vec<u8>, String> {
|
fn as_full_client(&self) -> Option<&::ethcore::client::BlockChainClient> {
|
||||||
Err("Contract calling not supported by light client".into())
|
None
|
||||||
}
|
|
||||||
|
|
||||||
fn transact_contract(&self, _address: Address, _data: Vec<u8>)
|
|
||||||
-> Result<TransactionImportResult, EthcoreError>
|
|
||||||
{
|
|
||||||
// TODO: these are only really used for misbehavior reporting.
|
|
||||||
// no relevant clients will be running light clients, but maybe
|
|
||||||
// they could be at some point?
|
|
||||||
Err(TransactionError::LimitReached.into())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn block_number(&self, id: BlockId) -> Option<BlockNumber> {
|
fn block_number(&self, id: BlockId) -> Option<BlockNumber> {
|
||||||
|
@ -1960,13 +1960,7 @@ impl super::traits::EngineClient for Client {
|
|||||||
BlockChainClient::chain_info(self)
|
BlockChainClient::chain_info(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call_contract(&self, id: BlockId, address: Address, data: Bytes) -> Result<Bytes, String> {
|
fn as_full_client(&self) -> Option<&BlockChainClient> { Some(self) }
|
||||||
BlockChainClient::call_contract(self, id, address, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn transact_contract(&self, address: Address, data: Bytes) -> Result<TransactionImportResult, EthcoreError> {
|
|
||||||
BlockChainClient::transact_contract(self, address, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn block_number(&self, id: BlockId) -> Option<BlockNumber> {
|
fn block_number(&self, id: BlockId) -> Option<BlockNumber> {
|
||||||
BlockChainClient::block_number(self, id)
|
BlockChainClient::block_number(self, id)
|
||||||
|
@ -828,13 +828,7 @@ impl super::traits::EngineClient for TestBlockChainClient {
|
|||||||
BlockChainClient::chain_info(self)
|
BlockChainClient::chain_info(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call_contract(&self, id: BlockId, address: Address, data: Bytes) -> Result<Bytes, String> {
|
fn as_full_client(&self) -> Option<&BlockChainClient> { Some(self) }
|
||||||
BlockChainClient::call_contract(self, id, address, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn transact_contract(&self, address: Address, data: Bytes) -> Result<TransactionImportResult, EthcoreError> {
|
|
||||||
BlockChainClient::transact_contract(self, address, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn block_number(&self, id: BlockId) -> Option<BlockNumber> {
|
fn block_number(&self, id: BlockId) -> Option<BlockNumber> {
|
||||||
BlockChainClient::block_number(self, id)
|
BlockChainClient::block_number(self, id)
|
||||||
|
@ -337,12 +337,10 @@ pub trait EngineClient: Sync + Send {
|
|||||||
/// Get block chain info.
|
/// Get block chain info.
|
||||||
fn chain_info(&self) -> BlockChainInfo;
|
fn chain_info(&self) -> BlockChainInfo;
|
||||||
|
|
||||||
/// Like `call`, but with various defaults. Designed to be used for calling contracts.
|
/// Attempt to cast the engine client to a full client.
|
||||||
fn call_contract(&self, id: BlockId, address: Address, data: Bytes) -> Result<Bytes, String>;
|
fn as_full_client(&self) -> Option<&BlockChainClient>;
|
||||||
|
|
||||||
/// Import a transaction: used for misbehaviour reporting.
|
|
||||||
fn transact_contract(&self, address: Address, data: Bytes) -> Result<TransactionImportResult, EthcoreError>;
|
|
||||||
|
|
||||||
|
/// Get a block number by ID.
|
||||||
fn block_number(&self, id: BlockId) -> Option<BlockNumber>;
|
fn block_number(&self, id: BlockId) -> Option<BlockNumber>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ use bigint::hash::{H256, H520};
|
|||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use util::*;
|
use util::*;
|
||||||
use unexpected::{OutOfBounds, Mismatch};
|
use unexpected::{OutOfBounds, Mismatch};
|
||||||
use client::{Client, EngineClient};
|
use client::EngineClient;
|
||||||
use error::{Error, BlockError};
|
use error::{Error, BlockError};
|
||||||
use header::{Header, BlockNumber};
|
use header::{Header, BlockNumber};
|
||||||
use builtin::Builtin;
|
use builtin::Builtin;
|
||||||
|
@ -58,7 +58,13 @@ impl ValidatorContract {
|
|||||||
Box::new(move |a, d| client.as_ref()
|
Box::new(move |a, d| client.as_ref()
|
||||||
.and_then(Weak::upgrade)
|
.and_then(Weak::upgrade)
|
||||||
.ok_or("No client!".into())
|
.ok_or("No client!".into())
|
||||||
.and_then(|c| c.transact_contract(a, d).map_err(|e| format!("Transaction import error: {}", e)))
|
.and_then(|c| {
|
||||||
|
match c.as_full_client() {
|
||||||
|
Some(c) => c.transact_contract(a, d)
|
||||||
|
.map_err(|e| format!("Transaction import error: {}", e)),
|
||||||
|
None => Err("No full client!".into()),
|
||||||
|
}
|
||||||
|
})
|
||||||
.map(|_| Default::default()))
|
.map(|_| Default::default()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -311,7 +311,12 @@ impl ValidatorSet for ValidatorSafeContract {
|
|||||||
Box::new(move |addr, data| client.as_ref()
|
Box::new(move |addr, data| client.as_ref()
|
||||||
.and_then(Weak::upgrade)
|
.and_then(Weak::upgrade)
|
||||||
.ok_or("No client!".into())
|
.ok_or("No client!".into())
|
||||||
.and_then(|c| c.call_contract(id, addr, data))
|
.and_then(|c| {
|
||||||
|
match c.as_full_client() {
|
||||||
|
Some(c) => c.call_contract(id, addr, data),
|
||||||
|
None => Err("No full client!".into()),
|
||||||
|
}
|
||||||
|
})
|
||||||
.map(|out| (out, Vec::new()))) // generate no proofs in general
|
.map(|out| (out, Vec::new()))) // generate no proofs in general
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ use rlp::{self, UntrustedRlp};
|
|||||||
use vm::LastHashes;
|
use vm::LastHashes;
|
||||||
use semantic_version::SemanticVersion;
|
use semantic_version::SemanticVersion;
|
||||||
use tx_filter::{TransactionFilter};
|
use tx_filter::{TransactionFilter};
|
||||||
use client::{Client, BlockChainClient};
|
use client::EngineClient;
|
||||||
|
|
||||||
/// Parity tries to round block.gas_limit to multiple of this constant
|
/// Parity tries to round block.gas_limit to multiple of this constant
|
||||||
pub const PARITY_GAS_LIMIT_DETERMINANT: U256 = U256([37, 0, 0, 0]);
|
pub const PARITY_GAS_LIMIT_DETERMINANT: U256 = U256([37, 0, 0, 0]);
|
||||||
@ -460,9 +460,9 @@ impl Engine for Arc<Ethash> {
|
|||||||
Some(Box::new(::snapshot::PowSnapshot::new(SNAPSHOT_BLOCKS, MAX_SNAPSHOT_BLOCKS)))
|
Some(Box::new(::snapshot::PowSnapshot::new(SNAPSHOT_BLOCKS, MAX_SNAPSHOT_BLOCKS)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn register_client(&self, client: Weak<Client>) {
|
fn register_client(&self, client: Weak<EngineClient>) {
|
||||||
if let Some(ref filter) = self.tx_filter {
|
if let Some(ref filter) = self.tx_filter {
|
||||||
filter.register_client(client as Weak<BlockChainClient>);
|
filter.register_client(client);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,9 +19,10 @@
|
|||||||
use std::sync::Weak;
|
use std::sync::Weak;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::collections::hash_map::Entry;
|
use std::collections::hash_map::Entry;
|
||||||
|
use bigint::hash::H256;
|
||||||
use native_contracts::TransactAcl as Contract;
|
use native_contracts::TransactAcl as Contract;
|
||||||
use client::{BlockChainClient, BlockId, ChainNotify};
|
use client::{EngineClient, BlockId, ChainNotify};
|
||||||
use util::{Address, H256, Bytes};
|
use util::{Address, Bytes};
|
||||||
use parking_lot::{Mutex, RwLock};
|
use parking_lot::{Mutex, RwLock};
|
||||||
use futures::{self, Future};
|
use futures::{self, Future};
|
||||||
use spec::CommonParams;
|
use spec::CommonParams;
|
||||||
@ -42,7 +43,7 @@ mod tx_permissions {
|
|||||||
/// Connection filter that uses a contract to manage permissions.
|
/// Connection filter that uses a contract to manage permissions.
|
||||||
pub struct TransactionFilter {
|
pub struct TransactionFilter {
|
||||||
contract: Mutex<Option<Contract>>,
|
contract: Mutex<Option<Contract>>,
|
||||||
client: RwLock<Option<Weak<BlockChainClient>>>,
|
client: RwLock<Option<Weak<EngineClient>>>,
|
||||||
contract_address: Address,
|
contract_address: Address,
|
||||||
permission_cache: Mutex<HashMap<(H256, Address), u32>>,
|
permission_cache: Mutex<HashMap<(H256, Address), u32>>,
|
||||||
}
|
}
|
||||||
@ -66,7 +67,7 @@ impl TransactionFilter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Set client reference to be used for contract call.
|
/// Set client reference to be used for contract call.
|
||||||
pub fn register_client(&self, client: Weak<BlockChainClient>) {
|
pub fn register_client(&self, client: Weak<EngineClient>) {
|
||||||
*self.client.write() = Some(client);
|
*self.client.write() = Some(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,6 +79,12 @@ impl TransactionFilter {
|
|||||||
Some(client) => client,
|
Some(client) => client,
|
||||||
_ => return false,
|
_ => return false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let client = match client.as_full_client() {
|
||||||
|
Some(client) => client,
|
||||||
|
_ => return false, // TODO: how to handle verification for light clients?
|
||||||
|
};
|
||||||
|
|
||||||
let tx_type = match transaction.action {
|
let tx_type = match transaction.action {
|
||||||
Action::Create => tx_permissions::CREATE,
|
Action::Create => tx_permissions::CREATE,
|
||||||
Action::Call(address) => if client.code_hash(&address, BlockId::Hash(*parent_hash)).map_or(false, |c| c != KECCAK_EMPTY) {
|
Action::Call(address) => if client.code_hash(&address, BlockId::Hash(*parent_hash)).map_or(false, |c| c != KECCAK_EMPTY) {
|
||||||
|
Loading…
Reference in New Issue
Block a user