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

Tact lacks support of exotic cells #154

Open
Gusarich opened this issue Feb 29, 2024 · 0 comments · May be fixed by #343
Open

Tact lacks support of exotic cells #154

Gusarich opened this issue Feb 29, 2024 · 0 comments · May be fixed by #343
Assignees
Milestone

Comments

@Gusarich
Copy link
Member

Gusarich commented Feb 29, 2024

Exotic cells are very useful in certain circumstances. For example, they allow efficient interactions with merkle trees and masterchain libraries usage.
But at the moment, there's no easy way to utilize exotic cells in Tact (actually it's not a trivial task in FunC too). It would be great to have a simple interface for working with them, which will handle low-level things (like parsing them automatically and checkin some fields).

It's not obvious how exactly should that interface look like, so it needs a discussion.

I imagine it to look somehow like this (example with merkle proofs. structures from https://github.com/Gusarich/airdrop):

struct AirdropEntry {
    address: Address;
    amount: Int as coins;
}

struct ProvableData {
    entries: map<Int, AirdropEntry>;
}

message ProcessClaim {
    queryId: Int as uint64;
    proof: MerkleProof<ProvableData>;
    index: Int as uint256;
}

// somewhere in the code later

receive(msg: ProcessClaim) {
    require(msg.proof.root == self.root, "wrong merkle root");
    entry: AirdropEntry = msg.proof.data.get(msg.index);
    // That's it!

    // do something else with data
}

However, there is an issue with the way structs are handled in Tact at the moment that prevents us from implementing this feature correctly. Currently, structs are being parsed completely right after their loading. It's fine for regular structs, but in the case of merkle proofs and merkle updates, some fields of the struct might be pruned and therefore impossible to parse. It'll work fine for small structs (like the one from the example above), but if we want to add some more fields to it so that it splits into multiple cells, and then we provide that struct with some of these cells pruned to the contract, it'll throw a runtime error because it won't be able to load pruned cells (even though we won't use them there).

We probably need to introduce a lazy struct parsing mechanism into Tact so that all the fields are parsed the moment they're accessed for the first time. Another approach is to analyze struct field accesses in each receiver to only parse the fields that are used and skip everything else.
But I'm not sure exactly how it should be implemented and what we should do with Struct.fromCell(). Maybe we should only use this "lazy loading" for merkle proof and merkle update cells?

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

Successfully merging a pull request may close this issue.

2 participants