Skip to content

Commit 3710628

Browse files
committed
test macro
1 parent 2110a3e commit 3710628

14 files changed

Lines changed: 347 additions & 278 deletions

File tree

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
members = [
33
".", # The main rblib library
44
"tools/fbutil",
5+
"src/tests/framework/macros"
56
]
67
resolver = "2"
78

@@ -93,6 +94,7 @@ tracing-subscriber = { workspace = true }
9394

9495
[dev-dependencies]
9596
rblib = { workspace = true, features = ["test-utils"] }
97+
macros = { path = "src/tests/framework/macros" }
9698

9799
dashmap = { workspace = true }
98100
orx-concurrent-vec = { workspace = true }

src/args.rs

Lines changed: 10 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,16 @@ impl Default for BuilderArgs {
109109
}
110110
}
111111

112+
impl Default for FlashblocksArgs {
113+
fn default() -> Self {
114+
let args = crate::args::Cli::parse_from(["dummy", "node"]);
115+
let Commands::Node(node_command) = args.command else {
116+
unreachable!()
117+
};
118+
node_command.ext.flashblocks_args
119+
}
120+
}
121+
112122
/// This trait is used to extend Reth's CLI with additional functionality that
113123
/// are specific to the OP builder, such as populating default values for CLI
114124
/// arguments when running in the playground mode or checking the builder mode.
@@ -187,55 +197,3 @@ fn expand_path(s: &str) -> Result<PathBuf> {
187197
.parse()
188198
.map_err(|e| eyre!("invalid path after expansion: {e}"))
189199
}
190-
191-
#[cfg(test)]
192-
impl FlashblocksArgs {
193-
/// Configures flashblocks for tests. Handles WS port assignment.
194-
pub fn default_on_for_tests() -> Self {
195-
use core::net::{Ipv4Addr, SocketAddrV4};
196-
197-
Self {
198-
interval: Duration::from_millis(250),
199-
leeway_time: Duration::from_millis(75),
200-
ws_address: SocketAddrV4::new(
201-
Ipv4Addr::UNSPECIFIED,
202-
Self::get_available_port(),
203-
)
204-
.into(),
205-
206-
calculate_state_root: true,
207-
}
208-
}
209-
210-
pub fn default_on_custom_leeway_time_and_interval_for_tests(
211-
leeway_time: Duration,
212-
interval: Duration,
213-
) -> Self {
214-
use core::net::{Ipv4Addr, SocketAddrV4};
215-
216-
Self {
217-
interval,
218-
leeway_time,
219-
ws_address: SocketAddrV4::new(
220-
Ipv4Addr::UNSPECIFIED,
221-
Self::get_available_port(),
222-
)
223-
.into(),
224-
225-
calculate_state_root: true,
226-
}
227-
}
228-
229-
/// Gets an available port by first binding to port 0 -- instructing the OS to
230-
/// find and assign one. Then the listener is dropped when this goes out of
231-
/// scope, freeing the port for the next time this function is called.
232-
fn get_available_port() -> u16 {
233-
use std::net::TcpListener;
234-
235-
TcpListener::bind("127.0.0.1:0")
236-
.expect("Failed to bind to random port")
237-
.local_addr()
238-
.expect("Failed to get local address")
239-
.port()
240-
}
241-
}

src/main.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use {
1919
steps::*,
2020
},
2121
std::sync::Arc,
22+
tracing::info,
2223
};
2324

