chia_sdk_client/
rate_limits.rs

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