def run_test(self):
    self.url = urllib.parse.urlparse(self.nodes[0].url)
    self.log.info('Mine blocks and send Bitcoin to node 1')
    not_related_address = convert_btc_address_to_qtum('2MxqoHEdNQTyYeX1mHcbrrpzgojbosTpCvJ')
    self.nodes[0].generate(1)
    self.sync_all()
    for i in range(0, COINBASE_MATURITY, 100):
        self.nodes[1].generatetoaddress(100, not_related_address)
    self.sync_all()
    assert_equal(self.nodes[0].getbalance(), INITIAL_BLOCK_REWARD)
    txid = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.1)
    self.sync_all()
    self.log.info('Test the /tx URI')
    json_obj = self.test_rest_request('/tx/{}'.format(txid))
    assert_equal(json_obj['txid'], txid)
    hex_response = self.test_rest_request('/tx/{}'.format(txid), req_type=ReqType.HEX, ret_type=RetType.OBJ)
    assert_greater_than_or_equal(int(hex_response.getheader('content-length')), (json_obj['size'] * 2))
    spent = (json_obj['vin'][0]['txid'], json_obj['vin'][0]['vout'])
    (n,) = filter_output_indices_by_value(json_obj['vout'], Decimal('0.1'))
    spending = (txid, n)
    self.log.info('Query an unspent TXO using the /getutxos URI')
    self.nodes[1].generatetoaddress(1, not_related_address)
    self.sync_all()
    bb_hash = self.nodes[0].getbestblockhash()
    assert_equal(self.nodes[1].getbalance(), Decimal('0.1'))
    json_obj = self.test_rest_request('/getutxos/{}-{}'.format(*spending))
    assert_equal(json_obj['chaintipHash'], bb_hash)
    assert_equal(len(json_obj['utxos']), 1)
    assert_equal(json_obj['utxos'][0]['value'], Decimal('0.1'))
    self.log.info('Query a spent TXO using the /getutxos URI')
    json_obj = self.test_rest_request('/getutxos/{}-{}'.format(*spent))
    assert_equal(json_obj['chaintipHash'], bb_hash)
    assert_equal(len(json_obj['utxos']), 0)
    assert_equal(json_obj['bitmap'], '0')
    self.log.info('Query two TXOs using the /getutxos URI')
    json_obj = self.test_rest_request('/getutxos/{}-{}/{}-{}'.format(*(spending + spent)))
    assert_equal(len(json_obj['utxos']), 1)
    assert_equal(json_obj['bitmap'], '10')
    self.log.info('Query the TXOs using the /getutxos URI with a binary response')
    bin_request = b'\x01\x02'
    for (txid, n) in [spending, spent]:
        bin_request += hex_str_to_bytes(txid)
        bin_request += pack('i', n)
    bin_response = self.test_rest_request('/getutxos', http_method='POST', req_type=ReqType.BIN, body=bin_request, ret_type=RetType.BYTES)
    output = BytesIO(bin_response)
    (chain_height,) = unpack('<i', output.read(4))
    response_hash = output.read(32)[::(- 1)].hex()
    assert_equal(bb_hash, response_hash)
    assert_equal(chain_height, (COINBASE_MATURITY + 2))
    self.log.info('Test the /getutxos URI with and without /checkmempool')
    txid = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.1)
    json_obj = self.test_rest_request('/tx/{}'.format(txid))
    spent = (json_obj['vin'][0]['txid'], json_obj['vin'][0]['vout'])
    (n,) = filter_output_indices_by_value(json_obj['vout'], Decimal('0.1'))
    spending = (txid, n)
    json_obj = self.test_rest_request('/getutxos/{}-{}'.format(*spending))
    assert_equal(len(json_obj['utxos']), 0)
    json_obj = self.test_rest_request('/getutxos/checkmempool/{}-{}'.format(*spending))
    assert_equal(len(json_obj['utxos']), 1)
    json_obj = self.test_rest_request('/getutxos/{}-{}'.format(*spent))
    assert_equal(len(json_obj['utxos']), 1)
    json_obj = self.test_rest_request('/getutxos/checkmempool/{}-{}'.format(*spent))
    assert_equal(len(json_obj['utxos']), 0)
    self.nodes[0].generate(1)
    self.sync_all()
    json_obj = self.test_rest_request('/getutxos/{}-{}'.format(*spending))
    assert_equal(len(json_obj['utxos']), 1)
    json_obj = self.test_rest_request('/getutxos/checkmempool/{}-{}'.format(*spending))
    assert_equal(len(json_obj['utxos']), 1)
    self.test_rest_request('/getutxos', http_method='POST', req_type=ReqType.JSON, body='{"checkmempool', status=400, ret_type=RetType.OBJ)
    self.test_rest_request('/getutxos', http_method='POST', req_type=ReqType.BIN, body='{"checkmempool', status=400, ret_type=RetType.OBJ)
    self.test_rest_request('/getutxos/checkmempool', http_method='POST', req_type=ReqType.JSON, status=400, ret_type=RetType.OBJ)
    long_uri = '/'.join(['{}-{}'.format(txid, n_) for n_ in range(20)])
    self.test_rest_request('/getutxos/checkmempool/{}'.format(long_uri), http_method='POST', status=400, ret_type=RetType.OBJ)
    long_uri = '/'.join(['{}-{}'.format(txid, n_) for n_ in range(15)])
    self.test_rest_request('/getutxos/checkmempool/{}'.format(long_uri), http_method='POST', status=200)
    self.nodes[0].generate(1)
    self.sync_all()
    self.log.info('Test the /block, /blockhashbyheight and /headers URIs')
    bb_hash = self.nodes[0].getbestblockhash()
    assert_equal(self.test_rest_request('/headers/1/0000000000000000000000000000000000000000000000000000000000000000'), [])
    self.test_rest_request('/block/0000000000000000000000000000000000000000000000000000000000000000', status=404, ret_type=RetType.OBJ)
    self.nodes[0].invalidateblock(bb_hash)
    assert_equal(self.test_rest_request('/headers/1/{}'.format(bb_hash)), [])
    self.test_rest_request('/block/{}'.format(bb_hash))
    self.nodes[0].reconsiderblock(bb_hash)
    response = self.test_rest_request('/block/{}'.format(bb_hash), req_type=ReqType.BIN, ret_type=RetType.OBJ)
    assert_greater_than(int(response.getheader('content-length')), BLOCK_HEADER_SIZE)
    response_bytes = response.read()
    response_header = self.test_rest_request('/headers/1/{}'.format(bb_hash), req_type=ReqType.BIN, ret_type=RetType.OBJ)
    assert_equal(int(response_header.getheader('content-length')), 181)
    response_header_bytes = response_header.read()
    assert_equal(response_bytes[:181], response_header_bytes)
    response_hex = self.test_rest_request('/block/{}'.format(bb_hash), req_type=ReqType.HEX, ret_type=RetType.OBJ)
    assert_greater_than(int(response_hex.getheader('content-length')), (BLOCK_HEADER_SIZE * 2))
    response_hex_bytes = response_hex.read().strip(b'\n')
    assert_equal(binascii.hexlify(response_bytes), response_hex_bytes)
    response_header_hex = self.test_rest_request('/headers/1/{}'.format(bb_hash), req_type=ReqType.HEX, ret_type=RetType.OBJ)
    assert_greater_than(int(response_header_hex.getheader('content-length')), (BLOCK_HEADER_SIZE * 2))
    response_header_hex_bytes = response_header_hex.read((BLOCK_HEADER_SIZE * 2))
    assert_equal(binascii.hexlify(response_bytes[:BLOCK_HEADER_SIZE]), response_header_hex_bytes)
    block_json_obj = self.test_rest_request('/block/{}'.format(bb_hash))
    assert_equal(block_json_obj['hash'], bb_hash)
    assert_equal(self.test_rest_request('/blockhashbyheight/{}'.format(block_json_obj['height']))['blockhash'], bb_hash)
    resp_hex = self.test_rest_request('/blockhashbyheight/{}'.format(block_json_obj['height']), req_type=ReqType.HEX, ret_type=RetType.OBJ)
    assert_equal(resp_hex.read().decode('utf-8').rstrip(), bb_hash)
    resp_bytes = self.test_rest_request('/blockhashbyheight/{}'.format(block_json_obj['height']), req_type=ReqType.BIN, ret_type=RetType.BYTES)
    blockhash = resp_bytes[::(- 1)].hex()
    assert_equal(blockhash, bb_hash)
    resp = self.test_rest_request('/blockhashbyheight/abc', ret_type=RetType.OBJ, status=400)
    assert_equal(resp.read().decode('utf-8').rstrip(), 'Invalid height: abc')
    resp = self.test_rest_request('/blockhashbyheight/1000000', ret_type=RetType.OBJ, status=404)
    assert_equal(resp.read().decode('utf-8').rstrip(), 'Block height out of range')
    resp = self.test_rest_request('/blockhashbyheight/-1', ret_type=RetType.OBJ, status=400)
    assert_equal(resp.read().decode('utf-8').rstrip(), 'Invalid height: -1')
    self.test_rest_request('/blockhashbyheight/', ret_type=RetType.OBJ, status=400)
    json_obj = self.test_rest_request('/headers/1/{}'.format(bb_hash))
    assert_equal(len(json_obj), 1)
    assert_equal(json_obj[0]['hash'], bb_hash)
    rpc_block_json = self.nodes[0].getblock(bb_hash)
    for key in ['hash', 'confirmations', 'height', 'version', 'merkleroot', 'time', 'nonce', 'bits', 'difficulty', 'chainwork', 'previousblockhash']:
        assert_equal(json_obj[0][key], rpc_block_json[key])
    self.nodes[1].generate(5)
    self.sync_all()
    json_obj = self.test_rest_request('/headers/5/{}'.format(bb_hash))
    assert_equal(len(json_obj), 5)
    self.log.info('Test tx inclusion in the /mempool and /block URIs')
    txs = []
    txs.append(self.nodes[0].sendtoaddress(not_related_address, 11))
    txs.append(self.nodes[0].sendtoaddress(not_related_address, 11))
    txs.append(self.nodes[0].sendtoaddress(not_related_address, 11))
    self.sync_all()
    json_obj = self.test_rest_request('/mempool/info')
    assert_equal(json_obj['size'], 3)
    assert_greater_than(json_obj['bytes'], 300)
    json_obj = self.test_rest_request('/mempool/contents')
    for (i, tx) in enumerate(txs):
        assert (tx in json_obj)
        assert_equal(json_obj[tx]['spentby'], txs[(i + 1):(i + 2)])
        assert_equal(json_obj[tx]['depends'], txs[(i - 1):i])
    newblockhash = self.nodes[1].generate(1)
    self.sync_all()
    json_obj = self.test_rest_request('/block/{}'.format(newblockhash[0]))
    non_coinbase_txs = {tx['txid'] for tx in json_obj['tx'] if ('coinbase' not in tx['vin'][0])}
    assert_equal(non_coinbase_txs, set(txs))
    json_obj = self.test_rest_request('/block/notxdetails/{}'.format(newblockhash[0]))
    for tx in txs:
        assert (tx in json_obj['tx'])
    self.log.info('Test the /chaininfo URI')
    bb_hash = self.nodes[0].getbestblockhash()
    json_obj = self.test_rest_request('/chaininfo')
    assert_equal(json_obj['bestblockhash'], bb_hash)
