* Asyncify sign_with * Asyncify generate/get keys * Complete BareCryptoStore asyncification * Cleanup * Rebase * Add Proxy * Inject keystore proxy into extensions * Implement some methods * Await on send * Cleanup * Send result over the oneshot channel sender * Process one future at a time * Fix cargo stuff * Asyncify sr25519_vrf_sign * Cherry-pick and fix changes * Introduce SyncCryptoStore * SQUASH ME WITH THE first commit * Implement into SyncCryptoStore * Implement BareCryptoStore for KeystoreProxyAdapter * authority-discovery * AURA * BABE * finality-grandpa * offchain-workers * benchmarking-cli * sp_io * test-utils * application-crypto * Extensions and RPC * Client Service * bin * Update cargo.lock * Implement BareCryptoStore on proxy directly * Simplify proxy setup * Fix authority-discover * Pass async keystore to authority-discovery * Fix tests * Use async keystore in authority-discovery * Rename BareCryptoStore to CryptoStore * WIP * Remote mutable borrow in CryptoStore trait * Implement Keystore with backends * Remove Proxy implementation * Fix service builder and keystore user-crates * Fix tests * Rework authority-discovery after refactoring * futures::select! * Fix multiple mut borrows in authority-discovery * Merge fixes * Require sync * Restore Cargo.lock * PR feedback - round 1 * Remove Keystore and use LocalKeystore directly Also renamed KeystoreParams to KeystoreContainer * Join * Remove sync requirement * Fix keystore tests * Fix tests * client/authority-discovery: Remove event stream dynamic dispatching With authority-discovery moving from a poll based future to an `async` future Rust has difficulties propagating the `Sync` trade through the generated state machine. Instead of using dynamic dispatching, use a trait parameter to specify the DHT event stream. * Make it compile * Fix submit_transaction * Fix block_on issue * Use await in async context * Fix manual seal keystore * Fix authoring_blocks test * fix aura authoring_blocks * Try to fix tests for auth-discovery * client/authority-discovery: Fix lookup_throttling test * client/authority-discovery: Fix triggers_dht_get_query test * Fix epoch_authorship_works * client/authority-discovery: Remove timing assumption in unit test * client/authority-discovery: Revert changes to termination test * PR feedback * Remove deadcode and mark test code * Fix test_sync * Use the correct keyring type * Return when from_service stream is closed * Convert SyncCryptoStore to a trait * Fix line width * Fix line width - take 2 * Remove unused import * Fix keystore instantiation * PR feedback * Remove KeystoreContainer * Revert "Remove KeystoreContainer" This reverts commit ea4a37c7d74f9772b93d974e05e4498af6192730. * Take a ref of keystore * Move keystore to dev-dependencies * Address some PR feedback * Missed one * Pass keystore reference - take 2 * client/finality-grandpa: Use `Arc<dyn CryptoStore>` instead of SyncXXX Instead of using `SyncCryptoStorePtr` within `client/finality-grandpa`, which is a type alias for `Arc<dyn SyncCryptoStore>`, use `Arc<dyn CryptoStore>`. Benefits are: 1. No additional mental overhead of a `SyncCryptoStorePtr`. 2. Ability for new code to use the asynchronous methods of `CryptoStore` instead of the synchronous `SyncCryptoStore` methods within `client/finality-granpa` without the need for larger refactorings. Note: This commit uses `Arc<dyn CryptoStore>` instead of `CryptoStorePtr`, as I find the type signature more descriptive. This is subjective and in no way required. * Remove SyncCryptoStorePtr * Remove KeystoreContainer & SyncCryptoStorePtr * PR feedback * *: Use CryptoStorePtr whereever possible * *: Define SyncCryptoStore as a pure extension trait of CryptoStore * Follow up to SyncCryptoStore extension trait * Adjust docs for SyncCryptoStore as Ben suggested * Cleanup unnecessary requirements * sp-keystore * Use async_std::task::block_on in keystore * Fix block_on std requirement * Update primitives/keystore/src/lib.rs Co-authored-by: Max Inden <mail@max-inden.de> * Fix wasm build * Remove unused var * Fix wasm compilation - take 2 * Revert async-std in keystore * Fix indent * Fix version and copyright * Cleanup feature = "std" * Auth Discovery: Ignore if from_service is cloed * Max's suggestion * Revert async-std usage for block_on * Address PR feedback * Fix example offchain worker build * Address PR feedback * Update Cargo.lock * Move unused methods to test helper functions * Restore accidentally deleted cargo.lock files * Fix unused imports Co-authored-by: Max Inden <mail@max-inden.de> Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com>
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/BABE/Babe.html
License: GPL-3.0-or-later WITH Classpath-exception-2.0