Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(docs): mention the limit of max number of messages that can be sent during action phase #1237

Merged
merged 1 commit into from
Dec 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added a link to the article by CertiK to Security best practices page: PR [#1185](https://github.com/tact-lang/tact/pull/1185)
- Added a note on `dump()` being computationally expensive: PR [#1189](https://github.com/tact-lang/tact/pull/1189)
- Fixed links in Chinese translation: PR [#1206](https://github.com/tact-lang/tact/pull/1206)
- Added a note on 255 being the maximum number of messages that can be sent during action phase: PR [#1237](https://github.com/tact-lang/tact/pull/1237)

### Release contributors

Expand Down
6 changes: 6 additions & 0 deletions docs/src/content/docs/book/exit-codes.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,12 @@ When processing the message, TON Blockchain tries to pack it according to the [r

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`.

:::note

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.

:::

### 41: Library reference is null {#41}

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`.
Expand Down
34 changes: 22 additions & 12 deletions docs/src/content/docs/book/send.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,16 @@ send(SendParameters{
});
```

The [optional flag](/book/message-mode#optional-flags) `SendIgnoreErrors{:tact}` means that even when an error occurs during message sending next messages would be sent anyway. **No error during the sending phase would revert a transaction.**
The [optional flag](/book/message-mode#optional-flags) `SendIgnoreErrors{:tact}` means that if an error occurs during [message send](#outbound-message-processing), it will be ignored and the given message will be skipped. Message-related [action phase][phases] [exit codes](/book/exit-codes) that might be thrown without the `SendIgnoreErrors{:tact}` set are:

* $36$: [`Invalid destination address in outbound message`](/book/exit-codes#36)
* $37$: [`Not enough Toncoin`](/book/exit-codes#37)
* $39$: [`Outbound message doesn't fit into a cell`](/book/exit-codes#39)
* $40$: [`Cannot process a message`](/book/exit-codes#40)

## Send typed message

To send a binary typed message you can use the following code:
To send a typed message you can use the following code:

```tact
let recipient: Address = address("...");
Expand Down Expand Up @@ -98,7 +103,7 @@ send(SendParameters{

Each transaction on TON Blockchain consists of [multiple phases][phases]. Outbound messages are evaluated in [compute phase][compute], but are **not** sent in that phase. Instead, they're queued in order of appearance for the [action phase][phases], where all actions listed in [compute phase][compute], like outbound messages or [reserve requests](/ref/core-advanced#nativereserve), are executed.

As all the values are computed in [compute phase][compute], all the fees computed by the end of it, and exceptions do not revert the transaction during [action phase][phases], outbound message sends can fail without bounce due to unsufficient [action fees](https://docs.ton.org/develop/howto/fees-low-level#action-fee) or [forward fees][fwdfee].
As all the values are computed in [compute phase][compute], all the fees computed by the end of it, and exceptions do not revert the transaction during [action phase][phases], outbound message sends can fail without bounce due to insufficient [action fees](https://docs.ton.org/develop/howto/fees-low-level#action-fee) or [forward fees][fwdfee].

Consider the following example:

Expand Down Expand Up @@ -132,17 +137,22 @@ There, the second message won't actually be sent:

* When the second message is processed, contract tries to send $\mathrm{R}$ [nanoToncoins](/book/integers#nanotoncoin), but fails to do so because there is already a smaller amount left.

:::note
## Message sending limits

In total, there could be no more than $255$ actions queued for execution, which means that the maximum allowed number of messages sent per transaction is $255$.

Attempts to queue more throw an exception with an [exit code 33](/book/exit-codes#33) during [action phase][phases]: `Action list is too long`.

## Message sending functions

Read more about all message sending functions in the Reference:
* [`send(){:tact}`](/ref/core-common#send)
* [`emit(){:tact}`](/ref/core-common#emit)
* [`self.notify(){:tact}`](/ref/core-base#self-notify)
* [`self.reply(){:tact}`](/ref/core-base#self-reply)
* [`self.forward(){:tact}`](/ref/core-base#self-forward)
* [`nativeSendMessage(){:tact}`](/ref/core-advanced#nativesendmessage)
Read more about all message sending functions in the Reference:

:::
* [`send(){:tact}`](/ref/core-common#send)
* [`emit(){:tact}`](/ref/core-common#emit)
* [`self.notify(){:tact}`](/ref/core-base#self-notify)
* [`self.reply(){:tact}`](/ref/core-base#self-reply)
* [`self.forward(){:tact}`](/ref/core-base#self-forward)
* [`nativeSendMessage(){:tact}`](/ref/core-advanced#nativesendmessage)

[p]: /book/types#primitive-types
[int]: /book/integers
Expand Down
4 changes: 4 additions & 0 deletions docs/src/content/docs/ref/core-advanced.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,8 @@ fun nativeSendMessage(cell: Cell, mode: Int);

[Queues the message](/book/send#outbound-message-processing) to be sent by specifying the complete `cell` and the [message `mode`](/book/message-mode).

Attempts to queue more than $255$ messages throw an exception with an [exit code 33](/book/exit-codes#33): `Action list is too long`.

:::note

Prefer using a much more common and user-friendly [`send(){:tact}`](/ref/core-common#send) function unless you have a complex logic that can't be expressed otherwise.
Expand Down Expand Up @@ -466,6 +468,8 @@ It's possible to use raw [`Int{:tact}`][int] values and manually provide them fo

Currently, `amount` must be a non-negative integer, and `mode` must be in the range $0..31$, inclusive.

Additionally, attempts to queue more than $255$ reservations in one transaction throw an exception with an [exit code 33](/book/exit-codes#33): `Action list is too long`.

:::

### Base modes {#nativereserve-base-modes}
Expand Down
6 changes: 5 additions & 1 deletion docs/src/content/docs/ref/core-common.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ let iNeedADolla: Int = myBalance();

:::caution

Beware, that [all message sending functions](/book/send) of Tact can change the _actual_ contract's balance, but they _won't_ update the value returned by this function.
Beware, that [all message sending functions](/book/send#message-sending-functions) of Tact can change the _actual_ contract's balance, but they _won't_ update the value returned by this function.

:::

Expand Down Expand Up @@ -202,6 +202,8 @@ fun send(params: SendParameters);

[Queues the message](/book/send#outbound-message-processing) to be sent using a [`SendParameters{:tact}`](/book/send) [Struct](/book/structs-and-messages#structs).

Attempts to queue more than $255$ messages throw an exception with an [exit code 33](/book/exit-codes#33): `Action list is too long`.

Usage example:

```tact
Expand All @@ -228,6 +230,8 @@ fun emit(body: Cell);

[Queues the message](/book/send#outbound-message-processing) `body` to be sent to the outer world with the purpose of logging and analyzing it later off-chain. The message does not have a recipient and is gas-efficient compared to using any other message sending functions of Tact.

Attempts to queue more than $255$ messages throw an exception with an [exit code 33](/book/exit-codes#33): `Action list is too long`.

Usage example:

```tact
Expand Down
Loading