Skip to content

feat(tokamak): JIT-compiled EVM with proven execution infrastructure#2

Open
jason-h23 wants to merge 106 commits intomainfrom
feat/tokamak-proven-execution
Open

feat(tokamak): JIT-compiled EVM with proven execution infrastructure#2
jason-h23 wants to merge 106 commits intomainfrom
feat/tokamak-proven-execution

Conversation

@jason-h23
Copy link
Copy Markdown

@jason-h23 jason-h23 commented Feb 23, 2026

Summary

Complete Tokamak JIT compilation infrastructure for the ethrex Ethereum client. This branch implements a tiered JIT execution system using revmc/LLVM 21, adding ~11K lines of Rust across 4 new crates and LEVM integration modules.

Key Features

  • JIT Compiler (tokamak-jit): revmc/LLVM 21 backend with tiered compilation (counter threshold → compile → execute), multi-fork support, arena-based memory lifecycle (G-1), LRU cache eviction (G-6), parallel compilation pool (G-5)
  • Dual-Execution Validation: State-swap mechanism validates JIT output against interpreter for all bytecodes including CALL/CREATE (G-3)
  • Constant Folding Optimizer: 22-opcode constant folding (PUSH+PUSH+OP → single PUSH), including signed arithmetic and unary patterns (D-3, G-7)
  • JIT-to-JIT Direct Dispatch: Child CALL bytecodes execute directly via JIT cache lookup, bypassing full suspend/resume (G-4)
  • Precompile Fast Dispatch: Metric tracking for precompile calls from JIT-compiled code (G-8)
  • Time-Travel Debugger (tokamak-debugger): Per-opcode replay engine with GDB-style CLI and debug_timeTravel JSON-RPC endpoint
  • Benchmark Infrastructure (tokamak-bench): 12 scenarios, JIT speedup regression detection CI, cross-client comparison (vs Geth/Reth)
  • Public Dashboard: Astro+React+Recharts static site with trend visualization
  • L2 Integration Scaffolding: VMType::TokamakL2, TokamakL2Hook, BlockchainType::TokamakL2 with feature flag propagation

JIT Benchmark Results

Scenario Interpreter JIT Speedup
Fibonacci 3.55ms 1.40ms 2.53x
BubbleSort 357.69ms 159.84ms 2.24x
Factorial 2.36ms 1.41ms 1.67x
ManyHashes 2.26ms 1.55ms 1.46x

Phase Completion

Phase Description Status
A Production Foundation (Hive 6/6, Hoodi sync) ✅ 4/4
B JIT Hardening (gas alignment, BAL recording) ✅ 3/3
C Benchmark CI (JIT regression, LLVM 21, stats) ✅ 3/3
D Performance Optimization (size limit, folding) ✅ 3/3
E Developer Experience (debugger, CLI, RPC) ✅ 3/3
F Ecosystem & Launch (cross-client, dashboard, L2) ✅ 4/5
G Memory & Stability (arena, LRU, parallel, dispatch) ✅ 8/8

Codebase

Component Location Lines
LEVM JIT infra crates/vm/levm/src/jit/ ~2,700
tokamak-jit crates/vm/tokamak-jit/src/ ~5,650
tokamak-bench crates/tokamak-bench/src/ ~1,700
tokamak-debugger crates/tokamak-debugger/src/ ~1,310

CI Verification

  • Hive: 6/6 suites PASS (RPC, Devp2p, Auth, Cancun, Paris, Withdrawals)
  • Hoodi snap sync: PASS (1h48m35s)
  • Feature flag safety: tokamak-jit Hive == upstream (both 6/6)
  • 58 tokamak-jit tests, 48 tokamak-bench tests, 45 tokamak-debugger tests

Commit History (104 commits)

Phases 0-1: Foundation, architecture docs, feature flags, CI workflows
Phase 2: JIT compiler infrastructure (revmc adapter, LEVM integration)
Phase 3-6: Execution wiring, production hardening, CALL/CREATE resume
Phase 7: Dual-execution validation
Phase 8-9: Benchmarking infrastructure, CI regression detection
Phase A: Hive 6/6 PASS, Hoodi sync PASS, feature flag safety
Phase B: Gas alignment, BAL recording, test quality
Phase C: LLVM 21 provisioning, benchmark statistics
Phase D: Bytecode size limit, constant folding optimizer
Phase E: Time-travel debugger (engine, CLI, RPC)
Phase F: Cross-client benchmarks, dashboard, L2 scaffolding, security audit
Phase G: Arena allocator, CALL/CREATE validation, parallel compilation, JIT-to-JIT dispatch, LRU cache, constant folding enhancement, precompile fast dispatch

Test plan

  • cargo test -p tokamak-jit -- --test-threads=1 (58 tests)
  • cargo test -p tokamak-bench (48 tests)
  • cargo test -p tokamak-debugger --features cli (45 tests)
  • cargo clippy -p tokamak-jit -p tokamak-bench -p tokamak-debugger
  • Hive test suites (6/6 PASS)
  • Hoodi snap sync (1h48m35s)
  • Mainnet full sync (F-5, CI configured, awaiting manual dispatch)

Complete Phase 0 analysis: evaluate ethrex, Reth, from-scratch, and
revm-only options via weighted decision matrix. ethrex fork selected
(score 4.85/5) for its custom LEVM, ZK-native architecture, Hook
system, and manageable 133K-line codebase.

Includes vision, competitive landscape, feature specs, team discussion
summaries, Volkov review history, and branch strategy.
- Rebalance decision matrix to ethrex vs Reth binary comparison;
  move "from scratch" and "revm only" to appendix
- Adjust Reth scores: ZK 1→2 (Zeth exists), manageability 2→3
  (modular arch acknowledged), sync 5→4 for ethrex (less battle-tested)
- Add EXIT criteria with 4 elements: metric, deadline, action, owner
- Add Tier S PoC section: perf_opcode_timings build verification
  and code path analysis
- Add JIT technical barriers (dynamic jumps, revmc reference)
- Fix weighted sum arithmetic (Reth 2.85→2.80)
Record completed work: DECISION.md creation, Volkov R6 review (6.5/10),
three mandatory fixes (matrix rebalance, EXIT criteria, Tier S PoC),
Reth/Zeth/ExEx research findings, and next steps for Phase 1.1.
- DECISION.md: DRAFT → FINAL
- Replace human staffing model with AI Agent development model
- Add bus factor policy (Kevin as interim decision-maker)
- Replace staffing risks with agent-specific risks
- Remove Senior Rust 2명 EXIT criterion
- Add 11 custom commands (.claude/commands/):
  - Development: /rust, /evm, /jit, /debugger, /l2
  - Verification: /quality-gate, /safety-review, /diff-test
  - Operations: /rebase-upstream, /phase, /bench
- Volkov R8: 7.5/10 PROCEED achieved
Architecture analysis documents:
- OVERVIEW.md: 25+2 crate dependency graph, node startup flow, CI inventory
- LEVM.md: VM struct, execution flow, dual-dispatch loop, hook system
- MODIFICATION-POINTS.md: 5 modification points, hybrid isolation strategy
- PHASE-1-1.md: Phase 1.1 execution plan with success criteria

