Example #1
0
def _mediation_fee_func(
    schedule_in: "FeeScheduleState",
    schedule_out: "FeeScheduleState",
    balance_in: Balance,
    balance_out: Balance,
    receivable: TokenAmount,
    amount_with_fees: Optional[PaymentWithFeeAmount],
    amount_without_fees: Optional[PaymentWithFeeAmount],
    cap_fees: bool,
) -> Interpolate:
    """ Returns a function which calculates total_mediation_fee(x)

    Either `amount_with_fees` or `amount_without_fees` must be given while the
    other one is None. The returned function will depend on the value that is
    not given.
    """
    assert (
        amount_with_fees is None or amount_without_fees is None
    ), "Must be called with either amount_with_fees or amount_without_fees as None"

    # If either channel can't transfer even a single token, there can be no mediation.
    if balance_out == 0 or receivable == 0:
        raise UndefinedMediationFee()

    # Add dummy penalty funcs if none are set
    if not schedule_in._penalty_func:
        schedule_in = copy(schedule_in)
        schedule_in._penalty_func = Interpolate([0, balance_in + receivable], [0, 0])
    if not schedule_out._penalty_func:
        schedule_out = copy(schedule_out)
        schedule_out._penalty_func = Interpolate([0, balance_out], [0, 0])

    x_list = _collect_x_values(
        penalty_func_in=schedule_in._penalty_func,
        penalty_func_out=schedule_out._penalty_func,
        balance_in=balance_in,
        balance_out=balance_out,
        max_x=receivable if amount_with_fees is None else balance_out,
    )

    # Sum up fees where either `amount_with_fees` or `amount_without_fees` is
    # fixed and the other one is represented by `x`.
    try:
        y_list = [
            schedule_in.fee(
                balance_in, x if amount_with_fees is None else Fraction(amount_with_fees)
            )
            + schedule_out.fee(
                balance_out, -x if amount_without_fees is None else -Fraction(amount_without_fees)
            )
            for x in x_list
        ]
    except ValueError:
        raise UndefinedMediationFee()

    if cap_fees:
        x_list, y_list = _cap_fees(x_list, y_list)

    return Interpolate(x_list, y_list)
Example #2
0
    def imbalance_fee_sender(self, amount: PaymentWithFeeAmount,
                             balance: Balance) -> FeeAmount:
        if not self._penalty_func:
            return FeeAmount(0)

        try:
            return FeeAmount(
                # Mediator is loosing balance on his channel side
                round(
                    self._penalty_func(balance - amount) -
                    self._penalty_func(balance)))
        except ValueError:
            raise UndefinedMediationFee()
Example #3
0
    def imbalance_fee(self, amount: PaymentWithFeeAmount,
                      balance: Balance) -> FeeAmount:
        if self._penalty_func:
            # Total channel balance - node balance = balance (used as x-axis for the penalty)
            balance = self._penalty_func.x_list[-1] - balance
            try:
                return FeeAmount(
                    round(
                        self._penalty_func(balance + amount) -
                        self._penalty_func(balance)))
            except ValueError:
                raise UndefinedMediationFee()

        return FeeAmount(0)
Example #4
0
    def imbalance_fee_receiver(self, amount: PaymentWithFeeAmount,
                               balance: Balance) -> FeeAmount:
        if not self._penalty_func:
            return FeeAmount(0)

        # Calculate the mediators balance
        balance = self._penalty_func.x_list[-1] - balance
        try:
            return FeeAmount(
                # Mediator is gaining balance on his channel side
                round(
                    self._penalty_func(balance + amount) -
                    self._penalty_func(balance)))
        except ValueError:
            raise UndefinedMediationFee()