github.com/cosmos/cosmos-sdk@v0.50.10/x/slashing/README.md (about)

     1  ---
     2  sidebar_position: 1
     3  ---
     4  
     5  # `x/slashing`
     6  
     7  ## Abstract
     8  
     9  This section specifies the slashing module of the Cosmos SDK, which implements functionality
    10  first outlined in the [Cosmos Whitepaper](https://cosmos.network/about/whitepaper) in June 2016.
    11  
    12  The slashing module enables Cosmos SDK-based blockchains to disincentivize any attributable action
    13  by a protocol-recognized actor with value at stake by penalizing them ("slashing").
    14  
    15  Penalties may include, but are not limited to:
    16  
    17  * Burning some amount of their stake
    18  * Removing their ability to vote on future blocks for a period of time.
    19  
    20  This module will be used by the Cosmos Hub, the first hub in the Cosmos ecosystem.
    21  
    22  ## Contents
    23  
    24  * [Concepts](#concepts)
    25      * [States](#states)
    26      * [Tombstone Caps](#tombstone-caps)
    27      * [Infraction Timelines](#infraction-timelines)
    28  * [State](#state)
    29      * [Signing Info (Liveness)](#signing-info-liveness)
    30      * [Params](#params)
    31  * [Messages](#messages)
    32      * [Unjail](#unjail)
    33  * [BeginBlock](#beginblock)
    34      * [Liveness Tracking](#liveness-tracking)
    35  * [Hooks](#hooks)
    36  * [Events](#events)
    37  * [Staking Tombstone](#staking-tombstone)
    38  * [Parameters](#parameters)
    39  * [CLI](#cli)
    40      * [Query](#query)
    41      * [Transactions](#transactions)
    42      * [gRPC](#grpc)
    43      * [REST](#rest)
    44  
    45  ## Concepts
    46  
    47  ### States
    48  
    49  At any given time, there are any number of validators registered in the state
    50  machine. Each block, the top `MaxValidators` (defined by `x/staking`) validators
    51  who are not jailed become _bonded_, meaning that they may propose and vote on
    52  blocks. Validators who are _bonded_ are _at stake_, meaning that part or all of
    53  their stake and their delegators' stake is at risk if they commit a protocol fault.
    54  
    55  For each of these validators we keep a `ValidatorSigningInfo` record that contains
    56  information partaining to validator's liveness and other infraction related
    57  attributes.
    58  
    59  ### Tombstone Caps
    60  
    61  In order to mitigate the impact of initially likely categories of non-malicious
    62  protocol faults, the Cosmos Hub implements for each validator
    63  a _tombstone_ cap, which only allows a validator to be slashed once for a double
    64  sign fault. For example, if you misconfigure your HSM and double-sign a bunch of
    65  old blocks, you'll only be punished for the first double-sign (and then immediately tombstombed). This will still be quite expensive and desirable to avoid, but tombstone caps
    66  somewhat blunt the economic impact of unintentional misconfiguration.
    67  
    68  Liveness faults do not have caps, as they can't stack upon each other. Liveness bugs are "detected" as soon as the infraction occurs, and the validators are immediately put in jail, so it is not possible for them to commit multiple liveness faults without unjailing in between.
    69  
    70  ### Infraction Timelines
    71  
    72  To illustrate how the `x/slashing` module handles submitted evidence through
    73  CometBFT consensus, consider the following examples:
    74  
    75  **Definitions**:
    76  
    77  _[_ : timeline start  
    78  _]_ : timeline end  
    79  _C<sub>n</sub>_ : infraction `n` committed  
    80  _D<sub>n</sub>_ : infraction `n` discovered  
    81  _V<sub>b</sub>_ : validator bonded  
    82  _V<sub>u</sub>_ : validator unbonded
    83  
    84  #### Single Double Sign Infraction
    85  
    86  \[----------C<sub>1</sub>----D<sub>1</sub>,V<sub>u</sub>-----\]
    87  
    88  A single infraction is committed then later discovered, at which point the
    89  validator is unbonded and slashed at the full amount for the infraction.
    90  
    91  #### Multiple Double Sign Infractions
    92  
    93  \[----------C<sub>1</sub>--C<sub>2</sub>---C<sub>3</sub>---D<sub>1</sub>,D<sub>2</sub>,D<sub>3</sub>V<sub>u</sub>-----\]
    94  
    95  Multiple infractions are committed and then later discovered, at which point the
    96  validator is jailed and slashed for only one infraction. Because the validator
    97  is also tombstoned, they can not rejoin the validator set.
    98  
    99  ## State
   100  
   101  ### Signing Info (Liveness)
   102  
   103  Every block includes a set of precommits by the validators for the previous block,
   104  known as the `LastCommitInfo` provided by CometBFT. A `LastCommitInfo` is valid so
   105  long as it contains precommits from +2/3 of total voting power.
   106  
   107  Proposers are incentivized to include precommits from all validators in the CometBFT `LastCommitInfo`
   108  by receiving additional fees proportional to the difference between the voting
   109  power included in the `LastCommitInfo` and +2/3 (see [fee distribution](../distribution/README.md#begin-block)).
   110  
   111  ```go
   112  type LastCommitInfo struct {
   113  	Round int32
   114  	Votes []VoteInfo
   115  }
   116  ```
   117  
   118  Validators are penalized for failing to be included in the `LastCommitInfo` for some
   119  number of blocks by being automatically jailed, potentially slashed, and unbonded.
   120  
   121  Information about validator's liveness activity is tracked through `ValidatorSigningInfo`.
   122  It is indexed in the store as follows:
   123  
   124  * ValidatorSigningInfo: `0x01 | ConsAddrLen (1 byte) | ConsAddress -> ProtocolBuffer(ValSigningInfo)`
   125  * MissedBlocksBitArray: `0x02 | ConsAddrLen (1 byte) | ConsAddress | LittleEndianUint64(signArrayIndex) -> VarInt(didMiss)` (varint is a number encoding format)
   126  
   127  The first mapping allows us to easily lookup the recent signing info for a
   128  validator based on the validator's consensus address.
   129  
   130  The second mapping (`MissedBlocksBitArray`) acts
   131  as a bit-array of size `SignedBlocksWindow` that tells us if the validator missed
   132  the block for a given index in the bit-array. The index in the bit-array is given
   133  as little endian uint64.
   134  The result is a `varint` that takes on `0` or `1`, where `0` indicates the
   135  validator did not miss (did sign) the corresponding block, and `1` indicates
   136  they missed the block (did not sign).
   137  
   138  Note that the `MissedBlocksBitArray` is not explicitly initialized up-front. Keys
   139  are added as we progress through the first `SignedBlocksWindow` blocks for a newly
   140  bonded validator. The `SignedBlocksWindow` parameter defines the size
   141  (number of blocks) of the sliding window used to track validator liveness.
   142  
   143  The information stored for tracking validator liveness is as follows:
   144  
   145  ```protobuf reference
   146  https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/slashing/v1beta1/slashing.proto#L13-L35
   147  ```
   148  
   149  ### Params
   150  
   151  The slashing module stores it's params in state with the prefix of `0x00`,
   152  it can be updated with governance or the address with authority.
   153  
   154  * Params: `0x00 | ProtocolBuffer(Params)`
   155  
   156  ```protobuf reference
   157  https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/slashing/v1beta1/slashing.proto#L37-L59
   158  ```
   159  
   160  ## Messages
   161  
   162  In this section we describe the processing of messages for the `slashing` module.
   163  
   164  ### Unjail
   165  
   166  If a validator was automatically unbonded due to downtime and wishes to come back online &
   167  possibly rejoin the bonded set, it must send `MsgUnjail`:
   168  
   169  ```protobuf
   170  // MsgUnjail is an sdk.Msg used for unjailing a jailed validator, thus returning
   171  // them into the bonded validator set, so they can begin receiving provisions
   172  // and rewards again.
   173  message MsgUnjail {
   174    string validator_addr = 1;
   175  }
   176  ```
   177  
   178  Below is a pseudocode of the `MsgSrv/Unjail` RPC:
   179  
   180  ```go
   181  unjail(tx MsgUnjail)
   182      validator = getValidator(tx.ValidatorAddr)
   183      if validator == nil
   184        fail with "No validator found"
   185  
   186      if getSelfDelegation(validator) == 0
   187        fail with "validator must self delegate before unjailing"
   188  
   189      if !validator.Jailed
   190        fail with "Validator not jailed, cannot unjail"
   191  
   192      info = GetValidatorSigningInfo(operator)
   193      if info.Tombstoned
   194        fail with "Tombstoned validator cannot be unjailed"
   195      if block time < info.JailedUntil
   196        fail with "Validator still jailed, cannot unjail until period has expired"
   197  
   198      validator.Jailed = false
   199      setValidator(validator)
   200  
   201      return
   202  ```
   203  
   204  If the validator has enough stake to be in the top `n = MaximumBondedValidators`, it will be automatically rebonded,
   205  and all delegators still delegated to the validator will be rebonded and begin to again collect
   206  provisions and rewards.
   207  
   208  ## BeginBlock
   209  
   210  ### Liveness Tracking
   211  
   212  At the beginning of each block, we update the `ValidatorSigningInfo` for each
   213  validator and check if they've crossed below the liveness threshold over a
   214  sliding window. This sliding window is defined by `SignedBlocksWindow` and the
   215  index in this window is determined by `IndexOffset` found in the validator's
   216  `ValidatorSigningInfo`. For each block processed, the `IndexOffset` is incremented
   217  regardless if the validator signed or not. Once the index is determined, the
   218  `MissedBlocksBitArray` and `MissedBlocksCounter` are updated accordingly.
   219  
   220  Finally, in order to determine if a validator crosses below the liveness threshold,
   221  we fetch the maximum number of blocks missed, `maxMissed`, which is
   222  `SignedBlocksWindow - (MinSignedPerWindow * SignedBlocksWindow)` and the minimum
   223  height at which we can determine liveness, `minHeight`. If the current block is
   224  greater than `minHeight` and the validator's `MissedBlocksCounter` is greater than
   225  `maxMissed`, they will be slashed by `SlashFractionDowntime`, will be jailed
   226  for `DowntimeJailDuration`, and have the following values reset:
   227  `MissedBlocksBitArray`, `MissedBlocksCounter`, and `IndexOffset`.
   228  
   229  **Note**: Liveness slashes do **NOT** lead to a tombstombing.
   230  
   231  ```go
   232  height := block.Height
   233  
   234  for vote in block.LastCommitInfo.Votes {
   235    signInfo := GetValidatorSigningInfo(vote.Validator.Address)
   236  
   237    // This is a relative index, so we counts blocks the validator SHOULD have
   238    // signed. We use the 0-value default signing info if not present, except for
   239    // start height.
   240    index := signInfo.IndexOffset % SignedBlocksWindow()
   241    signInfo.IndexOffset++
   242  
   243    // Update MissedBlocksBitArray and MissedBlocksCounter. The MissedBlocksCounter
   244    // just tracks the sum of MissedBlocksBitArray. That way we avoid needing to
   245    // read/write the whole array each time.
   246    missedPrevious := GetValidatorMissedBlockBitArray(vote.Validator.Address, index)
   247    missed := !signed
   248  
   249    switch {
   250    case !missedPrevious && missed:
   251      // array index has changed from not missed to missed, increment counter
   252      SetValidatorMissedBlockBitArray(vote.Validator.Address, index, true)
   253      signInfo.MissedBlocksCounter++
   254  
   255    case missedPrevious && !missed:
   256      // array index has changed from missed to not missed, decrement counter
   257      SetValidatorMissedBlockBitArray(vote.Validator.Address, index, false)
   258      signInfo.MissedBlocksCounter--
   259  
   260    default:
   261      // array index at this index has not changed; no need to update counter
   262    }
   263  
   264    if missed {
   265      // emit events...
   266    }
   267  
   268    minHeight := signInfo.StartHeight + SignedBlocksWindow()
   269    maxMissed := SignedBlocksWindow() - MinSignedPerWindow()
   270  
   271    // If we are past the minimum height and the validator has missed too many
   272    // jail and slash them.
   273    if height > minHeight && signInfo.MissedBlocksCounter > maxMissed {
   274      validator := ValidatorByConsAddr(vote.Validator.Address)
   275  
   276      // emit events...
   277  
   278      // We need to retrieve the stake distribution which signed the block, so we
   279      // subtract ValidatorUpdateDelay from the block height, and subtract an
   280      // additional 1 since this is the LastCommit.
   281      //
   282      // Note, that this CAN result in a negative "distributionHeight" up to
   283      // -ValidatorUpdateDelay-1, i.e. at the end of the pre-genesis block (none) = at the beginning of the genesis block.
   284      // That's fine since this is just used to filter unbonding delegations & redelegations.
   285      distributionHeight := height - sdk.ValidatorUpdateDelay - 1
   286  
   287      SlashWithInfractionReason(vote.Validator.Address, distributionHeight, vote.Validator.Power, SlashFractionDowntime(), stakingtypes.Downtime)
   288      Jail(vote.Validator.Address)
   289  
   290      signInfo.JailedUntil = block.Time.Add(DowntimeJailDuration())
   291  
   292      // We need to reset the counter & array so that the validator won't be
   293      // immediately slashed for downtime upon rebonding.
   294      signInfo.MissedBlocksCounter = 0
   295      signInfo.IndexOffset = 0
   296      ClearValidatorMissedBlockBitArray(vote.Validator.Address)
   297    }
   298  
   299    SetValidatorSigningInfo(vote.Validator.Address, signInfo)
   300  }
   301  ```
   302  
   303  ## Hooks
   304  
   305  This section contains a description of the module's `hooks`. Hooks are operations that are executed automatically when events are raised.
   306  
   307  ### Staking hooks
   308  
   309  The slashing module implements the `StakingHooks` defined in `x/staking` and are used as record-keeping of validators information. During the app initialization, these hooks should be registered in the staking module struct.
   310  
   311  The following hooks impact the slashing state:
   312  
   313  * `AfterValidatorBonded` creates a `ValidatorSigningInfo` instance as described in the following section.
   314  * `AfterValidatorCreated` stores a validator's consensus key.
   315  * `AfterValidatorRemoved` removes a validator's consensus key.
   316  
   317  ### Validator Bonded
   318  
   319  Upon successful first-time bonding of a new validator, we create a new `ValidatorSigningInfo` structure for the
   320  now-bonded validator, which `StartHeight` of the current block.
   321  
   322  If the validator was out of the validator set and gets bonded again, its new bonded height is set.
   323  
   324  ```go
   325  onValidatorBonded(address sdk.ValAddress)
   326  
   327    signingInfo, found = GetValidatorSigningInfo(address)
   328    if !found {
   329      signingInfo = ValidatorSigningInfo {
   330        StartHeight         : CurrentHeight,
   331        IndexOffset         : 0,
   332        JailedUntil         : time.Unix(0, 0),
   333        Tombstone           : false,
   334        MissedBloskCounter  : 0
   335      } else {
   336        signingInfo.StartHeight = CurrentHeight
   337      }
   338  
   339      setValidatorSigningInfo(signingInfo)
   340    }
   341  
   342    return
   343  ```
   344  
   345  ## Events
   346  
   347  The slashing module emits the following events:
   348  
   349  ### MsgServer
   350  
   351  #### MsgUnjail
   352  
   353  | Type    | Attribute Key | Attribute Value    |
   354  | ------- | ------------- | ------------------ |
   355  | message | module        | slashing           |
   356  | message | sender        | {validatorAddress} |
   357  
   358  ### Keeper
   359  
   360  ### BeginBlocker: HandleValidatorSignature
   361  
   362  | Type  | Attribute Key | Attribute Value             |
   363  | ----- | ------------- | --------------------------- |
   364  | slash | address       | {validatorConsensusAddress} |
   365  | slash | power         | {validatorPower}            |
   366  | slash | reason        | {slashReason}               |
   367  | slash | jailed [0]    | {validatorConsensusAddress} |
   368  | slash | burned coins  | {math.Int}                   |
   369  
   370  * [0] Only included if the validator is jailed.
   371  
   372  | Type     | Attribute Key | Attribute Value             |
   373  | -------- | ------------- | --------------------------- |
   374  | liveness | address       | {validatorConsensusAddress} |
   375  | liveness | missed_blocks | {missedBlocksCounter}       |
   376  | liveness | height        | {blockHeight}               |
   377  
   378  #### Slash
   379  
   380  * same as `"slash"` event from `HandleValidatorSignature`, but without the `jailed` attribute.
   381  
   382  #### Jail
   383  
   384  | Type  | Attribute Key | Attribute Value    |
   385  | ----- | ------------- | ------------------ |
   386  | slash | jailed        | {validatorAddress} |
   387  
   388  ## Staking Tombstone
   389  
   390  ### Abstract
   391  
   392  In the current implementation of the `slashing` module, when the consensus engine
   393  informs the state machine of a validator's consensus fault, the validator is
   394  partially slashed, and put into a "jail period", a period of time in which they
   395  are not allowed to rejoin the validator set. However, because of the nature of
   396  consensus faults and ABCI, there can be a delay between an infraction occurring,
   397  and evidence of the infraction reaching the state machine (this is one of the
   398  primary reasons for the existence of the unbonding period).
   399  
   400  > Note: The tombstone concept, only applies to faults that have a delay between
   401  > the infraction occurring and evidence reaching the state machine. For example,
   402  > evidence of a validator double signing may take a while to reach the state machine
   403  > due to unpredictable evidence gossip layer delays and the ability of validators to
   404  > selectively reveal double-signatures (e.g. to infrequently-online light clients).
   405  > Liveness slashing, on the other hand, is detected immediately as soon as the
   406  > infraction occurs, and therefore no slashing period is needed. A validator is
   407  > immediately put into jail period, and they cannot commit another liveness fault
   408  > until they unjail. In the future, there may be other types of byzantine faults
   409  > that have delays (for example, submitting evidence of an invalid proposal as a transaction).
   410  > When implemented, it will have to be decided whether these future types of
   411  > byzantine faults will result in a tombstoning (and if not, the slash amounts
   412  > will not be capped by a slashing period).
   413  
   414  In the current system design, once a validator is put in the jail for a consensus
   415  fault, after the `JailPeriod` they are allowed to send a transaction to `unjail`
   416  themselves, and thus rejoin the validator set.
   417  
   418  One of the "design desires" of the `slashing` module is that if multiple
   419  infractions occur before evidence is executed (and a validator is put in jail),
   420  they should only be punished for single worst infraction, but not cumulatively.
   421  For example, if the sequence of events is:
   422  
   423  1. Validator A commits Infraction 1 (worth 30% slash)
   424  2. Validator A commits Infraction 2 (worth 40% slash)
   425  3. Validator A commits Infraction 3 (worth 35% slash)
   426  4. Evidence for Infraction 1 reaches state machine (and validator is put in jail)
   427  5. Evidence for Infraction 2 reaches state machine
   428  6. Evidence for Infraction 3 reaches state machine
   429  
   430  Only Infraction 2 should have its slash take effect, as it is the highest. This
   431  is done, so that in the case of the compromise of a validator's consensus key,
   432  they will only be punished once, even if the hacker double-signs many blocks.
   433  Because, the unjailing has to be done with the validator's operator key, they
   434  have a chance to re-secure their consensus key, and then signal that they are
   435  ready using their operator key. We call this period during which we track only
   436  the max infraction, the "slashing period".
   437  
   438  Once, a validator rejoins by unjailing themselves, we begin a new slashing period;
   439  if they commit a new infraction after unjailing, it gets slashed cumulatively on
   440  top of the worst infraction from the previous slashing period.
   441  
   442  However, while infractions are grouped based off of the slashing periods, because
   443  evidence can be submitted up to an `unbondingPeriod` after the infraction, we
   444  still have to allow for evidence to be submitted for previous slashing periods.
   445  For example, if the sequence of events is:
   446  
   447  1. Validator A commits Infraction 1 (worth 30% slash)
   448  2. Validator A commits Infraction 2 (worth 40% slash)
   449  3. Evidence for Infraction 1 reaches state machine (and Validator A is put in jail)
   450  4. Validator A unjails
   451  
   452  We are now in a new slashing period, however we still have to keep the door open
   453  for the previous infraction, as the evidence for Infraction 2 may still come in.
   454  As the number of slashing periods increase, it creates more complexity as we have
   455  to keep track of the highest infraction amount for every single slashing period.
   456  
   457  > Note: Currently, according to the `slashing` module spec, a new slashing period
   458  > is created every time a validator is unbonded then rebonded. This should probably
   459  > be changed to jailed/unjailed. See issue [#3205](https://github.com/cosmos/cosmos-sdk/issues/3205)
   460  > for further details. For the remainder of this, I will assume that we only start
   461  > a new slashing period when a validator gets unjailed.
   462  
   463  The maximum number of slashing periods is the `len(UnbondingPeriod) / len(JailPeriod)`.
   464  The current defaults in Gaia for the `UnbondingPeriod` and `JailPeriod` are 3 weeks
   465  and 2 days, respectively. This means there could potentially be up to 11 slashing
   466  periods concurrently being tracked per validator. If we set the `JailPeriod >= UnbondingPeriod`,
   467  we only have to track 1 slashing period (i.e not have to track slashing periods).
   468  
   469  Currently, in the jail period implementation, once a validator unjails, all of
   470  their delegators who are delegated to them (haven't unbonded / redelegated away),
   471  stay with them. Given that consensus safety faults are so egregious
   472  (way more so than liveness faults), it is probably prudent to have delegators not
   473  "auto-rebond" to the validator.
   474  
   475  #### Proposal: infinite jail
   476  
   477  We propose setting the "jail time" for a
   478  validator who commits a consensus safety fault, to `infinite` (i.e. a tombstone state).
   479  This essentially kicks the validator out of the validator set and does not allow
   480  them to re-enter the validator set. All of their delegators (including the operator themselves)
   481  have to either unbond or redelegate away. The validator operator can create a new
   482  validator if they would like, with a new operator key and consensus key, but they
   483  have to "re-earn" their delegations back.
   484  
   485  Implementing the tombstone system and getting rid of the slashing period tracking
   486  will make the `slashing` module way simpler, especially because we can remove all
   487  of the hooks defined in the `slashing` module consumed by the `staking` module
   488  (the `slashing` module still consumes hooks defined in `staking`).
   489  
   490  #### Single slashing amount
   491  
   492  Another optimization that can be made is that if we assume that all ABCI faults
   493  for CometBFT consensus are slashed at the same level, we don't have to keep
   494  track of "max slash". Once an ABCI fault happens, we don't have to worry about
   495  comparing potential future ones to find the max.
   496  
   497  Currently the only CometBFT ABCI fault is:
   498  
   499  * Unjustified precommits (double signs)
   500  
   501  It is currently planned to include the following fault in the near future:
   502  
   503  * Signing a precommit when you're in unbonding phase (needed to make light client bisection safe)
   504  
   505  Given that these faults are both attributable byzantine faults, we will likely
   506  want to slash them equally, and thus we can enact the above change.
   507  
   508  > Note: This change may make sense for current CometBFT consensus, but maybe
   509  > not for a different consensus algorithm or future versions of CometBFT that
   510  > may want to punish at different levels (for example, partial slashing).
   511  
   512  ## Parameters
   513  
   514  The slashing module contains the following parameters:
   515  
   516  | Key                     | Type           | Example                |
   517  | ----------------------- | -------------- | ---------------------- |
   518  | SignedBlocksWindow      | string (int64) | "100"                  |
   519  | MinSignedPerWindow      | string (dec)   | "0.500000000000000000" |
   520  | DowntimeJailDuration    | string (ns)    | "600000000000"         |
   521  | SlashFractionDoubleSign | string (dec)   | "0.050000000000000000" |
   522  | SlashFractionDowntime   | string (dec)   | "0.010000000000000000" |
   523  
   524  ## CLI
   525  
   526  A user can query and interact with the `slashing` module using the CLI.
   527  
   528  ### Query
   529  
   530  The `query` commands allow users to query `slashing` state.
   531  
   532  ```shell
   533  simd query slashing --help
   534  ```
   535  
   536  #### params
   537  
   538  The `params` command allows users to query genesis parameters for the slashing module.
   539  
   540  ```shell
   541  simd query slashing params [flags]
   542  ```
   543  
   544  Example:
   545  
   546  ```shell
   547  simd query slashing params
   548  ```
   549  
   550  Example Output:
   551  
   552  ```yml
   553  downtime_jail_duration: 600s
   554  min_signed_per_window: "0.500000000000000000"
   555  signed_blocks_window: "100"
   556  slash_fraction_double_sign: "0.050000000000000000"
   557  slash_fraction_downtime: "0.010000000000000000"
   558  ```
   559  
   560  #### signing-info
   561  
   562  The `signing-info` command allows users to query signing-info of the validator using consensus public key.
   563  
   564  ```shell
   565  simd query slashing signing-infos [flags]
   566  ```
   567  
   568  Example:
   569  
   570  ```shell
   571  simd query slashing signing-info '{"@type":"/cosmos.crypto.ed25519.PubKey","key":"Auxs3865HpB/EfssYOzfqNhEJjzys6jD5B6tPgC8="}'
   572  
   573  ```
   574  
   575  Example Output:
   576  
   577  ```yml
   578  address: cosmosvalcons1nrqsld3aw6lh6t082frdqc84uwxn0t958c
   579  index_offset: "2068"
   580  jailed_until: "1970-01-01T00:00:00Z"
   581  missed_blocks_counter: "0"
   582  start_height: "0"
   583  tombstoned: false
   584  ```
   585  
   586  #### signing-infos
   587  
   588  The `signing-infos` command allows users to query signing infos of all validators.
   589  
   590  ```shell
   591  simd query slashing signing-infos [flags]
   592  ```
   593  
   594  Example:
   595  
   596  ```shell
   597  simd query slashing signing-infos
   598  ```
   599  
   600  Example Output:
   601  
   602  ```yml
   603  info:
   604  - address: cosmosvalcons1nrqsld3aw6lh6t082frdqc84uwxn0t958c
   605    index_offset: "2075"
   606    jailed_until: "1970-01-01T00:00:00Z"
   607    missed_blocks_counter: "0"
   608    start_height: "0"
   609    tombstoned: false
   610  pagination:
   611    next_key: null
   612    total: "0"
   613  ```
   614  
   615  ### Transactions
   616  
   617  The `tx` commands allow users to interact with the `slashing` module.
   618  
   619  ```bash
   620  simd tx slashing --help
   621  ```
   622  
   623  #### unjail
   624  
   625  The `unjail` command allows users to unjail a validator previously jailed for downtime.
   626  
   627  ```bash
   628  simd tx slashing unjail --from mykey [flags]
   629  ```
   630  
   631  Example:
   632  
   633  ```bash
   634  simd tx slashing unjail --from mykey
   635  ```
   636  
   637  ### gRPC
   638  
   639  A user can query the `slashing` module using gRPC endpoints.
   640  
   641  #### Params
   642  
   643  The `Params` endpoint allows users to query the parameters of slashing module.
   644  
   645  ```shell
   646  cosmos.slashing.v1beta1.Query/Params
   647  ```
   648  
   649  Example:
   650  
   651  ```shell
   652  grpcurl -plaintext localhost:9090 cosmos.slashing.v1beta1.Query/Params
   653  ```
   654  
   655  Example Output:
   656  
   657  ```json
   658  {
   659    "params": {
   660      "signedBlocksWindow": "100",
   661      "minSignedPerWindow": "NTAwMDAwMDAwMDAwMDAwMDAw",
   662      "downtimeJailDuration": "600s",
   663      "slashFractionDoubleSign": "NTAwMDAwMDAwMDAwMDAwMDA=",
   664      "slashFractionDowntime": "MTAwMDAwMDAwMDAwMDAwMDA="
   665    }
   666  }
   667  ```
   668  
   669  #### SigningInfo
   670  
   671  The SigningInfo queries the signing info of given cons address.
   672  
   673  ```shell
   674  cosmos.slashing.v1beta1.Query/SigningInfo
   675  ```
   676  
   677  Example:
   678  
   679  ```shell
   680  grpcurl -plaintext -d '{"cons_address":"cosmosvalcons1nrqsld3aw6lh6t082frdqc84uwxn0t958c"}' localhost:9090 cosmos.slashing.v1beta1.Query/SigningInfo
   681  ```
   682  
   683  Example Output:
   684  
   685  ```json
   686  {
   687    "valSigningInfo": {
   688      "address": "cosmosvalcons1nrqsld3aw6lh6t082frdqc84uwxn0t958c",
   689      "indexOffset": "3493",
   690      "jailedUntil": "1970-01-01T00:00:00Z"
   691    }
   692  }
   693  ```
   694  
   695  #### SigningInfos
   696  
   697  The SigningInfos queries signing info of all validators.
   698  
   699  ```shell
   700  cosmos.slashing.v1beta1.Query/SigningInfos
   701  ```
   702  
   703  Example:
   704  
   705  ```shell
   706  grpcurl -plaintext localhost:9090 cosmos.slashing.v1beta1.Query/SigningInfos
   707  ```
   708  
   709  Example Output:
   710  
   711  ```json
   712  {
   713    "info": [
   714      {
   715        "address": "cosmosvalcons1nrqslkwd3pz096lh6t082frdqc84uwxn0t958c",
   716        "indexOffset": "2467",
   717        "jailedUntil": "1970-01-01T00:00:00Z"
   718      }
   719    ],
   720    "pagination": {
   721      "total": "1"
   722    }
   723  }
   724  ```
   725  
   726  ### REST
   727  
   728  A user can query the `slashing` module using REST endpoints.
   729  
   730  #### Params
   731  
   732  ```shell
   733  /cosmos/slashing/v1beta1/params
   734  ```
   735  
   736  Example:
   737  
   738  ```shell
   739  curl "localhost:1317/cosmos/slashing/v1beta1/params"
   740  ```
   741  
   742  Example Output:
   743  
   744  ```json
   745  {
   746    "params": {
   747      "signed_blocks_window": "100",
   748      "min_signed_per_window": "0.500000000000000000",
   749      "downtime_jail_duration": "600s",
   750      "slash_fraction_double_sign": "0.050000000000000000",
   751      "slash_fraction_downtime": "0.010000000000000000"
   752  }
   753  ```
   754  
   755  #### signing_info
   756  
   757  ```shell
   758  /cosmos/slashing/v1beta1/signing_infos/%s
   759  ```
   760  
   761  Example:
   762  
   763  ```shell
   764  curl "localhost:1317/cosmos/slashing/v1beta1/signing_infos/cosmosvalcons1nrqslkwd3pz096lh6t082frdqc84uwxn0t958c"
   765  ```
   766  
   767  Example Output:
   768  
   769  ```json
   770  {
   771    "val_signing_info": {
   772      "address": "cosmosvalcons1nrqslkwd3pz096lh6t082frdqc84uwxn0t958c",
   773      "start_height": "0",
   774      "index_offset": "4184",
   775      "jailed_until": "1970-01-01T00:00:00Z",
   776      "tombstoned": false,
   777      "missed_blocks_counter": "0"
   778    }
   779  }
   780  ```
   781  
   782  #### signing_infos
   783  
   784  ```shell
   785  /cosmos/slashing/v1beta1/signing_infos
   786  ```
   787  
   788  Example:
   789  
   790  ```shell
   791  curl "localhost:1317/cosmos/slashing/v1beta1/signing_infos
   792  ```
   793  
   794  Example Output:
   795  
   796  ```json
   797  {
   798    "info": [
   799      {
   800        "address": "cosmosvalcons1nrqslkwd3pz096lh6t082frdqc84uwxn0t958c",
   801        "start_height": "0",
   802        "index_offset": "4169",
   803        "jailed_until": "1970-01-01T00:00:00Z",
   804        "tombstoned": false,
   805        "missed_blocks_counter": "0"
   806      }
   807    ],
   808    "pagination": {
   809      "next_key": null,
   810      "total": "1"
   811    }
   812  }
   813  ```