def _handle_accept(self, ml_trade_msg: MlTradeMessage, ml_trade_dialogue: MlTradeDialogue) -> None: """ Handle accept. :param ml_trade_msg: the ml trade message :param ml_trade_dialogue: the dialogue object :return: None """ terms = ml_trade_msg.terms self.context.logger.info("got an Accept from {}: {}".format( ml_trade_msg.counterparty[-5:], terms.values)) strategy = cast(Strategy, self.context.strategy) if not strategy.is_valid_terms(terms): self.context.logger.info("terms are not valid.") return data = strategy.sample_data(terms.values["batch_size"]) self.context.logger.info( "sending to address={} a Data message: shape={}".format( ml_trade_msg.counterparty[-5:], data[0].shape)) payload = pickle.dumps(data) # nosec data_msg = MlTradeMessage( performative=MlTradeMessage.Performative.DATA, dialogue_reference=ml_trade_dialogue.dialogue_label. dialogue_reference, message_id=ml_trade_msg.message_id + 1, target=ml_trade_msg.message_id, terms=terms, payload=payload, ) data_msg.counterparty = ml_trade_msg.counterparty ml_trade_dialogue.update(data_msg) self.context.outbox.put_message(message=data_msg)
def _handle_cft(self, ml_trade_msg: MlTradeMessage, ml_trade_dialogue: MlTradeDialogue) -> None: """ Handle call for terms. :param ml_trade_msg: the ml trade message :param ml_trade_dialogue: the dialogue object :return: None """ query = ml_trade_msg.query self.context.logger.info("got a Call for Terms from {}.".format( ml_trade_msg.counterparty[-5:])) strategy = cast(Strategy, self.context.strategy) if not strategy.is_matching_supply(query): self.context.logger.info("query does not match supply.") return terms = strategy.generate_terms() self.context.logger.info( "sending to the address={} a Terms message: {}".format( ml_trade_msg.counterparty[-5:], terms.values)) terms_msg = MlTradeMessage( performative=MlTradeMessage.Performative.TERMS, dialogue_reference=ml_trade_dialogue.dialogue_label. dialogue_reference, message_id=ml_trade_msg.message_id + 1, target=ml_trade_msg.message_id, terms=terms, ) terms_msg.counterparty = ml_trade_msg.counterparty ml_trade_dialogue.update(terms_msg) self.context.outbox.put_message(message=terms_msg)
def _handle_search(self, oef_search_msg: OefSearchMessage, oef_search_dialogue: OefSearchDialogue) -> None: """ Handle the search response. :param agents: the agents returned by the search :return: None """ if len(oef_search_msg.agents) == 0: self.context.logger.info("found no agents, continue searching.") return self.context.logger.info("found agents={}, stopping search.".format( list(map(lambda x: x[-5:], oef_search_msg.agents)), )) strategy = cast(Strategy, self.context.strategy) strategy.is_searching = False query = strategy.get_service_query() ml_trade_dialogues = cast(MlTradeDialogues, self.context.ml_trade_dialogues) for idx, opponent_address in enumerate(oef_search_msg.agents): if idx >= strategy.max_negotiations: continue self.context.logger.info("sending CFT to agent={}".format( opponent_address[-5:])) cft_msg = MlTradeMessage( performative=MlTradeMessage.Performative.CFP, dialogue_reference=ml_trade_dialogues. new_self_initiated_dialogue_reference(), query=query, ) cft_msg.counterparty = opponent_address ml_trade_dialogues.update(cft_msg) self.context.outbox.put_message(message=cft_msg)
def _handle_transaction_digest( self, ledger_api_msg: LedgerApiMessage, ledger_api_dialogue: LedgerApiDialogue) -> None: """ Handle a message of transaction_digest performative. :param ledger_api_message: the ledger api message :param ledger_api_dialogue: the ledger api dialogue """ ml_trade_dialogue = ledger_api_dialogue.associated_ml_trade_dialogue self.context.logger.info( "transaction was successfully submitted. Transaction digest={}". format(ledger_api_msg.transaction_digest)) ml_trade_msg = cast(Optional[MlTradeMessage], ml_trade_dialogue.last_incoming_message) assert ml_trade_msg is not None, "Could not retrieve ml_trade message" ml_accept = MlTradeMessage( performative=MlTradeMessage.Performative.ACCEPT, message_id=ml_trade_msg.message_id + 1, dialogue_reference=ml_trade_dialogue.dialogue_label. dialogue_reference, target=ml_trade_msg.message_id, tx_digest=ledger_api_msg.transaction_digest.body, terms=ml_trade_msg.terms, ) ml_accept.counterparty = ml_trade_msg.counterparty ml_trade_dialogue.update(ml_accept) self.context.outbox.put_message(message=ml_accept) self.context.logger.info( "informing counterparty={} of transaction digest={}.".format( ml_trade_msg.counterparty[-5:], ledger_api_msg.transaction_digest, ))
def _handle_terms(self, ml_trade_msg: MlTradeMessage, ml_trade_dialogue: MlTradeDialogue) -> None: """ Handle the terms of the request. :param ml_trade_msg: the ml trade message :param ml_trade_dialogue: the dialogue object :return: None """ terms = ml_trade_msg.terms self.context.logger.info( "received terms message from {}: terms={}".format( ml_trade_msg.counterparty[-5:], terms.values)) strategy = cast(Strategy, self.context.strategy) acceptable = strategy.is_acceptable_terms(terms) affordable = strategy.is_affordable_terms(terms) if not acceptable and affordable: self.context.logger.info( "rejecting, terms are not acceptable and/or affordable") return if strategy.is_ledger_tx: # construct a tx for settlement on the ledger ledger_api_dialogues = cast(LedgerApiDialogues, self.context.ledger_api_dialogues) ledger_api_msg = LedgerApiMessage( performative=LedgerApiMessage.Performative.GET_RAW_TRANSACTION, dialogue_reference=ledger_api_dialogues. new_self_initiated_dialogue_reference(), terms=Terms( ledger_id=terms.values["ledger_id"], sender_address=self.context.agent_addresses[ terms.values["ledger_id"]], counterparty_address=terms.values["address"], amount_by_currency_id={ terms.values["currency_id"]: -terms.values["price"] }, is_sender_payable_tx_fee=True, quantities_by_good_id={"ml_training_data": 1}, nonce=uuid.uuid4().hex, fee_by_currency_id={terms.values["currency_id"]: 1}, ), ) ledger_api_msg.counterparty = LEDGER_API_ADDRESS ledger_api_dialogue = cast( Optional[LedgerApiDialogue], ledger_api_dialogues.update(ledger_api_msg)) assert (ledger_api_dialogue is not None), "Error when creating ledger api dialogue." ledger_api_dialogue.associated_ml_trade_dialogue = ml_trade_dialogue self.context.outbox.put_message(message=ledger_api_msg) self.context.logger.info( "requesting transfer transaction from ledger api...") else: # accept directly with a dummy transaction digest, no settlement ml_accept = MlTradeMessage( performative=MlTradeMessage.Performative.ACCEPT, dialogue_reference=ml_trade_dialogue.dialogue_label. dialogue_reference, message_id=ml_trade_msg.message_id + 1, target=ml_trade_msg.message_id, tx_digest=DUMMY_DIGEST, terms=terms, ) ml_accept.counterparty = ml_trade_msg.counterparty ml_trade_dialogue.update(ml_accept) self.context.outbox.put_message(message=ml_accept) self.context.logger.info("sending dummy transaction digest ...")