Skip to content

Emit one self-describing artifact instead of r1cs.bin and basic.json - #429

Open
BornPsych wants to merge 12 commits into
mainfrom
ys/single-artifact
Open

BornPsych wants to merge 12 commits into
mainfrom
ys/single-artifact

Conversation

@BornPsych

Copy link
Copy Markdown
Collaborator

Summary

mavros compile used to write two files that only work as a pair: r1cs.bin (header, digest, manifest, R1CS) and basic.json (bytecode and ABI, unversioned, outside the digest). Nothing tied them together, so a stale pair could make the manifest and the bytecode disagree on the witness layout. This PR folds everything into one file (target/program.mavros).

Supersedes #424, which carried the same three commits stacked on #414 from a fork.

Closes #418

@github-actions

Copy link
Copy Markdown
Contributor

Overall success rate on test cases: 100.0%

No test improvements or size changes detected.

Comparison Base Details

Compared against: STATUS.md artifact from bfb46f5

@github-actions

Copy link
Copy Markdown
Contributor

Overall success rate on test cases: 100.0%

No test improvements or size changes detected.

Comparison Base Details

Compared against: Committed STATUS.md at a4f2a3d (MavrosBot)

@BornPsych BornPsych self-assigned this Oct 22, 2026
@BornPsych
BornPsych marked this pull request as ready for review October 22, 2026 14:02
@BornPsych BornPsych assigned iamrecursion and unassigned BornPsych Oct 22, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Overall success rate on test cases: 100.0%

No test improvements or size changes detected.

Comparison Base Details

Compared against: Committed STATUS.md at a4f2a3d (MavrosBot)

@iamrecursion iamrecursion left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Good stuff in general, but a few concerns:

  • We no longer have a digest that covers just the circuit. The only digest now covers bytecode and ABI JSON, so a codegen change can move the digest even if the circuit is the same. I think we should additionally expose a circuit_digest() that covers the R1CS plus the manifest, and the program digest should cover that plus the bytecode and ABI.
  • As is, the compiler version is hard to use for diagnostics as it can only be read after a fully successful parse. Make it peekable so that it can be used for errors in place of the static COMPILER_VERSION or CARGO_PKG_VERSION.
  • verifier.json is not tied to the artifact it came from in any way. It should be.
  • Nothing runs witgen or AD from artifact.bytecode() with artifact.r1cs(). compile_writes_one_artifact only checks the header's entry_blob_field_count. One round-trip run would cover how consumers actually use the file, so should be added.

Comment thread mavros-artifacts/src/manifest.rs Resolved
Comment thread README.md Resolved
Comment thread README.md Resolved
Comment thread mavros-artifacts/src/manifest.rs Resolved
Comment thread mavros-artifacts/src/manifest.rs Resolved
@github-actions

Copy link
Copy Markdown
Contributor

Overall success rate on test cases: 100.0%

No test improvements or size changes detected.

Comparison Base Details

Compared against: STATUS.md artifact from 95b1ca4

@github-actions

Copy link
Copy Markdown
Contributor

Overall success rate on test cases: 100.0%

No test improvements or size changes detected.

Comparison Base Details

Compared against: Committed STATUS.md at b7f1725 (MavrosBot)

@iamrecursion iamrecursion left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The style of the new documentation is extremely verbose and hard to follow. Please try and make it much more clear and concise.

Comment on lines +8 to +9
//! The magic, format version and compiler version form the [`ArtifactPreamble`], laid out the same
//! in every format version so that a reader can name the compiler that wrote a file it cannot

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

It is not laid out the same in every format version. If you mean to make a promise about future compatibility, then please make that explicitly.

("entry past the end", |b| b[17] = 99),
("no code after the header", |b| b.truncate(19)),
("no AD entry", |b| b[18] = NO_ENTRY_POINT as u64),
("witgen entry only", |b| {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This case never reaches the missing-AD branch as the case removes word 19 but the remaining entry still points at 19. The bytecode is now only 19 words long, so it fails on the "header points past its own end" check instead.

}

/// The digest is a compatibility promise to consumers that record it: pin its encoding.
/// Words: 0 magic, 1 version, 2 field, 3 layout tag, 4..12 layouts, 12 pool length,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This word map is off by one from word 12 on.

return Err("the bytecode's constraint layouts disagree with the R1CS".to_string());
}
let len = bytecode.len();
if header.code_start > len

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

header.code_start > len is always false as far as I can tell.

|| header
.entry_points
.iter()
.any(|&entry| entry != NO_ENTRY_POINT && entry >= len)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This bounds check is not as strong as the layout it guards. An entry is a function marker, with its frame size at +1 and its first opcode at +2. Yet entry >= len accepts an entry at the last word or inside the header.

Comment on lines +355 to +356
/// bytecode and ABI: the identity of the whole file, which the header carries. Pin it to mean
/// "these exact bytes".

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This is inaccurate as the compiler string is outside the digest. Say what it actually means.

Comment thread README.md
Comment on lines +82 to +83
matrices are required at runtime. Compare the verifier's `circuit_digest` with the artifact's before
trusting the pair. Verifier execution uses a dedicated forward bytecode entry point: witness writes

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This claims more than the check actually provides. The circuit_digest in verifier.json is a field the file declares about itself. Nothing hashes the verifier bytecode or binds it to that value. So the comparison catches mixing up files from different circuits, not a forged verifier.

The base's wording was much more accurate.

@iamrecursion iamrecursion added the enhancement New feature or request label Oct 29, 2026
@github-actions

github-actions Bot commented Nov 2, 2026

Copy link
Copy Markdown
Contributor

bn254

bn254 success rate on test cases: 100.0%

No test improvements or size changes detected.

goldilocks

goldilocks success rate on test cases: 50.5%

No test improvements or size changes detected.

Comparison Base Details

Compared against: STATUS.md artifact from fda6ae6

@github-actions

github-actions Bot commented Nov 3, 2026

Copy link
Copy Markdown
Contributor

bn254

bn254 success rate on test cases: 100.0%

No test improvements or size changes detected.

goldilocks

goldilocks success rate on test cases: 51.6%

No test improvements or size changes detected.

Comparison Base Details

Compared against: Committed STATUS.md at da1c83b (MavrosBot)

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

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Emit one self-describing artifact instead of two (r1cs.bin + basic.json)

2 participants