kaspa_consensus_core/config/
params.rs

1pub use super::{
2    bps::{Bps, Testnet11Bps},
3    constants::consensus::*,
4    genesis::{GenesisBlock, DEVNET_GENESIS, GENESIS, SIMNET_GENESIS, TESTNET11_GENESIS, TESTNET_GENESIS},
5};
6use crate::{
7    constants::STORAGE_MASS_PARAMETER,
8    network::{NetworkId, NetworkType},
9    BlockLevel, KType,
10};
11use kaspa_addresses::Prefix;
12use kaspa_math::Uint256;
13use std::{
14    cmp::min,
15    time::{SystemTime, UNIX_EPOCH},
16};
17
18/// Consensus parameters. Contains settings and configurations which are consensus-sensitive.
19/// Changing one of these on a network node would exclude and prevent it from reaching consensus
20/// with the other unmodified nodes.
21#[derive(Clone, Debug)]
22pub struct Params {
23    pub dns_seeders: &'static [&'static str],
24    pub net: NetworkId,
25    pub genesis: GenesisBlock,
26    pub ghostdag_k: KType,
27
28    /// Legacy timestamp deviation tolerance (in seconds)
29    pub legacy_timestamp_deviation_tolerance: u64,
30
31    /// New timestamp deviation tolerance (in seconds, activated with sampling)
32    pub new_timestamp_deviation_tolerance: u64,
33
34    /// Block sample rate for filling the past median time window (selects one every N blocks)
35    pub past_median_time_sample_rate: u64,
36
37    /// Size of sampled blocks window that is inspected to calculate the past median time of each block
38    pub past_median_time_sampled_window_size: u64,
39
40    /// Target time per block (in milliseconds)
41    pub target_time_per_block: u64,
42
43    /// DAA score from which the window sampling starts for difficulty and past median time calculation
44    pub sampling_activation_daa_score: u64,
45
46    /// Defines the highest allowed proof of work difficulty value for a block as a [`Uint256`]
47    pub max_difficulty_target: Uint256,
48
49    /// Highest allowed proof of work difficulty as a floating number
50    pub max_difficulty_target_f64: f64,
51
52    /// Block sample rate for filling the difficulty window (selects one every N blocks)
53    pub difficulty_sample_rate: u64,
54
55    /// Size of sampled blocks window that is inspected to calculate the required difficulty of each block
56    pub sampled_difficulty_window_size: usize,
57
58    /// Size of full blocks window that is inspected to calculate the required difficulty of each block
59    pub legacy_difficulty_window_size: usize,
60
61    /// The minimum length a difficulty window (full or sampled) must have to trigger a DAA calculation
62    pub min_difficulty_window_len: usize,
63
64    pub max_block_parents: u8,
65    pub mergeset_size_limit: u64,
66    pub merge_depth: u64,
67    pub finality_depth: u64,
68    pub pruning_depth: u64,
69    pub coinbase_payload_script_public_key_max_len: u8,
70    pub max_coinbase_payload_len: usize,
71    pub max_tx_inputs: usize,
72    pub max_tx_outputs: usize,
73    pub max_signature_script_len: usize,
74    pub max_script_public_key_len: usize,
75    pub mass_per_tx_byte: u64,
76    pub mass_per_script_pub_key_byte: u64,
77    pub mass_per_sig_op: u64,
78    pub max_block_mass: u64,
79
80    /// The parameter for scaling inverse KAS value to mass units (unpublished KIP-0009)
81    pub storage_mass_parameter: u64,
82
83    /// DAA score from which storage mass calculation and transaction mass field are activated as a consensus rule
84    pub storage_mass_activation_daa_score: u64,
85
86    /// DAA score after which the pre-deflationary period switches to the deflationary period
87    pub deflationary_phase_daa_score: u64,
88
89    pub pre_deflationary_phase_base_subsidy: u64,
90    pub coinbase_maturity: u64,
91    pub skip_proof_of_work: bool,
92    pub max_block_level: BlockLevel,
93    pub pruning_proof_m: u64,
94}
95
96fn unix_now() -> u64 {
97    SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_millis() as u64
98}
99
100impl Params {
101    /// Returns the size of the full blocks window that is inspected to calculate the past median time (legacy)
102    #[inline]
103    #[must_use]
104    pub fn legacy_past_median_time_window_size(&self) -> usize {
105        (2 * self.legacy_timestamp_deviation_tolerance - 1) as usize
106    }
107
108    /// Returns the size of the sampled blocks window that is inspected to calculate the past median time
109    #[inline]
110    #[must_use]
111    pub fn sampled_past_median_time_window_size(&self) -> usize {
112        self.past_median_time_sampled_window_size as usize
113    }
114
115    /// Returns the size of the blocks window that is inspected to calculate the past median time,
116    /// depending on a selected parent DAA score
117    #[inline]
118    #[must_use]
119    pub fn past_median_time_window_size(&self, selected_parent_daa_score: u64) -> usize {
120        if selected_parent_daa_score < self.sampling_activation_daa_score {
121            self.legacy_past_median_time_window_size()
122        } else {
123            self.sampled_past_median_time_window_size()
124        }
125    }
126
127    /// Returns the timestamp deviation tolerance,
128    /// depending on a selected parent DAA score
129    #[inline]
130    #[must_use]
131    pub fn timestamp_deviation_tolerance(&self, selected_parent_daa_score: u64) -> u64 {
132        if selected_parent_daa_score < self.sampling_activation_daa_score {
133            self.legacy_timestamp_deviation_tolerance
134        } else {
135            self.new_timestamp_deviation_tolerance
136        }
137    }
138
139    /// Returns the past median time sample rate,
140    /// depending on a selected parent DAA score
141    #[inline]
142    #[must_use]
143    pub fn past_median_time_sample_rate(&self, selected_parent_daa_score: u64) -> u64 {
144        if selected_parent_daa_score < self.sampling_activation_daa_score {
145            1
146        } else {
147            self.past_median_time_sample_rate
148        }
149    }
150
151    /// Returns the size of the blocks window that is inspected to calculate the difficulty,
152    /// depending on a selected parent DAA score
153    #[inline]
154    #[must_use]
155    pub fn difficulty_window_size(&self, selected_parent_daa_score: u64) -> usize {
156        if selected_parent_daa_score < self.sampling_activation_daa_score {
157            self.legacy_difficulty_window_size
158        } else {
159            self.sampled_difficulty_window_size
160        }
161    }
162
163    /// Returns the difficulty sample rate,
164    /// depending on a selected parent DAA score
165    #[inline]
166    #[must_use]
167    pub fn difficulty_sample_rate(&self, selected_parent_daa_score: u64) -> u64 {
168        if selected_parent_daa_score < self.sampling_activation_daa_score {
169            1
170        } else {
171            self.difficulty_sample_rate
172        }
173    }
174
175    /// Returns the target time per block,
176    /// depending on a selected parent DAA score
177    #[inline]
178    #[must_use]
179    pub fn target_time_per_block(&self, _selected_parent_daa_score: u64) -> u64 {
180        self.target_time_per_block
181    }
182
183    /// Returns the expected number of blocks per second
184    #[inline]
185    #[must_use]
186    pub fn bps(&self) -> u64 {
187        1000 / self.target_time_per_block
188    }
189
190    pub fn daa_window_duration_in_blocks(&self, selected_parent_daa_score: u64) -> u64 {
191        if selected_parent_daa_score < self.sampling_activation_daa_score {
192            self.legacy_difficulty_window_size as u64
193        } else {
194            self.difficulty_sample_rate * self.sampled_difficulty_window_size as u64
195        }
196    }
197
198    fn expected_daa_window_duration_in_milliseconds(&self, selected_parent_daa_score: u64) -> u64 {
199        if selected_parent_daa_score < self.sampling_activation_daa_score {
200            self.target_time_per_block * self.legacy_difficulty_window_size as u64
201        } else {
202            self.target_time_per_block * self.difficulty_sample_rate * self.sampled_difficulty_window_size as u64
203        }
204    }
205
206    /// Returns the depth at which the anticone of a chain block is final (i.e., is a permanently closed set).
207    /// Based on the analysis at <https://github.com/kaspanet/docs/blob/main/Reference/prunality/Prunality.pdf>
208    /// and on the decomposition of merge depth (rule R-I therein) from finality depth (φ)
209    pub fn anticone_finalization_depth(&self) -> u64 {
210        let anticone_finalization_depth = self.finality_depth
211            + self.merge_depth
212            + 4 * self.mergeset_size_limit * self.ghostdag_k as u64
213            + 2 * self.ghostdag_k as u64
214            + 2;
215
216        // In mainnet it's guaranteed that `self.pruning_depth` is greater
217        // than `anticone_finalization_depth`, but for some tests we use
218        // a smaller (unsafe) pruning depth, so we return the minimum of
219        // the two to avoid a situation where a block can be pruned and
220        // not finalized.
221        min(self.pruning_depth, anticone_finalization_depth)
222    }
223
224    /// Returns whether the sink timestamp is recent enough and the node is considered synced or nearly synced.
225    pub fn is_nearly_synced(&self, sink_timestamp: u64, sink_daa_score: u64) -> bool {
226        if self.net.is_mainnet() {
227            // We consider the node close to being synced if the sink (virtual selected parent) block
228            // timestamp is within DAA window duration far in the past. Blocks mined over such DAG state would
229            // enter the DAA window of fully-synced nodes and thus contribute to overall network difficulty
230            unix_now() < sink_timestamp + self.expected_daa_window_duration_in_milliseconds(sink_daa_score)
231        } else {
232            // For testnets we consider the node to be synced if the sink timestamp is within a time range which
233            // is overwhelmingly unlikely to pass without mined blocks even if net hashrate decreased dramatically.
234            //
235            // This period is smaller than the above mainnet calculation in order to ensure that an IBDing miner
236            // with significant testnet hashrate does not overwhelm the network with deep side-DAGs.
237            //
238            // We use DAA duration as baseline and scale it down with BPS (and divide by 3 for mining only when very close to current time on TN11)
239            let max_expected_duration_without_blocks_in_milliseconds = self.target_time_per_block * NEW_DIFFICULTY_WINDOW_DURATION / 3; // = DAA duration in milliseconds / bps / 3
240            unix_now() < sink_timestamp + max_expected_duration_without_blocks_in_milliseconds
241        }
242    }
243
244    pub fn network_name(&self) -> String {
245        self.net.to_prefixed()
246    }
247
248    pub fn prefix(&self) -> Prefix {
249        self.net.into()
250    }
251
252    pub fn default_p2p_port(&self) -> u16 {
253        self.net.default_p2p_port()
254    }
255
256    pub fn default_rpc_port(&self) -> u16 {
257        self.net.default_rpc_port()
258    }
259
260    pub fn finality_duration(&self) -> u64 {
261        self.target_time_per_block * self.finality_depth
262    }
263}
264
265impl From<NetworkType> for Params {
266    fn from(value: NetworkType) -> Self {
267        match value {
268            NetworkType::Mainnet => MAINNET_PARAMS,
269            NetworkType::Testnet => TESTNET_PARAMS,
270            NetworkType::Devnet => DEVNET_PARAMS,
271            NetworkType::Simnet => SIMNET_PARAMS,
272        }
273    }
274}
275
276impl From<NetworkId> for Params {
277    fn from(value: NetworkId) -> Self {
278        match value.network_type {
279            NetworkType::Mainnet => MAINNET_PARAMS,
280            NetworkType::Testnet => match value.suffix {
281                Some(10) => TESTNET_PARAMS,
282                Some(11) => TESTNET11_PARAMS,
283                Some(x) => panic!("Testnet suffix {} is not supported", x),
284                None => panic!("Testnet suffix not provided"),
285            },
286            NetworkType::Devnet => DEVNET_PARAMS,
287            NetworkType::Simnet => SIMNET_PARAMS,
288        }
289    }
290}
291
292pub const MAINNET_PARAMS: Params = Params {
293    dns_seeders: &[
294        // This DNS seeder is run by Denis Mashkevich
295        "mainnet-dnsseed-1.kaspanet.org",
296        // This DNS seeder is run by Denis Mashkevich
297        "mainnet-dnsseed-2.kaspanet.org",
298        // This DNS seeder is run by Constantine Bytensky
299        "dnsseed.cbytensky.org",
300        // This DNS seeder is run by Georges Künzli
301        "seeder1.kaspad.net",
302        // This DNS seeder is run by Georges Künzli
303        "seeder2.kaspad.net",
304        // This DNS seeder is run by Georges Künzli
305        "seeder3.kaspad.net",
306        // This DNS seeder is run by Georges Künzli
307        "seeder4.kaspad.net",
308        // This DNS seeder is run by Tim
309        "kaspadns.kaspacalc.net",
310        // This DNS seeder is run by supertypo
311        "n-mainnet.kaspa.ws",
312        // This DNS seeder is run by -gerri-
313        "dnsseeder-kaspa-mainnet.x-con.at",
314        // This DNS seeder is run by H@H
315        "ns-mainnet.kaspa-dnsseeder.net",
316    ],
317    net: NetworkId::new(NetworkType::Mainnet),
318    genesis: GENESIS,
319    ghostdag_k: LEGACY_DEFAULT_GHOSTDAG_K,
320    legacy_timestamp_deviation_tolerance: LEGACY_TIMESTAMP_DEVIATION_TOLERANCE,
321    new_timestamp_deviation_tolerance: NEW_TIMESTAMP_DEVIATION_TOLERANCE,
322    past_median_time_sample_rate: Bps::<1>::past_median_time_sample_rate(),
323    past_median_time_sampled_window_size: MEDIAN_TIME_SAMPLED_WINDOW_SIZE,
324    target_time_per_block: 1000,
325    sampling_activation_daa_score: u64::MAX,
326    max_difficulty_target: MAX_DIFFICULTY_TARGET,
327    max_difficulty_target_f64: MAX_DIFFICULTY_TARGET_AS_F64,
328    difficulty_sample_rate: Bps::<1>::difficulty_adjustment_sample_rate(),
329    sampled_difficulty_window_size: DIFFICULTY_SAMPLED_WINDOW_SIZE as usize,
330    legacy_difficulty_window_size: LEGACY_DIFFICULTY_WINDOW_SIZE,
331    min_difficulty_window_len: MIN_DIFFICULTY_WINDOW_LEN,
332    max_block_parents: 10,
333    mergeset_size_limit: (LEGACY_DEFAULT_GHOSTDAG_K as u64) * 10,
334    merge_depth: 3600,
335    finality_depth: 86400,
336    pruning_depth: 185798,
337    coinbase_payload_script_public_key_max_len: 150,
338    max_coinbase_payload_len: 204,
339
340    // This is technically a soft fork from the Go implementation since kaspad's consensus doesn't
341    // check these rules, but in practice it's enforced by the network layer that limits the message
342    // size to 1 GB.
343    // These values should be lowered to more reasonable amounts on the next planned HF/SF.
344    max_tx_inputs: 1_000_000_000,
345    max_tx_outputs: 1_000_000_000,
346    max_signature_script_len: 1_000_000_000,
347    max_script_public_key_len: 1_000_000_000,
348
349    mass_per_tx_byte: 1,
350    mass_per_script_pub_key_byte: 10,
351    mass_per_sig_op: 1000,
352    max_block_mass: 500_000,
353
354    storage_mass_parameter: STORAGE_MASS_PARAMETER,
355    storage_mass_activation_daa_score: u64::MAX,
356
357    // deflationary_phase_daa_score is the DAA score after which the pre-deflationary period
358    // switches to the deflationary period. This number is calculated as follows:
359    // We define a year as 365.25 days
360    // Half a year in seconds = 365.25 / 2 * 24 * 60 * 60 = 15778800
361    // The network was down for three days shortly after launch
362    // Three days in seconds = 3 * 24 * 60 * 60 = 259200
363    deflationary_phase_daa_score: 15778800 - 259200,
364    pre_deflationary_phase_base_subsidy: 50000000000,
365    coinbase_maturity: 100,
366    skip_proof_of_work: false,
367    max_block_level: 225,
368    pruning_proof_m: 1000,
369};
370
371pub const TESTNET_PARAMS: Params = Params {
372    dns_seeders: &[
373        // This DNS seeder is run by Tiram
374        "seeder1-testnet.kaspad.net",
375        // This DNS seeder is run by -gerri-
376        "dnsseeder-kaspa-testnet.x-con.at",
377        // This DNS seeder is run by H@H
378        "ns-testnet10.kaspa-dnsseeder.net",
379    ],
380    net: NetworkId::with_suffix(NetworkType::Testnet, 10),
381    genesis: TESTNET_GENESIS,
382    ghostdag_k: LEGACY_DEFAULT_GHOSTDAG_K,
383    legacy_timestamp_deviation_tolerance: LEGACY_TIMESTAMP_DEVIATION_TOLERANCE,
384    new_timestamp_deviation_tolerance: NEW_TIMESTAMP_DEVIATION_TOLERANCE,
385    past_median_time_sample_rate: Bps::<1>::past_median_time_sample_rate(),
386    past_median_time_sampled_window_size: MEDIAN_TIME_SAMPLED_WINDOW_SIZE,
387    target_time_per_block: 1000,
388    sampling_activation_daa_score: u64::MAX,
389    max_difficulty_target: MAX_DIFFICULTY_TARGET,
390    max_difficulty_target_f64: MAX_DIFFICULTY_TARGET_AS_F64,
391    difficulty_sample_rate: Bps::<1>::difficulty_adjustment_sample_rate(),
392    sampled_difficulty_window_size: DIFFICULTY_SAMPLED_WINDOW_SIZE as usize,
393    legacy_difficulty_window_size: LEGACY_DIFFICULTY_WINDOW_SIZE,
394    min_difficulty_window_len: MIN_DIFFICULTY_WINDOW_LEN,
395    max_block_parents: 10,
396    mergeset_size_limit: (LEGACY_DEFAULT_GHOSTDAG_K as u64) * 10,
397    merge_depth: 3600,
398    finality_depth: 86400,
399    pruning_depth: 185798,
400    coinbase_payload_script_public_key_max_len: 150,
401    max_coinbase_payload_len: 204,
402
403    // This is technically a soft fork from the Go implementation since kaspad's consensus doesn't
404    // check these rules, but in practice it's enforced by the network layer that limits the message
405    // size to 1 GB.
406    // These values should be lowered to more reasonable amounts on the next planned HF/SF.
407    max_tx_inputs: 1_000_000_000,
408    max_tx_outputs: 1_000_000_000,
409    max_signature_script_len: 1_000_000_000,
410    max_script_public_key_len: 1_000_000_000,
411
412    mass_per_tx_byte: 1,
413    mass_per_script_pub_key_byte: 10,
414    mass_per_sig_op: 1000,
415    max_block_mass: 500_000,
416
417    storage_mass_parameter: STORAGE_MASS_PARAMETER,
418    storage_mass_activation_daa_score: u64::MAX,
419
420    // deflationary_phase_daa_score is the DAA score after which the pre-deflationary period
421    // switches to the deflationary period. This number is calculated as follows:
422    // We define a year as 365.25 days
423    // Half a year in seconds = 365.25 / 2 * 24 * 60 * 60 = 15778800
424    // The network was down for three days shortly after launch
425    // Three days in seconds = 3 * 24 * 60 * 60 = 259200
426    deflationary_phase_daa_score: 15778800 - 259200,
427    pre_deflationary_phase_base_subsidy: 50000000000,
428    coinbase_maturity: 100,
429    skip_proof_of_work: false,
430    max_block_level: 250,
431    pruning_proof_m: 1000,
432};
433
434pub const TESTNET11_PARAMS: Params = Params {
435    dns_seeders: &[
436        // This DNS seeder is run by Tiram
437        "seeder1-testnet-11.kaspad.net",
438        // This DNS seeder is run by supertypo
439        "n-testnet-11.kaspa.ws",
440        // This DNS seeder is run by -gerri-
441        "dnsseeder-kaspa-testnet11.x-con.at",
442        // This DNS seeder is run by H@H
443        "ns-testnet11.kaspa-dnsseeder.net",
444    ],
445    net: NetworkId::with_suffix(NetworkType::Testnet, 11),
446    genesis: TESTNET11_GENESIS,
447    legacy_timestamp_deviation_tolerance: LEGACY_TIMESTAMP_DEVIATION_TOLERANCE,
448    new_timestamp_deviation_tolerance: NEW_TIMESTAMP_DEVIATION_TOLERANCE,
449    past_median_time_sampled_window_size: MEDIAN_TIME_SAMPLED_WINDOW_SIZE,
450    sampling_activation_daa_score: 0, // Sampling is activated from network inception
451    max_difficulty_target: MAX_DIFFICULTY_TARGET,
452    max_difficulty_target_f64: MAX_DIFFICULTY_TARGET_AS_F64,
453    sampled_difficulty_window_size: DIFFICULTY_SAMPLED_WINDOW_SIZE as usize,
454    legacy_difficulty_window_size: LEGACY_DIFFICULTY_WINDOW_SIZE,
455    min_difficulty_window_len: MIN_DIFFICULTY_WINDOW_LEN,
456
457    //
458    // ~~~~~~~~~~~~~~~~~~ BPS dependent constants ~~~~~~~~~~~~~~~~~~
459    //
460    ghostdag_k: Testnet11Bps::ghostdag_k(),
461    target_time_per_block: Testnet11Bps::target_time_per_block(),
462    past_median_time_sample_rate: Testnet11Bps::past_median_time_sample_rate(),
463    difficulty_sample_rate: Testnet11Bps::difficulty_adjustment_sample_rate(),
464    max_block_parents: Testnet11Bps::max_block_parents(),
465    mergeset_size_limit: Testnet11Bps::mergeset_size_limit(),
466    merge_depth: Testnet11Bps::merge_depth_bound(),
467    finality_depth: Testnet11Bps::finality_depth(),
468    pruning_depth: Testnet11Bps::pruning_depth(),
469    pruning_proof_m: Testnet11Bps::pruning_proof_m(),
470    deflationary_phase_daa_score: Testnet11Bps::deflationary_phase_daa_score(),
471    pre_deflationary_phase_base_subsidy: Testnet11Bps::pre_deflationary_phase_base_subsidy(),
472    coinbase_maturity: Testnet11Bps::coinbase_maturity(),
473
474    coinbase_payload_script_public_key_max_len: 150,
475    max_coinbase_payload_len: 204,
476
477    max_tx_inputs: 10_000,
478    max_tx_outputs: 10_000,
479    max_signature_script_len: 1_000_000,
480    max_script_public_key_len: 1_000_000,
481
482    mass_per_tx_byte: 1,
483    mass_per_script_pub_key_byte: 10,
484    mass_per_sig_op: 1000,
485    max_block_mass: 500_000,
486
487    storage_mass_parameter: STORAGE_MASS_PARAMETER,
488    storage_mass_activation_daa_score: 0,
489
490    skip_proof_of_work: false,
491    max_block_level: 250,
492};
493
494pub const SIMNET_PARAMS: Params = Params {
495    dns_seeders: &[],
496    net: NetworkId::new(NetworkType::Simnet),
497    genesis: SIMNET_GENESIS,
498    legacy_timestamp_deviation_tolerance: LEGACY_TIMESTAMP_DEVIATION_TOLERANCE,
499    new_timestamp_deviation_tolerance: NEW_TIMESTAMP_DEVIATION_TOLERANCE,
500    past_median_time_sampled_window_size: MEDIAN_TIME_SAMPLED_WINDOW_SIZE,
501    sampling_activation_daa_score: 0, // Sampling is activated from network inception
502    max_difficulty_target: MAX_DIFFICULTY_TARGET,
503    max_difficulty_target_f64: MAX_DIFFICULTY_TARGET_AS_F64,
504    sampled_difficulty_window_size: DIFFICULTY_SAMPLED_WINDOW_SIZE as usize,
505    legacy_difficulty_window_size: LEGACY_DIFFICULTY_WINDOW_SIZE,
506    min_difficulty_window_len: MIN_DIFFICULTY_WINDOW_LEN,
507
508    //
509    // ~~~~~~~~~~~~~~~~~~ BPS dependent constants ~~~~~~~~~~~~~~~~~~
510    //
511    // Note we use a 10 BPS configuration for simnet
512    ghostdag_k: Testnet11Bps::ghostdag_k(),
513    target_time_per_block: Testnet11Bps::target_time_per_block(),
514    past_median_time_sample_rate: Testnet11Bps::past_median_time_sample_rate(),
515    difficulty_sample_rate: Testnet11Bps::difficulty_adjustment_sample_rate(),
516    // For simnet, we deviate from TN11 configuration and allow at least 64 parents in order to support mempool benchmarks out of the box
517    max_block_parents: if Testnet11Bps::max_block_parents() > 64 { Testnet11Bps::max_block_parents() } else { 64 },
518    mergeset_size_limit: Testnet11Bps::mergeset_size_limit(),
519    merge_depth: Testnet11Bps::merge_depth_bound(),
520    finality_depth: Testnet11Bps::finality_depth(),
521    pruning_depth: Testnet11Bps::pruning_depth(),
522    pruning_proof_m: Testnet11Bps::pruning_proof_m(),
523    deflationary_phase_daa_score: Testnet11Bps::deflationary_phase_daa_score(),
524    pre_deflationary_phase_base_subsidy: Testnet11Bps::pre_deflationary_phase_base_subsidy(),
525    coinbase_maturity: Testnet11Bps::coinbase_maturity(),
526
527    coinbase_payload_script_public_key_max_len: 150,
528    max_coinbase_payload_len: 204,
529
530    max_tx_inputs: 10_000,
531    max_tx_outputs: 10_000,
532    max_signature_script_len: 1_000_000,
533    max_script_public_key_len: 1_000_000,
534
535    mass_per_tx_byte: 1,
536    mass_per_script_pub_key_byte: 10,
537    mass_per_sig_op: 1000,
538    max_block_mass: 500_000,
539
540    storage_mass_parameter: STORAGE_MASS_PARAMETER,
541    storage_mass_activation_daa_score: 0,
542
543    skip_proof_of_work: true, // For simnet only, PoW can be simulated by default
544    max_block_level: 250,
545};
546
547pub const DEVNET_PARAMS: Params = Params {
548    dns_seeders: &[],
549    net: NetworkId::new(NetworkType::Devnet),
550    genesis: DEVNET_GENESIS,
551    ghostdag_k: LEGACY_DEFAULT_GHOSTDAG_K,
552    legacy_timestamp_deviation_tolerance: LEGACY_TIMESTAMP_DEVIATION_TOLERANCE,
553    new_timestamp_deviation_tolerance: NEW_TIMESTAMP_DEVIATION_TOLERANCE,
554    past_median_time_sample_rate: Bps::<1>::past_median_time_sample_rate(),
555    past_median_time_sampled_window_size: MEDIAN_TIME_SAMPLED_WINDOW_SIZE,
556    target_time_per_block: 1000,
557    sampling_activation_daa_score: u64::MAX,
558    max_difficulty_target: MAX_DIFFICULTY_TARGET,
559    max_difficulty_target_f64: MAX_DIFFICULTY_TARGET_AS_F64,
560    difficulty_sample_rate: Bps::<1>::difficulty_adjustment_sample_rate(),
561    sampled_difficulty_window_size: DIFFICULTY_SAMPLED_WINDOW_SIZE as usize,
562    legacy_difficulty_window_size: LEGACY_DIFFICULTY_WINDOW_SIZE,
563    min_difficulty_window_len: MIN_DIFFICULTY_WINDOW_LEN,
564    max_block_parents: 10,
565    mergeset_size_limit: (LEGACY_DEFAULT_GHOSTDAG_K as u64) * 10,
566    merge_depth: 3600,
567    finality_depth: 86400,
568    pruning_depth: 185798,
569    coinbase_payload_script_public_key_max_len: 150,
570    max_coinbase_payload_len: 204,
571
572    // This is technically a soft fork from the Go implementation since kaspad's consensus doesn't
573    // check these rules, but in practice it's enforced by the network layer that limits the message
574    // size to 1 GB.
575    // These values should be lowered to more reasonable amounts on the next planned HF/SF.
576    max_tx_inputs: 1_000_000_000,
577    max_tx_outputs: 1_000_000_000,
578    max_signature_script_len: 1_000_000_000,
579    max_script_public_key_len: 1_000_000_000,
580
581    mass_per_tx_byte: 1,
582    mass_per_script_pub_key_byte: 10,
583    mass_per_sig_op: 1000,
584    max_block_mass: 500_000,
585
586    storage_mass_parameter: STORAGE_MASS_PARAMETER,
587    storage_mass_activation_daa_score: u64::MAX,
588
589    // deflationary_phase_daa_score is the DAA score after which the pre-deflationary period
590    // switches to the deflationary period. This number is calculated as follows:
591    // We define a year as 365.25 days
592    // Half a year in seconds = 365.25 / 2 * 24 * 60 * 60 = 15778800
593    // The network was down for three days shortly after launch
594    // Three days in seconds = 3 * 24 * 60 * 60 = 259200
595    deflationary_phase_daa_score: 15778800 - 259200,
596    pre_deflationary_phase_base_subsidy: 50000000000,
597    coinbase_maturity: 100,
598    skip_proof_of_work: false,
599    max_block_level: 250,
600    pruning_proof_m: 1000,
601};