def main(): loop = asyncio.get_event_loop() # because a KeyboardInterrupt is so violent it can shutdown the DB in an unpredictable state. loop.add_signal_handler(SIGINT, system_exit) main_task = loop.create_task(setup_and_start(loop)) try: loop.run_forever() except SystemExit: p2p = NetworkService() loop.run_until_complete(p2p.shutdown()) loop.run_until_complete(shutdown()) loop.run_until_complete(loop.shutdown_asyncgens()) loop.stop() finally: loop.close() logger.info("Closing databases...") NotificationDB.close() Blockchain.Default().Dispose() wallet = main_task.result() if wallet: wallet.Close()
async def setup_and_start(loop): # Use TestNet settings.setup_privnet() # Setup the blockchain blockchain = LevelDBBlockchain(settings.chain_leveldb_path) Blockchain.RegisterBlockchain(blockchain) p2p = NetworkService() loop.create_task(p2p.start()) bg_task = loop.create_task(custom_background_code()) # Disable smart contract events for external smart contracts settings.set_log_smart_contract_events(False) app = web.Application() app.add_routes([ web.route('*', '/', home_route), web.get("/echo-get/{msg}", echo_msg), web.post("/echo-post/", echo_post), ]) runner = web.AppRunner(app) await runner.setup() site = web.TCPSite(runner, "0.0.0.0", API_PORT) await site.start() # Run all the things (blocking call) logger.info("Everything setup and running. Waiting for events...") return site
def main(): # Use TestNet settings.setup_testnet() # Setup the blockchain blockchain = LevelDBBlockchain(settings.chain_leveldb_path) Blockchain.RegisterBlockchain(blockchain) loop = asyncio.get_event_loop() # Start a reoccurring task with custom code loop.create_task(custom_background_code()) p2p = NetworkService() loop.create_task(p2p.start()) # block from here on loop.run_forever()
async def setup_and_start(loop): # Use TestNet settings.setup_testnet() # Setup the blockchain blockchain = LevelDBBlockchain(settings.chain_leveldb_path) Blockchain.RegisterBlockchain(blockchain) p2p = NetworkService() loop.create_task(p2p.start()) bg_task = loop.create_task(custom_background_code()) # Disable smart contract events for external smart contracts settings.set_log_smart_contract_events(False) # Run all the things (blocking call) logger.info("Everything setup and running. Waiting for events...") return bg_task
def run(self): # bl: changing to 15 so that we can get connections with a high number to improve transaction relayability settings.set_max_peers(15) loop = asyncio.get_event_loop() # because a KeyboardInterrupt is so violent it can shutdown the DB in an unpredictable state. loop.add_signal_handler(SIGINT, quit) loop.add_signal_handler(SIGHUP, quit) loop.add_signal_handler(SIGTERM, quit) # Disable smart contract events for external smart contracts settings.set_log_smart_contract_events(False) # Instantiate the blockchain and subscribe to notifications blockchain = Blockchain( DBFactory.getBlockchainDB(settings.chain_leveldb_path)) Blockchain.RegisterBlockchain(blockchain) # Try to set up a notification db if NotificationDB.instance(): NotificationDB.instance().start() # if the wallet was set up (by setting a path and loading the password), then open it! if self.wallet_path: self.wallet_open() # invoke any pre-start action that needs to occur before we start the loop. # optional for subclasses to implement. self.pre_start() blockchain_main_task = loop.create_task(self.run_loop()) p2p = NetworkService() loop.create_task(p2p.start()) async def shutdown(): all_tasks = asyncio.all_tasks() for task in all_tasks: task.cancel() with suppress(asyncio.CancelledError): await task try: loop.run_forever() except (SystemExit, KeyboardInterrupt): with suppress((SystemExit, Exception)): blockchain_main_task.exception() loop.run_until_complete(p2p.shutdown()) loop.run_until_complete(shutdown()) loop.run_until_complete(loop.shutdown_asyncgens()) loop.stop() finally: loop.close() # Run things if self.wallet_path: logger.info("Closing wallet file %s" % self.wallet_path) asyncio.run(self.wallet_close()) # After the reactor is stopped, gracefully shutdown the database. logger.info("Closing databases...") NotificationDB.close() Blockchain.Default().Dispose()
async def setup_and_start(loop): 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 + 1), 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("--minpeers", action="store", type=int, choices=range(1, 10 + 1), metavar="[1-10]", help="Min peers to use for P2P Joining") parser.add_argument("--maxpeers", action="store", type=int, choices=range(1, 10 + 1), metavar="[1-10]", 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() raise SystemExit if args.port_rpc == args.port_rest: print("Error: --port-rpc and --port-rest cannot be the same") parser.print_help() raise SystemExit if args.logfile and (args.syslog or args.syslog_local): print("Error: Cannot only use logfile or syslog at once") parser.print_help() raise SystemExit # 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() def set_min_peers(num_peers) -> bool: try: settings.set_min_peers(num_peers) print("Minpeers set to ", num_peers) return True except ValueError: print("Please supply a positive integer for minpeers") return False def set_max_peers(num_peers) -> bool: try: settings.set_max_peers(num_peers) print("Maxpeers set to ", num_peers) return True except ValueError: print("Please supply a positive integer for maxpeers") return False minpeers = args.minpeers maxpeers = args.maxpeers if minpeers and maxpeers: if minpeers > maxpeers: print("minpeers setting cannot be bigger than maxpeers setting") return if not set_min_peers(minpeers) or not set_max_peers(maxpeers): return elif minpeers: if not set_min_peers(minpeers): return if minpeers > settings.CONNECTED_PEER_MAX: if not set_max_peers(minpeers): return elif maxpeers: if not set_max_peers(maxpeers): return if maxpeers < settings.CONNECTED_PEER_MIN: if not set_min_peers(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: try: passwd = prompt("[password]> ", is_password=True) except KeyboardInterrupt: print("Wallet opening cancelled") return password_key = to_aes_key(passwd) try: wallet = UserWallet.Open(args.wallet, password_key) asyncio.create_task( wallet.sync_wallet(start_block=wallet._current_height)) 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() # Instantiate the blockchain and subscribe to notifications blockchain = Blockchain(getBlockchainDB()) Blockchain.RegisterBlockchain(blockchain) p2p = NetworkService() p2p_task = loop.create_task(p2p.start()) loop.create_task(custom_background_code()) NotificationDB.instance().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(wallet=wallet) runner = web.AppRunner(api_server_rpc.app) await runner.setup() site = web.TCPSite(runner, args.host, args.port_rpc) await site.start() 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() runner = web.AppRunner(api_server_rest.app) await runner.setup() site = web.TCPSite(runner, args.host, args.port_rpc) await site.start() return wallet
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( "-u", "--unittest", 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("-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("--minpeers", action="store", type=int, choices=range(1, 10 + 1), metavar="[1-10]", help="Min peers to use for P2P Joining") parser.add_argument("--maxpeers", action="store", type=int, default=5, choices=range(1, 10 + 1), metavar="[1-10]", 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() # 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) # 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() elif args.unittest: settings.setup_unittest_net() # Logfile settings & setup logfile_fn = os.path.join(settings.DATA_DIR_PATH, 'prompt.log') logfile_max_bytes = 5e7 # 50 MB logfile_backup_count = 3 # 3 logfiles history settings.set_logfile(logfile_fn, logfile_max_bytes, logfile_backup_count) if args.theme: preferences.set_theme(args.theme) if args.verbose: settings.set_log_smart_contract_events(True) def set_min_peers(num_peers) -> bool: try: settings.set_min_peers(num_peers) print("Minpeers set to ", num_peers) return True except ValueError: print("Please supply a positive integer for minpeers") return False def set_max_peers(num_peers) -> bool: try: settings.set_max_peers(num_peers) print("Maxpeers set to ", num_peers) return True except ValueError: print("Please supply a positive integer for maxpeers") return False minpeers = args.minpeers maxpeers = args.maxpeers if minpeers and maxpeers: if minpeers > maxpeers: print("minpeers setting cannot be bigger than maxpeers setting") return if not set_min_peers(minpeers) or not set_max_peers(maxpeers): return elif minpeers: if not set_min_peers(minpeers): return if minpeers > settings.CONNECTED_PEER_MAX: if not set_max_peers(minpeers): return elif maxpeers: if not set_max_peers(maxpeers): return if maxpeers < settings.CONNECTED_PEER_MIN: if not set_min_peers(maxpeers): return loop = asyncio.get_event_loop() # put prompt_toolkit on top of asyncio to avoid blocking use_asyncio_event_loop() # Instantiate the blockchain and subscribe to notifications blockchain = Blockchain( DBFactory.getBlockchainDB(settings.chain_leveldb_path)) Blockchain.RegisterBlockchain(blockchain) # Try to set up a notification db if NotificationDB.instance(): NotificationDB.instance().start() # Start the prompt interface fn_prompt_history = os.path.join(settings.DATA_DIR_PATH, '.prompt.py.history') cli = PromptInterface(fn_prompt_history) cli_task = loop.create_task(cli.run()) p2p = NetworkService() loop.create_task(p2p.start()) async def shutdown(): all_tasks = asyncio.all_tasks() for task in all_tasks: task.cancel() with suppress(asyncio.CancelledError): await task # prompt_toolkit hack for not cleaning up see: https://github.com/prompt-toolkit/python-prompt-toolkit/issues/787 old_attrs = termios.tcgetattr(sys.stdin) try: loop.run_forever() except SystemExit: pass finally: with suppress(asyncio.InvalidStateError): app = prompt_toolkit_get_app() if app.is_running: app.exit() with suppress((SystemExit, Exception)): cli_task.exception() loop.run_until_complete(p2p.shutdown()) loop.run_until_complete(shutdown()) loop.run_until_complete(loop.shutdown_asyncgens()) loop.stop() loop.close() # Run things # After the reactor is stopped, gracefully shutdown the database. NotificationDB.close() Blockchain.Default().Dispose() # clean up prompt_toolkit mess, see above termios.tcsetattr(sys.stdin, termios.TCSANOW, old_attrs)