Skip to content

eqlabs/pathfinder

Repository files navigation

Welcome to Pathfinder

A Starknet full node giving you a safe view into Starknet.

Pathfinder is currently in alpha so expect some rough edges but it is already usable today!

Features

  • access the full Starknet state history
    • includes contract code and storage, and transactions
  • verifies state using Ethereum
    • calculates the Starknet state's Patricia-Merkle Trie root on a block-by-block basis and confirms it against L1
    • this means the contract code and storage are now locally verified
  • implements the Starknet JSON-RPC API
    • Starknet APIs like starknet.js or starknet.py full support using our JSON-RPC API for interacting with Starknet
  • run Starknet functions without requiring a Starknet transaction
    • executed against the local state
  • do fee estimation for transactions

Feedback

We appreciate any feedback, especially during this alpha period. This includes any documentation issues, feature requests and bugs that you may encounter.

For help or to submit bug reports or feature requests, please open an issue or alternatively visit the Starknet discord channel.

Hardware Requirements

Pathfinder hardware requirements depend greatly on your use case. The recommended configuration that allows for fast syncing and JSON-RPC queries (with limited concurrency) is:

  • 4 CPU cores
  • 8 GiB RAM
  • 250 GiB SSD storage

Running with Docker

The pathfinder node can be run in the provided Docker image. Using the Docker image is the easiest way to start pathfinder. If for any reason you're interested in how to set up all the dependencies yourself please check the Installation from source guide.

The following assumes you have Docker installed and ready to go. (In case of Ubuntu installing docker is as easy as running sudo snap install docker.)

The example below uses $HOME/pathfinder as the data directory where persistent files used by pathfinder will be stored. It is easiest to create the volume directory as the user who is running the docker command. If the directory gets created by docker upon startup, it might be unusable for creating files.

The following commands start the node in the background, also making sure that it starts automatically after reboot:

# Ensure the directory has been created before invoking docker
mkdir -p $HOME/pathfinder
# Start the pathfinder container instance running in the background
sudo docker run \
  --name pathfinder \
  --restart unless-stopped \
  --detach \
  -p 9545:9545 \
  --user "$(id -u):$(id -g)" \
  -e RUST_LOG=info \
  -e PATHFINDER_ETHEREUM_API_URL="https://sepolia.infura.io/v3/<project-id>" \
  -v $HOME/pathfinder:/usr/share/pathfinder/data \
  eqlabs/pathfinder

To check logs you can use:

sudo docker logs -f pathfinder

The node can be stopped using

sudo docker stop pathfinder

Updating the Docker image

When pathfinder detects there has been a new release, it will log a message similar to:

WARN New pathfinder release available! Please consider updating your node! release=0.14.3

You can try pulling the latest docker image to update it:

sudo docker pull eqlabs/pathfinder

After pulling the updated image you should stop and remove the pathfinder container then re-create it with the exact same command that was used above to start the node:

# This stops the running instance
sudo docker stop pathfinder
# This removes the current instance (using the old version of pathfinder)
sudo docker rm pathfinder
# This command re-creates the container instance with the latest version
sudo docker run \
  --name pathfinder \
  --restart unless-stopped \
  --detach \
  -p 9545:9545 \
  --user "$(id -u):$(id -g)" \
  -e RUST_LOG=info \
  -e PATHFINDER_ETHEREUM_API_URL="https://sepolia.infura.io/v3/<project-id>" \
  -v $HOME/pathfinder:/usr/share/pathfinder/data \
  eqlabs/pathfinder

Available images

Our images are updated on every pathfinder release. This means that the :latest docker image does not track our main branch here, but instead matches the latest pathfinder release.

Docker compose

You can also use docker-compose if you prefer that to just using Docker.

Create the folder pathfinder where your docker-compose.yaml is

mkdir -p pathfinder

# replace the value by of PATHFINDER_ETHEREUM_API_URL by the HTTP(s) URL pointing to your Ethereum node's endpoint
cp example.pathfinder-var.env pathfinder-var.env

docker-compose up -d

To check if it's running well use docker-compose logs -f.

Database Snapshots

Re-syncing the whole history for either the mainnet or testnet networks might take a long time. To speed up the process you can use database snapshot files that contain the full state and history of the network up to a specific block.

The database files are hosted on Cloudflare R2. There are two ways to download the files:

  • Using the Rclone tool
  • Via the HTTPS URL: we've found this to be less reliable in general

Rclone setup

We recommend using RClone. Add the following to your RClone configuration file ($HOME/.config/rclone/rclone.conf):

