async def on_request_replied(self, req_data, gen_req, resp_or_exp): if gen_req not in self._sent_reqs: return self._sent_reqs.remove(gen_req) if isinstance(resp_or_exp, Exception): return reply = json.loads(resp_or_exp) result = reply.get('result') if not result or result['txn']['type'] != PUB_XFER_TXN_ID: return try: receipt_infos_json = await payment.parse_payment_response( self._payment_method, resp_or_exp) receipt_infos = json.loads( receipt_infos_json) if receipt_infos_json else [] for ri in receipt_infos: self._addr_txos[ri["recipient"]].append( (ri["receipt"], ri["amount"])) log_addr_txos_update('XFER', self._addr_txos, len(receipt_infos)) except Exception as e: self._logger.info('Got unexpected error: {}'.format(e)) self._logger.info('While parsing reply: {}'.format(reply)) raise
async def _parse_fees_resp(self, req, resp_or_exp): if isinstance(resp_or_exp, Exception): self._logger.warning( "Pool responded with error, UTXOs are lost: {}".format( self._req_addrs.get(req))) self._req_addrs.pop(req, {}) return resp = resp_or_exp try: resp_obj = json.loads(resp) op_f = resp_obj.get("op", "") resp_type = response_get_type(resp_obj) if op_f == "REPLY" and resp_type not in self._ignore_fees_txns: receipt_infos_json = await payment.parse_response_with_fees( self._payment_method, resp) receipt_infos = json.loads( receipt_infos_json) if receipt_infos_json else [] for ri in receipt_infos: self._addr_txos[ri["recipient"]].append( (ri["receipt"], ri["amount"])) log_addr_txos_update('FEES', self._addr_txos, len(receipt_infos)) else: self._restore_fees_from_req(req) except Exception as e: self._logger.exception( "Error on payment txn postprocessing: {}".format(e)) self._req_addrs.pop(req, {})
async def _payment_address_init(self): pmt_addrs = await self.__create_payment_addresses(self._payment_addrs_count) mint_addrs = pmt_addrs[:self._mint_addrs_count] for payment_addrs_chunk in divide_sequence_into_chunks(mint_addrs, 500): await self.__mint_sources(payment_addrs_chunk, self._addr_mint_limit, self._mint_by) for pa in pmt_addrs: self._addr_txos.update(await self._get_payment_sources(pa)) log_addr_txos_update('MINT', self._addr_txos) self._logger.info("_payment_address_init done")
def _gen_input_output(self, val, fees): address, inputs, outputs = gen_input_output(self._addr_txos, val + fees) if inputs is None or outputs is None: self._logger.warning("Failed to create XFER, insufficient txos") raise NoReqDataAvailableException() log_addr_txos_update('XFER', self._addr_txos, -len(inputs)) addrs = list(self._addr_txos) addrs.remove(list(address)[0]) to_address = random.choice(addrs) outputs.append({"recipient": to_address, "amount": val}) return inputs, outputs
async def _add_fees(self, wallet_h, did, req): req_type = request_get_type(req) if req_type in self._ignore_fees_txns: return None, req fees_val = self._pool_fees.get(req_type, 0) if fees_val == 0: return None, req address, inputs, outputs = gen_input_output(self._addr_txos, fees_val) if not inputs: self._logger.warning("Failed to add fees to txn, insufficient txos") return None, req if self._allow_invalid_txns else None log_addr_txos_update('FEES', self._addr_txos, -len(inputs)) req_fees, _ = await payment.add_request_fees(wallet_h, did, req, json.dumps(inputs), json.dumps(outputs), None) return address, req_fees
def _restore_fees_from_req(self, req): fees_to_restore = self._req_addrs.pop(req, {}) for addr, txos in fees_to_restore.items(): self._addr_txos[addr].extend(txos) log_addr_txos_update('RESTORE', self._addr_txos, len(txos))