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!
- 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
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.
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
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
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
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.
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
.
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
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 .
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.
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 |
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
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"
.
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 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
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
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.
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
and v0.7
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 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.
Here are links to our API extensions and websocket API.
Pathfinder has a monitoring API which can be enabled with the --monitor-address
configuration option.
/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.
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.
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
provides a Prometheus metrics scrape endpoint. Currently the following metrics are available:
process_start_time_seconds
provides the unix timestamp at which pathfinder started
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"}
gateway_requests_total
gateway_requests_failed_total
gateway_request_duration_seconds
Labels:
method
, to retrieve a counter for a particular sequencer request typetag
- works with methods:
get_block
,get_state_update
- valid values:
pending
latest
- works with methods:
reason
- works with:
gateway_requests_failed_total
- valid values:
decode
starknet
rate_limiting
timeout
- works with:
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 thatmethod
gateway_requests_total{method="get_transaction", reason="decode"}
,reason
is only supported for failures.
current_block
currently sync'd block height of the nodehighest_block
height of the block chainblock_time
timestamp difference between the current block and its parentblock_latency
delay between current block being published and sync'd locallyblock_download
time taken to download current block's data excluding classesblock_processing
time taken to process and store the current blockblock_processing_duration_seconds
histogram of time taken to process and store a block
pathfinder_build_info
reports current version as aversion
property
See the guide.
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
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.