From 4f8c9e4917feb8208bf32852c209431196b2101e Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 13 Aug 2018 14:51:01 +0200 Subject: [PATCH 01/32] Update transactions.md --- docs/spec/slashing/transactions.md | 42 +++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/docs/spec/slashing/transactions.md b/docs/spec/slashing/transactions.md index cdf495e4d..33e3bd65e 100644 --- a/docs/spec/slashing/transactions.md +++ b/docs/spec/slashing/transactions.md @@ -1,19 +1,41 @@ +## Transaction Overview -### TxProveLive +In this section we describe the processing of transactions for the `slashing` module. -If a validator was automatically unbonded due to liveness issues and wishes to -assert it is still online, it can send `TxProveLive`: +### TxUnjail + +If a validator was automatically unbonded due to downtime and wishes to come back online & +possibly rejoin the bonded set, it must send `TxUnjail`: ```golang -type TxProveLive struct { - PubKey crypto.PubKey +type TxUnjail struct { + ValidatorAddr sdk.AccAddress } ``` -All delegators in the temporary unbonding pool which have not -transacted to move will be bonded back to the now-live validator and begin to -once again collect provisions and rewards. +All delegators still delegated to the validator will be rebonded and begin +to again collect provisions and rewards. -``` -TODO: pseudo-code +```golang +handleMsgUnjail(operator sdk.AccAddress) + + validator := getValidator(operator) + if validator == nil + fail with "No validator found" + + if !validator.Jailed + fail with "Validator not jailed, cannot unjail" + + info := getValidatorSigningInfo(operator) + if BlockHeader.Time.Before(info.JailedUntil) + fail with "Validator still jailed, cannot unjail until period has expired" + + // Update the start height so the validator won't be immediately unbonded again + info.StartHeight = BlockHeight + setValidatorSigningInfo(info) + + validator.Jailed = false + setValidator(validator) + + return ``` From 84e9b215b290030c76ed5135a687f312d3e1e7f7 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 13 Aug 2018 14:54:42 +0200 Subject: [PATCH 02/32] Fix typo --- docs/spec/slashing/transactions.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/spec/slashing/transactions.md b/docs/spec/slashing/transactions.md index 33e3bd65e..f241b12d2 100644 --- a/docs/spec/slashing/transactions.md +++ b/docs/spec/slashing/transactions.md @@ -17,9 +17,9 @@ All delegators still delegated to the validator will be rebonded and begin to again collect provisions and rewards. ```golang -handleMsgUnjail(operator sdk.AccAddress) +handleMsgUnjail(tx TxUnjail) - validator := getValidator(operator) + validator := getValidator(tx.ValidatorAddr) if validator == nil fail with "No validator found" From 98a278d5646f277690decc994dd4cafe608657d9 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 13 Aug 2018 14:56:10 +0200 Subject: [PATCH 03/32] Reorganize sections --- docs/spec/slashing/transactions.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/docs/spec/slashing/transactions.md b/docs/spec/slashing/transactions.md index f241b12d2..c6a9470fc 100644 --- a/docs/spec/slashing/transactions.md +++ b/docs/spec/slashing/transactions.md @@ -11,12 +11,7 @@ possibly rejoin the bonded set, it must send `TxUnjail`: type TxUnjail struct { ValidatorAddr sdk.AccAddress } -``` -All delegators still delegated to the validator will be rebonded and begin -to again collect provisions and rewards. - -```golang handleMsgUnjail(tx TxUnjail) validator := getValidator(tx.ValidatorAddr) @@ -39,3 +34,7 @@ handleMsgUnjail(tx TxUnjail) return ``` + +If the validotor has enough stake to be in the top hundred, they will be automatically rebonded, +and all delegators still delegated to the validator will be rebonded and begin to again collect +provisions and rewards. From ff01cbb093f5a54772773ea636a5b93e9ce7be54 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 13 Aug 2018 15:48:23 +0200 Subject: [PATCH 04/32] Update state.md --- docs/spec/slashing/state.md | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/docs/spec/slashing/state.md b/docs/spec/slashing/state.md index 1df9d5022..f4412067b 100644 --- a/docs/spec/slashing/state.md +++ b/docs/spec/slashing/state.md @@ -36,10 +36,11 @@ The information stored for tracking validator liveness is as follows: ```go type ValidatorSigningInfo struct { - StartHeight int64 - IndexOffset int64 - JailedUntil int64 - SignedBlocksCounter int64 + StartHeight int64 // Height at which the validator became able to sign blocks + IndexOffset int64 // Offset into the signed block bit array + JailedUntil int64 // Block height until which the validator is jailed, + // or sentinel value of 0 for not jailed + SignedBlocksCounter int64 // Running counter of signed blocks } ``` @@ -49,3 +50,29 @@ Where: * `IndexOffset` is incremented each time the candidate was a bonded validator in a block (and may have signed a precommit or not). * `JailedUntil` is set whenever the candidate is revoked due to downtime * `SignedBlocksCounter` is a counter kept to avoid unnecessary array reads. `SignedBlocksBitArray.Sum() == SignedBlocksCounter` always. + +### Slashing Period + +A slashing period is a start and end time associated with a particular validator, +within which only the "worst infraction counts": the total amount of slashing for +infractions committed within the period (and discovered whenever) is capped at the +penalty for the worst offense. + +This period starts when a validator is first bonded and ends when a validator is slashed & jailed +for double-signing (but does not end if they are slashed & jailed for just missing blocks). +When the validator voluntarily unjails themselves (and possibly changes signing keys), they reset the period. + +Slashing periods are indexed in the store as follows: + +- SlashingPeriod: ` 0x03 | ValTendermintAddr -> amino(slashingPeriod) ` + +This allows us to look up slashing period by validator address, the only lookup necessary. + +```go +type SlashingPeriod struct { + ValidatorAddr sdk.ValAddress // Tendermint address of the validator + StartHeight int64 // Block height at which slashing period begin + EndHeight int64 // Block height at which slashing period ended + SlashedSoFar sdk.Rat // Fraction slashed so far, cumulative +} +``` From 53fa4a28dcb3e72f54d4a793e9195190af903123 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 13 Aug 2018 15:55:30 +0200 Subject: [PATCH 05/32] Start update of state-machine.md --- .../{transactions.md => state-machine.md} | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) rename docs/spec/slashing/{transactions.md => state-machine.md} (70%) diff --git a/docs/spec/slashing/transactions.md b/docs/spec/slashing/state-machine.md similarity index 70% rename from docs/spec/slashing/transactions.md rename to docs/spec/slashing/state-machine.md index c6a9470fc..67a5ce39a 100644 --- a/docs/spec/slashing/transactions.md +++ b/docs/spec/slashing/state-machine.md @@ -1,8 +1,10 @@ -## Transaction Overview +## Transaction & State Machine Interaction Overview + +### Transactions In this section we describe the processing of transactions for the `slashing` module. -### TxUnjail +#### TxUnjail If a validator was automatically unbonded due to downtime and wishes to come back online & possibly rejoin the bonded set, it must send `TxUnjail`: @@ -35,6 +37,19 @@ handleMsgUnjail(tx TxUnjail) return ``` -If the validotor has enough stake to be in the top hundred, they will be automatically rebonded, +If the validater has enough stake to be in the top hundred, they will be automatically rebonded, and all delegators still delegated to the validator will be rebonded and begin to again collect provisions and rewards. + +### Interactions + +#### Validator Bonded + +#### Validator Slashed + +#### Validator Unjailed + +#### Slashing Period Cleanup + +Once no evidence for a given slashing period can possibly be valid (the end time plus the unbonding period is less than the current time), +old slashing periods should be cleaned up. From a8af4a4fadc4c275570289e3e703b763149fcb72 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 13 Aug 2018 16:04:35 +0200 Subject: [PATCH 06/32] End block to begin block, add README --- docs/spec/slashing/README.md | 29 +++++++++++++++++++ .../slashing/{end_block.md => begin-block.md} | 9 +++--- 2 files changed, 34 insertions(+), 4 deletions(-) create mode 100644 docs/spec/slashing/README.md rename docs/spec/slashing/{end_block.md => begin-block.md} (95%) diff --git a/docs/spec/slashing/README.md b/docs/spec/slashing/README.md new file mode 100644 index 000000000..23e5e604a --- /dev/null +++ b/docs/spec/slashing/README.md @@ -0,0 +1,29 @@ +# Slashing module specification + +## Abstract + +This section specifies the slashing module of the Cosmos SDK, which implements functionality +first outlined in the [Cosmos Whitepaper](https://cosmos.network/about/whitepaper) in June 2016. + +The slashing module enables Cosmos SDK-based blockchains to disincentivize any attributable action +by a protocol-recognized actor with value at stake by "slashing" them: burning some amount of their +stake - and possibly also removing their ability to vote on future blocks for a period of time. + +This module will be used by the Cosmos Hub, the first hub in the Cosmos ecosystem. + +## Contents + +1. **[State](state.md)** + 1. SigningInfo + 1. SlashingPeriod +1. **[State Machine](state-machine.md)** + 1. Transactions + 1. Unjail + 1. Interactions + 1. Validator Bonded + 1. Validator Slashed + 1. Validator Unjailed + 1. Slashing Period Cleanup +1. **[Begin Block](begin-block.md)** + 1. Evidence handling & slashing + 1. Uptime/downtime tracking & slashing diff --git a/docs/spec/slashing/end_block.md b/docs/spec/slashing/begin-block.md similarity index 95% rename from docs/spec/slashing/end_block.md rename to docs/spec/slashing/begin-block.md index 3eec27372..bdd7d9692 100644 --- a/docs/spec/slashing/end_block.md +++ b/docs/spec/slashing/begin-block.md @@ -1,12 +1,13 @@ -# End-Block +# Begin-Block -## Slashing +## Evidence handling & slashing Tendermint blocks can include [Evidence](https://github.com/tendermint/tendermint/blob/develop/docs/spec/blockchain/blockchain.md#evidence), which indicates that a validator committed malicious behaviour. The relevant information is forwarded to the application as [ABCI -Evidence](https://github.com/tendermint/tendermint/blob/develop/abci/types/types.proto#L259), so the validator an be accordingly punished. +Evidence](https://github.com/tendermint/tendermint/blob/develop/abci/types/types.proto#L259) in `abci.RequestBeginBlock` +so that the validator an be accordingly punished. For some `evidence` to be valid, it must satisfy: @@ -75,7 +76,7 @@ This ensures that offending validators are punished the same amount whether they act as a single validator with X stake or as N validators with collectively X stake. -## Automatic Unbonding +## Uptime/downtime tracking & slashing At the beginning of each block, we update the signing info for each validator and check if they should be automatically unbonded: From 07a7db7fdad9e596d158ccdbea476c3f3734da5d Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 13 Aug 2018 16:12:59 +0200 Subject: [PATCH 07/32] Update links --- docs/spec/slashing/README.md | 12 ++++++------ docs/spec/slashing/begin-block.md | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/spec/slashing/README.md b/docs/spec/slashing/README.md index 23e5e604a..da3069ffc 100644 --- a/docs/spec/slashing/README.md +++ b/docs/spec/slashing/README.md @@ -14,16 +14,16 @@ This module will be used by the Cosmos Hub, the first hub in the Cosmos ecosyste ## Contents 1. **[State](state.md)** - 1. SigningInfo - 1. SlashingPeriod + 1. [SigningInfo](state.md#signing-info) + 1. [SlashingPeriod](state.md#slashing-period) 1. **[State Machine](state-machine.md)** - 1. Transactions + 1. [Transactions](state-machine.md#transactions) 1. Unjail - 1. Interactions + 1. [Interactions](state-machine.md#interactions) 1. Validator Bonded 1. Validator Slashed 1. Validator Unjailed 1. Slashing Period Cleanup 1. **[Begin Block](begin-block.md)** - 1. Evidence handling & slashing - 1. Uptime/downtime tracking & slashing + 1. [Evidence handling](begin-block.md#evidence-handling) + 1. [Uptime tracking](begin-block.md#uptime-tracking) diff --git a/docs/spec/slashing/begin-block.md b/docs/spec/slashing/begin-block.md index bdd7d9692..9c2e5c121 100644 --- a/docs/spec/slashing/begin-block.md +++ b/docs/spec/slashing/begin-block.md @@ -1,6 +1,6 @@ # Begin-Block -## Evidence handling & slashing +## Evidence handling Tendermint blocks can include [Evidence](https://github.com/tendermint/tendermint/blob/develop/docs/spec/blockchain/blockchain.md#evidence), which indicates that a validator @@ -76,7 +76,7 @@ This ensures that offending validators are punished the same amount whether they act as a single validator with X stake or as N validators with collectively X stake. -## Uptime/downtime tracking & slashing +## Uptime tracking At the beginning of each block, we update the signing info for each validator and check if they should be automatically unbonded: From 2445718295931fe953a60c6ac9ee8a014c4ce85f Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 13 Aug 2018 17:03:37 +0200 Subject: [PATCH 08/32] State machine contd. --- docs/spec/slashing/README.md | 4 ++-- docs/spec/slashing/state-machine.md | 31 ++++++++++++++++++++++++++--- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/docs/spec/slashing/README.md b/docs/spec/slashing/README.md index da3069ffc..7e8b780a2 100644 --- a/docs/spec/slashing/README.md +++ b/docs/spec/slashing/README.md @@ -21,9 +21,9 @@ This module will be used by the Cosmos Hub, the first hub in the Cosmos ecosyste 1. Unjail 1. [Interactions](state-machine.md#interactions) 1. Validator Bonded + 1. Validator Unbonding 1. Validator Slashed - 1. Validator Unjailed - 1. Slashing Period Cleanup + 1. [State Cleanup](state-machine.md#state-cleanup) 1. **[Begin Block](begin-block.md)** 1. [Evidence handling](begin-block.md#evidence-handling) 1. [Uptime tracking](begin-block.md#uptime-tracking) diff --git a/docs/spec/slashing/state-machine.md b/docs/spec/slashing/state-machine.md index 67a5ce39a..22987bb6e 100644 --- a/docs/spec/slashing/state-machine.md +++ b/docs/spec/slashing/state-machine.md @@ -43,13 +43,38 @@ provisions and rewards. ### Interactions +In this section we describe the "hooks" - slashing module code that runs when other events happen. + #### Validator Bonded +Upon successful bonding of a validator (a given validator changing from "unbonded" state to "bonded" state, +which may happen on delegation, on unjailing, etc), we create a new `SlashingPeriod` structure for the +now-bonded validator, wich `StartHeight` of the current block, `EndHeight` of `0` (sentinel value for not-yet-ended), +and `SlashedSoFar` of `0`: + +```golang +onValidatorBonded(address sdk.ValAddress) +``` + +#### Validator Unbonded + +When a validator is unbonded, we update the in-progress `SlashingPeriod` with the current block as the `EndHeight`: + +```golang +onValidatorUnbonded(address sdk.ValAddress) +``` + #### Validator Slashed -#### Validator Unjailed +When a validator is slashed, we look up the appropriate `SlashingPeriod` based on the validator +address and the time of infraction, cap the fraction slashed as `max(SlashFraction, SlashedSoFar)` +(which may be `0`), and update the `SlashingPeriod` with the increased `SlashedSoFar`: -#### Slashing Period Cleanup +```golang +beforeValidatorSlashed(address sdk.ValAddress, fraction sdk.Rat) +``` + +### State Cleanup Once no evidence for a given slashing period can possibly be valid (the end time plus the unbonding period is less than the current time), -old slashing periods should be cleaned up. +old slashing periods should be cleaned up. This will be implemented post-launch. From 8b7d6e0979a950e6124381ecee5f40321b6a687a Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 13 Aug 2018 17:52:58 +0200 Subject: [PATCH 09/32] Update state machine, contd. --- docs/spec/slashing/state-machine.md | 28 +++++++++++++++++++++++++++- docs/spec/slashing/state.md | 6 ++++-- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/docs/spec/slashing/state-machine.md b/docs/spec/slashing/state-machine.md index 22987bb6e..77b41f9b5 100644 --- a/docs/spec/slashing/state-machine.md +++ b/docs/spec/slashing/state-machine.md @@ -54,6 +54,16 @@ and `SlashedSoFar` of `0`: ```golang onValidatorBonded(address sdk.ValAddress) + + slashingPeriod := SlashingPeriod{ + ValidatorAddr : address, + StartHeight : CurrentHeight, + EndHeight : 0, + SlashedSoFar : 0, + } + setSlashingPeriod(slashingPeriod) + + return ``` #### Validator Unbonded @@ -62,6 +72,12 @@ When a validator is unbonded, we update the in-progress `SlashingPeriod` with th ```golang onValidatorUnbonded(address sdk.ValAddress) + + slashingPeriod = getSlashingPeriod(address, CurrentHeight) + slashingPeriod.EndHeight = CurrentHeight + setSlashingPeriod(slashingPeriod) + + return ``` #### Validator Slashed @@ -71,7 +87,17 @@ address and the time of infraction, cap the fraction slashed as `max(SlashFracti (which may be `0`), and update the `SlashingPeriod` with the increased `SlashedSoFar`: ```golang -beforeValidatorSlashed(address sdk.ValAddress, fraction sdk.Rat) +beforeValidatorSlashed(address sdk.ValAddress, fraction sdk.Rat, infractionHeight int64) + + slashingPeriod = getSlashingPeriod(address, infractionHeight) + totalToSlash = max(slashingPeriod.SlashedSoFar, fraction) + slashingPeriod.SlashedSoFar = totalToSlash + setSlashingPeriod(slashingPeriod) + + remainderToSlash = slashingPeriod.SlashedSoFar - totalToSlash + fraction = remainderToSlash + + continue with slashing ``` ### State Cleanup diff --git a/docs/spec/slashing/state.md b/docs/spec/slashing/state.md index f4412067b..07bf3261c 100644 --- a/docs/spec/slashing/state.md +++ b/docs/spec/slashing/state.md @@ -64,9 +64,11 @@ When the validator voluntarily unjails themselves (and possibly changes signing Slashing periods are indexed in the store as follows: -- SlashingPeriod: ` 0x03 | ValTendermintAddr -> amino(slashingPeriod) ` +- SlashingPeriod: ` 0x03 | ValTendermintAddr | StartHeight -> amino(slashingPeriod) ` -This allows us to look up slashing period by validator address, the only lookup necessary. +This allows us to look up slashing period by validator address, the only lookup necessary, +and iterate over start height to efficiently retrieve the most recent slashing period(s) +or those beginning after a given height. ```go type SlashingPeriod struct { From 52475b1684f94a3d5fc7876cdeeb9c017324e8b6 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Tue, 14 Aug 2018 11:31:39 +0200 Subject: [PATCH 10/32] Fix minor typos --- docs/spec/slashing/state-machine.md | 2 +- docs/spec/slashing/state.md | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/spec/slashing/state-machine.md b/docs/spec/slashing/state-machine.md index 77b41f9b5..1105ceded 100644 --- a/docs/spec/slashing/state-machine.md +++ b/docs/spec/slashing/state-machine.md @@ -49,7 +49,7 @@ In this section we describe the "hooks" - slashing module code that runs when ot Upon successful bonding of a validator (a given validator changing from "unbonded" state to "bonded" state, which may happen on delegation, on unjailing, etc), we create a new `SlashingPeriod` structure for the -now-bonded validator, wich `StartHeight` of the current block, `EndHeight` of `0` (sentinel value for not-yet-ended), +now-bonded validator, which `StartHeight` of the current block, `EndHeight` of `0` (sentinel value for not-yet-ended), and `SlashedSoFar` of `0`: ```golang diff --git a/docs/spec/slashing/state.md b/docs/spec/slashing/state.md index 07bf3261c..cf39a8493 100644 --- a/docs/spec/slashing/state.md +++ b/docs/spec/slashing/state.md @@ -38,7 +38,7 @@ The information stored for tracking validator liveness is as follows: type ValidatorSigningInfo struct { StartHeight int64 // Height at which the validator became able to sign blocks IndexOffset int64 // Offset into the signed block bit array - JailedUntil int64 // Block height until which the validator is jailed, + JailedUntilHeight int64 // Block height until which the validator is jailed, // or sentinel value of 0 for not jailed SignedBlocksCounter int64 // Running counter of signed blocks } @@ -53,7 +53,7 @@ Where: ### Slashing Period -A slashing period is a start and end time associated with a particular validator, +A slashing period is a start and end block height associated with a particular validator, within which only the "worst infraction counts": the total amount of slashing for infractions committed within the period (and discovered whenever) is capped at the penalty for the worst offense. @@ -66,7 +66,7 @@ Slashing periods are indexed in the store as follows: - SlashingPeriod: ` 0x03 | ValTendermintAddr | StartHeight -> amino(slashingPeriod) ` -This allows us to look up slashing period by validator address, the only lookup necessary, +This allows us to look up slashing period by a validator's address, the only lookup necessary, and iterate over start height to efficiently retrieve the most recent slashing period(s) or those beginning after a given height. From a2463d038b285923c3f06dd597bc05ce63c8b2c9 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Tue, 14 Aug 2018 18:04:32 +0200 Subject: [PATCH 11/32] Clarify points from PR review --- docs/spec/slashing/state.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/spec/slashing/state.md b/docs/spec/slashing/state.md index cf39a8493..050f4c9ae 100644 --- a/docs/spec/slashing/state.md +++ b/docs/spec/slashing/state.md @@ -59,8 +59,8 @@ infractions committed within the period (and discovered whenever) is capped at t penalty for the worst offense. This period starts when a validator is first bonded and ends when a validator is slashed & jailed -for double-signing (but does not end if they are slashed & jailed for just missing blocks). -When the validator voluntarily unjails themselves (and possibly changes signing keys), they reset the period. +for any reason. When the validator rejoins the validator set (perhaps through unjailing themselves, +and perhaps also changing signing keys), they enter into a new period. Slashing periods are indexed in the store as follows: From 21be609f5281e44985c248433692a30cbd4fbe69 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Tue, 14 Aug 2018 19:04:57 +0200 Subject: [PATCH 12/32] Changes WIP --- docs/spec/slashing/state-machine.md | 20 +++++++++++++++++--- docs/spec/slashing/state.md | 4 +++- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/docs/spec/slashing/state-machine.md b/docs/spec/slashing/state-machine.md index 1105ceded..023d0a78b 100644 --- a/docs/spec/slashing/state-machine.md +++ b/docs/spec/slashing/state-machine.md @@ -80,6 +80,20 @@ onValidatorUnbonded(address sdk.ValAddress) return ``` +#### Validator Power Changed + +When a validator's power changes, we update the in-progress `SlashingPeriod` with the validator's current power: + +```golang +onValidatorPowerChanged(address sdk.ValAddress, stakeBonded sdk.Rat) + + slashingPeriod = getSlashingPeriod(address, CurrentHeight) + slashingPeriod.MaxStakeBonded = max(slashingPeriod.MaxStakeBonded, stakeBonded) + setSlashingPeriod(slashingPeriod) + + return +``` + #### Validator Slashed When a validator is slashed, we look up the appropriate `SlashingPeriod` based on the validator @@ -90,11 +104,11 @@ address and the time of infraction, cap the fraction slashed as `max(SlashFracti beforeValidatorSlashed(address sdk.ValAddress, fraction sdk.Rat, infractionHeight int64) slashingPeriod = getSlashingPeriod(address, infractionHeight) - totalToSlash = max(slashingPeriod.SlashedSoFar, fraction) - slashingPeriod.SlashedSoFar = totalToSlash + totalFractionToSlash = max(slashingPeriod.SlashedSoFar, fraction) + slashingPeriod.FractionSlashedSoFar = totalToSlash setSlashingPeriod(slashingPeriod) - remainderToSlash = slashingPeriod.SlashedSoFar - totalToSlash + remainderToSlash = slashingPeriod.FractionSlashedSoFar - totalToSlash fraction = remainderToSlash continue with slashing diff --git a/docs/spec/slashing/state.md b/docs/spec/slashing/state.md index 050f4c9ae..a8a834476 100644 --- a/docs/spec/slashing/state.md +++ b/docs/spec/slashing/state.md @@ -75,6 +75,8 @@ type SlashingPeriod struct { ValidatorAddr sdk.ValAddress // Tendermint address of the validator StartHeight int64 // Block height at which slashing period begin EndHeight int64 // Block height at which slashing period ended - SlashedSoFar sdk.Rat // Fraction slashed so far, cumulative + MaxBondedStake sdk.Rat // Maximum bonded stake during period + StakeSlashedSoFar sdk.Rat // Amount of stake slashed so far + FractionSlashedSoFar sdk.Rat // Fraction slashed so far, cumulative } ``` From 38c65f036c711b68c89cc7c2e15c9dd8a4e0b357 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 15 Aug 2018 15:51:01 +0200 Subject: [PATCH 13/32] Update PR template --- .github/PULL_REQUEST_TEMPLATE.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index f7e2d0fd6..060a9f2e3 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -4,12 +4,18 @@ v Before smashing the submit button please review the checkboxes. v If a checkbox is n/a - please still include it but + a little note why ☺ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > --> +- Targeted PR against correct branch + - `release/vxx.yy.zz` for a merge into a release candidate + - `master` for a merge of a release + - `develop` in the usual case + - [ ] Linked to github-issue with discussion and accepted design OR link to spec that describes this work. - [ ] Updated all relevant documentation (`docs/`) - [ ] Updated all relevant code comments - [ ] Wrote tests - [ ] Added entries in `PENDING.md` that include links to the relevant issue or PR that most accurately describes the change. - [ ] Updated `cmd/gaia` and `examples/` + ___________________________________ For Admin Use: - [ ] Added appropriate labels to PR (ex. wip, ready-for-review, docs) From 8afacac99d164336bbfe763de47a0451e8acdc6e Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 15 Aug 2018 15:53:41 +0200 Subject: [PATCH 14/32] Remove extra space --- .github/PULL_REQUEST_TEMPLATE.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 060a9f2e3..76ccb0d6b 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -4,7 +4,7 @@ v Before smashing the submit button please review the checkboxes. v If a checkbox is n/a - please still include it but + a little note why ☺ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > --> -- Targeted PR against correct branch +- Targeted PR against correct branch: - `release/vxx.yy.zz` for a merge into a release candidate - `master` for a merge of a release - `develop` in the usual case @@ -15,7 +15,6 @@ v If a checkbox is n/a - please still include it but + a little note why - [ ] Wrote tests - [ ] Added entries in `PENDING.md` that include links to the relevant issue or PR that most accurately describes the change. - [ ] Updated `cmd/gaia` and `examples/` - ___________________________________ For Admin Use: - [ ] Added appropriate labels to PR (ex. wip, ready-for-review, docs) From 79e3c0536778b526ed36ab403e13532875e59dab Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 20 Aug 2018 15:01:18 +0200 Subject: [PATCH 15/32] Revert "Changes WIP" - we decided not to do this This reverts commit 21be609f5281e44985c248433692a30cbd4fbe69. --- docs/spec/slashing/state-machine.md | 20 +++----------------- docs/spec/slashing/state.md | 4 +--- 2 files changed, 4 insertions(+), 20 deletions(-) diff --git a/docs/spec/slashing/state-machine.md b/docs/spec/slashing/state-machine.md index 023d0a78b..1105ceded 100644 --- a/docs/spec/slashing/state-machine.md +++ b/docs/spec/slashing/state-machine.md @@ -80,20 +80,6 @@ onValidatorUnbonded(address sdk.ValAddress) return ``` -#### Validator Power Changed - -When a validator's power changes, we update the in-progress `SlashingPeriod` with the validator's current power: - -```golang -onValidatorPowerChanged(address sdk.ValAddress, stakeBonded sdk.Rat) - - slashingPeriod = getSlashingPeriod(address, CurrentHeight) - slashingPeriod.MaxStakeBonded = max(slashingPeriod.MaxStakeBonded, stakeBonded) - setSlashingPeriod(slashingPeriod) - - return -``` - #### Validator Slashed When a validator is slashed, we look up the appropriate `SlashingPeriod` based on the validator @@ -104,11 +90,11 @@ address and the time of infraction, cap the fraction slashed as `max(SlashFracti beforeValidatorSlashed(address sdk.ValAddress, fraction sdk.Rat, infractionHeight int64) slashingPeriod = getSlashingPeriod(address, infractionHeight) - totalFractionToSlash = max(slashingPeriod.SlashedSoFar, fraction) - slashingPeriod.FractionSlashedSoFar = totalToSlash + totalToSlash = max(slashingPeriod.SlashedSoFar, fraction) + slashingPeriod.SlashedSoFar = totalToSlash setSlashingPeriod(slashingPeriod) - remainderToSlash = slashingPeriod.FractionSlashedSoFar - totalToSlash + remainderToSlash = slashingPeriod.SlashedSoFar - totalToSlash fraction = remainderToSlash continue with slashing diff --git a/docs/spec/slashing/state.md b/docs/spec/slashing/state.md index a8a834476..050f4c9ae 100644 --- a/docs/spec/slashing/state.md +++ b/docs/spec/slashing/state.md @@ -75,8 +75,6 @@ type SlashingPeriod struct { ValidatorAddr sdk.ValAddress // Tendermint address of the validator StartHeight int64 // Block height at which slashing period begin EndHeight int64 // Block height at which slashing period ended - MaxBondedStake sdk.Rat // Maximum bonded stake during period - StakeSlashedSoFar sdk.Rat // Amount of stake slashed so far - FractionSlashedSoFar sdk.Rat // Fraction slashed so far, cumulative + SlashedSoFar sdk.Rat // Fraction slashed so far, cumulative } ``` From 94dc512034640629234e411c76d11c704126b580 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 20 Aug 2018 15:07:23 +0200 Subject: [PATCH 16/32] Fix typos --- docs/spec/slashing/begin-block.md | 2 +- docs/spec/slashing/state-machine.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/spec/slashing/begin-block.md b/docs/spec/slashing/begin-block.md index 9c2e5c121..750228367 100644 --- a/docs/spec/slashing/begin-block.md +++ b/docs/spec/slashing/begin-block.md @@ -4,7 +4,7 @@ Tendermint blocks can include [Evidence](https://github.com/tendermint/tendermint/blob/develop/docs/spec/blockchain/blockchain.md#evidence), which indicates that a validator -committed malicious behaviour. The relevant information is forwarded to the +committed malicious behavior. The relevant information is forwarded to the application as [ABCI Evidence](https://github.com/tendermint/tendermint/blob/develop/abci/types/types.proto#L259) in `abci.RequestBeginBlock` so that the validator an be accordingly punished. diff --git a/docs/spec/slashing/state-machine.md b/docs/spec/slashing/state-machine.md index 1105ceded..b6bdf5820 100644 --- a/docs/spec/slashing/state-machine.md +++ b/docs/spec/slashing/state-machine.md @@ -37,7 +37,7 @@ handleMsgUnjail(tx TxUnjail) return ``` -If the validater has enough stake to be in the top hundred, they will be automatically rebonded, +If the validator has enough stake to be in the top hundred, they will be automatically rebonded, and all delegators still delegated to the validator will be rebonded and begin to again collect provisions and rewards. From e3cb1e12742347ff57dc500bcbb6da43b2d2e3ae Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 20 Aug 2018 15:13:17 +0200 Subject: [PATCH 17/32] Add safety note --- docs/spec/slashing/state-machine.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/spec/slashing/state-machine.md b/docs/spec/slashing/state-machine.md index b6bdf5820..df849398b 100644 --- a/docs/spec/slashing/state-machine.md +++ b/docs/spec/slashing/state-machine.md @@ -100,6 +100,17 @@ beforeValidatorSlashed(address sdk.ValAddress, fraction sdk.Rat, infractionHeigh continue with slashing ``` +##### Safety note + +Slashing is capped fractionally per period, but the amount of total bonded stake associated with any given validator can change (by an unbounded amount) over that period. + +For example, with MaxFractionSlashedPerPeriod = `0.5`, if a validator is initially slashed at `0.4` near the start of a period when they have 100 steak bonded, +then later slashed at `0.4` when they have `1000` steak bonded, the total amount slashed is just `40 + 100 = 140` (since the latter slash is capped at `0.1`) - +whereas if they had `1000` steak bonded initially, the total amount slashed would have been `500`. + +This means that any slashing events which utilize the slashing period (are capped-per-period) **must** *also* jail the validator when the infraction is discovered. +Otherwise it would be possible for a validator to slash themselves intentionally at a low bond, then increase their bond but no longer be at stake since they would have already hit the `SlashedSoFar` cap. + ### State Cleanup Once no evidence for a given slashing period can possibly be valid (the end time plus the unbonding period is less than the current time), From b8d6465613b9ba8f5ab730bff215a0f3f35c9ae2 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 20 Aug 2018 16:58:24 +0200 Subject: [PATCH 18/32] Conceptual overview & ASCII diagrams of slashing period --- docs/spec/slashing/state-machine.md | 57 +++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/docs/spec/slashing/state-machine.md b/docs/spec/slashing/state-machine.md index df849398b..46566caa6 100644 --- a/docs/spec/slashing/state-machine.md +++ b/docs/spec/slashing/state-machine.md @@ -1,5 +1,62 @@ ## Transaction & State Machine Interaction Overview +### Conceptual overview + +#### States + +At any given time, there are any number of validator candidates registered in the state machine. +Each block, the top `n` candidates who are not jailed become *bonded*, meaning that they may propose and vote on blocks. +Validators who are *bonded* are *at stake*, meaning that part or all of their stake is at risk if they commit a protocol fault. + +#### Slashing period + +In order to mitigate the impact of initially likely categories of non-malicious protocol faults, the Cosmos Hub implements for each validator +a *slashing period*, in which the amount by which a validator can be slashed is capped at the punishment for the worst violation. For example, +if you misconfigure your HSM and double-sign a bunch of old blocks, you'll only be punished for the first double-sign (and then immediately jailed, +so that you have a chance to reconfigure your setup). This will still be quite expensive and desirable to avoid, but slashing periods somewhat blunt +the economic impact of unintentional misconfiguration. + +A new slashing period starts whenever a validator is bonded and ends whenever the validator is unbonded (which will happen if the validator is jailed). +The amount of tokens slashed relative to validator power for infractions committed within the slashing period, whenever they are discovered, is capped +at the punishment for the worst infraction (which for the Cosmos Hub at launch will be double-signing a block). + +##### ASCII timelines + +*Code* + +*[* : timeline start +*]* : timeline end +*<* : slashing period start +*>* : slashing period end +*Cn* : infraction `n` committed +*Dn* : infraction `n` discovered +*Vb* : validator bonded +*Vu* : validator unbonded + +*Single infraction* + +<-----------------> +[----------C1----D1,Vu-----] + +A single infraction is committed then later discovered, at which point the validator is unbonded and slashed at the full amount for the infraction. + +*Multiple infractions* + +<----------------------------> +[----------C1--C2---C3---D1,D2,D3Vu-----] + +Multiple infractions are committed within a single slashing period then later discovered, at which point the validator is unbonded and slashed for only the worst infraction. + +*Multiple infractions after rebonding* + + +<---------------------------->                        <--------------> +[----------C1--C2---C3---D1,D2,D3Vu---Vb---C4----D4,Vu--] + +Multiple infractions are committed within a single slashing period then later discovered, at which point the validator is unbonded and slashed for only the worst infraction. +The validator then unjails themself and rebonds, then commits a fourth infraction - which is discovered and punished at the full amount, since a new slashing period started +when they unjailed and rebonded. + ### Transactions In this section we describe the processing of transactions for the `slashing` module. From da92b1bb1dafb3b8e15014242e038df00702800a Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 20 Aug 2018 18:28:40 +0200 Subject: [PATCH 19/32] h_n => h_n-1 --- docs/spec/slashing/state-machine.md | 24 ++++++++++++------------ docs/spec/slashing/state.md | 6 +++--- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/docs/spec/slashing/state-machine.md b/docs/spec/slashing/state-machine.md index 46566caa6..56eb82b46 100644 --- a/docs/spec/slashing/state-machine.md +++ b/docs/spec/slashing/state-machine.md @@ -1,14 +1,14 @@ -## Transaction & State Machine Interaction Overview +# State Machine Interaction Overview -### Conceptual overview +## Conceptual overview -#### States +### States At any given time, there are any number of validator candidates registered in the state machine. Each block, the top `n` candidates who are not jailed become *bonded*, meaning that they may propose and vote on blocks. Validators who are *bonded* are *at stake*, meaning that part or all of their stake is at risk if they commit a protocol fault. -#### Slashing period +### Slashing period In order to mitigate the impact of initially likely categories of non-malicious protocol faults, the Cosmos Hub implements for each validator a *slashing period*, in which the amount by which a validator can be slashed is capped at the punishment for the worst violation. For example, @@ -20,7 +20,7 @@ A new slashing period starts whenever a validator is bonded and ends whenever th The amount of tokens slashed relative to validator power for infractions committed within the slashing period, whenever they are discovered, is capped at the punishment for the worst infraction (which for the Cosmos Hub at launch will be double-signing a block). -##### ASCII timelines +#### ASCII timelines *Code* @@ -57,11 +57,11 @@ Multiple infractions are committed within a single slashing period then later di The validator then unjails themself and rebonds, then commits a fourth infraction - which is discovered and punished at the full amount, since a new slashing period started when they unjailed and rebonded. -### Transactions +## Transactions In this section we describe the processing of transactions for the `slashing` module. -#### TxUnjail +### TxUnjail If a validator was automatically unbonded due to downtime and wishes to come back online & possibly rejoin the bonded set, it must send `TxUnjail`: @@ -98,11 +98,11 @@ If the validator has enough stake to be in the top hundred, they will be automat and all delegators still delegated to the validator will be rebonded and begin to again collect provisions and rewards. -### Interactions +## Interactions In this section we describe the "hooks" - slashing module code that runs when other events happen. -#### Validator Bonded +### Validator Bonded Upon successful bonding of a validator (a given validator changing from "unbonded" state to "bonded" state, which may happen on delegation, on unjailing, etc), we create a new `SlashingPeriod` structure for the @@ -123,7 +123,7 @@ onValidatorBonded(address sdk.ValAddress) return ``` -#### Validator Unbonded +### Validator Unbonded When a validator is unbonded, we update the in-progress `SlashingPeriod` with the current block as the `EndHeight`: @@ -137,7 +137,7 @@ onValidatorUnbonded(address sdk.ValAddress) return ``` -#### Validator Slashed +### Validator Slashed When a validator is slashed, we look up the appropriate `SlashingPeriod` based on the validator address and the time of infraction, cap the fraction slashed as `max(SlashFraction, SlashedSoFar)` @@ -168,7 +168,7 @@ whereas if they had `1000` steak bonded initially, the total amount slashed woul This means that any slashing events which utilize the slashing period (are capped-per-period) **must** *also* jail the validator when the infraction is discovered. Otherwise it would be possible for a validator to slash themselves intentionally at a low bond, then increase their bond but no longer be at stake since they would have already hit the `SlashedSoFar` cap. -### State Cleanup +## State Cleanup Once no evidence for a given slashing period can possibly be valid (the end time plus the unbonding period is less than the current time), old slashing periods should be cleaned up. This will be implemented post-launch. diff --git a/docs/spec/slashing/state.md b/docs/spec/slashing/state.md index 050f4c9ae..34e436e37 100644 --- a/docs/spec/slashing/state.md +++ b/docs/spec/slashing/state.md @@ -1,6 +1,6 @@ -## State +# State -### Signing Info +## Signing Info Every block includes a set of precommits by the validators for the previous block, known as the LastCommit. A LastCommit is valid so long as it contains precommits from +2/3 of voting power. @@ -51,7 +51,7 @@ Where: * `JailedUntil` is set whenever the candidate is revoked due to downtime * `SignedBlocksCounter` is a counter kept to avoid unnecessary array reads. `SignedBlocksBitArray.Sum() == SignedBlocksCounter` always. -### Slashing Period +## Slashing Period A slashing period is a start and end block height associated with a particular validator, within which only the "worst infraction counts": the total amount of slashing for From d0c87ff5bcf5ed00e5698e12976f682023c43dc0 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 20 Aug 2018 18:31:55 +0200 Subject: [PATCH 20/32] Go => pseudocode --- docs/spec/slashing/state-machine.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/spec/slashing/state-machine.md b/docs/spec/slashing/state-machine.md index 56eb82b46..42b8a7f70 100644 --- a/docs/spec/slashing/state-machine.md +++ b/docs/spec/slashing/state-machine.md @@ -66,22 +66,22 @@ In this section we describe the processing of transactions for the `slashing` mo If a validator was automatically unbonded due to downtime and wishes to come back online & possibly rejoin the bonded set, it must send `TxUnjail`: -```golang +``` type TxUnjail struct { ValidatorAddr sdk.AccAddress } handleMsgUnjail(tx TxUnjail) - validator := getValidator(tx.ValidatorAddr) - if validator == nil + validator = getValidator(tx.ValidatorAddr) + if validator is nil fail with "No validator found" - if !validator.Jailed + if validator is not jailed fail with "Validator not jailed, cannot unjail" - info := getValidatorSigningInfo(operator) - if BlockHeader.Time.Before(info.JailedUntil) + info = getValidatorSigningInfo(operator) + if block time is before info.JailedUntil fail with "Validator still jailed, cannot unjail until period has expired" // Update the start height so the validator won't be immediately unbonded again @@ -109,10 +109,10 @@ which may happen on delegation, on unjailing, etc), we create a new `SlashingPer now-bonded validator, which `StartHeight` of the current block, `EndHeight` of `0` (sentinel value for not-yet-ended), and `SlashedSoFar` of `0`: -```golang +``` onValidatorBonded(address sdk.ValAddress) - slashingPeriod := SlashingPeriod{ + slashingPeriod = SlashingPeriod{ ValidatorAddr : address, StartHeight : CurrentHeight, EndHeight : 0, @@ -127,7 +127,7 @@ onValidatorBonded(address sdk.ValAddress) When a validator is unbonded, we update the in-progress `SlashingPeriod` with the current block as the `EndHeight`: -```golang +``` onValidatorUnbonded(address sdk.ValAddress) slashingPeriod = getSlashingPeriod(address, CurrentHeight) @@ -143,7 +143,7 @@ When a validator is slashed, we look up the appropriate `SlashingPeriod` based o address and the time of infraction, cap the fraction slashed as `max(SlashFraction, SlashedSoFar)` (which may be `0`), and update the `SlashingPeriod` with the increased `SlashedSoFar`: -```golang +``` beforeValidatorSlashed(address sdk.ValAddress, fraction sdk.Rat, infractionHeight int64) slashingPeriod = getSlashingPeriod(address, infractionHeight) From c9e5745cd7da94e28821ddf66d97d04931d425a9 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 20 Aug 2018 18:34:03 +0200 Subject: [PATCH 21/32] Clarify example --- docs/spec/slashing/state-machine.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/spec/slashing/state-machine.md b/docs/spec/slashing/state-machine.md index 42b8a7f70..e35b6b179 100644 --- a/docs/spec/slashing/state-machine.md +++ b/docs/spec/slashing/state-machine.md @@ -161,9 +161,9 @@ beforeValidatorSlashed(address sdk.ValAddress, fraction sdk.Rat, infractionHeigh Slashing is capped fractionally per period, but the amount of total bonded stake associated with any given validator can change (by an unbounded amount) over that period. -For example, with MaxFractionSlashedPerPeriod = `0.5`, if a validator is initially slashed at `0.4` near the start of a period when they have 100 steak bonded, -then later slashed at `0.4` when they have `1000` steak bonded, the total amount slashed is just `40 + 100 = 140` (since the latter slash is capped at `0.1`) - -whereas if they had `1000` steak bonded initially, the total amount slashed would have been `500`. +For example, with MaxFractionSlashedPerPeriod = `0.5`, if a validator is initially slashed at `0.4` near the start of a period when they have 100 stake bonded, +then later slashed at `0.4` when they have `1000` stake bonded, the total amount slashed is just `40 + 100 = 140` (since the latter slash is capped at `0.1`) - +whereas if they had `1000` stake bonded initially, the first offense would have been slashed for `400` stake and the total amount slashed would have been `400 + 100 = 500`. This means that any slashing events which utilize the slashing period (are capped-per-period) **must** *also* jail the validator when the infraction is discovered. Otherwise it would be possible for a validator to slash themselves intentionally at a low bond, then increase their bond but no longer be at stake since they would have already hit the `SlashedSoFar` cap. From f18895532d279a19d9d59c3ba545d4694c6b8e04 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 20 Aug 2018 18:37:16 +0200 Subject: [PATCH 22/32] Clarify which offenses utilize the slashing period --- docs/spec/slashing/begin-block.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/spec/slashing/begin-block.md b/docs/spec/slashing/begin-block.md index 750228367..0ab888317 100644 --- a/docs/spec/slashing/begin-block.md +++ b/docs/spec/slashing/begin-block.md @@ -76,6 +76,8 @@ This ensures that offending validators are punished the same amount whether they act as a single validator with X stake or as N validators with collectively X stake. +Double signature slashes are capped by the slashing period as described in [state-machine.md](state-machine.md). + ## Uptime tracking At the beginning of each block, we update the signing info for each validator and check if they should be automatically unbonded: @@ -114,3 +116,5 @@ for val in block.Validators: SigningInfo.Set(val.Address, signInfo) ``` + +Downtime slashes are *not* capped by the slashing period, although they do reset it (since the validator is unbonded). From 97ae9632bafcb1c836f7d63b2d96422946e62900 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 22 Aug 2018 16:10:57 +0200 Subject: [PATCH 23/32] Move to CONTRIBUTING.md --- .github/PULL_REQUEST_TEMPLATE.md | 5 +---- CONTRIBUTING.md | 7 +++++++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 76ccb0d6b..5b7c7d6dc 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -4,10 +4,7 @@ v Before smashing the submit button please review the checkboxes. v If a checkbox is n/a - please still include it but + a little note why ☺ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > --> -- Targeted PR against correct branch: - - `release/vxx.yy.zz` for a merge into a release candidate - - `master` for a merge of a release - - `develop` in the usual case +- Targeted PR against correct branch (see [CONTRIBUTING.md](https://github.com/cosmos/cosmos-sdk/blob/develop/CONTRIBUTING.md#pr-targeting)) - [ ] Linked to github-issue with discussion and accepted design OR link to spec that describes this work. - [ ] Updated all relevant documentation (`docs/`) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7b7ad81fd..e1a5e7c1f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -133,6 +133,13 @@ Libraries need not follow the model strictly, but would be wise to. The SDK utilizes [semantic versioning](https://semver.org/). +### PR Targeting + +Ensure that you base and target your PR on the correct branch: + - `release/vxx.yy.zz` for a merge into a release candidate + - `master` for a merge of a release + - `develop` in the usual case + ### Development Procedure: - the latest state of development is on `develop` - `develop` must never fail `make test` or `make test_cli` From 73e1965195e5a10105b04ca2f7f8b5bc5147f604 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 22 Aug 2018 18:30:34 +0200 Subject: [PATCH 24/32] Update PENDING.md --- PENDING.md | 1 + 1 file changed, 1 insertion(+) diff --git a/PENDING.md b/PENDING.md index 7ef999a7f..068e452dd 100644 --- a/PENDING.md +++ b/PENDING.md @@ -17,6 +17,7 @@ BREAKING CHANGES * Gaia * Make the transient store key use a distinct store key. [#2013](https://github.com/cosmos/cosmos-sdk/pull/2013) * [x/stake] \#1901 Validator type's Owner field renamed to Operator; Validator's GetOwner() renamed accordingly to comply with the SDK's Validator interface. + * [docs] [#2001](https://github.com/cosmos/cosmos-sdk/pull/2001) Update slashing spec for slashing period * SDK * [core] \#1807 Switch from use of rational to decimal From 0bf061b70793dd8e65f023a137db74c6cac4235d Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Wed, 22 Aug 2018 16:04:26 -0400 Subject: [PATCH 25/32] update to tm v0.23.1 - fixes unbounded WAL growth --- CHANGELOG.md | 9 +++++++++ Gopkg.lock | 9 ++++----- Gopkg.toml | 2 +- version/version.go | 4 ++-- 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 18b9d5348..479f5913a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## 0.24.2 + +*August 22nd, 2018* + +BUG FIXES + +* Tendermint + - Fix unbounded consensus WAL growth + ## 0.24.1 *August 21st, 2018* diff --git a/Gopkg.lock b/Gopkg.lock index c3a540858..5f988fd7a 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -165,13 +165,12 @@ [[projects]] branch = "master" - digest = "1:a361611b8c8c75a1091f00027767f7779b29cb37c456a71b8f2604c88057ab40" + digest = "1:12247a2e99a060cc692f6680e5272c8adf0b8f572e6bce0d7095e624c958a240" name = "github.com/hashicorp/hcl" packages = [ ".", "hcl/ast", "hcl/parser", - "hcl/printer", "hcl/scanner", "hcl/strconv", "hcl/token", @@ -424,7 +423,7 @@ version = "v0.9.2" [[projects]] - digest = "1:26146cdb2811ce481e72138439b9b1aa17a64d54364f96bb92f97a9ef8ba4f01" + digest = "1:4f15e95fe3888cc75dd34f407d6394cbc7fd3ff24920851b92b295f6a8b556e6" name = "github.com/tendermint/tendermint" packages = [ "abci/client", @@ -487,8 +486,8 @@ "version", ] pruneopts = "UT" - revision = "013b9cef642f875634c614019ab13b17570778ad" - version = "v0.23.0" + revision = "81df19e68ab1519399fccf0cab81cb75bf9d782e" + version = "v0.23.1-rc0" [[projects]] digest = "1:4dcb0dd65feecb068ce23a234d1a07c7868a1e39f52a6defcae0bb371d03abf6" diff --git a/Gopkg.toml b/Gopkg.toml index acc3e282a..4368699b6 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -57,7 +57,7 @@ [[override]] name = "github.com/tendermint/tendermint" - version = "=v0.23.0" + version = "=v0.23.1-rc0" [[constraint]] name = "github.com/bartekn/go-bip39" diff --git a/version/version.go b/version/version.go index 707868ae0..8bfea9577 100644 --- a/version/version.go +++ b/version/version.go @@ -3,9 +3,9 @@ package version const Maj = "0" const Min = "24" -const Fix = "1" +const Fix = "2" -const Version = "0.24.1" +const Version = "0.24.2" // GitCommit set by build flags var GitCommit = "" From 4cc2054d7bf79c387af1f0dcc8203e4ac3f9797c Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 23 Aug 2018 13:43:01 +0200 Subject: [PATCH 26/32] Address @rigelrozanski comments --- docs/spec/slashing/README.md | 24 +-- docs/spec/slashing/begin-block.md | 4 +- docs/spec/slashing/future-improvements.md | 4 + docs/spec/slashing/hooks.md | 58 ++++++++ docs/spec/slashing/overview.md | 68 +++++++++ docs/spec/slashing/state-machine.md | 174 ---------------------- docs/spec/slashing/state.md | 6 +- docs/spec/slashing/transactions.md | 40 +++++ 8 files changed, 189 insertions(+), 189 deletions(-) create mode 100644 docs/spec/slashing/future-improvements.md create mode 100644 docs/spec/slashing/hooks.md create mode 100644 docs/spec/slashing/overview.md delete mode 100644 docs/spec/slashing/state-machine.md create mode 100644 docs/spec/slashing/transactions.md diff --git a/docs/spec/slashing/README.md b/docs/spec/slashing/README.md index 7e8b780a2..d50d95d36 100644 --- a/docs/spec/slashing/README.md +++ b/docs/spec/slashing/README.md @@ -6,8 +6,11 @@ This section specifies the slashing module of the Cosmos SDK, which implements f first outlined in the [Cosmos Whitepaper](https://cosmos.network/about/whitepaper) in June 2016. The slashing module enables Cosmos SDK-based blockchains to disincentivize any attributable action -by a protocol-recognized actor with value at stake by "slashing" them: burning some amount of their -stake - and possibly also removing their ability to vote on future blocks for a period of time. +by a protocol-recognized actor with value at stake by penalizing them ("slashing"). + +Penalties may include, but are not limited to: +- Burning some amount of their stake +- Removing their ability to vote on future blocks for a period of time. This module will be used by the Cosmos Hub, the first hub in the Cosmos ecosystem. @@ -16,14 +19,15 @@ This module will be used by the Cosmos Hub, the first hub in the Cosmos ecosyste 1. **[State](state.md)** 1. [SigningInfo](state.md#signing-info) 1. [SlashingPeriod](state.md#slashing-period) -1. **[State Machine](state-machine.md)** - 1. [Transactions](state-machine.md#transactions) - 1. Unjail - 1. [Interactions](state-machine.md#interactions) - 1. Validator Bonded - 1. Validator Unbonding - 1. Validator Slashed - 1. [State Cleanup](state-machine.md#state-cleanup) +1. **[Overview](overview.md)** +1. **[Transactions](transactions.md)** + 1. Unjail +1. **[Hooks](hooks.md)** + 1. Validator Bonded + 1. Validator Unbonding + 1. Validator Slashed 1. **[Begin Block](begin-block.md)** 1. [Evidence handling](begin-block.md#evidence-handling) 1. [Uptime tracking](begin-block.md#uptime-tracking) +1. **[Future Improvements](future-improvements.md)** + 1. [State cleanup](future-improvements.md#state-cleanup) diff --git a/docs/spec/slashing/begin-block.md b/docs/spec/slashing/begin-block.md index 0ab888317..375e19185 100644 --- a/docs/spec/slashing/begin-block.md +++ b/docs/spec/slashing/begin-block.md @@ -76,7 +76,7 @@ This ensures that offending validators are punished the same amount whether they act as a single validator with X stake or as N validators with collectively X stake. -Double signature slashes are capped by the slashing period as described in [state-machine.md](state-machine.md). +The amount slashed for all double signature infractions committed within a single slashing period is capped as described in [state-machine.md](state-machine.md). ## Uptime tracking @@ -117,4 +117,4 @@ for val in block.Validators: SigningInfo.Set(val.Address, signInfo) ``` -Downtime slashes are *not* capped by the slashing period, although they do reset it (since the validator is unbonded). +The amount slashed for downtime slashes is *not* capped by the slashing period in which they are committed, although they do reset it (since the validator is unbonded). diff --git a/docs/spec/slashing/future-improvements.md b/docs/spec/slashing/future-improvements.md new file mode 100644 index 000000000..84be139e8 --- /dev/null +++ b/docs/spec/slashing/future-improvements.md @@ -0,0 +1,4 @@ +## State Cleanup + +Once no evidence for a given slashing period can possibly be valid (the end time plus the unbonding period is less than the current time), +old slashing periods should be cleaned up. This will be implemented post-launch. diff --git a/docs/spec/slashing/hooks.md b/docs/spec/slashing/hooks.md new file mode 100644 index 000000000..36dde61f9 --- /dev/null +++ b/docs/spec/slashing/hooks.md @@ -0,0 +1,58 @@ +## Hooks + +In this section we describe the "hooks" - slashing module code that runs when other events happen. + +### Validator Bonded + +Upon successful bonding of a validator (a given validator entering the "bonded" state, +which may happen on delegation, on unjailing, etc), we create a new `SlashingPeriod` structure for the +now-bonded validator, which `StartHeight` of the current block, `EndHeight` of `0` (sentinel value for not-yet-ended), +and `SlashedSoFar` of `0`: + +``` +onValidatorBonded(address sdk.ValAddress) + + slashingPeriod = SlashingPeriod{ + ValidatorAddr : address, + StartHeight : CurrentHeight, + EndHeight : 0, + SlashedSoFar : 0, + } + setSlashingPeriod(slashingPeriod) + + return +``` + +### Validator Unbonded + +When a validator is unbonded, we update the in-progress `SlashingPeriod` with the current block as the `EndHeight`: + +``` +onValidatorUnbonded(address sdk.ValAddress) + + slashingPeriod = getSlashingPeriod(address, CurrentHeight) + slashingPeriod.EndHeight = CurrentHeight + setSlashingPeriod(slashingPeriod) + + return +``` + +### Validator Slashed + +When a validator is slashed, we look up the appropriate `SlashingPeriod` based on the validator +address and the time of infraction, cap the fraction slashed as `max(SlashFraction, SlashedSoFar)` +(which may be `0`), and update the `SlashingPeriod` with the increased `SlashedSoFar`: + +``` +beforeValidatorSlashed(address sdk.ValAddress, fraction sdk.Rat, infractionHeight int64) + + slashingPeriod = getSlashingPeriod(address, infractionHeight) + totalToSlash = max(slashingPeriod.SlashedSoFar, fraction) + slashingPeriod.SlashedSoFar = totalToSlash + setSlashingPeriod(slashingPeriod) + + remainderToSlash = slashingPeriod.SlashedSoFar - totalToSlash + fraction = remainderToSlash + + continue with slashing +``` diff --git a/docs/spec/slashing/overview.md b/docs/spec/slashing/overview.md new file mode 100644 index 000000000..d9a8f39c1 --- /dev/null +++ b/docs/spec/slashing/overview.md @@ -0,0 +1,68 @@ +## Conceptual overview + +### States + +At any given time, there are any number of validators registered in the state machine. +Each block, the top `n = MaximumBondedValidators` validators who are not jailed become *bonded*, meaning that they may propose and vote on blocks. +Validators who are *bonded* are *at stake*, meaning that part or all of their stake and their delegators' stake is at risk if they commit a protocol fault. + +### Slashing period + +In order to mitigate the impact of initially likely categories of non-malicious protocol faults, the Cosmos Hub implements for each validator +a *slashing period*, in which the amount by which a validator can be slashed is capped at the punishment for the worst violation. For example, +if you misconfigure your HSM and double-sign a bunch of old blocks, you'll only be punished for the first double-sign (and then immediately jailed, +so that you have a chance to reconfigure your setup). This will still be quite expensive and desirable to avoid, but slashing periods somewhat blunt +the economic impact of unintentional misconfiguration. + +Unlike the unbonding period, the slashing period doesn't have a fixed length. A new slashing period starts whenever a validator is bonded and ends +whenever the validator is unbonded (which will happen if the validator is jailed). The amount of tokens slashed relative to validator power for infractions +committed within the slashing period, whenever they are discovered, is capped at the punishment for the worst infraction +(which for the Cosmos Hub at launch will be double-signing a block). + +#### ASCII timelines + +*Code* + +*[* : timeline start +*]* : timeline end +*<* : slashing period start +*>* : slashing period end +*Cn* : infraction `n` committed +*Dn* : infraction `n` discovered +*Vb* : validator bonded +*Vu* : validator unbonded + +*Single infraction* + +<-----------------> +[----------C1----D1,Vu-----] + +A single infraction is committed then later discovered, at which point the validator is unbonded and slashed at the full amount for the infraction. + +*Multiple infractions* + +<----------------------------> +[----------C1--C2---C3---D1,D2,D3Vu-----] + +Multiple infractions are committed within a single slashing period then later discovered, at which point the validator is unbonded and slashed for only the worst infraction. + +*Multiple infractions after rebonding* + + +<---------------------------->                        <--------------> +[----------C1--C2---C3---D1,D2,D3Vu---Vb---C4----D4,Vu--] + +Multiple infractions are committed within a single slashing period then later discovered, at which point the validator is unbonded and slashed for only the worst infraction. +The validator then unjails themself and rebonds, then commits a fourth infraction - which is discovered and punished at the full amount, since a new slashing period started +when they unjailed and rebonded. + +### Safety note + +Slashing is capped fractionally per period, but the amount of total bonded stake associated with any given validator can change (by an unbounded amount) over that period. + +For example, with MaxFractionSlashedPerPeriod = `0.5`, if a validator is initially slashed at `0.4` near the start of a period when they have 100 stake bonded, +then later slashed at `0.4` when they have `1000` stake bonded, the total amount slashed is just `40 + 100 = 140` (since the latter slash is capped at `0.1`) - +whereas if they had `1000` stake bonded initially, the first offense would have been slashed for `400` stake and the total amount slashed would have been `400 + 100 = 500`. + +This means that any slashing events which utilize the slashing period (are capped-per-period) **must also** jail the validator when the infraction is discovered. +Otherwise it would be possible for a validator to slash themselves intentionally at a low bond, then increase their bond but no longer be at stake since they would have already hit the `SlashedSoFar` cap. diff --git a/docs/spec/slashing/state-machine.md b/docs/spec/slashing/state-machine.md deleted file mode 100644 index e35b6b179..000000000 --- a/docs/spec/slashing/state-machine.md +++ /dev/null @@ -1,174 +0,0 @@ -# State Machine Interaction Overview - -## Conceptual overview - -### States - -At any given time, there are any number of validator candidates registered in the state machine. -Each block, the top `n` candidates who are not jailed become *bonded*, meaning that they may propose and vote on blocks. -Validators who are *bonded* are *at stake*, meaning that part or all of their stake is at risk if they commit a protocol fault. - -### Slashing period - -In order to mitigate the impact of initially likely categories of non-malicious protocol faults, the Cosmos Hub implements for each validator -a *slashing period*, in which the amount by which a validator can be slashed is capped at the punishment for the worst violation. For example, -if you misconfigure your HSM and double-sign a bunch of old blocks, you'll only be punished for the first double-sign (and then immediately jailed, -so that you have a chance to reconfigure your setup). This will still be quite expensive and desirable to avoid, but slashing periods somewhat blunt -the economic impact of unintentional misconfiguration. - -A new slashing period starts whenever a validator is bonded and ends whenever the validator is unbonded (which will happen if the validator is jailed). -The amount of tokens slashed relative to validator power for infractions committed within the slashing period, whenever they are discovered, is capped -at the punishment for the worst infraction (which for the Cosmos Hub at launch will be double-signing a block). - -#### ASCII timelines - -*Code* - -*[* : timeline start -*]* : timeline end -*<* : slashing period start -*>* : slashing period end -*Cn* : infraction `n` committed -*Dn* : infraction `n` discovered -*Vb* : validator bonded -*Vu* : validator unbonded - -*Single infraction* - -<-----------------> -[----------C1----D1,Vu-----] - -A single infraction is committed then later discovered, at which point the validator is unbonded and slashed at the full amount for the infraction. - -*Multiple infractions* - -<----------------------------> -[----------C1--C2---C3---D1,D2,D3Vu-----] - -Multiple infractions are committed within a single slashing period then later discovered, at which point the validator is unbonded and slashed for only the worst infraction. - -*Multiple infractions after rebonding* - - -<---------------------------->                        <--------------> -[----------C1--C2---C3---D1,D2,D3Vu---Vb---C4----D4,Vu--] - -Multiple infractions are committed within a single slashing period then later discovered, at which point the validator is unbonded and slashed for only the worst infraction. -The validator then unjails themself and rebonds, then commits a fourth infraction - which is discovered and punished at the full amount, since a new slashing period started -when they unjailed and rebonded. - -## Transactions - -In this section we describe the processing of transactions for the `slashing` module. - -### TxUnjail - -If a validator was automatically unbonded due to downtime and wishes to come back online & -possibly rejoin the bonded set, it must send `TxUnjail`: - -``` -type TxUnjail struct { - ValidatorAddr sdk.AccAddress -} - -handleMsgUnjail(tx TxUnjail) - - validator = getValidator(tx.ValidatorAddr) - if validator is nil - fail with "No validator found" - - if validator is not jailed - fail with "Validator not jailed, cannot unjail" - - info = getValidatorSigningInfo(operator) - if block time is before info.JailedUntil - fail with "Validator still jailed, cannot unjail until period has expired" - - // Update the start height so the validator won't be immediately unbonded again - info.StartHeight = BlockHeight - setValidatorSigningInfo(info) - - validator.Jailed = false - setValidator(validator) - - return -``` - -If the validator has enough stake to be in the top hundred, they will be automatically rebonded, -and all delegators still delegated to the validator will be rebonded and begin to again collect -provisions and rewards. - -## Interactions - -In this section we describe the "hooks" - slashing module code that runs when other events happen. - -### Validator Bonded - -Upon successful bonding of a validator (a given validator changing from "unbonded" state to "bonded" state, -which may happen on delegation, on unjailing, etc), we create a new `SlashingPeriod` structure for the -now-bonded validator, which `StartHeight` of the current block, `EndHeight` of `0` (sentinel value for not-yet-ended), -and `SlashedSoFar` of `0`: - -``` -onValidatorBonded(address sdk.ValAddress) - - slashingPeriod = SlashingPeriod{ - ValidatorAddr : address, - StartHeight : CurrentHeight, - EndHeight : 0, - SlashedSoFar : 0, - } - setSlashingPeriod(slashingPeriod) - - return -``` - -### Validator Unbonded - -When a validator is unbonded, we update the in-progress `SlashingPeriod` with the current block as the `EndHeight`: - -``` -onValidatorUnbonded(address sdk.ValAddress) - - slashingPeriod = getSlashingPeriod(address, CurrentHeight) - slashingPeriod.EndHeight = CurrentHeight - setSlashingPeriod(slashingPeriod) - - return -``` - -### Validator Slashed - -When a validator is slashed, we look up the appropriate `SlashingPeriod` based on the validator -address and the time of infraction, cap the fraction slashed as `max(SlashFraction, SlashedSoFar)` -(which may be `0`), and update the `SlashingPeriod` with the increased `SlashedSoFar`: - -``` -beforeValidatorSlashed(address sdk.ValAddress, fraction sdk.Rat, infractionHeight int64) - - slashingPeriod = getSlashingPeriod(address, infractionHeight) - totalToSlash = max(slashingPeriod.SlashedSoFar, fraction) - slashingPeriod.SlashedSoFar = totalToSlash - setSlashingPeriod(slashingPeriod) - - remainderToSlash = slashingPeriod.SlashedSoFar - totalToSlash - fraction = remainderToSlash - - continue with slashing -``` - -##### Safety note - -Slashing is capped fractionally per period, but the amount of total bonded stake associated with any given validator can change (by an unbounded amount) over that period. - -For example, with MaxFractionSlashedPerPeriod = `0.5`, if a validator is initially slashed at `0.4` near the start of a period when they have 100 stake bonded, -then later slashed at `0.4` when they have `1000` stake bonded, the total amount slashed is just `40 + 100 = 140` (since the latter slash is capped at `0.1`) - -whereas if they had `1000` stake bonded initially, the first offense would have been slashed for `400` stake and the total amount slashed would have been `400 + 100 = 500`. - -This means that any slashing events which utilize the slashing period (are capped-per-period) **must** *also* jail the validator when the infraction is discovered. -Otherwise it would be possible for a validator to slash themselves intentionally at a low bond, then increase their bond but no longer be at stake since they would have already hit the `SlashedSoFar` cap. - -## State Cleanup - -Once no evidence for a given slashing period can possibly be valid (the end time plus the unbonding period is less than the current time), -old slashing periods should be cleaned up. This will be implemented post-launch. diff --git a/docs/spec/slashing/state.md b/docs/spec/slashing/state.md index b64e99040..ae426db7b 100644 --- a/docs/spec/slashing/state.md +++ b/docs/spec/slashing/state.md @@ -54,9 +54,9 @@ Where: ## Slashing Period A slashing period is a start and end block height associated with a particular validator, -within which only the "worst infraction counts": the total amount of slashing for -infractions committed within the period (and discovered whenever) is capped at the -penalty for the worst offense. +within which only the "worst infraction counts" (see the [Overview](overview.md)): the total +amount of slashing for infractions committed within the period (and discovered whenever) is +capped at the penalty for the worst offense. This period starts when a validator is first bonded and ends when a validator is slashed & jailed for any reason. When the validator rejoins the validator set (perhaps through unjailing themselves, diff --git a/docs/spec/slashing/transactions.md b/docs/spec/slashing/transactions.md new file mode 100644 index 000000000..b1d523139 --- /dev/null +++ b/docs/spec/slashing/transactions.md @@ -0,0 +1,40 @@ +## Transactions + +In this section we describe the processing of transactions for the `slashing` module. + +### TxUnjail + +If a validator was automatically unbonded due to downtime and wishes to come back online & +possibly rejoin the bonded set, it must send `TxUnjail`: + +``` +type TxUnjail struct { + ValidatorAddr sdk.AccAddress +} + +handleMsgUnjail(tx TxUnjail) + + validator = getValidator(tx.ValidatorAddr) + if validator == nil + fail with "No validator found" + + if !validator.Jailed + fail with "Validator not jailed, cannot unjail" + + info = getValidatorSigningInfo(operator) + if block time < info.JailedUntil + fail with "Validator still jailed, cannot unjail until period has expired" + + // Update the start height so the validator won't be immediately unbonded again + info.StartHeight = BlockHeight + setValidatorSigningInfo(info) + + validator.Jailed = false + setValidator(validator) + + return +``` + +If the validator has enough stake to be in the top `n = MaximumBondedValidators`, they will be automatically rebonded, +and all delegators still delegated to the validator will be rebonded and begin to again collect +provisions and rewards. From 4475a8c7e8d568349618e02e3e23c78e32067333 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 23 Aug 2018 13:46:44 +0200 Subject: [PATCH 27/32] Fixup links --- docs/spec/slashing/README.md | 10 +++++----- docs/spec/slashing/transactions.md | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/spec/slashing/README.md b/docs/spec/slashing/README.md index d50d95d36..dee91eb33 100644 --- a/docs/spec/slashing/README.md +++ b/docs/spec/slashing/README.md @@ -16,16 +16,16 @@ This module will be used by the Cosmos Hub, the first hub in the Cosmos ecosyste ## Contents +1. **[Overview](overview.md)** 1. **[State](state.md)** 1. [SigningInfo](state.md#signing-info) 1. [SlashingPeriod](state.md#slashing-period) -1. **[Overview](overview.md)** 1. **[Transactions](transactions.md)** - 1. Unjail + 1. [Unjail](transactions.md#unjail) 1. **[Hooks](hooks.md)** - 1. Validator Bonded - 1. Validator Unbonding - 1. Validator Slashed + 1. [Validator Bonded](hooks.md#validator-bonded) + 1. [Validator Unbonded](hooks.md#validator-unbonded) + 1. [Validator Slashed](hooks.md#validator-slashed) 1. **[Begin Block](begin-block.md)** 1. [Evidence handling](begin-block.md#evidence-handling) 1. [Uptime tracking](begin-block.md#uptime-tracking) diff --git a/docs/spec/slashing/transactions.md b/docs/spec/slashing/transactions.md index b1d523139..be33ee096 100644 --- a/docs/spec/slashing/transactions.md +++ b/docs/spec/slashing/transactions.md @@ -2,7 +2,7 @@ In this section we describe the processing of transactions for the `slashing` module. -### TxUnjail +### Unjail If a validator was automatically unbonded due to downtime and wishes to come back online & possibly rejoin the bonded set, it must send `TxUnjail`: From 435f0d5f8f7fd0a5f26f7e7f2beda464cde3221e Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 23 Aug 2018 14:08:02 +0200 Subject: [PATCH 28/32] Decrease 'make test_sim_gaia_fast' to 100 blocks --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index de5f6956f..8dab98616 100644 --- a/Makefile +++ b/Makefile @@ -152,7 +152,7 @@ test_sim_gaia_nondeterminism: test_sim_gaia_fast: @echo "Running quick Gaia simulation. This may take several minutes..." - @go test ./cmd/gaia/app -run TestFullGaiaSimulation -SimulationEnabled=true -SimulationNumBlocks=200 -timeout 24h + @go test ./cmd/gaia/app -run TestFullGaiaSimulation -SimulationEnabled=true -SimulationNumBlocks=100 -timeout 24h test_sim_gaia_slow: @echo "Running full Gaia simulation. This may take awhile!" From efa820b8f46084ff0b3dbdf693adec7a3b7a3ac3 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 23 Aug 2018 15:14:12 +0200 Subject: [PATCH 29/32] Try printing output instead --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 8dab98616..d4bd0a718 100644 --- a/Makefile +++ b/Makefile @@ -152,7 +152,7 @@ test_sim_gaia_nondeterminism: test_sim_gaia_fast: @echo "Running quick Gaia simulation. This may take several minutes..." - @go test ./cmd/gaia/app -run TestFullGaiaSimulation -SimulationEnabled=true -SimulationNumBlocks=100 -timeout 24h + @go test ./cmd/gaia/app -run TestFullGaiaSimulation -SimulationEnabled=true -SimulationNumBlocks=200 -v -timeout 24h test_sim_gaia_slow: @echo "Running full Gaia simulation. This may take awhile!" From c37ae1d5630ebccccd1f0d6b0e774c315d4f57d1 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 23 Aug 2018 15:25:00 +0200 Subject: [PATCH 30/32] 50 blocks now --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index d4bd0a718..66d566309 100644 --- a/Makefile +++ b/Makefile @@ -152,7 +152,7 @@ test_sim_gaia_nondeterminism: test_sim_gaia_fast: @echo "Running quick Gaia simulation. This may take several minutes..." - @go test ./cmd/gaia/app -run TestFullGaiaSimulation -SimulationEnabled=true -SimulationNumBlocks=200 -v -timeout 24h + @go test ./cmd/gaia/app -run TestFullGaiaSimulation -SimulationEnabled=true -SimulationNumBlocks=50 -v -timeout 24h test_sim_gaia_slow: @echo "Running full Gaia simulation. This may take awhile!" From addd93b3e532111060f075e57439284cd313b45f Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 23 Aug 2018 15:30:29 +0200 Subject: [PATCH 31/32] Add info on what PRs should be targeted where --- CONTRIBUTING.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e1a5e7c1f..3a7dca210 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -140,6 +140,10 @@ Ensure that you base and target your PR on the correct branch: - `master` for a merge of a release - `develop` in the usual case +All feature additions should be targeted against `develop`. Bug fixes for an outstanding release candidate +should be targeted against the release candidate branch. Release candidate branches themselves should be the +only pull requests targeted directly against master. + ### Development Procedure: - the latest state of development is on `develop` - `develop` must never fail `make test` or `make test_cli` From 63a85aaacf341a9a7a04d6953e869fa7b964ee7c Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 23 Aug 2018 22:45:38 +0200 Subject: [PATCH 32/32] Change ASCII diagram slightly --- docs/spec/slashing/overview.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/spec/slashing/overview.md b/docs/spec/slashing/overview.md index d9a8f39c1..aa42f6193 100644 --- a/docs/spec/slashing/overview.md +++ b/docs/spec/slashing/overview.md @@ -41,7 +41,7 @@ A single infraction is committed then later discovered, at which point the valid *Multiple infractions* -<----------------------------> +<---------------------------> [----------C1--C2---C3---D1,D2,D3Vu-----] Multiple infractions are committed within a single slashing period then later discovered, at which point the validator is unbonded and slashed for only the worst infraction. @@ -49,7 +49,7 @@ Multiple infractions are committed within a single slashing period then later di *Multiple infractions after rebonding* -<---------------------------->                        <--------------> +<--------------------------->                        <-------------> [----------C1--C2---C3---D1,D2,D3Vu---Vb---C4----D4,Vu--] Multiple infractions are committed within a single slashing period then later discovered, at which point the validator is unbonded and slashed for only the worst infraction.