Ejemplo n.º 1
0
    def do_notifications(self, arguments):
        if NotificationDB.instance() is None:
            print("No notification DB Configured")
            return

        item = get_arg(arguments, 0)
        events = []
        if len(item) == 34:
            addr = item
            events = NotificationDB.instance().get_by_addr(addr)
        else:
            try:
                block_height = int(item)
                if block_height < Blockchain.Default().Height:
                    events = NotificationDB.instance().get_by_block(block_height)
                else:
                    print("Block %s not found" % block_height)
                    return
            except Exception as e:
                print("Could not parse block height %s" % e)
                return

        if len(events):
            [print(json.dumps(e.ToJson(), indent=4)) for e in events]
        else:
            print("No events found for %s" % item)
    def test_8_lookup_should_be_empty(self):

        ndb = NotificationDB.instance()

        events = ndb.get_by_block(123)

        self.assertEqual(len(events), 0)
Ejemplo n.º 3
0
    def test_8_lookup_should_be_empty(self):

        ndb = NotificationDB.instance()

        events = ndb.get_by_block(123)

        self.assertEqual(len(events), 0)
Ejemplo n.º 4
0
    def setUpClass(cls):

        super(NotificationDBTestCase, cls).setUpClass()

        if not os.path.exists(cls.N_FIXTURE_FILENAME):
            logzero.logger.info(
                "downloading fixture notification database from %s. this may take a while" % cls.N_FIXTURE_REMOTE_LOC)

            response = requests.get(cls.N_FIXTURE_REMOTE_LOC, stream=True)

            response.raise_for_status()
            with open(cls.N_FIXTURE_FILENAME, 'wb+') as handle:
                for block in response.iter_content(1024):
                    handle.write(block)

        try:
            tar = tarfile.open(cls.N_FIXTURE_FILENAME)
            tar.extractall(path=settings.DATA_DIR_PATH)
            tar.close()

        except Exception as e:
            raise Exception("Could not extract tar file - %s. You may want need to remove the fixtures file %s manually to fix this." % (e, cls.N_FIXTURE_FILENAME))

        if not os.path.exists(cls.N_NOTIFICATION_DB_NAME):
            raise Exception("Error downloading fixtures")

        settings.NOTIFICATION_DB_PATH = cls.N_NOTIFICATION_DB_NAME
        ndb = NotificationDB.instance()
        ndb.start()
Ejemplo n.º 5
0
    def test_4_notification_lookup(self):

        ndb = NotificationDB.instance()

        events = ndb.get_by_block(91349)

        self.assertEqual(len(events), 1)
Ejemplo n.º 6
0
    def test_2_persist_isnt_notify_event(self):
        sc = SmartContractEvent(SmartContractEvent.RUNTIME_NOTIFY, [], self.contract_hash, 99, self.event_tx, True, False)

        ndb = NotificationDB.instance()
        ndb.on_smart_contract_event(sc)

        self.assertEqual(ndb.current_events, [])
Ejemplo n.º 7
0
    def test_1_ok(self):

        ndb = NotificationDB.instance()

        events = ndb.get_by_block(627529)

        self.assertEqual(len(events), 1)
Ejemplo n.º 8
0
    def test_1_notify_should_not_persist(self):

        sc = NotifyEvent(SmartContractEvent.RUNTIME_NOTIFY, ContractParameter(ContractParameterType.Array, []), self.contract_hash, 99, self.event_tx, True, False)

        ndb = NotificationDB.instance()
        ndb.on_smart_contract_event(sc)

        self.assertEqual(ndb.current_events, [])
Ejemplo n.º 9
0
    def test_3_should_persist(self):
        sc = NotifyEvent(SmartContractEvent.RUNTIME_NOTIFY, [b'transfer', self.addr_to, self.addr_from, BigInteger(123000)], self.contract_hash, 91349, self.event_tx, True, False)

        ndb = NotificationDB.instance()
        ndb.on_smart_contract_event(sc)

        self.assertEqual(len(ndb.current_events), 1)
        ndb.on_persist_completed(None)
Ejemplo n.º 10
0
    def test_9_lookup_should_be_empty(self):

        ndb = NotificationDB.instance()

        sh = UInt160(data=b')\x96S\xb5\xe3e\xcb3\xb4\xea:\xd1\xd7\xe1\xb3\xf5\xe6\x82N/')

        events = ndb.get_by_addr(sh)

        self.assertEqual(len(events), 0)
    def test_2_persist_isnt_notify_event(self):
        sc = SmartContractEvent(SmartContractEvent.RUNTIME_NOTIFY, [],
                                self.contract_hash, 99, self.event_tx, True,
                                False)

        ndb = NotificationDB.instance()
        ndb.on_smart_contract_event(sc)

        self.assertEqual(ndb.current_events, [])
Ejemplo n.º 12
0
    def test_9_lookup_should_be_empty(self):

        ndb = NotificationDB.instance()

        sh = UInt160(data=b')\x96S\xb5\xe3e\xcb3\xb4\xea:\xd1\xd7\xe1\xb3\xf5\xe6\x82N/')

        events = ndb.get_by_addr(sh)

        self.assertEqual(len(events), 0)
Ejemplo n.º 13
0
    def test_7_lookup_addr_by_script_hash(self):

        ndb = NotificationDB.instance()

        sh = UInt160(data=b')\x96S\xb5\xe3e\xcb3\xb4\xea:\xd1\xd7\xe1\xb3\xf5\xe6\x81N/')

        events = ndb.get_by_addr(sh)

        self.assertEqual(len(events), 1)
Ejemplo n.º 14
0
    def test_7_lookup_addr_by_script_hash(self):

        ndb = NotificationDB.instance()

        sh = UInt160(data=b')\x96S\xb5\xe3e\xcb3\xb4\xea:\xd1\xd7\xe1\xb3\xf5\xe6\x81N/')

        events = ndb.get_by_addr(sh)

        self.assertEqual(len(events), 1)
Ejemplo n.º 15
0
    def test_6_addr_to_lookup(self):
        ndb = NotificationDB.instance()

        events = ndb.get_by_addr('AKZmSGPD7ytJBbxpRPmobYGLNxdWH3Jiqs')

        self.assertEqual(len(events), 1)

        evt = events[0]  # type:NotifyEvent

        self.assertEqual(evt.AddressFrom, 'AKZmSGPD7ytJBbxpRPmobYGLNxdWH3Jiqs')
Ejemplo n.º 16
0
    def test_5_addr_from_lookup(self):
        ndb = NotificationDB.instance()

        events = ndb.get_by_addr('ALb8FEhEmtSqv97fuNVuoLmcmrSKckffRf')

        self.assertEqual(len(events), 1)

        evt = events[0]  # type:NotifyEvent

        self.assertEqual(evt.AddressTo, 'ALb8FEhEmtSqv97fuNVuoLmcmrSKckffRf')
