light: broadcast status updates to peers
This commit is contained in:
		
							parent
							
								
									6f5f1f5e26
								
							
						
					
					
						commit
						e7ce8c9558
					
				@ -27,7 +27,7 @@ use network::{NetworkProtocolHandler, NetworkContext, NetworkError, PeerId};
 | 
				
			|||||||
use rlp::{RlpStream, Stream, UntrustedRlp, View};
 | 
					use rlp::{RlpStream, Stream, UntrustedRlp, View};
 | 
				
			||||||
use util::hash::H256;
 | 
					use util::hash::H256;
 | 
				
			||||||
use util::{Bytes, Mutex, RwLock, U256};
 | 
					use util::{Bytes, Mutex, RwLock, U256};
 | 
				
			||||||
use time::SteadyTime;
 | 
					use time::{Duration, SteadyTime};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use std::collections::HashMap;
 | 
					use std::collections::HashMap;
 | 
				
			||||||
use std::sync::Arc;
 | 
					use std::sync::Arc;
 | 
				
			||||||
@ -54,6 +54,9 @@ pub use self::status::{Status, Capabilities, Announcement};
 | 
				
			|||||||
const TIMEOUT: TimerToken = 0;
 | 
					const TIMEOUT: TimerToken = 0;
 | 
				
			||||||
const TIMEOUT_INTERVAL_MS: u64 = 1000;
 | 
					const TIMEOUT_INTERVAL_MS: u64 = 1000;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// minimum interval between updates.
 | 
				
			||||||
 | 
					const UPDATE_INTERVAL_MS: i64 = 5000;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Supported protocol versions.
 | 
					// Supported protocol versions.
 | 
				
			||||||
pub const PROTOCOL_VERSIONS: &'static [u8] = &[1];
 | 
					pub const PROTOCOL_VERSIONS: &'static [u8] = &[1];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -107,6 +110,7 @@ pub struct ReqId(usize);
 | 
				
			|||||||
// may not have received one for.
 | 
					// may not have received one for.
 | 
				
			||||||
struct PendingPeer {
 | 
					struct PendingPeer {
 | 
				
			||||||
	sent_head: H256,
 | 
						sent_head: H256,
 | 
				
			||||||
 | 
						last_update: SteadyTime,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// data about each peer.
 | 
					// data about each peer.
 | 
				
