fix(light-rpc): Make light_sync generic (#10238)
* fix(light-rpc): Make `light_sync` generic The motivation behind this change is to easily mock `light-sync` to make it possible to enable `rpc-integration` tests for the light-client. Currently the `rpc's` requires the concrete type `sync::LightSync` which makes it very hard to do so * fix(bad merge)
This commit is contained in:
committed by
Andrew Jones
parent
8b6c5be6a9
commit
751d15e4be
@@ -36,7 +36,9 @@ use light::client::{LightChainClient, LightChainNotify};
|
||||
use light::on_demand::OnDemand;
|
||||
use parity_runtime::Executor;
|
||||
use parking_lot::{RwLock, Mutex};
|
||||
use sync::LightSync;
|
||||
|
||||
use sync::{LightSyncProvider, LightNetworkDispatcher, ManageNetwork};
|
||||
|
||||
use types::encoded;
|
||||
use types::filter::Filter as EthFilter;
|
||||
|
||||
@@ -87,12 +89,15 @@ impl<C> EthPubSubClient<C> {
|
||||
}
|
||||
}
|
||||
|
||||
impl EthPubSubClient<LightFetch> {
|
||||
impl<S> EthPubSubClient<LightFetch<S>>
|
||||
where
|
||||
S: LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static
|
||||
{
|
||||
/// Creates a new `EthPubSubClient` for `LightClient`.
|
||||
pub fn light(
|
||||
client: Arc<LightChainClient>,
|
||||
on_demand: Arc<OnDemand>,
|
||||
sync: Arc<LightSync>,
|
||||
sync: Arc<S>,
|
||||
cache: Arc<Mutex<Cache>>,
|
||||
executor: Executor,
|
||||
gas_price_percentile: usize,
|
||||
@@ -189,7 +194,10 @@ pub trait LightClient: Send + Sync {
|
||||
fn logs(&self, filter: EthFilter) -> BoxFuture<Vec<Log>>;
|
||||
}
|
||||
|
||||
impl LightClient for LightFetch {
|
||||
impl<S> LightClient for LightFetch<S>
|
||||
where
|
||||
S: LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static
|
||||
{
|
||||
fn block_header(&self, id: BlockId) -> Option<encoded::Header> {
|
||||
self.client.block_header(id)
|
||||
}
|
||||
@@ -200,10 +208,7 @@ impl LightClient for LightFetch {
|
||||
}
|
||||
|
||||
impl<C: LightClient> LightChainNotify for ChainNotificationHandler<C> {
|
||||
fn new_headers(
|
||||
&self,
|
||||
enacted: &[H256],
|
||||
) {
|
||||
fn new_headers(&self, enacted: &[H256]) {
|
||||
let headers = enacted
|
||||
.iter()
|
||||
.filter_map(|hash| self.client.block_header(BlockId::Hash(*hash)))
|
||||
|
||||
@@ -32,7 +32,6 @@ use ethereum_types::{U256, Address};
|
||||
use hash::{KECCAK_NULL_RLP, KECCAK_EMPTY_LIST_RLP};
|
||||
use parking_lot::{RwLock, Mutex};
|
||||
use rlp::Rlp;
|
||||
use sync::LightSync;
|
||||
use types::transaction::SignedTransaction;
|
||||
use types::encoded;
|
||||
use types::filter::Filter as EthcoreFilter;
|
||||
@@ -45,19 +44,22 @@ use v1::helpers::deprecated::{self, DeprecationNotice};
|
||||
use v1::helpers::light_fetch::{self, LightFetch};
|
||||
use v1::traits::Eth;
|
||||
use v1::types::{
|
||||
RichBlock, Block, BlockTransactions, BlockNumber, LightBlockNumber, Bytes, SyncStatus, SyncInfo,
|
||||
RichBlock, Block, BlockTransactions, BlockNumber, LightBlockNumber, Bytes,
|
||||
SyncStatus as RpcSyncStatus, SyncInfo as RpcSyncInfo,
|
||||
Transaction, CallRequest, Index, Filter, Log, Receipt, Work, EthAccount,
|
||||
H64 as RpcH64, H256 as RpcH256, H160 as RpcH160, U256 as RpcU256,
|
||||
U64 as RpcU64,
|
||||
};
|
||||
use v1::metadata::Metadata;
|
||||
|
||||
use sync::{LightSyncInfo, LightSyncProvider, LightNetworkDispatcher, ManageNetwork};
|
||||
|
||||
const NO_INVALID_BACK_REFS: &str = "Fails only on invalid back-references; back-references here known to be valid; qed";
|
||||
|
||||
/// Light client `ETH` (and filter) RPC.
|
||||
pub struct EthClient<T> {
|
||||
sync: Arc<LightSync>,
|
||||
client: Arc<T>,
|
||||
pub struct EthClient<C, S: LightSyncProvider + LightNetworkDispatcher + 'static> {
|
||||
sync: Arc<S>,
|
||||
client: Arc<C>,
|
||||
on_demand: Arc<OnDemand>,
|
||||
transaction_queue: Arc<RwLock<TransactionQueue>>,
|
||||
accounts: Arc<Fn() -> Vec<Address> + Send + Sync>,
|
||||
@@ -68,7 +70,10 @@ pub struct EthClient<T> {
|
||||
deprecation_notice: DeprecationNotice,
|
||||
}
|
||||
|
||||
impl<T> Clone for EthClient<T> {
|
||||
impl<C, S> Clone for EthClient<C, S>
|
||||
where
|
||||
S: LightSyncProvider + LightNetworkDispatcher + 'static
|
||||
{
|
||||
fn clone(&self) -> Self {
|
||||
// each instance should have its own poll manager.
|
||||
EthClient {
|
||||
@@ -86,12 +91,16 @@ impl<T> Clone for EthClient<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: LightChainClient + 'static> EthClient<T> {
|
||||
impl<C, S> EthClient<C, S>
|
||||
where
|
||||
C: LightChainClient + 'static,
|
||||
S: LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static
|
||||
{
|
||||
/// Create a new `EthClient` with a handle to the light sync instance, client,
|
||||
/// and on-demand request service, which is assumed to be attached as a handler.
|
||||
pub fn new(
|
||||
sync: Arc<LightSync>,
|
||||
client: Arc<T>,
|
||||
sync: Arc<S>,
|
||||
client: Arc<C>,
|
||||
on_demand: Arc<OnDemand>,
|
||||
transaction_queue: Arc<RwLock<TransactionQueue>>,
|
||||
accounts: Arc<Fn() -> Vec<Address> + Send + Sync>,
|
||||
@@ -114,7 +123,8 @@ impl<T: LightChainClient + 'static> EthClient<T> {
|
||||
}
|
||||
|
||||
/// Create a light data fetcher instance.
|
||||
fn fetcher(&self) -> LightFetch {
|
||||
fn fetcher(&self) -> LightFetch<S>
|
||||
{
|
||||
LightFetch {
|
||||
client: self.client.clone(),
|
||||
on_demand: self.on_demand.clone(),
|
||||
@@ -211,21 +221,25 @@ impl<T: LightChainClient + 'static> EthClient<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: LightChainClient + 'static> Eth for EthClient<T> {
|
||||
impl<C, S> Eth for EthClient<C, S>
|
||||
where
|
||||
C: LightChainClient + 'static,
|
||||
S: LightSyncInfo + LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static
|
||||
{
|
||||
type Metadata = Metadata;
|
||||
|
||||
fn protocol_version(&self) -> Result<String> {
|
||||
Ok(format!("{}", ::light::net::MAX_PROTOCOL_VERSION))
|
||||
}
|
||||
|
||||
fn syncing(&self) -> Result<SyncStatus> {
|
||||
fn syncing(&self) -> Result<RpcSyncStatus> {
|
||||
if self.sync.is_major_importing() {
|
||||
let chain_info = self.client.chain_info();
|
||||
let current_block = U256::from(chain_info.best_block_number);
|
||||
let highest_block = self.sync.highest_block().map(U256::from)
|
||||
.unwrap_or_else(|| current_block);
|
||||
|
||||
Ok(SyncStatus::Info(SyncInfo {
|
||||
Ok(RpcSyncStatus::Info(RpcSyncInfo {
|
||||
starting_block: U256::from(self.sync.start_block()).into(),
|
||||
current_block: current_block.into(),
|
||||
highest_block: highest_block.into(),
|
||||
@@ -233,7 +247,7 @@ impl<T: LightChainClient + 'static> Eth for EthClient<T> {
|
||||
warp_chunks_processed: None,
|
||||
}))
|
||||
} else {
|
||||
Ok(SyncStatus::None)
|
||||
Ok(RpcSyncStatus::None)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -524,7 +538,11 @@ impl<T: LightChainClient + 'static> Eth for EthClient<T> {
|
||||
}
|
||||
|
||||
// This trait implementation triggers a blanked impl of `EthFilter`.
|
||||
impl<T: LightChainClient + 'static> Filterable for EthClient<T> {
|
||||
impl<C, S> Filterable for EthClient<C, S>
|
||||
where
|
||||
C: LightChainClient + 'static,
|
||||
S: LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static
|
||||
{
|
||||
fn best_block_number(&self) -> u64 { self.client.chain_info().best_block_number }
|
||||
|
||||
fn block_hash(&self, id: BlockId) -> Option<::ethereum_types::H256> {
|
||||
|
||||
@@ -23,7 +23,7 @@ use version::version_data;
|
||||
use crypto::DEFAULT_MAC;
|
||||
use ethkey::{crypto::ecies, Brain, Generator};
|
||||
use ethstore::random_phrase;
|
||||
use sync::LightSyncProvider;
|
||||
use sync::{LightSyncInfo, LightSyncProvider, LightNetworkDispatcher, ManageNetwork};
|
||||
use ethcore_logger::RotatingLogger;
|
||||
|
||||
use jsonrpc_core::{Result, BoxFuture};
|
||||
@@ -46,8 +46,8 @@ use v1::types::{
|
||||
use Host;
|
||||
|
||||
/// Parity implementation for light client.
|
||||
pub struct ParityClient {
|
||||
light_dispatch: Arc<LightDispatcher>,
|
||||
pub struct ParityClient<S: LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static> {
|
||||
light_dispatch: Arc<LightDispatcher<S>>,
|
||||
logger: Arc<RotatingLogger>,
|
||||
settings: Arc<NetworkSettings>,
|
||||
signer: Option<Arc<SignerService>>,
|
||||
@@ -55,10 +55,13 @@ pub struct ParityClient {
|
||||
gas_price_percentile: usize,
|
||||
}
|
||||
|
||||
impl ParityClient {
|
||||
impl<S> ParityClient<S>
|
||||
where
|
||||
S: LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static
|
||||
{
|
||||
/// Creates new `ParityClient`.
|
||||
pub fn new(
|
||||
light_dispatch: Arc<LightDispatcher>,
|
||||
light_dispatch: Arc<LightDispatcher<S>>,
|
||||
logger: Arc<RotatingLogger>,
|
||||
settings: Arc<NetworkSettings>,
|
||||
signer: Option<Arc<SignerService>>,
|
||||
@@ -76,7 +79,8 @@ impl ParityClient {
|
||||
}
|
||||
|
||||
/// Create a light blockchain data fetcher.
|
||||
fn fetcher(&self) -> LightFetch {
|
||||
fn fetcher(&self) -> LightFetch<S>
|
||||
{
|
||||
LightFetch {
|
||||
client: self.light_dispatch.client.clone(),
|
||||
on_demand: self.light_dispatch.on_demand.clone(),
|
||||
@@ -87,7 +91,10 @@ impl ParityClient {
|
||||
}
|
||||
}
|
||||
|
||||
impl Parity for ParityClient {
|
||||
impl<S> Parity for ParityClient<S>
|
||||
where
|
||||
S: LightSyncInfo + LightSyncProvider + LightNetworkDispatcher + ManageNetwork + 'static
|
||||
{
|
||||
type Metadata = Metadata;
|
||||
|
||||
fn transactions_limit(&self) -> Result<usize> {
|
||||
@@ -371,7 +378,7 @@ impl Parity for ParityClient {
|
||||
|
||||
fn status(&self) -> Result<()> {
|
||||
let has_peers = self.settings.is_dev_chain || self.light_dispatch.sync.peer_numbers().connected > 0;
|
||||
let is_importing = self.light_dispatch.sync.is_major_importing();
|
||||
let is_importing = (*self.light_dispatch.sync).is_major_importing();
|
||||
|
||||
if has_peers && !is_importing {
|
||||
Ok(())
|
||||
|
||||
Reference in New Issue
Block a user