Skip to content

Allow providing of actual datum for reference inputs #814

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 12, 2025

Conversation

carbolymer
Copy link
Contributor

@carbolymer carbolymer commented Apr 15, 2025

Changelog

- description: |
    Allow providing of actual datum for reference inputs in `TxInsReference`.
# uncomment types applicable to the change:
  type:
   - feature        # introduces a new feature
   - breaking       # the API has changed in a breaking way
  # - compatible     # the API has changed but is non-breaking
  # - optimisation   # measurable performance improvements
  # - refactoring    # QoL changes
  # - bugfix         # fixes a defect
  # - test           # fixes/modifies tests
  # - maintenance    # not directly related to the code
  # - release        # related to a new release preparation
  # - documentation  # change in code docs, haddocks...

Context

This PR adds a method of adding actual datum for the datum hashes present in reference inputs.

Tested in:

Integrated in CLI:

Closes #803

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

@carbolymer carbolymer self-assigned this Apr 15, 2025
@carbolymer carbolymer force-pushed the mgalazyn/feature/add-supplemental-data-from-txins branch from 65eb490 to 9803983 Compare April 18, 2025 06:20
@carbolymer carbolymer force-pushed the mgalazyn/feature/add-supplemental-data-from-txins branch 5 times, most recently from 1c26f76 to 1bd923a Compare April 30, 2025 15:35
@carbolymer carbolymer force-pushed the mgalazyn/feature/add-supplemental-data-from-txins branch 6 times, most recently from ee95c60 to 90f24cb Compare May 5, 2025 15:40
@carbolymer carbolymer changed the title Add supplemental data from txins Allow providing of datum for reference inputs May 6, 2025
@carbolymer carbolymer changed the title Allow providing of datum for reference inputs Allow providing of datum preimage for reference inputs May 6, 2025
@carbolymer carbolymer changed the title Allow providing of datum preimage for reference inputs Allow providing of actual datum for reference inputs May 6, 2025
@carbolymer
Copy link
Contributor Author

@mmontin This should implement #803 . What do you think about the design here?

@carbolymer carbolymer force-pushed the mgalazyn/feature/add-supplemental-data-from-txins branch from 90f24cb to 26567cf Compare May 6, 2025 14:41
@carbolymer carbolymer requested a review from Jimbo4350 May 6, 2025 14:41
@carbolymer carbolymer marked this pull request as ready for review May 6, 2025 14:41
@carbolymer carbolymer force-pushed the mgalazyn/feature/add-supplemental-data-from-txins branch from 26567cf to 0ff447b Compare May 6, 2025 14:41
@carbolymer carbolymer force-pushed the mgalazyn/feature/add-supplemental-data-from-txins branch from 0ff447b to 481f365 Compare May 6, 2025 14:55
Copy link
Contributor

@Jimbo4350 Jimbo4350 left a comment

Choose a reason for hiding this comment

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

LGTM 👍 . Get input from the ledger team regarding naming and we can finalize that aspect.

TxInsReference
:: BabbageEraOnwards era
-> [TxIn]
-> TxInsReference era
-- ^ A list of reference inputs
-> TxInsReferenceActualDatums build
Copy link
Contributor

Choose a reason for hiding this comment

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

TxInsReferenceAdditionalDatums? Can you run this by the ledger team. We should also get their input, it would be useful.

Copy link
Contributor

Choose a reason for hiding this comment

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

How about TxInsReferenceResolvedDatums?

Copy link
Contributor

@mmontin mmontin left a comment

Choose a reason for hiding this comment

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

Thanks a lot for implementing this ! I believe this feature, while somewhat a corner case, is very important to have.

