diff --git a/lbry/wallet/constants.py b/lbry/wallet/constants.py index 34b8baa88..775ba4bbc 100644 --- a/lbry/wallet/constants.py +++ b/lbry/wallet/constants.py @@ -2,6 +2,7 @@ NULL_HASH32 = b'\x00'*32 CENT = 1000000 COIN = 100*CENT +DUST = 1000 TIMEOUT = 30.0 diff --git a/lbry/wallet/transaction.py b/lbry/wallet/transaction.py index a6f3bf376..120482c55 100644 --- a/lbry/wallet/transaction.py +++ b/lbry/wallet/transaction.py @@ -14,7 +14,7 @@ from lbry.schema.purchase import Purchase from lbry.schema.support import Support from .script import InputScript, OutputScript -from .constants import COIN, NULL_HASH32 +from .constants import COIN, DUST, NULL_HASH32 from .bcd_data_stream import BCDataStream from .hash import TXRef, TXRefImmutable from .util import ReadOnlyList @@ -818,10 +818,10 @@ class Transaction: ) if payment > cost: change = payment - cost - if change > cost_of_change: + change_amount = change - cost_of_change + if change_amount > DUST: change_address = await change_account.change.get_or_create_usable_address() change_hash160 = change_account.ledger.address_to_hash160(change_address) - change_amount = change - cost_of_change change_output = Output.pay_pubkey_hash(change_amount, change_hash160) change_output.is_internal_transfer = True tx.add_outputs([Output.pay_pubkey_hash(change_amount, change_hash160)]) diff --git a/tests/integration/transactions/test_transaction_commands.py b/tests/integration/transactions/test_transaction_commands.py index 66810b30f..d85641847 100644 --- a/tests/integration/transactions/test_transaction_commands.py +++ b/tests/integration/transactions/test_transaction_commands.py @@ -3,6 +3,17 @@ from lbry.testcase import CommandTestCase class TransactionCommandsTestCase(CommandTestCase): + async def test_txo_dust_prevention(self): + address = await self.daemon.jsonrpc_address_unused(self.account.id) + tx = await self.account_send('9.9997758', address) + # dust prevention threshold not reached, small txo created + self.assertEqual(2, len(tx['outputs'])) + self.assertEqual(tx['outputs'][1]['amount'], '0.0001002') + tx = await self.account_send('9.999706', address) + # dust prevention prevented dust + self.assertEqual(1, len(tx['outputs'])) + self.assertEqual(tx['outputs'][0]['amount'], '9.999706') + async def test_transaction_show(self): # local tx result = await self.out(self.daemon.jsonrpc_account_send(