Skip to main content

Setting up an EVM Gateway node

This guide is for running the EVM Gateway node on Flow. The EVM Gateway implements the Ethereum JSON-RPC specification and is the only node type which accepts EVM client connections.

The EVM Gateway consumes Flow protocol state from the configured Flow Access Node and persists the indexed EVM state locally to service EVM client requests. It submits EVM transactions it receives into the Flow network, wrapped in a Cadence transaction, and mutating EVM state when executed. Non-mutating RPC methods only query the local state index of the gateway and are never forwarded to Access Nodes. It does not participate in the block production process and requires no stake.

Who Should Run an EVM Gateway

The EVM Gateway can serve as a dedicated private RPC, a performance scaling solution, and a free gas provider offering similar capabilities to centralized middleware providers like Infura, Alchemy, etc at a fraction of the cost. This is because EVM Gateway nodes connect directly to the Flow network with no middle layer in between.

Applications which generate high call volumes to the JSON-RPC and which may have hit rate limits on Flow public nodes may benefit from running their own gateway to remove rate limits. Self-hosted gateways connect directly to public Flow Access Nodes, which can also be self-operated.

Hardware specifications

The EVM Gateway is a lightweight node which runs on commodity hardware and cloud VMs. It can be run on GCP standard and AWS large VM types for typical app co-location use-cases. However, higher volume use cases may require larger instance types and more testing. An inactive node requires less than 200MB memory when run in Docker and data storage growth corresponds with Flow EVM transaction growth. Listed below are theoretical RPS maximums based on mainnet CPU and memory resource utilization metrics and linear volume scaling assumptions.

Google Cloud Platform (GCP) VM Types

VM TypevCPUsMemory (GB)Estimated Max Requests/s
n2-standard-228~2,950
c4a-standard-114~1,475
c4a-standard-228~2,950
n2-highmem-4432~11,800
c3-standard-8832~29,500

Amazon Web Services (AWS) EC2 Instance Types

Instance TypevCPUsMemory (GB)Estimated Max Requests/s
m6i.large28~2,950
c6i.large24~3,687
m6i.xlarge416~11,800
c6i.2xlarge816~29,500
t3.2xlarge832~17,700

How To Run EVM Gateway

Step 1 - Account Creation

The EVM Gateway's role in mediating EVM transactions over to Cadence is how it accrues fees from handling client transactions. Since the gateway submits Cadence transactions wrapping EVM transaction payloads to the Flow Access Node the transaction fee for that must be paid by the EVM Gateway.

The account used for funding gateway Cadence transactions must be a COA, not an EOA. --coa-address is configured with the Cadence address of the COA account and the --coa-key must belong to the same account. The --coinbase account accrues EVM Gateway fees from EVM client transactions and can be either an EVM EOA or COA address.

It is acceptable to create a single Cadence account for the COA and use the EVM address associated with that for the COINBASE address.

Create Flow account to use for COA

If you don't already have a Flow account you will need to create one.

  1. Install Flow Wallet
  2. Once installed you will be able to copy the wallet address, similar to 0x1844efeb3fef2242
  3. Obtain account private key from
    Settings -> Account List -> Choose Main account -> Private Key -> [Password prompt]
  4. Ensure the wallet is funded from a CEX or other wallet

Step 2 - Build the gateway

To run EVM Gateway on bare metal or in a VM without the use of docker, select the 'Build from source' tab otherwise refer to the 'Build using Docker' tab.

This will build the EVM gateway binary from source.


