Skip to content

Commit

Permalink
Merge 7d535d6 into 85564ab
Browse files Browse the repository at this point in the history
  • Loading branch information
jackzhhuang authored Sep 5, 2024
2 parents 85564ab + 7d535d6 commit 04a586b
Show file tree
Hide file tree
Showing 22 changed files with 1,254 additions and 165 deletions.
14 changes: 13 additions & 1 deletion chain/api/src/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

use anyhow::Result;
use starcoin_crypto::HashValue;
use starcoin_dag::types::ghostdata::GhostdagData;
use starcoin_state_api::ChainStateReader;
use starcoin_statedb::ChainStateDB;
use starcoin_time_service::TimeService;
Expand All @@ -22,7 +23,10 @@ pub use starcoin_types::block::ExecutedBlock;
use starcoin_vm_types::access_path::AccessPath;
use starcoin_vm_types::contract_event::ContractEvent;

pub struct VerifiedBlock(pub Block);
pub struct VerifiedBlock {
pub block: Block,
pub ghostdata: Option<GhostdagData>,
}
pub type MintedUncleNumber = u64;

pub trait ChainReader {
Expand Down Expand Up @@ -105,6 +109,11 @@ pub trait ChainReader {
fn current_tips_hash(&self) -> Result<Vec<HashValue>>;
fn has_dag_block(&self, header_id: HashValue) -> Result<bool>;
fn check_chain_type(&self) -> Result<ChainType>;
fn verify_and_ghostdata(
&self,
uncles: &[BlockHeader],
header: &BlockHeader,
) -> Result<GhostdagData>;
}

pub trait ChainWriter {
Expand All @@ -115,6 +124,9 @@ pub trait ChainWriter {
/// Verify, Execute and Connect block to current chain.
fn apply(&mut self, block: Block) -> Result<ExecutedBlock>;

/// Verify, Execute and Connect block to current chain.
fn apply_for_sync(&mut self, block: Block) -> Result<ExecutedBlock>;

fn chain_state(&mut self) -> &ChainStateDB;
}

Expand Down
36 changes: 27 additions & 9 deletions chain/src/chain.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) The Starcoin Core Contributors
// SPDX-License-Identifier: Apache-2.0

use crate::verifier::{BlockVerifier, DagVerifier, FullVerifier};
use crate::verifier::{BlockVerifier, DagVerifier, DagVerifierWithGhostData, FullVerifier};
use anyhow::{bail, ensure, format_err, Ok, Result};
use sp_utils::stop_watch::{watch, CHAIN_WATCH_NAME};
use starcoin_accumulator::inmemory::InMemoryAccumulator;
Expand Down Expand Up @@ -458,8 +458,8 @@ impl BlockChain {
}

fn execute_dag_block(&mut self, verified_block: VerifiedBlock) -> Result<ExecutedBlock> {
info!("execute dag block:{:?}", verified_block.0);
let block = verified_block.0;
info!("execute dag block:{:?}", verified_block.block);
let block = verified_block.block;
let selected_parent = block.parent_hash();
let block_info_past = self
.storage
Expand Down Expand Up @@ -645,9 +645,16 @@ impl BlockChain {
.storage
.get_block_header_by_hash(self.genesis_hash)?
.ok_or_else(|| format_err!("failed to get genesis because it is none"))?;
let result = self
.dag
.commit(header.to_owned(), genesis_header.parent_hash());
let result = match verified_block.ghostdata {
Some(trusted_ghostdata) => self.dag.commit_trusted_block(
header.to_owned(),
genesis_header.parent_hash(),
Arc::new(trusted_ghostdata),
),
None => self
.dag
.commit(header.to_owned(), genesis_header.parent_hash()),
};
match result {
anyhow::Result::Ok(_) => info!("finish to commit dag block: {:?}", block_id),
Err(e) => {
Expand Down Expand Up @@ -1210,8 +1217,7 @@ impl ChainReader for BlockChain {
}

fn verify(&self, block: Block) -> Result<VerifiedBlock> {
DagVerifier::verify_header(self, block.header())?;
Ok(VerifiedBlock(block))
DagVerifier::verify_block(self, block)
}

fn execute(&mut self, verified_block: VerifiedBlock) -> Result<ExecutedBlock> {
Expand All @@ -1225,7 +1231,7 @@ impl ChainReader for BlockChain {
self.block_accumulator.fork(None),
&self.epoch,
Some(self.status.status.clone()),
verified_block.0,
verified_block.block,
self.vm_metrics.clone(),
)
}
Expand Down Expand Up @@ -1348,6 +1354,14 @@ impl ChainReader for BlockChain {
fn check_chain_type(&self) -> Result<ChainType> {
Ok(ChainType::Dag)
}

fn verify_and_ghostdata(
&self,
uncles: &[BlockHeader],
header: &BlockHeader,
) -> Result<starcoin_dag::types::ghostdata::GhostdagData> {
self.dag().verify_and_ghostdata(uncles, header)
}
}

impl BlockChain {
Expand Down Expand Up @@ -1532,6 +1546,10 @@ impl ChainWriter for BlockChain {
fn chain_state(&mut self) -> &ChainStateDB {
&self.statedb
}

fn apply_for_sync(&mut self, block: Block) -> Result<ExecutedBlock> {
self.apply_with_verifier::<DagVerifierWithGhostData>(block)
}
}

pub(crate) fn info_2_accumulator(
Expand Down
114 changes: 65 additions & 49 deletions chain/src/verifier/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use starcoin_chain_api::{
verify_block, ChainReader, ConnectBlockError, VerifiedBlock, VerifyBlockField,
};
use starcoin_consensus::{Consensus, ConsensusVerifyError};
use starcoin_dag::types::ghostdata::GhostdagData;
use starcoin_logger::prelude::debug;
use starcoin_open_block::AddressFilter;
use starcoin_types::block::{Block, BlockHeader, ALLOWED_FUTURE_BLOCKTIME};
Expand Down Expand Up @@ -76,13 +77,16 @@ pub trait BlockVerifier {
StaticVerifier::verify_body_hash(&new_block)?;
watch(CHAIN_WATCH_NAME, "n13");
//verify uncles
Self::verify_uncles(
let ghostdata = Self::verify_uncles(
current_chain,
new_block.uncles().unwrap_or_default(),
new_block_header,
)?;
watch(CHAIN_WATCH_NAME, "n14");
Ok(VerifiedBlock(new_block))
Ok(VerifiedBlock {
block: new_block,
ghostdata,
})
}

fn verify_blacklisted_txns(new_block: &Block) -> Result<()> {
Expand All @@ -101,7 +105,7 @@ pub trait BlockVerifier {
current_chain: &R,
uncles: &[BlockHeader],
header: &BlockHeader,
) -> Result<()>
) -> Result<Option<GhostdagData>>
where
R: ChainReader,
{
Expand All @@ -118,7 +122,7 @@ pub trait BlockVerifier {
}

if uncles.is_empty() {
return Ok(());
return Ok(None);
}
verify_block!(
VerifyBlockField::Uncle,
Expand Down Expand Up @@ -163,7 +167,7 @@ pub trait BlockVerifier {
Self::verify_header(&uncle_branch, uncle)?;
uncle_ids.insert(uncle_id);
}
Ok(())
Ok(None)
}

fn can_be_uncle<R>(current_chain: &R, block_header: &BlockHeader) -> Result<bool>
Expand Down Expand Up @@ -318,25 +322,27 @@ impl BlockVerifier for NoneVerifier {
where
R: ChainReader,
{
Ok(VerifiedBlock(new_block))
Ok(VerifiedBlock {
block: new_block,
ghostdata: None,
})
}

fn verify_uncles<R>(
_current_chain: &R,
_uncles: &[BlockHeader],
_header: &BlockHeader,
) -> Result<()>
) -> Result<Option<GhostdagData>>
where
R: ChainReader,
{
Ok(())
Ok(None)
}
}

//TODO: Implement it.
pub struct DagVerifier;
impl BlockVerifier for DagVerifier {
fn verify_header<R>(current_chain: &R, new_block_header: &BlockHeader) -> Result<()>
struct BasicDagVerifier;
impl BasicDagVerifier {
pub fn verify_header<R>(current_chain: &R, new_block_header: &BlockHeader) -> Result<()>
where
R: ChainReader,
{
Expand Down Expand Up @@ -380,50 +386,60 @@ impl BlockVerifier for DagVerifier {
ConsensusVerifier::verify_header(current_chain, new_block_header)
}

fn verify_blue_blocks<R>(
current_chain: &R,
uncles: &[BlockHeader],
header: &BlockHeader,
) -> Result<GhostdagData>
where
R: ChainReader,
{
current_chain.verify_and_ghostdata(uncles, header)
}
}
//TODO: Implement it.
pub struct DagVerifier;
impl BlockVerifier for DagVerifier {
fn verify_header<R>(current_chain: &R, new_block_header: &BlockHeader) -> Result<()>
where
R: ChainReader,
{
BasicDagVerifier::verify_header(current_chain, new_block_header)
}

fn verify_uncles<R>(
_current_chain: &R,
_uncles: &[BlockHeader],
_header: &BlockHeader,
) -> Result<()>
) -> Result<Option<GhostdagData>>
where
R: ChainReader,
{
// let mut uncle_ids = HashSet::new();
// for uncle in uncles {
// let uncle_id = uncle.id();
// verify_block!(
// VerifyBlockField::Uncle,
// !uncle_ids.contains(&uncle.id()),
// "repeat uncle {:?} in current block {:?}",
// uncle_id,
// header.id()
// );

// if !header.is_dag() {
// verify_block!(
// VerifyBlockField::Uncle,
// uncle.number() < header.number() ,
// "uncle block number bigger than or equal to current block ,uncle block number is {} , current block number is {}", uncle.number(), header.number()
// );
// }

// verify_block!(
// VerifyBlockField::Uncle,
// current_chain.get_block_info(Some(uncle_id))?.is_some(),
// "Invalid block: uncle {} does not exist",
// uncle_id
// );

// debug!(
// "verify_uncle header number {} hash {:?} uncle number {} hash {:?}",
// header.number(),
// header.id(),
// uncle.number(),
// uncle.id()
// );
// uncle_ids.insert(uncle_id);
// }
Ok(None)
}
}

Ok(())
pub struct DagVerifierWithGhostData;
impl BlockVerifier for DagVerifierWithGhostData {
fn verify_header<R>(current_chain: &R, new_block_header: &BlockHeader) -> Result<()>
where
R: ChainReader,
{
BasicDagVerifier::verify_header(current_chain, new_block_header)
}

fn verify_uncles<R>(
current_chain: &R,
uncles: &[BlockHeader],
header: &BlockHeader,
) -> Result<Option<GhostdagData>>
where
R: ChainReader,
{
Ok(Some(BasicDagVerifier::verify_blue_blocks(
current_chain,
uncles,
header,
)?))
}
}
Loading

0 comments on commit 04a586b

Please sign in to comment.