Skip to content

feat(proposer/challenger): Support TEE fault proof#207

Open
JimmyShi22 wants to merge 31 commits intodevfrom
tz/dev
Open

feat(proposer/challenger): Support TEE fault proof#207
JimmyShi22 wants to merge 31 commits intodevfrom
tz/dev

Conversation

@JimmyShi22
Copy link

@JimmyShi22 JimmyShi22 commented Mar 23, 2026

This pull request adds support for a new TEE (Trusted Execution Environment) based fault proof dispute game type (game type 1960) for XLayer integration. It introduces a new contract suite, TEE Actor logic and Prover client in op-challenger, and a TeeRollup proposal source in op-proposer.

The most important changes are:

op-proposer:

  • Added TeeRollupRpc to CLIConfig with mutual-exclusion validation against other RPC sources; required when game type is 1960. Added guard in initRPCClients to reject WaitNodeSync=true for TEE games (TeeRollup has no L1 derivation). (op-proposer/proposer/config.go, service.go)
  • Added TeeRollupHTTPClient and TeeRollupProposalSource: the HTTP client calls GET /v1/chain/confirmed_block_info with a 16-entry LRU cache; the proposal source supports multi-client failover, conservative lowest-height SyncStatus, and computes rootClaim = keccak256(abi.encode(blockHash, stateHash)). (op-proposer/proposer/source/source_tee_rollup_xlayer.go)
  • Extended Proposal with optional TeeRollupData; ExtraData() encodes 100 bytes (uint256 l2SeqNum + uint32 parentIdx + bytes32 blockHash + bytes32 stateHash), aligned with TeeDisputeGame.sol's abi.encodePacked. (op-proposer/proposer/source/source.go)
  • Added service_tee_xlayer.go implementing initTeeSource, which injects a parentIdxFn closure into TeeRollupProposalSource. The closure calls FindLastGameIndex to reverse-scan the DGF (up to 1000 entries) for the most recent valid parent game, validated against AnchorStateRegistry's respected/blacklisted/retired flags. (op-proposer/proposer/service_tee_xlayer.go, contracts/teedisputegame_xlayer.go)
  • Refactored DisputeGameFactory.gameAtIndex() to branch by game type: types 0/1 use claimData(uint256); type 1960 uses the no-arg claimData() ABI with different return field offsets. (op-proposer/contracts/disputegamefactory.go)

op-challenger:

  • Added TeeGameType = 1960 constant to game_type.go. Added three TEE config fields (TeeProverRpc, TeeProvePollInterval, TeeProveTimeout) and corresponding CLI flags; Check() skips L1Beacon/L2Rpcs/L2EthRpc validation when only TEE game types are enabled. (op-challenger/config/, flags/)
  • Extended NewDisputeGameContract with a TeeGameType branch routing to TeeDisputeGameContractLatest, which wraps on-chain reads (GetMetadata, GetChallengerMetadata, GetProveParams) and transaction construction (ProveTx with simulate-first). GetProveParams traverses parent games to build start/end proof parameters; returns ErrAnchorGameUnprovable for anchor games. (op-challenger/game/fault/contracts/teedisputegame.go)
  • Added ProverClient with a ProveAndWait polling loop: submits prove request (POST /task/), polls for result (GET /task/{taskId}), distinguishes retryable vs. non-retryable error codes, and respects context timeout. (op-challenger/game/tee/prover_client.go)
  • Added Actor with non-blocking background goroutine pattern: Act() checks prove result → starts ProveAndWait goroutine on demand → attempts resolve. Blocks resolve while parent game is in-progress; gives up immediately on anchor games. (op-challenger/game/tee/actor.go)
  • Added register.go to register the TEE game type into the game player registry. Added filteredGameSource in service.go to filter Factory game lists by enabled types, enabling correct monitoring under a shared Factory. (op-challenger/game/tee/register.go, game/service_xlayer.go)

googgoog and others added 30 commits March 18, 2026 14:39
Implement TEE Actor that defends proposals by submitting TEE proofs
when games are challenged. Uses background goroutine + channel pattern
for non-blocking prove with user-configurable poll interval.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Cover contract bindings, actor state machine, prover HTTP client,
and config validation for the TEE game type.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…op and prove timeout

- Update ProverClient to TEE Prover v1 API: paths (/v1/task/), field names
  (startBlkHeight, startBlkStateHash, etc.), status enums (Running/Finished/Failed)
- Add universal error code handling (0=OK, 10000/20001=retryable, 10001=non-retryable, 10004=not found)
- Rewrite ProveAndWait as retry loop: POST → poll → Failed → re-POST, until Finished or ctx timeout
- Add --tee-prove-timeout flag (default 1h) to bound total prove time including retries
- Add proveGivenUp state to Actor: prevents infinite retry after timeout or non-retryable error
- Add DeleteTask method for task cleanup
- Differentiate error logs: timeout vs non-retryable vs generic failure
- Update tests for v1 API, retry scenarios, and proveGivenUp behavior

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…init

Move TEE CLI flags (tee-prover-rpc, tee-prove-poll-interval, tee-prove-timeout)
from a separate init() in flags_xlayer.go into the main init() in flags.go.
The separate init() ran after Flags was already built, so TEE flags were never
registered in the CLI app.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Move TeeGameType from init() in game_type_xlayer.go to the
SupportedGameTypes declaration in game_type.go, avoiding init()
ordering issues.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
TEE DisputeGame contracts for OP Stack. Replaces SP1 ZK proofs with
AWS Nitro Enclave ECDSA signatures for batch state transition verification.

- src/dispute/tee/TeeDisputeGame.sol: IDisputeGame impl (gameType=1960)
- src/dispute/tee/TeeProofVerifier.sol: enclave registration + batch ECDSA verification
- src/dispute/tee/AccessManager.sol: proposer/challenger permissions with fallback timeout
- src/dispute/DisputeGameFactoryRouter.sol: multi-zone router (zoneId→factory)
- interfaces/dispute/: ITeeProofVerifier, IRiscZeroVerifier, IDisputeGameFactoryRouter
- tests: 69 unit tests covering full lifecycle
- scripts: DeployTee.s.sol, RegisterTeeGame.s.sol

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
# Conflicts:
#	.gitignore
#	op-proposer/flags/flags.go
#	op-proposer/proposer/config.go
…ad of returning zero hashes

Anchor-based games (parentIndex=MaxUint32) cannot be proved because the
anchor root is a combined keccak256(blockHash, stateHash) that cannot be
decomposed back into individual hashes. Previously returned zero values
which would always cause StartHashMismatch revert. Now returns
ErrAnchorGameUnprovable so the actor marks proveGivenUp and lets the
game resolve via deadline expiry.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Replace common.Hex2Bytes with hex.DecodeString in decodeProofBytes to properly return errors on malformed hex
- Add single-goroutine safety comment to Act()
- Add metrics tracking to GetBondDistributionMode
- Add GetProveParams test coverage (normal path + anchor game)
- Validate TeeProvePollInterval and TeeProveTimeout > 0 in config

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When multiple challenger nodes share a single GameFactory contract,
each node only processes games matching its configured game types,
avoiding "unsupported game type" errors from unrelated games.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…eator

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@JimmyShi22 JimmyShi22 marked this pull request as ready for review March 25, 2026 07:59
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.

3 participants