Skip to content

Commit

Permalink
feat: handle 429 on chain id re
Browse files Browse the repository at this point in the history
  • Loading branch information
antazoey committed Dec 6, 2024
1 parent db57e9b commit 66ec76e
Showing 1 changed file with 32 additions and 2 deletions.
34 changes: 32 additions & 2 deletions ape_infura/provider.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import os
import random
import time
from collections.abc import Callable
from functools import cached_property
from typing import Optional

from ape.api import UpstreamProvider
from ape.exceptions import ContractLogicError, ProviderError, VirtualMachineError
from ape.logging import logger
from ape_ethereum.provider import Web3Provider
from requests import Session
from requests import HTTPError, Session
from web3 import HTTPProvider, Web3
from web3.exceptions import ContractLogicError as Web3ContractLogicError
from web3.exceptions import ExtraDataLengthError
Expand All @@ -16,6 +19,7 @@
from web3.middleware import ExtraDataToPOAMiddleware # type: ignore
except ImportError:
from web3.middleware import geth_poa_middleware as ExtraDataToPOAMiddleware # type: ignore

from web3.middleware.validation import MAX_EXTRADATA_LENGTH

_API_KEY_ENVIRONMENT_VARIABLE_NAMES = ("WEB3_INFURA_PROJECT_ID", "WEB3_INFURA_API_KEY")
Expand All @@ -36,6 +40,9 @@
"scroll": ("mainnet",),
}

_MAX_REQUEST_RETRIES = 5 # Number of retries before giving up
_REQUEST_RETRY_DELAY = 5 # Delay in seconds between retries


class InfuraProviderError(ProviderError):
"""
Expand Down Expand Up @@ -133,6 +140,10 @@ def ws_uri(self) -> Optional[str]:
def connection_str(self) -> str:
return self.uri

@property
def chain_id(self):
return _run_with_retry(lambda: self._web3.eth.chain_id)

def connect(self):
session = _get_session()
http_provider = HTTPProvider(self.uri, session=session)
Expand All @@ -154,7 +165,8 @@ def _needs_poa_middleware(self) -> bool:
linea = (59144, 59140)
blast = (11155111, 168587773)

if self._web3.eth.chain_id in (*optimism, *polygon, *linea, *blast):
chain_id = self.chain_id # NOTE: Includes retry mechanism
if chain_id in (*optimism, *polygon, *linea, *blast):
return True

for block_id in ("earliest", "latest"):
Expand Down Expand Up @@ -220,3 +232,21 @@ def get_virtual_machine_error(self, exception: Exception, **kwargs) -> VirtualMa

def _create_web3(http_provider: HTTPProvider) -> Web3:
return Web3(http_provider)


def _run_with_retry(
func: Callable, max_retries: int = _MAX_REQUEST_RETRIES, retry_delay: int = _REQUEST_RETRY_DELAY
):
retries = 0
while retries < max_retries:
try:
return func()
except HTTPError as err:
if err.response.status_code == 429:
logger.debug(f"429 Too Many Requests. Retrying in {retry_delay} seconds...")
time.sleep(retry_delay)
retries += 1
else:
raise # Re-raise non-429 HTTP errors

raise ProviderError(f"Exceeded maximum retries ({max_retries}).")

0 comments on commit 66ec76e

Please sign in to comment.