use crate::trust_tasks;
pub const TSP_REPLY_TIMEOUT_SECS: u64 = 30;
const RELAY_HOPS: u64 = 2;
const REFORM_MARGIN_SECS: u64 = 10;
const CLIENT_MARGIN_SECS: u64 = 10;
const _: () = assert!(
RELAY_HOPS >= 2,
"the §7.2.2 self-repair resend is not optional — the floor must cover it"
);
const _: () = assert!(
REFORM_MARGIN_SECS > 0 && CLIENT_MARGIN_SECS > 0,
"a zeroed margin puts the floor back level with the VTA's worst case"
);
#[must_use]
pub const fn relay_worst_case_secs() -> u64 {
RELAY_HOPS * TSP_REPLY_TIMEOUT_SECS + REFORM_MARGIN_SECS
}
#[must_use]
pub const fn min_relay_budget_secs() -> u64 {
relay_worst_case_secs() + CLIENT_MARGIN_SECS
}
#[allow(deprecated)] pub const RELAYS_ONWARD: &[&str] = &[
trust_tasks::TASK_WEBVH_DIDS_CREATE_1_0,
trust_tasks::TASK_WEBVH_DIDS_CREATE_1_1,
trust_tasks::TASK_WEBVH_DIDS_DELETE_1_0,
trust_tasks::TASK_WEBVH_DIDS_UPDATE_1_0,
trust_tasks::TASK_WEBVH_DIDS_ROTATE_KEYS_1_0,
trust_tasks::TASK_WEBVH_DIDS_REGISTER_WITH_SERVER_1_0,
trust_tasks::TASK_WEBVH_AGENT_NAME_LIST_1_0,
trust_tasks::TASK_WEBVH_AGENT_NAME_CHECK_1_0,
trust_tasks::TASK_WEBVH_AGENT_NAME_SET_1_0,
trust_tasks::TASK_WEBVH_AGENT_NAME_REMOVE_1_0,
trust_tasks::TASK_WEBVH_AGENT_NAME_DISABLE_1_0,
trust_tasks::TASK_WEBVH_AGENT_NAME_ENABLE_1_0,
trust_tasks::TASK_WEBVH_SERVERS_DOMAINS_0_1,
trust_tasks::TASK_WEBVH_SERVERS_RECONCILE_0_1,
trust_tasks::TASK_WEBVH_SERVERS_RETIRE_ORPHAN_0_1,
trust_tasks::TASK_ROOMS_OWNER_ANCHOR_0_1,
trust_tasks::TASK_ROOMS_OWNER_REGISTER_0_1,
trust_tasks::TASK_ROOMS_KEYS_BACKFILL_0_1,
trust_tasks::TASK_ROOMS_KEYS_READ_0_1,
trust_tasks::TASK_ROOMS_KEYS_BROWSE_0_1,
trust_tasks::TASK_VAULT_PROXY_LOGIN_0_1,
trust_tasks::TASK_VAULT_PROXY_LOGIN_0_2,
trust_tasks::TASK_SERVICES_ENABLE_1_0,
trust_tasks::TASK_SERVICES_UPDATE_1_0,
trust_tasks::TASK_SERVICES_UPDATE_1_1,
trust_tasks::TASK_PROVISION_INTEGRATION_0_3,
];
#[must_use]
pub fn relays_onward(type_uri: &str) -> bool {
RELAYS_ONWARD.contains(&type_uri)
}
#[must_use]
pub fn client_budget_secs(type_uri: &str, requested: u64) -> u64 {
if relays_onward(type_uri) {
requested.max(min_relay_budget_secs())
} else {
requested
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn the_old_sixty_second_budget_could_not_have_worked() {
assert!(
60 < relay_worst_case_secs(),
"60s was below the VTA's worst case ({}s) — the timeout could never \
have been anything but a mask",
relay_worst_case_secs()
);
assert!(min_relay_budget_secs() > relay_worst_case_secs());
}
#[test]
fn the_task_that_failed_now_outlasts_the_vta() {
let budget = client_budget_secs(trust_tasks::TASK_WEBVH_DIDS_CREATE_1_0, 60);
assert!(
budget > relay_worst_case_secs(),
"a relayed mint must outlast the VTA ({budget}s vs {}s)",
relay_worst_case_secs()
);
}
#[test]
fn budget_floor_holds_for_every_relaying_task() {
for uri in RELAYS_ONWARD {
for requested in [1, 30, 60] {
assert!(
client_budget_secs(uri, requested) > relay_worst_case_secs(),
"{uri} asked {requested}s and still cannot outlast the VTA"
);
}
}
}
#[test]
fn the_clamp_never_shortens_a_budget() {
let generous = min_relay_budget_secs() + 600;
assert_eq!(
client_budget_secs(trust_tasks::TASK_WEBVH_DIDS_CREATE_1_0, generous),
generous
);
assert_eq!(
client_budget_secs(trust_tasks::TASK_KEYS_CREATE_0_1, 30),
30
);
}
#[test]
fn relay_list_names_only_real_tasks() {
let catalog: std::collections::HashSet<&str> =
trust_tasks::ALL_URIS.iter().copied().collect();
let unknown: Vec<_> = RELAYS_ONWARD
.iter()
.filter(|u| !catalog.contains(*u))
.collect();
assert!(
unknown.is_empty(),
"these relay URIs are not in ALL_URIS — renamed or dropped, and \
their clamp now does nothing: {unknown:#?}"
);
}
#[test]
fn no_duplicate_relay_entries() {
let mut seen = std::collections::HashSet::new();
for uri in RELAYS_ONWARD {
assert!(seen.insert(*uri), "{uri} is listed twice");
}
}
}