Standing up a HIVE Engine Witness Node

in LeoFinance2 years ago (edited)

Welcome! I recently set up a HIVE Engine Witness, the @blockgolem, and wanted to document the process I followed and provide some tips to those who might be interested in standing up their own node. Firstly, I'd like to thank @rishi556 for his guide, @forykw for pointing me to @primersion's snapshots, and primersion for hosting those. This guide does assume some previous sys-admin experience and general familiarity and comfort with the Linux command line.

logo-dark.png

Hardware and Environment

The official wiki suggests that a low end system is fine, I'd recommend a larger amount of RAM (or swap if that's not an option) - 16GB with a modern dual or quad core CPU as a minimum. Having tested both on a HDD and an NVMe SSD, I'd also recommend an SSD as a storage medium to help prevent bottlenecks. Network connectivity is also important as well, raw bandwidth is a nice to have, but also be mindful of stability, ping, and geo location - one of the goals of any blockchain is decentralization.

Ubuntu is recommended as the operating system of choice here, though other Linux distributions will likely work - you may have to change some commands around package installation though.

By running a witness node, you'll be exposing two ports to the world (5000 and 5001 by default, though these are configurable) as well as broadcasting a transaction with these ports and your witness's IP. To that end, ensuring you have a dedicated/static IP is likely the best route, else you'll need to have the witness broadcast the transaction re-registering itself when it changes. This is achievable a few ways, either through your ISP or by the use of a VPN service, or by hosting the witness on a cloud provider.

Installing the Dependencies

At a high level, we'll be installing Node and NPM to run the smart contract node software, MongoDB as a database to store the chain data, and a few other tools such as PM2 to help with the administration of the server.

# Use UTC time, needed for consistent contract behaviour
export TZ=UTC


# Ensure we have the latest package links
sudo apt-get update

# Install needed applications and dependencies 
sudo apt install -y curl git gnupg ufw npm

# Import the public key for MongoDB
wget -qO - https://www.mongodb.org/static/pgp/server-4.4.asc | sudo apt-key add -

# Create the list file for MongoDB
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/4.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.4.list

# Reload our package links
sudo apt-get update

# Install MongoDB
sudo apt-get install -y mongodb-org

At this point, MongoDB is installed, NPM is installed, UFW is installed, but nothing is configured.

Installing fail2ban is also recommended. The exact configuration needed will vary by environment, so that will not be covered here. There may be other firewall/networking configurations needed depending on the exact environment.

UFW Config

As mentioned earlier, two ports are required to be opened for the HIVE Engine witness - one for RPC calls, and one for P2P communications. By default, these are 5000 and 5001 respectively. Above, ufw was installed as a firewall, configuring that looks similar to the below:

# Allow SSH traffic, might not be needed, or could be restricted to a specific IP/CIDR range depending on your needs and environment
sudo ufw allow ssh

# Allow traffic on the RPC port
sudo ufw allow 5000

# Allow traffic on the P2P port
sudo ufw allow 5001

# Enable UFW
sudo ufw enable

Depending on where you're running the node, there may be different configurations needed that better fit your environment.

MongoDB Config

Starting with MongoDB, we'll want to enable replica sets and then enable the service to start at boot time. By default, the MongoDB configuration is located at /etc/mongod.conf. We'll be enabling the replication set option as part of a production ready deployment configuration. To do so, we'll need to find the line:

# replication

within the configuration file and replace it with the following two lines:

replication:
  replSetName: "rs0"

Effectively, this enables replication by uncommenting the replication section of the config and adding a name for the replication set, "rs0". To have Mongo use this changed config, the service will need to be restarted:

# Restart the mongod service
sudo systemctl restart mongod

# Enable the service to start at boot
sudo systemctl enable mongod

We'll need to initialize the replica set by opening a Mongo session via mongo and then executing rs.initiate() within the session. The prompt should change and include rs0: if done correctly. The Mongo session can be exited by passing the EOF signal (ctrl+D).

Now that there's a configured Mongo instance running, restoring a snapshot is a great way to fast track getting the node synced. Primersion hosts snapshots at the following link:
https://snap.primersion.com/

Once the archive is downloaded, it can be restored via:

mongorestore --gzip --archive=<ARCHIVE_FILE_NAME>

This will take a while to complete, but ultimately saves time compared to syncing from the chain directly.

Installing the Smart Contract Node

Now that we have a working and restored DB, we'll need to get the code responsible for running the node. The easiest way to do this is cloning the official repository:

git clone https://github.com/hive-engine/steemsmartcontracts.git  -b hive-engine

Not only does the above command clone the repository, it also checks out the hive-engine branch which (as of time of writing) is the officially supported branch. If this changes in the future, or you're trying a different branch, you would then need to checkout a different branch.

It's worth noting that I ran into divergence issues on this branch. There's an open PR from @eonwarped that helped resolve this issue. If you're seeing that you're stuck on a particular round or have divergence and this is not yet merged, it may be worth bringing this patch in on your node and re-restoring the snapshot.

NPM was installed in the dependencies step, we can use that to install n which is a Node Version Manager and pm2, a Process Manager:

# Install the packages
sudo npm i -g n pm2

# Use n to install and use the latest LTS version of node 
sudo n lts

Stepping into the directory, we can start to install the NPM dependencies:

cd steemsmartcontracts
npm i

Now we are ready for configuration! We can start with the config.json file:

