1
0

registerAndWait.ts 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. export default () => {
  2. tier_outputs = self.tier_outputs
  3. tiers_sorted = sorted(tier_outputs.keys())
  4. if not tier_outputs:
  5. raise FusionError('No outputs available at any tier (selected inputs were too small / too large).')
  6. self.print_error(f'registering for tiers: {tiers_sorted}')
  7. tags = []
  8. for wallet in self.source_wallet_info:
  9. selffuse = Conf(wallet).self_fuse_players
  10. tags.append(pb.JoinPools.PoolTag(id = wallet.cashfusion_tag, limit = selffuse))
  11. ## Join waiting pools
  12. self.check_stop(running=False)
  13. self.check_coins()
  14. self.send(pb.JoinPools(tiers = tiers_sorted, tags=tags))
  15. self.status = ('waiting', 'Registered for tiers')
  16. # make nicer strings for UI
  17. tiers_strings = {t: '{:.8f}'.format(t * 1e-8).rstrip('0') for t, s in tier_outputs.items()}
  18. while True:
  19. # We should get a status update every 5 seconds.
  20. msg = self.recv('tierstatusupdate', 'fusionbegin', timeout=10)
  21. if isinstance(msg, pb.FusionBegin):
  22. break
  23. self.check_stop(running=False)
  24. self.check_coins()
  25. assert isinstance(msg, pb.TierStatusUpdate)
  26. statuses = msg.statuses
  27. maxfraction = 0.
  28. maxtiers = []
  29. besttime = None
  30. besttimetier = None
  31. for t,s in statuses.items():
  32. try:
  33. frac = s.players / s.min_players
  34. except ZeroDivisionError:
  35. frac = -1.
  36. if frac >= maxfraction:
  37. if frac > maxfraction:
  38. maxfraction = frac
  39. maxtiers.clear()
  40. maxtiers.append(t)
  41. if s.HasField('time_remaining'):
  42. tr = s.time_remaining
  43. if besttime is None or tr < besttime:
  44. besttime = tr
  45. besttimetier = t
  46. maxtiers = set(maxtiers)
  47. display_best = []
  48. display_mid = []
  49. display_queued = []
  50. for t in tiers_sorted:
  51. try:
  52. ts = tiers_strings[t]
  53. except KeyError:
  54. raise FusionError('server reported status on tier we are not registered for')
  55. if t in statuses:
  56. if t == besttimetier:
  57. display_best.insert(0, '**' + ts + '**')
  58. elif t in maxtiers:
  59. display_best.append('[' + ts + ']')
  60. else:
  61. display_mid.append(ts)
  62. else:
  63. display_queued.append(ts)
  64. parts = []
  65. if display_best or display_mid:
  66. parts.append(_("Tiers:") + ' ' + ', '.join(display_best + display_mid))
  67. if display_queued:
  68. parts.append(_("Queued:") + ' ' + ', '.join(display_queued))
  69. tiers_string = ' '.join(parts)
  70. if besttime is None and self.inactive_time_limit is not None:
  71. if time.monotonic() > self.inactive_time_limit:
  72. raise FusionError('stopping due to inactivity')
  73. if besttime is not None:
  74. self.status = ('waiting', 'Starting in {}s. {}'.format(besttime, tiers_string))
  75. elif maxfraction >= 1:
  76. self.status = ('waiting', 'Starting soon. {}'.format(tiers_string))
  77. elif display_best or display_mid:
  78. self.status = ('waiting', '{:d}% full. {}'.format(round(maxfraction*100), tiers_string))
  79. else:
  80. self.status = ('waiting', tiers_string)
  81. assert isinstance(msg, pb.FusionBegin)
  82. # Record the time we got FusionBegin. Later in run_round we will check that the
  83. # first round comes at a very particular time relative to this message.
  84. self.t_fusionbegin = time.monotonic()
  85. # Check the server's declared unix time, which will be committed.
  86. clock_mismatch = msg.server_time - time.time()
  87. if abs(clock_mismatch) > Protocol.MAX_CLOCK_DISCREPANCY:
  88. raise FusionError(f"Clock mismatch too large: {clock_mismatch:+.3f}.")
  89. self.tier = msg.tier
  90. self.covert_domain_b = msg.covert_domain
  91. self.covert_port = msg.covert_port
  92. self.covert_ssl = msg.covert_ssl
  93. self.begin_time = msg.server_time
  94. self.last_hash = calc_initial_hash(self.tier, msg.covert_domain, msg.covert_port, msg.covert_ssl, msg.server_time)
  95. out_amounts = tier_outputs[self.tier]
  96. out_addrs = self.target_wallet.reserve_change_addresses(len(out_amounts), temporary=True)
  97. self.reserved_addresses = out_addrs
  98. self.outputs = list(zip(out_amounts, out_addrs))
  99. self.safety_excess_fee = self.safety_excess_fees[self.tier]
  100. self.print_error(f"starting fusion rounds at tier {self.tier}: {len(self.inputs)} inputs and {len(self.outputs)} outputs")
  101. }