Remove collateral from transactions without Plutus scripts#1265
Open
palas wants to merge 2 commits into
Open
Conversation
…ripts The ledger requires collateral only for transactions that run Plutus scripts, but makeTransactionBodyAutoBalance and estimateBalancedTxBody (traditional and experimental API) keep the collateral inputs and set the collateral fields whenever collateral inputs are present. With a collateral input holding exactly the minimum UTxO value, the computed return collateral output falls below its own minimum UTxO value and the ledger rejects the transaction at submission time with BabbageOutputTooSmallUTxO (issue #1261). Since the ledger ignores collateral on transactions without Plutus scripts, balancing should remove the collateral inputs and set no collateral fields. Add one regression test for each of the four functions, checking that balancing a transaction without Plutus scripts succeeds and that the result carries no collateral. The four tests currently fail. See: #1261
The ledger requires collateral only for transactions that run Plutus scripts, but makeTransactionBodyAutoBalance and estimateBalancedTxBody (traditional and experimental API) kept the collateral inputs and set the collateral fields whenever collateral inputs were present. For transactions without Plutus scripts, remove the collateral inputs at the start of balancing: the ledger ignores them, but they cost fees and require the collateral UTxOs to stay unspent. With the collateral inputs removed, no collateral fields (including the dummy ones used for fee estimation) are set either. This is the only case where the balancing functions modify the transaction inputs; a transaction that should become invalid when some UTxO is spent can use a reference input for that purpose.
palas
requested review from
CarlosLopezDeLara,
Jimbo4350,
carbolymer,
disassembler and
erikd
as code owners
July 24, 2026 02:46
Contributor
There was a problem hiding this comment.
Pull request overview
Adjusts the transaction balancer to avoid producing ledger-rejected transactions caused by unnecessary collateral on transactions that do not run Plutus scripts (issue #1261). The change normalizes collateral handling at the balancing entry points for both the traditional and experimental APIs and adds regression coverage.
Changes:
- Drop collateral inputs (and consequently avoid setting collateral fields) when the transaction contains no Plutus script witnesses in
makeTransactionBodyAutoBalanceandestimateBalancedTxBody(traditional + experimental). - Add regression tests covering the “no Plutus scripts ⇒ no collateral” expectation for both balancing functions (traditional + experimental).
- Add a Herald changelog fragment describing the behavior change.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| cardano-api/test/cardano-api-test/Test/Cardano/Api/Transaction/Autobalance.hs | Adds regression properties asserting collateral is removed during balancing when no Plutus scripts are present (traditional API). |
| cardano-api/test/cardano-api-test/Test/Cardano/Api/Experimental/Fee.hs | Adds regression properties asserting collateral is removed during balancing when no Plutus scripts are present (experimental API). |
| cardano-api/src/Cardano/Api/Tx/Internal/Fee.hs | Implements the collateral-dropping normalization (traditional balancing paths) and introduces hasPlutusScriptWitnesses. |
| cardano-api/src/Cardano/Api/Experimental/Tx/Internal/Fee.hs | Implements the collateral-dropping normalization (experimental balancing paths) and introduces hasPlutusScriptWitnesses. |
| .changes/20260723_cardano_api_collateral_without_plutus.yml | Adds changelog fragment for the fix. |
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.
Context
This is the first of three stacked PRs fixing #1261: the balancing functions
(
makeTransactionBodyAutoBalanceandestimateBalancedTxBody, in both the traditional and theexperimental API) could build transactions that the ledger rejects at submission time because of
their collateral. Each PR contains a pair of commits — regression tests that fail, then the fix
that makes them pass — and each PR is based on the previous one, so every diff shows only its own
two commits.
🗺️ Map — you are here: 1️⃣
transaction builddoes not validate min UTxO value of the collateral return outputThis PR: the ledger requires collateral only for transactions that run Plutus scripts, but
balancing keeps the collateral inputs and sets the collateral fields whenever collateral inputs
are present. With a collateral input holding exactly the minimum UTxO value, the computed return
collateral output falls below its own minimum UTxO value and the ledger rejects the transaction
with
BabbageOutputTooSmallUTxO— the #1261 failure, reachable without any Plutus script. Sincethe ledger ignores collateral on transactions without Plutus scripts, balancing now removes the
collateral inputs and sets no collateral fields. A transaction that should become invalid when
some UTxO is spent can use a reference input for that purpose.
How to trust this PR
master;the second commit makes them pass. Check out the first commit alone and run the
cardano-api-testsuite to see them fail.collectTxBodyScriptWitnessesfinds no Plutus script witnesses; everything downstream isunchanged.
validateTotalCollateralinBabbage's
feesOK) only runs when the transaction has redeemers.Checklist
.changes/