Ejemplo n.º 17
0
def token_history(wallet, token_str):
    notification_db = NotificationDB.instance()

    try:
        token = PromptUtils.get_token(wallet, token_str)
    except ValueError:
        raise

    events = notification_db.get_by_contract(token.ScriptHash)
    return token, events
    def test_5_addr_from_lookup(self):
        ndb = NotificationDB.instance()

        events = ndb.get_by_addr('ALb8FEhEmtSqv97fuNVuoLmcmrSKckffRf')

        self.assertEqual(len(events), 1)

        evt = events[0]  # type:NotifyEvent

        self.assertEqual(evt.AddressTo, 'ALb8FEhEmtSqv97fuNVuoLmcmrSKckffRf')
    def test_6_addr_to_lookup(self):
        ndb = NotificationDB.instance()

        events = ndb.get_by_addr('AKZmSGPD7ytJBbxpRPmobYGLNxdWH3Jiqs')

        self.assertEqual(len(events), 1)

        evt = events[0]  # type:NotifyEvent

        self.assertEqual(evt.AddressFrom, 'AKZmSGPD7ytJBbxpRPmobYGLNxdWH3Jiqs')
Ejemplo n.º 20
0
    def test_should_persist_mint_event(self):
        sc = NotifyEvent(
            SmartContractEvent.RUNTIME_NOTIFY,
            [b'mint', self.addr_to, BigInteger(123000)], self.contract_hash,
            91349, self.event_tx, True, False)

        ndb = NotificationDB.instance()
        ndb.on_smart_contract_event(sc)

        self.assertEqual(len(ndb.current_events), 1)
        ndb.on_persist_completed(None)
Ejemplo n.º 21
0
    def test_7_token_history_no_token(self):

        wallet = self.GetWallet1(recreate=True)

        ImportToken(wallet, self.token_hash_str)

        db = NotificationDB.instance()

        result = token_history(wallet, db, ["BAD"])

        self.assertFalse(result)

        db.close()
Ejemplo n.º 22
0
    def execute(self, arguments):
        if NotificationDB.instance() is None:
            print("No notification DB Configured")
            return

        item = get_arg(arguments)
        if item is not None:
            if item[0:2] == "0x":
                item = item[2:]

            if len(item) == 34 and item[0] == 'A':
                events = NotificationDB.instance().get_by_addr(item)

            elif len(item) == 40:
                events = NotificationDB.instance().get_by_contract(item)

            else:
                try:
                    block_height = int(item)
                    if block_height < Blockchain.Default().Height:
                        events = NotificationDB.instance().get_by_block(
                            block_height)
                    else:
                        print("Block %s not found" % block_height)
                        return
                except Exception:
                    print("Could not find notifications from args: %s" %
                          arguments)
                    return

            if len(events):
                [print(json.dumps(e.ToJson(), indent=4)) for e in events]
                return events
            else:
                print("No events found for %s" % item)
                return
        else:
            print("Please specify the required parameter")
            return
    def test_4_should_persist(self):

        ndb = NotificationDB.instance()

        self.assertEqual(len(ndb.current_events), 0)
        sc = NotifyEvent(
            SmartContractEvent.RUNTIME_NOTIFY,
            [b'transfer', self.addr_to, self.addr_from,
             BigInteger(123000)], self.contract_hash, 91349, self.event_tx,
            True, True)

        ndb.on_smart_contract_event(sc)

        self.assertEqual(len(ndb.current_events), 0)
Ejemplo n.º 24
0
    def test_3_should_persist(self):
        payload = ContractParameter(ContractParameterType.Array, [
            ContractParameter(ContractParameterType.String, b'transfer'),
            ContractParameter(ContractParameterType.ByteArray, self.addr_to),
            ContractParameter(ContractParameterType.ByteArray, self.addr_from),
            ContractParameter(ContractParameterType.Integer, 123000)
        ])
        sc = NotifyEvent(SmartContractEvent.RUNTIME_NOTIFY, payload, self.contract_hash, 91349, self.event_tx, True, False)

        ndb = NotificationDB.instance()
        ndb.on_smart_contract_event(sc)

        self.assertEqual(len(ndb.current_events), 1)
        ndb.on_persist_completed(None)
Ejemplo n.º 25
0
def main():
    settings.setup_privnet(True)
    settings.set_log_smart_contract_events(True)

    # Instantiate the blockchain and subscribe to notifications
    blockchain = LevelDBBlockchain(settings.chain_leveldb_path)
    Blockchain.RegisterBlockchain(blockchain)

    args = sys.argv[1:]
    args += os.getenv('CONTRACT_FILE', '').split(' ')
    args += os.getenv('CONTRACT_ARGS', '').split(' ')
    args = list(filter(None, args))

    if len(args) < 2:  # must provide file name and arguments
        print("WARN! No smart contracts args... skip")
        return

    app = ImportSC(args, blockchain, reactor)

    loop = task.LoopingCall(blockchain.PersistBlocks)
    deferred = loop.start(.1)
    deferred.addErrback(app.on_loopError)

    # Try to set up a notification db
    if NotificationDB.instance():
        NotificationDB.instance().start()

    NodeLeader.Instance().Start()
    NodeLeader.Instance().PeerCheckLoop()

    # PyAssumeType(twisted.internet.reactor, twisted.internet.selectreactor.SelectReactor)
    reactor.callInThread(app.worker)
    reactor.run()

    NotificationDB.close()
    Blockchain.Default().Dispose()
    NodeLeader.Instance().Shutdown()
Ejemplo n.º 26
0
    def test_7_token_history_correct(self):

        wallet = self.GetWallet1(recreate=True)

        ImportToken(wallet, self.token_hash_str)

        db = NotificationDB.instance()

        token = self.get_token(wallet)

        result = token_history(wallet, db, [token.symbol])

        self.assertTrue(result)

        db.close()
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)

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

    notif_server = NotificationRestApi()

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

    port = 8000
    logger.info("Starting notification-api server on port %s" % (port))
    notif_server.app.run('0.0.0.0', port)
Ejemplo n.º 28
0
 def __init__(self):
     self.notif = NotificationDB.instance()
Ejemplo n.º 29
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.º 30
0
def main():
    parser = argparse.ArgumentParser()

    # Network group
    group = parser.add_mutually_exclusive_group()
    group.add_argument("-m", "--mainnet", action="store_true", default=False,
                       help="Use MainNet instead of the default TestNet")
    group.add_argument("-p", "--privnet", nargs="?", metavar="host", const=True, default=False,
                       help="Use a private net instead of the default TestNet, optionally using a custom host (default: 127.0.0.1)")
    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")

    # Theme
    parser.add_argument("-t", "--set-default-theme", dest="theme",
                        choices=["dark", "light"],
                        help="Set the default theme to be loaded from the config file. Default: 'dark'")

    # Verbose
    parser.add_argument("-v", "--verbose", action="store_true", default=False,
                        help="Show smart-contract events by default")

    # 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")

    # Show the neo-python version
    parser.add_argument("--version", action="version",
                        version="neo-python v{version}".format(version=__version__))

    args = parser.parse_args()

    # 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:
        try:
            settings.setup_privnet(args.privnet)
        except PrivnetConnectionError as e:
            logger.error(str(e))
            return
    elif args.coznet:
        settings.setup_coznet()

    if args.theme:
        preferences.set_theme(args.theme)

    if args.verbose:
        settings.set_log_smart_contract_events(True)

    if args.datadir:
        settings.set_data_dir(args.datadir)

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

    # Instantiate the blockchain and subscribe to notifications
    blockchain = LevelDBBlockchain(settings.chain_leveldb_path)
    Blockchain.RegisterBlockchain(blockchain)

    # Try to set up a notification db
    if NotificationDB.instance():
        NotificationDB.instance().start()

    # Start the prompt interface
    cli = PromptInterface()

    # Run things
