Skip to content

feat(tests): add withdrawal finalization e2e test#781

Open
fakedev9999 wants to merge 26 commits into
mainfrom
fakedev9999/withdrawal-test-issue
Open

feat(tests): add withdrawal finalization e2e test#781
fakedev9999 wants to merge 26 commits into
mainfrom
fakedev9999/withdrawal-test-issue

Conversation

@fakedev9999
Copy link
Copy Markdown
Member

@fakedev9999 fakedev9999 commented Jan 27, 2026

Summary

Add comprehensive e2e test TestFaultProof_WithdrawalFinalized that validates the complete withdrawal lifecycle from L2 initiation through L1 finalization via OptimismPortal2.

Test Flow

Phase 1: Deposit ETH from L1 to L2 (fund ETHLockbox)
Phase 2: Initiate withdrawal on L2 (L2ToL1MessagePasser)
Phase 3: Prove withdrawal on L1 (proveWithdrawal)
Phase 4: Wait for game resolution (DEFENDER_WINS)
Phase 5: Wait for finality delay
Phase 6: Finalize withdrawal on L1 (finalizeWithdrawalTransaction)
Phase 7: Verify funds received on L1

Changes

  • Add tests/e2e/faultproof/withdrawal/withdrawal_test.go
  • Add withdrawal test to CI workflow matrix in e2e-sysgo-tests.yml
  • Update optimism submodule with OptimismPortalProxyAddr interface change

Dependencies

⚠️ This PR depends on: succinctlabs/optimism#337

The optimism fork PR adds OptimismPortalProxyAddr() to the L2Deployment interface, which is required for the test to access the OptimismPortal2 proxy address.

Merge order:

  1. Merge feat(op-devstack): add withdrawal test support with OptimismPortalProxyAddr and setRespectedGameType optimism#337 first
  2. Update submodule reference in this PR (if needed)
  3. Merge this PR

Test Plan

  • CI runs the new withdrawal test via ./e2e/faultproof/withdrawal/...
  • Test validates full withdrawal lifecycle through OptimismPortal2
  • Test uses DSL patterns consistent with other e2e tests

Closes #780

Add comprehensive e2e test `TestFaultProof_WithdrawalFinalized` that validates
the complete withdrawal lifecycle from L2 initiation through L1 finalization
via OptimismPortal2.

Test flow:
1. Deposit ETH from L1 to L2 (fund ETHLockbox)
2. Initiate withdrawal on L2 (L2ToL1MessagePasser)
3. Prove withdrawal on L1 (proveWithdrawal)
4. Wait for game resolution (DEFENDER_WINS)
5. Wait for finality delay
6. Finalize withdrawal on L1 (finalizeWithdrawalTransaction)
7. Verify funds received on L1

Changes:
- Add tests/e2e/faultproof/withdrawal/withdrawal_test.go
- Add withdrawal test to CI workflow matrix
- Update optimism submodule with OptimismPortalProxyAddr interface change

Closes #780
Update submodule to include the fix that sets respectedGameType=42
after OPSuccinct FDG deployment. This ensures the StandardBridge DSL
can find games of the correct type during withdrawal proving.
Update submodule to include fix for setRespectedGameType call:
- Uses SuperchainConfigGuardianKey instead of L1ProxyAdminOwnerRole
- Calls AnchorStateRegistry instead of OptimismPortal2
…ctedGameType

Updates the optimism fork submodule reference to include the fix for
using L1ProxyAdminOwnerRole as the guardian key instead of
SuperchainConfigGuardianKey. The OPSuccinct FDG deployment creates
a MockSystemConfig with the deployer as guardian, so we must use
the same key that deployed the contracts.
Updates the optimism fork submodule to include the fix that sets
respectedGameType(42) on BOTH AnchorStateRegistries:
1. OPSuccinct AnchorStateRegistry (uses L1ProxyAdminOwnerRole)
2. Standard devstack AnchorStateRegistry (uses SuperchainConfigGuardianKey)

This ensures the StandardBridge DSL can find games of type 42 when
using the standard portal from the rollup config.
Add logging to help diagnose why StandardBridge gets wrong DGF address:
- Log DGF address from L2Deployment
- Wait for game creation via DgfClient before using StandardBridge
- Log respectedGameType and DGF address from StandardBridge
Compare DGF addresses from two paths to identify mismatch:
- sys.L2Chain.Escape().Deployment().DisputeGameFactoryProxyAddr()
- sys.L2Chain.DisputeGameFactoryProxyAddr()
The Go test infrastructure in deployer_succinct.go uses parseNamedAddresses()
to extract deployed contract addresses from forge script output. This function
expects lines in the format: "<name>: address 0x..."

The existing console.log statements used different formats that didn't match
the regex pattern, causing the addresses to not be parsed. This resulted in
GameImpls(42) returning address(0) because the DGF address wasn't properly
captured and used.

