#[cfg(feature = "rpc")]
use crate::common::address::get_challenge_verifier_address;
#[cfg(feature = "rpc")]
use crate::{
challenge_verifier::ChallengeVerifier, newton_policy_client::NewtonPolicyClient,
newton_prover_task_manager::NewtonProverTaskManager,
};
#[cfg(feature = "rpc")]
use alloy::{
primitives::{Address, ChainId, B256},
providers::Provider,
};
#[cfg(feature = "rpc")]
use newton_rpc_provider::get_provider;
#[cfg(feature = "rpc")]
use tracing::info;
#[cfg(feature = "rpc")]
pub use crate::common::address::{
get_mock_newton_policy_client_address, get_newton_prover_service_manager, get_newton_prover_task_manager,
};
#[cfg(feature = "rpc")]
pub async fn get_chain_id(rpc_url: &str) -> ChainId {
let provider = get_provider(rpc_url);
provider.get_chain_id().await.expect("Failed to get chain ID")
}
#[cfg(feature = "rpc")]
pub async fn get_task_response_window_blocks(rpc_url: &str) -> eyre::Result<u32> {
let chain_id = get_chain_id(rpc_url).await;
let provider = get_provider(rpc_url);
match chain_id {
id if is_supported_chain(id) => {
let task_manager_addr = get_newton_prover_task_manager(chain_id).await?;
let task_manager = NewtonProverTaskManager::new(task_manager_addr, &provider);
let task_response_window_block = task_manager
.taskResponseWindowBlock()
.call()
.await
.map_err(|e| eyre::eyre!("Failed to fetch task response window block from task manager: {}", e))?;
Ok(task_response_window_block)
}
_ => Err(eyre::eyre!("Unsupported chain id: {}", chain_id)),
}
}
#[cfg(feature = "rpc")]
pub async fn get_task_challenge_window_blocks(rpc_url: &str) -> eyre::Result<u32> {
let chain_id = get_chain_id(rpc_url).await;
let provider = get_provider(rpc_url);
match chain_id {
id if is_supported_chain(id) => {
let challenge_verifier_addr = get_challenge_verifier_address(chain_id).await?;
let challenge_verifier = ChallengeVerifier::new(challenge_verifier_addr, &provider);
let challenge_window_blocks = challenge_verifier
.taskChallengeWindowBlock()
.call()
.await
.map_err(|e| eyre::eyre!("Failed to fetch task challenge window from challenge verifier: {}", e))?;
Ok(challenge_window_blocks)
}
_ => Err(eyre::eyre!("Unsupported chain id: {}", chain_id)),
}
}
pub fn get_block_duration_ms(chain_id: ChainId) -> Result<u64, String> {
match chain_id {
ETHEREUM_MAINNET | SEPOLIA => Ok(12000),
1337 | LOCAL_ANVIL | LOCAL_ANVIL_DESTINATION => Ok(1000), BASE_MAINNET | BASE_SEPOLIA => Ok(2000),
ROBINHOOD | ROBINHOOD_TESTNET => Ok(100),
ARC | ARC_TESTNET => Ok(500),
_ => Err(format!(
"Unsupported chain ID: {}. Please add support for this chain.",
chain_id
)),
}
}
pub fn get_block_gas_limit(chain_id: ChainId) -> u64 {
match chain_id {
ETHEREUM_MAINNET | SEPOLIA => 36_000_000, BASE_MAINNET | BASE_SEPOLIA => 240_000_000, ROBINHOOD | ROBINHOOD_TESTNET => 32_000_000, ARC | ARC_TESTNET => 30_000_000, _ => 30_000_000, }
}
pub const fn task_created_block_offset(chain_id: ChainId) -> u64 {
match chain_id {
BASE_MAINNET | BASE_SEPOLIA | ROBINHOOD | ROBINHOOD_TESTNET => 5,
_ => 1,
}
}
#[cfg(feature = "rpc")]
pub async fn get_block_time_ms(rpc_url: &str) -> eyre::Result<u64> {
let chain_id = get_chain_id(rpc_url).await;
info!("Fetching block time for chain ID {}", chain_id);
let block_time_ms =
get_block_duration_ms(chain_id).map_err(|e| eyre::eyre!("Failed to get block duration: {}", e))?;
info!("Block time for chain ID {} is {} ms", chain_id, block_time_ms);
if block_time_ms == 0 {
Err(eyre::eyre!("Block time is zero"))
} else {
Ok(block_time_ms)
}
}
#[cfg(feature = "rpc")]
pub async fn get_epoch_blocks(rpc_url: &str) -> eyre::Result<u64> {
let chain_id = get_chain_id(rpc_url).await;
let provider = get_provider(rpc_url);
match chain_id {
31337 | 31338 | 11155111 | 1 | 84532 => {
let task_manager_addr = get_newton_prover_task_manager(chain_id).await?;
let task_manager = NewtonProverTaskManager::new(task_manager_addr, &provider);
let epoch_blocks: u32 = task_manager
.epochBlocks()
.call()
.await
.map_err(|e| eyre::eyre!("Failed to fetch epoch blocks from task manager: {}", e))?;
Ok(epoch_blocks as u64)
}
_ => Err(eyre::eyre!("Unsupported chain id: {}", chain_id)),
}
}
pub const ETHEREUM_MAINNET: u64 = 1;
pub const SEPOLIA: u64 = 11155111;
pub const LOCAL_ANVIL: u64 = 31337;
pub const LOCAL_ANVIL_DESTINATION: u64 = 31338;
pub const BASE_MAINNET: u64 = 8453;
pub const BASE_SEPOLIA: u64 = 84532;
pub const ROBINHOOD: u64 = 4663;
pub const ROBINHOOD_TESTNET: u64 = 46630;
pub const ARC: u64 = 5042;
pub const ARC_TESTNET: u64 = 5042002;
#[inline]
pub const fn is_source_chain(chain_id: u64) -> bool {
matches!(chain_id, ETHEREUM_MAINNET | SEPOLIA | LOCAL_ANVIL)
}
#[inline]
pub const fn is_destination_chain(chain_id: u64) -> bool {
is_supported_chain(chain_id) && !is_source_chain(chain_id)
}
#[inline]
pub const fn is_eigenlayer_supported_destination(chain_id: u64) -> bool {
matches!(chain_id, BASE_MAINNET | BASE_SEPOLIA)
}
#[inline]
pub const fn requires_newton_registry(chain_id: u64) -> bool {
is_destination_chain(chain_id) && !is_eigenlayer_supported_destination(chain_id)
}
#[inline]
pub const fn get_source_chain_id(chain_id: u64) -> Option<u64> {
if is_source_chain(chain_id) {
return Some(chain_id);
}
if chain_id == LOCAL_ANVIL_DESTINATION {
return Some(LOCAL_ANVIL);
}
if is_testnet(chain_id) {
return Some(SEPOLIA);
}
if is_mainnet(chain_id) {
return Some(ETHEREUM_MAINNET);
}
None }
#[inline]
pub const fn is_mainnet(chain_id: u64) -> bool {
matches!(chain_id, ETHEREUM_MAINNET | BASE_MAINNET | ROBINHOOD | ARC)
}
#[inline]
pub const fn is_testnet(chain_id: u64) -> bool {
matches!(chain_id, SEPOLIA | BASE_SEPOLIA | ROBINHOOD_TESTNET | ARC_TESTNET)
}
#[inline]
pub const fn is_local(chain_id: u64) -> bool {
matches!(chain_id, LOCAL_ANVIL | LOCAL_ANVIL_DESTINATION)
}
#[inline]
pub const fn is_supported_chain(chain_id: u64) -> bool {
is_mainnet(chain_id) || is_testnet(chain_id) || is_local(chain_id)
}