#    reactor.suggestThreadPoolSize(15)
    reactor.callInThread(cli.run)
    NodeLeader.Instance().Start()

    # reactor.run() is blocking, until `quit()` is called which stops the reactor.
    reactor.run()

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

    # Network group
    group = parser.add_mutually_exclusive_group()
    group.add_argument("-m",
                       "--mainnet",
                       action="store_true",
                       default=False,
                       help="Use MainNet instead of the default TestNet")
    group.add_argument(
        "-p",
        "--privnet",
        nargs="?",
        metavar="host",
        const=True,
        default=False,
        help=
        "Use a private net instead of the default TestNet, optionally using a custom host (default: 127.0.0.1)"
    )
    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")

    # Theme
    parser.add_argument(
        "-t",
        "--set-default-theme",
        dest="theme",
        choices=["dark", "light"],
        help=
        "Set the default theme to be loaded from the config file. Default: 'dark'"
    )

    # Verbose
    parser.add_argument("-v",
                        "--verbose",
                        action="store_true",
                        default=False,
                        help="Show smart-contract events by default")

    # Where to store stuff
    parser.add_argument("--datadir",
                        action="store",
                        help="Absolute path to use for database directories")

    # Show the neo-python version
    parser.add_argument(
        "--version",
        action="version",
        version="neo-python v{version}".format(version=__version__))

    args = parser.parse_args()

    # 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:
        try:
            settings.setup_privnet(args.privnet)
        except PrivnetConnectionError as e:
            logger.error(str(e))
            return
    elif args.coznet:
        settings.setup_coznet()

    if args.theme:
        preferences.set_theme(args.theme)

    if args.verbose:
        settings.set_log_smart_contract_events(True)

    if args.datadir:
        settings.set_data_dir(args.datadir)

    # Instantiate the blockchain and subscribe to notifications
    blockchain = LevelDBBlockchain(settings.chain_leveldb_path)
    Blockchain.RegisterBlockchain(blockchain)

    # Try to set up a notification db
    if NotificationDB.instance():
        NotificationDB.instance().start()

    # Start the prompt interface
    cli = PromptInterface()

    # Run things
    reactor.suggestThreadPoolSize(15)
    reactor.callInThread(cli.run)
    NodeLeader.Instance().Start()

    # reactor.run() is blocking, until `quit()` is called which stops the reactor.
    reactor.run()

    # After the reactor is stopped, gracefully shutdown the database.
    NotificationDB.close()
    Blockchain.Default().Dispose()
    NodeLeader.Instance().Shutdown()
Ejemplo n.º 32
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(
        "-t",
        "--set-default-theme",
        dest="theme",
        choices=["dark", "light"],
        help=
        "Set the default theme to be loaded from the config file. Default: 'dark'"
    )
    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 --config and --mainnet/--privnet together, please use only one"
        )
        exit(1)
    if args.mainnet and args.privnet:
        print("Cannot use --mainnet and --privnet together")
        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()

    if args.theme:
        preferences.set_theme(args.theme)

    # Instantiate the blockchain and subscribe to notifications
    blockchain = LevelDBBlockchain(settings.LEVELDB_PATH)
    Blockchain.RegisterBlockchain(blockchain)

    # Try to set up a notification db
    if NotificationDB.instance():
        NotificationDB.instance().start()

    # Start the prompt interface
    cli = PromptInterface()

    # Run
    reactor.suggestThreadPoolSize(15)
    reactor.callInThread(cli.run)
    NodeLeader.Instance().Start()
    reactor.run()
    def setUpClass(cls):

        settings.NOTIFICATION_DB_PATH = 'fixtures/' + str(uuid1())
        ndb = NotificationDB.instance()
        ndb.start()
Ejemplo n.º 34
0
def main():
    parser = argparse.ArgumentParser()

    group = parser.add_mutually_exclusive_group()
    group.add_argument("-m",
                       "--mainnet",
                       action="store_true",
                       default=False,
                       help="Use MainNet 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(
        "-t",
        "--set-default-theme",
        dest="theme",
        choices=["dark", "light"],
        help=
        "Set the default theme to be loaded from the config file. Default: 'dark'"
    )
    parser.add_argument(
        "--version",
        action="version",
        version="neo-python v{version}".format(version=__version__))

    args = parser.parse_args()

    # 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()
    elif args.coznet:
        settings.setup_coznet()

    if args.theme:
        preferences.set_theme(args.theme)

    # Instantiate the blockchain and subscribe to notifications
    blockchain = LevelDBBlockchain(settings.LEVELDB_PATH)
    Blockchain.RegisterBlockchain(blockchain)

    # Try to set up a notification db
    if NotificationDB.instance():
        NotificationDB.instance().start()

    # Start the prompt interface
    cli = PromptInterface()

    # Run things
    reactor.suggestThreadPoolSize(15)
    reactor.callInThread(cli.run)
    NodeLeader.Instance().Start()

    # reactor.run() is blocking, until `quit()` is called which stops the reactor.
    reactor.run()

    # After the reactor is stopped, gracefully shutdown the database.
    NotificationDB.close()
    Blockchain.Default().Dispose()
    NodeLeader.Instance().Shutdown()
Ejemplo n.º 35
0
    def tearDownClass(cls):

        super(NotificationDBTestCase, cls).tearDownClass()

        NotificationDB.instance().close()
        shutil.rmtree(cls.N_NOTIFICATION_DB_NAME)
Ejemplo n.º 36
0
 def tearDownClass(cls):
     NotificationDB.instance().close()
     shutil.rmtree(settings.NOTIFICATION_DB_PATH)
Ejemplo n.º 37
0
 def __init__(self):
     self.notif = NotificationDB.instance()
