1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
pub use solana_perf::sigverify::{
count_packets_in_batches, ed25519_verify_cpu, ed25519_verify_disabled, init, TxOffset,
};
use {
crate::{
banking_stage::BankingPacketBatch,
sigverify_stage::{SigVerifier, SigVerifyServiceError},
},
crossbeam_channel::Sender,
solana_perf::{cuda_runtime::PinnedVec, packet::PacketBatch, recycler::Recycler, sigverify},
solana_sdk::packet::Packet,
};
#[derive(Debug, Default, Clone)]
pub struct TransactionTracerPacketStats {
pub total_removed_before_sigverify_stage: usize,
pub total_tracer_packets_received_in_sigverify_stage: usize,
pub total_tracer_packets_deduped: usize,
pub total_excess_tracer_packets: usize,
pub total_tracker_packets_passed_sigverify: usize,
}
#[derive(Clone)]
pub struct TransactionSigVerifier {
packet_sender: Sender<<Self as SigVerifier>::SendType>,
tracer_packet_stats: TransactionTracerPacketStats,
recycler: Recycler<TxOffset>,
recycler_out: Recycler<PinnedVec<u8>>,
reject_non_vote: bool,
}
impl TransactionSigVerifier {
pub fn new_reject_non_vote(packet_sender: Sender<<Self as SigVerifier>::SendType>) -> Self {
let mut new_self = Self::new(packet_sender);
new_self.reject_non_vote = true;
new_self
}
pub fn new(packet_sender: Sender<<Self as SigVerifier>::SendType>) -> Self {
init();
Self {
packet_sender,
tracer_packet_stats: TransactionTracerPacketStats::default(),
recycler: Recycler::warmed(50, 4096),
recycler_out: Recycler::warmed(50, 4096),
reject_non_vote: false,
}
}
}
impl SigVerifier for TransactionSigVerifier {
type SendType = BankingPacketBatch;
#[inline(always)]
fn process_received_packet(
&mut self,
packet: &mut Packet,
removed_before_sigverify_stage: bool,
is_dup: bool,
) {
sigverify::check_for_tracer_packet(packet);
if packet.meta.is_tracer_packet() {
if removed_before_sigverify_stage {
self.tracer_packet_stats
.total_removed_before_sigverify_stage += 1;
} else {
self.tracer_packet_stats
.total_tracer_packets_received_in_sigverify_stage += 1;
if is_dup {
self.tracer_packet_stats.total_tracer_packets_deduped += 1;
}
}
}
}
#[inline(always)]
fn process_excess_packet(&mut self, packet: &Packet) {
if packet.meta.is_tracer_packet() {
self.tracer_packet_stats.total_excess_tracer_packets += 1;
}
}
#[inline(always)]
fn process_passed_sigverify_packet(&mut self, packet: &Packet) {
if packet.meta.is_tracer_packet() {
self.tracer_packet_stats
.total_tracker_packets_passed_sigverify += 1;
}
}
fn send_packets(
&mut self,
packet_batches: Vec<PacketBatch>,
) -> Result<(), SigVerifyServiceError<Self::SendType>> {
let mut tracer_packet_stats_to_send = TransactionTracerPacketStats::default();
std::mem::swap(
&mut tracer_packet_stats_to_send,
&mut self.tracer_packet_stats,
);
self.packet_sender
.send((packet_batches, Some(tracer_packet_stats_to_send)))?;
Ok(())
}
fn verify_batches(
&self,
mut batches: Vec<PacketBatch>,
valid_packets: usize,
) -> Vec<PacketBatch> {
sigverify::ed25519_verify(
&mut batches,
&self.recycler,
&self.recycler_out,
self.reject_non_vote,
valid_packets,
);
batches
}
}