codecov[bot]: # [Codecov](https://codecov.io/gh/raiden-network/raiden-services/pull/790?src=pr&el=h1) Report
> Merging [#790](https://codecov.io/gh/raiden-network/raiden-services/pull/790?src=pr&el=desc) into [master](https://codecov.io/gh/raiden-network/raiden-services/commit/ac396cd7eb1687b84bb479acfc08b667f5bcd955&el=desc) will **decrease** coverage by `0.06%`.
> The diff coverage is `0.00%`.

[![Impacted file tree graph](https://codecov.io/gh/raiden-network/raiden-services/pull/790/graphs/tree.svg?width=650&height=150&src=pr&token=H07qtpFA6p)](https://codecov.io/gh/raiden-network/raiden-services/pull/790?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master     #790      +/-   ##
==========================================
- Coverage   89.80%   89.74%   -0.07%     
==========================================
  Files          35       35              
  Lines        2639     2643       +4     
  Branches      334      335       +1     
==========================================
+ Hits         2370     2372       +2     
- Misses        199      200       +1     
- Partials       70       71       +1     
```


| [Impacted Files](https://codecov.io/gh/raiden-network/raiden-services/pull/790?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [src/pathfinding\_service/claim\_fees.py](https://codecov.io/gh/raiden-network/raiden-services/pull/790/diff?src=pr&el=tree#diff-c3JjL3BhdGhmaW5kaW5nX3NlcnZpY2UvY2xhaW1fZmVlcy5weQ==) | `84.93% <0.00%> (-4.93%)` | :arrow_down: |
| [src/pathfinding\_service/api.py](https://codecov.io/gh/raiden-network/raiden-services/pull/790/diff?src=pr&el=tree#diff-c3JjL3BhdGhmaW5kaW5nX3NlcnZpY2UvYXBpLnB5) | `95.68% <0.00%> (+0.78%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/raiden-network/raiden-services/pull/790?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/raiden-network/raiden-services/pull/790?src=pr&el=footer). Last update [ac396cd...aa41053](https://codecov.io/gh/raiden-network/raiden-services/pull/790?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

diff --git a/src/pathfinding_service/claim_fees.py b/src/pathfinding_service/claim_fees.py
index b368084..6f56178 100644
--- a/src/pathfinding_service/claim_fees.py
+++ b/src/pathfinding_service/claim_fees.py
@@ -55,6 +55,7 @@ def main(
     ious = list(
         get_claimable_ious(
             database,
+            expires_after=web3.eth.blockNumber,
             expires_before=BlockNumber(web3.eth.blockNumber + expires_within),
             claim_cost_rdn=claim_cost_rdn,
         )
@@ -77,12 +78,17 @@ def calc_claim_cost_rdn(web3: Web3, rdn_per_eth: float) -> TokenAmount:
 
 
 def get_claimable_ious(
-    database: PFSDatabase, expires_before: BlockNumber, claim_cost_rdn: TokenAmount
+    database: PFSDatabase,
+    expires_after: BlockNumber,
+    expires_before: BlockNumber,
+    claim_cost_rdn: TokenAmount,
 ) -> Iterable[IOU]:
-    ious = database.get_ious(
-        claimed=False, expires_before=expires_before, amount_at_least=claim_cost_rdn
+    return database.get_ious(
+        claimed=False,
+        expires_after=expires_after,
+        expires_before=expires_before,
+        amount_at_least=claim_cost_rdn,
     )
-    return ious
 
 
 def claim_ious(
diff --git a/src/pathfinding_service/database.py b/src/pathfinding_service/database.py
index 8762480..68055b2 100644
--- a/src/pathfinding_service/database.py
+++ b/src/pathfinding_service/database.py
@@ -115,6 +115,7 @@ class PFSDatabase(BaseDatabase):
         sender: Optional[Address] = None,
         expiration_block: Optional[BlockNumber] = None,
         claimed: Optional[bool] = None,
+        expires_after: Optional[BlockNumber] = None,
         expires_before: Optional[BlockNumber] = None,
         amount_at_least: Optional[TokenAmount] = None,
     ) -> Iterator[IOU]:
@@ -136,6 +137,9 @@ class PFSDatabase(BaseDatabase):
         if expires_before is not None:
             query += " AND expiration_block < ?"
             args.append(hex256(expires_before))
+        if expires_after is not None:
+            query += " AND expiration_block > ?"
+            args.append(hex256(expires_after))
         if amount_at_least is not None:
             query += " AND amount >= ?"
             args.append(hex256(amount_at_least))

`claim_iou` script doesn't check if expiration is in the past
The `claim_iou` script doesn't properly check if an IOUs expiration is in the past.

This leads to gas estimation to fail and the script to crash.
```
[info     ] Opening database               [raiden_libs.database] filename=/state/pfs-state.db
Found 1 claimable IOUs
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "/usr/local/lib/python3.7/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/services/src/pathfinding_service/claim_fees.py", line 135, in <module>
    main(auto_envvar_prefix="PFS")  # pragma: no cover
  File "/usr/local/lib/python3.7/site-packages/click/core.py", line 764, in __call__
    return self.main(*args, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/click/core.py", line 717, in main
    rv = self.invoke(ctx)
  File "/usr/local/lib/python3.7/site-packages/click/core.py", line 956, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/local/lib/python3.7/site-packages/click/core.py", line 555, in invoke
    return callback(*args, **kwargs)
  File "/services/src/raiden_libs/cli.py", line 243, in call_with_blockchain_info
    return callback(**params)
  File "/services/src/raiden_libs/cli.py", line 168, in call_with_common_options_initialized
    return func(**params)
  File "/services/src/pathfinding_service/claim_fees.py", line 63, in main
    _, failures = claim_ious(ious, claim_cost_rdn, contracts[CONTRACT_ONE_TO_N], web3, database)
  File "/services/src/pathfinding_service/claim_fees.py", line 111, in claim_ious
    tx_hash = claim.transact()
  File "/usr/local/lib/python3.7/site-packages/web3/contract.py", line 996, in transact
    **self.kwargs
  File "/usr/local/lib/python3.7/site-packages/web3/contract.py", line 1580, in transact_with_contract_function
    txn_hash = web3.eth.sendTransaction(transact_transaction)
  File "/usr/local/lib/python3.7/site-packages/web3/eth.py", line 381, in sendTransaction
    get_buffered_gas_estimate(self.web3, transaction),
  File "/usr/local/lib/python3.7/site-packages/web3/_utils/transactions.py", line 126, in get_buffered_gas_estimate
    gas_estimate = web3.eth.estimateGas(gas_estimate_transaction)
  File "/usr/local/lib/python3.7/site-packages/web3/eth.py", line 445, in estimateGas
    params,
  File "/usr/local/lib/python3.7/site-packages/web3/manager.py", line 153, in request_blocking
    raise ValueError(response["error"])
ValueError: {'code': -32000, 'message': 'gas required exceeds allowance (9983436) or always failing transaction'}
```

While at it, we should also add an explanation on how to run the script on the RSB.
diff --git a/tests/pathfinding/test_claim_fees.py b/tests/pathfinding/test_claim_fees.py
index 4039a3d..1382565 100644
--- a/tests/pathfinding/test_claim_fees.py
+++ b/tests/pathfinding/test_claim_fees.py
@@ -5,6 +5,7 @@ import pytest
 from click.testing import CliRunner
 from eth_utils import decode_hex, to_canonical_address
 from tests.libs.mocks.web3 import Web3Mock
+from web3 import Web3
 
 from pathfinding_service.claim_fees import claim_ious, get_claimable_ious, main
 from pathfinding_service.model import IOU
@@ -16,7 +17,7 @@ from raiden.utils.typing import BlockNumber, ChainID, Signature, TokenAmount
 def test_claim_fees(  # pylint: disable=too-many-locals
     pathfinding_service_web3_mock: PathfindingService,
     one_to_n_contract,
-    web3,
+    web3: Web3,
     deposit_to_udc,
     get_accounts,
     get_private_key,
@@ -24,7 +25,7 @@ def test_claim_fees(  # pylint: disable=too-many-locals
     pfs = pathfinding_service_web3_mock
 
     # Prepare test data
-    accounts = [decode_hex(acc) for acc in get_accounts(6)]
+    accounts = [decode_hex(acc) for acc in get_accounts(7)]
     iou_inputs: List[dict] = [
         dict(sender=accounts[0], amount=100, deposit=200),
         dict(sender=accounts[1], amount=200, deposit=100),
@@ -33,6 +34,9 @@ def test_claim_fees(  # pylint: disable=too-many-locals
         dict(sender=accounts[4], amount=104, claimed=True),  # already claimed
         dict(sender=accounts[4], amount=99),  # too low amount
         dict(sender=accounts[5], expiration_block=1000, amount=104),  # does not expire, yet
+        dict(
+            sender=accounts[6], expiration_block=web3.eth.blockNumber - 1, amount=104
+        ),  # already expired
     ]
 
     # Create IOUs from `iou_inputs`
@@ -60,6 +64,7 @@ def test_claim_fees(  # pylint: disable=too-many-locals
     claimable_ious = list(
         get_claimable_ious(
             database=pfs.database,
+            expires_after=web3.eth.blockNumber,
             expires_before=BlockNumber(1000),
             claim_cost_rdn=TokenAmount(100),
         )

pip install -U -r requirements-dev.txt && pip install -e .
parse_log_pytest
requirements.txt
pytest-gevent pytest
apt-get update apt-get install -y gcc
3.7
requirements.txt requirements-dev.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
alabaster==0.7.13
aniso8601==7.0.0
appdirs==1.4.4
asn1crypto==1.3.0
astroid==2.3.3
attrs==19.3.0
Babel==2.14.0
base58==2.0.0
bitarray==1.2.1
black==19.10b0
blake2b-py==0.1.4
bleach==6.0.0
blinker==1.6.3
bump2version==1.0.1
cached-property==1.5.2
cachetools==3.1.1
certifi==2019.3.9
cffi==1.12.3
chardet==3.0.4
Click==7.0
coincurve==13.0.0
colorama==0.4.1
coverage==7.2.7
cryptography==44.0.2
cytoolz==0.10.1
decorator==4.4.0
docutils==0.20.1
entrypoints==0.3
eth-abi==2.1.0
eth-account==0.5.2
eth-bloom==1.0.3
eth-hash==0.2.0
eth-keyfile==0.5.1
eth-keys==0.2.4
eth-rlp==0.1.2
eth-tester==0.4.0b2
eth-typing==2.2.1
eth-utils==1.8.4
exceptiongroup==1.2.2
execnet==2.0.2
fancycompleter==0.9.1
filelock==3.0.12
flake8==3.7.9
flake8-bugbear==20.1.2
flake8-tuple==0.4.1
Flask==1.0.3
Flask-Cors==3.0.8
Flask-RESTful==0.3.7
gevent==1.5a3
graphviz==0.13.2
greenlet==0.4.15
guppy3==3.0.9
hexbytes==0.2.0
idna==2.8
imagesize==1.4.1
importlib-metadata==1.5.0
iniconfig==2.0.0
ipfshttpclient==0.4.12
ipython==4.2.1
ipython-genutils==0.2.0
isort==4.3.21
itsdangerous==1.1.0
jeepney==0.9.0
Jinja2==2.10.1
jsonschema==3.2.0
keyring==22.3.0
lazy-object-proxy==1.4.3
lru-dict==1.1.6
MarkupSafe==1.1.1
marshmallow==3.4.0
marshmallow-dataclass==6.0.0
marshmallow-enum==1.5.1
marshmallow-polyfield==5.8
matrix-client==0.3.2
mccabe==0.6.1
mirakuru==2.1.2
multiaddr==0.0.9
mypy==0.770
mypy-extensions==0.4.3
netaddr==0.7.19
netifaces==0.10.9
networkx==2.3
objgraph==3.4.1
packaging==24.0
parsimonious==0.8.1
pathspec==0.11.2
pdbpp==0.10.3
pexpect==4.7.0
pickleshare==0.7.5
pkginfo==1.10.0
pluggy==1.2.0
protobuf==3.11.3
psutil==5.6.6
ptyprocess==0.6.0
py-ecc==1.4.7
py-evm==0.3.0a15
py-geth==2.1.0
py-solc==3.2.0
pycodestyle==2.5.0
pycparser==2.19
pycryptodome==3.8.2
pyethash==0.1.27
pyflakes==2.1.1
Pygments==2.17.2
pylint==2.4.4
pyrepl==0.9.0
pyrsistent==0.15.7
pysha3==1.0.2
pytest==7.4.4
pytest-cov==4.1.0
pytest-gevent==1.1.0
pytest-runner==6.0.1
pytest-structlog==0.2
pytest-xdist==3.5.0
pytoml==0.1.20
pytz==2019.1
raiden==0.200.0rc9
raiden-contracts==0.37.0
-e git+https://github.com/raiden-network/raiden-services.git@ac396cd7eb1687b84bb479acfc08b667f5bcd955#egg=raiden_services
raiden-webui==0.11.0
readme-renderer==37.3
regex==2024.4.16
requests==2.22.0
requests-toolbelt==1.0.0
rlp==1.1.0
SecretStorage==3.3.3
semantic-version==2.6.0
semver==2.8.1
sentry-sdk==0.14.1
simplegeneric==0.8.1
six==1.12.0
snowballstemmer==2.2.0
Sphinx==1.8.4
sphinx-rtd-theme==0.4.2
sphinxcontrib-serializinghtml==1.1.5
sphinxcontrib-websupport==1.2.4
structlog==20.1.0
toml==0.10.2
tomli==2.0.1
toolz==0.9.0
tqdm==4.67.1
traitlets==4.3.2
trie==1.4.0
twine==3.1.1
typed-ast==1.4.3
typing-extensions==3.7.4.1
typing-inspect==0.4.0
urllib3==1.25.3
varint==1.0.2
watchdog==3.0.0
web3==5.9.0
webargs==5.3.1
webencodings==0.5.1
websockets==8.1
Werkzeug==0.15.4
wmctrl==0.5
wrapt==1.11.2
zipp==3.1.0

name: raiden-services
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - python=3.7.16=h7a1cb2a_0
  - readline=8.2=h5eee18b_0
  - setuptools=65.6.3=py37h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - alabaster==0.7.13
      - aniso8601==7.0.0
      - appdirs==1.4.4
      - asn1crypto==1.3.0
      - astroid==2.3.3
      - attrs==19.3.0
      - babel==2.14.0
      - base58==2.0.0
      - bitarray==1.2.1
      - black==19.10b0
      - blake2b-py==0.1.4
      - bleach==6.0.0
      - blinker==1.6.3
      - bump2version==1.0.1
      - cached-property==1.5.2
      - cachetools==3.1.1
      - certifi==2019.3.9
      - cffi==1.12.3
      - chardet==3.0.4
      - click==7.0
      - coincurve==13.0.0
      - colorama==0.4.1
      - coverage==7.2.7
      - cryptography==44.0.2
      - cytoolz==0.10.1
      - decorator==4.4.0
      - docutils==0.20.1
      - entrypoints==0.3
      - eth-abi==2.1.0
      - eth-account==0.5.2
      - eth-bloom==1.0.3
      - eth-hash==0.2.0
      - eth-keyfile==0.5.1
      - eth-keys==0.2.4
      - eth-rlp==0.1.2
      - eth-tester==0.4.0b2
      - eth-typing==2.2.1
      - eth-utils==1.8.4
      - exceptiongroup==1.2.2
      - execnet==2.0.2
      - fancycompleter==0.9.1
      - filelock==3.0.12
      - flake8==3.7.9
      - flake8-bugbear==20.1.2
      - flake8-tuple==0.4.1
      - flask==1.0.3
      - flask-cors==3.0.8
      - flask-restful==0.3.7
      - gevent==1.5a3
      - graphviz==0.13.2
      - greenlet==0.4.15
      - guppy3==3.0.9
      - hexbytes==0.2.0
      - idna==2.8
      - imagesize==1.4.1
      - importlib-metadata==1.5.0
      - iniconfig==2.0.0
      - ipfshttpclient==0.4.12
      - ipython==4.2.1
      - ipython-genutils==0.2.0
      - isort==4.3.21
      - itsdangerous==1.1.0
      - jeepney==0.9.0
      - jinja2==2.10.1
      - jsonschema==3.2.0
      - keyring==22.3.0
      - lazy-object-proxy==1.4.3
      - lru-dict==1.1.6
      - markupsafe==1.1.1
      - marshmallow==3.4.0
      - marshmallow-dataclass==6.0.0
      - marshmallow-enum==1.5.1
      - marshmallow-polyfield==5.8
      - matrix-client==0.3.2
      - mccabe==0.6.1
      - mirakuru==2.1.2
      - multiaddr==0.0.9
      - mypy==0.770
      - mypy-extensions==0.4.3
      - netaddr==0.7.19
      - netifaces==0.10.9
      - networkx==2.3
      - objgraph==3.4.1
      - packaging==24.0
      - parsimonious==0.8.1
      - pathspec==0.11.2
      - pdbpp==0.10.3
      - pexpect==4.7.0
      - pickleshare==0.7.5
      - pip==24.0
      - pkginfo==1.10.0
      - pluggy==1.2.0
      - protobuf==3.11.3
      - psutil==5.6.6
      - ptyprocess==0.6.0
      - py-ecc==1.4.7
      - py-evm==0.3.0a15
      - py-geth==2.1.0
      - py-solc==3.2.0
      - pycodestyle==2.5.0
      - pycparser==2.19
      - pycryptodome==3.8.2
      - pyethash==0.1.27
      - pyflakes==2.1.1
      - pygments==2.17.2
      - pylint==2.4.4
      - pyrepl==0.9.0
      - pyrsistent==0.15.7
      - pysha3==1.0.2
      - pytest==7.4.4
      - pytest-cov==4.1.0
      - pytest-gevent==1.1.0
      - pytest-runner==6.0.1
      - pytest-structlog==0.2
      - pytest-xdist==3.5.0
      - pytoml==0.1.20
      - pytz==2019.1
      - raiden==0.200.0rc9
      - raiden-contracts==0.37.0
      - raiden-webui==0.11.0
      - readme-renderer==37.3
      - regex==2024.4.16
      - requests==2.22.0
      - requests-toolbelt==1.0.0
      - rlp==1.1.0
      - secretstorage==3.3.3
      - semantic-version==2.6.0
      - semver==2.8.1
      - sentry-sdk==0.14.1
      - simplegeneric==0.8.1
      - six==1.12.0
      - snowballstemmer==2.2.0
      - sphinx==1.8.4
      - sphinx-rtd-theme==0.4.2
      - sphinxcontrib-serializinghtml==1.1.5
      - sphinxcontrib-websupport==1.2.4
      - structlog==20.1.0
      - toml==0.10.2
      - tomli==2.0.1
      - toolz==0.9.0
      - tqdm==4.67.1
      - traitlets==4.3.2
      - trie==1.4.0
      - twine==3.1.1
      - typed-ast==1.4.3
      - typing-extensions==3.7.4.1
      - typing-inspect==0.4.0
      - urllib3==1.25.3
      - varint==1.0.2
      - watchdog==3.0.0
      - web3==5.9.0
      - webargs==5.3.1
      - webencodings==0.5.1
      - websockets==8.1
      - werkzeug==0.15.4
      - wheel==0.42.0
      - wmctrl==0.5
      - wrapt==1.11.2
      - zipp==3.1.0
prefix: /opt/conda/envs/raiden-services

tests/pathfinding/test_claim_fees.py::test_claim_fees
tests/pathfinding/test_claim_fees.py::test_cli
src/pathfinding_service/claim_fees.py src/pathfinding_service/database.py
src/pathfinding_service/claim_fees.py src/pathfinding_service/database.py