def __broadcast_tx(stored_tx_item): # logging.debug("BroadcastProcess : broadcast tx ") result_add_tx = None for peer_target in list(__audience): # logging.debug("peer_target: " + peer_target) stub_item = __audience[peer_target] try: response = stub_item.call_async( "AddTx", loopchain_pb2.TxSend(tx=stored_tx_item)) # logging.info("broadcast response: " + str(response)) if stub_item.target == __process_variables[ self.LEADER_PEER_TARGET_KEY]: if response is not None: result_add_tx = response if response.response_code != message_code.Response.success: # TODO leader 에게 전송한 tx 가 실패하는 경우에는 예외처리를 할 것인가? # stored_tx.put(stored_tx_item) # raise Exception(result_add_tx.message) pass except Exception as e: logging.warning("gRPC Exception: " + str(e)) logging.warning(f"Fail tx broadcast to: " + peer_target) return result_add_tx
def __handler_create_tx(create_tx_param): stub_to_leader = __process_variables[ self.PROCESS_VARIABLE_STUB_TO_LEADER] # logging.debug(f"TxProcess create_tx.... leader.target({stub_to_leader.target})") tx = pickle.dumps(create_tx_param) try: if __process_variables[ self. PROCESS_VARIABLE_PEER_STATUS] == PeerProcessStatus.leader_complained: stored_tx.put(tx) logging.warning( "Leader is complained your tx just stored in queue by temporally: " + str(stored_tx.qsize())) else: create_tx_continue(stub_to_leader) result_add_tx = stub_to_leader.call( "AddTx", loopchain_pb2.TxSend(tx=tx), is_stub_reuse=True) if result_add_tx.response_code != message_code.Response.success: raise Exception(result_add_tx.message) except Exception as e: logging.warning( f"in peer_process::create_tx target({stub_to_leader.target}) Exception: " + str(e)) stored_tx.put(tx) __process_variables[ self. PROCESS_VARIABLE_PEER_STATUS] = PeerProcessStatus.leader_complained
def __handler_create_tx(self, request, context): # logging.debug("TxService handler create tx") tx = request.object tx_object = pickle.loads(tx) # logging.debug(f"TxService got tx({tx_object.get_tx_hash()})") try: if self.__peer_status == PeerProcessStatus.leader_complained: self.__stored_tx.put(tx) logging.warning( "Leader is complained your tx just stored in queue by temporally: " + str(self.__stored_tx.qsize())) else: self.__create_tx_continue() result_add_tx = self.__stub_to_leader.call( "AddTx", loopchain_pb2.TxSend(tx=tx), is_stub_reuse=True) if result_add_tx.response_code != message_code.Response.success: raise Exception(result_add_tx.message) except Exception as e: logging.warning( f"in tx service create_tx target({self.__stub_to_leader.target}) Exception: " + str(e)) self.__stored_tx.put(tx) self.__peer_status = PeerProcessStatus.leader_complained # TODO leader complain 방식 변경중 임시로 현재 트리거는 중단한다. # stub_to_self_peer.call_in_time( # "NotifyLeaderBroken", # loopchain_pb2.CommonRequest(request="Fail Add Tx to Leader") # ) return loopchain_pb2.Message(code=message_code.Response.success)
def create_tx_continue(stub_to_leader): # 저장된 작업이 있으면 전송한다. while not stored_tx.empty(): stored_tx_item = stored_tx.get() result_add_tx = stub_to_leader.call_in_times( "AddTx", loopchain_pb2.TxSend(tx=stored_tx_item), is_stub_reuse=True) if result_add_tx is None and result_add_tx.response_code != message_code.Response.success: stored_tx.put(stored_tx_item) raise Exception(result_add_tx.message)
def __broadcast_tx(stored_tx_item: TxItem): # logging.debug(f"({self.__process_name}): broadcast tx audience({len(__audience)})") result_add_tx = None for peer_target in list(__audience): # logging.debug("peer_target: " + peer_target) stub_item = __audience[peer_target] stub_item.call_async( "AddTx", loopchain_pb2.TxSend(tx=stored_tx_item.tx_dump, channel=stored_tx_item.channel_name)) return result_add_tx
def get_tx_message(self): message = loopchain_pb2.TxSend(tx_json=self.__tx_json, channel=self.channel) return message