From 47cbcdb03fc2925a7e645a49e2ad40b121785358 Mon Sep 17 00:00:00 2001 From: stringhandler Date: Wed, 23 Oct 2024 09:22:24 +0200 Subject: [PATCH 1/5] fix: try remove stack overflow --- src/sharechain/p2chain.rs | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/sharechain/p2chain.rs b/src/sharechain/p2chain.rs index fe68c95a..7a0819e2 100644 --- a/src/sharechain/p2chain.rs +++ b/src/sharechain/p2chain.rs @@ -171,6 +171,7 @@ impl P2Chain { } fn verify_chain(&mut self, new_block_height: u64, hash: FixedHash) -> Result<(), Error> { + dbg!("Verify chain", new_block_height); // we should validate what we can if a block is invalid, we should delete it. let mut missing_parents = Vec::new(); let block = self @@ -350,23 +351,28 @@ impl P2Chain { } } + let mut next_level_data = None; + // let see if we already have a block that builds on top of this - if let Some(next_level) = self.level_at_height(new_block_height + 1).cloned() { + if let Some(next_level) = self.level_at_height(new_block_height + 1) { // we have a height here, lets check the blocks for block in next_level.blocks.iter() { if block.1.prev_hash == hash { - info!(target: LOG_TARGET, "[{:?}] Found block building on top of block: {:?}", algo, new_block_height); - // we have a parent here - match self.verify_chain(next_level.height, block.0.clone()) { - Err(Error::BlockParentDoesNotExist { - missing_parents: mut missing, - }) => missing_parents.append(&mut missing), - Err(e) => return Err(e), - Ok(_) => (), - } + next_level_data = Some((next_level.height, block.0.clone())); } } } + if let Some(next_level) = next_level_data { + info!(target: LOG_TARGET, "[{:?}] Found block building on top of block: {:?}", algo, new_block_height); + // we have a parent here + match self.verify_chain(next_level.0, next_level.1) { + Err(Error::BlockParentDoesNotExist { + missing_parents: mut missing, + }) => missing_parents.append(&mut missing), + Err(e) => return Err(e), + Ok(_) => (), + } + } if !missing_parents.is_empty() { return Err(Error::BlockParentDoesNotExist { missing_parents }); } From 1d4edbd68e10c3b375dbe9a864b5e9c072fe7295 Mon Sep 17 00:00:00 2001 From: stringhandler Date: Wed, 23 Oct 2024 10:06:01 +0200 Subject: [PATCH 2/5] solve overflow --- src/sharechain/p2chain.rs | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/src/sharechain/p2chain.rs b/src/sharechain/p2chain.rs index 7a0819e2..a295037e 100644 --- a/src/sharechain/p2chain.rs +++ b/src/sharechain/p2chain.rs @@ -171,9 +171,32 @@ impl P2Chain { } fn verify_chain(&mut self, new_block_height: u64, hash: FixedHash) -> Result<(), Error> { + let missing_parents = vec![]; + match self.verify_chain_inner(missing_parents, new_block_height, hash, 0) { + Ok((missing_parents, do_next_level)) => { + if !missing_parents.is_empty() { + return Err(Error::BlockParentDoesNotExist { missing_parents }); + } + if let Some((height, hash)) = do_next_level { + self.verify_chain_inner(vec![], height, hash, 0)?; + } + Ok(()) + }, + Err(e) => Err(e), + } + } + + fn verify_chain_inner( + &mut self, + mut missing_parents: Vec<(u64, FixedHash)>, + new_block_height: u64, + hash: FixedHash, + recursion_depth: usize, + ) -> Result<(Vec<(u64, FixedHash)>, Option<(u64, FixedHash)>), Error> { dbg!("Verify chain", new_block_height); + dbg!(recursion_depth); // we should validate what we can if a block is invalid, we should delete it. - let mut missing_parents = Vec::new(); + // let mut missing_parents = Vec::new(); let block = self .get_block_at_height(new_block_height, &hash) .ok_or(Error::BlockNotFound)? @@ -212,7 +235,7 @@ impl P2Chain { // the newly added block == 0 if self.get_tip().map(|tip| tip.height).unwrap_or(0) == 0 && new_block_height == 0 { self.set_new_tip(new_block_height, hash)?; - return Ok(()); + return Ok((missing_parents, None)); } // if !missing_parents.is_empty() { @@ -365,18 +388,12 @@ impl P2Chain { if let Some(next_level) = next_level_data { info!(target: LOG_TARGET, "[{:?}] Found block building on top of block: {:?}", algo, new_block_height); // we have a parent here - match self.verify_chain(next_level.0, next_level.1) { - Err(Error::BlockParentDoesNotExist { - missing_parents: mut missing, - }) => missing_parents.append(&mut missing), - Err(e) => return Err(e), - Ok(_) => (), - } + return Ok((missing_parents, Some(next_level))); } if !missing_parents.is_empty() { return Err(Error::BlockParentDoesNotExist { missing_parents }); } - Ok(()) + Ok((missing_parents, None)) } fn add_block(&mut self, block: Arc) -> Result<(), Error> { From 7bb90c026fede1efb20bb42f6eb05a88c3acc650 Mon Sep 17 00:00:00 2001 From: stringhandler Date: Wed, 23 Oct 2024 11:03:35 +0200 Subject: [PATCH 3/5] more fixes --- src/server/grpc/p2pool.rs | 4 ++-- src/server/p2p/network.rs | 6 ++--- src/sharechain/p2chain.rs | 47 +++++++++++++++++++++++++-------------- 3 files changed, 35 insertions(+), 22 deletions(-) diff --git a/src/server/grpc/p2pool.rs b/src/server/grpc/p2pool.rs index 8e1a5712..b0fd3212 100644 --- a/src/server/grpc/p2pool.rs +++ b/src/server/grpc/p2pool.rs @@ -193,13 +193,13 @@ where S: ShareChain .await .map_err(|error| Status::internal(format!("failed to get new tip block {error:?}")))?) .clone(); - dbg!(&new_tip_block.height, &new_tip_block.hash); + // dbg!(&new_tip_block.height, &new_tip_block.hash); let shares = share_chain .generate_shares(&new_tip_block) .await .map_err(|error| Status::internal(format!("failed to generate shares {error:?}")))?; - dbg!(&shares); + // dbg!(&shares); let mut response = self .client diff --git a/src/server/p2p/network.rs b/src/server/p2p/network.rs index 9dca6bac..f7500ebe 100644 --- a/src/server/p2p/network.rs +++ b/src/server/p2p/network.rs @@ -641,14 +641,14 @@ where S: ShareChain // Don't add unless we've already synced. - info!(target: LOG_TARGET, squad = &self.config.squad; "🆕 New block from broadcast: {:?}", &payload.new_blocks.iter().map(|b| b.0.to_string()).join(",")); + debug!(target: LOG_TARGET, squad = &self.config.squad; "🆕 New block from broadcast: {:?}", &payload.new_blocks.iter().map(|b| b.0.to_string()).join(",")); let algo = payload.algo(); let share_chain = match algo { PowAlgorithm::RandomX => self.share_chain_random_x.clone(), PowAlgorithm::Sha3x => self.share_chain_sha3x.clone(), }; if share_chain.tip_height().await.unwrap_or_default() == 0 { - warn!(target: LOG_TARGET, squad = &self.config.squad; "Share chain tip height is None, skipping block until we have synced"); + debug!(target: LOG_TARGET, squad = &self.config.squad; "Share chain tip height is None, skipping block until we have synced"); return; } let mut missing_blocks = vec![]; @@ -907,7 +907,7 @@ where S: ShareChain } if !self.network_peer_store.is_whitelisted(&peer) { - warn!(target: LOG_TARGET, squad = &self.config.squad; "Peer is not whitelisted, will still try to sync"); + debug!(target: LOG_TARGET, squad = &self.config.squad; "Peer is not whitelisted, will still try to sync"); // return; } diff --git a/src/sharechain/p2chain.rs b/src/sharechain/p2chain.rs index a295037e..60a36dc4 100644 --- a/src/sharechain/p2chain.rs +++ b/src/sharechain/p2chain.rs @@ -26,7 +26,7 @@ use std::{ sync::Arc, }; -use log::info; +use log::{debug, info}; use tari_common_types::types::FixedHash; use tari_core::proof_of_work::{lwma_diff::LinearWeightedMovingAverage, AccumulatedDifficulty, Difficulty}; @@ -171,19 +171,32 @@ impl P2Chain { } fn verify_chain(&mut self, new_block_height: u64, hash: FixedHash) -> Result<(), Error> { - let missing_parents = vec![]; - match self.verify_chain_inner(missing_parents, new_block_height, hash, 0) { - Ok((missing_parents, do_next_level)) => { - if !missing_parents.is_empty() { - return Err(Error::BlockParentDoesNotExist { missing_parents }); - } - if let Some((height, hash)) = do_next_level { - self.verify_chain_inner(vec![], height, hash, 0)?; - } - Ok(()) - }, - Err(e) => Err(e), + let mut next_level = Some((new_block_height, hash)); + let mut missing_parents = vec![]; + while let Some((next_height, next_hash)) = next_level { + let missing_parents2 = vec![]; + + match self.verify_chain_inner(missing_parents2, next_height, next_hash, 0) { + Ok((missing_parents2, do_next_level)) => { + if !missing_parents2.is_empty() { + missing_parents.extend_from_slice(&missing_parents2); + // return Err(Error::BlockParentDoesNotExist { + // missing_parents: missing_parents2, + // }); + } + next_level = do_next_level; + // if let Some((height, hash)) = do_next_level { + // self.verify_chain_inner(vec![], height, hash, 0)?; + // } + }, + Err(e) => return Err(e), + } } + if !missing_parents.is_empty() { + return Err(Error::BlockParentDoesNotExist { missing_parents }); + } + + Ok(()) } fn verify_chain_inner( @@ -193,8 +206,8 @@ impl P2Chain { hash: FixedHash, recursion_depth: usize, ) -> Result<(Vec<(u64, FixedHash)>, Option<(u64, FixedHash)>), Error> { - dbg!("Verify chain", new_block_height); - dbg!(recursion_depth); + // dbg!("Verify chain", new_block_height); + // dbg!(recursion_depth); // we should validate what we can if a block is invalid, we should delete it. // let mut missing_parents = Vec::new(); let block = self @@ -265,7 +278,7 @@ impl P2Chain { info!(target: LOG_TARGET, "[{:?}] Block building on tip: {:?}", algo, new_block_height); self.set_new_tip(new_block_height, hash)?; } else { - info!(target: LOG_TARGET, "[{:?}] Block is not building on tip: {:?}", algo, new_block_height); + debug!(target: LOG_TARGET, "[{:?}] Block is not building on tip: {:?}", algo, new_block_height); // lets check if we need to reorg here let block = self .get_block_at_height(new_block_height, &hash) @@ -386,7 +399,7 @@ impl P2Chain { } } if let Some(next_level) = next_level_data { - info!(target: LOG_TARGET, "[{:?}] Found block building on top of block: {:?}", algo, new_block_height); + debug!(target: LOG_TARGET, "[{:?}] Found block building on top of block: {:?}", algo, new_block_height); // we have a parent here return Ok((missing_parents, Some(next_level))); } From c26315a4f485e91004ec6e07e86b131315d4cb7a Mon Sep 17 00:00:00 2001 From: stringhandler Date: Wed, 23 Oct 2024 11:48:50 +0200 Subject: [PATCH 4/5] simplify code --- src/sharechain/p2chain.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/sharechain/p2chain.rs b/src/sharechain/p2chain.rs index 60a36dc4..b4a2aa76 100644 --- a/src/sharechain/p2chain.rs +++ b/src/sharechain/p2chain.rs @@ -174,9 +174,7 @@ impl P2Chain { let mut next_level = Some((new_block_height, hash)); let mut missing_parents = vec![]; while let Some((next_height, next_hash)) = next_level { - let missing_parents2 = vec![]; - - match self.verify_chain_inner(missing_parents2, next_height, next_hash, 0) { + match self.verify_chain_inner(next_height, next_hash, 0) { Ok((missing_parents2, do_next_level)) => { if !missing_parents2.is_empty() { missing_parents.extend_from_slice(&missing_parents2); @@ -201,7 +199,6 @@ impl P2Chain { fn verify_chain_inner( &mut self, - mut missing_parents: Vec<(u64, FixedHash)>, new_block_height: u64, hash: FixedHash, recursion_depth: usize, @@ -209,7 +206,7 @@ impl P2Chain { // dbg!("Verify chain", new_block_height); // dbg!(recursion_depth); // we should validate what we can if a block is invalid, we should delete it. - // let mut missing_parents = Vec::new(); + let mut missing_parents = Vec::new(); let block = self .get_block_at_height(new_block_height, &hash) .ok_or(Error::BlockNotFound)? From e1caf9619c71d856bf4cd0a40acc2fa0a80813f3 Mon Sep 17 00:00:00 2001 From: stringhandler Date: Wed, 23 Oct 2024 12:13:52 +0200 Subject: [PATCH 5/5] add debugging --- src/server/p2p/network.rs | 6 +++++- src/sharechain/in_memory.rs | 15 ++++++++++++++- src/sharechain/mod.rs | 3 +++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/server/p2p/network.rs b/src/server/p2p/network.rs index f7500ebe..e75a5454 100644 --- a/src/server/p2p/network.rs +++ b/src/server/p2p/network.rs @@ -1420,8 +1420,12 @@ where S: ShareChain .open(format!("{}_blocks_{}.txt", prefix, time)) .unwrap(); - file.write(b"@startuml\n").unwrap(); + // file.write(b"@startuml\n").unwrap(); file.write(b"digraph B {\n").unwrap(); + if let Some(tip) = chain.get_tip().await.unwrap() { + file.write(&format!("comment=\"{} - {}\"\n", tip.0, &tip.1.to_hex()[0..8]).into_bytes()) + .unwrap(); + } let blocks = chain.all_blocks().await.expect("errored"); for b in blocks { file.write( diff --git a/src/sharechain/in_memory.rs b/src/sharechain/in_memory.rs index 447b44b5..8de5dcbe 100644 --- a/src/sharechain/in_memory.rs +++ b/src/sharechain/in_memory.rs @@ -62,7 +62,10 @@ impl InMemoryShareChain { } Ok(Self { - p2_chain: Box::new(Arc::new(RwLock::new(P2Chain::new_empty(MAX_BLOCKS_COUNT, SHARE_WINDOW)))), + p2_chain: Box::new(Arc::new(RwLock::new(P2Chain::new_empty( + MAX_BLOCKS_COUNT, + SHARE_WINDOW, + )))), pow_algo, block_validation_params, consensus_manager, @@ -354,6 +357,16 @@ impl ShareChain for InMemoryShareChain { Ok(tip_level) } + async fn get_tip(&self) -> Result, Error> { + let bl = self.p2_chain.read().await; + let tip_level = bl.get_tip(); + if let Some(tip_level) = tip_level { + Ok(Some((tip_level.height, tip_level.chain_block))) + } else { + Ok(None) + } + } + async fn generate_shares(&self, new_tip_block: &P2Block) -> Result, Error> { let mut chain_read_lock = self.p2_chain.read().await; // first check if there is a cached hashmap of shares diff --git a/src/sharechain/mod.rs b/src/sharechain/mod.rs index 9639072f..6789b59c 100644 --- a/src/sharechain/mod.rs +++ b/src/sharechain/mod.rs @@ -106,6 +106,9 @@ pub(crate) trait ShareChain: Send + Sync + 'static { /// Returns the tip of height in chain (from original Tari block header) async fn tip_height(&self) -> Result; + /// Returns the tip of the chain. + async fn get_tip(&self) -> Result, Error>; + /// Generate shares based on the previous blocks. async fn generate_shares(&self, new_tip_block: &P2Block) -> Result, Error>;