Skip to content

feat(sharding): put in agreement with styleguide and port code samples to Tolk#2131

Open
aigerimu wants to merge 7 commits intomainfrom
contract-sharding-polishing
Open

feat(sharding): put in agreement with styleguide and port code samples to Tolk#2131
aigerimu wants to merge 7 commits intomainfrom
contract-sharding-polishing

Conversation

@aigerimu
Copy link
Copy Markdown
Contributor

@aigerimu aigerimu commented Apr 24, 2026

closes #500

Summary by CodeRabbit

  • Documentation
    • Enhanced contract sharding documentation with clearer explanations of child contract address derivation
    • Added comprehensive NFT and jetton examples demonstrating practical parent/child contract patterns
    • Updated code samples with improved validation logic and deterministic deployment patterns for managing child contracts

@aigerimu aigerimu requested a review from a team as a code owner April 24, 2026 20:16
@aigerimu aigerimu marked this pull request as draft April 24, 2026 20:16
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 24, 2026

Warning

Rate limit exceeded

@aigerimu has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 56 minutes and 6 seconds before requesting another review.

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 @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 880d76be-c47c-4f90-b4e4-399db0fb9640

📥 Commits

Reviewing files that changed from the base of the PR and between b5d1cb6 and 4858315.

📒 Files selected for processing (1)
  • contract-dev/techniques/contract-sharding.mdx
📝 Walkthrough

Walkthrough

The documentation for contract sharding is reorganized and expanded. The narrative replaces an earlier discussion of StateInit handling with an explanation of deriving child contract addresses from parent address and key. An "NFT and jetton examples" section is added, and an unbounded sharded structures example is rewritten from Tact to multi-file Tolk code with parent/child validation logic.

Changes

Cohort / File(s) Summary
Contract Sharding Documentation
contract-dev/techniques/contract-sharding.mdx
Reorganized narrative explaining child contract address derivation; updated caution requiring child to store and verify parent address; new "NFT and jetton examples" section; rewritten unbounded sharded structures example from Tact to multi-file Tolk with parent contract deploying children deterministically and child contract validating sender.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🐰 A rabbit hops through shards so neat,
With parent and child contracts that meet,
From Tact to Tolk, examples grow bright,
NFTs and jettons, all working just right!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main changes: styleguide alignment and Tolk port of code samples for contract sharding documentation.
Linked Issues check ✅ Passed The PR addresses issue #500's requirements: reorganized documentation, parent/child contract patterns, NFT/jetton examples section, and rewritten unbounded sharding examples in Tolk with shared storage layouts.
Out of Scope Changes check ✅ Passed All changes are within scope: documentation restructuring, styleguide alignment, and code example porting to Tolk directly address the linked issue #500 objectives.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch contract-sharding-polishing

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.

❤️ Share
Review rate limit: 0/1 reviews remaining, refill in 56 minutes and 6 seconds.

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions

This comment has been minimized.

@mintlify
Copy link
Copy Markdown

mintlify Bot commented Apr 24, 2026

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
mintlify-ton-docs 🟢 Ready View Preview Apr 24, 2026, 8:19 PM

💡 Tip: Enable Workflows to automatically generate PRs for you.

Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the clear docs updates in contract-dev/techniques/contract-sharding.mdx: please apply the couple of inline suggestions to keep terminology casing and code formatting consistent.

