diff --git a/Cargo.lock b/Cargo.lock index 051a2ed9..3d6e29f2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -76,9 +76,9 @@ dependencies = [ [[package]] name = "allocator-api2" -version = "0.2.18" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" +checksum = "45862d1c77f2228b9e10bc609d5bc203d86ebc9b87ad8d5d5167a6c9abf739d9" [[package]] name = "alloy" @@ -100,7 +100,7 @@ version = "0.1.47" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "18c5c520273946ecf715c0010b4e3503d7eba9893cd9ce6b7fff5654c4a3c470" dependencies = [ - "alloy-primitives 0.8.11", + "alloy-primitives 0.8.13", "num_enum", "serde", "strum", @@ -113,7 +113,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "705687d5bfd019fee57cf9e206b27b30a9a9617535d5590a02b171e813208f8e" dependencies = [ "alloy-eips", - "alloy-primitives 0.8.11", + "alloy-primitives 0.8.13", "alloy-rlp", "alloy-serde", "auto_impl", @@ -124,25 +124,25 @@ dependencies = [ [[package]] name = "alloy-core" -version = "0.8.11" +version = "0.8.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47ef9e96462d0b9fee9008c53c1f3d017b9498fcdef3ad8d728db98afef47955" +checksum = "e8d22df68fa7d9744be0b1a9be3260e9aa089fbf41903ab182328333061ed186" dependencies = [ "alloy-dyn-abi", "alloy-json-abi", - "alloy-primitives 0.8.11", + "alloy-primitives 0.8.13", "alloy-rlp", "alloy-sol-types", ] [[package]] name = "alloy-dyn-abi" -version = "0.8.11" +version = "0.8.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85132f2698b520fab3f54beed55a44389f7006a7b557a0261e1e69439dcc1572" +checksum = "1cf633ae9a1f0c82fdb9e559ed2be1c8e415c3e48fc47e1feaf32c6078ec0cdd" dependencies = [ "alloy-json-abi", - "alloy-primitives 0.8.11", + "alloy-primitives 0.8.13", "alloy-sol-type-parser", "alloy-sol-types", "const-hex", @@ -158,7 +158,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0069cf0642457f87a01a014f6dc29d5d893cd4fd8fddf0c3cdfad1bb3ebafc41" dependencies = [ - "alloy-primitives 0.8.11", + "alloy-primitives 0.8.13", "alloy-rlp", "serde", ] @@ -169,7 +169,7 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea59dc42102bc9a1905dc57901edc6dd48b9f38115df86c7d252acba70d71d04" dependencies = [ - "alloy-primitives 0.8.11", + "alloy-primitives 0.8.13", "alloy-rlp", "k256", "serde", @@ -183,7 +183,7 @@ checksum = "6ffb906284a1e1f63c4607da2068c8197458a352d0b3e9796e67353d72a9be85" dependencies = [ "alloy-eip2930", "alloy-eip7702", - "alloy-primitives 0.8.11", + "alloy-primitives 0.8.13", "alloy-rlp", "alloy-serde", "c-kzg", @@ -199,18 +199,18 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8429cf4554eed9b40feec7f4451113e76596086447550275e3def933faf47ce3" dependencies = [ - "alloy-primitives 0.8.11", + "alloy-primitives 0.8.13", "alloy-serde", "serde", ] [[package]] name = "alloy-json-abi" -version = "0.8.11" +version = "0.8.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ded610181f3dad5810f6ff12d1a99994cf9b42d2fcb7709029352398a5da5ae6" +checksum = "1a500037938085feed8a20dbfc8fce58c599db68c948cfae711147175dee392c" dependencies = [ - "alloy-primitives 0.8.11", + "alloy-primitives 0.8.13", "alloy-sol-type-parser", "serde", "serde_json", @@ -224,7 +224,7 @@ checksum = "801492711d4392b2ccf5fc0bc69e299fa1aab15167d74dcaa9aab96a54f684bd" dependencies = [ "alloy-consensus", "alloy-eips", - "alloy-primitives 0.8.11", + "alloy-primitives 0.8.13", "alloy-serde", "serde", ] @@ -253,9 +253,9 @@ dependencies = [ [[package]] name = "alloy-primitives" -version = "0.8.11" +version = "0.8.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd58d377699e6cfeab52c4a9d28bdc4ef37e2bd235ff2db525071fe37a2e9af5" +checksum = "3aeeb5825c2fc8c2662167058347cd0cafc3cb15bcb5cdb1758a63c2dca0409e" dependencies = [ "alloy-rlp", "bytes", @@ -264,7 +264,7 @@ dependencies = [ "derive_more 1.0.0", "foldhash", "getrandom", - "hashbrown 0.15.1", + "hashbrown 0.15.2", "hex-literal", "indexmap 2.6.0", "itoa", @@ -299,7 +299,7 @@ checksum = "2b09cae092c27b6f1bde952653a22708691802e57bfef4a2973b80bea21efd3f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -308,7 +308,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ffc534b7919e18f35e3aa1f507b6f3d9d92ec298463a9f6beaac112809d8d06" dependencies = [ - "alloy-primitives 0.8.11", + "alloy-primitives 0.8.13", "alloy-rpc-types-eth", "alloy-serde", "serde", @@ -323,7 +323,7 @@ dependencies = [ "alloy-consensus", "alloy-eips", "alloy-network-primitives", - "alloy-primitives 0.8.11", + "alloy-primitives 0.8.13", "alloy-rlp", "alloy-serde", "alloy-sol-types", @@ -339,30 +339,30 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9dff0ab1cdd43ca001e324dc27ee0e8606bd2161d6623c63e0e0b8c4dfc13600" dependencies = [ - "alloy-primitives 0.8.11", + "alloy-primitives 0.8.13", "serde", "serde_json", ] [[package]] name = "alloy-sol-macro" -version = "0.8.11" +version = "0.8.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a1b42ac8f45e2f49f4bcdd72cbfde0bb148f5481d403774ffa546e48b83efc1" +checksum = "5c0279d09463a4695788a3622fd95443625f7be307422deba4b55dd491a9c7a1" dependencies = [ "alloy-sol-macro-expander", "alloy-sol-macro-input", "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] name = "alloy-sol-macro-expander" -version = "0.8.11" +version = "0.8.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06318f1778e57f36333e850aa71bd1bb5e560c10279e236622faae0470c50412" +checksum = "4feea540fc8233df2ad1156efd744b2075372f43a8f942a68b3b19c8a00e2c12" dependencies = [ "alloy-sol-macro-input", "const-hex", @@ -371,31 +371,31 @@ dependencies = [ "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", "syn-solidity", "tiny-keccak", ] [[package]] name = "alloy-sol-macro-input" -version = "0.8.11" +version = "0.8.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaebb9b0ad61a41345a22c9279975c0cdd231b97947b10d7aad1cf0a7181e4a5" +checksum = "2a0ad281f3d1b613af814b66977ee698e443d4644a1510962d0241f26e0e53ae" dependencies = [ "const-hex", "dunce", "heck", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", "syn-solidity", ] [[package]] name = "alloy-sol-type-parser" -version = "0.8.11" +version = "0.8.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12c71028bfbfec210e24106a542aad3def7caf1a70e2c05710e92a98481980d3" +checksum = "96eff16c797438add6c37bb335839d015b186c5421ee5626f5559a7bfeb38ef5" dependencies = [ "serde", "winnow", @@ -403,12 +403,12 @@ dependencies = [ [[package]] name = "alloy-sol-types" -version = "0.8.11" +version = "0.8.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "374d7fb042d68ddfe79ccb23359de3007f6d4d53c13f703b64fb0db422132111" +checksum = "cff34e0682d6665da243a3e81da96f07a2dd50f7e64073e382b1a141f5a2a2f6" dependencies = [ "alloy-json-abi", - "alloy-primitives 0.8.11", + "alloy-primitives 0.8.13", "alloy-sol-macro", "const-hex", "serde", @@ -420,7 +420,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e9703ce68b97f8faae6f7739d1e003fc97621b856953cbcdbb2b515743f23288" dependencies = [ - "alloy-primitives 0.8.11", + "alloy-primitives 0.8.13", "alloy-rlp", "derive_more 1.0.0", "nybbles", @@ -675,7 +675,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -686,7 +686,7 @@ checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -714,7 +714,7 @@ checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -725,21 +725,20 @@ checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "aws-lc-rs" -version = "1.10.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdd82dba44d209fddb11c190e0a94b78651f95299598e472215667417a03ff1d" +checksum = "f47bb8cc16b669d267eeccf585aea077d0882f4777b1c1f740217885d6e6e5a3" dependencies = [ "aws-lc-sys", - "mirai-annotations", "paste", "zeroize", ] [[package]] name = "aws-lc-sys" -version = "0.22.0" +version = "0.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df7a4168111d7eb622a31b214057b8509c0a7e1794f44c546d742330dc793972" +checksum = "a2101df3813227bbaaaa0b04cd61c534c7954b22bd68d399b440be937dc63ff7" dependencies = [ "bindgen", "cc", @@ -752,9 +751,9 @@ dependencies = [ [[package]] name = "axum" -version = "0.7.7" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "504e3947307ac8326a5437504c517c4b56716c9d98fac0028c2acc7ca47d70ae" +checksum = "edca88bc138befd0323b20752846e6587272d3b03b0343c8ea28a6f819e6e71f" dependencies = [ "async-trait", "axum-core", @@ -771,7 +770,7 @@ dependencies = [ "pin-project-lite", "rustversion", "serde", - "sync_wrapper 1.0.1", + "sync_wrapper 1.0.2", "tower 0.5.1", "tower-layer", "tower-service", @@ -792,7 +791,7 @@ dependencies = [ "mime", "pin-project-lite", "rustversion", - "sync_wrapper 1.0.1", + "sync_wrapper 1.0.2", "tower-layer", "tower-service", ] @@ -842,6 +841,28 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" +[[package]] +name = "beacon-protos" +version = "0.1.1" +source = "git+https://github.com/semiotic-ai/beacon-protos.git?branch=main#9d26221607f85defba489b66857d1cf9c18d32b2" +dependencies = [ + "bls", + "firehose-protos 0.1.0 (git+https://github.com/semiotic-ai/veemon.git?branch=joseph/back-172-remove-forrestrie-from-veemon)", + "firehose-rs", + "primitive-types", + "prost", + "prost-build", + "prost-wkt", + "prost-wkt-types", + "serde", + "ssz_types 0.6.0", + "thiserror 2.0.3", + "tonic", + "tonic-build", + "tree_hash 0.6.0", + "types", +] + [[package]] name = "bimap" version = "0.6.3" @@ -876,7 +897,7 @@ dependencies = [ "regex", "rustc-hash 1.1.0", "shlex", - "syn 2.0.87", + "syn 2.0.89", "which", ] @@ -992,9 +1013,9 @@ checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" [[package]] name = "bytemuck" -version = "1.19.0" +version = "1.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8334215b81e418a0a7bdb8ef0849474f40bb10c8b71f1c4ed315cff49f32494d" +checksum = "8b37c88a63ffd85d15b406896cc343916d7cf57838a847b3a6f2ca5d39a5695a" [[package]] name = "byteorder" @@ -1034,9 +1055,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.1.36" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baee610e9452a8f6f0a1b6194ec09ff9e2d85dea54432acdae41aa0761c95d70" +checksum = "fd9de9f2205d5ef3fd67e685b0df337994ddd4495e2a28d185500d0e1edfea47" dependencies = [ "jobserver", "libc", @@ -1123,9 +1144,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.20" +version = "4.5.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" +checksum = "fb3b4b9e5a7c7514dfa52869339ee98b3156b0bfb4e8a77c4ff4babb64b1604f" dependencies = [ "clap_builder", "clap_derive", @@ -1133,9 +1154,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.20" +version = "4.5.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" +checksum = "b17a95aa67cc7b5ebd32aa5370189aa0d79069ef1c64ce893bd30fb24bff20ec" dependencies = [ "anstream", "anstyle", @@ -1152,20 +1173,20 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] name = "clap_lex" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" +checksum = "afb84c814227b90d6895e01398aee0d8033c00e7466aca416fb6a8e0eb19d8a7" [[package]] name = "cmake" -version = "0.1.51" +version = "0.1.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb1e43aa7fd152b1f968787f7dbcdeb306d1867ff373c69955211876c053f91a" +checksum = "c682c223677e0e5b6b7f63a64b9351844c3f1b1678a68b7ee617e30fb082620e" dependencies = [ "cc", ] @@ -1203,23 +1224,11 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "console" -version = "0.15.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" -dependencies = [ - "encode_unicode", - "lazy_static", - "libc", - "windows-sys 0.52.0", -] - [[package]] name = "const-hex" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0121754e84117e65f9d90648ee6aa4882a6e63110307ab73967a4c5e7e69e586" +checksum = "487981fa1af147182687064d0a2c336586d337a606595ced9ffb0c685c250c73" dependencies = [ "cfg-if", "cpufeatures", @@ -1286,6 +1295,16 @@ dependencies = [ "libc", ] +[[package]] +name = "core-foundation" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b55271e5c8c478ad3f38ad24ef34923091e0548492a266d19b3c0b4d82574c63" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation-sys" version = "0.8.7" @@ -1294,9 +1313,9 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cpufeatures" -version = "0.2.14" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" +checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3" dependencies = [ "libc", ] @@ -1456,7 +1475,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -1504,7 +1523,7 @@ dependencies = [ "proc-macro2", "quote", "strsim 0.11.1", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -1526,7 +1545,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core 0.20.10", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -1577,7 +1596,7 @@ checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -1590,7 +1609,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version 0.4.1", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -1611,16 +1630,10 @@ dependencies = [ "convert_case 0.6.0", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", "unicode-xid", ] -[[package]] -name = "deunicode" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "339544cc9e2c4dc3fc7149fd630c5f22263a4fdf18a98afd0075784968b5cf00" - [[package]] name = "digest" version = "0.9.0" @@ -1700,7 +1713,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -1785,21 +1798,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "encode_unicode" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" - -[[package]] -name = "encoding_rs" -version = "0.8.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" -dependencies = [ - "cfg-if", -] - [[package]] name = "enr" version = "0.10.0" @@ -1827,7 +1825,7 @@ checksum = "2f9ed6b3789237c8a0c1c505af1c7eb2c560df6186f01b098c3a1064ea532f38" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -1894,7 +1892,7 @@ name = "eth_trie" version = "0.4.0" source = "git+https://github.com/ethereum/eth-trie.rs?tag=v0.1.0-alpha.2#46da867d8a7eace0a9e912271b236b2007e4cd41" dependencies = [ - "alloy-primitives 0.8.11", + "alloy-primitives 0.8.13", "alloy-rlp", "hashbrown 0.14.5", "keccak-hash", @@ -1971,7 +1969,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70cbccfccf81d67bff0ab36e591fa536c8a935b078a7b0e58c1d00d418332fc9" dependencies = [ - "alloy-primitives 0.8.11", + "alloy-primitives 0.8.13", "hex", "serde", "serde_derive", @@ -1995,7 +1993,7 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e999563461faea0ab9bc0024e5e66adcee35881f3d5062f52f31a4070fe1522" dependencies = [ - "alloy-primitives 0.8.11", + "alloy-primitives 0.8.13", "itertools 0.13.0", "smallvec", ] @@ -2021,7 +2019,7 @@ dependencies = [ "darling 0.20.10", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -2063,7 +2061,7 @@ dependencies = [ "sha3 0.9.1", "ssz_types 0.8.0", "superstruct 0.7.0", - "thiserror 1.0.68", + "thiserror 1.0.69", "tokio", "tree_hash 0.8.0", "tree_hash_derive 0.8.0", @@ -2073,16 +2071,6 @@ dependencies = [ "validator", ] -[[package]] -name = "fake" -version = "2.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d391ba4af7f1d93f01fcf7b2f29e2bc9348e109dfdbf4dcbdc51dfa38dab0b6" -dependencies = [ - "deunicode", - "rand", -] - [[package]] name = "fallible-iterator" version = "0.2.0" @@ -2097,9 +2085,9 @@ checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" [[package]] name = "fastrand" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" +checksum = "486f806e73c5707928240ddc295403b1b93c96a02038563881c4a2fd84b81ac4" [[package]] name = "fastrlp" @@ -2131,18 +2119,19 @@ checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" [[package]] name = "firehose-client" version = "0.1.1" +source = "git+https://github.com/semiotic-ai/firehose-client.git?branch=main#97564c18b7da6ec49a45e9364f11b3cb22b8db43" dependencies = [ + "beacon-protos", "dotenvy", - "firehose-protos", - "forrestrie", + "firehose-protos 0.1.0 (git+https://github.com/semiotic-ai/veemon.git?branch=joseph/back-172-remove-forrestrie-from-veemon)", + "firehose-rs", "futures", - "hex", "http", "once_cell", "rustls", "serde", "serde_derive", - "thiserror 2.0.0", + "thiserror 2.0.3", "tokio", "tokio-stream", "tonic", @@ -2155,9 +2144,10 @@ version = "0.1.0" dependencies = [ "alloy-consensus", "alloy-eip2930", - "alloy-primitives 0.8.11", + "alloy-primitives 0.8.13", "alloy-rlp", "ethportal-api", + "firehose-rs", "hex", "primitive-types", "prost", @@ -2168,23 +2158,63 @@ dependencies = [ "reth-trie-common", "serde", "serde_json", - "thiserror 2.0.0", + "thiserror 2.0.3", "tokio", "tonic", "tonic-build", "tracing", ] +[[package]] +name = "firehose-protos" +version = "0.1.0" +source = "git+https://github.com/semiotic-ai/veemon.git?branch=joseph/back-172-remove-forrestrie-from-veemon#4e3555dd823478a4fa98ecfca13490f4e6162aef" +dependencies = [ + "alloy-consensus", + "alloy-eip2930", + "alloy-primitives 0.8.13", + "alloy-rlp", + "ethportal-api", + "firehose-rs", + "primitive-types", + "prost", + "prost-build", + "prost-wkt", + "prost-wkt-types", + "reth-primitives", + "reth-trie-common", + "serde", + "thiserror 2.0.3", + "tonic", + "tonic-build", + "tracing", +] + [[package]] name = "firehose-protos-examples" version = "0.1.1" dependencies = [ - "alloy-primitives 0.8.11", + "alloy-primitives 0.8.13", "firehose-client", - "firehose-protos", + "firehose-protos 0.1.0", + "firehose-rs", "tokio", ] +[[package]] +name = "firehose-rs" +version = "0.1.0" +source = "git+https://github.com/semiotic-ai/firehose-rs.git?branch=main#be85002a5a1d3d298704b0465d531d14cff51caf" +dependencies = [ + "prost", + "prost-build", + "prost-wkt", + "prost-wkt-types", + "serde", + "tonic", + "tonic-build", +] + [[package]] name = "fixed-hash" version = "0.8.0" @@ -2210,17 +2240,17 @@ version = "0.1.1" dependencies = [ "alloy-consensus", "alloy-eip2930", - "alloy-primitives 0.8.11", + "alloy-primitives 0.8.13", "bincode", "clap", "criterion", - "firehose-protos", + "firehose-protos 0.1.0", "prost", "rand", "reth-primitives", "serde", "serde_json", - "thiserror 2.0.0", + "thiserror 2.0.3", "tracing", "tracing-subscriber", "zstd", @@ -2228,9 +2258,9 @@ dependencies = [ [[package]] name = "flate2" -version = "1.0.34" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0" +checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c" dependencies = [ "crc32fast", "miniz_oxide", @@ -2248,21 +2278,6 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2" -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - [[package]] name = "form_urlencoded" version = "1.2.1" @@ -2272,68 +2287,6 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "forrestrie" -version = "0.1.1" -dependencies = [ - "alloy-primitives 0.8.11", - "alloy-rlp", - "bls", - "ethportal-api", - "fake", - "firehose-protos", - "futures", - "merkle_proof", - "primitive-types", - "prost", - "prost-build", - "prost-wkt", - "prost-wkt-types", - "rand", - "reth-primitives", - "reth-trie-common", - "serde", - "ssz_types 0.6.0", - "tonic", - "tonic-build", - "tree_hash 0.6.0", - "types", -] - -[[package]] -name = "forrestrie-examples" -version = "0.1.1" -dependencies = [ - "bls", - "ethereum_ssz 0.7.1", - "ethereum_ssz_derive 0.7.1", - "ethportal-api", - "firehose-client", - "firehose-protos", - "forrestrie", - "futures", - "insta", - "merkle_proof", - "primitive-types", - "prost", - "prost-wkt", - "prost-wkt-types", - "reqwest", - "reth-primitives", - "reth-trie-common", - "serde", - "serde_json", - "snap", - "ssz_types 0.8.0", - "tokio", - "tonic", - "tracing", - "tracing-subscriber", - "tree_hash 0.6.0", - "trin-validation", - "types", -] - [[package]] name = "fs_extra" version = "1.3.0" @@ -2402,7 +2355,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -2517,7 +2470,7 @@ dependencies = [ "pin-project", "serde", "serde_json", - "thiserror 1.0.68", + "thiserror 1.0.69", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", @@ -2561,9 +2514,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e8ac6999421f49a846c2d4411f337e53497d8ec55d67753beffa43c5d9205" +checksum = "ccae279728d634d083c00f6099cb58f01cc99c145b84b8be2f6c74618d79922e" dependencies = [ "atomic-waker", "bytes", @@ -2606,9 +2559,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.1" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" dependencies = [ "allocator-api2", "equivalent", @@ -2629,11 +2582,11 @@ dependencies = [ name = "header-accumulator" version = "0.1.0" dependencies = [ - "alloy-primitives 0.8.11", + "alloy-primitives 0.8.13", "base64 0.21.7", "clap", "ethportal-api", - "firehose-protos", + "firehose-protos 0.1.0", "flat-files-decoder", "log", "primitive-types", @@ -2641,7 +2594,7 @@ dependencies = [ "serde", "serde_json", "tempfile", - "thiserror 2.0.0", + "thiserror 2.0.3", "tree_hash 0.8.0", "trin-validation", ] @@ -2763,9 +2716,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hyper" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbbff0a806a4728c99295b254c8838933b5b082d75e3cb70c8dab21fdfbcfa9a" +checksum = "97818827ef4f364230e16705d4706e2897df2bb60617d6ca15d598025a3c481f" dependencies = [ "bytes", "futures-channel", @@ -2813,22 +2766,6 @@ dependencies = [ "tower-service", ] -[[package]] -name = "hyper-tls" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" -dependencies = [ - "bytes", - "http-body-util", - "hyper", - "hyper-util", - "native-tls", - "tokio", - "tokio-native-tls", - "tower-service", -] - [[package]] name = "hyper-util" version = "0.1.10" @@ -2986,7 +2923,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -3062,13 +2999,13 @@ dependencies = [ [[package]] name = "impl-trait-for-tuples" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" +checksum = "a0eb5a3343abf848c0984fe4604b2b105da9539376e24fc0a3b0007411ae4fd9" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.89", ] [[package]] @@ -3088,22 +3025,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", - "hashbrown 0.15.1", + "hashbrown 0.15.2", "serde", ] -[[package]] -name = "insta" -version = "1.41.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e9ffc4d4892617c50a928c52b2961cb5174b6fc6ebf252b2fac9d21955c48b8" -dependencies = [ - "console", - "lazy_static", - "linked-hash-map", - "similar", -] - [[package]] name = "instant" version = "0.1.13" @@ -3127,12 +3052,6 @@ version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f958d3d68f4167080a18141e10381e7634563984a537f2a49a30fd8e53ac5767" -[[package]] -name = "ipnet" -version = "2.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddc24109865250148c2e0f3d25d4f0f479571723792d3802153c60922a4fb708" - [[package]] name = "is-terminal" version = "0.4.13" @@ -3185,9 +3104,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.11" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" [[package]] name = "jni" @@ -3199,7 +3118,7 @@ dependencies = [ "combine", "jni-sys", "log", - "thiserror 1.0.68", + "thiserror 1.0.69", "walkdir", ] @@ -3262,7 +3181,7 @@ dependencies = [ "rustls-pki-types", "rustls-platform-verifier", "soketto", - "thiserror 1.0.68", + "thiserror 1.0.69", "tokio", "tokio-rustls", "tokio-util", @@ -3290,7 +3209,7 @@ dependencies = [ "rustc-hash 2.0.0", "serde", "serde_json", - "thiserror 1.0.68", + "thiserror 1.0.69", "tokio", "tokio-stream", "tracing", @@ -3315,7 +3234,7 @@ dependencies = [ "rustls-platform-verifier", "serde", "serde_json", - "thiserror 1.0.68", + "thiserror 1.0.69", "tokio", "tower 0.4.13", "tracing", @@ -3332,7 +3251,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -3354,7 +3273,7 @@ dependencies = [ "serde", "serde_json", "soketto", - "thiserror 1.0.68", + "thiserror 1.0.69", "tokio", "tokio-stream", "tokio-util", @@ -3371,7 +3290,7 @@ dependencies = [ "http", "serde", "serde_json", - "thiserror 1.0.68", + "thiserror 1.0.69", ] [[package]] @@ -3487,9 +3406,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.161" +version = "0.2.166" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" +checksum = "c2ccc108bbc0b1331bd061864e7cd823c0cab660bbe6970e66e2c0614decde36" [[package]] name = "libgit2-sys" @@ -3552,12 +3471,6 @@ dependencies = [ "vcpkg", ] -[[package]] -name = "linked-hash-map" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" - [[package]] name = "linux-raw-sys" version = "0.4.14" @@ -3566,9 +3479,9 @@ checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "litemap" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704" +checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" [[package]] name = "lock_api" @@ -3592,7 +3505,7 @@ version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" dependencies = [ - "hashbrown 0.15.1", + "hashbrown 0.15.2", ] [[package]] @@ -3641,18 +3554,18 @@ dependencies = [ [[package]] name = "metastruct" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f00a5ba4a0f3453c31c397b214e1675d95b697c33763aa58add57ea833424384" +checksum = "d74f54f231f9a18d77393ecc5cc7ab96709b2a61ee326c2b2b291009b0cc5a07" dependencies = [ "metastruct_macro", ] [[package]] name = "metastruct_macro" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c3a991d4536c933306e52f0e8ab303757185ec13a09d1f3e1cbde5a0d8410bf" +checksum = "985e7225f3a4dfbec47a0c6a730a874185fda840d365d7bbd6ba199dd81796d5" dependencies = [ "darling 0.13.4", "itertools 0.10.5", @@ -3718,12 +3631,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "mirai-annotations" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9be0862c1b3f26a88803c4a49de6889c10e608b3ee9344e6ef5b45fb37ad3d1" - [[package]] name = "modular-bitfield" version = "0.11.2" @@ -3763,23 +3670,6 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f247bfe894f8a04e0d8b1eb5eed9dfb7424f6dda47cf83e3f03670e87cb2831b" -[[package]] -name = "native-tls" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" -dependencies = [ - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", -] - [[package]] name = "nom" version = "7.1.3" @@ -3862,7 +3752,7 @@ checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -3916,7 +3806,7 @@ checksum = "7ea7162170c6f3cad8f67f4dd7108e3f78349fd553da5b8bebff1e7ef8f38896" dependencies = [ "alloy-consensus", "alloy-eips", - "alloy-primitives 0.8.11", + "alloy-primitives 0.8.13", "alloy-rlp", "alloy-serde", "derive_more 1.0.0", @@ -3933,7 +3823,7 @@ dependencies = [ "alloy-consensus", "alloy-eips", "alloy-network-primitives", - "alloy-primitives 0.8.11", + "alloy-primitives 0.8.13", "alloy-rpc-types-eth", "alloy-serde", "op-alloy-consensus", @@ -3947,50 +3837,12 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" -[[package]] -name = "openssl" -version = "0.10.68" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5" -dependencies = [ - "bitflags 2.6.0", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-macros", - "openssl-sys", -] - -[[package]] -name = "openssl-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.87", -] - [[package]] name = "openssl-probe" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" -[[package]] -name = "openssl-sys" -version = "0.9.104" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741" -dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", -] - [[package]] name = "overload" version = "0.1.1" @@ -3999,28 +3851,29 @@ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] name = "parity-scale-codec" -version = "3.6.12" +version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee" +checksum = "8be4817d39f3272f69c59fe05d0535ae6456c2dc2fa1ba02910296c7e0a5c590" dependencies = [ "arrayvec", "bitvec", "byte-slice-cast", "impl-trait-for-tuples", "parity-scale-codec-derive", + "rustversion", "serde", ] [[package]] name = "parity-scale-codec-derive" -version = "3.6.12" +version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c" +checksum = "8781a75c6205af67215f382092b6e0a4ff3734798523e69073d4bcd294ec767b" dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.89", ] [[package]] @@ -4090,7 +3943,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "879952a81a83930934cbf1786752d6dedc3b1f29e8f8fb2ad1d0a36f377cf442" dependencies = [ "memchr", - "thiserror 1.0.68", + "thiserror 1.0.69", "ucd-trie", ] @@ -4121,7 +3974,7 @@ checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -4214,7 +4067,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033" dependencies = [ "proc-macro2", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -4282,14 +4135,14 @@ dependencies = [ "proc-macro-error-attr2", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] name = "proc-macro2" -version = "1.0.89" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" dependencies = [ "unicode-ident", ] @@ -4341,7 +4194,7 @@ dependencies = [ "prost", "prost-types", "regex", - "syn 2.0.87", + "syn 2.0.89", "tempfile", ] @@ -4355,7 +4208,7 @@ dependencies = [ "itertools 0.13.0", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -4531,7 +4384,7 @@ checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ "getrandom", "libredox", - "thiserror 1.0.68", + "thiserror 1.0.69", ] [[package]] @@ -4542,7 +4395,7 @@ checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.8", + "regex-automata 0.4.9", "regex-syntax 0.8.5", ] @@ -4557,9 +4410,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", @@ -4578,49 +4431,6 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" -[[package]] -name = "reqwest" -version = "0.12.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a77c62af46e79de0a562e1a9849205ffcb7fc1238876e9bd743357570e04046f" -dependencies = [ - "base64 0.22.1", - "bytes", - "encoding_rs", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "http-body-util", - "hyper", - "hyper-rustls", - "hyper-tls", - "hyper-util", - "ipnet", - "js-sys", - "log", - "mime", - "native-tls", - "once_cell", - "percent-encoding", - "pin-project-lite", - "rustls-pemfile", - "serde", - "serde_json", - "serde_urlencoded", - "sync_wrapper 1.0.1", - "system-configuration", - "tokio", - "tokio-native-tls", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "windows-registry", -] - [[package]] name = "reth-codecs" version = "1.1.0" @@ -4629,7 +4439,7 @@ dependencies = [ "alloy-consensus", "alloy-eips", "alloy-genesis", - "alloy-primitives 0.8.11", + "alloy-primitives 0.8.13", "alloy-trie", "bytes", "modular-bitfield", @@ -4644,7 +4454,7 @@ dependencies = [ "convert_case 0.6.0", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -4653,7 +4463,7 @@ version = "1.1.0" source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.0#1ba631ba9581973e7c6cadeea92cfe1802aceb4a" dependencies = [ "alloy-chains", - "alloy-primitives 0.8.11", + "alloy-primitives 0.8.13", "alloy-rlp", "auto_impl", "crc", @@ -4671,7 +4481,7 @@ source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.0#1ba631ba9581973e7c6 dependencies = [ "alloy-consensus", "alloy-eips", - "alloy-primitives 0.8.11", + "alloy-primitives 0.8.13", "alloy-rlp", "alloy-rpc-types", "alloy-serde", @@ -4702,7 +4512,7 @@ dependencies = [ "alloy-consensus", "alloy-eips", "alloy-genesis", - "alloy-primitives 0.8.11", + "alloy-primitives 0.8.13", "alloy-rlp", "byteorder", "bytes", @@ -4719,7 +4529,7 @@ name = "reth-static-file-types" version = "1.1.0" source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.0#1ba631ba9581973e7c6cadeea92cfe1802aceb4a" dependencies = [ - "alloy-primitives 0.8.11", + "alloy-primitives 0.8.13", "derive_more 1.0.0", "serde", "strum", @@ -4732,7 +4542,7 @@ source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.0#1ba631ba9581973e7c6 dependencies = [ "alloy-consensus", "alloy-genesis", - "alloy-primitives 0.8.11", + "alloy-primitives 0.8.13", "alloy-rlp", "alloy-trie", "bytes", @@ -4753,7 +4563,7 @@ checksum = "6f1525851a03aff9a9d6a1d018b414d76252d6802ab54695b27093ecd7e7a101" dependencies = [ "alloy-eip2930", "alloy-eip7702", - "alloy-primitives 0.8.11", + "alloy-primitives 0.8.13", "auto_impl", "bitflags 2.6.0", "bitvec", @@ -4802,9 +4612,9 @@ dependencies = [ [[package]] name = "roaring" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f4b84ba6e838ceb47b41de5194a60244fac43d9fe03b71dbe8c5a201081d6d1" +checksum = "f81dc953b2244ddd5e7860cb0bb2a790494b898ef321d4aff8e260efab60cc88" dependencies = [ "bytemuck", "byteorder", @@ -4898,7 +4708,7 @@ dependencies = [ "proc-macro2", "quote", "rust-embed-utils", - "syn 2.0.87", + "syn 2.0.89", "walkdir", ] @@ -4959,9 +4769,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.39" +version = "0.38.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "375116bee2be9ed569afe2154ea6a99dfdffd257f533f187498c2a8f5feaf4ee" +checksum = "d7f649912bc1495e167a6edee79151c84b1bad49748cb4f1f1167f459f6224f6" dependencies = [ "bitflags 2.6.0", "errno", @@ -4972,9 +4782,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.16" +version = "0.23.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eee87ff5d9b36712a58574e12e9f0ea80f915a5b0ac518d322b24a465617925e" +checksum = "934b404430bb06b3fae2cba809eb45a1ab1aecd64491213d7c3301b88393f8d1" dependencies = [ "aws-lc-rs", "log", @@ -4996,20 +4806,19 @@ dependencies = [ "rustls-pemfile", "rustls-pki-types", "schannel", - "security-framework", + "security-framework 2.11.1", ] [[package]] name = "rustls-native-certs" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcaf18a4f2be7326cd874a5fa579fae794320a0f388d365dca7e480e55f83f8a" +checksum = "7fcff2dd52b58a8d98a70243663a0d234c4e2b79235637849d15913394a247d3" dependencies = [ "openssl-probe", - "rustls-pemfile", "rustls-pki-types", "schannel", - "security-framework", + "security-framework 3.0.1", ] [[package]] @@ -5033,7 +4842,7 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "afbb878bdfdf63a336a5e63561b1835e7a8c91524f51621db870169eac84b490" dependencies = [ - "core-foundation", + "core-foundation 0.9.4", "core-foundation-sys", "jni", "log", @@ -5042,7 +4851,7 @@ dependencies = [ "rustls-native-certs 0.7.3", "rustls-platform-verifier-android", "rustls-webpki", - "security-framework", + "security-framework 2.11.1", "security-framework-sys", "webpki-roots", "winapi", @@ -5106,9 +4915,9 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.26" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01227be5826fa0690321a2ba6c5cd57a19cf3f6a09e76973b58e61de6ab9d1c1" +checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" dependencies = [ "windows-sys 0.59.0", ] @@ -5159,18 +4968,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ "bitflags 2.6.0", - "core-foundation", + "core-foundation 0.9.4", "core-foundation-sys", "libc", "num-bigint", "security-framework-sys", ] +[[package]] +name = "security-framework" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1415a607e92bec364ea2cf9264646dcce0f91e6d65281bd6f2819cca3bf39c8" +dependencies = [ + "bitflags 2.6.0", + "core-foundation 0.10.0", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + [[package]] name = "security-framework-sys" -version = "2.12.0" +version = "2.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea4a292869320c0272d7bc55a5a6aafaff59b4f63404a003887b679a2e05b4b6" +checksum = "fa39c7303dc58b5543c94d22c1766b0d31f2ee58306363ea622b10bbc075eaa2" dependencies = [ "core-foundation-sys", "libc", @@ -5193,9 +5015,9 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "semver-parser" -version = "0.10.2" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" +checksum = "9900206b54a3527fdc7b8a938bffd94a568bac4f4aa8113b209df75a09c0dec2" dependencies = [ "pest", ] @@ -5208,9 +5030,9 @@ checksum = "f638d531eccd6e23b980caf34876660d38e265409d8e99b397ab71eb3612fad0" [[package]] name = "serde" -version = "1.0.214" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5" +checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" dependencies = [ "serde_derive", ] @@ -5226,20 +5048,20 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.214" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766" +checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] name = "serde_json" -version = "1.0.132" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" +checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" dependencies = [ "itoa", "memchr", @@ -5247,18 +5069,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_urlencoded" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" -dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", -] - [[package]] name = "serde_yaml" version = "0.9.34+deprecated" @@ -5373,12 +5183,6 @@ dependencies = [ "rand_core", ] -[[package]] -name = "similar" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1de1d4f81173b03af4c0cbed3c898f6bff5b870e4a7f5d6f4057d62a7a4b686e" - [[package]] name = "slab" version = "0.4.9" @@ -5407,12 +5211,6 @@ dependencies = [ "serde", ] -[[package]] -name = "snap" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b6b67fb9a61334225b5b790716f609cd58395f895b3fe8b328786812a40bc3b" - [[package]] name = "socket2" version = "0.4.10" @@ -5546,7 +5344,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -5605,9 +5403,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.87" +version = "2.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" +checksum = "44d46482f1c1c87acd84dea20c1bf5ebff4c757009ed6bf19cfd36fb10e92c4e" dependencies = [ "proc-macro2", "quote", @@ -5616,14 +5414,14 @@ dependencies = [ [[package]] name = "syn-solidity" -version = "0.8.11" +version = "0.8.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edf42e81491fb8871b74df3d222c64ae8cbc1269ea509fa768a3ed3e1b0ac8cb" +checksum = "6bdaa7b9e815582ba343a20c66627437cf45f1c6fba7f69772cbfd1358c7e197" dependencies = [ "paste", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -5634,12 +5432,9 @@ checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" [[package]] name = "sync_wrapper" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" -dependencies = [ - "futures-core", -] +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" [[package]] name = "synstructure" @@ -5649,28 +5444,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", -] - -[[package]] -name = "system-configuration" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" -dependencies = [ - "bitflags 2.6.0", - "core-foundation", - "system-configuration-sys", -] - -[[package]] -name = "system-configuration-sys" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" -dependencies = [ - "core-foundation-sys", - "libc", + "syn 2.0.89", ] [[package]] @@ -5681,9 +5455,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.13.0" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b" +checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" dependencies = [ "cfg-if", "fastrand", @@ -5703,42 +5477,42 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.68" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02dd99dc800bbb97186339685293e1cc5d9df1f8fae2d0aecd9ff1c77efea892" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ - "thiserror-impl 1.0.68", + "thiserror-impl 1.0.69", ] [[package]] name = "thiserror" -version = "2.0.0" +version = "2.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15291287e9bff1bc6f9ff3409ed9af665bec7a5fc8ac079ea96be07bca0e2668" +checksum = "c006c85c7651b3cf2ada4584faa36773bd07bac24acfb39f3c431b36d7e667aa" dependencies = [ - "thiserror-impl 2.0.0", + "thiserror-impl 2.0.3", ] [[package]] name = "thiserror-impl" -version = "1.0.68" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7c61ec9a6f64d2793d8a45faba21efbe3ced62a886d44c36a009b2b519b4c7e" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] name = "thiserror-impl" -version = "2.0.0" +version = "2.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22efd00f33f93fa62848a7cab956c3d38c8d43095efda1decfc2b3a5dc0b8972" +checksum = "f077553d607adc1caf65430528a576c757a71ed73944b66ebb58ef2bbd243568" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -5859,9 +5633,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.41.0" +version = "1.41.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "145f3413504347a2be84393cc8a7d2fb4d863b375909ea59f2158261aa258bbb" +checksum = "22cfb5bee7a6a52939ca9224d6ac897bb669134078daa8735560897f69de4d33" dependencies = [ "backtrace", "bytes", @@ -5883,17 +5657,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", -] - -[[package]] -name = "tokio-native-tls" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" -dependencies = [ - "native-tls", - "tokio", + "syn 2.0.89", ] [[package]] @@ -5972,7 +5736,7 @@ dependencies = [ "percent-encoding", "pin-project", "prost", - "rustls-native-certs 0.8.0", + "rustls-native-certs 0.8.1", "rustls-pemfile", "socket2 0.5.7", "tokio", @@ -5995,7 +5759,7 @@ dependencies = [ "prost-build", "prost-types", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -6046,9 +5810,9 @@ checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" -version = "0.1.40" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ "log", "pin-project-lite", @@ -6058,20 +5822,20 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] name = "tracing-core" -version = "0.1.32" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" dependencies = [ "once_cell", "valuable", @@ -6136,7 +5900,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "373495c23db675a5192de8b610395e1bec324d596f9e6111192ce903dc11403a" dependencies = [ - "alloy-primitives 0.8.11", + "alloy-primitives 0.8.13", "ethereum_hashing 0.7.0", "smallvec", ] @@ -6161,7 +5925,7 @@ dependencies = [ "darling 0.20.10", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -6299,7 +6063,7 @@ checksum = "70b20a22c42c8f1cd23ce5e34f165d4d37038f5b663ad20fb6adbdf029172483" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -6364,9 +6128,9 @@ checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893" [[package]] name = "unicode-ident" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" [[package]] name = "unicode-normalization" @@ -6431,9 +6195,9 @@ dependencies = [ [[package]] name = "url" -version = "2.5.3" +version = "2.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d157f1b96d14500ffdc1f10ba712e780825526c03d9a49b4d0324b0d9113ada" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" dependencies = [ "form_urlencoded", "idna 1.0.3", @@ -6577,7 +6341,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", "wasm-bindgen-shared", ] @@ -6611,7 +6375,7 @@ checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -6634,9 +6398,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.26.6" +version = "0.26.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841c67bff177718f1d4dfefde8d8f0e78f9b6589319ba88312f567fc5841a958" +checksum = "5d642ff16b7e79272ae451b7322067cdc17cadf68c23264be9d94a32319efe7e" dependencies = [ "rustls-pki-types", ] @@ -6693,36 +6457,6 @@ dependencies = [ "windows-targets", ] -[[package]] -name = "windows-registry" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" -dependencies = [ - "windows-result", - "windows-strings", - "windows-targets", -] - -[[package]] -name = "windows-result" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-strings" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" -dependencies = [ - "windows-result", - "windows-targets", -] - [[package]] name = "windows-sys" version = "0.52.0" @@ -6837,9 +6571,9 @@ dependencies = [ [[package]] name = "yoke" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c5b1314b079b0930c31e3af543d8ee1757b1951ae1e1565ec704403a7240ca5" +checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" dependencies = [ "serde", "stable_deref_trait", @@ -6849,13 +6583,13 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95" +checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", "synstructure", ] @@ -6877,27 +6611,27 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] name = "zerofrom" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ec111ce797d0e0784a1116d0ddcdbea84322cd79e5d5ad173daeba4f93ab55" +checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" dependencies = [ "zerofrom-derive", ] [[package]] name = "zerofrom-derive" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5" +checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", "synstructure", ] @@ -6918,7 +6652,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -6940,7 +6674,7 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 197c9bbb..fed56cd8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,6 +16,7 @@ dotenvy = "0.15.7" ethereum-types = "=0.14.1" ethportal-api = { git = "https://github.com/ethereum/trin.git", version = "0.2.2", tag = "v0.1.0-alpha.51" } fake = "2.10.0" +firehose-rs = { git = "https://github.com/semiotic-ai/firehose-rs.git", branch = "main" } futures = "0.3.31" hex = "0.4.3" http = "1.1.0" diff --git a/README.md b/README.md index d8d01f59..a576cd2a 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,6 @@ Semiotic Labs monorepo for Verifiable Extraction of blockchain data. ## Crates -- [firehose-client](./crates/firehose-client/README.md) - [firehose-protos](./crates/firehose-protos/README.md) - [flat-files-decoder](./crates/flat-files-decoder/README.md) -- [forrestrie](./crates/forrestrie/README.md) -- [forrestrie-examples](./crates/forrestrie-examples/README.md) - [header-accumulator](./crates/header-accumulator/README.md) diff --git a/crates/firehose-client/CHANGELOG.md b/crates/firehose-client/CHANGELOG.md deleted file mode 100644 index 2e302c2f..00000000 --- a/crates/firehose-client/CHANGELOG.md +++ /dev/null @@ -1,8 +0,0 @@ -# Changelog - -## [0.1.1](https://github.com/semiotic-ai/veemon/compare/firehose-client-v0.1.0...firehose-client-v0.1.1) (2024-10-22) - - -### Bug Fixes - -* **firehose-client:** fix chain specification in client ([a37c8e8](https://github.com/semiotic-ai/veemon/commit/a37c8e81d20075c0980e50a039cb580bcaaa85d1)) diff --git a/crates/firehose-client/Cargo.toml b/crates/firehose-client/Cargo.toml deleted file mode 100644 index d0fa4f11..00000000 --- a/crates/firehose-client/Cargo.toml +++ /dev/null @@ -1,27 +0,0 @@ -[package] -name = "firehose-client" -version = "0.1.1" -edition = "2021" - -[lib] -name = "firehose_client" -path = "src/lib.rs" - -[dependencies] -dotenvy.workspace = true -forrestrie = { path = "../forrestrie" } -firehose-protos = { path = "../firehose-protos" } -futures.workspace = true -http.workspace = true -once_cell.workspace = true -rustls.workspace = true -serde = { workspace = true, features = ["derive"] } -serde_derive.workspace = true -thiserror.workspace = true -tokio = { workspace = true, features = ["macros", "rt-multi-thread"] } -tokio-stream.workspace = true -tonic = { workspace = true, features = ["tls-roots"] } -tracing.workspace = true - -[dev-dependencies] -hex.workspace = true diff --git a/crates/firehose-client/README.md b/crates/firehose-client/README.md deleted file mode 100644 index d860b723..00000000 --- a/crates/firehose-client/README.md +++ /dev/null @@ -1,80 +0,0 @@ -# Firehose Rust Client - -Extract blocks from [StreamingFast Firehose](https://firehose.streamingfast.io/) -programatically in Rust. - -## gRPC Endpoints - -### Env Vars - -Use environment variables to provide Firehose Ethereum and Firehose -Beacon providers of your choice. - -To do this, place a `.env` file in the root of the `veemon` repository. -See the `.env.example` file, also in the root of this repository, for what -you'll need, depending on your requirements. You may have access to a -Firehose provider and/or may need to use a provider. For example, you can -use [Pinax](https://app.pinax.network/) as an endpoint provider. - -## firehose-ethereum and firehose-beacon gRPC - -### proto files - -We use the following protobuffers developed by Streamingfast via our -[`firehose-protos` crate](./../firehose-protos/README.md): - -See the [`firehose-protos` docs](./../firehose-protos/README.md) for information -on these protobuffers and links to the different repos that they've come from. - -Also check out [`forrestrie`](./../forrestrie/protos/README.md) for -Rust-compiled protobuffer Beacon block implementations. - -### gRPC Service Examples - -If you're looking to quickly explore what the Firehose API offers, -you can use the `grpcurl` tool to test your connection, verify your -API token, and get a list of available gRPC services. This is a great -way to interact with the API without writing any code. - -To get started, you can run the following command to retrieve the -service descriptions from the Firehose gRPC server: - -```bash -grpcurl -plaintext : describe -``` - -Below is an example of the service descriptions you might see when -querying the Firehose server: - -```terminal -grpc.health.v1.Health is a service: -service Health { - rpc Check ( .grpc.health.v1.HealthCheckRequest ) returns ( .grpc.health.v1.HealthCheckResponse ); - rpc Watch ( .grpc.health.v1.HealthCheckRequest ) returns ( stream .grpc.health.v1.HealthCheckResponse ); -} - -grpc.reflection.v1.ServerReflection is a service: -service ServerReflection { - rpc ServerReflectionInfo ( stream .grpc.reflection.v1.ServerReflectionRequest ) returns ( stream .grpc.reflection.v1.ServerReflectionResponse ); -} - -grpc.reflection.v1alpha.ServerReflection is a service: -service ServerReflection { - rpc ServerReflectionInfo ( stream .grpc.reflection.v1alpha.ServerReflectionRequest ) returns ( stream .grpc.reflection.v1alpha.ServerReflectionResponse ); -} - -sf.firehose.v1.Stream is a service: -service Stream { - rpc Blocks ( .sf.firehose.v1.Request ) returns ( stream .sf.firehose.v1.Response ); -} - -sf.firehose.v2.Fetch is a service: -service Fetch { - rpc Block ( .sf.firehose.v2.SingleBlockRequest ) returns ( .sf.firehose.v2.SingleBlockResponse ); -} - -sf.firehose.v2.Stream is a service: -service Stream { - rpc Blocks ( .sf.firehose.v2.Request ) returns ( stream .sf.firehose.v2.Response ); -} -``` diff --git a/crates/firehose-client/examples/fetch_beacon.rs b/crates/firehose-client/examples/fetch_beacon.rs deleted file mode 100644 index 73ce43cb..00000000 --- a/crates/firehose-client/examples/fetch_beacon.rs +++ /dev/null @@ -1,58 +0,0 @@ -//! # Fetch Beacon Block -//! -//! Demonstrates how to fetch a single block from Beacon Firehose, using the `Fetch` API. - -use firehose_client::{Chain, FirehoseClient}; -use firehose_protos::EthBlock; -use forrestrie::beacon_v1::{block::Body, Block as BeaconBlock}; - -#[tokio::main] -async fn main() { - // Show matching data from execution layer and beacon chain - let mut execution_layer_client = FirehoseClient::new(Chain::Ethereum); - - let response = execution_layer_client - .fetch_block(20672593) - .await - .unwrap() - .unwrap(); - - let block = EthBlock::try_from(response.into_inner()).unwrap(); - - assert_eq!(block.number, 20672593); - assert_eq!( - format!("0x{}", hex::encode(block.hash)).as_str(), - "0xea48ba1c8e38ea586239e9c5ec62949ddd79404c6006c099bb02a8b22ddd18e4" - ); - - let mut beacon_client = FirehoseClient::new(Chain::Beacon); - // This is the slot number for the Beacon block we want to fetch, but right now - // we don't have a way to map the block number of the execution block to the slot number - // of the Beacon block. - let response = beacon_client.fetch_block(9881091).await.unwrap().unwrap(); - let block = BeaconBlock::try_from(response.into_inner()).unwrap(); - - assert_eq!(block.slot, 9881091); - - let body = block.body.as_ref().unwrap(); - - match body { - Body::Deneb(body) => { - let execution_payload = body.execution_payload.as_ref().unwrap(); - - let block_hash = &execution_payload.block_hash; - - assert_eq!( - format!("0x{}", hex::encode(block_hash)).as_str(), - "0xea48ba1c8e38ea586239e9c5ec62949ddd79404c6006c099bb02a8b22ddd18e4" - ); - - let block_number = execution_payload.block_number; - - assert_eq!(block_number, 20672593); - } - _ => unimplemented!(), - }; - - println!("fetch_beacon ran to completion!"); -} diff --git a/crates/firehose-client/examples/fetch_ethereum.rs b/crates/firehose-client/examples/fetch_ethereum.rs deleted file mode 100644 index 5575f08b..00000000 --- a/crates/firehose-client/examples/fetch_ethereum.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! # Fetch Ethereum Block -//! -//! Demonstrates how to fetch a single block from Ethereum firehose. - -use firehose_client::{Chain, FirehoseClient}; -use firehose_protos::EthBlock as Block; - -#[tokio::main] -async fn main() { - let mut client = FirehoseClient::new(Chain::Ethereum); - let response = client.fetch_block(20672593).await.unwrap().unwrap(); - let block = Block::try_from(response.into_inner()).unwrap(); - - assert_eq!(block.number, 20672593); - assert_eq!( - format!("0x{}", hex::encode(block.hash)).as_str(), - "0xea48ba1c8e38ea586239e9c5ec62949ddd79404c6006c099bb02a8b22ddd18e4" - ); - - println!("fetch_beacon completed successfully!"); -} diff --git a/crates/firehose-client/examples/stream_beacon.rs b/crates/firehose-client/examples/stream_beacon.rs deleted file mode 100644 index da53428d..00000000 --- a/crates/firehose-client/examples/stream_beacon.rs +++ /dev/null @@ -1,32 +0,0 @@ -//! # Example: Stream Beacon Blocks -//! -//! Demonstrates how to stream a range of blocks from Firehose Beacon - -use firehose_client::{Chain, FirehoseClient}; -use forrestrie::beacon_v1::Block as FirehoseBeaconBlock; -use futures::StreamExt; - -#[tokio::main] -async fn main() { - // Testing this so far without proper benchmarking, the time taken to fetch the blocks - // grows linearly with the number of TOTAL_BLOCKS requested, to around 20 minutes for 8192 blocks! - const TOTAL_SLOTS: u64 = 100; - const START_SLOT: u64 = 9968872; - - let mut client = FirehoseClient::new(Chain::Beacon); - let mut stream = client - .stream_beacon_with_retry(START_SLOT, TOTAL_SLOTS) - .await - .unwrap(); - - let mut blocks: Vec = Vec::with_capacity(TOTAL_SLOTS as usize); - - while let Some(block) = stream.next().await { - blocks.push(block); - } - - // For now, just using this to signal that the test has completed - assert_eq!(blocks.len(), TOTAL_SLOTS as usize); - - println!("stream_beacon ran to completion!"); -} diff --git a/crates/firehose-client/examples/stream_ethereum.rs b/crates/firehose-client/examples/stream_ethereum.rs deleted file mode 100644 index 7962e90b..00000000 --- a/crates/firehose-client/examples/stream_ethereum.rs +++ /dev/null @@ -1,31 +0,0 @@ -//! # Example: Stream Ethereum Blocks -//! -//! This example demonstrates how to stream Ethereum blocks using the Firehose client. -use firehose_client::{Chain, FirehoseClient}; -use firehose_protos::EthBlock as Block; -use futures::StreamExt; - -#[tokio::main] -async fn main() { - // Testing this so far without proper benchmarking, the time taken to fetch the blocks - // grows linearly with the number of TOTAL_BLOCKS requested, to around 20 minutes for 8192 blocks! - const TOTAL_BLOCKS: u64 = 100; - const START_BLOCK: u64 = 19581798; - - let mut client = FirehoseClient::new(Chain::Ethereum); - let mut stream = client - .stream_blocks(START_BLOCK, TOTAL_BLOCKS) - .await - .unwrap(); - - let mut blocks: Vec = Vec::with_capacity(TOTAL_BLOCKS as usize); - - while let Some(block) = stream.next().await { - blocks.push(block); - } - - // For now, just using this to signal that the test has completed - assert_eq!(blocks.len(), TOTAL_BLOCKS as usize); - - println!("stream_ethereum ran successfully"); -} diff --git a/crates/firehose-client/src/client.rs b/crates/firehose-client/src/client.rs deleted file mode 100644 index 097e07ce..00000000 --- a/crates/firehose-client/src/client.rs +++ /dev/null @@ -1,290 +0,0 @@ -use std::str::FromStr; - -use crate::error::ClientError; -use dotenvy::{dotenv, var}; -use firehose_protos::{ - EthBlock as Block, FetchClient, Request, SingleBlockRequest, SingleBlockResponse, StreamClient, -}; -use forrestrie::beacon_v1::Block as FirehoseBeaconBlock; -use tokio_stream::wrappers::ReceiverStream; -use tonic::{ - transport::{Channel, Uri}, - Response, Status, -}; -use tracing::{error, info, trace}; - -/// Work with the fetch and streaming APIs supported by [StreamingFast Firehose](https://firehose.streamingfast.io/). -pub struct FirehoseClient { - chain: Chain, - fetch_client: Option>, - stream_client: Option>, -} - -impl FirehoseClient { - pub fn new(chain: Chain) -> Self { - Self { - chain, - fetch_client: None, - stream_client: None, - } - } - - /// The inner [`Result`] is the Firehose response, which can be either a [`Response`] or a [`Status`], - /// which is needed for handling empty slots on the Beacon chain. - pub async fn fetch_block( - &mut self, - number: u64, - ) -> Result, Status>, ClientError> { - if self.fetch_client.is_none() { - self.fetch_client = Some(fetch_client(self.chain).await?); - } - let mut request = create_single_block_fetch_request(number); - - request.insert_api_key_if_provided(self.chain); - - info!("Requesting block number:\n\t{}", number); - Ok(self.fetch_client.as_mut().unwrap().block(request).await) - } - - /// The tonic docs encourage cloning the client. - pub async fn get_streaming_client(&mut self) -> Result, ClientError> { - let client = if let Some(client) = self.stream_client.clone() { - client - } else { - self.stream_client = Some(stream_client(self.chain).await?); - self.stream_client.clone().unwrap() - }; - Ok(client) - } - - /// Stream a block range of Beacon blocks, with a retry mechanism if the stream cuts off - /// before the total number of blocks requested is reached, and accounting for missed slots. - pub async fn stream_beacon_with_retry( - &mut self, - start: u64, - total: u64, - ) -> Result, ClientError> { - let (tx, rx) = tokio::sync::mpsc::channel::(8192); - - let chain = self.chain; - let client = self.get_streaming_client().await?; - - tokio::spawn(async move { - let mut blocks = 0; - let mut last_valid_slot: Option = None; - let mut last_valid_block: Option = None; - - while blocks < total { - let mut client = client.clone(); - let request = create_blocks_streaming_request( - chain, - start + blocks, - start + total - 1, - BlocksRequested::All, - ); - match client.blocks(request).await { - Ok(response) => { - let mut stream_inner = response.into_inner(); - while let Ok(Some(block_msg)) = stream_inner.message().await { - if blocks % 100 == 0 { - trace!("Blocks fetched: {}", blocks); - } - match FirehoseBeaconBlock::try_from(block_msg) { - Ok(block) => { - if let Some(last_slot) = last_valid_slot { - let missed_slots = block.slot.saturating_sub(last_slot + 1); - if missed_slots > 0 { - trace!("Missed block at slot: {}", start + blocks); - - let last_block = last_valid_block.take().unwrap(); - let tx = tx.clone(); - for _ in 0..missed_slots { - blocks += 1; - tx.send(last_block.clone()).await.unwrap(); - } - } - } - last_valid_slot = Some(block.slot); - last_valid_block = Some(block.clone()); - - blocks += 1; - tx.clone().send(block).await.unwrap(); - } - Err(e) => { - error!("Failed to convert block message to block: {e}"); - break; - } - } - } - } - Err(e) => { - error!("Failed to get blocks stream: {:?}", e.code()); - break; - } - }; - } - }); - - Ok(ReceiverStream::new(rx)) - } - - pub async fn stream_blocks( - &mut self, - start: u64, - total: u64, - ) -> Result, ClientError> { - let (tx, rx) = tokio::sync::mpsc::channel::(8192); - - let chain = self.chain; - let client = self.get_streaming_client().await?; - - tokio::spawn(async move { - let mut blocks = 0; - - while blocks < total { - let mut client = client.clone(); - let request = create_blocks_streaming_request( - chain, - start + blocks, - start + total - 1, - BlocksRequested::All, - ); - let response = client.blocks(request).await.unwrap(); - let mut stream_inner = response.into_inner(); - while let Ok(Some(block_msg)) = stream_inner.message().await { - if blocks % 100 == 0 && blocks != 0 { - trace!("Blocks fetched: {}", blocks); - } - match Block::try_from(block_msg) { - Ok(block) => { - blocks += 1; - tx.clone().send(block).await.unwrap(); - } - Err(e) => { - panic!("Failed to convert block message to block: {e}"); - } - } - } - } - }); - - Ok(ReceiverStream::new(rx)) - } -} - -async fn build_and_connect_channel(uri: Uri) -> Result { - if uri.scheme_str() != Some("https") { - return Channel::builder(uri).connect().await; - } - - let config = crate::tls::config(); - - Channel::builder(uri) - .tls_config(config.clone())? - .connect() - .await -} - -fn create_blocks_streaming_request( - chain: Chain, - start_block_num: u64, - stop_block_num: u64, - blocks_requested: BlocksRequested, -) -> tonic::Request { - let mut request = tonic::Request::new(Request { - start_block_num: start_block_num as i64, - stop_block_num, - final_blocks_only: blocks_requested.into(), - ..Default::default() - }); - request.insert_api_key_if_provided(chain); - request -} - -async fn fetch_client(firehose: Chain) -> Result, ClientError> { - Ok(FetchClient::new({ - let uri = firehose.uri_from_env()?; - build_and_connect_channel(uri).await? - })) -} - -async fn stream_client(firehose: Chain) -> Result, ClientError> { - Ok(StreamClient::new({ - let uri = firehose.uri_from_env()?; - build_and_connect_channel(uri).await? - })) -} - -pub enum BlocksRequested { - All, - FinalOnly, -} - -impl From for bool { - fn from(blocks_requested: BlocksRequested) -> bool { - match blocks_requested { - BlocksRequested::All => false, - BlocksRequested::FinalOnly => true, - } - } -} - -/// Create a [`SingleBlockRequest`] for the given *number*. -/// Number is slot number for beacon blocks. -fn create_single_block_fetch_request(num: u64) -> tonic::Request { - tonic::Request::new(SingleBlockRequest::new(num)) -} - -trait FirehoseRequest { - fn insert_api_key_if_provided(&mut self, endpoint: Chain); -} - -impl FirehoseRequest for tonic::Request { - fn insert_api_key_if_provided(&mut self, endpoint: Chain) { - insert_api_key_if_provided(self, endpoint); - } -} - -fn insert_api_key_if_provided(request: &mut tonic::Request, chain: Chain) { - if let Ok(api_key) = var(chain.api_key_env_var_as_str()) { - let api_key_header = - tonic::metadata::MetadataValue::from_str(&api_key).expect("Invalid API key format"); - request.metadata_mut().insert("x-api-key", api_key_header); - } -} - -/// Extract blocks with [`FirehoseClient`] from an extendable union of chain variants. -#[derive(Clone, Copy, Debug)] -pub enum Chain { - Ethereum, - Beacon, - Arbitrum, -} - -impl Chain { - fn api_key_env_var_as_str(&self) -> &str { - match self { - Self::Beacon => "BEACON_API_KEY", - Self::Ethereum => "ETHEREUM_API_KEY", - Self::Arbitrum => "ARBITRUM_API_KEY", - } - } - - fn uri_from_env(&self) -> Result { - dotenv()?; - - let (url, port) = match self { - Self::Ethereum => ( - var("FIREHOSE_ETHEREUM_URL")?, - var("FIREHOSE_ETHEREUM_PORT")?, - ), - Self::Beacon => (var("FIREHOSE_BEACON_URL")?, var("FIREHOSE_BEACON_PORT")?), - Self::Arbitrum => ( - var("FIREHOSE_ARBITRUM_URL")?, - var("FIREHOSE_ARBITRUM_PORT")?, - ), - }; - - Ok(format!("{}:{}", url, port).parse::()?) - } -} diff --git a/crates/firehose-client/src/error.rs b/crates/firehose-client/src/error.rs deleted file mode 100644 index e1a9feae..00000000 --- a/crates/firehose-client/src/error.rs +++ /dev/null @@ -1,17 +0,0 @@ -use http::uri::InvalidUri; -use thiserror::Error; - -#[derive(Debug, Error)] -pub enum ClientError { - #[error("Missing environment variable: {0}")] - EnvVarMissing(#[from] dotenvy::Error), - - #[error("gRPC error: {0}")] - GRpc(#[from] tonic::transport::Error), - - #[error("{0}")] - TonicStatus(#[from] tonic::Status), - - #[error("Invalid URI: {0}")] - UriInvalid(#[from] InvalidUri), -} diff --git a/crates/firehose-client/src/lib.rs b/crates/firehose-client/src/lib.rs deleted file mode 100644 index 19d5d9fe..00000000 --- a/crates/firehose-client/src/lib.rs +++ /dev/null @@ -1,55 +0,0 @@ -//! # Rust Firehose Client -//! -//! Rust implementation of a client for the [StreamingFast Firehose](https://firehose.streamingfast.io/) -//! gRPC Fetch `Block` and Stream `Block`s APIs. -//! -//! ## Fetching an Ethereum Block -//! -//! ```no_run -//! # use firehose_client::{Chain, FirehoseClient}; -//! # use firehose_protos::EthBlock as Block; -//! # #[tokio::main] -//! # async fn main() -> Result<(), firehose_protos::ProtosError> { -//! let mut client = FirehoseClient::new(Chain::Ethereum); -//! -//! if let Some(response) = client.fetch_block(20672593).await.unwrap().ok() { -//! let block = Block::try_from(response.into_inner())?; -//! assert_eq!(block.number, 20672593); -//! assert_eq!( -//! format!("0x{}", hex::encode(block.hash)).as_str(), -//! "0xea48ba1c8e38ea586239e9c5ec62949ddd79404c6006c099bb02a8b22ddd18e4" -//! ); -//! } -//! # Ok(()) -//! # } -//! ``` -//! -//! ## Streaming Ethereum Blocks -//! -//! ```no_run -//! # use firehose_client::{Chain, FirehoseClient}; -//! # use futures::StreamExt; -//! # #[tokio::main] -//! # async fn main() -> Result<(), firehose_protos::ProtosError> { -//! const TOTAL_BLOCKS: u64 = 8192; -//! const START_BLOCK: u64 = 19581798; -//! -//! let mut client = FirehoseClient::new(Chain::Ethereum); -//! let mut stream = client -//! .stream_blocks(START_BLOCK, TOTAL_BLOCKS) -//! .await -//! .unwrap(); -//! -//! while let Some(block) = stream.next().await { -//! // Do Something with the extracted stream of blocks. -//! } -//! # Ok(()) -//! # } -//! ``` -//! - -mod client; -mod error; -mod tls; - -pub use crate::client::{Chain, FirehoseClient}; diff --git a/crates/firehose-client/src/tls.rs b/crates/firehose-client/src/tls.rs deleted file mode 100644 index c96a28f1..00000000 --- a/crates/firehose-client/src/tls.rs +++ /dev/null @@ -1,17 +0,0 @@ -use once_cell::sync::Lazy; - -use tonic::transport::ClientTlsConfig; - -static TLS_CONFIG: Lazy = Lazy::new(|| { - rustls::crypto::ring::default_provider() - .install_default() - .expect("Failed to install rustls crypto provider"); - - ClientTlsConfig::new() - .with_native_roots() - .assume_http2(true) -}); - -pub fn config() -> &'static ClientTlsConfig { - &TLS_CONFIG -} diff --git a/crates/firehose-protos-examples/Cargo.toml b/crates/firehose-protos-examples/Cargo.toml index 2f7af854..f066b0cf 100644 --- a/crates/firehose-protos-examples/Cargo.toml +++ b/crates/firehose-protos-examples/Cargo.toml @@ -5,6 +5,7 @@ edition = "2021" [dev-dependencies] alloy-primitives.workspace = true -firehose-client = { path = "../firehose-client" } +firehose-client = { git = "https://github.com/semiotic-ai/firehose-client.git", branch = "main" } firehose-protos = { path = "../firehose-protos" } +firehose-rs.workspace = true tokio.workspace = true diff --git a/crates/firehose-protos/Cargo.toml b/crates/firehose-protos/Cargo.toml index 14c56e28..194c7bfd 100644 --- a/crates/firehose-protos/Cargo.toml +++ b/crates/firehose-protos/Cargo.toml @@ -14,6 +14,7 @@ alloy-eip2930.workspace = true alloy-primitives.workspace = true alloy-rlp.workspace = true ethportal-api.workspace = true +firehose-rs.workspace = true primitive-types.workspace = true prost.workspace = true prost-wkt.workspace = true diff --git a/crates/firehose-protos/README.md b/crates/firehose-protos/README.md index 759d4bc3..71928635 100644 --- a/crates/firehose-protos/README.md +++ b/crates/firehose-protos/README.md @@ -13,7 +13,3 @@ Representation of the tracing of a block in the Ethereum blockchain. ### [`bstream.proto`](https://github.com/streamingfast/bstream/blob/develop/proto/sf/bstream/v1/bstream.proto) `Block` type from the Streamingfast block streaming Handlers library. Lower level building block of dfuse. - -### [`firehose.proto`](https://github.com/streamingfast/proto/blob/develop/sf/firehose/v2/firehose.proto) - -Firehose fetch and streaming, client and server gRPC implementation. diff --git a/crates/firehose-protos/build.rs b/crates/firehose-protos/build.rs index c94ae683..142367bf 100644 --- a/crates/firehose-protos/build.rs +++ b/crates/firehose-protos/build.rs @@ -19,11 +19,7 @@ fn main() { .file_descriptor_set_path(out_dir.join("descriptors.bin")) .compile_protos_with_config( config, - &[ - "protos/block.proto", - "protos/bstream.proto", - "protos/firehose.proto", - ], + &["protos/block.proto", "protos/bstream.proto"], &["protos/"], ) .unwrap(); diff --git a/crates/firehose-protos/protos/firehose.proto b/crates/firehose-protos/protos/firehose.proto deleted file mode 100644 index 5299bd8d..00000000 --- a/crates/firehose-protos/protos/firehose.proto +++ /dev/null @@ -1,150 +0,0 @@ -syntax = "proto3"; - -package sf.firehose.v2; - -import "google/protobuf/any.proto"; -import "google/protobuf/timestamp.proto"; - -option go_package = "github.com/streamingfast/pbgo/sf/firehose/v2;pbfirehose"; - -service Stream { - rpc Blocks(Request) returns (stream Response); -} - -service Fetch { - rpc Block(SingleBlockRequest) returns (SingleBlockResponse); -} - -message SingleBlockRequest { - - // Get the current known canonical version of a block at with this number - message BlockNumber{ - uint64 num=1; - } - - // Get the current block with specific hash and number - message BlockHashAndNumber{ - uint64 num=1; - string hash=2; - } - - // Get the block that generated a specific cursor - message Cursor{ - string cursor=1; - } - - oneof reference{ - BlockNumber block_number=3; - BlockHashAndNumber block_hash_and_number=4; - Cursor cursor=5; - } - - repeated google.protobuf.Any transforms = 6; -} - -message SingleBlockResponse { - google.protobuf.Any block = 1; - - // Metadata about the block, added in some Firehose version, so consumer - // should be ready to handle the absence of this field. - BlockMetadata metadata = 2; -} - -message Request { - - // Controls where the stream of blocks will start. - // - // The stream will start **inclusively** at the requested block num. - // - // When not provided, starts at first streamable block of the chain. Not all - // chain starts at the same block number, so you might get an higher block than - // requested when using default value of 0. - // - // Can be negative, will be resolved relative to the chain head block, assuming - // a chain at head block #100, then using `-50` as the value will start at block - // #50. If it resolves before first streamable block of chain, we assume start - // of chain. - // - // If `start_cursor` is given, this value is ignored and the stream instead starts - // immediately after the Block pointed by the opaque `start_cursor` value. - int64 start_block_num = 1; - - // Controls where the stream of blocks will start which will be immediately after - // the Block pointed by this opaque cursor. - // - // Obtain this value from a previously received `Response.cursor`. - // - // This value takes precedence over `start_block_num`. - string cursor = 2; - - // When non-zero, controls where the stream of blocks will stop. - // - // The stream will close **after** that block has passed so the boundary is - // **inclusive**. - uint64 stop_block_num = 3; - - // With final_block_only, you only receive blocks with STEP_FINAL - // Default behavior will send blocks as STEP_NEW, with occasional STEP_UNDO - bool final_blocks_only = 4; - - repeated google.protobuf.Any transforms = 10; -} - -message Response { - // Chain specific block payload, ex: - // - sf.eosio.type.v1.Block - // - sf.ethereum.type.v1.Block - // - sf.near.type.v1.Block - google.protobuf.Any block = 1; - ForkStep step = 6; - string cursor = 10; - - // Metadata about the block, added in some Firehose version, so consumer - // should be ready to handle the absence of this field. - BlockMetadata metadata = 12; -} - -message BlockMetadata { - // Num is the block number of this response's block. - uint64 num = 1; - // ID is the block ID of this response's block. The ID actual representation is chain specific. - // - Antelope & Ethereum uses hex. - // - NEAR & Solana uses base58. - // - // Refer to the chain documentation for more details. - string id = 2; - - // ParentNum is the block number of the parent of this response's block - uint64 parent_num = 3; - - // ParentID is the block ID of the parent of this response's block. If this response is the genesis block, - // this field is empty. - // - // The ID actual representation is chain specific. - // - Antelope & Ethereum uses hex. - // - NEAR & Solana uses base58. - // - // Refer to the chain documentation for more details. - string parent_id = 4; - - // LibNum is the block number of the last irreversible block (a.k.a last finalized block) at the time of this - // response' block. It determines the finality of the block. - uint64 lib_num = 5; - - // Time is the time at which the block was produced. - google.protobuf.Timestamp time = 6; -} - -enum ForkStep { - STEP_UNSET = 0; - - // Incoming block - STEP_NEW = 1; - - // A reorg caused this specific block to be excluded from the chain - STEP_UNDO = 2; - - // Block is now final and can be committed (finality is chain specific, - // see chain documentation for more details) - STEP_FINAL = 3; -} diff --git a/crates/firehose-protos/src/ethereum_v2/eth_block.rs b/crates/firehose-protos/src/ethereum_v2/eth_block.rs index 49f7f46f..e0d43f09 100644 --- a/crates/firehose-protos/src/ethereum_v2/eth_block.rs +++ b/crates/firehose-protos/src/ethereum_v2/eth_block.rs @@ -2,6 +2,7 @@ use super::{Block, BlockHeader, TransactionReceipt, TransactionTrace}; use alloy_primitives::{hex, Address, Bloom, FixedBytes, Uint, B256}; use alloy_rlp::{Encodable, Header as RlpHeader}; use ethportal_api::types::execution::header::Header; +use firehose_rs::{FromResponse, HasNumberOrSlot, Response, SingleBlockResponse}; use prost::Message; use prost_wkt_types::Any; use reth_primitives::{ @@ -10,10 +11,7 @@ use reth_primitives::{ use reth_trie_common::root::ordered_trie_root_with_encoder; use tracing::error; -use crate::{ - error::ProtosError, - firehose_v2::{Response, SingleBlockResponse}, -}; +use crate::error::ProtosError; impl TryFrom<&Block> for Header { type Error = ProtosError; @@ -360,6 +358,20 @@ impl FullReceipt { } } +impl FromResponse for Block { + type Error = ProtosError; + + fn from_response(msg: Response) -> Result { + Self::try_from(msg) + } +} + +impl HasNumberOrSlot for Block { + fn number_or_slot(&self) -> u64 { + self.number + } +} + #[cfg(test)] mod tests { use ethportal_api::Header; diff --git a/crates/firehose-protos/src/firehose_v2/mod.rs b/crates/firehose-protos/src/firehose_v2/mod.rs deleted file mode 100644 index c90bfe8b..00000000 --- a/crates/firehose-protos/src/firehose_v2/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub mod request; - -tonic::include_proto!("sf.firehose.v2"); diff --git a/crates/firehose-protos/src/firehose_v2/request.rs b/crates/firehose-protos/src/firehose_v2/request.rs deleted file mode 100644 index 036f03d4..00000000 --- a/crates/firehose-protos/src/firehose_v2/request.rs +++ /dev/null @@ -1,13 +0,0 @@ -use crate::BlockNumber; - -use super::{single_block_request::Reference, SingleBlockRequest}; - -impl SingleBlockRequest { - /// Create a Firehose [`SingleBlockRequest`] for the given *block number*. - pub fn new(num: u64) -> SingleBlockRequest { - SingleBlockRequest { - reference: Some(Reference::BlockNumber(BlockNumber { num })), - ..Default::default() - } - } -} diff --git a/crates/firehose-protos/src/lib.rs b/crates/firehose-protos/src/lib.rs index b111f2f8..b2aac611 100644 --- a/crates/firehose-protos/src/lib.rs +++ b/crates/firehose-protos/src/lib.rs @@ -16,7 +16,6 @@ mod error; mod ethereum_v2; -mod firehose_v2; mod bstream { pub mod v1 { @@ -27,22 +26,3 @@ mod bstream { pub use bstream::v1::Block as BstreamBlock; pub use error::ProtosError; pub use ethereum_v2::{eth_block::FullReceipt, Block as EthBlock, BlockHeader}; -pub(crate) use firehose_v2::single_block_request::BlockNumber; - -/// Interact programatically with the Firehose v2 Fetch API. -pub use firehose_v2::fetch_client::FetchClient; - -/// Create Firehose API fetch requests. -pub use firehose_v2::Request; - -/// Work with Firehose API streaming responses. -pub use firehose_v2::Response; - -/// Create Firehose API streaming requests. -pub use firehose_v2::SingleBlockRequest; - -/// Receive Firehose API fetch responses. -pub use firehose_v2::SingleBlockResponse; - -/// Work with the Firehose v2 Stream API. -pub use firehose_v2::stream_client::StreamClient; diff --git a/crates/forrestrie-examples/Cargo.toml b/crates/forrestrie-examples/Cargo.toml deleted file mode 100644 index 73c62268..00000000 --- a/crates/forrestrie-examples/Cargo.toml +++ /dev/null @@ -1,34 +0,0 @@ -[package] -name = "forrestrie-examples" -version = "0.1.1" -edition = "2021" - -[dev-dependencies] -bls.workspace = true -ethportal-api.workspace = true -firehose-client = { path = "../firehose-client" } -firehose-protos = { path = "../firehose-protos" } -forrestrie = { path = "../forrestrie" } -futures.workspace = true -insta.workspace = true -merkle_proof.workspace = true -primitive-types.workspace = true -prost.workspace = true -prost-wkt.workspace = true -prost-wkt-types.workspace = true -reqwest = { workspace = true, features = ["json"] } -reth-primitives.workspace = true -reth-trie-common.workspace = true -serde = { workspace = true, features = ["derive"] } -snap = "1.1.1" -ssz_types = "0.8.0" -ethereum_ssz = "0.7.1" -ethereum_ssz_derive = "0.7.1" -serde_json.workspace = true -tokio = { workspace = true, features = ["macros", "rt-multi-thread"] } -trin-validation = { git = "https://github.com/ethereum/trin.git", version = "0.1.0", tag = "v0.1.0-alpha.51" } -tonic.workspace = true -tracing.workspace = true -tracing-subscriber = "0.3" -tree_hash = "0.6.0" -types.workspace = true diff --git a/crates/forrestrie-examples/README.md b/crates/forrestrie-examples/README.md deleted file mode 100644 index 2063021f..00000000 --- a/crates/forrestrie-examples/README.md +++ /dev/null @@ -1,14 +0,0 @@ -# Forrestrie Examples - -Here's an example of how to run one of the examples in the `forrestrie-examples` crate: - -```terminal -cd crates/forrestrie-examples && cargo run -- --examples historical_state_roots_proof -``` - -Use environment variables to provide Firehose Ethereum and Firehose -Beacon providers of your choice. - -To do this, place a `.env` file in the root of `veemon`. See the -`.env.example` file in the root of this repository for what you'll need, -depending on your requirements. diff --git a/crates/forrestrie-examples/assets/historical_batch-573-c847a969.ssz b/crates/forrestrie-examples/assets/historical_batch-573-c847a969.ssz deleted file mode 100644 index 45631b2d..00000000 Binary files a/crates/forrestrie-examples/assets/historical_batch-573-c847a969.ssz and /dev/null differ diff --git a/crates/forrestrie-examples/examples/block_roots_only_proof.rs b/crates/forrestrie-examples/examples/block_roots_only_proof.rs deleted file mode 100644 index 303cbde2..00000000 --- a/crates/forrestrie-examples/examples/block_roots_only_proof.rs +++ /dev/null @@ -1,88 +0,0 @@ -//! # Inclusion Proofs for Block Roots Only -//! -//! For this test, we want to prove that a block_root is included in the `block_summary_root` -//! field of a [`HistoricalSummary`] from the [`BeaconState`] historical_summaries List. -//! A [`HistoricalSummary`] contains the roots of two Merkle trees, `block_summary_root` and -//! `state_summary_root`. -//! We are interested in the `block_summary_root` tree, whose leaves consists of the -//! [`BeaconBlockHeader`] roots for one era (8192 consecutive slots). -//! For this test, we are using the state at the first [`Slot`] of an era to build the proof. -//! We chose this [`Slot`] because it is the first [`Slot`] of an era, and all of the -//! [`BeaconBlockHeader`] roots needed to construct the [`HistoricalSummary`] for this era are -//! available in `state.block_roots`. - -use forrestrie::beacon_state::{HeadState, CAPELLA_START_ERA, HISTORY_TREE_DEPTH}; -use merkle_proof::verify_merkle_proof; -use types::{historical_summary::HistoricalSummary, MainnetEthSpec}; - -#[tokio::main] -async fn main() { - // You may need to update the slot being queried as the state data is updated. - // Multiply a recent era by 8192 to get the slot number. - const SLOT: u64 = 10182656; - let url = format!("https://www.lightclientdata.org/eth/v2/debug/beacon/states/{SLOT}"); - println!("Requesting state for slot {SLOT} ... (this can take a while!)"); - let response = reqwest::get(url).await.unwrap(); - let transition_state: HeadState = if response.status().is_success() { - let json_response: serde_json::Value = response.json().await.unwrap(); - serde_json::from_value(json_response).unwrap() - } else { - panic!("Request failed with status: {}", response.status()); - }; - - // There are 8192 slots in an era. 8790016 / 8192 = 1073. - let proof_era = transition_state.data().slot().as_usize() / 8192usize; - - // In this test we are using the `historical_summaries` (introduced in Capella) for - // verification, so we need to subtract the Capella start era to get the correct index. - let proof_era_index = proof_era - CAPELLA_START_ERA - 1; - - // We are going to prove that the block_root at index 4096 is included in the block_roots - // tree. - // This is an arbitrary choice just for test purposes. - let index = 4096usize; - - // Buffer of most recent 8192 block roots: - let block_root_at_index = *transition_state.data().block_roots().get(index).unwrap(); - - let proof = transition_state - .compute_block_roots_proof_only(index) - .unwrap(); - - // To verify the proof, we use the state from a later slot. - // The HistoricalSummary used to generate this proof is included in the historical_summaries - // list of this state. - let url = "https://www.lightclientdata.org/eth/v2/debug/beacon/states/head".to_string(); - println!("Requesting head state ... (this can take a while!)"); - let response = reqwest::get(url).await.unwrap(); - let state: HeadState = if response.status().is_success() { - let json_response: serde_json::Value = response.json().await.unwrap(); - serde_json::from_value(json_response).unwrap() - } else { - panic!("Request failed with status: {}", response.status()); - }; - - // The verifier retrieves the block_summary_root for the historical_summary and verifies the - // proof against it. - let historical_summary: &HistoricalSummary = state - .data() - .historical_summaries() - .unwrap() - .get(proof_era_index) - .unwrap(); - - let block_roots_summary_root = historical_summary.block_summary_root(); - - assert!( - verify_merkle_proof( - block_root_at_index, - &proof, - HISTORY_TREE_DEPTH, - index, - block_roots_summary_root - ), - "Merkle proof verification failed" - ); - - println!("Block roots only merkle proof verification succeeded"); -} diff --git a/crates/forrestrie-examples/examples/block_roots_proofs.rs b/crates/forrestrie-examples/examples/block_roots_proofs.rs deleted file mode 100644 index e0c7a18a..00000000 --- a/crates/forrestrie-examples/examples/block_roots_proofs.rs +++ /dev/null @@ -1,87 +0,0 @@ -//! # Block Roots Proofs -//! -//! We want to prove that a block_root is included in a [`HistoricalSummary`] from the [`BeaconState`] historical_summaries List. -//! A [`HistoricalSummary`] contains the roots of two Merkle trees, block_summary_root and state_summary root. -//! We are interested in the block_summary tree, whose leaves consists of the [`BeaconBlockHeader`] roots for one era (8192 consecutive slots). -//! For example, we could have used the state at [`Slot`] 8790016, which is the first [`Slot`] of era 1073, to build the proof. -//! Because it is the first [`Slot`] of an era, all of the [`BeaconBlockHeader`] roots needed to construct the -//! [`HistoricalSummary`] for this era are available in state.block_roots. -//! The last block root in the `block_roots` buffer is the block root of the previous block. - -use forrestrie::beacon_state::{ - HeadState, CAPELLA_START_ERA, HISTORICAL_SUMMARY_TREE_DEPTH, SLOTS_PER_HISTORICAL_ROOT, -}; -use merkle_proof::verify_merkle_proof; -use tree_hash::TreeHash; -use types::MainnetEthSpec; -#[tokio::main] -async fn main() { - // You may need to update the slot being queried as the state data is updated. - // Multiply a recent era by 8192 to get the slot number. - const SLOT: u64 = 10182656; - let url = format!("https://www.lightclientdata.org/eth/v2/debug/beacon/states/{SLOT}"); - println!("Requesting state for slot {SLOT} ... (this can take a while!)"); - let response = reqwest::get(url).await.unwrap(); - let transition_state: HeadState = if response.status().is_success() { - let json_response: serde_json::Value = response.json().await.unwrap(); - serde_json::from_value(json_response).unwrap() - } else { - panic!("Request failed with status: {}", response.status()); - }; - - // There are 8192 slots in an era. - let proof_era = transition_state.data().slot().as_usize() / SLOTS_PER_HISTORICAL_ROOT; - - // In this test we are using the historical_summaries (introduced in Capella) for verification, - // so we need to subtract the Capella start era to get the correct index. - let proof_era_index = proof_era - CAPELLA_START_ERA - 1; - - // We are going to prove that the block_root at index 4096 is included in the block_roots tree. - // This is an arbitrary choice just for test purposes. - let index = 4096usize; - - // Buffer of most recent 8192 block roots: - let block_root_at_index = *transition_state.data().block_roots().get(index).unwrap(); - - assert!( - transition_state.block_roots_contain_entire_era().unwrap(), - "Block roots buffer does not contain an entire era" - ); - - let proof = transition_state.compute_block_roots_proof(index).unwrap(); - - // To verify the proof, we use the state from a later slot. - // The HistoricalSummary used to generate this proof is included in the historical_summaries list of this state. - let url = "https://www.lightclientdata.org/eth/v2/debug/beacon/states/head".to_string(); - println!("Requesting head state ... (this can take a while!)"); - let response = reqwest::get(url).await.unwrap(); - let state: HeadState = if response.status().is_success() { - let json_response: serde_json::Value = response.json().await.unwrap(); - serde_json::from_value(json_response).unwrap() - } else { - panic!("Request failed with status: {}", response.status()); - }; - - // The verifier retrieves the block_summary_root for the historical_summary and verifies the proof against it. - let historical_summary = state - .data() - .historical_summaries() - .unwrap() - .get(proof_era_index) - .unwrap(); - - let historical_summary_root = historical_summary.tree_hash_root(); - - assert!( - verify_merkle_proof( - block_root_at_index, - &proof, - HISTORICAL_SUMMARY_TREE_DEPTH, - index, - historical_summary_root - ), - "Merkle proof verification failed" - ); - - println!("Block roots proof verified successfully"); -} diff --git a/crates/forrestrie-examples/examples/empty_slot_hashes.rs b/crates/forrestrie-examples/examples/empty_slot_hashes.rs deleted file mode 100644 index 5f3de492..00000000 --- a/crates/forrestrie-examples/examples/empty_slot_hashes.rs +++ /dev/null @@ -1,237 +0,0 @@ -//! # Empty Slot Block Hashes -//! -//! This example demonstrates that empty Beacon slots - slots with no execution block - -//! are represented in the [`BeaconState`] as duplicates of the previous full Beacon slot block hash. - -use std::collections::{BTreeMap, HashSet}; - -use forrestrie::beacon_state::{HeadState, CAPELLA_START_ERA, SLOTS_PER_HISTORICAL_ROOT}; -use primitive_types::H256; -use types::MainnetEthSpec; - -#[tokio::main] -async fn main() { - // This slot was chosen because it is the first slot of an era (and an epoch), - // which we demonstrate by showing that the slot number (see below) modulo 8192 is 0. - // You may need to update the slot being queried as the state data is updated. - // Multiply a recent era by 8192 to get the slot number. - const SLOT: u64 = 10182656; - let url = format!("https://www.lightclientdata.org/eth/v2/debug/beacon/states/{SLOT}"); - println!("Requesting state for slot {SLOT} ... (this can take a while!)"); - let response = reqwest::get(url).await.unwrap(); - let state: HeadState = if response.status().is_success() { - let json_response: serde_json::Value = response.json().await.unwrap(); - serde_json::from_value(json_response).unwrap() - } else { - panic!("Request failed with status: {}", response.status()); - }; - - let slot = state.data().slot().as_usize(); - - // Every 8192 slots, the era increments by 1, and (after Capella) the historical summaries buffer is updated. - let current_era = slot / SLOTS_PER_HISTORICAL_ROOT; - assert_eq!(slot % SLOTS_PER_HISTORICAL_ROOT, 0); - - // The historical summaries buffer is updated every 8192 slots, from the start of the Capella era. - let num_historical_summaries = state.data().historical_summaries().unwrap().len(); - assert_eq!((current_era - num_historical_summaries), CAPELLA_START_ERA); - - let block_roots = state.data().block_roots().to_vec(); - - // Block roots buffer contains duplicates. - let block_roots_set: HashSet<&H256, std::hash::RandomState> = - HashSet::from_iter(block_roots.iter()); - assert_ne!(block_roots_set.len(), block_roots.len()); - - let duplicate_block_roots_lookup_table = state - .data() - .block_roots() - .to_vec() - .iter() - .enumerate() - // Using BTreeMaps for deterministic order. - .fold(BTreeMap::>::new(), |mut acc, (i, root)| { - acc.entry(*root).or_default().push(i); - acc - }) - // Remove non-duplicate block roots. - .into_iter() - .filter(|(_, indices)| indices.len() > 1) - .collect::>>(); - - // The block roots buffer contains duplicates that are consecutive. - insta::assert_debug_snapshot!(duplicate_block_roots_lookup_table, @r###" - { - 0x0b181ac43241327561b0c9cb4e070f72989581fb49ed26f5435bef997c42ebf5: [ - 991, - 992, - ], - 0x0e0639696be97e597e0c7ee1acfff59f165ba9f5945e729633cff21c0c635848: [ - 6467, - 6468, - ], - 0x0e26c5f8321a19c33e0e190ad7f72d0c135ab8ba7104cd8a0473242c7064db18: [ - 6688, - 6689, - ], - 0x0f40bc4698ba17aa95faade9e069e95456bcffd3e966c1fb0510df803038df48: [ - 3396, - 3397, - ], - 0x0f57d09bbf7b6a20a76ce3683e555ca86e7a1c38a3d1414bc6afb76894c460c1: [ - 5265, - 5266, - ], - 0x1473d4d768a680e9e61e7c6904df1a798545e14295b664bd7be06951140e4650: [ - 7162, - 7163, - ], - 0x1e30ab8ebd808669cca453279c2d89ed1965c3920f33e2715aca2d3e2756722a: [ - 1162, - 1163, - ], - 0x287c4b53d1b7be5c6c1e42ee596cb6b2803dcdaf17821798f21175b1a7ded5a8: [ - 7543, - 7544, - ], - 0x2cf6c52b3a63f73d8393734ce77540b0ae4914f403128ef2e0b9dcabb36dd443: [ - 5087, - 5088, - ], - 0x2d8144f651ad2c0864d586f43c446570177ae0dc219f15ff9469dfd05fc8de6e: [ - 6465, - 6466, - ], - 0x3514b0a08790ff1047150893234575c86705b9b98ca0a0a109a39da2216a3a4f: [ - 2432, - 2433, - ], - 0x3e12555313ed8ad02e60bdf78688892a54e6e02498fffd5a2ed0dbfc38d97db5: [ - 2532, - 2533, - ], - 0x41eb012e02e62f6e31bf742c709a3e9ec654b9258ff86b2061d124f0839a0188: [ - 1799, - 1800, - ], - 0x4294e233c2ca1055127d1373ffaf96f91386a187f888c9de4742ea79ff2e67f0: [ - 3958, - 3959, - ], - 0x498bb1ca0923c4a56e094e2f6fe2243dff4a9766f317309da7c57be5940f5a56: [ - 124, - 125, - ], - 0x4ca5d89aaa6de795d3432fda64bbecf4aed5fa0966193e77aa1c98599fb08ebe: [ - 7807, - 7808, - ], - 0x4f497aaff8a60ec338bc3fd19e0089d3cfa922bd093f767e6ba34ce0ec0e69e9: [ - 6175, - 6176, - ], - 0x515519a00556388934dd24fd9c528b26af2dce885c4cd3d5b0120b3939808ddc: [ - 4410, - 4411, - ], - 0x56cf582ed2d994dc15c4e4e49cea4e013e5ccb825997958255ebff9a9c70a126: [ - 4127, - 4128, - ], - 0x59ef61abc9d0dee4a8c19d3f636876bc38aa56559bf29315b26ccfd66da73aa9: [ - 1510, - 1511, - ], - 0x5db5cee0a5a63e6f20744bd2da116f0b7ff1346b6b6014cf847977bd6036b17e: [ - 5297, - 5298, - ], - 0x5fe37ef18fdaee618fb869760b20be5f7d04334e93f356b00e313f3f2d4b5eb6: [ - 3743, - 3744, - ], - 0x6808158ef68b250694ebc6cfbd90418a0182ac3d6e0560ad19212dc902a31c2f: [ - 1937, - 1938, - ], - 0x6820e4ea1e925a0198c67e40d4a066778898cd8b2e6fea4c32d7dccec7c548d6: [ - 7294, - 7295, - ], - 0x69dfd5cbd798a693d3deb17ae9bb6c0b075e50d0e414b710f58438dc2a54b51d: [ - 3540, - 3541, - ], - 0x6f0b738c363cc6739178e2c813dc47d7ff9aaef5cda7b838a964ff67aa626ab3: [ - 1667, - 1668, - ], - 0x6fec0abed7cbf72b3c0c0fb00db7fa7e78fdf55c7bc52804971e9997e8c37ef6: [ - 5439, - 5440, - ], - 0x71afc6470dd6ea94a1cfa95d91975d2b2d0efcf261bcf92a37eeb722a10907e5: [ - 1518, - 1519, - ], - 0x99254b3ae83a064a9dd91f68c60630e88727bd2989110a041fed6aacb0780239: [ - 3555, - 3556, - ], - 0x9c91fed096d21a383bf4cba7ee5213c68f5fb662225af74864450d45bdd93e01: [ - 6028, - 6029, - ], - 0xa89ca327b5d989c3066ea390053651a5f8b951829bda21257f7b33503e1c7abc: [ - 6240, - 6241, - ], - 0xaba1fa146c1665c2a3083987e55a9ae15dc04800d527ca98f2baf8692b96d5fd: [ - 7167, - 7168, - ], - 0xb077d4b158fa43c1ac54ee3d608d9430970d10cbc64a219b819fc279f7d3d3e0: [ - 3380, - 3381, - ], - 0xc4153799a620d470ced2bf02f0275f6353ec57be64f34bb06a0bc3a13423a9e3: [ - 5453, - 5454, - ], - 0xcebd2b3111fce7d8f9f1ddcf556d7ba54aa0999342184e7c58fa262131e94283: [ - 2894, - 2895, - ], - 0xd436e0dbe68b089f4dca99cac9ab4dc044b448c3569ff029c230d1539c643b93: [ - 1036, - 1037, - ], - 0xd7e5a02180a5116042684af1b180739609e2424bbb4deb0d030b023b23490438: [ - 2050, - 2051, - ], - 0xda13e985195e44855e08d5bd2d54ca6ac8f4cfaa5668526760d521aeaa9c4178: [ - 7478, - 7479, - ], - 0xde5d5a3b2f2da2b6482adcd4f61c6addbf45dfee24ff938931ac90e56c9e73a9: [ - 6430, - 6431, - ], - 0xdef43bbd5c642857fdbb5fdcf8e566c1e1dffbb543c3a29e8d606c25e60d2bf3: [ - 5491, - 5492, - ], - 0xf406504fad9ec2165294c51a47bf6d258c07f7db212b897ebe5611153fbfcb88: [ - 3839, - 3840, - ], - 0xfe5b350eb4ae790d3c14db582269d3edea28f803a76983ababbf31926a7c9ff3: [ - 6784, - 6785, - ], - } - "###); - - println!("Empty slot block hashes example completed successfully"); -} diff --git a/crates/forrestrie-examples/examples/fetch_and_verify_block.rs b/crates/forrestrie-examples/examples/fetch_and_verify_block.rs deleted file mode 100644 index 0037500d..00000000 --- a/crates/forrestrie-examples/examples/fetch_and_verify_block.rs +++ /dev/null @@ -1,59 +0,0 @@ -//! # Beacon Block and Header Root Consistency -//! -//! In Ethereum's Beacon chain, the beacon block root and the block header root should match -//! for any given block, ensuring data integrity. This can be verified by computing the root -//! of a block and comparing it to the root of its header. -//! -//! For example, for slot 8786333, the block's root can be computed using the `canonical_root` method -//! from [`TreeHash`]: -//! -//! ```rust -//! let block_root = block.canonical_root(); -//! ``` -//! -//! Similarly, the block header root is derived as follows: -//! -//! ```rust -//! let block_header_root = block.block_header().tree_hash_root(); -//! ``` -//! -//! Both of these root hashes should be identical, indicating that the block's root hash -//! correctly represents the block header: -//! -//! ```rust -//! assert_eq!(block_root, block_header_root); -//! ``` -//! -use firehose_client::{Chain, FirehoseClient}; -use forrestrie::beacon_v1::Block as FirehoseBeaconBlock; -use tree_hash::TreeHash; -use types::{BeaconBlock, MainnetEthSpec}; - -#[tokio::main] -async fn main() { - let mut beacon_client = FirehoseClient::new(Chain::Beacon); - let response = beacon_client.fetch_block(8786333).await.unwrap().unwrap(); - let beacon_block = FirehoseBeaconBlock::try_from(response.into_inner()).unwrap(); - - let lighthouse_beacon_block = BeaconBlock::::try_from(beacon_block).unwrap(); - - insta::assert_debug_snapshot!(lighthouse_beacon_block.slot(), @ - "Slot(8786333)"); - - let block_root = lighthouse_beacon_block.canonical_root(); - - // See, for example, https://beaconcha.in/slot/8786333 and https://beaconscan.com/slot/8786333 - insta::assert_debug_snapshot!(block_root, @"0x063d4cf1a4f85d228d9eae17a9ab7df8b13de51e7a1988342a901575cce79613"); - - let block_header = lighthouse_beacon_block.block_header(); - let block_header_root = block_header.tree_hash_root(); - - assert_eq!(block_root, block_header_root); - - // This is to show that block hash and block body hash are different. - let body = lighthouse_beacon_block.body_deneb().unwrap(); - let body_hash = body.tree_hash_root(); - insta::assert_debug_snapshot!(body_hash, @"0xc15e821344ce5b201e2938248921743da8a07782168456929c8cef9f25a4cb02"); - - println!("fetch_and_verify_block.rs done"); -} diff --git a/crates/forrestrie-examples/examples/historical_state_roots_proof.rs b/crates/forrestrie-examples/examples/historical_state_roots_proof.rs deleted file mode 100644 index fa5dbdb2..00000000 --- a/crates/forrestrie-examples/examples/historical_state_roots_proof.rs +++ /dev/null @@ -1,42 +0,0 @@ -//! # Historical and state roots proof -//! -//! This example demonstrates how to prove the inclusion of historical state roots in the beacon state. -use forrestrie::beacon_state::{HeadState, HISTORICAL_ROOTS_FIELD_INDEX, HISTORICAL_ROOTS_INDEX}; -use merkle_proof::verify_merkle_proof; -use types::{light_client_update::CURRENT_SYNC_COMMITTEE_PROOF_LEN, MainnetEthSpec}; - -#[tokio::main] -async fn main() { - let url = "https://www.lightclientdata.org/eth/v2/debug/beacon/states/head"; - println!("Requesting head state ... (this can take a while!)"); - let response = reqwest::get(url).await.unwrap(); - let mut state: HeadState = if response.status().is_success() { - let json_response: serde_json::Value = response.json().await.unwrap(); - serde_json::from_value(json_response).unwrap() - } else { - panic!("Request failed with status: {}", response.status()); - }; - - let proof = state - .compute_merkle_proof_for_historical_data(HISTORICAL_ROOTS_INDEX) - .unwrap(); - - let historical_roots_tree_hash_root = state.historical_roots_tree_hash_root(); - - let depth = CURRENT_SYNC_COMMITTEE_PROOF_LEN; - - let state_root = state.state_root().unwrap(); - - assert!( - verify_merkle_proof( - historical_roots_tree_hash_root, - &proof, - depth, - HISTORICAL_ROOTS_FIELD_INDEX, - state_root - ), - "Merkle proof verification failed" - ); - - println!("historical state roots proof verified successfully"); -} diff --git a/crates/forrestrie-examples/examples/historical_summary_proof.rs b/crates/forrestrie-examples/examples/historical_summary_proof.rs deleted file mode 100644 index 51208850..00000000 --- a/crates/forrestrie-examples/examples/historical_summary_proof.rs +++ /dev/null @@ -1,45 +0,0 @@ -//! # Historical Summary Proof Given Historical Summaries Root -//! -//! This example demonstrates how to prove the inclusion of historical summaries in the beacon state. - -use forrestrie::beacon_state::{ - HeadState, HISTORICAL_SUMMARIES_FIELD_INDEX, HISTORICAL_SUMMARIES_INDEX, -}; -use merkle_proof::verify_merkle_proof; -use types::{light_client_update::CURRENT_SYNC_COMMITTEE_PROOF_LEN, MainnetEthSpec}; - -#[tokio::main] -async fn main() { - let url = "https://www.lightclientdata.org/eth/v2/debug/beacon/states/head".to_string(); - println!("Requesting head state ... (this can take a while!)"); - let response = reqwest::get(url).await.unwrap(); - let mut state: HeadState = if response.status().is_success() { - let json_response: serde_json::Value = response.json().await.unwrap(); - serde_json::from_value(json_response).unwrap() - } else { - panic!("Request failed with status: {}", response.status()); - }; - - let proof = state - .compute_merkle_proof_for_historical_data(HISTORICAL_SUMMARIES_INDEX) - .unwrap(); - - let historical_summaries_tree_hash_root = state.historical_summaries_tree_hash_root().unwrap(); - - let state_root = state.state_root().unwrap(); - - let depth = CURRENT_SYNC_COMMITTEE_PROOF_LEN; - - assert!( - verify_merkle_proof( - historical_summaries_tree_hash_root, - &proof, - depth, - HISTORICAL_SUMMARIES_FIELD_INDEX, - state_root - ), - "Merkle proof verification failed" - ); - - println!("historical summaries proof verified successfully"); -} diff --git a/crates/forrestrie-examples/examples/match_ethereum_to_beacon.rs b/crates/forrestrie-examples/examples/match_ethereum_to_beacon.rs deleted file mode 100644 index 2090307e..00000000 --- a/crates/forrestrie-examples/examples/match_ethereum_to_beacon.rs +++ /dev/null @@ -1,124 +0,0 @@ -//! # Ethereum Block to Beacon Slot Lookup Example -//! -//! This example performs a binary search to find the corresponding Beacon chain -//! slot for a given Ethereum execution block number. The problem being addressed -//! is that, due to missed slots in the Beacon chain, Ethereum execution blocks -//! and Beacon chain slots are not always aligned. Therefore, finding the correct -//! Beacon slot that contains the execution block requires searching through -//! Beacon blocks until the execution block is located. -//! -//! ## Key Concepts -//! -//! - **Execution Block Number**: This refers to the Ethereum block number that -//! we're trying to locate within the Beacon chain. -//! - **Beacon Slot Number**: The slot number in the Beacon chain that contains -//! the corresponding Ethereum execution block. -//! - **Deneb Fork**: This is the Ethereum fork that the blocks in the example -//! are from. We can imagine using `const` values to represent the start slot -//! of the Deneb fork and other upgrades, as well as the offsets between Ethereum -//! and Beacon block numbers at different known points along the chain. -//! -//! ## Approach -//! -//! The example uses a binary search algorithm to locate the Beacon slot that -//! contains the execution block. It starts with a search range defined by -//! `DENEB_START_SLOT` and an upper bound based on an estimated offset. -//! During each iteration of the search, the Beacon block is fetched, and its -//! execution payload is examined to check if it contains the target Ethereum -//! block number. The search range is adjusted based on the result of this -//! comparison until the correct Beacon slot is found. -//! - -use firehose_client::{Chain, FirehoseClient}; -use forrestrie::{ - beacon_state::ETHEREUM_BEACON_DENEB_OFFSET, - beacon_v1::{block, Block as FirehoseBeaconBlock}, -}; -use std::cmp::Ordering::*; -use tracing::info; -use tracing_subscriber::FmtSubscriber; - -/// This block relates to the slot represented by [`BEACON_SLOT_NUMBER`]. -/// The execution block is in the execution payload of the Beacon block in slot [`BEACON_SLOT_NUMBER`]. -const EXECUTION_BLOCK_NUMBER: u64 = 20759937; -/// This slot is the slot of the Beacon block that contains the execution block with [`EXECUTION_BLOCK_NUMBER`]. -#[allow(unused)] -const BEACON_SLOT_NUMBER: u64 = 9968872; // Beacon slot 9968872 pairs with Ethereum block 20759937. - -const IMAGINARY_CURRENT_SLOT: u64 = 10_000_000; - -#[tokio::main] -async fn main() { - let subscriber = FmtSubscriber::builder() - .with_max_level(tracing::Level::INFO) - .finish(); - tracing::subscriber::set_global_default(subscriber).expect("setting default subscriber failed"); - - let mut beacon_client = FirehoseClient::new(Chain::Beacon); - - let mut low = EXECUTION_BLOCK_NUMBER - ETHEREUM_BEACON_DENEB_OFFSET as u64; - let mut high = IMAGINARY_CURRENT_SLOT; - - let mut guesses = 0; - - while low <= high { - guesses += 1; - - let mid = low + (high - low) / 2; - - info!(guess = mid, "Current guess for Beacon slot"); - - let response = beacon_client.fetch_block(mid).await.unwrap().unwrap(); - let block = FirehoseBeaconBlock::try_from(response.into_inner()).unwrap(); - - let Some(block::Body::Deneb(body)) = &block.body else { - panic!("Unsupported block version!"); - }; - - let execution_payload = body.execution_payload.as_ref().unwrap(); - let block_number = execution_payload.block_number; - - match block_number.cmp(&EXECUTION_BLOCK_NUMBER) { - Less => low = mid + 1, - Greater => high = mid - 1, - Equal => { - info!( - beacon_slot = block.slot, - "Found matching Beacon block: {}!", block.slot - ); - break; - } - } - - if high == low || high == low + 1 { - if let Some(final_result) = try_final_fetches(low, high, &mut beacon_client).await { - println!( - "Found final result: matching execution block at Beacon slot: {}", - final_result - ); - break; - } - } - } - info!(guesses, "Guesses"); -} - -/// Helper function to fetch both `low` and `high` Beacon slots when binary search is down to two options -async fn try_final_fetches(low: u64, high: u64, client: &mut FirehoseClient) -> Option { - for slot in &[low, high] { - let response = client.fetch_block(*slot).await.unwrap().unwrap(); - - let block = FirehoseBeaconBlock::try_from(response.into_inner()).unwrap(); - - let Some(block::Body::Deneb(body)) = &block.body else { - return None; - }; - - let execution_payload = body.execution_payload.as_ref().unwrap(); - - if execution_payload.block_number == EXECUTION_BLOCK_NUMBER { - return Some(block.slot); - } - } - None -} diff --git a/crates/forrestrie-examples/examples/receipts_proof.rs b/crates/forrestrie-examples/examples/receipts_proof.rs deleted file mode 100644 index e78caeb3..00000000 --- a/crates/forrestrie-examples/examples/receipts_proof.rs +++ /dev/null @@ -1,59 +0,0 @@ -//! # Receipts proof given an EL block's `receipt_root` -//! -//! This example shows how to generate an inclusion proof for a set of receipts of an EL block. -//! - -use firehose_client::{Chain, FirehoseClient}; -use firehose_protos::{EthBlock as Block, FullReceipt}; -use forrestrie::execution_layer::{build_trie_with_proofs, TargetLeaves}; -use reth_primitives::ReceiptWithBloom; -use reth_trie_common::proof::verify_proof; - -const EXECUTION_BLOCK_NUMBER: u64 = 20759937; - -#[tokio::main] -async fn main() { - let mut eth1_client = FirehoseClient::new(Chain::Ethereum); - let response = eth1_client - .fetch_block(EXECUTION_BLOCK_NUMBER) - .await - .unwrap() - .unwrap(); - let eth1_block: Block = Block::try_from(response.into_inner()).unwrap(); - - let receipts: Vec = eth1_block.full_receipts().unwrap(); - - let receipts_with_bloom: Vec = receipts - .iter() - .map(|full_receipt| full_receipt.get_receipt_wb().clone()) - .collect(); - - // These are the indexes of receipts for which proofs need to be generated - let target_idxs = &[1, 2, 3]; - let targets = TargetLeaves::from_indices(target_idxs, &receipts_with_bloom).unwrap(); - let mut hb = build_trie_with_proofs(&receipts_with_bloom, target_idxs); - - // produces the root, which matches the root of the blocks. - // hb.root() also calculates the proofs and store them in the HashBuilder. - let root = hb.root(); - - let calc_root = eth1_block.calculate_receipt_root(); - println!("roots: {:?}, {:?}", root, calc_root); - - // proofs can be taken and sorted, so each proof matches one of the target. - // each proof of a specific target receipt is provided in `take_proof_nodes()` - // and can be stored or verified singularly - let proof = hb.take_proof_nodes(); - for target in targets { - let _verification = verify_proof( - hb.root(), - target.nibbles.clone(), - Some(target.value.to_vec()), - proof - .clone() - .matching_nodes_sorted(&target.nibbles) - .iter() - .map(|(_, node)| node), - ); - } -} diff --git a/crates/forrestrie-examples/examples/single_block_post_merge_pre_capella_proof.rs b/crates/forrestrie-examples/examples/single_block_post_merge_pre_capella_proof.rs deleted file mode 100644 index 4c1939f9..00000000 --- a/crates/forrestrie-examples/examples/single_block_post_merge_pre_capella_proof.rs +++ /dev/null @@ -1,61 +0,0 @@ -//! Proof for single block to be part of an era of beacon blocks using the [`HistoricalBatch`]. -//! -//! Notice that A [`HistoricalBatch`]` isn't an accumulator, it is a list of block_roots and state_roots -//! So each root in the [`HistoricalRootsAccumulator`] corresponds to hash_tree_root(historical_batch). -//! The batch is used to verify era against the accumulator. A block can be verified against an -//! [`HistoricalBatch`], hence chaining the proofs -use std::fs; - -use ethportal_api::consensus::beacon_state::HistoricalBatch; - -use ssz::Decode; -use trin_validation::{ - historical_roots_acc::HistoricalRootsAccumulator, merkle::proof::verify_merkle_proof, -}; - -#[tokio::main] -async fn main() { - // Load a historical batch. - // A historical batch has to be generated from beacon blocks or retrieved - // from some source that already calculated these - let bytes = - fs::read("./crates/forrestrie-examples/assets/historical_batch-573-c847a969.ssz").unwrap(); - let hist_batch = HistoricalBatch::from_ssz_bytes(&bytes).unwrap(); - - // check if my block_root is inside the HistoricalBatch - - // construct proof from historical batch - // In this example a slot that is inside the `HistoricalBatch` - // was picked: https://beaconcha.in/slot/4685828 - // NOTICE: we can also use the block roots themselves inside the the HistoricalBatch - // to figure out the slot by using the beacon chain explorer, for example: - // https://beaconcha.in/slot/58bbce808c399069fdd3e02e7906cd382ba8ffac8c1625a9d801ffa6a4120c98 - const EPOCH_SIZE: i32 = 8192; - let slot = 4685828; - let historical_root_index: i32 = slot % EPOCH_SIZE; - let historical_roots_proof = - hist_batch.build_block_root_proof((historical_root_index as u32).into()); - - // just checking if the rot macthes - let block_root = hist_batch.block_roots[historical_root_index as usize]; - - // The historical root we are getting: - println!("root: {:?}, index, {:?}", block_root, historical_root_index); - - // // verify the proof - let hist_acc = HistoricalRootsAccumulator::default(); - let block_root_index = slot % EPOCH_SIZE; - let gen_index = 2 * EPOCH_SIZE + block_root_index; - let historical_root_index = slot / EPOCH_SIZE; - let historical_root = hist_acc.historical_roots[historical_root_index as usize]; - - let result = verify_merkle_proof( - block_root, - &historical_roots_proof, - 14, - gen_index as usize, - historical_root, - ); - - println!("result of verifying proof: {:?}", result); -} diff --git a/crates/forrestrie-examples/examples/single_execution_block.rs b/crates/forrestrie-examples/examples/single_execution_block.rs deleted file mode 100644 index 46adc1b6..00000000 --- a/crates/forrestrie-examples/examples/single_execution_block.rs +++ /dev/null @@ -1,200 +0,0 @@ -//! # Prove Inclusion of a Single Execution Layer Block in the Canonical History of the Blockchain -//! -//! This example demonstrates how to prove the inclusion of a single execution layer block in the canonical -//! history of the blockchain. -//! -//! This method includes the following proofs: -//! 1. The block hash of the Ethereum block matches the hash in the block header. -//! 2. The block is the block it says it is, calculating its tree hash root matches the hash in the `root` -//! field of the block. -//! 3. The Beacon block's Execution Payload matches the Ethereum block. -//! 4. Reproducing the block root for the "era", or 8192 slots, of a Beacon block's slot by streaming 8192 -//! Beacon blocks from the Beacon chain. -//! 5. Calculating the merkle proof of the block's inclusion in the block roots of the historical summary for -//! the given era. -//! -//! We use a fork of [`lighthouse`](https://github.com/sigp/lighthouse)'s [`types`] that allows us to access -//! the `block_summary_root` of the [`HistoricalSummary`]. -//! -//! While this example demonstrates verifying block 20759937 on the execution layer, you could also use the -//! same method to prove the inclusion of an entire era of 8192 blocks, since the method for verifying a single -//! block already includes streaming 8192 blocks for the era. And its the same 8192 blocks required to compute -//! the block roots tree hash root, which can then be compared to the tree hash root in the historical summary -//! for the era. -//! -use ethportal_api::Header; -use firehose_client::{Chain, FirehoseClient}; -use firehose_protos::EthBlock; -use forrestrie::{ - beacon_block::{ - HistoricalDataProofs, BEACON_BLOCK_BODY_PROOF_DEPTH, EXECUTION_PAYLOAD_FIELD_INDEX, - }, - beacon_state::{ - compute_block_roots_proof_only, HeadState, CAPELLA_START_ERA, HISTORY_TREE_DEPTH, - SLOTS_PER_HISTORICAL_ROOT, - }, - beacon_v1::{self, BlockRoot}, -}; -use futures::StreamExt; -use merkle_proof::verify_merkle_proof; -use tree_hash::TreeHash; -use types::{ - historical_summary::HistoricalSummary, light_client_update::EXECUTION_PAYLOAD_INDEX, - BeaconBlock, BeaconBlockBody, BeaconBlockBodyDeneb, ExecPayload, Hash256, MainnetEthSpec, -}; - -/// This block relates to the slot represented by [`BEACON_SLOT_NUMBER`]. -/// The execution block is in the execution payload of the Beacon block in slot [`BEACON_SLOT_NUMBER`]. -const EXECUTION_BLOCK_NUMBER: u64 = 20759937; -/// This slot is the slot of the Beacon block that contains the execution block with [`EXECUTION_BLOCK_NUMBER`]. -const BEACON_SLOT_NUMBER: u64 = 9968872; // <- 9968872 pairs with 20759937 -/// The URL to fetch the head state of the Beacon chain. -const LIGHT_CLIENT_DATA_URL: &str = - "https://www.lightclientdata.org/eth/v2/debug/beacon/states/head"; - -#[tokio::main] -async fn main() { - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // Get the head state of the Beacon chain from a Beacon API provider. - let state_handle = tokio::spawn(async move { - let url = LIGHT_CLIENT_DATA_URL.to_string(); - println!("Requesting head state ... (this can take a while!)"); - let response = reqwest::get(url).await.unwrap(); - let head_state: HeadState = response.json().await.unwrap(); - head_state - }); - - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // Get the Ethereum block. - let mut eth1_client = FirehoseClient::new(Chain::Ethereum); - let response = eth1_client - .fetch_block(EXECUTION_BLOCK_NUMBER) - .await - .unwrap() - .unwrap(); - let eth1_block = EthBlock::try_from(response.into_inner()).unwrap(); - - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // And get the Beacon block. - let mut beacon_client = FirehoseClient::new(Chain::Beacon); - let response = beacon_client - .fetch_block(BEACON_SLOT_NUMBER) - .await - .unwrap() - .unwrap(); - let beacon_block = beacon_v1::Block::try_from(response.into_inner()).unwrap(); - assert_eq!(beacon_block.slot, BEACON_SLOT_NUMBER); - - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // Confirm that the block hash of the Ethereum block matches the hash in the block header. - let block_header = Header::try_from(ð1_block).unwrap(); - let eth1_block_hash = block_header.hash(); - assert_eq!(eth1_block_hash.as_slice(), ð1_block.hash); - - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // Convert the Beacon block to a Lighthouse `BeaconBlock`. This allows us to use Lighthouse's - // implementation of the `TreeHash` trait to calculate the root of the Beacon block, which we - // use to verify that the block is the block it says it is, i.e., the hash value in the `root` - // field of the block matches the calculated root, which we calculate using the method implemented - // on the `BeaconBlock` struct in Lighthouse. - let lighthouse_beacon_block = BeaconBlock::::try_from(beacon_block.clone()) - .expect("Failed to convert Beacon block to Lighthouse BeaconBlock"); - - // Check the root of the Beacon block. This check shows that the calculation of the block root - // of the Beacon block matches the hash in the `root` field of the block we fetched over gRPC; - // the block is the block that it says it is. - let lighthouse_beacon_block_root = lighthouse_beacon_block.canonical_root(); - assert_eq!( - lighthouse_beacon_block_root.as_bytes(), - beacon_block.root.as_slice() - ); - let Some(beacon_v1::block::Body::Deneb(body)) = beacon_block.body else { - panic!("Unsupported block version!"); - }; - let block_body: BeaconBlockBodyDeneb = body.try_into().unwrap(); - - // Confirm that the Beacon block's Execution Payload matches the Ethereum block we fetched. - assert_eq!( - block_body.execution_payload.block_number(), - EXECUTION_BLOCK_NUMBER - ); - - // Confirm that the Ethereum block matches the Beacon block's Execution Payload. - assert_eq!( - block_body - .execution_payload - .block_hash() - .into_root() - .as_bytes(), - eth1_block_hash.as_slice() - ); - - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // Confirm that the Execution Payload is included in the Beacon block. - let block_body_hash = block_body.tree_hash_root(); - let execution_payload = &block_body.execution_payload; - let execution_payload_root = execution_payload.tree_hash_root(); - let body = BeaconBlockBody::from(block_body.clone()); - let proof = body.compute_merkle_proof(EXECUTION_PAYLOAD_INDEX).unwrap(); - let depth = BEACON_BLOCK_BODY_PROOF_DEPTH; - assert!(verify_merkle_proof( - execution_payload_root, - &proof, - depth, - EXECUTION_PAYLOAD_FIELD_INDEX, - block_body_hash - )); - - // The era of the block's slot. - // This is also the index of the historical summary containing the block roots for this era. - let era = lighthouse_beacon_block.slot().as_usize() / SLOTS_PER_HISTORICAL_ROOT; - - println!("Requesting 8192 blocks for the era... (this takes a while)"); - let num_blocks = SLOTS_PER_HISTORICAL_ROOT as u64; - let mut stream = beacon_client - .stream_beacon_with_retry((era * SLOTS_PER_HISTORICAL_ROOT) as u64, num_blocks) - .await - .unwrap(); - let mut block_roots: Vec = Vec::with_capacity(SLOTS_PER_HISTORICAL_ROOT); - while let Some(block) = stream.next().await { - let root = BlockRoot::try_from(block).unwrap(); - block_roots.push(root.0); - } - assert_eq!(block_roots.len(), SLOTS_PER_HISTORICAL_ROOT); - - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // The index of the block in the complete era of block roots. - // Beacon chain slot numbers are zero-based; genesis slot is 0. - // We need this to calculate the merkle inclusion proof later. - // If this is the first/last block of the era, the index is 0/8191. - let index = lighthouse_beacon_block.slot().as_usize() % SLOTS_PER_HISTORICAL_ROOT; - // Compute the proof of the block's inclusion in the block roots. - let proof = compute_block_roots_proof_only::(&block_roots, index).unwrap(); - // To get the correct index, we need to subtract the Capella start era. - // `HistoricalSummary` was introduced in Capella and the block we're proving inclusion for is in - // the post-Capella era. - // For pre-Capella states, we would use the same method, only using the historical_roots field. - let proof_era = era - CAPELLA_START_ERA; - - let head_state = state_handle.await.unwrap(); - let historical_summary: &HistoricalSummary = head_state - .data() - .historical_summaries() - .unwrap() - .get(proof_era) - .unwrap(); - let block_roots_tree_hash_root = historical_summary.block_summary_root(); - assert_eq!(proof.len(), HISTORY_TREE_DEPTH); - // Verify the proof. - assert!( - verify_merkle_proof( - lighthouse_beacon_block_root, // the root of the block - &proof, // the proof of the block's inclusion in the block roots - HISTORY_TREE_DEPTH, // the depth of the block roots tree - index, // the index of the block in the era - block_roots_tree_hash_root // The root of the block roots - ), - "Merkle proof verification failed" - ); - println!("All checks passed!"); -} diff --git a/crates/forrestrie-examples/examples/verify-era.rs b/crates/forrestrie-examples/examples/verify-era.rs deleted file mode 100644 index 9018e2ab..00000000 --- a/crates/forrestrie-examples/examples/verify-era.rs +++ /dev/null @@ -1,182 +0,0 @@ -//! In this example, we verify a complete era of both beacon blocks and execution blocks. -//! We first fetch a complete era of beacon blocks (8192 beacon blocks), compute the associated historical summary and -//! compare it against the historical summary from a current consensus stated. We also extract the -//! execution block headers and block numbers from the beacon blocks. We then fetch the execution -//! blocks using the extracted block numbers and verify the execution block data against the -//! extracted block headers. - -use ethportal_api::Header; -use firehose_client::{Chain, FirehoseClient}; -use firehose_protos::EthBlock; -use forrestrie::{ - beacon_state::{HeadState, CAPELLA_START_ERA, HISTORY_TREE_DEPTH, SLOTS_PER_HISTORICAL_ROOT}, - beacon_v1::{self}, -}; -use futures::StreamExt; -use tree_hash::TreeHash; -use types::{ - historical_summary::HistoricalSummary, BeaconBlock, BeaconBlockBodyDeneb, ExecPayload, - MainnetEthSpec, Slot, -}; - -use merkle_proof::MerkleTree; - -/// This slot is the starting slot of the Beacon block era. -const BEACON_SLOT_NUMBER: u64 = 10436608; -/// The URL to fetch the head state of the Beacon chain. -const LIGHT_CLIENT_DATA_URL: &str = - "https://www.lightclientdata.org/eth/v2/debug/beacon/states/head"; - -#[tokio::main] -async fn main() { - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // Get the head state of the Beacon chain from a Beacon API provider. - let state_handle = tokio::spawn(async move { - let url = LIGHT_CLIENT_DATA_URL.to_string(); - println!("Requesting head state ... (this can take a while!)"); - let response = reqwest::get(url).await.unwrap(); - let head_state: HeadState = response.json().await.unwrap(); - head_state - }); - - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // Here we are going to fetch all of the beacon blocks for an era. - // We will verify that the blocks are correct by computing a block_summary_root from the beacon blocks and comparing it to the block_summary_root in the historical summary from the consensus state. - let mut beacon_client = FirehoseClient::new(Chain::Beacon); - - // The era of the block's slot. - // This is also the index of the historical summary containing the block roots for this era. - let era = BEACON_SLOT_NUMBER as usize / SLOTS_PER_HISTORICAL_ROOT; - - // Stream the blocks - println!("Requesting 8192 blocks for the era... (this takes a while)"); - let num_blocks = SLOTS_PER_HISTORICAL_ROOT as u64; - let mut stream = beacon_client - .stream_beacon_with_retry((era * SLOTS_PER_HISTORICAL_ROOT) as u64, num_blocks) - .await - .unwrap(); - - // We are going to store off the execution block numbers and hashes for later verification. - let mut execution_block_number_and_hash = Vec::with_capacity(SLOTS_PER_HISTORICAL_ROOT); - - // We are going to store off the beacon block roots and calculate the block_summary_root from them. - let mut beacon_block_roots = Vec::with_capacity(SLOTS_PER_HISTORICAL_ROOT); - - let mut idx = 0; - let mut prev_slot = Slot::new(0); - let mut push_parent_root = false; - while let Some(block) = stream.next().await { - // Get the exeuction block number and blockhash. - let lighthouse_beacon_block = BeaconBlock::::try_from(block.clone()) - .expect("Failed to convert Beacon block to Lighthouse BeaconBlock"); - let Some(beacon_v1::block::Body::Deneb(body)) = block.body else { - panic!("Unsupported block version!"); - }; - let block_body: BeaconBlockBodyDeneb = body.try_into().unwrap(); - let execution_block_number = block_body.execution_payload.block_number(); - let execution_block_hash = block_body.execution_payload.block_hash(); - execution_block_number_and_hash.push((execution_block_number, execution_block_hash)); - - // There are a few things going on here: - // 1. there is currently a bug in the Firehose API where if a slot does not have an execution payload (the slot was skipped), then Firehose simply repeats the previous beacon block. - // This is a problem because this means that we can't calculate the beacon block root for the skipped slot. - // As a workaround, whenever we see a repeated block (implying a skipped slot), we will skip processing that block and on the next block we will push the parent root to the beacon block roots. - // Assuming that the parent root is correct, then the block_summary_root will be correct. - // - // 2. We are going to check the consistency of the beacon chain by comparing the claimed parent root of the current block against the previous block's root, they should match. - // This helps us catch errors within the era. - - if idx > 0 { - // If there was a skipped slot, then we will skip processing the current block and push the parent root to the beacon block roots. - let curr_slot = lighthouse_beacon_block.as_deneb().unwrap().slot; - if curr_slot == prev_slot { - push_parent_root = true; - idx += 1; - println!("Slot skipped!"); - continue; - } - if push_parent_root { - let parent_root = lighthouse_beacon_block.as_deneb().unwrap().parent_root; - beacon_block_roots.push(parent_root); - push_parent_root = false; - } - - // Check the parent root of the current block against the previous block's root. - let prev_block_root = beacon_block_roots[idx - 1]; - let prev_block_root_from_block = - lighthouse_beacon_block.as_deneb().unwrap().parent_root; - if prev_block_root != prev_block_root_from_block { - println!("Slot {}", lighthouse_beacon_block.as_deneb().unwrap().slot); - panic!("Block root mismatch!"); - } - println!( - "Slot {} verified!", - lighthouse_beacon_block.as_deneb().unwrap().slot - ); - } - - // Store the beacon block root. - let beacon_block_root = lighthouse_beacon_block.tree_hash_root(); - beacon_block_roots.push(beacon_block_root); - idx += 1; - prev_slot = lighthouse_beacon_block.as_deneb().unwrap().slot; - } - - // Check that we have the correct number of blocks. - assert_eq!( - execution_block_number_and_hash.len(), - SLOTS_PER_HISTORICAL_ROOT - ); - assert_eq!(beacon_block_roots.len(), SLOTS_PER_HISTORICAL_ROOT); - - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // Here is where we check that the historical summary from the consensus state matches the historical summary computed from the beacon blocks. - - // Caculate the block_summary_root from the beacon blocks. Note that the block_summary_root is a field in the HistoricalSummary. - let beacon_block_roots_tree_hash_root = - MerkleTree::create(&beacon_block_roots, HISTORY_TREE_DEPTH).hash(); - - // To get the correct index for the era's HistoricalSummary in the consensus state, we need to subtract the Capella start era. - // `HistoricalSummary` was introduced in Capella and the block we're proving inclusion for is in - // the post-Capella era. - // For pre-Capella states, we would use the same method, only using the historical_roots field. - let era_index = era - CAPELLA_START_ERA; - - // Get the historical summary for the era from the consensus state. - let head_state = state_handle.await.unwrap(); - let historical_summary: &HistoricalSummary = head_state - .data() - .historical_summaries() - .unwrap() - .get(era_index) - .unwrap(); - - let block_summary_root = historical_summary.block_summary_root(); - assert_eq!(beacon_block_roots_tree_hash_root, block_summary_root); - println!("Historical summary verified!"); - - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // Now that we have a verified set of execution block headers (and block numbers) from the beacon blocks, we can fetch the execution blocks and verify them. - - for (number, blockhash) in execution_block_number_and_hash { - // Fetch execution blocks from the Firehose API. - let mut eth1_client = FirehoseClient::new(Chain::Ethereum); - let response = eth1_client.fetch_block(number).await.unwrap().unwrap(); - let eth1_block = EthBlock::try_from(response.into_inner()).unwrap(); - - // Confirm that the block hash of the Ethereum block matches the hash in the block header. - let block_header = Header::try_from(ð1_block).unwrap(); - let eth1_block_hash = block_header.hash(); - assert_eq!(eth1_block_hash.as_slice(), ð1_block.hash); - - // Confirm that the Ethereum block matches the Beacon block's Execution Payload. - // This is our first major check linking the exuction layer to the consensus layer. - assert_eq!(blockhash.into_root().as_bytes(), eth1_block_hash.as_slice()); - println!("Block number {} verified!", number); - } - - // At this point, we have checked that the complete era's beacon blocks are correct by comparing against a historical summary from the consensus state, - // and that the corresponding execution blocks are correct by comparing against the block headers from the verified beacon blocks. - // Assuming that all checks passed, then the extracted data has been verified. - println!("All checks passed!"); -} diff --git a/crates/forrestrie-examples/examples/verify_block_inclusion_proof.rs b/crates/forrestrie-examples/examples/verify_block_inclusion_proof.rs deleted file mode 100644 index 0060bcfc..00000000 --- a/crates/forrestrie-examples/examples/verify_block_inclusion_proof.rs +++ /dev/null @@ -1,73 +0,0 @@ -//! # Verify Block Inclusion Proof -//! -//! In Ethereum's Beacon Chain, execution layer payloads are included in the block body. -//! -//! This example demonstrates how to verify the inclusion proof of an execution payload -//! in a block body. -//! -//! For example, for block `20672593`, the execution payload root can be computed using the `tree_hash_root` method -//! from [`TreeHash`]: -//! -//! ```rust -//! let execution_payload_root = execution_payload.tree_hash_root(); -//! ``` -//! -//! Similarly, the block body root is derived as follows: -//! -//! ```rust -//! let block_body_hash = block_body.tree_hash_root(); -//! ``` -//! -//! The inclusion proof can be computed using the `compute_merkle_proof` method from [`BeaconBlockBody`]: -//! -//! ```rust -//! let proof = body.compute_merkle_proof(EXECUTION_PAYLOAD_INDEX).unwrap(); -//! ``` -//! -use firehose_client::{Chain, FirehoseClient}; -use forrestrie::{ - beacon_block::{ - HistoricalDataProofs, BEACON_BLOCK_BODY_PROOF_DEPTH, EXECUTION_PAYLOAD_FIELD_INDEX, - }, - beacon_v1::Block as FirehoseBeaconBlock, -}; -use merkle_proof::verify_merkle_proof; -use tree_hash::TreeHash; -use types::{ - light_client_update::EXECUTION_PAYLOAD_INDEX, BeaconBlock, BeaconBlockBody, MainnetEthSpec, -}; - -#[tokio::main] -async fn main() { - // test_inclusion_proof_for_block_body_given_execution_payload - let mut beacon_client = FirehoseClient::new(Chain::Beacon); - - let response = beacon_client.fetch_block(20672593).await.unwrap().unwrap(); - - let block = FirehoseBeaconBlock::try_from(response.into_inner()).unwrap(); - - let beacon_block = BeaconBlock::::try_from(block).unwrap(); - - let execution_payload = beacon_block.body().execution_payload().unwrap(); - let execution_payload_root = execution_payload.tree_hash_root(); - - let block_body = beacon_block.body_deneb().unwrap(); - let block_body_hash = block_body.tree_hash_root(); - - let body = BeaconBlockBody::from(block_body.clone()); - let proof = body.compute_merkle_proof(EXECUTION_PAYLOAD_INDEX).unwrap(); - - let depth = BEACON_BLOCK_BODY_PROOF_DEPTH; - - assert_eq!(proof.len(), depth, "proof length should equal depth"); - - assert!(verify_merkle_proof( - execution_payload_root, - &proof, - depth, - EXECUTION_PAYLOAD_FIELD_INDEX, - block_body_hash - )); - - println!("verify_block_inclusion_proof.rs done"); -} diff --git a/crates/forrestrie-examples/src/lib.rs b/crates/forrestrie-examples/src/lib.rs deleted file mode 100644 index 8b137891..00000000 --- a/crates/forrestrie-examples/src/lib.rs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/crates/forrestrie/CHANGELOG.md b/crates/forrestrie/CHANGELOG.md deleted file mode 100644 index 5c0cfa0d..00000000 --- a/crates/forrestrie/CHANGELOG.md +++ /dev/null @@ -1,8 +0,0 @@ -# Changelog - -## [0.1.1](https://github.com/semiotic-ai/veemon/compare/forrestrie-v0.1.0...forrestrie-v0.1.1) (2024-10-22) - - -### Bug Fixes - -* **forrestrie/examples:** substract capella start from index ([829c372](https://github.com/semiotic-ai/veemon/commit/829c3720eb99b5b0991c4e83e05876616cdfc168)) diff --git a/crates/forrestrie/Cargo.toml b/crates/forrestrie/Cargo.toml deleted file mode 100644 index b1b22a5d..00000000 --- a/crates/forrestrie/Cargo.toml +++ /dev/null @@ -1,36 +0,0 @@ -[package] -name = "forrestrie" -version = "0.1.1" -edition = "2021" - -[lib] -name = "forrestrie" -path = "src/lib.rs" - -[dependencies] -alloy-rlp.workspace = true -alloy-primitives.workspace = true -bls.workspace = true -ethportal-api.workspace = true -firehose-protos = { path = "../firehose-protos" } -futures.workspace = true -merkle_proof.workspace = true -primitive-types.workspace = true -prost.workspace = true -prost-wkt.workspace = true -prost-wkt-types.workspace = true -reth-trie-common.workspace = true -reth-primitives.workspace = true -serde = { workspace = true, features = ["derive"] } -ssz_types.workspace = true -tonic.workspace = true -tree_hash = "0.6.0" -types.workspace = true - -[dev-dependencies] -rand.workspace = true -fake.workspace = true - -[build-dependencies] -prost-build.workspace = true -tonic-build.workspace = true diff --git a/crates/forrestrie/README.md b/crates/forrestrie/README.md deleted file mode 100644 index f7d18240..00000000 --- a/crates/forrestrie/README.md +++ /dev/null @@ -1,23 +0,0 @@ -# Forrestrie - -Library of types and methods for verifying post-merge Ethereum data. - -## Documentation - -- Notion doc on -[Post-merge Header Record Data Structure](https://www.notion.so/semiotic/Post-merge-header_record-data-structure-7290d03d356946188bdb9ac29366f510?pvs=4). -- [Beacon Chain `BeaconState` spec](https://github.com/ethereum/consensus-specs/blob/dev/specs/capella/beacon-chain.md#beaconstate) -- [Beacon Chain `BeaconBlockBody` spec](https://github.com/ethereum/consensus-specs/blob/dev/specs/deneb/beacon-chain.md#beaconblockbody) -- The [fork of `sigp/lighthouse`](https://github.com/semiotic-ai/lighthouse) we've been spiking. -- [Google Drive shared resources](https://drive.google.com/drive/folders/19QBMHZFAV7uo_Cu4RwLPTwGpBcQMd-hy), -including `head-state.json` used in `beacon_state.rs` tests. - -## Examples - -See [forrestrie-examples](./../forrestrie-examples/README.md)! - -## Protobuffers - -### [protos/type.proto](https://github.com/pinax-network/firehose-beacon/blob/main/proto/sf/beacon/type/v1/type.proto) - -Pinax's Firehose Beacon `Block` implementation. diff --git a/crates/forrestrie/build.rs b/crates/forrestrie/build.rs deleted file mode 100644 index dff58a58..00000000 --- a/crates/forrestrie/build.rs +++ /dev/null @@ -1,20 +0,0 @@ -use prost_build::Config; -use std::{env, path::PathBuf}; - -fn main() { - let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap()); - - // Configure prost to derive serde traits on specific types - let mut config = Config::new(); - config.type_attribute(".", "#[derive(serde::Serialize, serde::Deserialize)]"); - - // Map Google protobuf types to prost_wkt_types - config.extern_path(".google.protobuf.Any", "::prost_wkt_types::Any"); - config.extern_path(".google.protobuf.Timestamp", "::prost_wkt_types::Timestamp"); - - tonic_build::configure() - .build_client(true) - .file_descriptor_set_path(out_dir.join("descriptors.bin")) - .compile_protos_with_config(config, &["protos/type.proto"], &["protos/"]) - .unwrap(); -} diff --git a/crates/forrestrie/protos/README.md b/crates/forrestrie/protos/README.md deleted file mode 100644 index b9aa605b..00000000 --- a/crates/forrestrie/protos/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Protobuffer definitions - -## [`type.proto`](https://github.com/pinax-network/firehose-beacon/blob/main/proto/sf/beacon/type/v1/type.proto) - -Pinax's Firehose Beacon `Block` implementation. diff --git a/crates/forrestrie/protos/type.proto b/crates/forrestrie/protos/type.proto deleted file mode 100644 index 302fdb1c..00000000 --- a/crates/forrestrie/protos/type.proto +++ /dev/null @@ -1,270 +0,0 @@ -syntax = "proto3"; - -option go_package = "github.com/pinax-network/firehose-beacon/pb/sf/beacon/type/v1;pbbeacon"; - -package sf.beacon.type.v1; - -import "google/protobuf/timestamp.proto"; - -enum Spec { - UNSPECIFIED = 0; - PHASE0 = 1; - ALTAIR = 2; - BELLATRIX = 3; - CAPELLA = 4; - DENEB = 5; -} - -message Block { - - uint32 version = 1; - - Spec spec = 2; - uint64 slot = 3; - uint64 parent_slot = 4; - bytes root = 5; - bytes parent_root = 6; - bytes state_root = 7; - uint64 proposer_index = 8; - bytes body_root = 9; - - oneof Body { - Phase0Body phase0 = 20; - AltairBody altair = 21; - BellatrixBody bellatrix = 22; - CapellaBody capella = 23; - DenebBody deneb = 24; - } - - bytes signature = 30; - google.protobuf.Timestamp timestamp = 31; -} - -message Phase0Body { - bytes rando_reveal = 1; - Eth1Data eth1_data = 2; - bytes graffiti = 3; - repeated ProposerSlashing proposer_slashings = 4; - repeated AttesterSlashing attester_slashings = 5; - repeated Attestation attestations = 6; - repeated Deposit deposits = 7; - repeated SignedVoluntaryExit voluntary_exits = 8; -} - -message AltairBody { - bytes rando_reveal = 1; - Eth1Data eth1_data = 2; - bytes graffiti = 3; - repeated ProposerSlashing proposer_slashings = 4; - repeated AttesterSlashing attester_slashings = 5; - repeated Attestation attestations = 6; - repeated Deposit deposits = 7; - repeated SignedVoluntaryExit voluntary_exits = 8; - SyncAggregate sync_aggregate = 9; -} - -message BellatrixBody { - bytes rando_reveal = 1; - Eth1Data eth1_data = 2; - bytes graffiti = 3; - repeated ProposerSlashing proposer_slashings = 4; - repeated AttesterSlashing attester_slashings = 5; - repeated Attestation attestations = 6; - repeated Deposit deposits = 7; - repeated SignedVoluntaryExit voluntary_exits = 8; - SyncAggregate sync_aggregate = 9; - BellatrixExecutionPayload execution_payload = 10; -} - -message CapellaBody { - bytes rando_reveal = 1; - Eth1Data eth1_data = 2; - bytes graffiti = 3; - repeated ProposerSlashing proposer_slashings = 4; - repeated AttesterSlashing attester_slashings = 5; - repeated Attestation attestations = 6; - repeated Deposit deposits = 7; - repeated SignedVoluntaryExit voluntary_exits = 8; - SyncAggregate sync_aggregate = 9; - CapellaExecutionPayload execution_payload = 10; -} - -message DenebBody { - bytes rando_reveal = 1; - Eth1Data eth1_data = 2; - bytes graffiti = 3; - repeated ProposerSlashing proposer_slashings = 4; - repeated AttesterSlashing attester_slashings = 5; - repeated Attestation attestations = 6; - repeated Deposit deposits = 7; - repeated SignedVoluntaryExit voluntary_exits = 8; - SyncAggregate sync_aggregate = 9; - DenebExecutionPayload execution_payload = 10; - repeated SignedBLSToExecutionChange bls_to_execution_changes = 11; - repeated bytes blob_kzg_commitments = 12; - - repeated Blob embedded_blobs = 20; -} - -message Eth1Data { - bytes deposit_root = 1; - uint64 deposit_count = 2; - bytes block_hash = 3; -} - -message ProposerSlashing { - SignedBeaconBlockHeader signed_header_1 = 1; - SignedBeaconBlockHeader signed_header_2 = 2; -} - -message AttesterSlashing { - IndexedAttestation attestation_1 = 1; - IndexedAttestation attestation_2 = 2; -} - -message Attestation { - bytes aggregation_bits = 1; - AttestationData data = 2; - bytes signature = 3; -} - -message Deposit { - repeated bytes proof = 1; - DepositData data = 2; -} - -message SignedVoluntaryExit { - VoluntaryExit message = 1; - bytes signature = 2; -} - -message SyncAggregate { - bytes sync_commitee_bits = 1; - bytes sync_comittee_signature = 2; -} - -message BellatrixExecutionPayload { - bytes parent_hash = 1; - bytes fee_recipient = 2; - bytes state_root = 3; - bytes receipts_root = 4; - bytes logs_bloom = 5; - bytes prev_randao = 6; - uint64 block_number = 7; - uint64 gas_limit = 8; - uint64 gas_used = 9; - google.protobuf.Timestamp timestamp = 10; - bytes extra_data = 11; - bytes base_fee_per_gas = 12; - bytes block_hash = 13; - repeated bytes transactions = 14; -} - - -message CapellaExecutionPayload { - bytes parent_hash = 1; - bytes fee_recipient = 2; - bytes state_root = 3; - bytes receipts_root = 4; - bytes logs_bloom = 5; - bytes prev_randao = 6; - uint64 block_number = 7; - uint64 gas_limit = 8; - uint64 gas_used = 9; - google.protobuf.Timestamp timestamp = 10; - bytes extra_data = 11; - bytes base_fee_per_gas = 12; - bytes block_hash = 13; - repeated bytes transactions = 14; - repeated Withdrawal withdrawals = 15; -} - -message DenebExecutionPayload { - bytes parent_hash = 1; - bytes fee_recipient = 2; - bytes state_root = 3; - bytes receipts_root = 4; - bytes logs_bloom = 5; - bytes prev_randao = 6; - uint64 block_number = 7; - uint64 gas_limit = 8; - uint64 gas_used = 9; - google.protobuf.Timestamp timestamp = 10; - bytes extra_data = 11; - bytes base_fee_per_gas = 12; - bytes block_hash = 13; - repeated bytes transactions = 14; - repeated Withdrawal withdrawals = 15; - uint64 blob_gas_used = 16; - uint64 excess_blob_gas = 17; -} - -message SignedBLSToExecutionChange { - BLSToExecutionChange message = 1; - bytes signature = 2; -} - -message BLSToExecutionChange { - uint64 validator_index = 1; - bytes from_bls_pub_key = 2; - bytes to_execution_address = 3; -} - -message Withdrawal { - uint64 withdrawal_index = 1; - uint64 validator_index = 2; - bytes address = 3; - uint64 gwei = 4; -} - -message VoluntaryExit { - uint64 epoch = 1; - uint64 validator_index = 2; -} - -message DepositData { - bytes public_key = 1; - bytes withdrawal_credentials = 2; - uint64 gwei = 3; - bytes signature = 4; -} - -message IndexedAttestation { - repeated uint64 attesting_indices = 1; - AttestationData data = 2; - bytes signature = 3; -} - -message AttestationData { - uint64 slot = 1; - uint64 committee_index = 2; - bytes beacon_block_root = 3; - Checkpoint source = 4; - Checkpoint target = 5; -} - -message Checkpoint { - uint64 epoch = 1; - bytes root = 2; -} - -message SignedBeaconBlockHeader { - BeaconBlockHeader message = 1; - bytes Signature = 2; -} - -message BeaconBlockHeader { - uint64 slot = 1; - uint64 proposer_index = 2; - bytes parent_root = 3; - bytes state_root = 4; - bytes body_root = 5; -} - -message Blob { - uint64 index = 1; - bytes blob = 2; - bytes kzg_commitment = 3; - bytes kzg_proof = 4; - repeated bytes kzg_commitment_inclusion_proof = 5; -} \ No newline at end of file diff --git a/crates/forrestrie/src/beacon_block.rs b/crates/forrestrie/src/beacon_block.rs deleted file mode 100644 index 1143b5ca..00000000 --- a/crates/forrestrie/src/beacon_block.rs +++ /dev/null @@ -1,91 +0,0 @@ -use serde::{Deserialize, Serialize}; -use tree_hash::TreeHash; -use types::{ - beacon_block_body::NUM_BEACON_BLOCK_BODY_HASH_TREE_ROOT_LEAVES, - light_client_update::{self, EXECUTION_PAYLOAD_INDEX}, - BeaconBlock, BeaconBlockBody, Error, EthSpec, ForkName, Hash256, MainnetEthSpec, -}; - -#[derive(Debug, Deserialize, Serialize)] -pub struct BlockWrapper { - pub version: String, - pub execution_optimistic: bool, - pub finalized: bool, - pub data: Data, -} - -#[derive(Debug, Deserialize, Serialize)] -pub struct Data { - pub message: BeaconBlock, -} - -/// Merkle proof depth for a `BeaconBlockBody` struct with 12 fields. -/// -/// The proof depth is determined by finding the smallest power of 2 that is -/// greater than or equal to the number of fields. In this case, the number of -/// fields is 12, which is between 8 (2^3) and 16 (2^4). -pub const BEACON_BLOCK_BODY_PROOF_DEPTH: usize = 4; - -/// The field corresponds to the index of the `execution_payload` field in the [`BeaconBlockBody`] struct: -/// . -pub const EXECUTION_PAYLOAD_FIELD_INDEX: usize = 9; - -pub trait HistoricalDataProofs { - fn compute_merkle_proof(&self, index: usize) -> Result, Error>; -} - -impl HistoricalDataProofs for BeaconBlockBody { - fn compute_merkle_proof(&self, index: usize) -> Result, Error> { - let field_index = match index { - index if index == EXECUTION_PAYLOAD_INDEX => index - .checked_sub(NUM_BEACON_BLOCK_BODY_HASH_TREE_ROOT_LEAVES) - .ok_or(Error::IndexNotSupported(index))?, - _ => return Err(Error::IndexNotSupported(index)), - }; - - let attestations_root = if self.fork_name() > ForkName::Electra { - self.attestations_electra()?.tree_hash_root() - } else { - self.attestations_base()?.tree_hash_root() - }; - - let attester_slashings_root = if self.fork_name() > ForkName::Electra { - self.attester_slashings_electra()?.tree_hash_root() - } else { - self.attester_slashings_base()?.tree_hash_root() - }; - - let mut leaves = vec![ - self.randao_reveal().tree_hash_root(), - self.eth1_data().tree_hash_root(), - self.graffiti().tree_hash_root(), - self.proposer_slashings().tree_hash_root(), - attester_slashings_root, - attestations_root, - self.deposits().tree_hash_root(), - self.voluntary_exits().tree_hash_root(), - ]; - - if let Ok(sync_aggregate) = self.sync_aggregate() { - leaves.push(sync_aggregate.tree_hash_root()) - } - - if let Ok(execution_payload) = self.execution_payload() { - leaves.push(execution_payload.tree_hash_root()) - } - - if let Ok(bls_to_execution_changes) = self.bls_to_execution_changes() { - leaves.push(bls_to_execution_changes.tree_hash_root()) - } - - if let Ok(blob_kzg_commitments) = self.blob_kzg_commitments() { - leaves.push(blob_kzg_commitments.tree_hash_root()) - } - - let depth = light_client_update::EXECUTION_PAYLOAD_PROOF_LEN; - let tree = merkle_proof::MerkleTree::create(&leaves, depth); - let (_, proof) = tree.generate_proof(field_index, depth)?; - - Ok(proof) - } -} diff --git a/crates/forrestrie/src/beacon_state.rs b/crates/forrestrie/src/beacon_state.rs deleted file mode 100644 index 531fa59a..00000000 --- a/crates/forrestrie/src/beacon_state.rs +++ /dev/null @@ -1,223 +0,0 @@ -use merkle_proof::MerkleTree; -use primitive_types::H256; -use serde::{Deserialize, Serialize}; -use std::sync::Arc; -use tree_hash::TreeHash; -use types::{ - historical_summary::HistoricalSummary, light_client_update, map_beacon_state_altair_fields, - map_beacon_state_base_fields, map_beacon_state_bellatrix_fields, - map_beacon_state_capella_fields, map_beacon_state_deneb_fields, - map_beacon_state_electra_fields, BeaconBlockHeader, BeaconState, BeaconStateAltair, - BeaconStateBase, BeaconStateBellatrix, BeaconStateCapella, BeaconStateDeneb, - BeaconStateElectra, BeaconStateError as Error, BitVector, Checkpoint, Epoch, Eth1Data, EthSpec, - ExecutionPayloadHeaderBellatrix, ExecutionPayloadHeaderCapella, ExecutionPayloadHeaderDeneb, - ExecutionPayloadHeaderElectra, Fork, Hash256, List, ParticipationFlags, PendingAttestation, - PendingBalanceDeposit, PendingConsolidation, PendingPartialWithdrawal, Slot, SyncCommittee, - Validator, Vector, -}; - -/// The number of slots in an epoch. -pub const SLOTS_PER_EPOCH: usize = 32; -/// The number of slots in an era. -pub const SLOTS_PER_ERA: usize = SLOTS_PER_HISTORICAL_ROOT; -/// Slots are 0-indexed. -/// See, for example, `https://beaconcha.in/slot/0`. -pub const BEACON_GENESIS_SLOT: usize = 0; -/// See [Upgrading Ethereum](https://eth2book.info/capella/part4/history/) for more information. -pub const PHASE_0_START_EPOCH: usize = 0; -/// See [Upgrading Ethereum](https://eth2book.info/capella/part4/history/) for more information. -pub const ALTAIR_START_EPOCH: usize = 74240; -/// See [Upgrading Ethereum](https://eth2book.info/capella/part4/history/) for more information. -pub const BELLATRIX_START_EPOCH: usize = 144896; -/// See [Upgrading Ethereum](https://eth2book.info/capella/part4/history/) for more information. -pub const CAPELLA_START_EPOCH: usize = 194048; -/// See [Upgrading Ethereum](https://eth2book.info/capella/part4/history/) for more information. -/// The first slot number of the Deneb fork. -pub const CAPELLA_START_SLOT: usize = CAPELLA_START_EPOCH * SLOTS_PER_EPOCH; -/// The first era of the Deneb fork. -pub const CAPELLA_START_ERA: usize = - (CAPELLA_START_EPOCH * SLOTS_PER_EPOCH) / SLOTS_PER_HISTORICAL_ROOT; -/// -pub const DENEB_START_SLOT: usize = 8626176; -/// -pub const FIRST_EXECUTION_BLOCK_DENEB: usize = 19426587; -/// The offset between the Ethereum block number and the Beacon block number at the start of the Deneb fork, -/// i.e. the difference between the first execution block number in the Deneb fork and the start slot number of the Deneb fork. -pub const ETHEREUM_BEACON_DENEB_OFFSET: usize = FIRST_EXECUTION_BLOCK_DENEB - DENEB_START_SLOT; - -/// [`BeaconState`] `block_roots` vector has length [`SLOTS_PER_HISTORICAL_ROOT`] (See ), -/// the value of which is calculated uint64(2**13) (= 8,192) (See ) -pub const HISTORY_TREE_DEPTH: usize = 13; - -/// The historical roots tree (pre-Capella) and the historical summaries tree (post-Capella) have the same depth. -/// Both tree's root has the block_roots tree root and the state_roots tree root as children and so has one more layer than each of these trees. -pub const HISTORICAL_SUMMARY_TREE_DEPTH: usize = 14; - -/// Historical roots is a top-level field on [`BeaconState`], subtract off the generalized indices -// for the internal nodes. Result should be 7, the field offset of the committee in the [`BeaconState`]: -// https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/beacon-chain.md#beaconstate -pub const HISTORICAL_ROOTS_INDEX: usize = 39; - -/// Historical summaries is a top-level field on [`BeaconState`], subtract off the generalized indices -// for the internal nodes. Result should be 27, the field offset of the committee in the [`BeaconState`]: -// https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/beacon-chain.md#beaconstate -pub const HISTORICAL_SUMMARIES_INDEX: usize = 59; - -/// Index of `historical_roots` field in the [`BeaconState`] [struct](https://github.com/ethereum/annotated-spec/blob/master/phase0/beacon-chain.md#beaconstate). -pub const HISTORICAL_ROOTS_FIELD_INDEX: usize = 7; - -/// Index of `historical_summaries` field in the (post-Capella) [`BeaconState`] [struct](https://github.com/ethereum/annotated-spec/blob/master/capella/beacon-chain.md#beaconstate). -pub const HISTORICAL_SUMMARIES_FIELD_INDEX: usize = 27; - -/// The maximum number of block roots that can be stored in a [`BeaconState`]'s `block_roots` list. -pub const SLOTS_PER_HISTORICAL_ROOT: usize = 8192; - -#[derive(Clone, Debug, Deserialize, Serialize)] -pub struct HeadState { - version: String, - execution_optimistic: bool, - data: BeaconState, -} - -impl HeadState { - pub fn compute_merkle_proof_for_historical_data( - &self, - index: usize, - ) -> Result, Error> { - // 1. Convert generalized index to field index. - let field_index = match index { - HISTORICAL_ROOTS_INDEX | HISTORICAL_SUMMARIES_INDEX => index - .checked_sub(self.data.num_fields_pow2()) - .ok_or(Error::IndexNotSupported(index))?, - _ => return Err(Error::IndexNotSupported(index)), - }; - - // 2. Get all `BeaconState` leaves. - let mut leaves = vec![]; - #[allow(clippy::arithmetic_side_effects)] - match &self.data { - BeaconState::Base(state) => { - map_beacon_state_base_fields!(state, |_, field| { - leaves.push(field.tree_hash_root()); - }); - } - BeaconState::Altair(state) => { - map_beacon_state_altair_fields!(state, |_, field| { - leaves.push(field.tree_hash_root()); - }); - } - BeaconState::Bellatrix(state) => { - map_beacon_state_bellatrix_fields!(state, |_, field| { - leaves.push(field.tree_hash_root()); - }); - } - BeaconState::Capella(state) => { - map_beacon_state_capella_fields!(state, |_, field| { - leaves.push(field.tree_hash_root()); - }); - } - BeaconState::Deneb(state) => { - map_beacon_state_deneb_fields!(state, |_, field| { - leaves.push(field.tree_hash_root()); - }); - } - BeaconState::Electra(state) => { - map_beacon_state_electra_fields!(state, |_, field| { - leaves.push(field.tree_hash_root()); - }); - } - }; - - // 3. Make deposit tree. - // Use the depth of the `BeaconState` fields (i.e. `log2(32) = 5`). - let depth = light_client_update::CURRENT_SYNC_COMMITTEE_PROOF_LEN; - let tree = MerkleTree::create(&leaves, depth); - let (_, proof) = tree.generate_proof(field_index, depth)?; - - Ok(proof) - } - - pub fn data(&self) -> &BeaconState { - &self.data - } - - pub fn execution_optimistic(&self) -> bool { - self.execution_optimistic - } - - pub fn historical_roots_tree_hash_root(&self) -> H256 { - self.data.historical_roots().tree_hash_root() - } - - pub fn historical_summaries_tree_hash_root(&self) -> Result { - Ok(self.data.historical_summaries()?.tree_hash_root()) - } - - pub fn state_root(&mut self) -> Result { - self.data.canonical_root() - } - - pub fn version(&self) -> &str { - &self.version - } - - /// This computation only makes sense if we have all of the leaves (BeaconBlock roots) to construct - /// the [`HistoricalSummary`] Merkle tree. - /// We construct a new [`HistoricalSummary`] from the state and check that the tree root is in historical_summaries. - /// This will be true if the state is in the first slot of an era. - pub fn block_roots_contain_entire_era(&self) -> Result { - // Check if the block_roots buffer can have accumulated an entire era, i.e. 8192 blocks. - if self.data.block_roots().len() % SLOTS_PER_HISTORICAL_ROOT == 0 { - let historical_summary = HistoricalSummary::new(&self.data); - Ok(self - .data - .historical_summaries()? - .iter() - .last() - .map(|summary| summary == &historical_summary) - .unwrap_or(false)) - } else { - Ok(false) - } - } - - /// Computes a Merkle inclusion proof of a `BeaconBlock` root using Merkle trees from either - /// the [`historical_roots`](https://github.com/ethereum/annotated-spec/blob/master/phase0/beacon-chain.md#beaconstate) - /// or [`historical_summaries`](https://github.com/ethereum/annotated-spec/blob/master/capella/beacon-chain.md#beaconstate) list. - /// See the discussion [here](https://github.com/ethereum/annotated-spec/blob/master/phase0/beacon-chain.md#slots_per_historical_root) - /// for more details about the `historical_roots` and [here](https://github.com/ethereum/annotated-spec/blob/master/capella/beacon-chain.md#historicalsummary) - /// about `historical_summaries`. - pub fn compute_block_roots_proof(&self, index: usize) -> Result, Error> { - // Construct the block_roots Merkle tree and generate the proof. - let leaves = self.data.block_roots().to_vec(); - let tree = MerkleTree::create(&leaves, HISTORY_TREE_DEPTH); - let (_, mut proof) = tree.generate_proof(index, HISTORY_TREE_DEPTH)?; - - // We are going to verify this proof using the HistoricalSummary root, the two children nodes are the block_roots tree root and that state_roots tree root. - // So we append the state_roots tree root to the proof. - let state_roots_root = self.data.state_roots().tree_hash_root(); - proof.push(state_roots_root); - - Ok(proof) - } - - pub fn compute_block_roots_proof_only(&self, index: usize) -> Result, Error> { - let leaves = self.data.block_roots().to_vec(); - let tree = MerkleTree::create(&leaves, HISTORY_TREE_DEPTH); - let (_, proof) = tree.generate_proof(index, HISTORY_TREE_DEPTH)?; - - Ok(proof) - } -} - -// Construct the block_roots Merkle tree and generate the proof. -pub fn compute_block_roots_proof_only( - block_roots: &[H256], - index: usize, -) -> Result, Error> { - let leaves = block_roots; - let tree = MerkleTree::create(leaves, HISTORY_TREE_DEPTH); - let (_, proof) = tree.generate_proof(index, HISTORY_TREE_DEPTH).unwrap(); - - Ok(proof) -} diff --git a/crates/forrestrie/src/beacon_v1.rs b/crates/forrestrie/src/beacon_v1.rs deleted file mode 100644 index 49a1b684..00000000 --- a/crates/forrestrie/src/beacon_v1.rs +++ /dev/null @@ -1,525 +0,0 @@ -//! Firehose Beacon-related data structures and operations. -//! See the protobuffer definitions section of the README for more information. -//! -use firehose_protos::{ProtosError, Response, SingleBlockResponse}; -use primitive_types::{H256, U256}; -use prost::Message; -use ssz_types::{length::Fixed, Bitfield, FixedVector}; -use types::{ - Address, BeaconBlock, BeaconBlockBodyDeneb, BitList, EthSpec, ExecutionBlockHash, Graffiti, - IndexedAttestationBase, MainnetEthSpec, GRAFFITI_BYTES_LEN, -}; - -tonic::include_proto!("sf.beacon.r#type.v1"); - -impl TryFrom for types::AttestationBase { - type Error = ProtosError; - - fn try_from( - Attestation { - aggregation_bits, - data, - signature, - }: Attestation, - ) -> Result { - Ok(Self { - aggregation_bits: BitList::from_bytes(aggregation_bits.as_slice().into()) - .map_err(|e| ProtosError::SszTypesError(format!("{:?}", e)))?, - data: data - .ok_or(ProtosError::AttestationDataMissing)? - .try_into()?, - signature: bls::generics::GenericAggregateSignature::deserialize(signature.as_slice()) - .map_err(|e| ProtosError::Bls(format!("{:?}", e)))?, - }) - } -} - -impl TryFrom for types::AttestationData { - type Error = ProtosError; - - fn try_from( - AttestationData { - slot, - committee_index, - beacon_block_root, - source, - target, - }: AttestationData, - ) -> Result { - Ok(Self { - slot: slot.into(), - index: committee_index, - beacon_block_root: H256::from_slice(beacon_block_root.as_slice()), - source: source.ok_or(ProtosError::CheckpointMissing)?.into(), - target: target.ok_or(ProtosError::CheckpointMissing)?.into(), - }) - } -} - -impl TryFrom for types::AttesterSlashingBase { - type Error = ProtosError; - - fn try_from( - AttesterSlashing { - attestation_1, - attestation_2, - }: AttesterSlashing, - ) -> Result { - let attestation_1 = attestation_1.ok_or(ProtosError::SignerMissing)?; - let attestation_2 = attestation_2.ok_or(ProtosError::SignerMissing)?; - - Ok(Self { - attestation_1: attestation_1.try_into()?, - attestation_2: attestation_2.try_into()?, - }) - } -} - -impl From for types::BeaconBlockHeader { - fn from( - BeaconBlockHeader { - slot, - proposer_index, - parent_root, - state_root, - body_root, - }: BeaconBlockHeader, - ) -> Self { - Self { - slot: slot.into(), - proposer_index, - parent_root: H256::from_slice(parent_root.as_slice()), - state_root: H256::from_slice(state_root.as_slice()), - body_root: H256::from_slice(body_root.as_slice()), - } - } -} - -impl TryFrom for types::BlsToExecutionChange { - type Error = ProtosError; - - fn try_from( - BlsToExecutionChange { - validator_index, - from_bls_pub_key, - to_execution_address, - }: BlsToExecutionChange, - ) -> Result { - Ok(Self { - validator_index, - from_bls_pubkey: bls::generics::GenericPublicKeyBytes::deserialize( - from_bls_pub_key.as_slice(), - ) - .map_err(|e| ProtosError::Bls(format!("{e:?}")))?, - to_execution_address: Address::from_slice(to_execution_address.as_slice()), - }) - } -} - -impl From for types::Checkpoint { - fn from(Checkpoint { epoch, root }: Checkpoint) -> Self { - Self { - epoch: epoch.into(), - root: H256::from_slice(root.as_slice()), - } - } -} - -impl TryFrom for types::ExecutionPayloadDeneb { - type Error = ProtosError; - - fn try_from( - DenebExecutionPayload { - parent_hash, - fee_recipient, - state_root, - receipts_root, - logs_bloom, - prev_randao, - block_number, - gas_limit, - gas_used, - timestamp, - extra_data, - base_fee_per_gas, - block_hash, - transactions, - withdrawals, - blob_gas_used, - excess_blob_gas, - }: DenebExecutionPayload, - ) -> Result { - Ok(Self { - parent_hash: ExecutionBlockHash::from_root(H256::from_slice(parent_hash.as_slice())), - fee_recipient: Address::from_slice(fee_recipient.as_slice()), - state_root: H256::from_slice(state_root.as_slice()), - receipts_root: H256::from_slice(receipts_root.as_slice()), - logs_bloom: FixedVector::from(logs_bloom), - prev_randao: H256::from_slice(prev_randao.as_slice()), - block_number, - gas_limit, - gas_used, - timestamp: timestamp - .as_ref() - .ok_or(ProtosError::BlockConversionError)? - .seconds as u64, - extra_data: extra_data.into(), - base_fee_per_gas: U256::from_big_endian(base_fee_per_gas.as_slice()), - block_hash: ExecutionBlockHash(H256::from_slice(block_hash.as_slice())), - transactions: transactions - .into_iter() - .map(Into::into) - .collect::>() - .into(), - withdrawals: withdrawals - .into_iter() - .map(Into::into) - .collect::>() - .into(), - blob_gas_used, - excess_blob_gas, - }) - } -} - -impl TryFrom for types::Deposit { - type Error = ProtosError; - - fn try_from(Deposit { proof, data }: Deposit) -> Result { - Ok(Self { - proof: proof - .into_iter() - .map(|v| H256::from_slice(v.as_slice())) - .collect::>() - .into(), - data: data.ok_or(ProtosError::DepositDataMissing)?.try_into()?, - }) - } -} - -impl TryFrom for types::DepositData { - type Error = ProtosError; - - fn try_from( - DepositData { - public_key, - withdrawal_credentials, - gwei, - signature, - }: DepositData, - ) -> Result { - Ok(Self { - pubkey: bls::generics::GenericPublicKeyBytes::deserialize(public_key.as_slice()) - .map_err(|e| ProtosError::Bls(format!("{:?}", e)))?, - withdrawal_credentials: H256::from_slice(withdrawal_credentials.as_slice()), - amount: gwei, - signature: bls::generics::GenericSignatureBytes::deserialize(signature.as_slice()) - .map_err(|e| ProtosError::Bls(format!("{:?}", e)))?, - }) - } -} - -impl From for types::Eth1Data { - fn from( - Eth1Data { - deposit_root, - deposit_count, - block_hash, - }: Eth1Data, - ) -> Self { - Self { - deposit_root: H256::from_slice(deposit_root.as_slice()), - deposit_count, - block_hash: H256::from_slice(block_hash.as_slice()), - } - } -} - -impl TryFrom for types::IndexedAttestationBase { - type Error = ProtosError; - - fn try_from( - IndexedAttestation { - attesting_indices, - data, - signature, - }: IndexedAttestation, - ) -> Result { - Ok(IndexedAttestationBase { - attesting_indices: attesting_indices.into(), - data: data - .ok_or(ProtosError::IndexedAttestationDataMissing)? - .try_into()?, - signature: bls::generics::GenericAggregateSignature::deserialize(signature.as_slice()) - .map_err(|e| ProtosError::Bls(format!("{:?}", e)))?, - }) - } -} - -impl TryFrom for types::ProposerSlashing { - type Error = ProtosError; - - fn try_from( - ProposerSlashing { - signed_header_1, - signed_header_2, - }: ProposerSlashing, - ) -> Result { - Ok(Self { - signed_header_1: signed_header_1 - .ok_or(ProtosError::SignerMissing)? - .try_into()?, - signed_header_2: signed_header_2 - .ok_or(ProtosError::SignerMissing)? - .try_into()?, - }) - } -} - -impl TryFrom for types::SignedBeaconBlockHeader { - type Error = ProtosError; - - fn try_from( - SignedBeaconBlockHeader { message, signature }: SignedBeaconBlockHeader, - ) -> Result { - Ok(Self { - message: message - .ok_or(ProtosError::SignedBeaconBlockHeaderMessageMissing)? - .into(), - signature: bls::generics::GenericSignature::deserialize(signature.as_slice()) - .map_err(|e| ProtosError::Bls(format!("{:?}", e)))?, - }) - } -} - -impl TryFrom for types::SignedBlsToExecutionChange { - type Error = ProtosError; - - fn try_from( - SignedBlsToExecutionChange { message, signature }: SignedBlsToExecutionChange, - ) -> Result { - Ok(Self { - message: message - .ok_or(ProtosError::BlsToExecutionChangeMissing)? - .try_into()?, - signature: bls::generics::GenericSignature::deserialize(signature.as_slice()) - .expect("Failed to deserialize signature"), - }) - } -} - -impl TryFrom for types::SignedVoluntaryExit { - type Error = ProtosError; - - fn try_from( - SignedVoluntaryExit { message, signature }: SignedVoluntaryExit, - ) -> Result { - Ok(Self { - message: message.ok_or(ProtosError::VoluntaryExitMissing)?.into(), - signature: bls::generics::GenericSignature::deserialize(signature.as_slice()) - .map_err(|e| ProtosError::Bls(format!("{:?}", e)))?, - }) - } -} - -impl TryFrom for Block { - type Error = ProtosError; - - fn try_from(response: SingleBlockResponse) -> Result { - let any = response.block.ok_or(ProtosError::BlockMissingInResponse)?; - let block = Block::decode(any.value.as_ref())?; - Ok(block) - } -} - -impl TryFrom for Block { - type Error = ProtosError; - - fn try_from(response: Response) -> Result { - let any = response.block.ok_or(ProtosError::BlockMissingInResponse)?; - let block = Block::decode(any.value.as_ref())?; - Ok(block) - } -} - -impl TryFrom for types::SyncAggregate { - type Error = ProtosError; - - fn try_from( - SyncAggregate { - sync_commitee_bits, - sync_comittee_signature, - }: SyncAggregate, - ) -> Result { - Ok(Self { - sync_committee_bits: Bitfield::::SyncCommitteeSize>>::from_bytes( - sync_commitee_bits.as_slice().into(), - ) - .map_err(|e| ProtosError::SszTypesError(format!("{:?}", e)))?, - sync_committee_signature: bls::generics::GenericAggregateSignature::deserialize( - sync_comittee_signature.as_slice(), - ) - .map_err(|e| ProtosError::Bls(format!("{:?}", e)))?, - }) - } -} - -impl From for types::VoluntaryExit { - fn from( - VoluntaryExit { - epoch, - validator_index, - }: VoluntaryExit, - ) -> Self { - Self { - epoch: epoch.into(), - validator_index, - } - } -} - -impl From for types::Withdrawal { - fn from( - Withdrawal { - withdrawal_index, - validator_index, - address, - gwei, - }: Withdrawal, - ) -> Self { - Self { - index: withdrawal_index, - validator_index, - address: Address::from_slice(address.as_slice()), - amount: gwei, - } - } -} - -impl TryFrom for types::BeaconBlockBodyDeneb { - type Error = ProtosError; - - fn try_from( - DenebBody { - rando_reveal, - eth1_data, - graffiti, - proposer_slashings, - attester_slashings, - attestations, - deposits, - voluntary_exits, - sync_aggregate, - execution_payload, - bls_to_execution_changes, - blob_kzg_commitments, - // Blobs not included. - .. - }: DenebBody, - ) -> Result { - let beacon_block_body = BeaconBlockBodyDeneb { - randao_reveal: bls::generics::GenericSignature::deserialize(&rando_reveal) - .map_err(|e| ProtosError::Bls(format!("{:?}", e)))?, - eth1_data: eth1_data - .map(|eth1_data| eth1_data.into()) - .unwrap_or_default(), - graffiti: Graffiti::from( - <[u8; GRAFFITI_BYTES_LEN]>::try_from(graffiti.as_slice()) - .map_err(|_| ProtosError::GraffitiInvalid)?, - ), - proposer_slashings: proposer_slashings - .into_iter() - .map(|proposer_slashing| proposer_slashing.try_into()) - .collect::, _>>()? - .into(), - attester_slashings: attester_slashings - .into_iter() - .map(|attester_slashing| attester_slashing.try_into()) - .collect::, _>>()? - .into(), - attestations: attestations - .into_iter() - .map(|attestation| attestation.try_into()) - .collect::, _>>()? - .into(), - deposits: deposits - .into_iter() - .map(|deposit| deposit.try_into()) - .collect::, _>>()? - .into(), - voluntary_exits: voluntary_exits - .into_iter() - .map(|voluntary_exit| voluntary_exit.try_into()) - .collect::, _>>()? - .into(), - sync_aggregate: sync_aggregate - .map(|sync_aggregate| sync_aggregate.try_into()) - .transpose()? - .unwrap_or_else(types::SyncAggregate::new), - execution_payload: execution_payload - .ok_or(ProtosError::ExecutionPayloadMissing) - .and_then(types::ExecutionPayloadDeneb::try_from)? - .into(), - bls_to_execution_changes: bls_to_execution_changes - .into_iter() - .map(|bls_to_execution_change| bls_to_execution_change.try_into()) - .collect::, _>>()? - .into(), - blob_kzg_commitments: blob_kzg_commitments - .into_iter() - .map(|blob_kzg_commitment| { - <[u8; 48]>::try_from(blob_kzg_commitment.as_slice()) - .map(types::KzgCommitment) - .map_err(|_| ProtosError::KzgCommitmentInvalid) - }) - .collect::, _>>()? - .into(), - }; - Ok(beacon_block_body) - } -} - -impl TryFrom for types::BeaconBlockBodyDeneb { - type Error = ProtosError; - - fn try_from(body: crate::beacon_v1::block::Body) -> Result { - match body { - crate::beacon_v1::block::Body::Deneb(deneb) => Ok(deneb.try_into()?), - _ => panic!("Invalid body type"), - } - } -} - -impl TryFrom for types::BeaconBlock { - type Error = ProtosError; - - fn try_from( - Block { - slot, - proposer_index, - parent_root, - state_root, - body, - .. - }: Block, - ) -> Result { - Ok(Self::Deneb(types::BeaconBlockDeneb { - slot: slot.into(), - proposer_index, - parent_root: H256::from_slice(parent_root.as_slice()), - state_root: H256::from_slice(state_root.as_slice()), - body: body.ok_or(ProtosError::BlockConversionError)?.try_into()?, - })) - } -} - -pub struct BlockRoot(pub H256); - -impl TryFrom for BlockRoot { - type Error = ProtosError; - - fn try_from(beacon_block: Block) -> Result { - let lighthouse_beacon_block = BeaconBlock::::try_from(beacon_block)?; - Ok(Self(lighthouse_beacon_block.canonical_root())) - } -} diff --git a/crates/forrestrie/src/execution_layer.rs b/crates/forrestrie/src/execution_layer.rs deleted file mode 100644 index 60687d84..00000000 --- a/crates/forrestrie/src/execution_layer.rs +++ /dev/null @@ -1,323 +0,0 @@ -//! Execution Layer functionality to build a Merkle Patricia Trie (MPT) from Ethereum receipts -//! and generate inclusion proofs for specified receipts within the trie. It includes data structures -//! for parsing and handling receipt data, as well as utilities for encoding and decoding as required -//! by the Ethereum specification. - -use alloy_primitives::{Bloom, U256}; -use alloy_rlp::Encodable; -use reth_primitives::{Log, Receipt, ReceiptWithBloom, TxType}; -use reth_trie_common::{proof::ProofRetainer, root::adjust_index_for_rlp, HashBuilder, Nibbles}; -use serde::{Deserialize, Deserializer, Serialize}; -use std::vec::IntoIter; - -#[derive(Debug, Deserialize, Serialize)] -pub struct ReceiptJson { - #[serde(rename = "type")] - #[serde(deserialize_with = "str_to_type")] - pub tx_type: TxType, - #[serde(rename = "blockHash")] - pub block_hash: String, - #[serde(rename = "blockNumber")] - pub block_number: String, - pub logs: Vec, - #[serde(rename = "cumulativeGasUsed")] - pub cumulative_gas_used: U256, - #[serde(deserialize_with = "status_to_bool")] - pub status: bool, - // TODO: should we trust logsBloom provided or calculate it from the logs? - #[serde(rename = "logsBloom")] - pub logs_bloom: Bloom, -} - -impl ReceiptJson { - #[cfg(test)] - fn fake() -> Self { - use alloy_primitives::{bytes, fixed_bytes, Address}; - use rand::{self, rngs::OsRng, RngCore}; - - fn fake_log() -> Log { - // generate random slice of bytes - let mut random_bytes = [0u8; 20]; - OsRng.fill_bytes(&mut random_bytes); - // Create a 32-byte array initialized with zeros - let mut bytes = [0u8; 32]; - - // Insert the random bytes into the last 20 bytes of the array - bytes[12..].copy_from_slice(&random_bytes); - - // Generate a static Log based on an actual log receipt - Log::new_unchecked( - Address::random(), - vec![ - fixed_bytes!( - "e1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c" - ), - fixed_bytes!( - "0000000000000000000000003328f7f4a1d1c57c35df56bbf0c9dcafca309c49" - ), - ], - bytes!("0000000000000000000000000000000000000000000000000dcf09da3e1eb9f3"), - ) - } - - let logs: Vec = (0..5).map(|_| fake_log()).collect(); - - ReceiptJson { - tx_type: TxType::Eip1559, // Replace with any desired variant - block_hash: "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef" - .to_string(), - block_number: "0x1a".to_string(), - logs, - cumulative_gas_used: U256::from(0x5208), - status: true, - logs_bloom: Bloom::default(), - } - } -} - -/// Represents a leaf in the trie for which a proof is to be generated, i.e., the target of the proof. -/// The `nibbles` represent the path to the leaf in the trie, and the `value` is the data stored at the leaf. -#[derive(Debug)] -pub struct TargetLeaf { - pub nibbles: Nibbles, - pub value: Vec, -} - -impl TargetLeaf { - // Constructor to create a new TargetLeaf - pub fn new(nibbles: Nibbles, value: Vec) -> Self { - TargetLeaf { nibbles, value } - } -} - -pub struct TargetLeaves(Vec); - -impl TargetLeaves { - fn new() -> Self { - TargetLeaves(Vec::new()) - } - - pub fn from_indices( - target_idxs: &[usize], - receipts: &[ReceiptWithBloom], - ) -> Result { - let mut index_buffer = Vec::new(); - let mut value_buffer = Vec::new(); - let mut targets = TargetLeaves::new(); - let receipts_len = receipts.len(); - - for &target_idx in target_idxs { - if target_idx >= receipts_len { - return Err("Index out of bounds"); - } - - index_buffer.clear(); - value_buffer.clear(); - - // Adjust the index and encode it - let index = adjust_index_for_rlp(target_idx, receipts_len); - index.encode(&mut index_buffer); - - // Generate nibble path from the index buffer - let nibble = Nibbles::unpack(&index_buffer); - - // Encode the receipt and create TargetLeaf - receipts[index].encode_inner(&mut value_buffer, false); - targets - .0 - .push(TargetLeaf::new(nibble, value_buffer.clone())); - } - - Ok(targets) - } -} - -impl IntoIterator for TargetLeaves { - type Item = TargetLeaf; - type IntoIter = IntoIter; - - fn into_iter(self) -> Self::IntoIter { - self.0.into_iter() - } -} - -impl TryFrom<&ReceiptJson> for ReceiptWithBloom { - type Error = String; - - fn try_from(receipt_json: &ReceiptJson) -> Result { - let cumulative_gas_used = receipt_json - .cumulative_gas_used - .try_into() - .map_err(|_| "Failed to convert U256 to u64".to_string())?; - - let receipt = Receipt { - tx_type: receipt_json.tx_type, - success: receipt_json.status, - cumulative_gas_used, - logs: receipt_json.logs.clone(), - // NOTICE: receipts will have more fields depending of the EVM chain. - // this is how to handle them in the futuro - // #[cfg(feature = "optimism")] - // deposit_nonce: None, // Handle Optimism-specific fields as necessary - // #[cfg(feature = "optimism")] - // deposit_receipt_version: None, - }; - - Ok(ReceiptWithBloom { - bloom: receipt_json.logs_bloom, - receipt, - }) - } -} - -#[derive(Debug, Deserialize, Serialize)] -pub struct ReceiptsFromBlock { - pub result: Vec, -} - -impl FromIterator for ReceiptsFromBlock { - fn from_iter>(iter: I) -> Self { - ReceiptsFromBlock { - result: iter.into_iter().collect(), - } - } -} - -fn status_to_bool<'de, D>(deserializer: D) -> Result -where - D: Deserializer<'de>, -{ - let status_str: &str = Deserialize::deserialize(deserializer)?; - match status_str { - "0x1" => Ok(true), - "0x0" => Ok(false), - _ => Err(serde::de::Error::custom("Invalid status value")), - } -} - -fn str_to_type<'de, D>(deserializer: D) -> Result -where - D: Deserializer<'de>, -{ - let tx_type_str: &str = Deserialize::deserialize(deserializer)?; - // Convert the hex string (without the "0x" prefix) to u8 - let tx_type_value = u8::from_str_radix(tx_type_str.trim_start_matches("0x"), 16) - .map_err(|_| serde::de::Error::custom("Invalid tx_type value"))?; - TxType::try_from(tx_type_value).map_err(|_| serde::de::Error::custom("Invalid tx_type value")) -} - -/// builds the trie to generate proofs from the Receipts -/// generate a different root. Make sure that the source of receipts sorts them by `logIndex` -/// # Example -/// -/// ```no_run -/// # use reth_primitives::ReceiptWithBloom; -/// # use forrestrie::execution_layer::build_trie_with_proofs; -/// # let receipts_json = vec![]; -/// // Assume `receipts_json` is a vector of deserialized receipt objects from an execution block given by an Ethereum node. -/// let receipts_with_bloom: Vec = receipts_json -/// .iter() -/// .map(ReceiptWithBloom::try_from) -/// .collect::>().unwrap(); -/// -/// // Specify the indices of receipts for which proofs are needed. -/// let target_indices = &[0, 2, 5]; -/// -/// // Build the trie and obtain proofs. -/// let mut hash_builder = build_trie_with_proofs(&receipts_with_bloom, target_indices); -/// -/// // Retrieve the root hash of the trie, and retain the proofs so they can be verified. -/// let trie_root = hash_builder.root(); -/// ``` -pub fn build_trie_with_proofs(receipts: &[ReceiptWithBloom], target_idxs: &[usize]) -> HashBuilder { - // Initialize ProofRetainer with the target nibbles (the keys for which we want proofs) - let receipts_len = receipts.len(); - let targets: Vec = target_idxs - .iter() - .map(|&i| { - let index = adjust_index_for_rlp(i, receipts_len); - let mut index_buffer = Vec::new(); - index.encode(&mut index_buffer); - Nibbles::unpack(&index_buffer) - }) - .collect(); - - let proof_retainer = ProofRetainer::new(targets); - let mut hb = HashBuilder::default().with_proof_retainer(proof_retainer); - - for i in 0..receipts_len { - // Adjust the index for RLP - let index = adjust_index_for_rlp(i, receipts_len); - - // Encode the index into nibbles - let mut index_buffer = Vec::new(); - index.encode(&mut index_buffer); - let index_nibbles = Nibbles::unpack(&index_buffer); - - // Encode the receipt value - let mut value_buffer = Vec::new(); - receipts[index].encode_inner(&mut value_buffer, false); - - hb.add_leaf(index_nibbles, &value_buffer); - } - - hb -} - -#[cfg(test)] -mod tests { - use super::*; - use reth_trie_common::proof::verify_proof; - - #[test] - fn test_compute_receipts_trie_root_and_proof() { - let block_receipts: ReceiptsFromBlock = (0_i32..10).map(|_| ReceiptJson::fake()).collect(); - - let receipts_with_bloom: Result, String> = block_receipts - .result - .iter() - .map(ReceiptWithBloom::try_from) - .collect::, _>>(); - - // computes the root and verify against existing data - let mut hb: HashBuilder; - //target_idxs are the logIndexes for receipts to get proofs from. - // these values are arbitrary - let target_idxs = &[4]; - let targets: TargetLeaves; - - match receipts_with_bloom { - Ok(receipts) => { - hb = build_trie_with_proofs(&receipts, target_idxs); - - // build some of the targets to get proofs for them - targets = TargetLeaves::from_indices(target_idxs, &receipts).unwrap(); - } - Err(e) => { - // Handle the error (e.g., by logging or panicking) - panic!("Failed to convert receipts: {}", e); - } - } - - // necessary to call this method to retain proofs - hb.root(); - - // verifies proof for retained targets - let proof = hb.take_proof_nodes(); - for target in targets { - assert_eq!( - verify_proof( - hb.root(), - target.nibbles.clone(), - Some(target.value.to_vec()), - proof - .clone() - .matching_nodes_sorted(&target.nibbles) - .iter() - .map(|(_, node)| node) - ), - Ok(()) - ); - } - } -} diff --git a/crates/forrestrie/src/lib.rs b/crates/forrestrie/src/lib.rs deleted file mode 100644 index 004216f2..00000000 --- a/crates/forrestrie/src/lib.rs +++ /dev/null @@ -1,4 +0,0 @@ -pub mod beacon_block; -pub mod beacon_state; -pub mod beacon_v1; -pub mod execution_layer; diff --git a/release-please-config.json b/release-please-config.json index cb6009b1..d2635bd0 100644 --- a/release-please-config.json +++ b/release-please-config.json @@ -6,10 +6,7 @@ "cargo-workspace" ], "packages": { - "crates/firehose-client": {}, "crates/flat-files-decoder": {}, - "crates/forrestrie": {}, - "crates/forrestrie-examples": {}, "crates/header-accumulator": {}, "crates/firehose-protos": {}, "crates/firehose-protos-examples": {}