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)
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()
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)
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()