Skip to content

Conversation

@krebernisak
Copy link
Collaborator

@krebernisak krebernisak commented Dec 23, 2025

  • Add tlbe.Dict[K, V] to replace cell.Dictionary as a JSON/Cell serializable generic (dict) type
  • Add tlbe.ToCell/LoadFromCell shims to support int/uint primitive types (avoid needing a wrapper type for these)
  • Mark all _ tlb.Magic struct opcodes with <tlb:...> json:"-" to make those structs pass CLDF's operations.IsSerializable check
  • Add codec.MessageEnvelope[T] which is a JSON/Cell serializable generic (message wrapper) type
  • Add tvm.MessageRegistry to map contract types (string) to their corresponding TLBMap (opcode -> msg)
  • New TON basic CLDF types:
    • Add ops.SendMessages[T] operation - standardizes sending any []codec.MessageEnvelope[T] batch (+ metadata) on input
    • Add ops.AnySequence sequence - standardizes sequencing of any operation based on input (e.g., ops.SendMessage above)
  • Add new pkg/ton/codec and restructure/rm the existing pkg/ton/debug package

@krebernisak krebernisak requested a review from a team as a code owner December 23, 2025 10:29
Copilot AI review requested due to automatic review settings December 23, 2025 10:29
@github-actions
Copy link

👋 krebernisak, thanks for creating this pull request!

To help reviewers, please consider creating future PRs as drafts first. This allows you to self-review and make any final changes before notifying the team.

Once you're ready, you can mark it as "Ready for review" to request feedback. Thanks!

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces serializable message envelopes and generic operations for TON blockchain interactions, reorganizing the codebase to support better message handling and codec functionality.

Key changes:

  • Introduced a generic message envelope system with JSON serialization support
  • Created a custom JSON codec for TL-B message structures
  • Moved debug-related code from pkg/ton/debug to pkg/ton/codec/debug for better organization
  • Added operations framework for message planning and execution

Reviewed changes

Copilot reviewed 69 out of 79 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
pkg/ton/tvm/registry.go Adds TLB map registry for message type lookups
pkg/ton/tvm/magic.go Implements magic number extraction from TL-B structs
pkg/ton/codec/envelope.go Introduces generic MessageEnvelope for type-safe message handling
pkg/ton/codec/jsoncodec/codec.go Implements custom JSON codec for TL-B structures
pkg/ton/codec/decoder.go Refactors decoder to use new TLB registry types
pkg/ton/tlbe/dictionary.go Adds generic dictionary wrapper for TL-B dictionaries
pkg/ton/tlbe/biguint.go Adds BitsLen methods and Cmp for Uint256
pkg/bindings/*.go Updates all bindings to add json:"-" tags to Magic fields and use new registry
deployment/pkg/ops/*.go Adds operations framework for message planning and execution
deployment/pkg/utils/generator.go Adds sample data generator for testing

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Amount *big.Int `tlb:"## 256"`
Token address.Address `tlb:"addr"`
Amount *big.Int `tlb:"## 256"`
Token *address.Address `tlb:"addr"`
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

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

Changing Token from address.Address to *address.Address is a breaking change. This makes the field nullable which could impact existing code that assumes this field is always present.

Copilot uses AI. Check for mistakes.
// Any2TVMMessage represents a cross-chain message to TON
type Any2TVMMessage struct {
MessageID [32]byte `tlb:"bits 256"`
MessageID []byte `tlb:"bits 256"`
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

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

Changing MessageID from [32]byte to []byte removes compile-time size guarantees. This is a breaking change that could lead to runtime errors if the slice doesn't have exactly 32 bytes.

Suggested change
MessageID []byte `tlb:"bits 256"`
MessageID [32]byte `tlb:"bits 256"`

Copilot uses AI. Check for mistakes.
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Using [32byte fails with panic: reflect.Value.Bytes of unaddressable byte array [recovered, repanicked], works as:

  • []byte - current choice
  • *[32]byte

Copy link
Collaborator

Choose a reason for hiding this comment

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

Maybe we can at least leave a comment clarifying it is 32 bytes? Should we create a wrapper type instead maybe?

// NewGenerator constructs a Generator with sensible defaults.
func NewGenerator(opts ...Option) *Generator {
g := &Generator{
rng: rand.New(rand.NewSource(42)),
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

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

Using a fixed seed (42) for random number generation makes the output predictable. While this may be intentional for testing, consider documenting this behavior and providing an option to use a secure random seed for production use cases.

Copilot uses AI. Check for mistakes.
if t.Kind() == reflect.Pointer {
inst = reflect.New(t.Elem()).Interface().(DictKey)
} else {
inst = reflect.New(t).Elem().Interface().(DictKey)
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

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

Type assertion without checking can panic. Wrap this in a type assertion with the ok pattern to handle cases where the type doesn't implement DictKey.

Copilot uses AI. Check for mistakes.
}

// Sent back to sender after the executor role check is updated.
type TestMessage struct {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

TODO: move to tests

// Any2TVMMessage represents a cross-chain message to TON
type Any2TVMMessage struct {
MessageID [32]byte `tlb:"bits 256"`
MessageID []byte `tlb:"bits 256"`
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Using [32byte fails with panic: reflect.Value.Bytes of unaddressable byte array [recovered, repanicked], works as:

  • []byte - current choice
  • *[32]byte

@krebernisak krebernisak changed the title Serializable messages and generic ops Serializable messages and generic operations Dec 23, 2025
Copy link
Collaborator

@patricios-space patricios-space left a comment

Choose a reason for hiding this comment

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

This is looking really promising! Left some small comments

Comment on lines +222 to +224
if field != nil {
ctx.Tag = parseTLBTag(field.Tag.Get("tlb"))
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Isn't this duplicated above?


size := g.randomCollectionSize()
slice := reflect.MakeSlice(t, size, size)
for i := 0; i < size; i++ {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit:

Suggested change
for i := 0; i < size; i++ {
for i := range size {

Copy link
Collaborator

Choose a reason for hiding this comment

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

Should we move tests to a different module so we don't ship them in the package?

// Any2TVMMessage represents a cross-chain message to TON
type Any2TVMMessage struct {
MessageID [32]byte `tlb:"bits 256"`
MessageID []byte `tlb:"bits 256"`
Copy link
Collaborator

Choose a reason for hiding this comment

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

Maybe we can at least leave a comment clarifying it is 32 bytes? Should we create a wrapper type instead maybe?

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.

2 participants