Enabling forging

1. Adding the delegate info to the config

This step only needs to be done when enabling forging on a node for a delegate the first time.

To enable your node to forge for a particular delegate, firstly it is required to insert some data into the config file under the forging.delegates array as described below:

  • address: The address of the delegate.

  • encryptedPassphrase: The symmetrically encrypted 12 word mnemonic passphrase of the delegate account.

  • hashOnion: The onion of hashes that is used by the delegate.

Generate the necessary config object conveniently with the Lisk Core CLI.

The following command will return a config object to the console. The object can be copy-pasted directly into the application configuration as shown below:

lisk-core forging:config --pretty

Add the JSON object to the config under forging.delegates as shown below:

/home/lisk/.lisk/lisk-core/config/testnet/config.json
{
  //...
  forging: {
    force: false,
    delegates: [ (1)
        {
            address: "86555265f0110b4ed5a8cb95dbc732e77732c474",
            encryptedPassphrase: "iterations=1&salt=476d4299531718af8c88156aab0bb7d6&cipherText=663dde611776d87029ec188dc616d96d813ecabcef62ed0ad05ffe30528f5462c8d499db943ba2ded55c3b7c506815d8db1c2d4c35121e1d27e740dc41f6c405ce8ab8e3120b23f546d8b35823a30639&iv=1a83940b72adc57ec060a648&tag=b5b1e6c6e225c428a4473735bc8f1fc9&version=1",
            hashOnion: {
                "count": 1000000,
                "distance": 1000,
                "hashes": [
                    "ff2156e33c4aefa4a5a790edbe329f4a",
                    "5f86db180d4e63be6412d42d444dfb49",
                    "10fc37bb42d7f77030138e45795fef65",
                    "f04a306a73c5d7d94cc4f262b4d5ebb4",
                    //[...]
                    "ca41d52225f4b76140fc7f277731d326",
                    "fde61109609b74ba16d5ebd72a8b446f",
                    "9752dc2228492466d7c2046354d5fdfd"
                ]
            }
        }
    ],
  },
  //...
}
1 The list of delegates who are allowed to forge on this node.

Restart the node to apply the changes in the config.

2. Forger_info data

The forger_info data contains the following three properties:

  • height: Last forged block height.

  • maxHeightPreviouslyForged: Delegates largest previously forged height.

  • maxHeightPrevoted: Delegates largest prevoted height for a block.

For each of these properties, the forger config contains the value used in the last block forged by the node.

The three variables are required for enabling forging for the corresponding delegate.

3. Checking the forging status

To check the forging status of a Lisk Core node, execute the following command:

lisk-core forging:status
Example output
[{"address":"89aa5fc8861d392f60662f76a379cc348fe97d28","forging":true,"height":670237,"maxHeightPrevoted":670159,"maxHeightPreviouslyForged":670187}]

The command returns a list of delegates, based on the list under forging.delegates in the Lisk Core config (based on the details added to the config in the previous step Adding the delegate info to the config). The following information is displayed for each delegate:

  • the hexadecimal representation of the delegate address

  • if the delegate has forging enabled or not.

  • the Forger_info data

4. Enable forging

  1. Ensure the node is fully synchronized with the network, before enabling forging on that node.

  2. If forging is enabled for a delegate for the first time, use 0 as value for HEIGHT, MAXHEIGHTPREVIOUSLYFORGED and MAXHEIGHTPREVOTED. Afterwards, it is always required to use the latest values of the forger_info info data.

  3. To avoid being punished by the network, ensure the following:

    1. Never use outdated Forger_info data.

    2. Never activate forging for the same delegate on two or more nodes at the same time (a.k.a double-forging).

Enable forging with the following command:

lisk-core forging:enable 9bd82e637d306533b1e1ad66e19ca0047faa1a6a --use-status-values (1)
1 Replace 9bd82e637d306533b1e1ad66e19ca0047faa1a6a with the hexadecimal representation of your delegate address, which was displayed while Checking the forging status.

This will automatically use the currently saved forger_info data to eenable forging on the node. Verify the correctness of the values height, maxHeightPrevoted and maxHeightPreviouslyForged by answering yes and use your password to decrypt the passphrasee for forging.

 Current forging status for delegate account 331e287263c8166febde9d77a5f333df75056c74 is:
{"height":14814092,"maxHeightPrevoted":14814017,"maxHeightPreviouslyForged":14814025}
? Do you want to use the above values to enable forging? yes
? Enter password to decrypt the encrypted passphrase:  **********
Updated forging status:
{"address":"331e287263c8166febde9d77a5f333df75056c74","forging":true}

Reference for the forging:enable command:

Enable forging for given delegate address.

USAGE
  $ lisk-core forging:enable ADDRESS [HEIGHT] [MAXHEIGHTPREVIOUSLYFORGED] [MAXHEIGHTPREVOTED]

