Skip to content

Remove collateral from transactions without Plutus scripts#1265

Open
palas wants to merge 2 commits into
masterfrom
1261-fix1-skip-collateral-without-plutus
Open

Remove collateral from transactions without Plutus scripts#1265
palas wants to merge 2 commits into
masterfrom
1261-fix1-skip-collateral-without-plutus

Conversation

@palas

@palas palas commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Context

This is the first of three stacked PRs fixing #1261: the balancing functions
(makeTransactionBodyAutoBalance and estimateBalancedTxBody, in both the traditional and the
experimental 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️⃣

🚪 #1261 the issue: transaction build does not validate min UTxO value of the collateral return output
1️⃣ (this PR) remove collateral from transactions without Plutus scripts
2️⃣ #1266 fail on invalid computed collateral instead of building a rejected transaction
3️⃣ #1267 fold return collateral dust into the total collateral

This 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. Since
the 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

  • The first commit adds four regression tests (one per balancing function) that fail on master;
    the second commit makes them pass. Check out the first commit alone and run the
    cardano-api-test suite to see them fail.
  • The fix is a single entry-point normalization: collateral inputs are dropped when
    collectTxBodyScriptWitnesses finds no Plutus script witnesses; everything downstream is
    unchanged.
  • The ledger rule that makes this safe: collateral validation (validateTotalCollateral in
    Babbage's feesOK) only runs when the transaction has redeemers.

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/

palas added 2 commits July 24, 2026 03:09
…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.

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.

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 makeTransactionBodyAutoBalance and estimateBalancedTxBody (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.

Comment thread .changes/20260723_cardano_api_collateral_without_plutus.yml
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.

[BUG] - transaction build does not validate min UTxO value of the collateral return output

2 participants