Skip to content

Fail instead of silently dropping Plutus scripts the era does not support - #1363

Open
carbolymer wants to merge 1 commit into
masterfrom
mgalazyn/fix/unsupported-plutus-language-error
Open

carbolymer wants to merge 1 commit into
masterfrom
mgalazyn/fix/unsupported-plutus-language-error

Conversation

@carbolymer

@carbolymer carbolymer commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

cardano-api dropped Plutus scripts silently when the era did not support their language.
This PR turns both cases into errors.

makeUnsignedTx now fails with MakeUnsignedTxPlutusLanguageNotSupportedInEra when an inline Plutus script uses a language the era does not support.
Before, the script was dropped from the witness set while its redeemer was kept, and the transaction failed on submission.
getAnyWitnessScript and getAnyPlutusWitnessPlutusScript now return Either L.Language instead of Maybe.
getTxScriptWitnessRequirements and getTxScriptWitnessesRequirements now return Either L.Language (TxScriptWitnessRequirements era) instead of TxScriptWitnessRequirements era.
This is a breaking change to the experimental API.

createTransactionBody now fails with TxOutputReferenceScriptLanguageNotSupportedInEra when an output or the return collateral carries a reference script in a language the era does not support.
Before, the output was built without the script.
This adds a constructor to TxOutputError, which is a breaking change.

The test generators now take the supported Plutus languages from scriptLanguageSupportedInEra.
The Plutus V4 generators use a validator compiled against Plutus V4 with plutus 1.70; its bytes equal the V3 always-succeeds script, because the validator ignores its argument.

Context

Found while adding Plutus V4 support to cardano-cli:

Enabling Plutus V4 in the Dijkstra era is stacked on this PR and waits for a ledger fix:

How to trust this PR

Three new properties in Test.Cardano.Api.Transaction.Body.Plutus.Scripts: an inline Plutus V4 witness is rejected in Conway, a Plutus V4 reference witness is still accepted, and createTransactionBody rejects a Plutus V4 reference script on a Conway output.
A new golden covers the error message.
All tests in cardano-api-test and cardano-api-golden pass.

Checklist

  • Commit sequence broadly makes sense and commits have useful messages
  • New tests are added if needed and existing tests are updated. See Running tests for more details
  • Self-reviewed the diff
  • Changelog fragment added in .changes/

@carbolymer
carbolymer added this pull request to stack #1364 September 30, 2026 13:48
@carbolymer carbolymer changed the title Fail instead of silently dropping Plutus scripts unsupported by the era Reject Plutus scripts unsupported by the era instead of silently dropping them Sep 30, 2026
@carbolymer carbolymer self-assigned this Sep 30, 2026
@carbolymer
carbolymer force-pushed the mgalazyn/fix/unsupported-plutus-language-error branch 2 times, most recently from 1c03d44 to ed67933 Compare October 1, 2026 19:25
@carbolymer carbolymer changed the title Reject Plutus scripts unsupported by the era instead of silently dropping them Fail instead of silently dropping Plutus scripts the era does not support Oct 1, 2026
@carbolymer
carbolymer force-pushed the mgalazyn/fix/unsupported-plutus-language-error branch from ed67933 to 62d4680 Compare October 1, 2026 20:13
@carbolymer
carbolymer marked this pull request as ready for review October 1, 2026 20:13
Copilot AI balanced review requested due to automatic review settings October 1, 2026 20:13

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

The dependency bump is misclassified and the experimental API migration note inaccurately describes two previous return types.

Review effort: Balanced
Findings: 3 Low severity

Open (3)
What changed in this PR

Prevents unsupported Plutus scripts from being silently omitted during transaction construction.

Changes:

  • Returns explicit errors for unsupported witness and reference-script languages.
  • Adds regression tests, V4 fixtures, and golden output.
  • Updates Plutus dependencies and changelog fragments.
