Skip to content

Commit a6d7dce

Browse files
authored
Merge pull request #260 from input-output-hk/refactor_balance_txouts
fix(txouts): improve txouts balancing logic
2 parents eb7d496 + c3922a9 commit a6d7dce

File tree

1 file changed

+15
-16
lines changed

1 file changed

+15
-16
lines changed

cardano_clusterlib/txtools.py

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ def _select_utxos(
142142
return utxo_ids
143143

144144

145-
def _balance_txouts( # noqa: C901
145+
def _balance_txouts(
146146
change_address: str,
147147
txouts: structs.OptionalTxOuts,
148148
txins_db: tp.Dict[str, tp.List[structs.UTXOData]],
@@ -155,39 +155,40 @@ def _balance_txouts( # noqa: C901
155155
skip_asset_balancing: bool = False,
156156
) -> tp.List[structs.TxOut]:
157157
"""Balance the transaction by adding change output for each coin."""
158-
# records for burning tokens, i.e. records with negative amount, are not allowed in `txouts`
158+
# Records for burning tokens, i.e. records with negative amount, are not allowed in `txouts`
159159
burning_txouts = [r for r in txouts if r.amount < 0 and r.coin != consts.DEFAULT_COIN]
160160
if burning_txouts:
161161
msg = f"Token burning is not allowed in txouts: {burning_txouts}"
162162
raise AssertionError(msg)
163163

164-
txouts_result: tp.List[structs.TxOut] = list(txouts)
164+
# Filter out negative amounts (-1 "max" amounts)
165+
txouts_result = [r for r in txouts if r.amount > 0]
165166

166-
# iterate over coins both in txins and txouts
167+
if skip_asset_balancing:
168+
# Balancing is done elsewhere (by the `transaction build` command)
169+
return txouts_result
170+
171+
# Iterate over coins both in txins and txouts
167172
for coin in set(txins_db).union(txouts_passed_db).union(txouts_mint_db):
168173
max_address = None
169174
change = 0
170175

171176
coin_txins = txins_db.get(coin) or []
172177
coin_txouts = txouts_passed_db.get(coin) or []
173178

179+
total_input_amount = functools.reduce(lambda x, y: x + y.amount, coin_txins, 0)
180+
174181
if coin == consts.DEFAULT_COIN:
175-
# the value "-1" means all available funds
182+
# The value "-1" means all available funds
176183
max_index = [idx for idx, val in enumerate(coin_txouts) if val.amount == -1]
177184
if len(max_index) > 1:
178185
msg = "Cannot send all remaining funds to more than one address."
179186
raise AssertionError(msg)
180187
if max_index:
181-
# remove the "-1" record and get its address
188+
# Remove the "-1" record and get its address
182189
max_address = coin_txouts.pop(max_index[0]).address
183190

184-
total_input_amount = functools.reduce(lambda x, y: x + y.amount, coin_txins, 0)
185-
total_output_amount = functools.reduce(lambda x, y: x + y.amount, coin_txouts, 0)
186-
187-
if skip_asset_balancing:
188-
# balancing is done elsewhere (by the `transaction build` command)
189-
pass
190-
elif coin == consts.DEFAULT_COIN:
191+
total_output_amount = functools.reduce(lambda x, y: x + y.amount, coin_txouts, 0)
191192
tx_fee = fee if fee > 0 else 0
192193
total_withdrawals_amount = functools.reduce(lambda x, y: x + y.amount, withdrawals, 0)
193194
funds_available = total_input_amount + total_withdrawals_amount
@@ -200,6 +201,7 @@ def _balance_txouts( # noqa: C901
200201
)
201202
else:
202203
coin_txouts_minted = txouts_mint_db.get(coin) or []
204+
total_output_amount = functools.reduce(lambda x, y: x + y.amount, coin_txouts, 0)
203205
total_minted_amount = functools.reduce(lambda x, y: x + y.amount, coin_txouts_minted, 0)
204206
funds_available = total_input_amount + total_minted_amount
205207
change = funds_available - total_output_amount
@@ -214,9 +216,6 @@ def _balance_txouts( # noqa: C901
214216
structs.TxOut(address=(max_address or change_address), amount=change, coin=coin)
215217
)
216218

217-
# filter out negative amounts (-1 "max" amounts)
218-
txouts_result = [r for r in txouts_result if r.amount > 0]
219-
220219
return txouts_result
221220

222221

0 commit comments

Comments
 (0)