diff --git a/src/config.rs b/src/config.rs index 078b562..6b1fbb7 100644 --- a/src/config.rs +++ b/src/config.rs @@ -190,6 +190,7 @@ fn parse_config(config_str: &str) -> Result { let toml_config: TomlConfig = toml::from_str(config_str)?; let mut networks: Vec = vec![]; + let mut network_ids: Vec = vec![]; for toml_network in toml_config.networks.iter() { let mut nodes: Vec = vec![]; let mut node_ids: Vec = vec![]; @@ -215,7 +216,18 @@ fn parse_config(config_str: &str) -> Result { } } match parse_toml_network(toml_network, nodes) { - Ok(network) => networks.push(network), + Ok(network) => { + if !network_ids.contains(&network.id) { + network_ids.push(network.id); + networks.push(network); + } else { + error!( + "Duplicate network id {}: The network {} could not be loaded.", + network.id, network.name + ); + return Err(ConfigError::DuplicateNetworkId); + } + } Err(e) => { error!( "Error while parsing a network configuration: {:?}", @@ -359,4 +371,53 @@ mod tests { panic!("Test did not error!"); } } + + #[test] + fn error_on_duplicate_network_id_test() { + if let Err(ConfigError::DuplicateNetworkId) = parse_config( + r#" + database_path = "" + www_path = "./www" + query_interval = 15 + address = "127.0.0.1:2323" + rss_base_url = "" + footer_html = "" + + [[networks]] + id = 1 + name = "" + description = "" + min_fork_height = 0 + max_interesting_heights = 0 + + [[networks.nodes]] + id = 0 + name = "Node B" + description = "" + rpc_host = "127.0.0.1" + rpc_port = 0 + rpc_user = "" + rpc_password = "" + [[networks]] + id = 1 + name = "" + description = "" + min_fork_height = 0 + max_interesting_heights = 0 + + [[networks.nodes]] + id = 0 + name = "Node B" + description = "" + rpc_host = "127.0.0.1" + rpc_port = 0 + rpc_user = "" + rpc_password = "" + "#, + ) { + // test OK, as we expect this to error + } else { + panic!("Test did not error!"); + } + } } diff --git a/src/error.rs b/src/error.rs index 5abf5f2..748c54d 100644 --- a/src/error.rs +++ b/src/error.rs @@ -112,6 +112,7 @@ pub enum ConfigError { NoNetworks, UnknownImplementation, DuplicateNodeId, + DuplicateNetworkId, TomlError(toml::de::Error), ReadError(io::Error), AddrError(AddrParseError), @@ -126,6 +127,7 @@ impl fmt::Display for ConfigError { ConfigError::NoNetworks => write!(f, "no networks defined in the configuration"), ConfigError::UnknownImplementation => write!(f, "the node implementation defined in the config is not supported"), ConfigError::DuplicateNodeId => write!(f, "a node id has been used multiple times in the same network"), + ConfigError::DuplicateNetworkId => write!(f, "a network id has been used multiple times"), ConfigError::TomlError(e) => write!(f, "the TOML in the configuration file could not be parsed: {}", e), ConfigError::ReadError(e) => write!(f, "the configuration file could not be read: {}", e), ConfigError::AddrError(e) => write!(f, "the address could not be parsed: {}", e), @@ -145,6 +147,7 @@ impl error::Error for ConfigError { ConfigError::ReadError(ref e) => Some(e), ConfigError::AddrError(ref e) => Some(e), ConfigError::DuplicateNodeId => None, + ConfigError::DuplicateNetworkId => None, } } }