From 2bd187f85b57ccbcddc1041dacea4be80a901edd Mon Sep 17 00:00:00 2001 From: Andrei Eres Date: Tue, 23 Jul 2024 15:49:54 +0200 Subject: [PATCH 01/27] [subsystem-bench] Adjust approval-voting-regression-bench (#5115) Fixes https://github.com/paritytech/polkadot-sdk/issues/5081 After last changes in approval subsystem and their benchmarks base values need to be updated --- .../benches/approval-voting-regression-bench.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/polkadot/node/core/approval-voting/benches/approval-voting-regression-bench.rs b/polkadot/node/core/approval-voting/benches/approval-voting-regression-bench.rs index 687063dd0eb3..a18e667253d0 100644 --- a/polkadot/node/core/approval-voting/benches/approval-voting-regression-bench.rs +++ b/polkadot/node/core/approval-voting/benches/approval-voting-regression-bench.rs @@ -77,12 +77,12 @@ fn main() -> Result<(), String> { // We expect no variance for received and sent // but use 0.001 because we operate with floats messages.extend(average_usage.check_network_usage(&[ - ("Received from peers", 52942.4600, 0.001), - ("Sent to peers", 63547.0330, 0.001), + ("Received from peers", 52941.6071, 0.001), + ("Sent to peers", 63810.1859, 0.001), ])); messages.extend(average_usage.check_cpu_usage(&[ - ("approval-distribution", 7.4075, 0.1), - ("approval-voting", 9.9873, 0.1), + ("approval-distribution", 6.3912, 0.1), + ("approval-voting", 10.0578, 0.1), ])); if messages.is_empty() { From 6d0926e239776a509586f2030fa5b5d9c6aac965 Mon Sep 17 00:00:00 2001 From: Muharem Date: Tue, 23 Jul 2024 15:53:10 +0200 Subject: [PATCH 02/27] Make `on_unbalanceds` work with `fungibles` `imbalances` (#4564) Make `on_unbalanceds` work with `fungibles` `imbalances`. The `fungibles` `imbalances` cannot be handled by the default implementation of `on_unbalanceds` from the `OnUnbalanced` trait. This is because the `fungibles` `imbalances` types do not implement the `Imbalance` trait (and cannot with its current semantics). The `on_unbalanceds` function requires only the `merge` function for the imbalance type. In this PR, we provide the `TryMerge` trait, which can be implemented by all imbalance types and make `OnUnbalanced` require it instead `Imbalance`. ### Migration for `OnUnbalanced` trait implementations: In case if you have a custom implementation of `on_unbalanceds` trait function, remove it's `` type argument. ### Migration for custom imbalance types: If you have your own imbalance types implementations, implement the `TryMerge` trait for it introduced with this update. The applicability of the `on_unbalanceds` function to fungibles imbalances is useful in cases like - [link](https://github.com/paritytech/polkadot-sdk/blob/3a8e675e9f6f283514c00c14d3d1d90ed5bf59c0/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/payment.rs#L267) from https://github.com/paritytech/polkadot-sdk/pull/4488. --------- Co-authored-by: Oliver Tale-Yazdi --- cumulus/parachains/common/src/impls.rs | 2 +- polkadot/runtime/common/src/impls.rs | 2 +- prdoc/pr_4564.prdoc | 32 +++++++++++++++++++ substrate/bin/node/runtime/src/lib.rs | 2 +- substrate/frame/balances/src/impl_currency.rs | 14 +++++++- .../src/traits/tokens/fungible/imbalance.rs | 10 +++++- .../src/traits/tokens/fungibles/imbalance.rs | 17 +++++++++- .../support/src/traits/tokens/imbalance.rs | 16 +++++++++- .../traits/tokens/imbalance/on_unbalanced.rs | 21 ++++++++++-- .../asset-conversion-tx-payment/src/mock.rs | 2 +- .../frame/transaction-payment/src/mock.rs | 2 +- 11 files changed, 108 insertions(+), 12 deletions(-) create mode 100644 prdoc/pr_4564.prdoc diff --git a/cumulus/parachains/common/src/impls.rs b/cumulus/parachains/common/src/impls.rs index 42ea50c75a8d..c1797c0a7513 100644 --- a/cumulus/parachains/common/src/impls.rs +++ b/cumulus/parachains/common/src/impls.rs @@ -67,7 +67,7 @@ where AccountIdOf: From + Into, ::RuntimeEvent: From>, { - fn on_unbalanceds( + fn on_unbalanceds( mut fees_then_tips: impl Iterator< Item = fungible::Credit>, >, diff --git a/polkadot/runtime/common/src/impls.rs b/polkadot/runtime/common/src/impls.rs index 7fdff814a2d5..b6a93cf53685 100644 --- a/polkadot/runtime/common/src/impls.rs +++ b/polkadot/runtime/common/src/impls.rs @@ -51,7 +51,7 @@ where ::AccountId: From, ::AccountId: Into, { - fn on_unbalanceds( + fn on_unbalanceds( mut fees_then_tips: impl Iterator>>, ) { if let Some(fees) = fees_then_tips.next() { diff --git a/prdoc/pr_4564.prdoc b/prdoc/pr_4564.prdoc new file mode 100644 index 000000000000..896e49ee6b9f --- /dev/null +++ b/prdoc/pr_4564.prdoc @@ -0,0 +1,32 @@ +title: "Make `OnUnbalanced::on_unbalanceds` work with `fungibles` `imbalances`" + +doc: + - audience: Runtime Dev + description: | + The `on_unbalanceds` function of `OnUnbalanced` trait accepts the `fungibles` `imbalances` + imbalances. This is done by replacing the `Imbalance` trait bound on imbalance type with + the `TryMerge` trait bound. The `TryMerge` trait is implemented for all imbalance types. + + ### Migration for `OnUnbalanced` trait implementations: + In case if you have a custom implementation of `on_unbalanceds` trait function, remove + it's `` type argument. + + ### Migration for custom imbalance types: + If you have your own imbalance types implementations, implement the `TryMerge` trait for it + introduced with this update. + +crates: + - name: frame-support + bump: major + - name: pallet-balances + bump: minor + - name: pallet-asset-conversion-tx-payment + bump: patch + - name: pallet-transaction-payment + bump: patch + - name: kitchensink-runtime + bump: patch + - name: polkadot-runtime-common + bump: patch + - name: parachains-common + bump: minor diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs index 78c7bba64579..997213447262 100644 --- a/substrate/bin/node/runtime/src/lib.rs +++ b/substrate/bin/node/runtime/src/lib.rs @@ -189,7 +189,7 @@ type NegativeImbalance = >::NegativeImbalance; pub struct DealWithFees; impl OnUnbalanced for DealWithFees { - fn on_unbalanceds(mut fees_then_tips: impl Iterator) { + fn on_unbalanceds(mut fees_then_tips: impl Iterator) { if let Some(fees) = fees_then_tips.next() { // for fees, 80% to treasury, 20% to author let mut split = fees.ration(80, 20); diff --git a/substrate/frame/balances/src/impl_currency.rs b/substrate/frame/balances/src/impl_currency.rs index 049f0cc626c2..23feb46b72ca 100644 --- a/substrate/frame/balances/src/impl_currency.rs +++ b/substrate/frame/balances/src/impl_currency.rs @@ -41,7 +41,7 @@ use sp_runtime::traits::Bounded; mod imbalances { use super::*; use core::mem; - use frame_support::traits::SameOrOther; + use frame_support::traits::{tokens::imbalance::TryMerge, SameOrOther}; /// Opaque, move-only struct with private fields that serves as a token denoting that /// funds have been created without any equal and opposite accounting. @@ -133,6 +133,12 @@ mod imbalances { } } + impl, I: 'static> TryMerge for PositiveImbalance { + fn try_merge(self, other: Self) -> Result { + Ok(self.merge(other)) + } + } + impl, I: 'static> TryDrop for NegativeImbalance { fn try_drop(self) -> result::Result<(), Self> { self.drop_zero() @@ -197,6 +203,12 @@ mod imbalances { } } + impl, I: 'static> TryMerge for NegativeImbalance { + fn try_merge(self, other: Self) -> Result { + Ok(self.merge(other)) + } + } + impl, I: 'static> Drop for PositiveImbalance { /// Basic drop handler will just square up the total issuance. fn drop(&mut self) { diff --git a/substrate/frame/support/src/traits/tokens/fungible/imbalance.rs b/substrate/frame/support/src/traits/tokens/fungible/imbalance.rs index 41907b2aa009..a9367d0f164f 100644 --- a/substrate/frame/support/src/traits/tokens/fungible/imbalance.rs +++ b/substrate/frame/support/src/traits/tokens/fungible/imbalance.rs @@ -24,7 +24,7 @@ use super::{super::Imbalance as ImbalanceT, Balanced, *}; use crate::traits::{ fungibles, misc::{SameOrOther, TryDrop}, - tokens::{AssetId, Balance}, + tokens::{imbalance::TryMerge, AssetId, Balance}, }; use core::marker::PhantomData; use frame_support_procedural::{EqNoBound, PartialEqNoBound, RuntimeDebugNoBound}; @@ -157,6 +157,14 @@ impl, OppositeOnDrop: HandleImbalance } } +impl, OppositeOnDrop: HandleImbalanceDrop> TryMerge + for Imbalance +{ + fn try_merge(self, other: Self) -> Result { + Ok(self.merge(other)) + } +} + /// Converts a `fungibles` `imbalance` instance to an instance of a `fungible` imbalance type. /// /// This function facilitates imbalance conversions within the implementations of diff --git a/substrate/frame/support/src/traits/tokens/fungibles/imbalance.rs b/substrate/frame/support/src/traits/tokens/fungibles/imbalance.rs index c3b213cc8fc8..349d9d7c65e8 100644 --- a/substrate/frame/support/src/traits/tokens/fungibles/imbalance.rs +++ b/substrate/frame/support/src/traits/tokens/fungibles/imbalance.rs @@ -24,7 +24,10 @@ use super::*; use crate::traits::{ fungible, misc::{SameOrOther, TryDrop}, - tokens::{imbalance::Imbalance as ImbalanceT, AssetId, Balance}, + tokens::{ + imbalance::{Imbalance as ImbalanceT, TryMerge}, + AssetId, Balance, + }, }; use core::marker::PhantomData; use frame_support_procedural::{EqNoBound, PartialEqNoBound, RuntimeDebugNoBound}; @@ -176,6 +179,18 @@ impl< } } +impl< + A: AssetId, + B: Balance, + OnDrop: HandleImbalanceDrop, + OppositeOnDrop: HandleImbalanceDrop, + > TryMerge for Imbalance +{ + fn try_merge(self, other: Self) -> Result { + self.merge(other) + } +} + /// Converts a `fungible` `imbalance` instance to an instance of a `fungibles` imbalance type using /// a specified `asset`. /// diff --git a/substrate/frame/support/src/traits/tokens/imbalance.rs b/substrate/frame/support/src/traits/tokens/imbalance.rs index 8eb9b355a4cf..ee0d7a81c36e 100644 --- a/substrate/frame/support/src/traits/tokens/imbalance.rs +++ b/substrate/frame/support/src/traits/tokens/imbalance.rs @@ -58,7 +58,7 @@ pub use split_two_ways::SplitTwoWays; /// /// You can always retrieve the raw balance value using `peek`. #[must_use] -pub trait Imbalance: Sized + TryDrop + Default { +pub trait Imbalance: Sized + TryDrop + Default + TryMerge { /// The oppositely imbalanced type. They come in pairs. type Opposite: Imbalance; @@ -182,6 +182,13 @@ pub trait Imbalance: Sized + TryDrop + Default { fn peek(&self) -> Balance; } +/// Try to merge two imbalances. +pub trait TryMerge: Sized { + /// Consume `self` and an `other` to return a new instance that combines both. Errors with + /// Err(self, other) if the imbalances cannot be merged (e.g. imbalances of different assets). + fn try_merge(self, other: Self) -> Result; +} + #[cfg(feature = "std")] impl Imbalance for () { type Opposite = (); @@ -236,3 +243,10 @@ impl Imbalance for () { Default::default() } } + +#[cfg(feature = "std")] +impl TryMerge for () { + fn try_merge(self, _: Self) -> Result { + Ok(()) + } +} diff --git a/substrate/frame/support/src/traits/tokens/imbalance/on_unbalanced.rs b/substrate/frame/support/src/traits/tokens/imbalance/on_unbalanced.rs index 4bf9af3fbb18..461fd203668d 100644 --- a/substrate/frame/support/src/traits/tokens/imbalance/on_unbalanced.rs +++ b/substrate/frame/support/src/traits/tokens/imbalance/on_unbalanced.rs @@ -35,11 +35,26 @@ pub trait OnUnbalanced { /// Handler for some imbalances. The different imbalances might have different origins or /// meanings, dependent on the context. Will default to simply calling on_unbalanced for all /// of them. Infallible. - fn on_unbalanceds(amounts: impl Iterator) + fn on_unbalanceds(mut amounts: impl Iterator) where - Imbalance: crate::traits::Imbalance, + Imbalance: crate::traits::tokens::imbalance::TryMerge, { - Self::on_unbalanced(amounts.fold(Imbalance::zero(), |i, x| x.merge(i))) + let mut sum: Option = None; + while let Some(next) = amounts.next() { + sum = match sum { + Some(sum) => match sum.try_merge(next) { + Ok(sum) => Some(sum), + Err((sum, next)) => { + Self::on_unbalanced(next); + Some(sum) + }, + }, + None => Some(next), + } + } + if let Some(sum) = sum { + Self::on_unbalanced(sum) + } } /// Handler for some imbalance. Infallible. diff --git a/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/mock.rs b/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/mock.rs index 3f8c7bc0ea34..245900760de9 100644 --- a/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/mock.rs +++ b/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/mock.rs @@ -131,7 +131,7 @@ pub struct DealWithFees; impl OnUnbalanced::AccountId, Balances>> for DealWithFees { - fn on_unbalanceds( + fn on_unbalanceds( mut fees_then_tips: impl Iterator< Item = fungible::Credit<::AccountId, Balances>, >, diff --git a/substrate/frame/transaction-payment/src/mock.rs b/substrate/frame/transaction-payment/src/mock.rs index fa61572e9831..8767024ee235 100644 --- a/substrate/frame/transaction-payment/src/mock.rs +++ b/substrate/frame/transaction-payment/src/mock.rs @@ -105,7 +105,7 @@ pub struct DealWithFees; impl OnUnbalanced::AccountId, Balances>> for DealWithFees { - fn on_unbalanceds( + fn on_unbalanceds( mut fees_then_tips: impl Iterator< Item = fungible::Credit<::AccountId, Balances>, >, From 216e8fa126df9ee819d524834e75a82881681e02 Mon Sep 17 00:00:00 2001 From: Serban Iorga Date: Tue, 23 Jul 2024 17:27:42 +0300 Subject: [PATCH 03/27] Beefy equivocation: add runtime API methods (#4993) Related to https://github.com/paritytech/polkadot-sdk/issues/4523 Add runtime API methods for: - generating the ancestry proof - submiting a fork voting report - submitting a future voting report --- polkadot/node/service/src/fake_runtime_api.rs | 25 ++++++++ polkadot/runtime/rococo/src/lib.rs | 38 ++++++++++++- polkadot/runtime/test-runtime/src/lib.rs | 26 +++++++++ polkadot/runtime/westend/src/lib.rs | 38 ++++++++++++- prdoc/pr_4993.prdoc | 27 +++++++++ substrate/bin/node/runtime/src/lib.rs | 38 ++++++++++++- substrate/frame/beefy-mmr/src/lib.rs | 18 ++++++ substrate/frame/beefy/src/lib.rs | 35 +++++++++++- substrate/frame/beefy/src/mock.rs | 7 +++ .../primitives/consensus/beefy/src/lib.rs | 57 ++++++++++++++++++- 10 files changed, 303 insertions(+), 6 deletions(-) create mode 100644 prdoc/pr_4993.prdoc diff --git a/polkadot/node/service/src/fake_runtime_api.rs b/polkadot/node/service/src/fake_runtime_api.rs index e971830c95cb..cdef39d5bdf1 100644 --- a/polkadot/node/service/src/fake_runtime_api.rs +++ b/polkadot/node/service/src/fake_runtime_api.rs @@ -252,12 +252,37 @@ sp_api::impl_runtime_apis! { unimplemented!() } + fn submit_report_fork_voting_unsigned_extrinsic( + _: sp_consensus_beefy::ForkVotingProof< + ::Header, + BeefyId, + sp_runtime::OpaqueValue + >, + _: sp_consensus_beefy::OpaqueKeyOwnershipProof, + ) -> Option<()> { + unimplemented!() + } + + fn submit_report_future_block_voting_unsigned_extrinsic( + _: sp_consensus_beefy::FutureBlockVotingProof, + _: sp_consensus_beefy::OpaqueKeyOwnershipProof, + ) -> Option<()> { + unimplemented!() + } + fn generate_key_ownership_proof( _: sp_consensus_beefy::ValidatorSetId, _: BeefyId, ) -> Option { unimplemented!() } + + fn generate_ancestry_proof( + _: BlockNumber, + _: Option, + ) -> Option { + unimplemented!() + } } impl sp_mmr_primitives::MmrApi for Runtime { diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index 058b9c279f2a..2a1cb58fc17f 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -2054,7 +2054,7 @@ sp_api::impl_runtime_apis! { } } - #[api_version(4)] + #[api_version(5)] impl sp_consensus_beefy::BeefyApi for Runtime { fn beefy_genesis() -> Option { pallet_beefy::GenesisBlock::::get() @@ -2080,6 +2080,31 @@ sp_api::impl_runtime_apis! { ) } + fn submit_report_fork_voting_unsigned_extrinsic( + equivocation_proof: + sp_consensus_beefy::ForkVotingProof< + ::Header, + BeefyId, + sp_runtime::OpaqueValue + >, + key_owner_proof: sp_consensus_beefy::OpaqueKeyOwnershipProof, + ) -> Option<()> { + Beefy::submit_unsigned_fork_voting_report( + equivocation_proof.try_into()?, + key_owner_proof.decode()?, + ) + } + + fn submit_report_future_block_voting_unsigned_extrinsic( + equivocation_proof: sp_consensus_beefy::FutureBlockVotingProof, + key_owner_proof: sp_consensus_beefy::OpaqueKeyOwnershipProof, + ) -> Option<()> { + Beefy::submit_unsigned_future_block_voting_report( + equivocation_proof, + key_owner_proof.decode()?, + ) + } + fn generate_key_ownership_proof( _set_id: sp_consensus_beefy::ValidatorSetId, authority_id: BeefyId, @@ -2090,6 +2115,17 @@ sp_api::impl_runtime_apis! { .map(|p| p.encode()) .map(sp_consensus_beefy::OpaqueKeyOwnershipProof::new) } + + fn generate_ancestry_proof( + prev_block_number: BlockNumber, + best_known_block_number: Option, + ) -> Option { + use sp_consensus_beefy::AncestryHelper; + + MmrLeaf::generate_proof(prev_block_number, best_known_block_number) + .map(|p| p.encode()) + .map(sp_runtime::OpaqueValue::new) + } } #[api_version(2)] diff --git a/polkadot/runtime/test-runtime/src/lib.rs b/polkadot/runtime/test-runtime/src/lib.rs index a8a369a68e66..8e34320d38f2 100644 --- a/polkadot/runtime/test-runtime/src/lib.rs +++ b/polkadot/runtime/test-runtime/src/lib.rs @@ -1029,12 +1029,38 @@ sp_api::impl_runtime_apis! { None } + fn submit_report_fork_voting_unsigned_extrinsic( + _equivocation_proof: + sp_consensus_beefy::ForkVotingProof< + ::Header, + BeefyId, + sp_runtime::OpaqueValue + >, + _key_owner_proof: sp_consensus_beefy::OpaqueKeyOwnershipProof, + ) -> Option<()> { + None + } + + fn submit_report_future_block_voting_unsigned_extrinsic( + _equivocation_proof: sp_consensus_beefy::FutureBlockVotingProof, + _key_owner_proof: sp_consensus_beefy::OpaqueKeyOwnershipProof, + ) -> Option<()> { + None + } + fn generate_key_ownership_proof( _set_id: sp_consensus_beefy::ValidatorSetId, _authority_id: BeefyId, ) -> Option { None } + + fn generate_ancestry_proof( + _prev_block_number: BlockNumber, + _best_known_block_number: Option, + ) -> Option { + None + } } impl mmr::MmrApi for Runtime { diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index 13a69050c342..093476106518 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -2109,7 +2109,7 @@ sp_api::impl_runtime_apis! { } } - #[api_version(4)] + #[api_version(5)] impl sp_consensus_beefy::BeefyApi for Runtime { fn beefy_genesis() -> Option { pallet_beefy::GenesisBlock::::get() @@ -2135,6 +2135,31 @@ sp_api::impl_runtime_apis! { ) } + fn submit_report_fork_voting_unsigned_extrinsic( + equivocation_proof: + sp_consensus_beefy::ForkVotingProof< + ::Header, + BeefyId, + sp_runtime::OpaqueValue + >, + key_owner_proof: sp_consensus_beefy::OpaqueKeyOwnershipProof, + ) -> Option<()> { + Beefy::submit_unsigned_fork_voting_report( + equivocation_proof.try_into()?, + key_owner_proof.decode()?, + ) + } + + fn submit_report_future_block_voting_unsigned_extrinsic( + equivocation_proof: sp_consensus_beefy::FutureBlockVotingProof, + key_owner_proof: sp_consensus_beefy::OpaqueKeyOwnershipProof, + ) -> Option<()> { + Beefy::submit_unsigned_future_block_voting_report( + equivocation_proof, + key_owner_proof.decode()?, + ) + } + fn generate_key_ownership_proof( _set_id: sp_consensus_beefy::ValidatorSetId, authority_id: BeefyId, @@ -2145,6 +2170,17 @@ sp_api::impl_runtime_apis! { .map(|p| p.encode()) .map(sp_consensus_beefy::OpaqueKeyOwnershipProof::new) } + + fn generate_ancestry_proof( + prev_block_number: BlockNumber, + best_known_block_number: Option, + ) -> Option { + use sp_consensus_beefy::AncestryHelper; + + BeefyMmrLeaf::generate_proof(prev_block_number, best_known_block_number) + .map(|p| p.encode()) + .map(sp_runtime::OpaqueValue::new) + } } impl mmr::MmrApi for Runtime { diff --git a/prdoc/pr_4993.prdoc b/prdoc/pr_4993.prdoc new file mode 100644 index 000000000000..d822d5cd6c76 --- /dev/null +++ b/prdoc/pr_4993.prdoc @@ -0,0 +1,27 @@ +# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0 +# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json + +title: Added BEEFY equivocation-related methods to BeefyApi + +doc: + - audience: Node Dev + description: | + This PR adds the `generate_ancestry_proof`, `submit_report_fork_voting_unsigned_extrinsic` and + `submit_report_future_block_voting_unsigned_extrinsic` to `BeefyApi` and bumps the `BeefyApi` version + from 4 to 5. + +crates: + - name: pallet-beefy + bump: minor + - name: pallet-beefy-mmr + bump: minor + - name: kitchensink-runtime + bump: major + - name: rococo-runtime + bump: major + - name: westend-runtime + bump: major + - name: sp-consensus-beefy + bump: minor + - name: polkadot-service + bump: patch diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs index 997213447262..cad2cc119f0d 100644 --- a/substrate/bin/node/runtime/src/lib.rs +++ b/substrate/bin/node/runtime/src/lib.rs @@ -3038,7 +3038,7 @@ impl_runtime_apis! { } } - #[api_version(4)] + #[api_version(5)] impl sp_consensus_beefy::BeefyApi for Runtime { fn beefy_genesis() -> Option { pallet_beefy::GenesisBlock::::get() @@ -3064,6 +3064,31 @@ impl_runtime_apis! { ) } + fn submit_report_fork_voting_unsigned_extrinsic( + equivocation_proof: + sp_consensus_beefy::ForkVotingProof< + ::Header, + BeefyId, + sp_runtime::OpaqueValue + >, + key_owner_proof: sp_consensus_beefy::OpaqueKeyOwnershipProof, + ) -> Option<()> { + Beefy::submit_unsigned_fork_voting_report( + equivocation_proof.try_into()?, + key_owner_proof.decode()?, + ) + } + + fn submit_report_future_block_voting_unsigned_extrinsic( + equivocation_proof: sp_consensus_beefy::FutureBlockVotingProof, + key_owner_proof: sp_consensus_beefy::OpaqueKeyOwnershipProof, + ) -> Option<()> { + Beefy::submit_unsigned_future_block_voting_report( + equivocation_proof, + key_owner_proof.decode()?, + ) + } + fn generate_key_ownership_proof( _set_id: sp_consensus_beefy::ValidatorSetId, authority_id: BeefyId, @@ -3072,6 +3097,17 @@ impl_runtime_apis! { .map(|p| p.encode()) .map(sp_consensus_beefy::OpaqueKeyOwnershipProof::new) } + + fn generate_ancestry_proof( + prev_block_number: BlockNumber, + best_known_block_number: Option, + ) -> Option { + use sp_consensus_beefy::AncestryHelper; + + MmrLeaf::generate_proof(prev_block_number, best_known_block_number) + .map(|p| p.encode()) + .map(sp_runtime::OpaqueValue::new) + } } impl pallet_mmr::primitives::MmrApi< diff --git a/substrate/frame/beefy-mmr/src/lib.rs b/substrate/frame/beefy-mmr/src/lib.rs index ec341cad2084..195bbfbf2f29 100644 --- a/substrate/frame/beefy-mmr/src/lib.rs +++ b/substrate/frame/beefy-mmr/src/lib.rs @@ -183,6 +183,24 @@ where type Proof = AncestryProof>; type ValidationContext = MerkleRootOf; + fn generate_proof( + prev_block_number: BlockNumberFor, + best_known_block_number: Option>, + ) -> Option { + pallet_mmr::Pallet::::generate_ancestry_proof(prev_block_number, best_known_block_number) + .map_err(|e| { + log::error!( + target: "runtime::beefy", + "Failed to generate ancestry proof for block {:?} at {:?}: {:?}", + prev_block_number, + best_known_block_number, + e + ); + e + }) + .ok() + } + fn extract_validation_context(header: HeaderFor) -> Option { // Check if the provided header is canonical. let expected_hash = frame_system::Pallet::::block_hash(header.number()); diff --git a/substrate/frame/beefy/src/lib.rs b/substrate/frame/beefy/src/lib.rs index fd9a0027c6fc..353ba876c7ed 100644 --- a/substrate/frame/beefy/src/lib.rs +++ b/substrate/frame/beefy/src/lib.rs @@ -538,8 +538,8 @@ impl Pallet { ValidatorSet::::new(validators, id) } - /// Submits an extrinsic to report an equivocation. This method will create - /// an unsigned extrinsic with a call to `report_equivocation_unsigned` and + /// Submits an extrinsic to report a double voting equivocation. This method will create + /// an unsigned extrinsic with a call to `report_double_voting_unsigned` and /// will push the transaction to the pool. Only useful in an offchain context. pub fn submit_unsigned_double_voting_report( equivocation_proof: DoubleVotingProof< @@ -556,6 +556,37 @@ impl Pallet { .ok() } + /// Submits an extrinsic to report a fork voting equivocation. This method will create + /// an unsigned extrinsic with a call to `report_fork_voting_unsigned` and + /// will push the transaction to the pool. Only useful in an offchain context. + pub fn submit_unsigned_fork_voting_report( + equivocation_proof: ForkVotingProof< + HeaderFor, + T::BeefyId, + >>::Proof, + >, + key_owner_proof: T::KeyOwnerProof, + ) -> Option<()> { + T::EquivocationReportSystem::publish_evidence(EquivocationEvidenceFor::ForkVotingProof( + equivocation_proof, + key_owner_proof, + )) + .ok() + } + + /// Submits an extrinsic to report a future block voting equivocation. This method will create + /// an unsigned extrinsic with a call to `report_future_block_voting_unsigned` and + /// will push the transaction to the pool. Only useful in an offchain context. + pub fn submit_unsigned_future_block_voting_report( + equivocation_proof: FutureBlockVotingProof, T::BeefyId>, + key_owner_proof: T::KeyOwnerProof, + ) -> Option<()> { + T::EquivocationReportSystem::publish_evidence( + EquivocationEvidenceFor::FutureBlockVotingProof(equivocation_proof, key_owner_proof), + ) + .ok() + } + fn change_authorities( new: BoundedVec, queued: BoundedVec, diff --git a/substrate/frame/beefy/src/mock.rs b/substrate/frame/beefy/src/mock.rs index 03efccff7643..a0880660d051 100644 --- a/substrate/frame/beefy/src/mock.rs +++ b/substrate/frame/beefy/src/mock.rs @@ -111,6 +111,13 @@ impl AncestryHelper
for MockAncestryHelper { type Proof = MockAncestryProof; type ValidationContext = MockAncestryProofContext; + fn generate_proof( + _prev_block_number: Header::Number, + _best_known_block_number: Option, + ) -> Option { + unimplemented!() + } + fn extract_validation_context(_header: Header) -> Option { AncestryProofContext::get() } diff --git a/substrate/primitives/consensus/beefy/src/lib.rs b/substrate/primitives/consensus/beefy/src/lib.rs index 7f6f733d0e39..020e1667cbc7 100644 --- a/substrate/primitives/consensus/beefy/src/lib.rs +++ b/substrate/primitives/consensus/beefy/src/lib.rs @@ -349,6 +349,19 @@ pub struct ForkVotingProof pub header: Header, } +impl ForkVotingProof { + /// Try to decode the `AncestryProof`. + pub fn try_into( + self, + ) -> Option> { + Some(ForkVotingProof:: { + vote: self.vote, + ancestry_proof: self.ancestry_proof.decode()?, + header: self.header, + }) + } +} + /// Proof showing that an authority voted for a future block. #[derive(Clone, Debug, Decode, Encode, PartialEq, TypeInfo)] pub struct FutureBlockVotingProof { @@ -428,6 +441,13 @@ pub trait AncestryHelper { /// The data needed for validating the proof. type ValidationContext; + /// Generates a proof that the `prev_block_number` is part of the canonical chain at + /// `best_known_block_number`. + fn generate_proof( + prev_block_number: Header::Number, + best_known_block_number: Option, + ) -> Option; + /// Extract the validation context from the provided header. fn extract_validation_context(header: Header) -> Option; @@ -450,7 +470,7 @@ pub type OpaqueKeyOwnershipProof = OpaqueValue; sp_api::decl_runtime_apis! { /// API necessary for BEEFY voters. - #[api_version(4)] + #[api_version(5)] pub trait BeefyApi where AuthorityId : Codec + RuntimeAppPublic, { @@ -474,6 +494,34 @@ sp_api::decl_runtime_apis! { key_owner_proof: OpaqueKeyOwnershipProof, ) -> Option<()>; + /// Submits an unsigned extrinsic to report a fork voting equivocation. The caller + /// must provide the fork voting proof (the ancestry proof should be obtained using + /// `generate_ancestry_proof`) and a key ownership proof (should be obtained using + /// `generate_key_ownership_proof`). The extrinsic will be unsigned and should only + /// be accepted for local authorship (not to be broadcast to the network). This method + /// returns `None` when creation of the extrinsic fails, e.g. if equivocation + /// reporting is disabled for the given runtime (i.e. this method is + /// hardcoded to return `None`). Only useful in an offchain context. + fn submit_report_fork_voting_unsigned_extrinsic( + equivocation_proof: + ForkVotingProof, + key_owner_proof: OpaqueKeyOwnershipProof, + ) -> Option<()>; + + /// Submits an unsigned extrinsic to report a future block voting equivocation. The caller + /// must provide the future block voting proof and a key ownership proof + /// (should be obtained using `generate_key_ownership_proof`). + /// The extrinsic will be unsigned and should only be accepted for local + /// authorship (not to be broadcast to the network). This method returns + /// `None` when creation of the extrinsic fails, e.g. if equivocation + /// reporting is disabled for the given runtime (i.e. this method is + /// hardcoded to return `None`). Only useful in an offchain context. + fn submit_report_future_block_voting_unsigned_extrinsic( + equivocation_proof: + FutureBlockVotingProof, AuthorityId>, + key_owner_proof: OpaqueKeyOwnershipProof, + ) -> Option<()>; + /// Generates a proof of key ownership for the given authority in the /// given set. An example usage of this module is coupled with the /// session historical module to prove that a given authority key is @@ -489,6 +537,13 @@ sp_api::decl_runtime_apis! { set_id: ValidatorSetId, authority_id: AuthorityId, ) -> Option; + + /// Generates a proof that the `prev_block_number` is part of the canonical chain at + /// `best_known_block_number`. + fn generate_ancestry_proof( + prev_block_number: NumberFor, + best_known_block_number: Option>, + ) -> Option; } } From bbb8668672896b1952496b2dfe641a91defb2454 Mon Sep 17 00:00:00 2001 From: Jun Jiang Date: Tue, 23 Jul 2024 23:54:20 +0800 Subject: [PATCH 04/27] Replace all ansi_term crates (#2923) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now Polkadot-SDK is ansi_term free --------- Co-authored-by: Bastian Köcher --- Cargo.lock | 6 +- Cargo.toml | 1 - bridges/relays/utils/Cargo.toml | 2 +- bridges/relays/utils/src/initialize.rs | 16 +-- cumulus/test/service/src/lib.rs | 1 - polkadot/node/test/service/src/lib.rs | 1 - prdoc/pr_2923.prdoc | 16 +++ .../bin/node/cli/benches/block_production.rs | 1 - .../bin/node/cli/benches/transaction_pool.rs | 1 - substrate/client/cli/src/config.rs | 3 +- substrate/client/cli/src/runner.rs | 1 - substrate/client/informant/Cargo.toml | 2 +- substrate/client/informant/src/display.rs | 22 ++- substrate/client/informant/src/lib.rs | 77 ++-------- substrate/client/service/src/builder.rs | 7 +- substrate/client/service/src/config.rs | 3 - substrate/client/service/test/src/lib.rs | 1 - substrate/client/tracing/Cargo.toml | 4 +- .../tracing/src/logging/event_format.rs | 136 ++++-------------- substrate/client/tracing/src/logging/mod.rs | 39 +---- 20 files changed, 81 insertions(+), 259 deletions(-) create mode 100644 prdoc/pr_2923.prdoc diff --git a/Cargo.lock b/Cargo.lock index 99dfbafafe28..50c2e8935832 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -16192,12 +16192,12 @@ dependencies = [ name = "relay-utils" version = "0.1.0" dependencies = [ - "ansi_term", "anyhow", "async-std", "async-trait", "backoff", "bp-runtime", + "console", "env_logger 0.11.3", "futures", "isahc", @@ -17668,7 +17668,7 @@ dependencies = [ name = "sc-informant" version = "0.33.0" dependencies = [ - "ansi_term", + "console", "futures", "futures-timer", "log", @@ -18364,8 +18364,8 @@ dependencies = [ name = "sc-tracing" version = "28.0.0" dependencies = [ - "ansi_term", "chrono", + "console", "criterion", "is-terminal", "lazy_static", diff --git a/Cargo.toml b/Cargo.toml index 3886014dc2b4..e9ab2934f446 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -576,7 +576,6 @@ ahash = { version = "0.8.2" } alloy-primitives = { version = "0.4.2", default-features = false } alloy-sol-types = { version = "0.4.2", default-features = false } always-assert = { version = "0.1" } -ansi_term = { version = "0.12.1" } anyhow = { version = "1.0.81" } aquamarine = { version = "0.5.0" } arbitrary = { version = "1.3.2" } diff --git a/bridges/relays/utils/Cargo.toml b/bridges/relays/utils/Cargo.toml index 93e42763967b..2c3f37750486 100644 --- a/bridges/relays/utils/Cargo.toml +++ b/bridges/relays/utils/Cargo.toml @@ -11,11 +11,11 @@ publish = false workspace = true [dependencies] -ansi_term = { workspace = true } anyhow = { workspace = true } async-std = { workspace = true } async-trait = { workspace = true } backoff = { workspace = true } +console = { workspace = true } isahc = { workspace = true } env_logger = { workspace = true } futures = { workspace = true } diff --git a/bridges/relays/utils/src/initialize.rs b/bridges/relays/utils/src/initialize.rs index 64d710242710..cd0377caa3d6 100644 --- a/bridges/relays/utils/src/initialize.rs +++ b/bridges/relays/utils/src/initialize.rs @@ -16,6 +16,7 @@ //! Relayer initialization functions. +use console::style; use parking_lot::Mutex; use std::{cell::RefCell, fmt::Display, io::Write}; @@ -55,7 +56,7 @@ pub fn initialize_logger(with_timestamp: bool) { let timestamp = if cfg!(windows) { Either::Left(timestamp) } else { - Either::Right(ansi_term::Colour::Fixed(8).bold().paint(timestamp)) + Either::Right(style(timestamp).black().bright().bold().to_string()) }; writeln!( @@ -120,7 +121,7 @@ fn color_target(target: &str) -> impl Display + '_ { if cfg!(windows) { Either::Left(target) } else { - Either::Right(ansi_term::Colour::Fixed(8).paint(target)) + Either::Right(style(target).black().bright().to_string()) } } @@ -129,13 +130,12 @@ fn color_level(level: log::Level) -> impl Display { Either::Left(level) } else { let s = level.to_string(); - use ansi_term::Colour as Color; Either::Right(match level { - log::Level::Error => Color::Fixed(9).bold().paint(s), - log::Level::Warn => Color::Fixed(11).bold().paint(s), - log::Level::Info => Color::Fixed(10).paint(s), - log::Level::Debug => Color::Fixed(14).paint(s), - log::Level::Trace => Color::Fixed(12).paint(s), + log::Level::Error => style(s).red().bright().bold().to_string(), + log::Level::Warn => style(s).yellow().bright().bold().to_string(), + log::Level::Info => style(s).green().bright().to_string(), + log::Level::Debug => style(s).cyan().bright().to_string(), + log::Level::Trace => style(s).blue().bright().to_string(), }) } } diff --git a/cumulus/test/service/src/lib.rs b/cumulus/test/service/src/lib.rs index 51cdebbaf54e..0458a0768925 100644 --- a/cumulus/test/service/src/lib.rs +++ b/cumulus/test/service/src/lib.rs @@ -891,7 +891,6 @@ pub fn node_config( announce_block: true, data_path: root, base_path, - informant_output_format: Default::default(), wasm_runtime_overrides: None, runtime_cache_size: 2, }) diff --git a/polkadot/node/test/service/src/lib.rs b/polkadot/node/test/service/src/lib.rs index 35156a3a9372..a4e58253bb17 100644 --- a/polkadot/node/test/service/src/lib.rs +++ b/polkadot/node/test/service/src/lib.rs @@ -232,7 +232,6 @@ pub fn node_config( announce_block: true, data_path: root, base_path, - informant_output_format: Default::default(), } } diff --git a/prdoc/pr_2923.prdoc b/prdoc/pr_2923.prdoc new file mode 100644 index 000000000000..88bf1d48dd84 --- /dev/null +++ b/prdoc/pr_2923.prdoc @@ -0,0 +1,16 @@ +title: "Use `console` crate instead of `ansi_term`" + +doc: + - audience: Node Dev + description: | + This PR replace obsoleted `ansi_term` to `console`. + +crates: + - name: relay-utils + bump: patch + - name: sc-informant + bump: patch + - name: sc-tracing + bump: patch + - name: sc-service + bump: major diff --git a/substrate/bin/node/cli/benches/block_production.rs b/substrate/bin/node/cli/benches/block_production.rs index c16b25187e5f..8239637b3a9f 100644 --- a/substrate/bin/node/cli/benches/block_production.rs +++ b/substrate/bin/node/cli/benches/block_production.rs @@ -104,7 +104,6 @@ fn new_node(tokio_handle: Handle) -> node_cli::service::NewFullBase { announce_block: true, data_path: base_path.path().into(), base_path, - informant_output_format: Default::default(), wasm_runtime_overrides: None, }; diff --git a/substrate/bin/node/cli/benches/transaction_pool.rs b/substrate/bin/node/cli/benches/transaction_pool.rs index 6618f4b1132e..9a71a4ec585d 100644 --- a/substrate/bin/node/cli/benches/transaction_pool.rs +++ b/substrate/bin/node/cli/benches/transaction_pool.rs @@ -99,7 +99,6 @@ fn new_node(tokio_handle: Handle) -> node_cli::service::NewFullBase { announce_block: true, data_path: base_path.path().into(), base_path, - informant_output_format: Default::default(), wasm_runtime_overrides: None, }; diff --git a/substrate/client/cli/src/config.rs b/substrate/client/cli/src/config.rs index 783c9313121f..283148a6d6ad 100644 --- a/substrate/client/cli/src/config.rs +++ b/substrate/client/cli/src/config.rs @@ -27,7 +27,7 @@ use names::{Generator, Name}; use sc_service::{ config::{ BasePath, Configuration, DatabaseSource, IpNetwork, KeystoreConfig, NetworkConfiguration, - NodeKeyConfig, OffchainWorkerConfig, OutputFormat, PrometheusConfig, PruningMode, Role, + NodeKeyConfig, OffchainWorkerConfig, PrometheusConfig, PruningMode, Role, RpcBatchRequestConfig, RpcMethods, TelemetryEndpoints, TransactionPoolOptions, WasmExecutionMethod, }, @@ -550,7 +550,6 @@ pub trait CliConfiguration: Sized { announce_block: self.announce_block()?, role, base_path, - informant_output_format: OutputFormat { enable_color: !self.disable_log_color()? }, runtime_cache_size, }) } diff --git a/substrate/client/cli/src/runner.rs b/substrate/client/cli/src/runner.rs index 6d986e38d2fb..b0dbccfa634c 100644 --- a/substrate/client/cli/src/runner.rs +++ b/substrate/client/cli/src/runner.rs @@ -291,7 +291,6 @@ mod tests { announce_block: true, base_path: sc_service::BasePath::new(root.clone()), data_path: root, - informant_output_format: Default::default(), runtime_cache_size: 2, }, runtime, diff --git a/substrate/client/informant/Cargo.toml b/substrate/client/informant/Cargo.toml index 9da2296deee3..aa54d9479f5c 100644 --- a/substrate/client/informant/Cargo.toml +++ b/substrate/client/informant/Cargo.toml @@ -16,7 +16,7 @@ workspace = true targets = ["x86_64-unknown-linux-gnu"] [dependencies] -ansi_term = { workspace = true } +console = { workspace = true } futures = { workspace = true } futures-timer = { workspace = true } log = { workspace = true, default-features = true } diff --git a/substrate/client/informant/src/display.rs b/substrate/client/informant/src/display.rs index cdbb83b6596c..655bf21c7115 100644 --- a/substrate/client/informant/src/display.rs +++ b/substrate/client/informant/src/display.rs @@ -16,8 +16,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -use crate::OutputFormat; -use ansi_term::Colour; +use console::style; use log::info; use sc_client_api::ClientInfo; use sc_network::NetworkStatus; @@ -47,19 +46,16 @@ pub struct InformantDisplay { last_total_bytes_inbound: u64, /// The last seen total of bytes sent. last_total_bytes_outbound: u64, - /// The format to print output in. - format: OutputFormat, } impl InformantDisplay { /// Builds a new informant display system. - pub fn new(format: OutputFormat) -> InformantDisplay { + pub fn new() -> InformantDisplay { InformantDisplay { last_number: None, last_update: Instant::now(), last_total_bytes_inbound: 0, last_total_bytes_outbound: 0, - format, } } @@ -144,17 +140,17 @@ impl InformantDisplay { info!( target: "substrate", - "{} {}{} ({} peers), best: #{} ({}), finalized #{} ({}), {} {}", + "{} {}{} ({} peers), best: #{} ({}), finalized #{} ({}), ⬇ {} ⬆ {}", level, - self.format.print_with_color(Colour::White.bold(), status), + style(&status).white().bold(), target, - self.format.print_with_color(Colour::White.bold(), num_connected_peers), - self.format.print_with_color(Colour::White.bold(), best_number), + style(num_connected_peers).white().bold(), + style(best_number).white().bold(), best_hash, - self.format.print_with_color(Colour::White.bold(), finalized_number), + style(finalized_number).white().bold(), info.chain.finalized_hash, - self.format.print_with_color(Colour::Green, format!("⬇ {}", TransferRateFormat(avg_bytes_per_sec_inbound))), - self.format.print_with_color(Colour::Red, format!("⬆ {}", TransferRateFormat(avg_bytes_per_sec_outbound))), + style(TransferRateFormat(avg_bytes_per_sec_inbound)).green(), + style(TransferRateFormat(avg_bytes_per_sec_outbound)).red(), ) } } diff --git a/substrate/client/informant/src/lib.rs b/substrate/client/informant/src/lib.rs index af778529ffc5..d44364539a29 100644 --- a/substrate/client/informant/src/lib.rs +++ b/substrate/client/informant/src/lib.rs @@ -18,7 +18,7 @@ //! Console informant. Prints sync progress and block events. Runs on the calling thread. -use ansi_term::{Colour, Style}; +use console::style; use futures::prelude::*; use futures_timer::Delay; use log::{debug, info, trace}; @@ -36,71 +36,15 @@ fn interval(duration: Duration) -> impl Stream + Unpin { futures::stream::unfold((), move |_| Delay::new(duration).map(|_| Some(((), ())))).map(drop) } -/// The format to print telemetry output in. -#[derive(Clone, Debug)] -pub struct OutputFormat { - /// Enable color output in logs. - /// - /// Is enabled by default. - pub enable_color: bool, -} - -impl Default for OutputFormat { - fn default() -> Self { - Self { enable_color: true } - } -} - -enum ColorOrStyle { - Color(Colour), - Style(Style), -} - -impl From for ColorOrStyle { - fn from(value: Colour) -> Self { - Self::Color(value) - } -} - -impl From