Skip to content

feat(tokamak-debugger): Sentinel Dashboard — H-4 Alert System + H-5 Live Dashboard#4

Open
jason-h23 wants to merge 127 commits intotokamak-devfrom
feat/tokamak-autopsy
Open

feat(tokamak-debugger): Sentinel Dashboard — H-4 Alert System + H-5 Live Dashboard#4
jason-h23 wants to merge 127 commits intotokamak-devfrom
feat/tokamak-autopsy

Conversation

@jason-h23
Copy link
Copy Markdown

Summary

Complete Sentinel real-time hack detection monitoring system with alert management and live dashboard:

  • H-4 Alert & Notification System: AlertDispatcher (composite fan-out), JsonlFileAlertHandler, StdoutAlertHandler, WebhookAlertHandler (HTTP POST + exponential backoff retry), AlertDeduplicator (block-window suppression), AlertRateLimiter (sliding-window)
  • H-5 Sentinel Dashboard: WsAlertBroadcaster (real-time WebSocket feed), AlertHistory (JSONL query engine with pagination/filtering/sorting), SentinelMetrics (Prometheus text exposition format), Dashboard UI (Astro+React sentinel page with AlertFeed, AlertCard, AlertHistoryTable, SentinelMetricsPanel)

This completes Phase H (5/5 tasks) of the Sentinel system.

Architecture

Block Processing → SentinelService (non-blocking mpsc)
    → PreFilter (7 heuristics, ~10-50μs/TX)
    → DeepAnalyzer (replay + AttackClassifier + FundFlowTracer)
    → AlertHandler pipeline:
        RateLimiter → Deduplicator → Dispatcher
            ├─> JsonlFileAlertHandler
            ├─> StdoutAlertHandler
            ├─> WebhookAlertHandler (autopsy-gated)
            └─> WsAlertBroadcaster → Dashboard WebSocket clients

Changes

Rust (crates/tokamak-debugger)

File Description
sentinel/alert.rs AlertDispatcher, JSONL/Stdout handlers, Deduplicator, RateLimiter
sentinel/webhook.rs WebhookAlertHandler (autopsy-gated, reqwest)
sentinel/ws_broadcaster.rs WsAlertBroadcaster + WsAlertHandler
sentinel/history.rs AlertHistory query engine (pagination, filtering, sorting)
sentinel/metrics.rs SentinelMetrics (8 AtomicU64 counters + Prometheus export)
sentinel/service.rs Integrated metrics instrumentation + timing
sentinel/types.rs Added Deserialize derives, label String change
sentinel/tests.rs 37 new tests (H-4: 14, H-5: 29+8 integration)

Dashboard (dashboard/)

File Description
types/sentinel.ts TypeScript types matching Rust structs
components/AlertPriorityBadge.tsx Color-coded priority pill badge
components/AlertCard.tsx Expandable alert display card
components/AlertFeed.tsx WebSocket live feed with auto-reconnect
components/AlertHistoryTable.tsx Paginated/filterable history table
components/SentinelMetricsPanel.tsx Auto-refresh metrics tiles (10s)
pages/sentinel.astro Three-section responsive layout
__tests__/sentinel.test.tsx 21 dashboard tests

Test Plan

  • cargo test -p tokamak-debugger --features "cli,autopsy,sentinel" — 259 passed, 10 ignored
  • cargo clippy -p tokamak-debugger --features "cli,autopsy,sentinel" — 0 warnings
  • cd dashboard && npm test — 97 passed
  • cd dashboard && npm run build — 4 pages clean
  • Feature-gated: sentinel-only (115), sentinel+autopsy (195+10ign), cli+autopsy+sentinel (259+10ign)

jason-h23 and others added 30 commits February 22, 2026 11:51
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
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.
…ment

Phase 6A — CALL/CREATE Resume:
- Add JitResumeState, SubCallResult, JitSubCall types for suspend/resume
- Add JitOutcome::Suspended variant for mid-execution suspension
- Extend JitBackend trait with execute_resume for resume-after-subcall
- Rewrite execution.rs: single-step execute, translate_frame_input,
  apply_subcall_result, handle_interpreter_action
- Add resume loop in vm.rs JIT dispatch block
- Add handle_jit_subcall() to execute sub-calls via LEVM interpreter
- Add run_subcall() with depth-bounded interpreter loop
- Remove has_external_calls compilation gate in backend.rs

Phase 6B — LLVM Memory Management:
- Add func_id: Option<u32> to CompiledCode for lifecycle tracking
- Return evicted func_id from CodeCache::insert() on eviction
- Add CompilerRequest enum (Compile/Free) to compiler_thread
- Add send_free() method for cache eviction notifications
- Wire Free request handling in register_jit_backend()
M1: Credit unused child gas back to revm interpreter via erase_cost()
M2: Write CALL output to interpreter memory at return_memory_offset
M3: Complete CREATE semantics (EIP-3860 initcode limit, nonce increment,
    EIP-170 code size check, deploy code storage)
M4: Extract shared interpreter_loop(stop_depth) to eliminate opcode
    dispatch table duplication between run_execution and run_subcall
M5: Add 7 tests for CALL/CREATE resume path (subcall.rs)
M6: Add balance validation before transfer in handle_jit_subcall
…daclass#6197)

## Motivation

The L2 integration test (`test_erc20_roundtrip`) panics with `unwrap()
on a None value` at `integration_tests.rs:705` after ~8 consecutive test
runs against the same L1/L2 instance. The `find_withdrawal_with_widget`
helper creates a fresh `L2ToL1MessagesTable` (starting from block 0),
fetches all withdrawal logs, and searches for the latest withdrawal —
but `on_tick` uses `truncate(50)` which keeps the **oldest** 50 items.
After enough runs accumulate >50 withdrawal events, the newest
withdrawal falls outside the window.

