const REACTOR_LOCK_KEY_SIGN_BIT: u64 = 1 << 63;
const FNV_OFFSET_BASIS: u64 = 0xcbf2_9ce4_8422_2325;
const FNV_PRIME: u64 = 0x0000_0100_0000_01b3;
fn fnv1a(bytes: &[u8]) -> u64 {
let mut hash = FNV_OFFSET_BASIS;
for byte in bytes {
hash ^= *byte as u64;
hash = hash.wrapping_mul(FNV_PRIME);
}
hash
}
pub fn reactor_lock_key(tenant: Option<&str>, reactor_name: &str) -> i64 {
let mut buf = Vec::with_capacity(reactor_name.len() + 32);
buf.extend_from_slice(b"cloacina.reactor.ownership.v1\0");
match tenant {
Some(t) => {
buf.push(1);
buf.extend_from_slice(&(t.len() as u64).to_be_bytes());
buf.extend_from_slice(t.as_bytes());
}
None => buf.push(0),
}
buf.extend_from_slice(&(reactor_name.len() as u64).to_be_bytes());
buf.extend_from_slice(reactor_name.as_bytes());
(fnv1a(&buf) | REACTOR_LOCK_KEY_SIGN_BIT) as i64
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn same_reactor_in_different_tenants_gets_different_keys() {
let a = reactor_lock_key(Some("tenant_a"), "orders_reactor");
let b = reactor_lock_key(Some("tenant_b"), "orders_reactor");
assert_ne!(
a, b,
"same-named reactors in different tenants must not share a lock key"
);
}
#[test]
fn different_reactors_in_same_tenant_get_different_keys() {
let a = reactor_lock_key(Some("tenant_a"), "orders_reactor");
let b = reactor_lock_key(Some("tenant_a"), "billing_reactor");
assert_ne!(a, b);
}
#[test]
fn keys_are_stable_across_processes() {
assert_eq!(
reactor_lock_key(Some("public"), "orders_reactor"),
reactor_lock_key(Some("public"), "orders_reactor"),
);
assert_eq!(
reactor_lock_key(Some("public"), "orders_reactor"),
-798_654_939_832_276_275,
);
assert_eq!(
reactor_lock_key(None, "orders_reactor"),
-6_219_432_407_812_253_675,
);
}
#[test]
fn none_tenant_is_distinct_from_named_tenant() {
let none_key = reactor_lock_key(None, "r");
assert_ne!(none_key, reactor_lock_key(Some(""), "r"));
assert_ne!(none_key, reactor_lock_key(Some("public"), "r"));
}
#[test]
fn field_boundaries_cannot_be_forged() {
assert_ne!(
reactor_lock_key(Some("a"), "bc"),
reactor_lock_key(Some("ab"), "c"),
);
assert_ne!(
reactor_lock_key(Some("a:b"), "c"),
reactor_lock_key(Some("a"), "b:c"),
);
}
#[test]
fn reactor_keys_never_collide_with_handpicked_subsystem_keys() {
const FLEET_CONTROL_LOCK_KEY: i64 = 8_110_127;
for name in ["a", "orders_reactor", "", "x".repeat(500).as_str()] {
for tenant in [None, Some("public"), Some("tenant_a")] {
let key = reactor_lock_key(tenant, name);
assert!(
key < 0,
"reactor key must be negative to stay disjoint from small positive subsystem keys, got {key}"
);
assert_ne!(key, FLEET_CONTROL_LOCK_KEY);
}
}
}
#[test]
fn no_collisions_across_a_realistic_population() {
let mut keys = std::collections::HashSet::new();
for t in 0..200 {
for r in 0..50 {
let tenant = format!("tenant_{t}");
let reactor = format!("reactor_{r}");
assert!(
keys.insert(reactor_lock_key(Some(&tenant), &reactor)),
"collision at tenant_{t}/reactor_{r}"
);
}
}
assert_eq!(keys.len(), 200 * 50);
}
}