Comment thread contract-dev/techniques/contract-sharding.mdx Outdated
Comment thread contract-dev/techniques/contract-sharding.mdx Outdated
Comment thread contract-dev/techniques/contract-sharding.mdx Outdated
Comment thread contract-dev/techniques/contract-sharding.mdx
Comment thread contract-dev/techniques/contract-sharding.mdx
Comment thread contract-dev/techniques/contract-sharding.mdx Outdated
self.numChildren = 0;
}
fun onInternalMessage(in: InMessage) {
val msg = lazy TodoChildMessage.fromSlice(in.body);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure, but I think the else branch in the match below may not be reachable as written. Since TodoChildMessage = Identify is a single-variant union, lazy TodoChildMessage.fromSlice(in.body) should throw on any body that doesn't parse as Identify - including an empty body, since the opcode parse fails first

If the intent is to ignore empty top-up messages, the empty-body check probably needs to happen before the lazy fromSlice call for instance

 fun onInternalMessage(in: InMessage) {
+    if (in.body.isEmpty()) {
+        return;
+    }
     val msg = lazy TodoChildMessage.fromSlice(in.body);

it definitely worths double-checking against actual Tolk semantics

Comment thread contract-dev/techniques/contract-sharding.mdx
@github-actions

This comment has been minimized.

Comment thread contract-dev/techniques/contract-sharding.mdx Outdated
Comment thread contract-dev/techniques/contract-sharding.mdx Outdated
Comment thread contract-dev/techniques/contract-sharding.mdx
struct (0x5b6f1392) DeployAnother {}

// Build StateInit for a TodoChild instance with the given seqno.
fun calcDeployedTodoChild(
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we should move it to parent.tolk (I am not sure)

Copy link
Copy Markdown
Contributor Author

@aigerimu aigerimu Apr 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed by moving calcDeployedTodoChild to parent.tolk. But this still needs to be validated

cc @Shvandre @Kaladin13

@aigerimu aigerimu marked this pull request as ready for review April 30, 2026 17:38
Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the updates in contract-dev/techniques/contract-sharding.mdx: I’ve suggested a couple of focused tweaks to align wording and code snippet labeling, so please apply the inline suggestions.

Comment thread contract-dev/techniques/contract-sharding.mdx Outdated
Comment thread contract-dev/techniques/contract-sharding.mdx
Comment thread contract-dev/techniques/contract-sharding.mdx
Comment thread contract-dev/techniques/contract-sharding.mdx
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
contract-dev/techniques/contract-sharding.mdx (1)

90-102: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

child.tolk: empty top-up fallback likely won’t run after upfront parse.

On Line 91, lazy TodoChildMessage.fromSlice(in.body) runs before the Line 100 empty-body fallback. If fromSlice rejects empty/unknown bodies first, the intended “ignore empty top-up” path is unreachable.

Suggested doc snippet fix
 fun onInternalMessage(in: InMessage) {
+    if (in.body.isEmpty()) {
+        return;
+    }
     val msg = lazy TodoChildMessage.fromSlice(in.body);

     match (msg) {
         Identify => {
             val storage = lazy TodoChildStorage.load();
             assert (in.senderAddress == storage.parentAddress) throw 0xFFFF;
             debug.print(storage.seqno);
         }
-        else => {
-            // Ignore empty top-up messages, reject everything else.
-            assert (in.body.isEmpty()) throw 0xFFFF;
-        }
+        else => { throw 0xFFFF; }
     }
 }
In Tolk, does `lazy <UnionType>.fromSlice(in.body)` throw on an empty body or unknown opcode before `match` fallback branches can execute?
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@contract-dev/techniques/contract-sharding.mdx` around lines 90 - 102, The
current code eagerly calls TodoChildMessage.fromSlice(in.body) in
onInternalMessage which can throw on empty/unknown payloads and prevents the
intended empty-body fallback; fix by deferring parsing: first check
in.body.isEmpty() (or use a non-throwing/optional parse helper) and handle the
empty top-up branch before calling TodoChildMessage.fromSlice, or move the
fromSlice call inside the Identify match arm so parsing only happens when the
message is non-empty and intended to be parsed.
🤖 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/contract-sharding.mdx`:
- Around line 42-43: The sample is missing the Poll/Voter example and
bounced-message handling from Issue `#500`: add two new contract examples named
Poll and Voter (mirroring the parent/child pattern) where Poll deploys Voter
instances and assigns sequence numbers, extend the shared storage definitions to
include the Poll/Voter message types and a bounced-message envelope, and
implement explicit bounce handling in the Voter (e.g., an onBounce or
handle_bounced_message function and examples of sending messages that may bounce
and how Poll reacts); update the narrative to show deployment, message flow, and
bounced-message test cases and link to Issue `#500` for scope reference.

---

Duplicate comments:
In `@contract-dev/techniques/contract-sharding.mdx`:
- Around line 90-102: The current code eagerly calls
TodoChildMessage.fromSlice(in.body) in onInternalMessage which can throw on
empty/unknown payloads and prevents the intended empty-body fallback; fix by
deferring parsing: first check in.body.isEmpty() (or use a non-throwing/optional
parse helper) and handle the empty top-up branch before calling
TodoChildMessage.fromSlice, or move the fromSlice call inside the Identify match
arm so parsing only happens when the message is non-empty and intended to be
parsed.
🪄 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: 7403c291-289a-4bf7-97a2-c4bb1517b988

📥 Commits

Reviewing files that changed from the base of the PR and between e5ddef7 and b5d1cb6.

📒 Files selected for processing (1)
  • contract-dev/techniques/contract-sharding.mdx

Comment on lines +42 to 43
The following example shows a parent contract that deploys child contracts and assigns each child a sequence number. The shared storage file defines the data layouts and message types used by both contracts.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Issue #500 scope is still incomplete (missing Poll/Voter + bounced-message logic).

The page now has a solid parent/child sample, but it still does not include (or link to) the requested Poll/Voter Tolk example demonstrating bounced-message handling from the linked issue scope.

Also applies to: 85-110, 114-167

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@contract-dev/techniques/contract-sharding.mdx` around lines 42 - 43, The
sample is missing the Poll/Voter example and bounced-message handling from Issue
`#500`: add two new contract examples named Poll and Voter (mirroring the
parent/child pattern) where Poll deploys Voter instances and assigns sequence
numbers, extend the shared storage definitions to include the Poll/Voter message
types and a bounced-message envelope, and implement explicit bounce handling in
the Voter (e.g., an onBounce or handle_bounced_message function and examples of
sending messages that may bounce and how Poll reacts); update the narrative to
show deployment, message flow, and bounced-message test cases and link to Issue
`#500` for scope reference.

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

Consider NFTs: the collection acts as the parent contract, and each NFT item is a child contract. The key in this case is the item index, and only the collection can set the initial owner.

For jettons, the parent contract is the minter, and the child contracts are user wallets. The key is the wallet's smart contract address.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

small accuracy thing: "The key is the wallet's smart contract address" is ambiguous - and probably wrong as it reads.the previous sentence says the children are user wallets, so "the wallet's smart contract address" naturally refers to the child's own address, which is the output of address derivation, not the input/key

the key for a jetton wallet is the address of the wallet's owner (the user's main wallet contract) which gets fed into address derivation along with the minter address and the wallet code

-For jettons, the parent contract is the minter, and the child contracts are user wallets. The key is the wallet's smart contract address.
+For jettons, the parent contract is the minter, and the child contracts are jetton wallets. The key is the address of the jetton wallet's owner, and the value is the owner's jetton balance.

match (msg) {
Identify => {
val storage = lazy TodoChildStorage.load();
assert (in.senderAddress == storage.parentAddress) throw 0xFFFF;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

throw 0xFFFF is reused for three different conditions: "sender is not the parent" (here), "unexpected message body" (line 101), and "sender is not the admin" (line 144). same code for three distinct failure modes makes a tx-dump in an explorer harder to triage

worth picking distinct codes (any value in 32-65535 outside reserved ranges), e.g. 100 / 101 / 200, but I am not sure

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Contract dev > Contract sharding] Add more examples and code with different scale & scope

3 participants