diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs
index 1d460762e43c81f9a3964b4610b1011564ea3d5e..a98b1700fe1aa15c9aa10dbf326f91ebd26fa072 100644
--- a/substrate/bin/node/runtime/src/lib.rs
+++ b/substrate/bin/node/runtime/src/lib.rs
@@ -82,8 +82,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
 	// and set impl_version to 0. If only runtime
 	// implementation changes and behavior does not, then leave spec_version as
 	// is and increment impl_version.
-	spec_version: 220,
-	impl_version: 1,
+	spec_version: 221,
+	impl_version: 0,
 	apis: RUNTIME_API_VERSIONS,
 };
 
diff --git a/substrate/frame/recovery/src/lib.rs b/substrate/frame/recovery/src/lib.rs
index b456d17c68d8173760e1d9e60d5ff2f32c65069a..6fa00af751e67cb33b0b05f8dd3b189083989462 100644
--- a/substrate/frame/recovery/src/lib.rs
+++ b/substrate/frame/recovery/src/lib.rs
@@ -160,10 +160,7 @@ use codec::{Encode, Decode};
 use frame_support::{
 	decl_module, decl_event, decl_storage, decl_error, ensure,
 	Parameter, RuntimeDebug,
-	weights::{
-		GetDispatchInfo, PaysFee, DispatchClass, ClassifyDispatch, Weight, WeighData,
-		SimpleDispatchInfo,
-	},
+	weights::{GetDispatchInfo, SimpleDispatchInfo, FunctionOf},
 	traits::{Currency, ReservableCurrency, Get, OnReapAccount, BalanceStatus},
 };
 use frame_system::{self as system, ensure_signed, ensure_root};
@@ -331,10 +328,14 @@ decl_module! {
 		/// - `call`: The call you want to make with the recovered account.
 		///
 		/// # <weight>
-		/// - The weight of the `call`.
+		/// - The weight of the `call` + 10,000.
 		/// - One storage lookup to check account is recovered by `who`. O(1)
 		/// # </weight>
-		#[weight = <Passthrough<T::AccountId, <T as Trait>::Call>>::new()]
+		#[weight = FunctionOf(
+			|args: (&T::AccountId, &Box<<T as Trait>::Call>)| args.1.get_dispatch_info().weight + 10_000, 
+			|args: (&T::AccountId, &Box<<T as Trait>::Call>)| args.1.get_dispatch_info().class,
+			true
+		)]
 		fn as_recovered(origin,
 			account: T::AccountId,
 			call: Box<<T as Trait>::Call>
@@ -646,25 +647,3 @@ impl<T: Trait> OnReapAccount<T::AccountId> for Module<T> {
 		<Recovered<T>>::remove(who);
 	}
 }
-
-/// Simple pass through for the weight functions.
-struct Passthrough<AccountId, Call>(sp_std::marker::PhantomData<(AccountId, Call)>);
-
-impl<AccountId, Call> Passthrough<AccountId, Call> {
-	fn new() -> Self { Self(Default::default()) }
-}
-impl<AccountId, Call: GetDispatchInfo> WeighData<(&AccountId, &Box<Call>)> for Passthrough<AccountId, Call> {
-	fn weigh_data(&self, (_, call): (&AccountId, &Box<Call>)) -> Weight {
-		call.get_dispatch_info().weight + 10_000
-	}
-}
-impl<AccountId, Call: GetDispatchInfo> ClassifyDispatch<(&AccountId, &Box<Call>)> for Passthrough<AccountId, Call> {
-	fn classify_dispatch(&self, (_, call): (&AccountId, &Box<Call>)) -> DispatchClass {
-		call.get_dispatch_info().class
-	}
-}
-impl<AccountId, Call: GetDispatchInfo> PaysFee<(&AccountId, &Box<Call>)> for Passthrough<AccountId, Call> {
-	fn pays_fee(&self, (_, call): (&AccountId, &Box<Call>)) -> bool {
-		call.get_dispatch_info().pays_fee
-	}
-}
diff --git a/substrate/frame/utility/src/lib.rs b/substrate/frame/utility/src/lib.rs
index c19b044ad769763d9af0fd1d1fd1c9aadf95804c..501e04ad55878ca0070b2223f63b85f09c8a1fbe 100644
--- a/substrate/frame/utility/src/lib.rs
+++ b/substrate/frame/utility/src/lib.rs
@@ -66,9 +66,9 @@ use codec::{Encode, Decode};
 use sp_core::TypeId;
 use sp_io::hashing::blake2_256;
 use frame_support::{decl_module, decl_event, decl_error, decl_storage, Parameter, ensure, RuntimeDebug};
