Ejemplo n.º 1
0
    def test_getpeer_list_vs_maxpeer_list(self):
        """https://github.com/CityOfZion/neo-python/issues/678"""
        settings.set_max_peers(1)
        api_server = JsonRpcApi(None, None)
        # test we start with a clean state
        peers = api_server.get_peers()
        self.assertEqual(len(peers['connected']), 0)

        # try connecting more nodes than allowed by the max peers settings
        first_node = self._add_new_node('127.0.0.1', 1111)
        second_node = self._add_new_node('127.0.0.2', 2222)
        peers = api_server.get_peers()
        # should respect max peer setting
        self.assertEqual(1, len(peers['connected']))
        self.assertEqual('127.0.0.1', peers['connected'][0]['address'])
        self.assertEqual(1111, peers['connected'][0]['port'])

        # now drop the existing node
        self.factory.clientConnectionLost(first_node, reason="unittest")
        # add a new one
        second_node = self._add_new_node('127.0.0.2', 2222)
        # and test if `first_node` we dropped can pass limit checks when it reconnects
        self.leader.PeerCheckLoop()
        peers = api_server.get_peers()
        self.assertEqual(1, len(peers['connected']))
        self.assertEqual('127.0.0.2', peers['connected'][0]['address'])
        self.assertEqual(2222, peers['connected'][0]['port'])

        # restore default settings
        settings.set_max_peers(5)
Ejemplo n.º 2
0
def main():
    parser = argparse.ArgumentParser()

    # Network options
    group_network_container = parser.add_argument_group(
        title="Network options")
    group_network = group_network_container.add_mutually_exclusive_group(
        required=True)
    group_network.add_argument("--mainnet",
                               action="store_true",
                               default=False,
                               help="Use MainNet")
    group_network.add_argument("--testnet",
                               action="store_true",
                               default=False,
                               help="Use TestNet")
    group_network.add_argument("--privnet",
                               action="store_true",
                               default=False,
                               help="Use PrivNet")
    group_network.add_argument("--coznet",
                               action="store_true",
                               default=False,
                               help="Use CozNet")
    group_network.add_argument("--config",
                               action="store",
                               help="Use a specific config file")

    # Ports for RPC and REST api
    group_modes = parser.add_argument_group(title="Mode(s)")
    group_modes.add_argument(
        "--port-rpc",
        type=int,
        help="port to use for the json-rpc api (eg. 10332)")
    group_modes.add_argument("--port-rest",
                             type=int,
                             help="port to use for the rest api (eg. 80)")

    # Advanced logging setup
    group_logging = parser.add_argument_group(title="Logging options")
    group_logging.add_argument("--logfile",
                               action="store",
                               type=str,
                               help="Logfile")
    group_logging.add_argument(
        "--syslog",
        action="store_true",
        help=
        "Log to syslog instead of to log file ('user' is the default facility)"
    )
    group_logging.add_argument(
        "--syslog-local",
        action="store",
        type=int,
        choices=range(0, 7),
        metavar="[0-7]",
        help=
        "Log to a local syslog facility instead of 'user'. Value must be between 0 and 7 (e.g. 0 for 'local0')."
    )
    group_logging.add_argument("--disable-stderr",
                               action="store_true",
                               help="Disable stderr logger")

    # Where to store stuff
    parser.add_argument("--datadir",
                        action="store",
                        help="Absolute path to use for database directories")
    # peers
    parser.add_argument("--maxpeers",
                        action="store",
                        default=5,
                        help="Max peers to use for P2P Joining")

    # host
    parser.add_argument("--host",
                        action="store",
                        type=str,
                        help="Hostname ( for example 127.0.0.1)",
                        default="0.0.0.0")

    # Now parse
    args = parser.parse_args()
    # print(args)

    if not args.port_rpc and not args.port_rest:
        print("Error: specify at least one of --port-rpc / --port-rest")
        parser.print_help()
        return

    if args.port_rpc == args.port_rest:
        print("Error: --port-rpc and --port-rest cannot be the same")
        parser.print_help()
        return

    if args.logfile and (args.syslog or args.syslog_local):
        print("Error: Cannot only use logfile or syslog at once")
        parser.print_help()
        return

    # Setting the datadir must come before setting the network, else the wrong path is checked at net setup.
    if args.datadir:
        settings.set_data_dir(args.datadir)

    # Network configuration depending on command line arguments. By default, the testnet settings are already loaded.
    if args.config:
        settings.setup(args.config)
    elif args.mainnet:
        settings.setup_mainnet()
    elif args.testnet:
        settings.setup_testnet()
    elif args.privnet:
        settings.setup_privnet()
    elif args.coznet:
        settings.setup_coznet()

    if args.maxpeers:
        settings.set_max_peers(args.maxpeers)

    if args.syslog or args.syslog_local is not None:
        # Setup the syslog facility
        if args.syslog_local is not None:
            print("Logging to syslog local%s facility" % args.syslog_local)
            syslog_facility = SysLogHandler.LOG_LOCAL0 + args.syslog_local
        else:
            print("Logging to syslog user facility")
            syslog_facility = SysLogHandler.LOG_USER

        # Setup logzero to only use the syslog handler
        logzero.syslog(facility=syslog_facility)
    else:
        # Setup file logging
        if args.logfile:
            logfile = os.path.abspath(args.logfile)
            if args.disable_stderr:
                print("Logging to logfile: %s" % logfile)
            else:
                print("Logging to stderr and logfile: %s" % logfile)
            logzero.logfile(logfile,
                            maxBytes=LOGFILE_MAX_BYTES,
                            backupCount=LOGFILE_BACKUP_COUNT,
                            disableStderrLogger=args.disable_stderr)

        else:
            print("Logging to stdout and stderr")

    # Disable logging smart contract events
    settings.set_log_smart_contract_events(False)

    # Write a PID file to easily quit the service
    write_pid_file()

    # Setup Twisted and Klein logging to use the logzero setup
    observer = STDLibLogObserver(name=logzero.LOGZERO_DEFAULT_LOGGER)
    globalLogPublisher.addObserver(observer)

    # Instantiate the blockchain and subscribe to notifications
    blockchain = LevelDBBlockchain(settings.chain_leveldb_path)
    Blockchain.RegisterBlockchain(blockchain)
    dbloop = task.LoopingCall(Blockchain.Default().PersistBlocks)
    dbloop.start(.1)

    # Setup twisted reactor, NodeLeader and start the NotificationDB
    reactor.suggestThreadPoolSize(15)
    NodeLeader.Instance().Start()
    NotificationDB.instance().start()

    # Start a thread with custom code
    d = threading.Thread(target=custom_background_code)
    d.setDaemon(
        True
    )  # daemonizing the thread will kill it when the main thread is quit
    d.start()

    if args.port_rpc:
        logger.info("Starting json-rpc api server on http://%s:%s" %
                    (args.host, args.port_rpc))
        api_server_rpc = JsonRpcApi(args.port_rpc)
        endpoint_rpc = "tcp:port={0}:interface={1}".format(
            args.port_rpc, args.host)
        endpoints.serverFromString(reactor, endpoint_rpc).listen(
            Site(api_server_rpc.app.resource()))
#        reactor.listenTCP(int(args.port_rpc), server.Site(api_server_rpc))
#        api_server_rpc.app.run(args.host, args.port_rpc)

    if args.port_rest:
        logger.info("Starting REST api server on http://%s:%s" %
                    (args.host, args.port_rest))
        api_server_rest = RestApi()
        endpoint_rest = "tcp:port={0}:interface={1}".format(
            args.port_rest, args.host)
        endpoints.serverFromString(reactor, endpoint_rest).listen(
            Site(api_server_rest.app.resource()))


#        api_server_rest.app.run(args.host, args.port_rest)

    reactor.run()

    # After the reactor is stopped, gracefully shutdown the database.
    logger.info("Closing databases...")
    NotificationDB.close()
    Blockchain.Default().Dispose()
    NodeLeader.Instance().Shutdown()
Ejemplo n.º 3
0
def main():
    parser = argparse.ArgumentParser()

    group = parser.add_mutually_exclusive_group(required=True)
    group.add_argument("-m", "--mainnet", action="store_true", default=False,
                       help="Use MainNet instead of the default TestNet")
    group.add_argument("-t", "--testnet", action="store_true", default=False,
                       help="Use TestNett instead of the default TestNet")
    group.add_argument("-p", "--privnet", action="store_true", default=False,
                       help="Use PrivNet instead of the default TestNet")
    group.add_argument("--coznet", action="store_true", default=False,
                       help="Use the CoZ network instead of the default TestNet")
    group.add_argument("-c", "--config", action="store", help="Use a specific config file")

    parser.add_argument("--port-rpc", type=int, help="port to use for the json-rpc api (eg. 10332)")
    parser.add_argument("--port-rest", type=int, help="port to use for the rest api (eg. 80)")

    args = parser.parse_args()

    if not args.port_rpc and not args.port_rest:
        print("Error: specify at least one of --port-rpc / --port-rest")
        parser.print_help()
        return

    if args.port_rpc == args.port_rest:
        print("Error: --port-rpc and --port-rest cannot be the same")
        parser.print_help()
        return

    # Setup depending on command line arguments. By default, the testnet settings are already loaded.
    if args.config:
        settings.setup(args.config)
    elif args.mainnet:
        settings.setup_mainnet()
    elif args.testnet:
        settings.setup_testnet()
    elif args.privnet:
        settings.setup_privnet()
    elif args.coznet:
        settings.setup_coznet()

    # Write a PID file to easily quit the service
    write_pid_file()

    # Instantiate the blockchain and subscribe to notifications
    blockchain = LevelDBBlockchain(settings.LEVELDB_PATH)
    Blockchain.RegisterBlockchain(blockchain)
    dbloop = task.LoopingCall(Blockchain.Default().PersistBlocks)
    dbloop.start(.1)

    # Disable logging smart contract events
    settings.set_log_smart_contract_events(False)

    # Start the notification db instance
    ndb = NotificationDB.instance()
    ndb.start()

    # Start a thread with custom code
    d = threading.Thread(target=custom_background_code)
    d.setDaemon(True)  # daemonizing the thread will kill it when the main thread is quit
    d.start()

    # Run
    reactor.suggestThreadPoolSize(15)
    NodeLeader.Instance().Start()

    host = "0.0.0.0"

    if args.port_rpc:
        logger.info("Starting json-rpc api server on http://%s:%s" % (host, args.port_rpc))
        api_server_rpc = JsonRpcApi(args.port_rpc)
        endpoint_rpc = "tcp:port={0}:interface={1}".format(args.port_rpc, host)
        endpoints.serverFromString(reactor, endpoint_rpc).listen(Site(api_server_rpc.app.resource()))

    if args.port_rest:
        logger.info("Starting notification api server on http://%s:%s" % (host, args.port_rest))
        api_server_rest = NotificationRestApi()
        endpoint_rest = "tcp:port={0}:interface={1}".format(args.port_rest, host)
        endpoints.serverFromString(reactor, endpoint_rest).listen(Site(api_server_rest.app.resource()))

    app = Klein()
    app.run(host, 9999)
Ejemplo n.º 4
0
 def setUp(self):
     self.app = JsonRpcApi(20332)
Ejemplo n.º 5
0
class JsonRpcInvokeApiTestCase(BlockchainFixtureTestCase):
    app = None  # type:JsonRpcApi

    @classmethod
    def leveldb_testpath(self):
        return './fixtures/test_chain'

    def setUp(self):
        self.app = JsonRpcApi(20332)

    def test_invalid_json_payload(self):
        mock_req = mock_request(b"{ invalid")
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res["error"]["code"], -32700)

        mock_req = mock_request(json.dumps({"some": "stuff"}).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res["error"]["code"], -32600)

    def _gen_rpc_req(self, method, params=None, request_id="2"):
        ret = {
            "jsonrpc": "2.0",
            "id": request_id,
            "method": method
        }
        if params:
            ret["params"] = params
        return ret

    def test_invoke_1(self):
        contract_hash = 'd7678dd97c000be3f33e9362e673101bac4ca654'
        jsn = [
            {
                'type': str(ContractParameterType.String),
                'value': 'name'
            },
            {
                'type': str(ContractParameterType.Array),
                'value': []
            }
        ]
        req = self._gen_rpc_req("invoke", params=[contract_hash, jsn])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result']['state'], VMState.HALT + VMState.BREAK)
        self.assertEqual(res['result']['gas_consumed'], '0.205')
        results = []
        for p in res['result']['stack']:
            results.append(ContractParameter.FromJson(p))
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].Type, ContractParameterType.ByteArray)
        self.assertEqual(results[0].Value, bytearray(b'LOCALTOKEN'))

    def test_invoke_2(self):
        contract_hash = 'd7678dd97c000be3f33e9362e673101bac4ca654'
        jsn = [
            {
                'type': str(ContractParameterType.String),
                'value': 'balanceOf'
            },
            {
                'type': str(ContractParameterType.Array),
                'value': [
                    {
                        'type': str(ContractParameterType.ByteArray),
                        'value': bytearray(b'\xec\xa8\xfc\xf9Nz*\x7f\xc3\xfdT\xae\x0e\xd3\xd3MR\xec%\x90').hex()
                    }
                ]
            }
        ]
        req = self._gen_rpc_req("invoke", params=[contract_hash, jsn])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result']['state'], VMState.HALT + VMState.BREAK)
        results = []
        for p in res['result']['stack']:
            results.append(ContractParameter.FromJson(p))
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].Type, ContractParameterType.ByteArray)
        self.assertEqual(results[0].Value, bytearray(b'\xe9\x0f\x80\xbb\x04\x90\x00'))

    def test_invoke_3(self):
        contract_hash = 'd7678dd97c000be3f33e9362e673101bac4ca654'
        req = self._gen_rpc_req("invokefunction", params=[contract_hash, 'symbol'])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result']['state'], VMState.HALT + VMState.BREAK)
        results = []
        for p in res['result']['stack']:
            results.append(ContractParameter.FromJson(p))
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].Type, ContractParameterType.ByteArray)
        self.assertEqual(results[0].Value, bytearray(b'LWTF'))

    def test_invoke_4(self):
        contract_hash = 'd7678dd97c000be3f33e9362e673101bac4ca654'
        params = [{'type': str(ContractParameterType.ByteArray),
                   'value': bytearray(b'\xec\xa8\xfc\xf9Nz*\x7f\xc3\xfdT\xae\x0e\xd3\xd3MR\xec%\x90').hex()}]

        req = self._gen_rpc_req("invokefunction", params=[contract_hash, 'balanceOf', params])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result']['state'], VMState.HALT + VMState.BREAK)
        results = []
        for p in res['result']['stack']:
            results.append(ContractParameter.FromJson(p))
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].Type, ContractParameterType.ByteArray)
        self.assertEqual(results[0].Value, bytearray(b'\xe9\x0f\x80\xbb\x04\x90\x00'))

    def test_invoke_5(self):
        test_script = '00046e616d656754a64cac1b1073e662933ef3e30b007cd98d67d7000673796d626f6c6754a64cac1b1073e662933ef3e30b007cd98d67d70008646563696d616c736754a64cac1b1073e662933ef3e30b007cd98d67d7'
        req = self._gen_rpc_req("invokescript", params=[test_script])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result']['state'], VMState.HALT + VMState.BREAK)

        results = []
        for p in res['result']['stack']:
            results.append(ContractParameter.FromJson(p))
        self.assertEqual(len(results), 3)
        self.assertEqual(results[0].Value, bytearray(b'LOCALTOKEN'))
        self.assertEqual(results[1].Value, bytearray(b'LWTF'))
        self.assertEqual(results[2].Value, 8)

    def test_bad_invoke_script(self):
        test_script = '0zzzzzzef3e30b007cd98d67d7'
        req = self._gen_rpc_req("invokescript", params=[test_script])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertTrue('error' in res)
        self.assertIn('Non-hexadecimal digit found', res['error']['message'])

    def test_bad_invoke_script_2(self):
        test_script = '00046e616d656754a64cac1b103e662933ef3e30b007cd98d67d7000673796d626f6c6754a64cac1b1073e662933ef3e30b007cd98d67d70008646563696d616c736754a64cac1b1073e662933ef3e30b007cd98d67d7'
        req = self._gen_rpc_req("invokescript", params=[test_script])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertTrue('error' in res)
        self.assertIn('Odd-length string', res['error']['message'])
