How Acton Leverages TON Asynchronous Message Processing for Smart Contract Debugging
Acton utilizes Rust's async/await patterns and the Tokio runtime to mirror TON's native asynchronous message passing architecture, enabling non-blocking blockchain communication, parallel VM emulation, and responsive developer tooling.
Acton is a Rust-based development toolkit designed specifically for the TON blockchain ecosystem. Unlike traditional blockchain development tools that rely on synchronous execution models, Acton embraces TON's fundamental architecture of asynchronous message processing to provide developers with non-blocking contract debugging and deployment workflows that align with the chain's queued message validation system.
Asynchronous Blockchain State Fetching
Acton communicates with TON network data through asynchronous HTTP clients that prevent I/O operations from blocking the main execution thread. The TonCenterClient implementation in crates/ton-retrace/src/remote.rs exposes methods like get_transactions and get_blocks as asynchronous functions that retrieve transaction logs and contract libraries while allowing other tasks to proceed.
This approach enables Acton to parse source files and handle user commands concurrently while waiting for network responses from TON-Center API endpoints.
// In crates/ton-retrace/src/remote.rs
pub(crate) async fn get_transactions(
&self,
hash: &str,
limit: u32,
) -> anyhow::Result<TransactionData> {
// Build request, add API key if present
let mut request = self
.client
.get(format!("{}/transactions", self.base_url))
.header(USER_AGENT, user_agent())
.query(&[("hash", hash), ("limit", &limit.to_string())]);
// Respect rate‑limit before sending
self.maybe_wait_for_rate_limit().await;
let response = request.send().await?;
// ...
}
The client also implements maybe_wait_for_rate_limit to respect TON-Center API constraints through asynchronous sleeping, ensuring the tool remains responsive even when throttling requests.
Non-Blocking VM Emulation with Tokio
When re-tracing contract execution, Acton spawns a dedicated Tokio runtime to handle CPU-intensive VM emulation without freezing the CLI interface. The src/commands/retrace/mod.rs file orchestrates this by creating a multi-threaded runtime and executing the retrace logic within an asynchronous future.
This architecture allows the VM to emit log messages such as process send message … while the main thread remains available for user interaction or additional processing.
let rt = tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()?;
// Try each network (mainnet & testnet)
for network in networks {
let retrace_future = retrace(network.clone(), &hash, HashMap::new());
match rt.block_on(retrace_future) {
Ok(result) => { /* handle success */ }
Err(e) => { /* store error and try next network */ }
}
}
The use of rt.block_on() ensures that heavy-weight VM emulation runs within the async ecosystem, maintaining the non-blocking characteristics essential for TON's message processing model.
Asynchronous TON Connect UI Handling
Acton's web-based wallet integration leverages browser-side asynchronous JavaScript to communicate with the HTTP API without page reloads. The src/tonconnect.rs file embeds async helper functions like postJson and storage.getItem that dispatch UI actions such as wallet connections and state persistence in a non-blocking manner.
This mirrors TON's on-chain asynchronous pattern where messages are queued and processed independently of the sender's execution flow.
const postJson = async (url, body) => {
const response = await fetch(url, {
method: 'POST',
headers: {'content-type': 'application/json', ...apiHeaders()},
body: JSON.stringify(body),
});
if (!response.ok) {
throw new Error(await response.text());
}
};
By implementing async fetches on the client side, Acton ensures that wallet connection workflows remain responsive while waiting for blockchain confirmations or user approvals.
Rate-Limited External Message Broadcasting
When submitting BOCs (Bags of Cells) to the TON network, Acton handles the uncertainty of message acceptance through asynchronous error handling and deferred processing. The src/external_send.rs module formats error scenarios and suggests fixes for failed transmissions, while the underlying TonCenterClient manages rate limiting through async-aware delays.
async fn maybe_wait_for_rate_limit(&self) {
if self.api_key.is_some() { return; }
let mut last = TONCENTER_REQUEST_GATE.lock().await;
if let Some(prev) = *last {
let elapsed = prev.elapsed();
if elapsed < TONCENTER_MIN_REQUEST_INTERVAL {
tokio::time::sleep(TONCENTER_MIN_REQUEST_INTERVAL - elapsed).await;
}
}
*last = Some(Instant::now());
}
This implementation respects TON's behavior where messages may sit in the mempool before validator pickup, using tokio::time::sleep to pause execution without blocking the entire application.
Debug Sessions with Concurrent Request Processing
Acton supports asynchronous debugging workflows through process_incoming_requests in src/context.rs. When running acton run --debug, the tool enters a listening state that waits for debug-related messages from the blockchain emulator using async request processing.
Because the underlying handler operates asynchronously, developers can attach debuggers, set breakpoints, or step through contract execution without halting the CLI or blocking other operations. This enables concurrent debugging sessions where multiple contracts can be analyzed simultaneously while maintaining responsiveness.
Summary
Acton's architecture fundamentally embraces TON's asynchronous message processing through several key implementations:
- TonCenterClient uses
async fnHTTP calls with mutex-guarded rate limiting for non-blocking blockchain data retrieval - Retrace engine leverages Tokio's multi-threaded runtime to execute VM emulation in async futures
- TON Connect UI implements browser-side async/await patterns for seamless wallet integration
- External send module handles deferred message acceptance and network delays through asynchronous error handling
- Debug context processes incoming requests asynchronously, allowing concurrent debugging sessions
Frequently Asked Questions
How does Acton prevent network calls from freezing the CLI interface?
Acton implements all network communication through Rust's async/await syntax using the Tokio runtime. Functions like TonCenterClient::get_transactions in crates/ton-retrace/src/remote.rs are defined as asynchronous, allowing the executor to yield control back to the main thread while waiting for TON-Center API responses. This ensures that parsing operations and user input handling continue uninterrupted during network latency.
What runtime does Acton use for asynchronous smart contract emulation?
Acton utilizes the Tokio runtime specifically configured as a multi-threaded executor via tokio::runtime::Builder::new_multi_thread(). As shown in src/commands/retrace/mod.rs, Acton builds this runtime explicitly and uses rt.block_on() to execute the retrace future, enabling CPU-intensive VM emulation to run concurrently without blocking the main CLI thread.
Can Acton process multiple contract debugging sessions simultaneously?
Yes, Acton supports concurrent debugging through asynchronous request processing in src/context.rs. When the --debug flag is enabled, process_incoming_requests(true) handles incoming emulator messages asynchronously, allowing developers to attach to multiple contracts or step through execution while the CLI remains responsive to new commands.
How does Acton's async architecture benefit TON Connect wallet integrations?
Acton embeds asynchronous JavaScript functions such as postJson and storage.getItem directly in the TON Connect UI code within src/tonconnect.rs. These async helpers enable the browser interface to communicate with Acton's HTTP API, persist connection state, and handle wallet callbacks without page reloads, perfectly aligning with TON's asynchronous message delivery model.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →