Guest User

Untitled

a guest
Dec 7th, 2018
199
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.02 KB | None | 0 0
  1. import threading
  2. import asyncio
  3. import time
  4. import json
  5. import subprocess
  6. import colorama
  7. import os
  8.  
  9. from utils import BitcoinRpc
  10. from electrumutils import ElectrumX, ElectrumNode
  11.  
  12. from electrum import constants
  13. constants.set_regtest()
  14. from electrum.bitcoin import script_to_scripthash
  15. from electrum.transaction import TxOutput
  16. from electrum.bitcoin import TYPE_SCRIPT
  17. from electrum.util import bh2u
  18. from electrum.crypto import hash_160
  19.  
  20. x = ElectrumX()
  21. x.start("doggman","donkey",18554)
  22.  
  23. elec = ElectrumNode(None,None,None,None)
  24. elec.daemon.start()
  25. time.sleep(1)
  26. print(elec.info())
  27.  
  28. class bitcoind:
  29. rpc = BitcoinRpc(rpcport=18554, rpcuser='doggman', rpcpassword='donkey')
  30. if bitcoind.rpc.getblockchaininfo()['blocks'] < 150:
  31. bitcoind.rpc.generate(150)
  32. elec.addfunds(bitcoind, 100000000)
  33.  
  34. script = "0014" + bh2u(os.urandom(20))
  35. scr = script_to_scripthash(script)
  36. print("SCRIPTHASH WE ARE TESTING FOR", scr)
  37.  
  38. import queue
  39.  
  40. q= queue.Queue()
  41.  
  42. def req(proc):
  43. while None is proc.poll():
  44. line = proc.stdout.readline()
  45. if line:
  46. q.put(line)
  47.  
  48. print("PROCESS DIED")
  49.  
  50. def generate_block(num=1):
  51. with subprocess.Popen(f'bitcoin-cli generate {num}'.split(' '), stdout=subprocess.PIPE) as btc:
  52. txids = json.loads(btc.stdout.read().strip())
  53. return txids
  54.  
  55. def make_tx(outputs, config):
  56. coins = elec.wallet.get_spendable_coins(None, config, nonlocal_only=True)
  57. from random import choice
  58. coins = [choice(coins)]
  59. tx = elec.wallet.make_unsigned_transaction(coins, outputs, config, None, None)
  60. elec.wallet.sign_transaction(tx, None)
  61. return tx
  62.  
  63. with subprocess.Popen(['nc', '-vvvvv', '127.0.0.1', '51001'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, bufsize=1, universal_newlines=True) as proc:
  64. obj1 = {"id": 1, "method": "server.version", "params": ["testing", "1.4"]}
  65. proc.stdin.write(json.dumps(obj1) + "\n")
  66. print('version response', proc.stdout.readline())
  67. obj2 = {"id": 2, "method": "blockchain.scripthash.subscribe", "params": [scr]}
  68. for_server = f'{json.dumps(obj2)}\n'
  69. proc.stdin.write(for_server)
  70. t = threading.Thread(target=lambda: req(proc))
  71. t.start()
  72. i=3
  73. while True:
  74. print(colorama.Fore.RED + f"NEW RUN, NOW MINING {(i+1)**4} BLOCKS TO TRIGGER THE RACE" + colorama.Fore.RESET)
  75.  
  76. coro = asyncio.run_coroutine_threadsafe(elec.wallet.network.get_history_for_scripthash(scr), elec.wallet.network.asyncio_loop)
  77. beforelen = len(coro.result(5))
  78.  
  79. outputs = [TxOutput(TYPE_SCRIPT, script, 100000+i)]
  80. i+=1
  81. tx = make_tx(outputs,elec.wallet.network.config)
  82. coro = asyncio.run_coroutine_threadsafe(elec.wallet.network.broadcast_transaction(tx), elec.wallet.network.asyncio_loop)
  83. try:
  84. coro.result(1)
  85. except:
  86. generate_block()
  87. time.sleep(5)
  88. continue
  89. block_hash = generate_block(i**4)[0]
  90. assert bitcoind.rpc.getblock(block_hash)['tx'][1] == tx.txid()
  91. saw_yet = False
  92. while not saw_yet:
  93. # if this continues for too long, it is a bug in electrumx
  94. print("electrumx did not see ", tx.txid(), "yet")
  95. print("it is in block", block_hash,"but")
  96. print("try yourself:")
  97. print('printf \'{"id": 1, "method": "server.version", "params": ["testing", "1.4"]}\\n{"id": 2, "method": "blockchain.scripthash.get_history", "params":["' + scr + '"]}\\n\' | nc 127.0.0.1 51001')
  98. time.sleep(5)
  99. saw_yet = not q.empty()
  100.  
  101. print('saw tx')
  102. while not q.empty():
  103. res= q.get()
  104. print('scripthash update response' , res)
  105. parsed = json.loads(res)
  106. if 'result' not in parsed or parsed['result'] is None:
  107. print("ignoring none result")
  108. continue
  109. coro = asyncio.run_coroutine_threadsafe(elec.wallet.network.get_history_for_scripthash(scr), elec.wallet.network.asyncio_loop)
  110. hist = coro.result(5)
  111. print("history", hist)
  112. assert len(hist) != beforelen
  113. time.sleep(5)
  114.  
  115. x.kill()
Add Comment
Please, Sign In to add comment