summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/simtest/identity.rs10
-rw-r--r--src/transport/identity.rs45
2 files changed, 41 insertions, 14 deletions
diff --git a/src/simtest/identity.rs b/src/simtest/identity.rs
index 6f468a3..68d81c4 100644
--- a/src/simtest/identity.rs
+++ b/src/simtest/identity.rs
@@ -202,13 +202,19 @@ async fn nodes_over_libp2p() {
}
};
let a_peer = key("a").public().to_peer_id();
- let seed = format!("libp2p:{}", address("a").with_p2p(a_peer).unwrap());
+ // With the peer ID, with the scheme but without the peer ID, and bare.
+ let seeds = [
+ format!("libp2p:{}", address("a").with_p2p(a_peer).unwrap()),
+ format!("libp2p:{}", address("a")),
+ address("a").to_string(),
+ ];
let sim = Sim::with_identity(56);
let a = sim.start_with("a", &[], Start::Genesis, on_libp2p("a"));
let others: Vec<AppState> = ["b", "c", "d"]
.into_iter()
- .map(|id| sim.start_with(id, &[seed.as_str()], Start::Join, on_libp2p(id)))
+ .zip(&seeds)
+ .map(|(id, seed)| sim.start_with(id, &[seed.as_str()], Start::Join, on_libp2p(id)))
.collect();
let mut all: Vec<&AppState> = vec![&a];
all.extend(others.iter());
diff --git a/src/transport/identity.rs b/src/transport/identity.rs
index abedd35..bfd9432 100644
--- a/src/transport/identity.rs
+++ b/src/transport/identity.rs
@@ -30,7 +30,7 @@ use std::collections::HashMap;
use std::sync::{Arc, Mutex, MutexGuard};
use std::time::Duration;
-use anyhow::{Result, anyhow, bail};
+use anyhow::{Context, Result, anyhow, bail};
use async_trait::async_trait;
use tokio::sync::{mpsc, oneshot};
use tokio::time::Instant;
@@ -514,22 +514,43 @@ impl Transport for IdentityTransport {
}
bail!("a node ID alone doesn't say where that node is; give its address");
}
+ // With a scheme of ours, only that transport resolves the rest (an address the
+ // transport can't read as an identity, e.g. a libp2p multiaddr without its peer
+ // ID, still resolves); without one, the first transport that can.
+ let scheme_and_rest = seed.split_once(':').and_then(|(scheme, rest)| {
+ let link = self
+ .shared
+ .links
+ .iter()
+ .find(|link| link.scheme == scheme)?;
+ Some((link, rest))
+ });
let address = match self.shared.canonical(seed) {
Some(address) => address,
- None => {
- let mut failures = Vec::new();
- let mut resolved = None;
- for link in &self.shared.links {
- match link.inner.resolve_seed(seed).await {
- Ok(target) => {
- resolved = Some(link.address(&target));
- break;
+ None => match scheme_and_rest {
+ Some((link, rest)) => {
+ let target = link
+ .inner
+ .resolve_seed(rest)
+ .await
+ .with_context(|| format!("{}: {seed}", link.scheme))?;
+ link.address(&target)
+ }
+ None => {
+ let mut failures = Vec::new();
+ let mut resolved = None;
+ for link in &self.shared.links {
+ match link.inner.resolve_seed(seed).await {
+ Ok(target) => {
+ resolved = Some(link.address(&target));
+ break;
+ }
+ Err(error) => failures.push(format!("{}: {error:#}", link.scheme)),
}
- Err(error) => failures.push(format!("{}: {error:#}", link.scheme)),
}
+ resolved.ok_or_else(|| anyhow!("{}", failures.join("; ")))?
}
- resolved.ok_or_else(|| anyhow!("{}", failures.join("; ")))?
- }
+ },
};
if self.shared.is_own(&address) {
bail!("{seed} is this node");