Add console.log statements in the expected format for:
- factoryProxy
- anchorStateRegistry
- sp1Verifier
The test DSL in bridge.go uses the standard FaultDisputeGame binding
which calls maxClockDuration(). However, OPSuccinctFaultDisputeGame
only had maxChallengeDuration().

Add maxClockDuration() as a compatibility alias that returns
MAX_CHALLENGE_DURATION, matching the standard FaultDisputeGame
interface expected by the test infrastructure.
The withdrawal test waits for a game covering the withdrawal block. With
ProposalIntervalInBlocks=20, the proposer creates games every ~40s.
Since the L2 chain can advance significantly during deposit/withdrawal
operations, the 90s timeout in bridge.go isn't enough for the proposer
to create a game covering block 315.

Decrease ProposalIntervalInBlocks to 5 so games are created every ~10s,
allowing the proposer to keep up with the L2 chain advancement.
The proposer creates games every ~30-40 seconds (not based on
ProposalIntervalInBlocks as expected). The chain advances rapidly during
deposit/withdrawal operations (~200+ blocks), so by the time withdrawal
is initiated, no game covers that block yet.

Wait for 5 games upfront (with 4 minute timeout) instead of just 1.
This ensures:
1. The proposer is actively creating games
2. Games cover higher block numbers
3. The proposer continues creating games during deposit/withdrawal

This gives enough coverage for the 90-second timeout in bridge.go's
game-finding logic to succeed.
Enable FastFinalityMode in the withdrawal test to allow the proposer
to create games for recent blocks (unsafe head) rather than only
finalized blocks. This is critical because the L2 chain advances
rapidly during deposit/withdrawal operations.

Also reorder the test to do deposit/withdrawal before waiting for
games, so the withdrawal block number is captured early.
With a small ProposalIntervalInBlocks (5), games cover blocks 6, 11, 16...
requiring ~56 games to cover block 279. At ~36s per game, this takes 33 min!

With ProposalIntervalInBlocks=50, games cover blocks 1, 51, 101, 151...
so only ~6 games are needed. This reduces wait time from 33 min to ~5 min.

Also increase game wait count to 8 and timeout to 6 minutes to ensure
sufficient coverage of the withdrawal block.
The withdrawal block can be 500-700 depending on L2 chain state at
withdrawal time. Previous count of 8 games only covered up to block
~400, causing prove transaction timeout. Increase to 15 games
(covering up to ~750 blocks) and 10-minute timeout.
Games are created every ~50-55 seconds, so 15 games requires ~13
minutes. Increase timeout from 10 to 15 minutes to ensure sufficient
time for all games to be created.
The withdrawal test was failing with "out-of-bounds access of an array"
because OptimismPortal2 references the STANDARD DisputeGameFactory,
but games were being created in a SEPARATE OPSuccinct DGF.

Root cause:
- OPSuccinct deployment was creating a NEW DGF with game type 42
- OptimismPortal2 internally references the STANDARD DGF
- When proveWithdrawalTransaction looked up game index N from standard DGF,
  it was out of bounds because games were in OPSuccinct DGF

Fix:
- Add existingDisputeGameFactoryProxy config field to FDGConfig
- Deployment script registers game type 42 in the STANDARD DGF when provided
- Go deployer passes standard DGF address and doesn't overwrite the reference

This ensures all games are created in the same DGF that OptimismPortal2
uses, fixing the DGF mismatch that caused the withdrawal test failure.

Files changed:
- fault-proof/src/config.rs: Add existing_dispute_game_factory_proxy field
- scripts/utils/bin/fetch_fault_dispute_game_config.rs: Read new env var
- contracts/test/helpers/JSONDecoder.sol: Add existingDisputeGameFactoryProxy
- contracts/script/fp/DeployOPSuccinctFDG.s.sol: Use existing DGF when provided
- tests/optimism: Go deployer changes (submodule)
…hdrawal test

The withdrawal test was failing with OptimismPortal_ImproperDisputeGame error
because games were referencing a different AnchorStateRegistry than the one
OptimismPortal2 uses for isGameProper() checks.

The isGameProper() function checks:
  return address(factoryRegisteredGame) == address(_game) && asr == address(this);

Where 'asr' is the game's AnchorStateRegistry and 'this' is the ASR that
OptimismPortal2 is configured with. If they differ, the game is considered improper.

Changes:
- Add existingAnchorStateRegistry to FaultDisputeGameConfig (Rust and Solidity)
- Modify deployment script to optionally use existing ASR instead of deploying new
- Read standard ASR from OptimismPortal2 and pass to deployment (Go deployer)
- Update submodule to include ASR fix in deployer_succinct.go
…thdrawal test

The withdrawal test uses sys.AdvanceTime() to simulate time passing for
game resolution and finality delays. This requires time travel to be
enabled in the test system.