Phase 1.1 infrastructure:
- Skeleton crates: tokamak-jit, tokamak-bench, tokamak-debugger
- Feature flag: `tokamak` propagation chain (cmd → vm → levm)
- Workspace registration for 3 new crates
- Fix OpcodeTimings: remove false min/max claim, document 4 actual fields
- Fix CallFrame: caller→msg_sender, Bytes→Code, return_data→output/sub_return_data
- Fix opcode table: describe const fn chaining pattern accurately
- Label all pseudocode snippets consistently (JIT, debugger, L2 hook)
- Plan feature flag split: tokamak → tokamak-jit/debugger/l2
- Add JIT-VM interface complexity analysis (5 challenges)
- Add failure scenarios & mitigations table (5 scenarios)
- Record build results: 5m53s clean, 718 tests passed
- Fix line count ~133K → ~103K (verified via wc -l)
- Add tokamak feature to OVERVIEW.md feature tables
Split monolithic `tokamak` feature into 3 independent features
(tokamak-jit, tokamak-debugger, tokamak-l2) with umbrella re-export.
Add pr-tokamak.yaml CI workflow for quality-gate and format checks.
Update snapsync action default image to tokamak-network/ethrex.
Document sync architecture, Hive test matrix, and success criteria.
Add structured benchmark infrastructure to tokamak-bench crate:
- timings.rs: reset(), raw_totals(), raw_counts() accessors
- tokamak-bench: types, runner, report, regression modules + CLI binary
- CI workflow: pr-tokamak-bench.yaml (bench PR vs base, post comparison)
- 11 unit tests covering regression detection, JSON roundtrip, reporting
Feature unification causes these modules to be compiled during L2
workspace clippy. Add targeted allows for arithmetic_side_effects,
as_conversions, expect_used, and unsafe_code lints.
Add the core JIT tiered compilation modules that were missing from
the branch: execution counter, code cache dispatch, types, and
module declaration. These provide the lightweight in-process
infrastructure gated behind the tokamak-jit feature flag.
- tokamak-jit: compiler, backend, adapter, validation, error modules
- JIT backend CI job with LLVM 18 in pr-tokamak.yaml
- jit_bench module in tokamak-bench for interpreter vs JIT comparison
- Phase 2 architecture documentation
- Updated HANDOFF with current status
@github-actions
Copy link
Copy Markdown

🤖 Kimi Code Review

⚠️ Review failed: KIMI_API_KEY secret is not set


Automated review by Kimi (Moonshot AI)

@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello @cd4761, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

이 풀 리퀘스트는 Tokamak 이더리움 클라이언트의 기반을 다지는 중요한 진전을 나타냅니다. JIT EVM, 연속 벤치마킹, 타임-트래블 디버거와 같은 핵심 기능을 위한 아키텍처적 토대를 마련하는 데 중점을 두었습니다. 이를 위해 새로운 크레이트와 CI 워크플로우를 도입하고, 기존 LEVM(Lambda EVM)에 JIT 관련 인프라를 통합하며, 프로젝트의 방향과 구현 세부 사항을 명확히 하는 광범위한 문서를 추가했습니다. 이 작업은 향후 Tokamak 클라이언트의 성능, 검증 가능성 및 디버깅 용이성을 향상시키기 위한 초석이 될 것입니다.

