Skip to content

Commit 2fd44a7

Browse files
committed
refactor: integrate env and cache tasks
1 parent 730dabd commit 2fd44a7

16 files changed

+419
-595
lines changed

Cargo.toml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ integration = []
2727
[dependencies]
2828
init4-bin-base = { version = "0.3.4", features = ["perms"] }
2929

30-
signet-bundle = { git = "https://github.com/init4tech/signet-sdk", branch = "main" }
3130
signet-constants = { git = "https://github.com/init4tech/signet-sdk", branch = "main" }
3231
signet-sim = { git = "https://github.com/init4tech/signet-sdk", branch = "main" }
3332
signet-tx-cache = { git = "https://github.com/init4tech/signet-sdk", branch = "main" }
@@ -56,6 +55,5 @@ serde_json = "1.0"
5655
tokio = { version = "1.36.0", features = ["full", "macros", "rt-multi-thread"] }
5756

5857
oauth2 = "5"
59-
chrono = "0.4.41"
6058
tokio-stream = "0.1.17"
6159
url = "2.5.4"

bin/builder.rs

Lines changed: 37 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,14 @@
11
use builder::{
22
config::BuilderConfig,
33
service::serve_builder,
4-
tasks::{
5-
block::sim::Simulator,
6-
cache::{BundlePoller, TxPoller},
7-
metrics::MetricsTask,
8-
submit::SubmitTask,
9-
},
4+
tasks::{block::sim::Simulator, metrics::MetricsTask, submit::SubmitTask},
5+
};
6+
use init4_bin_base::{
7+
deps::tracing::{info, info_span},
8+
utils::from_env::FromEnv,
109
};
11-
use init4_bin_base::{deps::tracing, utils::from_env::FromEnv};
12-
use signet_sim::SimCache;
1310
use signet_types::constants::SignetSystemConstants;
1411
use tokio::select;
15-
use tracing::info_span;
1612