Changes:
- Add enableTimeTravel flag to faultProofSystemOptions
- Add WithFPTimeTravel() function to enable time travel
- Modify newSystemCore and newSystemWithProposer to accept extra options
- Update withdrawal test to use WithFPTimeTravel()

This fixes the "Attempting to advance time when time travel is not enabled"
error in the withdrawal test.
- Add existing_anchor_state_registry and existing_dispute_game_factory_proxy
  fields to test_config() in env.rs
- These fields were added to FaultDisputeGameConfig for e2e test support
  but not to the integration test configuration
- Integration tests deploy their own contracts, so they use Address::ZERO
- Fix cargo fmt formatting in fetch_fault_dispute_game_config.rs
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jan 27, 2026

Metric Value
Batch Start 13,326,148
Batch End 13,326,153
Witness Generation (seconds) 0
Execution Duration (seconds) 17
Total Instruction Count 396,367,622
Oracle Verify Cycles 38,099,600
Derivation Cycles 286,738,593
Block Execution Cycles 7,070,724
Blob Verification Cycles 23,426,261
Total SP1 Gas 608,226,348
Number of Blocks 5
Number of Transactions 5
Ethereum Gas Used 242,338
Cycles per Block 79,273,524
Cycles per Transaction 79,273,524
Transactions per Block 1
Gas Used per Block 48,467
Gas Used per Transaction 48,467
BN Pair Cycles 0
BN Add Cycles 0
BN Mul Cycles 0
KZG Eval Cycles 0
EC Recover Cycles 0
P256 Verify Cycles 0

- Defense test: 60s → 180s for proof submission after challenge
- LongRunningFPProposerConfig: add 300s MaxProveDuration for mock proving

These timeouts were too tight for CI runners, causing flaky failures.
Resolve merge conflicts in:
- contracts/script/fp/DeployOPSuccinctFDG.s.sol: Combine existingAnchorStateRegistry
  early return with systemConfigAddress support from main
- scripts/utils/bin/fetch_fault_dispute_game_config.rs: Add both existing ASR/DGF
  env vars and systemConfigAddress support from main
…ests

The defense test was failing because with MaxConcurrentRangeProofs=1 and
FastFinalityMode=true, the proposer would get stuck proving Game 1 while
Game 0's defense deadline passed. The logs showed:
- Game 0 challenged, proposer starts defense
- Game 1 created, proposer starts proving (at 1/1 capacity)
- Game 0 defense deadline passes (~37 min before proposer tries to defend)
- Error: "Game deadline passed, cannot prove"

By increasing MaxConcurrentRangeProofs to 2, the proposer can defend
challenged games in parallel with fast finality proving.

Applied the same fix to LongRunningFastFinalityFPProposerConfig.
The fast finality proving code was iterating over unproven games using
HashMap::values() which provides non-deterministic iteration order. This
could cause newer games to be proven before older ones.

This fix sorts the candidate games by their index before processing,
ensuring that Game 0 (the oldest) is always proven before Game 1, Game 2,
etc. This fixes the "fast finality did not prove first game" test failure.

Root cause: HashMap iteration order is not stable, so older games could
be skipped in favor of newer ones during game proving selection.
The defense test was failing because FastFinalityProvingLimit=1 (default)
means only one game can be actively proving at a time. When Game 1 started
fast finality proving, Game 0's defense could not proceed because the
single slot was occupied.

By increasing FastFinalityProvingLimit to 2, both Game 1 (fast finality)
and Game 0 (defense) can be proven concurrently.

The logs showed:
- "Resumed proving for 1 existing game(s), now at 1/1 capacity"
- "Spawning defense for challenged game...game_index=0"
- "Game deadline passed, cannot prove"

This fix, combined with the previous MaxConcurrentRangeProofs=2 and the
sorting fix, should allow the defense test to pass.
The defense and long-running tests passed on main with their original
configs. Reverting all "fix" changes to isolate the withdrawal test:

- defense_test.go: restore MaxConcurrentRangeProofs=1, MaxProveDuration=60
- faultproof.go: remove MaxProveDuration from LongRunningFPProposerConfig,
  remove MaxConcurrentRangeProofs from LongRunningFastFinalityFPProposerConfig
- proposer.rs: remove sorting by game index (HashMap iteration order)

These tests passed when merged in PR #764. The withdrawal test PR should
not need to modify their configs.
Update tests/optimism submodule to include PR #337 which adds:
- OptimismPortalProxyAddr() in L2Deployment interface
- setStandardPortalRespectedGameType() for withdrawal test support
- EXISTING_DISPUTE_GAME_FACTORY_PROXY and EXISTING_ANCHOR_STATE_REGISTRY
  env vars to use standard DGF/ASR for OPSuccinct games