Ejemplo n.º 38
0
class PromptInterface(object):
    go_on = True

    _walletdb_loop = None

    Wallet = None

    _known_things = []

    commands = [
        'quit', 'help', 'block {index/hash} (tx)', 'header {index/hash}',
        'tx {hash}', 'asset {assetId}', 'asset search {query}',
        'contract {contract hash}', 'contract search {query}',
        'notifications {block_number or address}', 'mem', 'nodes', 'state',
        'config debug {on/off}', 'config sc-events {on/off}',
        'build {path/to/file.py} (test {params} {returntype} {needs_storage} {needs_dynamic_invoke} {test_params})',
        'load_run {path/to/file.avm} (test {params} {returntype} {needs_storage} {needs_dynamic_invoke} {test_params})',
        'import wif {wif}', 'import nep2 {nep2_encrypted_key}',
        'import contract {path/to/file.avm} {params} {returntype} {needs_storage} {needs_dynamic_invoke}',
        'import contract_addr {contract_hash} {pubkey}',
        'import watch_addr {address}', 'import token {token_contract_hash}',
        'export wif {address}', 'export nep2 {address}', 'open wallet {path}',
        'create wallet {path}', 'wallet {verbose}', 'wallet claim',
        'wallet migrate', 'wallet rebuild {start block}',
        'wallet delete_addr {addr}', 'wallet alias {addr} {title}',
        'wallet tkn_send {token symbol} {address_from} {address to} {amount} ',
        'wallet tkn_send_from {token symbol} {address_from} {address to} {amount}',
        'wallet tkn_approve {token symbol} {address_from} {address to} {amount}',
        'wallet tkn_allowance {token symbol} {address_from} {address to}',
        'wallet tkn_mint {token symbol} {mint_to_addr} (--attach-neo={amount}, --attach-gas={amount})',
        'wallet unspent', 'wallet close',
        'withdraw_request {asset_name} {contract_hash} {to_addr} {amount}',
        'withdraw holds # lists all current holds',
        'withdraw completed # lists completed holds eligible for cleanup',
        'withdraw cancel # cancels current holds',
        'witdraw cleanup # cleans up completed holds',
        'withdraw # withdraws the first hold availabe',
        'withdraw all # withdraw all holds available',
        'send {assetId or name} {address} {amount} (--from-addr={addr})',
        'sign {transaction in JSON format}',
        'testinvoke {contract hash} {params} (--attach-neo={amount}, --attach-gas={amount})',
        'debugstorage {on/off/reset}'
    ]

    history = FileHistory(FILENAME_PROMPT_HISTORY)

    token_style = None
    start_height = None
    start_dt = None

    def __init__(self):
        self.input_parser = InputParser()
        self.start_height = Blockchain.Default().Height
        self.start_dt = datetime.datetime.utcnow()

        self.token_style = style_from_dict({
            Token.Command:
            preferences.token_style['Command'],
            Token.Neo:
            preferences.token_style['Neo'],
            Token.Default:
            preferences.token_style['Default'],
            Token.Number:
            preferences.token_style['Number'],
        })

    def get_bottom_toolbar(self, cli=None):
        out = []
        try:
            out = [(Token.Command, '[%s] Progress: ' % settings.net_name),
                   (Token.Number, str(Blockchain.Default().Height)),
                   (Token.Neo, '/'),
                   (Token.Number, str(Blockchain.Default().HeaderHeight))]
        except Exception as e:
            pass

        return out

    def get_completer(self):

        standard_completions = [
            'block',
            'tx',
            'header',
            'mem',
            'neo',
            'gas',
            'help',
            'state',
            'nodes',
            'exit',
            'quit',
            'config',
            'import',
            'export',
            'open',
            'wallet',
            'contract',
            'asset',
            'wif',
            'watch_addr',
            'contract_addr',
            'testinvoke',
            'tkn_send',
            'tkn_mint',
            'tkn_send_from',
            'tkn_approve',
            'tkn_allowance',
            'build',
            'notifications',
        ]

        if self.Wallet:
            for addr in self.Wallet.Addresses:
                if addr not in self._known_things:
                    self._known_things.append(addr)
            for alias in self.Wallet.NamedAddr:
                if alias.Title not in self._known_things:
                    self._known_things.append(alias.Title)
            for tkn in self.Wallet.GetTokens().values():
                if tkn.symbol not in self._known_things:
                    self._known_things.append(tkn.symbol)

        all_completions = standard_completions + self._known_things

        completer = WordCompleter(all_completions)

        return completer

    def quit(self):
        print('Shutting down. This may take a bit...')
        self.go_on = False
        self.do_close_wallet()
        reactor.stop()

    def help(self):
        tokens = []
        for c in self.commands:
            tokens.append((Token.Command, "%s\n" % c))
        print_tokens(tokens, self.token_style)

    def do_open(self, arguments):
        if self.Wallet:
            self.do_close_wallet()

        item = get_arg(arguments)

        if item and item == 'wallet':

            path = get_arg(arguments, 1)

            if path:

                if not os.path.exists(path):
                    print("Wallet file not found")
                    return

                passwd = prompt("[password]> ", is_password=True)
                password_key = to_aes_key(passwd)

                try:
                    print(path)
                    self.Wallet = UserWallet.Open(path, password_key)

                    self._walletdb_loop = task.LoopingCall(
                        self.Wallet.ProcessBlocks)
                    self._walletdb_loop.start(1)
                    print("Opened wallet at bleeepp blooop %s" % path)
                except Exception as e:
                    print("Could not open wallet: %s" % e)

            else:
                print("Please specify a path")
        else:
            print("Please specify something to open")

    def do_create(self, arguments):
        item = get_arg(arguments)

        if item and item == 'wallet':

            path = get_arg(arguments, 1)

            if path:

                if os.path.exists(path):
                    print("File already exists")
                    return

                passwd1 = prompt("[password]> ", is_password=True)
                passwd2 = prompt("[password again]> ", is_password=True)

                if passwd1 != passwd2 or len(passwd1) < 10:
                    print(
                        "Please provide matching passwords that are at least 10 characters long"
                    )
                    return

                password_key = to_aes_key(passwd1)

                try:
                    self.Wallet = UserWallet.Create(path=path,
                                                    password=password_key)
                    contract = self.Wallet.GetDefaultContract()
                    key = self.Wallet.GetKey(contract.PublicKeyHash)
                    print("Wallet %s" %
                          json.dumps(self.Wallet.ToJson(), indent=4))
                    print("Pubkey %s" % key.PublicKey.encode_point(True))
                except Exception as e:
                    print("Exception creating wallet: %s" % e)
                    self.Wallet = None
                    if os.path.isfile(path):
                        try:
                            os.remove(path)
                        except Exception as e:
                            print("Could not remove {}: {}".format(path, e))
                    return

                if self.Wallet:
                    self._walletdb_loop = task.LoopingCall(
                        self.Wallet.ProcessBlocks)
                    self._walletdb_loop.start(1)

            else:
                print("Please specify a path")

    def do_close_wallet(self):
        if self.Wallet:
            path = self.Wallet._path
            self._walletdb_loop.stop()
            self._walletdb_loop = None
            self.Wallet.Close()
            self.Wallet = None
            print("Closed wallet %s" % path)

    def do_import(self, arguments):
        item = get_arg(arguments)

        if not item:
            print("Please specify something to import")
            return

        if item == 'wif':
            if not self.Wallet:
                print("Please open a wallet before importing WIF")
                return

            wif = get_arg(arguments, 1)
            if not wif:
                print("Please supply a valid WIF key")
                return

            try:
                prikey = KeyPair.PrivateKeyFromWIF(wif)
                key = self.Wallet.CreateKey(prikey)
                print("Imported key: %s" % wif)
                print("Pubkey: %s\n" % key.PublicKey.encode_point(True).hex())
                print("Wallet: %s" %
                      json.dumps(self.Wallet.ToJson(), indent=4))
            except ValueError as e:
                print(str(e))
            except Exception as e:
                print(str(e))

            return

        elif item == 'nep2':
            if not self.Wallet:
                print("Please open a wallet before importing a NEP2 key")
                return

            nep2_key = get_arg(arguments, 1)
            if not nep2_key:
                print("Please supply a valid NEP2 encrypted private key")
                return

            nep2_passwd = prompt("[key password]> ", is_password=True)

            try:
                prikey = KeyPair.PrivateKeyFromNEP2(nep2_key, nep2_passwd)
                key = self.Wallet.CreateKey(prikey)
                print("Imported NEP2 key: %s" % nep2_key)
                print("Pubkey: %s\n" % key.PublicKey.encode_point(True).hex())
                print("Wallet: %s" %
                      json.dumps(self.Wallet.ToJson(), indent=4))
            except ValueError as e:
                print(str(e))
            except Exception as e:
                print(str(e))

            return

        elif item == 'contract':
            return self.load_smart_contract(arguments)

        elif item == 'contract_addr':
            return ImportContractAddr(self.Wallet, arguments[1:])

        elif item == 'watch_addr':
            return ImportWatchAddr(self.Wallet, get_arg(arguments, 1))

        elif item == 'multisig_addr':
            return ImportMultiSigContractAddr(self.Wallet, arguments[1:])

        elif item == 'token':
            return ImportToken(self.Wallet, get_arg(arguments, 1))

        else:
            print("Import of '%s' not implemented" % item)

    def do_build(self, arguments):
        BuildAndRun(arguments, self.Wallet)

    def do_load_n_run(self, arguments):
        LoadAndRun(arguments, self.Wallet)

    def do_export(self, arguments):
        item = get_arg(arguments)

        if item == 'wif':
            if not self.Wallet:
                return print("Please open a wallet")

            address = get_arg(arguments, 1)
            if not address:
                return print("Please specify an address")

            passwd = prompt("[wallet password]> ", is_password=True)
            if not self.Wallet.ValidatePassword(passwd):
                return print("Incorrect password")

            keys = self.Wallet.GetKeys()
            for key in keys:
                if key.GetAddress() == address:
                    export = key.Export()
                    print("WIF key export: %s" % export)
            return

        elif item == 'nep2':
            if not self.Wallet:
                return print("Please open a wallet")

            address = get_arg(arguments, 1)
            if not address:
                return print("Please specify an address")

            passwd = prompt("[wallet password]> ", is_password=True)
            if not self.Wallet.ValidatePassword(passwd):
                return print("Incorrect password")

            nep2_passwd1 = prompt("[key password]> ", is_password=True)
            if len(nep2_passwd1) < 10:
                return print(
                    "Please provide a password with at least 10 characters")

            nep2_passwd2 = prompt("[key password again]> ", is_password=True)
            if nep2_passwd1 != nep2_passwd2:
                return print("Passwords do not match")

            keys = self.Wallet.GetKeys()
            for key in keys:
                export = key.ExportNEP2(nep2_passwd1)
                print("NEP2 key export: %s" % export)
            return

        print("Command export %s not found" % item)

    def make_withdraw_request(self, arguments):
        if not self.Wallet:
            print("Please open a wallet")
            return
        if len(arguments) == 4:
            RequestWithdrawFrom(self.Wallet, arguments[0], arguments[1],
                                arguments[2], arguments[3])
        else:
            print(
                "Incorrect arg length. Use 'withdraw_request {asset_id} {contract_hash} {to_addr} {amount}'"
            )

    def do_withdraw(self, arguments):
        if not self.Wallet:
            print("Please open a wallet")
            return

        item = get_arg(arguments, 0)

        if item:

            if item == 'holds':
                PrintHolds(self.Wallet)
            elif item == 'delete_holds':
                index_to_delete = -1
                if get_arg(arguments, 1) and int(get_arg(arguments, 1)) > -1:
                    index_to_delete = int(get_arg(arguments, 1))
                DeleteHolds(self.Wallet, index_to_delete)
            elif item == 'cancel_holds':
                if len(arguments) > 1:
                    CancelWithdrawalHolds(self.Wallet, get_arg(arguments, 1))
                else:
                    print("Please specify contract hash to cancel holds for")
            elif item == 'completed':
                ShowCompletedHolds(self.Wallet)
            elif item == 'cleanup':
                CleanupCompletedHolds(self.Wallet)
            elif item == 'all':
                WithdrawAll(self.Wallet)
        else:
            WithdrawOne(self.Wallet)

    def do_notifications(self, arguments):
        if NotificationDB.instance() is None:
            print("No notification DB Configured")
            return

        item = get_arg(arguments, 0)
        events = []
        if len(item) == 34:
            addr = item
            events = NotificationDB.instance().get_by_addr(addr)
        else:
            try:
                block_height = int(item)
                if block_height < Blockchain.Default().Height:
                    events = NotificationDB.instance().get_by_block(
                        block_height)
                else:
                    print("Block %s not found" % block_height)
                    return
            except Exception as e:
                print("Could not parse block height %s" % e)
                return

        if len(events):
            [print(json.dumps(e.ToJson(), indent=4)) for e in events]
        else:
            print("No events found for %s" % item)

    def show_wallet(self, arguments):
        if not self.Wallet:
            print("Please open a wallet")
            return

        item = get_arg(arguments)

        if not item:
            print("Wallet %s " % json.dumps(self.Wallet.ToJson(), indent=4))
            return

        if item in ['v', '--v', 'verbose']:
            print("Wallet %s " %
                  json.dumps(self.Wallet.ToJson(verbose=True), indent=4))
            return
        elif item == 'migrate' and self.Wallet is not None:
            self.Wallet.Migrate()
            print("Migrated wallet")
        elif item == 'delete_addr':
            addr_to_delete = get_arg(arguments, 1)
            DeleteAddress(self, self.Wallet, addr_to_delete)
        elif item == 'delete_token':
            token_to_delete = get_arg(arguments, 1)
            DeleteToken(self.Wallet, token_to_delete)
        elif item == 'close':
            self.do_close_wallet()
        elif item == 'claim':
            ClaimGas(self.Wallet, True, arguments[1:])
        elif item == 'rebuild':
            self.Wallet.Rebuild()
            try:
                item2 = int(get_arg(arguments, 1))
                if item2 and item2 > 0:
                    print("Restarting at %s" % item2)
                    self.Wallet._current_height = item2
            except Exception as e:
                pass
        elif item == 'tkn_send':
            token_send(self.Wallet, arguments[1:])
        elif item == 'tkn_send_from':
            token_send_from(self.Wallet, arguments[1:])
        elif item == 'tkn_approve':
            token_approve_allowance(self.Wallet, arguments[1:])
        elif item == 'tkn_allowance':
            token_get_allowance(self.Wallet, arguments[1:], verbose=True)
        elif item == 'tkn_mint':
            token_mint(self.Wallet, arguments[1:])
        elif item == 'tkn_register':
            token_crowdsale_register(self.Wallet, arguments[1:])
        elif item == 'unspent':
            ShowUnspentCoins(self.Wallet, arguments[1:])
        elif item == 'alias':
            if len(arguments) == 3:
                AddAlias(self.Wallet, arguments[1], arguments[2])
            else:
                print("Please supply an address and title")
        else:
            print("Wallet: '{}' is an invalid parameter".format(item))

    def do_send(self, arguments):
        construct_and_send(self, self.Wallet, arguments)

    def do_sign(self, arguments):
        jsn = get_arg(arguments)
        parse_and_sign(self, self.Wallet, jsn)

    def show_state(self):
        height = Blockchain.Default().Height
        headers = Blockchain.Default().HeaderHeight

        diff = height - self.start_height
        now = datetime.datetime.utcnow()
        difftime = now - self.start_dt

        mins = difftime / datetime.timedelta(minutes=1)

        bpm = 0
        if diff > 0 and mins > 0:
            bpm = diff / mins

        out = "Progress: %s / %s\n" % (height, headers)
        out += "Block-cache length %s\n" % Blockchain.Default().BlockCacheCount
        out += "Blocks since program start %s\n" % diff
        out += "Time elapsed %s mins\n" % mins
        out += "Blocks per min %s \n" % bpm
        tokens = [(Token.Number, out)]
        print_tokens(tokens, self.token_style)

    def show_nodes(self):
        if len(NodeLeader.Instance().Peers) > 0:
            out = ""
            for peer in NodeLeader.Instance().Peers:
                out += "Peer %s - IO: %s\n" % (peer.Name(), peer.IOStats())
            print_tokens([(Token.Number, out)], self.token_style)
        else:
            print("Not connected yet\n")

    def show_block(self, args):
        item = get_arg(args)
        txarg = get_arg(args, 1)
        if item is not None:
            block = Blockchain.Default().GetBlock(item)

            if block is not None:

                bjson = json.dumps(block.ToJson(), indent=4)
                tokens = [(Token.Number, bjson)]
                print_tokens(tokens, self.token_style)
                print('\n')
                if txarg and 'tx' in txarg:

                    for tx in block.FullTransactions:
                        print(json.dumps(tx.ToJson(), indent=4))

            else:
                print("Could not locate block %s" % item)
        else:
            print("please specify a block")

    def show_header(self, args):
        item = get_arg(args)
        if item is not None:
            header = Blockchain.Default().GetHeaderBy(item)
            if header is not None:
                print(json.dumps(header.ToJson(), indent=4))
            else:
                print("Could not locate header %s\n" % item)
        else:
            print("Please specify a header")

    def show_tx(self, args):
        if len(args):
            try:
                txid = UInt256.ParseString(get_arg(args))
                tx, height = Blockchain.Default().GetTransaction(txid)
                if height > -1:
                    jsn = tx.ToJson()
                    jsn['height'] = height
                    jsn['unspents'] = [
                        uns.ToJson(tx.outputs.index(uns))
                        for uns in Blockchain.Default().GetAllUnspent(txid)
                    ]
                    tokens = [(Token.Command, json.dumps(jsn, indent=4))]
                    print_tokens(tokens, self.token_style)
                    print('\n')
            except Exception as e:
                print("Could not find transaction from args: %s (%s)" %
                      (e, args))
        else:
            print("Please specify a TX hash")

    def show_account_state(self, args):
        item = get_arg(args)

        if item is not None:
            account = Blockchain.Default().GetAccountState(
                item, print_all_accounts=True)

            if account is not None:
                bjson = json.dumps(account.ToJson(), indent=4)
                tokens = [(Token.Number, bjson)]
                print_tokens(tokens, self.token_style)
                print('\n')
            else:
                print("Account %s not found" % item)
        else:
            print("Please specify an account address")

    def show_asset_state(self, args):
        item = get_arg(args)

        if item is not None:

            if item == 'search':
                query = get_arg(args, 1)
                results = Blockchain.Default().SearchAssetState(query)
                print("Found %s results for %s" % (len(results), query))
                for asset in results:
                    bjson = json.dumps(asset.ToJson(), indent=4)
                    tokens = [(Token.Number, bjson)]
                    print_tokens(tokens, self.token_style)
                    print('\n')

                return

            asset = Blockchain.Default().GetAssetState(item)

            if asset is not None:
                bjson = json.dumps(asset.ToJson(), indent=4)
                tokens = [(Token.Number, bjson)]
                print_tokens(tokens, self.token_style)
                print('\n')
            else:
                print("Asset %s not found" % item)
        else:
            print("Please specify an asset hash")

    def show_contract_state(self, args):
        item = get_arg(args)

        if item is not None:

            if item.lower() == 'all':
                contracts = Blockchain.Default().ShowAllContracts()
                print("Contracts: %s" % contracts)
            elif item.lower() == 'search':
                query = get_arg(args, 1)
                if query:

                    contracts = Blockchain.Default().SearchContracts(
                        query=query)
                    print("Found %s results for %s" % (len(contracts), query))
                    for contract in contracts:
                        bjson = json.dumps(contract.ToJson(), indent=4)
                        tokens = [(Token.Number, bjson)]
                        print_tokens(tokens, self.token_style)
                        print('\n')
                else:
                    print("Please specify a search query")
            else:
                contract = Blockchain.Default().GetContract(item)

                if contract is not None:
                    contract.DetermineIsNEP5()
                    jsn = contract.ToJson()
                    bjson = json.dumps(jsn, indent=4)
                    tokens = [(Token.Number, bjson)]
                    print_tokens(tokens, self.token_style)
                    print('\n')
        else:
            print("Please specify a contract")

    def test_invoke_contract(self, args):
        if not self.Wallet:
            print("Please open a wallet")
            return

        if args and len(args) > 0:
            tx, fee, results, num_ops = TestInvokeContract(self.Wallet, args)

            if tx is not None and results is not None:
                print(
                    "\n-------------------------------------------------------------------------------------------------------------------------------------"
                )
                print("Test invoke successful")
                print("Total operations: %s" % num_ops)
                print("Results %s" % [str(item) for item in results])
                print("Invoke TX GAS cost: %s" % (tx.Gas.value / Fixed8.D))
                print("Invoke TX fee: %s" % (fee.value / Fixed8.D))
                print(
                    "-------------------------------------------------------------------------------------------------------------------------------------\n"
                )
                print(
                    "Enter your password to continue and invoke on the network\n"
                )

                passwd = prompt("[password]> ", is_password=True)
                if not self.Wallet.ValidatePassword(passwd):
                    return print("Incorrect password")

                result = InvokeContract(self.Wallet, tx, fee)

                return
            else:
                print("Error testing contract invoke")
                return

        print("Please specify a contract to invoke")

    def load_smart_contract(self, args):
        if not self.Wallet:
            print("Please open a wallet")
            return

        function_code = LoadContract(args[1:])

        if function_code:

            contract_script = GatherContractDetails(function_code, self)

            if contract_script is not None:

                tx, fee, results, num_ops = test_invoke(
                    contract_script, self.Wallet, [])

                if tx is not None and results is not None:
                    print(
                        "\n-------------------------------------------------------------------------------------------------------------------------------------"
                    )
                    print("Test deploy invoke successful")
                    print("Total operations executed: %s" % num_ops)
                    print("Results %s " % [str(item) for item in results])
                    print("Deploy Invoke TX GAS cost: %s" %
                          (tx.Gas.value / Fixed8.D))
                    print("Deploy Invoke TX fee: %s" % (fee.value / Fixed8.D))
                    print(
                        "-------------------------------------------------------------------------------------------------------------------------------------\n"
                    )
                    print(
                        "Enter your password to continue and deploy this contract"
                    )

                    passwd = prompt("[password]> ", is_password=True)
                    if not self.Wallet.ValidatePassword(passwd):
                        return print("Incorrect password")

                    result = InvokeContract(self.Wallet, tx, Fixed8.Zero())

                    return
                else:
                    print("Test invoke failed")
                    print("TX is %s, results are %s" % (tx, results))
                    return

    def show_mem(self):
        process = psutil.Process(os.getpid())
        total = process.memory_info().rss
        totalmb = total / (1024 * 1024)
        out = "Total: %s MB\n" % totalmb
        out += "Total buffers: %s\n" % StreamManager.TotalBuffers()
        print_tokens([(Token.Number, out)], self.token_style)

    def handle_debug_storage(self, args):
        what = get_arg(args)

        if what == 'on':
            settings.USE_DEBUG_STORAGE = True
            print("Debug storage on")
        elif what == 'off':
            settings.USE_DEBUG_STORAGE = False
            print("Debug Storage off")
        elif what == 'reset':
            DebugStorage.instance().reset()
            print("Reset debug storage")
        else:
            print("Please specify on|off|reset")

    def configure(self, args):
        what = get_arg(args)

        if what == 'debug':
            c1 = get_arg(args, 1).lower()
            if c1 is not None:
                if c1 == 'on' or c1 == '1':
                    print("Debug logging is now enabled")
                    settings.set_loglevel(logging.DEBUG)
                if c1 == 'off' or c1 == '0':
                    print("Debug logging is now disabled")
                    settings.set_loglevel(logging.INFO)

            else:
                print("Cannot configure log. Please specify on|off")

        elif what == 'sc-events':
            c1 = get_arg(args, 1).lower()
            if c1 is not None:
                if c1 == 'on' or c1 == '1':
                    print("Smart contract event logging is now enabled")
                    settings.set_log_smart_contract_events(True)
                if c1 == 'off' or c1 == '0':
                    print("Smart contract event logging is now disabled")
                    settings.set_log_smart_contract_events(False)

            else:
                print("Cannot configure log. Please specify on|off")

        else:
            print(
                "Cannot configure %s try 'config sc-events on|off' or 'config debug on|off'",
                what)

    def run(self):
        dbloop = task.LoopingCall(Blockchain.Default().PersistBlocks)
        dbloop.start(.1)

        Blockchain.Default().PersistBlocks()

        tokens = [(Token.Neo, 'NEO'), (Token.Default, ' cli. Type '),
                  (Token.Command, '\'help\' '),
                  (Token.Default, 'to get started')]

        print_tokens(tokens, self.token_style)
        print('\n')

        while self.go_on:

            try:
                result = prompt(
                    "neo> ",
                    completer=self.get_completer(),
                    history=self.history,
                    get_bottom_toolbar_tokens=self.get_bottom_toolbar,
                    style=self.token_style,
                    refresh_interval=3)
            except EOFError:
                # Control-D pressed: quit
                return self.quit()
            except KeyboardInterrupt:
                # Control-C pressed: do nothing
                continue

            try:
                command, arguments = self.input_parser.parse_input(result)

                if command is not None and len(command) > 0:
                    command = command.lower()

                    if command == 'quit' or command == 'exit':
                        self.quit()
                    elif command == 'help':
                        self.help()
                    elif command == 'create':
                        self.do_create(arguments)
                    elif command == 'open':
                        self.do_open(arguments)
                    elif command == 'build':
                        self.do_build(arguments)
                    elif command == 'load_run':
                        self.do_load_n_run(arguments)
                    elif command == 'import':
                        self.do_import(arguments)
                    elif command == 'export':
                        self.do_export(arguments)
                    elif command == 'wallet':
                        self.show_wallet(arguments)
                    elif command == 'send':
                        self.do_send(arguments)
                    elif command == 'sign':
                        self.do_sign(arguments)
                    elif command == 'block':
                        self.show_block(arguments)
                    elif command == 'tx':
                        self.show_tx(arguments)
                    elif command == 'header':
                        self.show_header(arguments)
                    elif command == 'account':
                        self.show_account_state(arguments)
                    elif command == 'asset':
                        self.show_asset_state(arguments)
                    elif command == 'contract':
                        self.show_contract_state(arguments)
                    elif command == 'testinvoke':
                        self.test_invoke_contract(arguments)
                    elif command == 'withdraw_request':
                        self.make_withdraw_request(arguments)
                    elif command == 'withdraw':
                        self.do_withdraw(arguments)
                    elif command == 'notifications':
                        self.do_notifications(arguments)
                    elif command == 'mem':
                        self.show_mem()
                    elif command == 'nodes' or command == 'node':
                        self.show_nodes()
                    elif command == 'state':
                        self.show_state()
                    elif command == 'debugstorage':
                        self.handle_debug_storage(arguments)
                    elif command == 'config':
                        self.configure(arguments)
                    elif command is None:
                        print("Please specify a command")
                    else:
                        print("Command %s not found" % command)

            except Exception as e:

                print("Could not execute command: %s" % e)
                traceback.print_stack()
                traceback.print_exc()

    # Setup depending on command line arguments. By default, the testnet settings are already loaded.

    settings.setup_privnet()

    # Instantiate the blockchain and subscribe to notifications
    blockchain = LevelDBBlockchain(settings.LEVELDB_PATH)
    Blockchain.RegisterBlockchain(blockchain)

    # Try to set up a notification db
    if NotificationDB.instance():
        NotificationDB.instance().start()

    # Start the prompt interface
    #cli = PromptInterface()

    # Run things
    #reactor.suggestThreadPoolSize(15)
    #reactor.callInThread(cli.run)
    NodeLeader.Instance().Start()

    while True:
        f = open("com.txt", "r")
        file_input = f.read()
        f.close()
        #test 020707 07 True False 2 key value25
        if (file_input != ""):
            neo_args = file_input.split(';')
            print(neo_args)

            path = "privnet1"
            nargs = [
                '/Users/jacksonroberts/Desktop/TicketChain/test/RegisterPart.py'
            ]
            nargs.extend(neo_args)
            #print(nargs)

            Wallet = UserWallet.Open(path, to_aes_key("123123123123"))
            tx, result, total_ops, engine = BuildAndRun(nargs, Wallet)
            print(str(result))
            f = open("com.txt", "w")
            f.close()
            f = open("out.txt", "w")
            f.write(result)
            f.close()

        time.sleep(1)

    NotificationDB.close()
    Blockchain.Default().Dispose()
    NodeLeader.Instance().Shutdown()
    def setUpClass(cls):

        settings.NOTIFICATION_DB_PATH = os.path.join(
            settings.DATA_DIR_PATH, f"fixtures/{str(uuid1())}")
        ndb = NotificationDB.instance()
        ndb.start()
