예제 #1
0
파일: caretaker.py 프로젝트: Haroenv/MrHyde
    def deactivate_repos(self):
        timestamp = int(time()-float(self.get_config().get_cleanup_time()))
        try:
            database = dbhandler.DbHandler(self.get_config().get_db_file())
            old_repos = database.list('repo', '', 'last_used < %s and active > 0' % timestamp)
            for repo in old_repos:
                logger.info('Deleting repo %s' % repo['path'])
                try:
                    rmtree(repo['path'])
                except OSError as exception:
                    logger.error(exception.strerror)
                finally:
                    # Set repo inactive
                    database.updateData('repo', "id='%s'" % repo['id'], 'active = 0')

                try:
                    rmtree(repo['deploy_path'])
                except OSError as exception:
                    logger.error(exception.strerror)

                makedirs(repo['deploy_path'], 0o755, True)
                try:
                    index_file_path = '/'.join([repo['deploy_path'], 'index.html'])
                    index_file = open(index_file_path, 'w')
                    index_file.write(self.__html_content % (int(self.get_config().get_cleanup_time())/60))
                except IOError as exception:
                    logger.error(exception.strerror)
                finally:
                    index_file.close()
        except SQLError:
            logger.error("Database error, we're in trouble!")
            raise
예제 #2
0
    def init_repository(self, url, diff, static_files, draft=True):
        try:
            database = dbhandler.DbHandler(self.cm().get_db_file())
            id = self.utils().generateId(self.cm().get_hash_size())
            repo_path = join(self.__base_dir, id)
            deploy_path = ''.join([
                self.cm().get_deploy_base_path(), id,
                self.cm().get_deploy_append_path()
            ])

            if self.utils().repository_exists(id):
                return None

            database.insertData('repo', id, repo_path, deploy_path, url,
                                int(time()), 1)
            shutil.copytree(OWN_PATH + '/redirector/', deploy_path)

            t = threading.Thread(target=self.init_repository_async,
                                 args=(id, deploy_path, repo_path, url, diff,
                                       static_files, draft))
            t.daemon = True
            t.start()

            return id, ''.join(
                ['http://', id, '.',
                 self.cm().get_base_url(), '/poller.html'])
        except SQLError as exception:
            logger.error(exception.__str__())
            raise
예제 #3
0
 def update_timestamp(self, id):
     try:
         database = dbhandler.DbHandler(self.cm().get_db_file())
         database.updateData('repo', "id = '%s'" % id, 'last_used=%s' % int(time.time()))
     except SQLError as exception:
         logger.error(exception.__str__())
         raise
예제 #4
0
파일: cog.py 프로젝트: skylar32/qsprite
 def __init__(self, bot):
     self.bot = bot
     self.levels = {}
     with open("./cogs/market/levels.csv", mode="r") as file:
         reader = csv.reader(file)
         self.levels = {int(row[1]): row[0] for row in reader} # {price: level name, ...}
     self.handler = dbhandler.DbHandler()
예제 #5
0
파일: repoutils.py 프로젝트: xmia1/MrHyde
 def get_expiration_date(self, id):
     try:
         database = dbhandler.DbHandler(self.cm().get_db_file())
         last_used = database.list('repo', 'last_used', "id='%s'" % id)[0]
         return last_used + (24 * 3600)
     except SQLError as exception:
         logger.error(exception.__str__())
         raise
예제 #6
0
 def delete_repository(self, id):
     try:
         database = dbhandler.DbHandler(self.cm().get_db_file())
         repo = database.list('repo', '', "id='%s'" % id)[0]
         rmtree(repo['path'])
         database.deleteData('repo', "id='%s'" % repo['id'])
     except OSError as exception:
         logger.error(exception.strerror)
         raise
     except SQLError as exception:
         logger.error(exception.__str__())
         raise
예제 #7
0
파일: caretaker.py 프로젝트: Haroenv/MrHyde
 def cleanup_subdomains(self):
     logger.info('Cleaning up subdomains.')
     try:
         database = dbhandler.DbHandler(self.get_config().get_db_file())
         old_repos = database.list('repo', '', 'active < 1')
         for repo in old_repos:
             try:
                 logger.info('Cleaning up deploy path %s' % repo['deploy_path'])
                 rmtree(repo['deploy_path'])
             except OSError as exception:
                 logger.error(exception.strerror)
             else:
                 database.deleteData('repo', "id='%s'" % repo['id'])
     except SQLError:
         logger.error("Database error, we're in trouble!")
         raise