File Description
flake.lock Updates the CHaP revision.
cardano-api/​test/​cardano-api-test/​Test/​Cardano/​Api/​Transaction/​Body/​Plutus/​Scripts.hs Adds unsupported-language regression tests.
cardano-api/​test/​cardano-api-golden/​Test/​Golden/​ErrorsSpec.hs Adds the new output-error golden case.
cardano-api/​test/​cardano-api-golden/​files/​errors/​Cardano.Api.Tx.Body.TxBodyError/​TxBodyOutputReferenceScriptLanguageNotSupportedInEra.txt Records the new error message.
cardano-api/​src/​Cardano/​Api/​Tx/​Internal/​Output.hs Validates output reference-script languages.
cardano-api/​src/​Cardano/​Api/​Tx/​Internal/​Body.hs Applies validation during body creation.
cardano-api/​src/​Cardano/​Api/​Experimental/​Tx/​Internal/​TxScriptWitnessRequirements.hs Propagates unsupported-language failures.
cardano-api/​src/​Cardano/​Api/​Experimental/​Tx/​Internal/​BodyContent/​New.hs Adds and returns the unsigned-transaction error.
cardano-api/​src/​Cardano/​Api/​Experimental/​Tx/​Internal/​AnyWitness.hs Changes script extraction to Either.
cardano-api/​src/​Cardano/​Api/​Experimental/​Plutus/​Internal/​Shim/​LegacyScripts.hs Adapts legacy witness conversion.
cardano-api/​src/​Cardano/​Api/​Experimental/​AnyScriptWitness.hs Detects unsupported inline script languages.
cardano-api/​gen/​Test/​Gen/​Cardano/​Api/​Typed.hs Restricts generation to supported languages.
cardano-api/​gen/​Test/​Gen/​Cardano/​Api/​Hardcoded.hs Adds Plutus V4 fixtures.
cardano-api/​cardano-api.cabal Requires Plutus 1.71 dependencies.
cabal.project Advances the CHaP index state.
.changes/​plutus-1-71-bump.yml Documents the dependency bump.
.changes/​legacy-tx-body-unsupported-reference-script-language-error.yml Documents the legacy API break.
.changes/​experimental-tx-unsupported-plutus-language-error.yml Documents the experimental API break.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

description: |
`makeUnsignedTx` now fails with `MakeUnsignedTxPlutusLanguageNotSupportedInEra` when an inline Plutus script uses a language the era does not support.
Before, the script was silently dropped from the witness set while its redeemer was kept, so the transaction failed on submission.
`getAnyWitnessScript`, `getAnyPlutusWitnessPlutusScript`, `getTxScriptWitnessRequirements` and `getTxScriptWitnessesRequirements` now return `Either L.Language` instead of `Maybe`.
Comment thread .changes/plutus-1-71-bump.yml Outdated
Comment on lines +228 to +229
-- | An inline Plutus witness must be rejected, not silently dropped with its
-- redeemer, when the era does not support its language. V4 fails in Conway.
@Jimbo4350

Copy link
Copy Markdown
Contributor

What about this approach? master...jordan/plutus-language-in-era-vs-master

@carbolymer
carbolymer force-pushed the mgalazyn/fix/unsupported-plutus-language-error branch from 62d4680 to 4f7d365 Compare October 7, 2026 07:19
The experimental transaction builder now returns MakeUnsignedTxPlutusLanguageNotSupportedInEra instead of dropping an inline script while keeping its redeemer.
createTransactionBody now fails with TxOutputReferenceScriptLanguageNotSupportedInEra for an output or return collateral whose reference script language is unsupported in the era.
The test generator derives Plutus languages from scriptLanguageSupportedInEra instead of a hand-rolled table with an undefined arm.
@carbolymer
carbolymer force-pushed the mgalazyn/fix/unsupported-plutus-language-error branch from 4f7d365 to b2764fd Compare October 7, 2026 13:33

This branch has not been deployed

No deployments
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.

3 participants