Skip to content

C++ stepwise comparison #210

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

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

sellout
Copy link
Collaborator

@sellout sellout commented Apr 21, 2025

This PR exposes stepwise evaluation on the C++ and runs it against the Rust side to ensure the state is identical every step of the way.

There are two commits here. The first one makes minimal changes to the C++ interpreter to expose an EvalStep function. It should be reviewed with whitespace ignored, since the body of the interpreter is reindented without changes.

The second commit implements the comparison work, changing the zcash_script.h interface.

@sellout
Copy link
Collaborator Author

sellout commented Apr 21, 2025

BLOCKER: Stepwise comparison currently leaks ZcashScriptState on each call to zcash_script_eval_step. Before I spend too much time on it, I’d like to know whether the FFI approach I’m using is right and what the best way to delete these vectors (actually, pointers to vector::data()) would be.

@sellout sellout force-pushed the c++-stepwise-comparison branch from 279fafa to 99f3e88 Compare April 21, 2025 18:54
sellout added 3 commits April 21, 2025 14:54
This is as minimal as possible, and should be reviewed with whitespace
ignored.

This adds a new `EvalStep` function that contains the bulk of the
interpreter, with `EvalScript`’s `while` loop calling `EvalStep`.
@sellout sellout force-pushed the c++-stepwise-comparison branch from 99f3e88 to 3de50e0 Compare April 21, 2025 20:58
sellout added a commit to sellout/zcash_script that referenced this pull request May 20, 2025
Well, my _tiny_ edge case of “only if the 202nd operation is a disabled opcode” didn’t slip past the
fuzzer. It caught that pretty quickly.

So, this does a better job of normalizing errors for comparisons.

First, it normalizes both the C++ and Rust side, which allows the Rust error cases to not be a
superset of the C++ error cases. Then, it also normalizes errors in the stepwise comparator (which I
think was done in ZcashFoundation#210, but it’s reasonable to do along with these other changes).

Then it handles a couple “ambiguous” cases. One was already done – `UNKNOWN_ERROR` on the C++
side with `interpreter::Error::Num` on the Rust side, but now it’s handled differently. The other is
the edge case I introduced earlier in this PR – Rust will fail with a `DisabledOpcode` and C++ will
fail with a `OpCount`, so those two cases have been unified.
sellout added a commit to sellout/zcash_script that referenced this pull request May 20, 2025
Well, my _tiny_ edge case of “only if the 202nd operation is a disabled opcode” didn’t slip past the
fuzzer. It caught that pretty quickly.

So, this does a better job of normalizing errors for comparisons.

First, it normalizes both the C++ and Rust side, which allows the Rust error cases to not be a
superset of the C++ error cases. Then, it also normalizes errors in the stepwise comparator (which I
think was done in ZcashFoundation#210, but it’s reasonable to do along with these other changes).

Then it handles a couple “ambiguous” cases. One was already done – `UNKNOWN_ERROR` on the C++
side with `interpreter::Error::Num` on the Rust side, but now it’s handled differently. The other is
the edge case I introduced earlier in this PR – Rust will fail with a `DisabledOpcode` and C++ will
fail with a `OpCount`, so those two cases have been unified.
sellout added a commit to sellout/zcash_script that referenced this pull request May 22, 2025
Well, my _tiny_ edge case of “only if the 202nd operation is a disabled opcode” didn’t slip past the
fuzzer. It caught that pretty quickly.

So, this does a better job of normalizing errors for comparisons.

First, it normalizes both the C++ and Rust side, which allows the Rust error cases to not be a
superset of the C++ error cases. Then, it also normalizes errors in the stepwise comparator (which I
think was done in ZcashFoundation#210, but it’s reasonable to do along with these other changes).

Then it handles a couple “ambiguous” cases. One was already done – `UNKNOWN_ERROR` on the C++
side with `interpreter::Error::Num` on the Rust side, but now it’s handled differently. The other is
the edge case I introduced earlier in this PR – Rust will fail with a `DisabledOpcode` and C++ will
fail with a `OpCount`, so those two cases have been unified.
@mpguerra mpguerra added this to Zebra Jun 2, 2025
@mpguerra mpguerra requested a review from conradoplg June 2, 2025 13:55
@mpguerra mpguerra moved this to Review/QA in Zebra Jun 2, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Review/QA
Development

Successfully merging this pull request may close these issues.

2 participants