Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion bin/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,11 @@ async fn main() -> eyre::Result<()> {
// RU WS connection is invalid.
let (ru_provider, host_provider) =
tokio::try_join!(config.connect_ru_provider(), config.connect_host_provider(),)?;
let quincey = config.connect_quincey().await?;

// Spawn the EnvTask
let env_task = EnvTask::new(config.clone(), host_provider.clone(), ru_provider.clone());
let env_task =
EnvTask::new(config.clone(), host_provider.clone(), quincey, ru_provider.clone());
let (block_env, env_jh) = env_task.spawn();

// Spawn the cache system
Expand Down
10 changes: 9 additions & 1 deletion src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ macro_rules! span_info {

}

/// Helper macro to log a warning event within a span that is not currently
/// entered.
macro_rules! span_warn {
($span:expr, $($arg:tt)*) => {
span_scoped!($span, warn!($($arg)*))
};
}

/// Helper macro to log a warning event within a span that is not currently
/// entered.
macro_rules! span_error {
Expand All @@ -34,7 +42,7 @@ macro_rules! span_error {

/// Helper macro to unwrap a result or continue the loop with a tracing event.
macro_rules! res_unwrap_or_continue {
($result:expr, $span:expr, $level:ident!($($arg:tt)*)) => {
($result:expr, $span:expr, $level:ident!($($arg:tt)*) $(,)?) => {
match $result {
Ok(value) => value,
Err(err) => {
Expand Down
39 changes: 38 additions & 1 deletion src/quincey.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
use alloy::signers::Signer;
use alloy::{
primitives::{Address, B256, U256},
signers::Signer,
};
use eyre::bail;
use init4_bin_base::{perms::SharedToken, utils::signer::LocalOrAws};
use reqwest::Client;
use signet_constants::SignetSystemConstants;
use signet_types::{SignRequest, SignResponse};
use tracing::{debug, info, instrument, trace};

Expand Down Expand Up @@ -35,6 +39,16 @@ impl Quincey {
Self::Owned(client)
}

/// Returns `true` if the signer is local.
pub const fn is_local(&self) -> bool {
matches!(self, Self::Owned(_))
}

/// Returns `true` if the signer is remote.
pub const fn is_remote(&self) -> bool {
matches!(self, Self::Remote { .. })
}

async fn sup_owned(&self, sig_request: &SignRequest) -> eyre::Result<SignResponse> {
let Self::Owned(signer) = &self else { eyre::bail!("not an owned client") };

Expand Down Expand Up @@ -77,4 +91,27 @@ impl Quincey {
Self::Remote { .. } => self.sup_remote(sig_request).await,
}
}

/// Perform a preflight check to ensure that the Quincey service will
/// be able to sign a request with the provided parameters at this
/// point in time.
#[instrument(skip(self, constants))]
pub async fn preflight_check(
&self,
constants: &SignetSystemConstants,
host_block_number: u64,
) -> eyre::Result<()> {
if self.is_local() {
return Ok(());
}
let req = SignRequest {
host_block_number: U256::from(host_block_number),
host_chain_id: U256::from(constants.host_chain_id()),
ru_chain_id: U256::from(constants.ru_chain_id()),
gas_limit: U256::ZERO,
ru_reward_address: Address::ZERO,
contents: B256::ZERO,
};
self.sup_remote(&req).await.map(|_| ())
}
}
61 changes: 44 additions & 17 deletions src/tasks/env.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::{
config::{BuilderConfig, HostProvider, RuProvider},
quincey::Quincey,
tasks::block::cfg::SignetCfgEnv,
};
use alloy::{
Expand Down Expand Up @@ -31,21 +32,6 @@ pub type SimRollupEnv = RollupEnv<RollupAlloyDatabaseProvider, NoOpInspector>;
/// Type aliases for simulation environments.
pub type SimHostEnv = HostEnv<HostAlloyDatabaseProvider, NoOpInspector>;

/// A task that constructs a BlockEnv for the next block in the rollup chain.
#[derive(Debug, Clone)]
pub struct EnvTask {
/// Builder configuration values.
config: BuilderConfig,

/// Host provider is used to get the latest host block header for
/// constructing the next block environment.
host_provider: HostProvider,

/// Rollup provider is used to get the latest rollup block header for
/// simulation.
ru_provider: RuProvider,
}

/// An environment for simulating a block.
#[derive(Debug, Clone)]
pub struct Environment {
Expand Down Expand Up @@ -196,14 +182,33 @@ impl SimEnv {
}
}

/// A task that constructs a BlockEnv for the next block in the rollup chain.
#[derive(Debug, Clone)]
pub struct EnvTask {
/// Builder configuration values.
config: BuilderConfig,

/// Host provider is used to get the latest host block header for
/// constructing the next block environment.
host_provider: HostProvider,

/// Quincey instance for slot checking.
quincey: Quincey,

/// Rollup provider is used to get the latest rollup block header for
/// simulation.
ru_provider: RuProvider,
}

impl EnvTask {
/// Create a new [`EnvTask`] with the given config and providers.
pub const fn new(
config: BuilderConfig,
host_provider: HostProvider,
quincey: Quincey,
ru_provider: RuProvider,
) -> Self {
Self { config, host_provider, ru_provider }
Self { config, host_provider, quincey, ru_provider }
}

/// Construct a [`BlockEnv`] for the next host block from the previous host header.
Expand Down Expand Up @@ -271,11 +276,23 @@ impl EnvTask {

let span = info_span!("SimEnv", %host_block_number, %rollup_header.hash, %rollup_header.number);

let (host_block_res, quincey_res) = tokio::join!(
self.host_provider.get_block_by_number(host_block_number.into()),
self.quincey.preflight_check(&self.config.constants, host_block_number)
);

res_unwrap_or_continue!(
quincey_res,
span,
error!("error checking quincey slot - skipping block submission"),
);

let host_block_opt = res_unwrap_or_continue!(
self.host_provider.get_block_by_number(host_block_number.into()).await,
host_block_res,
span,
error!("error fetching previous host block - skipping block submission")
);

let host_header = opt_unwrap_or_continue!(
host_block_opt,
span,
Expand All @@ -284,6 +301,16 @@ impl EnvTask {
.header
.inner;

if rollup_header.timestamp != host_header.timestamp {
span_warn!(
span,
rollup_timestamp = rollup_header.timestamp,
host_timestamp = host_header.timestamp,
"rollup block timestamp differs from host block timestamp. - skipping block submission"
);
continue;
}

// 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);
Expand Down
5 changes: 4 additions & 1 deletion tests/block_builder_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,11 @@ async fn test_handle_build() {
let ru_provider = RootProvider::<Ethereum>::new_http(anvil_instance.endpoint_url());
let host_provider = config.connect_host_provider().await.unwrap();

// Create a quincey client
let quincey = config.connect_quincey().await.unwrap();

let block_env =
EnvTask::new(config.clone(), host_provider.clone(), ru_provider.clone()).spawn().0;
EnvTask::new(config.clone(), host_provider.clone(), quincey, ru_provider.clone()).spawn().0;

let block_builder =
Simulator::new(&config, host_provider.clone(), ru_provider.clone(), block_env);
Expand Down
1 change: 1 addition & 0 deletions tests/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ async fn test_bundle_poller_roundtrip() -> eyre::Result<()> {
let (block_env, _jh) = EnvTask::new(
config.clone(),
config.connect_host_provider().await?,
config.connect_quincey().await?,
config.connect_ru_provider().await?,
)
.spawn();
Expand Down
2 changes: 2 additions & 0 deletions tests/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ async fn test_bundle_poller_roundtrip() -> eyre::Result<()> {
setup_logging();

let config = setup_test_config().unwrap();

let (mut env_watcher, _jh) = EnvTask::new(
config.clone(),
config.connect_host_provider().await?,
config.connect_quincey().await?,
config.connect_ru_provider().await?,
)
.spawn();
Expand Down