From 2bd1fed9315477d18f17f93e4fcce8ba069df778 Mon Sep 17 00:00:00 2001 From: Vincenzo Palazzo Date: Tue, 28 Sep 2021 00:28:43 +0200 Subject: [PATCH 1/3] [common] Move the seed logic in external module Signed-off-by: Vincenzo Palazzo --- common/src/dns.rs | 55 +++++++++++++++++++++++++++++++++++++++++++ common/src/lib.rs | 2 +- common/src/network.rs | 2 ++ node/src/lib.rs | 2 ++ 4 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 common/src/dns.rs diff --git a/common/src/dns.rs b/common/src/dns.rs new file mode 100644 index 00000000..46cd3e56 --- /dev/null +++ b/common/src/dns.rs @@ -0,0 +1,55 @@ +//! Seed resolution. +use std::{iter}; + + +/// DNS feature +#[derive(Debug, Copy, Clone)] +pub enum SeedFeature { + /// x1, Full Node + NODE_NETWORK, + /// x5, all include in x1 plus Node network + NODE_BLOOM, + /// x9, all included in x1 plus Node Witness + NODE_WITNESS, + /// xd (aka x13), all included in x9 and x5 + FULL_NODE, +} + +impl Default for SeedFeature { + fn default() -> Self { + Self::NODE_NETWORK + } +} + +impl SeedFeature { + + pub fn as_code(&self) -> &'static str{ + match self { + Self::NODE_NETWORK => &"x1", + Self::NODE_BLOOM => &"x5", + Self::NODE_WITNESS => &"x9", + Self::FULL_NODE => &"xd", + } + } +} + +/// Seeds implementation +pub struct Seeds<'a> { + pub seeds: Vec<&'a str>, +} + +impl<'a> Seeds<'a> { + /// Create a new seed with the requirements + pub fn new(features: &[SeedFeature]) -> Self { + Seeds { + seeds: vec![] + } + } + + // FIXME(vincenzopalazzo): Return the iterator of the vetor + // to make easy the change in the interface. + pub fn iter(&self) -> &std::slice::Iter<'a, str> { + self.seeds.iter(); + } +} + diff --git a/common/src/lib.rs b/common/src/lib.rs index d2685a59..2c80f7a8 100644 --- a/common/src/lib.rs +++ b/common/src/lib.rs @@ -5,7 +5,7 @@ pub mod block; pub mod collections; pub mod network; pub mod p2p; - +mod dns; pub use nonempty; /// Return the function path at the current source location. diff --git a/common/src/network.rs b/common/src/network.rs index dc4af0e8..115395eb 100644 --- a/common/src/network.rs +++ b/common/src/network.rs @@ -10,6 +10,8 @@ use bitcoin_hashes::sha256d; use crate::block::Height; +use super::dns; + /// Peer services supported by nakamoto. #[derive(Debug, Copy, Clone)] pub enum Services { diff --git a/node/src/lib.rs b/node/src/lib.rs index 4ac0f5c1..3b35a762 100644 --- a/node/src/lib.rs +++ b/node/src/lib.rs @@ -11,6 +11,8 @@ pub use nakamoto_client::Domain; pub mod logger; +mod dns; + /// The network reactor we're going to use. type Reactor = nakamoto_net_poll::Reactor; From c105598af80fe20dbe4a6037828fe6e237049df0 Mon Sep 17 00:00:00 2001 From: Vincenzo Palazzo Date: Tue, 28 Sep 2021 13:38:35 +0200 Subject: [PATCH 2/3] [common] Continuing refactoring seed logic Signed-off-by: Vincenzo Palazzo --- common/src/dns.rs | 46 ++++++++++++++++++++++++++++++++++++------- common/src/network.rs | 3 +-- node/src/lib.rs | 2 -- 3 files changed, 40 insertions(+), 11 deletions(-) diff --git a/common/src/dns.rs b/common/src/dns.rs index 46cd3e56..5f796ee4 100644 --- a/common/src/dns.rs +++ b/common/src/dns.rs @@ -1,6 +1,5 @@ //! Seed resolution. -use std::{iter}; - +use crate::network::{Network}; /// DNS feature #[derive(Debug, Copy, Clone)] @@ -35,21 +34,54 @@ impl SeedFeature { /// Seeds implementation pub struct Seeds<'a> { - pub seeds: Vec<&'a str>, + /// The network to work load the dns + network: Network, + /// List of seed with all the feature supported by nakamoto + seeds: Vec<&'a str>, } impl<'a> Seeds<'a> { /// Create a new seed with the requirements - pub fn new(features: &[SeedFeature]) -> Self { + pub fn new(network: Network, features: &[SeedFeature]) -> Self { Seeds { - seeds: vec![] + network: network, + seeds: vec![], } } // FIXME(vincenzopalazzo): Return the iterator of the vetor // to make easy the change in the interface. - pub fn iter(&self) -> &std::slice::Iter<'a, str> { - self.seeds.iter(); + pub fn iter(&self) -> std::slice::Iter<'a, &str> { + self.seeds.iter() + } + + pub fn load(&self) -> &[&str] { + let seed = self.from_network(); + seed + } + + fn from_network(&self) -> &[&str] { + match self.network { + Network::Mainnet => &[ + "seed.bitcoin.sipa.be", // Pieter Wuille + "dnsseed.bluematt.me", // Matt Corallo + "dnsseed.bitcoin.dashjr.org", // Luke Dashjr + "seed.bitcoinstats.com", // Christian Decker + "seed.bitcoin.jonasschnelli.ch", // Jonas Schnelli + "seed.btc.petertodd.org", // Peter Todd + "seed.bitcoin.sprovoost.nl", // Sjors Provoost + "dnsseed.emzy.de", // Stephan Oeste + "seed.bitcoin.wiz.biz", // Jason Maurice + "seed.cloudhead.io", // Alexis Sellier + ], + Network::Testnet => &[ + "testnet-seed.bitcoin.jonasschnelli.ch", + "seed.tbtc.petertodd.org", + "seed.testnet.bitcoin.sprovoost.nl", + "testnet-seed.bluematt.me", + ], + Network::Regtest => &[], // No seeds + } } } diff --git a/common/src/network.rs b/common/src/network.rs index 115395eb..51c93f00 100644 --- a/common/src/network.rs +++ b/common/src/network.rs @@ -9,8 +9,7 @@ use bitcoin_hashes::hex::FromHex; use bitcoin_hashes::sha256d; use crate::block::Height; - -use super::dns; +use crate::dns; /// Peer services supported by nakamoto. #[derive(Debug, Copy, Clone)] diff --git a/node/src/lib.rs b/node/src/lib.rs index 3b35a762..4ac0f5c1 100644 --- a/node/src/lib.rs +++ b/node/src/lib.rs @@ -11,8 +11,6 @@ pub use nakamoto_client::Domain; pub mod logger; -mod dns; - /// The network reactor we're going to use. type Reactor = nakamoto_net_poll::Reactor; From 48f28457c2375fcb501af948318fc747ee1cabde Mon Sep 17 00:00:00 2001 From: Vincenzo Palazzo Date: Tue, 28 Sep 2021 15:49:41 +0200 Subject: [PATCH 3/3] [common] Resolving seeds socket addr, and skip seed with unsupported feature Signed-off-by: Vincenzo Palazzo --- common/src/dns.rs | 59 ++++++++++++++++++++++++++++-------------- common/src/lib.rs | 2 +- common/src/p2p/peer.rs | 2 ++ 3 files changed, 43 insertions(+), 20 deletions(-) diff --git a/common/src/dns.rs b/common/src/dns.rs index 5f796ee4..d4bd1385 100644 --- a/common/src/dns.rs +++ b/common/src/dns.rs @@ -1,5 +1,8 @@ //! Seed resolution. -use crate::network::{Network}; +use log::debug; +use std::net::{SocketAddr, ToSocketAddrs}; + +use crate::network::Network; /// DNS feature #[derive(Debug, Copy, Clone)] @@ -21,8 +24,7 @@ impl Default for SeedFeature { } impl SeedFeature { - - pub fn as_code(&self) -> &'static str{ + pub fn as_code(&self) -> &'static str { match self { Self::NODE_NETWORK => &"x1", Self::NODE_BLOOM => &"x5", @@ -36,33 +38,30 @@ impl SeedFeature { pub struct Seeds<'a> { /// The network to work load the dns network: Network, - /// List of seed with all the feature supported by nakamoto - seeds: Vec<&'a str>, + /// The default port of the node + port: u16, + /// List of feature supported by nakamoto + features: &'a [SeedFeature], } impl<'a> Seeds<'a> { /// Create a new seed with the requirements - pub fn new(network: Network, features: &[SeedFeature]) -> Self { + pub fn new(network: Network, port: u16, features: &'a [SeedFeature]) -> Self { Seeds { - network: network, - seeds: vec![], + network, + port, + features, } } - // FIXME(vincenzopalazzo): Return the iterator of the vetor - // to make easy the change in the interface. - pub fn iter(&self) -> std::slice::Iter<'a, &str> { - self.seeds.iter() - } - - pub fn load(&self) -> &[&str] { - let seed = self.from_network(); - seed + pub fn load(&self) -> Vec { + let seeds = self.from_network(); + self.filter_by_feature(seeds) } fn from_network(&self) -> &[&str] { match self.network { - Network::Mainnet => &[ + Network::Mainnet => &[ "seed.bitcoin.sipa.be", // Pieter Wuille "dnsseed.bluematt.me", // Matt Corallo "dnsseed.bitcoin.dashjr.org", // Luke Dashjr @@ -83,5 +82,27 @@ impl<'a> Seeds<'a> { Network::Regtest => &[], // No seeds } } -} + fn filter_by_feature(&self, seed_list: &[&str]) -> Vec { + let mut seeds_addr = Vec::new(); + for feature in self.features { + let feature_code = feature.as_code(); + debug!("Filtering by feature {}", feature_code); + + for seed in seed_list { + let sub_seed = format!("{}.{}:{}", feature_code, seed, self.port); + debug!("Sub seed {} checking ...", sub_seed); + if let Ok(hosts) = (*sub_seed).to_socket_addrs() { + for host in hosts { + seeds_addr.push(host); + } + } else { + // we admit the failure at this point because not all the seed + // support all the feature. + debug!("Seed {} doesn't support feature {}", seed, feature_code); + } + } + } + seeds_addr + } +} diff --git a/common/src/lib.rs b/common/src/lib.rs index 2c80f7a8..ea8182a8 100644 --- a/common/src/lib.rs +++ b/common/src/lib.rs @@ -3,9 +3,9 @@ #![deny(missing_docs, unsafe_code)] pub mod block; pub mod collections; +mod dns; pub mod network; pub mod p2p; -mod dns; pub use nonempty; /// Return the function path at the current source location. diff --git a/common/src/p2p/peer.rs b/common/src/p2p/peer.rs index f9f9cb10..f1c57df3 100644 --- a/common/src/p2p/peer.rs +++ b/common/src/p2p/peer.rs @@ -45,6 +45,8 @@ pub trait Store { seeds: impl Iterator, source: Source, ) -> io::Result<()> { + // TODO(vincenzopalazzo): move this logic inside the dns module in comm + // and use this method to add only the list of the socket addrs. let mut error = None; let mut success = false;