Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rolback dag-effective-height to zero #4117

Closed
wants to merge 20 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions chain/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ starcoin-force-upgrade = { workspace = true }
default = []
fuzzing = ["proptest", "proptest-derive", "starcoin-types/fuzzing"]
force-deploy = ["starcoin-vm-runtime/force-deploy", "starcoin-vm-runtime", "starcoin-executor/force-deploy"]
sync-dag-test = []

[package]
authors = { workspace = true }
Expand Down
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, header: &BlockHeader) -> Result<DagHeaderType>;
}
Expand Down
1 change: 1 addition & 0 deletions chain/mock/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ proptest-derive = { workspace = true }
[features]
default = []
fuzzing = ["proptest", "proptest-derive", "starcoin-types/fuzzing"]
sync-dag-test = ["starcoin-chain/sync-dag-test"]

[package]
authors = { workspace = true }
Expand Down
2 changes: 1 addition & 1 deletion chain/service/src/chain_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,7 @@ impl ReadableChainService for ChainReaderServiceInner {
head.number(),
);
}
let (dag_genesis, state) = self.main.get_dag_state_by_block(&head)?;
let (dag_genesis, state) = self.main.get_dag_state()?;
Ok(DagStateView {
dag_genesis,
tips: state.tips,
Expand Down
146 changes: 88 additions & 58 deletions chain/src/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ use starcoin_chain_api::{
verify_block, ChainReader, ChainWriter, ConnectBlockError, EventWithProof, ExcludedTxns,
ExecutedBlock, MintedUncleNumber, TransactionInfoWithProof, VerifiedBlock, VerifyBlockField,
};
use starcoin_config::genesis_config::{G_TEST_DAG_FORK_HEIGHT, G_TEST_DAG_FORK_STATE_KEY};
use starcoin_consensus::Consensus;
use starcoin_crypto::hash::PlainCryptoHash;
use starcoin_crypto::HashValue;
Expand Down Expand Up @@ -46,9 +45,7 @@ use starcoin_vm_runtime::force_upgrade_management::get_force_upgrade_block_numbe
use starcoin_vm_types::access_path::AccessPath;
use starcoin_vm_types::account_config::genesis_address;
use starcoin_vm_types::genesis_config::{ChainId, ConsensusStrategy};
use starcoin_vm_types::on_chain_config::FlexiDagConfig;
use starcoin_vm_types::on_chain_resource::Epoch;
use starcoin_vm_types::state_view::StateReaderExt;
use std::cmp::min;
use std::collections::HashSet;
use std::iter::Extend;
Expand Down Expand Up @@ -592,6 +589,7 @@ pub struct ChainStatusWithBlock {

pub struct BlockChain {
genesis_hash: HashValue,
dag_genesis_hash: Option<HashValue>,
txn_accumulator: MerkleAccumulator,
block_accumulator: MerkleAccumulator,
status: ChainStatusWithBlock,
Expand Down Expand Up @@ -638,9 +636,11 @@ impl BlockChain {
let genesis = storage
.get_genesis()?
.ok_or_else(|| format_err!("Can not find genesis hash in storage."))?;
let dag_genesis_hash = dag.load_dag_genesis()?;
watch(CHAIN_WATCH_NAME, "n1253");
let mut chain = Self {
genesis_hash: genesis,
dag_genesis_hash,
time_service,
txn_accumulator: info_2_accumulator(
txn_accumulator_info.clone(),
Expand Down Expand Up @@ -681,9 +681,10 @@ impl BlockChain {
storage: Arc<dyn Store>,
genesis_epoch: Epoch,
genesis_block: Block,
dag: BlockDAG,
mut dag: BlockDAG,
) -> Result<Self> {
debug_assert!(genesis_block.header().is_genesis());
let genesis_header = genesis_block.header().clone();
let txn_accumulator = MerkleAccumulator::new_empty(
storage.get_accumulator_store(AccumulatorStoreType::Transaction),
);
Expand All @@ -703,6 +704,15 @@ impl BlockChain {
&chain_id,
None,
)?;

#[cfg(feature = "sync-dag-test")]
let need_init = chain_id.is_dev();
#[cfg(not(feature = "sync-dag-test"))]
let need_init = true;

if need_init && dag.load_dag_genesis()?.is_none() {
dag.init_with_genesis(genesis_header)?;
}
Self::new(time_service, executed_block.block.id(), storage, None, dag)
}

Expand Down Expand Up @@ -812,13 +822,17 @@ impl BlockChain {
let final_block_gas_limit = block_gas_limit
.map(|block_gas_limit| min(block_gas_limit, on_chain_block_gas_limit))
.unwrap_or(on_chain_block_gas_limit);
let (_, tips_hash) = if current_number <= self.dag_fork_height()?.unwrap_or(u64::MAX) {
(None, None)
let dag_fork_height = self.dag_fork_height()?;
let tips_hash = if current_number <= dag_fork_height.unwrap_or(u64::MAX) {
None
} else if tips.is_some() {
(Some(self.get_block_dag_genesis(&previous_header)?), tips)
tips
} else {
let result = self.current_tips_hash(&previous_header)?.expect("the block number is larger than the dag fork number but the state data doese not exis");
(Some(result.0), Some(result.1))
Some(
self.current_tips_hash()?
.map(|r| r.1)
.expect("Creating a Dag block but tips don't exist"),
)
};
let strategy = epoch.strategy();
let difficulty = strategy.calculate_next_difficulty(self)?;
Expand Down Expand Up @@ -852,8 +866,8 @@ impl BlockChain {
}
};
debug!(
"Blue blocks:{:?} in chain/create_block_template_by_header",
blue_blocks
"current_number: {}/{:?}, Blue blocks:{:?} tips_hash {:?} in chain/create_block_template_by_header",
current_number, dag_fork_height, blue_blocks, tips_hash
);
let mut opened_block = OpenedBlock::new(
self.storage.clone(),
Expand Down Expand Up @@ -976,7 +990,7 @@ impl BlockChain {

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_hash = self.get_block_dag_genesis()?;
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<_>>>()?;
Expand Down Expand Up @@ -1667,33 +1681,35 @@ impl BlockChain {
"Init dag genesis {dag_genesis_id} height {}",
genesis.number()
);
self.dag.init_with_genesis(genesis)?;
if self.dag_genesis_hash.is_some() {
return Err(anyhow!(
"dag genesis already exist, new {}, current {:?}",
genesis.id(),
self.dag_genesis_hash
));
}
let loaded = self.dag.load_dag_genesis()?;
if loaded.is_none() {
self.dag.init_with_genesis(genesis)?;
self.dag_genesis_hash = Some(dag_genesis_id);
} else {
return Err(anyhow!(
"dag genesis already exists in db but hasn't been loaded, new {}, loaded {:?}",
genesis.id(),
loaded
));
}
}
Ok(())
}

pub fn get_block_dag_genesis(&self, header: &BlockHeader) -> Result<HashValue> {
let dag_fork_height = self
.dag_fork_height()?
.ok_or_else(|| anyhow!("unset dag fork height"))?;
let block_info = self
.storage
.get_block_info(header.id())?
.ok_or_else(|| anyhow!("Cannot find block info by hash {:?}", header.id()))?;
let block_accumulator = MerkleAccumulator::new_with_info(
block_info.get_block_accumulator_info().clone(),
self.storage
.get_accumulator_store(AccumulatorStoreType::Block),
);
let dag_genesis = block_accumulator
.get_leaf(dag_fork_height)?
.ok_or_else(|| anyhow!("failed to get the dag genesis"))?;

Ok(dag_genesis)
pub fn get_block_dag_genesis(&self) -> Result<HashValue> {
self.dag_genesis_hash
.ok_or(anyhow!("Dag genesis not exist"))
}

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)?
Expand All @@ -1704,34 +1720,36 @@ impl BlockChain {
))
}

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(&self) -> Result<(HashValue, DagState)> {
let dag_genesis = self.get_block_dag_genesis()?;
Ok((dag_genesis, self.dag.get_dag_state(dag_genesis)?))
}

pub fn check_dag_type(&self, header: &BlockHeader) -> Result<DagHeaderType> {
use std::cmp::Ordering;

let dag_height = self.dag_fork_height()?.unwrap_or(u64::MAX);
if header.is_genesis() {
return Ok(DagHeaderType::Single);
}
let no_parents = header.parents_hash().unwrap_or_default().is_empty();

match (no_parents, header.number().cmp(&dag_height)) {
(true, Ordering::Greater) => {
Err(anyhow!("block header with suitable height but no parents"))
}
(true, Ordering::Greater) => Err(anyhow!(
"block header with suitable height {}/{} but no parents",
header.number(),
dag_height
)),
(false, Ordering::Greater) => Ok(DagHeaderType::Normal),

(true, Ordering::Equal) => Ok(DagHeaderType::Genesis),
(false, Ordering::Equal) => Err(anyhow!(
"block header with dag genesis height but having parents"
"block header with dag genesis height {} but having parents",
dag_height
)),

(true, Ordering::Less) => Ok(DagHeaderType::Single),
(false, Ordering::Less) => Err(anyhow!(
"block header with smaller height but having parents"
"block header with smaller height {}/{} but having parents",
header.number(),
dag_height
)),
}
}
Expand Down Expand Up @@ -2120,11 +2138,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()?;
Ok(Some((dag_genesis, dag_state.tips)))
}

Expand Down Expand Up @@ -2283,7 +2298,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 @@ -2344,30 +2359,45 @@ impl BlockChain {
Ok(executed_block)
}

// todo: please remove me.
// Try to set custom dag_effective_height for `test` network for different test cases,
// or using different features to set the height.
#[cfg(feature = "sync-dag-test")]
pub fn dag_fork_height(&self) -> Result<Option<BlockNumber>> {
use starcoin_config::genesis_config::{G_TEST_DAG_FORK_HEIGHT, G_TEST_DAG_FORK_STATE_KEY};
use starcoin_state_api::StateReaderExt;
use starcoin_vm_types::on_chain_config::FlexiDagConfig;

let chain_id = self.status().head().chain_id();
if chain_id.is_test() {
let result = self.dag.get_dag_state(*G_TEST_DAG_FORK_STATE_KEY);
if result.is_ok() {
Ok(Some(G_TEST_DAG_FORK_HEIGHT))
} else {
let result = self.dag.get_dag_state(self.current_header().id());
if result.is_ok() {
Ok(Some(G_TEST_DAG_FORK_HEIGHT))
} else {
Ok(self
.statedb
.get_on_chain_config::<FlexiDagConfig>()?
.map(|c| c.effective_height))
}
let height = self
.statedb
.get_on_chain_config::<FlexiDagConfig>()?
.map(|c| c.effective_height);

Ok(Some(match height {
Some(h) if h != 0 => h,
_ => u64::MAX,
}))
}
} else {
} else if chain_id.is_dev() {
Ok(self
.statedb
.get_on_chain_config::<FlexiDagConfig>()?
.map(|c| c.effective_height))
} else {
Ok(Some(u64::MAX))
}
}

#[cfg(not(feature = "sync-dag-test"))]
pub fn dag_fork_height(&self) -> Result<Option<BlockNumber>> {
Ok(Some(0))
}
}

impl ChainWriter for BlockChain {
Expand Down
20 changes: 10 additions & 10 deletions chain/src/verifier/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -428,16 +428,6 @@ impl BlockVerifier for DagVerifier {
//TODO: Implement it.
pub struct DagBasicVerifier;
impl BlockVerifier for DagBasicVerifier {
fn verify_uncles<R>(
_current_chain: &R,
_uncles: &[BlockHeader],
_header: &BlockHeader,
) -> Result<()>
where
R: ChainReader,
{
Ok(())
}
fn verify_header<R>(current_chain: &R, new_block_header: &BlockHeader) -> Result<()>
where
R: ChainReader,
Expand Down Expand Up @@ -468,4 +458,14 @@ impl BlockVerifier for DagBasicVerifier {
Ok(())
// ConsensusVerifier::verify_header(current_chain, new_block_header)
}
fn verify_uncles<R>(
_current_chain: &R,
_uncles: &[BlockHeader],
_header: &BlockHeader,
) -> Result<()>
where
R: ChainReader,
{
Ok(())
}
}
Loading
Loading