Skip to content

Commit bb04633

Browse files
authored
Merge pull request #473 from EspressoSystems/ak/handover-test
Timeboost committee switch-over e2e test
2 parents bb787d4 + 1651ab4 commit bb04633

File tree

15 files changed

+1621
-756
lines changed

15 files changed

+1621
-756
lines changed

.config/nextest.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,7 @@
11
[profile.default]
22
slow-timeout = { period = "60s", terminate-after = 2 }
3+
4+
[[profile.default.overrides]]
5+
filter = 'test(/^tests::timeboost::timeboost_handover::/)'
6+
threads-required = 2
7+
slow-timeout = { period = "300s", terminate-after = 1 }

Cargo.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cliquenet/src/addr.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,13 @@ impl AddressableCommittee {
194194
.map(|(k, (x, a))| (*k, *x, a.clone()))
195195
}
196196

197+
pub fn update_addresses<F>(&mut self, f: F)
198+
where
199+
F: Fn(&Address) -> Address,
200+
{
201+
self.addresses.values_mut().for_each(|(_, a)| *a = f(a))
202+
}
203+
197204
/// Assert that addresses and committee have the same keys.
198205
fn assert_shared_domain(&self) {
199206
for p in self.committee.parties() {

tests/src/tests/timeboost.rs

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,28 @@
11
mod block_order;
22
mod handover;
33
mod test_timeboost_startup;
4+
mod timeboost_handover;
45
mod transaction_order;
56

7+
use std::collections::HashMap;
68
use std::net::Ipv4Addr;
79
use std::num::NonZeroUsize;
10+
use std::sync::atomic::{AtomicU64, Ordering};
811

9-
use alloy::eips::BlockNumberOrTag;
12+
use alloy::eips::{BlockNumberOrTag, Encodable2718};
13+
use bytes::Bytes;
1014
use cliquenet::{Address, AddressableCommittee};
15+
use metrics::NoMetrics;
1116
use multisig::Keypair;
1217
use multisig::{Committee, x25519};
13-
use sailfish_types::UNKNOWN_COMMITTEE_ID;
18+
use parking_lot::Mutex;
19+
use sailfish_types::{RoundNumber, UNKNOWN_COMMITTEE_ID};
1420
use test_utils::ports::alloc_ports;
1521
use timeboost::builder::CertifierConfig;
1622
use timeboost::config::{ChainConfig, ParentChain};
1723
use timeboost::crypto::prelude::DkgDecKey;
18-
use timeboost::sequencer::SequencerConfig;
19-
use timeboost::types::BundleVariant;
20-
use timeboost::types::{DecryptionKeyCell, KeyStore};
24+
use timeboost::sequencer::{Sequencer, SequencerConfig};
25+
use timeboost::types::{BlockNumber, BundleVariant, DecryptionKeyCell, KeyStore, Transaction};
2126
use timeboost_utils::load_generation::make_bundle;
2227
use tokio::sync::broadcast;
2328
use tokio::time::{Duration, sleep};
@@ -151,3 +156,38 @@ async fn gen_bundles(enc_key: DecryptionKeyCell, tx: broadcast::Sender<BundleVar
151156
sleep(Duration::from_millis(10)).await
152157
}
153158
}
159+
160+
fn hash(tx: &[Transaction]) -> Bytes {
161+
let mut h = blake3::Hasher::new();
162+
for t in tx {
163+
h.update(&t.encoded_2718());
164+
}
165+
Bytes::copy_from_slice(h.finalize().as_bytes())
166+
}
167+
168+
/// Map round numbers to block numbers.
169+
///
170+
/// Block numbers need to be consistent, consecutive and strictly monotonic.
171+
/// The round numbers of our sequencer output may contain gaps. To provide
172+
/// block numbers with the required properties we have here one monotonic
173+
/// counter and record which block number is used for a round number.
174+
/// Subsequent lookups will then get a consistent result.
175+
struct Round2Block {
176+
counter: AtomicU64,
177+
block_numbers: Mutex<HashMap<RoundNumber, BlockNumber>>,
178+
}
179+
180+
impl Round2Block {
181+
fn new() -> Self {
182+
Self {
183+
counter: AtomicU64::new(0),
184+
block_numbers: Mutex::new(HashMap::new()),
185+
}
186+
}
187+
188+
fn get(&self, r: RoundNumber) -> BlockNumber {
189+
let mut map = self.block_numbers.lock();
190+
*map.entry(r)
191+
.or_insert_with(|| self.counter.fetch_add(1, Ordering::Relaxed).into())
192+
}
193+
}

tests/src/tests/timeboost/block_order.rs

Lines changed: 4 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,13 @@ use std::collections::HashMap;
22
use std::iter::once;
33
use std::num::NonZeroUsize;
44
use std::sync::Arc;
5-
use std::sync::atomic::{AtomicU64, Ordering};
65
use std::time::Duration;
76

8-
use alloy::eips::Encodable2718;
9-
use bytes::Bytes;
107
use metrics::NoMetrics;
118
use multisig::Certificate;
12-
use parking_lot::Mutex;
139
use timeboost::builder::Certifier;
1410
use timeboost::sequencer::{Output, Sequencer};
15-
use timeboost::types::sailfish::RoundNumber;
16-
use timeboost::types::{Block, BlockInfo, BlockNumber, Transaction};
11+
use timeboost::types::{Block, BlockInfo};
1712
use timeboost_utils::types::logging::init_logging;
1813
use tokio::select;
1914
use tokio::sync::broadcast::error::RecvError;
@@ -23,6 +18,8 @@ use tokio_util::sync::CancellationToken;
2318
use tokio_util::task::TaskTracker;
2419
use tracing::{debug, error, info};
2520

21+
use crate::tests::timeboost::{Round2Block, hash};
22+
2623
use super::{gen_bundles, make_configs};
2724

2825
const NUM_OF_BLOCKS: usize = 50;
@@ -56,6 +53,7 @@ async fn block_order() {
5653
let mut s = Sequencer::new(c, &NoMetrics).await.unwrap();
5754
let mut p = Certifier::new(b, &NoMetrics).await.unwrap();
5855
let mut r = None;
56+
5957
let handle = p.handle();
6058
loop {
6159
select! {
@@ -124,38 +122,3 @@ async fn block_order() {
124122

125123
finish.cancel();
126124
}
127-
128-
fn hash(tx: &[Transaction]) -> Bytes {
129-
let mut h = blake3::Hasher::new();
130-
for t in tx {
131-
h.update(&t.encoded_2718());
132-
}
133-
Bytes::copy_from_slice(h.finalize().as_bytes())
134-
}
135-
136-
/// Map round numbers to block numbers.
137-
///
138-
/// Block numbers need to be consistent, consecutive and strictly monotonic.
139-
/// The round numbers of our sequencer output may contain gaps. To provide
140-
/// block numbers with the required properties we have here one monotonic
141-
/// counter and record which block number is used for a round number.
142-
/// Subsequent lookups will then get a consistent result.
143-
struct Round2Block {
144-
counter: AtomicU64,
145-
block_numbers: Mutex<HashMap<RoundNumber, BlockNumber>>,
146-
}
147-
148-
impl Round2Block {
149-
fn new() -> Self {
150-
Self {
151-
counter: AtomicU64::new(0),
152-
block_numbers: Mutex::new(HashMap::new()),
153-
}
154-
}
155-
156-
fn get(&self, r: RoundNumber) -> BlockNumber {
157-
let mut map = self.block_numbers.lock();
158-
*map.entry(r)
159-
.or_insert_with(|| self.counter.fetch_add(1, Ordering::Relaxed).into())
160-
}
161-
}

tests/src/tests/timeboost/handover.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -183,19 +183,17 @@ where
183183
///
184184
/// NB that the decryption parts of the config are not used yet.
185185
async fn mk_node(cfg: &SequencerConfig) -> Coordinator<Timestamp, Rbc<Timestamp>> {
186-
let met = NetworkMetrics::new(
187-
"sailfish",
188-
&NoMetrics,
189-
cfg.sailfish_committee().parties().copied(),
190-
);
191-
192186
let mut net = Network::create(
193187
"sailfish",
194188
cfg.sailfish_address().clone(),
195189
cfg.sign_keypair().public_key(),
196190
cfg.dh_keypair().clone(),
197191
cfg.sailfish_committee().entries(),
198-
met,
192+
NetworkMetrics::new(
193+
"sailfish",
194+
&NoMetrics,
195+
cfg.sailfish_committee().parties().copied(),
196+
),
199197
)
200198
.await
201199
.unwrap();

0 commit comments

Comments
 (0)