Skip to content

Commit

Permalink
chore: butterflynet reset
Browse files Browse the repository at this point in the history
  • Loading branch information
hanabi1224 committed Oct 18, 2024
1 parent fee60ee commit dacb202
Show file tree
Hide file tree
Showing 7 changed files with 112 additions and 18 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ gethostname = "0.5"
git-version = "0.3"
group = "0.13"
hex = { version = "0.4", features = ["serde"] }
hickory-resolver = { version = "0.24", default-features = false, features = ["system-config"] }
http = "1"
human-repr = "1"
human_bytes = "0.4"
Expand Down
3 changes: 1 addition & 2 deletions build/bootstrap/butterflynet
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
/dns4/bootstrap-0.butterfly.fildev.network/tcp/1347/p2p/12D3KooWHSojyKBpM7phx5jj9myYpmbVQ9n1MjQZmpSa7NL2RxwX
/dns4/bootstrap-1.butterfly.fildev.network/tcp/1347/p2p/12D3KooWKzxVysUt8FNEihBhWoN86BYnXh22GpEoYRKUAhXJtApt
/dnsaddr/bootstrap.butterfly.fildev.network
5 changes: 3 additions & 2 deletions src/libp2p/behaviour.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ impl Recorder<ForestBehaviourEvent> for Metrics {
}

