From ef5cef290e69b05482eb81aff8757984caa5ee11 Mon Sep 17 00:00:00 2001 From: Revertron Date: Mon, 11 Jul 2022 02:17:30 +0200 Subject: [PATCH] Fixed block-spam over the p2p if there is no consensus. --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/p2p/network.rs | 39 +++++++++++++++++++++++++-------------- 3 files changed, 27 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4131c64..0df289a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -84,7 +84,7 @@ dependencies = [ [[package]] name = "alfis" -version = "0.7.4" +version = "0.7.5" dependencies = [ "base64", "bincode", diff --git a/Cargo.toml b/Cargo.toml index bcd79be..748ed79 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "alfis" -version = "0.7.4" +version = "0.7.5" authors = ["Revertron "] edition = "2021" build = "build.rs" diff --git a/src/p2p/network.rs b/src/p2p/network.rs index b6753c5..63655f8 100644 --- a/src/p2p/network.rs +++ b/src/p2p/network.rs @@ -25,7 +25,7 @@ use crate::commons::*; use crate::crypto::Chacha; use crate::eventbus::{post, register}; use crate::p2p::{Message, Peer, Peers, State}; -use crate::{Block, Context}; +use crate::{Block, Bytes, Context}; const SERVER: Token = Token(0); @@ -82,6 +82,7 @@ impl Network { let mut old_keys = 0i64; let mut old_nodes = 0usize; let mut old_banned = 0usize; + let mut seen_blocks = HashSet::new(); loop { if self.peers.get_peers_count() == 0 && bootstrap_timer.elapsed().as_secs() > 60 { warn!("Restarting swarm connections..."); @@ -145,7 +146,7 @@ impl Network { } } token => { - if !self.handle_connection_event(poll.registry(), event) { + if !self.handle_connection_event(poll.registry(), event, &mut seen_blocks) { let _ = self.peers.close_peer(poll.registry(), &token); let blocks = self.context.lock().unwrap().chain.get_height(); let keys = self.context.lock().unwrap().chain.get_users_count(); @@ -199,6 +200,7 @@ impl Network { warn!("Last network events time {} seconds ago", elapsed); } log_timer = Instant::now(); + seen_blocks.clear(); } if nodes < MAX_NODES && connect_timer.elapsed().as_secs() >= 5 { self.peers.connect_new_peers(poll.registry(), &mut self.token, yggdrasil_only); @@ -219,13 +221,13 @@ impl Network { } } - fn handle_connection_event(&mut self, registry: &Registry, event: &Event) -> bool { + fn handle_connection_event(&mut self, registry: &Registry, event: &Event, seen_blocks: &mut HashSet) -> bool { if event.is_error() || (event.is_read_closed() && event.is_write_closed()) { return false; } if event.is_readable() { - return self.process_readable(registry, event); + return self.process_readable(registry, event, seen_blocks); } if event.is_writable() { @@ -235,7 +237,7 @@ impl Network { true } - fn process_readable(&mut self, registry: &Registry, event: &Event) -> bool { + fn process_readable(&mut self, registry: &Registry, event: &Event, seen_blocks: &mut HashSet) -> bool { let data = { let token = event.token(); match self.peers.get_mut_peer(&token) { @@ -328,7 +330,7 @@ impl Network { match Message::from_bytes(data) { Ok(message) => { //let m = format!("{:?}", &message); - let new_state = self.handle_message(message, &event.token()); + let new_state = self.handle_message(message, &event.token(), seen_blocks); let peer = self.peers.get_mut_peer(&event.token()).unwrap(); //debug!("Got message from {}: {:?}", &peer.get_addr(), &m); let stream = peer.get_stream(); @@ -448,7 +450,7 @@ impl Network { true } - fn handle_message(&mut self, message: Message, token: &Token) -> State { + fn handle_message(&mut self, message: Message, token: &Token, seen_blocks: &mut HashSet) -> State { let (my_height, my_hash, my_origin, my_version, me_public) = { let context = self.context.lock().unwrap(); // TODO cache it somewhere @@ -514,6 +516,9 @@ impl Network { let peer = self.peers.get_mut_peer(token).unwrap(); peer.set_height(height); peer.set_active(true); + if seen_blocks.contains(&hash) { + return State::message(Message::pong(my_height, my_hash)); + } if peer.is_higher(my_height) { let mut context = self.context.lock().unwrap(); context.chain.update_max_height(height); @@ -532,6 +537,9 @@ impl Network { let peer = self.peers.get_mut_peer(token).unwrap(); peer.set_height(height); peer.set_active(true); + if seen_blocks.contains(&hash) { + return State::idle(); + } if peer.is_higher(my_height) { let mut context = self.context.lock().unwrap(); context.chain.update_max_height(height); @@ -585,7 +593,11 @@ impl Network { return State::Banned; } info!("Received block {} with hash {:?}", block.index, &block.hash); - self.handle_block(token, block) + if !seen_blocks.contains(&block.hash) { + self.handle_block(token, block, seen_blocks) + } else { + State::idle() + } } Message::Twin => State::Twin, Message::Loop => State::Loop @@ -593,7 +605,8 @@ impl Network { answer } - fn handle_block(&mut self, token: &Token, block: Block) -> State { + fn handle_block(&mut self, token: &Token, block: Block, seen_blocks: &mut HashSet) -> State { + seen_blocks.insert(block.hash.clone()); let peers_count = self.peers.get_peers_active_count(); let peer = self.peers.get_mut_peer(token).unwrap(); peer.set_received_block(block.index); @@ -652,16 +665,14 @@ impl Network { debug!("Got forked block {} with hash {:?}", block.index, block.hash); // If we are very much behind of blockchain let lagged = block.index == context.chain.get_height() && block.index + LIMITED_CONFIDENCE_DEPTH <= max_height; - let last_block = context.chain.last_block().unwrap(); - if block.is_better_than(&last_block) || lagged { + let our_block = context.chain.get_block(block.index).unwrap(); + if block.is_better_than(&our_block) || lagged { context.chain.replace_block(block).expect("Error replacing block with fork"); let index = context.chain.get_height(); post(crate::event::Event::BlockchainChanged { index }); } else { debug!("Fork in not better than our block, dropping."); - if let Some(block) = context.chain.get_block(block.index) { - return State::message(Message::block(block.index, block.as_bytes())); - } + return State::message(Message::block(our_block.index, our_block.as_bytes())); } } }