Skip to content

Commit 46e5bfa

Browse files
committed
fix: env behavior and test env
1 parent 433e039 commit 46e5bfa

File tree

6 files changed

+197
-180
lines changed

6 files changed

+197
-180
lines changed

src/tasks/block/sim.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ impl Simulator {
138138
/// - `cache`: The simulation cache containing transactions and bundles.
139139
/// - `submit_sender`: A channel sender used to submit built blocks.
140140
async fn run_simulator(
141-
self,
141+
mut self,
142142
constants: SignetSystemConstants,
143143
cache: SimCache,
144144
submit_sender: mpsc::UnboundedSender<BuiltBlock>,
@@ -147,8 +147,14 @@ impl Simulator {
147147
let sim_cache = cache.clone();
148148
let finish_by = self.calculate_deadline();
149149

150+
// Wait for the block environment to be set
151+
if self.block_env.changed().await.is_err() {
152+
error!("block_env channel closed");
153+
return;
154+
}
155+
150156
// If no env, skip this run
151-
let Some(block_env) = self.block_env.borrow().clone() else { return };
157+
let Some(block_env) = self.block_env.borrow_and_update().clone() else { return };
152158

153159
debug!(block_env = ?block_env, "building on block");
154160

src/tasks/env.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,11 +96,13 @@ impl EnvTask {
9696
}
9797
};
9898
span.record("number", previous.number);
99+
debug!("retrieved latest block");
99100

100101
let env = self.construct_block_env(&previous);
101102
debug!(?env, "constructed block env");
102103
if sender.send(Some(env)).is_err() {
103104
// The receiver has been dropped, so we can stop the task.
105+
debug!("receiver dropped, stopping task");
104106
break;
105107
}
106108
}

tests/block_builder_test.rs

Lines changed: 127 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -1,132 +1,130 @@
11
//! Tests for the block building task.
2-
#[cfg(test)]
3-
mod tests {
4-
use alloy::{
5-
network::Ethereum,
6-
node_bindings::Anvil,
7-
primitives::U256,
8-
providers::{Provider, RootProvider},
9-
signers::local::PrivateKeySigner,
10-
};
11-
use builder::{
12-
tasks::{block::sim::Simulator, cache::CacheTask},
13-
test_utils::{new_signed_tx, setup_logging, setup_test_config, test_block_env},
14-
};
15-
use signet_sim::{SimCache, SimItem};
16-
use signet_types::constants::SignetSystemConstants;
17-
use std::time::{Duration, Instant};
18-
use tokio::{sync::mpsc::unbounded_channel, time::timeout};
19-
20-
/// Tests the `handle_build` method of the `Simulator`.
21-
///
22-
/// This test sets up a simulated environment using Anvil, creates a block builder,
23-
/// and verifies that the block builder can successfully build a block containing
24-
/// transactions from multiple senders.
25-
#[cfg(feature = "integration")]
26-
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
27-
async fn test_handle_build() {
28-
use alloy::eips::BlockId;
29-
30-
setup_logging();
31-
32-
// Make a test config
33-
let config = setup_test_config().unwrap();
34-
let constants = SignetSystemConstants::pecorino();
35-
36-
// Create an anvil instance for testing
37-
let anvil_instance = Anvil::new().chain_id(signet_constants::pecorino::RU_CHAIN_ID).spawn();
38-
39-
// Create a wallet
40-
let keys = anvil_instance.keys();
41-
let test_key_0 = PrivateKeySigner::from_signing_key(keys[0].clone().into());
42-
let test_key_1 = PrivateKeySigner::from_signing_key(keys[1].clone().into());
43-
44-
// Create a rollup provider
45-
let ru_provider = RootProvider::<Ethereum>::new_http(anvil_instance.endpoint_url());
46-
47-
let block_env = config.env_task().spawn().0;
48-
49-
let block_builder = Simulator::new(&config, ru_provider.clone(), block_env);
50-
51-
// Setup a sim cache
52-
let sim_items = SimCache::new();
53-
54-
// Add two transactions from two senders to the sim cache
55-
let tx_1 = new_signed_tx(&test_key_0, 0, U256::from(1_f64), 11_000).unwrap();
56-
sim_items.add_item(SimItem::Tx(tx_1), 0);
57-
58-
let tx_2 = new_signed_tx(&test_key_1, 0, U256::from(2_f64), 10_000).unwrap();
59-
sim_items.add_item(SimItem::Tx(tx_2), 0);
60-
61-
// Setup the block env
62-
let finish_by = Instant::now() + Duration::from_secs(2);
63-
let header = ru_provider.get_block(BlockId::latest()).await.unwrap().unwrap().header.inner;
64-
let number = header.number + 1;
65-
let timestamp = header.timestamp + config.slot_calculator.slot_duration();
66-
let block_env = test_block_env(config, number, 7, timestamp);
67-
68-
// Spawn the block builder task
69-
let got = block_builder.handle_build(constants, sim_items, finish_by, block_env).await;
70-
71-
// Assert on the built block
72-
assert!(got.is_ok());
73-
assert!(got.unwrap().tx_count() == 2);
74-
}
75-
76-
/// Tests the full block builder loop, including transaction ingestion and block simulation.
77-
///
78-
/// This test sets up a simulated environment using Anvil, creates a block builder,
79-
/// and verifies that the builder can process incoming transactions and produce a block
80-
/// within a specified timeout.
81-
#[ignore = "integration test"]
82-
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
83-
async fn test_spawn() {
84-
setup_logging();
85-
86-
// Make a test config
87-
let config = setup_test_config().unwrap();
88-
let constants = SignetSystemConstants::pecorino();
89-
90-
// Create an anvil instance for testing
91-
let anvil_instance = Anvil::new().chain_id(signet_constants::pecorino::RU_CHAIN_ID).spawn();
92-
93-
// Create a wallet
94-
let keys = anvil_instance.keys();
95-
let test_key_0 = PrivateKeySigner::from_signing_key(keys[0].clone().into());
96-
let test_key_1 = PrivateKeySigner::from_signing_key(keys[1].clone().into());
97-
98-
// Plumb inputs for the test setup
99-
let (tx_sender, tx_receiver) = unbounded_channel();
100-
let (_, bundle_receiver) = unbounded_channel();
101-
let (block_sender, mut block_receiver) = unbounded_channel();
102-
103-
let env_task = config.env_task();
104-
let (block_env, _env_jh) = env_task.spawn();
105-
106-
let cache_task = CacheTask::new(block_env.clone(), bundle_receiver, tx_receiver);
107-
let (sim_cache, _cache_jh) = cache_task.spawn();
108-
109-
// Create a rollup provider
110-
let ru_provider = RootProvider::<Ethereum>::new_http(anvil_instance.endpoint_url());
111-
112-
let sim = Simulator::new(&config, ru_provider.clone(), block_env);
113-
114-
// Finally, Kick off the block builder task.
115-
sim.spawn_simulator_task(constants, sim_cache.clone(), block_sender);
116-
117-
// Feed in transactions to the tx_sender and wait for the block to be simulated
118-
let tx_1 = new_signed_tx(&test_key_0, 0, U256::from(1_f64), 11_000).unwrap();
119-
let tx_2 = new_signed_tx(&test_key_1, 0, U256::from(2_f64), 10_000).unwrap();
120-
tx_sender.send(tx_1).unwrap();
121-
tx_sender.send(tx_2).unwrap();
122-
123-
// Wait for a block with timeout
124-
let result = timeout(Duration::from_secs(5), block_receiver.recv()).await;
125-
assert!(result.is_ok(), "Did not receive block within 5 seconds");
1262
127-
// Assert on the block
128-
let block = result.unwrap();
129-
assert!(block.is_some(), "Block channel closed without receiving a block");
130-
assert!(block.unwrap().tx_count() == 2); // TODO: Why is this failing? I'm seeing EVM errors but haven't tracked them down yet.
131-
}
3+
use alloy::{
4+
network::Ethereum,
5+
node_bindings::Anvil,
6+
primitives::U256,
7+
providers::{Provider, RootProvider},
8+
signers::local::PrivateKeySigner,
9+
};
10+
use builder::{
11+
tasks::{block::sim::Simulator, cache::CacheTask},
12+
test_utils::{new_signed_tx, setup_logging, setup_test_config, test_block_env},
13+
};
14+
use signet_sim::{SimCache, SimItem};
15+
use signet_types::constants::SignetSystemConstants;
16+
use std::time::{Duration, Instant};
17+
use tokio::{sync::mpsc::unbounded_channel, time::timeout};
18+
19+
/// Tests the `handle_build` method of the `Simulator`.
20+
///
21+
/// This test sets up a simulated environment using Anvil, creates a block builder,
22+
/// and verifies that the block builder can successfully build a block containing
23+
/// transactions from multiple senders.
24+
#[cfg(feature = "integration")]
25+
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
26+
async fn test_handle_build() {
27+
use alloy::eips::BlockId;
28+
29+
setup_logging();
30+
31+
// Make a test config
32+
let config = setup_test_config().unwrap();
33+
let constants = SignetSystemConstants::pecorino();
34+
35+
// Create an anvil instance for testing
36+
let anvil_instance = Anvil::new().chain_id(signet_constants::pecorino::RU_CHAIN_ID).spawn();
37+
38+
// Create a wallet
39+
let keys = anvil_instance.keys();
40+
let test_key_0 = PrivateKeySigner::from_signing_key(keys[0].clone().into());
41+
let test_key_1 = PrivateKeySigner::from_signing_key(keys[1].clone().into());
42+
43+
// Create a rollup provider
44+
let ru_provider = RootProvider::<Ethereum>::new_http(anvil_instance.endpoint_url());
45+
46+
let block_env = config.env_task().spawn().0;
47+
48+
let block_builder = Simulator::new(&config, ru_provider.clone(), block_env);
49+
50+
// Setup a sim cache
51+
let sim_items = SimCache::new();
52+
53+
// Add two transactions from two senders to the sim cache
54+
let tx_1 = new_signed_tx(&test_key_0, 0, U256::from(1_f64), 11_000).unwrap();
55+
sim_items.add_item(SimItem::Tx(tx_1), 0);
56+
57+
let tx_2 = new_signed_tx(&test_key_1, 0, U256::from(2_f64), 10_000).unwrap();
58+
sim_items.add_item(SimItem::Tx(tx_2), 0);
59+
60+
// Setup the block env
61+
let finish_by = Instant::now() + Duration::from_secs(2);
62+
let header = ru_provider.get_block(BlockId::latest()).await.unwrap().unwrap().header.inner;
63+
let number = header.number + 1;
64+
let timestamp = header.timestamp + config.slot_calculator.slot_duration();
65+
let block_env = test_block_env(config, number, 7, timestamp);
66+
67+
// Spawn the block builder task
68+
let got = block_builder.handle_build(constants, sim_items, finish_by, block_env).await;
69+
70+
// Assert on the built block
71+
assert!(got.is_ok());
72+
assert!(got.unwrap().tx_count() == 2);
73+
}
74+
75+
/// Tests the full block builder loop, including transaction ingestion and block simulation.
76+
///
77+
/// This test sets up a simulated environment using Anvil, creates a block builder,
78+
/// and verifies that the builder can process incoming transactions and produce a block
79+
/// within a specified timeout.
80+
#[ignore = "integration test"]
81+
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
82+
async fn test_spawn() {
83+
setup_logging();
84+
85+
// Make a test config
86+
let config = setup_test_config().unwrap();
87+
let constants = SignetSystemConstants::pecorino();
88+
89+
// Create an anvil instance for testing
90+
let anvil_instance = Anvil::new().chain_id(signet_constants::pecorino::RU_CHAIN_ID).spawn();
91+
92+
// Create a wallet
93+
let keys = anvil_instance.keys();
94+
let test_key_0 = PrivateKeySigner::from_signing_key(keys[0].clone().into());
95+
let test_key_1 = PrivateKeySigner::from_signing_key(keys[1].clone().into());
96+
97+
// Plumb inputs for the test setup
98+
let (tx_sender, tx_receiver) = unbounded_channel();
99+
let (_, bundle_receiver) = unbounded_channel();
100+
let (block_sender, mut block_receiver) = unbounded_channel();
101+
102+
let env_task = config.env_task();
103+
let (block_env, _env_jh) = env_task.spawn();
104+
105+
let cache_task = CacheTask::new(block_env.clone(), bundle_receiver, tx_receiver);
106+
let (sim_cache, _cache_jh) = cache_task.spawn();
107+
108+
// Create a rollup provider
109+
let ru_provider = RootProvider::<Ethereum>::new_http(anvil_instance.endpoint_url());
110+
111+
let sim = Simulator::new(&config, ru_provider.clone(), block_env);
112+
113+
// Finally, Kick off the block builder task.
114+
sim.spawn_simulator_task(constants, sim_cache.clone(), block_sender);
115+
116+
// Feed in transactions to the tx_sender and wait for the block to be simulated
117+
let tx_1 = new_signed_tx(&test_key_0, 0, U256::from(1_f64), 11_000).unwrap();
118+
let tx_2 = new_signed_tx(&test_key_1, 0, U256::from(2_f64), 10_000).unwrap();
119+
tx_sender.send(tx_1).unwrap();
120+
tx_sender.send(tx_2).unwrap();
121+
122+
// Wait for a block with timeout
123+
let result = timeout(Duration::from_secs(5), block_receiver.recv()).await;
124+
assert!(result.is_ok(), "Did not receive block within 5 seconds");
125+
126+
// Assert on the block
127+
let block = result.unwrap();
128+
assert!(block.is_some(), "Block channel closed without receiving a block");
129+
assert!(block.unwrap().tx_count() == 2); // TODO: Why is this failing? I'm seeing EVM errors but haven't tracked them down yet.
132130
}

tests/bundle_poller_test.rs

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,15 @@
1-
mod tests {
2-
use builder::{tasks::oauth::Authenticator, test_utils};
3-
use eyre::Result;
1+
use builder::{tasks::oauth::Authenticator, test_utils};
2+
use eyre::Result;
43

5-
#[ignore = "integration test"]
6-
#[tokio::test]
7-
async fn test_bundle_poller_roundtrip() -> Result<()> {
8-
let config = test_utils::setup_test_config().unwrap();
9-
let auth = Authenticator::new(&config)?;
4+
#[ignore = "integration test"]
5+
#[tokio::test]
6+
async fn test_bundle_poller_roundtrip() -> Result<()> {
7+
let config = test_utils::setup_test_config().unwrap();
8+
let auth = Authenticator::new(&config)?;
109

11-
let mut bundle_poller = builder::tasks::cache::BundlePoller::new(&config, auth.token());
10+
let mut bundle_poller = builder::tasks::cache::BundlePoller::new(&config, auth.token());
1211

13-
let _ = bundle_poller.check_bundle_cache().await?;
12+
let _ = bundle_poller.check_bundle_cache().await?;
1413

15-
Ok(())
16-
}
14+
Ok(())
1715
}

tests/env.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
use builder::test_utils::{setup_logging, setup_test_config};
2+
3+
#[ignore = "integration test. This test will take between 0 and 12 seconds to run."]
4+
#[tokio::test]
5+
async fn test_bundle_poller_roundtrip() {
6+
setup_logging();
7+
8+
let config = setup_test_config().unwrap();
9+
let env_task = config.env_task();
10+
let (mut env_watcher, _jh) = env_task.spawn();
11+
12+
env_watcher.changed().await.unwrap();
13+
let env = env_watcher.borrow_and_update();
14+
assert!(env.as_ref().is_some(), "Env should be Some");
15+
}

0 commit comments

Comments
 (0)