183 lines
5.3 KiB
Rust
183 lines
5.3 KiB
Rust
//! Fixed test vectors for the address book.
|
|
|
|
use std::time::Instant;
|
|
|
|
use chrono::Utc;
|
|
use tracing::Span;
|
|
|
|
use zebra_chain::{
|
|
parameters::Network::*,
|
|
serialization::{DateTime32, Duration32},
|
|
};
|
|
|
|
use crate::{
|
|
constants::{DEFAULT_MAX_CONNS_PER_IP, MAX_ADDRS_IN_ADDRESS_BOOK},
|
|
meta_addr::MetaAddr,
|
|
protocol::external::types::PeerServices,
|
|
AddressBook,
|
|
};
|
|
|
|
/// Make sure an empty address book is actually empty.
|
|
#[test]
|
|
fn address_book_empty() {
|
|
let address_book = AddressBook::new(
|
|
"0.0.0.0:0".parse().unwrap(),
|
|
&Mainnet,
|
|
DEFAULT_MAX_CONNS_PER_IP,
|
|
Span::current(),
|
|
);
|
|
|
|
assert_eq!(
|
|
address_book
|
|
.reconnection_peers(Instant::now(), Utc::now())
|
|
.next(),
|
|
None
|
|
);
|
|
assert_eq!(address_book.len(), 0);
|
|
}
|
|
|
|
/// Make sure peers are attempted in priority order.
|
|
#[test]
|
|
fn address_book_peer_order() {
|
|
let addr1 = "127.0.0.1:1".parse().unwrap();
|
|
let addr2 = "127.0.0.2:2".parse().unwrap();
|
|
|
|
let mut meta_addr1 =
|
|
MetaAddr::new_gossiped_meta_addr(addr1, PeerServices::NODE_NETWORK, DateTime32::MIN);
|
|
let mut meta_addr2 = MetaAddr::new_gossiped_meta_addr(
|
|
addr2,
|
|
PeerServices::NODE_NETWORK,
|
|
DateTime32::MIN.saturating_add(Duration32::from_seconds(1)),
|
|
);
|
|
|
|
// Regardless of the order of insertion, the most recent address should be chosen first
|
|
let addrs = vec![meta_addr1, meta_addr2];
|
|
let address_book = AddressBook::new_with_addrs(
|
|
"0.0.0.0:0".parse().unwrap(),
|
|
&Mainnet,
|
|
DEFAULT_MAX_CONNS_PER_IP,
|
|
MAX_ADDRS_IN_ADDRESS_BOOK,
|
|
Span::current(),
|
|
addrs,
|
|
);
|
|
assert_eq!(
|
|
address_book
|
|
.reconnection_peers(Instant::now(), Utc::now())
|
|
.next(),
|
|
Some(meta_addr2),
|
|
);
|
|
|
|
// Reverse the order, check that we get the same result
|
|
let addrs = vec![meta_addr2, meta_addr1];
|
|
let address_book = AddressBook::new_with_addrs(
|
|
"0.0.0.0:0".parse().unwrap(),
|
|
&Mainnet,
|
|
DEFAULT_MAX_CONNS_PER_IP,
|
|
MAX_ADDRS_IN_ADDRESS_BOOK,
|
|
Span::current(),
|
|
addrs,
|
|
);
|
|
assert_eq!(
|
|
address_book
|
|
.reconnection_peers(Instant::now(), Utc::now())
|
|
.next(),
|
|
Some(meta_addr2),
|
|
);
|
|
|
|
// Now check that the order depends on the time, not the address
|
|
meta_addr1.addr = addr2;
|
|
meta_addr2.addr = addr1;
|
|
|
|
let addrs = vec![meta_addr1, meta_addr2];
|
|
let address_book = AddressBook::new_with_addrs(
|
|
"0.0.0.0:0".parse().unwrap(),
|
|
&Mainnet,
|
|
DEFAULT_MAX_CONNS_PER_IP,
|
|
MAX_ADDRS_IN_ADDRESS_BOOK,
|
|
Span::current(),
|
|
addrs,
|
|
);
|
|
assert_eq!(
|
|
address_book
|
|
.reconnection_peers(Instant::now(), Utc::now())
|
|
.next(),
|
|
Some(meta_addr2),
|
|
);
|
|
|
|
// Reverse the order, check that we get the same result
|
|
let addrs = vec![meta_addr2, meta_addr1];
|
|
let address_book = AddressBook::new_with_addrs(
|
|
"0.0.0.0:0".parse().unwrap(),
|
|
&Mainnet,
|
|
DEFAULT_MAX_CONNS_PER_IP,
|
|
MAX_ADDRS_IN_ADDRESS_BOOK,
|
|
Span::current(),
|
|
addrs,
|
|
);
|
|
assert_eq!(
|
|
address_book
|
|
.reconnection_peers(Instant::now(), Utc::now())
|
|
.next(),
|
|
Some(meta_addr2),
|
|
);
|
|
}
|
|
|
|
/// Check that `reconnection_peers` skips addresses with IPs for which
|
|
/// Zebra already has recently updated outbound peers.
|
|
#[test]
|
|
fn reconnection_peers_skips_recently_updated_ip() {
|
|
// tests that reconnection_peers() skips addresses where there's a connection at that IP with a recent:
|
|
// - `last_response`
|
|
test_reconnection_peers_skips_recently_updated_ip(true, MetaAddr::new_responded);
|
|
|
|
// tests that reconnection_peers() *does not* skip addresses where there's a connection at that IP with a recent:
|
|
// - `last_attempt`
|
|
test_reconnection_peers_skips_recently_updated_ip(false, MetaAddr::new_reconnect);
|
|
// - `last_failure`
|
|
test_reconnection_peers_skips_recently_updated_ip(false, |addr| {
|
|
MetaAddr::new_errored(addr, PeerServices::NODE_NETWORK)
|
|
});
|
|
}
|
|
|
|
fn test_reconnection_peers_skips_recently_updated_ip<
|
|
M: Fn(crate::PeerSocketAddr) -> crate::meta_addr::MetaAddrChange,
|
|
>(
|
|
should_skip_ip: bool,
|
|
make_meta_addr_change: M,
|
|
) {
|
|
let addr1 = "127.0.0.1:1".parse().unwrap();
|
|
let addr2 = "127.0.0.1:2".parse().unwrap();
|
|
|
|
let meta_addr1 = make_meta_addr_change(addr1).into_new_meta_addr(
|
|
Instant::now(),
|
|
Utc::now().try_into().expect("will succeed until 2038"),
|
|
);
|
|
let meta_addr2 = MetaAddr::new_gossiped_meta_addr(
|
|
addr2,
|
|
PeerServices::NODE_NETWORK,
|
|
DateTime32::MIN.saturating_add(Duration32::from_seconds(1)),
|
|
);
|
|
|
|
// The second address should be skipped because the first address has a
|
|
// recent `last_response` time and the two addresses have the same IP.
|
|
let addrs = vec![meta_addr1, meta_addr2];
|
|
let address_book = AddressBook::new_with_addrs(
|
|
"0.0.0.0:0".parse().unwrap(),
|
|
&Mainnet,
|
|
DEFAULT_MAX_CONNS_PER_IP,
|
|
MAX_ADDRS_IN_ADDRESS_BOOK,
|
|
Span::current(),
|
|
addrs,
|
|
);
|
|
|
|
let next_reconnection_peer = address_book
|
|
.reconnection_peers(Instant::now(), Utc::now())
|
|
.next();
|
|
|
|
if should_skip_ip {
|
|
assert_eq!(next_reconnection_peer, None,);
|
|
} else {
|
|
assert_ne!(next_reconnection_peer, None,);
|
|
}
|
|
}
|