From df73c1b1ddd87bfeb9c710d5db59901b824391a9 Mon Sep 17 00:00:00 2001 From: Lohann Paterno Coutinho Ferreira Date: Thu, 26 Oct 2023 16:40:26 -0300 Subject: [PATCH 1/4] Fix event stream panic --- Cargo.lock | 490 ++++++++++++--------- chains/ethereum/server/Cargo.toml | 1 + chains/ethereum/server/src/client.rs | 138 +++--- chains/ethereum/server/src/event_stream.rs | 204 +++++---- chains/ethereum/server/src/lib.rs | 13 +- chains/ethereum/server/src/utils.rs | 55 ++- deny.toml | 1 - 7 files changed, 535 insertions(+), 367 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d7e64ad1..223f5b6f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -138,9 +138,9 @@ dependencies = [ [[package]] name = "ahash" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd" dependencies = [ "getrandom 0.2.10", "once_cell", @@ -149,14 +149,15 @@ dependencies = [ [[package]] name = "ahash" -version = "0.8.3" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" dependencies = [ "cfg-if", "getrandom 0.2.10", "once_cell", "version_check", + "zerocopy", ] [[package]] @@ -263,9 +264,9 @@ dependencies = [ [[package]] name = "async-executor" -version = "1.5.4" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c1da3ae8dabd9c00f453a329dfe1fb28da3c0a72e2478cdcd93171740c20499" +checksum = "4b0c4a4f319e45986f347ee47fef8bf5e81c9abc3f6f58dc2391439f30df65f0" dependencies = [ "async-lock", "async-task", @@ -305,14 +306,15 @@ dependencies = [ [[package]] name = "async-h1" -version = "2.3.3" +version = "2.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8101020758a4fc3a7c326cb42aa99e9fa77cbfb76987c128ad956406fe1f70a7" +checksum = "5d1d1dae8cb2c4258a79d6ed088b7fb9b4763bf4e9b22d040779761e046a2971" dependencies = [ "async-channel", "async-dup", - "async-std", - "futures-core", + "async-global-executor", + "async-io", + "futures-lite", "http-types", "httparse", "log", @@ -333,9 +335,9 @@ dependencies = [ "log", "parking", "polling", - "rustix 0.37.24", + "rustix 0.37.26", "slab", - "socket2 0.4.9", + "socket2 0.4.10", "waker-fn", ] @@ -372,15 +374,15 @@ dependencies = [ "cfg-if", "event-listener 3.0.0", "futures-lite", - "rustix 0.38.18", + "rustix 0.38.20", "windows-sys 0.48.0", ] [[package]] name = "async-signal" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1079d27511f6c038736279421774ef4ad4bdd2e300825f4a48c4cc463a57cedf" +checksum = "d2a5415b7abcdc9cd7d63d6badba5288b2ca017e3fbd4173b8f405449f1a2399" dependencies = [ "async-io", "async-lock", @@ -388,7 +390,7 @@ dependencies = [ "cfg-if", "futures-core", "futures-io", - "rustix 0.38.18", + "rustix 0.38.20", "signal-hook-registry", "slab", "windows-sys 0.48.0", @@ -437,15 +439,15 @@ dependencies = [ [[package]] name = "async-task" -version = "4.4.1" +version = "4.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9441c6b2fe128a7c2bf680a44c34d0df31ce09e5b7e401fcca3faa483dbc921" +checksum = "b4eb2cdb97421e01129ccb49169d8279ed21e829929144f4a22a6e54ac549ca1" [[package]] name = "async-trait" -version = "0.1.73" +version = "0.1.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" +checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" dependencies = [ "proc-macro2", "quote", @@ -547,9 +549,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.4" +version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" [[package]] name = "base64-compat" @@ -669,9 +671,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" [[package]] name = "bitvec" @@ -772,9 +774,9 @@ dependencies = [ [[package]] name = "bounded-collections" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb5b05133427c07c4776906f673ccf36c21b102c9829c641a5b56bd151d44fd6" +checksum = "ca548b6163b872067dc5eb82fd130c56881435e30367d2073594a3d9744120dd" dependencies = [ "log", "parity-scale-codec", @@ -878,7 +880,7 @@ checksum = "e7daec1a2a2129eeba1644b220b4647ec537b0b5d4bfd6876fcc5a540056b592" dependencies = [ "camino", "cargo-platform", - "semver 1.0.19", + "semver 1.0.20", "serde", "serde_json", "thiserror", @@ -1006,7 +1008,7 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5286a0843c21f8367f7be734f89df9b822e0321d8bcce8d6e735aadff7d74979" dependencies = [ - "base64 0.21.4", + "base64 0.21.5", "bech32 0.9.1", "bs58 0.5.0", "digest 0.10.7", @@ -1150,9 +1152,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.9" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" +checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" dependencies = [ "libc", ] @@ -1452,7 +1454,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" dependencies = [ "cfg-if", - "hashbrown 0.14.1", + "hashbrown 0.14.2", "lock_api", "once_cell", "parking_lot_core", @@ -1491,10 +1493,11 @@ dependencies = [ [[package]] name = "deranged" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2696e8a945f658fd14dc3b87242e6b80cd0f36ff04ea560fa39082368847946" +checksum = "0f32d04922c60427da6f9fef14d042d9edddef64cb9d4ce0d64d0685fbeb1fd3" dependencies = [ + "powerfmt", "serde", ] @@ -1783,7 +1786,7 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fe81b5c06ecfdbc71dd845216f225f53b62a10cb8a16c946836a3467f701d05b" dependencies = [ - "base64 0.21.4", + "base64 0.21.5", "bytes", "hex 0.4.3", "k256", @@ -2034,7 +2037,7 @@ checksum = "0e53451ea4a8128fbce33966da71132cf9e1040dcfd2a2084fd7733ada7b2045" dependencies = [ "ethers-core", "reqwest", - "semver 1.0.19", + "semver 1.0.20", "serde", "serde_json", "thiserror", @@ -2076,7 +2079,7 @@ checksum = "6838fa110e57d572336178b7c79e94ff88ef976306852d8cb87d9e5b1fc7c0b5" dependencies = [ "async-trait", "auto_impl", - "base64 0.21.4", + "base64 0.21.5", "bytes", "const-hex", "enr", @@ -2143,7 +2146,7 @@ dependencies = [ "path-slash", "rayon", "regex", - "semver 1.0.19", + "semver 1.0.20", "serde", "serde_json", "solang-parser", @@ -2274,9 +2277,9 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" [[package]] name = "flate2" -version = "1.0.27" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6c98ee8095e9d1dcbf2fcc6d95acccb90d1c81db1e44725c6a984b1dbdfb010" +checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" dependencies = [ "crc32fast", "miniz_oxide", @@ -2372,9 +2375,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "futures" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" +checksum = "da0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335" dependencies = [ "futures-channel", "futures-core", @@ -2387,9 +2390,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" dependencies = [ "futures-core", "futures-sink", @@ -2397,15 +2400,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" +checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" [[package]] name = "futures-executor" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" +checksum = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc" dependencies = [ "futures-core", "futures-task", @@ -2415,9 +2418,9 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" +checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" [[package]] name = "futures-lite" @@ -2446,9 +2449,9 @@ dependencies = [ [[package]] name = "futures-macro" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" dependencies = [ "proc-macro2", "quote", @@ -2457,15 +2460,15 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" +checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" [[package]] name = "futures-task" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" +checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" [[package]] name = "futures-timer" @@ -2479,9 +2482,9 @@ dependencies = [ [[package]] name = "futures-util" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" dependencies = [ "futures-channel", "futures-core", @@ -2654,7 +2657,7 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" dependencies = [ - "ahash 0.7.6", + "ahash 0.7.7", ] [[package]] @@ -2663,14 +2666,14 @@ version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" dependencies = [ - "ahash 0.8.3", + "ahash 0.8.6", ] [[package]] name = "hashbrown" -version = "0.14.1" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12" +checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" dependencies = [ "serde", ] @@ -2873,7 +2876,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite 0.2.13", - "socket2 0.4.9", + "socket2 0.4.10", "tokio", "tower-service", "tracing", @@ -2882,9 +2885,9 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.24.1" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" dependencies = [ "futures-util", "http", @@ -2911,16 +2914,16 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.57" +version = "0.1.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613" +checksum = "8326b86b6cff230b97d0d312a6c40a60726df3332e721f72a1b035f451663b20" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "windows", + "windows-core", ] [[package]] @@ -3010,7 +3013,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897" dependencies = [ "equivalent", - "hashbrown 0.14.1", + "hashbrown 0.14.2", ] [[package]] @@ -3071,9 +3074,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.8.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" [[package]] name = "is-terminal" @@ -3082,7 +3085,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ "hermit-abi", - "rustix 0.38.18", + "rustix 0.38.20", "windows-sys 0.48.0", ] @@ -3112,9 +3115,9 @@ checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "jobserver" -version = "0.1.26" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" +checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" dependencies = [ "libc", ] @@ -3144,9 +3147,9 @@ dependencies = [ [[package]] name = "jsonrpsee" -version = "0.20.1" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ad9b31183a8bcbe843e32ca8554ad2936633548d95a7bb6a8e14c767dea6b05" +checksum = "affdc52f7596ccb2d7645231fc6163bb314630c989b64998f3699a28b4d5d4dc" dependencies = [ "jsonrpsee-client-transport", "jsonrpsee-core", @@ -3159,9 +3162,9 @@ dependencies = [ [[package]] name = "jsonrpsee-client-transport" -version = "0.20.1" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97f2743cad51cc86b0dbfe316309eeb87a9d96a3d7f4dd7a99767c4b5f065335" +checksum = "b5b005c793122d03217da09af68ba9383363caa950b90d3436106df8cabce935" dependencies = [ "futures-util", "http", @@ -3180,9 +3183,9 @@ dependencies = [ [[package]] name = "jsonrpsee-core" -version = "0.20.1" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35dc957af59ce98373bcdde0c1698060ca6c2d2e9ae357b459c7158b6df33330" +checksum = "da2327ba8df2fdbd5e897e2b5ed25ce7f299d345b9736b6828814c3dbd1fd47b" dependencies = [ "anyhow", "async-lock", @@ -3202,9 +3205,9 @@ dependencies = [ [[package]] name = "jsonrpsee-http-client" -version = "0.20.1" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dd865d0072764cb937b0110a92b5f53e995f7101cb346beca03d93a2dea79de" +checksum = "5f80c17f62c7653ce767e3d7288b793dfec920f97067ceb189ebdd3570f2bc20" dependencies = [ "async-trait", "hyper", @@ -3222,9 +3225,9 @@ dependencies = [ [[package]] name = "jsonrpsee-proc-macros" -version = "0.20.1" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cef91b1017a4edb63f65239381c18de39f88d0e0760ab626d806e196f7f51477" +checksum = "29110019693a4fa2dbda04876499d098fa16d70eba06b1e6e2b3f1b251419515" dependencies = [ "heck", "proc-macro-crate", @@ -3235,9 +3238,9 @@ dependencies = [ [[package]] name = "jsonrpsee-types" -version = "0.20.1" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa9e25aec855b2a7d3ed90fded6c41e8c3fb72b63f071e1be3f0004eba19b625" +checksum = "5be0be325642e850ed0bdff426674d2e66b2b7117c9be23a7caef68a2902b7d9" dependencies = [ "anyhow", "beef", @@ -3249,9 +3252,9 @@ dependencies = [ [[package]] name = "jsonrpsee-ws-client" -version = "0.20.1" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d88e35e9dfa89248ae3e92f689c1f0a190ce12d377eba7d2d08e5a7f6cc5694a" +checksum = "bca9cb3933ccae417eb6b08c3448eb1cb46e39834e5b503e395e5e5bd08546c0" dependencies = [ "http", "jsonrpsee-client-transport", @@ -3266,9 +3269,9 @@ version = "8.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6971da4d9c3aa03c3d8f3ff0f4155b534aad021292003895a469716b2a230378" dependencies = [ - "base64 0.21.4", + "base64 0.21.5", "pem", - "ring", + "ring 0.16.20", "serde", "serde_json", "simple_asn1", @@ -3433,9 +3436,9 @@ checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" [[package]] name = "lock_api" -version = "0.4.10" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" dependencies = [ "autocfg", "scopeguard", @@ -3497,7 +3500,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2cffa4ad52c6f791f4f8b15f0c05f9824b2ced1160e88cc393d64fff9a8ac64" dependencies = [ - "rustix 0.38.18", + "rustix 0.38.20", ] [[package]] @@ -3584,9 +3587,9 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.8" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" +checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0" dependencies = [ "libc", "wasi 0.11.0+wasi-snapshot-preview1", @@ -3861,7 +3864,7 @@ version = "0.10.57" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bac25ee399abb46215765b1cb35bc0212377e58a061560d8b29b024fd0430e7c" dependencies = [ - "bitflags 2.4.0", + "bitflags 2.4.1", "cfg-if", "foreign-types", "libc", @@ -3946,9 +3949,9 @@ dependencies = [ [[package]] name = "parking" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e52c774a4c39359c1d1c52e43f73dd91a75a614652c825408eec30c95a9b2067" +checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" [[package]] name = "parking_lot" @@ -3962,13 +3965,13 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.8" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.3.5", + "redox_syscall 0.4.1", "smallvec", "windows-targets 0.48.5", ] @@ -4243,6 +4246,12 @@ dependencies = [ "universal-hash", ] +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -4276,9 +4285,9 @@ dependencies = [ [[package]] name = "primitive-types" -version = "0.12.1" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f3486ccba82358b11a77516035647c34ba167dfa53312630de83b12bd4f3d66" +checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2" dependencies = [ "fixed-hash", "impl-codec", @@ -4470,6 +4479,15 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + [[package]] name = "redox_users" version = "0.4.3" @@ -4503,14 +4521,14 @@ dependencies = [ [[package]] name = "regex" -version = "1.9.6" +version = "1.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebee201405406dbf528b8b672104ae6d6d63e6d118cb10e4d51abbc7b58044ff" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.3.9", - "regex-syntax 0.7.5", + "regex-automata 0.4.3", + "regex-syntax 0.8.2", ] [[package]] @@ -4524,13 +4542,13 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.3.9" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59b23e92ee4318893fa3fe3e6fb365258efbfe6ac6ab30f090cdcbb7aa37efa9" +checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.7.5", + "regex-syntax 0.8.2", ] [[package]] @@ -4545,13 +4563,19 @@ 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 = "reqwest" version = "0.11.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" dependencies = [ - "base64 0.21.4", + "base64 0.21.5", "bytes", "encoding_rs", "futures-core", @@ -4605,11 +4629,25 @@ dependencies = [ "libc", "once_cell", "spin 0.5.2", - "untrusted", + "untrusted 0.7.1", "web-sys", "winapi", ] +[[package]] +name = "ring" +version = "0.17.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb0205304757e5d899b9c2e448b867ffd03ae7f988002e47cd24954391394d0b" +dependencies = [ + "cc", + "getrandom 0.2.10", + "libc", + "spin 0.9.8", + "untrusted 0.9.0", + "windows-sys 0.48.0", +] + [[package]] name = "ripemd" version = "0.1.3" @@ -4870,6 +4908,7 @@ dependencies = [ "futures-timer", "futures-util", "hex 0.4.3", + "pin-project", "rosetta-client", "rosetta-config-ethereum", "rosetta-core", @@ -4991,14 +5030,14 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.19", + "semver 1.0.20", ] [[package]] name = "rustix" -version = "0.36.15" +version = "0.36.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c37f1bd5ef1b5422177b7646cba67430579cfe2ace80f284fee876bca52ad941" +checksum = "6da3636faa25820d8648e0e31c5d519bbb01f72fdf57131f0f5f7da5fed36eab" dependencies = [ "bitflags 1.3.2", "errno", @@ -5010,9 +5049,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.37.24" +version = "0.37.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4279d76516df406a8bd37e7dff53fd37d1a093f997a3c34a5c21658c126db06d" +checksum = "84f3f8f960ed3b5a59055428714943298bf3fa2d4a1d53135084e0544829d995" dependencies = [ "bitflags 1.3.2", "errno", @@ -5024,11 +5063,11 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.18" +version = "0.38.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a74ee2d7c2581cd139b42447d7d9389b889bdaad3a73f1ebb16f2a3237bb19c" +checksum = "67ce50cb2e16c2903e30d1cbccfd8387a74b9d4c938b6a4c5ec6cc7556f7a8a0" dependencies = [ - "bitflags 2.4.0", + "bitflags 2.4.1", "errno", "libc", "linux-raw-sys 0.4.10", @@ -5037,12 +5076,12 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.7" +version = "0.21.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8" +checksum = "446e14c5cda4f3f30fe71863c34ec70f5ac79d6087097ad0bb433e1be5edf04c" dependencies = [ "log", - "ring", + "ring 0.17.5", "rustls-webpki", "sct", ] @@ -5065,17 +5104,17 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" dependencies = [ - "base64 0.21.4", + "base64 0.21.5", ] [[package]] name = "rustls-webpki" -version = "0.101.6" +version = "0.101.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c7d5dece342910d9ba34d259310cae3e0154b873b35408b787b59bce53d34fe" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" dependencies = [ - "ring", - "untrusted", + "ring 0.17.5", + "untrusted 0.9.0", ] [[package]] @@ -5210,9 +5249,9 @@ dependencies = [ [[package]] name = "scale-info" -version = "2.9.0" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35c0a159d0c45c12b20c5a844feb1fe4bea86e28f17b92a5f0c42193634d3782" +checksum = "7f7d66a1128282b7ef025a8ead62a4a9fcf017382ec53b8ffbf4d7bf77bd3c60" dependencies = [ "bitvec", "cfg-if", @@ -5224,9 +5263,9 @@ dependencies = [ [[package]] name = "scale-info-derive" -version = "2.9.0" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "912e55f6d20e0e80d63733872b40e1227c0bce1e1ab81ba67d696339bfd7fd29" +checksum = "abf2c68b89cafb3b8d918dd07b42be0da66ff202cf1155c5739a4e0c1ea0dc19" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -5269,7 +5308,7 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "772575a524feeb803e5b0fcbc6dd9f367e579488197c94c6e4023aad2305774d" dependencies = [ - "ahash 0.8.3", + "ahash 0.8.6", "cfg-if", "hashbrown 0.13.2", ] @@ -5329,12 +5368,12 @@ dependencies = [ [[package]] name = "sct" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" dependencies = [ - "ring", - "untrusted", + "ring 0.17.5", + "untrusted 0.9.0", ] [[package]] @@ -5421,9 +5460,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.19" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad977052201c6de01a8ef2aa3378c4bd23217a056337d1d6da40468d267a4fb0" +checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" dependencies = [ "serde", ] @@ -5448,9 +5487,9 @@ checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" [[package]] name = "serde" -version = "1.0.188" +version = "1.0.190" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +checksum = "91d3c334ca1ee894a2c6f6ad698fe8c435b76d504b13d436f0685d648d6d96f7" dependencies = [ "serde_derive", ] @@ -5466,9 +5505,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.188" +version = "1.0.190" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" +checksum = "67c5609f394e5c2bd7fc51efda478004ea80ef42fee983d5c67a65e34f32c0e3" dependencies = [ "proc-macro2", "quote", @@ -5508,9 +5547,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186" +checksum = "12022b835073e5b11e90a14f86838ceb1c8fb0325b72416845c487ac0fa95e80" dependencies = [ "serde", ] @@ -5540,7 +5579,7 @@ dependencies = [ "serde", "serde_json", "serde_with_macros", - "time 0.3.29", + "time 0.3.30", ] [[package]] @@ -5692,7 +5731,7 @@ dependencies = [ "num-bigint", "num-traits", "thiserror", - "time 0.3.29", + "time 0.3.30", ] [[package]] @@ -5742,7 +5781,7 @@ dependencies = [ "arrayvec 0.7.4", "async-lock", "atomic", - "base64 0.21.4", + "base64 0.21.5", "bip39", "blake2-rfc", "bs58 0.5.0", @@ -5754,7 +5793,7 @@ dependencies = [ "fnv", "futures-channel", "futures-util", - "hashbrown 0.14.1", + "hashbrown 0.14.2", "hex 0.4.3", "hmac 0.12.1", "itertools 0.10.5", @@ -5799,7 +5838,7 @@ dependencies = [ "fnv", "futures-channel", "futures-util", - "hashbrown 0.14.1", + "hashbrown 0.14.2", "hex 0.4.3", "itertools 0.10.5", "log", @@ -5832,9 +5871,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" dependencies = [ "libc", "winapi", @@ -5842,9 +5881,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.5.4" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e" +checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" dependencies = [ "libc", "windows-sys 0.48.0", @@ -6170,7 +6209,7 @@ version = "22.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48e4eeb7ef23f79eba8609db79ef9cef242f994f1f87a3c0387b4b5f177fda74" dependencies = [ - "ahash 0.8.3", + "ahash 0.8.6", "hash-db", "hashbrown 0.13.2", "lazy_static", @@ -6359,7 +6398,7 @@ version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" dependencies = [ - "strum_macros 0.25.2", + "strum_macros 0.25.3", ] [[package]] @@ -6377,9 +6416,9 @@ dependencies = [ [[package]] name = "strum_macros" -version = "0.25.2" +version = "0.25.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad8d03b598d3d0fff69bf533ee3ef19b8eeb342729596df84bcc7e1f96ec4059" +checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" dependencies = [ "heck", "proc-macro2", @@ -6533,15 +6572,15 @@ dependencies = [ [[package]] name = "sval" -version = "2.10.1" +version = "2.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e55089b73dfa822e1eb6b635f8795215512cca94bfae11aee3a1a06228bc88bb" +checksum = "b15df12a8db7c216a04b4b438f90d50d5335cd38f161b56389c9f5c9d96d0873" [[package]] name = "sval_buffer" -version = "2.10.1" +version = "2.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df307823073d63f1fb126895439fead41afc493ea35d636cceedef9f6b32ba81" +checksum = "57e80556bc8acea0446e574ce542ad6114a76a0237f28a842bc01ca3ea98f479" dependencies = [ "sval", "sval_ref", @@ -6549,18 +6588,18 @@ dependencies = [ [[package]] name = "sval_dynamic" -version = "2.10.1" +version = "2.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5f8e4c4d6d028d3cbff66c2bb3d98181d031d312b7df4550eea7142d7036f37" +checksum = "9d93d2259edb1d7b4316179f0a98c62e3ffc726f47ab200e07cfe382771f57b8" dependencies = [ "sval", ] [[package]] name = "sval_fmt" -version = "2.10.1" +version = "2.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad53f8eb502b0a3051fea001ae2e3723044699868ebfe06ea81b45545db392c2" +checksum = "532f7f882226f7a5a4656f5151224aaebf8217e0d539cb1595b831bace921343" dependencies = [ "itoa", "ryu", @@ -6569,9 +6608,9 @@ dependencies = [ [[package]] name = "sval_json" -version = "2.10.1" +version = "2.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f913253c9f6cd27645ba9a0b6788039b5d4338eae0833c64b42ef178168d2862" +checksum = "76e03bd8aa0ae6ee018f7ae95c9714577687a4415bd1a5f19b26e34695f7e072" dependencies = [ "itoa", "ryu", @@ -6580,18 +6619,18 @@ dependencies = [ [[package]] name = "sval_ref" -version = "2.10.1" +version = "2.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66a9661412d06740ebe81512a527b3d9220460eb7685f4399232c0e670108cb7" +checksum = "75ed054f2fb8c2a0ab5d36c1ec57b412919700099fc5e32ad8e7a38b23e1a9e1" dependencies = [ "sval", ] [[package]] name = "sval_serde" -version = "2.10.1" +version = "2.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8d077e98c1c8dfa466837ae0ec1e03c78138d42ac75662dac05e1bf0aebae20" +checksum = "7ff191c4ff05b67e3844c161021427646cde5d6624597958be158357d9200586" dependencies = [ "serde", "sval", @@ -6610,7 +6649,7 @@ dependencies = [ "hex 0.4.3", "once_cell", "reqwest", - "semver 1.0.19", + "semver 1.0.20", "serde", "serde_json", "sha2 0.10.8", @@ -6681,9 +6720,9 @@ dependencies = [ [[package]] name = "target-lexicon" -version = "0.12.11" +version = "0.12.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d0e916b1148c8e263850e1ebcbd046f333e0683c724876bb0da63ea4373dc8a" +checksum = "14c39fd04924ca3a864207c66fc2cd7d22d7c016007f9ce846cbb9326331930a" [[package]] name = "tempfile" @@ -6694,7 +6733,7 @@ dependencies = [ "cfg-if", "fastrand 2.0.1", "redox_syscall 0.3.5", - "rustix 0.38.18", + "rustix 0.38.20", "windows-sys 0.48.0", ] @@ -6720,9 +6759,9 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.49" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1177e8c6d7ede7afde3585fd2513e611227efd6481bd78d2e82ba1ce16557ed4" +checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" dependencies = [ "thiserror-impl", ] @@ -6749,9 +6788,9 @@ dependencies = [ [[package]] name = "thiserror-impl" -version = "1.0.49" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" +checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" dependencies = [ "proc-macro2", "quote", @@ -6807,14 +6846,15 @@ dependencies = [ [[package]] name = "time" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "426f806f4089c493dcac0d24c29c01e2c38baf8e30f1b716ee37e83d200b18fe" +checksum = "c4a34ab300f2dee6e562c10a046fc05e358b29f9bf92277f30c3c8d82275f6f5" dependencies = [ "deranged", "itoa", "libc", "num_threads", + "powerfmt", "serde", "time-core", "time-macros 0.2.15", @@ -6915,7 +6955,7 @@ dependencies = [ "parking_lot", "pin-project-lite 0.2.13", "signal-hook-registry", - "socket2 0.5.4", + "socket2 0.5.5", "tokio-macros", "windows-sys 0.48.0", ] @@ -6992,9 +7032,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.9" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d68074620f57a0b21594d9735eb2e98ab38b17f80d3fcb189fca266771ca60d" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" dependencies = [ "bytes", "futures-core", @@ -7019,9 +7059,9 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.3" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" dependencies = [ "serde", ] @@ -7068,11 +7108,10 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" [[package]] name = "tracing" -version = "0.1.37" +version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ - "cfg-if", "log", "pin-project-lite 0.2.13", "tracing-attributes", @@ -7081,9 +7120,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.26" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", @@ -7092,9 +7131,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.31" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", "valuable", @@ -7112,12 +7151,12 @@ dependencies = [ [[package]] name = "tracing-log" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" +checksum = "f751112709b4e791d8ce53e32c4ed2d353565a795ce84da2285393f41557bdf2" dependencies = [ - "lazy_static", "log", + "once_cell", "tracing-core", ] @@ -7284,6 +7323,12 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + [[package]] name = "url" version = "2.4.1" @@ -7320,9 +7365,9 @@ checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" [[package]] name = "value-bag" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d92ccd67fb88503048c01b59152a04effd0782d035a83a6d256ce6085f08f4a3" +checksum = "4a72e1902dde2bd6441347de2b70b7f5d59bf157c6c62f0c44572607a1d55bbe" dependencies = [ "value-bag-serde1", "value-bag-sval2", @@ -7330,9 +7375,9 @@ dependencies = [ [[package]] name = "value-bag-serde1" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0b9f3feef403a50d4d67e9741a6d8fc688bcbb4e4f31bd4aab72cc690284394" +checksum = "07ba39dc791ecb35baad371a3fc04c6eab688c04937d2e0ac6c22b612c0357bf" dependencies = [ "erased-serde", "serde", @@ -7341,9 +7386,9 @@ dependencies = [ [[package]] name = "value-bag-sval2" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30b24f4146b6f3361e91cbf527d1fb35e9376c3c0cef72ca5ec5af6d640fad7d" +checksum = "c3e06c10810a57bbf45778d023d432a50a1daa7d185991ae06bcfb6c654d0945" dependencies = [ "sval", "sval_buffer", @@ -7368,7 +7413,7 @@ checksum = "85e7dc29b3c54a2ea67ef4f953d5ec0c4085035c0ae2d325be1c0d2144bd9f16" dependencies = [ "anyhow", "rustversion", - "time 0.3.29", + "time 0.3.30", ] [[package]] @@ -7646,7 +7691,7 @@ dependencies = [ "memoffset 0.8.0", "paste", "rand 0.8.5", - "rustix 0.36.15", + "rustix 0.36.16", "wasmtime-asm-macros", "wasmtime-environ", "wasmtime-jit-debug", @@ -7713,10 +7758,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] -name = "windows" -version = "0.48.0" +name = "windows-core" +version = "0.51.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" dependencies = [ "windows-targets 0.48.5", ] @@ -7855,9 +7900,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "winnow" -version = "0.5.16" +version = "0.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "037711d82167854aff2018dfd193aa0fef5370f456732f0d5a0c59b0f1b4b907" +checksum = "a3b801d0e0a6726477cc207f60162da452f3a95adb368399bef20a946e06f65c" dependencies = [ "memchr", ] @@ -7921,6 +7966,26 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff4524214bc4629eba08d78ceb1d6507070cc0bcbbed23af74e19e6e924a24cf" +[[package]] +name = "zerocopy" +version = "0.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81ba595b9f2772fbee2312de30eeb80ec773b4cb2f1e8098db024afadda6c06f" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "772666c41fb6dceaf520b564b962d738a8e1a83b41bd48945f50837aed78bb1d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + [[package]] name = "zeroize" version = "1.6.0" @@ -7957,7 +8022,7 @@ dependencies = [ "hmac 0.12.1", "pbkdf2 0.11.0", "sha1 0.10.6", - "time 0.3.29", + "time 0.3.30", "zstd", ] @@ -7982,11 +8047,10 @@ dependencies = [ [[package]] name = "zstd-sys" -version = "2.0.8+zstd.1.5.5" +version = "2.0.9+zstd.1.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5556e6ee25d32df2586c098bbfa278803692a20d0ab9565e049480d52707ec8c" +checksum = "9e16efa8a874a0481a574084d34cc26fdb3b99627480f785888deb6386506656" dependencies = [ "cc", - "libc", "pkg-config", ] diff --git a/chains/ethereum/server/Cargo.toml b/chains/ethereum/server/Cargo.toml index 9cd01862..2ba4a241 100644 --- a/chains/ethereum/server/Cargo.toml +++ b/chains/ethereum/server/Cargo.toml @@ -15,6 +15,7 @@ ethers = { version = "2.0", default-features = true, features = ["abigen", "rust futures-timer = "3.0" futures-util = "0.3" hex = "0.4" +pin-project = "1.0" rosetta-config-ethereum = { version = "0.4.0", path = "../config" } rosetta-core = { version = "0.4.0", path = "../../../rosetta-core" } rosetta-ethereum-rpc-client = { version = "0.1.0", path = "../rpc-client" } diff --git a/chains/ethereum/server/src/client.rs b/chains/ethereum/server/src/client.rs index e2a69f6b..755edd1a 100644 --- a/chains/ethereum/server/src/client.rs +++ b/chains/ethereum/server/src/client.rs @@ -1,4 +1,8 @@ -use crate::{event_stream::EthereumEventStream, proof::verify_proof}; +use crate::{ + event_stream::EthereumEventStream, + proof::verify_proof, + utils::{get_non_pending_block, NonPendingBlock}, +}; use anyhow::{bail, Context, Result}; use ethabi::token::{LenientTokenizer, Tokenizer}; use ethers::{ @@ -29,10 +33,36 @@ impl Detokenize for Detokenizer { } } +/// Strategy used to determine the finalized block +#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)] +pub enum BlockFinalityStrategy { + /// Query the finalized block using `eth_getBlockByNumber("finalized")` json-rpc method + #[default] + Finalized, + /// Use the number of confirmations to determine the finalized block + Confirmations(u64), + // TODO: ISSUE-176 for polygon the finalized block is stored on ethereum mainnet + // Polygon, +} + +impl BlockFinalityStrategy { + pub fn from_config(config: &BlockchainConfig) -> Self { + match (config.blockchain, config.testnet) { + // TODO: ISSUE-176 Replace this hack by querying polygon checkpoints + // Polygon finalized blocks are stored on ethereum mainnet roughly every 30 minutes + // and polygon block interval is ~2 seconds, 30 minutes / 2 seconds == 900 blocks. + ("polygon", false) => Self::Confirmations(900), + ("polygon", true) => Self::Confirmations(6), // For local testnet use 6 confirmations + _ => Self::Finalized, + } + } +} + pub struct EthereumClient

{ config: BlockchainConfig, client: Arc>, - genesis_block: BlockIdentifier, + genesis_block: NonPendingBlock, + block_finality_strategy: BlockFinalityStrategy, } impl

Clone for EthereumClient

{ @@ -41,23 +71,24 @@ impl

Clone for EthereumClient

{ config: self.config.clone(), client: self.client.clone(), genesis_block: self.genesis_block.clone(), + block_finality_strategy: self.block_finality_strategy, } } } impl

EthereumClient

where - P: JsonRpcClient, + P: JsonRpcClient + 'static, { pub async fn new(config: BlockchainConfig, rpc_client: P) -> Result { + let block_finality_strategy = BlockFinalityStrategy::from_config(&config); let client = Arc::new(Provider::new(rpc_client)); - let Some(genesis_hash) = - client.get_block(0).await?.context("Failed to get genesis block")?.hash + let Some(genesis_block) = + get_non_pending_block(Arc::clone(&client), BlockNumber::Number(0.into())).await? else { - anyhow::bail!("FATAL: genesis block doesn't have hash"); + anyhow::bail!("FATAL: genesis block not found"); }; - let genesis_block = BlockIdentifier { index: 0, hash: hex::encode(genesis_hash) }; - Ok(Self { config, client, genesis_block }) + Ok(Self { config, client, genesis_block, block_finality_strategy }) } pub const fn config(&self) -> &BlockchainConfig { @@ -65,7 +96,7 @@ where } pub const fn genesis_block(&self) -> &BlockIdentifier { - &self.genesis_block + &self.genesis_block.identifier } pub async fn node_version(&self) -> Result { @@ -81,49 +112,55 @@ where Ok(BlockIdentifier { index, hash: hex::encode(block_hash) }) } - pub async fn finalized_block(&self) -> Result { - // TODO: ISSUE-176 Create a new connector for polygon - let block = if self.config.blockchain == "polygon" || self.config.blockchain == "Arbitrum" { - let Some(latest_block) = - self.client.get_block(BlockId::Number(BlockNumber::Latest)).await? - else { - return Ok(self.genesis_block.clone()); - }; - - let Some(block_number) = latest_block.number else { - // This error should not happen once we query the latest block, not pending one. - anyhow::bail!("This is a bug, latest block doesn't have block number"); - }; + pub async fn finalized_block(&self, latest_block: Option) -> Result { + let number = match self.block_finality_strategy { + BlockFinalityStrategy::Confirmations(confirmations) => { + let latest_block = match latest_block { + Some(number) => number, + None => self + .client + .get_block_number() + .await + .context("Failed to retrieve latest block number")? + .as_u64(), + }; + let block_number = latest_block.saturating_sub(confirmations); + // If the number is zero, the latest finalized is the genesis block + if block_number == 0 { + return Ok(self.genesis_block.clone()); + } + BlockNumber::Number(U64::from(block_number)) + }, + BlockFinalityStrategy::Finalized => BlockNumber::Finalized, + }; - // TODO: ISSUE-176 Replace this hack by querying polygon checkpoints - // Polygon finalized blocks are stored on ethereum mainnet roughly every 30 minutes - // and polygon block interval is ~2 seconds, 30 minutes / 2 seconds == 900 blocks. - let block_number = block_number.saturating_sub(U64::from(900u32)); - if block_number.is_zero() { - return Ok(self.genesis_block.clone()); - } - - let Some(finalized_block) = self - .client - .get_block(BlockId::Number(BlockNumber::Number(block_number))) - .await? - else { - anyhow::bail!("Cannot find block number {block_number}"); - }; - - finalized_block - } else if let Some(finalized_block) = - self.client.get_block(BlockId::Number(BlockNumber::Finalized)).await? - { - finalized_block - } else { - return Ok(self.genesis_block.clone()); + let Some(finalized_block) = get_non_pending_block(Arc::clone(&self.client), number).await? + else { + anyhow::bail!("Cannot find finalized block at {number}"); }; + Ok(finalized_block) - Ok(BlockIdentifier { - index: block.number.context("Block is pending")?.as_u64(), - hash: hex::encode(block.hash.context("Block is pending")?), - }) + // TODO: ISSUE-176 Create a new connector for polygon + // if matches!(self.config.blockchain, "polygon" | "arbitrum") { + // // TODO: ISSUE-176 Replace this hack by querying polygon checkpoints + // // Polygon finalized blocks are stored on ethereum mainnet roughly every 30 minutes + // // and polygon block interval is ~2 seconds, 30 minutes / 2 seconds == 900 blocks. + // let block_number = latest_block.number.saturating_sub(900u64); + // if block_number == 0 { + // return Ok(self.genesis_block.clone()); + // } + + // let Some(finalized_block) = get_non_pending_block(Arc::clone(&self.client), + // U64::from(block_number)).await? else { anyhow::bail!("Cannot find block + // number {block_number}"); }; + + // return Ok(finalized_block); + // } + + // let Some(finalized_block) = get_non_pending_block(Arc::clone(&self.client), + // BlockNumber::Finalized).await? else { anyhow::bail!("Cannot find block number + // {block_number}"); }; + // Ok(finalized_block) } pub async fn balance(&self, address: &Address, block: &BlockIdentifier) -> Result { @@ -400,6 +437,7 @@ where { pub async fn listen(&self) -> Result> { let new_head_subscription = self.client.subscribe_blocks().await?; - Ok(EthereumEventStream::new(Arc::clone(&self.client), new_head_subscription)) + // let get_finalized = self.finalized_block(None); + Ok(EthereumEventStream::new(self, new_head_subscription)) } } diff --git a/chains/ethereum/server/src/event_stream.rs b/chains/ethereum/server/src/event_stream.rs index bf4d60f2..dc3baecc 100644 --- a/chains/ethereum/server/src/event_stream.rs +++ b/chains/ethereum/server/src/event_stream.rs @@ -1,14 +1,18 @@ +use crate::{client::EthereumClient, utils::NonPendingBlock}; use ethers::{prelude::*, providers::PubsubClient}; use futures_util::{future::BoxFuture, FutureExt}; -use rosetta_core::{stream::Stream, types::BlockIdentifier, BlockOrIdentifier, ClientEvent}; -use std::{pin::Pin, sync::Arc, task::Poll}; +use rosetta_core::{stream::Stream, BlockOrIdentifier, ClientEvent}; +use std::{pin::Pin, task::Poll}; // Maximum number of failures in sequence before closing the stream const FAILURE_THRESHOLD: u32 = 10; +#[pin_project::pin_project(project=EthereumEventStreamProjection)] pub struct EthereumEventStream<'a, P: PubsubClient> { /// Ethereum client - pub client: Arc>, + // #[pin] + pub client: &'a crate::EthereumClient

, + // pub client: Arc>, /// Ethereum subscription for new heads pub new_head: Option>>, /// Count the number of failed attempts to retrieve the finalized block @@ -17,49 +21,71 @@ pub struct EthereumEventStream<'a, P: PubsubClient> { pub latest_block_failures: u32, /// Cache the best finalized block, we use this to avoid emitting two /// [`ClientEvent::NewFinalized`] for the same block - pub best_finalized_block: Option, + pub best_finalized_block: Option, + /// Cache the latest block, used for retrieve the latest finalized block + /// see [`BlockFinalityStrategy`] + pub latest_block: Option, /// Ethereum client doesn't support subscribing for finalized blocks, as workaround /// everytime we receive a new head, we query the latest finalized block - pub finalized_block_future: - Option>, ProviderError>>>, + pub finalized_block_future: Option>>, } -impl<'a, P> EthereumEventStream<'a, P> +impl

EthereumEventStream<'_, P> where P: PubsubClient + 'static, { - pub fn new( - client: Arc>, + pub fn new<'a>( + // client: Arc>, + client: &'a crate::EthereumClient

, subscription: SubscriptionStream<'a, P, Block>, - ) -> Self { - Self { + ) -> EthereumEventStream<'a, P> { + EthereumEventStream { client, new_head: Some(subscription), finalized_block_failures: 0, latest_block_failures: 0, best_finalized_block: None, finalized_block_future: None, + latest_block: None, } } - fn finalized_block(&self) -> BoxFuture<'static, Result>, ProviderError>> { - // Clone client to make BoxFuture 'static - let client = Arc::clone(&self.client); - async move { client.get_block(BlockId::Number(BlockNumber::Finalized)).await }.boxed() - } + // fn finalized_block<'a>(self: Pin<&'a mut Self>) -> BoxFuture<'a, + // anyhow::Result> { self.client.finalized_block(None).boxed() + // // Clone client to make BoxFuture 'static + // // let client = Arc::clone(&self.client); + // // async move { client.get_block(BlockId::Number(BlockNumber::Finalized)).await }.boxed() + // } + + // fn finalized_block<'a, 'b: 'a>(self: &mut Pin<&'b mut Self>) { + // let fut = EthereumClient::finalized_block(self.client, None).boxed(); + // let this = self.project(); + // *this.finalized_block_future = Some(fut); + // // (&mut *self).finalized_block_future = Some(self.client.finalized_block(None).boxed()); + // // Clone client to make BoxFuture 'static + // // let client = Arc::clone(&self.client); + // // async move { client.get_block(BlockId::Number(BlockNumber::Finalized)).await }.boxed() + // } } -/// Converts [`Block`] to [`BlockIdentifier`] -fn block_to_identifier(block: &Block) -> Result { - let Some(number) = block.number else { return Err("block number is missing") }; - - let Some(hash) = block.hash else { return Err("block hash is missing") }; - - Ok(BlockIdentifier::new(number.as_u64(), hex::encode(hash))) +impl<'a, 'b, P> EthereumEventStreamProjection<'a, 'b, P> +where + P: PubsubClient + 'static, +{ + fn finalized_block(&self) -> BoxFuture<'b, anyhow::Result> { + let latest_block_number = self.latest_block.as_ref().map(|block| block.number); + let client = &self.client; + EthereumClient::finalized_block(client, latest_block_number).boxed() + } + // fn inc_finalized_failures(&mut self) { + // let failures = *self.finalized_block_failures; + // std::mem::replace(self.finalized_block_failures, failures + 1); + // // Clone client to make BoxFuture 'static + // // let client = Arc::clone(&self.client); + // // async move { client.get_block(BlockId::Number(BlockNumber::Finalized)).await }.boxed() + // } } -impl<'a, P> Unpin for EthereumEventStream<'a, P> where P: PubsubClient {} - impl

Stream for EthereumEventStream<'_, P> where P: PubsubClient + 'static, @@ -67,87 +93,72 @@ where type Item = ClientEvent; fn poll_next( - mut self: Pin<&mut Self>, + self: Pin<&mut Self>, cx: &mut std::task::Context<'_>, ) -> Poll> { - let this = &mut *self; - // Check if the stream is close - if this.new_head.is_none() && this.finalized_block_future.is_none() { + if self.new_head.is_none() && self.finalized_block_future.is_none() { return Poll::Ready(None); } + let this = self.project(); + // Query the latest finalized block - if let Some(mut finalized_block_future) = this.finalized_block_future.take() { - loop { - if this.finalized_block_failures >= FAILURE_THRESHOLD { - return Poll::Ready(Some(ClientEvent::Close( - "More than 10 failures in sequence".into(), - ))); - } - - match finalized_block_future.poll_unpin(cx) { - Poll::Ready(Ok(Some(block))) => { - // Convert raw block to block identifier - let block_identifier = match block_to_identifier(&block) { - Ok(block_identifier) => block_identifier, - Err(error) => { - this.finalized_block_failures += 1; - tracing::error!("finalized block: {error}"); - break; - }, - }; - - // Reset failure counter - this.finalized_block_failures = 0; - - // Skip if the finalized block is equal to the best finalized block - if let Some(best_finalized_block) = this.best_finalized_block.take() { - if block_identifier == best_finalized_block { - tracing::debug!("finalized block unchanged"); - this.best_finalized_block = Some(best_finalized_block); - break; - } + loop { + let Some(mut finalized_block_future) = this.finalized_block_future.take() else { + break; + }; + match finalized_block_future.poll_unpin(cx) { + Poll::Ready(Ok(block)) => { + // Reset failure counter + *this.finalized_block_failures = 0; + + // Skip if the finalized block is equal to the best finalized block + if let Some(best_finalized_block) = this.best_finalized_block.take() { + if block.hash == best_finalized_block.hash { + tracing::debug!("finalized block unchanged"); + *this.best_finalized_block = Some(best_finalized_block); } + } - // Cache the new best finalized block - this.best_finalized_block = Some(block_identifier.clone()); + // Cache the new best finalized block + *this.best_finalized_block = Some(block.clone()); - // Return the best finalized block - return Poll::Ready(Some(ClientEvent::NewFinalized( - BlockOrIdentifier::Identifier(block_identifier), + // Return the best finalized block + return Poll::Ready(Some(ClientEvent::NewFinalized( + BlockOrIdentifier::Identifier(block.identifier), + ))); + }, + Poll::Ready(Err(error)) => { + // Check failure count + *this.finalized_block_failures += 1; + tracing::error!("failed to retrieve finalized block: {error:?}"); + if *this.finalized_block_failures >= FAILURE_THRESHOLD { + *this.finalized_block_future = None; + return Poll::Ready(Some(ClientEvent::Close( + "More than 10 failures in sequence".into(), ))); - }, - Poll::Ready(Ok(None)) => { - // Retry to retrieve the latest finalized block. - this.finalized_block_future = Some(this.finalized_block()); - tracing::error!("finalized block not found"); - this.finalized_block_failures += 1; - continue; - }, - Poll::Ready(Err(error)) => { - // Retry to retrieve the latest finalized block. - this.finalized_block_future = Some(this.finalized_block()); - tracing::error!("failed to retrieve finalized block: {error:?}"); - this.finalized_block_failures += 1; - continue; - }, - Poll::Pending => { - this.finalized_block_future = Some(finalized_block_future); - break; - }, - } + } + + // Retry to retrieve the latest finalized block. + *this.finalized_block_future = Some(this.finalized_block()); + continue; + }, + Poll::Pending => { + *this.finalized_block_future = Some(finalized_block_future); + break; + }, } } let Some(mut new_head_stream) = this.new_head.take() else { - this.finalized_block_future = None; + *this.finalized_block_future = None; return Poll::Ready(None); }; // Query new heads loop { - if this.latest_block_failures >= FAILURE_THRESHOLD { + if *this.latest_block_failures >= FAILURE_THRESHOLD { return Poll::Ready(Some(ClientEvent::Close( "More than 10 failures in sequence".into(), ))); @@ -156,31 +167,34 @@ where match new_head_stream.poll_next_unpin(cx) { Poll::Ready(Some(block)) => { // Convert raw block to block identifier - let block_identifier = match block_to_identifier(&block) { - Ok(block_identifier) => block_identifier, + let block = match NonPendingBlock::try_from(block) { + Ok(block) => block, Err(error) => { - this.latest_block_failures += 1; - tracing::error!("latest block: {error}"); + *this.latest_block_failures += 1; + tracing::error!("[RPC BUG] invalid latest block: {error}"); continue; }, }; // Reset failure counter - this.latest_block_failures = 0; + *this.latest_block_failures = 0; + + // Store the new latest block + *this.latest_block = Some(block.clone()); // Query latest finalized block if this.finalized_block_future.is_none() { - this.finalized_block_future = Some(this.finalized_block()); + *this.finalized_block_future = Some(this.finalized_block()); } - this.new_head = Some(new_head_stream); + *this.new_head = Some(new_head_stream); return Poll::Ready(Some(ClientEvent::NewHead(BlockOrIdentifier::Identifier( - block_identifier, + block.identifier, )))); }, Poll::Ready(None) => return Poll::Ready(None), Poll::Pending => { - this.new_head = Some(new_head_stream); + *this.new_head = Some(new_head_stream); return Poll::Pending; }, }; diff --git a/chains/ethereum/server/src/lib.rs b/chains/ethereum/server/src/lib.rs index c7a21fb7..e2c08cb8 100644 --- a/chains/ethereum/server/src/lib.rs +++ b/chains/ethereum/server/src/lib.rs @@ -42,9 +42,9 @@ impl MaybeWsEthereumClient { addr: S, ) -> Result { let config = match blockchain { - "polygon" => rosetta_config_ethereum::polygon_config(network)?, "ethereum" => rosetta_config_ethereum::config(network)?, - "arbitrum" => rosetta_config_ethereum::config(network)?, + "polygon" => rosetta_config_ethereum::polygon_config(network)?, + "arbitrum" => rosetta_config_ethereum::arbitrum_config(network)?, blockchain => anyhow::bail!("1unsupported blockchain: {blockchain}"), }; Self::from_config(config, addr).await @@ -116,10 +116,11 @@ impl BlockchainClient for MaybeWsEthereumClient { } async fn finalized_block(&self) -> Result { - match self { - Self::Http(http_client) => http_client.finalized_block().await, - Self::Ws(ws_client) => ws_client.finalized_block().await, - } + let block = match self { + Self::Http(http_client) => http_client.finalized_block(None).await?, + Self::Ws(ws_client) => ws_client.finalized_block(None).await?, + }; + Ok(BlockIdentifier { index: block.number, hash: hex::encode(block.hash) }) } async fn balance(&self, address: &Address, block: &BlockIdentifier) -> Result { diff --git a/chains/ethereum/server/src/utils.rs b/chains/ethereum/server/src/utils.rs index bffdab74..00333eca 100644 --- a/chains/ethereum/server/src/utils.rs +++ b/chains/ethereum/server/src/utils.rs @@ -12,9 +12,9 @@ use ethers::{ utils::to_checksum, }; use rosetta_core::{ - types as rosetta_types, types::{ - AccountIdentifier, Amount, Currency, Operation, OperationIdentifier, TransactionIdentifier, + self as rosetta_types, AccountIdentifier, Amount, BlockIdentifier, Currency, Operation, + OperationIdentifier, TransactionIdentifier, }, BlockchainConfig, }; @@ -22,8 +22,59 @@ use serde_json::json; use std::{ collections::{HashMap, VecDeque}, str::FromStr, + sync::Arc, }; +/// A block that is not pending, so it must have a valid hash and number. +/// This allow skipping duplicated checks in the code +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct NonPendingBlock { + pub hash: H256, + pub number: u64, + pub identifier: BlockIdentifier, + pub block: ethers::types::Block, +} + +impl TryFrom> for NonPendingBlock { + type Error = anyhow::Error; + + fn try_from(block: ethers::types::Block) -> std::result::Result { + let Some(number) = block.number else { anyhow::bail!("block number is missing") }; + let Some(hash) = block.hash else { anyhow::bail!("block hash is missing") }; + Ok(Self { + hash, + number: number.as_u64(), + identifier: BlockIdentifier::new(number.as_u64(), hex::encode(hash)), + block, + }) + } +} + +// Retrieve a non-pending block +pub async fn get_non_pending_block( + client: Arc>, + block_id: ID, +) -> Result> +where + C: JsonRpcClient + 'static, + ID: Into + Send + Sync, +{ + let block_id = block_id.into(); + if matches!(block_id, BlockId::Number(BlockNumber::Pending)) { + anyhow::bail!("request a pending block is not allowed"); + } + let Some(block) = client.get_block(block_id).await? else { + return Ok(None); + }; + // The block is not pending, it MUST have a valid hash and number + let Ok(block) = NonPendingBlock::try_from(block) else { + anyhow::bail!( + "[RPC CLIENT BUG] the rpc client returned an invalid non-pending block at {block_id:?}" + ); + }; + Ok(Some(block)) +} + pub async fn get_transaction( client: &Provider

, config: &BlockchainConfig, diff --git a/deny.toml b/deny.toml index 240bdef5..2f83caca 100644 --- a/deny.toml +++ b/deny.toml @@ -114,7 +114,6 @@ notice = "deny" # A list of advisory IDs to ignore. Note that ignored advisories will still # output a note when they are encountered. ignore = [ - 'RUSTSEC-2020-0071', # Potential segfault in the time crate 'RUSTSEC-2021-0060', # Create `aes-soft` has been merged into the `aes` crate 'RUSTSEC-2021-0064', # Crate `cpuid-bool` has been renamed to `cpufeatures` 'RUSTSEC-2021-0139', # ansi_term is Unmaintained From 8b12912b7a5f636b9a6625cbf51dc891f5268d92 Mon Sep 17 00:00:00 2001 From: Lohann Paterno Coutinho Ferreira Date: Thu, 26 Oct 2023 16:47:21 -0300 Subject: [PATCH 2/4] Remove comments --- chains/ethereum/server/src/client.rs | 23 ------------------ chains/ethereum/server/src/event_stream.rs | 27 ---------------------- 2 files changed, 50 deletions(-) diff --git a/chains/ethereum/server/src/client.rs b/chains/ethereum/server/src/client.rs index 755edd1a..3560a56a 100644 --- a/chains/ethereum/server/src/client.rs +++ b/chains/ethereum/server/src/client.rs @@ -139,28 +139,6 @@ where anyhow::bail!("Cannot find finalized block at {number}"); }; Ok(finalized_block) - - // TODO: ISSUE-176 Create a new connector for polygon - // if matches!(self.config.blockchain, "polygon" | "arbitrum") { - // // TODO: ISSUE-176 Replace this hack by querying polygon checkpoints - // // Polygon finalized blocks are stored on ethereum mainnet roughly every 30 minutes - // // and polygon block interval is ~2 seconds, 30 minutes / 2 seconds == 900 blocks. - // let block_number = latest_block.number.saturating_sub(900u64); - // if block_number == 0 { - // return Ok(self.genesis_block.clone()); - // } - - // let Some(finalized_block) = get_non_pending_block(Arc::clone(&self.client), - // U64::from(block_number)).await? else { anyhow::bail!("Cannot find block - // number {block_number}"); }; - - // return Ok(finalized_block); - // } - - // let Some(finalized_block) = get_non_pending_block(Arc::clone(&self.client), - // BlockNumber::Finalized).await? else { anyhow::bail!("Cannot find block number - // {block_number}"); }; - // Ok(finalized_block) } pub async fn balance(&self, address: &Address, block: &BlockIdentifier) -> Result { @@ -437,7 +415,6 @@ where { pub async fn listen(&self) -> Result> { let new_head_subscription = self.client.subscribe_blocks().await?; - // let get_finalized = self.finalized_block(None); Ok(EthereumEventStream::new(self, new_head_subscription)) } } diff --git a/chains/ethereum/server/src/event_stream.rs b/chains/ethereum/server/src/event_stream.rs index dc3baecc..a33b6b1b 100644 --- a/chains/ethereum/server/src/event_stream.rs +++ b/chains/ethereum/server/src/event_stream.rs @@ -10,9 +10,7 @@ const FAILURE_THRESHOLD: u32 = 10; #[pin_project::pin_project(project=EthereumEventStreamProjection)] pub struct EthereumEventStream<'a, P: PubsubClient> { /// Ethereum client - // #[pin] pub client: &'a crate::EthereumClient

, - // pub client: Arc>, /// Ethereum subscription for new heads pub new_head: Option>>, /// Count the number of failed attempts to retrieve the finalized block @@ -35,7 +33,6 @@ where P: PubsubClient + 'static, { pub fn new<'a>( - // client: Arc>, client: &'a crate::EthereumClient

, subscription: SubscriptionStream<'a, P, Block>, ) -> EthereumEventStream<'a, P> { @@ -49,23 +46,6 @@ where latest_block: None, } } - - // fn finalized_block<'a>(self: Pin<&'a mut Self>) -> BoxFuture<'a, - // anyhow::Result> { self.client.finalized_block(None).boxed() - // // Clone client to make BoxFuture 'static - // // let client = Arc::clone(&self.client); - // // async move { client.get_block(BlockId::Number(BlockNumber::Finalized)).await }.boxed() - // } - - // fn finalized_block<'a, 'b: 'a>(self: &mut Pin<&'b mut Self>) { - // let fut = EthereumClient::finalized_block(self.client, None).boxed(); - // let this = self.project(); - // *this.finalized_block_future = Some(fut); - // // (&mut *self).finalized_block_future = Some(self.client.finalized_block(None).boxed()); - // // Clone client to make BoxFuture 'static - // // let client = Arc::clone(&self.client); - // // async move { client.get_block(BlockId::Number(BlockNumber::Finalized)).await }.boxed() - // } } impl<'a, 'b, P> EthereumEventStreamProjection<'a, 'b, P> @@ -77,13 +57,6 @@ where let client = &self.client; EthereumClient::finalized_block(client, latest_block_number).boxed() } - // fn inc_finalized_failures(&mut self) { - // let failures = *self.finalized_block_failures; - // std::mem::replace(self.finalized_block_failures, failures + 1); - // // Clone client to make BoxFuture 'static - // // let client = Arc::clone(&self.client); - // // async move { client.get_block(BlockId::Number(BlockNumber::Finalized)).await }.boxed() - // } } impl

Stream for EthereumEventStream<'_, P> From 35dcac2e3ac19adf576be1fd279075df079402c3 Mon Sep 17 00:00:00 2001 From: Lohann Paterno Coutinho Ferreira Date: Thu, 26 Oct 2023 19:35:31 -0300 Subject: [PATCH 3/4] Refactor event stream --- chains/ethereum/server/src/event_stream.rs | 268 +++++++++++++-------- rosetta-core/src/lib.rs | 12 + 2 files changed, 179 insertions(+), 101 deletions(-) diff --git a/chains/ethereum/server/src/event_stream.rs b/chains/ethereum/server/src/event_stream.rs index a33b6b1b..d0f4acbf 100644 --- a/chains/ethereum/server/src/event_stream.rs +++ b/chains/ethereum/server/src/event_stream.rs @@ -2,30 +2,19 @@ use crate::{client::EthereumClient, utils::NonPendingBlock}; use ethers::{prelude::*, providers::PubsubClient}; use futures_util::{future::BoxFuture, FutureExt}; use rosetta_core::{stream::Stream, BlockOrIdentifier, ClientEvent}; -use std::{pin::Pin, task::Poll}; +use std::{cmp::Ordering, pin::Pin, task::Poll}; // Maximum number of failures in sequence before closing the stream const FAILURE_THRESHOLD: u32 = 10; #[pin_project::pin_project(project=EthereumEventStreamProjection)] -pub struct EthereumEventStream<'a, P: PubsubClient> { - /// Ethereum client - pub client: &'a crate::EthereumClient

, +pub struct EthereumEventStream<'a, P: PubsubClient + 'static> { /// Ethereum subscription for new heads - pub new_head: Option>>, - /// Count the number of failed attempts to retrieve the finalized block - pub finalized_block_failures: u32, + new_head_stream: Option>>, + /// Finalized blocks stream + finalized_stream: Option>, /// Count the number of failed attempts to retrieve the latest block - pub latest_block_failures: u32, - /// Cache the best finalized block, we use this to avoid emitting two - /// [`ClientEvent::NewFinalized`] for the same block - pub best_finalized_block: Option, - /// Cache the latest block, used for retrieve the latest finalized block - /// see [`BlockFinalityStrategy`] - pub latest_block: Option, - /// Ethereum client doesn't support subscribing for finalized blocks, as workaround - /// everytime we receive a new head, we query the latest finalized block - pub finalized_block_future: Option>>, + failures: u32, } impl

EthereumEventStream<'_, P> @@ -33,32 +22,17 @@ where P: PubsubClient + 'static, { pub fn new<'a>( - client: &'a crate::EthereumClient

, + client: &'a EthereumClient

, subscription: SubscriptionStream<'a, P, Block>, ) -> EthereumEventStream<'a, P> { EthereumEventStream { - client, - new_head: Some(subscription), - finalized_block_failures: 0, - latest_block_failures: 0, - best_finalized_block: None, - finalized_block_future: None, - latest_block: None, + new_head_stream: Some(subscription), + finalized_stream: Some(FinalizedBlockStream::new(client)), + failures: 0, } } } -impl<'a, 'b, P> EthereumEventStreamProjection<'a, 'b, P> -where - P: PubsubClient + 'static, -{ - fn finalized_block(&self) -> BoxFuture<'b, anyhow::Result> { - let latest_block_number = self.latest_block.as_ref().map(|block| block.number); - let client = &self.client; - EthereumClient::finalized_block(client, latest_block_number).boxed() - } -} - impl

Stream for EthereumEventStream<'_, P> where P: PubsubClient + 'static, @@ -66,72 +40,43 @@ where type Item = ClientEvent; fn poll_next( - self: Pin<&mut Self>, + mut self: Pin<&mut Self>, cx: &mut std::task::Context<'_>, ) -> Poll> { // Check if the stream is close - if self.new_head.is_none() && self.finalized_block_future.is_none() { + let Some(mut finalized_stream) = self.finalized_stream.take() else { return Poll::Ready(None); - } - - let this = self.project(); - - // Query the latest finalized block - loop { - let Some(mut finalized_block_future) = this.finalized_block_future.take() else { - break; - }; - match finalized_block_future.poll_unpin(cx) { - Poll::Ready(Ok(block)) => { - // Reset failure counter - *this.finalized_block_failures = 0; - - // Skip if the finalized block is equal to the best finalized block - if let Some(best_finalized_block) = this.best_finalized_block.take() { - if block.hash == best_finalized_block.hash { - tracing::debug!("finalized block unchanged"); - *this.best_finalized_block = Some(best_finalized_block); - } - } - - // Cache the new best finalized block - *this.best_finalized_block = Some(block.clone()); - - // Return the best finalized block - return Poll::Ready(Some(ClientEvent::NewFinalized( - BlockOrIdentifier::Identifier(block.identifier), - ))); - }, - Poll::Ready(Err(error)) => { - // Check failure count - *this.finalized_block_failures += 1; - tracing::error!("failed to retrieve finalized block: {error:?}"); - if *this.finalized_block_failures >= FAILURE_THRESHOLD { - *this.finalized_block_future = None; - return Poll::Ready(Some(ClientEvent::Close( - "More than 10 failures in sequence".into(), - ))); - } + }; - // Retry to retrieve the latest finalized block. - *this.finalized_block_future = Some(this.finalized_block()); - continue; - }, - Poll::Pending => { - *this.finalized_block_future = Some(finalized_block_future); - break; - }, - } + // Poll the finalized block stream + match finalized_stream.poll_next_unpin(cx) { + Poll::Ready(Some(Ok(block))) => { + self.finalized_stream = Some(finalized_stream); + return Poll::Ready(Some(ClientEvent::NewFinalized(block.identifier.into()))); + }, + Poll::Ready(Some(Err(error))) => { + self.new_head_stream = None; + return Poll::Ready(Some(ClientEvent::Close(error))); + }, + Poll::Ready(None) => { + self.new_head_stream = None; + return Poll::Ready(None); + }, + Poll::Pending => { + self.finalized_stream = Some(finalized_stream); + }, } - let Some(mut new_head_stream) = this.new_head.take() else { - *this.finalized_block_future = None; + // Poll the new head stream + let Some(mut new_head_stream) = self.new_head_stream.take() else { + self.finalized_stream = None; return Poll::Ready(None); }; - // Query new heads loop { - if *this.latest_block_failures >= FAILURE_THRESHOLD { + if self.failures >= FAILURE_THRESHOLD { + self.new_head_stream = None; + self.finalized_stream = None; return Poll::Ready(Some(ClientEvent::Close( "More than 10 failures in sequence".into(), ))); @@ -143,34 +88,155 @@ where let block = match NonPendingBlock::try_from(block) { Ok(block) => block, Err(error) => { - *this.latest_block_failures += 1; + self.failures += 1; tracing::error!("[RPC BUG] invalid latest block: {error}"); continue; }, }; // Reset failure counter - *this.latest_block_failures = 0; + self.failures = 0; // Store the new latest block - *this.latest_block = Some(block.clone()); - - // Query latest finalized block - if this.finalized_block_future.is_none() { - *this.finalized_block_future = Some(this.finalized_block()); + if let Some(finalized_stream) = self.finalized_stream.as_mut() { + finalized_stream.update_latest_block(block.number); } - *this.new_head = Some(new_head_stream); + self.new_head_stream = Some(new_head_stream); return Poll::Ready(Some(ClientEvent::NewHead(BlockOrIdentifier::Identifier( block.identifier, )))); }, Poll::Ready(None) => return Poll::Ready(None), Poll::Pending => { - *this.new_head = Some(new_head_stream); - return Poll::Pending; + self.new_head_stream = Some(new_head_stream); + break Poll::Pending; }, }; } } } + +struct FinalizedBlockStream<'a, P> +where + P: PubsubClient + 'static, +{ + /// Ethereum client used to retrieve the finalized block + client: &'a EthereumClient

, + /// Cache the latest block, used for retrieve the latest finalized block + /// see [`BlockFinalityStrategy`] + latest_block: Option, + /// Ethereum client doesn't support subscribing for finalized blocks, as workaround + /// everytime we receive a new head, we query the latest finalized block + future: Option>>, + /// Cache the best finalized block, we use this to avoid emitting two + /// [`ClientEvent::NewFinalized`] for the same block + best_finalized_block: Option, + /// Count the number of failed attempts to retrieve the finalized block + failures: u32, + waker: Option, +} + +impl<'a, P> FinalizedBlockStream<'a, P> +where + P: PubsubClient + 'static, +{ + pub fn new(client: &EthereumClient

) -> FinalizedBlockStream<'_, P> { + FinalizedBlockStream { + client, + latest_block: None, + future: None, + best_finalized_block: None, + failures: 0, + waker: None, + } + } + + pub fn update_latest_block(&mut self, number: u64) { + if Some(number) == self.latest_block { + return; + } + self.latest_block = Some(number); + if self.future.is_none() { + self.future = Some(self.finalized_block()); + } + if let Some(waker) = self.waker.take() { + waker.wake(); + } + } + + fn finalized_block<'c>(&'c self) -> BoxFuture<'a, anyhow::Result> { + self.client.finalized_block(self.latest_block).boxed() + } +} + +impl

Stream for FinalizedBlockStream<'_, P> +where + P: PubsubClient + 'static, +{ + type Item = Result; + + fn poll_next( + mut self: Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> Poll> { + loop { + // Check the failure count + match self.failures.cmp(&FAILURE_THRESHOLD) { + Ordering::Greater => return Poll::Ready(None), + Ordering::Equal => { + self.failures += 1; + self.future = None; + return Poll::Ready(Some(Err(format!( + "More than {FAILURE_THRESHOLD} failures in sequence", + )))); + }, + Ordering::Less => {}, + } + + // If the future is not ready, store the waker and return pending + let Some(mut future) = self.future.take() else { + self.waker = Some(cx.waker().clone()); + return Poll::Pending; + }; + + match future.poll_unpin(cx) { + Poll::Ready(Ok(block)) => { + // Store the waker + self.waker = Some(cx.waker().clone()); + + // Skip if the finalized block is equal to the best finalized block + if let Some(best_finalized_block) = self.best_finalized_block.take() { + if block.hash == best_finalized_block.hash { + tracing::debug!("finalized block unchanged"); + self.best_finalized_block = Some(best_finalized_block); + break Poll::Pending; + } + } + + // Cache the new best finalized block + self.best_finalized_block = Some(block.clone()); + + // Return the best finalized block + break Poll::Ready(Some(Ok(block))); + }, + Poll::Ready(Err(error)) => { + // Increment failure count + self.failures += 1; + tracing::error!( + "failed to retrieve finalized block: {error:?} {}", + self.failures + ); + + // Retry to retrieve the latest finalized block. + self.future = Some(self.finalized_block()); + continue; + }, + Poll::Pending => { + self.future = Some(future); + break Poll::Pending; + }, + } + } + } +} diff --git a/rosetta-core/src/lib.rs b/rosetta-core/src/lib.rs index 7f1b560c..f76802ad 100644 --- a/rosetta-core/src/lib.rs +++ b/rosetta-core/src/lib.rs @@ -81,6 +81,18 @@ pub enum BlockOrIdentifier { Block(Block), } +impl From for BlockOrIdentifier { + fn from(identifier: BlockIdentifier) -> Self { + Self::Identifier(identifier) + } +} + +impl From for BlockOrIdentifier { + fn from(block: Block) -> Self { + Self::Block(block) + } +} + /// Event produced by a handler. #[derive(Debug, Clone, PartialEq, Eq)] pub enum ClientEvent { From 01da432f407ec2dff9f09c34b9a1af46664edcc7 Mon Sep 17 00:00:00 2001 From: Lohann Paterno Coutinho Ferreira Date: Thu, 26 Oct 2023 19:39:13 -0300 Subject: [PATCH 4/4] Remove unused crates --- Cargo.lock | 33 +++++++++++----------- chains/ethereum/server/Cargo.toml | 1 - chains/ethereum/server/src/client.rs | 2 -- chains/ethereum/server/src/event_stream.rs | 2 +- 4 files changed, 17 insertions(+), 21 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 223f5b6f..7ed4ae17 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -335,7 +335,7 @@ dependencies = [ "log", "parking", "polling", - "rustix 0.37.26", + "rustix 0.37.27", "slab", "socket2 0.4.10", "waker-fn", @@ -374,7 +374,7 @@ dependencies = [ "cfg-if", "event-listener 3.0.0", "futures-lite", - "rustix 0.38.20", + "rustix 0.38.21", "windows-sys 0.48.0", ] @@ -390,7 +390,7 @@ dependencies = [ "cfg-if", "futures-core", "futures-io", - "rustix 0.38.20", + "rustix 0.38.21", "signal-hook-registry", "slab", "windows-sys 0.48.0", @@ -3085,7 +3085,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ "hermit-abi", - "rustix 0.38.20", + "rustix 0.38.21", "windows-sys 0.48.0", ] @@ -3500,7 +3500,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2cffa4ad52c6f791f4f8b15f0c05f9824b2ced1160e88cc393d64fff9a8ac64" dependencies = [ - "rustix 0.38.20", + "rustix 0.38.21", ] [[package]] @@ -4908,7 +4908,6 @@ dependencies = [ "futures-timer", "futures-util", "hex 0.4.3", - "pin-project", "rosetta-client", "rosetta-config-ethereum", "rosetta-core", @@ -5035,9 +5034,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.36.16" +version = "0.36.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6da3636faa25820d8648e0e31c5d519bbb01f72fdf57131f0f5f7da5fed36eab" +checksum = "305efbd14fde4139eb501df5f136994bb520b033fa9fbdce287507dc23b8c7ed" dependencies = [ "bitflags 1.3.2", "errno", @@ -5049,9 +5048,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.37.26" +version = "0.37.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84f3f8f960ed3b5a59055428714943298bf3fa2d4a1d53135084e0544829d995" +checksum = "fea8ca367a3a01fe35e6943c400addf443c0f57670e6ec51196f71a4b8762dd2" dependencies = [ "bitflags 1.3.2", "errno", @@ -5063,9 +5062,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.20" +version = "0.38.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67ce50cb2e16c2903e30d1cbccfd8387a74b9d4c938b6a4c5ec6cc7556f7a8a0" +checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" dependencies = [ "bitflags 2.4.1", "errno", @@ -6726,14 +6725,14 @@ checksum = "14c39fd04924ca3a864207c66fc2cd7d22d7c016007f9ce846cbb9326331930a" [[package]] name = "tempfile" -version = "3.8.0" +version = "3.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" +checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" dependencies = [ "cfg-if", "fastrand 2.0.1", - "redox_syscall 0.3.5", - "rustix 0.38.20", + "redox_syscall 0.4.1", + "rustix 0.38.21", "windows-sys 0.48.0", ] @@ -7691,7 +7690,7 @@ dependencies = [ "memoffset 0.8.0", "paste", "rand 0.8.5", - "rustix 0.36.16", + "rustix 0.36.17", "wasmtime-asm-macros", "wasmtime-environ", "wasmtime-jit-debug", diff --git a/chains/ethereum/server/Cargo.toml b/chains/ethereum/server/Cargo.toml index 2ba4a241..9cd01862 100644 --- a/chains/ethereum/server/Cargo.toml +++ b/chains/ethereum/server/Cargo.toml @@ -15,7 +15,6 @@ ethers = { version = "2.0", default-features = true, features = ["abigen", "rust futures-timer = "3.0" futures-util = "0.3" hex = "0.4" -pin-project = "1.0" rosetta-config-ethereum = { version = "0.4.0", path = "../config" } rosetta-core = { version = "0.4.0", path = "../../../rosetta-core" } rosetta-ethereum-rpc-client = { version = "0.1.0", path = "../rpc-client" } diff --git a/chains/ethereum/server/src/client.rs b/chains/ethereum/server/src/client.rs index 3560a56a..b5a9f012 100644 --- a/chains/ethereum/server/src/client.rs +++ b/chains/ethereum/server/src/client.rs @@ -41,8 +41,6 @@ pub enum BlockFinalityStrategy { Finalized, /// Use the number of confirmations to determine the finalized block Confirmations(u64), - // TODO: ISSUE-176 for polygon the finalized block is stored on ethereum mainnet - // Polygon, } impl BlockFinalityStrategy { diff --git a/chains/ethereum/server/src/event_stream.rs b/chains/ethereum/server/src/event_stream.rs index d0f4acbf..905e7f79 100644 --- a/chains/ethereum/server/src/event_stream.rs +++ b/chains/ethereum/server/src/event_stream.rs @@ -7,7 +7,6 @@ use std::{cmp::Ordering, pin::Pin, task::Poll}; // Maximum number of failures in sequence before closing the stream const FAILURE_THRESHOLD: u32 = 10; -#[pin_project::pin_project(project=EthereumEventStreamProjection)] pub struct EthereumEventStream<'a, P: PubsubClient + 'static> { /// Ethereum subscription for new heads new_head_stream: Option>>, @@ -134,6 +133,7 @@ where best_finalized_block: Option, /// Count the number of failed attempts to retrieve the finalized block failures: u32, + /// Waker used to wake up the stream when a new block is available waker: Option, }