Ejemplo n.º 6
0
class JsonRpcApiTestCase(BlockchainFixtureTestCase):
    app = None  # type:JsonRpcApi

    @classmethod
    def leveldb_testpath(self):
        return os.path.join(settings.DATA_DIR_PATH, 'fixtures/test_chain')

    def setUp(self):
        self.app = JsonRpcApi(20332)

    def test_invalid_json_payload(self):
        mock_req = mock_request(b"{ invalid")
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res["error"]["code"], -32700)

        mock_req = mock_request(json.dumps({"some": "stuff"}).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res["error"]["code"], -32600)

    def _gen_rpc_req(self, method, params=None, request_id="2"):
        ret = {"jsonrpc": "2.0", "id": request_id, "method": method}
        if params:
            ret["params"] = params
        return ret

    def test_initial_setup(self):
        self.assertTrue(
            GetBlockchain().GetBlock(0).Hash.To0xString(),
            '0x996e37358dc369912041f966f8c5d8d3a8255ba5dcbd3447f8a82b55db869099'
        )

    def test_missing_fields(self):
        req = self._gen_rpc_req("foo")
        del req["jsonrpc"]
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res["error"]["code"], -32600)

        req = self._gen_rpc_req("foo")
        del req["id"]
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res["error"]["code"], -32600)

        req = self._gen_rpc_req("foo")
        del req["method"]
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res["error"]["code"], -32600)

    def test_invalid_method(self):
        req = self._gen_rpc_req("invalid", request_id="42")
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res["id"], "42")
        self.assertEqual(res["error"]["code"], -32601)
        self.assertEqual(res["error"]["message"], "Method not found")

    def test_getblockcount(self):
        req = self._gen_rpc_req("getblockcount")
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(GetBlockchain().Height + 1, res["result"])

    def test_getblockhash(self):
        req = self._gen_rpc_req("getblockhash", params=[2])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))

        # taken from neoscan
        expected_blockhash = '0x049db9f55ac45201c128d1a40d0ef9d4bdc58db97d47d985ce8d66511a1ef9eb'
        self.assertEqual(expected_blockhash, res["result"])

    def test_getblockhash_failure(self):
        req = self._gen_rpc_req("getblockhash", params=[-1])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(-100, res["error"]["code"])
        self.assertEqual("Invalid Height", res["error"]["message"])

    def test_account_state(self):
        addr_str = 'AK2nJJpJr6o664CWJKi1QRXjqeic2zRp8y'
        req = self._gen_rpc_req("getaccountstate", params=[addr_str])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(
            res['result']['balances']
            ['0xc56f33fc6ecfcd0c225c4ab356fee59390af8560be0e930faebe74a6daff7c9b'],
            '99989900.0')
        self.assertEqual(res['result']['script_hash'], addr_str)

    def test_account_state_not_existing_yet(self):
        addr_str = 'AHozf8x8GmyLnNv8ikQcPKgRHQTbFi46u2'
        req = self._gen_rpc_req("getaccountstate", params=[addr_str])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result']['balances'], {})
        self.assertEqual(res['result']['script_hash'], addr_str)

    def test_account_state_failure(self):
        addr_str = 'AK2nJJpJr6o664CWJKi1QRXjqeic2zRp81'
        req = self._gen_rpc_req("getaccountstate", params=[addr_str])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertTrue('error' in res)
        self.assertEqual(-2146233033, res['error']['code'])
        self.assertEqual(
            'One of the identified items was in an invalid format.',
            res['error']['message'])

    def test_get_asset_state(self):
        asset_str = '602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7'
        req = self._gen_rpc_req("getassetstate", params=[asset_str])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result']['assetId'], '0x%s' % asset_str)
        self.assertEqual(res['result']['admin'],
                         'AWKECj9RD8rS8RPcpCgYVjk1DeYyHwxZm3')
        self.assertEqual(res['result']['available'], 0)

    def test_get_asset_state_0x(self):
        asset_str = '0x602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7'
        req = self._gen_rpc_req("getassetstate", params=[asset_str])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result']['assetId'], asset_str)

    def test_bad_asset_state(self):
        asset_str = '602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282dee'
        req = self._gen_rpc_req("getassetstate", params=[asset_str])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))

        self.assertTrue('error' in res)
        self.assertEqual(res['error']['message'], 'Unknown asset')

    def test_get_bestblockhash(self):
        req = self._gen_rpc_req("getbestblockhash", params=[])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(
            res['result'],
            '0x62539bdf30ff2567355efb38b1911cc07258710cfab5b50d3e32751618969bcb'
        )

    def test_get_connectioncount(self):
        # @TODO
        # Not sure if there's a great way to test this as it will always return 0 in tests
        req = self._gen_rpc_req("getconnectioncount", params=[])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result'], 0)

    def test_get_block_int(self):
        req = self._gen_rpc_req("getblock", params=[10, 1])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))

        self.assertEqual(res['result']['index'], 10)
        self.assertEqual(
            res['result']['hash'],
            '0xd69e7a1f62225a35fed91ca578f33447d93fa0fd2b2f662b957e19c38c1dab1e'
        )
        self.assertEqual(res['result']['confirmations'],
                         GetBlockchain().Height - 10 + 1)
        self.assertEqual(
            res['result']['nextblockhash'],
            '0x2b1c78633dae7ab81f64362e0828153079a17b018d779d0406491f84c27b086f'
        )

    def test_get_block_hash(self):
        req = self._gen_rpc_req(
            "getblock",
            params=[
                '2b1c78633dae7ab81f64362e0828153079a17b018d779d0406491f84c27b086f',
                1
            ])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))

        self.assertEqual(res['result']['index'], 11)
        self.assertEqual(res['result']['confirmations'],
                         GetBlockchain().Height - 11 + 1)
        self.assertEqual(
            res['result']['previousblockhash'],
            '0xd69e7a1f62225a35fed91ca578f33447d93fa0fd2b2f662b957e19c38c1dab1e'
        )

    def test_get_block_hash_0x(self):
        req = self._gen_rpc_req(
            "getblock",
            params=[
                '0x2b1c78633dae7ab81f64362e0828153079a17b018d779d0406491f84c27b086f',
                1
            ])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result']['index'], 11)

    def test_get_block_hash_failure(self):
        req = self._gen_rpc_req(
            "getblock",
            params=[
                'aad34f68cb7a04d625ae095fa509479ec7dcb4dc87ecd865ab059d0f8a42decf',
                1
            ])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertTrue('error' in res)
        self.assertEqual(res['error']['message'], 'Unknown block')

    def test_get_block_sysfee(self):
        req = self._gen_rpc_req("getblocksysfee", params=[9479])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result'], 1560)

        # test negative block
        req = self._gen_rpc_req("getblocksysfee", params=[-1])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertTrue('error' in res)
        self.assertEqual(res['error']['message'], 'Invalid Height')

        # test block exceeding max block height
        req = self._gen_rpc_req("getblocksysfee", params=[3000000000])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertTrue('error' in res)
        self.assertEqual(res['error']['message'], 'Invalid Height')

    def test_block_non_verbose(self):
        req = self._gen_rpc_req("getblock", params=[2003, 0])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertIsNotNone(res['result'])

        # we should be able to instantiate a matching block with the result
        output = binascii.unhexlify(res['result'])
        block = Helper.AsSerializableWithType(output, 'neo.Core.Block.Block')
        self.assertEqual(block.Index, 2003)
        self.assertEqual(len(block.Transactions), 1)

    def test_get_contract_state(self):
        contract_hash = "b9fbcff6e50fd381160b822207231233dd3c56c2"
        req = self._gen_rpc_req("getcontractstate", params=[contract_hash])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result']['code_version'], '')
        self.assertEqual(res['result']['properties']['storage'], True)
        self.assertEqual(res['result']['code']['hash'],
                         '0xb9fbcff6e50fd381160b822207231233dd3c56c2')
        self.assertEqual(res['result']['code']['returntype'], 5)
        self.assertEqual(res['result']['code']['parameters'], '0710')

    def test_get_contract_state_0x(self):
        contract_hash = "0xb9fbcff6e50fd381160b822207231233dd3c56c2"
        req = self._gen_rpc_req("getcontractstate", params=[contract_hash])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result']['code_version'], '')

    def test_get_contract_state_not_found(self):
        contract_hash = '0xb9fbcff6e50fd381160b822207231233dd3c56c1'
        req = self._gen_rpc_req("getcontractstate", params=[contract_hash])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertTrue('error' in res)
        self.assertEqual(res['error']['message'], 'Unknown contract')

    def test_get_raw_mempool(self):
        # TODO: currently returns empty list. test with list would be great
        req = self._gen_rpc_req("getrawmempool", params=[])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        mempool = res['result']

        # when running only these tests, mempool is empty. when running all tests, there are a
        # number of entries
        if len(mempool) > 0:
            for entry in mempool:
                self.assertEqual(entry[0:2], "0x")
                self.assertEqual(len(entry), 66)

    def test_get_version(self):
        # TODO: what's the nonce? on testnet live server response it's always 771199013
        req = self._gen_rpc_req("getversion", params=[])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res["result"]["port"], 20332)
        self.assertEqual(res["result"]["useragent"],
                         "/NEO-PYTHON:%s/" % __version__)

    def test_validate_address(self):
        # example from docs.neo.org
        req = self._gen_rpc_req("validateaddress",
                                params=["AQVh2pG732YvtNaxEGkQUei3YA4cvo7d2i"])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertTrue(res["result"]["isvalid"])

        # example from docs.neo.org
        req = self._gen_rpc_req("validateaddress",
                                params=["152f1muMCNa7goXYhYAQC61hxEgGacmncB"])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertFalse(res["result"]["isvalid"])

        # catch completely invalid argument
        req = self._gen_rpc_req("validateaddress", params=[])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertTrue('error' in res)
        self.assertEqual('Missing argument', res['error']['message'])

        # catch completely invalid argument
        req = self._gen_rpc_req("validateaddress", params=[""])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertTrue('error' in res)
        self.assertEqual('Missing argument', res['error']['message'])

    def test_getrawtx_1(self):
        txid = 'f999c36145a41306c846ea80290416143e8e856559818065be3f4e143c60e43a'
        req = self._gen_rpc_req("getrawtransaction", params=[txid, 1])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))['result']
        self.assertEqual(
            res['blockhash'],
            '0x6088bf9d3b55c67184f60b00d2e380228f713b4028b24c1719796dcd2006e417'
        )
        self.assertEqual(res['txid'], "0x%s" % txid)
        self.assertEqual(res['blocktime'], 1533756500)
        self.assertEqual(res['type'], 'ContractTransaction')

    def test_getrawtx_2(self):
        txid = 'f999c36145a41306c846ea80290416143e8e856559818065be3f4e143c60e43a'
        req = self._gen_rpc_req("getrawtransaction", params=[txid, 0])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))['result']
        expected = '8000012023ba2703c53263e8d6e522dc32203339dcd8eee901ff6a846c115ef1fb88664b00aa67f2c95e9405286db1b56c9120c27c698490530000029b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc50010a5d4e8000000affb37f5fdb9c6fec48d9f0eee85af82950f9b4a9b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc500f01b9b0986230023ba2703c53263e8d6e522dc32203339dcd8eee9014140a88bd1fcfba334b06da0ce1a679f80711895dade50352074e79e438e142dc95528d04a00c579398cb96c7301428669a09286ae790459e05e907c61ab8a1191c62321031a6c6fbbdf02ca351745fa86b9ba5a9452d785ac4f7fc2b7548ca2a46c4fcf4aac'
        self.assertEqual(res, expected)

    def test_getrawtx_3(self):
        txid = 'f999c36145a41306c846ea80290416143e8e856559818065be3f4e143c60e43b'
        req = self._gen_rpc_req("getrawtransaction", params=[txid, 0])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertTrue('error' in res)
        self.assertEqual(res['error']['message'], 'Unknown Transaction')

    def test_get_storage_item(self):
        contract_hash = 'b9fbcff6e50fd381160b822207231233dd3c56c2'
        storage_key = binascii.hexlify(b'in_circulation').decode('utf-8')
        req = self._gen_rpc_req("getstorage",
                                params=[contract_hash, storage_key])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result'], '00a031a95fe300')
        actual_val = int.from_bytes(
            binascii.unhexlify(res['result'].encode('utf-8')), 'little')
        self.assertEqual(actual_val, 250000000000000)

    def test_get_storage_item2(self):
        contract_hash = '90ea0b9b8716cf0ceca5b24f6256adf204f444d9'
        storage_key = binascii.hexlify(b'in_circulation').decode('utf-8')
        req = self._gen_rpc_req("getstorage",
                                params=[contract_hash, storage_key])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result'], '00c06e31d91001')

    def test_get_storage_item_key_not_found(self):
        contract_hash = 'b9fbcff6e50fd381160b822207231233dd3c56c1'
        storage_key = binascii.hexlify(b'blah').decode('utf-8')
        req = self._gen_rpc_req("getstorage",
                                params=[contract_hash, storage_key])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result'], None)

    def test_get_storage_item_contract_not_found(self):
        contract_hash = 'b9fbcff6e50fd381160b822207231233dd3c56c1'
        storage_key = binascii.hexlify(b'blah').decode('utf-8')
        req = self._gen_rpc_req("getstorage",
                                params=[contract_hash, storage_key])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result'], None)

    def test_get_storage_item_bad_contract_hash(self):
        contract_hash = 'b9fbcff6e50f01160b822207231233dd3c56c1'
        storage_key = binascii.hexlify(b'blah').decode('utf-8')
        req = self._gen_rpc_req("getstorage",
                                params=[contract_hash, storage_key])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertTrue('error' in res)
        self.assertIn('Invalid UInt', res['error']['message'])

    def test_get_unspents(self):
        u = UInt256.ParseString(
            'f999c36145a41306c846ea80290416143e8e856559818065be3f4e143c60e43a')
        unspents = GetBlockchain().GetAllUnspent(u)
        self.assertEqual(len(unspents), 1)

    def test_gettxout(self):
        txid = 'a2a37fd2ab7048d70d51eaa8af2815e0e542400329b05a34274771174180a7e8'
        output_index = 0
        req = self._gen_rpc_req("gettxout", params=[txid, output_index])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        # will return `null` if not found
        self.assertEqual(None, res["result"])

        # output with index 1 is unspent, so should return valid values
        # The txid need to be updated whenever we spend NEO from the address: AK2nJJpJr6o664CWJKi1QRXjqeic2zRp8y (coz wallet)
        txid = '42978cd563e9e95550fb51281d9071e27ec94bd42116836f0d0141d57a346b3e'
        output_index = 1
        req = self._gen_rpc_req("gettxout", params=[txid, output_index])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))

        expected_asset = '0xc56f33fc6ecfcd0c225c4ab356fee59390af8560be0e930faebe74a6daff7c9b'
        expected_value = "99989900"
        expected_address = 'AK2nJJpJr6o664CWJKi1QRXjqeic2zRp8y'

        self.assertEqual(output_index, res["result"]["n"])
        self.assertEqual(expected_address, res["result"]["address"])
        self.assertEqual(expected_asset, res["result"]["asset"])
        self.assertEqual(expected_value, res["result"]["value"])

        # now test a different index
        txid = 'f999c36145a41306c846ea80290416143e8e856559818065be3f4e143c60e43a'
        output_index = 0
        req = self._gen_rpc_req("gettxout", params=[txid, output_index])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))

        expected_value = "10000"
        self.assertEqual(output_index, res["result"]["n"])
        self.assertEqual(expected_value, res["result"]["value"])

    def test_send_raw_tx(self):
        raw_tx = '8000000001e72d286979ee6cb1b7e65dfddfb2e384100b8d148e7758de42e4168b71792c6000ca9a3b0000000048033b58ef547cbf54c8ee2f72a42d5b603c00af'
        req = self._gen_rpc_req("sendrawtransaction", params=[raw_tx])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result'], True)

    def test_send_raw_tx_bad(self):
        raw_tx = '80000001b10ad9ec660bf343c0eb411f9e05b4fa4ad8abed31d4e4dc5bb6ae416af0c4de000002e72d286979ee6cb1b7e65dfddfb2e384100b8d148e7758de42e4168b71792c60c8db571300000000af12a8687b14948bc4a008128a550a63695bc1a5e72d286979ee6cb1b7e65dfddfb2e384100b8d148e7758de42e4168b71792c603808b44002000000eca8fcf94e7a2a7fc3fd54ae0ed3d34d52ec25900141404749ce868ed9588f604eeeb5c523db39fd57cd7f61d04393a1754c2d32f131d67e6b1ec561ac05012b7298eb5ff254487c76de0b2a0c4d097d17cec708c0a9802321025b5c8cdcb32f8e278e111a0bf58ebb463988024bb4e250aa4310b40252030b60ac'
        req = self._gen_rpc_req("sendrawtransaction", params=[raw_tx])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result'], False)

    def test_send_raw_tx_bad_2(self):
        raw_tx = '80000001b10ad9ec660bf343c0eb411f9e05b4fa4ad8abed31d4e4dc5bb6ae416af0c4de000002e72d286979ee6cbb7e65dfddfb2e384100b8d148e7758de42e4168b71792c60c8db571300000000af12a8687b14948bc4a008128a550a63695bc1a5e72d286979ee6cb1b7e65dfddfb2e384100b8d148e7758de42e4168b71792c603808b44002000000eca8fcf94e7a2a7fc3fd54ae0ed3d34d52ec25900141404749ce868ed9588f604eeeb5c523db39fd57cd7f61d04393a1754c2d32f131d67e6b1ec561ac05012b7298eb5ff254487c76de0b2a0c4d097d17cec708c0a9802321025b5c8cdcb32f8e278e111a0bf58ebb463988024bb4e250aa4310b40252030b60ac'
        req = self._gen_rpc_req("sendrawtransaction", params=[raw_tx])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertTrue('error' in res)
        self.assertEqual(res['error']['code'], -32603)

    def test_gzip_compression(self):
        req = self._gen_rpc_req(
            "getblock",
            params=[
                '307ed2cf8b8935dd38c534b10dceac55fcd0f60c68bf409627f6c155f8143b31',
                1
            ])
        body = json.dumps(req).encode("utf-8")

        # first validate that we get a gzip response if we accept gzip encoding
        mock_req = requestMock(
            path=b'/',
            method="POST",
            body=body,
            headers={'Accept-Encoding': ['deflate', 'gzip;q=1.0', '*;q=0.5']})
        res = self.app.home(mock_req)

        GZIP_MAGIC = b'\x1f\x8b'
        self.assertIsInstance(res, bytes)
        self.assertTrue(res.startswith(GZIP_MAGIC))

        # then validate that we don't get a gzip response if we don't accept gzip encoding
        mock_req = requestMock(path=b'/', method="POST", body=body, headers={})
        res = self.app.home(mock_req)

        self.assertIsInstance(res, str)

        try:
            json.loads(res)
            valid_json = True
        except ValueError:
            valid_json = False
        self.assertTrue(valid_json)

    def test_getpeers(self):
        # Given this is an isolated environment and there is no peers
        # lets simulate that at least some addresses are known
        node = NodeLeader.Instance()
        node.ADDRS = ["127.0.0.1:20333", "127.0.0.2:20334"]
        test_node = NeoNode()
        test_node.host = "127.0.0.1"
        test_node.port = 20333
        node.Peers.append(test_node)

        req = self._gen_rpc_req("getpeers", params=[])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))

        self.assertEqual(len(node.Peers), len(res['result']['connected']))
        self.assertEqual(len(res['result']['unconnected']),
                         len(node.ADDRS) - len(node.Peers))
        # To avoid messing up the next tests
        node.Peers = []
        node.ADDRS = []

    def test_getwalletheight_no_wallet(self):
        req = self._gen_rpc_req("getwalletheight", params=["some id here"])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))

        error = res.get('error', {})

        self.assertEqual(error.get('code', None), -400)
        self.assertEqual(error.get('message', None), "Access denied.")

    def test_getwalletheight(self):
        self.app.wallet = UserWallet.Open(
            os.path.join(ROOT_INSTALL_PATH,
                         "neo/data/neo-privnet.sample.wallet"),
            to_aes_key("coz"))

        req = self._gen_rpc_req("getwalletheight", params=[])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))

        self.assertEqual(1, res.get('result'))

    def test_getbalance_no_wallet(self):
        req = self._gen_rpc_req("getbalance", params=["some id here"])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))

        error = res.get('error', {})

        self.assertEqual(error.get('code', None), -400)
        self.assertEqual(error.get('message', None), "Access denied.")

    def test_getbalance_neo_with_wallet(self):
        test_wallet_path = os.path.join(mkdtemp(), "getbalance.db3")
        self.app.wallet = UserWallet.Create(test_wallet_path,
                                            to_aes_key('awesomepassword'))

        neo_id = "c56f33fc6ecfcd0c225c4ab356fee59390af8560be0e930faebe74a6daff7c9b"
        req = self._gen_rpc_req("getbalance", params=[neo_id])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))

        self.assertIn('Balance', res.get('result').keys())
        self.assertIn('Confirmed', res.get('result').keys())

        self.app.wallet.Close()
        self.app.wallet = None
        os.remove(test_wallet_path)

    def test_getbalance_token_with_wallet(self):
        test_wallet_path = os.path.join(mkdtemp(), "getbalance.db3")
        self.app.wallet = UserWallet.Create(test_wallet_path,
                                            to_aes_key('awesomepassword'))

        fake_token_id = "fd941304d9cf36f31cd141c7c7029d81b1efa4f3"
        req = self._gen_rpc_req("getbalance", params=[fake_token_id])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))

        self.assertIn('Balance', res.get('result').keys())
        self.assertNotIn('Confirmed', res.get('result').keys())

        self.app.wallet.Close()
        self.app.wallet = None
        os.remove(test_wallet_path)

    def test_listaddress_no_wallet(self):
        req = self._gen_rpc_req("listaddress", params=[])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))

        error = res.get('error', {})

        self.assertEqual(error.get('code', None), -400)
        self.assertEqual(error.get('message', None), "Access denied.")

    def test_listaddress_with_wallet(self):
        test_wallet_path = os.path.join(mkdtemp(), "listaddress.db3")
        self.app.wallet = UserWallet.Create(test_wallet_path,
                                            to_aes_key('awesomepassword'))

        req = self._gen_rpc_req("listaddress", params=[])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        results = res.get('result', [])
        self.assertGreater(len(results), 0)
        self.assertIn(results[0].get('address', None),
                      self.app.wallet.Addresses)
        self.app.wallet.Close()
        self.app.wallet = None
        os.remove(test_wallet_path)

    def test_getnewaddress_no_wallet(self):
        req = self._gen_rpc_req("getnewaddress", params=[])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))

        error = res.get('error', {})

        self.assertEqual(error.get('code', None), -400)
        self.assertEqual(error.get('message', None), "Access denied.")

    def test_getnewaddress_with_wallet(self):
        test_wallet_path = os.path.join(mkdtemp(), "getnewaddress.db3")
        self.app.wallet = UserWallet.Create(test_wallet_path,
                                            to_aes_key('awesomepassword'))

        old_addrs = self.app.wallet.Addresses

        req = self._gen_rpc_req("getnewaddress", params=[])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        result = res.get('result')

        self.assertNotIn(result, old_addrs)
        self.assertIn(result, self.app.wallet.Addresses)

        self.app.wallet.Close()
        self.app.wallet = None
        os.remove(test_wallet_path)

    def test_valid_multirequest(self):
        raw_block_request = {
            "jsonrpc": "2.0",
            "method": "getblock",
            "params": [1],
            "id": 1
        }
        verbose_block_request = {
            "jsonrpc": "2.0",
            "method": "getblock",
            "params": [1, 1],
            "id": 2
        }

        multi_request = json.dumps([raw_block_request, verbose_block_request])
        mock_req = mock_request(multi_request.encode())
        res = json.loads(self.app.home(mock_req))

        self.assertEqual(type(res), list)
        self.assertEqual(len(res), 2)
        expected_raw_block = '00000000999086db552ba8f84734bddca55b25a8d3d8c5f866f941209169c38d35376e9902c78a8ae8efe7e9d46f76399a9d9449155e861d6849c110ea5f6b7d146a9a8aa4d1305b01000000bd7d9349807816a1be48d3a3f5d10013ab9ffee489706078714f1ea201c340dcbeadb300ff983f40f537ba6d63721cafda183b2cd161801ffb0f8316f100b63dbfbae665bba75fa1a954f14351f91cbf07bf90e60ff79f3e9076bcb1b512184075c25a44184ce92f7d7af1d2f22bee69374dd1bf0327f8956ede0dc23dda90106cf555fb8202fe6db9acda1d0b4fff8fdcd0404daa4b359c73017c7cdb80094640fb383c7016aae89a0a01b3c431a5625340378b95b57f4b71c4427ff1177a786b11b1c8060c075e3234afdd03790764ccd99680ea102890e359ab9050b5b32b2b8b532102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd622102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc22103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee69954ae010000bd7d934900000000'
        self.assertEqual(res[0]['result'], expected_raw_block)
        expected_verbose_hash = '0x55f745c9098d5d5bdaff9f8f32aad29c904c83d9832b48c16e677d30c7da4273'
        self.assertEqual(res[1]['result']['hash'], expected_verbose_hash)

    def test_multirequest_with_1_invalid_request(self):
        """
        We provide 2 requests, first one invalid and should return and error, second one  valid and should still come up with correct results
        """
        # block request of invalid block, should fail
        raw_block_request = {
            "jsonrpc": "2.0",
            "method": "getblock",
            "params": [10000000000],
            "id": 1
        }
        verbose_block_request = {
            "jsonrpc": "2.0",
            "method": "getblock",
            "params": [1, 1],
            "id": 2
        }

        multi_request = json.dumps([raw_block_request, verbose_block_request])
        mock_req = mock_request(multi_request.encode())
        res = json.loads(self.app.home(mock_req))

        self.assertEqual(type(res), list)
        self.assertEqual(len(res), 2)

        # test for errors in first invalid request
        error = res[0].get('error', {})
        self.assertEqual(error.get('code', None), -100)
        self.assertEqual(error.get('message', None), "Unknown block")

        # test for success in second valid request
        expected_verbose_hash = '0x55f745c9098d5d5bdaff9f8f32aad29c904c83d9832b48c16e677d30c7da4273'
        self.assertEqual(res[1]['result']['hash'], expected_verbose_hash)

    def test_send_to_address_no_wallet(self):
        req = self._gen_rpc_req("sendtoaddress", params=[])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))

        error = res.get('error', {})

        self.assertEqual(error.get('code', None), -400)
        self.assertEqual(error.get('message', None), "Access denied.")

    def test_send_to_address_wrong_arguments(self):
        test_wallet_path = os.path.join(mkdtemp(), "sendtoaddress.db3")
        self.app.wallet = UserWallet.Create(test_wallet_path,
                                            to_aes_key('awesomepassword'))

        req = self._gen_rpc_req("sendtoaddress", params=["arg"])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))

        error = res.get('error', {})

        self.assertEqual(error.get('code', None), -32602)
        self.assertEqual(error.get('message', None), "Invalid params")

        self.app.wallet.Close()
        self.app.wallet = None
        os.remove(test_wallet_path)

    def test_send_to_address_simple(self):
        test_wallet_path = shutil.copyfile(
            WalletFixtureTestCase.wallet_1_path(),
            WalletFixtureTestCase.wallet_1_dest())
        self.app.wallet = UserWallet.Open(
            test_wallet_path,
            to_aes_key(WalletFixtureTestCase.wallet_1_pass()))
        address = 'AXjaFSP23Jkbe6Pk9pPGT6NBDs1HVdqaXK'

        req = self._gen_rpc_req("sendtoaddress", params=['gas', address, 1])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))

        self.assertEqual(res.get('jsonrpc', None), '2.0')
        self.assertIn('txid', res.get('result', {}).keys())
        self.assertIn('vin', res.get('result', {}).keys())

        self.app.wallet.Close()
        self.app.wallet = None
        os.remove(WalletFixtureTestCase.wallet_1_dest())

    def test_send_to_address_with_fee(self):
        test_wallet_path = shutil.copyfile(
            WalletFixtureTestCase.wallet_1_path(),
            WalletFixtureTestCase.wallet_1_dest())
        self.app.wallet = UserWallet.Open(
            test_wallet_path,
            to_aes_key(WalletFixtureTestCase.wallet_1_pass()))
        address = 'AXjaFSP23Jkbe6Pk9pPGT6NBDs1HVdqaXK'

        req = self._gen_rpc_req("sendtoaddress",
                                params=['neo', address, 1, 0.005])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))

        self.assertEqual(res.get('jsonrpc', None), '2.0')
        self.assertIn('txid', res.get('result', {}).keys())
        self.assertEqual(res['result']['net_fee'], "0.005")

        self.app.wallet.Close()
        self.app.wallet = None
        os.remove(WalletFixtureTestCase.wallet_1_dest())

    def test_send_to_address_bad_assetid(self):
        test_wallet_path = shutil.copyfile(
            WalletFixtureTestCase.wallet_1_path(),
            WalletFixtureTestCase.wallet_1_dest())
        self.app.wallet = UserWallet.Open(
            test_wallet_path,
            to_aes_key(WalletFixtureTestCase.wallet_1_pass()))
        address = 'AXjaFSP23Jkbe6Pk9pPGT6NBDs1HVdqaXK'

        req = self._gen_rpc_req("sendtoaddress", params=['ga', address, 1])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))

        error = res.get('error', {})
        self.assertEqual(error.get('code', None), -32602)
        self.assertEqual(error.get('message', None), "Invalid params")

        self.app.wallet.Close()
        self.app.wallet = None
        os.remove(WalletFixtureTestCase.wallet_1_dest())

    def test_send_to_address_bad_address(self):
        test_wallet_path = shutil.copyfile(
            WalletFixtureTestCase.wallet_1_path(),
            WalletFixtureTestCase.wallet_1_dest())
        self.app.wallet = UserWallet.Open(
            test_wallet_path,
            to_aes_key(WalletFixtureTestCase.wallet_1_pass()))
        address = 'AXjaFSP23Jkbe6Pk9pPGT6NBDs1HVdqaX'

        req = self._gen_rpc_req("sendtoaddress", params=['gas', address, 1])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))

        error = res.get('error', {})
        self.assertEqual(error.get('code', None), -32602)
        self.assertEqual(error.get('message', None), "Invalid params")

        self.app.wallet.Close()
        self.app.wallet = None
        os.remove(WalletFixtureTestCase.wallet_1_dest())

    def test_send_to_address_negative_amount(self):
        test_wallet_path = shutil.copyfile(
            WalletFixtureTestCase.wallet_1_path(),
            WalletFixtureTestCase.wallet_1_dest())
        self.app.wallet = UserWallet.Open(
            test_wallet_path,
            to_aes_key(WalletFixtureTestCase.wallet_1_pass()))
        address = 'AXjaFSP23Jkbe6Pk9pPGT6NBDs1HVdqaXK'

        req = self._gen_rpc_req("sendtoaddress", params=['gas', address, -1])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))

        error = res.get('error', {})
        self.assertEqual(error.get('code', None), -32602)
        self.assertEqual(error.get('message', None), "Invalid params")

        self.app.wallet.Close()
        self.app.wallet = None
        os.remove(WalletFixtureTestCase.wallet_1_dest())

    def test_send_to_address_zero_amount(self):
        test_wallet_path = shutil.copyfile(
            WalletFixtureTestCase.wallet_1_path(),
            WalletFixtureTestCase.wallet_1_dest())
        self.app.wallet = UserWallet.Open(
            test_wallet_path,
            to_aes_key(WalletFixtureTestCase.wallet_1_pass()))
        address = 'AXjaFSP23Jkbe6Pk9pPGT6NBDs1HVdqaXK'

        req = self._gen_rpc_req("sendtoaddress", params=['gas', address, 0])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))

        error = res.get('error', {})
        self.assertEqual(error.get('code', None), -32602)
        self.assertEqual(error.get('message', None), "Invalid params")

        self.app.wallet.Close()
        self.app.wallet = None
        os.remove(WalletFixtureTestCase.wallet_1_dest())

    def test_send_to_address_negative_fee(self):
        test_wallet_path = shutil.copyfile(
            WalletFixtureTestCase.wallet_1_path(),
            WalletFixtureTestCase.wallet_1_dest())
        self.app.wallet = UserWallet.Open(
            test_wallet_path,
            to_aes_key(WalletFixtureTestCase.wallet_1_pass()))
        address = 'AXjaFSP23Jkbe6Pk9pPGT6NBDs1HVdqaXK'

        req = self._gen_rpc_req("sendtoaddress",
                                params=['gas', address, 1, -0.005])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))

        error = res.get('error', {})
        self.assertEqual(error.get('code', None), -32602)
        self.assertEqual(error.get('message', None), "Invalid params")

        self.app.wallet.Close()
        self.app.wallet = None
        os.remove(WalletFixtureTestCase.wallet_1_dest())

    def test_send_to_address_insufficient_funds(self):
        test_wallet_path = shutil.copyfile(
            WalletFixtureTestCase.wallet_1_path(),
            WalletFixtureTestCase.wallet_1_dest())
        self.app.wallet = UserWallet.Open(
            test_wallet_path,
            to_aes_key(WalletFixtureTestCase.wallet_1_pass()))
        address = 'AXjaFSP23Jkbe6Pk9pPGT6NBDs1HVdqaXK'

        req = self._gen_rpc_req("sendtoaddress", params=['gas', address, 51])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))

        error = res.get('error', {})
        self.assertEqual(error.get('code', None), -300)
        self.assertEqual(error.get('message', None), "Insufficient funds")

        self.app.wallet.Close()
        self.app.wallet = None
        os.remove(WalletFixtureTestCase.wallet_1_dest())

    def test_send_to_address_fails_to_sign_tx(self):
        with patch('neo.api.JSONRPC.JsonRpcApi.Wallet.Sign',
                   return_value='False'):
            test_wallet_path = shutil.copyfile(
                WalletFixtureTestCase.wallet_1_path(),
                WalletFixtureTestCase.wallet_1_dest())
            self.app.wallet = UserWallet.Open(
                test_wallet_path,
                to_aes_key(WalletFixtureTestCase.wallet_1_pass()))
            address = 'AXjaFSP23Jkbe6Pk9pPGT6NBDs1HVdqaXK'

            req = self._gen_rpc_req("sendtoaddress",
                                    params=['gas', address, 1])
            mock_req = mock_request(json.dumps(req).encode("utf-8"))
            res = json.loads(self.app.home(mock_req))

            self.assertEqual(res.get('jsonrpc', None), '2.0')
            self.assertIn('type', res.get('result', {}).keys())
            self.assertIn('hex', res.get('result', {}).keys())

            self.app.wallet.Close()
            self.app.wallet = None
            os.remove(WalletFixtureTestCase.wallet_1_dest())
 def __init__(self, *args, **kwargs):
     super(JsonRpcInvokeApiTestCase, self).__init__(*args, **kwargs)
     self.api_server = JsonRpcApi()
