penumbra_sdk_stake/
params.rs

1use penumbra_sdk_num::Amount;
2use penumbra_sdk_proto::core::component::stake::v1 as pb;
3use penumbra_sdk_proto::DomainType;
4use serde::{Deserialize, Serialize};
5
6#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
7#[serde(try_from = "pb::StakeParameters", into = "pb::StakeParameters")]
8pub struct StakeParameters {
9    /// The number of blocks to wait before a validator can unbond their stake.
10    pub unbonding_delay: u64,
11    /// The number of validators allowed in the consensus set (Active state).
12    pub active_validator_limit: u64,
13    /// The penalty for slashing due to misbehavior, expressed in basis points squared (10^-8)
14    pub slashing_penalty_misbehavior: u64,
15    /// The penalty for slashing due to downtime, expressed in basis points squared (10^-8)
16    pub slashing_penalty_downtime: u64,
17    /// The number of blocks in the window to check for downtime.
18    pub signed_blocks_window_len: u64,
19    /// The maximum number of blocks in the window each validator can miss signing without slashing.
20    pub missed_blocks_maximum: u64,
21    /// The minimum amount of stake required for a validator to be indexed.
22    pub min_validator_stake: Amount,
23}
24
25impl DomainType for StakeParameters {
26    type Proto = pb::StakeParameters;
27}
28
29impl TryFrom<pb::StakeParameters> for StakeParameters {
30    type Error = anyhow::Error;
31
32    fn try_from(msg: pb::StakeParameters) -> anyhow::Result<Self> {
33        Ok(StakeParameters {
34            active_validator_limit: msg.active_validator_limit,
35            slashing_penalty_downtime: msg.slashing_penalty_downtime,
36            slashing_penalty_misbehavior: msg.slashing_penalty_misbehavior,
37            missed_blocks_maximum: msg.missed_blocks_maximum,
38            signed_blocks_window_len: msg.signed_blocks_window_len,
39            min_validator_stake: msg
40                .min_validator_stake
41                .ok_or_else(|| anyhow::anyhow!("missing min_validator_stake"))?
42                .try_into()?,
43            unbonding_delay: msg.unbonding_delay,
44        })
45    }
46}
47
48impl From<StakeParameters> for pb::StakeParameters {
49    #[allow(deprecated)]
50    fn from(params: StakeParameters) -> Self {
51        pb::StakeParameters {
52            unbonding_epochs: 0,
53            active_validator_limit: params.active_validator_limit,
54            signed_blocks_window_len: params.signed_blocks_window_len,
55            missed_blocks_maximum: params.missed_blocks_maximum,
56            slashing_penalty_downtime: params.slashing_penalty_downtime,
57            slashing_penalty_misbehavior: params.slashing_penalty_misbehavior,
58            base_reward_rate: 0,
59            min_validator_stake: Some(params.min_validator_stake.into()),
60            unbonding_delay: params.unbonding_delay,
61        }
62    }
63}
64
65impl Default for StakeParameters {
66    fn default() -> Self {
67        Self {
68            // About a week worth of blocks.
69            unbonding_delay: 120960,
70            active_validator_limit: 80,
71            // Copied from cosmos hub
72            signed_blocks_window_len: 10000,
73            missed_blocks_maximum: 9500,
74            // 1000 basis points = 10%
75            slashing_penalty_misbehavior: 1000_0000,
76            // 1 basis point = 0.01%
77            slashing_penalty_downtime: 1_0000,
78            // 1 penumbra
79            min_validator_stake: 1_000_000u128.into(),
80        }
81    }
82}