trigger event handlers, update capabilities
This commit is contained in:
		
							parent
							
								
									3fabad5c0f
								
							
						
					
					
						commit
						63aa54cfc7
					
				@ -1,40 +0,0 @@
 | 
				
			|||||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
 | 
					 | 
				
			||||||
// This file is part of Parity.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Parity is free software: you can redistribute it and/or modify
 | 
					 | 
				
			||||||
// it under the terms of the GNU General Public License as published by
 | 
					 | 
				
			||||||
// the Free Software Foundation, either version 3 of the License, or
 | 
					 | 
				
			||||||
// (at your option) any later version.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Parity is distributed in the hope that it will be useful,
 | 
					 | 
				
			||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					 | 
				
			||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					 | 
				
			||||||
// GNU General Public License for more details.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// You should have received a copy of the GNU General Public License
 | 
					 | 
				
			||||||
// along with Parity.  If not, see <http://www.gnu.org/licenses/>.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//! Network events and event listeners.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use network::PeerId;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use super::{Status, Capabilities, Announcement};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use transaction::SignedTransaction;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Peer connected
 | 
					 | 
				
			||||||
pub struct Connect(PeerId, Status, Capabilities);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Peer disconnected
 | 
					 | 
				
			||||||
pub struct Disconnect(PeerId);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Peer announces new capabilities.
 | 
					 | 
				
			||||||
pub struct Announcement(PeerId, Announcement);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Transactions to be relayed.
 | 
					 | 
				
			||||||
pub struct RelayTransactions(Vec<SignedTransaction>);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// An LES event handler.
 | 
					 | 
				
			||||||
pub trait Handler {
 | 
					 | 
				
			||||||
	fn on_connect(&self, _event: Connect);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -30,16 +30,15 @@ use std::sync::atomic::AtomicUsize;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use light::provider::Provider;
 | 
					use light::provider::Provider;
 | 
				
			||||||
use light::request::{self, Request};
 | 
					use light::request::{self, Request};
 | 
				
			||||||
 | 
					use transaction::SignedTransaction;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use self::buffer_flow::{Buffer, FlowParams};
 | 
					use self::buffer_flow::{Buffer, FlowParams};
 | 
				
			||||||
use self::error::{Error, Punishment};
 | 
					use self::error::{Error, Punishment};
 | 
				
			||||||
use self::status::{Status, Capabilities};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
mod buffer_flow;
 | 
					mod buffer_flow;
 | 
				
			||||||
mod error;
 | 
					mod error;
 | 
				
			||||||
mod status;
 | 
					mod status;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub mod event;
 | 
					 | 
				
			||||||
pub use self::status::{Status, Capabilities, Announcement};
 | 
					pub use self::status::{Status, Capabilities, Announcement};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const TIMEOUT: TimerToken = 0;
 | 
					const TIMEOUT: TimerToken = 0;
 | 
				
