Skip to content

Commit b55dd02

Browse files
authored
Merge pull request #459 from EspressoSystems/tw/transaction-order-test
Improve transaction order test.
2 parents 0e605cd + 6ec65c8 commit b55dd02

File tree

1 file changed

+33
-19
lines changed

1 file changed

+33
-19
lines changed

tests/src/tests/timeboost/transaction_order.rs

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
1+
use std::collections::HashMap;
12
use std::iter::once;
23
use std::num::NonZeroUsize;
34
use std::time::Duration;
45

6+
use alloy::primitives::B256;
57
use metrics::NoMetrics;
8+
use sailfish_types::RoundNumber;
69
use timeboost_sequencer::{Output, Sequencer};
710
use timeboost_utils::types::logging::init_logging;
811
use tokio::select;
912
use tokio::sync::broadcast::error::RecvError;
1013
use tokio::sync::{broadcast, mpsc};
11-
use tokio::task::JoinSet;
1214
use tokio::time::sleep;
1315
use tokio_util::sync::CancellationToken;
14-
use tracing::info;
16+
use tokio_util::task::TaskTracker;
17+
use tracing::{debug, info};
1518

1619
use super::{gen_bundles, make_configs};
1720

@@ -28,10 +31,11 @@ async fn transaction_order() {
2831
init_logging();
2932

3033
let num = NonZeroUsize::new(5).unwrap();
34+
let quorum = 4;
3135
let (enc_keys, cfg) = make_configs(num, RECOVER_INDEX);
3236

3337
let mut rxs = Vec::new();
34-
let mut tasks = JoinSet::new();
38+
let tasks = TaskTracker::new();
3539
let (bcast, _) = broadcast::channel(3);
3640
let finish = CancellationToken::new();
3741

@@ -42,6 +46,7 @@ async fn transaction_order() {
4246
let (tx, rx) = mpsc::unbounded_channel();
4347
let mut brx = bcast.subscribe();
4448
let finish = finish.clone();
49+
let label = c.sign_keypair().public_key();
4550
tasks.spawn(async move {
4651
if c.is_recover() {
4752
// delay start of a recovering node:
@@ -56,12 +61,11 @@ async fn transaction_order() {
5661
Err(err) => panic!("{err}")
5762
},
5863
out = s.next() => {
59-
let Output::Transactions { transactions, .. } = out.unwrap() else {
64+
let Output::Transactions { round, transactions, .. } = out.unwrap() else {
6065
continue
6166
};
62-
for t in transactions {
63-
tx.send(t).unwrap()
64-
}
67+
let transactions = transactions.into_iter().map(|t| *t.hash()).collect();
68+
tx.send((round, transactions)).unwrap()
6569
}
6670
_ = finish.cancelled() => {
6771
info!(node = %s.public_key(), "done");
@@ -70,7 +74,7 @@ async fn transaction_order() {
7074
}
7175
}
7276
});
73-
rxs.push(rx)
77+
rxs.push((label, rx))
7478
}
7579

7680
for enc_key in &enc_keys {
@@ -79,19 +83,29 @@ async fn transaction_order() {
7983

8084
tasks.spawn(gen_bundles(enc_keys[0].clone(), bcast.clone()));
8185

82-
for _ in 0..NUM_OF_TRANSACTIONS {
83-
let first = rxs[0].recv().await.unwrap();
84-
for rx in &mut rxs[1..] {
85-
let t = rx.recv().await.unwrap();
86-
assert_eq!(first.hash(), t.hash())
86+
let mut map: HashMap<(RoundNumber, Vec<B256>), usize> = HashMap::new();
87+
let mut transactions = 0;
88+
89+
while transactions < NUM_OF_TRANSACTIONS {
90+
map.clear();
91+
info!("{transactions}/{NUM_OF_TRANSACTIONS}");
92+
for (node, r) in &mut rxs {
93+
debug!(%node, "awaiting ...");
94+
let value = r.recv().await.unwrap();
95+
*map.entry(value).or_default() += 1
96+
}
97+
if let Some(((_, trxs), _)) = map.iter().find(|(_, n)| **n >= quorum && **n <= num.get()) {
98+
transactions += trxs.len();
99+
continue;
100+
}
101+
for ((r, trxs), k) in map {
102+
eprintln!(
103+
"{r}: {:?} = {k}",
104+
trxs.into_iter().map(|t| t.to_string()).collect::<Vec<_>>()
105+
)
87106
}
107+
panic!("outputs do not match")
88108
}
89109

90110
finish.cancel();
91-
92-
while let Some(result) = tasks.join_next().await {
93-
if let Err(err) = result {
94-
panic!("task panic: {err}")
95-
}
96-
}
97111
}

0 commit comments

Comments
 (0)