Highlights

  • Tokamak 클라이언트 기반 마련: ethrex 포크 결정, 비전 및 아키텍처 문서화, Volkov 리뷰를 통한 초기 단계 승인 등 Tokamak 이더리움 클라이언트의 기반 작업이 완료되었습니다.
  • 아키텍처 분석 및 스켈레톤 크레이트 추가: LEVM 아키텍처 분석을 통해 tokamak-jit, tokamak-debugger 스켈레톤 크레이트가 추가되었고, 초기 기능 플래그 설정 및 Volkov 리뷰를 통과했습니다.
  • 기능 플래그 분할 및 CI 워크플로우 개선: 모놀리식 tokamak 기능 플래그가 tokamak-jit, tokamak-debugger, tokamak-l2로 분할되었으며, pr-tokamak.yaml CI 워크플로우가 추가되고 포크 CI 설정이 조정되었습니다.
  • 연속 벤치마킹 인프라 구축: OpcodeTimingsreset, raw_totals, raw_counts 접근자 메서드가 추가되었고, tokamak-bench 크레이트(러너, 리포트, 회귀 분석) 및 pr-tokamak-bench.yaml CI가 구현되었습니다.
  • JIT EVM 인프라 초기 구현: tokamak-jit 컴파일러 인프라(어댑터, 컴파일러, 백엔드, 유효성 검사)와 LEVM JIT 인프라 모듈(분석기, 캐시, 카운터, 디스패치, 타입)이 추가되었습니다.
  • 새로운 크레이트 추가: tokamak-bench, tokamak-jit, tokamak-debugger 세 가지 새로운 크레이트가 워크스페이스에 추가되었습니다.
  • LEVM JIT 인프라 모듈: crates/vm/levm/src/jit/ 경로에 JIT 컴파일을 위한 분석기, 캐시, 카운터, 디스패치, 타입 모듈이 추가되었습니다.
  • 광범위한 문서화: docs/tokamak/ 디렉토리에 DECISION, 아키텍처, 기능, 비전 등 Tokamak 프로젝트 관련 광범위한 문서가 추가되었습니다.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • .claude/commands/bench.md
    • 벤치마크 러너에 대한 새로운 명령 문서가 추가되었습니다.
  • .claude/commands/debugger.md
    • 타임-트래블 디버거에 대한 새로운 명령 문서가 추가되었습니다.
  • .claude/commands/diff-test.md
    • 차등 테스트에 대한 새로운 명령 문서가 추가되었습니다.
  • .claude/commands/evm.md
    • EVM 전문가에 대한 새로운 명령 문서가 추가되었습니다.
  • .claude/commands/jit.md
    • JIT 컴파일러 개발자에 대한 새로운 명령 문서가 추가되었습니다.
  • .claude/commands/l2.md
    • L2 Hook 개발자에 대한 새로운 명령 문서가 추가되었습니다.
  • .claude/commands/phase.md
    • 단계 관리에 대한 새로운 명령 문서가 추가되었습니다.
  • .claude/commands/quality-gate.md
    • 품질 게이트에 대한 새로운 명령 문서가 추가되었습니다.
  • .claude/commands/rebase-upstream.md
    • 업스트림 리베이스에 대한 새로운 명령 문서가 추가되었습니다.
  • .claude/commands/rust.md
    • Rust 전문가 개발자에 대한 새로운 명령 문서가 추가되었습니다.
  • .claude/commands/safety-review.md
    • 안전성 검토에 대한 새로운 명령 문서가 추가되었습니다.
  • .github/actions/snapsync-run/action.yml
    • 기본 ethrex Docker 이미지 저장소가 업데이트되었습니다.
  • Cargo.lock
    • alloy-primitives 종속성 버전이 업데이트되었고, inkwell, llvm-sys, regex-lite, revm-*, revmc-* 패키지가 추가되었습니다.
  • Cargo.toml
    • tokamak-jit, tokamak-bench, tokamak-debugger가 워크스페이스 멤버로 추가되었습니다.
  • cmd/ethrex/Cargo.toml
    • tokamak-jit, tokamak-debugger, tokamak-l2, tokamak 기능 플래그가 추가되었습니다.
  • crates/tokamak-bench/Cargo.toml
    • Tokamak 벤치마크를 위한 새로운 크레이트가 추가되었습니다.
  • crates/tokamak-bench/src/bin/runner.rs
    • Tokamak 벤치마크를 위한 메인 CLI 러너가 추가되었습니다.
  • crates/tokamak-bench/src/jit_bench.rs
    • JIT 벤치마크 결과 구조와 인터프리터 기준선 측정 로직이 추가되었습니다.
  • crates/tokamak-bench/src/lib.rs
    • jit_bench, regression, report, runner, types 모듈 선언이 추가되었습니다.
  • crates/tokamak-bench/src/regression.rs
    • 벤치마크 스위트 비교 및 회귀 감지 로직이 추가되었습니다.
  • crates/tokamak-bench/src/report.rs
    • JSON 직렬화/역직렬화 및 마크다운 보고서 생성 함수가 추가되었습니다.
  • crates/tokamak-bench/src/types.rs
    • 벤치마크 스위트, 결과, opcode 항목 및 회귀 보고서를 위한 데이터 구조가 추가되었습니다.
  • crates/tokamak-debugger/Cargo.toml
    • Tokamak 디버거를 위한 새로운 크레이트가 추가되었습니다.
  • crates/tokamak-debugger/src/lib.rs
    • Tokamak 타임-트래블 디버거를 위한 플레이스홀더 파일이 추가되었습니다.
  • crates/vm/Cargo.toml
    • tokamak-jit, tokamak-debugger, tokamak-l2, tokamak 기능 플래그가 추가되었습니다.
  • crates/vm/levm/Cargo.toml
    • tokamak-jit, tokamak-debugger, tokamak-l2, tokamak 기능 플래그가 추가되었습니다.
  • crates/vm/levm/src/jit/analyzer.rs
    • JIT 컴파일을 위한 바이트코드 분석 로직이 추가되었습니다.
  • crates/vm/levm/src/jit/cache.rs
    • 컴파일된 함수 포인터를 저장하기 위한 JIT 코드 캐시가 추가되었습니다.
  • crates/vm/levm/src/jit/counter.rs
    • JIT 컴파일 티어링을 위한 실행 카운터가 추가되었습니다.
  • crates/vm/levm/src/jit/dispatch.rs
    • JIT 디스패치 로직 및 전역 상태 관리가 추가되었습니다.
  • crates/vm/levm/src/jit/mod.rs
    • JIT 컴파일 인프라를 위한 모듈 선언이 추가되었습니다.
  • crates/vm/levm/src/jit/types.rs
    • JIT 컴파일 시스템을 위한 핵심 데이터 구조가 추가되었습니다.
  • crates/vm/levm/src/lib.rs
    • jit 모듈이 조건부로 추가되었습니다.
  • crates/vm/levm/src/precompiles.rs
    • #[allow(clippy::expect_used)] 속성이 추가되었습니다.
  • crates/vm/levm/src/timings.rs
    • OpcodeTimingsPrecompilesTimingsreset, raw_totals, raw_counts 메서드가 추가되었고, clippy 허용 규칙이 추가되었습니다.
  • crates/vm/levm/src/vm.rs
    • JIT_STATE 지연 정적 변수와 run_execution 루프에 JIT 디스패치 로직이 추가되었습니다.
  • crates/vm/tokamak-jit/Cargo.toml
    • Tokamak JIT 컴파일러를 위한 새로운 크레이트가 revmc 종속성과 함께 추가되었습니다.
  • crates/vm/tokamak-jit/src/adapter.rs
    • LEVM 상태를 revmc/revm 타입 모델로 연결하기 위한 어댑터 계층이 추가되었습니다.
  • crates/vm/tokamak-jit/src/backend.rs
    • EVM 바이트코드 컴파일 및 캐싱을 위한 고수준 JIT 백엔드가 추가되었습니다.
  • crates/vm/tokamak-jit/src/compiler.rs
    • EVM 바이트코드 컴파일을 위한 revmc/LLVM 컴파일러 래퍼가 추가되었습니다.
  • crates/vm/tokamak-jit/src/error.rs
    • JIT 컴파일을 위한 오류 타입이 추가되었습니다.
  • crates/vm/tokamak-jit/src/lib.rs
    • Tokamak JIT 컴파일러를 위한 모듈 선언 및 재내보내기가 추가되었습니다.
  • crates/vm/tokamak-jit/src/tests/fibonacci.rs
    • JIT 컴파일러를 위한 피보나치 PoC 테스트가 추가되었습니다.
  • crates/vm/tokamak-jit/src/tests/mod.rs
    • JIT 테스트를 위한 모듈 선언이 추가되었습니다.
  • crates/vm/tokamak-jit/src/validation.rs
    • JIT 및 인터프리터 결과 비교를 위한 유효성 검사 로직이 추가되었습니다.
  • docs/tokamak/DECISION.md
    • Tokamak EL 클라이언트 기반으로 ethrex를 포크하기 위한 결정 문서가 추가되었습니다.
  • docs/tokamak/README.md
    • Tokamak 이더리움 클라이언트의 비전과 기능을 설명하는 README 문서가 추가되었습니다.
  • docs/tokamak/architecture/LEVM.md
    • LEVM 아키텍처에 대한 심층 분석 문서가 추가되었습니다.
  • docs/tokamak/architecture/MODIFICATION-POINTS.md
    • Tokamak 수정 지점 및 격리 전략을 상세히 설명하는 문서가 추가되었습니다.
  • docs/tokamak/architecture/OVERVIEW.md
    • ethrex 아키텍처 개요 문서가 추가되었습니다.
  • docs/tokamak/architecture/PHASE-1-1.md
    • Phase 1.1: 포크 및 환경 설정에 대한 문서가 추가되었습니다.
  • docs/tokamak/architecture/PHASE-1-2.md
    • Phase 1.2: 동기화 및 Hive + CI 인프라에 대한 문서가 추가되었습니다.
  • docs/tokamak/architecture/PHASE-1-3.md
    • Phase 1.3: 벤치마킹 기반에 대한 문서가 추가되었습니다.
  • docs/tokamak/architecture/PHASE-2.md
    • Phase 2: JIT 기반 (revmc 통합)에 대한 문서가 추가되었습니다.
  • docs/tokamak/branch-strategy.md
    • Tokamak ethrex 브랜치 전략을 설명하는 문서가 추가되었습니다.
  • docs/tokamak/context/competitive-landscape.md
    • 이더리움 EL 클라이언트의 경쟁 환경을 분석하는 문서가 추가되었습니다.
  • docs/tokamak/context/open-questions.md
    • 미해결 질문 및 듀얼-트랙 전략을 다루는 문서가 추가되었습니다.
  • docs/tokamak/context/team-discussion-summary.md
    • 팀 토론 요약 문서가 추가되었습니다.
  • docs/tokamak/context/volkov-reviews.md
    • Volkov의 검토 이력 문서가 추가되었습니다.
  • docs/tokamak/features/01-time-travel-debugger.md
    • 타임-트래블 디버거 기능 문서가 추가되었습니다.
  • docs/tokamak/features/02-continuous-benchmarking.md
    • 연속 벤치마킹 기능 문서가 추가되었습니다.
  • docs/tokamak/features/03-jit-compiled-evm.md
    • JIT-컴파일된 EVM 기능 문서가 추가되었습니다.
  • docs/tokamak/scaffold/HANDOFF.md
    • Tokamak 이더리움 클라이언트 핸드오프 문서가 추가되었습니다.
  • docs/tokamak/slack-post.md
    • 통합 비전을 위한 Slack 게시물 초안이 추가되었습니다.
  • docs/tokamak/slack-short.md
    • 요약된 Slack 게시물 초안이 추가되었습니다.
  • docs/tokamak/vision.md
    • Tokamak 이더리움 클라이언트의 통합 비전 문서가 추가되었습니다.
