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 = [