Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.

Commit 10f7356

Browse files
committed
experimental ed25519 parallelization
1 parent a89a531 commit 10f7356

File tree

3 files changed

+46
-9
lines changed

3 files changed

+46
-9
lines changed

Cargo.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

primitives/io/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ sp-runtime-interface = { version = "2.0.0-alpha.2", default-features = false, pa
2222
sp-trie = { version = "2.0.0-alpha.2", optional = true, path = "../../primitives/trie" }
2323
sp-externalities = { version = "0.8.0-alpha.2", optional = true, path = "../externalities" }
2424
log = { version = "0.4.8", optional = true }
25+
futures = { version = "0.3.1", features = ["thread-pool"], optional = true }
26+
lazy_static = { version = "1.4.0", optional = true }
2527

2628
[features]
2729
default = ["std"]
@@ -37,6 +39,8 @@ std = [
3739
"sp-externalities",
3840
"sp-wasm-interface/std",
3941
"log",
42+
"futures",
43+
"lazy_static",
4044
]
4145

4246
# These two features are used for `no_std` builds for the environments which already provides

primitives/io/src/batch_verifier.rs

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
//! This is part of the Substrate runtime.
1818
1919
use sp_core::{ed25519, sr25519, crypto::Pair};
20+
use std::sync::{Arc, atomic::{AtomicBool, AtomicUsize, Ordering as AtomicOrdering}};
2021

2122
#[derive(Debug, Clone)]
2223
struct Ed25519BatchItem {
@@ -32,15 +33,31 @@ struct Sr25519BatchItem {
3233
message: Vec<u8>,
3334
}
3435

35-
#[derive(Debug, Default)]
36+
#[derive(Debug)]
3637
pub struct BatchVerifier {
37-
ed25519_items: Vec<Ed25519BatchItem>,
3838
sr25519_items: Vec<Sr25519BatchItem>,
39+
invalid: Arc<AtomicBool>,
40+
left: Arc<AtomicUsize>,
41+
}
42+
43+
44+
lazy_static::lazy_static! {
45+
static ref LOCAL_POOL: futures::executor::ThreadPool = {
46+
futures::executor::ThreadPool::builder()
47+
.stack_size(16*1024)
48+
.name_prefix("io-background")
49+
.create()
50+
.expect("failed to create background thread pool")
51+
};
3952
}
4053

4154
impl BatchVerifier {
4255
pub fn new() -> Self {
43-
Self::default()
56+
BatchVerifier {
57+
sr25519_items: Default::default(),
58+
invalid: Arc::new(false.into()),
59+
left: Arc::new(0.into()),
60+
}
4461
}
4562

4663
pub fn push_ed25519(
@@ -49,7 +66,18 @@ impl BatchVerifier {
4966
pub_key: ed25519::Public,
5067
message: Vec<u8>,
5168
) {
52-
self.ed25519_items.push(Ed25519BatchItem { signature, pub_key, message });
69+
if self.invalid.load(AtomicOrdering::Relaxed) { return; } // there is already invalid transaction encountered
70+
71+
let invalid_clone = self.invalid.clone();
72+
let left_clone = self.left.clone();
73+
self.left.fetch_add(1, AtomicOrdering::SeqCst);
74+
75+
LOCAL_POOL.spawn_ok(async move {
76+
if !ed25519::Pair::verify(&signature, &message, &pub_key) {
77+
invalid_clone.store(true, AtomicOrdering::Relaxed);
78+
}
79+
left_clone.fetch_sub(1, AtomicOrdering::SeqCst);
80+
});
5381
}
5482

5583
pub fn push_sr25519(
@@ -62,13 +90,16 @@ impl BatchVerifier {
6290
}
6391

6492
pub fn verify_and_clear(&mut self) -> bool {
65-
// TODO: parallel
66-
for ed25519_item in self.ed25519_items.drain(..) {
67-
if !ed25519::Pair::verify(&ed25519_item.signature, &ed25519_item.message, &ed25519_item.pub_key) {
68-
return false;
69-
}
93+
while self.left.load(AtomicOrdering::SeqCst) != 0 {
94+
std::thread::park_timeout(std::time::Duration::from_micros(50));
7095
}
7196

97+
if self.invalid.load(AtomicOrdering::Relaxed) {
98+
self.invalid.store(false, AtomicOrdering::Relaxed);
99+
return false;
100+
}
101+
102+
72103
let sr25519_batch_result = {
73104
let messages = self.sr25519_items.iter().map(|item| &item.message[..]).collect();
74105
let signatures = self.sr25519_items.iter().map(|item| &item.signature).collect();

0 commit comments

Comments
 (0)