stratus/eth/miner/
miner_config.rsuse std::str::FromStr;
use std::sync::Arc;
use std::time::Duration;
use clap::Parser;
use display_json::DebugAsJson;
use crate::eth::miner::Miner;
use crate::eth::storage::StratusStorage;
use crate::ext::not;
use crate::ext::parse_duration;
use crate::GlobalState;
use crate::NodeMode;
#[derive(Parser, DebugAsJson, Clone, serde::Serialize)]
pub struct MinerConfig {
#[arg(long = "block-mode", env = "BLOCK_MODE", default_value = "automine")]
pub block_mode: MinerMode,
}
impl MinerConfig {
pub async fn init(&self, storage: Arc<StratusStorage>) -> anyhow::Result<Arc<Miner>> {
tracing::info!(config = ?self, "creating block miner");
let mode = match GlobalState::get_node_mode() {
NodeMode::Follower | NodeMode::FakeLeader => {
if not(self.block_mode.is_external()) {
tracing::error!(block_mode = ?self.block_mode, "invalid block-mode, a follower's miner can only start as external!");
}
MinerMode::External
}
NodeMode::Leader => self.block_mode,
};
self.init_with_mode(mode, storage).await
}
pub async fn init_with_mode(&self, mode: MinerMode, storage: Arc<StratusStorage>) -> anyhow::Result<Arc<Miner>> {
tracing::info!(config = ?self, mode = ?mode, "creating block miner with specific mode");
let miner = Miner::new(Arc::clone(&storage), mode);
let miner = Arc::new(miner);
if let MinerMode::Interval(block_time) = mode {
miner.start_interval_mining(block_time).await;
}
Ok(miner)
}
}
#[derive(Debug, Clone, Copy, PartialEq, strum::EnumIs, serde::Serialize, serde::Deserialize)]
pub enum MinerMode {
#[serde(rename = "automine")]
Automine,
#[serde(rename = "interval")]
Interval(Duration),
#[serde(rename = "external")]
External,
}
impl FromStr for MinerMode {
type Err = anyhow::Error;
fn from_str(s: &str) -> anyhow::Result<Self, Self::Err> {
match s {
"automine" => Ok(Self::Automine),
"external" => Ok(Self::External),
s => {
let block_time = parse_duration(s)?;
Ok(Self::Interval(block_time))
}
}
}
}