Stats (Statistics) - is a service designed to calculate and present statistical information from a Blockscout instance. This service establishes a connection with the Blockscout database and periodically updates a collection of charts, including lines and counters, based on a predefined schedule. The calculated data is then made available through a REST API, allowing users to access and utilize the statistical information.
The service consists of 2 parts, a stats calculation library and a transport layer that serves requests:
- stats - implements actual chart calculation logic as a library and exposes an interface to be used by the transport layer;
- A transport layer that implements some APIs over the service (stats-server).
- Postgresql database for this service
- Access to Blockscout database
-
You can build the provided sources using Dockerfile
-
Alternatively, you can use docker images from our registry
- You can use compose file from blockscout main repo to run latest version of stats with database
cargo install --git https://github.com/blockscout/blockscout-rs stats-server
stats-serverThe microservice can be controlled using configuration files and environmental variables. Envs have a priority over files.
Blockscout provides a collection of predefined charts to visualize statistics. You can enable or disable these charts by modifying the charts.json file. Layout of the charts (which is returned by the server) is configurable in layout.json. Schedule of updated charts for each group is set up in update_groups.json.
The default configurations can be found here. You can use these files as a base for customization.
If non-default config files are used, respective environment variables (e.g. STATS__CHARTS_CONFIG) should be set to the new files.
To disable unnecessary charts, open the charts.json file and set enabled: false for them. Other parameters can also be set/modified there.
An entry may set an optional implementation field so the public id keeps its own metadata (title, description, units) while its data comes from a different registered chart. Example: the Filecoin deployment serves txnsFee with the filecoinNewChainFees implementation (see STATS__ENABLE_ALL_FILECOIN).
The value is a chart id in snake_case, e.g. "filecoin_new_chain_fees". Startup fails if the target is unknown, of a different type, maps to itself, or is claimed by two entries. It also fails if the target is enabled under its own entry — a target must be an implementation-only id, so to reuse an already-enabled one, disable it too (enabled: false); serving one implementation under two ids is rejected, not resolved silently. Remap chains are unsupported. Via env (STATS_CHARTS__*__IMPLEMENTATION) a value can set or replace a mapping but not clear one from charts.json.
Categories for line charts, category metadata, and chart order within category are set in layout.json.
Charts dependant on each other are combined in update groups. Charts within one update group are updated together according to their dependency relations. Updates are scheduled for each such group in update_groups.json file.
Syntax for schedules specified in the config is parsed by rust cron crate, so refer to crate's documentation or source code for precise behaviour.
Some variables are hidden in a disclosure widget below the table.
| Variable | Required | Description | Default value |
|---|---|---|---|
STATS__DB_URL |
Postgres URL to stats db | `` | |
STATS__MODE |
Service mode: blockscout, multichain_aggregator, zetachain, or interchain. Modes are mutually exclusive. blockscout implies no zetachain CCTX and no multichain behavior. |
blockscout |
|
STATS__MULTICHAIN_FILTER |
An array of chain IDs used to filter input data in multichain_aggregator mode. Specified as a comma-separated list of identifiers without spaces (e.g. 10,130) |
null |
|
STATS__INTERCHAIN_PRIMARY_ID |
DEPRECATED: use STATS__INTERCHAIN_FILTER__HOME_CHAIN_ID. Still honoured and treated as exactly that value; setting both to different values is a startup error |
null |
|
STATS__INDEXER_DB_URL |
Postgres URL to indexer db; renamed from *_BLOCKSCOUT_DB_URL |
null |
|
STATS__BLOCKSCOUT_DB_URL |
Postgres URL to blockscout db. Renamed to *_INDEXER_DB_URL but left for backwards-compatibility |
null |
|
STATS__SECOND_INDEXER_DB_URL |
Postgres URL to second indexer db; i.e. zetachain cctx indexer db. Required if STATS__MODE=zetachain |
null |
|
STATS__LINKED_STATS__BASE_URL |
Base URL of an optional linked secondary stats service used to fill gaps in read responses. | null |
|
STATS__LINKED_STATS__TIMEOUT |
Timeout for linked secondary requests, in milliseconds | 3000 |
|
STATS__LINKED_STATS__MAX_HOPS |
Remaining hop budget propagated to linked secondary stats services. Missing incoming hop header starts with this value. Values above the hard cap of 4 are truncated. |
1 |
|
STATS__CREATE_DATABASE |
Create database on start | false |
|
STATS__RUN_MIGRATIONS |
Run migrations on start | false |
|
STATS__CHARTS_CONFIG |
Path to config file for charts | config/blockscout_instance/charts.json |
|
STATS__LAYOUT_CONFIG |
Path to config file for chart layout | config/blockscout_instance/layout.json |
|
STATS__UPDATE_GROUPS_CONFIG |
Path to config file for update groups | config/blockscout_instance/update_groups.json |
|
STATS__FORCE_UPDATE_ON_START |
Fully recalculate all charts on start | false |
|
STATS__CONCURRENT_START_UPDATES |
Amount of concurrent charts update on start | 3 |
|
STATS__DEFAULT_SCHEDULE |
Schedule used for update groups with no config | 0 0 1 * * * * |
|
STATS__LIMITS__REQUESTED_POINTS_LIMIT |
Maximum allowed number of requested points | 182500 |
|
STATS__BLOCKSCOUT_API_URL |
URL to Blockscout API. Used for conditional update start. Required unless STATS__IGNORE_BLOCKSCOUT_API_ABSENCE is set to true. |
null |
|
STATS__CONDITIONAL_START__CHECK_PERIOD_SECS |
Base time between start condition checking | 5 |
|
STATS__CONDITIONAL_START__BLOCKS_RATIO__ENABLED |
Enable blocks_ratio threshold |
true |
|
STATS__CONDITIONAL_START__BLOCKS_RATIO__THRESHOLD |
Value for blocks_ratio threshold |
0.98 |
|
STATS__CONDITIONAL_START__INTERNAL_TRANSACTIONS_RATIO__ENABLED |
Enable internal_transactions_ratio threshold |
true |
|
STATS__CONDITIONAL_START__INTERNAL_TRANSACTIONS_RATIO__THRESHOLD |
Value for internal_transactions_ratio threshold |
0.98 |
|
STATS__CONDITIONAL_START__USER_OPS_PAST_INDEXING_FINISHED__ENABLED |
Enable checking user ops indexing status | true |
|
STATS__CONDITIONAL_START__ZETACHAIN_INDEXED_UNTIL_TODAY__ENABLED |
Enable checking zetachain indexing stats, e.g. false. If not set, value is the same as STATS__MODE=zetachain |
null |
|
STATS__IGNORE_BLOCKSCOUT_API_ABSENCE |
Disable requirement for blockscout api url setting. Turns off corresponding features if the api setting is not set | false |
|
STATS__DISABLE_INTERNAL_TRANSACTIONS |
Disable functionality that utilizes internal transactions. In particular, disable internal transactions ratio check for starting the service and related charts (newContracts, lastNewContracts, and contractsGrowth). It has a higher priority than config files and respective envs. |
false |
|
STATS__ENABLE_ALL_ARBITRUM |
Enable Arbitrum-specific charts. Variable for convenience only, the same charts can be enabled one-by-one. | false |
|
STATS__ENABLE_ALL_OP_STACK |
Enable OP-Stack-specific charts. Variable for convenience only, the same charts can be enabled one-by-one. | false |
|
STATS__ENABLE_ALL_EIP_7702 |
Enable EIP-7702-specific charts. Variable for convenience only, the same charts can be enabled one-by-one. | false |
|
STATS__ENABLE_ALL_FILECOIN |
Enable the Filecoin-specific API surface: filecoinChainFeesGrowth is enabled under its own id, and the public txnsFee id is force-enabled and served with the filecoinNewChainFees implementation (chain-wide fees); filecoinNewChainFees is never exposed as a public chart id. |
false |
|
STATS__API_KEYS__<KEY_NAME> |
E.g. very_secure_key_value. Allows access to key-protected functinoality |
null |
|
STATS__INTERCHAIN_FILTER__BRIDGE_IDS |
Restriction on the interchain indexer's bridge ids, comma-separated | null |
|
STATS__INTERCHAIN_FILTER__COUNTERPARTY_CHAIN_IDS |
Counterparties of the focal chain, comma-separated (e.g. 10,137). Without ..__HOME_CHAIN_ID this is a conjunction, not a focal OR: it keeps only routes with both endpoints inside the set (src IN set AND dst IN set) |
null |
|
STATS__INTERCHAIN_FILTER__DST_CHAIN_IDS |
Additional restriction on the destination chain, comma-separated. Applied as a separate AND term. A message with no known destination is excluded by it, because dst IN (...) is NULL for a NULL destination |
null |
|
STATS__INTERCHAIN_FILTER__HOME_CHAIN_ID |
Focal chain for interchain mode. With ..__COUNTERPARTY_CHAIN_IDS keeps (src = home AND dst IN counterparties) OR (dst = home AND src IN counterparties); alone keeps src = home OR dst = home |
null |
|
STATS__INTERCHAIN_FILTER__INCLUDE_UNINDEXED_CHAINS |
Mirrors the indexer read API flag of the same name, including its default. false keeps only rows the row's own bridge could have fully observed - in particular it excludes every message with no known destination. Set true to count everything the indexer stored |
false |
|
STATS__INTERCHAIN_FILTER__SRC_CHAIN_IDS |
Additional restriction on the source chain, comma-separated. Applied as a separate AND term, never folded into the focal OR | null |
When linked_stats is configured, the intended topology is one primary stats service with at most one linked secondary service. Chaining is technically possible because a secondary service can also be configured with its own linked_stats, but this should be avoided unless there is a clear operational reason: it increases latency and complexity, and careless configuration can still create cycles.
In order to prevent incorrect statistics from being collected, there is an option to automatically delay chart update. This is controlled by STATS_CONDITIONAL_START_* environmental variables.
The service will periodically check the enabled start conditions and start updating charts once they are satisfied.
In interchain mode the service reads a universal interchain indexer: one database that can hold every chain and every bridge that indexer can reach. The STATS__INTERCHAIN_FILTER__* variables select the subset a given stats deployment counts.
Two properties follow from that, and they drive everything else in this section:
- The filter is applied when charts are computed, not when they are served. One stats deployment materialises exactly one subset into its own database. There is no per-request filtering; a second subset needs a second deployment.
- Stats configuration and an indexer API request must describe the same subset, or the dashboard and the list view behind it will disagree with each other while both are internally correct — they were simply asked different questions.
Each variable mirrors an indexer read-API query parameter of the same name, including its default. The predicate is not a re-implementation: stats depends on the indexer's interchain-indexer-filters crate and evaluates the same code, so no one has to keep two copies of the truth table in agreement.
That guarantee is per revision, not permanent. stats/Cargo.toml pins those crates to one git rev, so stats keeps rendering the predicate as of that rev; if the deployed indexer runs a newer one with a changed filter — a new dimension, a different focal truth table, a changed NULL rule — the two disagree until the pin is bumped, and each looks internally correct while doing so. Treat bumping that pin as a release step whenever the indexer's filter changes, and keep the deployed indexer's revision in mind when comparing a stats number against an API response.
| Stats env variable | Indexer API query parameter |
|---|---|
STATS__INTERCHAIN_FILTER__HOME_CHAIN_ID |
home_chain_id |
STATS__INTERCHAIN_FILTER__COUNTERPARTY_CHAIN_IDS |
counterparty_chain_ids |
STATS__INTERCHAIN_FILTER__SRC_CHAIN_IDS |
src_chain_ids |
STATS__INTERCHAIN_FILTER__DST_CHAIN_IDS |
dst_chain_ids |
STATS__INTERCHAIN_FILTER__BRIDGE_IDS |
bridge_ids |
STATS__INTERCHAIN_FILTER__INCLUDE_UNINDEXED_CHAINS |
include_unindexed_chains |
At startup the service logs the configured filter once, as a SQL WHERE clause (configured interchain read filter: …, or <unfiltered>), and it is worth reading after every configuration change. Read it as what you configured, not as what will be counted: the indexed-chain restriction is read from the indexer database on each update cycle and so cannot appear on that line, which means an otherwise unconfigured deployment logs <unfiltered> while still excluding rows. The line carries include_unindexed_chains as a field so the restriction's presence is visible; its resolved contents are logged per cycle at DEBUG (resolved the interchain observability horizon for this cycle).
COUNTERPARTY_CHAIN_IDSwithoutHOME_CHAIN_IDis a conjunction, not a focalOR. With a home chain it restricts the other endpoint:(src = home AND dst IN set) OR (dst = home AND src IN set). Without one it meanssrc IN set AND dst IN set— only routes with both endpoints inside the set survive. That is the indexer API's behaviour too, and the service warns about it at startup.INCLUDE_UNINDEXED_CHAINSdefaults tofalse, and that default excludes rows. It matches the indexer API's own default, so an unconfigured stats instance and an unparameterised API request answer the same question. What it excludes is every row its own bridge could not have observed from both sides — in particular every message whose destination is still unknown (dst_chain_id IS NULL), plus any row with an endpoint outside its bridge's indexed chain set. Set it totrueto count everything the indexer stored.- The "indexed chain set" comes from the indexer's database, not from stats configuration. Stats re-derives it from the indexer's own
bridges/bridge_contractstables at the start of every update cycle in which the restriction is enabled. There is no stats variable for it, and there is deliberately none: it is the indexer's fact about itself, and stats must not be able to disagree. If that read fails, the update group is skipped and retried on its next schedule, rather than computed without the restriction. STATS__INTERCHAIN_PRIMARY_IDis deprecated. It is still honoured and means exactlySTATS__INTERCHAIN_FILTER__HOME_CHAIN_ID. Setting both to the same value logs a deprecation warning; setting them to different values is a hard startup error, not a silent precedence rule.- Changing the filter rebuilds the affected charts by itself. A fingerprint of the configured filter is stored alongside every interchain point; on the next update a mismatch clears the stored series and recomputes it. Budget for one full backfill after a filter change; no manual intervention is needed, and none should be attempted.
For any STATS__INTERCHAIN_FILTER__* configuration there is an equivalent indexer API request that returns the same subset, and vice versa — except after something is removed from the indexer's bridges configuration. Both exceptions have the same single cause: the indexer derives its indexed chain set from its in-memory configuration, while stats derives it from the bridges and bridge_contracts tables, and the indexer's upserts into those tables never delete. A removal therefore shrinks the indexer's set and leaves stats' set as it was. Which way the numbers then diverge depends on what was removed, and the two directions are opposite:
- A bridge contract removed from a bridge that still exists ⇒ stats counts more than the API. The API stops admitting that bridge's rows whose endpoint is the dropped chain; stats still has the
bridge_contractsrow, so it keeps admitting them. - A whole bridge removed ⇒ stats counts less than the API. The bridge is simply absent from the API's restriction, and the shared predicate deliberately admits an absent bridge's rows unconditionally — its already-indexed history must not be reinterpreted (only messages with an unknown destination stay excluded). Stats still has the bridge's
bridgesrow, so it keeps testing its rows against the chain set recorded for it and drops any that fall outside.
Neither is repaired by a forced recompute: it re-reads the same stale tables. Both are documented rather than fixed; closing them needs the indexer to publish its effective set, not a workaround on the stats side. Neither is reachable without an edit to the indexer's configuration — a steady-state deployment is at parity.
The stored fingerprint covers the configured chain and bridge lists plus whether the indexed-chain restriction is enabled. It deliberately does not cover the resolved chain set itself, because that set grows on its own whenever the indexer gains a bridge or a bridge contract — hashing it would rebuild every interchain chart on every upstream bridge addition.
The cost of that choice: when the indexer's set widens — a redeploy that adds a bridge or a bridge contract — points already computed under the narrower one stay narrower than freshly computed points, and nothing detects the difference. A one-off restart with STATS__FORCE_UPDATE_ON_START=true makes the history uniform again in that direction.
It does not repair a narrowing, which is reachable mainly by starting stats before the indexer has populated bridges at all: a forced update recomputes and overwrites, but never deletes, so days that now yield no rows keep the values they had. Recovering from that means clearing the affected charts' stored data; only a filter-fingerprint change does that on its own.
Rolling back to a pre-filter build needs the same manual clear, and is the one case where it is easy to forget. The old build stores a constant where the new one stores a fingerprint, so it does see a mismatch and does recompute from scratch — but it recomputes with the old predicate, and the recompute only overwrites. Any day whose sole row is admitted by the new predicate and rejected by the old one therefore keeps its new value, and the series ends up mixing the two definitions with nothing to indicate it. This is reachable, not theoretical: the transfer *_sent / *_received charts changed which columns they scope on, so a transfer whose token source chain is the home chain while its parent message's route is not is exactly such a row. Clear the interchain charts' stored data as part of the rollback, before the old build's first update cycle; do not rely on it to clean up after itself.
# was: STATS__INTERCHAIN_PRIMARY_ID=<P>
STATS__INTERCHAIN_FILTER__HOME_CHAIN_ID=<P>
STATS__INTERCHAIN_FILTER__INCLUDE_UNINDEXED_CHAINS=true # keep the old, wider scopeThat reproduces the old scope as closely as the new model can, but some numbers still move:
- The four unscoped charts become scoped.
totalInterchainMessages,totalInterchainTransfers,newMessagesInterchainandnewTransfersInterchainpreviously counted everything the indexer held, ignoringSTATS__INTERCHAIN_PRIMARY_IDentirely. They keep their ids and now count within the configured scope, so with a home chain set they narrow to routes touching it. - The message
*_sent/*_receivedcharts do not move on account of the focal predicate. With only a home chain configured, the filter'ssrc = P OR dst = Pis absorbed by the chart's ownsrc = P(ordst = P) term, so the result is the same predicate as before. They move only if another filter dimension is also set, or if the indexed-chain restriction is left enabled. - The transfer
*_sent/*_receivedcharts move regardless, for two independent reasons. Their scope is now the transfer's own token source/destination chains rather than its parent message's route — the two answer genuinely different questions, not coarser and finer versions of one. And their join to the parent message is now on(message_id, bridge_id)rather thanmessage_idalone, which corrects an over-count that occurred whenever two bridges reused the same numeric message id. The second reason applies with no filter configured at all.totalInterchainTransferUsersmoves for the same two reasons; it no longer joins to messages at all.
How large that movement is for a particular deployment is characterised by the test fixtures rather than measured against production. There is no deployment in the target (universal, multi-bridge) configuration to measure: today's deployments read indexers that already filter at write time, where the indexed-chain restriction is close to a no-op, so numbers taken from them would describe a dataset that does not resemble the one this feature exists for.
Server settings
| Variable | Required | Description | Default value |
|---|---|---|---|
STATS__SERVER__GRPC__ADDR |
Address for the gRPC server to listen on | 0.0.0.0:8051 |
|
STATS__SERVER__GRPC__ENABLED |
Enable the gRPC server | false |
|
STATS__SERVER__HTTP__ADDR |
Address for the HTTP server to listen on | 0.0.0.0:8050 |
|
STATS__SERVER__HTTP__CORS__ALLOWED_CREDENTIALS |
Allow credentials in CORS requests | true |
|
STATS__SERVER__HTTP__CORS__ALLOWED_METHODS |
List of allowed HTTP methods for CORS | PUT, GET, POST, OPTIONS, DELETE, PATCH |
|
STATS__SERVER__HTTP__CORS__ALLOWED_ORIGIN |
Allowed origin for CORS requests | `` | |
STATS__SERVER__HTTP__CORS__BLOCK_ON_ORIGIN_MISMATCH |
Block requests if origin does not match | false |
|
STATS__SERVER__HTTP__CORS__ENABLED |
Enable CORS | false |
|
STATS__SERVER__HTTP__CORS__MAX_AGE |
Max age for CORS preflight request caching (in seconds) | 3600 |
|
STATS__SERVER__HTTP__CORS__SEND_WILDCARD |
Send wildcard for allowed origins in CORS | false |
|
STATS__SERVER__HTTP__ENABLED |
Enable the HTTP server | true |
|
STATS__SERVER__HTTP__MAX_BODY_SIZE |
Maximum allowed size for HTTP request bodies (in bytes) | 2097152 |
|
STATS__SERVER__HTTP__BASE_PATH |
Path prefix to use before all services' endpoints. E.g. "/abcd" will make the service endpoints start with /abcd/api/v1/... instead of /api/v1/... |
null |
Tracing settings
| Variable | Required | Description | Default value |
|---|---|---|---|
STATS__JAEGER__AGENT_ENDPOINT |
Jaeger agent endpoint for tracing | 127.0.0.1:6831 |
|
STATS__JAEGER__ENABLED |
Enable Jaeger tracing | false |
|
STATS__TRACING__ENABLED |
Enable tracing | true |
|
STATS__TRACING__FORMAT |
Tracing format to use, either 'default' or 'json' | default |
Metrics settings
| Variable | Required | Description | Default value |
|---|---|---|---|
STATS__METRICS__ADDR |
Address for the metrics server to listen on | 0.0.0.0:6060 |
|
STATS__METRICS__ENABLED |
Enable the metrics server | false |
|
STATS__METRICS__ROUTE |
Route for exposing metrics | /metrics |
| Variable | Required | Description | Default value |
|---|---|---|---|
STATS_CHARTS__COUNTERS__<COUNTER_NAME>__DESCRIPTION |
Counter <COUNTER_NAME> description, e.g. "Some description" |
null |
|
STATS_CHARTS__COUNTERS__<COUNTER_NAME>__ENABLED |
Enable counter <COUNTER_NAME>, e.g. true |
null |
|
STATS_CHARTS__COUNTERS__<COUNTER_NAME>__TITLE |
Displayed name of <COUNTER_NAME>, e.g. "Some title with {{<variable_name>}}" |
null |
|
STATS_CHARTS__COUNTERS__<COUNTER_NAME>__UNITS |
Measurement units for the counter, e.g. "Bytes" |
null |
|
STATS_CHARTS__LINE_CHARTS__<LINE_CHART_NAME>__DESCRIPTION |
Line chart <LINE_CHART_NAME> description, e.g. "Some description with {{<variable_name>}}" |
null |
|
STATS_CHARTS__LINE_CHARTS__<LINE_CHART_NAME>__ENABLED |
Enable <LINE_CHART_NAME>, e.g. true |
null |
|
STATS_CHARTS__LINE_CHARTS__<LINE_CHART_NAME>__RESOLUTIONS__DAY |
Enable daily data for the chart, e.g. true |
null |
|
STATS_CHARTS__LINE_CHARTS__<LINE_CHART_NAME>__RESOLUTIONS__WEEK |
Enable weekly data | null |
|
STATS_CHARTS__LINE_CHARTS__<LINE_CHART_NAME>__RESOLUTIONS__MONTH |
Enable monthly data | null |
|
STATS_CHARTS__LINE_CHARTS__<LINE_CHART_NAME>__RESOLUTIONS__YEAR |
Enable yearly data | null |
|
STATS_CHARTS__LINE_CHARTS__<LINE_CHART_NAME>__TITLE |
Displayed name of <LINE_CHART_NAME>, e.g. "Some line chart title" |
null |
|
STATS_CHARTS__LINE_CHARTS__<LINE_CHART_NAME>__UNITS |
Measurement units, e.g. "{{<variable_name>}}" |
null |
|
STATS_CHARTS__TEMPLATE_VALUES__<VARIABLE_NAME> |
Value to substitute instead of {{<variable_name>}}, e.g. STATS_CHARTS__TEMPLATE_VALUES__NATIVE_COIN_SYMBOL="some_value". See full list of variables in charts config file (charts.json). |
null |
|
STATS_CHARTS__COUNTERS__<COUNTER_NAME>__IMPLEMENTATION |
Serve counter <COUNTER_NAME> with the implementation of another registered counter; the value is a chart id in snake_case, e.g. "total_txns". The env value can set or replace a mapping but cannot clear one defined in charts.json (remove implementation from the JSON entry instead) |
null |
|
STATS_CHARTS__LINE_CHARTS__<LINE_CHART_NAME>__IMPLEMENTATION |
Serve <LINE_CHART_NAME> with the implementation of another registered line chart; the value is a chart id in snake_case, e.g. "filecoin_new_chain_fees". The env value can set or replace a mapping but cannot clear one defined in charts.json (remove implementation from the JSON entry instead) |
null |
| Variable | Required | Description | Default value |
|---|---|---|---|
STATS_LAYOUT__COUNTERS_ORDER__<COUNTER_NAME> |
Override position of <COUNTER_NAME> in the layout; 0 will place it first and N will place it Nth in the layout |
null |
|
STATS_LAYOUT__LINE_CHART_CATEGORIES__<CATEGORY_NAME>__ORDER |
Override position of <CATEGORY_NAME> in the layout |
null |
|
STATS_LAYOUT__LINE_CHART_CATEGORIES__<CATEGORY_NAME>__CHARTS_ORDER__<LINE_CHART_NAME> |
Override position of <LINE_CHART_NAME> within its category |
null |
|
STATS_LAYOUT__LINE_CHART_CATEGORIES__<CATEGORY_NAME>__TITLE |
Displayed name of the category, e.g. "Accounts" |
null |
| Variable | Required | Description | Default value |
|---|---|---|---|
STATS_UPDATE_GROUPS__SCHEDULES__<UPDATE_GROUP_NAME> |
Override update schedule of the group, e.g. "0 0 */3 * * * *" for update each 3 hours |
null |
just start-postgres-
Start blockscout instance with varialbe
DATABASE_URL=postgres://postgres:admin@host.docker.internal:5432/blockscout -
Start stats server:
export STATS__RUN_MIGRATIONS=true
export STATS__DB_URL="postgres://postgres:admin@localhost:5432/stats"
export STATS__BLOCKSCOUT_DB_URL="postgres://postgres:admin@localhost:5432/blockscout"
cargo run --bin stats-serverAlternatively, you can use docker-compose.dev.yml for simplicity.
- Set
ETHEREUM_JSONRPC_HTTP_URLandETHEREUM_JSONRPC_TRACE_URLto ethereum node you have access to (inbackend(Blockscout) service) - Set
FIRST_BLOCKto some recent block for less load on the node - Update
ETHEREUM_JSONRPC_VARIANTif necessary - Run
docker compose -f docker-compose.dev.yml up -d