1use std::collections::HashMap;
2
3use chik_protocol::ProtocolMessageTypes;
4use once_cell::sync::Lazy;
5
6#[derive(Debug, Clone)]
7pub struct RateLimits {
8 pub default_settings: RateLimit,
9 pub non_tx_frequency: f64,
10 pub non_tx_max_total_size: f64,
11 pub tx: HashMap<ProtocolMessageTypes, RateLimit>,
12 pub other: HashMap<ProtocolMessageTypes, RateLimit>,
13}
14
15impl RateLimits {
16 pub fn extend(&mut self, other: &Self) {
17 self.default_settings = other.default_settings;
18 self.non_tx_frequency = other.non_tx_frequency;
19 self.non_tx_max_total_size = other.non_tx_max_total_size;
20 self.tx.extend(other.tx.clone());
21 self.other.extend(other.other.clone());
22 }
23}
24
25#[derive(Debug, Clone, Copy)]
26pub struct RateLimit {
27 pub frequency: f64,
28 pub max_size: f64,
29 pub max_total_size: Option<f64>,
30}
31
32impl RateLimit {
33 pub fn new(frequency: f64, max_size: f64, max_total_size: Option<f64>) -> Self {
34 Self {
35 frequency,
36 max_size,
37 max_total_size,
38 }
39 }
40}
41
42macro_rules! settings {
43 ($($message:ident => $frequency:expr, $max_size:expr $(, $max_total_size:expr)? ;)*) => {
44 {
45 let mut settings = HashMap::new();
46 $(
47 #[allow(unused_mut, unused_assignments)]
48 let mut max_total_size = None;
49 $( max_total_size = Some($max_total_size); )?
50 settings.insert(
51 ProtocolMessageTypes::$message,
52 RateLimit::new(
53 $frequency.into(),
54 $max_size.into(),
55 max_total_size.map(|num: u32| num.into()),
56 )
57 );
58 )*
59 settings
60 }
61 };
62}
63
64pub static V1_RATE_LIMITS: Lazy<RateLimits> = Lazy::new(|| RateLimits {
66 default_settings: RateLimit::new(100.0, 1024.0 * 1024.0, Some(100.0 * 1024.0 * 1024.0)),
67 non_tx_frequency: 1000.0,
68 non_tx_max_total_size: 100.0 * 1024.0 * 1024.0,
69 tx: settings! {
70 NewTransaction => 5000, 100, 5000 * 100;
71 RequestTransaction => 5000, 100, 5000 * 100;
72 RespondTransaction => 5000, 1024 * 1024, 20 * 1024 * 1024;
73 SendTransaction => 5000, 1024 * 1024;
74 TransactionAck => 5000, 2048;
75 },
76 other: settings! {
77 Handshake => 5, 10 * 1024, 5 * 10 * 1024;
78 HarvesterHandshake => 5, 1024 * 1024;
79 NewSignagePointHarvester => 100, 4886;
80 NewProofOfSpace => 100, 2048;
81 RequestSignatures => 100, 2048;
82 RespondSignatures => 100, 2048;
83 NewSignagePoint => 200, 2048;
84 DeclareProofOfSpace => 100, 10 * 1024;
85 RequestSignedValues => 100, 10 * 1024;
86 FarmingInfo => 100, 1024;
87 SignedValues => 100, 1024;
88 NewPeakTimelord => 100, 20 * 1024;
89 NewUnfinishedBlockTimelord => 100, 10 * 1024;
90 NewSignagePointVdf => 100, 100 * 1024;
91 NewInfusionPointVdf => 100, 100 * 1024;
92 NewEndOfSubSlotVdf => 100, 100 * 1024;
93 RequestCompactProofOfTime => 100, 10 * 1024;
94 RespondCompactProofOfTime => 100, 100 * 1024;
95 NewPeak => 200, 512;
96 RequestProofOfWeight => 5, 100;
97 RespondProofOfWeight => 5, 50 * 1024 * 1024, 100 * 1024 * 1024;
98 RequestBlock => 200, 100;
99 RejectBlock => 200, 100;
100 RequestBlocks => 500, 100;
101 RespondBlocks => 100, 50 * 1024 * 1024, 5 * 50 * 1024 * 1024;
102 RejectBlocks => 100, 100;
103 RespondBlock => 200, 2 * 1024 * 1024, 10 * 2 * 1024 * 1024;
104 NewUnfinishedBlock => 200, 100;
105 RequestUnfinishedBlock => 200, 100;
106 NewUnfinishedBlock2 => 200, 100;
107 RequestUnfinishedBlock2 => 200, 100;
108 RespondUnfinishedBlock => 200, 2 * 1024 * 1024, 10 * 2 * 1024 * 1024;
109 NewSignagePointOrEndOfSubSlot => 200, 200;
110 RequestSignagePointOrEndOfSubSlot => 200, 200;
111 RespondSignagePoint => 200, 50 * 1024;
112 RespondEndOfSubSlot => 100, 50 * 1024;
113 RequestMempoolTransactions => 5, 1024 * 1024;
114 RequestCompactVDF => 200, 1024;
115 RespondCompactVDF => 200, 100 * 1024;
116 NewCompactVDF => 100, 1024;
117 RequestPeers => 10, 100;
118 RespondPeers => 10, 1024 * 1024;
119 RequestPuzzleSolution => 1000, 100;
120 RespondPuzzleSolution => 1000, 1024 * 1024;
121 RejectPuzzleSolution => 1000, 100;
122 NewPeakWallet => 200, 300;
123 RequestBlockHeader => 500, 100;
124 RespondBlockHeader => 500, 500 * 1024;
125 RejectHeaderRequest => 500, 100;
126 RequestRemovals => 500, 50 * 1024, 10 * 1024 * 1024;
127 RespondRemovals => 500, 1024 * 1024, 10 * 1024 * 1024;
128 RejectRemovalsRequest => 500, 100;
129 RequestAdditions => 500, 1024 * 1024, 10 * 1024 * 1024;
130 RespondAdditions => 500, 1024 * 1024, 10 * 1024 * 1024;
131 RejectAdditionsRequest => 500, 100;
132 RequestHeaderBlocks => 500, 100;
133 RejectHeaderBlocks => 100, 100;
134 RespondHeaderBlocks => 500, 2 * 1024 * 1024, 100 * 1024 * 1024;
135 RequestPeersIntroducer => 100, 100;
136 RespondPeersIntroducer => 100, 1024 * 1024;
137 FarmNewBlock => 200, 200;
138 RequestPlots => 10, 10 * 1024 * 1024;
139 RespondPlots => 10, 100 * 1024 * 1024;
140 PlotSyncStart => 1000, 100 * 1024 * 1024;
141 PlotSyncLoaded => 1000, 100 * 1024 * 1024;
142 PlotSyncRemoved => 1000, 100 * 1024 * 1024;
143 PlotSyncInvalid => 1000, 100 * 1024 * 1024;
144 PlotSyncKeysMissing => 1000, 100 * 1024 * 1024;
145 PlotSyncDuplicates => 1000, 100 * 1024 * 1024;
146 PlotSyncDone => 1000, 100 * 1024 * 1024;
147 PlotSyncResponse => 3000, 100 * 1024 * 1024;
148 CoinStateUpdate => 1000, 100 * 1024 * 1024;
149 RegisterForPhUpdates => 1000, 100 * 1024 * 1024;
150 RespondToPhUpdates => 1000, 100 * 1024 * 1024;
151 RegisterForCoinUpdates => 1000, 100 * 1024 * 1024;
152 RespondToCoinUpdates => 1000, 100 * 1024 * 1024;
153 RequestRemovePuzzleSubscriptions => 1000, 100 * 1024 * 1024;
154 RespondRemovePuzzleSubscriptions => 1000, 100 * 1024 * 1024;
155 RequestRemoveCoinSubscriptions => 1000, 100 * 1024 * 1024;
156 RespondRemoveCoinSubscriptions => 1000, 100 * 1024 * 1024;
157 RequestPuzzleState => 1000, 100 * 1024 * 1024;
158 RespondPuzzleState => 1000, 100 * 1024 * 1024;
159 RejectPuzzleState => 200, 100;
160 RequestCoinState => 1000, 100 * 1024 * 1024;
161 RespondCoinState => 1000, 100 * 1024 * 1024;
162 RejectCoinState => 200, 100;
163 RequestChildren => 2000, 1024 * 1024;
170 RespondChildren => 2000, 1024 * 1024;
171 },
172});
173
174static V2_RATE_LIMIT_CHANGES: Lazy<RateLimits> = Lazy::new(|| RateLimits {
177 default_settings: RateLimit::new(100.0, 1024.0 * 1024.0, Some(100.0 * 1024.0 * 1024.0)),
178 non_tx_frequency: 1000.0,
179 non_tx_max_total_size: 100.0 * 1024.0 * 1024.0,
180 tx: settings! {
181 RequestBlockHeader => 500, 100;
182 RespondBlockHeader => 500, 500 * 1024;
183 RejectHeaderRequest => 500, 100;
184 RequestRemovals => 5000, 50 * 1024, 10 * 1024 * 1024;
185 RespondRemovals => 5000, 1024 * 1024, 10 * 1024 * 1024;
186 RejectRemovalsRequest => 500, 100;
187 RequestAdditions => 50000, 100 * 1024 * 1024;
188 RespondAdditions => 50000, 100 * 1024 * 1024;
189 RejectAdditionsRequest => 500, 100;
190 RejectHeaderBlocks => 1000, 100;
191 RespondHeaderBlocks => 5000, 2 * 1024 * 1024;
192 RequestBlockHeaders => 5000, 100;
193 RejectBlockHeaders => 1000, 100;
194 RespondBlockHeaders => 5000, 2 * 1024 * 1024;
195 RequestChildren => 2000, 1024 * 1024;
198 RespondChildren => 2000, 1024 * 1024;
199 RequestPuzzleSolution => 5000, 100;
200 RespondPuzzleSolution => 5000, 1024 * 1024;
201 RejectPuzzleSolution => 5000, 100;
202 NoneResponse => 500, 100;
203 },
205 other: settings! {
206 RequestHeaderBlocks => 5000, 100;
207 },
208});
209
210pub static V2_RATE_LIMITS: Lazy<RateLimits> = Lazy::new(|| {
211 let mut rate_limits = V1_RATE_LIMITS.clone();
212 rate_limits.extend(&V2_RATE_LIMIT_CHANGES);
213 rate_limits
214});