From 796f1f2f607f457ca4cd834c39a49f0e346d8514 Mon Sep 17 00:00:00 2001 From: littleblack111 Date: Tue, 21 Oct 2025 09:05:16 +0800 Subject: network: verify requests --- src/blocks.rs | 17 +++++++++++++++-- src/client.rs | 2 +- src/network.rs | 39 ++++++++++++++++++++++++--------------- src/transaction.rs | 2 +- 4 files changed, 41 insertions(+), 19 deletions(-) diff --git a/src/blocks.rs b/src/blocks.rs index 39abde2..9c52d71 100644 --- a/src/blocks.rs +++ b/src/blocks.rs @@ -7,7 +7,7 @@ use serde::{Deserialize, Serialize}; use crate::{ZERO_PREFIX_AMOUNT, transaction::Transaction}; -#[derive(Deserialize, Serialize, Clone, Copy)] +#[derive(Deserialize, Serialize, Clone, Copy, PartialEq)] pub struct Block { pub prev_hash: u64, pub trans: Transaction, @@ -42,6 +42,19 @@ impl Block { unreachable!() } + pub fn verify_pow(&mut self, pow: u64) -> bool { + let mut hasher = DefaultHasher::new(); + (&self.prev_hash, &self.trans, pow).hash(&mut hasher); + hasher + .finish() + .to_string() + .to_string() + .starts_with( + &"0".repeat(ZERO_PREFIX_AMOUNT) + .to_string(), + ) + } + pub fn calc_set_pow(&mut self) { self.pow = Some(self.calc_pow()); } @@ -65,7 +78,7 @@ impl Hash for Block { } } -#[derive(Default, Deserialize, Serialize, Clone)] +#[derive(Default, Deserialize, Serialize, Clone, PartialEq)] pub struct BlockChain { blocks: Vec, } diff --git a/src/client.rs b/src/client.rs index 7919b94..5edba62 100644 --- a/src/client.rs +++ b/src/client.rs @@ -1,7 +1,7 @@ use rand::Rng; use serde::{Deserialize, Serialize}; -#[derive(Hash, Deserialize, Serialize, Clone, Copy)] +#[derive(Hash, Deserialize, Serialize, Clone, Copy, PartialEq)] pub struct Client { id: u32, } diff --git a/src/network.rs b/src/network.rs index b198221..5247c93 100644 --- a/src/network.rs +++ b/src/network.rs @@ -58,7 +58,7 @@ impl Network { .unwrap(), ))); self.peers - .push(peer.clone()); + .push(Arc::clone(&peer)); spawn(async move { peer.lock() @@ -136,7 +136,6 @@ struct Peer { impl Peer { fn new(parent: Weak>, stream: TcpStream) -> Self { - eprintln!("a"); Self { parent, framed: Framed::new(TokioFramed::new(stream, LengthDelimitedCodec::new()), Json::default()), @@ -150,7 +149,6 @@ impl Peer { .next() .await { - eprintln!("a"); self.handle(req.unwrap()) .await; } @@ -160,16 +158,21 @@ impl Peer { async fn handle(&mut self, req: Request) { match req { Request::Block(mut block) => match block.pow { - Some(_) => self - .parent - .upgrade() - .unwrap() - .lock() - .await - .blockchain - .lock() - .await - .store(block), + Some(pow) => { + if !block.verify_pow(pow) { + eprintln!("Rejecting remote block, POW verification failed"); // TODO: log remote IP + return; + } + self.parent + .upgrade() + .unwrap() + .lock() + .await + .blockchain + .lock() + .await + .store(block) + } None => { block.calc_set_pow(); let parent = self @@ -184,7 +187,7 @@ impl Peer { } }, Request::Ibd(bc) => match bc { - Some(_bc) => { + Some(bc) => { let parent = self .parent .upgrade() @@ -192,10 +195,16 @@ impl Peer { let net = parent .lock() .await; - let mut _bc_lock = net + let mut self_bc = net .blockchain .lock() .await; + // verify if our blocks match theirs + if *self_bc != bc { + eprintln!("Remote IBD broadcast did not match ours") // TODO: log IP of sender + // TODO: verify POWs, prev_hash of theirs(check missing), verify our POWs and if they have more blocks if their's all correct + // TODO: maybe queue and see if everybody else's blockchain match and is verified and has more block + } } None => { let parent = self diff --git a/src/transaction.rs b/src/transaction.rs index 4baf60f..0b77a10 100644 --- a/src/transaction.rs +++ b/src/transaction.rs @@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize}; use crate::client::Client; -#[derive(Hash, Deserialize, Serialize, Clone, Copy)] +#[derive(Hash, Deserialize, Serialize, Clone, Copy, PartialEq)] pub struct Transaction { from: Client, to: Client, -- cgit v1.2.3