To run the tx service in tracing mode you will need a tracing compatible node:
- Erigon node (recommended).
- Deprecated OpenEthereum node with tracing enabled (
--tracing
flag) if it's still supported on your network. - Nethermind (archive mode so tracing is enabled).
- Any RPC that supports eth_getLogs if using the Safe L2 Version. From Safe v1.3.0 there's an alternative and recommended way to avoid using tracing, the L2 Safe version (https://github.com/safe-global/safe-deployments/blob/main/src/assets/v1.3.0/gnosis_safe_l2.json) that emits events, so no tracing node is required. This is the approach used in networks like Polygon or Binance Smart Chain where fees are cheap and emitting events don't impact the user:
- A tx service configured with a tracing node can index L2 and non L2 versions of the Safe contracts.
- A tx service configured without a tracing node can only index L2 versions of the Safe contracts. Indexing mode should not be changed after initializing the service, as the database could become corrupted, so if a tracing node was not set up it shouldn't be added later. The opposite is also problematic.
For indexing, basic RPC methods are required, and the service uses batching to query the RPC:
eth_getTransactionByHash
eth_getBlockByNumber
eth_getTransactionReceipt
eth_getLogs
(for indexing ERC20/721 transfers)eth_chainId
(just called once and cached)- ...
For the regular version of the Safe (not L2), tracing endpoints are used:
- trace_filter: For quick sync, but it could be disabled setting the configuration parameter
ETH_INTERNAL_NO_FILTER=False
. Be careful, it will make the service really slow when syncing from scratch. - trace_block
- trace_transaction
For the L2 version of the Safe, no special RPC methods are used. The most demanding one will be eth_getLogs to get the Safe events.
That's not written in stone. Tx service has some environment variables that can be configured to set a limit on the number of blocks that are processed together (ETH_EVENTS_BLOCK_PROCESS_LIMIT_MAX
), but the default behaviour is trying to detect the best configuration for every network similar to how TCP congestion control works.Indexer tries to process a low number of blocks (currently 50). Depending on that:
- If the request takes less than 1 second, the node can process more. The number of blocks to fetch is duplicated for the next request.
- If the request takes less than 3 seconds, the number of blocks to process is incremented by a small amount (currently 20).
- If the request takes more than 20 seconds, the number of blocks to process is decremented by a small amount (currently 20).
- If the request takes more than 30 seconds, the number of blocks to process is halved.
- If there is an exception when requesting the information (I/O error) number of blocks to process is reset to the minimum number of blocks (currently 1).
- All this happens in every request to the node used for indexing (safe transactions, erc20/721 events...).
Be careful, some nodes like Binance Smart Chain public nodes have a hardcoded limit of blocks they can process (5000 in the case of BSC). SetETH_EVENTS_BLOCK_PROCESS_LIMIT_MAX
to prevent the algorithm trying to process more blocks and erroring all the time
For RPC providers we expect communication on every update and configuration change as it could impact our indexers:
- Timeout for the requests.
- Number of batch requests allowed in the same HTTP request.
- Block range that can be queried in queries like eth_getLogs or trace_filter.
- Results limit for endpoints (e.g. some providers implement a limit to the number of results of queries like eth_getLogs). Indexer is expecting a failure and not getting capped results.