fix: accept SOption(T) where T expected in check_post_eval_tpe#860
Open
mwaddip wants to merge 3 commits into
Open
fix: accept SOption(T) where T expected in check_post_eval_tpe#860mwaddip wants to merge 3 commits into
mwaddip wants to merge 3 commits into
Conversation
Pin two ergoTree fixtures from output[0] and output[2] of tx dce90de114a7d36cb2dd724c04ccc11b461a02bd2a783ef820234046cb47ff2c in mainnet block 1,711,120. output[0] reproduces the InvalidExprEvalTypeError "expected SColl(SByte), got SOption(SColl(SByte))" that blocks ergo-node-rust v0.3.1 from advancing past this height. The script uses blake2b256(getVar[Coll[Byte]](1)) without an explicit .get unwrap; the JVM v6.0.3 reference parses it without complaint because OneArgumentOperationSerializer uses an unchecked asValue[T] cast at parse time. output[2] is added at the same time as a paired round-trip check — already passes today, but locks in protection against future regressions that break only one of the two boxes. The output[0] test is expected to fail with this commit; the following commit makes it pass. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
JVM v6.0.3 sigmastate-interpreter never type-checks at parse time — OneArgumentOperationSerializer uses asValue[T] (an unchecked cast) and the predef Lambda arms it dispatches into perform no validation. Real on-chain scripts pass getVar[T](id) (post-eval SOption(T)) directly into combinators that statically expect T (e.g. blake2b256). Without this leniency sigma-rust rejects txs the JVM accepts, breaking consensus. Mainnet block 1,711,120 tx[1] output[0] is the observed reproducer: script computes blake2b256(getVar[Coll[Byte]](1)) without .get and the parser bails inside CalcBlake2b256::try_build with "InvalidExprEvalTypeError: expected SColl(SByte), got SOption(SColl(SByte))". The widened predicate accepts the Option wrapping at parse time; evaluation-time behavior is unchanged (evaluator's UnexpectedValue arm still fires if the script actually runs, matching JVM runtime). Same widening covers identical-shape failures from CalcSha256, ByteArrayToBigInt/Long, DecodePoint, Extract*, LongToByteArray, SigmaPropBytes, LogicalNot, CreateProveDlog, SubstConstants, CreateProveDhTuple, CreateAvlTree, TreeLookup, OptionGetOrElse — all 27 check_post_eval_tpe call sites in the workspace. Regression test (added in prior commit) now passes. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The crate has #![deny(clippy::expect_used)] and the surrounding tests module only allows clippy::unwrap_used and clippy::panic. Switch the two new regression tests to .unwrap() to match the existing convention in this file. No semantic change — both helpers still panic with the underlying parse error on failure. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Widens Expr::check_post_eval_tpe to accept SOption(T) where T is expected — matches JVM OneArgumentOperationSerializer.parse's unchecked asValue[T] cast. Without this, sigma-rust rejects mainnet block 1,711,120 tx dce9…ff2c (uses blake2b256(getVarColl[Byte]) without .get).
Eval-time type check unchanged — UnexpectedValue still fires at runtime if the var is missing.