ARGUMENTS
  ADDRESS                    Address of an account in hex format.
  HEIGHT                     Last forged block height.
  MAXHEIGHTPREVIOUSLYFORGED  Delegates largest previously forged height.
  MAXHEIGHTPREVOTED          Delegates largest prevoted height for a block.

OPTIONS
  -d, --data-path=data-path  Directory path to specify where node data is stored. Environment variable "LISK_DATA_PATH" can also be
                             used.

  -w, --password=password    Specifies a source for your secret password. Command will prompt you for input if this option is not
                             set.
                             	Examples:
                             	- --password=pass:password123 (should only be used where security is not important)

  -y, --yes                  Do you want to use these values to enable forging

  --overwrite                Overwrites the forger info

  --pretty                   Prints JSON in pretty format rather than condensed.

  --use-status-values        Use delegates forging status values

EXAMPLES
  forging:enable ab0041a7d3f7b2c290b5b834d46bdc7b7eb85815 --use-status-values
  forging:enable ab0041a7d3f7b2c290b5b834d46bdc7b7eb85815 --use-status-values --yes
  forging:enable ab0041a7d3f7b2c290b5b834d46bdc7b7eb85815 100 100 10
  forging:enable ab0041a7d3f7b2c290b5b834d46bdc7b7eb85815 100 100 10 --overwrite
  forging:enable ab0041a7d3f7b2c290b5b834d46bdc7b7eb85815 100 100 10 --data-path ./data
  forging:enable ab0041a7d3f7b2c290b5b834d46bdc7b7eb85815 100 100 10 --data-path ./data --password your_password

5. Disable forging

Disable forging for given delegate address.

USAGE
  $ lisk-core forging:disable ADDRESS

ARGUMENTS
  ADDRESS  Address of an account in a hexadecimal format.

OPTIONS
  -d, --data-path=data-path  Directory path to specify where node data is stored. Environment variable "LISK_DATA_PATH" can also be used.

  -w, --password=password    Specifies a source for your secret password. Command will prompt you for input if this option is not set.
                             	Examples:
                             	- --password=pass:password123 (should only be used where security is not important)

  --overwrite                Overwrites the forger info

  --pretty                   Prints JSON in pretty format rather than condensed.

EXAMPLES
  forging:disable ab0041a7d3f7b2c290b5b834d46bdc7b7eb85815
  forging:disable ab0041a7d3f7b2c290b5b834d46bdc7b7eb85815 --data-path ./data
  forging:disable ab0041a7d3f7b2c290b5b834d46bdc7b7eb85815 --data-path ./data --password your_password

6. Safely enabling forging on another node

To safely enable forging on another node, please ensure to follow the steps below:

  1. Setup a new node on another server.

  2. Start the node and let it synchronize with the network. If available, it is recommended to synchronize from snapshots to speed up the synchronization process.

  3. Login to the server with the old node.

  4. Disable forging on the old node.

  5. Stop the old node.

  6. Dump the data in the forger_info table of the db of your node.

    lisk-core forger-info:export
  7. Login to the server with the new node.

  8. Restore the forger_info table.

    lisk-core forger-info:import ./forger.db.tar.gz
  9. Adding the delegate info to the config.

  10. Ensure the node is fully synchronized with the network. The height of your node should be equal to the current network height.

    lisk-core node:info
  11. Fetch the forging data needed to enable forging by Checking the forging status.

  12. Enable forging.

7. Safely enabling forging without forger_info data

Configurable Constants
  • BLOCK_TIME = 10: The block time of the considered blockchain in seconds, i.e., 10 for Lisk Mainnet.

  • MAX_FORK_DEPTH = 8640: An upper bound on the largest chain of off-chain blocks for which the validator generated a block, i.e., for every block at height h generated by the validator, the parent block at height h - MAX_FORK_DEPTH must be contained in the canonical chain that is eventually finalized. It is recommended to use MAX_FORK_DEPTH = 8640 = 24*60 *6 (number of blocks generated in 24 h).

Required Delegate Input
  • lastHeightActive: Unix timestamp of the last height when the validator node could have been possibly active and forging (overestimate with a larger number when uncertain about the exact time).

Instructions
  1. Start a new node with forging deactivated and synchronize with the Lisk blockchain until there is a block finalizedBlock that is

    • finalized and

    • finalizedBlock.header.timestamp > lastHeightActive

  2. Obtain a block parentBlock which is a parent block of finalizedBlock at height finalizedBlock.header.height - MAX_FORK_DEPTH.

    parentBlock.header.height = finalizedBlock.header.height - MAX_FORK_DEPTH
  3. Compute the number of missed blocks in the current chain between the finalizedBlock and the parentBlock, i.e.,

    missedBlocks = ceil((finalizedBlock.header.timestamp - parentBlock.header.timestamp)/BLOCK_TIME) - (finalizedBlock.header.height - parentBlock.header.height)
  4. Use the following forging configuration and activate forging

    height = finalizedBlock.header.height
    maxHeightPreviouslyForged = finalizedBlock.header.height + missedBlocks
    heightPrevoted = finalizedBlock.header.height