Ejemplo n.º 1
0
 def _set_up(self):
     self._destroy_db()
     CONFIG.set('general', 'database', self.DATABASE_NAME)
     CONFIG.set('general', 'network', 'testnet')
     CONFIG.set('general', 'wallet_address', '3918807197700602162PR')
     CONFIG.set('bootstrap', 'bootstrap_nodes', '[]')
     CONFIG.set('developer', 'wallet_password', 'test1')
     self.clock = task.Clock()
     self.prisma = Prisma()
     self.prisma.callLater = self.clock.callLater
     self.prisma.start(False)
Ejemplo n.º 2
0
 def __init__(self):
     self.logger = logging.getLogger('Network')
     self.status = STATUS_INIT
     self.callLater = Prisma().callLater
     self.reactor = reactor
     self.factory = NetworkFactory()
     self.listen_port = CONFIG.getint('network', 'listen_port')
     self.listener = None
     self.node_id = self.get_node_id()
     self.get_peers_lc = None
     self.get_events_lc = None
     self.get_peers_timer = CONFIG.getint('network', 'get_peers_timer')
     self.get_events_timer = CONFIG.getint('network', 'get_events_timer')
     self.timeout = CONFIG.getint('network', 'timeout')
Ejemplo n.º 3
0
    def is_valid_node_ip(ip):
        """
        Validate node ip address.

        :param ip: An IPv4 address.
        :type ip: string
        :rtype: False: Is either a non valid IPv4 address or is an RFC1918-address.
        :rtype: string (IP address)
        """
        try:
            address = ipaddress.IPv4Address(ip)
        except ValueError:
            return False
        if address.is_private:
            if CONFIG.get('developer', 'developer_mode') is False:
                return False
        return ip
Ejemplo n.º 4
0
    def bootstrap(self):
        """
        Delete all peers and bootstrap the peers in the config file by connecting and asking
        them the peers they know.
        """
        self.status = STATUS_BOOTSTRAPPING

        # delete first all peers
        Prisma().db.delete_peers()

        # bootstrap each of the nodes
        bootstrap_nodes = json.loads(CONFIG.get('bootstrap',
                                                'bootstrap_nodes'))
        for bootstrap in bootstrap_nodes:
            host, port = bootstrap.split(":")
            self.bootstrap_peer(host, int(port))

        # get state from a random node
        self.download_state_from_random_peer()
Ejemplo n.º 5
0
 def __init__(self):
     self.port = CONFIG.getint('api', 'listen_port')
     self.factory = ApiFactory()
     self.listener = None
     self.push_info_lc = None
Ejemplo n.º 6
0
    def get_events_from_random_peer(self):
        """
        Gets a random a peer from the database and connects to it and asks for events.
        """
        # check first if ready
        if self.status != STATUS_READY:
            self.logger.info('Not ready, still bootstrapping.')
            return

        # check that we have enough peers
        peer_count = Prisma().db.count_peers()

        if peer_count < 3:
            if not CONFIG.getboolean('developer',
                                     'developer_mode') or peer_count < 1:
                self.logger.debug(
                    'Not enough peers found in the network, skipping...')
                return

        random_peer = Prisma().db.get_random_peer().pop()
        host = random_peer['host']
        port = random_peer['port']
        client = TCP4ClientEndpoint(self.reactor, host, port, self.timeout)
        d = client.connect(self.factory)

        # in case of connection ok, add the callbacks for get_peers and call send_get_peers
        def connection_ok(protocol):
            protocol.d = defer.Deferred()

            def get_events_ok(_):
                self.logger.info('Successfully got events from {0}:{1}'.format(
                    host, port))

            protocol.d.addCallback(get_events_ok)

            def get_events_error(reason):
                error_message = reason.getErrorMessage()
                self.logger.error(
                    'Error when getting events from {0}:{1}: {2}'.format(
                        host, port, error_message))
                protocol.close_connection()
                self.get_events_lc.reset()
                self.get_events_from_random_peer()

            protocol.d.addErrback(get_events_error)

            protocol.send_get_events()

        d.addCallback(connection_ok)

        # in case of connection error show in debug and try again
        def connection_error(reason):
            # in case of error remove the peer from the database
            addr = random_peer['host'] + ':' + str(random_peer['port'])
            self.logger.debug('Error while connecting to {0}: {1}'.format(
                addr, reason.getErrorMessage()))
            Prisma().db.delete_peer(random_peer['_id'])
            # then restart timer and try again get_peers_from_random_peer
            self.get_events_lc.reset()
            self.get_events_from_random_peer()

        d.addErrback(connection_error)
