From 0f0df9850ae5c85cdbb13cfcd5672ddb5ad75a34 Mon Sep 17 00:00:00 2001
From: Xiliang Chen <xlchen1291@gmail.com>
Date: Thu, 8 Aug 2019 19:56:04 +1200
Subject: [PATCH] add post_dispatch (#3229)

* add post_dispatch

* Update traits.rs

* Update checked_extrinsic.rs

* Update traits.rs

* Update traits.rs

* fix build issue

* update runtime version

* fix test build issue
---
 .../src/generic/checked_extrinsic.rs          | 14 ++++---
 .../src/generic/unchecked_extrinsic.rs        |  2 +
 substrate/core/sr-primitives/src/traits.rs    | 37 ++++++++++++++-----
 substrate/node/runtime/src/lib.rs             |  4 +-
 substrate/srml/balances/src/lib.rs            |  1 +
 substrate/srml/system/src/lib.rs              |  6 +++
 6 files changed, 46 insertions(+), 18 deletions(-)

diff --git a/substrate/core/sr-primitives/src/generic/checked_extrinsic.rs b/substrate/core/sr-primitives/src/generic/checked_extrinsic.rs
index 44a07582674..08d7b103867 100644
--- a/substrate/core/sr-primitives/src/generic/checked_extrinsic.rs
+++ b/substrate/core/sr-primitives/src/generic/checked_extrinsic.rs
@@ -77,14 +77,16 @@ where
 		info: DispatchInfo,
 		len: usize,
 	) -> Result<DispatchResult, DispatchError> {
-		let maybe_who = if let Some((id, extra)) = self.signed {
-			Extra::pre_dispatch(extra, &id, &self.function, info, len)?;
-			Some(id)
+		let (maybe_who, pre) = if let Some((id, extra)) = self.signed {
+			let pre = Extra::pre_dispatch(extra, &id, &self.function, info, len)?;
+			(Some(id), pre)
 		} else {
-			Extra::pre_dispatch_unsigned(&self.function, info, len)?;
-			None
+			let pre = Extra::pre_dispatch_unsigned(&self.function, info, len)?;
+			(None, pre)
 		};
-		Ok(self.function.dispatch(Origin::from(maybe_who)))
+		let res = self.function.dispatch(Origin::from(maybe_who));
+		Extra::post_dispatch(pre, info, len);
+		Ok(res)
 	}
 }
 
diff --git a/substrate/core/sr-primitives/src/generic/unchecked_extrinsic.rs b/substrate/core/sr-primitives/src/generic/unchecked_extrinsic.rs
index 17157c4a19b..cb9330cfaaf 100644
--- a/substrate/core/sr-primitives/src/generic/unchecked_extrinsic.rs
+++ b/substrate/core/sr-primitives/src/generic/unchecked_extrinsic.rs
@@ -236,6 +236,8 @@ mod tests {
 		type AccountId = u64;
 		type Call = ();
 		type AdditionalSigned = ();
+		type Pre = ();
+
 		fn additional_signed(&self) -> rstd::result::Result<(), &'static str> { Ok(()) }
 	}
 
diff --git a/substrate/core/sr-primitives/src/traits.rs b/substrate/core/sr-primitives/src/traits.rs
index 442aa9b0ac8..7272bd3488b 100644
--- a/substrate/core/sr-primitives/src/traits.rs
+++ b/substrate/core/sr-primitives/src/traits.rs
@@ -808,6 +808,9 @@ pub trait SignedExtension:
 	/// from the transaction using the `additional_signed` function.
 	type AdditionalSigned: Encode;
 
+	/// The type that encodes information that can be passed from pre_dispatch to post-dispatch.
+	type Pre: Default;
+
 	/// Construct any additional data that should be in the signed payload of the transaction. Can
 	/// also perform any pre-signature-verification checks and return an error if needed.
 	fn additional_signed(&self) -> Result<Self::AdditionalSigned, &'static str>;
@@ -830,8 +833,8 @@ pub trait SignedExtension:
 		call: &Self::Call,
 		info: DispatchInfo,
 		len: usize,
-	) -> Result<(), DispatchError> {
-		self.validate(who, call, info, len).map(|_| ())
+	) -> Result<Self::Pre, DispatchError> {
+		self.validate(who, call, info, len).map(|_| Self::Pre::default())
 	}
 
 	/// Validate an unsigned transaction for the transaction queue. Normally the default
@@ -848,9 +851,16 @@ pub trait SignedExtension:
 		call: &Self::Call,
 		info: DispatchInfo,
 		len: usize,
-	) -> Result<(), DispatchError> {
-		Self::validate_unsigned(call, info, len).map(|_| ())
+	) -> Result<Self::Pre, DispatchError> {
+		Self::validate_unsigned(call, info, len).map(|_| Self::Pre::default())
 	}