			||||||
@ -126,6 +125,18 @@ impl Peer {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// An LES event handler.
 | 
				
			||||||
 | 
					pub trait Handler: Send + Sync {
 | 
				
			||||||
 | 
						/// Called when a peer connects.
 | 
				
			||||||
 | 
						fn on_connect(&self, _id: PeerId, _status: &Status, _capabilities: &Capabilities) { }
 | 
				
			||||||
 | 
						/// Called when a peer disconnects
 | 
				
			||||||
 | 
						fn on_disconnect(&self, _id: PeerId) { }
 | 
				
			||||||
 | 
						/// Called when a peer makes an announcement.
 | 
				
			||||||
 | 
						fn on_announcement(&self, _id: PeerId, _announcement: &Announcement) { }
 | 
				
			||||||
 | 
						/// Called when a peer requests relay of some transactions.
 | 
				
			||||||
 | 
						fn on_transactions(&self, _id: PeerId, _relay: &[SignedTransaction]) { }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// This is an implementation of the light ethereum network protocol, abstracted
 | 
					/// This is an implementation of the light ethereum network protocol, abstracted
 | 
				
			||||||
/// over a `Provider` of data and a p2p network.
 | 
					/// over a `Provider` of data and a p2p network.
 | 
				
			||||||
///
 | 
					///
 | 
				
			||||||
@ -141,6 +152,7 @@ pub struct LightProtocol {
 | 
				
			|||||||
	pending_requests: RwLock<HashMap<usize, Request>>,
 | 
						pending_requests: RwLock<HashMap<usize, Request>>,
 | 
				
			||||||
	capabilities: RwLock<Capabilities>,
 | 
						capabilities: RwLock<Capabilities>,
 | 
				
			||||||
	flow_params: FlowParams, // assumed static and same for every peer.
 | 
						flow_params: FlowParams, // assumed static and same for every peer.
 | 
				
			||||||
 | 
						handlers: Vec<Box<Handler>>,
 | 
				
			||||||
	req_id: AtomicUsize,
 | 
						req_id: AtomicUsize,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -150,6 +162,9 @@ impl LightProtocol {
 | 
				
			|||||||
	pub fn make_announcement(&self, mut announcement: Announcement, io: &NetworkContext) {
 | 
						pub fn make_announcement(&self, mut announcement: Announcement, io: &NetworkContext) {
 | 
				
			||||||
		let mut reorgs_map = HashMap::new();
 | 
							let mut reorgs_map = HashMap::new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// update stored capabilities
 | 
				
			||||||
 | 
							self.capabilities.write().update_from(&announcement);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// calculate reorg info and send packets
 | 
							// calculate reorg info and send packets
 | 
				
			||||||
		for (peer_id, peer_info) in self.peers.write().iter_mut() {
 | 
							for (peer_id, peer_info) in self.peers.write().iter_mut() {
 | 
				
			||||||
			let reorg_depth = reorgs_map.entry(peer_info.sent_head)
 | 
								let reorg_depth = reorgs_map.entry(peer_info.sent_head)
 | 
				
			||||||
@ -174,6 +189,14 @@ impl LightProtocol {
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/// Add an event handler.
 | 
				
			||||||
 | 
						/// Ownership will be transferred to the protocol structure,
 | 
				
			||||||
 | 
						/// and the handler will be kept alive as long as it is.
 | 
				
			||||||
 | 
						/// These are intended to be added at the beginning of the 
 | 
				
			||||||
 | 
						pub fn add_handler(&mut self, handler: Box<Handler>) {
 | 
				
			||||||
 | 
							self.handlers.push(handler);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl LightProtocol {
 | 
					impl LightProtocol {
 | 
				
			||||||
@ -196,7 +219,11 @@ impl LightProtocol {
 | 
				
			|||||||
	fn on_disconnect(&self, peer: PeerId) {
 | 
						fn on_disconnect(&self, peer: PeerId) {
 | 
				
			||||||
		// TODO: reassign all requests assigned to this peer.
 | 
							// TODO: reassign all requests assigned to this peer.
 | 
				
			||||||
		self.pending_peers.write().remove(&peer);
 | 
							self.pending_peers.write().remove(&peer);
 | 
				
			||||||
		self.peers.write().remove(&peer);
 | 
							if self.peers.write().remove(&peer).is_some() {
 | 
				
			||||||
 | 
								for handler in &self.handlers {
 | 
				
			||||||
 | 
									handler.on_disconnect(peer)
 | 
				
			||||||
 | 
								}	
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// send status to a peer.
 | 
						// send status to a peer.
 | 
				
			||||||
@ -246,12 +273,16 @@ impl LightProtocol {
 | 
				
			|||||||
			local_buffer: Mutex::new(self.flow_params.create_buffer()),
 | 
								local_buffer: Mutex::new(self.flow_params.create_buffer()),
 | 
				
			||||||
			remote_buffer: flow_params.create_buffer(),
 | 
								remote_buffer: flow_params.create_buffer(),
 | 
				
			||||||
			current_asking: HashSet::new(),
 | 
								current_asking: HashSet::new(),
 | 
				
			||||||
			status: status,
 | 
								status: status.clone(),
 | 
				
			||||||
			capabilities: capabilities,
 | 
								capabilities: capabilities.clone(),
 | 
				
			||||||
			remote_flow: flow_params,
 | 
								remote_flow: flow_params,
 | 
				
			||||||
			sent_head: pending.sent_head,
 | 
								sent_head: pending.sent_head,
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for handler in &self.handlers {
 | 
				
			||||||
 | 
								handler.on_connect(*peer, &status, &capabilities)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Ok(())
 | 
							Ok(())
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -282,15 +313,11 @@ impl LightProtocol {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// update capabilities.
 | 
							// update capabilities.
 | 
				
			||||||
		{
 | 
							peer_info.capabilities.update_from(&announcement);
 | 
				
			||||||
			let caps = &mut peer_info.capabilities;
 | 
					 | 
				
			||||||
			caps.serve_headers = caps.serve_headers || announcement.serve_headers;
 | 
					 | 
				
			||||||
			caps.serve_state_since = caps.serve_state_since.or(announcement.serve_state_since);
 | 
					 | 
				
			||||||
			caps.serve_chain_since = caps.serve_chain_since.or(announcement.serve_chain_since);
 | 
					 | 
				
			||||||
			caps.tx_relay = caps.tx_relay || announcement.tx_relay;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// TODO: notify listeners if new best block.
 | 
							for handler in &self.handlers {
 | 
				
			||||||
 | 
								handler.on_announcement(*peer, &announcement);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Ok(())
 | 
							Ok(())
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -603,8 +630,18 @@ impl LightProtocol {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Receive a set of transactions to relay.
 | 
						// Receive a set of transactions to relay.
 | 
				
			||||||
	fn relay_transactions(&self, _: &PeerId, _: &NetworkContext, _: UntrustedRlp) -> Result<(), Error> {
 | 
						fn relay_transactions(&self, peer: &PeerId, data: UntrustedRlp) -> Result<(), Error> {
 | 
				
			||||||
		unimplemented!()
 | 
							const MAX_TRANSACTIONS: usize = 256;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							let txs: Vec<_> = try!(data.iter().take(MAX_TRANSACTIONS).map(|x| x.as_val::<SignedTransaction>()).collect());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							debug!(target: "les", "Received {} transactions to relay from peer {}", txs.len(), peer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for handler in &self.handlers {
 | 
				
			||||||
 | 
								handler.on_transactions(*peer, &txs);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							Ok(())
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -639,7 +676,7 @@ impl NetworkProtocolHandler for LightProtocol {
 | 
				
			|||||||
			packet::GET_HEADER_PROOFS => self.get_header_proofs(peer, io, rlp),
 | 
								packet::GET_HEADER_PROOFS => self.get_header_proofs(peer, io, rlp),
 | 
				
			||||||
			packet::HEADER_PROOFS => self.header_proofs(peer, io, rlp),
 | 
								packet::HEADER_PROOFS => self.header_proofs(peer, io, rlp),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			packet::SEND_TRANSACTIONS => self.relay_transactions(peer, io, rlp),
 | 
								packet::SEND_TRANSACTIONS => self.relay_transactions(peer, rlp),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			other => {
 | 
								other => {
 | 
				
			||||||
				Err(Error::UnrecognizedPacket(other))
 | 
									Err(Error::UnrecognizedPacket(other))
 | 
				
			||||||
 | 
				
			|||||||
@ -201,6 +201,16 @@ impl Default for Capabilities {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl Capabilities {
 | 
				
			||||||
 | 
						/// Update the capabilities from an announcement.
 | 
				
			||||||
 | 
						pub fn update_from(&mut self, announcement: &Announcement) {
 | 
				
			||||||
 | 
							self.serve_headers = self.serve_headers || announcement.serve_headers;
 | 
				
			||||||
 | 
							self.serve_state_since = self.serve_state_since.or(announcement.serve_state_since);
 | 
				
			||||||
 | 
							self.serve_chain_since = self.serve_chain_since.or(announcement.serve_chain_since);
 | 
				
			||||||
 | 
							self.tx_relay = self.tx_relay || announcement.tx_relay;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Attempt to parse a handshake message into its three parts:
 | 
					/// Attempt to parse a handshake message into its three parts:
 | 
				
			||||||
///   - chain status
 | 
					///   - chain status
 | 
				
			||||||
///   - serving capabilities
 | 
					///   - serving capabilities
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user