From 636ecf306ac28443c750dab2d3672793804f31e8 Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Tue, 12 Jul 2016 10:33:20 +0200 Subject: [PATCH] handshake sorting out (#1586) --- ipc/codegen/src/codegen.rs | 32 ++++----------- ipc/rpc/Cargo.toml | 2 +- ipc/rpc/src/binary.rs | 79 +++++++++++++++++++++++++++++++++++++- ipc/rpc/src/interface.rs | 1 + ipc/rpc/src/lib.rs | 2 +- 5 files changed, 87 insertions(+), 29 deletions(-) diff --git a/ipc/codegen/src/codegen.rs b/ipc/codegen/src/codegen.rs index dd93933cc..89aae7eae 100644 --- a/ipc/codegen/src/codegen.rs +++ b/ipc/codegen/src/codegen.rs @@ -62,24 +62,10 @@ pub fn expand_ipc_implementation( }; push_client(cx, &builder, &interface_map, push); - push_handshake_struct(cx, push); push(Annotatable::Item(interface_map.item)); } -fn push_handshake_struct(cx: &ExtCtxt, push: &mut FnMut(Annotatable)) { - let handshake_item = quote_item!(cx, - #[derive(Binary)] - pub struct BinHandshake { - api_version: String, - protocol_version: String, - reserved: Vec, - } - ).unwrap(); - - push(Annotatable::Item(handshake_item)); -} - fn field_name(builder: &aster::AstBuilder, arg: &Arg) -> ast::Ident { match arg.pat.node { PatKind::Ident(_, ref ident, _) => builder.id(ident.node), @@ -601,15 +587,14 @@ fn push_client_implementation( let handshake_item = quote_impl_item!(cx, pub fn handshake(&self) -> Result<(), ::ipc::Error> { - let payload = BinHandshake { - protocol_version: $item_ident::protocol_version().to_string(), - api_version: $item_ident::api_version().to_string(), - reserved: vec![0u8; 64], + let payload = ::ipc::Handshake { + protocol_version: $item_ident::protocol_version(), + api_version: $item_ident::api_version(), }; ::ipc::invoke( 0, - &Some(::ipc::binary::serialize(&payload).unwrap()), + &Some(::ipc::binary::serialize(&::ipc::BinHandshake::from(payload)).unwrap()), &mut *self.socket.write().unwrap()); let mut result = vec![0u8; 1]; @@ -673,18 +658,15 @@ fn implement_handshake_arm( ) -> (ast::Arm, ast::Arm) { let handshake_deserialize = quote_stmt!(&cx, - let handshake_payload = ::ipc::binary::deserialize_from::(r).unwrap(); + let handshake_payload = ::ipc::binary::deserialize_from::<::ipc::BinHandshake, _>(r).unwrap(); ); let handshake_deserialize_buf = quote_stmt!(&cx, - let handshake_payload = ::ipc::binary::deserialize::(buf).unwrap(); + let handshake_payload = ::ipc::binary::deserialize::<::ipc::BinHandshake>(buf).unwrap(); ); let handshake_serialize = quote_expr!(&cx, - ::ipc::binary::serialize::(&Self::handshake(&::ipc::Handshake { - api_version: ::semver::Version::parse(&handshake_payload.api_version).unwrap(), - protocol_version: ::semver::Version::parse(&handshake_payload.protocol_version).unwrap(), - })).unwrap() + ::ipc::binary::serialize::(&Self::handshake(&handshake_payload.to_semver())).unwrap() ); ( diff --git a/ipc/rpc/Cargo.toml b/ipc/rpc/Cargo.toml index ab00523de..b8512b2bb 100644 --- a/ipc/rpc/Cargo.toml +++ b/ipc/rpc/Cargo.toml @@ -8,6 +8,6 @@ license = "GPL-3.0" [dependencies] ethcore-devtools = { path = "../../devtools" } -semver = "0.2.0" nanomsg = { git = "https://github.com/ethcore/nanomsg.rs.git" } ethcore-util = { path = "../../util" } +semver = "0.2" diff --git a/ipc/rpc/src/binary.rs b/ipc/rpc/src/binary.rs index cfc7420f2..94d930941 100644 --- a/ipc/rpc/src/binary.rs +++ b/ipc/rpc/src/binary.rs @@ -21,6 +21,7 @@ use util::numbers::{U256, U512, H256, H2048, Address}; use std::mem; use std::collections::{VecDeque, BTreeMap}; use std::ops::Range; +use super::Handshake; #[derive(Debug)] pub struct BinaryConvertError; @@ -554,6 +555,61 @@ macro_rules! binary_fixed_size { } } +/// Fixed-sized version of Handshake struct +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct BinHandshake { + api_version: BinVersion, + protocol_version: BinVersion, +} + +/// Shorten version of semver Version without `pre` and `build` information +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct BinVersion { + pub major: u64, + pub minor: u64, + pub patch: u64, +} + +impl From for BinHandshake { + fn from(other: Handshake) -> Self { + BinHandshake { + api_version: BinVersion::from(other.api_version), + protocol_version: BinVersion::from(other.protocol_version), + } + } +} + +impl BinHandshake { + pub fn to_semver(self) -> Handshake { + Handshake { + api_version: self.api_version.to_semver(), + protocol_version: self.protocol_version.to_semver(), + } + } +} + +impl BinVersion { + pub fn to_semver(self) -> ::semver::Version { + ::semver::Version { + major: self.major, + minor: self.minor, + patch: self.patch, + pre: vec![], + build: vec![], + } + } +} + +impl From<::semver::Version> for BinVersion { + fn from(other: ::semver::Version) -> Self { + BinVersion { + major: other.major, + minor: other.minor, + patch: other.patch, + } + } +} + binary_fixed_size!(u64); binary_fixed_size!(u32); binary_fixed_size!(usize); @@ -564,6 +620,7 @@ binary_fixed_size!(U512); binary_fixed_size!(H256); binary_fixed_size!(H2048); binary_fixed_size!(Address); +binary_fixed_size!(BinHandshake); #[test] fn vec_serialize() { @@ -706,8 +763,6 @@ fn serialize_opt_vec() { #[test] fn serialize_opt_vec_payload() { - use std::io::Cursor; - let optional_vec: Option> = None; let payload = serialize(&optional_vec).unwrap(); @@ -776,3 +831,23 @@ fn serialize_btree() { assert_eq!(res[&1u64], 5u64); } + +#[test] +fn serialize_handshake() { + use std::io::{Cursor, SeekFrom, Seek}; + + let mut buff = Cursor::new(Vec::new()); + + let handshake = Handshake { + api_version: ::semver::Version::parse("1.2.0").unwrap(), + protocol_version: ::semver::Version::parse("1.2.0").unwrap(), + }; + + serialize_into(&BinHandshake::from(handshake.clone()), &mut buff).unwrap(); + + buff.seek(SeekFrom::Start(0)).unwrap(); + let res = deserialize_from::(&mut buff).unwrap().to_semver(); + + assert_eq!(res, handshake); + +} diff --git a/ipc/rpc/src/interface.rs b/ipc/rpc/src/interface.rs index d4514467f..3d97d59bc 100644 --- a/ipc/rpc/src/interface.rs +++ b/ipc/rpc/src/interface.rs @@ -20,6 +20,7 @@ use std::io::{Read, Write}; use std::marker::Sync; use semver::Version; +#[derive(Debug, PartialEq, Eq, Clone)] /// Handshake for client and server to negotiate api/protocol version pub struct Handshake { pub protocol_version: Version, diff --git a/ipc/rpc/src/lib.rs b/ipc/rpc/src/lib.rs index a19302fb2..a78320343 100644 --- a/ipc/rpc/src/lib.rs +++ b/ipc/rpc/src/lib.rs @@ -24,4 +24,4 @@ extern crate ethcore_util as util; pub mod interface; pub mod binary; pub use interface::{IpcInterface, IpcSocket, invoke, IpcConfig, Handshake, Error, WithSocket}; -pub use binary::{BinaryConvertable, BinaryConvertError}; +pub use binary::{BinaryConvertable, BinaryConvertError, BinHandshake};