@@ -98,6 +98,7 @@ import Data.Set (Set)
9898import qualified Data.Set as Set
9999import Data.Text (Text )
100100import GHC.Exts (IsList (.. ))
101+ import GHC.Stack
101102import Lens.Micro ((.~) , (^.) )
102103
103104-- | Type synonym for logs returned by the ledger's @evalTxExUnitsWithLogs@ function.
@@ -190,7 +191,8 @@ instance Error (TxFeeEstimationError era) where
190191-- | Use when you do not have access to the UTxOs you intend to spend
191192estimateBalancedTxBody
192193 :: forall era
193- . MaryEraOnwards era
194+ . HasCallStack
195+ => MaryEraOnwards era
194196 -> TxBodyContent BuildTx era
195197 -> L. PParams (ShelleyLedgerEra era )
196198 -> Set PoolId
@@ -273,9 +275,9 @@ estimateBalancedTxBody
273275 , negateValue (lovelaceToValue totalDeposits)
274276 ]
275277
276- let change = toLedgerValue w $ calculateChangeValue sbe availableUTxOValue txbodycontent1
278+ let partialChange = toLedgerValue w $ calculatePartialChangeValue sbe availableUTxOValue txbodycontent1
277279 maxLovelaceChange = L. Coin (2 ^ (64 :: Integer )) - 1
278- changeWithMaxLovelace = change & A. adaAssetL sbe .~ maxLovelaceChange
280+ changeWithMaxLovelace = partialChange & A. adaAssetL sbe .~ maxLovelaceChange
279281 changeTxOut =
280282 forShelleyBasedEraInEon
281283 sbe
@@ -1002,6 +1004,7 @@ data FeeEstimationMode era
10021004makeTransactionBodyAutoBalance
10031005 :: forall era
10041006 . ()
1007+ => HasCallStack
10051008 => ShelleyBasedEra era
10061009 -> SystemStart
10071010 -> LedgerEpochInfo
@@ -1016,7 +1019,7 @@ makeTransactionBodyAutoBalance
10161019 -- ^ Map of all deposits for drep credentials that are being
10171020 -- unregistered in this transaction
10181021 -> UTxO era
1019- -- ^ Just the transaction inputs, not the entire 'UTxO'.
1022+ -- ^ Just the transaction inputs (including reference and collateral ones) , not the entire 'UTxO'.
10201023 -> TxBodyContent BuildTx era
10211024 -> AddressInEra era
10221025 -- ^ Change address
@@ -1042,18 +1045,21 @@ makeTransactionBodyAutoBalance
10421045 -- 3. update tx with fees
10431046 -- 4. balance the transaction and update tx change output
10441047
1045- let totalValueAtSpendableUTxO = fromLedgerValue sbe . calculateIncomingUTxOValue . Map. elems $ unUTxO utxo
1046- change =
1047- monoidForEraInEon (toCardanoEra sbe) $ \ w ->
1048- toLedgerValue w $ calculateChangeValue sbe totalValueAtSpendableUTxO txbodycontent
1048+ txbodyForChange <- first TxBodyError $ createTransactionBody sbe txbodycontent
1049+ let initialChangeTxOut =
1050+ evaluateTransactionBalance sbe pp poolids stakeDelegDeposits drepDelegDeposits utxo txbodyForChange
10491051
1050- txbody0 <-
1052+ -- Tx body used only for evaluating execution units. Because txout exact
1053+ -- values do not matter much here, we are using an initial change value,
1054+ -- which is slightly overestimated, because it does not include fee or
1055+ -- scripts execution costs.
1056+ txbody <-
10511057 first TxBodyError
10521058 $ createTransactionBody
10531059 sbe
10541060 $ txbodycontent
10551061 & modTxOuts
1056- (<> [TxOut changeaddr ( TxOutValueShelleyBased sbe change) TxOutDatumNone ReferenceScriptNone ])
1062+ (<> [TxOut changeaddr initialChangeTxOut TxOutDatumNone ReferenceScriptNone ])
10571063 exUnitsMapWithLogs <-
10581064 first TxBodyErrorValidityInterval $
10591065 evaluateTransactionExecutionUnits
@@ -1062,7 +1068,7 @@ makeTransactionBodyAutoBalance
10621068 history
10631069 lpp
10641070 utxo
1065- txbody0
1071+ txbody
10661072
10671073 let exUnitsMap = Map. map (fmap snd ) exUnitsMapWithLogs
10681074
@@ -1077,24 +1083,14 @@ makeTransactionBodyAutoBalance
10771083 txbodycontent1 <- substituteExecutionUnits exUnitsMap' txbodycontent
10781084
10791085 -- Make a txbody that we will use for calculating the fees. For the purpose
1080- -- of fees we just need to make a txbody of the right size in bytes. We do
1081- -- not need the right values for the fee or change output. We use
1082- -- "big enough" values for the change output and set so that the CBOR
1083- -- encoding size of the tx will be big enough to cover the size of the final
1084- -- output and fee. Yes this means this current code will only work for
1085- -- final fee of less than around 4000 ada (2^32-1 lovelace) and change output
1086- -- of less than around 18 trillion ada (2^64-1 lovelace).
1087- -- However, since at this point we know how much non-Ada change to give
1088- -- we can use the true values for that.
1089- let maxLovelaceChange = L. Coin (2 ^ (64 :: Integer )) - 1
1086+ -- of fees we just need to make a txbody of the right size in bytes. We
1087+ -- do not need the right values for the fee. We use "big enough" value
1088+ -- for the fee and set so that the CBOR encoding size of the tx will be
1089+ -- big enough to cover the size of the final output and fee. Yes this
1090+ -- means this current code will only work for final fee of less than
1091+ -- around 4000 ada (2^32-1 lovelace).
10901092 let maxLovelaceFee = L. Coin (2 ^ (32 :: Integer ) - 1 )
1091- let changeWithMaxLovelace = change & A. adaAssetL sbe .~ maxLovelaceChange
1092- let changeTxOut =
1093- forShelleyBasedEraInEon
1094- sbe
1095- (lovelaceToTxOutValue sbe maxLovelaceChange)
1096- (\ w -> maryEraOnwardsConstraints w $ TxOutValueShelleyBased sbe changeWithMaxLovelace)
1097-
1093+ -- Make a txbody that we will use for calculating the fees.
10981094 let (dummyCollRet, dummyTotColl) = maybeDummyTotalCollAndCollReturnOutput sbe txbodycontent changeaddr
10991095 txbody1 <-
11001096 first TxBodyError $ -- TODO: impossible to fail now
@@ -1104,7 +1100,7 @@ makeTransactionBodyAutoBalance
11041100 { txFee = TxFeeExplicit sbe maxLovelaceFee
11051101 , txOuts =
11061102 txOuts txbodycontent
1107- <> [TxOut changeaddr changeTxOut TxOutDatumNone ReferenceScriptNone ]
1103+ <> [TxOut changeaddr initialChangeTxOut TxOutDatumNone ReferenceScriptNone ]
11081104 , txReturnCollateral = dummyCollRet
11091105 , txTotalCollateral = dummyTotColl
11101106 }
@@ -1240,15 +1236,10 @@ isNotAda _ = True
12401236onlyAda :: Value -> Bool
12411237onlyAda = null . toList . filterValue isNotAda
12421238
1243- calculateIncomingUTxOValue
1244- :: Monoid (Ledger. Value (ShelleyLedgerEra era ))
1245- => [TxOut ctx era ]
1246- -> Ledger. Value (ShelleyLedgerEra era )
1247- calculateIncomingUTxOValue providedUtxoOuts =
1248- mconcat [v | (TxOut _ (TxOutValueShelleyBased _ v) _ _) <- providedUtxoOuts]
1249-
1250- -- Calculation taken from validateInsufficientCollateral: https://github.com/input-output-hk/cardano-ledger/blob/389b266d6226dedf3d2aec7af640b3ca4984c5ea/eras/alonzo/impl/src/Cardano/Ledger/Alonzo/Rules/Utxo.hs#L335
1251- -- TODO: Bug Jared to expose a function from the ledger that returns total and return collateral.
1239+ -- Calculation taken from validateInsufficientCollateral:
1240+ -- https://github.com/input-output-hk/cardano-ledger/blob/389b266d6226dedf3d2aec7af640b3ca4984c5ea/eras/alonzo/impl/src/Cardano/Ledger/Alonzo/Rules/Utxo.hs#L335
1241+ -- TODO: Bug Jared to expose a function from the ledger that returns total and
1242+ -- return collateral.
12521243calcReturnAndTotalCollateral
12531244 :: ()
12541245 => Ledger. AlonzoEraPParams (ShelleyLedgerEra era )
@@ -1311,17 +1302,19 @@ calcReturnAndTotalCollateral w fee pp' TxInsCollateral{} txReturnCollateral txTo
13111302 , totalCollateral
13121303 )
13131304
1314- calculateCreatedUTOValue
1315- :: ShelleyBasedEra era -> TxBodyContent build era -> Value
1316- calculateCreatedUTOValue sbe txbodycontent =
1317- mconcat [fromLedgerValue sbe v | (TxOut _ (TxOutValueShelleyBased _ v) _ _) <- txOuts txbodycontent]
1318-
1319- calculateChangeValue
1320- :: ShelleyBasedEra era -> Value -> TxBodyContent build era -> Value
1321- calculateChangeValue sbe incoming txbodycontent =
1322- let outgoing = calculateCreatedUTOValue sbe txbodycontent
1305+ -- | Calculate the partial change - this does not include certificates' deposits
1306+ calculatePartialChangeValue
1307+ :: ShelleyBasedEra era
1308+ -> Value
1309+ -> TxBodyContent build era
1310+ -> Value
1311+ calculatePartialChangeValue sbe incoming txbodycontent = do
1312+ let outgoing = newUtxoValue
13231313 mintedValue = txMintValueToValue $ txMintValue txbodycontent
1324- in mconcat [incoming, mintedValue, negateValue outgoing]
1314+ mconcat [incoming, mintedValue, negateValue outgoing]
1315+ where
1316+ newUtxoValue =
1317+ mconcat [fromLedgerValue sbe v | (TxOut _ (TxOutValueShelleyBased _ v) _ _) <- txOuts txbodycontent]
13251318
13261319-- | This is used in the balance calculation in the event where
13271320-- the user does not supply the UTxO(s) they intend to spend
@@ -1585,7 +1578,8 @@ traverseScriptWitnesses =
15851578 traverse (\ (item, eRes) -> eRes >>= (\ res -> Right (item, res)))
15861579
15871580calculateMinimumUTxO
1588- :: ShelleyBasedEra era
1581+ :: HasCallStack
1582+ => ShelleyBasedEra era
15891583 -> TxOut CtxTx era
15901584 -> Ledger. PParams (ShelleyLedgerEra era )
15911585 -> L. Coin
0 commit comments