diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index 45f27312697ca..03e96ab388b72 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -1824,6 +1824,12 @@ sp_api::impl_runtime_apis! { impl offchain_primitives::OffchainWorkerApi for Runtime { fn offchain_worker(header: &::Header) { + use sp_runtime::{traits::Header, DigestItem}; + + if header.digest().logs().iter().any(|di| di == &DigestItem::RuntimeEnvironmentUpdated) { + pallet_im_online::migration::clear_offchain_storage(Session::validators().len() as u32); + } + Executive::offchain_worker(header) } } diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index 166c2d0d96e06..03bd5b18b5bed 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -1794,6 +1794,12 @@ sp_api::impl_runtime_apis! { impl offchain_primitives::OffchainWorkerApi for Runtime { fn offchain_worker(header: &::Header) { + use sp_runtime::{traits::Header, DigestItem}; + + if header.digest().logs().iter().any(|di| di == &DigestItem::RuntimeEnvironmentUpdated) { + pallet_im_online::migration::clear_offchain_storage(Session::validators().len() as u32); + } + Executive::offchain_worker(header) } } diff --git a/prdoc/pr_2290.prdoc b/prdoc/pr_2290.prdoc new file mode 100644 index 0000000000000..9f0476e915264 --- /dev/null +++ b/prdoc/pr_2290.prdoc @@ -0,0 +1,10 @@ +title: im-online pallet offcain storage cleanup + +doc: + - audience: Runtime Dev + description: | + Adds a function `clear_offchain_storage` to `pallet-im-online`. This function can be used + after the pallet was removed to clear its offchain storage. + +crates: + - name: pallet-im-online diff --git a/substrate/frame/im-online/src/migration.rs b/substrate/frame/im-online/src/migration.rs index 3860a7ca53295..0d2c0a055b6d8 100644 --- a/substrate/frame/im-online/src/migration.rs +++ b/substrate/frame/im-online/src/migration.rs @@ -116,6 +116,21 @@ pub mod v1 { } } +/// Clears the pallet's offchain storage. +/// +/// Must be put in `OffchainWorkerApi::offchain_worker` after +/// the pallet was removed. +pub fn clear_offchain_storage(validator_set_size: u32) { + (0..validator_set_size).for_each(|idx| { + let key = { + let mut key = DB_PREFIX.to_vec(); + key.extend(idx.encode()); + key + }; + sp_runtime::offchain::storage::StorageValueRef::persistent(&key).clear(); + }); +} + #[cfg(all(feature = "try-runtime", test))] mod test { use super::*;