Ejemplo n.º 40
0
    def show_wallet(self, arguments):
        if not self.Wallet:
            print("Please open a wallet")
            return

        item = get_arg(arguments)

        if not item:
            print("Wallet %s " % json.dumps(self.Wallet.ToJson(), indent=4))
            return

        if item in ['v', '--v', 'verbose']:
            print("Wallet %s " %
                  json.dumps(self.Wallet.ToJson(verbose=True), indent=4))
            return
        elif item == 'migrate' and self.Wallet is not None:
            self.Wallet.Migrate()
            print("Migrated wallet")
        elif item == 'create_addr':
            addresses_to_create = get_arg(arguments, 1)
            CreateAddress(self, self.Wallet, addresses_to_create)
        elif item == 'delete_addr':
            addr_to_delete = get_arg(arguments, 1)
            DeleteAddress(self, self.Wallet, addr_to_delete)
        elif item == 'delete_token':
            token_to_delete = get_arg(arguments, 1)
            DeleteToken(self.Wallet, token_to_delete)
        elif item == 'close':
            self.do_close_wallet()
        elif item == 'claim':
            ClaimGas(self.Wallet, True, arguments[1:])
        elif item == 'rebuild':
            self.stop_wallet_loop()
            try:
                self.Wallet.Rebuild()
            finally:
                self.start_wallet_loop()
            try:
                item2 = int(get_arg(arguments, 1))
                if item2 and item2 > 0:
                    print("Restarting at %s" % item2)
                    self.Wallet._current_height = item2
            except Exception as e:
                pass
        elif item == 'tkn_send':
            token_send(self.Wallet, arguments[1:])
        elif item == 'tkn_send_from':
            token_send_from(self.Wallet, arguments[1:])
        elif item == 'tkn_approve':
            token_approve_allowance(self.Wallet, arguments[1:])
        elif item == 'tkn_allowance':
            token_get_allowance(self.Wallet, arguments[1:], verbose=True)
        elif item == 'tkn_mint':
            token_mint(self.Wallet, arguments[1:])
        elif item == 'tkn_register':
            token_crowdsale_register(self.Wallet, arguments[1:])
        elif item == 'tkn_history':
            notification_db = NotificationDB.instance()
            token_history(self.Wallet, notification_db, arguments[1:])
        elif item == 'unspent':
            ShowUnspentCoins(self.Wallet, arguments[1:])
        elif item == 'split':
            SplitUnspentCoin(self.Wallet, arguments[1:])
        elif item == 'alias':
            if len(arguments) == 3:
                AddAlias(self.Wallet, arguments[1], arguments[2])
            else:
                print("Please supply an address and title")
        else:
            print("Wallet: '{}' is an invalid parameter".format(item))
 def tearDownClass(cls):
     NotificationDB.instance().close()
     shutil.rmtree(settings.NOTIFICATION_DB_PATH)