Ejemplo n.º 8
0
class JsonRpcApiTestCase(BlockchainFixtureTestCase):
    app = None  # type:JsonRpcApi

    @classmethod
    def leveldb_testpath(self):
        return os.path.join(settings.DATA_DIR_PATH, 'fixtures/test_chain')

    def setUp(self):
        self.app = JsonRpcApi(20332)

    def test_invalid_json_payload(self):
        mock_req = mock_request(b"{ invalid")
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res["error"]["code"], -32700)

        mock_req = mock_request(json.dumps({"some": "stuff"}).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res["error"]["code"], -32600)

    def _gen_rpc_req(self, method, params=None, request_id="2"):
        ret = {"jsonrpc": "2.0", "id": request_id, "method": method}
        if params:
            ret["params"] = params
        return ret

    def test_missing_fields(self):
        req = self._gen_rpc_req("foo")
        del req["jsonrpc"]
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res["error"]["code"], -32600)

        req = self._gen_rpc_req("foo")
        del req["id"]
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res["error"]["code"], -32600)

        req = self._gen_rpc_req("foo")
        del req["method"]
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res["error"]["code"], -32600)

    def test_invalid_method(self):
        req = self._gen_rpc_req("invalid", request_id="42")
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res["id"], "42")
        self.assertEqual(res["error"]["code"], -32601)
        self.assertEqual(res["error"]["message"], "Method not found")

    def test_getblockcount(self):
        req = self._gen_rpc_req("getblockcount")
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(758716, res["result"])

    def test_getblockhash(self):
        req = self._gen_rpc_req("getblockhash", params=[2])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))

        # taken from neoscan
        expected_blockhash = '0x60ad7aebdae37f1cad7a15b841363b5a7da9fd36bf689cfde75c26c0fa085b64'
        self.assertEqual(expected_blockhash, res["result"])

    def test_getblockhash_failure(self):
        req = self._gen_rpc_req("getblockhash", params=[-1])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(-100, res["error"]["code"])
        self.assertEqual("Invalid Height", res["error"]["message"])

    def test_account_state(self):
        addr_str = 'AXjaFSP23Jkbe6Pk9pPGT6NBDs1HVdqaXK'
        req = self._gen_rpc_req("getaccountstate", params=[addr_str])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(
            res['result']['balances']
            ['0xc56f33fc6ecfcd0c225c4ab356fee59390af8560be0e930faebe74a6daff7c9b'],
            '4061.0')
        self.assertEqual(res['result']['script_hash'], addr_str)

    def test_account_state_not_existing_yet(self):
        addr_str = 'AHozf8x8GmyLnNv8ikQcPKgRHQTbFi46u2'
        req = self._gen_rpc_req("getaccountstate", params=[addr_str])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result']['balances'], {})
        self.assertEqual(res['result']['script_hash'], addr_str)

    def test_account_state_failure(self):
        addr_str = 'Axozf8x8GmyLnNv8ikQcPKgRHQTbFi46u2'
        req = self._gen_rpc_req("getaccountstate", params=[addr_str])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertTrue('error' in res)
        self.assertEqual(-2146233033, res['error']['code'])
        self.assertEqual(
            'One of the identified items was in an invalid format.',
            res['error']['message'])

    def test_get_asset_state(self):
        asset_str = '602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7'
        req = self._gen_rpc_req("getassetstate", params=[asset_str])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result']['assetId'], '0x%s' % asset_str)
        self.assertEqual(res['result']['admin'],
                         'AWKECj9RD8rS8RPcpCgYVjk1DeYyHwxZm3')
        self.assertEqual(res['result']['available'], 3825482025899)

    def test_get_asset_state_0x(self):
        asset_str = '0x602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7'
        req = self._gen_rpc_req("getassetstate", params=[asset_str])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result']['assetId'], asset_str)

    def test_bad_asset_state(self):
        asset_str = '602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282dee'
        req = self._gen_rpc_req("getassetstate", params=[asset_str])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))

        self.assertTrue('error' in res)
        self.assertEqual(res['error']['message'], 'Unknown asset')

    def test_get_bestblockhash(self):
        req = self._gen_rpc_req("getbestblockhash", params=[])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(
            res['result'],
            '0x748de6a3bcb6f3dc70c72a625f8057f83e876a1168c373423f524dec78706d25'
        )

    def test_get_connectioncount(self):
        # @TODO
        # Not sure if there's a great way to test this as it will always return 0 in tests
        req = self._gen_rpc_req("getconnectioncount", params=[])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result'], 0)

    def test_get_block_int(self):
        req = self._gen_rpc_req("getblock", params=[10, 1])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result']['index'], 10)
        self.assertEqual(
            res['result']['hash'],
            '0x9410bd44beb7d6febc9278b028158af2781fcfb40cf2c6067b3525d24eff19f6'
        )
        self.assertEqual(res['result']['confirmations'], 758706)
        self.assertEqual(
            res['result']['nextblockhash'],
            '0xa0d34f68cb7a04d625ae095fa509479ec7dcb4dc87ecd865ab059d0f8a42decf'
        )

    def test_get_block_hash(self):
        req = self._gen_rpc_req(
            "getblock",
            params=[
                'a0d34f68cb7a04d625ae095fa509479ec7dcb4dc87ecd865ab059d0f8a42decf',
                1
            ])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))

        self.assertEqual(res['result']['index'], 11)
        self.assertEqual(res['result']['confirmations'], 758705)
        self.assertEqual(
            res['result']['previousblockhash'],
            '0x9410bd44beb7d6febc9278b028158af2781fcfb40cf2c6067b3525d24eff19f6'
        )

    def test_get_block_hash_0x(self):
        req = self._gen_rpc_req(
            "getblock",
            params=[
                '0xa0d34f68cb7a04d625ae095fa509479ec7dcb4dc87ecd865ab059d0f8a42decf',
                1
            ])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result']['index'], 11)

    def test_get_block_hash_failure(self):
        req = self._gen_rpc_req(
            "getblock",
            params=[
                'aad34f68cb7a04d625ae095fa509479ec7dcb4dc87ecd865ab059d0f8a42decf',
                1
            ])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertTrue('error' in res)
        self.assertEqual(res['error']['message'], 'Unknown block')

    def test_get_block_sysfee(self):
        req = self._gen_rpc_req("getblocksysfee", params=[13321])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result'], 230)

        # test negative block
        req = self._gen_rpc_req("getblocksysfee", params=[-1])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertTrue('error' in res)
        self.assertEqual(res['error']['message'], 'Invalid Height')

        # test block exceeding max block height
        req = self._gen_rpc_req("getblocksysfee", params=[3000000000])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertTrue('error' in res)
        self.assertEqual(res['error']['message'], 'Invalid Height')

    def test_block_non_verbose(self):
        req = self._gen_rpc_req("getblock", params=[2003, 0])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertIsNotNone(res['result'])

        # we should be able to instantiate a matching block with the result
        output = binascii.unhexlify(res['result'])
        block = Helper.AsSerializableWithType(output, 'neo.Core.Block.Block')
        self.assertEqual(block.Index, 2003)
        self.assertEqual(len(block.Transactions), 2)

    def test_get_contract_state(self):
        contract_hash = UInt160(data=bytearray(
            b'\x11\xc4\xd1\xf4\xfb\xa6\x19\xf2b\x88p\xd3n:\x97s\xe8tp[')
                                ).ToString()
        req = self._gen_rpc_req("getcontractstate", params=[contract_hash])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result']['code_version'], '3')
        self.assertEqual(res['result']['properties']['storage'], True)
        self.assertEqual(res['result']['code']['hash'],
                         '0x5b7074e873973a6ed3708862f219a6fbf4d1c411')
        self.assertEqual(res['result']['code']['returntype'], 5)
        self.assertEqual(res['result']['code']['parameters'], '0710')

    def test_get_contract_state_0x(self):
        contract_hash = '0x%s' % UInt160(data=bytearray(
            b'\x11\xc4\xd1\xf4\xfb\xa6\x19\xf2b\x88p\xd3n:\x97s\xe8tp[')
                                         ).ToString()
        req = self._gen_rpc_req("getcontractstate", params=[contract_hash])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result']['code_version'], '3')

    def test_get_contract_state_not_found(self):
        contract_hash = '0xf4e65b0e1ba449d8d0f3baae1690b455b0e6e75c'
        req = self._gen_rpc_req("getcontractstate", params=[contract_hash])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertTrue('error' in res)
        self.assertEqual(res['error']['message'], 'Unknown contract')

    def test_get_raw_mempool(self):
        # TODO: currently returns empty list. test with list would be great
        req = self._gen_rpc_req("getrawmempool", params=[])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        mempool = res['result']

        # when running only these tests, mempool is empty. when running all tests, there are a
        # number of entries
        if len(mempool) > 0:
            for entry in mempool:
                self.assertEqual(entry[0:2], "0x")
                self.assertEqual(len(entry), 66)

    def test_get_version(self):
        # TODO: what's the nonce? on testnet live server response it's always 771199013
        req = self._gen_rpc_req("getversion", params=[])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res["result"]["port"], 20332)
        self.assertEqual(res["result"]["useragent"],
                         "/NEO-PYTHON:%s/" % __version__)

    def test_validate_address(self):
        # example from docs.neo.org
        req = self._gen_rpc_req("validateaddress",
                                params=["AQVh2pG732YvtNaxEGkQUei3YA4cvo7d2i"])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertTrue(res["result"]["isvalid"])

        # example from docs.neo.org
        req = self._gen_rpc_req("validateaddress",
                                params=["152f1muMCNa7goXYhYAQC61hxEgGacmncB"])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertFalse(res["result"]["isvalid"])

        # catch completely invalid argument
        req = self._gen_rpc_req("validateaddress", params=[])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertTrue('error' in res)
        self.assertEqual('Missing argument', res['error']['message'])

        # catch completely invalid argument
        req = self._gen_rpc_req("validateaddress", params=[""])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertTrue('error' in res)
        self.assertEqual('Missing argument', res['error']['message'])

    def test_getrawtx_1(self):
        txid = 'cedb5c4e24b1f6fc5b239f2d1049c3229ad5ed05293c696b3740dc236c3f41b4'
        req = self._gen_rpc_req("getrawtransaction", params=[txid, 1])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))['result']
        self.assertEqual(
            res['blockhash'],
            '0x41720c35f5f15e5dc343d67fb54ab1e3825de47b476b5ae56cede2bf30657fde'
        )
        self.assertEqual(res['txid'], "0x%s" % txid)
        self.assertEqual(res['blocktime'], 1499393065)
        self.assertEqual(res['type'], 'ContractTransaction')

    def test_getrawtx_2(self):
        txid = 'cedb5c4e24b1f6fc5b239f2d1049c3229ad5ed05293c696b3740dc236c3f41b4'
        req = self._gen_rpc_req("getrawtransaction", params=[txid, 0])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))['result']
        expected = '800001f00431313131010206cc6f919695fb55c9605c55127128c29697d791af884c2636416c69a944880100029b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc500e1f50500000000e58e5999bcbf5d78f52ead40654131abb9ee27099b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc5009a04f516000000e53a27d37d7f5a3187003c21efe3725304a7410601414058b4a41beabdcf62381f7feea02767a714eb8ea49212fdb47a6f0bed2d0ae87d27377d9c2b4412ebf816042f2144e6e08939c7d83638b61208d3a7f5ea47c3ba232102ca81fa6c7ef20219c417d876c2743ea87728d416632d09c18004652aed09e000ac'
        self.assertEqual(res, expected)

    def test_getrawtx_3(self):
        txid = 'cedb5c4e24b1f6fc5b239f2d1049c3229ad5ed05293c696b3740dc236c3f41b3'
        req = self._gen_rpc_req("getrawtransaction", params=[txid, 0])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertTrue('error' in res)
        self.assertEqual(res['error']['message'], 'Unknown Transaction')

    def test_get_storage_item(self):
        contract_hash = '16f1559c3c27d66d087bef936804105457617c8a'
        storage_key = binascii.hexlify(b'totalSupply').decode('utf-8')
        req = self._gen_rpc_req("getstorage",
                                params=[contract_hash, storage_key])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result'], '001843d5ba05')
        actual_val = int.from_bytes(
            binascii.unhexlify(res['result'].encode('utf-8')), 'little')
        self.assertEqual(actual_val, 6300000000000)

    def test_get_storage_item2(self):
        contract_hash = '0xd7678dd97c000be3f33e9362e673101bac4ca654'
        storage_key = binascii.hexlify(b'totalSupply').decode('utf-8')
        req = self._gen_rpc_req("getstorage",
                                params=[contract_hash, storage_key])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result'], '0070723d14b200')

    def test_get_storage_item_key_not_found(self):
        contract_hash = '0xd7678dd97c000be3f33e9362e673101bac4ca654'
        storage_key = binascii.hexlify(b'blah').decode('utf-8')
        req = self._gen_rpc_req("getstorage",
                                params=[contract_hash, storage_key])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result'], None)

    def test_get_storage_item_contract_not_found(self):
        contract_hash = '0xd7678dd97c100be3f33e9362e673101bac4ca654'
        storage_key = binascii.hexlify(b'blah').decode('utf-8')
        req = self._gen_rpc_req("getstorage",
                                params=[contract_hash, storage_key])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result'], None)

    def test_get_storage_item_bad_contract_hash(self):
        contract_hash = '0xd7678dd97c000b3e9362e673101bac4ca654'
        storage_key = binascii.hexlify(b'blah').decode('utf-8')
        req = self._gen_rpc_req("getstorage",
                                params=[contract_hash, storage_key])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertTrue('error' in res)
        self.assertIn('Invalid UInt', res['error']['message'])

    def test_get_unspents(self):
        u = UInt256.ParseString(
            '0ff23561c611ccda65470c9a4a5f1be31f2f4f61b98c75d051e1a72e85a302eb')
        unspents = GetBlockchain().GetAllUnspent(u)
        self.assertEqual(len(unspents), 1)

    def test_gettxout(self):
        # block 730901 - 2 transactions
        # output with index 0 is spent, so should return an error

        txid = '0ff23561c611ccda65470c9a4a5f1be31f2f4f61b98c75d051e1a72e85a302eb'
        output_index = 0
        req = self._gen_rpc_req("gettxout", params=[txid, output_index])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        # will return `null` if not found
        self.assertEqual(None, res["result"])

        # output with index 1 is unspent, so should return valid values
        txid = '0ff23561c611ccda65470c9a4a5f1be31f2f4f61b98c75d051e1a72e85a302eb'
        output_index = 1
        req = self._gen_rpc_req("gettxout", params=[txid, output_index])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))

        expected_asset = '0x602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7'
        expected_value = "25"
        expected_address = 'AHYb3ySrHbhzouZ81ZMnCf8c7zYaoDg64x'

        self.assertEqual(output_index, res["result"]["n"])
        self.assertEqual(expected_address, res["result"]["address"])
        self.assertEqual(expected_asset, res["result"]["asset"])
        self.assertEqual(expected_value, res["result"]["value"])

        # now test for a different block (730848) with a floating value
        txid = '9c9f2c430c3cfb805e8c22d0a7778a60ce7792fad52ffe9b34f56de8e2c1d2e6'
        output_index = 1  # index 0 is spent, 0 is unspent
        req = self._gen_rpc_req("gettxout", params=[txid, output_index])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))

        expected_value = "2609.997813"
        self.assertEqual(output_index, res["result"]["n"])
        self.assertEqual(expected_value, res["result"]["value"])

    def test_send_raw_tx(self):
        raw_tx = '80000001b10ad9ec660bf343c0eb411f9e05b4fa4ad8abed31d4e4dc5bb6ae416af0c4de000002e72d286979ee6cb1b7e65dfddfb2e384100b8d148e7758de42e4168b71792c60c8db571300000000af12a8687b14948bc4a008128a550a63695bc1a5e72d286979ee6cb1b7e65dfddfb2e384100b8d148e7758de42e4168b71792c603808b44002000000eca8fcf94e7a2a7fc3fd54ae0ed3d34d52ec25900141404749ce868ed9588f604eeeb5c523db39fd57cd7f61d04393a1754c2d32f131d67e6b1ec561ac05012b7298eb5ff254487c76de0b2a0c4d097d17cec708c0a9802321025b5c8cdcb32f8e278e111a0bf58ebb463988024bb4e250aa4310b40252030b60ac'
        req = self._gen_rpc_req("sendrawtransaction", params=[raw_tx])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result'], True)

    def test_send_raw_tx_bad(self):
        raw_tx = '80000001b10ad9ec660bf343c0eb411f9e05b4fa4ad8abed31d4e4dc5bb6ae416af0c4de000002e72d286979ee6cb1b7e65dfddfb2e384100b8d148e7758de42e4168b71792c60c8db571300000000af12a8687b14948bc4a008128a550a63695bc1a5e72d286979ee6cb1b7e65dfddfb2e384100b8d148e7758de42e4168b71792c603808b44002000000eca8fcf94e7a2a7fc3fd54ae0ed3d34d52ec25900141404749ce868ed9588f604eeeb5c523db39fd57cd7f61d04393a1754c2d32f131d67e6b1ec561ac05012b7298eb5ff254487c76de0b2a0c4d097d17cec708c0a9802321025b5c8cdcb32f8e278e111a0bf58ebb463988024bb4e250aa4310b40252030b60ac'
        req = self._gen_rpc_req("sendrawtransaction", params=[raw_tx])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result'], False)

    def test_send_raw_tx_bad_2(self):
        raw_tx = '80000001b10ad9ec660bf343c0eb411f9e05b4fa4ad8abed31d4e4dc5bb6ae416af0c4de000002e72d286979ee6cbb7e65dfddfb2e384100b8d148e7758de42e4168b71792c60c8db571300000000af12a8687b14948bc4a008128a550a63695bc1a5e72d286979ee6cb1b7e65dfddfb2e384100b8d148e7758de42e4168b71792c603808b44002000000eca8fcf94e7a2a7fc3fd54ae0ed3d34d52ec25900141404749ce868ed9588f604eeeb5c523db39fd57cd7f61d04393a1754c2d32f131d67e6b1ec561ac05012b7298eb5ff254487c76de0b2a0c4d097d17cec708c0a9802321025b5c8cdcb32f8e278e111a0bf58ebb463988024bb4e250aa4310b40252030b60ac'
        req = self._gen_rpc_req("sendrawtransaction", params=[raw_tx])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertTrue('error' in res)
        self.assertEqual(res['error']['code'], -32603)

    def test_gzip_compression(self):
        req = self._gen_rpc_req(
            "getblock",
            params=[
                'a0d34f68cb7a04d625ae095fa509479ec7dcb4dc87ecd865ab059d0f8a42decf',
                1
            ])
        body = json.dumps(req).encode("utf-8")

        # first validate that we get a gzip response if we accept gzip encoding
        mock_req = requestMock(
            path=b'/',
            method="POST",
            body=body,
            headers={'Accept-Encoding': ['deflate', 'gzip;q=1.0', '*;q=0.5']})
        res = self.app.home(mock_req)

        GZIP_MAGIC = b'\x1f\x8b'
        self.assertIsInstance(res, bytes)
        self.assertTrue(res.startswith(GZIP_MAGIC))

        # then validate that we don't get a gzip response if we don't accept gzip encoding
        mock_req = requestMock(path=b'/', method="POST", body=body, headers={})
        res = self.app.home(mock_req)

        self.assertIsInstance(res, str)

        try:
            json.loads(res)
            valid_json = True
        except ValueError:
            valid_json = False
        self.assertTrue(valid_json)