1713
// Note: Must be set to `multi_thread` to support async tasks.
1814
// See: https://docs.rs/tokio/latest/tokio/attr.main.html
@@ -21,74 +17,74 @@ async fn main() -> eyre::Result<()> {
2117
let _guard = init4_bin_base::init4();
2218
let init_span_guard = info_span!("builder initialization");
2319

20+
// Pull the configuration from the environment
2421
let config = BuilderConfig::from_env()?.clone();
2522
let constants = SignetSystemConstants::pecorino();
26-
let token = config.oauth_token();
2723

24+
// Spawn the EnvTask
25+
let env_task = config.env_task();
26+
let (block_env, env_jh) = env_task.spawn();
27+
28+
// Spawn the cache system
29+
let cache_system = config.spawn_cache_system(block_env.clone());
30+
31+
// Prep providers and contracts
2832
let (host_provider, quincey) =
2933
tokio::try_join!(config.connect_host_provider(), config.connect_quincey())?;
3034
let ru_provider = config.connect_ru_provider();
31-
3235
let zenith = config.connect_zenith(host_provider.clone());
3336

37+
// Set up the metrics task
3438
let metrics = MetricsTask { host_provider };
3539
let (tx_channel, metrics_jh) = metrics.spawn();
3640

41+
// Make a Tx submission task
3742
let submit =
3843
SubmitTask { zenith, quincey, config: config.clone(), outbound_tx_channel: tx_channel };
3944

40-
let tx_poller = TxPoller::new(&config);
41-
let (tx_receiver, tx_poller_jh) = tx_poller.spawn();
42-
43-
let bundle_poller = BundlePoller::new(&config, token);
44-
let (bundle_receiver, bundle_poller_jh) = bundle_poller.spawn();
45-
45+
// Set up tx submission
4646
let (submit_channel, submit_jh) = submit.spawn();
4747

48-
let sim_items = SimCache::new();
49-
let slot_calculator = config.slot_calculator;
50-
51-
let sim = Simulator::new(&config, ru_provider.clone(), slot_calculator);
52-
53-
let (basefee_jh, sim_cache_jh) =
54-
sim.spawn_cache_tasks(tx_receiver, bundle_receiver, sim_items.clone());
55-
56-
let build_jh = sim.spawn_simulator_task(constants, sim_items.clone(), submit_channel);
48+
// Set up the simulator
49+
let sim = Simulator::new(&config, ru_provider.clone(), block_env);
50+
let build_jh = sim.spawn_simulator_task(constants, cache_system.sim_cache, submit_channel);
5751

52+
// Start the healthcheck server
5853
let server = serve_builder(([0, 0, 0, 0], config.builder_port));
5954

6055
// We have finished initializing the builder, so we can drop the init span
6156
// guard.
6257
drop(init_span_guard);
6358

6459
select! {
65-
_ = tx_poller_jh => {
66-
tracing::info!("tx_poller finished");
60+
61+
_ = env_jh => {
62+
info!("env task finished");
6763
},
68-
_ = bundle_poller_jh => {
69-
tracing::info!("bundle_poller finished");
64+
_ = cache_system.cache_task => {
65+
info!("cache task finished");
66+
},
67+
_ = cache_system.tx_poller => {
68+
info!("tx_poller finished");
69+
},
70+
_ = cache_system.bundle_poller => {
71+
info!("bundle_poller finished");
7072
},
71-
_ = sim_cache_jh => {
72-
tracing::info!("sim cache task finished");
73-
}
74-
_ = basefee_jh => {
75-
tracing::info!("basefee task finished");
76-
}
7773
_ = submit_jh => {
78-
tracing::info!("submit finished");
74+
info!("submit finished");
7975
},
8076
_ = metrics_jh => {
81-
tracing::info!("metrics finished");
77+
info!("metrics finished");
8278
},
8379
_ = build_jh => {
84-
tracing::info!("build finished");
80+
info!("build finished");
8581
}
8682
_ = server => {
87-
tracing::info!("server finished");
83+
info!("server finished");
8884
}
8985
}
9086

91-
tracing::info!("shutting down");
87+
info!("shutting down");
9288

9389
Ok(())
9490
}

src/config.rs

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
1-
use crate::quincey::Quincey;
1+
use crate::{
2+
quincey::Quincey,
3+
tasks::{
4+
block::cfg::SignetCfgEnv,
5+
cache::{BundlePoller, CacheSystem, CacheTask, TxPoller},
6+
env::EnvTask,
7+
},
8+
};
29
use alloy::{
310
network::{Ethereum, EthereumWallet},
411
primitives::Address,
@@ -21,6 +28,8 @@ use init4_bin_base::{
2128
};
2229
use signet_zenith::Zenith;
2330
use std::borrow::Cow;
31+
use tokio::sync::watch;
32+
use trevm::revm::context::BlockEnv;
2433

2534
/// Type alias for the provider used to simulate against rollup state.
2635
pub type RuProvider = RootProvider<Ethereum>;
@@ -166,8 +175,13 @@ impl BuilderConfig {
166175

167176
/// Connect to the Rollup rpc provider.
168177
pub fn connect_ru_provider(&self) -> RootProvider<Ethereum> {
169-
let url = url::Url::parse(&self.ru_rpc_url).expect("failed to parse URL");
170-
RootProvider::<Ethereum>::new_http(url)
178+
static ONCE: std::sync::OnceLock<RootProvider<Ethereum>> = std::sync::OnceLock::new();
179+
180+
ONCE.get_or_init(|| {
181+
let url = url::Url::parse(&self.ru_rpc_url).expect("failed to parse URL");
182+
RootProvider::new_http(url)
183+
})
184+
.clone()
171185
}
172186

173187
/// Connect to the Host rpc provider.
@@ -222,4 +236,36 @@ impl BuilderConfig {
222236

223237
Ok(Quincey::new_remote(client, url, token))
224238
}
239+
240+
/// Create an [`EnvTask`] using this config.
241+
pub fn env_task(&self) -> EnvTask {
242+
let provider = self.connect_ru_provider();
243+
EnvTask::new(self.clone(), provider)
244+
}
245+
246+
/// Spawn a new [`CacheSystem`] using this config. This contains the
247+
/// joinhandles for [`TxPoller`] and [`BundlePoller`] and [`CacheTask`], as
248+
/// well as the [`SimCache`] and the block env watcher.
249+
///
250+
/// [`SimCache`]: signet_sim::SimCache
251+
pub fn spawn_cache_system(&self, block_env: watch::Receiver<Option<BlockEnv>>) -> CacheSystem {
252+
// Tx Poller pulls transactions from the cache
253+
let tx_poller = TxPoller::new(self);
254+
let (tx_receiver, tx_poller) = tx_poller.spawn();
255+
256+
// Bundle Poller pulls bundles from the cache
257+
let bundle_poller = BundlePoller::new(self, self.oauth_token());
258+
let (bundle_receiver, bundle_poller) = bundle_poller.spawn();
259+
260+
// Set up the cache task
261+
let cache_task = CacheTask::new(block_env.clone(), bundle_receiver, tx_receiver);
262+
let (sim_cache, cache_task) = cache_task.spawn();
263+
264+
CacheSystem { cache_task, tx_poller, bundle_poller, sim_cache }
265+
}
266+
267+
/// Create a [`SignetCfgEnv`] using this config.
268+
pub const fn cfg_env(&self) -> SignetCfgEnv {
269+
SignetCfgEnv { chain_id: self.ru_chain_id }
270+
}
225271
}

src/tasks/block/cfg.rs

Lines changed: 7 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,14 @@
11
//! This file implements the [`trevm::Cfg`] and [`trevm::Block`] traits for Pecorino blocks.
2-
use alloy::primitives::{Address, B256, FixedBytes, U256};
3-
use trevm::{
4-
Block,
5-
revm::{
6-
context::{BlockEnv, CfgEnv},
7-
context_interface::block::BlobExcessGasAndPrice,
8-
primitives::hardfork::SpecId,
9-
},
10-
};
11-
12-
use crate::config::BuilderConfig;
2+
use trevm::revm::{context::CfgEnv, primitives::hardfork::SpecId};
133

144
/// PecorinoCfg holds network-level configuration values.
155
#[derive(Debug, Clone, Copy)]
16-
pub struct PecorinoCfg {}
6+
pub struct SignetCfgEnv {
7+
/// The chain ID.
8+
pub chain_id: u64,
9+
}
1710

18-
impl trevm::Cfg for PecorinoCfg {
11+
impl trevm::Cfg for SignetCfgEnv {
1912
/// Fills the configuration environment with Pecorino-specific values.
2013
///
2114
/// # Arguments
@@ -24,76 +17,7 @@ impl trevm::Cfg for PecorinoCfg {
2417
fn fill_cfg_env(&self, cfg_env: &mut CfgEnv) {
2518
let CfgEnv { chain_id, spec, .. } = cfg_env;
2619

27-
*chain_id = signet_constants::pecorino::RU_CHAIN_ID;
20+
*chain_id = self.chain_id;
2821
*spec = SpecId::default();
2922
}
3023
}
31-
32-
/// PecorinoBlockEnv holds block-level configurations for Pecorino blocks.
33-
#[derive(Debug, Clone, Copy)]
34-
pub struct PecorinoBlockEnv {
35-
/// The block number for this block.
36-
pub number: u64,
37-
/// The address the block reward should be sent to.
38-
pub beneficiary: Address,
39-
/// Timestamp for the block.
40-
pub timestamp: u64,
41-
/// The gas limit for this block environment.
42-
pub gas_limit: u64,
43-
/// The basefee to use for calculating gas usage.
44-
pub basefee: u64,
45-
/// The prevrandao to use for this block.
46-
pub prevrandao: Option<FixedBytes<32>>,
47-
}
48-
49-
/// Implements [`trevm::Block`] for the Pecorino block.
50-
impl Block for PecorinoBlockEnv {
51-
/// Fills the block environment with the Pecorino specific values
52-
fn fill_block_env(&self, block_env: &mut BlockEnv) {
53-
// Destructure the fields off of the block_env and modify them
54-
let BlockEnv {
55-
number,
56-
beneficiary,
57-
timestamp,
58-
gas_limit,
59-
basefee,
60-
difficulty,
61-
prevrandao,
62-
blob_excess_gas_and_price,
63-
} = block_env;
64-
*number = self.number;
65-
*beneficiary = self.beneficiary;
66-
*timestamp = self.timestamp;
67-
*gas_limit = self.gas_limit;
68-
*basefee = self.basefee;
69-
*prevrandao = self.prevrandao;
70-
71-
// NB: The following fields are set to sane defaults because they
72-
// are not supported by the rollup
73-
*difficulty = U256::ZERO;
74-
*blob_excess_gas_and_price =
75-
Some(BlobExcessGasAndPrice { excess_blob_gas: 0, blob_gasprice: 0 });
76-
}
77-
}
78-
79-
impl PecorinoBlockEnv {
80-
/// Returns a new PecorinoBlockEnv with the specified values.
81-
///
82-
/// # Arguments
83-
///
84-
/// - config: The BuilderConfig for the builder.
85-
/// - number: The block number of this block, usually the latest block number plus 1,
86-
/// unless simulating blocks in the past.
87-
/// - timestamp: The timestamp of the block, typically set to the deadline of the
88-
/// block building task.
89-
pub fn new(config: BuilderConfig, number: u64, timestamp: u64, basefee: u64) -> Self {
90-
PecorinoBlockEnv {
91-
number,
92-
beneficiary: config.builder_rewards_address,
93-
timestamp,
94-
gas_limit: config.rollup_block_gas_limit,
95-
basefee,
96-
prevrandao: Some(B256::random()),
97-
}
98-
}
99-
}

0 commit comments

Comments
 (0)