use super::*;
use crate::discovery::nostr::{BootstrapEvent, NostrDiscovery};
use crate::node::wire::{
EncryptedHeader, FLAG_CE, FLAG_KEY_EPOCH, FLAG_SP, Msg1Header, build_encrypted,
build_established_header, build_msg2,
};
use crate::peer::{ActivePeer, PromotionResult};
use crate::transport::ReceivedPacket;
use crate::transport::udp::UdpTransport;
use crate::transport::{TransportHandle, packet_channel};
use std::sync::Arc;
mod config_capacity_classifiers;
mod connected_udp_lifecycle;
mod endpoint_events;
mod fmp_worker;
mod link_registry_rx;
mod liveness_reconnect;
mod liveness_window;
mod node_lifecycle;
mod path_mtu;
mod peer_runtime_receive;
mod peer_runtime_route;
mod promotion_paths;
mod registries_core;
mod rekey;
mod retry_basics;
mod retry_paths;
mod session_registry;
mod update_peers_core;
mod update_peers_paths;
fn refresh_configured_peer_cache_for_test(node: &mut Node) {
node.configured_peer_send_weights = ConfiguredPeerSendWeights::from_config(&node.config);
}
fn make_test_fmp_session(
local: &Identity,
peer: &Identity,
local_epoch: [u8; 8],
peer_epoch: [u8; 8],
) -> crate::noise::NoiseSession {
make_test_fmp_session_pair(local, peer, local_epoch, peer_epoch).0
}
fn make_test_fmp_session_pair(
local: &Identity,
peer: &Identity,
local_epoch: [u8; 8],
peer_epoch: [u8; 8],
) -> (crate::noise::NoiseSession, crate::noise::NoiseSession) {
let mut initiator =
crate::noise::HandshakeState::new_initiator(local.keypair(), peer.pubkey_full());
let mut responder = crate::noise::HandshakeState::new_responder(peer.keypair());
initiator.set_local_epoch(local_epoch);
responder.set_local_epoch(peer_epoch);
let msg1 = initiator.write_message_1().unwrap();
responder.read_message_1(&msg1).unwrap();
let msg2 = responder.write_message_2().unwrap();
initiator.read_message_2(&msg2).unwrap();
(
initiator.into_session().unwrap(),
responder.into_session().unwrap(),
)
}
fn seal_test_fmp_packet(
sender: &mut crate::noise::NoiseSession,
receiver_idx: SessionIndex,
plaintext: &[u8],
k_bit: bool,
) -> Vec<u8> {
let flags = if k_bit { FLAG_KEY_EPOCH } else { 0 };
let counter = sender.current_send_counter();
let header = build_established_header(receiver_idx, counter, flags, plaintext.len() as u16);
let ciphertext = sender.encrypt_with_aad(plaintext, &header).unwrap();
build_encrypted(&header, &ciphertext)
}
#[allow(clippy::too_many_arguments)]
fn make_active_test_peer(
node: &Node,
peer_full: &Identity,
peer_identity: PeerIdentity,
transport_id: TransportId,
link_id: LinkId,
remote_addr: TransportAddr,
our_index: SessionIndex,
their_index: SessionIndex,
) -> ActivePeer {
let session = make_test_fmp_session(&node.identity, peer_full, [0x01; 8], [0x02; 8]);
ActivePeer::with_session(
peer_identity,
link_id,
1_000,
session,
our_index,
their_index,
transport_id,
remote_addr,
crate::transport::LinkStats::new(),
true,
&node.config.node.mmp,
Some([0x02; 8]),
)
}
fn arm_test_fmp_rekey(peer: &mut ActivePeer, rekey_our_index: SessionIndex) {
let remote = Identity::generate();
let local = Identity::generate();
let handshake =
crate::noise::HandshakeState::new_initiator(local.keypair(), remote.pubkey_full());
peer.set_rekey_state(handshake, rekey_our_index, vec![0xAB; 64], 0);
}
#[cfg(any(target_os = "linux", target_os = "macos"))]
fn make_test_connected_udp_pair(
transport_id: TransportId,
) -> (
Arc<crate::transport::udp::connected_peer::ConnectedPeerSocket>,
crate::transport::udp::peer_drain::PeerRecvDrain,
) {
let peer_udp = std::net::UdpSocket::bind("127.0.0.1:0").expect("bind peer udp");
let peer_socket_addr = peer_udp.local_addr().expect("peer udp local addr");
let socket = Arc::new(
crate::transport::udp::connected_peer::ConnectedPeerSocket::open(
"127.0.0.1:0".parse().unwrap(),
peer_socket_addr,
1 << 20,
1 << 20,
)
.expect("connected peer socket"),
);
let (packet_tx, _packet_rx) = packet_channel(16);
let drain = crate::transport::udp::peer_drain::PeerRecvDrain::spawn(
socket.clone(),
transport_id,
peer_socket_addr,
packet_tx,
None,
)
.expect("connected peer drain");
(socket, drain)
}
async fn make_udp_transport_with_mtu(id: u32, mtu: u16) -> TransportHandle {
let (packet_tx, _packet_rx) = packet_channel(64);
let transport_id = TransportId::new(id);
let mut udp = UdpTransport::new(
transport_id,
Some(format!("udp{}", id)),
crate::config::UdpConfig {
bind_addr: Some("127.0.0.1:0".to_string()),
mtu: Some(mtu),
..Default::default()
},
packet_tx,
);
udp.start_async().await.unwrap();
TransportHandle::Udp(udp)
}
fn npub_for_test() -> String {
Identity::generate().npub()
}
fn peer_identity_for_outbound_refresh_owner(node: &Node) -> (Identity, PeerIdentity) {
loop {
let identity = Identity::generate();
let peer_identity = PeerIdentity::from_pubkey_full(identity.pubkey_full());
if node.identity.node_addr() < peer_identity.node_addr() {
return (identity, peer_identity);
}
}
}
fn peer_identity_for_outbound_refresh_loser(node: &Node) -> (Identity, PeerIdentity) {
loop {
let identity = Identity::generate();
let peer_identity = PeerIdentity::from_pubkey_full(identity.pubkey_full());
if node.identity.node_addr() > peer_identity.node_addr() {
return (identity, peer_identity);
}
}
}
fn auto_connect_peer(npub: String, addr: &str) -> crate::config::PeerConfig {
crate::config::PeerConfig {
npub,
alias: None,
addresses: vec![crate::config::PeerAddress::new("udp", addr)],
connect_policy: crate::config::ConnectPolicy::AutoConnect,
auto_reconnect: true,
discovery_fallback_transit: true,
}
}
fn inject_dummy_peers(node: &mut Node, count: usize) {
for i in 0..count {
let identity = make_peer_identity();
let addr = *identity.node_addr();
let peer = ActivePeer::new(identity, LinkId::new((i + 1) as u64), 0);
node.peers.insert(addr, peer);
}
}