This ensures withdrawal tests work correctly with OptimismPortal2 by:
1. Registering game type 42 in the standard DGF
2. Using the standard ASR so isGameProper() checks pass
3. Setting respectedGameType to 42 so StandardBridge DSL finds games
fakedev9999 added a commit that referenced this pull request Feb 26, 2026
The faultproof bootstrap e2e test fails because the Forge deployment
script (DeployOPSuccinctFDG.s.sol) always deploys a new
DisputeGameFactory, while OptimismPortal2 is configured with the
standard DGF. This means game type 42 is registered in a different DGF
than the one the proposer reads from.

Cherry-pick the fix from PR #781:
- Solidity: conditionally reuse existing DGF/ASR when config addresses
  are non-zero, add maxClockDuration() compatibility alias
- Rust: add existing_anchor_state_registry and
  existing_dispute_game_factory_proxy fields to FaultDisputeGameConfig
- Go: propagate extraOpts through newSystemWithProposer/newSystemCore,
  add WithFPTimeTravel option, simplify NewValiditySystem
fakedev9999 added a commit that referenced this pull request Apr 3, 2026
* feat(altda): add AltDA DataAvailabilityProvider for zkVM proof program

Add client-side AltDA support to op-succinct, enabling the derivation
pipeline to resolve off-chain Keccak256 commitments into batch data
inside the SP1 zkVM. Follows the Celestia/EigenDA DA backend pattern.

New crate: op-succinct-altda-client-utils
- AltDADataSource: wraps EthereumDataSource, detects DerivationVersion1
  (0x01) prefix, sends hints to host, reads resolved data from preimage
  oracle. Keccak256 integrity verified automatically by PreimageStore.
- AltDAWitnessExecutor: WitnessExecutor impl for AltDA pipeline
- AltDAHintType: custom hint type ("altda-commitment")

New ELF program: programs/range/altda
- Uses DefaultWitnessData (same as Ethereum/Celestia)

Host-side hint handler (Phase 3) is required to complete the integration.

* feat(altda): add host-side hint handler for AltDA proof generation

Add the host-side components that receive "altda-commitment" hints from
the zkVM client, fetch batch data from the DA server, and store resolved
data in the preimage oracle for the client to consume.

New crate: op-succinct-altda-host-utils
- AltDAExtendedHintType: wraps kona HintType + AltDACommitment variant
- AltDAChainHost: wraps SingleChainHost + DA server URL config
- AltDAHintHandler: routes standard hints to kona, fetches AltDA
  commitments via HTTP GET from the DA server
- AltDAOPSuccinctHost: OPSuccinctHost impl for AltDA chains
- AltDAWitnessGenerator: witness generation using DefaultWitnessData

Wire up workspace and proof-utils with "altda" feature flag.

* feat(altda): add AltDA e2e test and wire up validity proposer

- Add `altda` feature flag to validity and fault-proof Cargo.toml
- Add `WithAltDA()` helper to test presets (starts in-memory DA server,
  configures batcher and op-node for AltDA mode)
- Extend `NewValiditySystem()` to accept extra stack options for
  composing AltDA with validity proposer setup
- Create AltDA e2e test that verifies proof generation with off-chain
  batch data (DA server + Keccak256 commitments on L1)
- Add `test-e2e-sysgo-altda` justfile target for running AltDA tests
- Update optimism submodule to include ALTDA_SERVER_URL env export

* build: add AltDA range ELF binary

Built with cargo-prove prove build (SP1 toolchain v6.0.1, rustc 1.93.0-dev)
on gpu-06. This ELF is loaded by the validity proposer when running with
the `altda` feature to generate range proofs for off-chain batch data.

* ci: add AltDA e2e sysgo test job

Adds a dedicated CI job that builds the validity binary with
--features altda and runs tests/e2e/validity/altda/... via the
test-e2e-sysgo-altda justfile target.

* style: run cargo fmt on AltDA crates

* build: rebuild AltDA range ELF with docker for determinism

Rebuilt with --docker --tag v6.0.1 to match CI's deterministic
build environment. The previous ELF was built locally without
docker, causing a byte-level mismatch in the ELF CI check.

* fix(faultproof): reuse existing DGF/ASR in Forge deploy script

The faultproof bootstrap e2e test fails because the Forge deployment
script (DeployOPSuccinctFDG.s.sol) always deploys a new
DisputeGameFactory, while OptimismPortal2 is configured with the
standard DGF. This means game type 42 is registered in a different DGF
than the one the proposer reads from.

Cherry-pick the fix from PR #781:
- Solidity: conditionally reuse existing DGF/ASR when config addresses
  are non-zero, add maxClockDuration() compatibility alias
- Rust: add existing_anchor_state_registry and
  existing_dispute_game_factory_proxy fields to FaultDisputeGameConfig
- Go: propagate extraOpts through newSystemWithProposer/newSystemCore,
  add WithFPTimeTravel option, simplify NewValiditySystem

