Example #1
0
    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
Example #2
0
    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
Example #3
0
    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
Example #4
0
    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
Example #5
0
    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