def run_coins_loop(cls): while not stop_test: try: if cls.btc_addr is not None: btcRpc('generatetoaddress 1 {}'.format(cls.btc_addr)) if cls.xmr_addr is not None: callrpc_xmr_na(XMR_BASE_RPC_PORT + 1, 'generateblocks', {'wallet_address': cls.xmr_addr, 'amount_of_blocks': 1}) except Exception as e: logging.warning('run_coins_loop ' + str(e)) time.sleep(1.0)
def updateThread(xmr_addr, delay_event): while not delay_event.is_set(): try: callrpc_xmr_na(XMR_BASE_RPC_PORT + 1, 'generateblocks', { 'wallet_address': xmr_addr, 'amount_of_blocks': 1 }) except Exception as e: print('updateThread error', str(e)) delay_event.wait(2)
def waitForXMRNode(rpc_offset, max_tries=7): for i in range(max_tries + 1): try: callrpc_xmr_na(XMR_BASE_RPC_PORT + rpc_offset, 'get_block_count') return except Exception as ex: if i < max_tries: logging.warning('Can\'t connect to XMR RPC: %s. Retrying in %d second/s.', str(ex), (i + 1)) time.sleep(i + 1) raise ValueError('waitForXMRNode failed')
def updateThreadXmr(cls): while not cls.delay_event.is_set(): try: if cls.xmr_addr is not None: callrpc_xmr_na(XMR_BASE_RPC_PORT + 1, 'generateblocks', { 'wallet_address': cls.xmr_addr, 'amount_of_blocks': 1 }) except Exception as e: print('updateThreadXmr error', str(e)) cls.delay_event.wait( random.randrange(cls.xmr_update_min, cls.xmr_update_max))
def start_processes(self): self.delay_event.clear() for i in range(3): self.processes.append( multiprocessing.Process(target=self.run_thread, args=(i, ))) self.processes[-1].start() waitForServer(self.delay_event, 12701) wallets = json.loads( urlopen('http://127.0.0.1:12701/json/wallets').read()) xmr_addr1 = wallets['6']['deposit_address'] num_blocks = 100 if callrpc_xmr_na(XMR_BASE_RPC_PORT + 1, 'get_block_count')['count'] < num_blocks: logging.info('Mining {} Monero blocks to {}.'.format( num_blocks, xmr_addr1)) callrpc_xmr_na(XMR_BASE_RPC_PORT + 1, 'generateblocks', { 'wallet_address': xmr_addr1, 'amount_of_blocks': num_blocks }) logging.info( 'XMR blocks: %d', callrpc_xmr_na(XMR_BASE_RPC_PORT + 1, 'get_block_count')['count']) self.update_thread = threading.Thread(target=updateThread, args=(xmr_addr1, self.delay_event)) self.update_thread.start() # Wait for height, or sequencelock is thrown off by genesis blocktime num_blocks = 3 logging.info('Waiting for Particl chain height %d', num_blocks) for i in range(60): if self.delay_event.is_set(): raise ValueError('Test stopped.') wallets = json.loads( urlopen('http://127.0.0.1:12701/json/wallets').read()) particl_blocks = wallets['1']['blocks'] print('particl_blocks', particl_blocks) if particl_blocks >= num_blocks: break self.delay_event.wait(1) assert (particl_blocks >= num_blocks)
def updateThread(xmr_addr): while not stop_test: callrpc_xmr_na(XMR_BASE_RPC_PORT + 1, 'generateblocks', {'wallet_address': xmr_addr, 'amount_of_blocks': 1}) time.sleep(5)
def test_reload(self): global stop_test update_thread = None processes = [] for i in range(3): processes.append(multiprocessing.Process(target=self.run_thread, args=(i,))) processes[-1].start() try: waitForServer(12701) wallets = json.loads(urlopen('http://localhost:12701/json/wallets').read()) xmr_addr1 = wallets['6']['deposit_address'] num_blocks = 500 logging.info('Mining %d Monero blocks.', num_blocks) callrpc_xmr_na(XMR_BASE_RPC_PORT + 1, 'generateblocks', {'wallet_address': xmr_addr1, 'amount_of_blocks': num_blocks}) rv = callrpc_xmr_na(XMR_BASE_RPC_PORT + 1, 'get_block_count') logging.info('XMR blocks: %d', rv['count']) data = parse.urlencode({ 'addr_from': '-1', 'coin_from': '1', 'coin_to': '6', 'amt_from': '1', 'amt_to': '1', 'lockhrs': '24'}).encode() offer_id = json.loads(urlopen('http://localhost:12700/json/offers/new', data=data).read()) summary = json.loads(urlopen('http://localhost:12700/json').read()) assert(summary['num_sent_offers'] == 1) logger.info('Waiting for offer') waitForNumOffers(12701, 1) offers = json.loads(urlopen('http://localhost:12701/json/offers').read()) offer = offers[0] data = parse.urlencode({ 'offer_id': offer['offer_id'], 'amount_from': offer['amount_from']}).encode() bid_id = json.loads(urlopen('http://localhost:12701/json/bids/new', data=data).read()) waitForNumBids(12700, 1) for i in range(10): bids = json.loads(urlopen('http://localhost:12700/json/bids').read()) bid = bids[0] if bid['bid_state'] == 'Received': break time.sleep(1) data = parse.urlencode({ 'accept': True }).encode() rv = json.loads(urlopen('http://localhost:12700/json/bids/{}'.format(bid['bid_id']), data=data).read()) assert(rv['bid_state'] == 'Accepted') waitForNumSwapping(12701, 1) logger.info('Restarting client') c1 = processes[1] c1.terminate() c1.join() processes[1] = multiprocessing.Process(target=self.run_thread, args=(1,)) processes[1].start() waitForServer(12701) rv = json.loads(urlopen('http://localhost:12701/json').read()) assert(rv['num_swapping'] == 1) update_thread = threading.Thread(target=updateThread, args=(xmr_addr1,)) update_thread.start() logger.info('Completing swap') for i in range(240): time.sleep(5) rv = json.loads(urlopen('http://localhost:12700/json/bids/{}'.format(bid['bid_id'])).read()) print(rv) if rv['bid_state'] == 'Completed': break assert(rv['bid_state'] == 'Completed') except Exception: traceback.print_exc() logger.info('Stopping test') stop_test = True if update_thread: update_thread.join() for p in processes: p.terminate() for p in processes: p.join()
def setUpClass(cls): super(Test, cls).setUpClass() cls.update_thread = None cls.coins_update_thread = None cls.http_threads = [] cls.swap_clients = [] cls.part_daemons = [] cls.btc_daemons = [] cls.xmr_daemons = [] cls.xmr_wallet_auth = [] cls.part_stakelimit = 0 cls.xmr_addr = None cls.btc_addr = None logger.propagate = False logger.handlers = [] logger.setLevel(logging.INFO) # DEBUG shows many messages from requests.post formatter = logging.Formatter('%(asctime)s %(levelname)s : %(message)s') stream_stdout = logging.StreamHandler() stream_stdout.setFormatter(formatter) logger.addHandler(stream_stdout) if os.path.isdir(TEST_DIR): logging.info('Removing ' + TEST_DIR) shutil.rmtree(TEST_DIR) if not os.path.exists(TEST_DIR): os.makedirs(TEST_DIR) cls.stream_fp = logging.FileHandler(os.path.join(TEST_DIR, 'test.log')) cls.stream_fp.setFormatter(formatter) logger.addHandler(cls.stream_fp) try: logging.info('Preparing coin nodes.') for i in range(NUM_NODES): prepareDataDir(TEST_DIR, i, 'particl.conf', 'part_') cls.part_daemons.append(startDaemon(os.path.join(TEST_DIR, 'part_' + str(i)), cfg.PARTICL_BINDIR, cfg.PARTICLD)) logging.info('Started %s %d', cfg.PARTICLD, cls.part_daemons[-1].pid) for i in range(NUM_NODES): # Load mnemonics after all nodes have started to avoid staking getting stuck in TryToSync rpc = make_rpc_func(i) waitForRPC(rpc) if i == 0: rpc('extkeyimportmaster', ['abandon baby cabbage dad eager fabric gadget habit ice kangaroo lab absorb']) elif i == 1: rpc('extkeyimportmaster', ['pact mammal barrel matrix local final lecture chunk wasp survey bid various book strong spread fall ozone daring like topple door fatigue limb olympic', '', 'true']) rpc('getnewextaddress', ['lblExtTest']) rpc('rescanblockchain') else: rpc('extkeyimportmaster', [rpc('mnemonic', ['new'])['master']]) # Lower output split threshold for more stakeable outputs rpc('walletsettings', ['stakingoptions', {'stakecombinethreshold': 100, 'stakesplitthreshold': 200}]) for i in range(NUM_BTC_NODES): prepareDataDir(TEST_DIR, i, 'bitcoin.conf', 'btc_', base_p2p_port=BTC_BASE_PORT, base_rpc_port=BTC_BASE_RPC_PORT) cls.btc_daemons.append(startDaemon(os.path.join(TEST_DIR, 'btc_' + str(i)), cfg.BITCOIN_BINDIR, cfg.BITCOIND)) logging.info('Started %s %d', cfg.BITCOIND, cls.part_daemons[-1].pid) waitForRPC(make_rpc_func(i, base_rpc_port=BTC_BASE_RPC_PORT)) for i in range(NUM_XMR_NODES): prepareXmrDataDir(TEST_DIR, i, 'monerod.conf') cls.xmr_daemons.append(startXmrDaemon(os.path.join(TEST_DIR, 'xmr_' + str(i)), cfg.XMR_BINDIR, cfg.XMRD)) logging.info('Started %s %d', cfg.XMRD, cls.xmr_daemons[-1].pid) waitForXMRNode(i) cls.xmr_daemons.append(startXmrWalletRPC(os.path.join(TEST_DIR, 'xmr_' + str(i)), cfg.XMR_BINDIR, cfg.XMR_WALLET_RPC, i)) for i in range(NUM_XMR_NODES): cls.xmr_wallet_auth.append(('test{0}'.format(i), 'test_pass{0}'.format(i))) logging.info('Creating XMR wallet %i', i) waitForXMRWallet(i, cls.xmr_wallet_auth[i]) cls.callxmrnodewallet(cls, i, 'create_wallet', {'filename': 'testwallet', 'language': 'English'}) cls.callxmrnodewallet(cls, i, 'open_wallet', {'filename': 'testwallet'}) logging.info('Preparing swap clients.') eckey = ECKey() eckey.generate() cls.network_key = toWIF(PREFIX_SECRET_KEY_REGTEST, eckey.get_bytes()) cls.network_pubkey = eckey.get_pubkey().get_bytes().hex() for i in range(NUM_NODES): prepare_swapclient_dir(TEST_DIR, i, cls.network_key, cls.network_pubkey) basicswap_dir = os.path.join(os.path.join(TEST_DIR, 'basicswap_' + str(i))) settings_path = os.path.join(basicswap_dir, cfg.CONFIG_FILENAME) with open(settings_path) as fs: settings = json.load(fs) fp = open(os.path.join(basicswap_dir, 'basicswap.log'), 'w') sc = BasicSwap(fp, basicswap_dir, settings, 'regtest', log_name='BasicSwap{}'.format(i)) sc.setDaemonPID(Coins.BTC, cls.btc_daemons[i].pid) sc.setDaemonPID(Coins.PART, cls.part_daemons[i].pid) sc.start() cls.swap_clients.append(sc) t = HttpThread(cls.swap_clients[i].fp, TEST_HTTP_HOST, TEST_HTTP_PORT + i, False, cls.swap_clients[i]) cls.http_threads.append(t) t.start() cls.btc_addr = callnoderpc(0, 'getnewaddress', ['mining_addr', 'bech32'], base_rpc_port=BTC_BASE_RPC_PORT) cls.xmr_addr = cls.callxmrnodewallet(cls, 1, 'get_address')['address'] num_blocks = 500 logging.info('Mining %d Bitcoin blocks to %s', num_blocks, cls.btc_addr) callnoderpc(0, 'generatetoaddress', [num_blocks, cls.btc_addr], base_rpc_port=BTC_BASE_RPC_PORT) checkForks(callnoderpc(0, 'getblockchaininfo', base_rpc_port=BTC_BASE_RPC_PORT)) if callrpc_xmr_na(XMR_BASE_RPC_PORT + 1, 'get_block_count')['count'] < num_blocks: logging.info('Mining %d Monero blocks.', num_blocks) callrpc_xmr_na(XMR_BASE_RPC_PORT + 1, 'generateblocks', {'wallet_address': cls.xmr_addr, 'amount_of_blocks': num_blocks}) rv = callrpc_xmr_na(XMR_BASE_RPC_PORT + 1, 'get_block_count') logging.info('XMR blocks: %d', rv['count']) logging.info('Starting update thread.') signal.signal(signal.SIGINT, signal_handler) cls.update_thread = threading.Thread(target=run_loop, args=(cls,)) cls.update_thread.start() cls.coins_update_thread = threading.Thread(target=run_coins_loop, args=(cls,)) cls.coins_update_thread.start() except Exception: traceback.print_exc() Test.tearDownClass() raise ValueError('setUpClass() failed.')
def start_processes(self): self.delay_event.clear() for i in range(NUM_NODES): self.processes.append( multiprocessing.Process(target=self.run_thread, args=(i, ))) self.processes[-1].start() for i in range(NUM_NODES): waitForServer(self.delay_event, UI_PORT + i) wallets = json.loads( urlopen('http://127.0.0.1:{}/json/wallets'.format(UI_PORT + 1)).read()) self.xmr_addr = wallets['6']['deposit_address'] num_blocks = 100 if callrpc_xmr_na(XMR_BASE_RPC_PORT + 1, 'get_block_count')['count'] < num_blocks: logging.info('Mining {} Monero blocks to {}.'.format( num_blocks, self.xmr_addr)) callrpc_xmr_na(XMR_BASE_RPC_PORT + 1, 'generateblocks', { 'wallet_address': self.xmr_addr, 'amount_of_blocks': num_blocks }) logging.info( 'XMR blocks: %d', callrpc_xmr_na(XMR_BASE_RPC_PORT + 1, 'get_block_count')['count']) self.btc_addr = callbtcrpc(0, 'getnewaddress', ['mining_addr', 'bech32']) num_blocks = 500 # Mine enough to activate segwit if callbtcrpc(0, 'getblockchaininfo')['blocks'] < num_blocks: logging.info('Mining %d Bitcoin blocks to %s', num_blocks, self.btc_addr) callbtcrpc(0, 'generatetoaddress', [num_blocks, self.btc_addr]) logging.info('BTC blocks: %d', callbtcrpc(0, 'getblockchaininfo')['blocks']) # Lower output split threshold for more stakeable outputs for i in range(NUM_NODES): callpartrpc(i, 'walletsettings', [ 'stakingoptions', { 'stakecombinethreshold': 100, 'stakesplitthreshold': 200 } ]) self.update_thread = threading.Thread(target=updateThread, args=(self, )) self.update_thread.start() self.update_thread_xmr = threading.Thread(target=updateThreadXmr, args=(self, )) self.update_thread_xmr.start() # Wait for height, or sequencelock is thrown off by genesis blocktime num_blocks = 3 logging.info('Waiting for Particl chain height %d', num_blocks) for i in range(60): if self.delay_event.is_set(): raise ValueError('Test stopped.') particl_blocks = callpartrpc(0, 'getblockchaininfo')['blocks'] print('particl_blocks', particl_blocks) if particl_blocks >= num_blocks: break self.delay_event.wait(1) logging.info('PART blocks: %d', callpartrpc(0, 'getblockchaininfo')['blocks']) assert (particl_blocks >= num_blocks)