Skip to content

Commit fd4bdcd

Browse files
committed
refactors test utils across tasks
1 parent 55b2193 commit fd4bdcd

File tree

6 files changed

+172
-207
lines changed

6 files changed

+172
-207
lines changed

src/lib.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ pub mod tasks;
2727
/// Utilities.
2828
pub mod utils;
2929

30+
/// Test utilitites
31+
pub mod test_utils;
32+
3033
// Anonymous import suppresses warnings about unused imports.
3134
use openssl as _;
32-
use tracing_subscriber as _;
35+
use tracing_subscriber as _;

src/tasks/oauth.rs

Lines changed: 6 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -122,54 +122,21 @@ impl Authenticator {
122122
}
123123

124124
mod tests {
125-
use crate::config::BuilderConfig;
126-
use alloy::primitives::Address;
127-
use eyre::Result;
128-
129125
#[ignore = "integration test"]
130126
#[tokio::test]
131-
async fn test_authenticator() -> Result<()> {
127+
async fn test_authenticator() -> eyre::Result<()> {
132128
use super::*;
129+
use crate::test_utils::setup_test_config;
133130
use oauth2::TokenResponse;
134131

135132
let config = setup_test_config()?;
136133
let auth = Authenticator::new(&config);
137-
let token = auth.fetch_oauth_token().await?;
138-
dbg!(&token);
134+
135+
let _ = auth.fetch_oauth_token().await?;
136+
139137
let token = auth.token().await.unwrap();
140-
println!("{:?}", token);
138+
141139
assert!(!token.access_token().secret().is_empty());
142140
Ok(())
143141
}
144-
145-
#[allow(dead_code)]
146-
fn setup_test_config() -> Result<BuilderConfig> {
147-
let config = BuilderConfig {
148-
host_chain_id: 17000,
149-
ru_chain_id: 17001,
150-
host_rpc_url: "host-rpc.example.com".into(),
151-
ru_rpc_url: "ru-rpc.example.com".into(),
152-
zenith_address: Address::default(),
153-
quincey_url: "http://localhost:8080".into(),
154-
builder_port: 8080,
155-
sequencer_key: None,
156-
builder_key: "0000000000000000000000000000000000000000000000000000000000000000".into(),
157-
block_confirmation_buffer: 1,
158-
chain_offset: 0,
159-
target_slot_time: 1,
160-
builder_rewards_address: Address::default(),
161-
rollup_block_gas_limit: 100_000,
162-
tx_pool_url: "http://localhost:9000/".into(),
163-
tx_pool_cache_duration: 5,
164-
oauth_client_id: "some_client_id".into(),
165-
oauth_client_secret: "some_client_secret".into(),
166-
oauth_authenticate_url: "http://localhost:9000".into(),
167-
oauth_token_url: "http://localhost:9000".into(),
168-
tx_broadcast_urls: vec!["http://localhost:9000".into()],
169-
oauth_token_refresh_interval: 300, // 5 minutes
170-
builder_helper_address: Address::default(),
171-
concurrency_limit: 1000,
172-
};
173-
Ok(config)
174-
}
175142
}

src/test_utils.rs

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
//! Test utilities for testing builder tasks
2+
use crate::{config::BuilderConfig, tasks::block::PECORINO_CHAIN_ID};
3+
use alloy::{
4+
consensus::{SignableTransaction, TxEip1559, TxEnvelope},
5+
primitives::{Address, TxKind, U256},
6+
signers::{SignerSync, local::PrivateKeySigner},
7+
};
8+
use eyre::Result;
9+
use std::str::FromStr;
10+
use tracing_subscriber::{EnvFilter, Layer, layer::SubscriberExt, util::SubscriberInitExt};
11+
12+
/// Sets up a block builder with test values
13+
pub fn setup_test_config() -> Result<BuilderConfig> {
14+
let config = BuilderConfig {
15+
host_chain_id: 17000,
16+
ru_chain_id: 17001,
17+
host_rpc_url: "host-rpc.example.com".into(),
18+
ru_rpc_url: "ru-rpc.example.com".into(),
19+
tx_broadcast_urls: vec!["http://localhost:9000".into()],
20+
zenith_address: Address::default(),
21+
quincey_url: "http://localhost:8080".into(),
22+
builder_port: 8080,
23+
sequencer_key: None,
24+
builder_key: "0000000000000000000000000000000000000000000000000000000000000000".into(),
25+
block_confirmation_buffer: 1,
26+
chain_offset: 0,
27+
target_slot_time: 1,
28+
builder_rewards_address: Address::default(),
29+
rollup_block_gas_limit: 100_000,
30+
tx_pool_url: "http://localhost:9000/".into(),
31+
tx_pool_cache_duration: 5,
32+
oauth_client_id: "some_client_id".into(),
33+
oauth_client_secret: "some_client_secret".into(),
34+
oauth_authenticate_url: "http://localhost:8080".into(),
35+
oauth_token_url: "http://localhost:8080".into(),
36+
oauth_token_refresh_interval: 300, // 5 minutes
37+
builder_helper_address: Address::default(),
38+
concurrency_limit: 1000,
39+
start_timestamp: 1740681556, // pecorino start timestamp as sane default
40+
};
41+
Ok(config)
42+
}
43+
44+
/// Returns a new signed test transaction with the provided nonce, value, and mpfpg.
45+
pub fn new_signed_tx(
46+
wallet: &PrivateKeySigner,
47+
nonce: u64,
48+
value: U256,
49+
mpfpg: u128,
50+
) -> Result<TxEnvelope> {
51+
let tx = TxEip1559 {
52+
chain_id: PECORINO_CHAIN_ID,
53+
nonce,
54+
max_fee_per_gas: 50_000,
55+
max_priority_fee_per_gas: mpfpg,
56+
to: TxKind::Call(Address::from_str("0x0000000000000000000000000000000000000000").unwrap()),
57+
value,
58+
gas_limit: 50_000,
59+
..Default::default()
60+
};
61+
let signature = wallet.sign_hash_sync(&tx.signature_hash())?;
62+
Ok(TxEnvelope::Eip1559(tx.into_signed(signature)))
63+
}
64+
65+
/// Initializes a logger that prints during testing
66+
pub fn setup_logging() {
67+
// Initialize logging
68+
let filter = EnvFilter::from_default_env();
69+
let fmt = tracing_subscriber::fmt::layer().with_filter(filter);
70+
let registry = tracing_subscriber::registry().with(fmt);
71+
let _ = registry.try_init();
72+
}

tests/block_builder_test.rs

Lines changed: 78 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,30 @@
11
#[cfg(test)]
22
mod tests {
33
use alloy::{
4-
consensus::{SignableTransaction, TxEip1559, TxEnvelope},
5-
node_bindings::Anvil,
6-
primitives::{Address, TxKind, U256},
7-
providers::ProviderBuilder,
8-
signers::{SignerSync, local::PrivateKeySigner},
4+
node_bindings::Anvil, primitives::U256, providers::ProviderBuilder,
5+
signers::local::PrivateKeySigner,
96
};
107
use builder::{
11-
config::BuilderConfig,
12-
tasks::{
13-
block::{BlockBuilder, PECORINO_CHAIN_ID},
14-
oauth::Authenticator,
15-
},
8+
tasks::block::{BlockBuilder, PECORINO_CHAIN_ID},
9+
test_utils::{new_signed_tx, setup_logging, setup_test_config},
1610
};
17-
use eyre::Result;
11+
1812
use signet_sim::{SimCache, SimItem};
19-
use std::str::FromStr;
20-
use tracing_subscriber::{EnvFilter, Layer, layer::SubscriberExt, util::SubscriberInitExt};
13+
use signet_types::SlotCalculator;
14+
use std::{
15+
sync::Arc,
16+
time::{Duration, Instant, SystemTime, UNIX_EPOCH},
17+
};
18+
use tokio::{sync::mpsc::unbounded_channel, time::timeout};
2119

22-
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
23-
async fn test_spawn() {
24-
let filter = EnvFilter::from_default_env();
25-
let fmt = tracing_subscriber::fmt::layer().with_filter(filter);
26-
let registry = tracing_subscriber::registry().with(fmt);
27-
registry.try_init().unwrap();
20+
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
21+
async fn test_handle_build() {
22+
setup_logging();
2823

2924
// Make a test config
30-
let config = setup_test_config();
25+
let config = setup_test_config().unwrap();
3126
let constants = config.load_pecorino_constants();
3227

33-
// Create an authenticator for bundle integration testing
34-
let authenticator = Authenticator::new(&config);
35-
3628
// Create an anvil instance for testing
3729
let anvil_instance = Anvil::new().chain_id(PECORINO_CHAIN_ID).spawn();
3830

@@ -44,8 +36,14 @@ mod tests {
4436
// Create a rollup provider
4537
let ru_provider = ProviderBuilder::new().on_http(anvil_instance.endpoint_url());
4638

47-
// Create a block builder
48-
let block_builder = BlockBuilder::new(&config, authenticator, ru_provider.clone());
39+
// Create a block builder with a slot calculator for testing
40+
let now = SystemTime::now()
41+
.duration_since(UNIX_EPOCH)
42+
.expect("Clock may have gone backwards")
43+
.as_secs();
44+
dbg!(now);
45+
let slot_calculator = SlotCalculator::new(now, 0, 12);
46+
let block_builder = BlockBuilder::new(&config, ru_provider.clone(), slot_calculator);
4947

5048
// Setup a sim cache
5149
let sim_items = SimCache::new();
@@ -57,64 +55,68 @@ mod tests {
5755
let tx_2 = new_signed_tx(&test_key_1, 0, U256::from(2_f64), 10_000).unwrap();
5856
sim_items.add_item(SimItem::Tx(tx_2));
5957

58+
let finish_by = Instant::now() + Duration::from_secs(2);
59+
6060
// Spawn the block builder task
61-
let got = block_builder.handle_build(constants, ru_provider, sim_items).await;
61+
let got = block_builder.handle_build(constants, sim_items, finish_by).await;
6262

6363
// Assert on the built block
6464
assert!(got.is_ok());
6565
assert!(got.unwrap().tx_count() == 2);
6666
}
6767

68-
fn setup_test_config() -> BuilderConfig {
69-
let config = BuilderConfig {
70-
host_chain_id: 1,
71-
ru_chain_id: PECORINO_CHAIN_ID,
72-
host_rpc_url: "https://host-rpc.example.com".into(),
73-
ru_rpc_url: "https://rpc.pecorino.signet.sh".into(),
74-
zenith_address: Address::default(),
75-
quincey_url: "http://localhost:8080".into(),
76-
builder_port: 8080,
77-
sequencer_key: None,
78-
builder_key: "0000000000000000000000000000000000000000000000000000000000000000".into(),
79-
block_confirmation_buffer: 1,
80-
chain_offset: 0,
81-
target_slot_time: 1,
82-
builder_rewards_address: Address::default(),
83-
rollup_block_gas_limit: 100_000_000,
84-
tx_pool_url: "http://localhost:9000/".into(),
85-
tx_pool_cache_duration: 5,
86-
oauth_client_id: "some_client_id".into(),
87-
oauth_client_secret: "some_client_secret".into(),
88-
oauth_authenticate_url: "http://localhost:9000".into(),
89-
oauth_token_url: "http://localhost:9000".into(),
90-
tx_broadcast_urls: vec!["http://localhost:9000".into()],
91-
oauth_token_refresh_interval: 300, // 5 minutes
92-
builder_helper_address: Address::default(),
93-
concurrency_limit: 1000,
94-
};
95-
config
96-
}
68+
/// Tests the full block builder loop
69+
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
70+
async fn test_spawn() {
71+
setup_logging();
72+
73+
// Make a test config
74+
let config = setup_test_config().unwrap();
75+
let constants = config.load_pecorino_constants();
76+
77+
// Create an anvil instance for testing
78+
let anvil_instance = Anvil::new().chain_id(PECORINO_CHAIN_ID).spawn();
79+
80+
// Create a wallet
81+
let keys = anvil_instance.keys();
82+
let test_key_0 = PrivateKeySigner::from_signing_key(keys[0].clone().into());
83+
let test_key_1 = PrivateKeySigner::from_signing_key(keys[1].clone().into());
84+
85+
// Plumb inputs for the test setup
86+
let (tx_sender, tx_receiver) = unbounded_channel();
87+
let (_, bundle_receiver) = unbounded_channel();
88+
let (block_sender, mut block_receiver) = unbounded_channel();
89+
90+
// Create a rollup provider
91+
let ru_provider = ProviderBuilder::new().on_http(anvil_instance.endpoint_url());
92+
93+
// Create a builder with a test slot calculator
94+
let slot_calculator = SlotCalculator::new(
95+
config.start_timestamp,
96+
config.chain_offset,
97+
config.target_slot_time,
98+
);
99+
let sim_cache = SimCache::new();
100+
let builder = Arc::new(BlockBuilder::new(&config, ru_provider.clone(), slot_calculator));
101+
102+
// Create a sim cache and start filling it with items
103+
let _ =
104+
builder.clone().spawn_cache_handler(tx_receiver, bundle_receiver, sim_cache.clone());
105+
106+
// Finally, Kick off the block builder task.
107+
let _ = builder.clone().spawn_builder_task(constants, sim_cache.clone(), block_sender);
108+
109+
let tx_1 = new_signed_tx(&test_key_0, 0, U256::from(1_f64), 11_000).unwrap();
110+
let tx_2 = new_signed_tx(&test_key_1, 0, U256::from(2_f64), 10_000).unwrap();
111+
tx_sender.send(tx_1).unwrap();
112+
tx_sender.send(tx_2).unwrap();
97113

98-
// Returns a new signed test transaction with default values
99-
fn new_signed_tx(
100-
wallet: &PrivateKeySigner,
101-
nonce: u64,
102-
value: U256,
103-
mpfpg: u128,
104-
) -> Result<TxEnvelope> {
105-
let tx = TxEip1559 {
106-
chain_id: PECORINO_CHAIN_ID,
107-
nonce,
108-
max_fee_per_gas: 50_000,
109-
max_priority_fee_per_gas: mpfpg,
110-
to: TxKind::Call(
111-
Address::from_str("0x0000000000000000000000000000000000000000").unwrap(),
112-
),
113-
value,
114-
gas_limit: 50_000,
115-
..Default::default()
116-
};
117-
let signature = wallet.sign_hash_sync(&tx.signature_hash())?;
118-
Ok(TxEnvelope::Eip1559(tx.into_signed(signature)))
114+
// Wait for a block with timeout
115+
let result = timeout(Duration::from_secs(5), block_receiver.recv()).await;
116+
assert!(result.is_ok(), "Did not receive block within 5 seconds");
117+
let block = result.unwrap();
118+
dbg!(&block);
119+
assert!(block.is_some(), "Block channel closed without receiving a block");
120+
assert!(block.unwrap().tx_count() == 2); // TODO: Why is this failing? I'm seeing EVM errors but haven't tracked them down yet.
119121
}
120122
}

tests/bundle_poller_test.rs

Lines changed: 4 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,17 @@
11
mod tests {
2-
use alloy::primitives::Address;
3-
use builder::{config::BuilderConfig, tasks::oauth::Authenticator};
2+
use builder::{tasks::oauth::Authenticator, test_utils};
43
use eyre::Result;
54

65
#[ignore = "integration test"]
76
#[tokio::test]
87
async fn test_bundle_poller_roundtrip() -> Result<()> {
9-
let config = setup_test_config().await.unwrap();
8+
let config = test_utils::setup_test_config().unwrap();
109
let auth = Authenticator::new(&config);
10+
1111
let mut bundle_poller = builder::tasks::bundler::BundlePoller::new(&config, auth);
1212

13-
let got = bundle_poller.check_bundle_cache().await?;
14-
dbg!(got);
13+
let _ = bundle_poller.check_bundle_cache().await?;
1514

1615
Ok(())
1716
}
18-
19-
async fn setup_test_config() -> Result<BuilderConfig> {
20-
let config = BuilderConfig {
21-
host_chain_id: 17000,
22-
ru_chain_id: 17001,
23-
host_rpc_url: "host-rpc.example.com".into(),
24-
ru_rpc_url: "ru-rpc.example.com".into(),
25-
zenith_address: Address::default(),
26-
quincey_url: "http://localhost:8080".into(),
27-
builder_port: 8080,
28-
sequencer_key: None,
29-
builder_key: "0000000000000000000000000000000000000000000000000000000000000000".into(),
30-
block_confirmation_buffer: 1,
31-
chain_offset: 0,
32-
target_slot_time: 1,
33-
builder_rewards_address: Address::default(),
34-
rollup_block_gas_limit: 100_000,
35-
tx_pool_url: "http://localhost:9000/".into(),
36-
// tx_pool_url: "https://transactions.holesky.signet.sh".into(),
37-
tx_pool_cache_duration: 5,
38-
oauth_client_id: "some_client_id".into(),
39-
oauth_client_secret: "some_client_secret".into(),
40-
oauth_authenticate_url: "http://localhost:8080".into(),
41-
oauth_token_url: "http://localhost:8080".into(),
42-
tx_broadcast_urls: vec!["http://localhost:9000".into()],
43-
oauth_token_refresh_interval: 300, // 5 minutes
44-
builder_helper_address: Address::default(),
45-
concurrency_limit: 1000,
46-
};
47-
Ok(config)
48-
}
4917
}

0 commit comments

Comments
 (0)