Ejemplo n.º 9
0
def main():
    parser = argparse.ArgumentParser()

    group = parser.add_mutually_exclusive_group(required=True)
    group.add_argument("-m",
                       "--mainnet",
                       action="store_true",
                       default=False,
                       help="Use MainNet instead of the default TestNet")
    group.add_argument("-t",
                       "--testnet",
                       action="store_true",
                       default=False,
                       help="Use TestNet instead of the default TestNet")
    group.add_argument("-p",
                       "--privnet",
                       action="store_true",
                       default=False,
                       help="Use PrivNet instead of the default TestNet")
    group.add_argument(
        "--coznet",
        action="store_true",
        default=False,
        help="Use the CoZ network instead of the default TestNet")
    group.add_argument("-c",
                       "--config",
                       action="store",
                       help="Use a specific config file")

    parser.add_argument("--port-rpc",
                        type=int,
                        help="port to use for the json-rpc api (eg. 10332)")
    parser.add_argument("--port-rest",
                        type=int,
                        help="port to use for the rest api (eg. 80)")

    args = parser.parse_args()

    if not args.port_rpc and not args.port_rest:
        print("Error: specify at least one of --port-rpc / --port-rest")
        parser.print_help()
        return

    if args.port_rpc == args.port_rest:
        print("Error: --port-rpc and --port-rest cannot be the same")
        parser.print_help()
        return

    # Setup depending on command line arguments. By default, the testnet settings are already loaded.
    if args.config:
        settings.setup(args.config)
    elif args.mainnet:
        settings.setup_mainnet()
    elif args.testnet:
        settings.setup_testnet()
    elif args.privnet:
        settings.setup_privnet()
    elif args.coznet:
        settings.setup_coznet()

    # Write a PID file to easily quit the service
    write_pid_file()

    # Setup the blockchain
    blockchain = LevelDBBlockchain(settings.LEVELDB_PATH)
    Blockchain.RegisterBlockchain(blockchain)
    dbloop = task.LoopingCall(Blockchain.Default().PersistBlocks)
    dbloop.start(.1)

    NodeLeader.Instance().Start()

    # Disable smart contract events for external smart contracts
    settings.set_log_smart_contract_events(False)

    # Open a wallet otherwise exit.
    try:
        bcontract.start_db_loop()
    except Exception as e:
        logger.error(
            "Error starting the custom neo node. wallet file and correct password are necessary %s"
            % e)
        exit(1)

    #
    # Start a thread with custom code
    #
    d = threading.Thread(target=custom_background_code)
    d.setDaemon(
        True
    )  # daemonizing the thread will kill it when the main thread is quit
    d.start()

    host = "0.0.0.0"

    if args.port_rpc:
        logger.info("Starting json-rpc api server on http://%s:%s" %
                    (host, args.port_rpc))
        api_server_rpc = JsonRpcApi(args.port_rpc)
        endpoint_rpc = "tcp:port={0}:interface={1}".format(args.port_rpc, host)
        endpoints.serverFromString(reactor, endpoint_rpc).listen(
            Site(api_server_rpc.app.resource()))

    if args.port_rest:
        logger.info("Starting smartcontract api server on http://%s:%s" %
                    (host, args.port_rest))
        endpoint_description = "tcp:port={0}:interface={1}".format(
            args.port_rest, host)
        endpoint = endpoints.serverFromString(reactor, endpoint_description)
        endpoint.listen(Site(app.resource()))

    # app.run(host, 9999)
    # Run all the things (blocking call)
    logger.info("Everything is setup and running. Waiting for events...")
    reactor.run()
    logger.info("Shutting down.")
