diff --git a/cardano-api/internal/Cardano/Api/Fees.hs b/cardano-api/internal/Cardano/Api/Fees.hs index 7f736b6f5..ac5bbadbb 100644 --- a/cardano-api/internal/Cardano/Api/Fees.hs +++ b/cardano-api/internal/Cardano/Api/Fees.hs @@ -325,7 +325,7 @@ estimateBalancedTxBody (txReturnCollateral txbodycontent) (txTotalCollateral txbodycontent) changeaddr - totalPotentialCollateral + (A.mkAdaValue sbe totalPotentialCollateral) ) sbe @@ -1070,10 +1070,8 @@ makeTransactionBodyAutoBalance availableEra $ obtainCommonConstraints availableEra $ txbodycontent - { txOuts = - txOuts txbodycontent - <> [TxOut changeaddr (TxOutValueShelleyBased sbe change) TxOutDatumNone ReferenceScriptNone] - } + & modTxOuts + (<> [TxOut changeaddr (TxOutValueShelleyBased sbe change) TxOutDatumNone ReferenceScriptNone]) exUnitsMapWithLogs <- first TxBodyErrorValidityInterval $ evaluateTransactionExecutionUnitsShelley @@ -1143,21 +1141,24 @@ makeTransactionBodyAutoBalance (retColl, reqCol) = caseShelleyToAlonzoOrBabbageEraOnwards (const (TxReturnCollateralNone, TxTotalCollateralNone)) - ( \w -> + ( \w -> do let collIns = case txInsCollateral txbodycontent of TxInsCollateral _ collIns' -> collIns' TxInsCollateralNone -> mempty collateralOuts = catMaybes [Map.lookup txin (unUTxO utxo) | txin <- collIns] - totalPotentialCollateral = mconcat $ map (\(TxOut _ txOutVal _ _) -> txOutValueToLovelace txOutVal) collateralOuts - in calcReturnAndTotalCollateral - w - fee - pp - (txInsCollateral txbodycontent) - (txReturnCollateral txbodycontent) - (txTotalCollateral txbodycontent) - changeaddr - totalPotentialCollateral + totalPotentialCollateral = mconcat . flip map collateralOuts $ + \case + (TxOut _ (TxOutValueShelleyBased _ v) _ _) -> v + _ -> mempty + calcReturnAndTotalCollateral + w + fee + pp + (txInsCollateral txbodycontent) + (txReturnCollateral txbodycontent) + (txTotalCollateral txbodycontent) + changeaddr + totalPotentialCollateral ) sbe @@ -1295,49 +1296,50 @@ calcReturnAndTotalCollateral -- ^ From the initial TxBodyContent -> AddressInEra era -- ^ Change address - -> Coin - -- ^ Total available collateral in lovelace + -> L.Value (ShelleyLedgerEra era) + -- ^ Total available collateral -> (TxReturnCollateral CtxTx era, TxTotalCollateral era) calcReturnAndTotalCollateral _ _ _ TxInsCollateralNone _ _ _ _ = (TxReturnCollateralNone, TxTotalCollateralNone) -calcReturnAndTotalCollateral retColSup fee pp' TxInsCollateral{} txReturnCollateral txTotalCollateral cAddr totalAvailableAda = - do - let colPerc = pp' ^. Ledger.ppCollateralPercentageL - -- We must first figure out how much lovelace we have committed - -- as collateral and we must determine if we have enough lovelace at our - -- collateral tx inputs to cover the tx - totalCollateralLovelace = totalAvailableAda - requiredCollateral@(L.Coin reqAmt) = fromIntegral colPerc * fee - totalCollateral = - TxTotalCollateral retColSup . L.rationalToCoinViaCeiling $ - reqAmt % 100 - -- Why * 100? requiredCollateral is the product of the collateral percentage and the tx fee - -- We choose to multiply 100 rather than divide by 100 to make the calculation - -- easier to manage. At the end of the calculation we then use % 100 to perform our division - -- and round the returnCollateral down which has the effect of potentially slightly - -- overestimating the required collateral. - L.Coin amt = totalCollateralLovelace * 100 - requiredCollateral - returnCollateral = L.rationalToCoinViaFloor $ amt % 100 - case (txReturnCollateral, txTotalCollateral) of - (rc@TxReturnCollateral{}, tc@TxTotalCollateral{}) -> - (rc, tc) - (rc@TxReturnCollateral{}, TxTotalCollateralNone) -> - (rc, TxTotalCollateralNone) - (TxReturnCollateralNone, tc@TxTotalCollateral{}) -> - (TxReturnCollateralNone, tc) - (TxReturnCollateralNone, TxTotalCollateralNone) -> - if totalCollateralLovelace * 100 >= requiredCollateral - then - ( TxReturnCollateral - retColSup - ( TxOut - cAddr - (lovelaceToTxOutValue (babbageEraOnwardsToShelleyBasedEra retColSup) returnCollateral) - TxOutDatumNone - ReferenceScriptNone - ) - , totalCollateral - ) - else (TxReturnCollateralNone, TxTotalCollateralNone) +calcReturnAndTotalCollateral w fee pp' TxInsCollateral{} txReturnCollateral txTotalCollateral cAddr totalAvailableCollateral = do + let sbe = babbageEraOnwardsToShelleyBasedEra w + totalAvailableAda = totalAvailableCollateral ^. A.adaAssetL sbe + colPerc = pp' ^. Ledger.ppCollateralPercentageL + -- We must first figure out how much lovelace we have committed + -- as collateral and we must determine if we have enough lovelace at our + -- collateral tx inputs to cover the tx + totalCollateralLovelace = totalAvailableAda + requiredCollateral@(L.Coin reqAmt) = fromIntegral colPerc * fee + totalCollateral = + TxTotalCollateral w . L.rationalToCoinViaCeiling $ + reqAmt % 100 + -- Why * 100? requiredCollateral is the product of the collateral percentage and the tx fee + -- We choose to multiply 100 rather than divide by 100 to make the calculation + -- easier to manage. At the end of the calculation we then use % 100 to perform our division + -- and round the returnCollateral down which has the effect of potentially slightly + -- overestimating the required collateral. + L.Coin amt = totalCollateralLovelace * 100 - requiredCollateral + returnCollateral = L.rationalToCoinViaFloor $ amt % 100 + case (txReturnCollateral, txTotalCollateral) of + (rc@TxReturnCollateral{}, tc@TxTotalCollateral{}) -> + (rc, tc) + (rc@TxReturnCollateral{}, TxTotalCollateralNone) -> + (rc, TxTotalCollateralNone) + (TxReturnCollateralNone, tc@TxTotalCollateral{}) -> + (TxReturnCollateralNone, tc) + (TxReturnCollateralNone, TxTotalCollateralNone) -> + if totalCollateralLovelace * 100 >= requiredCollateral + then + ( TxReturnCollateral + w + ( TxOut + cAddr + (lovelaceToTxOutValue sbe returnCollateral) + TxOutDatumNone + ReferenceScriptNone + ) + , totalCollateral + ) + else (TxReturnCollateralNone, TxTotalCollateralNone) calculateCreatedUTOValue :: ShelleyBasedEra era -> TxBodyContent build era -> Value diff --git a/cardano-api/test/cardano-api-test/Test/Cardano/Api/Transaction/Autobalance.hs b/cardano-api/test/cardano-api-test/Test/Cardano/Api/Transaction/Autobalance.hs index 58ade7eca..18d44c93b 100644 --- a/cardano-api/test/cardano-api-test/Test/Cardano/Api/Transaction/Autobalance.hs +++ b/cardano-api/test/cardano-api-test/Test/Cardano/Api/Transaction/Autobalance.hs @@ -294,7 +294,6 @@ prop_make_transaction_body_autobalance_multi_asset_collateral = H.propertyOnce $ let assets = [a | a@(AssetId _ _, _) <- toList $ txOutValueToValue txOutValue] H.annotateShow assets - H.noteShow_ fee H.failure -- * Utilities