|
1 | 1 | use crate::{
|
2 |
| - ipmode::IpMode, kbucket::MAX_NODES_PER_BUCKET, Enr, Executor, PermitBanList, RateLimiter, |
3 |
| - RateLimiterBuilder, |
| 2 | + ipmode::IpMode, |
| 3 | + kbucket::MAX_NODES_PER_BUCKET, |
| 4 | + packet::{PROTOCOL_ID_LENGTH, PROTOCOL_VERSION_LENGTH}, |
| 5 | + Enr, Executor, PermitBanList, RateLimiter, RateLimiterBuilder, |
4 | 6 | };
|
5 | 7 | ///! A set of configuration parameters to tune the discovery protocol.
|
6 | 8 | use std::time::Duration;
|
| 9 | +use std::{convert::TryInto, num::NonZeroU16}; |
| 10 | + |
| 11 | +/// Protocol ID sent with each message. |
| 12 | +pub(crate) const DEFAULT_PROTOCOL_ID: [u8; PROTOCOL_ID_LENGTH] = *b"discv5"; |
| 13 | +/// The version sent with each handshake. |
| 14 | +pub(crate) const DEFAULT_PROTOCOL_VERSION: [u8; PROTOCOL_VERSION_LENGTH] = 0x0001_u16.to_be_bytes(); |
7 | 15 |
|
8 | 16 | /// Configuration parameters that define the performance of the discovery network.
|
9 | 17 | #[derive(Clone)]
|
@@ -99,6 +107,9 @@ pub struct Discv5Config {
|
99 | 107 | /// A custom executor which can spawn the discv5 tasks. This must be a tokio runtime, with
|
100 | 108 | /// timing support. By default, the executor that created the discv5 struct will be used.
|
101 | 109 | pub executor: Option<Box<dyn Executor + Send + Sync>>,
|
| 110 | + |
| 111 | + /// The Discv5 protocol id and version, in bytes. |
| 112 | + pub protocol: ([u8; PROTOCOL_ID_LENGTH], [u8; PROTOCOL_VERSION_LENGTH]), |
102 | 113 | }
|
103 | 114 |
|
104 | 115 | impl Default for Discv5Config {
|
@@ -138,6 +149,7 @@ impl Default for Discv5Config {
|
138 | 149 | ban_duration: Some(Duration::from_secs(3600)), // 1 hour
|
139 | 150 | ip_mode: IpMode::default(),
|
140 | 151 | executor: None,
|
| 152 | + protocol: (DEFAULT_PROTOCOL_ID, DEFAULT_PROTOCOL_VERSION), |
141 | 153 | }
|
142 | 154 | }
|
143 | 155 | }
|
@@ -314,6 +326,30 @@ impl Discv5ConfigBuilder {
|
314 | 326 | self
|
315 | 327 | }
|
316 | 328 |
|
| 329 | + /// Set the discv5 wire protocol id. |
| 330 | + pub fn protocol_id(&mut self, protocol_id: &'static str) -> &mut Self { |
| 331 | + let protocol_id: [u8; PROTOCOL_ID_LENGTH] = |
| 332 | + protocol_id.as_bytes().try_into().unwrap_or_else(|_| { |
| 333 | + panic!("The protocol id must be {} bytes long", PROTOCOL_ID_LENGTH) |
| 334 | + }); |
| 335 | + |
| 336 | + self.config.protocol = (protocol_id, DEFAULT_PROTOCOL_VERSION); |
| 337 | + self |
| 338 | + } |
| 339 | + |
| 340 | + /// Set the discv5 wire protocol id and the version. |
| 341 | + pub fn protocol( |
| 342 | + &mut self, |
| 343 | + protocol_id: &'static str, |
| 344 | + protocol_version: NonZeroU16, |
| 345 | + ) -> &mut Self { |
| 346 | + self.protocol_id(protocol_id); |
| 347 | + let protocol_version = protocol_version.get().to_be_bytes(); |
| 348 | + |
| 349 | + self.config.protocol.1 = protocol_version; |
| 350 | + self |
| 351 | + } |
| 352 | + |
317 | 353 | pub fn build(&mut self) -> Discv5Config {
|
318 | 354 | // If an executor is not provided, assume a current tokio runtime is running.
|
319 | 355 | if self.config.executor.is_none() {
|
@@ -347,6 +383,7 @@ impl std::fmt::Debug for Discv5Config {
|
347 | 383 | .field("incoming_bucket_limit", &self.incoming_bucket_limit)
|
348 | 384 | .field("ping_interval", &self.ping_interval)
|
349 | 385 | .field("ban_duration", &self.ban_duration)
|
| 386 | + .field("protocol", &self.protocol) |
350 | 387 | .finish()
|
351 | 388 | }
|
352 | 389 | }
|
0 commit comments