Ejemplo n.º 10
0
class JsonRpcApiTestCase(BlockchainFixtureTestCase):
    app = None  # type:JsonRpcApi

    @classmethod
    def leveldb_testpath(self):
        return os.path.join(settings.DATA_DIR_PATH, 'fixtures/test_chain')

    def setUp(self):
        self.app = JsonRpcApi(20332)

    def test_invalid_json_payload(self):
        mock_req = mock_request(b"{ invalid")
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res["error"]["code"], -32700)

        mock_req = mock_request(json.dumps({"some": "stuff"}).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res["error"]["code"], -32600)

    def _gen_rpc_req(self, method, params=None, request_id="2"):
        ret = {
            "jsonrpc": "2.0",
            "id": request_id,
            "method": method
        }
        if params:
            ret["params"] = params
        return ret

    def test_missing_fields(self):
        req = self._gen_rpc_req("foo")
        del req["jsonrpc"]
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res["error"]["code"], -32600)

        req = self._gen_rpc_req("foo")
        del req["id"]
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res["error"]["code"], -32600)

        req = self._gen_rpc_req("foo")
        del req["method"]
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res["error"]["code"], -32600)

    def test_invalid_method(self):
        req = self._gen_rpc_req("invalid", request_id="42")
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res["id"], "42")
        self.assertEqual(res["error"]["code"], -32601)
        self.assertEqual(res["error"]["message"], "Method not found")

    def test_getblockcount(self):
        req = self._gen_rpc_req("getblockcount")
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(758987, res["result"])

    def test_getblockhash(self):
        req = self._gen_rpc_req("getblockhash", params=[2])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))

        # taken from neoscan
        expected_blockhash = '0x60ad7aebdae37f1cad7a15b841363b5a7da9fd36bf689cfde75c26c0fa085b64'
        self.assertEqual(expected_blockhash, res["result"])

    def test_getblockhash_failure(self):
        req = self._gen_rpc_req("getblockhash", params=[-1])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(-100, res["error"]["code"])
        self.assertEqual("Invalid Height", res["error"]["message"])

    def test_account_state(self):
        addr_str = 'AXjaFSP23Jkbe6Pk9pPGT6NBDs1HVdqaXK'
        req = self._gen_rpc_req("getaccountstate", params=[addr_str])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result']['balances']['0xc56f33fc6ecfcd0c225c4ab356fee59390af8560be0e930faebe74a6daff7c9b'], '4061.0')
        self.assertEqual(res['result']['script_hash'], addr_str)

    def test_account_state_not_existing_yet(self):
        addr_str = 'AHozf8x8GmyLnNv8ikQcPKgRHQTbFi46u2'
        req = self._gen_rpc_req("getaccountstate", params=[addr_str])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result']['balances'], {})
        self.assertEqual(res['result']['script_hash'], addr_str)

    def test_account_state_failure(self):
        addr_str = 'Axozf8x8GmyLnNv8ikQcPKgRHQTbFi46u2'
        req = self._gen_rpc_req("getaccountstate", params=[addr_str])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertTrue('error' in res)
        self.assertEqual(-2146233033, res['error']['code'])
        self.assertEqual('One of the identified items was in an invalid format.', res['error']['message'])

    def test_get_asset_state(self):
        asset_str = '602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7'
        req = self._gen_rpc_req("getassetstate", params=[asset_str])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result']['assetId'], '0x%s' % asset_str)
        self.assertEqual(res['result']['admin'], 'AWKECj9RD8rS8RPcpCgYVjk1DeYyHwxZm3')
        self.assertEqual(res['result']['available'], 3825482025899)

    def test_get_asset_state_0x(self):
        asset_str = '0x602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7'
        req = self._gen_rpc_req("getassetstate", params=[asset_str])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result']['assetId'], asset_str)

    def test_bad_asset_state(self):
        asset_str = '602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282dee'
        req = self._gen_rpc_req("getassetstate", params=[asset_str])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))

        self.assertTrue('error' in res)
        self.assertEqual(res['error']['message'], 'Unknown asset')

    def test_get_bestblockhash(self):
        req = self._gen_rpc_req("getbestblockhash", params=[])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result'], '0x6e9d1698ba2cd43432b6df1fca4bfbc53b2492a29401d1411699ddbd56cf8559')

    def test_get_connectioncount(self):
        # @TODO
        # Not sure if there's a great way to test this as it will always return 0 in tests
        req = self._gen_rpc_req("getconnectioncount", params=[])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result'], 0)

    def test_get_block_int(self):
        req = self._gen_rpc_req("getblock", params=[10, 1])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result']['index'], 10)
        self.assertEqual(res['result']['hash'], '0x9410bd44beb7d6febc9278b028158af2781fcfb40cf2c6067b3525d24eff19f6')
        self.assertEqual(res['result']['confirmations'], 758977)
        self.assertEqual(res['result']['nextblockhash'], '0xa0d34f68cb7a04d625ae095fa509479ec7dcb4dc87ecd865ab059d0f8a42decf')

    def test_get_block_hash(self):
        req = self._gen_rpc_req("getblock", params=['a0d34f68cb7a04d625ae095fa509479ec7dcb4dc87ecd865ab059d0f8a42decf', 1])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))

        self.assertEqual(res['result']['index'], 11)
        self.assertEqual(res['result']['confirmations'], 758976)
        self.assertEqual(res['result']['previousblockhash'], '0x9410bd44beb7d6febc9278b028158af2781fcfb40cf2c6067b3525d24eff19f6')

    def test_get_block_hash_0x(self):
        req = self._gen_rpc_req("getblock", params=['0xa0d34f68cb7a04d625ae095fa509479ec7dcb4dc87ecd865ab059d0f8a42decf', 1])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result']['index'], 11)

    def test_get_block_hash_failure(self):
        req = self._gen_rpc_req("getblock", params=['aad34f68cb7a04d625ae095fa509479ec7dcb4dc87ecd865ab059d0f8a42decf', 1])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertTrue('error' in res)
        self.assertEqual(res['error']['message'], 'Unknown block')

    def test_get_block_sysfee(self):
        req = self._gen_rpc_req("getblocksysfee", params=[13321])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result'], 230)

        # test negative block
        req = self._gen_rpc_req("getblocksysfee", params=[-1])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertTrue('error' in res)
        self.assertEqual(res['error']['message'], 'Invalid Height')

        # test block exceeding max block height
        req = self._gen_rpc_req("getblocksysfee", params=[3000000000])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertTrue('error' in res)
        self.assertEqual(res['error']['message'], 'Invalid Height')

    def test_block_non_verbose(self):
        req = self._gen_rpc_req("getblock", params=[2003, 0])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertIsNotNone(res['result'])

        # we should be able to instantiate a matching block with the result
        output = binascii.unhexlify(res['result'])
        block = Helper.AsSerializableWithType(output, 'neo.Core.Block.Block')
        self.assertEqual(block.Index, 2003)
        self.assertEqual(len(block.Transactions), 2)

    def test_get_contract_state(self):
        contract_hash = UInt160(data=bytearray(b'\x11\xc4\xd1\xf4\xfb\xa6\x19\xf2b\x88p\xd3n:\x97s\xe8tp[')).ToString()
        req = self._gen_rpc_req("getcontractstate", params=[contract_hash])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result']['code_version'], '3')
        self.assertEqual(res['result']['properties']['storage'], True)
        self.assertEqual(res['result']['code']['hash'], '0x5b7074e873973a6ed3708862f219a6fbf4d1c411')
        self.assertEqual(res['result']['code']['returntype'], 5)
        self.assertEqual(res['result']['code']['parameters'], '0710')

    def test_get_contract_state_0x(self):
        contract_hash = '0x%s' % UInt160(data=bytearray(b'\x11\xc4\xd1\xf4\xfb\xa6\x19\xf2b\x88p\xd3n:\x97s\xe8tp[')).ToString()
        req = self._gen_rpc_req("getcontractstate", params=[contract_hash])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result']['code_version'], '3')

    def test_get_contract_state_not_found(self):
        contract_hash = '0xf4e65b0e1ba449d8d0f3baae1690b455b0e6e75c'
        req = self._gen_rpc_req("getcontractstate", params=[contract_hash])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertTrue('error' in res)
        self.assertEqual(res['error']['message'], 'Unknown contract')

    def test_get_raw_mempool(self):
        # TODO: currently returns empty list. test with list would be great
        req = self._gen_rpc_req("getrawmempool", params=[])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        mempool = res['result']

        # when running only these tests, mempool is empty. when running all tests, there are a
        # number of entries
        if len(mempool) > 0:
            for entry in mempool:
                self.assertEqual(entry[0:2], "0x")
                self.assertEqual(len(entry), 66)

    def test_get_version(self):
        # TODO: what's the nonce? on testnet live server response it's always 771199013
        req = self._gen_rpc_req("getversion", params=[])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res["result"]["port"], 20332)
        self.assertEqual(res["result"]["useragent"], "/NEO-PYTHON:%s/" % __version__)

    def test_validate_address(self):
        # example from docs.neo.org
        req = self._gen_rpc_req("validateaddress", params=["AQVh2pG732YvtNaxEGkQUei3YA4cvo7d2i"])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertTrue(res["result"]["isvalid"])

        # address with invalid checksum
        req = self._gen_rpc_req("validateaddress", params=["AQVh2pG732YvtNaxEGkQUei3YA4cvo7d2x"])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertFalse(res["result"]["isvalid"])

        # example from docs.neo.org
        req = self._gen_rpc_req("validateaddress", params=["152f1muMCNa7goXYhYAQC61hxEgGacmncB"])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertFalse(res["result"]["isvalid"])

        # catch completely invalid argument
        req = self._gen_rpc_req("validateaddress", params=[])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertTrue('error' in res)
        self.assertEqual('Missing argument', res['error']['message'])

        # catch completely invalid argument
        req = self._gen_rpc_req("validateaddress", params=[""])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertTrue('error' in res)
        self.assertEqual('Missing argument', res['error']['message'])

    def test_getrawtx_1(self):
        txid = 'cedb5c4e24b1f6fc5b239f2d1049c3229ad5ed05293c696b3740dc236c3f41b4'
        req = self._gen_rpc_req("getrawtransaction", params=[txid, 1])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))['result']
        self.assertEqual(res['blockhash'], '0x41720c35f5f15e5dc343d67fb54ab1e3825de47b476b5ae56cede2bf30657fde')
        self.assertEqual(res['txid'], "0x%s" % txid)
        self.assertEqual(res['blocktime'], 1499393065)
        self.assertEqual(res['type'], 'ContractTransaction')

    def test_getrawtx_2(self):
        txid = 'cedb5c4e24b1f6fc5b239f2d1049c3229ad5ed05293c696b3740dc236c3f41b4'
        req = self._gen_rpc_req("getrawtransaction", params=[txid, 0])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))['result']
        expected = '800001f00431313131010206cc6f919695fb55c9605c55127128c29697d791af884c2636416c69a944880100029b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc500e1f50500000000e58e5999bcbf5d78f52ead40654131abb9ee27099b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc5009a04f516000000e53a27d37d7f5a3187003c21efe3725304a7410601414058b4a41beabdcf62381f7feea02767a714eb8ea49212fdb47a6f0bed2d0ae87d27377d9c2b4412ebf816042f2144e6e08939c7d83638b61208d3a7f5ea47c3ba232102ca81fa6c7ef20219c417d876c2743ea87728d416632d09c18004652aed09e000ac'
        self.assertEqual(res, expected)

    def test_getrawtx_3(self):
        txid = 'cedb5c4e24b1f6fc5b239f2d1049c3229ad5ed05293c696b3740dc236c3f41b3'
        req = self._gen_rpc_req("getrawtransaction", params=[txid, 0])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertTrue('error' in res)
        self.assertEqual(res['error']['message'], 'Unknown Transaction')

    def test_get_storage_item(self):
        contract_hash = '16f1559c3c27d66d087bef936804105457617c8a'
        storage_key = binascii.hexlify(b'totalSupply').decode('utf-8')
        req = self._gen_rpc_req("getstorage", params=[contract_hash, storage_key])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result'], '00f938dbba05')
        actual_val = int.from_bytes(binascii.unhexlify(res['result'].encode('utf-8')), 'little')
        self.assertEqual(actual_val, 6300100000000)

    def test_get_storage_item2(self):
        contract_hash = '0xd7678dd97c000be3f33e9362e673101bac4ca654'
        storage_key = binascii.hexlify(b'totalSupply').decode('utf-8')
        req = self._gen_rpc_req("getstorage", params=[contract_hash, storage_key])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result'], '003a0d7914b200')

    def test_get_storage_item_key_not_found(self):
        contract_hash = '0xd7678dd97c000be3f33e9362e673101bac4ca654'
        storage_key = binascii.hexlify(b'blah').decode('utf-8')
        req = self._gen_rpc_req("getstorage", params=[contract_hash, storage_key])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result'], None)

    def test_get_storage_item_contract_not_found(self):
        contract_hash = '0xd7678dd97c100be3f33e9362e673101bac4ca654'
        storage_key = binascii.hexlify(b'blah').decode('utf-8')
        req = self._gen_rpc_req("getstorage", params=[contract_hash, storage_key])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result'], None)

    def test_get_storage_item_bad_contract_hash(self):
        contract_hash = '0xd7678dd97c000b3e9362e673101bac4ca654'
        storage_key = binascii.hexlify(b'blah').decode('utf-8')
        req = self._gen_rpc_req("getstorage", params=[contract_hash, storage_key])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertTrue('error' in res)
        self.assertIn('Invalid UInt', res['error']['message'])

    def test_get_unspents(self):
        u = UInt256.ParseString('0ff23561c611ccda65470c9a4a5f1be31f2f4f61b98c75d051e1a72e85a302eb')
        unspents = GetBlockchain().GetAllUnspent(u)
        self.assertEqual(len(unspents), 1)

    def test_gettxout(self):
        # block 730901 - 2 transactions
        # output with index 0 is spent, so should return an error

        txid = '0ff23561c611ccda65470c9a4a5f1be31f2f4f61b98c75d051e1a72e85a302eb'
        output_index = 0
        req = self._gen_rpc_req("gettxout", params=[txid, output_index])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        # will return `null` if not found
        self.assertEqual(None, res["result"])

        # output with index 1 is unspent, so should return valid values
        txid = '0ff23561c611ccda65470c9a4a5f1be31f2f4f61b98c75d051e1a72e85a302eb'
        output_index = 1
        req = self._gen_rpc_req("gettxout", params=[txid, output_index])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))

        expected_asset = '0x602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7'
        expected_value = "25"
        expected_address = 'AHYb3ySrHbhzouZ81ZMnCf8c7zYaoDg64x'

        self.assertEqual(output_index, res["result"]["n"])
        self.assertEqual(expected_address, res["result"]["address"])
        self.assertEqual(expected_asset, res["result"]["asset"])
        self.assertEqual(expected_value, res["result"]["value"])

        # now test for a different block (730848) with a floating value
        txid = '9c9f2c430c3cfb805e8c22d0a7778a60ce7792fad52ffe9b34f56de8e2c1d2e6'
        output_index = 1  # index 0 is spent, 0 is unspent
        req = self._gen_rpc_req("gettxout", params=[txid, output_index])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))

        expected_value = "2609.997813"
        self.assertEqual(output_index, res["result"]["n"])
        self.assertEqual(expected_value, res["result"]["value"])

    def test_send_raw_tx(self):
        raw_tx = '80000001b10ad9ec660bf343c0eb411f9e05b4fa4ad8abed31d4e4dc5bb6ae416af0c4de000002e72d286979ee6cb1b7e65dfddfb2e384100b8d148e7758de42e4168b71792c60c8db571300000000af12a8687b14948bc4a008128a550a63695bc1a5e72d286979ee6cb1b7e65dfddfb2e384100b8d148e7758de42e4168b71792c603808b44002000000eca8fcf94e7a2a7fc3fd54ae0ed3d34d52ec25900141404749ce868ed9588f604eeeb5c523db39fd57cd7f61d04393a1754c2d32f131d67e6b1ec561ac05012b7298eb5ff254487c76de0b2a0c4d097d17cec708c0a9802321025b5c8cdcb32f8e278e111a0bf58ebb463988024bb4e250aa4310b40252030b60ac'
        req = self._gen_rpc_req("sendrawtransaction", params=[raw_tx])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result'], True)

    def test_send_raw_tx_bad(self):
        raw_tx = '80000001b10ad9ec660bf343c0eb411f9e05b4fa4ad8abed31d4e4dc5bb6ae416af0c4de000002e72d286979ee6cb1b7e65dfddfb2e384100b8d148e7758de42e4168b71792c60c8db571300000000af12a8687b14948bc4a008128a550a63695bc1a5e72d286979ee6cb1b7e65dfddfb2e384100b8d148e7758de42e4168b71792c603808b44002000000eca8fcf94e7a2a7fc3fd54ae0ed3d34d52ec25900141404749ce868ed9588f604eeeb5c523db39fd57cd7f61d04393a1754c2d32f131d67e6b1ec561ac05012b7298eb5ff254487c76de0b2a0c4d097d17cec708c0a9802321025b5c8cdcb32f8e278e111a0bf58ebb463988024bb4e250aa4310b40252030b60ac'
        req = self._gen_rpc_req("sendrawtransaction", params=[raw_tx])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result'], False)

    def test_send_raw_tx_bad_2(self):
        raw_tx = '80000001b10ad9ec660bf343c0eb411f9e05b4fa4ad8abed31d4e4dc5bb6ae416af0c4de000002e72d286979ee6cbb7e65dfddfb2e384100b8d148e7758de42e4168b71792c60c8db571300000000af12a8687b14948bc4a008128a550a63695bc1a5e72d286979ee6cb1b7e65dfddfb2e384100b8d148e7758de42e4168b71792c603808b44002000000eca8fcf94e7a2a7fc3fd54ae0ed3d34d52ec25900141404749ce868ed9588f604eeeb5c523db39fd57cd7f61d04393a1754c2d32f131d67e6b1ec561ac05012b7298eb5ff254487c76de0b2a0c4d097d17cec708c0a9802321025b5c8cdcb32f8e278e111a0bf58ebb463988024bb4e250aa4310b40252030b60ac'
        req = self._gen_rpc_req("sendrawtransaction", params=[raw_tx])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertTrue('error' in res)
        self.assertEqual(res['error']['code'], -32603)

    def test_gzip_compression(self):
        req = self._gen_rpc_req("getblock", params=['a0d34f68cb7a04d625ae095fa509479ec7dcb4dc87ecd865ab059d0f8a42decf', 1])
        body = json.dumps(req).encode("utf-8")

        # first validate that we get a gzip response if we accept gzip encoding
        mock_req = requestMock(path=b'/', method="POST", body=body, headers={'Accept-Encoding': ['deflate', 'gzip;q=1.0', '*;q=0.5']})
        res = self.app.home(mock_req)

        GZIP_MAGIC = b'\x1f\x8b'
        self.assertIsInstance(res, bytes)
        self.assertTrue(res.startswith(GZIP_MAGIC))

        # then validate that we don't get a gzip response if we don't accept gzip encoding
        mock_req = requestMock(path=b'/', method="POST", body=body, headers={})
        res = self.app.home(mock_req)

        self.assertIsInstance(res, str)

        try:
            json.loads(res)
            valid_json = True
        except ValueError:
            valid_json = False
        self.assertTrue(valid_json)

    def test_getpeers(self):
        # Given this is an isolated environment and there is no peers
        # lets simulate that at least some addresses are known
        node = NodeLeader.Instance()
        node.ADDRS = ["127.0.0.1:20333", "127.0.0.2:20334"]
        test_node = NeoNode()
        test_node.host = "127.0.0.1"
        test_node.port = 20333
        node.Peers.append(test_node)

        req = self._gen_rpc_req("getpeers", params=[])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))

        self.assertEqual(len(node.Peers), len(res['result']['connected']))
        self.assertEqual(len(res['result']['unconnected']),
                         len(node.ADDRS) - len(node.Peers))
        # To avoid messing up the next tests
        node.Peers = []
        node.ADDRS = []

    def test_getwalletheight_no_wallet(self):
        req = self._gen_rpc_req("getwalletheight", params=["some id here"])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))

        error = res.get('error', {})

        self.assertEqual(error.get('code', None), -400)
        self.assertEqual(error.get('message', None), "Access denied.")

    def test_getwalletheight(self):
        self.app.wallet = UserWallet.Open(os.path.join(ROOT_INSTALL_PATH, "neo/data/neo-privnet.sample.wallet"), to_aes_key("coz"))

        req = self._gen_rpc_req("getwalletheight", params=[])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))

        self.assertEqual(1, res.get('result'))

    def test_getbalance_no_wallet(self):
        req = self._gen_rpc_req("getbalance", params=["some id here"])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))

        error = res.get('error', {})

        self.assertEqual(error.get('code', None), -400)
        self.assertEqual(error.get('message', None), "Access denied.")

    def test_getbalance_neo_with_wallet(self):
        test_wallet_path = os.path.join(mkdtemp(), "getbalance.db3")
        self.app.wallet = UserWallet.Create(
            test_wallet_path,
            to_aes_key('awesomepassword')
        )

        neo_id = "c56f33fc6ecfcd0c225c4ab356fee59390af8560be0e930faebe74a6daff7c9b"
        req = self._gen_rpc_req("getbalance", params=[neo_id])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))

        self.assertIn('Balance', res.get('result').keys())
        self.assertIn('Confirmed', res.get('result').keys())

        self.app.wallet.Close()
        self.app.wallet = None
        os.remove(test_wallet_path)

    def test_getbalance_invalid_params(self):
        test_wallet_path = os.path.join(mkdtemp(), "getbalance.db3")
        self.app.wallet = UserWallet.Create(
            test_wallet_path,
            to_aes_key('awesomepassword')
        )

        # max param length should be one, we provide 2
        req = self._gen_rpc_req("getbalance", params=[1, 2])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))

        error = res.get('error', {})

        self.assertEqual(error.get('code', None), -400)
        self.assertEqual(error.get('message', None), "Params should contain 1 id.")

    def test_getbalance_token_with_wallet(self):
        test_wallet_path = os.path.join(mkdtemp(), "getbalance.db3")
        self.app.wallet = UserWallet.Create(
            test_wallet_path,
            to_aes_key('awesomepassword')
        )

        fake_token_id = "fd941304d9cf36f31cd141c7c7029d81b1efa4f3"
        req = self._gen_rpc_req("getbalance", params=[fake_token_id])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))

        self.assertIn('Balance', res.get('result').keys())
        self.assertNotIn('Confirmed', res.get('result').keys())

        self.app.wallet.Close()
        self.app.wallet = None
        os.remove(test_wallet_path)

    def test_listaddress_no_wallet(self):
        req = self._gen_rpc_req("listaddress", params=[])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))

        error = res.get('error', {})

        self.assertEqual(error.get('code', None), -400)
        self.assertEqual(error.get('message', None), "Access denied.")

    def test_listaddress_with_wallet(self):
        test_wallet_path = os.path.join(mkdtemp(), "listaddress.db3")
        self.app.wallet = UserWallet.Create(
            test_wallet_path,
            to_aes_key('awesomepassword')
        )

        req = self._gen_rpc_req("listaddress", params=[])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        results = res.get('result', [])
        self.assertGreater(len(results), 0)
        self.assertIn(results[0].get('address', None),
                      self.app.wallet.Addresses)
        self.app.wallet.Close()
        self.app.wallet = None
        os.remove(test_wallet_path)

    def test_getnewaddress_no_wallet(self):
        req = self._gen_rpc_req("getnewaddress", params=[])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))

        error = res.get('error', {})

        self.assertEqual(error.get('code', None), -400)
        self.assertEqual(error.get('message', None), "Access denied.")

    def test_getnewaddress_with_wallet(self):
        test_wallet_path = os.path.join(mkdtemp(), "getnewaddress.db3")
        self.app.wallet = UserWallet.Create(
            test_wallet_path,
            to_aes_key('awesomepassword')
        )

        old_addrs = self.app.wallet.Addresses

        req = self._gen_rpc_req("getnewaddress", params=[])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        result = res.get('result')

        self.assertNotIn(result, old_addrs)
        self.assertIn(result, self.app.wallet.Addresses)

        self.app.wallet.Close()
        self.app.wallet = None
        os.remove(test_wallet_path)

    def test_valid_multirequest(self):
        raw_block_request = {"jsonrpc": "2.0", "method": "getblock", "params": [1], "id": 1}
        verbose_block_request = {"jsonrpc": "2.0", "method": "getblock", "params": [1, 1], "id": 2}

        multi_request = json.dumps([raw_block_request, verbose_block_request])
        mock_req = mock_request(multi_request.encode())
        res = json.loads(self.app.home(mock_req))

        self.assertEqual(type(res), list)
        self.assertEqual(len(res), 2)
        expected_raw_block = '00000000ef1f8f66a16fba100ed760f4ac6aa5a0d0bb8f4a0e92705b106761ef181718b3d0765298ceb5f57de7d2b0dab00ed25be4134706ada2d90adb8b7e3aba323a8e1abd125901000000d11f7a289214bdaff3812db982f3b0089a21a278988efeec6a027b2501fd450140884037dd265cb5f5a54802f53c2c8593b31d5b8a9c0bad4c7e366b153d878989d168080ac36b930036a9eb966b48c70bb41792e698fa021116f27c09643563b840e83ab14404d964a91dbac45f5460e88ad57196b1779478e3475334af8c1b49cd9f0213257895c60b5b92a4800eb32d785cbb39ae1f022528943909fd37deba63403677848bf98cc9dbd8fbfd7f2e4f34471866ea82ca6bffbf0f778b6931483700c17829b4bd066eb04983d3aac0bd46b9c8d03a73a8e714d3119de93cd9522e314054d16853b22014190063f77d9edf6fbccefcf71fffd1234f688823b4e429ae5fa639d0a664c842fbdfcb4d6e21f39d81c23563b92cffa09696d93c95bc4893a6401a43071d00d3e854f7f1f321afa7d5301d36f2195dc1e2643463f34ae637d2b02ae0eb11d4256c507a4f8304cea6396a7fce640f50acb301c2f6336d27717e84f155210209e7fd41dfb5c2f8dc72eb30358ac100ea8c72da18847befe06eade68cebfcb9210327da12b5c40200e9f65569476bbff2218da4f32548ff43b6387ec1416a231ee821034ff5ceeac41acf22cd5ed2da17a6df4dd8358fcb2bfb1a43208ad0feaab2746b21026ce35b29147ad09e4afe4ec4a7319095f08198fa8babbe3c56e970b143528d2221038dddc06ce687677a53d54f096d2591ba2302068cf123c1f2d75c2dddc542557921039dafd8571a641058ccc832c5e2111ea39b09c0bde36050914384f7a48bce9bf92102d02b1873a0863cd042cc717da31cea0d7cf9db32b74d4c72c01b0011503e2e2257ae010000d11f7a2800000000'
        self.assertEqual(res[0]['result'], expected_raw_block)
        expected_verbose_hash = '0x0012f8566567a9d7ddf25acb5cf98286c9703297de675d01ba73fbfe6bcb841c'
        self.assertEqual(res[1]['result']['hash'], expected_verbose_hash)

    def test_multirequest_with_1_invalid_request(self):
        """
        We provide 2 requests, first one invalid and should return and error, second one  valid and should still come up with correct results
        """
        # block request of invalid block, should fail
        raw_block_request = {"jsonrpc": "2.0", "method": "getblock", "params": [10000000000], "id": 1}
        verbose_block_request = {"jsonrpc": "2.0", "method": "getblock", "params": [1, 1], "id": 2}

        multi_request = json.dumps([raw_block_request, verbose_block_request])
        mock_req = mock_request(multi_request.encode())
        res = json.loads(self.app.home(mock_req))

        self.assertEqual(type(res), list)
        self.assertEqual(len(res), 2)

        # test for errors in first invalid request
        error = res[0].get('error', {})
        self.assertEqual(error.get('code', None), -100)
        self.assertEqual(error.get('message', None), "Unknown block")

        # test for success in second valid request
        expected_verbose_hash = '0x0012f8566567a9d7ddf25acb5cf98286c9703297de675d01ba73fbfe6bcb841c'
        self.assertEqual(res[1]['result']['hash'], expected_verbose_hash)
