provider.broken_provider

Documentation for eth_defi.provider.broken_provider Python module.

Fixes and workaronds for various JSON-RPC service providers.

  • Mainly to deal with unstable blockchain chain tip

See also

Functions

get_almost_latest_block_number(web3)

Get the latest block number with workarounds for low quality JSON-RPC service providers.

get_block_tip_latency(web3)

What block tip latency we should use for this JSON-RPC provider

get_default_block_tip_latency(web3)

Workaround for Ankr and other node providers that do not handle the chain tip properly.

get_safe_cached_latest_block_number(web3, ...)

Get almost "latest" block to work around broken JSON-RPC providers.

set_block_tip_latency(web3, block_count)

Override the default block tip latency settings.

get_default_block_tip_latency(web3)

Workaround for Ankr and other node providers that do not handle the chain tip properly.

Likely due to how requests are broken a block number available in one call disappears in the following. Thus, with broken JSON-RPC service providers we cannot trust web3.eth.block_number to work and we need to subtract this number from it.

See get_block_tip_latency()

Returns

Number of blocks we need to subtract from the latest block

Parameters

web3 (web3.main.Web3) –

Return type

int

get_block_tip_latency(web3)

What block tip latency we should use for this JSON-RPC provider

  • Defaults to zero

  • If using eth_defi.provider.fallback.FallbackProvider we use 4 blocks latency as multiple providers are unlikely to agree on a chain tip (blocks have not propagated yet).

  • We have some built-in rules to work out specific providers

  • You can override this by setting the latency sa web3.block_tip_latency attribute

See the source code of get_default_block_tip_latency() for other rules.

Parameters

web3 (web3.main.Web3) –

Return type

int

set_block_tip_latency(web3, block_count)

Override the default block tip latency settings.

Useful for unit testing, because unit testing assumes stuff has happened in the latest block you want to read.

See get_block_tip_latency().

Parameters
  • web3 (web3.main.Web3) –

  • block_count (int) –

get_almost_latest_block_number(web3)

Get the latest block number with workarounds for low quality JSON-RPC service providers.

Use this method instead of web3.eth.block_number.

Because low quality providers may lose the block of this block number on the subsequent API calls, we add some number of delay or confirmations to the chain tip, specified by get_block_tip_latency().

Providers with known issues

  • LlamaNodes

  • Ankr

Example:

from eth_defi.provider.broken_provider import get_almost_latest_block_number

# We cannot query the chain head on Ankr or LlamaNodes,
# so get the almost head
if not block_number:
    block_number = get_almost_latest_block_number(web3)

timestamp = fetch_block_timestamp(web3, block_number)

token = fetch_erc20_details(web3, asset.address)
amount = token.fetch_balance_of(address, block_identifier=block_number)
Parameters

web3 (web3.main.Web3) –

Return type

int

get_safe_cached_latest_block_number(web3, chain_id, blocks=1000, cache_duration=3600)

Get almost “latest” block to work around broken JSON-RPC providers.

  • Not for high frequency usage, as it caches the block for delay seconds

  • No RPC call are made to

  • Disabled in Anvil configs

Work around the error on Monad/Arbitrum/dRPC/shitty RPCs:

{'message': 'upstream does not have the requested block yet', 'code': -32603}

Their internal routing is likely broken and when calling eth_call with latest the request fails for no reason.

Parameters
  • chain_id (int) – Chain id to use as part of the cache key

  • blocks – Number of blocks to subtract from the latest block

  • cache_duration (int) – Number of seconds to cache the result

  • web3 (web3.main.Web3) –

Returns

Latest block number minus blocks.

May return “latest” for special configs like unit tests.

Return type

Union[Literal[‘latest’, ‘earliest’, ‘pending’, ‘safe’, ‘finalized’], eth_typing.evm.BlockNumber, eth_typing.evm.Hash32, eth_typing.encoding.HexStr, int]