Request with one tape and one multihop tape source will crash submitter
Motivation
----------
Suppose in the `get_transfer_requests_and_source_replicas` main loop, a request is added with a multihop tape source. Then in another iteration, a direct tape source is identified. We end up in https://github.com/rucio/rucio/blob/740b825cac747280ca159089bca4635264c07fc1/lib/rucio/core/transfer.py#L968
Since the first source was multihop, we clear `transfers[req_id]['sources']` at https://github.com/rucio/rucio/blob/740b825cac747280ca159089bca4635264c07fc1/lib/rucio/core/transfer.py#L1005-L1009
Then shortly after, if the second source is tape, we will end up in https://github.com/rucio/rucio/blob/740b825cac747280ca159089bca4635264c07fc1/lib/rucio/core/transfer.py#L1042-L1050
where there is an unchecked access to `transfers[req_id]['sources'][0]` that crashes.

Modification
------------
In this situation, I believe we still want to prefer the direct tape source over the multihop tape source and want to take the path at L1047. So I would suggest modifying L1045 to
```python
if len(transfers[req_id]["sources"]) and (
    transfers[req_id]["sources"][0][3] > ranking
    or (
        transfers[req_id]["sources"][0][3] == ranking
        and transfers[req_id]["sources"][0][4] <= link_ranking
    )
):
    continue
```

diff --git a/lib/rucio/core/transfer.py b/lib/rucio/core/transfer.py
index c71ca30d0..bc3c71ebe 100644
--- a/lib/rucio/core/transfer.py
+++ b/lib/rucio/core/transfer.py
@@ -1029,12 +1029,6 @@ def get_transfer_requests_and_source_replicas(total_workers=0, worker_number=0,
                 if multihop:
                     continue
 
-                # The transfer queued previously is a multihop, but this one is direct.
-                # Reset the sources, remove the multihop flag
-                if transfers[req_id].get('multihop', False):
-                    transfers[req_id].pop('multihop', None)
-                    transfers[req_id]['sources'] = []
-
                 current_source_is_tape = transfers[req_id]['bring_online']
                 new_source_is_tape = ctx.is_tape_rse(source_rse_id) or ctx.rse_attrs(source_rse_id).get('staging_required', False)
 
@@ -1074,6 +1068,12 @@ def get_transfer_requests_and_source_replicas(total_workers=0, worker_number=0,
                     else:
                         continue
 
+                # The transfer queued previously is a multihop, but this one is direct.
+                # Reset the sources, remove the multihop flag
+                if transfers[req_id].get('multihop', False):
+                    transfers[req_id].pop('multihop', None)
+                    transfers[req_id]['sources'] = []
+
                 transfers[req_id]['sources'].append((rse, source_url, source_rse_id, ranking, link_ranking))
                 # if one source has force IPv4, force IPv4 for the whole job
                 use_ipv4 = ctx.rse_attrs(source_rse_id).get('use_ipv4', False)
['lib/rucio/core/transfer.py']