Skip to content

Commit e00b569

Browse files
committed
Some bug fixes related to change in txbuilder
1 parent 22ab109 commit e00b569

File tree

2 files changed

+97
-6
lines changed

2 files changed

+97
-6
lines changed

pycardano/txbuilder.py

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -751,6 +751,13 @@ def build(
751751
for v in self.withdrawals.values():
752752
selected_amount.coin += v
753753

754+
can_merge_change = False
755+
if merge_change:
756+
for o in self.outputs:
757+
if o.address == change_address:
758+
can_merge_change = True
759+
break
760+
754761
selected_amount.coin -= self._get_total_key_deposit()
755762

756763
requested_amount = Value()
@@ -771,14 +778,17 @@ def build(
771778

772779
unfulfilled_amount = requested_amount - trimmed_selected_amount
773780

774-
if change_address is not None:
781+
if change_address is not None and not can_merge_change:
775782
# If change address is provided and remainder is smaller than minimum ADA required in change,
776783
# we need to select additional UTxOs available from the address
777-
unfulfilled_amount.coin = max(
778-
0,
779-
unfulfilled_amount.coin
780-
+ min_lovelace(selected_amount - trimmed_selected_amount, self.context),
781-
)
784+
if unfulfilled_amount.coin < 0:
785+
unfulfilled_amount.coin = max(
786+
0,
787+
unfulfilled_amount.coin
788+
+ min_lovelace(
789+
selected_amount - trimmed_selected_amount, self.context
790+
),
791+
)
782792
else:
783793
unfulfilled_amount.coin = max(0, unfulfilled_amount.coin)
784794

@@ -808,6 +818,7 @@ def build(
808818
[TransactionOutput(None, unfulfilled_amount)],
809819
self.context,
810820
include_max_fee=False,
821+
respect_min_utxo=not can_merge_change,
811822
)
812823
for s in selected:
813824
selected_amount += s.output.amount

test/pycardano/test_txbuilder.py

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from dataclasses import replace
22
from test.pycardano.test_key import SK
33
from test.pycardano.util import chain_context
4+
from unittest.mock import patch
45

56
import pytest
67

@@ -924,3 +925,82 @@ def test_tx_builder_merge_change_to_zero_amount_output(chain_context):
924925
}
925926

926927
assert expected == tx_body.to_primitive()
928+
929+
930+
def test_tx_builder_small_utxo_input(chain_context):
931+
with patch.object(chain_context, "utxos") as mock_utxos:
932+
mock_utxos.return_value = [
933+
UTxO(
934+
TransactionInput.from_primitive(
935+
[
936+
"41cb004bec7051621b19b46aea28f0657a586a05ce2013152ea9b9f1a5614cc7",
937+
1,
938+
]
939+
),
940+
TransactionOutput.from_primitive(
941+
[
942+
"addr1qytqt3v9ej3kzefxcy8f59h9atf2knracnj5snkgtaea6p4r8g3mu652945v3gldw7v88dn5lrfudx0un540ak9qt2kqhfjl0d",
943+
2991353,
944+
]
945+
),
946+
)
947+
]
948+
builder = TransactionBuilder(chain_context)
949+
address = Address.from_primitive(
950+
"addr1qytqt3v9ej3kzefxcy8f59h9atf2knracnj5snkgtaea6p4r8g3mu652945v3gldw7v88dn5lrfudx0un540ak9qt2kqhfjl0d"
951+
)
952+
builder.add_input_address(address)
953+
954+
builder.add_output(
955+
TransactionOutput(
956+
Address.from_primitive(
957+
"addr1qyady0evsaxqsfmz0z8rvmq62fmuas5w8n4m8z6qcm4wrt3e8dlsen8n464ucw69acfgdxgguscgfl5we3rwts4s57ashysyee"
958+
),
959+
Value.from_primitive(
960+
[
961+
1000000,
962+
]
963+
),
964+
)
965+
)
966+
signed_tx = builder.build(change_address=address)
967+
968+
969+
def test_tx_builder_merge_change_to_output_3(chain_context):
970+
with patch.object(chain_context, "utxos") as mock_utxos:
971+
mock_utxos.return_value = [
972+
UTxO(
973+
TransactionInput.from_primitive(
974+
[
975+
"41cb004bec7051621b19b46aea28f0657a586a05ce2013152ea9b9f1a5614cc7",
976+
1,
977+
]
978+
),
979+
TransactionOutput.from_primitive(
980+
[
981+
"addr1qytqt3v9ej3kzefxcy8f59h9atf2knracnj5snkgtaea6p4r8g3mu652945v3gldw7v88dn5lrfudx0un540ak9qt2kqhfjl0d",
982+
2991353,
983+
]
984+
),
985+
)
986+
]
987+
builder = TransactionBuilder(chain_context)
988+
address = Address.from_primitive(
989+
"addr1qytqt3v9ej3kzefxcy8f59h9atf2knracnj5snkgtaea6p4r8g3mu652945v3gldw7v88dn5lrfudx0un540ak9qt2kqhfjl0d"
990+
)
991+
builder.add_input_address(address)
992+
993+
builder.add_output(
994+
TransactionOutput(
995+
Address.from_primitive(
996+
"addr1qytqt3v9ej3kzefxcy8f59h9atf2knracnj5snkgtaea6p4r8g3mu652945v3gldw7v88dn5lrfudx0un540ak9qt2kqhfjl0d"
997+
),
998+
Value.from_primitive(
999+
[
1000+
1000000,
1001+
]
1002+
),
1003+
)
1004+
)
1005+
tx = builder.build(change_address=address, merge_change=True)
1006+
assert len(tx.outputs) == 1

0 commit comments

Comments
 (0)