Files
pezkuwi-subxt/substrate/client/consensus/babe
Aaro Altonen 1a7f5be07f Extract syncing protocol from sc-network (#12828)
* Move import queue out of `sc-network`

Add supplementary asynchronous API for the import queue which means
it can be run as an independent task and communicated with through
the `ImportQueueService`.

This commit removes removes block and justification imports from
`sc-network` and provides `ChainSync` with a handle to import queue so
it can import blocks and justifications. Polling of the import queue is
moved complete out of `sc-network` and `sc_consensus::Link` is
implemented for `ChainSyncInterfaceHandled` so the import queue
can still influence the syncing process.

* Move stuff to SyncingEngine

* Move `ChainSync` instanation to `SyncingEngine`

Some of the tests have to be rewritten

* Move peer hashmap to `SyncingEngine`

* Let `SyncingEngine` to implement `ChainSyncInterface`

* Introduce `SyncStatusProvider`

* Move `sync_peer_(connected|disconnected)` to `SyncingEngine`

* Implement `SyncEventStream`

Remove `SyncConnected`/`SyncDisconnected` events from
`NetworkEvenStream` and provide those events through
`ChainSyncInterface` instead.

Modify BEEFY/GRANDPA/transactions protocol and `NetworkGossip` to take
`SyncEventStream` object which they listen to for incoming sync peer
events.

* Introduce `ChainSyncInterface`

This interface provides a set of miscellaneous functions that other
subsystems can use to query, for example, the syncing status.

* Move event stream polling to `SyncingEngine`

Subscribe to `NetworkStreamEvent` and poll the incoming notifications
and substream events from `SyncingEngine`.

The code needs refactoring.

* Make `SyncingEngine` into an asynchronous runner

This commits removes the last hard dependency of syncing from
`sc-network` meaning the protocol now lives completely outside of
`sc-network`, ignoring the hardcoded peerset entry which will be
addressed in the future.

Code needs a lot of refactoring.

* Fix warnings

* Code refactoring

* Use `SyncingService` for BEEFY

* Use `SyncingService` for GRANDPA

* Remove call delegation from `NetworkService`

* Remove `ChainSyncService`

* Remove `ChainSync` service tests

They were written for the sole purpose of verifying that `NetworWorker`
continues to function while the calls are being dispatched to
`ChainSync`.

* Refactor code

* Refactor code

* Update client/finality-grandpa/src/communication/tests.rs

Co-authored-by: Anton <anton.kalyaev@gmail.com>

* Fix warnings

* Apply review comments

* Fix docs

* Fix test

* cargo-fmt

* Update client/network/sync/src/engine.rs

Co-authored-by: Anton <anton.kalyaev@gmail.com>

* Update client/network/sync/src/engine.rs

Co-authored-by: Anton <anton.kalyaev@gmail.com>

* Add missing docs

* Refactor code

---------

Co-authored-by: Anton <anton.kalyaev@gmail.com>
2023-03-06 16:33:38 +00:00
..
2020-11-05 19:18:55 +01:00

BABE (Blind Assignment for Blockchain Extension)

BABE is a slot-based block production mechanism which uses a VRF PRNG to randomly perform the slot allocation. On every slot, all the authorities generate a new random number with the VRF function and if it is lower than a given threshold (which is proportional to their weight/stake) they have a right to produce a block. The proof of the VRF function execution will be used by other peer to validate the legitimacy of the slot claim.

The engine is also responsible for collecting entropy on-chain which will be used to seed the given VRF PRNG. An epoch is a contiguous number of slots under which we will be using the same authority set. During an epoch all VRF outputs produced as a result of block production will be collected on an on-chain randomness pool. Epoch changes are announced one epoch in advance, i.e. when ending epoch N, we announce the parameters (randomness, authorities, etc.) for epoch N+2.

Since the slot assignment is randomized, it is possible that a slot is assigned to multiple validators in which case we will have a temporary fork, or that a slot is assigned to no validator in which case no block is produced. Which means that block times are not deterministic.

The protocol has a parameter c [0, 1] for which 1 - c is the probability of a slot being empty. The choice of this parameter affects the security of the protocol relating to maximum tolerable network delays.

In addition to the VRF-based slot assignment described above, which we will call primary slots, the engine also supports a deterministic secondary slot assignment. Primary slots take precedence over secondary slots, when authoring the node starts by trying to claim a primary slot and falls back to a secondary slot claim attempt. The secondary slot assignment is done by picking the authority at index:

blake2_256(epoch_randomness ++ slot_number) % authorities_len.

The secondary slots supports either a SecondaryPlain or SecondaryVRF variant. Comparing with SecondaryPlain variant, the SecondaryVRF variant generates an additional VRF output. The output is not included in beacon randomness, but can be consumed by parachains.

The fork choice rule is weight-based, where weight equals the number of primary blocks in the chain. We will pick the heaviest chain (more primary blocks) and will go with the longest one in case of a tie.

An in-depth description and analysis of the protocol can be found here: https://research.web3.foundation/en/latest/polkadot/block-production/Babe.html

License: GPL-3.0-or-later WITH Classpath-exception-2.0