use iroh::EndpointId;
#[derive(Debug, PartialEq, Eq)]
pub enum Keep {
Held,
Arriving,
}
pub fn resolve(
ours: &EndpointId,
theirs: &EndpointId,
held_live: bool,
held_dialed_by_us: bool,
arriving_dialed_by_us: bool,
) -> Keep {
if !held_live {
return Keep::Arriving;
}
if held_dialed_by_us == arriving_dialed_by_us {
return Keep::Arriving;
}
let we_are_lower = ours.as_bytes() < theirs.as_bytes();
let lower_key_opened_held = we_are_lower == held_dialed_by_us;
if lower_key_opened_held {
Keep::Held
} else {
Keep::Arriving
}
}
#[cfg(test)]
mod tests {
use super::*;
use iroh::SecretKey;
fn key(n: u8) -> EndpointId {
SecretKey::from_bytes(&[n; 32]).public()
}
fn pair() -> (EndpointId, EndpointId) {
let (a, b) = (key(1), key(2));
if a.as_bytes() < b.as_bytes() {
(a, b)
} else {
(b, a)
}
}
#[test]
fn a_reconnect_from_the_dialer_is_not_a_race() {
let (low, high) = pair();
assert_eq!(resolve(&low, &high, true, false, false), Keep::Arriving);
assert_eq!(resolve(&high, &low, true, false, false), Keep::Arriving);
}
#[test]
fn a_closed_slot_takes_arriving() {
let (low, high) = pair();
assert_eq!(resolve(&low, &high, false, true, false), Keep::Arriving);
assert_eq!(resolve(&high, &low, false, true, true), Keep::Arriving);
}
#[test]
fn the_lower_key_keeps_its_own_dial() {
let (low, high) = pair();
assert_eq!(resolve(&low, &high, true, true, false), Keep::Held);
}
#[test]
fn the_higher_key_takes_theirs() {
let (low, high) = pair();
assert_eq!(resolve(&high, &low, true, true, false), Keep::Arriving);
}
#[test]
fn both_ends_keep_the_lower_keys_dial() {
let (low, high) = pair();
assert_eq!(resolve(&low, &high, true, true, false), Keep::Held);
assert_eq!(resolve(&high, &low, true, true, false), Keep::Arriving);
}
#[test]
fn inbound_then_our_dial_still_keeps_the_lower_keys_dial() {
let (low, high) = pair();
assert_eq!(resolve(&low, &high, true, false, true), Keep::Arriving);
assert_eq!(resolve(&high, &low, true, false, true), Keep::Held);
}
}