Skip to content

Commit

Permalink
feat: add downcast_ref support to ConnectionDenied type
Browse files Browse the repository at this point in the history
Prior to this change it was possible to only have a reference to a ConnectionDenied error and not be
able to downcast it to check if the connection-limits produced the error.

See #4018
  • Loading branch information
nathanielc committed Jun 2, 2023
1 parent b73f720 commit f601ee2
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 0 deletions.
51 changes: 51 additions & 0 deletions misc/connection-limits/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,57 @@ mod tests {
quickcheck(prop as fn(_));
}

#[test]
fn max_established_incoming_downcast_ref() {
fn prop(Limit(limit): Limit) {
let mut swarm1 = Swarm::new_ephemeral(|_| {
Behaviour::new(
ConnectionLimits::default().with_max_established_incoming(Some(limit)),
)
});
let mut swarm2 = Swarm::new_ephemeral(|_| {
Behaviour::new(
ConnectionLimits::default().with_max_established_incoming(Some(limit)),
)
});

async_std::task::block_on(async {
let (listen_addr, _) = swarm1.listen().await;

for _ in 0..limit {
swarm2.connect(&mut swarm1).await;
}

swarm2.dial(listen_addr).unwrap();

async_std::task::spawn(swarm2.loop_on_next());

let cause = swarm1
.wait(|event| match event {
SwarmEvent::IncomingConnectionError {
error: ListenError::Denied { cause },
..
} => Some(cause),
_ => None,
})
.await;

assert_eq!(cause.downcast_ref::<Exceeded>().unwrap().limit, limit);
});
}

#[derive(Debug, Clone)]
struct Limit(u32);

impl Arbitrary for Limit {
fn arbitrary(g: &mut Gen) -> Self {
Self(g.gen_range(1..10))
}
}

quickcheck(prop as fn(_));
}

#[derive(libp2p_swarm_derive::NetworkBehaviour)]
#[behaviour(prelude = "libp2p_swarm::derive_prelude")]
struct Behaviour {
Expand Down
8 changes: 8 additions & 0 deletions swarm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1710,6 +1710,14 @@ impl ConnectionDenied {

Ok(*inner)
}

/// Attempt to downcast to a particular reason for why the connection was denied.
pub fn downcast_ref<E>(&self) -> Option<&E>
where
E: error::Error + Send + Sync + 'static,
{
self.inner.downcast_ref::<E>()
}
}

impl fmt::Display for ConnectionDenied {
Expand Down

0 comments on commit f601ee2

Please sign in to comment.