ethereum / aleth

Aleth – Ethereum C++ client, tools and libraries
GNU General Public License v3.0
3.97k stars 2.17k forks source link

Clique PoA implementation plan #5522

Open gumb0 opened 5 years ago

gumb0 commented 5 years ago

https://eips.ethereum.org/EIPS/eip-225

Keeping track of signers

Each block has a corresponding list of currently authorized signers and the list of current pending votes. This signers/voting state may be represented as a separate class/struct and CliqueSealEngine will store the map of recently used block hash => clique voting state (Parity has LRU cache with 128 items for this)

Block validation

These checks should go into verify method of Clique's implementation of SealEngineFace.

Other important things

CLI

(optional) Sealing

(optional) Voting

(optional) Support Goerli in Warp sync

halfalicious commented 5 years ago

Oh awesome, I was just thinking of putting together a plan for this. Great timing!

axic commented 5 years ago

cc @jwasinger

jwasinger commented 5 years ago

A note on sealing (and block import) implementation:

The block coinbase field contains the vote (or is zeroed). During contract execution, it must be set to the author of the block and reset to the original value (the vote) after contract execution (and before the block is signed). Difficulty must also be set before contract execution.

gumb0 commented 5 years ago

@jwasinger yeah I've mentioned coinbase change in "Other important things" part. And DIFFICULTY opcode I think will work the same as for Ethash (will get it from the header)

jwasinger commented 5 years ago

My point was mainly to illustrate that you need to set the COINBASE to a different value when executing contracts, and reset it afterwards to the vote value.

axic commented 5 years ago

@jwasinger if this is not clarified in https://eips.ethereum.org/EIPS/eip-225 I suggest to create a PR improving the EIP.

jwasinger commented 5 years ago

Good point. Done https://github.com/ethereum/EIPs/pull/1846

gumb0 commented 5 years ago

Serializing signers and votes - the lists should be saved into DB periodically (the simplest solution - save them for each block, though this might be wasteful)

I've read through Parity's implementation and they do something simpler, though probably less efficient - just having an in-memory cache of vote states for a number (128) of blocks. In case required state is not present in the cache, it is reconstructed from the latest checkpoint block (by replaying all votes in blocks between checkpoint and required one)

I think it would be easier for us to start with something similar, too.

gumb0 commented 5 years ago

Updated Keeping track of signers section now with a better understanding.

gumb0 commented 5 years ago

Added a bit of more info in other sections, too.

gumb0 commented 5 years ago

Some highlights of Parity's implementation that I find important/relevant for us:

PR with all changes https://github.com/paritytech/parity-ethereum/pull/9981

Higher-level description of how the code works https://github.com/paritytech/parity-ethereum/blob/78d0a8696ffec4eb6b0e2214b476fed388e14bed/ethcore/src/engines/clique/mod.rs#L17-L59

Keeping track of signers

Data structure to keep the Clique signers/voting state https://github.com/paritytech/parity-ethereum/blob/78d0a8696ffec4eb6b0e2214b476fed388e14bed/ethcore/src/engines/clique/block_state.rs#L60

Processing the votes or checkpoint block (update Clique state from the new header) https://github.com/paritytech/parity-ethereum/blob/78d0a8696ffec4eb6b0e2214b476fed388e14bed/ethcore/src/engines/clique/block_state.rs#L163

Cache storing 128 recently used Clique states https://github.com/paritytech/parity-ethereum/blob/78d0a8696ffec4eb6b0e2214b476fed388e14bed/ethcore/src/engines/clique/mod.rs#L164

Function that reconstructs Clique state from checkpoint block if not found in cache https://github.com/paritytech/parity-ethereum/blob/78d0a8696ffec4eb6b0e2214b476fed388e14bed/ethcore/src/engines/clique/mod.rs#L272

Block validation

Validating the header https://github.com/paritytech/parity-ethereum/blob/78d0a8696ffec4eb6b0e2214b476fed388e14bed/ethcore/src/engines/clique/mod.rs#L536

Sealing

Filling the block to seal https://github.com/paritytech/parity-ethereum/blob/78d0a8696ffec4eb6b0e2214b476fed388e14bed/ethcore/src/engines/clique/mod.rs#L381 Another piece of filling the block, including setting the difficulty field https://github.com/paritytech/parity-ethereum/blob/78d0a8696ffec4eb6b0e2214b476fed388e14bed/ethcore/src/engines/clique/mod.rs#L699-L735

Calculating the timestamp when to seal the next block (including random delay for out-of-turn seal) https://github.com/paritytech/parity-ethereum/blob/78d0a8696ffec4eb6b0e2214b476fed388e14bed/ethcore/src/engines/clique/block_state.rs#L268

Other

Optimization for recovery of signer addresses from block signatures: cache that stores recently recovered signer addresses https://github.com/paritytech/parity-ethereum/blob/78d0a8696ffec4eb6b0e2214b476fed388e14bed/ethcore/src/engines/clique/util.rs#L34

Signer address recovery function https://github.com/paritytech/parity-ethereum/blob/78d0a8696ffec4eb6b0e2214b476fed388e14bed/ethcore/src/engines/clique/util.rs#L38

Function to extract the signer list from checkpoint block header https://github.com/paritytech/parity-ethereum/blob/78d0a8696ffec4eb6b0e2214b476fed388e14bed/ethcore/src/engines/clique/util.rs#L85