From 0bd20e87c967470c3ee991a86d19eb007243f294 Mon Sep 17 00:00:00 2001 From: Mengran Lan Date: Thu, 8 Aug 2024 18:25:53 +0800 Subject: [PATCH 01/16] integrate sentry --- prover/Cargo.lock | 272 ++++++++++++++++++++++- prover/Cargo.toml | 2 + prover/config.json | 6 +- prover/src/config.rs | 11 + prover/src/main.rs | 34 ++- prover/src/task_processor.rs | 13 +- prover/src/types.rs | 9 + prover/src/utils.rs | 15 +- prover/src/version.rs | 9 +- prover/src/zk_circuits_handler/curie.rs | 2 +- prover/src/zk_circuits_handler/darwin.rs | 2 +- 11 files changed, 361 insertions(+), 14 deletions(-) diff --git a/prover/Cargo.lock b/prover/Cargo.lock index ded147e00d..49b068c8ce 100644 --- a/prover/Cargo.lock +++ b/prover/Cargo.lock @@ -1083,6 +1083,16 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" +[[package]] +name = "debugid" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef552e6f588e446098f6ba40d89ac146c8c7b64aade83c051ee00bb5d2bc18d" +dependencies = [ + "serde", + "uuid 1.10.0", +] + [[package]] name = "der" version = "0.7.9" @@ -1093,6 +1103,15 @@ dependencies = [ "zeroize", ] +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", +] + [[package]] name = "derivative" version = "2.2.0" @@ -1306,7 +1325,7 @@ dependencies = [ "sha2", "sha3 0.10.8", "thiserror", - "uuid", + "uuid 0.8.2", ] [[package]] @@ -1612,6 +1631,18 @@ dependencies = [ "subtle", ] +[[package]] +name = "findshlibs" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40b9e59cd0f7e0806cca4be089683ecb6434e602038df21fe6bf6711b2f07f64" +dependencies = [ + "cc", + "lazy_static", + "libc", + "winapi", +] + [[package]] name = "fixed-hash" version = "0.8.0" @@ -2162,6 +2193,17 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "hostname" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9c7c7c8ac16c798734b8a24560c1362120597c40d5e1459f09498f8f6c8f2ba" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "windows", +] + [[package]] name = "http" version = "0.2.12" @@ -2783,6 +2825,12 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + [[package]] name = "num-derive" version = "0.3.3" @@ -2977,6 +3025,17 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "os_info" +version = "3.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae99c7fa6dd38c7cafe1ec085e804f8f555a2f8659b0dbe03f1f9963a9b51092" +dependencies = [ + "log", + "serde", + "windows-sys 0.52.0", +] + [[package]] name = "pairing" version = "0.23.0" @@ -3208,6 +3267,12 @@ dependencies = [ "thiserror", ] +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -3301,6 +3366,8 @@ dependencies = [ "reqwest-middleware", "reqwest-retry", "rlp", + "sentry", + "sentry-log", "serde", "serde_json", "sled", @@ -3564,6 +3631,7 @@ dependencies = [ "base64 0.22.1", "bytes", "encoding_rs", + "futures-channel", "futures-core", "futures-util", "h2 0.4.5", @@ -4130,6 +4198,124 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" +[[package]] +name = "sentry" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5484316556650182f03b43d4c746ce0e3e48074a21e2f51244b648b6542e1066" +dependencies = [ + "httpdate", + "native-tls", + "reqwest 0.12.4", + "sentry-backtrace", + "sentry-contexts", + "sentry-core", + "sentry-debug-images", + "sentry-panic", + "sentry-tracing", + "tokio", + "ureq", +] + +[[package]] +name = "sentry-backtrace" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40aa225bb41e2ec9d7c90886834367f560efc1af028f1c5478a6cce6a59c463a" +dependencies = [ + "backtrace", + "once_cell", + "regex", + "sentry-core", +] + +[[package]] +name = "sentry-contexts" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a8dd746da3d16cb8c39751619cefd4fcdbd6df9610f3310fd646b55f6e39910" +dependencies = [ + "hostname", + "libc", + "os_info", + "rustc_version 0.4.0", + "sentry-core", + "uname", +] + +[[package]] +name = "sentry-core" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "161283cfe8e99c8f6f236a402b9ccf726b201f365988b5bb637ebca0abbd4a30" +dependencies = [ + "once_cell", + "rand", + "sentry-types", + "serde", + "serde_json", +] + +[[package]] +name = "sentry-debug-images" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc6b25e945fcaa5e97c43faee0267eebda9f18d4b09a251775d8fef1086238a" +dependencies = [ + "findshlibs", + "once_cell", + "sentry-core", +] + +[[package]] +name = "sentry-log" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75bbcc61886955045a1dd4bdb173412a80bb2571be3c5bfcf7eb8f55a442bbf5" +dependencies = [ + "log", + "sentry-core", +] + +[[package]] +name = "sentry-panic" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc74f229c7186dd971a9491ffcbe7883544aa064d1589bd30b83fb856cd22d63" +dependencies = [ + "sentry-backtrace", + "sentry-core", +] + +[[package]] +name = "sentry-tracing" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd3c5faf2103cd01eeda779ea439b68c4ee15adcdb16600836e97feafab362ec" +dependencies = [ + "sentry-backtrace", + "sentry-core", + "tracing-core", + "tracing-subscriber", +] + +[[package]] +name = "sentry-types" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d68cdf6bc41b8ff3ae2a9c4671e97426dcdd154cc1d4b6b72813f285d6b163f" +dependencies = [ + "debugid", + "hex", + "rand", + "serde", + "serde_json", + "thiserror", + "time", + "url", + "uuid 1.10.0", +] + [[package]] name = "serde" version = "1.0.203" @@ -4592,6 +4778,37 @@ dependencies = [ "num_cpus", ] +[[package]] +name = "time" +version = "0.3.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +dependencies = [ + "deranged", + "itoa", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +dependencies = [ + "num-conv", + "time-core", +] + [[package]] name = "tiny-keccak" version = "2.0.2" @@ -4626,6 +4843,7 @@ dependencies = [ "bytes", "libc", "mio", + "num_cpus", "pin-project-lite", "socket2", "windows-sys 0.48.0", @@ -4763,6 +4981,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", + "valuable", ] [[package]] @@ -4775,6 +4994,15 @@ dependencies = [ "tracing", ] +[[package]] +name = "tracing-subscriber" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +dependencies = [ + "tracing-core", +] + [[package]] name = "try-lock" version = "0.2.5" @@ -4826,6 +5054,15 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "uname" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b72f89f0ca32e4db1c04e2a72f5345d59796d4866a1ee0609084569f73683dc8" +dependencies = [ + "libc", +] + [[package]] name = "unarray" version = "0.1.4" @@ -4871,6 +5108,19 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" +[[package]] +name = "ureq" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72139d247e5f97a3eff96229a7ae85ead5328a39efe76f8bf5a06313d505b6ea" +dependencies = [ + "base64 0.22.1", + "log", + "native-tls", + "once_cell", + "url", +] + [[package]] name = "url" version = "2.5.0" @@ -4880,6 +5130,7 @@ dependencies = [ "form_urlencoded", "idna", "percent-encoding", + "serde", ] [[package]] @@ -4904,6 +5155,15 @@ dependencies = [ "serde", ] +[[package]] +name = "uuid" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" +dependencies = [ + "serde", +] + [[package]] name = "valuable" version = "0.1.0" @@ -5093,6 +5353,16 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" +dependencies = [ + "windows-core", + "windows-targets 0.52.5", +] + [[package]] name = "windows-core" version = "0.52.0" diff --git a/prover/Cargo.toml b/prover/Cargo.toml index 19faa80f84..22930be549 100644 --- a/prover/Cargo.toml +++ b/prover/Cargo.toml @@ -46,3 +46,5 @@ sled = "0.34.7" http = "1.1.0" clap = { version = "4.5", features = ["derive"] } ctor = "0.2.8" +sentry = "0.34.0" +sentry-log = "0.34.0" diff --git a/prover/config.json b/prover/config.json index daaf989f53..4c0332109d 100644 --- a/prover/config.json +++ b/prover/config.json @@ -3,7 +3,7 @@ "keystore_path": "keystore.json", "keystore_password": "prover-pwd", "db_path": "unique-db-path-for-prover-1", - "proof_type": 2, + "prover_type": 2, "low_version_circuit": { "hard_fork_name": "bernoulli", "params_path": "params", @@ -22,5 +22,9 @@ }, "l2geth": { "endpoint": "http://localhost:9999" + }, + "sentry": { + "dsn": "", + "enabled": true } } diff --git a/prover/src/config.rs b/prover/src/config.rs index 4e3c1f2ccc..41284e8ae6 100644 --- a/prover/src/config.rs +++ b/prover/src/config.rs @@ -24,6 +24,12 @@ pub struct L2GethConfig { pub endpoint: String, } +#[derive(Debug, Serialize, Deserialize)] +pub struct SentryConfig { + pub dsn: String, + pub enabled: bool, +} + #[derive(Debug, Deserialize)] pub struct Config { pub prover_name: String, @@ -35,6 +41,7 @@ pub struct Config { pub high_version_circuit: CircuitConfig, pub coordinator: CoordinatorConfig, pub l2geth: Option, + pub sentry: Option, } impl Config { @@ -49,6 +56,10 @@ impl Config { let file = File::open(file_name)?; Config::from_reader(&file) } + + pub fn partner_name(&self) -> String { + todo!() + } } static SCROLL_PROVER_ASSETS_DIR_ENV_NAME: &str = "SCROLL_PROVER_ASSETS_DIR"; diff --git a/prover/src/main.rs b/prover/src/main.rs index 22605a7a5c..4060f6156c 100644 --- a/prover/src/main.rs +++ b/prover/src/main.rs @@ -45,10 +45,33 @@ fn main() -> Result<(), Box> { std::process::exit(0); } - utils::log_init(args.log_file); - let config: Config = Config::from_file(args.config_file)?; + let _guard = config.sentry.as_ref().and_then(|conf| { + if conf.enabled { + Some(sentry::init(( + conf.dsn.clone(), + sentry::ClientOptions { + release: Some(version::get_version_cow()), + ..Default::default() + }, + ))) + } else { + None + } + }); + + _guard.iter().for_each(|_| { + sentry::configure_scope(|scope| { + scope.set_tag("prover_type", config.prover_type); + scope.set_tag("partner_name", config.partner_name()); + }); + + sentry::capture_message("test message on start", sentry::Level::Info); + }); + + utils::log_init(args.log_file, _guard.is_some()); + if let Err(e) = AssetsDirEnvConfig::init() { log::error!("AssetsDirEnvConfig init failed: {:#}", e); std::process::exit(-2); @@ -62,6 +85,13 @@ fn main() -> Result<(), Box> { let prover = Prover::new(&config, coordinator_listener)?; + _guard.iter().for_each(|_| { + sentry::configure_scope(|scope| { + let public_key = sentry::protocol::Value::from(prover.get_public_key()); + scope.set_extra("public_key", public_key); + }); + }); + log::info!( "prover start successfully. name: {}, type: {:?}, publickey: {}, version: {}", config.prover_name, diff --git a/prover/src/task_processor.rs b/prover/src/task_processor.rs index 3b4044f96f..c3f6d88aae 100644 --- a/prover/src/task_processor.rs +++ b/prover/src/task_processor.rs @@ -54,11 +54,14 @@ impl<'a> TaskProcessor<'a> { ); let result = match self.prover.prove_task(&task_wrapper.task) { Ok(proof_detail) => self.prover.submit_proof(proof_detail, &task_wrapper.task), - Err(error) => self.prover.submit_error( - &task_wrapper.task, - super::types::ProofFailureType::NoPanic, - error, - ), + Err(error) => { + log::error!("failed to prove task, {:#}", error); + self.prover.submit_error( + &task_wrapper.task, + super::types::ProofFailureType::NoPanic, + error, + ) + } }; return result; } diff --git a/prover/src/types.rs b/prover/src/types.rs index 47f2724fc7..05f52ed4bf 100644 --- a/prover/src/types.rs +++ b/prover/src/types.rs @@ -1,3 +1,5 @@ +use std::fmt::Display; + use ethers_core::types::H256; use serde::{Deserialize, Deserializer, Serialize, Serializer}; @@ -101,6 +103,13 @@ impl<'de> Deserialize<'de> for ProverType { } } +impl Display for ProverType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(format!("{:?}", self).as_str())?; + Ok(()) + } +} + #[derive(Serialize, Deserialize, Default)] pub struct Task { pub uuid: String, diff --git a/prover/src/utils.rs b/prover/src/utils.rs index 18be4ac7a1..cb82920457 100644 --- a/prover/src/utils.rs +++ b/prover/src/utils.rs @@ -6,7 +6,7 @@ use crate::types::{ProverType, TaskType}; static LOG_INIT: Once = Once::new(); /// Initialize log -pub fn log_init(log_file: Option) { +pub fn log_init(log_file: Option, sentry_enabled: bool) { LOG_INIT.call_once(|| { let mut builder = env_logger::Builder::from_env(Env::default().default_filter_or("info")); if let Some(file_path) = log_file { @@ -20,7 +20,18 @@ pub fn log_init(log_file: Option) { ); builder.target(env_logger::Target::Pipe(target)); } - builder.init(); + let logger = builder.build(); + let max_level = logger.filter(); + + let boxed_logger: Box = if sentry_enabled { + Box::new(sentry_log::SentryLogger::with_dest(logger)) + } else { + Box::new(logger) + }; + + log::set_boxed_logger(boxed_logger) + .map(|()| log::set_max_level(max_level)) + .unwrap(); }); } diff --git a/prover/src/version.rs b/prover/src/version.rs index 76249adeae..9044cd9152 100644 --- a/prover/src/version.rs +++ b/prover/src/version.rs @@ -1,4 +1,4 @@ -use std::cell::OnceCell; +use std::{borrow::Cow, cell::OnceCell}; static DEFAULT_COMMIT: &str = "unknown"; static mut VERSION: OnceCell = OnceCell::new(); @@ -16,3 +16,10 @@ fn init_version() -> String { pub fn get_version() -> String { unsafe { VERSION.get_or_init(init_version).clone() } } + +pub fn get_version_cow() -> Cow<'static, str> { + unsafe { + let release: &'static str = std::mem::transmute(get_version().as_str()); + std::borrow::Cow::Borrowed(release) + } +} diff --git a/prover/src/zk_circuits_handler/curie.rs b/prover/src/zk_circuits_handler/curie.rs index c3b3a1966f..6d7a22683e 100644 --- a/prover/src/zk_circuits_handler/curie.rs +++ b/prover/src/zk_circuits_handler/curie.rs @@ -226,7 +226,7 @@ mod tests { #[ctor::ctor] fn init() { - crate::utils::log_init(None); + crate::utils::log_init(None, false); log::info!("logger initialized"); } diff --git a/prover/src/zk_circuits_handler/darwin.rs b/prover/src/zk_circuits_handler/darwin.rs index bbbd0251f1..b55b6de6d5 100644 --- a/prover/src/zk_circuits_handler/darwin.rs +++ b/prover/src/zk_circuits_handler/darwin.rs @@ -247,7 +247,7 @@ mod tests { #[ctor::ctor] fn init() { - crate::utils::log_init(None); + crate::utils::log_init(None, false); log::info!("logger initialized"); } From a1803c18bdf0c5bc7c051caf5982dddefd404b23 Mon Sep 17 00:00:00 2001 From: Mengran Lan Date: Thu, 8 Aug 2024 20:10:14 +0800 Subject: [PATCH 02/16] add partner_name implementation --- prover/Cargo.lock | 5 +++-- prover/Cargo.toml | 1 + prover/src/config.rs | 14 +++++++++++++- prover/src/main.rs | 3 +++ 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/prover/Cargo.lock b/prover/Cargo.lock index 49b068c8ce..08ab60cd03 100644 --- a/prover/Cargo.lock +++ b/prover/Cargo.lock @@ -3362,6 +3362,7 @@ dependencies = [ "prover 0.11.0", "prover 0.12.0", "rand", + "regex", "reqwest 0.12.4", "reqwest-middleware", "reqwest-retry", @@ -3553,9 +3554,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.4" +version = "1.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" dependencies = [ "aho-corasick", "memchr", diff --git a/prover/Cargo.toml b/prover/Cargo.toml index 22930be549..e3156f5f20 100644 --- a/prover/Cargo.toml +++ b/prover/Cargo.toml @@ -48,3 +48,4 @@ clap = { version = "4.5", features = ["derive"] } ctor = "0.2.8" sentry = "0.34.0" sentry-log = "0.34.0" +regex = "1.10.6" diff --git a/prover/src/config.rs b/prover/src/config.rs index 41284e8ae6..bf3150a9c1 100644 --- a/prover/src/config.rs +++ b/prover/src/config.rs @@ -1,4 +1,5 @@ use anyhow::{bail, Result}; +use regex::Regex; use serde::{Deserialize, Serialize}; use std::fs::File; @@ -58,7 +59,18 @@ impl Config { } pub fn partner_name(&self) -> String { - todo!() + let prover_name = &self.prover_name; + let scroll_prefix = Regex::new(r"^scroll-.*").unwrap(); + let idc_prefix = Regex::new(r"^idc-.*").unwrap(); + + if scroll_prefix.is_match(prover_name) || idc_prefix.is_match(prover_name) { + let parts = prover_name.split('-').collect::>(); + format!("{}-{}", parts[0], parts[1]) + } else { + let split_re = Regex::new(r"[-_]").unwrap(); + let parts = split_re.split(prover_name).collect::>(); + parts[0].to_string() + } } } diff --git a/prover/src/main.rs b/prover/src/main.rs index 4060f6156c..0a41ccadb4 100644 --- a/prover/src/main.rs +++ b/prover/src/main.rs @@ -65,6 +65,9 @@ fn main() -> Result<(), Box> { sentry::configure_scope(|scope| { scope.set_tag("prover_type", config.prover_type); scope.set_tag("partner_name", config.partner_name()); + + let prover_name = sentry::protocol::Value::from(config.prover_name.clone()); + scope.set_extra("prover_name", prover_name); }); sentry::capture_message("test message on start", sentry::Level::Info); From 376e300d2aeb5b00456fbe8a49e0beb78e1d0800 Mon Sep 17 00:00:00 2001 From: Mengran Lan Date: Tue, 13 Aug 2024 19:22:03 +0800 Subject: [PATCH 03/16] feat: fix sentry issues --- prover/src/coordinator_client.rs | 4 +++ prover/src/coordinator_client/errors.rs | 35 ++++++++++++++++++++++++ prover/src/main.rs | 5 ++-- prover/src/task_processor.rs | 7 ++++- prover/src/types.rs | 24 +++++++++++++++++ prover/src/version.rs | 36 ++++++++++++++++++++----- 6 files changed, 101 insertions(+), 10 deletions(-) diff --git a/prover/src/coordinator_client.rs b/prover/src/coordinator_client.rs index 56fd58954e..8f6ab225e7 100644 --- a/prover/src/coordinator_client.rs +++ b/prover/src/coordinator_client.rs @@ -11,6 +11,7 @@ use errors::*; use listener::Listener; use tokio::runtime::Runtime; use types::*; +pub use errors::GetEmptyTaskError; use crate::{config::Config, key_signer::KeySigner}; @@ -105,6 +106,9 @@ impl<'a> CoordinatorClient<'a> { self.login().context("JWT expired, re-login failed")?; log::info!("re-login success"); return self.action_with_re_login(req, f); + } else if response.errcode == ErrorCode::ErrCoordinatorEmptyProofData { + log::info!("coordinator return empty task"); + return Err(anyhow::anyhow!(GetEmptyTaskError)); } else if response.errcode != ErrorCode::Success { bail!("action failed: {}", response.errmsg) } diff --git a/prover/src/coordinator_client/errors.rs b/prover/src/coordinator_client/errors.rs index 2d27b3cd82..68da2547b9 100644 --- a/prover/src/coordinator_client/errors.rs +++ b/prover/src/coordinator_client/errors.rs @@ -1,4 +1,5 @@ use serde::{Deserialize, Deserializer}; +use std::fmt; #[derive(Debug, Clone, Copy, PartialEq)] pub enum ErrorCode { @@ -51,3 +52,37 @@ impl<'de> Deserialize<'de> for ErrorCode { Ok(ErrorCode::from_i32(v)) } } + +// ==================================================== + +#[derive(Debug, Clone)] +pub struct GetEmptyTaskError; + +impl fmt::Display for GetEmptyTaskError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "get empty task") + } +} + +// =================================== tests module ======================================== + +#[cfg(test)] +mod tests { + use super::*; + use anyhow::{Context, Ok, Result}; + + #[ctor::ctor] + fn init() { + crate::utils::log_init(None, false); + log::info!("logger initialized"); + } + + #[test] + fn test_anyhow_error_is() -> Result<()> { + let err: Result<()> = Err(anyhow::anyhow!(GetEmptyTaskError)).context("this is a test context"); + + assert!(err.unwrap_err().is::(), "error matches after anyhow context"); + + Ok(()) + } +} \ No newline at end of file diff --git a/prover/src/main.rs b/prover/src/main.rs index 0a41ccadb4..01facab003 100644 --- a/prover/src/main.rs +++ b/prover/src/main.rs @@ -1,4 +1,5 @@ #![feature(lazy_cell)] +#![feature(const_option)] mod config; mod coordinator_client; @@ -65,9 +66,7 @@ fn main() -> Result<(), Box> { sentry::configure_scope(|scope| { scope.set_tag("prover_type", config.prover_type); scope.set_tag("partner_name", config.partner_name()); - - let prover_name = sentry::protocol::Value::from(config.prover_name.clone()); - scope.set_extra("prover_name", prover_name); + scope.set_tag("prover_name", config.prover_name.clone()); }); sentry::capture_message("test message on start", sentry::Level::Info); diff --git a/prover/src/task_processor.rs b/prover/src/task_processor.rs index c3f6d88aae..c5ccc05a47 100644 --- a/prover/src/task_processor.rs +++ b/prover/src/task_processor.rs @@ -1,6 +1,7 @@ use super::{prover::Prover, task_cache::TaskCache}; use anyhow::{Context, Result}; use std::rc::Rc; +use super::coordinator_client::GetEmptyTaskError; pub struct TaskProcessor<'a> { prover: &'a Prover<'a>, @@ -16,7 +17,11 @@ impl<'a> TaskProcessor<'a> { loop { log::info!("start a new round."); if let Err(err) = self.prove_and_submit() { - log::error!("encounter error: {:#}", err); + if err.is::() { + log::info!("get empty task, skip."); + } else { + log::error!("encounter error: {:#}", err); + } } else { log::info!("prove & submit succeed."); } diff --git a/prover/src/types.rs b/prover/src/types.rs index 05f52ed4bf..711db07c75 100644 --- a/prover/src/types.rs +++ b/prover/src/types.rs @@ -252,3 +252,27 @@ impl Default for ProofStatus { Self::Ok } } + +// =================================== tests module ======================================== + +#[cfg(test)] +mod tests { + use super::*; + use anyhow::{Ok, Result}; + + #[ctor::ctor] + fn init() { + crate::utils::log_init(None, false); + log::info!("logger initialized"); + } + + #[test] + fn test_prover_type_display() -> Result<()> { + let chunk = ProverType::Chunk; + let batch = ProverType::Batch; + + assert_eq!(chunk.to_string(), "Chunk"); + assert_eq!(batch.to_string(), "Batch"); + Ok(()) + } +} \ No newline at end of file diff --git a/prover/src/version.rs b/prover/src/version.rs index 9044cd9152..9224fb422f 100644 --- a/prover/src/version.rs +++ b/prover/src/version.rs @@ -3,12 +3,14 @@ use std::{borrow::Cow, cell::OnceCell}; static DEFAULT_COMMIT: &str = "unknown"; static mut VERSION: OnceCell = OnceCell::new(); -pub const TAG: &str = "v0.0.0"; +pub const DEFAULT_TAG: &str = "v0.0.0"; pub const DEFAULT_ZK_VERSION: &str = "000000-000000"; +static TAG: Option<&str> = option_env!("GO_TAG"); + fn init_version() -> String { let commit = option_env!("GIT_REV").unwrap_or(DEFAULT_COMMIT); - let tag = option_env!("GO_TAG").unwrap_or(TAG); + let tag = TAG.unwrap_or(DEFAULT_TAG); let zk_version = option_env!("ZK_VERSION").unwrap_or(DEFAULT_ZK_VERSION); format!("{tag}-{commit}-{zk_version}") } @@ -18,8 +20,30 @@ pub fn get_version() -> String { } pub fn get_version_cow() -> Cow<'static, str> { - unsafe { - let release: &'static str = std::mem::transmute(get_version().as_str()); - std::borrow::Cow::Borrowed(release) - } + + let v = TAG.unwrap_or(DEFAULT_TAG); + std::borrow::Cow::Borrowed(v) } + +// =================================== tests module ======================================== + +#[cfg(test)] +mod tests { + use super::*; + use anyhow::{Ok, Result}; + + #[ctor::ctor] + fn init() { + crate::utils::log_init(None, false); + log::info!("logger initialized"); + } + + #[test] + fn test_get_version_cow() -> Result<()> { + let version = get_version_cow(); + + assert_eq!(get_version(), "v0.0.0-unknown-000000-000000"); + assert_eq!(&version, "v0.0.0"); + Ok(()) + } +} \ No newline at end of file From 9927cae1043358ec24f02a205a8bb99ccdcc3154 Mon Sep 17 00:00:00 2001 From: Mengran Lan Date: Tue, 13 Aug 2024 19:25:53 +0800 Subject: [PATCH 04/16] refactor version logic --- prover/Makefile | 4 +++- prover/src/version.rs | 27 +++++++-------------------- 2 files changed, 10 insertions(+), 21 deletions(-) diff --git a/prover/Makefile b/prover/Makefile index 6bcd3faa7f..79e681f2bd 100644 --- a/prover/Makefile +++ b/prover/Makefile @@ -35,8 +35,10 @@ else ZK_VERSION=${ZKEVM_COMMIT}-${HALO2_GPU_VERSION} endif +RELEASE_VERSION=${GO_TAG}-${GIT_REV}-${ZK_VERSION} + prover: - GO_TAG=${GO_TAG} GIT_REV=${GIT_REV} ZK_VERSION=${ZK_VERSION} cargo build --release + RELEASE_VERSION=${RELEASE_VERSION} cargo build --release tests_binary: cargo clean && cargo test --release --no-run diff --git a/prover/src/version.rs b/prover/src/version.rs index 9224fb422f..92915aa49e 100644 --- a/prover/src/version.rs +++ b/prover/src/version.rs @@ -1,27 +1,14 @@ -use std::{borrow::Cow, cell::OnceCell}; +use std::borrow::Cow; -static DEFAULT_COMMIT: &str = "unknown"; -static mut VERSION: OnceCell = OnceCell::new(); - -pub const DEFAULT_TAG: &str = "v0.0.0"; -pub const DEFAULT_ZK_VERSION: &str = "000000-000000"; - -static TAG: Option<&str> = option_env!("GO_TAG"); - -fn init_version() -> String { - let commit = option_env!("GIT_REV").unwrap_or(DEFAULT_COMMIT); - let tag = TAG.unwrap_or(DEFAULT_TAG); - let zk_version = option_env!("ZK_VERSION").unwrap_or(DEFAULT_ZK_VERSION); - format!("{tag}-{commit}-{zk_version}") -} +static RELEASE_VERSION: Option<&str> = option_env!("RELEASE_VERSION"); +const DEFAULT_VERSION: &str = "v0.0.0-unknown-000000-000000"; pub fn get_version() -> String { - unsafe { VERSION.get_or_init(init_version).clone() } + RELEASE_VERSION.unwrap_or(DEFAULT_VERSION).to_string() } pub fn get_version_cow() -> Cow<'static, str> { - - let v = TAG.unwrap_or(DEFAULT_TAG); + let v = RELEASE_VERSION.unwrap_or(DEFAULT_VERSION); std::borrow::Cow::Borrowed(v) } @@ -42,8 +29,8 @@ mod tests { fn test_get_version_cow() -> Result<()> { let version = get_version_cow(); - assert_eq!(get_version(), "v0.0.0-unknown-000000-000000"); - assert_eq!(&version, "v0.0.0"); + assert_eq!(get_version(), DEFAULT_VERSION); + assert_eq!(&version, DEFAULT_VERSION); Ok(()) } } \ No newline at end of file From 2956a25d5a78b7cb22ddfc1ad108b776db0d19f7 Mon Sep 17 00:00:00 2001 From: Mengran Lan Date: Tue, 13 Aug 2024 19:26:21 +0800 Subject: [PATCH 05/16] fix lint issues --- prover/src/coordinator_client.rs | 2 +- prover/src/coordinator_client/errors.rs | 10 +++++++--- prover/src/task_processor.rs | 3 +-- prover/src/types.rs | 2 +- prover/src/version.rs | 2 +- 5 files changed, 11 insertions(+), 8 deletions(-) diff --git a/prover/src/coordinator_client.rs b/prover/src/coordinator_client.rs index 8f6ab225e7..2276c84bd2 100644 --- a/prover/src/coordinator_client.rs +++ b/prover/src/coordinator_client.rs @@ -7,11 +7,11 @@ use anyhow::{bail, Context, Ok, Result}; use std::rc::Rc; use api::Api; +pub use errors::GetEmptyTaskError; use errors::*; use listener::Listener; use tokio::runtime::Runtime; use types::*; -pub use errors::GetEmptyTaskError; use crate::{config::Config, key_signer::KeySigner}; diff --git a/prover/src/coordinator_client/errors.rs b/prover/src/coordinator_client/errors.rs index 68da2547b9..76b577be88 100644 --- a/prover/src/coordinator_client/errors.rs +++ b/prover/src/coordinator_client/errors.rs @@ -79,10 +79,14 @@ mod tests { #[test] fn test_anyhow_error_is() -> Result<()> { - let err: Result<()> = Err(anyhow::anyhow!(GetEmptyTaskError)).context("this is a test context"); + let err: Result<()> = + Err(anyhow::anyhow!(GetEmptyTaskError)).context("this is a test context"); - assert!(err.unwrap_err().is::(), "error matches after anyhow context"); + assert!( + err.unwrap_err().is::(), + "error matches after anyhow context" + ); Ok(()) } -} \ No newline at end of file +} diff --git a/prover/src/task_processor.rs b/prover/src/task_processor.rs index c5ccc05a47..179354bcc6 100644 --- a/prover/src/task_processor.rs +++ b/prover/src/task_processor.rs @@ -1,7 +1,6 @@ -use super::{prover::Prover, task_cache::TaskCache}; +use super::{coordinator_client::GetEmptyTaskError, prover::Prover, task_cache::TaskCache}; use anyhow::{Context, Result}; use std::rc::Rc; -use super::coordinator_client::GetEmptyTaskError; pub struct TaskProcessor<'a> { prover: &'a Prover<'a>, diff --git a/prover/src/types.rs b/prover/src/types.rs index 711db07c75..771e308a26 100644 --- a/prover/src/types.rs +++ b/prover/src/types.rs @@ -275,4 +275,4 @@ mod tests { assert_eq!(batch.to_string(), "Batch"); Ok(()) } -} \ No newline at end of file +} diff --git a/prover/src/version.rs b/prover/src/version.rs index 92915aa49e..fbf72bffc4 100644 --- a/prover/src/version.rs +++ b/prover/src/version.rs @@ -33,4 +33,4 @@ mod tests { assert_eq!(&version, DEFAULT_VERSION); Ok(()) } -} \ No newline at end of file +} From bbfbfc5403394a1e1dfabfef9c634c210e8e0033 Mon Sep 17 00:00:00 2001 From: Mengran Lan Date: Tue, 13 Aug 2024 19:42:06 +0800 Subject: [PATCH 06/16] add custom environment tag to sentry --- prover/src/main.rs | 1 + prover/src/utils.rs | 19 ++++++++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/prover/src/main.rs b/prover/src/main.rs index 01facab003..35c64edbf1 100644 --- a/prover/src/main.rs +++ b/prover/src/main.rs @@ -54,6 +54,7 @@ fn main() -> Result<(), Box> { conf.dsn.clone(), sentry::ClientOptions { release: Some(version::get_version_cow()), + environment: Some(utils::get_environment()), ..Default::default() }, ))) diff --git a/prover/src/utils.rs b/prover/src/utils.rs index cb82920457..c7f97d715f 100644 --- a/prover/src/utils.rs +++ b/prover/src/utils.rs @@ -1,5 +1,5 @@ use env_logger::Env; -use std::{fs::OpenOptions, sync::Once}; +use std::{borrow::Cow, fs::OpenOptions, sync::Once}; use crate::types::{ProverType, TaskType}; @@ -41,3 +41,20 @@ pub fn get_task_types(prover_type: ProverType) -> Vec { ProverType::Batch => vec![TaskType::Batch, TaskType::Bundle], } } + +static ENV_UNKNOWN: &str = "unknown"; +static ENV_DEVNET: &str = "devnet"; +static ENV_SEPOLIA: &str = "sepolia"; +static ENV_MAINNET: &str = "mainnet"; + +pub fn get_environment() -> Cow<'static, str> { + let env: &'static str = match std::env::var("CHAIN_ID") { + Ok(chain_id) => match chain_id.as_str() { + "534352" => ENV_MAINNET, + "534351" => ENV_SEPOLIA, + _ => ENV_DEVNET, + }, + Err(_) => ENV_UNKNOWN, + }; + std::borrow::Cow::Borrowed(env) +} From 09f483031219417d7f0b4d085d8f870bed20304c Mon Sep 17 00:00:00 2001 From: Mengran Lan Date: Mon, 19 Aug 2024 15:55:25 +0800 Subject: [PATCH 07/16] coordinator issue sentry endpoint --- coordinator/conf/config.json | 3 ++- coordinator/internal/config/config.go | 2 ++ coordinator/internal/controller/api/auth.go | 14 ++++++++++++++ coordinator/internal/middleware/login_jwt.go | 2 +- coordinator/internal/types/auth.go | 5 +++-- 5 files changed, 22 insertions(+), 4 deletions(-) diff --git a/coordinator/conf/config.json b/coordinator/conf/config.json index 15ae708f8d..2ae55c0bf9 100644 --- a/coordinator/conf/config.json +++ b/coordinator/conf/config.json @@ -13,7 +13,8 @@ "assets_path_hi": "" }, "max_verifier_workers": 4, - "min_prover_version": "v1.0.0" + "min_prover_version": "v1.0.0", + "prover_sentry_endpoint": "" }, "db": { "driver_name": "postgres", diff --git a/coordinator/internal/config/config.go b/coordinator/internal/config/config.go index cbe9ca02d8..43fb1b522f 100644 --- a/coordinator/internal/config/config.go +++ b/coordinator/internal/config/config.go @@ -27,6 +27,8 @@ type ProverManager struct { MaxVerifierWorkers int `json:"max_verifier_workers"` // MinProverVersion is the minimum version of the prover that is required. MinProverVersion string `json:"min_prover_version"` + // ProverSentryEndpoint the sentry endpoint being sent to each prover in login response + ProverSentryEndpoint string `json:"prover_sentry_endpoint"` } // L2 loads l2geth configuration items. diff --git a/coordinator/internal/controller/api/auth.go b/coordinator/internal/controller/api/auth.go index dc4759524f..30d2aca6c3 100644 --- a/coordinator/internal/controller/api/auth.go +++ b/coordinator/internal/controller/api/auth.go @@ -3,12 +3,14 @@ package api import ( "errors" "fmt" + "time" jwt "github.com/appleboy/gin-jwt/v2" "github.com/gin-gonic/gin" "github.com/scroll-tech/go-ethereum/log" "gorm.io/gorm" + commonTypes "scroll-tech/common/types" "scroll-tech/coordinator/internal/config" "scroll-tech/coordinator/internal/logic/auth" "scroll-tech/coordinator/internal/logic/verifier" @@ -17,12 +19,14 @@ import ( // AuthController is login API type AuthController struct { + cfg *config.Config loginLogic *auth.LoginLogic } // NewAuthController returns an LoginController instance func NewAuthController(db *gorm.DB, cfg *config.Config, vf *verifier.Verifier) *AuthController { return &AuthController{ + cfg: cfg, loginLogic: auth.NewLoginLogic(db, cfg, vf), } } @@ -93,3 +97,13 @@ func (a *AuthController) IdentityHandler(c *gin.Context) interface{} { } return nil } + +// LoginResponse replies to client for /login +func (a *AuthController) LoginResponse(c *gin.Context, code int, message string, time time.Time) { + resp := types.LoginSchema{ + Time: time, + Token: message, + SentryEndpoint: a.cfg.ProverManager.ProverSentryEndpoint, + } + commonTypes.RenderSuccess(c, resp) +} diff --git a/coordinator/internal/middleware/login_jwt.go b/coordinator/internal/middleware/login_jwt.go index b04810b0b7..a067fad7f3 100644 --- a/coordinator/internal/middleware/login_jwt.go +++ b/coordinator/internal/middleware/login_jwt.go @@ -24,7 +24,7 @@ func LoginMiddleware(conf *config.Config) *jwt.GinJWTMiddleware { TokenLookup: "header: Authorization, query: token, cookie: jwt", TokenHeadName: "Bearer", TimeFunc: time.Now, - LoginResponse: loginResponse, + LoginResponse: api.Auth.LoginResponse, }) if err != nil { diff --git a/coordinator/internal/types/auth.go b/coordinator/internal/types/auth.go index 2b7434e112..9e7e0fb995 100644 --- a/coordinator/internal/types/auth.go +++ b/coordinator/internal/types/auth.go @@ -22,8 +22,9 @@ const ( // LoginSchema for /login response type LoginSchema struct { - Time time.Time `json:"time"` - Token string `json:"token"` + Time time.Time `json:"time"` + Token string `json:"token"` + SentryEndpoint string `json:"sentry_endpoint"` } // TODO just use for darwin upgrade, need delete next upgrade From 89d7f6da2a91126b087ed8def5c63a9275193cbb Mon Sep 17 00:00:00 2001 From: Mengran Lan Date: Tue, 20 Aug 2024 11:19:38 +0800 Subject: [PATCH 08/16] add alternative logger --- prover/Cargo.lock | 12 ++++++++++++ prover/Cargo.toml | 3 ++- prover/src/coordinator_client/types.rs | 1 + 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/prover/Cargo.lock b/prover/Cargo.lock index 08ab60cd03..671246d11f 100644 --- a/prover/Cargo.lock +++ b/prover/Cargo.lock @@ -155,6 +155,17 @@ dependencies = [ "bytes", ] +[[package]] +name = "alterable_logger" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "914a2c81a0e8d57d88d11554612d5e0afe5f942cecbcc239b10a394fd7ce404b" +dependencies = [ + "arc-swap", + "log", + "once_cell", +] + [[package]] name = "android-tzdata" version = "0.1.1" @@ -3345,6 +3356,7 @@ dependencies = [ name = "prover" version = "0.1.0" dependencies = [ + "alterable_logger", "anyhow", "base64 0.13.1", "clap", diff --git a/prover/Cargo.toml b/prover/Cargo.toml index e3156f5f20..200527cbd1 100644 --- a/prover/Cargo.toml +++ b/prover/Cargo.toml @@ -21,6 +21,7 @@ bls12_381 = { git = "https://github.com/scroll-tech/bls12_381", branch = "feat/i anyhow = "1.0" log = "0.4" env_logger = "0.11.3" +alterable_logger = "1.0.0" serde = { version = "1.0.198", features = ["derive"] } serde_json = "1.0.116" futures = "0.3.30" @@ -48,4 +49,4 @@ clap = { version = "4.5", features = ["derive"] } ctor = "0.2.8" sentry = "0.34.0" sentry-log = "0.34.0" -regex = "1.10.6" +regex = "1.10.6" \ No newline at end of file diff --git a/prover/src/coordinator_client/types.rs b/prover/src/coordinator_client/types.rs index c646a9afd4..d1e961b33e 100644 --- a/prover/src/coordinator_client/types.rs +++ b/prover/src/coordinator_client/types.rs @@ -52,6 +52,7 @@ pub struct LoginRequest { pub struct LoginResponseData { pub time: String, pub token: String, + pub sentry_endpoint: Option, } pub type ChallengeResponseData = LoginResponseData; From 1c31cecdf2a56616722a41af9bbb82dbe7d2abc6 Mon Sep 17 00:00:00 2001 From: Mengran Lan Date: Thu, 22 Aug 2024 16:26:51 +0800 Subject: [PATCH 09/16] move GetEmptyTaskError to inner get_task method --- prover/src/coordinator_client.rs | 3 --- prover/src/coordinator_client/api.rs | 10 +++++++++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/prover/src/coordinator_client.rs b/prover/src/coordinator_client.rs index 087d27fd07..6aad516a91 100644 --- a/prover/src/coordinator_client.rs +++ b/prover/src/coordinator_client.rs @@ -107,9 +107,6 @@ impl<'a> CoordinatorClient<'a> { self.login().context("JWT expired, re-login failed")?; log::info!("re-login success"); return self.action_with_re_login(req, f); - } else if response.errcode == ErrorCode::ErrCoordinatorEmptyProofData { - log::info!("coordinator return empty task"); - return Err(anyhow::anyhow!(GetEmptyTaskError)); } else if response.errcode != ErrorCode::Success { bail!("action failed: {}", response.errmsg) } diff --git a/prover/src/coordinator_client/api.rs b/prover/src/coordinator_client/api.rs index 905a1e61c5..d654de5a39 100644 --- a/prover/src/coordinator_client/api.rs +++ b/prover/src/coordinator_client/api.rs @@ -69,7 +69,15 @@ impl Api { token: &String, ) -> Result> { let method = "/coordinator/v1/get_task"; - self.post_with_token(method, req, token).await + let response = self + .post_with_token::>(method, req, token) + .await?; + + if response.errcode == ErrorCode::ErrCoordinatorEmptyProofData { + log::info!("coordinator return empty task"); + return Err(anyhow::anyhow!(GetEmptyTaskError)); + } + Ok(response) } pub async fn submit_proof( From ee4112525e9de8d9442b3fcd76543f5ccd1b76e4 Mon Sep 17 00:00:00 2001 From: Mengran Lan Date: Fri, 23 Aug 2024 00:10:17 +0800 Subject: [PATCH 10/16] prover get sentry endpoint from coordinator --- prover/src/config.rs | 7 --- prover/src/coordinator_client.rs | 9 +++- prover/src/coordinator_client/errors.rs | 2 +- prover/src/main.rs | 51 +++++++++++---------- prover/src/prover.rs | 2 +- prover/src/types.rs | 2 +- prover/src/utils.rs | 56 ++++++++++++------------ prover/src/version.rs | 2 +- prover/src/zk_circuits_handler/curie.rs | 2 +- prover/src/zk_circuits_handler/darwin.rs | 2 +- 10 files changed, 68 insertions(+), 67 deletions(-) diff --git a/prover/src/config.rs b/prover/src/config.rs index bf3150a9c1..f47be301e7 100644 --- a/prover/src/config.rs +++ b/prover/src/config.rs @@ -25,12 +25,6 @@ pub struct L2GethConfig { pub endpoint: String, } -#[derive(Debug, Serialize, Deserialize)] -pub struct SentryConfig { - pub dsn: String, - pub enabled: bool, -} - #[derive(Debug, Deserialize)] pub struct Config { pub prover_name: String, @@ -42,7 +36,6 @@ pub struct Config { pub high_version_circuit: CircuitConfig, pub coordinator: CoordinatorConfig, pub l2geth: Option, - pub sentry: Option, } impl Config { diff --git a/prover/src/coordinator_client.rs b/prover/src/coordinator_client.rs index 6aad516a91..366daf3163 100644 --- a/prover/src/coordinator_client.rs +++ b/prover/src/coordinator_client.rs @@ -4,7 +4,7 @@ pub mod listener; pub mod types; use anyhow::{bail, Context, Ok, Result}; -use std::rc::Rc; +use std::{cell::OnceCell, rc::Rc}; use api::Api; use errors::*; @@ -19,6 +19,7 @@ pub use errors::{GetEmptyTaskError, ProofStatusNotOKError}; pub struct CoordinatorClient<'a> { api: Api, token: Option, + sentry_endpoint: OnceCell>, config: &'a Config, key_signer: Rc, rt: Runtime, @@ -46,6 +47,7 @@ impl<'a> CoordinatorClient<'a> { let mut client = Self { api, token: None, + sentry_endpoint: OnceCell::new(), config, key_signer, rt, @@ -90,6 +92,7 @@ impl<'a> CoordinatorClient<'a> { } if let Some(r) = login_response.data { token = r.token; + let _ = self.sentry_endpoint.set(r.sentry_endpoint); } else { bail!("login failed: got empty token") } @@ -139,4 +142,8 @@ impl<'a> CoordinatorClient<'a> { ) -> Result> { self.action_with_re_login(req, |s, req| s.do_submit_proof(req)) } + + pub fn get_sentry_dsn(&self) -> Option { + self.sentry_endpoint.get().and_then(|v| v.clone()) + } } diff --git a/prover/src/coordinator_client/errors.rs b/prover/src/coordinator_client/errors.rs index 587dbbf181..55f0e37f0d 100644 --- a/prover/src/coordinator_client/errors.rs +++ b/prover/src/coordinator_client/errors.rs @@ -82,7 +82,7 @@ mod tests { #[ctor::ctor] fn init() { - crate::utils::log_init(None, false); + crate::utils::log_init(None); log::info!("logger initialized"); } diff --git a/prover/src/main.rs b/prover/src/main.rs index 19981faef2..918c41d933 100644 --- a/prover/src/main.rs +++ b/prover/src/main.rs @@ -48,20 +48,38 @@ fn start() -> Result<()> { let config: Config = Config::from_file(args.config_file)?; - let _guard = config.sentry.as_ref().and_then(|conf| { - if conf.enabled { - Some(sentry::init(( - conf.dsn.clone(), + utils::log_init(args.log_file.clone()); + + if let Err(e) = AssetsDirEnvConfig::init() { + log::error!("AssetsDirEnvConfig init failed: {:#}", e); + std::process::exit(-2); + } + + let task_cache = Rc::new(TaskCache::new(&config.db_path)?); + + let coordinator_listener = Box::new(ClearCacheCoordinatorListener { + task_cache: task_cache.clone(), + }); + + let prover = Prover::new(&config, coordinator_listener)?; + + let _guard = prover + .coordinator_client + .borrow() + .get_sentry_dsn() + .map(|dsn| { + log::info!("successfully get dsn from coordinator"); + let gurad = Some(sentry::init(( + dsn, sentry::ClientOptions { release: Some(version::get_version_cow()), environment: Some(utils::get_environment()), ..Default::default() }, - ))) - } else { - None - } - }); + ))); + utils::set_logger_with_sentry(args.log_file); + gurad + }); _guard.iter().for_each(|_| { sentry::configure_scope(|scope| { @@ -73,21 +91,6 @@ fn start() -> Result<()> { sentry::capture_message("test message on start", sentry::Level::Info); }); - utils::log_init(args.log_file, _guard.is_some()); - - if let Err(e) = AssetsDirEnvConfig::init() { - log::error!("AssetsDirEnvConfig init failed: {:#}", e); - std::process::exit(-2); - } - - let task_cache = Rc::new(TaskCache::new(&config.db_path)?); - - let coordinator_listener = Box::new(ClearCacheCoordinatorListener { - task_cache: task_cache.clone(), - }); - - let prover = Prover::new(&config, coordinator_listener)?; - _guard.iter().for_each(|_| { sentry::configure_scope(|scope| { let public_key = sentry::protocol::Value::from(prover.get_public_key()); diff --git a/prover/src/prover.rs b/prover/src/prover.rs index 7de83906e0..963d9bd47f 100644 --- a/prover/src/prover.rs +++ b/prover/src/prover.rs @@ -19,7 +19,7 @@ pub struct Prover<'a> { config: &'a Config, key_signer: Rc, circuits_handler_provider: RefCell>, - coordinator_client: RefCell>, + pub coordinator_client: RefCell>, geth_client: Option>>, } diff --git a/prover/src/types.rs b/prover/src/types.rs index 771e308a26..ea4677c72e 100644 --- a/prover/src/types.rs +++ b/prover/src/types.rs @@ -262,7 +262,7 @@ mod tests { #[ctor::ctor] fn init() { - crate::utils::log_init(None, false); + crate::utils::log_init(None); log::info!("logger initialized"); } diff --git a/prover/src/utils.rs b/prover/src/utils.rs index c7f97d715f..b6db76fa95 100644 --- a/prover/src/utils.rs +++ b/prover/src/utils.rs @@ -1,38 +1,36 @@ use env_logger::Env; -use std::{borrow::Cow, fs::OpenOptions, sync::Once}; +use std::{borrow::Cow, fs::OpenOptions}; use crate::types::{ProverType, TaskType}; -static LOG_INIT: Once = Once::new(); - -/// Initialize log -pub fn log_init(log_file: Option, sentry_enabled: bool) { - LOG_INIT.call_once(|| { - let mut builder = env_logger::Builder::from_env(Env::default().default_filter_or("info")); - if let Some(file_path) = log_file { - let target = Box::new( - OpenOptions::new() - .write(true) - .create(true) - .truncate(false) - .open(file_path) - .expect("Can't create log file"), - ); - builder.target(env_logger::Target::Pipe(target)); - } - let logger = builder.build(); - let max_level = logger.filter(); +pub fn build_logger(log_file: Option) -> env_logger::Logger { + let mut builder = env_logger::Builder::from_env(Env::default().default_filter_or("info")); + if let Some(file_path) = log_file { + let target = Box::new( + OpenOptions::new() + .write(true) + .create(true) + .truncate(false) + .open(file_path) + .expect("Can't create log file"), + ); + builder.target(env_logger::Target::Pipe(target)); + } + builder.build() +} - let boxed_logger: Box = if sentry_enabled { - Box::new(sentry_log::SentryLogger::with_dest(logger)) - } else { - Box::new(logger) - }; +pub fn log_init(log_file: Option) { + let logger = build_logger(log_file); + let max_level = logger.filter(); + let boxed_logger = Box::new(logger); + alterable_logger::configure(max_level, boxed_logger); +} - log::set_boxed_logger(boxed_logger) - .map(|()| log::set_max_level(max_level)) - .unwrap(); - }); +pub fn set_logger_with_sentry(log_file: Option) { + let logger = build_logger(log_file); + let max_level = logger.filter(); + let boxed_logger = Box::new(sentry_log::SentryLogger::with_dest(logger)); + alterable_logger::configure(max_level, boxed_logger); } pub fn get_task_types(prover_type: ProverType) -> Vec { diff --git a/prover/src/version.rs b/prover/src/version.rs index fbf72bffc4..11de9d59cb 100644 --- a/prover/src/version.rs +++ b/prover/src/version.rs @@ -21,7 +21,7 @@ mod tests { #[ctor::ctor] fn init() { - crate::utils::log_init(None, false); + crate::utils::log_init(None); log::info!("logger initialized"); } diff --git a/prover/src/zk_circuits_handler/curie.rs b/prover/src/zk_circuits_handler/curie.rs index 6d7a22683e..c3b3a1966f 100644 --- a/prover/src/zk_circuits_handler/curie.rs +++ b/prover/src/zk_circuits_handler/curie.rs @@ -226,7 +226,7 @@ mod tests { #[ctor::ctor] fn init() { - crate::utils::log_init(None, false); + crate::utils::log_init(None); log::info!("logger initialized"); } diff --git a/prover/src/zk_circuits_handler/darwin.rs b/prover/src/zk_circuits_handler/darwin.rs index b55b6de6d5..bbbd0251f1 100644 --- a/prover/src/zk_circuits_handler/darwin.rs +++ b/prover/src/zk_circuits_handler/darwin.rs @@ -247,7 +247,7 @@ mod tests { #[ctor::ctor] fn init() { - crate::utils::log_init(None, false); + crate::utils::log_init(None); log::info!("logger initialized"); } From c213c0b7a164103f32b43ed464f9822eb5eb664b Mon Sep 17 00:00:00 2001 From: Mengran Lan Date: Fri, 23 Aug 2024 00:11:12 +0800 Subject: [PATCH 11/16] fix lint issue --- coordinator/internal/controller/api/auth.go | 1 + 1 file changed, 1 insertion(+) diff --git a/coordinator/internal/controller/api/auth.go b/coordinator/internal/controller/api/auth.go index 30d2aca6c3..5a9e73d447 100644 --- a/coordinator/internal/controller/api/auth.go +++ b/coordinator/internal/controller/api/auth.go @@ -11,6 +11,7 @@ import ( "gorm.io/gorm" commonTypes "scroll-tech/common/types" + "scroll-tech/coordinator/internal/config" "scroll-tech/coordinator/internal/logic/auth" "scroll-tech/coordinator/internal/logic/verifier" From dd003ada57b830a31ef090c94bbd678b5f771beb Mon Sep 17 00:00:00 2001 From: Mengran Lan Date: Fri, 23 Aug 2024 00:13:13 +0800 Subject: [PATCH 12/16] remove unused lines --- prover/config.json | 4 ---- 1 file changed, 4 deletions(-) diff --git a/prover/config.json b/prover/config.json index 4c0332109d..0a816360d5 100644 --- a/prover/config.json +++ b/prover/config.json @@ -22,9 +22,5 @@ }, "l2geth": { "endpoint": "http://localhost:9999" - }, - "sentry": { - "dsn": "", - "enabled": true } } From 5495a73aa092924c7e1552d90e12b187630b035e Mon Sep 17 00:00:00 2001 From: Mengran Lan Date: Fri, 23 Aug 2024 00:23:55 +0800 Subject: [PATCH 13/16] filter the case when sentry endpoint is empty string --- coordinator/internal/types/auth.go | 2 +- prover/src/coordinator_client.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/coordinator/internal/types/auth.go b/coordinator/internal/types/auth.go index 9e7e0fb995..6bbe2080f2 100644 --- a/coordinator/internal/types/auth.go +++ b/coordinator/internal/types/auth.go @@ -24,7 +24,7 @@ const ( type LoginSchema struct { Time time.Time `json:"time"` Token string `json:"token"` - SentryEndpoint string `json:"sentry_endpoint"` + SentryEndpoint string `json:"sentry_endpoint,omitempty"` } // TODO just use for darwin upgrade, need delete next upgrade diff --git a/prover/src/coordinator_client.rs b/prover/src/coordinator_client.rs index 366daf3163..86e26c4e74 100644 --- a/prover/src/coordinator_client.rs +++ b/prover/src/coordinator_client.rs @@ -92,7 +92,7 @@ impl<'a> CoordinatorClient<'a> { } if let Some(r) = login_response.data { token = r.token; - let _ = self.sentry_endpoint.set(r.sentry_endpoint); + let _ = self.sentry_endpoint.set(r.sentry_endpoint.filter(|s| !s.is_empty())); } else { bail!("login failed: got empty token") } From 52666a72653630e7e0d724a58a0858bf1f01d2c3 Mon Sep 17 00:00:00 2001 From: Mengran Lan Date: Fri, 23 Aug 2024 00:38:00 +0800 Subject: [PATCH 14/16] fix lint issue --- prover/src/coordinator_client.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/prover/src/coordinator_client.rs b/prover/src/coordinator_client.rs index 86e26c4e74..8a19c1f3a0 100644 --- a/prover/src/coordinator_client.rs +++ b/prover/src/coordinator_client.rs @@ -92,7 +92,9 @@ impl<'a> CoordinatorClient<'a> { } if let Some(r) = login_response.data { token = r.token; - let _ = self.sentry_endpoint.set(r.sentry_endpoint.filter(|s| !s.is_empty())); + let _ = self + .sentry_endpoint + .set(r.sentry_endpoint.filter(|s| !s.is_empty())); } else { bail!("login failed: got empty token") } From 43fba89477099dfa34c848cfcc8c7e8b079b8ec9 Mon Sep 17 00:00:00 2001 From: Mengran Lan Date: Sun, 29 Sep 2024 16:23:46 +0800 Subject: [PATCH 15/16] feat(prover): dynamicly detect sentry endpoint from coordinator --- prover/src/main.rs | 114 ++++++++++++++++++++--------------- prover/src/task_processor.rs | 9 ++- 2 files changed, 74 insertions(+), 49 deletions(-) diff --git a/prover/src/main.rs b/prover/src/main.rs index 8b7cb12791..f0048ca845 100644 --- a/prover/src/main.rs +++ b/prover/src/main.rs @@ -39,6 +39,62 @@ struct Args { log_file: Option, } +fn start_loop<'a>( + config: &'a Config, + prover: &'a Prover<'a>, + task_cache: Rc, + log_file: Option, + current_dsn: Option, +) -> Option { + let mut new_dsn: Option = None; + let should_stop = || { + new_dsn = prover.coordinator_client.borrow().get_sentry_dsn(); + + current_dsn != new_dsn + }; + + let _guard = current_dsn.clone().map(|dsn| { + log::info!("successfully get dsn from coordinator"); + let gurad = sentry::init(( + dsn, + sentry::ClientOptions { + release: Some(version::get_version_cow()), + environment: Some(utils::get_environment()), + ..Default::default() + }, + )); + utils::set_logger_with_sentry(log_file); + gurad + }); + + _guard.iter().for_each(|_| { + sentry::configure_scope(|scope| { + scope.set_tag("prover_type", config.prover_type); + scope.set_tag("partner_name", config.partner_name()); + scope.set_tag("prover_name", config.prover_name.clone()); + + let public_key = sentry::protocol::Value::from(prover.get_public_key()); + scope.set_extra("public_key", public_key); + }); + + sentry::capture_message("test message on start", sentry::Level::Info); + }); + + log::info!( + "prover start successfully. name: {}, type: {:?}, publickey: {}, version: {}", + config.prover_name, + config.prover_type, + prover.get_public_key(), + version::get_version(), + ); + + let task_processor = TaskProcessor::new(prover, task_cache); + + task_processor.start(should_stop); + + new_dsn +} + fn start() -> Result<()> { let args = Args::parse(); @@ -64,54 +120,16 @@ fn start() -> Result<()> { let prover = Prover::new(&config, coordinator_listener)?; - let _guard = prover - .coordinator_client - .borrow() - .get_sentry_dsn() - .map(|dsn| { - log::info!("successfully get dsn from coordinator"); - let gurad = Some(sentry::init(( - dsn, - sentry::ClientOptions { - release: Some(version::get_version_cow()), - environment: Some(utils::get_environment()), - ..Default::default() - }, - ))); - utils::set_logger_with_sentry(args.log_file); - gurad - }); - - _guard.iter().for_each(|_| { - sentry::configure_scope(|scope| { - scope.set_tag("prover_type", config.prover_type); - scope.set_tag("partner_name", config.partner_name()); - scope.set_tag("prover_name", config.prover_name.clone()); - }); - - sentry::capture_message("test message on start", sentry::Level::Info); - }); - - _guard.iter().for_each(|_| { - sentry::configure_scope(|scope| { - let public_key = sentry::protocol::Value::from(prover.get_public_key()); - scope.set_extra("public_key", public_key); - }); - }); - - log::info!( - "prover start successfully. name: {}, type: {:?}, publickey: {}, version: {}", - config.prover_name, - config.prover_type, - prover.get_public_key(), - version::get_version(), - ); - - let task_processor = TaskProcessor::new(&prover, task_cache); - - task_processor.start(); - - Ok(()) + let mut current_dsn = None; + loop { + current_dsn = start_loop( + &config, + &prover, + task_cache.clone(), + args.log_file.clone(), + current_dsn, + ); + } } fn main() { diff --git a/prover/src/task_processor.rs b/prover/src/task_processor.rs index 366a8d9788..f92990fb11 100644 --- a/prover/src/task_processor.rs +++ b/prover/src/task_processor.rs @@ -16,8 +16,15 @@ impl<'a> TaskProcessor<'a> { TaskProcessor { prover, task_cache } } - pub fn start(&self) { + pub fn start(&self, mut should_stop: F) + where + F: FnMut() -> bool, + { loop { + if should_stop() { + log::info!("task processor should stop."); + break; + } log::info!("start a new round."); if let Err(err) = self.prove_and_submit() { if err.is::() { From 2352802b5759de70a3e9364be761233009ea9a9c Mon Sep 17 00:00:00 2001 From: Mengran Lan Date: Mon, 30 Sep 2024 14:17:58 +0800 Subject: [PATCH 16/16] fix bug --- prover/src/coordinator_client.rs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/prover/src/coordinator_client.rs b/prover/src/coordinator_client.rs index 8a19c1f3a0..a56a4aa83a 100644 --- a/prover/src/coordinator_client.rs +++ b/prover/src/coordinator_client.rs @@ -4,7 +4,7 @@ pub mod listener; pub mod types; use anyhow::{bail, Context, Ok, Result}; -use std::{cell::OnceCell, rc::Rc}; +use std::rc::Rc; use api::Api; use errors::*; @@ -19,7 +19,7 @@ pub use errors::{GetEmptyTaskError, ProofStatusNotOKError}; pub struct CoordinatorClient<'a> { api: Api, token: Option, - sentry_endpoint: OnceCell>, + sentry_endpoint: Option, config: &'a Config, key_signer: Rc, rt: Runtime, @@ -47,7 +47,7 @@ impl<'a> CoordinatorClient<'a> { let mut client = Self { api, token: None, - sentry_endpoint: OnceCell::new(), + sentry_endpoint: None, config, key_signer, rt, @@ -92,9 +92,7 @@ impl<'a> CoordinatorClient<'a> { } if let Some(r) = login_response.data { token = r.token; - let _ = self - .sentry_endpoint - .set(r.sentry_endpoint.filter(|s| !s.is_empty())); + self.sentry_endpoint = r.sentry_endpoint.filter(|s| !s.is_empty()); } else { bail!("login failed: got empty token") } @@ -146,6 +144,6 @@ impl<'a> CoordinatorClient<'a> { } pub fn get_sentry_dsn(&self) -> Option { - self.sentry_endpoint.get().and_then(|v| v.clone()) + self.sentry_endpoint.clone() } }