Skip to content

Commit

Permalink
add some test
Browse files Browse the repository at this point in the history
  • Loading branch information
jackzhhuang committed Sep 2, 2024
1 parent 95215f1 commit e27999f
Show file tree
Hide file tree
Showing 4 changed files with 200 additions and 16 deletions.
127 changes: 126 additions & 1 deletion flexidag/src/blockdag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ use crate::consensusdb::{
};
use crate::ghostdag::protocol::GhostdagManager;
use crate::prune::pruning_point_manager::PruningPointManagerT;
use crate::types::ghostdata::CompactGhostdagData;
use crate::{process_key_already_error, reachability};
use anyhow::{bail, format_err, Ok};
use anyhow::{bail, ensure, format_err, Ok};
use starcoin_accumulator::node::AccumulatorStoreType;
use starcoin_accumulator::{Accumulator, MerkleAccumulator};
use starcoin_config::temp_dir;
Expand All @@ -25,6 +26,8 @@ use starcoin_types::{
blockhash::{BlockHashes, KType},
consensus_header::ConsensusHeader,
};
use std::char::EscapeUnicode;
use std::collections::HashSet;
use std::ops::DerefMut;
use std::sync::Arc;

Expand Down Expand Up @@ -142,6 +145,128 @@ impl BlockDAG {
Ok(())
}

pub fn commit_trusted_block(&mut self, header: BlockHeader, origin: HashValue, trusted_ghostdata: Arc<GhostdagData>) -> anyhow::Result<()> {
info!(
"start to commit header: {:?}, number: {:?}",
header.id(),
header.number()
);
// Generate ghostdag data
let parents = header.parents();

debug!(
"start to get the ghost data from block: {:?}, number: {:?}",
header.id(),
header.number()
);
let ghostdata = match self.ghostdata_by_hash(header.id())? {
None => {
// It must be the dag genesis if header is a format for a single chain
if header.is_genesis() {
Arc::new(self.ghostdag_manager.genesis_ghostdag_data(&header))
} else {
self.storage.ghost_dag_store.insert(header.id(), trusted_ghostdata.clone())?;
trusted_ghostdata
}
}
Some(ghostdata) => {
ensure!(ghostdata.blue_score == trusted_ghostdata.blue_score, "blue score is not same");
ensure!(ghostdata.blue_work == trusted_ghostdata.blue_work, "blue work is not same");
ensure!(ghostdata.mergeset_blues.len() == trusted_ghostdata.mergeset_blues.len(), "blue len is not same");
ensure!(ghostdata.mergeset_blues.iter().cloned().collect::<HashSet<_>>() == trusted_ghostdata.mergeset_blues.iter().cloned().collect::<HashSet<_>>(), "blue values are not same");
trusted_ghostdata
}
};
// Store ghostdata
process_key_already_error(
self.storage
.ghost_dag_store
.insert(header.id(), ghostdata.clone()),
)?;

// Update reachability store
debug!(
"start to update reachability data for block: {:?}, number: {:?}",
header.id(),
header.number()
);
let reachability_store = self.storage.reachability_store.clone();

let mut merge_set = ghostdata
.unordered_mergeset_without_selected_parent()
.filter(|hash| self.storage.reachability_store.read().has(*hash).unwrap())
.collect::<Vec<_>>()
.into_iter();
let add_block_result = {
let mut reachability_writer = reachability_store.write();
inquirer::add_block(
reachability_writer.deref_mut(),
header.id(),
ghostdata.selected_parent,
&mut merge_set,
)
};
match add_block_result {
Result::Ok(_) => (),
Err(reachability::ReachabilityError::DataInconsistency) => {
let _future_covering_set = reachability_store
.read()
.get_future_covering_set(header.id())?;
info!(
"the key {:?} was already processed, original error message: {:?}",
header.id(),
reachability::ReachabilityError::DataInconsistency
);
}
Err(reachability::ReachabilityError::StoreError(StoreError::KeyNotFound(msg))) => {
if msg == *REINDEX_ROOT_KEY.to_string() {
info!(
"the key {:?} was already processed, original error message: {:?}",
header.id(),
reachability::ReachabilityError::StoreError(StoreError::KeyNotFound(
REINDEX_ROOT_KEY.to_string()
))
);
info!("now set the reindex key to origin: {:?}", origin);
// self.storage.reachability_store.set_reindex_root(origin)?;
self.set_reindex_root(origin)?;
bail!(
"failed to add a block when committing, e: {:?}",
reachability::ReachabilityError::StoreError(StoreError::KeyNotFound(msg))
);
} else {
bail!(
"failed to add a block when committing, e: {:?}",
reachability::ReachabilityError::StoreError(StoreError::KeyNotFound(msg))
);
}
}
Err(reachability::ReachabilityError::StoreError(StoreError::InvalidInterval(_, _))) => {
self.set_reindex_root(origin)?;
bail!("failed to add a block when committing for invalid interval",);
}
Err(e) => {
bail!("failed to add a block when committing, e: {:?}", e);
}
}

process_key_already_error(
self.storage
.relations_store
.write()
.insert(header.id(), BlockHashes::new(parents)),
)?;
// Store header store
process_key_already_error(self.storage.header_store.insert(
header.id(),
Arc::new(header),
1,
))?;
Ok(())
}



