use crate::protocol::{GossipsubMessage, MessageId};
use std::borrow::Cow;
use std::time::Duration;
pub const IDENTITY_SOURCE: [u8; 3] = [0, 1, 0];
#[derive(Clone)]
pub struct GossipsubConfig {
pub protocol_id: Cow<'static, [u8]>,
pub history_length: usize,
pub history_gossip: usize,
pub mesh_n: usize,
pub mesh_n_low: usize,
pub mesh_n_high: usize,
pub gossip_lazy: usize,
pub heartbeat_initial_delay: Duration,
pub heartbeat_interval: Duration,
pub fanout_ttl: Duration,
pub max_transmit_size: usize,
pub hash_topics: bool,
pub no_source_id: bool,
pub manual_propagation: bool,
pub message_id_fn: fn(&GossipsubMessage) -> MessageId,
}
impl Default for GossipsubConfig {
fn default() -> GossipsubConfig {
GossipsubConfig {
protocol_id: Cow::Borrowed(b"/meshsub/1.0.0"),
history_length: 5,
history_gossip: 3,
mesh_n: 6,
mesh_n_low: 4,
mesh_n_high: 12,
gossip_lazy: 6, heartbeat_initial_delay: Duration::from_secs(5),
heartbeat_interval: Duration::from_secs(1),
fanout_ttl: Duration::from_secs(60),
max_transmit_size: 2048,
hash_topics: false, no_source_id: false,
manual_propagation: false,
message_id_fn: |message| {
let mut source_string = message.source.to_base58();
source_string.push_str(&message.sequence_number.to_string());
MessageId(source_string)
},
}
}
}
pub struct GossipsubConfigBuilder {
config: GossipsubConfig,
}
impl Default for GossipsubConfigBuilder {
fn default() -> GossipsubConfigBuilder {
GossipsubConfigBuilder {
config: GossipsubConfig::default(),
}
}
}
impl GossipsubConfigBuilder {
pub fn new() -> GossipsubConfigBuilder {
GossipsubConfigBuilder::default()
}
pub fn protocol_id(&mut self, protocol_id: impl Into<Cow<'static, [u8]>>) -> &mut Self {
self.config.protocol_id = protocol_id.into();
self
}
pub fn history_length(&mut self, history_length: usize) -> &mut Self {
assert!(
history_length >= self.config.history_gossip,
"The history_length must be greater than or equal to the history_gossip length"
);
self.config.history_length = history_length;
self
}
pub fn history_gossip(&mut self, history_gossip: usize) -> &mut Self {
assert!(
self.config.history_length >= history_gossip,
"The history_length must be greater than or equal to the history_gossip length"
);
self.config.history_gossip = history_gossip;
self
}
pub fn mesh_n(&mut self, mesh_n: usize) -> &mut Self {
assert!(
self.config.mesh_n_low <= mesh_n && mesh_n <= self.config.mesh_n_high,
"The following equality doesn't hold mesh_n_low <= mesh_n <= mesh_n_high"
);
self.config.mesh_n = mesh_n;
self
}
pub fn mesh_n_low(&mut self, mesh_n_low: usize) -> &mut Self {
assert!(
mesh_n_low <= self.config.mesh_n && self.config.mesh_n <= self.config.mesh_n_high,
"The following equality doesn't hold mesh_n_low <= mesh_n <= mesh_n_high"
);
self.config.mesh_n_low = mesh_n_low;
self
}
pub fn mesh_n_high(&mut self, mesh_n_high: usize) -> &mut Self {
assert!(
self.config.mesh_n_low <= self.config.mesh_n && self.config.mesh_n <= mesh_n_high,
"The following equality doesn't hold mesh_n_low <= mesh_n <= mesh_n_high"
);
self.config.mesh_n_high = mesh_n_high;
self
}
pub fn gossip_lazy(&mut self, gossip_lazy: usize) -> &mut Self {
self.config.gossip_lazy = gossip_lazy;
self
}
pub fn heartbeat_initial_delay(&mut self, heartbeat_initial_delay: Duration) -> &mut Self {
self.config.heartbeat_initial_delay = heartbeat_initial_delay;
self
}
pub fn heartbeat_interval(&mut self, heartbeat_interval: Duration) -> &mut Self {
self.config.heartbeat_interval = heartbeat_interval;
self
}
pub fn fanout_ttl(&mut self, fanout_ttl: Duration) -> &mut Self {
self.config.fanout_ttl = fanout_ttl;
self
}
pub fn max_transmit_size(&mut self, max_transmit_size: usize) -> &mut Self {
self.config.max_transmit_size = max_transmit_size;
self
}
pub fn hash_topics(&mut self) -> &mut Self {
self.config.hash_topics = true;
self
}
pub fn no_source_id(&mut self) -> &mut Self {
self.config.no_source_id = true;
self
}
pub fn manual_propagation(&mut self) -> &mut Self {
self.config.manual_propagation = true;
self
}
pub fn message_id_fn(&mut self, id_fn: fn(&GossipsubMessage) -> MessageId) -> &mut Self {
self.config.message_id_fn = id_fn;
self
}
pub fn build(&self) -> GossipsubConfig {
self.config.clone()
}
}
impl std::fmt::Debug for GossipsubConfig {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
let mut builder = f.debug_struct("GossipsubConfig");
let _ = builder.field("protocol_id", &self.protocol_id);
let _ = builder.field("history_length", &self.history_length);
let _ = builder.field("history_gossip", &self.history_gossip);
let _ = builder.field("mesh_n", &self.mesh_n);
let _ = builder.field("mesh_n_low", &self.mesh_n_low);
let _ = builder.field("mesh_n_high", &self.mesh_n_high);
let _ = builder.field("gossip_lazy", &self.gossip_lazy);
let _ = builder.field("heartbeat_initial_delay", &self.heartbeat_initial_delay);
let _ = builder.field("heartbeat_interval", &self.heartbeat_interval);
let _ = builder.field("fanout_ttl", &self.fanout_ttl);
let _ = builder.field("max_transmit_size", &self.max_transmit_size);
let _ = builder.field("hash_topics", &self.hash_topics);
let _ = builder.field("no_source_id", &self.no_source_id);
let _ = builder.field("manual_propagation", &self.manual_propagation);
builder.finish()
}
}