Skip to content

Commit

Permalink
Remove newExUnits from TxUpdate, moved as separate function.
Browse files Browse the repository at this point in the history
  This was a quick-n-dirty hack to get started with the integration and testing. Adding witnesses is actually quite more involved in the end and it is therefore better done in a, far from trivial, separate function.
  • Loading branch information
KtorZ committed Oct 14, 2021
1 parent a018e3b commit 1c1b348
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 88 deletions.
13 changes: 3 additions & 10 deletions lib/core/src/Cardano/Wallet/Api/Server.hs
Expand Up @@ -2284,16 +2284,9 @@ balanceTransaction ctx genChange (ApiT wid) body = do
transform

let txUpdate =
TxUpdate { extraInputs, extraCollateral, extraOutputs, newFee, newExUnits }
where
-- FIXME: At this stage, we set all execution units for all redeemers to the
-- max cost, which is guaranteed to succeed (given the coin selection above
-- was done with the same assumption) but also terribly ineffective when it
-- comes to reducing the cost. This is however sufficient to start
-- preliminary integration work.
newExUnits = const (const (pp ^. #txParameters . #getMaxExecutionUnits))

case ApiT <$> updateTx tl nodePParams partialTx txUpdate of
TxUpdate { extraInputs, extraCollateral, extraOutputs, newFee }

case ApiT <$> updateTx tl partialTx txUpdate of
Left err -> liftHandler $ throwE $ ErrBalanceTxUpdateError err
Right transaction -> pure $ ApiSerialisedTransaction { transaction }
where
Expand Down
11 changes: 3 additions & 8 deletions lib/core/src/Cardano/Wallet/Transaction.hs
Expand Up @@ -51,8 +51,7 @@ import Cardano.Wallet.Primitive.CoinSelection.Balance
import Cardano.Wallet.Primitive.Slotting
( PastHorizonException, TimeInterpreter )
import Cardano.Wallet.Primitive.Types
( ExecutionUnits
, PoolId
( PoolId
, ProtocolParameters
, SlotNo (..)
, TokenBundleMaxSize (..)
Expand All @@ -69,8 +68,7 @@ import Cardano.Wallet.Primitive.Types.RewardAccount
import Cardano.Wallet.Primitive.Types.TokenMap
( TokenMap )
import Cardano.Wallet.Primitive.Types.Tx
( ScriptWitnessIndex
, TokenBundleSizeAssessor
( TokenBundleSizeAssessor
, Tx (..)
, TxConstraints
, TxIn
Expand Down Expand Up @@ -203,8 +201,7 @@ data TransactionLayer k tx = TransactionLayer
-- ^ Decode an externally-created transaction.

, updateTx
:: Node.ProtocolParameters
-> tx
:: tx
-> TxUpdate
-> Either ErrUpdateSealedTx tx
-- ^ Update tx by adding additional inputs and outputs
Expand All @@ -231,8 +228,6 @@ data TxUpdate = TxUpdate
-- ^ Only used in the Alonzo era and later. Will be silently ignored in
-- previous eras.
, extraOutputs :: [TxOut]
, newExUnits :: ScriptWitnessIndex -> ExecutionUnits -> ExecutionUnits
-- ^ Adjust execution units on existing redeemers.
, newFee :: Coin -> Coin
-- ^ Set the new fee, given the old one.
--
Expand Down
4 changes: 2 additions & 2 deletions lib/core/test/unit/Cardano/WalletSpec.hs
Expand Up @@ -1288,8 +1288,8 @@ dummyTransactionLayer = TransactionLayer
error "dummyTransactionLayer: constraints not implemented"
, decodeTx = \_sealed ->
Tx (Hash "") Nothing mempty mempty mempty mempty mempty Nothing
, updateTx = \_ sealed _update ->
pure sealed
, updateTx = \sealed _update ->
pure sealed
}
where
forMaybe :: [a] -> (a -> Maybe b) -> [b]
Expand Down
69 changes: 10 additions & 59 deletions lib/shelley/src/Cardano/Wallet/Shelley/Transaction.hs
Expand Up @@ -580,7 +580,7 @@ mkDelegationCertificates da accXPub =
-- == Right tx or Left
-- @
noTxUpdate :: TxUpdate
noTxUpdate = TxUpdate [] [] [] (const id) id
noTxUpdate = TxUpdate [] [] [] id

-- Used to add inputs and outputs when balancing a transaction.
--
Expand All @@ -595,12 +595,10 @@ noTxUpdate = TxUpdate [] [] [] (const id) id
-- To avoid the need for `ledger -> wallet` conversions, this function can only
-- be used to *add* tx body content.
updateSealedTx
:: Cardano.ProtocolParameters
-> SealedTx
:: SealedTx
-> TxUpdate
-> Either ErrUpdateSealedTx SealedTx
updateSealedTx pparams (cardanoTx -> InAnyCardanoEra _era tx) extraContent = do

updateSealedTx (cardanoTx -> InAnyCardanoEra _era tx) extraContent = do
-- NOTE: The script witnesses are carried along with the cardano-api
-- `anyEraBody`.
let (Cardano.Tx anyEraBody existingKeyWits) = tx
Expand All @@ -618,67 +616,22 @@ updateSealedTx pparams (cardanoTx -> InAnyCardanoEra _era tx) extraContent = do
-> Cardano.TxBody era
-> Either ErrUpdateSealedTx (Cardano.TxBody era)
modifyLedgerTx ebc (Cardano.ShelleyTxBody shelleyEra bod scripts scriptData aux val) =
let scriptData' = modifyRedeemers scriptData
integrityHash = calcScriptIntegrityHash shelleyEra scriptData' scripts
in
Right $ Cardano.ShelleyTxBody shelleyEra
(adjustBody ebc integrityHash shelleyEra bod)
scripts
scriptData'
aux
val
Right $ Cardano.ShelleyTxBody shelleyEra
(adjustBody ebc shelleyEra bod)
scripts
scriptData
aux
val
where
calcScriptIntegrityHash
:: ShelleyBasedEra era
-> Cardano.TxBodyScriptData era
-> [Ledger.Script (Cardano.ShelleyLedgerEra era)]
-> StrictMaybe (Alonzo.ScriptIntegrityHash crypto)
calcScriptIntegrityHash Cardano.ShelleyBasedEraShelley _ _ =
SNothing
calcScriptIntegrityHash Cardano.ShelleyBasedEraAllegra _ _ =
SNothing
calcScriptIntegrityHash Cardano.ShelleyBasedEraMary _ _ =
SNothing
calcScriptIntegrityHash Cardano.ShelleyBasedEraAlonzo datsAndRdmrs s =
let
ledgerLangs = Set.fromList [ PlutusV1 | not (null s) ]
ledgerPParams = toAlonzoPParams pparams
(ledgerDats, ledgerRedeemers) = case datsAndRdmrs of
Cardano.TxBodyNoScriptData ->
(mempty, Alonzo.Redeemers mempty)
Cardano.TxBodyScriptData Cardano.ScriptDataInAlonzoEra dats rdmrs ->
(dats, rdmrs)
in
Alonzo.hashScriptIntegrity
ledgerPParams
ledgerLangs
ledgerRedeemers
ledgerDats

modifyRedeemers :: Cardano.TxBodyScriptData era -> Cardano.TxBodyScriptData era
modifyRedeemers = \case
Cardano.TxBodyNoScriptData ->
Cardano.TxBodyNoScriptData
Cardano.TxBodyScriptData Cardano.ScriptDataInAlonzoEra dats (Alonzo.Redeemers redeemers) ->
Cardano.TxBodyScriptData Cardano.ScriptDataInAlonzoEra dats
$ Alonzo.Redeemers
$ Map.mapWithKey (\ptr (a, exUnits) ->
let ptr' = Cardano.fromAlonzoRdmrPtr ptr
exUnits' = fromLedgerExUnits exUnits
in
(a, toLedgerExUnits $ newExUnits extraContent ptr' exUnits')
) redeemers

-- NOTE: If the ShelleyMA MAClass were exposed, the Allegra and Mary
-- cases could perhaps be joined. It is not however. And we still need
-- to treat Alonzo and Shelley differently.
adjustBody
:: TxUpdate
-> StrictMaybe (Alonzo.ScriptIntegrityHash crypto)
-> ShelleyBasedEra era
-> Ledger.TxBody (Cardano.ShelleyLedgerEra era)
-> Ledger.TxBody (Cardano.ShelleyLedgerEra era)
adjustBody (TxUpdate extraInputs extraCollateral extraOutputs _ modifyFee) integrityHash era body = case era of
adjustBody (TxUpdate extraInputs extraCollateral extraOutputs modifyFee) era body = case era of
ShelleyBasedEraAlonzo -> body
Alonzo.outputs =
StrictSeq.fromList (Cardano.toShelleyTxOut era <$> extraOutputs')
Expand All @@ -689,8 +642,6 @@ updateSealedTx pparams (cardanoTx -> InAnyCardanoEra _era tx) extraContent = do
<> Set.fromList (Cardano.toShelleyTxIn <$> extraCollateral')
, Alonzo.txfee =
modifyFee' $ Alonzo.txfee body
, Alonzo.scriptIntegrityHash =
integrityHash
}
ShelleyBasedEraMary ->
let
Expand Down
13 changes: 4 additions & 9 deletions lib/shelley/test/unit/Cardano/Wallet/Shelley/TransactionSpec.hs
Expand Up @@ -123,7 +123,6 @@ import Cardano.Wallet.Primitive.Types.UTxO
import Cardano.Wallet.Shelley.Compatibility
( AnyShelleyBasedEra (..)
, computeTokenBundleSerializedLengthBytes
, fromLedgerAlonzoPParams
, getShelleyBasedEra
, shelleyToCardanoEra
, toCardanoLovelace
Expand Down Expand Up @@ -246,7 +245,6 @@ import Test.Utils.Pretty

import qualified Cardano.Api as Cardano
import qualified Cardano.Api.Shelley as Cardano
import qualified Cardano.Ledger.Alonzo.PParams as Alonzo
import qualified Cardano.Wallet.Primitive.CoinSelection.Balance as Balance
import qualified Cardano.Wallet.Primitive.Types.TokenBundle as TokenBundle
import qualified Cardano.Wallet.Primitive.Types.TokenMap as TokenMap
Expand Down Expand Up @@ -1443,7 +1441,7 @@ updateSealedTxSpec = do
txs <- readTestTransactions
forM_ txs $ \(filepath, tx) -> do
it ("without TxUpdate: " <> filepath) $ do
case updateSealedTx dummyNodeProtocolParameters tx noTxUpdate of
case updateSealedTx tx noTxUpdate of
Left e ->
expectationFailure $ "expected update to succeed but failed: " <> show e
Right tx' -> do
Expand All @@ -1461,7 +1459,7 @@ updateSealedTxSpec = do
case sealedTxFromBytes $ unsafeFromHex txWithInputsOutputsAndWits of
Left e -> expectationFailure $ show e
Right tx -> do
updateSealedTx dummyNodeProtocolParameters tx noTxUpdate
updateSealedTx tx noTxUpdate
`shouldBe` Left (ErrExistingKeyWitnesses 2)

it "returns `Left err` when extra body content is non-empty" $ do
Expand All @@ -1475,9 +1473,9 @@ unsafeSealedTxFromHex =

prop_updateSealedTx :: SealedTx -> [TxIn] -> [TxIn] -> [TxOut] -> Coin -> Property
prop_updateSealedTx tx extraIns extraCol extraOuts newFee = do
let extra = TxUpdate extraIns extraCol extraOuts (const id) (const newFee)
let extra = TxUpdate extraIns extraCol extraOuts (const newFee)
let tx' = either (error . show) id
$ updateSealedTx dummyNodeProtocolParameters tx extra
$ updateSealedTx tx extra
conjoin
[ sealedInputs tx' === sealedInputs tx <> Set.fromList extraIns
, sealedOutputs tx' === sealedOutputs tx <> Set.fromList extraOuts
Expand Down Expand Up @@ -1534,9 +1532,6 @@ readTestTransactions = runIO $ do
>>= traverse (\f -> (f,) <$> BS.readFile (dir </> f))
>>= traverse (\(f,bs) -> (f,) <$> unsafeSealedTxFromHex bs)

dummyNodeProtocolParameters :: Cardano.ProtocolParameters
dummyNodeProtocolParameters = fromLedgerAlonzoPParams Alonzo.emptyPParams

hasPlutusScripts :: SealedTx -> Bool
hasPlutusScripts sealedTx =
case cardanoTx sealedTx of
Expand Down

0 comments on commit 1c1b348

Please sign in to comment.