The bug is not easily reproducible manually because `--dev` mode removes
the databases on startup, so you can't restart with a pre-existing store
that has >50 entries. It surfaces in CI when integration tests run
repeatedly against the same L1/L2 instance without clearing state
between runs.

## Description

Replace `truncate(50)` with `drain(..len - 50)` in the `on_tick` methods
so that the **newest** 50 messages are kept instead of the oldest. This
fix is applied to all three monitor widgets that had the same pattern:

- `L2ToL1MessagesTable` — withdrawal messages (original bug)
- `L1ToL2MessagesTable` — deposit messages (same latent bug)
- `BlocksTable` — block list (same latent bug)

## Checklist

- [ ] Updated `STORE_SCHEMA_VERSION` (crates/storage/lib.rs) if the PR
includes breaking changes to the `Store` requiring a re-sync.
R13 fixes (3.0 → 6.0):
- M1: JIT CREATE tests exercising handle_jit_subcall CREATE arm
- M2: EIP-7702 delegation gap documented with TODO comment
- M3: Use from_bytecode_unchecked for CREATE init code
- R1: Precompile value transfer test with identity precompile
- R2: Non-precompile transfer guard aligned with generic_call
- R3: Comment reference format unified (no line numbers)

R14 fixes:
- M1: JitState::reset_for_testing() with clear() on CodeCache,
  ExecutionCounter, JitMetrics for test isolation across #[serial] tests
- M2: Differential JIT vs interpreter comparison in CREATE tests with
  jit_executions metrics assertion proving JIT path execution
- M3: Remaining line number reference removed from vm.rs
- R1: Precompile test strengthened with interpreter baseline comparison
- R2: CREATE collision JIT test with pre-seeded address verification

handle_jit_subcall CALL path: balance check, precompile BAL recording,
value transfer with EIP-7708 log, non-precompile BAL checkpoint.
handle_jit_subcall CREATE path: max nonce check, add_accessed_address,
BAL recording, collision check, deploy nonce, EIP-7708 log.
Gate test-only methods (reset_for_testing, clear, reset) behind
#[cfg(any(test, feature = "test-utils"))] to prevent production
exposure. Add missing reset_for_testing() calls to remaining serial
tests, gas_used differential assertions, and unit tests for new methods.
…tests

- fibonacci: add INTRINSIC_GAS import, use 20% tolerance for JIT vs
  interpreter gas comparison (EIP-2929 access list pre-warming causes
  small gas discrepancy between direct execute_jit and full VM paths)
- oversized: remove unused mut on db variable
- group-ib-analysis.md: product ideas from Group-IB Crime Trends 2026
- volkov-derived-ideas.md: 5 service ideas from internal Volkov Review
- autopsy-lab-plan.md: detailed implementation plan for hack post-mortem
  analysis service using existing Time-Travel Debugger infrastructure
Post-hack analysis service built on the Time-Travel Debugger:
- RemoteVmDatabase: archive node RPC client + LEVM Database impl with caching
- StepRecord enrichment: CALL value, LOG topics, SSTORE capture in recorder
- AttackClassifier: reentrancy, flash loan, price manipulation, access control detection
- FundFlowTracer: ETH transfers + ERC-20 Transfer event tracking
- AutopsyReport: JSON + Markdown output with suggested fixes
- CLI: `autopsy --tx-hash <HASH> --rpc-url <URL>` subcommand

New `autopsy` feature flag gates reqwest/sha3/serde_json/rustc-hash deps.
Tests: 28 base + 42 autopsy + 27 cli = 97 total (was 55).
… and all sections

- Add ExecutionOverview with call depth, opcode stats, contract count
- Always show all report sections (empty ones show "None detected")
- Fix legacy/EIP-1559 TX type auto-detection in CLI
- Set gas_price, tx_max_fee_per_gas, tx_nonce in Environment
- Use TX gas limit (not block) for Environment.gas_limit
Reports are now saved to a file instead of printing to stdout. Default
filename is autopsy-{hash_prefix}.{ext} in the current directory.
…callback patterns

Three detection strategies:
1. ETH value: existing CALL value borrow/repay matching
2. ERC-20: matching Transfer events (same token, to/from same address)
3. Callback depth: >60% of ops at depth > entry+1 indicates flash loan callback

Tested on Euler Finance stETH exploit TX — correctly identifies flash loan
provider (Lido stETH) and borrow/repay steps (257→9966 of 9991 total).
100 tests (was 97).
Address 9 issues from /devil review (6.8→target 8.5/10):
- Verdict-first summary ("VERDICT: Flash Loan detected.")
- Known contract labels (~20 mainnet addresses: DAI, WETH, Lido, Aave)
- PUSHn/DUPn/SWAPn aggregated in top opcodes (no duplicates)
- Zero-amount flash loans show "amount unknown" instead of "0 wei"
- All affected contracts listed with Role column (was 3/9, now 9/9)
- Storage value interpretation (MAX_UINT256, 0→nonzero, etc.)
- Section transition text for narrative flow
- Protocol-specific suggested fixes with disclaimer
- Conclusion section with attack timeline and callback span %
W1: Add Fund Flow limitation note (callback amounts not captured)
W2: Provider → "Suspected provider (heuristic)" throughout report
W2: Add "Unlabeled contracts" footer to Affected Contracts table
W3: Truncate storage slot hashes (0xabcdef01…89abcdef) + ABI footnote
W3: ERC-20 zero-value transfers show "(undecoded)" instead of "0"
W4: Uniform table separators (--- for all columns)
W5: Key Steps expanded — SSTORE, CREATE, ERC-20 events (2→7 entries)
W5: Conclusion replaces timeline copy with storage impact analysis
- E-4 (Smart Contract Autopsy Lab): mark as complete in ROADMAP + STATUS
  - RemoteVmDatabase, AttackClassifier (4 patterns), FundFlowTracer,
    AutopsyReport (verdict-first MD/JSON), CLI subcommand, 100 tests
