diff --git a/core/lib/eth_client/src/clients/http/decl.rs b/core/lib/eth_client/src/clients/http/decl.rs index 1dbda9d2264..7887e1bdee0 100644 --- a/core/lib/eth_client/src/clients/http/decl.rs +++ b/core/lib/eth_client/src/clients/http/decl.rs @@ -30,25 +30,17 @@ pub(super) trait L1EthNamespace { async fn get_transaction_count( &self, address: Address, - block: Option, + block: web3::BlockNumber, ) -> RpcResult; #[method(name = "gasPrice")] async fn gas_price(&self) -> RpcResult; #[method(name = "call")] - async fn call( - &self, - req: web3::CallRequest, - block: Option, - ) -> RpcResult; + async fn call(&self, req: web3::CallRequest, block: web3::BlockId) -> RpcResult; #[method(name = "getBalance")] - async fn get_balance( - &self, - address: Address, - block: Option, - ) -> RpcResult; + async fn get_balance(&self, address: Address, block: web3::BlockNumber) -> RpcResult; #[method(name = "getLogs")] async fn get_logs(&self, filter: web3::Filter) -> RpcResult>; diff --git a/core/lib/eth_client/src/clients/http/query.rs b/core/lib/eth_client/src/clients/http/query.rs index 89b793d463f..922248487e0 100644 --- a/core/lib/eth_client/src/clients/http/query.rs +++ b/core/lib/eth_client/src/clients/http/query.rs @@ -69,10 +69,7 @@ impl EthInterface for QueryClient { ) -> Result { COUNTERS.call[&(Method::NonceAtForAccount, self.component)].inc(); let latency = LATENCIES.direct[&Method::NonceAtForAccount].start(); - let nonce = self - .web3 - .get_transaction_count(account, Some(block)) - .await?; + let nonce = self.web3.get_transaction_count(account, block).await?; latency.observe(); Ok(nonce) } @@ -203,11 +200,10 @@ impl EthInterface for QueryClient { access_list: None, }; - let err = self - .web3 - .call(call_request, receipt.block_number.map(Into::into)) - .await - .err(); + let block_number = receipt + .block_number + .map_or_else(|| web3::BlockNumber::Latest.into(), Into::into); + let err = self.web3.call(call_request, block_number).await.err(); let failure_info = match err { Some(ClientError::Call(call_err)) => { @@ -246,6 +242,7 @@ impl EthInterface for QueryClient { block: Option, ) -> Result { let latency = LATENCIES.direct[&Method::CallContractFunction].start(); + let block = block.unwrap_or_else(|| web3::BlockNumber::Latest.into()); let output_bytes = self.web3.call(request, block).await?; latency.observe(); Ok(output_bytes) @@ -262,7 +259,10 @@ impl EthInterface for QueryClient { async fn eth_balance(&self, address: Address) -> Result { COUNTERS.call[&(Method::EthBalance, self.component)].inc(); let latency = LATENCIES.direct[&Method::EthBalance].start(); - let balance = self.web3.get_balance(address, None).await?; + let balance = self + .web3 + .get_balance(address, web3::BlockNumber::Latest) + .await?; latency.observe(); Ok(balance) } diff --git a/core/node/node_framework/src/service/runnables.rs b/core/node/node_framework/src/service/runnables.rs index 8567aacde97..7b3e3f7f43b 100644 --- a/core/node/node_framework/src/service/runnables.rs +++ b/core/node/node_framework/src/service/runnables.rs @@ -27,8 +27,8 @@ pub(super) struct Runnables { impl fmt::Debug for Runnables { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - // Macro that iterates over a `Vec`, invokes `.name()` method and collects the results into a Vec. - // Returns a reference to created vec to satisfy the `.field` method signature. + // Macro that iterates over a `Vec`, invokes `.name()` method and collects the results into a `Vec`. + // Returns a reference to created `Vec` to satisfy the `.field` method signature. macro_rules! names { ($vec:expr) => { &$vec.iter().map(|x| x.name()).collect::>() diff --git a/prover/Cargo.lock b/prover/Cargo.lock index c06f6f74048..c9ec3145cc0 100644 --- a/prover/Cargo.lock +++ b/prover/Cargo.lock @@ -193,6 +193,17 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +[[package]] +name = "async-lock" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d034b430882f8381900d3fe6f0aaa3ad94f2cb4ac519b429692a1bc2dda4ae7b" +dependencies = [ + "event-listener 4.0.3", + "event-listener-strategy", + "pin-project-lite", +] + [[package]] name = "async-stream" version = "0.3.5" @@ -346,6 +357,12 @@ version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + [[package]] name = "base64ct" version = "1.6.0" @@ -357,6 +374,9 @@ name = "beef" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1" +dependencies = [ + "serde", +] [[package]] name = "bellman_ce" @@ -1082,6 +1102,15 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bed69047ed42e52c7e38d6421eeb8ceefb4f2a2b52eed59137f7bad7908f6800" +[[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils 0.8.19", +] + [[package]] name = "const-decoder" version = "0.3.0" @@ -1764,11 +1793,7 @@ version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580" dependencies = [ - "humantime", - "is-terminal", "log", - "regex", - "termcolor", ] [[package]] @@ -1879,6 +1904,27 @@ version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" +[[package]] +name = "event-listener" +version = "4.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b215c49b2b248c855fb73579eb1f4f26c38ffdc12973e20e07b91d78d5646e" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "958e4d70b6d5e81971bebec42271ec641e7ff4e170a6fa605f2b8a8b65cb97d3" +dependencies = [ + "event-listener 4.0.3", + "pin-project-lite", +] + [[package]] name = "fastrand" version = "2.0.1" @@ -2195,6 +2241,16 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +[[package]] +name = "futures-timer" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" +dependencies = [ + "gloo-timers", + "send_wrapper", +] + [[package]] name = "futures-util" version = "0.3.30" @@ -2248,6 +2304,52 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +[[package]] +name = "gloo-net" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43aaa242d1239a8822c15c645f02166398da4f8b5c4bae795c1f5b44e9eee173" +dependencies = [ + "futures-channel", + "futures-core", + "futures-sink", + "gloo-utils", + "http", + "js-sys", + "pin-project", + "serde", + "serde_json", + "thiserror", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "gloo-timers" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "gloo-utils" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b5555354113b18c547c1d3a98fbf7fb32a9ff4f6fa112ce823a21641a0ba3aa" +dependencies = [ + "js-sys", + "serde", + "serde_json", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "google-cloud-auth" version = "0.13.0" @@ -2569,6 +2671,22 @@ dependencies = [ "want", ] +[[package]] +name = "hyper-rustls" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" +dependencies = [ + "futures-util", + "http", + "hyper", + "log", + "rustls 0.21.12", + "rustls-native-certs 0.6.3", + "tokio", + "tokio-rustls 0.24.1", +] + [[package]] name = "hyper-timeout" version = "0.4.1" @@ -2706,17 +2824,6 @@ dependencies = [ "serde", ] -[[package]] -name = "is-terminal" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" -dependencies = [ - "hermit-abi 0.3.6", - "libc", - "windows-sys 0.52.0", -] - [[package]] name = "itertools" version = "0.10.5" @@ -2788,6 +2895,156 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "jsonrpc-core" +version = "18.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14f7f76aef2d054868398427f6c54943cf3d1caa9a7ec7d0c38d69df97a965eb" +dependencies = [ + "futures 0.3.30", + "futures-executor", + "futures-util", + "log", + "serde", + "serde_derive", + "serde_json", +] + +[[package]] +name = "jsonrpsee" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9579d0ca9fb30da026bac2f0f7d9576ec93489aeb7cd4971dd5b4617d82c79b2" +dependencies = [ + "jsonrpsee-client-transport", + "jsonrpsee-core", + "jsonrpsee-http-client", + "jsonrpsee-proc-macros", + "jsonrpsee-types", + "jsonrpsee-wasm-client", + "jsonrpsee-ws-client", + "tracing", +] + +[[package]] +name = "jsonrpsee-client-transport" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9f9ed46590a8d5681975f126e22531698211b926129a40a2db47cbca429220" +dependencies = [ + "futures-channel", + "futures-util", + "gloo-net", + "http", + "jsonrpsee-core", + "pin-project", + "rustls-native-certs 0.7.0", + "rustls-pki-types", + "soketto", + "thiserror", + "tokio", + "tokio-rustls 0.25.0", + "tokio-util", + "tracing", + "url", + "webpki-roots", +] + +[[package]] +name = "jsonrpsee-core" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "776d009e2f591b78c038e0d053a796f94575d66ca4e77dd84bfc5e81419e436c" +dependencies = [ + "anyhow", + "async-lock", + "async-trait", + "beef", + "futures-timer", + "futures-util", + "hyper", + "jsonrpsee-types", + "pin-project", + "rustc-hash", + "serde", + "serde_json", + "thiserror", + "tokio", + "tokio-stream", + "tracing", + "wasm-bindgen-futures", +] + +[[package]] +name = "jsonrpsee-http-client" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b7de9f3219d95985eb77fd03194d7c1b56c19bce1abfcc9d07462574b15572" +dependencies = [ + "async-trait", + "hyper", + "hyper-rustls", + "jsonrpsee-core", + "jsonrpsee-types", + "serde", + "serde_json", + "thiserror", + "tokio", + "tower", + "tracing", + "url", +] + +[[package]] +name = "jsonrpsee-proc-macros" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d94b7505034e2737e688e1153bf81e6f93ad296695c43958d6da2e4321f0a990" +dependencies = [ + "heck 0.4.1", + "proc-macro-crate 2.0.0", + "proc-macro2 1.0.78", + "quote 1.0.35", + "syn 1.0.109", +] + +[[package]] +name = "jsonrpsee-types" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3266dfb045c9174b24c77c2dfe0084914bb23a6b2597d70c9dc6018392e1cd1b" +dependencies = [ + "anyhow", + "beef", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "jsonrpsee-wasm-client" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30f36d27503d0efc0355c1630b74ecfb367050847bf7241a0ed75fab6dfa96c0" +dependencies = [ + "jsonrpsee-client-transport", + "jsonrpsee-core", + "jsonrpsee-types", +] + +[[package]] +name = "jsonrpsee-ws-client" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "073c077471e89c4b511fa88b3df9a0f0abdf4a0a2e6683dd2ab36893af87bb2d" +dependencies = [ + "http", + "jsonrpsee-client-transport", + "jsonrpsee-core", + "jsonrpsee-types", + "url", +] + [[package]] name = "jsonwebtoken" version = "8.3.0" @@ -3824,6 +4081,12 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "parking" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" + [[package]] name = "parking_lot" version = "0.12.1" @@ -4277,18 +4540,20 @@ dependencies = [ "bincode", "clap 4.4.6", "colored", - "env_logger 0.10.2", "hex", - "log", "prover_dal", + "sqlx", "strum", "tokio", "tracing", "tracing-subscriber", "zksync_basic_types", "zksync_config", + "zksync_contracts", + "zksync_dal", "zksync_db_connection", "zksync_env_config", + "zksync_eth_client", "zksync_prover_fri_types", "zksync_prover_interface", "zksync_types", @@ -4588,7 +4853,7 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls-pemfile", + "rustls-pemfile 1.0.4", "serde", "serde_json", "serde_urlencoded", @@ -4825,6 +5090,57 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "rustls" +version = "0.21.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" +dependencies = [ + "log", + "ring 0.17.7", + "rustls-webpki 0.101.7", + "sct", +] + +[[package]] +name = "rustls" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432" +dependencies = [ + "log", + "ring 0.17.7", + "rustls-pki-types", + "rustls-webpki 0.102.3", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-native-certs" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" +dependencies = [ + "openssl-probe", + "rustls-pemfile 1.0.4", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-native-certs" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f1fb85efa936c42c6d5fc28d2629bb51e4b2f4b8a5211e297d599cc5a093792" +dependencies = [ + "openssl-probe", + "rustls-pemfile 2.1.2", + "rustls-pki-types", + "schannel", + "security-framework", +] + [[package]] name = "rustls-pemfile" version = "1.0.4" @@ -4834,6 +5150,43 @@ dependencies = [ "base64 0.21.7", ] +[[package]] +name = "rustls-pemfile" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d" +dependencies = [ + "base64 0.22.1", + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" + +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring 0.17.7", + "untrusted 0.9.0", +] + +[[package]] +name = "rustls-webpki" +version = "0.102.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3bce581c0dd41bce533ce695a1437fa16a7ab5ac3ccfa99fe1a620a7885eabf" +dependencies = [ + "ring 0.17.7", + "rustls-pki-types", + "untrusted 0.9.0", +] + [[package]] name = "rustversion" version = "1.0.14" @@ -4882,6 +5235,16 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring 0.17.7", + "untrusted 0.9.0", +] + [[package]] name = "seahash" version = "4.1.0" @@ -4966,6 +5329,12 @@ dependencies = [ "serde", ] +[[package]] +name = "send_wrapper" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f638d531eccd6e23b980caf34876660d38e265409d8e99b397ab71eb3612fad0" + [[package]] name = "sentry" version = "0.31.8" @@ -5169,6 +5538,19 @@ dependencies = [ "unsafe-libyaml", ] +[[package]] +name = "sha-1" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if 1.0.0", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + [[package]] name = "sha1" version = "0.10.6" @@ -5386,6 +5768,21 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "soketto" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d1c5305e39e09653383c2c7244f2f78b3bcae37cf50c64cb4789c9f5096ec2" +dependencies = [ + "base64 0.13.1", + "bytes", + "futures 0.3.30", + "httparse", + "log", + "rand 0.8.5", + "sha-1", +] + [[package]] name = "spin" version = "0.5.2" @@ -5467,7 +5864,7 @@ dependencies = [ "crossbeam-queue 0.3.11", "dotenvy", "either", - "event-listener", + "event-listener 2.5.3", "futures-channel", "futures-core", "futures-intrusive", @@ -5896,18 +6293,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.57" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b" +checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.57" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81" +checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" dependencies = [ "proc-macro2 1.0.78", "quote 1.0.35", @@ -6047,6 +6444,27 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls 0.21.12", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" +dependencies = [ + "rustls 0.22.4", + "rustls-pki-types", + "tokio", +] + [[package]] name = "tokio-stream" version = "0.1.14" @@ -6066,6 +6484,7 @@ checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" dependencies = [ "bytes", "futures-core", + "futures-io", "futures-sink", "pin-project-lite", "tokio", @@ -6699,6 +7118,15 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "webpki-roots" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3de34ae270483955a94f4b21bdaaeb83d508bb84a01435f393818edb0012009" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "which" version = "4.4.2" @@ -7513,6 +7941,37 @@ dependencies = [ "zksync_config", ] +[[package]] +name = "zksync_eth_client" +version = "0.1.0" +dependencies = [ + "async-trait", + "jsonrpsee", + "rlp", + "thiserror", + "tracing", + "vise", + "zksync_config", + "zksync_contracts", + "zksync_eth_signer", + "zksync_types", +] + +[[package]] +name = "zksync_eth_signer" +version = "0.1.0" +dependencies = [ + "async-trait", + "hex", + "jsonrpc-core", + "reqwest", + "rlp", + "serde", + "serde_json", + "thiserror", + "zksync_types", +] + [[package]] name = "zksync_health_check" version = "0.1.0" diff --git a/prover/Cargo.toml b/prover/Cargo.toml index 57808b5e253..ccd1e4d4fdd 100644 --- a/prover/Cargo.toml +++ b/prover/Cargo.toml @@ -86,6 +86,8 @@ zksync_state = { path = "../core/lib/state" } zksync_system_constants = { path = "../core/lib/constants" } zksync_types = { path = "../core/lib/types" } zksync_utils = { path = "../core/lib/utils" } +zksync_eth_client = { path = "../core/lib/eth_client" } +zksync_contracts = { path = "../core/lib/contracts" } # for `perf` profiling [profile.perf] diff --git a/prover/prover_cli/Cargo.toml b/prover/prover_cli/Cargo.toml index a09d012f5b4..f8045f0b0a5 100644 --- a/prover/prover_cli/Cargo.toml +++ b/prover/prover_cli/Cargo.toml @@ -10,14 +10,10 @@ keywords.workspace = true categories.workspace = true [dependencies] -tokio = { version = "1", features = ["rt-multi-thread", "macros"] } -env_logger = "0.10" -log = "0.4" -colored = "2.1.0" - +tokio = { workspace = true, features = ["rt-multi-thread", "macros"] } clap = { workspace = true, features = ["derive"] } -tracing.workspace = true tracing-subscriber = { workspace = true, features = ["env-filter"] } +tracing.workspace = true bincode.workspace = true hex.workspace = true anyhow.workspace = true @@ -29,4 +25,9 @@ zksync_types.workspace = true zksync_prover_fri_types.workspace = true zksync_prover_interface.workspace = true prover_dal.workspace = true +zksync_eth_client.workspace = true +zksync_contracts.workspace = true +zksync_dal.workspace = true strum.workspace = true +colored.workspace = true +sqlx.workspace = true diff --git a/prover/prover_cli/README.md b/prover/prover_cli/README.md index b57ec65956b..713fc6f3e62 100644 --- a/prover/prover_cli/README.md +++ b/prover/prover_cli/README.md @@ -121,7 +121,34 @@ Scheduler: In progress ⌛️ #### `prover_cli status l1` -TODO +Retrieve information about the state of the batches sent to L1 and compare the contract hashes in L1 with those stored +in the prover database. + +#### Example Output + + +``` +zk f run --release -- status l1 + +====== L1 Status ====== +State keeper: First batch: 0, recent batch: 10 +L1 state: block verified: 7, block committed: 9 +Eth sender is 1 behind. Last block committed: 9. Most recent sealed state keeper batch: 10. + ----------------------- +Verifier key hash matches: 0x063c9c1e9d39fc0b1633c78a49f1905s65ee0982ad96d97ef7fe3d4f1f1a72c7 + ----------------------- +Verification node hash in DB differs from the one in contract. +Contract hash: 0x1186ec268d49f1905f8d9c1e9d39fc33e98c74f91d91a21b8f7ef78bd09a8db8 +DB hash: 0x5a3ef282b21e12fe1f4438e5bb158fc5060b160559c5158c6389d62d9fe3d080 + ----------------------- +Verification leaf hash in DB differs from the one in contract. +Contract hash: 0x101e08b00193e529145ee09823378ef51a3bc8966504064f1f6ba3f1ba863210 +DB hash: 0x400a4b532c6f072c00d1806ef299300d4c104f4ac55bd8698ade78894fcadc0a + ----------------------- +Verification circuits hash in DB differs from the one in contract. +Contract hash: 0x18c1639094f58177409186e8c48d9f577c9410901d2f1d486b3e7d6cf553ae4c +DB hash: 0x0000000000000000000000000000000000000000000000000000000000000000 +``` ### `prover_cli requeue` diff --git a/prover/prover_cli/src/cli.rs b/prover/prover_cli/src/cli.rs index 4c01c132cea..64ec98426ba 100644 --- a/prover/prover_cli/src/cli.rs +++ b/prover/prover_cli/src/cli.rs @@ -1,4 +1,5 @@ -use clap::{command, Parser, Subcommand}; +use clap::{command, Args, Parser, Subcommand}; +use zksync_types::url::SensitiveUrl; use crate::commands::{self, get_file_info}; @@ -9,6 +10,20 @@ pub const VERSION_STRING: &str = env!("CARGO_PKG_VERSION"); struct ProverCLI { #[command(subcommand)] command: ProverCommand, + #[clap(flatten)] + config: ProverCLIConfig, +} + +// Note: This is a temporary solution for the configuration of the CLI. In the +// future, we should have an `config` command to set the configuration in a +// `.config` file. +#[derive(Args)] +pub struct ProverCLIConfig { + #[clap( + long, + default_value = "postgres://postgres:notsecurepassword@localhost/prover_local" + )] + pub db_url: SensitiveUrl, } #[derive(Subcommand)] @@ -19,10 +34,10 @@ enum ProverCommand { } pub async fn start() -> anyhow::Result<()> { - let ProverCLI { command } = ProverCLI::parse(); + let ProverCLI { command, config } = ProverCLI::parse(); match command { ProverCommand::FileInfo(args) => get_file_info::run(args).await?, - ProverCommand::Status(cmd) => cmd.run().await?, + ProverCommand::Status(cmd) => cmd.run(config).await?, }; Ok(()) diff --git a/prover/prover_cli/src/commands/status/batch.rs b/prover/prover_cli/src/commands/status/batch.rs index c29d25dc62e..b20078747f7 100644 --- a/prover/prover_cli/src/commands/status/batch.rs +++ b/prover/prover_cli/src/commands/status/batch.rs @@ -2,11 +2,12 @@ use anyhow::{ensure, Context as _}; use clap::Args as ClapArgs; use prover_dal::{Connection, ConnectionPool, Prover, ProverDal}; use zksync_types::{ - basic_fri_types::AggregationRound, prover_dal::WitnessJobStatus, L1BatchNumber, + basic_fri_types::AggregationRound, prover_dal::WitnessJobStatus, url::SensitiveUrl, + L1BatchNumber, }; use super::utils::{AggregationRoundInfo, BatchData, Task, TaskStatus}; -use crate::commands::status::utils::postgres_config; +use crate::cli::ProverCLIConfig; #[derive(ClapArgs)] pub struct Args { @@ -16,13 +17,13 @@ pub struct Args { verbose: bool, } -pub(crate) async fn run(args: Args) -> anyhow::Result<()> { +pub(crate) async fn run(args: Args, config: ProverCLIConfig) -> anyhow::Result<()> { ensure!( !args.batches.is_empty(), "At least one batch number should be provided" ); - let batches_data = get_batches_data(args.batches).await?; + let batches_data = get_batches_data(args.batches, config.db_url).await?; for batch_data in batches_data { println!("{batch_data:?}"); @@ -31,14 +32,14 @@ pub(crate) async fn run(args: Args) -> anyhow::Result<()> { Ok(()) } -async fn get_batches_data(batches: Vec) -> anyhow::Result> { - let config = postgres_config()?; - - let prover_connection_pool = - ConnectionPool::::builder(config.prover_url()?, config.max_connections()?) - .build() - .await - .context("failed to build a prover_connection_pool")?; +async fn get_batches_data( + batches: Vec, + db_url: SensitiveUrl, +) -> anyhow::Result> { + let prover_connection_pool = ConnectionPool::::singleton(db_url) + .build() + .await + .context("failed to build a prover_connection_pool")?; let mut conn = prover_connection_pool .connection() diff --git a/prover/prover_cli/src/commands/status/l1.rs b/prover/prover_cli/src/commands/status/l1.rs new file mode 100644 index 00000000000..19e5c3c4fa1 --- /dev/null +++ b/prover/prover_cli/src/commands/status/l1.rs @@ -0,0 +1,177 @@ +use anyhow::Context; +use prover_dal::{Prover, ProverDal}; +use zksync_basic_types::{ + protocol_version::{L1VerifierConfig, VerifierParams}, + L1BatchNumber, H256, U256, +}; +use zksync_config::{ContractsConfig, EthConfig, PostgresConfig}; +use zksync_dal::{ConnectionPool, Core, CoreDal}; +use zksync_env_config::FromEnv; +use zksync_eth_client::{clients::QueryClient, CallFunctionArgs}; + +pub(crate) async fn run() -> anyhow::Result<()> { + println!(" ====== L1 Status ====== "); + let postgres_config = PostgresConfig::from_env().context("PostgresConfig::from_env")?; + let contracts_config = ContractsConfig::from_env().context("ContractsConfig::from_env()")?; + let eth_config = EthConfig::from_env().context("EthConfig::from_env")?; + let query_client = QueryClient::new(eth_config.web3_url)?; + + let total_batches_committed: U256 = CallFunctionArgs::new("getTotalBatchesCommitted", ()) + .for_contract( + contracts_config.diamond_proxy_addr, + &zksync_contracts::hyperchain_contract(), + ) + .call(&query_client) + .await?; + + let total_batches_verified: U256 = CallFunctionArgs::new("getTotalBatchesVerified", ()) + .for_contract( + contracts_config.diamond_proxy_addr, + &zksync_contracts::hyperchain_contract(), + ) + .call(&query_client) + .await?; + + let connection_pool = ConnectionPool::::builder( + postgres_config + .replica_url() + .context("postgres_config.replica_url()")?, + postgres_config + .max_connections() + .context("postgres_config.max_connections()")?, + ) + .build() + .await + .context("ConnectionPoolBuilder::build()")?; + + let mut conn = connection_pool.connection().await?; + + // Using unwrap() safely as there will always be at least one block. + let first_state_keeper_l1_batch = conn + .blocks_dal() + .get_earliest_l1_batch_number() + .await? + .unwrap(); + let last_state_keeper_l1_batch = conn + .blocks_dal() + .get_sealed_l1_batch_number() + .await? + .unwrap(); + + pretty_print_l1_status( + total_batches_committed, + total_batches_verified, + first_state_keeper_l1_batch, + last_state_keeper_l1_batch, + ); + + let node_verification_key_hash: H256 = CallFunctionArgs::new("verificationKeyHash", ()) + .for_contract( + contracts_config.verifier_addr, + &zksync_contracts::verifier_contract(), + ) + .call(&query_client) + .await?; + + let node_verifier_params: VerifierParams = CallFunctionArgs::new("getVerifierParams", ()) + .for_contract( + contracts_config.diamond_proxy_addr, + &zksync_contracts::hyperchain_contract(), + ) + .call(&query_client) + .await?; + + let node_l1_verifier_config = L1VerifierConfig { + params: node_verifier_params, + recursion_scheduler_level_vk_hash: node_verification_key_hash, + }; + + let prover_connection_pool = ConnectionPool::::builder( + postgres_config + .prover_url() + .context("postgres_config.replica_url()")?, + postgres_config + .max_connections() + .context("postgres_config.max_connections()")?, + ) + .build() + .await + .context("ConnectionPoolBuilder::build()")?; + + let mut conn = prover_connection_pool.connection().await.unwrap(); + + let db_l1_verifier_config = conn + .fri_protocol_versions_dal() + .get_l1_verifier_config() + .await?; + + pretty_print_l1_verifier_config(node_l1_verifier_config, db_l1_verifier_config); + + Ok(()) +} + +fn pretty_print_l1_status( + total_batches_committed: U256, + total_batches_verified: U256, + first_state_keeper_l1_batch: L1BatchNumber, + last_state_keeper_l1_batch: L1BatchNumber, +) { + println!( + "State keeper: First batch: {}, recent batch: {}", + first_state_keeper_l1_batch, last_state_keeper_l1_batch + ); + + println!( + "L1 state: block verified: {}, block committed: {}", + total_batches_verified, total_batches_committed + ); + + let eth_sender_lag = U256::from(last_state_keeper_l1_batch.0) - total_batches_committed; + if eth_sender_lag > U256::zero() { + println!( + "Eth sender is {} behind. Last block committed: {}. Most recent sealed state keeper batch: {}.", + eth_sender_lag, + total_batches_committed, + last_state_keeper_l1_batch + ); + } +} + +fn print_hash_comparison(name: &str, contract_hash: H256, db_hash: H256) { + println!(" ----------------------- "); + if contract_hash != db_hash { + println!("{name} hash in DB differs from the one in contract."); + println!("Contract hash: {contract_hash:?}"); + println!("DB hash: {db_hash:?}"); + } else { + println!("{name} hash matches: {contract_hash:}"); + } +} + +fn pretty_print_l1_verifier_config( + node_l1_verifier_config: L1VerifierConfig, + db_l1_verifier_config: L1VerifierConfig, +) { + print_hash_comparison( + "Verifier key", + node_l1_verifier_config.recursion_scheduler_level_vk_hash, + db_l1_verifier_config.recursion_scheduler_level_vk_hash, + ); + print_hash_comparison( + "Verification node", + node_l1_verifier_config.params.recursion_node_level_vk_hash, + db_l1_verifier_config.params.recursion_node_level_vk_hash, + ); + print_hash_comparison( + "Verification leaf", + node_l1_verifier_config.params.recursion_leaf_level_vk_hash, + db_l1_verifier_config.params.recursion_leaf_level_vk_hash, + ); + print_hash_comparison( + "Verification circuits", + node_l1_verifier_config + .params + .recursion_circuits_set_vks_hash, + db_l1_verifier_config.params.recursion_circuits_set_vks_hash, + ); +} diff --git a/prover/prover_cli/src/commands/status/mod.rs b/prover/prover_cli/src/commands/status/mod.rs index 142f9e1feea..b6df8680151 100644 --- a/prover/prover_cli/src/commands/status/mod.rs +++ b/prover/prover_cli/src/commands/status/mod.rs @@ -1,17 +1,22 @@ use clap::Subcommand; +use crate::cli::ProverCLIConfig; + pub(crate) mod batch; +pub(crate) mod l1; mod utils; #[derive(Subcommand)] pub enum StatusCommand { Batch(batch::Args), + L1, } impl StatusCommand { - pub(crate) async fn run(self) -> anyhow::Result<()> { + pub(crate) async fn run(self, config: ProverCLIConfig) -> anyhow::Result<()> { match self { - StatusCommand::Batch(args) => batch::run(args).await, + StatusCommand::Batch(args) => batch::run(args, config).await, + StatusCommand::L1 => l1::run().await, } } } diff --git a/prover/prover_cli/src/commands/status/utils.rs b/prover/prover_cli/src/commands/status/utils.rs index 73daffbba61..3312149359b 100644 --- a/prover/prover_cli/src/commands/status/utils.rs +++ b/prover/prover_cli/src/commands/status/utils.rs @@ -2,18 +2,12 @@ use std::fmt::Debug; use colored::*; use strum::{Display, EnumString}; -use zksync_config::PostgresConfig; -use zksync_env_config::FromEnv; use zksync_types::{ basic_fri_types::AggregationRound, prover_dal::{ProofCompressionJobStatus, ProverJobFriInfo, ProverJobStatus, WitnessJobStatus}, L1BatchNumber, }; -pub fn postgres_config() -> anyhow::Result { - PostgresConfig::from_env() -} - /// Represents the proving data of a batch. pub struct BatchData { /// The number of the batch. @@ -120,7 +114,7 @@ pub enum TaskStatus { JobsNotFound, } -// This implementation will change to From> for AggregationRoundInfo +// This implementation will change to From> for `AggregationRoundInfo` // once the --verbose flag is implemented. impl From> for TaskStatus { fn from(jobs_vector: Vec) -> Self { diff --git a/prover/prover_cli/src/main.rs b/prover/prover_cli/src/main.rs index b979a36ed50..4bc0908a4f8 100644 --- a/prover/prover_cli/src/main.rs +++ b/prover/prover_cli/src/main.rs @@ -2,16 +2,13 @@ use prover_cli::cli; #[tokio::main] async fn main() { - env_logger::builder() - .filter_module("zksync_db_connection", log::LevelFilter::Off) - .filter_module("sqlx", log::LevelFilter::Off) - .filter_level(log::LevelFilter::Debug) + tracing_subscriber::fmt() + .with_max_level(tracing::Level::ERROR) .init(); - match cli::start().await { Ok(_) => {} Err(err) => { - log::error!("{err:?}"); + tracing::error!("{err:?}"); std::process::exit(1); } } diff --git a/prover/prover_dal/.sqlx/query-afc541dc4d550db9a2dacc6d65dd4f092115da1d00dc2122efae9cf070fcb266.json b/prover/prover_dal/.sqlx/query-afc541dc4d550db9a2dacc6d65dd4f092115da1d00dc2122efae9cf070fcb266.json new file mode 100644 index 00000000000..c828eb1ca56 --- /dev/null +++ b/prover/prover_dal/.sqlx/query-afc541dc4d550db9a2dacc6d65dd4f092115da1d00dc2122efae9cf070fcb266.json @@ -0,0 +1,38 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT\n recursion_scheduler_level_vk_hash,\n recursion_node_level_vk_hash,\n recursion_leaf_level_vk_hash,\n recursion_circuits_set_vks_hash\n FROM\n prover_fri_protocol_versions\n ORDER BY\n id DESC\n LIMIT 1\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "recursion_scheduler_level_vk_hash", + "type_info": "Bytea" + }, + { + "ordinal": 1, + "name": "recursion_node_level_vk_hash", + "type_info": "Bytea" + }, + { + "ordinal": 2, + "name": "recursion_leaf_level_vk_hash", + "type_info": "Bytea" + }, + { + "ordinal": 3, + "name": "recursion_circuits_set_vks_hash", + "type_info": "Bytea" + } + ], + "parameters": { + "Left": [] + }, + "nullable": [ + false, + false, + false, + false + ] + }, + "hash": "afc541dc4d550db9a2dacc6d65dd4f092115da1d00dc2122efae9cf070fcb266" +} diff --git a/prover/prover_dal/src/fri_protocol_versions_dal.rs b/prover/prover_dal/src/fri_protocol_versions_dal.rs index 2fc0e12cad6..7afcaef5ee4 100644 --- a/prover/prover_dal/src/fri_protocol_versions_dal.rs +++ b/prover/prover_dal/src/fri_protocol_versions_dal.rs @@ -128,4 +128,38 @@ impl FriProtocolVersionsDal<'_, '_> { ), }) } + + pub async fn get_l1_verifier_config(&mut self) -> Result { + let result = sqlx::query!( + r#" + SELECT + recursion_scheduler_level_vk_hash, + recursion_node_level_vk_hash, + recursion_leaf_level_vk_hash, + recursion_circuits_set_vks_hash + FROM + prover_fri_protocol_versions + ORDER BY + id DESC + LIMIT 1 + "#, + ) + .fetch_one(self.storage.conn()) + .await?; + + let params = VerifierParams { + recursion_node_level_vk_hash: H256::from_slice(&result.recursion_node_level_vk_hash), + recursion_leaf_level_vk_hash: H256::from_slice(&result.recursion_leaf_level_vk_hash), + recursion_circuits_set_vks_hash: H256::from_slice( + &result.recursion_circuits_set_vks_hash, + ), + }; + + Ok(L1VerifierConfig { + params, + recursion_scheduler_level_vk_hash: H256::from_slice( + &result.recursion_scheduler_level_vk_hash, + ), + }) + } }