mirror of
https://github.com/mimblewimble/grin.git
synced 2025-02-08 04:11:08 +03:00
Protocol cleanup. Tests cleanup. Additional test for transaction broadcast.
This commit is contained in:
parent
28f007240e
commit
ea425dc614
7 changed files with 80 additions and 85 deletions
|
@ -35,4 +35,3 @@ pub mod core;
|
||||||
pub mod genesis;
|
pub mod genesis;
|
||||||
pub mod pow;
|
pub mod pow;
|
||||||
pub mod ser;
|
pub mod ser;
|
||||||
// mod chain;
|
|
||||||
|
|
|
@ -17,3 +17,4 @@ grin_core = { path = "../core" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
env_logger = "^0.3"
|
env_logger = "^0.3"
|
||||||
|
secp256k1zkp = { path = "../secp256k1zkp" }
|
||||||
|
|
|
@ -36,11 +36,11 @@ extern crate num;
|
||||||
|
|
||||||
mod types;
|
mod types;
|
||||||
mod msg;
|
mod msg;
|
||||||
mod handshake;
|
pub mod handshake;
|
||||||
mod rw;
|
mod rw;
|
||||||
mod protocol;
|
mod protocol;
|
||||||
mod server;
|
mod server;
|
||||||
mod peer;
|
mod peer;
|
||||||
|
|
||||||
pub use server::{Server, DummyAdapter};
|
pub use server::{Server, DummyAdapter, DEFAULT_LISTEN_ADDR};
|
||||||
pub use server::DEFAULT_LISTEN_ADDR;
|
pub use peer::Peer;
|
||||||
|
|
|
@ -37,7 +37,7 @@ pub enum ErrCodes {
|
||||||
|
|
||||||
/// Types of messages
|
/// Types of messages
|
||||||
enum_from_primitive! {
|
enum_from_primitive! {
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum Type {
|
pub enum Type {
|
||||||
Error,
|
Error,
|
||||||
Hand,
|
Hand,
|
||||||
|
|
|
@ -86,7 +86,7 @@ impl Protocol for ProtocolV1 {
|
||||||
// main select loop, switches between listening, sending or stopping
|
// main select loop, switches between listening, sending or stopping
|
||||||
select!(
|
select!(
|
||||||
r:conn => {
|
r:conn => {
|
||||||
let res = self.read_msg(&mut conn, adapter);
|
let res = self.process_msg(&mut conn, adapter);
|
||||||
if let Err(_) = res {
|
if let Err(_) = res {
|
||||||
let mut cnt = self.error_count.lock().unwrap();
|
let mut cnt = self.error_count.lock().unwrap();
|
||||||
*cnt += 1;
|
*cnt += 1;
|
||||||
|
@ -146,7 +146,12 @@ impl Protocol for ProtocolV1 {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ProtocolV1 {
|
impl ProtocolV1 {
|
||||||
fn read_msg(&self, mut conn: &mut TcpStream, adapter: &NetAdapter) -> Result<(), ser::Error> {
|
/// Reads a message from the peer tcp stream and process it, usually simply
|
||||||
|
/// forwarding to the adapter.
|
||||||
|
fn process_msg(&self,
|
||||||
|
mut conn: &mut TcpStream,
|
||||||
|
adapter: &NetAdapter)
|
||||||
|
-> Result<(), ser::Error> {
|
||||||
// deser the header to get the message type
|
// deser the header to get the message type
|
||||||
let header = try!(ser::deserialize::<MsgHeader>(conn.deref_mut()));
|
let header = try!(ser::deserialize::<MsgHeader>(conn.deref_mut()));
|
||||||
if !header.acceptable() {
|
if !header.acceptable() {
|
||||||
|
@ -162,12 +167,12 @@ impl ProtocolV1 {
|
||||||
Type::Ping => {
|
Type::Ping => {
|
||||||
// respond with pong
|
// respond with pong
|
||||||
try!(self.send_pong());
|
try!(self.send_pong());
|
||||||
},
|
}
|
||||||
Type::Pong => {},
|
Type::Pong => {}
|
||||||
Type::Transaction => {
|
Type::Transaction => {
|
||||||
let tx = try!(ser::deserialize(&mut read_conn));
|
let tx = try!(ser::deserialize(&mut read_conn));
|
||||||
adapter.transaction_received(tx);
|
adapter.transaction_received(tx);
|
||||||
},
|
}
|
||||||
Type::Block => {
|
Type::Block => {
|
||||||
let b = try!(ser::deserialize(&mut read_conn));
|
let b = try!(ser::deserialize(&mut read_conn));
|
||||||
adapter.block_received(b);
|
adapter.block_received(b);
|
||||||
|
@ -176,8 +181,8 @@ impl ProtocolV1 {
|
||||||
}
|
}
|
||||||
|
|
||||||
// update total of bytes sent
|
// update total of bytes sent
|
||||||
let mut sent_bytes = self.sent_bytes.lock().unwrap();
|
let mut received_bytes = self.received_bytes.lock().unwrap();
|
||||||
*sent_bytes += header.serialized_len() + (read_conn.bytes_read() as u64);
|
*received_bytes += header.serialized_len() + (read_conn.bytes_read() as u64);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -194,6 +199,7 @@ impl ProtocolV1 {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sends a pong message (usually in reply to ping)
|
||||||
fn send_pong(&self) -> Result<(), ser::Error> {
|
fn send_pong(&self) -> Result<(), ser::Error> {
|
||||||
let data = try!(ser::ser_vec(&MsgHeader::new(Type::Pong)));
|
let data = try!(ser::ser_vec(&MsgHeader::new(Type::Pong)));
|
||||||
let msg_send = self.msg_send.borrow();
|
let msg_send = self.msg_send.borrow();
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
//! Grin server implementation, accepts incoming connections and connects to
|
//! Grin server implementation, accepts incoming connections and connects to
|
||||||
//! other peers in the network.
|
//! other peers in the network.
|
||||||
|
|
||||||
|
use rand::{self, Rng};
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
|
@ -91,7 +92,6 @@ impl Server {
|
||||||
{
|
{
|
||||||
let mut peers = self.peers.write().unwrap();
|
let mut peers = self.peers.write().unwrap();
|
||||||
peers.push(wpeer.clone());
|
peers.push(wpeer.clone());
|
||||||
println!("len {}", peers.len())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mioco::spawn(move || -> io::Result<()> {
|
mioco::spawn(move || -> io::Result<()> {
|
||||||
|
@ -131,6 +131,18 @@ impl Server {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Number of peers this server is connected to.
|
||||||
|
pub fn peers_count(&self) -> u32 {
|
||||||
|
self.peers.read().unwrap().len() as u32
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets a random peer from our set of connected peers.
|
||||||
|
pub fn get_any_peer(&self) -> Arc<Peer> {
|
||||||
|
let mut rng = rand::thread_rng();
|
||||||
|
let peers = self.peers.read().unwrap();
|
||||||
|
peers[rng.gen_range(0, peers.len())].clone()
|
||||||
|
}
|
||||||
|
|
||||||
/// Stops the server. Disconnect from all peers at the same time.
|
/// Stops the server. Disconnect from all peers at the same time.
|
||||||
pub fn stop(&self) {
|
pub fn stop(&self) {
|
||||||
let peers = self.peers.write().unwrap();
|
let peers = self.peers.write().unwrap();
|
||||||
|
@ -140,15 +152,4 @@ impl Server {
|
||||||
let stop_send = self.stop_send.borrow();
|
let stop_send = self.stop_send.borrow();
|
||||||
stop_send.as_ref().unwrap().send(0);
|
stop_send.as_ref().unwrap().send(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Simulates an unrelated client connecting to our server. Mostly used for
|
|
||||||
/// tests.
|
|
||||||
pub fn connect_as_client(addr: SocketAddr) -> Result<Peer, Error> {
|
|
||||||
let tcp_client = TcpStream::connect(&addr).unwrap();
|
|
||||||
Peer::accept(tcp_client, &Handshake::new())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn peers_count(&self) -> u32 {
|
|
||||||
self.peers.read().unwrap().len() as u32
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,53 +12,41 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
extern crate grin_core as core;
|
||||||
extern crate grin_p2p as p2p;
|
extern crate grin_p2p as p2p;
|
||||||
extern crate mioco;
|
extern crate mioco;
|
||||||
extern crate env_logger;
|
extern crate env_logger;
|
||||||
|
|
||||||
|
mod common;
|
||||||
|
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::sync::Arc;
|
|
||||||
use std::time;
|
use std::time;
|
||||||
|
|
||||||
|
use core::core::*;
|
||||||
|
use p2p::Peer;
|
||||||
|
use common::*;
|
||||||
|
|
||||||
|
// Starts a server and connects a client peer to it to check handshake, followed by a ping/pong exchange to make sure the connection is live.
|
||||||
#[test]
|
#[test]
|
||||||
fn peer_handshake() {
|
fn peer_handshake() {
|
||||||
env_logger::init().unwrap();
|
env_logger::init().unwrap();
|
||||||
|
|
||||||
mioco::start(|| -> io::Result<()> {
|
with_server(|server| -> io::Result<()> {
|
||||||
// start a server in its own coroutine
|
|
||||||
let server = Arc::new(p2p::Server::new());
|
|
||||||
let in_server = server.clone();
|
|
||||||
mioco::spawn(move || -> io::Result<()> {
|
|
||||||
try!(in_server.start().map_err(|_| io::Error::last_os_error()));
|
|
||||||
Ok(())
|
|
||||||
});
|
|
||||||
|
|
||||||
// giving server a little time to start
|
|
||||||
mioco::sleep(time::Duration::from_millis(50));
|
|
||||||
|
|
||||||
// connect a client peer to the server
|
// connect a client peer to the server
|
||||||
let addr = p2p::DEFAULT_LISTEN_ADDR.parse().unwrap();
|
let peer = try!(connect_peer());
|
||||||
let peer = try!(p2p::Server::connect_as_client(addr).map_err(|_| io::Error::last_os_error()));
|
|
||||||
mioco::sleep(time::Duration::from_millis(50));
|
|
||||||
assert_eq!(server.peers_count(), 1);
|
|
||||||
|
|
||||||
// spawn our client peer to its own coroutine so it can poll for replies
|
// check server peer count
|
||||||
let peer = Arc::new(peer);
|
let pc = server.peers_count();
|
||||||
let in_peer = peer.clone();
|
assert_eq!(pc, 1);
|
||||||
mioco::spawn(move || -> io::Result<()> {
|
|
||||||
in_peer.run(&p2p::DummyAdapter{});
|
|
||||||
Ok(())
|
|
||||||
});
|
|
||||||
mioco::sleep(time::Duration::from_millis(50));
|
|
||||||
|
|
||||||
// send a ping and check we got ponged
|
// send a ping and check we got ponged (received data back)
|
||||||
peer.send_ping();
|
peer.send_ping();
|
||||||
mioco::sleep(time::Duration::from_millis(50));
|
mioco::sleep(time::Duration::from_millis(50));
|
||||||
let (sent, recv) = peer.transmitted_bytes();
|
let (sent, recv) = peer.transmitted_bytes();
|
||||||
assert!(sent > 0);
|
assert!(sent > 0);
|
||||||
assert!(recv > 0);
|
assert!(recv > 0);
|
||||||
|
|
||||||
server.stop();
|
peer.stop();
|
||||||
Ok(())
|
Ok(())
|
||||||
}).unwrap().unwrap();
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue