Skip to content

Commit

Permalink
add fork number in block chain
Browse files Browse the repository at this point in the history
  • Loading branch information
jackzhhuang committed Jan 24, 2024
1 parent a720253 commit 55bdf16
Show file tree
Hide file tree
Showing 18 changed files with 186 additions and 128 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions chain/api/src/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@ pub trait ChainReader {

fn current_tips_hash(&self) -> Result<Option<Vec<HashValue>>>;
fn has_dag_block(&self, hash: HashValue) -> Result<bool>;
fn dag_fork_height(&self) -> BlockNumber;
fn is_dag(&self, block_header: &BlockHeader) -> bool;
fn is_legacy(&self, block_header: &BlockHeader) -> bool;
fn is_dag_genesis(&self, block_header: &BlockHeader) -> bool;
}

pub trait ChainWriter {
Expand Down
1 change: 1 addition & 0 deletions chain/mock/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ starcoin-dag = { workspace = true }
[dev-dependencies]
proptest = { workspace = true }
proptest-derive = { workspace = true }
starcoin-chain = { workspace = true }

[features]
default = []
Expand Down
5 changes: 5 additions & 0 deletions chain/mock/src/mock_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use starcoin_storage::Storage;
use starcoin_types::block::{Block, BlockHeader};
use starcoin_types::startup_info::ChainInfo;
use std::sync::Arc;
use starcoin_types::block::BlockNumber;

pub struct MockChain {
net: ChainNetwork,
Expand Down Expand Up @@ -105,6 +106,10 @@ impl MockChain {
)
}

pub fn set_test_flexidag_fork_height(&mut self, fork_number: BlockNumber) {
self.head.set_test_flexidag_fork_height(fork_number);
}

pub fn fork(&self, head_id: Option<HashValue>) -> Result<MockChain> {
let chain = self.fork_new_branch(head_id)?;
Ok(Self {
Expand Down
42 changes: 33 additions & 9 deletions chain/src/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use starcoin_state_api::{AccountStateReader, ChainStateReader, ChainStateWriter}
use starcoin_statedb::ChainStateDB;
use starcoin_storage::Store;
use starcoin_time_service::TimeService;
use starcoin_types::block::BlockIdAndNumber;
use starcoin_types::block::{BlockIdAndNumber, TEST_FLEXIDAG_FORK_HEIGHT_NEVER_REACH};
use starcoin_types::contract_event::ContractEventInfo;
use starcoin_types::filter::Filter;
use starcoin_types::startup_info::{ChainInfo, ChainStatus, DagState};
Expand Down Expand Up @@ -63,6 +63,7 @@ pub struct BlockChain {
epoch: Epoch,
vm_metrics: Option<VMMetrics>,
dag: BlockDAG,
dag_fork_number: BlockNumber,
}

impl BlockChain {
Expand Down Expand Up @@ -123,6 +124,7 @@ impl BlockChain {
epoch,
vm_metrics,
dag,
dag_fork_number: TEST_FLEXIDAG_FORK_HEIGHT_NEVER_REACH,
};
watch(CHAIN_WATCH_NAME, "n1251");
match uncles {
Expand Down Expand Up @@ -180,6 +182,10 @@ impl BlockChain {
self.dag.clone()
}

pub fn set_test_flexidag_fork_height(&mut self, fork_number: BlockNumber) {
self.dag_fork_number = fork_number;
}

//TODO lazy init uncles cache.
fn update_uncle_cache(&mut self) -> Result<()> {
self.uncles = self.epoch_uncles()?;
Expand Down Expand Up @@ -1002,7 +1008,7 @@ impl ChainReader for BlockChain {

fn execute(&self, verified_block: VerifiedBlock) -> Result<ExecutedBlock> {
let header = verified_block.0.header().clone();
if !header.is_dag() {
if !self.is_dag(&header) {
let executed = Self::execute_block_and_save(
self.storage.as_ref(),
self.statedb.fork(),
Expand All @@ -1013,7 +1019,7 @@ impl ChainReader for BlockChain {
verified_block.0,
self.vm_metrics.clone(),
)?;
if header.is_dag_genesis() {
if self.is_dag_genesis(&header) {
let dag_genesis_id = header.id();
self.dag.init_with_genesis(header)?;
self.storage.save_dag_state(DagState {
Expand Down Expand Up @@ -1131,6 +1137,28 @@ impl ChainReader for BlockChain {
fn has_dag_block(&self, hash: HashValue) -> Result<bool> {
self.dag.has_dag_block(hash)
}

#[cfg(not(test))]
fn dag_fork_height(&self) -> BlockNumber {
100000
}

#[cfg(test)]
fn dag_fork_height(&self) -> BlockNumber {
self.dag_fork_number
}

fn is_dag(&self, block_header: &BlockHeader) -> bool {
block_header.number() > self.dag_fork_height()
}

fn is_legacy(&self, block_header: &BlockHeader) -> bool {
!self.is_dag(block_header) && block_header.parents_hash().is_none()
}

fn is_dag_genesis(&self, block_header: &BlockHeader) -> bool {
block_header.number() == self.dag_fork_height()
}
}

impl BlockChain {
Expand Down Expand Up @@ -1301,10 +1329,6 @@ impl BlockChain {
self.storage.save_dag_state(DagState { tips })?;
Ok(executed_block)
}

pub fn dag_fork_height(&self) -> BlockNumber {
self.status.head.header().dag_fork_height()
}
}

impl ChainWriter for BlockChain {
Expand All @@ -1313,7 +1337,7 @@ impl ChainWriter for BlockChain {
}

fn connect(&mut self, executed_block: ExecutedBlock) -> Result<ExecutedBlock> {
if executed_block.block.is_dag() {
if self.is_dag(executed_block.block.header()) {
info!(
"connect a dag block, {:?}, number: {:?}",
executed_block.block.id(),
Expand Down Expand Up @@ -1355,7 +1379,7 @@ impl ChainWriter for BlockChain {
}

fn apply(&mut self, block: Block) -> Result<ExecutedBlock> {
if !block.is_dag() {
if !self.is_dag(block.header()) {
self.apply_with_verifier::<FullVerifier>(block)
} else {
self.apply_with_verifier::<DagVerifier>(block)
Expand Down
6 changes: 3 additions & 3 deletions chain/src/verifier/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,14 +273,14 @@ impl BlockVerifier for BasicVerifier {

verify_block!(
VerifyBlockField::Header,
!new_block_header.is_dag()
!current_chain.is_dag(new_block_header)
&& new_block_header
.parents_hash()
.unwrap_or_default()
.is_empty(),
"Single chain block is invalid: number {} fork_height {} parents_hash len {}",
new_block_header.number(),
new_block_header.dag_fork_height(),
current_chain.dag_fork_height(),
new_block_header.parents_hash().unwrap_or_default().len()
);
Ok(())
Expand Down Expand Up @@ -369,7 +369,7 @@ impl BlockVerifier for DagVerifier {
"Invalid parents_hash {:?} for a dag block {}, fork height {}",
new_block_header.parents_hash(),
new_block_header.number(),
new_block_header.dag_fork_height()
current_chain.dag_fork_height(),
);

verify_block!(
Expand Down
1 change: 1 addition & 0 deletions chain/tests/test_txn_info_and_proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ fn test_transaction_info_and_proof_1() -> Result<()> {
// generate 5 block
let config = Arc::new(NodeConfig::random_for_test());
let mut block_chain = test_helper::gen_blockchain_for_test(config.net())?;
block_chain.set_test_flexidag_fork_height(2);
let _current_header = block_chain.current_header();
let miner_account = AccountInfo::random();
let mut seq_num = 0;
Expand Down
20 changes: 14 additions & 6 deletions flexidag/dag/src/blockdag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ impl BlockDAG {
self.storage
.relations_store
.insert(origin, BlockHashes::new(vec![]))?;
self.commit(genesis)?;
self.commit_genesis(genesis)?;
Ok(())
}
pub fn ghostdata(&self, parents: &[HashValue]) -> GhostdagData {
Expand All @@ -98,11 +98,19 @@ impl BlockDAG {
}
}

fn commit_genesis(&self, genesis: BlockHeader) -> anyhow::Result<()> {
self.commit_inner(genesis, true)
}

pub fn commit(&self, header: BlockHeader) -> anyhow::Result<()> {
self.commit_inner(header, false)
}

fn commit_inner(&self, header: BlockHeader, is_dag_genesis: bool) -> anyhow::Result<()> {
// Generate ghostdag data
let parents = header.parents();
let ghostdata = self.ghostdata_by_hash(header.id())?.unwrap_or_else(|| {
Arc::new(if header.is_dag_genesis() {
Arc::new(if is_dag_genesis {
self.ghostdag_manager.genesis_ghostdag_data(&header)
} else {
self.ghostdag_manager.ghostdag(&parents)
Expand Down Expand Up @@ -161,7 +169,7 @@ mod tests {
use super::*;
use crate::consensusdb::prelude::FlexiDagStorageConfig;
use starcoin_config::RocksdbConfig;
use starcoin_types::block::{BlockHeader, BlockHeaderBuilder};
use starcoin_types::block::{BlockHeader, BlockHeaderBuilder, TEST_FLEXIDAG_FORK_HEIGHT_FOR_DAG};
use std::{env, fs};

fn build_block_dag(k: KType) -> BlockDAG {
Expand All @@ -183,7 +191,7 @@ mod tests {
#[test]
fn test_dag_0() {
let dag = BlockDAG::create_for_testing().unwrap();
let genesis = BlockHeader::dag_genesis_random()
let genesis = BlockHeader::dag_genesis_random(TEST_FLEXIDAG_FORK_HEIGHT_FOR_DAG)
.as_builder()
.with_difficulty(0.into())
.build();
Expand All @@ -205,7 +213,7 @@ mod tests {

#[test]
fn test_dag_1() {
let genesis = BlockHeader::dag_genesis_random()
let genesis = BlockHeader::dag_genesis_random(TEST_FLEXIDAG_FORK_HEIGHT_FOR_DAG)
.as_builder()
.with_difficulty(0.into())
.build();
Expand Down Expand Up @@ -262,7 +270,7 @@ mod tests {
#[tokio::test]
async fn test_with_spawn() {
use starcoin_types::block::{BlockHeader, BlockHeaderBuilder};
let genesis = BlockHeader::dag_genesis_random()
let genesis = BlockHeader::dag_genesis_random(TEST_FLEXIDAG_FORK_HEIGHT_FOR_DAG)
.as_builder()
.with_difficulty(0.into())
.build();
Expand Down
52 changes: 25 additions & 27 deletions flexidag/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,36 +1,34 @@
use std::path::Path;
use std::sync::Arc;

use starcoin_config::{ChainNetworkID, NodeConfig, RocksdbConfig};
use starcoin_config::{ChainNetworkID, RocksdbConfig};
use starcoin_dag::blockdag::BlockDAG;
use starcoin_dag::consensusdb::prelude::{FlexiDagStorage, FlexiDagStorageConfig};
use starcoin_storage::Store;

pub fn try_init_with_storage(
storage: Arc<dyn Store>,
config: Arc<NodeConfig>,
) -> anyhow::Result<BlockDAG> {
let dag = new_by_config(
config.data_dir().join("flexidag").as_path(),
config.net().id().clone(),
)?;
let startup_info = storage
.get_startup_info()?
.expect("startup info must exist");
// pub fn try_init_with_storage(
// storage: Arc<dyn Store>,
// config: Arc<NodeConfig>,
// ) -> anyhow::Result<BlockDAG> {
// let dag = new_by_config(
// config.data_dir().join("flexidag").as_path(),
// config.net().id().clone(),
// )?;
// let startup_info = storage
// .get_startup_info()?
// .expect("startup info must exist");

let block_header = storage
.get_block_header_by_hash(*startup_info.get_main())?
.expect("the genesis block in dag accumulator must none be none");
let fork_height = block_header.dag_fork_height();
match block_header.number().cmp(&fork_height) {
std::cmp::Ordering::Greater | std::cmp::Ordering::Less => Ok(dag),
std::cmp::Ordering::Equal => {
// dag.commit(block_header)?;
dag.init_with_genesis(block_header)?;
Ok(dag)
}
}
}
// let block_header = storage
// .get_block_header_by_hash(*startup_info.get_main())?
// .expect("the genesis block in dag accumulator must none be none");
// let fork_height = block_header.dag_fork_height();
// match block_header.number().cmp(&fork_height) {
// std::cmp::Ordering::Greater | std::cmp::Ordering::Less => Ok(dag),
// std::cmp::Ordering::Equal => {
// // dag.commit(block_header)?;
// dag.init_with_genesis(block_header)?;
// Ok(dag)
// }
// }
// }

pub fn new_by_config(db_path: &Path, _net: ChainNetworkID) -> anyhow::Result<BlockDAG> {
let config = FlexiDagStorageConfig::create_with_params(1, RocksdbConfig::default());
Expand Down
1 change: 0 additions & 1 deletion sync/src/block_connector/test_write_dag_block_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ use starcoin_chain_service::WriteableChainService;
use starcoin_config::NodeConfig;
use starcoin_consensus::Consensus;
use starcoin_crypto::HashValue;
use starcoin_dag::blockdag::BlockDAG;
use starcoin_time_service::TimeService;
use starcoin_txpool_mock_service::MockTxPoolService;
use starcoin_types::block::Block;
Expand Down
2 changes: 1 addition & 1 deletion sync/src/tasks/block_sync_task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,7 @@ where
}

pub fn ensure_dag_parent_blocks_exist(&mut self, block_header: BlockHeader) -> Result<()> {
if !block_header.is_dag() {
if !self.chain.is_dag(&block_header) {
info!(
"the block is not a dag block, skipping, its id: {:?}, its number {:?}",
block_header.id(),
Expand Down
4 changes: 4 additions & 0 deletions sync/src/tasks/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,10 @@ impl SyncNodeMocker {
}
}

pub fn set_test_flexidag_fork_height(&mut self, fork_number: BlockNumber) {
self.chain_mocker.set_test_flexidag_fork_height(fork_number);
}

pub fn peer_info(&self) -> PeerInfo {
PeerInfo::new(
self.peer_id.clone(),
Expand Down
6 changes: 5 additions & 1 deletion sync/src/tasks/test_tools.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,16 +129,20 @@ impl SyncTestSystem {
}

#[cfg(test)]
pub async fn full_sync_new_node() -> Result<()> {
pub async fn full_sync_new_node(fork_number: BlockNumber) -> Result<()> {
use starcoin_types::block::BlockNumber;

let net1 = ChainNetwork::new_builtin(BuiltinNetworkID::Test);
let mut node1 = SyncNodeMocker::new(net1, 300, 0)?;
node1.set_test_flexidag_fork_height(fork_number);
node1.produce_block(10)?;

let mut arc_node1 = Arc::new(node1);

let net2 = ChainNetwork::new_builtin(BuiltinNetworkID::Test);

let node2 = SyncNodeMocker::new(net2.clone(), 300, 0)?;
node2.set_test_flexidag_fork_height(fork_number);

let target = arc_node1.sync_target();

Expand Down
2 changes: 1 addition & 1 deletion sync/src/tasks/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ use super::BlockConnectedEvent;

#[stest::test(timeout = 120)]
pub async fn test_full_sync_new_node() -> Result<()> {
full_sync_new_node().await
full_sync_new_node(false).await
}

#[stest::test]
Expand Down
Loading

0 comments on commit 55bdf16

Please sign in to comment.