{
    "chainId": "mainnet-hive",
    "rpcNodePort": 5000,
    "p2pPort": 5001,
    "databaseURL": "mongodb://localhost:27017",
    "databaseName": "hsc",
    "blocksLogFilePath": "./blocks.log",
    "javascriptVMTimeout": 10000,
    "streamNodes": [
        "https://api.deathwing.me",
        "https://rpc.ecency.com",
        "https://hived.emre.sh",
        "https://api.hive.blog",
        "https://api.openhive.network"
    ],
    "startHiveBlock": 0,
    "genesisHiveBlock": 41967000,
    "witnessEnabled": true
}

The contents should largely mirror the above, with the RPC and P2P ports aligning to those that were opened previously, startHiveBlock should be 0 to ensure that the snapshot that was restored is used and has a later block than this, and witnessEnabled should be true, as it is in the current default config in the repository. The stream nodes can be modified as works best for the witness you're configuring, though this will likely depend on the geographic location and network performance.

Once done, we can configure the environment variables. A sample file is provided in .env.example, copying that provides an excellent starting point:

cp .env.example .env
cat .env
ACTIVE_SIGNING_KEY=5K...
ACCOUNT=acc...
NODE_IP=...

All of the fields will need to be provided, with the active signing key and account aligning to the witness account and the node IP being the public facing IP where the witness will be reachable.

With the environment configured, it's time to run!

Running the Node

The node application can be started with the PM2 process manager to help monitor and manage it:

pm2 start app.js --no-treekill --kill-timeout 10000 --no-autorestart --name engwit

This will start the node software in the background with the reference name of engwit. The logs are viewable with PM2 via

pm2 logs engwit

The logs will resemble a constant stream of block and witness updates, and it's probable that the snapshot that was restored isn't entirely up to date with the chain. You'll be able to see how many blocks ahead the blockchain is, and the goal is to get it to 0:

0|engwit  | 2022-01-10 23:30:54 info: [Streamer] head_block_number 60818805 currentBlock 60818806 Hive blockchain is 0 blocks ahead

Once it is at 0 blocks ahead, and remains at 0 blocks ahead for at least some amount of time (10-15 minutes), it can be considered fully caught up and stable. Exiting out of the logs (ctrl+C), it's time to register the witness. At this point, a transaction with the ports and IP will be broadcast to the HIVE blockchain. This can be done via:

node witness_action.js register

If you wish to take your witness offline, it's also important to unregister it via:

node witness_action.js unregister

One minor hang up I ran into when trying to register was an error relating to the OpenSSL version (OSSL_EVP_UNSUPPORTED). This is likely due to using a newer Node version, and is solved by:

export NODE_OPTIONS=--openssl-legacy-provider

This forces the legacy OpenSSL algorithm provider and allows the register/unregister actions to be performed.

Once registered, you'll need WORKERBEE staked on accounts that are voting for your witness. Primersion has a nice UI for voting for witnesses available here.

Closing Thoughts

With being outside of the top 20 witnesses, I don't expect to participate in many rounds. So why do this then? This was largely an experiment and learning process on my end to dive a bit deeper into the HIVE blockchain. I'm a guy that learns best by doing, and it allows me to also practice documenting my findings/processes. Adding another node that's active an

While writing this up, I noticed I did receive the first reward from this (after running consistently for a few days):

Screen Shot 2022-01-10 at 7.09.10 PM.png

Much better than expected honestly, being at rank 32.

There was a lot of debugging on my end and poking around that I wouldn't have been exposed to otherwise which was a nice learning experience. The hardest part was knowing where to find things, like an updated snapshot, which I only found out by mentioning it and @forykw was nice enough to point me in the right direction. The official HIVE Engine Discord is also a good resource.

There might have been other small issues I ran into that I'm forgetting here, but feel free to reach out if you hit any snags. Thanks for reading, and if you think this was helpful, please consider voting for the @blockgolem HIVE Engine Witness! Cheers!

Posted Using LeoFinance Beta

Sort:  

Once the archive is downloaded, it can be restored via:
mongorestore --gzip --archive=<ARCHIVE_FILE_NAME>

Hello sir, I have error in this.
Please help.

Thanks

Do you have details of the error you're seeing?

Thanks for helping support the #Hive-Engine! We run witnesses under @thelogicaldude and @hivelist.witness

More nodes, more decentralization!

That's the goal! Not just more nodes, but more nodes running on different servers/hosts too.

Yeah I have a fairly small host that runs their own machines out of Germany at the moment. Good price but they have their issues, lol. At least they are not AWS, and I am not using Privex because allot of Hive nodes run on that. If I had the ability, I would have a machine running. But I live rhe nomad life so that’s not possible.

I've been looking for a guide for a while now and this is by far the best understandable guide I have found. I have set up a node once for another blockchain and on a first view it looks like it works nearly the same here. Thanks for this guide.
!PIZZA

Hope it helps! Feel free to post any questions/issues you run into and I'll help if I can/update the guide to cover those as well.

Congratulations @fwxiii! You have completed the following achievement on the Hive blockchain and have been rewarded with new badge(s):

You received more than 1500 upvotes.
Your next target is to reach 1750 upvotes.

You can view your badges on your board and compare yourself to others in the Ranking
If you no longer want to receive notifications, reply to this comment with the word STOP

Check out the last post from @hivebuzz:

Hive Power Up Month - Feedback from Day 7

I would like a more detailed tutorial on how to do this, I've been thinking about setting up a node in Hive for a while.

Are there any details in particular that'd be helpful which aren't covered in here?

PIZZA!

PIZZA Holders sent $PIZZA tips in this post's comments:
@chaosmagic23(4/10) tipped @fwxiii (x1)

Please vote for pizza.witness!