Ejemplo n.º 42
0
    def setUpClass(cls):

        Blockchain.DeregisterBlockchain()

        super(BlockchainFixtureTestCase, cls).setUpClass()

        NodeLeader.Instance().Reset()
        NodeLeader.Instance().Setup()

        # setup Blockchain DB
        if not os.path.exists(cls.FIXTURE_FILENAME):
            logger.info(
                "downloading fixture block database from %s. this may take a while"
                % cls.FIXTURE_REMOTE_LOC)

            response = requests.get(cls.FIXTURE_REMOTE_LOC, stream=True)

            response.raise_for_status()
            os.makedirs(os.path.dirname(cls.FIXTURE_FILENAME), exist_ok=True)
            with open(cls.FIXTURE_FILENAME, 'wb+') as handle:
                for block in response.iter_content(1024):
                    handle.write(block)

        try:
            tar = tarfile.open(cls.FIXTURE_FILENAME)
            tar.extractall(path=settings.DATA_DIR_PATH)
            tar.close()
        except Exception as e:
            raise Exception(
                "Could not extract tar file - %s. You may want need to remove the fixtures file %s manually to fix this."
                % (e, cls.FIXTURE_FILENAME))

        if not os.path.exists(cls.leveldb_testpath()):
            raise Exception("Error downloading fixtures at %s" %
                            cls.leveldb_testpath())

        settings.setup_unittest_net()

        cls._blockchain = TestLevelDBBlockchain(path=cls.leveldb_testpath(),
                                                skip_version_check=True)
        Blockchain.RegisterBlockchain(cls._blockchain)

        # setup Notification DB
        if not os.path.exists(cls.N_FIXTURE_FILENAME):
            logger.info(
                "downloading fixture notification database from %s. this may take a while"
                % cls.N_FIXTURE_REMOTE_LOC)

            response = requests.get(cls.N_FIXTURE_REMOTE_LOC, stream=True)

            response.raise_for_status()
            with open(cls.N_FIXTURE_FILENAME, 'wb+') as handle:
                for block in response.iter_content(1024):
                    handle.write(block)

        try:
            tar = tarfile.open(cls.N_FIXTURE_FILENAME)
            tar.extractall(path=settings.DATA_DIR_PATH)
            tar.close()

        except Exception as e:
            raise Exception(
                "Could not extract tar file - %s. You may want need to remove the fixtures file %s manually to fix this."
                % (e, cls.N_FIXTURE_FILENAME))
        if not os.path.exists(cls.N_NOTIFICATION_DB_NAME):
            raise Exception("Error downloading fixtures at %s" %
                            cls.N_NOTIFICATION_DB_NAME)

        settings.NOTIFICATION_DB_PATH = cls.N_NOTIFICATION_DB_NAME
        ndb = NotificationDB.instance()
        ndb.start()
