Enabling forging
How to enable forging on a node as a delegate. For more information about forging, please check the forging explanations on the DPoS module page.
1. Registering a delegate
Before it is possible to enable forging on a node, it is required to register as a delegate. This is achieved by choosing a unique delegate name, and posting a corresponding Register Delegate transaction to the network.
There are many possibilities to post the transaction, use the one you prefer: Lisk Desktop, Lisk Elements, or the Dashboard plugin. |
An option is to create the transaction object with the application CLI:
1.2. Create the Delegate Registration transaction
lisk-core transaction:create 5 0 1100000000 --asset='{"username":"myname"}'
? Please enter passphrase: [hidden]
? Please re-enter passphrase: [hidden]
{"transaction":"0805100018032080d6c28c042a20bad983c72bed43fd274f852658c298b74c71ab6fc50508879fef309e3836384b32080a066d796e616d653a4045afdd04d0c0bc6e548c0915d5fabef1311b1b75b1eb919a43b88dab539e7b6a99b9075f5d6382ec3bbebfca3301651a15d8af3f999d5b6fa7873b3969cd3d0c"}
./bin/run transaction:create 5 0 1100000000 --asset='{"username":"myname"}'
? Please enter passphrase: [hidden]
? Please re-enter passphrase: [hidden]
{"transaction":"0805100018032080d6c28c042a20bad983c72bed43fd274f852658c298b74c71ab6fc50508879fef309e3836384b32080a066d796e616d653a4045afdd04d0c0bc6e548c0915d5fabef1311b1b75b1eb919a43b88dab539e7b6a99b9075f5d6382ec3bbebfca3301651a15d8af3f999d5b6fa7873b3969cd3d0c"}
1.3. Send the transaction
lisk-core transaction:send 0805100018032080d6c28c042a20bad983c72bed43fd274f852658c298b74c71ab6fc50508879fef309e3836384b32080a066d796e616d653a4045afdd04d0c0bc6e548c0915d5fabef1311b1b75b1eb919a43b88dab539e7b6a99b9075f5d6382ec3bbebfca3301651a15d8af3f999d5b6fa7873b3969cd3d0c
Transaction with id: '1809da284fe26dba90d34dc3aab837a32d3c291a4ca78a9bfa263f927c69598a' received by node.
./bin/run transaction:send 0805100018032080d6c28c042a20bad983c72bed43fd274f852658c298b74c71ab6fc50508879fef309e3836384b32080a066d796e616d653a4045afdd04d0c0bc6e548c0915d5fabef1311b1b75b1eb919a43b88dab539e7b6a99b9075f5d6382ec3bbebfca3301651a15d8af3f999d5b6fa7873b3969cd3d0c
Transaction with id: '1809da284fe26dba90d34dc3aab837a32d3c291a4ca78a9bfa263f927c69598a' received by node.
1.4. Check account details
Use the account:get
command to verify the account has now registered a delegate name:
lisk-core account:get ed86183c22f8399f7aa28f7d2c2f1680224f7281 --pretty
./bin/run account:get ed86183c22f8399f7aa28f7d2c2f1680224f7281 --pretty
The new delegate name should be displayed under dpos.delegate.username
:
{
"address": "ed86183c22f8399f7aa28f7d2c2f1680224f7281",
"token": {
"balance": "8888869000"
},
"sequence": {
"nonce": "4"
},
"keys": {
"numberOfSignatures": 0,
"mandatoryKeys": [],
"optionalKeys": []
},
"dpos": {
"delegate": {
"username": "myname",
"pomHeights": [],
"consecutiveMissedBlocks": 0,
"lastForgedHeight": 2467,
"isBanned": false,
"totalVotesReceived": "0"
},
"sentVotes": [],
"unlocking": []
},
"hello": {
"helloMessage": "Greetings World!"
}
}
2. Add delegate data to config
This step only needs to be performed when a delegate is enabling forging on a node for 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 as a hex string. -
encryptedPassphrase
: The symmetrically encrypted 12 word mnemonic passphrase of the delegate account. -
hashOnion
: The hash onion stores the random seeds of the delegate for each forging round.
To create the delegate configuration data,
-
First create a custom config file
-
Then use one of the following alternatives to generate the delegate config data:
-
Lastly, add the delegate config data to the custom config file.
2.2. Option 1: via application CLI
If the blockchain application was bootstrapped with Lisk Commander, it is possible to conveniently generate the relevant forging data using the command forging:config.
$ lisk-core forging:config --output ./delegate_config.json
? Please enter passphrase: [hidden] (1)
? Please re-enter passphrase: [hidden]
? Please enter password: [hidden] (2)
? Please re-enter password: [hidden]
$ ./bin/run forging:config --output ./delegate_config.json
? Please enter passphrase: [hidden] (1)
? Please re-enter passphrase: [hidden]
? Please enter password: [hidden] (2)
? Please re-enter password: [hidden]
1 | Passphrase of the delegate account. |
2 | Password to encrypt the passphrase of the delegate account. |
The command will ask for the delegate passphrase, and in order to symmetrically encrypt the passphrase for the config, it will also ask for a password.
Store the password you used for the encryption somewhere safe. It will be required everytime you wish to enable forging, in order to decrypt the delegates' passphrase in the config. |
After providing the required inputs, the delegate configuration data will be saved in the file delegate_config.json
.
Example of delegate_config.json
{
forging: {
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. |
2.3. Option 2: with Lisk Commander
Please ensure that the Lisk Commander is installed in a secure environment. Upon completion, please follow these commands to generate the encrypted passphrase:
$ lisk
lisk passphrase:encrypt --json
Please enter your secret passphrase: ***** (1)
Please re-enter your secret passphrase: *****
Please enter your password: *** (2)
Please re-enter your password: ***
{
"encryptedPassphrase": "iterations=1000000&cipherText=30a3c8&iv=b0d7322bf24e0dfe08462f4f&salt=aa7e26c9f4317b61b4f45b5c6909f941&tag=a2e0eadaf1f11a10b342965bc3bafc68&version=1",
}
1 | Enter the secret passphrase here that needs to be encrypted. |
2 | Enter the password here that will be required to decrypt the passphrase again. |
Ensure a strong password is used. See the Guidelines for password strength at Wikipedia for reference. |
The hash onion can be generated with Lisk Commander in the following manner:
lisk hash-onion --json
-
Add the hash onion and the delegate address in hexadecimal representation to the object with the
encryptedPassphrase
. -
Add the JSON object to the config under
forging.delegates
as shown below:
{
"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":[
"a623885d5422ce0f2aad3ee128e447ce",
"91e7ecad63bafdf36a5b02556ea77fe7",
"4a66b400290185cba622f8c9f5d37181",
//[...]
"fb8eee95e630e812cdf90d054acc903a"
]
}
}
]
}
}
1 | The list of delegates who are allowed to forge on this node. |
Restart the node to apply the changes in the config. |
For more information about the configuration of the Lisk SDK check out the configuration guide.
2.4. Updating the custom configuration
Add the JSON object to the config file of the application.
forging.delegates
stores the list of delegates who are allowed to forge on this node:
Merge the delegate config with the custom config which was created in step 2.1 above, to add the delegate information to the application configuration:
TEMP_FILE=$( mktemp )
jq --slurp '.[0] * .[1]' custom-config.json delegate_config.json > $TEMP_FILE
mv $TEMP_FILE custom-config.json
Open custom-config.json
to verify it was updated correctly.
Besides adding the delegate config data, the other options in the config can be adjusted as desired. Examples of config options that might be interesting to update can be found below.
Example: custom-config.json
file
{
//...
"logger": {
"fileLogLevel": "error",
"consoleLogLevel": "info" (1)
},
"rpc": {
"enable": true, (2)
"mode": "ipc"
},
"forging": {
"delegates": [ (3)
{
"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 | Set the console log level to info to view all relevant logs on the console. |
2 | Enable IPC to be able to use all commands of the Lisk Core CLI (see Command line interface) |
3 | Add the delegate config info here, under forging.delegates of the node configuration. |
3. 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.
These three variables are required for enabling forging for the corresponding delegate.
4. Checking the forging status
To check the forging status of a Lisk Core node, execute the following command:
[{"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 application config, (based on the details added to the config in the previous step, Add delegate data to 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.
5. Enable forging
|
5.1. via application CLI
If the blockchain application was bootstrapped with Lisk Commander, it is possible to conveniently generate the relevant forging data using the command forging:enable.
The blockchain application needs to be running to successfully enable forging on the node. |
lisk-core forging:enable 9bd82e637d306533b1e1ad66e19ca0047faa1a6a --use-status-values (1)
./bin/run forging:enable 9bd82e637d306533b1e1ad66e19ca0047faa1a6a --use-status-values (1)
1 | Replace 9bd82e637d306533b1e1ad66e19ca0047faa1a6a with the hex string representation of your delegate address, which was displayed while Checking the forging status. |
This will automatically use the currently saved forger_info
data to enable forging on the node.
Verify the correctness of the values height
, maxHeightPrevoted
, and maxHeightPreviouslyForged
by answering yes
, and use your password to decrypt the passphrase for forging.
Don’t trust Forger_info data from public APIs or explorers, make sure to always use your local data!
You can use your data automatically by setting the flag --use-status-values .
|
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 the 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.2. via the updateForgingStatus
action
Invoke the following action to enable the forging for a delegate:
const { createWSClient } = require('@liskhq/lisk-api-client');
export const enableForging = async () => {
let apiClient = await createWSClient('ws://localhost:8080/ws');
let response;
const { data } = await apiClient.invoke('app:updateForgingStatus', {
address: string, (1)
password: string, (2)
forging: true, (3)
height?: number, (4)
maxHeightPrevoted?: number, (5)
maxHeightPreviouslyForged?: number, (6)
override?: boolean (7)
});
try {
response = await apiClient.transaction.send(tx);
} catch (error) {
response = error;
}
};
1 | Address as hex string. |
2 | Password that was used above to encrypt the passphrase in the configuration. |
3 | When enabling forging, the value should be true . |
4 | Not required, when enabling forging for a delegate for the first time. Height of the last forged block by the delegate. |
5 | Not required, when enabling forging for a delegate for the first time.
Height of the previously prevoted block by any delegate.
Must match the value in the forger_info data. |
6 | Not required, when enabling forging for a delegate for the first time.
Height of the previously last forged block.
Must match the value in the forger_info data. |
7 | Optional: If true, overrides maxHeightPreviouslyForged and maxHeightPrevoted values in the forger_info data. |
6. Disable forging
Sometimes it is necessary to disable forging, for example to update to the latest Lisk Core version, or if you are moving your node to a different server.
If you would like to completely stop forging without being punished by the network, make sure to unvote yourself, see:
|
6.1. with the application CLI
lisk-core forging:disable 9bd82e637d306533b1e1ad66e19ca0047faa1a6a (1)
./bin/run forging:disable 9bd82e637d306533b1e1ad66e19ca0047faa1a6a (1)
1 | Replace 9bd82e637d306533b1e1ad66e19ca0047faa1a6a with the hexadecimal representation of your delegate address, which was displayed while Checking the forging status. |
Reference for the forging:disable
command
Disable forging for the 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.2. via the updateForgingStatus
action
Invoke the following action to disable the forging for a delegate:
const { createWSClient } = require('@liskhq/lisk-api-client');
export const disableForging = async () => {
let apiClient = await createWSClient('ws://localhost:8080/ws');
const { data } = await apiClient.invoke('app:updateForgingStatus', {
address: string,
password: string,
forging: false (1)
});
};
1 | Change forging to false to disable forging for a delegate on the node. |
7. Safely enabling forging on another node
To safely enable forging on another node, please ensure to follow the steps below:
-
Setup a new node on another server.
-
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.
-
Login to the server with the old node.
-
Disable forging on the old node.
-
Stop the old node.
-
Dump the data in the
forger_info
table of the db of your node.lisk-core forger-info:export
-
Login to the server with the new node.
-
Restore the
forger_info
table.lisk-core forger-info:import ./forger.db.tar.gz
-
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
-
Fetch the forging data needed to enable forging by Checking the forging status.
8. 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 boundary on the largest chain of off-chain blocks for which the validator generated a block, i.e., for every block at heighth
generated by the validator, the parent block at heighth - MAX_FORK_DEPTH
must be contained in the canonical chain that is eventually finalized. It is recommended to useMAX_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 possibly been active and forging, (over estimate with a larger number when uncertain about the exact time).
-
- Instructions
-
-
Start a new node with forging deactivated and synchronize with the Lisk blockchain until there is a block
finalizedBlock
that is finalized, and that the finalized block header timestamp is greater than the last active height:finalizedBlock.header.timestamp > lastHeightActive
-
Obtain a block
parentBlock
which is a parent block offinalizedBlock
at heightfinalizedBlock.header.height - MAX_FORK_DEPTH
.parentBlock.header.height = finalizedBlock.header.height - MAX_FORK_DEPTH
-
Compute the number of missed blocks in the current chain between the
finalizedBlock
and theparentBlock
, i.e., as shown below:missedBlocks = ceil((finalizedBlock.header.timestamp - parentBlock.header.timestamp)/BLOCK_TIME) - (finalizedBlock.header.height - parentBlock.header.height)
-
Use the following forging configuration and activate forging:
height = finalizedBlock.header.height maxHeightPreviouslyForged = finalizedBlock.header.height + missedBlocks heightPrevoted = finalizedBlock.header.height
-