From a9261cf0eff46da4af3206dba958529a78a39a33 Mon Sep 17 00:00:00 2001
From: Nikolay Volf <nikvolf@gmail.com>
Date: Thu, 30 Apr 2020 13:22:52 +0300
Subject: [PATCH] use background task to batch for optimum size (#5832)

---
 substrate/primitives/io/src/batch_verifier.rs | 31 +++++++++++++------
 1 file changed, 22 insertions(+), 9 deletions(-)

diff --git a/substrate/primitives/io/src/batch_verifier.rs b/substrate/primitives/io/src/batch_verifier.rs
index 2a2ad4dd5c5..55598217f6e 100644
--- a/substrate/primitives/io/src/batch_verifier.rs
+++ b/substrate/primitives/io/src/batch_verifier.rs
@@ -107,9 +107,30 @@ impl BatchVerifier {
 	) -> bool {
 		if self.invalid.load(AtomicOrdering::Relaxed) { return false; }
 		self.sr25519_items.push(Sr25519BatchItem { signature, pub_key, message });
+
+		if self.sr25519_items.len() >= 128 {
+			let items = std::mem::replace(&mut self.sr25519_items, vec![]);
+			if self.spawn_verification_task(move || Self::verify_sr25519_batch(items)).is_err() {
+				log::debug!(
+					target: "runtime",
+					"Batch-verification returns false because failed to spawn background task.",
+				);
+	
+				return false;
+			}
+		}
+
 		true
 	}
 
+	fn verify_sr25519_batch(items: Vec<Sr25519BatchItem>) -> bool {
+		let messages = items.iter().map(|item| &item.message[..]).collect();
+		let signatures = items.iter().map(|item| &item.signature).collect();
+		let pub_keys = items.iter().map(|item| &item.pub_key).collect();
+
+		sr25519::verify_batch(messages, signatures, pub_keys)
+	}
+
 	/// Verify all previously pushed signatures since last call and return
 	/// aggregated result.
 	#[must_use]
@@ -124,18 +145,10 @@ impl BatchVerifier {
 			self.sr25519_items.len(),
 		);
 
-		let messages = self.sr25519_items.iter().map(|item| &item.message[..]).collect();
-		let signatures = self.sr25519_items.iter().map(|item| &item.signature).collect();
-		let pub_keys = self.sr25519_items.iter().map(|item| &item.pub_key).collect();
-
-		if !sr25519::verify_batch(messages, signatures, pub_keys) {
-			self.sr25519_items.clear();
-
+		if !Self::verify_sr25519_batch(std::mem::replace(&mut self.sr25519_items, vec![])) {
 			return false;
 		}
 
-		self.sr25519_items.clear();
-
 		if pending.len() > 0 {
 			let (sender, receiver) = std::sync::mpsc::channel();
 			if self.scheduler.spawn_obj(FutureObj::new(async move {
-- 
GitLab