use std::{convert::TryFrom, path::Path};
use serde::{Deserialize, Serialize};
use casper_execution_engine::shared::{system_config::SystemConfig, wasm_config::WasmConfig};
use casper_types::{EraId, ProtocolVersion};
use super::{
accounts_config::AccountsConfig, global_state_update::GlobalStateUpdateConfig, ActivationPoint,
Chainspec, CoreConfig, DeployConfig, Error, GlobalStateUpdate, HighwayConfig, NetworkConfig,
ProtocolConfig,
};
use crate::utils::{self, Loadable};
#[derive(PartialEq, Eq, Serialize, Deserialize, Debug)]
#[serde(deny_unknown_fields)]
struct TomlNetwork {
name: String,
maximum_net_message_size: u32,
}
#[derive(PartialEq, Eq, Serialize, Deserialize, Debug)]
#[serde(deny_unknown_fields)]
struct TomlProtocol {
version: ProtocolVersion,
hard_reset: bool,
activation_point: ActivationPoint,
last_emergency_restart: Option<EraId>,
}
#[derive(PartialEq, Eq, Serialize, Deserialize, Debug)]
#[serde(deny_unknown_fields)]
pub(super) struct TomlChainspec {
protocol: TomlProtocol,
network: TomlNetwork,
core: CoreConfig,
deploys: DeployConfig,
highway: HighwayConfig,
wasm: WasmConfig,
system_costs: SystemConfig,
}
impl From<&Chainspec> for TomlChainspec {
fn from(chainspec: &Chainspec) -> Self {
let protocol = TomlProtocol {
version: chainspec.protocol_config.version,
hard_reset: chainspec.protocol_config.hard_reset,
activation_point: chainspec.protocol_config.activation_point,
last_emergency_restart: chainspec.protocol_config.last_emergency_restart,
};
let network = TomlNetwork {
name: chainspec.network_config.name.clone(),
maximum_net_message_size: chainspec.network_config.maximum_net_message_size,
};
let core = chainspec.core_config;
let deploys = chainspec.deploy_config;
let highway = chainspec.highway_config;
let wasm = chainspec.wasm_config;
let system_costs = chainspec.system_costs_config;
TomlChainspec {
protocol,
network,
core,
deploys,
highway,
wasm,
system_costs,
}
}
}
pub(super) fn parse_toml<P: AsRef<Path>>(chainspec_path: P) -> Result<Chainspec, Error> {
let bytes = utils::read_file(chainspec_path.as_ref()).map_err(Error::LoadChainspec)?;
let toml_chainspec: TomlChainspec = toml::from_slice(&bytes)?;
let root = chainspec_path
.as_ref()
.parent()
.unwrap_or_else(|| Path::new(""));
let accounts_config = AccountsConfig::from_path(root)?;
let network_config = NetworkConfig {
name: toml_chainspec.network.name,
accounts_config,
maximum_net_message_size: toml_chainspec.network.maximum_net_message_size,
};
let global_state_update = Option::<GlobalStateUpdateConfig>::from_path(root)?
.map(GlobalStateUpdate::try_from)
.transpose()?;
let protocol_config = ProtocolConfig {
version: toml_chainspec.protocol.version,
hard_reset: toml_chainspec.protocol.hard_reset,
activation_point: toml_chainspec.protocol.activation_point,
global_state_update,
last_emergency_restart: toml_chainspec.protocol.last_emergency_restart,
};
Ok(Chainspec {
protocol_config,
network_config,
core_config: toml_chainspec.core,
deploy_config: toml_chainspec.deploys,
highway_config: toml_chainspec.highway,
wasm_config: toml_chainspec.wasm,
system_costs_config: toml_chainspec.system_costs,
})
}