Abstract
The Open Network (TON) is a decentralized network designed to enable the creation and operation of various services, including decentralized applications, smart contracts, and value transfers. One of the core functionalities of TON is the ability to send messages between accounts and smart contracts. This article delves into the intricacies of the TON message sending process by analyzing the source code of the exec_send_message
function, which is pivotal in the TON Virtual Machine (VM). We aim to provide a comprehensive understanding of the underlying principles that govern message delivery within the TON network.
Source Code Overview
The exec_send_message
function is a critical component of the TON VM’s operation, responsible for the actual sending of messages. It is a complex function that interacts with multiple components of the VM, including the stack, storage, and configuration parameters. Below is a high-level breakdown of the function’s structure and its main components:
int exec_send_message(VmState* st) {
// Function implementation
}
The function begins by logging the execution of the SENDMSG
operation, followed by a series of checks and operations that ensure the message is constructed and sent according to the TON protocol specifications.
Analysis of Message Sending Principles
1. Parameter Acquisition and Verification
The process of sending a message in TON starts with the acquisition of parameters from the VM’s stack. These parameters define the mode of the message and the content of the message itself.
- Retrieving Parameters: The function extracts the sending mode (
mode
) and the message cell (msg_cell
) from the stack. The mode determines how the message will be processed and sent, while the message cell contains the actual data of the message. - Mode Verification: The function checks if the mode is within the valid range (0 to 2047). If the mode is not valid, the function throws an error, preventing the message from being sent with incorrect parameters.
- Address Retrieval and Verification: The function retrieves the sender’s address (
my_addr
) from the VM’s parameters. This address is crucial for identifying the sender and is used in various checks throughout the message sending process. If the address is not valid, the function throws an error, indicating an invalid parameter.
2. Message Parsing
The next step is to parse the message cell to extract the relevant information that will be used to construct the message.
- Message Type Determination: The function determines whether the message is an external message (sent to another account) or an internal message (sent within the same account, possibly to a smart contract).
- Content Extraction: Depending on the message type, the function extracts the destination address (
dest
), the value to be transferred (value
), and the fees associated with the message (fwd_fee
,ihr_fee
). For external messages, the value and fees are set to zero, while for internal messages, these values are extracted from the message cell. - Workchain Identification: The function checks if the message is being sent on the masterchain or a shardchain. This distinction is important because it affects the configuration parameters and fees associated with the message.
3. Fee Calculation
TON is designed to be a resource-efficient network, and as such, sending messages incurs fees based on the resources used.
- Configuration Retrieval: The function retrieves the message pricing and size limit configurations. These configurations are used to calculate the fees and ensure that the message does not exceed the network’s limits.
- Resource Calculation: The function calculates the number of cells and bits used by the message. This calculation is essential for determining the correct fees.
- Fee Calculation: The function calculates the forwarding fee (
fwd_fee
) and the immediate handling fee (ihr_fee
) based on the message size and the configuration parameters. The fees are calculated to ensure that the sender pays for the resources they consume.
4. Value Handling
The value associated with a message is the amount of TON Crystal (TON) or other supported currencies that are being transferred.
- Value Determination: Depending on the mode specified, the function determines the value to be sent with the message. This can be the balance of the contract, the value of the incoming message, or a specified amount.
- Extra Currencies: The function checks for the presence of extra currencies and handles them accordingly. This is important for supporting multi-currency transactions within the TON network.
5. Message Structure Optimization
TON has strict limits on the size of messages. If a message is too large, it must be optimized to fit within these limits.
- Initialization and Body References: The function checks if the initialization (
init
) and body (body
) parts of the message need to be referenced. If the message is too large, these parts may need to be stored separately to reduce the size of the root cell. - Optimization: If the message root cell exceeds the maximum allowed bits or references, the function performs optimization by converting the
init
andbody
parts into references. This process may increase the number of cells and bits used by the message, which requires a recalculation of the fees.
6. Fee Summary and Output
Once the message structure is optimized and the fees are calculated, the function proceeds to summarize the fees and prepare the message for sending.
- Fee Summation: The function calculates the total fee by summing the forwarding fee and the immediate handling fee. This total fee is then pushed onto the stack for future use.
- Output Preparation: If the send flag is true, indicating that the message should be sent, the function constructs an output action cell. This cell contains all the necessary information for the message to be processed and sent by the network.
- Action Installation: The function installs the output action cell into the output action list, which is a queue of actions to be executed by the VM. This finalizes the message sending process within the VM.
Detailed Breakdown of Key Components
Logging and Stack Operations
The function starts by logging the execution of the SENDMSG
operation, which is crucial for debugging and monitoring the VM’s operations. It then interacts with the VM’s stack to retrieve the necessary parameters.
VM_LOG(st) << "execute SENDMSG";
Stack& stack = st->get_stack();
stack.check_underflow(2);
Mode and Message Cell Extraction
The mode and message cell are extracted from the stack using pop_smallint_range
and pop_cell
methods. The mode is then checked to determine if the message is an external or internal message.
int mode = stack.pop_smallint_range(2047);
bool send = !(mode & 1024);
mode &= ~1024;
if (mode >= 256) {
throw VmError{Excno::range_chk};
}
Ref<Cell> msg_cell = stack.pop_cell();
Message Parsing and Fee Calculation
The message cell is parsed to extract the destination address, value, and fees. The function then retrieves the configuration parameters and calculates the fees based on the message’s size.
block::gen::MessageRelaxed::Record msg;
if (!tlb::type_unpack_cell(msg_cell, block::gen::t_MessageRelaxed_Any, msg)) {
throw VmError{Excno::unknown, "invalid message"};
}
// ... Fee calculation logic ...
Value Handling and Message Optimization
The function handles the value associated with the message and checks if the message needs to be optimized to fit within the network’s size limits.
if (have_init && !init_ref && (msg_root_bits() > Cell::max_bits || msg_root_refs() > Cell::max_refs)) {
init_ref = true;
// ... Optimization logic ...
}
Fee Summation and Output Action Installation
Finally, the function summarizes the fees, constructs the output action cell, and installs it into the output action list.
stack.push_int(fwd_fee + ihr_fee);
if (send) {
CellBuilder cb;
// ... Output action cell construction ...
return install_output_action(st, cb.finalize());
}
Conclusion
The exec_send_message
function in the TON VM is a sophisticated mechanism that ensures the secure, efficient, and cost-effective transmission of messages across the network. By dissecting the source code, we have illuminated the intricate steps involved in sending a message, from parameter acquisition and message parsing to fee calculation and output action installation.
Understanding these principles is vital for developers and users of the TON network. It enables the creation of robust smart contracts and decentralized applications that can interact with the network in a predictable and efficient manner. The TON network’s design, which emphasizes resource management and fee control, is a testament to its commitment to scalability and sustainability in the blockchain ecosystem.
As the TON network continues to evolve, it will be important for the community to maintain a deep understanding of these underlying principles to ensure the network’s growth and success. By doing so, TON can remain at the forefront of innovation in decentralized technologies, offering a platform where users can transact, create, and collaborate with confidence and efficiency.