Ejemplo n.º 11
0
 def setUp(self):
     self.app = JsonRpcApi(20332)
Ejemplo n.º 12
0
class JsonRpcInvokeApiTestCase(BlockchainFixtureTestCase):
    app = None  # type:JsonRpcApi

    @classmethod
    def leveldb_testpath(self):
        return os.path.join(settings.DATA_DIR_PATH, 'fixtures/test_chain')

    def setUp(self):
        self.app = JsonRpcApi(20332)

    def test_invalid_json_payload(self):
        mock_req = mock_request(b"{ invalid")
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res["error"]["code"], -32700)

        mock_req = mock_request(json.dumps({"some": "stuff"}).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res["error"]["code"], -32600)

    def _gen_rpc_req(self, method, params=None, request_id="2"):
        ret = {
            "jsonrpc": "2.0",
            "id": request_id,
            "method": method
        }
        if params:
            ret["params"] = params
        return ret

    def test_invoke_1(self):
        contract_hash = 'd7678dd97c000be3f33e9362e673101bac4ca654'
        jsn = [
            {
                'type': str(ContractParameterType.String),
                'value': 'name'
            },
            {
                'type': str(ContractParameterType.Array),
                'value': []
            }
        ]
        req = self._gen_rpc_req("invoke", params=[contract_hash, jsn])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result']['state'], VMStateStr(VMState.HALT + VMState.BREAK))
        self.assertEqual(res['result']['gas_consumed'], '0.205')
        results = []
        for p in res['result']['stack']:
            results.append(ContractParameter.FromJson(p))
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].Type, ContractParameterType.ByteArray)
        self.assertEqual(results[0].Value, bytearray(b'LOCALTOKEN'))

    def test_invoke_2(self):
        contract_hash = 'd7678dd97c000be3f33e9362e673101bac4ca654'
        jsn = [
            {
                'type': str(ContractParameterType.String),
                'value': 'balanceOf'
            },
            {
                'type': str(ContractParameterType.Array),
                'value': [
                    {
                        'type': str(ContractParameterType.ByteArray),
                        'value': bytearray(b'\xec\xa8\xfc\xf9Nz*\x7f\xc3\xfdT\xae\x0e\xd3\xd3MR\xec%\x90').hex()
                    }
                ]
            }
        ]
        req = self._gen_rpc_req("invoke", params=[contract_hash, jsn])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result']['state'], VMStateStr(VMState.HALT + VMState.BREAK))
        results = []
        for p in res['result']['stack']:
            results.append(ContractParameter.FromJson(p))
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].Type, ContractParameterType.ByteArray)
        self.assertEqual(results[0].Value, bytearray(b'\xe9\x0f\x80\xbb\x04\x90\x00'))

    def test_invoke_3(self):
        contract_hash = 'd7678dd97c000be3f33e9362e673101bac4ca654'
        req = self._gen_rpc_req("invokefunction", params=[contract_hash, 'symbol'])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result']['state'], VMStateStr(VMState.HALT + VMState.BREAK))
        results = []
        for p in res['result']['stack']:
            results.append(ContractParameter.FromJson(p))
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].Type, ContractParameterType.ByteArray)
        self.assertEqual(results[0].Value, bytearray(b'LWTF'))

    def test_invoke_4(self):
        contract_hash = 'd7678dd97c000be3f33e9362e673101bac4ca654'
        params = [{'type': str(ContractParameterType.ByteArray),
                   'value': bytearray(b'\xec\xa8\xfc\xf9Nz*\x7f\xc3\xfdT\xae\x0e\xd3\xd3MR\xec%\x90').hex()}]

        req = self._gen_rpc_req("invokefunction", params=[contract_hash, 'balanceOf', params])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result']['state'], VMStateStr(VMState.HALT + VMState.BREAK))
        results = []
        for p in res['result']['stack']:
            results.append(ContractParameter.FromJson(p))
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].Type, ContractParameterType.ByteArray)
        self.assertEqual(results[0].Value, bytearray(b'\xe9\x0f\x80\xbb\x04\x90\x00'))

    def test_invoke_5(self):
        test_script = '00046e616d656754a64cac1b1073e662933ef3e30b007cd98d67d7000673796d626f6c6754a64cac1b1073e662933ef3e30b007cd98d67d70008646563696d616c736754a64cac1b1073e662933ef3e30b007cd98d67d7'
        req = self._gen_rpc_req("invokescript", params=[test_script])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result']['state'], VMStateStr(VMState.HALT + VMState.BREAK))

        results = []
        for p in res['result']['stack']:
            results.append(ContractParameter.FromJson(p))
        self.assertEqual(len(results), 3)
        self.assertEqual(results[0].Value, bytearray(b'LOCALTOKEN'))
        self.assertEqual(results[1].Value, bytearray(b'LWTF'))
        self.assertEqual(results[2].Value, 8)

    def test_bad_invoke_script(self):
        test_script = '0zzzzzzef3e30b007cd98d67d7'
        req = self._gen_rpc_req("invokescript", params=[test_script])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertTrue('error' in res)
        self.assertIn('Non-hexadecimal digit found', res['error']['message'])

    def test_bad_invoke_script_2(self):
        test_script = '00046e616d656754a64cac1b103e662933ef3e30b007cd98d67d7000673796d626f6c6754a64cac1b1073e662933ef3e30b007cd98d67d70008646563696d616c736754a64cac1b1073e662933ef3e30b007cd98d67d7'
        req = self._gen_rpc_req("invokescript", params=[test_script])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertTrue('error' in res)
        self.assertIn('Odd-length string', res['error']['message'])
