pub(crate) use crate::common::*;
use nix::unistd;
use ruc::*;
use serde::{Deserialize, Serialize};
use std::{env, fmt, fs, str::FromStr, sync::LazyLock};
pub trait NodePorts:
Clone + fmt::Debug + Send + Sync + Serialize + for<'a> Deserialize<'a>
{
fn reserved() -> Vec<u16> {
let mut ret = Self::app_reserved();
ret.extend_from_slice(&Self::sys_reserved());
ret
}
fn sys_reserved() -> Vec<u16> {
[26656, 26657, 26658].to_vec()
}
fn app_reserved() -> Vec<u16>;
fn try_create(ports: &[u16]) -> Result<Self>;
fn get_port_list(&self) -> Vec<u16>;
fn get_sys_p2p(&self) -> u16;
fn get_sys_rpc(&self) -> u16;
fn get_sys_abci(&self) -> u16;
}
pub(crate) static BASE_DIR: LazyLock<String> = LazyLock::new(|| {
let ret = env::var("RUNTIME_CHAIN_DEV_BASE_DIR").unwrap_or_else(|_| {
format!(
"/tmp/__CHAIN_DEV__/tendermint_based/{}/{}/{}",
option_env!("STATIC_CHAIN_DEV_BASE_DIR_SUFFIX").unwrap_or(""),
unistd::gethostname().unwrap().into_string().unwrap(),
unistd::User::from_uid(unistd::getuid())
.unwrap()
.unwrap()
.name,
)
});
pnk!(fs::create_dir_all(&ret));
ret
});
pub(crate) const PRESET_POWER: u32 = 1_000_000_000;
#[derive(Debug, Copy, Clone, Deserialize, Serialize)]
#[serde(untagged)]
pub enum BlockItv {
Int(u16),
Float(f32),
}
impl BlockItv {
pub(crate) fn to_millisecond(self) -> Result<u32> {
const ITV_MAX: u16 = u16::MAX;
match self {
Self::Int(i) => Ok((i as u32) * 1000),
Self::Float(i) => {
if i > (ITV_MAX as f32) {
Err(eg!("block interval too big, max value: {}s", ITV_MAX))
} else {
Ok((i * 1000.0) as u32)
}
}
}
}
}
impl From<u8> for BlockItv {
fn from(t: u8) -> BlockItv {
Self::Int(t as u16)
}
}
impl From<u16> for BlockItv {
fn from(t: u16) -> BlockItv {
Self::Int(t)
}
}
impl From<f32> for BlockItv {
fn from(t: f32) -> BlockItv {
Self::Float(t)
}
}
impl fmt::Display for BlockItv {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Int(i) => write!(f, "{}", i),
Self::Float(i) => write!(f, "{}", i),
}
}
}
impl FromStr for BlockItv {
type Err = Box<(dyn ruc::RucError)>;
fn from_str(s: &str) -> Result<Self> {
s.parse::<u16>()
.map(Self::Int)
.c(d!())
.or_else(|_| s.parse::<f32>().map(Self::Float).c(d!()))
}
}
impl From<BlockItv> for f32 {
fn from(t: BlockItv) -> Self {
match t {
BlockItv::Int(i) => i as f32,
BlockItv::Float(i) => i,
}
}
}
impl From<BlockItv> for f64 {
fn from(t: BlockItv) -> Self {
f32::from(t) as f64
}
}