-use frame_support::{traits::{Get, ReservableCurrency, Currency}, weights::{
-	GetDispatchInfo, ClassifyDispatch, WeighData, Weight, DispatchClass, PaysFee
-}};
+use frame_support::{traits::{Get, ReservableCurrency, Currency},
+	weights::{GetDispatchInfo, DispatchClass,FunctionOf},
+};
 use frame_system::{self as system, ensure_signed};
 use sp_runtime::{DispatchError, DispatchResult, traits::Dispatchable};
 
@@ -188,126 +188,6 @@ decl_event! {
 	}
 }
 
-/// Simple index-based pass through for the weight functions.
-struct Passthrough<Call>(sp_std::marker::PhantomData<Call>);
-
-impl<Call> Passthrough<Call> {
-	fn new() -> Self { Self(Default::default()) }
-}
-impl<Call: GetDispatchInfo> WeighData<(&u16, &Box<Call>)> for Passthrough<Call> {
-	fn weigh_data(&self, (_, call): (&u16, &Box<Call>)) -> Weight {
-		call.get_dispatch_info().weight + 10_000
-	}
-}
-impl<Call: GetDispatchInfo> ClassifyDispatch<(&u16, &Box<Call>)> for Passthrough<Call> {
-	fn classify_dispatch(&self, (_, call): (&u16, &Box<Call>)) -> DispatchClass {
-		call.get_dispatch_info().class
-	}
-}
-impl<Call: GetDispatchInfo> PaysFee<(&u16, &Box<Call>)> for Passthrough<Call> {
-	fn pays_fee(&self, (_, call): (&u16, &Box<Call>)) -> bool {
-		call.get_dispatch_info().pays_fee
-	}
-}
-
-/// Summation pass-through for the weight function of the batch call.
-///
-/// This just adds all of the weights together of all of the calls.
-struct BatchPassthrough<Call>(sp_std::marker::PhantomData<Call>);
-
-impl<Call> BatchPassthrough<Call> {
-	fn new() -> Self { Self(Default::default()) }
-}
-impl<Call: GetDispatchInfo> WeighData<(&Vec<Call>,)> for BatchPassthrough<Call> {
-	fn weigh_data(&self, (calls,): (&Vec<Call>,)) -> Weight {
-		calls.iter()
-			.map(|call| call.get_dispatch_info().weight)
-			.fold(10_000, |a, n| a + n)
-	}
-}
-impl<Call: GetDispatchInfo> ClassifyDispatch<(&Vec<Call>,)> for BatchPassthrough<Call> {
-	fn classify_dispatch(&self, (calls,): (&Vec<Call>,)) -> DispatchClass {
-		let all_operational = calls.iter()
-			.map(|call| call.get_dispatch_info().class)
-			.all(|class| class == DispatchClass::Operational);
-		if all_operational {
-			DispatchClass::Operational
-		} else {
-			DispatchClass::Normal
-		}
-	}
-}
-impl<Call: GetDispatchInfo> PaysFee<(&Vec<Call>,)> for BatchPassthrough<Call> {
-	fn pays_fee(&self, (calls,): (&Vec<Call>,)) -> bool {
-		calls.iter()
-			.any(|call| call.get_dispatch_info().pays_fee)
-	}
-}
-
-/// Simple index-based pass through for the weight functions.
-struct MultiPassthrough<Call, AccountId, Timepoint>(
-	sp_std::marker::PhantomData<(Call, AccountId, Timepoint)>
-);
-
-impl<Call, AccountId, Timepoint> MultiPassthrough<Call, AccountId, Timepoint> {
-	fn new() -> Self { Self(Default::default()) }
-}
-impl<Call: GetDispatchInfo, AccountId, Timepoint> WeighData<(&u16, &Vec<AccountId>, &Timepoint, &Box<Call>)>
-for MultiPassthrough<Call, AccountId, Timepoint>
-{
-	fn weigh_data(&self, (_, sigs, _, call): (&u16, &Vec<AccountId>, &Timepoint, &Box<Call>)) -> Weight {
-		call.get_dispatch_info().weight + 10_000 * (sigs.len() as u32 + 1)
-	}
-}
-impl<Call: GetDispatchInfo, AccountId, Timepoint> ClassifyDispatch<(&u16, &Vec<AccountId>, &Timepoint, &Box<Call>)>
-for MultiPassthrough<Call, AccountId, Timepoint>
-{
-	fn classify_dispatch(&self, (_, _, _, call): (&u16, &Vec<AccountId>, &Timepoint, &Box<Call>))
-		-> DispatchClass
-	{
-		call.get_dispatch_info().class
-	}
-}
-impl<Call: GetDispatchInfo, AccountId, Timepoint> PaysFee<(&u16, &Vec<AccountId>, &Timepoint, &Box<Call>)>
-for MultiPassthrough<Call, AccountId, Timepoint>
-{
-	fn pays_fee(&self, _: (&u16, &Vec<AccountId>, &Timepoint, &Box<Call>)) -> bool {
-		true
-	}
-}
-
-/// Simple index-based pass through for the weight functions.
-struct SigsLen<AccountId, Timepoint>(
-	sp_std::marker::PhantomData<(AccountId, Timepoint)>
-);
-
-impl<AccountId, Timepoint> SigsLen<AccountId, Timepoint> {
-	fn new() -> Self { Self(Default::default()) }
-}
-impl<AccountId, Timepoint> WeighData<(&u16, &Vec<AccountId>, &Timepoint, &[u8; 32])>
-for SigsLen<AccountId, Timepoint>
-{
-	fn weigh_data(&self, (_, sigs, _, _): (&u16, &Vec<AccountId>, &Timepoint, &[u8; 32])) -> Weight {
-		10_000 * (sigs.len() as u32 + 1)
-	}
-}
-impl<AccountId, Timepoint> ClassifyDispatch<(&u16, &Vec<AccountId>, &Timepoint, &[u8; 32])>
-for SigsLen<AccountId, Timepoint>
-{
-	fn classify_dispatch(&self, _: (&u16, &Vec<AccountId>, &Timepoint, &[u8; 32]))
-		-> DispatchClass
-	{
-		DispatchClass::Normal
-	}
-}
-impl<AccountId, Timepoint> PaysFee<(&u16, &Vec<AccountId>, &Timepoint, &[u8; 32])>
-for SigsLen<AccountId, Timepoint>
-{
-	fn pays_fee(&self, _: (&u16, &Vec<AccountId>, &Timepoint, &[u8; 32])) -> bool {
-		true
-	}
-}
-
 /// A module identifier. These are per module and should be stored in a registry somewhere.
 #[derive(Clone, Copy, Eq, PartialEq, Encode, Decode)]
 struct IndexedUtilityModuleId(u16);