Ejemplo n.º 13
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("-m",
                        "--mainnet",
                        action="store_true",
                        default=False,
                        help="Use MainNet instead of the default TestNet")
    parser.add_argument("-p",
                        "--privnet",
                        action="store_true",
                        default=False,
                        help="Use PrivNet instead of the default TestNet")
    parser.add_argument("-c",
                        "--config",
                        action="store",
                        help="Use a specific config file")
    parser.add_argument(
        '--version',
        action='version',
        version='neo-python v{version}'.format(version=__version__))

    args = parser.parse_args()

    if args.config and (args.mainnet or args.privnet):
        print(
            "Cannot use both --config and --mainnet/--privnet arguments, please use only one."
        )
        exit(1)
    if args.mainnet and args.privnet:
        print("Cannot use both --mainnet and --privnet arguments")
        exit(1)

    # Setup depending on command line arguments. By default, the testnet settings are already loaded.
    if args.config:
        settings.setup(args.config)
    elif args.mainnet:
        settings.setup_mainnet()
    elif args.privnet:
        settings.setup_privnet()

    # Instantiate the blockchain and subscribe to notifications
    blockchain = LevelDBBlockchain(settings.LEVELDB_PATH)
    Blockchain.RegisterBlockchain(blockchain)
    dbloop = task.LoopingCall(Blockchain.Default().PersistBlocks)
    dbloop.start(.1)

    settings.set_log_smart_contract_events(False)

    ndb = NotificationDB.instance()
    ndb.start()

    # Run
    reactor.suggestThreadPoolSize(15)
    NodeLeader.Instance().Start()

    host = "0.0.0.0"
    port = settings.RPC_PORT
    logger.info("Starting json-rpc api server on http://%s:%s" % (host, port))

    api_server = JsonRpcApi(port)
    api_server.app.run(host, port)
Ejemplo n.º 14
0
 def setUp(self):
     self.app = JsonRpcApi(9479)
Ejemplo n.º 15
0
class JsonRpcInvokeApiTestCase(BlockchainFixtureTestCase):
    app = None  # type:JsonRpcApi

    @classmethod
    def leveldb_testpath(cls):
        return os.path.join(settings.DATA_DIR_PATH, 'fixtures/test_chain')

    def setUp(self):
        self.app = JsonRpcApi(9479)

    def test_invalid_request_method(self):
        # test HEAD method
        mock_req = mock_get_request(b'/?test', b"HEAD")
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res["error"]["code"], -32600)
        self.assertEqual(res["error"]["message"],
                         'HEAD is not a supported HTTP method')

    def test_invalid_json_payload(self):
        # test POST requests
        mock_req = mock_post_request(b"{ invalid")
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res["error"]["code"], -32700)

        mock_req = mock_post_request(
            json.dumps({
                "some": "stuff"
            }).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res["error"]["code"], -32600)

        # test GET requests
        mock_req = mock_get_request(
            b"/?%20invalid")  # equivalent to "/? invalid"
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res["error"]["code"], -32600)

        mock_req = mock_get_request(b"/?some=stuff")
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res["error"]["code"], -32600)

    def _gen_post_rpc_req(self, method, params=None, request_id="2"):
        ret = {"jsonrpc": "2.0", "id": request_id, "method": method}
        if params:
            ret["params"] = params
        return ret

    def _gen_get_rpc_req(self, method, params=None, request="2"):
        ret = "/?jsonrpc=2.0&method=%s&params=[]&id=%s" % (method, request)
        if params:
            ret = "/?jsonrpc=2.0&method=%s&params=%s&id=%s" % (method, params,
                                                               request)
        return ret.encode('utf-8')

    def test_invoke_1(self):
        # test POST requests
        contract_hash = 'b9fbcff6e50fd381160b822207231233dd3c56c2'
        jsn = [{
            'type': str(ContractParameterType.String),
            'value': 'name'
        }, {
            'type': str(ContractParameterType.Array),
            'value': []
        }]
        req = self._gen_post_rpc_req("invoke", params=[contract_hash, jsn])
        mock_req = mock_post_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result']['state'],
                         VMStateStr(VMState.HALT + VMState.BREAK))
        self.assertEqual(res['result']['gas_consumed'], '0.128')
        results = []
        for p in res['result']['stack']:
            results.append(ContractParameter.FromJson(p))
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].Type, ContractParameterType.ByteArray)
        self.assertEqual(results[0].Value, bytearray(b'NEX Template V2'))

        # test GET requests
        req = self._gen_get_rpc_req("invoke", params=[contract_hash, jsn])
        mock_req = mock_get_request(req)
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result']['state'],
                         VMStateStr(VMState.HALT + VMState.BREAK))
        self.assertEqual(res['result']['gas_consumed'], '0.128')
        results = []
        for p in res['result']['stack']:
            results.append(ContractParameter.FromJson(p))
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].Type, ContractParameterType.ByteArray)
        self.assertEqual(results[0].Value, bytearray(b'NEX Template V2'))

    def test_invoke_2(self):
        contract_hash = 'b9fbcff6e50fd381160b822207231233dd3c56c2'
        jsn = [{
            'type': str(ContractParameterType.String),
            'value': 'balanceOf'
        }, {
            'type':
            str(ContractParameterType.Array),
            'value': [{
                'type':
                str(ContractParameterType.ByteArray),
                'value':
                bytearray(
                    b'#\xba\'\x03\xc52c\xe8\xd6\xe5"\xdc2 39\xdc\xd8\xee\xe9').
                hex()
            }]
        }]
        req = self._gen_post_rpc_req("invoke", params=[contract_hash, jsn])
        mock_req = mock_post_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result']['state'],
                         VMStateStr(VMState.HALT + VMState.BREAK))
        results = []
        for p in res['result']['stack']:
            results.append(ContractParameter.FromJson(p))
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].Type, ContractParameterType.ByteArray)
        self.assertEqual(results[0].Value,
                         bytearray(b'\x00\x90\x8c\xd4v\xe2\x00'))

    def test_invoke_3(self):
        contract_hash = 'b9fbcff6e50fd381160b822207231233dd3c56c2'
        req = self._gen_post_rpc_req("invokefunction",
                                     params=[contract_hash, 'symbol'])
        mock_req = mock_post_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result']['state'],
                         VMStateStr(VMState.HALT + VMState.BREAK))
        results = []
        for p in res['result']['stack']:
            results.append(ContractParameter.FromJson(p))
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].Type, ContractParameterType.ByteArray)
        self.assertEqual(results[0].Value, bytearray(b'NXT2'))

    def test_invoke_4(self):
        contract_hash = 'b9fbcff6e50fd381160b822207231233dd3c56c2'
        params = [{
            'type':
            str(ContractParameterType.ByteArray),
            'value':
            bytearray(b'#\xba\'\x03\xc52c\xe8\xd6\xe5"\xdc2 39\xdc\xd8\xee\xe9'
                      ).hex()
        }]

        req = self._gen_post_rpc_req(
            "invokefunction", params=[contract_hash, 'balanceOf', params])
        mock_req = mock_post_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result']['state'],
                         VMStateStr(VMState.HALT + VMState.BREAK))
        results = []
        for p in res['result']['stack']:
            results.append(ContractParameter.FromJson(p))
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].Type, ContractParameterType.ByteArray)
        self.assertEqual(results[0].Value,
                         bytearray(b'\x00\x90\x8c\xd4v\xe2\x00'))

    def test_invoke_5(self):
        test_script = "00046e616d6567c2563cdd3312230722820b1681d30fe5f6cffbb9000673796d626f6c67c2563cdd3312230722820b1681d30fe5f6cffbb90008646563696d616c7367c2563cdd3312230722820b1681d30fe5f6cffbb9"

        req = self._gen_post_rpc_req("invokescript", params=[test_script])
        mock_req = mock_post_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result']['state'],
                         VMStateStr(VMState.HALT + VMState.BREAK))

        results = []
        for p in res['result']['stack']:
            results.append(ContractParameter.FromJson(p))

        self.assertEqual(len(results), 3)
        self.assertEqual(results[0].Value, bytearray(b'NEX Template V2'))
        self.assertEqual(results[1].Value, bytearray(b'NXT2'))
        self.assertEqual(results[2].Value, 8)

    def test_bad_invoke_script(self):
        test_script = '0zzzzzzef3e30b007cd98d67d7'
        req = self._gen_post_rpc_req("invokescript", params=[test_script])
        mock_req = mock_post_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertTrue('error' in res)
        self.assertIn('Non-hexadecimal digit found', res['error']['message'])

    def test_bad_invoke_script_2(self):
        test_script = '00046e616d656754a64cac1b103e662933ef3e30b007cd98d67d7000673796d626f6c6754a64cac1b1073e662933ef3e30b007cd98d67d70008646563696d616c736754a64cac1b1073e662933ef3e30b007cd98d67d7'
        req = self._gen_post_rpc_req("invokescript", params=[test_script])
        mock_req = mock_post_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertTrue('error' in res)
        self.assertIn('Odd-length string', res['error']['message'])
