IBFT 2.0

Pantheon implements the IBFT 2.0 Proof-of-Authority (PoA) consensus protocol. IBFT 2.0 can be used for private networks.

In IBFT 2.0 networks, transactions and blocks are validated by approved accounts, known as validators. Validators take turns to create the next block, and a super-majority (greater than 66%) of validators must sign the block before it can be inserted into the chain.

Existing validators propose and vote to add or remove validators. A majority vote (greater than 50%) is required to add or remove a validator.

Minimum Number of Validators

IBFT 2.0 requires 4 validators to be Byzantine fault tolerant.

Genesis File

To use IBFT 2.0 requires an IBFT 2.0 genesis file. The genesis file defines properties specific to IBFT 2.0:

Example IBFT 2.0 Genesis File

  {
    "config": {
      "chainId": 1981,
      "constantinoplefixblock": 0,
      "ibft2": {
        "blockperiodseconds": 2,
        "epochlength": 30000,
        "requesttimeoutseconds": 10
      }
    },
    "nonce": "0x0",
    "timestamp": "0x58ee40ba",
    "extraData": "0xf83ea00000000000000000000000000000000000000000000000000000000000000000d594c2ab482b506de561668e07f04547232a72897daf808400000000c0",
    "gasLimit": "0x47b760",
    "difficulty": "0x1",
    "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
    "coinbase": "0x0000000000000000000000000000000000000000",
    "alloc": {}
  }

Properties specific to IBFT 2.0 are:

  • blockperiodseconds - Minimum block time in seconds.
  • epochlength - Number of blocks after which to reset all votes.
  • requesttimeoutseconds - Timeout for each consensus round before a round change.
  • extraData - RLP([32 Bytes Vanity, List<Validators>, No Vote, Round=Int(0), 0 Seals])

Properties that have specific values in IBFT 2.0 genesis files are:

  • nonce - 0x0
  • difficulty - 0x1
  • mixHash - 0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365 for Istanbul block identification.

To start a node on an IBFT 2.0 private network, use the --genesis-file option to specify the custom genesis file.

Extra Data

The extraData property is RLP encoded. RLP encoding is a space efficient object serialization scheme used in Ethereum. Use the Pantheon subcommand rlp encode to generate the extraData RLP string to include in the genesis file.

Example

pantheon rlp encode --from=toEncode.json

Where the toEncode.json file contains a list of the initial validators in ascending order.

One Initial Validator

[
 "9811ebc35d7b06b3fa8dc5809a1f9c52751e1deb"
]

Copy the RLP encoded data to the extraData in the genesis file.

Block Time

When a new chain head is received, the block time (blockperiodseconds) and round timeout (requesttimeoutseconds) timers are started. When blockperiodseconds is reached, a new block is proposed.

If requesttimeoutseconds is reached before the proposed block is added, a round change occurs, and the block time and timeout timers are reset. The timeout period for the new round is two times requesttimeoutseconds. The timeout period continues to double each time a round fails to add a block.

Generally, the proposed block is added before reaching requesttimeoutseconds. A new round is then started, and the block time and round timeout timers are reset. When blockperiodseconds is reached, the next new block is proposed.

The time from proposing a block to the block being added is small (around 1s) even in networks with geographically dispersed validators. Setting blockperiodseconds to your desired block time and requesttimeoutseconds to two times blockperiodseconds generally results in blocks being added every blockperiodseconds.

Example

An internal PegaSys IBFT 2.0 testnet has 4 geographically dispersed validators in Sweden, Sydney, and North Virginia (2 validators). With a blockperiodsecondsof 5 and a requesttimeoutseconds of 10, the testnet consistently creates block with a 5 second blocktime.

Optional Configuration Options

Optional configuration options that can be specified in the genesis file are:

  • messageQueueLimit - Default is 1000. In very large networks with insufficient resources increasing the message queue limit may help to deal with message activity surges.

  • duplicateMesageLimit - Default is 100. If seeing messages being retransmitted by the same node, increasing the duplicate message limit may reduce the number of retransmissions. A value of 2 to 3 times the number of validators is generally sufficient.

  • futureMessagesLimit - Default is 1000. The future messages buffer holds IBFT 2.0 messages for a future chain height. For large networks, increasing the future messages limit may be useful.

  • futureMessagesMaxDistance - Default is 10. Specifies the maximum height from the current chain height for which messages are buffered in the future messages buffer.

Adding and Removing Validators

To propose adding or removing validators using the JSON-RPC methods, enable the HTTP interface using --rpc-http-enabled or WebSockets interface using --rpc-ws-enabled.

The IBFT API methods are not enabled by default. To enable, specify the --rpc-http-api or --rpc-ws-api option and include IBFT.

The JSON-RPC methods to add or remove validators are:

Important

A majority of existing validators must agree to add or remove a validator. That is, ibft_proposeValidatorVote must be executed on the majority (greater than 50%) of validators to take effect. For example, if you have 4 validators, the vote must be made on 3 validators.

Use ibft_getSignerMetrics to view validator metrics for a specified block range.

Adding a Validator

To propose adding a validator, call ibft_proposeValidatorVote specifying the address of the proposed validator and true. The call must be executed on the majority of the validators.

JSON-RPC ibft_proposeValidatorVote Request Example

curl -X POST --data '{"jsonrpc":"2.0","method":"ibft_proposeValidatorVote","params":["0xFE3B557E8Fb62b89F4916B721be55cEb828dBd73", true], "id":1}' <JSON-RPC-endpoint:port>

When the next block is proposed by the validator, one proposal received from ibft_proposeValidatorVote is inserted in the block.
If all proposals have been included in blocks, subsequent blocks proposed by the validator will not contain a vote.

When more than half of the existing validators have published a matching proposal, the proposed validator is added to the validator pool and can begin validating blocks.

Use ibft_getValidatorsByBlockNumber to return a list of the validators and confirm your proposed validator has been added.

JSON-RPC ibft_getValidatorsByBlockNumber Request Example

curl -X POST --data '{"jsonrpc":"2.0","method":"ibft_getValidatorsByBlockNumber","params":["latest"], "id":1}' <JSON-RPC-endpoint:port>

To discard your proposal after confirming the validator was added, call ibft_discardValidatorVote specifying the address of the proposed validator.

JSON-RPC ibft_discardValidatorVote Request Example

curl -X POST --data '{"jsonrpc":"2.0","method":"ibft_discardValidatorVote","params":["0xFE3B557E8Fb62b89F4916B721be55cEb828dBd73"], "id":1}' <JSON-RPC-endpoint:port>

Removing a Validator

The process for removing a validator is the same as adding a validator except you specify false as the second parameter of ibft_proposeValidatorVote.

Epoch Transition

At each epoch transition, all pending votes collected from received blocks are discarded. Existing proposals remain in effect and validators re-add their vote the next time they create a block.

An epoch transition occurs every epochLength blocks where epochlength is defined in the IBFT genesis file.