			||||||
@ -117,6 +121,7 @@ struct Peer {
 | 
				
			|||||||
	capabilities: Capabilities,
 | 
						capabilities: Capabilities,
 | 
				
			||||||
	remote_flow: FlowParams,
 | 
						remote_flow: FlowParams,
 | 
				
			||||||
	sent_head: H256, // last head we've given them.
 | 
						sent_head: H256, // last head we've given them.
 | 
				
			||||||
 | 
						last_update: SteadyTime,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl Peer {
 | 
					impl Peer {
 | 
				
			||||||
@ -293,6 +298,7 @@ impl LightProtocol {
 | 
				
			|||||||
	/// The announcement is expected to be valid.
 | 
						/// The announcement is expected to be valid.
 | 
				
			||||||
	pub fn make_announcement(&self, io: &IoContext, mut announcement: Announcement) {
 | 
						pub fn make_announcement(&self, io: &IoContext, mut announcement: Announcement) {
 | 
				
			||||||
		let mut reorgs_map = HashMap::new();
 | 
							let mut reorgs_map = HashMap::new();
 | 
				
			||||||
 | 
							let now = SteadyTime::now();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// update stored capabilities
 | 
							// update stored capabilities
 | 
				
			||||||
		self.capabilities.write().update_from(&announcement);
 | 
							self.capabilities.write().update_from(&announcement);
 | 
				
			||||||
@ -300,6 +306,17 @@ impl LightProtocol {
 | 
				
			|||||||
		// calculate reorg info and send packets
 | 
							// calculate reorg info and send packets
 | 
				
			||||||
		for (peer_id, peer_info) in self.peers.read().iter() {
 | 
							for (peer_id, peer_info) in self.peers.read().iter() {
 | 
				
			||||||
			let mut peer_info = peer_info.lock();
 | 
								let mut peer_info = peer_info.lock();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// TODO: "urgent" announcements like new blocks?
 | 
				
			||||||
 | 
								// the timer approach will skip 1 (possibly 2) in rare occasions.
 | 
				
			||||||
 | 
								if peer_info.sent_head == announcement.head_hash || 
 | 
				
			||||||
 | 
									peer_info.status.head_num >= announcement.head_num  ||
 | 
				
			||||||
 | 
									now - peer_info.last_update < Duration::milliseconds(UPDATE_INTERVAL_MS) {
 | 
				
			||||||
 | 
									continue 
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								peer_info.last_update = now;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			let reorg_depth = reorgs_map.entry(peer_info.sent_head)
 | 
								let reorg_depth = reorgs_map.entry(peer_info.sent_head)
 | 
				
			||||||
				.or_insert_with(|| {
 | 
									.or_insert_with(|| {
 | 
				
			||||||
					match self.provider.reorg_depth(&announcement.head_hash, &peer_info.sent_head) {
 | 
										match self.provider.reorg_depth(&announcement.head_hash, &peer_info.sent_head) {
 | 
				
			||||||
@ -496,6 +513,7 @@ impl LightProtocol {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		Ok(PendingPeer {
 | 
							Ok(PendingPeer {
 | 
				
			||||||
			sent_head: chain_info.best_block_hash,
 | 
								sent_head: chain_info.best_block_hash,
 | 
				
			||||||
 | 
								last_update: SteadyTime::now(),
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -523,6 +541,7 @@ impl LightProtocol {
 | 
				
			|||||||
			capabilities: capabilities.clone(),
 | 
								capabilities: capabilities.clone(),
 | 
				
			||||||
			remote_flow: flow_params,
 | 
								remote_flow: flow_params,
 | 
				
			||||||
			sent_head: pending.sent_head,
 | 
								sent_head: pending.sent_head,
 | 
				
			||||||
 | 
								last_update: pending.last_update,
 | 
				
			||||||
		}));
 | 
							}));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for handler in &self.handlers {
 | 
							for handler in &self.handlers {
 | 
				
			||||||
 | 
				
			|||||||
@ -279,6 +279,8 @@ impl ChainNotify for EthSync {
 | 
				
			|||||||
		sealed: Vec<H256>,
 | 
							sealed: Vec<H256>,
 | 
				
			||||||
		_duration: u64)
 | 
							_duration: u64)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
 | 
							use light::net::Announcement;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		self.network.with_context(self.subprotocol_name, |context| {
 | 
							self.network.with_context(self.subprotocol_name, |context| {
 | 
				
			||||||
			let mut sync_io = NetSyncIo::new(context, &*self.sync_handler.chain, &*self.sync_handler.snapshot_service, &self.sync_handler.overlay);
 | 
								let mut sync_io = NetSyncIo::new(context, &*self.sync_handler.chain, &*self.sync_handler.snapshot_service, &self.sync_handler.overlay);
 | 
				
			||||||
			self.sync_handler.sync.write().chain_new_blocks(
 | 
								self.sync_handler.sync.write().chain_new_blocks(
 | 
				
			||||||
@ -289,6 +291,25 @@ impl ChainNotify for EthSync {
 | 
				
			|||||||
				&retracted,
 | 
									&retracted,
 | 
				
			||||||
				&sealed);
 | 
									&sealed);
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							self.network.with_context(self.light_subprotocol_name, |context| {
 | 
				
			||||||
 | 
								let light_proto = match self.light_proto.as_ref() {
 | 
				
			||||||
 | 
									Some(lp) => lp,
 | 
				
			||||||
 | 
									None => return,
 | 
				
			||||||
 | 
								};
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								let chain_info = self.sync_handler.chain.chain_info();
 | 
				
			||||||
 | 
								light_proto.make_announcement(context, Announcement {
 | 
				
			||||||
 | 
									head_hash: chain_info.best_block_hash,
 | 
				
			||||||
 | 
									head_num: chain_info.best_block_number,
 | 
				
			||||||
 | 
									head_td: chain_info.total_difficulty,
 | 
				
			||||||
 | 
									reorg_depth: 0, // recalculated on a per-peer basis.
 | 
				
			||||||
 | 
									serve_headers: false, // these fields consist of _changes_ in capability.
 | 
				
			||||||
 | 
									serve_state_since: None,
 | 
				
			||||||
 | 
									serve_chain_since: None,
 | 
				
			||||||
 | 
									tx_relay: false,
 | 
				
			||||||
 | 
								})
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fn start(&self) {
 | 
						fn start(&self) {
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user