diff --git a/protocols/gossipsub/CHANGELOG.md b/protocols/gossipsub/CHANGELOG.md index b6a9eed434d..2ba33d085c6 100644 --- a/protocols/gossipsub/CHANGELOG.md +++ b/protocols/gossipsub/CHANGELOG.md @@ -1,5 +1,9 @@ ## 0.46.0 - unreleased +- Return typed error from config builder. + See [PR 4445]. + +[PR 4445]: https://github.com/libp2p/rust-libp2p/pull/4445 ## 0.45.2 @@ -22,7 +26,7 @@ ## 0.45.1 -- Add getter function to obtain `TopicScoreParams`. +- Add getter function to o btain `TopicScoreParams`. See [PR 4231]. [PR 4231]: https://github.com/libp2p/rust-libp2p/pull/4231 diff --git a/protocols/gossipsub/src/config.rs b/protocols/gossipsub/src/config.rs index 8ca1d4044f3..3c971abc601 100644 --- a/protocols/gossipsub/src/config.rs +++ b/protocols/gossipsub/src/config.rs @@ -22,6 +22,7 @@ use std::borrow::Cow; use std::sync::Arc; use std::time::Duration; +use crate::error::ConfigBuilderError; use crate::protocol::{ProtocolConfig, ProtocolId, FLOODSUB_PROTOCOL}; use crate::types::{FastMessageId, Message, MessageId, PeerKind, RawMessage}; @@ -834,40 +835,34 @@ impl ConfigBuilder { } /// Constructs a [`Config`] from the given configuration and validates the settings. - pub fn build(&self) -> Result { + pub fn build(&self) -> Result { // check all constraints on config if self.config.protocol.max_transmit_size < 100 { - return Err("The maximum transmission size must be greater than 100 to permit basic control messages"); + return Err(ConfigBuilderError::MaxTransmissionSizeTooSmall); } if self.config.history_length < self.config.history_gossip { - return Err( - "The history_length must be greater than or equal to the history_gossip \ - length", - ); + return Err(ConfigBuilderError::HistoryLengthTooSmall); } if !(self.config.mesh_outbound_min <= self.config.mesh_n_low && self.config.mesh_n_low <= self.config.mesh_n && self.config.mesh_n <= self.config.mesh_n_high) { - return Err("The following inequality doesn't hold \ - mesh_outbound_min <= mesh_n_low <= mesh_n <= mesh_n_high"); + return Err(ConfigBuilderError::MeshParametersInvalid); } if self.config.mesh_outbound_min * 2 > self.config.mesh_n { - return Err( - "The following inequality doesn't hold mesh_outbound_min <= self.config.mesh_n / 2", - ); + return Err(ConfigBuilderError::MeshOutboundInvalid); } if self.config.unsubscribe_backoff.as_millis() == 0 { - return Err("The unsubscribe_backoff parameter should be positive."); + return Err(ConfigBuilderError::UnsubscribeBackoffIsZero); } if self.invalid_protocol { - return Err("The provided protocol is invalid, it must start with a forward-slash"); + return Err(ConfigBuilderError::InvalidProtocol); } Ok(self.config.clone()) diff --git a/protocols/gossipsub/src/error.rs b/protocols/gossipsub/src/error.rs index 26f71a346c3..c461abc0d17 100644 --- a/protocols/gossipsub/src/error.rs +++ b/protocols/gossipsub/src/error.rs @@ -120,3 +120,37 @@ impl From for PublishError { PublishError::TransformFailed(error) } } + +/// Error associated with Config building. +#[derive(Debug)] +pub enum ConfigBuilderError { + /// Maximum transmission size is too small. + MaxTransmissionSizeTooSmall, + /// Histroy length less than history gossip length. + HistoryLengthTooSmall, + /// The ineauality doesn't hold mesh_outbound_min <= mesh_n_low <= mesh_n <= mesh_n_high + MeshParametersInvalid, + /// The inequality doesn't hold mesh_outbound_min <= self.config.mesh_n / 2 + MeshOutboundInvalid, + /// unsubscribe_backoff is zero + UnsubscribeBackoffIsZero, + /// Invalid protocol + InvalidProtocol, +} + +impl std::error::Error for ConfigBuilderError {} + +impl std::fmt::Display for ConfigBuilderError { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + match self { + Self::MaxTransmissionSizeTooSmall => { + write!(f, "Maximum transmission size is too small") + } + Self::HistoryLengthTooSmall => write!(f, "Histroy length less than history gossip length"), + Self::MeshParametersInvalid => write!(f, "The ineauality doesn't hold mesh_outbound_min <= mesh_n_low <= mesh_n <= mesh_n_high"), + Self::MeshOutboundInvalid => write!(f, "The inequality doesn't hold mesh_outbound_min <= self.config.mesh_n / 2"), + Self::UnsubscribeBackoffIsZero => write!(f, "unsubscribe_backoff is zero"), + Self::InvalidProtocol => write!(f, "Invalid protocol"), + } + } +} diff --git a/protocols/gossipsub/src/lib.rs b/protocols/gossipsub/src/lib.rs index e065319c4c3..fdc5c05ac76 100644 --- a/protocols/gossipsub/src/lib.rs +++ b/protocols/gossipsub/src/lib.rs @@ -158,7 +158,7 @@ mod types; pub use self::behaviour::{Behaviour, Event, MessageAuthenticity}; pub use self::config::{Config, ConfigBuilder, ValidationMode, Version}; -pub use self::error::{PublishError, SubscriptionError, ValidationError}; +pub use self::error::{ConfigBuilderError, PublishError, SubscriptionError, ValidationError}; pub use self::metrics::Config as MetricsConfig; pub use self::peer_score::{ score_parameter_decay, score_parameter_decay_with_base, PeerScoreParams, PeerScoreThresholds,