Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Ethereum Validation Clique PoA

maxrobot edited this page Feb 12, 2019 · 3 revisions

Clique

The Ion interoperability framework uses modular validation to allow interoperability with blockchains of any consensus protocol. This document describes the design and implemenntation of a validation contract for the Clique consensus mechanism.

A sequence diagram for the Clique Proof of Authority validation module is given below:

PlantUML Model

Clique Validation Contract

The latest contract can be found here.

Clique Specific Properties

The core functions and other properties are identical to those found in the generic validation module specifications - see here. However to support the functionality of the Clique block validation a number of changes are made to the implementation of the validation module.

Properties
m_validators

Array containing all active validators, which is referenced whenever a block is verified.

Functions

RegisterChain
Function: RegisterChain
Purpose: Registers a new chain to the Ion contract, creating a specific connection between the validation contract and Ion hub contract.
Arguments:
    * id (bytes32 Unique id of another chain to interoperate with )
    * validators (address[] Array containing the validators at the genesis block )
    * genesisHash (bytes32 Hash of the genesis block for the chain being registered with Ion )
SubmitBlock
Function: SubmitBlock
Purpose: Validates a submitted block, needs to recreate the signed hash using the submitted block then perform a verification of the signature used.
Arguments:
  * id (bytes32: the identification hash of the chain being interoperated with )
  * rlpBlockHeader (bytes: rlp encoded blockheader without validator signatures )
  * rlpSignerBlockHeader (bytes: rlp encoded signed block as defined by Clique, including the validator signature )

Unsigned blocks should be submitted RLP encoded in the following ordering:

{  
    header.ParentHash,
    header.UncleHash,
    header.Coinbase,
    header.Root,
    header.TxHash,
    header.ReceiptHash,
    header.Bloom,
    header.Difficulty,
    header.Number,
    header.GasLimit,
    header.GasUsed,
    header.Time,
    header.Extra[:len(header.Extra)-65],
    header.MixDigest,
    header.Nonce
}

In order to extract both the block hash and the hash that is signed by the PoA validators this RLP encoded signed block header must be submitted. Hashing this gives the blockhash:

{  
    header.ParentHash,
    header.UncleHash,
    header.Coinbase,
    header.Root,
    header.TxHash,
    header.ReceiptHash,
    header.Bloom,
    header.Difficulty,
    header.Number,
    header.GasLimit,
    header.GasUsed,
    header.Time,
    header.Extra,
    header.MixDigest,
    header.Nonce
}

Creating v, r, and s from the hash of the above block data a recovery against the hashed unsigned block can be performed. The public key recovered should exist within the list of validators. However for a given round the validator can only submit once.

Submitted blocks should be rejected if:

  • The signature recovered does not belong to a validator in the whitelist
  • The signatory has exceed their limit of blocks signed for a given round
  • ParentHash is not found in the BlockHeader mappings

If a block is successfully validated two things should happen:

  • Block is appended to the state history of the foreign chain
  • The vote for addition or removal of validators should be tallied

Therefore the list of validators for subsequent epochs will be known prior to the subsequent epochs beginning.

Votes for addition or removals are carried out using repurposed fields in the header. The address of the validator would be contained in the miner block and the indication whether they are to be added or removed indicated through setting the nonce field to 0 or 0xFFFF to add or remove respectively. This should be submitted to the countVotes() function.

Problems and Attacks

Listed are a number of issues when using clique.

Finality

Clique sacrifices consistency over availability. During any given round block sealers can propose a block in any given order it is possible that two separate proposers submit a block at the same time. This would create a small fork in the chain which should be solved using the GHOST protocol, however this would not prevent somebody from submitting an 'incorrect' block to the Ion contract.

PBFT/Istanbul should not suffer from this issue.

Validator Set Update

Clique allows additional validators to be added or removed from the validator set using a voting system. Validator sets are valid for a prescribed epoch, the start of an epoch does not require any knowledge of previous state. Validators active during the epoch are able to propose an addition or removal from the validator set, requiring floor((SIGNER_COUNT/2) + 1) of the set to agree.

Given N validators and M rounds, giving an epoch of length M*N blocks, validators can vote each time they propose a block. Changes to the set are conducted at the start of every new epoch.

However an edge case whereby removing a validator reduces the threshold which spurs a cascade of removals.

RLP Encoding in Solidity

To verify a block it is passed RLP encoded into solidity as a bytes. Given a standard clique block we can be assured it has the form [prefix, length, payload]. The payload is of the form:

Field Type Length Prefix Example
ParentHash String 32 bytes 0x80 + 0x20 = 0xa0 a0cc97e24be8f595ece94c345c88b178e395befbdf4590d861f85fad856630f5e9
UncleHash String 32 bytes 0x80 + 0x20 = 0xa0 a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347
Coinbase String 20 bytes 0x80 + 0x14 = 0x94 940000000000000000000000000000000000000000
Root String 32 bytes 0x80 + 0x20 = 0xa0 a0db37435caa1fca7e1aa5b4da1c69fdf1d127232519eb3b1b5069825e6c62f5dc
TxHash String 32 bytes 0x80 + 0x20 = 0xa0 a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421
ReceiptHash String 32 bytes 0x80 + 0x20 = 0xa0 a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421
LogsBloom String 256 bytes 0xb7 + 0x02 = 0xb9, 0x01\0x00 b90100000000000000000000000000...000000000000000000000000000000000
Difficulty Single Byte 1 byte 0x02 02
Number Single Byte 1 byte 0x0a 0a
GasLimit String 3 bytes 0x80 + 0x03 = 0x83 8347e7c4
GasUsed String 1 bytes 0x80 + 0x00 = 0x80 80
TimeStamp String 4 bytes 0x80 + 0x04 = 0x84 845b2228cb
ExtraData String 97 bytes 0xb7 + 0x01 = 0xb8, 0x67 b861d78301080a846765746887676f31...ebcaba778c634132e5771f19c1e7f00
MixHash String 32 bytes 0x80 + 0x20 = 0xa0 a00000000000000000000000000000000000000000000000000000000000000000
Nonce String 8 bytes 0x80 + 0x08 = 0x88 880000000000000000
Total N/A 15, 583 bytes [Prefixes, Payload] 0xf7 + 0x02 = 0xf9, 0x02\0x56 f90256[payload]

Hashing this gives the block hash, in order to verify the signed hash the signature(s) must be extracted from extraData field. Modifing the RLP encoded header however requires recalculating the overall RLP prefix and that of the extraData field.

Removing the

Field Type Length Prefix Example
ExtraData String 32 bytes 0xc0 + 0x20 = 0xe0 e0d78301080a846765746887676f312e392e33856c696e75780000000000000000
Total N/A 14, 518 bytes [Prefixes, Payload] 0xf7 + 0x02 = 0xf9, 0x02\0x14 f90214[payload]

Given any block header the RLP encoding is dependent upon the length of the arguments within each field. A number of fields are of a static length, meaning no matter what data is held it is encoded at the same length for each block. However there are five fields which cannot be expected to always have the same length in bytes:

  • Difficulty [PoW or PoS only]
  • Number
  • GasLimit
  • GasUsed
  • Timestamp
  • ExtraData [Istanbul Only]

Home Page

Ion

Design

Ethereum Integration

Ethereum

Implementations

Validation - Clique

Validation - IBFT Soma

Hyperledger Fabric

Hyperledger Fabric Integration

Ethereum

Implementations

Other

FAQ

Contributing

Clone this wiki locally