I switched to using Smoldot as looks like a lot of the RPC providers are shutting down. However noticed that a lot of queries are failing because of connection shutdowns. I vibe-coded a fix to reconnect/retry on failure but think it should probably be upstream.
class SafeSubstrate:
def __init__(
self,
connection: SubstrateInterface,
label: str,
reconnect_fn: Optional[Callable[[], SubstrateInterface]] = None
) -> None:
self._connection = connection
self._label = label
self._reconnect_fn = reconnect_fn
def query(self, module: str, storage_function: str, params: Optional[List[Any]] = None, block_hash: Optional[str] = None):
retries = int(os.environ.get('SMOLDOT_QUERY_RETRIES', '5'))
base_delay = float(os.environ.get('SMOLDOT_QUERY_BASE_DELAY', '0.5'))
params = params or []
for attempt in range(1, retries + 1):
try:
return self._connection.query(module, storage_function, params=params, block_hash=block_hash)
except SubstrateRequestException as exc:
if not is_transient_smoldot_error(exc) or attempt == retries:
raise
delay = base_delay * (2 ** (attempt - 1))
name = f"{self._label}.{module}.{storage_function}" if self._label else f"{module}.{storage_function}"
logger.warning(f"{name} failed with smoldot connection error (attempt {attempt}/{retries}); retrying in {delay:.2f}s")
if self._reconnect_fn is not None:
self._connection = self._reconnect_fn()
time.sleep(delay)
return self._connection.query(module, storage_function, params=params, block_hash=block_hash)
def __getattr__(self, name: str):
return getattr(self._connection, name)
def is_transient_smoldot_error(exc: SubstrateRequestException) -> bool:
error = exc.args[0] if exc.args else None
if isinstance(error, dict):
message = str(error.get('message', ''))
code = error.get('code')
else:
message = str(exc)
code = None
if code == -32000 and ('NoConnection' in message or 'ConnectionShutdown' in message):
return True
return 'NoConnection' in message or 'ConnectionShutdown' in message
I switched to using Smoldot as looks like a lot of the RPC providers are shutting down. However noticed that a lot of queries are failing because of connection shutdowns. I vibe-coded a fix to reconnect/retry on failure but think it should probably be upstream.