Extracting Block-by-Block Price Data#
Setting Up Oracle#
To set up a pricing oracle, a Full Node is required to extract historical swap events. When an oracle is initialized, it generates a list of all Uniswap V3 pools to extract prices from. It will also query the timestamp for every 10,000th block (configurable through timestamp_resolution param) to allow approximate block-to-date conversion.
import logging
from nethermind.entro import Factory
from eth_utils import to_checksum_address
project_logger = logging.getLogger("my_project")
project_logger.setLevel(logging.INFO)
factory = Factory(
sqlalchemy_db_uri="postgresql://postgres:postgres@localhost:5432/postgres",
w3="https://infura.io/v3/...",
logger=project_logger,
)
oracle_instance = factory.initialize_oracle()
.. note::
Unlike the Pool Simulations, the Oracle can be initialized from a standard full node (e.g. Infura) instead of
a full archive node. The RPC call requirements are also significantly reduced, which makes this a much more
lightweight process.
Extracting Historical Prices#
WETH_ADDRESS = to_checksum_address("0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2")
current_block = oracle_instance.w3.eth.block_number
# Backfill ~1 month of ETH prices.
oracle_instance.backfill_prices(token_id=WETH_ADDRESS, start=current_block - 225_000)
>>> Backfilling PoolCreated Events: 100%|██████████| 1/1 [00:00<00:00, 21.2s/it]
>>> Backfilling Swap Events: 100%|██████████| 225/225 [01:14<00:00, 3.03it/s]
Updating Backfilled prices#
Once prices are backfilled up to the current block, it is easy to create a cronjob or DAG to keep all price feeds up to date. The update_prices method will query the latest block and update all prices for the last 10,000 blocks.
If the price backfill for a token is more than 10k blocks behind the current chain head, the update_prices method will skip these tokens and log a warning to avoid stalling the update task backfilling years of history. First run the backfill_prices method to catch up to the current block, then run update_prices to keep prices up to date.
oracle_instance.update_prices()
>>> Backfilling Swap Events: 100%|██████████| 3/3 [00:01<00:00, 4.23it/s]