Simple way to achieve perfect productivity while avoiding double forging in Lisk DPoS, written in PHP
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.


Simple way to achieve perfect productivity while avoiding double forging in Lisk DPoS, written in PHP. It's designed with safe practices in mind. Script evaluate most stable and synced node from provided list and make sure only this one is forging. Additionally it will ensure terminating forging if script will be closed or terminal connection hang up. (Upon signals - SIGTERM,SIGHUP,SIGINT). It's also using secure forging with AES256-GCM introduced in Lisk 1.0.0.

It's compatible with Lisk 1.0.0 Core and up, if you are looking for previous versions please check legacy branch.


Designed for and tested on Ubuntu 16.04

git clone
cd Lisk-forging-failover


Configuration guide will be very detailed, if you understand exactly how to enable forging, skim it.


Script will install lisk-php in upper directory from Lisk-forging-failover.
From this directory navigate to lisk-php

cd ..
cd lisk-php
php lisk-cli.php help

More details in lisk-php repository.

Encrypt passphrase

We now need to encrypt passphrase in order to place AES256-GCM encrypted string in each lisk core node configuration file.
First parameter is your first delegate account passphrase, second is password or phrase used to decrypt passphrase upon request. Longer better.

php lisk-cli.php EncryptPassphrase "Passphrase" "password" OptionalNumberOfSaltIterations

Example with default salting iterations

php lisk-cli.php EncryptPassphrase "coyote cancel access fresh soccer club subject salad veteran sheriff laundry square" "VeryHardAndLongPassword128319239123"

Example with custom salting iterations, for more info see: this issue on lisk-php repository.

php lisk-cli.php EncryptPassphrase "coyote cancel access fresh soccer club subject salad veteran sheriff laundry square" "VeryHardAndLongPassword128319239123" 2500

It will return prepared json string


Configuring config.php

Now we need to configure servers which will be forging, navigate to Lisk-forging-failover and edit config.php first server in this config will always have forging priority and other servers can be considered as fallback. Please also change PublicKey and DecryptionPhrase.

$nodes = array('','');
$nodes = array_reverse($nodes);

return array(
	'nodes' => $nodes,
	'protocol' => 'https',
	'daemon_interval' => '5',
	'PublicKey' => "a570aa6d9bfe8aa2ada142053426d07e0e8da28a6d0cb3a1d856d7f17156ae0b",
	'DecryptionPhrase' => "VeryHardAndLongPassword128319239123",

Now let's configure Lisk Core nodes. Important sections of config.json are forging, ssl and api.

Configuring config.json in Lisk directory

Make sure to stop lisk

bash stop

Either make api public or better, whitelist ip of server running Lisk-forging-failover.

"api": {
        "enabled": true,
         "access": {
                    "public": true,
                    "whiteList": ["",""]

Forging section, paste json string into key secret between brackets []
Then replace ip with ip of server running Lisk-forging-failover.

"forging": {
             "force": false,
             "secret": [{"publicKey":"a570aa6d9bfe8aa2ada142053426d07e0e8da28a6d0cb3a1d856d7f17156ae0b","encryptedPassphrase":"iterations=1&salt=0d1574a91e45fde38967153052fdb748&cipherText=5bada3a9fefba2e8a067c1ef761622a15ca092f17fead0aa3b1fdffee59422ffbae120cfbe59693f82f6075e38123884b5c3fa959fd34a8d6306c5a67a4caf0a17094024349880ca8825ef048d3641ee5a7f85&iv=787c6e0d160d95b3867a79c1&tag=6f44977c659a00d2f3dad383167501ea&version=1"}
              "access": {
                    	"whiteList": ["",""]

ssl section, set enabled to true, change port to 4009 and make sure that paths in key and cert contain two dots "../ssl/"

   "ssl": {
           "enabled": true,
           "options": {
                       "port": 4009,
                       "address": "",
                       "key": "../ssl/lisk.key",
                       "cert": "../ssl/lisk.crt"

Generate certificate for ssl settings

Leave Lisk directory

cd ..
mkdir ssl
cd ssl
openssl req -x509 -nodes -days 9999 -newkey rsa:2048 -keyout lisk.key -out lisk.crt

Then start Lisk core and make sure it started correctly,

bash start && bash logs


Repeat Lisk core configuration procedure in as many nodes you need, but it's good to keep it around 3. There is not really a need for more than one master and 2 fallback servers.


Testing and starting script

cd Lisk-forging-failover
php forge.php

Essentially output should look similar to

[0] Forging failover script starts...
[1] Primary forging node:
[1] Forging Nodes count:3
[1] Forging not yet enabled!
[1] -> Height:24747 Consensus:0%
[1] -> Height:34144 Consensus:100%
[1] -> Height:34144 Consensus:0%
[1] Best Height id:1 with value:34144
[1] Best Consensus id:1 with value:100
[1] After evaluation best node to forging appears to be: with id:1
[1] Checking if node is forging already
[1] Forging disabled on this node, as precaution lets make sure all other nodes are not forging as well.
[1] -> IsForging: no
[1] -> IsForging: no
[1] -> IsForging: no
[1] Finally enabling forging on selected node.
[1] IsPredictedNodeForging: yes
[1] Took:2 sleep:3
Sleeping 0s [50/50(0.06s)] [###################################################] 100%

If IsPredictedNodeForging will stuck with no loop or there will be no height or consensus in log, it means Lisk config.json configuration is incorrect.

If everything works you can run script in background using screen

screen -dmS forge php forge.php

Listing all active screens

screen ls

Accessing screen session

screen -x forge

To leave active session, Ctrl-A-D to detach, Ctrl-D to terminate. This script can be added to crontab to ensure autostart.


To ensure forging safety, if you unintentionally close script or when ssh connection hangs up, script will automatically terminate forging on all nodes before exiting. However it's worth to clarify that ssh connection hang up, will only affect current task executed in current session, meaning php forge.php, but if you will run script in background using screen -dmS forge php forge.php connection hang up will not affect forging, script will continue executing in background.

Below example of Ctrl+C

[28] After evaluation best node to forging appears to be: with id:2
[28] Doing nothing, predicted node is the same as currently forging
[28] Took:0 sleep:5
Sleeping 3s [16/50(0.1s)] [#################                                  ] 32%^C
Caught SIGINT, terminating forging on all nodes and exiting this script...
[0] -> IsForging: no
[0] -> IsForging: no
[0] -> IsForging: yes
[0] Disable forging
[0] IsForging: no


If you find any issue or have any idea for improvement, feel free to either open issue or submit pull request. When script malfunction, double forge or act unexpectedly please attach logs from date of event and provide as much details as possible. Logs can be found in Lisk-forging-failover/logs