Skip to content

ADR-10 Script Witness API#67

Merged
Jimbo4350 merged 1 commit intomainfrom
jordan/adr-10-script-witness-api
Mar 13, 2025
Merged

ADR-10 Script Witness API#67
Jimbo4350 merged 1 commit intomainfrom
jordan/adr-10-script-witness-api

Conversation

@Jimbo4350
Copy link
Contributor

No description provided.

@Jimbo4350 Jimbo4350 requested review from a team as code owners March 7, 2025 16:25
Copy link
Contributor

@carbolymer carbolymer left a comment

Choose a reason for hiding this comment

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

Nice work. My main concern is about indexing logic: #67 (comment)


```haskell
data Witnessable thing era where
WitTxIn :: L.AlonzoEraScript era => TxIn -> Witnessable TxIn era
Copy link
Contributor

Choose a reason for hiding this comment

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

L.AlonzoEraScript era

I don't see it explained in the ADR - why not use our witnesses instead? i.e. why not

WitTxIn :: AlonzoEraOnwards era => TxIn -> Witnessable TxIn era

It would be more convenient I think, without exposing ledger constraints to cardano-api users.

I'm ok with using more and more ledger types, but I'm not sure about ledger constraints. This will be more confusing for the users if they have ledger constraints in the function signature. One would have to figure out the connection between a ledger constraint and our API, meaning, find out the right function bringing the constraint into the scope.

This means they would have to deal with both: eons and ledger constraints.

In case of using our eons, we can hide that plumbing behind the scenes.

Copy link
Contributor Author

@Jimbo4350 Jimbo4350 Mar 10, 2025

Choose a reason for hiding this comment

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

I added:

The ledger constraints in the Witnessable thing era data constructors allow us to directly construct the script witness index (PlutusPurpose AsIx era) with the toPlutusScriptPurpose class method. We no longer have to use the old api's ScriptWitnessIndex which is eventually converted into a PlutusPurpose AsIx era. This approach is more direct.

I'll need to think about it more. I don't see a nice way of constructing the index without adding more boiler plate or making the api more specific to either the old or experimental api.

Copy link
Contributor Author

@Jimbo4350 Jimbo4350 Mar 10, 2025

Choose a reason for hiding this comment

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

WitTxIn :: AlonzoEraOnwards era => TxIn -> Witnessable TxIn era

Because this puts us back to using eons which we don't want to use. The api I created is meant to be used with the old and new api. Sometimes we do reuse types from the old api but the eons are not one of them.

With the exception of getTxScriptWitnessesRequirements but that is called in legacyWitnessToScriptRequirements which is specific to the old api.

Copy link
Contributor

Choose a reason for hiding this comment

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

The api I created is meant to be used with the old and new api.

But the new API will be used in mainnet era onwards, so technically, we will always have the witness right?

My point is, I don't see any harm in using eons (old api) for now, and just removing them when we're done with old api.

Copy link
Contributor

@carbolymer carbolymer Mar 11, 2025

Choose a reason for hiding this comment

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

This is not a blocker from my side. I see exposing ledger constraints just as an inconvenience for the library user.

We can always hide them later, when moving to the new eras API, but that means one more breaking change.

Copy link
Contributor Author

@Jimbo4350 Jimbo4350 Mar 13, 2025

Choose a reason for hiding this comment

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

I'll have a think about this some more and see if I can come up with a nicer solution. I also want to see how this behaves in the cli.

compare a b =
case (a, b) of
(WitTxIn txinA, WitTxIn txinB) -> compare txinA txinB
(WitTxCert (certA, _), WitTxCert (certB, _)) -> compare certA certB
Copy link
Contributor

Choose a reason for hiding this comment

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

For certificates it's not technically 100% correct. Vide alonzo spec:

certificates in the DCert list are indexed in the order in which they arranged in the
(full, unfiltered) list of certificates inside the transaction

So if you read a transaction with an arbitrary order of certificates, and try to regenerate indices with this logic, you could get different indices.

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 catch, I forgot certs were in an OSet. I'll adjust the Eq instance.

@Jimbo4350 Jimbo4350 force-pushed the jordan/adr-10-script-witness-api branch from b9d9743 to bcce79a Compare March 11, 2025 13:48
compare a b =
case (a, b) of
(WitTxIn txinA, WitTxIn txinB) -> compare txinA txinB
(WitTxCert{}, WitTxCert{}) -> LT -- Certificates in the ledger are in an `OSet` therefore we preserve the order.
Copy link
Contributor

@carbolymer carbolymer Mar 11, 2025

Choose a reason for hiding this comment

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

This breaks Ord laws. I think it may also make some sorting algorithms not stable. Additionally, it will make the type unusable as a key in Data.Map.

Copy link
Contributor

@carbolymer carbolymer Mar 11, 2025

Choose a reason for hiding this comment

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

I think there's no clean way to implement this using Ord. You could extend witnessable certs with their original indices e.g.:

type Cert = (Word32, AnyCertificate, StakeCredential)

data Witnessable thing era where
  ...
  WitTxCert :: L.AlonzoEraScript era => Word32 -> Cert -> Witnessable Cert era

then you could implement Ord by simply sorting on that index.

The downside is that you'll require library user to set the index explicitly. A helper function [Cert] -> [Witnessable Cert era] would help here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed

@Jimbo4350 Jimbo4350 force-pushed the jordan/adr-10-script-witness-api branch from 67282ee to fe9df43 Compare March 13, 2025 15:38
@Jimbo4350 Jimbo4350 merged commit 0d50087 into main Mar 13, 2025
1 check failed
@Jimbo4350 Jimbo4350 deleted the jordan/adr-10-script-witness-api branch March 13, 2025 15:44
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.

2 participants