MultiprocessMulticallReader

Documentation for eth_defi.event_reader.multicall_batcher.MultiprocessMulticallReader Python class.

class MultiprocessMulticallReader

Bases: object

An instance created in a subprocess to do calls.

  • Specific to a chain (connection is married with a chain, otherwise stateless)

  • Initialises the web3 connection at the start of the process

  • If you try to read using multicall when the contract is not yet deployed (see get_multicall_block_number()) then you get no results

Create subprocess worker instance.

Parameters
  • web3factory – Initialise connection within the subprocess

  • batch_size

    How many calls we pack into the multicall.

    Manually tuned number if your RPC nodes start to crap out, as they hit their internal time limits.

Attributes summary

last_switch

How many calls ago we switched the fallback provider.

backswitch_threshold

Try to switch back from the fallback provider to the main provider after this many calls.

Methods summary

__init__(web3factory[, batch_size, ...])

Create subprocess worker instance.

call_multicall_with_batch_size(...)

Communicate with Multicall3 contract.

get_batch_size(web3, chain_id, block_identifier)

Fix non-standard out of gas issues.

get_block_timestamp(block_number)

get_gas_hint(chain_id, batch_calls)

Fix non-standard out of gas issues

process_calls(block_identifier, calls[, ...])

Work a chunk of calls in the subprocess.

__init__(web3factory, batch_size=40, backswitch_threshold=100, too_many_requets_sleep=61.0)

Create subprocess worker instance.

Parameters
  • web3factory (eth_defi.event_reader.web3factory.Web3Factory | web3.main.Web3) – Initialise connection within the subprocess

  • batch_size

    How many calls we pack into the multicall.

    Manually tuned number if your RPC nodes start to crap out, as they hit their internal time limits.

last_switch

How many calls ago we switched the fallback provider.

backswitch_threshold

Try to switch back from the fallback provider to the main provider after this many calls.

get_gas_hint(chain_id, batch_calls)

Fix non-standard out of gas issues

Parameters
Return type

int | None

get_batch_size(web3, chain_id, block_identifier)

Fix non-standard out of gas issues.

TODO: Move these rules to their own module.

Parameters
  • web3 (web3.main.Web3) –

  • chain_id (int) –

  • block_identifier (Union[Literal['latest', 'earliest', 'pending', 'safe', 'finalized'], eth_typing.evm.BlockNumber, eth_typing.evm.Hash32, eth_typing.encoding.HexStr, int]) –

Return type

int | None

call_multicall_with_batch_size(multicall_contract, block_identifier, batch_size, encoded_calls, require_multicall_result)

Communicate with Multicall3 contract.

  • Fail safes for ugly situations

Parameters
  • multicall_contract (web3.contract.contract.Contract) –

  • block_identifier (Union[Literal['latest', 'earliest', 'pending', 'safe', 'finalized'], eth_typing.evm.BlockNumber, eth_typing.evm.Hash32, eth_typing.encoding.HexStr, int]) –

  • batch_size (int) –

  • encoded_calls (list[tuple[eth_typing.evm.HexAddress, bytes]]) –

  • require_multicall_result (bool) –

Return type

list[tuple[bool, bytes]]

process_calls(block_identifier, calls, require_multicall_result=False, timestamp=None, min_fallback_retries=5)

Work a chunk of calls in the subprocess.

  • Divide unlimited number of calls to something we think Multicall3 and RPC node can handle

  • If a single batch fail

Parameters
  • require_multicall_result – Headache debug flag.

  • block_identifier (Union[Literal['latest', 'earliest', 'pending', 'safe', 'finalized'], eth_typing.evm.BlockNumber, eth_typing.evm.Hash32, eth_typing.encoding.HexStr, int]) – Block number

  • timestamp (datetime.datetime | None) – Block timestamp

  • min_fallback_retries – Bang all RPCs at least this many times when attempting to make progress.

  • calls (list[eth_defi.event_reader.multicall_batcher.EncodedCall]) –

Return type

Iterable[eth_defi.event_reader.multicall_batcher.EncodedCallResult]