def add_transaction(self, transaction):
     if isinstance(transaction, Transaction):
         self.transactions[transaction.hash()] = transaction.string()
     elif isinstance(transaction, str):
         self.transactions[hashutil.hash_string(transaction)] = transaction
     else:
         loggerutil.error(
             "attempted to pool tx that was neither string nor Transaction object")
 def handle_new_tx(self, tx):
     """handles tx received from the p2p network"""
     if isinstance(tx, Transaction):
         handle_new_transaction(tx)
     elif isinstance(tx, VotingTokenTransaction):
         handle_new_vtx(tx)
     else:
         loggerutil.error("received tx that was neither tx nor vtx")
 def handle_new_block(self, block):
     """handles blocks received from the p2p network"""
     if isinstance(block, MainBlock):
         handle_new_main_block(block)
     elif isinstance(block, ShardBlock):
         handle_new_shard_block(block)
     else:
         loggerutil.error(
             "received block that was neither main nor shard block")
Пример #4
0
def load_block_by_height(height: int) -> str:
    """loads a block by height/number and returns the json-string of this block"""
    block_path = str(Path(__file__).parent.parent.parent) + \
        "/.data/blocks/" + str(height) + ".block"
    if not os.path.isfile(block_path):
        loggerutil.error("could not load block for height " + str(height))
        raise ValueError("there is no block at height " + str(height))
    # read the block from file
    with open("{0}".format(block_path), "r") as block_file:
        return block_file.read()
def save_nonce(nonce: int):
    """saves the nonce"""
    wallet_path = str(Path(__file__).parent.parent.parent) + "/.data/wallet/"
    if not os.path.isdir(wallet_path):
        msg = "cannot save nonce to non existing wallet, try generating a wallet first"
        loggerutil.error(msg)
        raise ValueError(msg)
    # save nonce
    with open("{0}/nonce".format(wallet_path), "w") as nonce_file:
        print("{}".format(nonce), file=nonce_file)
def load_wallet() -> Wallet:
    """opens the locally saved wallet"""
    wallet_path = str(Path(__file__).parent.parent.parent) + "/.data/wallet/"
    if not os.path.isdir(wallet_path):
        msg = "cannot open non existing wallet, try generating a wallet first"
        loggerutil.error(msg)
        raise ValueError(msg)
    # read private key
    with open("{0}/private".format(wallet_path), "rb") as private_file:
        private_key = private_file.read()
        private_key = ecdsa.SigningKey.from_der(private_key)
    # read nonce as string
    with open("{0}/nonce".format(wallet_path), "r") as nonce_file:
        nonce = int(nonce_file.read())
    # generate the wallet
    return Wallet(private_key, nonce)
def save_block(height: int, block_json_string: str, block_hash: str):
    """saves a block and updates the list of height:hash for resolution of height from hash"""
    block_path = str(Path(__file__).parent.parent.parent) + \
        "/.data/blocks/"
    Path(block_path).mkdir(parents=True, exist_ok=True)
    # if there is a dicionary for height:block_hash
    if os.path.isfile("{0}/hash.dictionary".format(block_path)):
        # check if there is already a block for given height
        if "{}:".format(height) in open("{0}/hash.dictionary".format(block_path)).read():
            loggerutil.error("could not save block " + block_json_string +
                             " because there is already a block at height " + str(height))
            raise ValueError(
                "there is already a block at height " + str(height))

    # update the dicionary for height:hash
    with open("{0}/hash.dictionary".format(block_path), "a") as hash_file:
        print("{0}:{1}".format(str(height), block_hash), file=hash_file)
    # save the block as json
    with open("{0}/{1}.block".format(block_path, str(height)), "w") as block_file:
        print("{}".format(block_json_string), file=block_file)
Пример #8
0
def load_block_by_hash(block_hash: str) -> str:
    """loads the height/number of a block from the dicionary, returns load_block_by_height(said height)"""
    hash_path = str(Path(__file__).parent.parent.parent) + \
        "/.data/blocks/hash.dictionary"
    # open the block_hash database
    if not os.path.isfile(hash_path):
        loggerutil.error("could not load the block_hash database")
        raise ValueError("there is no block_hash database")
    try:
        with open(hash_path, "r") as hash_file:
            for line in hash_file:
                # read all lines and compare to block_hash
                if line.split(":")[1].replace("\n", "") == block_hash:
                    # if found return block for height
                    return load_block_by_height(int(line.split(":")[0]))
            loggerutil.error("could not load block with hash " + block_hash)
            raise ValueError("there is no block with hash " + block_hash +
                             " in block database")
    except Exception as e:
        loggerutil.error("error loading block_hash: " + str(e))
        raise ValueError("error loading block_hash: " + str(e))
Пример #9
0
def test_logger():
    loggerutil.debug("test_logging_debug")
    loggerutil.info("test_logging_info")
    loggerutil.warning("test_logging_warning")
    loggerutil.error("test_logging_error")
Пример #10
0
    def manage_events() -> bool:
        """
        Manages all functionality that has to be asynchronous. 
        All these events can be set by the p2p api, the client then handles these events in its own thread

        returns a bool that is only True if the client needs to be shut down in case of an error
        """
        # get data from the p2p
        if self.event_manager.block_received.isSet():
            block = p2p_api.get_recv_block()
            # do stuff
            self.event_manager.block_received.clear()

        if self.event_manager.tx_received.isSet():
            tx = p2p_api.get_recv_tx()
            # do stuff
            self.event_manager.tx_received.clear()

        if self.event_manager.tx_pool_received.isSet():
            tx_pool = p2p_api.get_recv_tx_pool()
            # do stuff
            self.event_manager.tx_pool_received.clear()

        if self.event_manager.bootstr_received.isSet():
            bootstr = p2p_api.get_recv_bootstr()
            # do stuff
            self.event_manager.bootstr_received.clear()

        # give data to the p2p
        if self.event_manager.height_request.isSet():
            p2p_api.send_height(my_height)
            # do stuff
            self.event_manager.height_request.clear()

        if self.event_manager.block_request.isSet():
            # returns list of block numbers
            number_list = p2p_api.get_requ_block_numbers()
            for number in number_list:
                p2p_api.send_block(number, the_block_to_number)
            # do stuff
            self.event_manager.block_request.clear()

        if self.event_manager.tx_request.isSet():
            # do stuff
            self.event_manager.tx_request.clear()

        if self.event_manager.tx_pool_request.isSet():
            p2p_api.send_pool(self.pool.string())
            self.event_manager.tx_pool_request.clear()

        if self.event_manager.bootstr_request.isSet():
            from_block_number, to_block_number, reciever = p2p_api.get_requ_bootstr_numbers(
            )
            temp = []
            # fill temp with the blocks from and to
            p2p_api.send_bootstr(reciever, temp)
            # do stuff
            self.event_manager.bootstr_request.clear()

        if self.event_manager.connection_lost.isSet():
            # reconnect maybe ?
            # do stuff
            self.event_manager.connection_lost.clear()

        if self.event_manager.error.isSet():
            loggerutil.error(p2p_api.get_error_message())
            # shut down the client after logging the error
            p2p_api.stop_peer(self.peer)
            return True

        return False