Ignored Files
  • Ignored by pattern: .github/workflows/** (2)
    • .github/workflows/pr-tokamak-bench.yaml
    • .github/workflows/pr-tokamak.yaml
Activity
  • Phase 0 작업(ethrex 포크 결정, 비전/아키텍처 문서화, Volkov R6 검토)이 완료되었습니다.
  • Phase 1.1 작업(아키텍처 분석, 스켈레톤 크레이트, 기능 플래그, Volkov R8-R10 검토)이 완료되었습니다.
  • Phase 1.2 작업(기능 플래그 분할, pr-tokamak.yaml CI 워크플로우, 포크 CI 조정)이 완료되었습니다.
  • Phase 1.3 작업(OpcodeTimings 접근자 메서드, tokamak-bench 크레이트, pr-tokamak-bench.yaml CI)이 완료되었습니다.
  • Phase 2 작업(JIT 컴파일러 인프라 및 LEVM JIT 인프라 모듈)이 완료되었습니다.
  • tokamak-benchtokamak-jit에 대한 로컬 검증 테스트가 통과되었습니다.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

이 PR은 Tokamak Ethereum 클라이언트의 기반을 마련하는 중요한 작업입니다. JIT 컴파일, 벤치마킹, 디버깅을 위한 새로운 크레이트(tokamak-jit, tokamak-bench, tokamak-debugger)를 도입하고, 기존 ethrex-levm에 JIT 인프라와 벤치마킹을 위한 접근자 메소드를 추가했습니다. 또한, 기능별로 분리된 tokamak-* 피처 플래그와 CI 워크플로우를 설정하여 프로젝트의 구조를 체계적으로 잡았습니다. 전반적으로 코드 품질이 높고, 아키텍처에 대한 깊은 고민이 엿보입니다. 몇 가지 유지보수성 및 잠재적 메모리 누수와 관련된 개선점을 제안했지만, 이는 이 훌륭한 기반 작업의 가치를 훼손하지 않습니다.

Comment on lines +42 to +50
// SAFETY: The compiled function pointer is stored in CompiledCode
// which is kept alive in the CodeCache. The LLVM JIT memory backing
// the function is not freed (no `free_function` call in PoC).
#[expect(unsafe_code)]
let f: EvmCompilerFn = unsafe {
compiler
.jit(&hash_hex, bytecode, SpecId::CANCUN)
.map_err(|e| JitError::CompilationFailed(format!("{e}")))?
};
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

안전성 주석에 "no free_function call in PoC"라고 언급되어 있는데, 이는 컴파일된 코드가 메모리에서 해제되지 않아 메모리 누수가 발생할 수 있음을 시사합니다. PoC 단계에서는 괜찮을 수 있지만, 프로덕션 환경에서는 반드시 해결해야 할 문제입니다. 향후 JIT 코드 캐시에서 엔트리가 제거될 때 (예: LRU 정책에 의해) 컴파일된 함수 메모리도 함께 해제하는 메커니즘을 설계해야 합니다. revmc가 컴파일된 함수를 해제하는 API를 제공하는지 확인하고, 이를 CodeCacheinvalidateDrop 구현과 연동하는 것을 고려해야 합니다.

Comment on lines +1 to +5
#![allow(
clippy::arithmetic_side_effects,
clippy::as_conversions,
clippy::type_complexity
)]
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

파일 전체에 대해 중요한 clippy lint(특히 arithmetic_side_effectsas_conversions)를 비활성화하는 것은 잠재적인 버그를 숨길 수 있어 위험합니다. 이 PR에서 추가된 코드는 이 lint들을 발생시키지 않는 것으로 보입니다. 기존 코드의 특정 부분에서 lint가 발생한다면, 해당 라인이나 함수에만 #[allow(...)]를 적용하여 범위를 좁히는 것이 더 안전합니다. 예를 들어, info 함수 내의 count as f64 변환이 원인이라면 해당 표현식에만 lint를 허용하는 것이 좋습니다.

@github-actions
Copy link
Copy Markdown

Tokamak Benchmark Results: Baseline

No baseline benchmark found on the base branch.
This PR establishes the initial benchmark baseline.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Feb 23, 2026

Benchmark Results Comparison

No significant difference was registered for any benchmark run.

Detailed Results

Benchmark Results: BubbleSort

Command Mean [s] Min [s] Max [s] Relative
main_revm_BubbleSort 2.945 ± 0.021 2.915 2.981 1.06 ± 0.01
main_levm_BubbleSort 2.770 ± 0.015 2.736 2.790 1.00
pr_revm_BubbleSort 2.992 ± 0.061 2.943 3.152 1.08 ± 0.02
pr_levm_BubbleSort 2.862 ± 0.279 2.753 3.653 1.03 ± 0.10

Benchmark Results: ERC20Approval

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_ERC20Approval 980.6 ± 14.0 967.3 1011.9 1.00
main_levm_ERC20Approval 1053.7 ± 10.6 1039.2 1071.6 1.07 ± 0.02
pr_revm_ERC20Approval 982.7 ± 6.5 974.8 994.3 1.00 ± 0.02
pr_levm_ERC20Approval 1048.9 ± 10.7 1039.6 1075.8 1.07 ± 0.02

Benchmark Results: ERC20Mint

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_ERC20Mint 135.2 ± 2.2 132.5 138.9 1.01 ± 0.02
main_levm_ERC20Mint 159.8 ± 2.3 157.2 163.6 1.19 ± 0.02
pr_revm_ERC20Mint 134.4 ± 1.2 133.2 137.3 1.00
pr_levm_ERC20Mint 160.8 ± 2.9 157.1 164.9 1.20 ± 0.02

Benchmark Results: ERC20Transfer

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_ERC20Transfer 236.6 ± 5.7 232.2 251.6 1.01 ± 0.03
main_levm_ERC20Transfer 273.1 ± 6.2 268.4 289.9 1.17 ± 0.03
pr_revm_ERC20Transfer 234.0 ± 2.1 231.2 237.2 1.00
pr_levm_ERC20Transfer 274.3 ± 11.9 265.5 306.0 1.17 ± 0.05

Benchmark Results: Factorial

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_Factorial 229.9 ± 1.0 228.0 231.5 1.00
main_levm_Factorial 265.8 ± 6.1 261.3 277.7 1.16 ± 0.03
pr_revm_Factorial 233.2 ± 2.6 230.3 239.2 1.01 ± 0.01
pr_levm_Factorial 265.4 ± 1.9 263.2 268.0 1.15 ± 0.01

Benchmark Results: FactorialRecursive

Command Mean [s] Min [s] Max [s] Relative
main_revm_FactorialRecursive 1.763 ± 0.040 1.694 1.810 1.03 ± 0.07
main_levm_FactorialRecursive 9.946 ± 0.082 9.784 10.063 5.83 ± 0.40
pr_revm_FactorialRecursive 1.706 ± 0.116 1.402 1.804 1.00
pr_levm_FactorialRecursive 9.870 ± 0.088 9.769 10.054 5.79 ± 0.40

Benchmark Results: Fibonacci

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_Fibonacci 211.4 ± 0.7 210.2 212.8 1.00
main_levm_Fibonacci 240.0 ± 4.5 236.1 250.1 1.14 ± 0.02
pr_revm_Fibonacci 213.6 ± 1.3 212.1 216.9 1.01 ± 0.01
pr_levm_Fibonacci 237.2 ± 0.9 235.1 238.5 1.12 ± 0.01

Benchmark Results: FibonacciRecursive

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_FibonacciRecursive 884.3 ± 12.8 864.0 909.1 1.21 ± 0.03
main_levm_FibonacciRecursive 731.5 ± 14.1 710.9 754.0 1.00
pr_revm_FibonacciRecursive 903.0 ± 11.7 886.9 929.2 1.23 ± 0.03
pr_levm_FibonacciRecursive 735.5 ± 5.0 728.4 744.2 1.01 ± 0.02

Benchmark Results: ManyHashes

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_ManyHashes 8.6 ± 0.1 8.5 8.8 1.00
main_levm_ManyHashes 10.1 ± 0.1 9.9 10.3 1.17 ± 0.02
pr_revm_ManyHashes 8.6 ± 0.1 8.4 8.9 1.01 ± 0.02
pr_levm_ManyHashes 10.2 ± 0.2 10.0 10.6 1.19 ± 0.03

Benchmark Results: MstoreBench

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_MstoreBench 267.8 ± 1.3 266.2 270.4 1.19 ± 0.02
main_levm_MstoreBench 225.8 ± 3.6 222.4 231.8 1.00
pr_revm_MstoreBench 272.0 ± 10.9 266.0 301.0 1.20 ± 0.05
pr_levm_MstoreBench 227.5 ± 5.7 222.3 240.9 1.01 ± 0.03

Benchmark Results: Push

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_Push 296.0 ± 2.1 294.1 301.3 1.00
main_levm_Push 297.6 ± 3.2 292.1 303.1 1.01 ± 0.01
pr_revm_Push 296.1 ± 3.0 294.0 303.8 1.00 ± 0.01
pr_levm_Push 306.4 ± 13.2 296.8 341.8 1.04 ± 0.05

Benchmark Results: SstoreBench_no_opt

Command Mean [ms] Min [ms] Max [ms] Relative
main_revm_SstoreBench_no_opt 171.0 ± 5.1 164.3 181.9 1.55 ± 0.05
main_levm_SstoreBench_no_opt 110.6 ± 1.7 108.8 113.2 1.00
pr_revm_SstoreBench_no_opt 172.2 ± 6.5 165.2 189.3 1.56 ± 0.06
pr_levm_SstoreBench_no_opt 112.2 ± 4.2 109.2 123.2 1.01 ± 0.04

Add Phase 3 JIT execution wiring so JIT-compiled bytecode actually
runs through the VM dispatch instead of only being compiled.

Key changes:
- JitBackend trait in dispatch.rs for dependency inversion (LEVM
  defines interface, tokamak-jit implements)
- LevmHost: revm Host v14.0 implementation backed by LEVM state
  (GeneralizedDatabase, Substate, Environment)
- Execution bridge: builds revm Interpreter, wraps state in LevmHost,
  transmutes CompiledCode to EvmCompilerFn, maps result to JitOutcome
- vm.rs wiring: try_jit_dispatch() && execute_jit() before interpreter
  loop, with fallback on failure
- register_jit_backend() for startup registration
- E2E tests: fibonacci JIT execution + JIT vs interpreter validation
  (behind revmc-backend feature, requires LLVM 21)
Close 7 gaps preventing production use of the JIT system:

- 4A: Propagate is_static from CallFrame to revm Interpreter
- 4B: Sync gas refunds after JIT execution, pass storage_original_values
  through JIT chain for correct SSTORE original vs present value
- 4C: Add LRU eviction to CodeCache (VecDeque + max_entries)
- 4D: Auto-compile when execution counter hits threshold, add compile()
  to JitBackend trait and backend() accessor to JitState
- 4E: Detect CALL/CREATE/DELEGATECALL/STATICCALL opcodes in analyzer,
  skip JIT compilation for contracts with external calls
- 4F: Skip JIT when tracer is active, add JitMetrics with atomic
  counters, log fallback events via eprintln
…compilation, and validation

Phase 5 addresses three remaining JIT gaps:

5A — Multi-fork support: Cache key changed from H256 to (H256, Fork) so the
same bytecode compiled at different forks gets separate cache entries.
fork_to_spec_id() adapter added. Hardcoded SpecId::CANCUN removed from
compiler, execution, and host — all now use the environment's fork.

5B — Background async compilation: New CompilerThread with std::sync::mpsc
channel and a single background thread. On threshold hit, vm.rs tries
request_compilation() first (non-blocking); falls back to synchronous
compile if no thread is registered. register_jit_backend() now also
starts the background compiler thread.

5C — Validation mode wiring: JitConfig.max_validation_runs (default 3)
gates logging to first N executions per (hash, fork). JitState tracks
validation_counts and logs [JIT-VALIDATE] with gas_used and output_len
for offline comparison. Full dual-execution deferred to Phase 6.
M1: CompilerThread now implements Drop — drops sender to signal
    shutdown, then joins the background thread. Panics are caught
    and logged (no silent swallowing). Fields changed to Option
    for take-on-drop pattern.

M2: SELFDESTRUCT (0xFF) added to has_external_calls detection in
    analyzer.rs. Bytecodes containing SELFDESTRUCT are now skipped
    by the JIT compiler, preventing the incomplete Host::selfdestruct
    (missing balance transfer) from being exercised.

M3: Negative gas refund cast fixed in execution.rs. Previously
    `refunded as u64` would wrap negative i64 (EIP-3529) to a huge
    u64. Now uses `u64::try_from(refunded)` — negative values are
    silently ignored (already reflected in gas remaining).

M4: Documented fork assumption in counter.rs and vm.rs. Counter is
    keyed by bytecode hash only (not fork). Safe because forks don't
    change during a node's runtime; cache miss on new fork falls back
    to interpreter.
… flag (F-3)

- TokamakFeeConfig + JitPolicy types (crates/common)
- TokamakL2Hook wrapping L2Hook via composition (crates/vm/levm)
- VMType::TokamakL2 variant + hook dispatch + Evm constructors
- BlockchainType::TokamakL2 + 5 match arm updates (blockchain.rs)
- --tokamak-l2 CLI flag with env var support
- Feature propagation across 6 Cargo.toml files
- P256Verify precompile extended via is_l2_type() helper
- 7 unit tests (4 fee config serde + 3 hook)
Test coverage (+28 tests across 3 crates):
- tokamak-jit: SELFDESTRUCT E2E tests (basic, self-target, nonexistent, double, gas) — 31→36
- tokamak-bench: runner/regression/report edge cases (load_bytecode, empty baseline, zero-div, no-stats) — 35→48
- tokamak-debugger: error handling (revert, stop, OOG, empty bytecode) + recorder edge cases (empty/partial/zero stack capture) — 18→28

F-5 Mainnet Full Sync CI:
- Add mainnet option to tokamak-sync.yaml (48h timeout)
- Use ethrex-sync self-hosted runner for mainnet (6h GitHub-hosted limit insufficient)
- Conditional Kurtosis install (GitHub-hosted) vs Docker cleanup (self-hosted)
- Dynamic runner selection via matrix.runner field
Add a /compare page with JIT speedup trend chart and cross-client
performance table. Extend landing page with JIT Speedup and
Cross-Client sections. Generate cross-client fixture data for all
7 dates with realistic Geth/Reth ratios.

New components: JitSpeedupTable, CrossClientTable, CompareView
New data function: fetchCrossClientSuite
Tests: 76 pass (was 62), 3 pages build (was 2)
…ycle (G-1)

Introduces an arena allocator that groups JIT-compiled functions by LLVM
context. When all functions in an arena are evicted from the cache, the
arena and its LLVM resources are freed — eliminating the 1-5 MB per
compilation memory leak caused by std::mem::forget(compiler).

Key changes:
- arena.rs: ArenaManager, ArenaEntry, FuncSlot types with CAS-based
  concurrent eviction tracking (12 tests incl. 100-thread stress)
- compiler.rs: ArenaCompiler stores compilers instead of leaking them;
  compile_in_arena() alongside existing compile() for backward compat
- lib.rs: thread_local ArenaState in background compiler handler manages
  arena rotation, eviction-triggered freeing, and FreeArena requests
- cache.rs: func_id → arena_slot; insert() returns Option<FuncSlot>
- compiler_thread.rs: Free{slot} and FreeArena{arena_id} request variants
- dispatch.rs: JitState gains arena_manager field + send_free/send_free_arena
- types.rs: JitConfig +arena_capacity/max_arenas/max_memory_mb;
  JitMetrics +arenas_created/arenas_freed/functions_evicted
… STATUS

Add Phase G section to ROADMAP-REMAINING.md with full G-1 entry,
update STATUS.md architecture decision (mem::forget → arena allocator),
bump overall completion to ~92%.

Also fix minor unused-variable warnings in compiler_thread.rs and
storage.rs caught during verification.
…odes (G-3)

Remove the `!compiled.has_external_calls` guard that skipped validation
for bytecodes containing CALL/CREATE/DELEGATECALL/STATICCALL. The
interpreter replay handles sub-calls natively, so the state-swap
mechanism works correctly for all bytecodes.

- vm.rs: remove has_external_calls guard from needs_validation condition
- dual_execution.rs: add 5 G-3 tests (CALL, STATICCALL, DELEGATECALL,
  pure regression, combined metrics), extract shared MismatchBackend,
  setup_call_vm() helper, make_external_call_bytecode() builder
  (1258→751 lines, -40%)
- docs: mark G-2 complete (auto-resolved by G-1 arena system)
…on report

JIT-LIMITATIONS-ROADMAP.md: G-1~G-8 resolution roadmap with severity
tiers, solution options, acceptance criteria, and dependency graph.

THREE-PILLARS.md: Completion report covering JIT compiler (~80%),
continuous benchmarking (~80%), and time-travel debugger (~85%) with
15,507 lines of code and 332 tests across all three pillars.
Add 16 new binary opcodes (DIV, SDIV, MOD, SMOD, EXP, SIGNEXTEND,
LT, GT, SLT, SGT, EQ, SHL, SHR, SAR) and 2 unary opcodes (NOT,
ISZERO) to the bytecode constant folding optimizer. Each opcode
replicates exact LEVM semantics including signed arithmetic helpers,
divide-by-zero returning 0, and shift >= 256 returning 0.

Extract eval_op arms into named helpers (eval_sdiv, eval_smod,
eval_signextend, signed_compare, eval_sar, eval_shift) reducing
eval_op from 120 to 25 lines. Extract shared bytecode rewrite
logic into write_folded_push() eliminating duplication between
binary and unary fold loops (optimize: 100 → 44 lines).

68 optimizer unit tests (31 new), 8 integration tests (3 new),
proptest convergence check updated for unary patterns.
Replace single-threaded CompilerThread (std::sync::mpsc) with
multi-worker CompilerThreadPool using crossbeam-channel for MPMC
work distribution. Default worker count: num_cpus/2 (minimum 1).

Key changes:
- CompilerThreadPool with configurable N workers (crossbeam-channel)
- Deduplication guard (compiling_in_progress FxHashSet) prevents
  duplicate compilations across workers
- CompilationGuard drop struct for panic-safe dedup cleanup
- compile_workers field in JitConfig
- 4 new integration tests, 48 total tokamak-jit tests passing
…UDIT

- ROADMAP-REMAINING: G-7 section + D-3 cross-reference + execution timeline
- STATUS: G-7 feature bullet + recently completed entry
- JIT-LIMITATIONS-ROADMAP: G-1/G-2/G-3/G-5/G-7 marked DONE, updated
  severity overview, execution order, timeline (5/8 done, 44-66h remaining)
- THREE-PILLARS: limitation tables updated to reflect completions,
  Pillar 1 ~88%, constant folding expanded to 22 opcodes
- SAFETY_AUDIT: added optimizer scope section documenting G-7 expansion
  (22 opcodes, signed arithmetic safety, wrapping/checked operations)
- proptest-regressions: preserve discovered regression test case
…s (G-4)

When a JIT-compiled parent contract hits CALL, the VM now checks if the
child bytecode is also in the JIT cache and executes it directly via
JitState.execute_jit(), bypassing the full LEVM interpreter dispatch.

Key design decisions:
- VM-layer fast dispatch (no revmc upstream changes needed)
- Cache lookup at dispatch time via try_jit_dispatch() — O(1)
- CREATE excluded (init code needs validate_contract_creation)
- Precompile addresses always bypass JIT dispatch
- JIT errors in child treated as revert (state may be mutated)
- Configurable via enable_jit_dispatch config (default: true)
- Observable via jit_to_jit_dispatches metric in JitMetrics

Phase 2 (v1.1 SIGNIFICANT) is now ALL RESOLVED: G-3, G-4, G-5.

security-scan: pass
…stamps (G-6)

Replace VecDeque-based FIFO eviction in JIT code cache with per-entry
AtomicU64 timestamps for LRU eviction. The get() hot path uses only a
read lock plus two atomic ops (~2-5ns overhead), while eviction runs an
O(n) min_by_key scan under write lock on insert().

- Add CacheEntry struct wrapping CompiledCode + AtomicU64 last_access
- Move access_counter Arc<AtomicU64> outside RwLock for lock-free get()
- Evict least-recently-used entry on capacity overflow (not oldest inserted)
- Return evicted entry's FuncSlot for arena memory reclamation
- Add 9 cache unit tests + 5 integration tests (53 total tokamak-jit tests)
- Update SAFETY_AUDIT.md: resolve LRU eviction recommendation
When JIT-compiled code suspends on a CALL to a precompile address,
handle_jit_subcall() already executes the precompile inline without
creating a full child call frame. G-8 adds observability and config:

- Add precompile_fast_dispatches AtomicU64 metric to JitMetrics
- Add enable_precompile_fast_dispatch config toggle to JitConfig
- Track metric in handle_jit_subcall() precompile arm (vm.rs)
- Add is_precompile_fast_dispatch_enabled() to JitState
- 9 tests: 5 interpreter correctness + 4 JIT differential (58 total)
- Update snapshot() return type from 7-tuple to 8-tuple
@jason-h23 jason-h23 changed the title feat(l1): tokamak proven execution — phase 0-1.3 foundation feat(tokamak): JIT-compiled EVM with proven execution infrastructure Feb 27, 2026
…udit after Phase G

- STATUS.md: overall 94% → 99%, JIT 80% → 92%
- THREE-PILLARS.md: tokamak-jit tests 73 → 58, debugger 45 → 55, summary table updated
- ROADMAP-REMAINING.md: added commit hashes for G-6 (3b2861b) and G-8 (ccf34e6)
- SAFETY_AUDIT.md: added G-5 parallel compilation and G-6 LRU cache eviction sections
Reduce per-CALL overhead in JIT suspend/resume cycles without modifying
revmc. Three runtime-level optimizations target DeFi router patterns
(5-10 CALLs per tx):

- Tier 1: Bytecode zero-copy — cache Arc<Bytes> in CompiledCode at
  compile time, use Arc::clone in execute_jit instead of
  Bytes::copy_from_slice (~1-5us/CALL saved)
- Tier 2: Resume state pool — thread-local pool of JitResumeStateInner
  boxes (16-entry cap) eliminates Box alloc/dealloc per suspend/resume
- Tier 3: TX-scoped bytecode cache — FxHashMap<H256, Code> on VM avoids
  repeated db.get_code() for same contract in multi-CALL transactions

Adds bytecode_cache_hits metric to JitMetrics (9-tuple snapshot).
11 new tests in recursive_call_opt.rs, 69 total tokamak-jit tests.
@Zena-park
Copy link
Copy Markdown
Member

@cd4761 Please change the base branch of this PR from main to tokamak-dev.
You can do this via the GitHub UI Edit button or by running gh pr edit 2 --base tokamak-dev.

@Zena-park
Copy link
Copy Markdown
Member

@cd4761 Please address the following items from the Gemini Code Assist review:

High Priority:

  • compiler.rs:50 — Potential memory leak in JIT-compiled functions. No free_function call means compiled code is never deallocated when evicted from the LRU cache. Must be fixed before production.

Medium Priority:

  • timings.rs — Disabling clippy lints (arithmetic_side_effects, as_conversions) for the entire file is risky. Apply #[allow(...)] only to specific lines instead.

@Zena-park
Copy link
Copy Markdown
Member

@cd4761 The "PR title" CI check is failing because the scope tokamak is not in the allowed list.

Error:

Unknown scope "tokamak" found in pull request title. Scope must match one of: l1, l2, levm.

Fix options:

  1. Change the PR title scope to an allowed one (e.g., feat(l1): JIT-compiled EVM...)
  2. Or add tokamak to the allowed scopes in the CI workflow (.github/workflows/ semantic PR config)

Zena-park added a commit that referenced this pull request Mar 16, 2026
…ntainability

- CORS: restrict origin to Tauri dev/prod allowlist (Copilot #1)
- open-url: use execFile with arg arrays instead of shell exec (Copilot #2)
- fs browse: restrict path traversal to home directory (Copilot #3)
- test-e2e-fork: move RPC URL to SEPOLIA_RPC_URL env var (Copilot #4)
- docker-remote: clear timeout on stream close, close stream on timeout (Copilot #5)
- docker-remote: add shell quoting (q()) and assertSafeName for all
  interpolated shell args to prevent injection (Copilot #6-8)
- genesis.rs: add ChainConfig::validate() for pre-startup checks (Copilot #9)
- listings.js: use named params (@id, @name, ...) instead of 30
  positional ? args for upsertListing (Gemini #1)
Zena-park added a commit that referenced this pull request Mar 17, 2026
…to-logout on 401

- Bug #1 (critical): getProgramById → getProgramByProgramId for slug lookup
  Pass program.id (UUID) to createDeployment and incrementUseCount
- Bug #2: incrementUseCount now receives UUID instead of slug
- Bug #3: fetch() headers properly merged (options can't overwrite auth)
- Bug #8: auto-logout on 401 response (expired token)
Zena-park added a commit that referenced this pull request Mar 17, 2026
- Add cross-platform keychain support: macOS uses `security` CLI,
  Windows/Linux uses `keyring` crate via cfg(target_os) (#1)
- Restore keychain key validation with allowed prefixes
  (pinata_, deployer_pk_, ai-) for security boundary (#3)
- Add warning log to empty catch block in tools container status (#2)
- Extract magic number 9 to LOCAL_L1_CHAIN_ID constant (#4)
Zena-park added a commit that referenced this pull request Mar 17, 2026
- Add cross-platform keychain support: macOS uses `security` CLI,
  Windows/Linux uses `keyring` crate via cfg(target_os) (#1)
- Restore keychain key validation with allowed prefixes
  (pinata_, deployer_pk_, ai-) for security boundary (#3)
- Add warning log to empty catch block in tools container status (#2)
- Extract magic number 9 to LOCAL_L1_CHAIN_ID constant (#4)
Zena-park added a commit that referenced this pull request Mar 17, 2026
…te detection

* fix(manager): prompt — download bridge UI source, reorder firewall before tools

- Step 6: download bridge UI source files (Dockerfile, HTML, entrypoint.sh)
  from GitHub before tools compose up (fixes build path not found)
- Move firewall (Step 7→6) before tools (Step 6→7) so ports are open
  for external monitoring before tools deployment
- Public URLs already set via VM_IP metadata for dashboard Explorer links

* feat(manager): auto-detect deployment success + save & complete button

- Monitor: when all services are healthy, show success message with URLs
- "배포 완료 — 정보 저장" button saves IP/port to DB, sets phase=running
- Navigates to dashboard detail view after save
- Guide text: "아래 버튼을 누르면 대시보드 화면으로 이동합니다"

* feat(messenger): Open Appchain public interface — API integration, metadata push, publish UX

- Replace mock data in OpenL2View with Platform API (getPublicAppchains)
- Add registration modal for external appchain publishing (name, RPC, chain ID)
- OpenL2DetailView: real screenshots (IPFS), RPC status check, reviews/comments/announcements
- L2DetailPublishTab: allow description/screenshots/social links input before publish toggle
- Platform server: metadata-push.js — push/delete metadata to GitHub repo via Contents API
- New routes: POST /deployments/:id/push-metadata, /delete-metadata
- Debounced metadata push (5s) after description/screenshot/social link saves
- Security: name length validation, status escalation guard, commit message sanitization, 409 retry
- i18n: loading/error/retry/nativeToken/rating/reviews/comments/noScreenshots/announcements
- Tests: 24 unit tests (metadata-push), e2e-store.js (11-step lifecycle test)

* fix(messenger): add save button for publish tab — persist draft to localStorage before publish

* fix(messenger): block publishing with localhost RPC URL — require publicly accessible endpoint

* fix(messenger): fix publish toggle disabled for non-local appchains — remove false localhost check

* feat(platform): server-side screenshot upload — no Pinata required

- POST /api/deployments/:id/screenshots — multer-based image upload (5MB, images only)
- platformAPI.uploadScreenshots() — FormData upload to Platform server
- L2DetailPublishTab: use server upload when platformId exists, IPFS fallback, data URL fallback
- Remove Pinata requirement for screenshot upload button

* fix(messenger): detect AWS deployments correctly — show AWS badge, fix L1 chain ID, enable publishing

- networkMode detection: config.mode > host_id (AWS) > l1_chain_id > local
- L1 chain ID: read from DB l1_chain_id field first, then config fallback
- Add AWS (orange), Mainnet (green) badges alongside existing Testnet/Local
- Add hostId, publicRpcUrl, deployMethod to L2Config interface

* fix(messenger): allow publishing when public URL or remote host exists, not just by networkMode

* fix(messenger): add missing DB fields (l1_chain_id, host_id, public_l2_rpc_url) to DeploymentRow

- Rust: add l1_chain_id, host_id, platform_deployment_id, public_l2_rpc_url, public_domain to SELECT
- TS: add matching fields to DeploymentFromDB interface
- Now AWS deployments show correctly (not as Local), L1 Chain ID displays properly

* fix(messenger): correct networkMode detection — use l1_port to distinguish local vs testnet

- l1_port exists → local (has bundled L1 node in Docker)
- host_id exists → AWS (remote deployment)
- l1_chain_id exists but no l1_port → testnet (external L1)
- Fixes: local Docker showing as Testnet, AWS showing as Local

* fix(messenger): detect AWS via config.cloud, read l1ChainId from config fallback

* docs: add deployment network mode detection documentation

* fix(manager): fix status showing stopped for AI-deploy local Docker — distinguish remote vs local

- AI Deploy with ec2IP → SSH remote status check
- AI Deploy without ec2IP (local Docker) → local docker compose ps
- Remote host deployments → SSH status check
- Fixes: local Docker containers showing as stopped, (pending) hostname

* fix(messenger): use l2.programSlug for publish instead of non-existent 'ethrex-appchain'

- Fixes 'Load failed' error when publishing — Platform has no 'ethrex-appchain' program
- L2DetailPublishTab: programId = l2.programSlug || 'evm-l2'
- OpenL2View registration modal: programId = 'evm-l2'
- Rename labels: '오픈 앱체인 공개' → '앱체인 공개 설정'

* fix: critical publish bugs — program lookup by slug, header merge, auto-logout on 401

- Bug #1 (critical): getProgramById → getProgramByProgramId for slug lookup
  Pass program.id (UUID) to createDeployment and incrementUseCount
- Bug #2: incrementUseCount now receives UUID instead of slug
- Bug #3: fetch() headers properly merged (options can't overwrite auth)
- Bug #8: auto-logout on 401 response (expired token)

* feat(messenger): make Platform URL configurable via VITE_PLATFORM_URL env var

* feat(messenger): metadata registry submission with auto register/update detection

- Add appchain-registry API client with check/submit/status endpoints
- Auto-detect register vs update by checking existing file on GitHub main branch
- Preserve immutable fields (l2ChainId, nativeToken, createdAt) on updates
- Fetch actual chain ID from L2 RPC (eth_chainId) for accuracy
- Map social links to correct schema fields (website → top-level, twitter → xUrl, etc.)
- Fix bridges.url empty string validation failure (omit if no dashboardUrl)
- Add GitHub PR title/body update when resubmitting to existing open PR
- Add keychain-based metadata signing (SECURITY_COUNCIL role)
- Open PR links in external browser via Tauri shell plugin

* fix(messenger): include dashboard URL in metadata — fallback to port 3000 for remote deployments

* fix(platform): sync metadata schema fields — resolve URLs from supportResources, explorers, bridges

listings.js was reading legacy top-level fields (dashboardUrl, explorerUrl, bridgeUrl)
that don't exist in the new appchain metadata schema. Now reads from:
- supportResources.dashboardUrl → dashboard_url
- explorers[0].url → explorer_url
- bridges[0].url → bridge_url
- top-level website → operator_website
- supportResources xUrl/communityUrl/telegramUrl/documentationUrl → social_links

* fix: address PR #66 code review feedback

- Add cross-platform keychain support: macOS uses `security` CLI,
  Windows/Linux uses `keyring` crate via cfg(target_os) (#1)
- Restore keychain key validation with allowed prefixes
  (pinata_, deployer_pk_, ai-) for security boundary (#3)
- Add warning log to empty catch block in tools container status (#2)
- Extract magic number 9 to LOCAL_L1_CHAIN_ID constant (#4)

* fix: address Copilot PR #66 review feedback

- Fix signing message indentation bug — spaces before each line caused
  signature mismatch with server (array.join instead of multiline string)
- Fix saveDraft stale state — pass fresh result to avoid missing prNumber
- Add NaN timestamp validation in submit endpoint
- Add rate limit map cleanup to prevent unbounded memory growth
- Strict address validation in getRepoFilePath (0x + 40 hex chars)
- findOpenPR verifies actual PR files instead of title-only matching
- Remove .deployed-*-tools.env from tracking, add to .gitignore
Zena-park added a commit that referenced this pull request Mar 17, 2026
- Return 503 instead of {exists:false} on check endpoint errors (#1)
- Sanitize all error messages — log internally, return generic to client (#2,#3,#4,#5)
- Add serverless rate limit limitation comment (#6)
- Add console.warn to all empty catch blocks in github-pr.ts (#9,#10,#11)
- Note: params as Promise is correct for Next.js 15 (#7,#8)
Zena-park added a commit that referenced this pull request Mar 17, 2026
* feat(platform): add appchain registry API routes to Next.js client

Port Express server appchain-registry endpoints to Next.js API routes
for Vercel deployment:
- GET /api/appchain-registry/check/[l1ChainId]/[stackType]/[identityAddress]
- POST /api/appchain-registry/submit
- GET /api/appchain-registry/status/[prNumber]

Shared logic in lib/appchain-registry.ts and lib/github-pr.ts.

* fix: address PR #67 code review feedback

- Return 503 instead of {exists:false} on check endpoint errors (#1)
- Sanitize all error messages — log internally, return generic to client (#2,#3,#4,#5)
- Add serverless rate limit limitation comment (#6)
- Add console.warn to all empty catch blocks in github-pr.ts (#9,#10,#11)
- Note: params as Promise is correct for Next.js 15 (#7,#8)

* fix: address additional Copilot PR #67 review feedback

- Add AbortSignal.timeout(15s) to all GitHub API fetch calls
- Fix authHeaders error message to list both accepted env vars
- Distinguish RPC errors (502) from permission denied (403) in ownership check
- Add typeof validation for metadata.signedBy
- Add unit test suggestion acknowledged (future work)
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.

9 participants