Skip to content

Commit 2a8f948

Browse files
committed
Refactor dag connect
1 parent 0d84add commit 2a8f948

File tree

4 files changed

+77
-100
lines changed

4 files changed

+77
-100
lines changed

chain/src/chain.rs

Lines changed: 62 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ use std::cmp::min;
4646
use std::iter::Extend;
4747
use std::option::Option::{None, Some};
4848
use std::{collections::HashMap, sync::Arc};
49+
use starcoin_types::header::DagHeader;
4950

5051

5152
pub struct ChainStatusWithBlock {
@@ -452,25 +453,25 @@ impl BlockChain {
452453
let blues = block.uncles().expect("Blue blocks must exist");
453454
let (selected_parent, blues) = blues.split_at(1);
454455
let selected_parent = selected_parent[0].clone();
455-
let block_info = self.storage.get_block_info(selected_parent.id())?.expect("selected parent must executed");
456+
let block_info_past = self.storage.get_block_info(selected_parent.id())?.expect("selected parent must executed");
456457
let header = block.header();
457-
458458
let block_id = header.id();
459-
460459
let block_metadata = block.to_metadata(selected_parent.gas_used());
461-
let mut transaction = vec![Transaction::BlockMetadata(block_metadata)];
460+
let mut transactions = vec![Transaction::BlockMetadata(block_metadata)];
461+
let mut total_difficulty = header.difficulty() + block_info_past.total_difficulty;
462462
for blue in blues {
463463
let blue_block = self.storage.get_block_by_hash(blue.parent_hash())?.expect("block blue need exist");
464-
transaction.extend(blue_block.transactions().iter().cloned().map(Transaction::UserTransaction))
464+
transactions.extend(blue_block.transactions().iter().cloned().map(Transaction::UserTransaction));
465+
total_difficulty += blue_block.header.difficulty();
465466
}
466-
transaction.extend(
467+
transactions.extend(
467468
block.transactions().iter().cloned().map(Transaction::UserTransaction),
468469
);
469470

470471
watch(CHAIN_WATCH_NAME, "n21");
471472
let executed_data = starcoin_executor::block_execute(
472473
&self.statedb,
473-
transaction.clone(),
474+
transactions.clone(),
474475
self.epoch.block_gas_limit(), //TODO: Fix me
475476
self.vm_metrics.clone(),
476477
)?;
@@ -494,18 +495,18 @@ impl BlockChain {
494495

495496
verify_block!(
496497
VerifyBlockField::State,
497-
vec_transaction_info.len() == transaction.len(),
498+
vec_transaction_info.len() == transactions.len(),
498499
"invalid txn num in the block"
499500
);
500-
let txn_accumulator= info_2_accumulator(
501-
block_info.txn_accumulator_info,
502-
AccumulatorStoreType::Transaction,
503-
self.storage.as_ref(),
501+
let txn_accumulator = info_2_accumulator(
502+
block_info_past.txn_accumulator_info,
503+
AccumulatorStoreType::Transaction,
504+
self.storage.as_ref(),
504505
);
505-
let block_accumulator= info_2_accumulator(
506-
block_info.block_accumulator_info,
507-
AccumulatorStoreType::Block,
508-
self.storage.as_ref(),
506+
let block_accumulator = info_2_accumulator(
507+
block_info_past.block_accumulator_info,
508+
AccumulatorStoreType::Block,
509+
self.storage.as_ref(),
509510
);
510511
let transaction_global_index = txn_accumulator.num_leaves();
511512

@@ -534,8 +535,6 @@ impl BlockChain {
534535
.flush()
535536
.map_err(|_err| BlockExecutorError::BlockAccumulatorFlushErr)?;
536537

537-
let pre_total_difficulty = block_info.total_difficulty;
538-
let total_difficulty = pre_total_difficulty + header.difficulty();
539538

540539
block_accumulator.append(&[block_id])?;
541540
block_accumulator.flush()?;
@@ -588,12 +587,12 @@ impl BlockChain {
588587
.collect(),
589588
)?;
590589

591-
let txn_id_vec = transaction
590+
let txn_id_vec = transactions
592591
.iter()
593592
.map(|user_txn| user_txn.id())
594593
.collect::<Vec<HashValue>>();
595594
// save transactions
596-
self.storage.save_transaction_batch(transaction)?;
595+
self.storage.save_transaction_batch(transactions)?;
597596

598597
// save block's transactions
599598
self.storage.save_block_transaction_ids(block_id, txn_id_vec)?;
@@ -602,7 +601,7 @@ impl BlockChain {
602601
self.storage.save_block_info(block_info.clone())?;
603602

604603
self.storage.save_table_infos(txn_table_infos)?;
605-
604+
self.dag.commit(DagHeader::new(header.clone()))?;
606605
watch(CHAIN_WATCH_NAME, "n26");
607606
Ok(ExecutedBlock { block, block_info })
608607
}
@@ -767,9 +766,7 @@ impl BlockChain {
767766
storage.save_block_txn_info_ids(block_id, txn_info_ids)?;
768767
storage.commit_block(block.clone())?;
769768
storage.save_block_info(block_info.clone())?;
770-
771769
storage.save_table_infos(txn_table_infos)?;
772-
773770
watch(CHAIN_WATCH_NAME, "n26");
774771
Ok(ExecutedBlock { block, block_info })
775772
}
@@ -1333,8 +1330,49 @@ impl BlockChain {
13331330
}
13341331

13351332
fn connect_dag(&mut self, executed_block: ExecutedBlock) -> Result<ExecutedBlock> {
1336-
let (block, block_info) = (executed_block.block(), executed_block.block_info());
1333+
let (new_tip_block, _) = (executed_block.block(), executed_block.block_info());
1334+
let mut tips = self.status.dag_tips().expect("Tips should exist on dag").clone();
1335+
let parents = executed_block.block.header.parents_hash().expect("Dag parents need exist");
1336+
for hash in parents {
1337+
tips.retain(|x| *x != hash);
1338+
}
1339+
tips.push(new_tip_block.id());
1340+
1341+
let block_hash = {
1342+
let ghost_of_tips = self.dag.ghostdata(tips.as_slice());
1343+
ghost_of_tips.selected_parent
1344+
};
1345+
let (block, block_info) = {
1346+
let block = self.storage.get_block(block_hash)?.expect("Dag block should exist");
1347+
let block_info = self.storage.get_block_info(block_hash)?.expect("Dag block info should exist");
1348+
(block, block_info)
1349+
};
1350+
1351+
1352+
let txn_accumulator_info = block_info.get_txn_accumulator_info();
1353+
let block_accumulator_info = block_info.get_block_accumulator_info();
1354+
let state_root = block.header().state_root();
13371355

1356+
self.txn_accumulator = info_2_accumulator(
1357+
txn_accumulator_info.clone(),
1358+
AccumulatorStoreType::Transaction,
1359+
self.storage.as_ref(),
1360+
);
1361+
self.block_accumulator = info_2_accumulator(
1362+
block_accumulator_info.clone(),
1363+
AccumulatorStoreType::Block,
1364+
self.storage.as_ref(),
1365+
);
1366+
1367+
self.statedb = ChainStateDB::new(self.storage.clone().into_super_arc(), Some(state_root));
1368+
1369+
self.status = ChainStatusWithBlock {
1370+
status: ChainStatus::new(block.header().clone(), block_info.clone(), Some(tips)),
1371+
head: block.clone(),
1372+
};
1373+
if self.epoch.end_block_number() == block.header().number() {
1374+
self.epoch = get_epoch_from_statedb(&self.statedb)?;
1375+
}
13381376
Ok(executed_block)
13391377
}
13401378
}

consensus/src/consensusdb/consensus_relations.rs

Lines changed: 3 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ pub trait RelationsStoreReader {
2121
/// non-append-only and thus needs to be guarded.
2222
pub trait RelationsStore: RelationsStoreReader {
2323
/// Inserts `parents` into a new store entry for `hash`, and for each `parent ∈ parents` adds `hash` to `parent.children`
24-
fn insert(&mut self, hash: Hash, parents: BlockHashes) -> Result<(), StoreError>;
24+
fn insert(&self, hash: Hash, parents: BlockHashes) -> Result<(), StoreError>;
2525
}
2626

2727
pub(crate) const PARENTS_CF: &str = "block-parents";
@@ -149,7 +149,7 @@ impl RelationsStoreReader for DbRelationsStore {
149149
impl RelationsStore for DbRelationsStore {
150150
/// See `insert_batch` as well
151151
/// TODO: use one function with DbWriter for both this function and insert_batch
152-
fn insert(&mut self, hash: Hash, parents: BlockHashes) -> Result<(), StoreError> {
152+
fn insert(&self, hash: Hash, parents: BlockHashes) -> Result<(), StoreError> {
153153
if self.has(hash)? {
154154
return Err(StoreError::KeyAlreadyExists(hash.to_string()));
155155
}
@@ -180,67 +180,6 @@ impl RelationsStore for DbRelationsStore {
180180
}
181181
}
182182

183-
pub struct MemoryRelationsStore {
184-
parents_map: BlockHashMap<BlockHashes>,
185-
children_map: BlockHashMap<BlockHashes>,
186-
}
187-
188-
impl MemoryRelationsStore {
189-
pub fn new() -> Self {
190-
Self {
191-
parents_map: BlockHashMap::new(),
192-
children_map: BlockHashMap::new(),
193-
}
194-
}
195-
}
196-
197-
impl Default for MemoryRelationsStore {
198-
fn default() -> Self {
199-
Self::new()
200-
}
201-
}
202-
203-
impl RelationsStoreReader for MemoryRelationsStore {
204-
fn get_parents(&self, hash: Hash) -> Result<BlockHashes, StoreError> {
205-
match self.parents_map.get(&hash) {
206-
Some(parents) => Ok(BlockHashes::clone(parents)),
207-
None => Err(StoreError::KeyNotFound(hash.to_string())),
208-
}
209-
}
210-
211-
fn get_children(&self, hash: Hash) -> Result<BlockHashes, StoreError> {
212-
match self.children_map.get(&hash) {
213-
Some(children) => Ok(BlockHashes::clone(children)),
214-
None => Err(StoreError::KeyNotFound(hash.to_string())),
215-
}
216-
}
217-
218-
fn has(&self, hash: Hash) -> Result<bool, StoreError> {
219-
Ok(self.parents_map.contains_key(&hash))
220-
}
221-
}
222-
223-
impl RelationsStore for MemoryRelationsStore {
224-
fn insert(&mut self, hash: Hash, parents: BlockHashes) -> Result<(), StoreError> {
225-
if let Vacant(e) = self.parents_map.entry(hash) {
226-
// Update the new entry for `hash`
227-
e.insert(BlockHashes::clone(&parents));
228-
229-
// Update `children` for each parent
230-
for parent in parents.iter().cloned() {
231-
let mut children = (*self.get_children(parent)?).clone();
232-
children.push(hash);
233-
self.children_map.insert(parent, BlockHashes::new(children));
234-
}
235-
236-
// The new hash has no children yet
237-
self.children_map.insert(hash, BlockHashes::new(Vec::new()));
238-
Ok(())
239-
} else {
240-
Err(StoreError::KeyAlreadyExists(hash.to_string()))
241-
}
242-
}
243-
}
244183

245184
#[cfg(test)]
246185
mod tests {
@@ -250,10 +189,7 @@ mod tests {
250189
prelude::{FlexiDagStorage, FlexiDagStorageConfig},
251190
};
252191

253-
#[test]
254-
fn test_memory_relations_store() {
255-
test_relations_store(MemoryRelationsStore::new());
256-
}
192+
257193

258194
#[test]
259195
fn test_db_relations_store() {

consensus/src/dag/blockdag.rs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use crate::consensusdb::{
1212
};
1313
use anyhow::{anyhow, bail, Ok};
1414
use parking_lot::RwLock;
15-
use starcoin_crypto::HashValue as Hash;
15+
use starcoin_crypto::{HashValue as Hash, HashValue};
1616
use starcoin_types::{
1717
blockhash::{BlockHashes, KType, ORIGIN},
1818
header::{ConsensusHeader, DagHeader},
@@ -81,11 +81,14 @@ impl BlockDAG {
8181
self.relations_store
8282
.insert(Hash::new(ORIGIN), BlockHashes::new(vec![]))
8383
.unwrap();
84-
let _ = self.addToDag(genesis);
84+
let _ = self.commit(genesis);
8585
Ok(())
8686
}
87+
pub fn ghostdata(&self, parents: &[HashValue]) -> GhostdagData {
88+
self.ghostdag_manager.ghostdag(parents)
89+
}
8790

88-
pub fn addToDag(&mut self, header: DagHeader) -> anyhow::Result<GhostdagData> {
91+
pub fn commit(&self, header: DagHeader) -> anyhow::Result<()> {
8992
//TODO:check genesis
9093
// Generate ghostdag data
9194
let parents_hash = header.parents_hash();
@@ -119,7 +122,7 @@ impl BlockDAG {
119122
let _ = self
120123
.header_store
121124
.insert(header.hash(), Arc::new(header.to_owned()), 0)?;
122-
return Ok(ghostdag_data.clone());
125+
return Ok(());
123126
}
124127

125128
fn is_in_dag(&self, _hash: Hash) -> anyhow::Result<bool> {
@@ -136,7 +139,7 @@ impl BlockDAG {
136139
if is_orphan_block {
137140
return Ok(());
138141
}
139-
self.addToDag(header.clone());
142+
self.commit(header.clone());
140143
self.check_missing_block(header)?;
141144
Ok(())
142145
}
@@ -146,7 +149,7 @@ impl BlockDAG {
146149
for orphan in orphans.iter() {
147150
let is_orphan = self.is_orphan(&orphan)?;
148151
if !is_orphan {
149-
self.addToDag(header.clone());
152+
self.commit(header.clone());
150153
}
151154
}
152155
}
@@ -254,7 +257,7 @@ mod tests {
254257
.expect("Failed to create flexidag storage");
255258
let mut dag = BlockDAG::new(genesis_hash, k, db);
256259
dag.init_with_genesis(genesis);
257-
let block = DagHeader::new(BlockHeader::random(), vec![genesis_hash]);
258-
dag.addToDag(block);
260+
let block = DagHeader::new(BlockHeader::random());
261+
dag.commit(block);
259262
}
260263
}

sync/src/block_connector/write_block_chain.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -687,7 +687,7 @@ where
687687

688688
fn connect_dag_inner(&mut self, block: Block) -> Result<ConnectOk> {
689689
let block_id = block.id();
690-
let ghost_dag_data = self.dag.lock().addToDag(DagHeader::new(block.header))?;
690+
let ghost_dag_data = self.dag.lock().commit(DagHeader::new(block.header))?;
691691
let selected_parent = self
692692
.storage
693693
.get_block_by_hash(ghost_dag_data.selected_parent)?

0 commit comments

Comments
 (0)