Implementation of the Clique PoA Engine.
File structure: - mod.rs -> Provides the engine API implementation, with additional block state tracking - blockstate.rs -> Records the Clique state for given block. - params.rs -> Contains the parameters for the Clique engine. - stepservice.rs -> An event loop to trigger sealing. - util.rs -> Various standalone utility functions. - tests.rs -> Consensus tests as defined in EIP-225.
How syncing works:
Clique::verify_block_basic()
Clique::verify_block_unordered()
Clique::verify_block_family()
Clique::state()
we try and retrieve the parent state. If this isn't found
we need to back-fill it from the last known checkpoint.CliqueBlockState::apply()
.How sealing works:
Engine::set_signer()
. If a miner account was set up through
a config file or CLI flag MinerService::set_author()
will eventually set the signerClique::sealing_state()
Note: This is always SealingState::Ready
for CliqueClique::new()
will spawn a StepService
thread. This thread will call Engine::step()
periodically. Internally, the Clique step()
function calls Client::update_sealing()
, which is
what makes and seals a block.Clique::generate_seal()
will then be called by miner
. This will return a Seal
which
is either a Seal::None
or Seal:Regular
. The following shows how a Seal
variant is chosen:
a. We return Seal::None
if no signer is available or the signer is not authorized.
b. If period == 0 and block has transactions, we return Seal::Regular
, otherwise return Seal::None
.
c. If we're INTURN
, wait for at least period
since last block before trying to seal.
d. If we're not INTURN
, we wait for a random amount of time using the algorithm specified
in EIP-225 before trying to seal again.Clique::open_block_header_timestamp()
must set timestamp correctly.
b. Clique::populate_from_parent()
must set difficulty to correct value.
Note: Clique::populate_from_parent()
is used in both the syncing and sealing code paths.Clique::on_seal_block()
which will allow us to modify the block header during seal generation.Clique::verify_local_seal()
is called. After this, the syncing code path will be followed
in order to import the new block.