diff --git a/.github/workflows/local-testnet.yml b/.github/workflows/local-testnet.yml index 42293d38a7..bcade948d7 100644 --- a/.github/workflows/local-testnet.yml +++ b/.github/workflows/local-testnet.yml @@ -13,87 +13,154 @@ concurrency: cancel-in-progress: true jobs: - run-local-testnet: - strategy: - matrix: - os: - - ubuntu-22.04 - - macos-12 - runs-on: ${{ matrix.os }} - env: - # Enable portable to prevent issues with caching `blst` for the wrong CPU type - FEATURES: portable,jemalloc + dockerfile-ubuntu: + runs-on: ${{ github.repository == 'sigp/lighthouse' && fromJson('["self-hosted", "linux", "CI", "large"]') || 'ubuntu-latest' }} steps: - uses: actions/checkout@v4 - - name: Get latest version of stable Rust - run: rustup update stable - - name: Install geth (ubuntu) - if: matrix.os == 'ubuntu-22.04' + - name: Build Docker image run: | - sudo add-apt-repository -y ppa:ethereum/ethereum - sudo apt-get update - sudo apt-get install ethereum - - name: Install geth (mac) - if: matrix.os == 'macos-12' - run: | - brew tap ethereum/ethereum - brew install ethereum - - name: Install GNU sed & GNU grep - if: matrix.os == 'macos-12' - run: | - brew install gnu-sed grep - echo "$(brew --prefix)/opt/gnu-sed/libexec/gnubin" >> $GITHUB_PATH - echo "$(brew --prefix)/opt/grep/libexec/gnubin" >> $GITHUB_PATH - # https://github.com/actions/cache/blob/main/examples.md#rust---cargo - - uses: actions/cache@v4 - id: cache-cargo - with: - path: | - ~/.cargo/bin/ - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ - target/ - key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} + docker build --build-arg FEATURES=portable -t lighthouse:local . + docker save lighthouse:local -o lighthouse-docker.tar - - name: Install lighthouse - run: make && make install-lcli + - name: Upload Docker image artifact + uses: actions/upload-artifact@v4 + with: + name: lighthouse-docker + path: lighthouse-docker.tar + retention-days: 3 + + run-local-testnet: + runs-on: ubuntu-22.04 + needs: dockerfile-ubuntu + steps: + - uses: actions/checkout@v4 + + - name: Install dependencies + run: | + sudo add-apt-repository ppa:rmescandon/yq + echo "deb [trusted=yes] https://apt.fury.io/kurtosis-tech/ /" | sudo tee /etc/apt/sources.list.d/kurtosis.list + sudo apt update + sudo apt install -y kurtosis-cli yq + kurtosis analytics disable + + - name: Download Docker image artifact + uses: actions/download-artifact@v4 + with: + name: lighthouse-docker + path: . + + - name: Load Docker image + run: docker load -i lighthouse-docker.tar - name: Start local testnet - run: ./start_local_testnet.sh genesis.json && sleep 60 + run: ./start_local_testnet.sh -e local -c -b false && sleep 60 working-directory: scripts/local_testnet - - name: Print logs - run: ./dump_logs.sh - working-directory: scripts/local_testnet - - - name: Stop local testnet - run: ./stop_local_testnet.sh - working-directory: scripts/local_testnet - - - name: Clean-up testnet - run: ./clean.sh + - name: Stop local testnet and dump logs + run: ./stop_local_testnet.sh local working-directory: scripts/local_testnet - name: Start local testnet with blinded block production - run: ./start_local_testnet.sh -p genesis.json && sleep 60 + run: ./start_local_testnet.sh -e local-blinded -c -p -b false && sleep 60 working-directory: scripts/local_testnet - - name: Print logs for blinded block testnet - run: ./dump_logs.sh + - name: Stop local testnet and dump logs + run: ./stop_local_testnet.sh local-blinded working-directory: scripts/local_testnet - - name: Stop local testnet with blinded block production - run: ./stop_local_testnet.sh - working-directory: scripts/local_testnet + - name: Upload logs artifact + uses: actions/upload-artifact@v4 + with: + name: logs-local-testnet + path: | + scripts/local_testnet/logs + retention-days: 3 + + doppelganger-protection-success-test: + needs: dockerfile-ubuntu + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v4 + + - name: Install dependencies + run: | + sudo add-apt-repository ppa:rmescandon/yq + echo "deb [trusted=yes] https://apt.fury.io/kurtosis-tech/ /" | sudo tee /etc/apt/sources.list.d/kurtosis.list + sudo apt update + sudo apt install -y kurtosis-cli yq + kurtosis analytics disable + + - name: Download Docker image artifact + uses: actions/download-artifact@v4 + with: + name: lighthouse-docker + path: . + + - name: Load Docker image + run: docker load -i lighthouse-docker.tar + + - name: Run the doppelganger protection success test script + run: | + ./doppelganger_protection.sh success + working-directory: scripts/tests + + - name: Upload logs artifact + uses: actions/upload-artifact@v4 + with: + name: logs-doppelganger-protection-success + path: | + scripts/local_testnet/logs + retention-days: 3 + + doppelganger-protection-failure-test: + needs: dockerfile-ubuntu + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v4 + + - name: Install dependencies + run: | + sudo add-apt-repository ppa:rmescandon/yq + echo "deb [trusted=yes] https://apt.fury.io/kurtosis-tech/ /" | sudo tee /etc/apt/sources.list.d/kurtosis.list + sudo apt update + sudo apt install -y kurtosis-cli yq + kurtosis analytics disable + + - name: Download Docker image artifact + uses: actions/download-artifact@v4 + with: + name: lighthouse-docker + path: . + + - name: Load Docker image + run: docker load -i lighthouse-docker.tar + + - name: Run the doppelganger protection failure test script + run: | + ./doppelganger_protection.sh failure + working-directory: scripts/tests + + - name: Upload logs artifact + uses: actions/upload-artifact@v4 + with: + name: logs-doppelganger-protection-failure + path: | + scripts/local_testnet/logs + retention-days: 3 + # This job succeeds ONLY IF all others succeed. It is used by the merge queue to determine whether # a PR is safe to merge. New jobs should be added here. local-testnet-success: name: local-testnet-success runs-on: ubuntu-latest - needs: ["run-local-testnet"] + needs: [ + 'dockerfile-ubuntu', + 'run-local-testnet', + 'doppelganger-protection-success-test', + 'doppelganger-protection-failure-test', + ] steps: - uses: actions/checkout@v4 - name: Check that success job is dependent on all others diff --git a/.github/workflows/test-suite.yml b/.github/workflows/test-suite.yml index b1239705fd..0840651bbc 100644 --- a/.github/workflows/test-suite.yml +++ b/.github/workflows/test-suite.yml @@ -41,7 +41,7 @@ jobs: LABELS: ${{ toJson(github.event.pull_request.labels) }} run: | SKIP_CI="false" - if [ -z "${LABELS}" ]; then + if [ -z "${LABELS}" ] || [ "${LABELS}" = "null" ]; then LABELS="none"; else LABELS=$(echo ${LABELS} | jq -r '.[].name') @@ -52,7 +52,7 @@ jobs: break fi done - echo "::set-output name=skip_ci::$SKIP_CI" + echo "skip_ci=$SKIP_CI" >> $GITHUB_OUTPUT target-branch-check: name: target-branch-check @@ -259,17 +259,6 @@ jobs: - name: Show cache stats if: env.SELF_HOSTED_RUNNERS == 'true' run: sccache --show-stats - dockerfile-ubuntu: - name: dockerfile-ubuntu - needs: [check-labels] - if: needs.check-labels.outputs.skip_ci != 'true' - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Build the root Dockerfile - run: docker build --build-arg FEATURES=portable -t lighthouse:local . - - name: Test the built image - run: docker run -t lighthouse:local lighthouse --version basic-simulator-ubuntu: name: basic-simulator-ubuntu needs: [check-labels] @@ -298,41 +287,6 @@ jobs: cache-target: release - name: Run a beacon chain sim which tests VC fallback behaviour run: cargo run --release --bin simulator fallback-sim - doppelganger-protection-test: - name: doppelganger-protection-test - needs: [check-labels] - if: needs.check-labels.outputs.skip_ci != 'true' - runs-on: ${{ github.repository == 'sigp/lighthouse' && fromJson('["self-hosted", "linux", "CI", "small"]') || 'ubuntu-latest' }} - env: - # Enable portable to prevent issues with caching `blst` for the wrong CPU type - FEATURES: jemalloc,portable - steps: - - uses: actions/checkout@v4 - - name: Get latest version of stable Rust - if: env.SELF_HOSTED_RUNNERS == 'false' - uses: moonrepo/setup-rust@v1 - with: - channel: stable - cache-target: release - - name: Install geth - if: env.SELF_HOSTED_RUNNERS == 'false' - run: | - sudo add-apt-repository -y ppa:ethereum/ethereum - sudo apt-get update - sudo apt-get install ethereum - - name: Install lighthouse - run: | - make - - name: Install lcli - run: make install-lcli - - name: Run the doppelganger protection failure test script - run: | - cd scripts/tests - ./doppelganger_protection.sh failure genesis.json - - name: Run the doppelganger protection success test script - run: | - cd scripts/tests - ./doppelganger_protection.sh success genesis.json execution-engine-integration-ubuntu: name: execution-engine-integration-ubuntu needs: [check-labels] @@ -465,10 +419,8 @@ jobs: 'debug-tests-ubuntu', 'state-transition-vectors-ubuntu', 'ef-tests-ubuntu', - 'dockerfile-ubuntu', 'basic-simulator-ubuntu', 'fallback-simulator-ubuntu', - 'doppelganger-protection-test', 'execution-engine-integration-ubuntu', 'check-code', 'check-msrv', diff --git a/Cargo.lock b/Cargo.lock index f2ac7c91b4..5c165cec89 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -18,7 +18,7 @@ version = "0.3.5" dependencies = [ "account_utils", "bls", - "clap 4.5.4", + "clap", "clap_utils", "directory", "environment", @@ -59,9 +59,9 @@ dependencies = [ [[package]] name = "addr2line" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" dependencies = [ "gimli", ] @@ -245,9 +245,9 @@ dependencies = [ [[package]] name = "alloy-rlp" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d58d9f5da7b40e9bfff0b7e7816700be4019db97d4b6359fe7f94a9e22e42ac" +checksum = "b155716bab55763c95ba212806cf43d05bcc70e5f35b02bad20cf5ec7fe11fed" dependencies = [ "alloy-rlp-derive", "arrayvec", @@ -256,13 +256,13 @@ dependencies = [ [[package]] name = "alloy-rlp-derive" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a047897373be4bbb0224c1afdabca92648dc57a9c9ef6e7b0be3aff7a859c83" +checksum = "8037e03c7f462a063f28daec9fda285a9a89da003c552f8637a80b9c8fd96241" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.66", ] [[package]] @@ -281,48 +281,55 @@ dependencies = [ ] [[package]] -name = "anstream" -version = "0.6.12" +name = "anes" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96b09b5178381e0874812a9b157f7fe84982617e48f71f4e3235482775e5b540" +checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" + +[[package]] +name = "anstream" +version = "0.6.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", + "is_terminal_polyfill", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" +checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" [[package]] name = "anstyle-parse" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5" dependencies = [ "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.2" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" dependencies = [ "anstyle", "windows-sys 0.52.0", @@ -330,9 +337,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.82" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" [[package]] name = "arbitrary" @@ -502,9 +509,9 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "asn1-rs" -version = "0.5.2" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f6fd5ddaf0351dff5b8da21b2fb4ff8e08ddd02857f0bf69c47639106c0fff0" +checksum = "22ad1373757efa0f70ec53939aabc7152e1591cb485208052993070ac8d2429d" dependencies = [ "asn1-rs-derive", "asn1-rs-impl", @@ -518,25 +525,25 @@ dependencies = [ [[package]] name = "asn1-rs-derive" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "726535892e8eae7e70657b4c8ea93d26b8553afb1ce617caee529ef96d7dee6c" +checksum = "7378575ff571966e99a744addeff0bff98b8ada0dedf1956d59e634db95eaac1" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.66", "synstructure", ] [[package]] name = "asn1-rs-impl" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2777730b2039ac0f95f093556e61b6d26cebed5393ca6f152717777cec3a42ed" +checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.66", ] [[package]] @@ -594,7 +601,7 @@ checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.66", ] [[package]] @@ -664,14 +671,14 @@ checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.66", ] [[package]] name = "autocfg" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "axum" @@ -730,9 +737,9 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.71" +version = "0.3.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" +checksum = "17c6a35df3749d2e8bb1b7b21a976d82b15548788d2735b9d82f329268f71a11" dependencies = [ "addr2line", "cc", @@ -817,7 +824,7 @@ dependencies = [ "merkle_proof", "oneshot_broadcast", "operation_pool", - "parking_lot 0.12.2", + "parking_lot 0.12.3", "proto_array", "rand", "rayon", @@ -848,10 +855,10 @@ dependencies = [ [[package]] name = "beacon_node" -version = "5.1.3" +version = "5.2.0" dependencies = [ "beacon_chain", - "clap 4.5.4", + "clap", "clap_utils", "client", "directory", @@ -889,14 +896,14 @@ dependencies = [ "lighthouse_network", "logging", "num_cpus", - "parking_lot 0.12.2", + "parking_lot 0.12.3", "serde", "slog", "slot_clock", "strum", "task_executor", "tokio", - "tokio-util 0.6.10", + "tokio-util", "types", ] @@ -1054,10 +1061,10 @@ dependencies = [ [[package]] name = "boot_node" -version = "5.1.3" +version = "5.2.0" dependencies = [ "beacon_node", - "clap 4.5.4", + "clap", "clap_utils", "eth2_network_config", "ethereum_ssz", @@ -1150,9 +1157,9 @@ dependencies = [ [[package]] name = "c-kzg" -version = "1.0.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3130f3d8717cc02e668a896af24984d5d5d4e8bf12e278e982e0f1bd88a0f9af" +checksum = "cdf100c4cea8f207e883ff91ca886d621d8a166cb04971dfaa9bb8fd99ed95df" dependencies = [ "blst", "cc", @@ -1178,9 +1185,9 @@ dependencies = [ [[package]] name = "camino" -version = "1.1.6" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c" +checksum = "e0ec6b951b160caa93cc0c7b209e5a3bff7aae9062213451ac99493cd844c239" dependencies = [ "serde", ] @@ -1202,7 +1209,7 @@ checksum = "eee4243f1f26fc7a42710e7439c149e2b10b05472f88090acce52632f231a73a" dependencies = [ "camino", "cargo-platform", - "semver 1.0.22", + "semver 1.0.23", "serde", "serde_json", "thiserror", @@ -1216,9 +1223,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.0.96" +version = "1.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "065a29261d53ba54260972629f9ca6bffa69bac13cd1fed61420f7fa68b9f8bd" +checksum = "41c270e7540d725e65ac7f1b212ac8ce349719624d7bcff99f8e2e488e8cf03f" dependencies = [ "jobserver", "libc", @@ -1282,6 +1289,33 @@ dependencies = [ "windows-targets 0.52.5", ] +[[package]] +name = "ciborium" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" +dependencies = [ + "ciborium-io", + "ciborium-ll", + "serde", +] + +[[package]] +name = "ciborium-io" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" + +[[package]] +name = "ciborium-ll" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" +dependencies = [ + "ciborium-io", + "half", +] + [[package]] name = "cipher" version = "0.3.0" @@ -1304,26 +1338,15 @@ dependencies = [ [[package]] name = "clang-sys" -version = "1.7.0" +version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67523a3b4be3ce1989d607a828d036249522dd9c1c8de7f4dd2dae43a37369d1" +checksum = "f803f94ecf597339c7a34eed2036ef83f86aaba937f001f7c5b5e251f043f1f9" dependencies = [ "glob", "libc", "libloading", ] -[[package]] -name = "clap" -version = "2.34.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" -dependencies = [ - "bitflags 1.3.2", - "textwrap", - "unicode-width", -] - [[package]] name = "clap" version = "4.5.4" @@ -1342,7 +1365,7 @@ dependencies = [ "anstream", "anstyle", "clap_lex", - "strsim 0.11.0", + "strsim 0.11.1", "terminal_size", ] @@ -1356,7 +1379,7 @@ checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" name = "clap_utils" version = "0.1.0" dependencies = [ - "clap 4.5.4", + "clap", "dirs", "eth2_network_config", "ethereum-types 0.14.1", @@ -1420,9 +1443,9 @@ dependencies = [ [[package]] name = "colorchoice" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" [[package]] name = "compare_fields" @@ -1451,9 +1474,9 @@ dependencies = [ [[package]] name = "const-hex" -version = "1.11.3" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ba00838774b4ab0233e355d26710fbfc8327a05c017f6dc4873f876d1f79f78" +checksum = "94fb8a24a26d37e1ffd45343323dc9fe6654ceea44c12f2fcb3d7ac29e610bc6" dependencies = [ "cfg-if", "cpufeatures", @@ -1516,33 +1539,33 @@ dependencies = [ [[package]] name = "crc32fast" -version = "1.4.0" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" dependencies = [ "cfg-if", ] [[package]] name = "criterion" -version = "0.3.6" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b01d6de93b2b6c65e17c634a26653a29d107b3c98c607c765bf38d041531cd8f" +checksum = "f2b12d017a929603d80db1831cd3a24082f8137ce19c69e6447f54f5fc8d692f" dependencies = [ - "atty", + "anes", "cast", - "clap 2.34.0", + "ciborium", + "clap", "criterion-plot", - "csv", + "is-terminal", "itertools", - "lazy_static", "num-traits", + "once_cell", "oorandom", "plotters", "rayon", "regex", "serde", - "serde_cbor", "serde_derive", "serde_json", "tinytemplate", @@ -1551,9 +1574,9 @@ dependencies = [ [[package]] name = "criterion-plot" -version = "0.4.5" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2673cc8207403546f45f5fd319a974b1e6983ad1a3ee7e6041650013be041876" +checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" dependencies = [ "cast", "itertools", @@ -1561,9 +1584,9 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.12" +version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab3db02a9c5b5121e1e42fbdb1aeb65f5e02624cc58c43f2884c6ccac0b82f95" +checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" dependencies = [ "crossbeam-utils", ] @@ -1589,9 +1612,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.19" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" [[package]] name = "crunchy" @@ -1654,27 +1677,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "csv" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac574ff4d437a7b5ad237ef331c17ccca63c46479e5b5453eb8e10bb99a759fe" -dependencies = [ - "csv-core", - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "csv-core" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5efa2b3d7902f4b634a20cae3c9c4e6209dc4779feb6863329607560143efa70" -dependencies = [ - "memchr", -] - [[package]] name = "ctr" version = "0.7.0" @@ -1737,7 +1739,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.66", ] [[package]] @@ -1833,7 +1835,7 @@ version = "0.1.0" dependencies = [ "beacon_chain", "beacon_node", - "clap 4.5.4", + "clap", "clap_utils", "environment", "hex", @@ -1856,7 +1858,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4355c25cbf99edcb6b4a0e906f6bdc6956eda149e84455bea49696429b2f8e8" dependencies = [ "futures", - "tokio-util 0.7.10", + "tokio-util", ] [[package]] @@ -1896,9 +1898,9 @@ dependencies = [ [[package]] name = "der-parser" -version = "8.2.0" +version = "9.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbd676fbbab537128ef0278adb5576cf363cff6aa22a7b24effe97347cfab61e" +checksum = "5cd0a5c643689626bec213c4d8bd4d96acc8ffdb4ad4bb6bc16abf27d5f4b553" dependencies = [ "asn1-rs", "displaydoc", @@ -1936,7 +1938,7 @@ checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.66", ] [[package]] @@ -1975,7 +1977,7 @@ dependencies = [ "diesel_table_macro_syntax", "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.66", ] [[package]] @@ -1995,7 +1997,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc5557efc453706fed5e4fa85006fe9817c224c3f480a34c7e5959fd700921c5" dependencies = [ - "syn 2.0.60", + "syn 2.0.66", ] [[package]] @@ -2023,7 +2025,7 @@ dependencies = [ name = "directory" version = "0.1.0" dependencies = [ - "clap 4.5.4", + "clap", "clap_utils", "eth2_network_config", ] @@ -2108,7 +2110,7 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.66", ] [[package]] @@ -2208,9 +2210,9 @@ dependencies = [ [[package]] name = "either" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2" +checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" [[package]] name = "elliptic-curve" @@ -2288,7 +2290,7 @@ dependencies = [ "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.66", ] [[package]] @@ -2352,9 +2354,9 @@ dependencies = [ [[package]] name = "errno" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", "windows-sys 0.52.0", @@ -2384,7 +2386,7 @@ dependencies = [ "lazy_static", "lighthouse_metrics", "merkle_proof", - "parking_lot 0.12.2", + "parking_lot 0.12.3", "sensitive_url", "serde", "serde_yaml", @@ -2884,7 +2886,7 @@ dependencies = [ "lighthouse_metrics", "lighthouse_version", "lru", - "parking_lot 0.12.2", + "parking_lot 0.12.3", "pretty_reqwest_error", "rand", "reqwest", @@ -2986,9 +2988,9 @@ checksum = "ec54ac60a7f2ee9a97cad9946f9bf629a3bc6a7ae59e68983dc9318f5a54b81a" [[package]] name = "fiat-crypto" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38793c55593b33412e3ae40c2c9781ffaa6f438f6f8c10f24e71846fbd7ae01e" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" [[package]] name = "field-offset" @@ -3008,12 +3010,6 @@ dependencies = [ "windows-acl", ] -[[package]] -name = "finl_unicode" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fcfdc7a0362c9f4444381a9e697c79d435fe65b52a37466fc2c1184cee9edc6" - [[package]] name = "fixed-hash" version = "0.7.0" @@ -3194,17 +3190,18 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.66", ] [[package]] name = "futures-rustls" -version = "0.24.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35bd3cf68c183738046838e300353e4716c674dc5e56890de4826801a6622a28" +checksum = "a8f2f12607f92c69b12ed746fabf9ca4f5c482cba46679c1a75b874ed7c26adb" dependencies = [ "futures-io", - "rustls 0.21.12", + "rustls 0.23.8", + "rustls-pki-types", ] [[package]] @@ -3297,9 +3294,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "js-sys", @@ -3330,9 +3327,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.28.1" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" [[package]] name = "git-version" @@ -3351,7 +3348,7 @@ checksum = "53010ccb100b96a67bc32c0175f0ed1426b31b655d562898e57325f81c023ac0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.66", ] [[package]] @@ -3427,15 +3424,19 @@ dependencies = [ "indexmap 2.2.6", "slab", "tokio", - "tokio-util 0.7.10", + "tokio-util", "tracing", ] [[package]] name = "half" -version = "1.8.3" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b43ede17f21864e81be2fa654110bf1e793774238d86ef8555c37e6519c0403" +checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +dependencies = [ + "cfg-if", + "crunchy", +] [[package]] name = "hash-db" @@ -3595,7 +3596,7 @@ dependencies = [ "ipconfig", "lru-cache", "once_cell", - "parking_lot 0.12.2", + "parking_lot 0.12.3", "rand", "resolv-conf", "smallvec", @@ -3746,7 +3747,7 @@ dependencies = [ "lru", "network", "operation_pool", - "parking_lot 0.12.2", + "parking_lot 0.12.3", "proto_array", "safe_arith", "sensitive_url", @@ -3878,9 +3879,9 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.3" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa" +checksum = "7b875924a60b96e5d7b9ae7b066540b1dd1cbd90d1828f54c92e02a283351c56" dependencies = [ "bytes", "futures-util", @@ -3888,7 +3889,6 @@ dependencies = [ "http-body 1.0.0", "hyper 1.3.1", "pin-project-lite", - "socket2 0.5.7", "tokio", ] @@ -4004,7 +4004,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" dependencies = [ - "parity-scale-codec 3.6.9", + "parity-scale-codec 3.6.12", ] [[package]] @@ -4082,9 +4082,9 @@ dependencies = [ [[package]] name = "instant" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" dependencies = [ "cfg-if", "js-sys", @@ -4150,6 +4150,12 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "is_terminal_polyfill" +version = "1.70.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" + [[package]] name = "itertools" version = "0.10.5" @@ -4266,9 +4272,9 @@ dependencies = [ [[package]] name = "keccak-asm" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb8515fff80ed850aea4a1595f2e519c003e2a00a82fe168ebf5269196caf444" +checksum = "47a3633291834c4fbebf8673acbc1b04ec9d151418ff9b8e26dcd79129928758" dependencies = [ "digest 0.10.7", "sha3-asm", @@ -4317,31 +4323,28 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "lcli" -version = "5.1.3" +version = "5.2.0" dependencies = [ "account_utils", "beacon_chain", "bls", - "clap 4.5.4", + "clap", "clap_utils", "deposit_contract", "env_logger 0.9.3", "environment", - "eth1_test_rig", "eth2", "eth2_network_config", "eth2_wallet", "ethereum_hashing", "ethereum_ssz", "execution_layer", - "genesis", "hex", "lighthouse_network", "lighthouse_version", "log", "malloc_utils", "rayon", - "sensitive_url", "serde", "serde_json", "serde_yaml", @@ -4378,9 +4381,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.154" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "libflate" @@ -4433,7 +4436,7 @@ dependencies = [ "indexmap 1.9.3", "libc", "mdbx-sys", - "parking_lot 0.12.2", + "parking_lot 0.12.3", "thiserror", ] @@ -4510,7 +4513,7 @@ dependencies = [ "multihash", "multistream-select", "once_cell", - "parking_lot 0.12.2", + "parking_lot 0.12.3", "pin-project", "quick-protobuf", "rand", @@ -4533,7 +4536,7 @@ dependencies = [ "hickory-resolver", "libp2p-core", "libp2p-identity", - "parking_lot 0.12.2", + "parking_lot 0.12.3", "smallvec", "tracing", ] @@ -4633,7 +4636,7 @@ dependencies = [ "libp2p-core", "libp2p-identity", "nohash-hasher", - "parking_lot 0.12.2", + "parking_lot 0.12.3", "rand", "smallvec", "tracing", @@ -4684,9 +4687,9 @@ dependencies = [ [[package]] name = "libp2p-quic" -version = "0.10.2" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0375cdfee57b47b313ef1f0fdb625b78aed770d33a40cf1c294a371ff5e6666" +checksum = "c67296ad4e092e23f92aea3d2bdb6f24eab79c0929ed816dfb460ea2f4567d2b" dependencies = [ "bytes", "futures", @@ -4695,11 +4698,11 @@ dependencies = [ "libp2p-core", "libp2p-identity", "libp2p-tls", - "parking_lot 0.12.2", + "parking_lot 0.12.3", "quinn", "rand", - "ring 0.16.20", - "rustls 0.21.12", + "ring 0.17.8", + "rustls 0.23.8", "socket2 0.5.7", "thiserror", "tokio", @@ -4739,7 +4742,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.66", ] [[package]] @@ -4761,17 +4764,17 @@ dependencies = [ [[package]] name = "libp2p-tls" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93ce7e3c2e7569d685d08ec795157981722ff96e9e9f9eae75df3c29d02b07a5" +checksum = "251b17aebdd29df7e8f80e4d94b782fae42e934c49086e1a81ba23b60a8314f2" dependencies = [ "futures", "futures-rustls", "libp2p-core", "libp2p-identity", "rcgen", - "ring 0.16.20", - "rustls 0.21.12", + "ring 0.17.8", + "rustls 0.23.8", "rustls-webpki 0.101.7", "thiserror", "x509-parser", @@ -4880,9 +4883,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.16" +version = "1.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e143b5e666b2695d28f6bca6497720813f699c9602dd7f5cac91008b8ada7f9" +checksum = "c15da26e5af7e25c90b37a2d75cdbf940cf4a55316de9d84c679c9b8bfabf82e" dependencies = [ "cc", "pkg-config", @@ -4891,7 +4894,7 @@ dependencies = [ [[package]] name = "lighthouse" -version = "5.1.3" +version = "5.2.0" dependencies = [ "account_manager", "account_utils", @@ -4899,7 +4902,7 @@ dependencies = [ "beacon_processor", "bls", "boot_node", - "clap 4.5.4", + "clap", "clap_utils", "database_manager", "directory", @@ -4963,7 +4966,7 @@ dependencies = [ "lighthouse_version", "lru", "lru_cache", - "parking_lot 0.12.2", + "parking_lot 0.12.3", "prometheus-client", "quickcheck", "quickcheck_macros", @@ -4984,9 +4987,9 @@ dependencies = [ "tiny-keccak", "tokio", "tokio-io-timeout", - "tokio-util 0.6.10", + "tokio-util", "types", - "unsigned-varint 0.6.0", + "unsigned-varint 0.8.0", "unused_port", "void", ] @@ -5014,9 +5017,9 @@ checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" [[package]] name = "linux-raw-sys" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "lmdb-rkv" @@ -5070,7 +5073,7 @@ dependencies = [ "chrono", "lazy_static", "lighthouse_metrics", - "parking_lot 0.12.2", + "parking_lot 0.12.3", "serde", "serde_json", "slog", @@ -5129,7 +5132,7 @@ dependencies = [ "lazy_static", "libc", "lighthouse_metrics", - "parking_lot 0.12.2", + "parking_lot 0.12.3", ] [[package]] @@ -5276,7 +5279,7 @@ dependencies = [ "ethereum_ssz", "ethereum_ssz_derive", "itertools", - "parking_lot 0.12.2", + "parking_lot 0.12.3", "rayon", "serde", "smallvec", @@ -5310,9 +5313,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +checksum = "87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdae" dependencies = [ "adler", ] @@ -5415,11 +5418,10 @@ dependencies = [ [[package]] name = "native-tls" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" dependencies = [ - "lazy_static", "libc", "log", "openssl", @@ -5525,7 +5527,7 @@ dependencies = [ "lru_cache", "matches", "operation_pool", - "parking_lot 0.12.2", + "parking_lot 0.12.3", "rand", "rlp", "slog", @@ -5619,11 +5621,10 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +checksum = "c165a9ab64cf766f73521c0dd2cfdff64f488b8f0b3e621face3462d3db536d7" dependencies = [ - "autocfg", "num-integer", "num-traits", ] @@ -5663,9 +5664,9 @@ dependencies = [ [[package]] name = "num-iter" -version = "0.1.44" +version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d869c01cc0c455284163fd0092f1f93835385ccab5a98a0dcc497b2f8bf055a9" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" dependencies = [ "autocfg", "num-integer", @@ -5674,9 +5675,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", "libm", @@ -5694,18 +5695,18 @@ dependencies = [ [[package]] name = "object" -version = "0.32.2" +version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +checksum = "b8ec7ab813848ba4522158d5517a6093db1ded27575b070f4177b8d12b41db5e" dependencies = [ "memchr", ] [[package]] name = "oid-registry" -version = "0.6.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bedf36ffb6ba96c2eb7144ef6270557b52e54b20c0a8e1eb2ff99a6c6959bff" +checksum = "1c958dd45046245b9c3c2547369bb634eb461670b2e7e0de552905801a648d1d" dependencies = [ "asn1-rs", ] @@ -5720,7 +5721,7 @@ checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" name = "oneshot_broadcast" version = "0.1.0" dependencies = [ - "parking_lot 0.12.2", + "parking_lot 0.12.3", ] [[package]] @@ -5783,7 +5784,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.66", ] [[package]] @@ -5794,9 +5795,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-src" -version = "300.2.3+3.2.1" +version = "300.3.0+3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cff92b6f71555b61bb9315f7c64da3ca43d87531622120fea0195fc761b4843" +checksum = "eba8804a1c5765b18c4b3f907e6897ebabeedebc9830e1a0046c4a4cf44663e1" dependencies = [ "cc", ] @@ -5827,7 +5828,7 @@ dependencies = [ "lazy_static", "lighthouse_metrics", "maplit", - "parking_lot 0.12.2", + "parking_lot 0.12.3", "rand", "rayon", "serde", @@ -5871,15 +5872,15 @@ dependencies = [ [[package]] name = "parity-scale-codec" -version = "3.6.9" +version = "3.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "881331e34fa842a2fb61cc2db9643a8fedc615e47cfcc52597d1af0db9a7e8fe" +checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee" dependencies = [ "arrayvec", "bitvec 1.0.1", "byte-slice-cast", "impl-trait-for-tuples", - "parity-scale-codec-derive 3.6.9", + "parity-scale-codec-derive 3.6.12", "serde", ] @@ -5897,11 +5898,11 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "3.6.9" +version = "3.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be30eaf4b0a9fba5336683b38de57bb86d179a35862ba6bfcf57625d006bde5b" +checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c" dependencies = [ - "proc-macro-crate 2.0.0", + "proc-macro-crate 3.1.0", "proc-macro2", "quote", "syn 1.0.109", @@ -5926,9 +5927,9 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.12.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e4af0ca4f6caed20e900d564c242b8e5d4903fdacf31d3daf527b66fe6f42fb" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", "parking_lot_core 0.9.10", @@ -5974,9 +5975,9 @@ dependencies = [ [[package]] name = "paste" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] name = "pbkdf2" @@ -6095,7 +6096,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.66", ] [[package]] @@ -6150,9 +6151,9 @@ checksum = "db23d408679286588f4d4644f965003d056e3dd5abcaaa938116871d7ce2fee7" [[package]] name = "plotters" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2c224ba00d7cadd4d5c660deaf2098e5e80e07846537c51f9cfa4be50c1fd45" +checksum = "a15b6eccb8484002195a3e44fe65a4ce8e93a625797a063735536fd59cb01cf3" dependencies = [ "num-traits", "plotters-backend", @@ -6163,15 +6164,15 @@ dependencies = [ [[package]] name = "plotters-backend" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e76628b4d3a7581389a35d5b6e2139607ad7c75b17aed325f210aa91f4a9609" +checksum = "414cec62c6634ae900ea1c56128dfe87cf63e7caece0852ec76aba307cebadb7" [[package]] name = "plotters-svg" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38f6d39893cca0701371e3c27294f09797214b86f1fb951b89ade8ec04e2abab" +checksum = "81b30686a7d9c3e010b84284bdd26a29f2138574f52f5eb6f794fc0ad924e705" dependencies = [ "plotters-backend", ] @@ -6332,18 +6333,18 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "2.0.0" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8" +checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" dependencies = [ - "toml_edit 0.20.7", + "toml_edit 0.21.1", ] [[package]] name = "proc-macro2" -version = "1.0.81" +version = "1.0.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba" +checksum = "ec96c6a92621310b51366f1e28d05ef11489516e93be030060e5fc12024a49d6" dependencies = [ "unicode-ident", ] @@ -6365,15 +6366,15 @@ dependencies = [ [[package]] name = "prometheus" -version = "0.13.3" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "449811d15fbdf5ceb5c1144416066429cf82316e2ec8ce0c1f6f8a02e7bbcf8c" +checksum = "3d33c28a30771f7f96db69893f78b857f7450d7e0237e9c8fc6427a81bae7ed1" dependencies = [ "cfg-if", "fnv", "lazy_static", "memchr", - "parking_lot 0.12.2", + "parking_lot 0.12.3", "protobuf", "thiserror", ] @@ -6386,7 +6387,7 @@ checksum = "c1ca959da22a332509f2a73ae9e5f23f9dcfc31fd3a54d71f159495bd5909baa" dependencies = [ "dtoa", "itoa", - "parking_lot 0.12.2", + "parking_lot 0.12.3", "prometheus-client-derive-encode", ] @@ -6398,7 +6399,7 @@ checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.66", ] [[package]] @@ -6524,9 +6525,9 @@ dependencies = [ [[package]] name = "quinn" -version = "0.10.2" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cc2c5017e4b43d5995dcea317bc46c1e09404c0a9664d2908f7f02dfe943d75" +checksum = "904e3d3ba178131798c6d9375db2b13b34337d489b089fc5ba0825a2ff1bee73" dependencies = [ "bytes", "futures-io", @@ -6534,7 +6535,7 @@ dependencies = [ "quinn-proto", "quinn-udp", "rustc-hash", - "rustls 0.21.12", + "rustls 0.23.8", "thiserror", "tokio", "tracing", @@ -6542,15 +6543,15 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.10.6" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "141bf7dfde2fbc246bfd3fe12f2455aa24b0fbd9af535d8c86c7bd1381ff2b1a" +checksum = "e974563a4b1c2206bbc61191ca4da9c22e4308b4c455e8906751cc7828393f08" dependencies = [ "bytes", "rand", - "ring 0.16.20", + "ring 0.17.8", "rustc-hash", - "rustls 0.21.12", + "rustls 0.23.8", "slab", "thiserror", "tinyvec", @@ -6559,15 +6560,15 @@ dependencies = [ [[package]] name = "quinn-udp" -version = "0.4.1" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "055b4e778e8feb9f93c4e439f71dc2156ef13360b432b799e179a8c4cdf0b1d7" +checksum = "e4f0def2590301f4f667db5a77f9694fb004f82796dc1a8b1508fafa3d0e8b72" dependencies = [ - "bytes", "libc", + "once_cell", "socket2 0.5.7", "tracing", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -6586,7 +6587,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51de85fb3fb6524929c8a2eb85e6b6d363de4e8c48f9e2c2eac4944abc181c93" dependencies = [ "log", - "parking_lot 0.12.2", + "parking_lot 0.12.3", "scheduled-thread-pool", ] @@ -6800,7 +6801,7 @@ dependencies = [ "tokio", "tokio-native-tls", "tokio-rustls 0.24.1", - "tokio-util 0.7.10", + "tokio-util", "tower-service", "url", "wasm-bindgen", @@ -6946,7 +6947,7 @@ dependencies = [ "fastrlp", "num-bigint", "num-traits", - "parity-scale-codec 3.6.9", + "parity-scale-codec 3.6.12", "primitive-types 0.12.2", "proptest", "rand", @@ -6979,9 +6980,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc-hash" @@ -7010,7 +7011,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.22", + "semver 1.0.23", ] [[package]] @@ -7045,7 +7046,7 @@ dependencies = [ "bitflags 2.5.0", "errno", "libc", - "linux-raw-sys 0.4.13", + "linux-raw-sys 0.4.14", "windows-sys 0.52.0", ] @@ -7070,7 +7071,21 @@ dependencies = [ "log", "ring 0.17.8", "rustls-pki-types", - "rustls-webpki 0.102.3", + "rustls-webpki 0.102.4", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls" +version = "0.23.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79adb16721f56eb2d843e67676896a61ce7a0fa622dc18d3e372477a029d2740" +dependencies = [ + "once_cell", + "ring 0.17.8", + "rustls-pki-types", + "rustls-webpki 0.102.4", "subtle", "zeroize", ] @@ -7096,9 +7111,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.5.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "beb461507cee2c2ff151784c52762cf4d9ff6a61f3e80968600ed24fa837fa54" +checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" [[package]] name = "rustls-webpki" @@ -7112,9 +7127,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.102.3" +version = "0.102.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3bce581c0dd41bce533ce695a1437fa16a7ab5ac3ccfa99fe1a620a7885eabf" +checksum = "ff448f7e92e913c4b7d4c6d8e4540a1724b319b4152b8aef6d4cf8339712b33e" dependencies = [ "ring 0.17.8", "rustls-pki-types", @@ -7123,9 +7138,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.15" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80af6f9131f277a45a3fba6ce8e2258037bb0477a67e610d3c1fe046ab31de47" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" [[package]] name = "rusty-fork" @@ -7152,9 +7167,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "safe_arith" @@ -7180,23 +7195,23 @@ dependencies = [ [[package]] name = "scale-info" -version = "2.11.2" +version = "2.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c453e59a955f81fb62ee5d596b450383d699f152d350e9d23a0db2adb78e4c0" +checksum = "eca070c12893629e2cc820a9761bedf6ce1dcddc9852984d1dc734b8bd9bd024" dependencies = [ "cfg-if", "derive_more", - "parity-scale-codec 3.6.9", + "parity-scale-codec 3.6.12", "scale-info-derive", ] [[package]] name = "scale-info-derive" -version = "2.11.2" +version = "2.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18cf6c6447f813ef19eb450e985bcce6705f9ce7660db221b59093d15c79c4b7" +checksum = "2d35494501194174bda522a32605929eefc9ecf7e0a326c26db1fdd85881eb62" dependencies = [ - "proc-macro-crate 1.3.1", + "proc-macro-crate 3.1.0", "proc-macro2", "quote", "syn 1.0.109", @@ -7217,7 +7232,7 @@ version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3cbc66816425a074528352f5789333ecff06ca41b36b0b0efdfbb29edc391a19" dependencies = [ - "parking_lot 0.12.2", + "parking_lot 0.12.3", ] [[package]] @@ -7284,11 +7299,11 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.10.0" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "770452e37cad93e0a50d5abc3990d2bc351c36d0328f86cefec2f2fb206eaef6" +checksum = "c627723fd09706bacdb5cf41499e95098555af3c3c29d014dc3c458ef6be11c0" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.5.0", "core-foundation", "core-foundation-sys", "libc", @@ -7297,9 +7312,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.10.0" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f3cc463c0ef97e11c3461a9d3787412d30e8e7eb907c79180c4a57bf7c04ef" +checksum = "317936bbbd05227752583946b9e66d7ce3b489f84e11a94a510b4437fef407d7" dependencies = [ "core-foundation-sys", "libc", @@ -7316,9 +7331,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" dependencies = [ "serde", ] @@ -7348,9 +7363,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.200" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddc6f9cc94d67c0e21aaf7eda3a010fd3af78ebf6e096aa6e2e13c79749cce4f" +checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" dependencies = [ "serde_derive", ] @@ -7365,32 +7380,22 @@ dependencies = [ "serde_urlencoded", ] -[[package]] -name = "serde_cbor" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" -dependencies = [ - "half", - "serde", -] - [[package]] name = "serde_derive" -version = "1.0.200" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "856f046b9400cee3c8c94ed572ecdb752444c24528c035cd35882aad6f492bcb" +checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.66", ] [[package]] name = "serde_json" -version = "1.0.116" +version = "1.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813" +checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" dependencies = [ "itoa", "ryu", @@ -7415,14 +7420,14 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.66", ] [[package]] name = "serde_spanned" -version = "0.6.5" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" +checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0" dependencies = [ "serde", ] @@ -7533,9 +7538,9 @@ dependencies = [ [[package]] name = "sha3-asm" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bac61da6b35ad76b195eb4771210f947734321a8d81d7738e1580d953bc7a15e" +checksum = "a9b57fd861253bff08bb1919e995f90ba8f4889de2726091c8876f3a4e823b40" dependencies = [ "cc", "cfg-if", @@ -7601,13 +7606,13 @@ dependencies = [ name = "simulator" version = "0.2.0" dependencies = [ - "clap 4.5.4", + "clap", "env_logger 0.9.3", "eth2_network_config", "execution_layer", "futures", "node_test_rig", - "parking_lot 0.12.2", + "parking_lot 0.12.3", "rayon", "sensitive_url", "serde_json", @@ -7648,7 +7653,7 @@ dependencies = [ "logging", "lru", "maplit", - "parking_lot 0.12.2", + "parking_lot 0.12.3", "rand", "rayon", "safe_arith", @@ -7804,7 +7809,7 @@ version = "0.2.0" dependencies = [ "lazy_static", "lighthouse_metrics", - "parking_lot 0.12.2", + "parking_lot 0.12.3", "types", ] @@ -7972,7 +7977,7 @@ dependencies = [ "leveldb", "lighthouse_metrics", "lru", - "parking_lot 0.12.2", + "parking_lot 0.12.3", "serde", "slog", "sloggers", @@ -7984,13 +7989,13 @@ dependencies = [ [[package]] name = "stringprep" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb41d74e231a107a1b4ee36bd1214b11285b77768d2e3824aedafa988fd36ee6" +checksum = "7b4df3d392d81bd458a8a621b8bffbd2302a12ffe288a9d931670948749463b1" dependencies = [ - "finl_unicode", "unicode-bidi", "unicode-normalization", + "unicode-properties", ] [[package]] @@ -8001,9 +8006,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "strsim" -version = "0.11.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "strum" @@ -8068,9 +8073,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.60" +version = "2.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3" +checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" dependencies = [ "proc-macro2", "quote", @@ -8091,14 +8096,13 @@ checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" [[package]] name = "synstructure" -version = "0.12.6" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", - "unicode-xid", + "syn 2.0.66", ] [[package]] @@ -8142,7 +8146,7 @@ name = "system_health" version = "0.1.0" dependencies = [ "lighthouse_network", - "parking_lot 0.12.2", + "parking_lot 0.12.3", "serde", "sysinfo", "types", @@ -8262,33 +8266,24 @@ dependencies = [ "sha2 0.10.8", ] -[[package]] -name = "textwrap" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" -dependencies = [ - "unicode-width", -] - [[package]] name = "thiserror" -version = "1.0.59" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0126ad08bff79f29fc3ae6a55cc72352056dfff61e3ff8bb7129476d44b23aa" +checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.59" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1cd413b5d558b4c5bf3680e324a6fa5014e7b7c067a51e69dbdf47eb7148b66" +checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.66", ] [[package]] @@ -8441,7 +8436,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.66", ] [[package]] @@ -8467,7 +8462,7 @@ dependencies = [ "futures-channel", "futures-util", "log", - "parking_lot 0.12.2", + "parking_lot 0.12.3", "percent-encoding", "phf", "pin-project-lite", @@ -8476,7 +8471,7 @@ dependencies = [ "rand", "socket2 0.5.7", "tokio", - "tokio-util 0.7.10", + "tokio-util", "whoami", ] @@ -8510,40 +8505,24 @@ dependencies = [ "futures-core", "pin-project-lite", "tokio", - "tokio-util 0.7.10", + "tokio-util", ] [[package]] name = "tokio-util" -version = "0.6.10" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36943ee01a6d67977dd3f84a5a1d2efeb4ada3a1ae771cadfaa535d9d9fc6507" +checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" dependencies = [ "bytes", "futures-core", "futures-io", "futures-sink", - "log", "pin-project-lite", "slab", "tokio", ] -[[package]] -name = "tokio-util" -version = "0.7.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", - "slab", - "tokio", - "tracing", -] - [[package]] name = "toml" version = "0.5.11" @@ -8567,9 +8546,9 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.5" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" dependencies = [ "serde", ] @@ -8589,9 +8568,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.20.7" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81" +checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" dependencies = [ "indexmap 2.2.6", "toml_datetime", @@ -8658,7 +8637,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.66", ] [[package]] @@ -8763,9 +8742,9 @@ dependencies = [ [[package]] name = "triomphe" -version = "0.1.11" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "859eb650cfee7434994602c3a68b25d77ad9e68c8a6cd491616ef86661382eb3" +checksum = "1b2cb4fbb9995eeb36ac86fadf24031ccd58f99d6b4b2d7b911db70bddb80d90" dependencies = [ "serde", "stable_deref_trait", @@ -8811,7 +8790,7 @@ dependencies = [ "merkle_proof", "metastruct", "milhouse", - "parking_lot 0.12.2", + "parking_lot 0.12.3", "paste", "rand", "rand_xorshift", @@ -8898,10 +8877,10 @@ dependencies = [ ] [[package]] -name = "unicode-width" -version = "0.1.12" +name = "unicode-properties" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6" +checksum = "e4259d9d4425d9f0661581b804cb85fe66a4c631cadd8f490d1c13a35d5d9291" [[package]] name = "unicode-xid" @@ -8935,16 +8914,6 @@ version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" -[[package]] -name = "unsigned-varint" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35581ff83d4101e58b582e607120c7f5ffb17e632a980b1f38334d76b36908b2" -dependencies = [ - "bytes", - "tokio-util 0.6.10", -] - [[package]] name = "unsigned-varint" version = "0.7.2" @@ -8960,6 +8929,10 @@ name = "unsigned-varint" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb066959b24b5196ae73cb057f45598450d2c5f71460e98c49b738086eff9c06" +dependencies = [ + "bytes", + "tokio-util", +] [[package]] name = "untrusted" @@ -8979,7 +8952,7 @@ version = "0.1.0" dependencies = [ "lazy_static", "lru_cache", - "parking_lot 0.12.2", + "parking_lot 0.12.3", ] [[package]] @@ -9016,7 +8989,7 @@ dependencies = [ "account_utils", "bincode", "bls", - "clap 4.5.4", + "clap", "clap_utils", "deposit_contract", "directory", @@ -9039,7 +9012,7 @@ dependencies = [ "logging", "malloc_utils", "monitoring_api", - "parking_lot 0.12.2", + "parking_lot 0.12.3", "rand", "reqwest", "ring 0.16.20", @@ -9088,7 +9061,7 @@ name = "validator_manager" version = "0.1.0" dependencies = [ "account_utils", - "clap 4.5.4", + "clap", "clap_utils", "environment", "eth2", @@ -9188,7 +9161,7 @@ dependencies = [ "serde_urlencoded", "tokio", "tokio-rustls 0.25.0", - "tokio-util 0.7.10", + "tokio-util", "tower-service", "tracing", ] @@ -9246,7 +9219,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.66", "wasm-bindgen-shared", ] @@ -9280,7 +9253,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.66", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -9327,7 +9300,7 @@ dependencies = [ "beacon_chain", "beacon_node", "bls", - "clap 4.5.4", + "clap", "clap_utils", "diesel", "diesel_migrations", @@ -9384,7 +9357,7 @@ dependencies = [ "eth2_network_config", "futures", "lazy_static", - "parking_lot 0.12.2", + "parking_lot 0.12.3", "reqwest", "serde", "serde_json", @@ -9771,9 +9744,9 @@ dependencies = [ [[package]] name = "x509-parser" -version = "0.15.1" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7069fba5b66b9193bd2c5d3d4ff12b839118f6bcbef5328efafafb5395cf63da" +checksum = "fcbc162f30700d6f3f82a24bf7cc62ffe7caea42c0b2cba8bf7f3ae50cf51f69" dependencies = [ "asn1-rs", "data-encoding", @@ -9821,7 +9794,7 @@ dependencies = [ "futures", "log", "nohash-hasher", - "parking_lot 0.12.2", + "parking_lot 0.12.3", "pin-project", "rand", "static_assertions", @@ -9837,7 +9810,7 @@ dependencies = [ "instant", "log", "nohash-hasher", - "parking_lot 0.12.2", + "parking_lot 0.12.3", "pin-project", "rand", "static_assertions", @@ -9854,29 +9827,29 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.7.32" +version = "0.7.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.32" +version = "0.7.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.66", ] [[package]] name = "zeroize" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" dependencies = [ "zeroize_derive", ] @@ -9889,7 +9862,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.66", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 5fe9812bc6..1059c74625 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -107,7 +107,7 @@ clap = { version = "4.5.4", features = ["cargo", "wrap_help"] } # feature ourselves when desired. c-kzg = { version = "1", default-features = false } compare_fields_derive = { path = "common/compare_fields_derive" } -criterion = "0.3" +criterion = "0.5" delay_map = "0.3" derivative = "2" dirs = "3" @@ -168,7 +168,7 @@ sysinfo = "0.26" tempfile = "3" tokio = { version = "1", features = ["rt-multi-thread", "sync", "signal"] } tokio-stream = { version = "0.1", features = ["sync"] } -tokio-util = { version = "0.6", features = ["codec", "compat", "time"] } +tokio-util = { version = "0.7", features = ["codec", "compat", "time"] } tracing = "0.1.40" tracing-appender = "0.2" tracing-core = "0.1" diff --git a/Dockerfile b/Dockerfile index 901c1b83d6..e0c48699bf 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM rust:1.75.0-bullseye AS builder +FROM rust:1.78.0-bullseye AS builder RUN apt-get update && apt-get -y upgrade && apt-get install -y cmake libclang-dev COPY . lighthouse ARG FEATURES diff --git a/account_manager/src/lib.rs b/account_manager/src/lib.rs index f1160fff9c..534939cf6b 100644 --- a/account_manager/src/lib.rs +++ b/account_manager/src/lib.rs @@ -18,7 +18,7 @@ pub const WALLETS_DIR_FLAG: &str = "wallets-dir"; pub fn cli_app() -> Command { Command::new(CMD) - .visible_aliases(["a", "am", "account", CMD]) + .visible_aliases(["a", "am", "account"]) .about("Utilities for generating and managing Ethereum 2.0 accounts.") .display_order(0) .arg( diff --git a/beacon_node/Cargo.toml b/beacon_node/Cargo.toml index e2f6c681c1..b95720e807 100644 --- a/beacon_node/Cargo.toml +++ b/beacon_node/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "beacon_node" -version = "5.1.3" +version = "5.2.0" authors = [ "Paul Hauner ", "Age Manning ( if let Some(slasher) = chain.slasher.as_ref() { let (indexed_attestation, check_signature, err) = match slash_info { SignatureNotChecked(attestation, err) => { + if let Error::UnknownHeadBlock { .. } = err { + if attestation.data.beacon_block_root == attestation.data.target.root { + return err; + } + } match obtain_indexed_attestation_and_committees_per_slot(chain, attestation) { Ok((indexed, _)) => (indexed, true, err), Err(e) => { diff --git a/beacon_node/beacon_chain/src/beacon_chain.rs b/beacon_node/beacon_chain/src/beacon_chain.rs index a0c2ab3f23..3d14747a5f 100644 --- a/beacon_node/beacon_chain/src/beacon_chain.rs +++ b/beacon_node/beacon_chain/src/beacon_chain.rs @@ -3400,6 +3400,20 @@ impl BeaconChain { "payload_verification_handle", ) .await??; + + // Remove block components from da_checker AFTER completing block import. Then we can assert + // the following invariant: + // > A valid unfinalized block is either in fork-choice or da_checker. + // + // If we remove the block when it becomes available, there's some time window during + // `import_block` where the block is nowhere. Consumers of the da_checker can handle the + // extend time a block may exist in the da_checker. + // + // If `import_block` errors (only errors with internal errors), the pending components will + // be pruned on data_availability_checker maintenance as finality advances. + self.data_availability_checker + .remove_pending_components(block_root); + Ok(AvailabilityProcessingStatus::Imported(block_root)) } diff --git a/beacon_node/beacon_chain/src/data_availability_checker.rs b/beacon_node/beacon_chain/src/data_availability_checker.rs index 57f718f62d..e0347d81c3 100644 --- a/beacon_node/beacon_chain/src/data_availability_checker.rs +++ b/beacon_node/beacon_chain/src/data_availability_checker.rs @@ -164,6 +164,11 @@ impl DataAvailabilityChecker { .put_pending_executed_block(executed_block) } + pub fn remove_pending_components(&self, block_root: Hash256) { + self.availability_cache + .remove_pending_components(block_root) + } + /// Verifies kzg commitments for an RpcBlock, returns a `MaybeAvailableBlock` that may /// include the fully available block. /// diff --git a/beacon_node/beacon_chain/src/data_availability_checker/overflow_lru_cache.rs b/beacon_node/beacon_chain/src/data_availability_checker/overflow_lru_cache.rs index e350181c86..adc1a1e202 100644 --- a/beacon_node/beacon_chain/src/data_availability_checker/overflow_lru_cache.rs +++ b/beacon_node/beacon_chain/src/data_availability_checker/overflow_lru_cache.rs @@ -498,6 +498,21 @@ impl Critical { } } + /// Removes and returns the pending_components corresponding to + /// the `block_root` or `None` if it does not exist + pub fn remove_pending_components(&mut self, block_root: Hash256) { + match self.in_memory.pop_entry(&block_root) { + Some { .. } => {} + None => { + // not in memory, is it in the store? + // We don't need to remove the data from the store as we have removed it from + // `store_keys` so we won't go looking for it on disk. The maintenance thread + // will remove it from disk the next time it runs. + self.store_keys.remove(&block_root); + } + } + } + /// Returns the number of pending component entries in memory. pub fn num_blocks(&self) -> usize { self.in_memory.len() @@ -607,6 +622,11 @@ impl OverflowLRUCache { pending_components.merge_blobs(fixed_blobs); if pending_components.is_available() { + write_lock.put_pending_components( + block_root, + pending_components.clone(), + &self.overflow_store, + )?; // No need to hold the write lock anymore drop(write_lock); pending_components.make_available(|diet_block| { @@ -646,6 +666,11 @@ impl OverflowLRUCache { // Check if we have all components and entire set is consistent. if pending_components.is_available() { + write_lock.put_pending_components( + block_root, + pending_components.clone(), + &self.overflow_store, + )?; // No need to hold the write lock anymore drop(write_lock); pending_components.make_available(|diet_block| { @@ -661,6 +686,10 @@ impl OverflowLRUCache { } } + pub fn remove_pending_components(&self, block_root: Hash256) { + self.critical.write().remove_pending_components(block_root); + } + /// write all in memory objects to disk pub fn write_all_to_disk(&self) -> Result<(), AvailabilityCheckError> { let maintenance_lock = self.maintenance_lock.lock(); @@ -1195,10 +1224,17 @@ mod test { matches!(availability, Availability::Available(_)), "block doesn't have blobs, should be available" ); + assert_eq!( + cache.critical.read().in_memory.len(), + 1, + "cache should still have block as it hasn't been imported yet" + ); + // remove the blob to simulate successful import + cache.remove_pending_components(root); assert_eq!( cache.critical.read().in_memory.len(), 0, - "cache should be empty because we don't have blobs" + "cache should be empty now that block has been imported" ); } else { assert!( @@ -1263,6 +1299,12 @@ mod test { "block should be available: {:?}", availability ); + assert!( + cache.critical.read().in_memory.len() == 1, + "cache should still have available block until import" + ); + // remove the blob to simulate successful import + cache.remove_pending_components(root); assert!( cache.critical.read().in_memory.is_empty(), "cache should be empty now that all components available" @@ -1378,6 +1420,8 @@ mod test { .expect("should put blob"); if blob_index == expected_blobs - 1 { assert!(matches!(availability, Availability::Available(_))); + // remove the block from the cache to simulate import + cache.remove_pending_components(roots[0]); } else { // the first block should be brought back into memory assert!( diff --git a/beacon_node/beacon_processor/src/lib.rs b/beacon_node/beacon_processor/src/lib.rs index fee55b39ad..5bf13d82b7 100644 --- a/beacon_node/beacon_processor/src/lib.rs +++ b/beacon_node/beacon_processor/src/lib.rs @@ -60,7 +60,9 @@ use std::time::Duration; use task_executor::TaskExecutor; use tokio::sync::mpsc; use tokio::sync::mpsc::error::TrySendError; -use types::{Attestation, Hash256, SignedAggregateAndProof, SubnetId}; +use types::{ + Attestation, BeaconState, ChainSpec, Hash256, RelativeEpoch, SignedAggregateAndProof, SubnetId, +}; use types::{EthSpec, Slot}; use work_reprocessing_queue::IgnoredRpcBlock; use work_reprocessing_queue::{ @@ -85,123 +87,98 @@ const MAX_IDLE_QUEUE_LEN: usize = 16_384; /// The maximum size of the channel for re-processing work events. const DEFAULT_MAX_SCHEDULED_WORK_QUEUE_LEN: usize = 3 * DEFAULT_MAX_WORK_EVENT_QUEUE_LEN / 4; -/// The maximum number of queued `Attestation` objects that will be stored before we start dropping -/// them. -const MAX_UNAGGREGATED_ATTESTATION_QUEUE_LEN: usize = 16_384; +/// Over-provision queues based on active validator count by some factor. The beacon chain has +/// strict churns that prevent the validator set size from changing rapidly. By over-provisioning +/// slightly, we don't need to adjust the queues during the lifetime of a process. +const ACTIVE_VALIDATOR_COUNT_OVERPROVISION_PERCENT: usize = 110; -/// The maximum number of queued `Attestation` objects that will be stored before we start dropping -/// them. -const MAX_UNAGGREGATED_ATTESTATION_REPROCESS_QUEUE_LEN: usize = 8_192; +/// Maximum number of queued items that will be stored before dropping them +pub struct BeaconProcessorQueueLengths { + aggregate_queue: usize, + attestation_queue: usize, + unknown_block_aggregate_queue: usize, + unknown_block_attestation_queue: usize, + sync_message_queue: usize, + sync_contribution_queue: usize, + gossip_voluntary_exit_queue: usize, + gossip_proposer_slashing_queue: usize, + gossip_attester_slashing_queue: usize, + finality_update_queue: usize, + optimistic_update_queue: usize, + unknown_light_client_update_queue: usize, + rpc_block_queue: usize, + rpc_blob_queue: usize, + chain_segment_queue: usize, + backfill_chain_segment: usize, + gossip_block_queue: usize, + gossip_blob_queue: usize, + delayed_block_queue: usize, + status_queue: usize, + bbrange_queue: usize, + bbroots_queue: usize, + blbroots_queue: usize, + blbrange_queue: usize, + gossip_bls_to_execution_change_queue: usize, + lc_bootstrap_queue: usize, + lc_optimistic_update_queue: usize, + lc_finality_update_queue: usize, + api_request_p0_queue: usize, + api_request_p1_queue: usize, +} -/// The maximum number of queued `SignedAggregateAndProof` objects that will be stored before we -/// start dropping them. -const MAX_AGGREGATED_ATTESTATION_QUEUE_LEN: usize = 4_096; +impl BeaconProcessorQueueLengths { + pub fn from_state( + state: &BeaconState, + spec: &ChainSpec, + ) -> Result { + let active_validator_count = + match state.get_cached_active_validator_indices(RelativeEpoch::Current) { + Ok(indices) => indices.len(), + Err(_) => state + .get_active_validator_indices(state.current_epoch(), spec) + .map_err(|e| format!("Error computing active indices: {:?}", e))? + .len(), + }; + let active_validator_count = + (ACTIVE_VALIDATOR_COUNT_OVERPROVISION_PERCENT * active_validator_count) / 100; + let slots_per_epoch = E::slots_per_epoch() as usize; -/// The maximum number of queued `SignedAggregateAndProof` objects that will be stored before we -/// start dropping them. -const MAX_AGGREGATED_ATTESTATION_REPROCESS_QUEUE_LEN: usize = 1_024; - -/// The maximum number of queued `SignedBeaconBlock` objects received on gossip that will be stored -/// before we start dropping them. -const MAX_GOSSIP_BLOCK_QUEUE_LEN: usize = 1_024; - -/// The maximum number of queued `BlobSidecar` objects received on gossip that -/// will be stored before we start dropping them. -const MAX_GOSSIP_BLOB_QUEUE_LEN: usize = 1_024; - -/// The maximum number of queued `SignedBeaconBlock` objects received prior to their slot (but -/// within acceptable clock disparity) that will be queued before we start dropping them. -const MAX_DELAYED_BLOCK_QUEUE_LEN: usize = 1_024; - -/// The maximum number of queued `SignedVoluntaryExit` objects received on gossip that will be stored -/// before we start dropping them. -const MAX_GOSSIP_EXIT_QUEUE_LEN: usize = 4_096; - -/// The maximum number of queued `ProposerSlashing` objects received on gossip that will be stored -/// before we start dropping them. -const MAX_GOSSIP_PROPOSER_SLASHING_QUEUE_LEN: usize = 4_096; - -/// The maximum number of queued `AttesterSlashing` objects received on gossip that will be stored -/// before we start dropping them. -const MAX_GOSSIP_ATTESTER_SLASHING_QUEUE_LEN: usize = 4_096; - -/// The maximum number of queued `LightClientFinalityUpdate` objects received on gossip that will be stored -/// before we start dropping them. -const MAX_GOSSIP_FINALITY_UPDATE_QUEUE_LEN: usize = 1_024; - -/// The maximum number of queued `LightClientOptimisticUpdate` objects received on gossip that will be stored -/// before we start dropping them. -const MAX_GOSSIP_OPTIMISTIC_UPDATE_QUEUE_LEN: usize = 1_024; - -/// The maximum number of queued `LightClientOptimisticUpdate` objects received on gossip that will be stored -/// for reprocessing before we start dropping them. -const MAX_GOSSIP_OPTIMISTIC_UPDATE_REPROCESS_QUEUE_LEN: usize = 128; - -/// The maximum number of queued `SyncCommitteeMessage` objects that will be stored before we start dropping -/// them. -const MAX_SYNC_MESSAGE_QUEUE_LEN: usize = 2048; - -/// The maximum number of queued `SignedContributionAndProof` objects that will be stored before we -/// start dropping them. -const MAX_SYNC_CONTRIBUTION_QUEUE_LEN: usize = 1024; - -/// The maximum number of queued `SignedBeaconBlock` objects received from the network RPC that -/// will be stored before we start dropping them. -const MAX_RPC_BLOCK_QUEUE_LEN: usize = 1_024; - -/// The maximum number of queued `BlobSidecar` objects received from the network RPC that -/// will be stored before we start dropping them. -const MAX_RPC_BLOB_QUEUE_LEN: usize = 1_024; - -/// The maximum number of queued `Vec` objects received during syncing that will -/// be stored before we start dropping them. -const MAX_CHAIN_SEGMENT_QUEUE_LEN: usize = 64; - -/// The maximum number of queued `StatusMessage` objects received from the network RPC that will be -/// stored before we start dropping them. -const MAX_STATUS_QUEUE_LEN: usize = 1_024; - -/// The maximum number of queued `BlocksByRangeRequest` objects received from the network RPC that -/// will be stored before we start dropping them. -const MAX_BLOCKS_BY_RANGE_QUEUE_LEN: usize = 1_024; - -/// The maximum number of queued `BlobsByRangeRequest` objects received from the network RPC that -/// will be stored before we start dropping them. -const MAX_BLOBS_BY_RANGE_QUEUE_LEN: usize = 1024; - -/// The maximum number of queued `BlocksByRootRequest` objects received from the network RPC that -/// will be stored before we start dropping them. -const MAX_BLOCKS_BY_ROOTS_QUEUE_LEN: usize = 1_024; - -/// The maximum number of queued `BlobsByRootRequest` objects received from the network RPC that -/// will be stored before we start dropping them. -const MAX_BLOBS_BY_ROOTS_QUEUE_LEN: usize = 1_024; - -/// Maximum number of `SignedBlsToExecutionChange` messages to queue before dropping them. -/// -/// This value is set high to accommodate the large spike that is expected immediately after Capella -/// is activated. -const MAX_BLS_TO_EXECUTION_CHANGE_QUEUE_LEN: usize = 16_384; - -/// The maximum number of queued `LightClientBootstrapRequest` objects received from the network RPC that -/// will be stored before we start dropping them. -const MAX_LIGHT_CLIENT_BOOTSTRAP_QUEUE_LEN: usize = 1_024; - -/// The maximum number of queued `LightClientOptimisticUpdateRequest` objects received from the network RPC that -/// will be stored before we start dropping them. -const MAX_LIGHT_CLIENT_OPTIMISTIC_UPDATE_QUEUE_LEN: usize = 512; - -/// The maximum number of queued `LightClientFinalityUpdateRequest` objects received from the network RPC that -/// will be stored before we start dropping them. -const MAX_LIGHT_CLIENT_FINALITY_UPDATE_QUEUE_LEN: usize = 512; - -/// The maximum number of priority-0 (highest priority) messages that will be queued before -/// they begin to be dropped. -const MAX_API_REQUEST_P0_QUEUE_LEN: usize = 1_024; - -/// The maximum number of priority-1 (second-highest priority) messages that will be queued before -/// they begin to be dropped. -const MAX_API_REQUEST_P1_QUEUE_LEN: usize = 1_024; + Ok(Self { + aggregate_queue: 4096, + unknown_block_aggregate_queue: 1024, + // Capacity for a full slot's worth of attestations if subscribed to all subnets + attestation_queue: active_validator_count / slots_per_epoch, + // Capacity for a full slot's worth of attestations if subscribed to all subnets + unknown_block_attestation_queue: active_validator_count / slots_per_epoch, + sync_message_queue: 2048, + sync_contribution_queue: 1024, + gossip_voluntary_exit_queue: 4096, + gossip_proposer_slashing_queue: 4096, + gossip_attester_slashing_queue: 4096, + finality_update_queue: 1024, + optimistic_update_queue: 1024, + unknown_light_client_update_queue: 128, + rpc_block_queue: 1024, + rpc_blob_queue: 1024, + chain_segment_queue: 64, + backfill_chain_segment: 64, + gossip_block_queue: 1024, + gossip_blob_queue: 1024, + delayed_block_queue: 1024, + status_queue: 1024, + bbrange_queue: 1024, + bbroots_queue: 1024, + blbroots_queue: 1024, + blbrange_queue: 1024, + gossip_bls_to_execution_change_queue: 16384, + lc_bootstrap_queue: 1024, + lc_optimistic_update_queue: 512, + lc_finality_update_queue: 512, + api_request_p0_queue: 1024, + api_request_p1_queue: 1024, + }) + } +} /// The name of the manager tokio task. const MANAGER_TASK_NAME: &str = "beacon_processor_manager"; @@ -772,6 +749,7 @@ impl BeaconProcessor { /// /// The optional `work_journal_tx` allows for an outside process to receive a log of all work /// events processed by `self`. This should only be used during testing. + #[allow(clippy::too_many_arguments)] pub fn spawn_manager( mut self, event_rx: mpsc::Receiver>, @@ -780,6 +758,7 @@ impl BeaconProcessor { work_journal_tx: Option>, slot_clock: S, maximum_gossip_clock_disparity: Duration, + queue_lengths: BeaconProcessorQueueLengths, ) -> Result<(), String> { // Used by workers to communicate that they are finished a task. let (idle_tx, idle_rx) = mpsc::channel::<()>(MAX_IDLE_QUEUE_LEN); @@ -787,61 +766,61 @@ impl BeaconProcessor { // Using LIFO queues for attestations since validator profits rely upon getting fresh // attestations into blocks. Additionally, later attestations contain more information than // earlier ones, so we consider them more valuable. - let mut aggregate_queue = LifoQueue::new(MAX_AGGREGATED_ATTESTATION_QUEUE_LEN); + let mut aggregate_queue = LifoQueue::new(queue_lengths.aggregate_queue); let mut aggregate_debounce = TimeLatch::default(); - let mut attestation_queue = LifoQueue::new(MAX_UNAGGREGATED_ATTESTATION_QUEUE_LEN); + let mut attestation_queue = LifoQueue::new(queue_lengths.attestation_queue); let mut attestation_debounce = TimeLatch::default(); let mut unknown_block_aggregate_queue = - LifoQueue::new(MAX_AGGREGATED_ATTESTATION_REPROCESS_QUEUE_LEN); + LifoQueue::new(queue_lengths.unknown_block_aggregate_queue); let mut unknown_block_attestation_queue = - LifoQueue::new(MAX_UNAGGREGATED_ATTESTATION_REPROCESS_QUEUE_LEN); + LifoQueue::new(queue_lengths.unknown_block_attestation_queue); - let mut sync_message_queue = LifoQueue::new(MAX_SYNC_MESSAGE_QUEUE_LEN); - let mut sync_contribution_queue = LifoQueue::new(MAX_SYNC_CONTRIBUTION_QUEUE_LEN); + let mut sync_message_queue = LifoQueue::new(queue_lengths.sync_message_queue); + let mut sync_contribution_queue = LifoQueue::new(queue_lengths.sync_contribution_queue); // Using a FIFO queue for voluntary exits since it prevents exit censoring. I don't have // a strong feeling about queue type for exits. - let mut gossip_voluntary_exit_queue = FifoQueue::new(MAX_GOSSIP_EXIT_QUEUE_LEN); + let mut gossip_voluntary_exit_queue = + FifoQueue::new(queue_lengths.gossip_voluntary_exit_queue); // Using a FIFO queue for slashing to prevent people from flushing their slashings from the // queues with lots of junk messages. let mut gossip_proposer_slashing_queue = - FifoQueue::new(MAX_GOSSIP_PROPOSER_SLASHING_QUEUE_LEN); + FifoQueue::new(queue_lengths.gossip_proposer_slashing_queue); let mut gossip_attester_slashing_queue = - FifoQueue::new(MAX_GOSSIP_ATTESTER_SLASHING_QUEUE_LEN); + FifoQueue::new(queue_lengths.gossip_attester_slashing_queue); // Using a FIFO queue for light client updates to maintain sequence order. - let mut finality_update_queue = FifoQueue::new(MAX_GOSSIP_FINALITY_UPDATE_QUEUE_LEN); - let mut optimistic_update_queue = FifoQueue::new(MAX_GOSSIP_OPTIMISTIC_UPDATE_QUEUE_LEN); + let mut finality_update_queue = FifoQueue::new(queue_lengths.finality_update_queue); + let mut optimistic_update_queue = FifoQueue::new(queue_lengths.optimistic_update_queue); let mut unknown_light_client_update_queue = - FifoQueue::new(MAX_GOSSIP_OPTIMISTIC_UPDATE_REPROCESS_QUEUE_LEN); + FifoQueue::new(queue_lengths.unknown_light_client_update_queue); // Using a FIFO queue since blocks need to be imported sequentially. - let mut rpc_block_queue = FifoQueue::new(MAX_RPC_BLOCK_QUEUE_LEN); - let mut rpc_blob_queue = FifoQueue::new(MAX_RPC_BLOB_QUEUE_LEN); - let mut chain_segment_queue = FifoQueue::new(MAX_CHAIN_SEGMENT_QUEUE_LEN); - let mut backfill_chain_segment = FifoQueue::new(MAX_CHAIN_SEGMENT_QUEUE_LEN); - let mut gossip_block_queue = FifoQueue::new(MAX_GOSSIP_BLOCK_QUEUE_LEN); - let mut gossip_blob_queue = FifoQueue::new(MAX_GOSSIP_BLOB_QUEUE_LEN); - let mut delayed_block_queue = FifoQueue::new(MAX_DELAYED_BLOCK_QUEUE_LEN); + let mut rpc_block_queue = FifoQueue::new(queue_lengths.rpc_block_queue); + let mut rpc_blob_queue = FifoQueue::new(queue_lengths.rpc_blob_queue); + let mut chain_segment_queue = FifoQueue::new(queue_lengths.chain_segment_queue); + let mut backfill_chain_segment = FifoQueue::new(queue_lengths.backfill_chain_segment); + let mut gossip_block_queue = FifoQueue::new(queue_lengths.gossip_block_queue); + let mut gossip_blob_queue = FifoQueue::new(queue_lengths.gossip_blob_queue); + let mut delayed_block_queue = FifoQueue::new(queue_lengths.delayed_block_queue); - let mut status_queue = FifoQueue::new(MAX_STATUS_QUEUE_LEN); - let mut bbrange_queue = FifoQueue::new(MAX_BLOCKS_BY_RANGE_QUEUE_LEN); - let mut bbroots_queue = FifoQueue::new(MAX_BLOCKS_BY_ROOTS_QUEUE_LEN); - let mut blbroots_queue = FifoQueue::new(MAX_BLOBS_BY_ROOTS_QUEUE_LEN); - let mut blbrange_queue = FifoQueue::new(MAX_BLOBS_BY_RANGE_QUEUE_LEN); + let mut status_queue = FifoQueue::new(queue_lengths.status_queue); + let mut bbrange_queue = FifoQueue::new(queue_lengths.bbrange_queue); + let mut bbroots_queue = FifoQueue::new(queue_lengths.bbroots_queue); + let mut blbroots_queue = FifoQueue::new(queue_lengths.blbroots_queue); + let mut blbrange_queue = FifoQueue::new(queue_lengths.blbrange_queue); let mut gossip_bls_to_execution_change_queue = - FifoQueue::new(MAX_BLS_TO_EXECUTION_CHANGE_QUEUE_LEN); + FifoQueue::new(queue_lengths.gossip_bls_to_execution_change_queue); - let mut lc_bootstrap_queue = FifoQueue::new(MAX_LIGHT_CLIENT_BOOTSTRAP_QUEUE_LEN); + let mut lc_bootstrap_queue = FifoQueue::new(queue_lengths.lc_bootstrap_queue); let mut lc_optimistic_update_queue = - FifoQueue::new(MAX_LIGHT_CLIENT_OPTIMISTIC_UPDATE_QUEUE_LEN); - let mut lc_finality_update_queue = - FifoQueue::new(MAX_LIGHT_CLIENT_FINALITY_UPDATE_QUEUE_LEN); + FifoQueue::new(queue_lengths.lc_optimistic_update_queue); + let mut lc_finality_update_queue = FifoQueue::new(queue_lengths.lc_finality_update_queue); - let mut api_request_p0_queue = FifoQueue::new(MAX_API_REQUEST_P0_QUEUE_LEN); - let mut api_request_p1_queue = FifoQueue::new(MAX_API_REQUEST_P1_QUEUE_LEN); + let mut api_request_p0_queue = FifoQueue::new(queue_lengths.api_request_p0_queue); + let mut api_request_p1_queue = FifoQueue::new(queue_lengths.api_request_p1_queue); // Channels for sending work to the re-process scheduler (`work_reprocessing_tx`) and to // receive them back once they are ready (`ready_work_rx`). diff --git a/beacon_node/beacon_processor/src/work_reprocessing_queue.rs b/beacon_node/beacon_processor/src/work_reprocessing_queue.rs index 496fa683d2..137010557d 100644 --- a/beacon_node/beacon_processor/src/work_reprocessing_queue.rs +++ b/beacon_node/beacon_processor/src/work_reprocessing_queue.rs @@ -28,7 +28,6 @@ use std::time::Duration; use strum::AsRefStr; use task_executor::TaskExecutor; use tokio::sync::mpsc::{self, Receiver, Sender}; -use tokio::time::error::Error as TimeError; use tokio_util::time::delay_queue::{DelayQueue, Key as DelayKey}; use types::{EthSpec, Hash256, Slot}; @@ -196,8 +195,6 @@ enum InboundEvent { ReadyLightClientUpdate(QueuedLightClientUpdateId), /// A backfill batch that was queued is ready for processing. ReadyBackfillSync(QueuedBackfillBatch), - /// A `DelayQueue` returned an error. - DelayQueueError(TimeError, &'static str), /// A message sent to the `ReprocessQueue` Msg(ReprocessQueueMessage), } @@ -279,54 +276,42 @@ impl Stream for ReprocessQueue { // The sequential nature of blockchains means it is generally better to try and import all // existing blocks before new ones. match self.gossip_block_delay_queue.poll_expired(cx) { - Poll::Ready(Some(Ok(queued_block))) => { + Poll::Ready(Some(queued_block)) => { return Poll::Ready(Some(InboundEvent::ReadyGossipBlock( queued_block.into_inner(), ))); } - Poll::Ready(Some(Err(e))) => { - return Poll::Ready(Some(InboundEvent::DelayQueueError(e, "gossip_block_queue"))); - } // `Poll::Ready(None)` means that there are no more entries in the delay queue and we // will continue to get this result until something else is added into the queue. Poll::Ready(None) | Poll::Pending => (), } match self.rpc_block_delay_queue.poll_expired(cx) { - Poll::Ready(Some(Ok(queued_block))) => { + Poll::Ready(Some(queued_block)) => { return Poll::Ready(Some(InboundEvent::ReadyRpcBlock(queued_block.into_inner()))); } - Poll::Ready(Some(Err(e))) => { - return Poll::Ready(Some(InboundEvent::DelayQueueError(e, "rpc_block_queue"))); - } // `Poll::Ready(None)` means that there are no more entries in the delay queue and we // will continue to get this result until something else is added into the queue. Poll::Ready(None) | Poll::Pending => (), } match self.attestations_delay_queue.poll_expired(cx) { - Poll::Ready(Some(Ok(attestation_id))) => { + Poll::Ready(Some(attestation_id)) => { return Poll::Ready(Some(InboundEvent::ReadyAttestation( attestation_id.into_inner(), ))); } - Poll::Ready(Some(Err(e))) => { - return Poll::Ready(Some(InboundEvent::DelayQueueError(e, "attestations_queue"))); - } // `Poll::Ready(None)` means that there are no more entries in the delay queue and we // will continue to get this result until something else is added into the queue. Poll::Ready(None) | Poll::Pending => (), } match self.lc_updates_delay_queue.poll_expired(cx) { - Poll::Ready(Some(Ok(lc_id))) => { + Poll::Ready(Some(lc_id)) => { return Poll::Ready(Some(InboundEvent::ReadyLightClientUpdate( lc_id.into_inner(), ))); } - Poll::Ready(Some(Err(e))) => { - return Poll::Ready(Some(InboundEvent::DelayQueueError(e, "lc_updates_queue"))); - } // `Poll::Ready(None)` means that there are no more entries in the delay queue and we // will continue to get this result until something else is added into the queue. Poll::Ready(None) | Poll::Pending => (), @@ -786,14 +771,6 @@ impl ReprocessQueue { ); } } - InboundEvent::DelayQueueError(e, queue_name) => { - crit!( - log, - "Failed to poll queue"; - "queue" => queue_name, - "e" => ?e - ) - } InboundEvent::ReadyAttestation(queued_id) => { metrics::inc_counter( &metrics::BEACON_PROCESSOR_REPROCESSING_QUEUE_EXPIRED_ATTESTATIONS, diff --git a/beacon_node/client/src/builder.rs b/beacon_node/client/src/builder.rs index 2af4e74c22..393ce35f00 100644 --- a/beacon_node/client/src/builder.rs +++ b/beacon_node/client/src/builder.rs @@ -19,8 +19,8 @@ use beacon_chain::{ store::{HotColdDB, ItemStore, LevelDB, StoreConfig}, BeaconChain, BeaconChainTypes, Eth1ChainBackend, MigratorConfig, ServerSentEventHandler, }; -use beacon_processor::BeaconProcessorConfig; use beacon_processor::{BeaconProcessor, BeaconProcessorChannels}; +use beacon_processor::{BeaconProcessorConfig, BeaconProcessorQueueLengths}; use environment::RuntimeContext; use eth1::{Config as Eth1Config, Service as Eth1Service}; use eth2::{ @@ -884,6 +884,14 @@ where None, beacon_chain.slot_clock.clone(), beacon_chain.spec.maximum_gossip_clock_disparity(), + BeaconProcessorQueueLengths::from_state( + &beacon_chain + .canonical_head + .cached_head() + .snapshot + .beacon_state, + &beacon_chain.spec, + )?, )?; } diff --git a/beacon_node/execution_layer/src/engine_api/json_structures.rs b/beacon_node/execution_layer/src/engine_api/json_structures.rs index f0d7930351..c41ee30e3d 100644 --- a/beacon_node/execution_layer/src/engine_api/json_structures.rs +++ b/beacon_node/execution_layer/src/engine_api/json_structures.rs @@ -805,6 +805,9 @@ pub mod serde_logs_bloom { #[serde(rename_all = "camelCase")] pub struct JsonClientVersionV1 { pub code: String, + // This `default` is required until Geth v1.13.x is no longer supported on mainnet. + // See: https://github.com/ethereum/go-ethereum/pull/29351 + #[serde(default)] pub name: String, pub version: String, pub commit: String, diff --git a/beacon_node/genesis/tests/tests.rs b/beacon_node/genesis/tests/tests.rs index f99fcb55bf..1252e0100b 100644 --- a/beacon_node/genesis/tests/tests.rs +++ b/beacon_node/genesis/tests/tests.rs @@ -1,7 +1,3 @@ -//! NOTE: These tests will not pass unless an anvil is running on `ENDPOINT` (see below). -//! -//! You can start a suitable instance using the `anvil_test_node.sh` script in the `scripts` -//! dir in the root of the `lighthouse` repo. #![cfg(test)] use environment::{Environment, EnvironmentBuilder}; use eth1::{Eth1Endpoint, DEFAULT_CHAIN_ID}; diff --git a/beacon_node/http_api/src/test_utils.rs b/beacon_node/http_api/src/test_utils.rs index c1313168bc..88112de10b 100644 --- a/beacon_node/http_api/src/test_utils.rs +++ b/beacon_node/http_api/src/test_utils.rs @@ -3,7 +3,9 @@ use beacon_chain::{ test_utils::{BeaconChainHarness, BoxedMutator, Builder, EphemeralHarnessType}, BeaconChain, BeaconChainTypes, }; -use beacon_processor::{BeaconProcessor, BeaconProcessorChannels, BeaconProcessorConfig}; +use beacon_processor::{ + BeaconProcessor, BeaconProcessorChannels, BeaconProcessorConfig, BeaconProcessorQueueLengths, +}; use directory::DEFAULT_ROOT_DIR; use eth2::{BeaconNodeHttpClient, Timeouts}; use lighthouse_network::{ @@ -206,6 +208,11 @@ pub async fn create_api_server( None, chain.slot_clock.clone(), chain.spec.maximum_gossip_clock_disparity(), + BeaconProcessorQueueLengths::from_state( + &chain.canonical_head.cached_head().snapshot.beacon_state, + &chain.spec, + ) + .unwrap(), ) .unwrap(); diff --git a/beacon_node/lighthouse_network/Cargo.toml b/beacon_node/lighthouse_network/Cargo.toml index b318bd4fb3..e850bced16 100644 --- a/beacon_node/lighthouse_network/Cargo.toml +++ b/beacon_node/lighthouse_network/Cargo.toml @@ -7,7 +7,7 @@ edition = { workspace = true } [dependencies] discv5 = { workspace = true } gossipsub = { workspace = true } -unsigned-varint = { version = "0.6", features = ["codec"] } +unsigned-varint = { version = "0.8", features = ["codec"] } ssz_types = { workspace = true } types = { workspace = true } serde = { workspace = true } diff --git a/beacon_node/lighthouse_network/src/rpc/handler.rs b/beacon_node/lighthouse_network/src/rpc/handler.rs index daf95fb8c9..48f69c64c5 100644 --- a/beacon_node/lighthouse_network/src/rpc/handler.rs +++ b/beacon_node/lighthouse_network/src/rpc/handler.rs @@ -15,7 +15,7 @@ use libp2p::swarm::handler::{ FullyNegotiatedInbound, FullyNegotiatedOutbound, StreamUpgradeError, SubstreamProtocol, }; use libp2p::swarm::Stream; -use slog::{crit, debug, trace, warn}; +use slog::{crit, debug, trace}; use smallvec::SmallVec; use std::{ collections::{hash_map::Entry, VecDeque}, @@ -414,70 +414,44 @@ where } // purge expired inbound substreams and send an error - loop { - match self.inbound_substreams_delay.poll_expired(cx) { - Poll::Ready(Some(Ok(inbound_id))) => { - // handle a stream timeout for various states - if let Some(info) = self.inbound_substreams.get_mut(inbound_id.get_ref()) { - // the delay has been removed - info.delay_key = None; - self.events_out.push(HandlerEvent::Err(HandlerErr::Inbound { - error: RPCError::StreamTimeout, - proto: info.protocol, - id: *inbound_id.get_ref(), - })); - if info.pending_items.back().map(|l| l.close_after()) == Some(false) { - // if the last chunk does not close the stream, append an error - info.pending_items.push_back(RPCCodedResponse::Error( - RPCResponseErrorCode::ServerError, - "Request timed out".into(), - )); - } - } - } - Poll::Ready(Some(Err(e))) => { - warn!(self.log, "Inbound substream poll failed"; "error" => ?e); - // drops the peer if we cannot read the delay queue - return Poll::Ready(ConnectionHandlerEvent::NotifyBehaviour( - HandlerEvent::Close(RPCError::InternalError( - "Could not poll inbound stream timer", - )), + while let Poll::Ready(Some(inbound_id)) = self.inbound_substreams_delay.poll_expired(cx) { + // handle a stream timeout for various states + if let Some(info) = self.inbound_substreams.get_mut(inbound_id.get_ref()) { + // the delay has been removed + info.delay_key = None; + self.events_out.push(HandlerEvent::Err(HandlerErr::Inbound { + error: RPCError::StreamTimeout, + proto: info.protocol, + id: *inbound_id.get_ref(), + })); + + if info.pending_items.back().map(|l| l.close_after()) == Some(false) { + // if the last chunk does not close the stream, append an error + info.pending_items.push_back(RPCCodedResponse::Error( + RPCResponseErrorCode::ServerError, + "Request timed out".into(), )); } - Poll::Pending | Poll::Ready(None) => break, } } // purge expired outbound substreams - loop { - match self.outbound_substreams_delay.poll_expired(cx) { - Poll::Ready(Some(Ok(outbound_id))) => { - if let Some(OutboundInfo { proto, req_id, .. }) = - self.outbound_substreams.remove(outbound_id.get_ref()) - { - let outbound_err = HandlerErr::Outbound { - id: req_id, - proto, - error: RPCError::StreamTimeout, - }; - // notify the user - return Poll::Ready(ConnectionHandlerEvent::NotifyBehaviour( - HandlerEvent::Err(outbound_err), - )); - } else { - crit!(self.log, "timed out substream not in the books"; "stream_id" => outbound_id.get_ref()); - } - } - Poll::Ready(Some(Err(e))) => { - warn!(self.log, "Outbound substream poll failed"; "error" => ?e); - return Poll::Ready(ConnectionHandlerEvent::NotifyBehaviour( - HandlerEvent::Close(RPCError::InternalError( - "Could not poll outbound stream timer", - )), - )); - } - Poll::Pending | Poll::Ready(None) => break, + while let Poll::Ready(Some(outbound_id)) = self.outbound_substreams_delay.poll_expired(cx) { + if let Some(OutboundInfo { proto, req_id, .. }) = + self.outbound_substreams.remove(outbound_id.get_ref()) + { + let outbound_err = HandlerErr::Outbound { + id: req_id, + proto, + error: RPCError::StreamTimeout, + }; + // notify the user + return Poll::Ready(ConnectionHandlerEvent::NotifyBehaviour(HandlerEvent::Err( + outbound_err, + ))); + } else { + crit!(self.log, "timed out substream not in the books"; "stream_id" => outbound_id.get_ref()); } } diff --git a/beacon_node/lighthouse_network/src/rpc/mod.rs b/beacon_node/lighthouse_network/src/rpc/mod.rs index a91c9e44b2..1fa6862351 100644 --- a/beacon_node/lighthouse_network/src/rpc/mod.rs +++ b/beacon_node/lighthouse_network/src/rpc/mod.rs @@ -10,7 +10,7 @@ use libp2p::swarm::{ handler::ConnectionHandler, CloseConnection, ConnectionId, NetworkBehaviour, NotifyHandler, ToSwarm, }; -use libp2p::swarm::{FromSwarm, SubstreamProtocol, THandlerInEvent}; +use libp2p::swarm::{ConnectionClosed, FromSwarm, SubstreamProtocol, THandlerInEvent}; use libp2p::PeerId; use rate_limiter::{RPCRateLimiter as RateLimiter, RateLimitedErr}; use slog::{crit, debug, o}; @@ -283,9 +283,40 @@ where Ok(handler) } - fn on_swarm_event(&mut self, _event: FromSwarm) { + fn on_swarm_event(&mut self, event: FromSwarm) { // NOTE: FromSwarm is a non exhaustive enum so updates should be based on release notes more // than compiler feedback + // The self rate limiter holds on to requests and attempts to process them within our rate + // limits. If a peer disconnects whilst we are self-rate limiting, we want to terminate any + // pending requests and return an error response to the application. + + if let FromSwarm::ConnectionClosed(ConnectionClosed { + peer_id, + remaining_established, + connection_id, + .. + }) = event + { + // If there are still connections remaining, do nothing. + if remaining_established > 0 { + return; + } + // Get a list of pending requests from the self rate limiter + if let Some(limiter) = self.self_limiter.as_mut() { + for (id, proto) in limiter.peer_disconnected(peer_id) { + let error_msg = ToSwarm::GenerateEvent(RPCMessage { + peer_id, + conn_id: connection_id, + event: HandlerEvent::Err(HandlerErr::Outbound { + id, + proto, + error: RPCError::Disconnected, + }), + }); + self.events.push(error_msg); + } + } + } } fn on_connection_handler_event( diff --git a/beacon_node/lighthouse_network/src/rpc/self_limiter.rs b/beacon_node/lighthouse_network/src/rpc/self_limiter.rs index e845a775cb..be4c572308 100644 --- a/beacon_node/lighthouse_network/src/rpc/self_limiter.rs +++ b/beacon_node/lighthouse_network/src/rpc/self_limiter.rs @@ -158,13 +158,39 @@ impl SelfRateLimiter { entry.remove(); } } + // NOTE: There can be entries that have been removed due to peer disconnections, we simply + // ignore these messages here. + } + + /// Informs the limiter that a peer has disconnected. This removes any pending requests and + /// returns their IDs. + pub fn peer_disconnected(&mut self, peer_id: PeerId) -> Vec<(Id, Protocol)> { + // It's not ideal to iterate this map, but the key is (PeerId, Protocol) and this map + // should never really be large. So we iterate for simplicity + let mut failed_requests = Vec::new(); + self.delayed_requests + .retain(|(map_peer_id, protocol), queue| { + if map_peer_id == &peer_id { + // NOTE: Currently cannot remove entries from the DelayQueue, we will just let + // them expire and ignore them. + for message in queue { + failed_requests.push((message.request_id, *protocol)) + } + // Remove the entry + false + } else { + // Keep the entry + true + } + }); + failed_requests } pub fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { // First check the requests that were self rate limited, since those might add events to // the queue. Also do this this before rate limiter prunning to avoid removing and // immediately adding rate limiting keys. - if let Poll::Ready(Some(Ok(expired))) = self.next_peer_request.poll_expired(cx) { + if let Poll::Ready(Some(expired)) = self.next_peer_request.poll_expired(cx) { let (peer_id, protocol) = expired.into_inner(); self.next_peer_request_ready(peer_id, protocol); } diff --git a/beacon_node/lighthouse_network/src/service/gossip_cache.rs b/beacon_node/lighthouse_network/src/service/gossip_cache.rs index 225b4ef8dd..158c7a994a 100644 --- a/beacon_node/lighthouse_network/src/service/gossip_cache.rs +++ b/beacon_node/lighthouse_network/src/service/gossip_cache.rs @@ -240,7 +240,7 @@ impl futures::stream::Stream for GossipCache { fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { match self.expirations.poll_expired(cx) { - Poll::Ready(Some(Ok(expired))) => { + Poll::Ready(Some(expired)) => { let expected_key = expired.key(); let (topic, data) = expired.into_inner(); match self.topic_msgs.get_mut(&topic) { @@ -259,7 +259,6 @@ impl futures::stream::Stream for GossipCache { } Poll::Ready(Some(Ok(topic))) } - Poll::Ready(Some(Err(x))) => Poll::Ready(Some(Err(x.to_string()))), Poll::Ready(None) => Poll::Ready(None), Poll::Pending => Poll::Pending, } diff --git a/beacon_node/lighthouse_network/src/service/mod.rs b/beacon_node/lighthouse_network/src/service/mod.rs index 86086feda3..dbf7c38226 100644 --- a/beacon_node/lighthouse_network/src/service/mod.rs +++ b/beacon_node/lighthouse_network/src/service/mod.rs @@ -917,12 +917,23 @@ impl Network { /* Eth2 RPC behaviour functions */ /// Send a request to a peer over RPC. - pub fn send_request(&mut self, peer_id: PeerId, request_id: AppReqId, request: Request) { + pub fn send_request( + &mut self, + peer_id: PeerId, + request_id: AppReqId, + request: Request, + ) -> Result<(), (AppReqId, RPCError)> { + // Check if the peer is connected before sending an RPC request + if !self.swarm.is_connected(&peer_id) { + return Err((request_id, RPCError::Disconnected)); + } + self.eth2_rpc_mut().send_request( peer_id, RequestId::Application(request_id), request.into(), - ) + ); + Ok(()) } /// Send a successful response to a peer over RPC. @@ -1378,26 +1389,17 @@ impl Network { ) -> Option> { let peer_id = event.peer_id; - if !self.peer_manager().is_connected(&peer_id) { - // Sync expects a RPCError::Disconnected to drop associated lookups with this peer. - // Silencing this event breaks the API contract with RPC where every request ends with - // - A stream termination event, or - // - An RPCError event - return if let HandlerEvent::Err(HandlerErr::Outbound { - id: RequestId::Application(id), - error, - .. - }) = event.event - { - Some(NetworkEvent::RPCFailed { peer_id, id, error }) - } else { - debug!( - self.log, - "Ignoring rpc message of disconnecting peer"; - event - ); - None - }; + // Do not permit Inbound events from peers that are being disconnected, or RPC requests. + if !self.peer_manager().is_connected(&peer_id) + && (matches!(event.event, HandlerEvent::Err(HandlerErr::Inbound { .. })) + || matches!(event.event, HandlerEvent::Ok(RPCReceived::Request(..)))) + { + debug!( + self.log, + "Ignoring rpc message of disconnecting peer"; + event + ); + return None; } let handler_id = event.conn_id; diff --git a/beacon_node/lighthouse_network/tests/rpc_tests.rs b/beacon_node/lighthouse_network/tests/rpc_tests.rs index e2b72f8673..8d29f5158b 100644 --- a/beacon_node/lighthouse_network/tests/rpc_tests.rs +++ b/beacon_node/lighthouse_network/tests/rpc_tests.rs @@ -98,7 +98,9 @@ fn test_tcp_status_rpc() { NetworkEvent::PeerConnectedOutgoing(peer_id) => { // Send a STATUS message debug!(log, "Sending RPC"); - sender.send_request(peer_id, 10, rpc_request.clone()); + sender + .send_request(peer_id, 10, rpc_request.clone()) + .unwrap(); } NetworkEvent::ResponseReceived { peer_id: _, @@ -202,7 +204,9 @@ fn test_tcp_blocks_by_range_chunked_rpc() { NetworkEvent::PeerConnectedOutgoing(peer_id) => { // Send a STATUS message debug!(log, "Sending RPC"); - sender.send_request(peer_id, request_id, rpc_request.clone()); + sender + .send_request(peer_id, request_id, rpc_request.clone()) + .unwrap(); } NetworkEvent::ResponseReceived { peer_id: _, @@ -327,7 +331,9 @@ fn test_blobs_by_range_chunked_rpc() { NetworkEvent::PeerConnectedOutgoing(peer_id) => { // Send a STATUS message debug!(log, "Sending RPC"); - sender.send_request(peer_id, request_id, rpc_request.clone()); + sender + .send_request(peer_id, request_id, rpc_request.clone()) + .unwrap(); } NetworkEvent::ResponseReceived { peer_id: _, @@ -435,7 +441,9 @@ fn test_tcp_blocks_by_range_over_limit() { NetworkEvent::PeerConnectedOutgoing(peer_id) => { // Send a STATUS message debug!(log, "Sending RPC"); - sender.send_request(peer_id, request_id, rpc_request.clone()); + sender + .send_request(peer_id, request_id, rpc_request.clone()) + .unwrap(); } // The request will fail because the sender will refuse to send anything > MAX_RPC_SIZE NetworkEvent::RPCFailed { id, .. } => { @@ -528,7 +536,9 @@ fn test_tcp_blocks_by_range_chunked_rpc_terminates_correctly() { NetworkEvent::PeerConnectedOutgoing(peer_id) => { // Send a STATUS message debug!(log, "Sending RPC"); - sender.send_request(peer_id, request_id, rpc_request.clone()); + sender + .send_request(peer_id, request_id, rpc_request.clone()) + .unwrap(); } NetworkEvent::ResponseReceived { peer_id: _, @@ -657,7 +667,9 @@ fn test_tcp_blocks_by_range_single_empty_rpc() { NetworkEvent::PeerConnectedOutgoing(peer_id) => { // Send a STATUS message debug!(log, "Sending RPC"); - sender.send_request(peer_id, 10, rpc_request.clone()); + sender + .send_request(peer_id, 10, rpc_request.clone()) + .unwrap(); } NetworkEvent::ResponseReceived { peer_id: _, @@ -780,7 +792,9 @@ fn test_tcp_blocks_by_root_chunked_rpc() { NetworkEvent::PeerConnectedOutgoing(peer_id) => { // Send a STATUS message debug!(log, "Sending RPC"); - sender.send_request(peer_id, 6, rpc_request.clone()); + sender + .send_request(peer_id, 6, rpc_request.clone()) + .unwrap(); } NetworkEvent::ResponseReceived { peer_id: _, @@ -911,7 +925,9 @@ fn test_tcp_blocks_by_root_chunked_rpc_terminates_correctly() { NetworkEvent::PeerConnectedOutgoing(peer_id) => { // Send a STATUS message debug!(log, "Sending RPC"); - sender.send_request(peer_id, 10, rpc_request.clone()); + sender + .send_request(peer_id, 10, rpc_request.clone()) + .unwrap(); } NetworkEvent::ResponseReceived { peer_id: _, @@ -1031,7 +1047,9 @@ fn test_disconnect_triggers_rpc_error() { NetworkEvent::PeerConnectedOutgoing(peer_id) => { // Send a STATUS message debug!(log, "Sending RPC"); - sender.send_request(peer_id, 42, rpc_request.clone()); + sender + .send_request(peer_id, 42, rpc_request.clone()) + .unwrap(); } NetworkEvent::RPCFailed { error, id: 42, .. } => match error { RPCError::Disconnected => return, diff --git a/beacon_node/network/src/network_beacon_processor/tests.rs b/beacon_node/network/src/network_beacon_processor/tests.rs index 4ba4c4ddd1..06b12c14ae 100644 --- a/beacon_node/network/src/network_beacon_processor/tests.rs +++ b/beacon_node/network/src/network_beacon_processor/tests.rs @@ -239,6 +239,11 @@ impl TestRig { Some(work_journal_tx), harness.chain.slot_clock.clone(), chain.spec.maximum_gossip_clock_disparity(), + BeaconProcessorQueueLengths::from_state( + &chain.canonical_head.cached_head().snapshot.beacon_state, + &chain.spec, + ) + .unwrap(), ); assert!(beacon_processor.is_ok()); diff --git a/beacon_node/network/src/service.rs b/beacon_node/network/src/service.rs index 34ed3edcf9..e215f25387 100644 --- a/beacon_node/network/src/service.rs +++ b/beacon_node/network/src/service.rs @@ -613,7 +613,15 @@ impl NetworkService { request, request_id, } => { - self.libp2p.send_request(peer_id, request_id, request); + if let Err((request_id, error)) = + self.libp2p.send_request(peer_id, request_id, request) + { + self.send_to_router(RouterMessage::RPCFailed { + peer_id, + request_id, + error, + }); + } } NetworkMessage::SendResponse { peer_id, diff --git a/beacon_node/src/cli.rs b/beacon_node/src/cli.rs index dbfda2d530..40a343a7fe 100644 --- a/beacon_node/src/cli.rs +++ b/beacon_node/src/cli.rs @@ -1101,6 +1101,8 @@ pub fn cli_app() -> Command { [Enabled by default].") .action(ArgAction::Set) .default_value("true") + .num_args(0..=1) + .default_missing_value("true") .display_order(0) ) .arg( diff --git a/book/src/help_bn.md b/book/src/help_bn.md index b458842e08..8bbbd3eb6b 100644 --- a/book/src/help_bn.md +++ b/book/src/help_bn.md @@ -356,7 +356,7 @@ Options: --slasher-backend Set the database backend to be used by the slasher. [possible values: lmdb, disabled] - --slasher-broadcast + --slasher-broadcast [] Broadcast slashings found by the slasher to the rest of the network [Enabled by default]. [default: true] --slasher-chunk-size diff --git a/book/src/help_general.md b/book/src/help_general.md index 42bff04d1a..a8cd459614 100644 --- a/book/src/help_general.md +++ b/book/src/help_general.md @@ -9,7 +9,7 @@ Usage: lighthouse [OPTIONS] [COMMAND] Commands: account_manager Utilities for generating and managing Ethereum 2.0 accounts. [aliases: - a, am, account, account_manager] + a, am, account] beacon_node The primary component which connects to the Ethereum 2.0 P2P network and downloads, verifies and stores blocks. Provides a HTTP API for @@ -30,7 +30,7 @@ Commands: validator] validator_manager Utilities for managing a Lighthouse validator client via the HTTP API. - [aliases: vm, validator-manager, validator_manager] + [aliases: vm, validator-manager] help Print this message or the help of the given subcommand(s) diff --git a/boot_node/Cargo.toml b/boot_node/Cargo.toml index d5c5fe0d64..ee7cb96d21 100644 --- a/boot_node/Cargo.toml +++ b/boot_node/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "boot_node" -version = "5.1.3" +version = "5.2.0" authors = ["Sigma Prime "] edition = { workspace = true } diff --git a/common/lighthouse_version/src/lib.rs b/common/lighthouse_version/src/lib.rs index 985eaff1b5..6fb06cc543 100644 --- a/common/lighthouse_version/src/lib.rs +++ b/common/lighthouse_version/src/lib.rs @@ -17,8 +17,8 @@ pub const VERSION: &str = git_version!( // NOTE: using --match instead of --exclude for compatibility with old Git "--match=thiswillnevermatchlol" ], - prefix = "Lighthouse/v5.1.3-", - fallback = "Lighthouse/v5.1.3" + prefix = "Lighthouse/v5.2.0-", + fallback = "Lighthouse/v5.2.0" ); /// Returns the first eight characters of the latest commit hash for this build. diff --git a/common/logging/src/async_record.rs b/common/logging/src/async_record.rs index 6f998c6191..81037b11a4 100644 --- a/common/logging/src/async_record.rs +++ b/common/logging/src/async_record.rs @@ -123,12 +123,10 @@ impl Serializer for ToSendSerializer { take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val)))); Ok(()) } - #[cfg(integer128)] fn emit_u128(&mut self, key: Key, val: u128) -> slog::Result { take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val)))); Ok(()) } - #[cfg(integer128)] fn emit_i128(&mut self, key: Key, val: i128) -> slog::Result { take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val)))); Ok(()) diff --git a/common/validator_dir/src/validator_dir.rs b/common/validator_dir/src/validator_dir.rs index 24b317dcfe..4f9b786844 100644 --- a/common/validator_dir/src/validator_dir.rs +++ b/common/validator_dir/src/validator_dir.rs @@ -39,8 +39,6 @@ pub enum Error { /// generally caused by supplying an `amount` at deposit-time that is different to the one used /// at generation-time. Eth1DepositRootMismatch, - #[cfg(feature = "unencrypted_keys")] - SszKeypairError(String), } /// Information required to submit a deposit to the Eth1 deposit contract. diff --git a/consensus/swap_or_not_shuffle/benches/benches.rs b/consensus/swap_or_not_shuffle/benches/benches.rs index d5f64f0b6b..2909ff1ac6 100644 --- a/consensus/swap_or_not_shuffle/benches/benches.rs +++ b/consensus/swap_or_not_shuffle/benches/benches.rs @@ -1,7 +1,4 @@ -#![allow(deprecated)] - -use criterion::Criterion; -use criterion::{black_box, criterion_group, criterion_main, Benchmark}; +use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion}; use swap_or_not_shuffle::{compute_shuffled_index, shuffle_list as fast_shuffle}; const SHUFFLE_ROUND_COUNT: u8 = 90; @@ -25,70 +22,32 @@ fn shuffles(c: &mut Criterion) { b.iter(|| black_box(shuffle_list(&seed, 8))) }); - c.bench( - "whole list shuffle", - Benchmark::new("8 elements", move |b| { - let seed = vec![42; 32]; - b.iter(|| black_box(shuffle_list(&seed, 8))) - }), - ); + for size in [8, 16, 512, 16_384] { + c.bench_with_input( + BenchmarkId::new("whole list shuffle", format!("{size} elements")), + &size, + move |b, &n| { + let seed = vec![42; 32]; + b.iter(|| black_box(shuffle_list(&seed, n))) + }, + ); + } - c.bench( - "whole list shuffle", - Benchmark::new("16 elements", move |b| { - let seed = vec![42; 32]; - b.iter(|| black_box(shuffle_list(&seed, 16))) - }), - ); - - c.bench( - "whole list shuffle", - Benchmark::new("512 elements", move |b| { - let seed = vec![42; 32]; - b.iter(|| black_box(shuffle_list(&seed, 512))) - }) - .sample_size(10), - ); - - c.bench( - "_fast_ whole list shuffle", - Benchmark::new("512 elements", move |b| { - let seed = vec![42; 32]; - let list: Vec = (0..512).collect(); - b.iter(|| black_box(fast_shuffle(list.clone(), SHUFFLE_ROUND_COUNT, &seed, true))) - }) - .sample_size(10), - ); - - c.bench( - "whole list shuffle", - Benchmark::new("16384 elements", move |b| { - let seed = vec![42; 32]; - b.iter(|| black_box(shuffle_list(&seed, 16_384))) - }) - .sample_size(10), - ); - - c.bench( - "_fast_ whole list shuffle", - Benchmark::new("16384 elements", move |b| { - let seed = vec![42; 32]; - let list: Vec = (0..16384).collect(); - b.iter(|| black_box(fast_shuffle(list.clone(), SHUFFLE_ROUND_COUNT, &seed, true))) - }) - .sample_size(10), - ); - - c.bench( - "_fast_ whole list shuffle", - Benchmark::new("4m elements", move |b| { - let seed = vec![42; 32]; - let list: Vec = (0..4_000_000).collect(); - b.iter(|| black_box(fast_shuffle(list.clone(), SHUFFLE_ROUND_COUNT, &seed, true))) - }) - .sample_size(10), - ); + let mut group = c.benchmark_group("fast"); + group.sample_size(10); + for size in [512, 16_384, 4_000_000] { + group.bench_with_input( + BenchmarkId::new("whole list shuffle", format!("{size} elements")), + &size, + move |b, &n| { + let seed = vec![42; 32]; + let list: Vec = (0..n).collect(); + b.iter(|| black_box(fast_shuffle(list.clone(), SHUFFLE_ROUND_COUNT, &seed, true))) + }, + ); + } + group.finish(); } -criterion_group!(benches, shuffles,); +criterion_group!(benches, shuffles); criterion_main!(benches); diff --git a/consensus/types/benches/benches.rs b/consensus/types/benches/benches.rs index 5c1036a4c5..c6dda142b2 100644 --- a/consensus/types/benches/benches.rs +++ b/consensus/types/benches/benches.rs @@ -1,7 +1,4 @@ -#![allow(deprecated)] - -use criterion::Criterion; -use criterion::{black_box, criterion_group, criterion_main, Benchmark}; +use criterion::{black_box, criterion_group, criterion_main, BatchSize, BenchmarkId, Criterion}; use milhouse::List; use rayon::prelude::*; use ssz::Encode; @@ -53,75 +50,82 @@ fn all_benches(c: &mut Criterion) { let validator_count = 16_384; let spec = Arc::new(MainnetEthSpec::default_spec()); + let mut g = c.benchmark_group("types"); + g.sample_size(10); + let mut state = get_state::(validator_count); state.build_caches(&spec).expect("should build caches"); let state_bytes = state.as_ssz_bytes(); let inner_state = state.clone(); - c.bench( - &format!("{}_validators", validator_count), - Benchmark::new("encode/beacon_state", move |b| { + g.bench_with_input( + BenchmarkId::new("encode/beacon_state", validator_count), + &inner_state, + |b, state| { b.iter_batched_ref( - || inner_state.clone(), + || state.clone(), |state| black_box(state.as_ssz_bytes()), - criterion::BatchSize::SmallInput, + BatchSize::SmallInput, ) - }) - .sample_size(10), + }, ); - c.bench( - &format!("{}_validators", validator_count), - Benchmark::new("decode/beacon_state", move |b| { + g.bench_with_input( + BenchmarkId::new("decode/beacon_state", validator_count), + &(state_bytes.clone(), spec.clone()), + |b, (bytes, spec)| { b.iter_batched_ref( - || (state_bytes.clone(), spec.clone()), + || (bytes.clone(), spec.clone()), |(bytes, spec)| { let state: BeaconState = BeaconState::from_ssz_bytes(&bytes, &spec).expect("should decode"); black_box(state) }, - criterion::BatchSize::SmallInput, + BatchSize::SmallInput, ) - }) - .sample_size(10), + }, ); let inner_state = state.clone(); - c.bench( - &format!("{}_validators", validator_count), - Benchmark::new("clone/beacon_state", move |b| { + g.bench_with_input( + BenchmarkId::new("clone/beacon_state", validator_count), + &inner_state, + |b, state| { b.iter_batched_ref( - || inner_state.clone(), + || state.clone(), |state| black_box(state.clone()), - criterion::BatchSize::SmallInput, + BatchSize::SmallInput, ) - }) - .sample_size(10), + }, ); let inner_state = state.clone(); - c.bench( - &format!("{}_validators", validator_count), - Benchmark::new( + g.bench_with_input( + BenchmarkId::new( "initialized_cached_tree_hash_without_changes/beacon_state", - move |b| { - b.iter_batched_ref( - || inner_state.clone(), - |state| black_box(state.update_tree_hash_cache()), - criterion::BatchSize::SmallInput, - ) - }, - ) - .sample_size(10), + validator_count, + ), + &inner_state, + |b, state| { + b.iter_batched_ref( + || state.clone(), + |state| black_box(state.update_tree_hash_cache()), + BatchSize::SmallInput, + ) + }, ); let mut inner_state = state.clone(); inner_state.drop_all_caches().unwrap(); - c.bench( - &format!("{}_validators", validator_count), - Benchmark::new("non_initialized_cached_tree_hash/beacon_state", move |b| { + g.bench_with_input( + BenchmarkId::new( + "non_initialized_cached_tree_hash/beacon_state", + validator_count, + ), + &inner_state, + |b, state| { b.iter_batched_ref( - || inner_state.clone(), + || state.clone(), |state| { black_box( state @@ -129,41 +133,40 @@ fn all_benches(c: &mut Criterion) { .expect("should update tree hash"), ) }, - criterion::BatchSize::SmallInput, + BatchSize::SmallInput, ) - }) - .sample_size(10), + }, ); let inner_state = state.clone(); - c.bench( - &format!("{}_validators", validator_count), - Benchmark::new( + g.bench_with_input( + BenchmarkId::new( "initialized_cached_tree_hash_with_new_validators/beacon_state", - move |b| { - b.iter_batched_ref( - || { - let mut state = inner_state.clone(); - for _ in 0..16 { - state - .validators_mut() - .push(Validator::default()) - .expect("should push validatorj"); - state - .balances_mut() - .push(32_000_000_000) - .expect("should push balance"); - } + validator_count, + ), + &inner_state, + |b, state| { + b.iter_batched_ref( + || { + let mut state = state.clone(); + for _ in 0..16 { state - }, - |state| black_box(state.update_tree_hash_cache()), - criterion::BatchSize::SmallInput, - ) - }, - ) - .sample_size(10), + .validators_mut() + .push(Validator::default()) + .expect("should push validator"); + state + .balances_mut() + .push(32_000_000_000) + .expect("should push balance"); + } + state + }, + |state| black_box(state.update_tree_hash_cache()), + BatchSize::SmallInput, + ) + }, ); } -criterion_group!(benches, all_benches,); +criterion_group!(benches, all_benches); criterion_main!(benches); diff --git a/consensus/types/src/beacon_block_body.rs b/consensus/types/src/beacon_block_body.rs index 0466d1b768..76a2fc1872 100644 --- a/consensus/types/src/beacon_block_body.rs +++ b/consensus/types/src/beacon_block_body.rs @@ -2,6 +2,7 @@ use crate::test_utils::TestRandom; use crate::*; use derivative::Derivative; use merkle_proof::{MerkleTree, MerkleTreeError}; +use metastruct::metastruct; use serde::{Deserialize, Serialize}; use ssz_derive::{Decode, Encode}; use std::marker::PhantomData; @@ -50,6 +51,14 @@ pub const BLOB_KZG_COMMITMENTS_INDEX: usize = 11; ), arbitrary(bound = "E: EthSpec, Payload: AbstractExecPayload"), ), + specific_variant_attributes( + Base(metastruct(mappings(beacon_block_body_base_fields(groups(fields))))), + Altair(metastruct(mappings(beacon_block_body_altair_fields(groups(fields))))), + Bellatrix(metastruct(mappings(beacon_block_body_bellatrix_fields(groups(fields))))), + Capella(metastruct(mappings(beacon_block_body_capella_fields(groups(fields))))), + Deneb(metastruct(mappings(beacon_block_body_deneb_fields(groups(fields))))), + Electra(metastruct(mappings(beacon_block_body_electra_fields(groups(fields))))), + ), cast_error(ty = "Error", expr = "Error::IncorrectStateVariant"), partial_getter_error(ty = "Error", expr = "Error::IncorrectStateVariant") )] @@ -108,6 +117,7 @@ pub struct BeaconBlockBody = FullPay #[superstruct(only(Electra))] pub consolidations: VariableList, #[superstruct(only(Base, Altair))] + #[metastruct(exclude_from(fields))] #[ssz(skip_serializing, skip_deserializing)] #[tree_hash(skip_hashing)] #[serde(skip)] @@ -132,139 +142,88 @@ impl<'a, E: EthSpec, Payload: AbstractExecPayload> BeaconBlockBodyRef<'a, E, } } + fn body_merkle_leaves(&self) -> Vec { + let mut leaves = vec![]; + match self { + Self::Base(body) => { + beacon_block_body_base_fields!(body, |_, field| leaves + .push(field.tree_hash_root())); + } + Self::Altair(body) => { + beacon_block_body_altair_fields!(body, |_, field| leaves + .push(field.tree_hash_root())); + } + Self::Bellatrix(body) => { + beacon_block_body_bellatrix_fields!(body, |_, field| leaves + .push(field.tree_hash_root())); + } + Self::Capella(body) => { + beacon_block_body_capella_fields!(body, |_, field| leaves + .push(field.tree_hash_root())); + } + Self::Deneb(body) => { + beacon_block_body_deneb_fields!(body, |_, field| leaves + .push(field.tree_hash_root())); + } + Self::Electra(body) => { + beacon_block_body_electra_fields!(body, |_, field| leaves + .push(field.tree_hash_root())); + } + } + leaves + } + /// Produces the proof of inclusion for a `KzgCommitment` in `self.blob_kzg_commitments` /// at `index`. pub fn kzg_commitment_merkle_proof( &self, index: usize, ) -> Result, Error> { - match self { - Self::Base(_) | Self::Altair(_) | Self::Bellatrix(_) | Self::Capella(_) => { - Err(Error::IncorrectStateVariant) - } - Self::Deneb(body) => { - // We compute the branches by generating 2 merkle trees: - // 1. Merkle tree for the `blob_kzg_commitments` List object - // 2. Merkle tree for the `BeaconBlockBody` container - // We then merge the branches for both the trees all the way up to the root. + // We compute the branches by generating 2 merkle trees: + // 1. Merkle tree for the `blob_kzg_commitments` List object + // 2. Merkle tree for the `BeaconBlockBody` container + // We then merge the branches for both the trees all the way up to the root. - // Part1 (Branches for the subtree rooted at `blob_kzg_commitments`) - // - // Branches for `blob_kzg_commitments` without length mix-in - let depth = E::max_blob_commitments_per_block() - .next_power_of_two() - .ilog2(); - let leaves: Vec<_> = body - .blob_kzg_commitments - .iter() - .map(|commitment| commitment.tree_hash_root()) - .collect(); - let tree = MerkleTree::create(&leaves, depth as usize); - let (_, mut proof) = tree - .generate_proof(index, depth as usize) - .map_err(Error::MerkleTreeError)?; + // Part1 (Branches for the subtree rooted at `blob_kzg_commitments`) + // + // Branches for `blob_kzg_commitments` without length mix-in + let blob_leaves = self + .blob_kzg_commitments()? + .iter() + .map(|commitment| commitment.tree_hash_root()) + .collect::>(); + let depth = E::max_blob_commitments_per_block() + .next_power_of_two() + .ilog2(); + let tree = MerkleTree::create(&blob_leaves, depth as usize); + let (_, mut proof) = tree + .generate_proof(index, depth as usize) + .map_err(Error::MerkleTreeError)?; - // Add the branch corresponding to the length mix-in. - let length = body.blob_kzg_commitments.len(); - let usize_len = std::mem::size_of::(); - let mut length_bytes = [0; BYTES_PER_CHUNK]; - length_bytes - .get_mut(0..usize_len) - .ok_or(Error::MerkleTreeError(MerkleTreeError::PleaseNotifyTheDevs))? - .copy_from_slice(&length.to_le_bytes()); - let length_root = Hash256::from_slice(length_bytes.as_slice()); - proof.push(length_root); + // Add the branch corresponding to the length mix-in. + let length = blob_leaves.len(); + let usize_len = std::mem::size_of::(); + let mut length_bytes = [0; BYTES_PER_CHUNK]; + length_bytes + .get_mut(0..usize_len) + .ok_or(Error::MerkleTreeError(MerkleTreeError::PleaseNotifyTheDevs))? + .copy_from_slice(&length.to_le_bytes()); + let length_root = Hash256::from_slice(length_bytes.as_slice()); + proof.push(length_root); - // Part 2 - // Branches for `BeaconBlockBody` container - let leaves = [ - body.randao_reveal.tree_hash_root(), - body.eth1_data.tree_hash_root(), - body.graffiti.tree_hash_root(), - body.proposer_slashings.tree_hash_root(), - body.attester_slashings.tree_hash_root(), - body.attestations.tree_hash_root(), - body.deposits.tree_hash_root(), - body.voluntary_exits.tree_hash_root(), - body.sync_aggregate.tree_hash_root(), - body.execution_payload.tree_hash_root(), - body.bls_to_execution_changes.tree_hash_root(), - body.blob_kzg_commitments.tree_hash_root(), - ]; - let beacon_block_body_depth = leaves.len().next_power_of_two().ilog2() as usize; - let tree = MerkleTree::create(&leaves, beacon_block_body_depth); - let (_, mut proof_body) = tree - .generate_proof(BLOB_KZG_COMMITMENTS_INDEX, beacon_block_body_depth) - .map_err(Error::MerkleTreeError)?; - // Join the proofs for the subtree and the main tree - proof.append(&mut proof_body); + // Part 2 + // Branches for `BeaconBlockBody` container + let body_leaves = self.body_merkle_leaves(); + let beacon_block_body_depth = body_leaves.len().next_power_of_two().ilog2() as usize; + let tree = MerkleTree::create(&body_leaves, beacon_block_body_depth); + let (_, mut proof_body) = tree + .generate_proof(BLOB_KZG_COMMITMENTS_INDEX, beacon_block_body_depth) + .map_err(Error::MerkleTreeError)?; + // Join the proofs for the subtree and the main tree + proof.append(&mut proof_body); + debug_assert_eq!(proof.len(), E::kzg_proof_inclusion_proof_depth()); - debug_assert_eq!(proof.len(), E::kzg_proof_inclusion_proof_depth()); - Ok(proof.into()) - } - // TODO(electra): De-duplicate proof computation. - Self::Electra(body) => { - // We compute the branches by generating 2 merkle trees: - // 1. Merkle tree for the `blob_kzg_commitments` List object - // 2. Merkle tree for the `BeaconBlockBody` container - // We then merge the branches for both the trees all the way up to the root. - - // Part1 (Branches for the subtree rooted at `blob_kzg_commitments`) - // - // Branches for `blob_kzg_commitments` without length mix-in - let depth = E::max_blob_commitments_per_block() - .next_power_of_two() - .ilog2(); - let leaves: Vec<_> = body - .blob_kzg_commitments - .iter() - .map(|commitment| commitment.tree_hash_root()) - .collect(); - let tree = MerkleTree::create(&leaves, depth as usize); - let (_, mut proof) = tree - .generate_proof(index, depth as usize) - .map_err(Error::MerkleTreeError)?; - - // Add the branch corresponding to the length mix-in. - let length = body.blob_kzg_commitments.len(); - let usize_len = std::mem::size_of::(); - let mut length_bytes = [0; BYTES_PER_CHUNK]; - length_bytes - .get_mut(0..usize_len) - .ok_or(Error::MerkleTreeError(MerkleTreeError::PleaseNotifyTheDevs))? - .copy_from_slice(&length.to_le_bytes()); - let length_root = Hash256::from_slice(length_bytes.as_slice()); - proof.push(length_root); - - // Part 2 - // Branches for `BeaconBlockBody` container - let leaves = [ - body.randao_reveal.tree_hash_root(), - body.eth1_data.tree_hash_root(), - body.graffiti.tree_hash_root(), - body.proposer_slashings.tree_hash_root(), - body.attester_slashings.tree_hash_root(), - body.attestations.tree_hash_root(), - body.deposits.tree_hash_root(), - body.voluntary_exits.tree_hash_root(), - body.sync_aggregate.tree_hash_root(), - body.execution_payload.tree_hash_root(), - body.bls_to_execution_changes.tree_hash_root(), - body.blob_kzg_commitments.tree_hash_root(), - body.consolidations.tree_hash_root(), - ]; - let beacon_block_body_depth = leaves.len().next_power_of_two().ilog2() as usize; - let tree = MerkleTree::create(&leaves, beacon_block_body_depth); - let (_, mut proof_body) = tree - .generate_proof(BLOB_KZG_COMMITMENTS_INDEX, beacon_block_body_depth) - .map_err(Error::MerkleTreeError)?; - // Join the proofs for the subtree and the main tree - proof.append(&mut proof_body); - - debug_assert_eq!(proof.len(), E::kzg_proof_inclusion_proof_depth()); - Ok(proof.into()) - } - } + Ok(proof.into()) } /// Return `true` if this block body has a non-zero number of blobs. diff --git a/lcli/Cargo.toml b/lcli/Cargo.toml index 5d948a25c3..73dd93dc3e 100644 --- a/lcli/Cargo.toml +++ b/lcli/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "lcli" description = "Lighthouse CLI (modeled after zcli)" -version = "5.1.3" +version = "5.2.0" authors = ["Paul Hauner "] edition = { workspace = true } @@ -24,17 +24,14 @@ ethereum_hashing = { workspace = true } ethereum_ssz = { workspace = true } environment = { workspace = true } eth2_network_config = { workspace = true } -genesis = { workspace = true } deposit_contract = { workspace = true } tree_hash = { workspace = true } clap_utils = { workspace = true } lighthouse_network = { workspace = true } -validator_dir = { workspace = true, features = ["insecure_keys"] } +validator_dir = { workspace = true } lighthouse_version = { workspace = true } account_utils = { workspace = true } eth2_wallet = { workspace = true } -eth1_test_rig = { workspace = true } -sensitive_url = { workspace = true } eth2 = { workspace = true } snap = { workspace = true } beacon_chain = { workspace = true } diff --git a/lcli/src/change_genesis_time.rs b/lcli/src/change_genesis_time.rs deleted file mode 100644 index 1b100d4644..0000000000 --- a/lcli/src/change_genesis_time.rs +++ /dev/null @@ -1,45 +0,0 @@ -use clap::ArgMatches; -use eth2_network_config::Eth2NetworkConfig; -use ssz::Encode; -use std::fs::File; -use std::io::{Read, Write}; -use std::path::PathBuf; -use types::{BeaconState, EthSpec}; - -pub fn run(testnet_dir: PathBuf, matches: &ArgMatches) -> Result<(), String> { - let path = matches - .get_one::("ssz-state") - .ok_or("ssz-state not specified")? - .parse::() - .map_err(|e| format!("Unable to parse ssz-state: {}", e))?; - - let genesis_time = matches - .get_one::("genesis-time") - .ok_or("genesis-time not specified")? - .parse::() - .map_err(|e| format!("Unable to parse genesis-time: {}", e))?; - - let eth2_network_config = Eth2NetworkConfig::load(testnet_dir)?; - let spec = ð2_network_config.chain_spec::()?; - - let mut state: BeaconState = { - let mut file = File::open(&path).map_err(|e| format!("Unable to open file: {}", e))?; - - let mut ssz = vec![]; - - file.read_to_end(&mut ssz) - .map_err(|e| format!("Unable to read file: {}", e))?; - - BeaconState::from_ssz_bytes(&ssz, spec) - .map_err(|e| format!("Unable to decode SSZ: {:?}", e))? - }; - - *state.genesis_time_mut() = genesis_time; - - let mut file = File::create(path).map_err(|e| format!("Unable to create file: {}", e))?; - - file.write_all(&state.as_ssz_bytes()) - .map_err(|e| format!("Unable to write to file: {}", e))?; - - Ok(()) -} diff --git a/lcli/src/create_payload_header.rs b/lcli/src/create_payload_header.rs deleted file mode 100644 index 65ee40a5e7..0000000000 --- a/lcli/src/create_payload_header.rs +++ /dev/null @@ -1,69 +0,0 @@ -use clap::ArgMatches; -use clap_utils::{parse_optional, parse_required}; -use ssz::Encode; -use std::fs::File; -use std::io::Write; -use std::time::{SystemTime, UNIX_EPOCH}; -use types::{ - EthSpec, ExecutionPayloadHeader, ExecutionPayloadHeaderBellatrix, - ExecutionPayloadHeaderCapella, ExecutionPayloadHeaderDeneb, ExecutionPayloadHeaderElectra, - ForkName, -}; - -pub fn run(matches: &ArgMatches) -> Result<(), String> { - let eth1_block_hash = parse_required(matches, "execution-block-hash")?; - let genesis_time = parse_optional(matches, "genesis-time")?.unwrap_or( - SystemTime::now() - .duration_since(UNIX_EPOCH) - .map_err(|e| format!("Unable to get time: {:?}", e))? - .as_secs(), - ); - let base_fee_per_gas = parse_required(matches, "base-fee-per-gas")?; - let gas_limit = parse_required(matches, "gas-limit")?; - let file_name = matches - .get_one::("file") - .ok_or("No file supplied")?; - let fork_name: ForkName = parse_optional(matches, "fork")?.unwrap_or(ForkName::Bellatrix); - - let execution_payload_header: ExecutionPayloadHeader = match fork_name { - ForkName::Base | ForkName::Altair => return Err("invalid fork name".to_string()), - ForkName::Bellatrix => ExecutionPayloadHeader::Bellatrix(ExecutionPayloadHeaderBellatrix { - gas_limit, - base_fee_per_gas, - timestamp: genesis_time, - block_hash: eth1_block_hash, - prev_randao: eth1_block_hash.into_root(), - ..ExecutionPayloadHeaderBellatrix::default() - }), - ForkName::Capella => ExecutionPayloadHeader::Capella(ExecutionPayloadHeaderCapella { - gas_limit, - base_fee_per_gas, - timestamp: genesis_time, - block_hash: eth1_block_hash, - prev_randao: eth1_block_hash.into_root(), - ..ExecutionPayloadHeaderCapella::default() - }), - ForkName::Deneb => ExecutionPayloadHeader::Deneb(ExecutionPayloadHeaderDeneb { - gas_limit, - base_fee_per_gas, - timestamp: genesis_time, - block_hash: eth1_block_hash, - prev_randao: eth1_block_hash.into_root(), - ..ExecutionPayloadHeaderDeneb::default() - }), - ForkName::Electra => ExecutionPayloadHeader::Electra(ExecutionPayloadHeaderElectra { - gas_limit, - base_fee_per_gas, - timestamp: genesis_time, - block_hash: eth1_block_hash, - prev_randao: eth1_block_hash.into_root(), - ..ExecutionPayloadHeaderElectra::default() - }), - }; - - let mut file = File::create(file_name).map_err(|_| "Unable to create file".to_string())?; - let bytes = execution_payload_header.as_ssz_bytes(); - file.write_all(bytes.as_slice()) - .map_err(|_| "Unable to write to file".to_string())?; - Ok(()) -} diff --git a/lcli/src/deploy_deposit_contract.rs b/lcli/src/deploy_deposit_contract.rs deleted file mode 100644 index 0674028bee..0000000000 --- a/lcli/src/deploy_deposit_contract.rs +++ /dev/null @@ -1,32 +0,0 @@ -use clap::ArgMatches; -use environment::Environment; -use types::EthSpec; - -use eth1_test_rig::{Http, Provider}; - -pub fn run(env: Environment, matches: &ArgMatches) -> Result<(), String> { - let eth1_http: String = clap_utils::parse_required(matches, "eth1-http")?; - let confirmations: usize = clap_utils::parse_required(matches, "confirmations")?; - let validator_count: Option = clap_utils::parse_optional(matches, "validator-count")?; - - let client = Provider::::try_from(ð1_http) - .map_err(|e| format!("Unable to connect to eth1 HTTP: {:?}", e))?; - - env.runtime().block_on(async { - let contract = eth1_test_rig::DepositContract::deploy(client, confirmations, None) - .await - .map_err(|e| format!("Failed to deploy deposit contract: {:?}", e))?; - - println!("Deposit contract address: {:?}", contract.address()); - - // Deposit insecure validators to the deposit contract created - if let Some(validator_count) = validator_count { - let amount = env.eth2_config.spec.max_effective_balance; - for i in 0..validator_count { - println!("Submitting deposit for validator {}...", i); - contract.deposit_deterministic_async::(i, amount).await?; - } - } - Ok(()) - }) -} diff --git a/lcli/src/eth1_genesis.rs b/lcli/src/eth1_genesis.rs deleted file mode 100644 index 1879851841..0000000000 --- a/lcli/src/eth1_genesis.rs +++ /dev/null @@ -1,66 +0,0 @@ -use clap::ArgMatches; -use environment::Environment; -use eth2_network_config::Eth2NetworkConfig; -use genesis::{Eth1Config, Eth1Endpoint, Eth1GenesisService}; -use sensitive_url::SensitiveUrl; -use ssz::Encode; -use std::cmp::max; -use std::path::PathBuf; -use std::time::Duration; -use types::EthSpec; - -/// Interval between polling the eth1 node for genesis information. -pub const ETH1_GENESIS_UPDATE_INTERVAL: Duration = Duration::from_millis(7_000); - -pub fn run( - env: Environment, - testnet_dir: PathBuf, - matches: &ArgMatches, -) -> Result<(), String> { - let endpoints = matches - .get_one::("eth1-endpoint") - .map(|e| { - warn!("The --eth1-endpoint flag is deprecated. Please use --eth1-endpoints instead"); - String::from(e) - }) - .or_else(|| { - matches - .get_one::("eth1-endpoints") - .map(String::from) - }); - - let mut eth2_network_config = Eth2NetworkConfig::load(testnet_dir.clone())?; - - let spec = eth2_network_config.chain_spec::()?; - - let mut config = Eth1Config::default(); - if let Some(v) = endpoints.clone() { - let endpoint = SensitiveUrl::parse(&v) - .map_err(|e| format!("Unable to parse eth1 endpoint URL: {:?}", e))?; - config.endpoint = Eth1Endpoint::NoAuth(endpoint); - } - config.deposit_contract_address = format!("{:?}", spec.deposit_contract_address); - config.deposit_contract_deploy_block = eth2_network_config.deposit_contract_deploy_block; - config.lowest_cached_block_number = eth2_network_config.deposit_contract_deploy_block; - config.follow_distance = spec.eth1_follow_distance / 2; - config.node_far_behind_seconds = max(5, config.follow_distance) * spec.seconds_per_eth1_block; - - let genesis_service = - Eth1GenesisService::new(config, env.core_context().log().clone(), spec.clone())?; - - env.runtime().block_on(async { - let _ = genesis_service - .wait_for_genesis_state::(ETH1_GENESIS_UPDATE_INTERVAL, spec) - .await - .map(move |genesis_state| { - eth2_network_config.genesis_state_bytes = Some(genesis_state.as_ssz_bytes().into()); - eth2_network_config.force_write_to_file(testnet_dir) - }) - .map_err(|e| format!("Failed to find genesis: {}", e))?; - - info!("Starting service to produce genesis BeaconState from eth1"); - info!("Connecting to eth1 http endpoints: {:?}", endpoints); - - Ok(()) - }) -} diff --git a/lcli/src/insecure_validators.rs b/lcli/src/insecure_validators.rs deleted file mode 100644 index 67d04c2cd5..0000000000 --- a/lcli/src/insecure_validators.rs +++ /dev/null @@ -1,64 +0,0 @@ -use clap::ArgMatches; -use std::fs; -use std::path::PathBuf; -use validator_dir::Builder as ValidatorBuilder; - -/// Generates validator directories with INSECURE, deterministic keypairs given the range -/// of indices, validator and secret directories. -pub fn generate_validator_dirs( - indices: &[usize], - validators_dir: PathBuf, - secrets_dir: PathBuf, -) -> Result<(), String> { - if !validators_dir.exists() { - fs::create_dir_all(&validators_dir) - .map_err(|e| format!("Unable to create validators dir: {:?}", e))?; - } - - if !secrets_dir.exists() { - fs::create_dir_all(&secrets_dir) - .map_err(|e| format!("Unable to create secrets dir: {:?}", e))?; - } - - for i in indices { - println!("Validator {}", i + 1); - - ValidatorBuilder::new(validators_dir.clone()) - .password_dir(secrets_dir.clone()) - .store_withdrawal_keystore(false) - .insecure_voting_keypair(*i) - .map_err(|e| format!("Unable to generate keys: {:?}", e))? - .build() - .map_err(|e| format!("Unable to build validator: {:?}", e))?; - } - - Ok(()) -} - -pub fn run(matches: &ArgMatches) -> Result<(), String> { - let validator_count: usize = clap_utils::parse_required(matches, "count")?; - let base_dir: PathBuf = clap_utils::parse_required(matches, "base-dir")?; - let node_count: Option = clap_utils::parse_optional(matches, "node-count")?; - if let Some(node_count) = node_count { - let validators_per_node = validator_count / node_count; - let validator_range = (0..validator_count).collect::>(); - let indices_range = validator_range - .chunks(validators_per_node) - .collect::>(); - - for (i, indices) in indices_range.iter().enumerate() { - let validators_dir = base_dir.join(format!("node_{}", i + 1)).join("validators"); - let secrets_dir = base_dir.join(format!("node_{}", i + 1)).join("secrets"); - generate_validator_dirs(indices, validators_dir, secrets_dir)?; - } - } else { - let validators_dir = base_dir.join("validators"); - let secrets_dir = base_dir.join("secrets"); - generate_validator_dirs( - (0..validator_count).collect::>().as_slice(), - validators_dir, - secrets_dir, - )?; - } - Ok(()) -} diff --git a/lcli/src/interop_genesis.rs b/lcli/src/interop_genesis.rs deleted file mode 100644 index 4987a84476..0000000000 --- a/lcli/src/interop_genesis.rs +++ /dev/null @@ -1,49 +0,0 @@ -use clap::ArgMatches; -use clap_utils::parse_ssz_optional; -use eth2_network_config::Eth2NetworkConfig; -use genesis::{interop_genesis_state, DEFAULT_ETH1_BLOCK_HASH}; -use ssz::Encode; -use std::path::PathBuf; -use std::time::{SystemTime, UNIX_EPOCH}; -use types::{test_utils::generate_deterministic_keypairs, EthSpec, Hash256}; - -pub fn run(testnet_dir: PathBuf, matches: &ArgMatches) -> Result<(), String> { - let validator_count = matches - .get_one::("validator-count") - .ok_or("validator-count not specified")? - .parse::() - .map_err(|e| format!("Unable to parse validator-count: {}", e))?; - - let genesis_time = if let Some(genesis_time) = matches.get_one::("genesis-time") { - genesis_time - .parse::() - .map_err(|e| format!("Unable to parse genesis-time: {}", e))? - } else { - SystemTime::now() - .duration_since(UNIX_EPOCH) - .map_err(|e| format!("Unable to get time: {:?}", e))? - .as_secs() - }; - - let mut eth2_network_config = Eth2NetworkConfig::load(testnet_dir.clone())?; - - let mut spec = eth2_network_config.chain_spec::()?; - - if let Some(v) = parse_ssz_optional(matches, "genesis-fork-version")? { - spec.genesis_fork_version = v; - } - - let keypairs = generate_deterministic_keypairs(validator_count); - let genesis_state = interop_genesis_state::( - &keypairs, - genesis_time, - Hash256::from_slice(DEFAULT_ETH1_BLOCK_HASH), - None, - &spec, - )?; - - eth2_network_config.genesis_state_bytes = Some(genesis_state.as_ssz_bytes().into()); - eth2_network_config.force_write_to_file(testnet_dir)?; - - Ok(()) -} diff --git a/lcli/src/main.rs b/lcli/src/main.rs index e0e3b9b461..911e9bdcac 100644 --- a/lcli/src/main.rs +++ b/lcli/src/main.rs @@ -1,20 +1,12 @@ #[macro_use] extern crate log; mod block_root; -mod change_genesis_time; mod check_deposit_data; -mod create_payload_header; -mod deploy_deposit_contract; -mod eth1_genesis; mod generate_bootnode_enr; mod indexed_attestations; -mod insecure_validators; -mod interop_genesis; mod mnemonic_validators; mod mock_el; -mod new_testnet; mod parse_ssz; -mod replace_state_pubkeys; mod skip_slots; mod state_root; mod transition_blocks; @@ -272,489 +264,6 @@ fn main() { .display_order(0) ) ) - .subcommand( - Command::new("deploy-deposit-contract") - .about( - "Deploy a testing eth1 deposit contract.", - ) - .arg( - Arg::new("eth1-http") - .long("eth1-http") - .short('e') - .value_name("ETH1_HTTP_PATH") - .help("Path to an Eth1 JSON-RPC IPC endpoint") - .action(ArgAction::Set) - .required(true) - .display_order(0) - ) - .arg( - Arg::new("confirmations") - .value_name("INTEGER") - .long("confirmations") - .action(ArgAction::Set) - .default_value("3") - .help("The number of block confirmations before declaring the contract deployed.") - .display_order(0) - ) - .arg( - Arg::new("validator-count") - .value_name("VALIDATOR_COUNT") - .long("validator-count") - .action(ArgAction::Set) - .help("If present, makes `validator_count` number of INSECURE deterministic deposits after \ - deploying the deposit contract." - ) - .display_order(0) - ) - ) - .subcommand( - Command::new("eth1-genesis") - .about("Listens to the eth1 chain and finds the genesis beacon state") - .arg( - Arg::new("eth1-endpoint") - .short('e') - .long("eth1-endpoint") - .value_name("HTTP_SERVER") - .action(ArgAction::Set) - .help("Deprecated. Use --eth1-endpoints.") - .display_order(0) - ) - .arg( - Arg::new("eth1-endpoints") - .long("eth1-endpoints") - .value_name("HTTP_SERVER_LIST") - .action(ArgAction::Set) - .conflicts_with("eth1-endpoint") - .help( - "One or more comma-delimited URLs to eth1 JSON-RPC http APIs. \ - If multiple endpoints are given the endpoints are used as \ - fallback in the given order.", - ) - .display_order(0) - ), - ) - .subcommand( - Command::new("interop-genesis") - .about("Produces an interop-compatible genesis state using deterministic keypairs") - .arg( - Arg::new("validator-count") - .long("validator-count") - .index(1) - .value_name("INTEGER") - .action(ArgAction::Set) - .default_value("1024") - .help("The number of validators in the genesis state.") - .display_order(0) - ) - .arg( - Arg::new("genesis-time") - .long("genesis-time") - .short('t') - .value_name("UNIX_EPOCH") - .action(ArgAction::Set) - .help("The value for state.genesis_time. Defaults to now.") - .display_order(0) - ) - .arg( - Arg::new("genesis-fork-version") - .long("genesis-fork-version") - .value_name("HEX") - .action(ArgAction::Set) - .help( - "Used to avoid reply attacks between testnets. Recommended to set to - non-default.", - ) - .display_order(0) - ), - ) - .subcommand( - Command::new("change-genesis-time") - .about( - "Loads a file with an SSZ-encoded BeaconState and modifies the genesis time.", - ) - .arg( - Arg::new("ssz-state") - .index(1) - .value_name("PATH") - .action(ArgAction::Set) - .required(true) - .help("The path to the SSZ file") - .display_order(0) - ) - .arg( - Arg::new("genesis-time") - .index(2) - .value_name("UNIX_EPOCH") - .action(ArgAction::Set) - .required(true) - .help("The value for state.genesis_time.") - .display_order(0) - ), - ) - .subcommand( - Command::new("replace-state-pubkeys") - .about( - "Loads a file with an SSZ-encoded BeaconState and replaces \ - all the validator pubkeys with ones derived from the mnemonic \ - such that validator indices correspond to EIP-2334 voting keypair \ - derivation paths.", - ) - .arg( - Arg::new("ssz-state") - .index(1) - .value_name("PATH") - .action(ArgAction::Set) - .required(true) - .help("The path to the SSZ file") - .display_order(0) - ) - .arg( - Arg::new("mnemonic") - .index(2) - .value_name("BIP39_MNENMONIC") - .action(ArgAction::Set) - .default_value( - "replace nephew blur decorate waste convince soup column \ - orient excite play baby", - ) - .help("The mnemonic for key derivation.") - .display_order(0) - ), - ) - .subcommand( - Command::new("create-payload-header") - .about("Generates an SSZ file containing bytes for an `ExecutionPayloadHeader`. \ - Useful as input for `lcli new-testnet --execution-payload-header FILE`. If `--fork` \ - is not provided, a payload header for the `Bellatrix` fork will be created.") - .arg( - Arg::new("execution-block-hash") - .long("execution-block-hash") - .value_name("BLOCK_HASH") - .action(ArgAction::Set) - .help("The block hash used when generating an execution payload. This \ - value is used for `execution_payload_header.block_hash` as well as \ - `execution_payload_header.random`") - .default_value( - "0x0000000000000000000000000000000000000000000000000000000000000000", - ) - .display_order(0) - ) - .arg( - Arg::new("genesis-time") - .long("genesis-time") - .value_name("INTEGER") - .action(ArgAction::Set) - .help("The genesis time when generating an execution payload.") - .display_order(0) - ) - .arg( - Arg::new("base-fee-per-gas") - .long("base-fee-per-gas") - .value_name("INTEGER") - .action(ArgAction::Set) - .help("The base fee per gas field in the execution payload generated.") - .default_value("1000000000") - .display_order(0) - ) - .arg( - Arg::new("gas-limit") - .long("gas-limit") - .value_name("INTEGER") - .action(ArgAction::Set) - .help("The gas limit field in the execution payload generated.") - .default_value("30000000") - .display_order(0) - ) - .arg( - Arg::new("file") - .long("file") - .value_name("FILE") - .action(ArgAction::Set) - .required(true) - .help("Output file") - .display_order(0) - ).arg( - Arg::new("fork") - .long("fork") - .value_name("FORK") - .action(ArgAction::Set) - .default_value("bellatrix") - .help("The fork for which the execution payload header should be created.") - .value_parser(["bellatrix", "capella", "deneb", "electra"]) - .display_order(0) - ) - ) - .subcommand( - Command::new("new-testnet") - .about( - "Produce a new testnet directory. If any of the optional flags are not - supplied the values will remain the default for the --spec flag", - ) - .arg( - Arg::new("force") - .long("force") - .short('f') - .action(ArgAction::SetTrue) - .help_heading(FLAG_HEADER) - .help("Overwrites any previous testnet configurations") - .display_order(0) - ) - .arg( - Arg::new("interop-genesis-state") - .long("interop-genesis-state") - .action(ArgAction::SetTrue) - .help_heading(FLAG_HEADER) - .help( - "If present, a interop-style genesis.ssz file will be generated.", - ) - .display_order(0) - ) - .arg( - Arg::new("derived-genesis-state") - .long("derived-genesis-state") - .action(ArgAction::SetTrue) - .help_heading(FLAG_HEADER) - .help( - "If present, a genesis.ssz file will be generated with keys generated from a given mnemonic.", - ) - .display_order(0) - ) - .arg( - Arg::new("mnemonic-phrase") - .long("mnemonic-phrase") - .value_name("MNEMONIC_PHRASE") - .action(ArgAction::Set) - .requires("derived-genesis-state") - .help("The mnemonic with which we generate the validator keys for a derived genesis state") - .display_order(0) - ) - .arg( - Arg::new("min-genesis-time") - .long("min-genesis-time") - .value_name("UNIX_SECONDS") - .action(ArgAction::Set) - .help( - "The minimum permitted genesis time. For non-eth1 testnets will be - the genesis time. Defaults to now.", - ) - .display_order(0) - ) - .arg( - Arg::new("min-genesis-active-validator-count") - .long("min-genesis-active-validator-count") - .value_name("INTEGER") - .action(ArgAction::Set) - .help("The number of validators required to trigger eth2 genesis.") - .display_order(0) - ) - .arg( - Arg::new("genesis-delay") - .long("genesis-delay") - .value_name("SECONDS") - .action(ArgAction::Set) - .help("The delay between sufficient eth1 deposits and eth2 genesis.") - .display_order(0) - ) - .arg( - Arg::new("min-deposit-amount") - .long("min-deposit-amount") - .value_name("GWEI") - .action(ArgAction::Set) - .help("The minimum permitted deposit amount.") - .display_order(0) - ) - .arg( - Arg::new("max-effective-balance") - .long("max-effective-balance") - .value_name("GWEI") - .action(ArgAction::Set) - .help("The amount required to become a validator.") - .display_order(0) - ) - .arg( - Arg::new("effective-balance-increment") - .long("effective-balance-increment") - .value_name("GWEI") - .action(ArgAction::Set) - .help("The steps in effective balance calculation.") - .display_order(0) - ) - .arg( - Arg::new("ejection-balance") - .long("ejection-balance") - .value_name("GWEI") - .action(ArgAction::Set) - .help("The balance at which a validator gets ejected.") - .display_order(0) - ) - .arg( - Arg::new("eth1-follow-distance") - .long("eth1-follow-distance") - .value_name("ETH1_BLOCKS") - .action(ArgAction::Set) - .help("The distance to follow behind the eth1 chain head.") - .display_order(0) - ) - .arg( - Arg::new("genesis-fork-version") - .long("genesis-fork-version") - .value_name("HEX") - .action(ArgAction::Set) - .help( - "Used to avoid reply attacks between testnets. Recommended to set to - non-default.", - ) - .display_order(0) - ) - .arg( - Arg::new("seconds-per-slot") - .long("seconds-per-slot") - .value_name("SECONDS") - .action(ArgAction::Set) - .help("Eth2 slot time") - .display_order(0) - ) - .arg( - Arg::new("seconds-per-eth1-block") - .long("seconds-per-eth1-block") - .value_name("SECONDS") - .action(ArgAction::Set) - .help("Eth1 block time") - .display_order(0) - ) - .arg( - Arg::new("eth1-id") - .long("eth1-id") - .value_name("ETH1_ID") - .action(ArgAction::Set) - .help("The chain id and network id for the eth1 testnet.") - .display_order(0) - ) - .arg( - Arg::new("deposit-contract-address") - .long("deposit-contract-address") - .value_name("ETH1_ADDRESS") - .action(ArgAction::Set) - .required(true) - .help("The address of the deposit contract.") - .display_order(0) - ) - .arg( - Arg::new("deposit-contract-deploy-block") - .long("deposit-contract-deploy-block") - .value_name("ETH1_BLOCK_NUMBER") - .action(ArgAction::Set) - .default_value("0") - .help( - "The block the deposit contract was deployed. Setting this is a huge - optimization for nodes, please do it.", - ) - .display_order(0) - ) - .arg( - Arg::new("altair-fork-epoch") - .long("altair-fork-epoch") - .value_name("EPOCH") - .action(ArgAction::Set) - .help( - "The epoch at which to enable the Altair hard fork", - ) - .display_order(0) - ) - .arg( - Arg::new("bellatrix-fork-epoch") - .long("bellatrix-fork-epoch") - .value_name("EPOCH") - .action(ArgAction::Set) - .help( - "The epoch at which to enable the Bellatrix hard fork", - ) - .display_order(0) - ) - .arg( - Arg::new("capella-fork-epoch") - .long("capella-fork-epoch") - .value_name("EPOCH") - .action(ArgAction::Set) - .help( - "The epoch at which to enable the Capella hard fork", - ) - .display_order(0) - ) - .arg( - Arg::new("deneb-fork-epoch") - .long("deneb-fork-epoch") - .value_name("EPOCH") - .action(ArgAction::Set) - .help( - "The epoch at which to enable the Deneb hard fork", - ) - .display_order(0) - ) - .arg( - Arg::new("electra-fork-epoch") - .long("electra-fork-epoch") - .value_name("EPOCH") - .action(ArgAction::Set) - .help( - "The epoch at which to enable the Electra hard fork", - ) - .display_order(0) - ) - .arg( - Arg::new("ttd") - .long("ttd") - .value_name("TTD") - .action(ArgAction::Set) - .help( - "The terminal total difficulty", - ) - .display_order(0) - ) - .arg( - Arg::new("eth1-block-hash") - .long("eth1-block-hash") - .value_name("BLOCK_HASH") - .action(ArgAction::Set) - .help("The eth1 block hash used when generating a genesis state.") - .display_order(0) - ) - .arg( - Arg::new("execution-payload-header") - .long("execution-payload-header") - .value_name("FILE") - .action(ArgAction::Set) - .required(false) - .help("Path to file containing `ExecutionPayloadHeader` SSZ bytes to be \ - used in the genesis state.") - .display_order(0) - ) - .arg( - Arg::new("validator-count") - .long("validator-count") - .value_name("INTEGER") - .action(ArgAction::Set) - .help("The number of validators when generating a genesis state.") - .display_order(0) - ) - .arg( - Arg::new("genesis-time") - .long("genesis-time") - .value_name("INTEGER") - .action(ArgAction::Set) - .help("The genesis time when generating a genesis state.") - .display_order(0) - ) - .arg( - Arg::new("proposer-score-boost") - .long("proposer-score-boost") - .value_name("INTEGER") - .action(ArgAction::Set) - .help("The proposer score boost to apply as a percentage, e.g. 70 = 70%") - .display_order(0) - ) - - ) .subcommand( Command::new("check-deposit-data") .about("Checks the integrity of some deposit data.") @@ -834,36 +343,6 @@ fn main() { .display_order(0) ), ) - .subcommand( - Command::new("insecure-validators") - .about("Produces validator directories with INSECURE, deterministic keypairs.") - .arg( - Arg::new("count") - .long("count") - .value_name("COUNT") - .action(ArgAction::Set) - .required(true) - .help("Produces validators in the range of 0..count.") - .display_order(0) - ) - .arg( - Arg::new("base-dir") - .long("base-dir") - .value_name("BASE_DIR") - .action(ArgAction::Set) - .required(true) - .help("The base directory where validator keypairs and secrets are stored") - .display_order(0) - ) - .arg( - Arg::new("node-count") - .long("node-count") - .value_name("NODE_COUNT") - .action(ArgAction::Set) - .help("The number of nodes to divide the validator keys to") - .display_order(0) - ) - ) .subcommand( Command::new("mnemonic-validators") .about("Produces validator directories by deriving the keys from \ @@ -1128,9 +607,6 @@ fn run(env_builder: EnvironmentBuilder, matches: &ArgMatches) -> (None, Some(network_name)) }; - // Lazily load either the testnet dir or the network config, as required. - // Some subcommands like new-testnet need the testnet dir but not the network config. - let get_testnet_dir = || testnet_dir.clone().ok_or("testnet-dir is required"); let get_network_config = || { if let Some(testnet_dir) = &testnet_dir { Eth2NetworkConfig::load(testnet_dir.clone()).map_err(|e| { @@ -1162,43 +638,10 @@ fn run(env_builder: EnvironmentBuilder, matches: &ArgMatches) -> run_parse_ssz::(network_config, matches) .map_err(|e| format!("Failed to pretty print hex: {}", e)) } - Some(("deploy-deposit-contract", matches)) => { - deploy_deposit_contract::run::(env, matches) - .map_err(|e| format!("Failed to run deploy-deposit-contract command: {}", e)) - } - Some(("eth1-genesis", matches)) => { - let testnet_dir = get_testnet_dir()?; - eth1_genesis::run::(env, testnet_dir, matches) - .map_err(|e| format!("Failed to run eth1-genesis command: {}", e)) - } - Some(("interop-genesis", matches)) => { - let testnet_dir = get_testnet_dir()?; - interop_genesis::run::(testnet_dir, matches) - .map_err(|e| format!("Failed to run interop-genesis command: {}", e)) - } - Some(("change-genesis-time", matches)) => { - let testnet_dir = get_testnet_dir()?; - change_genesis_time::run::(testnet_dir, matches) - .map_err(|e| format!("Failed to run change-genesis-time command: {}", e)) - } - Some(("create-payload-header", matches)) => create_payload_header::run::(matches) - .map_err(|e| format!("Failed to run create-payload-header command: {}", e)), - Some(("replace-state-pubkeys", matches)) => { - let testnet_dir = get_testnet_dir()?; - replace_state_pubkeys::run::(testnet_dir, matches) - .map_err(|e| format!("Failed to run replace-state-pubkeys command: {}", e)) - } - Some(("new-testnet", matches)) => { - let testnet_dir = get_testnet_dir()?; - new_testnet::run::(testnet_dir, matches) - .map_err(|e| format!("Failed to run new_testnet command: {}", e)) - } Some(("check-deposit-data", matches)) => check_deposit_data::run(matches) .map_err(|e| format!("Failed to run check-deposit-data command: {}", e)), Some(("generate-bootnode-enr", matches)) => generate_bootnode_enr::run::(matches) .map_err(|e| format!("Failed to run generate-bootnode-enr command: {}", e)), - Some(("insecure-validators", matches)) => insecure_validators::run(matches) - .map_err(|e| format!("Failed to run insecure-validators command: {}", e)), Some(("mnemonic-validators", matches)) => mnemonic_validators::run(matches) .map_err(|e| format!("Failed to run mnemonic-validators command: {}", e)), Some(("indexed-attestations", matches)) => indexed_attestations::run::(matches) diff --git a/lcli/src/new_testnet.rs b/lcli/src/new_testnet.rs deleted file mode 100644 index 57b1199917..0000000000 --- a/lcli/src/new_testnet.rs +++ /dev/null @@ -1,393 +0,0 @@ -use account_utils::eth2_keystore::keypair_from_secret; -use clap::ArgMatches; -use clap_utils::{parse_optional, parse_required, parse_ssz_optional}; -use eth2_network_config::{Eth2NetworkConfig, GenesisStateSource, TRUSTED_SETUP_BYTES}; -use eth2_wallet::bip39::Seed; -use eth2_wallet::bip39::{Language, Mnemonic}; -use eth2_wallet::{recover_validator_secret_from_mnemonic, KeyType}; -use ethereum_hashing::hash; -use ssz::Decode; -use ssz::Encode; -use state_processing::process_activations; -use state_processing::upgrade::{ - upgrade_to_altair, upgrade_to_bellatrix, upgrade_to_capella, upgrade_to_deneb, - upgrade_to_electra, -}; -use std::fs::File; -use std::io::Read; -use std::path::PathBuf; -use std::str::FromStr; -use std::time::{SystemTime, UNIX_EPOCH}; -use types::ExecutionBlockHash; -use types::{ - test_utils::generate_deterministic_keypairs, Address, BeaconState, ChainSpec, Config, Epoch, - Eth1Data, EthSpec, ExecutionPayloadHeader, ExecutionPayloadHeaderBellatrix, - ExecutionPayloadHeaderCapella, ExecutionPayloadHeaderDeneb, ExecutionPayloadHeaderElectra, - ForkName, Hash256, Keypair, PublicKey, Validator, -}; - -pub fn run(testnet_dir_path: PathBuf, matches: &ArgMatches) -> Result<(), String> { - let deposit_contract_address: Address = parse_required(matches, "deposit-contract-address")?; - let deposit_contract_deploy_block = parse_required(matches, "deposit-contract-deploy-block")?; - - let overwrite_files = matches.get_flag("force"); - - if testnet_dir_path.exists() && !overwrite_files { - return Err(format!( - "{:?} already exists, will not overwrite. Use --force to overwrite", - testnet_dir_path - )); - } - - let mut spec = E::default_spec(); - - // Update the spec value if the flag was defined. Otherwise, leave it as the default. - macro_rules! maybe_update { - ($flag: tt, $var: ident) => { - if let Some(val) = parse_optional(matches, $flag)? { - spec.$var = val - } - }; - } - - spec.deposit_contract_address = deposit_contract_address; - - maybe_update!("min-genesis-time", min_genesis_time); - maybe_update!("min-deposit-amount", min_deposit_amount); - maybe_update!( - "min-genesis-active-validator-count", - min_genesis_active_validator_count - ); - maybe_update!("max-effective-balance", max_effective_balance); - maybe_update!("effective-balance-increment", effective_balance_increment); - maybe_update!("ejection-balance", ejection_balance); - maybe_update!("eth1-follow-distance", eth1_follow_distance); - maybe_update!("genesis-delay", genesis_delay); - maybe_update!("eth1-id", deposit_chain_id); - maybe_update!("eth1-id", deposit_network_id); - maybe_update!("seconds-per-slot", seconds_per_slot); - maybe_update!("seconds-per-eth1-block", seconds_per_eth1_block); - - if let Some(v) = parse_ssz_optional(matches, "genesis-fork-version")? { - spec.genesis_fork_version = v; - } - - if let Some(proposer_score_boost) = parse_optional(matches, "proposer-score-boost")? { - spec.proposer_score_boost = Some(proposer_score_boost); - } - - if let Some(fork_epoch) = parse_optional(matches, "altair-fork-epoch")? { - spec.altair_fork_epoch = Some(fork_epoch); - } - - if let Some(fork_epoch) = parse_optional(matches, "bellatrix-fork-epoch")? { - spec.bellatrix_fork_epoch = Some(fork_epoch); - } - - if let Some(fork_epoch) = parse_optional(matches, "capella-fork-epoch")? { - spec.capella_fork_epoch = Some(fork_epoch); - } - - if let Some(fork_epoch) = parse_optional(matches, "deneb-fork-epoch")? { - spec.deneb_fork_epoch = Some(fork_epoch); - } - - if let Some(fork_epoch) = parse_optional(matches, "electra-fork-epoch")? { - spec.electra_fork_epoch = Some(fork_epoch); - } - - if let Some(ttd) = parse_optional(matches, "ttd")? { - spec.terminal_total_difficulty = ttd; - } - - let validator_count = parse_required(matches, "validator-count")?; - let execution_payload_header: Option> = - parse_optional(matches, "execution-payload-header")? - .map(|filename: String| { - let mut bytes = vec![]; - let mut file = File::open(filename.as_str()) - .map_err(|e| format!("Unable to open {}: {}", filename, e))?; - file.read_to_end(&mut bytes) - .map_err(|e| format!("Unable to read {}: {}", filename, e))?; - let fork_name = spec.fork_name_at_epoch(Epoch::new(0)); - match fork_name { - ForkName::Base | ForkName::Altair => Err(ssz::DecodeError::BytesInvalid( - "genesis fork must be post-merge".to_string(), - )), - ForkName::Bellatrix => { - ExecutionPayloadHeaderBellatrix::::from_ssz_bytes(bytes.as_slice()) - .map(ExecutionPayloadHeader::Bellatrix) - } - ForkName::Capella => { - ExecutionPayloadHeaderCapella::::from_ssz_bytes(bytes.as_slice()) - .map(ExecutionPayloadHeader::Capella) - } - ForkName::Deneb => { - ExecutionPayloadHeaderDeneb::::from_ssz_bytes(bytes.as_slice()) - .map(ExecutionPayloadHeader::Deneb) - } - ForkName::Electra => { - ExecutionPayloadHeaderElectra::::from_ssz_bytes(bytes.as_slice()) - .map(ExecutionPayloadHeader::Electra) - } - } - .map_err(|e| format!("SSZ decode failed: {:?}", e)) - }) - .transpose()?; - - let (eth1_block_hash, genesis_time) = if let Some(payload) = execution_payload_header.as_ref() { - let eth1_block_hash = - parse_optional(matches, "eth1-block-hash")?.unwrap_or_else(|| payload.block_hash()); - let genesis_time = - parse_optional(matches, "genesis-time")?.unwrap_or_else(|| payload.timestamp()); - (eth1_block_hash, genesis_time) - } else { - let eth1_block_hash = parse_required(matches, "eth1-block-hash").map_err(|_| { - "One of `--execution-payload-header` or `--eth1-block-hash` must be set".to_string() - })?; - let genesis_time = parse_optional(matches, "genesis-time")?.unwrap_or( - SystemTime::now() - .duration_since(UNIX_EPOCH) - .map_err(|e| format!("Unable to get time: {:?}", e))? - .as_secs(), - ); - (eth1_block_hash, genesis_time) - }; - - let genesis_state_bytes = if matches.get_flag("interop-genesis-state") { - let keypairs = generate_deterministic_keypairs(validator_count); - let keypairs: Vec<_> = keypairs.into_iter().map(|kp| (kp.clone(), kp)).collect(); - - let genesis_state = initialize_state_with_validators::( - &keypairs, - genesis_time, - eth1_block_hash.into_root(), - execution_payload_header, - &spec, - )?; - - Some(genesis_state.as_ssz_bytes()) - } else if matches.get_flag("derived-genesis-state") { - let mnemonic_phrase: String = clap_utils::parse_required(matches, "mnemonic-phrase")?; - let mnemonic = Mnemonic::from_phrase(&mnemonic_phrase, Language::English).map_err(|e| { - format!( - "Unable to derive mnemonic from string {:?}: {:?}", - mnemonic_phrase, e - ) - })?; - let seed = Seed::new(&mnemonic, ""); - let keypairs = (0..validator_count as u32) - .map(|index| { - let (secret, _) = - recover_validator_secret_from_mnemonic(seed.as_bytes(), index, KeyType::Voting) - .unwrap(); - - let voting_keypair = keypair_from_secret(secret.as_bytes()).unwrap(); - - let (secret, _) = recover_validator_secret_from_mnemonic( - seed.as_bytes(), - index, - KeyType::Withdrawal, - ) - .unwrap(); - let withdrawal_keypair = keypair_from_secret(secret.as_bytes()).unwrap(); - (voting_keypair, withdrawal_keypair) - }) - .collect::>(); - let genesis_state = initialize_state_with_validators::( - &keypairs, - genesis_time, - eth1_block_hash.into_root(), - execution_payload_header, - &spec, - )?; - Some(genesis_state.as_ssz_bytes()) - } else { - None - }; - - let kzg_trusted_setup = if let Some(epoch) = spec.deneb_fork_epoch { - // Only load the trusted setup if the deneb fork epoch is set - if epoch != Epoch::max_value() { - Some(TRUSTED_SETUP_BYTES.to_vec()) - } else { - None - } - } else { - None - }; - let testnet = Eth2NetworkConfig { - deposit_contract_deploy_block, - boot_enr: Some(vec![]), - genesis_state_bytes: genesis_state_bytes.map(Into::into), - genesis_state_source: GenesisStateSource::IncludedBytes, - config: Config::from_chain_spec::(&spec), - kzg_trusted_setup, - }; - - testnet.write_to_file(testnet_dir_path, overwrite_files) -} - -/// Returns a `BeaconState` with the given validator keypairs embedded into the -/// genesis state. This allows us to start testnets without having to deposit validators -/// manually. -/// -/// The optional `execution_payload_header` allows us to start a network from the bellatrix -/// fork without the need to transition to altair and bellatrix. -/// -/// We need to ensure that `eth1_block_hash` is equal to the genesis block hash that is -/// generated from the execution side `genesis.json`. -fn initialize_state_with_validators( - keypairs: &[(Keypair, Keypair)], // Voting and Withdrawal keypairs - genesis_time: u64, - eth1_block_hash: Hash256, - execution_payload_header: Option>, - spec: &ChainSpec, -) -> Result, String> { - // If no header is provided, then start from a Bellatrix state by default - let default_header: ExecutionPayloadHeader = - ExecutionPayloadHeader::Bellatrix(ExecutionPayloadHeaderBellatrix { - block_hash: ExecutionBlockHash::from_root(eth1_block_hash), - parent_hash: ExecutionBlockHash::zero(), - ..ExecutionPayloadHeaderBellatrix::default() - }); - let execution_payload_header = execution_payload_header.unwrap_or(default_header); - // Empty eth1 data - let eth1_data = Eth1Data { - block_hash: eth1_block_hash, - deposit_count: 0, - deposit_root: Hash256::from_str( - "0xd70a234731285c6804c2a4f56711ddb8c82c99740f207854891028af34e27e5e", - ) - .unwrap(), // empty deposit tree root - }; - let mut state = BeaconState::new(genesis_time, eth1_data, spec); - - // Seed RANDAO with Eth1 entropy - state.fill_randao_mixes_with(eth1_block_hash).unwrap(); - - for keypair in keypairs.iter() { - let withdrawal_credentials = |pubkey: &PublicKey| { - let mut credentials = hash(&pubkey.as_ssz_bytes()); - credentials[0] = spec.bls_withdrawal_prefix_byte; - Hash256::from_slice(&credentials) - }; - let amount = spec.max_effective_balance; - // Create a new validator. - let validator = Validator { - pubkey: keypair.0.pk.clone().into(), - withdrawal_credentials: withdrawal_credentials(&keypair.1.pk), - activation_eligibility_epoch: spec.far_future_epoch, - activation_epoch: spec.far_future_epoch, - exit_epoch: spec.far_future_epoch, - withdrawable_epoch: spec.far_future_epoch, - effective_balance: std::cmp::min( - amount - amount % (spec.effective_balance_increment), - spec.max_effective_balance, - ), - slashed: false, - }; - state.validators_mut().push(validator).unwrap(); - state.balances_mut().push(amount).unwrap(); - } - - process_activations(&mut state, spec).unwrap(); - - if spec - .altair_fork_epoch - .map_or(false, |fork_epoch| fork_epoch == E::genesis_epoch()) - { - upgrade_to_altair(&mut state, spec).unwrap(); - - state.fork_mut().previous_version = spec.altair_fork_version; - } - - // Similarly, perform an upgrade to Bellatrix if configured from genesis. - if spec - .bellatrix_fork_epoch - .map_or(false, |fork_epoch| fork_epoch == E::genesis_epoch()) - { - upgrade_to_bellatrix(&mut state, spec).unwrap(); - - // Remove intermediate Altair fork from `state.fork`. - state.fork_mut().previous_version = spec.bellatrix_fork_version; - - // Override latest execution payload header. - // See https://github.com/ethereum/consensus-specs/blob/v1.1.0/specs/bellatrix/beacon-chain.md#testing - if let ExecutionPayloadHeader::Bellatrix(ref header) = execution_payload_header { - *state - .latest_execution_payload_header_bellatrix_mut() - .or(Err("mismatched fork".to_string()))? = header.clone(); - } - } - - // Similarly, perform an upgrade to Capella if configured from genesis. - if spec - .capella_fork_epoch - .map_or(false, |fork_epoch| fork_epoch == E::genesis_epoch()) - { - upgrade_to_capella(&mut state, spec).unwrap(); - - // Remove intermediate Bellatrix fork from `state.fork`. - state.fork_mut().previous_version = spec.capella_fork_version; - - // Override latest execution payload header. - // See https://github.com/ethereum/consensus-specs/blob/v1.1.0/specs/bellatrix/beacon-chain.md#testing - if let ExecutionPayloadHeader::Capella(ref header) = execution_payload_header { - *state - .latest_execution_payload_header_capella_mut() - .or(Err("mismatched fork".to_string()))? = header.clone(); - } - } - - // Similarly, perform an upgrade to Deneb if configured from genesis. - if spec - .deneb_fork_epoch - .map_or(false, |fork_epoch| fork_epoch == E::genesis_epoch()) - { - upgrade_to_deneb(&mut state, spec).unwrap(); - - // Remove intermediate Capella fork from `state.fork`. - state.fork_mut().previous_version = spec.deneb_fork_version; - - // Override latest execution payload header. - // See https://github.com/ethereum/consensus-specs/blob/v1.1.0/specs/bellatrix/beacon-chain.md#testing - if let ExecutionPayloadHeader::Deneb(ref header) = execution_payload_header { - *state - .latest_execution_payload_header_deneb_mut() - .or(Err("mismatched fork".to_string()))? = header.clone(); - } - } - - // Similarly, perform an upgrade to Electra if configured from genesis. - if spec - .electra_fork_epoch - .map_or(false, |fork_epoch| fork_epoch == E::genesis_epoch()) - { - upgrade_to_electra(&mut state, spec).unwrap(); - - // Remove intermediate Deneb fork from `state.fork`. - state.fork_mut().previous_version = spec.electra_fork_version; - - // Override latest execution payload header. - // See https://github.com/ethereum/consensus-specs/blob/v1.1.0/specs/bellatrix/beacon-chain.md#testing - if let ExecutionPayloadHeader::Electra(ref header) = execution_payload_header { - *state - .latest_execution_payload_header_electra_mut() - .or(Err("mismatched fork".to_string()))? = header.clone(); - } - } - - // Now that we have our validators, initialize the caches (including the committees) - state.build_caches(spec).unwrap(); - - // Set genesis validators root for domain separation and chain versioning - *state.genesis_validators_root_mut() = state.update_validators_tree_hash_cache().unwrap(); - - // Sanity check for state fork matching config fork. - state - .fork_name(spec) - .map_err(|e| format!("state fork mismatch: {e:?}"))?; - - Ok(state) -} diff --git a/lcli/src/replace_state_pubkeys.rs b/lcli/src/replace_state_pubkeys.rs deleted file mode 100644 index 4b8d6c8253..0000000000 --- a/lcli/src/replace_state_pubkeys.rs +++ /dev/null @@ -1,86 +0,0 @@ -use account_utils::{eth2_keystore::keypair_from_secret, mnemonic_from_phrase}; -use clap::ArgMatches; -use eth2_network_config::Eth2NetworkConfig; -use eth2_wallet::bip39::Seed; -use eth2_wallet::{recover_validator_secret_from_mnemonic, KeyType}; -use ssz::Encode; -use state_processing::common::DepositDataTree; -use std::fs::File; -use std::io::{Read, Write}; -use std::path::PathBuf; -use tree_hash::TreeHash; -use types::{BeaconState, DepositData, EthSpec, Hash256, SignatureBytes, DEPOSIT_TREE_DEPTH}; - -pub fn run(testnet_dir: PathBuf, matches: &ArgMatches) -> Result<(), String> { - let path = matches - .get_one::("ssz-state") - .ok_or("ssz-state not specified")? - .parse::() - .map_err(|e| format!("Unable to parse ssz-state: {}", e))?; - - let mnemonic_phrase = matches - .get_one::("mnemonic") - .ok_or("mnemonic not specified")?; - - let eth2_network_config = Eth2NetworkConfig::load(testnet_dir)?; - let spec = ð2_network_config.chain_spec::()?; - - let mut state: BeaconState = { - let mut file = File::open(&path).map_err(|e| format!("Unable to open file: {}", e))?; - - let mut ssz = vec![]; - - file.read_to_end(&mut ssz) - .map_err(|e| format!("Unable to read file: {}", e))?; - - BeaconState::from_ssz_bytes(&ssz, spec) - .map_err(|e| format!("Unable to decode SSZ: {:?}", e))? - }; - - let mnemonic = mnemonic_from_phrase(mnemonic_phrase)?; - let seed = Seed::new(&mnemonic, ""); - - let mut deposit_tree = DepositDataTree::create(&[], 0, DEPOSIT_TREE_DEPTH); - let mut deposit_root = Hash256::zero(); - let validators = state.validators_mut(); - for index in 0..validators.len() { - let (secret, _) = - recover_validator_secret_from_mnemonic(seed.as_bytes(), index as u32, KeyType::Voting) - .map_err(|e| format!("Unable to generate validator key: {:?}", e))?; - - let keypair = keypair_from_secret(secret.as_bytes()) - .map_err(|e| format!("Unable build keystore: {:?}", e))?; - - eprintln!("{}: {}", index, keypair.pk); - - validators.get_mut(index).unwrap().pubkey = keypair.pk.into(); - - // Update the deposit tree. - let mut deposit_data = DepositData { - pubkey: validators.get(index).unwrap().pubkey, - // Set this to a junk value since it's very time consuming to generate the withdrawal - // keys and it's not useful for the time being. - withdrawal_credentials: Hash256::zero(), - amount: spec.min_deposit_amount, - signature: SignatureBytes::empty(), - }; - deposit_data.signature = deposit_data.create_signature(&keypair.sk, spec); - deposit_tree - .push_leaf(deposit_data.tree_hash_root()) - .map_err(|e| format!("failed to create deposit tree: {:?}", e))?; - deposit_root = deposit_tree.root(); - } - - // Update the genesis validators root since we changed the validators. - *state.genesis_validators_root_mut() = state.validators().tree_hash_root(); - - // Update the deposit root with our simulated deposits. - state.eth1_data_mut().deposit_root = deposit_root; - - let mut file = File::create(path).map_err(|e| format!("Unable to create file: {}", e))?; - - file.write_all(&state.as_ssz_bytes()) - .map_err(|e| format!("Unable to write to file: {}", e))?; - - Ok(()) -} diff --git a/lighthouse/Cargo.toml b/lighthouse/Cargo.toml index b6d4166b6a..20466b5de7 100644 --- a/lighthouse/Cargo.toml +++ b/lighthouse/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "lighthouse" -version = "5.1.3" +version = "5.2.0" authors = ["Sigma Prime "] edition = { workspace = true } autotests = false -rust-version = "1.75.0" +rust-version = "1.77.0" [features] default = ["slasher-lmdb"] diff --git a/lighthouse/environment/src/lib.rs b/lighthouse/environment/src/lib.rs index e59b1d455a..a83a7a9157 100644 --- a/lighthouse/environment/src/lib.rs +++ b/lighthouse/environment/src/lib.rs @@ -36,7 +36,7 @@ use {futures::channel::oneshot, std::cell::RefCell}; pub use task_executor::test_utils::null_logger; -const LOG_CHANNEL_SIZE: usize = 2048; +const LOG_CHANNEL_SIZE: usize = 16384; const SSE_LOG_CHANNEL_SIZE: usize = 2048; /// The maximum time in seconds the client will wait for all internal tasks to shutdown. const MAXIMUM_SHUTDOWN_TIME: u64 = 15; diff --git a/lighthouse/tests/beacon_node.rs b/lighthouse/tests/beacon_node.rs index f8e1182e89..73badac913 100644 --- a/lighthouse/tests/beacon_node.rs +++ b/lighthouse/tests/beacon_node.rs @@ -2178,6 +2178,21 @@ fn slasher_broadcast_flag_no_default() { }); } #[test] +fn slasher_broadcast_flag_no_argument() { + CommandLineTest::new() + .flag("slasher", None) + .flag("slasher-max-db-size", Some("1")) + .flag("slasher-broadcast", None) + .run_with_zero_port() + .with_config(|config| { + let slasher_config = config + .slasher + .as_ref() + .expect("Unable to parse Slasher config"); + assert!(slasher_config.broadcast); + }); +} +#[test] fn slasher_broadcast_flag_true() { CommandLineTest::new() .flag("slasher", None) diff --git a/lighthouse/tests/validator_client.rs b/lighthouse/tests/validator_client.rs index 9ca6ab4333..3e85375971 100644 --- a/lighthouse/tests/validator_client.rs +++ b/lighthouse/tests/validator_client.rs @@ -593,7 +593,7 @@ fn wrong_broadcast_flag() { } #[test] -fn latency_measurement_service() { +fn disable_latency_measurement_service() { CommandLineTest::new() .flag("disable-latency-measurement-service", None) .run() @@ -601,6 +601,16 @@ fn latency_measurement_service() { assert!(!config.enable_latency_measurement_service); }); } +#[test] +fn latency_measurement_service() { + // This flag is DEPRECATED so has no effect, but should still be accepted. + CommandLineTest::new() + .flag("latency-measurement-service", Some("false")) + .run() + .with_config(|config| { + assert!(config.enable_latency_measurement_service); + }); +} #[test] fn validator_registration_batch_size() { diff --git a/scripts/local_testnet/.gitignore b/scripts/local_testnet/.gitignore new file mode 100644 index 0000000000..98d8a5a630 --- /dev/null +++ b/scripts/local_testnet/.gitignore @@ -0,0 +1 @@ +logs diff --git a/scripts/local_testnet/anvil_test_node.sh b/scripts/local_testnet/anvil_test_node.sh deleted file mode 100755 index 41be917560..0000000000 --- a/scripts/local_testnet/anvil_test_node.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env bash - -set -Eeuo pipefail - -source ./vars.env - -exec anvil \ - --balance 1000000000 \ - --gas-limit 1000000000 \ - --accounts 10 \ - --mnemonic "$ETH1_NETWORK_MNEMONIC" \ - --block-time $SECONDS_PER_ETH1_BLOCK \ - --port 8545 \ - --chain-id "$CHAIN_ID" diff --git a/scripts/local_testnet/beacon_node.sh b/scripts/local_testnet/beacon_node.sh deleted file mode 100755 index 940fe2b858..0000000000 --- a/scripts/local_testnet/beacon_node.sh +++ /dev/null @@ -1,70 +0,0 @@ -#!/usr/bin/env bash - -# -# Starts a beacon node based upon a genesis state created by `./setup.sh`. -# - -set -Eeuo pipefail - -source ./vars.env - -SUBSCRIBE_ALL_SUBNETS= -DEBUG_LEVEL=${DEBUG_LEVEL:-info} - -# Get options -while getopts "d:sh" flag; do - case "${flag}" in - d) DEBUG_LEVEL=${OPTARG};; - s) SUBSCRIBE_ALL_SUBNETS="--subscribe-all-subnets";; - h) - echo "Start a beacon node" - echo - echo "usage: $0 " - echo - echo "Options:" - echo " -s: pass --subscribe-all-subnets to 'lighthouse bn ...', default is not passed" - echo " -d: DEBUG_LEVEL, default info" - echo " -h: this help" - echo - echo "Positional arguments:" - echo " DATADIR Value for --datadir parameter" - echo " NETWORK-PORT Value for --enr-udp-port, --enr-tcp-port and --port" - echo " HTTP-PORT Value for --http-port" - echo " EXECUTION-ENDPOINT Value for --execution-endpoint" - echo " EXECUTION-JWT Value for --execution-jwt" - exit - ;; - esac -done - -# Get positional arguments -data_dir=${@:$OPTIND+0:1} -tcp_port=${@:$OPTIND+1:1} -quic_port=${@:$OPTIND+2:1} -http_port=${@:$OPTIND+3:1} -execution_endpoint=${@:$OPTIND+4:1} -execution_jwt=${@:$OPTIND+5:1} - -lighthouse_binary=lighthouse - -exec $lighthouse_binary \ - --debug-level $DEBUG_LEVEL \ - bn \ - $SUBSCRIBE_ALL_SUBNETS \ - --datadir $data_dir \ - --testnet-dir $TESTNET_DIR \ - --enable-private-discovery \ - --disable-peer-scoring \ - --staking \ - --enr-address 127.0.0.1 \ - --enr-udp-port $tcp_port \ - --enr-tcp-port $tcp_port \ - --enr-quic-port $quic_port \ - --port $tcp_port \ - --quic-port $quic_port \ - --http-port $http_port \ - --disable-packet-filter \ - --target-peers $((BN_COUNT - 1)) \ - --execution-endpoint $execution_endpoint \ - --execution-jwt $execution_jwt \ - $BN_ARGS diff --git a/scripts/local_testnet/bootnode.sh b/scripts/local_testnet/bootnode.sh deleted file mode 100755 index ca02a24140..0000000000 --- a/scripts/local_testnet/bootnode.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env bash - -# -# Generates a bootnode enr and saves it in $TESTNET/boot_enr.yaml -# Starts a bootnode from the generated enr. -# - -set -Eeuo pipefail - -source ./vars.env - -echo "Generating bootnode enr" - -lcli \ - generate-bootnode-enr \ - --ip 127.0.0.1 \ - --udp-port $BOOTNODE_PORT \ - --tcp-port $BOOTNODE_PORT \ - --genesis-fork-version $GENESIS_FORK_VERSION \ - --output-dir $DATADIR/bootnode - -bootnode_enr=`cat $DATADIR/bootnode/enr.dat` -echo "- $bootnode_enr" > $TESTNET_DIR/boot_enr.yaml - -echo "Generated bootnode enr and written to $TESTNET_DIR/boot_enr.yaml" - -DEBUG_LEVEL=${1:-info} - -echo "Starting bootnode" - -exec lighthouse boot_node \ - --testnet-dir $TESTNET_DIR \ - --port $BOOTNODE_PORT \ - --listen-address 127.0.0.1 \ - --disable-packet-filter \ - --network-dir $DATADIR/bootnode \ diff --git a/scripts/local_testnet/clean.sh b/scripts/local_testnet/clean.sh deleted file mode 100755 index cd915e470d..0000000000 --- a/scripts/local_testnet/clean.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env bash - -# -# Deletes all files associated with the local testnet. -# - -set -Eeuo pipefail - -source ./vars.env - -if [ -d $DATADIR ]; then - rm -rf $DATADIR -fi diff --git a/scripts/local_testnet/dump_logs.sh b/scripts/local_testnet/dump_logs.sh deleted file mode 100755 index 64b7942fb6..0000000000 --- a/scripts/local_testnet/dump_logs.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env bash - -# Print all the logs output from local testnet - -set -Eeuo pipefail - -source ./vars.env - -for f in "$TESTNET_DIR"/*.log -do - [[ -e "$f" ]] || break # handle the case of no *.log files - echo "=============================================================================" - echo "$f" - echo "=============================================================================" - cat "$f" - echo "" -done diff --git a/scripts/local_testnet/el_bootnode.sh b/scripts/local_testnet/el_bootnode.sh deleted file mode 100755 index ee437a491c..0000000000 --- a/scripts/local_testnet/el_bootnode.sh +++ /dev/null @@ -1,3 +0,0 @@ -priv_key="02fd74636e96a8ffac8e7b01b0de8dea94d6bcf4989513b38cf59eb32163ff91" -source ./vars.env -exec $EL_BOOTNODE_BINARY --nodekeyhex $priv_key \ No newline at end of file diff --git a/scripts/local_testnet/genesis.json b/scripts/local_testnet/genesis.json deleted file mode 100644 index 26003bed5d..0000000000 --- a/scripts/local_testnet/genesis.json +++ /dev/null @@ -1,863 +0,0 @@ -{ - "config": { - "chainId": 4242, - "homesteadBlock": 0, - "eip150Block": 0, - "eip155Block": 0, - "eip158Block": 0, - "byzantiumBlock": 0, - "constantinopleBlock": 0, - "petersburgBlock": 0, - "istanbulBlock": 0, - "berlinBlock": 0, - "londonBlock": 0, - "mergeNetsplitBlock": 0, - "shanghaiTime": 0, - "cancunTime": 0, - "pragueTime": 0, - "terminalTotalDifficulty": 0, - "terminalTotalDifficultyPassed": true - }, - "alloc": { - "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": { - "balance": "0x6d6172697573766477000000" - }, - "0x7b8C3a386C0eea54693fFB0DA17373ffC9228139": { - "balance": "10000000000000000000000000" - }, - "0xdA2DD7560DB7e212B945fC72cEB54B7D8C886D77": { - "balance": "10000000000000000000000000" - }, - "0x0000000000000000000000000000000000000000": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000001": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000002": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000003": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000004": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000005": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000006": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000007": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000008": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000009": { - "balance": "1" - }, - "0x000000000000000000000000000000000000000a": { - "balance": "1" - }, - "0x000000000000000000000000000000000000000b": { - "balance": "1" - }, - "0x000000000000000000000000000000000000000c": { - "balance": "1" - }, - "0x000000000000000000000000000000000000000d": { - "balance": "1" - }, - "0x000000000000000000000000000000000000000e": { - "balance": "1" - }, - "0x000000000000000000000000000000000000000f": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000010": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000011": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000012": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000013": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000014": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000015": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000016": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000017": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000018": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000019": { - "balance": "1" - }, - "0x000000000000000000000000000000000000001a": { - "balance": "1" - }, - "0x000000000000000000000000000000000000001b": { - "balance": "1" - }, - "0x000000000000000000000000000000000000001c": { - "balance": "1" - }, - "0x000000000000000000000000000000000000001d": { - "balance": "1" - }, - "0x000000000000000000000000000000000000001e": { - "balance": "1" - }, - "0x000000000000000000000000000000000000001f": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000020": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000021": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000022": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000023": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000024": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000025": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000026": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000027": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000028": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000029": { - "balance": "1" - }, - "0x000000000000000000000000000000000000002a": { - "balance": "1" - }, - "0x000000000000000000000000000000000000002b": { - "balance": "1" - }, - "0x000000000000000000000000000000000000002c": { - "balance": "1" - }, - "0x000000000000000000000000000000000000002d": { - "balance": "1" - }, - "0x000000000000000000000000000000000000002e": { - "balance": "1" - }, - "0x000000000000000000000000000000000000002f": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000030": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000031": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000032": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000033": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000034": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000035": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000036": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000037": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000038": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000039": { - "balance": "1" - }, - "0x000000000000000000000000000000000000003a": { - "balance": "1" - }, - "0x000000000000000000000000000000000000003b": { - "balance": "1" - }, - "0x000000000000000000000000000000000000003c": { - "balance": "1" - }, - "0x000000000000000000000000000000000000003d": { - "balance": "1" - }, - "0x000000000000000000000000000000000000003e": { - "balance": "1" - }, - "0x000000000000000000000000000000000000003f": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000040": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000041": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000042": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000043": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000044": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000045": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000046": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000047": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000048": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000049": { - "balance": "1" - }, - "0x000000000000000000000000000000000000004a": { - "balance": "1" - }, - "0x000000000000000000000000000000000000004b": { - "balance": "1" - }, - "0x000000000000000000000000000000000000004c": { - "balance": "1" - }, - "0x000000000000000000000000000000000000004d": { - "balance": "1" - }, - "0x000000000000000000000000000000000000004e": { - "balance": "1" - }, - "0x000000000000000000000000000000000000004f": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000050": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000051": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000052": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000053": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000054": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000055": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000056": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000057": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000058": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000059": { - "balance": "1" - }, - "0x000000000000000000000000000000000000005a": { - "balance": "1" - }, - "0x000000000000000000000000000000000000005b": { - "balance": "1" - }, - "0x000000000000000000000000000000000000005c": { - "balance": "1" - }, - "0x000000000000000000000000000000000000005d": { - "balance": "1" - }, - "0x000000000000000000000000000000000000005e": { - "balance": "1" - }, - "0x000000000000000000000000000000000000005f": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000060": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000061": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000062": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000063": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000064": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000065": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000066": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000067": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000068": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000069": { - "balance": "1" - }, - "0x000000000000000000000000000000000000006a": { - "balance": "1" - }, - "0x000000000000000000000000000000000000006b": { - "balance": "1" - }, - "0x000000000000000000000000000000000000006c": { - "balance": "1" - }, - "0x000000000000000000000000000000000000006d": { - "balance": "1" - }, - "0x000000000000000000000000000000000000006e": { - "balance": "1" - }, - "0x000000000000000000000000000000000000006f": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000070": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000071": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000072": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000073": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000074": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000075": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000076": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000077": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000078": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000079": { - "balance": "1" - }, - "0x000000000000000000000000000000000000007a": { - "balance": "1" - }, - "0x000000000000000000000000000000000000007b": { - "balance": "1" - }, - "0x000000000000000000000000000000000000007c": { - "balance": "1" - }, - "0x000000000000000000000000000000000000007d": { - "balance": "1" - }, - "0x000000000000000000000000000000000000007e": { - "balance": "1" - }, - "0x000000000000000000000000000000000000007f": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000080": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000081": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000082": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000083": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000084": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000085": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000086": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000087": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000088": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000089": { - "balance": "1" - }, - "0x000000000000000000000000000000000000008a": { - "balance": "1" - }, - "0x000000000000000000000000000000000000008b": { - "balance": "1" - }, - "0x000000000000000000000000000000000000008c": { - "balance": "1" - }, - "0x000000000000000000000000000000000000008d": { - "balance": "1" - }, - "0x000000000000000000000000000000000000008e": { - "balance": "1" - }, - "0x000000000000000000000000000000000000008f": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000090": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000091": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000092": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000093": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000094": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000095": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000096": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000097": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000098": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000099": { - "balance": "1" - }, - "0x000000000000000000000000000000000000009a": { - "balance": "1" - }, - "0x000000000000000000000000000000000000009b": { - "balance": "1" - }, - "0x000000000000000000000000000000000000009c": { - "balance": "1" - }, - "0x000000000000000000000000000000000000009d": { - "balance": "1" - }, - "0x000000000000000000000000000000000000009e": { - "balance": "1" - }, - "0x000000000000000000000000000000000000009f": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000a0": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000a1": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000a2": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000a3": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000a4": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000a5": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000a6": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000a7": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000a8": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000a9": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000aa": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ab": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ac": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ad": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ae": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000af": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000b0": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000b1": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000b2": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000b3": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000b4": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000b5": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000b6": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000b7": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000b8": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000b9": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ba": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000bb": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000bc": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000bd": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000be": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000bf": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000c0": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000c1": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000c2": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000c3": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000c4": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000c5": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000c6": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000c7": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000c8": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000c9": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ca": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000cb": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000cc": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000cd": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ce": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000cf": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000d0": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000d1": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000d2": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000d3": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000d4": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000d5": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000d6": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000d7": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000d8": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000d9": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000da": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000db": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000dc": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000dd": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000de": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000df": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000e0": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000e1": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000e2": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000e3": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000e4": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000e5": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000e6": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000e7": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000e8": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000e9": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ea": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000eb": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ec": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ed": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ee": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ef": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000f0": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000f1": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000f2": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000f3": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000f4": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000f5": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000f6": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000f7": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000f8": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000f9": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000fa": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000fb": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000fc": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000fd": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000fe": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ff": { - "balance": "1" - }, - "0x4242424242424242424242424242424242424242": { - "balance": "0", - "code": "0x60806040526004361061003f5760003560e01c806301ffc9a71461004457806322895118146100a4578063621fd130146101ba578063c5f2892f14610244575b600080fd5b34801561005057600080fd5b506100906004803603602081101561006757600080fd5b50357fffffffff000000000000000000000000000000000000000000000000000000001661026b565b604080519115158252519081900360200190f35b6101b8600480360360808110156100ba57600080fd5b8101906020810181356401000000008111156100d557600080fd5b8201836020820111156100e757600080fd5b8035906020019184600183028401116401000000008311171561010957600080fd5b91939092909160208101903564010000000081111561012757600080fd5b82018360208201111561013957600080fd5b8035906020019184600183028401116401000000008311171561015b57600080fd5b91939092909160208101903564010000000081111561017957600080fd5b82018360208201111561018b57600080fd5b803590602001918460018302840111640100000000831117156101ad57600080fd5b919350915035610304565b005b3480156101c657600080fd5b506101cf6110b5565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102095781810151838201526020016101f1565b50505050905090810190601f1680156102365780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561025057600080fd5b506102596110c7565b60408051918252519081900360200190f35b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a70000000000000000000000000000000000000000000000000000000014806102fe57507fffffffff0000000000000000000000000000000000000000000000000000000082167f8564090700000000000000000000000000000000000000000000000000000000145b92915050565b6030861461035d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806118056026913960400191505060405180910390fd5b602084146103b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603681526020018061179c6036913960400191505060405180910390fd5b6060821461040f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260298152602001806118786029913960400191505060405180910390fd5b670de0b6b3a7640000341015610470576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806118526026913960400191505060405180910390fd5b633b9aca003406156104cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260338152602001806117d26033913960400191505060405180910390fd5b633b9aca00340467ffffffffffffffff811115610535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602781526020018061182b6027913960400191505060405180910390fd5b6060610540826114ba565b90507f649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c589898989858a8a6105756020546114ba565b6040805160a0808252810189905290819060208201908201606083016080840160c085018e8e80828437600083820152601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690910187810386528c815260200190508c8c808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690920188810386528c5181528c51602091820193918e019250908190849084905b83811015610648578181015183820152602001610630565b50505050905090810190601f1680156106755780820380516001836020036101000a031916815260200191505b5086810383528881526020018989808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169092018881038452895181528951602091820193918b019250908190849084905b838110156106ef5781810151838201526020016106d7565b50505050905090810190601f16801561071c5780820380516001836020036101000a031916815260200191505b509d505050505050505050505050505060405180910390a1600060028a8a600060801b604051602001808484808284377fffffffffffffffffffffffffffffffff0000000000000000000000000000000090941691909301908152604080517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0818403018152601090920190819052815191955093508392506020850191508083835b602083106107fc57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016107bf565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610859573d6000803e3d6000fd5b5050506040513d602081101561086e57600080fd5b5051905060006002806108846040848a8c6116fe565b6040516020018083838082843780830192505050925050506040516020818303038152906040526040518082805190602001908083835b602083106108f857805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016108bb565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610955573d6000803e3d6000fd5b5050506040513d602081101561096a57600080fd5b5051600261097b896040818d6116fe565b60405160009060200180848480828437919091019283525050604080518083038152602092830191829052805190945090925082918401908083835b602083106109f457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016109b7565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610a51573d6000803e3d6000fd5b5050506040513d6020811015610a6657600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310610ada57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610a9d565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610b37573d6000803e3d6000fd5b5050506040513d6020811015610b4c57600080fd5b50516040805160208101858152929350600092600292839287928f928f92018383808284378083019250505093505050506040516020818303038152906040526040518082805190602001908083835b60208310610bd957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610b9c565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610c36573d6000803e3d6000fd5b5050506040513d6020811015610c4b57600080fd5b50516040518651600291889160009188916020918201918291908601908083835b60208310610ca957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610c6c565b6001836020036101000a0380198251168184511680821785525050505050509050018367ffffffffffffffff191667ffffffffffffffff1916815260180182815260200193505050506040516020818303038152906040526040518082805190602001908083835b60208310610d4e57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610d11565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610dab573d6000803e3d6000fd5b5050506040513d6020811015610dc057600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310610e3457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610df7565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610e91573d6000803e3d6000fd5b5050506040513d6020811015610ea657600080fd5b50519050858114610f02576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260548152602001806117486054913960600191505060405180910390fd5b60205463ffffffff11610f60576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806117276021913960400191505060405180910390fd5b602080546001019081905560005b60208110156110a9578160011660011415610fa0578260008260208110610f9157fe5b0155506110ac95505050505050565b600260008260208110610faf57fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061102557805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610fe8565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015611082573d6000803e3d6000fd5b5050506040513d602081101561109757600080fd5b50519250600282049150600101610f6e565b50fe5b50505050505050565b60606110c26020546114ba565b905090565b6020546000908190815b60208110156112f05781600116600114156111e6576002600082602081106110f557fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061116b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161112e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156111c8573d6000803e3d6000fd5b5050506040513d60208110156111dd57600080fd5b505192506112e2565b600283602183602081106111f657fe5b015460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061126b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161122e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156112c8573d6000803e3d6000fd5b5050506040513d60208110156112dd57600080fd5b505192505b6002820491506001016110d1565b506002826112ff6020546114ba565b600060401b6040516020018084815260200183805190602001908083835b6020831061135a57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161131d565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790527fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000095909516920191825250604080518083037ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8018152601890920190819052815191955093508392850191508083835b6020831061143f57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101611402565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa15801561149c573d6000803e3d6000fd5b5050506040513d60208110156114b157600080fd5b50519250505090565b60408051600880825281830190925260609160208201818036833701905050905060c082901b8060071a60f81b826000815181106114f457fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060061a60f81b8260018151811061153757fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060051a60f81b8260028151811061157a57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060041a60f81b826003815181106115bd57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060031a60f81b8260048151811061160057fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060021a60f81b8260058151811061164357fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060011a60f81b8260068151811061168657fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060001a60f81b826007815181106116c957fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535050919050565b6000808585111561170d578182fd5b83861115611719578182fd5b505082019391909203915056fe4465706f736974436f6e74726163743a206d65726b6c6520747265652066756c6c4465706f736974436f6e74726163743a207265636f6e7374727563746564204465706f7369744461746120646f6573206e6f74206d6174636820737570706c696564206465706f7369745f646174615f726f6f744465706f736974436f6e74726163743a20696e76616c6964207769746864726177616c5f63726564656e7469616c73206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c7565206e6f74206d756c7469706c65206f6620677765694465706f736974436f6e74726163743a20696e76616c6964207075626b6579206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f20686967684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f206c6f774465706f736974436f6e74726163743a20696e76616c6964207369676e6174757265206c656e677468a26469706673582212201dd26f37a621703009abf16e77e69c93dc50c79db7f6cc37543e3e0e3decdc9764736f6c634300060b0033", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000022": "0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b", - "0x0000000000000000000000000000000000000000000000000000000000000023": "0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71", - "0x0000000000000000000000000000000000000000000000000000000000000024": "0xc78009fdf07fc56a11f122370658a353aaa542ed63e44c4bc15ff4cd105ab33c", - "0x0000000000000000000000000000000000000000000000000000000000000025": "0x536d98837f2dd165a55d5eeae91485954472d56f246df256bf3cae19352a123c", - "0x0000000000000000000000000000000000000000000000000000000000000026": "0x9efde052aa15429fae05bad4d0b1d7c64da64d03d7a1854a588c2cb8430c0d30", - "0x0000000000000000000000000000000000000000000000000000000000000027": "0xd88ddfeed400a8755596b21942c1497e114c302e6118290f91e6772976041fa1", - "0x0000000000000000000000000000000000000000000000000000000000000028": "0x87eb0ddba57e35f6d286673802a4af5975e22506c7cf4c64bb6be5ee11527f2c", - "0x0000000000000000000000000000000000000000000000000000000000000029": "0x26846476fd5fc54a5d43385167c95144f2643f533cc85bb9d16b782f8d7db193", - "0x000000000000000000000000000000000000000000000000000000000000002a": "0x506d86582d252405b840018792cad2bf1259f1ef5aa5f887e13cb2f0094f51e1", - "0x000000000000000000000000000000000000000000000000000000000000002b": "0xffff0ad7e659772f9534c195c815efc4014ef1e1daed4404c06385d11192e92b", - "0x000000000000000000000000000000000000000000000000000000000000002c": "0x6cf04127db05441cd833107a52be852868890e4317e6a02ab47683aa75964220", - "0x000000000000000000000000000000000000000000000000000000000000002d": "0xb7d05f875f140027ef5118a2247bbb84ce8f2f0f1123623085daf7960c329f5f", - "0x000000000000000000000000000000000000000000000000000000000000002e": "0xdf6af5f5bbdb6be9ef8aa618e4bf8073960867171e29676f8b284dea6a08a85e", - "0x000000000000000000000000000000000000000000000000000000000000002f": "0xb58d900f5e182e3c50ef74969ea16c7726c549757cc23523c369587da7293784", - "0x0000000000000000000000000000000000000000000000000000000000000030": "0xd49a7502ffcfb0340b1d7885688500ca308161a7f96b62df9d083b71fcc8f2bb", - "0x0000000000000000000000000000000000000000000000000000000000000031": "0x8fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb", - "0x0000000000000000000000000000000000000000000000000000000000000032": "0x8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab", - "0x0000000000000000000000000000000000000000000000000000000000000033": "0x95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a4", - "0x0000000000000000000000000000000000000000000000000000000000000034": "0xf893e908917775b62bff23294dbbe3a1cd8e6cc1c35b4801887b646a6f81f17f", - "0x0000000000000000000000000000000000000000000000000000000000000035": "0xcddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa", - "0x0000000000000000000000000000000000000000000000000000000000000036": "0x8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9c", - "0x0000000000000000000000000000000000000000000000000000000000000037": "0xfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167", - "0x0000000000000000000000000000000000000000000000000000000000000038": "0xe71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d7", - "0x0000000000000000000000000000000000000000000000000000000000000039": "0x31206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc0", - "0x000000000000000000000000000000000000000000000000000000000000003a": "0x21352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544", - "0x000000000000000000000000000000000000000000000000000000000000003b": "0x619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a46765", - "0x000000000000000000000000000000000000000000000000000000000000003c": "0x7cdd2986268250628d0c10e385c58c6191e6fbe05191bcc04f133f2cea72c1c4", - "0x000000000000000000000000000000000000000000000000000000000000003d": "0x848930bd7ba8cac54661072113fb278869e07bb8587f91392933374d017bcbe1", - "0x000000000000000000000000000000000000000000000000000000000000003e": "0x8869ff2c22b28cc10510d9853292803328be4fb0e80495e8bb8d271f5b889636", - "0x000000000000000000000000000000000000000000000000000000000000003f": "0xb5fe28e79f1b850f8658246ce9b6a1e7b49fc06db7143e8fe0b4f2b0c5523a5c", - "0x0000000000000000000000000000000000000000000000000000000000000040": "0x985e929f70af28d0bdd1a90a808f977f597c7c778c489e98d3bd8910d31ac0f7" - } - }, - "0x9a4aa7d9C2F6386e5F24d790eB2FFB9fd543A170": { - "balance": "1000000000000000000000000000" - }, - "0x5E3141B900ac5f5608b0d057D10d45a0e4927cD9": { - "balance": "1000000000000000000000000000" - }, - "0x7cF5Dbc49F0904065664b5B6C0d69CaB55F33988": { - "balance": "1000000000000000000000000000" - }, - "0x8D12b071A6F3823A535D38C4a583a2FA1859e822": { - "balance": "1000000000000000000000000000" - }, - "0x3B575D3cda6b30736A38B031E0d245E646A21135": { - "balance": "1000000000000000000000000000" - }, - "0x53bDe6CF93461674F590E532006b4022dA57A724": { - "balance": "1000000000000000000000000000" - } - }, - "coinbase": "0x0000000000000000000000000000000000000000", - "difficulty": "0x01", - "extraData": "", - "gasLimit": "0x400000", - "nonce": "0x1234", - "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "timestamp": "1662465600" -} diff --git a/scripts/local_testnet/geth.sh b/scripts/local_testnet/geth.sh deleted file mode 100755 index 5dc4575cf0..0000000000 --- a/scripts/local_testnet/geth.sh +++ /dev/null @@ -1,53 +0,0 @@ -set -Eeuo pipefail - -source ./vars.env - -# Get options -while getopts "d:sh" flag; do - case "${flag}" in - d) DEBUG_LEVEL=${OPTARG};; - s) SUBSCRIBE_ALL_SUBNETS="--subscribe-all-subnets";; - h) - echo "Start a geth node" - echo - echo "usage: $0 " - echo - echo "Options:" - echo " -h: this help" - echo - echo "Positional arguments:" - echo " DATADIR Value for --datadir parameter" - echo " NETWORK-PORT Value for --port" - echo " HTTP-PORT Value for --http.port" - echo " AUTH-PORT Value for --authrpc.port" - echo " GENESIS_FILE Value for geth init" - exit - ;; - esac -done - -# Get positional arguments -data_dir=${@:$OPTIND+0:1} -network_port=${@:$OPTIND+1:1} -http_port=${@:$OPTIND+2:1} -auth_port=${@:$OPTIND+3:1} -genesis_file=${@:$OPTIND+4:1} - -# Init -$GETH_BINARY init \ - --datadir $data_dir \ - $genesis_file - -echo "Completed init" - -exec $GETH_BINARY \ - --datadir $data_dir \ - --ipcdisable \ - --http \ - --http.api="engine,eth,web3,net,debug" \ - --networkid=$CHAIN_ID \ - --syncmode=full \ - --bootnodes $EL_BOOTNODE_ENODE \ - --port $network_port \ - --http.port $http_port \ - --authrpc.port $auth_port diff --git a/scripts/local_testnet/kill_processes.sh b/scripts/local_testnet/kill_processes.sh deleted file mode 100755 index 83a0027337..0000000000 --- a/scripts/local_testnet/kill_processes.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env bash -# Kill processes - -set -Euo pipefail - -# First parameter is the file with -# one pid per line. -if [ -f "$1" ]; then - while read pid - do - # handle the case of blank lines - [[ -n "$pid" ]] || continue - - echo killing $pid - kill $pid || true - done < $1 -fi - - diff --git a/scripts/local_testnet/network_params.yaml b/scripts/local_testnet/network_params.yaml new file mode 100644 index 0000000000..f54fce354a --- /dev/null +++ b/scripts/local_testnet/network_params.yaml @@ -0,0 +1,14 @@ +# Full configuration reference [here](https://github.com/kurtosis-tech/ethereum-package?tab=readme-ov-file#configuration). +participants: + - el_type: geth + el_image: ethereum/client-go:latest + cl_type: lighthouse + cl_image: lighthouse:local + cl_extra_params: + - --target-peers=3 + count: 4 +network_params: + deneb_fork_epoch: 0 + seconds_per_slot: 3 +global_log_level: debug +snooper_enabled: false diff --git a/scripts/local_testnet/reset_genesis_time.sh b/scripts/local_testnet/reset_genesis_time.sh deleted file mode 100755 index 68c8fb6b4c..0000000000 --- a/scripts/local_testnet/reset_genesis_time.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash - -# -# Resets the beacon state genesis time to now. -# - -set -Eeuo pipefail - -source ./vars.env - -NOW=$(date +%s) - -lcli \ - change-genesis-time \ - $TESTNET_DIR/genesis.ssz \ - $(date +%s) - -echo "Reset genesis time to now ($NOW)" diff --git a/scripts/local_testnet/setup.sh b/scripts/local_testnet/setup.sh deleted file mode 100755 index 419cba19ed..0000000000 --- a/scripts/local_testnet/setup.sh +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/env bash - -# -# Produces a testnet specification and a genesis state where the genesis time -# is now + $GENESIS_DELAY. -# -# Generates datadirs for multiple validator keys according to the -# $VALIDATOR_COUNT and $BN_COUNT variables. -# - -set -o nounset -o errexit -o pipefail - -source ./vars.env - - -NOW=`date +%s` -GENESIS_TIME=`expr $NOW + $GENESIS_DELAY` - -lcli \ - new-testnet \ - --spec $SPEC_PRESET \ - --deposit-contract-address $DEPOSIT_CONTRACT_ADDRESS \ - --testnet-dir $TESTNET_DIR \ - --min-genesis-active-validator-count $GENESIS_VALIDATOR_COUNT \ - --min-genesis-time $GENESIS_TIME \ - --genesis-delay $GENESIS_DELAY \ - --genesis-fork-version $GENESIS_FORK_VERSION \ - --altair-fork-epoch $ALTAIR_FORK_EPOCH \ - --bellatrix-fork-epoch $BELLATRIX_FORK_EPOCH \ - --capella-fork-epoch $CAPELLA_FORK_EPOCH \ - --deneb-fork-epoch $DENEB_FORK_EPOCH \ - --electra-fork-epoch $ELECTRA_FORK_EPOCH \ - --ttd $TTD \ - --eth1-block-hash $ETH1_BLOCK_HASH \ - --eth1-id $CHAIN_ID \ - --eth1-follow-distance 128 \ - --seconds-per-slot $SECONDS_PER_SLOT \ - --seconds-per-eth1-block $SECONDS_PER_ETH1_BLOCK \ - --proposer-score-boost "$PROPOSER_SCORE_BOOST" \ - --validator-count $GENESIS_VALIDATOR_COUNT \ - --interop-genesis-state \ - --force - -echo Specification and genesis.ssz generated at $TESTNET_DIR. -echo "Generating $VALIDATOR_COUNT validators concurrently... (this may take a while)" - -lcli \ - insecure-validators \ - --count $VALIDATOR_COUNT \ - --base-dir $DATADIR \ - --node-count $VC_COUNT - -echo Validators generated with keystore passwords at $DATADIR. diff --git a/scripts/local_testnet/setup_time.sh b/scripts/local_testnet/setup_time.sh deleted file mode 100755 index 36f7fc4e99..0000000000 --- a/scripts/local_testnet/setup_time.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env bash - -set -Eeuo pipefail - -source ./vars.env - -# Function to output SLOT_PER_EPOCH for mainnet or minimal -get_spec_preset_value() { - case "$SPEC_PRESET" in - mainnet) echo 32 ;; - minimal) echo 8 ;; - gnosis) echo 16 ;; - *) echo "Unsupported preset: $SPEC_PRESET" >&2; exit 1 ;; - esac -} - -SLOT_PER_EPOCH=$(get_spec_preset_value $SPEC_PRESET) -echo "slot_per_epoch=$SLOT_PER_EPOCH" - -genesis_file=$1 - -# Update future hardforks time in the EL genesis file based on the CL genesis time -GENESIS_TIME=$(lcli pretty-ssz --spec $SPEC_PRESET --testnet-dir $TESTNET_DIR BeaconState $TESTNET_DIR/genesis.ssz | jq | grep -Po 'genesis_time": "\K.*\d') -echo $GENESIS_TIME -CAPELLA_TIME=$((GENESIS_TIME + (CAPELLA_FORK_EPOCH * $SLOT_PER_EPOCH * SECONDS_PER_SLOT))) -echo $CAPELLA_TIME -sed -i 's/"shanghaiTime".*$/"shanghaiTime": '"$CAPELLA_TIME"',/g' $genesis_file -CANCUN_TIME=$((GENESIS_TIME + (DENEB_FORK_EPOCH * $SLOT_PER_EPOCH * SECONDS_PER_SLOT))) -echo $CANCUN_TIME -sed -i 's/"cancunTime".*$/"cancunTime": '"$CANCUN_TIME"',/g' $genesis_file -PRAGUE_TIME=$((GENESIS_TIME + (ELECTRA_FORK_EPOCH * $SLOT_PER_EPOCH * SECONDS_PER_SLOT))) -echo $PRAGUE_TIME -sed -i 's/"pragueTime".*$/"pragueTime": '"$PRAGUE_TIME"',/g' $genesis_file -cat $genesis_file - diff --git a/scripts/local_testnet/start_local_testnet.sh b/scripts/local_testnet/start_local_testnet.sh index be91d06998..e0172e6b28 100755 --- a/scripts/local_testnet/start_local_testnet.sh +++ b/scripts/local_testnet/start_local_testnet.sh @@ -1,147 +1,83 @@ #!/usr/bin/env bash -# Start all processes necessary to create a local testnet + +# Requires `docker`, `kurtosis`, `yq` set -Eeuo pipefail -source ./vars.env +SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" +ENCLAVE_NAME=local-testnet +NETWORK_PARAMS_FILE=$SCRIPT_DIR/network_params.yaml -# Set a higher ulimit in case we want to import 1000s of validators. -ulimit -n 65536 - -# VC_COUNT is defaulted in vars.env -DEBUG_LEVEL=${DEBUG_LEVEL:-info} -BUILDER_PROPOSALS= +BUILD_IMAGE=true +BUILDER_PROPOSALS=false +CI=false # Get options -while getopts "v:d:ph" flag; do +while getopts "e:b:n:phc" flag; do case "${flag}" in - v) VC_COUNT=${OPTARG};; - d) DEBUG_LEVEL=${OPTARG};; - p) BUILDER_PROPOSALS="-p";; + e) ENCLAVE_NAME=${OPTARG};; + b) BUILD_IMAGE=${OPTARG};; + n) NETWORK_PARAMS_FILE=${OPTARG};; + p) BUILDER_PROPOSALS=true;; + c) CI=true;; h) - validators=$(( $VALIDATOR_COUNT / $BN_COUNT )) - echo "Start local testnet, defaults: 1 eth1 node, $BN_COUNT beacon nodes," - echo "and $VC_COUNT validator clients with each vc having $validators validators." + echo "Start a local testnet with kurtosis." echo echo "usage: $0 " echo echo "Options:" - echo " -v: VC_COUNT default: $VC_COUNT" - echo " -d: DEBUG_LEVEL default: info" - echo " -p: enable builder proposals" - echo " -h: this help" + echo " -e: enclave name default: $ENCLAVE_NAME" + echo " -b: whether to build Lighthouse docker image default: $BUILD_IMAGE" + echo " -n: kurtosis network params file path default: $NETWORK_PARAMS_FILE" + echo " -p: enable builder proposals" + echo " -c: CI mode, run without other additional services like Grafana and Dora explorer" + echo " -h: this help" exit ;; esac done -if (( $VC_COUNT > $BN_COUNT )); then - echo "Error $VC_COUNT is too large, must be <= BN_COUNT=$BN_COUNT" +LH_IMAGE_NAME=$(yq eval ".participants[0].cl_image" $NETWORK_PARAMS_FILE) + +if ! command -v docker &> /dev/null; then + echo "Docker is not installed. Please install Docker and try again." + exit 1 +fi + +if ! command -v kurtosis &> /dev/null; then + echo "kurtosis command not found. Please install kurtosis and try again." exit fi -genesis_file=${@:$OPTIND+0:1} +if ! command -v yq &> /dev/null; then + echo "yq not found. Please install yq and try again." +fi -# Init some constants -PID_FILE=$TESTNET_DIR/PIDS.pid -LOG_DIR=$TESTNET_DIR +if [ "$BUILDER_PROPOSALS" = true ]; then + yq eval '.participants[0].vc_extra_params = ["--builder-proposals"]' -i $NETWORK_PARAMS_FILE + echo "--builder-proposals VC flag added to network_params.yaml" +fi -# Stop local testnet and remove $PID_FILE -./stop_local_testnet.sh +if [ "$CI" = true ]; then + # TODO: run assertoor tests + yq eval '.additional_services = []' -i $NETWORK_PARAMS_FILE + echo "Running without additional services (CI mode)." +else + yq eval '.additional_services = ["dora", "prometheus_grafana"]' -i $NETWORK_PARAMS_FILE + echo "Additional services dora and prometheus_grafana added to network_params.yaml" +fi -# Clean $DATADIR and create empty log files so the -# user can "tail -f" right after starting this script -# even before its done. -./clean.sh -mkdir -p $LOG_DIR -for (( bn=1; bn<=$BN_COUNT; bn++ )); do - touch $LOG_DIR/beacon_node_$bn.log -done -for (( el=1; el<=$BN_COUNT; el++ )); do - touch $LOG_DIR/geth_$el.log -done -for (( vc=1; vc<=$VC_COUNT; vc++ )); do - touch $LOG_DIR/validator_node_$vc.log -done +if [ "$BUILD_IMAGE" = true ]; then + echo "Building Lighthouse Docker image." + ROOT_DIR="$SCRIPT_DIR/../.." + docker build --build-arg FEATURES=portable -f $ROOT_DIR/Dockerfile -t $LH_IMAGE_NAME $ROOT_DIR +else + echo "Not rebuilding Lighthouse Docker image." +fi -# Sleep with a message -sleeping() { - echo sleeping $1 - sleep $1 -} +# Stop local testnet +kurtosis enclave rm -f $ENCLAVE_NAME 2>/dev/null || true -# Execute the command with logs saved to a file. -# -# First parameter is log file name -# Second parameter is executable name -# Remaining parameters are passed to executable -execute_command() { - LOG_NAME=$1 - EX_NAME=$2 - shift - shift - CMD="$EX_NAME $@ >> $LOG_DIR/$LOG_NAME 2>&1" - echo "executing: $CMD" - echo "$CMD" > "$LOG_DIR/$LOG_NAME" - eval "$CMD &" -} - -# Execute the command with logs saved to a file -# and is PID is saved to $PID_FILE. -# -# First parameter is log file name -# Second parameter is executable name -# Remaining parameters are passed to executable -execute_command_add_PID() { - execute_command $@ - echo "$!" >> $PID_FILE -} - - -# Setup data -echo "executing: ./setup.sh >> $LOG_DIR/setup.log" -./setup.sh >> $LOG_DIR/setup.log 2>&1 - -# Call setup_time.sh to update future hardforks time in the EL genesis file based on the CL genesis time -./setup_time.sh $genesis_file - -# Delay to let boot_enr.yaml to be created -execute_command_add_PID bootnode.log ./bootnode.sh -sleeping 3 - -execute_command_add_PID el_bootnode.log ./el_bootnode.sh -sleeping 3 - -# Start beacon nodes -BN_udp_tcp_base=9000 -BN_http_port_base=8000 - -EL_base_network=7000 -EL_base_http=6000 -EL_base_auth_http=5000 - -(( $VC_COUNT < $BN_COUNT )) && SAS=-s || SAS= - -for (( el=1; el<=$BN_COUNT; el++ )); do - execute_command_add_PID geth_$el.log ./geth.sh $DATADIR/geth_datadir$el $((EL_base_network + $el)) $((EL_base_http + $el)) $((EL_base_auth_http + $el)) $genesis_file -done - -sleeping 20 - -# Reset the `genesis.json` config file fork times. -sed -i 's/"shanghaiTime".*$/"shanghaiTime": 0,/g' $genesis_file -sed -i 's/"cancunTime".*$/"cancunTime": 0,/g' $genesis_file -sed -i 's/"pragueTime".*$/"pragueTime": 0,/g' $genesis_file - -for (( bn=1; bn<=$BN_COUNT; bn++ )); do - secret=$DATADIR/geth_datadir$bn/geth/jwtsecret - echo $secret - execute_command_add_PID beacon_node_$bn.log ./beacon_node.sh $SAS -d $DEBUG_LEVEL $DATADIR/node_$bn $((BN_udp_tcp_base + $bn)) $((BN_udp_tcp_base + $bn + 100)) $((BN_http_port_base + $bn)) http://localhost:$((EL_base_auth_http + $bn)) $secret -done - -# Start requested number of validator clients -for (( vc=1; vc<=$VC_COUNT; vc++ )); do - execute_command_add_PID validator_node_$vc.log ./validator_client.sh $BUILDER_PROPOSALS -d $DEBUG_LEVEL $DATADIR/node_$vc http://localhost:$((BN_http_port_base + $vc)) -done +kurtosis run --enclave $ENCLAVE_NAME github.com/kurtosis-tech/ethereum-package --args-file $NETWORK_PARAMS_FILE echo "Started!" diff --git a/scripts/local_testnet/stop_local_testnet.sh b/scripts/local_testnet/stop_local_testnet.sh index b1c3188ee3..5500f8d5a0 100755 --- a/scripts/local_testnet/stop_local_testnet.sh +++ b/scripts/local_testnet/stop_local_testnet.sh @@ -1,10 +1,15 @@ #!/usr/bin/env bash -# Stop all processes that were started with start_local_testnet.sh - set -Eeuo pipefail -source ./vars.env +SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" +ENCLAVE_NAME=${1:-local-testnet} +LOGS_PATH=$SCRIPT_DIR/logs +LOGS_SUBDIR=$LOGS_PATH/$ENCLAVE_NAME -PID_FILE=$TESTNET_DIR/PIDS.pid -./kill_processes.sh $PID_FILE -rm -f $PID_FILE +# Delete existing logs directory and make sure parent directory exists. +rm -rf $LOGS_SUBDIR && mkdir -p $LOGS_PATH +kurtosis enclave dump $ENCLAVE_NAME $LOGS_SUBDIR +echo "Local testnet logs stored to $LOGS_SUBDIR." + +kurtosis enclave rm -f $ENCLAVE_NAME +echo "Local testnet stopped." diff --git a/scripts/local_testnet/validator_client.sh b/scripts/local_testnet/validator_client.sh deleted file mode 100755 index d88a1833cb..0000000000 --- a/scripts/local_testnet/validator_client.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env bash - -# -# Starts a validator client based upon a genesis state created by -# `./setup.sh`. -# -# Usage: ./validator_client.sh - -set -Eeuo pipefail - -source ./vars.env - -DEBUG_LEVEL=info - -BUILDER_PROPOSALS= - -# Get options -while getopts "pd:" flag; do - case "${flag}" in - p) BUILDER_PROPOSALS="--builder-proposals";; - d) DEBUG_LEVEL=${OPTARG};; - esac -done - -exec lighthouse \ - --debug-level $DEBUG_LEVEL \ - vc \ - $BUILDER_PROPOSALS \ - --datadir ${@:$OPTIND:1} \ - --testnet-dir $TESTNET_DIR \ - --init-slashing-protection \ - --beacon-nodes ${@:$OPTIND+1:1} \ - --suggested-fee-recipient 0x690B9A9E9aa1C9dB991C7721a92d351Db4FaC990 \ - $VC_ARGS diff --git a/scripts/local_testnet/vars.env b/scripts/local_testnet/vars.env deleted file mode 100644 index 9bdec71ff7..0000000000 --- a/scripts/local_testnet/vars.env +++ /dev/null @@ -1,69 +0,0 @@ -# Path to the geth binary -GETH_BINARY=geth -EL_BOOTNODE_BINARY=bootnode - -# Base directories for the validator keys and secrets -DATADIR=~/.lighthouse/local-testnet - -# Directory for the eth2 config -TESTNET_DIR=$DATADIR/testnet - -# Mnemonic for generating validator keys -MNEMONIC_PHRASE="vast thought differ pull jewel broom cook wrist tribe word before omit" - -EL_BOOTNODE_ENODE="enode://51ea9bb34d31efc3491a842ed13b8cab70e753af108526b57916d716978b380ed713f4336a80cdb85ec2a115d5a8c0ae9f3247bed3c84d3cb025c6bab311062c@127.0.0.1:0?discport=30301" - -# Hardcoded deposit contract -DEPOSIT_CONTRACT_ADDRESS=4242424242424242424242424242424242424242 - -GENESIS_FORK_VERSION=0x42424242 - -# Block hash generated from genesis.json in directory -ETH1_BLOCK_HASH=4b0e17cf5c04616d64526d292b80a1f2720cf2195d990006e4ea6950c5bbcb9f - -VALIDATOR_COUNT=80 -GENESIS_VALIDATOR_COUNT=80 - -# Number of beacon_node instances that you intend to run -BN_COUNT=4 - -# Number of validator clients -VC_COUNT=$BN_COUNT - -# Number of seconds to delay to start genesis block. -# If started by a script this can be 0, if starting by hand -# use something like 180. -GENESIS_DELAY=0 - -# Port for P2P communication with bootnode -BOOTNODE_PORT=4242 - -# Network ID and Chain ID of local eth1 test network -CHAIN_ID=4242 - -# Hard fork configuration -ALTAIR_FORK_EPOCH=0 -BELLATRIX_FORK_EPOCH=0 -CAPELLA_FORK_EPOCH=0 -DENEB_FORK_EPOCH=1 -ELECTRA_FORK_EPOCH=9999999 - -TTD=0 - -# Spec version (mainnet or minimal) -SPEC_PRESET=mainnet - -# Seconds per Eth2 slot -SECONDS_PER_SLOT=3 - -# Seconds per Eth1 block -SECONDS_PER_ETH1_BLOCK=3 - -# Proposer score boost percentage -PROPOSER_SCORE_BOOST=40 - -# Command line arguments for beacon node client -BN_ARGS="" - -# Command line arguments for validator client -VC_ARGS="" diff --git a/scripts/tests/doppelganger_protection.sh b/scripts/tests/doppelganger_protection.sh index e13c06cdba..441e2a6357 100755 --- a/scripts/tests/doppelganger_protection.sh +++ b/scripts/tests/doppelganger_protection.sh @@ -1,101 +1,129 @@ #!/usr/bin/env bash -# Requires `lighthouse`, `lcli`, `geth`, `bootnode`, `curl`, `jq` +# Requires `docker`, `kurtosis`, `yq`, `curl`, `jq` +set -Eeuo pipefail +SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" +NETWORK_PARAMS_FILE=$SCRIPT_DIR/network_params.yaml BEHAVIOR=$1 +ENCLAVE_NAME=local-testnet-$BEHAVIOR + +SECONDS_PER_SLOT=$(yq eval ".network_params.seconds_per_slot" $NETWORK_PARAMS_FILE) +KEYS_PER_NODE=$(yq eval ".network_params.num_validator_keys_per_node" $NETWORK_PARAMS_FILE) +LH_IMAGE_NAME=$(yq eval ".participants[0].cl_image" $NETWORK_PARAMS_FILE) if [[ "$BEHAVIOR" != "success" ]] && [[ "$BEHAVIOR" != "failure" ]]; then echo "Usage: doppelganger_protection.sh [success|failure]" exit 1 fi -exit_if_fails() { - echo $@ - $@ - EXIT_CODE=$? - if [[ $EXIT_CODE -eq 1 ]]; then - exit 1 - fi +function exit_and_dump_logs() { + local exit_code=$1 + echo "Shutting down..." + $SCRIPT_DIR/../local_testnet/stop_local_testnet.sh $ENCLAVE_NAME + echo "Test completed with exit code $exit_code." + exit $exit_code } -genesis_file=$2 -source ./vars.env +function get_service_status() { + local service_name=$1 + kurtosis service inspect $ENCLAVE_NAME $service_name | grep Status | cut -d':' -f2 | xargs +} -exit_if_fails ../local_testnet/clean.sh +function run_command_without_exit() { + local command=$1 + set +e + eval "$command" + local exit_code=$? + set -e + echo $exit_code +} +# Start local testnet +$SCRIPT_DIR/../local_testnet/start_local_testnet.sh -e $ENCLAVE_NAME -b false -c -n $NETWORK_PARAMS_FILE -echo "Setting up local testnet" +# Immediately stop node 4 (as we only need the node 4 validator keys generated for later use) +kurtosis service stop $ENCLAVE_NAME cl-4-lighthouse-geth el-4-geth-lighthouse vc-4-geth-lighthouse > /dev/null -exit_if_fails ../local_testnet/setup.sh +# Get the http port to get the config +BN1_HTTP_ADDRESS=`kurtosis port print $ENCLAVE_NAME cl-1-lighthouse-geth http` -# Duplicate this directory so slashing protection doesn't keep us from re-using validator keys -exit_if_fails cp -R $HOME/.lighthouse/local-testnet/node_1 $HOME/.lighthouse/local-testnet/node_1_doppelganger +# Get the genesis time and genesis delay +MIN_GENESIS_TIME=`curl -s $BN1_HTTP_ADDRESS/eth/v1/config/spec | jq '.data.MIN_GENESIS_TIME|tonumber'` +GENESIS_DELAY=`curl -s $BN1_HTTP_ADDRESS/eth/v1/config/spec | jq '.data.GENESIS_DELAY|tonumber'` -echo "Starting bootnode" +CURRENT_TIME=`date +%s` +# Note: doppelganger protection can only be started post epoch 0 +echo "Waiting until next epoch before starting the next validator client..." +DELAY=$(( $SECONDS_PER_SLOT * 32 + $GENESIS_DELAY + $MIN_GENESIS_TIME - $CURRENT_TIME)) +sleep $DELAY -exit_if_fails ../local_testnet/bootnode.sh &> /dev/null & - -exit_if_fails ../local_testnet/el_bootnode.sh &> /dev/null & - -# wait for the bootnode to start -sleep 10 - -echo "Starting local execution nodes" - -exit_if_fails ../local_testnet/geth.sh $HOME/.lighthouse/local-testnet/geth_datadir1 6000 5000 4000 $genesis_file &> geth.log & -exit_if_fails ../local_testnet/geth.sh $HOME/.lighthouse/local-testnet/geth_datadir2 6100 5100 4100 $genesis_file &> /dev/null & -exit_if_fails ../local_testnet/geth.sh $HOME/.lighthouse/local-testnet/geth_datadir3 6200 5200 4200 $genesis_file &> /dev/null & - -sleep 20 - -exit_if_fails ../local_testnet/beacon_node.sh -d debug $HOME/.lighthouse/local-testnet/node_1 8000 7000 9000 http://localhost:4000 $HOME/.lighthouse/local-testnet/geth_datadir1/geth/jwtsecret &> /dev/null & -exit_if_fails ../local_testnet/beacon_node.sh $HOME/.lighthouse/local-testnet/node_2 8100 7100 9100 http://localhost:4100 $HOME/.lighthouse/local-testnet/geth_datadir2/geth/jwtsecret &> /dev/null & -exit_if_fails ../local_testnet/beacon_node.sh $HOME/.lighthouse/local-testnet/node_3 8200 7200 9200 http://localhost:4200 $HOME/.lighthouse/local-testnet/geth_datadir3/geth/jwtsecret &> /dev/null & - -echo "Starting local validator clients" - -exit_if_fails ../local_testnet/validator_client.sh $HOME/.lighthouse/local-testnet/node_1 http://localhost:9000 &> /dev/null & -exit_if_fails ../local_testnet/validator_client.sh $HOME/.lighthouse/local-testnet/node_2 http://localhost:9100 &> /dev/null & -exit_if_fails ../local_testnet/validator_client.sh $HOME/.lighthouse/local-testnet/node_3 http://localhost:9200 &> /dev/null & - -echo "Waiting an epoch before starting the next validator client" -sleep $(( $SECONDS_PER_SLOT * 32 )) +# Use BN2 for the next validator client +bn_2_url=$(kurtosis service inspect $ENCLAVE_NAME cl-2-lighthouse-geth | grep 'enr-address' | cut -d'=' -f2) +bn_2_port=4000 if [[ "$BEHAVIOR" == "failure" ]]; then - echo "Starting the doppelganger validator client" + echo "Starting the doppelganger validator client." # Use same keys as keys from VC1 and connect to BN2 # This process should not last longer than 2 epochs - timeout $(( $SECONDS_PER_SLOT * 32 * 2 )) ../local_testnet/validator_client.sh $HOME/.lighthouse/local-testnet/node_1_doppelganger http://localhost:9100 - DOPPELGANGER_EXIT=$? + vc_1_range_start=0 + vc_1_range_end=$(($KEYS_PER_NODE - 1)) + vc_1_keys_artifact_id="1-lighthouse-geth-$vc_1_range_start-$vc_1_range_end-0" + service_name=vc-1-doppelganger - echo "Shutting down" + kurtosis service add \ + --files /validator_keys:$vc_1_keys_artifact_id,/testnet:el_cl_genesis_data \ + $ENCLAVE_NAME $service_name $LH_IMAGE_NAME -- lighthouse \ + vc \ + --debug-level debug \ + --testnet-dir=/testnet \ + --validators-dir=/validator_keys/keys \ + --secrets-dir=/validator_keys/secrets \ + --init-slashing-protection \ + --beacon-nodes=http://$bn_2_url:$bn_2_port \ + --enable-doppelganger-protection \ + --suggested-fee-recipient 0x690B9A9E9aa1C9dB991C7721a92d351Db4FaC990 - # Cleanup - killall geth - killall lighthouse - killall bootnode + # Check if doppelganger VC has stopped and exited. Exit code 1 means the check timed out and VC is still running. + check_exit_cmd="until [ \$(get_service_status $service_name) != 'RUNNING' ]; do sleep 1; done" + doppelganger_exit=$(run_command_without_exit "timeout $(( $SECONDS_PER_SLOT * 32 * 2 )) bash -c \"$check_exit_cmd\"") - echo "Done" - - # We expect to find a doppelganger, exit with success error code if doppelganger was found - # and failure if no doppelganger was found. - if [[ $DOPPELGANGER_EXIT -eq 1 ]]; then - exit 0 + if [[ $doppelganger_exit -eq 1 ]]; then + echo "Test failed: expected doppelganger but VC is still running. Check the logs for details." + exit_and_dump_logs 1 else - exit 1 + echo "Test passed: doppelganger found and VC process stopped successfully." + exit_and_dump_logs 0 fi fi if [[ "$BEHAVIOR" == "success" ]]; then - echo "Starting the last validator client" + echo "Starting the last validator client." - ../local_testnet/validator_client.sh $HOME/.lighthouse/local-testnet/node_4 http://localhost:9100 & - DOPPELGANGER_FAILURE=0 + vc_4_range_start=$(($KEYS_PER_NODE * 3)) + vc_4_range_end=$(($KEYS_PER_NODE * 4 - 1)) + vc_4_keys_artifact_id="4-lighthouse-geth-$vc_4_range_start-$vc_4_range_end-0" + service_name=vc-4 + + kurtosis service add \ + --files /validator_keys:$vc_4_keys_artifact_id,/testnet:el_cl_genesis_data \ + $ENCLAVE_NAME $service_name $LH_IMAGE_NAME -- lighthouse \ + vc \ + --debug-level debug \ + --testnet-dir=/testnet \ + --validators-dir=/validator_keys/keys \ + --secrets-dir=/validator_keys/secrets \ + --init-slashing-protection \ + --beacon-nodes=http://$bn_2_url:$bn_2_port \ + --enable-doppelganger-protection \ + --suggested-fee-recipient 0x690B9A9E9aa1C9dB991C7721a92d351Db4FaC990 + + doppelganger_failure=0 # Sleep three epochs, then make sure all validators were active in epoch 2. Use # `is_previous_epoch_target_attester` from epoch 3 for a complete view of epoch 2 inclusion. @@ -104,20 +132,27 @@ if [[ "$BEHAVIOR" == "success" ]]; then echo "Waiting three epochs..." sleep $(( $SECONDS_PER_SLOT * 32 * 3 )) - PREVIOUS_DIR=$(pwd) - cd $HOME/.lighthouse/local-testnet/node_4/validators + # Get VC4 validator keys + keys_path=$SCRIPT_DIR/$ENCLAVE_NAME/node_4/validators + rm -rf $keys_path && mkdir -p $keys_path + kurtosis files download $ENCLAVE_NAME $vc_4_keys_artifact_id $keys_path + cd $keys_path/keys + for val in 0x*; do [[ -e $val ]] || continue - curl -s localhost:9100/lighthouse/validator_inclusion/3/$val | jq | grep -q '"is_previous_epoch_target_attester": false' - IS_ATTESTER=$? - if [[ $IS_ATTESTER -eq 0 ]]; then + is_attester=$(run_command_without_exit "curl -s $BN1_HTTP_ADDRESS/lighthouse/validator_inclusion/3/$val | jq | grep -q '\"is_previous_epoch_target_attester\": false'") + if [[ $is_attester -eq 0 ]]; then echo "$val did not attest in epoch 2." else echo "ERROR! $val did attest in epoch 2." - DOPPELGANGER_FAILURE=1 + doppelganger_failure=1 fi done + if [[ $doppelganger_failure -eq 1 ]]; then + exit_and_dump_logs 1 + fi + # Sleep two epochs, then make sure all validators were active in epoch 4. Use # `is_previous_epoch_target_attester` from epoch 5 for a complete view of epoch 4 inclusion. # @@ -126,30 +161,18 @@ if [[ "$BEHAVIOR" == "success" ]]; then sleep $(( $SECONDS_PER_SLOT * 32 * 2 )) for val in 0x*; do [[ -e $val ]] || continue - curl -s localhost:9100/lighthouse/validator_inclusion/5/$val | jq | grep -q '"is_previous_epoch_target_attester": true' - IS_ATTESTER=$? - if [[ $IS_ATTESTER -eq 0 ]]; then + is_attester=$(run_command_without_exit "curl -s $BN1_HTTP_ADDRESS/lighthouse/validator_inclusion/5/$val | jq | grep -q '\"is_previous_epoch_target_attester\": true'") + if [[ $is_attester -eq 0 ]]; then echo "$val attested in epoch 4." else echo "ERROR! $val did not attest in epoch 4." - DOPPELGANGER_FAILURE=1 + doppelganger_failure=1 fi done - echo "Shutting down" - - # Cleanup - cd $PREVIOUS_DIR - - killall geth - killall lighthouse - killall bootnode - - echo "Done" - - if [[ $DOPPELGANGER_FAILURE -eq 1 ]]; then - exit 1 + if [[ $doppelganger_failure -eq 1 ]]; then + exit_and_dump_logs 1 fi fi -exit 0 +exit_and_dump_logs 0 diff --git a/scripts/tests/genesis.json b/scripts/tests/genesis.json deleted file mode 100644 index bfbc08c81e..0000000000 --- a/scripts/tests/genesis.json +++ /dev/null @@ -1,856 +0,0 @@ -{ - "config": { - "chainId": 4242, - "homesteadBlock": 0, - "eip150Block": 0, - "eip155Block": 0, - "eip158Block": 0, - "byzantiumBlock": 0, - "constantinopleBlock": 0, - "petersburgBlock": 0, - "istanbulBlock": 0, - "berlinBlock": 0, - "londonBlock": 0, - "mergeForkBlock": 0, - "shanghaiTime": 0, - "cancunTime": 0, - "terminalTotalDifficulty": 0, - "terminalTotalDifficultyPassed": true - }, - "alloc": { - "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": { - "balance": "0x6d6172697573766477000000" - }, - "0x0000000000000000000000000000000000000000": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000001": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000002": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000003": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000004": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000005": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000006": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000007": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000008": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000009": { - "balance": "1" - }, - "0x000000000000000000000000000000000000000a": { - "balance": "1" - }, - "0x000000000000000000000000000000000000000b": { - "balance": "1" - }, - "0x000000000000000000000000000000000000000c": { - "balance": "1" - }, - "0x000000000000000000000000000000000000000d": { - "balance": "1" - }, - "0x000000000000000000000000000000000000000e": { - "balance": "1" - }, - "0x000000000000000000000000000000000000000f": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000010": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000011": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000012": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000013": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000014": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000015": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000016": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000017": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000018": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000019": { - "balance": "1" - }, - "0x000000000000000000000000000000000000001a": { - "balance": "1" - }, - "0x000000000000000000000000000000000000001b": { - "balance": "1" - }, - "0x000000000000000000000000000000000000001c": { - "balance": "1" - }, - "0x000000000000000000000000000000000000001d": { - "balance": "1" - }, - "0x000000000000000000000000000000000000001e": { - "balance": "1" - }, - "0x000000000000000000000000000000000000001f": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000020": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000021": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000022": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000023": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000024": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000025": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000026": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000027": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000028": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000029": { - "balance": "1" - }, - "0x000000000000000000000000000000000000002a": { - "balance": "1" - }, - "0x000000000000000000000000000000000000002b": { - "balance": "1" - }, - "0x000000000000000000000000000000000000002c": { - "balance": "1" - }, - "0x000000000000000000000000000000000000002d": { - "balance": "1" - }, - "0x000000000000000000000000000000000000002e": { - "balance": "1" - }, - "0x000000000000000000000000000000000000002f": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000030": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000031": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000032": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000033": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000034": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000035": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000036": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000037": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000038": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000039": { - "balance": "1" - }, - "0x000000000000000000000000000000000000003a": { - "balance": "1" - }, - "0x000000000000000000000000000000000000003b": { - "balance": "1" - }, - "0x000000000000000000000000000000000000003c": { - "balance": "1" - }, - "0x000000000000000000000000000000000000003d": { - "balance": "1" - }, - "0x000000000000000000000000000000000000003e": { - "balance": "1" - }, - "0x000000000000000000000000000000000000003f": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000040": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000041": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000042": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000043": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000044": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000045": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000046": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000047": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000048": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000049": { - "balance": "1" - }, - "0x000000000000000000000000000000000000004a": { - "balance": "1" - }, - "0x000000000000000000000000000000000000004b": { - "balance": "1" - }, - "0x000000000000000000000000000000000000004c": { - "balance": "1" - }, - "0x000000000000000000000000000000000000004d": { - "balance": "1" - }, - "0x000000000000000000000000000000000000004e": { - "balance": "1" - }, - "0x000000000000000000000000000000000000004f": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000050": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000051": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000052": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000053": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000054": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000055": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000056": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000057": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000058": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000059": { - "balance": "1" - }, - "0x000000000000000000000000000000000000005a": { - "balance": "1" - }, - "0x000000000000000000000000000000000000005b": { - "balance": "1" - }, - "0x000000000000000000000000000000000000005c": { - "balance": "1" - }, - "0x000000000000000000000000000000000000005d": { - "balance": "1" - }, - "0x000000000000000000000000000000000000005e": { - "balance": "1" - }, - "0x000000000000000000000000000000000000005f": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000060": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000061": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000062": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000063": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000064": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000065": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000066": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000067": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000068": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000069": { - "balance": "1" - }, - "0x000000000000000000000000000000000000006a": { - "balance": "1" - }, - "0x000000000000000000000000000000000000006b": { - "balance": "1" - }, - "0x000000000000000000000000000000000000006c": { - "balance": "1" - }, - "0x000000000000000000000000000000000000006d": { - "balance": "1" - }, - "0x000000000000000000000000000000000000006e": { - "balance": "1" - }, - "0x000000000000000000000000000000000000006f": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000070": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000071": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000072": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000073": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000074": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000075": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000076": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000077": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000078": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000079": { - "balance": "1" - }, - "0x000000000000000000000000000000000000007a": { - "balance": "1" - }, - "0x000000000000000000000000000000000000007b": { - "balance": "1" - }, - "0x000000000000000000000000000000000000007c": { - "balance": "1" - }, - "0x000000000000000000000000000000000000007d": { - "balance": "1" - }, - "0x000000000000000000000000000000000000007e": { - "balance": "1" - }, - "0x000000000000000000000000000000000000007f": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000080": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000081": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000082": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000083": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000084": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000085": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000086": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000087": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000088": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000089": { - "balance": "1" - }, - "0x000000000000000000000000000000000000008a": { - "balance": "1" - }, - "0x000000000000000000000000000000000000008b": { - "balance": "1" - }, - "0x000000000000000000000000000000000000008c": { - "balance": "1" - }, - "0x000000000000000000000000000000000000008d": { - "balance": "1" - }, - "0x000000000000000000000000000000000000008e": { - "balance": "1" - }, - "0x000000000000000000000000000000000000008f": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000090": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000091": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000092": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000093": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000094": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000095": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000096": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000097": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000098": { - "balance": "1" - }, - "0x0000000000000000000000000000000000000099": { - "balance": "1" - }, - "0x000000000000000000000000000000000000009a": { - "balance": "1" - }, - "0x000000000000000000000000000000000000009b": { - "balance": "1" - }, - "0x000000000000000000000000000000000000009c": { - "balance": "1" - }, - "0x000000000000000000000000000000000000009d": { - "balance": "1" - }, - "0x000000000000000000000000000000000000009e": { - "balance": "1" - }, - "0x000000000000000000000000000000000000009f": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000a0": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000a1": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000a2": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000a3": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000a4": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000a5": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000a6": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000a7": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000a8": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000a9": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000aa": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ab": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ac": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ad": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ae": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000af": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000b0": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000b1": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000b2": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000b3": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000b4": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000b5": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000b6": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000b7": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000b8": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000b9": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ba": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000bb": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000bc": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000bd": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000be": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000bf": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000c0": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000c1": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000c2": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000c3": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000c4": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000c5": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000c6": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000c7": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000c8": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000c9": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ca": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000cb": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000cc": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000cd": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ce": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000cf": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000d0": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000d1": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000d2": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000d3": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000d4": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000d5": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000d6": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000d7": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000d8": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000d9": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000da": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000db": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000dc": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000dd": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000de": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000df": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000e0": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000e1": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000e2": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000e3": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000e4": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000e5": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000e6": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000e7": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000e8": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000e9": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ea": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000eb": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ec": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ed": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ee": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ef": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000f0": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000f1": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000f2": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000f3": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000f4": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000f5": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000f6": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000f7": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000f8": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000f9": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000fa": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000fb": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000fc": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000fd": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000fe": { - "balance": "1" - }, - "0x00000000000000000000000000000000000000ff": { - "balance": "1" - }, - "0x4242424242424242424242424242424242424242": { - "balance": "0", - "code": "0x60806040526004361061003f5760003560e01c806301ffc9a71461004457806322895118146100a4578063621fd130146101ba578063c5f2892f14610244575b600080fd5b34801561005057600080fd5b506100906004803603602081101561006757600080fd5b50357fffffffff000000000000000000000000000000000000000000000000000000001661026b565b604080519115158252519081900360200190f35b6101b8600480360360808110156100ba57600080fd5b8101906020810181356401000000008111156100d557600080fd5b8201836020820111156100e757600080fd5b8035906020019184600183028401116401000000008311171561010957600080fd5b91939092909160208101903564010000000081111561012757600080fd5b82018360208201111561013957600080fd5b8035906020019184600183028401116401000000008311171561015b57600080fd5b91939092909160208101903564010000000081111561017957600080fd5b82018360208201111561018b57600080fd5b803590602001918460018302840111640100000000831117156101ad57600080fd5b919350915035610304565b005b3480156101c657600080fd5b506101cf6110b5565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102095781810151838201526020016101f1565b50505050905090810190601f1680156102365780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561025057600080fd5b506102596110c7565b60408051918252519081900360200190f35b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a70000000000000000000000000000000000000000000000000000000014806102fe57507fffffffff0000000000000000000000000000000000000000000000000000000082167f8564090700000000000000000000000000000000000000000000000000000000145b92915050565b6030861461035d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806118056026913960400191505060405180910390fd5b602084146103b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603681526020018061179c6036913960400191505060405180910390fd5b6060821461040f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260298152602001806118786029913960400191505060405180910390fd5b670de0b6b3a7640000341015610470576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806118526026913960400191505060405180910390fd5b633b9aca003406156104cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260338152602001806117d26033913960400191505060405180910390fd5b633b9aca00340467ffffffffffffffff811115610535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602781526020018061182b6027913960400191505060405180910390fd5b6060610540826114ba565b90507f649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c589898989858a8a6105756020546114ba565b6040805160a0808252810189905290819060208201908201606083016080840160c085018e8e80828437600083820152601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690910187810386528c815260200190508c8c808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690920188810386528c5181528c51602091820193918e019250908190849084905b83811015610648578181015183820152602001610630565b50505050905090810190601f1680156106755780820380516001836020036101000a031916815260200191505b5086810383528881526020018989808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169092018881038452895181528951602091820193918b019250908190849084905b838110156106ef5781810151838201526020016106d7565b50505050905090810190601f16801561071c5780820380516001836020036101000a031916815260200191505b509d505050505050505050505050505060405180910390a1600060028a8a600060801b604051602001808484808284377fffffffffffffffffffffffffffffffff0000000000000000000000000000000090941691909301908152604080517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0818403018152601090920190819052815191955093508392506020850191508083835b602083106107fc57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016107bf565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610859573d6000803e3d6000fd5b5050506040513d602081101561086e57600080fd5b5051905060006002806108846040848a8c6116fe565b6040516020018083838082843780830192505050925050506040516020818303038152906040526040518082805190602001908083835b602083106108f857805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016108bb565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610955573d6000803e3d6000fd5b5050506040513d602081101561096a57600080fd5b5051600261097b896040818d6116fe565b60405160009060200180848480828437919091019283525050604080518083038152602092830191829052805190945090925082918401908083835b602083106109f457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016109b7565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610a51573d6000803e3d6000fd5b5050506040513d6020811015610a6657600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310610ada57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610a9d565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610b37573d6000803e3d6000fd5b5050506040513d6020811015610b4c57600080fd5b50516040805160208101858152929350600092600292839287928f928f92018383808284378083019250505093505050506040516020818303038152906040526040518082805190602001908083835b60208310610bd957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610b9c565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610c36573d6000803e3d6000fd5b5050506040513d6020811015610c4b57600080fd5b50516040518651600291889160009188916020918201918291908601908083835b60208310610ca957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610c6c565b6001836020036101000a0380198251168184511680821785525050505050509050018367ffffffffffffffff191667ffffffffffffffff1916815260180182815260200193505050506040516020818303038152906040526040518082805190602001908083835b60208310610d4e57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610d11565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610dab573d6000803e3d6000fd5b5050506040513d6020811015610dc057600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310610e3457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610df7565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610e91573d6000803e3d6000fd5b5050506040513d6020811015610ea657600080fd5b50519050858114610f02576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260548152602001806117486054913960600191505060405180910390fd5b60205463ffffffff11610f60576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806117276021913960400191505060405180910390fd5b602080546001019081905560005b60208110156110a9578160011660011415610fa0578260008260208110610f9157fe5b0155506110ac95505050505050565b600260008260208110610faf57fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061102557805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610fe8565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015611082573d6000803e3d6000fd5b5050506040513d602081101561109757600080fd5b50519250600282049150600101610f6e565b50fe5b50505050505050565b60606110c26020546114ba565b905090565b6020546000908190815b60208110156112f05781600116600114156111e6576002600082602081106110f557fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061116b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161112e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156111c8573d6000803e3d6000fd5b5050506040513d60208110156111dd57600080fd5b505192506112e2565b600283602183602081106111f657fe5b015460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061126b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161122e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156112c8573d6000803e3d6000fd5b5050506040513d60208110156112dd57600080fd5b505192505b6002820491506001016110d1565b506002826112ff6020546114ba565b600060401b6040516020018084815260200183805190602001908083835b6020831061135a57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161131d565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790527fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000095909516920191825250604080518083037ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8018152601890920190819052815191955093508392850191508083835b6020831061143f57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101611402565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa15801561149c573d6000803e3d6000fd5b5050506040513d60208110156114b157600080fd5b50519250505090565b60408051600880825281830190925260609160208201818036833701905050905060c082901b8060071a60f81b826000815181106114f457fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060061a60f81b8260018151811061153757fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060051a60f81b8260028151811061157a57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060041a60f81b826003815181106115bd57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060031a60f81b8260048151811061160057fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060021a60f81b8260058151811061164357fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060011a60f81b8260068151811061168657fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060001a60f81b826007815181106116c957fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535050919050565b6000808585111561170d578182fd5b83861115611719578182fd5b505082019391909203915056fe4465706f736974436f6e74726163743a206d65726b6c6520747265652066756c6c4465706f736974436f6e74726163743a207265636f6e7374727563746564204465706f7369744461746120646f6573206e6f74206d6174636820737570706c696564206465706f7369745f646174615f726f6f744465706f736974436f6e74726163743a20696e76616c6964207769746864726177616c5f63726564656e7469616c73206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c7565206e6f74206d756c7469706c65206f6620677765694465706f736974436f6e74726163743a20696e76616c6964207075626b6579206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f20686967684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f206c6f774465706f736974436f6e74726163743a20696e76616c6964207369676e6174757265206c656e677468a26469706673582212201dd26f37a621703009abf16e77e69c93dc50c79db7f6cc37543e3e0e3decdc9764736f6c634300060b0033", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000022": "0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b", - "0x0000000000000000000000000000000000000000000000000000000000000023": "0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71", - "0x0000000000000000000000000000000000000000000000000000000000000024": "0xc78009fdf07fc56a11f122370658a353aaa542ed63e44c4bc15ff4cd105ab33c", - "0x0000000000000000000000000000000000000000000000000000000000000025": "0x536d98837f2dd165a55d5eeae91485954472d56f246df256bf3cae19352a123c", - "0x0000000000000000000000000000000000000000000000000000000000000026": "0x9efde052aa15429fae05bad4d0b1d7c64da64d03d7a1854a588c2cb8430c0d30", - "0x0000000000000000000000000000000000000000000000000000000000000027": "0xd88ddfeed400a8755596b21942c1497e114c302e6118290f91e6772976041fa1", - "0x0000000000000000000000000000000000000000000000000000000000000028": "0x87eb0ddba57e35f6d286673802a4af5975e22506c7cf4c64bb6be5ee11527f2c", - "0x0000000000000000000000000000000000000000000000000000000000000029": "0x26846476fd5fc54a5d43385167c95144f2643f533cc85bb9d16b782f8d7db193", - "0x000000000000000000000000000000000000000000000000000000000000002a": "0x506d86582d252405b840018792cad2bf1259f1ef5aa5f887e13cb2f0094f51e1", - "0x000000000000000000000000000000000000000000000000000000000000002b": "0xffff0ad7e659772f9534c195c815efc4014ef1e1daed4404c06385d11192e92b", - "0x000000000000000000000000000000000000000000000000000000000000002c": "0x6cf04127db05441cd833107a52be852868890e4317e6a02ab47683aa75964220", - "0x000000000000000000000000000000000000000000000000000000000000002d": "0xb7d05f875f140027ef5118a2247bbb84ce8f2f0f1123623085daf7960c329f5f", - "0x000000000000000000000000000000000000000000000000000000000000002e": "0xdf6af5f5bbdb6be9ef8aa618e4bf8073960867171e29676f8b284dea6a08a85e", - "0x000000000000000000000000000000000000000000000000000000000000002f": "0xb58d900f5e182e3c50ef74969ea16c7726c549757cc23523c369587da7293784", - "0x0000000000000000000000000000000000000000000000000000000000000030": "0xd49a7502ffcfb0340b1d7885688500ca308161a7f96b62df9d083b71fcc8f2bb", - "0x0000000000000000000000000000000000000000000000000000000000000031": "0x8fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb", - "0x0000000000000000000000000000000000000000000000000000000000000032": "0x8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab", - "0x0000000000000000000000000000000000000000000000000000000000000033": "0x95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a4", - "0x0000000000000000000000000000000000000000000000000000000000000034": "0xf893e908917775b62bff23294dbbe3a1cd8e6cc1c35b4801887b646a6f81f17f", - "0x0000000000000000000000000000000000000000000000000000000000000035": "0xcddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa", - "0x0000000000000000000000000000000000000000000000000000000000000036": "0x8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9c", - "0x0000000000000000000000000000000000000000000000000000000000000037": "0xfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167", - "0x0000000000000000000000000000000000000000000000000000000000000038": "0xe71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d7", - "0x0000000000000000000000000000000000000000000000000000000000000039": "0x31206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc0", - "0x000000000000000000000000000000000000000000000000000000000000003a": "0x21352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544", - "0x000000000000000000000000000000000000000000000000000000000000003b": "0x619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a46765", - "0x000000000000000000000000000000000000000000000000000000000000003c": "0x7cdd2986268250628d0c10e385c58c6191e6fbe05191bcc04f133f2cea72c1c4", - "0x000000000000000000000000000000000000000000000000000000000000003d": "0x848930bd7ba8cac54661072113fb278869e07bb8587f91392933374d017bcbe1", - "0x000000000000000000000000000000000000000000000000000000000000003e": "0x8869ff2c22b28cc10510d9853292803328be4fb0e80495e8bb8d271f5b889636", - "0x000000000000000000000000000000000000000000000000000000000000003f": "0xb5fe28e79f1b850f8658246ce9b6a1e7b49fc06db7143e8fe0b4f2b0c5523a5c", - "0x0000000000000000000000000000000000000000000000000000000000000040": "0x985e929f70af28d0bdd1a90a808f977f597c7c778c489e98d3bd8910d31ac0f7" - } - }, - "0x9a4aa7d9C2F6386e5F24d790eB2FFB9fd543A170": { - "balance": "1000000000000000000000000000" - }, - "0x5E3141B900ac5f5608b0d057D10d45a0e4927cD9": { - "balance": "1000000000000000000000000000" - }, - "0x7cF5Dbc49F0904065664b5B6C0d69CaB55F33988": { - "balance": "1000000000000000000000000000" - }, - "0x8D12b071A6F3823A535D38C4a583a2FA1859e822": { - "balance": "1000000000000000000000000000" - }, - "0x3B575D3cda6b30736A38B031E0d245E646A21135": { - "balance": "1000000000000000000000000000" - }, - "0x53bDe6CF93461674F590E532006b4022dA57A724": { - "balance": "1000000000000000000000000000" - } - }, - "coinbase": "0x0000000000000000000000000000000000000000", - "difficulty": "0x01", - "extraData": "", - "gasLimit": "0x400000", - "nonce": "0x1234", - "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "timestamp": "1662465600" -} diff --git a/scripts/tests/network_params.yaml b/scripts/tests/network_params.yaml new file mode 100644 index 0000000000..1725203138 --- /dev/null +++ b/scripts/tests/network_params.yaml @@ -0,0 +1,16 @@ +# Full configuration reference [here](https://github.com/kurtosis-tech/ethereum-package?tab=readme-ov-file#configuration). +participants: + - el_type: geth + el_image: ethereum/client-go:latest + cl_type: lighthouse + cl_image: lighthouse:local + cl_extra_params: + - --target-peers=3 + count: 4 +network_params: + deneb_fork_epoch: 0 + seconds_per_slot: 3 + num_validator_keys_per_node: 20 +global_log_level: debug +snooper_enabled: false +additional_services: [] diff --git a/scripts/tests/vars.env b/scripts/tests/vars.env deleted file mode 100644 index 4d8f9db64e..0000000000 --- a/scripts/tests/vars.env +++ /dev/null @@ -1,66 +0,0 @@ -# Path to the geth binary -GETH_BINARY=geth -EL_BOOTNODE_BINARY=bootnode - -# Base directories for the validator keys and secrets -DATADIR=~/.lighthouse/local-testnet - -# Directory for the eth2 config -TESTNET_DIR=$DATADIR/testnet - -EL_BOOTNODE_ENODE="enode://51ea9bb34d31efc3491a842ed13b8cab70e753af108526b57916d716978b380ed713f4336a80cdb85ec2a115d5a8c0ae9f3247bed3c84d3cb025c6bab311062c@127.0.0.1:0?discport=30301" - -# Hardcoded deposit contract -DEPOSIT_CONTRACT_ADDRESS=4242424242424242424242424242424242424242 - -GENESIS_FORK_VERSION=0x42424242 - -# Block hash generated from genesis.json in directory -ETH1_BLOCK_HASH=7a5c656343c3a66dcf75415958b500e8873f9dab0cd588e6cf0785b52a06dd34 - -VALIDATOR_COUNT=80 -GENESIS_VALIDATOR_COUNT=80 - -# Number of beacon_node instances that you intend to run -BN_COUNT=4 - -# Number of validator clients -VC_COUNT=$BN_COUNT - -# Number of seconds to delay to start genesis block. -# If started by a script this can be 0, if starting by hand -# use something like 180. -GENESIS_DELAY=0 - -# Port for P2P communication with bootnode -BOOTNODE_PORT=4242 - -# Network ID and Chain ID of local eth1 test network -CHAIN_ID=4242 - -# Hard fork configuration -ALTAIR_FORK_EPOCH=0 -BELLATRIX_FORK_EPOCH=0 -CAPELLA_FORK_EPOCH=0 -DENEB_FORK_EPOCH=0 -ELECTRA_FORK_EPOCH=18446744073709551615 - -TTD=0 - -# Spec version (mainnet or minimal) -SPEC_PRESET=mainnet - -# Seconds per Eth2 slot -SECONDS_PER_SLOT=3 - -# Seconds per Eth1 block -SECONDS_PER_ETH1_BLOCK=1 - -# Proposer score boost percentage -PROPOSER_SCORE_BOOST=70 - -# Command line arguments for beacon node client -BN_ARGS="" - -# Enable doppelganger detection -VC_ARGS=" --enable-doppelganger-protection " diff --git a/testing/eth1_test_rig/src/lib.rs b/testing/eth1_test_rig/src/lib.rs index 0063975ee1..55a7160594 100644 --- a/testing/eth1_test_rig/src/lib.rs +++ b/testing/eth1_test_rig/src/lib.rs @@ -95,7 +95,7 @@ impl DepositContract { .await .map_err(|e| { format!( - "Failed to deploy contract: {}. Is scripts/anvil_tests_node.sh running?.", + "Failed to deploy contract: {}. Is the RPC server running?.", e ) })?; diff --git a/validator_client/slashing_protection/src/interchange.rs b/validator_client/slashing_protection/src/interchange.rs index ad5f21e511..95a39c50e4 100644 --- a/validator_client/slashing_protection/src/interchange.rs +++ b/validator_client/slashing_protection/src/interchange.rs @@ -7,7 +7,7 @@ use types::{Epoch, Hash256, PublicKeyBytes, Slot}; #[derive(Debug, Clone, PartialEq, Deserialize, Serialize)] #[serde(deny_unknown_fields)] -#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] +#[cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))] pub struct InterchangeMetadata { #[serde(with = "serde_utils::quoted_u64::require_quotes")] pub interchange_format_version: u64, @@ -16,7 +16,7 @@ pub struct InterchangeMetadata { #[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize, Serialize)] #[serde(deny_unknown_fields)] -#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] +#[cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))] pub struct InterchangeData { pub pubkey: PublicKeyBytes, pub signed_blocks: Vec, @@ -25,7 +25,7 @@ pub struct InterchangeData { #[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize, Serialize)] #[serde(deny_unknown_fields)] -#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] +#[cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))] pub struct SignedBlock { #[serde(with = "serde_utils::quoted_u64::require_quotes")] pub slot: Slot, @@ -35,7 +35,7 @@ pub struct SignedBlock { #[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize, Serialize)] #[serde(deny_unknown_fields)] -#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] +#[cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))] pub struct SignedAttestation { #[serde(with = "serde_utils::quoted_u64::require_quotes")] pub source_epoch: Epoch, @@ -46,7 +46,7 @@ pub struct SignedAttestation { } #[derive(Debug, Clone, PartialEq, Deserialize, Serialize)] -#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] +#[cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))] pub struct Interchange { pub metadata: InterchangeMetadata, pub data: Vec, diff --git a/validator_client/slashing_protection/src/interchange_test.rs b/validator_client/slashing_protection/src/interchange_test.rs index d88bb93a0d..d99647bc93 100644 --- a/validator_client/slashing_protection/src/interchange_test.rs +++ b/validator_client/slashing_protection/src/interchange_test.rs @@ -9,7 +9,7 @@ use tempfile::tempdir; use types::{Epoch, Hash256, PublicKeyBytes, Slot}; #[derive(Debug, Clone, Deserialize, Serialize)] -#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] +#[cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))] pub struct MultiTestCase { pub name: String, pub genesis_validators_root: Hash256, @@ -17,7 +17,7 @@ pub struct MultiTestCase { } #[derive(Debug, Clone, Deserialize, Serialize)] -#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] +#[cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))] pub struct TestCase { pub should_succeed: bool, pub contains_slashable_data: bool, @@ -27,7 +27,7 @@ pub struct TestCase { } #[derive(Debug, Clone, Deserialize, Serialize)] -#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] +#[cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))] pub struct TestBlock { pub pubkey: PublicKeyBytes, pub slot: Slot, @@ -37,7 +37,7 @@ pub struct TestBlock { } #[derive(Debug, Clone, Deserialize, Serialize)] -#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] +#[cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))] pub struct TestAttestation { pub pubkey: PublicKeyBytes, pub source_epoch: Epoch, diff --git a/validator_client/src/cli.rs b/validator_client/src/cli.rs index 66b467c1e2..24f9f41415 100644 --- a/validator_client/src/cli.rs +++ b/validator_client/src/cli.rs @@ -406,6 +406,15 @@ pub fn cli_app() -> Command { .help_heading(FLAG_HEADER) .display_order(0) ) + .arg( + Arg::new("latency-measurement-service") + .long("latency-measurement-service") + .help("DEPRECATED") + .action(ArgAction::Set) + .help_heading(FLAG_HEADER) + .display_order(0) + .hide(true) + ) .arg( Arg::new("validator-registration-batch-size") .long("validator-registration-batch-size") diff --git a/validator_client/src/config.rs b/validator_client/src/config.rs index eb47fcf31a..3edab712b3 100644 --- a/validator_client/src/config.rs +++ b/validator_client/src/config.rs @@ -412,6 +412,17 @@ impl Config { config.enable_latency_measurement_service = !cli_args.get_flag("disable-latency-measurement-service"); + if cli_args + .get_one::("latency-measurement-service") + .is_some() + { + warn!( + log, + "latency-measurement-service flag"; + "note" => "deprecated flag has no effect and should be removed" + ); + } + config.validator_registration_batch_size = parse_required(cli_args, "validator-registration-batch-size")?; if config.validator_registration_batch_size == 0 { diff --git a/validator_manager/src/lib.rs b/validator_manager/src/lib.rs index 101d6d2136..222dd7076d 100644 --- a/validator_manager/src/lib.rs +++ b/validator_manager/src/lib.rs @@ -40,7 +40,7 @@ impl DumpConfig { pub fn cli_app() -> Command { Command::new(CMD) - .visible_aliases(["vm", "validator-manager", CMD]) + .visible_aliases(["vm", "validator-manager"]) .display_order(0) .styles(get_color_style()) .about("Utilities for managing a Lighthouse validator client via the HTTP API.")