1//! Killswitch.
2//!
3//! This module implements code for shutting down `cuprated`
4//! after a certain timestamp has passed.
5//!
6//! The reasoning is twofold:
7//! 1. Limiting the effects of any network errors
8//! caused by a faulty `cuprated`.
9//! 2. To enforce users to update `alpha` builds,
10//! if they choose to run them.
11//!
12//! This behavior is limited to an alpha build;
13//! this module will be removed after a stable v1 release.
1415use std::{process::exit, time::Duration};
1617use cuprate_helper::time::current_unix_timestamp;
1819/// Assert that this is an alpha release.
20const _: () = {
21const_format::assertcp_ne!(
22crate::constants::MAJOR_VERSION,
23"1",
24"`cuprated` major version is 1, killswitch module should be deleted."
25);
26const_format::assertcp_ne!(
27crate::constants::MINOR_VERSION,
28"1",
29"`cuprated` minor version is 1, killswitch module should be deleted."
30);
31};
3233/// The killswitch activates if the current timestamp is ahead of this timestamp.
34///
35/// Wed May 14 12:00:00 AM UTC 2025
36pub const KILLSWITCH_ACTIVATION_TIMESTAMP: u64 = 1747180800;
3738/// Check if the system clock is past a certain timestamp,
39/// if so, exit the entire program.
40fn killswitch() {
41/// A timestamp known to have been passed.
42 ///
43 /// This is an arbitrary timestamp used for
44 /// sanity checking the system's clock to make
45 /// sure it is not overly behind.
46 ///
47 /// Tue April 8 12:00:00 AM UTC 2025
48const SYSTEM_CLOCK_SANITY_TIMESTAMP: u64 = 1744070400;
4950let current_ts = current_unix_timestamp();
5152// Prints a generic killswitch message.
53let print_killswitch_msg = |msg| {
54eprintln!("killswitch: {msg}. (current_ts: {current_ts}, killswitch_activation_timestamp: {KILLSWITCH_ACTIVATION_TIMESTAMP}). `cuprated` will now exit. For more details on why this exists, see: <https://github.com/Cuprate/cuprate/pull/365>.");
55 };
5657if current_ts < SYSTEM_CLOCK_SANITY_TIMESTAMP {
58 print_killswitch_msg("The system clock is too far behind and is not reliable to use");
59 exit(66);
60 }
6162if current_ts > KILLSWITCH_ACTIVATION_TIMESTAMP {
63 print_killswitch_msg("The killswitch activation timestamp for alpha builds has passed.");
64 exit(88);
65 }
66}
6768/// Spawn a thread that sleeps until the [`KILLSWITCH_ACTIVATION_TIMESTAMP`] activates.
69pub fn init_killswitch() {
70// Check if we should exit immediately.
71killswitch();
7273// Else spawn a thread that waits until we should.
74std::thread::spawn(|| -> ! {
75// Sleep until killswitch activation.
76let current_ts = current_unix_timestamp();
77let sleep_duration = Duration::from_secs(KILLSWITCH_ACTIVATION_TIMESTAMP - current_ts);
78 std::thread::sleep(sleep_duration);
7980// To account for any miscalculated or drifted sleep time,
81 // loop until the killswitch activates.
82loop {
83 killswitch();
84 std::thread::sleep(Duration::from_secs(30));
85 }
86 });
87}