Skip to main content

TVM upgrade Apr 2024

Introduction of new instructions for low fees calculation

tip

This upgrade is active on the Mainnet since Mar 16, 2024. See the details here. A preview of the update for blueprints is available in the following packages: @ton/[email protected], @ton-community/[email protected], and @ton-community/[email protected].

This update is enabled with Config8 version >= 6.

c7

The c7 tuple has been extended from 14 to 16 elements as follows:

  • 14: a tuple containing various config parameters as cell slices. If a parameter is absent from the config, its value is null.
    • 0: StoragePrices from ConfigParam 18. Not the entire dictionary but the specific StoragePrices entry corresponding to the current time.
    • 1: ConfigParam 19 - global ID.
    • 2: ConfigParam 20 - MasterChain gas prices.
    • 3: ConfigParam 21 - gas prices.
    • 4: ConfigParam 24 - MasterChain forward fees.
    • 5: ConfigParam 25 - forward fees.
    • 6: ConfigParam 43 - size limits.
  • 15: "Due payment" - current debt for the storage fee in nanotons. asm opcode: DUEPAYMENT.
  • 16: "Precompiled gas usage" - gas usage for the current contract if precompiled as defined in ConfigParam 45; null otherwise. asm opcode: GETPRECOMPILEDGAS.

The extension of c7 with unpacked config parameters aims to improve efficiency. Now, this data is retrieved from the global configuration by the transaction executor, making it readily available in the executor's memory. Previously, the smart contract had to fetch each parameter one by one from the configuration dictionary. This method was costly and gas-inefficient, as the cost depended on the number of parameters.

Due payment field

The due payment field is crucial for accurately managing storage fees. Here's how it works:

  • When a message is sent in the default (bounceable) mode to a smart contract, storage fees are either:
    • Deducted, or
    • Added to the due_payment field, which stores the storage fee-related debt.
  • These adjustments happen before the message value is added to the contract's balance.
  • If the contract processes the message and sends back excess gas with mode=64, the following occurs:
    • If the contract's balance reaches 0, storage fees will accumulate in the due_payment field on subsequent transactions instead of being deducted from incoming messages.
    • This results in the debt silently accumulating until the account is frozen.

The DUEPAYMENT opcode allows developers to explicitly account for or withhold storage fees, preventing potential issues.

New opcodes

Opcodes for new c7 values

Each opcode consumes 26 gas, except for SENDMSG, due to cell operations.

Fift syntaxStackDescription
UNPACKEDCONFIGTUPLE- cRetrieves the tuple of config slices from c7.
DUEPAYMENT- iRetrieves the value of due payment from c7.
GLOBALID- iRetrieves ConfigParam 19 from c7 instead of the configuration dictionary.
SENDMSGmsg mode - iRetrieves ConfigParam 24/25 (message prices) and ConfigParam 43 (max_msg_cells) from c7 rather than from the config dictionary.

Opcodes to process config parameters

Introducing the configuration tuple in the TON transaction executor makes parsing fee parameters more cost-effective. However, smart contracts may require updates to interpret new configuration parameter constructors as they are introduced.

To address this, special opcodes for fee calculation are introduced. These opcodes:

  • Retrieve parameters from c7.
  • Calculate fees in the same way as the executor.

As new parameter constructors are introduced, these opcodes are updated accordingly. This ensures that smart contracts can rely on these instructions for fee calculation without needing to interpret each new constructor.

Each opcode consumes 26 gas.

Fift syntaxStackDescription
GETGASFEEgas_used is_mc - priceCalculates the computation cost in nanotons for a transaction that consumes gas_used gas.
GETSTORAGEFEEcells bits seconds is_mc - priceCalculates the storage fees in nanotons for the contract based on current storage prices.cells and bits represent the size of the AccountState with deduplication, including the root cell.
GETFORWARDFEEcells bits is_mc - priceCalculates forward fees in nanotons for an outgoing message. is_mc is true if the source or the destination is in the MasterChain and false if both are in the basechain. Note: cells and bits in the message should be counted with deduplication and the root-not-counted rules.
GETPRECOMPILEDGAS- nullReserved; currently returns null. It returns the cost of contract execution in gas units if the contract is precompiled.
GETORIGINALFWDFEEfwd_fee is_mc - orig_fwd_feeCalculates fwd_fee * 2^16 / first_frac. It can be used to get the original fwd_fee of the message as a replacement for hardcoded values like this from the fwd_fee parsed from an incoming message. is_mc is true if the source or destination is in the MasterChain and false if both are in the basechain.
GETGASFEESIMPLEgas_used is_mc - priceCalculates the additional computation cost in nanotons for a transaction that consumes additional gas_used gas. This is the same as GETGASFEE, but without the flat price calculated as (gas_used * price) / 2^16.
GETFORWARDFEESIMPLEcells bits is_mc - priceCalculates the additional forward cost in nanotons for a message containing additional cells and bits. This is the same as GETFORWARDFEE, but without the lump price calculated as (bits * bit_price + cells * cell_price) / 2^16).

Note: gas_used, cells, bits, and time_delta are integers in the range 0..2^63-1.

Cell-level operations

These operations work with Merkle proofs, where cells can have a non-zero level and multiple hashes. Each operation consumes 26 gas.

Fift syntaxStackDescription
CLEVELcell - levelReturns the level of the cell.
CLEVELMASKcell - level_maskReturns the level mask of the cell.
i CHASHIcell - hashReturns the i-th hash of the cell.
i CDEPTHIcell - depthReturns the i-th depth of the cell.
CHASHIXcell i - depthReturns the i-th hash of the cell.
CDEPTHIXcell i - depthReturns the i-th depth of the cell.

The value of i is in the range 0..3.