Hello, I'm Jeongseup from Cosmostation.
This document is for sharing some information to prepare hyperliquid network joining as one of validators like us.
As you know, there is an offical docs link: https://github.com/hyperliquid-dex/node , But I wanted to share some personal experiences and insights to newbies like us :)
Actually, I don't like to install and setup standard like installing binary in the $HOME location.
That's why I changed to $HOME/.local/bin (if you have more preper location, it's better to change by your proper)
You should know some points before starting the binary.
visor.jsonfile must be located with the hl-node, hl-visor binary.override_gossip_config.jsonfile could be located in the working directory.node_config.jsonfile could be located in the default node directory(~/hl/hyperliquid_data/node_config.json)
So, I will make a working directory and make a start.sh with service file in the ubuntu 24.04 LTS
# mkdir for binaries and default json file(`visor.json`)
mkdir -p ~/.local/bin
# make default json file if not existed got panic error.
cd ~/.local/bin && echo '{"chain": "Testnet"}' > ~/visor.json
# install hl-visor(~= cosmovisor), hl-node(cosmos node)
curl https://binaries.hyperliquid.xyz/Testnet/hl-visor > ~/.local/bin/hl-visor && chmod a+x ~/.local/bin/hl-visor
# automatically download hl-node also when running the hl-visor later
# skip..
# setup working directory (I named the workspace here)
git clone .. or mkdir -p ~/workspace
# setup hyperliquid.sh
# here is skipped. Check the next step
# make override_config.json, for adding peers or open p2p exchanging
# I used this config in the b-harverst repo(https://github.com/b-harvest/awesome-hyperliquid-validators)
echo '{ "root_node_ips": [{"Ip": "52.193.108.168"}, {"Ip": "109.123.231.191"}, {"Ip": "13.230.56.50"}, {"Ip": "13.230.8.235"}, {"Ip": "172.105.216.226"}, {"Ip": "172.111.146.215"}, {"Ip": "172.237.11.56"}, {"Ip": "189.1.164.19"}, {"Ip": "198.13.56.193"}, {"Ip": "198.13.56.227"}, {"Ip": "199.254.199.101"}, {"Ip": "199.254.199.190"}, {"Ip": "199.254.199.243"}, {"Ip": "199.254.199.6"}, {"Ip": "202.182.101.169"}, {"Ip": "23.106.227.201"}, {"Ip": "23.81.44.34"}, {"Ip": "23.81.44.98"}, {"Ip": "34.146.90.209"}, {"Ip": "34.85.11.190"}, {"Ip": "35.190.227.149"}, {"Ip": "35.213.85.108"}, {"Ip": "45.12.134.122"}, {"Ip": "45.250.255.137"}, {"Ip": "45.250.255.44"}, {"Ip": "45.32.50.65"}, {"Ip": "45.63.123.73"}, {"Ip": "46.250.251.251"}, {"Ip": "46.250.253.204"}, {"Ip": "46.250.254.53"}, {"Ip": "5.104.84.73"}, {"Ip": "5.104.86.171"}, {"Ip": "72.46.86.159"}, {"Ip": "72.46.86.237"}, {"Ip": "72.46.86.39"}, {"Ip": "72.46.86.9"}, {"Ip": "95.173.204.141"}], "try_new_peers": true, "chain": "Testnet" }' > ~/workspace/override_gossip_config.jsonAnd then making service and script for running hyperliquid node.
# create a script file
cd ~/workspace && echo '
#!/usr/bin/env bash
NOK=1
SNM=hyperliquid
CMD=$1
function help()
{
echo ".${SNM}.sh start / stop / restart / reload / status / log"
}
if [ ! $# -eq 1 ]; then
help
exit ${NOK}
fi
case ${CMD} in
"start"|"restart")
sudo systemctl ${CMD} ${SNM} && sudo journalctl -u ${SNM} -f
;;
"stop"|"reload"|"status"|"enable"|"disable")
sudo systemctl ${CMD} ${SNM}
;;
"log")
sudo journalctl -u ${SNM} -f
;;
*)
echo "not proper command : ${CMD}"
help
;;
esac
unset SNM
unset CMD' > hyperliquid.sh && chmod +x hyperliquid.sh
# create a service file
echo "
Description=Hyperliquid Service
After=NetworkManager.service
Wants=network-online.target
StartLimitIntervalSec=500
StartLimitBurst=5
[Service]
Type=simple
User=$USER
Group=$USER
# ref; https://github.com/hyperliquid-dex/node?tab=readme-ov-file#flags
WorkingDirectory=$HOME/workspace
ExecStart=$HOME/.local/bin/hl-visor run-non-validator \
--serve-eth-rpc \
--replica-cmds-style
ExecStop=/bin/kill -s INT ${MAINPID}
RestartSec=5s
Restart=always
# make sure log directory exists and owned by syslog
PermissionsStartOnly=true
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=hyperliquid
[Install]
WantedBy=multi-user.target" > /etc/systemd/system/hyperliquid.serviceFinally, just start the script in the working directory.
cd ~/workspace && ./hyperliquid.sh start
## get logs..
#Dec 26 09:35:27 ip-172-31-41-245 hyperliquid[547080]: @@ [context: Context { initial_height: 306477500, hardfork: Hardfork { version: 311, round: #Round(208674452) }, height: 307849000, tx_index: 2, round: Round(213751566), time: Time(Time(2024-12-26T09:35:24.376)), next_oid: 21474855775, #next_lid: 855, next_twap_id: 3426 }] @ [books_pre_hash_latency: Duration(0.033763)] @ [total_latency: Duration(1.773946)]
#Dec 26 09:36:53 ip-172-31-41-245 hyperliquid[547080]: 2024-12-26T09:36:53.306Z WARN >>> hl-node @@ applied block 307849100
#Dec 26 09:38:31 ip-172-31-41-245 hyperliquid[547080]: 2024-12-26T09:38:31.279Z WARN >>> hl-node @@ applied block 307849200
#Dec 26 09:39:59 ip-172-31-41-245 hyperliquid[547080]: 2024-12-26T09:39:59.830Z WARN >>> hl-node @@ applied block 307849300- 3001 : evm json-rpc
- 3999 : unknown
- 4000-4010 : will be used for p2p or something
tcp LISTEN 0 128 0.0.0.0:3001 0.0.0.0:* users:(("hl-node",pid=497345,fd=40))
tcp LISTEN 0 1024 0.0.0.0:3999 0.0.0.0:* users:(("hl-node",pid=497345,fd=35))
tcp LISTEN 0 1024 0.0.0.0:4002 0.0.0.0:* users:(("hl-node",pid=497345,fd=34))
tcp LISTEN 0 1024 0.0.0.0:4001 0.0.0.0:* users:(("hl-node",pid=497345,fd=33))
-
Adding a key via metamask: if you don't want to use openssl to create a new key, just create a new account in the metamask and export the private key to use
-
tl;dr about hotstuff for hyperliquid: to operate your validator stably, we should know and understand some pre-knowledge about the hyperliquid consensus algorithm(Hotstuff),
-
With Tendermint, Hyperliquid was limited to processing 20,000 orders per second—a respectable figure, but far below Binance’s capability of handling 1.4 million operations per second.
-
Written entirely in Rust, HyperBFT is capable of theoretically processing 2 million orders per second—a 100x improvement over Tendermint.
-
I recommend to read this article before operating validator nodes, article link: https://x.com/asxn_r/status/1853871055208640904
-
-
Old files pruning: data size is increasing about 30G on a day. we should prune the old files by pruner(in the offical docs)
- 1_check_block_height.sh
#!/usr/bin/env bash
# https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/evm
endpoint=http://localhost:3001/evm
height=$(curl -sSX POST --header 'Content-Type: application/json' --data '{"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["latest",false],"id":1}' $endpoint | jq .result.number | xargs printf "%d")
echo "our node evm block number: $height"
current_date=$(date +%Y%m%d)
echo "our node abci block number: "
tail -n 1 ~/hl/data/block_times/$current_date | jq .- 2_check_balances.sh
address=0x388Ff9fdB11A22aD78e9C5977CC4eD130cE5E88b
# check spot assets balance
curl -X POST --header "Content-Type: application/json" --data '{ "type": "spotClearinghouseState", "user": "$address"}' https://api.hyperliquid-testnet.xyz/info
# check perpetuals assets balance
curl -X POST --header "Content-Type: application/json" --data '{ "type": "clearinghouseState", "user": "$address"}' https://api.hyperliquid-testnet.xyz/info- 3_register_validator.sh
hl-node \
--chain Testnet \
--key <YOUR_KEY> \
send-signed-action '{"type": "CValidatorAction", "register": {"profile": {"node_ip": {"Ip": "<SERVER_IP>"}, "signer": "<SIGNER_ADDRESS>", "name": "<VALIDATOR_MONIKER>", "description": "<DESCRIPTION...>"}, "initial_wei": 1000000000000}}'
and then a check by this query
curl -sX POST --header "Content-Type: application/json" --data '{ "type": "validatorSummaries"}' https://api.hyperliquid-testnet.xyz/info | jq '.[] | select(.name == "Cosmostation")'