les: use negotiated protocol version
This commit is contained in:
		
							parent
							
								
									eec1929658
								
							
						
					
					
						commit
						5f37c93659
					
				@ -38,6 +38,9 @@ pub trait IoContext {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /// Disable a peer -- this is a disconnect + a time-out.
 | 
					    /// Disable a peer -- this is a disconnect + a time-out.
 | 
				
			||||||
    fn disable_peer(&self, peer: PeerId);
 | 
					    fn disable_peer(&self, peer: PeerId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Get a peer's protocol version.
 | 
				
			||||||
 | 
					    fn protocol_version(&self, peer: PeerId) -> Option<u8>;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'a> IoContext for NetworkContext<'a> {
 | 
					impl<'a> IoContext for NetworkContext<'a> {
 | 
				
			||||||
@ -60,6 +63,10 @@ impl<'a> IoContext for NetworkContext<'a> {
 | 
				
			|||||||
    fn disable_peer(&self, peer: PeerId) {
 | 
					    fn disable_peer(&self, peer: PeerId) {
 | 
				
			||||||
        NetworkContext::disable_peer(self, peer);
 | 
					        NetworkContext::disable_peer(self, peer);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn protocol_version(&self, peer: PeerId) -> Option<u8> {
 | 
				
			||||||
 | 
					        self.protocol_version(self.subprotocol_name(), peer)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Context for a protocol event.
 | 
					/// Context for a protocol event.
 | 
				
			||||||
 | 
				
			|||||||
@ -58,6 +58,10 @@ pub enum Error {
 | 
				
			|||||||
	UnsolicitedResponse,
 | 
						UnsolicitedResponse,
 | 
				
			||||||
	/// Not a server.
 | 
						/// Not a server.
 | 
				
			||||||
	NotServer,
 | 
						NotServer,
 | 
				
			||||||
 | 
						/// Unsupported protocol version.
 | 
				
			||||||
 | 
						UnsupportedProtocolVersion(u8),
 | 
				
			||||||
 | 
						/// Bad protocol version.
 | 
				
			||||||
 | 
						BadProtocolVersion,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl Error {
 | 
					impl Error {
 | 
				
			||||||
@ -73,6 +77,8 @@ impl Error {
 | 
				
			|||||||
			Error::UnknownPeer => Punishment::Disconnect,
 | 
								Error::UnknownPeer => Punishment::Disconnect,
 | 
				
			||||||
			Error::UnsolicitedResponse => Punishment::Disable,
 | 
								Error::UnsolicitedResponse => Punishment::Disable,
 | 
				
			||||||
			Error::NotServer => Punishment::Disable,
 | 
								Error::NotServer => Punishment::Disable,
 | 
				
			||||||
 | 
								Error::UnsupportedProtocolVersion(_) => Punishment::Disable,
 | 
				
			||||||
 | 
								Error::BadProtocolVersion => Punishment::Disable,
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -101,6 +107,8 @@ impl fmt::Display for Error {
 | 
				
			|||||||
			Error::UnknownPeer => write!(f, "Unknown peer"),
 | 
								Error::UnknownPeer => write!(f, "Unknown peer"),
 | 
				
			||||||
			Error::UnsolicitedResponse => write!(f, "Peer provided unsolicited data"),
 | 
								Error::UnsolicitedResponse => write!(f, "Peer provided unsolicited data"),
 | 
				
			||||||
			Error::NotServer => write!(f, "Peer not a server."),
 | 
								Error::NotServer => write!(f, "Peer not a server."),
 | 
				
			||||||
 | 
								Error::UnsupportedProtocolVersion(pv) => write!(f, "Unsupported protocol version: {}", pv),	
 | 
				
			||||||
 | 
								Error::BadProtocolVersion => write!(f, "Bad protocol version in handshake"),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -23,7 +23,7 @@ use ethcore::transaction::SignedTransaction;
 | 
				
			|||||||
use ethcore::receipt::Receipt;
 | 
					use ethcore::receipt::Receipt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use io::TimerToken;
 | 
					use io::TimerToken;
 | 
				
			||||||
use network::{NetworkProtocolHandler, NetworkContext, NetworkError, PeerId};
 | 
					use network::{NetworkProtocolHandler, NetworkContext, 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};
 | 
				
			||||||
@ -111,6 +111,7 @@ pub struct ReqId(usize);
 | 
				
			|||||||
struct PendingPeer {
 | 
					struct PendingPeer {
 | 
				
			||||||
	sent_head: H256,
 | 
						sent_head: H256,
 | 
				
			||||||
	last_update: SteadyTime,
 | 
						last_update: SteadyTime,
 | 
				
			||||||
 | 
						proto_version: u8,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// data about each peer.
 | 
					// data about each peer.
 | 
				
			||||||
@ -121,6 +122,7 @@ struct Peer {
 | 
				
			|||||||
	remote_flow: Option<(Buffer, FlowParams)>,
 | 
						remote_flow: Option<(Buffer, FlowParams)>,
 | 
				
			||||||
	sent_head: H256, // last head we've given them.
 | 
						sent_head: H256, // last head we've given them.
 | 
				
			||||||
	last_update: SteadyTime,
 | 
						last_update: SteadyTime,
 | 
				
			||||||
 | 
						proto_version: u8,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl Peer {
 | 
					impl Peer {
 | 
				
			||||||
@ -507,17 +509,21 @@ impl LightProtocol {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// send status to a peer.
 | 
						// send status to a peer.
 | 
				
			||||||
	fn send_status(&self, peer: PeerId, io: &IoContext) -> Result<PendingPeer, NetworkError> {
 | 
						fn send_status(&self, peer: PeerId, io: &IoContext) -> Result<PendingPeer, Error> {
 | 
				
			||||||
		let chain_info = self.provider.chain_info();
 | 
							let proto_version = try!(io.protocol_version(peer).ok_or(Error::WrongNetwork));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// TODO: could update capabilities here.
 | 
							if PROTOCOL_VERSIONS.iter().find(|x| **x == proto_version).is_none() {
 | 
				
			||||||
 | 
								return Err(Error::UnsupportedProtocolVersion(proto_version));
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							let chain_info = self.provider.chain_info();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		let status = Status {
 | 
							let status = Status {
 | 
				
			||||||
			head_td: chain_info.total_difficulty,
 | 
								head_td: chain_info.total_difficulty,
 | 
				
			||||||
			head_hash: chain_info.best_block_hash,
 | 
								head_hash: chain_info.best_block_hash,
 | 
				
			||||||
			head_num: chain_info.best_block_number,
 | 
								head_num: chain_info.best_block_number,
 | 
				
			||||||
			genesis_hash: chain_info.genesis_hash,
 | 
								genesis_hash: chain_info.genesis_hash,
 | 
				
			||||||
			protocol_version: MAX_PROTOCOL_VERSION as u32,
 | 
								protocol_version: proto_version as u32, // match peer proto version
 | 
				
			||||||
			network_id: self.network_id,
 | 
								network_id: self.network_id,
 | 
				
			||||||
			last_head: None,
 | 
								last_head: None,
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
@ -530,6 +536,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(),
 | 
								last_update: SteadyTime::now(),
 | 
				
			||||||
 | 
								proto_version: proto_version,			
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -550,6 +557,10 @@ impl LightProtocol {
 | 
				
			|||||||
			return Err(Error::WrongNetwork);
 | 
								return Err(Error::WrongNetwork);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if Some(status.protocol_version as u8) != io.protocol_version(*peer) {
 | 
				
			||||||
 | 
								return Err(Error::BadProtocolVersion);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		let remote_flow = flow_params.map(|params| (params.create_buffer(), params));
 | 
							let remote_flow = flow_params.map(|params| (params.create_buffer(), params));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		self.peers.write().insert(*peer, Mutex::new(Peer {
 | 
							self.peers.write().insert(*peer, Mutex::new(Peer {
 | 
				
			||||||
@ -559,6 +570,7 @@ impl LightProtocol {
 | 
				
			|||||||
			remote_flow: remote_flow,
 | 
								remote_flow: remote_flow,
 | 
				
			||||||
			sent_head: pending.sent_head,
 | 
								sent_head: pending.sent_head,
 | 
				
			||||||
			last_update: pending.last_update,
 | 
								last_update: pending.last_update,
 | 
				
			||||||
 | 
								proto_version: pending.proto_version,
 | 
				
			||||||
		}));
 | 
							}));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for handler in &self.handlers {
 | 
							for handler in &self.handlers {
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user