diff --git a/docs/src/content/docs/book/exit-codes.mdx b/docs/src/content/docs/book/exit-codes.mdx index 1f1516582..399734809 100644 --- a/docs/src/content/docs/book/exit-codes.mdx +++ b/docs/src/content/docs/book/exit-codes.mdx @@ -13,7 +13,7 @@ The range from $256$ to $65535$ is free for developer-defined exit codes. :::note - While an exit (or [result](#action)) code is a $32$-bit signed integer on TON Blockchain, an attempt to [throw](/ref/core-debug) an exit code out of bounds of the $16$-bit unsigned integer ($0 - 65535$) will cause an error with [exit code 5](#5). That's done intentionally to prevent some exit codes from being produced artificially, such as the [exit code -14](#13). + While an exit (or [result](#action)) code is a $32$-bit signed integer on TON Blockchain, an attempt to [throw](/ref/core-debug) an exit code out of bounds of the $16$-bit unsigned integer ($0 - 65535$) will cause an error with [exit code 5](#5). That's done intentionally to prevent some exit codes from being produced artificially, such as the [exit code -14](#-14). ::: @@ -26,10 +26,10 @@ The table doesn't list the exit code of the [`require()`](/ref/core-debug#requir Exit code | Origin | Brief description :------------ | :---------------------------------- | :---------------- [$0$](#0) | [Compute][c] and [action][a] phases | Standard successful execution exit code. -[$1$](#1) | [Compute phase][c] | Alternative successful execution exit code. Reserved, but never occurs. -[$2$](#2) | [Compute phase][c] | Stack underflow. Last op-code consumed more elements than there are on the stacks. -[$3$](#3) | [Compute phase][c] | Stack overflow. More values have been stored on a stack than allowed by this version of TVM. -[$4$](#4) | [Compute phase][c] | Integer overflow. Integer does not fit into $−2^{256} ≤ x < 2^{256}$ or a division by zero has occurred. +[$1$](#1) | [Compute phase][c] | Alternative successful execution exit code. Reserved, but doesn't occur. +[$2$](#2) | [Compute phase][c] | Stack underflow. +[$3$](#3) | [Compute phase][c] | Stack overflow. +[$4$](#4) | [Compute phase][c] | Integer overflow — it did not fit into $−2^{256} ≤ x < 2^{256}$ or a division by zero has occurred. [$5$](#5) | [Compute phase][c] | Range check error — some integer is out of its expected range. [$6$](#6) | [Compute phase][c] | Invalid opcode. Instruction is unknown in the current [TVM][tvm] version. [$7$](#7) | [Compute phase][c] | Type check error. An argument to a primitive is of an incorrect value type. @@ -39,14 +39,14 @@ Exit code | Origin | Brief description [$11$](#11) | [Compute phase][c] | Described in TVM docs as "Unknown error, may be thrown by user programs", although most commonly used for problems with queueing a message send. [$12$](#12) | [Compute phase][c] | Fatal error. Thrown by [TVM][tvm] in situations deemed impossible. [$13$](#13) | [Compute phase][c] | Out of gas error. Thrown by [TVM][tvm] when the remaining gas becomes negative. -[$-14$](#13) | [Compute phase][c] | Same as $13$. Negative, so that it cannot be faked. +[$-14$](#-14) | [Compute phase][c] | Same as $13$. Negative, so that it cannot be faked. [$14$](#14) | [Compute phase][c] | VM virtualization error. Reserved, but never thrown. [$32$](#32) | [Action phase][a] | Action list is invalid. Set during action phase if c5 register after execution contains unparsable object. [$33$](#33) | [Action phase][a] | Action list is too long. [$34$](#34) | [Action phase][a] | Action is invalid or not supported. Set during action phase if current action cannot be applied. [$35$](#35) | [Action phase][a] | Invalid source address in outbound message. [$36$](#36) | [Action phase][a] | Invalid destination address in outbound message. -[$37$](#37) | [Action phase][a] | Message sends too much TON or there is not enough TON after deducting fees. +[$37$](#37) | [Action phase][a] | Not enough Toncoin. [$38$](#38) | [Action phase][a] | Not enough extra currencies. [$39$](#39) | [Action phase][a] | Outbound message does not fit into a cell after rewriting. [$40$](#40) | [Action phase][a] | Cannot process a message — not enough funds, the message is too large or it merkle depth is too big. @@ -128,12 +128,60 @@ This is an alternative exit code for the successful execution of the [compute ph ### 2: Stack underflow {#2} -TODO: edit. -TODO: update the table of exit codes on top, enhance short descriptions. +If some operation consumed more elements than there were on the stacks, the error with exit code $2$ is thrown: `Stack underflow`. + +```tact +asm fun drop() { DROP } + +contract Loot { + receive("I solemnly swear that I'm up to no good") { + try { + // Removes 100 elements from the stack, causing an underflow + repeat (100) { drop() } + } catch (exitCode) { + exitCode; // 2 + } + } +} +``` + +:::note[Useful links:] + + [TVM is a stack machine](https://docs.ton.org/learn/tvm-instructions/tvm-overview#tvm-is-a-stack-machine) in TON Docs. + +::: ### 3: Stack overflow {#3} -TODO: edit. +If there are too many elements copied into a closure continuation or stored on the stack, an error with exit code $3$ is thrown: `Stack overflow`. Won't ever occur, unless you're deep in [Fift and TVM assembly](https://docs.ton.org/develop/fift/fift-and-tvm-assembly) trenches: + +```tact +// Remember kids, don't try to overflow the stack at home! +asm fun stackOverflow() { + <{ + }>CONT // c + 0 SETNUMARGS // c' + 2 PUSHINT // c' 2 + SWAP // 2 c' + 1 -1 SETCONTARGS // <- this blows up +} + +contract ItsSoOver { + receive("I solemnly swear that I'm up to no good") { + try { + stackOverflow(); + } catch (exitCode) { + exitCode; // 3 + } + } +} +``` + +:::note[Useful links:] + + [TVM is a stack machine](https://docs.ton.org/learn/tvm-instructions/tvm-overview#tvm-is-a-stack-machine) in TON Docs. + +::: ### 4: Integer overflow {#4} @@ -159,26 +207,6 @@ try { Range check error — some integer is out of its expected range. I.e. any attempt to store an unexpected amount of data or specify an out-of-bounds value throws an error with exit code $5$: `Integer out of range`. -Example of storing too much: - -```tact -contract RangeOver { - val: Int as uint8; // from 0 to 255 inclusive - - init() { - self.val = 255; // fits just fine - } - - receive("I solemnly swear that I'm up to no good") { - try { - self.val = 512; // integer out of the expected range! - } catch (exitCode) { - exitCode; // 5 - } - } -} -``` - Examples of specifying an out-of-bounds value: ```tact @@ -194,7 +222,7 @@ try { try { // Builder.storeUint() function can only use up to 256 bits, so 512 is too much: - let s: Slice = beginCell().storeUint(0, 512).asSlice(); + let s: Slice = beginCell().storeUint(-1, 512).asSlice(); } catch (exitCode) { exitCode; // 5 } @@ -258,20 +286,24 @@ Fatal error. Thrown by TVM in situations deemed impossible. ### 13: Out of gas error {#13} -TODO: edit. Cannot be thrown in the contracts and therefore can only occur when [TVM][tvm] hits it. +If there isn't enough gas to end computations in the [compute phase](#compute), the error with exit code $13$ is thrown: `Out of gas error`. -If there isn't enough gas to finish computations in the [compute phase](#compute), the error with exit code $13$ is thrown: `Out of gas error`. +But this code isn't immediately shown as is — instead, the bitwise NOT operation is applied, which changes the value from $13$ to $-14$. And only then the code is shown. -During processing, the NOT operation is applied to this value, which changes this value to -14. This is done so that this exit code cannot be faked using the throw function, since all such functions accept only positive values for the exit code as it was discussed previously. +That's done in order to prevent the resulting code ($-14$) from being produced artificially in user contracts, since all functions that can [throw an exit code](/ref/core-debug) can only specify integers in the range from $0$ to $65535$ inclusive. ```tact try { repeat (pow(2, 31) - 1) {} } catch (exitCode) { - exitCode; // 13 here, but will yield to -14 TODO: double-check + exitCode; // -14 } ``` +### -14: Out of gas error {#-14} + +See [exit code 13](#13). + ### 14: Virtualization error {#14} Virtualization error, related to [prunned branch cells](/book/cells#cells-kinds). Reserved, but never thrown. @@ -284,12 +316,13 @@ Some actions may fail during processing, in which case those actions may be skip ### 32: Action list is invalid {#32} -TODO: edit. +If the list of actions contains [exotic cells](/book/cells#cells-kinds), an action entry cell does not have references or some action entry cell couldn't be parsed, an error with exit code $32$ is thrown: `Action list is invalid`. -1. no special cells (not-ordinary ones) -2. no refs +:::note -{/* See ton/crypto/block/transactions.cpp: prepare_action_phase */} + Aside from this exit code there's a boolean flag `valid`, which you can find under `description.actionPhase.valid` in the transaction results when working with [Sandbox and Blueprint](#blueprint). This flag can be set to `false` even when there is some other exit code thrown from the action phase. + +::: ### 33: Action list is too long {#33} @@ -315,53 +348,66 @@ nativeSendMessage(emptyCell(), 0); // won't fail in compute phase, ### 35: Invalid source address in outbound message {#35} -TODO: edit. +If the source address in the outbound message isn't equal to [`addr_none`](https://docs.ton.org/develop/data-formats/msg-tlb#addr_none00) or to the address of the contract that initiated this message, an error with exit code $35$ is thrown: `Invalid source address in outbound message`. ### 36: Invalid destination address in outbound message {#36} -TODO: edit. +If the destination address in the outbound message is invalid, e.g. it doesn't conform to the relevant [TL-B][tlb] schemas, contains unknown workchain ID or it has invalid length for the given workchain, an error with exit code $36$ is thrown: `Invalid destination address in outbound message`. -{/* in crypto/block/transaction.cpp: try_action_send_msg, check_skip_invalid(36) */} +:::note -### 37: Not enough TON {#37} + If the [optional flag +2](/book/message-mode#optional-flags) is set, this error won't be thrown and the given message won't be sent. -TODO: edit. +::: -It means that there isn't enough TON to send the specified amount of it. +### 37: Not enough Toncoin {#37} -Example: +If all the inbound message value with [base mode 64](/book/message-mode#base-modes) set has been already consumed and there's not enough funds to pay for the failed action, or the [TL-B][tlb] layout of the provided value ([`CurrencyCollection`](https://docs.ton.org/develop/data-formats/msg-tlb#currencycollection)) is invalid, or there's not enough funds to pay [forward fees](https://docs.ton.org/develop/smart-contracts/guidelines/processing) or not enough funds after deducting fees, an error with exit code $37$ is thrown: `Not enough Toncoin`. -```tact -send(SendParameters{to: context().sender, value: ton("10")}); -``` +:::note -### 38: Not enough extra-currencies {#38} + If the [optional flag +2](/book/message-mode#optional-flags) is set, this error won't be thrown and the given message won't be sent. -TODO: edit. +::: + +### 38: Not enough extra currencies {#38} + +Besides the native currency, Toncoin, TON Blockchain supports up to $2^{32}$ extra currencies. They differ from making new [Jettons](/cookbook/jettons) because extra currencies are natively supported — one can potentially just specify an extra [hashmap](https://docs.ton.org/develop/data-formats/tl-b-types#hashmap) of extra currency amounts in addition to the Toncoin amount in the internal message to another contract. Unlike Jettons, extra currencies can only be stored and transferred and do not have any other functionality. + +At the moment, **there are no extra currencies** on TON Blockchain, but the exit code $38$ in cases when there is not enough extra currency to send the specified amount of it is already reserved: `Not enough extra currencies`. + +:::note[Useful links:] + + [Extra currencies](https://docs.ton.org/develop/dapps/defi/coins) in TON Docs.\ + [Extra currency mining](https://docs.ton.org/develop/research-and-development/minter-flow) in TON Docs. + +::: ### 39: Outbound message doesn't fit into a cell {#39} -TODO: edit. +When processing the message, TON Blockchain tries to pack it according to the [relevant TL-B schemas](https://docs.ton.org/develop/data-formats/msg-tlb), and if it cannot an error with exit code $39$ is thrown: `Outbound message doesn't fit into a cell`. -Outbound message does not fit into a cell after rewriting. +:::note -### 40: Cannot process a message {#40} + If attempts at sending the message fail multiple times and the [optional flag +2](/book/message-mode#optional-flags) is set, this error won't be thrown and the given message won't be sent. -TODO: edit. +::: + +### 40: Cannot process a message {#40} -Cannot process a message — not enough funds to process, the message is too large or it merkle depth is too big. +If there would not be enough funds to process all the cells in a message, the message is too large or its merkle depth is too big, an error with exit code $40$ is thrown: `Cannot process a message`. ### 41: Library reference is null {#41} -Library reference was required during library change action, but it was null. +If the library reference was required during library change action, but it was null, an error with exit code $41$ is thrown: `Library reference is null`. ### 42: Library change action error {#42} -Error during an attempt at library change action. +If there's an error during an attempt at library change action, an error with exit code $42$ is thrown: `Library change action error`. ### 43: Library limits exceeded {#43} -Maximum number of cells in the library is exceeded or the maximum depth of the Merkle tree is exceeded. +If the maximum number of cells in the library is exceeded or the maximum depth of the Merkle tree is exceeded, an error with exit code $43$ is thrown: `Library limits exceeded`. ### 50: Account state size exceeded limits {#50} @@ -514,6 +560,7 @@ try { [slice]: /book/cells#slices [message]: /book/structs-and-messages#messages +[tlb]: https://docs.ton.org/develop/data-formats/tl-b-language [tvm]: https://docs.ton.org/develop/func/statements#function-application [bp]: https://github.com/ton-org/blueprint [sb]: https://github.com/ton-org/sandbox