Ejemplo n.º 16
0
class JsonRpcApiTestCase(BlockchainFixtureTestCase):
    app = None  # type:JsonRpcApi

    @classmethod
    def leveldb_testpath(self):
        return os.path.join(settings.DATA_DIR_PATH, 'fixtures/test_chain')

    def setUp(self):
        self.app = JsonRpcApi(20332)

    def test_invalid_json_payload(self):
        mock_req = mock_request(b"{ invalid")
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res["error"]["code"], -32700)

        mock_req = mock_request(json.dumps({"some": "stuff"}).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res["error"]["code"], -32600)

    def _gen_rpc_req(self, method, params=None, request_id="2"):
        ret = {
            "jsonrpc": "2.0",
            "id": request_id,
            "method": method
        }
        if params:
            ret["params"] = params
        return ret

    def test_missing_fields(self):
        req = self._gen_rpc_req("foo")
        del req["jsonrpc"]
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res["error"]["code"], -32600)

        req = self._gen_rpc_req("foo")
        del req["id"]
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res["error"]["code"], -32600)

        req = self._gen_rpc_req("foo")
        del req["method"]
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res["error"]["code"], -32600)

    def test_invalid_method(self):
        req = self._gen_rpc_req("invalid", request_id="42")
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res["id"], "42")
        self.assertEqual(res["error"]["code"], -32601)
        self.assertEqual(res["error"]["message"], "Method not found")

    def test_getblockcount(self):
        req = self._gen_rpc_req("getblockcount")
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(758987, res["result"])

    def test_getblockhash(self):
        req = self._gen_rpc_req("getblockhash", params=[2])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))

        # taken from neoscan
        expected_blockhash = '0x60ad7aebdae37f1cad7a15b841363b5a7da9fd36bf689cfde75c26c0fa085b64'
        self.assertEqual(expected_blockhash, res["result"])

    def test_getblockhash_failure(self):
        req = self._gen_rpc_req("getblockhash", params=[-1])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(-100, res["error"]["code"])
        self.assertEqual("Invalid Height", res["error"]["message"])

    def test_account_state(self):
        addr_str = 'AXjaFSP23Jkbe6Pk9pPGT6NBDs1HVdqaXK'
        req = self._gen_rpc_req("getaccountstate", params=[addr_str])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result']['balances']['0xc56f33fc6ecfcd0c225c4ab356fee59390af8560be0e930faebe74a6daff7c9b'], '4061.0')
        self.assertEqual(res['result']['script_hash'], addr_str)

    def test_account_state_not_existing_yet(self):
        addr_str = 'AHozf8x8GmyLnNv8ikQcPKgRHQTbFi46u2'
        req = self._gen_rpc_req("getaccountstate", params=[addr_str])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result']['balances'], {})
        self.assertEqual(res['result']['script_hash'], addr_str)

    def test_account_state_failure(self):
        addr_str = 'Axozf8x8GmyLnNv8ikQcPKgRHQTbFi46u2'
        req = self._gen_rpc_req("getaccountstate", params=[addr_str])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertTrue('error' in res)
        self.assertEqual(-2146233033, res['error']['code'])
        self.assertEqual('One of the identified items was in an invalid format.', res['error']['message'])

    def test_get_asset_state(self):
        asset_str = '602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7'
        req = self._gen_rpc_req("getassetstate", params=[asset_str])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result']['assetId'], '0x%s' % asset_str)
        self.assertEqual(res['result']['admin'], 'AWKECj9RD8rS8RPcpCgYVjk1DeYyHwxZm3')
        self.assertEqual(res['result']['available'], 3825482025899)

    def test_get_asset_state_0x(self):
        asset_str = '0x602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7'
        req = self._gen_rpc_req("getassetstate", params=[asset_str])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result']['assetId'], asset_str)

    def test_bad_asset_state(self):
        asset_str = '602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282dee'
        req = self._gen_rpc_req("getassetstate", params=[asset_str])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))

        self.assertTrue('error' in res)
        self.assertEqual(res['error']['message'], 'Unknown asset')

    def test_get_bestblockhash(self):
        req = self._gen_rpc_req("getbestblockhash", params=[])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result'], '0x6e9d1698ba2cd43432b6df1fca4bfbc53b2492a29401d1411699ddbd56cf8559')

    def test_get_connectioncount(self):
        # @TODO
        # Not sure if there's a great way to test this as it will always return 0 in tests
        req = self._gen_rpc_req("getconnectioncount", params=[])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result'], 0)

    def test_get_block_int(self):
        req = self._gen_rpc_req("getblock", params=[10, 1])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result']['index'], 10)
        self.assertEqual(res['result']['hash'], '0x9410bd44beb7d6febc9278b028158af2781fcfb40cf2c6067b3525d24eff19f6')
        self.assertEqual(res['result']['confirmations'], 758977)
        self.assertEqual(res['result']['nextblockhash'], '0xa0d34f68cb7a04d625ae095fa509479ec7dcb4dc87ecd865ab059d0f8a42decf')

    def test_get_block_hash(self):
        req = self._gen_rpc_req("getblock", params=['a0d34f68cb7a04d625ae095fa509479ec7dcb4dc87ecd865ab059d0f8a42decf', 1])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))

        self.assertEqual(res['result']['index'], 11)
        self.assertEqual(res['result']['confirmations'], 758976)
        self.assertEqual(res['result']['previousblockhash'], '0x9410bd44beb7d6febc9278b028158af2781fcfb40cf2c6067b3525d24eff19f6')

    def test_get_block_hash_0x(self):
        req = self._gen_rpc_req("getblock", params=['0xa0d34f68cb7a04d625ae095fa509479ec7dcb4dc87ecd865ab059d0f8a42decf', 1])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result']['index'], 11)

    def test_get_block_hash_failure(self):
        req = self._gen_rpc_req("getblock", params=['aad34f68cb7a04d625ae095fa509479ec7dcb4dc87ecd865ab059d0f8a42decf', 1])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertTrue('error' in res)
        self.assertEqual(res['error']['message'], 'Unknown block')

    def test_get_block_sysfee(self):
        req = self._gen_rpc_req("getblocksysfee", params=[13321])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result'], 230)

        # test negative block
        req = self._gen_rpc_req("getblocksysfee", params=[-1])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertTrue('error' in res)
        self.assertEqual(res['error']['message'], 'Invalid Height')

        # test block exceeding max block height
        req = self._gen_rpc_req("getblocksysfee", params=[3000000000])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertTrue('error' in res)
        self.assertEqual(res['error']['message'], 'Invalid Height')

    def test_block_non_verbose(self):
        req = self._gen_rpc_req("getblock", params=[2003, 0])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertIsNotNone(res['result'])

        # we should be able to instantiate a matching block with the result
        output = binascii.unhexlify(res['result'])
        block = Helper.AsSerializableWithType(output, 'neo.Core.Block.Block')
        self.assertEqual(block.Index, 2003)
        self.assertEqual(len(block.Transactions), 2)

    def test_get_contract_state(self):
        contract_hash = UInt160(data=bytearray(b'\x11\xc4\xd1\xf4\xfb\xa6\x19\xf2b\x88p\xd3n:\x97s\xe8tp[')).ToString()
        req = self._gen_rpc_req("getcontractstate", params=[contract_hash])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result']['code_version'], '3')
        self.assertEqual(res['result']['properties']['storage'], True)
        self.assertEqual(res['result']['code']['hash'], '0x5b7074e873973a6ed3708862f219a6fbf4d1c411')
        self.assertEqual(res['result']['code']['returntype'], 5)
        self.assertEqual(res['result']['code']['parameters'], '0710')

    def test_get_contract_state_0x(self):
        contract_hash = '0x%s' % UInt160(data=bytearray(b'\x11\xc4\xd1\xf4\xfb\xa6\x19\xf2b\x88p\xd3n:\x97s\xe8tp[')).ToString()
        req = self._gen_rpc_req("getcontractstate", params=[contract_hash])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result']['code_version'], '3')

    def test_get_contract_state_not_found(self):
        contract_hash = '0xf4e65b0e1ba449d8d0f3baae1690b455b0e6e75c'
        req = self._gen_rpc_req("getcontractstate", params=[contract_hash])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertTrue('error' in res)
        self.assertEqual(res['error']['message'], 'Unknown contract')

    def test_get_raw_mempool(self):
        # TODO: currently returns empty list. test with list would be great
        req = self._gen_rpc_req("getrawmempool", params=[])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        mempool = res['result']

        # when running only these tests, mempool is empty. when running all tests, there are a
        # number of entries
        if len(mempool) > 0:
            for entry in mempool:
                self.assertEqual(entry[0:2], "0x")
                self.assertEqual(len(entry), 66)

    def test_get_version(self):
        # TODO: what's the nonce? on testnet live server response it's always 771199013
        req = self._gen_rpc_req("getversion", params=[])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res["result"]["port"], 20332)
        self.assertEqual(res["result"]["useragent"], "/NEO-PYTHON:%s/" % __version__)

    def test_validate_address(self):
        # example from docs.neo.org
        req = self._gen_rpc_req("validateaddress", params=["AQVh2pG732YvtNaxEGkQUei3YA4cvo7d2i"])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertTrue(res["result"]["isvalid"])

        # example from docs.neo.org
        req = self._gen_rpc_req("validateaddress", params=["152f1muMCNa7goXYhYAQC61hxEgGacmncB"])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertFalse(res["result"]["isvalid"])

        # catch completely invalid argument
        req = self._gen_rpc_req("validateaddress", params=[])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertTrue('error' in res)
        self.assertEqual('Missing argument', res['error']['message'])

        # catch completely invalid argument
        req = self._gen_rpc_req("validateaddress", params=[""])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertTrue('error' in res)
        self.assertEqual('Missing argument', res['error']['message'])

    def test_getrawtx_1(self):
        txid = 'cedb5c4e24b1f6fc5b239f2d1049c3229ad5ed05293c696b3740dc236c3f41b4'
        req = self._gen_rpc_req("getrawtransaction", params=[txid, 1])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))['result']
        self.assertEqual(res['blockhash'], '0x41720c35f5f15e5dc343d67fb54ab1e3825de47b476b5ae56cede2bf30657fde')
        self.assertEqual(res['txid'], "0x%s" % txid)
        self.assertEqual(res['blocktime'], 1499393065)
        self.assertEqual(res['type'], 'ContractTransaction')

    def test_getrawtx_2(self):
        txid = 'cedb5c4e24b1f6fc5b239f2d1049c3229ad5ed05293c696b3740dc236c3f41b4'
        req = self._gen_rpc_req("getrawtransaction", params=[txid, 0])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))['result']
        expected = '800001f00431313131010206cc6f919695fb55c9605c55127128c29697d791af884c2636416c69a944880100029b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc500e1f50500000000e58e5999bcbf5d78f52ead40654131abb9ee27099b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc5009a04f516000000e53a27d37d7f5a3187003c21efe3725304a7410601414058b4a41beabdcf62381f7feea02767a714eb8ea49212fdb47a6f0bed2d0ae87d27377d9c2b4412ebf816042f2144e6e08939c7d83638b61208d3a7f5ea47c3ba232102ca81fa6c7ef20219c417d876c2743ea87728d416632d09c18004652aed09e000ac'
        self.assertEqual(res, expected)

    def test_getrawtx_3(self):
        txid = 'cedb5c4e24b1f6fc5b239f2d1049c3229ad5ed05293c696b3740dc236c3f41b3'
        req = self._gen_rpc_req("getrawtransaction", params=[txid, 0])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertTrue('error' in res)
        self.assertEqual(res['error']['message'], 'Unknown Transaction')

    def test_get_storage_item(self):
        contract_hash = '16f1559c3c27d66d087bef936804105457617c8a'
        storage_key = binascii.hexlify(b'totalSupply').decode('utf-8')
        req = self._gen_rpc_req("getstorage", params=[contract_hash, storage_key])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result'], '00f938dbba05')
        actual_val = int.from_bytes(binascii.unhexlify(res['result'].encode('utf-8')), 'little')
        self.assertEqual(actual_val, 6300100000000)

    def test_get_storage_item2(self):
        contract_hash = '0xd7678dd97c000be3f33e9362e673101bac4ca654'
        storage_key = binascii.hexlify(b'totalSupply').decode('utf-8')
        req = self._gen_rpc_req("getstorage", params=[contract_hash, storage_key])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result'], '003a0d7914b200')

    def test_get_storage_item_key_not_found(self):
        contract_hash = '0xd7678dd97c000be3f33e9362e673101bac4ca654'
        storage_key = binascii.hexlify(b'blah').decode('utf-8')
        req = self._gen_rpc_req("getstorage", params=[contract_hash, storage_key])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result'], None)

    def test_get_storage_item_contract_not_found(self):
        contract_hash = '0xd7678dd97c100be3f33e9362e673101bac4ca654'
        storage_key = binascii.hexlify(b'blah').decode('utf-8')
        req = self._gen_rpc_req("getstorage", params=[contract_hash, storage_key])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result'], None)

    def test_get_storage_item_bad_contract_hash(self):
        contract_hash = '0xd7678dd97c000b3e9362e673101bac4ca654'
        storage_key = binascii.hexlify(b'blah').decode('utf-8')
        req = self._gen_rpc_req("getstorage", params=[contract_hash, storage_key])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertTrue('error' in res)
        self.assertIn('Invalid UInt', res['error']['message'])

    def test_get_unspents(self):
        u = UInt256.ParseString('0ff23561c611ccda65470c9a4a5f1be31f2f4f61b98c75d051e1a72e85a302eb')
        unspents = GetBlockchain().GetAllUnspent(u)
        self.assertEqual(len(unspents), 1)

    def test_gettxout(self):
        # block 730901 - 2 transactions
        # output with index 0 is spent, so should return an error

        txid = '0ff23561c611ccda65470c9a4a5f1be31f2f4f61b98c75d051e1a72e85a302eb'
        output_index = 0
        req = self._gen_rpc_req("gettxout", params=[txid, output_index])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        # will return `null` if not found
        self.assertEqual(None, res["result"])

        # output with index 1 is unspent, so should return valid values
        txid = '0ff23561c611ccda65470c9a4a5f1be31f2f4f61b98c75d051e1a72e85a302eb'
        output_index = 1
        req = self._gen_rpc_req("gettxout", params=[txid, output_index])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))

        expected_asset = '0x602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7'
        expected_value = "25"
        expected_address = 'AHYb3ySrHbhzouZ81ZMnCf8c7zYaoDg64x'

        self.assertEqual(output_index, res["result"]["n"])
        self.assertEqual(expected_address, res["result"]["address"])
        self.assertEqual(expected_asset, res["result"]["asset"])
        self.assertEqual(expected_value, res["result"]["value"])

        # now test for a different block (730848) with a floating value
        txid = '9c9f2c430c3cfb805e8c22d0a7778a60ce7792fad52ffe9b34f56de8e2c1d2e6'
        output_index = 1  # index 0 is spent, 0 is unspent
        req = self._gen_rpc_req("gettxout", params=[txid, output_index])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))

        expected_value = "2609.997813"
        self.assertEqual(output_index, res["result"]["n"])
        self.assertEqual(expected_value, res["result"]["value"])

    def test_send_raw_tx(self):
        raw_tx = '80000001b10ad9ec660bf343c0eb411f9e05b4fa4ad8abed31d4e4dc5bb6ae416af0c4de000002e72d286979ee6cb1b7e65dfddfb2e384100b8d148e7758de42e4168b71792c60c8db571300000000af12a8687b14948bc4a008128a550a63695bc1a5e72d286979ee6cb1b7e65dfddfb2e384100b8d148e7758de42e4168b71792c603808b44002000000eca8fcf94e7a2a7fc3fd54ae0ed3d34d52ec25900141404749ce868ed9588f604eeeb5c523db39fd57cd7f61d04393a1754c2d32f131d67e6b1ec561ac05012b7298eb5ff254487c76de0b2a0c4d097d17cec708c0a9802321025b5c8cdcb32f8e278e111a0bf58ebb463988024bb4e250aa4310b40252030b60ac'
        req = self._gen_rpc_req("sendrawtransaction", params=[raw_tx])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result'], True)

    def test_send_raw_tx_bad(self):
        raw_tx = '80000001b10ad9ec660bf343c0eb411f9e05b4fa4ad8abed31d4e4dc5bb6ae416af0c4de000002e72d286979ee6cb1b7e65dfddfb2e384100b8d148e7758de42e4168b71792c60c8db571300000000af12a8687b14948bc4a008128a550a63695bc1a5e72d286979ee6cb1b7e65dfddfb2e384100b8d148e7758de42e4168b71792c603808b44002000000eca8fcf94e7a2a7fc3fd54ae0ed3d34d52ec25900141404749ce868ed9588f604eeeb5c523db39fd57cd7f61d04393a1754c2d32f131d67e6b1ec561ac05012b7298eb5ff254487c76de0b2a0c4d097d17cec708c0a9802321025b5c8cdcb32f8e278e111a0bf58ebb463988024bb4e250aa4310b40252030b60ac'
        req = self._gen_rpc_req("sendrawtransaction", params=[raw_tx])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertEqual(res['result'], False)

    def test_send_raw_tx_bad_2(self):
        raw_tx = '80000001b10ad9ec660bf343c0eb411f9e05b4fa4ad8abed31d4e4dc5bb6ae416af0c4de000002e72d286979ee6cbb7e65dfddfb2e384100b8d148e7758de42e4168b71792c60c8db571300000000af12a8687b14948bc4a008128a550a63695bc1a5e72d286979ee6cb1b7e65dfddfb2e384100b8d148e7758de42e4168b71792c603808b44002000000eca8fcf94e7a2a7fc3fd54ae0ed3d34d52ec25900141404749ce868ed9588f604eeeb5c523db39fd57cd7f61d04393a1754c2d32f131d67e6b1ec561ac05012b7298eb5ff254487c76de0b2a0c4d097d17cec708c0a9802321025b5c8cdcb32f8e278e111a0bf58ebb463988024bb4e250aa4310b40252030b60ac'
        req = self._gen_rpc_req("sendrawtransaction", params=[raw_tx])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))
        self.assertTrue('error' in res)
        self.assertEqual(res['error']['code'], -32603)

    def test_gzip_compression(self):
        req = self._gen_rpc_req("getblock", params=['a0d34f68cb7a04d625ae095fa509479ec7dcb4dc87ecd865ab059d0f8a42decf', 1])
        body = json.dumps(req).encode("utf-8")

        # first validate that we get a gzip response if we accept gzip encoding
        mock_req = requestMock(path=b'/', method="POST", body=body, headers={'Accept-Encoding': ['deflate', 'gzip;q=1.0', '*;q=0.5']})
        res = self.app.home(mock_req)

        GZIP_MAGIC = b'\x1f\x8b'
        self.assertIsInstance(res, bytes)
        self.assertTrue(res.startswith(GZIP_MAGIC))

        # then validate that we don't get a gzip response if we don't accept gzip encoding
        mock_req = requestMock(path=b'/', method="POST", body=body, headers={})
        res = self.app.home(mock_req)

        self.assertIsInstance(res, str)

        try:
            json.loads(res)
            valid_json = True
        except ValueError:
            valid_json = False
        self.assertTrue(valid_json)

    def test_getpeers(self):
        # Given this is an isolated environment and there is no peers
        # lets simulate that at least some addresses are known
        node = NodeLeader.Instance()
        node.ADDRS = ["127.0.0.1:20333", "127.0.0.2:20334"]
        test_node = NeoNode()
        test_node.host = "127.0.0.1"
        test_node.port = 20333
        node.Peers.append(test_node)

        req = self._gen_rpc_req("getpeers", params=[])
        mock_req = mock_request(json.dumps(req).encode("utf-8"))
        res = json.loads(self.app.home(mock_req))

        self.assertEqual(len(node.Peers), len(res['result']['connected']))
        self.assertEqual(len(res['result']['unconnected']),
                         len(node.ADDRS) - len(node.Peers))
        # To avoid messing up the next tests
        node.Peers = []
        node.ADDRS = []