use crate::helpers::{NodeType, Status, Tasks};
use snarkvm::dpc::Network;
use once_cell::sync::OnceCell;
use rayon::{ThreadPool, ThreadPoolBuilder};
use std::{
collections::HashSet,
fmt::Debug,
marker::PhantomData,
net::SocketAddr,
sync::{atomic::AtomicBool, Arc},
};
#[rustfmt::skip]
pub trait Environment: 'static + Clone + Debug + Default + Send + Sync {
type Network: Network;
const NODE_TYPE: NodeType;
const MESSAGE_VERSION: u32 = 12;
const COINBASE_IS_PUBLIC: bool = false;
const DEFAULT_NODE_PORT: u16 = 4130 + Self::Network::NETWORK_ID;
const DEFAULT_RPC_PORT: u16 = 3030 + Self::Network::NETWORK_ID;
const BEACON_NODES: &'static [&'static str] = &[];
const SYNC_NODES: &'static [&'static str] = &["127.0.0.1:4135"];
const HEARTBEAT_IN_SECS: u64 = 9;
const CONNECTION_TIMEOUT_IN_MILLIS: u64 = 500;
const PING_SLEEP_IN_SECS: u64 = 60;
const RADIO_SILENCE_IN_SECS: u64 = 210; const FAILURE_EXPIRY_TIME_IN_SECS: u64 = 7200;
const MINIMUM_NUMBER_OF_PEERS: usize;
const MAXIMUM_NUMBER_OF_PEERS: usize;
const MAXIMUM_CONNECTION_FAILURES: u32 = 3;
const MAXIMUM_CANDIDATE_PEERS: usize = 10_000;
const MAXIMUM_MESSAGE_SIZE: usize = 128 * 1024 * 1024; const MAXIMUM_BLOCK_REQUEST: u32 = 250;
const MAXIMUM_NUMBER_OF_FAILURES: usize = 1024;
fn beacon_nodes() -> &'static HashSet<SocketAddr> {
static NODES: OnceCell<HashSet<SocketAddr>> = OnceCell::new();
NODES.get_or_init(|| Self::BEACON_NODES.iter().map(|ip| ip.parse().unwrap()).collect())
}
fn sync_nodes() -> &'static HashSet<SocketAddr> {
static NODES: OnceCell<HashSet<SocketAddr>> = OnceCell::new();
NODES.get_or_init(|| Self::SYNC_NODES.iter().map(|ip| ip.parse().unwrap()).collect())
}
fn tasks() -> &'static Tasks<tokio::task::JoinHandle<()>> {
static TASKS: OnceCell<Tasks<tokio::task::JoinHandle<()>>> = OnceCell::new();
TASKS.get_or_init(Tasks::new)
}
fn status() -> &'static Status {
static STATUS: OnceCell<Status> = OnceCell::new();
STATUS.get_or_init(Status::new)
}
fn terminator() -> &'static Arc<AtomicBool> {
static TERMINATOR: OnceCell<Arc<AtomicBool>> = OnceCell::new();
TERMINATOR.get_or_init(|| Arc::new(AtomicBool::new(false)))
}
fn thread_pool() -> &'static Arc<ThreadPool> {
static POOL: OnceCell<Arc<ThreadPool>> = OnceCell::new();
POOL.get_or_init(|| {
Arc::new(ThreadPoolBuilder::new()
.stack_size(8 * 1024 * 1024)
.num_threads((num_cpus::get() * 7 / 8).max(2))
.build()
.expect("Failed to initialize a thread pool for the node"))
})
}
}
#[derive(Clone, Debug, Default)]
pub struct Client<N: Network>(PhantomData<N>);
#[rustfmt::skip]
impl<N: Network> Environment for Client<N> {
type Network = N;
const NODE_TYPE: NodeType = NodeType::Client;
const MINIMUM_NUMBER_OF_PEERS: usize = 2;
const MAXIMUM_NUMBER_OF_PEERS: usize = 21;
}
#[derive(Clone, Debug, Default)]
pub struct Miner<N: Network>(PhantomData<N>);
#[rustfmt::skip]
impl<N: Network> Environment for Miner<N> {
type Network = N;
const NODE_TYPE: NodeType = NodeType::Miner;
const COINBASE_IS_PUBLIC: bool = true;
const MINIMUM_NUMBER_OF_PEERS: usize = 1;
const MAXIMUM_NUMBER_OF_PEERS: usize = 21;
}
#[derive(Clone, Debug, Default)]
pub struct Operator<N: Network>(PhantomData<N>);
#[rustfmt::skip]
impl<N: Network> Environment for Operator<N> {
type Network = N;
const NODE_TYPE: NodeType = NodeType::Operator;
const COINBASE_IS_PUBLIC: bool = true;
const MINIMUM_NUMBER_OF_PEERS: usize = 1;
const MAXIMUM_NUMBER_OF_PEERS: usize = 1000;
}
#[derive(Clone, Debug, Default)]
pub struct Prover<N: Network>(PhantomData<N>);
#[rustfmt::skip]
impl<N: Network> Environment for Prover<N> {
type Network = N;
const NODE_TYPE: NodeType = NodeType::Prover;
const COINBASE_IS_PUBLIC: bool = true;
const MINIMUM_NUMBER_OF_PEERS: usize = 2;
const MAXIMUM_NUMBER_OF_PEERS: usize = 21;
}
#[derive(Clone, Debug, Default)]
pub struct SyncNode<N: Network>(PhantomData<N>);
#[rustfmt::skip]
impl<N: Network> Environment for SyncNode<N> {
type Network = N;
const NODE_TYPE: NodeType = NodeType::Sync;
const MINIMUM_NUMBER_OF_PEERS: usize = 35;
const MAXIMUM_NUMBER_OF_PEERS: usize = 1024;
const HEARTBEAT_IN_SECS: u64 = 5;
}
#[derive(Clone, Debug, Default)]
pub struct ClientTrial<N: Network>(PhantomData<N>);
#[rustfmt::skip]
impl<N: Network> Environment for ClientTrial<N> {
type Network = N;
const NODE_TYPE: NodeType = NodeType::Client;
const SYNC_NODES: &'static [&'static str] = &[
"144.126.219.193:4132", "165.232.145.194:4132", "143.198.164.241:4132", "188.166.7.13:4132", "167.99.40.226:4132",
"159.223.124.150:4132", "137.184.192.155:4132", "147.182.213.228:4132", "137.184.202.162:4132", "159.223.118.35:4132",
"161.35.106.91:4132", "157.245.133.62:4132", "143.198.166.150:4132",
];
const MINIMUM_NUMBER_OF_PEERS: usize = 11;
const MAXIMUM_NUMBER_OF_PEERS: usize = 31;
}
#[derive(Clone, Debug, Default)]
pub struct MinerTrial<N: Network>(PhantomData<N>);
#[rustfmt::skip]
impl<N: Network> Environment for MinerTrial<N> {
type Network = N;
const NODE_TYPE: NodeType = NodeType::Miner;
const SYNC_NODES: &'static [&'static str] = &[
"144.126.219.193:4132", "165.232.145.194:4132", "143.198.164.241:4132", "188.166.7.13:4132", "167.99.40.226:4132",
"159.223.124.150:4132", "137.184.192.155:4132", "147.182.213.228:4132", "137.184.202.162:4132", "159.223.118.35:4132",
"161.35.106.91:4132", "157.245.133.62:4132", "143.198.166.150:4132",
];
const MINIMUM_NUMBER_OF_PEERS: usize = 11;
const MAXIMUM_NUMBER_OF_PEERS: usize = 21;
const COINBASE_IS_PUBLIC: bool = true;
}
#[derive(Clone, Debug, Default)]
pub struct OperatorTrial<N: Network>(PhantomData<N>);
#[rustfmt::skip]
impl<N: Network> Environment for OperatorTrial<N> {
type Network = N;
const NODE_TYPE: NodeType = NodeType::Operator;
const SYNC_NODES: &'static [&'static str] = &[
"144.126.219.193:4132", "165.232.145.194:4132", "143.198.164.241:4132", "188.166.7.13:4132", "167.99.40.226:4132",
"159.223.124.150:4132", "137.184.192.155:4132", "147.182.213.228:4132", "137.184.202.162:4132", "159.223.118.35:4132",
"161.35.106.91:4132", "157.245.133.62:4132", "143.198.166.150:4132",
];
const MINIMUM_NUMBER_OF_PEERS: usize = 11;
const MAXIMUM_NUMBER_OF_PEERS: usize = 1000;
const COINBASE_IS_PUBLIC: bool = true;
}
#[derive(Clone, Debug, Default)]
pub struct ProverTrial<N: Network>(PhantomData<N>);
#[rustfmt::skip]
impl<N: Network> Environment for ProverTrial<N> {
type Network = N;
const NODE_TYPE: NodeType = NodeType::Prover;
const SYNC_NODES: &'static [&'static str] = &[
"144.126.219.193:4132", "165.232.145.194:4132", "143.198.164.241:4132", "188.166.7.13:4132", "167.99.40.226:4132",
"159.223.124.150:4132", "137.184.192.155:4132", "147.182.213.228:4132", "137.184.202.162:4132", "159.223.118.35:4132",
"161.35.106.91:4132", "157.245.133.62:4132", "143.198.166.150:4132",
];
const MINIMUM_NUMBER_OF_PEERS: usize = 11;
const MAXIMUM_NUMBER_OF_PEERS: usize = 21;
const COINBASE_IS_PUBLIC: bool = true;
}