Implemented block adding check. Cleared many warnings, cleaned code.
This commit is contained in:
@@ -2,7 +2,6 @@ extern crate serde;
|
||||
extern crate serde_json;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use crate::p2p::peer::Peer;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub enum Message {
|
||||
|
||||
+24
-23
@@ -2,7 +2,6 @@ extern crate serde;
|
||||
extern crate serde_json;
|
||||
|
||||
use std::{io, thread};
|
||||
use std::collections::HashMap;
|
||||
use std::io::{Read, Write};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::time::Duration;
|
||||
@@ -11,11 +10,9 @@ use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
|
||||
use mio::{Events, Interest, Poll, Registry, Token};
|
||||
use mio::event::Event;
|
||||
use mio::net::{TcpListener, TcpStream};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{Context, Block, p2p::Message, p2p::State, p2p::Peer, p2p::Peers};
|
||||
use std::net::{SocketAddr, IpAddr, SocketAddrV4};
|
||||
use std::borrow::BorrowMut;
|
||||
|
||||
const SERVER: Token = Token(0);
|
||||
const POLL_TIMEOUT: Option<Duration> = Some(Duration::from_millis(3000));
|
||||
@@ -88,7 +85,7 @@ impl Network {
|
||||
}
|
||||
token => {
|
||||
match peers.get_mut_peer(&token) {
|
||||
Some(peer) => {
|
||||
Some(_peer) => {
|
||||
match handle_connection_event(context.clone(), &mut peers, &poll.registry(), &event) {
|
||||
Ok(result) => {
|
||||
if !result {
|
||||
@@ -123,7 +120,7 @@ fn handle_connection_event(context: Arc<Mutex<Context>>, peers: &mut Peers, regi
|
||||
|
||||
if event.is_readable() {
|
||||
let data = {
|
||||
let mut peer = peers.get_mut_peer(&event.token()).expect("Error getting peer for connection");
|
||||
let peer = peers.get_mut_peer(&event.token()).expect("Error getting peer for connection");
|
||||
let mut stream = peer.get_stream();
|
||||
read_message(&mut stream)
|
||||
};
|
||||
@@ -134,8 +131,8 @@ fn handle_connection_event(context: Arc<Mutex<Context>>, peers: &mut Peers, regi
|
||||
Ok(message) => {
|
||||
println!("Got message from socket {}: {:?}", &event.token().0, &message);
|
||||
let new_state = handle_message(context.clone(), message, peers, &event.token());
|
||||
let mut peer = peers.get_mut_peer(&event.token()).unwrap();
|
||||
let mut stream = peer.get_stream();
|
||||
let peer = peers.get_mut_peer(&event.token()).unwrap();
|
||||
let stream = peer.get_stream();
|
||||
match new_state {
|
||||
State::Message { data } => {
|
||||
if event.is_writable() {
|
||||
@@ -154,7 +151,7 @@ fn handle_connection_event(context: Arc<Mutex<Context>>, peers: &mut Peers, regi
|
||||
State::Error => {}
|
||||
State::Banned => {}
|
||||
State::Offline { .. } => {
|
||||
peer.set_state(State::offline(1));
|
||||
peer.set_state(State::offline());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -175,7 +172,7 @@ fn handle_connection_event(context: Arc<Mutex<Context>>, peers: &mut Peers, regi
|
||||
State::Connecting => {
|
||||
println!("Sending hello to socket {}", event.token().0);
|
||||
let data: String = {
|
||||
let mut c = context.lock().unwrap();
|
||||
let c = context.lock().unwrap();
|
||||
let message = Message::hand(&c.settings.origin, c.settings.version, c.settings.public);
|
||||
serde_json::to_string(&message).unwrap()
|
||||
};
|
||||
@@ -191,7 +188,7 @@ fn handle_connection_event(context: Arc<Mutex<Context>>, peers: &mut Peers, regi
|
||||
println!("Odd version of pings :)");
|
||||
if from.elapsed().as_secs() >= 30 {
|
||||
let data: String = {
|
||||
let mut c = context.lock().unwrap();
|
||||
let c = context.lock().unwrap();
|
||||
let message = Message::ping(c.blockchain.height());
|
||||
serde_json::to_string(&message).unwrap()
|
||||
};
|
||||
@@ -232,7 +229,7 @@ fn read_message(stream: &mut &mut TcpStream) -> Result<Vec<u8>, Vec<u8>> {
|
||||
Err(ref err) if would_block(err) => break,
|
||||
Err(ref err) if interrupted(err) => continue,
|
||||
// Other errors we'll consider fatal.
|
||||
Err(err) => return Err(buf),
|
||||
Err(_) => return Err(buf),
|
||||
}
|
||||
}
|
||||
if buf.len() == data_size {
|
||||
@@ -244,29 +241,30 @@ fn read_message(stream: &mut &mut TcpStream) -> Result<Vec<u8>, Vec<u8>> {
|
||||
|
||||
fn send_message(connection: &mut TcpStream, data: &Vec<u8>) {
|
||||
// TODO handle errors
|
||||
connection.write_u32::<BigEndian>(data.len() as u32);
|
||||
connection.write_u32::<BigEndian>(data.len() as u32).expect("Error sending message");
|
||||
connection.write_all(&data).expect("Error writing to socket");
|
||||
connection.flush();
|
||||
connection.flush().expect("Error sending message");
|
||||
}
|
||||
|
||||
fn handle_message(context: Arc<Mutex<Context>>, message: Message, peers: &mut Peers, token: &Token) -> State {
|
||||
let my_height = {
|
||||
let (my_height, my_origin, my_version) = {
|
||||
let context = context.lock().unwrap();
|
||||
context.blockchain.height()
|
||||
(context.blockchain.height(), &context.settings.origin.clone(), context.settings.version)
|
||||
};
|
||||
match message {
|
||||
Message::Hand { origin: origin, version, public } => {
|
||||
let context = context.lock().unwrap();
|
||||
if origin == context.settings.origin && version == context.settings.version {
|
||||
let mut peer = peers.get_mut_peer(token).unwrap();
|
||||
Message::Hand { origin, version, public } => {
|
||||
if origin.eq(my_origin) && version == my_version {
|
||||
let peer = peers.get_mut_peer(token).unwrap();
|
||||
peer.set_public(public);
|
||||
State::message(Message::shake(&context.settings.origin, context.settings.version, true, context.blockchain.height()))
|
||||
State::message(Message::shake(&origin, version, true, my_height))
|
||||
} else {
|
||||
State::Error
|
||||
}
|
||||
}
|
||||
Message::Shake { origin, version, ok, height } => {
|
||||
// TODO check origin and version for compatibility
|
||||
if origin.ne(my_origin) || version != my_version {
|
||||
return State::Error;
|
||||
}
|
||||
if ok {
|
||||
if height > my_height {
|
||||
State::message(Message::GetBlock { index: my_height + 1u64 })
|
||||
@@ -308,6 +306,7 @@ fn handle_message(context: Arc<Mutex<Context>>, message: Message, peers: &mut Pe
|
||||
}
|
||||
}
|
||||
Message::Block { index, block } => {
|
||||
println!("Received block {}", index);
|
||||
let block: Block = match serde_json::from_str(&block) {
|
||||
Ok(block) => block,
|
||||
Err(_) => return State::Error
|
||||
@@ -316,8 +315,10 @@ fn handle_message(context: Arc<Mutex<Context>>, message: Message, peers: &mut Pe
|
||||
let context = context.clone();
|
||||
thread::spawn(move || {
|
||||
let mut context = context.lock().unwrap();
|
||||
context.blockchain.add_block(block);
|
||||
context.bus.post(crate::event::Event::BlockchainChanged)
|
||||
match context.blockchain.add_block(block) {
|
||||
Ok(_) => { context.bus.post(crate::event::Event::BlockchainChanged); }
|
||||
Err(_) => { println!("Error adding received block"); }
|
||||
}
|
||||
});
|
||||
State::idle()
|
||||
}
|
||||
|
||||
+2
-3
@@ -1,7 +1,6 @@
|
||||
use crate::p2p::State;
|
||||
use std::net::SocketAddr;
|
||||
use mio::net::TcpStream;
|
||||
use std::sync::RwLock;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Peer {
|
||||
@@ -49,9 +48,9 @@ impl Peer {
|
||||
self.state.disabled()
|
||||
}
|
||||
|
||||
/// If loopback address then we care about ip and port.
|
||||
/// If regular address then we only care about the ip and ignore the port.
|
||||
pub fn equals(&self, addr: &SocketAddr) -> bool {
|
||||
/// If loopback address then we care about ip and port.
|
||||
/// If regular address then we only care about the ip and ignore the port.
|
||||
if self.addr.ip().is_loopback() {
|
||||
self.addr == *addr
|
||||
} else {
|
||||
|
||||
+2
-2
@@ -80,7 +80,7 @@ impl Peers {
|
||||
}
|
||||
|
||||
pub fn send_pings(&mut self, registry: &Registry, height: u64) {
|
||||
for (token, mut peer) in self.peers.iter_mut() {
|
||||
for (token, peer) in self.peers.iter_mut() {
|
||||
match peer.get_state() {
|
||||
State::Idle { from } => {
|
||||
if from.elapsed().as_secs() >= PING_PERIOD {
|
||||
@@ -93,7 +93,7 @@ impl Peers {
|
||||
};
|
||||
|
||||
peer.set_state(State::message(message));
|
||||
let mut stream = peer.get_stream();
|
||||
let stream = peer.get_stream();
|
||||
registry.reregister(stream, token.clone(), Interest::WRITABLE).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
+4
-15
@@ -9,7 +9,7 @@ pub enum State {
|
||||
Message { data: Vec<u8> },
|
||||
Error,
|
||||
Banned,
|
||||
Offline { from: Instant, attempts: usize },
|
||||
Offline { from: Instant },
|
||||
}
|
||||
|
||||
impl State {
|
||||
@@ -17,19 +17,8 @@ impl State {
|
||||
Self::Idle { from: Instant::now() }
|
||||
}
|
||||
|
||||
pub fn offline(attempts: usize) -> Self {
|
||||
Self::Offline { attempts, from: Instant::now() }
|
||||
}
|
||||
|
||||
pub fn still_offline(state: Self) -> Self {
|
||||
match state {
|
||||
State::Offline { attempts, from } => {
|
||||
Self::Offline { attempts: attempts + 1, from }
|
||||
}
|
||||
_ => {
|
||||
Self::Offline { attempts: 1, from: Instant::now() }
|
||||
}
|
||||
}
|
||||
pub fn offline() -> Self {
|
||||
Self::Offline { from: Instant::now() }
|
||||
}
|
||||
|
||||
pub fn message(message: Message) -> Self {
|
||||
@@ -51,7 +40,7 @@ impl State {
|
||||
match self {
|
||||
State::Error => { true }
|
||||
State::Banned => { true }
|
||||
State::Offline { from, attempts } => {
|
||||
State::Offline { from} => {
|
||||
from.elapsed().as_secs() < 60 // We check offline peers to become online every 5 minutes
|
||||
}
|
||||
_ => { false }
|
||||
|
||||
Reference in New Issue
Block a user