[pathfinder-snapshots]
type = s3
provider = Cloudflare
env_auth = false
access_key_id = 7635ce5752c94f802d97a28186e0c96d
secret_access_key = 529f8db483aae4df4e2a781b9db0c8a3a7c75c82ff70787ba2620310791c7821
endpoint = https://cbf011119e7864a873158d83f3304e27.r2.cloudflarestorage.com
acl = private

You can then download a compressed database using the command:

rclone copy -P pathfinder-snapshots:pathfinder-snapshots/sepolia-testnet_0.14.0_209745_pruned.sqlite.zst .

Uncompressing database snapshots

To avoid issues please check that the SHA2-256 checksum of the compressed file you've downloaded matches the value we've published.

We're storing database snapshots as SQLite database files compressed with zstd. You can uncompress the files you've downloaded using the following command:

zstd -T0 -d sepolia-testnet_0.14.0_209745_pruned.sqlite.zst -o testnet-sepolia.sqlite

This produces uncompressed database file testnet-sepolia.sqlite that can then be used by pathfinder.

Available database snapshots

Network Block Pathfinder version required Mode Filename Download URL Compressed size SHA2-256 checksum of compressed file
Mainnet 751397 >= 0.14.0 pruned mainnet_0.14.0_751397_pruned.sqlite.zst Download 71.03 GB 2f9aa8b98086c12a1ce14e89ddfe02ebf320a7ba47e63829056a405866568113
Mainnet 751250 >= 0.14.0 archive mainnet_0.14.0_751250_archive.sqlite.zst Download 433.13 GB 3540087b326b58437fd12bcf427eaeb6323f3efc3def56816b7e5fc06d2633ae
Sepolia testnet 209745 >= 0.14.0 pruned sepolia-testnet_0.14.0_209745_pruned.sqlite.zst Download 5.71 GB 5cc9a13079a36ee09c04824f6b30b5ce16cd2d26039b23c7c7937f57a76ba19b
Sepolia testnet 209758 >= 0.14.0 archive sepolia-testnet_0.14.0_209758_archive.sqlite.zst Download 18.93 GB 3c24a6e9e5294d738f5976e2c949ebac42ed3fc4865a21893df44897fe803686

Configuration

The pathfinder node options can be configured via the command line as well as environment variables.

The command line options are passed in after the docker run options, as follows:

sudo docker run --name pathfinder [...] eqlabs/pathfinder:latest <pathfinder options>

Using --help will display the pathfinder options, including their environment variable names:

sudo docker run --rm eqlabs/pathfinder:latest --help

Pending Support

Block times on mainnet can be prohibitively long for certain applications. As a workaround, Starknet added the concept of a pending block which is the block currently under construction. This is supported by pathfinder, and usage is documented in the JSON-RPC API with various methods accepting "block_id"="pending".

State trie pruning

Pathfinder allows you to control the number of blocks of state trie history to preserve. You can choose between archive:

--storage.state-tries = archive

which stores all of history, or to keep only the last k+1 blocks:

--storage.state-tries = k

The latest block is always stored, though in the future we plan an option to disable this entirely. Currently at least one block is required to trustlessly verify Starknet's state update.

State trie data consumes a massive amount of storage space. You can expect an overall storage reduction of ~75% when going from archive to pruned mode.

The downside to pruning this data is that storage proofs are only available for blocks that are not pruned i.e. with --storage.state-tries = k you can only serve storage proofs for the latest k+1 blocks.

Note that this only impacts storage proofs - for all other considerations pathfinder is still an archive mode and no data is dropped.

Also note that you cannot switch between archive and pruned modes. You may however change k between different runs of pathfinder.

If you don't care about storage proofs, you can maximise storage savings by setting --storage.state-tries = 0, which will only store the latest block's state trie.

Logging

Logging can be configured using the RUST_LOG environment variable. We recommend setting it when you start the container:

sudo docker run --name pathfinder [...] -e RUST_LOG=<log level> eqlabs/pathfinder:latest

The following log levels are supported, from most to least verbose:

trace
debug
info  # default
warn
error

Network Selection

The Starknet network can be selected with the --network configuration option.

If --network is not specified, network selection will default to match your Ethereum endpoint:

  • Starknet mainnet for Ethereum mainnet,
  • Starknet testnet for Ethereum Sepolia

Custom networks & gateway proxies

You can specify a custom network with --network custom and specifying the --gateway-url, feeder-gateway-url and chain-id options. Note that chain-id should be specified as text e.g. SN_SEPOLIA.

This can be used to interact with a custom Starknet gateway, or to use a gateway proxy.

