@@ -763,11 +763,6 @@ data TxBodyErrorAutoBalance =
763
763
-- | One or more of the scripts were expected to fail validation, but none did.
764
764
| TxBodyScriptBadScriptValidity
765
765
766
- -- | The balance of the non-ada assets is not zero. The 'Value' here is
767
- -- that residual non-zero balance. The 'makeTransactionBodyAutoBalance'
768
- -- function only automatically balances ada, not other assets.
769
- | TxBodyErrorAssetBalanceWrong Value
770
-
771
766
-- | There is not enough ada to cover both the outputs and the fees.
772
767
-- The transaction should be changed to provide more input ada, or
773
768
-- otherwise adjusted to need less (e.g. outputs, script etc).
@@ -826,13 +821,6 @@ instance Error TxBodyErrorAutoBalance where
826
821
displayError TxBodyScriptBadScriptValidity =
827
822
" One or more of the scripts were expected to fail validation, but none did."
828
823
829
- displayError (TxBodyErrorAssetBalanceWrong _value) =
830
- " The transaction does not correctly balance in its non-ada assets. "
831
- ++ " The balance between inputs and outputs should sum to zero. "
832
- ++ " The actual balance is: "
833
- ++ " TODO: move the Value renderer and parser from the CLI into the API and use them here"
834
- -- TODO: do this ^^
835
-
836
824
displayError (TxBodyErrorAdaBalanceNegative lovelace) =
837
825
" The transaction does not balance in its use of ada. The net balance "
838
826
++ " of the transaction is negative: " ++ show lovelace ++ " lovelace. "
@@ -971,13 +959,23 @@ makeTransactionBodyAutoBalance eraInMode systemstart history pparams
971
959
-- output and fee. Yes this means this current code will only work for
972
960
-- final fee of less than around 4000 ada (2^32-1 lovelace) and change output
973
961
-- of less than around 18 trillion ada (2^64-1 lovelace).
962
+ -- However, since at this point we know how much non-Ada change to give
963
+ -- we can use the true values for that.
964
+
965
+ let outgoingNonAda = mconcat [filterValue isNotAda v | (TxOut _ (TxOutValue _ v) _ _) <- txOuts txbodycontent]
966
+ let incomingNonAda = mconcat [filterValue isNotAda v | (TxOut _ (TxOutValue _ v) _ _) <- Map. elems $ unUTxO utxo]
967
+ let nonAdaChange = incomingNonAda <> negateValue outgoingNonAda
968
+
969
+ let changeTxOut = case multiAssetSupportedInEra cardanoEra of
970
+ Left _ -> lovelaceToTxOutValue $ Lovelace (2 ^ (64 :: Integer )) - 1
971
+ Right multiAsset -> TxOutValue multiAsset (lovelaceToValue (Lovelace (2 ^ (64 :: Integer )) - 1 ) <> nonAdaChange)
974
972
975
973
let (dummyCollRet, dummyTotColl) = maybeDummyTotalCollAndCollReturnOutput txbodycontent changeaddr
976
974
txbody1 <- first TxBodyError $ -- TODO: impossible to fail now
977
975
createAndValidateTransactionBody txbodycontent1 {
978
976
txFee = TxFeeExplicit explicitTxFees $ Lovelace (2 ^ (32 :: Integer ) - 1 ),
979
977
txOuts = TxOut changeaddr
980
- (lovelaceToTxOutValue $ Lovelace ( 2 ^ ( 64 :: Integer )) - 1 )
978
+ changeTxOut
981
979
TxOutDatumNone ReferenceScriptNone
982
980
: txOuts txbodycontent,
983
981
txReturnCollateral = dummyCollRet,
@@ -1009,13 +1007,7 @@ makeTransactionBodyAutoBalance eraInMode systemstart history pparams
1009
1007
1010
1008
-- check if the balance is positive or negative
1011
1009
-- in one case we can produce change, in the other the inputs are insufficient
1012
- case balance of
1013
- TxOutAdaOnly _ _ -> balanceCheck balance
1014
- TxOutValue _ v ->
1015
- case valueToLovelace v of
1016
- Nothing -> Left $ TxBodyErrorNonAdaAssetsUnbalanced v
1017
- Just _ -> balanceCheck balance
1018
-
1010
+ balanceCheck balance
1019
1011
1020
1012
-- TODO: we could add the extra fee for the CBOR encoding of the change,
1021
1013
-- now that we know the magnitude of the change: i.e. 1-8 bytes extra.
@@ -1135,7 +1127,7 @@ makeTransactionBodyAutoBalance eraInMode systemstart history pparams
1135
1127
1136
1128
balanceCheck :: TxOutValue era -> Either TxBodyErrorAutoBalance ()
1137
1129
balanceCheck balance
1138
- | txOutValueToLovelace balance == 0 = return ()
1130
+ | txOutValueToLovelace balance == 0 && onlyAda (txOutValueToValue balance) = return ()
1139
1131
| txOutValueToLovelace balance < 0 =
1140
1132
Left . TxBodyErrorAdaBalanceNegative $ txOutValueToLovelace balance
1141
1133
| otherwise =
@@ -1145,6 +1137,13 @@ makeTransactionBodyAutoBalance eraInMode systemstart history pparams
1145
1137
Left err -> Left err
1146
1138
Right _ -> Right ()
1147
1139
1140
+ isNotAda :: AssetId -> Bool
1141
+ isNotAda AdaAssetId = False
1142
+ isNotAda _ = True
1143
+
1144
+ onlyAda :: Value -> Bool
1145
+ onlyAda = null . valueToList . filterValue isNotAda
1146
+
1148
1147
checkMinUTxOValue
1149
1148
:: TxOut CtxTx era
1150
1149
-> ProtocolParameters
0 commit comments