Skip to content
This repository has been archived by the owner on Oct 27, 2024. It is now read-only.

Commit

Permalink
Handle out of bounds errors for FeeSchedule
Browse files Browse the repository at this point in the history
  • Loading branch information
karlb committed May 24, 2019
1 parent adf9b11 commit 05676d7
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 8 deletions.
6 changes: 6 additions & 0 deletions src/pathfinding_service/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ class InvalidCapacityUpdate(Exception):
"""Exception for incoming messages"""


class UndefinedFee(Exception):
"""The fee schedule is not applicable resulting in undefined fees
This should be handled by excluding the route from the results"""


class ApiException(Exception):
"""An exception that can be returned via the REST API"""

Expand Down
6 changes: 5 additions & 1 deletion src/pathfinding_service/model/channel_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from marshmallow_dataclass import add_schema

from pathfinding_service.config import DEFAULT_REVEAL_TIMEOUT
from pathfinding_service.exceptions import UndefinedFee
from raiden.utils.typing import (
Address,
ChannelID,
Expand Down Expand Up @@ -58,7 +59,10 @@ def fee(self, amount: TokenAmount, capacity: TokenAmount) -> FeeAmount:
if self.imbalance_penalty:
# Total channel capacity - node capacity = balance (used as x-axis for the penalty)
balance = self._penalty_func.x_list[-1] - capacity
imbalance_fee = self._penalty_func(balance + amount) - self._penalty_func(balance)
try:
imbalance_fee = self._penalty_func(balance + amount) - self._penalty_func(balance)
except ValueError:
raise UndefinedFee()
else:
imbalance_fee = 0
return FeeAmount(round(self.flat + amount * self.proportional + imbalance_fee))
Expand Down
23 changes: 16 additions & 7 deletions src/pathfinding_service/model/token_network.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
DIVERSITY_PEN_DEFAULT,
FEE_PEN_DEFAULT,
)
from pathfinding_service.exceptions import UndefinedFee
from pathfinding_service.model.channel_view import ChannelView, FeeSchedule
from raiden.messages import Message, UpdatePFS
from raiden.network.transport.matrix import AddressReachability
Expand Down Expand Up @@ -53,12 +54,15 @@ def __init__(

def _calc_fees(self) -> None:
total = self.value
for prev_node, mediator, next_node in reversed(list(window(self.nodes, 3))):
fee_for_this_mediator = self.G[prev_node][mediator]["view"].fee_receiver(
total
) + self.G[mediator][next_node]["view"].fee_sender(total)
total += fee_for_this_mediator
self.fees.append(fee_for_this_mediator)
try:
for prev_node, mediator, next_node in reversed(list(window(self.nodes, 3))):
fee_for_this_mediator = self.G[prev_node][mediator]["view"].fee_receiver(
total
) + self.G[mediator][next_node]["view"].fee_sender(total)
total += fee_for_this_mediator
self.fees.append(fee_for_this_mediator)
except UndefinedFee:
self._is_valid = False

@property
def edge_attrs(self) -> Iterable[dict]:
Expand All @@ -82,6 +86,8 @@ def is_valid(self) -> bool:
should not use such routes. See
https://github.com/raiden-network/raiden-services/issues/5.
"""
if hasattr(self, "_is_valid"):
return self._is_valid
required_capacity = self.value
edges = reversed(list(self.edge_attrs))
fees = self.fees + [FeeAmount(0)] # The hop to the target does not incur mediation fees
Expand Down Expand Up @@ -276,7 +282,10 @@ def edge_weight(
# Fees for initiator and target are included here. This promotes routes
# that are nice to the initiator's and target's capacities, but it's
# inconsistent with the estimated total fee.
fee_weight = (view.fee_sender(amount) + view.fee_receiver(amount)) / 1e18 * fee_penalty
try:
fee_weight = (view.fee_sender(amount) + view.fee_receiver(amount)) / 1e18 * fee_penalty
except UndefinedFee:
return float("inf")
no_refund_weight = 0
if view_from_partner.capacity < int(float(amount) * 1.1):
no_refund_weight = 1
Expand Down
7 changes: 7 additions & 0 deletions tests/pathfinding/test_fee_schedule.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ def set_fee(self, node1, node2, fee_schedule: FeeSchedule):

def estimate_fee(self, initator, target, value=TA(10), max_paths=1):
result = self.get_paths(a(initator), a(target), value=value, max_paths=max_paths)
if not result:
return None
return result[0]["estimated_fee"]


Expand Down Expand Up @@ -134,6 +136,11 @@ def test_fees_in_routing():
assert tn.estimate_fee(1, 3) == 10
assert tn.estimate_fee(3, 1) == -10

# When the range covered by the imbalance_penalty does include the
# necessary belance values, the route should be considered invalid.
tn.set_fee(2, 3, FeeSchedule(imbalance_penalty=[(TA(0), FA(0)), (TA(80), FA(200))]))
assert tn.estimate_fee(1, 3) is None


def test_compounding_fees():
""" The transferred amount needs to include the fees for all mediators.
Expand Down

0 comments on commit 05676d7

Please sign in to comment.