def is_error_response(self, response): if response is None: raise BcosError(-1, None, "response is None") result = response["result"] if isinstance(result, dict) and "error" in result.keys(): msg = result["error"]["message"] code = result["error"]["code"] data = None if("data" in result["error"]): data = result["error"]["data"] self.logger.error("is_error_response code: {}, msg:{} ,data:{}".format(code, msg, data)) raise BcosError(code, data, msg) return None
def make_request(self, method, params, type=ChannelPack.TYPE_RPC): stat = StatTool.begin() rpc_data = self.encode_rpc_request(method,params) self.logger.debug("request rpc_data : {}".format(rpc_data) ) #print("request rpc_data", rpc_data) request_pack = ChannelPack(type,ChannelPack.make_seq32(), 0,rpc_data) res = self.send_pack(request_pack) starttime = time.time() responsematch = False while time.time() - starttime < 10: # spend max 10 sec to wait a correct response try: theQueue = self.recvThread.getQueue(ChannelPack.TYPE_RPC) responsepack = theQueue.get(block=True, timeout=3) # pop msg from queue except Empty as e: continue #print("got a pack from queue, detail:{}".format(responsepack.detail())) self.logger.debug("got a pack from queue, detail:{}".format(responsepack.detail())) if responsepack.type == ChannelPack.TYPE_RPC and responsepack.seq == request_pack.seq: responsematch = True break else: #print("*******SKIP!!!! pack ", responsepack.detail()) self.logger.debug("*******SKIP!!!! pack {}".format( responsepack.detail() )) responsepack = None continue if responsematch == False: raise BcosError(102,None,"timeout") result = responsepack.result data = responsepack.data.decode("utf-8") msg = "success" if(result!=0): if result in self.errorMsg: msg = "unknow error %d"%result msg = self.errorMsg[result] raise BcosError(result,msg) response = FriendlyJsonSerde().json_decode(data) stat.done() stat.debug("make_request:{}".format(method) ) self.logger.debug("GetResponse. %s, Response: %s", method, response) #print("response from server:",response) self.logger.debug("response from server: {}".format( response) ) if "result" not in response: tempresp =dict() tempresp["result"] = response response =tempresp return response
def common_request(self, cmd, params, packet_type=ChannelPack.TYPE_RPC): response = None try: next(self.request_counter) stat = StatTool.begin() if client_config.client_protocol == client_config.PROTOCOL_RPC: response = self.rpc.make_request(cmd, params) if client_config.client_protocol == client_config.PROTOCOL_CHANNEL: response = self.channel_handler.make_channel_rpc_request( cmd, params, ChannelPack.TYPE_RPC, packet_type) self.is_error_response(response) memo = "DONE" stat.done() stat.debug("commonrequest:{}:{}".format(cmd, memo)) return response["result"] except Exception as e: # timeout exception exception_str = str(e).lower() if "timeout" in exception_str: raise BcosException( ("{} timeout for without response after 60s, " "please check the status of the node").format(cmd)) else: raise BcosError(-1, None, ( "{} failed," " params: {}, response: {}, error information: {}").format( cmd, params, json.dumps(response), e))
def rpc_sendRawTransactionGetReceipt(self, to_address, contract_abi, fn_name, args=None, bin_data=None, gasPrice=30000000, timeout=15): # print("sendRawTransactionGetReceipt",args) stat = StatTool.begin() txid = self.sendRawTransaction(to_address, contract_abi, fn_name, args, bin_data, gasPrice) result = None for i in range(0, timeout): result = self.getTransactionReceipt(txid) # print("getTransactionReceipt : ", result) if result is None: time.sleep(1) self.logger.info( "sendRawTransactionGetReceipt,retrying getTransactionReceipt : {}".format(i)) continue else: break # get the result break stat.done() memo = "DONE" if result is None: memo = "ERROR:TIMEOUT" stat.debug("sendRawTransactionGetReceipt,{}".format(memo)) if result is None: raise BcosError(-1, None, "sendRawTransactionGetReceipt,{}".format(memo)) return result
def is_error_reponse(self, response): if response == None: e = BcosError(-1, None, "response is None") return e if ("error" in response): msg = response["error"]["message"] code = response["error"]["code"] data = None if ("data" in response["error"]): data = response["error"]["data"] self.logger.error( "is_error_reponse code: {}, msg:{} ,data:{}".format( code, msg, data)) e = BcosError(code, data, msg) return e return None
def send_transaction_getReceipt(self, fn_name, fn_args, gasPrice=30000000, deploy=False): """ send transactions to CNS contract with the givn function name and args """ try: contract_abi, args = self.format_args(fn_name, fn_args, deploy) contract_bin = None if deploy is True and os.path.exists( self.contract_bin_path) is True: with open(self.contract_bin_path) as f: contract_bin = f.read() if contract_bin is not None and len(contract_bin) > 0x40000: raise BcosException( ("contract bin size overflow," " limit: 0x40000(256K), size: {})").format( len(contract_bin), 16)) receipt = super().sendRawTransactionGetReceipt( self.contract_addr, contract_abi, fn_name, args, contract_bin, gasPrice) # check status if "status" not in receipt.keys() or \ "output" not in receipt.keys(): raise BcosError(-1, None, ("send transaction failed" "for empty status and output," "transaction receipt:{}").format(receipt)) status = receipt["status"] if int(status, 16) != 0 or receipt["output"] is None: raise TransactionException( receipt, ("send transaction failed," "status: {}, gasUsed: {}," " (not enough gas?)" " (non-exist contract address?)").format( status, receipt["gasUsed"])) if fn_name is not None and fn_args is not None: output = common.parse_output(receipt["output"], fn_name, contract_abi, args) else: output = None return (receipt, output) except BcosError as e: self.logger.error( "send transaction failed, fn_name: {}, fn_args:{}, error_info:{}" .format(fn_name, fn_args, e)) raise e except CompileError as e: self.logger.error( ("send transaction failed for compile soldity failed," "contract_path {}, error_info:{}").format(self.sol_path, e)) raise e
def common_request(self, cmd, params, packet_type=ChannelPack.TYPE_RPC): response = None try: next(self.request_counter) stat = StatTool.begin() if client_config.client_protocol == client_config.PROTOCOL_RPC: response = self.rpc.make_request(cmd, params) if client_config.client_protocol == client_config.PROTOCOL_CHANNEL: response = self.channel_handler.make_request( cmd, params, ChannelPack.TYPE_RPC, packet_type) self.is_error_response(response) memo = "DONE" stat.done() stat.debug("commonrequest:{}:{}".format(cmd, memo)) return response["result"] except Exception as e: raise BcosError(-1, None, ("{} failed," " params: {}, response: {}, error information: {}"). format(cmd, params, response, e))
def sendpack(self, pack): if self.packQueue.full(): raise BcosError(-1, None, "sendThread Queue full") self.packQueue.put(pack)
def send_pack(self, pack): if self.sendThread.packQueue.full(): self.logger.error("channel send Queue full!") raise BcosError(-1, None, "channel send Queue full!") self.sendThread.packQueue.put(pack)
def send_transaction_getReceipt(self, fn_name, fn_args, gasPrice=30000000, isdeploy=False, from_account_signer=None): """ send transactions to CNS contract with the givn function name and args """ try: contract_abi, args = self.format_abi_args(fn_name, fn_args, isdeploy) contract_bin = None if isdeploy is True and os.path.exists( self.contract_bin_path) is True: with open(self.contract_bin_path, "rb") as f: contract_bin = f.read() f.close() # print(contract_bin) if self.contract_bin_path.endswith("wasm"): contract_bin = encode_hex(contract_bin) else: contract_bin = bytes.decode(contract_bin, "utf-8") if contract_bin is not None and len(contract_bin) > 0x40000: raise BcosException( ("contract bin size overflow," " limit: 0x40000(256K), size: {})").format( len(contract_bin), 16)) receipt = super().sendRawTransactionGetReceipt( self.contract_addr, contract_abi, fn_name, args, contract_bin, gasPrice, from_account_signer=from_account_signer) # check status if "status" not in receipt.keys() or \ "output" not in receipt.keys(): raise BcosError(-1, None, ("send transaction failed" "for empty status and output," "transaction receipt:{}").format(receipt)) status = receipt["status"] status_code = int(status, 16) error_message = transaction_status_code.TransactionStatusCode.get_error_message( status_code) if error_message is not None: raise BcosException( "call error, error message: {}".format(error_message)) if receipt["output"] is None: raise TransactionException(receipt, ("send transaction failed," "status: {}, gasUsed: {}").format( status, receipt["gasUsed"])) if fn_name is not None and fn_args is not None and self.dataparser is not None: output = self.dataparser.parse_receipt_output( fn_name, receipt["output"]) else: output = None return (receipt, output) except BcosError as e: self.logger.error( "send transaction failed, fn_name: {}, fn_args:{}, error_info:{}" .format(fn_name, fn_args, e)) raise e except CompileError as e: self.logger.error( ("send transaction failed for compile soldity failed," "contract_path {}, error_info:{}").format(self.sol_path, e)) raise e