Skip to content

Commit ea6bb09

Browse files
committed
fix(submit_api): improve transaction submission retries and error handling
- Remove use of contextlib.suppress for ReadTimeout, handle with try/except instead. - Increase post timeout from 60s to 300s for more robust network handling. - Refactor retry logic to properly handle "MempoolTxTooSlow" and ReadTimeout cases. - Improve error tracking and reporting in submit_tx, ensuring exceptions are captured and retried appropriately.
1 parent 45f3a8b commit ea6bb09

File tree

1 file changed

+20
-18
lines changed

1 file changed

+20
-18
lines changed

cardano_node_tests/utils/submit_api.py

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
"""Utilities for `cardano-submit-api` REST service."""
22

33
import binascii
4-
import contextlib
54
import dataclasses
65
import json
76
import logging
@@ -68,20 +67,16 @@ def post_cbor(*, cbor_file: clusterlib.FileType, url: str) -> requests.Response:
6867
if r > 1:
6968
LOGGER.warning(f"Resubmitting transaction to submit-api. Attempt {r}/{attempts}.")
7069

71-
response = None
72-
with contextlib.suppress(requests.exceptions.ReadTimeout):
73-
response = http_client.get_session().post(
74-
url, headers=headers, data=cbor_binary, timeout=60
75-
)
70+
response = http_client.get_session().post(
71+
url, headers=headers, data=cbor_binary, timeout=300
72+
)
7673

77-
if response is not None and not response and "MempoolTxTooSlow" in response.text:
78-
# Repeat the request as the transaction didn't make it to mempool
79-
pass
80-
elif response is not None:
81-
break
74+
if not response and "MempoolTxTooSlow" in response.text:
75+
if r < attempts:
76+
time.sleep(random.uniform(0, r))
77+
continue
8278

83-
if r < attempts:
84-
time.sleep(random.uniform(0, r))
79+
break
8580
else:
8681
err = f"Failed to submit the tx after {attempts} attempts."
8782
raise SubmitApiError(err)
@@ -132,20 +127,21 @@ def submit_tx(
132127
wait_blocks: A number of new blocks to wait for (default = 2).
133128
"""
134129
txid = ""
135-
err = None
130+
err: Exception | None = None
136131
attempts = 20
137132
for r in range(1, attempts + 1):
138133
if r == 1:
139-
txid = submit_tx_bare(tx_file=tx_file).txid
134+
try:
135+
txid = submit_tx_bare(tx_file=tx_file).txid
136+
except requests.exceptions.ReadTimeout as exc:
137+
err = exc
140138
else:
141-
if not txid:
142-
msg = "The TxId is not known."
143-
raise SubmitApiError(msg)
144139
LOGGER.warning(
145140
f"Resubmitting transaction '{txid}' (from '{tx_file}'). Attempt {r}/{attempts}."
146141
)
147142
try:
148143
submit_tx_bare(tx_file=tx_file)
144+
err = None
149145
except SubmitApiError as exc:
150146
# Check if resubmitting failed because an input UTxO was already spent
151147
exc_str = str(exc)
@@ -157,6 +153,10 @@ def submit_tx(
157153
raise
158154
err = exc
159155
# If here, the TX is likely still in mempool and we need to wait
156+
except requests.exceptions.ReadTimeout as exc:
157+
# If here, the TX might have been successfully submitted, but
158+
# the timeout occurred before we got response.
159+
err = exc
160160

161161
cluster_obj.wait_for_new_block(wait_blocks)
162162

@@ -168,6 +168,8 @@ def submit_tx(
168168
utxo_data = cluster_obj.g_query.get_utxo(utxo=txins[0])
169169
if not utxo_data:
170170
break
171+
172+
txid = txid or cluster_obj.g_transaction.get_txid(tx_file=tx_file)
171173
else:
172174
if err is not None:
173175
# Submitting the TX raised an exception as if the input was already

0 commit comments

Comments
 (0)