Skip to content

Commit

Permalink
[Flexidag] Fix some test case to cover the dag logic (#4123)
Browse files Browse the repository at this point in the history
* add delete sync blocks

* add test codes for dag

* test_sync_red_blocks_dag will cover the dag sync case

* fix some test case

* return Vec<Block> not Vec<(id, Block)> in fetch_blocks

* change name fetch_block to fetch_blocks

* remove jacktest
  • Loading branch information
jackzhhuang authored May 30, 2024
1 parent eefd848 commit 22bdfb9
Show file tree
Hide file tree
Showing 7 changed files with 183 additions and 103 deletions.
51 changes: 51 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 std::vec;

pub struct MockChain {
net: ChainNetwork,
Expand Down Expand Up @@ -175,6 +176,24 @@ impl MockChain {
.create_block(template, self.net.time_service().as_ref())
}

pub fn produce_block_by_tips(
&mut self,
parent_header: BlockHeader,
tips: Vec<HashValue>,
) -> Result<Block> {
let (template, _) = self.head.create_block_template_by_header(
*self.miner.address(),
parent_header,
vec![],
vec![],
None,
Some(tips),
)?;
self.head
.consensus()
.create_block(template, self.net.time_service().as_ref())
}

pub fn apply(&mut self, block: Block) -> Result<()> {
self.head.apply(block)?;
Ok(())
Expand All @@ -194,6 +213,38 @@ impl MockChain {
Ok(())
}

pub fn produce_fork_chain(&mut self, one_count: u64, two_count: u64) -> Result<()> {
let start_header = self.head.current_header();

let mut parent_one = start_header.clone();
for _i in 0..one_count {
let new_block =
self.produce_block_by_tips(parent_one.clone(), vec![parent_one.id()])?;
parent_one = new_block.header().clone();
self.apply(new_block)?;
}

let mut parent_two = start_header.clone();
for _i in 0..two_count {
let new_block =
self.produce_block_by_tips(parent_two.clone(), vec![parent_two.id()])?;
parent_two = new_block.header().clone();
self.apply(new_block)?;
}

let meetup_block = if one_count < two_count {
self.produce_block_by_tips(parent_two.clone(), vec![parent_one.id(), parent_two.id()])?
} else {
self.produce_block_by_tips(parent_one.clone(), vec![parent_one.id(), parent_two.id()])?
};
let new_header_id = meetup_block.header().id();
self.apply(meetup_block)?;

assert_eq!(self.head().current_header().id(), new_header_id);

Ok(())
}

pub fn miner(&self) -> &AccountInfo {
&self.miner
}
Expand Down
47 changes: 39 additions & 8 deletions chain/tests/test_txn_info_and_proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ use rand::Rng;
use starcoin_account_api::AccountInfo;
use starcoin_accumulator::Accumulator;
use starcoin_chain_api::{ChainReader, ChainWriter};
use starcoin_config::genesis_config::{G_TEST_DAG_FORK_HEIGHT, G_TEST_DAG_FORK_STATE_KEY};
use starcoin_config::NodeConfig;
use starcoin_consensus::Consensus;
use starcoin_crypto::HashValue;
use starcoin_dag::consensusdb::consenses_state::DagState;
use starcoin_logger::prelude::debug;
use starcoin_transaction_builder::{peer_to_peer_txn_sent_as_association, DEFAULT_EXPIRATION_TIME};
use starcoin_types::account_config;
Expand Down Expand Up @@ -43,14 +45,22 @@ pub fn gen_txns(seq_num: &mut u64) -> Result<Vec<SignedUserTransaction>> {

#[stest::test(timeout = 480)]
fn test_transaction_info_and_proof_1() -> Result<()> {
starcoin_types::block::set_test_flexidag_fork_height(2);
// generate 5 block
let config = Arc::new(NodeConfig::random_for_test());
let mut block_chain = test_helper::gen_blockchain_for_test(config.net())?;

// set the flexidag fork height to G_TEST_DAG_FORK_HEIGHT
block_chain
.dag()
.save_dag_state(*G_TEST_DAG_FORK_STATE_KEY, DagState { tips: vec![] })?;

let _current_header = block_chain.current_header();
let miner_account = AccountInfo::random();
let mut seq_num = 0;
(0..5).for_each(|_| {
// generate G_TEST_DAG_FORK_HEIGHT + 5 blocks
let block_count = G_TEST_DAG_FORK_HEIGHT
.checked_add(5)
.ok_or_else(|| format_err!("overflow in calculation of the block count"))?;
(0..block_count).for_each(|_| {
let txns = gen_txns(&mut seq_num).unwrap();
let (template, _) = block_chain
.create_block_template(*miner_account.address(), None, txns, vec![], None, None)
Expand All @@ -62,8 +72,14 @@ fn test_transaction_info_and_proof_1() -> Result<()> {
debug!("apply block:{:?}", &block);
block_chain.apply(block).unwrap();
});
// fork from 3 block
let fork_point = block_chain.get_block_by_number(3).unwrap().unwrap();
// fork from G_TEST_DAG_FORK_HEIGHT + 3 block
let fork_count = G_TEST_DAG_FORK_HEIGHT
.checked_add(3)
.ok_or_else(|| format_err!("overflow in calculation of the fork count"))?;
let fork_point = block_chain
.get_block_by_number(fork_count)
.unwrap()
.unwrap();
let mut fork_chain = block_chain.fork(fork_point.id()).unwrap();
let account_reader = fork_chain.chain_state_reader();
seq_num = account_reader.get_sequence_number(account_config::association_address())?;
Expand All @@ -86,7 +102,15 @@ fn test_transaction_info_and_proof_1() -> Result<()> {
fork_chain.apply(block).unwrap();
assert_eq!(
block_chain.current_header().id(),
block_chain.get_block_by_number(5).unwrap().unwrap().id()
block_chain
.get_block_by_number(
G_TEST_DAG_FORK_HEIGHT
.checked_add(5)
.ok_or_else(|| format_err!("failed add the block number for overflow"))?
)
.unwrap()
.unwrap()
.id()
);
// create latest block
let account_reader = block_chain.chain_state_reader();
Expand All @@ -103,9 +127,16 @@ fn test_transaction_info_and_proof_1() -> Result<()> {
block_chain.apply(block).unwrap();
assert_eq!(
block_chain.current_header().id(),
block_chain.get_block_by_number(6).unwrap().unwrap().id()
block_chain
.get_block_by_number(
G_TEST_DAG_FORK_HEIGHT
.checked_add(6)
.ok_or_else(|| format_err!("overflow in calulation of the latest number"))?
)
.unwrap()
.unwrap()
.id()
);
starcoin_types::block::reset_test_custom_fork_height();
Ok(())
}

Expand Down
59 changes: 30 additions & 29 deletions flexidag/tests/tests.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 anyhow::{bail, Ok};
use anyhow::{bail, format_err, Ok, Result};
use starcoin_crypto::HashValue as Hash;
use starcoin_dag::{
blockdag::BlockDAG,
Expand All @@ -16,9 +16,7 @@ use starcoin_dag::{
types::interval::Interval,
};
use starcoin_logger::prelude::debug;
use starcoin_types::block::{
set_test_flexidag_fork_height, BlockHeader, BlockHeaderBuilder, BlockNumber,
};
use starcoin_types::block::{BlockHeader, BlockHeaderBuilder, BlockNumber};

use std::{
ops::{Deref, DerefMut},
Expand All @@ -27,32 +25,33 @@ use std::{
};

#[test]
fn test_dag_0() {
fn test_dag_commit() -> Result<()> {
let mut dag = BlockDAG::create_for_testing().unwrap();
let genesis = BlockHeader::dag_genesis_random()
let genesis = BlockHeader::dag_genesis_random(0)
.as_builder()
.with_difficulty(0.into())
.build();

let mut parents_hash = vec![genesis.id()];
dag.init_with_genesis(genesis.clone()).unwrap();
let origin = dag.init_with_genesis(genesis.clone())?;

for _ in 0..10 {
let header_builder = BlockHeaderBuilder::random();
let header = header_builder
.with_parents_hash(Some(parents_hash.clone()))
.build();
parents_hash = vec![header.id()];
dag.commit(header.to_owned(), genesis.parent_hash())
.unwrap();
dag.commit(header.to_owned(), origin)?;
let ghostdata = dag.ghostdata_by_hash(header.id()).unwrap().unwrap();
println!("{:?},{:?}", header, ghostdata);
}

Ok(())
}

#[test]
fn test_dag_1() {
let genesis = BlockHeader::dag_genesis_random()
fn test_dag_1() -> Result<()> {
let genesis = BlockHeader::dag_genesis_random(0)
.as_builder()
.with_difficulty(0.into())
.build();
Expand Down Expand Up @@ -88,28 +87,32 @@ fn test_dag_1() {
let genesis_id = genesis.id();
let mut dag = BlockDAG::create_for_testing().unwrap();
let expect_selected_parented = [block5.id(), block3.id(), block3_1.id(), genesis_id];
dag.init_with_genesis(genesis.clone()).unwrap();

dag.commit(block1, genesis.parent_hash()).unwrap();
dag.commit(block2, genesis.parent_hash()).unwrap();
dag.commit(block3_1, genesis.parent_hash()).unwrap();
dag.commit(block3, genesis.parent_hash()).unwrap();
dag.commit(block4, genesis.parent_hash()).unwrap();
dag.commit(block5, genesis.parent_hash()).unwrap();
dag.commit(block6, genesis.parent_hash()).unwrap();
let origin = dag.init_with_genesis(genesis.clone()).unwrap();

dag.commit(block1, origin)?;
dag.commit(block2, origin)?;
dag.commit(block3_1, origin)?;
dag.commit(block3, origin)?;
dag.commit(block4, origin)?;
dag.commit(block5, origin)?;
dag.commit(block6, origin)?;
let mut count = 0;
while latest_id != genesis_id && count < 4 {
let ghostdata = dag.ghostdata_by_hash(latest_id).unwrap().unwrap();
let ghostdata = dag
.ghostdata_by_hash(latest_id)?
.ok_or_else(|| format_err!("Failed to get ghostdata"))?;
latest_id = ghostdata.selected_parent;
assert_eq!(expect_selected_parented[count], latest_id);
count += 1;
}

Ok(())
}

#[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(0)
.as_builder()
.with_difficulty(0.into())
.build();
Expand Down Expand Up @@ -165,7 +168,7 @@ async fn test_with_spawn() {
#[test]
fn test_write_asynchronization() -> anyhow::Result<()> {
let mut dag = BlockDAG::create_for_testing()?;
let genesis = BlockHeader::dag_genesis_random()
let genesis = BlockHeader::dag_genesis_random(0)
.as_builder()
.with_difficulty(0.into())
.build();
Expand Down Expand Up @@ -239,7 +242,7 @@ fn test_dag_genesis_fork() {
// initialzie the dag firstly
let mut dag = BlockDAG::create_for_testing().unwrap();

let genesis = BlockHeader::dag_genesis_random()
let genesis = BlockHeader::dag_genesis_random(0)
.as_builder()
.with_difficulty(0.into())
.build();
Expand All @@ -259,7 +262,7 @@ fn test_dag_genesis_fork() {
}

// fork, produce a new dag genesis
let new_genesis = BlockHeader::dag_genesis_random()
let new_genesis = BlockHeader::dag_genesis_random(0)
.as_builder()
.with_difficulty(0.into())
.build();
Expand Down Expand Up @@ -350,12 +353,11 @@ fn test_dag_tips_store() {

#[test]
fn test_dag_multiple_commits() -> anyhow::Result<()> {
set_test_flexidag_fork_height(1);
// initialzie the dag firstly
let mut dag = BlockDAG::create_for_testing().unwrap();

let origin = BlockHeaderBuilder::random().with_number(0).build();
let genesis = BlockHeader::dag_genesis_random_with_parent(origin);
let genesis = BlockHeader::dag_genesis_random_with_parent(origin)?;

dag.init_with_genesis(genesis.clone()).unwrap();

Expand Down Expand Up @@ -742,12 +744,11 @@ fn add_and_print(

#[test]
fn test_dag_mergeset() -> anyhow::Result<()> {
set_test_flexidag_fork_height(1);
// initialzie the dag firstly
let mut dag = BlockDAG::create_for_testing().unwrap();

let origin = BlockHeaderBuilder::random().with_number(0).build();
let genesis = BlockHeader::dag_genesis_random_with_parent(origin);
let genesis = BlockHeader::dag_genesis_random_with_parent(origin)?;

dag.init_with_genesis(genesis.clone()).unwrap();

Expand Down
15 changes: 7 additions & 8 deletions sync/src/tasks/block_sync_task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,6 @@ where
fn find_absent_parent_dag_blocks(
&self,
block_header: BlockHeader,
// ancestors: &mut Vec<HashValue>,
absent_blocks: &mut Vec<HashValue>,
) -> Result<()> {
let parents = block_header.parents_hash().unwrap_or_default();
Expand Down Expand Up @@ -404,13 +403,13 @@ where
if absent_blocks.is_empty() {
return Ok(absent_blocks_map.into_values().collect());
}
let remote_absent_blocks = self.fetch_block(absent_blocks).await?;
let remote_absent_blocks = self.fetch_blocks(absent_blocks).await?;
block_headers = remote_absent_blocks
.iter()
.map(|(_, block)| block.header().clone())
.map(|block| block.header().clone())
.collect();

remote_absent_blocks.into_iter().for_each(|(_id, block)| {
remote_absent_blocks.into_iter().for_each(|block| {
absent_blocks_map.insert(block.id(), block);
});
}
Expand Down Expand Up @@ -533,13 +532,13 @@ where
async_std::task::block_on(fut)
}

async fn fetch_block(&self, mut block_ids: Vec<HashValue>) -> Result<Vec<(HashValue, Block)>> {
let mut result: Vec<(HashValue, Block)> = vec![];
async fn fetch_blocks(&self, mut block_ids: Vec<HashValue>) -> Result<Vec<Block>> {
let mut result = vec![];
block_ids.retain(|id| {
match self.local_store.get_dag_sync_block(*id) {
Ok(op_dag_sync_block) => {
if let Some(dag_sync_block) = op_dag_sync_block {
result.push((dag_sync_block.block.id(), dag_sync_block.block));
result.push(dag_sync_block.block);
false // read from local store, remove from p2p request
} else {
true // need retaining
Expand All @@ -555,7 +554,7 @@ where
block: block.clone(),
children: vec![],
})?;
result.push((block.id(), block));
result.push(block);
}
}
Ok(result)
Expand Down
10 changes: 10 additions & 0 deletions sync/src/tasks/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,10 @@ impl SyncNodeMocker {
self.chain_mocker.produce_and_apply_times(times)
}

pub fn produce_fork_chain(&mut self, one_count: u64, two_count: u64) -> Result<()> {
self.chain_mocker.produce_fork_chain(one_count, two_count)
}

pub fn select_head(&mut self, block: Block) -> Result<()> {
self.chain_mocker.select_head(block)
}
Expand Down Expand Up @@ -346,6 +350,12 @@ impl BlockFetcher for SyncNodeMocker {
.map(|block_id| {
if let Some(block) = self.chain().get_block(block_id)? {
Ok((block, Some(PeerId::random())))
} else if !self.chain().head_block().block().header().is_single() {
if let Some(block) = self.chain().get_storage().get_block(block_id)? {
Ok((block, Some(PeerId::random())))
} else {
Err(format_err!("Cannot find block by id: {}", block_id))
}
} else {
Err(format_err!("Can not find block by id: {}", block_id))
}
Expand Down
Loading

0 comments on commit 22bdfb9

Please sign in to comment.