From b9102969e1bb09cfa320f1e55c78ed7970c99159 Mon Sep 17 00:00:00 2001
From: Leonardo Razovic <4128940+lrazovic@users.noreply.github.com>
Date: Tue, 19 Mar 2024 16:02:18 +0100
Subject: [PATCH] Migration: Issuance and Dust fix (#197)
* feat: remove migrations already ran
* feat: add vesting migration
* docs: add more comments
* chore: print the total issuance
* chore: split migrations in multiple files
* chore: fmt
* docs: add more details about the account
---
Cargo.lock | 2 +
Cargo.toml | 1 +
runtimes/base/Cargo.toml | 8 +-
.../src/custom_migrations/deposit_dust.rs | 61 +++++++++++
.../init_pallet.rs} | 11 +-
runtimes/base/src/custom_migrations/mod.rs | 22 ++++
.../custom_migrations/unhashed_migration.rs | 101 ++++++++++++++++++
runtimes/base/src/lib.rs | 11 +-
runtimes/testnet/Cargo.toml | 2 +-
9 files changed, 201 insertions(+), 18 deletions(-)
create mode 100644 runtimes/base/src/custom_migrations/deposit_dust.rs
rename runtimes/base/src/{custom_migrations.rs => custom_migrations/init_pallet.rs} (91%)
create mode 100644 runtimes/base/src/custom_migrations/mod.rs
create mode 100644 runtimes/base/src/custom_migrations/unhashed_migration.rs
diff --git a/Cargo.lock b/Cargo.lock
index bba3f4261..a7555f535 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -7472,6 +7472,7 @@ dependencies = [
name = "polimec-base-runtime"
version = "0.5.1"
dependencies = [
+ "array-bytes",
"cumulus-pallet-aura-ext",
"cumulus-pallet-dmp-queue",
"cumulus-pallet-parachain-system",
@@ -7488,6 +7489,7 @@ dependencies = [
"frame-system-benchmarking",
"frame-system-rpc-runtime-api",
"frame-try-runtime",
+ "hex-literal 0.3.4",
"log",
"orml-oracle",
"pallet-assets",
diff --git a/Cargo.toml b/Cargo.toml
index 764c610a7..a4f629706 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -87,6 +87,7 @@ serde = { version = "1.0.188", default-features = false }
smallvec = "1.11.0"
log = { version = "0.4.17", default-features = false }
itertools = { version = "0.11.0", default-features = false, features = ["use_alloc"] }
+array-bytes = { version = "*", default-features = false }
# Emulations
xcm-emulator = { git = "https://github.com/paritytech/cumulus", default-features = false, branch = "release-v1.0.0" }
diff --git a/runtimes/base/Cargo.toml b/runtimes/base/Cargo.toml
index 778e3c29f..c45af7b29 100644
--- a/runtimes/base/Cargo.toml
+++ b/runtimes/base/Cargo.toml
@@ -14,11 +14,11 @@ version.workspace = true
substrate-wasm-builder.workspace = true
[dependencies]
-parity-scale-codec = { workspace= true, default-features = false, features = [
+parity-scale-codec = { workspace = true, default-features = false, features = [
"derive",
] }
log.workspace = true
-scale-info = { workspace= true, default-features = false, features = [
+scale-info = { workspace = true, default-features = false, features = [
"derive",
] }
@@ -93,6 +93,10 @@ parachains-common.workspace = true
# ORML
orml-oracle.workspace = true
+# Migration utilities
+hex-literal = { workspace = true }
+array-bytes = { workspace = true, default-features = false }
+
[features]
default = [ "std" ]
fast-mode = [ "shared-configuration/fast-mode" ]
diff --git a/runtimes/base/src/custom_migrations/deposit_dust.rs b/runtimes/base/src/custom_migrations/deposit_dust.rs
new file mode 100644
index 000000000..880bf6528
--- /dev/null
+++ b/runtimes/base/src/custom_migrations/deposit_dust.rs
@@ -0,0 +1,61 @@
+// Polimec Blockchain – https://www.polimec.org/
+// Copyright (C) Polimec 2022. All rights reserved.
+
+// The Polimec Blockchain is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// The Polimec Blockchain is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#[allow(unused_imports)]
+use crate::*;
+
+// Substrate
+use frame_support::{log, traits::tokens::Precision::Exact};
+
+pub struct DepositDust;
+impl frame_support::traits::OnRuntimeUpgrade for DepositDust {
+ #[cfg(feature = "try-runtime")]
+ fn pre_upgrade() -> Result, sp_runtime::DispatchError> {
+ log::info!("Pre-upgrade");
+ Ok(Vec::new())
+ }
+
+ #[cfg(feature = "try-runtime")]
+ fn post_upgrade(_state: Vec) -> Result<(), sp_runtime::DispatchError> {
+ log::info!("Post-upgrade");
+ let total_issuance = Balances::total_issuance();
+ assert_eq!(total_issuance, 100_000_000 * PLMC);
+ Ok(())
+ }
+
+ fn on_runtime_upgrade() -> frame_support::weights::Weight {
+ // +1 R
+ let total_issuance = Balances::total_issuance();
+
+ // Idempotent check.
+ if total_issuance != 100_000_000 * PLMC {
+ log::info!("⚠️ Correcting total issuance from {} to {}", total_issuance, 100_000_000 * PLMC);
+ // +1 R
+ let treasury_account = PayMaster::get();
+ // +1 W
+ // The values are coming from these `DustLost` events:
+ // - https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Frpc.polimec.org#/explorer/query/0x6fec4ce782f42afae1437f53e3382d9e6804692de868a28908ed6b9104bdd536
+ // - https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Frpc.polimec.org#/explorer/query/0x390d04247334df9d9eb02e1dc7c6d01910c950d99a5d8d17441eb202cd751f42
+ let _ = >::deposit(
+ &treasury_account,
+ 39988334 + 70094167,
+ Exact,
+ );
+ }
+
+ ::DbWeight::get().reads_writes(2, 1)
+ }
+}
diff --git a/runtimes/base/src/custom_migrations.rs b/runtimes/base/src/custom_migrations/init_pallet.rs
similarity index 91%
rename from runtimes/base/src/custom_migrations.rs
rename to runtimes/base/src/custom_migrations/init_pallet.rs
index ccd2e69fc..b5d2479cd 100644
--- a/runtimes/base/src/custom_migrations.rs
+++ b/runtimes/base/src/custom_migrations/init_pallet.rs
@@ -18,13 +18,10 @@
use crate::*;
// Substrate
-#[allow(unused_imports)]
-use frame_support::{
- dispatch::DispatchError,
- log, migration,
- storage::unhashed,
- traits::{GetStorageVersion, PalletInfoAccess, StorageVersion},
-};
+use frame_support::traits::{GetStorageVersion, PalletInfoAccess, StorageVersion};
+
+#[cfg(feature = "try-runtime")]
+use frame_support::dispatch::DispatchError;
pub struct InitializePallet + PalletInfoAccess>(
sp_std::marker::PhantomData,
diff --git a/runtimes/base/src/custom_migrations/mod.rs b/runtimes/base/src/custom_migrations/mod.rs
new file mode 100644
index 000000000..78b2f04e5
--- /dev/null
+++ b/runtimes/base/src/custom_migrations/mod.rs
@@ -0,0 +1,22 @@
+// Polimec Blockchain – https://www.polimec.org/
+// Copyright (C) Polimec 2022. All rights reserved.
+
+// The Polimec Blockchain is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// The Polimec Blockchain is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+// the generated files do not pass clippy
+#![allow(clippy::all)]
+
+pub mod deposit_dust;
+pub mod init_pallet;
+pub mod unhashed_migration;
diff --git a/runtimes/base/src/custom_migrations/unhashed_migration.rs b/runtimes/base/src/custom_migrations/unhashed_migration.rs
new file mode 100644
index 000000000..a2acb28b5
--- /dev/null
+++ b/runtimes/base/src/custom_migrations/unhashed_migration.rs
@@ -0,0 +1,101 @@
+// Polimec Blockchain – https://www.polimec.org/
+// Copyright (C) Polimec 2022. All rights reserved.
+
+// The Polimec Blockchain is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// The Polimec Blockchain is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#[allow(unused_imports)]
+use crate::*;
+
+// Substrate
+use frame_support::{log, storage::unhashed};
+use sp_runtime::AccountId32;
+
+#[cfg(feature = "try-runtime")]
+use sp_core::crypto::Ss58Codec;
+
+#[cfg(feature = "try-runtime")]
+use pallet_vesting::Vesting;
+
+// The `VestingInfo` fields from `pallet_vesting` are private, so we need to define them here.
+#[derive(parity_scale_codec::Encode, parity_scale_codec::Decode, sp_runtime::RuntimeDebug, Eq, PartialEq)]
+struct VestingInfo {
+ locked: Balance,
+ per_block: Balance,
+ starting_block: BlockNumber,
+}
+
+pub struct UnhashedMigration;
+impl frame_support::traits::OnRuntimeUpgrade for UnhashedMigration {
+ #[cfg(feature = "try-runtime")]
+ fn pre_upgrade() -> Result, sp_runtime::DispatchError> {
+ log::info!("Pre-upgrade");
+ check_balances();
+ Ok(Vec::new())
+ }
+
+ #[cfg(feature = "try-runtime")]
+ fn post_upgrade(_state: Vec) -> Result<(), sp_runtime::DispatchError> {
+ log::info!("Post-upgrade");
+ check_balances();
+ Ok(())
+ }
+
+ fn on_runtime_upgrade() -> frame_support::weights::Weight {
+ // This account received a wrong vesting schedule.
+ // Hex encoded representation of 5Ag8zhuoZjKzc3YzmkWFrrmU5GvxdHLtpAN425RW9ZgWS5V7.
+ let acct: AccountId32 =
+ hex_literal::hex!["c28dbf096b5acf3c0d87dd8ef8cabea0794cc72200a2368751a0fe470d5f9f69"].into();
+
+ // The vesting.Vesting(5Ag8zhuoZjKzc3YzmkWFrrmU5GvxdHLtpAN425RW9ZgWS5V7) encoded storage key.
+ const ENCODED_STORAGE_KEY: &str =
+"0x5f27b51b5ec208ee9cb25b55d87282435f27b51b5ec208ee9cb25b55d872824334f5503ce555ea3ee18396f4bde1b40bc28dbf096b5acf3c0d87dd8ef8cabea0794cc72200a2368751a0fe470d5f9f69";
+
+ if let Ok(k) = array_bytes::hex2bytes(ENCODED_STORAGE_KEY) {
+ // If `is_some` which means it has a vesting schedule, that we could potentially have to correct.
+ // +1 R
+ if let Some(value) = unhashed::get::>(&k) {
+ let v = vec![
+ VestingInfo { locked: 119574300000000, per_block: 182000456, starting_block: 249000 },
+ VestingInfo { locked: 6485400000000, per_block: 9870000, starting_block: 249000 },
+ ];
+ // Idempotent check.
+ if value != v {
+ log::info!("⚠️ Correcting storage for {:?}", acct.encode());
+ // +1 W
+ unhashed::put::>(&k, &v);
+ } else {
+ log::info!("✅ Storage for {:?} is already correct", acct.encode());
+ }
+ }
+ }
+
+ ::DbWeight::get().reads_writes(1, 1)
+ }
+}
+
+#[cfg(feature = "try-runtime")]
+fn check_balances() {
+ let acct: AccountId32 =
+ hex_literal::hex!["c28dbf096b5acf3c0d87dd8ef8cabea0794cc72200a2368751a0fe470d5f9f69"].into();
+ let balance = Balances::balance(&acct);
+ log::info!("Account: {} | Balance: {}", acct.to_ss58check(), balance);
+ let vesting_stored = >::get(acct.clone());
+ if let Some(vesting) = vesting_stored {
+ log::info!("Vesting: {:?}", vesting);
+ } else {
+ log::info!("Vesting: None");
+ }
+ let total_issuance = Balances::total_issuance();
+ log::info!("Total Issuance: {}", total_issuance);
+}
diff --git a/runtimes/base/src/lib.rs b/runtimes/base/src/lib.rs
index 8067efc46..6629d60d9 100644
--- a/runtimes/base/src/lib.rs
+++ b/runtimes/base/src/lib.rs
@@ -136,16 +136,11 @@ pub type Migrations = migrations::Unreleased;
#[allow(missing_docs)]
pub mod migrations {
// Not warn for unused imports in this module.
- #![allow(unused_imports)]
- use frame_support::migrations::RemovePallet;
- parameter_types! {
- pub const Sudo: &'static str = "Sudo";
- }
+ use crate::custom_migrations::{deposit_dust::DepositDust, unhashed_migration::UnhashedMigration};
- use super::*;
/// Unreleased migrations. Add new ones here:
- pub type Unreleased = (RemovePallet,);
+ pub type Unreleased = (UnhashedMigration, DepositDust);
}
/// Executive: handles dispatch to the various modules.
@@ -195,7 +190,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
spec_name: create_runtime_str!("polimec-mainnet"),
impl_name: create_runtime_str!("polimec-mainnet"),
authoring_version: 1,
- spec_version: 0_005_006,
+ spec_version: 0_005_007,
impl_version: 0,
apis: RUNTIME_API_VERSIONS,
transaction_version: 1,
diff --git a/runtimes/testnet/Cargo.toml b/runtimes/testnet/Cargo.toml
index f6d688a4a..09e3786b8 100644
--- a/runtimes/testnet/Cargo.toml
+++ b/runtimes/testnet/Cargo.toml
@@ -168,6 +168,7 @@ std = [
"sp-block-builder/std",
"sp-consensus-aura/std",
"sp-core/std",
+ "sp-debug-derive/std",
"sp-inherents/std",
"sp-io/std",
"sp-offchain/std",
@@ -179,7 +180,6 @@ std = [
"xcm-builder/std",
"xcm-executor/std",
"xcm/std",
- "sp-debug-derive/std"
]
runtime-benchmarks = [