예제 #8
0
 def update_repository(self, id, diff, draft=True):
     try:
         database = dbhandler.DbHandler(self.cm().get_db_file())
         repo_path = database.list('repo', 'path', "id='%s'" % id)[0]
         deploy_path = database.list('repo', 'deploy_path', "id='%s'" % id)[0]
         diff_file = self.fm().create_diff_file(id, diff)
         self.apply_diff(id, repo_path, diff_file)
         build_successful = self.jm().build(repo_path, deploy_path, draft)
         if build_successful:
             return (id, ''.join(['https://', id, '.', self.__base_url]))
         else:
             return (id, self.jm().get_errors())
     except OSError as exception:
         logger.error(exception.strerror)
         raise
     except SQLError as exception:
         logger.error(exception.__str__())
         raise
     except git.GitCommandError as exception:
         logger.error(exception.__str__())
         raise
예제 #9
0
파일: filemanager.py 프로젝트: xmia1/MrHyde
    def file_download(self, id, file_name):
        repo_id = id.split('/')[0]
        if id.split('/')[1:]:
            file_path = id.split('/')[1:][0]
        else:
            file_path = []

        try:
            database = dbhandler.DbHandler(self.cm().get_db_file())
            repo_path = database.list('repo', 'path', "id='%s'" % repo_id)[0]
            abs_path = '/'.join([repo_path, ''.join(file_path), file_name])
            if isfile(abs_path):
                return True
            else:
                return False
        except OSError as exception:
            logger.error(exception.strerror)
            raise
        except SQLError as exception:
            logger.error(exception.__str__())
            raise
예제 #10
0
파일: cog.py 프로젝트: skylar32/qsprite
 def __init__(self, bot):
     self.bot = bot
     self.handler = dbhandler.DbHandler()
