cuprate/consensus/src/batch_verifier.rs
hinto-janai 354ac9c2f6
Add typos + cargo doc CI (#32)
* 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
2024-02-15 16:03:04 +00:00

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()
}
}