JSON-RPC API

You can interact with Starknet using the JSON-RPC API. Pathfinder supports the official Starknet RPC API and in addition supplements this with its own pathfinder specific extensions such as pathfinder_getProof.

Currently, pathfinder supports v0.6, v0.7 and v0.8 versions of the Starknet JSON-RPC specification. The path of the URL used to access the JSON-RPC server determines which version of the API is served:

  • the v0.6.0 API is exposed on the /rpc/v0_6 path via HTTP and on /ws/rpc/v0_6 via Websocket
  • the v0.7.0 API is exposed on the /rpc/v0_7 path via HTTP and on /ws/rpc/v0_7 via Websocket
  • the v0.8.0-rc1 API is exposed on the /rpc/v0_8 path via both HTTP and Websocket
  • the pathfinder extension API is exposed on /rpc/pathfinder/v0.1 and /rpc/pathfinder/v0_1 via HTTP and /ws/rpc/pathfinder/v0_1 via Websocket.

Version of the API, which is served on the root (/) path via HTTP and on /ws via Websocket, can be configured via the pathfinder parameter --rpc.root-version (or the RPC_ROOT_VERSION environment variable).

Note that the pathfinder extension is versioned separately from the Starknet specification itself.

pathfinder extension API

Here are links to our API extensions and websocket API.

Monitoring API

Pathfinder has a monitoring API which can be enabled with the --monitor-address configuration option.

Health

/health provides a method to check the health status of your pathfinder node, and is commonly useful in Kubernetes docker setups. It returns a 200 OK status if the node is healthy.

Readiness

pathfinder does several things before it is ready to respond to RPC queries. In most cases this startup time is less than a second, however there are certain scenarios where this can be considerably longer. For example, applying an expensive database migration after an upgrade could take several minutes (or even longer) on testnet. Or perhaps our startup network checks fail many times due to connection issues.

/ready provides a way of checking whether the node's JSON-RPC API is ready to be queried. It returns a 503 Service Unavailable status until all startup tasks complete, and then 200 OK from then on.

Synced

Similar to /ready, /ready/synced checks whether the node's JSON-RPC API is ready to be queried and also checks if the node is synced (within 6 blocks of the current tip of the chain). It returns a 503 Service Unavailable status if either check fails, and 200 OK if they both pass.

This endpoint is useful for Docker nodes which only want to present themselves as ready after they have been synced.

Metrics

/metrics provides a Prometheus metrics scrape endpoint. Currently the following metrics are available:

Process metrics

  • process_start_time_seconds provides the unix timestamp at which pathfinder started

RPC related counters

  • rpc_method_calls_total,
  • rpc_method_calls_failed_total,

You must use the label key method to retrieve a counter for a particular RPC method, for example:

rpc_method_calls_total{method="starknet_getStateUpdate"}
rpc_method_calls_failed_total{method="starknet_chainId"}

You may also use the label key version to specify a particular version of the RPC API, for example:

rpc_method_calls_total{method="starknet_getEvents", version="v0.3"}

Feeder Gateway and Gateway related counters

  • gateway_requests_total
  • gateway_requests_failed_total
  • gateway_request_duration_seconds

Labels:

  • method, to retrieve a counter for a particular sequencer request type
  • tag
    • works with methods: get_block, get_state_update
    • valid values:
      • pending
      • latest
  • reason
    • works with: gateway_requests_failed_total
    • valid values:
      • decode
      • starknet
      • rate_limiting
      • timeout

Valid examples:

gateway_requests_total{method="get_block"}
gateway_requests_total{method="get_block", tag="latest"}
gateway_requests_failed_total{method="get_state_update"}
gateway_requests_failed_total{method="get_state_update", tag="pending"}
gateway_requests_failed_total{method="get_state_update", tag="pending", reason="starknet"}
gateway_requests_failed_total{method="get_state_update", reason="rate_limiting"}

These will not work:

  • gateway_requests_total{method="get_transaction", tag="latest"}, tag is not supported for that method
  • gateway_requests_total{method="get_transaction", reason="decode"}, reason is only supported for failures.

Sync related metrics

  • current_block currently sync'd block height of the node
  • highest_block height of the block chain
  • block_time timestamp difference between the current block and its parent
  • block_latency delay between current block being published and sync'd locally
  • block_download time taken to download current block's data excluding classes
  • block_processing time taken to process and store the current block
  • block_processing_duration_seconds histogram of time taken to process and store a block

Build info metrics

  • pathfinder_build_info reports current version as a version property

Build from source

See the guide.

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.