* build: rebuild AltDA range ELF with fresh SP1 v6.0.1 docker toolchain

* fix(altda): pass Cargo features to deploy-oracle for correct vkey commitment

The AltDA e2e test was failing because deploy-oracle compiled
fetch-l2oo-config without --features altda, producing a vkey commitment
from the standard range ELF. The proposer binary (compiled with
--features altda) uses the AltDA range ELF, which has a different vkey.

Thread Features through ValidityConfig → L2OOConfigs → execDeployOracle
so that `just deploy-oracle <env> altda` is invoked, producing a
matching vkey commitment.

* fix(altda): switch DA server to Keccak256 commitment mode

Update submodule pointer for the da_server.go change that switches
from Generic to Keccak256 commitments, matching what the Rust AltDA
data source supports.

* build: add Docker packaging for AltDA validity and fault-proof proposers

Add Dockerfile and docker-compose for both validity and fault-proof
modes, following the established patterns from Celestia and EigenDA.

- validity/Dockerfile.altda: builds with --features altda
- docker-compose-altda.yml: postgres + proposer service
- fault-proof/Dockerfile.proposer.altda: builds with --features altda
- fault-proof/docker-compose-altda.yml: proposer + challenger + monitoring

AltDA is the simplest DA variant — no external indexer (unlike Celestia)
and no SRS download (unlike EigenDA). The only DA-specific env var is
ALTDA_SERVER_URL, provided by the user's .env file.

* fix: remove feature gate from AltDA ELF declaration

Make ALTDA_RANGE_ELF_EMBEDDED unconditional, matching the Celestia and
EigenDA pattern. Unconditional include_bytes! ensures the ELF CI
workflow catches missing or corrupt ELF files at compile time regardless
of feature flags.

* fix(altda): add HTTP timeout, error on unsupported commitments, add spec refs

- Add 30s timeout to DA server HTTP client to prevent indefinite hangs
- Return errors instead of silently succeeding for Generic/unknown
  commitment types in the hint handler
- Add OP Stack spec references alongside Go source refs in constant docs

* fix: bump SP1 to 6.0.2 and add Go 1.24 in AltDA Dockerfiles

Align AltDA Dockerfiles and justfile with the SP1 6.0.2 bump from main.
Also adds Go 1.24 install (required for sp1-recursion-gnark-ffi).

* chore: bump altda-range-elf-embedded

* fix(altda): use ClusterTimeout when SP1_PROVER=cluster

The 20-minute ShortTimeout is insufficient for real cluster proving.
Use ClusterTimeout (180 min) when cluster mode is detected.

Depends on op-succinct#837 for UseClusterProver() and ClusterTimeout().

* docs: address review feedback on FDG config field naming

Reframe existing_anchor_state_registry and existing_dispute_game_factory_proxy
doc comments as general-purpose deployment options rather than e2e-specific.
Clarify EXISTING_* env var naming rationale to distinguish from runtime vars.

* fix(altda): remove non-existent UseClusterProver/ClusterTimeout references

Use ShortTimeout() directly, matching the pattern in other sysgo tests.

* chore: bump optimism submodule to include AltDA sysgo support

