mirror of
https://github.com/Cuprate/cuprate.git
synced 2025-01-25 03:55:52 +00:00
354ac9c2f6
* ci: add separate `typo` job * add `typos.toml` for false positives * fix all typos * ci: add `cargo doc` step * fix doc errors * contributing.md: update passing CI steps * fix more typos, add exception to `cryptonight/` * ci: move `cargo doc` step within `ci` job It needs dependencies. * ci: add https://github.com/Cuprate/cuprate/pull/63 * test-utils: fix typo * ci: switch `rustup update` and switch order * ci: only update rust on unix * ci: set `RUSTDOCFLAGS` env earlier * ci: only run `cargo doc` on linux * ci: remove `bash` on `cargo doc` * ci: remove `--all-targets` We now have the target OS's in CI, no need to compile for each. * contributing.md: update ci steps * ci: add `--all-targets` back to clippy, build * update contributing.md
47 lines
1.5 KiB
Rust
47 lines
1.5 KiB
Rust
use std::cell::UnsafeCell;
|
|
|
|
use multiexp::BatchVerifier as InternalBatchVerifier;
|
|
use rayon::prelude::*;
|
|
use thread_local::ThreadLocal;
|
|
|
|
use crate::ConsensusError;
|
|
|
|
/// A multi threaded batch verifier.
|
|
pub struct MultiThreadedBatchVerifier {
|
|
internal: ThreadLocal<UnsafeCell<InternalBatchVerifier<(), dalek_ff_group::EdwardsPoint>>>,
|
|
}
|
|
|
|
impl MultiThreadedBatchVerifier {
|
|
/// Create a new multithreaded batch verifier,
|
|
pub fn new(numb_threads: usize) -> MultiThreadedBatchVerifier {
|
|
MultiThreadedBatchVerifier {
|
|
internal: ThreadLocal::with_capacity(numb_threads),
|
|
}
|
|
}
|
|
|
|
pub fn queue_statement<R>(
|
|
&self,
|
|
stmt: impl FnOnce(
|
|
&mut InternalBatchVerifier<(), dalek_ff_group::EdwardsPoint>,
|
|
) -> Result<R, ConsensusError>,
|
|
) -> Result<R, ConsensusError> {
|
|
let verifier_cell = self
|
|
.internal
|
|
.get_or(|| UnsafeCell::new(InternalBatchVerifier::new(0)));
|
|
// SAFETY: This is safe for 2 reasons:
|
|
// 1. each thread gets a different batch verifier.
|
|
// 2. only this function `queue_statement` will get the inner batch verifier, it's private.
|
|
//
|
|
// TODO: it's probably ok to just use RefCell
|
|
stmt(unsafe { &mut *verifier_cell.get() })
|
|
}
|
|
|
|
pub fn verify(self) -> bool {
|
|
self.internal
|
|
.into_iter()
|
|
.map(UnsafeCell::into_inner)
|
|
.par_bridge()
|
|
.find_any(|batch_verifier| !batch_verifier.verify_vartime())
|
|
.is_none()
|
|
}
|
|
}
|