pub fn commit(&mut self, header: BlockHeader, origin: HashValue) -> anyhow::Result<()> {
info!(
"start to commit header: {:?}, number: {:?}",
Expand Down
22 changes: 22 additions & 0 deletions flexidag/src/ghostdag/protocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use starcoin_crypto::HashValue as Hash;
use starcoin_logger::prelude::*;
use starcoin_types::block::BlockHeader;
use starcoin_types::blockhash::{BlockHashMap, BlockHashes, BlueWorkType, HashKTypeMap, KType};
use std::collections::HashSet;
use std::sync::Arc;

#[derive(Clone)]
Expand Down Expand Up @@ -170,6 +171,27 @@ impl<
Ok(new_block_data)
}

pub fn check_ghostdata_blue_block(&self, ghostdata: &GhostdagData) -> Result<()> {
let mut new_block_data = GhostdagData::new_with_selected_parent(ghostdata.selected_parent, self.k);
for blue_candidate in ghostdata.mergeset_blues.iter().skip(1).cloned() {
let coloring = self.check_blue_candidate(&new_block_data, blue_candidate)?;
if let ColoringOutput::Blue(blue_anticone_size, blues_anticone_sizes) = coloring {
new_block_data.add_blue(blue_candidate, blue_anticone_size, &blues_anticone_sizes);
} else {
new_block_data.add_red(blue_candidate);
}
}
println!("jacktest: new_block_data: {:?}", new_block_data);
println!("jacktest: ghostdata: {:?}", ghostdata);
if ghostdata.mergeset_blues.len() != new_block_data.mergeset_blues.len() {
return Err(anyhow::anyhow!("The len of blue set is not equal, for {}, {}", ghostdata.mergeset_blues.len(), new_block_data.mergeset_blues.len()));
}
if ghostdata.mergeset_blues.iter().cloned().collect::<HashSet<_>>() != new_block_data.mergeset_blues.iter().cloned().collect::<HashSet<_>>() {
return Err(anyhow::anyhow!("The blue set is not equal"));
}
Ok(())
}

fn check_blue_candidate_with_chain_block(
&self,
new_block_data: &GhostdagData,
Expand Down
2 changes: 1 addition & 1 deletion flexidag/src/types/ghostdata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize};
use starcoin_crypto::HashValue as Hash;
use starcoin_types::blockhash::{BlockHashMap, BlockHashes, BlueWorkType, HashKTypeMap, KType};

#[derive(Clone, Serialize, Deserialize, Default, Debug, JsonSchema)]
#[derive(Clone, Serialize, Deserialize, Default, Debug, JsonSchema, PartialEq, Eq)]
pub struct GhostdagData {
pub blue_score: u64,
#[schemars(with = "String")]
Expand Down
65 changes: 51 additions & 14 deletions flexidag/tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,16 @@
use anyhow::{bail, format_err, Ok, Result};
use starcoin_crypto::HashValue as Hash;
use starcoin_dag::{
blockdag::{BlockDAG, MineNewDagBlockInfo},
consensusdb::{
blockdag::{BlockDAG, MineNewDagBlockInfo}, consensusdb::{
consenses_state::{DagState, DagStateReader, DagStateStore},
schemadb::{
DbReachabilityStore, ReachabilityStore, ReachabilityStoreReader, RelationsStore,
RelationsStoreReader,
},
},
reachability::{inquirer, ReachabilityError},
types::interval::Interval,
}, ghostdag, reachability::{inquirer, ReachabilityError}, types::{ghostdata::GhostdagData, interval::Interval}
};
use starcoin_logger::prelude::debug;
use starcoin_types::block::{BlockHeader, BlockHeaderBuilder, BlockNumber};
use starcoin_types::{block::{BlockHeader, BlockHeaderBuilder, BlockNumber}, blockhash::{BlockHashMap, HashKTypeMap, KType}};

use std::{
ops::{Deref, DerefMut},
Expand Down Expand Up @@ -702,6 +699,37 @@ fn test_reachability_algorithm() -> anyhow::Result<()> {
Ok(())
}

fn add_and_print_with_ghostdata(
number: BlockNumber,
parent: Hash,
parents: Vec<Hash>,
origin: Hash,
dag: &mut BlockDAG,
ghostdata: GhostdagData,
) -> anyhow::Result<BlockHeader> {
let header_builder = BlockHeaderBuilder::random();
let header = header_builder
.with_parent_hash(parent)
.with_parents_hash(parents)
.with_number(number)
.build();
let start = Instant::now();
dag.commit_trusted_block(header.to_owned(), origin, Arc::new(ghostdata))?;
let duration = start.elapsed();
println!(
"commit header: {:?}, number: {:?}, duration: {:?}",
header.id(),
header.number(),
duration
);
let _ghostdata = dag.ghostdata(&[header.id()])?;
// println!(
// "add a header: {:?}, blue set: {:?}, red set: {:?}, blue anticone size: {:?}",
// header, ghostdata.mergeset_blues, ghostdata.mergeset_reds, ghostdata.blues_anticone_sizes
// );
Ok(header)
}

fn add_and_print(
number: BlockNumber,
parent: Hash,
Expand Down Expand Up @@ -1027,13 +1055,7 @@ fn test_verification_blue_block() -> anyhow::Result<()> {
genesis.parent_hash(),
&mut dag,
)?;
// let block_red_4 = add_and_print(
// 4,
// block_red_3.id(),
// vec![block_red_3.id()],
// genesis.parent_hash(),
// &mut dag,
// )?;


// let's obser the blue scores which show how blue the tips are
let observer1 = dag.ghostdata(&[block_red_3.id()])?;
Expand All @@ -1051,8 +1073,23 @@ fn test_verification_blue_block() -> anyhow::Result<()> {
// assert_eq!(observer3.blue_score, observer2.blue_score);
// assert_eq!(observer3.selected_parent, observer2.selected_parent);


let normal_block = add_and_print(6, block_main_5.id(), vec![block_main_5.id(), block_red_3.id()], genesis.parent_hash(), &mut dag)?;
assert_eq!(observer2, dag.ghostdata_by_hash(normal_block.id())?.expect("the data cannot be none").as_ref().clone());

let makeup_ghostdata = GhostdagData::new(observer2.blue_score, observer2.blue_work, observer2.selected_parent, observer2.mergeset_blues.clone(), Arc::new(vec![]), HashKTypeMap::new(BlockHashMap::<KType>::new()));
dag.ghost_dag_manager().check_ghostdata_blue_block(&makeup_ghostdata)?;
let makeup_block = add_and_print_with_ghostdata(6, block_main_5.id(), vec![block_main_5.id(), block_red_3.id()], genesis.parent_hash(), &mut dag, makeup_ghostdata.clone())?;

let block_from_normal = add_and_print(7, normal_block.id(), vec![normal_block.id()], genesis.parent_hash(), &mut dag)?;
let block_from_makeup = add_and_print(7, makeup_block.id(), vec![makeup_block.id()], genesis.parent_hash(), &mut dag)?;

let ghostdag_data_from_normal = dag.ghostdata_by_hash(block_from_normal.id())?.expect("the data cannot be none").as_ref().clone();
let ghostdag_data_from_makeup = dag.ghostdata_by_hash(block_from_makeup.id())?.expect("the data cannot be none").as_ref().clone();

println!("normal: {:?}", ghostdag_data_from_normal);
println!("makeup: {:?}", ghostdag_data_from_makeup);

dag.ghost_dag_manager().check_ghostdata_blue_block(&ghostdag_data_from_makeup)?;

anyhow::Result::Ok(())
}

0 comments on commit e27999f

Please sign in to comment.