refactor(contract-dev): port gas article code samples to Tolk#2101
refactor(contract-dev): port gas article code samples to Tolk#2101delovoyhomie wants to merge 7 commits intomainfrom
Conversation
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Workflows to automatically generate PRs for you. |
|
Warning Rate limit exceeded
To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughThe documentation file migrated code examples from Tact to Tolk, updating function APIs for gas computation, message handling, reserve mechanics, and error validation patterns to reflect Tolk's syntax and available functions. Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Warning Review ran into problems🔥 ProblemsTimed out fetching pipeline failures after 30000ms Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
contract-dev/gas.mdx (2)
144-152:⚠️ Potential issue | 🟡 MinorStale prose references
computeDataSize()after Tolk port.The Aside still talks about
computeDataSize()and its "second argument: maximum number of cells to visit", but the code at Lines 134-135 now usescell.calculateSizeStrict(8192). Similarly, Line 152's "In Tolk, both computations can be performed with a call tomsg.send()with mode 1024" is disconnected from the preceding snippet (nomsg.send()example is shown) and the old Tact-era phrasing leaks through.Please rewrite this Aside and the following paragraph to reference
calculateSizeStrict()/calculateForwardFee()by their Tolk names so readers can actually find them in the stdlib.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@contract-dev/gas.mdx` around lines 144 - 152, The Aside and following paragraph still reference the old computeDataSize() API and Tact-era phrasing; update them to mention Tolk stdlib functions calculateSizeStrict(maxCells) and calculateForwardFee() instead (replace “computeDataSize” and its "second argument" wording with calculateSizeStrict(8192) and explain the maxCells parameter), and change the Tolk example text to reference using msg.send() with mode 1024 as a way to perform the same computations in Tolk while keeping the TVM reference to SENDRAWMSG; ensure the prose points readers to the stdlib names calculateSizeStrict and calculateForwardFee so links/searches work.
165-189:⚠️ Potential issue | 🟠 MajorFix function name and parameters to match Tolk stdlib signature.
Two issues here:
Line 179 calls
getSimpleForwardFee(...), but the prose at line 169 and the Tolk stdlib reference both confirm the canonical function iscalculateForwardFeeWithoutLumpPrice.The function call passes
isAccountInMasterchainas a parameter, but examining the parallel functioncalculateForwardFee(workchain, bits, cells)at lines 137–142 establishes the correct pattern: all parameters should be explicit, withworkchainas the first parameter, followed bybitsandcells.🔧 Suggested fix
- val additionalFwdFee = getSimpleForwardFee( - additionalFieldsSize.cells, - additionalFieldsSize.bits, - isAccountInMasterchain - ); + val additionalFwdFee = calculateForwardFeeWithoutLumpPrice( + workchain, + additionalFieldsSize.bits, + additionalFieldsSize.cells, + );🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@contract-dev/gas.mdx` around lines 165 - 189, The call to getSimpleForwardFee should be renamed to calculateForwardFeeWithoutLumpPrice and its arguments reordered to match the Tolk stdlib: pass the workchain identifier as the first argument, then bits, then cells (i.e., use the same signature pattern as calculateForwardFee(workchain, bits, cells)); replace the isAccountInMasterchain argument with the actual workchain value for the account/message and pass additionalFieldsSize.bits and additionalFieldsSize.cells in that order.
🧹 Nitpick comments (1)
contract-dev/gas.mdx (1)
234-258: Unusedmsgbinding and missinglazyin message-parse examples.Minor refactor consistency items across the ported
onInternalMessagesamples (Lines 215, 238, 279, 300, 331):
- The recommended Tolk idiom per
tolk/features/message-handling.mdx:7-62isval msg = lazy X.fromSlice(in.body);— readers copying from these docs miss the perf benefit without thelazykeyword.- In the samples on Lines 238 and 279 the parsed
msgis declared but never referenced. Either use it (e.g. inmsg.amountor similar) or drop the binding so the snippet doesn't read as dead code.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@contract-dev/gas.mdx` around lines 234 - 258, The sample onInternalMessage examples declare val msg = UserIn.fromSlice(in.body) but omit the recommended lazy and in some snippets the binding is unused; update the parsing to use the lazy idiom (e.g., make the binding lazy by changing the declaration to use lazy with UserIn.fromSlice) and either reference msg where needed (e.g., use msg fields in the fee/assert logic) or remove the unused val msg binding so there is no dead code; target the onInternalMessage examples and the val msg declarations to apply these changes.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@contract-dev/gas.mdx`:
- Around line 298-308: Replace the invalid placeholder and the non-existent
function: in onInternalMessage (and any other places using getFreezeLimit), set
otherFees to a concrete value (e.g., 0) instead of `...`, and replace calls to
getFreezeLimit(workchain) with the actual freeze_due_limit configuration value
(100000000 nanotons) or a call to the real config accessor if one exists in your
codebase; ensure the assertion uses the concrete freeze_due_limit and the
concrete otherFees variable so the snippet compiles (references:
onInternalMessage, InMessage, Operation.fromSlice, otherFees, getFreezeLimit,
freeze_due_limit).
---
Outside diff comments:
In `@contract-dev/gas.mdx`:
- Around line 144-152: The Aside and following paragraph still reference the old
computeDataSize() API and Tact-era phrasing; update them to mention Tolk stdlib
functions calculateSizeStrict(maxCells) and calculateForwardFee() instead
(replace “computeDataSize” and its "second argument" wording with
calculateSizeStrict(8192) and explain the maxCells parameter), and change the
Tolk example text to reference using msg.send() with mode 1024 as a way to
perform the same computations in Tolk while keeping the TVM reference to
SENDRAWMSG; ensure the prose points readers to the stdlib names
calculateSizeStrict and calculateForwardFee so links/searches work.
- Around line 165-189: The call to getSimpleForwardFee should be renamed to
calculateForwardFeeWithoutLumpPrice and its arguments reordered to match the
Tolk stdlib: pass the workchain identifier as the first argument, then bits,
then cells (i.e., use the same signature pattern as
calculateForwardFee(workchain, bits, cells)); replace the isAccountInMasterchain
argument with the actual workchain value for the account/message and pass
additionalFieldsSize.bits and additionalFieldsSize.cells in that order.
---
Nitpick comments:
In `@contract-dev/gas.mdx`:
- Around line 234-258: The sample onInternalMessage examples declare val msg =
UserIn.fromSlice(in.body) but omit the recommended lazy and in some snippets the
binding is unused; update the parsing to use the lazy idiom (e.g., make the
binding lazy by changing the declaration to use lazy with UserIn.fromSlice) and
either reference msg where needed (e.g., use msg fields in the fee/assert logic)
or remove the unused val msg binding so there is no dead code; target the
onInternalMessage examples and the val msg declarations to apply these changes.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
contract-dev/techniques/gas.mdx (1)
179-183:⚠️ Potential issue | 🟠 MajorReplace the non-existent
getSimpleForwardFeeAPI with the Tolk stdlib function.The code at line 179 uses
getSimpleForwardFee(), which does not exist in Tolk's stdlib. The correct function iscalculateForwardFeeWithoutLumpPrice(workchain: int8, bits: int, cells: int), mentioned in the preceding paragraph. However, the function signatureonInternalMessage(in: InMessage)does not have access to aworkchainparameter. Determine the appropriate workchain value (or how to obtain it from the context) before applying the fix. See Tolk gas-payments stdlib for the correct API signature.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@contract-dev/techniques/gas.mdx` around lines 179 - 183, Replace the nonexistent getSimpleForwardFee call in onInternalMessage with the Tolk stdlib calculateForwardFeeWithoutLumpPrice and pass a proper workchain value: derive workchain as int8 from isAccountInMasterchain (use -1 for masterchain, 0 for basic workchain) and call calculateForwardFeeWithoutLumpPrice(workchain, additionalFieldsSize.bits, additionalFieldsSize.cells) so the argument order matches the stdlib signature.
♻️ Duplicate comments (1)
contract-dev/techniques/gas.mdx (1)
302-303:⚠️ Potential issue | 🟡 MinorReplace the unresolved freeze-limit placeholder.
getFreezeLimit(workchain)is not a Tolk stdlib helper, and...is not valid Tolk syntax. Use a real config parser or a concretefreeze_due_limitconstant, and reuse it in the final validation snippet too. This duplicates a prior review comment but remains unresolved. Refs: Tolk stdlib docs, TON limits docs.🔧 Possible illustrative fix
+const FreezeDueLimit = ton("0.1"); + fun onInternalMessage(in: InMessage) { val msg = Operation.fromSlice(in.body); // The trace is still receiver -> A -> B - val freezeLimit = getFreezeLimit(workchain); - val otherFees = ...; + val freezeLimit = FreezeDueLimit; + val otherFees = 0; // compute + forward fees go here // n equals 3 because receiver -> A -> B assert (in.valueCoins >= freezeLimit * 3 + otherFees) throw ERR_NOT_ENOUGH_TONS; }- 3 * getFreezeLimit(workchain); + 3 * FreezeDueLimit;Verification:
#!/bin/bash set -euo pipefail gas="$(curl -fsSL https://raw.githubusercontent.com/ton-blockchain/ton/master/crypto/smartcont/tolk-stdlib/gas-payments.tolk)" if printf '%s\n' "$gas" | grep -n 'getFreezeLimit'; then echo "Unexpected getFreezeLimit API found in Tolk stdlib" >&2 exit 1 else echo "getFreezeLimit is not present in Tolk gas-payments stdlib" fi curl -fsSL https://docs.ton.org/foundations/limits | grep -E 'freeze_due_limit|100000000'Also applies to: 348-348
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@contract-dev/techniques/gas.mdx` around lines 302 - 303, The snippet uses a non-existent helper getFreezeLimit(workchain) and an invalid '...' placeholder; replace them by declaring a concrete constant (e.g. freeze_due_limit = <value_from_TON_limits_or_config>) or parsing it from a real config parser, then assign val freezeLimit = freeze_due_limit and compute val otherFees explicitly instead of '...'; update the final validation snippet to reuse freeze_due_limit/freezeLimit (and remove getFreezeLimit and '...') so all references (freezeLimit, otherFees) are real values derived from the declared constant or parsed config.
🧹 Nitpick comments (1)
contract-dev/techniques/gas.mdx (1)
288-288: UseBounceMode.NoBounceinstead of deprecated boolean bounce.Current Tolk stdlib marks
falseas deprecated for the bounce field; documentation examples should use the enum form. The Tolk stdlib deprecation notice explicitly recommendsBounceMode.NoBounceinstead.♻️ Proposed refactor
- bounce: false, + bounce: BounceMode.NoBounce,🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@contract-dev/techniques/gas.mdx` at line 288, The example uses the deprecated boolean bounce flag; replace the boolean usage (bounce: false) with the enum form (bounce: BounceMode.NoBounce) and ensure the BounceMode symbol is in scope (import or reference the enum where the message/transaction object is constructed). Update the object property to use BounceMode.NoBounce and remove the boolean literal so the code uses the recommended enum constant.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@contract-dev/techniques/gas.mdx`:
- Around line 107-109: The snippet uses the helper function calculateGasFee but
Tolk only auto-imports common.tolk, so add the explicit import for the fee
helpers by inserting import "@stdlib/gas-payments"; immediately before the
calculateGasFee usage (ensure the import appears at the top of the tolk code
block containing calculateGasFee so the fee helper symbols are available).
---
Outside diff comments:
In `@contract-dev/techniques/gas.mdx`:
- Around line 179-183: Replace the nonexistent getSimpleForwardFee call in
onInternalMessage with the Tolk stdlib calculateForwardFeeWithoutLumpPrice and
pass a proper workchain value: derive workchain as int8 from
isAccountInMasterchain (use -1 for masterchain, 0 for basic workchain) and call
calculateForwardFeeWithoutLumpPrice(workchain, additionalFieldsSize.bits,
additionalFieldsSize.cells) so the argument order matches the stdlib signature.
---
Duplicate comments:
In `@contract-dev/techniques/gas.mdx`:
- Around line 302-303: The snippet uses a non-existent helper
getFreezeLimit(workchain) and an invalid '...' placeholder; replace them by
declaring a concrete constant (e.g. freeze_due_limit =
<value_from_TON_limits_or_config>) or parsing it from a real config parser, then
assign val freezeLimit = freeze_due_limit and compute val otherFees explicitly
instead of '...'; update the final validation snippet to reuse
freeze_due_limit/freezeLimit (and remove getFreezeLimit and '...') so all
references (freezeLimit, otherFees) are real values derived from the declared
constant or parsed config.
---
Nitpick comments:
In `@contract-dev/techniques/gas.mdx`:
- Line 288: The example uses the deprecated boolean bounce flag; replace the
boolean usage (bounce: false) with the enum form (bounce: BounceMode.NoBounce)
and ensure the BounceMode symbol is in scope (import or reference the enum where
the message/transaction object is constructed). Update the object property to
use BounceMode.NoBounce and remove the boolean literal so the code uses the
recommended enum constant.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: e08d6a54-9838-4ca1-9864-22043048c71e
📒 Files selected for processing (1)
contract-dev/techniques/gas.mdx
|
/review |
| fun onInternalMessage(in: InMessage) { | ||
| val workchain = contract.getAddress().getWorkchain(); | ||
| val minTonsForStorage = calculateStorageFee( | ||
| workchain, | ||
| secondsInFiveYears, | ||
| isAccountInMasterchain | ||
| maxBits, | ||
| maxCells, | ||
| ); | ||
| nativeReserve( | ||
| val oldBalance = contract.getOriginalBalance() - in.valueCoins; | ||
| reserveToncoinsOnBalance( | ||
| max(oldBalance, minTonsForStorage), | ||
| ReserveAtMost | ||
| RESERVE_MODE_AT_MOST, | ||
| ); | ||
| // Process operation with remaining value... | ||
| } | ||
| // Also this contract probably will require some code, that will allow owner to withdraw TONs from this contract. | ||
| // This contract probably also requires some code allowing the owner to withdraw TONs from it. | ||
| ``` | ||
|
|
||
| In this approach, a receiver contract should calculate maximum possible storage fees for all contracts in trace. | ||
|
|
||
| ```tact | ||
| const secondsInFiveYears: Int = 5 * 365 * 24 * 60 * 60; | ||
| receive(msg: UserIn) { | ||
| // Suppose trace will be | ||
| ```tolk | ||
| import "@stdlib/gas-payments"; | ||
|
|
||
| const secondsInFiveYears = 5 * 365 * 24 * 60 * 60; | ||
|
|
||
| fun onInternalMessage(in: InMessage) { |
There was a problem hiding this comment.
[HIGH] Error identifiers in prose not formatted as code
Lines 243–268 describe Tolk error handling using identifiers such as ERR_NOT_ENOUGH_TONS and ERR_INSUFFICIENT_TON_ATTACHED in running text, but they are not consistently wrapped in code formatting. The style guide requires that error codes and identifiers be rendered in code font so they stand out visually, remain copy‑pasteable, and are clearly distinguished from surrounding prose. Leaving them as plain text decreases readability and can make it harder to spot exact names.
Please leave a reaction 👍/👎 to this suggestion to improve future reviews for everyone!
| ```tolk | ||
| const FreezeDueLimit = ton("0.1"); // Current mainnet freeze_due_limit; adjust for other networks if needed. | ||
|
|
||
| ```tact | ||
| receive(msg: Operation) { | ||
| fun onInternalMessage(in: InMessage) { | ||
| // The trace is still receiver -> A -> B | ||
| let freezeLimit = getFreezeLimit(isAccountsInMasterchain); | ||
| let otherFees = ...; | ||
| val freezeLimit = FreezeDueLimit; | ||
| val otherFees = 0; // Compute + forward fees go here. | ||
| // n equals 3 because receiver -> A -> B | ||
| require( | ||
| messageValue() >= freezeLimit * 3 + otherFees, | ||
| "Not enough TONs" | ||
| ); | ||
| assert (in.valueCoins >= freezeLimit * 3 + otherFees) | ||
| throw ERR_NOT_ENOUGH_TONS; | ||
| } |
There was a problem hiding this comment.
[HIGH] Hardcoded FreezeDueLimit requires explicit network-scope safety callout
The example on lines 331–341 hardcodes const FreezeDueLimit = ton("0.1"); and comments that this reflects the “Current mainnet freeze_due_limit; adjust for other networks if needed.” Without an explicit safety callout, this may encourage readers to copy the value verbatim across networks, which can misprice storage reservation and affect funds, contrary to the style guidance for safety‑critical content. Because the code is illustrative, the primary risk is misunderstanding the network-specific nature of the constant, not the numeric value itself.
Please leave a reaction 👍/👎 to this suggestion to improve future reviews for everyone!
| assert (in.valueCoins >= totalStorageFees + otherFees) | ||
| throw ERR_NOT_ENOUGH_TONS; | ||
| } |
There was a problem hiding this comment.
[MEDIUM] Receiver reserve check uses generic error identifier without quoted mapping
The example check on lines 287–289 throws ERR_NOT_ENOUGH_TONS without showing the corresponding user-facing error string, while similar examples later introduce identifiers like ERR_INSUFFICIENT_TON_ATTACHED. For consistency and grep‑ability, the style rules favor either using a clearly named identifier everywhere or showing how it maps to a literal error message in comments or surrounding text. Making this mapping explicit in the snippet avoids ambiguity when correlating documentation with runtime errors.
Please leave a reaction 👍/👎 to this suggestion to improve future reviews for everyone!
|
Thanks for the detailed work on Per-comment submission: 8 posted, 5 failed. Unposted inline comments (raw text):
|
|
do we have some tests for these contracts? |
no, should we? |
yes, it is open source |
Closes #1003
Summary by CodeRabbit