Skip to content

Parity ethereum code walkthrough 2 The Consensus Engine, Miner and Client

David Forstenlechner edited this page Feb 4, 2020 · 10 revisions

There are three main actors in Consensus Engine operation and block creation, which are the Engine, the Miner and the Client. Building on the the Parity ethereum code walkthrough 1 document we explore how these three entities are initialized and how they interact to produce blocks.

parity-ethereum/parity/run.rs

The Run command's execute_impl function creates and configures the Ethereum client service, and all its dependencies, most notably the Spec and the Miner, where the Spec owns an Arc of a Consensus Engine implementation exposing the Engine trait.

The relevant excerpts of the execute_impl function:

let spec = cmd.spec.spec(&cmd.dirs.cache)?;
...
let miner = Arc::new(Miner::new(
   cmd.miner_options,
   cmd.gas_pricer_conf.to_gas_pricer(fetch.clone(), runtime.executor()),
   &spec,
   (
      cmd.miner_extras.local_accounts,
      account_utils::miner_local_accounts(account_provider.clone()),
   )
));
miner.set_author(miner::Author::External(cmd.miner_extras.author));
...
let service = ClientService::start(
   client_config,
   &spec,
   client_db,
...

Note that both Miner and Client Service take the spec (including the Consensus Engine implementation) as argument.

Note also that the set_author function of the miner is getting called, which in turn calls the Engine's set_signer function.

ClientService::start creates the Client and calls the Engine's register_client function.

At that point the Consensus Engine is initialized with a Signer as well as with an EngineClient trait object exposed by the Client implementation.

This EngineClient trait object is the main means of communication with the rest of Parity for the Consensus Engine.

The Consensus Engine

parity-ethereum/ethcore/engine/src/engine.rs

"Engine" is a trait required to be implemented by consensus engines used in parity-ethereum's pluggable consensus system.

Notable members of that trait are:

  • register_client Called on client service initialization, supplies the consensus engine with an "EngineClient" trait object, usually implemented by the Client. The "EngineClient" trait is the main way Engines interact with the Client and Miner to create blocks.
  • set_signer Called by the Miner's "set_author" function, which in turn is called by "execute_impl"
  • sealing_state Returns the Engine's current sealing state
  • generate_seal Attempts to seal the block
  • should_miner_prepare_blocks Whether the miner should prepare blocks for sealing for this engine (HBBFT-specific extension)
  • use_block_author Use the author as signer as well as block author (HBBFT-specific extension)

For the full documentation see ethcore/engine/src/engine.rs

Main responsibilities:

  • Trigger block creation
  • Seal blocks
  • Expose the Engine trait

The Miner

Main responsibilities:

  • Manage the transaction queue and transaction imports
  • Manages the creation of new blocks
  • Expose the MinerService trait

For the full implementation see ethcore/engine/src/engine.rs

The Client

Responsibilities:

  • Manage the blockchain database
  • Expose the EngineClient trait, among others (for example the ImportSealedBlock trait which is used to commit the block to the blockchain as shown in the diagrams below)

Notable members of the EngineClient trait are:

  • broadcast_consensus_message Sends a consensus message to all connected clients
  • send_consensus_message Sends a consensus message to a specific client (HBBFT-specific extension)
  • create_pending_block_at Creates a new pending block with a specific collection of transactions and time stamp (HBBFT-specific extension)

For the full implementation see ethcore/src/client/client.rs

Consensus Engine Block Creation

Block creation is under full control of the consensus engine implementation. It can trigger the creation and sealing of a new block as it sees fit, just consider that by default the granularity of block time stamps is 1s, causing verification failures with sub-second block times.

The actual sequence of events can look very different between consensus protocols. For authority round it works like this: Aura Block Generation

While Honey Badger BFT needs more control over the block creation process, since all validator nodes need to arrive at exactly the same block, containing exactly the same transactions simultaneously.

Block creation is triggered only when HBBFT consensus has already finished and the transactions to include as well as the block time stamp are final. The function create_pending_block_at (HBBFT-specific extension) takes the transactions to include and the time stamp as argument to assure the blocks created by all validators produce identical hashes. All there is left to do is to perform the sealing round to finalize and import the block: Honey Badger BFT block generation