Skip to content

conway transaction build silently drops pre-Conway stake registration certificates #1349

@Jimbo4350

Description

@Jimbo4350

Summary

cardano-cli conway transaction build silently drops stake registration certificates that were created using the compatible command for pre-Conway eras (e.g. cardano-cli compatible shelley stake-address registration-certificate). The certificate does not appear in the built transaction and the stake address is never registered.

This does not affect cardano-cli conway transaction build-raw.

Affected versions

  • cardano-cli-10.15.0.0
  • cardano-cli-10.15.0.1

All earlier releases (<=10.14.0.0) used cardano-api ^>=10.20 or lower and are not affected.

Root cause

The bug is in cardano-api. During estimateBalancedTxBody, mapScriptWitnessesCertificates rebuilds the TxCertificates map from only the entries returned by indexTxCertificates:

https://github.com/IntersectMBO/cardano-api/blob/e42d72e2d2dfa4e4884d7e709547c7a8ccb061f2/cardano-api/src/Cardano/Api/Experimental/Tx/Internal/Fee.hs

indexTxCertificates only returns certificates with a Just (stakeCred, witness) entry — it pattern-matches on Just and silently drops Nothing entries:

indexTxCertificates (TxCertificates certsWits) =
  [ (ScriptWitnessIndexCertificate ix, cert, stakeCred, witness)
  | (ix, (cert, Just (stakeCred, witness))) <- zip [0 ..] $ toList certsWits
  ]

Pre-Conway registration certificates (ConwayRegCert cred SNothing) do not require a witness during the Conway transition period, so getTxCertWitness returns Nothing for them. This means they are dropped by mapScriptWitnessesCertificates when estimateBalancedTxBody rebuilds the certificate map.

The fix is to preserve Nothing-witness certificates in mapScriptWitnessesCertificates rather than discarding them.

Background

Using a pre-Conway registration certificate in Conway is valid and intentional by ledger design. The Conway ledger accepts ConwayRegCert cred SNothing (old-style, no explicit deposit) during the transition period, taking the deposit from the ppKeyDepositL protocol parameter. See: https://github.com/IntersectMBO/cardano-ledger/blob/4e182984fa4b442ca2dd75ec86f1cfda5c59a208/eras/conway/impl/src/Cardano/Ledger/Conway/TxCert.hs#L451-L454

Steps to reproduce

cardano-cli compatible shelley stake-address registration-certificate \
  --stake-verification-key-file stake.vkey \
  --out-file stake.cert

cardano-cli conway transaction build \
  --tx-in <utxo> \
  --certificate-file stake.cert \
  --change-address <addr> \
  --out-file tx.raw

cardano-cli debug transaction view --tx-file tx.raw
# "certificates": null  ← certificate was dropped

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions