use std::net::{IpAddr, Ipv4Addr, SocketAddr};
pub fn enabled() -> bool {
std::env::var("BLVM_IBD_SYNTH_WAN")
.map(|v| v == "1" || v.eq_ignore_ascii_case("true"))
.unwrap_or(false)
}
pub fn allow_zero_real_peers() -> bool {
enabled()
|| std::env::var("BLVM_IBD_ALLOW_ZERO_PEERS")
.map(|v| v == "1" || v.eq_ignore_ascii_case("true"))
.unwrap_or(false)
}
pub fn body_tip_override() -> Option<u64> {
if !enabled() {
return None;
}
std::env::var("BLVM_IBD_SYNTH_WAN_BODY_TIP")
.ok()
.and_then(|s| s.parse().ok())
}
pub fn peer_count() -> usize {
if !enabled() {
return 0;
}
std::env::var("BLVM_IBD_SYNTH_WAN_PEER_COUNT")
.ok()
.and_then(|s| s.parse().ok())
.unwrap_or(4)
.clamp(1, 16)
}
pub fn peer_ids() -> Vec<String> {
if !enabled() {
return Vec::new();
}
(0..peer_count())
.map(|i| {
let octet = (i + 1).min(254);
SocketAddr::new(IpAddr::V4(Ipv4Addr::new(203, 0, 113, octet as u8)), 8333).to_string()
})
.collect()
}
pub fn is_synthetic_peer(peer_id: &str) -> bool {
if !enabled() {
return false;
}
let Ok(addr) = peer_id.parse::<SocketAddr>() else {
return false;
};
matches!(
addr.ip(),
IpAddr::V4(v4) if v4.octets()[0] == 203 && v4.octets()[1] == 0 && v4.octets()[2] == 113
)
}
pub fn getdata_delay_ms() -> u64 {
if !enabled() {
return 0;
}
std::env::var("BLVM_IBD_SYNTH_GETDATA_DELAY_MS")
.ok()
.and_then(|s| s.parse().ok())
.unwrap_or(0)
.min(30_000)
}
pub fn use_fake_download_peers() -> bool {
if !enabled() {
return false;
}
if getdata_delay_ms() > 0 {
return true;
}
if std::env::var("BLVM_IBD_SYNTH_WAN_FORCE_PEERS")
.map(|v| v == "1" || v.eq_ignore_ascii_case("true"))
.unwrap_or(false)
{
return true;
}
peer_count() >= 2
}
pub fn bulk_local_disk_stream() -> bool {
enabled() && !use_fake_download_peers()
}
pub fn effective_wan_body_tip(live_tip: u64) -> u64 {
body_tip_override().unwrap_or(live_tip)
}
#[cfg(test)]
mod tests {
use super::*;
use crate::network::peer_scoring::is_lan_peer;
#[serial_test::serial(ibd)]
#[test]
fn synth_peer_ids_are_non_lan_wan_addrs() {
let _lock = crate::ibd_test_lock::guard();
unsafe { std::env::set_var("BLVM_IBD_SYNTH_WAN", "1") };
unsafe { std::env::set_var("BLVM_IBD_SYNTH_WAN_PEER_COUNT", "3") };
let peers = peer_ids();
assert_eq!(peers.len(), 3);
for p in &peers {
assert!(is_synthetic_peer(p));
let addr: SocketAddr = p.parse().expect("parse");
assert!(!is_lan_peer(&addr));
}
unsafe { std::env::remove_var("BLVM_IBD_SYNTH_WAN") };
unsafe { std::env::remove_var("BLVM_IBD_SYNTH_WAN_PEER_COUNT") };
}
#[serial_test::serial(ibd)]
#[test]
fn bulk_delay_zero_single_peer_uses_local_disk_stream() {
let _lock = crate::ibd_test_lock::guard();
unsafe { std::env::set_var("BLVM_IBD_SYNTH_WAN", "1") };
unsafe { std::env::set_var("BLVM_IBD_SYNTH_WAN_PEER_COUNT", "1") };
unsafe { std::env::remove_var("BLVM_IBD_SYNTH_GETDATA_DELAY_MS") };
unsafe { std::env::remove_var("BLVM_IBD_SYNTH_WAN_FORCE_PEERS") };
assert!(!use_fake_download_peers());
assert!(bulk_local_disk_stream());
unsafe { std::env::set_var("BLVM_IBD_SYNTH_WAN_PEER_COUNT", "4") };
assert!(use_fake_download_peers());
assert!(!bulk_local_disk_stream());
unsafe { std::env::set_var("BLVM_IBD_SYNTH_WAN_PEER_COUNT", "1") };
unsafe { std::env::set_var("BLVM_IBD_SYNTH_WAN_FORCE_PEERS", "1") };
assert!(use_fake_download_peers());
assert!(!bulk_local_disk_stream());
unsafe { std::env::remove_var("BLVM_IBD_SYNTH_WAN") };
unsafe { std::env::remove_var("BLVM_IBD_SYNTH_WAN_PEER_COUNT") };
unsafe { std::env::remove_var("BLVM_IBD_SYNTH_WAN_FORCE_PEERS") };
}
}