- Phase H (Real-Time Attack Detection — Sentinel): new 5-task roadmap
  - H-1: Block execution recording hook
  - H-2: Lightweight pre-filter (depth/gas/calls/watchlist)
  - H-3: Real-time classification pipeline (async producer-consumer)
  - H-4: Alert & notification system (webhook/Slack/log)
  - H-5: Sentinel dashboard (WebSocket + historical browsing)
- STATUS: update Feature #21 (85%→95%), add Feature #22 (0%)
…provements

Phase I — Network Resilience:
- RPC timeout (30s) + exponential backoff retry (3 retries, 1s→2s→4s)
- Structured RpcError enum (6 variants) with retryable classification
- RpcConfig struct with --rpc-timeout/--rpc-retries CLI flags

Phase II — Data Quality:
- ERC-20 transfer amount decoding from LOG3 data bytes
- Price delta estimation via SLOAD value comparison
- 80+ known mainnet contract labels (DEX, lending, bridges, oracles)
- ABI-based storage slot decoding (keccak256 mapping support)

Phase III — Robustness:
- Bounded caches with FIFO eviction in RemoteVmDatabase
- AutopsyMetrics observability (RPC calls, cache hits, latency)
- 100k-step stress tests (<5s classification, <1s report)

Phase IV — Validation & Confidence:
- DetectedPattern wrapper with 0.0-1.0 confidence + evidence chains
- 10 mainnet exploit validation scaffolds (DAO, Euler, Curve, etc.)

Cross-crate: OpcodeRecorder::record_step now takes &Memory for LOG
data capture. Memory::current_base_offset() added to LEVM.

Tests: 145 passing + 10 ignored mainnet scaffolds (was 97).
Remove JIT compiler (tokamak-jit), benchmark harness (tokamak-bench),
dashboard, LEVM JIT module, L2 scaffolding, and related CI/docs from
the autopsy branch. These features live on feat/tokamak-three-pillars.

Add Phase H Sentinel real-time attack detection plan (SENTINEL-PLAN.md).
…H-3)

Implement the Sentinel system — a real-time hack detection pipeline that
monitors committed blocks for suspicious transactions and generates alerts.

Phase H-1: Pre-Filter Engine
- 7 receipt-based heuristics (flash loan signature, high-value revert,
  multiple ERC-20 transfers, known contract interaction, unusual gas,
  self-destruct indicators, oracle+swap pattern)
- SentinelConfig with configurable thresholds, 14 known mainnet addresses
- `sentinel` feature flag in tokamak-debugger
- 32 tests

Phase H-2: Deep Analysis Engine
- replay_tx_from_store: re-executes suspicious TX from local Store with
  OpcodeRecorder, executing preceding TXs to reconstruct correct state
