selectCoins.ts 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. /**
  2. * """ Sort the wallet's coins into address buckets, returning two lists:
  3. - Eligible addresses and their coins.
  4. - Ineligible addresses and their coins.
  5. An address is eligible if it satisfies all conditions:
  6. - the address is unfrozen
  7. - has 1, 2, or 3 utxo
  8. - all utxo are confirmed (or matured in case of coinbases)
  9. - has no SLP utxo or frozen utxo
  10. """
  11. */
  12. export default async (wallet) => {
  13. # First, select all the coins
  14. eligible = []
  15. ineligible = []
  16. has_unconfirmed = False
  17. has_coinbase = False
  18. sum_value = 0
  19. mincbheight = (wallet.get_local_height() + 1 - COINBASE_MATURITY if Conf(wallet).autofuse_coinbase
  20. else -1) # -1 here causes coinbase coins to always be rejected
  21. for addr in wallet.get_addresses():
  22. acoins = list(wallet.get_addr_utxo(addr).values())
  23. if not acoins:
  24. continue # prevent inserting empty lists into eligible/ineligible
  25. good = True
  26. if addr in wallet.frozen_addresses:
  27. good = False
  28. for i,c in enumerate(acoins):
  29. sum_value += c['value'] # tally up values regardless of eligibility
  30. # If too many coins, any SLP tokens, any frozen coins, or any
  31. # immature coinbase on the address -> flag all address coins as
  32. # ineligible if not already flagged as such.
  33. good = good and (
  34. i < 3 # must not have too many coins on the same address*
  35. and not c['token_data'] # must not have a CashToken on it
  36. and not c['slp_token'] # must not be SLP
  37. and not c['is_frozen_coin'] # must not be frozen
  38. and (not c['coinbase'] or c['height'] <= mincbheight) # if coinbase -> must be mature coinbase
  39. )
  40. # * = We skip addresses with too many coins, since they take up lots
  41. # of 'space' for consolidation. TODO: there is possibility of
  42. # disruption here, if we get dust spammed. Need to deal with
  43. # 'dusty' addresses by ignoring / consolidating dusty coins.
  44. # Next, detect has_unconfirmed & has_coinbase:
  45. if c['height'] <= 0:
  46. # Unconfirmed -> Flag as not eligible and set the has_unconfirmed flag.
  47. good = False
  48. has_unconfirmed = True
  49. # Update has_coinbase flag if not already set
  50. has_coinbase = has_coinbase or c['coinbase']
  51. if good:
  52. eligible.append((addr,acoins))
  53. else:
  54. ineligible.append((addr,acoins))
  55. return eligible, ineligible, int(sum_value), bool(has_unconfirmed), bool(has_coinbase)
  56. }