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

Empty string processed by empty receiver #1843

Open
jeshecdom opened this issue Feb 14, 2025 · 4 comments
Open

Empty string processed by empty receiver #1843

jeshecdom opened this issue Feb 14, 2025 · 4 comments
Assignees
Labels
docs: Book /book section of the docs: Guides, Cheatsheets, and a streamlined sequence of educational materials feature: receivers Process internal, external, bounced incoming messages kind: docs Documentation for docs.tact-lang.org kept in docs folder
Milestone

Comments

@jeshecdom
Copy link
Contributor

In this contract:

contract Test {

    receiver: String = "unknown";
    
    receive() {
       self.receiver = "empty";    
    }

    receive(msg: String) {
       self.receiver = "string";
    }
}

If we send a message with an empty string (done in a spec.ts file):

await contract.send(
      treasure.getSender(),
      { value: toNano("10") },
      "",
);

the message will get processed by the empty receiver, when it should be processed by the String receiver, because the body has an opcode of 0 with an empty string.

As a comparison, the following contract correctly catches the above message in the string receiver:

contract Test {

    receiver: String = "unknown";
    
    receive(msg: String) {
       self.receiver = "string";
    }
}

I tried sending a message to the contract inside Tact:

send(SendParameters{to: contractAddr, value: ton("1"), body: "".asComment()})

And again, the empty receiver processes the message.

The problem is that in the generated FunC code, the handler for the empty receiver has a <= 32 comparison:

    ;; Receive empty message
    if ((op == 0) & (slice_bits(in_msg) <= 32)) {
        self~%$Test$_internal_empty();
        return (self, true);
    }

and I think it should be strict inequality < 32.

Additionally, the case for empty string should be added to the tests in src/test/e2e-emulated/receiver-precedence.spec.ts.

@novusnota novusnota added the kind: bug Something isn't working or isn't right label Feb 14, 2025
@anton-trunov
Copy link
Member

Try typechecking

contract Test {
    
    receive("") {
       self.receiver = "empty";    
    }
}

@jeshecdom
Copy link
Contributor Author

Try typechecking

contract Test {

receive("") {
   self.receiver = "empty";    
}

}

Interesting. The compiler gives the error: "To use empty comment receiver, just remove parameter instead of passing empty string".
So, the actual semantics is that the empty string is a en empty body. In fact, any message that contains less than or equal to 32 bits in its body, with opcode 0, is considered to be an empty message. Then, it is not a bug. =D

@jeshecdom
Copy link
Contributor Author

Then, it should be stated somewhere in the docs.

@anton-trunov
Copy link
Member

Then, it should be stated somewhere in the docs.

Absolutely!

@novusnota novusnota added docs: Book /book section of the docs: Guides, Cheatsheets, and a streamlined sequence of educational materials and removed kind: bug Something isn't working or isn't right labels Feb 14, 2025
@novusnota novusnota self-assigned this Feb 14, 2025
@novusnota novusnota added the kind: docs Documentation for docs.tact-lang.org kept in docs folder label Feb 14, 2025
@novusnota novusnota added this to the Doc: 2025-02 milestone Feb 14, 2025
@anton-trunov anton-trunov added the feature: receivers Process internal, external, bounced incoming messages label Feb 25, 2025
@novusnota novusnota modified the milestones: Doc: 2025-02, Doc: 2025-03 Mar 2, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs: Book /book section of the docs: Guides, Cheatsheets, and a streamlined sequence of educational materials feature: receivers Process internal, external, bounced incoming messages kind: docs Documentation for docs.tact-lang.org kept in docs folder
Projects
None yet
Development

No branches or pull requests

3 participants