Points to validium-support branch after merging optimism#338.
fakedev9999 added a commit that referenced this pull request May 12, 2026
* feat(altda): add AltDA support (Validium) (#818)

* feat(altda): add AltDA DataAvailabilityProvider for zkVM proof program

Add client-side AltDA support to op-succinct, enabling the derivation
pipeline to resolve off-chain Keccak256 commitments into batch data
inside the SP1 zkVM. Follows the Celestia/EigenDA DA backend pattern.

New crate: op-succinct-altda-client-utils
- AltDADataSource: wraps EthereumDataSource, detects DerivationVersion1
  (0x01) prefix, sends hints to host, reads resolved data from preimage
  oracle. Keccak256 integrity verified automatically by PreimageStore.
- AltDAWitnessExecutor: WitnessExecutor impl for AltDA pipeline
- AltDAHintType: custom hint type ("altda-commitment")

New ELF program: programs/range/altda
- Uses DefaultWitnessData (same as Ethereum/Celestia)

Host-side hint handler (Phase 3) is required to complete the integration.

* feat(altda): add host-side hint handler for AltDA proof generation

Add the host-side components that receive "altda-commitment" hints from
the zkVM client, fetch batch data from the DA server, and store resolved
data in the preimage oracle for the client to consume.

New crate: op-succinct-altda-host-utils
- AltDAExtendedHintType: wraps kona HintType + AltDACommitment variant
- AltDAChainHost: wraps SingleChainHost + DA server URL config
- AltDAHintHandler: routes standard hints to kona, fetches AltDA
  commitments via HTTP GET from the DA server
- AltDAOPSuccinctHost: OPSuccinctHost impl for AltDA chains
- AltDAWitnessGenerator: witness generation using DefaultWitnessData

Wire up workspace and proof-utils with "altda" feature flag.

* feat(altda): add AltDA e2e test and wire up validity proposer

- Add `altda` feature flag to validity and fault-proof Cargo.toml
- Add `WithAltDA()` helper to test presets (starts in-memory DA server,
  configures batcher and op-node for AltDA mode)
- Extend `NewValiditySystem()` to accept extra stack options for
  composing AltDA with validity proposer setup
- Create AltDA e2e test that verifies proof generation with off-chain
  batch data (DA server + Keccak256 commitments on L1)
- Add `test-e2e-sysgo-altda` justfile target for running AltDA tests
- Update optimism submodule to include ALTDA_SERVER_URL env export

* build: add AltDA range ELF binary

Built with cargo-prove prove build (SP1 toolchain v6.0.1, rustc 1.93.0-dev)
on gpu-06. This ELF is loaded by the validity proposer when running with
the `altda` feature to generate range proofs for off-chain batch data.

* ci: add AltDA e2e sysgo test job

Adds a dedicated CI job that builds the validity binary with
--features altda and runs tests/e2e/validity/altda/... via the
test-e2e-sysgo-altda justfile target.

* style: run cargo fmt on AltDA crates

* build: rebuild AltDA range ELF with docker for determinism

Rebuilt with --docker --tag v6.0.1 to match CI's deterministic
build environment. The previous ELF was built locally without
docker, causing a byte-level mismatch in the ELF CI check.

* fix(faultproof): reuse existing DGF/ASR in Forge deploy script

The faultproof bootstrap e2e test fails because the Forge deployment
script (DeployOPSuccinctFDG.s.sol) always deploys a new
DisputeGameFactory, while OptimismPortal2 is configured with the
standard DGF. This means game type 42 is registered in a different DGF
than the one the proposer reads from.

Cherry-pick the fix from PR #781:
- Solidity: conditionally reuse existing DGF/ASR when config addresses
  are non-zero, add maxClockDuration() compatibility alias
- Rust: add existing_anchor_state_registry and
  existing_dispute_game_factory_proxy fields to FaultDisputeGameConfig
- Go: propagate extraOpts through newSystemWithProposer/newSystemCore,
  add WithFPTimeTravel option, simplify NewValiditySystem

* build: rebuild AltDA range ELF with fresh SP1 v6.0.1 docker toolchain

* fix(altda): pass Cargo features to deploy-oracle for correct vkey commitment

The AltDA e2e test was failing because deploy-oracle compiled
fetch-l2oo-config without --features altda, producing a vkey commitment
from the standard range ELF. The proposer binary (compiled with
--features altda) uses the AltDA range ELF, which has a different vkey.

Thread Features through ValidityConfig → L2OOConfigs → execDeployOracle
so that `just deploy-oracle <env> altda` is invoked, producing a
matching vkey commitment.

* fix(altda): switch DA server to Keccak256 commitment mode

Update submodule pointer for the da_server.go change that switches
from Generic to Keccak256 commitments, matching what the Rust AltDA
data source supports.

* build: add Docker packaging for AltDA validity and fault-proof proposers

Add Dockerfile and docker-compose for both validity and fault-proof
modes, following the established patterns from Celestia and EigenDA.

- validity/Dockerfile.altda: builds with --features altda
- docker-compose-altda.yml: postgres + proposer service
- fault-proof/Dockerfile.proposer.altda: builds with --features altda
- fault-proof/docker-compose-altda.yml: proposer + challenger + monitoring

AltDA is the simplest DA variant — no external indexer (unlike Celestia)
and no SRS download (unlike EigenDA). The only DA-specific env var is
ALTDA_SERVER_URL, provided by the user's .env file.

* fix: remove feature gate from AltDA ELF declaration

Make ALTDA_RANGE_ELF_EMBEDDED unconditional, matching the Celestia and
EigenDA pattern. Unconditional include_bytes! ensures the ELF CI
workflow catches missing or corrupt ELF files at compile time regardless
of feature flags.

* fix(altda): add HTTP timeout, error on unsupported commitments, add spec refs

- Add 30s timeout to DA server HTTP client to prevent indefinite hangs
- Return errors instead of silently succeeding for Generic/unknown
  commitment types in the hint handler
- Add OP Stack spec references alongside Go source refs in constant docs

* fix: bump SP1 to 6.0.2 and add Go 1.24 in AltDA Dockerfiles

Align AltDA Dockerfiles and justfile with the SP1 6.0.2 bump from main.
Also adds Go 1.24 install (required for sp1-recursion-gnark-ffi).

* chore: bump altda-range-elf-embedded

* fix(altda): use ClusterTimeout when SP1_PROVER=cluster

The 20-minute ShortTimeout is insufficient for real cluster proving.
Use ClusterTimeout (180 min) when cluster mode is detected.

Depends on op-succinct#837 for UseClusterProver() and ClusterTimeout().

* docs: address review feedback on FDG config field naming

Reframe existing_anchor_state_registry and existing_dispute_game_factory_proxy
doc comments as general-purpose deployment options rather than e2e-specific.
Clarify EXISTING_* env var naming rationale to distinguish from runtime vars.

* fix(altda): remove non-existent UseClusterProver/ClusterTimeout references

Use ShortTimeout() directly, matching the pattern in other sysgo tests.

* chore: bump optimism submodule to include AltDA sysgo support

Points to validium-support branch after merging optimism#338.

* fix: register altda feature on op-succinct-scripts crate (#904)

* fix(altda): align with post-rebase main API and SP1 v6.1.0

- Migrate AltDAOPSuccinctHost from get_finalized_l2_block_number to
  get_max_provable_l2_block_number with L1 selection branching, and
  extend calculate_safe_l1_head to honor non-default L1 selection
  (mirrors SingleChainOPSuccinctHost; needed after #883 landed on main).
- Bump SP1 tag v6.0.2 -> v6.1.0 in justfile altda recipe and altda
  Dockerfiles for validity and fault-proof.
- Refresh Cargo.lock for workspace version 4.3.1.

ELF rebuild on gpu-06 follows in the next commit.

* chore: rebuild altda-range-elf-embedded with SP1 v6.1.0 toolchain
fakedev9999 added a commit that referenced this pull request May 14, 2026
…) (#912)

* feat(altda): merge AltDA (Validium) support into main (#908)

* feat(altda): add AltDA support (Validium) (#818)

* feat(altda): add AltDA DataAvailabilityProvider for zkVM proof program

Add client-side AltDA support to op-succinct, enabling the derivation
pipeline to resolve off-chain Keccak256 commitments into batch data
inside the SP1 zkVM. Follows the Celestia/EigenDA DA backend pattern.

New crate: op-succinct-altda-client-utils
- AltDADataSource: wraps EthereumDataSource, detects DerivationVersion1
  (0x01) prefix, sends hints to host, reads resolved data from preimage
  oracle. Keccak256 integrity verified automatically by PreimageStore.
- AltDAWitnessExecutor: WitnessExecutor impl for AltDA pipeline
- AltDAHintType: custom hint type ("altda-commitment")

New ELF program: programs/range/altda
- Uses DefaultWitnessData (same as Ethereum/Celestia)

Host-side hint handler (Phase 3) is required to complete the integration.

* feat(altda): add host-side hint handler for AltDA proof generation

Add the host-side components that receive "altda-commitment" hints from
the zkVM client, fetch batch data from the DA server, and store resolved
data in the preimage oracle for the client to consume.

New crate: op-succinct-altda-host-utils
- AltDAExtendedHintType: wraps kona HintType + AltDACommitment variant
- AltDAChainHost: wraps SingleChainHost + DA server URL config
- AltDAHintHandler: routes standard hints to kona, fetches AltDA
  commitments via HTTP GET from the DA server
- AltDAOPSuccinctHost: OPSuccinctHost impl for AltDA chains
- AltDAWitnessGenerator: witness generation using DefaultWitnessData

Wire up workspace and proof-utils with "altda" feature flag.

* feat(altda): add AltDA e2e test and wire up validity proposer

- Add `altda` feature flag to validity and fault-proof Cargo.toml
- Add `WithAltDA()` helper to test presets (starts in-memory DA server,
  configures batcher and op-node for AltDA mode)
- Extend `NewValiditySystem()` to accept extra stack options for
  composing AltDA with validity proposer setup
- Create AltDA e2e test that verifies proof generation with off-chain
  batch data (DA server + Keccak256 commitments on L1)
- Add `test-e2e-sysgo-altda` justfile target for running AltDA tests
- Update optimism submodule to include ALTDA_SERVER_URL env export

* build: add AltDA range ELF binary

Built with cargo-prove prove build (SP1 toolchain v6.0.1, rustc 1.93.0-dev)
on gpu-06. This ELF is loaded by the validity proposer when running with
the `altda` feature to generate range proofs for off-chain batch data.

* ci: add AltDA e2e sysgo test job

Adds a dedicated CI job that builds the validity binary with
--features altda and runs tests/e2e/validity/altda/... via the
test-e2e-sysgo-altda justfile target.

* style: run cargo fmt on AltDA crates

* build: rebuild AltDA range ELF with docker for determinism

Rebuilt with --docker --tag v6.0.1 to match CI's deterministic
build environment. The previous ELF was built locally without
docker, causing a byte-level mismatch in the ELF CI check.

* fix(faultproof): reuse existing DGF/ASR in Forge deploy script

The faultproof bootstrap e2e test fails because the Forge deployment
script (DeployOPSuccinctFDG.s.sol) always deploys a new
DisputeGameFactory, while OptimismPortal2 is configured with the
standard DGF. This means game type 42 is registered in a different DGF
than the one the proposer reads from.

Cherry-pick the fix from PR #781:
- Solidity: conditionally reuse existing DGF/ASR when config addresses
  are non-zero, add maxClockDuration() compatibility alias
- Rust: add existing_anchor_state_registry and
  existing_dispute_game_factory_proxy fields to FaultDisputeGameConfig
- Go: propagate extraOpts through newSystemWithProposer/newSystemCore,
  add WithFPTimeTravel option, simplify NewValiditySystem

* build: rebuild AltDA range ELF with fresh SP1 v6.0.1 docker toolchain

* fix(altda): pass Cargo features to deploy-oracle for correct vkey commitment

The AltDA e2e test was failing because deploy-oracle compiled
fetch-l2oo-config without --features altda, producing a vkey commitment
from the standard range ELF. The proposer binary (compiled with
--features altda) uses the AltDA range ELF, which has a different vkey.

Thread Features through ValidityConfig → L2OOConfigs → execDeployOracle
so that `just deploy-oracle <env> altda` is invoked, producing a
matching vkey commitment.

* fix(altda): switch DA server to Keccak256 commitment mode

Update submodule pointer for the da_server.go change that switches
from Generic to Keccak256 commitments, matching what the Rust AltDA
data source supports.

* build: add Docker packaging for AltDA validity and fault-proof proposers

Add Dockerfile and docker-compose for both validity and fault-proof
modes, following the established patterns from Celestia and EigenDA.

- validity/Dockerfile.altda: builds with --features altda
- docker-compose-altda.yml: postgres + proposer service
- fault-proof/Dockerfile.proposer.altda: builds with --features altda
- fault-proof/docker-compose-altda.yml: proposer + challenger + monitoring

AltDA is the simplest DA variant — no external indexer (unlike Celestia)
and no SRS download (unlike EigenDA). The only DA-specific env var is
ALTDA_SERVER_URL, provided by the user's .env file.

* fix: remove feature gate from AltDA ELF declaration

Make ALTDA_RANGE_ELF_EMBEDDED unconditional, matching the Celestia and
EigenDA pattern. Unconditional include_bytes! ensures the ELF CI
workflow catches missing or corrupt ELF files at compile time regardless
of feature flags.

* fix(altda): add HTTP timeout, error on unsupported commitments, add spec refs

- Add 30s timeout to DA server HTTP client to prevent indefinite hangs
- Return errors instead of silently succeeding for Generic/unknown
  commitment types in the hint handler
- Add OP Stack spec references alongside Go source refs in constant docs

* fix: bump SP1 to 6.0.2 and add Go 1.24 in AltDA Dockerfiles

Align AltDA Dockerfiles and justfile with the SP1 6.0.2 bump from main.
Also adds Go 1.24 install (required for sp1-recursion-gnark-ffi).

* chore: bump altda-range-elf-embedded

* fix(altda): use ClusterTimeout when SP1_PROVER=cluster

The 20-minute ShortTimeout is insufficient for real cluster proving.
Use ClusterTimeout (180 min) when cluster mode is detected.

Depends on op-succinct#837 for UseClusterProver() and ClusterTimeout().

* docs: address review feedback on FDG config field naming

Reframe existing_anchor_state_registry and existing_dispute_game_factory_proxy
doc comments as general-purpose deployment options rather than e2e-specific.
Clarify EXISTING_* env var naming rationale to distinguish from runtime vars.

* fix(altda): remove non-existent UseClusterProver/ClusterTimeout references

Use ShortTimeout() directly, matching the pattern in other sysgo tests.

* chore: bump optimism submodule to include AltDA sysgo support

Points to validium-support branch after merging optimism#338.

* fix: register altda feature on op-succinct-scripts crate (#904)

* fix(altda): align with post-rebase main API and SP1 v6.1.0

- Migrate AltDAOPSuccinctHost from get_finalized_l2_block_number to
  get_max_provable_l2_block_number with L1 selection branching, and
  extend calculate_safe_l1_head to honor non-default L1 selection
  (mirrors SingleChainOPSuccinctHost; needed after #883 landed on main).
- Bump SP1 tag v6.0.2 -> v6.1.0 in justfile altda recipe and altda
  Dockerfiles for validity and fault-proof.
- Refresh Cargo.lock for workspace version 4.3.1.

ELF rebuild on gpu-06 follows in the next commit.

* chore: rebuild altda-range-elf-embedded with SP1 v6.1.0 toolchain

* chore(backport): align Cargo.lock altda crate versions to v3.8.1

* chore: rebuild altda-range-elf-embedded with SP1 v6.1.0 from v3.x source
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add test_withdrawal_finalized: Full lifecycle e2e test for withdrawal finalization through OptimismPortal2

1 participant