handle creating transactions where input is consumed by fees and there is no output by creating an additional input which will require some change output
This commit is contained in:
parent
ae8fece9bb
commit
268e599423
1 changed files with 31 additions and 16 deletions
|
@ -444,6 +444,8 @@ class BaseTransaction:
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
||||||
|
for _ in range(2):
|
||||||
|
|
||||||
if payment < cost:
|
if payment < cost:
|
||||||
deficit = cost - payment
|
deficit = cost - payment
|
||||||
spendables = await ledger.get_spendable_utxos(deficit, funding_accounts)
|
spendables = await ledger.get_spendable_utxos(deficit, funding_accounts)
|
||||||
|
@ -452,11 +454,11 @@ class BaseTransaction:
|
||||||
payment += sum(s.effective_amount for s in spendables)
|
payment += sum(s.effective_amount for s in spendables)
|
||||||
tx.add_inputs(s.txi for s in spendables)
|
tx.add_inputs(s.txi for s in spendables)
|
||||||
|
|
||||||
if payment > cost:
|
|
||||||
cost_of_change = (
|
cost_of_change = (
|
||||||
tx.get_base_fee(ledger) +
|
tx.get_base_fee(ledger) +
|
||||||
cls.output_class.pay_pubkey_hash(COIN, NULL_HASH32).get_fee(ledger)
|
cls.output_class.pay_pubkey_hash(COIN, NULL_HASH32).get_fee(ledger)
|
||||||
)
|
)
|
||||||
|
if payment > cost:
|
||||||
change = payment - cost
|
change = payment - cost
|
||||||
if change > cost_of_change:
|
if change > cost_of_change:
|
||||||
change_address = await change_account.change.get_or_create_usable_address()
|
change_address = await change_account.change.get_or_create_usable_address()
|
||||||
|
@ -466,6 +468,19 @@ class BaseTransaction:
|
||||||
change_output.is_change = True
|
change_output.is_change = True
|
||||||
tx.add_outputs([cls.output_class.pay_pubkey_hash(change_amount, change_hash160)])
|
tx.add_outputs([cls.output_class.pay_pubkey_hash(change_amount, change_hash160)])
|
||||||
|
|
||||||
|
if tx._outputs:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
# this condition and the outer range(2) loop cover an edge case
|
||||||
|
# whereby a single input is just enough to cover the fee and
|
||||||
|
# has some change left over, but the change left over is less
|
||||||
|
# than the cost_of_change: thus the input is completely
|
||||||
|
# consumed and no output is added, which is an invalid tx.
|
||||||
|
# to be able to spend this input we must increase the cost
|
||||||
|
# of the TX and run through the balance algorithm a second time
|
||||||
|
# adding an extra input and change output, making tx valid.
|
||||||
|
cost = cost + cost_of_change + 1
|
||||||
|
|
||||||
await tx.sign(funding_accounts)
|
await tx.sign(funding_accounts)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|
Loading…
Reference in a new issue