예제 #11
0
def worker(host, port, node):
    logger = node.logger

    this_client = f"{host}:{port}"

    if node.IS_STOPPING:
        return

    dict_ip = {'ip': host}
    node.plugin_manager.execute_filter_hook('peer_ip', dict_ip)
    client_instance_worker = client.Client()

    if node.peers.is_banned(host) or dict_ip['ip'] == 'banned':
        node.logger.app_log.warning(f"IP {host} is banned, won't connect")
        return

    timeout_operation = 60  # timeout
    timer_operation = time.time()  # start counting

    try:

        s = socks.socksocket()

        if node.tor:
            s.setproxy(socks.PROXY_TYPE_SOCKS5, "127.0.0.1", 9050)
        # s.setblocking(0)
        s.connect((host, port))
        node.logger.app_log.info(f"Outbound: Connected to {this_client}")
        client_instance_worker.connected = True

        # communication starter

        send(s, "version")
        send(s, node.version)

        data = receive(s)

        if data == "ok":
            node.logger.app_log.info(
                f"Outbound: Node protocol version of {this_client} matches our client"
            )
        else:
            raise ValueError(
                f"Outbound: Node protocol version of {this_client} mismatch")

        send(s, "getversion")
        peer_version = receive(s)
        if peer_version not in node.version_allow:
            raise ValueError(
                f"Outbound: Incompatible peer version {peer_version} from {this_client}"
            )

        send(s, "hello")

        # communication starter

    except Exception as e:
        node.logger.app_log.info(f"Could not connect to {this_client}: {e}")
        return  # can return here, because no lists are affected yet

    node.peers.store_mainnet(host, peer_version)
    try:
        peer_ip = s.getpeername()[0]
    except:
        # Should not happen, extra safety
        node.logger.app_log.warning(
            "Outbound: Transport endpoint was not connected")
        return

    if this_client not in node.peers.connection_pool:
        node.peers.append_client(this_client)
        node.logger.app_log.info(f"Connected to {this_client}")
        node.logger.app_log.info(
            f"Current active pool: {node.peers.connection_pool}")

    if not node.peers.is_banned(host) and node.peers.version_allowed(
            host, node.version_allow) and not node.IS_STOPPING:
        db_handler_instance = dbhandler.DbHandler(node.index_db,
                                                  node.ledger_path,
                                                  node.hyper_path, node.ram,
                                                  node.ledger_ram_file, logger)

    while not node.peers.is_banned(host) and node.peers.version_allowed(
            host, node.version_allow) and not node.IS_STOPPING:
        try:
            #ensure_good_peer_version(host)

            data = receive(s)  # receive data, one and the only root point
            # print(data)

            if data == "peers":
                subdata = receive(s)  # dict of "ip":"port"
                node.peers.peersync(subdata)

            elif data == "sync":
                if not time.time() <= timer_operation + timeout_operation:
                    timer_operation = time.time()  # reset timer

                try:
                    while len(node.syncing) >= 3:
                        if node.IS_STOPPING:
                            return
                        time.sleep(int(node.pause))

                    node.syncing.append(peer_ip)
                    # sync start

                    # send block height, receive block height
                    send(s, "blockheight")

                    node.logger.app_log.info(
                        f"Outbound: Sending block height to compare: {node.hdd_block}"
                    )
                    # append zeroes to get static length
                    send(s, node.hdd_block)

                    received_block_height = receive(
                        s)  # receive node's block height
                    node.logger.app_log.info(
                        f"Outbound: Node {peer_ip} is at block height: {received_block_height}"
                    )

                    if int(received_block_height) < node.hdd_block:
                        node.logger.app_log.warning(
                            f"Outbound: We have a higher block ({node.hdd_block}) than {peer_ip} ({received_block_height}), sending"
                        )

                        data = receive(s)  # receive client's last block_hash

                        # send all our followup hashes
                        node.logger.app_log.info(
                            f"Outbound: Will seek the following block: {data}")

                        # consensus pool 2 (active connection)
                        consensus_blockheight = int(received_block_height)
                        node.peers.consensus_add(peer_ip,
                                                 consensus_blockheight, s,
                                                 node.hdd_block)
                        # consensus pool 2 (active connection)

                        client_block = db_handler_instance.block_height_from_hash(
                            data)

                        if not client_block:
                            node.logger.app_log.warning(
                                f"Outbound: Block {data[:8]} of {peer_ip} not found"
                            )
                            if node.full_ledger:
                                send(s, "blocknf")
                            else:
                                send(s, "blocknfhb")
                            send(s, data)

                            if node.peers.warning(s, peer_ip, "Forked", 1):
                                raise ValueError(f"{peer_ip} is banned")

                        else:
                            node.logger.app_log.warning(
                                f"Outbound: Node is at block {client_block}"
                            )  # now check if we have any newer

                            if node.hdd_hash == data or not node.egress:
                                if not node.egress:
                                    node.logger.app_log.warning(
                                        f"Outbound: Egress disabled for {peer_ip}"
                                    )
                                    time.sleep(int(
                                        node.pause))  # reduce CPU usage
                                else:
                                    node.logger.app_log.info(
                                        f"Outbound: Node {peer_ip} has the latest block"
                                    )
                                    # TODO: this is unlikely to happen due to conditions above, consider removing
                                send(s, "nonewblk")

                            else:
                                blocks_fetched = db_handler_instance.blocksync(
                                    client_block)

                                node.logger.app_log.info(
                                    f"Outbound: Selected {blocks_fetched}")

                                send(s, "blocksfnd")

                                confirmation = receive(s)

                                if confirmation == "blockscf":
                                    node.logger.app_log.info(
                                        "Outbound: Client confirmed they want to sync from us"
                                    )
                                    send(s, blocks_fetched)

                                elif confirmation == "blocksrj":
                                    node.logger.app_log.info(
                                        "Outbound: Client rejected to sync from us because we're dont have the latest block"
                                    )

                    elif int(received_block_height) >= node.hdd_block:
                        if int(received_block_height) == node.hdd_block:
                            node.logger.app_log.info(
                                f"Outbound: We have the same block as {peer_ip} ({received_block_height}), hash will be verified"
                            )
                        else:
                            node.logger.app_log.warning(
                                f"Outbound: We have a lower block ({node.hdd_block}) than {peer_ip} ({received_block_height}), hash will be verified"
                            )

                        node.logger.app_log.info(
                            f"Outbound: block_hash to send: {node.hdd_hash}")
                        send(s, node.hdd_hash)

                        #ensure_good_peer_version(host)

                        # consensus pool 2 (active connection)
                        consensus_blockheight = int(
                            received_block_height
                        )  # str int to remove leading zeros
                        node.peers.consensus_add(peer_ip,
                                                 consensus_blockheight, s,
                                                 node.hdd_block)
                        # consensus pool 2 (active connection)

                except Exception as e:
                    node.logger.app_log.warning(f"Outbound: Sync failed {e}")
                finally:
                    node.syncing.remove(peer_ip)

            elif data == "blocknfhb":  # one of the possible outcomes
                block_hash_delete = receive(s)
                # print peer_ip
                # if max(consensus_blockheight_list) == int(received_block_height):
                if int(received_block_height) == node.peers.consensus_max:

                    blocknf(node,
                            block_hash_delete,
                            peer_ip,
                            db_handler_instance,
                            hyperblocks=True)

                    if node.peers.warning(s, peer_ip, "Rollback", 2):
                        raise ValueError(f"{peer_ip} is banned")

                sendsync(s, peer_ip, "Block not found", node)

            elif data == "blocknf":  # one of the possible outcomes
                block_hash_delete = receive(s)
                # print peer_ip
                # if max(consensus_blockheight_list) == int(received_block_height):
                if int(received_block_height) == node.peers.consensus_max:

                    blocknf(node, block_hash_delete, peer_ip,
                            db_handler_instance)

                    if node.peers.warning(s, peer_ip, "Rollback", 2):
                        raise ValueError(f"{peer_ip} is banned")

                sendsync(s, peer_ip, "Block not found", node)

            elif data == "blocksfnd":
                node.logger.app_log.info(
                    f"Outbound: Node {peer_ip} has the block(s)"
                )  # node should start sending txs in this step

                # node.logger.app_log.info("Inbound: Combined segments: " + segments)
                # print peer_ip
                if node.db_lock.locked():
                    node.logger.app_log.warning(
                        f"Skipping sync from {peer_ip}, syncing already in progress"
                    )

                else:
                    if int(node.last_block_timestamp) < (time.time() - 600):
                        block_req = node.peers.consensus_most_common
                        node.logger.app_log.warning(
                            "Most common block rule triggered")

                    else:
                        block_req = node.peers.consensus_max
                        node.logger.app_log.warning(
                            "Longest chain rule triggered")

                    #ensure_good_peer_version(host)

                    if int(received_block_height) >= block_req and int(
                            received_block_height) > node.last_block:
                        try:  # they claim to have the longest chain, things must go smooth or ban
                            node.logger.app_log.warning(
                                f"Confirming to sync from {peer_ip}")

                            send(s, "blockscf")
                            segments = receive(s)
                            #ensure_good_peer_version(host)

                        except:
                            if node.peers.warning(
                                    s, peer_ip,
                                    "Failed to deliver the longest chain", 2):
                                raise ValueError(f"{peer_ip} is banned")
                        else:
                            digest_block(node, segments, s, peer_ip,
                                         db_handler_instance)

                            # receive theirs
                    else:
                        send(s, "blocksrj")
                        node.logger.app_log.warning(
                            f"Inbound: Distant peer {peer_ip} is at {received_block_height}, should be at least {max(block_req,node.last_block+1)}"
                        )

                sendsync(s, peer_ip, "Block found", node)

                # block_hash validation end

            elif data == "nonewblk":
                # send and receive mempool
                if mp.MEMPOOL.sendable(peer_ip):
                    mempool_txs = mp.MEMPOOL.tx_to_send(peer_ip)
                    # node.logger.app_log.info("Outbound: Extracted from the mempool: " + str(mempool_txs))  # improve: sync based on signatures only
                    # if len(mempool_txs) > 0: #wont sync mempool until we send something, which is bad
                    # send own
                    send(s, "mempool")
                    send(s, mempool_txs)
                    # send own
                    # receive theirs
                    segments = receive(s)

                    node.logger.app_log.info(
                        mp.MEMPOOL.merge(segments, peer_ip,
                                         db_handler_instance.c, True))

                    # receive theirs
                    # Tell the mempool we just send our pool to a peer
                    mp.MEMPOOL.sent(peer_ip)
                sendsync(s, peer_ip, "No new block", node)

            elif data == "hyperlane":
                pass

            else:
                if data == '*':
                    raise ValueError("Broken pipe")
                raise ValueError(
                    f"Unexpected error, received: {str(data)[:32]}")

        except Exception as e:
            """
            exc_type, exc_obj, exc_tb = sys.exc_info()
            fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
            print(exc_type, fname, exc_tb.tb_lineno)
            """

            db_handler_instance.close()

            # remove from active pool
            node.peers.remove_client(this_client)
            node.logger.app_log.warning(
                f"Outbound: Disconnected from {this_client}: {e}")
            # remove from active pool

            # remove from consensus 2
            node.peers.consensus_remove(peer_ip)
            # remove from consensus 2

            node.logger.app_log.info(
                f"Connection to {this_client} terminated due to {e}")
            node.logger.app_log.info(
                f"---thread {threading.currentThread()} ended---")

            # properly end the connection
            s.close()

            # properly end the connection
            if node.debug:
                raise  # major debug client
            else:
                node.logger.app_log.info(f"Ending thread, because {e}")
                return

    if not node.peers.version_allowed(host, node.version_allow):
        node.logger.app_log.warning(
            f"Outbound: Ending thread, because {host} has too old a version: {node.peers.ip_to_mainnet[host]}"
        )
