+# 'zigbuild' is needed to build for target 'x86_64-unknown-linux-gnu' on linux:
+# https://github.com/rust-cross/cargo-zigbuild
+
def main [host: string, destination: string, ssh_key: path] {
let ssh_args = [-i $ssh_key $host]
let scp_args = [-r -i $ssh_key]
- let target = "x86_64-unknown-linux-musl"
+ let target = "x86_64-unknown-linux-gnu"
let app_name = "staking_watchdog"
let build = "debug" # "debug" or "release".
# Don't know how to dynamically pass variable arguments.
if $build == "release" {
- cargo build --target $target --release
+ cargo zigbuild --target $target --release
} else {
- cargo build --target $target
+ cargo zigbuild --target $target
}
# invoke_ssh [sudo systemctl stop $app_name]
};
use anyhow::{Context, Result};
+use lettre::{
+ message::header::ContentType, transport::smtp::authentication::Credentials, Message,
+ SmtpTransport, Transport,
+};
use reqwest::StatusCode;
use serde::Deserialize;
use serde_json::{json, Value};
// mod error;
const FILE_CONF: &str = "config.ron";
-const CHECK_PERIOD: Duration = Duration::from_secs(5); // 5s.
-const EMAIL_RESEND_PERIOD: Duration = Duration::from_secs(12 * 60 * 60); // 12h.
+const CHECK_PERIOD: Duration = Duration::from_secs(10); // 10s.
+const EMAIL_RESEND_PERIOD: Duration = Duration::from_secs(6 * 60 * 60); // 6h.
const BASE_URI: &str = "http://localhost:5052/eth/v1/";
fn main() -> Result<()> {
if time::Instant::now() - time_last_email_send >= EMAIL_RESEND_PERIOD {
// Send e-mail.
println!("Sending email...");
-
- time_last_email_send = time::Instant::now();
+ match send_email(
+ "Staking ERROR",
+ &format!("Error: {:?}", error),
+ &config.smtp_login,
+ &config.smtp_password,
+ ) {
+ Err(email_error) => println!("Error sending email: {:?}", email_error),
+ _ => {
+ println!("Email successfully sent");
+ time_last_email_send = time::Instant::now();
+ }
+ }
}
}
.header("accept", "application/json");
match request_health.send() {
Ok(resp) => {
- println!("{resp:?}");
+ // println!("{resp:?}"); // For debug.
match resp.status().as_u16() {
200 => (),
206 => return Err(CheckError::NotSync),
}
}
- return Err(CheckError::NotSync);
-
for pub_key in pub_keys {
let request = client
.get(format!("{url}beacon/states/head/validators/0x{pub_key}"))
.header("accept", "application/json");
match request.send() {
Ok(resp) => {
- println!("{resp:?}");
+ // println!("{resp:?}"); // For debug.
match resp.status().as_u16() {
200 => {
let json: JsonValidatorState = resp.json()?;
- // println!("JSON:\n{:?}", json); // For Debug.
if json.data.status != "active_ongoing" {
return Err(CheckError::ValidatorStatusError {
pub_key: pub_key.clone(),
}
code => {
let json: JsonError = resp.json()?;
- // println!("JSON:\n{:?}", json); // For Debug.
return Err(CheckError::ValidatorError {
pub_key: pub_key.clone(),
message: format!(
}
}
Err(error) => {
- println!("{error:?}");
return Err(CheckError::ValidatorError {
pub_key: pub_key.clone(),
message: error.to_string(),
}
}
- // match request_builder
- // .header("Authorization", format!("Apikey {}", api_key))
- // .send()
- // {
- // Ok(resp) => {
- // if resp.status().is_success() {
- // let content = resp.text().unwrap();
- // Ok(serde_json::from_str(&content).unwrap())
- // } else {
- // Err(Box::new(Error {
- // message: format!("Request unsuccessful to {}: {:#?}", &url, resp),
- // }))
- // }
- // }
- // Err(error) => Err(Box::new(Error {
- // message: format!("Error during request to {}: {:?}", &url, error),
- // })),
- // }
-
- // 1) Check health.
-
- // 2) Check each validators.
+ Ok(())
+}
+
+fn send_email(title: &str, body: &str, login: &str, pass: &str) -> Result<()> {
+ let email = Message::builder()
+ .message_id(None)
+ .from("Staking Watchdog <redmine@d-lan.net>".parse()?)
+ .to("Greg Burri <greg.burri@gmail.com>".parse()?)
+ .subject(title)
+ .header(ContentType::TEXT_PLAIN)
+ .body(body.to_string())?;
+
+ let creds = Credentials::new(login.to_string(), pass.to_string());
+
+ // Open a remote connection to gmail
+ let mailer = SmtpTransport::relay("mail.gandi.net")?
+ .credentials(creds)
+ .build();
+
+ // Send the email
+ let response = mailer.send(&email)?;
+
+ println!("{:?}", response);
Ok(())
}