solana_core/
sigverify.rs

1//! The `sigverify` module provides digital signature verification functions.
2//! By default, signatures are verified in parallel using all available CPU
3//! cores.  When perf-libs are available signature verification is offloaded
4//! to the GPU.
5//!
6
7pub use solana_perf::sigverify::{
8    count_packets_in_batches, ed25519_verify_cpu, ed25519_verify_disabled, init, TxOffset,
9};
10use {
11    crate::{
12        banking_trace::BankingPacketSender,
13        sigverify_stage::{SigVerifier, SigVerifyServiceError},
14    },
15    agave_banking_stage_ingress_types::BankingPacketBatch,
16    crossbeam_channel::{Sender, TrySendError},
17    solana_perf::{cuda_runtime::PinnedVec, packet::PacketBatch, recycler::Recycler, sigverify},
18};
19
20pub struct TransactionSigVerifier {
21    banking_stage_sender: BankingPacketSender,
22    forward_stage_sender: Option<Sender<(BankingPacketBatch, bool)>>,
23    recycler: Recycler<TxOffset>,
24    recycler_out: Recycler<PinnedVec<u8>>,
25    reject_non_vote: bool,
26}
27
28impl TransactionSigVerifier {
29    pub fn new_reject_non_vote(
30        packet_sender: BankingPacketSender,
31        forward_stage_sender: Option<Sender<(BankingPacketBatch, bool)>>,
32    ) -> Self {
33        let mut new_self = Self::new(packet_sender, forward_stage_sender);
34        new_self.reject_non_vote = true;
35        new_self
36    }
37
38    pub fn new(
39        banking_stage_sender: BankingPacketSender,
40        forward_stage_sender: Option<Sender<(BankingPacketBatch, bool)>>,
41    ) -> Self {
42        init();
43        Self {
44            banking_stage_sender,
45            forward_stage_sender,
46            recycler: Recycler::warmed(50, 4096),
47            recycler_out: Recycler::warmed(50, 4096),
48            reject_non_vote: false,
49        }
50    }
51}
52
53impl SigVerifier for TransactionSigVerifier {
54    type SendType = BankingPacketBatch;
55
56    fn send_packets(
57        &mut self,
58        packet_batches: Vec<PacketBatch>,
59    ) -> Result<(), SigVerifyServiceError<Self::SendType>> {
60        let banking_packet_batch = BankingPacketBatch::new(packet_batches);
61        if let Some(forward_stage_sender) = &self.forward_stage_sender {
62            self.banking_stage_sender
63                .send(banking_packet_batch.clone())?;
64            if let Err(TrySendError::Full(_)) =
65                forward_stage_sender.try_send((banking_packet_batch, self.reject_non_vote))
66            {
67                warn!("forwarding stage channel is full, dropping packets.");
68            }
69        } else {
70            self.banking_stage_sender.send(banking_packet_batch)?;
71        }
72
73        Ok(())
74    }
75
76    fn verify_batches(
77        &self,
78        mut batches: Vec<PacketBatch>,
79        valid_packets: usize,
80    ) -> Vec<PacketBatch> {
81        sigverify::ed25519_verify(
82            &mut batches,
83            &self.recycler,
84            &self.recycler_out,
85            self.reject_non_vote,
86            valid_packets,
87        );
88        batches
89    }
90}