Skip to content

Commit 23b4cb7

Browse files
committed
draw dag
1 parent 7c2a9e9 commit 23b4cb7

File tree

1 file changed

+54
-0
lines changed

1 file changed

+54
-0
lines changed

src/tx_dependency.rs

+54
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ use std::{
44
cmp::{max, min, Reverse},
55
collections::{BTreeMap, BTreeSet, BinaryHeap, VecDeque},
66
};
7+
use std::fs::File;
8+
use std::io::{BufWriter, Write};
79

810
pub(crate) type DependentTxsVec = SmallVec<[TxId; 1]>;
911

@@ -35,6 +37,7 @@ pub(crate) struct TxDependency {
3537

3638
pub round: Option<usize>,
3739
pub block_height: u64,
40+
tx_states: SharedTxStates,
3841
}
3942

4043
impl TxDependency {
@@ -46,6 +49,7 @@ impl TxDependency {
4649
tx_weight: None,
4750
round: None,
4851
block_height: 0,
52+
tx_states: Default::default(),
4953
}
5054
}
5155

@@ -64,6 +68,7 @@ impl TxDependency {
6468
last_write_tx.insert(location.clone(), txid);
6569
}
6670
}
71+
self.tx_states = tx_states;
6772
}
6873

6974
/// Retrieve the optimal partitions based on the dependency relationships between transactions.
@@ -224,12 +229,14 @@ impl TxDependency {
224229
counter!("grevm.total_block_cnt").increment(1);
225230
}
226231
let mut subgraph = BTreeSet::new();
232+
let mut two = false;
227233
if let Some((_, groups)) = weighted_group.last_key_value() {
228234
if self.round.is_none() {
229235
let largest_ratio = groups[0].len() as f64 / num_remaining as f64;
230236
histogram!("grevm.large_graph_ratio").record(largest_ratio);
231237
if groups[0].len() >= num_remaining / 2 {
232238
counter!("grevm.low_parallelism_cnt").increment(1);
239+
two = true;
233240
}
234241
}
235242
if groups[0].len() >= num_remaining / 3 {
@@ -240,16 +247,19 @@ impl TxDependency {
240247
return;
241248
}
242249

250+
let mut longest_chain: Vec<TxId> = vec![];
243251
// ChainLength -> ChainNumber
244252
let mut chains = BTreeMap::new();
245253
let mut visited = HashSet::new();
246254
for txid in subgraph.iter().rev() {
247255
if !visited.contains(txid) {
248256
let mut txid = *txid;
249257
let mut chain_len = 0;
258+
let mut curr_chain = vec![];
250259
while !visited.contains(&txid) {
251260
chain_len += 1;
252261
visited.insert(txid);
262+
curr_chain.push(txid);
253263
let dep: BTreeSet<TxId> =
254264
self.tx_dependency[txid - num_finality_txs].clone().into_iter().collect();
255265
for dep_id in dep.into_iter().rev() {
@@ -259,6 +269,9 @@ impl TxDependency {
259269
}
260270
}
261271
}
272+
if curr_chain.len() > longest_chain.len() {
273+
longest_chain = curr_chain;
274+
}
262275
let chain_num = chains.get(&chain_len).cloned().unwrap_or(0) + 1;
263276
chains.insert(chain_len, chain_num);
264277
}
@@ -282,6 +295,47 @@ impl TxDependency {
282295
counter!("grevm.large_graph", "type" => chain_type, "tip" => tip.clone()).increment(1);
283296
if self.round.is_none() {
284297
info!("Block({}) has large subgraph, type={}", self.block_height, chain_type);
298+
if two && chain_type == "chain" {
299+
self.draw_dag(weighted_group, longest_chain);
300+
}
301+
}
302+
}
303+
}
304+
305+
fn draw_dag(&self, weighted_group: &BTreeMap<usize, Vec<DependentTxsVec>>, longest_chain: Vec<TxId>) {
306+
let file = File::create(format!("dag/block{}.info", self.block_height)).unwrap();
307+
let mut writer = BufWriter::new(file);
308+
writeln!(writer, "[dag]").unwrap();
309+
310+
for txid in (0..self.tx_dependency.len()).rev() {
311+
let deps: BTreeSet<TxId> = self.tx_dependency[txid].clone().into_iter().collect();
312+
for dep_id in deps.into_iter().rev() {
313+
writeln!(writer, "tx{}->tx{}", txid, dep_id).unwrap();
314+
}
315+
}
316+
writeln!(writer, "").unwrap();
317+
318+
let mut locations: HashSet<LocationAndType> = HashSet::new();
319+
info!("Block({}) has large subgraph, longest chain: {:?}", self.block_height, longest_chain);
320+
for index in 0..longest_chain.len() - 1 {
321+
let txid = longest_chain[index];
322+
let dep_id = longest_chain[index + 1];
323+
let rs = self.tx_states[txid].read_set.clone();
324+
let ws = self.tx_states[dep_id].write_set.clone();
325+
let mut intersection = HashSet::new();
326+
for l in ws {
327+
if rs.contains_key(&l) {
328+
intersection.insert(l);
329+
}
330+
}
331+
if locations.is_empty() {
332+
locations = intersection;
333+
} else {
334+
let join: HashSet<LocationAndType> = locations.intersection(&intersection).cloned().collect();
335+
if join.is_empty() {
336+
info!("Block({}) has large subgraph, ==> tx{}: {:?}", self.block_height, txid, locations);
337+
}
338+
locations = join;
285339
}
286340
}
287341
}

0 commit comments

Comments
 (0)