@@ -341,7 +221,24 @@ decl_module! {
 		/// `BatchInterrupted` event is deposited, along with the number of successful calls made
 		/// and the error of the failed call. If all were successful, then the `BatchCompleted`
 		/// event is deposited.
-		#[weight = <BatchPassthrough<<T as Trait>::Call>>::new()]
+		#[weight = FunctionOf(
+			|args: (&Vec<<T as Trait>::Call>,)| {
+				args.0.iter()
+					.map(|call| call.get_dispatch_info().weight)
+					.fold(10_000, |a, n| a + n)
+			},
+			|args: (&Vec<<T as Trait>::Call>,)| {
+				let all_operational = args.0.iter()
+					.map(|call| call.get_dispatch_info().class)
+					.all(|class| class == DispatchClass::Operational);
+				if all_operational {
+					DispatchClass::Operational
+				} else {
+					DispatchClass::Normal
+				}
+			},
+			true
+		)]
 		fn batch(origin, calls: Vec<<T as Trait>::Call>) {
 			for (index, call) in calls.into_iter().enumerate() {
 				let result = call.dispatch(origin.clone());
@@ -358,9 +255,13 @@ decl_module! {
 		/// The dispatch origin for this call must be _Signed_.
 		///
 		/// # <weight>
-		/// - The weight of the `call`.
+		/// - The weight of the `call` + 10,000.
 		/// # </weight>
-		#[weight = <Passthrough<<T as Trait>::Call>>::new()]
+		#[weight = FunctionOf(
+			|args: (&u16, &Box<<T as Trait>::Call>)| args.1.get_dispatch_info().weight + 10_000, 
+			|args: (&u16, &Box<<T as Trait>::Call>)| args.1.get_dispatch_info().class,
+			true
+		)]
 		fn as_sub(origin, index: u16, call: Box<<T as Trait>::Call>) -> DispatchResult {
 			let who = ensure_signed(origin)?;
 			let pseudonym = Self::sub_account_id(who, index);
@@ -408,7 +309,15 @@ decl_module! {
 		///   deposit taken for its lifetime of
 		///   `MultisigDepositBase + threshold * MultisigDepositFactor`.
 		/// # </weight>
-		#[weight = <MultiPassthrough<<T as Trait>::Call, T::AccountId, Option<Timepoint<T::BlockNumber>>>>::new()]
+		#[weight = FunctionOf(
+			|args: (&u16, &Vec<T::AccountId>, &Option<Timepoint<T::BlockNumber>>, &Box<<T as Trait>::Call>)| {
+				args.3.get_dispatch_info().weight + 10_000 * (args.1.len() as u32 + 1)
+			},
+			|args: (&u16, &Vec<T::AccountId>, &Option<Timepoint<T::BlockNumber>>, &Box<<T as Trait>::Call>)| {
+				args.3.get_dispatch_info().class
+			},
+			true
+		)]
 		fn as_multi(origin,
 			threshold: u16,
 			other_signatories: Vec<T::AccountId>,
@@ -498,7 +407,13 @@ decl_module! {
 		///   deposit taken for its lifetime of
 		///   `MultisigDepositBase + threshold * MultisigDepositFactor`.
 		/// # </weight>
-		#[weight = <SigsLen<T::AccountId, Option<Timepoint<T::BlockNumber>>>>::new()]
+		#[weight = FunctionOf(
+			|args: (&u16, &Vec<T::AccountId>, &Option<Timepoint<T::BlockNumber>>, &[u8; 32])| {
+				10_000 * (args.1.len() as u32 + 1)
+			}, 
+			DispatchClass::Normal,
+			true
+		)]
 		fn approve_as_multi(origin,
 			threshold: u16,
 			other_signatories: Vec<T::AccountId>,
@@ -567,7 +482,13 @@ decl_module! {
 		/// - I/O: 1 read `O(S)`, one remove.
 		/// - Storage: removes one item.
 		/// # </weight>
-		#[weight = <SigsLen<T::AccountId, Timepoint<T::BlockNumber>>>::new()]
+		#[weight = FunctionOf(
+			|args: (&u16, &Vec<T::AccountId>, &Timepoint<T::BlockNumber>, &[u8; 32])| {
+				10_000 * (args.1.len() as u32 + 1)
+			}, 
+			DispatchClass::Normal,
+			true
+		)]
 		fn cancel_as_multi(origin,
 			threshold: u16,
 			other_signatories: Vec<T::AccountId>,