cuprated/killswitch.rs
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.
14
15use std::{process::exit, time::Duration};
16
17use cuprate_helper::time::current_unix_timestamp;
18
19/// Assert that this is an alpha release.
20const _: () = {
21 const_format::assertcp_ne!(
22 crate::constants::MAJOR_VERSION,
23 "1",
24 "`cuprated` major version is 1, killswitch module should be deleted."
25 );
26 const_format::assertcp_ne!(
27 crate::constants::MINOR_VERSION,
28 "1",
29 "`cuprated` minor version is 1, killswitch module should be deleted."
30 );
31};
32
33/// The killswitch activates if the current timestamp is ahead of this timestamp.
34///
35/// Wed Apr 16 12:00:00 AM UTC 2025
36pub const KILLSWITCH_ACTIVATION_TIMESTAMP: u64 = 1744761600;
37
38/// 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 Mar 11 08:33:20 PM UTC 2025
48 const SYSTEM_CLOCK_SANITY_TIMESTAMP: u64 = 1741725200;
49
50 let current_ts = current_unix_timestamp();
51
52 // Prints a generic killswitch message.
53 let print_killswitch_msg = |msg| {
54 eprintln!("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 };
56
57 if 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 }
61
62 if current_ts > KILLSWITCH_ACTIVATION_TIMESTAMP {
63 print_killswitch_msg("The killswitch activation timestamp for alpha builds has passed.");
64 exit(88);
65 }
66}
67
68/// Spawn a thread that sleeps until the [`KILLSWITCH_ACTIVATION_TIMESTAMP`] activates.
69pub fn init_killswitch() {
70 // Check if we should exit immediately.
71 killswitch();
72
73 // Else spawn a thread that waits until we should.
74 std::thread::spawn(|| -> ! {
75 // Sleep until killswitch activation.
76 let current_ts = current_unix_timestamp();
77 let sleep_duration = Duration::from_secs(KILLSWITCH_ACTIVATION_TIMESTAMP - current_ts);
78 std::thread::sleep(sleep_duration);
79
80 // To account for any miscalculated or drifted sleep time,
81 // loop until the killswitch activates.
82 loop {
83 killswitch();
84 std::thread::sleep(Duration::from_secs(30));
85 }
86 });
87}