diff --git a/Cargo.lock b/Cargo.lock index b801da264363a..54088c9572717 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3648,7 +3648,6 @@ dependencies = [ "serde_json", "sp-consensus", "sp-core", - "sp-finality-tracker", "sp-inherents", "sp-runtime", "sp-state-machine", @@ -3734,7 +3733,6 @@ dependencies = [ "sp-consensus-babe", "sp-core", "sp-finality-grandpa", - "sp-finality-tracker", "sp-inherents", "sp-io", "sp-keyring", @@ -3882,7 +3880,6 @@ dependencies = [ "pallet-contracts-rpc-runtime-api", "pallet-democracy", "pallet-elections-phragmen", - "pallet-finality-tracker", "pallet-grandpa", "pallet-identity", "pallet-im-online", @@ -4034,7 +4031,6 @@ dependencies = [ "sp-blockchain", "sp-consensus", "sp-core", - "sp-finality-tracker", "sp-inherents", "sp-io", "sp-keyring", @@ -4530,23 +4526,6 @@ dependencies = [ "sp-std", ] -[[package]] -name = "pallet-finality-tracker" -version = "2.0.0" -dependencies = [ - "frame-support", - "frame-system", - "impl-trait-for-tuples", - "parity-scale-codec", - "serde", - "sp-core", - "sp-finality-tracker", - "sp-inherents", - "sp-io", - "sp-runtime", - "sp-std", -] - [[package]] name = "pallet-grandpa" version = "2.0.0" @@ -4557,7 +4536,6 @@ dependencies = [ "frame-system", "pallet-authorship", "pallet-balances", - "pallet-finality-tracker", "pallet-offences", "pallet-session", "pallet-staking", @@ -6816,7 +6794,6 @@ dependencies = [ "sp-consensus-babe", "sp-core", "sp-finality-grandpa", - "sp-finality-tracker", "sp-inherents", "sp-keyring", "sp-keystore", @@ -8133,15 +8110,6 @@ dependencies = [ "sp-std", ] -[[package]] -name = "sp-finality-tracker" -version = "2.0.0" -dependencies = [ - "parity-scale-codec", - "sp-inherents", - "sp-std", -] - [[package]] name = "sp-inherents" version = "2.0.0" diff --git a/Cargo.toml b/Cargo.toml index ecea10cc45582..dbe5211e8c0ef 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -77,7 +77,6 @@ members = [ "frame/example", "frame/example-offchain-worker", "frame/executive", - "frame/finality-tracker", "frame/grandpa", "frame/identity", "frame/im-online", @@ -133,7 +132,6 @@ members = [ "primitives/debug-derive", "primitives/storage", "primitives/externalities", - "primitives/finality-tracker", "primitives/finality-grandpa", "primitives/inherents", "primitives/keyring", diff --git a/bin/node-template/node/src/service.rs b/bin/node-template/node/src/service.rs index 8a9e9bfad882a..1029685628986 100644 --- a/bin/node-template/node/src/service.rs +++ b/bin/node-template/node/src/service.rs @@ -201,7 +201,6 @@ pub fn new_full(config: Configuration) -> Result { config: grandpa_config, link: grandpa_link, network, - inherent_data_providers, telemetry_on_connect: Some(telemetry_connection_sinks.on_connect_stream()), voting_rule: sc_finality_grandpa::VotingRulesBuilder::default().build(), prometheus_registry, @@ -215,11 +214,7 @@ pub fn new_full(config: Configuration) -> Result { sc_finality_grandpa::run_grandpa_voter(grandpa_config)? ); } else { - sc_finality_grandpa::setup_disabled_grandpa( - client, - &inherent_data_providers, - network, - )?; + sc_finality_grandpa::setup_disabled_grandpa(network)?; } network_starter.start_network(); diff --git a/bin/node/bench/Cargo.toml b/bin/node/bench/Cargo.toml index c0f5bf889521c..88362f7e51022 100644 --- a/bin/node/bench/Cargo.toml +++ b/bin/node/bench/Cargo.toml @@ -29,7 +29,6 @@ sp-consensus = { version = "0.8.0", path = "../../../primitives/consensus/common sp-transaction-pool = { version = "2.0.0", path = "../../../primitives/transaction-pool" } sc-basic-authorship = { version = "0.8.0", path = "../../../client/basic-authorship" } sp-inherents = { version = "2.0.0", path = "../../../primitives/inherents" } -sp-finality-tracker = { version = "2.0.0", default-features = false, path = "../../../primitives/finality-tracker" } sp-timestamp = { version = "2.0.0", default-features = false, path = "../../../primitives/timestamp" } sp-tracing = { version = "2.0.0", path = "../../../primitives/tracing" } hash-db = "0.15.2" diff --git a/bin/node/cli/Cargo.toml b/bin/node/cli/Cargo.toml index bc9351e2046c2..e396b2dcefff5 100644 --- a/bin/node/cli/Cargo.toml +++ b/bin/node/cli/Cargo.toml @@ -51,7 +51,6 @@ grandpa-primitives = { version = "2.0.0", package = "sp-finality-grandpa", path sp-core = { version = "2.0.0", path = "../../../primitives/core" } sp-runtime = { version = "2.0.0", path = "../../../primitives/runtime" } sp-timestamp = { version = "2.0.0", default-features = false, path = "../../../primitives/timestamp" } -sp-finality-tracker = { version = "2.0.0", default-features = false, path = "../../../primitives/finality-tracker" } sp-inherents = { version = "2.0.0", path = "../../../primitives/inherents" } sp-keyring = { version = "2.0.0", path = "../../../primitives/keyring" } sp-keystore = { version = "0.8.0", path = "../../../primitives/keystore" } diff --git a/bin/node/cli/src/service.rs b/bin/node/cli/src/service.rs index 61b17899c6afa..c9918eec219d2 100644 --- a/bin/node/cli/src/service.rs +++ b/bin/node/cli/src/service.rs @@ -316,7 +316,6 @@ pub fn new_full_base( config, link: grandpa_link, network: network.clone(), - inherent_data_providers: inherent_data_providers.clone(), telemetry_on_connect: Some(telemetry_connection_sinks.on_connect_stream()), voting_rule: grandpa::VotingRulesBuilder::default().build(), prometheus_registry, @@ -330,16 +329,16 @@ pub fn new_full_base( grandpa::run_grandpa_voter(grandpa_config)? ); } else { - grandpa::setup_disabled_grandpa( - client.clone(), - &inherent_data_providers, - network.clone(), - )?; + grandpa::setup_disabled_grandpa(network.clone())?; } network_starter.start_network(); Ok(NewFullBase { - task_manager, inherent_data_providers, client, network, network_status_sinks, + task_manager, + inherent_data_providers, + client, + network, + network_status_sinks, transaction_pool, }) } @@ -481,7 +480,6 @@ mod tests { traits::Verify, }; use sp_timestamp; - use sp_finality_tracker; use sp_keyring::AccountKeyring; use sc_service_test::TestNetNode; use crate::service::{new_full_base, new_light_base, NewFullBase}; @@ -541,7 +539,6 @@ mod tests { let mut inherent_data = inherent_data_providers .create_inherent_data() .expect("Creates inherent data."); - inherent_data.replace_data(sp_finality_tracker::INHERENT_IDENTIFIER, &1u64); let parent_id = BlockId::number(service.client().chain_info().best_number); let parent_header = service.client().header(&parent_id).unwrap().unwrap(); diff --git a/bin/node/runtime/Cargo.toml b/bin/node/runtime/Cargo.toml index 6142998ac063c..80c914ff57580 100644 --- a/bin/node/runtime/Cargo.toml +++ b/bin/node/runtime/Cargo.toml @@ -54,7 +54,6 @@ pallet-contracts-primitives = { version = "2.0.0", default-features = false, pat pallet-contracts-rpc-runtime-api = { version = "0.8.0", default-features = false, path = "../../../frame/contracts/rpc/runtime-api/" } pallet-democracy = { version = "2.0.0", default-features = false, path = "../../../frame/democracy" } pallet-elections-phragmen = { version = "2.0.0", default-features = false, path = "../../../frame/elections-phragmen" } -pallet-finality-tracker = { version = "2.0.0", default-features = false, path = "../../../frame/finality-tracker" } pallet-grandpa = { version = "2.0.0", default-features = false, path = "../../../frame/grandpa" } pallet-im-online = { version = "2.0.0", default-features = false, path = "../../../frame/im-online" } pallet-indices = { version = "2.0.0", default-features = false, path = "../../../frame/indices" } @@ -105,7 +104,6 @@ std = [ "pallet-democracy/std", "pallet-elections-phragmen/std", "frame-executive/std", - "pallet-finality-tracker/std", "pallet-grandpa/std", "pallet-im-online/std", "pallet-indices/std", diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 2d150e22bddaa..dfa7a4680abe8 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -112,8 +112,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to 0. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 259, - impl_version: 1, + spec_version: 260, + impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 1, }; @@ -814,17 +814,6 @@ impl pallet_grandpa::Trait for Runtime { type WeightInfo = (); } -parameter_types! { - pub const WindowSize: BlockNumber = 101; - pub const ReportLatency: BlockNumber = 1000; -} - -impl pallet_finality_tracker::Trait for Runtime { - type OnFinalizationStalled = (); - type WindowSize = WindowSize; - type ReportLatency = ReportLatency; -} - parameter_types! { pub const BasicDeposit: Balance = 10 * DOLLARS; // 258 bytes on-chain pub const FieldDeposit: Balance = 250 * CENTS; // 66 bytes on-chain @@ -927,7 +916,6 @@ construct_runtime!( TechnicalCommittee: pallet_collective::::{Module, Call, Storage, Origin, Event, Config}, Elections: pallet_elections_phragmen::{Module, Call, Storage, Event, Config}, TechnicalMembership: pallet_membership::::{Module, Call, Storage, Event, Config}, - FinalityTracker: pallet_finality_tracker::{Module, Call, Inherent}, Grandpa: pallet_grandpa::{Module, Call, Storage, Config, Event, ValidateUnsigned}, Treasury: pallet_treasury::{Module, Call, Storage, Config, Event}, Contracts: pallet_contracts::{Module, Call, Config, Storage, Event}, diff --git a/bin/node/testing/Cargo.toml b/bin/node/testing/Cargo.toml index 3b541b696815b..bc1f07645eed9 100644 --- a/bin/node/testing/Cargo.toml +++ b/bin/node/testing/Cargo.toml @@ -40,7 +40,6 @@ pallet-timestamp = { version = "2.0.0", path = "../../../frame/timestamp" } pallet-transaction-payment = { version = "2.0.0", path = "../../../frame/transaction-payment" } pallet-treasury = { version = "2.0.0", path = "../../../frame/treasury" } sp-api = { version = "2.0.0", path = "../../../primitives/api" } -sp-finality-tracker = { version = "2.0.0", default-features = false, path = "../../../primitives/finality-tracker" } sp-timestamp = { version = "2.0.0", default-features = false, path = "../../../primitives/timestamp" } sp-block-builder = { version = "2.0.0", path = "../../../primitives/block-builder" } sc-block-builder = { version = "0.8.0", path = "../../../client/block-builder" } diff --git a/bin/node/testing/src/bench.rs b/bin/node/testing/src/bench.rs index 07bf2bf57abd1..754552fe4f174 100644 --- a/bin/node/testing/src/bench.rs +++ b/bin/node/testing/src/bench.rs @@ -431,10 +431,9 @@ impl BenchDb { let mut inherent_data = InherentData::new(); let timestamp = 1 * MinimumPeriod::get(); - inherent_data.put_data(sp_timestamp::INHERENT_IDENTIFIER, ×tamp) + inherent_data + .put_data(sp_timestamp::INHERENT_IDENTIFIER, ×tamp) .expect("Put timestamp failed"); - inherent_data.put_data(sp_finality_tracker::INHERENT_IDENTIFIER, &0) - .expect("Put finality tracker failed"); client.runtime_api() .inherent_extrinsics_with_context( diff --git a/client/finality-grandpa/Cargo.toml b/client/finality-grandpa/Cargo.toml index b36d9a7cda70f..8966f5e8f657a 100644 --- a/client/finality-grandpa/Cargo.toml +++ b/client/finality-grandpa/Cargo.toml @@ -40,7 +40,6 @@ sp-inherents = { version = "2.0.0", path = "../../primitives/inherents" } sp-blockchain = { version = "2.0.0", path = "../../primitives/blockchain" } sc-network = { version = "0.8.0", path = "../network" } sc-network-gossip = { version = "0.8.0", path = "../network-gossip" } -sp-finality-tracker = { version = "2.0.0", path = "../../primitives/finality-tracker" } sp-finality-grandpa = { version = "2.0.0", path = "../../primitives/finality-grandpa" } prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../utils/prometheus", version = "0.8.0"} sc-block-builder = { version = "0.8.0", path = "../block-builder" } diff --git a/client/finality-grandpa/src/environment.rs b/client/finality-grandpa/src/environment.rs index 9215dcb323516..aeb1cbca67d76 100644 --- a/client/finality-grandpa/src/environment.rs +++ b/client/finality-grandpa/src/environment.rs @@ -1157,9 +1157,9 @@ where let status = client.info(); if number <= status.finalized_number && client.hash(number)? == Some(hash) { - // This can happen after a forced change (triggered by the finality tracker when finality is stalled), since - // the voter will be restarted at the median last finalized block, which can be lower than the local best - // finalized block. + // This can happen after a forced change (triggered manually from the runtime when + // finality is stalled), since the voter will be restarted at the median last finalized + // block, which can be lower than the local best finalized block. warn!(target: "afg", "Re-finalized block #{:?} ({:?}) in the canonical chain, current best finalized is #{:?}", hash, number, diff --git a/client/finality-grandpa/src/lib.rs b/client/finality-grandpa/src/lib.rs index 753fa5310d62e..23ad993b98ef6 100644 --- a/client/finality-grandpa/src/lib.rs +++ b/client/finality-grandpa/src/lib.rs @@ -72,7 +72,6 @@ use sp_api::ProvideRuntimeApi; use sp_blockchain::{HeaderBackend, Error as ClientError, HeaderMetadata}; use sp_runtime::generic::BlockId; use sp_runtime::traits::{NumberFor, Block as BlockT, DigestFor, Zero}; -use sp_inherents::InherentDataProviders; use sp_consensus::{SelectChain, BlockImport}; use sp_core::{ crypto::Public, @@ -650,33 +649,6 @@ fn global_communication( (global_in, global_out) } -/// Register the finality tracker inherent data provider (which is used by -/// GRANDPA), if not registered already. -fn register_finality_tracker_inherent_data_provider( - client: Arc, - inherent_data_providers: &InherentDataProviders, -) -> Result<(), sp_consensus::Error> where - Client: HeaderBackend + 'static, -{ - if !inherent_data_providers.has_provider(&sp_finality_tracker::INHERENT_IDENTIFIER) { - inherent_data_providers - .register_provider(sp_finality_tracker::InherentDataProvider::new(move || { - #[allow(deprecated)] - { - let info = client.info(); - telemetry!(CONSENSUS_INFO; "afg.finalized"; - "finalized_number" => ?info.finalized_number, - "finalized_hash" => ?info.finalized_hash, - ); - Ok(info.finalized_number) - } - })) - .map_err(|err| sp_consensus::Error::InherentData(err)) - } else { - Ok(()) - } -} - /// Parameters used to run Grandpa. pub struct GrandpaParams { /// Configuration for the GRANDPA service. @@ -685,8 +657,6 @@ pub struct GrandpaParams { pub link: LinkHalf, /// The Network instance. pub network: N, - /// The inherent data providers. - pub inherent_data_providers: InherentDataProviders, /// If supplied, can be used to hook on telemetry connection established events. pub telemetry_on_connect: Option>, /// A voting rule used to potentially restrict target votes. @@ -716,7 +686,6 @@ pub fn run_grandpa_voter( mut config, link, network, - inherent_data_providers, telemetry_on_connect, voting_rule, prometheus_registry, @@ -745,8 +714,6 @@ pub fn run_grandpa_voter( prometheus_registry.as_ref(), ); - register_finality_tracker_inherent_data_provider(client.clone(), &inherent_data_providers)?; - let conf = config.clone(); let telemetry_task = if let Some(telemetry_on_connect) = telemetry_on_connect { let authorities = persistent_data.authority_set.clone(); @@ -1096,19 +1063,10 @@ where /// discards all GRANDPA messages (otherwise, we end up banning nodes that send /// us a `Neighbor` message, since there is no registered gossip validator for /// the engine id defined in the message.) -pub fn setup_disabled_grandpa( - client: Arc, - inherent_data_providers: &InherentDataProviders, - network: N, -) -> Result<(), sp_consensus::Error> where +pub fn setup_disabled_grandpa(network: N) -> Result<(), sp_consensus::Error> +where N: NetworkT + Send + Clone + 'static, - Client: HeaderBackend + 'static, { - register_finality_tracker_inherent_data_provider( - client, - inherent_data_providers, - )?; - // We register the GRANDPA protocol so that we don't consider it an anomaly // to receive GRANDPA messages on the network. We don't process the // messages. diff --git a/client/finality-grandpa/src/tests.rs b/client/finality-grandpa/src/tests.rs index 83f1c498a1951..c9d9f717cdcec 100644 --- a/client/finality-grandpa/src/tests.rs +++ b/client/finality-grandpa/src/tests.rs @@ -371,7 +371,6 @@ fn run_to_completion_with( }, link: link, network: net_service, - inherent_data_providers: InherentDataProviders::new(), telemetry_on_connect: None, voting_rule: (), prometheus_registry: None, @@ -503,7 +502,6 @@ fn finalize_3_voters_1_full_observer() { }, link: link, network: net_service, - inherent_data_providers: InherentDataProviders::new(), telemetry_on_connect: None, voting_rule: (), prometheus_registry: None, @@ -667,7 +665,6 @@ fn transition_3_voters_twice_1_full_observer() { }, link: link, network: net_service, - inherent_data_providers: InherentDataProviders::new(), telemetry_on_connect: None, voting_rule: (), prometheus_registry: None, @@ -1092,7 +1089,6 @@ fn voter_persists_its_votes() { }, link, network: this.net.lock().peers[0].network_service().clone(), - inherent_data_providers: InherentDataProviders::new(), telemetry_on_connect: None, voting_rule: VotingRulesBuilder::default().build(), prometheus_registry: None, @@ -1438,7 +1434,6 @@ fn voter_catches_up_to_latest_round_when_behind() { }, link, network: net.lock().peer(peer_id).network_service().clone(), - inherent_data_providers: InherentDataProviders::new(), telemetry_on_connect: None, voting_rule: (), prometheus_registry: None, diff --git a/frame/finality-tracker/Cargo.toml b/frame/finality-tracker/Cargo.toml deleted file mode 100644 index b8597acc3bc07..0000000000000 --- a/frame/finality-tracker/Cargo.toml +++ /dev/null @@ -1,43 +0,0 @@ -[package] -name = "pallet-finality-tracker" -version = "2.0.0" -authors = ["Parity Technologies "] -edition = "2018" -license = "Apache-2.0" -homepage = "https://substrate.dev" -repository = "https://github.com/paritytech/substrate/" -description = "FRAME Pallet that tracks the last finalized block, as perceived by block authors." -documentation = "https://docs.rs/pallet-finality-tracker" -readme = "README.md" - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] - - -[dependencies] -serde = { version = "1.0.101", default-features = false, features = ["derive"] } -codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false } -sp-inherents = { version = "2.0.0", default-features = false, path = "../../primitives/inherents" } -sp-std = { version = "2.0.0", default-features = false, path = "../../primitives/std" } -sp-runtime = { version = "2.0.0", default-features = false, path = "../../primitives/runtime" } -sp-finality-tracker = { version = "2.0.0", default-features = false, path = "../../primitives/finality-tracker" } -frame-support = { version = "2.0.0", default-features = false, path = "../support" } -frame-system = { version = "2.0.0", default-features = false, path = "../system" } -impl-trait-for-tuples = "0.1.3" - -[dev-dependencies] -sp-core = { version = "2.0.0", default-features = false, path = "../../primitives/core" } -sp-io = { version = "2.0.0", default-features = false, path = "../../primitives/io" } - -[features] -default = ["std"] -std = [ - "serde/std", - "codec/std", - "sp-std/std", - "frame-support/std", - "sp-runtime/std", - "frame-system/std", - "sp-finality-tracker/std", - "sp-inherents/std", -] diff --git a/frame/finality-tracker/README.md b/frame/finality-tracker/README.md deleted file mode 100644 index bf42605ffc6f9..0000000000000 --- a/frame/finality-tracker/README.md +++ /dev/null @@ -1,3 +0,0 @@ -FRAME Pallet that tracks the last finalized block, as perceived by block authors. - -License: Apache-2.0 \ No newline at end of file diff --git a/frame/finality-tracker/src/lib.rs b/frame/finality-tracker/src/lib.rs deleted file mode 100644 index 3b38c4c20033f..0000000000000 --- a/frame/finality-tracker/src/lib.rs +++ /dev/null @@ -1,352 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) 2019-2020 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. - -//! FRAME Pallet that tracks the last finalized block, as perceived by block authors. - -#![cfg_attr(not(feature = "std"), no_std)] - -use sp_inherents::{InherentIdentifier, ProvideInherent, InherentData, MakeFatalError}; -use sp_runtime::traits::{One, Zero, SaturatedConversion}; -use sp_std::{prelude::*, result, cmp, vec}; -use frame_support::{decl_module, decl_storage, decl_error, ensure}; -use frame_support::traits::Get; -use frame_support::weights::{DispatchClass}; -use frame_system::{ensure_none, Trait as SystemTrait}; -use sp_finality_tracker::{INHERENT_IDENTIFIER, FinalizedInherentData}; - -pub const DEFAULT_WINDOW_SIZE: u32 = 101; -pub const DEFAULT_REPORT_LATENCY: u32 = 1000; - -pub trait Trait: SystemTrait { - /// Something which can be notified when the timestamp is set. Set this to `()` - /// if not needed. - type OnFinalizationStalled: OnFinalizationStalled; - /// The number of recent samples to keep from this chain. Default is 101. - type WindowSize: Get; - /// The delay after which point things become suspicious. Default is 1000. - type ReportLatency: Get; -} - -decl_storage! { - trait Store for Module as FinalityTracker { - /// Recent hints. - RecentHints get(fn recent_hints) build(|_| vec![T::BlockNumber::zero()]): Vec; - /// Ordered recent hints. - OrderedHints get(fn ordered_hints) build(|_| vec![T::BlockNumber::zero()]): Vec; - /// The median. - Median get(fn median) build(|_| T::BlockNumber::zero()): T::BlockNumber; - - /// Final hint to apply in the block. `None` means "same as parent". - Update: Option; - - // when initialized through config this is set in the beginning. - Initialized get(fn initialized) build(|_| false): bool; - } -} - -decl_error! { - pub enum Error for Module { - /// Final hint must be updated only once in the block - AlreadyUpdated, - /// Finalized height above block number - BadHint, - } -} - -decl_module! { - pub struct Module for enum Call where origin: T::Origin { - type Error = Error; - /// The number of recent samples to keep from this chain. Default is 101. - const WindowSize: T::BlockNumber = T::WindowSize::get(); - - /// The delay after which point things become suspicious. Default is 1000. - const ReportLatency: T::BlockNumber = T::ReportLatency::get(); - - /// Hint that the author of this block thinks the best finalized - /// block is the given number. - #[weight = (0, DispatchClass::Mandatory)] - fn final_hint(origin, #[compact] hint: T::BlockNumber) { - ensure_none(origin)?; - ensure!(!::Update::exists(), Error::::AlreadyUpdated); - ensure!( - frame_system::Module::::block_number() >= hint, - Error::::BadHint, - ); - ::Update::put(hint); - } - - fn on_finalize() { - Self::update_hint(::Update::take()) - } - } -} - -impl Module { - fn update_hint(hint: Option) { - if !Self::initialized() { - ::RecentHints::put(vec![T::BlockNumber::zero()]); - ::OrderedHints::put(vec![T::BlockNumber::zero()]); - ::Median::put(T::BlockNumber::zero()); - - ::Initialized::put(true); - } - - let mut recent = Self::recent_hints(); - let mut ordered = Self::ordered_hints(); - let window_size = cmp::max(T::BlockNumber::one(), T::WindowSize::get()); - - let hint = hint.unwrap_or_else(|| recent.last() - .expect("always at least one recent sample; qed").clone() - ); - - // prune off the front of the list -- typically 1 except for when - // the sample size has just been shrunk. - { - // take into account the item we haven't pushed yet. - let to_prune = (recent.len() + 1).saturating_sub(window_size.saturated_into::()); - - for drained in recent.drain(..to_prune) { - let idx = ordered.binary_search(&drained) - .expect("recent and ordered contain the same items; qed"); - - ordered.remove(idx); - } - } - - // find the position in the ordered list where the new item goes. - let ordered_idx = ordered.binary_search(&hint) - .unwrap_or_else(|idx| idx); - - ordered.insert(ordered_idx, hint); - recent.push(hint); - - let two = T::BlockNumber::one() + T::BlockNumber::one(); - - let median = { - let len = ordered.len(); - assert!(len > 0, "pruning dictated by window_size which is always saturated at 1; qed"); - - if len % 2 == 0 { - let a = ordered[len / 2]; - let b = ordered[(len / 2) - 1]; - - // compute average. - (a + b) / two - } else { - ordered[len / 2] - } - }; - - let our_window_size = recent.len() as u32; - - ::RecentHints::put(recent); - ::OrderedHints::put(ordered); - ::Median::put(median); - - if T::BlockNumber::from(our_window_size) == window_size { - let now = frame_system::Module::::block_number(); - let latency = T::ReportLatency::get(); - - // the delay is the latency plus half the window size. - let delay = latency + (window_size / two); - // median may be at most n - delay - if median + delay <= now { - T::OnFinalizationStalled::on_stalled(window_size - T::BlockNumber::one(), median); - } - } - } -} - -/// Called when finalization stalled at a given number. -#[impl_trait_for_tuples::impl_for_tuples(30)] -pub trait OnFinalizationStalled { - /// The parameter here is how many more blocks to wait before applying - /// changes triggered by finality stalling. - fn on_stalled(further_wait: N, median: N); -} - -impl ProvideInherent for Module { - type Call = Call; - type Error = MakeFatalError<()>; - const INHERENT_IDENTIFIER: InherentIdentifier = INHERENT_IDENTIFIER; - - fn create_inherent(data: &InherentData) -> Option { - if let Ok(final_num) = data.finalized_number() { - // make hint only when not same as last to avoid bloat. - Self::recent_hints().last().and_then(|last| if last == &final_num { - None - } else { - Some(Call::final_hint(final_num)) - }) - } else { - None - } - } - - fn check_inherent(_call: &Self::Call, _data: &InherentData) -> result::Result<(), Self::Error> { - Ok(()) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - use sp_io::TestExternalities; - use sp_core::H256; - use sp_runtime::{ - testing::Header, - traits::{BlakeTwo256, IdentityLookup}, - Perbill, - }; - use frame_support::{ - assert_ok, impl_outer_origin, parameter_types, - weights::Weight, - traits::OnFinalize, - }; - use frame_system as system; - use std::cell::RefCell; - - #[derive(Clone, PartialEq, Debug)] - pub struct StallEvent { - at: u64, - further_wait: u64, - } - - #[derive(Clone, Eq, PartialEq)] - pub struct Test; - - impl_outer_origin! { - pub enum Origin for Test where system = frame_system {} - } - - thread_local! { - static NOTIFICATIONS: RefCell> = Default::default(); - } - - pub struct StallTracker; - impl OnFinalizationStalled for StallTracker { - fn on_stalled(further_wait: u64, _median: u64) { - let now = System::block_number(); - NOTIFICATIONS.with(|v| v.borrow_mut().push(StallEvent { at: now, further_wait })); - } - } - - parameter_types! { - pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: Weight = 1024; - pub const MaximumBlockLength: u32 = 2 * 1024; - pub const AvailableBlockRatio: Perbill = Perbill::one(); - } - impl system::Trait for Test { - type BaseCallFilter = (); - type Origin = Origin; - type Index = u64; - type BlockNumber = u64; - type Call = (); - type Hash = H256; - type Hashing = BlakeTwo256; - type AccountId = u64; - type Lookup = IdentityLookup; - type Header = Header; - type Event = (); - type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; - type DbWeight = (); - type BlockExecutionWeight = (); - type ExtrinsicBaseWeight = (); - type MaximumExtrinsicWeight = MaximumBlockWeight; - type AvailableBlockRatio = AvailableBlockRatio; - type MaximumBlockLength = MaximumBlockLength; - type Version = (); - type PalletInfo = (); - type AccountData = (); - type OnNewAccount = (); - type OnKilledAccount = (); - type SystemWeightInfo = (); - } - parameter_types! { - pub const WindowSize: u64 = 11; - pub const ReportLatency: u64 = 100; - } - impl Trait for Test { - type OnFinalizationStalled = StallTracker; - type WindowSize = WindowSize; - type ReportLatency = ReportLatency; - } - - type System = system::Module; - type FinalityTracker = Module; - - #[test] - fn median_works() { - let t = system::GenesisConfig::default().build_storage::().unwrap(); - TestExternalities::new(t).execute_with(|| { - FinalityTracker::update_hint(Some(500)); - assert_eq!(FinalityTracker::median(), 250); - assert!(NOTIFICATIONS.with(|n| n.borrow().is_empty())); - }); - } - - #[test] - fn notifies_when_stalled() { - let t = system::GenesisConfig::default().build_storage::().unwrap(); - TestExternalities::new(t).execute_with(|| { - let mut parent_hash = System::parent_hash(); - for i in 2..106 { - System::initialize( - &i, - &parent_hash, - &Default::default(), - &Default::default(), - Default::default() - ); - FinalityTracker::on_finalize(i); - let hdr = System::finalize(); - parent_hash = hdr.hash(); - } - - assert_eq!( - NOTIFICATIONS.with(|n| n.borrow().clone()), - vec![StallEvent { at: 105, further_wait: 10 }] - ) - }); - } - - #[test] - fn recent_notifications_prevent_stalling() { - let t = system::GenesisConfig::default().build_storage::().unwrap(); - TestExternalities::new(t).execute_with(|| { - let mut parent_hash = System::parent_hash(); - for i in 2..106 { - System::initialize( - &i, - &parent_hash, - &Default::default(), - &Default::default(), - Default::default(), - ); - assert_ok!(FinalityTracker::final_hint(Origin::none(), i - 1)); - FinalityTracker::on_finalize(i); - let hdr = System::finalize(); - parent_hash = hdr.hash(); - } - - assert!(NOTIFICATIONS.with(|n| n.borrow().is_empty())); - }); - } -} diff --git a/frame/grandpa/Cargo.toml b/frame/grandpa/Cargo.toml index 6147458b0dbd7..6cde1061df87c 100644 --- a/frame/grandpa/Cargo.toml +++ b/frame/grandpa/Cargo.toml @@ -27,7 +27,6 @@ frame-support = { version = "2.0.0", default-features = false, path = "../suppor frame-system = { version = "2.0.0", default-features = false, path = "../system" } pallet-authorship = { version = "2.0.0", default-features = false, path = "../authorship" } pallet-session = { version = "2.0.0", default-features = false, path = "../session" } -pallet-finality-tracker = { version = "2.0.0", default-features = false, path = "../finality-tracker" } [dev-dependencies] frame-benchmarking = { version = "2.0.0", path = "../benchmarking" } @@ -57,6 +56,5 @@ std = [ "frame-system/std", "pallet-authorship/std", "pallet-session/std", - "pallet-finality-tracker/std", ] runtime-benchmarks = ["frame-benchmarking"] diff --git a/frame/grandpa/src/lib.rs b/frame/grandpa/src/lib.rs index 9a592ab9266f1..d4612e1760057 100644 --- a/frame/grandpa/src/lib.rs +++ b/frame/grandpa/src/lib.rs @@ -44,7 +44,6 @@ use frame_support::{ storage, traits::KeyOwnerProofSystem, weights::{Pays, Weight}, Parameter, }; use frame_system::{ensure_none, ensure_root, ensure_signed}; -use pallet_finality_tracker::OnFinalizationStalled; use sp_runtime::{ generic::DigestItem, traits::Zero, @@ -575,6 +574,13 @@ impl Module { ) .ok() } + + fn on_stalled(further_wait: T::BlockNumber, median: T::BlockNumber) { + // when we record old authority sets we could try to figure out _who_ + // failed. until then, we can't meaningfully guard against + // `next == last` the way that normal session changes do. + >::put((further_wait, median)); + } } impl sp_runtime::BoundToRuntimeAppPublic for Module { @@ -635,12 +641,3 @@ impl pallet_session::OneSessionHandler for Module Self::deposit_log(ConsensusLog::OnDisabled(i as u64)) } } - -impl OnFinalizationStalled for Module { - fn on_stalled(further_wait: T::BlockNumber, median: T::BlockNumber) { - // when we record old authority sets, we can use `pallet_finality_tracker::median` - // to figure out _who_ failed. until then, we can't meaningfully guard - // against `next == last` the way that normal session changes do. - >::put((further_wait, median)); - } -} diff --git a/primitives/finality-tracker/Cargo.toml b/primitives/finality-tracker/Cargo.toml deleted file mode 100644 index 756b6d91e296e..0000000000000 --- a/primitives/finality-tracker/Cargo.toml +++ /dev/null @@ -1,26 +0,0 @@ -[package] -name = "sp-finality-tracker" -version = "2.0.0" -authors = ["Parity Technologies "] -edition = "2018" -license = "Apache-2.0" -homepage = "https://substrate.dev" -repository = "https://github.com/paritytech/substrate/" -description = "FRAME module that tracks the last finalized block, as perceived by block authors." -readme = "README.md" - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] - -[dependencies] -codec = { package = "parity-scale-codec", version = "1.3.1", default-features = false } -sp-inherents = { version = "2.0.0", default-features = false, path = "../../primitives/inherents" } -sp-std = { version = "2.0.0", default-features = false, path = "../../primitives/std" } - -[features] -default = ["std"] -std = [ - "codec/std", - "sp-std/std", - "sp-inherents/std", -] diff --git a/primitives/finality-tracker/README.md b/primitives/finality-tracker/README.md deleted file mode 100644 index f9778e38a2bce..0000000000000 --- a/primitives/finality-tracker/README.md +++ /dev/null @@ -1,3 +0,0 @@ -FRAME module that tracks the last finalized block, as perceived by block authors. - -License: Apache-2.0 \ No newline at end of file diff --git a/primitives/finality-tracker/src/lib.rs b/primitives/finality-tracker/src/lib.rs deleted file mode 100644 index fea4003905606..0000000000000 --- a/primitives/finality-tracker/src/lib.rs +++ /dev/null @@ -1,77 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) 2019-2020 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. - -//! FRAME module that tracks the last finalized block, as perceived by block authors. - -#![cfg_attr(not(feature = "std"), no_std)] - -use sp_inherents::{InherentIdentifier, InherentData, Error}; -use codec::Decode; - -#[cfg(feature = "std")] -use codec::Encode; - -/// The identifier for the `finalnum` inherent. -pub const INHERENT_IDENTIFIER: InherentIdentifier = *b"finalnum"; - -/// Auxiliary trait to extract finalized inherent data. -pub trait FinalizedInherentData { - /// Get finalized inherent data. - fn finalized_number(&self) -> Result; -} - -impl FinalizedInherentData for InherentData { - fn finalized_number(&self) -> Result { - self.get_data(&INHERENT_IDENTIFIER) - .and_then(|r| r.ok_or_else(|| "Finalized number inherent data not found".into())) - } -} - -/// Provider for inherent data. -#[cfg(feature = "std")] -pub struct InherentDataProvider { - inner: F, - _marker: std::marker::PhantomData, -} - -#[cfg(feature = "std")] -impl InherentDataProvider { - pub fn new(final_oracle: F) -> Self { - InherentDataProvider { inner: final_oracle, _marker: Default::default() } - } -} - -#[cfg(feature = "std")] -impl sp_inherents::ProvideInherentData for InherentDataProvider - where F: Fn() -> Result -{ - fn inherent_identifier(&self) -> &'static InherentIdentifier { - &INHERENT_IDENTIFIER - } - - fn provide_inherent_data( - &self, - inherent_data: &mut InherentData, - ) -> Result<(), Error> { - (self.inner)() - .and_then(|n| inherent_data.put_data(INHERENT_IDENTIFIER, &n)) - } - - fn error_to_string(&self, _error: &[u8]) -> Option { - Some(format!("no further information")) - } -}