diff --git a/.release-please-manifest.json b/.release-please-manifest.json index e568574c..35ec8500 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,8 +1,5 @@ { - "crates/firehose-client": "0.1.1", "crates/flat-files-decoder": "0.2.0", - "crates/forrestrie": "0.1.1", - "crates/forrestrie-examples": "0.1.1", "crates/header-accumulator": "0.2.0", "crates/firehose-protos": "0.1.0", "crates/firehose-protos-examples": "0.1.0" diff --git a/Cargo.lock b/Cargo.lock index aee83724..4547cc8c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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.13", + "alloy-primitives", "num_enum", "serde", "strum", @@ -113,36 +113,36 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "705687d5bfd019fee57cf9e206b27b30a9a9617535d5590a02b171e813208f8e" dependencies = [ "alloy-eips", - "alloy-primitives 0.8.13", + "alloy-primitives", "alloy-rlp", "alloy-serde", "auto_impl", "c-kzg", - "derive_more 1.0.0", + "derive_more", "serde", ] [[package]] name = "alloy-core" -version = "0.8.13" +version = "0.8.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8d22df68fa7d9744be0b1a9be3260e9aa089fbf41903ab182328333061ed186" +checksum = "c3d14d531c99995de71558e8e2206c27d709559ee8e5a0452b965ea82405a013" dependencies = [ "alloy-dyn-abi", "alloy-json-abi", - "alloy-primitives 0.8.13", + "alloy-primitives", "alloy-rlp", "alloy-sol-types", ] [[package]] name = "alloy-dyn-abi" -version = "0.8.13" +version = "0.8.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cf633ae9a1f0c82fdb9e559ed2be1c8e415c3e48fc47e1feaf32c6078ec0cdd" +checksum = "80759b3f57b3b20fa7cd8fef6479930fc95461b58ff8adea6e87e618449c8a1d" dependencies = [ "alloy-json-abi", - "alloy-primitives 0.8.13", + "alloy-primitives", "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.13", + "alloy-primitives", "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.13", + "alloy-primitives", "alloy-rlp", "k256", "serde", @@ -183,11 +183,11 @@ checksum = "6ffb906284a1e1f63c4607da2068c8197458a352d0b3e9796e67353d72a9be85" dependencies = [ "alloy-eip2930", "alloy-eip7702", - "alloy-primitives 0.8.13", + "alloy-primitives", "alloy-rlp", "alloy-serde", "c-kzg", - "derive_more 1.0.0", + "derive_more", "once_cell", "serde", "sha2", @@ -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.13", + "alloy-primitives", "alloy-serde", "serde", ] [[package]] name = "alloy-json-abi" -version = "0.8.13" +version = "0.8.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a500037938085feed8a20dbfc8fce58c599db68c948cfae711147175dee392c" +checksum = "ac4b22b3e51cac09fd2adfcc73b55f447b4df669f983c13f7894ec82b607c63f" dependencies = [ - "alloy-primitives 0.8.13", + "alloy-primitives", "alloy-sol-type-parser", "serde", "serde_json", @@ -224,44 +224,22 @@ checksum = "801492711d4392b2ccf5fc0bc69e299fa1aab15167d74dcaa9aab96a54f684bd" dependencies = [ "alloy-consensus", "alloy-eips", - "alloy-primitives 0.8.13", + "alloy-primitives", "alloy-serde", "serde", ] [[package]] name = "alloy-primitives" -version = "0.7.7" +version = "0.8.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccb3ead547f4532bc8af961649942f0b9c16ee9226e26caa3f38420651cc0bf4" +checksum = "9db948902dfbae96a73c2fbf1f7abec62af034ab883e4c777c3fd29702bd6e2c" dependencies = [ "alloy-rlp", "bytes", "cfg-if", "const-hex", - "derive_more 0.99.18", - "hex-literal", - "itoa", - "k256", - "keccak-asm", - "proptest", - "rand", - "ruint", - "serde", - "tiny-keccak", -] - -[[package]] -name = "alloy-primitives" -version = "0.8.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3aeeb5825c2fc8c2662167058347cd0cafc3cb15bcb5cdb1758a63c2dca0409e" -dependencies = [ - "alloy-rlp", - "bytes", - "cfg-if", - "const-hex", - "derive_more 1.0.0", + "derive_more", "foldhash", "getrandom", "hashbrown 0.15.2", @@ -308,7 +286,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ffc534b7919e18f35e3aa1f507b6f3d9d92ec298463a9f6beaac112809d8d06" dependencies = [ - "alloy-primitives 0.8.13", + "alloy-primitives", "alloy-rpc-types-eth", "alloy-serde", "serde", @@ -323,11 +301,11 @@ dependencies = [ "alloy-consensus", "alloy-eips", "alloy-network-primitives", - "alloy-primitives 0.8.13", + "alloy-primitives", "alloy-rlp", "alloy-serde", "alloy-sol-types", - "derive_more 1.0.0", + "derive_more", "itertools 0.13.0", "serde", "serde_json", @@ -339,16 +317,16 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9dff0ab1cdd43ca001e324dc27ee0e8606bd2161d6623c63e0e0b8c4dfc13600" dependencies = [ - "alloy-primitives 0.8.13", + "alloy-primitives", "serde", "serde_json", ] [[package]] name = "alloy-sol-macro" -version = "0.8.13" +version = "0.8.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c0279d09463a4695788a3622fd95443625f7be307422deba4b55dd491a9c7a1" +checksum = "3bfd7853b65a2b4f49629ec975fee274faf6dff15ab8894c620943398ef283c0" dependencies = [ "alloy-sol-macro-expander", "alloy-sol-macro-input", @@ -360,9 +338,9 @@ dependencies = [ [[package]] name = "alloy-sol-macro-expander" -version = "0.8.13" +version = "0.8.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4feea540fc8233df2ad1156efd744b2075372f43a8f942a68b3b19c8a00e2c12" +checksum = "82ec42f342d9a9261699f8078e57a7a4fda8aaa73c1a212ed3987080e6a9cd13" dependencies = [ "alloy-sol-macro-input", "const-hex", @@ -378,9 +356,9 @@ dependencies = [ [[package]] name = "alloy-sol-macro-input" -version = "0.8.13" +version = "0.8.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0ad281f3d1b613af814b66977ee698e443d4644a1510962d0241f26e0e53ae" +checksum = "ed2c50e6a62ee2b4f7ab3c6d0366e5770a21cad426e109c2f40335a1b3aff3df" dependencies = [ "const-hex", "dunce", @@ -393,9 +371,9 @@ dependencies = [ [[package]] name = "alloy-sol-type-parser" -version = "0.8.13" +version = "0.8.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96eff16c797438add6c37bb335839d015b186c5421ee5626f5559a7bfeb38ef5" +checksum = "ac17c6e89a50fb4a758012e4b409d9a0ba575228e69b539fe37d7a1bd507ca4a" dependencies = [ "serde", "winnow", @@ -403,12 +381,12 @@ dependencies = [ [[package]] name = "alloy-sol-types" -version = "0.8.13" +version = "0.8.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cff34e0682d6665da243a3e81da96f07a2dd50f7e64073e382b1a141f5a2a2f6" +checksum = "c9dc0fffe397aa17628160e16b89f704098bf3c9d74d5d369ebc239575936de5" dependencies = [ "alloy-json-abi", - "alloy-primitives 0.8.13", + "alloy-primitives", "alloy-sol-macro", "const-hex", "serde", @@ -420,9 +398,9 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e9703ce68b97f8faae6f7739d1e003fc97621b856953cbcdbb2b515743f23288" dependencies = [ - "alloy-primitives 0.8.13", + "alloy-primitives", "alloy-rlp", - "derive_more 1.0.0", + "derive_more", "nybbles", "serde", "smallvec", @@ -508,24 +486,6 @@ version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" -[[package]] -name = "arbitrary" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223" -dependencies = [ - "derive_arbitrary", -] - -[[package]] -name = "archery" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a8da9bc4c4053ee067669762bcaeea6e241841295a2b6c948312dad6ef4cc02" -dependencies = [ - "static_assertions", -] - [[package]] name = "ark-ff" version = "0.3.0" @@ -841,27 +801,6 @@ 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#ce68a3b7cef376887d0583dcc9e2234ffc5abb7f" -dependencies = [ - "bls", - "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" @@ -968,24 +907,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" -[[package]] -name = "bls" -version = "0.2.0" -source = "git+https://github.com/semiotic-ai/lighthouse.git?branch=stable#680cdbfcecb03c651db15e8949bd7367ef39c9ed" -dependencies = [ - "arbitrary", - "blst", - "ethereum-types", - "ethereum_hashing 0.6.0", - "ethereum_serde_utils 0.5.2", - "ethereum_ssz 0.5.4", - "hex", - "rand", - "serde", - "tree_hash 0.6.0", - "zeroize", -] - [[package]] name = "blst" version = "0.3.13" @@ -1206,40 +1127,11 @@ dependencies = [ "memchr", ] -[[package]] -name = "compare_fields" -version = "0.2.0" -source = "git+https://github.com/semiotic-ai/lighthouse.git?branch=stable#680cdbfcecb03c651db15e8949bd7367ef39c9ed" -dependencies = [ - "itertools 0.10.5", -] - -[[package]] -name = "compare_fields_derive" -version = "0.2.0" -source = "git+https://github.com/semiotic-ai/lighthouse.git?branch=stable#680cdbfcecb03c651db15e8949bd7367ef39c9ed" -dependencies = [ - "quote", - "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.2" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "487981fa1af147182687064d0a2c336586d337a606595ced9ffb0c685c250c73" +checksum = "4b0485bab839b018a8f1723fc5391819fea5f8f0f32288ef8a735fd096b6160c" dependencies = [ "cfg-if", "cpufeatures", @@ -1281,12 +1173,6 @@ dependencies = [ "unicode-xid", ] -[[package]] -name = "convert_case" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" - [[package]] name = "convert_case" version = "0.6.0" @@ -1599,30 +1485,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "derive_arbitrary" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.89", -] - -[[package]] -name = "derive_more" -version = "0.99.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" -dependencies = [ - "convert_case 0.4.0", - "proc-macro2", - "quote", - "rustc_version 0.4.1", - "syn 2.0.89", -] - [[package]] name = "derive_more" version = "1.0.0" @@ -1638,19 +1500,13 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" dependencies = [ - "convert_case 0.6.0", + "convert_case", "proc-macro2", "quote", "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" @@ -1815,21 +1671,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" @@ -1876,15 +1717,6 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" -[[package]] -name = "erased-serde" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c138974f9d5e7fe373eb04df7cae98833802ae4b11c24ac7039a21d5af4b26c" -dependencies = [ - "serde", -] - [[package]] name = "erased-serde" version = "0.4.5" @@ -1905,26 +1737,12 @@ dependencies = [ "windows-sys 0.59.0", ] -[[package]] -name = "eth2_interop_keypairs" -version = "0.2.0" -source = "git+https://github.com/semiotic-ai/lighthouse.git?branch=stable#680cdbfcecb03c651db15e8949bd7367ef39c9ed" -dependencies = [ - "bls", - "ethereum_hashing 0.6.0", - "hex", - "lazy_static", - "num-bigint", - "serde", - "serde_yaml", -] - [[package]] 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.13", + "alloy-primitives", "alloy-rlp", "hashbrown 0.14.5", "keccak-hash", @@ -1932,45 +1750,6 @@ dependencies = [ "parking_lot 0.12.3", ] -[[package]] -name = "ethbloom" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c22d4b5885b6aa2fe5e8b9329fb8d232bf739e434e6b87347c63bdd00c120f60" -dependencies = [ - "crunchy", - "fixed-hash", - "impl-rlp", - "impl-serde", - "tiny-keccak", -] - -[[package]] -name = "ethereum-types" -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02d215cbf040552efcbe99a38372fe80ab9d00268e20012b79fcd0f073edd8ee" -dependencies = [ - "ethbloom", - "fixed-hash", - "impl-rlp", - "impl-serde", - "primitive-types", - "uint", -] - -[[package]] -name = "ethereum_hashing" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea7b408432c13f71af01197b1d3d0069c48a27bfcfbe72a81fc346e47f6defb" -dependencies = [ - "cpufeatures", - "lazy_static", - "ring", - "sha2", -] - [[package]] name = "ethereum_hashing" version = "0.7.0" @@ -1982,66 +1761,30 @@ dependencies = [ "sha2", ] -[[package]] -name = "ethereum_serde_utils" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de4d5951468846963c24e8744c133d44f39dff2cd3a233f6be22b370d08a524f" -dependencies = [ - "ethereum-types", - "hex", - "serde", - "serde_derive", - "serde_json", -] - [[package]] name = "ethereum_serde_utils" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70cbccfccf81d67bff0ab36e591fa536c8a935b078a7b0e58c1d00d418332fc9" dependencies = [ - "alloy-primitives 0.8.13", + "alloy-primitives", "hex", "serde", "serde_derive", "serde_json", ] -[[package]] -name = "ethereum_ssz" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d3627f83d8b87b432a5fad9934b4565260722a141a2c40f371f8080adec9425" -dependencies = [ - "ethereum-types", - "itertools 0.10.5", - "smallvec", -] - [[package]] name = "ethereum_ssz" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e999563461faea0ab9bc0024e5e66adcee35881f3d5062f52f31a4070fe1522" dependencies = [ - "alloy-primitives 0.8.13", + "alloy-primitives", "itertools 0.13.0", "smallvec", ] -[[package]] -name = "ethereum_ssz_derive" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eccd5378ec34a07edd3d9b48088cbc63309d0367d14ba10b0cdb1d1791080ea" -dependencies = [ - "darling 0.13.4", - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "ethereum_ssz_derive" version = "0.7.1" @@ -2071,10 +1814,10 @@ dependencies = [ "const_format", "discv5", "eth_trie", - "ethereum_hashing 0.7.0", - "ethereum_serde_utils 0.7.0", - "ethereum_ssz 0.7.1", - "ethereum_ssz_derive 0.7.1", + "ethereum_hashing", + "ethereum_serde_utils", + "ethereum_ssz", + "ethereum_ssz_derive", "hex", "jsonrpsee", "keccak-hash", @@ -2091,40 +1834,18 @@ dependencies = [ "serde_json", "sha2", "sha3 0.9.1", - "ssz_types 0.8.0", - "superstruct 0.7.0", + "ssz_types", + "superstruct", "thiserror 1.0.69", "tokio", - "tree_hash 0.8.0", - "tree_hash_derive 0.8.0", + "tree_hash", + "tree_hash_derive", "trin-utils", "ureq", "url", "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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" - -[[package]] -name = "fallible-streaming-iterator" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" - [[package]] name = "fastrand" version = "2.2.0" @@ -2184,7 +1905,7 @@ version = "0.1.0" dependencies = [ "alloy-consensus", "alloy-eip2930", - "alloy-primitives 0.8.13", + "alloy-primitives", "alloy-rlp", "ethportal-api", "firehose-rs", @@ -2209,7 +1930,7 @@ dependencies = [ name = "firehose-protos-examples" version = "0.1.1" dependencies = [ - "alloy-primitives 0.8.13", + "alloy-primitives", "firehose-client", "firehose-protos", "tokio", @@ -2235,7 +1956,6 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" dependencies = [ - "arbitrary", "byteorder", "rand", "rustc-hex", @@ -2254,7 +1974,7 @@ version = "0.1.1" dependencies = [ "alloy-consensus", "alloy-eip2930", - "alloy-primitives 0.8.13", + "alloy-primitives", "bincode", "clap", "criterion", @@ -2292,21 +2012,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" @@ -2316,60 +2021,6 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "forrestrie" -version = "0.1.1" -dependencies = [ - "alloy-primitives 0.8.13", - "alloy-rlp", - "bls", - "fake", - "merkle_proof", - "primitive-types", - "rand", - "reth-primitives", - "reth-trie-common", - "serde", - "ssz_types 0.6.0", - "tree_hash 0.6.0", - "types", -] - -[[package]] -name = "forrestrie-examples" -version = "0.1.1" -dependencies = [ - "beacon-protos", - "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" @@ -2665,7 +2316,7 @@ dependencies = [ name = "header-accumulator" version = "0.1.0" dependencies = [ - "alloy-primitives 0.8.13", + "alloy-primitives", "base64 0.21.7", "clap", "ethportal-api", @@ -2678,7 +2329,7 @@ dependencies = [ "serde_json", "tempfile", "thiserror 2.0.3", - "tree_hash 0.8.0", + "tree_hash", "trin-validation", ] @@ -2849,22 +2500,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" @@ -3078,24 +2713,6 @@ dependencies = [ "parity-scale-codec", ] -[[package]] -name = "impl-rlp" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f28220f89297a075ddc7245cd538076ee98b01f2a9c23a53a4f1105d5a322808" -dependencies = [ - "rlp", -] - -[[package]] -name = "impl-serde" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc88fc67028ae3db0c853baa36269d398d5f45b6982f95549ff5def78c935cd" -dependencies = [ - "serde", -] - [[package]] name = "impl-trait-for-tuples" version = "0.2.3" @@ -3128,18 +2745,6 @@ dependencies = [ "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" @@ -3149,26 +2754,12 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "int_to_bytes" -version = "0.2.0" -source = "git+https://github.com/semiotic-ai/lighthouse.git?branch=stable#680cdbfcecb03c651db15e8949bd7367ef39c9ed" -dependencies = [ - "bytes", -] - [[package]] name = "inventory" 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" @@ -3492,23 +3083,6 @@ version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4933f3f57a8e9d9da04db23fb153356ecaf00cbd14aee46279c33dc80925c37" -[[package]] -name = "kzg" -version = "0.1.0" -source = "git+https://github.com/semiotic-ai/lighthouse.git?branch=stable#680cdbfcecb03c651db15e8949bd7367ef39c9ed" -dependencies = [ - "arbitrary", - "c-kzg", - "derivative", - "ethereum_hashing 0.6.0", - "ethereum_serde_utils 0.5.2", - "ethereum_ssz 0.5.4", - "ethereum_ssz_derive 0.5.4", - "hex", - "serde", - "tree_hash 0.6.0", -] - [[package]] name = "lazy_static" version = "1.5.0" @@ -3565,17 +3139,6 @@ dependencies = [ "libc", ] -[[package]] -name = "libsqlite3-sys" -version = "0.25.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29f835d03d717946d28b1d1ed632eb6f0e24a299388ee623d0c23118d3e8a7fa" -dependencies = [ - "cc", - "pkg-config", - "vcpkg", -] - [[package]] name = "libz-sys" version = "1.1.20" @@ -3588,12 +3151,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" @@ -3631,12 +3188,6 @@ dependencies = [ "hashbrown 0.15.2", ] -[[package]] -name = "maplit" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" - [[package]] name = "matchers" version = "0.1.0" @@ -3664,63 +3215,6 @@ version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" -[[package]] -name = "merkle_proof" -version = "0.2.0" -source = "git+https://github.com/semiotic-ai/lighthouse.git?branch=stable#680cdbfcecb03c651db15e8949bd7367ef39c9ed" -dependencies = [ - "ethereum-types", - "ethereum_hashing 0.6.0", - "lazy_static", - "safe_arith", -] - -[[package]] -name = "metastruct" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d74f54f231f9a18d77393ecc5cc7ab96709b2a61ee326c2b2b291009b0cc5a07" -dependencies = [ - "metastruct_macro", -] - -[[package]] -name = "metastruct_macro" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "985e7225f3a4dfbec47a0c6a730a874185fda840d365d7bbd6ba199dd81796d5" -dependencies = [ - "darling 0.13.4", - "itertools 0.10.5", - "proc-macro2", - "quote", - "smallvec", - "syn 1.0.109", -] - -[[package]] -name = "milhouse" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3826d3602a3674b07e080ce1982350e454ec253d73f156bd927ac1b652293f4d" -dependencies = [ - "arbitrary", - "derivative", - "ethereum-types", - "ethereum_hashing 0.6.0", - "ethereum_ssz 0.5.4", - "ethereum_ssz_derive 0.5.4", - "itertools 0.10.5", - "parking_lot 0.12.3", - "rayon", - "serde", - "smallvec", - "tree_hash 0.6.0", - "triomphe", - "typenum", - "vec_map", -] - [[package]] name = "mime" version = "0.3.17" @@ -3789,26 +3283,9 @@ checksum = "defc4c55412d89136f966bbb339008b474350e5e6e78d2714439c386b3137a03" [[package]] name = "nanotemplate" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f247bfe894f8a04e0d8b1eb5eed9dfb7424f6dda47cf83e3f03670e87cb2831b" - -[[package]] -name = "native-tls" -version = "0.2.12" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" -dependencies = [ - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework 2.11.1", - "security-framework-sys", - "tempfile", -] +checksum = "f247bfe894f8a04e0d8b1eb5eed9dfb7424f6dda47cf83e3f03670e87cb2831b" [[package]] name = "nom" @@ -3946,10 +3423,10 @@ checksum = "7ea7162170c6f3cad8f67f4dd7108e3f78349fd553da5b8bebff1e7ef8f38896" dependencies = [ "alloy-consensus", "alloy-eips", - "alloy-primitives 0.8.13", + "alloy-primitives", "alloy-rlp", "alloy-serde", - "derive_more 1.0.0", + "derive_more", "serde", "spin", ] @@ -3963,7 +3440,7 @@ dependencies = [ "alloy-consensus", "alloy-eips", "alloy-network-primitives", - "alloy-primitives 0.8.13", + "alloy-primitives", "alloy-rpc-types-eth", "alloy-serde", "op-alloy-consensus", @@ -3977,50 +3454,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.89", -] - [[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" @@ -4256,8 +3695,6 @@ checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2" dependencies = [ "fixed-hash", "impl-codec", - "impl-rlp", - "impl-serde", "uint", ] @@ -4609,49 +4046,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.2", - "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" @@ -4660,7 +4054,7 @@ dependencies = [ "alloy-consensus", "alloy-eips", "alloy-genesis", - "alloy-primitives 0.8.13", + "alloy-primitives", "alloy-trie", "bytes", "modular-bitfield", @@ -4672,7 +4066,7 @@ name = "reth-codecs-derive" version = "1.1.0" source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.0#1ba631ba9581973e7c6cadeea92cfe1802aceb4a" dependencies = [ - "convert_case 0.6.0", + "convert_case", "proc-macro2", "quote", "syn 2.0.89", @@ -4684,7 +4078,7 @@ version = "1.1.0" source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.0#1ba631ba9581973e7c6cadeea92cfe1802aceb4a" dependencies = [ "alloy-chains", - "alloy-primitives 0.8.13", + "alloy-primitives", "alloy-rlp", "auto_impl", "crc", @@ -4702,13 +4096,13 @@ source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.0#1ba631ba9581973e7c6 dependencies = [ "alloy-consensus", "alloy-eips", - "alloy-primitives 0.8.13", + "alloy-primitives", "alloy-rlp", "alloy-rpc-types", "alloy-serde", "bytes", "c-kzg", - "derive_more 1.0.0", + "derive_more", "k256", "modular-bitfield", "once_cell", @@ -4733,11 +4127,11 @@ dependencies = [ "alloy-consensus", "alloy-eips", "alloy-genesis", - "alloy-primitives 0.8.13", + "alloy-primitives", "alloy-rlp", "byteorder", "bytes", - "derive_more 1.0.0", + "derive_more", "modular-bitfield", "reth-codecs", "revm-primitives", @@ -4750,8 +4144,8 @@ 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.13", - "derive_more 1.0.0", + "alloy-primitives", + "derive_more", "serde", "strum", ] @@ -4763,11 +4157,11 @@ source = "git+https://github.com/paradigmxyz/reth?tag=v1.1.0#1ba631ba9581973e7c6 dependencies = [ "alloy-consensus", "alloy-genesis", - "alloy-primitives 0.8.13", + "alloy-primitives", "alloy-rlp", "alloy-trie", "bytes", - "derive_more 1.0.0", + "derive_more", "itertools 0.13.0", "nybbles", "reth-codecs", @@ -4784,7 +4178,7 @@ checksum = "6f1525851a03aff9a9d6a1d018b414d76252d6802ab54695b27093ecd7e7a101" dependencies = [ "alloy-eip2930", "alloy-eip7702", - "alloy-primitives 0.8.13", + "alloy-primitives", "auto_impl", "bitflags 2.6.0", "bitvec", @@ -4847,15 +4241,6 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "afab94fb28594581f62d981211a9a4d53cc8130bbcbbb89a0440d9b8e81a7746" -[[package]] -name = "rpds" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4ef5140bcb576bfd6d56cd2de709a7d17851ac1f3805e67fe9d99e42a11821f" -dependencies = [ - "archery", -] - [[package]] name = "rs_merkle" version = "1.4.2" @@ -4895,20 +4280,6 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48fd7bd8a6377e15ad9d42a8ec25371b94ddc67abe7c8b9127bec79bebaaae18" -[[package]] -name = "rusqlite" -version = "0.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01e213bc3ecb39ac32e81e51ebe31fd888a940515173e3a18a35f8c6e896422a" -dependencies = [ - "bitflags 1.3.2", - "fallible-iterator", - "fallible-streaming-iterator", - "hashlink", - "libsqlite3-sys", - "smallvec", -] - [[package]] name = "rust-embed" version = "6.8.1" @@ -5120,11 +4491,6 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" -[[package]] -name = "safe_arith" -version = "0.1.0" -source = "git+https://github.com/semiotic-ai/lighthouse.git?branch=stable#680cdbfcecb03c651db15e8949bd7367ef39c9ed" - [[package]] name = "same-file" version = "1.0.6" @@ -5290,31 +4656,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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" -dependencies = [ - "indexmap 2.6.0", - "itoa", - "ryu", - "serde", - "unsafe-libyaml", -] - [[package]] name = "sha1" version = "0.10.6" @@ -5416,12 +4757,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" @@ -5431,31 +4766,15 @@ dependencies = [ "autocfg", ] -[[package]] -name = "slog" -version = "2.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8347046d4ebd943127157b94d63abb990fcf729dc4e9978927fdf4ac3c998d06" -dependencies = [ - "erased-serde 0.3.31", -] - [[package]] name = "smallvec" version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" dependencies = [ - "arbitrary", "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" @@ -5511,24 +4830,6 @@ dependencies = [ "der", ] -[[package]] -name = "ssz_types" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "625b20de2d4b3891e6972f4ce5061cb11bd52b3479270c4b177c134b571194a9" -dependencies = [ - "arbitrary", - "derivative", - "ethereum_serde_utils 0.5.2", - "ethereum_ssz 0.5.4", - "itertools 0.10.5", - "serde", - "serde_derive", - "smallvec", - "tree_hash 0.6.0", - "typenum", -] - [[package]] name = "ssz_types" version = "0.8.0" @@ -5536,13 +4837,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35e0719d2b86ac738a55ae71a8429f52aa2741da988f1fd0975b4cc610fd1e08" dependencies = [ "derivative", - "ethereum_serde_utils 0.7.0", - "ethereum_ssz 0.7.1", + "ethereum_serde_utils", + "ethereum_ssz", "itertools 0.13.0", "serde", "serde_derive", "smallvec", - "tree_hash 0.8.0", + "tree_hash", "typenum", ] @@ -5612,29 +4913,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "superstruct" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf0f31f730ad9e579364950e10d6172b4a9bd04b447edf5988b066a860cc340e" -dependencies = [ - "darling 0.13.4", - "itertools 0.10.5", - "proc-macro2", - "quote", - "smallvec", - "syn 1.0.109", -] - -[[package]] -name = "swap_or_not_shuffle" -version = "0.2.0" -source = "git+https://github.com/semiotic-ai/lighthouse.git?branch=stable#680cdbfcecb03c651db15e8949bd7367ef39c9ed" -dependencies = [ - "ethereum-types", - "ethereum_hashing 0.6.0", -] - [[package]] name = "syn" version = "1.0.109" @@ -5659,9 +4937,9 @@ dependencies = [ [[package]] name = "syn-solidity" -version = "0.8.13" +version = "0.8.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdaa7b9e815582ba343a20c66627437cf45f1c6fba7f69772cbfd1358c7e197" +checksum = "da0523f59468a2696391f2a772edc089342aacd53c3caa2ac3264e598edf119b" dependencies = [ "paste", "proc-macro2", @@ -5680,9 +4958,6 @@ name = "sync_wrapper" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" -dependencies = [ - "futures-core", -] [[package]] name = "synstructure" @@ -5695,27 +4970,6 @@ dependencies = [ "syn 2.0.89", ] -[[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 0.9.4", - "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", -] - [[package]] name = "tap" version = "1.0.1" @@ -5735,15 +4989,6 @@ dependencies = [ "windows-sys 0.59.0", ] -[[package]] -name = "test_random_derive" -version = "0.2.0" -source = "git+https://github.com/semiotic-ai/lighthouse.git?branch=stable#680cdbfcecb03c651db15e8949bd7367ef39c9ed" -dependencies = [ - "quote", - "syn 1.0.109", -] - [[package]] name = "thiserror" version = "1.0.69" @@ -5929,16 +5174,6 @@ dependencies = [ "syn 2.0.89", ] -[[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", -] - [[package]] name = "tokio-rustls" version = "0.26.0" @@ -6162,39 +5397,17 @@ dependencies = [ "tracing-serde", ] -[[package]] -name = "tree_hash" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134d6b24a5b829f30b5ee7de05ba7384557f5f6b00e29409cdf2392f93201bfa" -dependencies = [ - "ethereum-types", - "ethereum_hashing 0.6.0", - "smallvec", -] - [[package]] name = "tree_hash" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "373495c23db675a5192de8b610395e1bec324d596f9e6111192ce903dc11403a" dependencies = [ - "alloy-primitives 0.8.13", - "ethereum_hashing 0.7.0", + "alloy-primitives", + "ethereum_hashing", "smallvec", ] -[[package]] -name = "tree_hash_derive" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce7bccc538359a213436af7bc95804bdbf1c2a21d80e22953cbe9e096837ff1" -dependencies = [ - "darling 0.13.4", - "quote", - "syn 1.0.109", -] - [[package]] name = "tree_hash_derive" version = "0.8.0" @@ -6229,28 +5442,18 @@ dependencies = [ "alloy", "anyhow", "enr", - "ethereum_hashing 0.7.0", - "ethereum_ssz 0.7.1", - "ethereum_ssz_derive 0.7.1", + "ethereum_hashing", + "ethereum_ssz", + "ethereum_ssz_derive", "ethportal-api", "lazy_static", "rust-embed", "serde", "serde_json", - "ssz_types 0.8.0", + "ssz_types", "tokio", - "tree_hash 0.8.0", - "tree_hash_derive 0.8.0", -] - -[[package]] -name = "triomphe" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef8f7726da4807b58ea5c96fdc122f80702030edc33b35aff9190a51148ccc85" -dependencies = [ - "serde", - "stable_deref_trait", + "tree_hash", + "tree_hash_derive", ] [[package]] @@ -6271,63 +5474,13 @@ version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" -[[package]] -name = "types" -version = "0.2.1" -source = "git+https://github.com/semiotic-ai/lighthouse.git?branch=stable#680cdbfcecb03c651db15e8949bd7367ef39c9ed" -dependencies = [ - "alloy-primitives 0.7.7", - "alloy-rlp", - "arbitrary", - "bls", - "compare_fields", - "compare_fields_derive", - "derivative", - "eth2_interop_keypairs", - "ethereum-types", - "ethereum_hashing 0.6.0", - "ethereum_serde_utils 0.5.2", - "ethereum_ssz 0.5.4", - "ethereum_ssz_derive 0.5.4", - "hex", - "int_to_bytes", - "itertools 0.10.5", - "kzg", - "lazy_static", - "log", - "maplit", - "merkle_proof", - "metastruct", - "milhouse", - "parking_lot 0.12.3", - "rand", - "rand_xorshift", - "rayon", - "regex", - "rpds", - "rusqlite", - "safe_arith", - "serde", - "serde_json", - "serde_yaml", - "slog", - "smallvec", - "ssz_types 0.6.0", - "superstruct 0.8.0", - "swap_or_not_shuffle", - "tempfile", - "test_random_derive", - "tree_hash 0.6.0", - "tree_hash_derive 0.6.0", -] - [[package]] name = "typetag" version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52ba3b6e86ffe0054b2c44f2d86407388b933b16cb0a70eea3929420db1d9bbe" dependencies = [ - "erased-serde 0.4.5", + "erased-serde", "inventory", "once_cell", "serde", @@ -6386,7 +5539,6 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" dependencies = [ - "arbitrary", "byteorder", "crunchy", "hex", @@ -6442,12 +5594,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "unsafe-libyaml" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" - [[package]] name = "untrusted" version = "0.9.0" @@ -6552,12 +5698,6 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" -[[package]] -name = "vec_map" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" - [[package]] name = "version_check" version = "0.9.5" @@ -6736,36 +5876,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" diff --git a/Cargo.toml b/Cargo.toml index 4903da96..795bf668 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,54 +8,33 @@ alloy-consensus = "0.4.2" alloy-eip2930 = "0.1.0" alloy-rlp = "0.3.9" base64 = "0.21.7" -beacon-protos = { git = "https://github.com/semiotic-ai/beacon-protos.git", branch = "main" } bincode = "1.3.3" -bls = { git = "https://github.com/semiotic-ai/lighthouse.git", branch = "stable" } clap = { version = "4.4.10", features = ["derive"] } criterion = { version = "0.5.1", features = ["html_reports"] } -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-client = { git = "https://github.com/semiotic-ai/firehose-client.git", branch = "main" } 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" -insta = "1.41.1" log = "0.4.20" -merkle_proof = { git = "https://github.com/semiotic-ai/lighthouse.git", branch = "stable" } -once_cell = "1.20.2" primitive-types = "0.12.2" prost = "0.13.1" prost-build = "0.13.1" -prost-types = "0.13.1" prost-wkt = "0.6.0" prost-wkt-types = "0.6.0" -prost-wkt-build = "0.6.0" rand = "0.8.5" -reqwest = { version = "0.12.8", features = ["json"] } reth-primitives = { git = "https://github.com/paradigmxyz/reth", version = "1.1.0", tag = "v1.1.0" } reth-trie-common = { git = "https://github.com/paradigmxyz/reth", version = "1.1.0", tag = "v1.1.0" } -revm-primitives = "=6.0.0" rlp = "0.5.2" -rustls = { version = "0.23.12", features = ["ring"] } serde = "1.0.208" -serde_derive = "1.0.208" serde_json = "1.0.127" -ssz_types = "0.6" tempfile = "3.0" thiserror = "2.0.0" tokio = "1.39.2" -tokio-stream = "0.1.16" tonic = "0.12.0" tonic-build = "0.12.0" tracing = "0.1.40" tracing-subscriber = "0.3.18" tree_hash = "0.8.0" trin-validation = { git = "https://github.com/ethereum/trin.git", version = "0.1.0", tag = "v0.1.0-alpha.51" } -types = { git = "https://github.com/semiotic-ai/lighthouse.git", branch = "stable" } -url = "2.5" zstd = "0.13.0" [profile.dev.build-override] 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-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/forrestrie-examples/Cargo.toml b/crates/forrestrie-examples/Cargo.toml deleted file mode 100644 index faf71d80..00000000 --- a/crates/forrestrie-examples/Cargo.toml +++ /dev/null @@ -1,35 +0,0 @@ -[package] -name = "forrestrie-examples" -version = "0.1.1" -edition = "2021" - -[dev-dependencies] -beacon-protos.workspace = true -bls.workspace = true -ethportal-api.workspace = true -firehose-client.workspace = true -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 48af6f3c..00000000 --- a/crates/forrestrie-examples/examples/block_roots_only_proof.rs +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright 2024-, Semiotic AI, Inc. -// SPDX-License-Identifier: Apache-2.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 16bde5fa..00000000 --- a/crates/forrestrie-examples/examples/block_roots_proofs.rs +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright 2024-, Semiotic AI, Inc. -// SPDX-License-Identifier: Apache-2.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 3a4cb2f1..00000000 --- a/crates/forrestrie-examples/examples/empty_slot_hashes.rs +++ /dev/null @@ -1,240 +0,0 @@ -// Copyright 2024-, Semiotic AI, Inc. -// SPDX-License-Identifier: Apache-2.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 59067700..00000000 --- a/crates/forrestrie-examples/examples/fetch_and_verify_block.rs +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright 2024-, Semiotic AI, Inc. -// SPDX-License-Identifier: Apache-2.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 beacon_protos::Block as FirehoseBeaconBlock; -use firehose_client::{Chain, FirehoseClient}; -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 b151f727..00000000 --- a/crates/forrestrie-examples/examples/historical_state_roots_proof.rs +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2024-, Semiotic AI, Inc. -// SPDX-License-Identifier: Apache-2.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 3314b998..00000000 --- a/crates/forrestrie-examples/examples/historical_summary_proof.rs +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2024-, Semiotic AI, Inc. -// SPDX-License-Identifier: Apache-2.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 063b8d74..00000000 --- a/crates/forrestrie-examples/examples/match_ethereum_to_beacon.rs +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright 2024-, Semiotic AI, Inc. -// SPDX-License-Identifier: Apache-2.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 beacon_protos::{Block as FirehoseBeaconBlock, Body}; -use firehose_client::{Chain, FirehoseClient}; -use forrestrie::beacon_state::ETHEREUM_BEACON_DENEB_OFFSET; -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(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(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 e8c7181e..00000000 --- a/crates/forrestrie-examples/examples/receipts_proof.rs +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright 2024-, Semiotic AI, Inc. -// SPDX-License-Identifier: Apache-2.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 0a87c88b..00000000 --- a/crates/forrestrie-examples/examples/single_block_post_merge_pre_capella_proof.rs +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2024-, Semiotic AI, Inc. -// SPDX-License-Identifier: Apache-2.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 cbebc77d..00000000 --- a/crates/forrestrie-examples/examples/single_execution_block.rs +++ /dev/null @@ -1,203 +0,0 @@ -// Copyright 2024-, Semiotic AI, Inc. -// SPDX-License-Identifier: Apache-2.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 beacon_protos::{Block, BlockRoot, Body}; -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, - }, -}; -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 = 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(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_blocks::((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 92f29020..00000000 --- a/crates/forrestrie-examples/examples/verify-era.rs +++ /dev/null @@ -1,185 +0,0 @@ -// Copyright 2024-, Semiotic AI, Inc. -// SPDX-License-Identifier: Apache-2.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 beacon_protos::Block; -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, -}; -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_blocks::((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_protos::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 a2ae87fd..00000000 --- a/crates/forrestrie-examples/examples/verify_block_inclusion_proof.rs +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright 2024-, Semiotic AI, Inc. -// SPDX-License-Identifier: Apache-2.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 beacon_protos::Block as FirehoseBeaconBlock; -use firehose_client::{Chain, FirehoseClient}; -use forrestrie::beacon_block::{ - HistoricalDataProofs, BEACON_BLOCK_BODY_PROOF_DEPTH, EXECUTION_PAYLOAD_FIELD_INDEX, -}; -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 3f733a7e..00000000 --- a/crates/forrestrie-examples/src/lib.rs +++ /dev/null @@ -1,2 +0,0 @@ -// Copyright 2024-, Semiotic AI, Inc. -// SPDX-License-Identifier: Apache-2.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 578dde6f..00000000 --- a/crates/forrestrie/Cargo.toml +++ /dev/null @@ -1,25 +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 -merkle_proof.workspace = true -primitive-types.workspace = true -reth-trie-common.workspace = true -reth-primitives.workspace = true -serde = { workspace = true, features = ["derive"] } -ssz_types.workspace = true -tree_hash = "0.6.0" -types.workspace = true - -[dev-dependencies] -rand.workspace = true -fake.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/src/beacon_block.rs b/crates/forrestrie/src/beacon_block.rs deleted file mode 100644 index b4ef04e3..00000000 --- a/crates/forrestrie/src/beacon_block.rs +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright 2024-, Semiotic AI, Inc. -// SPDX-License-Identifier: Apache-2.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 49342c1b..00000000 --- a/crates/forrestrie/src/beacon_state.rs +++ /dev/null @@ -1,226 +0,0 @@ -// Copyright 2024-, Semiotic AI, Inc. -// SPDX-License-Identifier: Apache-2.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/execution_layer.rs b/crates/forrestrie/src/execution_layer.rs deleted file mode 100644 index 245c8a27..00000000 --- a/crates/forrestrie/src/execution_layer.rs +++ /dev/null @@ -1,326 +0,0 @@ -// Copyright 2024-, Semiotic AI, Inc. -// SPDX-License-Identifier: Apache-2.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 19785755..00000000 --- a/crates/forrestrie/src/lib.rs +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright 2024-, Semiotic AI, Inc. -// SPDX-License-Identifier: Apache-2.0 - -pub mod beacon_block; -pub mod beacon_state; -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": {}