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 ```