Skip to content

snarkVM can't handle duplicate outputs, or record outputs which were received as inputs. #28603

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

Merged
merged 1 commit into from
May 21, 2025

Conversation

mikebenfield
Copy link
Collaborator

We can handle duplicate outputs by "cloning", and input record ouputs too, unless they were external records. The latter case we need to catch.

The following changes were made to support the above:

  • codegen can "clone" registers (by casting it into a new register)

  • codegen tracks record inputs and clones them if they are output (since record inputs cannot be output by snarkVM)

  • codegen clones duplicate outputs

  • type checking disallows assignment to an external record type

  • type checking disallows tuple expressions containing an input external record type

  • type checking disallows ternary expressions of external record type, or of tuples which contain such

  • type checker track external record inputs and makes sure we don't output them

  • tests of the above functionality

Fixes #28602

@mikebenfield mikebenfield requested a review from d0cd May 9, 2025 23:14
@mikebenfield
Copy link
Collaborator Author

@d0cd

I decided to go ahead and disallow tuple expressions with external record inputs. It's goofy but we have to impose some goofy restrictions anyway: for instance we can't apply the conditional ? : to tuples with external records in them.

@mikebenfield
Copy link
Collaborator Author

Note also that the test nested_record_as_function_io.leo now fails. AFAICT it was testing exactly what doesn't work and we're now disallowing - so I'm inclined to just remove it.

@formatted
external_record_output {
args: (ty: impl Display, local_name: impl Display, input_name: impl Display),
msg: format!("Cannot output input external record `{local_name}: {ty}` (which was received as input {input_name})."),
Copy link
Collaborator

@d0cd d0cd May 16, 2025

Choose a reason for hiding this comment

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

Suggested change
msg: format!("Cannot output input external record `{local_name}: {ty}` (which was received as input {input_name})."),
msg: format!("Cannot output external record `{local_name}: {ty}` (which was received as input `{input_name}`)."),

Copy link
Collaborator

@d0cd d0cd left a comment

Choose a reason for hiding this comment

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

Is it possible to allow external record inputs as outputs, but no modification to them, purely pass through. Does snarkVM fail on those cases?

@mikebenfield
Copy link
Collaborator Author

Is it possible to allow external record inputs as outputs, but no modification to them, purely pass through. Does snarkVM fail on those cases?

Wow, to my surprise that actually does seem to work! Given the linked issue I assumed it'd fail regardless of whether the input record was external or not, but no, external records can just pass through. So I'll need to revise this PR.

@mikebenfield
Copy link
Collaborator Author

Rebase with changes allowing external record inputs to pass through, and loosening restrictions that turned out to be unnecessary, like putting external records in tuples.

Commit message has changed too.

@mikebenfield mikebenfield requested a review from d0cd May 19, 2025 19:26
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should this be moved to a compile test if its expected to fail?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

sorry, meant to delete this test (this stuff now appears as record_and_duplicate_outputs.{leo, out})

@mikebenfield
Copy link
Collaborator Author

This should pass tests now that the leo-test commit removing proofs from execution transactions is merged.

which were received as inputs.

We can handle duplicate outputs by "cloning", and input record ouputs
too, unless they were external records.

The following changes were made to support the above:

- codegen can "clone" registers (by casting it into a new register)

- codegen tracks record inputs and clones them if they are output
	(since record inputs cannot be output by snarkVM)

- codegen clones duplicate outputs

- type checking disallows assignment to an external record type,
  of to tuples which contain such

- type checking disallows ternary expressions of external record type,
  or of tuples which contain such

- tests of the above functionality

Fixes #28602
Copy link
Collaborator

@d0cd d0cd left a comment

Choose a reason for hiding this comment

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

LGTM!

@mikebenfield mikebenfield merged commit e9c86d6 into mainnet May 21, 2025
9 checks passed
@mikebenfield mikebenfield deleted the fix-outputs branch May 21, 2025 15:04
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.

[Bug] Compiler should throw an error for that pass record inputs directly to outputs
2 participants