How to Debug Acton-based TON Applications: Complete DAP Guide

Acton provides a built-in debugging stack that implements the Debug Adapter Protocol (DAP), allowing you to set breakpoints, step through Tolk source code, and inspect TVM stack variables using any standard IDE like VS Code or Neovim.

Debugging smart contracts on The Open Network (TON) traditionally requires interpreting low-level VM logs. The ton-blockchain/acton repository solves this by embedding a source-level debugger directly into the CLI. This guide explains how to use Acton’s DAP-compatible debugging tools to step through live contract execution or replay historical transactions with full visibility into variables and call stacks.

The Acton Debugging Architecture

The debugging functionality in Acton is modular and built around the acton_debug crate. It bridges the gap between the TON Virtual Machine (TVM) and modern development environments.

Component Responsibility Primary Source File
acton_debug crate DAP server implementation, state reconstruction, and TVM value rendering [crates/acton-debug/src/lib.rs](https://github.com/ton-blockchain/acton/blob/master/crates/acton-debug/src/lib.rs)
Script debugger Launches live VM execution with debugging enabled [src/commands/script/mod.rs](https://github.com/ton-blockchain/acton/blob/master/src/commands/script/mod.rs) (lines 39-44, 64-78)
Retrace debugger Replays historical transaction traces [src/commands/retrace/mod.rs](https://github.com/ton-blockchain/acton/blob/master/src/commands/retrace/mod.rs) (lines 30-38, 87-99)
Replayer engine Converts VM events into source-level debug events [crates/acton-debug/src/core/replayer.rs](https://github.com/ton-blockchain/acton/blob/master/crates/acton-debug/src/core/replayer.rs)

The system supports two primary workflows: debugging a live script execution and replaying a previously recorded transaction trace.

How the Debugger Works

When you invoke Acton with the --debug flag, the CLI initializes a DAP server that translates between your IDE’s requests and the contract’s execution state.

The process follows these stages:

  1. Listener Reservation – The CLI calls reserve_dap_listener(port) (as seen in src/commands/script/mod.rs line 39) to open a TCP socket for the IDE to connect.

  2. Execution Context Setup –

    • For live execution: A StepGetExecutor is wrapped in a TolkReplayer via TolkReplayer::new_live_vm, creating a ReplayerDebugSession that implements the DAP loop.
    • For trace replay: VM logs are fed into TolkReplayer::new(&source_map, vm_logs) and served via serve_single_replayer_dap (line 97 in retrace/mod.rs).
  3. DAP Request Handling – The ReplayerDebugSession processes standard DAP requests like "next" or "stepIn", driving the replayer forward and updating the call-frame stack.

  4. Variable Rendering – TVM stack values are converted to human-readable formats using the rendering utilities in [crates/acton-debug/src/core/types_render.rs](https://github.com/ton-blockchain/acton/blob/master/crates/acton-debug/src/core/types_render.rs), producing RenderedValue objects displayed in your IDE’s Variables pane.

  5. Cleanup – When execution completes or the session ends, the DebugExecutorHandle drops, closing the TCP listener and returning control to the shell.

Debugging Live Contract Scripts

To debug a contract script during development, use the script command with the --debug flag. This starts a live TVM instance and pauses execution until a debugger client connects.

acton script contracts/counter.tolk \
    --net testnet \
    --debug \
    --debug-port 5678

Key flags:

  • --debug – Enables the debugging mode and initializes the DAP server.
  • --debug-port <port> – Specifies the TCP port for the DAP listener (defaults to an ephemeral port if omitted).

Once running, Acton prints a message indicating it is waiting for a debugger connection on the specified port.

Debugging Transaction Traces

For post-mortem analysis of failed transactions or historical execution analysis, use the retrace command. This replays VM logs from a specific transaction hash without requiring a live network connection.

acton retrace 0x1234abcd5678ef90 \
    --contract Counter \
    --debug \
    --debug-port 5678

When to use retrace debugging:

  • Analyzing failed transactions on mainnet or testnet
  • Debugging gas consumption issues in historical executions
  • Stepping through execution without network latency

The replayer reconstructs the execution state from the trace, allowing you to set breakpoints at specific source lines and inspect the stack exactly as it existed during the original transaction.

Configuring Your IDE for Acton DAP

Any editor supporting the Debug Adapter Protocol can connect to Acton. The debugger uses standard DAP wire formats, making configuration straightforward.

VS Code Configuration

Add the following to your .vscode/launch.json to attach to an Acton debugging session:

{
  "type": "node",
  "request": "attach",
  "name": "Attach to Acton Debugger",
  "port": 5678,
  "host": "127.0.0.1",
  "restart": false,
  "protocol": "inspector"
}

Neovim Configuration

If using Neovim with nvim-dap, configure an attach adapter pointing to localhost:5678 with the vscode-debugadapter protocol. The configuration mirrors the VS Code example above, using the same port and host settings.

Embedding Debugging in Custom Tools

The debugging primitives are exposed as a public Rust API in the acton_debug crate, allowing you to build custom debugging tools or integrate Acton debugging into larger test frameworks.

use acton_debug::{reserve_dap_listener, start_dap_server_with_listener, ReplayerDebugSession};
use acton_debug::replayer::TolkReplayer;

// Reserve a TCP listener for the DAP client
let listener = reserve_dap_listener(12345)?;

// Build replayer from source map and VM logs
let source_map = /* tolk_compiler::SourceMap */;
let vm_logs = /* String containing TVM log output */;
let replayer = TolkReplayer::new(&source_map, &vm_logs)?;

// Initialize DAP transport and session
let transport = start_dap_server_with_listener(listener)?;
let mut session = ReplayerDebugSession::new(transport, replayer, "my_contract".into());

// Block and handle DAP requests
session.run()?;

This pattern is identical to how the CLI implements the script and retrace commands, utilizing DebugCtx::new(&mut dbg_session) to inject debugging capabilities into the execution context.

Key Source Files Reference

Understanding these files helps when extending the debugger or troubleshooting issues:

Summary

  • Enable debugging by adding --debug to acton script or acton retrace commands, optionally specifying --debug-port for the DAP listener.
  • Connect any DAP-compatible IDE (VS Code, Neovim, JetBrains) to localhost:<port> to access breakpoints, stepping, and variable inspection.
  • Choose live debugging for active development and interactive testing, or trace replay for analyzing historical transactions without network dependencies.
  • Leverage the Rust API via acton_debug crate primitives like reserve_dap_listener, TolkReplayer, and ReplayerDebugSession for custom tooling integration.

Frequently Asked Questions

What is the Debug Adapter Protocol (DAP) in Acton?

The Debug Adapter Protocol is a standardized JSON-based protocol that decouples debuggers from IDEs. Acton implements a DAP server in the acton_debug crate, allowing any editor supporting DAP (VS Code, Neovim, Emacs) to debug TON smart contracts without editor-specific plugins. The server translates IDE requests like "step over" into TVM execution steps and returns formatted variable states.

How do I debug a failed transaction on TON mainnet?

Use the acton retrace command with the transaction hash and the --debug flag. This downloads the VM execution trace and replays it locally, allowing you to set breakpoints and inspect the stack state at any point during the failed execution. You must specify the contract name with --contract to ensure the debugger maps bytecode back to the correct source files.

Can I debug Tolk source code or only TVM assembly?

Acton debugs at the Tolk source level. The TolkReplayer uses the compiler's SourceMap to map VM program counters back to original Tolk source lines, variables, and function names. When you step through execution in your IDE, you see Tolk code, not TVM assembly, and variable watches show Tolk variable values rendered from the TVM stack.

What port should I use for the debugger?

You can use any available TCP port. If you omit --debug-port, Acton selects an ephemeral port automatically. Standard development environments typically use ports 5678, 9229, or 1025-65535. Ensure the port is not blocked by a firewall and matches the port specified in your IDE's debug configuration (e.g., launch.json in VS Code).

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →