mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-26 18:07:58 +00:00
Batch signature verification (#5023)
* create parallel tasks extension * make type system happy * basic externalities * test for dynamic extensions * batching test * remove premature verify_batch * shnschnorrkel batch * alter test * shnschnorrkel test * executive batching * some docs * also multi/any signatgures * error propagation * styling * make verification extension optional * experimental ed25519 parallelization * some merge fallout * utilize task executor * merge fallout * utilize task executor more * another merge fallout * feature-gate sp-io * arrange toml * fix no-std * sr25519 batching and refactoring * add docs * fix name * add newline * fix block import test * long sr25519 test * blocking instead of parking * move everything in crypto * return batch_verify to check :) * use condvars * use multi-threaded executor for benches * don't call via host interface * try no spawning * add true * cleanup * straighten batching * remove signature check from this test (?) * remove now pointless test * remove another now useless test * fix warnings * Revert "remove another now useless test" This reverts commit bbdec24bb67ed4373072daef7c863e1a8825bd8b. * rethink the sp-io-part * Revert "remove now pointless test" This reverts commit 4d553066322e65782264caa6053d4cd5538df977. * fix wording * add wording * add todo and fix * return check and fix * add logging in sp-io * Update primitives/io/src/batch_verifier.rs Co-Authored-By: cheme <emericchevalier.pro@gmail.com> * address review and use std condvar * account for early exit * address reivew * address review * more suggestions * add docs for batch verification * remove unused * more review suggestions * move to sp-runtime * add expects * remove blocks * use entry * Update primitives/io/src/batch_verifier.rs Co-Authored-By: Bastian Köcher <bkchr@users.noreply.github.com> * Update primitives/externalities/src/extensions.rs Co-Authored-By: Bastian Köcher <bkchr@users.noreply.github.com> * update overlooked note * remove stupid return * Update primitives/io/src/lib.rs Co-Authored-By: Bastian Köcher <bkchr@users.noreply.github.com> * Update primitives/io/src/lib.rs Co-Authored-By: Bastian Köcher <bkchr@users.noreply.github.com> * fix wording * bump spec_version Co-authored-by: cheme <emericchevalier.pro@gmail.com> Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>
This commit is contained in:
@@ -24,7 +24,8 @@ use crate::{
|
||||
self, Member, MaybeDisplay, SignedExtension, Checkable, Extrinsic, ExtrinsicMetadata,
|
||||
IdentifyAccount,
|
||||
},
|
||||
generic::CheckedExtrinsic, transaction_validity::{TransactionValidityError, InvalidTransaction},
|
||||
generic::CheckedExtrinsic,
|
||||
transaction_validity::{TransactionValidityError, InvalidTransaction},
|
||||
};
|
||||
|
||||
const TRANSACTION_VERSION: u8 = 4;
|
||||
@@ -125,9 +126,7 @@ where
|
||||
Some((signed, signature, extra)) => {
|
||||
let signed = lookup.lookup(signed)?;
|
||||
let raw_payload = SignedPayload::new(self.function, extra)?;
|
||||
if !raw_payload.using_encoded(|payload| {
|
||||
signature.verify(payload, &signed)
|
||||
}) {
|
||||
if !raw_payload.using_encoded(|payload| signature.verify(payload, &signed)) {
|
||||
return Err(InvalidTransaction::BadProof.into())
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,8 @@ pub use sp_core::storage::{Storage, StorageChild};
|
||||
|
||||
use sp_std::prelude::*;
|
||||
use sp_std::convert::TryFrom;
|
||||
use sp_core::{crypto, ed25519, sr25519, ecdsa, hash::{H256, H512}};
|
||||
use sp_core::{crypto::{self, Public}, ed25519, sr25519, ecdsa, hash::{H256, H512}};
|
||||
|
||||
use codec::{Encode, Decode};
|
||||
|
||||
pub mod curve;
|
||||
@@ -299,7 +300,6 @@ impl std::fmt::Display for MultiSigner {
|
||||
impl Verify for MultiSignature {
|
||||
type Signer = MultiSigner;
|
||||
fn verify<L: Lazy<[u8]>>(&self, mut msg: L, signer: &AccountId32) -> bool {
|
||||
use sp_core::crypto::Public;
|
||||
match (self, signer) {
|
||||
(MultiSignature::Ed25519(ref sig), who) => sig.verify(msg, &ed25519::Public::from_slice(who.as_ref())),
|
||||
(MultiSignature::Sr25519(ref sig), who) => sig.verify(msg, &sr25519::Public::from_slice(who.as_ref())),
|
||||
@@ -324,7 +324,6 @@ pub struct AnySignature(H512);
|
||||
impl Verify for AnySignature {
|
||||
type Signer = sr25519::Public;
|
||||
fn verify<L: Lazy<[u8]>>(&self, mut msg: L, signer: &sr25519::Public) -> bool {
|
||||
use sp_core::crypto::Public;
|
||||
let msg = msg.get();
|
||||
sr25519::Signature::try_from(self.0.as_fixed_bytes().as_ref())
|
||||
.map(|s| s.verify(msg, signer))
|
||||
@@ -735,6 +734,39 @@ pub fn print(print: impl traits::Printable) {
|
||||
print.print();
|
||||
}
|
||||
|
||||
|
||||
/// Batching session.
|
||||
///
|
||||
/// To be used in runtime only. Outside of runtime, just construct
|
||||
/// `BatchVerifier` directly.
|
||||
#[must_use = "`verify()` needs to be called to finish batch signature verification!"]
|
||||
pub struct SignatureBatching(bool);
|
||||
|
||||
impl SignatureBatching {
|
||||
/// Start new batching session.
|
||||
pub fn start() -> Self {
|
||||
sp_io::crypto::start_batch_verify();
|
||||
SignatureBatching(false)
|
||||
}
|
||||
|
||||
/// Verify all signatures submitted during the batching session.
|
||||
#[must_use]
|
||||
pub fn verify(mut self) -> bool {
|
||||
self.0 = true;
|
||||
sp_io::crypto::finish_batch_verify()
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for SignatureBatching {
|
||||
fn drop(&mut self) {
|
||||
// Sanity check. If user forgets to actually call `verify()`.
|
||||
if !self.0 {
|
||||
panic!("Signature verification has not been called before `SignatureBatching::drop`")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
@@ -782,4 +814,19 @@ mod tests {
|
||||
let multi_signer = MultiSigner::from(pair.public());
|
||||
assert!(multi_sig.verify(msg, &multi_signer.into_account()));
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "Signature verification has not been called")]
|
||||
fn batching_still_finishes_when_not_called_directly() {
|
||||
let mut ext = sp_state_machine::BasicExternalities::with_tasks_executor();
|
||||
ext.execute_with(|| {
|
||||
let _batching = SignatureBatching::start();
|
||||
sp_io::crypto::sr25519_verify(
|
||||
&Default::default(),
|
||||
&Vec::new(),
|
||||
&Default::default(),
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,12 +81,15 @@ impl IdentifyAccount for sp_core::ecdsa::Public {
|
||||
pub trait Verify {
|
||||
/// Type of the signer.
|
||||
type Signer: IdentifyAccount;
|
||||
/// Verify a signature. Return `true` if signature is valid for the value.
|
||||
/// Verify a signature.
|
||||
///
|
||||
/// Return `true` if signature is valid for the value.
|
||||
fn verify<L: Lazy<[u8]>>(&self, msg: L, signer: &<Self::Signer as IdentifyAccount>::AccountId) -> bool;
|
||||
}
|
||||
|
||||
impl Verify for sp_core::ed25519::Signature {
|
||||
type Signer = sp_core::ed25519::Public;
|
||||
|
||||
fn verify<L: Lazy<[u8]>>(&self, mut msg: L, signer: &sp_core::ed25519::Public) -> bool {
|
||||
sp_io::crypto::ed25519_verify(self, msg.get(), signer)
|
||||
}
|
||||
@@ -94,6 +97,7 @@ impl Verify for sp_core::ed25519::Signature {
|
||||
|
||||
impl Verify for sp_core::sr25519::Signature {
|
||||
type Signer = sp_core::sr25519::Public;
|
||||
|
||||
fn verify<L: Lazy<[u8]>>(&self, mut msg: L, signer: &sp_core::sr25519::Public) -> bool {
|
||||
sp_io::crypto::sr25519_verify(self, msg.get(), signer)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user