Skip to content

feat(outbox): produce outbox proofs#808

Open
victor-dumitrescu wants to merge 5 commits intomainfrom
vdum/rv-877
Open

feat(outbox): produce outbox proofs#808
victor-dumitrescu wants to merge 5 commits intomainfrom
vdum/rv-877

Conversation

@victor-dumitrescu
Copy link
Contributor

@victor-dumitrescu victor-dumitrescu commented Feb 11, 2026

Closes RV-872. Closes RV-877.

What

The outbox can now produce a proof for an outbox message. A proof contains the message metadata and a Merkle proof which ties the inclusion of the given message in the outbox with a particular state hash.

Why

The outbox needs to support inclusion proofs for messages.

How

The OutboxProof type is introduced, along with Output and OutputInfo, which model Tezos protocol types.

Outbox proofs employ the same proof production mechanism used for fraud proofs. The difference is that the proven state transition is not one step of the PVM but a successful read of the given message from the outbox. The outbox is thus also expanded with the ability to read a single message.

Manually Testing

make all

In particular, the test_outbox_proofs_dummy_kernel test.

Regressions

A regression for an outbox proof for the first message of the last level of the dummy kernel is checked in.

Tasks for the Author

  • Link all Linear issues related to this MR using magic words (e.g. part of, relates to, closes).
  • Eliminate dead code and other spurious artefacts introduced in your changes.
  • Document new public functions, methods and types.
  • Make sure the documentation for updated functions, methods, and types is correct.
  • Add tests for bugs that have been fixed.
  • Explain changes to regression test captures when applicable.
  • Write commit messages in agreement with our guidelines.
  • Self-review your changes to ensure they are high-quality.
  • Complete all of the above before assigning this MR to reviewers.

@codecov
Copy link

codecov bot commented Feb 11, 2026

Codecov Report

❌ Patch coverage is 96.42857% with 11 lines in your changes missing coverage. Please review.
✅ Project coverage is 91.16%. Comparing base (c98f128) to head (301d866).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
src/riscv/lib/src/pvm/outbox.rs 98.04% 4 Missing and 1 partial ⚠️
src/riscv/lib/src/pvm/node_pvm.rs 0.00% 4 Missing ⚠️
src/riscv/lib/src/pvm/common.rs 96.87% 0 Missing and 1 partial ⚠️
src/riscv/lib/src/stepper/pvm.rs 93.33% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #808      +/-   ##
==========================================
+ Coverage   91.10%   91.16%   +0.06%     
==========================================
  Files         110      110              
  Lines       20913    21206     +293     
  Branches    20913    21206     +293     
==========================================
+ Hits        19052    19333     +281     
- Misses       1488     1498      +10     
- Partials      373      375       +2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@victor-dumitrescu victor-dumitrescu force-pushed the vdum/rv-877 branch 2 times, most recently from 76fdfcc to 0886566 Compare February 11, 2026 10:32
@victor-dumitrescu victor-dumitrescu marked this pull request as ready for review February 11, 2026 10:47
@github-actions
Copy link

github-actions bot commented Feb 11, 2026

Benchmark results for revision c3a446c:

Metric Duration TPS
Mean 1.528951897s 26.162
Worst 1.540370312s 25.968
Best 1.521102946s 26.297
Standard Deviation ±5.973894ms ±0.102
Full results
Run Transfers Duration TPS
1 40 1.536132429s 26.039
2 40 1.537733353s 26.012
3 40 1.523636957s 26.253
4 40 1.537448994s 26.017
5 40 1.525626483s 26.219
6 40 1.525423517s 26.222
7 40 1.538525564s 25.999
8 40 1.522496032s 26.273
9 40 1.528819503s 26.164
10 40 1.526859912s 26.198
11 40 1.521102946s 26.297
12 40 1.527209634s 26.192
13 40 1.523487918s 26.256
14 40 1.532344032s 26.104
15 40 1.523018678s 26.264
16 40 1.526718663s 26.200
17 40 1.532351207s 26.104
18 40 1.540370312s 25.968
19 40 1.525832874s 26.215
20 40 1.523898923s 26.248

Compare the results above with those for the default branch.

@emturner
Copy link
Contributor

Mean 1.543554521s 25.915

There seems to be a performance drop, perhaps?

Copy link
Contributor

@emturner emturner left a comment

Choose a reason for hiding this comment

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

overall LGTM

@victor-dumitrescu victor-dumitrescu force-pushed the vdum/rv-877 branch 4 times, most recently from 592faa4 to 01886c1 Compare February 12, 2026 14:07
Copy link
Contributor

@thomasathorne thomasathorne left a comment

Choose a reason for hiding this comment

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

Generally looks great!

Have a few questions about the different error cases and how they are currently tested (or not tested). I may have misunderstood something as some of the errors output in the tests aren't what I expected! 😅 At any rate, the different cases could be clarified a bit.

@victor-dumitrescu victor-dumitrescu force-pushed the vdum/rv-877 branch 2 times, most recently from fec1f02 to ec13689 Compare February 13, 2026 09:16
@victor-dumitrescu
Copy link
Contributor Author

Mean 1.543554521s 25.915

There seems to be a performance drop, perhaps?

This PR now also contains a small PVM state restructuring which @emturner discovered offsets the slight dip in performance.

}
}

/// Write `message` to the outbox at the current level. Returns `Err(OutboxFull)`
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
/// Write `message` to the outbox at the current level. Returns `Err(FullOutbox)`

Copy link
Contributor

@thomasathorne thomasathorne left a comment

Choose a reason for hiding this comment

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

Ok, I've understood the different error cases now---sorry for my confusion earlier.

I still think if you want to make it really clear what is being tested in each case, adding a few more cases to the OutboxProofError enum would help. Unless I am missing something I think there are still two cases that aren't tested: the case where the outbox is uninitialised and the case where we try to read from a level that doesn't exist yet.

Splitting LevelNotFound into three cases (OutboxUninitialised, LevelTooOld and LevelNotReachedYet) would clarify this.

But this is more a stylistic choice than anything else, happy for you to resolve this comment if you want.

Comment on lines +483 to +491
return Err(SbiError::OutputTooLarge);
}
let boxed_slice = vec![0u8; size].into_boxed_slice();
Ok(OutboxMessage(boxed_slice))
}
}

impl TryFrom<Box<[u8]>> for OutboxMessage {
type Error = OutboxProofError;
Copy link

@zcabter zcabter Feb 13, 2026

Choose a reason for hiding this comment

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

On line 483, the error type is SbiError where as on line 491 the error type is OutboxProofError. try_from Error type should really be generic across contexts.

Does it make sense to use an OutboxError type then map those to Proof or SBI errors depending on the context? The other thing that we could do is to have try_from return the SbiError then map it to a Proof error as you need it.

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.

4 participants