diff --git a/bin/builder.rs b/bin/builder.rs index e6049d5..f64d791 100644 --- a/bin/builder.rs +++ b/bin/builder.rs @@ -43,8 +43,7 @@ async fn main() -> eyre::Result<()> { // Set up the simulator let sim = Simulator::new(&config, host_provider, ru_provider, block_env); - let build_jh = - sim.spawn_simulator_task(config.constants.clone(), cache_system.sim_cache, submit_channel); + let build_jh = sim.spawn_simulator_task(cache_system.sim_cache, submit_channel); // Start the healthcheck server let server = serve_builder(([0, 0, 0, 0], config.builder_port)); diff --git a/src/config.rs b/src/config.rs index ef77656..7a72788 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,9 +1,6 @@ use crate::{ quincey::Quincey, - tasks::{ - block::{cfg::SignetCfgEnv, sim::SimResult}, - submit::FlashbotsTask, - }, + tasks::{block::sim::SimResult, submit::FlashbotsTask}, }; use alloy::{ network::{Ethereum, EthereumWallet}, @@ -73,14 +70,6 @@ pub const DEFAULT_CONCURRENCY_LIMIT: usize = 8; /// chain. #[derive(Debug, Clone, FromEnv)] pub struct BuilderConfig { - /// The chain ID of the host chain. - #[from_env(var = "HOST_CHAIN_ID", desc = "The chain ID of the host chain")] - pub host_chain_id: u64, - - /// The chain ID of the rollup chain. - #[from_env(var = "RU_CHAIN_ID", desc = "The chain ID of the rollup chain")] - pub ru_chain_id: u64, - /// URL for Host RPC node. #[from_env( var = "HOST_RPC_URL", @@ -121,17 +110,6 @@ pub struct BuilderConfig { )] pub flashbots_endpoint: Option, - /// Address of the Zenith contract on Host. - #[from_env(var = "ZENITH_ADDRESS", desc = "address of the Zenith contract on Host")] - pub zenith_address: Address, - - /// Address of the Builder Helper contract on Host. - #[from_env( - var = "BUILDER_HELPER_ADDRESS", - desc = "address of the Builder Helper contract on Host" - )] - pub builder_helper_address: Address, - /// URL for remote Quincey Sequencer server to sign blocks. /// NB: Disregarded if a sequencer_signer is configured. #[from_env( @@ -207,7 +185,7 @@ impl BuilderConfig { static ONCE: tokio::sync::OnceCell = tokio::sync::OnceCell::const_new(); ONCE.get_or_try_init(|| async { - LocalOrAws::load(&self.builder_key, Some(self.host_chain_id)).await + LocalOrAws::load(&self.builder_key, Some(self.constants.host_chain_id())).await }) .await .cloned() @@ -217,7 +195,7 @@ impl BuilderConfig { /// Connect to the Sequencer signer. pub async fn connect_sequencer_signer(&self) -> eyre::Result> { if let Some(sequencer_key) = &self.sequencer_key { - LocalOrAws::load(sequencer_key, Some(self.host_chain_id)) + LocalOrAws::load(sequencer_key, Some(self.constants.host_chain_id())) .await .map_err(Into::into) .map(Some) @@ -279,7 +257,7 @@ impl BuilderConfig { /// Connect to the Zenith instance, using the specified provider. pub const fn connect_zenith(&self, provider: HostProvider) -> ZenithInstance { - Zenith::new(self.zenith_address, provider) + Zenith::new(self.constants.host_zenith(), provider) } /// Get an oauth2 token for the builder, starting the authenticator if it @@ -309,16 +287,6 @@ impl BuilderConfig { Ok(Quincey::new_remote(client, url, token)) } - /// Create a rollup [`SignetCfgEnv`] using this config. - pub const fn ru_cfg_env(&self) -> SignetCfgEnv { - SignetCfgEnv { chain_id: self.ru_chain_id } - } - - /// Create a host [`SignetCfgEnv`] using this config. - pub const fn host_cfg_env(&self) -> SignetCfgEnv { - SignetCfgEnv { chain_id: self.host_chain_id } - } - /// Memoizes the concurrency limit for the current system. Uses [`std::thread::available_parallelism`] if no /// value is set. If that for some reason fails, it returns the default concurrency limit. pub fn concurrency_limit(&self) -> usize { diff --git a/src/tasks/block/sim.rs b/src/tasks/block/sim.rs index 2d761b0..6547262 100644 --- a/src/tasks/block/sim.rs +++ b/src/tasks/block/sim.rs @@ -5,12 +5,12 @@ use crate::{ config::{BuilderConfig, HostProvider, RuProvider}, tasks::env::SimEnv, }; -use alloy::{consensus::Header, eips::BlockId, network::Ethereum, providers::Provider}; +use alloy::consensus::Header; use init4_bin_base::{ deps::metrics::{counter, histogram}, utils::calc::SlotCalculator, }; -use signet_sim::{BlockBuild, BuiltBlock, HostEnv, RollupEnv, SimCache}; +use signet_sim::{BlockBuild, BuiltBlock, SimCache}; use signet_types::constants::SignetSystemConstants; use std::time::{Duration, Instant}; use tokio::{ @@ -21,13 +21,6 @@ use tokio::{ task::JoinHandle, }; use tracing::{Instrument, Span, debug, instrument}; -use trevm::revm::{ - database::{AlloyDB, WrapDatabaseAsync}, - inspector::NoOpInspector, -}; - -type HostAlloyDatabaseProvider = WrapDatabaseAsync>; -type RollupAlloyDatabaseProvider = WrapDatabaseAsync>; /// `Simulator` is responsible for periodically building blocks and submitting them for /// signing and inclusion in the blockchain. It wraps a rollup provider and a slot @@ -112,6 +105,11 @@ impl Simulator { &self.config.slot_calculator } + /// Get the system constants. + pub const fn constants(&self) -> &SignetSystemConstants { + &self.config.constants + } + /// Handles building a single block. /// /// Builds a block in the block environment with items from the simulation cache @@ -134,16 +132,16 @@ impl Simulator { ))] pub async fn handle_build( &self, - constants: SignetSystemConstants, sim_items: SimCache, finish_by: Instant, - sim_env: SimEnv, + sim_env: &SimEnv, ) -> eyre::Result { let concurrency_limit = self.config.concurrency_limit(); let max_host_gas = self.config.max_host_gas(sim_env.prev_host().gas_limit); - let (rollup_env, host_env) = self.create_envs(constants, &sim_env).await; - debug!(rollup_block_height = ?rollup_env.block().number, host_block_height = ?host_env.block().number, "building with block environments"); + let rollup_env = sim_env.sim_rollup_env(self.constants(), self.ru_provider.clone()); + + let host_env = sim_env.sim_host_env(self.constants(), self.host_provider.clone()); let block_build = BlockBuild::new( rollup_env, @@ -167,45 +165,6 @@ impl Simulator { Ok(built_block) } - // Helper to create rollup + host envs from the sim env. - async fn create_envs( - &self, - constants: SignetSystemConstants, - sim_env: &SimEnv, - ) -> ( - RollupEnv, - HostEnv, - ) { - // Host DB and Env - let host_db = self.create_host_db().await; - - let host_block_number = sim_env.host_block_number(); - let host_env_block_number = sim_env.host_env().number; - debug!(%host_block_number, %host_env_block_number, " host env comparisons"); - - let host_env = HostEnv::::new( - host_db, - constants.clone(), - &self.config.host_cfg_env(), - sim_env.host_env(), - ); - debug!(?host_env, "created host env"); - - // Rollup DB and Env - let rollup_block_number = sim_env.rollup_block_number(); - let rollup_db = self.create_rollup_db(rollup_block_number); - - let rollup_env = RollupEnv::::new( - rollup_db, - constants, - &self.config.ru_cfg_env(), - sim_env.rollup_env(), - ); - debug!(?rollup_env, "created rollup env"); - - (rollup_env, host_env) - } - /// Spawns the simulator task, which ticks along the simulation loop /// as it receives block environments. /// @@ -220,13 +179,12 @@ impl Simulator { /// A `JoinHandle` for the spawned task. pub fn spawn_simulator_task( self, - constants: SignetSystemConstants, cache: SimCache, submit_sender: mpsc::UnboundedSender, ) -> JoinHandle<()> { debug!("starting simulator task"); - tokio::spawn(async move { self.run_simulator(constants, cache, submit_sender).await }) + tokio::spawn(async move { self.run_simulator(cache, submit_sender).await }) } /// This function runs indefinitely, waiting for the block environment to be set and checking @@ -247,7 +205,6 @@ impl Simulator { /// - `submit_sender`: A channel sender used to submit built blocks. async fn run_simulator( mut self, - constants: SignetSystemConstants, cache: SimCache, submit_sender: mpsc::UnboundedSender, ) { @@ -269,7 +226,7 @@ impl Simulator { let sim_cache = cache.clone(); let Ok(block) = self - .handle_build(constants.clone(), sim_cache, finish_by, sim_env.clone()) + .handle_build(sim_cache, finish_by, &sim_env) .instrument(span.clone()) .await .inspect_err(|err| span_error!(span, %err, "error during block build")) @@ -302,33 +259,4 @@ impl Simulator { let deadline = Instant::now() + Duration::from_secs(remaining); deadline.max(Instant::now()) } - - /// Creates an `AlloyDB` instance from the host provider. - async fn create_host_db(&self) -> HostAlloyDatabaseProvider { - let block_height = self.host_provider.get_block_number().await.unwrap(); - debug!(%block_height, "creating host alloyDB at block height"); - - let alloy_db = AlloyDB::new(self.host_provider.clone(), BlockId::latest()); - - // Wrap the AlloyDB instance in a WrapDatabaseAsync and return it. - // This is safe to unwrap because the main function sets the proper runtime settings. - // - // See: https://docs.rs/tokio/latest/tokio/attr.main.html - WrapDatabaseAsync::new(alloy_db).unwrap() - } - - /// Creates an `AlloyDB` instance from the rollup provider. - fn create_rollup_db(&self, latest_block_number: u64) -> RollupAlloyDatabaseProvider { - debug!(%latest_block_number, "creating rollup alloyDB at block height"); - - // Make an AlloyDB instance from the rollup provider with that latest block number - let alloy_db: AlloyDB = - AlloyDB::new(self.ru_provider.clone(), BlockId::from(latest_block_number)); - - // Wrap the AlloyDB instance in a WrapDatabaseAsync and return it. - // This is safe to unwrap because the main function sets the proper runtime settings. - // - // See: https://docs.rs/tokio/latest/tokio/attr.main.html - WrapDatabaseAsync::new(alloy_db).unwrap() - } } diff --git a/src/tasks/env.rs b/src/tasks/env.rs index 373ea35..f77cc3d 100644 --- a/src/tasks/env.rs +++ b/src/tasks/env.rs @@ -1,14 +1,35 @@ -use crate::config::{BuilderConfig, HostProvider, RuProvider}; +use crate::{ + config::{BuilderConfig, HostProvider, RuProvider}, + tasks::block::cfg::SignetCfgEnv, +}; use alloy::{ consensus::Header, eips::eip1559::BaseFeeParams, + network::Ethereum, primitives::{B256, U256}, - providers::Provider, + providers::{Provider, network::Network}, }; +use signet_constants::SignetSystemConstants; +use signet_sim::{HostEnv, RollupEnv}; use tokio::{sync::watch, task::JoinHandle}; use tokio_stream::StreamExt; use tracing::{Instrument, Span, debug, info_span}; -use trevm::revm::{context::BlockEnv, context_interface::block::BlobExcessGasAndPrice}; +use trevm::revm::{ + context::BlockEnv, + context_interface::block::BlobExcessGasAndPrice, + database::{AlloyDB, WrapDatabaseAsync}, + inspector::NoOpInspector, +}; + +/// Type aliases for database providers. +pub type HostAlloyDatabaseProvider = WrapDatabaseAsync>; +/// Type aliases for database providers. +pub type RollupAlloyDatabaseProvider = WrapDatabaseAsync>; + +/// Type aliases for simulation environments. +pub type SimRollupEnv = RollupEnv; +/// Type aliases for simulation environments. +pub type SimHostEnv = HostEnv; /// A task that constructs a BlockEnv for the next block in the rollup chain. #[derive(Debug, Clone)] @@ -54,6 +75,11 @@ impl Environment { pub fn for_testing() -> Self { Self { block_env: Default::default(), prev_header: Header::default() } } + + /// Create a new [`AlloyDB`] for this environment using the given provider. + pub fn alloy_db>(&self, provider: P) -> AlloyDB { + AlloyDB::new(provider, self.prev_header.number.into()) + } } /// Contains environments to simulate both host and rollup blocks. @@ -80,6 +106,16 @@ impl SimEnv { &self.host.prev_header } + /// Get the block number of the rollup block environment. + pub const fn prev_rollup_block_number(&self) -> u64 { + self.prev_rollup().number + } + + /// Get the block number for the host block environment. + pub const fn prev_host_block_number(&self) -> u64 { + self.prev_host().number + } + /// Get the block number of the rollup block environment. pub const fn rollup_block_number(&self) -> u64 { self.prev_rollup().number.saturating_add(1) @@ -109,6 +145,55 @@ impl SimEnv { pub fn clone_span(&self) -> Span { self.span.clone() } + + /// Create an [`AlloyDB`] for the rollup environment using the given + /// provider. + /// + /// # Panics + /// + /// This function will panic if not called within a Tokio runtime. + pub fn rollup_db(&self, provider: RuProvider) -> RollupAlloyDatabaseProvider { + WrapDatabaseAsync::new(self.rollup.alloy_db(provider)).expect("in tokio runtime") + } + + /// Create an [`AlloyDB`] for the host environment using the given provider. + /// + /// # Panics + /// + /// This function will panic if not called within a Tokio runtime. + pub fn host_db(&self, provider: HostProvider) -> HostAlloyDatabaseProvider { + WrapDatabaseAsync::new(self.host.alloy_db(provider)).expect("in tokio runtime") + } + + /// Create a simulated rollup environment using the given provider, + /// constants, and configuration. + /// + /// # Panics + /// + /// This function will panic if not called within a Tokio runtime. + pub fn sim_rollup_env( + &self, + constants: &SignetSystemConstants, + provider: RuProvider, + ) -> SimRollupEnv { + let rollup_cfg = SignetCfgEnv { chain_id: constants.ru_chain_id() }; + RollupEnv::new(self.rollup_db(provider), constants.clone(), &rollup_cfg, self.rollup_env()) + } + + /// Create a simulated host environment using the given provider, + /// constants, and configuration. + /// + /// # Panics + /// + /// This function will panic if not called within a Tokio runtime. + pub fn sim_host_env( + &self, + constants: &SignetSystemConstants, + provider: HostProvider, + ) -> SimHostEnv { + let host_cfg = SignetCfgEnv { chain_id: constants.host_chain_id() }; + HostEnv::new(self.host_db(provider), constants.clone(), &host_cfg, self.host_env()) + } } impl EnvTask { @@ -202,7 +287,7 @@ impl EnvTask { // Construct the block env using the previous block header let rollup_env = self.construct_rollup_env(rollup_header.into()); let host_env = self.construct_host_env(host_header); - + debug!(host_env_block_number = ?host_env.block_env().number, %host_block_number, "host block number comparisons"); span_debug!( diff --git a/src/tasks/submit/prep.rs b/src/tasks/submit/prep.rs index 310bfe2..daf807f 100644 --- a/src/tasks/submit/prep.rs +++ b/src/tasks/submit/prep.rs @@ -62,8 +62,8 @@ impl<'a> SubmitPrep<'a> { SignRequest { host_block_number: U256::from(host_block_number), - host_chain_id: U256::from(self.config.host_chain_id), - ru_chain_id: U256::from(self.config.ru_chain_id), + host_chain_id: U256::from(self.config.constants.host_chain_id()), + ru_chain_id: U256::from(self.config.constants.ru_chain_id()), gas_limit: U256::from(self.config.rollup_block_gas_limit), ru_reward_address: self.config.builder_rewards_address, contents: *self.block.contents_hash(), @@ -122,7 +122,7 @@ impl<'a> SubmitPrep<'a> { let tx = self .build_blob_tx() .await? - .with_to(self.config.builder_helper_address) + .with_to(self.config.constants.host_zenith()) .with_nonce(nonce); Ok(tx) diff --git a/src/test_utils.rs b/src/test_utils.rs index 50dd4c2..50d8c84 100644 --- a/src/test_utils.rs +++ b/src/test_utils.rs @@ -23,8 +23,6 @@ use trevm::revm::{context::BlockEnv, context_interface::block::BlobExcessGasAndP pub fn setup_test_config() -> Result { let config = BuilderConfig { // host_chain_id: signet_constants::pecorino::HOST_CHAIN_ID, - host_chain_id: 11155111, // Sepolia chain ID - ru_chain_id: signet_constants::pecorino::RU_CHAIN_ID, host_rpc: "ws://host-rpc.pecorino.signet.sh" .parse::() .map(ProviderConfig::new) @@ -36,7 +34,6 @@ pub fn setup_test_config() -> Result { .unwrap(), tx_broadcast_urls: vec!["http://localhost:9000".into()], flashbots_endpoint: Some("https://relay-sepolia.flashbots.net:443".parse().unwrap()), - zenith_address: Address::default(), quincey_url: "http://localhost:8080".into(), sequencer_key: None, builder_key: env::var("SEPOLIA_ETH_PRIV_KEY") @@ -52,7 +49,6 @@ pub fn setup_test_config() -> Result { oauth_token_url: "http://localhost:8080".parse().unwrap(), oauth_token_refresh_interval: 300, // 5 minutes }, - builder_helper_address: Address::default(), concurrency_limit: None, // NB: Defaults to available parallelism slot_calculator: SlotCalculator::new( 1740681556, // pecorino start timestamp as sane default diff --git a/tests/block_builder_test.rs b/tests/block_builder_test.rs index d8ddc30..92adfef 100644 --- a/tests/block_builder_test.rs +++ b/tests/block_builder_test.rs @@ -16,7 +16,6 @@ use builder::{ test_utils::{new_signed_tx, setup_logging, setup_test_config, test_block_env}, }; use signet_sim::SimCache; -use signet_types::constants::SignetSystemConstants; use std::time::{Duration, Instant}; /// Tests the `handle_build` method of the `Simulator`. @@ -31,7 +30,6 @@ async fn test_handle_build() { // Make a test config let config = setup_test_config().unwrap(); - let constants = SignetSystemConstants::pecorino(); // Create an anvil instance for testing let anvil_instance = Anvil::new().chain_id(signet_constants::pecorino::RU_CHAIN_ID).spawn(); @@ -45,13 +43,8 @@ async fn test_handle_build() { let ru_provider = RootProvider::::new_http(anvil_instance.endpoint_url()); let host_provider = config.connect_host_provider().await.unwrap(); - let block_env = EnvTask::new( - config.clone(), - config.connect_host_provider().await.unwrap(), - ru_provider.clone(), - ) - .spawn() - .0; + let block_env = + EnvTask::new(config.clone(), host_provider.clone(), ru_provider.clone()).spawn().0; let block_builder = Simulator::new(&config, host_provider.clone(), ru_provider.clone(), block_env); @@ -79,7 +72,7 @@ async fn test_handle_build() { rollup: Environment::new(block_env, ru_header), span: tracing::Span::none(), }; - let got = block_builder.handle_build(constants, sim_items, finish_by, sim_env).await; + let got = block_builder.handle_build(sim_items, finish_by, &sim_env).await; // Assert on the built block assert!(got.is_ok());