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