Skip to content
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

Resolve PartialTx inputs over LSQ #4630

Merged
merged 4 commits into from
Jun 27, 2024
Merged

Conversation

Anviking
Copy link
Member

@Anviking Anviking commented Jun 13, 2024

  • Add getUTxOByTxIn local state query
  • Resolve PartialTx inputs over LSQ in Cardano.Wallet.balanceTx

Comments

This is part of the fix for the integration test in the 8.11 branch; if we have the UTxO of the reference input containing the script used for minting in constructTx, then Ledger.getMinFeeTxUtxo pp tx utxo will correctly account for minFeeRefScriptCoinsPerByte * totalRefScriptSize.

Previous step: #4629
Next step: #4631

Issue Number

ADP-3373

@Anviking Anviking self-assigned this Jun 13, 2024
@Anviking Anviking changed the base branch from master to anviking/ADP-3373/wrap-balanceTx June 13, 2024 22:52
@Anviking Anviking force-pushed the anviking/ADP-3373/wrap-balanceTx branch 3 times, most recently from 81b160c to 620ff36 Compare June 25, 2024 11:00
Base automatically changed from anviking/ADP-3373/wrap-balanceTx to master June 25, 2024 12:54
@Anviking Anviking force-pushed the anviking/ADP-3373/getUTxOByTxIn branch 3 times, most recently from 24cb44d to fb6ec5d Compare June 26, 2024 10:33
@Anviking Anviking marked this pull request as ready for review June 26, 2024 10:33
@@ -659,6 +661,10 @@ withNodeNetworkLayerBase
return res
Nothing -> pure $ StakePoolsSummary 0 mempty mempty

_getUTxOByTxIn queue ins =
Copy link
Member Author

@Anviking Anviking Jun 26, 2024

Choose a reason for hiding this comment

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

Not sure if this is already done under the hood, but it's probably worth adding a special case for mempty -> mempty. Then we'd incur no additional performance cost in the common path. No exchange and daedalus related tx creation will construct PartialTxs with existing inputs for lookup. Only the balanceTx endpoint, and constructTx in the specific case of minting using a reference input.

Copy link
Contributor

Choose a reason for hiding this comment

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

I agree that it's worth adding the special case — we don't want to do an IO roundtrip over the node socket if we already know the answer.

But which era should the result be in?

At the very least, calling getUTxOByTxIn will entail a query about the current node era — which we would need to cache in order to avoid sending something to the node.

Copy link
Member Author

Choose a reason for hiding this comment

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

But which era should the result be in?

Right, good point. Luckily we already have access to a cached value of the era, so it should be easy.

I think we could also imagine using your Data.These here with something isomorophic to Maybe (Data.These (UTxO ConwayEra) (UTxO BabbageEra)), to be able to return Just $ These mempty mempty, but doesn't seem worth it for this problem alone (particularly as Cardano.Wallet.balanceTx is still uncertain about the UTxO's era even when the node was queried)

Copy link
Member Author

Choose a reason for hiding this comment

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

Copy link
Contributor

@HeinrichApfelmus HeinrichApfelmus left a comment

Choose a reason for hiding this comment

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

Thank you! 😊

One request concerning the location of the new helper functions in balanceTx.

On the implementation of getUTxOByTxIn, I agree that it's worth adding the special case for mempty, because that avoids a roundtrip over the node socket. However, this requires information about the era in which we want to return the result. We can do this optimization later when cleaning up the NetworkLayer.

Comment on lines +156 to +158
, getUTxOByTxIn
:: Set Write.TxIn
-> m (MaybeInRecentEra Write.UTxO)
Copy link
Contributor

Choose a reason for hiding this comment

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

I think that we want

Suggested change
, getUTxOByTxIn
:: Set Write.TxIn
-> m (MaybeInRecentEra Write.UTxO)
, getUTxOByTxIn
:: Set Read.TxIn
-> m (Read.EraValue Read.UTxO)

at some point here — the function simply returns the UTxO in whatever era the node is currently in. But we can adjust that later, your version is fine for now.

@@ -659,6 +661,10 @@ withNodeNetworkLayerBase
return res
Nothing -> pure $ StakePoolsSummary 0 mempty mempty

_getUTxOByTxIn queue ins =
Copy link
Contributor

Choose a reason for hiding this comment

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

I agree that it's worth adding the special case — we don't want to do an IO roundtrip over the node socket if we already know the answer.

But which era should the result be in?

At the very least, calling getUTxOByTxIn will entail a query about the current node era — which we would need to cache in order to avoid sending something to the node.

