mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-28 02:48:03 +00:00
Integrate BEEFY (#9833)
* Initial project setup and skeleton (#4) * initial project setup for beefy gadget client * update editorconfig * update gitignore * add initial skeleton for beefy gadget worker * add skeleton for gossip processing * add app crypto * move around some code * add basic flow for voting * add logic for picking blocks to sign * add rustfmt config * add example node with beefy gadget * use u32::next_power_of_two * make maximum periodicity configurable * add copyright header * rename max_periodicity to min_interval * CI stuff (#5) * CI stuff. * Fix workspace. * cargo fmt --all * Add license for beefy-gadget * One toolchain to rule them all. * Clippy. * Fix clippy. * Clippy in the runtime. * Fix clippy grumbles. * cargo fmt --all * Primitives & Light Client examples (#8) * Primitives. * Docs. * Document primitives. * Simple tests. * Light client examples. * Fix stuff. * cargo fmt --all * Add a bunch of tests for imports. * Add more examples. * cargo fmt --all * Fix clippy. * cargo fmt --all * Apply suggestions from code review Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com> * Add GRANDPA / FG clarifications. * Fix min number of signatures. Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com> * Update to substrate master (#22) * update to substrate master * update dependencies * fix clippy issues Co-authored-by: Tomasz Drwięga <tomasz@parity.io> * Add beefy pallet (#25) * move beefy application crypto to primitives * make primitives compile under no_std * add beefy pallet that maintains authority set * add beefy pallet to node example runtime * tabify node-example cargo.toml files * use double quotes in Cargo.toml files * add missing hex-literal dependency * add runtime api to fetch BEEFY authorities * fix clippy warnings * rename beefy-pallet to pallet-beefy * sort dependencies in node-example/runtime/Cargo.toml * Signed commitments rpc pubsub (#26) * move beefy application crypto to primitives * make primitives compile under no_std * add beefy pallet that maintains authority set * add beefy pallet to node example runtime * tabify node-example cargo.toml files * use double quotes in Cargo.toml files * add missing hex-literal dependency * add runtime api to fetch BEEFY authorities * fix clippy warnings * gadget: use commitment and signedcommitment * gadget: send notifications for signed commitments * gadget: add rpc pubsub for signed commitments * node-example: enable beefy rpc * gadget: fix clippy warnings * rename beefy-pallet to pallet-beefy * sort dependencies in node-example/runtime/Cargo.toml * gadget: add documentation on SignedCommitment rpc wrapper type * gadget: add todos about dummy beefy commitments * gadget: remove redundant closure Co-authored-by: Tomasz Drwięga <tomusdrw@users.noreply.github.com> Co-authored-by: Tomasz Drwięga <tomusdrw@users.noreply.github.com> * Integrate MMR and deposit root into the digest. (#24) * Add basic MMR. * Deposit digest item. * cargo fmt --all * Merge with primitives. * cargo fmt --all * Fix extra spaces. * cargo fmt --all * Switch branch. * remove stray whitespace * update to latest td-mmr commit * fix clippy error Co-authored-by: André Silva <andrerfosilva@gmail.com> * use new mmr root as commitment payload (#27) * use new mmr root as commitment payload * fix mmr root codec index * warn on MMR root digest not found Co-authored-by: Tomasz Drwięga <tomusdrw@users.noreply.github.com> * add type alias for MMR root hash Co-authored-by: Tomasz Drwięga <tomusdrw@users.noreply.github.com> * Bump serde_json from 1.0.59 to 1.0.60 (#28) * Update to latest substrate. (#32) * Update to latest substrate. * Fix tests. * cargo fmt --all * Switch to master. * Bump serde from 1.0.117 to 1.0.118 (#29) * Bump serde from 1.0.117 to 1.0.118 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.117 to 1.0.118. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.117...v1.0.118) Signed-off-by: dependabot-preview[bot] <support@dependabot.com> * Bump arc-swap. Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> Co-authored-by: Tomasz Drwięga <tomusdrw@users.noreply.github.com> Co-authored-by: Tomasz Drwięga <tomasz@parity.io> * Remove transition flag (#35) * Get rid of is_set_transition_flag * Fix tests. * cargo fmt --all * Bump futures from 0.3.9 to 0.3.12 (#50) * Bump log from 0.4.11 to 0.4.13 (#52) * Bump Substrate and Deps (#57) * Update README (#58) * Update README * Apply suggestions from code review Co-authored-by: Tomasz Drwięga <tomusdrw@users.noreply.github.com> * address review comments * missed a typo Co-authored-by: Tomasz Drwięga <tomusdrw@users.noreply.github.com> * Add validator set to the pallet. (#65) * Bump Substrate and Deps (#71) * Bump Substrate and Deps * pin serde and syn * bump Substrate again for '__Nonexhaustive' fix * add cargo deny ignore * Beefy pallet test (#74) * setup mock * test session change * silence beefy * clippy still * no change - no log * clippy again * Apply suggestions from code review Co-authored-by: Tomasz Drwięga <tomusdrw@users.noreply.github.com> * code review changes, added additional test Co-authored-by: Tomasz Drwięga <tomusdrw@users.noreply.github.com> * Beefy node cleanup (#75) * bump serde * bump substrate, scale-codec 2.0.0 * we need a proper beefy node * rename primitives as well * Sort members. Co-authored-by: Tomasz Drwięga <tomasz@parity.io> * Migrate beefy-pallet to FRAMEv2 (#76) * migrate beefy-pallet to FRAMEv2 * Code review Co-authored-by: Hernando Castano <HCastano@users.noreply.github.com> Co-authored-by: Hernando Castano <HCastano@users.noreply.github.com> * Run BEEFY worker as non-validator (#77) * run BEEFY worker as non-validator * don't check for roloe.is_authority * change enum type name * Bump Substrate and Deps (#79) * Add BEEFY gadget as extra peer set (#80) * Add BEEFY gadget as extra peer set * use BEEFY protocol * Add ValidatorSetId to BEEFY digest (#85) * add ValidatorSetId to BEEFY digest * apply review changes * Bump Substrate and Deps (#91) * Bump Substrate and Deps * Bump Substrate again in order to include a hot-fix * redo again * use CryptoStore issue * cargo fmt * Bump serde_json from 1.0.63 to 1.0.64 (#93) * Track BEEFY validator set (#94) * Track BEEFY validator set * Add validator_set_id to BeefyWorker * Make validattor_set_id optional * Ad 92 (#97) * sign_commitment() * Error handling todo * Add error type (#99) * Add error type * Address review * Extract worker and round logic (#104) * Bump serde from 1.0.123 to 1.0.124 (#106) * Rework BeefyAPI (#110) * Initialize BeefyWorker with current validator set (#111) * Update toolchain (#115) * Use nightly toolchain * dongradde to latest clippy stable * GH workflow trail and error * next try * use stable for clippy * update wasm builder * yet another try * fun with CI * no env var * and one more * allow from_over_into bco contruct_runtime * back to start * well ... * full circle * old version was still used * Bump Substrate and Deps (#117) * Bump Substrate and Deps * cargo fmt should enforce uniform imports * merge some imports * Delayed BEEFY worker initialization (#121) * lifecycle state * add Client convenience trait * rework trait identifiers * WIP * rework BeefyWorker::new() signature * Delayed BEEFY gadget initialization * address review * Bump substrate. (#123) * Bump substrate. * Fix tests. * Lower log-level for a missing validator set (#124) * lower log-level for a missing validator set * move best_finalized_block initialization * Setup Prometheus metrics (#125) * setup Prometheus metrics * expose validator set id * cargo fmt * Update beefy-gadget/src/lib.rs Co-authored-by: Tomasz Drwięga <tomusdrw@users.noreply.github.com> * add vote messages gossiped metric * track authorities change, before checking for MMR root digest Co-authored-by: Tomasz Drwięga <tomusdrw@users.noreply.github.com> * Make Client convenience trait public (#126) * Bump serde from 1.0.124 to 1.0.125 (#131) * Reset rounds on new validator set. (#133) * Re-set rounds on new validator set. * Fix docs. * Bump Substrate and Deps (#134) * beefy: authority set changes fixes (#139) * node: fix grandpa peers set config * gadget: update best finalized number only when finalized with beefy * gadget: process authorities changes regardless of vote status * gadget: remove superfluous signature type (#140) * node: fix grandpa peers set config * gadget: update best finalized number only when finalized with beefy * gadget: process authorities changes regardless of vote status * gadget: remove superfluous signature type Co-authored-by: Tomasz Drwięga <tomasz@parity.io> * gadget: reduce gossip spam (#141) * node: fix grandpa peers set config * gadget: update best finalized number only when finalized with beefy * gadget: process authorities changes regardless of vote status * gadget: remove superfluous signature type * gadget: only gossip last 5 rounds * gadget: note round to gossip validator before gossiping message * gadget: fix clippy warnings * gadget: update docs Co-authored-by: Tomasz Drwięga <tomusdrw@users.noreply.github.com> Co-authored-by: Tomasz Drwięga <tomusdrw@users.noreply.github.com> Co-authored-by: adoerr <0xad@gmx.net> * gadget: verify SignedCommitment message signature (#142) * gadget: verify SignedCommitment message signature * gadget: log messages with bad sigs * gadget: move todo comment * Bump futures from 0.3.13 to 0.3.14 (#145) * Milestone 1 (#144) * use best_finalized, prevent race * make best_finalized_block an Option, should_vote_on bails on None * Bump futures from 0.3.13 to 0.3.14 * Revert futures bump * Revert "Revert futures bump" This reverts commit a1b5e7e9bac526f2897ebfdfee7f02dd29a13ac5. * Revert "Bump futures from 0.3.13 to 0.3.14" This reverts commit a4e508b118ad2c4b52909d24143c284073961458. * debug msg if the bail voting * validator_set() * local_id() * get rid of worker state * Apply review suggestions * fix should_vote_on() * Extract BeefyGossipValidator (#147) * Extract BeefyGossipValidator * Apply review suggestions * Add block_delta parameter to start_beefy_gadget (#151) * Add block_delta parameter * rename to min_block_delta * Add additional metrics (#152) * Add additional metrics * add skipped session metric * add some comment for temp metric * don't log under info for every concluded round (#156) * don't log error on missing validator keys (#157) * don't log error on missing validator keys * remove unused import * Fix validator set change handling (#158) * reduce some logs from debug to trace * fix validator set changes handling * rename validator module to gossip * run rustfmt * Fix should_vote_on() (#160) * Fix should_vote_on() * by the textbook * fix the algorithm * Apply review suggestions * don't use NumberFor in vote_target Co-authored-by: André Silva <andrerfosilva@gmail.com> * Make KeyStore optional (#173) * Use builder pattern for NonDefaultSetConfig (#178) Co-authored-by: adoerr <0xad@gmx.net> * Append SignedCommitment to block justifications (#177) * Append SignedCommitment * add BeefyParams * add WorkerParams * use warn * versioned variant for SignedCommitment * Bump serde from 1.0.125 to 1.0.126 (#184) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.125 to 1.0.126. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.125...v1.0.126) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump strum from 0.20.0 to 0.21.0 (#195) * Bump strum from 0.20.0 to 0.21.0 Bumps [strum](https://github.com/Peternator7/strum) from 0.20.0 to 0.21.0. - [Release notes](https://github.com/Peternator7/strum/releases) - [Changelog](https://github.com/Peternator7/strum/blob/master/CHANGELOG.md) - [Commits](https://github.com/Peternator7/strum/commits) --- updated-dependencies: - dependency-name: strum dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * use dervie feature for strum; clippy and deny housekeeping Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: adoerr <0xad@gmx.net> * Make concluded round an info log (#200) * Remove external crypto trait bounds (#207) * BeefyKeystore newtype * WIP * remove mod ecdsa * WIP * fix tests * some polishing * Rename AuthorityId to BeefyId to avoid type conflict in UI (#211) * Add trace points; Reduce MAX_LIVE_GOSSIP_ROUNDS (#210) * Add trace points; Reduce MAX_LIVE_GOSSIP_ROUNDS * log local authority id * Additional initial authority id's (#217) * Scratch concluded rounds * adjust testnet doc * fix authority key typo * We don't want no scratches * address review comments * Fix note_round() (#219) * rename BeefyGossipValidator * Fix note_round() * use const for assert * put message trace points back in * test case note_same_round_twice() * address review comments * remove redundant check * Use LocalKeystore for tests (#224) * private_keys() * Use LocalKeystore for tests * Use keystore helper * Address review * some reformatting * Cache known votes in gossip (#227) * Implement known messages cache. * Add tests. * Appease clippy. * More clippy Co-authored-by: adoerr <0xad@gmx.net> * Some key store sanity checks (#232) * verify vote message * verify_validator_set() * rework logging * some rework * Tone down warnings. * Add signature verification. * Tone down more. * Fix clippy Co-authored-by: Tomasz Drwięga <tomasz@parity.io> * Use Binary Merkle Tree instead of a trie (#225) * Binary tree merkle root. * Add proofs and verification. * Clean up debug. * Use BEEFY addresses instead of pubkeys. * Use new merkle tree. * Optimize allocations. * Add test for larger trees. * Add tests for larger cases. * Appease clippy * Appease clippy2. * Fix proof generation & verification. * Add more test data. * Fix CLI. * Update README * Bump version. * Update docs. * Rename beefy-merkle-root to beefy-merkle-tree Co-authored-by: adoerr <0xad@gmx.net> * Bump Substrate and Deps (#235) * BEEFY+MMR pallet (#236) * Add MMR leaf format to primitives. * Fix tests * Initial work on the BEEFY-MMR pallet. * Add tests to MMR pallet. * Use eth addresses. * Use binary merkle tree. * Bump libsecp256k1 * Fix compilation. * Bump deps. * Appease cargo deny. * Re-format. * Module-level docs. * no-std fix. * update README Co-authored-by: adoerr <0xad@gmx.net> * Fix noting rounds for non-authorities (#238) * Bump env_logger from 0.8.4 to 0.9.0 (#242) Bumps [env_logger](https://github.com/env-logger-rs/env_logger) from 0.8.4 to 0.9.0. - [Release notes](https://github.com/env-logger-rs/env_logger/releases) - [Changelog](https://github.com/env-logger-rs/env_logger/blob/main/CHANGELOG.md) - [Commits](https://github.com/env-logger-rs/env_logger/compare/v0.8.4...v0.9.0) --- updated-dependencies: - dependency-name: env_logger dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * gadget: add global timeout for rebroadcasting messages (#243) * gadget: add global timeout for rebroadcasting messages * update rustfmt.toml * make message_allowed() a debug trace Co-authored-by: adoerr <0xad@gmx.net> * Bump Substrate and Deps (#245) * Bump Substrate and Deps * Bump Substrate again * Bump futures from 0.3.15 to 0.3.16 (#247) Bumps [futures](https://github.com/rust-lang/futures-rs) from 0.3.15 to 0.3.16. - [Release notes](https://github.com/rust-lang/futures-rs/releases) - [Changelog](https://github.com/rust-lang/futures-rs/blob/master/CHANGELOG.md) - [Commits](https://github.com/rust-lang/futures-rs/compare/0.3.15...0.3.16) --- updated-dependencies: - dependency-name: futures dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump libsecp256k1 from 0.5.0 to 0.6.0 (#249) * Bump libsecp256k1 from 0.5.0 to 0.6.0 Bumps [libsecp256k1](https://github.com/paritytech/libsecp256k1) from 0.5.0 to 0.6.0. - [Release notes](https://github.com/paritytech/libsecp256k1/releases) - [Changelog](https://github.com/paritytech/libsecp256k1/blob/master/CHANGELOG.md) - [Commits](https://github.com/paritytech/libsecp256k1/commits) --- updated-dependencies: - dependency-name: libsecp256k1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * use correct crate name Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: adoerr <0xad@gmx.net> * Derive `scale_info::TypeInfo` for types used in polkadot (#218) * Add scale-info TypeInfo derives * Update scale-info * Add crates.io patches * Use substrate aj-metadata-vnext branch * Revert master branch substrate deps * Add scale-info to beefy-pallet * scale-info v0.9.0 * Remove github dependencies and patches * More TypeInfo derives * Update scale-info to 0.10.0 * Add missing scale-info dependency * Add missing TypeInfo derive * Hide TypeInfo under a feature. Co-authored-by: Tomasz Drwięga <tomasz@parity.io> * Bump serde from 1.0.126 to 1.0.127 (#260) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.126 to 1.0.127. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.126...v1.0.127) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump Substrate and Deps (#262) * Update jsonrpc (#265) * Update jsonrpc * Update Substrate * bump Substrate and Deps (#268) * Bump serde from 1.0.127 to 1.0.128 (#272) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.127 to 1.0.128. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.127...v1.0.128) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Fix spelling (#271) * Bump serde from 1.0.128 to 1.0.130 (#276) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.128 to 1.0.130. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.128...v1.0.130) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump scale-info from 0.10.0 to 0.12.0 (#275) Bumps [scale-info](https://github.com/paritytech/scale-info) from 0.10.0 to 0.12.0. - [Release notes](https://github.com/paritytech/scale-info/releases) - [Changelog](https://github.com/paritytech/scale-info/blob/master/CHANGELOG.md) - [Commits](https://github.com/paritytech/scale-info/commits) --- updated-dependencies: - dependency-name: scale-info dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: adoerr <0xad@gmx.net> * Update to scale-info 1.0 (#278) * bump substrate (#282) * bump Substrate and Deps * cargo fmt Co-authored-by: Wenfeng Wang <kalot.wang@gmail.com> * Update worker.rs (#287) * Bump anyhow from 1.0.43 to 1.0.44 (#290) * Bump anyhow from 1.0.43 to 1.0.44 Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.43 to 1.0.44. - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.43...1.0.44) --- updated-dependencies: - dependency-name: anyhow dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * derive Default Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: adoerr <0xad@gmx.net> * Remove optional `scale-info` feature (#292) * Make scale-info dependency non-optional * Remove feature gated TypeInfo derives * Import TypeInfo * Update substrate * Fix up runtime * prune .git suffix (#294) * remove unused deps (#295) * remove unused deps * update lock file * Bump libsecp256k1 from 0.6.0 to 0.7.0 (#296) * Bump libsecp256k1 from 0.6.0 to 0.7.0 Bumps [libsecp256k1](https://github.com/paritytech/libsecp256k1) from 0.6.0 to 0.7.0. - [Release notes](https://github.com/paritytech/libsecp256k1/releases) - [Changelog](https://github.com/paritytech/libsecp256k1/blob/master/CHANGELOG.md) - [Commits](https://github.com/paritytech/libsecp256k1/commits) --- updated-dependencies: - dependency-name: libsecp256k1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * update sec advisories Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: adoerr <0xad@gmx.net> * clean compile * use path dependencies * beefy-gadget license header * pallet-beefy license header * pallet-beefy-mmr license header * beefy-primitves license header * carg fmt * more formatting * shorten line * downgrade parity-scale-codec to 2.2.0 * use path dependency for Prometheus endpoint * remove clippy annotations Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com> Co-authored-by: Tomasz Drwięga <tomusdrw@users.noreply.github.com> Co-authored-by: Tomasz Drwięga <tomasz@parity.io> Co-authored-by: André Silva <andrerfosilva@gmail.com> Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> Co-authored-by: Hernando Castano <HCastano@users.noreply.github.com> Co-authored-by: Pierre Krieger <pierre.krieger1708@gmail.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Andrew Jones <ascjones@gmail.com> Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com> Co-authored-by: drewstone <drewstone329@gmail.com> Co-authored-by: Andronik Ordian <write@reusable.software> Co-authored-by: Wenfeng Wang <kalot.wang@gmail.com> Co-authored-by: Joshy Orndorff <JoshOrndorff@users.noreply.github.com> Co-authored-by: Squirrel <gilescope@gmail.com>
This commit is contained in:
@@ -0,0 +1,179 @@
|
||||
// This file is part of Substrate.
|
||||
|
||||
// Copyright (C) 2021 Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
|
||||
use codec::Encode;
|
||||
|
||||
use frame_support::{traits::OneSessionHandler, Parameter};
|
||||
|
||||
use sp_runtime::{
|
||||
generic::DigestItem,
|
||||
traits::{IsMember, Member},
|
||||
RuntimeAppPublic,
|
||||
};
|
||||
use sp_std::prelude::*;
|
||||
|
||||
use beefy_primitives::{AuthorityIndex, ConsensusLog, ValidatorSet, BEEFY_ENGINE_ID};
|
||||
|
||||
#[cfg(test)]
|
||||
mod mock;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
pub use pallet::*;
|
||||
|
||||
#[frame_support::pallet]
|
||||
pub mod pallet {
|
||||
use super::*;
|
||||
use frame_support::pallet_prelude::*;
|
||||
use frame_system::pallet_prelude::*;
|
||||
|
||||
#[pallet::config]
|
||||
pub trait Config: frame_system::Config {
|
||||
/// Authority identifier type
|
||||
type BeefyId: Member + Parameter + RuntimeAppPublic + Default + MaybeSerializeDeserialize;
|
||||
}
|
||||
|
||||
#[pallet::pallet]
|
||||
pub struct Pallet<T>(PhantomData<T>);
|
||||
|
||||
#[pallet::hooks]
|
||||
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {}
|
||||
|
||||
#[pallet::call]
|
||||
impl<T: Config> Pallet<T> {}
|
||||
|
||||
/// The current authorities set
|
||||
#[pallet::storage]
|
||||
#[pallet::getter(fn authorities)]
|
||||
pub(super) type Authorities<T: Config> = StorageValue<_, Vec<T::BeefyId>, ValueQuery>;
|
||||
|
||||
/// The current validator set id
|
||||
#[pallet::storage]
|
||||
#[pallet::getter(fn validator_set_id)]
|
||||
pub(super) type ValidatorSetId<T: Config> =
|
||||
StorageValue<_, beefy_primitives::ValidatorSetId, ValueQuery>;
|
||||
|
||||
/// Authorities set scheduled to be used with the next session
|
||||
#[pallet::storage]
|
||||
#[pallet::getter(fn next_authorities)]
|
||||
pub(super) type NextAuthorities<T: Config> = StorageValue<_, Vec<T::BeefyId>, ValueQuery>;
|
||||
|
||||
#[pallet::genesis_config]
|
||||
pub struct GenesisConfig<T: Config> {
|
||||
pub authorities: Vec<T::BeefyId>,
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl<T: Config> Default for GenesisConfig<T> {
|
||||
fn default() -> Self {
|
||||
Self { authorities: Vec::new() }
|
||||
}
|
||||
}
|
||||
|
||||
#[pallet::genesis_build]
|
||||
impl<T: Config> GenesisBuild<T> for GenesisConfig<T> {
|
||||
fn build(&self) {
|
||||
Pallet::<T>::initialize_authorities(&self.authorities);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Config> Pallet<T> {
|
||||
/// Return the current active BEEFY validator set.
|
||||
pub fn validator_set() -> ValidatorSet<T::BeefyId> {
|
||||
ValidatorSet::<T::BeefyId> { validators: Self::authorities(), id: Self::validator_set_id() }
|
||||
}
|
||||
|
||||
fn change_authorities(new: Vec<T::BeefyId>, queued: Vec<T::BeefyId>) {
|
||||
// As in GRANDPA, we trigger a validator set change only if the the validator
|
||||
// set has actually changed.
|
||||
if new != Self::authorities() {
|
||||
<Authorities<T>>::put(&new);
|
||||
|
||||
let next_id = Self::validator_set_id() + 1u64;
|
||||
<ValidatorSetId<T>>::put(next_id);
|
||||
|
||||
let log: DigestItem<T::Hash> = DigestItem::Consensus(
|
||||
BEEFY_ENGINE_ID,
|
||||
ConsensusLog::AuthoritiesChange(ValidatorSet { validators: new, id: next_id })
|
||||
.encode(),
|
||||
);
|
||||
<frame_system::Pallet<T>>::deposit_log(log);
|
||||
}
|
||||
|
||||
<NextAuthorities<T>>::put(&queued);
|
||||
}
|
||||
|
||||
fn initialize_authorities(authorities: &[T::BeefyId]) {
|
||||
if authorities.is_empty() {
|
||||
return
|
||||
}
|
||||
|
||||
assert!(<Authorities<T>>::get().is_empty(), "Authorities are already initialized!");
|
||||
|
||||
<Authorities<T>>::put(authorities);
|
||||
<ValidatorSetId<T>>::put(0);
|
||||
// Like `pallet_session`, initialize the next validator set as well.
|
||||
<NextAuthorities<T>>::put(authorities);
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Config> sp_runtime::BoundToRuntimeAppPublic for Pallet<T> {
|
||||
type Public = T::BeefyId;
|
||||
}
|
||||
|
||||
impl<T: Config> OneSessionHandler<T::AccountId> for Pallet<T> {
|
||||
type Key = T::BeefyId;
|
||||
|
||||
fn on_genesis_session<'a, I: 'a>(validators: I)
|
||||
where
|
||||
I: Iterator<Item = (&'a T::AccountId, T::BeefyId)>,
|
||||
{
|
||||
let authorities = validators.map(|(_, k)| k).collect::<Vec<_>>();
|
||||
Self::initialize_authorities(&authorities);
|
||||
}
|
||||
|
||||
fn on_new_session<'a, I: 'a>(changed: bool, validators: I, queued_validators: I)
|
||||
where
|
||||
I: Iterator<Item = (&'a T::AccountId, T::BeefyId)>,
|
||||
{
|
||||
if changed {
|
||||
let next_authorities = validators.map(|(_, k)| k).collect::<Vec<_>>();
|
||||
let next_queued_authorities = queued_validators.map(|(_, k)| k).collect::<Vec<_>>();
|
||||
|
||||
Self::change_authorities(next_authorities, next_queued_authorities);
|
||||
}
|
||||
}
|
||||
|
||||
fn on_disabled(i: usize) {
|
||||
let log: DigestItem<T::Hash> = DigestItem::Consensus(
|
||||
BEEFY_ENGINE_ID,
|
||||
ConsensusLog::<T::BeefyId>::OnDisabled(i as AuthorityIndex).encode(),
|
||||
);
|
||||
|
||||
<frame_system::Pallet<T>>::deposit_log(log);
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Config> IsMember<T::BeefyId> for Pallet<T> {
|
||||
fn is_member(authority_id: &T::BeefyId) -> bool {
|
||||
Self::authorities().iter().any(|id| id == authority_id)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
// This file is part of Substrate.
|
||||
|
||||
// Copyright (C) 2021 Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use std::vec;
|
||||
|
||||
use frame_support::{
|
||||
construct_runtime, parameter_types, sp_io::TestExternalities, BasicExternalities,
|
||||
};
|
||||
use sp_core::H256;
|
||||
use sp_runtime::{
|
||||
app_crypto::ecdsa::Public,
|
||||
impl_opaque_keys,
|
||||
testing::Header,
|
||||
traits::{BlakeTwo256, ConvertInto, IdentityLookup, OpaqueKeys},
|
||||
Perbill,
|
||||
};
|
||||
|
||||
use crate as pallet_beefy;
|
||||
|
||||
pub use beefy_primitives::{crypto::AuthorityId as BeefyId, ConsensusLog, BEEFY_ENGINE_ID};
|
||||
|
||||
impl_opaque_keys! {
|
||||
pub struct MockSessionKeys {
|
||||
pub dummy: pallet_beefy::Pallet<Test>,
|
||||
}
|
||||
}
|
||||
|
||||
type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic<Test>;
|
||||
type Block = frame_system::mocking::MockBlock<Test>;
|
||||
|
||||
construct_runtime!(
|
||||
pub enum Test where
|
||||
Block = Block,
|
||||
NodeBlock = Block,
|
||||
UncheckedExtrinsic = UncheckedExtrinsic,
|
||||
{
|
||||
System: frame_system::{Pallet, Call, Config, Storage, Event<T>},
|
||||
Beefy: pallet_beefy::{Pallet, Call, Config<T>, Storage},
|
||||
Session: pallet_session::{Pallet, Call, Storage, Event, Config<T>},
|
||||
}
|
||||
);
|
||||
|
||||
parameter_types! {
|
||||
pub const BlockHashCount: u64 = 250;
|
||||
pub const SS58Prefix: u8 = 42;
|
||||
}
|
||||
|
||||
impl frame_system::Config for Test {
|
||||
type BaseCallFilter = frame_support::traits::Everything;
|
||||
type BlockWeights = ();
|
||||
type BlockLength = ();
|
||||
type DbWeight = ();
|
||||
type Origin = Origin;
|
||||
type Index = u64;
|
||||
type BlockNumber = u64;
|
||||
type Hash = H256;
|
||||
type Call = Call;
|
||||
type Hashing = BlakeTwo256;
|
||||
type AccountId = u64;
|
||||
type Lookup = IdentityLookup<Self::AccountId>;
|
||||
type Header = Header;
|
||||
type Event = Event;
|
||||
type BlockHashCount = BlockHashCount;
|
||||
type Version = ();
|
||||
type PalletInfo = PalletInfo;
|
||||
type AccountData = ();
|
||||
type OnNewAccount = ();
|
||||
type OnKilledAccount = ();
|
||||
type SystemWeightInfo = ();
|
||||
type SS58Prefix = SS58Prefix;
|
||||
type OnSetCode = ();
|
||||
}
|
||||
|
||||
impl pallet_beefy::Config for Test {
|
||||
type BeefyId = BeefyId;
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub const Period: u64 = 1;
|
||||
pub const Offset: u64 = 0;
|
||||
pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(33);
|
||||
}
|
||||
|
||||
impl pallet_session::Config for Test {
|
||||
type Event = Event;
|
||||
type ValidatorId = u64;
|
||||
type ValidatorIdOf = ConvertInto;
|
||||
type ShouldEndSession = pallet_session::PeriodicSessions<Period, Offset>;
|
||||
type NextSessionRotation = pallet_session::PeriodicSessions<Period, Offset>;
|
||||
type SessionManager = MockSessionManager;
|
||||
type SessionHandler = <MockSessionKeys as OpaqueKeys>::KeyTypeIdProviders;
|
||||
type Keys = MockSessionKeys;
|
||||
type DisabledValidatorsThreshold = DisabledValidatorsThreshold;
|
||||
type WeightInfo = ();
|
||||
}
|
||||
|
||||
pub struct MockSessionManager;
|
||||
|
||||
impl pallet_session::SessionManager<u64> for MockSessionManager {
|
||||
fn end_session(_: sp_staking::SessionIndex) {}
|
||||
fn start_session(_: sp_staking::SessionIndex) {}
|
||||
fn new_session(idx: sp_staking::SessionIndex) -> Option<Vec<u64>> {
|
||||
if idx == 0 || idx == 1 {
|
||||
Some(vec![1, 2])
|
||||
} else if idx == 2 {
|
||||
Some(vec![3, 4])
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Note, that we can't use `UintAuthorityId` here. Reason is that the implementation
|
||||
// of `to_public_key()` assumes, that a public key is 32 bytes long. This is true for
|
||||
// ed25519 and sr25519 but *not* for ecdsa. An ecdsa public key is 33 bytes.
|
||||
pub fn mock_beefy_id(id: u8) -> BeefyId {
|
||||
let buf: [u8; 33] = [id; 33];
|
||||
let pk = Public::from_raw(buf);
|
||||
BeefyId::from(pk)
|
||||
}
|
||||
|
||||
pub fn mock_authorities(vec: Vec<u8>) -> Vec<(u64, BeefyId)> {
|
||||
vec.into_iter().map(|id| ((id as u64), mock_beefy_id(id))).collect()
|
||||
}
|
||||
|
||||
pub fn new_test_ext(ids: Vec<u8>) -> TestExternalities {
|
||||
new_test_ext_raw_authorities(mock_authorities(ids))
|
||||
}
|
||||
|
||||
pub fn new_test_ext_raw_authorities(authorities: Vec<(u64, BeefyId)>) -> TestExternalities {
|
||||
let mut t = frame_system::GenesisConfig::default().build_storage::<Test>().unwrap();
|
||||
|
||||
let session_keys: Vec<_> = authorities
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(_, id)| (id.0 as u64, id.0 as u64, MockSessionKeys { dummy: id.1.clone() }))
|
||||
.collect();
|
||||
|
||||
BasicExternalities::execute_with_storage(&mut t, || {
|
||||
for (ref id, ..) in &session_keys {
|
||||
frame_system::Pallet::<Test>::inc_providers(id);
|
||||
}
|
||||
});
|
||||
|
||||
pallet_session::GenesisConfig::<Test> { keys: session_keys }
|
||||
.assimilate_storage(&mut t)
|
||||
.unwrap();
|
||||
|
||||
t.into()
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
// This file is part of Substrate.
|
||||
|
||||
// Copyright (C) 2021 Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use std::vec;
|
||||
|
||||
use beefy_primitives::ValidatorSet;
|
||||
use codec::Encode;
|
||||
|
||||
use sp_core::H256;
|
||||
use sp_runtime::DigestItem;
|
||||
|
||||
use frame_support::traits::OnInitialize;
|
||||
|
||||
use crate::mock::*;
|
||||
|
||||
fn init_block(block: u64) {
|
||||
System::set_block_number(block);
|
||||
Session::on_initialize(block);
|
||||
}
|
||||
|
||||
pub fn beefy_log(log: ConsensusLog<BeefyId>) -> DigestItem<H256> {
|
||||
DigestItem::Consensus(BEEFY_ENGINE_ID, log.encode())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn genesis_session_initializes_authorities() {
|
||||
let want = vec![mock_beefy_id(1), mock_beefy_id(2), mock_beefy_id(3), mock_beefy_id(4)];
|
||||
|
||||
new_test_ext(vec![1, 2, 3, 4]).execute_with(|| {
|
||||
let authorities = Beefy::authorities();
|
||||
|
||||
assert!(authorities.len() == 2);
|
||||
assert_eq!(want[0], authorities[0]);
|
||||
assert_eq!(want[1], authorities[1]);
|
||||
|
||||
assert!(Beefy::validator_set_id() == 0);
|
||||
|
||||
let next_authorities = Beefy::next_authorities();
|
||||
|
||||
assert!(next_authorities.len() == 2);
|
||||
assert_eq!(want[0], next_authorities[0]);
|
||||
assert_eq!(want[1], next_authorities[1]);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn session_change_updates_authorities() {
|
||||
new_test_ext(vec![1, 2, 3, 4]).execute_with(|| {
|
||||
init_block(1);
|
||||
|
||||
assert!(0 == Beefy::validator_set_id());
|
||||
|
||||
// no change - no log
|
||||
assert!(System::digest().logs.is_empty());
|
||||
|
||||
init_block(2);
|
||||
|
||||
assert!(1 == Beefy::validator_set_id());
|
||||
|
||||
let want = beefy_log(ConsensusLog::AuthoritiesChange(ValidatorSet {
|
||||
validators: vec![mock_beefy_id(3), mock_beefy_id(4)],
|
||||
id: 1,
|
||||
}));
|
||||
|
||||
let log = System::digest().logs[0].clone();
|
||||
|
||||
assert_eq!(want, log);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn session_change_updates_next_authorities() {
|
||||
let want = vec![mock_beefy_id(1), mock_beefy_id(2), mock_beefy_id(3), mock_beefy_id(4)];
|
||||
|
||||
new_test_ext(vec![1, 2, 3, 4]).execute_with(|| {
|
||||
init_block(1);
|
||||
|
||||
let next_authorities = Beefy::next_authorities();
|
||||
|
||||
assert!(next_authorities.len() == 2);
|
||||
assert_eq!(want[0], next_authorities[0]);
|
||||
assert_eq!(want[1], next_authorities[1]);
|
||||
|
||||
init_block(2);
|
||||
|
||||
let next_authorities = Beefy::next_authorities();
|
||||
|
||||
assert!(next_authorities.len() == 2);
|
||||
assert_eq!(want[2], next_authorities[0]);
|
||||
assert_eq!(want[3], next_authorities[1]);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn validator_set_at_genesis() {
|
||||
let want = vec![mock_beefy_id(1), mock_beefy_id(2)];
|
||||
|
||||
new_test_ext(vec![1, 2, 3, 4]).execute_with(|| {
|
||||
let vs = Beefy::validator_set();
|
||||
|
||||
assert_eq!(vs.id, 0u64);
|
||||
assert_eq!(vs.validators[0], want[0]);
|
||||
assert_eq!(vs.validators[1], want[1]);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn validator_set_updates_work() {
|
||||
let want = vec![mock_beefy_id(1), mock_beefy_id(2), mock_beefy_id(3), mock_beefy_id(4)];
|
||||
|
||||
new_test_ext(vec![1, 2, 3, 4]).execute_with(|| {
|
||||
init_block(1);
|
||||
|
||||
let vs = Beefy::validator_set();
|
||||
|
||||
assert_eq!(vs.id, 0u64);
|
||||
assert_eq!(want[0], vs.validators[0]);
|
||||
assert_eq!(want[1], vs.validators[1]);
|
||||
|
||||
init_block(2);
|
||||
|
||||
let vs = Beefy::validator_set();
|
||||
|
||||
assert_eq!(vs.id, 1u64);
|
||||
assert_eq!(want[2], vs.validators[0]);
|
||||
assert_eq!(want[3], vs.validators[1]);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user