# Privex dual RPC setup (full node + separated account history) (C) 2020 Privex Inc. - https://www.privex.io/ If this guide helped you, vote for @someguy123 on Hive / Steem, and maybe buy a server from https://www.privex.io/ ### specs - min 1 TB (2-3 TB recommended) of high speed storage (NVMe preferred!) - this guide uses LVM for flexible raid0 (we've found it's faster than mdadm) - more NVMe's = faster, we recommend 3 to 8 NVMe's rather than a 1 or 2 big NVMe's - 64GB RAM (128GB recommended) - a CPU with good single threaded performance - Ubuntu 18.04 Bionic ### Partition disks ```sh # !!! WARNING: Will delete any existing partitions! # Create a Linux partition filling the disk for each drive echo ",,L" | sfdisk -X gpt /dev/nvme0n1 echo ",,L" | sfdisk -X gpt /dev/nvme1n1 echo ",,L" | sfdisk -X gpt /dev/nvme2n1 ``` ### install thin provision tools ```sh apt install thin-provisioning-tools ``` ### setup lvm ```sh # Setup LVM on NVMe's 0, 1 and 2 pvcreate /dev/nvme{0..2}n1p1 vgcreate nvraid /dev/nvme0n1p3 /dev/nvme1n1p1 /dev/nvme2n1p1 # Change the '3' in -i3 to however many disks/partitions you're RAID0'ing lvcreate --type raid0 -i3 -I64 -L 1500G -n thin64 nvraid lvconvert --thinpool nvraid/thin64 lvextend --poolmetadatasize +1G nvraid/thin64 # Create volume for storing the block_log # We'll download the block_log onto it, then snapshot it into hive1 + hive2 # This means both RPCs will only consume as much space as ONE block_log lvcreate -V 500G --thinpool nvraid/thin64 -n blockshive # Create two volumes for shared_memory/rocksdb lvcreate -V 200G --thinpool nvraid/thin64 -n hiveshm1 lvcreate -V 100G --thinpool nvraid/thin64 -n hiveshm2 ``` ### format shm vols + blockshive and mount blockshive ```sh # Format the two volumes with XFS. Change the '3' in sw=3 to amount of drives raid'ed mkfs.xfs -f -s size=4096 -b size=4096 -d su=65536,sw=3 -i maxpct=3 /dev/nvraid/hiveshm1 mkfs.xfs -f -s size=4096 -b size=4096 -d su=65536,sw=3 -i maxpct=3 /dev/nvraid/hiveshm2 # Format blockshive with XFS. Change the '3' in sw=3 to amount of drives raid'ed mkfs.xfs -f -s size=4096 -b size=4096 -d su=65536,sw=3 -i maxpct=3 /dev/nvraid/blockshive mkdir /mnt/blockshive mount /dev/nvraid/blockshive /mnt/blockshive ``` ### create blockchain folder + download block log ```sh cd /mnt/blockshive mkdir -p witness_node_data_dir/blockchain rsync -avh --progress --append rsync://files.privex.io/hive/block_log witness_node_data_dir/blockchain/block_log ``` ### snapshot blockshive + clone into hive1 + hive2 data vols ```sh # once downloaded, snapshot blockshive with a timestamp umount /mnt/blockshive lvcreate -s -n blockshive_28mar2020 nvraid/blockshive # remove original blockshive (won't hurt the snapshot) lvremove nvraid/blockshive # clone blockshive snapshot into hive1 and hive2 lvcreate -s -n hive1 nvraid/blockshive_28mar2020 lvcreate -s -n hive2 nvraid/blockshive_28mar2020 # Activate the snapshots so we can mount them lvchange -v -K -a y nvraid/blockshive_28mar2020 lvchange -v -K -a y nvraid/hive1 lvchange -v -K -a y nvraid/hive2 # Clear XFS journal + regenerate UUID, otherwise Linux thinks they're all the same volume xfs_repair -L /dev/mapper/nvraid-blockshive_28mar2020 xfs_repair -L /dev/mapper/nvraid-hive1 xfs_repair -L /dev/mapper/nvraid-hive2 xfs_admin -U $(uuidgen) /dev/mapper/nvraid-blockshive_28mar2020 xfs_admin -U $(uuidgen) /dev/mapper/nvraid-hive1 xfs_admin -U $(uuidgen) /dev/mapper/nvraid-hive2 ``` ### create mountpoints and setup fstab ```sh # Create mountpoints for hive data + hive shm mkdir -p /hive/rpc{1..2} mkdir -p /shmhive/rpc{1..2} # Open up fstab and add the following entries nano /etc/fstab ``` ``` ### BEGIN /etc/fstab entries /dev/mapper/nvraid-hiveshm1 /shmhive/rpc1 xfs defaults 0 0 /dev/mapper/nvraid-hiveshm2 /shmhive/rpc2 xfs defaults 0 0 /dev/mapper/nvraid-hive1 /hive/rpc1 xfs defaults 0 0 /dev/mapper/nvraid-hive2 /hive/rpc2 xfs defaults 0 0 ### END /etc/fstab entries ``` ### mount volumes, clone hive-rpcs-docker, and copy configs ```sh # now mount all of them mount -av cd ~ git clone https://github.com/Privex/hive-rpcs-docker.git rpc cd rpc git clone https://github.com/Someguy123/steem-docker.git acchist git clone https://github.com/Someguy123/steem-docker.git core cp core.env core/.env cp acchist.env acchist/.env cp rpc1_config.ini /hive/rpc1/witness_node_data_dir/config.ini cp rpc2_config.ini /hive/rpc2/witness_node_data_dir/config.ini ``` ### install docker if needed, then build images + replay ```sh cd acchist/ ./run.sh install_docker STEEM_SOURCE="https://github.com/openhive-network/hive.git" ./run.sh build 0.23.0 tag hive-lowmem-nomira 'ENABLE_MIRA=OFF' ./run.sh replay cd ../core STEEM_SOURCE="https://github.com/openhive-network/hive.git" ./run.sh build_full 0.23.0 tag hive-fullmem-mira 'ENABLE_MIRA=ON' ./run.sh replay ``` ### once acchist is replayed: ```sh cd ~/rpc/acchist ./run.sh stop cd ~/rpc docker-compose up -d rpc-acchist nginx-acchist jussi redis1 redis2 ``` ### once core is replayed: ```sh cd ~/rpc/core ./run.sh stop cd ~/rpc docker-compose up -d rpc-core nginx-core ``` ### install nginx on host + create nginx config to point to jussi ```sh apt install -y nginx nano /etc/nginx/snippets/rpc.conf nano /etc/nginx/sites-enabled/hived ``` rpc.conf snippet: ```nginx access_log off; proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504; proxy_connect_timeout 10; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; keepalive_timeout 65; keepalive_requests 100000; sendfile on; tcp_nopush on; tcp_nodelay on; proxy_ssl_verify off; ``` nginx config: ```nginx upstream hivesrvs { # Dirty Hack. Causes nginx to retry jussi server 127.0.0.1:8080; server 127.0.0.1:8080; server 127.0.0.1:8080; server 127.0.0.1:8080; keepalive 10; } server { server_name direct.hived.privex.io hived.privex.io; root /var/www/html/; location ~ ^(/|/ws) { proxy_pass http://hivesrvs; proxy_set_header Connection ""; include snippets/rpc.conf; } listen 80; listen [::]:80; # listen 443 http2 ssl; # listen [::]:443 http2 ssl; } ```