_10
git clone https://github.com/onflow/flow-evm-gateway.git
_10
_10
cd flow-evm-gateway
_10
git checkout $(curl -s https://api.github.com/repos/onflow/flow-evm-gateway/releases/latest | jq -r .tag_name)
_10
CGO_ENABLED=1 go build -o evm-gateway cmd/main/main.go
_10
chmod a+x evm-gateway
_10
mv evm-gateway /usr/bin

Step 3 - Start Your Node

Operators will need to refer to the gateway configuration flags and make adjustments that align with the desired deployment topology.

EVM Coinbase address

If this is your first time setting up the gateway we need to ensure that an EVM COA or EOA address is available to configure the COINBASE. This account can be an account created using Metamask or other web3.js wallet, or otherwise can be the EVM address corresponding to the Flow Wallet COA account created above.

If you haven't already got an EVM address and you have the COA account created by Flow Wallet above then follow the steps below:

  • Click top left burger icon to show current profile
  • Click 'Enable the path to EVM on Flow' button
  • Your EVM account will now be available to use in the left nav account view
  • When you switch to that account you can obtain its EVM address

COA Address and Key

COA address and private key is configured for --coa-address & --coa-key configuration flags. If running multiple EVM Gateway hosts it is standard to share the same COA address and key across n hosts.

Run the gateway

Ensure that the following ENV variables have been set. Add/update as required if your configuration differs from those listed.


_12
# Set required environment variables
_12
export ACCESS_NODE_GRPC_HOST="access.mainnet.nodes.onflow.org:9000" # or access.devnet.nodes.onflow.org:9000 for testnet
_12
export FLOW_NETWORK_ID="flow-mainnet" # or flow-testnet
_12
export INIT_CADENCE_HEIGHT="85981135" # 211176670 for testnet
_12
export COINBASE="${EVM_ADDRESS_WITHOUT_0x}"
_12
export COA_ADDRESS="${CADENCE_ACCOUNT_ADDRESS_WITHOUT_0x}"
_12
export COA_KEY="${CADENCE_ACCOUNT_PRIVATE_KEY_WITHOUT_0x}"
_12
export GAS_PRICE="100" # operators can set this to 0 for zero cost transactions. The linked COA account will pay for transactions on users behalf
_12
_12
# $\{ACCESS_NODE_SPORK_HOSTS\} are comma separated
_12
# testnet: access-001.devnet51.nodes.onflow.org:9000
_12
# mainnet: access-001.mainnet25.nodes.onflow.org:9000

ACCESS_NODE_SPORK_HOSTS is used by the gateway to track state across Flow sporks. These are generally infrequent with only one planned spork per year. A canonical list of required hosts can be found in the EVM Gateway Makefile.

Create EVM Gateway service


_30
sudo tee <<EOF >/dev/null /etc/systemd/system/gateway.service
_30
[Unit]
_30
Description=Gateway daemon
_30
After=network-online.target
_30
_30
[Service]
_30
User=$USER
_30
ExecStart=/usr/bin/evm-gateway \
_30
--access-node-grpc-host=$ACCESS_NODE_GRPC_HOST \
_30
--access-node-spork-hosts=ACCESS_NODE_SPORK_HOSTS \
_30
--flow-network-id=$FLOW_NETWORK_ID \
_30
--init-cadence-height=$INIT_CADENCE_HEIGHT \
_30
--ws-enabled=true \
_30
--coinbase=$COINBASE \
_30
--coa-address=$COA_ADDRESS \
_30
--coa-key=$COA_KEY \
_30
--rate-limit=9999999 \
_30
--rpc-host=0.0.0.0 \
_30
--gas-price=$GAS_PRICE \
_30
--tx-state-validation=local-index
_30
Restart=always
_30
RestartSec=3
_30
LimitNOFILE=4096
_30
_30
[Install]
_30
WantedBy=multi-user.target
_30
EOF
_30
_30
cat /etc/systemd/system/gateway.service
_30
sudo systemctl enable gateway

Start all services


_10
sudo systemctl daemon-reload
_10
sudo systemctl restart access-node
_10
sudo systemctl restart gateway

Check logs


_10
# change log settings to persistent if not already
_10
sed -i 's/#Storage=auto/Storage=persistent/g' /etc/systemd/journald.conf
_10
sudo systemctl restart systemd-journald
_10
_10
journalctl -u gateway.service -f -n 100

Startup bootstrap indexing

Once your EVM Gateway is up and running you will see it indexing the Flow network which was configured. At the present time this is a lengthy process (possibly 1-3 days, depending on CPU core count) during which time the gateway will not respond to queries. Once the data is fully indexed the gateway can serve requests to clients.

To speed up gateway setup we recommend backing up the /${GATEWAY_HOME_DIR}/data directory to use when creating additional nodes using the same release version. We are currently working on an export/import feature that will enable gateway operators to store state snapshots to bootstrap newly created nodes without the delay.

note

If you are upgrading the gateway from pre-v1.0.0 release versions the indexed data directory will need to be reindexed from genesis. You will not be able to re-use the DB data dir from the previous versions.

Account and Key Management

EVM Gateway allows for Google and AWS Key Management Service (KMS) setup, which is the recommended way of setting up the gateway for live networks. We recommend creating multiple KMS keys for the same Flow account (ideally 10 or more), how many depends on the desired transaction throughput, since the keys are used in rotation when submitting the transactions. If too few keys are configured it may result in sequence number collisions if the same key is used concurrently by multiple EVM client requests.

KMS Configuration


_10
--coa-cloud-kms-project-id=your-project-kms-id \
_10
--coa-cloud-kms-location-id=global \
_10
--coa-cloud-kms-key-ring-id=your-project-kms-key-ring-id \
_10
--coa-cloud-kms-key=example-gcp-kms1@1,example-gcp-kms2@1 \

Monitoring and Metrics

The EVM Gateway reports Prometheus metrics which are a way to monitor the gateway's availability and progress. The database folder size may also need to be monitored to prevent disk full issues.

Metric labels


_12
evm_gateway_api_errors_total # Total count of API errors for period
_12
evm_gateway_api_request_duration_seconds_bucket # Histogram metric buckets for API request durations
_12
evm_gateway_api_request_duration_seconds_count # Histogram metric API request count for period
_12
evm_gateway_api_request_duration_seconds_sum # Histogram metric API request sum of values for period
_12
evm_gateway_api_server_panics_total # Total count of server panics for period
_12
evm_gateway_blocks_indexed_total # Total count of EVM blocks indexed
_12
evm_gateway_cadence_block_height # Cadence block height
_12
evm_gateway_evm_account_interactions_total # Count of unique accounts observed for period
_12
evm_gateway_evm_block_height # EVM block height
_12
evm_gateway_operator_balance # Gateway node COA operator account balance
_12
evm_gateway_trace_download_errors_total # Total count of trace download errors
_12
evm_gateway_txs_indexed_total # Total count of indexed transactions

Alerts are recommended to be configured on server panics, low operator balance, and disk usage metrics.

Metrics port


_10
--metrics-port 8080 \

Node Status

For basic node status or keepalive monitoring we recommend automated checks on the following monotonically increasing counter:


_10
curl -s -XPOST 'your-evm-gw-host:8545' --header 'Content-Type: application/json' --data-raw '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' | jq -r '.result' | xargs printf "%d\n"
_10
10020239

Troubleshooting

Join our Discord and use the #flow-evm channel to ask any questions you may have about EVM Gateway.

Database version inconsistency/corruption

If you see a similar message to this from an aborted startup the gateway database directory is not compatible with the schema versions of the runtime, or there may be corruption. In this instance we recommend


_10
Jan 16 17:00:57 nodename docker[6552]: {"level":"error","error":"failed to open db for dir: /flow-evm-gateway/db, with: pebble: manifest file \"MANIFEST-018340\" for DB \"/flow-evm-gateway/db\": comparer name from file \"leveldb.BytewiseComparator\" != comparer name from Options \"flow.MVCCComparer\"","time":"2025-01-16T17:00:57Z","message":"Gateway runtime error"}

State stream configuration

If you are running an Access Node on the same logical host as the EVM Gateway you may see ehe following log entries.


_10
failure in event subscription at height ${INIT-CADENCE-HEIGHT}, with: recoverable: disconnected: error receiving event: rpc error: code = Unimplemented desc = unknown service flow.executiondata.ExecutionDataAPI”


_10
component execution data indexer initialization failed: could not verify checkpoint file: could not find expected root hash e6d4f4c755666c21d7456441b4d33d3521e5e030b3eae391295577e9130fd715 in checkpoint file which contains: [e10d3c53608a1f195b7969fbc06763285281f64595be491630a1e1bdfbe69161]

To resolve this configure --state-stream-addr to use the same address/port combination which is set for Access Node --rpc-addr. This is required by the gateway to allow both the streaming and non-streaming APIs to query using the same connection.

Access Node not fully synced

The following log entry will occur when the EVM Gateway attempts to sync with the Access Node but it has not yet synced up to latest block


_10
failure in event subscription at height ${INIT-CADENCE-HEIGHT}, with: recoverable: disconnected: error receiving event: rpc error: code = FailedPrecondition desc = could not get start height: failed to get lowest indexed height: index not initialized

FAQs

TBD