[frame/im-online] remove network state from heartbeats (#14251)

* [frame/im-online] remove `external_addresses` from heartbeats

Users should use DHT for discovering new nodes. The reason for adding external addresses was
unstable work of authority discovery (see https://github.com/paritytech/substrate/issues/2719),
which is now stable. Hence we can safely remove `external_addresses`.

Refs https://github.com/paritytech/polkadot/issues/7181

* remove unused import

* run benchmark

* remove external_addresses from offchain NetworkState

* add missing fn to TestNetwork

* Revert "run benchmark"

This reverts commit a282042c2d6bf8bae2c383f6e2699c3fe2970a3d.

* update weights

* address @bkchr comments

* remove duplicate fn

* cleanup benchmarking.rs

* fix executor tests

* remove peer_id from hearbeat as well

https://github.com/paritytech/substrate/pull/14251#discussion_r1210887220

* remove MaxPeerDataEncodingSize

* change storage value type to `()`

https://github.com/paritytech/substrate/pull/14251#discussion_r1214268931

* scaffold storage migration

* no need to check the type actually

* remove unnecessary types from v0 mod

* add a test for migration

* expose Config types

+ pre_upgrade and post_upgrade working fn

* fix test

* replace dummy type with ConstU32

* add some comments to migration test

* fix comment

* respond to @bkchr comments

* use BoundedOpaqueNetworkState::default

intead of using default for each field
This commit is contained in:
Anton
2023-06-15 13:42:36 +04:00
committed by GitHub
parent 4057ef1554
commit 6cd2c8b395
10 changed files with 226 additions and 198 deletions
@@ -37,7 +37,6 @@ fn should_submit_unsigned_transaction() {
pallet_im_online::sr25519::AuthoritySignature::try_from(vec![0; 64]).unwrap();
let heartbeat_data = pallet_im_online::Heartbeat {
block_number: 1,
network_state: Default::default(),
session_index: 1,
authority_index: 0,
validators_len: 0,
+3 -4
View File
@@ -328,8 +328,9 @@ impl InstanceFilter<RuntimeCall> for ProxyType {
RuntimeCall::Elections(..) |
RuntimeCall::Treasury(..)
),
ProxyType::Staking =>
matches!(c, RuntimeCall::Staking(..) | RuntimeCall::FastUnstake(..)),
ProxyType::Staking => {
matches!(c, RuntimeCall::Staking(..) | RuntimeCall::FastUnstake(..))
},
}
}
fn is_superset(&self, o: &Self) -> bool {
@@ -1261,7 +1262,6 @@ parameter_types! {
pub const MaxAuthorities: u32 = 100;
pub const MaxKeys: u32 = 10_000;
pub const MaxPeerInHeartbeats: u32 = 10_000;
pub const MaxPeerDataEncodingSize: u32 = 1_000;
}
impl<LocalCall> frame_system::offchain::CreateSignedTransaction<LocalCall> for Runtime
@@ -1329,7 +1329,6 @@ impl pallet_im_online::Config for Runtime {
type WeightInfo = pallet_im_online::weights::SubstrateWeight<Runtime>;
type MaxKeys = MaxKeys;
type MaxPeerInHeartbeats = MaxPeerInHeartbeats;
type MaxPeerDataEncodingSize = MaxPeerDataEncodingSize;
}
impl pallet_offences::Config for Runtime {
-1
View File
@@ -324,7 +324,6 @@ impl AsyncApi {
#[cfg(test)]
mod tests {
use super::*;
use libp2p::PeerId;
use sc_client_db::offchain::LocalStorage;
use sc_network::{
config::MultiaddrWithPeerId, types::ProtocolName, NetworkPeers, NetworkStateInfo,
+3 -14
View File
@@ -24,7 +24,6 @@ use super::*;
use frame_benchmarking::v1::benchmarks;
use frame_support::{traits::UnfilteredDispatchable, WeakBoundedVec};
use frame_system::RawOrigin;
use sp_core::{offchain::OpaqueMultiaddr, OpaquePeerId};
use sp_runtime::{
traits::{ValidateUnsigned, Zero},
transaction_validity::TransactionSource,
@@ -33,11 +32,9 @@ use sp_runtime::{
use crate::Pallet as ImOnline;
const MAX_KEYS: u32 = 1000;
const MAX_EXTERNAL_ADDRESSES: u32 = 100;
pub fn create_heartbeat<T: Config>(
k: u32,
e: u32,
) -> Result<
(crate::Heartbeat<T::BlockNumber>, <T::AuthorityId as RuntimeAppPublic>::Signature),
&'static str,
@@ -50,13 +47,8 @@ pub fn create_heartbeat<T: Config>(
.map_err(|()| "More than the maximum number of keys provided")?;
Keys::<T>::put(bounded_keys);
let network_state = OpaqueNetworkState {
peer_id: OpaquePeerId::default(),
external_addresses: vec![OpaqueMultiaddr::new(vec![0; 32]); e as usize],
};
let input_heartbeat = Heartbeat {
block_number: T::BlockNumber::zero(),
network_state,
session_index: 0,
authority_index: k - 1,
validators_len: keys.len() as u32,
@@ -73,15 +65,13 @@ benchmarks! {
#[extra]
heartbeat {
let k in 1 .. MAX_KEYS;
let e in 1 .. MAX_EXTERNAL_ADDRESSES;
let (input_heartbeat, signature) = create_heartbeat::<T>(k, e)?;
let (input_heartbeat, signature) = create_heartbeat::<T>(k)?;
}: _(RawOrigin::None, input_heartbeat, signature)
#[extra]
validate_unsigned {
let k in 1 .. MAX_KEYS;
let e in 1 .. MAX_EXTERNAL_ADDRESSES;
let (input_heartbeat, signature) = create_heartbeat::<T>(k, e)?;
let (input_heartbeat, signature) = create_heartbeat::<T>(k)?;
let call = Call::heartbeat { heartbeat: input_heartbeat, signature };
}: {
ImOnline::<T>::validate_unsigned(TransactionSource::InBlock, &call)
@@ -90,8 +80,7 @@ benchmarks! {
validate_unsigned_and_then_heartbeat {
let k in 1 .. MAX_KEYS;
let e in 1 .. MAX_EXTERNAL_ADDRESSES;
let (input_heartbeat, signature) = create_heartbeat::<T>(k, e)?;
let (input_heartbeat, signature) = create_heartbeat::<T>(k)?;
let call = Call::heartbeat { heartbeat: input_heartbeat, signature };
let call_enc = call.encode();
}: {
+30 -123
View File
@@ -26,8 +26,7 @@
//! in the current era or session.
//!
//! The heartbeat is a signed transaction, which was signed using the session key
//! and includes the recent best block number of the local validators chain as well
//! as the [NetworkState](../../client/offchain/struct.NetworkState.html).
//! and includes the recent best block number of the local validators chain.
//! It is submitted as an Unsigned Transaction via off-chain workers.
//!
//! - [`Config`]
@@ -78,23 +77,27 @@
#![cfg_attr(not(feature = "std"), no_std)]
mod benchmarking;
pub mod migration;
mod mock;
mod tests;
pub mod weights;
use codec::{Decode, Encode, MaxEncodedLen};
use frame_support::{
pallet_prelude::*,
traits::{
EstimateNextSessionRotation, Get, OneSessionHandler, ValidatorSet,
ValidatorSetWithIdentification, WrapperOpaque,
ValidatorSetWithIdentification,
},
BoundedSlice, WeakBoundedVec,
};
use frame_system::offchain::{SendTransactionTypes, SubmitTransaction};
use frame_system::{
offchain::{SendTransactionTypes, SubmitTransaction},
pallet_prelude::*,
};
pub use pallet::*;
use scale_info::TypeInfo;
use sp_application_crypto::RuntimeAppPublic;
use sp_core::offchain::OpaqueNetworkState;
use sp_runtime::{
offchain::storage::{MutateStorageError, StorageRetrievalError, StorageValueRef},
traits::{AtLeast32BitUnsigned, Convert, Saturating, TrailingZeroInput},
@@ -190,7 +193,6 @@ enum OffchainErr<BlockNumber> {
AlreadyOnline(u32),
FailedSigning,
FailedToAcquireLock,
NetworkState,
SubmitTransaction,
}
@@ -206,7 +208,6 @@ impl<BlockNumber: sp_std::fmt::Debug> sp_std::fmt::Debug for OffchainErr<BlockNu
},
OffchainErr::FailedSigning => write!(fmt, "Failed to sign heartbeat"),
OffchainErr::FailedToAcquireLock => write!(fmt, "Failed to acquire lock"),
OffchainErr::NetworkState => write!(fmt, "Failed to fetch network state"),
OffchainErr::SubmitTransaction => write!(fmt, "Failed to submit transaction"),
}
}
@@ -222,8 +223,6 @@ where
{
/// Block number at the time heartbeat is created..
pub block_number: BlockNumber,
/// A state of local network (peer id and external addresses)
pub network_state: OpaqueNetworkState,
/// Index of the current session.
pub session_index: SessionIndex,
/// An index of the authority on the list of validators.
@@ -232,64 +231,6 @@ where
pub validators_len: u32,
}
/// A type that is the same as [`OpaqueNetworkState`] but with [`Vec`] replaced with
/// [`WeakBoundedVec<Limit>`] where Limit is the respective size limit
/// `PeerIdEncodingLimit` represents the size limit of the encoding of `PeerId`
/// `MultiAddrEncodingLimit` represents the size limit of the encoding of `MultiAddr`
/// `AddressesLimit` represents the size limit of the vector of peers connected
#[derive(Clone, Eq, PartialEq, Encode, Decode, MaxEncodedLen, TypeInfo)]
#[codec(mel_bound())]
#[scale_info(skip_type_params(PeerIdEncodingLimit, MultiAddrEncodingLimit, AddressesLimit))]
pub struct BoundedOpaqueNetworkState<PeerIdEncodingLimit, MultiAddrEncodingLimit, AddressesLimit>
where
PeerIdEncodingLimit: Get<u32>,
MultiAddrEncodingLimit: Get<u32>,
AddressesLimit: Get<u32>,
{
/// PeerId of the local node in SCALE encoded.
pub peer_id: WeakBoundedVec<u8, PeerIdEncodingLimit>,
/// List of addresses the node knows it can be reached as.
pub external_addresses:
WeakBoundedVec<WeakBoundedVec<u8, MultiAddrEncodingLimit>, AddressesLimit>,
}
impl<PeerIdEncodingLimit: Get<u32>, MultiAddrEncodingLimit: Get<u32>, AddressesLimit: Get<u32>>
BoundedOpaqueNetworkState<PeerIdEncodingLimit, MultiAddrEncodingLimit, AddressesLimit>
{
fn force_from(ons: &OpaqueNetworkState) -> Self {
let peer_id = WeakBoundedVec::<_, PeerIdEncodingLimit>::force_from(
ons.peer_id.0.clone(),
Some(
"Warning: The size of the encoding of PeerId \
is bigger than expected. A runtime configuration \
adjustment may be needed.",
),
);
let external_addresses = WeakBoundedVec::<_, AddressesLimit>::force_from(
ons.external_addresses
.iter()
.map(|x| {
WeakBoundedVec::<_, MultiAddrEncodingLimit>::force_from(
x.0.clone(),
Some(
"Warning: The size of the encoding of MultiAddr \
is bigger than expected. A runtime configuration \
adjustment may be needed.",
),
)
})
.collect(),
Some(
"Warning: The network has more peers than expected \
A runtime configuration adjustment may be needed.",
),
);
Self { peer_id, external_addresses }
}
}
/// A type for representing the validator id in a session.
pub type ValidatorId<T> = <<T as Config>::ValidatorSet as ValidatorSet<
<T as frame_system::Config>::AccountId,
@@ -309,10 +250,12 @@ type OffchainResult<T, A> = Result<A, OffchainErr<<T as frame_system::Config>::B
#[frame_support::pallet]
pub mod pallet {
use super::*;
use frame_support::pallet_prelude::*;
use frame_system::pallet_prelude::*;
/// The current storage version.
const STORAGE_VERSION: StorageVersion = StorageVersion::new(1);
#[pallet::pallet]
#[pallet::storage_version(STORAGE_VERSION)]
pub struct Pallet<T>(_);
#[pallet::config]
@@ -331,10 +274,6 @@ pub mod pallet {
/// The maximum number of peers to be stored in `ReceivedHeartbeats`
type MaxPeerInHeartbeats: Get<u32>;
/// The maximum size of the encoding of `PeerId` and `MultiAddr` that are coming
/// from the hearbeat
type MaxPeerDataEncodingSize: Get<u32>;
/// The overarching event type.
type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
@@ -400,38 +339,25 @@ pub mod pallet {
/// more accurate then the value we calculate for `HeartbeatAfter`.
#[pallet::storage]
#[pallet::getter(fn heartbeat_after)]
pub(crate) type HeartbeatAfter<T: Config> = StorageValue<_, T::BlockNumber, ValueQuery>;
pub(super) type HeartbeatAfter<T: Config> = StorageValue<_, T::BlockNumber, ValueQuery>;
/// The current set of keys that may issue a heartbeat.
#[pallet::storage]
#[pallet::getter(fn keys)]
pub(crate) type Keys<T: Config> =
pub(super) type Keys<T: Config> =
StorageValue<_, WeakBoundedVec<T::AuthorityId, T::MaxKeys>, ValueQuery>;
/// For each session index, we keep a mapping of `SessionIndex` and `AuthIndex` to
/// `WrapperOpaque<BoundedOpaqueNetworkState>`.
/// For each session index, we keep a mapping of `SessionIndex` and `AuthIndex`.
#[pallet::storage]
#[pallet::getter(fn received_heartbeats)]
pub(crate) type ReceivedHeartbeats<T: Config> = StorageDoubleMap<
_,
Twox64Concat,
SessionIndex,
Twox64Concat,
AuthIndex,
WrapperOpaque<
BoundedOpaqueNetworkState<
T::MaxPeerDataEncodingSize,
T::MaxPeerDataEncodingSize,
T::MaxPeerInHeartbeats,
>,
>,
>;
pub(super) type ReceivedHeartbeats<T: Config> =
StorageDoubleMap<_, Twox64Concat, SessionIndex, Twox64Concat, AuthIndex, bool>;
/// For each session index, we keep a mapping of `ValidatorId<T>` to the
/// number of blocks authored by the given authority.
#[pallet::storage]
#[pallet::getter(fn authored_blocks)]
pub(crate) type AuthoredBlocks<T: Config> = StorageDoubleMap<
pub(super) type AuthoredBlocks<T: Config> = StorageDoubleMap<
_,
Twox64Concat,
SessionIndex,
@@ -457,16 +383,13 @@ pub mod pallet {
#[pallet::call]
impl<T: Config> Pallet<T> {
/// ## Complexity:
/// - `O(K + E)` where K is length of `Keys` (heartbeat.validators_len) and E is length of
/// `heartbeat.network_state.external_address`
/// - `O(K)` where K is length of `Keys` (heartbeat.validators_len)
/// - `O(K)`: decoding of length `K`
/// - `O(E)`: decoding/encoding of length `E`
// NOTE: the weight includes the cost of validate_unsigned as it is part of the cost to
// import block with such an extrinsic.
#[pallet::call_index(0)]
#[pallet::weight(<T as Config>::WeightInfo::validate_unsigned_and_then_heartbeat(
heartbeat.validators_len as u32,
heartbeat.network_state.external_addresses.len() as u32,
heartbeat.validators_len,
))]
pub fn heartbeat(
origin: OriginFor<T>,
@@ -479,22 +402,13 @@ pub mod pallet {
let current_session = T::ValidatorSet::session_index();
let exists =
ReceivedHeartbeats::<T>::contains_key(&current_session, &heartbeat.authority_index);
ReceivedHeartbeats::<T>::contains_key(current_session, heartbeat.authority_index);
let keys = Keys::<T>::get();
let public = keys.get(heartbeat.authority_index as usize);
if let (false, Some(public)) = (exists, public) {
Self::deposit_event(Event::<T>::HeartbeatReceived { authority_id: public.clone() });
let network_state_bounded = BoundedOpaqueNetworkState::<
T::MaxPeerDataEncodingSize,
T::MaxPeerDataEncodingSize,
T::MaxPeerInHeartbeats,
>::force_from(&heartbeat.network_state);
ReceivedHeartbeats::<T>::insert(
&current_session,
&heartbeat.authority_index,
WrapperOpaque::from(network_state_bounded),
);
ReceivedHeartbeats::<T>::insert(current_session, heartbeat.authority_index, true);
Ok(())
} else if exists {
@@ -618,22 +532,22 @@ impl<T: Config> Pallet<T> {
fn is_online_aux(authority_index: AuthIndex, authority: &ValidatorId<T>) -> bool {
let current_session = T::ValidatorSet::session_index();
ReceivedHeartbeats::<T>::contains_key(&current_session, &authority_index) ||
AuthoredBlocks::<T>::get(&current_session, authority) != 0
ReceivedHeartbeats::<T>::contains_key(current_session, authority_index) ||
AuthoredBlocks::<T>::get(current_session, authority) != 0
}
/// Returns `true` if a heartbeat has been received for the authority at `authority_index` in
/// the authorities series, during the current session. Otherwise `false`.
pub fn received_heartbeat_in_current_session(authority_index: AuthIndex) -> bool {
let current_session = T::ValidatorSet::session_index();
ReceivedHeartbeats::<T>::contains_key(&current_session, &authority_index)
ReceivedHeartbeats::<T>::contains_key(current_session, authority_index)
}
/// Note that the given authority has authored a block in the current session.
fn note_authorship(author: ValidatorId<T>) {
let current_session = T::ValidatorSet::session_index();
AuthoredBlocks::<T>::mutate(&current_session, author, |authored| *authored += 1);
AuthoredBlocks::<T>::mutate(current_session, author, |authored| *authored += 1);
}
pub(crate) fn send_heartbeats(
@@ -705,15 +619,8 @@ impl<T: Config> Pallet<T> {
) -> OffchainResult<T, ()> {
// A helper function to prepare heartbeat call.
let prepare_heartbeat = || -> OffchainResult<T, Call<T>> {
let network_state =
sp_io::offchain::network_state().map_err(|_| OffchainErr::NetworkState)?;
let heartbeat = Heartbeat {
block_number,
network_state,
session_index,
authority_index,
validators_len,
};
let heartbeat =
Heartbeat { block_number, session_index, authority_index, validators_len };
let signature = key.sign(&heartbeat.encode()).ok_or(OffchainErr::FailedSigning)?;
@@ -887,9 +794,9 @@ impl<T: Config> OneSessionHandler<T::AccountId> for Pallet<T> {
// current session, they have already been processed and won't be needed
// anymore.
#[allow(deprecated)]
ReceivedHeartbeats::<T>::remove_prefix(&T::ValidatorSet::session_index(), None);
ReceivedHeartbeats::<T>::remove_prefix(T::ValidatorSet::session_index(), None);
#[allow(deprecated)]
AuthoredBlocks::<T>::remove_prefix(&T::ValidatorSet::session_index(), None);
AuthoredBlocks::<T>::remove_prefix(T::ValidatorSet::session_index(), None);
if offenders.is_empty() {
Self::deposit_event(Event::<T>::AllGood);
+164
View File
@@ -0,0 +1,164 @@
// This file is part of Substrate.
// Copyright (C) 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.
//! Storage migrations for the im-online pallet.
use super::*;
use frame_support::{storage_alias, traits::OnRuntimeUpgrade};
#[cfg(feature = "try-runtime")]
use frame_support::ensure;
#[cfg(feature = "try-runtime")]
use sp_runtime::TryRuntimeError;
/// The log target.
const TARGET: &str = "runtime::im-online::migration::v1";
/// The original data layout of the im-online pallet (`ReceivedHeartbeats` storage item).
mod v0 {
use super::*;
use frame_support::traits::WrapperOpaque;
#[derive(Encode, Decode)]
pub(super) struct BoundedOpaqueNetworkState {
/// PeerId of the local node in SCALE encoded.
pub peer_id: Vec<u8>,
/// List of addresses the node knows it can be reached as.
pub external_addresses: Vec<Vec<u8>>,
}
#[storage_alias]
pub(super) type ReceivedHeartbeats<T: Config> = StorageDoubleMap<
Pallet<T>,
Twox64Concat,
SessionIndex,
Twox64Concat,
AuthIndex,
WrapperOpaque<BoundedOpaqueNetworkState>,
>;
}
pub mod v1 {
use super::*;
/// Simple migration that replaces `ReceivedHeartbeats` values with `true`.
pub struct Migration<T>(sp_std::marker::PhantomData<T>);
impl<T: Config> OnRuntimeUpgrade for Migration<T> {
#[cfg(feature = "try-runtime")]
fn pre_upgrade() -> Result<Vec<u8>, TryRuntimeError> {
ensure!(StorageVersion::get::<Pallet<T>>() == 0, "can only upgrade from version 0");
let count = v0::ReceivedHeartbeats::<T>::iter().count();
log::info!(target: TARGET, "Migrating {} received heartbeats", count);
Ok((count as u32).encode())
}
fn on_runtime_upgrade() -> Weight {
let mut weight = T::DbWeight::get().reads(1);
if StorageVersion::get::<Pallet<T>>() != 0 {
log::warn!(
target: TARGET,
"Skipping migration because current storage version is not 0"
);
return weight
}
let heartbeats = v0::ReceivedHeartbeats::<T>::drain().collect::<Vec<_>>();
weight.saturating_accrue(T::DbWeight::get().reads(heartbeats.len() as u64));
weight.saturating_accrue(T::DbWeight::get().writes(heartbeats.len() as u64));
for (session_index, auth_index, _) in heartbeats {
log::trace!(
target: TARGET,
"Migrated received heartbeat for {:?}...",
(session_index, auth_index)
);
crate::ReceivedHeartbeats::<T>::insert(session_index, auth_index, true);
}
StorageVersion::new(1).put::<Pallet<T>>();
weight.saturating_add(T::DbWeight::get().writes(1))
}
#[cfg(feature = "try-runtime")]
fn post_upgrade(state: Vec<u8>) -> DispatchResult {
let old_received_heartbeats: u32 =
Decode::decode(&mut &state[..]).expect("pre_upgrade provides a valid state; qed");
let new_received_heartbeats = crate::ReceivedHeartbeats::<T>::iter().count();
if new_received_heartbeats != old_received_heartbeats as usize {
log::error!(
target: TARGET,
"migrated {} received heartbeats, expected {}",
new_received_heartbeats,
old_received_heartbeats
);
}
ensure!(StorageVersion::get::<Pallet<T>>() == 1, "must upgrade");
Ok(())
}
}
}
#[cfg(test)]
#[cfg(feature = "try-runtime")]
mod test {
use super::*;
use crate::mock::{new_test_ext, Runtime as T};
use frame_support::traits::WrapperOpaque;
#[test]
fn migration_works() {
new_test_ext().execute_with(|| {
assert_eq!(StorageVersion::get::<Pallet<T>>(), 0);
// Insert some received heartbeats into the v0 storage:
let current_session = <T as pallet::Config>::ValidatorSet::session_index();
v0::ReceivedHeartbeats::<T>::insert(
&current_session,
0,
WrapperOpaque(v0::BoundedOpaqueNetworkState::default()),
);
v0::ReceivedHeartbeats::<T>::insert(
&current_session,
1,
WrapperOpaque(v0::BoundedOpaqueNetworkState::default()),
);
// Check that the v0 storage is populated
assert_eq!(v0::ReceivedHeartbeats::<T>::iter().count(), 2);
assert_eq!(crate::ReceivedHeartbeats::<T>::iter().count(), 0, "V1 storage corrupted");
// Perform the migration
let state = v1::Migration::<T>::pre_upgrade().unwrap();
let _w = v1::Migration::<T>::on_runtime_upgrade();
v1::Migration::<T>::post_upgrade(state).unwrap();
// Check that the v1 storage is populated and v0 storage is empty
assert_eq!(v0::ReceivedHeartbeats::<T>::iter().count(), 0);
assert_eq!(crate::ReceivedHeartbeats::<T>::iter().count(), 2);
assert!(crate::ReceivedHeartbeats::<T>::contains_key(&current_session, 0));
assert_eq!(Some(true), crate::ReceivedHeartbeats::<T>::get(&current_session, 1));
assert_eq!(StorageVersion::get::<Pallet<T>>(), 1);
});
}
}
-1
View File
@@ -217,7 +217,6 @@ impl Config for Runtime {
type WeightInfo = ();
type MaxKeys = ConstU32<10_000>;
type MaxPeerInHeartbeats = ConstU32<10_000>;
type MaxPeerDataEncodingSize = ConstU32<1_000>;
}
impl<LocalCall> frame_system::offchain::SendTransactionTypes<LocalCall> for Runtime
+4 -24
View File
@@ -22,12 +22,9 @@
use super::*;
use crate::mock::*;
use frame_support::{assert_noop, dispatch};
use sp_core::{
offchain::{
testing::{TestOffchainExt, TestTransactionPoolExt},
OffchainDbExt, OffchainWorkerExt, TransactionPoolExt,
},
OpaquePeerId,
use sp_core::offchain::{
testing::{TestOffchainExt, TestTransactionPoolExt},
OffchainDbExt, OffchainWorkerExt, TransactionPoolExt,
};
use sp_runtime::{
testing::UintAuthorityId,
@@ -121,14 +118,8 @@ fn heartbeat(
id: UintAuthorityId,
validators: Vec<u64>,
) -> dispatch::DispatchResult {
use frame_support::unsigned::ValidateUnsigned;
let heartbeat = Heartbeat {
block_number,
network_state: OpaqueNetworkState {
peer_id: OpaquePeerId(vec![1]),
external_addresses: vec![],
},
session_index,
authority_index,
validators_len: validators.len() as u32,
@@ -212,8 +203,6 @@ fn late_heartbeat_and_invalid_keys_len_should_fail() {
#[test]
fn should_generate_heartbeats() {
use frame_support::traits::OffchainWorker;
let mut ext = new_test_ext();
let (offchain, _state) = TestOffchainExt::new();
let (pool, state) = TestTransactionPoolExt::new();
@@ -252,7 +241,6 @@ fn should_generate_heartbeats() {
heartbeat,
Heartbeat {
block_number: block,
network_state: sp_io::offchain::network_state().unwrap(),
session_index: 2,
authority_index: 2,
validators_len: 3,
@@ -365,21 +353,13 @@ fn should_not_send_a_report_if_already_online() {
assert_eq!(
heartbeat,
Heartbeat {
block_number: 4,
network_state: sp_io::offchain::network_state().unwrap(),
session_index: 2,
authority_index: 0,
validators_len: 3,
}
Heartbeat { block_number: 4, session_index: 2, authority_index: 0, validators_len: 3 }
);
});
}
#[test]
fn should_handle_missing_progress_estimates() {
use frame_support::traits::OffchainWorker;
let mut ext = new_test_ext();
let (offchain, _state) = TestOffchainExt::new();
let (pool, state) = TestTransactionPoolExt::new();
+22 -29
View File
@@ -18,9 +18,9 @@
//! Autogenerated weights for pallet_im_online
//!
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
//! DATE: 2023-04-06, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
//! DATE: 2023-05-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
//! WORST CASE MAP SIZE: `1000000`
//! HOSTNAME: `bm2`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz`
//! HOSTNAME: `build-host`, CPU: `AMD EPYC 7601 32-Core Processor`
//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024
// Executed Command:
@@ -37,18 +37,19 @@
// --heap-pages=4096
// --output=./frame/im-online/src/weights.rs
// --header=./HEADER-APACHE2
// --template=./.maintain/frame-weight-template.hbs
// --template=./frame-weight-template.hbs
#![cfg_attr(rustfmt, rustfmt_skip)]
#![allow(unused_parens)]
#![allow(unused_imports)]
#![allow(missing_docs)]
use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}};
use sp_std::marker::PhantomData;
use core::marker::PhantomData;
/// Weight functions needed for pallet_im_online.
pub trait WeightInfo {
fn validate_unsigned_and_then_heartbeat(k: u32, e: u32, ) -> Weight;
fn validate_unsigned_and_then_heartbeat(k: u32, ) -> Weight;
}
/// Weights for pallet_im_online using the Substrate node and recommended hardware.
@@ -61,25 +62,21 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
/// Storage: ImOnline Keys (r:1 w:0)
/// Proof: ImOnline Keys (max_values: Some(1), max_size: Some(320002), added: 320497, mode: MaxEncodedLen)
/// Storage: ImOnline ReceivedHeartbeats (r:1 w:1)
/// Proof: ImOnline ReceivedHeartbeats (max_values: None, max_size: Some(10021032), added: 10023507, mode: MaxEncodedLen)
/// Proof: ImOnline ReceivedHeartbeats (max_values: None, max_size: Some(1028), added: 3503, mode: MaxEncodedLen)
/// Storage: ImOnline AuthoredBlocks (r:1 w:0)
/// Proof: ImOnline AuthoredBlocks (max_values: None, max_size: Some(56), added: 2531, mode: MaxEncodedLen)
/// The range of component `k` is `[1, 1000]`.
/// The range of component `e` is `[1, 100]`.
fn validate_unsigned_and_then_heartbeat(k: u32, e: u32, ) -> Weight {
fn validate_unsigned_and_then_heartbeat(k: u32, ) -> Weight {
// Proof Size summary in bytes:
// Measured: `295 + k * (32 ±0)`
// Estimated: `10024497 + e * (35 ±0) + k * (32 ±0)`
// Minimum execution time: 95_573_000 picoseconds.
Weight::from_parts(78_856_572, 10024497)
// Standard Error: 315
.saturating_add(Weight::from_parts(22_926, 0).saturating_mul(k.into()))
// Standard Error: 3_181
.saturating_add(Weight::from_parts(362_093, 0).saturating_mul(e.into()))
// Estimated: `321487 + k * (1761 ±0)`
// Minimum execution time: 120_818_000 picoseconds.
Weight::from_parts(121_396_296, 321487)
// Standard Error: 2_183
.saturating_add(Weight::from_parts(58_710, 0).saturating_mul(k.into()))
.saturating_add(T::DbWeight::get().reads(4_u64))
.saturating_add(T::DbWeight::get().writes(1_u64))
.saturating_add(Weight::from_parts(0, 35).saturating_mul(e.into()))
.saturating_add(Weight::from_parts(0, 32).saturating_mul(k.into()))
.saturating_add(Weight::from_parts(0, 1761).saturating_mul(k.into()))
}
}
@@ -92,24 +89,20 @@ impl WeightInfo for () {
/// Storage: ImOnline Keys (r:1 w:0)
/// Proof: ImOnline Keys (max_values: Some(1), max_size: Some(320002), added: 320497, mode: MaxEncodedLen)
/// Storage: ImOnline ReceivedHeartbeats (r:1 w:1)
/// Proof: ImOnline ReceivedHeartbeats (max_values: None, max_size: Some(10021032), added: 10023507, mode: MaxEncodedLen)
/// Proof: ImOnline ReceivedHeartbeats (max_values: None, max_size: Some(1028), added: 3503, mode: MaxEncodedLen)
/// Storage: ImOnline AuthoredBlocks (r:1 w:0)
/// Proof: ImOnline AuthoredBlocks (max_values: None, max_size: Some(56), added: 2531, mode: MaxEncodedLen)
/// The range of component `k` is `[1, 1000]`.
/// The range of component `e` is `[1, 100]`.
fn validate_unsigned_and_then_heartbeat(k: u32, e: u32, ) -> Weight {
fn validate_unsigned_and_then_heartbeat(k: u32, ) -> Weight {
// Proof Size summary in bytes:
// Measured: `295 + k * (32 ±0)`
// Estimated: `10024497 + e * (35 ±0) + k * (32 ±0)`
// Minimum execution time: 95_573_000 picoseconds.
Weight::from_parts(78_856_572, 10024497)
// Standard Error: 315
.saturating_add(Weight::from_parts(22_926, 0).saturating_mul(k.into()))
// Standard Error: 3_181
.saturating_add(Weight::from_parts(362_093, 0).saturating_mul(e.into()))
// Estimated: `321487 + k * (1761 ±0)`
// Minimum execution time: 120_818_000 picoseconds.
Weight::from_parts(121_396_296, 321487)
// Standard Error: 2_183
.saturating_add(Weight::from_parts(58_710, 0).saturating_mul(k.into()))
.saturating_add(RocksDbWeight::get().reads(4_u64))
.saturating_add(RocksDbWeight::get().writes(1_u64))
.saturating_add(Weight::from_parts(0, 35).saturating_mul(e.into()))
.saturating_add(Weight::from_parts(0, 32).saturating_mul(k.into()))
.saturating_add(Weight::from_parts(0, 1761).saturating_mul(k.into()))
}
}
@@ -197,7 +197,6 @@ impl pallet_im_online::Config for Test {
type WeightInfo = ();
type MaxKeys = ConstU32<10_000>;
type MaxPeerInHeartbeats = ConstU32<10_000>;
type MaxPeerDataEncodingSize = ConstU32<1_000>;
}
impl pallet_offences::Config for Test {