In terms of the actual implementation, I have two general comments / remarks on top of the small comments I left here and there

  1. I wonder why these additional datums are given as a set directly inside TxInsReference instead of input by input. This breaks the link as to which input is supposed to bear which datum hash. In other words, why not couple each TxIn with a Maybe HashableScriptData in a structure (let's call it RefInputWithDatum) and have TxInsReference take a list of those?

  2. About the need of providing a UTxO here and there. I understand the need for this structure. It allows to ensure that the provided datums do indeed correspond to the resolved variants of hashed datums in reference inputs. However, this will be caught later on in the pipeline anyway as the ledger with throw an error when they do not. So is this necessary to ensure this here? Admittedly, I don't have a full picture as to which properties need to be satisfied by createTransactionBody and are expected to hold by the caller. However, it makes the implementation more involved, and also forces the caller to build this UTxO and understand that it corresponds to the corner case of providing resolved datums to reference inputs. Additionally, since the current implementation seems to just ignore datums that do not correspond to hashed datums in ref inputs, there is no clear way to bypass this requirement for testing purposes. And I believe this is dangerous that this process is silent. This makes me wonder if there are other places in the code base where silent discards are performed.

TxInsReference
:: BabbageEraOnwards era
-> [TxIn]
-> TxInsReference era
-- ^ A list of reference inputs
-> TxInsReferenceActualDatums build
Copy link
Contributor

Choose a reason for hiding this comment

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

How about TxInsReferenceResolvedDatums?

Comment on lines 1121 to 1123
:: Applicative (BuildTxWith build)
=> IsBabbageBasedEra era
=> TxIn
-> TxBodyContent build era
-> TxBodyContent build era
Copy link
Contributor

Choose a reason for hiding this comment

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

It seems weird that addTxInsReference allows to provide the full datums for the given list of TxIn while addTxInReference does not for its own TxIn. I would expect to have an additional argument of type Maybe HashableScriptData.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point, added, thanks.

Comment on lines 3108 to 3114
[ d
| TxInsReference _ txIns datumSet <- [txInsRef]
, let datumMap = getReferenceInputDatumMap datumSet
, txIn <- txIns
, -- resolve only hashes
TxOut _ _ (TxOutDatumHash _ datumHash) _ <- maybeToList $ UTxO.lookup txIn utxo
, d <- maybeToList $ Map.lookup datumHash datumMap
Copy link
Contributor

Choose a reason for hiding this comment

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

It seems that this will silently ignore datums that do not correspond to hashed datums in the reference inputs. Is there any way to make this visible? Are there other places where such elements are ignored under the hood?

@carbolymer
Copy link
Contributor Author

carbolymer commented May 7, 2025

@mmontin Good remarks thanks!

ad 2. I agree. Passing UTXO around mostly gets in the way, without any real benefit here. I think we could skip it, ditch the filtering and do the validation at transaction submission step (by ledger).

ad 1. Assuming we remove the necessity of passing UTXO: tying TxIns with datum values would only make sense if we have UTXOs of reference inputs in the scope, and we would validate that respective datum is at the right input. I agree that there's a link there, but I'm not sure there's a value in that information: this link gets "lost" when the transaction gets submitted to the ledger. So the constructor TxInsReference would potentially look similar to this:

 TxInsReference
    :: BabbageEraOnwards era
    -> [( TxIn
        , BuildTx build (Maybe HashableScriptData)
        )
       ]
    -> TxInsReference build era

which would complicate handling of the type a bit: the values would have to be zipped and unziped when constructing and deconstructing the type.
Do you have an example, where this form of TxInsReference would be beneficial?

@mmontin
Copy link
Contributor

mmontin commented May 7, 2025

About location of datums in the body. Your point makes sense, it would be unwise to complicate the type for no valid reason. And to be honest, the current version where the datum are grouped into a set would be suitable enough for my use case and overall satisfactory, in my opinion. However, I see 2 reasons why the other option also makes sense, based on my current understanding of cardano-api and my current biases as to how I use it in cooked-validators:

  1. Consistency: Currently, the second use case for supplemental datums (when paying outputs with hashed datums) is handled locally, within the TxOut itself. Technically, TxOutSupplementalDatum is the same as TxOutDatumHash with the exception that the full datum will be given to the transaction. This means that TxOutSupplementalDatum could technically be removed and, instead, the txOuts field of the TxBodyContent could be typed:
TxOuts
   :: BabbageEraOnwards era -- not sure about Babbage, but not so relevant for the example
   -> [TxOut ctx era]
   -> Set (BuildTx build HashableScriptData)
   -> TxOuts build era

I am definitely not advocating for such a change, just pointing out that the choice was made to have these supplemental datums be handled within each TxOut instead of grouped outside. Admittedly, this makes a lot more sense here, because the TxOuts naturally contain a datum, as opposed to TxIn which are merely ids. That being said, handling supplemental datums similarly for the second possible use case would make sense and likely be more familiar to future users relying on this new feature.

  1. Locality: This one is more related to my personal bias, but I like when the information is as close as possible to where it belongs. Granted, this will be lost later on in the pipeline, but I see cardano-api transaction bodies as an opportunity to layout pieces of information in a more local way as the transaction produced by the ledger and given to the scripts. Having these supplemental datums defined locally would feel just right (for me at least) and this is the place where I would naturally search for this information. That being said, having the datum a bit higher up does not hurt and they could also be found quite easily there.

I feel like this second point is not quite as strong as I thought when I decided to write it, because it's mostly just based on a feeling, and I leave it to you to take it into account or not. Regardless, I hope these points are of help in making the final decision.

@carbolymer carbolymer force-pushed the mgalazyn/feature/add-supplemental-data-from-txins branch from fbe82fd to 481f365 Compare May 8, 2025 11:07
@Jimbo4350
Copy link
Contributor

  1. I wonder why these additional datums are given as a set directly inside TxInsReference instead of input by input. This breaks the link as to which input is supposed to bear which datum hash. In other words, why not couple each TxIn with a Maybe HashableScriptData in a structure (let's call it RefInputWithDatum) and have TxInsReference take a list of those?

What would be the purpose? You would lose the connection as soon as you construct a valid transaction.

However, this will be caught later on in the pipeline anyway as the ledger with throw an error when they do not.

I agree with this regarding removing the UTxO era parameter. cc: @carbolymer

@Jimbo4350
Copy link
Contributor

Jimbo4350 commented May 8, 2025

just pointing out that the choice was made to have these supplemental datums be handled within each TxOut instead of grouped outside.

I see your point but the TxOut type was designed this way so that consumers of cardano-api could easily differentiate between the different datums that exist at outputs.

I wouldn't include the "resolved datums' in the TxOut definition because currently it concerns itself with the creation of datums/datum hashes (or not) at outputs. The "resolved datums" feature is about including already existing datums in the datum map which to me means it should live with the reference inputs definition.

@carbolymer carbolymer force-pushed the mgalazyn/feature/add-supplemental-data-from-txins branch from 481f365 to e997263 Compare May 12, 2025 15:49
@carbolymer carbolymer enabled auto-merge May 12, 2025 16:00
@carbolymer carbolymer added this pull request to the merge queue May 12, 2025
Merged via the queue into master with commit 6897855 May 12, 2025
28 of 29 checks passed
@carbolymer carbolymer deleted the mgalazyn/feature/add-supplemental-data-from-txins branch May 12, 2025 16:15
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.

[FR] - Extra ScriptData for reference inputs with hashed datums
3 participants