Skip to content

Commit e3f2362

Browse files
committed
[Bug fix] Don't add min_lovelace to unfulfilled_amount when change address is not provided.
Previously, in tx builder, we enforce input amount to be able to cover the minimum lovelace amount for change UTxO. This will cause a problem when user doesn't provide a change address. We fix this problem by checking whether a change address is provided before adding the minimum lovelace amount to unfulfilled amount.
1 parent bbce32f commit e3f2362

File tree

2 files changed

+57
-10
lines changed

2 files changed

+57
-10
lines changed

pycardano/txbuilder.py

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -623,13 +623,17 @@ def build(self, change_address: Optional[Address] = None) -> TransactionBody:
623623
)
624624

625625
unfulfilled_amount = requested_amount - trimmed_selected_amount
626-
# if remainder is smaller than minimum ADA required in change,
627-
# we need to select additional UTxOs available from the address
628-
unfulfilled_amount.coin = max(
629-
0,
630-
unfulfilled_amount.coin
631-
+ min_lovelace(selected_amount - trimmed_selected_amount, self.context),
632-
)
626+
627+
if change_address is not None:
628+
# If change address is provided and remainder is smaller than minimum ADA required in change,
629+
# we need to select additional UTxOs available from the address
630+
unfulfilled_amount.coin = max(
631+
0,
632+
unfulfilled_amount.coin
633+
+ min_lovelace(selected_amount - trimmed_selected_amount, self.context),
634+
)
635+
else:
636+
unfulfilled_amount.coin = max(0, unfulfilled_amount.coin)
633637
# Clean up all non-positive assets
634638
unfulfilled_amount.multi_asset = unfulfilled_amount.multi_asset.filter(
635639
lambda p, n, v: v > 0

test/pycardano/test_txbuilder.py

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ def test_tx_small_utxo_precise_fee(chain_context):
220220
2: 165413,
221221
}
222222

223-
expect == tx_body.to_primitive()
223+
assert expect == tx_body.to_primitive()
224224

225225

226226
def test_tx_small_utxo_balance_fail(chain_context):
@@ -261,8 +261,8 @@ def test_tx_small_utxo_balance_pass(chain_context):
261261

262262
expected = {
263263
0: [
264+
[b"11111111111111111111111111111111", 0],
264265
[b"11111111111111111111111111111111", 3],
265-
[b"11111111111111111111111111111111", 1],
266266
],
267267
1: [
268268
# First output
@@ -273,7 +273,7 @@ def test_tx_small_utxo_balance_pass(chain_context):
273273
2: 166997,
274274
}
275275

276-
expected == tx_body.to_primitive()
276+
assert expected == tx_body.to_primitive()
277277

278278

279279
def test_tx_builder_mint_multi_asset(chain_context):
@@ -578,3 +578,46 @@ def test_estimate_execution_unit(chain_context):
578578
"1eb6776ed7f80b68536a14954657374546f6b656e010b58206b5664c6f79646f2a4c17bdc1e"
579579
"cb6f6bf540db5c82dfa0a9d806c435398756fa" == tx_body.to_cbor()
580580
)
581+
582+
583+
def test_tx_builder_exact_fee_no_change(chain_context):
584+
tx_builder = TransactionBuilder(chain_context)
585+
sender = "addr_test1vrm9x2zsux7va6w892g38tvchnzahvcd9tykqf3ygnmwtaqyfg52x"
586+
sender_address = Address.from_primitive(sender)
587+
588+
input_amount = 10000000
589+
590+
tx_in1 = TransactionInput.from_primitive([b"1" * 32, 3])
591+
tx_out1 = TransactionOutput.from_primitive([sender, input_amount])
592+
utxo1 = UTxO(tx_in1, tx_out1)
593+
594+
tx_builder.add_input(utxo1)
595+
596+
tx_builder.add_output(TransactionOutput.from_primitive([sender, 5000000]))
597+
598+
tx_body = tx_builder.build()
599+
600+
tx_builder = TransactionBuilder(chain_context)
601+
602+
tx_in1 = TransactionInput.from_primitive([b"1" * 32, 3])
603+
tx_out1 = TransactionOutput.from_primitive([sender, input_amount])
604+
utxo1 = UTxO(tx_in1, tx_out1)
605+
606+
tx_builder.add_input(utxo1)
607+
608+
tx_builder.add_output(
609+
TransactionOutput.from_primitive([sender, input_amount - tx_body.fee])
610+
)
611+
612+
tx_body = tx_builder.build()
613+
614+
expected = {
615+
0: [[b"11111111111111111111111111111111", 3]],
616+
1: [
617+
# First output
618+
[sender_address.to_primitive(), 9836391],
619+
],
620+
2: 163609,
621+
}
622+
623+
assert expected == tx_body.to_primitive()

0 commit comments

Comments
 (0)