diff --git a/chain/api/src/chain.rs b/chain/api/src/chain.rs index 4249859727..d9f22746cd 100644 --- a/chain/api/src/chain.rs +++ b/chain/api/src/chain.rs @@ -113,19 +113,10 @@ pub trait ChainReader { pub trait ChainWriter { fn can_connect(&self, executed_block: &ExecutedBlock) -> bool; /// Connect a executed block to current chain. - fn connect( - &mut self, - executed_block: ExecutedBlock, - next_tips: &mut Option>, - ) -> Result; + fn connect(&mut self, executed_block: ExecutedBlock) -> Result; /// Verify, Execute and Connect block to current chain. - fn apply( - &mut self, - block: Block, - dag_block_next_parent: Option, - next_tips: &mut Option>, - ) -> Result; + fn apply(&mut self, block: Block) -> Result; fn chain_state(&mut self) -> &ChainStateDB; diff --git a/chain/src/chain.rs b/chain/src/chain.rs index a957515ceb..858b19cd83 100644 --- a/chain/src/chain.rs +++ b/chain/src/chain.rs @@ -13,6 +13,7 @@ use starcoin_chain_api::{ verify_block, ChainReader, ChainWriter, ConnectBlockError, EventWithProof, ExcludedTxns, ExecutedBlock, MintedUncleNumber, TransactionInfoWithProof, VerifiedBlock, VerifyBlockField, }; +use starcoin_consensus::dag::types::ghostdata::GhostdagData; use starcoin_consensus::{BlockDAG, Consensus, FlexiDagStorage}; use starcoin_crypto::hash::PlainCryptoHash; use starcoin_crypto::HashValue; @@ -47,7 +48,6 @@ use std::cmp::min; use std::iter::Extend; use std::option::Option::{None, Some}; use std::{collections::HashMap, sync::Arc}; -use starcoin_consensus::dag::types::ghostdata::GhostdagData; pub struct ChainStatusWithBlock { pub status: ChainStatus, @@ -365,26 +365,21 @@ impl BlockChain { } pub fn verify_with_verifier(&mut self, block: Block) -> Result - where - V: BlockVerifier, + where + V: BlockVerifier, { V::verify_block(self, block) } - pub fn apply_with_verifier( - &mut self, - block: Block, - dag_block_parent: Option, - next_tips: &mut Option>, - ) -> Result - where - V: BlockVerifier, + pub fn apply_with_verifier(&mut self, block: Block) -> Result + where + V: BlockVerifier, { let verified_block = self.verify_with_verifier::(block)?; watch(CHAIN_WATCH_NAME, "n1"); - let executed_block = self.execute(verified_block, dag_block_parent)?; + let executed_block = self.execute(verified_block)?; watch(CHAIN_WATCH_NAME, "n2"); - self.connect(executed_block, next_tips) + self.connect(executed_block) } //TODO remove this function. @@ -416,7 +411,6 @@ impl BlockChain { epoch: &Epoch, parent_status: Option, block: Block, - dag_block_parent: Option, vm_metrics: Option, ) -> Result { let header = block.header(); @@ -428,8 +422,7 @@ impl BlockChain { let mut t = match &parent_status { None => vec![], Some(parent) => { - let block_metadata = - block.to_metadata(parent.head().gas_used(), dag_block_parent); + let block_metadata = block.to_metadata(parent.head().gas_used()); vec![Transaction::BlockMetadata(block_metadata)] } }; @@ -654,9 +647,9 @@ impl BlockChain { return Ok(next_tips_info == self - .dag_accumulator - .as_ref() - .map(|accumulator| accumulator.get_info())); + .dag_accumulator + .as_ref() + .map(|accumulator| accumulator.get_info())); } } @@ -915,11 +908,7 @@ impl ChainReader for BlockChain { FullVerifier::verify_block(self, block) } - fn execute( - &self, - verified_block: VerifiedBlock, - dag_block_parent: Option, - ) -> Result { + fn execute(&self, verified_block: VerifiedBlock) -> Result { Self::execute_block_and_save( self.storage.as_ref(), self.statedb.fork(), @@ -928,7 +917,6 @@ impl ChainReader for BlockChain { &self.epoch, Some(self.status.status.clone()), verified_block.0, - dag_block_parent, self.vm_metrics.clone(), ) } @@ -1148,15 +1136,11 @@ impl ChainWriter for BlockChain { .expect("dag blocks must have tips") .clone(), ) - .expect("failed to calculate the tips hash") + .expect("failed to calculate the tips hash") == executed_block.block().header().parent_hash(); } } - fn connect( - &mut self, - executed_block: ExecutedBlock, - next_tips: &mut Option>, - ) -> Result { + fn connect(&mut self, executed_block: ExecutedBlock) -> Result { let (block, block_info) = (executed_block.block(), executed_block.block_info()); if self.status.status.tips_hash.is_some() { let mut tips = self.status.status.tips_hash.clone().unwrap(); @@ -1184,20 +1168,18 @@ impl ChainWriter for BlockChain { ); self.statedb = ChainStateDB::new(self.storage.clone().into_super_arc(), Some(state_root)); - match next_tips { - Some(tips) => { + let tips = self.status.status.tips_hash.clone(); + let next_tips = match tips { + Some(mut tips) => { if !tips.contains(&block.header().id()) { - tips.push(block.header().id()) + tips.push(block.header().id()); } + Some(tips) } - None => (), - } + None => None, + }; self.status = ChainStatusWithBlock { - status: ChainStatus::new( - block.header().clone(), - block_info.clone(), - next_tips.clone(), - ), + status: ChainStatus::new(block.header().clone(), block_info.clone(), next_tips), head: block.clone(), }; if self.epoch.end_block_number() == block.header().number() { @@ -1212,13 +1194,8 @@ impl ChainWriter for BlockChain { Ok(executed_block) } - fn apply( - &mut self, - block: Block, - dag_block_next_parent: Option, - next_tips: &mut Option>, - ) -> Result { - self.apply_with_verifier::(block, dag_block_next_parent, next_tips) + fn apply(&mut self, block: Block) -> Result { + self.apply_with_verifier::(block) } fn chain_state(&mut self) -> &ChainStateDB { diff --git a/cmd/db-exporter/src/verify_header.rs b/cmd/db-exporter/src/verify_header.rs index 900e4bb71f..b49baffcdc 100644 --- a/cmd/db-exporter/src/verify_header.rs +++ b/cmd/db-exporter/src/verify_header.rs @@ -48,4 +48,4 @@ impl BatchCmdExec for Block { } } } -} \ No newline at end of file +} diff --git a/consensus/src/dag/blockdag.rs b/consensus/src/dag/blockdag.rs index 9487158d3c..e23c8d1d00 100644 --- a/consensus/src/dag/blockdag.rs +++ b/consensus/src/dag/blockdag.rs @@ -119,7 +119,7 @@ impl BlockDAG { let _ = self .header_store .insert(header.hash(), Arc::new(header.to_owned()), 0)?; - return Ok(ghostdag_data.clone()) + return Ok(ghostdag_data.clone()); } fn is_in_dag(&self, _hash: Hash) -> anyhow::Result { @@ -160,9 +160,9 @@ impl BlockDAG { } return Ok(true); } - pub fn get_ghostdag_data(&self, hash: Hash)->anyhow::Result>{ + pub fn get_ghostdag_data(&self, hash: Hash) -> anyhow::Result> { let ghostdata = self.ghostdag_store.get_data(hash)?; - return Ok(ghostdata) + return Ok(ghostdata); } fn update_orphans(&mut self, block_header: &DagHeader) -> anyhow::Result { diff --git a/sync/src/block_connector/write_block_chain.rs b/sync/src/block_connector/write_block_chain.rs index f40a60773b..9f0761794b 100644 --- a/sync/src/block_connector/write_block_chain.rs +++ b/sync/src/block_connector/write_block_chain.rs @@ -2,6 +2,9 @@ // SPDX-License-Identifier: Apache-2.0 use crate::block_connector::metrics::ChainMetrics; +use crate::block_connector::write_block_chain::ConnectOk::{ + DagConnectMissingBlock, DagConnected, ExeConnectMain, +}; use anyhow::{bail, format_err, Ok, Result}; use async_std::stream::StreamExt; use starcoin_chain::BlockChain; @@ -11,6 +14,7 @@ use starcoin_consensus::dag::ghostdag::protocol::ColoringOutput; use starcoin_consensus::BlockDAG; use starcoin_crypto::HashValue; use starcoin_executor::VMMetrics; +use starcoin_logger::prelude::Level::Error; use starcoin_logger::prelude::*; use starcoin_service_registry::bus::{Bus, BusService}; use starcoin_service_registry::ServiceRef; @@ -20,6 +24,7 @@ use starcoin_time_service::{DagBlockTimeWindowService, TimeWindowResult}; use starcoin_txpool_api::TxPoolSyncService; use starcoin_types::block::BlockInfo; use starcoin_types::blockhash::BlockHashMap; +use starcoin_types::header::DagHeader; use starcoin_types::{ block::{Block, BlockHeader, ExecutedBlock}, startup_info::StartupInfo, @@ -27,14 +32,12 @@ use starcoin_types::{ }; use std::fmt::Formatter; use std::sync::{Arc, Mutex}; -use starcoin_types::header::DagHeader; -use crate::block_connector::write_block_chain::ConnectOk::{DagConnected, ExeConnectMain}; const MAX_ROLL_BACK_BLOCK: usize = 10; pub struct WriteBlockChainService

- where - P: TxPoolSyncService, +where + P: TxPoolSyncService, { config: Arc, startup_info: StartupInfo, @@ -64,6 +67,7 @@ pub enum ConnectOk { MainDuplicate, // the dag block waiting for the time window end DagPending, + DagConnectMissingBlock, } impl ConnectOk { @@ -94,8 +98,8 @@ impl std::fmt::Display for ConnectOk { } impl

WriteableChainService for WriteBlockChainService

- where - P: TxPoolSyncService + 'static, +where + P: TxPoolSyncService + 'static, { fn try_connect(&mut self, block: Block, tips_headers: Option>) -> Result<()> { let _timer = self @@ -126,8 +130,8 @@ impl

WriteableChainService for WriteBlockChainService

} impl

WriteBlockChainService

- where - P: TxPoolSyncService + 'static, +where + P: TxPoolSyncService + 'static, { pub fn new( config: Arc, @@ -149,7 +153,6 @@ impl

WriteBlockChainService

.metrics .registry() .and_then(|registry| ChainMetrics::register(registry).ok()); - Ok(Self { config, startup_info, @@ -793,15 +796,29 @@ impl

WriteBlockChainService

return Ok(ConnectOk::ExeConnectMain(executed_block)); } - fn connect_dag_inner(&mut self, block: Block, parents_hash: Vec, + fn connect_dag_inner( + &mut self, + block: Block, + parents_hash: Vec, ) -> Result { - let ghost_dag_data = self.dag.lock().unwrap().addToDag(DagHeader::new(block.header, parents_hash))?; - let past_header = ghost_dag_data.selected_parent; - let mut chain = self.main.fork(past_header)?; - for blue_hash in ghost_dag_data.mergeset_blues{ - chain.apply(blue_hash); + let ghost_dag_data = self + .dag + .lock() + .unwrap() + .addToDag(DagHeader::new(block.header, parents_hash))?; + let selected_parent = self + .storage + .get_block_by_hash(ghost_dag_data.selected_parent)? + .expect("selected parent should in storage"); + let mut chain = self.main.fork(selected_parent.header.parent_hash())?; + for blue_hash in ghost_dag_data.mergeset_blues.iter() { + if let Some(blue_block) = self.storage.get_block(blue_hash.to_owned())? { + chain.apply(blue_block); + } else { + error!("Failed to get block {:?}", blue_hash); + return Ok(DagConnectMissingBlock); + } } - //self.broadcast_new_head(); Ok(DagConnected) } diff --git a/types/src/block.rs b/types/src/block.rs index 2d5b11bfae..f31b654480 100644 --- a/types/src/block.rs +++ b/types/src/block.rs @@ -718,21 +718,15 @@ impl Block { } } - pub fn to_metadata( - &self, - parent_gas_used: u64, - dag_block_parent: Option, - ) -> BlockMetadata { + pub fn to_metadata(&self, parent_gas_used: u64) -> BlockMetadata { let uncles = self .body .uncles .as_ref() .map(|uncles| uncles.len() as u64) .unwrap_or(0); - - let parent = dag_block_parent.unwrap_or(self.header.parent_hash()); BlockMetadata::new( - parent, + self.header.parent_hash(), self.header.timestamp, self.header.author, self.header.author_auth_key,