From 17ce6c006a2f065855d76c8e5773c78c50fafb49 Mon Sep 17 00:00:00 2001 From: Miguel de Elias Date: Thu, 22 Feb 2024 18:05:58 -0300 Subject: [PATCH 1/6] feat: add Blockmeta service client --- Cargo.lock | 1517 +++++++++++++++-- crates/oracle/Cargo.toml | 13 +- crates/oracle/build.rs | 69 + .../proto/sf/blockmeta/v2/blockmeta.proto | 45 + .../oracle/src/blockmeta/blockmeta_client.rs | 177 ++ .../sf_blockmeta_client/sf.blockmeta.v2.rs | 896 ++++++++++ crates/oracle/src/config.rs | 48 + crates/oracle/src/main.rs | 6 +- crates/oracle/src/models.rs | 17 + crates/oracle/src/runner/oracle.rs | 65 +- crates/oracle/test/config/config.sample.toml | 3 +- .../indexed_chain_provider_via_env_var.toml | 4 + .../config/invalid_grpc_provider_url.toml | 17 + .../config/invalid_jrpc_provider_url.toml | 2 +- k8s/overlays/staging-mainnet/config.toml | 3 + 15 files changed, 2749 insertions(+), 133 deletions(-) create mode 100644 crates/oracle/build.rs create mode 100644 crates/oracle/proto/sf/blockmeta/v2/blockmeta.proto create mode 100644 crates/oracle/src/blockmeta/blockmeta_client.rs create mode 100644 crates/oracle/src/blockmeta/sf_blockmeta_client/sf.blockmeta.v2.rs create mode 100644 crates/oracle/test/config/invalid_grpc_provider_url.toml diff --git a/Cargo.lock b/Cargo.lock index 80f5b5df..25f8d61f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,13 +19,45 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "aho-corasick" -version = "0.7.18" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" dependencies = [ "memchr", ] +[[package]] +name = "alloy-primitives" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef197eb250c64962003cb08b90b17f0882c192f4a6f2f544809d424fd7cb0e7d" +dependencies = [ + "alloy-rlp", + "bytes", + "cfg-if", + "const-hex", + "derive_more", + "hex-literal", + "itoa", + "k256", + "keccak-asm", + "proptest", + "rand", + "ruint", + "serde", + "tiny-keccak", +] + +[[package]] +name = "alloy-rlp" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d58d9f5da7b40e9bfff0b7e7816700be4019db97d4b6359fe7f94a9e22e42ac" +dependencies = [ + "arrayvec", + "bytes", +] + [[package]] name = "ansi_term" version = "0.12.1" @@ -41,6 +73,130 @@ version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb07d2053ccdbe10e2af2995a2f116c1330396493dc1269f6a91d0ae82e19704" +[[package]] +name = "ark-ff" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b3235cc41ee7a12aaaf2c575a2ad7b46713a8a50bda2fc3b003a04845c05dd6" +dependencies = [ + "ark-ff-asm 0.3.0", + "ark-ff-macros 0.3.0", + "ark-serialize 0.3.0", + "ark-std 0.3.0", + "derivative", + "num-bigint", + "num-traits", + "paste", + "rustc_version 0.3.3", + "zeroize", +] + +[[package]] +name = "ark-ff" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" +dependencies = [ + "ark-ff-asm 0.4.2", + "ark-ff-macros 0.4.2", + "ark-serialize 0.4.2", + "ark-std 0.4.0", + "derivative", + "digest 0.10.7", + "itertools", + "num-bigint", + "num-traits", + "paste", + "rustc_version 0.4.0", + "zeroize", +] + +[[package]] +name = "ark-ff-asm" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db02d390bf6643fb404d3d22d31aee1c4bc4459600aef9113833d17e786c6e44" +dependencies = [ + "quote", + "syn 1.0.98", +] + +[[package]] +name = "ark-ff-asm" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" +dependencies = [ + "quote", + "syn 1.0.98", +] + +[[package]] +name = "ark-ff-macros" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fd794a08ccb318058009eefdf15bcaaaaf6f8161eb3345f907222bac38b20" +dependencies = [ + "num-bigint", + "num-traits", + "quote", + "syn 1.0.98", +] + +[[package]] +name = "ark-ff-macros" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" +dependencies = [ + "num-bigint", + "num-traits", + "proc-macro2", + "quote", + "syn 1.0.98", +] + +[[package]] +name = "ark-serialize" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6c2b318ee6e10f8c2853e73a83adc0ccb88995aa978d8a3408d492ab2ee671" +dependencies = [ + "ark-std 0.3.0", + "digest 0.9.0", +] + +[[package]] +name = "ark-serialize" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" +dependencies = [ + "ark-std 0.4.0", + "digest 0.10.7", + "num-bigint", +] + +[[package]] +name = "ark-std" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1df2c09229cbc5a028b1d70e00fdb2acee28b1055dfb5ca73eea49c5a25c4e7c" +dependencies = [ + "num-traits", + "rand", +] + +[[package]] +name = "ark-std" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" +dependencies = [ + "num-traits", + "rand", +] + [[package]] name = "arrayvec" version = "0.7.2" @@ -53,15 +209,37 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eab1c04a571841102f5345a8fc0f6bb3d31c315dec879b5c6e42e40ce7ffa34e" +[[package]] +name = "async-stream" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + [[package]] name = "async-trait" -version = "0.1.56" +version = "0.1.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96cf8829f67d2eab0b2dfa42c5d0ef737e0724e4a82b01b3e292456202b19716" +checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.48", ] [[package]] @@ -75,12 +253,68 @@ dependencies = [ "winapi", ] +[[package]] +name = "auto_impl" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "823b8bb275161044e2ac7a25879cb3e2480cb403e3943022c7c769c599b756aa" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + [[package]] name = "autocfg" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "axum" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" +dependencies = [ + "async-trait", + "axum-core", + "bitflags 1.3.2", + "bytes", + "futures-util", + "http", + "http-body", + "hyper", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "sync_wrapper", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-core" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http", + "http-body", + "mime", + "rustversion", + "tower-layer", + "tower-service", +] + [[package]] name = "backoff" version = "0.4.0" @@ -110,18 +344,57 @@ dependencies = [ "rustc-demangle", ] +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + [[package]] name = "base64" version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "bit-set" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + [[package]] name = "bitflags" version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" + [[package]] name = "bitvec" version = "0.20.4" @@ -169,6 +442,7 @@ dependencies = [ name = "block-oracle" version = "0.1.0" dependencies = [ + "alloy-primitives", "anyhow", "async-trait", "backoff", @@ -186,6 +460,8 @@ dependencies = [ "jsonrpc-core", "lazy_static", "prometheus", + "prost", + "prost-types", "rand", "reqwest", "secp256k1", @@ -195,6 +471,8 @@ dependencies = [ "thiserror", "tokio", "toml", + "tonic", + "tonic-build", "tracing", "tracing-subscriber", "url", @@ -238,15 +516,21 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" -version = "1.2.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0b3de4a0c5e67e16066a0715723abd91edc2f9001d09c46e1dca929351e130e" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +dependencies = [ + "serde", +] [[package]] name = "cc" -version = "1.0.73" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] [[package]] name = "cfg-if" @@ -261,10 +545,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac2bd7a1eb07da9ac757c923f69373deb7bc2ba5efc951b873bcb5e693992dca" dependencies = [ "atty", - "bitflags", + "bitflags 1.3.2", "clap_derive", "clap_lex", - "indexmap", + "indexmap 1.9.1", "once_cell", "strsim", "termcolor", @@ -281,7 +565,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn", + "syn 1.0.98", ] [[package]] @@ -306,6 +590,25 @@ dependencies = [ "unreachable", ] +[[package]] +name = "const-hex" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18d59688ad0945eaf6b84cb44fedbe93484c81b48970e98f09db8a22832d7961" +dependencies = [ + "cfg-if", + "cpufeatures", + "hex", + "proptest", + "serde", +] + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + [[package]] name = "convert_case" version = "0.4.0" @@ -343,6 +646,18 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "rand_core", + "subtle", + "zeroize", +] + [[package]] name = "crypto-common" version = "0.1.6" @@ -384,7 +699,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn", + "syn 1.0.98", ] [[package]] @@ -395,7 +710,28 @@ checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" dependencies = [ "darling_core", "quote", - "syn", + "syn 1.0.98", +] + +[[package]] +name = "der" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +dependencies = [ + "const-oid", + "zeroize", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.98", ] [[package]] @@ -407,8 +743,8 @@ dependencies = [ "convert_case", "proc-macro2", "quote", - "rustc_version", - "syn", + "rustc_version 0.4.0", + "syn 1.0.98", ] [[package]] @@ -422,12 +758,28 @@ dependencies = [ [[package]] name = "digest" -version = "0.10.3" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer 0.10.2", + "const-oid", "crypto-common", + "subtle", +] + +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der", + "digest 0.10.7", + "elliptic-curve", + "rfc6979", + "signature", + "spki", ] [[package]] @@ -436,6 +788,25 @@ version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest 0.10.7", + "ff", + "generic-array", + "group", + "pkcs8", + "rand_core", + "sec1", + "subtle", + "zeroize", +] + [[package]] name = "encoding_rs" version = "0.8.31" @@ -456,6 +827,22 @@ dependencies = [ "tokio", ] +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + [[package]] name = "ethabi" version = "16.0.0" @@ -495,7 +882,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfb684ac8fa8f6c5759f788862bb22ec6fe3cb392f6bfd08e3c64b603661e3f8" dependencies = [ "crunchy", - "fixed-hash", + "fixed-hash 0.7.0", "impl-rlp", "impl-serde", "tiny-keccak", @@ -508,7 +895,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "11da94e443c60508eb62cf256243a64da87304c2802ac2528847f79d750007ef" dependencies = [ "crunchy", - "fixed-hash", + "fixed-hash 0.7.0", "impl-rlp", "impl-serde", "tiny-keccak", @@ -521,7 +908,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05136f7057fe789f06e6d41d07b34e6f70d8c86e5693b60f97aaa6553553bdaf" dependencies = [ "ethbloom 0.11.1", - "fixed-hash", + "fixed-hash 0.7.0", "impl-rlp", "impl-serde", "primitive-types 0.10.1", @@ -535,7 +922,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2827b94c556145446fcce834ca86b7abf0c39a805883fe20e72c5bfdb5a0dc6" dependencies = [ "ethbloom 0.12.1", - "fixed-hash", + "fixed-hash 0.7.0", "impl-rlp", "impl-serde", "primitive-types 0.11.1", @@ -560,7 +947,7 @@ checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.98", "synstructure", ] @@ -573,6 +960,27 @@ dependencies = [ "instant", ] +[[package]] +name = "fastrlp" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "139834ddba373bbdd213dffe02c8d110508dcf1726c2be27e8d1f7d7e1856418" +dependencies = [ + "arrayvec", + "auto_impl", + "bytes", +] + +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "rand_core", + "subtle", +] + [[package]] name = "fixed-hash" version = "0.7.0" @@ -585,6 +993,24 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "fixed-hash" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" +dependencies = [ + "byteorder", + "rand", + "rustc-hex", + "static_assertions", +] + +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + [[package]] name = "fnv" version = "1.0.7" @@ -684,7 +1110,7 @@ checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.98", ] [[package]] @@ -725,19 +1151,20 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.5" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", + "zeroize", ] [[package]] name = "getrandom" -version = "0.2.7" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" dependencies = [ "cfg-if", "libc", @@ -800,7 +1227,7 @@ dependencies = [ "quote", "serde", "serde_json", - "syn", + "syn 1.0.98", ] [[package]] @@ -811,14 +1238,25 @@ checksum = "e56b093bfda71de1da99758b036f4cc811fd2511c8a76f75680e9ffbd2bb4251" dependencies = [ "graphql_client_codegen", "proc-macro2", - "syn", + "syn 1.0.98", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core", + "subtle", ] [[package]] name = "h2" -version = "0.3.13" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37a82c6d637fc9515a4694bbf1cb2457b79d81ce52b3108bdeea58b07dd34a57" +checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9" dependencies = [ "bytes", "fnv", @@ -826,7 +1264,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap", + "indexmap 2.2.3", "slab", "tokio", "tokio-util 0.7.3", @@ -839,14 +1277,20 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +[[package]] +name = "hashbrown" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" + [[package]] name = "headers" version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4cff78e5788be1e0ab65b04d306b2ed5092c815ec97ec70f4ebd5aee158aa55d" dependencies = [ - "base64", - "bitflags", + "base64 0.13.0", + "bitflags 1.3.2", "bytes", "headers-core", "http", @@ -893,12 +1337,39 @@ name = "hex" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +dependencies = [ + "serde", +] + +[[package]] +name = "hex-literal" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "home" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +dependencies = [ + "windows-sys 0.52.0", +] [[package]] name = "http" -version = "0.2.8" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" +checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" dependencies = [ "bytes", "fnv", @@ -918,9 +1389,9 @@ dependencies = [ [[package]] name = "httparse" -version = "1.7.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "496ce29bb5a52785b44e0f7ca2847ae0bb839c9bd28f69acac9b99d461c0c04c" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" [[package]] name = "httpdate" @@ -930,9 +1401,9 @@ checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" [[package]] name = "hyper" -version = "0.14.20" +version = "0.14.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02c929dc5c39e335a03c405292728118860721b10190d98c2a0f0efd5baafbac" +checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" dependencies = [ "bytes", "futures-channel", @@ -945,11 +1416,23 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-timeout" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" +dependencies = [ + "hyper", + "pin-project-lite", "tokio", - "tower-service", - "tracing", - "want", + "tokio-io-timeout", ] [[package]] @@ -1026,7 +1509,7 @@ checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.98", ] [[package]] @@ -1036,7 +1519,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" dependencies = [ "autocfg", - "hashbrown", + "hashbrown 0.12.3", +] + +[[package]] +name = "indexmap" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "233cf39063f058ea2caae4091bf4a3ef70a653afbc026f5c4a4135d114e3c177" +dependencies = [ + "equivalent", + "hashbrown 0.14.3", ] [[package]] @@ -1065,9 +1558,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.2" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] name = "js-sys" @@ -1105,12 +1598,36 @@ dependencies = [ "serde_json", ] +[[package]] +name = "k256" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" +dependencies = [ + "cfg-if", + "ecdsa", + "elliptic-curve", + "once_cell", + "sha2", + "signature", +] + [[package]] name = "keccak" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9b7d56ba4a8344d6be9729995e6b06f928af29998cdf79fe390cbf6b1fee838" +[[package]] +name = "keccak-asm" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb8515fff80ed850aea4a1595f2e519c003e2a00a82fe168ebf5269196caf444" +dependencies = [ + "digest 0.10.7", + "sha3-asm", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -1119,9 +1636,21 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.126" +version = "0.2.153" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" + +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + +[[package]] +name = "linux-raw-sys" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" [[package]] name = "lock_api" @@ -1148,7 +1677,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" dependencies = [ - "regex-automata", + "regex-automata 0.1.10", ] [[package]] @@ -1157,6 +1686,12 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" +[[package]] +name = "matchit" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" + [[package]] name = "memchr" version = "2.5.0" @@ -1190,16 +1725,21 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.4" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57ee1c23c7c63b0c9250c339ffdc69255f110b298b901b9f6c82547b7b87caaf" +checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" dependencies = [ "libc", - "log", "wasi", - "windows-sys", + "windows-sys 0.48.0", ] +[[package]] +name = "multimap" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" + [[package]] name = "multipart" version = "0.18.0" @@ -1248,11 +1788,41 @@ version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "195cdbc1741b8134346d515b3a56a1c94b0912758009cfd53f99ea0f57b065fc" dependencies = [ - "bitflags", + "bitflags 1.3.2", "cfg-if", "libc", ] +[[package]] +name = "num-bigint" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +dependencies = [ + "autocfg", + "libm", +] + [[package]] name = "num_cpus" version = "1.13.1" @@ -1274,9 +1844,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.13.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "opaque-debug" @@ -1290,7 +1860,7 @@ version = "0.10.41" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "618febf65336490dfcf20b73f885f5651a0c89c64c2d4a8c3662585a70bf5bd0" dependencies = [ - "bitflags", + "bitflags 1.3.2", "cfg-if", "foreign-types", "libc", @@ -1307,7 +1877,7 @@ checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.98", ] [[package]] @@ -1372,7 +1942,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn", + "syn 1.0.98", ] [[package]] @@ -1384,7 +1954,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn", + "syn 1.0.98", ] [[package]] @@ -1407,15 +1977,42 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-sys", + "windows-sys 0.36.1", ] +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + [[package]] name = "percent-encoding" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" +[[package]] +name = "pest" +version = "2.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "219c0dcc30b6a27553f9cc242972b67f75b60eb0db71f0b5462f38b058c41546" +dependencies = [ + "memchr", + "thiserror", + "ucd-trie", +] + +[[package]] +name = "petgraph" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" +dependencies = [ + "fixedbitset", + "indexmap 2.2.3", +] + [[package]] name = "pin-project" version = "1.0.11" @@ -1433,14 +2030,14 @@ checksum = "710faf75e1b33345361201d36d04e98ac1ed8909151a017ed384700836104c74" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.98", ] [[package]] name = "pin-project-lite" -version = "0.2.9" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" [[package]] name = "pin-utils" @@ -1448,6 +2045,16 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + [[package]] name = "pkg-config" version = "0.3.25" @@ -1460,13 +2067,23 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" +[[package]] +name = "prettyplease" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a41cf62165e97c7f814d2221421dbb9afcbcdb0a88068e5ea206e19951c2cbb5" +dependencies = [ + "proc-macro2", + "syn 2.0.48", +] + [[package]] name = "primitive-types" version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05e4722c697a58a99d5d06a08c30821d7c082a4632198de1eaa5a6c22ef42373" dependencies = [ - "fixed-hash", + "fixed-hash 0.7.0", "impl-codec 0.5.1", "impl-rlp", "impl-serde", @@ -1479,13 +2096,24 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e28720988bff275df1f51b171e1b2a18c30d194c4d2b61defdacecd625a5d94a" dependencies = [ - "fixed-hash", + "fixed-hash 0.7.0", "impl-codec 0.6.0", "impl-rlp", "impl-serde", "uint", ] +[[package]] +name = "primitive-types" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2" +dependencies = [ + "fixed-hash 0.8.0", + "impl-codec 0.6.0", + "uint", +] + [[package]] name = "proc-macro-crate" version = "1.1.3" @@ -1505,7 +2133,7 @@ dependencies = [ "proc-macro-error-attr", "proc-macro2", "quote", - "syn", + "syn 1.0.98", "version_check", ] @@ -1522,9 +2150,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.40" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" dependencies = [ "unicode-ident", ] @@ -1544,6 +2172,80 @@ dependencies = [ "thiserror", ] +[[package]] +name = "proptest" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31b476131c3c86cb68032fdc5cb6d5a1045e3e42d96b69fa599fd77701e1f5bf" +dependencies = [ + "bit-set", + "bit-vec", + "bitflags 2.4.2", + "lazy_static", + "num-traits", + "rand", + "rand_chacha", + "rand_xorshift", + "regex-syntax 0.8.2", + "rusty-fork", + "tempfile", + "unarray", +] + +[[package]] +name = "prost" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "146c289cda302b98a28d40c8b3b90498d6e526dd24ac2ecea73e4e491685b94a" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-build" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c55e02e35260070b6f716a2423c2ff1c3bb1642ddca6f99e1f26d06268a0e2d2" +dependencies = [ + "bytes", + "heck 0.4.0", + "itertools", + "log", + "multimap", + "once_cell", + "petgraph", + "prettyplease", + "prost", + "prost-types", + "regex", + "syn 2.0.48", + "tempfile", + "which", +] + +[[package]] +name = "prost-derive" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" +dependencies = [ + "anyhow", + "itertools", + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "prost-types" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "193898f59edcf43c26227dcd4c8427f00d99d61e95dcde58dabd49fa291d470e" +dependencies = [ + "prost", +] + [[package]] name = "protobuf" version = "2.27.1" @@ -1558,9 +2260,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quote" -version = "1.0.20" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -1600,31 +2302,41 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ "getrandom", ] +[[package]] +name = "rand_xorshift" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" +dependencies = [ + "rand_core", +] + [[package]] name = "redox_syscall" version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] name = "regex" -version = "1.6.0" +version = "1.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" +checksum = "12de2eff854e5fa4b1295edd650e227e9d8fb0c9e90b12e7f36d6a6811791a29" dependencies = [ "aho-corasick", "memchr", - "regex-syntax", + "regex-automata 0.3.7", + "regex-syntax 0.7.5", ] [[package]] @@ -1633,7 +2345,18 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" dependencies = [ - "regex-syntax", + "regex-syntax 0.6.27", +] + +[[package]] +name = "regex-automata" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49530408a136e16e5b486e883fbb6ba058e8e4e8ae6621a77b048b314336e629" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.7.5", ] [[package]] @@ -1642,6 +2365,18 @@ version = "0.6.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" +[[package]] +name = "regex-syntax" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" + +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" + [[package]] name = "remove_dir_all" version = "0.5.3" @@ -1657,7 +2392,7 @@ version = "0.11.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b75aa69a3f06bbcc66ede33af2af253c6f7a86b1ca0033f60c580a27074fbf92" dependencies = [ - "base64", + "base64 0.13.0", "bytes", "encoding_rs", "futures-core", @@ -1688,6 +2423,30 @@ dependencies = [ "winreg", ] +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + +[[package]] +name = "ring" +version = "0.17.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74" +dependencies = [ + "cc", + "getrandom", + "libc", + "spin", + "untrusted", + "windows-sys 0.48.0", +] + [[package]] name = "rlp" version = "0.5.1" @@ -1698,6 +2457,36 @@ dependencies = [ "rustc-hex", ] +[[package]] +name = "ruint" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608a5726529f2f0ef81b8fde9873c4bb829d6b5b5ca6be4d97345ddf0749c825" +dependencies = [ + "alloy-rlp", + "ark-ff 0.3.0", + "ark-ff 0.4.2", + "bytes", + "fastrlp", + "num-bigint", + "num-traits", + "parity-scale-codec 3.1.5", + "primitive-types 0.12.2", + "proptest", + "rand", + "rlp", + "ruint-macro", + "serde", + "valuable", + "zeroize", +] + +[[package]] +name = "ruint-macro" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e666a5496a0b2186dbcd0ff6106e29e093c15591bde62c20d3842007c6978a09" + [[package]] name = "rustc-demangle" version = "0.1.21" @@ -1705,18 +2494,112 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" [[package]] -name = "rustc-hex" -version = "2.1.0" +name = "rustc-hex" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" + +[[package]] +name = "rustc_version" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" +dependencies = [ + "semver 0.11.0", +] + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver 1.0.12", +] + +[[package]] +name = "rustix" +version = "0.38.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" +dependencies = [ + "bitflags 2.4.2", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustls" +version = "0.22.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e87c9956bd9807afa1f77e0f7594af32566e830e088a5576d27c5b6f30f49d41" +dependencies = [ + "log", + "ring", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[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", + "rustls-pki-types", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-pemfile" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c333bb734fcdedcea57de1602543590f545f127dc8b533324318fd492c5c70b" +dependencies = [ + "base64 0.21.7", + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "048a63e5b3ac996d78d402940b5fa47973d2d080c6c6fffa1d0f19c4445310b7" + +[[package]] +name = "rustls-webpki" +version = "0.102.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faaa0a62740bedb9b2ef5afa303da42764c012f743917351dc9a237ea1663610" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + +[[package]] +name = "rustversion" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" [[package]] -name = "rustc_version" -version = "0.4.0" +name = "rusty-fork" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f" dependencies = [ - "semver", + "fnv", + "quick-error", + "tempfile", + "wait-timeout", ] [[package]] @@ -1738,7 +2621,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2" dependencies = [ "lazy_static", - "windows-sys", + "windows-sys 0.36.1", ] [[package]] @@ -1753,6 +2636,20 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] + [[package]] name = "secp256k1" version = "0.21.3" @@ -1777,7 +2674,7 @@ version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dc14f172faf8a0194a3aded622712b0de276821addc574fa54fc0a1167e10dc" dependencies = [ - "bitflags", + "bitflags 1.3.2", "core-foundation", "core-foundation-sys", "libc", @@ -1794,12 +2691,30 @@ dependencies = [ "libc", ] +[[package]] +name = "semver" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" +dependencies = [ + "semver-parser", +] + [[package]] name = "semver" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2333e6df6d6598f2b1974829f853c2b4c5f4a6e503c10af918081aa6f8564e1" +[[package]] +name = "semver-parser" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" +dependencies = [ + "pest", +] + [[package]] name = "serde" version = "1.0.139" @@ -1817,7 +2732,7 @@ checksum = "dc1d3230c1de7932af58ad8ffbe1d784bd55efd5a9d84ac24f69c72d83543dfb" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.98", ] [[package]] @@ -1862,7 +2777,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn", + "syn 1.0.98", ] [[package]] @@ -1886,7 +2801,18 @@ checksum = "028f48d513f9678cda28f6e4064755b3fbb2af6acd672f2c209b62323f7aea0f" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.3", + "digest 0.10.7", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", ] [[package]] @@ -1907,10 +2833,20 @@ version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0a31480366ec990f395a61b7c08122d99bd40544fdb5abcfc1b06bb29994312c" dependencies = [ - "digest 0.10.3", + "digest 0.10.7", "keccak", ] +[[package]] +name = "sha3-asm" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bac61da6b35ad76b195eb4771210f947734321a8d81d7738e1580d953bc7a15e" +dependencies = [ + "cc", + "cfg-if", +] + [[package]] name = "sharded-slab" version = "0.1.4" @@ -1929,6 +2865,16 @@ dependencies = [ "libc", ] +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest 0.10.7", + "rand_core", +] + [[package]] name = "slab" version = "0.4.7" @@ -1946,12 +2892,12 @@ checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1" [[package]] name = "socket2" -version = "0.4.4" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0" +checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" dependencies = [ "libc", - "winapi", + "windows-sys 0.48.0", ] [[package]] @@ -1960,7 +2906,7 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41d1c5305e39e09653383c2c7244f2f78b3bcae37cf50c64cb4789c9f5096ec2" dependencies = [ - "base64", + "base64 0.13.0", "bytes", "futures", "httparse", @@ -1969,6 +2915,22 @@ dependencies = [ "sha-1 0.9.8", ] +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + [[package]] name = "static_assertions" version = "1.1.0" @@ -1981,6 +2943,12 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "subtle" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" + [[package]] name = "syn" version = "1.0.98" @@ -1992,6 +2960,23 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn" +version = "2.0.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + [[package]] name = "synstructure" version = "0.12.6" @@ -2000,7 +2985,7 @@ checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.98", "unicode-xid", ] @@ -2041,22 +3026,22 @@ checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" [[package]] name = "thiserror" -version = "1.0.31" +version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a" +checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.31" +version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a" +checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.48", ] [[package]] @@ -2094,34 +3079,42 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.20.0" +version = "1.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57aec3cfa4c296db7255446efb4928a6be304b431a806216105542a67b6ca82e" +checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" dependencies = [ - "autocfg", + "backtrace", "bytes", "libc", - "memchr", "mio", "num_cpus", - "once_cell", "parking_lot", "pin-project-lite", "signal-hook-registry", "socket2", "tokio-macros", - "winapi", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-io-timeout" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" +dependencies = [ + "pin-project-lite", + "tokio", ] [[package]] name = "tokio-macros" -version = "1.8.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.48", ] [[package]] @@ -2134,6 +3127,17 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-rustls" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" +dependencies = [ + "rustls", + "rustls-pki-types", + "tokio", +] + [[package]] name = "tokio-stream" version = "0.1.9" @@ -2196,6 +3200,76 @@ dependencies = [ "serde", ] +[[package]] +name = "tonic" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76c4eb7a4e9ef9d4763600161f12f5070b92a578e1b634db88a6887844c91a13" +dependencies = [ + "async-stream", + "async-trait", + "axum", + "base64 0.21.7", + "bytes", + "h2", + "http", + "http-body", + "hyper", + "hyper-timeout", + "percent-encoding", + "pin-project", + "prost", + "rustls-native-certs", + "rustls-pemfile", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tokio-stream", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tonic-build" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4ef6dd70a610078cb4e338a0f79d06bc759ff1b22d2120c2ff02ae264ba9c2" +dependencies = [ + "prettyplease", + "proc-macro2", + "prost-build", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "indexmap 1.9.1", + "pin-project", + "pin-project-lite", + "rand", + "slab", + "tokio", + "tokio-util 0.7.3", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + [[package]] name = "tower-service" version = "0.3.2" @@ -2223,7 +3297,7 @@ checksum = "11c75893af559bc8e10716548bdef5cb2b983f8e637db9d0e15126b61b484ee2" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.98", ] [[package]] @@ -2277,7 +3351,7 @@ version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0b2d8558abd2e276b0a8df5c05a2ec762609344191e5fd23e292c910e9165b5" dependencies = [ - "base64", + "base64 0.13.0", "byteorder", "bytes", "http", @@ -2305,11 +3379,17 @@ version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" +[[package]] +name = "ucd-trie" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" + [[package]] name = "uint" -version = "0.9.3" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12f03af7ccf01dd611cc450a0d10dbc9b745770d096473e2faf0ca6e2d66d1e0" +checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" dependencies = [ "byteorder", "crunchy", @@ -2317,6 +3397,12 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "unarray" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" + [[package]] name = "unicase" version = "2.6.0" @@ -2368,6 +3454,12 @@ dependencies = [ "void", ] +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + [[package]] name = "url" version = "2.2.2" @@ -2411,6 +3503,15 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" +[[package]] +name = "wait-timeout" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" +dependencies = [ + "libc", +] + [[package]] name = "want" version = "0.3.0" @@ -2478,7 +3579,7 @@ dependencies = [ "log", "proc-macro2", "quote", - "syn", + "syn 1.0.98", "wasm-bindgen-shared", ] @@ -2512,7 +3613,7 @@ checksum = "7d94ac45fcf608c1f45ef53e748d35660f168490c10b23704c7779ab8f5c3048" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.98", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2540,7 +3641,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44f258e254752d210b84fe117b31f1e3cc9cbf04c0d747eb7f8cf7cf5e370f6d" dependencies = [ "arrayvec", - "base64", + "base64 0.13.0", "bytes", "derive_more", "ethabi 16.0.0", @@ -2581,6 +3682,18 @@ dependencies = [ "url", ] +[[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix", +] + [[package]] name = "winapi" version = "0.3.9" @@ -2618,43 +3731,175 @@ version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" dependencies = [ - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_msvc", + "windows_aarch64_msvc 0.36.1", + "windows_i686_gnu 0.36.1", + "windows_i686_msvc 0.36.1", + "windows_x86_64_gnu 0.36.1", + "windows_x86_64_msvc 0.36.1", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.0", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +dependencies = [ + "windows_aarch64_gnullvm 0.52.0", + "windows_aarch64_msvc 0.52.0", + "windows_i686_gnu 0.52.0", + "windows_i686_msvc 0.52.0", + "windows_x86_64_gnu 0.52.0", + "windows_x86_64_gnullvm 0.52.0", + "windows_x86_64_msvc 0.52.0", ] +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" + [[package]] name = "windows_aarch64_msvc" version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" + [[package]] name = "windows_i686_gnu" version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" + [[package]] name = "windows_i686_msvc" version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" + [[package]] name = "windows_x86_64_gnu" version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" + [[package]] name = "windows_x86_64_msvc" version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" + [[package]] name = "winreg" version = "0.10.1" @@ -2708,3 +3953,23 @@ dependencies = [ "web3", "xshell", ] + +[[package]] +name = "zeroize" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] diff --git a/crates/oracle/Cargo.toml b/crates/oracle/Cargo.toml index 9823c6e4..a920bb4c 100644 --- a/crates/oracle/Cargo.toml +++ b/crates/oracle/Cargo.toml @@ -3,6 +3,10 @@ name = "block-oracle" version = "0.1.0" edition = "2021" +[features] +# Enable to run protobuf messages code generation at compile time (requires protoc, etc.). +proto-gen = [] + [dependencies] anyhow = "1.0.57" async-trait = "0.1.53" @@ -26,7 +30,7 @@ serde = { version = "1.0.136", features = ["derive"] } serde_json = "1" serde_with = "1.1.12" thiserror = "1.0.30" -tokio = { version = "1", features = ["rt", "macros", "sync"] } +tokio = { version = "1.36.0", features = ["rt", "macros", "sync"] } toml = "0.5.8" tracing = "0.1.34" tracing-subscriber = { version = "0.3.11", features = ["env-filter"] } @@ -34,8 +38,15 @@ url = { version = "2.2.2", features = ["serde"] } web3 = { version = "0.18.0", features = ["signing"] } warp = "0.3" either = "1.8.0" +tonic = { version = "0.11.0", features = ["tls", "tls-roots"] } +prost = "0.12.3" +prost-types = "0.12.3" +alloy-primitives = { version = "0.6.3", features = ["serde"] } [dev-dependencies] hyper = { version = "0.14", features = ["full"] } rand = "0.8" serde_json = "1" + +[build-dependencies] +tonic-build = "0.11.0" \ No newline at end of file diff --git a/crates/oracle/build.rs b/crates/oracle/build.rs new file mode 100644 index 00000000..17699897 --- /dev/null +++ b/crates/oracle/build.rs @@ -0,0 +1,69 @@ +use std::env; +use std::path::PathBuf; +use std::process::Command; + +/// Return the path to root of the crate being built. +/// +/// The `CARGO_MANIFEST_DIR` env variable contains the path to the directory containing the +/// manifest for the package being built (the package containing the build script). Also note that +/// this is the value of the current working directory of the build script when it starts. +/// +/// https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-build-scripts +fn root_dir() -> PathBuf { + PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()) +} + +/// Check if all the build requirements are met. +/// +/// This function checks if the following tools are installed: +/// - protoc (required by `prost-build`, see: https://github.com/tokio-rs/prost#protoc) +fn check_build_requirements() -> Result<(), String> { + let mut errors = vec![]; + + // Check if protoc is installed. + let protoc = Command::new("protoc").arg("--version").status().unwrap(); + if !protoc.success() { + errors.push( + "protoc not found. Please install protoc: https://grpc.io/docs/protoc-installation/", + ); + } + + if !errors.is_empty() { + return Err(format!( + "Build requirements not met:\n - {}", + errors.join("\n - ") + )); + } + + Ok(()) +} + +fn main() { + // Run code generation only if 'proto-gen' feature is enabled. + if env::var("CARGO_FEATURE_PROTO_GEN").is_ok() { + // Check if all the build requirements are met. + if let Err(err) = check_build_requirements() { + panic!("{}", err); + } + + let src_dir = root_dir().join("src"); + let proto_dir = root_dir().join("proto"); + + // Streamingfast Blockmeta service gRPC proto files + let sf_blockmeta_proto_dir = proto_dir.join("sf/blockmeta/v2"); + let sf_blockmeta_src_dir = src_dir.join("blockmeta/sf_blockmeta_client"); + + let status = tonic_build::configure() + .build_client(true) + .out_dir(sf_blockmeta_src_dir) + .emit_rerun_if_changed(true) + .compile( + &[sf_blockmeta_proto_dir.join("blockmeta.proto")], + &[sf_blockmeta_proto_dir], + ); + + if let Err(err) = status { + panic!("Protobuf code generation failed: {}", err); + } + } +} diff --git a/crates/oracle/proto/sf/blockmeta/v2/blockmeta.proto b/crates/oracle/proto/sf/blockmeta/v2/blockmeta.proto new file mode 100644 index 00000000..96d7cb20 --- /dev/null +++ b/crates/oracle/proto/sf/blockmeta/v2/blockmeta.proto @@ -0,0 +1,45 @@ +syntax = "proto3"; +package sf.blockmeta.v2; +import "google/protobuf/timestamp.proto"; + +option go_package = "github.com/streamingfast/blockmeta-service;pbbmsrv"; + +service Block { + rpc NumToID (NumToIDReq) returns (BlockResp); + rpc IDToNum(IDToNumReq) returns (BlockResp); + rpc Head(Empty) returns (BlockResp); +} + +message Empty {} + +service BlockByTime { + rpc At (TimeReq) returns (BlockResp); + rpc After (RelativeTimeReq) returns (BlockResp); + rpc Before (RelativeTimeReq) returns (BlockResp); +} + +// Block Requests +message NumToIDReq { + uint64 blockNum = 1; +} + +message IDToNumReq { + string blockID = 1; +} + +// Block & BlockByTime Responses +message BlockResp { + string id = 1; + uint64 num = 2; + google.protobuf.Timestamp time = 3; +} + +// BlockByTime Requests +message TimeReq { + google.protobuf.Timestamp time = 1; +} + +message RelativeTimeReq { + google.protobuf.Timestamp time = 1; + bool inclusive = 2; +} diff --git a/crates/oracle/src/blockmeta/blockmeta_client.rs b/crates/oracle/src/blockmeta/blockmeta_client.rs new file mode 100644 index 00000000..66918648 --- /dev/null +++ b/crates/oracle/src/blockmeta/blockmeta_client.rs @@ -0,0 +1,177 @@ +//! StreamingFast Blockmeta gRPC client. + +use std::collections::BTreeMap; +use std::time::Duration; + +use prost::bytes::Bytes; + +use futures::stream::{FuturesUnordered, StreamExt}; + +use tonic::codegen::{Body, InterceptedService, StdError}; +use tonic::transport::{Channel, Uri}; + +pub use self::auth::AuthInterceptor; +use self::gen::block_client::BlockClient; +pub use self::gen::BlockResp as Block; +use self::gen::Empty; +use crate::{BlockmetaProviderForChain, Caip2ChainId}; + +/// This file is **generated** by the `build.rs` when compiling the crate with the `proto-gen` +/// feature enabled. The `build.rs` script uses the `tonic-build` crate to generate the files. +/// +/// ```shell +/// cargo build --features proto-gen --bin block-oracle +/// ``` +mod gen { + include!("sf_blockmeta_client/sf.blockmeta.v2.rs"); +} + +mod auth { + use tonic::{Request, Status}; + + /// The `AuthInterceptor` is a gRPC interceptor that adds an `authorization` header to the request + /// metadata. + /// + /// This middleware inserts the `authorization` header into the request metadata. The header is + /// expected to be in the format `Bearer `. + /// + /// It is used to authenticate requests to the StreamingFast Blockmeta service. + #[derive(Clone)] + pub struct AuthInterceptor { + header_value: String, + } + + impl AuthInterceptor { + /// Create a new `AuthInterceptor` with the given authorization token. + pub(super) fn with_token(token: &str) -> Self { + Self { + header_value: format!("bearer {}", token), + } + } + } + + impl tonic::service::Interceptor for AuthInterceptor { + fn call(&mut self, mut request: Request<()>) -> Result, Status> { + // The `authorization` header is expected to be in the format `Bearer ` + let auth = self.header_value.parse().map_err(|err| { + Status::new( + tonic::Code::Unauthenticated, + format!("invalid authorization token: {}", err), + ) + })?; + + // Insert the `authorization` header into the request metadata + request.metadata_mut().insert("authorization", auth); + Ok(request) + } + } +} + +/// StreamingFast Blockmeta gRPC client. +/// +/// The `BlockmetaClient` is a gRPC client for the StreamingFast Blockmeta service. It provides +/// method to fetch the latest block. +#[derive(Debug, Clone)] +pub struct BlockmetaClient { + grpc_client: BlockClient, +} + +impl BlockmetaClient { + /// Create a new `BlockmetaClient` with the given gRPC endpoint. + /// + /// The service will connect once the first request is made. It will attempt to connect for + /// 5 seconds before timing out. + pub fn new(endpoint: Uri) -> Self { + let channel = Channel::builder(endpoint) + .tls_config(Default::default()) + .expect("failed to configure TLS") + .connect_timeout(Duration::from_secs(5)) + .connect_lazy(); + Self { + grpc_client: BlockClient::new(channel), + } + } +} + +impl BlockmetaClient> { + /// Create a new `BlockmetaClient` with the given gRPC endpoint and authorization token. + /// + /// The cliient will connect to the given endpoint and authenticate requests with the given + /// authorization token inserted into the `authorization` header by the [`AuthInterceptor`]. + /// + /// The service will connect once the first request is made. It will attempt to connect for + /// 5 seconds before timing out. + pub fn new_with_auth(endpoint: Uri, auth: impl AsRef) -> Self { + let interceptor = AuthInterceptor::with_token(auth.as_ref()); + let channel = Channel::builder(endpoint) + .tls_config(Default::default()) + .expect("failed to configure TLS") + .connect_timeout(Duration::from_secs(5)) + .connect_lazy(); + + Self { + grpc_client: BlockClient::with_interceptor(channel, interceptor), + } + } +} + +impl BlockmetaClient +where + T: tonic::client::GrpcService, + T::Error: Into, + T::ResponseBody: Body + Send + 'static, + ::Error: Into + Send, +{ + /// Fetch the latest block from the StreamingFast Blockmeta service. + /// + /// Returns `None` if the block does not exist. + pub async fn get_latest_block(&mut self) -> anyhow::Result> { + let request = Empty {}; + + match self.grpc_client.head(request).await { + Ok(res) => Ok(Some(res.into_inner())), + Err(err) if err.code() == tonic::Code::NotFound => Ok(None), + Err(err) => Err(anyhow::anyhow!("request failed: {}", err.message())), + } + } +} + +/// Fetches the latest available block number and hash from all `chains`. +pub async fn get_latest_blockmeta_blocks( + chains: &[BlockmetaProviderForChain], +) -> BTreeMap> +where + T: tonic::client::GrpcService, + T::Error: Into, + T::ResponseBody: Body + Send + 'static, + ::Error: Into + Send, + T: std::clone::Clone, +{ + let mut tasks = chains + .iter() + .cloned() + .map(|mut chain| async move { + chain.client.get_latest_block().await.map(|block| { + ( + chain.chain_id, + block.ok_or_else(|| anyhow::anyhow!("Block not found")), + ) + }) + }) + .collect::>(); + + let mut block_ptr_per_chain = BTreeMap::new(); + while let Some(result) = tasks.next().await { + match result { + Ok((chain_id, block)) => { + block_ptr_per_chain.insert(chain_id, block); + } + Err(e) => { + println!("Error: {:?}", e); + } + } + } + + assert!(block_ptr_per_chain.len() == chains.len()); + block_ptr_per_chain +} diff --git a/crates/oracle/src/blockmeta/sf_blockmeta_client/sf.blockmeta.v2.rs b/crates/oracle/src/blockmeta/sf_blockmeta_client/sf.blockmeta.v2.rs new file mode 100644 index 00000000..946e2605 --- /dev/null +++ b/crates/oracle/src/blockmeta/sf_blockmeta_client/sf.blockmeta.v2.rs @@ -0,0 +1,896 @@ +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Empty {} +/// Block Requests +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct NumToIdReq { + #[prost(uint64, tag = "1")] + pub block_num: u64, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct IdToNumReq { + #[prost(string, tag = "1")] + pub block_id: ::prost::alloc::string::String, +} +/// Block & BlockByTime Responses +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct BlockResp { + #[prost(string, tag = "1")] + pub id: ::prost::alloc::string::String, + #[prost(uint64, tag = "2")] + pub num: u64, + #[prost(message, optional, tag = "3")] + pub time: ::core::option::Option<::prost_types::Timestamp>, +} +/// BlockByTime Requests +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct TimeReq { + #[prost(message, optional, tag = "1")] + pub time: ::core::option::Option<::prost_types::Timestamp>, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct RelativeTimeReq { + #[prost(message, optional, tag = "1")] + pub time: ::core::option::Option<::prost_types::Timestamp>, + #[prost(bool, tag = "2")] + pub inclusive: bool, +} +/// Generated client implementations. +pub mod block_client { + #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] + use tonic::codegen::*; + use tonic::codegen::http::Uri; + #[derive(Debug, Clone)] + pub struct BlockClient { + inner: tonic::client::Grpc, + } + impl BlockClient { + /// Attempt to create a new client by connecting to a given endpoint. + pub async fn connect(dst: D) -> Result + where + D: TryInto, + D::Error: Into, + { + let conn = tonic::transport::Endpoint::new(dst)?.connect().await?; + Ok(Self::new(conn)) + } + } + impl BlockClient + where + T: tonic::client::GrpcService, + T::Error: Into, + T::ResponseBody: Body + Send + 'static, + ::Error: Into + Send, + { + pub fn new(inner: T) -> Self { + let inner = tonic::client::Grpc::new(inner); + Self { inner } + } + pub fn with_origin(inner: T, origin: Uri) -> Self { + let inner = tonic::client::Grpc::with_origin(inner, origin); + Self { inner } + } + pub fn with_interceptor( + inner: T, + interceptor: F, + ) -> BlockClient> + where + F: tonic::service::Interceptor, + T::ResponseBody: Default, + T: tonic::codegen::Service< + http::Request, + Response = http::Response< + >::ResponseBody, + >, + >, + , + >>::Error: Into + Send + Sync, + { + BlockClient::new(InterceptedService::new(inner, interceptor)) + } + /// Compress requests with the given encoding. + /// + /// This requires the server to support it otherwise it might respond with an + /// error. + #[must_use] + pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.inner = self.inner.send_compressed(encoding); + self + } + /// Enable decompressing responses. + #[must_use] + pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.inner = self.inner.accept_compressed(encoding); + self + } + /// Limits the maximum size of a decoded message. + /// + /// Default: `4MB` + #[must_use] + pub fn max_decoding_message_size(mut self, limit: usize) -> Self { + self.inner = self.inner.max_decoding_message_size(limit); + self + } + /// Limits the maximum size of an encoded message. + /// + /// Default: `usize::MAX` + #[must_use] + pub fn max_encoding_message_size(mut self, limit: usize) -> Self { + self.inner = self.inner.max_encoding_message_size(limit); + self + } + pub async fn num_to_id( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result, tonic::Status> { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::new( + tonic::Code::Unknown, + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/sf.blockmeta.v2.Block/NumToID", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert(GrpcMethod::new("sf.blockmeta.v2.Block", "NumToID")); + self.inner.unary(req, path, codec).await + } + pub async fn id_to_num( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result, tonic::Status> { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::new( + tonic::Code::Unknown, + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/sf.blockmeta.v2.Block/IDToNum", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert(GrpcMethod::new("sf.blockmeta.v2.Block", "IDToNum")); + self.inner.unary(req, path, codec).await + } + pub async fn head( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result, tonic::Status> { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::new( + tonic::Code::Unknown, + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/sf.blockmeta.v2.Block/Head", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert(GrpcMethod::new("sf.blockmeta.v2.Block", "Head")); + self.inner.unary(req, path, codec).await + } + } +} +/// Generated client implementations. +pub mod block_by_time_client { + #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] + use tonic::codegen::*; + use tonic::codegen::http::Uri; + #[derive(Debug, Clone)] + pub struct BlockByTimeClient { + inner: tonic::client::Grpc, + } + impl BlockByTimeClient { + /// Attempt to create a new client by connecting to a given endpoint. + pub async fn connect(dst: D) -> Result + where + D: TryInto, + D::Error: Into, + { + let conn = tonic::transport::Endpoint::new(dst)?.connect().await?; + Ok(Self::new(conn)) + } + } + impl BlockByTimeClient + where + T: tonic::client::GrpcService, + T::Error: Into, + T::ResponseBody: Body + Send + 'static, + ::Error: Into + Send, + { + pub fn new(inner: T) -> Self { + let inner = tonic::client::Grpc::new(inner); + Self { inner } + } + pub fn with_origin(inner: T, origin: Uri) -> Self { + let inner = tonic::client::Grpc::with_origin(inner, origin); + Self { inner } + } + pub fn with_interceptor( + inner: T, + interceptor: F, + ) -> BlockByTimeClient> + where + F: tonic::service::Interceptor, + T::ResponseBody: Default, + T: tonic::codegen::Service< + http::Request, + Response = http::Response< + >::ResponseBody, + >, + >, + , + >>::Error: Into + Send + Sync, + { + BlockByTimeClient::new(InterceptedService::new(inner, interceptor)) + } + /// Compress requests with the given encoding. + /// + /// This requires the server to support it otherwise it might respond with an + /// error. + #[must_use] + pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.inner = self.inner.send_compressed(encoding); + self + } + /// Enable decompressing responses. + #[must_use] + pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.inner = self.inner.accept_compressed(encoding); + self + } + /// Limits the maximum size of a decoded message. + /// + /// Default: `4MB` + #[must_use] + pub fn max_decoding_message_size(mut self, limit: usize) -> Self { + self.inner = self.inner.max_decoding_message_size(limit); + self + } + /// Limits the maximum size of an encoded message. + /// + /// Default: `usize::MAX` + #[must_use] + pub fn max_encoding_message_size(mut self, limit: usize) -> Self { + self.inner = self.inner.max_encoding_message_size(limit); + self + } + pub async fn at( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result, tonic::Status> { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::new( + tonic::Code::Unknown, + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/sf.blockmeta.v2.BlockByTime/At", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert(GrpcMethod::new("sf.blockmeta.v2.BlockByTime", "At")); + self.inner.unary(req, path, codec).await + } + pub async fn after( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result, tonic::Status> { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::new( + tonic::Code::Unknown, + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/sf.blockmeta.v2.BlockByTime/After", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert(GrpcMethod::new("sf.blockmeta.v2.BlockByTime", "After")); + self.inner.unary(req, path, codec).await + } + pub async fn before( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result, tonic::Status> { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::new( + tonic::Code::Unknown, + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/sf.blockmeta.v2.BlockByTime/Before", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert(GrpcMethod::new("sf.blockmeta.v2.BlockByTime", "Before")); + self.inner.unary(req, path, codec).await + } + } +} +/// Generated server implementations. +pub mod block_server { + #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] + use tonic::codegen::*; + /// Generated trait containing gRPC methods that should be implemented for use with BlockServer. + #[async_trait] + pub trait Block: Send + Sync + 'static { + async fn num_to_id( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status>; + async fn id_to_num( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status>; + async fn head( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status>; + } + #[derive(Debug)] + pub struct BlockServer { + inner: _Inner, + accept_compression_encodings: EnabledCompressionEncodings, + send_compression_encodings: EnabledCompressionEncodings, + max_decoding_message_size: Option, + max_encoding_message_size: Option, + } + struct _Inner(Arc); + impl BlockServer { + pub fn new(inner: T) -> Self { + Self::from_arc(Arc::new(inner)) + } + pub fn from_arc(inner: Arc) -> Self { + let inner = _Inner(inner); + Self { + inner, + accept_compression_encodings: Default::default(), + send_compression_encodings: Default::default(), + max_decoding_message_size: None, + max_encoding_message_size: None, + } + } + pub fn with_interceptor( + inner: T, + interceptor: F, + ) -> InterceptedService + where + F: tonic::service::Interceptor, + { + InterceptedService::new(Self::new(inner), interceptor) + } + /// Enable decompressing requests with the given encoding. + #[must_use] + pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.accept_compression_encodings.enable(encoding); + self + } + /// Compress responses with the given encoding, if the client supports it. + #[must_use] + pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.send_compression_encodings.enable(encoding); + self + } + /// Limits the maximum size of a decoded message. + /// + /// Default: `4MB` + #[must_use] + pub fn max_decoding_message_size(mut self, limit: usize) -> Self { + self.max_decoding_message_size = Some(limit); + self + } + /// Limits the maximum size of an encoded message. + /// + /// Default: `usize::MAX` + #[must_use] + pub fn max_encoding_message_size(mut self, limit: usize) -> Self { + self.max_encoding_message_size = Some(limit); + self + } + } + impl tonic::codegen::Service> for BlockServer + where + T: Block, + B: Body + Send + 'static, + B::Error: Into + Send + 'static, + { + type Response = http::Response; + type Error = std::convert::Infallible; + type Future = BoxFuture; + fn poll_ready( + &mut self, + _cx: &mut Context<'_>, + ) -> Poll> { + Poll::Ready(Ok(())) + } + fn call(&mut self, req: http::Request) -> Self::Future { + let inner = self.inner.clone(); + match req.uri().path() { + "/sf.blockmeta.v2.Block/NumToID" => { + #[allow(non_camel_case_types)] + struct NumToIDSvc(pub Arc); + impl tonic::server::UnaryService + for NumToIDSvc { + type Response = super::BlockResp; + type Future = BoxFuture< + tonic::Response, + tonic::Status, + >; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + ::num_to_id(&inner, request).await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let inner = inner.0; + let method = NumToIDSvc(inner); + let codec = tonic::codec::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.unary(method, req).await; + Ok(res) + }; + Box::pin(fut) + } + "/sf.blockmeta.v2.Block/IDToNum" => { + #[allow(non_camel_case_types)] + struct IDToNumSvc(pub Arc); + impl tonic::server::UnaryService + for IDToNumSvc { + type Response = super::BlockResp; + type Future = BoxFuture< + tonic::Response, + tonic::Status, + >; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + ::id_to_num(&inner, request).await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let inner = inner.0; + let method = IDToNumSvc(inner); + let codec = tonic::codec::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.unary(method, req).await; + Ok(res) + }; + Box::pin(fut) + } + "/sf.blockmeta.v2.Block/Head" => { + #[allow(non_camel_case_types)] + struct HeadSvc(pub Arc); + impl tonic::server::UnaryService + for HeadSvc { + type Response = super::BlockResp; + type Future = BoxFuture< + tonic::Response, + tonic::Status, + >; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + ::head(&inner, request).await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let inner = inner.0; + let method = HeadSvc(inner); + let codec = tonic::codec::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.unary(method, req).await; + Ok(res) + }; + Box::pin(fut) + } + _ => { + Box::pin(async move { + Ok( + http::Response::builder() + .status(200) + .header("grpc-status", "12") + .header("content-type", "application/grpc") + .body(empty_body()) + .unwrap(), + ) + }) + } + } + } + } + impl Clone for BlockServer { + fn clone(&self) -> Self { + let inner = self.inner.clone(); + Self { + inner, + accept_compression_encodings: self.accept_compression_encodings, + send_compression_encodings: self.send_compression_encodings, + max_decoding_message_size: self.max_decoding_message_size, + max_encoding_message_size: self.max_encoding_message_size, + } + } + } + impl Clone for _Inner { + fn clone(&self) -> Self { + Self(Arc::clone(&self.0)) + } + } + impl std::fmt::Debug for _Inner { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{:?}", self.0) + } + } + impl tonic::server::NamedService for BlockServer { + const NAME: &'static str = "sf.blockmeta.v2.Block"; + } +} +/// Generated server implementations. +pub mod block_by_time_server { + #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] + use tonic::codegen::*; + /// Generated trait containing gRPC methods that should be implemented for use with BlockByTimeServer. + #[async_trait] + pub trait BlockByTime: Send + Sync + 'static { + async fn at( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status>; + async fn after( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status>; + async fn before( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status>; + } + #[derive(Debug)] + pub struct BlockByTimeServer { + inner: _Inner, + accept_compression_encodings: EnabledCompressionEncodings, + send_compression_encodings: EnabledCompressionEncodings, + max_decoding_message_size: Option, + max_encoding_message_size: Option, + } + struct _Inner(Arc); + impl BlockByTimeServer { + pub fn new(inner: T) -> Self { + Self::from_arc(Arc::new(inner)) + } + pub fn from_arc(inner: Arc) -> Self { + let inner = _Inner(inner); + Self { + inner, + accept_compression_encodings: Default::default(), + send_compression_encodings: Default::default(), + max_decoding_message_size: None, + max_encoding_message_size: None, + } + } + pub fn with_interceptor( + inner: T, + interceptor: F, + ) -> InterceptedService + where + F: tonic::service::Interceptor, + { + InterceptedService::new(Self::new(inner), interceptor) + } + /// Enable decompressing requests with the given encoding. + #[must_use] + pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.accept_compression_encodings.enable(encoding); + self + } + /// Compress responses with the given encoding, if the client supports it. + #[must_use] + pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.send_compression_encodings.enable(encoding); + self + } + /// Limits the maximum size of a decoded message. + /// + /// Default: `4MB` + #[must_use] + pub fn max_decoding_message_size(mut self, limit: usize) -> Self { + self.max_decoding_message_size = Some(limit); + self + } + /// Limits the maximum size of an encoded message. + /// + /// Default: `usize::MAX` + #[must_use] + pub fn max_encoding_message_size(mut self, limit: usize) -> Self { + self.max_encoding_message_size = Some(limit); + self + } + } + impl tonic::codegen::Service> for BlockByTimeServer + where + T: BlockByTime, + B: Body + Send + 'static, + B::Error: Into + Send + 'static, + { + type Response = http::Response; + type Error = std::convert::Infallible; + type Future = BoxFuture; + fn poll_ready( + &mut self, + _cx: &mut Context<'_>, + ) -> Poll> { + Poll::Ready(Ok(())) + } + fn call(&mut self, req: http::Request) -> Self::Future { + let inner = self.inner.clone(); + match req.uri().path() { + "/sf.blockmeta.v2.BlockByTime/At" => { + #[allow(non_camel_case_types)] + struct AtSvc(pub Arc); + impl tonic::server::UnaryService + for AtSvc { + type Response = super::BlockResp; + type Future = BoxFuture< + tonic::Response, + tonic::Status, + >; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + ::at(&inner, request).await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let inner = inner.0; + let method = AtSvc(inner); + let codec = tonic::codec::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.unary(method, req).await; + Ok(res) + }; + Box::pin(fut) + } + "/sf.blockmeta.v2.BlockByTime/After" => { + #[allow(non_camel_case_types)] + struct AfterSvc(pub Arc); + impl< + T: BlockByTime, + > tonic::server::UnaryService + for AfterSvc { + type Response = super::BlockResp; + type Future = BoxFuture< + tonic::Response, + tonic::Status, + >; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + ::after(&inner, request).await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let inner = inner.0; + let method = AfterSvc(inner); + let codec = tonic::codec::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.unary(method, req).await; + Ok(res) + }; + Box::pin(fut) + } + "/sf.blockmeta.v2.BlockByTime/Before" => { + #[allow(non_camel_case_types)] + struct BeforeSvc(pub Arc); + impl< + T: BlockByTime, + > tonic::server::UnaryService + for BeforeSvc { + type Response = super::BlockResp; + type Future = BoxFuture< + tonic::Response, + tonic::Status, + >; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + ::before(&inner, request).await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let inner = inner.0; + let method = BeforeSvc(inner); + let codec = tonic::codec::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.unary(method, req).await; + Ok(res) + }; + Box::pin(fut) + } + _ => { + Box::pin(async move { + Ok( + http::Response::builder() + .status(200) + .header("grpc-status", "12") + .header("content-type", "application/grpc") + .body(empty_body()) + .unwrap(), + ) + }) + } + } + } + } + impl Clone for BlockByTimeServer { + fn clone(&self) -> Self { + let inner = self.inner.clone(); + Self { + inner, + accept_compression_encodings: self.accept_compression_encodings, + send_compression_encodings: self.send_compression_encodings, + max_decoding_message_size: self.max_decoding_message_size, + max_encoding_message_size: self.max_encoding_message_size, + } + } + } + impl Clone for _Inner { + fn clone(&self) -> Self { + Self(Arc::clone(&self.0)) + } + } + impl std::fmt::Debug for _Inner { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{:?}", self.0) + } + } + impl tonic::server::NamedService for BlockByTimeServer { + const NAME: &'static str = "sf.blockmeta.v2.BlockByTime"; + } +} diff --git a/crates/oracle/src/config.rs b/crates/oracle/src/config.rs index d2794c5e..cbac4109 100644 --- a/crates/oracle/src/config.rs +++ b/crates/oracle/src/config.rs @@ -26,6 +26,12 @@ pub struct IndexedChain { pub jrpc_url: Url, } +#[derive(Clone, Debug)] +pub struct BlockmetaIndexedChain { + pub id: Caip2ChainId, + pub url: String, +} + #[derive(Clone, Debug)] pub struct ProtocolChain { pub id: Caip2ChainId, @@ -85,11 +91,13 @@ pub struct Config { pub bearer_token: String, pub owner_address: H160, pub indexed_chains: Vec, + pub blockmeta_indexed_chains: Vec, pub freshness_threshold: u64, pub protocol_chain: ProtocolChain, pub retry_strategy_max_wait_time: Duration, pub metrics_port: u16, pub transaction_monitoring_options: TransactionMonitoringOptions, + pub blockmeta_auth_token: String, } impl Config { @@ -124,6 +132,15 @@ impl Config { jrpc_url: provider.0, }) .collect::>(), + blockmeta_indexed_chains: config_file + .blockmeta_indexed_chains + .unwrap_or_else(|| HashMap::new()) + .into_iter() + .map(|(id, provider)| BlockmetaIndexedChain { + id, + url: provider.0, + }) + .collect::>(), protocol_chain: ProtocolChain { id: config_file.protocol_chain.name, jrpc_url: config_file.protocol_chain.jrpc.0, @@ -133,6 +150,7 @@ impl Config { }, metrics_port: config_file.metrics_port, transaction_monitoring_options: config_file.transaction_monitoring_options, + blockmeta_auth_token: config_file.blockmeta_auth_token.0, } } } @@ -158,10 +176,12 @@ struct ConfigFile { log_level: FromStrWrapper, protocol_chain: SerdeProtocolChain, indexed_chains: HashMap>, + blockmeta_indexed_chains: Option>>, #[serde(default = "serde_defaults::metrics_port")] metrics_port: u16, #[serde(default, rename = "transaction_monitoring")] transaction_monitoring_options: TransactionMonitoringOptions, + blockmeta_auth_token: EitherLiteralOrEnvVar, } impl ConfigFile { @@ -290,6 +310,15 @@ mod tests { .clone() } + fn blockmeta_indexed_chain(config: &Config, id: &str) -> BlockmetaIndexedChain { + config + .blockmeta_indexed_chains + .iter() + .find(|x| x.id.as_str() == id) + .unwrap() + .clone() + } + fn config_file_path(filename: &str) -> String { format!("{}/test/config/{}", env!("CARGO_MANIFEST_DIR"), filename) } @@ -300,6 +329,12 @@ mod tests { Config::parse(config_file_path("invalid_jrpc_provider_url.toml")); } + #[test] + #[should_panic] + fn invalid_blockmeta_provider_url() { + Config::parse(config_file_path("invalid_blockmeta_provider_url.toml")); + } + #[test] fn example_config() { Config::parse(config_file_path("config.sample.toml")); @@ -317,4 +352,17 @@ mod tests { jrpc_url ); } + + #[test] + fn set_blockmeta_provider_via_env_var() { + let url = "https://sokol-archive.blockscout.com/"; + std::env::set_var("FOOBAR_bip122:77", url); + + let config = Config::parse(config_file_path("indexed_chain_provider_via_env_var.toml")); + + assert_eq!( + blockmeta_indexed_chain(&config, "bip122:77").url.as_str(), + url + ); + } } diff --git a/crates/oracle/src/main.rs b/crates/oracle/src/main.rs index 52e6cd08..c2df6add 100644 --- a/crates/oracle/src/main.rs +++ b/crates/oracle/src/main.rs @@ -12,10 +12,14 @@ use std::path::PathBuf; use web3::transports::Http; pub use config::Config; -pub use models::{Caip2ChainId, JrpcProviderForChain}; +pub use models::{BlockmetaProviderForChain, Caip2ChainId, JrpcProviderForChain}; pub use runner::*; pub use subgraph::{query_subgraph, SubgraphQueryError}; +pub mod blockmeta { + pub mod blockmeta_client; +} + #[tokio::main] async fn main() -> anyhow::Result<()> { match Clap::parse() { diff --git a/crates/oracle/src/models.rs b/crates/oracle/src/models.rs index ca94ca65..4ec37e5c 100644 --- a/crates/oracle/src/models.rs +++ b/crates/oracle/src/models.rs @@ -1,5 +1,8 @@ +use crate::blockmeta::blockmeta_client::{AuthInterceptor, BlockmetaClient}; use serde_with::DeserializeFromStr; use std::{fmt::Display, str::FromStr}; +use tonic::codegen::InterceptedService; +use tonic::transport::{Channel, Uri}; use web3::Web3; #[derive(Clone, Debug)] @@ -23,6 +26,20 @@ where } } +#[derive(Clone, Debug)] +pub struct BlockmetaProviderForChain { + pub chain_id: Caip2ChainId, + pub client: BlockmetaClient, +} + +impl BlockmetaProviderForChain> { + pub fn new(chain_id: Caip2ChainId, url: String, auth: impl AsRef) -> Self { + let uri: Uri = url.parse().unwrap(); + let client = BlockmetaClient::new_with_auth(uri, auth); + Self { chain_id, client } + } +} + /// See https://github.com/ChainAgnostic/CAIPs/blob/master/CAIPs/caip-2.md. #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, DeserializeFromStr)] #[repr(transparent)] diff --git a/crates/oracle/src/runner/oracle.rs b/crates/oracle/src/runner/oracle.rs index a0265ee0..a65fab8f 100644 --- a/crates/oracle/src/runner/oracle.rs +++ b/crates/oracle/src/runner/oracle.rs @@ -1,13 +1,17 @@ use crate::{ + blockmeta::blockmeta_client::{get_latest_blockmeta_blocks, AuthInterceptor}, contracts::Contracts, hex_string, jrpc_utils::{get_latest_block, get_latest_blocks, JrpcExpBackoff}, metrics::METRICS, subgraph::{query_subgraph, SubgraphState}, - Caip2ChainId, Config, Error, JrpcProviderForChain, + BlockmetaProviderForChain, Caip2ChainId, Config, Error, JrpcProviderForChain, }; +use alloy_primitives::BlockHash; use epoch_encoding::{BlockPtr, Encoder, Message, CURRENT_ENCODING_VERSION}; use std::{cmp::Ordering, collections::BTreeMap}; +use tonic::codegen::InterceptedService; +use tonic::transport::Channel; use tracing::{debug, error, info, warn}; /// The main application in-memory state. @@ -15,6 +19,8 @@ pub struct Oracle { config: Config, protocol_chain: JrpcProviderForChain, indexed_chains: Vec>, + blockmeta_indexed_chains: + Vec>>, contracts: Contracts, } @@ -22,6 +28,7 @@ impl Oracle { pub fn new(config: Config) -> Self { let protocol_chain = protocol_chain(&config); let indexed_chains = indexed_chains(&config); + let blockmeta_indexed_chains = blockmeta_indexed_chains(&config); let contracts = Contracts::new( protocol_chain.web3.clone(), config.data_edge_address, @@ -34,6 +41,7 @@ impl Oracle { config, protocol_chain, indexed_chains, + blockmeta_indexed_chains, contracts, } } @@ -146,8 +154,8 @@ impl Oracle { info!("Entering a new epoch."); info!("Collecting latest block information from all indexed chains."); - let latest_blocks_res = get_latest_blocks(&self.indexed_chains).await; - let latest_blocks = latest_blocks_res + let latest_jrpc_blocks_res = get_latest_blocks(&self.indexed_chains).await; + let latest_jrpc_blocks: BTreeMap = latest_jrpc_blocks_res .iter() .filter_map(|(chain_id, res)| -> Option<(Caip2ChainId, BlockPtr)> { match res { @@ -171,6 +179,41 @@ impl Oracle { }) .collect(); + let latest_blockmeta_blocks_res = + get_latest_blockmeta_blocks(&self.blockmeta_indexed_chains).await; + let latest_blockmeta_blocks: BTreeMap = latest_blockmeta_blocks_res + .iter() + .filter_map(|(chain_id, res)| -> Option<(Caip2ChainId, BlockPtr)> { + match res { + Ok(block) => { + METRICS.set_latest_block_number( + chain_id.as_str(), + "blockmeta", + block.num as i64, + ); + let hash: BlockHash = block.id.clone().parse().unwrap(); + let block_ptr = BlockPtr { + number: block.num as u64, + hash: hash.0, + }; + Some((chain_id.clone(), block_ptr)) + } + Err(e) => { + warn!( + chain_id = chain_id.as_str(), + error = e.to_string().as_str(), + "Failed to get latest block from chain. Skipping." + ); + None + } + } + }) + .collect(); + + let latest_blocks: BTreeMap = latest_jrpc_blocks + .into_iter() + .chain(latest_blockmeta_blocks.into_iter()) + .collect(); let payload = set_block_numbers_for_next_epoch(subgraph_state, latest_blocks); let transaction_receipt = self .contracts @@ -314,6 +357,22 @@ fn indexed_chains(config: &Config) -> Vec> .collect() } +fn blockmeta_indexed_chains( + config: &Config, +) -> Vec>> { + config + .blockmeta_indexed_chains + .iter() + .map(|chain| { + BlockmetaProviderForChain::new( + chain.id.clone(), + chain.url.clone(), + config.blockmeta_auth_token.clone(), + ) + }) + .collect() +} + mod freshness { use crate::models::JrpcProviderForChain; use crate::runner::jrpc_utils::calls_in_block_range; diff --git a/crates/oracle/test/config/config.sample.toml b/crates/oracle/test/config/config.sample.toml index ee0507e7..73b1447d 100644 --- a/crates/oracle/test/config/config.sample.toml +++ b/crates/oracle/test/config/config.sample.toml @@ -5,6 +5,7 @@ data_edge_address = "0x0000000000000000000000000000000000000000" epoch_manager_address = "0x0000000000000000000000000000000000000000" subgraph_url = "http://example.com" bearer_token = "token" +blockmeta_auth_token = "token" [protocol_chain] name = "eip155:1" @@ -12,4 +13,4 @@ jrpc = "http://example.com" polling_interval_in_seconds = 5 [indexed_chains] -"spam:42" = "https://example.com" +"spam:42" = "https://example.com" \ No newline at end of file diff --git a/crates/oracle/test/config/indexed_chain_provider_via_env_var.toml b/crates/oracle/test/config/indexed_chain_provider_via_env_var.toml index c95a191c..dc3bb270 100644 --- a/crates/oracle/test/config/indexed_chain_provider_via_env_var.toml +++ b/crates/oracle/test/config/indexed_chain_provider_via_env_var.toml @@ -4,6 +4,7 @@ subgraph_url = "http://localhost:8080" bearer_token = "token" data_edge_address = "e78a0f7e598cc8b0bb87894b0f60dd2a88d6a8ab" epoch_manager_address = "e78a0f7e598cc8b0bb87894b0f60dd2a88d6a8ab" +blockmeta_auth_token = "token" [protocol_chain] name = "eip155:1" @@ -12,3 +13,6 @@ polling_interval_in_seconds = 5 [indexed_chains] "eip155:77" = "$FOOBAR_EIP155:77" + +[blockmeta_indexed_chains] +"bip122:77" = "$FOOBAR_bip122:77" \ No newline at end of file diff --git a/crates/oracle/test/config/invalid_grpc_provider_url.toml b/crates/oracle/test/config/invalid_grpc_provider_url.toml new file mode 100644 index 00000000..4598a190 --- /dev/null +++ b/crates/oracle/test/config/invalid_grpc_provider_url.toml @@ -0,0 +1,17 @@ +# Hardhat's first account. +owner_address = "0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1" +# Deployed in the first block. +contract_address = "0xe78a0f7e598cc8b0bb87894b0f60dd2a88d6a8ab" + +protocol_chain_polling_interval_in_seconds = 5 +blockmeta_auth_token = "token" + +[protocol_chain] +name = "eip155:1" # the CAIP2 network identifier for this chain +jrpc = "http://127.0.0.1:8545/" # The URL to the JSON RPC for this network. Using Ganache in this example. + +[indexed_chains] +"eip155:99" = "https://core-archive.blockscout.com/" # POA Network Core + +[blockmeta_indexed_chains] +"bip122:000000000019d6689c085ae165831e93" = "foobar" \ No newline at end of file diff --git a/crates/oracle/test/config/invalid_jrpc_provider_url.toml b/crates/oracle/test/config/invalid_jrpc_provider_url.toml index 088835f0..73e5057c 100644 --- a/crates/oracle/test/config/invalid_jrpc_provider_url.toml +++ b/crates/oracle/test/config/invalid_jrpc_provider_url.toml @@ -4,7 +4,7 @@ owner_address = "0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1" contract_address = "0xe78a0f7e598cc8b0bb87894b0f60dd2a88d6a8ab" protocol_chain_polling_interval_in_seconds = 5 - +blockmeta_auth_token = "token" [protocol_chain] name = "eip155:1" # the CAIP2 network identifier for this chain diff --git a/k8s/overlays/staging-mainnet/config.toml b/k8s/overlays/staging-mainnet/config.toml index 8775fb70..8703ddf7 100644 --- a/k8s/overlays/staging-mainnet/config.toml +++ b/k8s/overlays/staging-mainnet/config.toml @@ -6,6 +6,7 @@ log_level = "trace" subgraph_url = "https://api.thegraph.com/subgraphs/name/graphprotocol/mainnet-epoch-block-oracle" bearer_token = "TODO" protocol_chain_polling_interval_in_seconds = 30 +blockmeta_auth_token = "$BLOCKMETA_AUTH_TOKEN" [protocol_chain] name = "eip155:1" @@ -16,3 +17,5 @@ polling_interval_in_seconds = 30 "eip155:1" = "$ETHEREUM_MAINNET" "eip155:5" = "$ETHEREUM_GOERLI" "eip155:100" = "$GNOSIS_MAINNET" + +[blockmeta_indexed_chains] \ No newline at end of file From 831aafe75bc1a80eb2ea5cb3574e6f0e949043ba Mon Sep 17 00:00:00 2001 From: Miguel de Elias Date: Fri, 23 Feb 2024 15:18:19 -0300 Subject: [PATCH 2/6] fix: unit test --- crates/oracle/src/config.rs | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/crates/oracle/src/config.rs b/crates/oracle/src/config.rs index cbac4109..ea074466 100644 --- a/crates/oracle/src/config.rs +++ b/crates/oracle/src/config.rs @@ -341,24 +341,19 @@ mod tests { } #[test] - fn set_jrpc_provider_via_env_var() { + fn set_provider_via_env_var() { let jrpc_url = "https://sokol-archive.blockscout.com/"; std::env::set_var("FOOBAR_EIP155:77", jrpc_url); + let url = "https://sokol-archive.blockscout.com/"; + std::env::set_var("FOOBAR_bip122:77", url); + let config = Config::parse(config_file_path("indexed_chain_provider_via_env_var.toml")); assert_eq!( indexed_chain(&config, "eip155:77").jrpc_url.as_str(), jrpc_url ); - } - - #[test] - fn set_blockmeta_provider_via_env_var() { - let url = "https://sokol-archive.blockscout.com/"; - std::env::set_var("FOOBAR_bip122:77", url); - - let config = Config::parse(config_file_path("indexed_chain_provider_via_env_var.toml")); assert_eq!( blockmeta_indexed_chain(&config, "bip122:77").url.as_str(), From ac88212e2e9066a3cf2b33f751fe9477ab25b765 Mon Sep 17 00:00:00 2001 From: Miguel de Elias Date: Fri, 23 Feb 2024 15:27:49 -0300 Subject: [PATCH 3/6] fix: clippy suggestions --- crates/oracle/src/config.rs | 2 +- crates/oracle/src/runner/oracle.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/oracle/src/config.rs b/crates/oracle/src/config.rs index ea074466..73367c36 100644 --- a/crates/oracle/src/config.rs +++ b/crates/oracle/src/config.rs @@ -134,7 +134,7 @@ impl Config { .collect::>(), blockmeta_indexed_chains: config_file .blockmeta_indexed_chains - .unwrap_or_else(|| HashMap::new()) + .unwrap_or_default() .into_iter() .map(|(id, provider)| BlockmetaIndexedChain { id, diff --git a/crates/oracle/src/runner/oracle.rs b/crates/oracle/src/runner/oracle.rs index a65fab8f..1fa8a66a 100644 --- a/crates/oracle/src/runner/oracle.rs +++ b/crates/oracle/src/runner/oracle.rs @@ -193,7 +193,7 @@ impl Oracle { ); let hash: BlockHash = block.id.clone().parse().unwrap(); let block_ptr = BlockPtr { - number: block.num as u64, + number: block.num, hash: hash.0, }; Some((chain_id.clone(), block_ptr)) From 55ec1a494cd760dbfaaeb3b70a6392b85a3d3bb2 Mon Sep 17 00:00:00 2001 From: Miguel de Elias Date: Fri, 23 Feb 2024 15:44:40 -0300 Subject: [PATCH 4/6] fix: clippy suggestion --- crates/oracle/src/subgraph.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/crates/oracle/src/subgraph.rs b/crates/oracle/src/subgraph.rs index a35a5871..bd0a0230 100644 --- a/crates/oracle/src/subgraph.rs +++ b/crates/oracle/src/subgraph.rs @@ -83,8 +83,7 @@ pub async fn query_subgraph( .transpose() .map_err(SubgraphQueryError::BadData)?; let last_payload: Option = data - .payloads - .get(0) + .payloads.first() .map(|p| p.try_into()) .transpose() .map_err(SubgraphQueryError::BadData)?; From 834c99f4a098bfff083b7eae2943fd602a9bded8 Mon Sep 17 00:00:00 2001 From: Miguel de Elias Date: Fri, 23 Feb 2024 16:10:36 -0300 Subject: [PATCH 5/6] fix: fmt suggestion --- crates/oracle/src/subgraph.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/oracle/src/subgraph.rs b/crates/oracle/src/subgraph.rs index bd0a0230..852a4091 100644 --- a/crates/oracle/src/subgraph.rs +++ b/crates/oracle/src/subgraph.rs @@ -83,7 +83,8 @@ pub async fn query_subgraph( .transpose() .map_err(SubgraphQueryError::BadData)?; let last_payload: Option = data - .payloads.first() + .payloads + .first() .map(|p| p.try_into()) .transpose() .map_err(SubgraphQueryError::BadData)?; From ba71ff4719720a60632960c1ba04199ef7c16b03 Mon Sep 17 00:00:00 2001 From: Miguel de Elias Date: Tue, 27 Feb 2024 15:09:53 -0300 Subject: [PATCH 6/6] fix: handle error when block hash parse fails --- crates/oracle/src/runner/oracle.rs | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/crates/oracle/src/runner/oracle.rs b/crates/oracle/src/runner/oracle.rs index 1fa8a66a..36b5dfeb 100644 --- a/crates/oracle/src/runner/oracle.rs +++ b/crates/oracle/src/runner/oracle.rs @@ -191,12 +191,24 @@ impl Oracle { "blockmeta", block.num as i64, ); - let hash: BlockHash = block.id.clone().parse().unwrap(); - let block_ptr = BlockPtr { - number: block.num, - hash: hash.0, - }; - Some((chain_id.clone(), block_ptr)) + + match block.id.clone().parse::() { + Ok(hash) => { + let block_ptr = BlockPtr { + number: block.num, + hash: hash.0, + }; + Some((chain_id.clone(), block_ptr)) + } + Err(e) => { + warn!( + chain_id = chain_id.as_str(), + error = e.to_string().as_str(), + "Failed to parse block hash. Skipping." + ); + None + } + } } Err(e) => { warn!(