-
Notifications
You must be signed in to change notification settings - Fork 214
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
Conversation
81b160c
to
620ff36
Compare
24cb44d
to
fb6ec5d
Compare
@@ -659,6 +661,10 @@ withNodeNetworkLayerBase | |||
return res | |||
Nothing -> pure $ StakePoolsSummary 0 mempty mempty | |||
|
|||
_getUTxOByTxIn queue ins = |
There was a problem hiding this comment.
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 PartialTx
s with existing inputs for lookup. Only the balanceTx endpoint, and constructTx in the specific case of minting using a reference input.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this 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
.
lib/network-layer/src/Cardano/Wallet/Network/LocalStateQuery/UTxO.hs
Outdated
Show resolved
Hide resolved
, getUTxOByTxIn | ||
:: Set Write.TxIn | ||
-> m (MaybeInRecentEra Write.UTxO) |
There was a problem hiding this comment.
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
, 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 = |
There was a problem hiding this comment.
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.
lib/wallet/src/Cardano/Wallet.hs
Outdated
-- | '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 |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
.
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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)
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
9f09fbf
to
ebe1412
Compare
ebe1412
to
f5214c2
Compare
…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">
…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
getUTxOByTxIn
local state queryPartialTx
inputs over LSQ inCardano.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