mmnode-peerblocks 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. #!/usr/bin/env python
  2. # -*- coding: UTF-8 -*-
  3. import time,threading
  4. from mmgen.common import *
  5. opts_data = {
  6. 'desc': 'List blocks in flight, disconnect stalling nodes',
  7. 'usage': '[opts]',
  8. 'options': """
  9. -h, --help Print this help message
  10. --, --longhelp Print help message for long options (common options)
  11. """
  12. }
  13. cmd_args = opts.init(opts_data)
  14. colors = ['\033[38;5;%s;1m' % c for c in 238,240,242,244,246,247,249,251,253,255]
  15. _red,_reset = '\033[31m','\033[0m'
  16. ERASE_ALL,ERASE_LINE,CUR_HOME,CUR_HIDE,CUR_SHOW = \
  17. '\033[J','\033[K','\033[H','\033[?25l','\033[?25h'
  18. import atexit
  19. def at_exit():
  20. import os
  21. os.system('stty sane')
  22. sys.stderr.write('\n')
  23. atexit.register(at_exit)
  24. bc = bitcoin_connection()
  25. msg_r(CUR_HOME+ERASE_ALL)
  26. def do_display():
  27. from mmgen.term import get_terminal_size
  28. global data
  29. count = 1
  30. while True:
  31. twid = get_terminal_size()[0]
  32. data = bc.getpeerinfo()
  33. min_t = None
  34. lines = []
  35. with lock:
  36. msg('{}{}{}ACTIVE PEERS ({}) - poll {}'.format(
  37. CUR_HOME,ERASE_ALL,CUR_HOME,len(data),count))
  38. for d in data:
  39. line = { 'id': d['id'], 'data': [] }
  40. if 'inflight' in d and d['inflight']:
  41. blks = [str(e) for e in d['inflight']]
  42. min_p = min(e for e in d['inflight'])
  43. if not min_t or min_t > min_p: min_t = min_p
  44. line_d = ' '.join(blks)[:twid-6]
  45. blks = blks[:len(line_d) - len(line_d.replace(' ','')) + 1]
  46. blks[-1] = blks[-1][:len(line_d.split(' ')[-1])]
  47. line['data'] = [[colors[int(i)%10],i,_reset] for i in blks if i]
  48. else:
  49. line['data'] = []
  50. lines.append(line)
  51. for line in lines:
  52. d = ' '.join([(a,_red)[int(b)==min_t]+b+c for a,b,c in line['data']])
  53. sys.stderr.write('\r{} {:>3}: {}\n'.format(ERASE_LINE,line['id'],d))
  54. msg_r(ERASE_ALL+'Hit ENTER for disconnect prompt: ')
  55. time.sleep(2)
  56. count += 1
  57. lock = threading.Lock()
  58. data = {}
  59. t = threading.Thread(target=do_display,name='display')
  60. t.daemon = True
  61. t.start()
  62. def do_loop():
  63. global data
  64. while True:
  65. raw_input()
  66. with lock:
  67. ids = [str(d['id']) for d in data]
  68. msg('{}{}{}ACTIVE PEERS ({})'.format(CUR_HOME,ERASE_ALL,CUR_HOME,len(data)))
  69. msg(' '+'\n '.join(['{:>3}: {:30} {}'.format(*[d[k] for k in 'id','addr','subver']) for d in data]))
  70. reply = raw_input('Enter a peer number to disconnect> ')
  71. if reply == '':
  72. pass
  73. elif reply in ids:
  74. idx = ids.index(reply)
  75. msg("Disconnecting peer {} ('{}')".format(reply,data[idx]['addr']))
  76. bc.disconnectnode(data[idx]['addr'])
  77. time.sleep(1.5)
  78. else:
  79. msg("'{}': invalid peer number".format(reply))
  80. time.sleep(0.5)
  81. try:
  82. do_loop()
  83. except KeyboardInterrupt:
  84. pass