mirror of
https://github.com/mimblewimble/grin.git
synced 2025-02-01 08:51:08 +03:00
Getting started on the p2p networking code.
This commit is contained in:
parent
0855d7b41e
commit
c8aa8d7c18
5 changed files with 218 additions and 0 deletions
12
p2p/Cargo.toml
Normal file
12
p2p/Cargo.toml
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
[package]
|
||||||
|
name = "grin_p2p"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Ignotus Peverell <igno.peverell@protonmail.com>"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
bitflags = "^0.7.0"
|
||||||
|
byteorder = "^0.5"
|
||||||
|
mioco = "^0.8"
|
||||||
|
time = "^0.1"
|
||||||
|
|
||||||
|
grin_core = { path = "../core" }
|
3
p2p/rustfmt.toml
Normal file
3
p2p/rustfmt.toml
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
hard_tabs = true
|
||||||
|
wrap_comments = true
|
||||||
|
write_mode = "Overwrite"
|
29
p2p/src/lib.rs
Normal file
29
p2p/src/lib.rs
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
// Copyright 2016 The Grin Developers
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
//! Networking code to connect to other peers and exchange block, transactions,
|
||||||
|
//! etc.
|
||||||
|
|
||||||
|
#![deny(non_upper_case_globals)]
|
||||||
|
#![deny(non_camel_case_types)]
|
||||||
|
#![deny(non_snake_case)]
|
||||||
|
#![deny(unused_mut)]
|
||||||
|
#![warn(missing_docs)]
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate bitflags;
|
||||||
|
extern crate mioco;
|
||||||
|
|
||||||
|
mod msg;
|
||||||
|
mod server;
|
50
p2p/src/msg.rs
Normal file
50
p2p/src/msg.rs
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
// Copyright 2016 The Grin Developers
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
//! Message types that transit over the network and related serialization code.
|
||||||
|
|
||||||
|
use std::net::SocketAddr;
|
||||||
|
|
||||||
|
use core::ser::{Writeable, Readable, Writer, Reader};
|
||||||
|
|
||||||
|
mod ErrCodes {
|
||||||
|
const UNSUPPORTED_VERSION: u32 = 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
bitflags! {
|
||||||
|
/// Options for block validation
|
||||||
|
pub flags Capabilities: u32 {
|
||||||
|
/// Runs with the easier version of the Proof of Work, mostly to make testing easier.
|
||||||
|
const FULL_SYNC = 0b00000001,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Hand {
|
||||||
|
version: u32,
|
||||||
|
capabilities: Capabilities,
|
||||||
|
sender_addr: SocketAddr,
|
||||||
|
receiver_addr: SocketAddr,
|
||||||
|
user_agent: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Shake {
|
||||||
|
version: u32,
|
||||||
|
capabilities: Capabilities,
|
||||||
|
user_agent: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct PeerError {
|
||||||
|
code: u32,
|
||||||
|
message: String,
|
||||||
|
}
|
124
p2p/src/server.rs
Normal file
124
p2p/src/server.rs
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
// Copyright 2016 The Grin Developers
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
//! Grin server implementation, accepts incoming connections and connects to
|
||||||
|
//! other peers in the network, handling handshake and message receive/send.
|
||||||
|
|
||||||
|
use str::net::SocketAddr;
|
||||||
|
use std::str::FromStr;
|
||||||
|
use time::Duration;
|
||||||
|
|
||||||
|
use mioco::tcp::{TcpListener, TcpStream, Shutdown};
|
||||||
|
|
||||||
|
use core::ser::{serialize, deserialize};
|
||||||
|
use msg::*;
|
||||||
|
|
||||||
|
const DEFAULT_LISTEN_ADDR: &'static str = "127.0.0.1:555";
|
||||||
|
const PROTOCOL_VERSION: u32 = 1;
|
||||||
|
const USER_AGENT: &'static str = "MW/Grin 0.1";
|
||||||
|
|
||||||
|
// replace with some config lookup or something
|
||||||
|
fn listen_addr() -> SocketAddr {
|
||||||
|
FromStr::from_str(DEFAULT_LISTEN_ADDR).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The local representation of a remotely connected peer. Handles most
|
||||||
|
/// low-level network communication.
|
||||||
|
struct Peer {
|
||||||
|
conn: TcpStream,
|
||||||
|
reader: BufReader,
|
||||||
|
capabilities: Capabilities,
|
||||||
|
user_agent: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Peer {
|
||||||
|
/// Create a new local peer instance connected to a remote peer with the
|
||||||
|
/// provided TcpStream.
|
||||||
|
fn new(conn: TcpStream) -> Peer {
|
||||||
|
// don't wait on read for more than 2 seconds by default
|
||||||
|
conn.set_read_timeout(Some(Duration::seconds(2)));
|
||||||
|
|
||||||
|
Peer {
|
||||||
|
conn: conn,
|
||||||
|
reader: BufReader::new(conn),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Handles connecting to a new remote peer, starting the version handshake.
|
||||||
|
fn connect(&mut self) {
|
||||||
|
serialize(self.conn,
|
||||||
|
&Hand {
|
||||||
|
version: PROTOCOL_VERSION,
|
||||||
|
capabilities: FULL_SYNC,
|
||||||
|
sender_addr: listen_addr(),
|
||||||
|
receiver_addr: conn.peer_addr(),
|
||||||
|
user_agent: USER_AGENT,
|
||||||
|
});
|
||||||
|
let shake = deserialize(self.reader);
|
||||||
|
if shake.version != 1 {
|
||||||
|
self.close(ErrCodes::UNSUPPORTED_VERSION,
|
||||||
|
format!("Unsupported version: {}, ours: {})",
|
||||||
|
shake.version,
|
||||||
|
PROTOCOL_VERSION));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self.capabilities = shake.capabilities;
|
||||||
|
self.user_agent = shake.user_agent;
|
||||||
|
|
||||||
|
self.accept_loop();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Handles receiving a connection from a new remote peer that started the
|
||||||
|
/// version handshake.
|
||||||
|
fn handshake(&mut self) {}
|
||||||
|
|
||||||
|
fn accept_loop(&mut self) {
|
||||||
|
loop {
|
||||||
|
let msg = deserialize(self.reader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn close(err_code: u32, explanation: &'static str) {
|
||||||
|
serialize(self.conn,
|
||||||
|
&Err {
|
||||||
|
code: err_code,
|
||||||
|
message: explanation,
|
||||||
|
});
|
||||||
|
self.conn.shutdown(Shutdown::Both);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Server {
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Server {
|
||||||
|
/// Creates a new p2p server. Opens a TCP port to allow incoming
|
||||||
|
/// connections and starts the bootstrapping process to find peers.
|
||||||
|
pub fn new() -> Server {
|
||||||
|
mioco::start(|| -> io::Result<()> {
|
||||||
|
let addr = "127.0.0.1:3414".parse().unwrap();
|
||||||
|
let listener = try!(TcpListener::bind(&addr));
|
||||||
|
info!("P2P server started on {}", addr);
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let mut conn = try!(listener.accept());
|
||||||
|
mioco::spawn(move || -> io::Result<()> {
|
||||||
|
Peer::new(conn).connect();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.unwrap()
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue