-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Conversation
/bench |
Finished benchmark for branch: nv-dynamic-extensions MASTER RESULTimport block/Wasm time: import block/Native time: BRANCH RESULTimport block/Wasm time: import block/Native time: |
We should put some benchmarks in schnorrkel for this so that we have a comparison. Can I ask @demimarie-parity to fix the existing ones? |
As discussed in dalek-cryptography/ed25519-dalek#117 we seemingly need deterministic batch verification for ed25519 since you can craft invalid blocks that's invalid for only some validators using its current form. We avoid this problem in schnorrkel by avoiding the cofactor. Yay Decaf! |
Finished benchmark for branch: nv-dynamic-extensions MASTER RESULTimport block/Wasm time: import block/Native time: BRANCH RESULTimport block/Wasm time: import block/Native time: |
that was bench before ab94831 where batching was effectively activated |
Just for testing, I think it would be nice to see a version that "dispatches" the verification to a background thread. The background thread could just verify signature by signature. However, as this is done in parallel to the execution of the transaction. We may can get even a better performance than blocking at the end for batch verify. |
For sr25519/ed25519 part, I'm thinking of maybe even better approach - figure out optimal batch size (it is variable afaik, so 100 tx can be more cheap to batch-verify per-tx than 200, for example - @burdges ?), and then send batch of optimal size to the background thread once it is reached. I think it will be more robust on low-tier machines and will cost less computing power. For |
What happens when we don't reach this batch size? I think the batch size should be much smaller to make sure we really dispatch it multiple times. |
It will just block-verify with suboptimal batch size at the end. It will be suboptimal in terms of time than doing everything at the background immediately, but it means that block are very far from full, and we don't need to waste computing power to try to import them as fast as possible? |
The whole work isn't required when we talk about the current, almost empty blocks :D This optimizations will just be really useful for full blocks. In general I just wanted to know what would be the difference when we import in the background while we execute the transactions. Maybe it is total useless and don't bring that much. |
This is my point also, yes :)
I will use your approach for ed25519 (it's batching is buggy anyway) and make a benchmarking run just for that. I don't think it is useless, I think theoretical answer to that that it will effectively remove signature verification from the main pipeline and give time performance boost of ~20% instead of current 13%. |
I filed w3f/schnorrkel#54 to fix the benchmarks @burdges. |
frame/executive/src/lib.rs
Outdated
// execute extrinsics | ||
let (header, extrinsics) = block.deconstruct(); | ||
Self::execute_extrinsics_with_book_keeping(extrinsics, *header.number()); | ||
|
||
if !sp_io::crypto::batch_verify() { | ||
panic!("Signature verification failed.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This really needs better justification. Obviously, this panic is reachable, so there needs to be an explanation for why panicking here is justified.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should panic in runtime AFAIK
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code looks very much strange comparing to the rest of the runtime, but if I have understood correctly ant this is only being used for block execution (not validation and production) then if we are trying to import a block with even a single invalid signature, then yes panic it is.
@@ -106,10 +117,24 @@ impl Extensions { | |||
self.extensions.insert(ext.type_id(), Box::new(ext)); | |||
} | |||
|
|||
/// Register extension `ext`. | |||
pub fn register_with_type_id(&mut self, type_id: TypeId, extension: Box<dyn Extension>) -> Result<(), Error> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should not have a separate type_id
parameter. Instead, we should make Extension
a subtrait of Any
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you provide an example?
78525b3
to
10f7356
Compare
An auditor noticed nodes gossiping bad transactions consumes too much CPU. Among the solutions is rate limiting gossiped transactions per gossip source. If we know the gossip source, and can assume the source checked all signatures, then we can batch verify transaction signatures gossiped from the same source. We require the Ed25519 We could benefit even more with other gossip messages signed by different nodes. We might want a more general infrastructure for this, ala https://www.zfnd.org/blog/futures-batch-verification/ |
I'm not sure about the current implementation, but we should use the same reputation system as it is used for sync. If a node sends a transaction with an invalid signature, it should be instantly disconnected. |
Can I read this auditor report? |
/bench ed25519 |
Finished benchmark for branch: nv-dynamic-extensions Master: Wasm: 62.26 ms (+/- 0.14 ms) |
as predicted @bkchr 😅 |
/bench import |
Finished benchmark for branch: nv-dynamic-extensions Benchmark: Import Benchmark (random transfers) Master: Wasm: 61.76 ms (+/- 0.07 ms) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some last nitpicks and than we are good to go ;)
/// Returns `true` if all signatures are correct, `false` otherwise. | ||
#[cfg(feature = "std")] | ||
pub fn verify_batch( | ||
messages: Vec<&[u8]>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we make these 3 parameters impl Iterator<&[u8]>
etc, we could prevent some allocations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but schnorrkel expects slice and IntoIterator :(
https://docs.rs/schnorrkel/0.9.1/schnorrkel/fn.verify_batch.html
Co-Authored-By: Bastian Köcher <[email protected]>
Co-Authored-By: Bastian Köcher <[email protected]>
3b7b925
to
766ec69
Compare
# Conflicts: # frame/executive/Cargo.toml
Co-Authored-By: Bastian Köcher <[email protected]>
Co-Authored-By: Bastian Köcher <[email protected]>
# Conflicts: # bin/node/runtime/src/lib.rs # frame/executive/Cargo.toml
# Conflicts: # bin/node/runtime/src/lib.rs
…te into nv-dynamic-extensions # Conflicts: # bin/node/runtime/src/lib.rs
* 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 bbdec24. * rethink the sp-io-part * Revert "remove now pointless test" This reverts commit 4d55306. * 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 <[email protected]> * 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 <[email protected]> * Update primitives/externalities/src/extensions.rs Co-Authored-By: Bastian Köcher <[email protected]> * update overlooked note * remove stupid return * Update primitives/io/src/lib.rs Co-Authored-By: Bastian Köcher <[email protected]> * Update primitives/io/src/lib.rs Co-Authored-By: Bastian Köcher <[email protected]> * fix wording * bump spec_version Co-authored-by: cheme <[email protected]> Co-authored-by: Bastian Köcher <[email protected]> # Conflicts: # bin/node/runtime/src/lib.rs # frame/executive/Cargo.toml
polkadot companion: paritytech/polkadot#939