Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions base_layer/core/src/base_node/tari_pulse_service/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,8 @@ impl TariPulseService {
})
}

async fn get_dns_client(&self) -> Result<DnsClient, anyhow::Error> {
let client = DnsClient::connect(DnsNameServer::System).await?;
fn get_dns_client(&self) -> Result<DnsClient, anyhow::Error> {
let client = DnsClient::connect(DnsNameServer::System)?;
Ok(client)
}

Expand Down Expand Up @@ -239,7 +239,7 @@ impl TariPulseService {
}

async fn fetch_checkpoints(&mut self) -> Result<Vec<(u64, String)>, anyhow::Error> {
let mut client = self.get_dns_client().await?;
let mut client = self.get_dns_client()?;
let response = client.query_txt(self.dns_name).await?;
let checkpoints: Vec<(u64, String)> = response
.iter()
Expand Down
7 changes: 6 additions & 1 deletion base_layer/p2p/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,12 @@ tokio-stream = { version = "0.1.9", default-features = false, features = [
"time",
] }
tower = "0.4.11"
hickory-resolver = { version = "=0.25.0-alpha.4", features = ["tokio-runtime", "dns-over-tls", "dns-over-rustls"] }
hickory-resolver = { version = "=0.25.0-alpha.4", features = [
"tokio-runtime",
"dns-over-tls",
"dns-over-rustls",
"native-certs",
] }
hickory-proto = { version = "=0.25.0-alpha.4" }

[dev-dependencies]
Expand Down
6 changes: 3 additions & 3 deletions base_layer/p2p/src/auto_update/dns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,12 @@ pub struct DnsSoftwareUpdate {

impl DnsSoftwareUpdate {
/// Connect to DNS host according to the given config
pub async fn connect(config: AutoUpdateConfig) -> Result<Self, AutoUpdateError> {
pub fn connect(config: AutoUpdateConfig) -> Result<Self, AutoUpdateError> {
let name_server = config.name_server.clone();
let client = if config.use_dnssec {
DnsClient::connect_secure(name_server).await?
DnsClient::connect_secure(name_server)?
} else {
DnsClient::connect(name_server).await?
DnsClient::connect(name_server)?
};

Ok(Self { client, config })
Expand Down
2 changes: 1 addition & 1 deletion base_layer/p2p/src/auto_update/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ pub async fn check_for_updates(
let download_base_url = config.download_base_url.clone();
let hashes_url = config.hashes_url.clone();
let hashes_sig_url = config.hashes_sig_url.clone();
let dns_update = dns::DnsSoftwareUpdate::connect(config).await?;
let dns_update = dns::DnsSoftwareUpdate::connect(config)?;

match dns_update.check_for_updates(app, arch, version).await? {
Some(update_spec) => {
Expand Down
22 changes: 18 additions & 4 deletions base_layer/p2p/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,24 @@ impl Default for PeerSeedsConfig {
Self {
override_from: None,
peer_seeds: StringList::default(),
dns_seeds: vec![format!(
"seeds.{}.tari.com",
Network::get_current_or_user_setting_or_default().as_key_str()
)]
dns_seeds: vec![
format!(
"seeds.{}.tari.com",
Network::get_current_or_user_setting_or_default().as_key_str()
),
format!(
"ip4.seeds.{}.tari.com",
Network::get_current_or_user_setting_or_default().as_key_str()
),
format!(
"ip6.seeds.{}.tari.com",
Network::get_current_or_user_setting_or_default().as_key_str()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can also add tor.seeds.{}.tari.com, if we want to pull as many nodes?

),
format!(
"tor.seeds.{}.tari.com",
Network::get_current_or_user_setting_or_default().as_key_str()
),
]
.into(),
dns_seed_name_servers: DnsNameServerList::from_str(
"system, 1.1.1.1:853/cloudflare-dns.com, 8.8.8.8:853/dns.google, 9.9.9.9:853/dns.quad9.net",
Expand Down
12 changes: 10 additions & 2 deletions base_layer/p2p/src/dns/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ pub struct DnsClient {
}

impl DnsClient {
pub async fn connect_secure(name_server: DnsNameServer) -> Result<Self, DnsClientError> {
pub fn connect_secure(name_server: DnsNameServer) -> Result<Self, DnsClientError> {
let resolver = match name_server {
DnsNameServer::System => TokioResolver::from_system_conf(TokioConnectionProvider::default())?,
DnsNameServer::Custom { addr, dns_name } => Self::create_resolver(addr, dns_name, Protocol::Tls),
Expand All @@ -52,7 +52,7 @@ impl DnsClient {
Ok(Self { resolver })
}

pub async fn connect(name_server: DnsNameServer) -> Result<Self, DnsClientError> {
pub fn connect(name_server: DnsNameServer) -> Result<Self, DnsClientError> {
let resolver = match name_server {
DnsNameServer::System => TokioResolver::from_system_conf(TokioConnectionProvider::default())?,
DnsNameServer::Custom { addr, dns_name } => Self::create_resolver(addr, dns_name, Protocol::default()),
Expand All @@ -76,9 +76,11 @@ impl DnsClient {
bind_addr: None,
tls_config: None,
});

let mut opts = ResolverOpts::default();
opts.edns0 = true;
opts.try_tcp_on_error = true;
opts.timeout = std::time::Duration::from_secs(1);
TokioResolver::tokio(conf, opts)
}

Expand Down Expand Up @@ -115,6 +117,12 @@ impl DnsClient {
// Exclude the first length byte from the string result
Some(String::from_utf8_lossy(&txt[1..=len]).to_string())
})
.inspect_err(|e| {
warn!(
target: LOG_TARGET,
"Failed to parse DNS TXT record. Error: {}", e
);
})
.transpose()
})
.collect::<Result<_, DnsClientError>>()?;
Expand Down
38 changes: 23 additions & 15 deletions base_layer/p2p/src/initialization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,10 @@ use tari_storage::{
LMDBWrapper,
};
use thiserror::Error;
use tokio::sync::{broadcast, mpsc};
use tokio::{
sync::{broadcast, mpsc},
time::timeout,
};
use tower::ServiceBuilder;

use crate::{
Expand Down Expand Up @@ -508,7 +511,20 @@ impl P2pInitializer {
P2pInitializer::get_dns_seed_resolver(config.dns_seeds_use_dnssec, &config.dns_seed_name_servers).await?;
let resolving = config.dns_seeds.iter().map(|addr| {
let mut resolver = resolver.clone();
async move { (resolver.resolve(addr).await, addr) }
async move {
let timer = Instant::now();
let seeds_res = match timeout(Duration::from_secs(5), resolver.resolve(addr)).await {
Ok(res) => res,
Err(_) => {
warn!(target: LOG_TARGET, "Timeout resolving DNS seed `{}`", addr);
Err(DnsClientError::Timeout)
},
};
// let res = (resolver.resolve(addr).await, addr);
let res = (seeds_res, addr.clone());
info!(target: LOG_TARGET, "Resolved DNS seed `{}` in {:.0?}", addr, timer.elapsed());
res
}
});

let peers = future::join_all(resolving)
Expand Down Expand Up @@ -549,23 +565,15 @@ impl P2pInitializer {
}
let mut dns_errors = Vec::new();
for dns in dns_seed_name_servers {
info!(target: LOG_TARGET, "Connecting to DNS name server: {}", dns);
let res = match (dns_seeds_use_dnssec, dns == &DnsNameServer::System) {
(true, false) => DnsSeedResolver::connect_secure(dns.clone()).await,
(_, _) => DnsSeedResolver::connect(dns.clone()).await,
(true, false) => DnsSeedResolver::connect_secure(dns.clone()),
(_, _) => DnsSeedResolver::connect(dns.clone()),
};
match res {
Ok(val) => {
trace!(target: LOG_TARGET, "Found DNS client at '{}'", dns);
return Ok(val);
},
Ok(resolver) => return Ok(resolver),
Err(err) => {
warn!(
target: LOG_TARGET,
"DNS entry '{}' did not respond, trying the next one. You can edit 'dns_seed_name_servers' in \
the config file. (Error: {})",
dns,
err.to_string(),
);
warn!(target: LOG_TARGET, "Failed to connect to DNS name server: {}", err);
dns_errors.push(err.to_string())
},
}
Expand Down
49 changes: 13 additions & 36 deletions base_layer/p2p/src/peer_seeds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,17 +54,17 @@ impl DnsSeedResolver {
///
/// ## Arguments
/// -`name_server` - the DNS name server to use to resolve records
pub async fn connect_secure(name_server: DnsNameServer) -> Result<Self, DnsClientError> {
let client = DnsClient::connect_secure(name_server).await?;
pub fn connect_secure(name_server: DnsNameServer) -> Result<Self, DnsClientError> {
let client = DnsClient::connect_secure(name_server)?;
Ok(Self { client })
}

/// Connect without DNSSEC protection
///
/// ## Arguments
/// -`name_server` - the DNS name server to use to resolve records
pub async fn connect(name_server: DnsNameServer) -> Result<Self, DnsClientError> {
let client = DnsClient::connect(name_server).await?;
pub fn connect(name_server: DnsNameServer) -> Result<Self, DnsClientError> {
let client = DnsClient::connect(name_server)?;
Ok(Self { client })
}

Expand All @@ -80,7 +80,7 @@ impl DnsSeedResolver {
.into_iter()
.filter_map(|txt| {
txt.parse()
.inspect(|err| {
.inspect_err(|err| {
warn!(
target: LOG_TARGET,
"Failed to parse DNS seed peer string: {}. Error: {}", txt, err
Expand Down Expand Up @@ -124,15 +124,13 @@ impl FromStr for SeedPeer {
type Err = anyhow::Error;

fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut parts = s.split("::").map(|s| s.trim());
let public_key = parts
.next()
.and_then(|s| UncompressedCommsPublicKey::from_hex(s).ok())
let (part_a, part_b) = s
.split_once("::")
.ok_or_else(|| anyhow!("Invalid seed peer string, missing '::' delimiter"))?;
let public_key = UncompressedCommsPublicKey::from_hex(part_a)
.ok()
.ok_or_else(|| anyhow!("Invalid public key string"))?;
let addresses = parts.map(Multiaddr::from_str).collect::<Result<Vec<_>, _>>()?;
if addresses.is_empty() || addresses.iter().any(|a| a.is_empty()) {
return Err(anyhow!("Empty or invalid address in seed peer string"));
}
let addresses = vec![Multiaddr::from_str(part_b).map_err(|e| anyhow!("Invalid address string:{}", e))?];
Ok(SeedPeer {
public_key: CommsPublicKey::new_from_pk(public_key),
addresses,
Expand Down Expand Up @@ -195,19 +193,6 @@ mod test {
assert_eq!(seed.addresses[0].to_string(), "/ip4/127.0.0.1/tcp/8000");
}

#[test]
fn it_parses_mulitple_addresses() {
let sample = "06e98e9c5eb52bd504836edec1878eccf12eb9f26a5fe5ec0e279423156e657a::/ip4/127.0.0.1/tcp/8000::/\
onion3/bsmuof2cn4y2ysz253gzsvg3s72fcgh4f3qcm3hdlxdtcwe6al2dicyd:1234";

let seed = SeedPeer::from_str(sample).unwrap();
assert_eq!(
seed.public_key.to_hex(),
"06e98e9c5eb52bd504836edec1878eccf12eb9f26a5fe5ec0e279423156e657a"
);
assert_eq!(seed.addresses.len(), 2);
}

#[test]
fn it_errors_if_empty_or_blank() {
SeedPeer::from_str("").unwrap_err();
Expand All @@ -219,14 +204,6 @@ mod test {
SeedPeer::from_str("nonsensical::garbage").unwrap_err();
}

#[test]
fn it_errors_if_trailing_delim() {
let sample = "06e98e9c5eb52bd504836edec1878eccf12eb9f26a5fe5ec0e279423156e657a::/ip4/127.0.0.1/tcp/8000::";
SeedPeer::from_str(sample).unwrap_err();
let sample = "06e98e9c5eb52bd504836edec1878eccf12eb9f26a5fe5ec0e279423156e657a::";
SeedPeer::from_str(sample).unwrap_err();
}

#[test]
fn it_errors_invalid_public_key() {
let sample = "16e98e9c5eb52bd504836edec1878eccf12eb9f26a5fe5ec0e279423156e657a::/ip4/127.0.0.1/tcp/8000";
Expand All @@ -246,8 +223,8 @@ mod test {
#[tokio::test]
#[ignore = "Useful for developer testing but will fail unless the DNS has TXT records setup correctly."]
async fn it_returns_seeds_from_real_address() {
let mut resolver = DnsSeedResolver::connect(DnsNameServer::System).await.unwrap();
let seeds = resolver.resolve("seeds.esmeralda.tari.com").await.unwrap();
let mut resolver = DnsSeedResolver::connect(DnsNameServer::System).unwrap();
let seeds = resolver.resolve("seeds.nextnet.tari.com").await.unwrap();
println!("{:?}", seeds);
assert!(!seeds.is_empty());
}
Expand Down
16 changes: 13 additions & 3 deletions common/config/presets/b_peer_seeds.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,16 @@
# DNS seeds hosts - DNS TXT records are queried from these hosts and the resulting peers added to the comms peer list.
# (Default: peer_seeds = [])
dns_seeds = ["seeds.nextnet.tari.com"]
# Custom specified peer seed nodes (Default: peer_seeds = [])
#peer_seeds = ["a062ae2345b0db0df9fb1504b99511e23d98f8513f9b5503efcc6dad8eca7e47::/ip4/54.77.66.39/tcp/18189"]
peer_seeds = [
"18a07e52ef6616d74a31b4c26d34fb7debdbe6d8b0261f6fff67e5801da8ee5d::/onion3/6huatttx2xvnhg7pui22rqweegmyjp7mr6wkppqjwrcqgzqqnv2okfad:18141",
"928b89d44afcebd5ae305113409f0d0c6237278a6451e19e270245358d945b1e::/ip6/2001:41d0:701:1000::4716/tcp/18189",
"0c42312a2bdd7d17b12047b515d36c982e56573cc5e9d6d19cf29210624ec02b::/ip4/148.113.143.145/tcp/18189",
"0c42312a2bdd7d17b12047b515d36c982e56573cc5e9d6d19cf29210624ec02b::/onion3/on77pvjtgvpsyrfzzmusvtdknuy6l44av5ifxaeo2hvaarcanccta4qd:18141",
"0e99cc89439546d3a59d02fb498d6e1bd7dbeee17c2cecea1966244b8f83b77d::/onion3/kjwvw4tg4pvgqrzaks7atnf7kjesteoxt5wpjd4b6lusezkqxgiktoqd:18141",
"928b89d44afcebd5ae305113409f0d0c6237278a6451e19e270245358d945b1e::/ip4/51.75.94.140/tcp/18189",
"463cb7d9238a30901b88370dac817da738a722f5fb0d340ab4eb52b747f3e149::/onion3/qugw4hf5zsopghjlrbcm6crggzbozp4tfbu4duadrf55nyb5dijm6pqd:18141",
"0e99cc89439546d3a59d02fb498d6e1bd7dbeee17c2cecea1966244b8f83b77d::/ip4/57.128.24.58/tcp/18189",
]

[stagenet.p2p.seeds]
# DNS seeds hosts - DNS TXT records are queried from these hosts and the resulting peers added to the comms peer list.
Expand Down Expand Up @@ -56,4 +64,6 @@ dns_seeds = ["seeds.igor.tari.com"]
# (Default: peer_seeds = [])
dns_seeds = ["seeds.mainnet.tari.com"]
# Custom specified peer seed nodes (Default: peer_seeds = [])
peer_seeds = ["a062ae2345b0db0df9fb1504b99511e23d98f8513f9b5503efcc6dad8eca7e47::/ip4/54.77.66.39/tcp/18189"]
peer_seeds = [
"a062ae2345b0db0df9fb1504b99511e23d98f8513f9b5503efcc6dad8eca7e47::/ip4/54.77.66.39/tcp/18189",
] # Custom specified peer seed nodes (Default: peer_seeds = [])
Loading