vapcore-clique
Implementation of the Clique PoA Engine.
File structure:
- mod.rs -> Provides the engine API implementation, with additional block state tracking
- block_state.rs -> Records the Clique state for given block.
- params.rs -> Contains the parameters for the Clique engine.
- step_service.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:
- Client will call:
Clique::verify_block_basic()Clique::verify_block_unordered()Clique::verify_block_family()
- Using
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. - Once we have a good state, we can record it using
CliqueBlockState::apply().
How sealing works:
- Set a signer using
Engine::set_signer(). If a miner account was set up through a config file or CLI flagMinerService::set_author()will eventually set the signer - We check that the engine is ready for sealing through
Clique::sealing_state()Note: This is alwaysSealingState::Readyfor Clique - Calling
Clique::new()will spawn aStepServicethread. This thread will callEngine::step()periodically. Internally, the Cliquestep()function callsClient::update_sealing(), which is what makes and seals a block. Clique::generate_seal()will then be called byminer. This will return aSealwhich is either aSeal::NoneorSeal:Regular. The following shows how aSealvariant is chosen: a. We returnSeal::Noneif no signer is available or the signer is not authorized. b. If period == 0 and block has transactions, we returnSeal::Regular, otherwise returnSeal::None. c. If we'reINTURN, wait for at leastperiodsince last block before trying to seal. d. If we're notINTURN, we wait for a random amount of time using the algorithm specified in EIP-225 before trying to seal again.- Miner will create new block, in process it will call several engine methods to do following:
a.
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. - We call
Clique::on_seal_block()which will allow us to modify the block header during seal generation. - Finally,
Clique::verify_local_seal()is called. After this, the syncing code path will be followed in order to import the new block.