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")
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)
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))
def test_logger(): loggerutil.debug("test_logging_debug") loggerutil.info("test_logging_info") loggerutil.warning("test_logging_warning") loggerutil.error("test_logging_error")
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