fetcher.core
Implements Core that is used in other modules.
- class web3cat.fetcher.core.Core(rpc: Optional[str] = None, cache_path: Optional[str] = None, block_grid_step: int = 1000, w3: Optional[Web3] = None, conn: Optional[Connection] = None)
Bases:
objectA base class for any class that wants to use an Ethereum RPC or Sqlite3 cache database.
When deriving this class, you’re providing arguments like rpc url or OS path to the database. The resources are instantiated on demand though. It means that if you’re just using the Ethereum RPC it’s sufficient to supply only the rpc endpoint and skip OS path to the database in the constructor.
So this class lightweight and safe to derive from any other class.
Caching
The web3 instance and chain_id are cached by the rpc url key. The sqlite3 connection is cached by the OS path of the database.
While this might not work well in a multi-threaded scenario, for single-threaded there’s no overhead like making new connections and, for example, querying chain_id each time it’s accessed.
Block grid
It’s often desirable to convert block number to timestamp and vice versa. In a way, blocks are blockchain-readable, and timestamps are human-readable.
However, fetching every single block is impractical in many cases.
That’s why the following algorithm is used for timestamp estimation:
We make a block number grid with a width specified by the
block_grid_stepparameter.For each block number, we take the two closest grid blocks (below and above).
Fetch the grid blocks
Assume \(a_n\) and \(a_t\) is a number and a timestamp for the block above
Assume \(b_n\) and \(b_t\) is a number and a timestamp for the block below
Assume \(c_n\) and \(c_t\) is a number and a timestamp for the block we’re looking for
\(w = (c_n - b_n) / (a_n - b_n)\)
Then \(c_t = b_t \cdot (1-w) + a_t * w\)
This algorithm gives a reasonably good approximation for the block timestamp and considerably reduces the number of block fetches. For example, if we have 500 events happening in the 1000 - 2000 block range, then we fetch only two blocks (1000, 2000) instead of 500.
If you still want the exact precision, use
block_grid_step = 1.Warning
It’s highly advisable to use a single
block_grid_stepfor all data. Otherwise (in theory) the happens-before relationship might be violated for the data points.- Parameters:
rpc – An https Ethereum RPC endpoint uri
cache_path – OS path to the cache database
block_grid_step – Distance between two adjacent grid blocks
w3 – an instance of web3 (overrides rpc)
conn – an instance of database connection (overrides cache_path)
- cache: str | None
OS path to the cache database. Can be
Noneifsqlite3.Connectionis injected directly.
- property chain_id
Chain id for the current web3 connection
- property conn: Connection
sqlite3.Connectionto a database cache
- web3cat.fetcher.core.connection_from_path(path: str) Connection
Creates a connection to a database at
path. If the file atpathdoesn’t exist, creates a new one and initializes a database schema.- Parameters:
path – The absolute path to the database
- Returns:
An instance of sqlite3 Connection
Note
The schema migrations are currently not supported.