From 4d1d24ecb40911816b3eb6a80a813d21406645e6 Mon Sep 17 00:00:00 2001 From: mh0lt Date: Wed, 1 Jul 2026 19:19:29 +0000 Subject: [PATCH 1/4] ci, db/state: matrix-test serial vs parallel commitment across the test workflows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Parallel execution (dbg.Exec3Parallel) is now the default, so the serial/parallel exec-mode CI matrix from #21017 no longer needs to toggle it — both legs run parallel exec. This repurposes that matrix axis to instead exercise serial vs parallel commitment, so divergence between statecfg.ExperimentalParallelCommitment true and false is caught on the PR rather than after release. The toggle is plumbed via ERIGON_COMMITMENT_PARALLEL: state_schema.go now reads COMMITMENT_PARALLEL via dbg.EnvBool (envLookup auto-prepends ERIGON_), mirroring EXEC3_PARALLEL. The existing CLI flag still composes — backend.go only flips the flag on, and the integration command's BoolVar now defaults to the env-derived value instead of clobbering it to false at registration. Across the 11 test workflows the exec_mode axis is renamed commitment_mode, the ERIGON_EXEC3_PARALLEL assignment is dropped, and ERIGON_COMMITMENT_PARALLEL is set from the axis (or, for the two workflow_dispatch perf tests, from the renamed input). Docker ENV injection for the hive/kurtosis/txpool images is updated to the new var. Per-mode Go build-cache lineages and artifact/enclave/testbed names carry over unchanged in shape. --- .../qa-rpc-integration-tests-latest.yml | 20 +++---- .../qa-rpc-performance-comparison-tests.yml | 26 ++++----- .../workflows/qa-rpc-performance-tests.yml | 26 ++++----- .github/workflows/qa-stage-exec.yml | 38 ++++++------- .../workflows/qa-txpool-performance-test.yml | 30 +++++------ .github/workflows/test-all-erigon-race.yml | 27 +++++----- .github/workflows/test-all-erigon.yml | 29 +++++----- .github/workflows/test-bench.yml | 17 +++--- .github/workflows/test-hive-eest.yml | 51 +++++++++--------- .github/workflows/test-hive.yml | 53 ++++++++++--------- .github/workflows/test-kurtosis-assertoor.yml | 45 ++++++++-------- cmd/integration/commands/flags.go | 4 +- db/state/statecfg/state_schema.go | 5 +- 13 files changed, 189 insertions(+), 182 deletions(-) diff --git a/.github/workflows/qa-rpc-integration-tests-latest.yml b/.github/workflows/qa-rpc-integration-tests-latest.yml index da22e7a2867..3b758c43b19 100644 --- a/.github/workflows/qa-rpc-integration-tests-latest.yml +++ b/.github/workflows/qa-rpc-integration-tests-latest.yml @@ -23,7 +23,7 @@ on: jobs: mainnet-rpc-integ-tests-latest: - name: mainnet-rpc-integ-tests-latest (${{ matrix.exec_mode }}) + name: mainnet-rpc-integ-tests-latest (${{ matrix.commitment_mode }}) concurrency: group: >- ${{ @@ -42,7 +42,7 @@ jobs: # just one after the other (~2× wall-clock). max-parallel: 1 matrix: - exec_mode: + commitment_mode: - serial - parallel env: @@ -53,10 +53,10 @@ jobs: ERIGON_ASSERT: true RPC_PAST_TEST_DIR: /opt/rpc-past-tests CHAIN: mainnet - # Toggle dbg.Exec3Parallel from CI without code changes. envLookup - # in common/dbg/dbg_env.go auto-prepends ERIGON_, so this maps to - # the EXEC3_PARALLEL flag declared in common/dbg/experiments.go. - ERIGON_EXEC3_PARALLEL: ${{ matrix.exec_mode == 'parallel' && 'true' || 'false' }} + # Toggle statecfg.ExperimentalParallelCommitment from CI without code + # changes. envLookup in common/dbg/dbg_env.go auto-prepends ERIGON_, so + # this maps to the COMMITMENT_PARALLEL flag read in db/state/statecfg. + ERIGON_COMMITMENT_PARALLEL: ${{ matrix.commitment_mode == 'parallel' && 'true' || 'false' }} steps: - name: Check out repository @@ -123,7 +123,7 @@ jobs: if: failure() && steps.preparing_step.outcome == 'failure' uses: actions/upload-artifact@v7 with: - name: preparing-step-logs-${{ matrix.exec_mode }} + name: preparing-step-logs-${{ matrix.commitment_mode }} path: ${{ env.ERIGON_REFERENCE_DATA_DIR }}/logs/ - name: Pause the Erigon instance dedicated to db maintenance @@ -180,7 +180,7 @@ jobs: if: failure() && steps.pre_test_step.outcome == 'failure' uses: actions/upload-artifact@v7 with: - name: pre-test-logs-${{ matrix.exec_mode }} + name: pre-test-logs-${{ matrix.commitment_mode }} path: ${{ env.ERIGON_TESTBED_DATA_DIR }}/logs/ - name: Run RPC Integration Tests @@ -260,7 +260,7 @@ jobs: if: always() && steps.test_step.outputs.test_executed == 'true' uses: actions/upload-artifact@v7 with: - name: test-results-${{ matrix.exec_mode }} + name: test-results-${{ matrix.commitment_mode }} path: | ${{ env.TEST_RESULT_DIR }} ${{ env.ERIGON_TESTBED_DATA_DIR }}/logs/ @@ -280,7 +280,7 @@ jobs: --repo erigon \ --commit $(git rev-parse HEAD) \ --branch ${{ github.ref_name }} \ - --test_name rpc-integration-tests-latest${{ matrix.exec_mode == 'parallel' && '-parallel' || '' }} \ + --test_name rpc-integration-tests-latest${{ matrix.commitment_mode == 'parallel' && '-parallel' || '' }} \ --chain $CHAIN \ --runner ${{ runner.name }} \ --db_version $db_version \ diff --git a/.github/workflows/qa-rpc-performance-comparison-tests.yml b/.github/workflows/qa-rpc-performance-comparison-tests.yml index 6127920cde0..e07970cd891 100644 --- a/.github/workflows/qa-rpc-performance-comparison-tests.yml +++ b/.github/workflows/qa-rpc-performance-comparison-tests.yml @@ -8,8 +8,8 @@ on: type: boolean required: false default: false - exec_mode: - description: 'Erigon execution mode ("default" leaves ERIGON_EXEC3_PARALLEL unset)' + commitment_mode: + description: 'Erigon commitment mode ("default" leaves ERIGON_COMMITMENT_PARALLEL unset)' type: choice required: false default: default @@ -194,22 +194,22 @@ jobs: id: erigon_running_step working-directory: ${{ github.workspace }}/build/bin env: - EXEC_MODE: ${{ github.event.inputs.exec_mode }} + EXEC_MODE: ${{ github.event.inputs.commitment_mode }} run: | set +e # Disable exit on error echo "Starting Erigon..." - # Only set ERIGON_EXEC3_PARALLEL on an explicit choice; otherwise ensure it's + # Only set ERIGON_COMMITMENT_PARALLEL on an explicit choice; otherwise ensure it's # unset so erigon uses its built-in default (and doesn't inherit runner env). if [ "$EXEC_MODE" = "parallel" ]; then - export ERIGON_EXEC3_PARALLEL=true - echo "Set ERIGON_EXEC3_PARALLEL=true (parallel mode)" + export ERIGON_COMMITMENT_PARALLEL=true + echo "Set ERIGON_COMMITMENT_PARALLEL=true (parallel mode)" elif [ "$EXEC_MODE" = "serial" ]; then - export ERIGON_EXEC3_PARALLEL=false - echo "Set ERIGON_EXEC3_PARALLEL=false (serial mode)" + export ERIGON_COMMITMENT_PARALLEL=false + echo "Set ERIGON_COMMITMENT_PARALLEL=false (serial mode)" else - unset ERIGON_EXEC3_PARALLEL - echo "Leaving ERIGON_EXEC3_PARALLEL unset (default behavior)" + unset ERIGON_COMMITMENT_PARALLEL + echo "Leaving ERIGON_COMMITMENT_PARALLEL unset (default behavior)" fi ./erigon --prune.mode=minimal --datadir $ERIGON_TESTBED_DATA_DIR --http.api admin,debug,eth,parity,erigon,trace,web3,txpool,ots,net --ws > erigon.log 2>&1 & @@ -378,7 +378,7 @@ jobs: --repo $client \ --branch $branch_name \ --commit $commit_hash \ - --test_name rpc-performance-test-latest${{ (matrix.client == 'erigon' && github.event.inputs.exec_mode == 'parallel' && '-parallel') || (matrix.client == 'erigon' && github.event.inputs.exec_mode == 'serial' && '-serial') || '' }}-$method \ + --test_name rpc-performance-test-latest${{ (matrix.client == 'erigon' && github.event.inputs.commitment_mode == 'parallel' && '-parallel') || (matrix.client == 'erigon' && github.event.inputs.commitment_mode == 'serial' && '-serial') || '' }}-$method \ --chain $CHAIN \ --runner ${{ runner.name }} \ --db_version $db_version \ @@ -451,7 +451,7 @@ jobs: if: (matrix.client == 'erigon' || needs.setup.outputs.run_geth == 'true') && steps.test_step.outputs.test_executed == 'true' uses: actions/upload-artifact@v7 with: - name: test-results-${{ env.CHAIN }}-${{ matrix.client }}${{ (matrix.client == 'erigon' && github.event.inputs.exec_mode == 'parallel' && '-parallel') || (matrix.client == 'erigon' && github.event.inputs.exec_mode == 'serial' && '-serial') || '' }} + name: test-results-${{ env.CHAIN }}-${{ matrix.client }}${{ (matrix.client == 'erigon' && github.event.inputs.commitment_mode == 'parallel' && '-parallel') || (matrix.client == 'erigon' && github.event.inputs.commitment_mode == 'serial' && '-serial') || '' }} path: ${{ env.past_test_dir }} - name: Stop Erigon @@ -471,7 +471,7 @@ jobs: if: matrix.client == 'erigon' && steps.test_step.outputs.test_executed == 'true' uses: actions/upload-artifact@v7 with: - name: erigon-logs-${{ env.CHAIN }}${{ (github.event.inputs.exec_mode == 'parallel' && '-parallel') || (github.event.inputs.exec_mode == 'serial' && '-serial') || '' }} + name: erigon-logs-${{ env.CHAIN }}${{ (github.event.inputs.commitment_mode == 'parallel' && '-parallel') || (github.event.inputs.commitment_mode == 'serial' && '-serial') || '' }} path: ${{ github.workspace }}/build/bin/erigon.log - name: Delete Erigon Testbed Data Directory diff --git a/.github/workflows/qa-rpc-performance-tests.yml b/.github/workflows/qa-rpc-performance-tests.yml index e08e7ab9d09..1303d34bfa2 100644 --- a/.github/workflows/qa-rpc-performance-tests.yml +++ b/.github/workflows/qa-rpc-performance-tests.yml @@ -11,8 +11,8 @@ on: type: boolean required: false default: false - exec_mode: - description: 'Erigon execution mode ("default" leaves ERIGON_EXEC3_PARALLEL unset)' + commitment_mode: + description: 'Erigon commitment mode ("default" leaves ERIGON_COMMITMENT_PARALLEL unset)' type: choice required: false default: default @@ -208,21 +208,21 @@ jobs: if: matrix.client == 'erigon' working-directory: ${{ github.workspace }}/build/bin env: - EXEC_MODE: ${{ github.event.inputs.exec_mode }} + EXEC_MODE: ${{ github.event.inputs.commitment_mode }} run: | echo "Starting RpcDaemon..." - # Only set ERIGON_EXEC3_PARALLEL on an explicit choice; otherwise ensure it's + # Only set ERIGON_COMMITMENT_PARALLEL on an explicit choice; otherwise ensure it's # unset so erigon uses its built-in default (and doesn't inherit runner env). if [ "$EXEC_MODE" = "parallel" ]; then - export ERIGON_EXEC3_PARALLEL=true - echo "Set ERIGON_EXEC3_PARALLEL=true (parallel mode)" + export ERIGON_COMMITMENT_PARALLEL=true + echo "Set ERIGON_COMMITMENT_PARALLEL=true (parallel mode)" elif [ "$EXEC_MODE" = "serial" ]; then - export ERIGON_EXEC3_PARALLEL=false - echo "Set ERIGON_EXEC3_PARALLEL=false (serial mode)" + export ERIGON_COMMITMENT_PARALLEL=false + echo "Set ERIGON_COMMITMENT_PARALLEL=false (serial mode)" else - unset ERIGON_EXEC3_PARALLEL - echo "Leaving ERIGON_EXEC3_PARALLEL unset (default behavior)" + unset ERIGON_COMMITMENT_PARALLEL + echo "Leaving ERIGON_COMMITMENT_PARALLEL unset (default behavior)" fi ./rpcdaemon --datadir $ERIGON_REFERENCE_DATA_DIR --http.api admin,debug,eth,parity,erigon,trace,web3,txpool,ots,net > erigon.log 2>&1 & @@ -371,7 +371,7 @@ jobs: --repo $client \ --branch $branch_name \ --commit $commit_hash \ - --test_name rpc-performance-test-$client${{ (matrix.client == 'erigon' && github.event.inputs.exec_mode == 'parallel' && '-parallel') || (matrix.client == 'erigon' && github.event.inputs.exec_mode == 'serial' && '-serial') || '' }}-$method \ + --test_name rpc-performance-test-$client${{ (matrix.client == 'erigon' && github.event.inputs.commitment_mode == 'parallel' && '-parallel') || (matrix.client == 'erigon' && github.event.inputs.commitment_mode == 'serial' && '-serial') || '' }}-$method \ --chain $CHAIN \ --runner ${{ runner.name }} \ --db_version $db_version \ @@ -434,7 +434,7 @@ jobs: if: always() && matrix.client == 'erigon' && steps.rpcdaemon_running_step.outputs.rpc_daemon_started == 'true' uses: actions/upload-artifact@v7 with: - name: rpcdaemon-logs${{ (github.event.inputs.exec_mode == 'parallel' && '-parallel') || (github.event.inputs.exec_mode == 'serial' && '-serial') || '' }} + name: rpcdaemon-logs${{ (github.event.inputs.commitment_mode == 'parallel' && '-parallel') || (github.event.inputs.commitment_mode == 'serial' && '-serial') || '' }} path: ${{ github.workspace }}/build/bin/erigon.log - name: Restore Erigon Chaindata Directory @@ -470,7 +470,7 @@ jobs: if: (matrix.client == 'erigon' || needs.setup.outputs.run_geth == 'true') && steps.test_step.outputs.test_executed == 'true' uses: actions/upload-artifact@v7 with: - name: test-results-${{ env.CHAIN }}-${{ matrix.client }}${{ (matrix.client == 'erigon' && github.event.inputs.exec_mode == 'parallel' && '-parallel') || (matrix.client == 'erigon' && github.event.inputs.exec_mode == 'serial' && '-serial') || '' }} + name: test-results-${{ env.CHAIN }}-${{ matrix.client }}${{ (matrix.client == 'erigon' && github.event.inputs.commitment_mode == 'parallel' && '-parallel') || (matrix.client == 'erigon' && github.event.inputs.commitment_mode == 'serial' && '-serial') || '' }} path: ${{ env.past_test_dir }} - name: Action to check failure condition diff --git a/.github/workflows/qa-stage-exec.yml b/.github/workflows/qa-stage-exec.yml index 96f931f01e8..76448237d32 100644 --- a/.github/workflows/qa-stage-exec.yml +++ b/.github/workflows/qa-stage-exec.yml @@ -17,48 +17,48 @@ concurrency: jobs: stage-exec-test: - name: stage-exec-test (${{ matrix.mode_name }}, ${{ matrix.exec_mode }}) + name: stage-exec-test (${{ matrix.mode_name }}, ${{ matrix.commitment_mode }}) runs-on: [self-hosted, qa, Ethereum, tip-tracking] strategy: fail-fast: false matrix: - # Each (mode_name, exec_mode) pair runs separately. The testbed + # Each (mode_name, commitment_mode) pair runs separately. The testbed # data dir already disambiguates by mode_name; we extend it with - # exec_mode so serial+parallel entries don't clobber each other. + # commitment_mode so serial+parallel entries don't clobber each other. include: - mode_name: resume-nonchaintip extra_flags: "" test_name: stage_exec_resume_nonchaintip - exec_mode: serial + commitment_mode: serial - mode_name: resume-nonchaintip extra_flags: "" test_name: stage_exec_resume_nonchaintip - exec_mode: parallel + commitment_mode: parallel - mode_name: from-0 extra_flags: "--rm-state-all" test_name: stage_exec_from_0 - exec_mode: serial + commitment_mode: serial - mode_name: from-0 extra_flags: "--rm-state-all" test_name: stage_exec_from_0 - exec_mode: parallel + commitment_mode: parallel - mode_name: chaintip extra_flags: "--chaintip" test_name: stage_exec_resume_chaintip - exec_mode: serial + commitment_mode: serial - mode_name: chaintip extra_flags: "--chaintip" test_name: stage_exec_resume_chaintip - exec_mode: parallel + commitment_mode: parallel env: - ERIGON_TESTBED_DATA_DIR: /opt/erigon-testbed/datadir-${{ matrix.mode_name }}-${{ matrix.exec_mode }} + ERIGON_TESTBED_DATA_DIR: /opt/erigon-testbed/datadir-${{ matrix.mode_name }}-${{ matrix.commitment_mode }} ERIGON_QA_PATH: /home/qarunner/erigon-qa TIMEOUT_SECONDS: 360 CHAIN: mainnet - # Toggle dbg.Exec3Parallel from CI without code changes. envLookup - # in common/dbg/dbg_env.go auto-prepends ERIGON_, so this maps to - # the EXEC3_PARALLEL flag declared in common/dbg/experiments.go. - ERIGON_EXEC3_PARALLEL: ${{ matrix.exec_mode == 'parallel' && 'true' || 'false' }} + # Toggle statecfg.ExperimentalParallelCommitment from CI without code + # changes. envLookup in common/dbg/dbg_env.go auto-prepends ERIGON_, so + # this maps to the COMMITMENT_PARALLEL flag read in db/state/statecfg. + ERIGON_COMMITMENT_PARALLEL: ${{ matrix.commitment_mode == 'parallel' && 'true' || 'false' }} steps: - name: Check out repository @@ -114,7 +114,7 @@ jobs: python3 $ERIGON_QA_PATH/test_system/qa-tests/stage-exec/run_and_check_stage_exec.py \ ${{ github.workspace }}/build/bin $ERIGON_TESTBED_DATA_DIR $TIMEOUT_SECONDS $CHAIN \ - --result-file ${{ github.workspace }}/result-$CHAIN-${{ matrix.mode_name }}-${{ matrix.exec_mode }}.json \ + --result-file ${{ github.workspace }}/result-$CHAIN-${{ matrix.mode_name }}-${{ matrix.commitment_mode }}.json \ ${{ matrix.extra_flags }} test_exit_status=$? @@ -148,20 +148,20 @@ jobs: --runner ${{ runner.name }} \ --db_version $db_version \ --outcome $TEST_RESULT \ - --result_file ${{ github.workspace }}/result-$CHAIN-${{ matrix.mode_name }}-${{ matrix.exec_mode }}.json + --result_file ${{ github.workspace }}/result-$CHAIN-${{ matrix.mode_name }}-${{ matrix.commitment_mode }}.json - name: Upload test results if: ${{ always() && steps.test_step.outputs.test_executed == 'true' }} uses: actions/upload-artifact@v7 with: - name: test-results-${{ matrix.mode_name }}-${{ matrix.exec_mode }} - path: ${{ github.workspace }}/result-${{ env.CHAIN }}-${{ matrix.mode_name }}-${{ matrix.exec_mode }}.json + name: test-results-${{ matrix.mode_name }}-${{ matrix.commitment_mode }} + path: ${{ github.workspace }}/result-${{ env.CHAIN }}-${{ matrix.mode_name }}-${{ matrix.commitment_mode }}.json - name: Upload erigon logs if: ${{ always() && steps.test_step.outputs.test_executed == 'true' }} uses: actions/upload-artifact@v7 with: - name: erigon-logs-${{ matrix.mode_name }}-${{ matrix.exec_mode }} + name: erigon-logs-${{ matrix.mode_name }}-${{ matrix.commitment_mode }} path: ${{ env.ERIGON_TESTBED_DATA_DIR }}/logs/ - name: Delete Erigon Testbed Data Directory diff --git a/.github/workflows/qa-txpool-performance-test.yml b/.github/workflows/qa-txpool-performance-test.yml index 57dc5ecce98..fab477c46ab 100644 --- a/.github/workflows/qa-txpool-performance-test.yml +++ b/.github/workflows/qa-txpool-performance-test.yml @@ -18,23 +18,23 @@ on: jobs: tx_pool_assertoor_test: - name: tx_pool_assertoor_test (${{ matrix.exec_mode }}) + name: tx_pool_assertoor_test (${{ matrix.commitment_mode }}) runs-on: [self-hosted, qa, X64, long-running] strategy: fail-fast: false # Self-hosted long-running pool is small; matrix entries serialize. max-parallel: 1 matrix: - exec_mode: + commitment_mode: - serial - parallel env: ERIGON_QA_PATH: /home/qarunner/erigon-qa - ENCLAVE_NAME: "kurtosis-run-${{ github.run_id }}-${{ matrix.exec_mode }}" - # Toggle dbg.Exec3Parallel from CI without code changes. envLookup - # in common/dbg/dbg_env.go auto-prepends ERIGON_, so this maps to - # the EXEC3_PARALLEL flag declared in common/dbg/experiments.go. - ERIGON_EXEC3_PARALLEL: ${{ matrix.exec_mode == 'parallel' && 'true' || 'false' }} + ENCLAVE_NAME: "kurtosis-run-${{ github.run_id }}-${{ matrix.commitment_mode }}" + # Toggle statecfg.ExperimentalParallelCommitment from CI without code + # changes. envLookup in common/dbg/dbg_env.go auto-prepends ERIGON_, so + # this maps to the COMMITMENT_PARALLEL flag read in db/state/statecfg. + ERIGON_COMMITMENT_PARALLEL: ${{ matrix.commitment_mode == 'parallel' && 'true' || 'false' }} steps: - name: Fast checkout git repository @@ -50,14 +50,14 @@ jobs: run: | docker build -t test/erigon:current-base . - - name: Bake exec_mode env into the runtime image - # Add ERIGON_EXEC3_PARALLEL as an ENV layer on top of the base image - # so the matrix entries differ in exec mode. ENV layers are cheap and - # don't invalidate earlier layer caches. + - name: Bake commitment_mode env into the runtime image + # Add ERIGON_COMMITMENT_PARALLEL as an ENV layer on top of the base + # image so the matrix entries differ in commitment mode. ENV layers are + # cheap and don't invalidate earlier layer caches. run: | docker build -t test/erigon:current - <> clients/erigon/Dockerfile + echo "ENV ERIGON_COMMITMENT_PARALLEL=${ERIGON_COMMITMENT_PARALLEL}" >> clients/erigon/Dockerfile erigon_extra_flags="${{ matrix.erigon-extra-flags }}" if [ -n "$erigon_extra_flags" ]; then echo "Patching erigon.sh with extra flags: $erigon_extra_flags" @@ -324,9 +325,9 @@ jobs: if: always() uses: actions/upload-artifact@v7 with: - # exec_mode in the artifact name keeps the two matrix entries from + # commitment_mode in the artifact name keeps the two matrix entries from # clobbering each other's logs on the same artifact key. - name: hive-workspace-log-${{ matrix.shard }}-${{ matrix.exec_mode }} + name: hive-workspace-log-${{ matrix.shard }}-${{ matrix.commitment_mode }} path: hive/workspace/logs if-no-files-found: ignore - name: Test Results diff --git a/.github/workflows/test-hive.yml b/.github/workflows/test-hive.yml index a811bb0677e..d466f48e493 100644 --- a/.github/workflows/test-hive.yml +++ b/.github/workflows/test-hive.yml @@ -12,7 +12,7 @@ concurrency: jobs: test-hive: - name: test-hive (${{ matrix.sim }}, ${{ matrix.sim-limit }}, ${{ matrix.exec_mode }}) + name: test-hive (${{ matrix.sim }}, ${{ matrix.sim-limit }}, ${{ matrix.commitment_mode }}) if: >- ${{ !github.event.pull_request.number || (!github.event.pull_request.draft @@ -26,10 +26,11 @@ jobs: # picture across every shard. fail-fast: ${{ github.event_name == 'merge_group' }} matrix: - # Each (sim, sim-limit) pair is run twice — once with serial exec - # (ERIGON_EXEC3_PARALLEL=false) and once with parallel — so engine-API - # / wire-protocol divergence between the two paths is caught on the - # PR. Matrix entries spawn separate `hive` group runners and run + # Each (sim, sim-limit) pair is run twice — once with serial commitment + # (ERIGON_COMMITMENT_PARALLEL=false) and once with parallel — so + # engine-API / wire-protocol divergence between the two paths is caught + # on the PR. Execution is parallel in both legs (default). Matrix + # entries spawn separate `hive` group runners and run # concurrently — wall-clock unchanged, runner-minutes doubled. # `sim` is the simulator path passed to `hive --sim`. Most simulators # live under simulators/ethereum/, but a few (e.g. devp2p) are top-level. @@ -37,53 +38,53 @@ jobs: - sim: ethereum/engine sim-limit: exchange-capabilities|auth max-allowed-failures: 0 - exec_mode: serial + commitment_mode: serial - sim: ethereum/engine sim-limit: exchange-capabilities|auth max-allowed-failures: 0 - exec_mode: parallel + commitment_mode: parallel - sim: ethereum/engine sim-limit: withdrawals max-allowed-failures: 0 - exec_mode: serial + commitment_mode: serial - sim: ethereum/engine sim-limit: withdrawals max-allowed-failures: 0 - exec_mode: parallel + commitment_mode: parallel - sim: ethereum/engine sim-limit: cancun max-allowed-failures: 0 - exec_mode: serial + commitment_mode: serial - sim: ethereum/engine sim-limit: cancun max-allowed-failures: 0 - exec_mode: parallel + commitment_mode: parallel - sim: ethereum/engine sim-limit: api max-allowed-failures: 0 - exec_mode: serial + commitment_mode: serial - sim: ethereum/engine sim-limit: api max-allowed-failures: 0 - exec_mode: parallel + commitment_mode: parallel - sim: ethereum/rpc-compat sim-limit: ".*" max-allowed-failures: 7 - exec_mode: serial + commitment_mode: serial - sim: ethereum/rpc-compat sim-limit: ".*" max-allowed-failures: 7 - exec_mode: parallel + commitment_mode: parallel - sim: devp2p sim-limit: eth max-allowed-failures: 0 - exec_mode: serial + commitment_mode: serial # discv5 exercises peer discovery, not the EL exec path, so it runs in - # just one exec mode — duplicating it in the serial leg adds no signal. + # just one commitment mode — duplicating it in the serial leg adds no signal. - sim: devp2p sim-limit: eth|discv5 max-allowed-failures: 0 - exec_mode: parallel + commitment_mode: parallel steps: - name: Checkout Erigon uses: actions/checkout@v7 @@ -149,10 +150,10 @@ jobs: - name: Get dependencies and build hive env: EXECUTION_APIS_REF: ${{ steps.hive-version.outputs.execution_apis_ref }} - # Toggle dbg.Exec3Parallel inside the hive erigon container. - # We bake this as an ENV directive into the client Dockerfile so - # every erigon instance hive launches inherits it. - ERIGON_EXEC3_PARALLEL: ${{ matrix.exec_mode == 'parallel' && 'true' || 'false' }} + # Toggle statecfg.ExperimentalParallelCommitment inside the hive + # erigon container. We bake this as an ENV directive into the client + # Dockerfile so every erigon instance hive launches inherits it. + ERIGON_COMMITMENT_PARALLEL: ${{ matrix.commitment_mode == 'parallel' && 'true' || 'false' }} run: | cd hive retry() { @@ -175,10 +176,10 @@ jobs: echo "ERROR: failed to repoint hive's erigon client Dockerfile at hive/erigon:cilocal" exit 1 fi - # Inject ERIGON_EXEC3_PARALLEL into the runtime image so the + # Inject ERIGON_COMMITMENT_PARALLEL into the runtime image so the # erigon process inside hive picks it up. Append as the last layer # so it doesn't invalidate earlier build caches. - echo "ENV ERIGON_EXEC3_PARALLEL=${ERIGON_EXEC3_PARALLEL}" >> clients/erigon/Dockerfile + echo "ENV ERIGON_COMMITMENT_PARALLEL=${ERIGON_COMMITMENT_PARALLEL}" >> clients/erigon/Dockerfile # Pin the execution-apis ref used by the rpc-compat simulator so that # upstream test additions don't break CI unexpectedly. # SECURITY: value comes from hive-versions.json which fork PRs can modify; @@ -254,13 +255,13 @@ jobs: - name: Compute artifact name id: artifact-name env: - RAW_NAME: hive-workspace-log-${{ matrix.sim }}-${{ matrix.sim-limit }}-${{ matrix.exec_mode }} + RAW_NAME: hive-workspace-log-${{ matrix.sim }}-${{ matrix.sim-limit }}-${{ matrix.commitment_mode }} run: echo "name=${RAW_NAME//[^A-Za-z0-9._-]/_}" >> "$GITHUB_OUTPUT" - name: Upload output log uses: actions/upload-artifact@v7 with: - # exec_mode in the artifact name keeps the two matrix entries from + # commitment_mode in the artifact name keeps the two matrix entries from # clobbering each other's logs on the same artifact key. name: ${{ steps.artifact-name.outputs.name }} path: hive/workspace/logs diff --git a/.github/workflows/test-kurtosis-assertoor.yml b/.github/workflows/test-kurtosis-assertoor.yml index 37bf448da6a..af645d30295 100644 --- a/.github/workflows/test-kurtosis-assertoor.yml +++ b/.github/workflows/test-kurtosis-assertoor.yml @@ -304,7 +304,7 @@ jobs: key: docker-buildkit-${{ env.BUILDKIT_IMAGE }} assertoor_test: - name: assertoor_${{ matrix.suite }}_${{ matrix.exec_mode }}_test + name: assertoor_${{ matrix.suite }}_${{ matrix.commitment_mode }}_test needs: build-erigon-image # On cache-warming runs build-erigon-image alone warms the kurtosis image # cache; there's nothing for the matrix to do (the test step is skipped). @@ -324,32 +324,33 @@ jobs: # pass but pathological hangs (e.g. a node that silently stops proposing) # fail in reasonable time instead of burning hours. # - # Each suite runs twice — once with serial exec - # (ERIGON_EXEC3_PARALLEL=false) and once with parallel — so divergence - # is caught on the PR. Matrix entries spawn separate hosted runners - # and run concurrently — wall-clock unchanged, runner-minutes doubled. + # Each suite runs twice — once with serial commitment + # (ERIGON_COMMITMENT_PARALLEL=false) and once with parallel — so + # divergence is caught on the PR. Execution is parallel in both legs + # (default). Matrix entries spawn separate hosted runners and run + # concurrently — wall-clock unchanged, runner-minutes doubled. # All entries share the single erigon image built by build-erigon-image. include: - suite: regular package_args: .github/workflows/kurtosis/regular-assertoor.io ethereum_package_branch: "5.0.1" test_timeout_minutes: 50 - exec_mode: serial + commitment_mode: serial - suite: regular package_args: .github/workflows/kurtosis/regular-assertoor.io ethereum_package_branch: "5.0.1" test_timeout_minutes: 50 - exec_mode: parallel + commitment_mode: parallel - suite: pectra package_args: .github/workflows/kurtosis/pectra.io ethereum_package_branch: "5.0.1" test_timeout_minutes: 45 - exec_mode: serial + commitment_mode: serial - suite: pectra package_args: .github/workflows/kurtosis/pectra.io ethereum_package_branch: "5.0.1" test_timeout_minutes: 45 - exec_mode: parallel + commitment_mode: parallel - suite: glamsterdam package_args: .github/workflows/kurtosis/glamsterdam.io # Pinned to 6.1.0 rather than main: commit 835dd9b on main introduced GpuConfig, @@ -357,19 +358,19 @@ jobs: # Unpin to main once CI is upgraded to Kurtosis 1.18.1. ethereum_package_branch: "6.1.0" test_timeout_minutes: 20 - exec_mode: parallel + commitment_mode: parallel - suite: caplin-minimal package_args: .github/workflows/kurtosis/caplin-minimal-assertoor.io ethereum_package_url: "github.com/erigontech/ethereum-package" ethereum_package_branch: "erigontech/fix-caplin-launcher" test_timeout_minutes: 20 - exec_mode: serial + commitment_mode: serial - suite: caplin-minimal package_args: .github/workflows/kurtosis/caplin-minimal-assertoor.io ethereum_package_url: "github.com/erigontech/ethereum-package" ethereum_package_branch: "erigontech/fix-caplin-launcher" test_timeout_minutes: 20 - exec_mode: parallel + commitment_mode: parallel steps: - name: Fast checkout git repository @@ -502,16 +503,16 @@ jobs: - name: Load erigon base image into daemon run: docker load -i "${RUNNER_TEMP}/erigon-base-image.tar" - - name: Bake exec_mode env into the runtime image + - name: Bake commitment_mode env into the runtime image # Kurtosis launches `test/erigon:current` as the EL participant. - # Add ERIGON_EXEC3_PARALLEL as an ENV layer on top of the shared - # base image so the matrix entries differ only in exec mode. + # Add ERIGON_COMMITMENT_PARALLEL as an ENV layer on top of the shared + # base image so the matrix entries differ only in commitment mode. env: - ERIGON_EXEC3_PARALLEL: ${{ matrix.exec_mode == 'parallel' && 'true' || 'false' }} + ERIGON_COMMITMENT_PARALLEL: ${{ matrix.commitment_mode == 'parallel' && 'true' || 'false' }} run: | docker build -t test/erigon:current - < Date: Thu, 2 Jul 2026 17:52:57 +0000 Subject: [PATCH 2/4] ci: switch EEST spec shards from exec-parallel to commitment-parallel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Addresses review: the EEST spec shard matrix also toggled execution mode via a -sequential/-parallel suffix (manifest exec3-parallel → ERIGON_EXEC3_PARALLEL). Repurpose it the same way as the other workflows: the suffix now selects serial vs parallel commitment, execution is parallel in every shard (default). tools/eest-spec-shards.yml: rename the per-entry field exec3-parallel → commitment-parallel. tools/run-eest-spec-test.sh: read commitment-parallel and export ERIGON_COMMITMENT_PARALLEL instead of ERIGON_EXEC3_PARALLEL. Shard names (and therefore the ci-gate check names and Makefile targets) are unchanged. --- tools/eest-spec-shards.yml | 36 ++++++++++++++++++++---------------- tools/run-eest-spec-test.sh | 33 +++++++++++++++++---------------- 2 files changed, 37 insertions(+), 32 deletions(-) diff --git a/tools/eest-spec-shards.yml b/tools/eest-spec-shards.yml index 19128d01ff1..e3d2e5cd14a 100644 --- a/tools/eest-spec-shards.yml +++ b/tools/eest-spec-shards.yml @@ -16,7 +16,11 @@ # workers (required) — parallel worker count. # max-allowed-failures (required) — failure budget; bump only with a comment # explaining why and a tracking issue. -# exec3-parallel (optional, default false) — pins ERIGON_EXEC3_PARALLEL. +# commitment-parallel (optional, default false) — pins ERIGON_COMMITMENT_PARALLEL. +# Execution is parallel in every shard +# (dbg.Exec3Parallel defaults true); the +# -sequential/-parallel suffix selects +# serial vs parallel commitment. - shard: statetests-stable workers: 12 @@ -30,67 +34,67 @@ - shard: blocktests-stable-parallel workers: 12 max-allowed-failures: 0 - exec3-parallel: true + commitment-parallel: true - shard: blocktests-devnet workers: 12 max-allowed-failures: 0 - exec3-parallel: true + commitment-parallel: true - shard: enginextests-stable-sequential workers: 8 max-allowed-failures: 0 - shard: enginextests-stable-parallel workers: 8 max-allowed-failures: 0 - exec3-parallel: true + commitment-parallel: true - shard: enginextests-benchmark-1m-sequential workers: 1 max-allowed-failures: 0 - shard: enginextests-benchmark-1m-parallel workers: 1 max-allowed-failures: 0 - exec3-parallel: true + commitment-parallel: true - shard: enginextests-benchmark-5m-sequential workers: 1 max-allowed-failures: 0 - shard: enginextests-benchmark-5m-parallel workers: 1 max-allowed-failures: 0 - exec3-parallel: true + commitment-parallel: true - shard: enginextests-benchmark-10m-sequential workers: 1 max-allowed-failures: 0 - shard: enginextests-benchmark-10m-parallel workers: 1 max-allowed-failures: 0 - exec3-parallel: true + commitment-parallel: true - shard: enginextests-benchmark-30m-sequential workers: 1 max-allowed-failures: 0 - shard: enginextests-benchmark-30m-parallel workers: 1 max-allowed-failures: 0 - exec3-parallel: true + commitment-parallel: true - shard: enginextests-benchmark-60m-sequential workers: 1 max-allowed-failures: 0 - shard: enginextests-benchmark-60m-parallel workers: 1 max-allowed-failures: 0 - exec3-parallel: true + commitment-parallel: true - shard: enginextests-benchmark-100m-sequential workers: 1 max-allowed-failures: 0 - shard: enginextests-benchmark-100m-parallel workers: 1 max-allowed-failures: 0 - exec3-parallel: true + commitment-parallel: true - shard: enginextests-benchmark-150m-sequential workers: 1 max-allowed-failures: 0 - shard: enginextests-benchmark-150m-parallel workers: 1 max-allowed-failures: 0 - exec3-parallel: true + commitment-parallel: true - shard: blocktests-stable-race-pre-cancun-sequential workers: 12 max-allowed-failures: 0 @@ -106,23 +110,23 @@ - shard: blocktests-stable-race-pre-cancun-parallel workers: 12 max-allowed-failures: 0 - exec3-parallel: true + commitment-parallel: true - shard: blocktests-stable-race-cancun-parallel workers: 12 max-allowed-failures: 0 - exec3-parallel: true + commitment-parallel: true - shard: blocktests-stable-race-prague-parallel workers: 12 max-allowed-failures: 0 - exec3-parallel: true + commitment-parallel: true - shard: blocktests-stable-race-osaka-parallel workers: 12 max-allowed-failures: 0 - exec3-parallel: true + commitment-parallel: true - shard: blocktests-devnet-race-amsterdam workers: 12 max-allowed-failures: 0 - exec3-parallel: true + commitment-parallel: true - shard: zkevm-witness-race workers: 8 max-allowed-failures: 0 diff --git a/tools/run-eest-spec-test.sh b/tools/run-eest-spec-test.sh index 239e789010a..3f31c30b542 100755 --- a/tools/run-eest-spec-test.sh +++ b/tools/run-eest-spec-test.sh @@ -35,12 +35,13 @@ # the whole corpus (run via evm.race). # *-parallel any of the above with "-parallel" # appended runs with -# ERIGON_EXEC3_PARALLEL=true. Every +# ERIGON_COMMITMENT_PARALLEL=true. Every # other shard runs with -# ERIGON_EXEC3_PARALLEL=false so +# ERIGON_COMMITMENT_PARALLEL=false so # the runtime default in -# dbg.Exec3Parallel can flip without -# redefining the shards. +# statecfg.ExperimentalParallelCommitment +# can flip without redefining the shards. +# Execution is parallel in every shard. # # Each shard maps to one cmd/evm subcommand running with --jsonout. Pass/fail # is decided here (not by the binary, which always exits 0): the shard fails @@ -77,26 +78,26 @@ case "$shard" in esac base=test-fixtures-cache/$fixtures/fixtures -# Resolve workers + failure budget + exec3-parallel flag from the single-source -# manifest. Both this script and the test-eest-spec.yml load-matrix job read -# tools/eest-spec-shards.yml, so adding a shard / tweaking a budget is a +# Resolve workers + failure budget + commitment-parallel flag from the +# single-source manifest. Both this script and the test-eest-spec.yml load-matrix +# job read tools/eest-spec-shards.yml, so adding a shard / tweaking a budget is a # one-file edit. yq converts YAML→JSON so the jq query stays identical. manifest=tools/eest-spec-shards.yml -budget_row=$(yq -o=json '.' "$manifest" | jq -r --arg s "$shard" '.[] | select(.shard == $s) | "\(.workers)\t\(."max-allowed-failures")\t\(."exec3-parallel" // false)"') +budget_row=$(yq -o=json '.' "$manifest" | jq -r --arg s "$shard" '.[] | select(.shard == $s) | "\(.workers)\t\(."max-allowed-failures")\t\(."commitment-parallel" // false)"') if [[ -z "$budget_row" ]]; then echo "shard $shard not found in $manifest" >&2 exit 2 fi -IFS=$'\t' read -r default_workers default_max exec3_parallel <<<"$budget_row" -# Always set ERIGON_EXEC3_PARALLEL explicitly (true or false) so the shard's -# behaviour is pinned to the manifest, independent of whatever dbg.Exec3Parallel -# defaults to at runtime. If the default flips, the shards still run the mode -# they were defined for. -export ERIGON_EXEC3_PARALLEL="$exec3_parallel" +IFS=$'\t' read -r default_workers default_max commitment_parallel <<<"$budget_row" +# Always set ERIGON_COMMITMENT_PARALLEL explicitly (true or false) so the shard's +# commitment mode is pinned to the manifest, independent of whatever +# statecfg.ExperimentalParallelCommitment defaults to at runtime. Execution is +# parallel in every shard (dbg.Exec3Parallel defaults true). +export ERIGON_COMMITMENT_PARALLEL="$commitment_parallel" # Strip "-parallel" / "-sequential" suffix for case-arm routing — both variants # share the same fixture path / regex as the parent shard; only the -# ERIGON_EXEC3_PARALLEL env var differs. +# ERIGON_COMMITMENT_PARALLEL env var differs. shard_route="${shard%-parallel}" shard_route="${shard_route%-sequential}" @@ -193,7 +194,7 @@ echo "max-allowed-failures: $max" # code 66: the Go race runtime's "data race detected" signal, emitted even when # the run completes and the JSON parses clean, so it must be checked explicitly. # The grep filter strips any init-time log lines (e.g. dbg.envLookup's -# "[WARN] [env]" message when ERIGON_EXEC3_PARALLEL is set fires before cmd/evm +# "[WARN] [env]" message when ERIGON_COMMITMENT_PARALLEL is set fires before cmd/evm # sets the log handler, and the default log handler writes to stdout) so jq # sees only JSON. raw_file=$(mktemp) From c923faae769ae153dee39ed9791e7d9fee04363d Mon Sep 17 00:00:00 2001 From: mh0lt Date: Fri, 3 Jul 2026 07:41:38 +0000 Subject: [PATCH 3/4] ci: default suffix-less EEST devnet shards to serial commitment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit blocktests-devnet and blocktests-devnet-race-amsterdam carried commitment-parallel: true as a mechanical rename of the old exec3-parallel: true (which forced parallel execution — now the default). Those shards have no -parallel suffix, so per the manifest's suffix-selects-mode rule they must run the default serial commitment; the override forced parallel commitment with no serial counterpart. Drop it so commitment-parallel is set iff the shard name ends in -parallel. --- tools/eest-spec-shards.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/tools/eest-spec-shards.yml b/tools/eest-spec-shards.yml index e3d2e5cd14a..2443a953eb7 100644 --- a/tools/eest-spec-shards.yml +++ b/tools/eest-spec-shards.yml @@ -38,7 +38,6 @@ - shard: blocktests-devnet workers: 12 max-allowed-failures: 0 - commitment-parallel: true - shard: enginextests-stable-sequential workers: 8 max-allowed-failures: 0 @@ -126,7 +125,6 @@ - shard: blocktests-devnet-race-amsterdam workers: 12 max-allowed-failures: 0 - commitment-parallel: true - shard: zkevm-witness-race workers: 8 max-allowed-failures: 0 From 1436a650f18f967020261d8a654a7ad24b5e48a4 Mon Sep 17 00:00:00 2001 From: awskii Date: Tue, 7 Jul 2026 16:54:58 +0700 Subject: [PATCH 4/4] execution/commitment: defer parallel trie selection to EnableParaTrieDB MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With COMMITMENT_PARALLEL set globally, every SharedDomains selected the parallel trie, but only DB-backed consumers (exec, builder, squeeze, backtester) wire the per-worker TrieContextFactory it needs — integrity checks, RPC-created domains, and test harnesses failed with 'ParallelPatriciaHashed.Process requires a TrieContextFactory'. The context now starts on the sequential trie and upgrades to the selected parallel/streaming variant when EnableParaTrieDB provides the DB. SeekCommitment may restore state before the DB is wired, so the upgrade adopts the already-restored trie as the parallel template instead of re-encoding (SetState re-reads a sole-account root through the not-yet-installed context). Touching before the upgrade panics: keys collected on the sequential buffer would be dropped. --- .../commitmentdb/commitment_context.go | 41 ++++++++++++++++++- .../commitment/parallel_patricia_hashed.go | 7 ++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/execution/commitment/commitmentdb/commitment_context.go b/execution/commitment/commitmentdb/commitment_context.go index 1d5e12ad5f4..190db8f54d7 100644 --- a/execution/commitment/commitmentdb/commitment_context.go +++ b/execution/commitment/commitmentdb/commitment_context.go @@ -77,6 +77,11 @@ type SharedDomainsCommitmentContext struct { deferCommitmentUpdates bool // pendingUpdate stores a single deferred branch update to be flushed at the next ComputeCommitment call. pendingUpdate *commitment.PendingCommitmentUpdate + + // pendingVariant holds a parallel/streaming trie selection that waits for + // EnableParaTrieDB: those variants need the DB-backed TrieContextFactory. + pendingVariant commitment.TrieVariant + pendingCfg commitment.TrieConfig } // SetStateReader can be used to set a custom state reader (otherwise the default one is set in SharedDomainsCommitmentContext.trieContext). @@ -92,6 +97,30 @@ func (sdc *SharedDomainsCommitmentContext) StateReader() StateReader { func (sdc *SharedDomainsCommitmentContext) EnableParaTrieDB(db kv.TemporalRoDB) { sdc.paraTrieDB = db + if sdc.pendingVariant == "" { + return + } + if sdc.updates.Size() != 0 { + panic("EnableParaTrieDB after touches: keys collected on the sequential buffer would be dropped") + } + prev, ok := sdc.patriciaTrie.(*commitment.HexPatriciaHashed) + if !ok { + panic("pending trie upgrade expects the sequential trie") + } + cfg := sdc.pendingCfg + cfg.Variant = sdc.pendingVariant + sdc.updates.Close() + sdc.patriciaTrie, sdc.updates = commitment.InitializeTrieAndUpdates(commitment.ModeDirect, sdc.tmpDir, cfg) + if ppht, ok := sdc.patriciaTrie.(*commitment.ParallelPatriciaHashed); ok { + // State may already be restored (SeekCommitment can run before the DB + // is wired); adopting the trie carries it over losslessly. + ppht.AdoptRootTrie(prev) + } + sdc.variant = sdc.pendingVariant + sdc.pendingVariant = "" + if sdc.traceW != nil { + sdc.patriciaTrie.SetTraceWriter(sdc.traceW) + } } // EnableTrieWarmup enables parallel warmup of MDBX page cache during commitment. @@ -199,12 +228,22 @@ func NewSharedDomainsCommitmentContext(sd sd, mode commitment.Mode, tmpDir strin ctx := &SharedDomainsCommitmentContext{ sharedDomains: sd, tmpDir: tmpDir, - variant: variant, + variant: commitment.VariantHexPatriciaTrie, warmupBase: commitment.WarmupConfig{ Enabled: cfg.EnableTrieWarmup, NumWorkers: cfg.WarmupNumWorkersOrDefault(), }, } + // The parallel and streaming tries need a per-worker TrieContextFactory that + // only DB-backed consumers can provide (via EnableParaTrieDB). Start on the + // sequential trie and upgrade when the DB arrives, so context holders that + // never wire one (RPC, integrity, tests) keep working under a global variant + // selection. + if variant == commitment.VariantParallelHexPatricia || variant == commitment.VariantStreamingHexPatricia { + ctx.pendingVariant = variant + cfg.Variant = commitment.VariantHexPatriciaTrie + ctx.pendingCfg = cfg + } ctx.patriciaTrie, ctx.updates = commitment.InitializeTrieAndUpdates(mode, tmpDir, cfg) return ctx } diff --git a/execution/commitment/parallel_patricia_hashed.go b/execution/commitment/parallel_patricia_hashed.go index f9024be00a5..c08cae21073 100644 --- a/execution/commitment/parallel_patricia_hashed.go +++ b/execution/commitment/parallel_patricia_hashed.go @@ -100,6 +100,13 @@ func (p *ParallelPatriciaHashed) TakeDeferredUpdates() []*DeferredBranchUpdate { } // RootTrie exposes the configuration template only; it must not be used as live root state. +// AdoptRootTrie replaces the template trie with one that already carries state +// (e.g. restored before the variant upgrade), the same slot state restore +// targets; the previous trie must no longer be used. +func (p *ParallelPatriciaHashed) AdoptRootTrie(root *HexPatriciaHashed) { + p.template = root +} + func (p *ParallelPatriciaHashed) RootTrie() *HexPatriciaHashed { return p.template }