Comment on lines 2219 to 2258
-- | 'assumeUTxOInEra era utxo' will convert the 'utxo' to the given era,
-- and throw an exception in 'IO' if the conversion fails.
--
-- It assumes the 'utxo' was queried from the node /after/ the 'era'.
assumeUTxOInEra
:: RecentEra era
-> MaybeInRecentEra Write.UTxO
-> IO (Write.UTxO era)
assumeUTxOInEra RecentEraConway (InRecentEraConway u)
= pure u
assumeUTxOInEra RecentEraBabbage (InRecentEraBabbage u)
= pure u
assumeUTxOInEra RecentEraBabbage (InRecentEraConway u)
-- The era changed to Conway between fetching the era and fetching the
-- utxo. Let's downgrade the utxo and continue.
= either (throwIO . ExceptionInvalidTxOutInEra) pure $ downgradeEra u
assumeUTxOInEra RecentEraConway (InRecentEraBabbage _)
-- It should be impossible for the node's tip to change from Conway back
-- to Babbage.
= impossibleRollback
assumeUTxOInEra _ InNonRecentEraAllegra
= impossibleRollback
assumeUTxOInEra _ InNonRecentEraAlonzo
= impossibleRollback
assumeUTxOInEra _ InNonRecentEraMary
= impossibleRollback
assumeUTxOInEra _ InNonRecentEraShelley
= impossibleRollback
assumeUTxOInEra _ InNonRecentEraByron
= impossibleRollback

impossibleRollback = error "assumeUTxOInEra: era should not roll back"

downgradeEra
:: Write.UTxO ConwayEra
-> Either Write.ErrInvalidTxOutInEra (Write.UTxO BabbageEra)
downgradeEra (Write.UTxO utxo) =
Write.utxoFromTxOutsInRecentEra
$ map (second Write.wrapTxOutInRecentEra)
$ Map.toList utxo
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you move these helper functions to Internal.Cardano.Write.Tx?

These function relate to the issue of converting MaybeInRecentEra Write.UTxO to a specific Write.UTxO era; their internal workings should not be a concern of balanceTx.

Notation: Instead of calling the function assumeUTxOInEra, I would call the function forceUTxOInEra, because the function can forcefully downgrade a Conway UTxO to a Babbage UTxO.

Copy link
Member

Choose a reason for hiding this comment

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

I would call the function forceUTxOInEra

In that case, would suggest changing "in" to "to", making it forceUTxOToEra.

Copy link
Member Author

Choose a reason for hiding this comment

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

Moved

forceUTxOToEra
    :: forall era1 era2. (IsRecentEra era1, IsRecentEra era2)
    => UTxO era1
    -> Either ErrInvalidTxOutInEra (UTxO era2)
forceUTxOToEra (UTxO utxo) =
    utxoFromTxOutsInRecentEra
    $ map (second wrapTxOutInRecentEra)
    $ Map.toList utxo

to Write.Tx, but left the dealing with the MaybeInRecentEra in a helper in Cardano.Wallet.balanceTx.

@@ -591,6 +594,18 @@ data TxOutInRecentEra =
(Maybe (AlonzoScript LatestLedgerEra))
-- Same contents as 'TxOut LatestLedgerEra'.

wrapTxOutInRecentEra
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not particularly fond of the TxOutInRecentEra type and the wrappings / unwrappings — why not directly type TxOutInRecentEra = TxOut LatestLedgerEra?

But we can fix that later, this is fine for now.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes — I started questioning it as well. Will fix in another PR 👍 (Would go with newtype though to avoid mixup)

Copy link
Member Author

Choose a reason for hiding this comment

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

On the other hand — defining TxOutInRecentEra in terms of the address, value, datum and script directly makes it a little more easy to use, e.g. in tests.

Copy link
Contributor

Choose a reason for hiding this comment

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

On the other hand — defining TxOutInRecentEra in terms of the address, value, datum and script directly makes it a little more easy to use, e.g. in tests.

Sure — but that's a general concern: Which functions do we have available for working with TxOut?

The answer that we have chosen by introducing Write is: "Whatever functions the cardano-ledger libraries offer".

If we don't like that answer, we can add our own taste to it, i.e. offer custom functions, lenses or even pattern synonyms that operate on TxOut LatestLedgerEra — but I would stop before defining new types, because that is then outside of the answer above.

@Anviking Anviking force-pushed the anviking/ADP-3373/getUTxOByTxIn branch 2 times, most recently from 9f09fbf to ebe1412 Compare June 27, 2024 09:25
@Anviking Anviking force-pushed the anviking/ADP-3373/getUTxOByTxIn branch from ebe1412 to f5214c2 Compare June 27, 2024 09:32
@Anviking Anviking added this pull request to the merge queue Jun 27, 2024
Merged via the queue into master with commit 5aa4a5b Jun 27, 2024
3 checks passed
@Anviking Anviking deleted the anviking/ADP-3373/getUTxOByTxIn branch June 27, 2024 13:33
github-merge-queue bot pushed a commit that referenced this pull request Jul 17, 2024
…ers` (#4684)

- Document recent changes to the `transactions-balance` `inputs` field
(#4630 )
- Clarify semantics of the `transactions-balance` `redeemers` field

### Rendered

<img width="739" alt="Skärmavbild 2024-07-16 kl 16 55 27"
src="https://github.com/user-attachments/assets/9b92879b-e11e-4d80-9c04-7f2e4f7cdae2">
WilliamKingNoel-Bot pushed a commit that referenced this pull request Jul 17, 2024
…redeemers` (#4684) - Document recent changes to the `transactions-balance` `inputs` field (#4630 ) - Clarify semantics of the `transactions-balance` `redeemers` field ### Rendered <img width="739" alt="Skärmavbild 2024-07-16 kl 16 55 27" src="https://github.com/user-attachments/assets/9b92879b-e11e-4d80-9c04-7f2e4f7cdae2"> Source commit: 0e59ac1
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.

3 participants