Skip to content

Commit

Permalink
Refactor header name && dag init in BlockChain
Browse files Browse the repository at this point in the history
  • Loading branch information
sanlee42 committed Sep 22, 2023
1 parent c23f1b5 commit c8556ab
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 61 deletions.
19 changes: 11 additions & 8 deletions chain/src/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ use starcoin_time_service::TimeService;
use starcoin_types::block::BlockIdAndNumber;
use starcoin_types::contract_event::ContractEventInfo;
use starcoin_types::filter::Filter;
use starcoin_types::header::DagHeader;
use starcoin_types::startup_info::{ChainInfo, ChainStatus};
use starcoin_types::transaction::RichTransactionInfo;
use starcoin_types::{
Expand Down Expand Up @@ -72,13 +73,13 @@ impl BlockChain {
time_service: Arc<dyn TimeService>,
head_block_hash: HashValue,
storage: Arc<dyn Store>,
dag_store: FlexiDagStorage,
vm_metrics: Option<VMMetrics>,
dag: BlockDAG,
) -> Result<Self> {
let head = storage
.get_block_by_hash(head_block_hash)?
.ok_or_else(|| format_err!("Can not find block by hash {:?}", head_block_hash))?;
Self::new_with_uncles(time_service, head, None, storage, vm_metrics, dag_store)
Self::new_with_uncles(time_service, head, None, storage, vm_metrics, dag)
}

fn new_with_uncles(
Expand All @@ -87,7 +88,7 @@ impl BlockChain {
uncles: Option<HashMap<HashValue, MintedUncleNumber>>,
storage: Arc<dyn Store>,
vm_metrics: Option<VMMetrics>,
dag_store: FlexiDagStorage,
dag: BlockDAG,
) -> Result<Self> {
let block_info = storage
.get_block_info(head_block.id())?
Expand Down Expand Up @@ -115,7 +116,6 @@ impl BlockChain {
.get_accumulator_snapshot_storage()
.get(head_id)?
.map(|snapshot| snapshot.child_hashes);
let dag = BlockDAG::new(genesis,16,dag_store),
let mut chain = Self {
genesis_hash: genesis,
time_service,
Expand Down Expand Up @@ -155,6 +155,7 @@ impl BlockChain {
storage: Arc<dyn Store>,
genesis_epoch: Epoch,
genesis_block: Block,
dag_store: FlexiDagStorage,
) -> Result<Self> {
debug_assert!(genesis_block.header().is_genesis());
let txn_accumulator = MerkleAccumulator::new_empty(
Expand All @@ -164,7 +165,7 @@ impl BlockChain {
storage.get_accumulator_store(AccumulatorStoreType::Block),
);
let statedb = ChainStateDB::new(storage.clone().into_super_arc(), None);

let genesis_header = genesis_block.header.clone();
let genesis_id = genesis_block.header.id();
let executed_block = Self::execute_block_and_save(
storage.as_ref(),
Expand All @@ -190,8 +191,9 @@ impl BlockChain {
new_tips,
dag_accumulator.get_info(),
)?;

Self::new(time_service, executed_block.block.id(), storage, None)
let mut dag = BlockDAG::new(genesis_id, 16, dag_store);
dag.init_with_genesis(DagHeader::new_genesis(genesis_header))?;
Self::new(time_service, executed_block.block.id(), storage, None, dag)
}

pub fn current_epoch_uncles_size(&self) -> u64 {
Expand Down Expand Up @@ -884,6 +886,8 @@ impl ChainReader for BlockChain {
uncles,
self.storage.clone(),
self.vm_metrics.clone(),
//TODO: check missing blocks need to be clean
self.dag.clone(),
)
}

Expand Down Expand Up @@ -1155,7 +1159,6 @@ impl ChainWriter for BlockChain {
== executed_block.block().header().parent_hash();
}
}

fn connect(
&mut self,
executed_block: ExecutedBlock,
Expand Down
19 changes: 12 additions & 7 deletions consensus/src/consensusdb/consensus_header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use rocksdb::WriteBatch;
use starcoin_crypto::HashValue as Hash;
use starcoin_types::{
blockhash::BlockLevel,
header::{CompactHeaderData, ConsensusHeader, Header, HeaderWithBlockLevel},
header::{CompactHeaderData, ConsensusHeader, DagHeader, HeaderWithBlockLevel},
U256,
};
use std::sync::Arc;
Expand All @@ -20,7 +20,7 @@ pub trait HeaderStoreReader {
fn get_blue_score(&self, hash: Hash) -> Result<u64, StoreError>;
fn get_timestamp(&self, hash: Hash) -> Result<u64, StoreError>;
fn get_difficulty(&self, hash: Hash) -> Result<U256, StoreError>;
fn get_header(&self, hash: Hash) -> Result<Arc<Header>, StoreError>;
fn get_header(&self, hash: Hash) -> Result<Arc<DagHeader>, StoreError>;
fn get_header_with_block_level(&self, hash: Hash) -> Result<HeaderWithBlockLevel, StoreError>;
fn get_compact_header_data(&self, hash: Hash) -> Result<CompactHeaderData, StoreError>;
}
Expand All @@ -30,7 +30,7 @@ pub trait HeaderStore: HeaderStoreReader {
fn insert(
&self,
hash: Hash,
header: Arc<Header>,
header: Arc<DagHeader>,
block_level: BlockLevel,
) -> Result<(), StoreError>;
}
Expand Down Expand Up @@ -108,7 +108,7 @@ impl DbHeadersStore {
self.headers_access.has(hash)
}

pub fn get_header(&self, hash: Hash) -> Result<Header, StoreError> {
pub fn get_header(&self, hash: Hash) -> Result<DagHeader, StoreError> {
let result = self.headers_access.read(hash)?;
Ok((*result.header).clone())
}
Expand All @@ -117,7 +117,7 @@ impl DbHeadersStore {
&self,
batch: &mut WriteBatch,
hash: Hash,
header: Arc<Header>,
header: Arc<DagHeader>,
block_level: BlockLevel,
) -> Result<(), StoreError> {
if self.headers_access.has(hash)? {
Expand Down Expand Up @@ -166,7 +166,7 @@ impl HeaderStoreReader for DbHeadersStore {
Ok(self.compact_headers_access.read(hash)?.difficulty)
}

fn get_header(&self, hash: Hash) -> Result<Arc<Header>, StoreError> {
fn get_header(&self, hash: Hash) -> Result<Arc<DagHeader>, StoreError> {
Ok(self.headers_access.read(hash)?.header)
}

Expand All @@ -186,7 +186,12 @@ impl HeaderStoreReader for DbHeadersStore {
}

impl HeaderStore for DbHeadersStore {
fn insert(&self, hash: Hash, header: Arc<Header>, block_level: u8) -> Result<(), StoreError> {
fn insert(
&self,
hash: Hash,
header: Arc<DagHeader>,
block_level: u8,
) -> Result<(), StoreError> {
if self.headers_access.has(hash)? {
return Err(StoreError::KeyAlreadyExists(hash.to_string()));
}
Expand Down
71 changes: 36 additions & 35 deletions consensus/src/dag/blockdag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ use crate::consensusdb::{
HeaderStore, ReachabilityStoreReader, RelationsStore, RelationsStoreReader,
},
};
use anyhow::{bail, Ok};
use anyhow::{anyhow, bail, Ok};
use parking_lot::RwLock;
use starcoin_crypto::HashValue as Hash;
use starcoin_types::{
blockhash::{BlockHashes, KType, ORIGIN},
header::{ConsensusHeader, Header},
header::{ConsensusHeader, DagHeader},
};
use std::collections::HashMap;
use std::collections::HashSet;
Expand All @@ -26,19 +26,21 @@ pub type DbGhostdagManager = GhostdagManager<
MTReachabilityService<DbReachabilityStore>,
DbHeadersStore,
>;

#[derive(Clone)]
pub struct BlockDAG {
genesis: Header,
genesis_hash: Hash,
ghostdag_manager: DbGhostdagManager,
relations_store: DbRelationsStore,
reachability_store: DbReachabilityStore,
ghostdag_store: DbGhostdagStore,
header_store: DbHeadersStore,
/// orphan blocks, parent hash -> orphan block
missing_blocks: HashMap<Hash, HashSet<Header>>,
missing_blocks: HashMap<Hash, HashSet<DagHeader>>,
}

impl BlockDAG {
pub fn new(genesis: Header, k: KType, db: FlexiDagStorage) -> Self {
pub fn new(genesis_hash: Hash, k: KType, db: FlexiDagStorage) -> Self {
let ghostdag_store = db.ghost_dag_store.clone();
let header_store = db.header_store.clone();
let relations_store = db.relations_store.clone();
Expand All @@ -47,7 +49,7 @@ impl BlockDAG {
let reachability_service =
MTReachabilityService::new(Arc::new(RwLock::new(reachability_store.clone())));
let ghostdag_manager = DbGhostdagManager::new(
genesis.hash(),
genesis_hash,
k,
ghostdag_store.clone(),
relations_store.clone(),
Expand All @@ -56,38 +58,36 @@ impl BlockDAG {
);

let mut dag = Self {
genesis,
genesis_hash,
ghostdag_manager,
relations_store,
reachability_store,
ghostdag_store,
header_store,
missing_blocks: HashMap::new(),
};
dag.init_with_genesis();
dag
}

pub fn clear_missing_block(&mut self) {
self.missing_blocks.clear();
}

pub fn init_with_genesis(&mut self) -> anyhow::Result<()> {
let exits = self.relations_store.has(Hash::new(ORIGIN))?;
if exits {
return Ok(());
}
pub fn init_with_genesis(&mut self, genesis: DagHeader) -> anyhow::Result<()> {
if self.relations_store.has(Hash::new(ORIGIN))? {
return Err(anyhow!("Already init with genesis"));
};
self.relations_store
.insert(Hash::new(ORIGIN), BlockHashes::new(vec![]))
.unwrap();
self.commit_header(&self.genesis.clone())?;
Ok(())
self.commit_header(genesis)
}

pub fn commit_header(&mut self, header: &Header) -> anyhow::Result<()> {
pub fn commit_header(&mut self, header: DagHeader) -> anyhow::Result<()> {
//TODO:check genesis
// Generate ghostdag data
let parents_hash = header.parents_hash();
let ghostdag_data = if header.hash() != self.genesis.hash() {
let ghostdag_data = if header.hash() != self.genesis_hash {
self.ghostdag_manager.ghostdag(parents_hash)
} else {
self.ghostdag_manager.genesis_ghostdag_data()
Expand All @@ -114,43 +114,43 @@ impl BlockDAG {
self.relations_store
.insert(header.hash(), BlockHashes::new(parents_hash.to_vec()))?;
// Store header store
self.header_store
let _ = self
.header_store
.insert(header.hash(), Arc::new(header.to_owned()), 0)?;

Ok(())
}

fn is_in_dag(&self, _hash: Hash) -> anyhow::Result<bool> {
return Ok(true);
}
pub fn verify_header(&self, _header: &Header) -> anyhow::Result<()> {
pub fn verify_header(&self, _header: &DagHeader) -> anyhow::Result<()> {
//TODO: implemented it
Ok(())
}

pub fn connect_block(&mut self, header: &Header) -> anyhow::Result<()> {
let _ = self.verify_header(header)?;
let is_orphan_block = self.update_orphans(header)?;
pub fn connect_block(&mut self, header: DagHeader) -> anyhow::Result<()> {
let _ = self.verify_header(&header)?;
let is_orphan_block = self.update_orphans(&header)?;
if is_orphan_block {
return Ok(());
}
self.commit_header(header);
self.commit_header(header.clone());
self.check_missing_block(header)?;
Ok(())
}

pub fn check_missing_block(&mut self, header: &Header) -> anyhow::Result<()> {
pub fn check_missing_block(&mut self, header: DagHeader) -> anyhow::Result<()> {
if let Some(orphans) = self.missing_blocks.remove(&header.hash()) {
for orphan in orphans.iter() {
let is_orphan = self.is_orphan(&orphan)?;
if !is_orphan {
self.commit_header(header);
self.commit_header(header.clone());
}
}
}
Ok(())
}
fn is_orphan(&self, header: &Header) -> anyhow::Result<bool> {
fn is_orphan(&self, header: &DagHeader) -> anyhow::Result<bool> {
for parent in header.parents_hash() {
if !self.is_in_dag(parent.to_owned())? {
return Ok(false);
Expand All @@ -159,7 +159,7 @@ impl BlockDAG {
return Ok(true);
}

fn update_orphans(&mut self, block_header: &Header) -> anyhow::Result<bool> {
fn update_orphans(&mut self, block_header: &DagHeader) -> anyhow::Result<bool> {
let mut is_orphan = false;
for parent in block_header.parents_hash() {
if self.is_in_dag(parent.to_owned())? {
Expand All @@ -178,7 +178,7 @@ impl BlockDAG {
Ok(is_orphan)
}

pub fn get_block_header(&self, hash: Hash) -> anyhow::Result<Header> {
pub fn get_block_header(&self, hash: Hash) -> anyhow::Result<DagHeader> {
match self.header_store.get_header(hash) {
anyhow::Result::Ok(header) => anyhow::Result::Ok(header),
Err(error) => {
Expand Down Expand Up @@ -218,7 +218,7 @@ impl BlockDAG {
}

pub fn get_genesis_hash(&self) -> Hash {
self.genesis.hash()
self.genesis_hash
}
}

Expand All @@ -228,9 +228,10 @@ mod tests {
use crate::consensusdb::prelude::{FlexiDagStorage, FlexiDagStorageConfig};
use starcoin_types::block::BlockHeader;
use std::{env, fs};

#[test]
fn base_test() {
let genesis = Header::new(BlockHeader::random(), vec![Hash::new(ORIGIN)]);
let genesis = DagHeader::new_genesis(BlockHeader::random());
let genesis_hash = genesis.hash();
let k = 16;
let db_path = env::temp_dir().join("smolstc");
Expand All @@ -245,9 +246,9 @@ mod tests {
let config = FlexiDagStorageConfig::create_with_params(1, 0, 1024);
let db = FlexiDagStorage::create_from_path(db_path, config)
.expect("Failed to create flexidag storage");
let mut dag = BlockDAG::new(genesis, k, db);

let block = Header::new(BlockHeader::random(), vec![genesis_hash]);
dag.commit_header(&block);
let mut dag = BlockDAG::new(genesis_hash, k, db);
dag.init_with_genesis(genesis);
let block = DagHeader::new(BlockHeader::random(), vec![genesis_hash]);
dag.commit_header(block);
}
}
4 changes: 2 additions & 2 deletions node/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ use starcoin_sync::txn_sync::TxnSyncService;
use starcoin_sync::verified_rpc_client::VerifiedRpcClient;
use starcoin_txpool::TxPoolActorService;
use starcoin_types::blockhash::ORIGIN;
use starcoin_types::header::Header;
use starcoin_types::header::DagHeader;
use starcoin_types::system_events::{SystemShutdown, SystemStarted};
use starcoin_vm_runtime::metrics::VMMetrics;
use std::sync::{Arc, Mutex};
Expand Down Expand Up @@ -368,7 +368,7 @@ impl NodeService {
.expect("Failed to create flexidag storage");

let dag = BlockDAG::new(
Header::new(
DagHeader::new(
genesis.block().header().clone(),
vec![HashValue::new(ORIGIN)],
),
Expand Down
4 changes: 2 additions & 2 deletions sync/src/block_connector/test_write_block_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use starcoin_time_service::TimeService;
use starcoin_txpool_mock_service::MockTxPoolService;
use starcoin_types::block::Block;
use starcoin_types::blockhash::ORIGIN;
use starcoin_types::header::Header;
use starcoin_types::header::DagHeader;
use starcoin_types::startup_info::StartupInfo;
use std::sync::{Arc, Mutex};

Expand Down Expand Up @@ -48,7 +48,7 @@ pub async fn create_writeable_block_chain() -> (
.expect("Failed to create flexidag storage");

let dag = BlockDAG::new(
Header::new(
DagHeader::new(
genesis.block().header().clone(),
vec![HashValue::new(ORIGIN)],
),
Expand Down
Loading

0 comments on commit c8556ab

Please sign in to comment.