-
Notifications
You must be signed in to change notification settings - Fork 23
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
Use ledger presentation of multi-asset values directly. Lens to make this uniform over ShelleyBasedEra
#360
Conversation
{-# LANGUAGE StandaloneDeriving #-} | ||
{-# LANGUAGE TypeFamilies #-} | ||
|
||
module Cardano.Api.Eon.ByronToAllegraEra |
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.
This PR deletes ByronToAllegraEra
because we don't need it anymore.
This moves us towards to goal of having fewer eons.
MaryEra -> r MaryEraOnwardsMary | ||
AlonzoEra -> r MaryEraOnwardsAlonzo | ||
BabbageEra -> r MaryEraOnwardsBabbage | ||
ConwayEra -> r MaryEraOnwardsConway |
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.
Deletes a case function because we don't need it anymore.
caseShelleyToAllegraOrMaryEraOnwards | ||
adaAssetShelleyToAllegraEraL | ||
adaAssetMaryEraOnwardsL | ||
sbe |
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.
We use lenses to present a consistent interface across all Shelley based eras. With this single lens we can access the ADA value inside the L.Value ledgerera
.
It is a direct field lookup, not a map lookup like selectLovelace
in cardano-api
.
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.
We need to move this lens to cardano-ledger
in a follow up PR.
) | ||
=> ShelleyBasedEra era | ||
-> L.Value (ShelleyLedgerEra era) | ||
-> TxOutValue era |
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.
This definition has two constructors like before, the main difference is that all Shelley eras are now treated the same and only Byron is different. This is as it should be because the ledger treats Byron as legacy so it doesn't even have lens support.
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.
The TxOutValueByron
constructor will eventually be removed because:
makeByronTransactionBody :: ()
=> ByronEraOnly era
-> TxBodyContent BuildTx era
-> Either TxBodyError (TxBody era)
We don't need TxBodyContent BuildTx Era
to construct a Byron tx as the majority of the fields aren't used in Byron. We are only interested in inputs, outputs and update proposals and we can parameterize makeByronTransactionBody
as such.
We will follow the approach of ledger the ledger towards the Byron era as we don't want consumers of the api who are interested only in the latest shelley era dealing with Byron related types.
Most places where TxOutValueByron
is called we see usage of the EmptyCase
pragma either for the Byron era or the ShelleyBasedEra so the code is also hinting this to us.
TxOutAdaOnly _ l -> l | ||
TxOutValue _ v -> selectLovelace v | ||
TxOutValueByron _ l -> l | ||
TxOutValueShelleyBased sbe v -> coinToLovelace $ v ^. A.adaAssetL sbe |
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.
Example of where we use adaAssetL
to access the ADA value.
& L.datumTxOutL .~ toBabbageTxOutDatum' txoutdata | ||
& L.referenceScriptTxOutL .~ refScriptToShelleyScript cEra refScript | ||
where | ||
cEra = shelleyBasedToCardanoEra sbe |
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.
Opportunity to simplify because L.mkBasicTxOut (toShelleyAddr addr) value
is repeated. This wasn't the case previously.
lovelaceToCoin (Lovelace ll) = Shelley.Coin ll | ||
|
||
coinToLovelace :: Shelley.Coin -> Lovelace | ||
coinToLovelace (Shelley.Coin ll) = Lovelace ll |
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.
We could delete Lovelace
and use the Coin
ledger type directly to avoid conversions.
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.
We should in another PR.
caseShelleyToAllegraOrMaryEraOnwards | ||
(const (coinToValue v)) | ||
(const (fromMaryValue v)) | ||
sbe |
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.
These conversions were functions were introduced to convert between Value
and L.Value ledgerera
. Value
could actually be deleted if we use the ledger type directly everywhere and then these conversion functions go away.
…implify the code by deleting the feature we no longer use
|
||
toShelleyTxOut _ (TxOut addr (TxOutValue MaryEraOnwardsAlonzo value) txoutdata _) = | ||
L.mkBasicTxOut (toShelleyAddr addr) (toMaryValue value) | ||
& L.dataHashTxOutL .~ toAlonzoTxOutDataHash txoutdata |
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.
This appears to be Alonzo only. Deleting this can simplify the code a lot.
@@ -223,6 +223,7 @@ library | |||
-- exposed by cardano-api-ledger | |||
Cardano.Api.Ledger | |||
|
|||
reexported-modules: Cardano.Api.Ledger.Lens |
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.
New export so we can use eon enabled from the CLI and from 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.
Why not just expose it?
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.
The code needs to live in the internal
component because code in internal
uses it. This doesn't apply to the other modules because those are never imported by code in internal
.
f27b67e
to
cf84f53
Compare
cf84f53
to
9774286
Compare
-> StrictMaybe (L.DataHash StandardCrypto) | ||
-> TxOutDatum ctx era | ||
fromAlonzoTxOutDataHash _ SNothing = TxOutDatumNone | ||
fromAlonzoTxOutDataHash s (SJust dh) = TxOutDatumHash s (ScriptDataHash dh) |
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.
A bunch of alonzo specific code disappears because we remove the feature that only worked in Alonzo and choose to no longer support.
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.
Datum hashes weren't deprecated. See in ledger: instance Crypto c => AlonzoEraTxOut (BabbageEra c) where
. This is removing the possibility for users to specify datum hashes instead of inline datums!
SNothing -> TxOutDatumNone | ||
SJust dh | ||
| Just d <- Map.lookup dh txdatums -> TxOutDatumInTx' w (ScriptDataHash dh) (fromAlonzoData d) | ||
| otherwise -> TxOutDatumHash w (ScriptDataHash dh) |
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.
A bunch of alonzo specific code disappears because we remove the feature that only worked in Alonzo and choose to no longer support.
toShelleyTxOutAny sbe (TxOut addr (TxOutValue MaryEraOnwardsBabbage value) txoutdata refScript) = | ||
let cEra = shelleyBasedToCardanoEra sbe | ||
in L.mkBasicTxOut (toShelleyAddr addr) (toMaryValue value) | ||
& L.datumTxOutL .~ toBabbageTxOutDatum' txoutdata |
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.
Being able to remove this Alonzo specific one-liner allows toShelleyTxOutAny
to be implemented with a single eon case.
lookupDRepDeposit | ||
isRegPool | ||
(toLedgerUTxO sbe utxo) | ||
txbody |
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.
Because the lens adapter makes the ADA asset interface consistent across all of ShelleyBasedEra
we no longer need to case on the eon to implement evaluateTransactionBalance
.
sbe | ||
|
||
let addressInEra :: AddressInEra era | ||
addressInEra = shelleyBasedEraConstraints sbe $ fromShelleyAddr sbe $ ledgerTxOut ^. L.addrTxOutL |
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.
More simplifications because the eon-enabled lens adapter makes ADA Asset appear uniform across all of ShelleyBasedEra
.
@@ -170,6 +169,7 @@ library internal | |||
, errors | |||
, filepath | |||
, formatting | |||
, groups |
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.
We import groups
because ledger implements Group
for multi-asset values which we can use to negate the entire L.Value ledgerera
.
ShelleyBasedEra
caseShelleyToAllegraOrMaryEraOnwards | ||
adaAssetShelleyToAllegraEraL | ||
adaAssetMaryEraOnwardsL | ||
sbe |
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.
We need to move this lens to cardano-ledger
in a follow up PR.
@@ -223,6 +223,7 @@ library | |||
-- exposed by cardano-api-ledger | |||
Cardano.Api.Ledger | |||
|
|||
reexported-modules: Cardano.Api.Ledger.Lens |
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.
Why not just expose it?
evalMultiAsset | ||
sbe | ||
shelleyBasedEraConstraints sbe | ||
$ TxOutValueShelleyBased sbe |
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.
👍
@@ -828,21 +809,22 @@ makeTransactionBodyAutoBalance sbe systemstart history lpp@(LedgerProtocolParame | |||
-- However, since at this point we know how much non-Ada change to give | |||
-- we can use the true values for that. | |||
|
|||
let outgoingNonAda = mconcat [filterValue isNotAda v | (TxOut _ (TxOutValue _ v) _ _) <- txOuts txbodycontent] | |||
let incomingNonAda = mconcat [filterValue isNotAda v | (TxOut _ (TxOutValue _ v) _ _) <- Map.elems $ unUTxO utxo] | |||
let outgoingNonAda = mconcat [v | (TxOut _ (TxOutValueShelleyBased _ v) _ _) <- txOuts txbodycontent] |
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.
Where has the isNotAda
filter gone?
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.
In the old code, isNotAda
removes the ADA asset, which is equivalent to setting the ADA asset value to zero. Later the ADA asset value is set by way of addition so the zero value is necessary:
lovelaceToValue (Lovelace (2^(64 :: Integer)) - 1) <> nonAdaChange
The new code doesn't both to set it to zero because instead of adding nonAdaChange
to the ADA asset value we overwrite it with nonAdaChange
instead:
change & A.adaAssetL sbe .~ lovelaceToCoin maxLovelaceChange
mkBasicTxOut sbe addr value = | ||
shelleyBasedEraConstraints sbe $ L.mkBasicTxOut addr value | ||
|
||
mkAdaValue :: ShelleyBasedEra era -> L.Coin -> L.Value (ShelleyLedgerEra era) |
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.
Another function that should live in the ledger
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.
This can't move to the ledger as is because it used ShelleyBasedEra
, but there is n eon-free version of this that can move to the ledger.
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, ledger can implement a function that constructs a Value
regardless of the era.
lovelaceToCoin (Lovelace ll) = Shelley.Coin ll | ||
|
||
coinToLovelace :: Shelley.Coin -> Lovelace | ||
coinToLovelace (Shelley.Coin ll) = Lovelace ll |
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.
We should in another PR.
-> StrictMaybe (L.DataHash StandardCrypto) | ||
-> TxOutDatum ctx era | ||
fromAlonzoTxOutDataHash _ SNothing = TxOutDatumNone | ||
fromAlonzoTxOutDataHash s (SJust dh) = TxOutDatumHash s (ScriptDataHash dh) |
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.
Datum hashes weren't deprecated. See in ledger: instance Crypto c => AlonzoEraTxOut (BabbageEra c) where
. This is removing the possibility for users to specify datum hashes instead of inline datums!
toAlonzoTxOutDataHash' (TxOutDatumInTx' _ (ScriptDataHash dh) _) = SJust dh | ||
toAlonzoTxOutDataHash' (TxOutDatumInline inlineDatumSupp _sd) = | ||
case inlineDatumSupp :: BabbageEraOnwards AlonzoEra of {} | ||
|
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.
The code above gets the hash and the code below also gets the hash as a Datum
.
, mkAdaValue | ||
|
||
-- * Lenses | ||
, strictMaybeL | ||
, L.invalidBeforeL |
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.
We need a clear distinction between ledger and cardano-api. We are mixing lenses here which is confusing.
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.
Nice work. I would like to sort out Cardano.Api.Ledger
and Cardano.Api.Ledger.Lens
before we release again.
…es-for-key-commands Command argument types for `key` commands
Changelog
Context
This PR introduces adapter lenses
adaAssetL
andmultiAssetL
.The former provides a uniform way to access the ADA asset in ledger values uniformly across all of
ShelleyBasedEra
which simplifies code considerably.The latter provides an easy way to access all the non-ADA assets from Mary onwards.
The change also deletes
ByronToAllegraEra
Further simplifications are possible but are left to future PRs to keep this PR small.
How to trust this PR
Highlight important bits of the PR that will make the review faster. If there are commands the reviewer can run to observe the new behavior, describe them.
Checklist