def run_test(self):
    self.url = urllib.parse.urlparse(self.nodes[0].url)
    self.log.info('Mine blocks and send Bitcoin to node 1')
    not_related_address = convert_btc_address_to_qtum('2MxqoHEdNQTyYeX1mHcbrrpzgojbosTpCvJ')
    self.nodes[0].generate(1)
    self.sync_all()
    for i in range(0, COINBASE_MATURITY, 100):
        self.nodes[1].generatetoaddress(100, not_related_address)
    self.sync_all()
    assert_equal(self.nodes[0].getbalance(), INITIAL_BLOCK_REWARD)
    txid = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.1)
    self.sync_all()
    self.log.info('Test the /tx URI')
    json_obj = self.test_rest_request('/tx/{}'.format(txid))
    assert_equal(json_obj['txid'], txid)
    hex_response = self.test_rest_request('/tx/{}'.format(txid), req_type=ReqType.HEX, ret_type=RetType.OBJ)
    assert_greater_than_or_equal(int(hex_response.getheader('content-length')), (json_obj['size'] * 2))
    spent = (json_obj['vin'][0]['txid'], json_obj['vin'][0]['vout'])
    (n,) = filter_output_indices_by_value(json_obj['vout'], Decimal('0.1'))
    spending = (txid, n)
    self.log.info('Query an unspent TXO using the /getutxos URI')
    self.nodes[1].generatetoaddress(1, not_related_address)
    self.sync_all()
    bb_hash = self.nodes[0].getbestblockhash()
    assert_equal(self.nodes[1].getbalance(), Decimal('0.1'))
    json_obj = self.test_rest_request('/getutxos/{}-{}'.format(*spending))
    assert_equal(json_obj['chaintipHash'], bb_hash)
    assert_equal(len(json_obj['utxos']), 1)
    assert_equal(json_obj['utxos'][0]['value'], Decimal('0.1'))
    self.log.info('Query a spent TXO using the /getutxos URI')
    json_obj = self.test_rest_request('/getutxos/{}-{}'.format(*spent))
    assert_equal(json_obj['chaintipHash'], bb_hash)
    assert_equal(len(json_obj['utxos']), 0)
    assert_equal(json_obj['bitmap'], '0')
    self.log.info('Query two TXOs using the /getutxos URI')
    json_obj = self.test_rest_request('/getutxos/{}-{}/{}-{}'.format(*(spending + spent)))
    assert_equal(len(json_obj['utxos']), 1)
    assert_equal(json_obj['bitmap'], '10')
    self.log.info('Query the TXOs using the /getutxos URI with a binary response')
    bin_request = b'\x01\x02'
    for (txid, n) in [spending, spent]:
        bin_request += hex_str_to_bytes(txid)
        bin_request += pack('i', n)
    bin_response = self.test_rest_request('/getutxos', http_method='POST', req_type=ReqType.BIN, body=bin_request, ret_type=RetType.BYTES)
    output = BytesIO(bin_response)
    (chain_height,) = unpack('<i', output.read(4))
    response_hash = output.read(32)[::(- 1)].hex()
    assert_equal(bb_hash, response_hash)
    assert_equal(chain_height, (COINBASE_MATURITY + 2))
    self.log.info('Test the /getutxos URI with and without /checkmempool')
    txid = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.1)
    json_obj = self.test_rest_request('/tx/{}'.format(txid))
    spent = (json_obj['vin'][0]['txid'], json_obj['vin'][0]['vout'])
    (n,) = filter_output_indices_by_value(json_obj['vout'], Decimal('0.1'))
    spending = (txid, n)
    json_obj = self.test_rest_request('/getutxos/{}-{}'.format(*spending))
    assert_equal(len(json_obj['utxos']), 0)
    json_obj = self.test_rest_request('/getutxos/checkmempool/{}-{}'.format(*spending))
    assert_equal(len(json_obj['utxos']), 1)
    json_obj = self.test_rest_request('/getutxos/{}-{}'.format(*spent))
    assert_equal(len(json_obj['utxos']), 1)
    json_obj = self.test_rest_request('/getutxos/checkmempool/{}-{}'.format(*spent))
    assert_equal(len(json_obj['utxos']), 0)
    self.nodes[0].generate(1)
    self.sync_all()
    json_obj = self.test_rest_request('/getutxos/{}-{}'.format(*spending))
    assert_equal(len(json_obj['utxos']), 1)
    json_obj = self.test_rest_request('/getutxos/checkmempool/{}-{}'.format(*spending))
    assert_equal(len(json_obj['utxos']), 1)
    self.test_rest_request('/getutxos', http_method='POST', req_type=ReqType.JSON, body='{"checkmempool', status=400, ret_type=RetType.OBJ)
    self.test_rest_request('/getutxos', http_method='POST', req_type=ReqType.BIN, body='{"checkmempool', status=400, ret_type=RetType.OBJ)
    self.test_rest_request('/getutxos/checkmempool', http_method='POST', req_type=ReqType.JSON, status=400, ret_type=RetType.OBJ)
    long_uri = '/'.join(['{}-{}'.format(txid, n_) for n_ in range(20)])
    self.test_rest_request('/getutxos/checkmempool/{}'.format(long_uri), http_method='POST', status=400, ret_type=RetType.OBJ)
    long_uri = '/'.join(['{}-{}'.format(txid, n_) for n_ in range(15)])
    self.test_rest_request('/getutxos/checkmempool/{}'.format(long_uri), http_method='POST', status=200)
    self.nodes[0].generate(1)
    self.sync_all()
    self.log.info('Test the /block, /blockhashbyheight and /headers URIs')
    bb_hash = self.nodes[0].getbestblockhash()
    assert_equal(self.test_rest_request('/headers/1/0000000000000000000000000000000000000000000000000000000000000000'), [])
    self.test_rest_request('/block/0000000000000000000000000000000000000000000000000000000000000000', status=404, ret_type=RetType.OBJ)
    self.nodes[0].invalidateblock(bb_hash)
    assert_equal(self.test_rest_request('/headers/1/{}'.format(bb_hash)), [])
    self.test_rest_request('/block/{}'.format(bb_hash))
    self.nodes[0].reconsiderblock(bb_hash)
    response = self.test_rest_request('/block/{}'.format(bb_hash), req_type=ReqType.BIN, ret_type=RetType.OBJ)
    assert_greater_than(int(response.getheader('content-length')), BLOCK_HEADER_SIZE)
    response_bytes = response.read()
    response_header = self.test_rest_request('/headers/1/{}'.format(bb_hash), req_type=ReqType.BIN, ret_type=RetType.OBJ)
    assert_equal(int(response_header.getheader('content-length')), 181)
    response_header_bytes = response_header.read()
    assert_equal(response_bytes[:181], response_header_bytes)
    response_hex = self.test_rest_request('/block/{}'.format(bb_hash), req_type=ReqType.HEX, ret_type=RetType.OBJ)
    assert_greater_than(int(response_hex.getheader('content-length')), (BLOCK_HEADER_SIZE * 2))
    response_hex_bytes = response_hex.read().strip(b'\n')
    assert_equal(binascii.hexlify(response_bytes), response_hex_bytes)
    response_header_hex = self.test_rest_request('/headers/1/{}'.format(bb_hash), req_type=ReqType.HEX, ret_type=RetType.OBJ)
    assert_greater_than(int(response_header_hex.getheader('content-length')), (BLOCK_HEADER_SIZE * 2))
    response_header_hex_bytes = response_header_hex.read((BLOCK_HEADER_SIZE * 2))
    assert_equal(binascii.hexlify(response_bytes[:BLOCK_HEADER_SIZE]), response_header_hex_bytes)
    block_json_obj = self.test_rest_request('/block/{}'.format(bb_hash))
    assert_equal(block_json_obj['hash'], bb_hash)
    assert_equal(self.test_rest_request('/blockhashbyheight/{}'.format(block_json_obj['height']))['blockhash'], bb_hash)
    resp_hex = self.test_rest_request('/blockhashbyheight/{}'.format(block_json_obj['height']), req_type=ReqType.HEX, ret_type=RetType.OBJ)
    assert_equal(resp_hex.read().decode('utf-8').rstrip(), bb_hash)
    resp_bytes = self.test_rest_request('/blockhashbyheight/{}'.format(block_json_obj['height']), req_type=ReqType.BIN, ret_type=RetType.BYTES)
    blockhash = resp_bytes[::(- 1)].hex()
    assert_equal(blockhash, bb_hash)
    resp = self.test_rest_request('/blockhashbyheight/abc', ret_type=RetType.OBJ, status=400)
    assert_equal(resp.read().decode('utf-8').rstrip(), 'Invalid height: abc')
    resp = self.test_rest_request('/blockhashbyheight/1000000', ret_type=RetType.OBJ, status=404)
    assert_equal(resp.read().decode('utf-8').rstrip(), 'Block height out of range')
    resp = self.test_rest_request('/blockhashbyheight/-1', ret_type=RetType.OBJ, status=400)
    assert_equal(resp.read().decode('utf-8').rstrip(), 'Invalid height: -1')
    self.test_rest_request('/blockhashbyheight/', ret_type=RetType.OBJ, status=400)
    json_obj = self.test_rest_request('/headers/1/{}'.format(bb_hash))
    assert_equal(len(json_obj), 1)
    assert_equal(json_obj[0]['hash'], bb_hash)
    rpc_block_json = self.nodes[0].getblock(bb_hash)
    for key in ['hash', 'confirmations', 'height', 'version', 'merkleroot', 'time', 'nonce', 'bits', 'difficulty', 'chainwork', 'previousblockhash']:
        assert_equal(json_obj[0][key], rpc_block_json[key])
    self.nodes[1].generate(5)
    self.sync_all()
    json_obj = self.test_rest_request('/headers/5/{}'.format(bb_hash))
    assert_equal(len(json_obj), 5)
    self.log.info('Test tx inclusion in the /mempool and /block URIs')
    txs = []
    txs.append(self.nodes[0].sendtoaddress(not_related_address, 11))
    txs.append(self.nodes[0].sendtoaddress(not_related_address, 11))
    txs.append(self.nodes[0].sendtoaddress(not_related_address, 11))
    self.sync_all()
    json_obj = self.test_rest_request('/mempool/info')
    assert_equal(json_obj['size'], 3)
    assert_greater_than(json_obj['bytes'], 300)
    json_obj = self.test_rest_request('/mempool/contents')
    for (i, tx) in enumerate(txs):
        assert (tx in json_obj)
        assert_equal(json_obj[tx]['spentby'], txs[(i + 1):(i + 2)])
        assert_equal(json_obj[tx]['depends'], txs[(i - 1):i])
    newblockhash = self.nodes[1].generate(1)
    self.sync_all()
    json_obj = self.test_rest_request('/block/{}'.format(newblockhash[0]))
    non_coinbase_txs = {tx['txid'] for tx in json_obj['tx'] if ('coinbase' not in tx['vin'][0])}
    assert_equal(non_coinbase_txs, set(txs))
    json_obj = self.test_rest_request('/block/notxdetails/{}'.format(newblockhash[0]))
    for tx in txs:
        assert (tx in json_obj['tx'])
    self.log.info('Test the /chaininfo URI')
    bb_hash = self.nodes[0].getbestblockhash()
    json_obj = self.test_rest_request('/chaininfo')
    assert_equal(json_obj['bestblockhash'], bb_hash)