diff --git a/Cargo.lock b/Cargo.lock index 830157efd38af..e9b609536b29e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4588,6 +4588,7 @@ dependencies = [ "sp-io", "sp-runtime", "sp-std", + "sp-storage", ] [[package]] diff --git a/frame/support/src/storage/migration.rs b/frame/support/src/storage/migration.rs index 8e6beefa8886e..264c3c644e144 100644 --- a/frame/support/src/storage/migration.rs +++ b/frame/support/src/storage/migration.rs @@ -159,7 +159,7 @@ pub fn get_storage_value(module: &[u8], item: &[u8], hash: &[ frame_support::storage::unhashed::get::(&key) } -/// Get a particular value in storage by the `module`, the map's `item` name and the key `hash`. +/// Take a particular value in storage by the `module`, the map's `item` name and the key `hash`. pub fn take_storage_value(module: &[u8], item: &[u8], hash: &[u8]) -> Option { let mut key = vec![0u8; 32 + hash.len()]; key[0..16].copy_from_slice(&Twox128::hash(module)); diff --git a/frame/transaction-payment/Cargo.toml b/frame/transaction-payment/Cargo.toml index e6720e4b54ff4..a969f30086884 100644 --- a/frame/transaction-payment/Cargo.toml +++ b/frame/transaction-payment/Cargo.toml @@ -23,6 +23,7 @@ pallet-transaction-payment-rpc-runtime-api = { version = "2.0.0-dev", default-fe sp-io = { version = "2.0.0-dev", path = "../../primitives/io" } sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } pallet-balances = { version = "2.0.0-dev", path = "../balances" } +sp-storage = { version = "2.0.0-dev", path = "../../primitives/storage" } [features] default = ["std"] diff --git a/frame/transaction-payment/src/lib.rs b/frame/transaction-payment/src/lib.rs index 8e3a9e398d66a..bf55885363f08 100644 --- a/frame/transaction-payment/src/lib.rs +++ b/frame/transaction-payment/src/lib.rs @@ -99,6 +99,20 @@ decl_module! { *fm = T::FeeMultiplierUpdate::convert(*fm) }); } + + fn on_runtime_upgrade() -> Weight { + // TODO: Remove this code after on-chain upgrade from u32 to u64 weights + use sp_runtime::Fixed64; + use frame_support::migration::take_storage_value; + if let Some(old_next_fee_multiplier) = take_storage_value::(b"TransactionPayment", b"NextFeeMultiplier", &[]) { + let raw_multiplier = old_next_fee_multiplier.into_inner() as i128; + // Fixed64 used 10^9 precision, where Fixed128 uses 10^18, so we need to add 9 zeros. + let new_raw_multiplier: i128 = raw_multiplier.saturating_mul(1_000_000_000); + let new_next_fee_multiplier: Fixed128 = Fixed128::from_parts(new_raw_multiplier); + NextFeeMultiplier::put(new_next_fee_multiplier); + } + 0 + } } } @@ -792,4 +806,38 @@ mod tests { assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 100 - 5); }); } + + // TODO Remove after u32 to u64 weights upgrade + #[test] + fn upgrade_to_fixed128_works() { + // TODO You can remove this from dev-dependencies after removing this test + use sp_storage::Storage; + use sp_runtime::Fixed64; + use frame_support::storage::generator::StorageValue; + use frame_support::traits::OnRuntimeUpgrade; + use core::num::NonZeroI128; + + let mut s = Storage::default(); + + let original_multiplier = Fixed64::from_rational(1, 2); + + let data = vec![ + ( + NextFeeMultiplier::storage_value_final_key().to_vec(), + original_multiplier.encode().to_vec() + ), + ]; + + s.top = data.into_iter().collect(); + + sp_io::TestExternalities::new(s).execute_with(|| { + let old_value = NextFeeMultiplier::get(); + assert!(old_value != Fixed128::from_rational(1, NonZeroI128::new(2).unwrap())); + + // Convert Fixed64(.5) to Fixed128(.5) + TransactionPayment::on_runtime_upgrade(); + let new_value = NextFeeMultiplier::get(); + assert_eq!(new_value, Fixed128::from_rational(1, NonZeroI128::new(2).unwrap())); + }); + } } diff --git a/primitives/arithmetic/src/fixed64.rs b/primitives/arithmetic/src/fixed64.rs index 6f7e5fe84249f..af4dbf34e293b 100644 --- a/primitives/arithmetic/src/fixed64.rs +++ b/primitives/arithmetic/src/fixed64.rs @@ -49,9 +49,6 @@ impl Fixed64 { } /// Consume self and return the inner value. - /// - /// This should only be used for testing. - #[cfg(any(feature = "std", test))] pub fn into_inner(self) -> i64 { self.0 } /// Raw constructor. Equal to `parts / 1_000_000_000`.