Skip to content

Commit

Permalink
1, use match to determine the way of the execution and verification
Browse files Browse the repository at this point in the history
2, return test message in apply failed function
  • Loading branch information
jackzhhuang committed Jun 11, 2024
1 parent 7cd0053 commit 5b35308
Show file tree
Hide file tree
Showing 9 changed files with 64 additions and 80 deletions.
5 changes: 1 addition & 4 deletions chain/api/src/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,7 @@ pub trait ChainReader {
access_path: Option<AccessPath>,
) -> Result<Option<TransactionInfoWithProof>>;

fn current_tips_hash(
&self,
header: &BlockHeader,
) -> Result<Option<(HashValue, Vec<HashValue>)>>;
fn current_tips_hash(&self) -> Result<Option<(HashValue, Vec<HashValue>)>>;
fn has_dag_block(&self, header_id: HashValue) -> Result<bool>;
fn check_dag_type(&self) -> Result<DagHeaderType>;
}
Expand Down
5 changes: 2 additions & 3 deletions chain/service/src/chain_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -451,11 +451,10 @@ impl ReadableChainService for ChainReaderServiceInner {
}

fn get_dag_state(&self) -> Result<DagStateView> {
let head = self.main.current_header();
if self.main.check_dag_type()? != DagHeaderType::Normal {
bail!("The current chain is not a dag chain.");
bail!("The dag block is not built yet.");
}
let (dag_genesis, state) = self.main.get_dag_state_by_block(&head)?;
let (dag_genesis, state) = self.main.get_dag_state_by_block()?;
Ok(DagStateView {
dag_genesis,
tips: state.tips,
Expand Down
83 changes: 29 additions & 54 deletions chain/src/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

use crate::verifier::{BlockVerifier, DagBasicVerifier, DagVerifier, FullVerifier};
use anyhow::{anyhow, bail, ensure, format_err, Ok, Result};
use bcs_ext::BCSCodec;
use once_cell::sync::Lazy;
use sp_utils::stop_watch::{watch, CHAIN_WATCH_NAME};
use starcoin_accumulator::inmemory::InMemoryAccumulator;
Expand Down Expand Up @@ -48,7 +47,6 @@ use starcoin_vm_types::account_config::genesis_address;
use starcoin_vm_types::genesis_config::{ChainId, ConsensusStrategy};
use starcoin_vm_types::on_chain_resource::Epoch;
use std::cmp::min;
use std::collections::HashSet;
use std::iter::Extend;
use std::option::Option::{None, Some};
use std::sync::atomic::{AtomicBool, Ordering};
Expand Down Expand Up @@ -856,7 +854,7 @@ impl BlockChain {
tips
} else {
let (_dag_genesis, tips_hash) = self
.current_tips_hash(&previous_header)?
.current_tips_hash()?
.ok_or_else(|| {
anyhow!(
"the number of the block is larger than the dag fork number but no dag state!"
Expand Down Expand Up @@ -984,10 +982,11 @@ impl BlockChain {
self.vm_metrics.clone(),
self.dag.clone(),
)?;
if selected_chain.check_dag_type()? == DagHeaderType::Normal {
V::verify_block(&selected_chain, block)
} else {
V::verify_block(self, block)
match selected_chain.check_dag_type()? {
DagHeaderType::Single => V::verify_block(self, block),
DagHeaderType::Genesis | DagHeaderType::Normal => {
V::verify_block(&selected_chain, block)
}
}
}

Expand Down Expand Up @@ -1020,30 +1019,7 @@ impl BlockChain {
self.connect(ExecutedBlock { block, block_info })
}

fn check_parents_coherent(&self, header: &BlockHeader) -> Result<HashValue> {
if self.check_dag_type()? != DagHeaderType::Normal {
bail!("Block is not a dag block.");
}

let results = header.parents_hash().ok_or_else(|| anyhow!("dag block has no parents."))?.into_iter().map(|parent_hash| {
let header = self.storage.get_block_header_by_hash(parent_hash)?.ok_or_else(|| anyhow!("failed to find the block header in the block storage when checking the dag block exists, block hash: {:?}, number: {:?}", header.id(), header.number()))?;
let dag_genesis_hash = self.get_block_dag_genesis(&header)?;
let dag_genesis = self.storage.get_block_header_by_hash(dag_genesis_hash)?.ok_or_else(|| anyhow!("failed to find the block header in the block storage when checking the dag block exists, block hash: {:?}, number: {:?}", header.id(), header.number()))?;
Ok(dag_genesis.parent_hash())
}).collect::<Result<HashSet<_>>>()?;

if results.len() == 1 {
Ok(results
.into_iter()
.next()
.expect("the len of the results is larger than 1 but no the first elemen!"))
} else {
bail!("dag block: {:?}, number: {:?} has multiple parents whose dags are not the same one! Their dag genesis are: {:?}", header.id(), header.number(), results);
}
}

fn execute_dag_block(&mut self, verified_block: VerifiedBlock) -> Result<ExecutedBlock> {
let origin = self.check_parents_coherent(verified_block.0.header())?;
info!("execute dag block:{:?}", verified_block.0);
let block = verified_block.0;
let selected_parent = block.parent_hash();
Expand Down Expand Up @@ -1239,7 +1215,9 @@ impl BlockChain {
self.storage.save_block_info(block_info.clone())?;

self.storage.save_table_infos(txn_table_infos)?;
let result = self.dag.commit(header.to_owned(), origin);
let result = self
.dag
.commit(header.to_owned(), self.get_block_dag_origin()?);
match result {
anyhow::Result::Ok(_) => (),
Err(e) => {
Expand Down Expand Up @@ -1723,7 +1701,8 @@ impl BlockChain {
Ok(())
}

pub fn get_block_dag_genesis(&self, header: &BlockHeader) -> Result<HashValue> {
pub fn get_block_dag_genesis(&self) -> Result<HashValue> {
let header = self.status().head().clone();
let net: BuiltinNetworkID = header.chain_id().try_into()?;
let dag_fork_height = net.genesis_config().dag_effective_height;
if header.number() < dag_fork_height {
Expand All @@ -1746,19 +1725,16 @@ impl BlockChain {
}

pub fn get_block_dag_origin(&self) -> Result<HashValue> {
let dag_genesis = self.get_block_dag_genesis(&self.current_header())?;
let dag_genesis = self.get_block_dag_genesis()?;
let block_header = self
.storage
.get_block_header_by_hash(dag_genesis)?
.ok_or_else(|| anyhow!("Cannot find block by hash {:?}", dag_genesis))?;

Ok(HashValue::sha3_256_of(
&[block_header.parent_hash(), block_header.id()].encode()?,
))
Ok(block_header.parent_hash())
}

pub fn get_dag_state_by_block(&self, header: &BlockHeader) -> Result<(HashValue, DagState)> {
let dag_genesis = self.get_block_dag_genesis(header)?;
pub fn get_dag_state_by_block(&self) -> Result<(HashValue, DagState)> {
let dag_genesis = self.get_block_dag_genesis()?;
Ok((dag_genesis, self.dag.get_dag_state(dag_genesis)?))
}
}
Expand Down Expand Up @@ -1992,11 +1968,12 @@ impl ChainReader for BlockChain {
}

fn verify(&self, block: Block) -> Result<VerifiedBlock> {
if self.check_dag_type()? == DagHeaderType::Normal {
DagBasicVerifier::verify_header(self, block.header())?;
Ok(VerifiedBlock(block))
} else {
FullVerifier::verify_block(self, block)
match self.check_dag_type()? {
DagHeaderType::Single => FullVerifier::verify_block(self, block),
DagHeaderType::Genesis | DagHeaderType::Normal => {
DagBasicVerifier::verify_header(self, block.header())?;
Ok(VerifiedBlock(block))
}
}
}

Expand Down Expand Up @@ -2146,11 +2123,8 @@ impl ChainReader for BlockChain {
}))
}

fn current_tips_hash(
&self,
header: &BlockHeader,
) -> Result<Option<(HashValue, Vec<HashValue>)>> {
let (dag_genesis, dag_state) = self.get_dag_state_by_block(header)?;
fn current_tips_hash(&self) -> Result<Option<(HashValue, Vec<HashValue>)>> {
let (dag_genesis, dag_state) = self.get_dag_state_by_block()?;
Ok(Some((dag_genesis, dag_state.tips)))
}

Expand Down Expand Up @@ -2317,7 +2291,7 @@ impl BlockChain {
let dag = self.dag.clone();
let (new_tip_block, _) = (executed_block.block(), executed_block.block_info());
let (dag_genesis, mut tips) = self
.current_tips_hash(new_tip_block.header())?
.current_tips_hash()?
.expect("tips should exists in dag");
let parents = executed_block
.block
Expand Down Expand Up @@ -2429,10 +2403,11 @@ impl ChainWriter for BlockChain {
}

fn apply(&mut self, block: Block) -> Result<ExecutedBlock> {
if self.check_dag_type()? == DagHeaderType::Single {
self.apply_with_verifier::<FullVerifier>(block)
} else {
self.apply_with_verifier::<DagVerifier>(block)
match self.check_dag_type()? {
DagHeaderType::Single => self.apply_with_verifier::<FullVerifier>(block),
DagHeaderType::Genesis | DagHeaderType::Normal => {
self.apply_with_verifier::<DagVerifier>(block)
}
}
}

Expand Down
4 changes: 4 additions & 0 deletions config/src/genesis_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,10 @@ impl BuiltinNetworkID {
matches!(self, BuiltinNetworkID::Halley)
}

pub fn is_dag_test(self) -> bool {
matches!(self, BuiltinNetworkID::DagTest)
}

pub fn networks() -> Vec<BuiltinNetworkID> {
vec![
BuiltinNetworkID::Test,
Expand Down
2 changes: 1 addition & 1 deletion config/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ fn test_example_config_compact() -> Result<()> {
#[test]
fn test_genesis_config_security() {
for net in BuiltinNetworkID::networks() {
if net.is_dev() || net.is_test() {
if net.is_dev() || net.is_test() || net.is_dag_test() {
continue;
}
let genesis_config = net.genesis_config().clone();
Expand Down
9 changes: 3 additions & 6 deletions miner/src/create_block_template/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -359,14 +359,11 @@ where
}
let difficulty = strategy.calculate_next_difficulty(&self.chain)?;
let tips_hash = if self.chain.check_dag_type()? == DagHeaderType::Normal {
let (_dag_genesis, tips_hash) = self
.chain
.current_tips_hash(&previous_header)?
.ok_or_else(|| {
anyhow!(
let (_dag_genesis, tips_hash) = self.chain.current_tips_hash()?.ok_or_else(|| {
anyhow!(
"the number of the block is larger than the dag fork number but no dag state!"
)
})?;
})?;
Some(tips_hash)
} else {
None
Expand Down
2 changes: 1 addition & 1 deletion sync/src/block_connector/test_write_dag_block_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ pub fn new_dag_block(

let block_chain = writeable_block_chain_service.get_main();
let (_dag_genesis, tips) = block_chain
.current_tips_hash(&block_chain.current_header())
.current_tips_hash()
.expect("failed to get tips")
.expect("failed to get the tip and dag genesis");
let (block_template, _) = block_chain
Expand Down
22 changes: 15 additions & 7 deletions sync/src/block_connector/write_block_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,14 +240,22 @@ where

#[cfg(test)]
pub fn apply_failed(&mut self, block: Block) -> Result<()> {
use starcoin_chain::verifier::FullVerifier;
use anyhow::bail;
use starcoin_chain::verifier::{DagBasicVerifier, FullVerifier};

// apply but no connection
let verified_block = self.main.verify_with_verifier::<FullVerifier>(block)?;
let executed_block = self.main.execute(verified_block)?;
let enacted_blocks = vec![executed_block.block().clone()];
self.do_new_head(executed_block, 1, enacted_blocks, 0, vec![])?;
Ok(())
let verified_block = match self.main.check_dag_type()? {
starcoin_types::block::DagHeaderType::Single => {
// apply but no connection
self.main.verify_with_verifier::<FullVerifier>(block)?
}
starcoin_types::block::DagHeaderType::Genesis
| starcoin_types::block::DagHeaderType::Normal => {
// apply but no connection
self.main.verify_with_verifier::<DagBasicVerifier>(block)?
}
};
let _executed_block = self.main.execute(verified_block)?;
bail!("In test case, return a failure intentionally to force sync to reconnect the block");
}

// for sync task to connect to its chain, if chain's total difficulties is larger than the main
Expand Down
12 changes: 8 additions & 4 deletions sync/src/tasks/tests_dag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use futures::channel::mpsc::unbounded;
use starcoin_chain_api::ChainReader;
use starcoin_logger::prelude::*;
use starcoin_service_registry::{RegistryAsyncService, RegistryService, ServiceRef};
use starcoin_storage::BlockStore;
use starcoin_txpool_mock_service::MockTxPoolService;
use test_helper::DummyNetworkService;

Expand Down Expand Up @@ -91,11 +92,14 @@ async fn test_sync_dag_blocks() -> Result<()> {
.unwrap()
.produce_block(count)
.expect("failed to produce block");
let dag_genesis_header = target_node.chain().status().head;
let dag_genesis_header_id = target_node.chain().get_block_dag_genesis()?;
let dag_genesis_header = target_node
.get_storage()
.get_block_header_by_hash(dag_genesis_header_id)?
.ok_or_else(|| format_err!("dag genesis header should exist."))?;
assert!(
dag_genesis_header.number() == count,
"dag genesis header number should be {}, but {}",
count,
dag_genesis_header.number() == 0,
"dag genesis header number should be 0, but {:?}",
dag_genesis_header.number()
);

Expand Down

0 comments on commit 5b35308

Please sign in to comment.