예제 #12
0
파일: worker.py 프로젝트: RajaMBZ/Bismuth
def worker(host, port, node):
    logger = node.logger

    this_client = f"{host}:{port}"

    if node.IS_STOPPING:
        return

    dict_ip = {'ip': host}
    node.plugin_manager.execute_filter_hook('peer_ip', dict_ip)
    client_instance_worker = classes.Client()

    if node.peers.is_banned(host) or dict_ip['ip'] == 'banned':
        client_instance_worker.banned = True
        node.logger.app_log.warning(f"IP {host} is banned, won't connect")
        return

    timeout_operation = 60  # timeout
    timer_operation = time.time()  # start counting

    try:

        s = socks.socksocket()

        if node.tor_conf:
            s.setproxy(socks.PROXY_TYPE_SOCKS5, "127.0.0.1", 9050)
        # s.setblocking(0)
        s.connect((host, port))
        node.logger.app_log.info(f"Outbound: Connected to {this_client}")
        client_instance_worker.connected = True

        # communication starter

        send(s, "version")
        send(s, node.version)

        data = receive(s)

        if data == "ok":
            node.logger.app_log.info(
                f"Outbound: Node protocol version of {this_client} matches our client"
            )
        else:
            raise ValueError(
                f"Outbound: Node protocol version of {this_client} mismatch")

        # If we are post pow fork, then the peer has getversion command
        # if node.last_block >= POW_FORK - FORK_AHEAD:
        # Peers that are not up to date will disconnect since they don't know that command.
        # That is precisely what we need :D
        send(s, "getversion")
        peer_version = receive(s)
        if peer_version not in node.version_allow:
            raise ValueError(
                f"Outbound: Incompatible peer version {peer_version} from {this_client}"
            )

        send(s, "hello")

        # communication starter

    except Exception as e:
        node.logger.app_log.info(f"Could not connect to {this_client}: {e}")
        return  # can return here, because no lists are affected yet

    # if node.last_block >= POW_FORK - FORK_AHEAD:
    node.peers.store_mainnet(host, peer_version)
    try:
        peer_ip = s.getpeername()[0]
    except:
        # Should not happen, extra safety
        node.logger.app_log.warning(
            "Outbound: Transport endpoint was not connected")
        return

    if this_client not in node.peers.connection_pool:
        node.peers.append_client(this_client)
        node.logger.app_log.info(f"Connected to {this_client}")
        node.logger.app_log.info(
            f"Current active pool: {node.peers.connection_pool}")

    if not client_instance_worker.banned and node.peers.version_allowed(
            host, node.version_allow) and not node.IS_STOPPING:
        db_handler_instance = dbhandler.DbHandler(
            node.index_db, node.ledger_path_conf, node.hyper_path_conf,
            node.full_ledger, node.ram_conf, node.ledger_ram_file, logger)

    while not client_instance_worker.banned and node.peers.version_allowed(
            host, node.version_allow) and not node.IS_STOPPING:
        try:
            #ensure_good_peer_version(host)

            data = receive(s)  # receive data, one and the only root point
            # print(data)

            if data == "peers":
                subdata = receive(s)
                node.peers.peersync(subdata)

            elif data == "sync":
                if not time.time() <= timer_operation + timeout_operation:
                    timer_operation = time.time()  # reset timer

                try:
                    while len(node.syncing) >= 3:
                        if node.IS_STOPPING:
                            return
                        time.sleep(int(node.pause_conf))

                    node.syncing.append(peer_ip)
                    # sync start

                    # send block height, receive block height
                    send(s, "blockheight")

                    db_handler_instance.execute(
                        db_handler_instance.c,
                        'SELECT max(block_height) FROM transactions')
                    db_block_height = db_handler_instance.c.fetchone()[0]

                    node.logger.app_log.info(
                        f"Outbound: Sending block height to compare: {db_block_height}"
                    )
                    # append zeroes to get static length
                    send(s, db_block_height)

                    received_block_height = receive(
                        s)  # receive node's block height
                    node.logger.app_log.info(
                        f"Outbound: Node {peer_ip} is at block height: {received_block_height}"
                    )

                    if int(received_block_height) < db_block_height:
                        node.logger.app_log.warning(
                            f"Outbound: We have a higher block ({db_block_height}) than {peer_ip} ({received_block_height}), sending"
                        )

                        data = receive(s)  # receive client's last block_hash

                        # send all our followup hashes
                        node.logger.app_log.info(
                            f"Outbound: Will seek the following block: {data}")

                        # consensus pool 2 (active connection)
                        consensus_blockheight = int(received_block_height)
                        node.peers.consensus_add(peer_ip,
                                                 consensus_blockheight, s,
                                                 node.last_block)
                        # consensus pool 2 (active connection)

                        try:
                            db_handler_instance.execute_param(
                                db_handler_instance.h3,
                                "SELECT block_height FROM transactions WHERE block_hash = ?;",
                                (data, ))
                            client_block = db_handler_instance.h3.fetchone()[0]
                        except Exception:
                            node.logger.app_log.warning(
                                f"Outbound: Block {data[:8]} of {peer_ip} not found"
                            )
                            send(s, "blocknf")
                            send(s, data)

                        else:

                            node.logger.app_log.info(
                                f"Outbound: Node is at block {client_block}"
                            )  # now check if we have any newer

                            db_handler_instance.execute(
                                db_handler_instance.h3,
                                'SELECT block_hash FROM transactions ORDER BY block_height DESC LIMIT 1'
                            )
                            db_block_hash = db_handler_instance.h3.fetchone()[
                                0]  # get latest block_hash

                            if db_block_hash == data or not node.egress:
                                if not node.egress:
                                    node.logger.app_log.warning(
                                        f"Outbound: Egress disabled for {peer_ip}"
                                    )
                                    time.sleep(int(
                                        node.pause_conf))  # reduce CPU usage
                                else:
                                    node.logger.app_log.info(
                                        f"Outbound: Node {peer_ip} has the latest block"
                                    )
                                    # TODO: this is unlikely to happen due to conditions above, consider removing
                                send(s, "nonewblk")

                            else:
                                blocks_fetched = []
                                while sys.getsizeof(
                                        str(blocks_fetched)
                                ) < 500000:  # limited size based on txs in blocks
                                    # db_handler.execute_param(db_handler.h3, ("SELECT block_height, timestamp,address,recipient,amount,signature,public_key,keep,openfield FROM transactions WHERE block_height > ? AND block_height <= ?;"),(str(int(client_block)),) + (str(int(client_block + 1)),))
                                    db_handler_instance.execute_param(
                                        db_handler_instance.h3,
                                        ("SELECT timestamp,address,recipient,amount,signature,public_key,operation,openfield FROM transactions WHERE block_height > ? AND block_height <= ?;"
                                         ), (
                                             str(int(client_block)),
                                             str(int(client_block + 1)),
                                         ))
                                    result = db_handler_instance.h3.fetchall()
                                    if not result:
                                        break
                                    blocks_fetched.extend([result])
                                    client_block = int(client_block) + 1

                                # blocks_send = [[l[1:] for l in group] for _, group in groupby(blocks_fetched, key=itemgetter(0))]  # remove block number

                                node.logger.app_log.info(
                                    f"Outbound: Selected {blocks_fetched}")

                                send(s, "blocksfnd")

                                confirmation = receive(s)

                                if confirmation == "blockscf":
                                    node.logger.app_log.info(
                                        "Outbound: Client confirmed they want to sync from us"
                                    )
                                    send(s, blocks_fetched)

                                elif confirmation == "blocksrj":
                                    node.logger.app_log.info(
                                        "Outbound: Client rejected to sync from us because we're dont have the latest block"
                                    )

                    elif int(received_block_height) >= db_block_height:
                        if int(received_block_height) == db_block_height:
                            node.logger.app_log.info(
                                f"Outbound: We have the same block as {peer_ip} ({received_block_height}), hash will be verified"
                            )
                        else:
                            node.logger.app_log.warning(
                                f"Outbound: We have a lower block ({db_block_height}) than {peer_ip} ({received_block_height}), hash will be verified"
                            )

                        db_handler_instance.execute(
                            db_handler_instance.c,
                            'SELECT block_hash FROM transactions ORDER BY block_height DESC LIMIT 1'
                        )
                        db_block_hash = db_handler_instance.c.fetchone()[
                            0]  # get latest block_hash

                        node.logger.app_log.info(
                            f"Outbound: block_hash to send: {db_block_hash}")
                        send(s, db_block_hash)

                        #ensure_good_peer_version(host)

                        # consensus pool 2 (active connection)
                        consensus_blockheight = int(
                            received_block_height
                        )  # str int to remove leading zeros
                        node.peers.consensus_add(peer_ip,
                                                 consensus_blockheight, s,
                                                 node.last_block)
                        # consensus pool 2 (active connection)

                except Exception as e:
                    node.logger.app_log.info(f"Outbound: Sync failed {e}")
                finally:
                    node.syncing.remove(peer_ip)

            elif data == "blocknf":  # one of the possible outcomes
                block_hash_delete = receive(s)
                # print peer_ip
                # if max(consensus_blockheight_list) == int(received_block_height):
                if int(received_block_height) == node.peers.consensus_max:

                    blocknf(node, block_hash_delete, peer_ip,
                            db_handler_instance)

                    if node.peers.warning(s, peer_ip, "Rollback", 2):
                        raise ValueError(f"{peer_ip} is banned")

                sendsync(s, peer_ip, "Block not found", False, node)

            elif data == "blocksfnd":
                node.logger.app_log.info(
                    f"Outbound: Node {peer_ip} has the block(s)"
                )  # node should start sending txs in this step

                # node.logger.app_log.info("Inbound: Combined segments: " + segments)
                # print peer_ip
                if node.db_lock.locked():
                    node.logger.app_log.warning(
                        f"Skipping sync from {peer_ip}, syncing already in progress"
                    )

                else:
                    db_handler_instance.execute(
                        db_handler_instance.c,
                        "SELECT timestamp FROM transactions WHERE reward != 0 ORDER BY block_height DESC LIMIT 1;"
                    )  # or it takes the first
                    node.last_block_timestamp = quantize_two(
                        db_handler_instance.c.fetchone()[0])

                    if int(node.last_block_timestamp) < (time.time() - 600):
                        block_req = node.peers.consensus_most_common
                        node.logger.app_log.warning(
                            "Most common block rule triggered")

                    else:
                        block_req = node.peers.consensus_max
                        node.logger.app_log.warning(
                            "Longest chain rule triggered")

                    #ensure_good_peer_version(host)

                    if int(received_block_height) >= block_req:
                        try:  # they claim to have the longest chain, things must go smooth or ban
                            node.logger.app_log.warning(
                                f"Confirming to sync from {peer_ip}")

                            send(s, "blockscf")
                            segments = receive(s)
                            #ensure_good_peer_version(host)

                        except:
                            if node.peers.warning(
                                    s, peer_ip,
                                    "Failed to deliver the longest chain", 2):
                                raise ValueError(f"{peer_ip} is banned")

                        else:
                            digest_block(node, segments, s, peer_ip,
                                         db_handler_instance)
                            # receive theirs
                    else:
                        send(s, "blocksrj")
                        node.logger.app_log.warning(
                            f"Inbound: Distant peer {peer_ip} is at {received_block_height}, should be at least {block_req}"
                        )

                sendsync(s, peer_ip, "Block found", True, node)

                # block_hash validation end

            elif data == "nonewblk":
                # send and receive mempool
                if mp.MEMPOOL.sendable(peer_ip):
                    mempool_txs = mp.MEMPOOL.tx_to_send(peer_ip)
                    # node.logger.app_log.info("Outbound: Extracted from the mempool: " + str(mempool_txs))  # improve: sync based on signatures only
                    # if len(mempool_txs) > 0: #wont sync mempool until we send something, which is bad
                    # send own
                    send(s, "mempool")
                    send(s, mempool_txs)
                    # send own
                    # receive theirs
                    segments = receive(s)
                    node.logger.app_log.info(
                        mp.MEMPOOL.merge(segments, peer_ip,
                                         db_handler_instance.c, True))
                    # receive theirs
                    # Tell the mempool we just send our pool to a peer
                    mp.MEMPOOL.sent(peer_ip)
                sendsync(s, peer_ip, "No new block", True, node)

            elif data == "hyperlane":
                pass

            else:
                if data == '*':
                    raise ValueError("Broken pipe")
                raise ValueError(
                    f"Unexpected error, received: {str(data)[:32]}")

        except Exception as e:
            """
            exc_type, exc_obj, exc_tb = sys.exc_info()
            fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
            print(exc_type, fname, exc_tb.tb_lineno)
            """

            # remove from active pool
            node.peers.remove_client(this_client)
            node.logger.app_log.warning(
                f"Outbound: Disconnected from {this_client}: {e}")
            # remove from active pool

            # remove from consensus 2
            node.peers.consensus_remove(peer_ip)
            # remove from consensus 2

            node.logger.app_log.info(
                f"Connection to {this_client} terminated due to {e}")
            node.logger.app_log.info(
                f"---thread {threading.currentThread()} ended---")

            # properly end the connection
            s.close()
            # properly end the connection
            if node.debug_conf:
                raise  # major debug client
            else:
                node.logger.app_log.info(f"Ending thread, because {e}")
                return

    if not node.peers.version_allowed(host, node.version_allow):
        node.logger.app_log.warning(
            f"Outbound: Ending thread, because {host} has too old a version: {node.peers.ip_to_mainnet[host]}"
        )
예제 #13
0
 def list_repositories(self):
     database = dbhandler.DbHandler(self.cm().get_db_file())
     dir_list = [[f['path'].split('/')[-1], f['url']] for f in database.list('repo') if isdir(f['path'])]
     return dir_list
예제 #14
0
                except Exception as e:
                    node.logger.app_log.warning("Exception {}".format(e))

                node.logger.app_log.warning(
                    "Processing of {} finished".format(token))
        except:
            node.logger.app_log.warning("Error parsing")

        db_handler_instance.index.commit()


if __name__ == "__main__":
    from libs import node, logger
    import dbhandler

    node = node.Node()
    node.debug_level = "WARNING"
    node.terminal_output = True

    node.logger = logger.Logger()
    node.logger.app_log = log.log("local_test.log", node.debug_level,
                                  node.terminal_output)
    node.logger.app_log.warning("Configuration settings loaded")

    db_handler = dbhandler.DbHandler("static/index_local_test.db",
                                     "static/ledger.db", "static/hyper.db",
                                     False, None, node.logger, False)

    tokens_update(node, db_handler)
    # tokens_update("tokens.db","reindex")