Ejemplo n.º 43
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

    # 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()

    if args.datadir:
        settings.set_data_dir(args.datadir)
    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.º 44
0
    def setUpClass(cls):

        settings.NOTIFICATION_DB_PATH = os.path.join(settings.DATA_DIR_PATH,
                                                     f"fixtures/{str(uuid1())}")
        ndb = NotificationDB.instance()
        ndb.start()
Ejemplo n.º 45
0
    def tearDownClass(cls):

        super(NotificationDBTestCase, cls).tearDownClass()

        NotificationDB.instance().close()
        shutil.rmtree(cls.N_NOTIFICATION_DB_NAME)
Ejemplo n.º 46
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.º 47
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")

    # If a wallet should be opened
    parser.add_argument("--wallet",
                        action="store",
                        help="Open wallet. Will allow you to use methods that require an open wallet")

    # 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:
        try:
            settings.set_max_peers(args.maxpeers)
            print("Maxpeers set to ", args.maxpeers)
        except ValueError:
            print("Please supply a positive integer for maxpeers")
            return  

    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")

    if args.wallet:
        if not os.path.exists(args.wallet):
            print("Wallet file not found")
            return

        passwd = os.environ.get('NEO_PYTHON_JSONRPC_WALLET_PASSWORD', None)
        if not passwd:
            passwd = prompt("[password]> ", is_password=True)

        password_key = to_aes_key(passwd)
        try:
            wallet = UserWallet.Open(args.wallet, password_key)

        except Exception as e:
            print(f"Could not open wallet {e}")
            return
    else:
        wallet = None

    # 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)

    def loopingCallErrorHandler(error):
        logger.info("Error in loop: %s " % error)

    # Instantiate the blockchain and subscribe to notifications
    blockchain = LevelDBBlockchain(settings.chain_leveldb_path)
    Blockchain.RegisterBlockchain(blockchain)

    start_block_persisting()

    # If a wallet is open, make sure it processes blocks
    if wallet:
        walletdb_loop = task.LoopingCall(wallet.ProcessBlocks)
        wallet_loop_deferred = walletdb_loop.start(1)
        wallet_loop_deferred.addErrback(loopingCallErrorHandler)

    # 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))
        try:
            rpc_class = load_class_from_path(settings.RPC_SERVER)
        except ValueError as err:
            logger.error(err)
            sys.exit()
        api_server_rpc = rpc_class(args.port_rpc, wallet=wallet)

        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()))

    if args.port_rest:
        logger.info("Starting REST api server on http://%s:%s" % (args.host, args.port_rest))
        try:
            rest_api = load_class_from_path(settings.REST_SERVER)
        except ValueError as err:
            logger.error(err)
            sys.exit()
        api_server_rest = rest_api()
        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()))

    reactor.addSystemEventTrigger('before', 'shutdown', stop_block_persisting)
    reactor.run()

    # After the reactor is stopped, gracefully shutdown the database.
    logger.info("Closing databases...")
    NotificationDB.close()
    Blockchain.Default().Dispose()
    NodeLeader.Instance().Shutdown()
    if wallet:
        wallet.Close()