guide
Run a Node on Linuxβ
Recommended Hardware Specificationsβ
Please refer to Hardware Requirements for Validator Node.
Node installationβ
Get Build and latest updateβ
sudo apt update && sudo apt upgrade -y && sudo apt install -y git binutils-dev libcurl4-openssl-dev zlib1g-dev libdw-dev libiberty-dev cmake gcc g++ python3 docker.io protobuf-compiler libssl-dev pkg-config clang llvm awscli tmux jq ccze rclone
Install Rustβ
For Rust, we use standard installation, just press "Enter" when asked for the setup.
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh && source $HOME/.cargo/env
Install NEAR CLI and NEAR-Validatorβ
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/near/near-cli-rs/releases/latest/download/near-cli-rs-installer.sh | sh &&
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/near-cli-rs/near-validator-cli-rs/releases/latest/download/near-validator-installer.sh | sh &&
source $HOME/.cargo/env
Clone Nearcore repoβ
First get latest version available:
Nearcore_Version=$(curl -s https://api.github.com/repos/near/nearcore/releases/latest | jq -r .tag_name)
Clone the nearcore repo, choose the latest stable branch for mainnet and build the nearcore from source:
cd ~ && git clone https://github.com/near/nearcore && cd nearcore/ && git checkout $Nearcore_Version
make release
echo 'export NEAR_ENV=mainnet' >> ~/.bashrc
source ~/.bashrc
During the building time, let's make a wallet.
We recommend to use a partner wallet like Meteor, MyNearWallet or SenderWallet.
Add at least 31 NEAR to this wallet:
- 30 NEAR will be used for wallet creation
- 1 NEAR will be used for transaction fees
β οΈ This 30 NEAR can't be recovered if you decide to stop your validator.
Wallet Authorizationβ
A full access key needs to be installed locally to be able to send transactions via NEAR-CLI.
near login
Note: This command launches a web browser allowing for the authorization of a full access key to be copied locally.
Copy the link in your browser.
Grant Access to Near CLI, fill your validator address and press Enter.
Choose "Store the access key in my keychain" from the CLI command.
If you get an error, you can retry near login
with "Store the access key in my legacy keychain (compatible with the old near CLI)".
Initialize & Start the Nodeβ
Time to think about your validator name.
Your validator node will finish with a poolv1.near
.
For example:
- If you want to have a validator pool named "panda", set
panda.poolv1.near
. - If you want to have a name "validator_near", your full pool name will be
validator_near.poolv1.near
.
Reminder:β
<pool_id>
β your pool name, for examplepanda
.<full_pool_id>
βxxx.poolv1.near
, wherexxx
is your pool_id likepanda.poolv1.near
.<accountId>
oraccountId
βxxx.near
, wherexxx
is your account name, for examplevalidator_near.near
.
# You can use any RPC provider for this command.
BOOT_NODES=$(curl -s -X POST https://rpc.mainnet.near.org -H "Content-Type: application/json" -d '{
"jsonrpc": "2.0",
"method": "network_info",
"params": [],
"id": "dontcare"
}' | jq -r '.result.active_peers as $list1 | .result.known_producers as $list2 |
$list1[] as $active_peer | $list2[] |
select(.peer_id == $active_peer.id) |
"\(.peer_id)@\($active_peer.addr)"' | paste -sd "," -)
cd ~/nearcore && target/release/neard init --chain-id="mainnet" --account-id=<full_pool_id> --download-genesis --download-config validator --boot-nodes $BOOT_NODES
Set your <full_pool_id>
, example: xxx.poolv1.near
, where xxx
is your pool_id.
validator_key.json
generated after the above command in ~/.near/
folder must be something like this:
The account_id
must match the staking pool contract ID, or you will not be able to sign/verify blocks.
Tips before launching the nodeβ
If you want to reduce the size used by the data folder, you can run this command:
This will reduce the number of epoch stores from 5 (default) to 3, without any issue for your node.
jq '.gc_num_epochs_to_keep = 3' ~/.near/config.json > ~/.near/config.json.tmp && mv ~/.near/config.json.tmp ~/.near/config.json
Network optimizationsβ
To optimize the network settings for better validator performance, execute the following commands:
MaxExpectedPathBDP=8388608 && \
sudo sysctl -w net.core.rmem_max=$MaxExpectedPathBDP && \
sudo sysctl -w net.core.wmem_max=$MaxExpectedPathBDP && \
sudo sysctl -w net.ipv4.tcp_rmem="4096 87380 $MaxExpectedPathBDP" && \
sudo sysctl -w net.ipv4.tcp_wmem="4096 16384 $MaxExpectedPathBDP" && \
sudo sysctl -w net.ipv4.tcp_slow_start_after_idle=0 && \
sudo bash -c "cat > /etc/sysctl.d/local.conf" <<EOL
# Network settings for better validator performance
net.core.rmem_max = $MaxExpectedPathBDP
net.core.wmem_max = $MaxExpectedPathBDP
net.ipv4.tcp_rmem = 4096 87380 $MaxExpectedPathBDP
net.ipv4.tcp_wmem = 4096 16384 $MaxExpectedPathBDP
net.ipv4.tcp_slow_start_after_idle = 0
EOL
sudo sysctl --system
Neard Serviceβ
Let's setup Systemd so the node will always run with the system
sudo bash -c 'cat > /etc/systemd/system/neard.service << EOF
[Unit]
Description=NEARd Daemon Service
[Service]
Type=simple
User=[USER] /!_ UPDATE HERE
WorkingDirectory=/root/.near
ExecStart=/root/nearcore/target/release/neard run
Restart=on-failure
RestartSec=30
KillSignal=SIGINT
TimeoutStopSec=45
KillMode=mixed
[Install]
WantedBy=multi-user.target
EOF
systemctl enable neard'
Syncing Dataβ
Syncing consists of two main steps:
Syncing headers β achieved in one of three ways:
- Epoch Sync: the recommended, decentralized approach. This solution results in the smallest database size, as the node will only contain compacted block headers.
- Using a snapshot: a centralized solution.
- Fallback: If neither option is used, the node defaults to Header Sync, which can be extremely slow.
Syncing blocks β involves downloading the blockchain state at the start of the latest epoch and then processing the remaining blocks to fully sync with the chain. State sync, the process of downloading the state, can be done in two ways:
- Decentralized state sync: the default method, which pulls data directly from peers.
- Centralized state sync: uses cloud-based storage as a fallback when configured in
config.json
.
Epoch Syncβ
Epoch Sync enables a node to sync from genesis without relying on snapshots.
Unlike Header Sync, it requires downloading only a small subset of past block headers rather than all of them.
To sync using Epoch Sync, update the config.json
file with the latest boot nodes list from the NEAR network and then start the neard
service, here is the command:
BOOT_NODES=$(curl -s -X POST https://rpc.mainnet.near.org -H "Content-Type: application/json" -d '{
"jsonrpc": "2.0",
"method": "network_info",
"params": [],
"id": "dontcare"
}' | jq -r '.result.active_peers as $list1 | .result.known_producers as $list2 |
$list1[] as $active_peer | $list2[] |
select(.peer_id == $active_peer.id) |
"\(.peer_id)@\($active_peer.addr)"' | paste -sd "," -)
jq --arg newBootNodes $BOOT_NODES '.network.boot_nodes = $newBootNodes' ~/.near/config.json > ~/.near/config.tmp && mv ~/.near/config.json ~/.near/config.json.backup && mv ~/.near/config.tmp ~/.near/config.json
after that, just restart the node (sudo systemctl restart neard).
Wait for approximately 3 hours and you are done, follow the next step to become an active validator!
Sync data with snapshotβ
To sync data fast, we can download the snapshot of recent NEAR epochs instead of waiting for node sync with other peers, this process will take a few hours, the expected data size will be around 580GB.
Run this to download snapshot and start the node (huge thanks FastNEAR for maintaining this):
curl --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/fastnear/static/refs/heads/main/down_rclone.sh | DATA_PATH=~/.near/data CHAIN_ID=mainnet RPC_TYPE=fast-rpc bash && sudo systemctl restart neard
The command will sync data and restart the neard!
If you need to make a change to service in the config.json file, the node also need to be reloaded:
sudo systemctl restart neard
Watch logs:
journalctl -n 100 -f -u neard | ccze -A
Check the running status of the validator node. If you see something like the image above, it means the node is fully synced, and you are ready to become an active validator!
State sync from external storageβ
To configure your node to sync from external storage, follow the link.
The new state sync bucket is fast-state-parts
and it is maintained by FastNEAR.
Becoming an active Validatorβ
In order to become a validator and enter the validator set to help secure the network and earn rewards, a minimum set of success criteria must be met:
- The node must be fully synced
- The validator_key.json must be in place
- The contract must be initialized with the public_key in validator_key.json
- The account_id must be set to the staking pool contract id
- There must be enough delegations to meet the minimum seat price. See the seat price here or just run this command
near-validator validators network-config mainnet next
- A proposal must be submitted by pinging the contract
- Once a proposal is accepted a validator must wait 2-3 epoch to enter the validator set
- Once in the validator set the validator must produce great than 90% of assigned blocks or your node will be kick out
Check the running status of the validator node. If "Validator" is showing up, your pool is selected in the current validators list.
Deploy your staking pool contractβ
NEAR uses a staking pool factory with a whitelisted staking contract to ensure delegatorsβ funds are safe. In order to run a validator on NEAR, a staking pool must be deployed to a NEAR account and integrated into a NEAR validator node. Delegators must use a UI or the command line to stake to the pool. A staking pool is a smart contract that is deployed to a NEAR account.
Note: STAKING POOL CONTRACT WON'T HAVE WRITE ACCESS TO ALL SUB ACCOUNTS FUNDS OR DATA, this also applies for any sub accounts on NEAR, that means your staking balance is SAFE!
Deploy a Staking Pool Contractβ
Calls the staking pool factory, creates a new staking pool with the specified name, and deploys it to the indicated accountId.
near contract call-function as-transaction poolv1.near create_staking_pool json-args '{"staking_pool_id": "<pool_id>", "owner_id": "<accountId>", "stake_public_key": "<public_key>", "reward_fee_fraction": {"numerator": 5, "denominator": 100}}' prepaid-gas '300.0 Tgas' attached-deposit '30 NEAR' sign-as <accountId> network-config mainnet sign-with-keychain
From the example above, you need to replace:
pool_id: Staking pool name example "panda"
owner_id: The NEAR account that will manage the staking pool. Usually your main NEAR account.
public_key: The public key in your validator_key.json file.
5: The fee the pool will charge (e.g. in this case 5 over 100 is 5% of fees), usually validators take 5% fee, if you set the fee so high, no one will stake to your node π
accountId: The NEAR account deploying the staking pool.
Be sure to have at least 30 NEAR available, it is the minimum required for storage.
Final command will look something like this:
near contract call-function as-transaction poolv1.near create_staking_pool json-args '{"staking_pool_id": "panda", "owner_id": "validator_near.near", "stake_public_key": "ed25519:xxx", "reward_fee_fraction": {"numerator": 5, "denominator": 100}}' prepaid-gas '300.0 Tgas' attached-deposit '30 NEAR' sign-as validator_near.near network-config mainnet sign-with-keychain
To change the pool parameters, such as changing the amount of commission charged to 1% in the example below, use this command:
near contract call-function as-transaction <full_pool_id> update_reward_fee_fraction json-args '{"reward_fee_fraction": {"numerator": 1, "denominator": 100}}' prepaid-gas '100.0 Tgas' attached-deposit '0 NEAR' sign-as <account_id> network-config mainnet sign-with-keychain
Note: full_pool_id: <pool_id>.poolv1.near
, itβs panda.poolv1.near
in this case.
If there is a "True" at the End. Your pool is created.
Congrats! You have now configure your Staking pool up and running ππππ
Manage your staking pool contractβ
Few useful commands you should know:
Retrieve the owner ID of the staking pool
near contract call-function as-read-only <full_pool_id> get_owner_id json-args {} network-config mainnet now
Issue this command to retrieve the public key the network has for your validator
near contract call-function as-read-only <full_pool_id> get_staking_key json-args {} network-config mainnet now
If the public key does not match you can update the staking key like this (replace the pubkey below with the key in your validator.json file)
near contract call-function as-transaction <full_pool_id> update_staking_key json-args '{"stake_public_key": "<public key>"}' prepaid-gas '100.0 Tgas' attached-deposit '0 NEAR' sign-as <accountId> network-config mainnet sign-with-keychain
Working with Staking Pools
NOTE: Your validator must be fully synced before issuing a proposal or depositing funds.
Proposals and Pingsβ
In order to get a validator seat you must first submit a proposal with an appropriate amount of stake. Proposals are sent for epoch +2. Meaning if you send a proposal now, if approved, you would get the seat in 3 epochs. You should submit a proposal every epoch to ensure your seat. To send a proposal we use the ping command. A proposal is also sent if a stake or unstake command is sent to the staking pool contract.
To note, a ping also updates the staking balances for your delegators. A ping should be issued each epoch to keep reported rewards current on the pool contract. You could set up a ping using a cron job with a ping script here.
Ping are done by Metapool too, you don't need anymore to use a script ping but you can. You need at least 1 ping to be visible for the first time.
Replace <full_pool_id>
and <account_id>
before execution:
mkdir -p /home/root/scripts /home/root/logs && sudo bash -c 'cat > /home/root/scripts/ping.sh << EOF
#!/bin/sh
# Ping call to renew Proposal added to crontab
export NEAR_ENV=mainnet
export LOGS=/home/root/logs
export POOLID=<full_pool_id>
export ACCOUNTID=<account_id>
echo "---" >> \$LOGS/near_ping.log
date >> \$LOGS/near_ping.log
near contract call-function as-transaction \$POOLID ping json-args '\''{"stake_public_key": "<public key>"}'\'' prepaid-gas '\''100.0 Tgas'\'' attached-deposit '\''0 NEAR'\'' sign-as \$ACCOUNTID network-config mainnet sign-with-keychain >> \$LOGS/near_ping.log
EOF
chmod +x /home/root/scripts/ping.sh && (crontab -l 2>/dev/null; echo "0 */8 * * * sh /home/root/scripts/ping.sh") | crontab -'
This will ping you node every 8h
List crontab to see it is running:
crontab -l
Review your logs
cat $HOME/logs/near_ping.log
Now you only need to have enough token staked to start earning Rewards.
How to have Logo, Description, Contact Details on Nearscope - Near Stakingβ
Adding pool information helps delegators and also helps with outreach for upgrades and other important announcements: Near Pool Details.
The available fields to add are: Fields Documentation.
The identifying information that validators need to provide includes:
- Name
- Description
- URL
- Telegram
Example Commandsβ
Change validator name and description:
Replace <full_pool_id>
with your pool address, e.g., panda.poolv1.near
.
Replace <accountId>
with your authenticated wallet address, e.g., validator_near.near
.
near contract call-function as-transaction pool-details.near update_field json-args '{"pool_id": "<full_pool_id>", "name": "name", "value": "PandaPool"}' prepaid-gas '100.0 Tgas' attached-deposit '0 NEAR' sign-as <accountId> network-config mainnet sign-with-keychain
near contract call-function as-transaction pool-details.near update_field json-args '{"pool_id": "<full_pool_id>", "name": "description", "value": "PandaPool Description"}' prepaid-gas '100.0 Tgas' attached-deposit '0 NEAR' sign-as <accountId> network-config mainnet sign-with-keychain
View your validator info from CLI:
near contract call-function as-read-only pool-details.near get_fields_by_pool json-args '{"pool_id":"<full_pool_id>"}' network-config mainnet now
View validator info on NearScope or NearBlocks: The info will appear as shown on NearScope.
How to Know When to Update Node Versionβ
You can get update notifications from:
- Discord: NEAR Protocol Discord
- Telegram: NEAR Validators Group
- Twitter (X): NEAR Chain Status (Only for Mainnet)
- Email Subscription: NEAR Update Notifications
How to Update Node Versionβ
When there is a new node version, you will receive a notification on the Telegram Validator group. Run the following command to update your node:
cd ~/nearcore && git fetch && export NEAR_RELEASE_VERSION=<node_version> && git checkout tags/$NEAR_RELEASE_VERSION && make release && sudo systemctl stop neard && sudo systemctl start neard
Replace <node_version>
with the correct NEAR core release version.
Update Priority Codes:
- CODERED<network_id> β where
<network_id>
is eitherMAINNET
orTESTNET
. This represents the most dire and urgent situation. Usually it means that the network has stalled or crashed and we need validators to take immediate actions to bring the network up. Alternatively it could mean that we discovered some highly critical security vulnerabilities and a patch is needed as soon as possible. If it is about mainnet, we expect that validators will react immediately to such alerts, ideally within 30 minutes. - CODEYELLOW<network_id> β where
<network_id>
is eitherMAINNET
orTESTNET
. This represents a less urgent announcement. Usually it means the release of a protocol change or a fix of a moderate security issue. In such cases, validators are not expected to take immediate actions but are still expected to react within days. - CODEGREEN<network_id> β where
<network_id>
is eitherMAINNET
orTESTNET
. This usually means some general announcement that is more informational or doesn't require actions within a short period of time. It could be an announcement of a release that improves performance or a fix some minor issues.
Monitor the Node Performanceβ
- Monitoring Tools:
- Telegram BOT Monitoring: Near Validator Watcher Bot
How to Withdraw Your Rewardsβ
Log in to your wallet you created few steps before, unstake (takes 3 epochs), and withdraw.
Useful Commandsβ
Get active epoch data (list of active validators, seat price, and performance):
near-validator validators network-config mainnet now
Next epoch validators list:
near-validator validators network-config mainnet next
View validator staked balance:
near-validator staking view-stake <full_pool_id> network-config mainnet now
Troubleshootingβ
No Peersβ
If you have no peers, run this script:
BOOT_NODES=$(curl -s -X POST https://rpc.mainnet.near.org -H "Content-Type: application/json" -d '{
"jsonrpc": "2.0",
"method": "network_info",
"params": [],
"id": "dontcare"
}' | jq -r '.result.active_peers as $list1 | .result.known_producers as $list2 |
$list1[] as $active_peer | $list2[] |
select(.peer_id == $active_peer.id) |
"\(.peer_id)@\($active_peer.addr)"' | paste -sd "," -)
jq --arg newBootNodes $BOOT_NODES '.network.boot_nodes = $newBootNodes' ~/.near/config.json > ~/.near/config.tmp && mv ~/.near/config.json ~/.near/config.json.backup && mv ~/.near/config.tmp ~/.near/config.json
Weird Error When Running a Commandβ
First, check that you are using the correct NEAR-CLI:
near --version
Expected Output: near-cli-rs 0.XX.X
If it returns X.X.XX
, the NEAR CLI JS version is overshadowing the Rust version. You can either:
- Use
npx near-cli-rs
instead ofnear
. - Uninstall
near-cli
with:npm remove near-cli
.
How to Get Metrics from My Nodeβ
Check metrics with:
curl -s http://localhost:3030/metrics
Content Type: application/json
Warning Messagesβ
Warning messages can be ignored unless they indicate critical issues.
Get Latest Config.jsonβ
Find the latest config.json
here:
https://s3-us-west-1.amazonaws.com/build.nearprotocol.com/nearcore-deploy/mainnet/validator/config.json
Always Kicked Issueβ
Ensure your config file has store.load_mem_tries_for_tracked_shards
set to true
.
Useful Linksβ
- NEAR Chain Status Twitter: @NEARChainStatus
- NEAR Staking: Near Staking Website
- NEARBlocks Node Explorer: NearBlocks
- NearScope: NearScope
Supportβ
- Telegram: NEAR Validators
- Discord: NEAR Protocol Discord