eth_syncing RPC for light client
This commit is contained in:
parent
a55001ad1d
commit
b96eb45877
@ -245,7 +245,22 @@ impl Eth for EthClient {
|
||||
}
|
||||
|
||||
fn syncing(&self) -> Result<SyncStatus, Error> {
|
||||
rpc_unimplemented!()
|
||||
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.clone());
|
||||
|
||||
Ok(SyncStatus::Info(SyncInfo {
|
||||
starting_block: U256::from(self.sync.start_block()).into(),
|
||||
current_block: current_block.into(),
|
||||
highest_block: highest_block.into(),
|
||||
warp_chunks_amount: None,
|
||||
warp_chunks_processed: None,
|
||||
}))
|
||||
} else {
|
||||
Ok(SyncStatus::None)
|
||||
}
|
||||
}
|
||||
|
||||
fn author(&self, _meta: Self::Metadata) -> BoxFuture<RpcH160, Error> {
|
||||
|
@ -669,6 +669,7 @@ pub struct LightSyncParams<L> {
|
||||
/// Service for light synchronization.
|
||||
pub struct LightSync {
|
||||
proto: Arc<LightProtocol>,
|
||||
sync: Arc<::light_sync::SyncInfo + Sync + Send>,
|
||||
network: NetworkService,
|
||||
subprotocol_name: [u8; 3],
|
||||
network_id: u64,
|
||||
@ -682,7 +683,7 @@ impl LightSync {
|
||||
use light_sync::LightSync as SyncHandler;
|
||||
|
||||
// initialize light protocol handler and attach sync module.
|
||||
let light_proto = {
|
||||
let (sync, light_proto) = {
|
||||
let light_params = LightParams {
|
||||
network_id: params.network_id,
|
||||
flow_params: Default::default(), // or `None`?
|
||||
@ -695,20 +696,21 @@ impl LightSync {
|
||||
};
|
||||
|
||||
let mut light_proto = LightProtocol::new(params.client.clone(), light_params);
|
||||
let sync_handler = try!(SyncHandler::new(params.client.clone()));
|
||||
light_proto.add_handler(Arc::new(sync_handler));
|
||||
let sync_handler = Arc::new(try!(SyncHandler::new(params.client.clone())));
|
||||
light_proto.add_handler(sync_handler.clone());
|
||||
|
||||
for handler in params.handlers {
|
||||
light_proto.add_handler(handler);
|
||||
}
|
||||
|
||||
Arc::new(light_proto)
|
||||
(sync_handler, Arc::new(light_proto))
|
||||
};
|
||||
|
||||
let service = try!(NetworkService::new(params.network_config));
|
||||
|
||||
Ok(LightSync {
|
||||
proto: light_proto,
|
||||
sync: sync,
|
||||
network: service,
|
||||
subprotocol_name: params.subprotocol_name,
|
||||
network_id: params.network_id,
|
||||
@ -726,6 +728,12 @@ impl LightSync {
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::ops::Deref for LightSync {
|
||||
type Target = ::light_sync::SyncInfo;
|
||||
|
||||
fn deref(&self) -> &Self::Target { &*self.sync }
|
||||
}
|
||||
|
||||
impl ManageNetwork for LightSync {
|
||||
fn accept_unreserved_peers(&self) {
|
||||
self.network.set_non_reserved_mode(NonReservedPeerMode::Accept);
|
||||
|
@ -206,6 +206,7 @@ impl<'a> ResponseContext for ResponseCtx<'a> {
|
||||
|
||||
/// Light client synchronization manager. See module docs for more details.
|
||||
pub struct LightSync<L: AsLightClient> {
|
||||
start_block_number: u64,
|
||||
best_seen: Mutex<Option<ChainInfo>>, // best seen block on the network.
|
||||
peers: RwLock<HashMap<PeerId, Mutex<Peer>>>, // peers which are relevant to synchronization.
|
||||
client: Arc<L>,
|
||||
@ -525,6 +526,7 @@ impl<L: AsLightClient> LightSync<L> {
|
||||
/// so it can act on events.
|
||||
pub fn new(client: Arc<L>) -> Result<Self, ::std::io::Error> {
|
||||
Ok(LightSync {
|
||||
start_block_number: client.as_light_client().chain_info().best_block_number,
|
||||
best_seen: Mutex::new(None),
|
||||
peers: RwLock::new(HashMap::new()),
|
||||
client: client,
|
||||
@ -533,3 +535,38 @@ impl<L: AsLightClient> LightSync<L> {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Trait for erasing the type of a light sync object and exposing read-only methods.
|
||||
pub trait SyncInfo {
|
||||
/// Get the highest block advertised on the network.
|
||||
fn highest_block(&self) -> Option<u64>;
|
||||
|
||||
/// Get the block number at the time of sync start.
|
||||
fn start_block(&self) -> u64;
|
||||
|
||||
/// Whether major sync is underway.
|
||||
fn is_major_importing(&self) -> bool;
|
||||
}
|
||||
|
||||
impl<L: AsLightClient> SyncInfo for LightSync<L> {
|
||||
fn highest_block(&self) -> Option<u64> {
|
||||
self.best_seen.lock().as_ref().map(|x| x.head_num)
|
||||
}
|
||||
|
||||
fn start_block(&self) -> u64 {
|
||||
self.start_block_number
|
||||
}
|
||||
|
||||
fn is_major_importing(&self) -> bool {
|
||||
const EMPTY_QUEUE: usize = 3;
|
||||
|
||||
if self.client.as_light_client().queue_info().unverified_queue_size > EMPTY_QUEUE {
|
||||
return true;
|
||||
}
|
||||
|
||||
match *self.state.lock() {
|
||||
SyncState::Idle => false,
|
||||
_ => true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user