From 3169e90ac7e87f1b02e26e87bf3fa3df11fd6521 Mon Sep 17 00:00:00 2001 From: Joseph Livesey Date: Wed, 16 Oct 2024 15:21:47 -0400 Subject: [PATCH] fix ci: miscellaneous chores and fixes (#3) * build(header-accumulator): fix workspace crate dev-dependency import * build: install protoc in CI tests * fix(header-accumulator): fix cargo fmt * chore(flat-files-decoder): fix clippy::doc-lazy-continuation warning * chore(firehose-client): fix clippy::unnecessary_to_owned warning * chore(flat-files-decoder): fix clippy::filter_next warning * chore(sf-protos): fix code snippet in doc comment * chore(header-accumulator): fix clippy::bool_assert_comparison * chore(firehose-client): add streaming support for beacon and ethereum * build(forrestrie): add firehose-client as dependency * build(forrestrie): add reqwest as dependency * chore(forrestrie): make historical roots index public * chore(forrestrie): add fetch and verify block example * chore(forrestrie): add verify block inclusion proof example * chore(forrestrie): add historical state roots proof example * chore(forrestrie): add historical summary proof example * chore(forrestrie): add block roots proof example * chore(forrestrie): add block roots only proof example * chore(forrestrie): add empty slot hashes example * chore(firehose-client): add fetch ethereum block example * chore(firehose-client): add stream ethereum blocks example * chore(firehose-client): add stream beacon blocks example * chore(forehose-client): add fetch beacon block example * docs: add note on examples to README * build(workspace): use workspace dependency imports for legibility * ci(tests): remove coverage requirements for now --- .github/workflows/tests.yml | 26 +- Cargo.lock | 725 +++++++++--------- Cargo.toml | 43 +- README.md | 36 +- crates/flat-files-decoder/Cargo.toml | 43 +- crates/flat-files-decoder/src/lib.rs | 2 +- .../src/transactions/mod.rs | 6 +- crates/flat-head/Cargo.toml | 32 +- crates/forrestrie/Cargo.toml | 8 +- .../examples/block_roots_only_proof.rs | 88 +++ .../forrestrie/examples/block_roots_proofs.rs | 87 +++ .../forrestrie/examples/empty_slot_hashes.rs | 237 ++++++ .../examples/fetch_and_verify_block.rs | 59 ++ .../examples/historical_state_roots_proof.rs | 42 + .../examples/historical_summary_proof.rs | 45 ++ .../examples/verify_block_inclusion_proof.rs | 71 ++ crates/forrestrie/src/beacon_block.rs | 73 -- crates/forrestrie/src/beacon_state.rs | 437 +---------- crates/header-accumulator/Cargo.toml | 26 +- crates/header-accumulator/src/errors.rs | 2 +- crates/header-accumulator/src/sync.rs | 19 +- crates/sf-protos/Cargo.toml | 23 +- crates/sf-protos/protos/block.proto | 12 +- 23 files changed, 1170 insertions(+), 972 deletions(-) create mode 100644 crates/forrestrie/examples/block_roots_only_proof.rs create mode 100644 crates/forrestrie/examples/block_roots_proofs.rs create mode 100644 crates/forrestrie/examples/empty_slot_hashes.rs create mode 100644 crates/forrestrie/examples/fetch_and_verify_block.rs create mode 100644 crates/forrestrie/examples/historical_state_roots_proof.rs create mode 100644 crates/forrestrie/examples/historical_summary_proof.rs create mode 100644 crates/forrestrie/examples/verify_block_inclusion_proof.rs diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index de178ce1..4a6b20dc 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -36,13 +36,15 @@ jobs: - name: Run sccache-cache uses: mozilla-actions/sccache-action@89e9040de88b577a072e3760aaf59f585da083af #v0.0.5 if: ${{ !startsWith(github.head_ref, 'renovate/') }} + - name: Install Protoc + uses: arduino/setup-protoc@v3 - run: | rustup component add clippy # Temporarily allowing dead-code, while denying all other warnings cargo clippy --all-features --all-targets -- -A dead-code -D warnings - test-and-coverage: - name: cargo test and coverage + test: + name: cargo test runs-on: ubuntu-latest permissions: contents: write @@ -63,14 +65,10 @@ jobs: - name: Run sccache-cache uses: mozilla-actions/sccache-action@89e9040de88b577a072e3760aaf59f585da083af #v0.0.5 if: ${{ !startsWith(github.head_ref, 'renovate/') }} - - name: Install cargo-llvm-cov - uses: taiki-e/install-action@cargo-llvm-cov - - name: Run tests and generate coverage report - run: cargo llvm-cov test --all-features --workspace --lcov --output-path lcov.info - - name: Upload coverage to Coveralls - uses: coverallsapp/github-action@643bc377ffa44ace6394b2b5d0d3950076de9f63 # v2.3.0 - with: - file: ./lcov.info + - name: Install Protoc + uses: arduino/setup-protoc@v3 + - name: Run tests + run: cargo test --all-features --workspace # Cannot do with llvm-cov, see https://github.com/taiki-e/cargo-llvm-cov/issues/2 test-docs: @@ -95,6 +93,8 @@ jobs: - name: Run sccache-cache uses: mozilla-actions/sccache-action@89e9040de88b577a072e3760aaf59f585da083af #v0.0.5 if: ${{ !startsWith(github.head_ref, 'renovate/') }} + - name: Install Protoc + uses: arduino/setup-protoc@v3 - name: Test documentation code snippets run: cargo test --doc --all-features --workspace @@ -116,11 +116,13 @@ jobs: - name: Run sccache-cache uses: mozilla-actions/sccache-action@89e9040de88b577a072e3760aaf59f585da083af #v0.0.5 if: ${{ !startsWith(github.head_ref, 'renovate/') }} + - name: Install Protoc + uses: arduino/setup-protoc@v3 - name: Cargo check run: cargo check audit: - name: Cargo Audit + name: cargo audit runs-on: ubuntu-latest permissions: actions: read @@ -141,6 +143,8 @@ jobs: - name: Run sccache-cache uses: mozilla-actions/sccache-action@89e9040de88b577a072e3760aaf59f585da083af #v0.0.5 if: ${{ !startsWith(github.head_ref, 'renovate/') }} + - name: Install Protoc + uses: arduino/setup-protoc@v3 - name: Install Cargo Audit run: | cargo install cargo-audit diff --git a/Cargo.lock b/Cargo.lock index cc5297ff..8a18ce76 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -82,10 +82,11 @@ checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" [[package]] name = "alloy-chains" -version = "0.1.36" +version = "0.1.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94c225801d42099570d0674701dddd4142f0ef715282aeb5985042e2ec962df7" +checksum = "156bfc5dcd52ef9a5f33381701fa03310317e14c65093a9430d3e3557b08dcd3" dependencies = [ + "alloy-primitives 0.8.8", "num_enum", "serde", "strum", @@ -97,7 +98,7 @@ version = "0.1.0" source = "git+https://github.com/alloy-rs/alloy?rev=8c9dd0a#8c9dd0ae0a0f12eb81b5afe75a9b55ea4ad3abf4" dependencies = [ "alloy-eips 0.1.0", - "alloy-primitives", + "alloy-primitives 0.7.7", "alloy-rlp", "alloy-serde 0.1.0", "serde", @@ -111,7 +112,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da374e868f54c7f4ad2ad56829827badca388efd645f8cf5fccc61c2b5343504" dependencies = [ "alloy-eips 0.1.4", - "alloy-primitives", + "alloy-primitives 0.7.7", "alloy-rlp", "alloy-serde 0.1.4", "c-kzg", @@ -123,7 +124,7 @@ name = "alloy-eips" version = "0.1.0" source = "git+https://github.com/alloy-rs/alloy?rev=8c9dd0a#8c9dd0ae0a0f12eb81b5afe75a9b55ea4ad3abf4" dependencies = [ - "alloy-primitives", + "alloy-primitives 0.7.7", "alloy-rlp", "alloy-serde 0.1.0", "c-kzg", @@ -137,11 +138,11 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f76ecab54890cdea1e4808fc0891c7e6cfcf71fe1a9fe26810c7280ef768f4ed" dependencies = [ - "alloy-primitives", + "alloy-primitives 0.7.7", "alloy-rlp", "alloy-serde 0.1.4", "c-kzg", - "derive_more", + "derive_more 0.99.18", "once_cell", "serde", "sha2 0.10.8", @@ -152,7 +153,7 @@ name = "alloy-genesis" version = "0.1.0" source = "git+https://github.com/alloy-rs/alloy?rev=8c9dd0a#8c9dd0ae0a0f12eb81b5afe75a9b55ea4ad3abf4" dependencies = [ - "alloy-primitives", + "alloy-primitives 0.7.7", "alloy-serde 0.1.0", "serde", ] @@ -163,7 +164,7 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bca15afde1b6d15e3fc1c97421262b1bbb37aee45752e3c8b6d6f13f776554ff" dependencies = [ - "alloy-primitives", + "alloy-primitives 0.7.7", "alloy-serde 0.1.4", "serde", ] @@ -178,7 +179,7 @@ dependencies = [ "bytes", "cfg-if", "const-hex", - "derive_more", + "derive_more 0.99.18", "ethereum_ssz", "getrandom", "hex-literal", @@ -192,6 +193,33 @@ dependencies = [ "tiny-keccak", ] +[[package]] +name = "alloy-primitives" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38f35429a652765189c1c5092870d8360ee7b7769b09b06d89ebaefd34676446" +dependencies = [ + "alloy-rlp", + "bytes", + "cfg-if", + "const-hex", + "derive_more 1.0.0", + "foldhash", + "hex-literal", + "indexmap 2.6.0", + "itoa", + "k256", + "keccak-asm", + "paste", + "proptest", + "rand", + "ruint", + "rustc-hash 2.0.0", + "serde", + "sha3 0.10.8", + "tiny-keccak", +] + [[package]] name = "alloy-rlp" version = "0.3.8" @@ -222,7 +250,7 @@ dependencies = [ "alloy-consensus 0.1.0", "alloy-eips 0.1.0", "alloy-genesis 0.1.0", - "alloy-primitives", + "alloy-primitives 0.7.7", "alloy-rlp", "alloy-serde 0.1.0", "alloy-sol-types", @@ -249,7 +277,7 @@ version = "0.1.0" source = "git+https://github.com/alloy-rs/alloy?rev=8c9dd0a#8c9dd0ae0a0f12eb81b5afe75a9b55ea4ad3abf4" dependencies = [ "alloy-consensus 0.1.0", - "alloy-primitives", + "alloy-primitives 0.7.7", "alloy-rlp", "alloy-rpc-types 0.1.0", "alloy-serde 0.1.0", @@ -266,7 +294,7 @@ checksum = "ab4123ee21f99ba4bd31bfa36ba89112a18a500f8b452f02b35708b1b951e2b9" dependencies = [ "alloy-consensus 0.1.4", "alloy-eips 0.1.4", - "alloy-primitives", + "alloy-primitives 0.7.7", "alloy-rlp", "alloy-serde 0.1.4", "alloy-sol-types", @@ -281,7 +309,7 @@ name = "alloy-rpc-types-trace" version = "0.1.0" source = "git+https://github.com/alloy-rs/alloy?rev=8c9dd0a#8c9dd0ae0a0f12eb81b5afe75a9b55ea4ad3abf4" dependencies = [ - "alloy-primitives", + "alloy-primitives 0.7.7", "alloy-rpc-types 0.1.0", "alloy-serde 0.1.0", "serde", @@ -293,7 +321,7 @@ name = "alloy-serde" version = "0.1.0" source = "git+https://github.com/alloy-rs/alloy?rev=8c9dd0a#8c9dd0ae0a0f12eb81b5afe75a9b55ea4ad3abf4" dependencies = [ - "alloy-primitives", + "alloy-primitives 0.7.7", "serde", "serde_json", ] @@ -304,7 +332,7 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9416c52959e66ead795a11f4a86c248410e9e368a0765710e57055b8a1774dd6" dependencies = [ - "alloy-primitives", + "alloy-primitives 0.7.7", "serde", "serde_json", ] @@ -362,7 +390,7 @@ version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a91ca40fa20793ae9c3841b83e74569d1cc9af29a2f5237314fd3452d51e38c7" dependencies = [ - "alloy-primitives", + "alloy-primitives 0.7.7", "alloy-sol-macro", "const-hex", ] @@ -373,9 +401,9 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "03704f265cbbb943b117ecb5055fd46e8f41e7dc8a58b1aed20bcd40ace38c15" dependencies = [ - "alloy-primitives", + "alloy-primitives 0.7.7", "alloy-rlp", - "derive_more", + "derive_more 0.99.18", "hashbrown 0.14.5", "nybbles", "serde", @@ -950,24 +978,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "bls" -version = "0.2.0" -source = "git+https://github.com/sigp/lighthouse.git?branch=stable#2e0eb6d1b8705bbda2ba56eb195d9cc7c6575e95" -dependencies = [ - "arbitrary", - "blst", - "ethereum-types", - "ethereum_hashing", - "ethereum_serde_utils", - "ethereum_ssz", - "hex", - "rand", - "serde", - "tree_hash 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "zeroize", -] - [[package]] name = "blst" version = "0.3.13" @@ -994,9 +1004,9 @@ checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" [[package]] name = "bytemuck" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94bbb0ad554ad961ddc5da507a12a29b14e4ae5bda06b19f575a3e6079d2e2ae" +checksum = "8334215b81e418a0a7bdb8ef0849474f40bb10c8b71f1c4ed315cff49f32494d" [[package]] name = "byteorder" @@ -1036,9 +1046,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.1.28" +version = "1.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e80e3b6a3ab07840e1cae9b0666a63970dc28e8ed5ffbcdacbfc760c281bfc1" +checksum = "b16803a61b81d9eabb7eae2588776c4c1e584b738ede45fdbb4c972cec1e9945" dependencies = [ "jobserver", "libc", @@ -1183,14 +1193,6 @@ dependencies = [ "itertools 0.10.5", ] -[[package]] -name = "compare_fields" -version = "0.2.0" -source = "git+https://github.com/sigp/lighthouse.git?branch=stable#2e0eb6d1b8705bbda2ba56eb195d9cc7c6575e95" -dependencies = [ - "itertools 0.10.5", -] - [[package]] name = "compare_fields_derive" version = "0.2.0" @@ -1200,15 +1202,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "compare_fields_derive" -version = "0.2.0" -source = "git+https://github.com/sigp/lighthouse.git?branch=stable#2e0eb6d1b8705bbda2ba56eb195d9cc7c6575e95" -dependencies = [ - "quote", - "syn 1.0.109", -] - [[package]] name = "console" version = "0.15.8" @@ -1548,14 +1541,13 @@ dependencies = [ name = "decoder" version = "0.1.1" dependencies = [ - "alloy-primitives", + "alloy-primitives 0.7.7", "alloy-rlp", "bincode", "clap", "criterion", "prost", "prost-build", - "prost-types", "prost-wkt-build", "rand", "rayon", @@ -1564,7 +1556,7 @@ dependencies = [ "revm-primitives", "serde", "serde_json", - "sf-protos 0.1.0", + "sf-protos", "simple-log", "thiserror", "tokio", @@ -1572,33 +1564,6 @@ dependencies = [ "zstd", ] -[[package]] -name = "decoder" -version = "0.1.1" -source = "git+https://github.com/semiotic-ai/flat-files-decoder.git?branch=main#42c5b1009705ec6bd6458726fce035f66873b268" -dependencies = [ - "alloy-primitives", - "alloy-rlp", - "bincode", - "clap", - "prost", - "prost-build", - "prost-types", - "prost-wkt-build", - "rand", - "rayon", - "reth-primitives", - "reth-trie-common", - "revm-primitives", - "serde", - "serde_json", - "sf-protos 0.1.0 (git+https://github.com/semiotic-ai/sf-protos.git?branch=main)", - "simple-log", - "thiserror", - "tokio", - "zstd", -] - [[package]] name = "delay_map" version = "0.3.0" @@ -1664,6 +1629,27 @@ dependencies = [ "syn 2.0.79", ] +[[package]] +name = "derive_more" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05" +dependencies = [ + "derive_more-impl", +] + +[[package]] +name = "derive_more-impl" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.79", + "unicode-xid", +] + [[package]] name = "digest" version = "0.9.0" @@ -1875,19 +1861,6 @@ dependencies = [ "regex", ] -[[package]] -name = "env_logger" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580" -dependencies = [ - "humantime", - "is-terminal", - "log", - "regex", - "termcolor", -] - [[package]] name = "env_logger" version = "0.11.5" @@ -1953,21 +1926,7 @@ name = "eth2_interop_keypairs" version = "0.2.0" source = "git+https://github.com/semiotic-ai/lighthouse.git?branch=stable#680cdbfcecb03c651db15e8949bd7367ef39c9ed" dependencies = [ - "bls 0.2.0 (git+https://github.com/semiotic-ai/lighthouse.git?branch=stable)", - "ethereum_hashing", - "hex", - "lazy_static", - "num-bigint", - "serde", - "serde_yaml", -] - -[[package]] -name = "eth2_interop_keypairs" -version = "0.2.0" -source = "git+https://github.com/sigp/lighthouse.git?branch=stable#2e0eb6d1b8705bbda2ba56eb195d9cc7c6575e95" -dependencies = [ - "bls 0.2.0 (git+https://github.com/sigp/lighthouse.git?branch=stable)", + "bls", "ethereum_hashing", "hex", "lazy_static", @@ -1981,7 +1940,7 @@ name = "eth_trie" version = "0.4.0" source = "git+https://github.com/kolbyml/eth-trie.rs.git?rev=11ec003e3276e1413f06328ab746af5d99f112bb#11ec003e3276e1413f06328ab746af5d99f112bb" dependencies = [ - "alloy-primitives", + "alloy-primitives 0.7.7", "alloy-rlp", "hashbrown 0.14.5", "keccak-hash", @@ -2075,7 +2034,7 @@ name = "ethportal-api" version = "0.2.2" source = "git+https://github.com/ethereum/trin.git?tag=v0.1.0-alpha.35#31ea2a21df5dcefcd779ea32c72e016a34555fed" dependencies = [ - "alloy-primitives", + "alloy-primitives 0.7.7", "alloy-rlp", "anyhow", "base64 0.13.1", @@ -2178,16 +2137,18 @@ name = "firehose-client" version = "0.1.0" dependencies = [ "dotenvy", + "futures", "hex", "http 1.1.0", "insta", "once_cell", - "rustls 0.23.14", + "rustls 0.23.15", "serde", "serde_derive", - "sf-protos 0.1.0", + "sf-protos", "thiserror", "tokio", + "tokio-stream", "tonic", ] @@ -2218,17 +2179,17 @@ dependencies = [ "bincode", "bytes", "clap", - "decoder 0.1.1", + "decoder", "dotenv", "env_logger 0.11.5", "futures", "header_accumulator", "log", "object_store", - "sf-protos 0.1.0", + "sf-protos", "thiserror", "tokio", - "tree_hash 0.6.0 (git+https://github.com/KolbyML/tree_hash.git?rev=8aaf8bb4184148768d48e2cfbbdd0b95d1da8730)", + "tree_hash 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "trin-validation", "url", "zstd", @@ -2256,6 +2217,21 @@ 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" @@ -2269,15 +2245,17 @@ dependencies = [ name = "forrestrie" version = "0.1.0" dependencies = [ + "firehose-client", "insta", - "merkle_proof 0.2.0 (git+https://github.com/semiotic-ai/lighthouse.git?branch=stable)", + "merkle_proof", "primitive-types", + "reqwest 0.12.8", "serde", "serde_json", - "sf-protos 0.1.0", + "sf-protos", "tokio", "tree_hash 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "types 0.2.1 (git+https://github.com/semiotic-ai/lighthouse.git?branch=stable)", + "types", ] [[package]] @@ -2594,11 +2572,11 @@ dependencies = [ name = "header_accumulator" version = "0.1.0" dependencies = [ - "alloy-primitives", + "alloy-primitives 0.7.7", "base64 0.21.7", "clap", - "decoder 0.1.1 (git+https://github.com/semiotic-ai/flat-files-decoder.git?branch=main)", - "env_logger 0.10.2", + "decoder", + "env_logger 0.11.5", "ethereum-types", "ethportal-api", "log", @@ -2606,7 +2584,7 @@ dependencies = [ "rlp", "serde", "serde_json", - "sf-protos 0.1.0", + "sf-protos", "tempfile", "tree_hash 0.6.0 (git+https://github.com/KolbyML/tree_hash.git?rev=8aaf8bb4184148768d48e2cfbbdd0b95d1da8730)", "trin-validation", @@ -2763,9 +2741,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.30" +version = "0.14.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" +checksum = "8c08302e8fa335b151b788c775ff56e7a03ae64ff85c548ee820fecb70356e85" dependencies = [ "bytes", "futures-channel", @@ -2787,9 +2765,9 @@ dependencies = [ [[package]] name = "hyper" -version = "1.4.1" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" +checksum = "bbbff0a806a4728c99295b254c8838933b5b082d75e3cb70c8dab21fdfbcfa9a" dependencies = [ "bytes", "futures-channel", @@ -2814,7 +2792,7 @@ checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" dependencies = [ "futures-util", "http 0.2.12", - "hyper 0.14.30", + "hyper 0.14.31", "log", "rustls 0.21.12", "rustls-native-certs 0.6.3", @@ -2822,19 +2800,52 @@ dependencies = [ "tokio-rustls 0.24.1", ] +[[package]] +name = "hyper-rustls" +version = "0.27.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" +dependencies = [ + "futures-util", + "http 1.1.0", + "hyper 1.5.0", + "hyper-util", + "rustls 0.23.15", + "rustls-pki-types", + "tokio", + "tokio-rustls 0.26.0", + "tower-service", +] + [[package]] name = "hyper-timeout" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3203a961e5c83b6f5498933e78b6b263e208c197b63e9c6c53cc82ffd3f63793" dependencies = [ - "hyper 1.4.1", + "hyper 1.5.0", "hyper-util", "pin-project-lite", "tokio", "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 1.5.0", + "hyper-util", + "native-tls", + "tokio", + "tokio-native-tls", + "tower-service", +] + [[package]] name = "hyper-util" version = "0.1.9" @@ -2846,7 +2857,7 @@ dependencies = [ "futures-util", "http 1.1.0", "http-body 1.0.1", - "hyper 1.4.1", + "hyper 1.5.0", "pin-project-lite", "socket2 0.5.7", "tokio", @@ -2999,14 +3010,6 @@ dependencies = [ "bytes", ] -[[package]] -name = "int_to_bytes" -version = "0.2.0" -source = "git+https://github.com/sigp/lighthouse.git?branch=stable#2e0eb6d1b8705bbda2ba56eb195d9cc7c6575e95" -dependencies = [ - "bytes", -] - [[package]] name = "inventory" version = "0.3.15" @@ -3086,9 +3089,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.71" +version = "0.3.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cb94a0ffd3f3ee755c20f7d8752f45cac88605a4dcf808abcff72873296ec7b" +checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" dependencies = [ "wasm-bindgen", ] @@ -3146,7 +3149,7 @@ dependencies = [ "beef", "futures-timer", "futures-util", - "hyper 0.14.30", + "hyper 0.14.31", "jsonrpsee-types", "parking_lot 0.12.3", "rand", @@ -3167,8 +3170,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c7b9f95208927653e7965a98525e7fc641781cab89f0e27c43fa2974405683" dependencies = [ "async-trait", - "hyper 0.14.30", - "hyper-rustls", + "hyper 0.14.31", + "hyper-rustls 0.24.2", "jsonrpsee-core", "jsonrpsee-types", "serde", @@ -3201,7 +3204,7 @@ checksum = "a482bc4e25eebd0adb61a3468c722763c381225bd3ec46e926f709df8a8eb548" dependencies = [ "futures-util", "http 0.2.12", - "hyper 0.14.30", + "hyper 0.14.31", "jsonrpsee-core", "jsonrpsee-types", "route-recognizer", @@ -3329,23 +3332,6 @@ dependencies = [ "tree_hash 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "kzg" -version = "0.1.0" -source = "git+https://github.com/sigp/lighthouse.git?branch=stable#2e0eb6d1b8705bbda2ba56eb195d9cc7c6575e95" -dependencies = [ - "arbitrary", - "c-kzg", - "derivative", - "ethereum_hashing", - "ethereum_serde_utils", - "ethereum_ssz", - "ethereum_ssz_derive", - "hex", - "serde", - "tree_hash 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "lazy_static" version = "1.5.0" @@ -3540,18 +3526,7 @@ dependencies = [ "ethereum-types", "ethereum_hashing", "lazy_static", - "safe_arith 0.1.0 (git+https://github.com/semiotic-ai/lighthouse.git?branch=stable)", -] - -[[package]] -name = "merkle_proof" -version = "0.2.0" -source = "git+https://github.com/sigp/lighthouse.git?branch=stable#2e0eb6d1b8705bbda2ba56eb195d9cc7c6575e95" -dependencies = [ - "ethereum-types", - "ethereum_hashing", - "lazy_static", - "safe_arith 0.1.0 (git+https://github.com/sigp/lighthouse.git?branch=stable)", + "safe_arith", ] [[package]] @@ -3678,6 +3653,23 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f247bfe894f8a04e0d8b1eb5eed9dfb7424f6dda47cf83e3f03670e87cb2831b" +[[package]] +name = "native-tls" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" +dependencies = [ + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + [[package]] name = "nom" version = "7.1.3" @@ -3806,14 +3798,14 @@ dependencies = [ "chrono", "futures", "humantime", - "hyper 0.14.30", + "hyper 0.14.31", "itertools 0.12.1", "md-5", "parking_lot 0.12.3", "percent-encoding", "quick-xml", "rand", - "reqwest", + "reqwest 0.11.27", "ring 0.17.8", "rustls-pemfile 2.2.0", "serde", @@ -3843,12 +3835,50 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" +[[package]] +name = "openssl" +version = "0.10.67" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b8cefcf97f41316955f9294cd61f639bdcfa9f2f230faac6cb896aa8ab64704" +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.79", +] + [[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 = "ordered-float" version = "2.10.1" @@ -3952,9 +3982,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.13" +version = "2.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdbef9d1d47087a895abd220ed25eb4ad973a5e26f6a4367b038c25e28dfc2d9" +checksum = "879952a81a83930934cbf1786752d6dedc3b1f29e8f8fb2ad1d0a36f377cf442" dependencies = [ "memchr", "thiserror", @@ -4142,9 +4172,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.87" +version = "1.0.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a" +checksum = "7c3a7fc5db1e57d5a779a352c8cdb57b29aa4c40cc69c3a68a7fedc815fbf2f9" dependencies = [ "unicode-ident", ] @@ -4445,8 +4475,8 @@ dependencies = [ "h2 0.3.26", "http 0.2.12", "http-body 0.4.6", - "hyper 0.14.30", - "hyper-rustls", + "hyper 0.14.31", + "hyper-rustls 0.24.2", "ipnet", "js-sys", "log", @@ -4461,7 +4491,7 @@ dependencies = [ "serde_json", "serde_urlencoded", "sync_wrapper 0.1.2", - "system-configuration", + "system-configuration 0.5.1", "tokio", "tokio-rustls 0.24.1", "tokio-util", @@ -4474,6 +4504,49 @@ dependencies = [ "winreg", ] +[[package]] +name = "reqwest" +version = "0.12.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f713147fbe92361e52392c73b8c9e48c04c6625bce969ef54dc901e58e042a7b" +dependencies = [ + "base64 0.22.1", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2 0.4.6", + "http 1.1.0", + "http-body 1.0.1", + "http-body-util", + "hyper 1.5.0", + "hyper-rustls 0.27.3", + "hyper-tls", + "hyper-util", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls-pemfile 2.2.0", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper 1.0.1", + "system-configuration 0.6.1", + "tokio", + "tokio-native-tls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "windows-registry", +] + [[package]] name = "reth-codecs" version = "1.0.1" @@ -4482,7 +4555,7 @@ dependencies = [ "alloy-consensus 0.1.4", "alloy-eips 0.1.4", "alloy-genesis 0.1.4", - "alloy-primitives", + "alloy-primitives 0.7.7", "bytes", "modular-bitfield", "reth-codecs-derive", @@ -4506,7 +4579,7 @@ version = "1.0.1" source = "git+https://github.com/paradigmxyz/reth?tag=v1.0.1#d599393771f9d7d137ea4abf271e1bd118184c73" dependencies = [ "alloy-chains", - "alloy-primitives", + "alloy-primitives 0.7.7", "alloy-rlp", "auto_impl", "crc", @@ -4524,12 +4597,12 @@ source = "git+https://github.com/paradigmxyz/reth?tag=v1.0.1#d599393771f9d7d137e dependencies = [ "alloy-eips 0.1.4", "alloy-genesis 0.1.4", - "alloy-primitives", + "alloy-primitives 0.7.7", "alloy-rlp", "alloy-rpc-types 0.1.4", "bytes", "c-kzg", - "derive_more", + "derive_more 0.99.18", "modular-bitfield", "once_cell", "rayon", @@ -4554,12 +4627,12 @@ dependencies = [ "alloy-consensus 0.1.4", "alloy-eips 0.1.4", "alloy-genesis 0.1.4", - "alloy-primitives", + "alloy-primitives 0.7.7", "alloy-rlp", "alloy-rpc-types-eth", "byteorder", "bytes", - "derive_more", + "derive_more 0.99.18", "modular-bitfield", "reth-codecs", "revm-primitives", @@ -4574,7 +4647,7 @@ version = "0.2.0-beta.5" source = "git+https://github.com/paradigmxyz/reth.git?rev=8d1d13ef89cf19459adc37ba0c45e7aac6270dc1#8d1d13ef89cf19459adc37ba0c45e7aac6270dc1" dependencies = [ "alloy-genesis 0.1.0", - "alloy-primitives", + "alloy-primitives 0.7.7", "alloy-rlp", "alloy-rpc-types 0.1.0", "alloy-rpc-types-engine", @@ -4594,8 +4667,8 @@ name = "reth-static-file-types" version = "1.0.1" source = "git+https://github.com/paradigmxyz/reth?tag=v1.0.1#d599393771f9d7d137ea4abf271e1bd118184c73" dependencies = [ - "alloy-primitives", - "derive_more", + "alloy-primitives 0.7.7", + "derive_more 0.99.18", "serde", "strum", ] @@ -4607,11 +4680,11 @@ source = "git+https://github.com/paradigmxyz/reth?tag=v1.0.1#d599393771f9d7d137e dependencies = [ "alloy-consensus 0.1.4", "alloy-genesis 0.1.4", - "alloy-primitives", + "alloy-primitives 0.7.7", "alloy-rlp", "alloy-trie", "bytes", - "derive_more", + "derive_more 0.99.18", "itertools 0.13.0", "nybbles", "reth-codecs", @@ -4627,13 +4700,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b518f536bacee396eb28a43f0984b25b2cd80f052ba4f2e794d554d711c13f33" dependencies = [ "alloy-eips 0.1.4", - "alloy-primitives", + "alloy-primitives 0.7.7", "auto_impl", "bitflags 2.6.0", "bitvec", "c-kzg", "cfg-if", - "derive_more", + "derive_more 0.99.18", "dyn-clone", "enumn", "hashbrown 0.14.5", @@ -4874,9 +4947,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.14" +version = "0.23.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "415d9944693cb90382053259f89fbb077ea730ad7273047ec63b19bc9b160ba8" +checksum = "5fbb44d7acc4e873d613422379f69f237a1b141928c02f6bc6ccfddddc2d7993" dependencies = [ "aws-lc-rs", "log", @@ -4933,9 +5006,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e696e35370c65c9c541198af4543ccd580cf17fc25d8e05c5a242b202488c55" +checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b" [[package]] name = "rustls-webpki" @@ -4961,9 +5034,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" +checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" [[package]] name = "rusty-fork" @@ -4988,11 +5061,6 @@ name = "safe_arith" version = "0.1.0" source = "git+https://github.com/semiotic-ai/lighthouse.git?branch=stable#680cdbfcecb03c651db15e8949bd7367ef39c9ed" -[[package]] -name = "safe_arith" -version = "0.1.0" -source = "git+https://github.com/sigp/lighthouse.git?branch=stable#2e0eb6d1b8705bbda2ba56eb195d9cc7c6575e95" - [[package]] name = "same-file" version = "1.0.6" @@ -5241,8 +5309,8 @@ dependencies = [ name = "sf-protos" version = "0.1.0" dependencies = [ - "alloy-primitives", - "bls 0.2.0 (git+https://github.com/semiotic-ai/lighthouse.git?branch=stable)", + "alloy-primitives 0.7.7", + "bls", "ethportal-api", "hex", "primitive-types", @@ -5257,29 +5325,7 @@ dependencies = [ "thiserror", "tonic", "tonic-build", - "types 0.2.1 (git+https://github.com/semiotic-ai/lighthouse.git?branch=stable)", -] - -[[package]] -name = "sf-protos" -version = "0.1.0" -source = "git+https://github.com/semiotic-ai/sf-protos.git?branch=main#48ccab8b1dd49de143d3285200e3d6f90a9d2b17" -dependencies = [ - "alloy-primitives", - "bls 0.2.0 (git+https://github.com/sigp/lighthouse.git?branch=stable)", - "ethportal-api", - "primitive-types", - "prost", - "prost-build", - "prost-wkt", - "prost-wkt-types", - "reth-primitives", - "serde", - "ssz_types 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "thiserror", - "tonic", - "tonic-build", - "types 0.2.1 (git+https://github.com/sigp/lighthouse.git?branch=stable)", + "types", ] [[package]] @@ -5653,15 +5699,6 @@ dependencies = [ "ethereum_hashing", ] -[[package]] -name = "swap_or_not_shuffle" -version = "0.2.0" -source = "git+https://github.com/sigp/lighthouse.git?branch=stable#2e0eb6d1b8705bbda2ba56eb195d9cc7c6575e95" -dependencies = [ - "ethereum-types", - "ethereum_hashing", -] - [[package]] name = "syn" version = "1.0.109" @@ -5707,6 +5744,9 @@ name = "sync_wrapper" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" +dependencies = [ + "futures-core", +] [[package]] name = "system-configuration" @@ -5716,7 +5756,18 @@ checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" dependencies = [ "bitflags 1.3.2", "core-foundation", - "system-configuration-sys", + "system-configuration-sys 0.5.0", +] + +[[package]] +name = "system-configuration" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" +dependencies = [ + "bitflags 2.6.0", + "core-foundation", + "system-configuration-sys 0.6.0", ] [[package]] @@ -5729,6 +5780,16 @@ dependencies = [ "libc", ] +[[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" @@ -5748,15 +5809,6 @@ dependencies = [ "windows-sys 0.59.0", ] -[[package]] -name = "termcolor" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" -dependencies = [ - "winapi-util", -] - [[package]] name = "test_random_derive" version = "0.2.0" @@ -5766,15 +5818,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "test_random_derive" -version = "0.2.0" -source = "git+https://github.com/sigp/lighthouse.git?branch=stable#2e0eb6d1b8705bbda2ba56eb195d9cc7c6575e95" -dependencies = [ - "quote", - "syn 1.0.109", -] - [[package]] name = "thiserror" version = "1.0.64" @@ -5940,6 +5983,16 @@ dependencies = [ "syn 2.0.79", ] +[[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.24.1" @@ -5956,7 +6009,7 @@ version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" dependencies = [ - "rustls 0.23.14", + "rustls 0.23.15", "rustls-pki-types", "tokio", ] @@ -6043,7 +6096,7 @@ dependencies = [ "http 1.1.0", "http-body 1.0.1", "http-body-util", - "hyper 1.4.1", + "hyper 1.5.0", "hyper-timeout", "hyper-util", "percent-encoding", @@ -6199,7 +6252,7 @@ name = "tree_hash" version = "0.6.0" source = "git+https://github.com/KolbyML/tree_hash.git?rev=8aaf8bb4184148768d48e2cfbbdd0b95d1da8730#8aaf8bb4184148768d48e2cfbbdd0b95d1da8730" dependencies = [ - "alloy-primitives", + "alloy-primitives 0.7.7", "ethereum_hashing", "smallvec", ] @@ -6241,7 +6294,7 @@ name = "trin-validation" version = "0.1.0" source = "git+https://github.com/ethereum/trin.git?tag=v0.1.0-alpha.35#31ea2a21df5dcefcd779ea32c72e016a34555fed" dependencies = [ - "alloy-primitives", + "alloy-primitives 0.7.7", "anyhow", "eth2_hashing", "ethereum_ssz", @@ -6291,77 +6344,27 @@ name = "types" version = "0.2.1" source = "git+https://github.com/semiotic-ai/lighthouse.git?branch=stable#680cdbfcecb03c651db15e8949bd7367ef39c9ed" dependencies = [ - "alloy-primitives", - "alloy-rlp", - "arbitrary", - "bls 0.2.0 (git+https://github.com/semiotic-ai/lighthouse.git?branch=stable)", - "compare_fields 0.2.0 (git+https://github.com/semiotic-ai/lighthouse.git?branch=stable)", - "compare_fields_derive 0.2.0 (git+https://github.com/semiotic-ai/lighthouse.git?branch=stable)", - "derivative", - "eth2_interop_keypairs 0.2.0 (git+https://github.com/semiotic-ai/lighthouse.git?branch=stable)", - "ethereum-types", - "ethereum_hashing", - "ethereum_serde_utils", - "ethereum_ssz", - "ethereum_ssz_derive", - "hex", - "int_to_bytes 0.2.0 (git+https://github.com/semiotic-ai/lighthouse.git?branch=stable)", - "itertools 0.10.5", - "kzg 0.1.0 (git+https://github.com/semiotic-ai/lighthouse.git?branch=stable)", - "lazy_static", - "log", - "maplit", - "merkle_proof 0.2.0 (git+https://github.com/semiotic-ai/lighthouse.git?branch=stable)", - "metastruct", - "milhouse", - "parking_lot 0.12.3", - "rand", - "rand_xorshift", - "rayon", - "regex", - "rpds", - "rusqlite", - "safe_arith 0.1.0 (git+https://github.com/semiotic-ai/lighthouse.git?branch=stable)", - "serde", - "serde_json", - "serde_yaml", - "slog", - "smallvec", - "ssz_types 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "superstruct 0.8.0", - "swap_or_not_shuffle 0.2.0 (git+https://github.com/semiotic-ai/lighthouse.git?branch=stable)", - "tempfile", - "test_random_derive 0.2.0 (git+https://github.com/semiotic-ai/lighthouse.git?branch=stable)", - "tree_hash 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tree_hash_derive 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "types" -version = "0.2.1" -source = "git+https://github.com/sigp/lighthouse.git?branch=stable#2e0eb6d1b8705bbda2ba56eb195d9cc7c6575e95" -dependencies = [ - "alloy-primitives", + "alloy-primitives 0.7.7", "alloy-rlp", "arbitrary", - "bls 0.2.0 (git+https://github.com/sigp/lighthouse.git?branch=stable)", - "compare_fields 0.2.0 (git+https://github.com/sigp/lighthouse.git?branch=stable)", - "compare_fields_derive 0.2.0 (git+https://github.com/sigp/lighthouse.git?branch=stable)", + "bls", + "compare_fields", + "compare_fields_derive", "derivative", - "eth2_interop_keypairs 0.2.0 (git+https://github.com/sigp/lighthouse.git?branch=stable)", + "eth2_interop_keypairs", "ethereum-types", "ethereum_hashing", "ethereum_serde_utils", "ethereum_ssz", "ethereum_ssz_derive", "hex", - "int_to_bytes 0.2.0 (git+https://github.com/sigp/lighthouse.git?branch=stable)", + "int_to_bytes", "itertools 0.10.5", - "kzg 0.1.0 (git+https://github.com/sigp/lighthouse.git?branch=stable)", + "kzg", "lazy_static", "log", "maplit", - "merkle_proof 0.2.0 (git+https://github.com/sigp/lighthouse.git?branch=stable)", + "merkle_proof", "metastruct", "milhouse", "parking_lot 0.12.3", @@ -6371,7 +6374,7 @@ dependencies = [ "regex", "rpds", "rusqlite", - "safe_arith 0.1.0 (git+https://github.com/sigp/lighthouse.git?branch=stable)", + "safe_arith", "serde", "serde_json", "serde_yaml", @@ -6379,9 +6382,9 @@ dependencies = [ "smallvec", "ssz_types 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "superstruct 0.8.0", - "swap_or_not_shuffle 0.2.0 (git+https://github.com/sigp/lighthouse.git?branch=stable)", + "swap_or_not_shuffle", "tempfile", - "test_random_derive 0.2.0 (git+https://github.com/sigp/lighthouse.git?branch=stable)", + "test_random_derive", "tree_hash 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "tree_hash_derive 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -6535,7 +6538,7 @@ dependencies = [ "flate2", "log", "once_cell", - "rustls 0.23.14", + "rustls 0.23.15", "rustls-pki-types", "serde", "serde_json", @@ -6659,9 +6662,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.94" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef073ced962d62984fb38a36e5fdc1a2b23c9e0e1fa0689bb97afa4202ef6887" +checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" dependencies = [ "cfg-if", "once_cell", @@ -6670,9 +6673,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.94" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4bfab14ef75323f4eb75fa52ee0a3fb59611977fd3240da19b2cf36ff85030e" +checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" dependencies = [ "bumpalo", "log", @@ -6685,9 +6688,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.44" +version = "0.4.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65471f79c1022ffa5291d33520cbbb53b7687b01c2f8e83b57d102eed7ed479d" +checksum = "cc7ec4f8827a71586374db3e87abdb5a2bb3a15afed140221307c3ec06b1f63b" dependencies = [ "cfg-if", "js-sys", @@ -6697,9 +6700,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.94" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7bec9830f60924d9ceb3ef99d55c155be8afa76954edffbb5936ff4509474e7" +checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -6707,9 +6710,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.94" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c74f6e152a76a2ad448e223b0fc0b6b5747649c3d769cc6bf45737bf97d0ed6" +checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" dependencies = [ "proc-macro2", "quote", @@ -6720,9 +6723,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.94" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a42f6c679374623f295a8623adfe63d9284091245c3504bde47c17a3ce2777d9" +checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" [[package]] name = "wasm-streams" @@ -6739,9 +6742,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.71" +version = "0.3.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44188d185b5bdcae1052d08bcbcf9091a5524038d4572cc4f4f2bb9d5554ddd9" +checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112" dependencies = [ "js-sys", "wasm-bindgen", @@ -6814,6 +6817,36 @@ dependencies = [ "windows-targets 0.52.6", ] +[[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 0.52.6", +] + +[[package]] +name = "windows-result" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +dependencies = [ + "windows-targets 0.52.6", +] + +[[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 0.52.6", +] + [[package]] name = "windows-sys" version = "0.48.0" diff --git a/Cargo.toml b/Cargo.toml index 337e4263..2a9ca790 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,26 +4,59 @@ resolver = "2" [workspace.dependencies] alloy-primitives = "=0.7.7" +alloy-rlp = "0.3.7" +anyhow = "1" +base64 = "0.21.7" +bincode = "1.3.3" +bls = { git = "https://github.com/semiotic-ai/lighthouse.git", branch = "stable" } +bytes = "1.5" +clap = { version = "4.4.10", features = ["derive"] } +criterion = { version = "0.5.1", features = ["html_reports"] } +dotenv = "0.15.0" dotenvy = "0.15.7" +env_logger = "0.11.2" +ethereum-types = "=0.14.1" ethportal-api = { git = "https://github.com/ethereum/trin.git", version = "0.2.2", tag = "v0.1.0-alpha.35" } +futures = "0.3.31" hex = "0.4.3" http = "1.1.0" insta = "1.39.0" +log = "0.4.20" merkle_proof = { git = "https://github.com/semiotic-ai/lighthouse.git", branch = "stable" } - -bls = { git = "https://github.com/semiotic-ai/lighthouse.git", branch = "stable" } - +object_store = { version = "0.9.0", features = ["gcp", "http", "aws"] } 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" +rayon = "1.8.0" +reqwest = { version = "0.12.8", features = ["json"] } +reth-primitives = { git = "https://github.com/paradigmxyz/reth", version = "1.0.1", tag = "v1.0.1" } +reth-trie-common = { git = "https://github.com/paradigmxyz/reth", version = "1.0.1", tag = "v1.0.1" } +revm-primitives = "=6.0.0" +rlp = "0.5.2" rustls = { version = "0.23.12", features = ["ring"] } -serde = { version = "1.0.208", features = ["derive"] } +serde = "1.0.208" serde_derive = "1.0.208" serde_json = "1.0.127" +simple-log = "1.6.0" +ssz_types = "0.6" +tempfile = "3.0" thiserror = "1.0.63" -tokio = { version = "1.39.2", features = ["macros", "rt-multi-thread"] } +tokio = "1.39.2" +tokio-stream = "0.1.16" +tokio-test = "0.4.3" tonic = "0.12.0" +tonic-build = "0.12.0" tree_hash = "0.6.0" +trin-validation = { git = "https://github.com/ethereum/trin.git", version = "0.1.0", tag = "v0.1.0-alpha.35" } types = { git = "https://github.com/semiotic-ai/lighthouse.git", branch = "stable" } +url = "2.5" +zstd = "0.13.0" [profile.dev.build-override] opt-level = 3 diff --git a/README.md b/README.md index c73020d3..c09c1683 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,16 @@ -# Forrestrie +# Veemon ## Overview -Validating post-merge Ethereum data. +Verifying Ethereum data. -### Crates +## Crates -#### Forrestrie +### Forrestrie Library of types and methods for verifying post-merge Ethereum data. -#### Firehose Client +### Firehose Client Support for interfacing programmatically with Firehose gRPC endpoints. @@ -27,9 +27,25 @@ For more information see the - [Google Drive shared resources](https://drive.google.com/drive/folders/19QBMHZFAV7uo_Cu4RwLPTwGpBcQMd-hy), including `head-state.json` used in `beacon_state.rs` tests. -## Prerequisites +## Examples -> [!NOTE] -> You need to add the test assets files from our shared Google Drive to -> the root of this repo to run tests. See **Google Drive shared resources** -> above. +Here's an example of how to run one of the examples in the `forrestrie` crate: + +```terminal +cd crates/forrestrie && cargo run -- --examples historical_state_roots_proof +``` + +Use environment variables to provide Firehose Ethereum and Firehose Beacon providers of +your choice. + +To do so, place a `.env` file in the root of the crate you want to run examples for. +Your `.env` file should look like something this, depending on your requirements: + +```shell +FIREHOSE_ETHEREUM_URL= +FIREHOSE_ETHEREUM_PORT= +FIREHOSE_BEACON_URL= +FIREHOSE_BEACON_PORT= +BEACON_API_KEY= +ETHEREUM_API_KEY= +``` diff --git a/crates/flat-files-decoder/Cargo.toml b/crates/flat-files-decoder/Cargo.toml index ada824cc..bc1b6144 100644 --- a/crates/flat-files-decoder/Cargo.toml +++ b/crates/flat-files-decoder/Cargo.toml @@ -6,29 +6,27 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -sf-protos = { path = "../sf-protos" } alloy-primitives.workspace = true - -alloy-rlp = "0.3.7" -bincode = "1.3.3" -clap = { version = "4.3.21", features = ["derive"] } -prost = "0.13.1" -prost-types = "0.13.1" -rand = "0.8.5" -rayon = "1.8.0" -reth-primitives = { git = "https://github.com/paradigmxyz/reth", version = "1.0.1", tag = "v1.0.1" } -reth-trie-common = { git = "https://github.com/paradigmxyz/reth", version = "1.0.1", tag = "v1.0.1" } -revm-primitives = "=6.0.0" -serde = { version = "1.0.196", features = ["derive"] } -serde_json = "1.0.108" -simple-log = "1.6.0" -thiserror = "1.0.44" -tokio = { version = "1.35.0", features = ["full"] } -zstd = "0.13.0" +alloy-rlp.workspace = true +bincode.workspace = true +clap.workspace = true +prost.workspace = true +rand.workspace = true +rayon.workspace = true +reth-primitives.workspace = true +reth-trie-common.workspace = true +revm-primitives.workspace = true +serde = { workspace = true, features = ["derive"] } +serde_json.workspace = true +sf-protos = { path = "../sf-protos" } +simple-log.workspace = true +thiserror.workspace = true +tokio = { workspace = true, features = ["full"] } +zstd.workspace = true [dev-dependencies] -criterion = { version = "0.5.1", features = ["html_reports"] } -tokio-test = "0.4.3" +criterion.workspace = true +tokio-test.workspace = true [[bench]] name = "decoder" @@ -38,7 +36,6 @@ harness = false name = "stream_blocks" harness = false - [build-dependencies] -prost-build = "0.13.1" -prost-wkt-build = "0.6.0" +prost-build.workspace = true +prost-wkt-build.workspace = true diff --git a/crates/flat-files-decoder/src/lib.rs b/crates/flat-files-decoder/src/lib.rs index e7a2b566..686b1167 100644 --- a/crates/flat-files-decoder/src/lib.rs +++ b/crates/flat-files-decoder/src/lib.rs @@ -236,7 +236,7 @@ pub fn extract_blocks(mut reader: R) -> Result, DecodeError> /// # Arguments /// /// * `end_block`: For blocks after the merge, Ethereum sync committee should be used. This is why the default block -/// for this param is the MERGE_BLOCK (block 15537393) +/// for this param is the MERGE_BLOCK (block 15537393) /// * `reader`: where bytes are read from /// * `writer`: where bytes written to pub async fn stream_blocks( diff --git a/crates/flat-files-decoder/src/transactions/mod.rs b/crates/flat-files-decoder/src/transactions/mod.rs index 502cc34a..f21c110e 100644 --- a/crates/flat-files-decoder/src/transactions/mod.rs +++ b/crates/flat-files-decoder/src/transactions/mod.rs @@ -153,8 +153,7 @@ mod tests { let trace = block .transaction_traces .iter() - .filter(|t| Type::try_from(t.r#type).unwrap() == Type::TrxTypeLegacy) - .next() + .find(|t| Type::try_from(t.r#type).unwrap() == Type::TrxTypeLegacy) .unwrap(); let transaction = trace_to_signed(trace).unwrap(); @@ -199,8 +198,7 @@ mod tests { let trace = block .transaction_traces .iter() - .filter(|t| t.index == 141) - .next() + .find(|t| t.index == 141) .unwrap(); let transaction = trace_to_signed(trace).unwrap(); diff --git a/crates/flat-head/Cargo.toml b/crates/flat-head/Cargo.toml index cadce321..127478b3 100644 --- a/crates/flat-head/Cargo.toml +++ b/crates/flat-head/Cargo.toml @@ -6,21 +6,21 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -sf-protos = { path = "../sf-protos" } -anyhow = "1" -bincode = "1.3.3" -bytes = "1.5" -clap = { version = "4.3.21", features = ["derive"] } +anyhow.workspace = true +bincode.workspace = true +bytes.workspace = true +clap.workspace = true decoder = { path = "../flat-files-decoder" } -dotenv = "0.15.0" -env_logger = "0.11.2" -futures = "0.3" +dotenv.workspace = true +env_logger.workspace = true +futures.workspace = true header_accumulator = { path = "../header-accumulator" } -log = "0.4.20" -object_store = { version = "0.9.0", features = ["gcp", "http", "aws"] } -thiserror = "1" -tokio = { version = "1.0", features = ["full"] } -tree_hash = { git = "https://github.com/KolbyML/tree_hash.git", rev = "8aaf8bb4184148768d48e2cfbbdd0b95d1da8730" } -trin-validation = { git = "https://github.com/ethereum/trin.git", version = "0.1.0", tag = "v0.1.0-alpha.35" } -url = "2.5" -zstd = "0.13.0" +log.workspace = true +object_store.workspace = true +sf-protos = { path = "../sf-protos" } +thiserror.workspace = true +tokio = { workspace = true, features = ["full"] } +tree_hash.workspace = true +trin-validation.workspace = true +url.workspace = true +zstd.workspace = true diff --git a/crates/forrestrie/Cargo.toml b/crates/forrestrie/Cargo.toml index 94ca4e46..7226ef1e 100644 --- a/crates/forrestrie/Cargo.toml +++ b/crates/forrestrie/Cargo.toml @@ -15,12 +15,14 @@ path = "src/main.rs" [dependencies] merkle_proof.workspace = true primitive-types.workspace = true -serde.workspace = true +serde = { workspace = true, features = ["derive"] } +sf-protos = { path = "../sf-protos" } tree_hash.workspace = true types.workspace = true -sf-protos = { path = "../sf-protos" } [dev-dependencies] +firehose-client = { path = "../firehose-client" } insta.workspace = true +reqwest.workspace = true serde_json.workspace = true -tokio.workspace = true +tokio = { workspace = true, features = ["macros", "rt-multi-thread"] } diff --git a/crates/forrestrie/examples/block_roots_only_proof.rs b/crates/forrestrie/examples/block_roots_only_proof.rs new file mode 100644 index 00000000..303cbde2 --- /dev/null +++ b/crates/forrestrie/examples/block_roots_only_proof.rs @@ -0,0 +1,88 @@ +//! # 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/block_roots_proofs.rs b/crates/forrestrie/examples/block_roots_proofs.rs new file mode 100644 index 00000000..e0c7a18a --- /dev/null +++ b/crates/forrestrie/examples/block_roots_proofs.rs @@ -0,0 +1,87 @@ +//! # 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/empty_slot_hashes.rs b/crates/forrestrie/examples/empty_slot_hashes.rs new file mode 100644 index 00000000..5f3de492 --- /dev/null +++ b/crates/forrestrie/examples/empty_slot_hashes.rs @@ -0,0 +1,237 @@ +//! # 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/fetch_and_verify_block.rs b/crates/forrestrie/examples/fetch_and_verify_block.rs new file mode 100644 index 00000000..43c97fd8 --- /dev/null +++ b/crates/forrestrie/examples/fetch_and_verify_block.rs @@ -0,0 +1,59 @@ +//! # Beacon Block and Header Root Consistency +//! +//! In Ethereum's Beacon chain, the beacon block root and the block header root should match +//! for any given block, ensuring data integrity. This can be verified by computing the root +//! of a block and comparing it to the root of its header. +//! +//! For example, for slot 8786333, the block's root can be computed using the `canonical_root` method +//! from [`TreeHash`]: +//! +//! ```rust +//! let block_root = block.canonical_root(); +//! ``` +//! +//! Similarly, the block header root is derived as follows: +//! +//! ```rust +//! let block_header_root = block.block_header().tree_hash_root(); +//! ``` +//! +//! Both of these root hashes should be identical, indicating that the block's root hash +//! correctly represents the block header: +//! +//! ```rust +//! assert_eq!(block_root, block_header_root); +//! ``` +//! +use firehose_client::client::{Chain, FirehoseClient}; +use sf_protos::beacon::r#type::v1::Block as FirehoseBeaconBlock; +use tree_hash::TreeHash; +use types::{BeaconBlock, MainnetEthSpec}; + +#[tokio::main] +async fn main() { + let mut beacon_client = FirehoseClient::new(Chain::Beacon); + let response = beacon_client.fetch_block(8786333).await.unwrap().unwrap(); + let beacon_block = FirehoseBeaconBlock::try_from(response.into_inner()).unwrap(); + + let lighthouse_beacon_block = BeaconBlock::::try_from(beacon_block).unwrap(); + + insta::assert_debug_snapshot!(lighthouse_beacon_block.slot(), @ + "Slot(8786333)"); + + let block_root = lighthouse_beacon_block.canonical_root(); + + // See, for example, https://beaconcha.in/slot/8786333 and https://beaconscan.com/slot/8786333 + insta::assert_debug_snapshot!(block_root, @"0x063d4cf1a4f85d228d9eae17a9ab7df8b13de51e7a1988342a901575cce79613"); + + let block_header = lighthouse_beacon_block.block_header(); + let block_header_root = block_header.tree_hash_root(); + + assert_eq!(block_root, block_header_root); + + // This is to show that block hash and block body hash are different. + let body = lighthouse_beacon_block.body_deneb().unwrap(); + let body_hash = body.tree_hash_root(); + insta::assert_debug_snapshot!(body_hash, @"0xc15e821344ce5b201e2938248921743da8a07782168456929c8cef9f25a4cb02"); + + println!("fetch_and_verify_block.rs done"); +} diff --git a/crates/forrestrie/examples/historical_state_roots_proof.rs b/crates/forrestrie/examples/historical_state_roots_proof.rs new file mode 100644 index 00000000..fa5dbdb2 --- /dev/null +++ b/crates/forrestrie/examples/historical_state_roots_proof.rs @@ -0,0 +1,42 @@ +//! # 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/historical_summary_proof.rs b/crates/forrestrie/examples/historical_summary_proof.rs new file mode 100644 index 00000000..51208850 --- /dev/null +++ b/crates/forrestrie/examples/historical_summary_proof.rs @@ -0,0 +1,45 @@ +//! # 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/verify_block_inclusion_proof.rs b/crates/forrestrie/examples/verify_block_inclusion_proof.rs new file mode 100644 index 00000000..07ffb6b4 --- /dev/null +++ b/crates/forrestrie/examples/verify_block_inclusion_proof.rs @@ -0,0 +1,71 @@ +//! # Verify Block Inclusion Proof +//! +//! In Ethereum's Beacon Chain, execution layer payloads are included in the block body. +//! +//! This example demonstrates how to verify the inclusion proof of an execution payload +//! in a block body. +//! +//! For example, for block `20672593`, the execution payload root can be computed using the `tree_hash_root` method +//! from [`TreeHash`]: +//! +//! ```rust +//! let execution_payload_root = execution_payload.tree_hash_root(); +//! ``` +//! +//! Similarly, the block body root is derived as follows: +//! +//! ```rust +//! let block_body_hash = block_body.tree_hash_root(); +//! ``` +//! +//! The inclusion proof can be computed using the `compute_merkle_proof` method from [`BeaconBlockBody`]: +//! +//! ```rust +//! let proof = body.compute_merkle_proof(EXECUTION_PAYLOAD_INDEX).unwrap(); +//! ``` +//! +use firehose_client::client::{Chain, FirehoseClient}; +use forrestrie::beacon_block::{ + HistoricalDataProofs, BEACON_BLOCK_BODY_PROOF_DEPTH, EXECUTION_PAYLOAD_FIELD_INDEX, +}; +use merkle_proof::verify_merkle_proof; +use sf_protos::beacon::r#type::v1::Block as FirehoseBeaconBlock; +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/src/beacon_block.rs b/crates/forrestrie/src/beacon_block.rs index 176c6147..1143b5ca 100644 --- a/crates/forrestrie/src/beacon_block.rs +++ b/crates/forrestrie/src/beacon_block.rs @@ -89,76 +89,3 @@ impl HistoricalDataProofs for BeaconBlockBody { Ok(proof) } } - -#[cfg(test)] -mod tests { - use std::cell::LazyCell; - - use super::*; - - use merkle_proof::verify_merkle_proof; - - /// Deneb block JSON file shared among contributors. - /// The execution payload block hash is `0xad1b9aa0d3315a08d38e258a914721630aa5d32efef8d02607555fe8ae92d7fc`. - const DENEB_BLOCK_JSON: &str = include_str!("../../../bb-8786333.json"); - - const BLOCK_WRAPPER: LazyCell = LazyCell::new(|| { - serde_json::from_str(DENEB_BLOCK_JSON).expect( - "For this spike we are using a Deneb block JSON file that has been shared among contributors", - ) - }); - - /// Demonstrate that we can verify the inclusion proof for the execution payload field in the block body. - /// The execution payload block hash should match the block hash of the execution block. - #[test] - fn test_inclusion_proof_for_block_body_given_execution_payload() { - let block_wrapper = &BLOCK_WRAPPER; - let block = &block_wrapper.data.message; - - let execution_payload = block.body().execution_payload().unwrap(); - let execution_payload_root = execution_payload.tree_hash_root(); - - let block_body = 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 - )); - } - - #[test] - fn test_beacon_block_header_root_and_beacon_block_root_match() { - let block_wrapper = &BLOCK_WRAPPER; - let block = &block_wrapper.data.message; - - insta::assert_debug_snapshot!(block.slot(), @ - "Slot(8786333)"); - - // `BeaconBlock::canonical_root` calls `tree_hash_root` on the block. - let block_root = 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 = 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 = block.body_deneb().unwrap(); - let body_hash = body.tree_hash_root(); - insta::assert_debug_snapshot!(body_hash, @"0xc15e821344ce5b201e2938248921743da8a07782168456929c8cef9f25a4cb02"); - } -} diff --git a/crates/forrestrie/src/beacon_state.rs b/crates/forrestrie/src/beacon_state.rs index 5d5e41f1..db8c1c75 100644 --- a/crates/forrestrie/src/beacon_state.rs +++ b/crates/forrestrie/src/beacon_state.rs @@ -29,7 +29,7 @@ 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 -const HISTORICAL_ROOTS_INDEX: usize = 39; +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`]: @@ -194,438 +194,3 @@ pub fn compute_block_roots_proof_only( Ok(proof) } - -#[cfg(test)] -mod tests { - use std::{ - cell::LazyCell, - collections::{BTreeMap, HashSet}, - sync::Mutex, - }; - - use super::*; - - use merkle_proof::verify_merkle_proof; - use types::{light_client_update::CURRENT_SYNC_COMMITTEE_PROOF_LEN, MainnetEthSpec}; - - // State for slot number 9471054, Deneb, latest execution payload header block number 20264676. - const HEAD_STATE_JSON: &str = include_str!("../../../head-state.json"); - const STATE: LazyCell>> = LazyCell::new(|| { - Mutex::new({ - serde_json::from_str(HEAD_STATE_JSON).expect( - "For this spike we are using a 'head-state.json' file that has been shared among contributors", - ) - }) - }); - - const TRANSITION_STATE_JSON: &str = include_str!("../../../8790016-state.json"); - - /// # [https://beaconcha.in/slot/8790016](https://beaconcha.in/slot/8790016) - /// State root: `0xcdf3dc15e11659b7bc6c6a79a953877d89c6ea6f5909b31c9c1f097d82d5e1cd` - /// Block root: `0xa3649fb5d35ad9ea4094ffda055e65115a31eab0bd19fa5d8fe4f8214a8c3ff3` - const TRANSITION_STATE: LazyCell>> = LazyCell::new(|| { - serde_json::from_str(TRANSITION_STATE_JSON).expect( - "We are using a '8790016-state.json' file that has been shared among contributors", - ) - }); - - #[test] - fn test_inclusion_proofs_with_historical_and_state_roots() { - let state = STATE; - - let state_lock = state.lock().unwrap(); - - let proof = state_lock - .compute_merkle_proof_for_historical_data(HISTORICAL_ROOTS_INDEX) - .unwrap(); - - drop(state_lock); - - insta::assert_debug_snapshot!(proof, @r###" - [ - 0xe81a79506c46b126f75a08cdd5cbc35052b61ca944c6c3becf32432e2ee6373a, - 0xcfb49cd7eb0051153685e5e6124b635c6b9bcc69a6ead6af0ef7d9885fcc16e2, - 0x29c2e1f6d96493e9b49517cb78123990038429e4c3574688a48f9abe69238449, - 0xdb329a01d9114f087155633b36b498c8e60028c0acedc8e3b64e013dbbd4fa06, - 0x53b107024e402f616f8f348d900e0d62f4b6f0558d2bfbd09200e68620a5b9c2, - ] - "###); - - let mut state_lock = state.lock().unwrap(); - - let historical_roots_tree_hash_root = state_lock.historical_roots_tree_hash_root(); - - let state_root = state_lock.state_root().unwrap(); - - drop(state_lock); - - let depth = CURRENT_SYNC_COMMITTEE_PROOF_LEN; - - assert!( - verify_merkle_proof( - historical_roots_tree_hash_root, - &proof, - depth, - HISTORICAL_ROOTS_FIELD_INDEX, - state_root - ), - "Merkle proof verification failed" - ); - } - - #[test] - fn test_inclusion_proofs_for_historical_summary_given_historical_summaries_root() { - let state = &STATE; - - let state_lock = state.lock().unwrap(); - - let proof = state_lock - .compute_merkle_proof_for_historical_data(HISTORICAL_SUMMARIES_INDEX) - .unwrap(); - - drop(state_lock); - - insta::assert_debug_snapshot!(proof, @r###" - [ - 0x053a090000000000000000000000000000000000000000000000000000000000, - 0x455a0d1e0a3b5660d74b6520062c9c3cead986928686e535451ca6e61aeb291f, - 0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71, - 0xc204e43766c4e9d43da1a54c3053024eef28d407bcca7936900ffd2e7aa165b2, - 0x2150a88f205759c59817f42dc307620c67d3d23417959286928d186c639a0948, - ] - "###); - - let mut state_lock = state.lock().unwrap(); - - let historical_summaries_tree_hash_root = - state_lock.historical_summaries_tree_hash_root().unwrap(); - - let state_root = state_lock.state_root().unwrap(); - - drop(state_lock); - - 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" - ); - } - - #[test] - /// For this test, 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 this test, we are using the state at [`Slot`] 8790016, which is the first [`Slot`] of era 1073, 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. - /// The last block root in the `block_roots` buffer is the block root of the previous block, in this case block number 19588228 - /// from slot 8790015. - fn test_inclusion_proofs_for_block_roots() { - let transition_state = &TRANSITION_STATE; - - let state_lock = transition_state.lock().unwrap(); - - // There are 8192 slots in an era. 8790016 / 8192 = 1073. - let proof_era = state_lock.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 = state_lock.data().block_roots().get(index).unwrap().clone(); - - assert!( - state_lock.block_roots_contain_entire_era().unwrap(), - "Block roots buffer does not contain an entire era" - ); - - let proof = state_lock.compute_block_roots_proof(index).unwrap(); - - drop(state_lock); - - // 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 state = &STATE; - - let state_lock = state.lock().unwrap(); - - // The verifier retrieves the block_summary_root for the historical_summary and verifies the proof against it. - let historical_summary = state_lock - .data() - .historical_summaries() - .unwrap() - .get(proof_era_index) - .unwrap(); - - let historical_summary_root = historical_summary.tree_hash_root(); - - drop(state_lock); - - assert!( - verify_merkle_proof( - block_root_at_index, - &proof, - HISTORICAL_SUMMARY_TREE_DEPTH, - index, - historical_summary_root - ), - "Merkle proof verification failed" - ); - } - - #[test] - /// 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 [`Slot`] 8790016 - the last [`Slot`] of era 1073 - - /// to build the proof. - /// We chose this [`Slot`] because it is the last [`Slot`] of an era, and all of the - /// [`BeaconBlockHeader`] roots needed to construct the [`HistoricalSummary`] for this era are - /// available in `state.block_roots`. - fn test_inclusion_proofs_for_block_roots_only() { - let transition_state = &TRANSITION_STATE; - - let state_lock = transition_state.lock().unwrap(); - - // There are 8192 slots in an era. 8790016 / 8192 = 1073. - let proof_era = state_lock.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 = state_lock.data().block_roots().get(index).unwrap().clone(); - - let proof = state_lock.compute_block_roots_proof_only(index).unwrap(); - - drop(state_lock); - - // 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 state = &STATE; - - let state_lock = state.lock().unwrap(); - - // The verifier retrieves the block_summary_root for the historical_summary and verifies the - // proof against it. - let historical_summary: &HistoricalSummary = state_lock - .data() - .historical_summaries() - .unwrap() - .get(proof_era_index) - .unwrap(); - - let block_roots_summary_root = historical_summary.block_summary_root(); - - drop(state_lock); - - assert!( - verify_merkle_proof( - block_root_at_index, - &proof, - HISTORY_TREE_DEPTH, - index, - block_roots_summary_root - ), - "Merkle proof verification failed" - ); - } - - #[test] - fn test_empty_slot_block_hashes_are_duplicates_of_previous_full_slot_block() { - // TODO(TRU-322): Test artifacts are a mess, ideally we would trim these JSON files - // to only include the necessary fields. - // - // The JSON artifact used in this test is a BeaconState at slot 10035200, acquired from the - // https://www.lightclientdata.org/eth/v2/debug/beacon/states/ provider. - // - // 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. - let state: HeadState = - serde_json::from_str(std::include_str!("../../../state-10035200.json")).unwrap(); - - let slot = state.data().slot().as_u64(); - insta::assert_debug_snapshot!(slot, @ - "10035200"); - - // Slot 10035200 is the first slot of the 1225th era. - // Every 8192 slots, the era increments by 1, and (after Capella) the historical summaries buffer is updated. - let current_era = slot / 8192; - assert_eq!(current_era, 1225); - // Total number of slots at end of 1224th era is 10035200. - assert_eq!(current_era * 8192, 10035200); - // Remember, slots are counted using zero-based numbering. - assert_eq!(slot % 8192, 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() as u64; - assert_eq!( - (current_era - num_historical_summaries) as usize, - 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_insert(Vec::new()).push(i); - acc - }) - // Remove non-duplicate block roots. - .into_iter() - .filter(|(_, indices)| indices.len() > 1) - .collect::>>(); - - insta::assert_debug_snapshot!(duplicate_block_roots_lookup_table, @r###" - { - 0x0a82fc1f6bf1b23143f85193290ae6a1a3829f97b8cbebc7310ccd4e2670ac04: [ - 8159, - 8160, - ], - 0x10160a60710f5cd535744af4ab93945b53a69d8ad5c2d185cef39fb5db2c739f: [ - 4829, - 4830, - ], - 0x144136a34d785b87f9b10252d656b7d76d72bf24d6c98f1ecf3db075e65ba11f: [ - 5408, - 5409, - ], - 0x1f44d980ff3fad59550d67a72899c2a9a382c27dcac285da4a30f4813a32ec6b: [ - 2082, - 2083, - ], - 0x33efdf2390b28e8b83a7ce932e9f7ae652cc94baea7529b066406d92a17a0085: [ - 2863, - 2864, - ], - 0x389f6d0adc7c3ac69e335bd7a23bd021bb2ca7f0379cf4747b3a57b8a3e84c26: [ - 6988, - 6989, - ], - 0x512b89995f45b2518c1533d0d0c2868952ffee057520ca9c8abaa4583a755d0c: [ - 3910, - 3911, - ], - 0x6205798f4257b000255c8decdfc19eb0ab5a7b1a37007ca38af772d9c06d3663: [ - 7263, - 7264, - ], - 0x845cb1a3a04d8461ba50186d3c441316bf62530e3875bb95b342cb3f8a527d3b: [ - 2568, - 2569, - ], - 0x8748739e4d1c526616e9ad02669abb7c937cb9329e4ec43a4b6da7fa987e9ea5: [ - 3776, - 3777, - 3778, - ], - 0x9476f0da6e2711039adc15848cb2613c4c557f6dbc17b0ca6c2253b7b1583fb0: [ - 7235, - 7236, - ], - 0xa02ea51e375ce6d23bdbd6826ff9e9919b65d85aacffe241554e071e72fe55cc: [ - 6214, - 6215, - ], - 0xb4808b92f60e4261bd183000ace249bfe104f57f2fe4072c23966676defe5cd0: [ - 7098, - 7099, - ], - 0xb5aa2838677f7781c02eeed2503fe832a8193821568d91749614a417b9aefcce: [ - 7383, - 7384, - ], - 0xb84c76d1ec6022a00d445bd978445c5234c18ea33107121c622a75e2e4e59301: [ - 3743, - 3744, - 3745, - ], - 0xb99242051a8ba08e6b903b6e0b13b97d0ba1e81f805ead71b9f9ee0d0c50bc51: [ - 8027, - 8028, - ], - 0xc165e4bfbfa8aaccbc18030442e93db86062ed37564c52e47a54c6d65fdbeb71: [ - 35, - 36, - ], - 0xc90431f6b954f062c250f9146febc938d9e285e4f3c716512c3bcc57b0afcd14: [ - 427, - 428, - ], - 0xc9465a42c903868b90c1520abf25940a7d441e0b580e880b9873ef347a4cdfd2: [ - 6852, - 6853, - ], - 0xccc381c7dd2f4867f6c1b57970fffc143acf3b78219d18f39c511099ec240c8d: [ - 1615, - 1616, - ], - 0xcfab9ef6f4de3ef63a869ba093400a18a5cf49f16965d22dad820f107fc626a1: [ - 6082, - 6083, - ], - 0xd5981b2a671bce2bba148ba165637700f71c9dd1841c4f34622c04fda51449f9: [ - 1839, - 1840, - ], - 0xd7601a5fe3e02182a18a63b78b99327b63c915461d2b5c069203c5654c461521: [ - 248, - 249, - ], - 0xdbc617a37da7178961ed67da921ae4fd2b1d5d88965f1917bd498681f3964402: [ - 5835, - 5836, - ], - 0xe727e8acedd15bd499acf5f049c13c225d33a53a6281fcfce721f18ce5008103: [ - 7405, - 7406, - ], - 0xf07c053f494307167b4301b68739c87b57f55ae6417ca6727a9c32ad1d497555: [ - 3579, - 3580, - ], - 0xf355793a27a764dd9536b7bd8199ce73af90cd130edeb70f461f31fc3ce65fb4: [ - 4530, - 4531, - ], - 0xfc5647ebb69a2b32742387a2eda5b4ce0b8670721c8b4558477de554655fb0ec: [ - 4174, - 4175, - ], - } - "###); - } -} diff --git a/crates/header-accumulator/Cargo.toml b/crates/header-accumulator/Cargo.toml index 357f0b3e..f76737c4 100644 --- a/crates/header-accumulator/Cargo.toml +++ b/crates/header-accumulator/Cargo.toml @@ -6,24 +6,22 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -sf-protos = { path = "../sf-protos" } - +alloy-primitives.workspace = true +base64.workspace = true +clap.workspace = true +env_logger.workspace = true +ethereum-types.workspace = true ethportal-api.workspace = true +log.workspace = true primitive-types.workspace = true -serde.workspace = true +rlp.workspace = true +serde = { workspace = true, features = ["derive"] } serde_json.workspace = true - -alloy-primitives = "=0.7.7" -base64 = "0.21.7" -clap = { version = "4.4.10", features = ["derive"] } -env_logger = "0.10.1" -ethereum-types = "=0.14.1" -log = "0.4.20" -rlp = "0.5.2" +sf-protos = { path = "../sf-protos" } # Needs to match that transitively depended on by trin-validation tree_hash = { git = "https://github.com/KolbyML/tree_hash.git", rev = "8aaf8bb4184148768d48e2cfbbdd0b95d1da8730" } -trin-validation = { git = "https://github.com/ethereum/trin.git", version = "0.1.0", tag = "v0.1.0-alpha.35" } +trin-validation.workspace = true [dev-dependencies] -decoder = { git = "https://github.com/semiotic-ai/flat-files-decoder.git", branch = "main" } -tempfile = "3.0" +decoder = { path = "../flat-files-decoder" } +tempfile.workspace = true diff --git a/crates/header-accumulator/src/errors.rs b/crates/header-accumulator/src/errors.rs index dc713e05..d0c4fb78 100644 --- a/crates/header-accumulator/src/errors.rs +++ b/crates/header-accumulator/src/errors.rs @@ -138,7 +138,7 @@ impl From for EraValidateError { fn from(error: ProtosError) -> Self { match error { ProtosError::BlockConversionError => Self::HeaderDecodeError, - _ => unimplemented!("Error mapping is not implemented") + _ => unimplemented!("Error mapping is not implemented"), } } } diff --git a/crates/header-accumulator/src/sync.rs b/crates/header-accumulator/src/sync.rs index da2317eb..ac1fdc30 100644 --- a/crates/header-accumulator/src/sync.rs +++ b/crates/header-accumulator/src/sync.rs @@ -175,24 +175,21 @@ mod tests { // Test case where epoch exists and hashes match let epoch = 0; - assert_eq!( - json_lock - .check_sync_state(&file_path, epoch, mac_file.historical_epochs[0].0) - .unwrap(), - true - ); + assert!(json_lock + .check_sync_state(&file_path, epoch, mac_file.historical_epochs[0].0) + .unwrap(),); // Test case where epoch does not exist let epoch = 2; let result = json_lock - .check_sync_state(&file_path, epoch.clone(), mac_file.historical_epochs[2].0) + .check_sync_state(&file_path, epoch, mac_file.historical_epochs[2].0) .unwrap(); - assert_eq!(result, false); + assert!(!result); // // test when hashes differ but lock is present let epoch = 0; let result = json_lock - .check_sync_state(&file_path, epoch.clone(), mac_file.historical_epochs[1].0) + .check_sync_state(&file_path, epoch, mac_file.historical_epochs[1].0) .map_err(|error| error.to_string()); assert_eq!( result.unwrap_err(), @@ -202,9 +199,9 @@ mod tests { // test case for another epoch hash let epoch = 1; let result = json_lock - .check_sync_state(&file_path, epoch.clone(), mac_file.historical_epochs[1].0) + .check_sync_state(&file_path, epoch, mac_file.historical_epochs[1].0) .map_err(|error| error.to_string()); - assert_eq!(result.unwrap(), true); + assert!(result.unwrap()); Ok(()) } diff --git a/crates/sf-protos/Cargo.toml b/crates/sf-protos/Cargo.toml index 0f4b7a9b..33acdfc6 100644 --- a/crates/sf-protos/Cargo.toml +++ b/crates/sf-protos/Cargo.toml @@ -10,23 +10,22 @@ path = "src/lib.rs" [dependencies] alloy-primitives.workspace = true bls.workspace = true +ethportal-api.workspace = true primitive-types.workspace = true +prost.workspace = true +prost-wkt.workspace = true +prost-wkt-types.workspace = true +reth-primitives = { git = "https://github.com/paradigmxyz/reth", version = "1.0.1", tag = "v1.0.1" } +serde.workspace = true +ssz_types.workspace = true thiserror.workspace = true tonic.workspace = true types.workspace = true -ethportal-api = { git = "https://github.com/ethereum/trin.git", version = "0.2.2", tag = "v0.1.0-alpha.35" } -prost = "0.13.1" -prost-wkt = "0.6.0" -prost-wkt-types = "0.6.0" -reth-primitives = { git = "https://github.com/paradigmxyz/reth", version = "1.0.1", tag = "v1.0.1" } -serde = "1.0.196" -ssz_types = "0.6" - [dev-dependencies] -hex = "0.4.3" -serde_json = "1.0.127" +hex.workspace = true +serde_json.workspace = true [build-dependencies] -prost-build = "0.13.1" -tonic-build = "0.12.0" +prost-build.workspace = true +tonic-build.workspace = true diff --git a/crates/sf-protos/protos/block.proto b/crates/sf-protos/protos/block.proto index 4398f26e..ea53a709 100644 --- a/crates/sf-protos/protos/block.proto +++ b/crates/sf-protos/protos/block.proto @@ -666,9 +666,9 @@ message BalanceChange { // It is safe in those case(s) to consider the balance as being 0. // // If you consume this from a Substreams, you can safely use: - // - // let old_value = old_value.unwrap_or_default(); - // + // ```rust,ignore + // let old_value = old_value.unwrap_or_default(); + // ``` BigInt old_value = 2; // NewValue is the balance of the address after the change. This value @@ -677,9 +677,9 @@ message BalanceChange { // 0. // // If you consume this from a Substreams, you can safely use: - // - // let new_value = new_value.unwrap_or_default(); - // + // ```rust,ignore + // let new_value = new_value.unwrap_or_default(); + // ``` BigInt new_value = 3; // Reason is the reason why the balance has changed. This is useful to determine