diff --git a/p2p/src/config.rs b/p2p/src/config.rs index 29f2f4a4..c096a018 100644 --- a/p2p/src/config.rs +++ b/p2p/src/config.rs @@ -6,10 +6,6 @@ use net::Config as NetConfig; pub struct Config { /// Number of threads used by p2p thread pool. pub threads: usize, - /// Lowest supported protocol version. - pub protocol_minimum: u32, - /// Highest supported protocol version. - pub protocol_maximum: u32, /// Number of inbound connections. pub inbound_connections: u32, /// Number of outbound connections. diff --git a/p2p/src/io/handshake.rs b/p2p/src/io/handshake.rs index c93bd5ec..b3b2c13c 100644 --- a/p2p/src/io/handshake.rs +++ b/p2p/src/io/handshake.rs @@ -1,19 +1,20 @@ use std::{io, cmp}; use futures::{Future, Poll, Async}; -use message::{Message, MessageResult}; +use message::{Message, MessageResult, Error}; use message::types::{Version, Verack}; use message::common::Magic; use io::{write_message, WriteMessage, ReadMessage, read_message}; -pub fn handshake(a: A, magic: Magic, version: Version) -> Handshake where A: io::Write + io::Read { +pub fn handshake(a: A, magic: Magic, version: Version, min_version: u32) -> Handshake where A: io::Write + io::Read { Handshake { version: version.version(), state: HandshakeState::SendVersion(write_message(a, version_message(magic, version))), magic: magic, + min_version: min_version, } } -pub fn accept_handshake(a: A, magic: Magic, version: Version) -> AcceptHandshake where A: io::Write + io::Read { +pub fn accept_handshake(a: A, magic: Magic, version: Version, min_version: u32) -> AcceptHandshake where A: io::Write + io::Read { AcceptHandshake { version: version.version(), state: AcceptHandshakeState::ReceiveVersion { @@ -21,6 +22,7 @@ pub fn accept_handshake(a: A, magic: Magic, version: Version) -> AcceptHandsh future: read_message(a, magic, 0), }, magic: magic, + min_version: min_version, } } @@ -72,12 +74,14 @@ pub struct Handshake { state: HandshakeState, magic: Magic, version: u32, + min_version: u32, } pub struct AcceptHandshake { state: AcceptHandshakeState, magic: Magic, version: u32, + min_version: u32, } impl Future for Handshake where A: io::Read + io::Write { @@ -97,6 +101,10 @@ impl Future for Handshake where A: io::Read + io::Write { Err(err) => return Ok((stream, Err(err.into())).into()), }; + if version.version() < self.min_version { + return Ok((stream, Err(Error::InvalidVersion)).into()); + } + let next = HandshakeState::ReceiveVerack { version: Some(version), future: read_message(stream, self.magic, 0), @@ -140,6 +148,10 @@ impl Future for AcceptHandshake where A: io::Read + io::Write { Err(err) => return Ok((stream, Err(err.into())).into()), }; + if version.version() < self.min_version { + return Ok((stream, Err(Error::InvalidVersion)).into()); + } + let local_version = local_version.take().expect("local version must be set"); let next = AcceptHandshakeState::SendVersion { version: Some(version), diff --git a/p2p/src/lib.rs b/p2p/src/lib.rs index 2b640099..7a0bbb0d 100644 --- a/p2p/src/lib.rs +++ b/p2p/src/lib.rs @@ -25,9 +25,6 @@ mod config; mod event_loop; mod p2p; -pub const VERSION: u32 = 70_014; -pub const USER_AGENT: &'static str = "pbtc"; - pub use primitives::{hash, bytes}; pub use config::Config; diff --git a/p2p/src/net/accept_connection.rs b/p2p/src/net/accept_connection.rs index 75acd4c3..af915b13 100644 --- a/p2p/src/net/accept_connection.rs +++ b/p2p/src/net/accept_connection.rs @@ -9,7 +9,7 @@ use net::{Config, Connection}; pub fn accept_connection(stream: TcpStream, handle: &Handle, config: &Config, address: net::SocketAddr) -> Deadline { let accept = AcceptConnection { - handshake: accept_handshake(stream, config.magic, config.version(&address)), + handshake: accept_handshake(stream, config.magic, config.version(&address), config.protocol_minimum), magic: config.magic, address: address, }; diff --git a/p2p/src/net/config.rs b/p2p/src/net/config.rs index 5f620abb..1c71d183 100644 --- a/p2p/src/net/config.rs +++ b/p2p/src/net/config.rs @@ -3,10 +3,11 @@ use message::common::{Magic, Services, NetAddress}; use message::types::version::{Version, V0, V106, V70001}; use util::time::{Time, RealTime}; use util::nonce::{NonceGenerator, RandomNonce}; -use VERSION; #[derive(Debug, Clone)] pub struct Config { + pub protocol_version: u32, + pub protocol_minimum: u32, pub magic: Magic, pub local_address: SocketAddr, pub services: Services, @@ -18,7 +19,7 @@ pub struct Config { impl Config { pub fn version(&self, to: &SocketAddr) -> Version { Version::V70001(V0 { - version: VERSION, + version: self.protocol_version, services: self.services, timestamp: RealTime.get().sec, receiver: NetAddress { diff --git a/p2p/src/net/connect.rs b/p2p/src/net/connect.rs index 788717b9..7b78fa77 100644 --- a/p2p/src/net/connect.rs +++ b/p2p/src/net/connect.rs @@ -18,6 +18,7 @@ pub fn connect(address: &SocketAddr, handle: &Handle, config: &Config) -> Deadli }, magic: config.magic, address: *address, + protocol_minimum: config.protocol_minimum, }; deadline(Duration::new(5, 0), handle, connect).expect("Failed to create timeout") @@ -36,6 +37,7 @@ pub struct Connect { state: ConnectState, magic: Magic, address: SocketAddr, + protocol_minimum: u32, } impl Future for Connect { @@ -47,7 +49,7 @@ impl Future for Connect { ConnectState::TcpConnect { ref mut future, ref mut version } => { let stream = try_ready!(future.poll()); let version = version.take().expect("state TcpConnect must have version"); - let handshake = handshake(stream, self.magic, version); + let handshake = handshake(stream, self.magic, version, self.protocol_minimum); (ConnectState::Handshake(handshake), Async::NotReady) }, ConnectState::Handshake(ref mut future) => { diff --git a/pbtc/commands/start.rs b/pbtc/commands/start.rs index 890be31d..111ae3bc 100644 --- a/pbtc/commands/start.rs +++ b/pbtc/commands/start.rs @@ -2,7 +2,7 @@ use std::net::SocketAddr; use sync::create_sync_connection_factory; use message::Services; use util::{open_db, init_db, node_table_path}; -use {config, p2p}; +use {config, p2p, PROTOCOL_VERSION, PROTOCOL_MINIMUM, USER_AGENT}; pub fn start(cfg: config::Config) -> Result<(), String> { let mut el = p2p::event_loop(); @@ -12,15 +12,15 @@ pub fn start(cfg: config::Config) -> Result<(), String> { let p2p_cfg = p2p::Config { threads: 4, - protocol_minimum: 70001, - protocol_maximum: 70017, inbound_connections: 10, outbound_connections: 10, connection: p2p::NetConfig { + protocol_version: PROTOCOL_VERSION, + protocol_minimum: PROTOCOL_MINIMUM, magic: cfg.magic, local_address: SocketAddr::new("127.0.0.1".parse().unwrap(), cfg.port), services: Services::default().with_network(true), - user_agent: "pbtc".into(), + user_agent: USER_AGENT.into(), start_height: 0, relay: false, }, diff --git a/pbtc/main.rs b/pbtc/main.rs index 31d2c6a5..099430d6 100644 --- a/pbtc/main.rs +++ b/pbtc/main.rs @@ -23,6 +23,9 @@ mod util; use app_dirs::AppInfo; pub const APP_INFO: AppInfo = AppInfo { name: "pbtc", author: "Parity" }; +pub const PROTOCOL_VERSION: u32 = 70_014; +pub const PROTOCOL_MINIMUM: u32 = 70_001; +pub const USER_AGENT: &'static str = "pbtc"; fn main() { env_logger::init().unwrap();