2425
mod args;
@@ -82,6 +83,7 @@ fn build_pipeline(
8283
cli_args: &BuilderArgs,
8384
pool: &OrderPool<Flashblocks>,
8485
) -> eyre::Result<Pipeline<Flashblocks>> {
86+
info!("ARGS: {cli_args:?}");
8587
let flashblock_interval = cli_args.flashblocks_args.interval;
8688

8789
// time by which flashblocks will be delivered earlier to account for latency

src/tests/bundle.rs

Lines changed: 37 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
use {
22
crate::{
33
Flashblocks,
4+
args::BuilderArgs,
45
bundle::FlashblocksBundle,
5-
tests::assert_has_sequencer_tx,
6+
tests::{Harness, assert_has_sequencer_tx},
67
},
78
jsonrpsee::core::ClientError,
9+
macros::unichain_test,
810
rand::{Rng, rng},
911
rblib::{
1012
alloy::{
@@ -139,9 +141,9 @@ pub fn random_bundle_with_reverts(
139141
FlashblocksBundle::with_transactions(txs)
140142
}
141143

142-
#[tokio::test]
143-
async fn empty_bundle_rejected() -> eyre::Result<()> {
144-
let (node, _) = Flashblocks::test_node().await?;
144+
#[unichain_test]
145+
async fn empty_bundle_rejected(harness: Harness) -> eyre::Result<()> {
146+
let node = harness.node();
145147

146148
let empty_bundle = FlashblocksBundle::with_transactions(vec![]);
147149
let result = BundlesApiClient::<Flashblocks>::send_bundle(
@@ -157,9 +159,9 @@ async fn empty_bundle_rejected() -> eyre::Result<()> {
157159

158160
/// This bundle should be rejected by because we only support bundles with one
159161
/// transaction
160-
#[tokio::test]
161-
async fn bundle_with_two_txs_rejected() -> eyre::Result<()> {
162-
let (node, _) = Flashblocks::test_node().await?;
162+
#[unichain_test]
163+
async fn bundle_with_two_txs_rejected(harness: Harness) -> eyre::Result<()> {
164+
let node = harness.node();
163165

164166
let bundle_with_two_txs = random_valid_bundle(2);
165167

@@ -174,9 +176,9 @@ async fn bundle_with_two_txs_rejected() -> eyre::Result<()> {
174176
Ok(())
175177
}
176178

177-
#[tokio::test]
178-
async fn valid_tx_included() -> eyre::Result<()> {
179-
let (node, _) = Flashblocks::test_node().await?;
179+
#[unichain_test]
180+
async fn valid_tx_included(harness: Harness) -> eyre::Result<()> {
181+
let node = harness.node();
180182

181183
let bundle_with_one_tx = random_valid_bundle(1);
182184
let bundle_hash = bundle_with_one_tx.hash();
@@ -199,9 +201,9 @@ async fn valid_tx_included() -> eyre::Result<()> {
199201
Ok(())
200202
}
201203

202-
#[tokio::test]
203-
async fn reverted_tx_not_included() -> eyre::Result<()> {
204-
let (node, _) = Flashblocks::test_node().await?;
204+
#[unichain_test]
205+
async fn reverted_tx_not_included(harness: Harness) -> eyre::Result<()> {
206+
let node = harness.node();
205207

206208
let bundle_with_reverts = random_bundle_with_reverts(0, 1);
207209

@@ -223,9 +225,9 @@ async fn reverted_tx_not_included() -> eyre::Result<()> {
223225

224226
/// Bundles that will never be eligible for inclusion in any future block
225227
/// should be rejected by the RPC before making it to the orders pool.
226-
#[tokio::test]
227-
async fn max_block_number_in_past() -> eyre::Result<()> {
228-
let (node, _) = Flashblocks::test_node().await?;
228+
#[unichain_test]
229+
async fn max_block_number_in_past(harness: Harness) -> eyre::Result<()> {
230+
let node = harness.node();
229231

230232
let block = node.next_block().await?;
231233
assert_eq!(block.number(), 1);
@@ -249,10 +251,10 @@ async fn max_block_number_in_past() -> eyre::Result<()> {
249251

250252
/// This bundle should be rejected because its `max_timestamp` is in the past
251253
/// and it will never be eligible for inclusion in any future block.
252-
#[tokio::test]
253-
async fn max_block_timestamp_in_past() -> eyre::Result<()> {
254+
#[unichain_test]
255+
async fn max_block_timestamp_in_past(harness: Harness) -> eyre::Result<()> {
254256
// node at genesis, block 0
255-
let (node, _) = Flashblocks::test_node().await?;
257+
let node = harness.node();
256258
let genesis_timestamp = node.config().chain.genesis_timestamp();
257259
let mut bundle = random_valid_bundle(1);
258260
bundle.max_timestamp = Some(genesis_timestamp.saturating_sub(1));
@@ -268,10 +270,12 @@ async fn max_block_timestamp_in_past() -> eyre::Result<()> {
268270
Ok(())
269271
}
270272

271-
#[tokio::test]
272-
async fn min_block_greater_than_max_block() -> eyre::Result<()> {
273+
#[unichain_test]
274+
async fn min_block_greater_than_max_block(
275+
harness: Harness,
276+
) -> eyre::Result<()> {
273277
// node at genesis, block 0
274-
let (node, _) = Flashblocks::test_node().await?;
278+
let node = harness.node();
275279
let mut bundle = random_valid_bundle(1);
276280
bundle.min_block_number = Some(2);
277281
bundle.max_block_number = Some(1);
@@ -289,9 +293,9 @@ async fn min_block_greater_than_max_block() -> eyre::Result<()> {
289293

290294
/// Test that a bundle with the `min_block_number` param set to a future block
291295
/// isn't included until that block.
292-
#[tokio::test]
293-
async fn min_block_number_in_future() -> eyre::Result<()> {
294-
let (node, _) = Flashblocks::test_node().await?;
296+
#[unichain_test]
297+
async fn min_block_number_in_future(harness: Harness) -> eyre::Result<()> {
298+
let node = harness.node();
295299

296300
let mut bundle_with_one_tx = random_valid_bundle(1);
297301
bundle_with_one_tx.min_block_number = Some(2);
@@ -321,9 +325,14 @@ async fn min_block_number_in_future() -> eyre::Result<()> {
321325
Ok(())
322326
}
323327

324-
#[tokio::test]
325-
async fn when_disabled_reverted_txs_are_included() -> eyre::Result<()> {
326-
let (node, _) = Flashblocks::test_node_with_revert_protection_off().await?;
328+
#[unichain_test(args = BuilderArgs {
329+
revert_protection: false,
330+
..Default::default()
331+
})]
332+
async fn when_disabled_reverted_txs_are_included(
333+
harness: Harness,
334+
) -> eyre::Result<()> {
335+
let node = harness.node();
327336

328337
// create a bundle with one valid and one reverting tx
329338
let mut bundle_with_reverts = random_bundle_with_reverts(0, 1);

src/tests/flashblocks.rs

Lines changed: 47 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,20 @@
33
#![allow(clippy::large_futures)]
44

55
use {
6-
crate::{Flashblocks, tests::*},
6+
crate::{
7+
Flashblocks,
8+
args::{BuilderArgs, FlashblocksArgs},
9+
tests::*,
10+
},
11+
macros::unichain_test,
712
rblib::alloy::{eips::Decodable2718, network::BlockResponse},
813
std::time::{Duration, SystemTime, UNIX_EPOCH},
914
};
1015

11-
#[tokio::test]
12-
async fn empty_blocks_smoke() -> eyre::Result<()> {
13-
let (node, ws_addr) = Flashblocks::test_node().await?;
14-
let ws = WebSocketObserver::new(ws_addr).await?;
16+
#[unichain_test]
17+
async fn empty_blocks_smoke(harness: Harness) -> eyre::Result<()> {
18+
let node = harness.node();
19+
let ws = harness.ws_observer().await?;
1520

1621
for i in 1..=5 {
1722
let block = node.next_block().await?;
@@ -40,13 +45,13 @@ async fn empty_blocks_smoke() -> eyre::Result<()> {
4045
Ok(())
4146
}
4247

43-
#[tokio::test]
44-
async fn blocks_with_txs_smoke() -> eyre::Result<()> {
48+
#[unichain_test]
49+
async fn blocks_with_txs_smoke(harness: Harness) -> eyre::Result<()> {
4550
const BLOCKS: usize = 5;
4651
const TXS_PER_BLOCK: usize = 60;
4752

48-
let (node, ws_addr) = Flashblocks::test_node().await?;
49-
let ws = WebSocketObserver::new(ws_addr).await?;
53+
let node = harness.node();
54+
let ws = harness.ws_observer().await?;
5055

5156
for i in 1..=BLOCKS {
5257
let mut sent_txs = Vec::new();
@@ -100,19 +105,22 @@ async fn blocks_with_txs_smoke() -> eyre::Result<()> {
100105
}
101106

102107
// This test is to check that we get 8 flashblocks with 2000ms remaining time
103-
// and 250ms flashblock interval and 75ms leeway time
104-
#[tokio::test]
105-
async fn flashblock_timings_2000ms_block_time_0ms_leeway_time()
106-
-> eyre::Result<()> {
108+
// and 250ms flashblock interval and 0ms leeway time
109+
#[unichain_test(args = BuilderArgs {
110+
flashblocks_args: FlashblocksArgs {
111+
interval: Duration::from_millis(250),
112+
leeway_time: Duration::from_millis(0),
113+
..Default::default()
114+
},
115+
..Default::default()
116+
})]
117+
async fn flashblock_timings_2000ms_block_time_0ms_leeway_time(
118+
harness: Harness,
119+
) -> eyre::Result<()> {
107120
const TXS_PER_BLOCK: usize = 60;
108121

109-
let (node, ws_addr) =
110-
Flashblocks::test_node_with_custom_leeway_time_and_interval(
111-
Duration::from_millis(0),
112-
Duration::from_millis(250),
113-
)
114-
.await?;
115-
let ws = WebSocketObserver::new(ws_addr).await?;
122+
let node = harness.node();
123+
let ws = harness.ws_observer().await?;
116124

117125
// Create a block at the top of the timestamp second
118126
// Wait until the exact top of the next second
@@ -150,16 +158,17 @@ async fn flashblock_timings_2000ms_block_time_0ms_leeway_time()
150158
Ok(())
151159
}
152160

153-
#[tokio::test]
154161
// This test is to check that we get 8 flashblocks with 2000ms - 75ms = 1925ms
155162
// remaining time. 2000ms blocktimes, 250ms flashblock interval, and 75ms leeway
156163
// time
157-
async fn flashblock_timings_2000ms_block_time_75ms_leeway_time()
158-
-> eyre::Result<()> {
164+
#[unichain_test]
165+
async fn flashblock_timings_2000ms_block_time_75ms_leeway_time(
166+
harness: Harness,
167+
) -> eyre::Result<()> {
159168
const TXS_PER_BLOCK: usize = 60;
160169

161-
let (node, ws_addr) = Flashblocks::test_node().await?;
162-
let ws = WebSocketObserver::new(ws_addr).await?;
170+
let node = harness.node();
171+
let ws = harness.ws_observer().await?;
163172

164173
// Create a block at the top of the timestamp second
165174
// Wait until the exact top of the next second
@@ -197,21 +206,24 @@ async fn flashblock_timings_2000ms_block_time_75ms_leeway_time()
197206
Ok(())
198207
}
199208

200-
#[tokio::test]
201209
// This test is to check that we get 3 flashblocks with 2000ms - 500ms = 1500ms
202210
// remaining time. 2000ms blocktimes, 500ms flashblock interval, and 500ms
203211
// leeway time
204-
async fn flashblock_timings_2000ms_block_time_500ms_leeway_time()
205-
-> eyre::Result<()> {
212+
#[unichain_test(args = BuilderArgs {
213+
flashblocks_args: FlashblocksArgs {
214+
interval: Duration::from_millis(500),
215+
leeway_time: Duration::from_millis(500),
216+
..Default::default()
217+
},
218+
..Default::default()
219+
})]
220+
async fn flashblock_timings_2000ms_block_time_500ms_leeway_time(
221+
harness: Harness,
222+
) -> eyre::Result<()> {
206223
const TXS_PER_BLOCK: usize = 60;
207224

208-
let (node, ws_addr) =
209-
Flashblocks::test_node_with_custom_leeway_time_and_interval(
210-
Duration::from_millis(500),
211-
Duration::from_millis(500),
212-
)
213-
.await?;
214-
let ws = WebSocketObserver::new(ws_addr).await?;
225+
let node = harness.node();
226+
let ws = harness.ws_observer().await?;
215227

216228
// Create a block at the top of the timestamp second
217229
// Wait until the exact top of the next second
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
[package]
2+
name = "macros"
3+
version = "0.1.0"
4+
edition = "2024"
5+
description = "Macros supporting the tests infrastructure for unichain-builder"
6+
7+
[lib]
8+
proc-macro = true
9+
10+
[dependencies]
11+
syn = "2.0"
12+
quote = "1.0"
13+
proc-macro2 = "1.0"
14+
paste = "1.0"

0 commit comments

Comments
 (0)