+
+	/// Do any post-flight stuff for a transaction.
+	fn post_dispatch(
+		_pre: Self::Pre,
+		_info: DispatchInfo,
+		_len: usize,
+	) { }
 }
 
 macro_rules! tuple_impl_indexed {
@@ -866,6 +876,7 @@ macro_rules! tuple_impl_indexed {
 			type AccountId = AccountId;
 			type Call = Call;
 			type AdditionalSigned = ($($direct::AdditionalSigned,)+);
+			type Pre =  ($($direct::Pre,)+);
 			fn additional_signed(&self) -> Result<Self::AdditionalSigned, &'static str> {
 				Ok(( $(self.$index.additional_signed()?,)+ ))
 			}
@@ -885,9 +896,8 @@ macro_rules! tuple_impl_indexed {
 				call: &Self::Call,
 				info: DispatchInfo,
 				len: usize,
-			) -> Result<(), DispatchError> {
-				$(self.$index.pre_dispatch(who, call, info, len)?;)+
-				Ok(())
+			) -> Result<Self::Pre, DispatchError> {
+				Ok(($(self.$index.pre_dispatch(who, call, info, len)?,)+))
 			}
 			fn validate_unsigned(
 				call: &Self::Call,
@@ -901,9 +911,15 @@ macro_rules! tuple_impl_indexed {
 				call: &Self::Call,
 				info: DispatchInfo,
 				len: usize,
-			) -> Result<(), DispatchError> {
-				$($direct::pre_dispatch_unsigned(call, info, len)?;)+
-				Ok(())
+			) -> Result<Self::Pre, DispatchError> {
+				Ok(($($direct::pre_dispatch_unsigned(call, info, len)?,)+))
+			}
+			fn post_dispatch(
+				pre: Self::Pre,
+				info: DispatchInfo,
+				len: usize,
+			) {
+				$($direct::post_dispatch(pre.$index, info, len);)+
 			}
 		}
 
@@ -931,6 +947,7 @@ impl SignedExtension for () {
 	type AccountId = u64;
 	type AdditionalSigned = ();
 	type Call = ();
+	type Pre = ();
 	fn additional_signed(&self) -> rstd::result::Result<(), &'static str> { Ok(()) }
 }
 
diff --git a/substrate/node/runtime/src/lib.rs b/substrate/node/runtime/src/lib.rs
index 9f247c63203..05d6845a570 100644
--- a/substrate/node/runtime/src/lib.rs
+++ b/substrate/node/runtime/src/lib.rs
@@ -80,8 +80,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
 	// and set impl_version to equal spec_version. If only runtime
 	// implementation changes and behavior does not, then leave spec_version as
 	// is and increment impl_version.
-	spec_version: 134,
-	impl_version: 134,
+	spec_version: 135,
+	impl_version: 135,
 	apis: RUNTIME_API_VERSIONS,
 };
 
diff --git a/substrate/srml/balances/src/lib.rs b/substrate/srml/balances/src/lib.rs
index 4d0306af28e..66d0ee02849 100644
--- a/substrate/srml/balances/src/lib.rs
+++ b/substrate/srml/balances/src/lib.rs
@@ -1216,6 +1216,7 @@ impl<T: Trait<I>, I: Instance + Clone + Eq> SignedExtension for TakeFees<T, I> {
 	type AccountId = T::AccountId;
 	type Call = T::Call;
 	type AdditionalSigned = ();
+	type Pre = ();
 	fn additional_signed(&self) -> rstd::result::Result<(), &'static str> { Ok(()) }
 
 	fn validate(
diff --git a/substrate/srml/system/src/lib.rs b/substrate/srml/system/src/lib.rs
index f41a566724c..571ec6ad6ce 100644
--- a/substrate/srml/system/src/lib.rs
+++ b/substrate/srml/system/src/lib.rs
@@ -881,6 +881,7 @@ impl<T: Trait + Send + Sync> SignedExtension for CheckWeight<T> {
 	type AccountId = T::AccountId;
 	type Call = T::Call;
 	type AdditionalSigned = ();
+	type Pre = ();
 
 	fn additional_signed(&self) -> rstd::result::Result<(), &'static str> { Ok(()) }
 
@@ -944,6 +945,7 @@ impl<T: Trait> SignedExtension for CheckNonce<T> {
 	type AccountId = T::AccountId;
 	type Call = T::Call;
 	type AdditionalSigned = ();
+	type Pre = ();
 
 	fn additional_signed(&self) -> rstd::result::Result<(), &'static str> { Ok(()) }
 
@@ -1017,6 +1019,8 @@ impl<T: Trait + Send + Sync> SignedExtension for CheckEra<T> {
 	type AccountId = T::AccountId;
 	type Call = T::Call;
 	type AdditionalSigned = T::Hash;
+	type Pre = ();
+
 	fn additional_signed(&self) -> Result<Self::AdditionalSigned, &'static str> {
 		let current_u64 = <Module<T>>::block_number().saturated_into::<u64>();
 		let n = (self.0).0.birth(current_u64).saturated_into::<T::BlockNumber>();
@@ -1047,6 +1051,8 @@ impl<T: Trait + Send + Sync> SignedExtension for CheckGenesis<T> {
 	type AccountId = T::AccountId;
 	type Call = <T as Trait>::Call;
 	type AdditionalSigned = T::Hash;
+	type Pre = ();
+
 	fn additional_signed(&self) -> Result<Self::AdditionalSigned, &'static str> {
 		Ok(<Module<T>>::block_hash(T::BlockNumber::zero()))
 	}
-- 
GitLab