- DeepAnalyzer: orchestrates replay → AttackClassifier → FundFlowTracer
  (reuses E-4 autopsy infrastructure via #[cfg(feature = "autopsy")])
- SentinelAlert, SentinelError (8 variants), AnalysisConfig types
- 20 tests (14 sentinel-only + 6 autopsy-gated)

Phase H-3: Block Processing Integration
- BlockObserver trait in ethrex-blockchain (DIP — avoids circular dep)
- SentinelService: background worker thread with mpsc channel, two-stage
  PreFilter → DeepAnalyzer pipeline, non-blocking on block processing
- Hooks in add_block/add_block_pipeline after store_block
- AlertHandler trait + LogAlertHandler default implementation
- Graceful shutdown via Drop (send signal + join worker thread)
- 11 tests

Architecture doc: docs/tokamak/SENTINEL-ARCHITECTURE.md

Total: 208 passing + 10 ignored, clippy clean all feature combinations.
…nd metrics (H-4/H-5)

H-4 Alert & Notification System:
- AlertDispatcher composite fan-out to multiple handlers
- JsonlFileAlertHandler (append-only JSONL), StdoutAlertHandler
- WebhookAlertHandler (HTTP POST + exponential backoff, autopsy-gated)
- AlertDeduplicator (block-window suppression), AlertRateLimiter (sliding-window)

H-5 Sentinel Dashboard:
- WsAlertBroadcaster: real-time WebSocket alert feed with dead-subscriber cleanup
- AlertHistory: JSONL-based query engine with pagination, filtering, sorting
- SentinelMetrics: Prometheus text exposition format (8 atomic counters)
- Dashboard UI: Astro+React sentinel page with AlertFeed, AlertCard,
  AlertHistoryTable, SentinelMetricsPanel components
- SentinelService instrumented with timing and counter metrics

Tests: 259 Rust (cli+autopsy+sentinel) + 97 dashboard, clippy clean
@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello, 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!

This pull request significantly enhances the Tokamak Debugger by introducing the Sentinel real-time hack detection system, which includes a robust alert and notification framework alongside a live dashboard for monitoring. It also integrates advanced time-travel debugging capabilities and optimizes core block processing mechanisms, particularly for Block Access List (BAL) enabled chains. These changes collectively improve the platform's security monitoring, debugging tools, and overall performance efficiency.

Highlights

  • Sentinel Real-time Hack Detection System (H-4): Introduced a comprehensive alert and notification system including an AlertDispatcher for composite fan-out, JsonlFileAlertHandler for file logging, StdoutAlertHandler for console output, and a WebhookAlertHandler with HTTP POST and exponential backoff retry. The system also features an AlertDeduplicator for block-window suppression and an AlertRateLimiter using a sliding window to manage alert volume.
  • Sentinel Live Dashboard (H-5): Developed a live dashboard with a WsAlertBroadcaster for real-time WebSocket alert feeds, AlertHistory for JSONL query engine capabilities (pagination, filtering, sorting), and SentinelMetrics for Prometheus text exposition. The dashboard UI is built with Astro+React, featuring AlertFeed, AlertCard, AlertHistoryTable, and SentinelMetricsPanel components.
  • Time-Travel Debugger Integration: Integrated the tokamak-debugger crate, enabling opcode-level tracing and a new debug_timeTravel RPC endpoint for detailed transaction replay and state inspection. This includes new OpcodeRecorder trait in LEVM and enhanced VM state capture.
  • Optimized Block Processing with Block Access List (BAL): Improved block processing efficiency by introducing warm_block_from_bal for direct prefetching of accounts and storage slots based on the Block Access List, reducing speculative re-execution. The merkleization process (handle_merkleization_bal) was also optimized for BAL-enabled blocks, allowing parallel storage root computation.
  • L1 Proof Sender Batch Verification: Updated L1 proof sending logic to support batch verification (verifyBatches) on the OnChainProposer contract, improving efficiency by allowing multiple consecutive L2 batches to be verified in a single transaction. Includes fallback to single-batch sending on failure and improved error handling for invalid proofs.
  • P2P Discovery External IP Detection: Implemented an IP voting mechanism in the discv5 server to detect the node's external IP address using PONG messages from peers. This mechanism uses voting rounds and a configurable threshold to update the local ENR, enhancing network discoverability.
  • Precompile Caching in LEVM: Introduced a PrecompileCache in LEVM to store results of precompile calls, allowing the warmer and executor threads to share cached results and avoid redundant computations.

🧠 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
    • Added documentation for the benchmark runner command.
  • .claude/commands/debugger.md
    • Added documentation for the time-travel debugger developer mode.
  • .claude/commands/diff-test.md
    • Added documentation for the differential testing command.
  • .claude/commands/evm.md
    • Added documentation for the EVM specialist developer mode.
  • .claude/commands/jit.md
    • Added documentation for the JIT compiler developer mode.
  • .claude/commands/l2.md
    • Added documentation for the L2 Hook developer mode.
  • .claude/commands/phase.md
    • Added documentation for the phase management command.
  • .claude/commands/quality-gate.md
    • Added documentation for the quality gate command.
  • .claude/commands/rebase-upstream.md
    • Added documentation for the upstream rebase workflow command.
  • .claude/commands/rust.md
    • Added documentation for the Rust expert developer mode.
  • .claude/commands/safety-review.md
    • Added documentation for the safety review command.
  • .github/actions/build-docker/action.yml
    • Updated build variant description to include 'tokamak' option.
  • .github/actions/snapsync-run/action.yml
    • Updated default ethrex Docker image repository to tokamak-network.
    • Added support for additional cargo build flags.
    • Updated assertoor config URL to use GITHUB_REPOSITORY variable.
  • .gitignore
    • Added new entries for dashboard-related build artifacts and node modules.
  • CHANGELOG.md
    • Added new performance entries for LEVM interpreter loop, substate lookups, and precompile cache.
  • Cargo.lock
    • Added crossbeam-channel and tokamak-debugger dependencies.
  • Cargo.toml
    • Added tokamak-debugger to workspace members.
    • Added jit-bench profile for JIT benchmarking.
    • Added serial_test dependency.
  • cmd/ethrex/Cargo.toml
    • Added tokamak-debugger feature flag.
  • cmd/ethrex/cli.rs
    • Added environment variable support for various CLI options including bootnodes, syncmode, metrics, dev mode, log color, log directory, mempool max size, authrpc, p2p, builder, and precompute witnesses.
  • cmd/ethrex/initializers.rs
    • Modified add_block_pipeline calls to include bal parameter.
  • cmd/ethrex/l2/command.rs
    • Modified add_block_pipeline calls to include bal parameter.
  • cmd/ethrex/l2/options.rs
    • Added ETHREX_SPONSORABLE_ADDRESSES_PATH environment variable support.
    • Added prover_timeout_ms to ProofCoordinatorOptions and SequencerConfig.
    • Added PROVER_CLIENT_LOG_LEVEL environment variable support.
  • crates/blockchain/blockchain.rs
    • Introduced BlockObserver trait for block commit notifications.
    • Removed Debug derive from Blockchain and implemented custom Debug trait.
    • Added block_observer field to Blockchain and methods to set/unset it.
    • Added BalStateWorkItem struct for BAL state trie shard workers.
    • Modified warm_block logic to use warm_block_from_bal when BAL is present.
    • Modified handle_merkleization to dispatch to handle_merkleization_bal for BAL-specific processing.
    • Implemented handle_merkleization_bal for parallel storage root computation and state trie updates.
    • Modified add_block_pipeline to accept an optional BlockAccessList and notify the block_observer.
  • crates/blockchain/mempool.rs
    • Renamed clear_broadcasted_txs to remove_broadcasted_txs and updated its functionality to remove specific hashes.
  • crates/blockchain/metrics/l2/metrics.rs
    • Updated batch_verification_gas metric labels to include tx_hash.
  • crates/blockchain/tracing.rs
    • Refactored transaction tracing by extracting prepare_state_for_tx method.
  • crates/common/types/block_access_list.rs
    • Added all_storage_slots method to AccountChanges for iterating over storage slots.
  • crates/common/types/transaction.rs
    • Removed rlp_encode_as_pooled_tx and rlp_length_as_pooled_tx methods from EIP4844Transaction.
  • crates/l2/based/README.md
    • Updated verifyBatch to verifyBatches in documentation.
  • crates/l2/contracts/src/l1/OnChainProposer.sol
    • Refactored verifyBatch into _verifyBatchInternal.
    • Introduced verifyBatches to allow verification of multiple batches in a single transaction.
  • crates/l2/contracts/src/l1/Timelock.sol
    • Updated verifyBatch to verifyBatches.
  • crates/l2/contracts/src/l1/based/OnChainProposer.sol
    • Refactored verifyBatch into _verifyBatchInternal.
    • Introduced verifyBatches to allow verification of multiple batches in a single transaction.
  • crates/l2/contracts/src/l1/based/interfaces/IOnChainProposer.sol
    • Updated verifyBatch to verifyBatches in the interface.
  • crates/l2/contracts/src/l1/interfaces/IOnChainProposer.sol
    • Updated verifyBatch to verifyBatches in the interface.
  • crates/l2/contracts/src/l1/interfaces/ITimelock.sol
    • Updated verifyBatch to verifyBatches in the interface.
  • crates/l2/sequencer/configs.rs
    • Added prover_timeout_ms field to ProofCoordinatorConfig.
  • crates/l2/sequencer/l1_committer.rs
    • Modified add_block_pipeline calls to include bal parameter.
  • crates/l2/sequencer/l1_proof_sender.rs
    • Changed VERIFY_FUNCTION_SIGNATURE to VERIFY_BATCHES_FUNCTION_SIGNATURE.
    • Refactored verify_and_send_proof to verify_and_send_proofs to handle multiple batches.
    • Implemented send_verify_batches_tx for sending batch verification transactions.
    • Added invalid_proof_type and try_delete_invalid_proof for better error handling.
    • Added finalize_batch_proof for updating progress and cleaning up checkpoints.
    • Implemented send_single_batch_proof and send_batches_proof_to_contract with fallback logic.
  • crates/l2/sequencer/proof_coordinator.rs
    • Removed request_timestamp metric.
    • Added assignments and prover_timeout fields for tracking batch assignments.
    • Implemented next_batch_to_assign to find the next unassigned batch for a prover.
  • crates/networking/p2p/discv5/server.rs
    • Added IP_VOTE_WINDOW and IP_VOTE_THRESHOLD constants for external IP detection.
    • Introduced ip_votes, ip_vote_period_start, and first_ip_vote_round_completed fields.
    • Implemented record_ip_vote and finalize_ip_vote_round for IP voting logic.
    • Added is_private_ip and update_local_ip helper functions.
    • Modified handle_pong to record IP votes.
    • Modified handle_find_node to validate sender contact.
    • Updated cleanup_stale_entries to check for IP voting round end.
  • crates/networking/p2p/rlpx/connection/handshake.rs
    • Optimized buffer handling in receive_auth, receive_ack, and receive_handshake_msg to avoid unnecessary cloning and improve efficiency.
  • crates/networking/p2p/rlpx/connection/server.rs
    • Offloaded transaction processing in handle_incoming_message to a background task for better performance and non-blocking behavior.
  • crates/networking/p2p/rlpx/eth/transactions.rs
    • Updated NewPooledTransactionHashes to use WrappedEIP4844Transaction for calculating transaction size.
  • crates/networking/p2p/rlpx/l2/l2_connection.rs
    • Modified add_block_pipeline calls to include bal parameter.
  • crates/networking/p2p/sync/full.rs
    • Modified add_block_pipeline calls to include bal parameter.
  • crates/networking/p2p/tx_broadcaster.rs
    • Changed clear_broadcasted_txs to remove_broadcasted_txs for more granular control over broadcasted transactions.
  • crates/networking/rpc/Cargo.toml
    • Added tokamak-debugger as an optional dependency.
  • crates/networking/rpc/debug/mod.rs
    • Added time_travel module, gated by tokamak-debugger feature.
  • crates/networking/rpc/debug/time_travel.rs
    • Added new RPC endpoint debug_timeTravel for time-travel debugging, allowing replay of transactions with opcode-level detail.
  • crates/networking/rpc/engine/payload.rs
    • Modified handle_new_payload_v1_v2, handle_new_payload_v3, handle_new_payload_v4, add_block, and try_execute_payload to accept an optional BlockAccessList parameter.
  • crates/networking/rpc/rpc.rs
    • Updated BlockWorkerMessage type to include BlockAccessList.
    • Modified start_block_executor to pass BlockAccessList to add_block_pipeline.
    • Added debug_timeTravel to the RPC method mapping.
  • crates/tokamak-debugger/Cargo.toml
    • Added new crate tokamak-debugger with cli, autopsy, and sentinel features.
  • crates/tokamak-debugger/src/autopsy/abi_decoder.rs
    • Added AbiDecoder for ABI-based storage slot decoding.
  • crates/tokamak-debugger/src/autopsy/classifier.rs
    • Added AttackClassifier for detecting reentrancy, flash loans, price manipulation, and access control bypasses.
  • crates/tokamak-debugger/src/autopsy/enrichment.rs
    • Added enrich_storage_writes to fill old_value for SSTOREs and collect_sstore_slots.
  • crates/tokamak-debugger/src/autopsy/fund_flow.rs
    • Added FundFlowTracer for extracting ETH and ERC-20 transfers.
  • crates/tokamak-debugger/src/autopsy/metrics.rs
    • Added AutopsyMetrics for tracking RPC calls, cache hits, and timing during autopsy analysis.
  • crates/tokamak-debugger/src/autopsy/mod.rs
    • Organized autopsy-related modules.
  • crates/tokamak-debugger/src/autopsy/remote_db.rs
    • Added RemoteVmDatabase for fetching state from archive nodes via JSON-RPC.
  • crates/tokamak-debugger/src/autopsy/report.rs
    • Added AutopsyReport for generating JSON and Markdown reports of transaction analysis.
  • crates/tokamak-debugger/src/autopsy/rpc_client.rs
    • Added EthRpcClient for robust JSON-RPC communication with retry and backoff.
  • crates/tokamak-debugger/src/autopsy/types.rs
    • Defined core types for autopsy analysis, including AttackPattern, FundFlow, DetectedPattern, AnnotatedStep, and Severity.
  • crates/tokamak-debugger/src/bin/debugger.rs
    • Added main binary for tokamak-debugger CLI.
  • crates/tokamak-debugger/src/cli/commands.rs
    • Defined debugger CLI commands and their execution logic.
  • crates/tokamak-debugger/src/cli/formatter.rs
    • Added formatting utilities for debugger output.
  • crates/tokamak-debugger/src/cli/mod.rs
    • Organized CLI-related modules and defined Args for command-line parsing.
  • crates/tokamak-debugger/src/cli/repl.rs
    • Implemented the interactive REPL loop for the debugger.
  • crates/tokamak-debugger/src/engine.rs
    • Implemented ReplayEngine for recording and navigating transaction execution traces.
  • crates/tokamak-debugger/src/error.rs
    • Defined error types for the debugger, including DebuggerError and RpcError.
  • crates/tokamak-debugger/src/lib.rs
    • Main library file for tokamak-debugger.
  • crates/tokamak-debugger/src/recorder.rs
    • Implemented DebugRecorder as an OpcodeRecorder to capture StepRecords.
  • crates/tokamak-debugger/src/sentinel/alert.rs
    • Implemented AlertDispatcher, JsonlFileAlertHandler, StdoutAlertHandler, AlertDeduplicator, and AlertRateLimiter for Sentinel alert management.
  • crates/tokamak-debugger/src/sentinel/analyzer.rs
    • Implemented DeepAnalyzer for re-executing suspicious transactions and running the autopsy pipeline.
  • crates/tokamak-debugger/src/sentinel/history.rs
    • Implemented AlertHistory for querying historical alerts from JSONL files.
  • crates/tokamak-debugger/src/sentinel/metrics.rs
    • Implemented SentinelMetrics for Prometheus-compatible metrics collection.
  • crates/tokamak-debugger/src/sentinel/mod.rs
    • Organized Sentinel-related modules.
  • crates/tokamak-debugger/src/sentinel/pre_filter.rs
    • Implemented PreFilter for receipt-based detection of suspicious transactions.
  • crates/tokamak-debugger/src/sentinel/replay.rs
    • Implemented replay_tx_from_store for replaying transactions from local node state.
  • crates/tokamak-debugger/src/sentinel/service.rs
    • Implemented SentinelService as a background service for block monitoring and alert processing.
  • crates/tokamak-debugger/src/sentinel/tests.rs
    • Added tests for Sentinel pre-filter, deep analysis types, and service integration.
  • crates/tokamak-debugger/src/sentinel/types.rs
    • Defined Sentinel-specific types for configuration, suspicious transactions, and alerts.
  • crates/tokamak-debugger/src/sentinel/webhook.rs
    • Implemented WebhookAlertHandler for sending alerts via HTTP POST.
  • crates/tokamak-debugger/src/sentinel/ws_broadcaster.rs
    • Implemented WsAlertBroadcaster for real-time WebSocket alert distribution.
  • crates/tokamak-debugger/src/tests/autopsy_tests.rs
    • Added tests for Autopsy Lab components, including classifier, enrichment, and report generation.
  • crates/tokamak-debugger/src/tests/basic_replay.rs
    • Added basic replay tests for step recording and opcode/PC verification.
  • crates/tokamak-debugger/src/tests/cli_tests.rs
    • Added tests for CLI command parsing, formatting, and execution.
  • crates/tokamak-debugger/src/tests/error_handling.rs
    • Added error handling tests for ReplayEngine::record().
  • crates/tokamak-debugger/src/tests/gas_tracking.rs
    • Added gas tracking tests to verify gas accounting in traces.
  • crates/tokamak-debugger/src/tests/helpers.rs
    • Added shared test helpers for tokamak-debugger tests.
  • crates/tokamak-debugger/src/tests/mainnet_validation.rs
    • Added mainnet exploit validation tests (ignored by default).
  • crates/tokamak-debugger/src/tests/mod.rs
    • Organized debugger test modules.
  • crates/tokamak-debugger/src/tests/navigation.rs
    • Added navigation tests for forward/backward/goto cursor operations.
  • crates/tokamak-debugger/src/tests/nested_calls.rs
    • Added nested calls tests to verify depth tracking.
  • crates/tokamak-debugger/src/tests/recorder_edge_cases.rs
    • Added edge case tests for DebugRecorder stack capture.
  • crates/tokamak-debugger/src/tests/serde_tests.rs
    • Added serialization round-trip tests for debugger types.
  • crates/tokamak-debugger/src/tests/stress_tests.rs
    • Added large trace stress tests for performance validation.
  • crates/tokamak-debugger/src/types.rs
    • Defined core data types for the time-travel debugger, including ReplayConfig, StorageWrite, StepRecord, and ReplayTrace.
  • crates/vm/Cargo.toml
    • Added tokamak-debugger feature flag.
  • crates/vm/backends/levm/mod.rs
    • Added warm_block_from_bal for BAL-based state pre-warming.
    • Updated execute_precompile call to utilize the new PrecompileCache.
  • crates/vm/levm/Cargo.toml
    • Added crossbeam-channel dependency.
    • Added test-utils and tokamak-debugger features.
  • crates/vm/levm/bench/revm_comparison/contracts/BitwiseOps.sol
    • Added BitwiseOps Solidity contract for benchmarking.
  • crates/vm/levm/bench/revm_comparison/contracts/Exponentiation.sol
    • Added Exponentiation Solidity contract for benchmarking.
  • crates/vm/levm/bench/revm_comparison/contracts/KeccakLoop.sol
    • Added KeccakLoop Solidity contract for benchmarking.
  • crates/vm/levm/bench/revm_comparison/contracts/bin/BitwiseOps.bin-runtime
    • Added runtime bytecode for BitwiseOps contract.
  • crates/vm/levm/bench/revm_comparison/contracts/bin/Exponentiation.bin-runtime
    • Added runtime bytecode for Exponentiation contract.
  • crates/vm/levm/bench/revm_comparison/contracts/bin/KeccakLoop.bin-runtime
    • Added runtime bytecode for KeccakLoop contract.
  • crates/vm/levm/src/call_frame.rs
    • Added peek method to Stack for inspecting stack values.
  • crates/vm/levm/src/db/mod.rs
    • Added precompile_cache accessor to Database trait and CachingDatabase.
  • crates/vm/levm/src/debugger_hook.rs
    • Added OpcodeRecorder trait for per-opcode recording.
  • crates/vm/levm/src/lib.rs
    • Added debugger_hook module, gated by tokamak-debugger feature.
  • crates/vm/levm/src/memory.rs
    • Added current_base_offset method to Memory.
  • crates/vm/levm/src/opcode_handlers/arithmetic.rs
    • Added #[inline] attribute to op_sub and op_mul for performance optimization.
  • crates/vm/levm/src/opcode_handlers/bitwise_comparison.rs
    • Added #[inline] attribute to op_lt, op_gt, op_eq, op_iszero, op_and, op_or, op_shl, and op_shr for performance optimization.
  • crates/vm/levm/src/opcode_handlers/environment.rs
    • Added #[inline] attribute to op_calldataload for performance optimization.
  • crates/vm/levm/src/opcode_handlers/push.rs
    • Added #[inline] attribute to op_push0 for performance optimization.
  • crates/vm/levm/src/opcode_handlers/stack_memory_storage_flow.rs
    • Added #[inline] attribute to op_pop, op_mstore, and op_sload for performance optimization.
  • crates/vm/levm/src/opcode_handlers/system.rs
    • Added #[inline] attribute to op_return for performance optimization.
    • Updated execute_precompile call to pass precompile_cache.
  • crates/vm/levm/src/opcodes.rs
    • Added #[inline] attribute to op_stop for performance optimization.
    • Added fast-path dispatch for common opcodes in the interpreter loop.
  • crates/vm/levm/src/precompiles.rs
    • Added PrecompileCache struct for caching precompile results.
    • Implemented caching logic within execute_precompile.
  • crates/vm/levm/src/timings.rs
    • Added reset, raw_totals, and raw_counts methods to OpcodeTimings and PrecompilesTimings.
  • crates/vm/levm/src/vm.rs
    • Improved Substate methods (add_selfdestruct, add_accessed_slot, add_accessed_address, add_created_account) to check self first for warm lookups.
    • Added opcode_recorder field to VM struct.
    • Integrated record_step call from opcode_recorder before each opcode dispatch.
    • Refactored run_execution into a new interpreter_loop to support bounded execution for JIT sub-calls.
    • Updated execute_precompile call to pass the PrecompileCache.
  • crates/vm/lib.rs
    • Exported PrecompileCache from ethrex_levm::precompiles.
  • crates/vm/tracing.rs
    • Added setup_env_for_tx method to Evm for setting up transaction execution environments.
  • dashboard/.gitignore
    • Added dashboard-specific ignore patterns.
  • dashboard/astro.config.ts
    • Added Astro configuration for React and Tailwind integrations.
  • dashboard/fixtures/2026-02-20/818e015fe-bench.json
    • Added benchmark data for commit 818e015fe.
  • dashboard/fixtures/2026-02-20/818e015fe-cross-client.json
    • Added cross-client benchmark data for commit 818e015fe.
  • dashboard/fixtures/2026-02-20/818e015fe-jit-bench.json
    • Added JIT benchmark data for commit 818e015fe.
  • dashboard/fixtures/2026-02-20/818e015fe-regression.json
    • Added regression analysis data for commit 818e015fe.
  • dashboard/fixtures/2026-02-21/705f74ba5-bench.json
    • Added benchmark data for commit 705f74ba5.
  • dashboard/fixtures/2026-02-21/705f74ba5-cross-client.json
    • Added cross-client benchmark data for commit 705f74ba5.
  • dashboard/fixtures/2026-02-21/705f74ba5-jit-bench.json
    • Added JIT benchmark data for commit 705f74ba5.
  • dashboard/fixtures/2026-02-21/705f74ba5-regression.json
    • Added regression analysis data for commit 705f74ba5.
Ignored Files
  • Ignored by pattern: .github/workflows/** (1)
    • .github/workflows/pr-main_mdbook.yml
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

This is an impressive and substantial pull request that introduces the complete Sentinel real-time hack detection system and the Tokamak time-travel debugger. The architecture is well-designed, particularly the use of the BlockObserver trait to cleanly integrate the Sentinel service. The performance optimizations, such as the fast-path dispatch in the EVM interpreter loop, the Block Access List (BAL)-based merkleization, and the precompile result caching, are excellent additions that demonstrate a deep understanding of EVM performance characteristics. The refactoring of L1 proof submission to support batch verification is a significant gas optimization and the fallback logic enhances its robustness. The addition of external IP discovery via P2P voting is also a solid improvement for node connectivity. The new tokamak-debugger crate is well-structured and the features it provides are powerful. I have one minor suggestion for improving maintainability in one of the new documentation files.

Comment on lines +36 to +37
`crates/vm/levm/src/hooks/l2_hook.rs` (844줄)이 완전한 L2 Hook 구현.
이것을 기반으로 TokamakL2Hook을 구현한다.
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

Hardcoding line numbers in documentation can become a maintenance issue as the code evolves and line numbers change. It would be more robust to refer to the code by its structure, for example, by mentioning 'the L2Hook implementation in l2_hook.rs' instead of citing a specific line number.

Suggested change
`crates/vm/levm/src/hooks/l2_hook.rs` (844줄)이 완전한 L2 Hook 구현.
이것을 기반으로 TokamakL2Hook을 구현한다.
`crates/vm/levm/src/hooks/l2_hook.rs` 파일이 완전한 L2 Hook 구현의 좋은 참조입니다.
이것을 기반으로 TokamakL2Hook을 구현한다.

…mode

Add prefilter_alert_mode to AnalysisConfig for lightweight monitoring
without full Merkle trie state. When enabled, SentinelService emits
PreFilter-based alerts if deep analysis fails or returns nothing.

Three E2E tests prove the full pipeline: bytecode execution through
LEVM with opcode recording, AttackClassifier reentrancy detection
(confidence >= 0.7), PreFilter receipt-based heuristics, and
SentinelService background worker alert emission.

262 tests pass (+3 new), 10 ignored, clippy clean.
…2E test

6-phase E2E test with real bytecode execution through the entire
Sentinel pipeline (LEVM → AttackClassifier → FundFlowTracer →
SentinelService → alert validation). Also adds an executable demo
example that visualizes each phase.

- Phase 1: Deploy attacker+victim contracts, execute in LEVM (80 steps)
- Phase 2: Verify call depth >= 3 and SSTORE count >= 2
- Phase 3: AttackClassifier detects Reentrancy (confidence >= 70%)
- Phase 4: FundFlowTracer traces ETH transfers (victim → attacker)
- Phase 5: SentinelService processes real receipt, emits alert
- Phase 6: Validate alert content and metrics counters

Test count: 263 passing + 10 ignored (was 262+10), clippy clean.
- Add live reentrancy pipeline entry to Feature #21 and Phase H sections
- Update tokamak-debugger file/line counts (33→45 files, ~6,950→~13,900 lines)
- Update total Tokamak codebase count (~16,630→~23,980 lines)
- Test count: 263 passing + 10 ignored
…ptive pipeline, and auto-pause

Expand the Sentinel real-time attack detection system with four H-6
sub-features, plus security hardening from code review:

H-6a (CLI & Configuration):
- TOML SentinelFullConfig with 6 sub-configs (sentinel, analysis,
  alert, dedup, rate-limit, auto-pause)
- load_config/merge_cli_overrides/validate functions
- 6 --sentinel.* CLI flags in ethrex cmd
- init_sentinel() bootstrap returning SentinelComponents

H-6b (Mempool Monitoring):
- MempoolPreFilter with 5 calldata heuristics (flash-loan selector,
  high-value DeFi, high-gas known contract, suspicious creation,
  multicall pattern)
- MempoolObserver trait in ethrex-blockchain with hooks in
  add_transaction_to_pool/add_blob_transaction_to_pool
- MempoolAlert/MempoolSuspicionReason types

H-6c (Adaptive Pipeline):
- AnalysisStep trait + StepResult (Continue/Dismiss/AddSteps)
- FeatureVector (16 numerical features)
- 6 pipeline steps (FlashLoan/Reentrancy/PriceManip/AccessControl/
  FundFlow/AnomalyDetection)
- StatisticalAnomalyDetector (z-score + sigmoid confidence)
- AnalysisPipeline orchestrator with PipelineMetrics

H-6d (Auto Pause):
- PauseController (AtomicBool + Condvar + auto-resume timer) in
  ethrex-blockchain with check_pause() in add_block
- AutoPauseHandler (AlertHandler circuit breaker with configurable
  score threshold)
- sentinel_resume/sentinel_status JSON-RPC endpoints

Security fixes from code review:
- Move sentinel_resume to authrpc-only (was exposed on public HTTP)
- Bound dynamic pipeline step queue to MAX_DYNAMIC_STEPS=64
- Use combined confidence score (max of prefilter, pipeline) in alerts
- PauseController fail-open on lock poisoning (log + unpause, no panic)

Tests: 310 passing + 10 ignored (debugger), 5 passing (PauseController)
Clippy: clean on tokamak-debugger, ethrex-blockchain, ethrex (default)
Add Tokamak-specific features to root README.md (debugger, autopsy lab,
sentinel, benchmarking) and update docs/tokamak/README.md with Feature
#4 (Autopsy Lab) and #5 (Sentinel) in the feature table and competitive
positioning.
Add sentinel_dashboard_demo.rs — a mini HTTP+WS server (Axum on port 3001)
that serves the 3 endpoints expected by the Astro+React dashboard:

- GET /sentinel/metrics  — 4-field JSON metrics snapshot
- GET /sentinel/history  — paginated alert history with filters
- GET /sentinel/ws       — WebSocket real-time alert feed

Key design:
- SuspicionReason remapping from Rust externally-tagged enum to
  dashboard's {type, details} format
- AlertQueryResult field mapping (total_count → total)
- Background block generator (3s cycle, 3 TX patterns)
- CORS permissive for cross-origin dashboard access
- axum(ws), tower-http(cors), tokio(full) added to sentinel feature
@jason-h23 jason-h23 force-pushed the feat/tokamak-autopsy branch from 9a7fe47 to 03fc185 Compare March 2, 2026 14:43
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
- 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.

8 participants