impl ForestBehaviour {
pub fn new(
pub async fn new(
local_key: &Keypair,
config: &Libp2pConfig,
network_name: &str,
Expand Down Expand Up @@ -122,7 +122,8 @@ impl ForestBehaviour {
let discovery = DiscoveryConfig::new(local_key.public(), network_name)
.with_mdns(config.mdns)
.with_kademlia(config.kademlia)
.with_user_defined(config.bootstrap_peers.clone())?
.with_user_defined(config.bootstrap_peers.clone())
.await?
.target_peer_count(config.target_peer_count as u64)
.finish()?;

Expand Down
108 changes: 100 additions & 8 deletions src/libp2p/discovery.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
// Copyright 2019-2024 ChainSafe Systems
// SPDX-License-Identifier: Apache-2.0, MIT

use core::str;
use std::{
cmp,
collections::VecDeque,
io,
task::{Context, Poll},
time::Duration,
};
Expand Down Expand Up @@ -94,12 +96,20 @@ impl<'a> DiscoveryConfig<'a> {
}

/// Set custom nodes which never expire, e.g. bootstrap or reserved nodes.
pub fn with_user_defined(
pub async fn with_user_defined(
mut self,
user_defined: impl IntoIterator<Item = Multiaddr>,
) -> anyhow::Result<Self> {
for mut addr in user_defined.into_iter() {
if let Some(Protocol::P2p(peer_id)) = addr.pop() {
if let Some((_, Protocol::Dnsaddr(addr))) = addr
.iter()
.enumerate()
.find(|(_, p)| matches!(p, Protocol::Dnsaddr(_)))
{
for pair in resolve_libp2p_dnsaddr(&addr).await? {
self.user_defined.push(pair)
}
} else if let Some(Protocol::P2p(peer_id)) = addr.pop() {
self.user_defined.push((peer_id, addr))
} else {
anyhow::bail!("Failed to parse peer id from {addr}")
Expand Down Expand Up @@ -527,30 +537,112 @@ impl NetworkBehaviour for DiscoveryBehaviour {
}
}

async fn resolve_libp2p_dnsaddr(name: &str) -> anyhow::Result<Vec<(PeerId, Multiaddr)>> {
use hickory_resolver::{system_conf, TokioAsyncResolver};

let (cfg, opts) = system_conf::read_system_conf()?;
let resolver = TokioAsyncResolver::tokio(cfg, opts);

let name = ["_dnsaddr.", name].concat();
let txts = resolver.txt_lookup(name).await?;

let mut pairs = vec![];
for txt in txts {
if let Some(chars) = txt.txt_data().first() {
match parse_dnsaddr_txt(chars) {
Err(e) => {
// Skip over seemingly invalid entries.
tracing::debug!("Invalid TXT record: {:?}", e);
}
Ok(mut addr) => {
if let Some(Protocol::P2p(peer_id)) = addr.pop() {
pairs.push((peer_id, addr))
} else {
tracing::debug!("Failed to parse peer id from {addr}")
}
}
}
}
}
Ok(pairs)
}

/// Parses a `<character-string>` of a `dnsaddr` `TXT` record.
fn parse_dnsaddr_txt(txt: &[u8]) -> io::Result<Multiaddr> {
let s = str::from_utf8(txt).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
match s.strip_prefix("dnsaddr=") {
None => Err(io::Error::new(
io::ErrorKind::InvalidData,
"Missing `dnsaddr=` prefix.",
)),
Some(a) => Ok(
Multiaddr::try_from(a).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?
),
}
}

#[cfg(test)]
mod tests {
use libp2p::{identity::Keypair, swarm::SwarmEvent, Swarm};
use super::*;
use libp2p::{
core::transport::MemoryTransport, identity::Keypair, swarm::SwarmEvent, Swarm,
Transport as _,
};
use libp2p_swarm_test::SwarmExt as _;
use std::str::FromStr as _;

use super::*;
#[tokio::test]
async fn resolve_libp2p_dnsaddr_test() {
let addr = Multiaddr::from_str("/dnsaddr/bootstrap.butterfly.fildev.network").unwrap();
let p = addr
.iter()
.find(|p| matches!(p, Protocol::Dnsaddr(_)))
.unwrap();
if let Protocol::Dnsaddr(name) = p {
let pairs = resolve_libp2p_dnsaddr(&name).await.unwrap();
assert!(!pairs.is_empty());
} else {
panic!("No dnsaddr protocol found");
}
}

#[tokio::test]
async fn kademlia_test() {
fn new_discovery(
async fn new_discovery(
keypair: Keypair,
seed_peers: impl IntoIterator<Item = Multiaddr>,
) -> DiscoveryBehaviour {
DiscoveryConfig::new(keypair.public(), "calibnet")
.with_mdns(false)
.with_kademlia(true)
.with_user_defined(seed_peers)
.await
.unwrap()
.target_peer_count(128)
.finish()
.unwrap()
}

let mut b = Swarm::new_ephemeral(|k| new_discovery(k, vec![]));
async fn new_ephemeral(seed_peers: Vec<Multiaddr>) -> Swarm<DiscoveryBehaviour> {
let identity = Keypair::generate_ed25519();
let peer_id = PeerId::from(identity.public());
let transport = MemoryTransport::default()
.or_transport(libp2p::tcp::tokio::Transport::default())
.upgrade(libp2p::core::upgrade::Version::V1)
.authenticate(libp2p::noise::Config::new(&identity).unwrap())
.multiplex(libp2p::yamux::Config::default())
.timeout(Duration::from_secs(20))
.boxed();
Swarm::new(
transport,
new_discovery(identity, seed_peers).await,
peer_id,
libp2p::swarm::Config::with_tokio_executor()
.with_idle_connection_timeout(Duration::from_secs(5)),
)
}

let mut b = new_ephemeral(vec![]).await;
b.listen().with_memory_addr_external().await;
let b_peer_id = *b.local_peer_id();
let b_addresses: Vec<_> = b
Expand All @@ -562,7 +654,7 @@ mod tests {
})
.collect();

let mut c = Swarm::new_ephemeral(|k| new_discovery(k, vec![]));
let mut c = new_ephemeral(vec![]).await;
c.listen().with_memory_addr_external().await;
let c_peer_id = *c.local_peer_id();
if let Some(c_kad) = c.behaviour_mut().discovery.kademlia.as_mut() {
Expand All @@ -571,7 +663,7 @@ mod tests {
}
}

let mut a = Swarm::new_ephemeral(|k| new_discovery(k, b_addresses));
let mut a = new_ephemeral(b_addresses).await;

// Bootstrap `a` and `c`
a.behaviour_mut().bootstrap().unwrap();
Expand Down
2 changes: 1 addition & 1 deletion src/libp2p/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ where
genesis_cid: Cid,
) -> anyhow::Result<Self> {
let behaviour =
ForestBehaviour::new(&net_keypair, &config, network_name, peer_manager.clone())?;
ForestBehaviour::new(&net_keypair, &config, network_name, peer_manager.clone()).await?;
let mut swarm = SwarmBuilder::with_existing_identity(net_keypair)
.with_tokio()
.with_tcp(
Expand Down
10 changes: 5 additions & 5 deletions src/networks/butterflynet/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,22 +40,22 @@ pub async fn fetch_genesis<DB: SettingsStore>(db: &DB) -> anyhow::Result<Vec<u8>

/// Genesis CID
pub static GENESIS_CID: Lazy<Cid> = Lazy::new(|| {
Cid::from_str("bafy2bzacecqfnzdjcmjisrj6qvdaohweaxdvgwfej2sb4eklw3ksatbg7xj4k").unwrap()
Cid::from_str("bafy2bzacedgcrrsfkdi5dcdfuj6b6zsuenzd3bzeeirvffhoiecddco4ahoni").unwrap()
});

/// Compressed genesis file. It is compressed with zstd and cuts the download size by 80% (from 10 MB to 2 MB).
static GENESIS_URL: Lazy<Url> = Lazy::new(|| {
"https://forest-snapshots.fra1.cdn.digitaloceanspaces.com/genesis/butterflynet.car.zst"
"https://forest-snapshots.fra1.cdn.digitaloceanspaces.com/genesis/butterflynet-bafy2bzacedgcrrsfkdi5dcdfuj6b6zsuenzd3bzeeirvffhoiecddco4ahoni.car.zst"
.parse()
.expect("hard-coded URL must parse")
});

/// Alternative URL for the genesis file. This is hosted on the `lotus` repository and is not
/// compressed.
/// The genesis file does not live on the `master` branch, currently on a draft PR.
/// `<https://github.com/filecoin-project/lotus/pull/11458>`
/// The genesis file does not live on the `master` branch, currently on `butterfly/v24` branch.
/// `<https://github.com/filecoin-project/lotus/commit/36e6a639fd8411dd69048c95ac478468f2755b8d>`
static GENESIS_URL_ALT: Lazy<Url> = Lazy::new(|| {
"https://github.com/filecoin-project/lotus/raw/4dfe16f58e55b3bbb87c5ff95fbe80bb41d44b80/build/genesis/butterflynet.car".parse().expect("hard-coded URL must parse")
"https://github.com/filecoin-project/lotus/raw/36e6a639fd8411dd69048c95ac478468f2755b8d/build/genesis/butterflynet.car".parse().expect("hard-coded URL must parse")
});

pub(crate) const MINIMUM_CONSENSUS_POWER: i64 = 2 << 30;
Expand Down

0 comments on commit dacb202

Please sign in to comment.