use std::time::Duration;
use eyre::Result;
use ethers_core::types::{Address, H256};
use ethers_providers::Middleware;
use crate::{metrics::Metrics, L1Client, rollup::{RollupNode, SyncStatus}, OutputOracle, builder::VarroBuilder, prelude::VarroBuilderError};
#[derive(Debug, Clone)]
pub struct Varro {
l1_client: L1Client,
rollup_node: RollupNode,
output_oracle: OutputOracle,
allow_non_finalized: bool,
proposer: Address,
output_private_key: H256,
polling_interval: Duration,
metrics: Option<Metrics>,
}
impl TryFrom<VarroBuilder> for Varro {
type Error = VarroBuilderError;
fn try_from(mut builder: VarroBuilder) -> std::result::Result<Self, Self::Error> {
let l1_client = builder.l1_client.take().ok_or(VarroBuilderError::MissingL1Client)?;
let rollup_node = builder.rollup_node.take().ok_or(VarroBuilderError::MissingRollupNode)?;
let output_oracle = builder.output_oracle.take().ok_or(VarroBuilderError::MissingOutputOracle)?;
let proposer = builder.proposer.take().ok_or(VarroBuilderError::MissingProposer)?;
let output_private_key = builder.output_private_key.take().ok_or(VarroBuilderError::MissingOutputPrivateKey)?;
let polling_interval = builder.polling_interval.take().ok_or(VarroBuilderError::MissingPollingInterval)?;
let allow_non_finalized = match builder.allow_non_finalized {
Some(allow_non_finalized) => allow_non_finalized,
None => {
tracing::warn!(target: "varro=client", "VarroBuilder was not provided 'allow_non_finalized', defaulting to false");
false
}
};
let metrics = builder.metrics.take();
Ok(Varro {
l1_client,
rollup_node,
output_oracle,
allow_non_finalized,
proposer,
output_private_key,
polling_interval,
metrics
})
}
}
impl Varro {
pub fn get_block_number(&self, sync_status: SyncStatus) -> u64 {
if !self.allow_non_finalized {
return sync_status.finalized_l2;
}
sync_status.safe_l2
}
pub async fn start(&self) -> Result<()> {
let l1_chain_id = self.l1_client.get_chainid().await?;
loop {
let next_block_number = self.output_oracle.get_next_block_number().await?;
let sync_status = self.rollup_node.sync_status().await?;
let block_number = self.get_block_number(sync_status);
if block_number < next_block_number {
tracing::info!(target: "varro=client", "proposer submission interval has not elapsed, current block number: {}, next block number: {}", block_number, next_block_number);
continue;
}
let output = self.rollup_node.output_at_block(next_block_number).await?;
}
Ok(())
}
}