2018-01-30 17:42:04 +03:00
|
|
|
// Copyright 2018 The Grin Developers
|
2016-10-25 07:35:10 +03:00
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
2017-10-26 20:48:51 +03:00
|
|
|
use std::sync::Arc;
|
2017-11-21 17:24:29 +03:00
|
|
|
use std::net::SocketAddr;
|
2016-10-29 22:36:45 +03:00
|
|
|
|
2017-01-30 02:52:01 +03:00
|
|
|
use futures::Future;
|
|
|
|
use futures::sync::mpsc::UnboundedSender;
|
2017-12-14 15:19:43 +03:00
|
|
|
use futures_cpupool::CpuPool;
|
2016-12-11 06:11:49 +03:00
|
|
|
use tokio_core::net::TcpStream;
|
2016-10-29 22:36:45 +03:00
|
|
|
|
2016-11-01 20:42:33 +03:00
|
|
|
use core::core;
|
2018-01-30 17:42:04 +03:00
|
|
|
use core::core::hash::{Hash, Hashed};
|
2017-11-21 17:24:29 +03:00
|
|
|
use core::core::target::Difficulty;
|
2016-10-25 07:35:10 +03:00
|
|
|
use core::ser;
|
2017-02-02 06:05:17 +03:00
|
|
|
use conn::TimeoutConnection;
|
2016-10-26 08:06:13 +03:00
|
|
|
use msg::*;
|
|
|
|
use types::*;
|
2017-10-12 19:56:44 +03:00
|
|
|
use util::LOGGER;
|
2017-01-30 02:52:01 +03:00
|
|
|
use util::OneTime;
|
2016-10-25 07:35:10 +03:00
|
|
|
|
2017-08-10 03:54:10 +03:00
|
|
|
#[allow(dead_code)]
|
2016-10-29 22:36:45 +03:00
|
|
|
pub struct ProtocolV1 {
|
2017-02-02 06:05:17 +03:00
|
|
|
conn: OneTime<TimeoutConnection>,
|
2016-10-31 22:29:08 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
impl ProtocolV1 {
|
2017-02-02 06:05:17 +03:00
|
|
|
pub fn new() -> ProtocolV1 {
|
2017-11-01 02:32:33 +03:00
|
|
|
ProtocolV1 {
|
|
|
|
conn: OneTime::new(),
|
|
|
|
}
|
2017-02-02 06:05:17 +03:00
|
|
|
}
|
2016-10-25 07:35:10 +03:00
|
|
|
}
|
|
|
|
|
2016-10-29 22:36:45 +03:00
|
|
|
impl Protocol for ProtocolV1 {
|
2017-01-30 02:52:01 +03:00
|
|
|
/// Sets up the protocol reading, writing and closing logic.
|
2017-10-26 20:48:51 +03:00
|
|
|
fn handle(
|
|
|
|
&self,
|
|
|
|
conn: TcpStream,
|
|
|
|
adapter: Arc<NetAdapter>,
|
2017-11-21 17:24:29 +03:00
|
|
|
addr: SocketAddr,
|
2017-12-14 15:19:43 +03:00
|
|
|
pool: CpuPool,
|
2017-10-26 20:48:51 +03:00
|
|
|
) -> Box<Future<Item = (), Error = Error>> {
|
2017-12-14 15:19:43 +03:00
|
|
|
let (conn, listener) = TimeoutConnection::listen(conn, pool, move |sender, header, data| {
|
2017-02-02 06:05:17 +03:00
|
|
|
let adapt = adapter.as_ref();
|
2017-11-21 17:24:29 +03:00
|
|
|
handle_payload(adapt, sender, header, data, addr)
|
2017-02-02 06:05:17 +03:00
|
|
|
});
|
2016-12-11 06:11:49 +03:00
|
|
|
|
2017-02-02 06:05:17 +03:00
|
|
|
self.conn.init(conn);
|
2016-12-12 00:04:52 +03:00
|
|
|
|
2017-02-02 06:05:17 +03:00
|
|
|
listener
|
2016-12-12 00:04:52 +03:00
|
|
|
}
|
|
|
|
|
2017-01-30 02:52:01 +03:00
|
|
|
/// Bytes sent and received.
|
2016-12-12 00:04:52 +03:00
|
|
|
fn transmitted_bytes(&self) -> (u64, u64) {
|
2017-02-02 06:05:17 +03:00
|
|
|
self.conn.borrow().transmitted_bytes()
|
2016-12-12 00:04:52 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Sends a ping message to the remote peer. Will panic if handle has never
|
|
|
|
/// been called on this protocol.
|
2017-12-14 00:52:21 +03:00
|
|
|
fn send_ping(&self, total_difficulty: Difficulty, height: u64) -> Result<(), Error> {
|
2017-11-21 17:24:29 +03:00
|
|
|
self.send_request(
|
|
|
|
Type::Ping,
|
|
|
|
Type::Pong,
|
2017-12-14 00:52:21 +03:00
|
|
|
&Ping { total_difficulty, height },
|
2017-11-21 17:24:29 +03:00
|
|
|
None,
|
|
|
|
)
|
2016-12-12 00:04:52 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Serializes and sends a block to our remote peer
|
2017-02-27 07:08:40 +03:00
|
|
|
fn send_block(&self, b: &core::Block) -> Result<(), Error> {
|
2016-12-12 00:04:52 +03:00
|
|
|
self.send_msg(Type::Block, b)
|
|
|
|
}
|
|
|
|
|
2018-01-30 17:42:04 +03:00
|
|
|
/// Serializes and sends a block header to our remote peer ("header first" propagation)
|
|
|
|
fn send_header(&self, bh: &core::BlockHeader) -> Result<(), Error> {
|
|
|
|
self.send_msg(Type::Header, bh)
|
|
|
|
}
|
|
|
|
|
2016-12-12 00:04:52 +03:00
|
|
|
/// Serializes and sends a transaction to our remote peer
|
2017-02-27 07:08:40 +03:00
|
|
|
fn send_transaction(&self, tx: &core::Transaction) -> Result<(), Error> {
|
2016-12-12 00:04:52 +03:00
|
|
|
self.send_msg(Type::Transaction, tx)
|
|
|
|
}
|
|
|
|
|
2017-02-27 07:08:40 +03:00
|
|
|
fn send_header_request(&self, locator: Vec<Hash>) -> Result<(), Error> {
|
2017-09-29 21:44:25 +03:00
|
|
|
self.send_request(
|
|
|
|
Type::GetHeaders,
|
|
|
|
Type::Headers,
|
|
|
|
&Locator { hashes: locator },
|
|
|
|
None,
|
|
|
|
)
|
2017-02-08 00:52:17 +03:00
|
|
|
}
|
|
|
|
|
2017-02-27 07:08:40 +03:00
|
|
|
fn send_block_request(&self, h: Hash) -> Result<(), Error> {
|
2017-02-19 05:42:34 +03:00
|
|
|
self.send_request(Type::GetBlock, Type::Block, &h, Some(h))
|
|
|
|
}
|
|
|
|
|
2017-02-27 07:08:40 +03:00
|
|
|
fn send_peer_request(&self, capab: Capabilities) -> Result<(), Error> {
|
2017-09-29 21:44:25 +03:00
|
|
|
self.send_request(
|
|
|
|
Type::GetPeerAddrs,
|
|
|
|
Type::PeerAddrs,
|
2017-11-01 02:32:33 +03:00
|
|
|
&GetPeerAddrs {
|
|
|
|
capabilities: capab,
|
|
|
|
},
|
2017-09-29 21:44:25 +03:00
|
|
|
None,
|
|
|
|
)
|
2017-02-08 00:52:17 +03:00
|
|
|
}
|
|
|
|
|
2016-12-12 00:04:52 +03:00
|
|
|
/// Close the connection to the remote peer
|
|
|
|
fn close(&self) {
|
|
|
|
// TODO some kind of shutdown signal
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ProtocolV1 {
|
2017-04-07 08:54:54 +03:00
|
|
|
fn send_msg<W: ser::Writeable>(&self, t: Type, body: &W) -> Result<(), Error> {
|
2017-02-02 06:05:17 +03:00
|
|
|
self.conn.borrow().send_msg(t, body)
|
|
|
|
}
|
2017-01-30 02:52:01 +03:00
|
|
|
|
2017-10-26 20:48:51 +03:00
|
|
|
fn send_request<W: ser::Writeable>(
|
|
|
|
&self,
|
|
|
|
t: Type,
|
|
|
|
rt: Type,
|
|
|
|
body: &W,
|
|
|
|
expect_resp: Option<Hash>,
|
|
|
|
) -> Result<(), Error> {
|
2017-12-14 00:52:21 +03:00
|
|
|
if self.conn.is_initialized() {
|
|
|
|
self.conn.borrow().send_request(t, rt, body, expect_resp)
|
|
|
|
} else {
|
|
|
|
Ok(())
|
|
|
|
}
|
2017-02-02 06:05:17 +03:00
|
|
|
}
|
2016-11-01 20:42:33 +03:00
|
|
|
}
|
2016-12-16 01:57:04 +03:00
|
|
|
|
2017-10-26 20:48:51 +03:00
|
|
|
fn handle_payload(
|
|
|
|
adapter: &NetAdapter,
|
|
|
|
sender: UnboundedSender<Vec<u8>>,
|
|
|
|
header: MsgHeader,
|
|
|
|
buf: Vec<u8>,
|
2017-11-21 17:24:29 +03:00
|
|
|
addr: SocketAddr,
|
2017-10-26 20:48:51 +03:00
|
|
|
) -> Result<Option<Hash>, ser::Error> {
|
2017-02-02 06:05:17 +03:00
|
|
|
match header.msg_type {
|
|
|
|
Type::Ping => {
|
2017-11-21 17:24:29 +03:00
|
|
|
let ping = ser::deserialize::<Ping>(&mut &buf[..])?;
|
2017-12-14 00:52:21 +03:00
|
|
|
adapter.peer_difficulty(addr, ping.total_difficulty, ping.height);
|
|
|
|
let pong = Pong { total_difficulty: adapter.total_difficulty(), height: adapter.total_height() };
|
2017-11-21 17:24:29 +03:00
|
|
|
let mut body_data = vec![];
|
|
|
|
try!(ser::serialize(&mut body_data, &pong));
|
|
|
|
let mut data = vec![];
|
|
|
|
try!(ser::serialize(
|
|
|
|
&mut data,
|
|
|
|
&MsgHeader::new(Type::Pong, body_data.len() as u64),
|
|
|
|
));
|
|
|
|
data.append(&mut body_data);
|
2017-12-14 15:19:43 +03:00
|
|
|
|
|
|
|
if let Err(e) = sender.unbounded_send(data) {
|
|
|
|
debug!(LOGGER, "handle_payload: Ping, error sending: {:?}", e);
|
|
|
|
}
|
|
|
|
|
2017-02-02 06:05:17 +03:00
|
|
|
Ok(None)
|
|
|
|
}
|
2017-11-21 17:24:29 +03:00
|
|
|
Type::Pong => {
|
|
|
|
let pong = ser::deserialize::<Pong>(&mut &buf[..])?;
|
2017-12-14 00:52:21 +03:00
|
|
|
adapter.peer_difficulty(addr, pong.total_difficulty, pong.height);
|
2017-11-21 17:24:29 +03:00
|
|
|
Ok(None)
|
|
|
|
},
|
2017-02-02 06:05:17 +03:00
|
|
|
Type::Transaction => {
|
2017-02-08 00:52:17 +03:00
|
|
|
let tx = ser::deserialize::<core::Transaction>(&mut &buf[..])?;
|
2018-01-30 17:42:04 +03:00
|
|
|
debug!(LOGGER, "handle_payload: Transaction: {}", tx.hash());
|
|
|
|
|
2017-02-02 06:05:17 +03:00
|
|
|
adapter.transaction_received(tx);
|
|
|
|
Ok(None)
|
|
|
|
}
|
2017-02-08 00:52:17 +03:00
|
|
|
Type::GetBlock => {
|
|
|
|
let h = ser::deserialize::<Hash>(&mut &buf[..])?;
|
2018-01-30 17:42:04 +03:00
|
|
|
debug!(LOGGER, "handle_payload: GetBlock: {}", h);
|
2017-12-11 17:51:52 +03:00
|
|
|
|
2017-02-08 00:52:17 +03:00
|
|
|
let bo = adapter.get_block(h);
|
|
|
|
if let Some(b) = bo {
|
|
|
|
// serialize and send the block over
|
|
|
|
let mut body_data = vec![];
|
|
|
|
try!(ser::serialize(&mut body_data, &b));
|
|
|
|
let mut data = vec![];
|
2017-09-29 21:44:25 +03:00
|
|
|
try!(ser::serialize(
|
|
|
|
&mut data,
|
|
|
|
&MsgHeader::new(Type::Block, body_data.len() as u64),
|
|
|
|
));
|
2017-02-08 00:52:17 +03:00
|
|
|
data.append(&mut body_data);
|
2017-12-14 15:19:43 +03:00
|
|
|
if let Err(e) = sender.unbounded_send(data) {
|
|
|
|
debug!(LOGGER, "handle_payload: GetBlock, error sending: {:?}", e);
|
|
|
|
}
|
2017-02-08 00:52:17 +03:00
|
|
|
}
|
|
|
|
Ok(None)
|
|
|
|
}
|
2017-02-02 06:05:17 +03:00
|
|
|
Type::Block => {
|
2017-02-08 00:52:17 +03:00
|
|
|
let b = ser::deserialize::<core::Block>(&mut &buf[..])?;
|
2017-02-02 06:05:17 +03:00
|
|
|
let bh = b.hash();
|
2018-01-30 17:42:04 +03:00
|
|
|
debug!(LOGGER, "handle_payload: Block: {}", bh);
|
2017-12-14 15:19:43 +03:00
|
|
|
|
2017-11-28 07:44:33 +03:00
|
|
|
adapter.block_received(b, addr);
|
2017-02-02 06:05:17 +03:00
|
|
|
Ok(Some(bh))
|
|
|
|
}
|
2018-01-30 17:42:04 +03:00
|
|
|
// A peer is asking us for some headers via a locator
|
2017-02-08 00:52:17 +03:00
|
|
|
Type::GetHeaders => {
|
|
|
|
let loc = ser::deserialize::<Locator>(&mut &buf[..])?;
|
2018-01-30 17:42:04 +03:00
|
|
|
debug!(LOGGER, "handle_payload: GetHeaders: {:?}", loc);
|
|
|
|
|
2017-02-08 00:52:17 +03:00
|
|
|
let headers = adapter.locate_headers(loc.hashes);
|
|
|
|
|
|
|
|
// serialize and send all the headers over
|
|
|
|
let mut body_data = vec![];
|
2017-10-26 20:48:51 +03:00
|
|
|
try!(ser::serialize(
|
|
|
|
&mut body_data,
|
|
|
|
&Headers { headers: headers },
|
|
|
|
));
|
2017-02-08 00:52:17 +03:00
|
|
|
let mut data = vec![];
|
2017-09-29 21:44:25 +03:00
|
|
|
try!(ser::serialize(
|
|
|
|
&mut data,
|
|
|
|
&MsgHeader::new(Type::Headers, body_data.len() as u64),
|
|
|
|
));
|
2017-02-08 00:52:17 +03:00
|
|
|
data.append(&mut body_data);
|
2017-12-14 15:19:43 +03:00
|
|
|
if let Err(e) = sender.unbounded_send(data) {
|
|
|
|
debug!(LOGGER, "handle_payload: GetHeaders, error sending: {:?}", e);
|
|
|
|
}
|
2017-02-08 00:52:17 +03:00
|
|
|
|
|
|
|
Ok(None)
|
|
|
|
}
|
2018-01-30 17:42:04 +03:00
|
|
|
// "header first" block propagation - if we have not yet seen this block
|
|
|
|
// we can go request it from some of our peers
|
|
|
|
Type::Header => {
|
|
|
|
let header = ser::deserialize::<core::BlockHeader>(&mut &buf[..])?;
|
|
|
|
debug!(LOGGER, "handle_payload: Header: {}", header.hash());
|
|
|
|
|
|
|
|
adapter.header_received(header, addr);
|
|
|
|
|
|
|
|
// we do not return a hash here as we never request a single header
|
|
|
|
// a header will always arrive unsolicited
|
|
|
|
Ok(None)
|
|
|
|
}
|
|
|
|
// receive headers as part of the sync process
|
2017-02-08 00:52:17 +03:00
|
|
|
Type::Headers => {
|
|
|
|
let headers = ser::deserialize::<Headers>(&mut &buf[..])?;
|
2018-01-30 17:42:04 +03:00
|
|
|
debug!(LOGGER, "handle_payload: Headers: {}", headers.headers.len());
|
|
|
|
|
2017-11-30 18:27:50 +03:00
|
|
|
adapter.headers_received(headers.headers, addr);
|
2017-02-08 00:52:17 +03:00
|
|
|
Ok(None)
|
|
|
|
}
|
2017-02-19 05:42:34 +03:00
|
|
|
Type::GetPeerAddrs => {
|
|
|
|
let get_peers = ser::deserialize::<GetPeerAddrs>(&mut &buf[..])?;
|
|
|
|
let peer_addrs = adapter.find_peer_addrs(get_peers.capabilities);
|
|
|
|
|
|
|
|
// serialize and send all the headers over
|
|
|
|
let mut body_data = vec![];
|
2017-09-29 21:44:25 +03:00
|
|
|
try!(ser::serialize(
|
|
|
|
&mut body_data,
|
|
|
|
&PeerAddrs {
|
|
|
|
peers: peer_addrs.iter().map(|sa| SockAddr(*sa)).collect(),
|
|
|
|
},
|
|
|
|
));
|
2017-02-19 05:42:34 +03:00
|
|
|
let mut data = vec![];
|
2017-09-29 21:44:25 +03:00
|
|
|
try!(ser::serialize(
|
|
|
|
&mut data,
|
|
|
|
&MsgHeader::new(Type::PeerAddrs, body_data.len() as u64),
|
|
|
|
));
|
2017-02-19 05:42:34 +03:00
|
|
|
data.append(&mut body_data);
|
2017-12-14 15:19:43 +03:00
|
|
|
if let Err(e) = sender.unbounded_send(data) {
|
|
|
|
debug!(LOGGER, "handle_payload: GetPeerAddrs, error sending: {:?}", e);
|
|
|
|
}
|
2017-02-19 05:42:34 +03:00
|
|
|
|
|
|
|
Ok(None)
|
|
|
|
}
|
|
|
|
Type::PeerAddrs => {
|
|
|
|
let peer_addrs = ser::deserialize::<PeerAddrs>(&mut &buf[..])?;
|
|
|
|
adapter.peer_addrs_received(peer_addrs.peers.iter().map(|pa| pa.0).collect());
|
|
|
|
Ok(None)
|
|
|
|
}
|
2017-02-02 06:05:17 +03:00
|
|
|
_ => {
|
2017-10-12 19:56:44 +03:00
|
|
|
debug!(LOGGER, "unknown message type {:?}", header.msg_type);
|
2017-02-02 06:05:17 +03:00
|
|
|
Ok(None)
|
|
|
|
}
|
|
|
|
}
|
2016-12-16 01:57:04 +03:00
|
|
|
}
|