-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
# Description This PR makes the following changes: - [x] Add AutoNAT behavior to probe for public listen addresses - [x] Update `external_addresses` with reported public addresses - [x] Add `StatusChangedAutonat` notification - [x] Add `NatStatus` extension trait with `to_tuple` helper - [x] Confirm addresses observed on identify events with an AutoNAT probe - [x] Minor refactoring in settings When the `NatStatus` changes to public, the reported address is added to `external_addresses`. If a previously reported address transitions from public to private or unknown, the address is removed from `external_addresses`. Note that `announce_addresses` are always kept in `external_addresses` and will not be removed by changes to `NatStatus`. ## Link to issue Implements #398 ## Type of change - [x] New feature (non-breaking change that adds functionality) - [x] Refactor (non-breaking change that updates existing functionality) - [x] This change requires a documentation update ## Test plan (required) This PR adds the following tests: - [x] AutoNAT confirms a reachable address - [x] `StatusAutoNat` notification to and from IPLD bytes and JSON tests - [x] Test `NatStatus` `to_tuple` returns expected tuples
- Loading branch information
Showing
14 changed files
with
553 additions
and
21 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
89 changes: 89 additions & 0 deletions
89
homestar-runtime/src/event_handler/notification/network/autonat.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
//! Notification types for [swarm] autonat events. | ||
//! | ||
//! [swarm]: libp2p::swarm::Swarm | ||
|
||
use crate::libp2p::nat_status::NatStatusExt; | ||
use anyhow::anyhow; | ||
use chrono::prelude::Utc; | ||
use derive_getters::Getters; | ||
use homestar_invocation::ipld::DagJson; | ||
use libipld::{serde::from_ipld, Ipld}; | ||
use libp2p::autonat::NatStatus; | ||
use schemars::JsonSchema; | ||
use std::collections::BTreeMap; | ||
|
||
const ADDRESS_KEY: &str = "address"; | ||
const STATUS_KEY: &str = "status"; | ||
const TIMESTAMP_KEY: &str = "timestamp"; | ||
|
||
#[derive(Debug, Clone, Getters, JsonSchema)] | ||
#[schemars(rename = "status_changed_autonat")] | ||
pub struct StatusChangedAutonat { | ||
timestamp: i64, | ||
status: String, | ||
address: Option<String>, | ||
} | ||
|
||
impl StatusChangedAutonat { | ||
pub(crate) fn new(status: NatStatus) -> StatusChangedAutonat { | ||
let (status, address) = status.to_tuple(); | ||
|
||
StatusChangedAutonat { | ||
timestamp: Utc::now().timestamp_millis(), | ||
status: status.to_string(), | ||
address: address.map(|a| a.to_string()), | ||
} | ||
} | ||
} | ||
|
||
impl DagJson for StatusChangedAutonat {} | ||
|
||
impl From<StatusChangedAutonat> for Ipld { | ||
fn from(notification: StatusChangedAutonat) -> Self { | ||
Ipld::Map(BTreeMap::from([ | ||
(TIMESTAMP_KEY.into(), notification.timestamp.into()), | ||
(STATUS_KEY.into(), notification.status.into()), | ||
( | ||
ADDRESS_KEY.into(), | ||
notification | ||
.address | ||
.map(|peer_id| peer_id.into()) | ||
.unwrap_or(Ipld::Null), | ||
), | ||
])) | ||
} | ||
} | ||
|
||
impl TryFrom<Ipld> for StatusChangedAutonat { | ||
type Error = anyhow::Error; | ||
|
||
fn try_from(ipld: Ipld) -> Result<Self, Self::Error> { | ||
let map = from_ipld::<BTreeMap<String, Ipld>>(ipld)?; | ||
|
||
let timestamp = from_ipld( | ||
map.get(TIMESTAMP_KEY) | ||
.ok_or_else(|| anyhow!("missing {TIMESTAMP_KEY}"))? | ||
.to_owned(), | ||
)?; | ||
|
||
let status = from_ipld( | ||
map.get(STATUS_KEY) | ||
.ok_or_else(|| anyhow!("missing {STATUS_KEY}"))? | ||
.to_owned(), | ||
)?; | ||
|
||
let address = map | ||
.get(ADDRESS_KEY) | ||
.and_then(|ipld| match ipld { | ||
Ipld::Null => None, | ||
ipld => Some(ipld), | ||
}) | ||
.and_then(|ipld| from_ipld(ipld.to_owned()).ok()); | ||
|
||
Ok(StatusChangedAutonat { | ||
timestamp, | ||
status, | ||
address, | ||
}) | ||
} | ||
} |
Oops, something went wrong.