mod util;
use std::time::Duration;
use libp2p_core::Multiaddr;
use libp2p_identity::PeerId;
use libp2p_memory_connection_limits::*;
use libp2p_swarm::{dial_opts::DialOpts, DialError, Swarm};
use libp2p_swarm_test::SwarmExt;
use util::*;
#[tokio::test]
async fn max_bytes() {
const CONNECTION_LIMIT: usize = 20;
let max_allowed_bytes = CONNECTION_LIMIT * 1024 * 1024;
let mut network = Swarm::new_ephemeral_tokio(|_| TestBehaviour {
connection_limits: Behaviour::with_max_bytes(max_allowed_bytes),
mem_consumer: ConsumeMemoryBehaviour1MBPending0Established::default(),
});
let addr: Multiaddr = "/memory/1234".parse().unwrap();
let target = PeerId::random();
network
.dial(
DialOpts::peer_id(target)
.addresses(vec![addr.clone()])
.build(),
)
.expect("Unexpected connection limit.");
let max_allowed_bytes_plus_base_usage =
max_allowed_bytes + memory_stats::memory_stats().unwrap().physical_mem;
network.behaviour_mut().connection_limits =
Behaviour::with_max_bytes(max_allowed_bytes_plus_base_usage);
for _ in 0..CONNECTION_LIMIT {
network
.dial(
DialOpts::peer_id(target)
.condition(libp2p_swarm::dial_opts::PeerCondition::Always)
.addresses(vec![addr.clone()])
.build(),
)
.expect("Unexpected connection limit.");
}
tokio::time::sleep(Duration::from_millis(100)).await;
match network
.dial(
DialOpts::peer_id(target)
.condition(libp2p_swarm::dial_opts::PeerCondition::Always)
.addresses(vec![addr])
.build(),
)
.expect_err("Unexpected dialing success.")
{
DialError::Denied { cause } => {
let exceeded = cause
.downcast::<MemoryUsageLimitExceeded>()
.expect("connection denied because of limit");
assert_eq!(
exceeded.max_allowed_bytes(),
max_allowed_bytes_plus_base_usage
);
assert!(exceeded.process_physical_memory_bytes() >= exceeded.max_allowed_bytes());
}
e => panic!("Unexpected error: {e:?}"),
}
}