def get_own_service_description( self, is_supply: bool, is_search_description: bool) -> Description: """ Get the description of the supplied goods (as a seller), or the demanded goods (as a buyer). :param is_supply: Boolean indicating whether it is supply or demand. :param is_search_description: whether or not the description is for search. :return: the description (to advertise on the Service Directory). """ transactions = cast(Transactions, self.context.transactions) ownership_state_after_locks = transactions.ownership_state_after_locks( is_seller=is_supply) good_id_to_quantities = ( self._supplied_goods( ownership_state_after_locks.quantities_by_good_id) if is_supply else self._demanded_goods( ownership_state_after_locks.quantities_by_good_id)) currency_id = list( ownership_state_after_locks.amount_by_currency_id.keys())[0] desc = build_goods_description( good_id_to_quantities=good_id_to_quantities, currency_id=currency_id, is_supply=is_supply, is_search_description=is_search_description, ) return desc
def get_own_service_description(self, is_supply: bool) -> Description: """ Get the description of the supplied goods (as a seller), or the demanded goods (as a buyer). :param is_supply: Boolean indicating whether it is supply or demand. :return: the description (to advertise on the Service Directory). """ transactions = cast(Transactions, self.context.transactions) ownership_state_after_locks = transactions.ownership_state_after_locks( is_seller=is_supply ) quantities_by_good_id = ( self._supplied_goods(ownership_state_after_locks.quantities_by_good_id) if is_supply else self._demanded_goods(ownership_state_after_locks.quantities_by_good_id) ) currency_id = next( iter(ownership_state_after_locks.amount_by_currency_id.keys()) ) desc = build_goods_description( quantities_by_good_id=quantities_by_good_id, currency_id=currency_id, ledger_id=self.ledger_id, is_supply=is_supply, ) return desc
def test_build_goods_description_demand(self): """Test the build_goods_description of Helpers module for demand (same as above).""" quantities_by_good_id = {"2": 5, "3": 10} currency_id = "1" ledger_id = "some_ledger_id" is_supply = False attributes = [ Attribute("2", int, True, "A good on offer."), Attribute("3", int, True, "A good on offer."), Attribute("ledger_id", str, True, "The ledger for transacting."), Attribute( "currency_id", str, True, "The currency for pricing and transacting the goods.", ), Attribute("price", int, False, "The price of the goods in the currency."), Attribute( "fee", int, False, "The transaction fee payable by the buyer in the currency.", ), Attribute("nonce", str, False, "The nonce to distinguish identical descriptions."), ] expected_data_model = DataModel(DEMAND_DATAMODEL_NAME, attributes) expected_values = {"currency_id": currency_id, "ledger_id": ledger_id} expected_values.update(quantities_by_good_id) expected_description = Description(expected_values, expected_data_model) actual_description = build_goods_description(quantities_by_good_id, currency_id, ledger_id, is_supply) assert actual_description == expected_description
def test_get_own_service_description_not_is_supply(self): """Test the get_own_service_description method of the Strategy class where is_supply is False.""" # setup is_supply = False mocked_demanded_quantities_by_good_id = {"2": 1, "3": 1} expected_description = build_goods_description( mocked_demanded_quantities_by_good_id, self.mocked_currency_id, self.ledger_id, is_supply, ) # operation with patch.object( self.skill.skill_context.transactions, "ownership_state_after_locks", return_value=self.mocked_ownership_state, ) as mock_ownership: actual_description = self.strategy.get_own_service_description( is_supply) # after mock_ownership.assert_any_call(is_seller=is_supply) assert actual_description == expected_description
def _generate_candidate_proposals(self, is_seller: bool): """ Generate proposals from the agent in the role of seller/buyer. :param is_seller: the bool indicating whether the agent is a seller. :return: a list of proposals in Description form """ transactions = cast(Transactions, self.context.transactions) ownership_state_after_locks = transactions.ownership_state_after_locks( is_seller=is_seller ) good_id_to_quantities = ( self._supplied_goods(ownership_state_after_locks.quantities_by_good_id) if is_seller else self._demanded_goods(ownership_state_after_locks.quantities_by_good_id) ) nil_proposal_dict = { good_id: 0 for good_id in good_id_to_quantities.keys() } # type: Dict[str, int] proposals = [] fee_by_currency_id = self.context.shared_state.get("tx_fee", {"FET": 0}) buyer_tx_fee = next(iter(fee_by_currency_id.values())) ownership_state = cast( OwnershipState, self.context.decision_maker_handler_context.ownership_state ) currency_id = list(ownership_state.amount_by_currency_id.keys())[0] preferences = cast( Preferences, self.context.decision_maker_handler_context.preferences ) for good_id, quantity in good_id_to_quantities.items(): if is_seller and quantity == 0: continue proposal_dict = copy.copy(nil_proposal_dict) proposal_dict[good_id] = 1 proposal = build_goods_description( quantities_by_good_id=proposal_dict, currency_id=currency_id, ledger_id=self.ledger_id, is_supply=is_seller, ) if is_seller: delta_quantities_by_good_id = { good_id: quantity * -1 for good_id, quantity in proposal_dict.items() } # type: Dict[str, int] else: delta_quantities_by_good_id = proposal_dict marginal_utility_from_delta_good_holdings = preferences.marginal_utility( ownership_state=ownership_state_after_locks, delta_quantities_by_good_id=delta_quantities_by_good_id, ) switch = -1 if is_seller else 1 breakeven_price_rounded = ( round(marginal_utility_from_delta_good_holdings) * switch ) if is_seller: proposal.values["price"] = breakeven_price_rounded + ROUNDING_ADJUSTMENT else: proposal.values["price"] = ( breakeven_price_rounded - buyer_tx_fee - ROUNDING_ADJUSTMENT ) proposal.values["fee"] = buyer_tx_fee if not proposal.values["price"] > 0: continue nonce = transactions.get_next_nonce() proposal.values["nonce"] = nonce proposals.append(proposal) return proposals