Ejemplo n.º 7
0
    def prompt_unlock(self):
        """
        Prompt user for unlocking a certain wallet by its address.

        :return: success: keys dictionary, no success: False
        """
        try:
            # verify if there is not an existing wallet then create a new wallet and continue
            if len(self.list_wallets()) == 0:
                print(
                    'You don\'t have any wallets. Let\'s create your first wallet.'
                )
                keys = self.create_wallet()
                print('Wallet created with address: ' + keys['address'])
                return keys

            # if wallet address is specified in the config file then just ask for a password, otherwise ask for an
            # address in the prompt
            if CONFIG.has_option('general', 'wallet_address'):
                wallet_address = CONFIG.get('general', 'wallet_address')
                if CONFIG.get('general',
                              'wallet_address') not in self.list_wallets():
                    raise Exception(
                        'Wallet provided in the config file does not exist.')
                self.logger.info(
                    'Unlocking wallet with address {0}'.format(wallet_address))
                # in case of dev mode we can have the password in the config file, otherwise ask for a password
                if CONFIG.getboolean('developer', 'developer_mode') and \
                        CONFIG.has_option('developer', 'wallet_password'):
                    keys = self.decrypt_keystore(
                        wallet_address,
                        CONFIG.get('developer', 'wallet_password'))
                    if keys:
                        return keys
                else:
                    while True:
                        password = getpass(prompt="Password: "******"Password can not be empty.")
            else:
                while True:
                    wallet_address = input("Wallet address: ")
                    if wallet_address and wallet_address in self.list_wallets(
                    ):
                        password = getpass(prompt="Password: "******"Password can not be empty.")
                    else:
                        self.logger.info("Wallet address does not exist.")
                        break
        except Exception as e:
            self.logger.error(
                'Error when unlocking wallet. Reason: {0}'.format(e))
        return False
Ejemplo n.º 8
0
def main():
    """
    Entry point
    """
    parser = argparse.ArgumentParser('Run a cryptograph manager.')
    parser.add_argument('--create',
                        action='store_true',
                        help='create a new wallet address')
    parser.add_argument('--list',
                        action='store_true',
                        help='list all wallet addresses')
    parser.add_argument('--wallet', help='wallet address')
    parser.add_argument('--listenport',
                        help='what port the manager should bind to')
    parser.add_argument('--apiport',
                        help='what port for the API should bind to')
    parser.add_argument('--database', help='mongodb database name')
    parser.add_argument('--prompt',
                        '-p',
                        action='store_true',
                        help='show prompt')
    parser.add_argument('--log', '-l', help='log into a file')
    parser.add_argument('--version', action='store_true', help='print version')
    parser.add_argument('-v', action='store_true', help='verbose')
    parser.add_argument('-vv', action='store_true', help='very verbose')
    args = parser.parse_args()

    if args.version:
        print('Prisma v{0}'.format(__version__))
        exit(0)

    # check version and ask for updating in case that is not updated.
    last_version = retrieve_last_version()
    if last_version and version.parse(last_version) > version.parse(
            __version__):
        print(
            'A newer version of Prisma is available ({0}), please update Prisma with pip3.'
            .format(last_version))
        choice = input(
            'Do you wish to continue anyway? (y/N): ').strip().lower()
        if choice != 'y':
            exit()

    wallet = Wallet()

    # create a new wallet if --create
    if args.create:
        try:
            keys = wallet.create_wallet()
            print('Wallet created with address: ' + keys['address'])
        except Exception as e:
            print(str(e))
        exit()

    # list wallet list if --list
    if args.list:
        print(wallet.list_wallets())
        exit()

    # set logger options
    if args.vv:
        logging.basicConfig(
            format=
            '[%(asctime)s] [%(levelname)-8s] [%(name)-10s] %(message)s [%(filename)s:%(lineno)d]',
            level=logging.DEBUG,
            filename=args.log)
    elif args.v:
        logging.basicConfig(format='[%(levelname)s] [%(name)s] %(message)s',
                            level=logging.INFO,
                            filename=args.log)

    observer = log.PythonLoggingObserver()
    observer.start()

    if args.listenport:
        CONFIG.set('network', 'listen_port', args.listenport)

    if args.apiport:
        CONFIG.set('api', 'listen_port', args.apiport)

    if args.wallet:
        CONFIG.set('general', 'wallet_address', args.wallet)

    if args.database:
        CONFIG.set('general', 'database', args.database)

    # preparing manager
    def signal_handler(sig, frame):
        Prisma().stop()

    signal.signal(signal.SIGINT, signal_handler)
    signal.signal(signal.SIGQUIT, signal_handler)

    # starting manager
    Prisma().start(args.prompt)
    reactor.run()