-
Notifications
You must be signed in to change notification settings - Fork 3
Parity ethereum code walkthrough 2 The Consensus Engine, Miner and Client
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.
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
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
Responsibilities:
- Manage the blockchain database
- Expose the
EngineClient
trait, among others (for example theImportSealedBlock
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
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:
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: